tu, freedreno/a6xx: Don't use VS for PrimID passthru state

Emit the registers solely based on whether FS reads PrimID, and assume
the HW will do the right thing and disable PrimID passthru when GS is
enabled. This untangles these registers so we can set them from the FS
draw state in the future.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25076>
This commit is contained in:
Connor Abbott 2023-05-09 19:59:54 +02:00 committed by Marge Bot
parent b312155cc5
commit 5666758820
4 changed files with 11 additions and 12 deletions

View file

@ -3991,6 +3991,9 @@ setup_input(struct ir3_context *ctx, nir_intrinsic_instr *intr)
unsigned idx = (n * 4) + i + frac;
ctx->last_dst[i] = create_frag_input(ctx, coord, idx);
}
if (slot == VARYING_SLOT_PRIMITIVE_ID)
so->reads_primid = true;
} else {
struct ir3_instruction *input = NULL;

View file

@ -650,6 +650,7 @@ struct ir3_shader_variant {
bool half : 1;
bool flat : 1;
} inputs[32 + 2]; /* +POSITION +FACE */
bool reads_primid;
/* sum of input components (scalar). For frag shaders, it only counts
* the varying inputs:
@ -1120,7 +1121,7 @@ ir3_link_shaders(struct ir3_shader_linkage *l,
k = ir3_find_output(vs, (gl_varying_slot)fs->inputs[j].slot);
if (k < 0 && fs->inputs[j].slot == VARYING_SLOT_PRIMITIVE_ID) {
if (fs->inputs[j].slot == VARYING_SLOT_PRIMITIVE_ID) {
l->primid_loc = fs->inputs[j].inloc;
}

View file

@ -841,7 +841,7 @@ tu6_emit_vs_system_values(struct tu_cs *cs,
const struct ir3_shader_variant *hs,
const struct ir3_shader_variant *ds,
const struct ir3_shader_variant *gs,
bool primid_passthru)
const struct ir3_shader_variant *fs)
{
const uint32_t vertexid_regid =
ir3_find_sysval_regid(vs, SYSTEM_VALUE_VERTEX_ID);
@ -896,7 +896,7 @@ tu6_emit_vs_system_values(struct tu_cs *cs,
tu_cs_emit(cs, 0x000000fc); /* VFD_CONTROL_4 */
tu_cs_emit(cs, A6XX_VFD_CONTROL_5_REGID_GSHEADER(gsheader_regid) |
0xfc00); /* VFD_CONTROL_5 */
tu_cs_emit(cs, COND(primid_passthru, A6XX_VFD_CONTROL_6_PRIMID4PSEN)); /* VFD_CONTROL_6 */
tu_cs_emit(cs, COND(fs && fs->reads_primid, A6XX_VFD_CONTROL_6_PRIMID4PSEN)); /* VFD_CONTROL_6 */
}
static void
@ -1280,11 +1280,7 @@ tu6_emit_vpc(struct tu_cs *cs,
if (last_shader->stream_output.num_outputs)
ir3_link_stream_out(&linkage, last_shader);
/* We do this after linking shaders in order to know whether PrimID
* passthrough needs to be enabled.
*/
bool primid_passthru = linkage.primid_loc != 0xff;
tu6_emit_vs_system_values(cs, vs, hs, ds, gs, primid_passthru);
tu6_emit_vs_system_values(cs, vs, hs, ds, gs, fs);
tu_cs_emit_pkt4(cs, REG_A6XX_VPC_VAR_DISABLE(0), 4);
tu_cs_emit(cs, ~linkage.varmask[0]);
@ -1437,7 +1433,7 @@ tu6_emit_vpc(struct tu_cs *cs,
tu_cs_emit(cs, CONDREG(layer_regid, A6XX_GRAS_GS_LAYER_CNTL_WRITES_LAYER) |
CONDREG(view_regid, A6XX_GRAS_GS_LAYER_CNTL_WRITES_VIEW));
tu_cs_emit_regs(cs, A6XX_PC_PS_CNTL(.primitiveiden = primid_passthru));
tu_cs_emit_regs(cs, A6XX_PC_PS_CNTL(.primitiveiden = fs && fs->reads_primid));
tu_cs_emit_pkt4(cs, REG_A6XX_VPC_CNTL_0, 1);
tu_cs_emit(cs, A6XX_VPC_CNTL_0_NUMNONPOSVAR(fs ? fs->total_in : 0) |

View file

@ -622,7 +622,6 @@ setup_stateobj(struct fd_screen *screen, struct fd_ringbuffer *ring,
*/
ir3_link_shaders(&l, last_shader, do_streamout ? state->fs : fs, true);
bool primid_passthru = l.primid_loc != 0xff;
clip0_loc = l.clip0_loc;
clip1_loc = l.clip1_loc;
@ -1141,7 +1140,7 @@ setup_stateobj(struct fd_screen *screen, struct fd_ringbuffer *ring,
if (fs->instrlen)
fd6_emit_shader(ctx, ring, fs);
OUT_REG(ring, A6XX_PC_PS_CNTL(.primitiveiden = primid_passthru));
OUT_REG(ring, A6XX_PC_PS_CNTL(.primitiveiden = fs->reads_primid));
uint32_t non_sysval_input_count = 0;
for (uint32_t i = 0; i < vs->inputs_count; i++)
@ -1175,7 +1174,7 @@ setup_stateobj(struct fd_screen *screen, struct fd_ringbuffer *ring,
OUT_RING(ring, 0x000000fc); /* VFD_CONTROL_4 */
OUT_RING(ring, A6XX_VFD_CONTROL_5_REGID_GSHEADER(gs_header_regid) |
0xfc00); /* VFD_CONTROL_5 */
OUT_RING(ring, COND(primid_passthru,
OUT_RING(ring, COND(fs->reads_primid,
A6XX_VFD_CONTROL_6_PRIMID4PSEN)); /* VFD_CONTROL_6 */
if (!binning_pass)