aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2020-03-21 20:18:02 -0400
committerMarek Olšák <[email protected]>2020-04-06 10:27:59 -0400
commita0a0c68150b4dbba469c62159a327ae9465f6016 (patch)
tree9bae5b98e11c883794c7116f2f79463bc056ffd0
parentdbdd0149ed5b28730a31ebc2bc49f8e955523bbb (diff)
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 <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4466>
-rw-r--r--src/mesa/main/arrayobj.c80
-rw-r--r--src/mesa/main/attrib.c2
-rw-r--r--src/mesa/main/mtypes.h3
-rw-r--r--src/mesa/main/varray.c71
4 files changed, 83 insertions, 73 deletions
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;
@@ -386,43 +386,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.
*/
void
@@ -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);