ac: add helper ac_build_triangle_strip_indices_to_triangle
authorMarek Olšák <marek.olsak@amd.com>
Fri, 10 Jan 2020 00:12:36 +0000 (19:12 -0500)
committerMarek Olšák <marek.olsak@amd.com>
Mon, 20 Jan 2020 21:16:11 +0000 (16:16 -0500)
Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
src/amd/llvm/ac_llvm_build.c
src/amd/llvm/ac_llvm_build.h
src/gallium/drivers/radeonsi/gfx10_shader_ngg.c
src/gallium/drivers/radeonsi/si_compute_prim_discard.c

index 3640c7c22fa74b1006b0c00051eb855e0cc78d8b..33cec6b878d2271d48729ba1be28568d7683816d 100644 (file)
@@ -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));
+}
index 4be06a9c1043fb0dc269e0df0687bbe2e0f83509..772054efecde2d8dd02eed161526c1e6884bcd64 100644 (file)
@@ -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
 }
index 8092b796b5d7b121f9ea07f6966280e61ecad7a7..9d50409bf3943dd159385634becdcb936020e10e 100644 (file)
@@ -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);
index 2fcec436bb0bec066a43ec96be2402ed72b0f97f..57c73e33a97d0eb8e48bbd69433a0c20ad4df10f 100644 (file)
@@ -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. */