[Mesa-dev] [PATCH 30/31] vbo: Use a bitmask to track the active arrays in vbo_exec*.

Mathias.Froehlich at gmx.net Mathias.Froehlich at gmx.net
Tue Jun 7 05:31:09 UTC 2016


From: Mathias Fröhlich <mathias.froehlich at web.de>

The use of a bitmask makes functions iterating only active
attributes less visible in profiles.

v2: Use _mesa_bit_scan{,64} instead of open coding.

Reviewed-by: Brian Paul <brianp at vmware.com>
Signed-off-by: Mathias Fröhlich <Mathias.Froehlich at web.de>
---
 src/mesa/vbo/vbo_exec.h      |   1 +
 src/mesa/vbo/vbo_exec_api.c  | 145 ++++++++++++++++++++++---------------------
 src/mesa/vbo/vbo_exec_draw.c |   2 +
 3 files changed, 78 insertions(+), 70 deletions(-)

diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h
index 27bff4a..9748ef2 100644
--- a/src/mesa/vbo/vbo_exec.h
+++ b/src/mesa/vbo/vbo_exec.h
@@ -101,6 +101,7 @@ struct vbo_exec_context
       GLuint max_vert;     /**< Max number of vertices allowed in buffer */
       struct vbo_exec_copied_vtx copied;
 
+      GLbitfield64 enabled;/**< mask of enabled vbo arrays. */
       GLubyte attrsz[VBO_ATTRIB_MAX];   /**< nr. of attrib components (1..4) */
       GLenum attrtype[VBO_ATTRIB_MAX];  /**< GL_FLOAT, GL_DOUBLE, GL_INT, etc */
       GLubyte active_sz[VBO_ATTRIB_MAX];  /**< attrib size (nr. 32-bit words) */
diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
index 7534599..abf3c63 100644
--- a/src/mesa/vbo/vbo_exec_api.c
+++ b/src/mesa/vbo/vbo_exec_api.c
@@ -167,54 +167,56 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )
 {
    struct gl_context *ctx = exec->ctx;
    struct vbo_context *vbo = vbo_context(ctx);
-   GLuint i;
+   GLbitfield64 enabled = exec->vtx.enabled & (~BITFIELD64_BIT(VBO_ATTRIB_POS));
 
-   for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
-      if (exec->vtx.attrsz[i]) {
-         /* Note: the exec->vtx.current[i] pointers point into the
-          * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays.
-          */
-	 GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
-         fi_type tmp[8]; /* space for doubles */
-         int dmul = exec->vtx.attrtype[i] == GL_DOUBLE ? 2 : 1;
-
-         if (exec->vtx.attrtype[i] == GL_DOUBLE) {
-            memset(tmp, 0, sizeof(tmp));
-            memcpy(tmp, exec->vtx.attrptr[i], exec->vtx.attrsz[i] * sizeof(GLfloat));
-         } else {
-            COPY_CLEAN_4V_TYPE_AS_UNION(tmp,
-                                        exec->vtx.attrsz[i],
-                                        exec->vtx.attrptr[i],
-                                        exec->vtx.attrtype[i]);
-         }
+   while (enabled) {
+      const int i = _mesa_bit_scan64(&enabled);
+
+      /* Note: the exec->vtx.current[i] pointers point into the
+       * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays.
+       */
+      GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
+      fi_type tmp[8]; /* space for doubles */
+      int dmul = exec->vtx.attrtype[i] == GL_DOUBLE ? 2 : 1;
+
+      assert(exec->vtx.attrsz[i]);
+
+      if (exec->vtx.attrtype[i] == GL_DOUBLE) {
+         memset(tmp, 0, sizeof(tmp));
+         memcpy(tmp, exec->vtx.attrptr[i], exec->vtx.attrsz[i] * sizeof(GLfloat));
+      } else {
+         COPY_CLEAN_4V_TYPE_AS_UNION(tmp,
+                                     exec->vtx.attrsz[i],
+                                     exec->vtx.attrptr[i],
+                                     exec->vtx.attrtype[i]);
+      }
 
-         if (exec->vtx.attrtype[i] != vbo->currval[i].Type ||
-             memcmp(current, tmp, 4 * sizeof(GLfloat) * dmul) != 0) {
-            memcpy(current, tmp, 4 * sizeof(GLfloat) * dmul);
+      if (exec->vtx.attrtype[i] != vbo->currval[i].Type ||
+          memcmp(current, tmp, 4 * sizeof(GLfloat) * dmul) != 0) {
+         memcpy(current, tmp, 4 * sizeof(GLfloat) * dmul);
 	 
-            /* 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.
-             */
-            /* Size here is in components - not bytes */
-            vbo->currval[i].Size = exec->vtx.attrsz[i] / dmul;
-            vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat) * dmul;
-            vbo->currval[i].Type = exec->vtx.attrtype[i];
-            vbo->currval[i].Integer =
-                  vbo_attrtype_to_integer_flag(exec->vtx.attrtype[i]);
-            vbo->currval[i].Doubles =
-                  vbo_attrtype_to_double_flag(exec->vtx.attrtype[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;
-         }
+         /* 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.
+          */
+         /* Size here is in components - not bytes */
+         vbo->currval[i].Size = exec->vtx.attrsz[i] / dmul;
+         vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat) * dmul;
+         vbo->currval[i].Type = exec->vtx.attrtype[i];
+         vbo->currval[i].Integer =
+            vbo_attrtype_to_integer_flag(exec->vtx.attrtype[i]);
+         vbo->currval[i].Doubles =
+            vbo_attrtype_to_double_flag(exec->vtx.attrtype[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;
       }
    }
 
@@ -311,6 +313,7 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
    exec->vtx.max_vert = vbo_compute_max_verts(exec);
    exec->vtx.vert_count = 0;
    exec->vtx.buffer_ptr = exec->vtx.buffer_map;
+   exec->vtx.enabled |= BITFIELD64_BIT(attr);
 
    if (unlikely(oldSize)) {
       /* Size changed, recalculate all the attrptr[] values
@@ -345,34 +348,34 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
    if (unlikely(exec->vtx.copied.nr)) {
       fi_type *data = exec->vtx.copied.buffer;
       fi_type *dest = exec->vtx.buffer_ptr;
-      GLuint j;
 
       assert(exec->vtx.buffer_ptr == exec->vtx.buffer_map);
 
       for (i = 0 ; i < exec->vtx.copied.nr ; i++) {
-	 for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) {
+         GLbitfield64 enabled = exec->vtx.enabled;
+         while (enabled) {
+            const int j = _mesa_bit_scan64(&enabled);
 	    GLuint sz = exec->vtx.attrsz[j];
-
-	    if (sz) {
-	       GLint old_offset = old_attrptr[j] - exec->vtx.vertex;
-	       GLint new_offset = exec->vtx.attrptr[j] - exec->vtx.vertex;
-
-	       if (j == attr) {
-		  if (oldSize) {
-		     fi_type tmp[4];
-		     COPY_CLEAN_4V_TYPE_AS_UNION(tmp, oldSize,
-                                                 data + old_offset,
-                                                 exec->vtx.attrtype[j]);
-		     COPY_SZ_4V(dest + new_offset, newSize, tmp);
-		  } else {
-		     fi_type *current = (fi_type *)vbo->currval[j].Ptr;
-		     COPY_SZ_4V(dest + new_offset, sz, current);
-		  }
-	       }
-	       else {
-		  COPY_SZ_4V(dest + new_offset, sz, data + old_offset);
-	       }
-	    }
+            GLint old_offset = old_attrptr[j] - exec->vtx.vertex;
+            GLint new_offset = exec->vtx.attrptr[j] - exec->vtx.vertex;
+
+            assert(sz);
+
+            if (j == attr) {
+               if (oldSize) {
+                  fi_type tmp[4];
+                  COPY_CLEAN_4V_TYPE_AS_UNION(tmp, oldSize,
+                                              data + old_offset,
+                                              exec->vtx.attrtype[j]);
+                  COPY_SZ_4V(dest + new_offset, newSize, tmp);
+               } else {
+                  fi_type *current = (fi_type *)vbo->currval[j].Ptr;
+                  COPY_SZ_4V(dest + new_offset, sz, current);
+               }
+            }
+            else {
+               COPY_SZ_4V(dest + new_offset, sz, data + old_offset);
+            }
 	 }
 
 	 data += old_vtx_size;
@@ -1145,6 +1148,7 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec )
    vbo_exec_vtxfmt_init( exec );
    _mesa_noop_vtxfmt_init(&exec->vtxfmt_noop);
 
+   exec->vtx.enabled = 0;
    for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
       assert(i < ARRAY_SIZE(exec->vtx.attrsz));
       exec->vtx.attrsz[i] = 0;
@@ -1273,9 +1277,10 @@ void vbo_exec_FlushVertices( struct gl_context *ctx, GLuint flags )
 
 static void reset_attrfv( struct vbo_exec_context *exec )
 {   
-   GLuint i;
+   while (exec->vtx.enabled) {
+      const int i = _mesa_bit_scan64(&exec->vtx.enabled);
+      assert(exec->vtx.attrsz[i]);
 
-   for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
       exec->vtx.attrsz[i] = 0;
       exec->vtx.attrtype[i] = GL_FLOAT;
       exec->vtx.active_sz[i] = 0;
diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c
index 0d42618..8d1b2c0 100644
--- a/src/mesa/vbo/vbo_exec_draw.c
+++ b/src/mesa/vbo/vbo_exec_draw.c
@@ -214,6 +214,8 @@ vbo_exec_bind_arrays( struct gl_context *ctx )
          exec->vtx.attrsz[VERT_ATTRIB_GENERIC0] = exec->vtx.attrsz[0];
          exec->vtx.attrptr[VERT_ATTRIB_GENERIC0] = exec->vtx.attrptr[0];
          exec->vtx.attrsz[0] = 0;
+         exec->vtx.enabled &= (~BITFIELD64_BIT(VBO_ATTRIB_POS));
+         exec->vtx.enabled |= BITFIELD64_BIT(VBO_ATTRIB_GENERIC0);
       }
       break;
    default:
-- 
2.5.5



More information about the mesa-dev mailing list