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:
parent
dbdd0149ed
commit
a0a0c68150
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue