radv: Decompress copy destination if formats are incompatible.
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Fri, 29 Dec 2017 00:57:17 +0000 (01:57 +0100)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Fri, 29 Dec 2017 11:21:58 +0000 (12:21 +0100)
If both source and destination are DCC compressed, and their formats
are not compatible, we need to decompress one of them to make
sure we can do reinterpretation (which needs src format == dst format)
.

Reviewed-by: Dave Airlie <airlied@redhat.com>
Tested-by: Dieter Nützel <Dieter@nuetzel-hh.de>
src/amd/vulkan/radv_meta_copy.c

index 29951f2ba44910b782ef04197199185dc440be8b..7f7ef22efc815f7b01f43d80ec657386c1b355f9 100644 (file)
@@ -369,8 +369,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