glthread: ignore non-VBO vertex arrays with NULL data pointers

This can happen when an attrib is enabled, but the shader doesn't use it,
so it's ignored by mesa/state_tracker, and should be ignored here as well.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/8138

Acked-by: Timothy Arceri <tarceri@itsqueeze.com>
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21039>
(cherry picked from commit efb531fcb5)

Conflicts:
	src/mesa/main/glthread_draw.c
This commit is contained in:
Marek Olšák 2023-02-01 08:00:01 -05:00 committed by Dylan Baker
parent 6dfc7eaeb2
commit f2fb52d61a
4 changed files with 41 additions and 11 deletions

View file

@ -1246,7 +1246,7 @@
"description": "glthread: ignore non-VBO vertex arrays with NULL data pointers",
"nominated": false,
"nomination_type": null,
"resolution": 4,
"resolution": 1,
"main_sha": null,
"because_sha": null
},
@ -16865,4 +16865,4 @@
"main_sha": null,
"because_sha": null
}
]
]

View file

@ -76,6 +76,7 @@ struct glthread_vao {
GLbitfield BufferEnabled; /**< "Enabled" converted to buffer bindings. */
GLbitfield BufferInterleaved; /**< Bitmask of buffers used by multiple attribs. */
GLbitfield UserPointerMask; /**< Bitmask of buffer bindings. */
GLbitfield NonNullPointerMask; /**< Bitmask of buffer bindings with non-NULL user pointers. */
GLbitfield NonZeroDivisorMask; /**< Bitmask of buffer bindings. */
struct {

View file

@ -407,14 +407,31 @@ draw_arrays_async_user(struct gl_context *ctx, GLenum mode, GLint first,
memcpy(cmd + 1, buffers, buffers_size);
}
static inline unsigned
get_user_buffer_mask(struct gl_context *ctx)
{
struct glthread_vao *vao = ctx->GLThread.CurrentVAO;
/* BufferEnabled means which attribs are enabled in terms of buffer
* binding slots (not attrib slots).
*
* UserPointerMask means which buffer bindings don't have a buffer bound.
*
* NonNullPointerMask means which buffer bindings have a NULL pointer.
* Those are not uploaded. This can happen when an attrib is enabled, but
* the shader doesn't use it, so it's ignored by mesa/state_tracker.
*/
return vao->BufferEnabled & vao->UserPointerMask & vao->NonNullPointerMask;
}
static ALWAYS_INLINE void
draw_arrays(GLenum mode, GLint first, GLsizei count, GLsizei instance_count,
GLuint baseinstance, bool compiled_into_dlist)
{
GET_CURRENT_CONTEXT(ctx);
struct glthread_vao *vao = ctx->GLThread.CurrentVAO;
unsigned user_buffer_mask = vao->UserPointerMask & vao->BufferEnabled;
unsigned user_buffer_mask =
ctx->API == API_OPENGL_CORE ? 0 : get_user_buffer_mask(ctx);
if (compiled_into_dlist && ctx->GLThread.ListMode) {
_mesa_glthread_finish_before(ctx, "DrawArrays");
@ -537,8 +554,9 @@ _mesa_marshal_MultiDrawArrays(GLenum mode, const GLint *first,
{
GET_CURRENT_CONTEXT(ctx);
struct glthread_vao *vao = ctx->GLThread.CurrentVAO;
unsigned user_buffer_mask = vao->UserPointerMask & vao->BufferEnabled;
unsigned user_buffer_mask =
ctx->API == API_OPENGL_CORE || draw_count <= 0 ?
0 : get_user_buffer_mask(ctx);
if (ctx->GLThread.ListMode)
goto sync;
@ -880,10 +898,10 @@ draw_elements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
bool compiled_into_dlist)
{
GET_CURRENT_CONTEXT(ctx);
struct glthread_vao *vao = ctx->GLThread.CurrentVAO;
unsigned user_buffer_mask = vao->UserPointerMask & vao->BufferEnabled;
bool has_user_indices = vao->CurrentElementBufferName == 0;
unsigned user_buffer_mask =
ctx->API == API_OPENGL_CORE ? 0 : get_user_buffer_mask(ctx);
bool has_user_indices = vao->CurrentElementBufferName == 0 && indices;
if (compiled_into_dlist && ctx->GLThread.ListMode)
goto sync;
@ -1103,9 +1121,9 @@ _mesa_marshal_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count,
const GLsizei *basevertex)
{
GET_CURRENT_CONTEXT(ctx);
struct glthread_vao *vao = ctx->GLThread.CurrentVAO;
unsigned user_buffer_mask = vao->UserPointerMask & vao->BufferEnabled;
unsigned user_buffer_mask =
ctx->API == API_OPENGL_CORE ? 0 : get_user_buffer_mask(ctx);
bool has_user_indices = vao->CurrentElementBufferName == 0;
if (ctx->GLThread.ListMode)

View file

@ -51,6 +51,7 @@ _mesa_glthread_reset_vao(struct glthread_vao *vao)
vao->Enabled = 0;
vao->BufferEnabled = 0;
vao->UserPointerMask = 0;
vao->NonNullPointerMask = 0;
vao->NonZeroDivisorMask = 0;
for (unsigned i = 0; i < ARRAY_SIZE(vao->Attrib); i++) {
@ -363,6 +364,11 @@ attrib_pointer(struct glthread_state *glthread, struct glthread_vao *vao,
vao->UserPointerMask &= ~(1u << attrib);
else
vao->UserPointerMask |= 1u << attrib;
if (pointer)
vao->NonNullPointerMask |= 1u << attrib;
else
vao->NonNullPointerMask &= ~(1u << attrib);
}
void
@ -447,6 +453,11 @@ bind_vertex_buffer(struct glthread_state *glthread, struct glthread_vao *vao,
vao->UserPointerMask &= ~(1u << i);
else
vao->UserPointerMask |= 1u << i;
if (offset)
vao->NonNullPointerMask |= 1u << i;
else
vao->NonNullPointerMask &= ~(1u << i);
}
void