aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2019-11-05 12:04:57 +0100
committerSamuel Pitoiset <[email protected]>2019-11-07 19:21:15 +0000
commitdeafe4cc58746a3c46d16a9cf784819d49848dc6 (patch)
tree34a538b1117c0a5fda96fb997e281757d9679fcc
parent49ee657ef8ce30f9e829d23b6b9a3a6cb9ef0434 (diff)
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 <[email protected]> Reviewed-by: Bas Nieuwenhuizen <[email protected]>
-rw-r--r--src/amd/vulkan/radv_nir_to_llvm.c52
-rw-r--r--src/amd/vulkan/radv_pipeline.c2
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.
*/