From: Mathias Fröhlich Date: Sun, 22 May 2016 12:10:19 +0000 (+0200) Subject: vbo: Use a bitmask to track the active arrays in vbo_save*. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0e73d9454d626f4ac96be51733d3d3db4b77392c;p=mesa.git vbo: Use a bitmask to track the active arrays in vbo_save*. 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 Signed-off-by: Mathias Fröhlich --- diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h index 8032db8a9e0..2843b3c9b9c 100644 --- a/src/mesa/vbo/vbo_save.h +++ b/src/mesa/vbo/vbo_save.h @@ -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 */ diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index 97a1dfdeb3f..650c9b6b411 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -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; } diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index b1fd6892026..7881ce17d0f 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -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.