<div dir="ltr">rb<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 24, 2016 at 3:22 PM, Nanley Chery <span dir="ltr"><<a href="mailto:nanleychery@gmail.com" target="_blank">nanleychery@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">From: Nanley Chery <<a href="mailto:nanley.g.chery@intel.com">nanley.g.chery@intel.com</a>><br>
<br>
Prepare Image extents and offsets for internal consumption by assigning<br>
</span>the default values implicitly defned by the spec. Fixes textures on<br>
<span class="">several Vulkan demos in which the VkImageCopy depth is set to zero when<br>
copying a 2D image.<br>
<br>
</span>v2 (Jason Ekstrand):<br>
   Replace "prep" with "sanitize"<br>
   Make function static inline<br>
   Pass structs instead of pointers<br>
<span class=""><br>
Signed-off-by: Nanley Chery <<a href="mailto:nanley.g.chery@intel.com">nanley.g.chery@intel.com</a>><br>
---<br>
</span> src/intel/vulkan/anv_image.c        | 24 ++++-------------<br>
 src/intel/vulkan/anv_meta_copy.c    | 53 ++++++++++++++++++++++++++-----------<br>
 src/intel/vulkan/anv_meta_resolve.c | 41 +++++++++++++++++++++-------<br>
 src/intel/vulkan/anv_private.h      | 33 +++++++++++++++++++++++<br>
 4 files changed, 106 insertions(+), 45 deletions(-)<br>
<br>
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c<br>
index 143a084..b47425b 100644<br>
--- a/src/intel/vulkan/anv_image.c<br>
+++ b/src/intel/vulkan/anv_image.c<br>
@@ -124,30 +124,16 @@ make_surface(const struct anv_device *dev,<br>
<span class=""><br>
    struct anv_surface *anv_surf = get_surface(image, aspect);<br>
<br>
-   VkExtent3D extent;<br>
-   switch (vk_info->imageType) {<br>
-   case VK_IMAGE_TYPE_1D:<br>
-      extent = (VkExtent3D) { vk_info->extent.width, 1, 1 };<br>
-      break;<br>
-   case VK_IMAGE_TYPE_2D:<br>
-      extent = (VkExtent3D) { vk_info->extent.width, vk_info->extent.height, 1 };<br>
-      break;<br>
-   case VK_IMAGE_TYPE_3D:<br>
-      extent = vk_info->extent;<br>
-      break;<br>
-   default:<br>
-      unreachable("invalid image type");<br>
-   }<br>
-<br>
-   image->extent = extent;<br>
</span>+   image->extent = anv_sanitize_image_extent(vk_info->imageType,<br>
+                                             vk_info->extent);<br>
<span class=""><br>
    ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,<br>
       .dim = vk_to_isl_surf_dim[vk_info->imageType],<br>
       .format = anv_get_isl_format(vk_info->format, aspect,<br>
                                    vk_info->tiling, NULL),<br>
-      .width = extent.width,<br>
-      .height = extent.height,<br>
-      .depth = extent.depth,<br>
+      .width = image->extent.width,<br>
+      .height = image->extent.height,<br>
+      .depth = image->extent.depth,<br>
       .levels = vk_info->mipLevels,<br>
       .array_len = vk_info->arrayLayers,<br>
       .samples = vk_info->samples,<br>
diff --git a/src/intel/vulkan/anv_meta_copy.c b/src/intel/vulkan/anv_meta_copy.c<br>
</span>index 1a2bfd6..982fa7e 100644<br>
<span class="">--- a/src/intel/vulkan/anv_meta_copy.c<br>
+++ b/src/intel/vulkan/anv_meta_copy.c<br>
@@ -28,16 +28,16 @@<br>
  * if Image is uncompressed or compressed, respectively.<br>
  */<br>
 static struct VkExtent3D<br>
-meta_region_extent_el(const VkFormat format,<br>
+meta_region_extent_el(const struct anv_image *image,<br>
                       const struct VkExtent3D *extent)<br>
 {<br>
    const struct isl_format_layout *isl_layout =<br>
-      anv_format_for_vk_format(format)->isl_layout;<br>
-   return (VkExtent3D) {<br>
+      anv_format_for_vk_format(image->vk_format)->isl_layout;<br>
</span>+   return anv_sanitize_image_extent(image->type, (VkExtent3D) {<br>
<span class="">       .width  = DIV_ROUND_UP(extent->width , isl_layout->bw),<br>
       .height = DIV_ROUND_UP(extent->height, isl_layout->bh),<br>
       .depth  = DIV_ROUND_UP(extent->depth , isl_layout->bd),<br>
-   };<br>
+   });<br>
 }<br>
<br>
 /* Returns the user-provided VkBufferImageCopy::imageOffset in units of<br>
@@ -49,11 +49,11 @@ meta_region_offset_el(const struct anv_image *image,<br>
                       const struct VkOffset3D *offset)<br>
 {<br>
    const struct isl_format_layout *isl_layout = image->format->isl_layout;<br>
-   return (VkOffset3D) {<br>
</span>+   return anv_sanitize_image_offset(image->type, (VkOffset3D) {<br>
<span class="">       .x = offset->x / isl_layout->bw,<br>
       .y = offset->y / isl_layout->bh,<br>
       .z = offset->z / isl_layout->bd,<br>
-   };<br>
+   });<br>
 }<br>
<br>
 static struct anv_meta_blit2d_surf<br>
</span>@@ -115,17 +115,28 @@ meta_copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,<br>
<div><div class="h5"><br>
    for (unsigned r = 0; r < regionCount; r++) {<br>
<br>
-      /* Start creating blit rect */<br>
+      /**<br>
+       * From the Vulkan 1.0.6 spec: 18.3 Copying Data Between Images<br>
+       *    extent is the size in texels of the source image to copy in width,<br>
+       *    height and depth. 1D images use only x and width. 2D images use x, y,<br>
+       *    width and height. 3D images use x, y, z, width, height and depth.<br>
+       *<br>
+       *<br>
+       * Also, convert the offsets and extent from units of texels to units of<br>
+       * blocks - which is the highest resolution accessible in this command.<br>
+       */<br>
       const VkOffset3D img_offset_el =<br>
          meta_region_offset_el(image, &pRegions[r].imageOffset);<br>
       const VkExtent3D bufferExtent = {<br>
          .width = pRegions[r].bufferRowLength,<br>
          .height = pRegions[r].bufferImageHeight,<br>
       };<br>
+<br>
+      /* Start creating blit rect */<br>
       const VkExtent3D buf_extent_el =<br>
-         meta_region_extent_el(image->vk_format, &bufferExtent);<br>
+         meta_region_extent_el(image, &bufferExtent);<br>
       const VkExtent3D img_extent_el =<br>
-         meta_region_extent_el(image->vk_format, &pRegions[r].imageExtent);<br>
+         meta_region_extent_el(image, &pRegions[r].imageExtent);<br>
       struct anv_meta_blit2d_rect rect = {<br>
          .width = MAX2(buf_extent_el.width, img_extent_el.width),<br>
          .height = MAX2(buf_extent_el.height, img_extent_el.height),<br>
</div></div>@@ -152,7 +163,7 @@ meta_copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,<br>
<span class="">       uint32_t *y_offset = forward ? &rect.dst_y : &rect.src_y;<br>
<br>
       /* Loop through each 3D or array slice */<br>
-      unsigned num_slices_3d = pRegions[r].imageExtent.depth;<br>
+      unsigned num_slices_3d = img_extent_el.depth;<br>
       unsigned num_slices_array = pRegions[r].imageSubresource.layerCount;<br>
       unsigned slice_3d = 0;<br>
       unsigned slice_array = 0;<br>
</span>@@ -163,7 +174,7 @@ meta_copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,<br>
<span class="">                                     pRegions[r].imageSubresource.mipLevel,<br>
                                     pRegions[r].imageSubresource.baseArrayLayer<br>
                                        + slice_array,<br>
-                                    pRegions[r].imageOffset.z + slice_3d,<br>
+                                    img_offset_el.z + slice_3d,<br>
                                     x_offset,<br>
                                     y_offset);<br>
          *x_offset += img_offset_el.x;<br>
</span>@@ -259,20 +270,30 @@ void anv_CmdCopyImage(<br>
<div><div class="h5">       struct anv_meta_blit2d_surf b_dst =<br>
          blit_surf_for_image(dest_image, dst_isl_surf);<br>
<br>
-      /* Start creating blit rect */<br>
+      /**<br>
+       * From the Vulkan 1.0.6 spec: 18.4 Copying Data Between Buffers and Images<br>
+       *    imageExtent is the size in texels of the image to copy in width, height<br>
+       *    and depth. 1D images use only x and width. 2D images use x, y, width<br>
+       *    and height. 3D images use x, y, z, width, height and depth.<br>
+       *<br>
+       * Also, convert the offsets and extent from units of texels to units of<br>
+       * blocks - which is the highest resolution accessible in this command.<br>
+       */<br>
       const VkOffset3D dst_offset_el =<br>
          meta_region_offset_el(dest_image, &pRegions[r].dstOffset);<br>
       const VkOffset3D src_offset_el =<br>
          meta_region_offset_el(src_image, &pRegions[r].srcOffset);<br>
       const VkExtent3D img_extent_el =<br>
-         meta_region_extent_el(src_image->vk_format, &pRegions[r].extent);<br>
+         meta_region_extent_el(src_image, &pRegions[r].extent);<br>
+<br>
+      /* Start creating blit rect */<br>
       struct anv_meta_blit2d_rect rect = {<br>
          .width = img_extent_el.width,<br>
          .height = img_extent_el.height,<br>
       };<br>
<br>
       /* Loop through each 3D or array slice */<br>
-      unsigned num_slices_3d = pRegions[r].extent.depth;<br>
+      unsigned num_slices_3d = img_extent_el.depth;<br>
       unsigned num_slices_array = pRegions[r].dstSubresource.layerCount;<br>
       unsigned slice_3d = 0;<br>
       unsigned slice_array = 0;<br>
</div></div>@@ -283,14 +304,14 @@ void anv_CmdCopyImage(<br>
<span class="">                                     pRegions[r].dstSubresource.mipLevel,<br>
                                     pRegions[r].dstSubresource.baseArrayLayer<br>
                                        + slice_array,<br>
-                                    pRegions[r].dstOffset.z + slice_3d,<br>
+                                    dst_offset_el.z + slice_3d,<br>
                                     &rect.dst_x,<br>
                                     &rect.dst_y);<br>
          isl_surf_get_image_offset_el(src_isl_surf,<br>
                                     pRegions[r].srcSubresource.mipLevel,<br>
                                     pRegions[r].srcSubresource.baseArrayLayer<br>
                                        + slice_array,<br>
-                                    pRegions[r].srcOffset.z + slice_3d,<br>
+                                    src_offset_el.z + slice_3d,<br>
                                     &rect.src_x,<br>
                                     &rect.src_y);<br>
          rect.dst_x += dst_offset_el.x;<br>
diff --git a/src/intel/vulkan/anv_meta_resolve.c b/src/intel/vulkan/anv_meta_resolve.c<br>
</span>index 19fb3ad..f50af52 100644<br>
<span class="">--- a/src/intel/vulkan/anv_meta_resolve.c<br>
+++ b/src/intel/vulkan/anv_meta_resolve.c<br>
@@ -719,6 +719,27 @@ void anv_CmdResolveImage(<br>
          anv_meta_get_iview_layer(dest_image, &region->dstSubresource,<br>
                                   &region->dstOffset);<br>
<br>
+      /**<br>
+       * From Vulkan 1.0.6 spec: 18.6 Resolving Multisample Images<br>
+       *<br>
+       *    extent is the size in texels of the source image to resolve in width,<br>
+       *    height and depth. 1D images use only x and width. 2D images use x, y,<br>
+       *    width and height. 3D images use x, y, z, width, height and depth.<br>
+       *<br>
+       *    srcOffset and dstOffset select the initial x, y, and z offsets in<br>
+       *    texels of the sub-regions of the source and destination image data.<br>
+       *    extent is the size in texels of the source image to resolve in width,<br>
+       *    height and depth. 1D images use only x and width. 2D images use x, y,<br>
+       *    width and height. 3D images use x, y, z, width, height and depth.<br>
+       */<br>
+      const struct VkExtent3D extent =<br>
</span>+         anv_sanitize_image_extent(src_image->type, region->extent);<br>
<span class="">+      const struct VkOffset3D srcOffset =<br>
</span>+         anv_sanitize_image_offset(src_image->type, region->srcOffset);<br>
<span class="">+      const struct VkOffset3D dstOffset =<br>
</span>+         anv_sanitize_image_offset(dest_image->type, region->dstOffset);<br>
<div><div class="h5">+<br>
+<br>
       for (uint32_t layer = 0; layer < region->srcSubresource.layerCount;<br>
            ++layer) {<br>
<br>
@@ -780,12 +801,12 @@ void anv_CmdResolveImage(<br>
                .framebuffer = fb_h,<br>
                .renderArea = {<br>
                   .offset = {<br>
-                     region->dstOffset.x,<br>
-                     region->dstOffset.y,<br>
+                     dstOffset.x,<br>
+                     dstOffset.y,<br>
                   },<br>
                   .extent = {<br>
-                     region->extent.width,<br>
-                     region->extent.height,<br>
+                     extent.width,<br>
+                     extent.height,<br>
                   }<br>
                },<br>
                .clearValueCount = 0,<br>
@@ -796,17 +817,17 @@ void anv_CmdResolveImage(<br>
          emit_resolve(cmd_buffer,<br>
              &src_iview,<br>
              &(VkOffset2D) {<br>
-               .x = region->srcOffset.x,<br>
-               .y = region->srcOffset.y,<br>
+               .x = srcOffset.x,<br>
+               .y = srcOffset.y,<br>
              },<br>
              &dest_iview,<br>
              &(VkOffset2D) {<br>
-               .x = region->dstOffset.x,<br>
-               .y = region->dstOffset.y,<br>
+               .x = dstOffset.x,<br>
+               .y = dstOffset.y,<br>
              },<br>
              &(VkExtent2D) {<br>
-               .width = region->extent.width,<br>
-               .height = region->extent.height,<br>
+               .width = extent.width,<br>
+               .height = extent.height,<br>
              });<br>
<br>
          ANV_CALL(CmdEndRenderPass)(cmd_buffer_h);<br>
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h<br>
</div></div>index 03e8767..94a13d7 100644<br>
--- a/src/intel/vulkan/anv_private.h<br>
+++ b/src/intel/vulkan/anv_private.h<br>
@@ -1670,6 +1670,39 @@ struct anv_buffer_view {<br>
<span class=""> const struct anv_format *<br>
 anv_format_for_descriptor_type(VkDescriptorType type);<br>
<br>
</span>+static inline struct VkExtent3D<br>
+anv_sanitize_image_extent(const VkImageType imageType,<br>
+                          const struct VkExtent3D imageExtent)<br>
<span class="">+{<br>
+   switch (imageType) {<br>
+   case VK_IMAGE_TYPE_1D:<br>
</span>+      return (VkExtent3D) { imageExtent.width, 1, 1 };<br>
+   case VK_IMAGE_TYPE_2D:<br>
+      return (VkExtent3D) { imageExtent.width, imageExtent.height, 1 };<br>
+   case VK_IMAGE_TYPE_3D:<br>
+      return imageExtent;<br>
<span class="">+   default:<br>
+      unreachable("invalid image type");<br>
+   }<br>
+}<br>
+<br>
</span>+static inline struct VkOffset3D<br>
+anv_sanitize_image_offset(const VkImageType imageType,<br>
+                          const struct VkOffset3D imageOffset)<br>
<span class="">+{<br>
+   switch (imageType) {<br>
+   case VK_IMAGE_TYPE_1D:<br>
</span>+      return (VkOffset3D) { imageOffset.x, 0, 0 };<br>
+   case VK_IMAGE_TYPE_2D:<br>
+      return (VkOffset3D) { imageOffset.x, imageOffset.y, 0 };<br>
+   case VK_IMAGE_TYPE_3D:<br>
+      return imageOffset;<br>
<span class="im HOEnZb">+   default:<br>
+      unreachable("invalid image type");<br>
+   }<br>
+}<br>
+<br>
</span><div class="HOEnZb"><div class="h5">+<br>
 void anv_fill_buffer_surface_state(struct anv_device *device,<br>
                                    struct anv_state state,<br>
                                    enum isl_format format,<br>
--<br>
2.7.4<br>
<br>
_______________________________________________<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/mailman/listinfo/mesa-dev</a><br>
</div></div></blockquote></div><br></div>