diff options
-rw-r--r-- | src/amd/llvm/ac_llvm_build.c | 35 | ||||
-rw-r--r-- | src/amd/llvm/ac_llvm_build.h | 4 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/gfx10_shader_ngg.c | 26 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_compute_prim_discard.c | 19 |
4 files changed, 47 insertions, 37 deletions
diff --git a/src/amd/llvm/ac_llvm_build.c b/src/amd/llvm/ac_llvm_build.c index 3640c7c22fa..33cec6b878d 100644 --- a/src/amd/llvm/ac_llvm_build.c +++ b/src/amd/llvm/ac_llvm_build.c @@ -4967,3 +4967,38 @@ LLVMValueRef ac_prefix_bitcount_2x64(struct ac_llvm_context *ctx, return LLVMBuildAdd(builder, prefix_bcnt[0], prefix_bcnt[1], ""); #endif } + +/** + * Convert triangle strip indices to triangle indices. This is used to decompose + * triangle strips into triangles. + */ +void ac_build_triangle_strip_indices_to_triangle(struct ac_llvm_context *ctx, + LLVMValueRef is_odd, + LLVMValueRef flatshade_first, + LLVMValueRef index[3]) +{ + LLVMBuilderRef builder = ctx->builder; + LLVMValueRef out[3]; + + /* We need to change the vertex order for odd triangles to get correct + * front/back facing by swapping 2 vertex indices, but we also have to + * keep the provoking vertex in the same place. + * + * If the first vertex is provoking, swap index 1 and 2. + * If the last vertex is provoking, swap index 0 and 1. + */ + out[0] = LLVMBuildSelect(builder, flatshade_first, + index[0], + LLVMBuildSelect(builder, is_odd, + index[1], index[0], ""), ""); + out[1] = LLVMBuildSelect(builder, flatshade_first, + LLVMBuildSelect(builder, is_odd, + index[2], index[1], ""), + LLVMBuildSelect(builder, is_odd, + index[0], index[1], ""), ""); + out[2] = LLVMBuildSelect(builder, flatshade_first, + LLVMBuildSelect(builder, is_odd, + index[1], index[2], ""), + index[2], ""); + memcpy(index, out, sizeof(out)); +} diff --git a/src/amd/llvm/ac_llvm_build.h b/src/amd/llvm/ac_llvm_build.h index 4be06a9c104..772054efecd 100644 --- a/src/amd/llvm/ac_llvm_build.h +++ b/src/amd/llvm/ac_llvm_build.h @@ -795,6 +795,10 @@ LLVMValueRef ac_prefix_bitcount(struct ac_llvm_context *ctx, LLVMValueRef mask, LLVMValueRef index); LLVMValueRef ac_prefix_bitcount_2x64(struct ac_llvm_context *ctx, LLVMValueRef mask[2], LLVMValueRef index); +void ac_build_triangle_strip_indices_to_triangle(struct ac_llvm_context *ctx, + LLVMValueRef is_odd, + LLVMValueRef flatshade_first, + LLVMValueRef index[3]); #ifdef __cplusplus } diff --git a/src/gallium/drivers/radeonsi/gfx10_shader_ngg.c b/src/gallium/drivers/radeonsi/gfx10_shader_ngg.c index 8092b796b5d..9d50409bf39 100644 --- a/src/gallium/drivers/radeonsi/gfx10_shader_ngg.c +++ b/src/gallium/drivers/radeonsi/gfx10_shader_ngg.c @@ -1894,14 +1894,7 @@ void gfx10_ngg_gs_emit_epilogue(struct si_shader_context *ctx) prim.edgeflag[i] = ctx->ac.i1false; } - /* Geometry shaders output triangle strips, but NGG expects triangles. - * We need to change the vertex order for odd triangles to get correct - * front/back facing by swapping 2 vertex indices, but we also have to - * keep the provoking vertex in the same place. - * - * If the first vertex is provoking, swap index 1 and 2. - * If the last vertex is provoking, swap index 0 and 1. - */ + /* Geometry shaders output triangle strips, but NGG expects triangles. */ if (verts_per_prim == 3) { LLVMValueRef is_odd = LLVMBuildLShr(builder, flags, ctx->ac.i8_1, ""); is_odd = LLVMBuildTrunc(builder, is_odd, ctx->i1, ""); @@ -1910,20 +1903,9 @@ void gfx10_ngg_gs_emit_epilogue(struct si_shader_context *ctx) si_unpack_param(ctx, ctx->vs_state_bits, 4, 2), ctx->i32_0, ""); - struct ac_ngg_prim in = prim; - prim.index[0] = LLVMBuildSelect(builder, flatshade_first, - in.index[0], - LLVMBuildSelect(builder, is_odd, - in.index[1], in.index[0], ""), ""); - prim.index[1] = LLVMBuildSelect(builder, flatshade_first, - LLVMBuildSelect(builder, is_odd, - in.index[2], in.index[1], ""), - LLVMBuildSelect(builder, is_odd, - in.index[0], in.index[1], ""), ""); - prim.index[2] = LLVMBuildSelect(builder, flatshade_first, - LLVMBuildSelect(builder, is_odd, - in.index[1], in.index[2], ""), - in.index[2], ""); + ac_build_triangle_strip_indices_to_triangle(&ctx->ac, is_odd, + flatshade_first, + prim.index); } ac_build_export_prim(&ctx->ac, &prim); diff --git a/src/gallium/drivers/radeonsi/si_compute_prim_discard.c b/src/gallium/drivers/radeonsi/si_compute_prim_discard.c index 2fcec436bb0..57c73e33a97 100644 --- a/src/gallium/drivers/radeonsi/si_compute_prim_discard.c +++ b/src/gallium/drivers/radeonsi/si_compute_prim_discard.c @@ -656,21 +656,10 @@ void si_build_prim_discard_compute_shader(struct si_shader_context *ctx) LLVMBuildXor(builder, first_is_odd, LLVMBuildTrunc(builder, thread_id, ctx->i1, ""), ""); - /* Determine the primitive orientation. - * Only swap the vertices that are not the provoking vertex. We need to keep - * the provoking vertex in place. - */ - if (key->opt.cs_provoking_vertex_first) { - LLVMValueRef index1 = index[1]; - LLVMValueRef index2 = index[2]; - index[1] = LLVMBuildSelect(builder, prim_is_odd, index2, index1, ""); - index[2] = LLVMBuildSelect(builder, prim_is_odd, index1, index2, ""); - } else { - LLVMValueRef index0 = index[0]; - LLVMValueRef index1 = index[1]; - index[0] = LLVMBuildSelect(builder, prim_is_odd, index1, index0, ""); - index[1] = LLVMBuildSelect(builder, prim_is_odd, index0, index1, ""); - } + /* Convert triangle strip indices to triangle indices. */ + ac_build_triangle_strip_indices_to_triangle(&ctx->ac, prim_is_odd, + LLVMConstInt(ctx->i1, key->opt.cs_provoking_vertex_first, 0), + index); } /* Execute the vertex shader for each vertex to get vertex positions. */ |