From e9b44a3bb55dffb72c49edc8c1f8c4e1a16edb2c Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Wed, 28 Feb 2024 11:13:19 +0100 Subject: [PATCH] v3dv: handle render pass continue flag with dynamic passes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a secondary command buffer recording a dynamic pass has the VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT flag then the rendering information for it should come from a VkCommandBufferInheritanceRenderingInfo struct in the pNext chain instead of the usual render pass information in the VkCommandBufferInheritanceInfo struct. We take the information from the new struct and build a render pass description from it assuming a setup without a framebuffer (which is optional for regular render passes too). Reviewed-by: Alejandro PiƱeiro Part-of: --- src/broadcom/vulkan/v3dv_cmd_buffer.c | 29 ++++++--- src/broadcom/vulkan/v3dv_pass.c | 84 +++++++++++++++++++++++++++ src/broadcom/vulkan/v3dv_private.h | 4 ++ 3 files changed, 108 insertions(+), 9 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index 0c1c6bad6c6..aff6ad96ea7 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -1033,16 +1033,27 @@ cmd_buffer_begin_render_pass_secondary( assert(cmd_buffer->usage_flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT); assert(inheritance_info); - cmd_buffer->state.pass = - v3dv_render_pass_from_handle(inheritance_info->renderPass); + const VkCommandBufferInheritanceRenderingInfo *rendering_info = NULL; + if (inheritance_info->renderPass == VK_NULL_HANDLE) { + rendering_info = vk_find_struct_const(inheritance_info, + COMMAND_BUFFER_INHERITANCE_RENDERING_INFO); + assert(rendering_info); + v3dv_setup_dynamic_render_pass_inheritance(cmd_buffer, rendering_info); + cmd_buffer->state.pass = &cmd_buffer->state.dynamic_pass; + cmd_buffer->state.subpass_idx = 0; + cmd_buffer->state.framebuffer = NULL; + } else { + cmd_buffer->state.pass = + v3dv_render_pass_from_handle(inheritance_info->renderPass); + + assert(inheritance_info->subpass < cmd_buffer->state.pass->subpass_count); + cmd_buffer->state.subpass_idx = inheritance_info->subpass; + + cmd_buffer->state.framebuffer = + v3dv_framebuffer_from_handle(inheritance_info->framebuffer); + } assert(cmd_buffer->state.pass); - cmd_buffer->state.framebuffer = - v3dv_framebuffer_from_handle(inheritance_info->framebuffer); - - assert(inheritance_info->subpass < cmd_buffer->state.pass->subpass_count); - cmd_buffer->state.subpass_idx = inheritance_info->subpass; - cmd_buffer->state.inheritance.occlusion_query_enable = inheritance_info->occlusionQueryEnable; @@ -1050,7 +1061,7 @@ cmd_buffer_begin_render_pass_secondary( * so we want to create a job for them here. */ struct v3dv_job *job = - v3dv_cmd_buffer_start_job(cmd_buffer, inheritance_info->subpass, + v3dv_cmd_buffer_start_job(cmd_buffer, cmd_buffer->state.subpass_idx, V3DV_JOB_TYPE_GPU_CL_INCOMPLETE); if (!job) { v3dv_flag_oom(cmd_buffer, NULL); diff --git a/src/broadcom/vulkan/v3dv_pass.c b/src/broadcom/vulkan/v3dv_pass.c index 5d8a335c344..ae6e37159d4 100644 --- a/src/broadcom/vulkan/v3dv_pass.c +++ b/src/broadcom/vulkan/v3dv_pass.c @@ -610,3 +610,87 @@ v3dv_setup_dynamic_render_pass(struct v3dv_cmd_buffer *cmd_buffer, pass->attachment_count = a; } + +void +v3dv_setup_dynamic_render_pass_inheritance(struct v3dv_cmd_buffer *cmd_buffer, + const VkCommandBufferInheritanceRenderingInfo *info) +{ + struct v3dv_device *device = cmd_buffer->device; + struct v3dv_cmd_buffer_state *state = &cmd_buffer->state; + + struct v3dv_render_pass *pass = &state->dynamic_pass; + struct v3dv_subpass *subpass = &state->dynamic_subpass; + struct v3dv_render_pass_attachment *pass_attachments = + &state->dynamic_attachments[0]; + struct v3dv_subpass_attachment *subpass_attachments = + &state->dynamic_subpass_attachments[0]; + + memset(pass, 0, sizeof(*pass)); + memset(subpass, 0, sizeof(*subpass)); + memset(pass_attachments, 0, sizeof(state->dynamic_subpass_attachments)); + memset(subpass_attachments, 0, sizeof(state->dynamic_subpass_attachments)); + + vk_object_base_init(&device->vk, (struct vk_object_base *) pass, + VK_OBJECT_TYPE_RENDER_PASS); + + pass->attachments = pass_attachments; + pass->subpass_attachments = subpass_attachments; + + subpass->view_mask = info->viewMask; + subpass->color_count = info->colorAttachmentCount; + subpass->color_attachments = &subpass_attachments[0]; + subpass->resolve_attachments = NULL; + + pass->multiview_enabled = info->viewMask != 0; + pass->subpass_count = 1; + pass->subpasses = subpass; + + int a = 0; + for (int i = 0; i < info->colorAttachmentCount; i++) { + struct v3dv_render_pass_attachment *att = &pass->attachments[a]; + const VkFormat format = info->pColorAttachmentFormats[i]; + + if (format == VK_FORMAT_UNDEFINED) { + subpass->color_attachments[i].attachment = VK_ATTACHMENT_UNUSED; + continue; + } + + /* We don't have info about load/store, so we assume we load and we + * store. + */ + att->desc.format = format; + att->desc.samples = info->rasterizationSamples; + att->desc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + att->desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + att->desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + att->desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + subpass->color_attachments[i].attachment = a++; + } + + if (info->depthAttachmentFormat != VK_FORMAT_UNDEFINED || + info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED) { + struct v3dv_render_pass_attachment *att = &pass->attachments[a]; + att->desc.format = info->depthAttachmentFormat != VK_FORMAT_UNDEFINED ? + info->depthAttachmentFormat : info->stencilAttachmentFormat; + att->desc.samples = info->rasterizationSamples; + if (vk_format_has_depth(att->desc.format)) { + att->desc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + att->desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + } else { + att->desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + att->desc.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + } + if (vk_format_has_stencil(att->desc.format)) { + att->desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + att->desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; + } else { + att->desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + att->desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + } + subpass->ds_attachment.attachment = a++; + } else { + subpass->ds_attachment.attachment = VK_ATTACHMENT_UNUSED; + } + + pass->attachment_count = a; +} diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index f73c991a872..e9911524f76 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -1430,6 +1430,10 @@ void v3dv_setup_dynamic_render_pass(struct v3dv_cmd_buffer *cmd_buffer, const VkRenderingInfoKHR *pRenderingInfo); +void +v3dv_setup_dynamic_render_pass_inheritance(struct v3dv_cmd_buffer *cmd_buffer, + const VkCommandBufferInheritanceRenderingInfo *info); + /* FIXME: only used on v3dv_cmd_buffer and v3dvx_cmd_buffer, perhaps move to a * cmd_buffer specific header? */