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 9a9804fc..7274d20e 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp @@ -275,34 +275,26 @@ namespace skyline::gpu::interconnect { allocator = &slot->allocator; } + static bool ViewsEqual(vk::ImageView a, TextureView *b) { + return (!a && !b) || (a && b && b->GetView() == a); + } + bool CommandExecutor::CreateRenderPassWithSubpass(vk::Rect2D renderArea, span sampledImages, span inputAttachments, span colorAttachments, TextureView *depthStencilAttachment, bool noSubpassCreation) { auto addSubpass{[&] { renderPass->AddSubpass(inputAttachments, colorAttachments, depthStencilAttachment, gpu); + lastSubpassColorAttachments.clear(); + lastSubpassInputAttachments.clear(); - lastSubpassAttachments.clear(); - auto insertAttachmentRange{[this](auto &attachments) -> std::pair { - size_t beginIndex{lastSubpassAttachments.size()}; - lastSubpassAttachments.insert(lastSubpassAttachments.end(), attachments.begin(), attachments.end()); - return {beginIndex, attachments.size()}; - }}; - - auto rangeToSpan{[this](auto &range) -> span { - return {lastSubpassAttachments.data() + range.first, range.second}; - }}; - - auto inputAttachmentRange{insertAttachmentRange(inputAttachments)}; - auto colorAttachmentRange{insertAttachmentRange(colorAttachments)}; - - lastSubpassInputAttachments = rangeToSpan(inputAttachmentRange); - lastSubpassColorAttachments = rangeToSpan(colorAttachmentRange); - lastSubpassDepthStencilAttachment = depthStencilAttachment; + ranges::transform(colorAttachments, std::back_inserter(lastSubpassColorAttachments), [](TextureView *view){ return view ? view->GetView() : vk::ImageView{};}); + ranges::transform(inputAttachments, std::back_inserter(lastSubpassInputAttachments), [](TextureView *view){ return view ? view->GetView() : vk::ImageView{};}); + lastSubpassDepthStencilAttachment = depthStencilAttachment ? depthStencilAttachment->GetView() : vk::ImageView{}; }}; span depthStencilAttachmentSpan{depthStencilAttachment ? span(depthStencilAttachment) : span()}; auto outputAttachmentViews{ranges::views::concat(colorAttachments, depthStencilAttachmentSpan)}; - bool attachmentsMatch{ranges::equal(lastSubpassInputAttachments, inputAttachments) && - ranges::equal(lastSubpassColorAttachments, colorAttachments) && - lastSubpassDepthStencilAttachment == depthStencilAttachment}; + bool attachmentsMatch{std::equal(lastSubpassInputAttachments.begin(), lastSubpassInputAttachments.end(), inputAttachments.begin(), inputAttachments.end(), ViewsEqual) && + std::equal(lastSubpassColorAttachments.begin(), lastSubpassColorAttachments.end(), colorAttachments.begin(), colorAttachments.end(), ViewsEqual) && + ViewsEqual(lastSubpassDepthStencilAttachment, depthStencilAttachment)}; bool splitRenderPass{renderPass == nullptr || renderPass->renderArea != renderArea || !attachmentsMatch || !ranges::all_of(outputAttachmentViews, [this] (auto view) { return !view || view->texture->ValidateRenderPassUsage(renderPassIndex, texture::RenderPassUsage::RenderTarget); }) || @@ -343,10 +335,9 @@ namespace skyline::gpu::interconnect { renderPass = nullptr; subpassCount = 0; - lastSubpassAttachments.clear(); - lastSubpassInputAttachments = nullptr; - lastSubpassColorAttachments = nullptr; - lastSubpassDepthStencilAttachment = nullptr; + lastSubpassInputAttachments.clear(); + lastSubpassColorAttachments.clear(); + lastSubpassDepthStencilAttachment = vk::ImageView{}; } } 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 c1bfd401..bf133f9a 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.h @@ -175,10 +175,9 @@ namespace skyline::gpu::interconnect { std::vector attachedBuffers; //!< All textures that are attached to the current execution - std::vector lastSubpassAttachments; //!< The storage backing for attachments used in the last subpass - span lastSubpassInputAttachments; //!< The set of input attachments used in the last subpass - span lastSubpassColorAttachments; //!< The set of color attachments used in the last subpass - TextureView *lastSubpassDepthStencilAttachment{}; //!< The depth stencil attachment used in the last subpass + std::vector lastSubpassInputAttachments; //!< The set of input attachments used in the last subpass + std::vector lastSubpassColorAttachments; //!< The set of color attachments used in the last subpass + vk::ImageView lastSubpassDepthStencilAttachment{}; //!< The depth stencil attachment used in the last subpass std::vector> flushCallbacks; //!< Set of persistent callbacks that will be called at the start of Execute in order to flush data required for recording std::vector> pipelineChangeCallbacks; //!< Set of persistent callbacks that will be called after any non-Maxwell 3D engine changes the active pipeline