<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>