diff --git a/.pick_status.json b/.pick_status.json index 2f32b276534..1eed4e8c4dc 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -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 } -] \ No newline at end of file +] diff --git a/src/mesa/main/glthread.h b/src/mesa/main/glthread.h index ce0faf69ca9..427aa90df4e 100644 --- a/src/mesa/main/glthread.h +++ b/src/mesa/main/glthread.h @@ -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 { diff --git a/src/mesa/main/glthread_draw.c b/src/mesa/main/glthread_draw.c index b77e0b3cb5d..b0c433a686f 100644 --- a/src/mesa/main/glthread_draw.c +++ b/src/mesa/main/glthread_draw.c @@ -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) diff --git a/src/mesa/main/glthread_varray.c b/src/mesa/main/glthread_varray.c index f4f2bde2158..a309ffe21aa 100644 --- a/src/mesa/main/glthread_varray.c +++ b/src/mesa/main/glthread_varray.c @@ -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