[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