204 lines
6.5 KiB
C++
204 lines
6.5 KiB
C++
#pragma once
|
|
|
|
#include <XCEngine/Core/Asset/IResource.h>
|
|
#include <XCEngine/Core/Containers/Array.h>
|
|
#include <XCEngine/Core/Types.h>
|
|
#include <XCEngine/Resources/Material/MaterialRenderState.h>
|
|
#include <XCEngine/Resources/Shader/ShaderKeywordTypes.h>
|
|
|
|
namespace XCEngine {
|
|
namespace Resources {
|
|
|
|
enum class ShaderType : Core::uint8 {
|
|
Vertex,
|
|
Fragment,
|
|
Geometry,
|
|
Compute,
|
|
Hull,
|
|
Domain
|
|
};
|
|
|
|
enum class ShaderLanguage : Core::uint8 {
|
|
GLSL,
|
|
HLSL,
|
|
SPIRV
|
|
};
|
|
|
|
enum class ShaderBackend : Core::uint8 {
|
|
Generic = 0,
|
|
D3D12,
|
|
OpenGL,
|
|
Vulkan
|
|
};
|
|
|
|
// Keep shader property kinds close to Unity's public shader syntax so the
|
|
// runtime contract can be reused when ShaderLab-compatible parsing is added.
|
|
enum class ShaderPropertyType : Core::uint8 {
|
|
Float = 0,
|
|
Range,
|
|
Int,
|
|
Vector,
|
|
Color,
|
|
Texture2D,
|
|
TextureCube
|
|
};
|
|
|
|
enum class ShaderResourceType : Core::uint8 {
|
|
ConstantBuffer = 0,
|
|
Texture2D,
|
|
TextureCube,
|
|
Sampler
|
|
};
|
|
|
|
struct ShaderUniform {
|
|
Containers::String name;
|
|
Core::uint32 location;
|
|
Core::uint32 size;
|
|
Core::uint32 type;
|
|
};
|
|
|
|
struct ShaderAttribute {
|
|
Containers::String name;
|
|
Core::uint32 location;
|
|
Core::uint32 size;
|
|
Core::uint32 type;
|
|
};
|
|
|
|
struct ShaderPassTagEntry {
|
|
Containers::String name;
|
|
Containers::String value;
|
|
};
|
|
|
|
struct ShaderPropertyDesc {
|
|
Containers::String name;
|
|
Containers::String displayName;
|
|
ShaderPropertyType type = ShaderPropertyType::Float;
|
|
Containers::String defaultValue;
|
|
Containers::String semantic;
|
|
};
|
|
|
|
struct ShaderResourceBindingDesc {
|
|
Containers::String name;
|
|
ShaderResourceType type = ShaderResourceType::ConstantBuffer;
|
|
Core::uint32 set = 0;
|
|
Core::uint32 binding = 0;
|
|
Containers::String semantic;
|
|
};
|
|
|
|
struct ShaderStageVariant {
|
|
ShaderType stage = ShaderType::Fragment;
|
|
ShaderLanguage language = ShaderLanguage::GLSL;
|
|
ShaderBackend backend = ShaderBackend::Generic;
|
|
ShaderKeywordSet requiredKeywords;
|
|
Containers::String entryPoint;
|
|
Containers::String profile;
|
|
Containers::String sourceCode;
|
|
Containers::Array<Core::uint8> compiledBinary;
|
|
};
|
|
|
|
struct ShaderPass {
|
|
Containers::String name;
|
|
bool hasFixedFunctionState = false;
|
|
MaterialRenderState fixedFunctionState;
|
|
Containers::Array<ShaderPassTagEntry> tags;
|
|
Containers::Array<ShaderResourceBindingDesc> resources;
|
|
Containers::Array<ShaderKeywordDeclaration> keywordDeclarations;
|
|
Containers::Array<ShaderStageVariant> variants;
|
|
};
|
|
|
|
class Shader : public IResource {
|
|
public:
|
|
Shader();
|
|
virtual ~Shader() override;
|
|
|
|
ResourceType GetType() const override { return ResourceType::Shader; }
|
|
const Containers::String& GetName() const override { return m_name; }
|
|
const Containers::String& GetPath() const override { return m_path; }
|
|
ResourceGUID GetGUID() const override { return m_guid; }
|
|
bool IsValid() const override { return m_isValid; }
|
|
size_t GetMemorySize() const override { return m_memorySize; }
|
|
void Release() override;
|
|
|
|
void SetShaderType(ShaderType type);
|
|
ShaderType GetShaderType() const { return m_shaderType; }
|
|
|
|
void SetShaderLanguage(ShaderLanguage lang);
|
|
ShaderLanguage GetShaderLanguage() const { return m_language; }
|
|
|
|
void SetSourceCode(const Containers::String& source);
|
|
const Containers::String& GetSourceCode() const { return m_sourceCode; }
|
|
|
|
void SetCompiledBinary(const Containers::Array<Core::uint8>& binary);
|
|
const Containers::Array<Core::uint8>& GetCompiledBinary() const { return m_compiledBinary; }
|
|
|
|
void AddUniform(const ShaderUniform& uniform);
|
|
const Containers::Array<ShaderUniform>& GetUniforms() const { return m_uniforms; }
|
|
|
|
void AddAttribute(const ShaderAttribute& attribute);
|
|
const Containers::Array<ShaderAttribute>& GetAttributes() const { return m_attributes; }
|
|
|
|
void AddProperty(const ShaderPropertyDesc& property);
|
|
void ClearProperties();
|
|
const Containers::Array<ShaderPropertyDesc>& GetProperties() const { return m_properties; }
|
|
const ShaderPropertyDesc* FindProperty(const Containers::String& propertyName) const;
|
|
void SetFallback(const Containers::String& fallback);
|
|
const Containers::String& GetFallback() const { return m_fallback; }
|
|
|
|
void AddPass(const ShaderPass& pass);
|
|
void ClearPasses();
|
|
Core::uint32 GetPassCount() const { return static_cast<Core::uint32>(m_passes.Size()); }
|
|
const Containers::Array<ShaderPass>& GetPasses() const { return m_passes; }
|
|
|
|
void AddPassVariant(const Containers::String& passName, const ShaderStageVariant& variant);
|
|
void SetPassTag(
|
|
const Containers::String& passName,
|
|
const Containers::String& tagName,
|
|
const Containers::String& tagValue);
|
|
void AddPassResourceBinding(
|
|
const Containers::String& passName,
|
|
const ShaderResourceBindingDesc& binding);
|
|
void AddPassKeywordDeclaration(
|
|
const Containers::String& passName,
|
|
const ShaderKeywordDeclaration& declaration);
|
|
bool HasPass(const Containers::String& passName) const;
|
|
const ShaderPass* FindPass(const Containers::String& passName) const;
|
|
ShaderPass* FindPass(const Containers::String& passName);
|
|
bool PassDeclaresKeyword(
|
|
const Containers::String& passName,
|
|
const Containers::String& keyword) const;
|
|
bool DeclaresKeyword(const Containers::String& keyword) const;
|
|
const ShaderResourceBindingDesc* FindPassResourceBinding(
|
|
const Containers::String& passName,
|
|
const Containers::String& resourceName) const;
|
|
const ShaderStageVariant* FindVariant(
|
|
const Containers::String& passName,
|
|
ShaderType stage,
|
|
ShaderBackend backend = ShaderBackend::Generic,
|
|
const ShaderKeywordSet& enabledKeywords = ShaderKeywordSet()) const;
|
|
|
|
class IRHIShader* GetRHIResource() const { return m_rhiResource; }
|
|
void SetRHIResource(class IRHIShader* resource);
|
|
|
|
private:
|
|
ShaderPass& GetOrCreatePass(const Containers::String& passName);
|
|
ShaderStageVariant& GetOrCreateLegacyVariant();
|
|
void SyncLegacyVariant();
|
|
|
|
ShaderType m_shaderType = ShaderType::Fragment;
|
|
ShaderLanguage m_language = ShaderLanguage::GLSL;
|
|
|
|
Containers::String m_sourceCode;
|
|
Containers::Array<Core::uint8> m_compiledBinary;
|
|
|
|
Containers::Array<ShaderUniform> m_uniforms;
|
|
Containers::Array<ShaderAttribute> m_attributes;
|
|
Containers::Array<ShaderPropertyDesc> m_properties;
|
|
Containers::Array<ShaderPass> m_passes;
|
|
Containers::String m_fallback;
|
|
|
|
class IRHIShader* m_rhiResource = nullptr;
|
|
};
|
|
|
|
} // namespace Resources
|
|
} // namespace XCEngine
|