mesa: optimize initialization of new VAOs

Precompute the default state in gl_context, and just copy it when we create
a VAO.

This also helps glPushClientAttrib function, which always creates a VAO,
which has a substantial CPU overhead in profiles.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4466>
This commit is contained in:
Marek Olšák 2020-03-21 20:18:02 -04:00
parent dbdd0149ed
commit a0a0c68150
4 changed files with 83 additions and 73 deletions

View File

@ -319,7 +319,7 @@ unbind_array_object_vbos(struct gl_context *ctx, struct gl_vertex_array_object *
struct gl_vertex_array_object *
_mesa_new_vao(struct gl_context *ctx, GLuint name)
{
struct gl_vertex_array_object *obj = CALLOC_STRUCT(gl_vertex_array_object);
struct gl_vertex_array_object *obj = MALLOC_STRUCT(gl_vertex_array_object);
if (obj)
_mesa_initialize_vao(ctx, obj, name);
return obj;
@ -385,43 +385,6 @@ _mesa_reference_vao_(struct gl_context *ctx,
}
/**
* Initialize attributes of a vertex array within a vertex array object.
* \param vao the container vertex array object
* \param index which array in the VAO to initialize
* \param size number of components (1, 2, 3 or 4) per attribute
* \param type datatype of the attribute (GL_FLOAT, GL_INT, etc).
*/
static void
init_array(struct gl_context *ctx,
struct gl_vertex_array_object *vao,
gl_vert_attrib index, GLint size, GLint type)
{
assert(index < ARRAY_SIZE(vao->VertexAttrib));
struct gl_array_attributes *array = &vao->VertexAttrib[index];
assert(index < ARRAY_SIZE(vao->BufferBinding));
struct gl_vertex_buffer_binding *binding = &vao->BufferBinding[index];
_mesa_set_vertex_format(&array->Format, size, type, GL_RGBA,
GL_FALSE, GL_FALSE, GL_FALSE);
array->Stride = 0;
array->Ptr = NULL;
array->RelativeOffset = 0;
ASSERT_BITFIELD_SIZE(struct gl_array_attributes, BufferBindingIndex,
VERT_ATTRIB_MAX - 1);
array->BufferBindingIndex = index;
binding->Offset = 0;
binding->Stride = array->Format._ElementSize;
binding->BufferObj = NULL;
binding->_BoundArrays = BITFIELD_BIT(index);
/* Vertex array buffers */
_mesa_reference_buffer_object(ctx, &binding->BufferObj,
ctx->Shared->NullBufferObj);
}
/**
* Initialize a gl_vertex_array_object's arrays.
*/
@ -430,44 +393,17 @@ _mesa_initialize_vao(struct gl_context *ctx,
struct gl_vertex_array_object *vao,
GLuint name)
{
GLuint i;
memcpy(vao, &ctx->Array.DefaultVAOState, sizeof(*vao));
vao->Name = name;
vao->RefCount = 1;
vao->SharedAndImmutable = false;
/* Init the individual arrays */
for (i = 0; i < ARRAY_SIZE(vao->VertexAttrib); i++) {
switch (i) {
case VERT_ATTRIB_NORMAL:
init_array(ctx, vao, VERT_ATTRIB_NORMAL, 3, GL_FLOAT);
break;
case VERT_ATTRIB_COLOR1:
init_array(ctx, vao, VERT_ATTRIB_COLOR1, 3, GL_FLOAT);
break;
case VERT_ATTRIB_FOG:
init_array(ctx, vao, VERT_ATTRIB_FOG, 1, GL_FLOAT);
break;
case VERT_ATTRIB_COLOR_INDEX:
init_array(ctx, vao, VERT_ATTRIB_COLOR_INDEX, 1, GL_FLOAT);
break;
case VERT_ATTRIB_EDGEFLAG:
init_array(ctx, vao, VERT_ATTRIB_EDGEFLAG, 1, GL_UNSIGNED_BYTE);
break;
case VERT_ATTRIB_POINT_SIZE:
init_array(ctx, vao, VERT_ATTRIB_POINT_SIZE, 1, GL_FLOAT);
break;
default:
init_array(ctx, vao, i, 4, GL_FLOAT);
break;
}
}
vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_IDENTITY;
_mesa_reference_buffer_object(ctx, &vao->IndexBufferObj,
ctx->Shared->NullBufferObj);
/* Vertex array buffers */
for (unsigned i = 0; i < ARRAY_SIZE(vao->BufferBinding); i++) {
_mesa_reference_buffer_object(ctx, &vao->BufferBinding[i].BufferObj,
ctx->Shared->NullBufferObj);
}
}

View File

@ -1692,7 +1692,7 @@ init_array_attrib_data(struct gl_context *ctx,
struct gl_array_attrib *attrib)
{
/* Get a non driver gl_vertex_array_object. */
attrib->VAO = CALLOC_STRUCT(gl_vertex_array_object);
attrib->VAO = MALLOC_STRUCT(gl_vertex_array_object);
if (attrib->VAO == NULL) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");

View File

@ -1591,6 +1591,9 @@ struct gl_array_attrib
/** The last VAO accessed by a DSA function */
struct gl_vertex_array_object *LastLookedUpVAO;
/** These contents are copied to newly created VAOs. */
struct gl_vertex_array_object DefaultVAOState;
/** Array objects (GL_ARB_vertex_array_object) */
struct _mesa_HashTable *Objects;

View File

@ -3788,6 +3788,75 @@ _mesa_print_arrays(struct gl_context *ctx)
}
}
/**
* Initialize attributes of a vertex array within a vertex array object.
* \param vao the container vertex array object
* \param index which array in the VAO to initialize
* \param size number of components (1, 2, 3 or 4) per attribute
* \param type datatype of the attribute (GL_FLOAT, GL_INT, etc).
*/
static void
init_array(struct gl_context *ctx,
struct gl_vertex_array_object *vao,
gl_vert_attrib index, GLint size, GLint type)
{
assert(index < ARRAY_SIZE(vao->VertexAttrib));
struct gl_array_attributes *array = &vao->VertexAttrib[index];
assert(index < ARRAY_SIZE(vao->BufferBinding));
struct gl_vertex_buffer_binding *binding = &vao->BufferBinding[index];
_mesa_set_vertex_format(&array->Format, size, type, GL_RGBA,
GL_FALSE, GL_FALSE, GL_FALSE);
array->Stride = 0;
array->Ptr = NULL;
array->RelativeOffset = 0;
ASSERT_BITFIELD_SIZE(struct gl_array_attributes, BufferBindingIndex,
VERT_ATTRIB_MAX - 1);
array->BufferBindingIndex = index;
binding->Offset = 0;
binding->Stride = array->Format._ElementSize;
binding->BufferObj = NULL;
binding->_BoundArrays = BITFIELD_BIT(index);
}
static void
init_default_vao_state(struct gl_context *ctx)
{
struct gl_vertex_array_object *vao = &ctx->Array.DefaultVAOState;
vao->RefCount = 1;
vao->SharedAndImmutable = false;
/* Init the individual arrays */
for (unsigned i = 0; i < ARRAY_SIZE(vao->VertexAttrib); i++) {
switch (i) {
case VERT_ATTRIB_NORMAL:
init_array(ctx, vao, VERT_ATTRIB_NORMAL, 3, GL_FLOAT);
break;
case VERT_ATTRIB_COLOR1:
init_array(ctx, vao, VERT_ATTRIB_COLOR1, 3, GL_FLOAT);
break;
case VERT_ATTRIB_FOG:
init_array(ctx, vao, VERT_ATTRIB_FOG, 1, GL_FLOAT);
break;
case VERT_ATTRIB_COLOR_INDEX:
init_array(ctx, vao, VERT_ATTRIB_COLOR_INDEX, 1, GL_FLOAT);
break;
case VERT_ATTRIB_EDGEFLAG:
init_array(ctx, vao, VERT_ATTRIB_EDGEFLAG, 1, GL_UNSIGNED_BYTE);
break;
case VERT_ATTRIB_POINT_SIZE:
init_array(ctx, vao, VERT_ATTRIB_POINT_SIZE, 1, GL_FLOAT);
break;
default:
init_array(ctx, vao, i, 4, GL_FLOAT);
break;
}
}
vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_IDENTITY;
}
/**
* Initialize vertex array state for given context.
@ -3795,6 +3864,8 @@ _mesa_print_arrays(struct gl_context *ctx)
void
_mesa_init_varray(struct gl_context *ctx)
{
init_default_vao_state(ctx);
ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0);
_mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO);
ctx->Array._EmptyVAO = _mesa_new_vao(ctx, ~0u);