<div dir="ltr">Hi Gražvydas,<br><br>I don't have Doom available to test. How's it broken?<br><br>Could you see if removing the usage flags condition on the second call to radv_image_view_make_descriptor makes any difference? Otherwise I'm not sure what's wrong - as far as I could tell this should be making RADV do basically the same as what radeonsi does.<div><br></div><div>Thanks,</div><div>Alex</div></div><div class="gmail_extra"><br><div class="gmail_quote">On 21 July 2017 at 02:20, Grazvydas Ignotas <span dir="ltr"><<a href="mailto:notasas@gmail.com" target="_blank">notasas@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">For whatever reason this patch is breaking DOOM.<br>
<br>
Gražvydas<br>
<div><div class="h5"><br>
On Wed, Jul 12, 2017 at 12:29 PM, Alex Smith<br>
<<a href="mailto:asmith@feralinteractive.com">asmith@feralinteractive.com</a>> wrote:<br>
> If a cube image has VK_IMAGE_USAGE_STORAGE_BIT set, the type in an image<br>
> view's descriptor was set to a 2D array (and a few other fields adjusted<br>
> accordingly). This is correct when the image view is actually bound as a<br>
> storage image, but not when bound as a sampled image. In that case the<br>
> type should be set as a cube.<br>
><br>
> Fix by generating 2 sets of descriptors at view creation time for both<br>
> storage and non-storage usage, and then choose between them based on<br>
> descriptor type when writing descriptor sets.<br>
><br>
> v2: Generate storage descriptors for images with TRANSFER_DST, since<br>
>     those may be used as storage images internally.<br>
><br>
> Signed-off-by: Alex Smith <<a href="mailto:asmith@feralinteractive.com">asmith@feralinteractive.com</a>><br>
> Reviewed-by: Bas Nieuwenhuizen <<a href="mailto:bas@basnieuwenhuizen.nl">bas@basnieuwenhuizen.nl</a>><br>
> ---<br>
>  src/amd/vulkan/radv_<wbr>descriptor_set.c | 18 ++++++--<br>
>  src/amd/vulkan/radv_image.c          | 79 ++++++++++++++++++++++++------<wbr>------<br>
>  src/amd/vulkan/radv_private.h        |  6 +++<br>
>  3 files changed, 74 insertions(+), 29 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 ec7fd3d..b4a78aa 100644<br>
> --- a/src/amd/vulkan/radv_<wbr>descriptor_set.c<br>
> +++ b/src/amd/vulkan/radv_<wbr>descriptor_set.c<br>
> @@ -603,11 +603,18 @@ write_image_descriptor(struct radv_device *device,<br>
>                        struct radv_cmd_buffer *cmd_buffer,<br>
>                        unsigned *dst,<br>
>                        struct radeon_winsys_bo **buffer_list,<br>
> +                      VkDescriptorType descriptor_type,<br>
>                        const VkDescriptorImageInfo *image_info)<br>
>  {<br>
>         RADV_FROM_HANDLE(radv_image_<wbr>view, iview, image_info->imageView);<br>
> -       memcpy(dst, iview->descriptor, 8 * 4);<br>
> -       memcpy(dst + 8, iview->fmask_descriptor, 8 * 4);<br>
> +<br>
> +       if (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_<wbr>IMAGE) {<br>
> +               memcpy(dst, iview->storage_descriptor, 8 * 4);<br>
> +               memcpy(dst + 8, iview->storage_fmask_<wbr>descriptor, 8 * 4);<br>
> +       } else {<br>
> +               memcpy(dst, iview->descriptor, 8 * 4);<br>
> +               memcpy(dst + 8, iview->fmask_descriptor, 8 * 4);<br>
> +       }<br>
><br>
>         if (cmd_buffer)<br>
>                 device->ws->cs_add_buffer(cmd_<wbr>buffer->cs, iview->bo, 7);<br>
> @@ -620,12 +627,13 @@ write_combined_image_sampler_<wbr>descriptor(struct radv_device *device,<br>
>                                         struct radv_cmd_buffer *cmd_buffer,<br>
>                                         unsigned *dst,<br>
>                                         struct radeon_winsys_bo **buffer_list,<br>
> +                                       VkDescriptorType descriptor_type,<br>
>                                         const VkDescriptorImageInfo *image_info,<br>
>                                         bool has_sampler)<br>
>  {<br>
>         RADV_FROM_HANDLE(radv_sampler, sampler, image_info->sampler);<br>
><br>
> -       write_image_descriptor(device, cmd_buffer, dst, buffer_list, image_info);<br>
> +       write_image_descriptor(device, cmd_buffer, dst, buffer_list, descriptor_type, image_info);<br>
>         /* copy over sampler state */<br>
>         if (has_sampler)<br>
>                 memcpy(dst + 16, sampler->state, 16);<br>
> @@ -696,10 +704,12 @@ void radv_update_descriptor_sets(<br>
>                         case VK_DESCRIPTOR_TYPE_STORAGE_<wbr>IMAGE:<br>
>                         case VK_DESCRIPTOR_TYPE_INPUT_<wbr>ATTACHMENT:<br>
>                                 write_image_descriptor(device, cmd_buffer, ptr, buffer_list,<br>
> +                                                      writeset->descriptorType,<br>
>                                                        writeset->pImageInfo + j);<br>
>                                 break;<br>
>                         case VK_DESCRIPTOR_TYPE_COMBINED_<wbr>IMAGE_SAMPLER:<br>
>                                 write_combined_image_sampler_<wbr>descriptor(device, cmd_buffer, ptr, buffer_list,<br>
> +                                                                       writeset->descriptorType,<br>
>                                                                         writeset->pImageInfo + j,<br>
>                                                                         !binding_layout->immutable_<wbr>samplers_offset);<br>
>                                 if (copy_immutable_samplers) {<br>
> @@ -866,10 +876,12 @@ void radv_update_descriptor_set_<wbr>with_template(struct radv_device *device,<br>
>                         case VK_DESCRIPTOR_TYPE_STORAGE_<wbr>IMAGE:<br>
>                         case VK_DESCRIPTOR_TYPE_INPUT_<wbr>ATTACHMENT:<br>
>                                 write_image_descriptor(device, cmd_buffer, pDst, buffer_list,<br>
> +                                                      templ->entry[i].descriptor_<wbr>type,<br>
>                                                        (struct VkDescriptorImageInfo *) pSrc);<br>
>                                 break;<br>
>                         case VK_DESCRIPTOR_TYPE_COMBINED_<wbr>IMAGE_SAMPLER:<br>
>                                 write_combined_image_sampler_<wbr>descriptor(device, cmd_buffer, pDst, buffer_list,<br>
> +                                                                       templ->entry[i].descriptor_<wbr>type,<br>
>                                                                         (struct VkDescriptorImageInfo *) pSrc,<br>
>                                                                         templ->entry[i].has_sampler);<br>
>                                 if (templ->entry[i].immutable_<wbr>samplers)<br>
> diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c<br>
> index 115e5a5..245bca3 100644<br>
> --- a/src/amd/vulkan/radv_image.c<br>
> +++ b/src/amd/vulkan/radv_image.c<br>
> @@ -325,7 +325,7 @@ static unsigned gfx9_border_color_swizzle(<wbr>const unsigned char swizzle[4])<br>
>  static void<br>
>  si_make_texture_descriptor(<wbr>struct radv_device *device,<br>
>                            struct radv_image *image,<br>
> -                          bool sampler,<br>
> +                          bool is_storage_image,<br>
>                            VkImageViewType view_type,<br>
>                            VkFormat vk_format,<br>
>                            const VkComponentMapping *mapping,<br>
> @@ -362,7 +362,7 @@ si_make_texture_descriptor(<wbr>struct radv_device *device,<br>
>         }<br>
><br>
>         type = radv_tex_dim(image->type, view_type, image->info.array_size, image->info.samples,<br>
> -                           (image->usage & VK_IMAGE_USAGE_STORAGE_BIT));<br>
> +                           is_storage_image);<br>
>         if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {<br>
>                 height = 1;<br>
>                 depth = image->info.array_size;<br>
> @@ -526,7 +526,7 @@ radv_query_opaque_metadata(<wbr>struct radv_device *device,<br>
>         md->metadata[1] = si_get_bo_metadata_word1(<wbr>device);<br>
><br>
><br>
> -       si_make_texture_descriptor(<wbr>device, image, true,<br>
> +       si_make_texture_descriptor(<wbr>device, image, false,<br>
>                                    (VkImageViewType)image->type, image->vk_format,<br>
>                                    &fixedmapping, 0, image->info.levels - 1, 0,<br>
>                                    image->info.array_size,<br>
> @@ -834,6 +834,50 @@ radv_image_create(VkDevice _device,<br>
>         return VK_SUCCESS;<br>
>  }<br>
><br>
> +static void<br>
> +radv_image_view_make_<wbr>descriptor(struct radv_image_view *iview,<br>
> +                               struct radv_device *device,<br>
> +                               const VkImageViewCreateInfo* pCreateInfo,<br>
> +                               bool is_storage_image)<br>
> +{<br>
> +       RADV_FROM_HANDLE(radv_image, image, pCreateInfo->image);<br>
> +       const VkImageSubresourceRange *range = &pCreateInfo-><wbr>subresourceRange;<br>
> +       bool is_stencil = iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT;<br>
> +       uint32_t blk_w;<br>
> +       uint32_t *descriptor;<br>
> +       uint32_t *fmask_descriptor;<br>
> +<br>
> +       if (is_storage_image) {<br>
> +               descriptor = iview->storage_descriptor;<br>
> +               fmask_descriptor = iview->storage_fmask_<wbr>descriptor;<br>
> +       } else {<br>
> +               descriptor = iview->descriptor;<br>
> +               fmask_descriptor = iview->fmask_descriptor;<br>
> +       }<br>
> +<br>
> +       assert(image->surface.blk_w % vk_format_get_blockwidth(<wbr>image->vk_format) == 0);<br>
> +       blk_w = image->surface.blk_w / vk_format_get_blockwidth(<wbr>image->vk_format) * vk_format_get_blockwidth(<wbr>iview->vk_format);<br>
> +<br>
> +       si_make_texture_descriptor(<wbr>device, image, is_storage_image,<br>
> +                                  iview->type,<br>
> +                                  iview->vk_format,<br>
> +                                  &pCreateInfo->components,<br>
> +                                  0, radv_get_levelCount(image, range) - 1,<br>
> +                                  range->baseArrayLayer,<br>
> +                                  range->baseArrayLayer + radv_get_layerCount(image, range) - 1,<br>
> +                                  iview->extent.width,<br>
> +                                  iview->extent.height,<br>
> +                                  iview->extent.depth,<br>
> +                                  descriptor,<br>
> +                                  fmask_descriptor);<br>
> +       si_set_mutable_tex_desc_<wbr>fields(device, image,<br>
> +                                      is_stencil ? &image->surface.u.legacy.<wbr>stencil_level[range-><wbr>baseMipLevel]<br>
> +                                                 : &image->surface.u.legacy.<wbr>level[range->baseMipLevel],<br>
> +                                      range->baseMipLevel,<br>
> +                                      range->baseMipLevel,<br>
> +                                      blk_w, is_stencil, descriptor);<br>
> +}<br>
> +<br>
>  void<br>
>  radv_image_view_init(struct radv_image_view *iview,<br>
>                      struct radv_device *device,<br>
> @@ -841,8 +885,7 @@ radv_image_view_init(struct radv_image_view *iview,<br>
>  {<br>
>         RADV_FROM_HANDLE(radv_image, image, pCreateInfo->image);<br>
>         const VkImageSubresourceRange *range = &pCreateInfo-><wbr>subresourceRange;<br>
> -       uint32_t blk_w;<br>
> -       bool is_stencil = false;<br>
> +<br>
>         switch (image->type) {<br>
>         case VK_IMAGE_TYPE_1D:<br>
>         case VK_IMAGE_TYPE_2D:<br>
> @@ -862,7 +905,6 @@ radv_image_view_init(struct radv_image_view *iview,<br>
>         iview->aspect_mask = pCreateInfo->subresourceRange.<wbr>aspectMask;<br>
><br>
>         if (iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {<br>
> -               is_stencil = true;<br>
>                 iview->vk_format = vk_format_stencil_only(iview-><wbr>vk_format);<br>
>         } else if (iview->aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) {<br>
>                 iview->vk_format = vk_format_depth_only(iview-><wbr>vk_format);<br>
> @@ -879,30 +921,15 @@ radv_image_view_init(struct radv_image_view *iview,<br>
>         iview->extent.height = round_up_u32(iview->extent.<wbr>height * vk_format_get_blockheight(<wbr>iview->vk_format),<br>
>                                             vk_format_get_blockheight(<wbr>image->vk_format));<br>
><br>
> -       assert(image->surface.blk_w % vk_format_get_blockwidth(<wbr>image->vk_format) == 0);<br>
> -       blk_w = image->surface.blk_w / vk_format_get_blockwidth(<wbr>image->vk_format) * vk_format_get_blockwidth(<wbr>iview->vk_format);<br>
>         iview->base_layer = range->baseArrayLayer;<br>
>         iview->layer_count = radv_get_layerCount(image, range);<br>
>         iview->base_mip = range->baseMipLevel;<br>
><br>
> -       si_make_texture_descriptor(<wbr>device, image, false,<br>
> -                                  iview->type,<br>
> -                                  iview->vk_format,<br>
> -                                  &pCreateInfo->components,<br>
> -                                  0, radv_get_levelCount(image, range) - 1,<br>
> -                                  range->baseArrayLayer,<br>
> -                                  range->baseArrayLayer + radv_get_layerCount(image, range) - 1,<br>
> -                                  iview->extent.width,<br>
> -                                  iview->extent.height,<br>
> -                                  iview->extent.depth,<br>
> -                                  iview->descriptor,<br>
> -                                  iview->fmask_descriptor);<br>
> -       si_set_mutable_tex_desc_<wbr>fields(device, image,<br>
> -                                      is_stencil ? &image->surface.u.legacy.<wbr>stencil_level[range-><wbr>baseMipLevel]<br>
> -                                                 : &image->surface.u.legacy.<wbr>level[range->baseMipLevel],<br>
> -                                      range->baseMipLevel,<br>
> -                                      range->baseMipLevel,<br>
> -                                      blk_w, is_stencil, iview->descriptor);<br>
> +       radv_image_view_make_<wbr>descriptor(iview, device, pCreateInfo, false);<br>
> +<br>
> +       /* For transfers we may use the image as a storage image. */<br>
> +       if (image->usage & (VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_<wbr>BIT))<br>
> +               radv_image_view_make_<wbr>descriptor(iview, device, pCreateInfo, true);<br>
>  }<br>
><br>
>  bool radv_layout_has_htile(const struct radv_image *image,<br>
> diff --git a/src/amd/vulkan/radv_private.<wbr>h b/src/amd/vulkan/radv_private.<wbr>h<br>
> index a167409..a8bc5c9 100644<br>
> --- a/src/amd/vulkan/radv_private.<wbr>h<br>
> +++ b/src/amd/vulkan/radv_private.<wbr>h<br>
> @@ -1276,6 +1276,12 @@ struct radv_image_view {<br>
><br>
>         uint32_t descriptor[8];<br>
>         uint32_t fmask_descriptor[8];<br>
> +<br>
> +       /* Descriptor for use as a storage image as opposed to a sampled image.<br>
> +        * This has a few differences for cube maps (e.g. type).<br>
> +        */<br>
> +       uint32_t storage_descriptor[8];<br>
> +       uint32_t storage_fmask_descriptor[8];<br>
>  };<br>
><br>
>  struct radv_image_create_info {<br>
> --<br>
> 2.9.4<br>
><br>
</div></div>> ______________________________<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>
</blockquote></div><br></div>