radv/gfx10: Use correct ES shader for es_vgpr_comp_cnt for GS.
[mesa.git] / src / amd / vulkan / radv_meta_copy.c
index a4d359826617a723a833a6d55723fb9dc757ce21..78a23851281ebb44393d3fc30b5ee0796c34498d 100644 (file)
@@ -82,15 +82,12 @@ vk_format_for_size(int bs)
 static struct radv_meta_blit2d_surf
 blit_surf_for_image_level_layer(struct radv_image *image,
                                VkImageLayout layout,
-                               const VkImageSubresourceLayers *subres)
+                               const VkImageSubresourceLayers *subres,
+                               VkImageAspectFlags aspect_mask)
 {
-       VkFormat format = image->vk_format;
-       if (subres->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
-               format = vk_format_depth_only(format);
-       else if (subres->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
-               format = vk_format_stencil_only(format);
+       VkFormat format = radv_get_aspect_format(image, aspect_mask);
 
-       if (!radv_image_has_dcc(image) &&
+       if (!radv_dcc_enabled(image, subres->mipLevel) &&
            !(radv_image_is_tc_compat_htile(image)))
                format = vk_format_for_size(vk_format_get_blocksize(format));
 
@@ -102,11 +99,27 @@ blit_surf_for_image_level_layer(struct radv_image *image,
                .level = subres->mipLevel,
                .layer = subres->baseArrayLayer,
                .image = image,
-               .aspect_mask = subres->aspectMask,
+               .aspect_mask = aspect_mask,
                .current_layout = layout,
        };
 }
 
+static bool
+image_is_renderable(struct radv_device *device, struct radv_image *image)
+{
+       if (image->vk_format == VK_FORMAT_R32G32B32_UINT ||
+           image->vk_format == VK_FORMAT_R32G32B32_SINT ||
+           image->vk_format == VK_FORMAT_R32G32B32_SFLOAT)
+               return false;
+
+       if (device->physical_device->rad_info.chip_class >= GFX9 &&
+           image->type == VK_IMAGE_TYPE_3D &&
+           vk_format_get_blocksizebits(image->vk_format) == 128 &&
+           vk_format_is_compressed(image->vk_format))
+               return false;
+       return true;
+}
+
 static void
 meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer,
                           struct radv_buffer* buffer,
@@ -117,6 +130,7 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer,
 {
        bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE;
        struct radv_meta_saved_state saved_state;
+       bool old_predicating;
 
        /* The Vulkan 1.0 spec says "dstImage must have a sample count equal to
         * VK_SAMPLE_COUNT_1_BIT."
@@ -129,6 +143,12 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer,
                       RADV_META_SAVE_CONSTANTS |
                       RADV_META_SAVE_DESCRIPTORS);
 
+       /* VK_EXT_conditional_rendering says that copy commands should not be
+        * affected by conditional rendering.
+        */
+       old_predicating = cmd_buffer->state.predicating;
+       cmd_buffer->state.predicating = false;
+
        for (unsigned r = 0; r < regionCount; r++) {
 
                /**
@@ -164,7 +184,26 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer,
                struct radv_meta_blit2d_surf img_bsurf =
                        blit_surf_for_image_level_layer(image,
                                                        layout,
-                                                       &pRegions[r].imageSubresource);
+                                                       &pRegions[r].imageSubresource,
+                                                       pRegions[r].imageSubresource.aspectMask);
+
+               if (!radv_is_buffer_format_supported(img_bsurf.format, NULL)) {
+                       uint32_t queue_mask = radv_image_queue_family_mask(image,
+                                                                          cmd_buffer->queue_family_index,
+                                                                          cmd_buffer->queue_family_index);
+                       MAYBE_UNUSED bool compressed = radv_layout_dcc_compressed(image, layout, queue_mask);
+                       if (compressed) {
+                               radv_decompress_dcc(cmd_buffer, image, &(VkImageSubresourceRange) {
+                                                               .aspectMask = pRegions[r].imageSubresource.aspectMask,
+                                                               .baseMipLevel = pRegions[r].imageSubresource.mipLevel,
+                                                               .levelCount = 1,
+                                                               .baseArrayLayer = pRegions[r].imageSubresource.baseArrayLayer,
+                                                               .layerCount = pRegions[r].imageSubresource.layerCount,
+                                                       });
+                       }
+                       img_bsurf.format = vk_format_for_size(vk_format_get_blocksize(img_bsurf.format));
+                       img_bsurf.current_layout = VK_IMAGE_LAYOUT_GENERAL;
+               }
 
                struct radv_meta_blit2d_buffer buf_bsurf = {
                        .bs = img_bsurf.bs,
@@ -188,10 +227,12 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer,
 
 
                        /* Perform Blit */
-                       if (cs)
+                       if (cs ||
+                           !image_is_renderable(cmd_buffer->device, img_bsurf.image)) {
                                radv_meta_buffer_to_image_cs(cmd_buffer, &buf_bsurf, &img_bsurf, 1, &rect);
-                       else
+                       } else {
                                radv_meta_blit2d(cmd_buffer, NULL, &buf_bsurf, &img_bsurf, 1, &rect);
+                       }
 
                        /* Once we've done the blit, all of the actual information about
                         * the image is embedded in the command buffer so we can just
@@ -208,6 +249,9 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer,
                }
        }
 
+       /* Restore conditional rendering. */
+       cmd_buffer->state.predicating = old_predicating;
+
        radv_meta_restore(&saved_state, cmd_buffer);
 }
 
@@ -236,12 +280,19 @@ meta_copy_image_to_buffer(struct radv_cmd_buffer *cmd_buffer,
                           const VkBufferImageCopy* pRegions)
 {
        struct radv_meta_saved_state saved_state;
+       bool old_predicating;
 
        radv_meta_save(&saved_state, cmd_buffer,
                       RADV_META_SAVE_COMPUTE_PIPELINE |
                       RADV_META_SAVE_CONSTANTS |
                       RADV_META_SAVE_DESCRIPTORS);
 
+       /* VK_EXT_conditional_rendering says that copy commands should not be
+        * affected by conditional rendering.
+        */
+       old_predicating = cmd_buffer->state.predicating;
+       cmd_buffer->state.predicating = false;
+
        for (unsigned r = 0; r < regionCount; r++) {
 
                /**
@@ -277,7 +328,26 @@ meta_copy_image_to_buffer(struct radv_cmd_buffer *cmd_buffer,
                struct radv_meta_blit2d_surf img_info =
                        blit_surf_for_image_level_layer(image,
                                                        layout,
-                                                       &pRegions[r].imageSubresource);
+                                                       &pRegions[r].imageSubresource,
+                                                       pRegions[r].imageSubresource.aspectMask);
+
+               if (!radv_is_buffer_format_supported(img_info.format, NULL)) {
+                       uint32_t queue_mask = radv_image_queue_family_mask(image,
+                                                                          cmd_buffer->queue_family_index,
+                                                                          cmd_buffer->queue_family_index);
+                       MAYBE_UNUSED bool compressed = radv_layout_dcc_compressed(image, layout, queue_mask);
+                       if (compressed) {
+                               radv_decompress_dcc(cmd_buffer, image, &(VkImageSubresourceRange) {
+                                                               .aspectMask = pRegions[r].imageSubresource.aspectMask,
+                                                               .baseMipLevel = pRegions[r].imageSubresource.mipLevel,
+                                                               .levelCount = 1,
+                                                               .baseArrayLayer = pRegions[r].imageSubresource.baseArrayLayer,
+                                                               .layerCount = pRegions[r].imageSubresource.layerCount,
+                                                       });
+                       }
+                       img_info.format = vk_format_for_size(vk_format_get_blocksize(img_info.format));
+                       img_info.current_layout = VK_IMAGE_LAYOUT_GENERAL;
+               }
 
                struct radv_meta_blit2d_buffer buf_info = {
                        .bs = img_info.bs,
@@ -313,6 +383,9 @@ meta_copy_image_to_buffer(struct radv_cmd_buffer *cmd_buffer,
                }
        }
 
+       /* Restore conditional rendering. */
+       cmd_buffer->state.predicating = old_predicating;
+
        radv_meta_restore(&saved_state, cmd_buffer);
 }
 
@@ -344,6 +417,7 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer,
 {
        bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE;
        struct radv_meta_saved_state saved_state;
+       bool old_predicating;
 
        /* From the Vulkan 1.0 spec:
         *
@@ -358,113 +432,133 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer,
                       RADV_META_SAVE_CONSTANTS |
                       RADV_META_SAVE_DESCRIPTORS);
 
-       for (unsigned r = 0; r < regionCount; r++) {
-               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;
+       /* VK_EXT_conditional_rendering says that copy commands should not be
+        * affected by conditional rendering.
+        */
+       old_predicating = cmd_buffer->state.predicating;
+       cmd_buffer->state.predicating = false;
 
-               if (dest_image->type == VK_IMAGE_TYPE_3D)
-                       b_dst.layer = dst_offset_el.z;
+       for (unsigned r = 0; r < regionCount; r++) {
+               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;
+                       }
+
+
+                       /**
+                        * 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);
 
-               /* Loop through each 3D or array slice */
-               unsigned num_slices_3d = img_extent_el.depth;
-               unsigned num_slices_array = pRegions[r].dstSubresource.layerCount;
-               unsigned slice_3d = 0;
-               unsigned slice_array = 0;
-               while (slice_3d < num_slices_3d && slice_array < num_slices_array) {
+                       /* Start creating blit rect */
+                       struct radv_meta_blit2d_rect rect = {
+                               .width = img_extent_el.width,
+                               .height = img_extent_el.height,
+                       };
 
-                       /* Finish creating blit rect */
-                       rect.dst_x = dst_offset_el.x;
-                       rect.dst_y = dst_offset_el.y;
-                       rect.src_x = src_offset_el.x;
-                       rect.src_y = src_offset_el.y;
+                       if (src_image->type == VK_IMAGE_TYPE_3D)
+                               b_src.layer = src_offset_el.z;
 
-                       /* Perform Blit */
-                       if (cs)
-                               radv_meta_image_to_image_cs(cmd_buffer, &b_src, &b_dst, 1, &rect);
-                       else
-                               radv_meta_blit2d(cmd_buffer, &b_src, NULL, &b_dst, 1, &rect);
-
-                       b_src.layer++;
-                       b_dst.layer++;
                        if (dest_image->type == VK_IMAGE_TYPE_3D)
-                               slice_3d++;
-                       else
-                               slice_array++;
+                               b_dst.layer = dst_offset_el.z;
+
+                       /* Loop through each 3D or array slice */
+                       unsigned num_slices_3d = img_extent_el.depth;
+                       unsigned num_slices_array = pRegions[r].dstSubresource.layerCount;
+                       unsigned slice_3d = 0;
+                       unsigned slice_array = 0;
+                       while (slice_3d < num_slices_3d && slice_array < num_slices_array) {
+
+                               /* Finish creating blit rect */
+                               rect.dst_x = dst_offset_el.x;
+                               rect.dst_y = dst_offset_el.y;
+                               rect.src_x = src_offset_el.x;
+                               rect.src_y = src_offset_el.y;
+
+                               /* Perform Blit */
+                               if (cs ||
+                                   !image_is_renderable(cmd_buffer->device, b_dst.image)) {
+                                       radv_meta_image_to_image_cs(cmd_buffer, &b_src, &b_dst, 1, &rect);
+                               } else {
+                                       radv_meta_blit2d(cmd_buffer, &b_src, NULL, &b_dst, 1, &rect);
+                               }
+
+                               b_src.layer++;
+                               b_dst.layer++;
+                               if (dest_image->type == VK_IMAGE_TYPE_3D)
+                                       slice_3d++;
+                               else
+                                       slice_array++;
+                       }
                }
        }
 
+       /* Restore conditional rendering. */
+       cmd_buffer->state.predicating = old_predicating;
+
        radv_meta_restore(&saved_state, cmd_buffer);
 }
 
@@ -486,24 +580,3 @@ void radv_CmdCopyImage(
                        dest_image, destImageLayout,
                        regionCount, pRegions);
 }
-
-void radv_blit_to_prime_linear(struct radv_cmd_buffer *cmd_buffer,
-                              struct radv_image *image,
-                              struct radv_image *linear_image)
-{
-       struct VkImageCopy image_copy = { 0 };
-
-       image_copy.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-       image_copy.srcSubresource.layerCount = 1;
-
-       image_copy.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-       image_copy.dstSubresource.layerCount = 1;
-
-       image_copy.extent.width = image->info.width;
-       image_copy.extent.height = image->info.height;
-       image_copy.extent.depth = 1;
-
-       meta_copy_image(cmd_buffer, image, VK_IMAGE_LAYOUT_GENERAL, linear_image,
-                       VK_IMAGE_LAYOUT_GENERAL,
-                       1, &image_copy);
-}