<div dir="ltr"><div>Oh, this is definitely against the spec... From section 11.6 of the 1.0.32 spec:<br><br>> Non-sparse resources must be bound completely and contiguously to a single<br>> VkDeviceMemory object before the resource is passed as a parameter to any<br>> of the following operations:<br>><br>> creating image or buffer views<br>> updating descriptor sets<br>> recording commands in a command buffer <br>><br>> Once bound, the memory binding is immutable for the lifetime of the resource.<br><br></div>Please do not implement this! Tell the app author to fix their bug instead.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Nov 3, 2016 at 6:29 PM, Dave Airlie <span dir="ltr"><<a href="mailto:airlied@gmail.com" target="_blank">airlied@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Dave Airlie <<a href="mailto:airlied@redhat.com">airlied@redhat.com</a>><br>
<br>
The spec doesn't seem to say this is illegal anywhere, it is<br>
unexpected, but I've got an app doing what appears to be this.<br>
<br>
This change splits out setting the base addresses to a separate<br>
function, if the image has no memory bound we wait until<br>
descriptor update time to bind the base addresses, after this<br>
point they should be immutable.<br>
<br>
Signed-off-by: Dave Airlie <<a href="mailto:airlied@redhat.com">airlied@redhat.com</a>><br>
---<br>
src/amd/vulkan/radv_<wbr>descriptor_set.c | 2 ++<br>
src/amd/vulkan/radv_image.c | 66 ++++++++++++++++++++++++++----<wbr>------<br>
src/amd/vulkan/radv_private.h | 3 ++<br>
3 files changed, 54 insertions(+), 17 deletions(-)<br>
<br>
diff --git a/src/amd/vulkan/radv_<wbr>descriptor_set.c b/src/amd/vulkan/radv_<wbr>descriptor_set.c<br>
index a4a12bf..599699d 100644<br>
--- a/src/amd/vulkan/radv_<wbr>descriptor_set.c<br>
+++ b/src/amd/vulkan/radv_<wbr>descriptor_set.c<br>
@@ -616,6 +616,8 @@ write_image_descriptor(struct radv_device *device,<br>
const VkDescriptorImageInfo *image_info)<br>
{<br>
RADV_FROM_HANDLE(radv_image_<wbr>view, iview, image_info->imageView);<br>
+<br>
+ radv_set_descriptor_base_<wbr>addresses(device, iview);<br>
memcpy(dst, iview->descriptor, 8 * 4);<br>
memcpy(dst + 8, iview->fmask_descriptor, 8 * 4);<br>
*buffer_list = iview->image->bo;<br>
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c<br>
index 7e8b837..da8d0f5 100644<br>
--- a/src/amd/vulkan/radv_image.c<br>
+++ b/src/amd/vulkan/radv_image.c<br>
@@ -195,31 +195,63 @@ si_set_mutable_tex_desc_<wbr>fields(struct radv_device *device,<br>
unsigned block_width, bool is_stencil,<br>
uint32_t *state)<br>
{<br>
- uint64_t gpu_address = device->ws->buffer_get_va(<wbr>image->bo) + image->offset;<br>
- uint64_t va = gpu_address + base_level_info->offset;<br>
unsigned pitch = base_level_info->nblk_x * block_width;<br>
<br>
- state[1] &= C_008F14_BASE_ADDRESS_HI;<br>
state[3] &= C_008F1C_TILING_INDEX;<br>
state[4] &= C_008F20_PITCH;<br>
state[6] &= C_008F28_COMPRESSION_EN;<br>
<br>
- assert(!(va & 255));<br>
-<br>
- state[0] = va >> 8;<br>
- state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40);<br>
state[3] |= S_008F1C_TILING_INDEX(si_tile_<wbr>mode_index(image, base_level,<br>
is_stencil));<br>
state[4] |= S_008F20_PITCH(pitch - 1);<br>
<br>
if (image->surface.dcc_size && image->surface.level[first_<wbr>level].dcc_enabled) {<br>
state[6] |= S_008F28_COMPRESSION_EN(1);<br>
- state[7] = (gpu_address +<br>
- image->dcc_offset +<br>
- base_level_info->dcc_offset) >> 8;<br>
+ state[7] = 0;<br>
}<br>
}<br>
<br>
+void<br>
+radv_set_descriptor_base_<wbr>addresses(struct radv_device *device,<br>
+ struct radv_image_view *iview)<br>
+{<br>
+ uint32_t *state = iview->descriptor;<br>
+ uint64_t gpu_address = device->ws->buffer_get_va(<wbr>iview->image->bo) + iview->image->offset;<br>
+ uint64_t va;<br>
+ const struct radeon_surf_level *base_level_info;<br>
+<br>
+ if (iview->descriptor_has_base_<wbr>address)<br>
+ return;<br>
+<br>
+ if (iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)<br>
+ base_level_info = &iview->image->surface.<wbr>stencil_level[iview->base_mip]<wbr>;<br>
+ else<br>
+ base_level_info = &iview->image->surface.level[<wbr>iview->base_mip];<br>
+<br>
+ va = gpu_address + base_level_info->offset;<br>
+<br>
+ state[0] = va >> 8;<br>
+ state[1] &= C_008F14_BASE_ADDRESS_HI;<br>
+ state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40);<br>
+<br>
+ if (iview->image->surface.dcc_<wbr>size &&<br>
+ iview->image->surface.level[<wbr>iview->base_mip].dcc_enabled) {<br>
+ state[7] = (gpu_address + iview->image->dcc_offset +<br>
+ base_level_info->dcc_offset) >> 8;<br>
+ }<br>
+<br>
+ if (iview->image->fmask.size) {<br>
+ uint32_t *state = iview->fmask_descriptor;<br>
+<br>
+ va = gpu_address + iview->image->fmask.offset;<br>
+ state[0] = va >> 8;<br>
+ state[1] &= C_008F14_BASE_ADDRESS_HI;<br>
+ state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40);<br>
+ }<br>
+<br>
+ iview->descriptor_has_base_<wbr>address = true;<br>
+}<br>
+<br>
static unsigned radv_tex_dim(VkImageType image_type, VkImageViewType view_type,<br>
unsigned nr_layers, unsigned nr_samples, bool is_storage_image)<br>
{<br>
@@ -347,10 +379,6 @@ si_make_texture_descriptor(<wbr>struct radv_device *device,<br>
/* Initialize the sampler view for FMASK. */<br>
if (image->fmask.size) {<br>
uint32_t fmask_format;<br>
- uint64_t gpu_address = device->ws->buffer_get_va(<wbr>image->bo);<br>
- uint64_t va;<br>
-<br>
- va = gpu_address + image->offset + image->fmask.offset;<br>
<br>
switch (image->samples) {<br>
case 2:<br>
@@ -367,9 +395,8 @@ si_make_texture_descriptor(<wbr>struct radv_device *device,<br>
fmask_format = V_008F14_IMG_DATA_FORMAT_<wbr>INVALID;<br>
}<br>
<br>
- fmask_state[0] = va >> 8;<br>
- fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) |<br>
- S_008F14_DATA_FORMAT(fmask_<wbr>format) |<br>
+ fmask_state[0] = 0;<br>
+ fmask_state[1] = S_008F14_DATA_FORMAT(fmask_<wbr>format) |<br>
S_008F14_NUM_FORMAT(V_008F14_<wbr>IMG_NUM_FORMAT_UINT);<br>
fmask_state[2] = S_008F18_WIDTH(width - 1) |<br>
S_008F18_HEIGHT(height - 1);<br>
@@ -803,6 +830,11 @@ radv_image_view_init(struct radv_image_view *iview,<br>
is_stencil ? &image->surface.stencil_level[<wbr>range->baseMipLevel] : &image->surface.level[range-><wbr>baseMipLevel], range->baseMipLevel,<br>
range->baseMipLevel,<br>
image->surface.blk_w, is_stencil, iview->descriptor);<br>
+<br>
+ /* set base addresses if we have a image memory binding */<br>
+ if (iview->image->bo)<br>
+ radv_set_descriptor_base_<wbr>addresses(device, iview);<br>
+<br>
}<br>
<br>
void radv_image_set_optimal_micro_<wbr>tile_mode(struct radv_device *device,<br>
diff --git a/src/amd/vulkan/radv_private.<wbr>h b/src/amd/vulkan/radv_private.<wbr>h<br>
index cfb913f..7dfc146 100644<br>
--- a/src/amd/vulkan/radv_private.<wbr>h<br>
+++ b/src/amd/vulkan/radv_private.<wbr>h<br>
@@ -1028,6 +1028,7 @@ struct radv_image_view {<br>
uint32_t base_mip;<br>
VkExtent3D extent; /**< Extent of VkImageViewCreateInfo::<wbr>baseMipLevel. */<br>
<br>
+ bool descriptor_has_base_address;<br>
uint32_t descriptor[8];<br>
uint32_t fmask_descriptor[8];<br>
};<br>
@@ -1050,6 +1051,8 @@ void radv_image_view_init(struct radv_image_view *view,<br>
VkImageUsageFlags usage_mask);<br>
void radv_image_set_optimal_micro_<wbr>tile_mode(struct radv_device *device,<br>
struct radv_image *image, uint32_t micro_tile_mode);<br>
+void radv_set_descriptor_base_<wbr>addresses(struct radv_device *device,<br>
+ struct radv_image_view *iview);<br>
struct radv_buffer_view {<br>
struct radeon_winsys_bo *bo;<br>
VkFormat vk_format;<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.7.4<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div>