From c082cdacae8fc977f0c39ea12874e183ceac3286 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Wed, 5 Apr 2023 09:27:50 +0800 Subject: [PATCH] ac/nir/ngg: fix gs culling vertex liveness check for odd vertices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If vertex does not complete a primitive, it should not set the odd flag which miss lead liveness check when culling is enabled. For example, if odd flag is set regardless of complete flag, when culling is enabled, 3 vertices of a triangle's init prim flag: [0x00 0x04 0x01] then after culling, this triangle has been culled, their prim flag: [0x00 0x04 0x00] the second vertex is miss treat as live because its odd flag (code check prim_flag!=0 for liveness). Fixes: 1bdeb961bd8 ("ac/nir/ngg: add gs culling") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/8725 Reviewed-by: Timur Kristóf Signed-off-by: Qiang Yu Part-of: --- src/amd/common/ac_nir_lower_ngg.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/amd/common/ac_nir_lower_ngg.c b/src/amd/common/ac_nir_lower_ngg.c index c2ed88318b5..af8032290b8 100644 --- a/src/amd/common/ac_nir_lower_ngg.c +++ b/src/amd/common/ac_nir_lower_ngg.c @@ -2758,6 +2758,7 @@ lower_ngg_gs_emit_vertex_with_counter(nir_builder *b, nir_intrinsic_instr *intri /* Calculate and store per-vertex primitive flags based on vertex counts: * - bit 0: whether this vertex finishes a primitive (a real primitive, not the strip) * - bit 1: whether the primitive index is odd (if we are emitting triangle strips, otherwise always 0) + * only set when the vertex also finishes the primitive * - bit 2: whether vertex is live (if culling is enabled: set after culling, otherwise always 1) */ @@ -2771,8 +2772,9 @@ lower_ngg_gs_emit_vertex_with_counter(nir_builder *b, nir_intrinsic_instr *intri nir_ssa_def *prim_flag = nir_ior(b, vertex_live_flag, complete_flag); if (s->num_vertices_per_primitive == 3) { - nir_ssa_def *odd = nir_iand_imm(b, current_vtx_per_prim, 1); - prim_flag = nir_iadd_nuw(b, prim_flag, nir_ishl(b, odd, nir_imm_int(b, 1))); + nir_ssa_def *odd = nir_iand(b, current_vtx_per_prim, complete_flag); + nir_ssa_def *odd_flag = nir_ishl(b, odd, nir_imm_int(b, 1)); + prim_flag = nir_ior(b, prim_flag, odd_flag); } nir_store_shared(b, nir_u2u8(b, prim_flag), gs_emit_vtx_addr, .base = s->lds_offs_primflags + stream, .align_mul = 4u);