best
Mathias
On Thursday, 25 January 2018 00:20:34 CET Brian Paul wrote:
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;
}