mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 13:48:06 +02:00
turnip, ir3: Use shader for vertex input count
Maintenance9 will require us to make unbound vertex inputs (that is, attributes in the VS without a corresponding binding at the same location) be defined. In order for this to work, VFD_FETCH_INSTR_INSTR must be defined for all attributes used in the shader. Imagine we do something like: CmdSetVertexInputs(only 1 input at location 0) CmdBindPipeline(VS reads only location 0) CmdDraw() CmdBindPipeline(VS reads locations 0 and 1) CmdDraw() For the first draw we only need to emit VFD_FETCH_INSTR_INSTR[0], for the second draw we need to emit VFD_FETCH_INSTR_INSTR[1] as well in the VI draw state. This unfortunately means we have to do draw-time validation for vertex input state. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40552>
This commit is contained in:
parent
b8a5aeee48
commit
789e765161
6 changed files with 32 additions and 17 deletions
|
|
@ -5170,6 +5170,9 @@ setup_input(struct ir3_context *ctx, nir_intrinsic_instr *intr)
|
|||
unsigned idx = (n * 4) + i + frac;
|
||||
ctx->last_dst[i] = ctx->inputs[idx];
|
||||
}
|
||||
|
||||
if (slot >= VERT_ATTRIB_GENERIC0)
|
||||
so->attr_in = MAX2(so->attr_in, slot - VERT_ATTRIB_GENERIC0 + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -825,6 +825,11 @@ struct ir3_shader_variant {
|
|||
*/
|
||||
unsigned varying_in;
|
||||
|
||||
/* For vertex shaders, the number of generic attribute slots (i.e. 1 plus the
|
||||
* max VERT_ATTRIB_GENERICn).
|
||||
*/
|
||||
unsigned attr_in;
|
||||
|
||||
/* Remapping table to map Image and SSBO to hw state: */
|
||||
struct ir3_ibo_mapping image_mapping;
|
||||
|
||||
|
|
|
|||
|
|
@ -5329,7 +5329,10 @@ TU_GENX(tu_EndCommandBuffer);
|
|||
static void
|
||||
tu_bind_vs(struct tu_cmd_buffer *cmd, struct tu_shader *vs)
|
||||
{
|
||||
cmd->state.shaders[MESA_SHADER_VERTEX] = vs;
|
||||
if (cmd->state.shaders[MESA_SHADER_VERTEX] != vs) {
|
||||
cmd->state.shaders[MESA_SHADER_VERTEX] = vs;
|
||||
cmd->state.dirty |= TU_CMD_DIRTY_VS;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ enum tu_cmd_dirty_bits
|
|||
TU_CMD_DIRTY_SHADING_RATE = BIT(15),
|
||||
TU_CMD_DIRTY_DISABLE_FS = BIT(16),
|
||||
TU_CMD_DIRTY_TCS = BIT(17),
|
||||
TU_CMD_DIRTY_VS = BIT(18),
|
||||
|
||||
/* all draw states were disabled and need to be re-enabled: */
|
||||
TU_CMD_DIRTY_DRAW_STATE = BIT(18)
|
||||
|
|
|
|||
|
|
@ -2451,17 +2451,18 @@ static const enum mesa_vk_dynamic_graphics_state tu_vertex_input_state[] = {
|
|||
template <chip CHIP>
|
||||
static unsigned
|
||||
tu6_vertex_input_size(struct tu_device *dev,
|
||||
const struct vk_vertex_input_state *vi)
|
||||
const struct vk_vertex_input_state *vi,
|
||||
unsigned attr_count)
|
||||
{
|
||||
return 1 + 2 * util_last_bit(vi->attributes_valid);
|
||||
return 1 + 2 * attr_count;
|
||||
}
|
||||
|
||||
template <chip CHIP>
|
||||
static void
|
||||
tu6_emit_vertex_input(struct tu_cs *cs,
|
||||
const struct vk_vertex_input_state *vi)
|
||||
const struct vk_vertex_input_state *vi,
|
||||
unsigned attr_count)
|
||||
{
|
||||
unsigned attr_count = util_last_bit(vi->attributes_valid);
|
||||
if (attr_count != 0)
|
||||
tu_cs_emit_pkt4(cs, REG_A6XX_VFD_FETCH_INSTR_INSTR(0), attr_count * 2);
|
||||
|
||||
|
|
@ -3924,8 +3925,10 @@ tu_pipeline_builder_emit_state(struct tu_pipeline_builder *builder,
|
|||
}
|
||||
#define DRAW_STATE(name, id, ...) DRAW_STATE_COND(name, id, true, __VA_ARGS__)
|
||||
|
||||
DRAW_STATE(vertex_input, TU_DYNAMIC_STATE_VERTEX_INPUT,
|
||||
builder->graphics_state.vi);
|
||||
DRAW_STATE_COND(vertex_input, TU_DYNAMIC_STATE_VERTEX_INPUT,
|
||||
pipeline->shaders[MESA_SHADER_VERTEX],
|
||||
builder->graphics_state.vi,
|
||||
pipeline->shaders[MESA_SHADER_VERTEX]->variant->attr_in);
|
||||
DRAW_STATE(vertex_stride, TU_DYNAMIC_STATE_VB_STRIDE,
|
||||
builder->graphics_state.vi);
|
||||
/* If (a) per-view viewport is used or (b) we don't know yet, then we need
|
||||
|
|
@ -4188,8 +4191,10 @@ tu_emit_draw_state(struct tu_cmd_buffer *cmd)
|
|||
}
|
||||
#define DRAW_STATE(name, id, ...) DRAW_STATE_COND(name, id, false, __VA_ARGS__)
|
||||
|
||||
DRAW_STATE(vertex_input, TU_DYNAMIC_STATE_VERTEX_INPUT,
|
||||
cmd->vk.dynamic_graphics_state.vi);
|
||||
DRAW_STATE_COND(vertex_input, TU_DYNAMIC_STATE_VERTEX_INPUT,
|
||||
cmd->state.dirty & TU_CMD_DIRTY_VS,
|
||||
cmd->vk.dynamic_graphics_state.vi,
|
||||
cmd->state.shaders[MESA_SHADER_VERTEX]->variant->attr_in);
|
||||
|
||||
/* Vertex input stride is special because it's part of the vertex input in
|
||||
* the pipeline but a separate array when it's dynamic state so we have to
|
||||
|
|
|
|||
|
|
@ -1982,7 +1982,6 @@ tu6_emit_vfd_dest(struct tu_cs *cs,
|
|||
const struct ir3_shader_variant *vs)
|
||||
{
|
||||
int32_t input_for_attr[MAX_VERTEX_ATTRIBS];
|
||||
uint32_t attr_count = 0;
|
||||
|
||||
for (unsigned i = 0; i < MAX_VERTEX_ATTRIBS; i++)
|
||||
input_for_attr[i] = -1;
|
||||
|
|
@ -1994,13 +1993,12 @@ tu6_emit_vfd_dest(struct tu_cs *cs,
|
|||
assert(vs->inputs[i].slot >= VERT_ATTRIB_GENERIC0);
|
||||
unsigned loc = vs->inputs[i].slot - VERT_ATTRIB_GENERIC0;
|
||||
input_for_attr[loc] = i;
|
||||
attr_count = MAX2(attr_count, loc + 1);
|
||||
}
|
||||
|
||||
tu_cs_emit_regs(cs,
|
||||
A6XX_VFD_CNTL_0(
|
||||
.fetch_cnt = attr_count, /* decode_cnt for binning pass ? */
|
||||
.decode_cnt = attr_count));
|
||||
.fetch_cnt = vs->attr_in, /* decode_cnt for binning pass ? */
|
||||
.decode_cnt = vs->attr_in));
|
||||
|
||||
if (CHIP >= A8XX) {
|
||||
const uint32_t vertexid_regid =
|
||||
|
|
@ -2016,15 +2014,15 @@ tu6_emit_vfd_dest(struct tu_cs *cs,
|
|||
(viewid_regid != INVALID_REG);
|
||||
|
||||
tu_cs_emit_regs(cs, PC_VS_INPUT_CNTL(CHIP,
|
||||
.instr_cnt = attr_count,
|
||||
.instr_cnt = vs->attr_in,
|
||||
.sideband_cnt = sideband_count,
|
||||
));
|
||||
}
|
||||
|
||||
if (attr_count)
|
||||
tu_cs_emit_pkt4(cs, REG_A6XX_VFD_DEST_CNTL_INSTR(0), attr_count);
|
||||
if (vs->attr_in)
|
||||
tu_cs_emit_pkt4(cs, REG_A6XX_VFD_DEST_CNTL_INSTR(0), vs->attr_in);
|
||||
|
||||
for (unsigned i = 0; i < attr_count; i++) {
|
||||
for (unsigned i = 0; i < vs->attr_in; i++) {
|
||||
if (input_for_attr[i] >= 0) {
|
||||
unsigned input_idx = input_for_attr[i];
|
||||
tu_cs_emit(cs, A6XX_VFD_DEST_CNTL_INSTR(0,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue