Graphics/PipelinePassList: Add support for attachment proxy

This commit is contained in:
SirLynix 2023-11-06 19:16:27 +01:00 committed by Jérôme Leclercq
parent 578240cd6f
commit db58921cc4
4 changed files with 52 additions and 4 deletions

View File

@ -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<std::unique_ptr<FramePipelinePass>> BuildPasses(FramePipelinePass::PassData& passData) const;
@ -73,6 +74,12 @@ namespace Nz
private:
static constexpr std::size_t NoAttachment = std::numeric_limits<std::size_t>::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<FramePassAttachment> m_attachments;
std::vector<std::variant<FramePassAttachment, AttachmentProxy>> m_attachments;
std::vector<Pass> m_passes;
};
}

View File

@ -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();

View File

@ -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")

View File

@ -32,9 +32,6 @@ namespace Nz
NazaraAssert(m_passes.size() == passes.size(), "pass vector size doesn't match passlist size");
StackArray<std::size_t> 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<decltype(arg)>;
if constexpr (std::is_same_v<T, FramePassAttachment>)
return frameGraph.AddAttachment(arg);
else if constexpr (std::is_same_v<T, AttachmentProxy>)
return frameGraph.AddAttachmentProxy(arg.name, GetAttachmentIndex(arg.attachmentIndex));
else
static_assert(AlwaysFalse<T>(), "unhandled case");
}, m_attachments[i]);
}
for (std::size_t passIndex = 0; passIndex < passes.size(); ++passIndex)
{
const Pass& passData = m_passes[passIndex];