From bbd7f700739f2ae6106e71505cd5ec40096fbb61 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Tue, 6 Dec 2022 15:21:56 +0100 Subject: [PATCH] radv: rework PS epilog emission With PS epilogs compiled on-demand (for some dynamic states), they need to be emitted outside of the graphics pipeline path. Also keep track of the last emitted PS epilog to avoid redundant emission. Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_cmd_buffer.c | 19 ++++++++++++++----- src/amd/vulkan/radv_pipeline.c | 3 +++ src/amd/vulkan/radv_private.h | 2 ++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 6c0a6c8a7ce..cd751c3b43f 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -1885,15 +1885,20 @@ radv_emit_rbplus_state(struct radv_cmd_buffer *cmd_buffer) } static void -radv_emit_ps_epilog(struct radv_cmd_buffer *cmd_buffer) +radv_emit_ps_epilog_state(struct radv_cmd_buffer *cmd_buffer, struct radv_shader_part *ps_epilog, + bool pipeline_is_dirty) { struct radv_graphics_pipeline *pipeline = cmd_buffer->state.graphics_pipeline; struct radv_shader *ps_shader = pipeline->base.shaders[MESA_SHADER_FRAGMENT]; - struct radv_shader_part *ps_epilog = pipeline->ps_epilog; - if (!ps_epilog) + if (cmd_buffer->state.emitted_ps_epilog == ps_epilog && !pipeline_is_dirty) return; + radeon_set_context_reg(cmd_buffer->cs, R_028714_SPI_SHADER_COL_FORMAT, + ps_epilog->spi_shader_col_format); + radeon_set_context_reg(cmd_buffer->cs, R_02823C_CB_SHADER_MASK, + ac_get_cb_shader_mask(ps_epilog->spi_shader_col_format)); + /* The main shader must not use less VGPRs than the epilog, otherwise shared vgprs might not * work. */ @@ -1910,6 +1915,8 @@ radv_emit_ps_epilog(struct radv_cmd_buffer *cmd_buffer) assert(loc->num_sgprs == 1); radv_emit_shader_pointer(cmd_buffer->device, cmd_buffer->cs, base_reg + loc->sgpr_idx * 4, ps_epilog->va, false); + + cmd_buffer->state.emitted_ps_epilog = ps_epilog; } static void @@ -1981,8 +1988,6 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer) } } - radv_emit_ps_epilog(cmd_buffer); - radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, pipeline->base.slab_bo); /* With graphics pipeline library, binaries are uploaded from a library and they hold a pointer @@ -8452,6 +8457,10 @@ radv_emit_all_graphics_states(struct radv_cmd_buffer *cmd_buffer, const struct r const struct radv_device *device = cmd_buffer->device; bool late_scissor_emission; + if (cmd_buffer->state.graphics_pipeline->ps_epilog) + radv_emit_ps_epilog_state(cmd_buffer, cmd_buffer->state.graphics_pipeline->ps_epilog, + pipeline_is_dirty); + if (cmd_buffer->state.dirty & RADV_CMD_DIRTY_RBPLUS) radv_emit_rbplus_state(cmd_buffer); diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 3b158447939..8fc97e279ec 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -3920,6 +3920,9 @@ radv_pipeline_emit_blend_state(struct radeon_cmdbuf *ctx_cs, const struct radv_graphics_pipeline *pipeline, const struct radv_blend_state *blend) { + if (pipeline->ps_epilog) + return; + radeon_set_context_reg(ctx_cs, R_028714_SPI_SHADER_COL_FORMAT, blend->spi_shader_col_format); radeon_set_context_reg(ctx_cs, R_02823C_CB_SHADER_MASK, blend->cb_shader_mask); diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 9f5181c870e..4d1aaebee64 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1543,6 +1543,8 @@ struct radv_cmd_state { uint32_t vbo_misaligned_mask_invalid; uint32_t vbo_bound_mask; + struct radv_shader_part *emitted_ps_epilog; + /* Per-vertex VRS state. */ uint32_t last_vrs_rates; int8_t last_vrs_rates_sgpr_idx;