mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
radv: emit a dummy PS state for noop FS on GFX12
It seems the hardware requires a dummy PS state with a noop FS,
otherwise it might just hang. This used to work just fine on older
gens.
Note that RadeonSI refuses to draw if VS or PS is missing and AMDVLK
seems to also always emit this state. So, this might be a bug that AMD
didn't encounter at all.
This fixes a GPU hang during loading with Ghostwire: Tokyo.
Backport-to: 25.0
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34070>
(cherry picked from commit 1e4cfd9dfa)
This commit is contained in:
parent
e576d84f03
commit
0c0f4de8ad
2 changed files with 46 additions and 26 deletions
|
|
@ -464,7 +464,7 @@
|
|||
"description": "radv: emit a dummy PS state for noop FS on GFX12",
|
||||
"nominated": true,
|
||||
"nomination_type": 4,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": null,
|
||||
"notes": null
|
||||
|
|
|
|||
|
|
@ -2595,11 +2595,45 @@ radv_emit_ps_inputs(struct radv_cmd_buffer *cmd_buffer)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
radv_emit_fragment_shader_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_shader *ps)
|
||||
{
|
||||
struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
|
||||
const struct radv_physical_device *pdev = radv_device_physical(device);
|
||||
const uint32_t spi_ps_input_ena = ps ? ps->config.spi_ps_input_ena : 0;
|
||||
const uint32_t spi_ps_input_addr = ps ? ps->config.spi_ps_input_addr : 0;
|
||||
const uint32_t spi_ps_in_control = ps ? ps->info.regs.ps.spi_ps_in_control : 0;
|
||||
|
||||
if (pdev->info.gfx_level >= GFX12) {
|
||||
const uint32_t pa_sc_hisz_control = ps ? ps->info.regs.ps.pa_sc_hisz_control : 0;
|
||||
|
||||
radeon_opt_set_context_reg2(cmd_buffer, R_02865C_SPI_PS_INPUT_ENA, RADV_TRACKED_SPI_PS_INPUT_ENA,
|
||||
spi_ps_input_ena, spi_ps_input_addr);
|
||||
|
||||
radeon_opt_set_context_reg(cmd_buffer, R_028640_SPI_PS_IN_CONTROL, RADV_TRACKED_SPI_PS_IN_CONTROL,
|
||||
spi_ps_in_control);
|
||||
|
||||
radeon_set_context_reg(cmd_buffer->cs, R_028BBC_PA_SC_HISZ_CONTROL, pa_sc_hisz_control);
|
||||
} else {
|
||||
const uint32_t pa_sc_shader_control = ps ? ps->info.regs.ps.pa_sc_shader_control : 0;
|
||||
|
||||
radeon_opt_set_context_reg2(cmd_buffer, R_0286CC_SPI_PS_INPUT_ENA, RADV_TRACKED_SPI_PS_INPUT_ENA,
|
||||
spi_ps_input_ena, spi_ps_input_addr);
|
||||
|
||||
if (pdev->info.gfx_level != GFX10_3) {
|
||||
radeon_opt_set_context_reg(cmd_buffer, R_0286D8_SPI_PS_IN_CONTROL, RADV_TRACKED_SPI_PS_IN_CONTROL,
|
||||
spi_ps_in_control);
|
||||
}
|
||||
|
||||
if (pdev->info.gfx_level >= GFX9 && pdev->info.gfx_level < GFX11)
|
||||
radeon_opt_set_context_reg(cmd_buffer, R_028C40_PA_SC_SHADER_CONTROL, RADV_TRACKED_PA_SC_SHADER_CONTROL,
|
||||
pa_sc_shader_control);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
radv_emit_fragment_shader(struct radv_cmd_buffer *cmd_buffer)
|
||||
{
|
||||
const struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
|
||||
const struct radv_physical_device *pdev = radv_device_physical(device);
|
||||
const struct radv_shader *ps = cmd_buffer->state.shaders[MESA_SHADER_FRAGMENT];
|
||||
const uint64_t va = radv_shader_get_va(ps);
|
||||
|
||||
|
|
@ -2609,27 +2643,7 @@ radv_emit_fragment_shader(struct radv_cmd_buffer *cmd_buffer)
|
|||
radeon_emit(cmd_buffer->cs, ps->config.rsrc1);
|
||||
radeon_emit(cmd_buffer->cs, ps->config.rsrc2);
|
||||
|
||||
if (pdev->info.gfx_level >= GFX12) {
|
||||
radeon_opt_set_context_reg2(cmd_buffer, R_02865C_SPI_PS_INPUT_ENA, RADV_TRACKED_SPI_PS_INPUT_ENA,
|
||||
ps->config.spi_ps_input_ena, ps->config.spi_ps_input_addr);
|
||||
|
||||
radeon_opt_set_context_reg(cmd_buffer, R_028640_SPI_PS_IN_CONTROL, RADV_TRACKED_SPI_PS_IN_CONTROL,
|
||||
ps->info.regs.ps.spi_ps_in_control);
|
||||
|
||||
radeon_set_context_reg(cmd_buffer->cs, R_028BBC_PA_SC_HISZ_CONTROL, ps->info.regs.ps.pa_sc_hisz_control);
|
||||
} else {
|
||||
radeon_opt_set_context_reg2(cmd_buffer, R_0286CC_SPI_PS_INPUT_ENA, RADV_TRACKED_SPI_PS_INPUT_ENA,
|
||||
ps->config.spi_ps_input_ena, ps->config.spi_ps_input_addr);
|
||||
|
||||
if (pdev->info.gfx_level != GFX10_3) {
|
||||
radeon_opt_set_context_reg(cmd_buffer, R_0286D8_SPI_PS_IN_CONTROL, RADV_TRACKED_SPI_PS_IN_CONTROL,
|
||||
ps->info.regs.ps.spi_ps_in_control);
|
||||
}
|
||||
|
||||
if (pdev->info.gfx_level >= GFX9 && pdev->info.gfx_level < GFX11)
|
||||
radeon_opt_set_context_reg(cmd_buffer, R_028C40_PA_SC_SHADER_CONTROL, RADV_TRACKED_PA_SC_SHADER_CONTROL,
|
||||
ps->info.regs.ps.pa_sc_shader_control);
|
||||
}
|
||||
radv_emit_fragment_shader_state(cmd_buffer, ps);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2843,8 +2857,14 @@ radv_emit_graphics_shaders(struct radv_cmd_buffer *cmd_buffer)
|
|||
if (pdev->info.gfx_level >= GFX12) {
|
||||
const struct radv_shader *ps = cmd_buffer->state.shaders[MESA_SHADER_FRAGMENT];
|
||||
const struct radv_shader *last_vgt_shader = cmd_buffer->state.last_vgt_shader;
|
||||
const uint32_t gs_out_config_ps =
|
||||
last_vgt_shader->info.regs.spi_vs_out_config | (ps ? ps->info.regs.ps.spi_gs_out_config_ps : 0);
|
||||
uint32_t gs_out_config_ps = last_vgt_shader->info.regs.spi_vs_out_config;
|
||||
|
||||
if (ps) {
|
||||
gs_out_config_ps |= ps->info.regs.ps.spi_gs_out_config_ps;
|
||||
} else {
|
||||
/* GFX12 seems to require a dummy FS state otherwise it might just hang. */
|
||||
radv_emit_fragment_shader_state(cmd_buffer, NULL);
|
||||
}
|
||||
|
||||
radeon_set_sh_reg(cmd_buffer->cs, R_00B0C4_SPI_SHADER_GS_OUT_CONFIG_PS, gs_out_config_ps);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue