From e34542bdf12740372732bef20d6327e7b46696c9 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Wed, 5 Aug 2020 03:32:19 +0200 Subject: [PATCH] radv: Implement initialization of displayable DCC. Reviewed-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_image.c | 37 +++++++++++++++++++++++++++++ src/amd/vulkan/radv_private.h | 9 +++++++ src/amd/vulkan/radv_radeon_winsys.h | 1 + 3 files changed, 47 insertions(+) diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index 3f87a60ebe4..5ab7ac671b9 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -1320,6 +1320,36 @@ radv_image_reset_layout(struct radv_image *image) } } +static VkResult +radv_image_init_retile_map(struct radv_device *device, struct radv_image *image) +{ + /* If we do a relayout we have to free the old buffer. */ + if(image->retile_map) + device->ws->buffer_destroy(device->ws, image->retile_map); + + image->retile_map = NULL; + if (!radv_image_has_dcc(image) || !image->planes[0].surface.display_dcc_offset || + image->planes[0].surface.display_dcc_offset == image->planes[0].surface.dcc_offset) + return VK_SUCCESS; + + uint32_t retile_map_size = ac_surface_get_retile_map_size(&image->planes[0].surface); + image->retile_map = device->ws->buffer_create(device->ws, retile_map_size, 4096, + RADEON_DOMAIN_VRAM, RADEON_FLAG_READ_ONLY | + RADEON_FLAG_NO_INTERPROCESS_SHARING, + RADV_BO_PRIORITY_METADATA); + if (!image->retile_map) { + return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY); + } + void *data = device->ws->buffer_map(image->retile_map); + if (!data) { + device->ws->buffer_destroy(device->ws, image->retile_map); + return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + } + + memcpy(data, image->planes[0].surface.u.gfx9.dcc_retile_map, retile_map_size); + return VK_SUCCESS; +} + VkResult radv_image_create_layout(struct radv_device *device, struct radv_image_create_info create_info, @@ -1411,6 +1441,10 @@ radv_image_create_layout(struct radv_device *device, radv_image_alloc_values(device, image); + result = radv_image_init_retile_map(device, image); + if (result != VK_SUCCESS) + return result; + assert(image->planes[0].surface.surf_size); assert(image->planes[0].surface.modifier == DRM_FORMAT_MOD_INVALID || ac_modifier_has_dcc(image->planes[0].surface.modifier) == radv_image_has_dcc(image)); @@ -1425,6 +1459,9 @@ radv_destroy_image(struct radv_device *device, if ((image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && image->bo) device->ws->buffer_destroy(device->ws, image->bo); + if(image->retile_map) + device->ws->buffer_destroy(device->ws, image->retile_map); + if (image->owned_memory != VK_NULL_HANDLE) { RADV_FROM_HANDLE(radv_device_memory, mem, image->owned_memory); radv_free_memory(device, pAllocator, mem); diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 7b4d291b600..8cbea4c0cec 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1870,6 +1870,15 @@ struct radv_image { uint64_t fce_pred_offset; uint64_t dcc_pred_offset; + /* On some GPUs DCC needs different tiling of the metadata for + * rendering and for display, so we're stuck with having the metadata + * two times and then occasionally copying one into the other. + * + * The retile map is an array of (src index, dst index) pairs to + * determine how it should be copied between the two. + */ + struct radeon_winsys_bo *retile_map; + /* * Metadata for the TC-compat zrange workaround. If the 32-bit value * stored at this offset is UINT_MAX, the driver will emit diff --git a/src/amd/vulkan/radv_radeon_winsys.h b/src/amd/vulkan/radv_radeon_winsys.h index cbab78ad249..ef24483a788 100644 --- a/src/amd/vulkan/radv_radeon_winsys.h +++ b/src/amd/vulkan/radv_radeon_winsys.h @@ -192,6 +192,7 @@ enum { /* virtual buffers have 0 priority since the priority is not used. */ RADV_BO_PRIORITY_VIRTUAL = 0, + RADV_BO_PRIORITY_METADATA = 10, /* This should be considerably lower than most of the stuff below, * but how much lower is hard to say since we don't know application * assignments. Put it pretty high since it is GTT anyway. */