mesa: move _DrawVAOEnabledAttribs determination into st_update_array
authorMarek Olšák <marek.olsak@amd.com>
Tue, 22 Nov 2022 11:57:43 +0000 (06:57 -0500)
committerMarge Bot <emma+marge@anholt.net>
Mon, 12 Dec 2022 19:15:34 +0000 (19:15 +0000)
This can just be computed where it's used.

Now the non-glDraw paths like glRasterPos, glBegin/End, and the slow
display list path have to save and restore _VPModeInputFilter, which
is the only field that's different from the glDraw* path.

_VPModeInputFilter is a bitmask of VP inputs that might have to be bound.
The only difference with glBegin/End and the slow display list path is
that they also add VERT_BIT_MAT_ALL to the bitmask, whereas the glDraw* path
doesn't have that.

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.h
src/mesa/main/draw.c
src/mesa/main/draw.h
src/mesa/main/mtypes.h
src/mesa/state_tracker/st_atom_array.cpp
src/mesa/state_tracker/st_cb_rasterpos.c
src/mesa/state_tracker/st_context.c
src/mesa/vbo/vbo_exec_draw.c
src/mesa/vbo/vbo_save_draw.c

index 2914932..3edb425 100644 (file)
@@ -152,6 +152,17 @@ _mesa_vao_enable_to_vp_inputs(gl_attribute_map_mode mode, GLbitfield enabled)
    }
 }
 
+/**
+ * Return enabled vertex arrays. The bitmask is trimmed based on POS/GENERIC0
+ * remapping, and generic varyings are masked out for fixed-func shaders.
+ */
+static inline GLbitfield
+_mesa_get_enabled_vertex_arrays(const struct gl_context *ctx)
+{
+   return ctx->VertexProgram._VPModeInputFilter &
+          ctx->Array._DrawVAO->_EnabledWithMapMode;
+}
+
 
 /**
  * Return the enabled user (= non-VBO) attrib mask and the non-zero divisor
@@ -161,6 +172,7 @@ _mesa_vao_enable_to_vp_inputs(gl_attribute_map_mode mode, GLbitfield enabled)
  */
 static inline void
 _mesa_get_derived_vao_masks(const struct gl_context *ctx,
+                            const GLbitfield enabled_attribs,
                             GLbitfield *enabled_user_attribs,
                             GLbitfield *nonzero_divisor_attribs)
 {
@@ -169,10 +181,8 @@ _mesa_get_derived_vao_masks(const struct gl_context *ctx,
    const GLbitfield enabled_nonuser = enabled & vao->VertexAttribBufferMask;
    const GLbitfield enabled_nonzero_divisor = enabled & vao->NonZeroDivisorMask;
 
-   *enabled_user_attribs = ~enabled_nonuser &
-                           ctx->Array._DrawVAOEnabledAttribs;
-   *nonzero_divisor_attribs = enabled_nonzero_divisor &
-                              ctx->Array._DrawVAOEnabledAttribs;
+   *enabled_user_attribs = ~enabled_nonuser & enabled_attribs;
+   *nonzero_divisor_attribs = enabled_nonzero_divisor & enabled_attribs;
 
    switch (vao->_AttributeMapMode) {
    case ATTRIBUTE_MAP_MODE_POSITION:
index febcaae..9f264b7 100644 (file)
@@ -118,25 +118,47 @@ _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.
+ * the previously-bound VAO and the previous _VPModeInputFilter value through
+ * parameters. The caller must call _mesa_restore_draw_vao to ensure
+ * reference counting is done properly and the affected states are restored.
+ *
+ * \param ctx  GL context
+ * \param vao  VAO to set.
+ * \param vp_input_filter  Mask of enabled vertex attribs.
+ *        Possible values that can also be OR'd with each other:
+ *        - VERT_BIT_FF_ALL
+ *        - VERT_BIT_MAT_ALL
+ *        - VERT_BIT_ALL
+ *        - VERT_BIT_SELECT_RESULT_OFFSET
+ * \param old_vao  Previous bound VAO.
+ * \param old_vp_input_filter  Previous value of vp_input_filter.
  */
 void
 _mesa_save_and_set_draw_vao(struct gl_context *ctx,
                             struct gl_vertex_array_object *vao,
-                            struct gl_vertex_array_object **old_vao)
+                            GLbitfield vp_input_filter,
+                            struct gl_vertex_array_object **old_vao,
+                            GLbitfield *old_vp_input_filter)
 {
    *old_vao = ctx->Array._DrawVAO;
+   *old_vp_input_filter = ctx->VertexProgram._VPModeInputFilter;
+
    ctx->Array._DrawVAO = NULL;
+   ctx->VertexProgram._VPModeInputFilter = vp_input_filter;
    _mesa_set_draw_vao(ctx, vao);
 }
 
 void
 _mesa_restore_draw_vao(struct gl_context *ctx,
-                       struct gl_vertex_array_object *saved)
+                       struct gl_vertex_array_object *saved,
+                       GLbitfield saved_vp_input_filter)
 {
+   /* Restore states. */
    _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, NULL);
    ctx->Array._DrawVAO = saved;
+   ctx->VertexProgram._VPModeInputFilter = saved_vp_input_filter;
+
+   /* Update states. */
    _mesa_update_edgeflag_state_vao(ctx);
    ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS;
    ctx->Array.NewVertexElements = true;
@@ -151,19 +173,7 @@ void
 _mesa_update_vao_state(struct gl_context *ctx, GLbitfield filter)
 {
    struct gl_vertex_array_object *vao = ctx->Array._DrawVAO;
-
-   assert(vao->_EnabledWithMapMode ==
-          _mesa_vao_enable_to_vp_inputs(vao->_AttributeMapMode, vao->Enabled));
-
-   /* Filter out unwanted arrays. */
-   const GLbitfield enabled = filter & vao->_EnabledWithMapMode;
-   if (ctx->Array._DrawVAOEnabledAttribs != enabled) {
-      ctx->Array._DrawVAOEnabledAttribs = enabled;
-      ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS;
-      ctx->Array.NewVertexElements |= true;
-   }
-
-   _mesa_set_varying_vp_inputs(ctx, enabled);
+   _mesa_set_varying_vp_inputs(ctx, filter & vao->_EnabledWithMapMode);
 }
 
 
index 1e55837..e55ed8a 100644 (file)
@@ -86,11 +86,14 @@ _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);
+                            GLbitfield vp_input_filter,
+                            struct gl_vertex_array_object **old_vao,
+                            GLbitfield *old_vp_input_filter);
 
 void
 _mesa_restore_draw_vao(struct gl_context *ctx,
-                       struct gl_vertex_array_object *saved);
+                       struct gl_vertex_array_object *saved,
+                       GLbitfield saved_vp_input_filter);
 
 void
 _mesa_update_vao_state(struct gl_context *ctx, GLbitfield filter);
index ac73ccf..da6b80a 100644 (file)
@@ -1739,15 +1739,6 @@ struct gl_array_attrib
     * mode or display list draws.
     */
    struct gl_vertex_array_object *_DrawVAO;
-   /**
-    * The VERT_BIT_* bits effectively enabled from the current _DrawVAO.
-    * This is always a subset of _mesa_get_vao_vp_inputs(_DrawVAO)
-    * but may omit those arrays that shall not be referenced by the current
-    * gl_vertex_program_state::_VPMode. For example, the generic attributes are
-    * masked out from the _DrawVAO's enabled arrays when a fixed function
-    * array draw is executed.
-    */
-   GLbitfield _DrawVAOEnabledAttribs;
 
    /**
     * Whether per-vertex edge flags are enabled and should be processed by
index 759a322..1398e8a 100644 (file)
@@ -178,10 +178,11 @@ st_setup_arrays(struct st_context *st,
                 struct pipe_vertex_buffer *vbuffer, unsigned *num_vbuffers)
 {
    struct gl_context *ctx = st->ctx;
+   GLbitfield enabled_attribs = _mesa_get_enabled_vertex_arrays(ctx);
 
    setup_arrays<POPCNT_NO, UPDATE_ALL>
       (st, ctx->Array._DrawVAO, vp->Base.DualSlotInputs,
-       vp_variant->vert_attrib_mask, ctx->Array._DrawVAOEnabledAttribs,
+       vp_variant->vert_attrib_mask, enabled_attribs,
        velements, vbuffer, num_vbuffers);
 }
 
@@ -195,13 +196,14 @@ template<util_popcnt POPCNT, st_update_flag UPDATE> void ALWAYS_INLINE
 st_setup_current(struct st_context *st,
                  const GLbitfield inputs_read,
                  const GLbitfield dual_slot_inputs,
+                 const GLbitfield enabled_attribs,
                  struct cso_velems_state *velements,
                  struct pipe_vertex_buffer *vbuffer, unsigned *num_vbuffers)
 {
    struct gl_context *ctx = st->ctx;
 
    /* Process values that should have better been uniforms in the application */
-   GLbitfield curmask = inputs_read & ~ctx->Array._DrawVAOEnabledAttribs;
+   GLbitfield curmask = inputs_read & ~enabled_attribs;
    if (curmask) {
       unsigned num_attribs = util_bitcount_fast<POPCNT>(curmask);
       unsigned num_dual_attribs = util_bitcount_fast<POPCNT>(curmask &
@@ -272,11 +274,12 @@ st_setup_current_user(struct st_context *st,
                       struct pipe_vertex_buffer *vbuffer, unsigned *num_vbuffers)
 {
    struct gl_context *ctx = st->ctx;
+   const GLbitfield enabled_attribs = _mesa_get_enabled_vertex_arrays(ctx);
    const GLbitfield inputs_read = vp_variant->vert_attrib_mask;
    const GLbitfield dual_slot_inputs = vp->Base.DualSlotInputs;
 
    /* Process values that should have better been uniforms in the application */
-   GLbitfield curmask = inputs_read & ~ctx->Array._DrawVAOEnabledAttribs;
+   GLbitfield curmask = inputs_read & ~enabled_attribs;
    /* For each attribute, make an own user buffer binding. */
    while (curmask) {
       const gl_vert_attrib attr = (gl_vert_attrib)u_bit_scan(&curmask);
@@ -297,6 +300,7 @@ st_setup_current_user(struct st_context *st,
 
 template<util_popcnt POPCNT, st_update_flag UPDATE> void ALWAYS_INLINE
 st_update_array_templ(struct st_context *st,
+                      const GLbitfield enabled_attribs,
                       const GLbitfield enabled_user_attribs,
                       const GLbitfield nonzero_divisor_attribs)
 {
@@ -323,11 +327,12 @@ st_update_array_templ(struct st_context *st,
    /* Setup arrays */
    setup_arrays<POPCNT, UPDATE>
       (st, ctx->Array._DrawVAO, dual_slot_inputs, inputs_read,
-       ctx->Array._DrawVAOEnabledAttribs, &velements, vbuffer, &num_vbuffers);
+       enabled_attribs, &velements, vbuffer, &num_vbuffers);
 
    /* _NEW_CURRENT_ATTRIB */
    /* Setup zero-stride attribs. */
    st_setup_current<POPCNT, UPDATE>(st, inputs_read, dual_slot_inputs,
+                                    enabled_attribs,
                                     &velements, vbuffer, &num_vbuffers);
 
    unsigned unbind_trailing_vbuffers =
@@ -364,13 +369,17 @@ st_update_array_impl(struct st_context *st)
 {
    struct gl_context *ctx = st->ctx;
    struct gl_vertex_array_object *vao = ctx->Array._DrawVAO;
+   const GLbitfield enabled_attribs = _mesa_get_enabled_vertex_arrays(ctx);
    GLbitfield enabled_user_attribs;
    GLbitfield nonzero_divisor_attribs;
 
+   assert(vao->_EnabledWithMapMode ==
+          _mesa_vao_enable_to_vp_inputs(vao->_AttributeMapMode, vao->Enabled));
+
    if (!vao->IsDynamic && !vao->SharedAndImmutable)
       _mesa_update_vao_derived_arrays(ctx, vao);
 
-   _mesa_get_derived_vao_masks(ctx, &enabled_user_attribs,
+   _mesa_get_derived_vao_masks(ctx, enabled_attribs, &enabled_user_attribs,
                                &nonzero_divisor_attribs);
 
    /* Changing from user to non-user buffers and vice versa can switch between
@@ -381,10 +390,10 @@ st_update_array_impl(struct st_context *st)
        st->uses_user_vertex_buffers !=
        !!(st->vp_variant->vert_attrib_mask & enabled_user_attribs)) {
       st_update_array_templ<POPCNT, UPDATE_ALL>
-         (st, enabled_user_attribs, nonzero_divisor_attribs);
+         (st, enabled_attribs, enabled_user_attribs, nonzero_divisor_attribs);
    } else {
       st_update_array_templ<POPCNT, UPDATE_BUFFERS_ONLY>
-         (st, enabled_user_attribs, nonzero_divisor_attribs);
+         (st, enabled_attribs, enabled_user_attribs, nonzero_divisor_attribs);
    }
 }
 
index 0b9582a..90e6d0f 100644 (file)
@@ -270,13 +270,15 @@ st_RasterPos(struct gl_context *ctx, const GLfloat v[4])
 
    /* Save the Draw VAO before we override it. */
    struct gl_vertex_array_object *old_vao;
+   GLbitfield old_vp_input_filter;
 
-   _mesa_save_and_set_draw_vao(ctx, rs->VAO, &old_vao);
+   _mesa_save_and_set_draw_vao(ctx, rs->VAO, VERT_BIT_POS,
+                               &old_vao, &old_vp_input_filter);
    _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);
+   _mesa_restore_draw_vao(ctx, old_vao, old_vp_input_filter);
 
    /* restore draw's rasterization stage depending on rendermode */
    if (ctx->RenderMode == GL_FEEDBACK) {
index 9bc63b5..80d2e60 100644 (file)
@@ -108,7 +108,8 @@ static inline bool
 st_vp_uses_current_values(const struct gl_context *ctx)
 {
    const uint64_t inputs = ctx->VertexProgram._Current->info.inputs_read;
-   return ~ctx->Array._DrawVAOEnabledAttribs & inputs;
+
+   return ~_mesa_get_enabled_vertex_arrays(ctx) & inputs;
 }
 
 
index 1c39ef4..81a26df 100644 (file)
@@ -84,7 +84,8 @@ vbo_exec_copy_vertices(struct vbo_exec_context *exec)
  */
 static void
 vbo_exec_bind_arrays(struct gl_context *ctx,
-                     struct gl_vertex_array_object **old_vao)
+                     struct gl_vertex_array_object **old_vao,
+                     GLbitfield *old_vp_input_filter)
 {
    struct vbo_context *vbo = vbo_context(ctx);
    struct gl_vertex_array_object *vao = vbo->VAO;
@@ -148,7 +149,8 @@ vbo_exec_bind_arrays(struct gl_context *ctx,
    assert(!exec->vtx.bufferobj ||
           (vao_enabled & ~vao->VertexAttribBufferMask) == 0);
 
-   _mesa_save_and_set_draw_vao(ctx, vao, old_vao);
+   _mesa_save_and_set_draw_vao(ctx, vao, vao_filter,
+                               old_vao, old_vp_input_filter);
    _mesa_update_vao_state(ctx, vao_filter);
 }
 
@@ -320,9 +322,10 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec)
 
       if (exec->vtx.copied.nr != exec->vtx.vert_count) {
          struct gl_vertex_array_object *old_vao;
+         GLbitfield old_vp_input_filter;
 
-         /* Prepare and set the exec draws internal VAO for drawing. */
-         vbo_exec_bind_arrays(ctx, &old_vao);
+         /* Prepare and set the Begin/End internal VAO for drawing. */
+         vbo_exec_bind_arrays(ctx, &old_vao, &old_vp_input_filter);
 
          if (ctx->NewState)
             _mesa_update_state(ctx);
@@ -345,7 +348,7 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec)
          if (!persistent_mapping)
             vbo_exec_vtx_map(exec);
 
-         _mesa_restore_draw_vao(ctx, old_vao);
+         _mesa_restore_draw_vao(ctx, old_vao, old_vp_input_filter);
       }
    }
 
index 20da9c4..1d95737 100644 (file)
@@ -203,7 +203,6 @@ vbo_save_playback_vertex_list_gallium(struct gl_context *ctx,
     * which attribs have stride = 0 and whether edge flags are enabled.
     */
    const GLbitfield enabled = node->enabled_attribs[mode];
-   ctx->Array._DrawVAOEnabledAttribs = enabled;
    _mesa_set_varying_vp_inputs(ctx, enabled);
 
    if (ctx->NewState)
@@ -323,10 +322,13 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data, bool copy_to_c
 
    /* Save the Draw VAO before we override it. */
    const gl_vertex_processing_mode mode = ctx->VertexProgram._VPMode;
+   GLbitfield vao_filter = _vbo_get_vao_filter(mode);
    struct gl_vertex_array_object *old_vao;
+   GLbitfield old_vp_input_filter;
 
-   _mesa_save_and_set_draw_vao(ctx, node->cold->VAO[mode], &old_vao);
-   _mesa_update_vao_state(ctx, _vbo_get_vao_filter(mode));
+   _mesa_save_and_set_draw_vao(ctx, node->cold->VAO[mode], vao_filter,
+                               &old_vao, &old_vp_input_filter);
+   _mesa_update_vao_state(ctx, vao_filter);
 
    /* Need that at least one time. */
    if (ctx->NewState)
@@ -334,7 +336,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_restore_draw_vao(ctx, old_vao, old_vp_input_filter);
       _mesa_error(ctx, ctx->DrawGLError, "glCallList");
       return;
    }
@@ -356,7 +358,7 @@ 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);
+   _mesa_restore_draw_vao(ctx, old_vao, old_vp_input_filter);
 
    if (copy_to_current)
       playback_copy_to_current(ctx, node);