radv: add support for CmdBlitImage2KHR()
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Tue, 22 Sep 2020 06:46:43 +0000 (08:46 +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_blit.c

index 71cea3b..b31af3b 100644 (file)
@@ -526,20 +526,17 @@ flip_coords(unsigned *src0, unsigned *src1, unsigned *dst0, unsigned *dst1)
        return flip;
 }
 
-void radv_CmdBlitImage(
-       VkCommandBuffer                             commandBuffer,
-       VkImage                                     srcImage,
-       VkImageLayout                               srcImageLayout,
-       VkImage                                     destImage,
-       VkImageLayout                               destImageLayout,
-       uint32_t                                    regionCount,
-       const VkImageBlit*                          pRegions,
-       VkFilter                                    filter)
-
+static void
+blit_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 VkImageBlit2KHR *region,
+          VkFilter filter)
 {
-       RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
-       RADV_FROM_HANDLE(radv_image, src_image, srcImage);
-       RADV_FROM_HANDLE(radv_image, dest_image, destImage);
+       const VkImageSubresourceLayers *src_res = &region->srcSubresource;
+       const VkImageSubresourceLayers *dst_res = &region->dstSubresource;
        struct radv_device *device = cmd_buffer->device;
        struct radv_meta_saved_state saved_state;
        bool old_predicating;
@@ -551,7 +548,7 @@ void radv_CmdBlitImage(
         *    destination images. Use vkCmdResolveImage for this purpose.
         */
        assert(src_image->info.samples == 1);
-       assert(dest_image->info.samples == 1);
+       assert(dst_image->info.samples == 1);
 
        radv_CreateSampler(radv_device_to_handle(device),
                           &(VkSamplerCreateInfo) {
@@ -574,126 +571,121 @@ void radv_CmdBlitImage(
        old_predicating = cmd_buffer->state.predicating;
        cmd_buffer->state.predicating = false;
 
-       for (unsigned r = 0; r < regionCount; r++) {
-               const VkImageSubresourceLayers *src_res = &pRegions[r].srcSubresource;
-               const VkImageSubresourceLayers *dst_res = &pRegions[r].dstSubresource;
-
-               unsigned dst_start, dst_end;
-               if (dest_image->type == VK_IMAGE_TYPE_3D) {
-                       assert(dst_res->baseArrayLayer == 0);
-                       dst_start = pRegions[r].dstOffsets[0].z;
-                       dst_end = pRegions[r].dstOffsets[1].z;
-               } else {
-                       dst_start = dst_res->baseArrayLayer;
-                       dst_end = dst_start + dst_res->layerCount;
-               }
+       unsigned dst_start, dst_end;
+       if (dst_image->type == VK_IMAGE_TYPE_3D) {
+               assert(dst_res->baseArrayLayer == 0);
+               dst_start = region->dstOffsets[0].z;
+               dst_end = region->dstOffsets[1].z;
+       } else {
+               dst_start = dst_res->baseArrayLayer;
+               dst_end = dst_start + dst_res->layerCount;
+       }
 
-               unsigned src_start, src_end;
-               if (src_image->type == VK_IMAGE_TYPE_3D) {
-                       assert(src_res->baseArrayLayer == 0);
-                       src_start = pRegions[r].srcOffsets[0].z;
-                       src_end = pRegions[r].srcOffsets[1].z;
-               } else {
-                       src_start = src_res->baseArrayLayer;
-                       src_end = src_start + src_res->layerCount;
-               }
+       unsigned src_start, src_end;
+       if (src_image->type == VK_IMAGE_TYPE_3D) {
+               assert(src_res->baseArrayLayer == 0);
+               src_start = region->srcOffsets[0].z;
+               src_end = region->srcOffsets[1].z;
+       } else {
+               src_start = src_res->baseArrayLayer;
+               src_end = src_start + src_res->layerCount;
+       }
 
-               bool flip_z = flip_coords(&src_start, &src_end, &dst_start, &dst_end);
-               float src_z_step = (float)(src_end - src_start) /
-                       (float)(dst_end - dst_start);
+       bool flip_z = flip_coords(&src_start, &src_end, &dst_start, &dst_end);
+       float src_z_step = (float)(src_end - src_start) /
+               (float)(dst_end - dst_start);
 
-               /* There is no interpolation to the pixel center during
-                * rendering, so add the 0.5 offset ourselves here. */
-               float depth_center_offset = 0;
-               if (src_image->type == VK_IMAGE_TYPE_3D)
-                       depth_center_offset = 0.5 / (dst_end - dst_start) * (src_end - src_start);
+       /* There is no interpolation to the pixel center during
+        * rendering, so add the 0.5 offset ourselves here. */
+       float depth_center_offset = 0;
+       if (src_image->type == VK_IMAGE_TYPE_3D)
+               depth_center_offset = 0.5 / (dst_end - dst_start) * (src_end - src_start);
 
-               if (flip_z) {
-                       src_start = src_end;
-                       src_z_step *= -1;
-                       depth_center_offset *= -1;
-               }
+       if (flip_z) {
+               src_start = src_end;
+               src_z_step *= -1;
+               depth_center_offset *= -1;
+       }
 
-               unsigned src_x0 = pRegions[r].srcOffsets[0].x;
-               unsigned src_x1 = pRegions[r].srcOffsets[1].x;
-               unsigned dst_x0 = pRegions[r].dstOffsets[0].x;
-               unsigned dst_x1 = pRegions[r].dstOffsets[1].x;
-
-               unsigned src_y0 = pRegions[r].srcOffsets[0].y;
-               unsigned src_y1 = pRegions[r].srcOffsets[1].y;
-               unsigned dst_y0 = pRegions[r].dstOffsets[0].y;
-               unsigned dst_y1 = pRegions[r].dstOffsets[1].y;
-
-               VkRect2D dest_box;
-               dest_box.offset.x = MIN2(dst_x0, dst_x1);
-               dest_box.offset.y = MIN2(dst_y0, dst_y1);
-               dest_box.extent.width = dst_x1 - dst_x0;
-               dest_box.extent.height = dst_y1 - dst_y0;
-
-               const unsigned num_layers = dst_end - dst_start;
-               for (unsigned i = 0; i < num_layers; i++) {
-                       struct radv_image_view dest_iview, src_iview;
-
-                       const VkOffset2D dest_offset_0 = {
-                               .x = dst_x0,
-                               .y = dst_y0,
-                       };
-                       const VkOffset2D dest_offset_1 = {
-                               .x = dst_x1,
-                               .y = dst_y1,
-                       };
-
-                       float src_offset_0[3] = {
-                               src_x0,
-                               src_y0,
-                               src_start + i * src_z_step + depth_center_offset,
-                       };
-                       float src_offset_1[3] = {
-                               src_x1,
-                               src_y1,
-                               src_start + i * src_z_step + depth_center_offset,
-                       };
-                       const uint32_t dest_array_slice = dst_start + i;
-
-                       /* 3D images have just 1 layer */
-                       const uint32_t src_array_slice = src_image->type == VK_IMAGE_TYPE_3D ? 0 : src_start + i;
-
-                       radv_image_view_init(&dest_iview, cmd_buffer->device,
-                                            &(VkImageViewCreateInfo) {
-                                                    .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-                                                            .image = destImage,
-                                                            .viewType = radv_meta_get_view_type(dest_image),
-                                                            .format = dest_image->vk_format,
-                                                            .subresourceRange = {
-                                                            .aspectMask = dst_res->aspectMask,
-                                                            .baseMipLevel = dst_res->mipLevel,
-                                                            .levelCount = 1,
-                                                            .baseArrayLayer = dest_array_slice,
-                                                            .layerCount = 1
-                                                    },
-                                            }, NULL);
-                       radv_image_view_init(&src_iview, cmd_buffer->device,
-                                            &(VkImageViewCreateInfo) {
-                                               .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-                                                       .image = srcImage,
-                                                       .viewType = radv_meta_get_view_type(src_image),
-                                                       .format = src_image->vk_format,
-                                                       .subresourceRange = {
-                                                       .aspectMask = src_res->aspectMask,
-                                                       .baseMipLevel = src_res->mipLevel,
-                                                       .levelCount = 1,
-                                                       .baseArrayLayer = src_array_slice,
-                                                       .layerCount = 1
-                                               },
-                                       }, NULL);
-                       meta_emit_blit(cmd_buffer,
-                                      src_image, &src_iview, srcImageLayout,
-                                      src_offset_0, src_offset_1,
-                                      dest_image, &dest_iview, destImageLayout,
-                                      dest_offset_0, dest_offset_1,
-                                      dest_box,
-                                      sampler);
-               }
+       unsigned src_x0 = region->srcOffsets[0].x;
+       unsigned src_x1 = region->srcOffsets[1].x;
+       unsigned dst_x0 = region->dstOffsets[0].x;
+       unsigned dst_x1 = region->dstOffsets[1].x;
+
+       unsigned src_y0 = region->srcOffsets[0].y;
+       unsigned src_y1 = region->srcOffsets[1].y;
+       unsigned dst_y0 = region->dstOffsets[0].y;
+       unsigned dst_y1 = region->dstOffsets[1].y;
+
+       VkRect2D dst_box;
+       dst_box.offset.x = MIN2(dst_x0, dst_x1);
+       dst_box.offset.y = MIN2(dst_y0, dst_y1);
+       dst_box.extent.width = dst_x1 - dst_x0;
+       dst_box.extent.height = dst_y1 - dst_y0;
+
+       const unsigned num_layers = dst_end - dst_start;
+       for (unsigned i = 0; i < num_layers; i++) {
+               struct radv_image_view dst_iview, src_iview;
+
+               const VkOffset2D dst_offset_0 = {
+                       .x = dst_x0,
+                       .y = dst_y0,
+               };
+               const VkOffset2D dst_offset_1 = {
+                       .x = dst_x1,
+                       .y = dst_y1,
+               };
+
+               float src_offset_0[3] = {
+                       src_x0,
+                       src_y0,
+                       src_start + i * src_z_step + depth_center_offset,
+               };
+               float src_offset_1[3] = {
+                       src_x1,
+                       src_y1,
+                       src_start + i * src_z_step + depth_center_offset,
+               };
+               const uint32_t dst_array_slice = dst_start + i;
+
+               /* 3D images have just 1 layer */
+               const uint32_t src_array_slice = src_image->type == VK_IMAGE_TYPE_3D ? 0 : src_start + i;
+
+               radv_image_view_init(&dst_iview, cmd_buffer->device,
+                                    &(VkImageViewCreateInfo) {
+                                            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+                                                    .image = radv_image_to_handle(dst_image),
+                                                    .viewType = radv_meta_get_view_type(dst_image),
+                                                    .format = dst_image->vk_format,
+                                                    .subresourceRange = {
+                                                    .aspectMask = dst_res->aspectMask,
+                                                    .baseMipLevel = dst_res->mipLevel,
+                                                    .levelCount = 1,
+                                                    .baseArrayLayer = dst_array_slice,
+                                                    .layerCount = 1
+                                            },
+                                    }, NULL);
+               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 = src_res->aspectMask,
+                                               .baseMipLevel = src_res->mipLevel,
+                                               .levelCount = 1,
+                                               .baseArrayLayer = src_array_slice,
+                                               .layerCount = 1
+                                       },
+                               }, NULL);
+               meta_emit_blit(cmd_buffer,
+                              src_image, &src_iview, src_image_layout,
+                              src_offset_0, src_offset_1,
+                              dst_image, &dst_iview, dst_image_layout,
+                              dst_offset_0, dst_offset_1,
+                              dst_box,
+                              sampler);
        }
 
        /* Restore conditional rendering. */
@@ -705,6 +697,60 @@ void radv_CmdBlitImage(
                            &cmd_buffer->pool->alloc);
 }
 
+void radv_CmdBlitImage(
+       VkCommandBuffer                             commandBuffer,
+       VkImage                                     srcImage,
+       VkImageLayout                               srcImageLayout,
+       VkImage                                     dstImage,
+       VkImageLayout                               dstImageLayout,
+       uint32_t                                    regionCount,
+       const VkImageBlit*                          pRegions,
+       VkFilter                                    filter)
+
+{
+       RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+       RADV_FROM_HANDLE(radv_image, src_image, srcImage);
+       RADV_FROM_HANDLE(radv_image, dst_image, dstImage);
+
+       for (unsigned r = 0; r < regionCount; r++) {
+               VkImageBlit2KHR blit = {
+                       .sType          = VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR,
+                       .srcSubresource = pRegions[r].srcSubresource,
+                       .srcOffsets     = {
+                               pRegions[r].srcOffsets[0],
+                               pRegions[r].srcOffsets[1],
+                       },
+                       .dstSubresource = pRegions[r].dstSubresource,
+                       .dstOffsets     = {
+                               pRegions[r].dstOffsets[0],
+                               pRegions[r].dstOffsets[1],
+                       },
+               };
+
+               blit_image(cmd_buffer,
+                          src_image, srcImageLayout,
+                          dst_image, dstImageLayout,
+                          &blit, filter);
+       }
+}
+
+void radv_CmdBlitImage2KHR(
+       VkCommandBuffer                             commandBuffer,
+       const VkBlitImageInfo2KHR*                  pBlitImageInfo)
+{
+       RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+       RADV_FROM_HANDLE(radv_image, src_image, pBlitImageInfo->srcImage);
+       RADV_FROM_HANDLE(radv_image, dst_image, pBlitImageInfo->dstImage);
+
+       for (unsigned r = 0; r < pBlitImageInfo->regionCount; r++) {
+               blit_image(cmd_buffer,
+                          src_image, pBlitImageInfo->srcImageLayout,
+                          dst_image, pBlitImageInfo->dstImageLayout,
+                          &pBlitImageInfo->pRegions[r],
+                          pBlitImageInfo->filter);
+       }
+}
+
 void
 radv_device_finish_meta_blit_state(struct radv_device *device)
 {