diff options
Diffstat (limited to 'src/intel/vulkan')
-rw-r--r-- | src/intel/vulkan/anv_image.c | 24 | ||||
-rw-r--r-- | src/intel/vulkan/anv_meta_copy.c | 53 | ||||
-rw-r--r-- | src/intel/vulkan/anv_meta_resolve.c | 41 | ||||
-rw-r--r-- | src/intel/vulkan/anv_private.h | 33 |
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, ®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) { @@ -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, |