mesa: optimize glPush/PopClientAttrib for GL_CLIENT_VERTEX_ARRAY_BIT

This improves performance in torcs by 6%.

The idea is to skip saving and restoring vertex attribs and bindings that
have never been changed.

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10994>
This commit is contained in:
Marek Olšák 2021-05-25 17:09:18 -04:00 committed by Marge Bot
parent c1205a6b0f
commit 67ab6e8eb1
3 changed files with 29 additions and 9 deletions

View file

@ -1336,14 +1336,15 @@ copy_vertex_buffer_binding(struct gl_context *ctx,
static void
copy_array_object(struct gl_context *ctx,
struct gl_vertex_array_object *dest,
struct gl_vertex_array_object *src)
struct gl_vertex_array_object *src,
unsigned copy_attrib_mask)
{
GLuint i;
/* skip Name */
/* skip RefCount */
for (i = 0; i < ARRAY_SIZE(src->VertexAttrib); i++) {
while (copy_attrib_mask) {
unsigned i = u_bit_scan(&copy_attrib_mask);
copy_vertex_attrib_array(ctx, &dest->VertexAttrib[i], &src->VertexAttrib[i]);
copy_vertex_buffer_binding(ctx, &dest->BufferBinding[i], &src->BufferBinding[i]);
}
@ -1370,7 +1371,8 @@ static void
copy_array_attrib(struct gl_context *ctx,
struct gl_array_attrib *dest,
struct gl_array_attrib *src,
bool vbo_deleted)
bool vbo_deleted,
unsigned copy_attrib_mask)
{
/* skip ArrayObj */
/* skip DefaultArrayObj, Objects */
@ -1387,7 +1389,7 @@ copy_array_attrib(struct gl_context *ctx,
/* skip RebindArrays */
if (!vbo_deleted)
copy_array_object(ctx, dest->VAO, src->VAO);
copy_array_object(ctx, dest->VAO, src->VAO, copy_attrib_mask);
/* skip ArrayBufferObj */
/* skip IndexBufferObj */
@ -1404,8 +1406,9 @@ save_array_attrib(struct gl_context *ctx,
/* Set the Name, needed for restore, but do never overwrite.
* Needs to match value in the object hash. */
dest->VAO->Name = src->VAO->Name;
dest->VAO->NonDefaultStateMask = src->VAO->NonDefaultStateMask;
/* And copy all of the rest. */
copy_array_attrib(ctx, dest, src, false);
copy_array_attrib(ctx, dest, src, false, src->VAO->NonDefaultStateMask);
/* Just reference them here */
_mesa_reference_buffer_object(ctx, &dest->ArrayBufferObj,
@ -1442,13 +1445,15 @@ restore_array_attrib(struct gl_context *ctx,
if (is_vao_name_zero || !src->ArrayBufferObj ||
_mesa_IsBuffer(src->ArrayBufferObj->Name)) {
/* ... and restore its content */
copy_array_attrib(ctx, dest, src, false);
dest->VAO->NonDefaultStateMask |= src->VAO->NonDefaultStateMask;
copy_array_attrib(ctx, dest, src, false,
dest->VAO->NonDefaultStateMask);
_mesa_BindBuffer(GL_ARRAY_BUFFER_ARB,
src->ArrayBufferObj ?
src->ArrayBufferObj->Name : 0);
} else {
copy_array_attrib(ctx, dest, src, true);
copy_array_attrib(ctx, dest, src, true, 0);
}
/* Invalidate array state. It will be updated during the next draw. */

View file

@ -1609,6 +1609,15 @@ struct gl_vertex_array_object
/** Mask of VERT_BIT_* values indicating which arrays are enabled */
GLbitfield Enabled;
/**
* Mask indicating which VertexAttrib and BufferBinding structures have
* been changed since the VAO creation. No bit is ever cleared to 0 by
* state updates. Setting to the default state doesn't update this.
* (e.g. unbinding) Setting the derived state (_* fields) doesn't update
* this either.
*/
GLbitfield NonDefaultStateMask;
/**
* Mask of VERT_BIT_* enabled arrays past position/generic0 mapping
*

View file

@ -185,6 +185,7 @@ _mesa_vertex_attrib_binding(struct gl_context *ctx,
array->BufferBindingIndex = bindingIndex;
vao->NewArrays |= vao->Enabled & array_bit;
vao->NonDefaultStateMask |= array_bit | BITFIELD_BIT(bindingIndex);
}
}
@ -241,6 +242,7 @@ _mesa_bind_vertex_buffer(struct gl_context *ctx,
}
vao->NewArrays |= vao->Enabled & binding->_BoundArrays;
vao->NonDefaultStateMask |= BITFIELD_BIT(index);
}
}
@ -268,6 +270,7 @@ vertex_binding_divisor(struct gl_context *ctx,
vao->NonZeroDivisorMask &= ~binding->_BoundArrays;
vao->NewArrays |= vao->Enabled & binding->_BoundArrays;
vao->NonDefaultStateMask |= BITFIELD_BIT(bindingIndex);
}
}
@ -648,6 +651,7 @@ _mesa_update_array_format(struct gl_context *ctx,
array->Format = new_format;
vao->NewArrays |= vao->Enabled & VERT_BIT(attrib);
vao->NonDefaultStateMask |= BITFIELD_BIT(attrib);
}
/**
@ -907,6 +911,7 @@ update_array(struct gl_context *ctx,
array->Stride = stride;
array->Ptr = ptr;
vao->NewArrays |= vao->Enabled & VERT_BIT(attrib);
vao->NonDefaultStateMask |= BITFIELD_BIT(attrib);
}
/* Update the vertex buffer binding */
@ -1878,6 +1883,7 @@ _mesa_enable_vertex_array_attribs(struct gl_context *ctx,
/* was disabled, now being enabled */
vao->Enabled |= attrib_bits;
vao->NewArrays |= attrib_bits;
vao->NonDefaultStateMask |= attrib_bits;
/* Update the map mode if needed */
if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0))