NazaraEngine/include/Nazara/Graphics/ShaderReflection.hpp

121 lines
3.4 KiB
C++

// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_SHADERREFLECTION_HPP
#define NAZARA_GRAPHICS_SHADERREFLECTION_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
#include <NZSL/Ast/Module.hpp>
#include <NZSL/Ast/RecursiveVisitor.hpp>
#include <NZSL/Ast/Option.hpp>
#include <NZSL/Math/FieldOffsets.hpp>
#include <unordered_map>
namespace Nz
{
class NAZARA_GRAPHICS_API ShaderReflection : nzsl::Ast::RecursiveVisitor
{
public:
struct ExternalBlockData;
struct OptionData;
struct StructData;
ShaderReflection() = default;
ShaderReflection(const ShaderReflection&) = delete;
ShaderReflection(ShaderReflection&&) = delete;
~ShaderReflection() = default;
inline const RenderPipelineLayoutInfo& GetPipelineLayoutInfo() const;
inline const ExternalBlockData* GetExternalBlockByTag(const std::string& tag) const;
inline const OptionData* GetOptionByName(const std::string& optionName) const;
inline const StructData* GetStructByIndex(std::size_t structIndex) const;
void Reflect(nzsl::Ast::Module& module);
ShaderReflection& operator=(const ShaderReflection&) = delete;
ShaderReflection& operator=(ShaderReflection&&) = delete;
struct ExternalData
{
UInt32 bindingSet;
UInt32 bindingIndex;
};
struct ExternalSampler : ExternalData
{
UInt32 arraySize;
nzsl::ImageType imageType;
nzsl::Ast::PrimitiveType sampledType;
};
struct ExternalStorageBlock : ExternalData
{
std::size_t structIndex;
};
struct ExternalTexture : ExternalData
{
UInt32 arraySize;
nzsl::AccessPolicy accessPolicy;
nzsl::ImageFormat imageFormat;
nzsl::ImageType imageType;
nzsl::Ast::PrimitiveType baseType;
};
struct ExternalUniformBlock : ExternalData
{
std::size_t structIndex;
};
struct ExternalBlockData
{
std::unordered_map<std::string /*tag*/, ExternalSampler> samplers;
std::unordered_map<std::string /*tag*/, ExternalStorageBlock> storageBlocks;
std::unordered_map<std::string /*tag*/, ExternalTexture> textures;
std::unordered_map<std::string /*tag*/, ExternalUniformBlock> uniformBlocks;
};
struct OptionData
{
nzsl::Ast::ExpressionType type;
nzsl::Ast::OptionHash hash;
};
struct StructMemberData
{
std::size_t offset;
std::size_t size;
nzsl::Ast::ExpressionType type;
};
struct StructData
{
StructData(nzsl::StructLayout layout) : fieldOffsets(layout) {}
std::unordered_map<std::string /*tag*/, StructMemberData> members;
nzsl::FieldOffsets fieldOffsets;
};
private:
void Visit(nzsl::Ast::ConditionalStatement& node) override;
void Visit(nzsl::Ast::DeclareExternalStatement& node) override;
void Visit(nzsl::Ast::DeclareOptionStatement& node) override;
void Visit(nzsl::Ast::DeclareStructStatement& node) override;
std::unordered_map<std::string /*tag*/, ExternalBlockData> m_externalBlocks;
std::unordered_map<std::string /*name*/, OptionData> m_options;
std::unordered_map<std::size_t /*structIndex*/, StructData> m_structs;
RenderPipelineLayoutInfo m_pipelineLayoutInfo;
bool m_isConditional;
};
}
#include <Nazara/Graphics/ShaderReflection.inl>
#endif // NAZARA_GRAPHICS_SHADERREFLECTION_HPP