[Mesa-dev] [PATCH 22/25] mesa: Track the current vertex/element array buffers for glthread.

Timothy Arceri tarceri at itsqueeze.com
Tue Mar 7 06:21:34 UTC 2017


From: Eric Anholt <eric at anholt.net>

We want to support glthread on GLES contexts with reasonable apps, and on
desktop for apps that use VBOs but haven't completely moved to core GL.
To do so, we have to deal with the "the user may or may not pass user
pointers to draw calls" problem.
---
 src/mapi/glapi/gen/ARB_base_instance.xml           |   9 +-
 .../glapi/gen/ARB_draw_elements_base_vertex.xml    |  12 ++-
 src/mapi/glapi/gen/ARB_draw_instanced.xml          |   3 +-
 src/mapi/glapi/gen/ARB_vertex_array_object.xml     |   3 +-
 src/mapi/glapi/gen/GL3x.xml                        |   3 +-
 src/mapi/glapi/gen/gl_API.xml                      |  59 ++++++++----
 src/mapi/glapi/gen/gl_marshal.py                   |   4 -
 src/mesa/main/glthread.h                           |  12 +++
 src/mesa/main/marshal.c                            | 103 +++++++++++++++++++++
 src/mesa/main/marshal.h                            |  57 ++++++++++++
 10 files changed, 231 insertions(+), 34 deletions(-)

diff --git a/src/mapi/glapi/gen/ARB_base_instance.xml b/src/mapi/glapi/gen/ARB_base_instance.xml
index 5bd6cab..e3bbcd1 100644
--- a/src/mapi/glapi/gen/ARB_base_instance.xml
+++ b/src/mapi/glapi/gen/ARB_base_instance.xml
@@ -1,38 +1,41 @@
 <?xml version="1.0"?>
 <!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
 
 <!-- Note: no GLX protocol info yet. -->
 
 
 <OpenGLAPI>
 
 <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_elements(ctx)">
     <param name="mode" type="GLenum"/>
     <param name="first" type="GLint"/>
     <param name="count" type="GLsizei"/>
     <param name="primcount" type="GLsizei"/>
     <param name="baseinstance" type="GLuint"/>
   </function>
 
-  <function name="DrawElementsInstancedBaseInstance" exec="dynamic" marshal="draw">
+  <function name="DrawElementsInstancedBaseInstance" exec="dynamic" marshal="draw"
+            marshal_fail="_mesa_glthread_is_non_vbo_draw_elements(ctx)">
     <param name="mode" type="GLenum"/>
     <param name="count" type="GLsizei"/>
     <param name="type" type="GLenum"/>
     <param name="indices" type="const GLvoid *"/>
     <param name="primcount" type="GLsizei"/>
     <param name="baseinstance" type="GLuint"/>
   </function>
 
-  <function name="DrawElementsInstancedBaseVertexBaseInstance" exec="dynamic" marshal="draw">
+  <function name="DrawElementsInstancedBaseVertexBaseInstance" exec="dynamic" marshal="draw"
+            marshal_fail="_mesa_glthread_is_non_vbo_draw_elements(ctx)">
     <param name="mode" type="GLenum"/>
     <param name="count" type="GLsizei"/>
     <param name="type" type="GLenum"/>
     <param name="indices" type="const GLvoid *"/>
     <param name="primcount" type="GLsizei"/>
     <param name="basevertex" type="GLint"/>
     <param name="baseinstance" type="GLuint"/>
   </function>
 
 </category>
diff --git a/src/mapi/glapi/gen/ARB_draw_elements_base_vertex.xml b/src/mapi/glapi/gen/ARB_draw_elements_base_vertex.xml
index 7c7a6a4..2f1a93d 100644
--- a/src/mapi/glapi/gen/ARB_draw_elements_base_vertex.xml
+++ b/src/mapi/glapi/gen/ARB_draw_elements_base_vertex.xml
@@ -1,48 +1,52 @@
 <?xml version="1.0"?>
 <!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
 
 <!-- Note: no GLX protocol info yet. -->
 
 
 <OpenGLAPI>
 
 <category name="GL_ARB_draw_elements_base_vertex" number="62">
 
-    <function name="DrawElementsBaseVertex" es2="3.2" exec="dynamic" marshal="draw">
+    <function name="DrawElementsBaseVertex" es2="3.2" exec="dynamic" marshal="draw"
+              marshal_fail="_mesa_glthread_is_non_vbo_draw_elements(ctx)">
         <param name="mode" type="GLenum"/>
         <param name="count" type="GLsizei"/>
         <param name="type" type="GLenum"/>
         <param name="indices" type="const GLvoid *"/>
         <param name="basevertex" type="GLint"/>
     </function>
 
-    <function name="DrawRangeElementsBaseVertex" es2="3.2" exec="dynamic" marshal="draw">
+    <function name="DrawRangeElementsBaseVertex" es2="3.2" exec="dynamic" marshal="draw"
+              marshal_fail="_mesa_glthread_is_non_vbo_draw_elements(ctx)">
         <param name="mode" type="GLenum"/>
         <param name="start" type="GLuint"/>
         <param name="end" type="GLuint"/>
         <param name="count" type="GLsizei"/>
         <param name="type" type="GLenum"/>
         <param name="indices" type="const GLvoid *"/>
         <param name="basevertex" type="GLint"/>
     </function>
 
-    <function name="MultiDrawElementsBaseVertex" exec="dynamic" marshal="draw">
+    <function name="MultiDrawElementsBaseVertex" exec="dynamic" marshal="draw"
+              marshal_fail="_mesa_glthread_is_non_vbo_draw_elements(ctx)">
         <param name="mode" type="GLenum"/>
         <param name="count" type="const GLsizei *"/>
         <param name="type" type="GLenum"/>
         <param name="indices" type="const GLvoid * const *"/>
         <param name="primcount" type="GLsizei"/>
         <param name="basevertex" type="const GLint *"/>
     </function>
 
-    <function name="DrawElementsInstancedBaseVertex" es2="3.2" exec="dynamic" marshal="draw">
+    <function name="DrawElementsInstancedBaseVertex" es2="3.2" exec="dynamic" marshal="draw"
+              marshal_fail="_mesa_glthread_is_non_vbo_draw_elements(ctx)">
         <param name="mode" type="GLenum"/>
         <param name="count" type="GLsizei"/>
         <param name="type" type="GLenum"/>
         <param name="indices" type="const GLvoid *"/>
         <param name="primcount" type="GLsizei"/>
         <param name="basevertex" type="GLint"/>
     </function>
 
 </category>
 
diff --git a/src/mapi/glapi/gen/ARB_draw_instanced.xml b/src/mapi/glapi/gen/ARB_draw_instanced.xml
index 52dba3c..8d7fd63 100644
--- a/src/mapi/glapi/gen/ARB_draw_instanced.xml
+++ b/src/mapi/glapi/gen/ARB_draw_instanced.xml
@@ -8,21 +8,22 @@
 
 <category name="GL_ARB_draw_instanced" number="44">
 
   <function name="DrawArraysInstancedARB" exec="dynamic" marshal="draw">
     <param name="mode" type="GLenum"/>
     <param name="first" type="GLint"/>
     <param name="count" type="GLsizei"/>
     <param name="primcount" type="GLsizei"/>
   </function>
 
-  <function name="DrawElementsInstancedARB" exec="dynamic" marshal="draw">
+  <function name="DrawElementsInstancedARB" exec="dynamic" marshal="draw"
+            marshal_fail="_mesa_glthread_is_non_vbo_draw_elements(ctx)">
     <param name="mode" type="GLenum"/>
     <param name="count" type="GLsizei"/>
     <param name="type" type="GLenum"/>
     <param name="indices" type="const GLvoid *"/>
     <param name="primcount" type="GLsizei"/>
   </function>
 
 </category>
 
 
diff --git a/src/mapi/glapi/gen/ARB_vertex_array_object.xml b/src/mapi/glapi/gen/ARB_vertex_array_object.xml
index 4a392db..4f21137 100644
--- a/src/mapi/glapi/gen/ARB_vertex_array_object.xml
+++ b/src/mapi/glapi/gen/ARB_vertex_array_object.xml
@@ -3,21 +3,22 @@
 
 <!-- Note: no GLX protocol info yet. -->
 
 
 <OpenGLAPI>
 
 <category name="GL_ARB_vertex_array_object" number="54">
 
     <enum name="VERTEX_ARRAY_BINDING" value="0x85B5"/>
 
-    <function name="BindVertexArray" es2="3.0">
+    <function name="BindVertexArray" es2="3.0"
+              marshal_fail="_mesa_glthread_is_compat_bind_vertex_array(ctx)">
         <param name="array" type="GLuint"/>
     </function>
 
     <function name="DeleteVertexArrays" es2="3.0">
         <param name="n" type="GLsizei"/>
         <param name="arrays" type="const GLuint *" count="n"/>
     </function>
 
     <function name="GenVertexArrays" es2="3.0">
         <param name="n" type="GLsizei"/>
diff --git a/src/mapi/glapi/gen/GL3x.xml b/src/mapi/glapi/gen/GL3x.xml
index 65f12a4..b603e1f 100644
--- a/src/mapi/glapi/gen/GL3x.xml
+++ b/src/mapi/glapi/gen/GL3x.xml
@@ -249,21 +249,22 @@
   <function name="BeginConditionalRender">
     <param name="query" type="GLuint"/>
     <param name="mode" type="GLenum"/>
   </function>
 
   <function name="EndConditionalRender">
   </function>
 
   <!-- These functions alias ones from GL_EXT_gpu_shader4 -->
 
-  <function name="VertexAttribIPointer" es2="3.0" marshal="async">
+  <function name="VertexAttribIPointer" es2="3.0" marshal="async"
+            marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
     <param name="index" type="GLuint"/>
     <param name="size" type="GLint"/>
     <param name="type" type="GLenum"/>
     <param name="stride" type="GLsizei"/>
     <param name="pointer" type="const GLvoid *"/>
   </function>
 
   <function name="GetVertexAttribIiv" es2="3.0">
     <param name="index" type="GLuint"/>
     <param name="pname" type="GLenum"/>
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index ae1c9ea..c94cccc 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -3146,95 +3146,102 @@
     <enum name="EDGE_FLAG_ARRAY_POINTER"                  value="0x8093"/>
     <enum name="CLIENT_PIXEL_STORE_BIT"                   value="0x00000001"/>
     <enum name="CLIENT_VERTEX_ARRAY_BIT"                  value="0x00000002"/>
     <enum name="CLIENT_ALL_ATTRIB_BITS"                   value="0xFFFFFFFF"/>
 
     <function name="ArrayElement" deprecated="3.1" exec="dynamic" marshal="draw">
         <param name="i" type="GLint"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="ColorPointer" es1="1.0" deprecated="3.1" marshal="async">
+    <function name="ColorPointer" es1="1.0" deprecated="3.1" marshal="async"
+              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
     <function name="DisableClientState" es1="1.0" deprecated="3.1">
         <param name="array" type="GLenum"/>
         <glx handcode="true"/>
     </function>
 
     <function name="DrawArrays" es1="1.0" es2="2.0" exec="dynamic" marshal="draw">
         <param name="mode" type="GLenum"/>
         <param name="first" type="GLint"/>
         <param name="count" type="GLsizei"/>
         <glx rop="193" handcode="true"/>
     </function>
 
-    <function name="DrawElements" es1="1.0" es2="2.0" exec="dynamic" marshal="draw">
+    <function name="DrawElements" es1="1.0" es2="2.0" exec="dynamic" marshal="draw"
+              marshal_fail="_mesa_glthread_is_non_vbo_draw_elements(ctx)">
         <param name="mode" type="GLenum"/>
         <param name="count" type="GLsizei"/>
         <param name="type" type="GLenum"/>
         <param name="indices" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="EdgeFlagPointer" deprecated="3.1" marshal="async">
+    <function name="EdgeFlagPointer" deprecated="3.1" marshal="async"
+              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
     <function name="EnableClientState" es1="1.0" deprecated="3.1">
         <param name="array" type="GLenum"/>
         <glx handcode="true"/>
     </function>
 
     <function name="GetPointerv" es1="1.1" es2="3.2">
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLvoid **" output="true"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="IndexPointer" deprecated="3.1" marshal="async">
+    <function name="IndexPointer" deprecated="3.1" marshal="async"
+              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
     <function name="InterleavedArrays" deprecated="3.1">
         <param name="format" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="NormalPointer" es1="1.0" deprecated="3.1" marshal="async">
+    <function name="NormalPointer" es1="1.0" deprecated="3.1" marshal="async"
+              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="TexCoordPointer" es1="1.0" deprecated="3.1" marshal="async">
+    <function name="TexCoordPointer" es1="1.0" deprecated="3.1" marshal="async"
+              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="VertexPointer" es1="1.0" deprecated="3.1" marshal="async">
+    <function name="VertexPointer" es1="1.0" deprecated="3.1" marshal="async"
+              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
     <function name="PolygonOffset" es1="1.0" es2="2.0">
         <param name="factor" type="GLfloat"/>
         <param name="units" type="GLfloat"/>
@@ -3723,21 +3730,22 @@
         <param name="blue" type="GLclampf"/>
         <param name="alpha" type="GLclampf"/>
         <glx rop="4096"/>
     </function>
 
     <function name="BlendEquation" es2="2.0">
         <param name="mode" type="GLenum"/>
         <glx rop="4097"/>
     </function>
 
-    <function name="DrawRangeElements" es2="3.0" exec="dynamic" marshal="draw">
+    <function name="DrawRangeElements" es2="3.0" exec="dynamic" marshal="draw"
+              marshal_fail="_mesa_glthread_is_non_vbo_draw_elements(ctx)">
         <param name="mode" type="GLenum"/>
         <param name="start" type="GLuint"/>
         <param name="end" type="GLuint"/>
         <param name="count" type="GLsizei"/>
         <param name="type" type="GLenum"/>
         <param name="indices" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
     <function name="ColorTable" deprecated="3.1">
@@ -4709,21 +4717,22 @@
 
     <function name="FogCoordd" deprecated="3.1">
         <param name="coord" type="GLdouble"/>
     </function>
 
     <function name="FogCoorddv" deprecated="3.1">
         <param name="coord" type="const GLdouble *" count="1"/>
         <glx rop="4125"/>
     </function>
 
-    <function name="FogCoordPointer" deprecated="3.1" marshal="async">
+    <function name="FogCoordPointer" deprecated="3.1" marshal="async"
+              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(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">
         <param name="mode" type="GLenum"/>
         <param name="first" type="const GLint *"/>
         <param name="count" type="const GLsizei *"/>
@@ -4845,21 +4854,22 @@
         <param name="red" type="GLushort"/>
         <param name="green" type="GLushort"/>
         <param name="blue" type="GLushort"/>
     </function>
 
     <function name="SecondaryColor3usv" deprecated="3.1">
         <param name="v" type="const GLushort *" count="3"/>
         <glx rop="4132"/>
     </function>
 
-    <function name="SecondaryColorPointer" deprecated="3.1" marshal="async">
+    <function name="SecondaryColorPointer" deprecated="3.1" marshal="async"
+              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
     <function name="WindowPos2d" deprecated="3.1">
         <param name="x" type="GLdouble"/>
         <param name="y" type="GLdouble"/>
@@ -5010,21 +5020,21 @@
     <enum name="SRC0_RGB"                                 value="0x8580"/>
     <enum name="SRC1_RGB"                                 value="0x8581"/>
     <enum name="SRC2_RGB"                                 value="0x8582"/>
     <enum name="SRC0_ALPHA"                               value="0x8588"/>
     <enum name="SRC1_ALPHA"                               value="0x8589"/>
     <enum name="SRC2_ALPHA"                               value="0x858A"/>
 
     <type name="intptr"   size="4"                  glx_name="CARD32"/>
     <type name="sizeiptr" size="4"  unsigned="true" glx_name="CARD32"/>
 
-    <function name="BindBuffer" es1="1.1" es2="2.0">
+    <function name="BindBuffer" es1="1.1" es2="2.0" marshal="custom">
         <param name="target" type="GLenum"/>
         <param name="buffer" type="GLuint"/>
         <glx ignore="true"/>
     </function>
 
     <function name="BufferData" es1="1.1" es2="2.0">
         <param name="target" type="GLenum"/>
         <param name="size" type="GLsizeiptr" counter="true"/>
         <param name="data" type="const GLvoid *" count="size" img_null_flag="true"/>
         <param name="usage" type="GLenum"/>
@@ -5799,21 +5809,22 @@
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLuint *" count="4"/>
         <glx rop="4234"/>
     </function>
     <function name="VertexAttrib4usv">
         <param name="index" type="GLuint"/>
         <param name="v" type="const GLushort *" count="4"/>
         <glx rop="4233"/>
     </function>
 
-    <function name="VertexAttribPointer" es2="2.0" marshal="async">
+    <function name="VertexAttribPointer" es2="2.0" marshal="async"
+              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
         <param name="index" type="GLuint"/>
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="normalized" type="GLboolean"/>
         <param name="stride" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
 </category>
@@ -9172,73 +9183,79 @@
     <enum name="COLOR_ARRAY_COUNT_EXT"                    value="0x8084"/>
     <enum name="INDEX_ARRAY_COUNT_EXT"                    value="0x8087"/>
     <enum name="TEXTURE_COORD_ARRAY_COUNT_EXT"            value="0x808B"/>
     <enum name="EDGE_FLAG_ARRAY_COUNT_EXT"                value="0x808D"/>
 
 
     <function name="ArrayElementEXT" alias="ArrayElement">
         <param name="i" type="GLint"/>
     </function>
 
-    <function name="ColorPointerEXT" deprecated="3.1" marshal="async">
+    <function name="ColorPointerEXT" deprecated="3.1" marshal="async"
+              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="count" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
     <function name="DrawArraysEXT" alias="DrawArrays">
         <param name="mode" type="GLenum"/>
         <param name="first" type="GLint"/>
         <param name="count" type="GLsizei"/>
     </function>
 
-    <function name="EdgeFlagPointerEXT" deprecated="3.1" marshal="async">
+    <function name="EdgeFlagPointerEXT" deprecated="3.1" marshal="async"
+              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
         <param name="stride" type="GLsizei"/>
         <param name="count" type="GLsizei"/>
         <param name="pointer" type="const GLboolean *"/>
         <glx handcode="true"/>
     </function>
 
     <function name="GetPointervEXT" alias="GetPointerv">
         <param name="pname" type="GLenum"/>
         <param name="params" type="GLvoid **" output="true"/>
     </function>
 
-    <function name="IndexPointerEXT" deprecated="3.1" marshal="async">
+    <function name="IndexPointerEXT" deprecated="3.1" marshal="async"
+              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="count" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="NormalPointerEXT" deprecated="3.1" marshal="async">
+    <function name="NormalPointerEXT" deprecated="3.1" marshal="async"
+              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="count" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="TexCoordPointerEXT" deprecated="3.1" marshal="async">
+    <function name="TexCoordPointerEXT" deprecated="3.1" marshal="async"
+              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="count" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 
-    <function name="VertexPointerEXT" deprecated="3.1" marshal="async">
+    <function name="VertexPointerEXT" deprecated="3.1" marshal="async"
+              marshal_fail="_mesa_glthread_is_non_vbo_vertex_attrib_pointer(ctx)">
         <param name="size" type="GLint"/>
         <param name="type" type="GLenum"/>
         <param name="stride" type="GLsizei"/>
         <param name="count" type="GLsizei"/>
         <param name="pointer" type="const GLvoid *"/>
         <glx handcode="true"/>
     </function>
 </category>
 
 <category name="GL_SGIS_generate_mipmap" number="32">
@@ -10199,21 +10216,22 @@
 </category>
 
 <category name="GL_EXT_multi_draw_arrays" number="148">
     <function name="MultiDrawArraysEXT" es1="1.0" es2="2.0" alias="MultiDrawArrays">
         <param name="mode" type="GLenum"/>
         <param name="first" type="const GLint *"/>
         <param name="count" type="const GLsizei *"/>
         <param name="primcount" type="GLsizei"/>
     </function>
 
-    <function name="MultiDrawElementsEXT" es1="1.0" es2="2.0" exec="dynamic" marshal="draw">
+    <function name="MultiDrawElementsEXT" es1="1.0" es2="2.0" exec="dynamic" marshal="draw"
+              marshal_fail="_mesa_glthread_is_non_vbo_draw_elements(ctx)">
         <param name="mode" type="GLenum"/>
         <param name="count" type="const GLsizei *"/>
         <param name="type" type="GLenum"/>
         <param name="indices" type="const GLvoid * const *"/>
         <param name="primcount" type="GLsizei"/>
         <glx handcode="true"/>
     </function>
 </category>
 
 <category name="GL_EXT_fog_coord" number="149">
@@ -11218,21 +11236,22 @@
 <category name="GL_IBM_multimode_draw_arrays" number="200">
     <function name="MultiModeDrawArraysIBM" marshal="draw">
         <param name="mode" type="const GLenum *"/>
         <param name="first" type="const GLint *"/>
         <param name="count" type="const GLsizei *"/>
         <param name="primcount" type="GLsizei"/>
         <param name="modestride" type="GLint"/>
         <glx handcode="true" ignore="true"/>
     </function>
 
-    <function name="MultiModeDrawElementsIBM" marshal="draw">
+    <function name="MultiModeDrawElementsIBM" marshal="draw"
+              marshal_fail="_mesa_glthread_is_non_vbo_draw_elements(ctx)">
         <param name="mode" type="const GLenum *"/>
         <param name="count" type="const GLsizei *"/>
         <param name="type" type="GLenum"/>
         <param name="indices" type="const GLvoid * const *"/>
         <param name="primcount" type="GLsizei"/>
         <param name="modestride" type="GLint"/>
         <glx handcode="true" ignore="true"/>
     </function>
 </category>
 
diff --git a/src/mapi/glapi/gen/gl_marshal.py b/src/mapi/glapi/gen/gl_marshal.py
index a50d773..1652759 100644
--- a/src/mapi/glapi/gen/gl_marshal.py
+++ b/src/mapi/glapi/gen/gl_marshal.py
@@ -245,24 +245,20 @@ class PrintCode(gl_XML.gl_print_base):
                 out('}')
 
             out('if (cmd_size <= MARSHAL_MAX_CMD_SIZE) {')
             with indent():
                 self.print_async_dispatch(func)
             out('} else {')
             with indent():
                 self.print_sync_dispatch(func)
             out('}')
 
-            if func.marshal == 'draw':
-                out('/* We relied on all vertex and index data being in VBOs */')
-                out('assert(ctx->API == API_OPENGL_CORE);')
-
         out('}')
 
     def print_async_body(self, func):
         out('/* {0}: marshalled asynchronously */'.format(func.name))
         self.print_async_struct(func)
         self.print_async_unmarshal(func)
         self.print_async_marshal(func)
         out('')
         out('')
 
diff --git a/src/mesa/main/glthread.h b/src/mesa/main/glthread.h
index 98ae115..04eb5ff 100644
--- a/src/mesa/main/glthread.h
+++ b/src/mesa/main/glthread.h
@@ -72,20 +72,32 @@ struct glthread_state
    struct glthread_batch **batch_queue_tail;
 
    /**
     * Batch containing commands that are being prepared for insertion into
     * batch_queue.  NULL if there are no such commands.
     *
     * Since this is only used by the main thread, it doesn't need the mutex to
     * be accessed.
     */
    struct glthread_batch *batch;
+
+   /**
+    * Tracks on the main thread side whether the current vertex array binding
+    * is in a VBO.
+    */
+   bool vertex_array_is_vbo;
+
+   /**
+    * Tracks on the main thread side whether the current element array (index
+    * buffer) binding is in a VBO.
+    */
+   bool element_array_is_vbo;
 };
 
 /**
  * A single batch of commands queued up for later execution by a thread pool
  * task.
  */
 struct glthread_batch
 {
    /**
     * Next batch of commands to execute after this batch, or NULL if this is
diff --git a/src/mesa/main/marshal.c b/src/mesa/main/marshal.c
index 14577dd..37c7b1b 100644
--- a/src/mesa/main/marshal.c
+++ b/src/mesa/main/marshal.c
@@ -147,10 +147,113 @@ _mesa_marshal_ShaderSource(GLuint shader, GLsizei count,
          cmd_strings += cmd_length[i];
       }
       _mesa_post_marshal_hook(ctx);
    } else {
       _mesa_glthread_finish(ctx);
       CALL_ShaderSource(ctx->CurrentServerDispatch,
                         (shader, count, string, length_tmp));
    }
    free(length_tmp);
 }
+
+
+/* BindBufferBase: marshalled asynchronously */
+struct marshal_cmd_BindBufferBase
+{
+   struct marshal_cmd_base cmd_base;
+   GLenum target;
+   GLuint index;
+   GLuint buffer;
+};
+static inline void
+_mesa_unmarshal_BindBufferBase(struct gl_context *ctx, const struct marshal_cmd_BindBufferBase *cmd)
+{
+   const GLenum target = cmd->target;
+   const GLuint index = cmd->index;
+   const GLuint buffer = cmd->buffer;
+   CALL_BindBufferBase(ctx->CurrentServerDispatch, (target, index, buffer));
+}
+
+/** Tracks the current bindings for the vertex array and index array buffers.
+ *
+ * This is part of what we need to enable glthread on compat-GL contexts that
+ * happen to use VBOs, without also supporting the full tracking of VBO vs
+ * user vertex array bindings per attribute on each vertex array for
+ * determining what to upload at draw call time.
+ *
+ * Note that GL core makes it so that a buffer binding with an invalid handle
+ * in the "buffer" parameter will throw an error, and then a
+ * glVertexAttribPointer() that followsmight not end up pointing at a VBO.
+ * However, in GL core the draw call would throw an error as well, so we don't
+ * really care if our tracking is wrong for this case -- we never need to
+ * marshal user data for draw calls, and the unmarshal will just generate an
+ * error or not as appropriate.
+ *
+ * For compatibility GL, we do need to accurately know whether the draw call
+ * on the unmarshal side will dereference a user pointer or load data from a
+ * VBO per vertex.  That would make it seem like we need to track whether a
+ * "buffer" is valid, so that we can know when an error will be generated
+ * instead of updating the binding.  However, compat GL has the ridiculous
+ * feature that if you pass a bad name, it just gens a buffer object for you,
+ * so we escape without having to know if things are valid or not.
+ */
+static void
+track_vbo_binding(struct gl_context *ctx, GLenum target, GLuint buffer)
+{
+   struct glthread_state *glthread = ctx->GLThread;
+
+   switch (target) {
+   case GL_ARRAY_BUFFER:
+      glthread->vertex_array_is_vbo = (buffer != 0);
+      break;
+   case GL_ELEMENT_ARRAY_BUFFER:
+      /* The current element array buffer binding is actually tracked in the
+       * 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);
+      break;
+   }
+}
+
+
+struct marshal_cmd_BindBuffer
+{
+   struct marshal_cmd_base cmd_base;
+   GLenum target;
+   GLuint buffer;
+};
+
+/**
+ * This is just like the code-generated glBindBuffer() support, except that we
+ * call track_vbo_binding().
+ */
+void
+_mesa_unmarshal_BindBuffer(struct gl_context *ctx,
+                           const struct marshal_cmd_BindBuffer *cmd)
+{
+   const GLenum target = cmd->target;
+   const GLuint buffer = cmd->buffer;
+   CALL_BindBuffer(ctx->CurrentServerDispatch, (target, buffer));
+}
+void GLAPIENTRY
+_mesa_marshal_BindBuffer(GLenum target, GLuint buffer)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   size_t cmd_size = sizeof(struct marshal_cmd_BindBuffer);
+   struct marshal_cmd_BindBuffer *cmd;
+   debug_print_marshal("BindBuffer");
+
+   track_vbo_binding(ctx, target, buffer);
+
+   if (cmd_size <= MARSHAL_MAX_CMD_SIZE) {
+      cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_BindBuffer,
+                                            cmd_size);
+      cmd->target = target;
+      cmd->buffer = buffer;
+      _mesa_post_marshal_hook(ctx);
+   } else {
+      _mesa_glthread_finish(ctx);
+      CALL_BindBuffer(ctx->CurrentServerDispatch, (target, buffer));
+   }
+}
+
diff --git a/src/mesa/main/marshal.h b/src/mesa/main/marshal.h
index 0e0e9b2..23b3300 100644
--- a/src/mesa/main/marshal.h
+++ b/src/mesa/main/marshal.h
@@ -102,29 +102,86 @@ static inline void
 _mesa_post_marshal_hook(struct gl_context *ctx)
 {
    /* This can be enabled for debugging whether a failure is a synchronization
     * problem between the main thread and the worker thread, or a failure in
     * how we actually marshal.
     */
    if (false)
       _mesa_glthread_finish(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;
+}
+
+/**
+ * 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.
+ */
+static inline bool
+_mesa_glthread_is_non_vbo_vertex_attrib_pointer(const struct gl_context *ctx)
+{
+   struct glthread_state *glthread = ctx->GLThread;
+
+   return ctx->API != API_OPENGL_CORE && !glthread->vertex_array_is_vbo;
+}
+
+/**
+ * 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)
+{
+   struct glthread_state *glthread = ctx->GLThread;
+
+   return ctx->API != API_OPENGL_CORE && !glthread->element_array_is_vbo;
+}
+
 struct marshal_cmd_ShaderSource;
 struct marshal_cmd_Flush;
+struct marshal_cmd_BindBuffer;
 
 void GLAPIENTRY
 _mesa_marshal_ShaderSource(GLuint shader, GLsizei count,
                            const GLchar * const *string, const GLint *length);
 
 void
 _mesa_unmarshal_ShaderSource(struct gl_context *ctx,
                              const struct marshal_cmd_ShaderSource *cmd);
 
 void GLAPIENTRY
 _mesa_marshal_Flush(void);
 
 void
 _mesa_unmarshal_Flush(struct gl_context *ctx,
                       const struct marshal_cmd_Flush *cmd);
 
+void GLAPIENTRY
+_mesa_marshal_BindBuffer(GLenum target, GLuint buffer);
+
+void
+_mesa_unmarshal_BindBuffer(struct gl_context *ctx,
+                           const struct marshal_cmd_BindBuffer *cmd);
+
 #endif /* MARSHAL_H */
-- 
2.9.3



More information about the mesa-dev mailing list