diff --git a/include/Nazara/Graphics/FrameGraph.hpp b/include/Nazara/Graphics/FrameGraph.hpp index c86673d35..df6325c07 100644 --- a/include/Nazara/Graphics/FrameGraph.hpp +++ b/include/Nazara/Graphics/FrameGraph.hpp @@ -33,6 +33,8 @@ namespace Nz ~FrameGraph() = default; inline std::size_t AddAttachment(FramePassAttachment attachment); + inline std::size_t AddAttachmentArray(FramePassAttachment attachment, std::size_t layerCount); + inline std::size_t AddAttachmentArrayLayer(std::size_t attachmentId, std::size_t layerIndex); inline std::size_t AddAttachmentCube(FramePassAttachment attachment); inline std::size_t AddAttachmentCubeFace(std::size_t attachmentId, CubemapFace face); inline std::size_t AddAttachmentProxy(std::string name, std::size_t attachmentId); @@ -55,6 +57,11 @@ namespace Nz using PassIdToPhysicalPassIndex = std::unordered_map; using TextureBarrier = BakedFrameGraph::TextureBarrier; + struct AttachmentArray : FramePassAttachment + { + std::size_t layerCount; + }; + struct AttachmentCube : FramePassAttachment { }; @@ -103,6 +110,7 @@ namespace Nz std::vector physicalPasses; std::vector textures; std::vector texture2DPool; + std::vector texture2DArrayPool; std::vector textureCubePool; AttachmentIdToPassId attachmentLastUse; AttachmentIdToPassMap attachmentReadList; @@ -128,7 +136,7 @@ namespace Nz void ReorderPasses(); void TraverseGraph(std::size_t passIndex); - using AttachmentType = std::variant; + using AttachmentType = std::variant; std::vector m_backbufferOutputs; std::vector m_framePasses; diff --git a/include/Nazara/Graphics/FrameGraph.inl b/include/Nazara/Graphics/FrameGraph.inl index 40d3928f3..eb4110539 100644 --- a/include/Nazara/Graphics/FrameGraph.inl +++ b/include/Nazara/Graphics/FrameGraph.inl @@ -15,6 +15,33 @@ namespace Nz return id; } + inline std::size_t FrameGraph::AddAttachmentArray(FramePassAttachment attachment, std::size_t layerCount) + { + AttachmentArray attachmentArray{ std::move(attachment) }; + attachmentArray.layerCount = layerCount; + + std::size_t id = m_attachments.size(); + m_attachments.emplace_back(std::move(attachmentArray)); + + return id; + } + + inline std::size_t FrameGraph::AddAttachmentArrayLayer(std::size_t attachmentId, std::size_t layerIndex) + { + attachmentId = ResolveAttachmentIndex(attachmentId); + + assert(std::holds_alternative(m_attachments[attachmentId])); + assert(layerIndex < std::get(m_attachments[attachmentId]).layerCount); + + std::size_t id = m_attachments.size(); + m_attachments.emplace_back(AttachmentLayer{ + attachmentId, + layerIndex + }); + + return id; + } + inline std::size_t FrameGraph::AddAttachmentCube(FramePassAttachment attachment) { std::size_t id = m_attachments.size(); diff --git a/include/Nazara/Graphics/FrameGraphStructs.hpp b/include/Nazara/Graphics/FrameGraphStructs.hpp index ca4a15fe1..4750aca7a 100644 --- a/include/Nazara/Graphics/FrameGraphStructs.hpp +++ b/include/Nazara/Graphics/FrameGraphStructs.hpp @@ -32,6 +32,7 @@ namespace Nz TextureUsageFlags usage; unsigned int width; unsigned int height; + unsigned int layerCount; }; } diff --git a/src/Nazara/Graphics/BakedFrameGraph.cpp b/src/Nazara/Graphics/BakedFrameGraph.cpp index 1a9195059..b18d29db9 100644 --- a/src/Nazara/Graphics/BakedFrameGraph.cpp +++ b/src/Nazara/Graphics/BakedFrameGraph.cpp @@ -170,8 +170,9 @@ namespace Nz textureCreationParams.pixelFormat = textureData.format; textureCreationParams.levelCount = 1; + textureCreationParams.layerCount = textureData.layerCount; if (textureCreationParams.type == ImageType::Cubemap) - textureCreationParams.layerCount = 6; + textureCreationParams.layerCount *= 6; textureCreationParams.width = 1; textureCreationParams.height = 1; diff --git a/src/Nazara/Graphics/FrameGraph.cpp b/src/Nazara/Graphics/FrameGraph.cpp index fcbe7e505..6f3519ef0 100644 --- a/src/Nazara/Graphics/FrameGraph.cpp +++ b/src/Nazara/Graphics/FrameGraph.cpp @@ -258,6 +258,13 @@ namespace Nz assert(std::find(m_pending.texture2DPool.begin(), m_pending.texture2DPool.end(), textureId) == m_pending.texture2DPool.end()); m_pending.texture2DPool.push_back(textureId); } + else if (std::holds_alternative(attachmentData)) + { + std::size_t textureId = Retrieve(m_pending.attachmentToTextures, attachmentId); + + assert(std::find(m_pending.textureCubePool.begin(), m_pending.textureCubePool.end(), textureId) == m_pending.textureCubePool.end()); + m_pending.texture2DArrayPool.push_back(textureId); + } else if (std::holds_alternative(attachmentData)) { std::size_t textureId = Retrieve(m_pending.attachmentToTextures, attachmentId); @@ -1014,6 +1021,49 @@ namespace Nz data.width = attachmentData.width; data.height = attachmentData.height; data.size = attachmentData.size; + data.layerCount = 1; + + return textureId; + } + else if constexpr (std::is_same_v) + { + const AttachmentArray& attachmentData = arg; + + // Fetch from reuse pool if possible + for (auto it = m_pending.texture2DArrayPool.begin(); it != m_pending.texture2DArrayPool.end(); ++it) + { + std::size_t textureId = *it; + + FrameGraphTextureData& data = m_pending.textures[textureId]; + assert(data.type == ImageType::E2D_Array); + + if (data.format != attachmentData.format || + data.width != attachmentData.width || + data.height != attachmentData.height || + data.size != attachmentData.size || + data.layerCount != attachmentData.layerCount) + continue; + + m_pending.textureCubePool.erase(it); + m_pending.attachmentToTextures.emplace(attachmentIndex, textureId); + + if (!attachmentData.name.empty() && data.name != attachmentData.name) + data.name += " / " + attachmentData.name; + + return textureId; + } + + std::size_t textureId = m_pending.textures.size(); + m_pending.attachmentToTextures.emplace(attachmentIndex, textureId); + + FrameGraphTextureData& data = m_pending.textures.emplace_back(); + data.type = ImageType::E2D_Array; + data.name = attachmentData.name; + data.format = attachmentData.format; + data.width = attachmentData.width; + data.height = attachmentData.height; + data.size = attachmentData.size; + data.layerCount = attachmentData.layerCount; return textureId; } @@ -1054,6 +1104,7 @@ namespace Nz data.width = attachmentData.width; data.height = attachmentData.height; data.size = attachmentData.size; + data.layerCount = 1; return textureId; }