radv: allow to disable sinking of load inputs for FS via drirc

To workaround game bugs where partial derivatives are used in
non-uniform control flow. A proper solution needs to be implemented,
but as a quick fix disabling nir_opt_sink() works.

Cc: mesa-stable
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16165>
This commit is contained in:
Samuel Pitoiset
2022-04-26 14:20:56 +02:00
parent 6261ca7425
commit 1dbfd2be4b
5 changed files with 22 additions and 2 deletions

View File

@@ -3151,6 +3151,9 @@ radv_generate_graphics_pipeline_key(const struct radv_pipeline *pipeline,
device->physical_device->rad_info.family == CHIP_VANGOGH))
key.adjust_frag_coord_z = true;
if (device->instance->disable_sinking_load_input_fs)
key.disable_sinking_load_input_fs = true;
return key;
}
@@ -4470,7 +4473,11 @@ radv_create_shaders(struct radv_pipeline *pipeline, struct radv_pipeline_layout
.allow_fp16 = device->physical_device->rad_info.chip_class >= GFX9,
});
nir_opt_sink(stages[i].nir, nir_move_load_input | nir_move_const_undef | nir_move_copies);
nir_move_options sink_opts = nir_move_const_undef | nir_move_copies;
if (i != MESA_SHADER_FRAGMENT || !pipeline_key->disable_sinking_load_input_fs)
sink_opts |= nir_move_load_input;
nir_opt_sink(stages[i].nir, sink_opts);
nir_opt_move(stages[i].nir, nir_move_load_input | nir_move_const_undef | nir_move_copies);
/* Lower I/O intrinsics to memory instructions. */
@@ -4513,9 +4520,12 @@ radv_create_shaders(struct radv_pipeline *pipeline, struct radv_pipeline_layout
/* cleanup passes */
nir_lower_load_const_to_scalar(stages[i].nir);
sink_opts |= nir_move_comparisons | nir_move_load_ubo | nir_move_load_ssbo;
nir_opt_sink(stages[i].nir, sink_opts);
nir_move_options move_opts = nir_move_const_undef | nir_move_load_ubo |
nir_move_load_input | nir_move_comparisons | nir_move_copies;
nir_opt_sink(stages[i].nir, move_opts | nir_move_load_ssbo);
nir_opt_move(stages[i].nir, move_opts);
stages[i].feedback.duration += os_time_get_nano() - stage_start;