- assert(pRegions[r].srcSubresource.aspectMask ==
- pRegions[r].dstSubresource.aspectMask);
-
- /* Create blit surfaces */
- struct radv_meta_blit2d_surf b_src =
- blit_surf_for_image_level_layer(src_image,
- src_image_layout,
- &pRegions[r].srcSubresource);
-
- struct radv_meta_blit2d_surf b_dst =
- blit_surf_for_image_level_layer(dest_image,
- dest_image_layout,
- &pRegions[r].dstSubresource);
-
- uint32_t dst_queue_mask = radv_image_queue_family_mask(dest_image,
- cmd_buffer->queue_family_index,
- cmd_buffer->queue_family_index);
- bool dst_compressed = radv_layout_dcc_compressed(dest_image, dest_image_layout, dst_queue_mask);
- uint32_t src_queue_mask = radv_image_queue_family_mask(src_image,
- cmd_buffer->queue_family_index,
- cmd_buffer->queue_family_index);
- bool src_compressed = radv_layout_dcc_compressed(src_image, src_image_layout, src_queue_mask);
-
- if (!src_compressed || radv_dcc_formats_compatible(b_src.format, b_dst.format)) {
- b_src.format = b_dst.format;
- } else if (!dst_compressed) {
- b_dst.format = b_src.format;
- } else {
- radv_decompress_dcc(cmd_buffer, dest_image, &(VkImageSubresourceRange) {
- .aspectMask = pRegions[r].dstSubresource.aspectMask,
- .baseMipLevel = pRegions[r].dstSubresource.mipLevel,
- .levelCount = 1,
- .baseArrayLayer = pRegions[r].dstSubresource.baseArrayLayer,
- .layerCount = pRegions[r].dstSubresource.layerCount,
- });
- b_dst.format = b_src.format;
- b_dst.current_layout = VK_IMAGE_LAYOUT_GENERAL;
- }
-
-
- /**
- * 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);
-
- /*
- * From Vulkan 1.0.68, "Copying Data Between Images":
- * "When copying between compressed and uncompressed formats
- * the extent members represent the texel dimensions of the
- * source image and not the destination."
- * However, we must use the destination image type to avoid
- * clamping depth when copying multiple layers of a 2D image to
- * a 3D image.
- */
- const VkExtent3D img_extent_el =
- meta_region_extent_el(src_image, dest_image->type, &pRegions[r].extent);
-
- /* Start creating blit rect */
- struct radv_meta_blit2d_rect rect = {
- .width = img_extent_el.width,
- .height = img_extent_el.height,
- };
-
- if (src_image->type == VK_IMAGE_TYPE_3D)
- b_src.layer = src_offset_el.z;
+ VkImageAspectFlags src_aspects[3] = {VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT, VK_IMAGE_ASPECT_PLANE_2_BIT};
+ VkImageAspectFlags dst_aspects[3] = {VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT, VK_IMAGE_ASPECT_PLANE_2_BIT};
+ unsigned aspect_count = pRegions[r].srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT ? src_image->plane_count : 1;
+ if (pRegions[r].srcSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT)
+ src_aspects[0] = pRegions[r].srcSubresource.aspectMask;
+ if (pRegions[r].dstSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT)
+ dst_aspects[0] = pRegions[r].dstSubresource.aspectMask;
+
+ for (unsigned a = 0; a < aspect_count; ++a) {
+ /* Create blit surfaces */
+ struct radv_meta_blit2d_surf b_src =
+ blit_surf_for_image_level_layer(src_image,
+ src_image_layout,
+ &pRegions[r].srcSubresource,
+ src_aspects[a]);
+
+ struct radv_meta_blit2d_surf b_dst =
+ blit_surf_for_image_level_layer(dest_image,
+ dest_image_layout,
+ &pRegions[r].dstSubresource,
+ dst_aspects[a]);
+
+ uint32_t dst_queue_mask = radv_image_queue_family_mask(dest_image,
+ cmd_buffer->queue_family_index,
+ cmd_buffer->queue_family_index);
+ bool dst_compressed = radv_layout_dcc_compressed(dest_image, dest_image_layout, dst_queue_mask);
+ uint32_t src_queue_mask = radv_image_queue_family_mask(src_image,
+ cmd_buffer->queue_family_index,
+ cmd_buffer->queue_family_index);
+ bool src_compressed = radv_layout_dcc_compressed(src_image, src_image_layout, src_queue_mask);
+
+ if (!src_compressed || radv_dcc_formats_compatible(b_src.format, b_dst.format)) {
+ b_src.format = b_dst.format;
+ } else if (!dst_compressed) {
+ b_dst.format = b_src.format;
+ } else {
+ radv_decompress_dcc(cmd_buffer, dest_image, &(VkImageSubresourceRange) {
+ .aspectMask = dst_aspects[a],
+ .baseMipLevel = pRegions[r].dstSubresource.mipLevel,
+ .levelCount = 1,
+ .baseArrayLayer = pRegions[r].dstSubresource.baseArrayLayer,
+ .layerCount = pRegions[r].dstSubresource.layerCount,
+ });
+ b_dst.format = b_src.format;
+ b_dst.current_layout = VK_IMAGE_LAYOUT_GENERAL;
+ }