From fe1d53355324a42ca6c69bd565131255aec0a56c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 22 Nov 2022 06:57:43 -0500 Subject: [PATCH] mesa: move _DrawVAOEnabledAttribs determination into st_update_array 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 Part-of: --- src/mesa/main/arrayobj.h | 18 +++++++--- src/mesa/main/draw.c | 44 +++++++++++++++--------- src/mesa/main/draw.h | 7 ++-- src/mesa/main/mtypes.h | 9 ----- src/mesa/state_tracker/st_atom_array.cpp | 23 +++++++++---- src/mesa/state_tracker/st_cb_rasterpos.c | 6 ++-- src/mesa/state_tracker/st_context.c | 3 +- src/mesa/vbo/vbo_exec_draw.c | 13 ++++--- src/mesa/vbo/vbo_save_draw.c | 12 ++++--- 9 files changed, 83 insertions(+), 52 deletions(-) diff --git a/src/mesa/main/arrayobj.h b/src/mesa/main/arrayobj.h index 2914932868b..3edb4252c91 100644 --- a/src/mesa/main/arrayobj.h +++ b/src/mesa/main/arrayobj.h @@ -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: diff --git a/src/mesa/main/draw.c b/src/mesa/main/draw.c index febcaae0f93..9f264b72401 100644 --- a/src/mesa/main/draw.c +++ b/src/mesa/main/draw.c @@ -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); } diff --git a/src/mesa/main/draw.h b/src/mesa/main/draw.h index 1e558379768..e55ed8a4fc3 100644 --- a/src/mesa/main/draw.h +++ b/src/mesa/main/draw.h @@ -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); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index ac73ccf66bb..da6b80a2a88 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -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 diff --git a/src/mesa/state_tracker/st_atom_array.cpp b/src/mesa/state_tracker/st_atom_array.cpp index 759a3221e6b..1398e8aa454 100644 --- a/src/mesa/state_tracker/st_atom_array.cpp +++ b/src/mesa/state_tracker/st_atom_array.cpp @@ -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 (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 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(curmask); unsigned num_dual_attribs = util_bitcount_fast(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 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 (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(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 - (st, enabled_user_attribs, nonzero_divisor_attribs); + (st, enabled_attribs, enabled_user_attribs, nonzero_divisor_attribs); } else { st_update_array_templ - (st, enabled_user_attribs, nonzero_divisor_attribs); + (st, enabled_attribs, enabled_user_attribs, nonzero_divisor_attribs); } } diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c index 0b9582aa082..90e6d0f0fb4 100644 --- a/src/mesa/state_tracker/st_cb_rasterpos.c +++ b/src/mesa/state_tracker/st_cb_rasterpos.c @@ -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) { diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 9bc63b5f9af..80d2e608a99 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -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; } diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index 1c39ef43b84..81a26df1019 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -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); } } diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index 20da9c43fbc..1d9573738cd 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -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);