radv: add support for CmdResolveImage2KHR()
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Tue, 22 Sep 2020 08:40:51 +0000 (10:40 +0200)
committerMarge Bot <eric+marge@anholt.net>
Wed, 23 Sep 2020 07:14:15 +0000 (07:14 +0000)
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6813>

src/amd/vulkan/radv_meta.h
src/amd/vulkan/radv_meta_resolve.c
src/amd/vulkan/radv_meta_resolve_cs.c
src/amd/vulkan/radv_meta_resolve_fs.c

index f799467..aaf569c 100644 (file)
@@ -219,24 +219,21 @@ void radv_meta_resolve_compute_image(struct radv_cmd_buffer *cmd_buffer,
                                     struct radv_image *dest_image,
                                     VkFormat dest_format,
                                     VkImageLayout dest_image_layout,
-                                    uint32_t region_count,
-                                    const VkImageResolve *regions);
+                                    const VkImageResolve2KHR *region);
 
 void radv_meta_resolve_fragment_image(struct radv_cmd_buffer *cmd_buffer,
                                      struct radv_image *src_image,
                                      VkImageLayout src_image_layout,
                                      struct radv_image *dest_image,
                                      VkImageLayout dest_image_layout,
-                                     uint32_t region_count,
-                                     const VkImageResolve *regions);
+                                    const VkImageResolve2KHR *region);
 
 void radv_decompress_resolve_subpass_src(struct radv_cmd_buffer *cmd_buffer);
 
 void radv_decompress_resolve_src(struct radv_cmd_buffer *cmd_buffer,
                                 struct radv_image *src_image,
                                 VkImageLayout src_image_layout,
-                                uint32_t region_count,
-                                const VkImageResolve *regions);
+                                const VkImageResolve2KHR *region);
 
 uint32_t radv_clear_cmask(struct radv_cmd_buffer *cmd_buffer,
                          struct radv_image *image,
index 9d5a306..1318ff1 100644 (file)
@@ -426,7 +426,7 @@ radv_meta_resolve_hardware_image(struct radv_cmd_buffer *cmd_buffer,
                                 VkImageLayout src_image_layout,
                                 struct radv_image *dst_image,
                                 VkImageLayout dst_image_layout,
-                                const VkImageResolve *region)
+                                const VkImageResolve2KHR *region)
 {
        struct radv_device *device = cmd_buffer->device;
        struct radv_meta_saved_state saved_state;
@@ -599,6 +599,47 @@ radv_meta_resolve_hardware_image(struct radv_cmd_buffer *cmd_buffer,
        radv_meta_restore(&saved_state, cmd_buffer);
 }
 
+static void
+resolve_image(struct radv_cmd_buffer *cmd_buffer,
+             struct radv_image *src_image,
+             VkImageLayout src_image_layout,
+             struct radv_image *dst_image,
+             VkImageLayout dst_image_layout,
+             const VkImageResolve2KHR *region,
+             enum radv_resolve_method resolve_method)
+{
+       switch (resolve_method) {
+       case RESOLVE_HW:
+               radv_meta_resolve_hardware_image(cmd_buffer,
+                                                src_image,
+                                                src_image_layout,
+                                                dst_image,
+                                                dst_image_layout,
+                                                region);
+               break;
+       case RESOLVE_FRAGMENT:
+               radv_meta_resolve_fragment_image(cmd_buffer,
+                                                src_image,
+                                                src_image_layout,
+                                                dst_image,
+                                                dst_image_layout,
+                                                region);
+               break;
+       case RESOLVE_COMPUTE:
+               radv_meta_resolve_compute_image(cmd_buffer,
+                                               src_image,
+                                               src_image->vk_format,
+                                               src_image_layout,
+                                               dst_image,
+                                               dst_image->vk_format,
+                                               dst_image_layout,
+                                               region);
+               break;
+       default:
+               assert(!"Invalid resolve method selected");
+       }
+}
+
 void radv_CmdResolveImage(
        VkCommandBuffer                             cmd_buffer_h,
        VkImage                                     src_image_h,
@@ -635,36 +676,59 @@ void radv_CmdResolveImage(
                                        dest_image_layout, false, cmd_buffer,
                                        &resolve_method);
 
-       switch (resolve_method) {
-       case RESOLVE_HW:
-               assert(region_count == 1);
-               radv_meta_resolve_hardware_image(cmd_buffer,
-                                                src_image,
-                                                src_image_layout,
-                                                dest_image,
-                                                dest_image_layout,
-                                                &regions[0]);
-               break;
-       case RESOLVE_FRAGMENT:
-               radv_meta_resolve_fragment_image(cmd_buffer,
-                                                src_image,
-                                                src_image_layout,
-                                                dest_image,
-                                                dest_image_layout,
-                                                region_count, regions);
-               break;
-       case RESOLVE_COMPUTE:
-               radv_meta_resolve_compute_image(cmd_buffer,
-                                               src_image,
-                                               src_image->vk_format,
-                                               src_image_layout,
-                                               dest_image,
-                                               dest_image->vk_format,
-                                               dest_image_layout,
-                                               region_count, regions);
-               break;
-       default:
-               assert(!"Invalid resolve method selected");
+       for (uint32_t r = 0; r < region_count; r++) {
+               VkImageResolve2KHR region = {
+                       .sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR,
+                       .srcSubresource = regions[r].srcSubresource,
+                       .srcOffset      = regions[r].srcOffset,
+                       .dstSubresource = regions[r].dstSubresource,
+                       .dstOffset      = regions[r].dstOffset,
+                       .extent         = regions[r].extent,
+               };
+
+               resolve_image(cmd_buffer, src_image, src_image_layout,
+                             dest_image, dest_image_layout,
+                             &region, resolve_method);
+       }
+}
+
+void radv_CmdResolveImage2KHR(
+       VkCommandBuffer                             commandBuffer,
+       const VkResolveImageInfo2KHR*               pResolveImageInfo)
+{
+       RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+       RADV_FROM_HANDLE(radv_image, src_image, pResolveImageInfo->srcImage);
+       RADV_FROM_HANDLE(radv_image, dst_image, pResolveImageInfo->dstImage);
+       VkImageLayout src_image_layout = pResolveImageInfo->srcImageLayout;
+       VkImageLayout dst_image_layout = pResolveImageInfo->dstImageLayout;
+       enum radv_resolve_method resolve_method = RESOLVE_HW;
+       /* we can use the hw resolve only for single full resolves */
+       if (pResolveImageInfo->regionCount == 1) {
+               if (pResolveImageInfo->pRegions[0].srcOffset.x ||
+                   pResolveImageInfo->pRegions[0].srcOffset.y ||
+                   pResolveImageInfo->pRegions[0].srcOffset.z)
+                       resolve_method = RESOLVE_COMPUTE;
+               if (pResolveImageInfo->pRegions[0].dstOffset.x ||
+                   pResolveImageInfo->pRegions[0].dstOffset.y ||
+                   pResolveImageInfo->pRegions[0].dstOffset.z)
+                       resolve_method = RESOLVE_COMPUTE;
+
+               if (pResolveImageInfo->pRegions[0].extent.width != src_image->info.width ||
+                   pResolveImageInfo->pRegions[0].extent.height != src_image->info.height ||
+                   pResolveImageInfo->pRegions[0].extent.depth != src_image->info.depth)
+                       resolve_method = RESOLVE_COMPUTE;
+       } else
+               resolve_method = RESOLVE_COMPUTE;
+
+       radv_pick_resolve_method_images(cmd_buffer->device, src_image,
+                                       src_image->vk_format, dst_image,
+                                       dst_image_layout, false, cmd_buffer,
+                                       &resolve_method);
+
+       for (uint32_t r = 0; r < pResolveImageInfo->regionCount; r++) {
+               resolve_image(cmd_buffer, src_image, src_image_layout,
+                             dst_image, dst_image_layout,
+                             &pResolveImageInfo->pRegions[r], resolve_method);
        }
 }
 
@@ -839,14 +903,15 @@ radv_decompress_resolve_subpass_src(struct radv_cmd_buffer *cmd_buffer)
                struct radv_image_view *src_iview = cmd_buffer->state.attachments[src_att.attachment].iview;
                struct radv_image *src_image = src_iview->image;
 
-               VkImageResolve region = {};
+               VkImageResolve2KHR region = {};
+               region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR;
                region.srcSubresource.aspectMask = src_iview->aspect_mask;
                region.srcSubresource.mipLevel = 0;
                region.srcSubresource.baseArrayLayer = src_iview->base_layer;
                region.srcSubresource.layerCount = layer_count;
 
                radv_decompress_resolve_src(cmd_buffer, src_image,
-                                           src_att.layout, 1, &region);
+                                           src_att.layout, &region);
        }
 
        if (subpass->ds_resolve_attachment) {
@@ -854,14 +919,15 @@ radv_decompress_resolve_subpass_src(struct radv_cmd_buffer *cmd_buffer)
                struct radv_image_view *src_iview = fb->attachments[src_att.attachment];
                struct radv_image *src_image = src_iview->image;
 
-               VkImageResolve region = {};
+               VkImageResolve2KHR region = {};
+               region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR;
                region.srcSubresource.aspectMask = src_iview->aspect_mask;
                region.srcSubresource.mipLevel = 0;
                region.srcSubresource.baseArrayLayer = src_iview->base_layer;
                region.srcSubresource.layerCount = layer_count;
 
                radv_decompress_resolve_src(cmd_buffer, src_image,
-                                           src_att.layout, 1, &region);
+                                           src_att.layout, &region);
        }
 }
 
@@ -886,48 +952,44 @@ void
 radv_decompress_resolve_src(struct radv_cmd_buffer *cmd_buffer,
                            struct radv_image *src_image,
                            VkImageLayout src_image_layout,
-                           uint32_t region_count,
-                           const VkImageResolve *regions)
+                            const VkImageResolve2KHR *region)
 {
-       for (uint32_t r = 0; r < region_count; ++r) {
-               const VkImageResolve *region = &regions[r];
-               const uint32_t src_base_layer =
-                       radv_meta_get_iview_layer(src_image, &region->srcSubresource,
-                                                 &region->srcOffset);
-
-               VkImageMemoryBarrier barrier = {};
-               barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
-               barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
-               barrier.oldLayout = src_image_layout;
-               barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
-               barrier.image = radv_image_to_handle(src_image);
-               barrier.subresourceRange = (VkImageSubresourceRange) {
-                       .aspectMask = region->srcSubresource.aspectMask,
-                       .baseMipLevel = region->srcSubresource.mipLevel,
-                       .levelCount = 1,
-                       .baseArrayLayer = src_base_layer,
-                       .layerCount = region->srcSubresource.layerCount,
-               };
+       const uint32_t src_base_layer =
+               radv_meta_get_iview_layer(src_image, &region->srcSubresource,
+                                         &region->srcOffset);
 
-               if (src_image->flags & VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT) {
-                       /* If the depth/stencil image uses different sample
-                        * locations, we need them during HTILE decompressions.
-                        */
-                       struct radv_sample_locations_state *sample_locs =
-                               radv_get_resolve_sample_locations(cmd_buffer);
-
-                       barrier.pNext = &(VkSampleLocationsInfoEXT) {
-                               .sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT,
-                               .sampleLocationsPerPixel = sample_locs->per_pixel,
-                               .sampleLocationGridSize = sample_locs->grid_size,
-                               .sampleLocationsCount = sample_locs->count,
-                               .pSampleLocations = sample_locs->locations,
-                       };
-               }
+       VkImageMemoryBarrier barrier = {};
+       barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+       barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+       barrier.oldLayout = src_image_layout;
+       barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+       barrier.image = radv_image_to_handle(src_image);
+       barrier.subresourceRange = (VkImageSubresourceRange) {
+               .aspectMask = region->srcSubresource.aspectMask,
+               .baseMipLevel = region->srcSubresource.mipLevel,
+               .levelCount = 1,
+               .baseArrayLayer = src_base_layer,
+               .layerCount = region->srcSubresource.layerCount,
+       };
 
-               radv_CmdPipelineBarrier(radv_cmd_buffer_to_handle(cmd_buffer),
-                                       VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
-                                       VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
-                                       false, 0, NULL, 0, NULL, 1, &barrier);
+       if (src_image->flags & VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT) {
+               /* If the depth/stencil image uses different sample
+                * locations, we need them during HTILE decompressions.
+                */
+               struct radv_sample_locations_state *sample_locs =
+                       radv_get_resolve_sample_locations(cmd_buffer);
+
+               barrier.pNext = &(VkSampleLocationsInfoEXT) {
+                       .sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT,
+                       .sampleLocationsPerPixel = sample_locs->per_pixel,
+                       .sampleLocationGridSize = sample_locs->grid_size,
+                       .sampleLocationsCount = sample_locs->count,
+                       .pSampleLocations = sample_locs->locations,
+               };
        }
+
+       radv_CmdPipelineBarrier(radv_cmd_buffer_to_handle(cmd_buffer),
+                               VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                               VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+                               false, 0, NULL, 0, NULL, 1, &barrier);
 }
index e1e3077..a5b5c32 100644 (file)
@@ -811,84 +811,80 @@ void radv_meta_resolve_compute_image(struct radv_cmd_buffer *cmd_buffer,
                                     struct radv_image *dest_image,
                                     VkFormat dest_format,
                                     VkImageLayout dest_image_layout,
-                                    uint32_t region_count,
-                                    const VkImageResolve *regions)
+                                    const VkImageResolve2KHR *region)
 {
        struct radv_meta_saved_state saved_state;
 
        radv_decompress_resolve_src(cmd_buffer, src_image, src_image_layout,
-                                   region_count, regions);
+                                   region);
 
        radv_meta_save(&saved_state, cmd_buffer,
                       RADV_META_SAVE_COMPUTE_PIPELINE |
                       RADV_META_SAVE_CONSTANTS |
                       RADV_META_SAVE_DESCRIPTORS);
 
-       for (uint32_t r = 0; r < region_count; ++r) {
-               const VkImageResolve *region = &regions[r];
-
-               assert(region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
-               assert(region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
-               assert(region->srcSubresource.layerCount == region->dstSubresource.layerCount);
-
-               const uint32_t src_base_layer =
-                       radv_meta_get_iview_layer(src_image, &region->srcSubresource,
-                                                 &region->srcOffset);
-
-               const uint32_t dest_base_layer =
-                       radv_meta_get_iview_layer(dest_image, &region->dstSubresource,
-                                                 &region->dstOffset);
-
-               const struct VkExtent3D extent =
-                       radv_sanitize_image_extent(src_image->type, region->extent);
-               const struct VkOffset3D srcOffset =
-                       radv_sanitize_image_offset(src_image->type, region->srcOffset);
-               const struct VkOffset3D dstOffset =
-                       radv_sanitize_image_offset(dest_image->type, region->dstOffset);
-
-               for (uint32_t layer = 0; layer < region->srcSubresource.layerCount;
-                    ++layer) {
-
-                       struct radv_image_view src_iview;
-                       radv_image_view_init(&src_iview, cmd_buffer->device,
-                                            &(VkImageViewCreateInfo) {
-                                                    .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-                                                            .image = radv_image_to_handle(src_image),
-                                                            .viewType = radv_meta_get_view_type(src_image),
-                                                            .format = src_format,
-                                                            .subresourceRange = {
-                                                            .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
-                                                            .baseMipLevel = region->srcSubresource.mipLevel,
-                                                            .levelCount = 1,
-                                                            .baseArrayLayer = src_base_layer + layer,
-                                                            .layerCount = 1,
-                                                    },
-                                            }, NULL);
-
-                       struct radv_image_view dest_iview;
-                       radv_image_view_init(&dest_iview, cmd_buffer->device,
-                                            &(VkImageViewCreateInfo) {
-                                                    .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-                                                            .image = radv_image_to_handle(dest_image),
-                                                            .viewType = radv_meta_get_view_type(dest_image),
-                                                            .format = vk_to_non_srgb_format(dest_format),
-                                                            .subresourceRange = {
-                                                            .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
-                                                            .baseMipLevel = region->dstSubresource.mipLevel,
-                                                            .levelCount = 1,
-                                                            .baseArrayLayer = dest_base_layer + layer,
-                                                            .layerCount = 1,
-                                                    },
-                                            }, NULL);
-
-                       emit_resolve(cmd_buffer,
-                                    &src_iview,
-                                    &dest_iview,
-                                    &(VkOffset2D) {srcOffset.x, srcOffset.y },
-                                    &(VkOffset2D) {dstOffset.x, dstOffset.y },
-                                    &(VkExtent2D) {extent.width, extent.height });
-               }
+       assert(region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
+       assert(region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
+       assert(region->srcSubresource.layerCount == region->dstSubresource.layerCount);
+
+       const uint32_t src_base_layer =
+               radv_meta_get_iview_layer(src_image, &region->srcSubresource,
+                                         &region->srcOffset);
+
+       const uint32_t dest_base_layer =
+               radv_meta_get_iview_layer(dest_image, &region->dstSubresource,
+                                         &region->dstOffset);
+
+       const struct VkExtent3D extent =
+               radv_sanitize_image_extent(src_image->type, region->extent);
+       const struct VkOffset3D srcOffset =
+               radv_sanitize_image_offset(src_image->type, region->srcOffset);
+       const struct VkOffset3D dstOffset =
+               radv_sanitize_image_offset(dest_image->type, region->dstOffset);
+
+       for (uint32_t layer = 0; layer < region->srcSubresource.layerCount;
+            ++layer) {
+
+               struct radv_image_view src_iview;
+               radv_image_view_init(&src_iview, cmd_buffer->device,
+                                    &(VkImageViewCreateInfo) {
+                                            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+                                                    .image = radv_image_to_handle(src_image),
+                                                    .viewType = radv_meta_get_view_type(src_image),
+                                                    .format = src_format,
+                                                    .subresourceRange = {
+                                                    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+                                                    .baseMipLevel = region->srcSubresource.mipLevel,
+                                                    .levelCount = 1,
+                                                    .baseArrayLayer = src_base_layer + layer,
+                                                    .layerCount = 1,
+                                            },
+                                    }, NULL);
+
+               struct radv_image_view dest_iview;
+               radv_image_view_init(&dest_iview, cmd_buffer->device,
+                                    &(VkImageViewCreateInfo) {
+                                            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+                                                    .image = radv_image_to_handle(dest_image),
+                                                    .viewType = radv_meta_get_view_type(dest_image),
+                                                    .format = vk_to_non_srgb_format(dest_format),
+                                                    .subresourceRange = {
+                                                    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+                                                    .baseMipLevel = region->dstSubresource.mipLevel,
+                                                    .levelCount = 1,
+                                                    .baseArrayLayer = dest_base_layer + layer,
+                                                    .layerCount = 1,
+                                            },
+                                    }, NULL);
+
+               emit_resolve(cmd_buffer,
+                            &src_iview,
+                            &dest_iview,
+                            &(VkOffset2D) {srcOffset.x, srcOffset.y },
+                            &(VkOffset2D) {dstOffset.x, dstOffset.y },
+                            &(VkExtent2D) {extent.width, extent.height });
        }
+
        radv_meta_restore(&saved_state, cmd_buffer);
 }
 
@@ -924,7 +920,8 @@ radv_cmd_buffer_resolve_subpass_cs(struct radv_cmd_buffer *cmd_buffer)
                struct radv_image_view *src_iview = cmd_buffer->state.attachments[src_att.attachment].iview;
                struct radv_image_view *dst_iview = cmd_buffer->state.attachments[dst_att.attachment].iview;
 
-               VkImageResolve region = {
+               VkImageResolve2KHR region = {
+                       .sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR,
                        .extent = (VkExtent3D){ fb->width, fb->height, 0 },
                        .srcSubresource = (VkImageSubresourceLayers) {
                                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
@@ -949,7 +946,7 @@ radv_cmd_buffer_resolve_subpass_cs(struct radv_cmd_buffer *cmd_buffer)
                                                dst_iview->image,
                                                dst_iview->vk_format,
                                                dst_att.layout,
-                                               1, &region);
+                                               &region);
        }
 
        cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH |
index 12ff91a..c60d5eb 100644 (file)
@@ -1027,8 +1027,7 @@ void radv_meta_resolve_fragment_image(struct radv_cmd_buffer *cmd_buffer,
                                      VkImageLayout src_image_layout,
                                      struct radv_image *dest_image,
                                      VkImageLayout dest_image_layout,
-                                     uint32_t region_count,
-                                     const VkImageResolve *regions)
+                                     const VkImageResolve2KHR *region)
 {
        struct radv_device *device = cmd_buffer->device;
        struct radv_meta_saved_state saved_state;
@@ -1039,7 +1038,7 @@ void radv_meta_resolve_fragment_image(struct radv_cmd_buffer *cmd_buffer,
        VkRenderPass rp;
 
        radv_decompress_resolve_src(cmd_buffer, src_image, src_image_layout,
-                                   region_count, regions);
+                                   region);
 
        if (!device->meta_state.resolve_fragment.rc[samples_log2].render_pass[fs_key][dst_layout]) {
                VkResult ret = create_resolve_pipeline(device, samples_log2, radv_fs_key_format_exemplars[fs_key]);
@@ -1056,104 +1055,100 @@ void radv_meta_resolve_fragment_image(struct radv_cmd_buffer *cmd_buffer,
                       RADV_META_SAVE_CONSTANTS |
                       RADV_META_SAVE_DESCRIPTORS);
 
-       for (uint32_t r = 0; r < region_count; ++r) {
-               const VkImageResolve *region = &regions[r];
-
-               assert(region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
-               assert(region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
-               assert(region->srcSubresource.layerCount == region->dstSubresource.layerCount);
-
-               const uint32_t src_base_layer =
-                       radv_meta_get_iview_layer(src_image, &region->srcSubresource,
-                                                 &region->srcOffset);
-
-               const uint32_t dest_base_layer =
-                       radv_meta_get_iview_layer(dest_image, &region->dstSubresource,
-                                                 &region->dstOffset);
-
-               const struct VkExtent3D extent =
-                       radv_sanitize_image_extent(src_image->type, region->extent);
-               const struct VkOffset3D srcOffset =
-                       radv_sanitize_image_offset(src_image->type, region->srcOffset);
-               const struct VkOffset3D dstOffset =
-                       radv_sanitize_image_offset(dest_image->type, region->dstOffset);
-
-               for (uint32_t layer = 0; layer < region->srcSubresource.layerCount;
-                    ++layer) {
-
-                       struct radv_image_view src_iview;
-                       radv_image_view_init(&src_iview, cmd_buffer->device,
-                                            &(VkImageViewCreateInfo) {
-                                                    .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-                                                            .image = radv_image_to_handle(src_image),
-                                                            .viewType = radv_meta_get_view_type(src_image),
-                                                            .format = src_image->vk_format,
-                                                            .subresourceRange = {
-                                                            .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
-                                                            .baseMipLevel = region->srcSubresource.mipLevel,
-                                                            .levelCount = 1,
-                                                            .baseArrayLayer = src_base_layer + layer,
-                                                            .layerCount = 1,
-                                                    },
-                                            }, NULL);
-
-                       struct radv_image_view dest_iview;
-                       radv_image_view_init(&dest_iview, cmd_buffer->device,
-                                            &(VkImageViewCreateInfo) {
-                                                    .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-                                                            .image = radv_image_to_handle(dest_image),
-                                                            .viewType = radv_meta_get_view_type(dest_image),
-                                                            .format = dest_image->vk_format,
-                                                            .subresourceRange = {
-                                                            .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
-                                                            .baseMipLevel = region->dstSubresource.mipLevel,
-                                                            .levelCount = 1,
-                                                            .baseArrayLayer = dest_base_layer + layer,
-                                                            .layerCount = 1,
-                                                    },
-                                            }, NULL);
-
-
-                       VkFramebuffer fb;
-                       radv_CreateFramebuffer(radv_device_to_handle(cmd_buffer->device),
-                              &(VkFramebufferCreateInfo) {
-                                      .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
-                                              .attachmentCount = 1,
-                                              .pAttachments = (VkImageView[]) {
-                                              radv_image_view_to_handle(&dest_iview),
-                                      },
-                                      .width = extent.width + dstOffset.x,
-                                      .height = extent.height + dstOffset.y,
-                                      .layers = 1
-                               }, &cmd_buffer->pool->alloc, &fb);
-
-                       radv_cmd_buffer_begin_render_pass(cmd_buffer,
-                                                         &(VkRenderPassBeginInfo) {
-                                                               .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
-                                                                       .renderPass = rp,
-                                                                       .framebuffer = fb,
-                                                                       .renderArea = {
-                                                                               .offset = { dstOffset.x, dstOffset.y, },
-                                                                               .extent = { extent.width, extent.height },
-                                                                       },
-                                                               .clearValueCount = 0,
-                                                               .pClearValues = NULL,
-                                               });
-
-                       radv_cmd_buffer_set_subpass(cmd_buffer,
-                                                   &cmd_buffer->state.pass->subpasses[0]);
-
-                       emit_resolve(cmd_buffer,
-                                    &src_iview,
-                                    &dest_iview,
-                                    &(VkOffset2D) { srcOffset.x, srcOffset.y },
-                                    &(VkOffset2D) { dstOffset.x, dstOffset.y },
-                                    &(VkExtent2D) { extent.width, extent.height });
-
-                       radv_cmd_buffer_end_render_pass(cmd_buffer);
-
-                       radv_DestroyFramebuffer(radv_device_to_handle(cmd_buffer->device), fb, &cmd_buffer->pool->alloc);
-               }
+       assert(region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
+       assert(region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
+       assert(region->srcSubresource.layerCount == region->dstSubresource.layerCount);
+
+       const uint32_t src_base_layer =
+               radv_meta_get_iview_layer(src_image, &region->srcSubresource,
+                                         &region->srcOffset);
+
+       const uint32_t dest_base_layer =
+               radv_meta_get_iview_layer(dest_image, &region->dstSubresource,
+                                         &region->dstOffset);
+
+       const struct VkExtent3D extent =
+               radv_sanitize_image_extent(src_image->type, region->extent);
+       const struct VkOffset3D srcOffset =
+               radv_sanitize_image_offset(src_image->type, region->srcOffset);
+       const struct VkOffset3D dstOffset =
+               radv_sanitize_image_offset(dest_image->type, region->dstOffset);
+
+       for (uint32_t layer = 0; layer < region->srcSubresource.layerCount;
+            ++layer) {
+
+               struct radv_image_view src_iview;
+               radv_image_view_init(&src_iview, cmd_buffer->device,
+                                    &(VkImageViewCreateInfo) {
+                                            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+                                                    .image = radv_image_to_handle(src_image),
+                                                    .viewType = radv_meta_get_view_type(src_image),
+                                                    .format = src_image->vk_format,
+                                                    .subresourceRange = {
+                                                    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+                                                    .baseMipLevel = region->srcSubresource.mipLevel,
+                                                    .levelCount = 1,
+                                                    .baseArrayLayer = src_base_layer + layer,
+                                                    .layerCount = 1,
+                                            },
+                                    }, NULL);
+
+               struct radv_image_view dest_iview;
+               radv_image_view_init(&dest_iview, cmd_buffer->device,
+                                    &(VkImageViewCreateInfo) {
+                                            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+                                                    .image = radv_image_to_handle(dest_image),
+                                                    .viewType = radv_meta_get_view_type(dest_image),
+                                                    .format = dest_image->vk_format,
+                                                    .subresourceRange = {
+                                                    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+                                                    .baseMipLevel = region->dstSubresource.mipLevel,
+                                                    .levelCount = 1,
+                                                    .baseArrayLayer = dest_base_layer + layer,
+                                                    .layerCount = 1,
+                                            },
+                                    }, NULL);
+
+
+               VkFramebuffer fb;
+               radv_CreateFramebuffer(radv_device_to_handle(cmd_buffer->device),
+                      &(VkFramebufferCreateInfo) {
+                              .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+                                      .attachmentCount = 1,
+                                      .pAttachments = (VkImageView[]) {
+                                      radv_image_view_to_handle(&dest_iview),
+                              },
+                              .width = extent.width + dstOffset.x,
+                              .height = extent.height + dstOffset.y,
+                              .layers = 1
+                       }, &cmd_buffer->pool->alloc, &fb);
+
+               radv_cmd_buffer_begin_render_pass(cmd_buffer,
+                                                 &(VkRenderPassBeginInfo) {
+                                                       .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+                                                               .renderPass = rp,
+                                                               .framebuffer = fb,
+                                                               .renderArea = {
+                                                                       .offset = { dstOffset.x, dstOffset.y, },
+                                                                       .extent = { extent.width, extent.height },
+                                                               },
+                                                       .clearValueCount = 0,
+                                                       .pClearValues = NULL,
+                                       });
+
+               radv_cmd_buffer_set_subpass(cmd_buffer,
+                                           &cmd_buffer->state.pass->subpasses[0]);
+
+               emit_resolve(cmd_buffer,
+                            &src_iview,
+                            &dest_iview,
+                            &(VkOffset2D) { srcOffset.x, srcOffset.y },
+                            &(VkOffset2D) { dstOffset.x, dstOffset.y },
+                            &(VkExtent2D) { extent.width, extent.height });
+
+               radv_cmd_buffer_end_render_pass(cmd_buffer);
+
+               radv_DestroyFramebuffer(radv_device_to_handle(cmd_buffer->device), fb, &cmd_buffer->pool->alloc);
        }
 
        radv_meta_restore(&saved_state, cmd_buffer);