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:
Connor Abbott 2022-06-28 10:33:01 +02:00 committed by Marge Bot
parent 22be08a21e
commit ed125e6cca
6 changed files with 477 additions and 76 deletions

View File

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

View File

@ -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,

View File

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

View File

@ -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,

View File

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

View File

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