radv: optimize clipping performance with PA_SU_HARDWARE_SCREEN_OFFSET

This optimization was missing in RADV for a very long time.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6492
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40249>
This commit is contained in:
Samuel Pitoiset 2026-03-05 17:28:00 +01:00 committed by Marge Bot
parent c7cfa5324d
commit e293993fff
2 changed files with 17 additions and 4 deletions

View file

@ -4188,8 +4188,16 @@ radv_emit_scissor_state(struct radv_cmd_buffer *cmd_buffer)
radeon_emit(S_028250_TL_X(minx) | S_028250_TL_Y_GFX12(miny));
radeon_emit(S_028254_BR_X(maxx - 1) | S_028254_BR_Y(maxy - 1));
} else {
radeon_emit(S_028250_TL_X(minx) | S_028250_TL_Y_GFX6(miny) | S_028250_WINDOW_OFFSET_DISABLE(1));
radeon_emit(S_028254_BR_X(maxx) | S_028254_BR_Y(maxy));
/* Workaround for a hw bug on GFX6 that occurs when PA_SU_HARDWARE_SCREEN_OFFSET != 0 and
* any_scissor.BR_X/Y <= 0.
*/
if (pdev->info.gfx_level == GFX6 && (maxx == 0 || maxy == 0)) {
radeon_emit(S_028250_TL_X(1) | S_028250_TL_Y_GFX6(1) | S_028250_WINDOW_OFFSET_DISABLE(1));
radeon_emit(S_028254_BR_X(1) | S_028254_BR_Y(1));
} else {
radeon_emit(S_028250_TL_X(minx) | S_028250_TL_Y_GFX6(miny) | S_028250_WINDOW_OFFSET_DISABLE(1));
radeon_emit(S_028254_BR_X(maxx) | S_028254_BR_Y(maxy));
}
}
}
@ -5779,6 +5787,12 @@ radv_emit_guardband_state(struct radv_cmd_buffer *cmd_buffer)
ac_compute_guardband(&pdev->info, minx, miny, maxx, maxy, AC_QUANT_MODE_16_8_FIXED_POINT_1_256TH,
clip_discard_distance, &guardband);
int hw_screen_offset_x = guardband.hw_screen_offset_x >> 4;
int hw_screen_offset_y = guardband.hw_screen_offset_y >> 4;
uint32_t pa_su_hardware_screen_offset =
S_028234_HW_SCREEN_OFFSET_X(hw_screen_offset_x) | S_028234_HW_SCREEN_OFFSET_Y(hw_screen_offset_y);
radeon_begin(cs);
if (pdev->info.gfx_level >= GFX12) {
radeon_set_context_reg_seq(R_02842C_PA_CL_GB_VERT_CLIP_ADJ, 4);
@ -5789,6 +5803,7 @@ radv_emit_guardband_state(struct radv_cmd_buffer *cmd_buffer)
radeon_emit(fui(guardband.discard_y));
radeon_emit(fui(guardband.clip_x));
radeon_emit(fui(guardband.discard_x));
radeon_set_context_reg(R_028234_PA_SU_HARDWARE_SCREEN_OFFSET, pa_su_hardware_screen_offset);
radeon_end();
}

View file

@ -710,8 +710,6 @@ radv_emit_graphics(struct radv_device *device, struct radv_cmd_stream *cs)
if (!has_clear_state) {
ac_pm4_set_reg(pm4, R_028230_PA_SC_EDGERULE, 0xAAAAAAAA);
/* PA_SU_HARDWARE_SCREEN_OFFSET must be 0 due to hw bug on GFX6 */
ac_pm4_set_reg(pm4, R_028234_PA_SU_HARDWARE_SCREEN_OFFSET, 0);
}
if (pdev->info.gfx_level <= GFX8)