summaryrefslogtreecommitdiffstats
path: root/src/intel
diff options
context:
space:
mode:
Diffstat (limited to 'src/intel')
-rw-r--r--src/intel/vulkan/anv_image.c24
-rw-r--r--src/intel/vulkan/anv_meta_copy.c53
-rw-r--r--src/intel/vulkan/anv_meta_resolve.c41
-rw-r--r--src/intel/vulkan/anv_private.h33
4 files changed, 106 insertions, 45 deletions
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index 143a08413f7..b47425bd0e1 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -124,30 +124,16 @@ make_surface(const struct anv_device *dev,
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,
diff --git a/src/intel/vulkan/anv_meta_copy.c b/src/intel/vulkan/anv_meta_copy.c
index 1a2bfd6cf01..982fa7e10c1 100644
--- a/src/intel/vulkan/anv_meta_copy.c
+++ b/src/intel/vulkan/anv_meta_copy.c
@@ -28,16 +28,16 @@
* 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
@@ -49,11 +49,11 @@ meta_region_offset_el(const struct anv_image *image,
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
@@ -115,17 +115,28 @@ meta_copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,
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),
@@ -152,7 +163,7 @@ meta_copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,
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;
@@ -163,7 +174,7 @@ meta_copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,
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;
@@ -259,20 +270,30 @@ void anv_CmdCopyImage(
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;
@@ -283,14 +304,14 @@ void anv_CmdCopyImage(
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;
diff --git a/src/intel/vulkan/anv_meta_resolve.c b/src/intel/vulkan/anv_meta_resolve.c
index 19fb3ad3003..f50af52ece5 100644
--- a/src/intel/vulkan/anv_meta_resolve.c
+++ b/src/intel/vulkan/anv_meta_resolve.c
@@ -719,6 +719,27 @@ void anv_CmdResolveImage(
anv_meta_get_iview_layer(dest_image, &region->dstSubresource,
&region->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) {
@@ -780,12 +801,12 @@ void anv_CmdResolveImage(
.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,
@@ -796,17 +817,17 @@ void anv_CmdResolveImage(
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);
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 03e87670165..94a13d7d331 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1670,6 +1670,39 @@ struct anv_buffer_view {
const struct anv_format *
anv_format_for_descriptor_type(VkDescriptorType type);
+static inline struct VkExtent3D
+anv_sanitize_image_extent(const VkImageType imageType,
+ const struct VkExtent3D imageExtent)
+{
+ switch (imageType) {
+ case VK_IMAGE_TYPE_1D:
+ return (VkExtent3D) { imageExtent.width, 1, 1 };
+ case VK_IMAGE_TYPE_2D:
+ return (VkExtent3D) { imageExtent.width, imageExtent.height, 1 };
+ case VK_IMAGE_TYPE_3D:
+ return imageExtent;
+ default:
+ unreachable("invalid image type");
+ }
+}
+
+static inline struct VkOffset3D
+anv_sanitize_image_offset(const VkImageType imageType,
+ const struct VkOffset3D imageOffset)
+{
+ switch (imageType) {
+ case VK_IMAGE_TYPE_1D:
+ return (VkOffset3D) { imageOffset.x, 0, 0 };
+ case VK_IMAGE_TYPE_2D:
+ return (VkOffset3D) { imageOffset.x, imageOffset.y, 0 };
+ case VK_IMAGE_TYPE_3D:
+ return imageOffset;
+ default:
+ unreachable("invalid image type");
+ }
+}
+
+
void anv_fill_buffer_surface_state(struct anv_device *device,
struct anv_state state,
enum isl_format format,