radv: add a new dirty bit for compiling/binding a PS epilog

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37087>
This commit is contained in:
Samuel Pitoiset 2025-08-29 16:37:00 +02:00 committed by Marge Bot
parent 11e5f86a94
commit 211e0823ec
2 changed files with 31 additions and 22 deletions

View file

@ -8317,6 +8317,9 @@ radv_bind_fragment_shader(struct radv_cmd_buffer *cmd_buffer, const struct radv_
cmd_buffer->sample_positions_needed = true;
}
if (ps->info.ps.has_epilog)
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_PS_EPILOG_SHADER;
if (radv_get_user_sgpr_info(ps, AC_UD_PS_STATE)->sgpr_idx != -1)
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_FS_STATE;
@ -8378,12 +8381,22 @@ radv_bind_rt_prolog(struct radv_cmd_buffer *cmd_buffer, struct radv_shader *rt_p
radv_cs_add_buffer(device->ws, cs->b, rt_prolog->bo);
}
static void
radv_bind_ps_epilog(struct radv_cmd_buffer *cmd_buffer, struct radv_shader_part *ps_epilog)
static struct radv_shader_part *
radv_bind_ps_epilog(struct radv_cmd_buffer *cmd_buffer)
{
const struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
const struct radv_shader *ps = cmd_buffer->state.shaders[MESA_SHADER_FRAGMENT];
struct radv_cmd_stream *cs = cmd_buffer->cs;
struct radv_shader_part *ps_epilog;
if (!ps || !ps->info.ps.has_epilog)
return NULL;
ps_epilog = lookup_ps_epilog(cmd_buffer);
if (!ps_epilog) {
vk_command_buffer_set_error(&cmd_buffer->vk, VK_ERROR_OUT_OF_HOST_MEMORY);
return NULL;
}
assert(cmd_buffer->state.custom_blend_mode == 0);
radv_bind_fragment_output_state(cmd_buffer, ps, ps_epilog, 0);
@ -8393,6 +8406,8 @@ radv_bind_ps_epilog(struct radv_cmd_buffer *cmd_buffer, struct radv_shader_part
cmd_buffer->shader_upload_seq = MAX2(cmd_buffer->shader_upload_seq, ps_epilog->upload_seq);
radv_cs_add_buffer(device->ws, cs->b, ps_epilog->bo);
return ps_epilog;
}
/* This function binds/unbinds a shader to the cmdbuffer state. */
@ -9835,7 +9850,8 @@ radv_CmdBeginRendering(VkCommandBuffer commandBuffer, const VkRenderingInfo *pRe
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_FRAMEBUFFER | RADV_CMD_DIRTY_BINNING_STATE |
RADV_CMD_DIRTY_FBFETCH_OUTPUT | RADV_CMD_DIRTY_DEPTH_BIAS_STATE |
RADV_CMD_DIRTY_DEPTH_STENCIL_STATE | RADV_CMD_DIRTY_CB_RENDER_STATE |
RADV_CMD_DIRTY_MSAA_STATE | RADV_CMD_DIRTY_RAST_SAMPLES_STATE | RADV_CMD_DIRTY_FS_STATE;
RADV_CMD_DIRTY_MSAA_STATE | RADV_CMD_DIRTY_RAST_SAMPLES_STATE | RADV_CMD_DIRTY_FS_STATE |
RADV_CMD_DIRTY_PS_EPILOG_SHADER;
if (pdev->info.rbplus_allowed)
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_RBPLUS;
@ -12009,6 +12025,11 @@ radv_validate_dynamic_states(struct radv_cmd_buffer *cmd_buffer, uint64_t dynami
if ((dynamic_states & RADV_DYNAMIC_PRIMITIVE_TOPOLOGY) ||
(pdev->info.gfx_level >= GFX12 && dynamic_states & RADV_DYNAMIC_PATCH_CONTROL_POINTS))
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_VGT_PRIM_STATE;
if (dynamic_states &
(RADV_DYNAMIC_COLOR_WRITE_MASK | RADV_DYNAMIC_COLOR_BLEND_ENABLE | RADV_DYNAMIC_ALPHA_TO_COVERAGE_ENABLE |
RADV_DYNAMIC_COLOR_BLEND_EQUATION | RADV_DYNAMIC_ALPHA_TO_ONE_ENABLE | RADV_DYNAMIC_COLOR_ATTACHMENT_MAP))
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_PS_EPILOG_SHADER;
}
static void
@ -12018,24 +12039,6 @@ radv_emit_all_graphics_states(struct radv_cmd_buffer *cmd_buffer, const struct r
const struct radv_physical_device *pdev = radv_device_physical(device);
struct radv_shader_part *ps_epilog = NULL;
if (cmd_buffer->state.shaders[MESA_SHADER_FRAGMENT] &&
cmd_buffer->state.shaders[MESA_SHADER_FRAGMENT]->info.ps.has_epilog) {
if ((cmd_buffer->state.emitted_graphics_pipeline != cmd_buffer->state.graphics_pipeline ||
((cmd_buffer->state.dirty & (RADV_CMD_DIRTY_GRAPHICS_SHADERS | RADV_CMD_DIRTY_FRAMEBUFFER)) ||
(cmd_buffer->state.dirty_dynamic &
(RADV_DYNAMIC_COLOR_WRITE_MASK | RADV_DYNAMIC_COLOR_BLEND_ENABLE | RADV_DYNAMIC_ALPHA_TO_COVERAGE_ENABLE |
RADV_DYNAMIC_COLOR_BLEND_EQUATION | RADV_DYNAMIC_ALPHA_TO_ONE_ENABLE |
RADV_DYNAMIC_COLOR_ATTACHMENT_MAP))))) {
ps_epilog = lookup_ps_epilog(cmd_buffer);
if (!ps_epilog) {
vk_command_buffer_set_error(&cmd_buffer->vk, VK_ERROR_OUT_OF_HOST_MEMORY);
return;
}
radv_bind_ps_epilog(cmd_buffer, ps_epilog);
}
}
const uint64_t dynamic_states = cmd_buffer->state.dirty_dynamic & radv_get_needed_dynamic_states(cmd_buffer);
if (((cmd_buffer->state.dirty & (RADV_CMD_DIRTY_PIPELINE | RADV_CMD_DIRTY_GRAPHICS_SHADERS)) ||
(dynamic_states & RADV_DYNAMIC_PATCH_CONTROL_POINTS))) {
@ -12065,6 +12068,11 @@ radv_emit_all_graphics_states(struct radv_cmd_buffer *cmd_buffer, const struct r
if (dynamic_states)
radv_validate_dynamic_states(cmd_buffer, dynamic_states);
if (cmd_buffer->state.dirty & RADV_CMD_DIRTY_PS_EPILOG_SHADER) {
ps_epilog = radv_bind_ps_epilog(cmd_buffer);
cmd_buffer->state.dirty &= ~RADV_CMD_DIRTY_PS_EPILOG_SHADER;
}
/* Determine whether GFX9 late scissor workaround should be applied based on:
* 1. radv_need_late_scissor_emission
* 2. any dirty dynamic flags that may cause context rolls

View file

@ -120,7 +120,8 @@ enum radv_cmd_dirty_bits {
RADV_CMD_DIRTY_FORCE_VRS_STATE = 1ull << 34,
RADV_CMD_DIRTY_NGGC_VIEWPORT = 1ull << 35,
RADV_CMD_DIRTY_NGGC_SETTINGS = 1ull << 36,
RADV_CMD_DIRTY_ALL = (1ull << 37) - 1,
RADV_CMD_DIRTY_PS_EPILOG_SHADER = 1ull << 37,
RADV_CMD_DIRTY_ALL = (1ull << 38) - 1,
RADV_CMD_DIRTY_SHADER_QUERY = RADV_CMD_DIRTY_NGG_STATE | RADV_CMD_DIRTY_TASK_STATE,
};