diff --git a/app/src/main/cpp/skyline/gpu/interconnect/command_nodes.cpp b/app/src/main/cpp/skyline/gpu/interconnect/command_nodes.cpp index 7ed11770..342b1556 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/command_nodes.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/command_nodes.cpp @@ -6,14 +6,7 @@ #include namespace skyline::gpu::interconnect::node { - RenderPassNode::RenderPassNode(vk::Rect2D renderArea) - : externalDependency{vk::SubpassDependency{ - .srcSubpass = VK_SUBPASS_EXTERNAL, - .dstSubpass = 0, - .srcAccessMask = vk::AccessFlagBits::eMemoryWrite, - .dstAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite, - }}, - renderArea{renderArea} {} + RenderPassNode::RenderPassNode(vk::Rect2D renderArea) : renderArea{renderArea} {} u32 RenderPassNode::AddAttachment(TextureView *view, GPU &gpu) { auto vkView{view->GetView()}; @@ -41,15 +34,18 @@ namespace skyline::gpu::interconnect::node { }); if (auto usage{view->texture->GetLastRenderPassUsage()}; usage != texture::RenderPassUsage::None) { + vk::PipelineStageFlags attachmentDstStageMask{}; if (view->format->vkAspect & vk::ImageAspectFlagBits::eColor) - externalDependency.dstStageMask |= vk::PipelineStageFlagBits::eColorAttachmentOutput; + attachmentDstStageMask |= vk::PipelineStageFlagBits::eColorAttachmentOutput; else if (view->format->vkAspect & (vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil)) - externalDependency.dstStageMask |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests; + attachmentDstStageMask |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests; + + dependencyDstStageMask |= attachmentDstStageMask; if (usage == texture::RenderPassUsage::RenderTarget) - externalDependency.srcStageMask |= externalDependency.dstStageMask; + dependencySrcStageMask |= attachmentDstStageMask; else if (usage == texture::RenderPassUsage::Sampled) - externalDependency.srcStageMask |= vk::PipelineStageFlagBits::eAllGraphics; + dependencySrcStageMask |= view->texture->GetReadStageMask(); } return static_cast(attachments.size() - 1); @@ -173,8 +169,8 @@ namespace skyline::gpu::interconnect::node { } void RenderPassNode::UpdateDependency(vk::PipelineStageFlags srcStageMask, vk::PipelineStageFlags dstStageMask) { - externalDependency.srcStageMask |= srcStageMask; - externalDependency.dstStageMask |= dstStageMask; + dependencySrcStageMask |= srcStageMask; + dependencyDstStageMask |= dstStageMask; } bool RenderPassNode::ClearColorAttachment(u32 colorAttachment, const vk::ClearColorValue &value, GPU& gpu) { @@ -240,8 +236,12 @@ namespace skyline::gpu::interconnect::node { preserveAttachmentIt++; } - if (externalDependency.srcStageMask && externalDependency.dstStageMask) - subpassDependencies.push_back(externalDependency); + if (dependencyDstStageMask && dependencySrcStageMask) { + commandBuffer.pipelineBarrier(dependencySrcStageMask, dependencyDstStageMask, {}, {vk::MemoryBarrier{ + .srcAccessMask = vk::AccessFlagBits::eMemoryWrite, + .dstAccessMask = vk::AccessFlagBits::eMemoryWrite | vk::AccessFlagBits::eMemoryRead, + }}, {}, {}); + } auto renderPass{gpu.renderPassCache.GetRenderPass(vk::RenderPassCreateInfo{ .attachmentCount = static_cast(attachmentDescriptions.size()), diff --git a/app/src/main/cpp/skyline/gpu/interconnect/command_nodes.h b/app/src/main/cpp/skyline/gpu/interconnect/command_nodes.h index dc2edc1b..6507feae 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/command_nodes.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/command_nodes.h @@ -48,7 +48,8 @@ namespace skyline::gpu::interconnect::node { public: std::vector subpassDescriptions; std::vector subpassDependencies; - vk::SubpassDependency externalDependency; + vk::PipelineStageFlags dependencySrcStageMask; + vk::PipelineStageFlags dependencyDstStageMask; vk::Rect2D renderArea; std::vector clearValues; @@ -64,7 +65,12 @@ namespace skyline::gpu::interconnect::node { /** * @brief Creates a subpass with the attachments bound in the specified order */ - void AddSubpass(span inputAttachments, span colorAttachments, TextureView *depthStencilAttachment, GPU &gpu, vk::PipelineStageFlags srcStageMask, vk::PipelineStageFlags dstStageMask); + void AddSubpass(span inputAttachments, span colorAttachments, TextureView *depthStencilAttachment, GPU &gpu); + + /** + * @brief Updates the dependency barrier for the renderpass + */ + void UpdateDependency(vk::PipelineStageFlags srcStageMask, vk::PipelineStageFlags dstStageMask); /** * @brief Clears a color attachment in the current subpass with VK_ATTACHMENT_LOAD_OP_CLEAR