From: Marek Olšák Date: Sun, 22 Mar 2020 00:18:02 +0000 (-0400) Subject: mesa: optimize initialization of new VAOs X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a0a0c68150b4dbba469c62159a327ae9465f6016;p=mesa.git 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 Part-of: --- diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index 371ca7b04e3..2c2c164123d 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -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); + } } diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index c39412e9fe0..ce6c519737f 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -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"); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 7b52a2528fd..33adf42ae54 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -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; diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 3c9c6f3d31a..df63e556a36 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -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);