From c186420b26e6de96798925fd174cbef6f9907ac4 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Thu, 15 Dec 2022 11:54:01 +0100 Subject: [PATCH] radv: add support for VRS attachment on GFX11 Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_cmd_buffer.c | 24 ++++++++++++++++++++++++ src/amd/vulkan/radv_image.c | 2 +- src/amd/vulkan/radv_pipeline.c | 33 +++++++++++++++++++++++++++++---- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index acd1d39..72cda45 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -3425,6 +3425,30 @@ radv_emit_framebuffer_state(struct radv_cmd_buffer *cmd_buffer) radeon_emit(cmd_buffer->cs, S_028044_FORMAT(V_028044_STENCIL_INVALID)); /* DB_STENCIL_INFO */ } + if (cmd_buffer->device->physical_device->rad_info.gfx_level >= GFX11) { + bool vrs_surface_enable = render->vrs_att.iview != NULL; + unsigned xmax = 0, ymax = 0; + uint64_t va = 0; + + if (vrs_surface_enable) { + struct radv_image *vrs_image = render->vrs_att.iview->image; + + va = radv_buffer_get_va(vrs_image->bindings[0].bo) + vrs_image->bindings[0].offset; + va |= vrs_image->planes[0].surface.tile_swizzle << 8; + + xmax = vrs_image->info.width - 1; + ymax = vrs_image->info.height - 1; + } + + radeon_set_context_reg_seq(cmd_buffer->cs, R_0283F0_PA_SC_VRS_RATE_BASE, 3); + radeon_emit(cmd_buffer->cs, va >> 8); + radeon_emit(cmd_buffer->cs, S_0283F4_BASE_256B(va >> 40)); + radeon_emit(cmd_buffer->cs, S_0283F8_X_MAX(xmax) | S_0283F8_Y_MAX(ymax)); + + radeon_set_context_reg(cmd_buffer->cs, R_0283D0_PA_SC_VRS_OVERRIDE_CNTL, + S_0283D0_VRS_SURFACE_ENABLE(vrs_surface_enable)); + } + if (cmd_buffer->device->physical_device->rad_info.gfx_level >= GFX8) { bool disable_constant_encode = cmd_buffer->device->physical_device->rad_info.has_dcc_constant_encode; diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index d5594b6..014a337 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -655,7 +655,7 @@ radv_get_surface_flags(struct radv_device *device, struct radv_image *image, uns /* Disable DCC for VRS rate images because the hw can't handle compression. */ if (pCreateInfo->usage & VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR) - flags |= RADEON_SURF_DISABLE_DCC; + flags |= RADEON_SURF_VRS_RATE | RADEON_SURF_DISABLE_DCC; return flags; } diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index c231a84..9f72969 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -445,8 +445,25 @@ radv_pipeline_init_blend_state(struct radv_graphics_pipeline *pipeline, return blend; } +static bool +radv_pipeline_uses_vrs_attachment(const VkGraphicsPipelineCreateInfo *pCreateInfo, + const struct vk_graphics_pipeline_state *state) +{ + VK_FROM_HANDLE(vk_render_pass, render_pass, state->rp->render_pass); + + if (render_pass) { + uint32_t subpass_idx = state->rp->subpass; + struct vk_subpass *subpass = &render_pass->subpasses[subpass_idx]; + + return !!subpass->fragment_shading_rate_attachment; + } + + return (pCreateInfo->flags & VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR) != 0; +} + static void radv_pipeline_init_multisample_state(struct radv_graphics_pipeline *pipeline, + const VkGraphicsPipelineCreateInfo *pCreateInfo, const struct vk_graphics_pipeline_state *state, unsigned rast_prim) { @@ -489,9 +506,17 @@ radv_pipeline_init_multisample_state(struct radv_graphics_pipeline *pipeline, S_028A4C_OUT_OF_ORDER_PRIMITIVE_ENABLE(out_of_order_rast) | S_028A4C_OUT_OF_ORDER_WATER_MARK(0x7) | /* always 1: */ - S_028A4C_WALK_ALIGN8_PRIM_FITS_ST(1) | S_028A4C_SUPERTILE_WALK_ORDER_ENABLE(1) | - S_028A4C_TILE_WALK_ORDER_ENABLE(1) | S_028A4C_MULTI_SHADER_ENGINE_PRIM_DISCARD_ENABLE(1) | - S_028A4C_FORCE_EOV_CNTDWN_ENABLE(1) | S_028A4C_FORCE_EOV_REZ_ENABLE(1); + S_028A4C_SUPERTILE_WALK_ORDER_ENABLE(1) | S_028A4C_TILE_WALK_ORDER_ENABLE(1) | + S_028A4C_MULTI_SHADER_ENGINE_PRIM_DISCARD_ENABLE(1) | S_028A4C_FORCE_EOV_CNTDWN_ENABLE(1) | + S_028A4C_FORCE_EOV_REZ_ENABLE(1); + + if (pdevice->rad_info.gfx_level < GFX11 || + !radv_pipeline_uses_vrs_attachment(pCreateInfo, state)) { + /* This should only be set when VRS surfaces aren't enabled on GFX11, otherwise the GPU might + * hang. + */ + pipeline->pa_sc_mode_cntl_1 |= S_028A4C_WALK_ALIGN8_PRIM_FITS_ST(1); + } } static void @@ -5002,7 +5027,7 @@ radv_graphics_pipeline_init(struct radv_graphics_pipeline *pipeline, struct radv uint32_t vgt_gs_out_prim_type = radv_pipeline_init_vgt_gs_out(pipeline, &state); - radv_pipeline_init_multisample_state(pipeline, &state, vgt_gs_out_prim_type); + radv_pipeline_init_multisample_state(pipeline, pCreateInfo, &state, vgt_gs_out_prim_type); if (!radv_pipeline_has_stage(pipeline, MESA_SHADER_MESH)) radv_pipeline_init_input_assembly_state(pipeline); -- 2.7.4