anv: Add workaround for vertex explosions in Split Fiction
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

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 <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41716>
This commit is contained in:
Calder Young 2026-05-22 11:03:56 -07:00 committed by Marge Bot
parent abe41f3acf
commit bec5d3fff5
3 changed files with 14 additions and 0 deletions

View file

@ -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,

View file

@ -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);

View file

@ -1337,6 +1337,10 @@ TODO: document the other workarounds.
<engine engine_name_match="vkd3d">
<option name="anv_state_cache_perf_fix" value="true" />
</engine>
<application name="Split Fiction" executable="SplitFiction.exe">
<!-- Problematic shader: dxil:2b33f0608c02f754 (TODO: there could be others) -->
<option name="anv_fs_sampler_undef_derivatives_workaround" value="true" />
</application>
</device>
<device driver="dzn">
<application name="DOOMEternal" executable="DOOMEternalx64vk.exe">