diff --git a/src/vulkan/runtime/vk_image.c b/src/vulkan/runtime/vk_image.c index 42bc307eec4..a16c2ecd169 100644 --- a/src/vulkan/runtime/vk_image.c +++ b/src/vulkan/runtime/vk_image.c @@ -250,6 +250,38 @@ vk_image_expand_aspect_mask(const struct vk_image *image, } } +struct vk_image_buffer_layout +vk_image_buffer_copy_layout(const struct vk_image *image, + const VkBufferImageCopy2KHR* region) +{ + VkExtent3D extent = vk_image_sanitize_extent(image, region->imageExtent); + + const uint32_t row_length = region->bufferRowLength ? + region->bufferRowLength : extent.width; + const uint32_t image_height = region->bufferImageHeight ? + region->bufferImageHeight : extent.height; + + const VkImageAspectFlags aspect = region->imageSubresource.aspectMask; + VkFormat format = vk_format_get_aspect_format(image->format, aspect); + const struct util_format_description *fmt = vk_format_description(format); + + assert(fmt->block.bits % 8 == 0); + const uint32_t element_size_B = fmt->block.bits / 8; + + const uint32_t row_stride_B = + DIV_ROUND_UP(row_length, fmt->block.width) * element_size_B; + const uint64_t image_stride_B = + DIV_ROUND_UP(image_height, fmt->block.height) * (uint64_t)row_stride_B; + + return (struct vk_image_buffer_layout) { + .row_length = row_length, + .image_height = image_height, + .element_size_B = element_size_B, + .row_stride_B = row_stride_B, + .image_stride_B = image_stride_B, + }; +} + static VkComponentSwizzle remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component) { diff --git a/src/vulkan/runtime/vk_image.h b/src/vulkan/runtime/vk_image.h index 95dc3d63803..f1d5a6f7a13 100644 --- a/src/vulkan/runtime/vk_image.h +++ b/src/vulkan/runtime/vk_image.h @@ -157,6 +157,38 @@ vk_image_sanitize_offset(const struct vk_image *image, } } +struct vk_image_buffer_layout { + /** + * VkBufferImageCopy2KHR::bufferRowLength or + * VkBufferImageCopy2KHR::extent::width as needed. + */ + uint32_t row_length; + + /** + * VkBufferImageCopy2KHR::bufferImageHeight or + * VkBufferImageCopy2KHR::extent::height as needed. + */ + uint32_t image_height; + + /** Size of a single element (pixel or compressed block) in bytes */ + uint32_t element_size_B; + + /** Row stride in bytes */ + uint32_t row_stride_B; + + /** Image (or layer) stride in bytes + * + * For 1D or 2D array images, this is the stride in bytes between array + * slices. For 3D images, this is the stride in bytes between fixed-Z + * slices. + */ + uint64_t image_stride_B; +}; + +struct vk_image_buffer_layout +vk_image_buffer_copy_layout(const struct vk_image *image, + const VkBufferImageCopy2KHR* region); + struct vk_image_view { struct vk_object_base base;