Module: Mesa Branch: main Commit: dcff89994c690be4dca0c610f3179f99f57ba0d3 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=dcff89994c690be4dca0c610f3179f99f57ba0d3
Author: Samuel Pitoiset <[email protected]> Date: Thu Aug 25 17:14:58 2022 +0200 radv: add support for emitting and prefetching PS epilogs Long jumps seem to be slow and prefetching might help. Signed-off-by: Samuel Pitoiset <[email protected]> Reviewed-by: Timur Kristóf <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18255> --- src/amd/vulkan/radv_cmd_buffer.c | 41 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 3819dffdcea..db1086978ba 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -1223,8 +1223,15 @@ radv_emit_prefetch_L2(struct radv_cmd_buffer *cmd_buffer, radv_emit_shader_prefetch(cmd_buffer, pipeline->base.gs_copy_shader); } - if (mask & RADV_PREFETCH_PS) + if (mask & RADV_PREFETCH_PS) { radv_emit_shader_prefetch(cmd_buffer, pipeline->base.shaders[MESA_SHADER_FRAGMENT]); + if (pipeline->ps_epilog) { + struct radv_shader_part *ps_epilog = pipeline->ps_epilog; + uint64_t va = radv_buffer_get_va(ps_epilog->bo) + ps_epilog->alloc->offset; + + si_cp_dma_prefetch(cmd_buffer, va, ps_epilog->code_size); + } + } state->prefetch_L2_mask &= ~mask; } @@ -1395,6 +1402,36 @@ radv_emit_rbplus_state(struct radv_cmd_buffer *cmd_buffer) cmd_buffer->state.last_sx_blend_opt_control = sx_blend_opt_control; } +static void +radv_emit_ps_epilog(struct radv_cmd_buffer *cmd_buffer) +{ + 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; + uint64_t ps_epilog_va; + + if (!ps_epilog) + return; + + /* The main shader must not use less VGPRs than the epilog, otherwise shared vgprs might not + * work. + */ + assert(G_00B848_VGPRS(ps_shader->config.rsrc1) >= G_00B848_VGPRS(ps_epilog->rsrc1)); + + radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, ps_epilog->bo); + + ps_epilog_va = radv_buffer_get_va(ps_epilog->bo) + ps_epilog->alloc->offset; + assert((ps_epilog_va >> 32) == cmd_buffer->device->physical_device->rad_info.address32_hi); + + struct radv_userdata_info *loc = + &ps_shader->info.user_sgprs_locs.shader_data[AC_UD_PS_EPILOG_PC]; + uint32_t base_reg = pipeline->base.user_data_0[MESA_SHADER_FRAGMENT]; + assert(loc->sgpr_idx != -1); + 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); +} + static void radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer) { @@ -1487,6 +1524,8 @@ 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); if (unlikely(cmd_buffer->device->trace_bo))
