Graphics/FrameGraph: Reuse memory when building physical passes

This commit is contained in:
SirLynix 2023-09-10 14:46:09 +02:00
parent e1ccb3187d
commit 4723c92a65
1 changed files with 86 additions and 80 deletions

View File

@ -704,89 +704,95 @@ namespace Nz
std::vector<TextureLayout> textureLayouts(m_pending.textures.size(), TextureLayout::Undefined); std::vector<TextureLayout> textureLayouts(m_pending.textures.size(), TextureLayout::Undefined);
// Per-pass data (reuse memory)
std::optional<std::size_t> depthStencilAttachmentIndex;
std::size_t depthStencilAttachmentId;
std::unordered_map<std::size_t /*textureId*/, std::size_t /*attachmentIndex*/> usedTextureAttachments;
std::vector<RenderPass::Attachment> renderPassAttachments;
std::vector<RenderPass::SubpassDescription> subpassesDesc;
std::vector<RenderPass::SubpassDependency> subpassesDeps;
auto RegisterColorInputRead = [&](const FramePass::Input& input)
{
std::size_t textureId = Retrieve(m_pending.attachmentToTextures, input.attachmentId);
TextureLayout& textureLayout = textureLayouts[textureId];
if (!input.assumedLayout)
{
assert(textureLayouts[textureId] != TextureLayout::Undefined);
textureLayout = TextureLayout::ColorInput;
}
else
textureLayout = *input.assumedLayout;
};
auto RegisterColorOutput = [&](const FramePass::Output& output, bool shouldLoad)
{
std::size_t textureId = Retrieve(m_pending.attachmentToTextures, output.attachmentId);
TextureLayout initialLayout = textureLayouts[textureId];
textureLayouts[textureId] = TextureLayout::ColorOutput;
auto it = usedTextureAttachments.find(textureId);
if (it != usedTextureAttachments.end())
return it->second;
std::size_t attachmentIndex = renderPassAttachments.size();
auto& attachment = renderPassAttachments.emplace_back();
attachment.format = m_pending.textures[textureId].format;
attachment.initialLayout = initialLayout;
attachment.storeOp = AttachmentStoreOp::Store;
attachment.stencilLoadOp = AttachmentLoadOp::Discard;
attachment.stencilStoreOp = AttachmentStoreOp::Discard;
if (output.clearColor)
attachment.loadOp = AttachmentLoadOp::Clear;
else if (shouldLoad)
attachment.loadOp = AttachmentLoadOp::Load;
else
attachment.loadOp = AttachmentLoadOp::Discard;
usedTextureAttachments.emplace(textureId, attachmentIndex);
return attachmentIndex;
};
auto RegisterDepthStencil = [&](std::size_t attachmentId, TextureLayout textureLayout, bool* first) -> RenderPass::Attachment&
{
if (depthStencilAttachmentIndex)
{
assert(depthStencilAttachmentId == attachmentId);
*first = false;
return renderPassAttachments[depthStencilAttachmentIndex.value()];
}
*first = true;
std::size_t textureId = Retrieve(m_pending.attachmentToTextures, attachmentId);
TextureLayout initialLayout = textureLayouts[textureId];
textureLayouts[textureId] = textureLayout;
depthStencilAttachmentId = attachmentId;
depthStencilAttachmentIndex = renderPassAttachments.size();
usedTextureAttachments.emplace(textureId, *depthStencilAttachmentIndex);
auto& depthStencilAttachment = renderPassAttachments.emplace_back();
depthStencilAttachment.format = m_pending.textures[textureId].format;
depthStencilAttachment.initialLayout = initialLayout;
return depthStencilAttachment;
};
std::size_t physicalPassIndex = 0; std::size_t physicalPassIndex = 0;
for (auto& physicalPass : m_pending.physicalPasses) for (auto& physicalPass : m_pending.physicalPasses)
{ {
std::unordered_map<std::size_t /*textureId*/, std::size_t /*attachmentIndex*/> usedTextureAttachments; depthStencilAttachmentIndex = std::nullopt;
std::size_t depthStencilAttachmentId; usedTextureAttachments.clear();
std::optional<std::size_t> depthStencilAttachmentIndex; renderPassAttachments.clear();
subpassesDesc.clear();
std::vector<RenderPass::Attachment> renderPassAttachments; subpassesDeps.clear();
std::vector<RenderPass::SubpassDescription> subpassesDesc;
std::vector<RenderPass::SubpassDependency> subpassesDeps;
auto RegisterColorInputRead = [&](const FramePass::Input& input)
{
std::size_t textureId = Retrieve(m_pending.attachmentToTextures, input.attachmentId);
TextureLayout& textureLayout = textureLayouts[textureId];
if (!input.assumedLayout)
{
assert(textureLayouts[textureId] != TextureLayout::Undefined);
textureLayout = TextureLayout::ColorInput;
}
else
textureLayout = *input.assumedLayout;
};
auto RegisterColorOutput = [&](const FramePass::Output& output, bool shouldLoad)
{
std::size_t textureId = Retrieve(m_pending.attachmentToTextures, output.attachmentId);
TextureLayout initialLayout = textureLayouts[textureId];
textureLayouts[textureId] = TextureLayout::ColorOutput;
auto it = usedTextureAttachments.find(textureId);
if (it != usedTextureAttachments.end())
return it->second;
std::size_t attachmentIndex = renderPassAttachments.size();
auto& attachment = renderPassAttachments.emplace_back();
attachment.format = m_pending.textures[textureId].format;
attachment.initialLayout = initialLayout;
attachment.storeOp = AttachmentStoreOp::Store;
attachment.stencilLoadOp = AttachmentLoadOp::Discard;
attachment.stencilStoreOp = AttachmentStoreOp::Discard;
if (output.clearColor)
attachment.loadOp = AttachmentLoadOp::Clear;
else if (shouldLoad)
attachment.loadOp = AttachmentLoadOp::Load;
else
attachment.loadOp = AttachmentLoadOp::Discard;
usedTextureAttachments.emplace(textureId, attachmentIndex);
return attachmentIndex;
};
auto RegisterDepthStencil = [&](std::size_t attachmentId, TextureLayout textureLayout, bool* first) -> RenderPass::Attachment&
{
if (depthStencilAttachmentIndex)
{
assert(depthStencilAttachmentId == attachmentId);
*first = false;
return renderPassAttachments[depthStencilAttachmentIndex.value()];
}
*first = true;
std::size_t textureId = Retrieve(m_pending.attachmentToTextures, attachmentId);
TextureLayout initialLayout = textureLayouts[textureId];
textureLayouts[textureId] = textureLayout;
depthStencilAttachmentId = attachmentId;
depthStencilAttachmentIndex = renderPassAttachments.size();
usedTextureAttachments.emplace(textureId, *depthStencilAttachmentIndex);
auto& depthStencilAttachment = renderPassAttachments.emplace_back();
depthStencilAttachment.format = m_pending.textures[textureId].format;
depthStencilAttachment.initialLayout = initialLayout;
return depthStencilAttachment;
};
std::size_t subpassIndex = 0; std::size_t subpassIndex = 0;