mesa/dlist: shortcircuit some redundant statechanges at compile time
[mesa.git] / src / mesa / main / dlist.c
index 76b33150346daa21ad6c3d6b9623ff63f03e2d98..3647401a1bd32d5d6665de39dd877490d145f311 100644 (file)
@@ -33,6 +33,7 @@
 #include "api_arrayelt.h"
 #include "api_loopback.h"
 #include "config.h"
+#include "mfeatures.h"
 #include "attrib.h"
 #include "blend.h"
 #include "buffers.h"
@@ -319,6 +320,8 @@ typedef enum
    /* GL_ARB_draw_buffers */
    OPCODE_DRAW_BUFFERS_ARB,
    /* GL_ATI_fragment_shader */
+   OPCODE_TEX_BUMP_PARAMETER_ATI,
+   /* GL_ATI_fragment_shader */
    OPCODE_BIND_FRAGMENT_SHADER_ATI,
    OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI,
    /* OpenGL 2.0 */
@@ -704,7 +707,7 @@ unpack_image(GLuint dimensions, GLsizei width, GLsizei height, GLsizei depth,
 /**
  * Allocate space for a display list instruction.
  * \param opcode  the instruction opcode (OPCODE_* value)
- * \param size   instruction size in bytes, not counting opcode.
+ * \param bytes   instruction size in bytes, not counting opcode.
  * \return pointer to the usable data area (not including the internal
  *         opcode).
  */
@@ -972,7 +975,7 @@ _mesa_save_CallList(GLuint list)
    ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
 
    if (ctx->ExecuteFlag) {
-      CALL_CallList(ctx->Exec, (list));
+      _mesa_CallList(list);
    }
 }
 
@@ -3174,14 +3177,21 @@ save_ShadeModel(GLenum mode)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx);
+
+   if (ctx->ExecuteFlag) {
+      CALL_ShadeModel(ctx->Exec, (mode));
+   }
+
+   if (ctx->ListState.Current.ShadeModel == mode)
+      return;
+
+   ctx->ListState.Current.ShadeModel = mode;
+
    n = ALLOC_INSTRUCTION(ctx, OPCODE_SHADE_MODEL, 1);
    if (n) {
       n[1].e = mode;
    }
-   if (ctx->ExecuteFlag) {
-      CALL_ShadeModel(ctx->Exec, (mode));
-   }
 }
 
 
@@ -4802,6 +4812,36 @@ save_DrawBuffersARB(GLsizei count, const GLenum * buffers)
    }
 }
 
+static void GLAPIENTRY
+save_TexBumpParameterfvATI(GLenum pname, const GLfloat *param)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+
+   n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_BUMP_PARAMETER_ATI, 5);
+   if (n) {
+      n[1].ui = pname;
+      n[2].f = param[0];
+      n[3].f = param[1];
+      n[4].f = param[2];
+      n[5].f = param[3];
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_TexBumpParameterfvATI(ctx->Exec, (pname, param));
+   }
+}
+
+static void GLAPIENTRY
+save_TexBumpParameterivATI(GLenum pname, const GLint *param)
+{
+   GLfloat p[4];
+   p[0] = INT_TO_FLOAT(param[0]);
+   p[1] = INT_TO_FLOAT(param[1]);
+   p[2] = INT_TO_FLOAT(param[2]);
+   p[3] = INT_TO_FLOAT(param[3]);
+   save_TexBumpParameterfvATI(pname, p);
+}
+
 #if FEATURE_ATI_fragment_shader
 static void GLAPIENTRY
 save_BindFragmentShaderATI(GLuint id)
@@ -4941,7 +4981,7 @@ save_Attr1fARB(GLenum attr, GLfloat x)
       n[2].f = x;
    }
 
-   ASSERT(attr < MAX_VERTEX_ATTRIBS);
+   ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
    ctx->ListState.ActiveAttribSize[attr] = 1;
    ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, 0, 0, 1);
 
@@ -4963,7 +5003,7 @@ save_Attr2fARB(GLenum attr, GLfloat x, GLfloat y)
       n[3].f = y;
    }
 
-   ASSERT(attr < MAX_VERTEX_ATTRIBS);
+   ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
    ctx->ListState.ActiveAttribSize[attr] = 2;
    ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, 0, 1);
 
@@ -4986,7 +5026,7 @@ save_Attr3fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z)
       n[4].f = z;
    }
 
-   ASSERT(attr < MAX_VERTEX_ATTRIBS);
+   ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
    ctx->ListState.ActiveAttribSize[attr] = 3;
    ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, 1);
 
@@ -5010,7 +5050,7 @@ save_Attr4fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
       n[5].f = w;
    }
 
-   ASSERT(attr < MAX_VERTEX_ATTRIBS);
+   ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
    ctx->ListState.ActiveAttribSize[attr] = 4;
    ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, w);
 
@@ -5113,14 +5153,21 @@ save_EdgeFlag(GLboolean x)
    save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? (GLfloat)1.0 : (GLfloat)0.0);
 }
 
+static INLINE GLboolean compare4fv( const GLfloat *a,
+                                    const GLfloat *b,
+                                    GLuint count )
+{
+   return memcmp( a, b, count * sizeof(GLfloat) ) == 0;
+}
+                              
+
 static void GLAPIENTRY
 save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    int args, i;
-
-   SAVE_FLUSH_VERTICES(ctx);
+   GLuint bitmask;
 
    switch (face) {
    case GL_BACK:
@@ -5150,6 +5197,28 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
       _mesa_compile_error(ctx, GL_INVALID_ENUM, "material(pname)");
       return;
    }
+   
+   if (ctx->ExecuteFlag) {
+      CALL_Materialfv(ctx->Exec, (face, pname, param));
+   }
+
+   bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, NULL);
+
+   /* Try to eliminate redundant statechanges
+    */
+   for (i = 0; i < MAT_ATTRIB_MAX; i++) {
+      if (bitmask & (1 << i)) {
+         if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END && 
+             ctx->ListState.ActiveMaterialSize[i] == args &&
+             compare4fv(ctx->ListState.CurrentMaterial[i], param, args))
+            return;
+             
+         ctx->ListState.ActiveMaterialSize[i] = args;
+         COPY_SZ_4V(ctx->ListState.CurrentMaterial[i], args, param);
+      }
+   }
+
+   SAVE_FLUSH_VERTICES(ctx);
 
    n = ALLOC_INSTRUCTION(ctx, OPCODE_MATERIAL, 6);
    if (n) {
@@ -5158,19 +5227,6 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
       for (i = 0; i < args; i++)
          n[3 + i].f = param[i];
    }
-
-   {
-      GLuint bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, NULL);
-      for (i = 0; i < MAT_ATTRIB_MAX; i++)
-         if (bitmask & (1 << i)) {
-            ctx->ListState.ActiveMaterialSize[i] = args;
-            COPY_SZ_4V(ctx->ListState.CurrentMaterial[i], args, param);
-         }
-   }
-
-   if (ctx->ExecuteFlag) {
-      CALL_Materialfv(ctx->Exec, (face, pname, param));
-   }
 }
 
 static void GLAPIENTRY
@@ -5473,7 +5529,7 @@ index_error(void)
 static void GLAPIENTRY
 save_VertexAttrib1fNV(GLuint index, GLfloat x)
 {
-   if (index < MAX_VERTEX_PROGRAM_ATTRIBS)
+   if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
       save_Attr1fNV(index, x);
    else
       index_error();
@@ -5482,7 +5538,7 @@ save_VertexAttrib1fNV(GLuint index, GLfloat x)
 static void GLAPIENTRY
 save_VertexAttrib1fvNV(GLuint index, const GLfloat * v)
 {
-   if (index < MAX_VERTEX_PROGRAM_ATTRIBS)
+   if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
       save_Attr1fNV(index, v[0]);
    else
       index_error();
@@ -5491,7 +5547,7 @@ save_VertexAttrib1fvNV(GLuint index, const GLfloat * v)
 static void GLAPIENTRY
 save_VertexAttrib2fNV(GLuint index, GLfloat x, GLfloat y)
 {
-   if (index < MAX_VERTEX_PROGRAM_ATTRIBS)
+   if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
       save_Attr2fNV(index, x, y);
    else
       index_error();
@@ -5500,7 +5556,7 @@ save_VertexAttrib2fNV(GLuint index, GLfloat x, GLfloat y)
 static void GLAPIENTRY
 save_VertexAttrib2fvNV(GLuint index, const GLfloat * v)
 {
-   if (index < MAX_VERTEX_PROGRAM_ATTRIBS)
+   if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
       save_Attr2fNV(index, v[0], v[1]);
    else
       index_error();
@@ -5509,7 +5565,7 @@ save_VertexAttrib2fvNV(GLuint index, const GLfloat * v)
 static void GLAPIENTRY
 save_VertexAttrib3fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z)
 {
-   if (index < MAX_VERTEX_PROGRAM_ATTRIBS)
+   if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
       save_Attr3fNV(index, x, y, z);
    else
       index_error();
@@ -5518,7 +5574,7 @@ save_VertexAttrib3fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z)
 static void GLAPIENTRY
 save_VertexAttrib3fvNV(GLuint index, const GLfloat * v)
 {
-   if (index < MAX_VERTEX_PROGRAM_ATTRIBS)
+   if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
       save_Attr3fNV(index, v[0], v[1], v[2]);
    else
       index_error();
@@ -5528,7 +5584,7 @@ static void GLAPIENTRY
 save_VertexAttrib4fNV(GLuint index, GLfloat x, GLfloat y,
                       GLfloat z, GLfloat w)
 {
-   if (index < MAX_VERTEX_PROGRAM_ATTRIBS)
+   if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
       save_Attr4fNV(index, x, y, z, w);
    else
       index_error();
@@ -5537,7 +5593,7 @@ save_VertexAttrib4fNV(GLuint index, GLfloat x, GLfloat y,
 static void GLAPIENTRY
 save_VertexAttrib4fvNV(GLuint index, const GLfloat * v)
 {
-   if (index < MAX_VERTEX_PROGRAM_ATTRIBS)
+   if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
       save_Attr4fNV(index, v[0], v[1], v[2], v[3]);
    else
       index_error();
@@ -5549,7 +5605,7 @@ save_VertexAttrib4fvNV(GLuint index, const GLfloat * v)
 static void GLAPIENTRY
 save_VertexAttrib1fARB(GLuint index, GLfloat x)
 {
-   if (index < MAX_VERTEX_ATTRIBS)
+   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
       save_Attr1fARB(index, x);
    else
       index_error();
@@ -5558,7 +5614,7 @@ save_VertexAttrib1fARB(GLuint index, GLfloat x)
 static void GLAPIENTRY
 save_VertexAttrib1fvARB(GLuint index, const GLfloat * v)
 {
-   if (index < MAX_VERTEX_ATTRIBS)
+   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
       save_Attr1fARB(index, v[0]);
    else
       index_error();
@@ -5567,7 +5623,7 @@ save_VertexAttrib1fvARB(GLuint index, const GLfloat * v)
 static void GLAPIENTRY
 save_VertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y)
 {
-   if (index < MAX_VERTEX_ATTRIBS)
+   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
       save_Attr2fARB(index, x, y);
    else
       index_error();
@@ -5576,7 +5632,7 @@ save_VertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y)
 static void GLAPIENTRY
 save_VertexAttrib2fvARB(GLuint index, const GLfloat * v)
 {
-   if (index < MAX_VERTEX_ATTRIBS)
+   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
       save_Attr2fARB(index, v[0], v[1]);
    else
       index_error();
@@ -5585,7 +5641,7 @@ save_VertexAttrib2fvARB(GLuint index, const GLfloat * v)
 static void GLAPIENTRY
 save_VertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z)
 {
-   if (index < MAX_VERTEX_ATTRIBS)
+   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
       save_Attr3fARB(index, x, y, z);
    else
       index_error();
@@ -5594,7 +5650,7 @@ save_VertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z)
 static void GLAPIENTRY
 save_VertexAttrib3fvARB(GLuint index, const GLfloat * v)
 {
-   if (index < MAX_VERTEX_ATTRIBS)
+   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
       save_Attr3fARB(index, v[0], v[1], v[2]);
    else
       index_error();
@@ -5604,7 +5660,7 @@ static void GLAPIENTRY
 save_VertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z,
                        GLfloat w)
 {
-   if (index < MAX_VERTEX_ATTRIBS)
+   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
       save_Attr4fARB(index, x, y, z, w);
    else
       index_error();
@@ -5613,7 +5669,7 @@ save_VertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z,
 static void GLAPIENTRY
 save_VertexAttrib4fvARB(GLuint index, const GLfloat * v)
 {
-   if (index < MAX_VERTEX_ATTRIBS)
+   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
       save_Attr4fARB(index, v[0], v[1], v[2], v[3]);
    else
       index_error();
@@ -6504,6 +6560,16 @@ execute_list(GLcontext *ctx, GLuint list)
                                                 n[9].i, n[10].e));
            break;
 #endif
+         case OPCODE_TEX_BUMP_PARAMETER_ATI:
+            {
+               GLfloat values[4];
+               GLuint i, pname = n[1].ui;
+
+               for (i = 0; i < 4; i++)
+                  values[i] = n[1 + i].f;
+               CALL_TexBumpParameterfvATI(ctx->Exec, (pname, values));
+            }
+            break;
 #if FEATURE_ATI_fragment_shader
          case OPCODE_BIND_FRAGMENT_SHADER_ATI:
             CALL_BindFragmentShaderATI(ctx->Exec, (n[1].i));
@@ -6769,6 +6835,8 @@ _mesa_NewList(GLuint name, GLenum mode)
    for (i = 0; i < MAT_ATTRIB_MAX; i++)
       ctx->ListState.ActiveMaterialSize[i] = 0;
 
+   memset(&ctx->ListState.Current, 0, sizeof ctx->ListState.Current);
+
    ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
    ctx->Driver.NewList(ctx, name, mode);
 
@@ -8042,6 +8110,10 @@ _mesa_init_dlist_table(struct _glapi_table *table)
    SET_VertexAttribPointerNV(table, _mesa_VertexAttribPointerNV);
 #endif
 
+   /* 244. GL_ATI_envmap_bumpmap */
+   SET_TexBumpParameterivATI(table, save_TexBumpParameterivATI);
+   SET_TexBumpParameterfvATI(table, save_TexBumpParameterfvATI);
+
    /* 245. GL_ATI_fragment_shader */
 #if FEATURE_ATI_fragment_shader
    SET_BindFragmentShaderATI(table, save_BindFragmentShaderATI);