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>
}
}
+/**
+ * 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
*/
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)
{
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:
/**
* 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;
_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);
}
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);
* 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
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);
}
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 &
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);
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)
{
/* 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 =
{
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
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);
}
}
/* 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) {
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;
}
*/
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;
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);
}
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);
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);
}
}
* 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)
/* 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)
/* 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;
}
}
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);