diff --git a/src/freedreno/vulkan/tu_cmd_buffer.cc b/src/freedreno/vulkan/tu_cmd_buffer.cc index b61e105ff86..17b60c99c65 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.cc +++ b/src/freedreno/vulkan/tu_cmd_buffer.cc @@ -4400,7 +4400,7 @@ tu_BeginCommandBuffer(VkCommandBuffer commandBuffer, if (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; + cmd_buffer->state.subpass = &cmd_buffer->dynamic_subpasses[0]; const VkRenderingAttachmentLocationInfoKHR *location_info = vk_find_struct_const(pBeginInfo->pInheritanceInfo->pNext, @@ -6864,7 +6864,7 @@ tu_CmdBeginRendering(VkCommandBuffer commandBuffer, tu_setup_dynamic_framebuffer(cmd, pRenderingInfo); cmd->state.pass = &cmd->dynamic_pass; - cmd->state.subpass = &cmd->dynamic_subpass; + cmd->state.subpass = &cmd->dynamic_subpasses[0]; cmd->state.framebuffer = &cmd->dynamic_framebuffer; cmd->state.render_area = pRenderingInfo->renderArea; cmd->state.fdm_per_layer = @@ -6877,7 +6877,7 @@ tu_CmdBeginRendering(VkCommandBuffer commandBuffer, for (unsigned i = 0; i < pRenderingInfo->colorAttachmentCount; i++) { if (!pRenderingInfo->pColorAttachments[i].imageView) continue; - uint32_t a = cmd->dynamic_subpass.color_attachments[i].attachment; + uint32_t a = cmd->dynamic_subpasses[0].color_attachments[i].attachment; cmd->state.clear_values[a] = pRenderingInfo->pColorAttachments[i].clearValue; @@ -6897,7 +6897,12 @@ tu_CmdBeginRendering(VkCommandBuffer commandBuffer, pRenderingInfo->pColorAttachments[i].imageView); cmd->state.attachments[a] = view; - a = cmd->dynamic_subpass.resolve_attachments[i].attachment; + if (cmd->dynamic_pass.subpass_count > 1) { + a = cmd->dynamic_subpasses[1].color_attachments[i].attachment; + } else { + a = cmd->dynamic_subpasses[0].resolve_attachments[i].attachment; + } + if (!msrtss && a != VK_ATTACHMENT_UNUSED) { VK_FROM_HANDLE(tu_image_view, resolve_view, pRenderingInfo->pColorAttachments[i].resolveImageView); @@ -6905,7 +6910,7 @@ tu_CmdBeginRendering(VkCommandBuffer commandBuffer, } } - uint32_t a = cmd->dynamic_subpass.depth_stencil_attachment.attachment; + uint32_t a = cmd->dynamic_subpasses[0].depth_stencil_attachment.attachment; if (pRenderingInfo->pDepthAttachment || pRenderingInfo->pStencilAttachment) { const struct VkRenderingAttachmentInfo *common_info = (pRenderingInfo->pDepthAttachment && @@ -6932,13 +6937,22 @@ tu_CmdBeginRendering(VkCommandBuffer commandBuffer, cmd->state.attachments[a] = view; - if (!msrtss && cmd->dynamic_subpass.resolve_count > - cmd->dynamic_subpass.color_count) { + if (!msrtss && cmd->dynamic_subpasses[0].resolve_count > + cmd->dynamic_subpasses[0].color_count) { VK_FROM_HANDLE(tu_image_view, resolve_view, common_info->resolveImageView); - a = cmd->dynamic_subpass.resolve_attachments[cmd->dynamic_subpass.color_count].attachment; + a = cmd->dynamic_subpasses[0].resolve_attachments[cmd->dynamic_subpasses[0].color_count].attachment; cmd->state.attachments[a] = resolve_view; } + + if (cmd->dynamic_pass.subpass_count > 1) { + a = cmd->dynamic_subpasses[1].depth_stencil_attachment.attachment; + if (a != VK_ATTACHMENT_UNUSED) { + VK_FROM_HANDLE(tu_image_view, resolve_view, + common_info->resolveImageView); + cmd->state.attachments[a] = resolve_view; + } + } } } @@ -6959,7 +6973,7 @@ tu_CmdBeginRendering(VkCommandBuffer commandBuffer, cmd->patchpoints_ctx = ralloc_context(NULL); - a = cmd->dynamic_subpass.fsr_attachment; + a = cmd->dynamic_subpasses[0].fsr_attachment; if (a != VK_ATTACHMENT_UNUSED) { const VkRenderingFragmentShadingRateAttachmentInfoKHR *fsr_info = vk_find_struct_const(pRenderingInfo->pNext, @@ -7087,7 +7101,7 @@ tu_CmdSetRenderingInputAttachmentIndicesKHR( const struct vk_input_attachment_location_state *ial = &cmd->vk.dynamic_graphics_state.ial; - struct tu_subpass *subpass = &cmd->dynamic_subpass; + struct tu_subpass *subpass = &cmd->dynamic_subpasses[0]; for (unsigned i = 0; i < ARRAY_SIZE(cmd->dynamic_input_attachments); i++) { subpass->input_attachments[i].attachment = VK_ATTACHMENT_UNUSED; @@ -7128,7 +7142,23 @@ tu_CmdSetRenderingInputAttachmentIndicesKHR( subpass->input_count = input_count; - tu_set_input_attachments(cmd, cmd->state.subpass); + tu_set_input_attachments(cmd, subpass); +} + +static void +tu_next_subpass_lrz(struct tu_cmd_buffer *cmd, + const struct tu_subpass *subpass, + const struct tu_subpass *new_subpass) +{ + /* Track LRZ valid state + * + * TODO: Improve this tracking for keeping the state of the past depth/stencil images, + * so if they become active again, we reuse its old state. + */ + if (new_subpass->depth_stencil_attachment.attachment != subpass->depth_stencil_attachment.attachment) { + cmd->state.lrz.valid = false; + cmd->state.dirty |= TU_CMD_DIRTY_LRZ; + } } template @@ -7150,15 +7180,7 @@ tu_CmdNextSubpass2(VkCommandBuffer commandBuffer, const struct tu_subpass *subpass = cmd->state.subpass++; const struct tu_subpass *new_subpass = cmd->state.subpass; - /* Track LRZ valid state - * - * TODO: Improve this tracking for keeping the state of the past depth/stencil images, - * so if they become active again, we reuse its old state. - */ - if (new_subpass->depth_stencil_attachment.attachment != subpass->depth_stencil_attachment.attachment) { - cmd->state.lrz.valid = false; - cmd->state.dirty |= TU_CMD_DIRTY_LRZ; - } + tu_next_subpass_lrz(cmd, subpass, new_subpass); if (cmd->state.tiling->possible) { if (cmd->state.pass->has_fdm) @@ -7198,6 +7220,24 @@ tu_CmdNextSubpass2(VkCommandBuffer commandBuffer, } TU_GENX(tu_CmdNextSubpass2); +template +VKAPI_ATTR void VKAPI_CALL +tu_CmdBeginCustomResolveEXT(VkCommandBuffer commandBuffer, + const VkBeginCustomResolveInfoEXT *pBeginShaderResolveInfo) +{ + VK_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer); + + const struct tu_subpass *subpass = &cmd->dynamic_subpasses[0]; + + const struct tu_subpass *new_subpass = &cmd->dynamic_subpasses[1]; + cmd->state.subpass = new_subpass; + + tu_next_subpass_lrz(cmd, subpass, new_subpass); + + tu_emit_subpass_begin(cmd); +} +TU_GENX(tu_CmdBeginCustomResolveEXT); + static uint32_t tu6_user_consts_size(const struct tu_const_state *const_state, bool ldgk, diff --git a/src/freedreno/vulkan/tu_cmd_buffer.h b/src/freedreno/vulkan/tu_cmd_buffer.h index f83948a74b6..4e974e12827 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.h +++ b/src/freedreno/vulkan/tu_cmd_buffer.h @@ -684,7 +684,7 @@ struct tu_cmd_buffer struct tu_image dynamic_msrtss_images[MAX_RTS + 1]; struct tu_render_pass dynamic_pass; - struct tu_subpass dynamic_subpass; + struct tu_subpass dynamic_subpasses[2]; struct tu_framebuffer dynamic_framebuffer; struct tu_cs cs; diff --git a/src/freedreno/vulkan/tu_device.cc b/src/freedreno/vulkan/tu_device.cc index 036088a8fdb..5e58614fa4c 100644 --- a/src/freedreno/vulkan/tu_device.cc +++ b/src/freedreno/vulkan/tu_device.cc @@ -270,6 +270,7 @@ get_device_extensions(const struct tu_physical_device *device, .EXT_conditional_rendering = true, .EXT_conservative_rasterization = device->info->chip >= 7, .EXT_custom_border_color = true, + .EXT_custom_resolve = true, .EXT_depth_clamp_zero_one = true, .EXT_depth_clip_control = true, .EXT_depth_clip_enable = true, @@ -821,6 +822,9 @@ tu_get_features(struct tu_physical_device *pdevice, /* VK_EXT_multisampled_render_to_single_sampled */ features->multisampledRenderToSingleSampled = true; + + /* VK_EXT_custom_resolve */ + features->customResolve = true; } static void @@ -955,8 +959,12 @@ tu_get_physical_device_properties_1_2(struct tu_physical_device *pdevice, p->maxDescriptorSetUpdateAfterBindStorageImages = max_descriptor_set_size; p->maxDescriptorSetUpdateAfterBindInputAttachments = MAX_RTS; - p->supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; - p->supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; + p->supportedDepthResolveModes = + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT | + VK_RESOLVE_MODE_CUSTOM_BIT_EXT; + p->supportedStencilResolveModes = + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT | + VK_RESOLVE_MODE_CUSTOM_BIT_EXT; p->independentResolveNone = false; p->independentResolve = false; diff --git a/src/freedreno/vulkan/tu_pass.cc b/src/freedreno/vulkan/tu_pass.cc index 05fe8e74f26..372689c2d5f 100644 --- a/src/freedreno/vulkan/tu_pass.cc +++ b/src/freedreno/vulkan/tu_pass.cc @@ -1184,7 +1184,7 @@ tu_CreateRenderPass2(VkDevice _device, subpass->legacy_dithering_enabled = desc->flags & VK_SUBPASS_DESCRIPTION_ENABLE_LEGACY_DITHERING_BIT_EXT; subpass->custom_resolve = desc->flags & - VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM; + VK_SUBPASS_DESCRIPTION_CUSTOM_RESOLVE_BIT_EXT; const BITMASK_ENUM(VkSubpassDescriptionFlagBits) raster_order_access_bits = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT | @@ -1399,7 +1399,8 @@ tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer, { struct tu_device *device = cmd_buffer->device; struct tu_render_pass *pass = &cmd_buffer->dynamic_pass; - struct tu_subpass *subpass = &cmd_buffer->dynamic_subpass; + struct tu_subpass *subpass = &cmd_buffer->dynamic_subpasses[0]; + struct tu_subpass *resolve_subpass = &cmd_buffer->dynamic_subpasses[1]; const VkMultisampledRenderToSingleSampledInfoEXT *msrtss = vk_find_struct_const(info->pNext, MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT); @@ -1407,16 +1408,40 @@ tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer, *pass = {}; *subpass = {}; - pass->subpass_count = 1; + if (info->flags & VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT) { + *resolve_subpass = {}; + resolve_subpass->custom_resolve = true; + resolve_subpass->samples = VK_SAMPLE_COUNT_1_BIT; + resolve_subpass->color_count = info->colorAttachmentCount; + resolve_subpass->input_count = info->colorAttachmentCount + 1; + resolve_subpass->color_attachments = cmd_buffer->dynamic_resolve_attachments; + resolve_subpass->input_attachments = cmd_buffer->dynamic_input_attachments; + resolve_subpass->multiview_mask = info->viewMask; + resolve_subpass->legacy_dithering_enabled = info->flags & + VK_RENDERING_ENABLE_LEGACY_DITHERING_BIT_EXT; + + /* These will be filled in below. */ + for (unsigned i = 0; i < info->colorAttachmentCount; i++) { + resolve_subpass->color_attachments[i].attachment = VK_ATTACHMENT_UNUSED; + } + + resolve_subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED; + pass->subpass_count = 2; + subpass->resolve_count = 0; + } else { + subpass->resolve_attachments = cmd_buffer->dynamic_resolve_attachments; + subpass->resolve_count = info->colorAttachmentCount; + pass->subpass_count = 1; + } + pass->attachments = cmd_buffer->dynamic_rp_attachments; - subpass->color_count = subpass->resolve_count = info->colorAttachmentCount; + subpass->color_count = info->colorAttachmentCount; if (msrtss) subpass->unresolve_count = info->colorAttachmentCount; subpass->input_count = info->colorAttachmentCount + 1; subpass->color_attachments = cmd_buffer->dynamic_color_attachments; subpass->input_attachments = cmd_buffer->dynamic_input_attachments; - subpass->resolve_attachments = cmd_buffer->dynamic_resolve_attachments; subpass->unresolve_attachments = cmd_buffer->dynamic_unresolve_attachments; subpass->multiview_mask = info->viewMask; subpass->legacy_dithering_enabled = info->flags & @@ -1442,7 +1467,8 @@ tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer, if (att_info->imageView == VK_NULL_HANDLE) { subpass->color_attachments[i].attachment = VK_ATTACHMENT_UNUSED; subpass->input_attachments[i + 1].attachment = VK_ATTACHMENT_UNUSED; - subpass->resolve_attachments[i].attachment = VK_ATTACHMENT_UNUSED; + if (subpass->resolve_attachments) + subpass->resolve_attachments[i].attachment = VK_ATTACHMENT_UNUSED; subpass->unresolve_attachments[i].attachment = VK_ATTACHMENT_UNUSED; continue; } @@ -1500,10 +1526,16 @@ tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer, device, resolve_att, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_STORE_OP_DONT_CARE); - subpass->resolve_attachments[i].attachment = a++; - att->will_be_resolved = true; + if (att_info->resolveMode == VK_RESOLVE_MODE_CUSTOM_BIT_EXT) { + att->will_be_resolved = false; + resolve_subpass->color_attachments[i].attachment = a++; + } else { + subpass->resolve_attachments[i].attachment = a++; + att->will_be_resolved = true; + } } else { - subpass->resolve_attachments[i].attachment = VK_ATTACHMENT_UNUSED; + if (subpass->resolve_count) + subpass->resolve_attachments[i].attachment = VK_ATTACHMENT_UNUSED; att->will_be_resolved = false; } } @@ -1584,7 +1616,6 @@ tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer, if (!att_is_msrtss) { if (common_info->resolveMode != VK_RESOLVE_MODE_NONE) { - unsigned i = subpass->resolve_count++; struct tu_render_pass_attachment *resolve_att = &pass->attachments[a]; VK_FROM_HANDLE(tu_image_view, resolve_view, common_info->resolveImageView); @@ -1596,9 +1627,15 @@ tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer, 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; + if (common_info->resolveMode == VK_RESOLVE_MODE_CUSTOM_BIT_EXT) { + resolve_subpass->depth_stencil_attachment.attachment = a++; + att->will_be_resolved = false; + } else { + unsigned i = subpass->resolve_count++; + subpass->resolve_attachments[i].attachment = a++; + att->will_be_resolved = true; + subpass->resolve_depth_stencil = true; + } } else { att->will_be_resolved = false; } @@ -1659,6 +1696,12 @@ tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer, subpass->fsr_attachment = VK_ATTACHMENT_UNUSED; } + if (info->flags & VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT) { + resolve_subpass->fsr_attachment_texel_size = + subpass->fsr_attachment_texel_size; + resolve_subpass->fsr_attachment = subpass->fsr_attachment; + } + if (TU_DEBUG(FDM) && !tu_render_pass_disable_fdm(device, pass)) pass->has_fdm = true; @@ -1746,7 +1789,11 @@ 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; + struct tu_subpass *subpass = &cmd_buffer->dynamic_subpasses[0]; + + const VkCustomResolveCreateInfoEXT *crc_info = + vk_find_struct_const(info->pNext, CUSTOM_RESOLVE_CREATE_INFO_EXT); + bool custom_resolve = crc_info && crc_info->customResolve; pass->subpass_count = 1; pass->attachments = cmd_buffer->dynamic_rp_attachments; @@ -1764,12 +1811,16 @@ tu_setup_dynamic_inheritance(struct tu_cmd_buffer *cmd_buffer, subpass->srgb_cntl = 0; subpass->raster_order_attachment_access = false; subpass->multiview_mask = info->viewMask; - subpass->samples = info->rasterizationSamples; + subpass->samples = + custom_resolve ? VK_SAMPLE_COUNT_1_BIT : info->rasterizationSamples; + subpass->custom_resolve = crc_info && crc_info->customResolve; 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]; + VkFormat format = + custom_resolve ? crc_info->pColorAttachmentFormats[i] : + info->pColorAttachmentFormats[i]; if (format == VK_FORMAT_UNDEFINED) { subpass->color_attachments[i].attachment = VK_ATTACHMENT_UNUSED; @@ -1777,8 +1828,7 @@ tu_setup_dynamic_inheritance(struct tu_cmd_buffer *cmd_buffer, } att->format = format; - att->samples = info->rasterizationSamples; - subpass->samples = info->rasterizationSamples; + att->samples = subpass->samples; subpass->color_attachments[i].attachment = a++; /* conservatively assume that the attachment may be conditionally @@ -1787,17 +1837,21 @@ tu_setup_dynamic_inheritance(struct tu_cmd_buffer *cmd_buffer, att->cond_load_allowed = att->cond_store_allowed = true; } - if (info->depthAttachmentFormat != VK_FORMAT_UNDEFINED || - info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED) { + VkFormat depth_format = + custom_resolve ? crc_info->depthAttachmentFormat : + info->depthAttachmentFormat; + VkFormat stencil_format = + custom_resolve ? crc_info->stencilAttachmentFormat : + info->stencilAttachmentFormat; + if (depth_format != VK_FORMAT_UNDEFINED || + stencil_format != 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; + att->format = depth_format != VK_FORMAT_UNDEFINED ? + depth_format : stencil_format; + att->samples = subpass->samples; subpass->depth_stencil_attachment.attachment = a++; - subpass->depth_used = - info->depthAttachmentFormat != VK_FORMAT_UNDEFINED; - subpass->stencil_used = - info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED; + subpass->depth_used = depth_format != VK_FORMAT_UNDEFINED; + subpass->stencil_used = stencil_format != VK_FORMAT_UNDEFINED; att->cond_load_allowed = att->cond_store_allowed = true; } else { subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;