Mesa (master): radeonsi: implement the workaround for Rocket League - postponed TGSI kill

Marek Olšák mareko at kemper.freedesktop.org
Fri Jun 23 17:51:30 UTC 2017


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

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Tue Jun 20 22:55:56 2017 +0200

radeonsi: implement the workaround for Rocket League - postponed TGSI kill

Do KILL at the end of shaders so as not to break WQM.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100070

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>

---

 src/gallium/drivers/radeon/r600_pipe_common.c     |  5 +++++
 src/gallium/drivers/radeon/r600_pipe_common.h     |  1 +
 src/gallium/drivers/radeonsi/si_shader.c          |  9 +++++++++
 src/gallium/drivers/radeonsi/si_shader_internal.h |  1 +
 src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c | 21 +++++++++++++++++++++
 5 files changed, 37 insertions(+)

diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
index 04f7fc19e9..fd67d9ae1b 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.c
+++ b/src/gallium/drivers/radeon/r600_pipe_common.c
@@ -1382,6 +1382,11 @@ bool r600_common_screen_init(struct r600_common_screen *rscreen,
 	rscreen->has_rbplus = false;
 	rscreen->rbplus_allowed = false;
 
+	/* Set the flag in debug_flags, so that the shader cache takes it
+	 * into account. */
+	if (flags & PIPE_SCREEN_ENABLE_CORRECT_TGSI_DERIVATIVES_AFTER_KILL)
+		rscreen->debug_flags |= DBG_FS_CORRECT_DERIVS_AFTER_KILL;
+
 	r600_disk_cache_create(rscreen);
 
 	slab_create_parent(&rscreen->pool_transfers, sizeof(struct r600_transfer), 64);
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index e67982a409..b22a3a75cb 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -85,6 +85,7 @@
 #define DBG_PREOPT_IR		(1 << 15)
 #define DBG_CHECK_IR		(1 << 16)
 #define DBG_NO_OPT_VARIANT	(1 << 17)
+#define DBG_FS_CORRECT_DERIVS_AFTER_KILL (1 << 18)
 /* gaps */
 #define DBG_TEST_DMA		(1 << 20)
 /* Bits 21-31 are reserved for the r600g driver. */
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index e525a18076..ecc51a3f4f 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -3251,6 +3251,9 @@ static void si_llvm_return_fs_outputs(struct lp_build_tgsi_context *bld_base)
 	LLVMValueRef depth = NULL, stencil = NULL, samplemask = NULL;
 	LLVMValueRef ret;
 
+	if (ctx->postponed_kill)
+		ac_build_kill(&ctx->ac, LLVMBuildLoad(builder, ctx->postponed_kill, ""));
+
 	/* Read the output values. */
 	for (i = 0; i < info->num_outputs; i++) {
 		unsigned semantic_name = info->output_semantic_name[i];
@@ -5530,6 +5533,12 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx,
 		}
 	}
 
+	if (ctx->type == PIPE_SHADER_FRAGMENT && sel->info.uses_kill &&
+	    ctx->screen->b.debug_flags & DBG_FS_CORRECT_DERIVS_AFTER_KILL) {
+		/* This is initialized to 0.0 = not kill. */
+		ctx->postponed_kill = lp_build_alloca(&ctx->gallivm, ctx->f32, "");
+	}
+
 	if (!lp_build_tgsi_llvm(bld_base, sel->tokens)) {
 		fprintf(stderr, "Failed to translate shader from TGSI to LLVM\n");
 		return false;
diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h
index 5ccde713c7..3556e69cd0 100644
--- a/src/gallium/drivers/radeonsi/si_shader_internal.h
+++ b/src/gallium/drivers/radeonsi/si_shader_internal.h
@@ -217,6 +217,7 @@ struct si_shader_context {
 
 	LLVMValueRef lds;
 	LLVMValueRef gs_next_vertex[4];
+	LLVMValueRef postponed_kill;
 	LLVMValueRef return_value;
 
 	LLVMTypeRef voidt;
diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c
index 9fa56c7576..12f8de4056 100644
--- a/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_alu.c
@@ -60,6 +60,27 @@ static void kil_emit(const struct lp_build_tgsi_action *action,
 		     struct lp_build_emit_data *emit_data)
 {
 	struct si_shader_context *ctx = si_shader_context(bld_base);
+	LLVMBuilderRef builder = ctx->gallivm.builder;
+
+	if (ctx->postponed_kill) {
+		if (emit_data->inst->Instruction.Opcode == TGSI_OPCODE_KILL_IF) {
+			LLVMValueRef val;
+
+			/* Take the minimum kill value. This is the same as OR
+			 * between 2 kill values. If the value is negative,
+			 * the pixel will be killed.
+			 */
+			val = LLVMBuildLoad(builder, ctx->postponed_kill, "");
+			val = lp_build_emit_llvm_binary(bld_base, TGSI_OPCODE_MIN,
+							val, emit_data->args[0]);
+			LLVMBuildStore(builder, val, ctx->postponed_kill);
+		} else {
+			LLVMBuildStore(builder,
+				       LLVMConstReal(ctx->f32, -1),
+				       ctx->postponed_kill);
+		}
+		return;
+	}
 
 	if (emit_data->inst->Instruction.Opcode == TGSI_OPCODE_KILL_IF)
 		ac_build_kill(&ctx->ac, emit_data->args[0]);




More information about the mesa-commit mailing list