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@amd.com>
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -217,6 +217,7 @@ struct si_shader_context {
|
||||
|
||||
LLVMValueRef lds;
|
||||
LLVMValueRef gs_next_vertex[4];
|
||||
LLVMValueRef postponed_kill;
|
||||
LLVMValueRef return_value;
|
||||
|
||||
LLVMTypeRef voidt;
|
||||
|
||||
@@ -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]);
|
||||
|
||||
Reference in New Issue
Block a user