Mesa (master): mesa: optimize initialization of new VAOs

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Apr 6 15:04:56 UTC 2020


Module: Mesa
Branch: master
Commit: a0a0c68150b4dbba469c62159a327ae9465f6016
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a0a0c68150b4dbba469c62159a327ae9465f6016

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Sat Mar 21 20:18:02 2020 -0400

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 at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4466>

---

 src/mesa/main/arrayobj.c | 80 +++++-------------------------------------------
 src/mesa/main/attrib.c   |  2 +-
 src/mesa/main/mtypes.h   |  3 ++
 src/mesa/main/varray.c   | 71 ++++++++++++++++++++++++++++++++++++++++++
 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;
@@ -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);



More information about the mesa-commit mailing list