From 7a1e941ebee43cb97a2c77fd2269999b202308a2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mathias=20Fr=C3=B6hlich?= Date: Thu, 29 Dec 2011 13:10:01 +0100 Subject: [PATCH] mesa: Fix and speedup gl_array_object::_MaxElement computation. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Use a bitmask approach to compute gl_array_object::_MaxElement. To make this work correctly depending on the shader type actually used, make use of the newly introduced typed bitmask getters. With this change I gain about 5% draw time on some osgviewer examples. Signed-off-by: Mathias Fröhlich Reviewed-by: Brian Paul --- src/mesa/main/arrayobj.c | 41 ++++++++----- src/mesa/main/state.c | 126 +-------------------------------------- 2 files changed, 28 insertions(+), 139 deletions(-) diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index 29bfed8f51e..3287745432f 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -280,15 +280,26 @@ remove_array_object( struct gl_context *ctx, struct gl_array_object *obj ) /** - * Helper for update_arrays(). - * \return min(current min, array->_MaxElement). + * Helper for _mesa_update_array_object_max_element(). + * \return min(arrayObj->VertexAttrib[*]._MaxElement). */ static GLuint -update_min(GLuint min, struct gl_client_array *array) +compute_max_element(struct gl_array_object *arrayObj, GLbitfield64 enabled) { - assert(array->Enabled); - _mesa_update_array_max_element(array); - return MIN2(min, array->_MaxElement); + GLuint min = ~((GLuint)0); + + while (enabled) { + struct gl_client_array *client_array; + GLint attrib = ffsll(enabled) - 1; + enabled ^= BITFIELD64_BIT(attrib); + + client_array = &arrayObj->VertexAttrib[attrib]; + assert(client_array->Enabled); + _mesa_update_array_max_element(client_array); + min = MIN2(min, client_array->_MaxElement); + } + + return min; } @@ -299,17 +310,19 @@ void _mesa_update_array_object_max_element(struct gl_context *ctx, struct gl_array_object *arrayObj) { - GLbitfield64 enabled = arrayObj->_Enabled; - GLuint min = ~0u; - - while (enabled) { - GLint attrib = ffsll(enabled) - 1; - enabled &= ~BITFIELD64_BIT(attrib); - min = update_min(min, &arrayObj->VertexAttrib[attrib]); + GLbitfield64 enabled; + + if (!ctx->VertexProgram._Current || + ctx->VertexProgram._Current == ctx->VertexProgram._TnlProgram) { + enabled = _mesa_array_object_get_enabled_ff(arrayObj); + } else if (ctx->VertexProgram._Current->IsNVProgram) { + enabled = _mesa_array_object_get_enabled_nv(arrayObj); + } else { + enabled = _mesa_array_object_get_enabled_arb(arrayObj); } /* _MaxElement is one past the last legal array element */ - arrayObj->_MaxElement = min; + arrayObj->_MaxElement = compute_max_element(arrayObj, enabled); } diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index b910543e2cf..adbb0c32b6c 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -62,130 +62,6 @@ update_separate_specular(struct gl_context *ctx) } -/** - * Helper for update_arrays(). - * \return min(current min, array->_MaxElement). - */ -static GLuint -update_min(GLuint min, struct gl_client_array *array) -{ - _mesa_update_array_max_element(array); - return MIN2(min, array->_MaxElement); -} - - -/** - * Update ctx->Array._MaxElement (the max legal index into all enabled arrays). - * Need to do this upon new array state or new buffer object state. - */ -static void -update_arrays( struct gl_context *ctx ) -{ - struct gl_array_object *arrayObj = ctx->Array.ArrayObj; - GLuint i, min = ~0; - - /* find min of _MaxElement values for all enabled arrays. - * Note that the generic arrays always take precedence over - * the legacy arrays. - */ - - /* 0 */ - if (ctx->VertexProgram._Current - && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0]); - } - else if (arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_POS]); - } - - /* 1 */ - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC1].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC1]); - } - /* no conventional vertex weight array */ - - /* 2 */ - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC2].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC2]); - } - else if (arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]); - } - - /* 3 */ - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC3].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC3]); - } - else if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]); - } - - /* 4 */ - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC4].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC4]); - } - else if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]); - } - - /* 5 */ - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC5].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC5]); - } - else if (arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_FOG]); - } - - /* 6 */ - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC6].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC6]); - } - else if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]); - } - - /* 7 */ - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC7].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC7]); - } - - /* 8..15 */ - for (i = 0; i < VERT_ATTRIB_TEX_MAX; i++) { - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC8 + i].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC8 + i]); - } - else if (i < ctx->Const.MaxTextureCoordUnits - && arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)]); - } - } - - /* 16..31 */ - if (ctx->VertexProgram._Current) { - for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) { - if (arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)]); - } - } - } - - if (arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]); - } - - /* _MaxElement is one past the last legal array element */ - arrayObj->_MaxElement = min; -} - - /** * Update the following fields: * ctx->VertexProgram._Enabled @@ -690,7 +566,7 @@ _mesa_update_state_locked( struct gl_context *ctx ) } if (new_state & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) - update_arrays( ctx ); + _mesa_update_array_object_max_element(ctx, ctx->Array.ArrayObj); out: new_prog_state |= update_program_constants(ctx); -- 2.30.2