Mesa (main): vulkan/render_pass: Add a better helper for render pass inheritance
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Jun 24 23:08:44 UTC 2022
Module: Mesa
Branch: main
Commit: 3a204d5cf370116a427361410a449dde002bc143
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=3a204d5cf370116a427361410a449dde002bc143
Author: Jason Ekstrand <jason.ekstrand at collabora.com>
Date: Tue May 31 15:53:51 2022 -0500
vulkan/render_pass: Add a better helper for render pass inheritance
Instead of making drivers dive into the render pass and framebuffer
themselves, provide a helper that constructs a VkRenderingInfo for a
render pass resume that they can use instead. This should reduce code
duplication between driver implementations of BeginRendering and
BeginCommandBuffer.
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16953>
---
src/vulkan/runtime/vk_render_pass.c | 120 ++++++++++++++++++++++++++++++++++++
src/vulkan/runtime/vk_render_pass.h | 40 +++++++++++-
2 files changed, 158 insertions(+), 2 deletions(-)
diff --git a/src/vulkan/runtime/vk_render_pass.c b/src/vulkan/runtime/vk_render_pass.c
index 6780baf75de..91f2a055d1e 100644
--- a/src/vulkan/runtime/vk_render_pass.c
+++ b/src/vulkan/runtime/vk_render_pass.c
@@ -820,6 +820,126 @@ vk_get_command_buffer_inheritance_rendering_info(
COMMAND_BUFFER_INHERITANCE_RENDERING_INFO);
}
+const VkRenderingInfo *
+vk_get_command_buffer_inheritance_as_rendering_resume(
+ VkCommandBufferLevel level,
+ const VkCommandBufferBeginInfo *pBeginInfo,
+ void *stack_data)
+{
+ struct vk_gcbiarr_data *data = stack_data;
+
+ /* From the Vulkan 1.3.204 spec:
+ *
+ * "VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT specifies that a
+ * secondary command buffer is considered to be entirely inside a render
+ * pass. If this is a primary command buffer, then this bit is ignored."
+ *
+ * Since we're only concerned with the continue case here, we can ignore
+ * any primary command buffers.
+ */
+ if (level == VK_COMMAND_BUFFER_LEVEL_PRIMARY)
+ return NULL;
+
+ if (!(pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT))
+ return NULL;
+
+ const VkCommandBufferInheritanceInfo *inheritance =
+ pBeginInfo->pInheritanceInfo;
+
+ VK_FROM_HANDLE(vk_render_pass, pass, inheritance->renderPass);
+ if (pass == NULL)
+ return NULL;
+
+ assert(inheritance->subpass < pass->subpass_count);
+ const struct vk_subpass *subpass = &pass->subpasses[inheritance->subpass];
+
+ VK_FROM_HANDLE(vk_framebuffer, fb, inheritance->framebuffer);
+ if (fb == NULL || (fb->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR))
+ return NULL;
+
+ data->rendering = (VkRenderingInfo) {
+ .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
+ .flags = VK_RENDERING_RESUMING_BIT,
+ .renderArea = {
+ .offset = { 0, 0 },
+ .extent = { fb->width, fb->height },
+ },
+ .layerCount = fb->layers,
+ .viewMask = pass->is_multiview ? subpass->view_mask : 0,
+ };
+
+ VkRenderingAttachmentInfo *attachments = data->attachments;
+
+ for (unsigned i = 0; i < subpass->color_count; i++) {
+ const struct vk_subpass_attachment *sp_att =
+ &subpass->color_attachments[i];
+ if (sp_att->attachment == VK_ATTACHMENT_UNUSED) {
+ attachments[i] = (VkRenderingAttachmentInfo) {
+ .imageView = VK_NULL_HANDLE,
+ };
+ continue;
+ }
+
+ assert(sp_att->attachment < pass->attachment_count);
+ attachments[i] = (VkRenderingAttachmentInfo) {
+ .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
+ .imageView = fb->attachments[sp_att->attachment],
+ .imageLayout = sp_att->layout,
+ .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
+ .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
+ };
+ }
+ data->rendering.colorAttachmentCount = subpass->color_count;
+ data->rendering.pColorAttachments = attachments;
+ attachments += subpass->color_count;
+
+ if (subpass->depth_stencil_attachment) {
+ const struct vk_subpass_attachment *sp_att =
+ subpass->depth_stencil_attachment;
+ assert(sp_att->attachment < pass->attachment_count);
+
+ VK_FROM_HANDLE(vk_image_view, iview, fb->attachments[sp_att->attachment]);
+ if (iview->image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
+ *attachments = (VkRenderingAttachmentInfo) {
+ .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
+ .imageView = vk_image_view_to_handle(iview),
+ .imageLayout = sp_att->layout,
+ .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
+ .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
+ };
+ data->rendering.pDepthAttachment = attachments++;
+ }
+
+ if (iview->image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
+ *attachments = (VkRenderingAttachmentInfo) {
+ .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
+ .imageView = vk_image_view_to_handle(iview),
+ .imageLayout = sp_att->stencil_layout,
+ .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
+ .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
+ };
+ data->rendering.pStencilAttachment = attachments++;
+ }
+ }
+
+ if (subpass->fragment_shading_rate_attachment) {
+ const struct vk_subpass_attachment *sp_att =
+ subpass->fragment_shading_rate_attachment;
+ assert(sp_att->attachment < pass->attachment_count);
+
+ data->fsr_att = (VkRenderingFragmentShadingRateAttachmentInfoKHR) {
+ .sType = VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR,
+ .imageView = fb->attachments[sp_att->attachment],
+ .imageLayout = sp_att->layout,
+ .shadingRateAttachmentTexelSize =
+ subpass->fragment_shading_rate_attachment_texel_size,
+ };
+ __vk_append_struct(&data->rendering, &data->fsr_att);
+ }
+
+ return &data->rendering;
+}
+
VKAPI_ATTR void VKAPI_CALL
vk_common_DestroyRenderPass(VkDevice _device,
VkRenderPass renderPass,
diff --git a/src/vulkan/runtime/vk_render_pass.h b/src/vulkan/runtime/vk_render_pass.h
index 8eb99455c93..59b40a25bf5 100644
--- a/src/vulkan/runtime/vk_render_pass.h
+++ b/src/vulkan/runtime/vk_render_pass.h
@@ -305,7 +305,7 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(vk_render_pass, base, VkRenderPass,
/** Returns the VkPipelineRenderingCreateInfo for a graphics pipeline
*
- * For render-pass-free drivers, this can be used in the implementaiton of
+ * For render-pass-free drivers, this can be used in the implementation of
* vkCreateGraphicsPipelines to get the VkPipelineRenderingCreateInfo. If
* VkGraphicsPipelineCreateInfo::renderPass is not VK_NULL_HANDLE, it will
* return a representation of the specified subpass as a
@@ -322,7 +322,7 @@ vk_get_pipeline_rendering_create_info(const VkGraphicsPipelineCreateInfo *info);
* Returns the VkCommandBufferInheritanceRenderingInfo for secondary command
* buffer execution
*
- * For render-pass-free drivers, this can be used in the implementaiton of
+ * For render-pass-free drivers, this can be used in the implementation of
* vkCmdExecuteCommands to get the VkCommandBufferInheritanceRenderingInfo.
* If VkCommandBufferInheritanceInfo::renderPass is not VK_NULL_HANDLE, it
* will return a representation of the specified subpass as a
@@ -339,6 +339,42 @@ vk_get_command_buffer_inheritance_rendering_info(
VkCommandBufferLevel level,
const VkCommandBufferBeginInfo *pBeginInfo);
+struct vk_gcbiarr_data {
+ VkRenderingInfo rendering;
+ VkRenderingFragmentShadingRateAttachmentInfoKHR fsr_att;
+ VkRenderingAttachmentInfo attachments[];
+};
+
+#define VK_GCBIARR_DATA_SIZE(max_color_rts) (\
+ sizeof(struct vk_gcbiarr_data) + \
+ sizeof(VkRenderingAttachmentInfo) * ((max_color_rts) + 2) \
+)
+
+/**
+ * Constructs a VkRenderingInfo for the inheritance rendering info
+ *
+ * For render-pass-free drivers, this can be used in the implementaiton of
+ * vkCmdExecuteCommands to get a VkRenderingInfo representing the subpass and
+ * framebuffer provided via the inheritance info for a command buffer created
+ * with VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT. The mental model
+ * here is that VkExecuteCommands() implicitly suspends the render pass and
+ * VkBeginCommandBuffer() resumes it. If a VkRenderingInfo cannot be
+ * constructed due to a missing framebuffer or similar, NULL will be
+ * returned.
+ *
+ * @param[in] level The nesting level of this command buffer
+ * @param[in] pBeginInfo The pBeginInfo from vkBeginCommandBuffer
+ * @param[out] stack_data An opaque blob of data which will be overwritten by
+ * this function, passed in from the caller to avoid
+ * heap allocations. It must be at least
+ * VK_GCBIARR_DATA_SIZE(max_color_rts) bytes.
+ */
+const VkRenderingInfo *
+vk_get_command_buffer_inheritance_as_rendering_resume(
+ VkCommandBufferLevel level,
+ const VkCommandBufferBeginInfo *pBeginInfo,
+ void *stack_data);
+
#ifdef __cplusplus
}
#endif
More information about the mesa-commit
mailing list