From bec5d3fff51702fdf76cc397fec2b1a89a37a698 Mon Sep 17 00:00:00 2001 From: Calder Young Date: Fri, 22 May 2026 11:03:56 -0700 Subject: [PATCH] anv: Add workaround for vertex explosions in Split Fiction The game tries to use anisotropic filtering deep in some control flow while updating a procedural displacement map, our sampling hardware does not check the channel enable mask before calculating the derivatives for each subspan, which causes it to get garbage for any subspans that have partially disabled lanes. This workaround converts any sample messages in fragment shaders that have divergent control flow into a sample_d message with the derivatives zero'd by software if some of the lanes are disabled. Closes: #12796 Reviewed-by: Lionel Landwerlin Part-of: --- src/intel/vulkan/anv_dricrc_gen.py | 3 +++ src/intel/vulkan/anv_shader_compile.c | 7 +++++++ src/util/00-mesa-defaults.conf | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/src/intel/vulkan/anv_dricrc_gen.py b/src/intel/vulkan/anv_dricrc_gen.py index d0bad545688..e0664e549e1 100644 --- a/src/intel/vulkan/anv_dricrc_gen.py +++ b/src/intel/vulkan/anv_dricrc_gen.py @@ -84,6 +84,9 @@ def declare_options(android_version): I("shader_spilling_rate", 11, 0, 100, "Speed up shader compilation by increasing number of spilled registers after ra_allocate failure", c_name="shader_spilling_rate"), + B("anv_fs_sampler_undef_derivatives_workaround", False, + "Fixes samplers in fragment shaders computing undefined values for derivatives with lanes disabled by control flow", + c_name="fs_sampler_undef_derivatives_workaround"), # Workaround various driver B("always_flush_cache", False, diff --git a/src/intel/vulkan/anv_shader_compile.c b/src/intel/vulkan/anv_shader_compile.c index de316ca2bc5..a2b3a39d1b5 100644 --- a/src/intel/vulkan/anv_shader_compile.c +++ b/src/intel/vulkan/anv_shader_compile.c @@ -276,6 +276,9 @@ anv_shader_init_uuid(struct anv_physical_device *device) const bool cbv_push_buffer = device->instance->drirc.perf.promote_cbv_push_buffer; _mesa_blake3_update(&ctx, &cbv_push_buffer, sizeof(cbv_push_buffer)); + const bool fs_sample_d_wa = device->instance->drirc.debug.fs_sampler_undef_derivatives_workaround; + _mesa_blake3_update(&ctx, &fs_sample_d_wa, sizeof(fs_sample_d_wa)); + uint8_t blake3[BLAKE3_KEY_LEN]; _mesa_blake3_final(&ctx, blake3); memcpy(device->shader_binary_uuid, blake3, sizeof(device->shader_binary_uuid)); @@ -1510,6 +1513,10 @@ anv_shader_lower_nir(struct anv_device *device, NIR_PASS(_, nir, nir_opt_dce); } + if (nir->info.stage == MESA_SHADER_FRAGMENT && + pdevice->instance->drirc.debug.fs_sampler_undef_derivatives_workaround) + NIR_PASS(_, nir, brw_nir_apply_sampler_undef_derivatives_workaround); + if (mesa_shader_stage_uses_workgroup(nir->info.stage)) { NIR_PASS(_, nir, nir_lower_vars_to_explicit_types, nir_var_mem_shared, shared_type_info); diff --git a/src/util/00-mesa-defaults.conf b/src/util/00-mesa-defaults.conf index b0c57f2cb08..9d98dcdbc48 100644 --- a/src/util/00-mesa-defaults.conf +++ b/src/util/00-mesa-defaults.conf @@ -1337,6 +1337,10 @@ TODO: document the other workarounds. + + +