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>
This commit is contained in:
parent
22be08a21e
commit
ed125e6cca
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue