Graphics: Add PipelinePassList loader (able to load from a file)

Fix compilation
This commit is contained in:
SirLynix
2023-11-05 17:33:16 +01:00
committed by Jérôme Leclercq
parent ef0a34b7b1
commit 886991f86d
16 changed files with 737 additions and 39 deletions

View File

@@ -44,7 +44,8 @@ namespace Nz
inline StreamOptionFlags GetStreamOptions() const;
std::size_t Read(void* buffer, std::size_t size);
virtual std::string ReadLine(unsigned int lineSize = 0);
virtual void ReadLine(std::string& line, unsigned int lineSize = 0);
inline std::string ReadLine(unsigned int lineSize = 0);
inline bool IsBufferingEnabled() const;
inline bool IsMemoryMapped() const;

View File

@@ -105,6 +105,27 @@ namespace Nz
return m_streamOptions;
}
/*!
* \brief Reads a line from the stream
*
* Reads the stream until a line separator or the end of the stream is found.
*
* If lineSize does not equal zero, it represents the maximum character count to be read from the stream.
*
* \param lineSize Maximum number of characters to read, or zero for no limit
*
* \return Line read from file
*
* \remark With the text stream option, "\r\n" is treated as "\n"
* \remark The line separator character is not returned as part of the string
*/
inline std::string Stream::ReadLine(unsigned int lineSize)
{
std::string line;
ReadLine(line, lineSize);
return line;
}
/*!
* \brief Checks whether the stream is readable
* \return true if it is the case

View File

@@ -33,17 +33,28 @@ namespace Nz
inline std::unique_ptr<FramePipelinePass> BuildPass(std::size_t passIndex, FramePipelinePass::PassData& passData, std::string passName, const ParameterList& parameters) const;
inline std::size_t GetPassIndex(std::string_view passName) const;
inline std::size_t GetPassInputIndex(std::size_t passIndex, std::string_view inputName) const;
inline std::size_t GetPassOutputIndex(std::size_t passIndex, std::string_view inputName) const;
template<typename T> std::size_t RegisterPass(std::string passName);
inline std::size_t RegisterPass(std::string passName, Factory factory);
template<typename T> std::size_t RegisterPass(std::string passName, std::vector<std::string> inputs, std::vector<std::string> outputs);
inline std::size_t RegisterPass(std::string passName, std::vector<std::string> inputs, std::vector<std::string> outputs, Factory factory);
FramePipelinePassRegistry& operator=(const FramePipelinePassRegistry&) = default;
FramePipelinePassRegistry& operator=(FramePipelinePassRegistry&&) = default;
static constexpr std::size_t InvalidIndex = std::numeric_limits<std::size_t>::max();
private:
struct Pass
{
Factory factory;
std::vector<std::string> inputs;
std::vector<std::string> outputs;
};
std::list<std::string> m_passNames; //< in order to allow std::string_view as a key in C++17 (keep std::string stable as well because of SSO)
std::unordered_map<std::string_view, std::size_t> m_passIndex;
std::vector<Factory> m_passFactories;
std::vector<Pass> m_passes;
};
}

View File

@@ -9,29 +9,51 @@ namespace Nz
{
inline std::unique_ptr<FramePipelinePass> FramePipelinePassRegistry::BuildPass(std::size_t passIndex, FramePipelinePass::PassData& passData, std::string passName, const ParameterList& parameters) const
{
assert(passIndex < m_passFactories.size());
return m_passFactories[passIndex](passData, passName, parameters);
assert(passIndex < m_passes.size());
return m_passes[passIndex].factory(passData, passName, parameters);
}
inline std::size_t FramePipelinePassRegistry::GetPassIndex(std::string_view passName) const
{
auto it = m_passIndex.find(passName);
if (it == m_passIndex.end())
throw std::runtime_error("pass " + std::string(passName) + " must be registered before being used");
return InvalidIndex;
return it->second;
}
template<typename T>
std::size_t FramePipelinePassRegistry::RegisterPass(std::string passName)
inline std::size_t FramePipelinePassRegistry::GetPassInputIndex(std::size_t passIndex, std::string_view inputName) const
{
return RegisterPass(std::move(passName), [](FramePipelinePass::PassData& passData, std::string passName, const ParameterList& parameters) -> std::unique_ptr<FramePipelinePass>
assert(passIndex < m_passes.size());
auto& passData = m_passes[passIndex];
auto it = std::find(passData.inputs.begin(), passData.inputs.end(), inputName);
if (it == passData.inputs.end())
return InvalidIndex;
return std::distance(passData.inputs.begin(), it);
}
inline std::size_t FramePipelinePassRegistry::GetPassOutputIndex(std::size_t passIndex, std::string_view outputName) const
{
assert(passIndex < m_passes.size());
auto& passData = m_passes[passIndex];
auto it = std::find(passData.outputs.begin(), passData.outputs.end(), outputName);
if (it == passData.outputs.end())
return InvalidIndex;
return std::distance(passData.outputs.begin(), it);
}
template<typename T>
std::size_t FramePipelinePassRegistry::RegisterPass(std::string passName, std::vector<std::string> inputs, std::vector<std::string> outputs)
{
return RegisterPass(std::move(passName), std::move(inputs), std::move(outputs), [](FramePipelinePass::PassData& passData, std::string passName, const ParameterList& parameters) -> std::unique_ptr<FramePipelinePass>
{
return std::make_unique<T>(passData, std::move(passName), parameters);
});
}
inline std::size_t FramePipelinePassRegistry::RegisterPass(std::string passName, Factory factory)
inline std::size_t FramePipelinePassRegistry::RegisterPass(std::string passName, std::vector<std::string> inputs, std::vector<std::string> outputs, Factory factory)
{
if (m_passIndex.find(passName) != m_passIndex.end())
throw std::runtime_error("pass " + passName + " is already registered");
@@ -40,7 +62,10 @@ namespace Nz
std::size_t passIndex = m_passIndex.size();
m_passIndex.emplace(m_passNames.back(), passIndex);
m_passFactories.emplace_back(std::move(factory));
auto& passData = m_passes.emplace_back();
passData.factory = std::move(factory);
passData.inputs = std::move(inputs);
passData.outputs = std::move(outputs);
return passIndex;
}

View File

@@ -55,6 +55,8 @@ namespace Nz
inline const MaterialInstanceLoader& GetMaterialInstanceLoader() const;
inline MaterialLoader& GetMaterialLoader();
inline const MaterialLoader& GetMaterialLoader() const;
inline PipelinePassListLoader& GetPipelinePassListLoader();
inline const PipelinePassListLoader& GetPipelinePassListLoader() const;
inline PixelFormat GetPreferredDepthFormat() const;
inline PixelFormat GetPreferredDepthStencilFormat() const;
inline const std::shared_ptr<RenderDevice>& GetRenderDevice() const;
@@ -115,6 +117,7 @@ namespace Nz
MaterialInstanceLoader m_materialInstanceLoader;
MaterialLoader m_materialLoader;
MaterialPassRegistry m_materialPassRegistry;
PipelinePassListLoader m_pipelinePassListLoader;
PixelFormat m_preferredDepthFormat;
PixelFormat m_preferredDepthStencilFormat;

View File

@@ -71,6 +71,16 @@ namespace Nz
return m_materialLoader;
}
inline PipelinePassListLoader& Graphics::GetPipelinePassListLoader()
{
return m_pipelinePassListLoader;
}
inline const PipelinePassListLoader& Graphics::GetPipelinePassListLoader() const
{
return m_pipelinePassListLoader;
}
inline PixelFormat Graphics::GetPreferredDepthFormat() const
{
return m_preferredDepthFormat;

View File

@@ -8,7 +8,10 @@
#define NAZARA_GRAPHICS_PIPELINEPASSLIST_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Core/ObjectLibrary.hpp>
#include <Nazara/Core/ParameterList.hpp>
#include <Nazara/Core/Resource.hpp>
#include <Nazara/Core/ResourceLoader.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/FramePassAttachment.hpp>
@@ -21,11 +24,22 @@
namespace Nz
{
class FrameGraph;
struct NAZARA_GRAPHICS_API PipelinePassListParams : ResourceParameters
{
bool IsValid() const;
};
class NAZARA_GRAPHICS_API PipelinePassList
class FrameGraph;
class PipelinePassList;
using PipelinePassListLibrary = ObjectLibrary<PipelinePassList>;
using PipelinePassListLoader = ResourceLoader<PipelinePassList, PipelinePassListParams>;
class NAZARA_GRAPHICS_API PipelinePassList : public Resource
{
public:
using Params = PipelinePassListParams;
PipelinePassList() = default;
PipelinePassList(const PipelinePassList&) = delete;
PipelinePassList(PipelinePassList&&) = delete;
@@ -50,6 +64,10 @@ namespace Nz
PipelinePassList& operator=(const PipelinePassList&) = delete;
PipelinePassList& operator=(PipelinePassList&&) = delete;
static std::shared_ptr<PipelinePassList> LoadFromFile(const std::filesystem::path& filePath, const PipelinePassListParams& params = PipelinePassListParams());
static std::shared_ptr<PipelinePassList> LoadFromMemory(const void* data, std::size_t size, const PipelinePassListParams& params = PipelinePassListParams());
static std::shared_ptr<PipelinePassList> LoadFromStream(Stream& stream, const PipelinePassListParams& params = PipelinePassListParams());
static constexpr std::size_t MaxPassAttachment = 8;
private:

View File

@@ -76,7 +76,8 @@ namespace Nz
static inline bool HasAlpha(PixelFormat format);
static PixelFormat IdentifyFormat(const PixelFormatDescription& info);
static inline PixelFormat IdentifyFormat(const PixelFormatDescription& info);
static inline PixelFormat IdentifyFormat(std::string_view formatName);
static inline bool IsCompressed(PixelFormat format);
static inline bool IsConversionSupported(PixelFormat srcFormat, PixelFormat dstFormat);

View File

@@ -243,6 +243,30 @@ namespace Nz
return s_pixelFormatInfos[format].alphaMask.TestAny();
}
inline PixelFormat PixelFormatInfo::IdentifyFormat(const PixelFormatDescription& info)
{
for (auto&& [format, formatDesc] : s_pixelFormatInfos.iter_kv())
{
if (info.bitsPerPixel == formatDesc.bitsPerPixel && info.content == formatDesc.content &&
info.redMask == formatDesc.redMask && info.greenMask == formatDesc.greenMask && info.blueMask == formatDesc.blueMask && info.alphaMask == formatDesc.alphaMask &&
info.redType == formatDesc.redType && info.greenType == formatDesc.greenType && info.blueType == formatDesc.blueType && info.alphaType == formatDesc.alphaType)
return format;
}
return PixelFormat::Undefined;
}
inline PixelFormat PixelFormatInfo::IdentifyFormat(std::string_view formatName)
{
for (auto&& [format, formatDesc] : s_pixelFormatInfos.iter_kv())
{
if (formatDesc.name == formatName)
return format;
}
return PixelFormat::Undefined;
}
inline bool PixelFormatInfo::IsCompressed(PixelFormat format)
{
return s_pixelFormatInfos[format].IsCompressed();