From 3f01bbe7f3e2639ca176c7873ea5e16ba16e4042 Mon Sep 17 00:00:00 2001 From: Nanley Chery Date: Mon, 4 Jan 2016 12:41:22 -0800 Subject: [PATCH] anv/image: Scale iview extent by backing image Aligns with formula's presented in Vulkan spec concerning CopyBufferToImage. 18.4 Copying Data Between Buffers and Images This won't conflict with valid API usage, because: 1) Users are not allowed to create an uncompressed ImageView with a compressed Image. see: VkSpec - 11.5 Image Views - VkImageViewCreateInfo's Valid Usage box 2) If users create a differently formatted compressed ImageView with a compressed Image, the block dimensions will still match. see: VkSpec - 28.3.1.5 Format Compatibility Classes - Table 28.5 --- src/vulkan/anv_image.c | 24 +++++++++++++++++++++--- src/vulkan/anv_private.h | 1 + 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/vulkan/anv_image.c b/src/vulkan/anv_image.c index 1af316b4936..8b2003587ac 100644 --- a/src/vulkan/anv_image.c +++ b/src/vulkan/anv_image.c @@ -532,10 +532,28 @@ anv_image_view_init(struct anv_image_view *iview, iview->base_layer = range->baseArrayLayer; iview->base_mip = range->baseMipLevel; + + if (!isl_format_is_compressed(iview->format) && + isl_format_is_compressed(image->format->surface_format)) { + /* Scale the ImageView extent by the backing Image. This is used + * internally when an uncompressed ImageView is created on a + * compressed Image. The ImageView can therefore be used for copying + * data from a source Image to a destination Image. + */ + const struct isl_format_layout * isl_layout = image->format->isl_layout; + iview->level_0_extent.width = DIV_ROUND_UP(image->extent.width , isl_layout->bw); + iview->level_0_extent.height = DIV_ROUND_UP(image->extent.height, isl_layout->bh); + iview->level_0_extent.depth = DIV_ROUND_UP(image->extent.depth , isl_layout->bd); + } else { + iview->level_0_extent.width = image->extent.width ; + iview->level_0_extent.height = image->extent.height; + iview->level_0_extent.depth = image->extent.depth ; + } + iview->extent = (VkExtent3D) { - .width = anv_minify(image->extent.width, range->baseMipLevel), - .height = anv_minify(image->extent.height, range->baseMipLevel), - .depth = anv_minify(image->extent.depth, range->baseMipLevel), + .width = anv_minify(iview->level_0_extent.width , range->baseMipLevel), + .height = anv_minify(iview->level_0_extent.height, range->baseMipLevel), + .depth = anv_minify(iview->level_0_extent.depth , range->baseMipLevel), }; if (image->needs_nonrt_surface_state) { diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h index 1ae7066f5fd..79af4102e3f 100644 --- a/src/vulkan/anv_private.h +++ b/src/vulkan/anv_private.h @@ -1578,6 +1578,7 @@ struct anv_image_view { enum isl_format format; uint32_t base_layer; uint32_t base_mip; + VkExtent3D level_0_extent; /**< Extent of ::image's level 0 adjusted for ::vk_format. */ VkExtent3D extent; /**< Extent of VkImageViewCreateInfo::baseMipLevel. */ /** RENDER_SURFACE_STATE when using image as a color render target. */ -- 2.30.2