Mesa (staging/22.0): radv: only apply enable_mrt_output_nan_fixup for 32-bit float MRTs

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Apr 26 13:14:02 UTC 2022


Module: Mesa
Branch: staging/22.0
Commit: 812c15d7b53b997ff6acbcb9cb1d30634395b832
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=812c15d7b53b997ff6acbcb9cb1d30634395b832

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Thu Apr 21 12:41:27 2022 +0200

radv: only apply enable_mrt_output_nan_fixup for 32-bit float MRTs

This is incorrect for 32-bit integer MRTs which are clamped to the
maximum value of the format, and returning 0 can break some shaders.

This fixes a rendering issue with RAGE2.

Cc: mesa-stable
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4329
Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16103>

---

 src/amd/compiler/aco_instruction_selection.cpp |  8 +++-----
 src/amd/vulkan/radv_nir_to_llvm.c              | 10 +++-------
 src/amd/vulkan/radv_pipeline.c                 | 18 ++++++++++++++++--
 src/amd/vulkan/radv_shader.h                   |  4 ++--
 4 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp
index acb93f85b83..2d24932208c 100644
--- a/src/amd/compiler/aco_instruction_selection.cpp
+++ b/src/amd/compiler/aco_instruction_selection.cpp
@@ -11061,13 +11061,11 @@ export_fs_mrt_color(isel_context* ctx, int slot)
 
    bool is_int8 = (ctx->options->key.ps.is_int8 >> slot) & 1;
    bool is_int10 = (ctx->options->key.ps.is_int10 >> slot) & 1;
+   bool enable_mrt_output_nan_fixup = (ctx->options->key.ps.enable_mrt_output_nan_fixup >> slot) & 1;
    bool is_16bit = values[0].regClass() == v2b;
 
-   /* Replace NaN by zero (only 32-bit) to fix game bugs if requested. */
-   if (ctx->options->enable_mrt_output_nan_fixup && !is_16bit &&
-       (col_format == V_028714_SPI_SHADER_32_R || col_format == V_028714_SPI_SHADER_32_GR ||
-        col_format == V_028714_SPI_SHADER_32_AR || col_format == V_028714_SPI_SHADER_32_ABGR ||
-        col_format == V_028714_SPI_SHADER_FP16_ABGR)) {
+   /* Replace NaN by zero (for 32-bit float formats) to fix game bugs if requested. */
+   if (enable_mrt_output_nan_fixup && !is_16bit) {
       for (int i = 0; i < 4; i++) {
          if (!(write_mask & (1 << i)))
             continue;
diff --git a/src/amd/vulkan/radv_nir_to_llvm.c b/src/amd/vulkan/radv_nir_to_llvm.c
index 6aaa6233846..876c42dfe4e 100644
--- a/src/amd/vulkan/radv_nir_to_llvm.c
+++ b/src/amd/vulkan/radv_nir_to_llvm.c
@@ -909,6 +909,7 @@ si_llvm_init_export_args(struct radv_shader_context *ctx, LLVMValueRef *values,
       unsigned col_format = (ctx->options->key.ps.col_format >> (4 * index)) & 0xf;
       bool is_int8 = (ctx->options->key.ps.is_int8 >> index) & 1;
       bool is_int10 = (ctx->options->key.ps.is_int10 >> index) & 1;
+      bool enable_mrt_output_nan_fixup = (ctx->options->key.ps.enable_mrt_output_nan_fixup >> index) & 1;
 
       LLVMValueRef (*packf)(struct ac_llvm_context * ctx, LLVMValueRef args[2]) = NULL;
       LLVMValueRef (*packi)(struct ac_llvm_context * ctx, LLVMValueRef args[2], unsigned bits,
@@ -988,13 +989,8 @@ si_llvm_init_export_args(struct radv_shader_context *ctx, LLVMValueRef *values,
          break;
       }
 
-      /* Replace NaN by zero (only 32-bit) to fix game bugs if
-       * requested.
-       */
-      if (ctx->options->enable_mrt_output_nan_fixup && !is_16bit &&
-          (col_format == V_028714_SPI_SHADER_32_R || col_format == V_028714_SPI_SHADER_32_GR ||
-           col_format == V_028714_SPI_SHADER_32_AR || col_format == V_028714_SPI_SHADER_32_ABGR ||
-           col_format == V_028714_SPI_SHADER_FP16_ABGR)) {
+      /* Replace NaN by zero (for 32-bit float formats) to fix game bugs if requested. */
+      if (enable_mrt_output_nan_fixup && !is_16bit) {
          for (unsigned i = 0; i < 4; i++) {
             LLVMValueRef class_args[2] = {values[i],
                                           LLVMConstInt(ctx->ac.i32, S_NAN | Q_NAN, false)};
diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index 827198e878d..8fa53b052ce 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -59,6 +59,7 @@ struct radv_blend_state {
    uint32_t spi_shader_col_format;
    uint32_t col_format_is_int8;
    uint32_t col_format_is_int10;
+   uint32_t col_format_is_float32;
    uint32_t cb_shader_mask;
    uint32_t db_alpha_to_mask;
 
@@ -524,6 +525,16 @@ format_is_int10(VkFormat format)
    return false;
 }
 
+static bool
+format_is_float32(VkFormat format)
+{
+   const struct util_format_description *desc = vk_format_description(format);
+   int channel = vk_format_get_first_non_void_channel(format);
+
+   return channel >= 0 &&
+          desc->channel[channel].type == UTIL_FORMAT_TYPE_FLOAT && desc->channel[channel].size == 32;
+}
+
 static void
 radv_pipeline_compute_spi_color_formats(const struct radv_pipeline *pipeline,
                                         const VkGraphicsPipelineCreateInfo *pCreateInfo,
@@ -531,7 +542,7 @@ radv_pipeline_compute_spi_color_formats(const struct radv_pipeline *pipeline,
 {
    const VkPipelineRenderingCreateInfoKHR *render_create_info =
       vk_find_struct_const(pCreateInfo->pNext, PIPELINE_RENDERING_CREATE_INFO_KHR);
-   unsigned col_format = 0, is_int8 = 0, is_int10 = 0;
+   unsigned col_format = 0, is_int8 = 0, is_int10 = 0, is_float32 = 0;
    unsigned num_targets;
 
    if (render_create_info) {
@@ -552,6 +563,8 @@ radv_pipeline_compute_spi_color_formats(const struct radv_pipeline *pipeline,
                is_int8 |= 1 << i;
             if (format_is_int10(fmt))
                is_int10 |= 1 << i;
+            if (format_is_float32(fmt))
+               is_float32 |= 1 << i;
          }
 
          col_format |= cf << (4 * i);
@@ -588,6 +601,7 @@ radv_pipeline_compute_spi_color_formats(const struct radv_pipeline *pipeline,
    blend->spi_shader_col_format = col_format;
    blend->col_format_is_int8 = is_int8;
    blend->col_format_is_int10 = is_int10;
+   blend->col_format_is_float32 = is_float32;
 }
 
 /*
@@ -2952,7 +2966,7 @@ radv_generate_graphics_pipeline_key(const struct radv_pipeline *pipeline,
       key.ps.lower_discard_to_demote = true;
 
    if (pipeline->device->instance->enable_mrt_output_nan_fixup)
-      key.ps.enable_mrt_output_nan_fixup = true;
+      key.ps.enable_mrt_output_nan_fixup = blend->col_format_is_float32;
 
    key.ps.force_vrs = pipeline->device->force_vrs;
 
diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h
index 6fd999b1b73..362220e4e50 100644
--- a/src/amd/vulkan/radv_shader.h
+++ b/src/amd/vulkan/radv_shader.h
@@ -90,7 +90,7 @@ struct radv_pipeline_key {
       uint8_t num_samples;
 
       bool lower_discard_to_demote;
-      bool enable_mrt_output_nan_fixup;
+      uint8_t enable_mrt_output_nan_fixup;
       uint8_t force_vrs;
    } ps;
 
@@ -121,7 +121,7 @@ struct radv_nir_compiler_options {
    bool check_ir;
    bool has_ls_vgpr_init_bug;
    bool has_image_load_dcc_bug;
-   bool enable_mrt_output_nan_fixup;
+   uint8_t enable_mrt_output_nan_fixup;
    bool wgp_mode;
    bool remap_spi_ps_input;
    bool disable_aniso_single_level;



More information about the mesa-commit mailing list