Mesa (main): tu: Initial support for dynamic rendering
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Jul 27 20:15:22 UTC 2022
Module: Mesa
Branch: main
Commit: ed125e6cca188275631641784fcf3ddcbcfef193
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=ed125e6cca188275631641784fcf3ddcbcfef193
Author: Connor Abbott <cwabbott0 at gmail.com>
Date: Tue Jun 28 10:33:01 2022 +0200
tu: Initial support for dynamic rendering
Support for suspend/resume will be added later. This just sets up
the internal render pass, and adds support to pipeline creation and
secondary inheritance.
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17378>
---
src/freedreno/vulkan/tu_cmd_buffer.c | 147 +++++++++++++++++---
src/freedreno/vulkan/tu_device.c | 17 +++
src/freedreno/vulkan/tu_image.c | 1 +
src/freedreno/vulkan/tu_pass.c | 259 +++++++++++++++++++++++++++++++----
src/freedreno/vulkan/tu_pipeline.c | 109 ++++++++++-----
src/freedreno/vulkan/tu_private.h | 20 +++
6 files changed, 477 insertions(+), 76 deletions(-)
diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c
index c246d90293b..cd43c8fb53d 100644
--- a/src/freedreno/vulkan/tu_cmd_buffer.c
+++ b/src/freedreno/vulkan/tu_cmd_buffer.c
@@ -269,8 +269,22 @@ tu6_emit_mrt(struct tu_cmd_buffer *cmd,
for (uint32_t i = 0; i < subpass->color_count; ++i) {
uint32_t a = subpass->color_attachments[i].attachment;
- if (a == VK_ATTACHMENT_UNUSED)
+ if (a == VK_ATTACHMENT_UNUSED) {
+ /* From the VkPipelineRenderingCreateInfo definition:
+ *
+ * Valid formats indicate that an attachment can be used - but it
+ * is still valid to set the attachment to NULL when beginning
+ * rendering.
+ *
+ * This means that with dynamic rendering, pipelines may write to
+ * some attachments that are UNUSED here. Setting the format to 0
+ * here should prevent them from writing to anything.
+ */
+ tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_BUF_INFO(i), 6);
+ for (unsigned i = 0; i < 6; i++)
+ tu_cs_emit(cs, 0);
continue;
+ }
const struct tu_image_view *iview = cmd->state.attachments[a];
@@ -1770,10 +1784,18 @@ tu_BeginCommandBuffer(VkCommandBuffer commandBuffer,
}
if (pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) {
- cmd_buffer->state.pass = tu_render_pass_from_handle(pBeginInfo->pInheritanceInfo->renderPass);
- cmd_buffer->state.subpass =
- &cmd_buffer->state.pass->subpasses[pBeginInfo->pInheritanceInfo->subpass];
-
+ if (pBeginInfo->pInheritanceInfo->renderPass) {
+ cmd_buffer->state.pass = tu_render_pass_from_handle(pBeginInfo->pInheritanceInfo->renderPass);
+ cmd_buffer->state.subpass =
+ &cmd_buffer->state.pass->subpasses[pBeginInfo->pInheritanceInfo->subpass];
+ } else {
+ const VkCommandBufferInheritanceRenderingInfo *rendering_info =
+ vk_find_struct_const(pBeginInfo->pInheritanceInfo->pNext,
+ COMMAND_BUFFER_INHERITANCE_RENDERING_INFO);
+ tu_setup_dynamic_inheritance(cmd_buffer, rendering_info);
+ cmd_buffer->state.pass = &cmd_buffer->dynamic_pass;
+ cmd_buffer->state.subpass = &cmd_buffer->dynamic_subpass;
+ }
tu_lrz_begin_secondary_cmdbuf(cmd_buffer);
} else {
/* When executing in the middle of another command buffer, the CCU
@@ -3590,6 +3612,85 @@ tu_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,
tu_emit_subpass_begin(cmd);
}
+VKAPI_ATTR void VKAPI_CALL
+tu_CmdBeginRendering(VkCommandBuffer commandBuffer,
+ const VkRenderingInfo *pRenderingInfo)
+{
+ TU_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer);
+ VkClearValue clear_values[2 * (MAX_RTS + 1)];
+
+ tu_setup_dynamic_render_pass(cmd, pRenderingInfo);
+ tu_setup_dynamic_framebuffer(cmd, pRenderingInfo);
+
+ cmd->state.pass = &cmd->dynamic_pass;
+ cmd->state.subpass = &cmd->dynamic_subpass;
+ cmd->state.framebuffer = &cmd->dynamic_framebuffer;
+ cmd->state.render_area = pRenderingInfo->renderArea;
+
+ cmd->state.attachments = cmd->dynamic_attachments;
+
+ cmd->state.draw_cs_writes_to_cond_pred = false;
+
+ for (unsigned i = 0; i < pRenderingInfo->colorAttachmentCount; i++) {
+ uint32_t a = cmd->dynamic_subpass.color_attachments[i].attachment;
+ if (!pRenderingInfo->pColorAttachments[i].imageView)
+ continue;
+
+ TU_FROM_HANDLE(tu_image_view, view,
+ pRenderingInfo->pColorAttachments[i].imageView);
+ cmd->state.attachments[a] = view;
+ clear_values[a] = pRenderingInfo->pColorAttachments[i].clearValue;
+
+ a = cmd->dynamic_subpass.resolve_attachments[i].attachment;
+ if (a != VK_ATTACHMENT_UNUSED) {
+ TU_FROM_HANDLE(tu_image_view, resolve_view,
+ pRenderingInfo->pColorAttachments[i].resolveImageView);
+ cmd->state.attachments[a] = resolve_view;
+ }
+ }
+
+ uint32_t a = cmd->dynamic_subpass.depth_stencil_attachment.attachment;
+ if (pRenderingInfo->pDepthAttachment || pRenderingInfo->pStencilAttachment) {
+ const struct VkRenderingAttachmentInfo *common_info =
+ (pRenderingInfo->pDepthAttachment &&
+ pRenderingInfo->pDepthAttachment->imageView != VK_NULL_HANDLE) ?
+ pRenderingInfo->pDepthAttachment :
+ pRenderingInfo->pStencilAttachment;
+ if (common_info && common_info->imageView != VK_NULL_HANDLE) {
+ TU_FROM_HANDLE(tu_image_view, view, common_info->imageView);
+ cmd->state.attachments[a] = view;
+ if (pRenderingInfo->pDepthAttachment) {
+ clear_values[a].depthStencil.depth =
+ pRenderingInfo->pDepthAttachment->clearValue.depthStencil.depth;
+ }
+
+ if (pRenderingInfo->pStencilAttachment) {
+ clear_values[a].depthStencil.stencil =
+ pRenderingInfo->pStencilAttachment->clearValue.depthStencil.stencil;
+ }
+
+ if (cmd->dynamic_subpass.resolve_count >
+ cmd->dynamic_subpass.color_count) {
+ TU_FROM_HANDLE(tu_image_view, resolve_view,
+ common_info->resolveImageView);
+ a = cmd->dynamic_subpass.resolve_attachments[cmd->dynamic_subpass.color_count].attachment;
+ cmd->state.attachments[a] = resolve_view;
+ }
+ }
+ }
+
+ cmd->state.renderpass_cache.pending_flush_bits =
+ cmd->state.cache.pending_flush_bits;
+ cmd->state.renderpass_cache.flush_bits = 0;
+
+ trace_start_render_pass(&cmd->trace, &cmd->cs);
+
+ cmd->trace_renderpass_start = u_trace_end_iterator(&cmd->trace);
+
+ tu_emit_renderpass_begin(cmd, clear_values);
+ tu_emit_subpass_begin(cmd);
+}
+
VKAPI_ATTR void VKAPI_CALL
tu_CmdNextSubpass2(VkCommandBuffer commandBuffer,
const VkSubpassBeginInfo *pSubpassBeginInfo,
@@ -4698,12 +4799,9 @@ tu_CmdDispatchIndirect(VkCommandBuffer commandBuffer,
tu_dispatch(cmd_buffer, &info);
}
-VKAPI_ATTR void VKAPI_CALL
-tu_CmdEndRenderPass2(VkCommandBuffer commandBuffer,
- const VkSubpassEndInfo *pSubpassEndInfo)
+static void
+tu_end_rendering(struct tu_cmd_buffer *cmd_buffer)
{
- TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
-
tu_cs_end(&cmd_buffer->draw_cs);
tu_cs_end(&cmd_buffer->draw_epilogue_cs);
@@ -4731,12 +4829,6 @@ tu_CmdEndRenderPass2(VkCommandBuffer commandBuffer,
tu_cs_discard_entries(&cmd_buffer->draw_epilogue_cs);
tu_cs_begin(&cmd_buffer->draw_epilogue_cs);
- cmd_buffer->state.cache.pending_flush_bits |=
- cmd_buffer->state.renderpass_cache.pending_flush_bits;
- tu_subpass_barrier(cmd_buffer, &cmd_buffer->state.pass->end_barrier, true);
-
- vk_free(&cmd_buffer->pool->vk.alloc, cmd_buffer->state.attachments);
-
cmd_buffer->state.pass = NULL;
cmd_buffer->state.subpass = NULL;
cmd_buffer->state.framebuffer = NULL;
@@ -4754,6 +4846,29 @@ tu_CmdEndRenderPass2(VkCommandBuffer commandBuffer,
cmd_buffer->state.dirty |= TU_CMD_DIRTY_LRZ;
}
+VKAPI_ATTR void VKAPI_CALL
+tu_CmdEndRenderPass2(VkCommandBuffer commandBuffer,
+ const VkSubpassEndInfo *pSubpassEndInfo)
+{
+ TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
+
+ tu_end_rendering(cmd_buffer);
+
+ cmd_buffer->state.cache.pending_flush_bits |=
+ cmd_buffer->state.renderpass_cache.pending_flush_bits;
+ tu_subpass_barrier(cmd_buffer, &cmd_buffer->state.pass->end_barrier, true);
+
+ vk_free(&cmd_buffer->pool->vk.alloc, cmd_buffer->state.attachments);
+}
+
+VKAPI_ATTR void VKAPI_CALL
+tu_CmdEndRendering(VkCommandBuffer commandBuffer)
+{
+ TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
+
+ tu_end_rendering(cmd_buffer);
+}
+
static void
tu_barrier(struct tu_cmd_buffer *cmd,
const VkDependencyInfo *dep_info)
diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c
index 4dccc2f033e..1986701c796 100644
--- a/src/freedreno/vulkan/tu_device.c
+++ b/src/freedreno/vulkan/tu_device.c
@@ -2628,6 +2628,23 @@ tu_CreateFramebuffer(VkDevice _device,
return VK_SUCCESS;
}
+void
+tu_setup_dynamic_framebuffer(struct tu_cmd_buffer *cmd_buffer,
+ const VkRenderingInfo *pRenderingInfo)
+{
+ struct tu_render_pass *pass = &cmd_buffer->dynamic_pass;
+ struct tu_framebuffer *framebuffer = &cmd_buffer->dynamic_framebuffer;
+
+ framebuffer->attachment_count = pass->attachment_count;
+ framebuffer->width = pRenderingInfo->renderArea.offset.x +
+ pRenderingInfo->renderArea.extent.width;
+ framebuffer->height = pRenderingInfo->renderArea.offset.y +
+ pRenderingInfo->renderArea.extent.height;
+ framebuffer->layers = pRenderingInfo->layerCount;
+
+ tu_framebuffer_tiling_config(framebuffer, cmd_buffer->device, pass);
+}
+
VKAPI_ATTR void VKAPI_CALL
tu_DestroyFramebuffer(VkDevice _device,
VkFramebuffer _fb,
diff --git a/src/freedreno/vulkan/tu_image.c b/src/freedreno/vulkan/tu_image.c
index bf892ccbdf8..d04b4860ebf 100644
--- a/src/freedreno/vulkan/tu_image.c
+++ b/src/freedreno/vulkan/tu_image.c
@@ -180,6 +180,7 @@ tu_image_view_init(struct tu_image_view *iview,
vk_find_struct_const(pCreateInfo->pNext, IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT);
iview->image = image;
+ iview->format = pCreateInfo->format;
const struct fdl_layout *layouts[3];
diff --git a/src/freedreno/vulkan/tu_pass.c b/src/freedreno/vulkan/tu_pass.c
index 7eab7ad4a5c..97838d639af 100644
--- a/src/freedreno/vulkan/tu_pass.c
+++ b/src/freedreno/vulkan/tu_pass.c
@@ -523,6 +523,19 @@ static void update_samples(struct tu_subpass *subpass,
subpass->samples = samples;
}
+static void
+tu_render_pass_cond_config(struct tu_render_pass *pass)
+{
+ for (uint32_t i = 0; i < pass->attachment_count; i++) {
+ struct tu_render_pass_attachment *att = &pass->attachments[i];
+
+ att->cond_load_allowed =
+ (att->load || att->load_stencil) && !att->clear_mask && !att->will_be_resolved;
+ att->cond_store_allowed =
+ (att->store || att->store_stencil) && !att->clear_mask;
+ }
+}
+
static void
tu_render_pass_gmem_config(struct tu_render_pass *pass,
const struct tu_physical_device *phys_dev)
@@ -626,6 +639,32 @@ tu_render_pass_gmem_config(struct tu_render_pass *pass,
pass->gmem_pixels = pixels;
}
+static void
+tu_render_pass_bandwidth_config(struct tu_render_pass *pass)
+{
+ for (uint32_t i = 0; i < pass->attachment_count; i++) {
+ const struct tu_render_pass_attachment *att = &pass->attachments[i];
+
+ /* approximate tu_load_gmem_attachment */
+ if (att->load)
+ pass->gmem_bandwidth_per_pixel += att->cpp;
+
+ /* approximate tu_store_gmem_attachment */
+ if (att->store)
+ pass->gmem_bandwidth_per_pixel += att->cpp;
+
+ /* approximate tu_clear_sysmem_attachment */
+ if (att->clear_mask)
+ pass->sysmem_bandwidth_per_pixel += att->cpp;
+
+ /* approximate tu6_emit_sysmem_resolves */
+ if (att->will_be_resolved) {
+ pass->sysmem_bandwidth_per_pixel +=
+ att->cpp + att->cpp / att->samples;
+ }
+ }
+}
+
static void
attachment_set_ops(struct tu_device *device,
struct tu_render_pass_attachment *att,
@@ -876,36 +915,11 @@ tu_CreateRenderPass2(VkDevice _device,
att->clear_mask = 0;
att->load = false;
}
-
- att->cond_load_allowed =
- (att->load || att->load_stencil) && !att->clear_mask && !att->will_be_resolved;
- att->cond_store_allowed =
- (att->store || att->store_stencil) && !att->clear_mask;
}
+ tu_render_pass_cond_config(pass);
tu_render_pass_gmem_config(pass, device->physical_device);
-
- for (uint32_t i = 0; i < pass->attachment_count; i++) {
- const struct tu_render_pass_attachment *att = &pass->attachments[i];
-
- /* approximate tu_load_gmem_attachment */
- if (att->load)
- pass->gmem_bandwidth_per_pixel += att->cpp;
-
- /* approximate tu_store_gmem_attachment */
- if (att->store)
- pass->gmem_bandwidth_per_pixel += att->cpp;
-
- /* approximate tu_clear_sysmem_attachment */
- if (att->clear_mask)
- pass->sysmem_bandwidth_per_pixel += att->cpp;
-
- /* approximate tu6_emit_sysmem_resolves */
- if (att->will_be_resolved) {
- pass->sysmem_bandwidth_per_pixel +=
- att->cpp + att->cpp / att->samples;
- }
- }
+ tu_render_pass_bandwidth_config(pass);
for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) {
tu_render_pass_add_subpass_dep(pass, &pCreateInfo->pDependencies[i]);
@@ -933,6 +947,197 @@ tu_DestroyRenderPass(VkDevice _device,
vk_object_free(&device->vk, pAllocator, pass);
}
+static void
+tu_setup_dynamic_attachment(struct tu_render_pass_attachment *att,
+ struct tu_image_view *view)
+{
+ att->format = view->format;
+ att->samples = view->image->layout->nr_samples;
+
+ /* for d32s8, cpp is for the depth image, and
+ * att->samples will be used as the cpp for the stencil image
+ */
+ if (att->format == VK_FORMAT_D32_SFLOAT_S8_UINT)
+ att->cpp = 4 * att->samples;
+ else
+ att->cpp = vk_format_get_blocksize(att->format) * att->samples;
+}
+
+void
+tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer,
+ const VkRenderingInfo *info)
+{
+ struct tu_device *device = cmd_buffer->device;
+ struct tu_render_pass *pass = &cmd_buffer->dynamic_pass;
+ struct tu_subpass *subpass = &cmd_buffer->dynamic_subpass;
+
+ pass->subpass_count = 1;
+ pass->attachments = cmd_buffer->dynamic_rp_attachments;
+
+ subpass->color_count = subpass->resolve_count = info->colorAttachmentCount;
+ subpass->color_attachments = cmd_buffer->dynamic_color_attachments;
+ subpass->resolve_attachments = cmd_buffer->dynamic_resolve_attachments;
+ subpass->feedback_invalidate = false;
+ subpass->feedback_loop_ds = subpass->feedback_loop_color = false;
+ subpass->input_count = 0;
+ subpass->samples = 0;
+ subpass->srgb_cntl = 0;
+ subpass->raster_order_attachment_access = false;
+ subpass->multiview_mask = info->viewMask;
+
+ uint32_t a = 0;
+ for (uint32_t i = 0; i < info->colorAttachmentCount; i++) {
+ struct tu_render_pass_attachment *att = &pass->attachments[a];
+ const VkRenderingAttachmentInfo *att_info = &info->pColorAttachments[i];
+
+ if (att_info->imageView == VK_NULL_HANDLE) {
+ subpass->color_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
+ subpass->resolve_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
+ continue;
+ }
+
+ TU_FROM_HANDLE(tu_image_view, view, att_info->imageView);
+ tu_setup_dynamic_attachment(att, view);
+ att->gmem_offset = 0;
+ att->clear_views = info->viewMask;
+ attachment_set_ops(device, att, att_info->loadOp, 0,
+ att_info->storeOp, 0);
+ subpass->color_attachments[i].attachment = a++;
+
+ subpass->samples = view->image->layout->nr_samples;
+
+ if (vk_format_is_srgb(view->format))
+ subpass->srgb_cntl |= 1 << i;
+
+ if (att_info->resolveMode != VK_RESOLVE_MODE_NONE) {
+ struct tu_render_pass_attachment *resolve_att = &pass->attachments[a];
+ TU_FROM_HANDLE(tu_image_view, resolve_view, att_info->resolveImageView);
+ tu_setup_dynamic_attachment(resolve_att, resolve_view);
+ resolve_att->gmem_offset = -1;
+ attachment_set_ops(device, resolve_att,
+ VK_ATTACHMENT_LOAD_OP_DONT_CARE, 0,
+ VK_ATTACHMENT_STORE_OP_STORE, 0);
+ subpass->resolve_attachments[i].attachment = a++;
+ att->will_be_resolved = true;
+ } else {
+ subpass->resolve_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
+ att->will_be_resolved = false;
+ }
+ }
+
+ if (info->pDepthAttachment || info->pStencilAttachment) {
+ const struct VkRenderingAttachmentInfo *common_info =
+ (info->pDepthAttachment &&
+ info->pDepthAttachment->imageView != VK_NULL_HANDLE) ?
+ info->pDepthAttachment :
+ info->pStencilAttachment;
+
+ if (common_info && common_info->imageView != VK_NULL_HANDLE) {
+ TU_FROM_HANDLE(tu_image_view, view, common_info->imageView);
+
+ struct tu_render_pass_attachment *att = &pass->attachments[a];
+ tu_setup_dynamic_attachment(att, view);
+ att->gmem_offset = 0;
+ att->clear_views = info->viewMask;
+ subpass->depth_stencil_attachment.attachment = a++;
+
+ attachment_set_ops(device, att,
+ info->pDepthAttachment ? info->pDepthAttachment->loadOp : 0,
+ info->pStencilAttachment ? info->pStencilAttachment->loadOp : 0,
+ info->pDepthAttachment ? info->pDepthAttachment->storeOp : 0,
+ info->pStencilAttachment ? info->pStencilAttachment->storeOp : 0);
+
+ subpass->samples = view->image->layout->nr_samples;
+
+ if (common_info->resolveMode != VK_RESOLVE_MODE_NONE) {
+ unsigned i = subpass->resolve_count++;
+ struct tu_render_pass_attachment *resolve_att = &pass->attachments[a];
+ TU_FROM_HANDLE(tu_image_view, resolve_view,
+ common_info->resolveImageView);
+ tu_setup_dynamic_attachment(resolve_att, resolve_view);
+ resolve_att->gmem_offset = -1;
+ attachment_set_ops(device, resolve_att,
+ VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+ VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+ VK_ATTACHMENT_STORE_OP_STORE,
+ VK_ATTACHMENT_STORE_OP_STORE);
+ subpass->resolve_attachments[i].attachment = a++;
+ att->will_be_resolved = true;
+ subpass->resolve_depth_stencil = true;
+ } else {
+ att->will_be_resolved = false;
+ }
+ } else {
+ subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;
+ }
+ } else {
+ subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;
+ }
+
+ pass->attachment_count = a;
+
+ tu_render_pass_cond_config(pass);
+ tu_render_pass_gmem_config(pass, device->physical_device);
+ tu_render_pass_bandwidth_config(pass);
+}
+
+void
+tu_setup_dynamic_inheritance(struct tu_cmd_buffer *cmd_buffer,
+ const VkCommandBufferInheritanceRenderingInfo *info)
+{
+ struct tu_render_pass *pass = &cmd_buffer->dynamic_pass;
+ struct tu_subpass *subpass = &cmd_buffer->dynamic_subpass;
+
+ pass->subpass_count = 1;
+ pass->attachments = cmd_buffer->dynamic_rp_attachments;
+
+ subpass->color_count = info->colorAttachmentCount;
+ subpass->resolve_count = 0;
+ subpass->color_attachments = cmd_buffer->dynamic_color_attachments;
+ subpass->resolve_attachments = NULL;
+ subpass->feedback_invalidate = false;
+ subpass->feedback_loop_ds = subpass->feedback_loop_color = false;
+ subpass->input_count = 0;
+ subpass->samples = 0;
+ subpass->srgb_cntl = 0;
+ subpass->raster_order_attachment_access = false;
+ subpass->multiview_mask = info->viewMask;
+ subpass->samples = info->rasterizationSamples;
+
+ unsigned a = 0;
+ for (unsigned i = 0; i < info->colorAttachmentCount; i++) {
+ struct tu_render_pass_attachment *att = &pass->attachments[a];
+ VkFormat format = info->pColorAttachmentFormats[i];
+
+ if (format == VK_FORMAT_UNDEFINED) {
+ subpass->color_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
+ continue;
+ }
+
+ att->format = format;
+ att->samples = info->rasterizationSamples;
+ subpass->samples = info->rasterizationSamples;
+ subpass->color_attachments[i].attachment = a++;
+
+ /* conservatively assume that the attachment may be conditionally
+ * loaded/stored.
+ */
+ att->cond_load_allowed = att->cond_store_allowed = true;
+ }
+
+ if (info->depthAttachmentFormat != VK_FORMAT_UNDEFINED ||
+ info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED) {
+ struct tu_render_pass_attachment *att = &pass->attachments[a];
+ att->format = info->depthAttachmentFormat != VK_FORMAT_UNDEFINED ?
+ info->depthAttachmentFormat : info->stencilAttachmentFormat;
+ att->samples = info->rasterizationSamples;
+ subpass->depth_stencil_attachment.attachment = a++;
+ att->cond_load_allowed = att->cond_store_allowed = true;
+ } else {
+ subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;
+ }
+}
+
VKAPI_ATTR void VKAPI_CALL
tu_GetRenderAreaGranularity(VkDevice _device,
VkRenderPass renderPass,
diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c
index bdda536fbb8..90acc12a3f2 100644
--- a/src/freedreno/vulkan/tu_pipeline.c
+++ b/src/freedreno/vulkan/tu_pipeline.c
@@ -3890,24 +3890,85 @@ tu_pipeline_builder_init_graphics(
}
}
- const struct tu_render_pass *pass =
- tu_render_pass_from_handle(create_info->renderPass);
- const struct tu_subpass *subpass =
- &pass->subpasses[create_info->subpass];
-
- builder->subpass_raster_order_attachment_access =
- subpass->raster_order_attachment_access;
- builder->subpass_feedback_loop_color = subpass->feedback_loop_color;
- builder->subpass_feedback_loop_ds = subpass->feedback_loop_ds;
-
- builder->multiview_mask = subpass->multiview_mask;
-
builder->rasterizer_discard =
builder->create_info->pRasterizationState->rasterizerDiscardEnable &&
!rasterizer_discard_dynamic;
- /* variableMultisampleRate support */
- builder->emit_msaa_state = (subpass->samples == 0) && !builder->rasterizer_discard;
+ const VkPipelineRenderingCreateInfo *rendering_info =
+ vk_find_struct_const(create_info->pNext, PIPELINE_RENDERING_CREATE_INFO);
+
+ if (rendering_info) {
+ builder->subpass_raster_order_attachment_access = false;
+ builder->subpass_feedback_loop_ds = false;
+ builder->subpass_feedback_loop_color = false;
+
+ builder->multiview_mask = rendering_info->viewMask;
+
+ /* We don't know with dynamic rendering whether the pipeline will be
+ * used in a render pass with none of attachments enabled, so we have to
+ * dynamically emit MSAA state.
+ *
+ * TODO: Move MSAA state to a separate draw state and emit it
+ * dynamically only when the sample count is different from the
+ * subpass's sample count.
+ */
+ builder->emit_msaa_state = !builder->rasterizer_discard;
+
+ if (!builder->rasterizer_discard) {
+ builder->depth_attachment_format =
+ rendering_info->depthAttachmentFormat == VK_FORMAT_UNDEFINED ?
+ rendering_info->stencilAttachmentFormat :
+ rendering_info->depthAttachmentFormat;
+
+ builder->color_attachment_count =
+ rendering_info->colorAttachmentCount;
+
+ for (unsigned i = 0; i < rendering_info->colorAttachmentCount; i++) {
+ builder->color_attachment_formats[i] =
+ rendering_info->pColorAttachmentFormats[i];
+ if (builder->color_attachment_formats[i] != VK_FORMAT_UNDEFINED) {
+ builder->use_color_attachments = true;
+ builder->render_components |= 0xf << (i * 4);
+ }
+ }
+ }
+ } else {
+ const struct tu_render_pass *pass =
+ tu_render_pass_from_handle(create_info->renderPass);
+ const struct tu_subpass *subpass =
+ &pass->subpasses[create_info->subpass];
+
+ builder->subpass_raster_order_attachment_access =
+ subpass->raster_order_attachment_access;
+ builder->subpass_feedback_loop_color = subpass->feedback_loop_color;
+ builder->subpass_feedback_loop_ds = subpass->feedback_loop_ds;
+
+ builder->multiview_mask = subpass->multiview_mask;
+
+ /* variableMultisampleRate support */
+ builder->emit_msaa_state = (subpass->samples == 0) && !builder->rasterizer_discard;
+
+ if (!builder->rasterizer_discard) {
+ const uint32_t a = subpass->depth_stencil_attachment.attachment;
+ builder->depth_attachment_format = (a != VK_ATTACHMENT_UNUSED) ?
+ pass->attachments[a].format : VK_FORMAT_UNDEFINED;
+
+ assert(subpass->color_count == 0 ||
+ !create_info->pColorBlendState ||
+ subpass->color_count == create_info->pColorBlendState->attachmentCount);
+ builder->color_attachment_count = subpass->color_count;
+ for (uint32_t i = 0; i < subpass->color_count; i++) {
+ const uint32_t a = subpass->color_attachments[i].attachment;
+ if (a == VK_ATTACHMENT_UNUSED)
+ continue;
+
+ builder->color_attachment_formats[i] = pass->attachments[a].format;
+ builder->use_color_attachments = true;
+ builder->render_components |= 0xf << (i * 4);
+ }
+ }
+ }
+
if (builder->rasterizer_discard) {
builder->samples = VK_SAMPLE_COUNT_1_BIT;
@@ -3915,29 +3976,11 @@ tu_pipeline_builder_init_graphics(
builder->samples = create_info->pMultisampleState->rasterizationSamples;
builder->alpha_to_coverage = create_info->pMultisampleState->alphaToCoverageEnable;
- const uint32_t a = subpass->depth_stencil_attachment.attachment;
- builder->depth_attachment_format = (a != VK_ATTACHMENT_UNUSED) ?
- pass->attachments[a].format : VK_FORMAT_UNDEFINED;
-
- assert(subpass->color_count == 0 ||
- !create_info->pColorBlendState ||
- subpass->color_count == create_info->pColorBlendState->attachmentCount);
- builder->color_attachment_count = subpass->color_count;
- for (uint32_t i = 0; i < subpass->color_count; i++) {
- const uint32_t a = subpass->color_attachments[i].attachment;
- if (a == VK_ATTACHMENT_UNUSED)
- continue;
-
- builder->color_attachment_formats[i] = pass->attachments[a].format;
- builder->use_color_attachments = true;
- builder->render_components |= 0xf << (i * 4);
- }
-
if (tu_blend_state_is_dual_src(create_info->pColorBlendState)) {
builder->color_attachment_count++;
builder->use_dual_src_blend = true;
/* dual source blending has an extra fs output in the 2nd slot */
- if (subpass->color_attachments[0].attachment != VK_ATTACHMENT_UNUSED)
+ if (builder->color_attachment_formats[0] != VK_FORMAT_UNDEFINED)
builder->render_components |= 0xf << 4;
}
}
diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h
index 7eeef5c0f2f..f835874bcf7 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -1459,6 +1459,15 @@ struct tu_cmd_buffer
struct tu_descriptor_state descriptors[MAX_BIND_POINTS];
+ struct tu_render_pass_attachment dynamic_rp_attachments[2 * (MAX_RTS + 1)];
+ struct tu_subpass_attachment dynamic_color_attachments[MAX_RTS];
+ struct tu_subpass_attachment dynamic_resolve_attachments[MAX_RTS + 1];
+ const struct tu_image_view *dynamic_attachments[2 * (MAX_RTS + 1)];
+
+ struct tu_render_pass dynamic_pass;
+ struct tu_subpass dynamic_subpass;
+ struct tu_framebuffer dynamic_framebuffer;
+
VkResult record_result;
struct tu_cs cs;
@@ -1492,6 +1501,15 @@ void tu_emit_cache_flush_ccu(struct tu_cmd_buffer *cmd_buffer,
struct tu_cs *cs,
enum tu_cmd_ccu_state ccu_state);
+void tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer,
+ const VkRenderingInfo *pRenderingInfo);
+
+void tu_setup_dynamic_inheritance(struct tu_cmd_buffer *cmd_buffer,
+ const VkCommandBufferInheritanceRenderingInfo *info);
+
+void tu_setup_dynamic_framebuffer(struct tu_cmd_buffer *cmd_buffer,
+ const VkRenderingInfo *pRenderingInfo);
+
void
tu6_emit_event_write(struct tu_cmd_buffer *cmd,
struct tu_cs *cs,
@@ -1936,6 +1954,8 @@ struct tu_image_view
struct tu_image *image; /**< VkImageViewCreateInfo::image */
+ VkFormat format;
+
struct fdl6_view view;
/* for d32s8 separate depth */
More information about the mesa-commit
mailing list