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 <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19953>
This commit is contained in:
Marek Olšák
2022-11-22 06:57:43 -05:00
committed by Marge Bot
parent 01ef28f1af
commit fe1d533553
9 changed files with 83 additions and 52 deletions

View 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:

View 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);
}

View 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);

View 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

View 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);
}
}

View 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) {

View 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;
}

View 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);
}
}

View 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);