From 4e3c1ace659c7325bd8d54b66370c3755e40a266 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Thu, 8 Mar 2018 09:53:14 +0100 Subject: [PATCH] ac/nir: do not emit unnecessary null exports in fragment shaders Null exports should only be needed when no other exports are emitted. This removes a bunch of 'exp null off, off, off, off done vm'. Affected games are Dota 2 and Wolfenstein 2, not sure if that really helps, but code size is decreasing there. Polaris10: Totals from affected shaders: SGPRS: 8216 -> 8216 (0.00 %) VGPRS: 7072 -> 7072 (0.00 %) Spilled SGPRs: 0 -> 0 (0.00 %) Spilled VGPRs: 0 -> 0 (0.00 %) Code Size: 454968 -> 453896 (-0.24 %) bytes Max Waves: 772 -> 772 (0.00 %) Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen --- src/amd/common/ac_nir_to_llvm.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index c785244dcc4..9b850698608 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -6539,17 +6539,13 @@ handle_tcs_outputs_post(struct radv_shader_context *ctx) static bool si_export_mrt_color(struct radv_shader_context *ctx, - LLVMValueRef *color, unsigned index, bool is_last, + LLVMValueRef *color, unsigned index, struct ac_export_args *args) { /* Export */ si_llvm_init_export_args(ctx, color, 0xf, V_008DFC_SQ_EXP_MRT + index, args); - - if (is_last) { - args->valid_mask = 1; /* whether the EXEC mask is valid */ - args->done = 1; /* DONE bit */ - } else if (!args->enabled_channels) + if (!args->enabled_channels) return false; /* unnecessary NULL export */ return true; @@ -6576,7 +6572,6 @@ handle_fs_outputs_post(struct radv_shader_context *ctx) for (unsigned i = 0; i < AC_LLVM_MAX_OUTPUTS; ++i) { LLVMValueRef values[4]; - bool last = false; if (!(ctx->output_mask & (1ull << i))) continue; @@ -6588,14 +6583,9 @@ handle_fs_outputs_post(struct radv_shader_context *ctx) values[j] = ac_to_float(&ctx->ac, radv_load_output(ctx, i, j)); - if (!ctx->shader_info->info.ps.writes_z && - !ctx->shader_info->info.ps.writes_stencil && - !ctx->shader_info->info.ps.writes_sample_mask) - last = ctx->output_mask <= ((1ull << (i + 1)) - 1); - bool ret = si_export_mrt_color(ctx, values, i - FRAG_RESULT_DATA0, - last, &color_args[index]); + &color_args[index]); if (ret) index++; } @@ -6614,6 +6604,19 @@ handle_fs_outputs_post(struct radv_shader_context *ctx) radv_load_output(ctx, FRAG_RESULT_SAMPLE_MASK, 0)); } + /* Set the DONE bit on last non-null color export only if Z isn't + * exported. + */ + if (index > 0 && + !ctx->shader_info->info.ps.writes_z && + !ctx->shader_info->info.ps.writes_stencil && + !ctx->shader_info->info.ps.writes_sample_mask) { + unsigned last = index - 1; + + color_args[last].valid_mask = 1; /* whether the EXEC mask is valid */ + color_args[last].done = 1; /* DONE bit */ + } + /* Export PS outputs. */ for (unsigned i = 0; i < index; i++) ac_build_export(&ctx->ac, &color_args[i]); -- 2.30.2