Module: Mesa
Branch: staging/23.3
Commit: 3d31646c7e07450878b98fe8e6bf0a14d45216de
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=3d31646c7e07450878b98fe8e6bf0a14d45216de

Author: Friedrich Vock <friedrich.v...@gmx.de>
Date:   Wed Nov 29 01:20:54 2023 +0100

radv,vtn,driconf: Add and use radv_rt_ssbo_non_uniform workaround for Crysis 
2/3 Remastered

Crysis 2 and 3 Remastered's RT shaders non-uniformly index into SSBO
descriptor arrays without specifying the NonUniformEXT qualifier on the
relevant access chains/load ops. This leads to artifacts around objects.

To add insult to injury, the game fails to provide a meaningful
applicationName/engineName in the Vulkan part of the DX11-Vulkan interop
solution used for RT. Both of these fields are set to "nvpro-sample"
(perhaps the code has been copied from NVIDIA's sample applications).
Therefore, fall back to executable name matching.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/9883
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26391>
(cherry picked from commit f1817ab7e03f188164c7d6850149781066418d49)

---

 .pick_status.json                  | 2 +-
 src/amd/vulkan/radv_instance.c     | 3 +++
 src/amd/vulkan/radv_pipeline.c     | 1 +
 src/amd/vulkan/radv_private.h      | 1 +
 src/amd/vulkan/radv_shader.c       | 1 +
 src/amd/vulkan/radv_shader.h       | 1 +
 src/compiler/spirv/nir_spirv.h     | 2 ++
 src/compiler/spirv/vtn_variables.c | 3 +++
 src/util/00-radv-defaults.conf     | 8 ++++++++
 src/util/driconf.h                 | 4 ++++
 10 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/.pick_status.json b/.pick_status.json
index 882b5efe2bb..866721e4d95 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -524,7 +524,7 @@
         "description": "radv,vtn,driconf: Add and use radv_rt_ssbo_non_uniform 
workaround for Crysis 2/3 Remastered",
         "nominated": true,
         "nomination_type": 0,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": null,
         "notes": null
diff --git a/src/amd/vulkan/radv_instance.c b/src/amd/vulkan/radv_instance.c
index 6cd78b4265f..14032b93a19 100644
--- a/src/amd/vulkan/radv_instance.c
+++ b/src/amd/vulkan/radv_instance.c
@@ -153,6 +153,7 @@ static const driOptionDescription radv_dri_options[] = {
       DRI_CONF_RADV_FLUSH_BEFORE_TIMESTAMP_WRITE(false)
       DRI_CONF_RADV_RT_WAVE64(false)
       DRI_CONF_DUAL_COLOR_BLEND_BY_LOCATION(false)
+      DRI_CONF_RADV_SSBO_NON_UNIFORM(false)
       DRI_CONF_RADV_APP_LAYER()
    DRI_CONF_SECTION_END
 };
@@ -203,6 +204,8 @@ radv_init_dri_options(struct radv_instance *instance)
 
    instance->tex_non_uniform = driQueryOptionb(&instance->dri_options, 
"radv_tex_non_uniform");
 
+   instance->ssbo_non_uniform = driQueryOptionb(&instance->dri_options, 
"radv_ssbo_non_uniform");
+
    instance->app_layer = driQueryOptionstr(&instance->dri_options, 
"radv_app_layer");
 
    instance->flush_before_timestamp_write =
diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index d9b5eb2a098..26303796128 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -162,6 +162,7 @@ radv_generate_pipeline_key(const struct radv_device 
*device, const VkPipelineSha
    key.image_2d_view_of_3d = device->image_2d_view_of_3d && 
device->physical_device->rad_info.gfx_level == GFX9;
 
    key.tex_non_uniform = device->instance->tex_non_uniform;
+   key.ssbo_non_uniform = device->instance->ssbo_non_uniform;
 
    for (unsigned i = 0; i < num_stages; ++i) {
       const VkPipelineShaderStageCreateInfo *const stage = &stages[i];
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index bb2b9925c7b..1d2e3f90769 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -416,6 +416,7 @@ struct radv_instance {
    bool flush_before_query_copy;
    bool enable_unified_heap_on_apu;
    bool tex_non_uniform;
+   bool ssbo_non_uniform;
    bool flush_before_timestamp_write;
    bool force_rt_wave64;
    bool dual_color_blend_by_location;
diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c
index 84f33eeea15..54d1800a9ef 100644
--- a/src/amd/vulkan/radv_shader.c
+++ b/src/amd/vulkan/radv_shader.c
@@ -461,6 +461,7 @@ radv_shader_spirv_to_nir(struct radv_device *device, const 
struct radv_shader_st
                .private_data = &spirv_debug_data,
             },
          .force_tex_non_uniform = key->tex_non_uniform,
+         .force_ssbo_non_uniform = key->ssbo_non_uniform,
       };
       nir = spirv_to_nir(spirv, stage->spirv.size / 4, spec_entries, 
num_spec_entries, stage->stage, stage->entrypoint,
                          &spirv_options, 
&device->physical_device->nir_options[stage->stage]);
diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h
index 445f8b8e0a5..c728412832b 100644
--- a/src/amd/vulkan/radv_shader.h
+++ b/src/amd/vulkan/radv_shader.h
@@ -95,6 +95,7 @@ struct radv_pipeline_key {
    uint32_t dynamic_provoking_vtx_mode : 1;
    uint32_t dynamic_line_rast_mode : 1;
    uint32_t tex_non_uniform : 1;
+   uint32_t ssbo_non_uniform : 1;
    uint32_t enable_remove_point_size : 1;
    uint32_t unknown_rast_prim : 1;
    uint32_t mesh_shader_queries : 1;
diff --git a/src/compiler/spirv/nir_spirv.h b/src/compiler/spirv/nir_spirv.h
index 1369a0e6b47..bfcccdc0fcc 100644
--- a/src/compiler/spirv/nir_spirv.h
+++ b/src/compiler/spirv/nir_spirv.h
@@ -116,6 +116,8 @@ struct spirv_to_nir_options {
 
    /* Force texture sampling to be non-uniform. */
    bool force_tex_non_uniform;
+   /* Force SSBO accesses to be non-uniform. */
+   bool force_ssbo_non_uniform;
 
    /* In Debug Builds, instead of emitting an OS break on failure, just return 
NULL from
     * spirv_to_nir().  This is useful for the unit tests that want to report a 
test failed
diff --git a/src/compiler/spirv/vtn_variables.c 
b/src/compiler/spirv/vtn_variables.c
index d00e3d785fd..651041ad4c0 100644
--- a/src/compiler/spirv/vtn_variables.c
+++ b/src/compiler/spirv/vtn_variables.c
@@ -2632,6 +2632,9 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
       /* Workaround for https://gitlab.freedesktop.org/mesa/mesa/-/issues/3406 
*/
       access |= base->access & ACCESS_NON_UNIFORM;
 
+      if (base->mode == vtn_variable_mode_ssbo && 
b->options->force_ssbo_non_uniform)
+         access |= ACCESS_NON_UNIFORM;
+
       struct vtn_pointer *ptr = vtn_pointer_dereference(b, base, chain);
       ptr->ptr_type = ptr_type;
       ptr->access |= access;
diff --git a/src/util/00-radv-defaults.conf b/src/util/00-radv-defaults.conf
index b13d92f84ce..0dcec733e52 100644
--- a/src/util/00-radv-defaults.conf
+++ b/src/util/00-radv-defaults.conf
@@ -148,6 +148,14 @@ Application bugs worked around in this file:
             <option name="radv_invariant_geom" value="true"/>
         </application>
 
+        <application name="Crysis 2 Remastered" 
executable="Crysis2Remastered.exe">
+            <option name="radv_ssbo_non_uniform" value="true" />
+        </application>
+
+        <application name="Crysis 3 Remastered" 
executable="Crysis3Remastered.exe">
+            <option name="radv_ssbo_non_uniform" value="true" />
+        </application>
+
         <!-- OpenGL Game workarounds (zink) -->
         <application name="Black Geyser: Couriers of Darkness" 
executable="BlackGeyser.x86_64">
             <option name="radv_zero_vram" value="true" />
diff --git a/src/util/driconf.h b/src/util/driconf.h
index e24c1eefd43..c79f969d517 100644
--- a/src/util/driconf.h
+++ b/src/util/driconf.h
@@ -674,6 +674,10 @@
    DRI_CONF_OPT_B(radv_tex_non_uniform, def, \
                   "Always mark texture sample operations as non-uniform.")
 
+#define DRI_CONF_RADV_SSBO_NON_UNIFORM(def) \
+   DRI_CONF_OPT_B(radv_ssbo_non_uniform, def, \
+                  "Always mark SSBO operations as non-uniform.")
+
 #define DRI_CONF_RADV_FLUSH_BEFORE_TIMESTAMP_WRITE(def) \
    DRI_CONF_OPT_B(radv_flush_before_timestamp_write, def, \
                   "Wait for previous commands to finish before writing 
timestamps")

Reply via email to