Graphics/FrameGraph: Reuse memory when building physical passes
This commit is contained in:
parent
e1ccb3187d
commit
4723c92a65
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue