mesa: optimize initialization of new VAOs
authorMarek Olšák <marek.olsak@amd.com>
Sun, 22 Mar 2020 00:18:02 +0000 (20:18 -0400)
committerMarek Olšák <marek.olsak@amd.com>
Mon, 6 Apr 2020 14:27:59 +0000 (10:27 -0400)
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>

src/mesa/main/arrayobj.c
src/mesa/main/attrib.c
src/mesa/main/mtypes.h
src/mesa/main/varray.c

index 371ca7b04e37aa0ede9fe5daf169d2a054dcddc8..2c2c164123d62307d2ea4538c3afb0748e8a13f9 100644 (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);
+   }
 }
 
 
index c39412e9fe0ab3cb1140718fab0808e28619d0d3..ce6c519737fccdfd6dd05a05d2ce62d2b6d8659c 100644 (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");
index 7b52a2528fd310915d9eeae903913d27001b82d0..33adf42ae5458ffa2b3c5c0251efe4c015be4417 100644 (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;
 
index 3c9c6f3d31ad11db02c71cb0872258d2ebcdad39..df63e556a36d8ff1775eb16525d59b987f123a22 100644 (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);