panfrost: Fix instanced draws when attributes have a non-zero divisor
On Bifrost/Midgard, when an attribute has a non-zero divisors, the attribute offset is tweaked to take the base_instance into account, which implies we have to re-emit the attributes if the base instance value changed. Let's not bother tracking the last base instance and re-emit unconditionally in that case, which is still better than what we had before3db963a135
("panfrost: Emit attribs in panfrost_update_state_3d() on bifrost/midgard") and fixes the regression introduced by this commit. Fixes:3db963a135
("panfrost: Emit attribs in panfrost_update_state_3d() on bifrost/midgard") Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Tested-By: Chris Healy <healych@amazon.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33010>
This commit is contained in:

committed by
Marge Bot

parent
1c59793d2d
commit
8891c2aeba
@@ -2886,12 +2886,18 @@ panfrost_update_state_3d(struct panfrost_batch *batch)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
unsigned vt_shader_dirty = ctx->dirty_shader[PIPE_SHADER_VERTEX];
|
unsigned vt_shader_dirty = ctx->dirty_shader[PIPE_SHADER_VERTEX];
|
||||||
|
struct panfrost_compiled_shader *vs = ctx->prog[PIPE_SHADER_VERTEX];
|
||||||
|
struct panfrost_vertex_state *vstate = ctx->vertex;
|
||||||
|
bool attr_offsetted_by_instance_base =
|
||||||
|
vstate->attr_depends_on_base_instance_mask &
|
||||||
|
BITFIELD_MASK(vs->info.attributes_read_count);
|
||||||
|
|
||||||
/* Vertex data, vertex shader and images accessed by the vertex shader have
|
/* Vertex data, vertex shader and images accessed by the vertex shader have
|
||||||
* an impact on the attributes array, we need to re-emit anytime one of these
|
* an impact on the attributes array, we need to re-emit anytime one of these
|
||||||
* parameters changes. */
|
* parameters changes. */
|
||||||
if ((dirty & PAN_DIRTY_VERTEX) ||
|
if ((dirty & PAN_DIRTY_VERTEX) ||
|
||||||
(vt_shader_dirty & (PAN_DIRTY_STAGE_IMAGE | PAN_DIRTY_STAGE_SHADER))) {
|
(vt_shader_dirty & (PAN_DIRTY_STAGE_IMAGE | PAN_DIRTY_STAGE_SHADER)) ||
|
||||||
|
attr_offsetted_by_instance_base) {
|
||||||
batch->attribs[PIPE_SHADER_VERTEX] = panfrost_emit_vertex_data(
|
batch->attribs[PIPE_SHADER_VERTEX] = panfrost_emit_vertex_data(
|
||||||
batch, &batch->attrib_bufs[PIPE_SHADER_VERTEX]);
|
batch, &batch->attrib_bufs[PIPE_SHADER_VERTEX]);
|
||||||
}
|
}
|
||||||
@@ -3533,6 +3539,8 @@ panfrost_create_vertex_elements_state(struct pipe_context *pctx,
|
|||||||
so->element_buffer[i] = pan_assign_vertex_buffer(
|
so->element_buffer[i] = pan_assign_vertex_buffer(
|
||||||
so->buffers, &so->nr_bufs, elements[i].vertex_buffer_index,
|
so->buffers, &so->nr_bufs, elements[i].vertex_buffer_index,
|
||||||
elements[i].instance_divisor);
|
elements[i].instance_divisor);
|
||||||
|
if (elements[i].instance_divisor)
|
||||||
|
so->attr_depends_on_base_instance_mask |= BITFIELD_BIT(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < num_elements; ++i) {
|
for (int i = 0; i < num_elements; ++i) {
|
||||||
|
@@ -93,6 +93,12 @@ struct panfrost_vertex_state {
|
|||||||
unsigned element_buffer[PIPE_MAX_ATTRIBS];
|
unsigned element_buffer[PIPE_MAX_ATTRIBS];
|
||||||
unsigned nr_bufs;
|
unsigned nr_bufs;
|
||||||
|
|
||||||
|
/* Bitmask flagging attributes with a non-zero instance divisor which
|
||||||
|
* require an attribute offset adjustment when base_instance != 0.
|
||||||
|
* This is used to force attributes re-emission even if the vertex state
|
||||||
|
* isn't dirty to take the new base instance into account. */
|
||||||
|
uint32_t attr_depends_on_base_instance_mask;
|
||||||
|
|
||||||
unsigned formats[PIPE_MAX_ATTRIBS];
|
unsigned formats[PIPE_MAX_ATTRIBS];
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user