mesa: optimize glPush/PopClientAttrib for GL_CLIENT_VERTEX_ARRAY_BIT
authorMarek Olšák <marek.olsak@amd.com>
Tue, 25 May 2021 21:09:18 +0000 (17:09 -0400)
committerMarge Bot <eric+marge@anholt.net>
Fri, 28 May 2021 22:15:38 +0000 (22:15 +0000)
This improves performance in torcs by 6%.

The idea is to skip saving and restoring vertex attribs and bindings that
have never been changed.

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10994>

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

index 9bf4514..e46d298 100644 (file)
@@ -1336,14 +1336,15 @@ copy_vertex_buffer_binding(struct gl_context *ctx,
 static void
 copy_array_object(struct gl_context *ctx,
                   struct gl_vertex_array_object *dest,
-                  struct gl_vertex_array_object *src)
+                  struct gl_vertex_array_object *src,
+                  unsigned copy_attrib_mask)
 {
-   GLuint i;
-
    /* skip Name */
    /* skip RefCount */
 
-   for (i = 0; i < ARRAY_SIZE(src->VertexAttrib); i++) {
+   while (copy_attrib_mask) {
+      unsigned i = u_bit_scan(&copy_attrib_mask);
+
       copy_vertex_attrib_array(ctx, &dest->VertexAttrib[i], &src->VertexAttrib[i]);
       copy_vertex_buffer_binding(ctx, &dest->BufferBinding[i], &src->BufferBinding[i]);
    }
@@ -1370,7 +1371,8 @@ static void
 copy_array_attrib(struct gl_context *ctx,
                   struct gl_array_attrib *dest,
                   struct gl_array_attrib *src,
-                  bool vbo_deleted)
+                  bool vbo_deleted,
+                  unsigned copy_attrib_mask)
 {
    /* skip ArrayObj */
    /* skip DefaultArrayObj, Objects */
@@ -1387,7 +1389,7 @@ copy_array_attrib(struct gl_context *ctx,
    /* skip RebindArrays */
 
    if (!vbo_deleted)
-      copy_array_object(ctx, dest->VAO, src->VAO);
+      copy_array_object(ctx, dest->VAO, src->VAO, copy_attrib_mask);
 
    /* skip ArrayBufferObj */
    /* skip IndexBufferObj */
@@ -1404,8 +1406,9 @@ save_array_attrib(struct gl_context *ctx,
    /* Set the Name, needed for restore, but do never overwrite.
     * Needs to match value in the object hash. */
    dest->VAO->Name = src->VAO->Name;
+   dest->VAO->NonDefaultStateMask = src->VAO->NonDefaultStateMask;
    /* And copy all of the rest. */
-   copy_array_attrib(ctx, dest, src, false);
+   copy_array_attrib(ctx, dest, src, false, src->VAO->NonDefaultStateMask);
 
    /* Just reference them here */
    _mesa_reference_buffer_object(ctx, &dest->ArrayBufferObj,
@@ -1442,13 +1445,15 @@ restore_array_attrib(struct gl_context *ctx,
    if (is_vao_name_zero || !src->ArrayBufferObj ||
        _mesa_IsBuffer(src->ArrayBufferObj->Name)) {
       /* ... and restore its content */
-      copy_array_attrib(ctx, dest, src, false);
+      dest->VAO->NonDefaultStateMask |= src->VAO->NonDefaultStateMask;
+      copy_array_attrib(ctx, dest, src, false,
+                        dest->VAO->NonDefaultStateMask);
 
       _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB,
                        src->ArrayBufferObj ?
                           src->ArrayBufferObj->Name : 0);
    } else {
-      copy_array_attrib(ctx, dest, src, true);
+      copy_array_attrib(ctx, dest, src, true, 0);
    }
 
    /* Invalidate array state. It will be updated during the next draw. */
index ab95ef2..ee1c19d 100644 (file)
@@ -1610,6 +1610,15 @@ struct gl_vertex_array_object
    GLbitfield Enabled;
 
    /**
+    * Mask indicating which VertexAttrib and BufferBinding structures have
+    * been changed since the VAO creation. No bit is ever cleared to 0 by
+    * state updates. Setting to the default state doesn't update this.
+    * (e.g. unbinding) Setting the derived state (_* fields) doesn't update
+    * this either.
+    */
+   GLbitfield NonDefaultStateMask;
+
+   /**
     * Mask of VERT_BIT_* enabled arrays past position/generic0 mapping
     *
     * The value is valid past calling _mesa_update_vao_derived_arrays.
index f9fc598..ad34e44 100644 (file)
@@ -185,6 +185,7 @@ _mesa_vertex_attrib_binding(struct gl_context *ctx,
       array->BufferBindingIndex = bindingIndex;
 
       vao->NewArrays |= vao->Enabled & array_bit;
+      vao->NonDefaultStateMask |= array_bit | BITFIELD_BIT(bindingIndex);
    }
 }
 
@@ -241,6 +242,7 @@ _mesa_bind_vertex_buffer(struct gl_context *ctx,
       }
 
       vao->NewArrays |= vao->Enabled & binding->_BoundArrays;
+      vao->NonDefaultStateMask |= BITFIELD_BIT(index);
    }
 }
 
@@ -268,6 +270,7 @@ vertex_binding_divisor(struct gl_context *ctx,
          vao->NonZeroDivisorMask &= ~binding->_BoundArrays;
 
       vao->NewArrays |= vao->Enabled & binding->_BoundArrays;
+      vao->NonDefaultStateMask |= BITFIELD_BIT(bindingIndex);
    }
 }
 
@@ -648,6 +651,7 @@ _mesa_update_array_format(struct gl_context *ctx,
    array->Format = new_format;
 
    vao->NewArrays |= vao->Enabled & VERT_BIT(attrib);
+   vao->NonDefaultStateMask |= BITFIELD_BIT(attrib);
 }
 
 /**
@@ -907,6 +911,7 @@ update_array(struct gl_context *ctx,
       array->Stride = stride;
       array->Ptr = ptr;
       vao->NewArrays |= vao->Enabled & VERT_BIT(attrib);
+      vao->NonDefaultStateMask |= BITFIELD_BIT(attrib);
    }
 
    /* Update the vertex buffer binding */
@@ -1878,6 +1883,7 @@ _mesa_enable_vertex_array_attribs(struct gl_context *ctx,
       /* was disabled, now being enabled */
       vao->Enabled |= attrib_bits;
       vao->NewArrays |= attrib_bits;
+      vao->NonDefaultStateMask |= attrib_bits;
 
       /* Update the map mode if needed */
       if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0))