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:
@@ -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:
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user