v3dv: handle render pass continue flag with dynamic passes

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 <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27978>
This commit is contained in:
Iago Toral Quiroga 2024-02-28 11:13:19 +01:00 committed by Marge Bot
parent f4ec92084e
commit e9b44a3bb5
3 changed files with 108 additions and 9 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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?
*/