venus: track viewMask
authorJuston Li <justonli@google.com>
Fri, 30 Jun 2023 15:37:12 +0000 (08:37 -0700)
committerMarge Bot <emma+marge@anholt.net>
Fri, 30 Jun 2023 18:50:52 +0000 (18:50 +0000)
Per spec 1.3.255: "If queries are used while executing a render pass
instance that has multiview enabled, the query uses N consecutive query
indices in the query pool (starting at query) where N is the number of
bits set in the view mask in the subpass the query is used in."

track viewMask so query feedback can copy the correct amount of queries
when multiview is enabled.

viewMask is passed in for vkCmdBeginRendering but for legacy
vkCmdBeginRenderPass/2 they are set by vkCreateRenderPass for each
subpass.

Signed-off-by: Juston Li <justonli@google.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23348>

src/virtio/vulkan/vn_command_buffer.c
src/virtio/vulkan/vn_command_buffer.h
src/virtio/vulkan/vn_render_pass.c
src/virtio/vulkan/vn_render_pass.h

index 822c049..17468fe 100644 (file)
@@ -513,6 +513,12 @@ vn_cmd_begin_render_pass(struct vn_command_buffer *cmd,
    cmd->builder.render_pass = pass;
    cmd->builder.framebuffer = fb;
 
+   if (begin_info) {
+      cmd->render_pass = pass;
+      cmd->subpass_index = 0;
+      cmd->view_mask = cmd->render_pass->subpasses[0].view_mask;
+   }
+
    if (!pass->present_count ||
        cmd->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY)
       return;
@@ -563,6 +569,10 @@ vn_cmd_end_render_pass(struct vn_command_buffer *cmd)
    cmd->builder.render_pass = NULL;
    cmd->builder.framebuffer = NULL;
 
+   cmd->render_pass = NULL;
+   cmd->subpass_index = 0;
+   cmd->view_mask = 0;
+
    if (!pass->present_count || !cmd->builder.present_src_images)
       return;
 
@@ -651,6 +661,10 @@ vn_cmd_reset(struct vn_command_buffer *cmd)
    vn_cs_encoder_reset(&cmd->cs);
    cmd->state = VN_COMMAND_BUFFER_STATE_INITIAL;
    cmd->draw_cmd_batched = 0;
+
+   cmd->render_pass = NULL;
+   cmd->subpass_index = 0;
+   cmd->view_mask = 0;
 }
 
 VkResult
@@ -898,12 +912,34 @@ vn_BeginCommandBuffer(VkCommandBuffer commandBuffer,
 
    cmd->state = VN_COMMAND_BUFFER_STATE_RECORDING;
 
-   if (local_begin_info.has_inherited_pass) {
-      const VkCommandBufferInheritanceInfo *inheritance_info =
-         pBeginInfo->pInheritanceInfo;
-      vn_cmd_begin_render_pass(
-         cmd, vn_render_pass_from_handle(inheritance_info->renderPass),
-         vn_framebuffer_from_handle(inheritance_info->framebuffer), NULL);
+   const VkCommandBufferInheritanceInfo *inheritance_info =
+      pBeginInfo->pInheritanceInfo;
+
+   if (inheritance_info) {
+      if (local_begin_info.has_inherited_pass) {
+         vn_cmd_begin_render_pass(
+            cmd, vn_render_pass_from_handle(inheritance_info->renderPass),
+            vn_framebuffer_from_handle(inheritance_info->framebuffer), NULL);
+
+         /* Store the viewMask from the inherited render pass subpass for
+          * query feedback.
+          */
+         const struct vn_render_pass *pass =
+            vn_render_pass_from_handle(inheritance_info->renderPass);
+         cmd->view_mask =
+            pass->subpasses[inheritance_info->subpass].view_mask;
+      } else {
+         /* Store the viewMask from the
+          * VkCommandBufferInheritanceRenderingInfo.
+          */
+         const VkCommandBufferInheritanceRenderingInfo
+            *inheritance_rendering_info = vk_find_struct_const(
+               inheritance_info->pNext,
+               COMMAND_BUFFER_INHERITANCE_RENDERING_INFO);
+
+         if (inheritance_rendering_info)
+            cmd->view_mask = inheritance_rendering_info->viewMask;
+      }
    }
 
    return VK_SUCCESS;
@@ -1111,13 +1147,23 @@ void
 vn_CmdBeginRendering(VkCommandBuffer commandBuffer,
                      const VkRenderingInfo *pRenderingInfo)
 {
+   struct vn_command_buffer *cmd =
+      vn_command_buffer_from_handle(commandBuffer);
+
+   cmd->view_mask = pRenderingInfo->viewMask;
+
    VN_CMD_ENQUEUE(vkCmdBeginRendering, commandBuffer, pRenderingInfo);
 }
 
 void
 vn_CmdEndRendering(VkCommandBuffer commandBuffer)
 {
+   struct vn_command_buffer *cmd =
+      vn_command_buffer_from_handle(commandBuffer);
+
    VN_CMD_ENQUEUE(vkCmdEndRendering, commandBuffer);
+
+   cmd->view_mask = 0;
 }
 
 void
@@ -1694,6 +1740,11 @@ vn_CmdBeginRenderPass(VkCommandBuffer commandBuffer,
 void
 vn_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
 {
+   struct vn_command_buffer *cmd =
+      vn_command_buffer_from_handle(commandBuffer);
+   cmd->view_mask =
+      cmd->render_pass->subpasses[++cmd->subpass_index].view_mask;
+
    VN_CMD_ENQUEUE(vkCmdNextSubpass, commandBuffer, contents);
 }
 
@@ -1730,6 +1781,11 @@ vn_CmdNextSubpass2(VkCommandBuffer commandBuffer,
                    const VkSubpassBeginInfo *pSubpassBeginInfo,
                    const VkSubpassEndInfo *pSubpassEndInfo)
 {
+   struct vn_command_buffer *cmd =
+      vn_command_buffer_from_handle(commandBuffer);
+   cmd->view_mask =
+      cmd->render_pass->subpasses[++cmd->subpass_index].view_mask;
+
    VN_CMD_ENQUEUE(vkCmdNextSubpass2, commandBuffer, pSubpassBeginInfo,
                   pSubpassEndInfo);
 }
index 3ed1623..432ffe7 100644 (file)
@@ -67,6 +67,16 @@ struct vn_command_buffer {
    struct vn_cs_encoder cs;
 
    uint32_t draw_cmd_batched;
+
+   /* For batching query feedback in render passes */
+   /* viewMask is stored per subpass for legacy render pass */
+   const struct vn_render_pass *render_pass;
+   uint32_t subpass_index;
+   /* view_mask is set when passed in by dynamic rendering/secondary cmd
+    * buffers or on each subpass iteration for legacy render pass with
+    * the above variables.
+    */
+   uint32_t view_mask;
 };
 VK_DEFINE_HANDLE_CASTS(vn_command_buffer,
                        base.base,
index 2084c38..f4edce9 100644 (file)
@@ -210,6 +210,16 @@ vn_CreateRenderPass(VkDevice device,
       pCreateInfo = &local_pass_info;
    }
 
+   const struct VkRenderPassMultiviewCreateInfo *multiview_info =
+      vk_find_struct_const(pCreateInfo->pNext,
+                           RENDER_PASS_MULTIVIEW_CREATE_INFO);
+
+   /* Store the viewMask of each subpass for query feedback */
+   if (multiview_info) {
+      for (uint32_t i = 0; i < multiview_info->subpassCount; i++)
+         pass->subpasses[i].view_mask = multiview_info->pViewMasks[i];
+   }
+
    VkRenderPass pass_handle = vn_render_pass_to_handle(pass);
    vn_async_vkCreateRenderPass(dev->instance, device, pCreateInfo, NULL,
                                &pass_handle);
@@ -262,6 +272,10 @@ vn_CreateRenderPass2(VkDevice device,
       pCreateInfo = &local_pass_info;
    }
 
+   /* Store the viewMask of each subpass for query feedback */
+   for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++)
+      pass->subpasses[i].view_mask = pCreateInfo->pSubpasses[i].viewMask;
+
    VkRenderPass pass_handle = vn_render_pass_to_handle(pass);
    vn_async_vkCreateRenderPass2(dev->instance, device, pCreateInfo, NULL,
                                 &pass_handle);
index 9ae7715..19c1878 100644 (file)
@@ -26,6 +26,7 @@ struct vn_present_src_attachment {
 struct vn_subpass {
    bool has_color_attachment;
    bool has_depth_stencil_attachment;
+   uint32_t view_mask;
 };
 
 struct vn_render_pass {