vbo: Use a bitmask to track the active arrays in vbo_save*.
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_save.h
src/mesa/vbo/vbo_save_api.c
src/mesa/vbo/vbo_save_draw.c

index 8032db8a9e0e35cd753dd93a27769f95692b8ff2..2843b3c9b9c76c66dc36023a8249a09e337791df 100644 (file)
@@ -61,6 +61,7 @@ struct vbo_save_copied_vtx {
  * compiled using the fallback opcode mechanism provided by dlist.c.
  */
 struct vbo_save_vertex_list {
+   GLbitfield64 enabled; /**< mask of enabled vbo arrays. */
    GLubyte attrsz[VBO_ATTRIB_MAX];
    GLenum attrtype[VBO_ATTRIB_MAX];
    GLuint vertex_size;  /**< size in GLfloats */
@@ -126,6 +127,7 @@ struct vbo_save_context {
    struct gl_client_array arrays[VBO_ATTRIB_MAX];
    const struct gl_client_array *inputs[VBO_ATTRIB_MAX];
 
+   GLbitfield64 enabled; /**< mask of enabled vbo arrays. */
    GLubyte attrsz[VBO_ATTRIB_MAX];  /**< 1, 2, 3 or 4 */
    GLenum attrtype[VBO_ATTRIB_MAX];  /**< GL_FLOAT, GL_INT, etc */
    GLubyte active_sz[VBO_ATTRIB_MAX];  /**< 1, 2, 3 or 4 */
index 97a1dfdeb3f926fb5ae75ab0a4fcb0fd54b507d0..650c9b6b411e9b7bf41351be9ff6722d64d0a7ad 100644 (file)
@@ -78,6 +78,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/api_arrayelt.h"
 #include "main/vtxfmt.h"
 #include "main/dispatch.h"
+#include "util/bitscan.h"
 
 #include "vbo_context.h"
 #include "vbo_noop.h"
@@ -429,6 +430,7 @@ _save_compile_vertex_list(struct gl_context *ctx)
 
    /* Duplicate our template, increment refcounts to the storage structs:
     */
+   node->enabled = save->enabled;
    memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz));
    memcpy(node->attrtype, save->attrtype, sizeof(node->attrtype));
    node->vertex_size = save->vertex_size;
@@ -624,14 +626,15 @@ static void
 _save_copy_to_current(struct gl_context *ctx)
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
-   GLuint i;
+   GLbitfield64 enabled = save->enabled & (~BITFIELD64_BIT(VBO_ATTRIB_POS));
 
-   for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
-      if (save->attrsz[i]) {
-         save->currentsz[i][0] = save->attrsz[i];
-         COPY_CLEAN_4V_TYPE_AS_UNION(save->current[i], save->attrsz[i],
-                                     save->attrptr[i], save->attrtype[i]);
-      }
+   while (enabled) {
+      const int i = u_bit_scan64(&enabled);
+      assert(save->attrsz[i]);
+
+      save->currentsz[i][0] = save->attrsz[i];
+      COPY_CLEAN_4V_TYPE_AS_UNION(save->current[i], save->attrsz[i],
+                                  save->attrptr[i], save->attrtype[i]);
    }
 }
 
@@ -640,9 +643,11 @@ static void
 _save_copy_from_current(struct gl_context *ctx)
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
-   GLint i;
+   GLbitfield64 enabled = save->enabled & (~BITFIELD64_BIT(VBO_ATTRIB_POS));
+
+   while (enabled) {
+      const int i = u_bit_scan64(&enabled);
 
-   for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
       switch (save->attrsz[i]) {
       case 4:
          save->attrptr[i][3] = save->current[i][3];
@@ -652,7 +657,9 @@ _save_copy_from_current(struct gl_context *ctx)
          save->attrptr[i][1] = save->current[i][1];
       case 1:
          save->attrptr[i][0] = save->current[i][0];
+         break;
       case 0:
+         assert(0);
          break;
       }
    }
@@ -691,6 +698,7 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
     */
    oldsz = save->attrsz[attr];
    save->attrsz[attr] = newsz;
+   save->enabled |= BITFIELD64_BIT(attr);
 
    save->vertex_size += newsz - oldsz;
    save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) /
@@ -723,7 +731,6 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
    if (save->copied.nr) {
       const fi_type *data = save->copied.buffer;
       fi_type *dest = save->buffer;
-      GLuint j;
 
       /* Need to note this and fix up at runtime (or loopback):
        */
@@ -733,27 +740,28 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
       }
 
       for (i = 0; i < save->copied.nr; i++) {
-         for (j = 0; j < VBO_ATTRIB_MAX; j++) {
-            if (save->attrsz[j]) {
-               if (j == attr) {
-                  if (oldsz) {
-                     COPY_CLEAN_4V_TYPE_AS_UNION(dest, oldsz, data,
-                                                 save->attrtype[j]);
-                     data += oldsz;
-                     dest += newsz;
-                  }
-                  else {
-                     COPY_SZ_4V(dest, newsz, save->current[attr]);
-                     dest += newsz;
-                  }
+         GLbitfield64 enabled = save->enabled;
+         while (enabled) {
+            const int j = u_bit_scan64(&enabled);
+            assert(save->attrsz[j]);
+            if (j == attr) {
+               if (oldsz) {
+                  COPY_CLEAN_4V_TYPE_AS_UNION(dest, oldsz, data,
+                                              save->attrtype[j]);
+                  data += oldsz;
+                  dest += newsz;
                }
                else {
-                  GLint sz = save->attrsz[j];
-                  COPY_SZ_4V(dest, sz, data);
-                  data += sz;
-                  dest += sz;
+                  COPY_SZ_4V(dest, newsz, save->current[attr]);
+                  dest += newsz;
                }
             }
+            else {
+               GLint sz = save->attrsz[j];
+               COPY_SZ_4V(dest, sz, data);
+               data += sz;
+               dest += sz;
+            }
          }
       }
 
@@ -803,9 +811,10 @@ static void
 _save_reset_vertex(struct gl_context *ctx)
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
-   GLuint i;
 
-   for (i = 0; i < VBO_ATTRIB_MAX; i++) {
+   while (save->enabled) {
+      const int i = u_bit_scan64(&save->enabled);
+      assert(save->attrsz[i]);
       save->attrsz[i] = 0;
       save->active_sz[i] = 0;
    }
index b1fd6892026e6f78b83c422342e146ae2ca5765b..7881ce17d0f7640ba2cb15140a202b10ea684d49 100644 (file)
@@ -34,6 +34,7 @@
 #include "main/macros.h"
 #include "main/light.h"
 #include "main/state.h"
+#include "util/bitscan.h"
 
 #include "vbo_context.h"
 
@@ -49,7 +50,8 @@ _playback_copy_to_current(struct gl_context *ctx,
    struct vbo_context *vbo = vbo_context(ctx);
    fi_type vertex[VBO_ATTRIB_MAX * 4];
    fi_type *data;
-   GLuint i, offset;
+   GLbitfield64 mask;
+   GLuint offset;
 
    if (node->current_size == 0)
       return;
@@ -73,35 +75,36 @@ _playback_copy_to_current(struct gl_context *ctx,
       data += node->attrsz[0]; /* skip vertex position */
    }
 
-   for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
-      if (node->attrsz[i]) {
-        fi_type *current = (fi_type *)vbo->currval[i].Ptr;
-         fi_type tmp[4];
-
-         COPY_CLEAN_4V_TYPE_AS_UNION(tmp,
-                                     node->attrsz[i],
-                                     data,
-                                     node->attrtype[i]);
+   mask = node->enabled & (~BITFIELD64_BIT(VBO_ATTRIB_POS));
+   while (mask) {
+      const int i = u_bit_scan64(&mask);
+      fi_type *current = (fi_type *)vbo->currval[i].Ptr;
+      fi_type tmp[4];
+      assert(node->attrsz[i]);
+
+      COPY_CLEAN_4V_TYPE_AS_UNION(tmp,
+                                  node->attrsz[i],
+                                  data,
+                                  node->attrtype[i]);
+
+      if (node->attrtype[i] != vbo->currval[i].Type ||
+          memcmp(current, tmp, 4 * sizeof(GLfloat)) != 0) {
+         memcpy(current, tmp, 4 * sizeof(GLfloat));
          
-         if (node->attrtype[i] != vbo->currval[i].Type ||
-             memcmp(current, tmp, 4 * sizeof(GLfloat)) != 0) {
-            memcpy(current, tmp, 4 * sizeof(GLfloat));
-
-            vbo->currval[i].Size = node->attrsz[i];
-            vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat);
-            vbo->currval[i].Type = node->attrtype[i];
-            vbo->currval[i].Integer =
-                  vbo_attrtype_to_integer_flag(node->attrtype[i]);
+         vbo->currval[i].Size = node->attrsz[i];
+         vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat);
+         vbo->currval[i].Type = node->attrtype[i];
+         vbo->currval[i].Integer =
+            vbo_attrtype_to_integer_flag(node->attrtype[i]);
 
-            if (i >= VBO_ATTRIB_FIRST_MATERIAL &&
-                i <= VBO_ATTRIB_LAST_MATERIAL)
-               ctx->NewState |= _NEW_LIGHT;
+         if (i >= VBO_ATTRIB_FIRST_MATERIAL &&
+             i <= VBO_ATTRIB_LAST_MATERIAL)
+            ctx->NewState |= _NEW_LIGHT;
 
-            ctx->NewState |= _NEW_CURRENT_ATTRIB;
-         }
-
-        data += node->attrsz[i];
+         ctx->NewState |= _NEW_CURRENT_ATTRIB;
       }
+
+      data += node->attrsz[i];
    }
 
    /* Colormaterial -- this kindof sucks.