mesa: add new internal state for tracking current vertex attribs
authorKeith Whitwell <keith@tungstengraphics.com>
Fri, 3 Oct 2008 12:55:40 +0000 (13:55 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Fri, 3 Oct 2008 15:49:52 +0000 (16:49 +0100)
src/mesa/main/mtypes.h
src/mesa/main/state.c
src/mesa/shader/prog_statevars.c
src/mesa/shader/prog_statevars.h
src/mesa/vbo/vbo_exec_api.c
src/mesa/vbo/vbo_save_draw.c

index a5e1cf6a276c58fa54414a6240edf1b6236a9ec4..bc099dabeb08efe225801d839ada7f29bfb64708 100644 (file)
@@ -2744,6 +2744,7 @@ struct gl_matrix_stack
 #define _NEW_MULTISAMPLE        0x2000000  /**< __GLcontextRec::Multisample */
 #define _NEW_TRACK_MATRIX       0x4000000  /**< __GLcontextRec::VertexProgram */
 #define _NEW_PROGRAM            0x8000000  /**< __GLcontextRec::VertexProgram */
+#define _NEW_CURRENT_ATTRIB     0x10000000  /**< __GLcontextRec::Current */
 #define _NEW_ALL ~0
 /*@}*/
 
index d355f78a0efbf98b2ac1184c6f91d4edf0042589..eb8dc2a3398f2ed42360ea56b30b4e9d1b2f37ef 100644 (file)
@@ -407,6 +407,9 @@ _mesa_update_state_locked( GLcontext *ctx )
    GLbitfield new_state = ctx->NewState;
    GLbitfield prog_flags = _NEW_PROGRAM;
 
+   if (new_state == _NEW_CURRENT_ATTRIB) 
+      goto out;
+
    if (MESA_VERBOSE & VERBOSE_STATE)
       _mesa_print_state("_mesa_update_state", new_state);
 
@@ -484,6 +487,7 @@ _mesa_update_state_locked( GLcontext *ctx )
     * Set ctx->NewState to zero to avoid recursion if
     * Driver.UpdateState() has to call FLUSH_VERTICES().  (fixed?)
     */
+ out:
    new_state = ctx->NewState;
    ctx->NewState = 0;
    ctx->Driver.UpdateState(ctx, new_state);
index 47c46f63ec972576f1ae8959100a094928819b69..9cc33fa2c115f4e885356fed4c80dd95ef507b29 100644 (file)
@@ -395,6 +395,12 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
 
    case STATE_INTERNAL:
       switch (state[1]) {
+      case STATE_CURRENT_ATTRIB: {
+         const GLuint idx = (GLuint) state[2];
+         COPY_4V(value, ctx->Current.Attrib[idx]);
+         return;
+      }                                                  
+
       case STATE_NORMAL_SCALE:
          ASSIGN_4V(value, 
                    ctx->_ModelViewInvScale, 
@@ -565,6 +571,8 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
 
    case STATE_INTERNAL:
       switch (state[1]) {
+      case STATE_CURRENT_ATTRIB:
+         return _NEW_CURRENT_ATTRIB;
 
       case STATE_NORMAL_SCALE:
          return _NEW_MODELVIEW;
index 7b490e3d630e7773eaec7e3915ee80d6bf1aa2d1..1f728c64e80b6d8666e40956969a72901233a00c 100644 (file)
@@ -104,6 +104,7 @@ typedef enum gl_state_index_ {
    STATE_LOCAL,
 
    STATE_INTERNAL,             /* Mesa additions */
+   STATE_CURRENT_ATTRIB,        /* ctx->Current vertex attrib value */
    STATE_NORMAL_SCALE,
    STATE_TEXRECT_SCALE,
    STATE_FOG_PARAMS_OPTIMIZED,  /* for faster fog calc */
index d70b4bb1a1141db8b3d31a438c4cf432d00521e5..23f4f8331e3722c567adf66bf5a3f26300e32ee2 100644 (file)
@@ -143,29 +143,37 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )
 
    for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
       if (exec->vtx.attrsz[i]) {
-        GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
-
          /* Note: the exec->vtx.current[i] pointers point into the
           * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays.
           */
-        COPY_CLEAN_4V(current, 
-                      exec->vtx.attrsz[i], 
-                      exec->vtx.attrptr[i]);
+        GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
+         GLfloat tmp[4];
+
+         COPY_CLEAN_4V(tmp, 
+                       exec->vtx.attrsz[i], 
+                       exec->vtx.attrptr[i]);
+         
+         if (memcmp(current, tmp, sizeof(tmp)) != 0)
+         { 
+            memcpy(current, tmp, sizeof(tmp));
 
         
-        /* Given that we explicitly state size here, there is no need
-         * for the COPY_CLEAN above, could just copy 16 bytes and be
-         * done.  The only problem is when Mesa accesses ctx->Current
-         * directly.
-         */
-        vbo->currval[i].Size = exec->vtx.attrsz[i];
-
-        /* This triggers rather too much recalculation of Mesa state
-         * that doesn't get used (eg light positions).
-         */
-        if (i >= VBO_ATTRIB_MAT_FRONT_AMBIENT &&
-            i <= VBO_ATTRIB_MAT_BACK_INDEXES)
-           ctx->NewState |= _NEW_LIGHT;
+            /* Given that we explicitly state size here, there is no need
+             * for the COPY_CLEAN above, could just copy 16 bytes and be
+             * done.  The only problem is when Mesa accesses ctx->Current
+             * directly.
+             */
+            vbo->currval[i].Size = exec->vtx.attrsz[i];
+
+            /* This triggers rather too much recalculation of Mesa state
+             * that doesn't get used (eg light positions).
+             */
+            if (i >= VBO_ATTRIB_MAT_FRONT_AMBIENT &&
+                i <= VBO_ATTRIB_MAT_BACK_INDEXES)
+               ctx->NewState |= _NEW_LIGHT;
+            
+            ctx->NewState |= _NEW_CURRENT_ATTRIB;
+         }
       }
    }
 
index ed82f09958daf1c76eea0c98e600bc29dae32eac..4c97acddb9ff4850cc9ab343c9bf994ce88aadc7 100644 (file)
@@ -64,18 +64,26 @@ static void _playback_copy_to_current( GLcontext *ctx,
    for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
       if (node->attrsz[i]) {
         GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
+         GLfloat tmp[4];
 
-        COPY_CLEAN_4V(current, 
-                      node->attrsz[i], 
-                      data);
+         COPY_CLEAN_4V(tmp, 
+                       node->attrsz[i], 
+                       data);
+         
+         if (memcmp(current, tmp, 4 * sizeof(GLfloat)) != 0)
+         {
+            memcpy(current, tmp, 4 * sizeof(GLfloat));
 
-        vbo->currval[i].Size = node->attrsz[i];
+            vbo->currval[i].Size = node->attrsz[i];
 
-        data += node->attrsz[i];
+            if (i >= VBO_ATTRIB_FIRST_MATERIAL &&
+                i <= VBO_ATTRIB_LAST_MATERIAL)
+               ctx->NewState |= _NEW_LIGHT;
+
+            ctx->NewState |= _NEW_CURRENT_ATTRIB;
+         }
 
-        if (i >= VBO_ATTRIB_FIRST_MATERIAL &&
-            i <= VBO_ATTRIB_LAST_MATERIAL)
-           ctx->NewState |= _NEW_LIGHT;
+        data += node->attrsz[i];
       }
    }