anv,radv: Drop XML workarounds for VK_ANDROID_native_buffer
[mesa.git] / src / amd / vulkan / radv_meta_copy.c
index de784d53050b15d7085e3e289a64b139300dca88..2055289a9bb1e310b6743e97a68acd8f1dd9d8ad 100644 (file)
@@ -37,10 +37,11 @@ meta_image_block_size(const struct radv_image *image)
  */
 static struct VkExtent3D
 meta_region_extent_el(const struct radv_image *image,
+                      const VkImageType imageType,
                       const struct VkExtent3D *extent)
 {
        const VkExtent3D block = meta_image_block_size(image);
-       return radv_sanitize_image_extent(image->type, (VkExtent3D) {
+       return radv_sanitize_image_extent(imageType, (VkExtent3D) {
                        .width  = DIV_ROUND_UP(extent->width , block.width),
                                .height = DIV_ROUND_UP(extent->height, block.height),
                                .depth  = DIV_ROUND_UP(extent->depth , block.depth),
@@ -88,7 +89,8 @@ blit_surf_for_image_level_layer(struct radv_image *image,
        else if (subres->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
                format = vk_format_stencil_only(format);
 
-       if (!image->surface.dcc_size)
+       if (!radv_image_has_dcc(image) &&
+           !(radv_image_is_tc_compat_htile(image)))
                format = vk_format_for_size(vk_format_get_blocksize(format));
 
        return (struct radv_meta_blit2d_surf) {
@@ -145,11 +147,11 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer,
                        pRegions[r].bufferImageHeight : pRegions[r].imageExtent.height,
                };
                const VkExtent3D buf_extent_el =
-                       meta_region_extent_el(image, &bufferExtent);
+                       meta_region_extent_el(image, image->type, &bufferExtent);
 
                /* Start creating blit rect */
                const VkExtent3D img_extent_el =
-                       meta_region_extent_el(image, &pRegions[r].imageExtent);
+                       meta_region_extent_el(image, image->type, &pRegions[r].imageExtent);
                struct radv_meta_blit2d_rect rect = {
                        .width = img_extent_el.width,
                        .height =  img_extent_el.height,
@@ -258,11 +260,11 @@ meta_copy_image_to_buffer(struct radv_cmd_buffer *cmd_buffer,
                        pRegions[r].bufferImageHeight : pRegions[r].imageExtent.height,
                };
                const VkExtent3D buf_extent_el =
-                       meta_region_extent_el(image, &bufferExtent);
+                       meta_region_extent_el(image, image->type, &bufferExtent);
 
                /* Start creating blit rect */
                const VkExtent3D img_extent_el =
-                       meta_region_extent_el(image, &pRegions[r].imageExtent);
+                       meta_region_extent_el(image, image->type, &pRegions[r].imageExtent);
                struct radv_meta_blit2d_rect rect = {
                        .width = img_extent_el.width,
                        .height =  img_extent_el.height,
@@ -368,8 +370,31 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer,
                                                        dest_image_layout,
                                                        &pRegions[r].dstSubresource);
 
-               /* for DCC */
-               b_src.format = b_dst.format;
+               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
@@ -384,8 +409,18 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer,
                        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(dest_image, &pRegions[r].extent);
+                       meta_region_extent_el(src_image, dest_image->type, &pRegions[r].extent);
 
                /* Start creating blit rect */
                struct radv_meta_blit2d_rect rect = {
@@ -393,6 +428,9 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer,
                        .height = img_extent_el.height,
                };
 
+               if (src_image->type == VK_IMAGE_TYPE_3D)
+                       b_src.layer = src_offset_el.z;
+
                if (dest_image->type == VK_IMAGE_TYPE_3D)
                        b_dst.layer = dst_offset_el.z;