diff --git a/src/virtio/vulkan/vn_command_buffer.c b/src/virtio/vulkan/vn_command_buffer.c index 822c0491864..17468fe19d2 100644 --- a/src/virtio/vulkan/vn_command_buffer.c +++ b/src/virtio/vulkan/vn_command_buffer.c @@ -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); } diff --git a/src/virtio/vulkan/vn_command_buffer.h b/src/virtio/vulkan/vn_command_buffer.h index 3ed16236cb8..432ffe74d8a 100644 --- a/src/virtio/vulkan/vn_command_buffer.h +++ b/src/virtio/vulkan/vn_command_buffer.h @@ -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, diff --git a/src/virtio/vulkan/vn_render_pass.c b/src/virtio/vulkan/vn_render_pass.c index 2084c38a02a..f4edce92ef6 100644 --- a/src/virtio/vulkan/vn_render_pass.c +++ b/src/virtio/vulkan/vn_render_pass.c @@ -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); diff --git a/src/virtio/vulkan/vn_render_pass.h b/src/virtio/vulkan/vn_render_pass.h index 9ae77155979..19c1878016b 100644 --- a/src/virtio/vulkan/vn_render_pass.h +++ b/src/virtio/vulkan/vn_render_pass.h @@ -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 {