vbo: Use a bitmask to track the active arrays in vbo_exec*.
authorMathias Fröhlich <mathias.froehlich@web.de>
Sun, 22 May 2016 12:10:19 +0000 (14:10 +0200)
committerMathias Fröhlich <mathias.froehlich@web.de>
Thu, 16 Jun 2016 03:50:55 +0000 (05:50 +0200)
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.
v3: Use u_bit_scan{,64} instead of _mesa_bit_scan{,64}.

Reviewed-by: Brian Paul <brianp@vmware.com>
Signed-off-by: Mathias Fröhlich <Mathias.Froehlich@web.de>
src/mesa/vbo/vbo_exec.h
src/mesa/vbo/vbo_exec_api.c
src/mesa/vbo/vbo_exec_draw.c

index 27bff4a2aa92373b8b85ed8ebe59db97346513be..5e20cf6f24a564a03f5a4a4b954892637cc530d2 100644 (file)
@@ -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) */
index 7534599c3134b1dce00aaf581c1f41ac462b59b9..e02bb907c4fca6f318acef6317b672f7744be512 100644 (file)
@@ -42,6 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/api_arrayelt.h"
 #include "main/api_validate.h"
 #include "main/dispatch.h"
+#include "util/bitscan.h"
 
 #include "vbo_context.h"
 #include "vbo_noop.h"
@@ -167,54 +168,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 = u_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 +314,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 +349,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 = u_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 +1149,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 +1278,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 = u_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;
index 0d42618f2469f2992025d82ee511c1898a859261..8d1b2c08d270347f21c2463cb2d49b97c81513df 100644 (file)
@@ -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: