radv: allow to select a different HiZ workaround on GFX12

And describe all of them better.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36839>
This commit is contained in:
Samuel Pitoiset 2025-08-19 09:51:22 +02:00 committed by Marge Bot
parent 4ce8d471b5
commit e4ef804013
6 changed files with 34 additions and 22 deletions

View file

@ -5575,7 +5575,7 @@ radv_gfx12_override_hiz_enable(struct radv_cmd_buffer *cmd_buffer, bool enable)
}
static void
radv_gfx12_emit_alt_hiz_wa(struct radv_cmd_buffer *cmd_buffer)
radv_gfx12_emit_hiz_wa_full(struct radv_cmd_buffer *cmd_buffer)
{
const struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
const struct radv_rendering_state *render = &cmd_buffer->state.render;
@ -9443,7 +9443,7 @@ radv_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCou
*/
radv_emit_framebuffer_state(primary);
if (pdev->info.gfx_level == GFX12 && !pdev->use_gfx12_hiz_his_event_wa) {
if (pdev->gfx12_hiz_wa == RADV_GFX12_HIZ_WA_FULL) {
const struct radv_rendering_state *render = &primary->state.render;
const struct radv_image_view *iview = render->ds_att.iview;
@ -10021,11 +10021,7 @@ radv_gfx12_emit_hiz_his_wa(const struct radv_device *device, const struct radv_c
const struct radv_physical_device *pdev = radv_device_physical(device);
const struct radv_rendering_state *render = &cmd_state->render;
/* On GFX12, HiZ/HiS is buggy and can cause random GPU hangs. There are basically two alternatives:
* - disable HiZ/HiS completely which is the safest workaround but this is known to decrease performance
* - emit a dummy BOTTOM_OF_PIPE_TS after every draw which should workaround the hang and maintain performance
*/
if (pdev->use_gfx12_hiz_his_event_wa && render->has_hiz_his) {
if (pdev->gfx12_hiz_wa == RADV_GFX12_HIZ_WA_PARTIAL && render->has_hiz_his) {
radeon_begin(cs);
radeon_emit(PKT3(PKT3_RELEASE_MEM, 6, 0));
radeon_emit(S_490_EVENT_TYPE(V_028A90_BOTTOM_OF_PIPE_TS) | S_490_EVENT_INDEX(5));
@ -12031,8 +12027,8 @@ radv_emit_all_graphics_states(struct radv_cmd_buffer *cmd_buffer, const struct r
const bool late_scissor_emission =
pdev->info.has_gfx9_scissor_bug ? radv_need_late_scissor_emission(cmd_buffer, info) : false;
const bool gfx12_emit_alt_hiz_wa =
pdev->info.gfx_level == GFX12 && !pdev->use_gfx12_hiz_his_event_wa &&
const bool gfx12_emit_hiz_wa_full =
pdev->gfx12_hiz_wa == RADV_GFX12_HIZ_WA_FULL &&
cmd_buffer->state.dirty & (RADV_CMD_DIRTY_FRAMEBUFFER | RADV_CMD_DIRTY_DEPTH_STENCIL_STATE);
if (cmd_buffer->state.dirty & RADV_CMD_DIRTY_RBPLUS) {
@ -12176,8 +12172,8 @@ radv_emit_all_graphics_states(struct radv_cmd_buffer *cmd_buffer, const struct r
cmd_buffer->state.dirty &= ~RADV_CMD_DIRTY_RAST_SAMPLES_STATE;
}
if (gfx12_emit_alt_hiz_wa)
radv_gfx12_emit_alt_hiz_wa(cmd_buffer);
if (gfx12_emit_hiz_wa_full)
radv_gfx12_emit_hiz_wa_full(cmd_buffer);
radv_emit_shaders_state(cmd_buffer);

View file

@ -390,7 +390,7 @@ radv_get_sequence_size_graphics(const struct radv_indirect_command_layout *layou
}
}
if (pdev->use_gfx12_hiz_his_event_wa) {
if (pdev->gfx12_hiz_wa == RADV_GFX12_HIZ_WA_PARTIAL) {
/* HiZ/HiS hw workaround */
*cmd_size += 8 * 4;
}
@ -1274,7 +1274,7 @@ dgc_gfx12_emit_hiz_his_wa(struct dgc_cmdbuf *cs)
const struct radv_device *device = cs->dev;
const struct radv_physical_device *pdev = radv_device_physical(device);
if (pdev->use_gfx12_hiz_his_event_wa) {
if (pdev->gfx12_hiz_wa == RADV_GFX12_HIZ_WA_PARTIAL) {
dgc_cs_begin(cs);
dgc_cs_emit_imm(PKT3(PKT3_RELEASE_MEM, 6, 0));
dgc_cs_emit_imm(S_490_EVENT_TYPE(V_028A90_BOTTOM_OF_PIPE_TS) | S_490_EVENT_INDEX(5));

View file

@ -900,7 +900,7 @@ radv_image_alloc_values(const struct radv_device *device, struct radv_image *ima
assert(!surf->u.gfx9.zs.his.offset);
/* Allocate HiZ metadata when the image has depth/stencil aspects to implement a workaround. */
if (!pdev->use_gfx12_hiz_his_event_wa && surf->u.gfx9.zs.hiz.offset &&
if (pdev->gfx12_hiz_wa == RADV_GFX12_HIZ_WA_FULL && surf->u.gfx9.zs.hiz.offset &&
(image->vk.aspects == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
image->hiz_valid_offset = image->size;
image->size += image->vk.mip_levels * 4;

View file

@ -2308,8 +2308,8 @@ radv_physical_device_try_create(struct radv_instance *instance, drmDevicePtr drm
if (pdev->info.gfx_level == GFX12 && instance->drirc.disable_hiz_his_gfx12)
pdev->use_hiz = false;
pdev->use_gfx12_hiz_his_event_wa =
pdev->info.gfx_level == GFX12 && pdev->use_hiz; /* TODO: Implement the alternative solution. */
if (pdev->info.gfx_level == GFX12)
pdev->gfx12_hiz_wa = RADV_GFX12_HIZ_WA_PARTIAL;
pdev->use_ngg = (pdev->info.gfx_level >= GFX10 && pdev->info.family != CHIP_NAVI14 &&
!(instance->debug_flags & RADV_DEBUG_NO_NGG)) ||

View file

@ -76,6 +76,25 @@ enum radv_video_enc_hw_ver {
RADV_VIDEO_ENC_HW_5,
};
/**
* Description of the various HiZ workarounds for GFX12.
*
* - disabled: None of the HiZ/HiS workarounds are enabled. This is very risky and should only be
* used when we guarantee no issues. Performance is optimal.
*
* - partial: Emit BOTTOM_OF_PIPE_TS events after every draw to mitigate the issue. This is
* potentially risky because it doesn't mitigate the issue complety but it helps in most cases.
* Performance should be mostly optimal.
*
* - full: Disable HiZ/HiS at draw time when required to prevent the issue to happen. This solution
* should be completely safe but it might decrease performance in some cases.
*/
enum radv_gfx12_hiz_wa {
RADV_GFX12_HIZ_WA_DISABLED,
RADV_GFX12_HIZ_WA_PARTIAL,
RADV_GFX12_HIZ_WA_FULL,
};
struct radv_physical_device {
struct vk_physical_device vk;
@ -104,11 +123,8 @@ struct radv_physical_device {
/* Whether to enable HTILE compression for depth/stencil images. */
bool use_hiz;
/* Whether the driver uses BOTTOM_OF_PIPE_TS events to workaround random GPU hangs with HiZ/HiS
* on GFX12. Note that this workaround doesn't mitigate the issue reliably but it helps in most
* scenarios.
*/
bool use_gfx12_hiz_his_event_wa;
/* GFX12 HiZ workaround behavior. */
enum radv_gfx12_hiz_wa gfx12_hiz_wa;
/* Whether to enable NGG. */
bool use_ngg;

View file

@ -706,7 +706,7 @@ radv_emit_ge_rings(struct radv_device *device, struct radv_cmd_stream *cs, struc
/* Mitigate the HiZ GPU hang by increasing a timeout when BOTTOM_OF_PIPE_TS is used as the
* workaround. This must be emitted when the gfx queue is idle.
*/
const uint32_t timeout = pdev->use_gfx12_hiz_his_event_wa ? 0xfff : 0;
const uint32_t timeout = pdev->gfx12_hiz_wa == RADV_GFX12_HIZ_WA_PARTIAL ? 0xfff : 0;
radeon_emit(PKT3(PKT3_UPDATE_DB_SUMMARIZER_TIMEOUT, 0, 0));
radeon_emit(S_EF1_SUMM_CNTL_EVICT_TIMEOUT(timeout));