Module: Mesa
Branch: staging/23.0
Commit: f2fb52d61a7d02e4b514744fce7a5dd52f48bbad
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=f2fb52d61a7d02e4b514744fce7a5dd52f48bbad

Author: Marek Olšák <[email protected]>
Date:   Wed Feb  1 08:00:01 2023 -0500

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 <[email protected]>
Reviewed-by: Pierre-Eric Pelloux-Prayer <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21039>
(cherry picked from commit efb531fcb5a53e46d12517c8a08c07a453f334fe)

Conflicts:
        src/mesa/main/glthread_draw.c

---

 .pick_status.json               |  4 ++--
 src/mesa/main/glthread.h        |  1 +
 src/mesa/main/glthread_draw.c   | 36 +++++++++++++++++++++++++++---------
 src/mesa/main/glthread_varray.c | 11 +++++++++++
 4 files changed, 41 insertions(+), 11 deletions(-)

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

Reply via email to