struct anv_surface *anv_surf = get_surface(image, aspect);
- VkExtent3D extent;
- switch (vk_info->imageType) {
- case VK_IMAGE_TYPE_1D:
- extent = (VkExtent3D) { vk_info->extent.width, 1, 1 };
- break;
- case VK_IMAGE_TYPE_2D:
- extent = (VkExtent3D) { vk_info->extent.width, vk_info->extent.height, 1 };
- break;
- case VK_IMAGE_TYPE_3D:
- extent = vk_info->extent;
- break;
- default:
- unreachable("invalid image type");
- }
-
- image->extent = extent;
+ image->extent = anv_sanitize_image_extent(vk_info->imageType,
+ vk_info->extent);
ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,
.dim = vk_to_isl_surf_dim[vk_info->imageType],
.format = anv_get_isl_format(vk_info->format, aspect,
vk_info->tiling, NULL),
- .width = extent.width,
- .height = extent.height,
- .depth = extent.depth,
+ .width = image->extent.width,
+ .height = image->extent.height,
+ .depth = image->extent.depth,
.levels = vk_info->mipLevels,
.array_len = vk_info->arrayLayers,
.samples = vk_info->samples,
* if Image is uncompressed or compressed, respectively.
*/
static struct VkExtent3D
-meta_region_extent_el(const VkFormat format,
+meta_region_extent_el(const struct anv_image *image,
const struct VkExtent3D *extent)
{
const struct isl_format_layout *isl_layout =
- anv_format_for_vk_format(format)->isl_layout;
- return (VkExtent3D) {
+ anv_format_for_vk_format(image->vk_format)->isl_layout;
+ return anv_sanitize_image_extent(image->type, (VkExtent3D) {
.width = DIV_ROUND_UP(extent->width , isl_layout->bw),
.height = DIV_ROUND_UP(extent->height, isl_layout->bh),
.depth = DIV_ROUND_UP(extent->depth , isl_layout->bd),
- };
+ });
}
/* Returns the user-provided VkBufferImageCopy::imageOffset in units of
const struct VkOffset3D *offset)
{
const struct isl_format_layout *isl_layout = image->format->isl_layout;
- return (VkOffset3D) {
+ return anv_sanitize_image_offset(image->type, (VkOffset3D) {
.x = offset->x / isl_layout->bw,
.y = offset->y / isl_layout->bh,
.z = offset->z / isl_layout->bd,
- };
+ });
}
static struct anv_meta_blit2d_surf
for (unsigned r = 0; r < regionCount; r++) {
- /* Start creating blit rect */
+ /**
+ * From the Vulkan 1.0.6 spec: 18.3 Copying Data Between Images
+ * extent is the size in texels of the source image to copy in width,
+ * height and depth. 1D images use only x and width. 2D images use x, y,
+ * width and height. 3D images use x, y, z, width, height and depth.
+ *
+ *
+ * Also, convert the offsets and extent from units of texels to units of
+ * blocks - which is the highest resolution accessible in this command.
+ */
const VkOffset3D img_offset_el =
meta_region_offset_el(image, &pRegions[r].imageOffset);
const VkExtent3D bufferExtent = {
.width = pRegions[r].bufferRowLength,
.height = pRegions[r].bufferImageHeight,
};
+
+ /* Start creating blit rect */
const VkExtent3D buf_extent_el =
- meta_region_extent_el(image->vk_format, &bufferExtent);
+ meta_region_extent_el(image, &bufferExtent);
const VkExtent3D img_extent_el =
- meta_region_extent_el(image->vk_format, &pRegions[r].imageExtent);
+ meta_region_extent_el(image, &pRegions[r].imageExtent);
struct anv_meta_blit2d_rect rect = {
.width = MAX2(buf_extent_el.width, img_extent_el.width),
.height = MAX2(buf_extent_el.height, img_extent_el.height),
uint32_t *y_offset = forward ? &rect.dst_y : &rect.src_y;
/* Loop through each 3D or array slice */
- unsigned num_slices_3d = pRegions[r].imageExtent.depth;
+ unsigned num_slices_3d = img_extent_el.depth;
unsigned num_slices_array = pRegions[r].imageSubresource.layerCount;
unsigned slice_3d = 0;
unsigned slice_array = 0;
pRegions[r].imageSubresource.mipLevel,
pRegions[r].imageSubresource.baseArrayLayer
+ slice_array,
- pRegions[r].imageOffset.z + slice_3d,
+ img_offset_el.z + slice_3d,
x_offset,
y_offset);
*x_offset += img_offset_el.x;
struct anv_meta_blit2d_surf b_dst =
blit_surf_for_image(dest_image, dst_isl_surf);
- /* Start creating blit rect */
+ /**
+ * From the Vulkan 1.0.6 spec: 18.4 Copying Data Between Buffers and Images
+ * imageExtent is the size in texels of the image to copy in width, height
+ * and depth. 1D images use only x and width. 2D images use x, y, width
+ * and height. 3D images use x, y, z, width, height and depth.
+ *
+ * Also, convert the offsets and extent from units of texels to units of
+ * blocks - which is the highest resolution accessible in this command.
+ */
const VkOffset3D dst_offset_el =
meta_region_offset_el(dest_image, &pRegions[r].dstOffset);
const VkOffset3D src_offset_el =
meta_region_offset_el(src_image, &pRegions[r].srcOffset);
const VkExtent3D img_extent_el =
- meta_region_extent_el(src_image->vk_format, &pRegions[r].extent);
+ meta_region_extent_el(src_image, &pRegions[r].extent);
+
+ /* Start creating blit rect */
struct anv_meta_blit2d_rect rect = {
.width = img_extent_el.width,
.height = img_extent_el.height,
};
/* Loop through each 3D or array slice */
- unsigned num_slices_3d = pRegions[r].extent.depth;
+ unsigned num_slices_3d = img_extent_el.depth;
unsigned num_slices_array = pRegions[r].dstSubresource.layerCount;
unsigned slice_3d = 0;
unsigned slice_array = 0;
pRegions[r].dstSubresource.mipLevel,
pRegions[r].dstSubresource.baseArrayLayer
+ slice_array,
- pRegions[r].dstOffset.z + slice_3d,
+ dst_offset_el.z + slice_3d,
&rect.dst_x,
&rect.dst_y);
isl_surf_get_image_offset_el(src_isl_surf,
pRegions[r].srcSubresource.mipLevel,
pRegions[r].srcSubresource.baseArrayLayer
+ slice_array,
- pRegions[r].srcOffset.z + slice_3d,
+ src_offset_el.z + slice_3d,
&rect.src_x,
&rect.src_y);
rect.dst_x += dst_offset_el.x;
anv_meta_get_iview_layer(dest_image, ®ion->dstSubresource,
®ion->dstOffset);
+ /**
+ * From Vulkan 1.0.6 spec: 18.6 Resolving Multisample Images
+ *
+ * extent is the size in texels of the source image to resolve in width,
+ * height and depth. 1D images use only x and width. 2D images use x, y,
+ * width and height. 3D images use x, y, z, width, height and depth.
+ *
+ * srcOffset and dstOffset select the initial x, y, and z offsets in
+ * texels of the sub-regions of the source and destination image data.
+ * extent is the size in texels of the source image to resolve in width,
+ * height and depth. 1D images use only x and width. 2D images use x, y,
+ * width and height. 3D images use x, y, z, width, height and depth.
+ */
+ const struct VkExtent3D extent =
+ anv_sanitize_image_extent(src_image->type, region->extent);
+ const struct VkOffset3D srcOffset =
+ anv_sanitize_image_offset(src_image->type, region->srcOffset);
+ const struct VkOffset3D dstOffset =
+ anv_sanitize_image_offset(dest_image->type, region->dstOffset);
+
+
for (uint32_t layer = 0; layer < region->srcSubresource.layerCount;
++layer) {
.framebuffer = fb_h,
.renderArea = {
.offset = {
- region->dstOffset.x,
- region->dstOffset.y,
+ dstOffset.x,
+ dstOffset.y,
},
.extent = {
- region->extent.width,
- region->extent.height,
+ extent.width,
+ extent.height,
}
},
.clearValueCount = 0,
emit_resolve(cmd_buffer,
&src_iview,
&(VkOffset2D) {
- .x = region->srcOffset.x,
- .y = region->srcOffset.y,
+ .x = srcOffset.x,
+ .y = srcOffset.y,
},
&dest_iview,
&(VkOffset2D) {
- .x = region->dstOffset.x,
- .y = region->dstOffset.y,
+ .x = dstOffset.x,
+ .y = dstOffset.y,
},
&(VkExtent2D) {
- .width = region->extent.width,
- .height = region->extent.height,
+ .width = extent.width,
+ .height = extent.height,
});
ANV_CALL(CmdEndRenderPass)(cmd_buffer_h);