<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 24, 2016 at 9:27 AM, 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">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>
the default values implicitly defined by the spec. Fixes textures on<br>
several Vulkan demos in which the VkImageCopy depth is set to zero when<br>
copying a 2D image.<br>
<br>
Signed-off-by: Nanley Chery <<a href="mailto:nanley.g.chery@intel.com">nanley.g.chery@intel.com</a>><br>
---<br>
 src/intel/vulkan/anv_image.c        | 56 ++++++++++++++++++++++++-------------<br>
 src/intel/vulkan/anv_meta_copy.c    | 54 ++++++++++++++++++++++++-----------<br>
 src/intel/vulkan/anv_meta_resolve.c | 41 ++++++++++++++++++++-------<br>
 src/intel/vulkan/anv_private.h      |  7 +++++<br>
 4 files changed, 113 insertions(+), 45 deletions(-)<br>
<br>
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c<br>
index 143a084..88db1fc 100644<br>
--- a/src/intel/vulkan/anv_image.c<br>
+++ b/src/intel/vulkan/anv_image.c<br>
@@ -97,6 +97,38 @@ get_surface(struct anv_image *image, VkImageAspectFlags aspect)<br>
    }<br>
 }<br>
<br>
+struct VkExtent3D<br>
+anv_prep_image_extent(const VkImageType imageType,<br>
+                      const struct VkExtent3D *imageExtent)<br>
+{<br>
+   switch (imageType) {<br>
+   case VK_IMAGE_TYPE_1D:<br>
+      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>
+   default:<br>
+      unreachable("invalid image type");<br>
+   }<br>
+}<br>
+<br>
+struct VkOffset3D<br>
+anv_prep_image_offset(const VkImageType imageType,<br>
+                      const struct VkOffset3D *imageOffset)<br>
+{<br>
+   switch (imageType) {<br>
+   case VK_IMAGE_TYPE_1D:<br>
+      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>
+   default:<br>
+      unreachable("invalid image type");<br></blockquote><div><br></div><div>Two primary comments.  First, I don't really like "prep".  Maybe "anv_sanatize_offset".  Second, I think this is a good candidate for an inline function.  It's used a lot of places and the compiler may be able to optimize things a bit.<br><br></div><div>Also, I don't think we really need to pass in a pointer.  For a struct as small as VkOffset3D it's probably going to be more efficient to just pass the struct.<br><br></div><div>Other than that, I really like it.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+   }<br>
+}<br>
+<br>
 /**<br>
  * Initialize the anv_image::*_surface selected by \a aspect. Then update the<br>
  * image's memory requirements (that is, the image's size and alignment).<br>
@@ -124,30 +156,16 @@ make_surface(const struct anv_device *dev,<br>
<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>
+   image->extent = anv_prep_image_extent(vk_info->imageType,<br>
+                                         &vk_info->extent);<br>
<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>
index 1a2bfd6..16a802b 100644<br>
--- 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>
+   return anv_prep_image_extent(image->type, &(VkExtent3D) {<br>
       .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>
+   return anv_prep_image_offset(image->type, &(VkOffset3D) {<br>
       .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>
@@ -115,17 +115,29 @@ meta_copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,<br>
<br>
    for (unsigned r = 0; r < regionCount; r++) {<br>
<br>
-      /* Start creating blit rect */<br>
+<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>
@@ -152,7 +164,7 @@ meta_copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,<br>
       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>
@@ -163,7 +175,7 @@ meta_copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,<br>
                                     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>
@@ -259,20 +271,30 @@ void anv_CmdCopyImage(<br>
       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>
@@ -283,14 +305,14 @@ void anv_CmdCopyImage(<br>
                                     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>
index 19fb3ad..914494b 100644<br>
--- 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>
+         anv_prep_image_extent(src_image->type, &region->extent);<br>
+      const struct VkOffset3D srcOffset =<br>
+         anv_prep_image_offset(src_image->type, &region->srcOffset);<br>
+      const struct VkOffset3D dstOffset =<br>
+         anv_prep_image_offset(dest_image->type, &region->dstOffset);<br>
+<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>
index 03e8767..44b4091 100644<br>
--- a/src/intel/vulkan/anv_private.h<br>
+++ b/src/intel/vulkan/anv_private.h<br>
@@ -1670,6 +1670,13 @@ struct anv_buffer_view {<br>
 const struct anv_format *<br>
 anv_format_for_descriptor_type(VkDescriptorType type);<br>
<br>
+struct VkExtent3D<br>
+anv_prep_image_extent(const VkImageType imageType,<br>
+                      const struct VkExtent3D *imageExtent);<br>
+struct VkOffset3D<br>
+anv_prep_image_offset(const VkImageType imageType,<br>
+                      const struct VkOffset3D *imageOffset);<br>
+<br>
 void anv_fill_buffer_surface_state(struct anv_device *device,<br>
                                    struct anv_state state,<br>
                                    enum isl_format format,<br>
<span class="HOEnZb"><font color="#888888">--<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>
</font></span></blockquote></div><br></div></div>