Mesa (master): radv: Implement initialization of displayable DCC.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Feb 23 13:02:37 UTC 2021


Module: Mesa
Branch: master
Commit: e34542bdf12740372732bef20d6327e7b46696c9
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e34542bdf12740372732bef20d6327e7b46696c9

Author: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Date:   Wed Aug  5 03:32:19 2020 +0200

radv: Implement initialization of displayable DCC.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9042>

---

 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. */



More information about the mesa-commit mailing list