From 9af11bf306c4b67c434044a7ba2907a5c6df5542 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 29 Jan 2025 09:17:05 -0800 Subject: [PATCH] radv: add initial DCC support on GFX12 Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_device_memory.c | 34 +++++++++++++++++++++++++++++ src/amd/vulkan/radv_image.c | 10 +++++++++ src/amd/vulkan/radv_image_view.c | 8 +++---- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/amd/vulkan/radv_device_memory.c b/src/amd/vulkan/radv_device_memory.c index 44b71f0cfc9..8016fbbae54 100644 --- a/src/amd/vulkan/radv_device_memory.c +++ b/src/amd/vulkan/radv_device_memory.c @@ -11,6 +11,7 @@ #include "radv_device_memory.h" #include "radv_android.h" #include "radv_buffer.h" +#include "radv_debug.h" #include "radv_entrypoints.h" #include "radv_image.h" #include "radv_rmv.h" @@ -201,6 +202,17 @@ radv_alloc_memory(struct radv_device *device, const VkMemoryAllocateInfo *pAlloc if (instance->drirc.zero_vram) flags |= RADEON_FLAG_ZERO_VRAM; + /* On GFX12, DCC is transparent to the userspace driver and PTE.DCC is + * set per buffer allocation. Only VRAM can have DCC. When the kernel + * moves a buffer from VRAM->GTT it decompresses. When the kernel moves + * it from GTT->VRAM it recompresses but only if WRITE_COMPRESS_DISABLE=0 + * (see DCC tiling flags). + */ + if (pdev->info.gfx_level >= GFX12 && pdev->info.gfx12_supports_dcc_write_compress_disable && + domain == RADEON_DOMAIN_VRAM && !(instance->debug_flags & RADV_DEBUG_NO_DCC)) { + flags |= RADEON_FLAG_GFX12_ALLOW_DCC; + } + if (device->overallocation_disallowed) { uint64_t total_size = pdev->memory_properties.memoryHeaps[heap_index].size; @@ -226,6 +238,28 @@ radv_alloc_memory(struct radv_device *device, const VkMemoryAllocateInfo *pAlloc goto fail; } + if (flags & RADEON_FLAG_GFX12_ALLOW_DCC) { + if (mem->image) { + /* Set BO metadata (including DCC tiling flags) for dedicated + * allocations because compressed writes are enabled and the kernel + * requires a DCC view for recompression. + */ + radv_image_bo_set_metadata(device, mem->image, mem->bo); + } else { + /* Otherwise, disable compressed writes to prevent recompression + * when the BO is moved back to VRAM because it's not yet possible + * to set DCC tiling flags per range for suballocations. The only + * problem is that we will loose DCC after migration but that + * should happen rarely. + */ + struct radeon_bo_metadata md = {0}; + + md.u.gfx12.dcc_write_compress_disable = true; + + device->ws->buffer_set_metadata(device->ws, mem->bo, &md); + } + } + mem->heap_index = heap_index; mem->alloc_size = alloc_size; } diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index b941ea77b35..5ffc50ce3de 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -1206,6 +1206,16 @@ radv_image_create_layout(struct radv_device *device, struct radv_image_create_in ac_surface_zero_dcc_fields(&image->planes[0].surface); } + if (pdev->info.gfx_level >= GFX12 && + (!radv_surface_has_scanout(device, &create_info) || pdev->info.gfx12_supports_display_dcc)) { + const enum pipe_format format = vk_format_to_pipe_format(image->vk.format); + + /* Set DCC tilings for both color and depth/stencil. */ + image->planes[plane].surface.u.gfx9.color.dcc_number_type = ac_get_cb_number_type(format); + image->planes[plane].surface.u.gfx9.color.dcc_data_format = ac_get_cb_format(pdev->info.gfx_level, format); + image->planes[plane].surface.u.gfx9.color.dcc_write_compress_disable = false; + } + if (create_info.bo_metadata && !mod_info && !ac_surface_apply_umd_metadata(&pdev->info, &image->planes[plane].surface, image->vk.samples, image->vk.mip_levels, create_info.bo_metadata->size_metadata, diff --git a/src/amd/vulkan/radv_image_view.c b/src/amd/vulkan/radv_image_view.c index 5b1b4349ab0..3483f935acc 100644 --- a/src/amd/vulkan/radv_image_view.c +++ b/src/amd/vulkan/radv_image_view.c @@ -55,19 +55,19 @@ radv_set_mutable_tex_desc_fields(struct radv_device *device, struct radv_image * bool is_storage_image, bool disable_compression, bool enable_write_compression, uint32_t *state, const struct ac_surf_nbc_view *nbc_view, uint64_t offset) { + const struct radv_physical_device *pdev = radv_device_physical(device); struct radv_image_plane *plane = &image->planes[plane_id]; const uint32_t bind_idx = image->disjoint ? plane_id : 0; struct radv_image_binding *binding = &image->bindings[bind_idx]; uint64_t gpu_address = binding->bo ? radv_image_get_va(image, bind_idx) + offset : 0; - const struct radv_physical_device *pdev = radv_device_physical(device); + const bool dcc_enabled = pdev->info.gfx_level >= GFX12 || radv_dcc_enabled(image, first_level); const struct ac_mutable_tex_state ac_state = { .surf = &plane->surface, .va = gpu_address, .gfx10 = { - .write_compress_enable = - radv_dcc_enabled(image, first_level) && is_storage_image && enable_write_compression, + .write_compress_enable = dcc_enabled && is_storage_image && enable_write_compression, .iterate_256 = radv_image_get_iterate256(device, image), }, .gfx9 = @@ -81,7 +81,7 @@ radv_set_mutable_tex_desc_fields(struct radv_device *device, struct radv_image * .block_width = block_width, }, .is_stencil = is_stencil, - .dcc_enabled = !disable_compression && radv_dcc_enabled(image, first_level), + .dcc_enabled = !disable_compression && dcc_enabled, .tc_compat_htile_enabled = !disable_compression && radv_image_is_tc_compat_htile(image), };