mesa: Fix and speedup gl_array_object::_MaxElement computation.

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 <Mathias.Froehlich@web.de>
Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
Mathias Fröhlich
2011-12-29 13:10:01 +01:00
committed by Mathias Fröhlich
parent 2a207c4bf9
commit 7a1e941ebe
2 changed files with 27 additions and 138 deletions

View File

@@ -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;
GLbitfield64 enabled;
while (enabled) {
GLint attrib = ffsll(enabled) - 1;
enabled &= ~BITFIELD64_BIT(attrib);
min = update_min(min, &arrayObj->VertexAttrib[attrib]);
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);
}