anv/image: Scale iview extent by backing image
authorNanley Chery <nanley.g.chery@intel.com>
Mon, 4 Jan 2016 20:41:22 +0000 (12:41 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Wed, 27 Jan 2016 23:12:42 +0000 (15:12 -0800)
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
src/vulkan/anv_private.h

index 1af316b49360e2fe977e020db13d19f2784c9b01..8b2003587ac7873e7d1e35e9ac1ca6df4e5eaa2e 100644 (file)
@@ -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) {
index 1ae7066f5fddd1e5acf726df3a6201b5b7980ba1..79af4102e3f8b696030049ab1410a9a3027aa3cf 100644 (file)
@@ -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. */