[Mesa-dev] [PATCH v8 1/3] mesa/glthread: track buffer destruction

Gregory Hainaut gregory.hainaut at gmail.com
Tue Jul 25 20:58:37 UTC 2017


It would be used in following commits to allow asynchronous PBO transfer.

The tracking saves the buffer name into a hash. Saving pointer
will be more complex as the buffer is created in BindBuffer due to IsBuffer
insanity.

Perf wise DeleteBuffers is now synchronous for robustness.

v5: properly delete hash element with the help of _mesa_HashDeleteAll

v6: rebase

v7: rebase
s/GLint pixel_pack_buffer_bound/GLuint bound_pixel_pack_buffer/
Drop the ShadowBufferObjects hash. Synchronous creation/destruction
gives us enough guarantee to lookup the BufferObjects hash directly.
Drop custom code for GenBuffers/CreateBuffers

v8: rebase
Signed-off-by: Gregory Hainaut <gregory.hainaut at gmail.com>
---
 src/mapi/glapi/gen/gl_API.xml |  2 +-
 src/mesa/main/glthread.h      | 10 ++++++++++
 src/mesa/main/marshal.c       | 40 ++++++++++++++++++++++++++++++++++++++++
 src/mesa/main/marshal.h       |  8 ++++++++
 4 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index 18839ec70c..4b01ca552f 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -5055,21 +5055,21 @@
 
     <function name="BufferSubData" es1="1.1" es2="2.0" marshal="custom"
               no_error="true">
         <param name="target" type="GLenum"/>
         <param name="offset" type="GLintptr"/>
         <param name="size" type="GLsizeiptr" counter="true"/>
         <param name="data" type="const GLvoid *" count="size"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="DeleteBuffers" es1="1.1" es2="2.0">
+    <function name="DeleteBuffers" es1="1.1" es2="2.0" marshal="custom">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="buffer" type="const GLuint *" count="n"/>
         <glx ignore="true"/>
     </function>
 
     <function name="GenBuffers" es1="1.1" es2="2.0" no_error="true">
         <param name="n" type="GLsizei" counter="true"/>
         <param name="buffer" type="GLuint *" output="true" count="n"/>
         <glx ignore="true"/>
     </function>
diff --git a/src/mesa/main/glthread.h b/src/mesa/main/glthread.h
index 306246ca1c..e5c8b79a97 100644
--- a/src/mesa/main/glthread.h
+++ b/src/mesa/main/glthread.h
@@ -88,20 +88,30 @@ struct glthread_state
     * 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;
+
+   /**
+    * Tracks on the main thread side the bound unpack pixel buffer
+    */
+   GLuint bound_pixel_unpack_buffer;
+
+   /**
+    * Tracks on the main thread side the bound pack pixel buffer
+    */
+   GLuint bound_pixel_pack_buffer;
 };
 
 void _mesa_glthread_init(struct gl_context *ctx);
 void _mesa_glthread_destroy(struct gl_context *ctx);
 
 void _mesa_glthread_restore_dispatch(struct gl_context *ctx);
 void _mesa_glthread_flush_batch(struct gl_context *ctx);
 void _mesa_glthread_finish(struct gl_context *ctx);
 
 #endif /* _GLTHREAD_H*/
diff --git a/src/mesa/main/marshal.c b/src/mesa/main/marshal.c
index 8f8e8c78ed..1914b54444 100644
--- a/src/mesa/main/marshal.c
+++ b/src/mesa/main/marshal.c
@@ -25,20 +25,21 @@
  *
  * Custom functions for marshalling GL calls from the main thread to a worker
  * thread when automatic code generation isn't appropriate.
  */
 
 #include "main/enums.h"
 #include "main/macros.h"
 #include "marshal.h"
 #include "dispatch.h"
 #include "marshal_generated.h"
+#include "hash.h"
 
 struct marshal_cmd_Flush
 {
    struct marshal_cmd_base cmd_base;
 };
 
 
 void
 _mesa_unmarshal_Flush(struct gl_context *ctx,
                       const struct marshal_cmd_Flush *cmd)
@@ -188,20 +189,59 @@ _mesa_marshal_ShaderSource(GLuint shader, GLsizei count,
       _mesa_post_marshal_hook(ctx);
    } else {
       _mesa_glthread_finish(ctx);
       CALL_ShaderSource(ctx->CurrentServerDispatch,
                         (shader, count, string, length_tmp));
    }
    free(length_tmp);
 }
 
 
+static void track_buffers_destruction(struct gl_context *ctx,
+      GLsizei n, const GLuint * buffers)
+{
+   GLsizei i;
+   struct glthread_state *glthread = ctx->GLThread;
+
+   if (n < 0 || !buffers)
+      return;
+
+   for (i = 0; i < n ; i++) {
+      if (buffers[i] == glthread->bound_pixel_pack_buffer)
+         glthread->bound_pixel_pack_buffer = 0;
+
+      if (buffers[i] == glthread->bound_pixel_unpack_buffer)
+         glthread->bound_pixel_unpack_buffer = 0;
+   }
+}
+
+/* DeleteBuffers: custom marshal to track buffers destruction */
+void GLAPIENTRY
+_mesa_marshal_DeleteBuffers(GLsizei n, const GLuint * buffer)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_glthread_finish(ctx);
+   debug_print_sync("DeleteBuffers");
+
+   // It is done before CALL_DeleteBuffers to avoid any ABA multithread issue.
+   track_buffers_destruction(ctx, n, buffer);
+
+   CALL_DeleteBuffers(ctx->CurrentServerDispatch, (n, buffer));
+}
+
+void
+_mesa_unmarshal_DeleteBuffers(struct gl_context *ctx,
+                           const struct marshal_cmd_DeleteBuffers *cmd)
+{
+   assert(0);
+}
+
 /* BindBufferBase: marshalled asynchronously */
 struct marshal_cmd_BindBufferBase
 {
    struct marshal_cmd_base cmd_base;
    GLenum target;
    GLuint index;
    GLuint buffer;
 };
 
 /** Tracks the current bindings for the vertex array and index array buffers.
diff --git a/src/mesa/main/marshal.h b/src/mesa/main/marshal.h
index 63e0295576..e7f681213c 100644
--- a/src/mesa/main/marshal.h
+++ b/src/mesa/main/marshal.h
@@ -180,20 +180,21 @@ struct marshal_cmd_Flush;
 struct marshal_cmd_BindBuffer;
 struct marshal_cmd_BufferData;
 struct marshal_cmd_BufferSubData;
 struct marshal_cmd_NamedBufferData;
 struct marshal_cmd_NamedBufferSubData;
 struct marshal_cmd_ClearBuffer;
 #define marshal_cmd_ClearBufferfv   marshal_cmd_ClearBuffer
 #define marshal_cmd_ClearBufferiv   marshal_cmd_ClearBuffer
 #define marshal_cmd_ClearBufferuiv  marshal_cmd_ClearBuffer
 #define marshal_cmd_ClearBufferfi   marshal_cmd_ClearBuffer
+struct marshal_cmd_DeleteBuffers;
 
 void
 _mesa_unmarshal_Enable(struct gl_context *ctx,
                        const struct marshal_cmd_Enable *cmd);
 
 void GLAPIENTRY
 _mesa_marshal_Enable(GLenum cap);
 
 void GLAPIENTRY
 _mesa_marshal_ShaderSource(GLuint shader, GLsizei count,
@@ -274,11 +275,18 @@ _mesa_marshal_ClearBufferuiv(GLenum buffer, GLint drawbuffer,
                              const GLuint *value);
 
 void
 _mesa_unmarshal_ClearBufferfi(struct gl_context *ctx,
                               const struct marshal_cmd_ClearBuffer *cmd);
 
 void GLAPIENTRY
 _mesa_marshal_ClearBufferfi(GLenum buffer, GLint drawbuffer,
                             const GLfloat depth, const GLint stencil);
 
+void GLAPIENTRY
+_mesa_marshal_DeleteBuffers(GLsizei n, const GLuint * buffer);
+
+void
+_mesa_unmarshal_DeleteBuffers(struct gl_context *ctx,
+                           const struct marshal_cmd_DeleteBuffers *cmd);
+
 #endif /* MARSHAL_H */
-- 
2.11.0



More information about the mesa-dev mailing list