diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index 7a02da38796..07589bca753 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -1156,7 +1156,7 @@
+ marshal_call_after="_mesa_glthread_Begin(ctx);">
@@ -1371,7 +1371,7 @@
+ marshal_call_after="_mesa_glthread_End(ctx);">
diff --git a/src/mesa/main/glthread.c b/src/mesa/main/glthread.c
index c72a1fa0a0e..673134260e6 100644
--- a/src/mesa/main/glthread.c
+++ b/src/mesa/main/glthread.c
@@ -214,6 +214,8 @@ _mesa_glthread_init(struct gl_context *ctx)
/* glthread takes over all L3 pinning */
ctx->st->pin_thread_counter = ST_L3_PINNING_DISABLED;
+ _mesa_glthread_update_draw_always_async(ctx);
+
/* Execute the thread initialization function in the thread. */
struct util_queue_fence fence;
util_queue_fence_init(&fence);
diff --git a/src/mesa/main/glthread.h b/src/mesa/main/glthread.h
index b772d874697..c202e3c16a3 100644
--- a/src/mesa/main/glthread.h
+++ b/src/mesa/main/glthread.h
@@ -186,6 +186,7 @@ struct glthread_state
/** Whether GLThread is enabled. */
bool enabled;
bool inside_begin_end;
+ bool draw_always_async;
/** Display lists. */
GLenum16 ListMode; /**< Zero if not inside display list, else list mode. */
diff --git a/src/mesa/main/glthread_draw.c b/src/mesa/main/glthread_draw.c
index 9af7e296c68..c84f8394117 100644
--- a/src/mesa/main/glthread_draw.c
+++ b/src/mesa/main/glthread_draw.c
@@ -467,9 +467,7 @@ draw_arrays(GLenum mode, GLint first, GLsizei count, GLsizei instance_count,
* for possible GL errors.
*/
if (!user_buffer_mask || count <= 0 || instance_count <= 0 ||
- /* This will just generate GL_INVALID_OPERATION, as it should. */
- ctx->GLThread.inside_begin_end ||
- (!compiled_into_dlist && ctx->GLThread.ListMode)) {
+ ctx->GLThread.draw_always_async) {
draw_arrays_async(ctx, mode, first, count, instance_count, baseinstance);
return;
}
@@ -543,7 +541,7 @@ _mesa_marshal_MultiDrawArrays(GLenum mode, const GLint *first,
struct glthread_attrib_binding buffers[VERT_ATTRIB_MAX];
unsigned user_buffer_mask =
ctx->API == API_OPENGL_CORE || draw_count <= 0 ||
- ctx->GLThread.inside_begin_end ? 0 : get_user_buffer_mask(ctx);
+ ctx->GLThread.draw_always_async ? 0 : get_user_buffer_mask(ctx);
if (user_buffer_mask) {
unsigned min_index = ~0;
@@ -879,12 +877,9 @@ draw_elements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
* This is also an error path. Zero counts should still call the driver
* for possible GL errors.
*/
- if (count <= 0 || instance_count <= 0 ||
+ if (ctx->GLThread.draw_always_async || count <= 0 || instance_count <= 0 ||
!is_index_type_valid(type) ||
- (!user_buffer_mask && !has_user_indices) ||
- /* This will just generate GL_INVALID_OPERATION, as it should. */
- ctx->GLThread.inside_begin_end ||
- (!compiled_into_dlist && ctx->GLThread.ListMode)) {
+ (!user_buffer_mask && !has_user_indices)) {
draw_elements_async(ctx, mode, count, type, indices, instance_count,
basevertex, baseinstance);
return;
@@ -1122,7 +1117,7 @@ _mesa_marshal_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count,
* a GL error, we don't upload anything.
*/
if (draw_count > 0 && is_index_type_valid(type) &&
- !ctx->GLThread.inside_begin_end) {
+ !ctx->GLThread.draw_always_async) {
user_buffer_mask = ctx->API == API_OPENGL_CORE ? 0 : get_user_buffer_mask(ctx);
has_user_indices = vao->CurrentElementBufferName == 0;
}
diff --git a/src/mesa/main/glthread_marshal.h b/src/mesa/main/glthread_marshal.h
index 69f4f2a62cd..1aab57de21c 100644
--- a/src/mesa/main/glthread_marshal.h
+++ b/src/mesa/main/glthread_marshal.h
@@ -142,6 +142,16 @@ _mesa_glthread_has_non_vbo_vertices_or_indices_or_indirect(const struct gl_conte
(vao->UserPointerMask & vao->BufferEnabled));
}
+static inline void
+_mesa_glthread_update_draw_always_async(struct gl_context *ctx)
+{
+ /* Executing erroneous cases will just generate GL_INVALID_OPERATION. */
+ ctx->GLThread.draw_always_async =
+ ctx->API == API_OPENGL_CORE ||
+ ctx->GLThread.inside_begin_end ||
+ ctx->GLThread.ListMode;
+}
+
static inline unsigned
_mesa_buffer_enum_to_count(GLenum buffer)
{
@@ -879,8 +889,10 @@ _mesa_glthread_CallLists(struct gl_context *ctx, GLsizei n, GLenum type,
static inline void
_mesa_glthread_NewList(struct gl_context *ctx, GLuint list, GLenum mode)
{
- if (!ctx->GLThread.ListMode)
+ if (!ctx->GLThread.ListMode) {
ctx->GLThread.ListMode = MIN2(mode, 0xffff);
+ _mesa_glthread_update_draw_always_async(ctx);
+ }
}
static inline void
@@ -890,6 +902,7 @@ _mesa_glthread_EndList(struct gl_context *ctx)
return;
ctx->GLThread.ListMode = 0;
+ _mesa_glthread_update_draw_always_async(ctx);
/* Track the last display list change. */
p_atomic_set(&ctx->GLThread.LastDListChangeBatchIndex, ctx->GLThread.next);
@@ -938,4 +951,18 @@ _mesa_glthread_DeleteFramebuffers(struct gl_context *ctx, GLsizei n,
}
}
+static inline void
+_mesa_glthread_Begin(struct gl_context *ctx)
+{
+ ctx->GLThread.inside_begin_end = true;
+ _mesa_glthread_update_draw_always_async(ctx);
+}
+
+static inline void
+_mesa_glthread_End(struct gl_context *ctx)
+{
+ ctx->GLThread.inside_begin_end = false;
+ _mesa_glthread_update_draw_always_async(ctx);
+}
+
#endif /* MARSHAL_H */