mesa: keep the current VAO also set as _DrawVAO
authorMarek Olšák <marek.olsak@amd.com>
Fri, 18 Nov 2022 22:04:50 +0000 (17:04 -0500)
committerMarge Bot <emma+marge@anholt.net>
Mon, 12 Dec 2022 19:15:34 +0000 (19:15 +0000)
This removes setting _DrawVAO from all glDraw* functions that draw
primitives because now _DrawVAO is always equal to the current VAO.

glEnd, glRasterPos, and the slow display list path now have to save
_DrawVAO before changing it, and restore it after they are done.

This also removes _EmptyVAO, which becomes unused because we no longer
bind "no VAO" into _DrawVAO.

Rules:
- only glBindVertexArray and non-glDraw* paths should call
  _mesa_set_draw_vao, other places shouldn't
- only draws should call _mesa_update_vao_state, other places shouldn't

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19953>

src/mesa/main/arrayobj.c
src/mesa/main/attrib.c
src/mesa/main/context.c
src/mesa/main/draw.c
src/mesa/main/draw.h
src/mesa/main/mtypes.h
src/mesa/main/varray.c
src/mesa/state_tracker/st_cb_rasterpos.c
src/mesa/vbo/vbo_exec_draw.c
src/mesa/vbo/vbo_save_draw.c

index f4338d6..c1b4c9a 100644 (file)
@@ -941,20 +941,8 @@ bind_vertex_array(struct gl_context *ctx, GLuint id, bool no_error)
       newObj->EverBound = GL_TRUE;
    }
 
-   /* The _DrawArrays pointer is pointing at the VAO being unbound and
-    * that VAO may be in the process of being deleted. If it's not going
-    * to be deleted, this will have no effect, because the pointer needs
-    * to be updated by the VBO module anyway.
-    *
-    * Before the VBO module can update the pointer, we have to set it
-    * to NULL for drivers not to set up arrays which are not bound,
-    * or to prevent a crash if the VAO being unbound is going to be
-    * deleted.
-    */
-   _mesa_set_draw_vao(ctx, ctx->Array._EmptyVAO);
-   _mesa_update_vao_state(ctx, 0);
-
    _mesa_reference_vao(ctx, &ctx->Array.VAO, newObj);
+   _mesa_set_draw_vao(ctx, newObj);
 
    /* Update the valid-to-render state if binding on unbinding default VAO
     * if drawing with the default VAO is invalid.
@@ -1015,11 +1003,6 @@ delete_vertex_arrays(struct gl_context *ctx, GLsizei n, const GLuint *ids)
          if (ctx->Array.LastLookedUpVAO == obj)
             _mesa_reference_vao(ctx, &ctx->Array.LastLookedUpVAO, NULL);
 
-         if (ctx->Array._DrawVAO == obj) {
-            _mesa_set_draw_vao(ctx, ctx->Array._EmptyVAO);
-            _mesa_update_vao_state(ctx, 0);
-         }
-
          /* Unreference the array object.
           * If refcount hits zero, the object will be deleted.
           */
index 4b9d641..6572e4c 100644 (file)
@@ -1309,10 +1309,6 @@ restore_array_attrib(struct gl_context *ctx,
       copy_array_attrib(ctx, dest, src, true, 0);
    }
 
-   /* Invalidate array state. It will be updated during the next draw. */
-   _mesa_set_draw_vao(ctx, ctx->Array._EmptyVAO);
-   _mesa_update_vao_state(ctx, 0);
-
    if (is_vao_name_zero || !src->VAO->IndexBufferObj ||
        _mesa_IsBuffer(src->VAO->IndexBufferObj->Name)) {
       _mesa_BindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,
index eacce93..0a51f01 100644 (file)
@@ -1105,7 +1105,6 @@ _mesa_free_context_data(struct gl_context *ctx, bool destroy_debug_output)
 
    _mesa_reference_vao(ctx, &ctx->Array.VAO, NULL);
    _mesa_reference_vao(ctx, &ctx->Array.DefaultVAO, NULL);
-   _mesa_reference_vao(ctx, &ctx->Array._EmptyVAO, NULL);
    _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, NULL);
 
    _mesa_free_attrib_data(ctx);
index 192b943..b1f9421 100644 (file)
@@ -115,6 +115,30 @@ _mesa_set_draw_vao(struct gl_context *ctx, struct gl_vertex_array_object *vao)
 }
 
 /**
+ * Other than setting the new VAO, this returns a VAO reference to
+ * the previously-bound VAO through the parameter. The caller must call
+ * _mesa_restore_draw_vao to ensure reference counting is done properly.
+ */
+void
+_mesa_save_and_set_draw_vao(struct gl_context *ctx,
+                            struct gl_vertex_array_object *vao,
+                            struct gl_vertex_array_object **old_vao)
+{
+   *old_vao = ctx->Array._DrawVAO;
+   ctx->Array._DrawVAO = NULL;
+   _mesa_set_draw_vao(ctx, vao);
+}
+
+void
+_mesa_restore_draw_vao(struct gl_context *ctx,
+                       struct gl_vertex_array_object *saved)
+{
+   _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, NULL);
+   ctx->Array._DrawVAO = saved;
+   ctx->Array.NewVAO = true;
+}
+
+/**
  * Update derived VAO state. This determines whether to update gallium vertex
  * buffers and vertex elements, and it sets which vertex attribs are enabled
  * according to the filter.
@@ -1380,7 +1404,6 @@ _mesa_DrawArrays(GLenum mode, GLint start, GLsizei count)
    GET_CURRENT_CONTEXT(ctx);
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -1411,7 +1434,6 @@ _mesa_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
    GET_CURRENT_CONTEXT(ctx);
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -1443,7 +1465,6 @@ _mesa_DrawArraysInstancedBaseInstance(GLenum mode, GLint first,
    GET_CURRENT_CONTEXT(ctx);
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -1474,7 +1495,6 @@ _mesa_MultiDrawArrays(GLenum mode, const GLint *first,
    GET_CURRENT_CONTEXT(ctx);
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -1707,7 +1727,6 @@ _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
    GET_CURRENT_CONTEXT(ctx);
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -1803,7 +1822,6 @@ _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
    GET_CURRENT_CONTEXT(ctx);
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -1828,7 +1846,6 @@ _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
    GET_CURRENT_CONTEXT(ctx);
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -1853,7 +1870,6 @@ _mesa_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
    GET_CURRENT_CONTEXT(ctx);
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -1881,7 +1897,6 @@ _mesa_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count,
    GET_CURRENT_CONTEXT(ctx);
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -1911,7 +1926,6 @@ _mesa_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count,
    GET_CURRENT_CONTEXT(ctx);
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -1943,7 +1957,6 @@ _mesa_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode,
    GET_CURRENT_CONTEXT(ctx);
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -2094,7 +2107,6 @@ _mesa_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type,
    GET_CURRENT_CONTEXT(ctx);
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -2120,7 +2132,6 @@ _mesa_MultiDrawElementsBaseVertex(GLenum mode,
    GET_CURRENT_CONTEXT(ctx);
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -2151,7 +2162,6 @@ _mesa_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
 {
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -2257,7 +2267,6 @@ _mesa_DrawArraysIndirect(GLenum mode, const GLvoid *indirect)
 
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -2315,7 +2324,6 @@ _mesa_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
 
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -2341,7 +2349,6 @@ _mesa_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect,
 
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -2413,7 +2420,6 @@ _mesa_MultiDrawElementsIndirect(GLenum mode, GLenum type,
 
    FLUSH_FOR_DRAW(ctx);
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -2510,7 +2516,6 @@ _mesa_MultiDrawArraysIndirectCountARB(GLenum mode, GLintptr indirect,
    if (stride == 0)
       stride = 4 * sizeof(GLuint);      /* sizeof(DrawArraysIndirectCommand) */
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
@@ -2540,7 +2545,6 @@ _mesa_MultiDrawElementsIndirectCountARB(GLenum mode, GLenum type,
    if (stride == 0)
       stride = 5 * sizeof(GLuint);      /* sizeof(DrawElementsIndirectCommand) */
 
-   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    _mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
 
    if (ctx->NewState)
index 0b5dd46..1e55837 100644 (file)
@@ -84,6 +84,15 @@ void
 _mesa_set_draw_vao(struct gl_context *ctx, struct gl_vertex_array_object *vao);
 
 void
+_mesa_save_and_set_draw_vao(struct gl_context *ctx,
+                            struct gl_vertex_array_object *vao,
+                            struct gl_vertex_array_object **old_vao);
+
+void
+_mesa_restore_draw_vao(struct gl_context *ctx,
+                       struct gl_vertex_array_object *saved);
+
+void
 _mesa_update_vao_state(struct gl_context *ctx, GLbitfield filter);
 
 void
index b195a9f..974af94 100644 (file)
@@ -1780,12 +1780,6 @@ struct gl_array_attrib
     */
    bool NewVertexElements;
 
-   /**
-    * Initially or if the VAO referenced by _DrawVAO is deleted the _DrawVAO
-    * pointer is set to the _EmptyVAO which is just an empty VAO all the time.
-    */
-   struct gl_vertex_array_object *_EmptyVAO;
-
    /** Legal array datatypes and the API for which they have been computed */
    GLbitfield LegalTypesMask;
    gl_api LegalTypesMaskAPI;
index 201d93f..30b6f07 100644 (file)
@@ -4028,8 +4028,7 @@ _mesa_init_varray(struct gl_context *ctx)
 
    ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0);
    _mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO);
-   ctx->Array._EmptyVAO = _mesa_new_vao(ctx, ~0u);
-   _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, ctx->Array._EmptyVAO);
+   _mesa_set_draw_vao(ctx, ctx->Array.VAO);
    ctx->Array.ActiveTexture = 0;   /* GL_ARB_multitexture */
 
    ctx->Array.Objects = _mesa_NewHashTable();
index fecbb0b..64dbd49 100644 (file)
@@ -265,11 +265,16 @@ st_RasterPos(struct gl_context *ctx, const GLfloat v[4])
    if (!rs->VAO->IsDynamic)
       rs->VAO->NewVertexElements = true;
 
-   _mesa_set_draw_vao(ctx, rs->VAO);
+   /* Save the Draw VAO before we override it. */
+   struct gl_vertex_array_object *old_vao;
+
+   _mesa_save_and_set_draw_vao(ctx, rs->VAO, &old_vao);
    _mesa_update_vao_state(ctx, VERT_BIT_POS);
 
    st_feedback_draw_vbo(ctx, &rs->info, 0, &rs->draw, 1);
 
+   _mesa_restore_draw_vao(ctx, old_vao);
+
    /* restore draw's rasterization stage depending on rendermode */
    if (ctx->RenderMode == GL_FEEDBACK) {
       draw_set_rasterize_stage(draw, st->feedback_stage);
index e4adbc1..235b97b 100644 (file)
@@ -83,7 +83,8 @@ vbo_exec_copy_vertices(struct vbo_exec_context *exec)
 /* TODO: populate these as the vertex is defined:
  */
 static void
-vbo_exec_bind_arrays(struct gl_context *ctx)
+vbo_exec_bind_arrays(struct gl_context *ctx,
+                     struct gl_vertex_array_object **old_vao)
 {
    struct vbo_context *vbo = vbo_context(ctx);
    struct gl_vertex_array_object *vao = vbo->VAO;
@@ -147,7 +148,7 @@ vbo_exec_bind_arrays(struct gl_context *ctx)
    assert(!exec->vtx.bufferobj ||
           (vao_enabled & ~vao->VertexAttribBufferMask) == 0);
 
-   _mesa_set_draw_vao(ctx, vao);
+   _mesa_save_and_set_draw_vao(ctx, vao, old_vao);
    _mesa_update_vao_state(ctx, vao_filter);
 }
 
@@ -318,8 +319,10 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec)
       exec->vtx.copied.nr = vbo_exec_copy_vertices(exec);
 
       if (exec->vtx.copied.nr != exec->vtx.vert_count) {
+         struct gl_vertex_array_object *old_vao;
+
          /* Prepare and set the exec draws internal VAO for drawing. */
-         vbo_exec_bind_arrays(ctx);
+         vbo_exec_bind_arrays(ctx, &old_vao);
 
          if (ctx->NewState)
             _mesa_update_state(ctx);
@@ -341,6 +344,8 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec)
          /* Get new storage -- unless asked not to. */
          if (!persistent_mapping)
             vbo_exec_vtx_map(exec);
+
+         _mesa_restore_draw_vao(ctx, old_vao);
       }
    }
 
index 4a53a8a..093cbe7 100644 (file)
@@ -128,21 +128,6 @@ playback_copy_to_current(struct gl_context *ctx,
 }
 
 
-
-/**
- * Set the appropriate VAO to draw.
- */
-static void
-bind_vertex_list(struct gl_context *ctx,
-                 const struct vbo_save_vertex_list *node)
-{
-   const gl_vertex_processing_mode mode = ctx->VertexProgram._VPMode;
-
-   _mesa_set_draw_vao(ctx, node->cold->VAO[mode]);
-   _mesa_update_vao_state(ctx, _vbo_get_vao_filter(mode));
-}
-
-
 static void
 loopback_vertex_list(struct gl_context *ctx,
                      const struct vbo_save_vertex_list *list)
@@ -329,7 +314,12 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data, bool copy_to_c
    if (vbo_save_playback_vertex_list_gallium(ctx, node, copy_to_current) == DONE)
       return;
 
-   bind_vertex_list(ctx, node);
+   /* Save the Draw VAO before we override it. */
+   const gl_vertex_processing_mode mode = ctx->VertexProgram._VPMode;
+   struct gl_vertex_array_object *old_vao;
+
+   _mesa_save_and_set_draw_vao(ctx, node->cold->VAO[mode], &old_vao);
+   _mesa_update_vao_state(ctx, _vbo_get_vao_filter(mode));
 
    /* Need that at least one time. */
    if (ctx->NewState)
@@ -337,6 +327,7 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data, bool copy_to_c
 
    /* Return precomputed GL errors such as invalid shaders. */
    if (!ctx->ValidPrimMask) {
+      _mesa_restore_draw_vao(ctx, old_vao);
       _mesa_error(ctx, ctx->DrawGLError, "glCallList");
       return;
    }
@@ -358,6 +349,8 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data, bool copy_to_c
    }
    info->index.gl_bo = gl_bo;
 
+   _mesa_restore_draw_vao(ctx, old_vao);
+
    if (copy_to_current)
       playback_copy_to_current(ctx, node);
 }