glthread: track for each VAO whether the user has set a user pointer
authorMarek Olšák <marek.olsak@amd.com>
Fri, 21 Feb 2020 00:28:56 +0000 (19:28 -0500)
committerMarge Bot <eric+marge@anholt.net>
Fri, 6 Mar 2020 01:06:14 +0000 (01:06 +0000)
This commit mainly adds basic infrastructure for tracking vertex array
state.

If glthread gets a non-VBO pointer, this commit delays disabling
glthread until glDraw is called. The next will change that to "sync"
instead of "disable".

Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3948>

16 files changed:
src/mapi/glapi/gen/ARB_base_instance.xml
src/mapi/glapi/gen/ARB_draw_instanced.xml
src/mapi/glapi/gen/ARB_indirect_parameters.xml
src/mapi/glapi/gen/ARB_vertex_array_object.xml
src/mapi/glapi/gen/ARB_vertex_attrib_64bit.xml
src/mapi/glapi/gen/EXT_direct_state_access.xml
src/mapi/glapi/gen/GL3x.xml
src/mapi/glapi/gen/es_EXT.xml
src/mapi/glapi/gen/gl_API.xml
src/mesa/Makefile.sources
src/mesa/main/glthread.c
src/mesa/main/glthread.h
src/mesa/main/glthread_varray.c [new file with mode: 0644]
src/mesa/main/marshal.c
src/mesa/main/marshal.h
src/mesa/meson.build

index 92892c290784ae24119fd71a7f8c25cb375f7d74..22c57167fd570cba398ce8bc0208ace31b947754 100644 (file)
@@ -8,7 +8,8 @@
 
 <category name="GL_ARB_base_instance" number="107">
 
-  <function name="DrawArraysInstancedBaseInstance" exec="dynamic" marshal="draw">
+  <function name="DrawArraysInstancedBaseInstance" exec="dynamic" marshal="draw"
+            marshal_fail="_mesa_glthread_is_non_vbo_draw_arrays(ctx)">
     <param name="mode" type="GLenum"/>
     <param name="first" type="GLint"/>
     <param name="count" type="GLsizei"/>
index 8d7fd6301b3efaf330c7dc9337afbc420ab8d5ca..e450f04a8e1447236149e6a870049f656fde5320 100644 (file)
@@ -8,7 +8,8 @@
 
 <category name="GL_ARB_draw_instanced" number="44">
 
-  <function name="DrawArraysInstancedARB" exec="dynamic" marshal="draw">
+  <function name="DrawArraysInstancedARB" exec="dynamic" marshal="draw"
+            marshal_fail="_mesa_glthread_is_non_vbo_draw_arrays(ctx)">
     <param name="mode" type="GLenum"/>
     <param name="first" type="GLint"/>
     <param name="count" type="GLsizei"/>
index 20de9057707706a2c5ee7ad655282eab2882d533..3938bd643bb18725d84aaccbf383b1e56a75b171 100644 (file)
@@ -8,7 +8,8 @@
     <enum name="PARAMETER_BUFFER_ARB"                   value="0x80EE"/>
     <enum name="PARAMETER_BUFFER_BINDING_ARB"           value="0x80EF"/>
 
-    <function name="MultiDrawArraysIndirectCountARB" exec="dynamic">
+    <function name="MultiDrawArraysIndirectCountARB" exec="dynamic" marshal="draw"
+              marshal_fail="_mesa_glthread_is_non_vbo_draw_arrays(ctx)">
         <param name="mode" type="GLenum"/>
         <param name="indirect" type="GLintptr"/>
         <param name="drawcount" type="GLintptr"/>
@@ -16,7 +17,9 @@
         <param name="stride" type="GLsizei"/>
     </function>
 
-    <function name="MultiDrawElementsIndirectCountARB" exec="dynamic">
+    <!-- Use "...vbo_draw_arrays", because indices always come from a buffer object. -->
+    <function name="MultiDrawElementsIndirectCountARB" exec="dynamic" marshal="draw"
+              marshal_fail="_mesa_glthread_is_non_vbo_draw_arrays(ctx)">
         <param name="mode" type="GLenum"/>
         <param name="type" type="GLenum"/>
         <param name="indirect" type="GLintptr"/>
index befa4c91c635060aab3ca37677bb15c2b8549ba3..e149997d05ce0fe315ed48d0fb454815fa3249b6 100644 (file)
     <enum name="VERTEX_ARRAY_BINDING" value="0x85B5"/>
 
     <function name="BindVertexArray" es2="3.0" no_error="true"
-              marshal_fail="_mesa_glthread_is_compat_bind_vertex_array(ctx)">
+              marshal_call_after="_mesa_glthread_BindVertexArray(ctx, array);">
         <param name="array" type="GLuint"/>
     </function>
 
-    <function name="DeleteVertexArrays" es2="3.0" no_error="true">
+    <function name="DeleteVertexArrays" es2="3.0" no_error="true"
+              marshal_call_after="_mesa_glthread_DeleteVertexArrays(ctx, n, arrays);">
         <param name="n" type="GLsizei"/>
         <param name="arrays" type="const GLuint *" count="n"/>
     </function>
 
-    <function name="GenVertexArrays" es2="3.0" no_error="true">
+    <function name="GenVertexArrays" es2="3.0" no_error="true"
+              marshal_call_after="_mesa_glthread_GenVertexArrays(ctx, n, arrays);">
         <param name="n" type="GLsizei"/>
         <param name="arrays" type="GLuint *"/>
     </function>
index d96729be3acd519c13c50843a3c168a593bd3ffb..f75387bf8fea78b90d2089e5a6323598b42d80ad 100644 (file)
@@ -52,7 +52,7 @@
     </function>
 
     <function name="VertexAttribLPointer" no_error="true" marshal="async"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="index" type="GLuint"/>
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
index 8e68ec38b9910c5ececd27fe4d21cee2f6cad155..0fe9ebcd647a634790874a9374f1ada0e3372d9a 100644 (file)
    </function>
 
    <function name="MultiTexCoordPointerEXT" marshal="async"
-             marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+             marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
       <param name="texunit" type="GLenum" />
       <param name="size" type="GLint" />
       <param name="type" type="GLenum" />
index 4bf7c1325606c145f07f102404cbaa02d6b66150..16035adc01d16a780faeaec3056edbfa7fae88db 100644 (file)
 
   <function name="VertexAttribIPointer" es2="3.0" marshal="async"
             no_error="true"
-            marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+            marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
     <param name="index" type="GLuint"/>
     <param name="size" type="GLint"/>
     <param name="type" type="GLenum"/>
index c30ad56c75dc04a3bfce5e1ebd073deade60e052..9dc1444bafec1ff1aef3207c8fc506e34f712db3 100644 (file)
 
     <function name="PointSizePointerOES" es1="1.0" desktop="false"
               no_error="true" marshal="async"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
index 256d0f3aa15756fcb7b7252569672237a566e3fa..6de88c6d7fe97ab7b46fd6208f8c5c75e7eb7ea0 100644 (file)
 
     <function name="ColorPointer" es1="1.0" deprecated="3.1" marshal="async"
               no_error="true"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="DrawArrays" es1="1.0" es2="2.0" exec="dynamic" marshal="draw">
+    <function name="DrawArrays" es1="1.0" es2="2.0" exec="dynamic" marshal="draw"
+              marshal_fail="_mesa_glthread_is_non_vbo_draw_arrays(ctx)">
         <param name="mode" type="GLenum"/>
         <param name="first" type="GLint"/>
         <param name="count" type="GLsizei"/>
 
     <function name="EdgeFlagPointer" deprecated="3.1" marshal="async"
               no_error="true"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
 
     <function name="IndexPointer" deprecated="3.1" marshal="async"
               no_error="true"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
 
     <function name="NormalPointer" es1="1.0" deprecated="3.1" marshal="async"
               no_error="true"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
 
     <function name="TexCoordPointer" es1="1.0" deprecated="3.1" marshal="async"
               no_error="true"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
 
     <function name="VertexPointer" es1="1.0" deprecated="3.1" marshal="async"
               no_error="true"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
 
     <function name="FogCoordPointer" deprecated="3.1" marshal="async"
               no_error="true"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="MultiDrawArrays" marshal="draw">
+    <function name="MultiDrawArrays" marshal="draw"
+              marshal_fail="_mesa_glthread_is_non_vbo_draw_arrays(ctx)">
         <param name="mode" type="GLenum"/>
         <param name="first" type="const GLint *" count="primcount"/>
         <param name="count" type="const GLsizei *" count="primcount"/>
 
     <function name="SecondaryColorPointer" deprecated="3.1" marshal="async"
               no_error="true"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
 
     <function name="VertexAttribPointer" es2="2.0" marshal="async"
               no_error="true"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="index" type="GLuint"/>
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
     </function>
 
     <function name="ColorPointerEXT" deprecated="3.1" marshal="async"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
     </function>
 
     <function name="EdgeFlagPointerEXT" deprecated="3.1" marshal="async"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="stride" type="GLsizei"/>
         <param name="count" type="GLsizei"/>
         <param name="pointer" type="const GLboolean *"/>
     </function>
 
     <function name="IndexPointerEXT" deprecated="3.1" marshal="async"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="count" type="GLsizei"/>
     </function>
 
     <function name="NormalPointerEXT" deprecated="3.1" marshal="async"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="count" type="GLsizei"/>
     </function>
 
     <function name="TexCoordPointerEXT" deprecated="3.1" marshal="async"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
     </function>
 
     <function name="VertexPointerEXT" deprecated="3.1" marshal="async"
-              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
+              marshal_call_after="_mesa_glthread_AttribPointer(ctx);">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
 
 <category name="GL_IBM_multimode_draw_arrays" number="200">
     <function name="MultiModeDrawArraysIBM" marshal="draw"
-              marshal_fail="_mesa_glthread_is_non_vbo_draw_elements(ctx)">
+              marshal_fail="_mesa_glthread_is_non_vbo_draw_arrays(ctx)">
         <param name="mode" type="const GLenum *" count="primcount"/>
         <param name="first" type="const GLint *" count="primcount"/>
         <param name="count" type="const GLsizei *" count="primcount"/>
index f55ae3de302be70ea0368ee3250ebe2056ae9d50..b09c019546bf12b40e640e513b361faf56280c2b 100644 (file)
@@ -125,6 +125,7 @@ MAIN_FILES = \
        main/glspirv.h \
        main/glthread.c \
        main/glthread.h \
+       main/glthread_varray.c \
        main/glheader.h \
        main/hash.c \
        main/hash.h \
index af4eb15cb4de01e9d14164d2daf972a024b3bd1f..4288c9aedbb03f00fbd980e67abbaced7e3b702b 100644 (file)
@@ -35,6 +35,7 @@
 #include "main/mtypes.h"
 #include "main/glthread.h"
 #include "main/marshal.h"
+#include "main/hash.h"
 #include "util/u_atomic.h"
 #include "util/u_thread.h"
 
@@ -85,8 +86,17 @@ _mesa_glthread_init(struct gl_context *ctx)
       return;
    }
 
+   glthread->VAOs = _mesa_NewHashTable();
+   if (!glthread->VAOs) {
+      util_queue_destroy(&glthread->queue);
+      free(glthread);
+      return;
+   }
+   glthread->CurrentVAO = &glthread->DefaultVAO;
+
    ctx->MarshalExec = _mesa_create_marshal_table(ctx);
    if (!ctx->MarshalExec) {
+      _mesa_DeleteHashTable(glthread->VAOs);
       util_queue_destroy(&glthread->queue);
       free(glthread);
       return;
@@ -110,6 +120,12 @@ _mesa_glthread_init(struct gl_context *ctx)
    util_queue_fence_destroy(&fence);
 }
 
+static void
+free_vao(GLuint key, void *data, void *userData)
+{
+   free(data);
+}
+
 void
 _mesa_glthread_destroy(struct gl_context *ctx)
 {
@@ -124,6 +140,9 @@ _mesa_glthread_destroy(struct gl_context *ctx)
    for (unsigned i = 0; i < MARSHAL_MAX_BATCHES; i++)
       util_queue_fence_destroy(&glthread->batches[i].fence);
 
+   _mesa_HashDeleteAll(glthread->VAOs, free_vao, NULL);
+   _mesa_DeleteHashTable(glthread->VAOs);
+
    free(glthread);
    ctx->GLThread = NULL;
 
index 5e99602b4188aa949d88b3a57871197f6cf1ba63..d4a680ab0388e2853ca3cefa4e769e604456f1e9 100644 (file)
 #include <inttypes.h>
 #include <stdbool.h>
 #include "util/u_queue.h"
+#include "GL/gl.h"
 
 enum marshal_dispatch_cmd_id;
 struct gl_context;
+struct _mesa_HashTable;
+
+struct glthread_vao {
+   GLuint Name;
+   bool HasUserPointer;
+   bool IndexBufferIsUserPointer;
+};
 
 /** A single batch of commands queued up for execution. */
 struct glthread_batch
@@ -83,6 +91,12 @@ struct glthread_state
    /** Index of the batch being filled and about to be submitted. */
    unsigned next;
 
+   /** Vertex Array objects tracked by glthread independently of Mesa. */
+   struct _mesa_HashTable *VAOs;
+   struct glthread_vao *CurrentVAO;
+   struct glthread_vao *LastLookedUpVAO;
+   struct glthread_vao DefaultVAO;
+
    /**
     * Tracks on the main thread side whether the current vertex array binding
     * is in a VBO.
@@ -93,7 +107,6 @@ struct glthread_state
     * Tracks on the main thread side whether the current element array (index
     * buffer) binding is in a VBO.
     */
-   bool element_array_is_vbo;
    bool draw_indirect_buffer_is_vbo;
 };
 
@@ -106,4 +119,11 @@ void _mesa_glthread_flush_batch(struct gl_context *ctx);
 void _mesa_glthread_finish(struct gl_context *ctx);
 void _mesa_glthread_finish_before(struct gl_context *ctx, const char *func);
 
+void _mesa_glthread_BindVertexArray(struct gl_context *ctx, GLuint id);
+void _mesa_glthread_DeleteVertexArrays(struct gl_context *ctx,
+                                       GLsizei n, const GLuint *ids);
+void _mesa_glthread_GenVertexArrays(struct gl_context *ctx,
+                                    GLsizei n, GLuint *arrays);
+void _mesa_glthread_AttribPointer(struct gl_context *ctx);
+
 #endif /* _GLTHREAD_H*/
diff --git a/src/mesa/main/glthread_varray.c b/src/mesa/main/glthread_varray.c
new file mode 100644 (file)
index 0000000..8786f0f
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright © 2020 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/* This implements vertex array state tracking for glthread. It's separate
+ * from the rest of Mesa. Only minimum functionality is implemented here
+ * to serve glthread.
+ */
+
+#include "main/glthread.h"
+#include "main/mtypes.h"
+#include "main/hash.h"
+#include "main/dispatch.h"
+
+/* TODO:
+ *   - Implement better tracking of user pointers
+ *   - These can unbind user pointers:
+ *       ARB_vertex_attrib_binding
+ *       ARB_direct_state_access
+ *       EXT_direct_state_access
+ */
+
+static struct glthread_vao *
+lookup_vao(struct gl_context *ctx, GLuint id)
+{
+   struct glthread_state *glthread = ctx->GLThread;
+   struct glthread_vao *vao;
+
+   assert(id != 0);
+
+   if (glthread->LastLookedUpVAO &&
+       glthread->LastLookedUpVAO->Name == id) {
+      vao = glthread->LastLookedUpVAO;
+   } else {
+      vao = _mesa_HashLookupLocked(glthread->VAOs, id);
+      if (!vao)
+         return NULL;
+
+      glthread->LastLookedUpVAO = vao;
+   }
+
+   return vao;
+}
+
+void
+_mesa_glthread_BindVertexArray(struct gl_context *ctx, GLuint id)
+{
+   struct glthread_state *glthread = ctx->GLThread;
+
+   if (id == 0) {
+      glthread->CurrentVAO = &glthread->DefaultVAO;
+   } else {
+      struct glthread_vao *vao = lookup_vao(ctx, id);
+
+      if (vao)
+         glthread->CurrentVAO = vao;
+   }
+}
+
+void
+_mesa_glthread_DeleteVertexArrays(struct gl_context *ctx,
+                                  GLsizei n, const GLuint *ids)
+{
+   struct glthread_state *glthread = ctx->GLThread;
+
+   if (!ids)
+      return;
+
+   for (int i = 0; i < n; i++) {
+      /* IDs equal to 0 should be silently ignored. */
+      if (!ids[i])
+         continue;
+
+      struct glthread_vao *vao = lookup_vao(ctx, ids[i]);
+      if (!vao)
+         continue;
+
+      /* If the array object is currently bound, the spec says "the binding
+       * for that object reverts to zero and the default vertex array
+       * becomes current."
+       */
+      if (glthread->CurrentVAO == vao)
+         glthread->CurrentVAO = &glthread->DefaultVAO;
+
+      if (glthread->LastLookedUpVAO == vao)
+         glthread->LastLookedUpVAO = NULL;
+
+      /* The ID is immediately freed for re-use */
+      _mesa_HashRemoveLocked(glthread->VAOs, vao->Name);
+      free(vao);
+   }
+}
+
+void
+_mesa_glthread_GenVertexArrays(struct gl_context *ctx,
+                               GLsizei n, GLuint *arrays)
+{
+   struct glthread_state *glthread = ctx->GLThread;
+
+   if (!arrays)
+      return;
+
+   /* The IDs have been generated at this point. Create VAOs for glthread. */
+   for (int i = 0; i < n; i++) {
+      GLuint id = arrays[i];
+      struct glthread_vao *vao;
+
+      vao = malloc(sizeof(*vao));
+      if (!vao)
+         continue; /* Is that all we can do? */
+
+      vao->Name = id;
+      vao->HasUserPointer = false;
+      _mesa_HashInsertLocked(glthread->VAOs, id, vao);
+   }
+}
+
+void
+_mesa_glthread_AttribPointer(struct gl_context *ctx)
+{
+   struct glthread_state *glthread = ctx->GLThread;
+
+   if (ctx->API != API_OPENGL_CORE && !glthread->vertex_array_is_vbo)
+      glthread->CurrentVAO->HasUserPointer = true;
+}
index ce9bbf8139f635d5d19d34c60e68edb74254e539..ce91d6a8f66ee0f8323475cccec7dbc77925a600 100644 (file)
@@ -182,7 +182,7 @@ track_vbo_binding(struct gl_context *ctx, GLenum target, GLuint buffer)
        * vertex array object instead of the context, so this would need to
        * change on vertex array object updates.
        */
-      glthread->element_array_is_vbo = (buffer != 0);
+      glthread->CurrentVAO->IndexBufferIsUserPointer = buffer != 0;
       break;
    case GL_DRAW_INDIRECT_BUFFER:
       glthread->draw_indirect_buffer_is_vbo = buffer != 0;
index 78f6fbc34f7fc0fe2708684d6a5ca2d42635241d..c53c060f593fa9169bc9005d057b64071f5e94bb 100644 (file)
@@ -74,28 +74,25 @@ _mesa_glthread_allocate_command(struct gl_context *ctx,
 }
 
 /**
- * Instead of conditionally handling marshaling previously-bound user vertex
- * array data in draw calls (deprecated and removed in GL core), we just
- * disable threading at the point where the user sets a user vertex array.
+ * Instead of conditionally handling marshaling immediate index data in draw
+ * calls (deprecated and removed in GL core), we just disable threading.
  */
 static inline bool
-_mesa_glthread_is_non_vbo_vertex_attrib_pointer(const struct gl_context *ctx)
+_mesa_glthread_is_non_vbo_draw_elements(const struct gl_context *ctx)
 {
    struct glthread_state *glthread = ctx->GLThread;
 
-   return ctx->API != API_OPENGL_CORE && !glthread->vertex_array_is_vbo;
+   return ctx->API != API_OPENGL_CORE &&
+          (glthread->CurrentVAO->IndexBufferIsUserPointer ||
+           glthread->CurrentVAO->HasUserPointer);
 }
 
-/**
- * Instead of conditionally handling marshaling immediate index data in draw
- * calls (deprecated and removed in GL core), we just disable threading.
- */
 static inline bool
-_mesa_glthread_is_non_vbo_draw_elements(const struct gl_context *ctx)
+_mesa_glthread_is_non_vbo_draw_arrays(const struct gl_context *ctx)
 {
    struct glthread_state *glthread = ctx->GLThread;
 
-   return ctx->API != API_OPENGL_CORE && !glthread->element_array_is_vbo;
+   return ctx->API != API_OPENGL_CORE && glthread->CurrentVAO->HasUserPointer;
 }
 
 static inline bool
@@ -104,7 +101,8 @@ _mesa_glthread_is_non_vbo_draw_arrays_indirect(const struct gl_context *ctx)
    struct glthread_state *glthread = ctx->GLThread;
 
    return ctx->API != API_OPENGL_CORE &&
-          !glthread->draw_indirect_buffer_is_vbo;
+          (!glthread->draw_indirect_buffer_is_vbo ||
+           glthread->CurrentVAO->HasUserPointer );
 }
 
 static inline bool
@@ -114,7 +112,8 @@ _mesa_glthread_is_non_vbo_draw_elements_indirect(const struct gl_context *ctx)
 
    return ctx->API != API_OPENGL_CORE &&
           (!glthread->draw_indirect_buffer_is_vbo ||
-           !glthread->element_array_is_vbo);
+           glthread->CurrentVAO->IndexBufferIsUserPointer ||
+           glthread->CurrentVAO->HasUserPointer);
 }
 
 #define DEBUG_MARSHAL_PRINT_CALLS 0
@@ -151,30 +150,6 @@ debug_print_marshal(const char *func)
 struct _glapi_table *
 _mesa_create_marshal_table(const struct gl_context *ctx);
 
-
-/**
- * Checks whether we're on a compat context for code-generated
- * glBindVertexArray().
- *
- * In order to decide whether a draw call uses only VBOs for vertex and index
- * buffers, we track the current vertex and index buffer bindings by
- * glBindBuffer().  However, the index buffer binding is stored in the vertex
- * array as opposed to the context.  If we were to accurately track whether
- * the index buffer was a user pointer ot not, we'd have to track it per
- * vertex array, which would mean synchronizing with the client thread and
- * looking into the hash table to find the actual vertex array object.  That's
- * more tracking than we'd like to do in the main thread, if possible.
- *
- * Instead, just punt for now and disable threading on apps using vertex
- * arrays and compat contexts.  Apps using vertex arrays can probably use a
- * core context.
- */
-static inline bool
-_mesa_glthread_is_compat_bind_vertex_array(const struct gl_context *ctx)
-{
-   return ctx->API != API_OPENGL_CORE;
-}
-
 struct marshal_cmd_ShaderSource;
 struct marshal_cmd_BindBuffer;
 struct marshal_cmd_BufferData;
index 1060cfe3388be94ef0f630490378231abfb46baf..2db8bbe8e9caae1d1c70e808821b4d58d595521c 100644 (file)
@@ -167,6 +167,7 @@ files_libmesa_common = files(
   'main/glspirv.h',
   'main/glthread.c',
   'main/glthread.h',
+  'main/glthread_varray.c',
   'main/glheader.h',
   'main/hash.c',
   'main/hash.h',