<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, ®ion->dstSubresource,<br>
®ion->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, ®ion->extent);<br>
+ const struct VkOffset3D srcOffset =<br>
+ anv_prep_image_offset(src_image->type, ®ion->srcOffset);<br>
+ const struct VkOffset3D dstOffset =<br>
+ anv_prep_image_offset(dest_image->type, ®ion->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>