Mesa (master): radv/gfx10: fix primitive indices orientation for NGG GS

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Nov 7 19:22:13 UTC 2019


Module: Mesa
Branch: master
Commit: deafe4cc58746a3c46d16a9cf784819d49848dc6
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=deafe4cc58746a3c46d16a9cf784819d49848dc6

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Tue Nov  5 12:04:57 2019 +0100

radv/gfx10: fix primitive indices orientation for NGG GS

The primitive indices have to be swapped to follow the drawing
order.

This fixes corruption with Overwatch when NGG GS is force enabled.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>

---

 src/amd/vulkan/radv_nir_to_llvm.c | 52 +++++++++++++++++++++++++++++++++------
 src/amd/vulkan/radv_pipeline.c    |  2 --
 2 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/src/amd/vulkan/radv_nir_to_llvm.c b/src/amd/vulkan/radv_nir_to_llvm.c
index 07c9d0e2a19..1ed1a382a37 100644
--- a/src/amd/vulkan/radv_nir_to_llvm.c
+++ b/src/amd/vulkan/radv_nir_to_llvm.c
@@ -3137,6 +3137,7 @@ static void build_sendmsg_gs_alloc_req(struct radv_shader_context *ctx,
 struct ngg_prim {
 	unsigned num_vertices;
 	LLVMValueRef isnull;
+	LLVMValueRef swap;
 	LLVMValueRef index[3];
 	LLVMValueRef edgeflag[3];
 };
@@ -3146,19 +3147,52 @@ static void build_export_prim(struct radv_shader_context *ctx,
 {
 	LLVMBuilderRef builder = ctx->ac.builder;
 	struct ac_export_args args;
+	LLVMValueRef vertices[3];
+	LLVMValueRef odd, even;
 	LLVMValueRef tmp;
 
 	tmp = LLVMBuildZExt(builder, prim->isnull, ctx->ac.i32, "");
 	args.out[0] = LLVMBuildShl(builder, tmp, LLVMConstInt(ctx->ac.i32, 31, false), "");
 
 	for (unsigned i = 0; i < prim->num_vertices; ++i) {
-		tmp = LLVMBuildShl(builder, prim->index[i],
-				   LLVMConstInt(ctx->ac.i32, 10 * i, false), "");
-		args.out[0] = LLVMBuildOr(builder, args.out[0], tmp, "");
-		tmp = LLVMBuildZExt(builder, prim->edgeflag[i], ctx->ac.i32, "");
-		tmp = LLVMBuildShl(builder, tmp,
-				   LLVMConstInt(ctx->ac.i32, 10 * i + 9, false), "");
-		args.out[0] = LLVMBuildOr(builder, args.out[0], tmp, "");
+               tmp = LLVMBuildZExt(builder, prim->edgeflag[i], ctx->ac.i32, "");
+               tmp = LLVMBuildShl(builder, tmp,
+                                  LLVMConstInt(ctx->ac.i32, 9, false), "");
+               vertices[i] = LLVMBuildOr(builder, prim->index[i], tmp, "");
+	}
+
+	switch (prim->num_vertices) {
+	case 1:
+		args.out[0] = LLVMBuildOr(builder, args.out[0], vertices[0], "");
+		break;
+	case 2:
+		tmp = LLVMBuildShl(builder, vertices[1],
+				   LLVMConstInt(ctx->ac.i32, 10, false), "");
+		tmp = LLVMBuildOr(builder, args.out[0], tmp, "");
+		args.out[0] = LLVMBuildOr(builder, tmp, vertices[0], "");
+		break;
+	case 3:
+		/* Swap vertices if needed to follow drawing order. */
+		tmp = LLVMBuildShl(builder, vertices[2],
+				   LLVMConstInt(ctx->ac.i32, 20, false), "");
+		even = LLVMBuildOr(builder, args.out[0], tmp, "");
+		tmp = LLVMBuildShl(builder, vertices[1],
+				   LLVMConstInt(ctx->ac.i32, 10, false), "");
+		even = LLVMBuildOr(builder, even, tmp, "");
+		even = LLVMBuildOr(builder, even, vertices[0], "");
+
+		tmp = LLVMBuildShl(builder, vertices[1],
+				   LLVMConstInt(ctx->ac.i32, 20, false), "");
+		odd = LLVMBuildOr(builder, args.out[0], tmp, "");
+		tmp = LLVMBuildShl(builder, vertices[2],
+				   LLVMConstInt(ctx->ac.i32, 10, false), "");
+		odd = LLVMBuildOr(builder, odd, tmp, "");
+		odd = LLVMBuildOr(builder, odd, vertices[0], "");
+
+		args.out[0] = LLVMBuildSelect(builder, prim->swap, odd, even, "");
+		break;
+	default:
+		unreachable("invalid number of vertices");
 	}
 
 	args.out[0] = LLVMBuildBitCast(builder, args.out[0], ctx->ac.f32, "");
@@ -3784,6 +3818,7 @@ handle_ngg_outputs_post_2(struct radv_shader_context *ctx)
 
 		prim.num_vertices = num_vertices;
 		prim.isnull = ctx->ac.i1false;
+		prim.swap = ctx->ac.i1false;
 		memcpy(prim.index, vtxindex, sizeof(vtxindex[0]) * 3);
 
 		for (unsigned i = 0; i < num_vertices; ++i) {
@@ -4092,6 +4127,9 @@ static void gfx10_ngg_gs_emit_epilogue_2(struct radv_shader_context *ctx)
 		tmp = LLVMBuildLoad(builder, tmp, "");
 		prim.isnull = LLVMBuildICmp(builder, LLVMIntEQ, tmp,
 					    LLVMConstInt(ctx->ac.i8, 0, false), "");
+		prim.swap = LLVMBuildICmp(builder, LLVMIntEQ,
+					  LLVMBuildAnd(builder, tid, LLVMConstInt(ctx->ac.i32, 1, false), ""),
+					  LLVMConstInt(ctx->ac.i32, 1, false), "");
 
 		for (unsigned i = 0; i < verts_per_prim; ++i) {
 			prim.index[i] = LLVMBuildSub(builder, vertlive_scan.result_exclusive,
diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index a2839b65dd5..c187e3e7d2c 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -2347,8 +2347,6 @@ radv_fill_shader_keys(struct radv_device *device,
 		 * issues still:
 		 *   * GS primitives in pipeline statistic queries do not get
 		 *     updates. See dEQP-VK.query_pool.statistics_query.geometry_shader_primitives
-		 *   * General issues with the last primitive missing/corrupt:
-		 *     https://bugs.freedesktop.org/show_bug.cgi?id=111248
 		 *
 		 * Furthermore, XGL/AMDVLK also disables this as of 9b632ef.
 		 */




More information about the mesa-commit mailing list