[Mesa-dev] [PATCH 2/2] radv: allow image view to be create before memory is bound

Dave Airlie airlied at gmail.com
Fri Nov 4 01:29:20 UTC 2016


From: Dave Airlie <airlied at redhat.com>

The spec doesn't seem to say this is illegal anywhere, it is
unexpected, but I've got an app doing what appears to be this.

This change splits out setting the base addresses to a separate
function, if the image has no memory bound we wait until
descriptor update time to bind the base addresses, after this
point they should be immutable.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/amd/vulkan/radv_descriptor_set.c |  2 ++
 src/amd/vulkan/radv_image.c          | 66 ++++++++++++++++++++++++++----------
 src/amd/vulkan/radv_private.h        |  3 ++
 3 files changed, 54 insertions(+), 17 deletions(-)

diff --git a/src/amd/vulkan/radv_descriptor_set.c b/src/amd/vulkan/radv_descriptor_set.c
index a4a12bf..599699d 100644
--- a/src/amd/vulkan/radv_descriptor_set.c
+++ b/src/amd/vulkan/radv_descriptor_set.c
@@ -616,6 +616,8 @@ write_image_descriptor(struct radv_device *device,
 		       const VkDescriptorImageInfo *image_info)
 {
 	RADV_FROM_HANDLE(radv_image_view, iview, image_info->imageView);
+
+	radv_set_descriptor_base_addresses(device, iview);
 	memcpy(dst, iview->descriptor, 8 * 4);
 	memcpy(dst + 8, iview->fmask_descriptor, 8 * 4);
 	*buffer_list = iview->image->bo;
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index 7e8b837..da8d0f5 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -195,31 +195,63 @@ si_set_mutable_tex_desc_fields(struct radv_device *device,
 			       unsigned block_width, bool is_stencil,
 			       uint32_t *state)
 {
-	uint64_t gpu_address = device->ws->buffer_get_va(image->bo) + image->offset;
-	uint64_t va = gpu_address + base_level_info->offset;
 	unsigned pitch = base_level_info->nblk_x * block_width;
 
-	state[1] &= C_008F14_BASE_ADDRESS_HI;
 	state[3] &= C_008F1C_TILING_INDEX;
 	state[4] &= C_008F20_PITCH;
 	state[6] &= C_008F28_COMPRESSION_EN;
 
-	assert(!(va & 255));
-
-	state[0] = va >> 8;
-	state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40);
 	state[3] |= S_008F1C_TILING_INDEX(si_tile_mode_index(image, base_level,
 							     is_stencil));
 	state[4] |= S_008F20_PITCH(pitch - 1);
 
 	if (image->surface.dcc_size && image->surface.level[first_level].dcc_enabled) {
 		state[6] |= S_008F28_COMPRESSION_EN(1);
-		state[7] = (gpu_address +
-			    image->dcc_offset +
-			    base_level_info->dcc_offset) >> 8;
+		state[7] = 0;
 	}
 }
 
+void
+radv_set_descriptor_base_addresses(struct radv_device *device,
+				   struct radv_image_view *iview)
+{
+	uint32_t *state = iview->descriptor;
+	uint64_t gpu_address = device->ws->buffer_get_va(iview->image->bo) + iview->image->offset;
+	uint64_t va;
+	const struct radeon_surf_level *base_level_info;
+
+	if (iview->descriptor_has_base_address)
+		return;
+
+	if (iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
+		base_level_info = &iview->image->surface.stencil_level[iview->base_mip];
+	else
+		base_level_info = &iview->image->surface.level[iview->base_mip];
+
+	va = gpu_address + base_level_info->offset;
+
+	state[0] = va >> 8;
+	state[1] &= C_008F14_BASE_ADDRESS_HI;
+	state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40);
+
+	if (iview->image->surface.dcc_size &&
+	    iview->image->surface.level[iview->base_mip].dcc_enabled) {
+		state[7] = (gpu_address + iview->image->dcc_offset +
+			     base_level_info->dcc_offset) >> 8;
+	}
+
+	if (iview->image->fmask.size) {
+		uint32_t *state = iview->fmask_descriptor;
+
+		va = gpu_address + iview->image->fmask.offset;
+		state[0] = va >> 8;
+		state[1] &= C_008F14_BASE_ADDRESS_HI;
+		state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40);
+	}
+
+	iview->descriptor_has_base_address = true;
+}
+
 static unsigned radv_tex_dim(VkImageType image_type, VkImageViewType view_type,
 			     unsigned nr_layers, unsigned nr_samples, bool is_storage_image)
 {
@@ -347,10 +379,6 @@ si_make_texture_descriptor(struct radv_device *device,
 	/* Initialize the sampler view for FMASK. */
 	if (image->fmask.size) {
 		uint32_t fmask_format;
-		uint64_t gpu_address = device->ws->buffer_get_va(image->bo);
-		uint64_t va;
-
-		va = gpu_address + image->offset + image->fmask.offset;
 
 		switch (image->samples) {
 		case 2:
@@ -367,9 +395,8 @@ si_make_texture_descriptor(struct radv_device *device,
 			fmask_format = V_008F14_IMG_DATA_FORMAT_INVALID;
 		}
 
-		fmask_state[0] = va >> 8;
-		fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) |
-			S_008F14_DATA_FORMAT(fmask_format) |
+		fmask_state[0] = 0;
+		fmask_state[1] = S_008F14_DATA_FORMAT(fmask_format) |
 			S_008F14_NUM_FORMAT(V_008F14_IMG_NUM_FORMAT_UINT);
 		fmask_state[2] = S_008F18_WIDTH(width - 1) |
 			S_008F18_HEIGHT(height - 1);
@@ -803,6 +830,11 @@ radv_image_view_init(struct radv_image_view *iview,
 				       is_stencil ? &image->surface.stencil_level[range->baseMipLevel] : &image->surface.level[range->baseMipLevel], range->baseMipLevel,
 				       range->baseMipLevel,
 				       image->surface.blk_w, is_stencil, iview->descriptor);
+
+	/* set base addresses if we have a image memory binding */
+	if (iview->image->bo)
+		radv_set_descriptor_base_addresses(device, iview);
+
 }
 
 void radv_image_set_optimal_micro_tile_mode(struct radv_device *device,
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index cfb913f..7dfc146 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -1028,6 +1028,7 @@ struct radv_image_view {
 	uint32_t base_mip;
 	VkExtent3D extent; /**< Extent of VkImageViewCreateInfo::baseMipLevel. */
 
+	bool descriptor_has_base_address;
 	uint32_t descriptor[8];
 	uint32_t fmask_descriptor[8];
 };
@@ -1050,6 +1051,8 @@ void radv_image_view_init(struct radv_image_view *view,
 			  VkImageUsageFlags usage_mask);
 void radv_image_set_optimal_micro_tile_mode(struct radv_device *device,
 					    struct radv_image *image, uint32_t micro_tile_mode);
+void radv_set_descriptor_base_addresses(struct radv_device *device,
+					struct radv_image_view *iview);
 struct radv_buffer_view {
 	struct radeon_winsys_bo *bo;
 	VkFormat vk_format;
-- 
2.7.4



More information about the mesa-dev mailing list