pvr: Add attachment resolve support.
authorRajnesh Kanwal <rajnesh.kanwal@imgtec.com>
Fri, 2 Sep 2022 14:15:42 +0000 (15:15 +0100)
committerRajnesh Kanwal <rajnesh.kanwal@imgtec.com>
Thu, 22 Sep 2022 15:54:07 +0000 (16:54 +0100)
Signed-off-by: Rajnesh Kanwal <rajnesh.kanwal@imgtec.com>
Reviewed-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18707>

src/imagination/vulkan/pvr_blit.c
src/imagination/vulkan/pvr_cmd_buffer.c
src/imagination/vulkan/pvr_private.h

index 363769f..80ed1da 100644 (file)
@@ -42,6 +42,16 @@ void pvr_CmdBlitImage2KHR(VkCommandBuffer commandBuffer,
    assert(!"Unimplemented");
 }
 
+VkResult
+pvr_copy_or_resolve_color_image_region(struct pvr_cmd_buffer *cmd_buffer,
+                                       const struct pvr_image *src,
+                                       const struct pvr_image *dst,
+                                       const VkImageCopy2 *region)
+{
+   assert(!"Unimplemented");
+   return VK_SUCCESS;
+}
+
 void pvr_CmdCopyImageToBuffer2KHR(
    VkCommandBuffer commandBuffer,
    const VkCopyImageToBufferInfo2 *pCopyImageToBufferInfo)
index cd131f2..635e2f2 100644 (file)
@@ -5453,9 +5453,82 @@ void pvr_CmdDrawIndirect(VkCommandBuffer commandBuffer,
 }
 
 static VkResult
-pvr_resolve_unemitted_resolve_attachments(struct pvr_cmd_buffer *cmd_buffer)
+pvr_resolve_unemitted_resolve_attachments(struct pvr_cmd_buffer *cmd_buffer,
+                                          struct pvr_render_pass_info *info)
 {
-   pvr_finishme("Add attachment resolve support!");
+   struct pvr_cmd_buffer_state *state = &cmd_buffer->state;
+   const struct pvr_renderpass_hwsetup_render *hw_render =
+      &state->render_pass_info.pass->hw_setup->renders[info->current_hw_subpass];
+
+   for (uint32_t i = 0U; i < hw_render->eot_surface_count; i++) {
+      const struct pvr_renderpass_hwsetup_eot_surface *surface =
+         &hw_render->eot_surfaces[i];
+      const uint32_t color_attach_idx = surface->src_attachment_idx;
+      const uint32_t resolve_attach_idx = surface->attachment_idx;
+      VkImageSubresourceLayers src_subresource;
+      VkImageSubresourceLayers dst_subresource;
+      struct pvr_image_view *dst_view;
+      struct pvr_image_view *src_view;
+      VkFormat src_format;
+      VkFormat dst_format;
+      VkImageCopy2 region;
+      VkResult result;
+
+      if (!surface->need_resolve ||
+          surface->resolve_type != PVR_RESOLVE_TYPE_TRANSFER)
+         continue;
+
+      dst_view = info->attachments[resolve_attach_idx];
+      src_view = info->attachments[color_attach_idx];
+
+      src_subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+      src_subresource.mipLevel = src_view->vk.base_mip_level;
+      src_subresource.baseArrayLayer = src_view->vk.base_array_layer;
+      src_subresource.layerCount = src_view->vk.layer_count;
+
+      dst_subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+      dst_subresource.mipLevel = dst_view->vk.base_mip_level;
+      dst_subresource.baseArrayLayer = dst_view->vk.base_array_layer;
+      dst_subresource.layerCount = dst_view->vk.layer_count;
+
+      region.srcOffset = (VkOffset3D){ info->render_area.offset.x,
+                                       info->render_area.offset.y,
+                                       0 };
+      region.dstOffset = (VkOffset3D){ info->render_area.offset.x,
+                                       info->render_area.offset.y,
+                                       0 };
+      region.extent = (VkExtent3D){ info->render_area.extent.width,
+                                    info->render_area.extent.height,
+                                    1 };
+
+      region.srcSubresource = src_subresource;
+      region.dstSubresource = dst_subresource;
+
+      /* TODO: if ERN_46863 is supported, Depth and stencil are sampled
+       * separately from images with combined depth+stencil. Add logic here to
+       * handle it using appropriate format from image view.
+       */
+      src_format = src_view->vk.image->format;
+      dst_format = dst_view->vk.image->format;
+      src_view->vk.image->format = src_view->vk.format;
+      dst_view->vk.image->format = dst_view->vk.format;
+
+      result = pvr_copy_or_resolve_color_image_region(
+         cmd_buffer,
+         vk_to_pvr_image(src_view->vk.image),
+         vk_to_pvr_image(dst_view->vk.image),
+         &region);
+
+      src_view->vk.image->format = src_format;
+      dst_view->vk.image->format = dst_format;
+
+      state->current_sub_cmd->flags |=
+         PVR_SUB_COMMAND_FLAG_WAIT_ON_PREVIOUS_FRAG;
+
+      if (result != VK_SUCCESS)
+         return result;
+   }
+
    return pvr_cmd_buffer_end_sub_cmd(cmd_buffer);
 }
 
@@ -5481,7 +5554,8 @@ void pvr_CmdEndRenderPass2(VkCommandBuffer commandBuffer,
    if (result != VK_SUCCESS)
       return;
 
-   result = pvr_resolve_unemitted_resolve_attachments(cmd_buffer);
+   result = pvr_resolve_unemitted_resolve_attachments(cmd_buffer,
+                                                      &state->render_pass_info);
    if (result != VK_SUCCESS)
       return;
 
index a71da85..a1ab839 100644 (file)
@@ -121,6 +121,10 @@ enum pvr_event_type {
    PVR_EVENT_TYPE_BARRIER,
 };
 
+enum pvr_sub_command_flags {
+   PVR_SUB_COMMAND_FLAG_WAIT_ON_PREVIOUS_FRAG = BITFIELD_BIT(0),
+};
+
 enum pvr_depth_stencil_usage {
    PVR_DEPTH_STENCIL_USAGE_UNDEFINED = 0, /* explicitly treat 0 as undefined */
    PVR_DEPTH_STENCIL_USAGE_NEEDED,
@@ -769,6 +773,8 @@ struct pvr_sub_cmd {
 
    enum pvr_sub_cmd_type type;
 
+   enum pvr_sub_command_flags flags;
+
    union {
       struct pvr_sub_cmd_gfx gfx;
       struct pvr_sub_cmd_compute compute;
@@ -1489,6 +1495,12 @@ VkResult pvr_emit_ppp_from_template(
    const struct pvr_static_clear_ppp_template *const template,
    struct pvr_bo **const pvr_bo_out);
 
+VkResult
+pvr_copy_or_resolve_color_image_region(struct pvr_cmd_buffer *cmd_buffer,
+                                       const struct pvr_image *src,
+                                       const struct pvr_image *dst,
+                                       const VkImageCopy2 *region);
+
 void pvr_get_image_subresource_layout(const struct pvr_image *image,
                                       const VkImageSubresource *subresource,
                                       VkSubresourceLayout *layout);