From 566675882035e8dc006a2c21fbd5cb2767d8145f Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Tue, 9 May 2023 19:59:54 +0200 Subject: [PATCH] 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: --- src/freedreno/ir3/ir3_compiler_nir.c | 3 +++ src/freedreno/ir3/ir3_shader.h | 3 ++- src/freedreno/vulkan/tu_pipeline.cc | 12 ++++-------- src/gallium/drivers/freedreno/a6xx/fd6_program.cc | 5 ++--- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index d36753ce5d8..bc80313439e 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -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; diff --git a/src/freedreno/ir3/ir3_shader.h b/src/freedreno/ir3/ir3_shader.h index f356bc6a444..5c62daeb544 100644 --- a/src/freedreno/ir3/ir3_shader.h +++ b/src/freedreno/ir3/ir3_shader.h @@ -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; } diff --git a/src/freedreno/vulkan/tu_pipeline.cc b/src/freedreno/vulkan/tu_pipeline.cc index 4de9034a72c..e536333d526 100644 --- a/src/freedreno/vulkan/tu_pipeline.cc +++ b/src/freedreno/vulkan/tu_pipeline.cc @@ -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) | diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_program.cc b/src/gallium/drivers/freedreno/a6xx/fd6_program.cc index 3c40eb2eff1..efb9a1b96df 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_program.cc +++ b/src/gallium/drivers/freedreno/a6xx/fd6_program.cc @@ -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)