Instead of looping over 32 attributes, just scan the enabled attrib bits.
This involves manipulating the 'enabled' attributes variable depending
on whether we're using legacy GL or a vertex shader.

We can remove the varying_inputs variable since it's the same as
the new 'enabled' bitfield.
---
 src/mesa/vbo/vbo_exec_draw.c | 37 ++++++++++++++++++++++++++++++++-----
 src/mesa/vbo/vbo_save_draw.c | 36 +++++++++++++++++++++++++++++++-----
 2 files changed, 63 insertions(+), 10 deletions(-)

diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c
index 5cea7fe..fcda235 100644
--- a/src/mesa/vbo/vbo_exec_draw.c
+++ b/src/mesa/vbo/vbo_exec_draw.c
@@ -174,9 +174,9 @@ vbo_exec_bind_arrays(struct gl_context *ctx)
    struct vbo_context *vbo = vbo_context(ctx);
    struct vbo_exec_context *exec = &vbo->exec;
    struct gl_vertex_array *arrays = exec->vtx.arrays;
-   const GLubyte *map;
+   const GLubyte *map;  /** map from VERT_ATTRIB_x to VBO_ATTRIB_x */
    GLuint attr;
-   GLbitfield varying_inputs = 0x0;
+   GLbitfield64 enabled = exec->vtx.enabled;
    bool swap_pos = false;
 
    /* Install the default (ie Current) attributes first */
@@ -194,6 +194,10 @@ vbo_exec_bind_arrays(struct gl_context *ctx)
             &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+attr];
       }
       map = vbo->map_vp_none;
+
+      /* shift material attrib flags into generic attribute positions */
+      enabled = (enabled & VBO_ATTRIBS_LEGACY)
+         | ((enabled & VBO_ATTRIBS_MATERIALS) >> VBO_MATERIAL_SHIFT);
       break;
    case VP_SHADER:
       for (attr = 0; attr < VERT_ATTRIB_GENERIC_MAX; attr++) {
@@ -203,6 +207,9 @@ vbo_exec_bind_arrays(struct gl_context *ctx)
       }
       map = vbo->map_vp_arb;
 
+      /* per-vertex materials are to be ignored when using a VS */
+      enabled &= ~VBO_ATTRIBS_MATERIALS;
+
       /* check if VERT_ATTRIB_POS is not read but VERT_BIT_GENERIC0 is read.
        * In that case we effectively need to route the data from
        * glVertexAttrib(0, val) calls to feed into the GENERIC0 input.
@@ -218,13 +225,34 @@ vbo_exec_bind_arrays(struct gl_context *ctx)
          exec->vtx.attrtype[VERT_ATTRIB_GENERIC0] = exec->vtx.attrtype[0];
          exec->vtx.attrptr[VERT_ATTRIB_GENERIC0] = exec->vtx.attrptr[0];
          exec->vtx.attrsz[0] = 0;
+         enabled &= ~BITFIELD64_BIT(VBO_ATTRIB_POS);
+         enabled |= BITFIELD64_BIT(VBO_ATTRIB_GENERIC0);
       }
       break;
    default:
       unreachable("Bad vertex program mode");
    }
 
-   for (attr = 0; attr < VERT_ATTRIB_MAX ; attr++) {
+#ifdef DEBUG
+   /* verify the enabled bitmask is consistent with attribute size info */
+   {
+      GLbitfield64 used = 0x0;
+      for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
+         const GLuint src = map[attr];
+         if (exec->vtx.attrsz[src]) {
+            assert(enabled & VERT_BIT(attr));
+            used |= VERT_BIT(attr);
+         } else {
+            assert((enabled & VERT_BIT(attr)) == 0);
+         }
+      }
+      assert(used == enabled);
+   }
+#endif
+
+   GLbitfield64 enabled_scan = enabled;
+   while (enabled_scan) {
+      const int attr = u_bit_scan64(&enabled_scan);
       const GLuint src = map[attr];
 
       if (exec->vtx.attrsz[src]) {
@@ -258,7 +286,6 @@ vbo_exec_bind_arrays(struct gl_context *ctx)
                                        &arrays[attr].BufferObj,
                                        exec->vtx.bufferobj);
 
-         varying_inputs |= VERT_BIT(attr);
       }
    }
 
@@ -272,7 +299,7 @@ vbo_exec_bind_arrays(struct gl_context *ctx)
       exec->vtx.attrsz[VERT_ATTRIB_GENERIC0] = 0;
    }
 
-   _mesa_set_varying_vp_inputs(ctx, varying_inputs);
+   _mesa_set_varying_vp_inputs(ctx, enabled);
    ctx->NewDriverState |= ctx->DriverFlags.NewArray;
 }
 
diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
index c86efcb..5f5dcbe 100644
--- a/src/mesa/vbo/vbo_save_draw.c
+++ b/src/mesa/vbo/vbo_save_draw.c
@@ -138,11 +138,11 @@ bind_vertex_list(struct gl_context *ctx,
    struct vbo_save_context *save = &vbo->save;
    struct gl_vertex_array *arrays = save->arrays;
    GLuint buffer_offset = node->buffer_offset;
-   const GLubyte *map;
+   const GLubyte *map;  /** map from VERT_ATTRIB_x to VBO_ATTRIB_x */
    GLuint attr;
    GLubyte node_attrsz[VBO_ATTRIB_MAX];  /* copy of node->attrsz[] */
    GLenum node_attrtype[VBO_ATTRIB_MAX];  /* copy of node->attrtype[] */
-   GLbitfield varying_inputs = 0x0;
+   GLbitfield64 enabled = node->enabled;
 
    memcpy(node_attrsz, node->attrsz, sizeof(node->attrsz));
    memcpy(node_attrtype, node->attrtype, sizeof(node->attrtype));
@@ -173,6 +173,10 @@ bind_vertex_list(struct gl_context *ctx,
             &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+attr];
       }
       map = vbo->map_vp_none;
+
+      /* shift material attrib flags into generic attribute positions */
+      enabled = (enabled & VBO_ATTRIBS_LEGACY)
+         | ((enabled & VBO_ATTRIBS_MATERIALS) >> VBO_MATERIAL_SHIFT);
       break;
    case VP_SHADER:
       for (attr = 0; attr < VERT_ATTRIB_GENERIC_MAX; attr++) {
@@ -181,6 +185,9 @@ bind_vertex_list(struct gl_context *ctx,
       }
       map = vbo->map_vp_arb;
 
+      /* per-vertex materials are to be ignored when using a VS */
+      enabled &= ~VBO_ATTRIBS_MATERIALS;
+
       /* check if VERT_ATTRIB_POS is not read but VERT_BIT_GENERIC0 is read.
        * In that case we effectively need to route the data from
        * glVertexAttrib(0, val) calls to feed into the GENERIC0 input.
@@ -193,13 +200,33 @@ bind_vertex_list(struct gl_context *ctx,
          node_attrsz[VERT_ATTRIB_GENERIC0] = node_attrsz[0];
          node_attrtype[VERT_ATTRIB_GENERIC0] = node_attrtype[0];
          node_attrsz[0] = 0;
+         enabled = (enabled & ~VERT_BIT_POS) | VERT_BIT_GENERIC0;
       }
       break;
    default:
       unreachable("Bad vertex program mode");
    }
 
-   for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
+#ifdef DEBUG
+   /* verify the enabled bitmask is consistent with attribute size info */
+   {
+      GLbitfield64 used = 0x0;
+      for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
+         const GLuint src = map[attr];
+         if (node_attrsz[src]) {
+            assert(enabled & VERT_BIT(attr));
+            used |= VERT_BIT(attr);
+         } else {
+            assert((enabled & VERT_BIT(attr)) == 0);
+         }
+      }
+      assert(used == enabled);
+   }
+#endif
+
+   GLbitfield64 enabled_scan = enabled;
+   while (enabled_scan) {
+      const int attr = u_bit_scan64(&enabled_scan);
       const GLuint src = map[attr];
 
       if (node_attrsz[src]) {
@@ -222,11 +249,10 @@ bind_vertex_list(struct gl_context *ctx,
          assert(array->BufferObj->Name);
 
          buffer_offset += node_attrsz[src] * sizeof(GLfloat);
-         varying_inputs |= VERT_BIT(attr);
       }
    }
 
-   _mesa_set_varying_vp_inputs(ctx, varying_inputs);
+   _mesa_set_varying_vp_inputs(ctx, enabled);
    ctx->NewDriverState |= ctx->DriverFlags.NewArray;
 }
 
-- 
2.7.4

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to