diff --git a/include/Nazara/Graphics/PipelinePassList.hpp b/include/Nazara/Graphics/PipelinePassList.hpp index 40d1b206d..a098c7583 100644 --- a/include/Nazara/Graphics/PipelinePassList.hpp +++ b/include/Nazara/Graphics/PipelinePassList.hpp @@ -46,6 +46,7 @@ namespace Nz ~PipelinePassList() = default; inline std::size_t AddAttachment(FramePassAttachment attachment); + inline std::size_t AddAttachmentProxy(std::string name, std::size_t attachmentIndex); inline std::size_t AddPass(std::string name, std::size_t implIndex, ParameterList parameterList = {}); std::vector> BuildPasses(FramePipelinePass::PassData& passData) const; @@ -73,6 +74,12 @@ namespace Nz private: static constexpr std::size_t NoAttachment = std::numeric_limits::max(); + struct AttachmentProxy + { + std::string name; + std::size_t attachmentIndex; + }; + struct Pass { std::size_t depthStencilInput = NoAttachment; @@ -86,7 +93,7 @@ namespace Nz }; std::size_t m_finalOutputAttachment; - std::vector m_attachments; + std::vector> m_attachments; std::vector m_passes; }; } diff --git a/include/Nazara/Graphics/PipelinePassList.inl b/include/Nazara/Graphics/PipelinePassList.inl index 5f0d5d5ff..f055edfb2 100644 --- a/include/Nazara/Graphics/PipelinePassList.inl +++ b/include/Nazara/Graphics/PipelinePassList.inl @@ -15,6 +15,14 @@ namespace Nz return index; } + inline std::size_t PipelinePassList::AddAttachmentProxy(std::string name, std::size_t attachmentIndex) + { + std::size_t index = m_attachments.size(); + m_attachments.emplace_back(AttachmentProxy{ std::move(name), attachmentIndex }); + + return index; + } + inline std::size_t PipelinePassList::AddPass(std::string name, std::size_t implIndex, ParameterList parameterList) { std::size_t index = m_passes.size(); diff --git a/src/Nazara/Graphics/Formats/PipelinePassListLoader.cpp b/src/Nazara/Graphics/Formats/PipelinePassListLoader.cpp index e40d67f5c..dacc6ae3c 100644 --- a/src/Nazara/Graphics/Formats/PipelinePassListLoader.cpp +++ b/src/Nazara/Graphics/Formats/PipelinePassListLoader.cpp @@ -34,6 +34,27 @@ namespace Nz::Loaders std::string kw = ReadKeyword(); if (kw == "attachment") HandleAttachment(); + else if (kw == "attachmentproxy") + { + std::string proxyName = ReadString(); + std::string targetName = ReadString(); + + auto it = m_current->attachmentsByName.find(targetName); + if (it == m_current->attachmentsByName.end()) + { + NazaraErrorFmt("unknown attachment {}", targetName); + throw ResourceLoadingError::DecodingError; + } + + if (m_current->attachmentsByName.find(proxyName) != m_current->attachmentsByName.end()) + { + NazaraErrorFmt("attachment {} already exists", proxyName); + throw ResourceLoadingError::DecodingError; + } + + std::size_t proxyId = m_current->passList->AddAttachmentProxy(proxyName, it->second); + m_current->attachmentsByName.emplace(std::move(proxyName), proxyId); + } else if (kw == "pass") HandlePass(); else if (kw == "output") diff --git a/src/Nazara/Graphics/PipelinePassList.cpp b/src/Nazara/Graphics/PipelinePassList.cpp index 9f6208157..a86e867a8 100644 --- a/src/Nazara/Graphics/PipelinePassList.cpp +++ b/src/Nazara/Graphics/PipelinePassList.cpp @@ -32,9 +32,6 @@ namespace Nz NazaraAssert(m_passes.size() == passes.size(), "pass vector size doesn't match passlist size"); StackArray attachmentIndices = NazaraStackArrayNoInit(std::size_t, m_attachments.size()); - for (std::size_t i = 0; i < m_attachments.size(); ++i) - attachmentIndices[i] = frameGraph.AddAttachment(m_attachments[i]); - auto GetAttachmentIndex = [&](std::size_t attachmentIndex) { if (attachmentIndex == NoAttachment) @@ -44,6 +41,21 @@ namespace Nz return attachmentIndices[attachmentIndex]; }; + for (std::size_t i = 0; i < m_attachments.size(); ++i) + { + attachmentIndices[i] = std::visit([&](auto&& arg) + { + using T = std::decay_t; + if constexpr (std::is_same_v) + return frameGraph.AddAttachment(arg); + else if constexpr (std::is_same_v) + return frameGraph.AddAttachmentProxy(arg.name, GetAttachmentIndex(arg.attachmentIndex)); + else + static_assert(AlwaysFalse(), "unhandled case"); + + }, m_attachments[i]); + } + for (std::size_t passIndex = 0; passIndex < passes.size(); ++passIndex) { const Pass& passData = m_passes[passIndex];