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>
This commit is contained in:
committed by
Marge Bot
parent
4608eef0a0
commit
1e4cfd9dfa
@@ -2593,11 +2593,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);
|
||||
|
||||
@@ -2607,27 +2641,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
|
||||
@@ -2841,8 +2855,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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user