diff --git a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp index 7f080a55..836ffd62 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp @@ -152,7 +152,7 @@ namespace skyline::gpu::interconnect { return gpu.megaBufferAllocator; } - bool CommandExecutor::CreateRenderPassWithSubpass(vk::Rect2D renderArea, span inputAttachments, span colorAttachments, TextureView *depthStencilAttachment) { + bool CommandExecutor::CreateRenderPassWithSubpass(vk::Rect2D renderArea, span inputAttachments, span colorAttachments, TextureView *depthStencilAttachment, bool noSubpassCreation) { auto addSubpass{[&] { renderPass->AddSubpass(inputAttachments, colorAttachments, depthStencilAttachment, gpu); @@ -175,7 +175,12 @@ namespace skyline::gpu::interconnect { lastSubpassDepthStencilAttachment = depthStencilAttachment; }}; - if (renderPass == nullptr || renderPass->renderArea != renderArea || subpassCount >= gpu.traits.quirks.maxSubpassCount) { + bool attachmentsMatch{ranges::equal(lastSubpassInputAttachments, inputAttachments) && + ranges::equal(lastSubpassColorAttachments, colorAttachments) && + lastSubpassDepthStencilAttachment == depthStencilAttachment}; + + if (renderPass == nullptr || renderPass->renderArea != renderArea || + ((noSubpassCreation || subpassCount >= gpu.traits.quirks.maxSubpassCount) && !attachmentsMatch)) { // We need to create a render pass if one doesn't already exist or the current one isn't compatible if (renderPass != nullptr) slot->nodes.emplace_back(std::in_place_type_t()); @@ -184,9 +189,7 @@ namespace skyline::gpu::interconnect { subpassCount = 1; return false; } else { - if (ranges::equal(lastSubpassInputAttachments, inputAttachments) && - ranges::equal(lastSubpassColorAttachments, colorAttachments) && - lastSubpassDepthStencilAttachment == depthStencilAttachment) { + if (attachmentsMatch) { // The last subpass had the same attachments, so we can reuse them return false; } else { @@ -285,18 +288,12 @@ namespace skyline::gpu::interconnect { cycle->AttachObject(dependency); } - void CommandExecutor::AddSubpass(std::function &, GPU &, vk::RenderPass, u32)> &&function, vk::Rect2D renderArea, span inputAttachments, span colorAttachments, TextureView *depthStencilAttachment, bool exclusiveSubpass) { - if (exclusiveSubpass) - FinishRenderPass(); - - bool gotoNext{CreateRenderPassWithSubpass(renderArea, inputAttachments, colorAttachments, depthStencilAttachment ? &*depthStencilAttachment : nullptr)}; + void CommandExecutor::AddSubpass(std::function &, GPU &, vk::RenderPass, u32)> &&function, vk::Rect2D renderArea, span inputAttachments, span colorAttachments, TextureView *depthStencilAttachment, bool noSubpassCreation) { + bool gotoNext{CreateRenderPassWithSubpass(renderArea, inputAttachments, colorAttachments, depthStencilAttachment ? &*depthStencilAttachment : nullptr, noSubpassCreation)}; if (gotoNext) slot->nodes.emplace_back(std::in_place_type_t(), std::forward(function)); else slot->nodes.emplace_back(std::in_place_type_t(), std::forward(function)); - - if (exclusiveSubpass) - FinishRenderPass(); } void CommandExecutor::AddOutsideRpCommand(std::function &, GPU &)> &&function) { diff --git a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.h b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.h index 497897cc..04f6ca3c 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.h @@ -127,10 +127,11 @@ namespace skyline::gpu::interconnect { /** * @brief Create a new render pass and subpass with the specified attachments, if one doesn't already exist or the current one isn't compatible + * @param noSubpassCreation Forces creation of a renderpass when a new subpass would otherwise be created * @note This also checks for subpass coalescing and will merge the new subpass with the previous one when possible * @return If the next subpass must be started prior to issuing any commands */ - bool CreateRenderPassWithSubpass(vk::Rect2D renderArea, span inputAttachments, span colorAttachments, TextureView *depthStencilAttachment); + bool CreateRenderPassWithSubpass(vk::Rect2D renderArea, span inputAttachments, span colorAttachments, TextureView *depthStencilAttachment, bool noSubpassCreation = false); /** * @brief Ends a render pass if one is currently active and resets all corresponding state @@ -218,7 +219,7 @@ namespace skyline::gpu::interconnect { * @param exclusiveSubpass If this subpass should be the only subpass in a render pass * @note Any supplied texture should be attached prior and not undergo any persistent layout transitions till execution */ - void AddSubpass(std::function &, GPU &, vk::RenderPass, u32)> &&function, vk::Rect2D renderArea, span inputAttachments = {}, span colorAttachments = {}, TextureView *depthStencilAttachment = {}, bool exclusiveSubpass = false); + void AddSubpass(std::function &, GPU &, vk::RenderPass, u32)> &&function, vk::Rect2D renderArea, span inputAttachments = {}, span colorAttachments = {}, TextureView *depthStencilAttachment = {}, bool noSubpassCreation = false); /** * @brief Adds a subpass that clears the entirety of the specified attachment with a color value, it may utilize VK_ATTACHMENT_LOAD_OP_CLEAR for a more efficient clear when possible