mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
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:
parent
c1205a6b0f
commit
67ab6e8eb1
3 changed files with 29 additions and 9 deletions
|
|
@ -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(©_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. */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue