Commit current work

Reworked conditions, added uber-shaders, comparison nodes, fixed Discard
This commit is contained in:
Jérôme Leclercq
2021-01-02 21:15:59 +01:00
parent ed72d668d9
commit f327932738
103 changed files with 3248 additions and 790 deletions

View File

@@ -17,30 +17,48 @@ namespace Nz
friend class MaterialPipeline;
public:
struct UniformOffsets;
BasicMaterial(Material& material);
inline void EnableAlphaTest(bool alphaTest);
inline const std::shared_ptr<Texture>& GetAlphaMap() const;
float GetAlphaThreshold() const;
inline const std::shared_ptr<TextureSampler>& GetAlphaSampler() const;
float GetAlphaTestThreshold() const;
Color GetDiffuseColor() const;
inline const std::shared_ptr<Texture>& GetDiffuseMap() const;
inline const std::shared_ptr<TextureSampler>& GetDiffuseSampler() const;
inline bool HasAlphaMap() const;
inline bool HasAlphaThreshold() const;
inline bool HasAlphaTest() const;
inline bool HasAlphaTestThreshold() const;
inline bool HasDiffuseColor() const;
inline bool HasDiffuseMap() const;
inline void SetAlphaMap(std::shared_ptr<Texture> alphaMap);
void SetAlphaThreshold(float alphaThreshold);
inline void SetAlphaSampler(std::shared_ptr<TextureSampler> alphaSampler);
void SetAlphaTestThreshold(float alphaThreshold);
void SetDiffuseColor(const Color& diffuse);
inline void SetDiffuseMap(std::shared_ptr<Texture> diffuseMap);
inline void SetDiffuseSampler(std::shared_ptr<TextureSampler> diffuseSampler);
static const std::shared_ptr<MaterialSettings>& GetSettings();
static inline const UniformOffsets& GetOffsets();
static inline const std::shared_ptr<MaterialSettings>& GetSettings();
private:
struct UniformOffsets
{
std::size_t alphaThreshold;
std::size_t diffuseColor;
std::size_t totalSize;
};
private:
struct ConditionIndexes
{
std::size_t alphaTest;
std::size_t hasAlphaMap;
std::size_t hasDiffuseMap;
};
struct TextureIndexes
@@ -54,11 +72,13 @@ namespace Nz
Material& m_material;
std::size_t m_uniformBlockIndex;
ConditionIndexes m_conditionIndexes;
TextureIndexes m_textureIndexes;
UniformOffsets m_uniformOffsets;
static std::shared_ptr<MaterialSettings> s_materialSettings;
static std::size_t s_uniformBlockIndex;
static ConditionIndexes s_conditionIndexes;
static TextureIndexes s_textureIndexes;
static UniformOffsets s_uniformOffsets;
};

View File

@@ -9,24 +9,47 @@
namespace Nz
{
inline void BasicMaterial::EnableAlphaTest(bool alphaTest)
{
NazaraAssert(HasAlphaTest(), "Material has no alpha test condition");
m_material.EnableCondition(m_conditionIndexes.alphaTest, alphaTest);
}
inline const std::shared_ptr<Texture>& BasicMaterial::GetAlphaMap() const
{
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
NazaraAssert(HasAlphaMap(), "Material has no alpha texture slot");
return m_material.GetTexture(m_textureIndexes.alpha);
}
inline const std::shared_ptr<TextureSampler>& BasicMaterial::GetAlphaSampler() const
{
NazaraAssert(HasAlphaMap(), "Material has no alpha texture slot");
return m_material.GetTextureSampler(m_textureIndexes.alpha);
}
inline const std::shared_ptr<Texture>& BasicMaterial::GetDiffuseMap() const
{
NazaraAssert(HasDiffuseMap(), "Material has no alpha map slot");
NazaraAssert(HasDiffuseMap(), "Material has no alpha texture slot");
return m_material.GetTexture(m_textureIndexes.diffuse);
}
inline const std::shared_ptr<TextureSampler>& BasicMaterial::GetDiffuseSampler() const
{
NazaraAssert(HasDiffuseMap(), "Material has no alpha texture slot");
return m_material.GetTextureSampler(m_textureIndexes.diffuse);
}
inline bool BasicMaterial::HasAlphaMap() const
{
return m_textureIndexes.alpha != MaterialSettings::InvalidIndex;
}
inline bool BasicMaterial::HasAlphaThreshold() const
inline bool BasicMaterial::HasAlphaTest() const
{
return m_conditionIndexes.alphaTest != MaterialSettings::InvalidIndex;
}
inline bool BasicMaterial::HasAlphaTestThreshold() const
{
return m_uniformOffsets.alphaThreshold != MaterialSettings::InvalidIndex;
}
@@ -44,13 +67,43 @@ namespace Nz
inline void BasicMaterial::SetAlphaMap(std::shared_ptr<Texture> alphaMap)
{
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
bool hasAlphaMap = (alphaMap != nullptr);
m_material.SetTexture(m_textureIndexes.alpha, std::move(alphaMap));
if (m_conditionIndexes.hasDiffuseMap != MaterialSettings::InvalidIndex)
m_material.EnableCondition(m_conditionIndexes.hasAlphaMap, hasAlphaMap);
}
inline void BasicMaterial::SetAlphaSampler(std::shared_ptr<TextureSampler> alphaSampler)
{
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
m_material.SetTextureSampler(m_textureIndexes.alpha, std::move(alphaSampler));
}
inline void BasicMaterial::SetDiffuseMap(std::shared_ptr<Texture> diffuseMap)
{
NazaraAssert(HasDiffuseMap(), "Material has no diffuse map slot");
bool hasDiffuseMap = (diffuseMap != nullptr);
m_material.SetTexture(m_textureIndexes.diffuse, std::move(diffuseMap));
if (m_conditionIndexes.hasDiffuseMap != MaterialSettings::InvalidIndex)
m_material.EnableCondition(m_conditionIndexes.hasDiffuseMap, hasDiffuseMap);
}
inline void BasicMaterial::SetDiffuseSampler(std::shared_ptr<TextureSampler> diffuseSampler)
{
NazaraAssert(HasDiffuseMap(), "Material has no diffuse map slot");
m_material.SetTextureSampler(m_textureIndexes.diffuse, std::move(diffuseSampler));
}
inline const std::shared_ptr<MaterialSettings>& BasicMaterial::GetSettings()
{
return s_materialSettings;
}
inline auto BasicMaterial::GetOffsets() -> const UniformOffsets&
{
return s_uniformOffsets;
}
}

View File

@@ -41,6 +41,7 @@ namespace Nz
inline void EnableAlphaTest(bool alphaTest);
inline void EnableBlending(bool blending);
inline void EnableColorWrite(bool colorWrite);
inline void EnableCondition(std::size_t conditionIndex, bool enable);
inline void EnableDepthBuffer(bool depthBuffer);
inline void EnableDepthSorting(bool depthSorting);
inline void EnableDepthWrite(bool depthWrite);
@@ -53,7 +54,7 @@ namespace Nz
inline void EnableVertexColor(bool vertexColor);
inline void EnsurePipelineUpdate() const;
inline RendererComparison GetDepthCompareFunc() const;
inline BlendFunc GetDstBlend() const;
inline FaceSide GetFaceCulling() const;
@@ -63,7 +64,7 @@ namespace Nz
inline const MaterialPipelineInfo& GetPipelineInfo() const;
inline float GetPointSize() const;
inline const std::shared_ptr<const MaterialSettings>& GetSettings() const;
inline const std::shared_ptr<ShaderStage>& GetShader(ShaderStageType shaderStage) const;
inline const std::shared_ptr<UberShader>& GetShader(ShaderStageType shaderStage) const;
inline BlendFunc GetSrcBlend() const;
inline const std::shared_ptr<Texture>& GetTexture(std::size_t textureIndex) const;
inline const std::shared_ptr<TextureSampler>& GetTextureSampler(std::size_t textureIndex) const;
@@ -76,6 +77,7 @@ namespace Nz
inline bool IsAlphaTestEnabled() const;
inline bool IsBlendingEnabled() const;
inline bool IsColorWriteEnabled() const;
inline bool IsConditionEnabled(std::size_t conditionIndex) const;
inline bool IsDepthBufferEnabled() const;
inline bool IsDepthSortingEnabled() const;
inline bool IsDepthWriteEnabled() const;
@@ -92,7 +94,6 @@ namespace Nz
inline void SetFaceFilling(FaceFilling filling);
inline void SetLineWidth(float lineWidth);
inline void SetPointSize(float pointSize);
inline void SetShader(ShaderStageType shaderStage, std::shared_ptr<ShaderStage> shader);
inline void SetUniformBuffer(std::size_t bufferIndex, UniformBufferRef uniformBuffer);
inline void SetSrcBlend(BlendFunc func);
inline void SetTexture(std::size_t textureIndex, std::shared_ptr<Texture> texture);
@@ -115,7 +116,8 @@ namespace Nz
std::vector<MaterialTexture> m_textures;
std::vector<UniformBufferRef> m_uniformBuffers;
mutable std::shared_ptr<MaterialPipeline> m_pipeline;
MaterialPipelineInfo m_pipelineInfo;
UInt32 m_enabledConditions;
mutable MaterialPipelineInfo m_pipelineInfo;
mutable bool m_pipelineUpdated;
bool m_shadowCastingEnabled;
};

View File

@@ -111,6 +111,15 @@ namespace Nz
InvalidatePipeline();
}
inline void Material::EnableCondition(std::size_t conditionIndex, bool enable)
{
if (TestBit<UInt64>(m_enabledConditions, conditionIndex) != enable)
{
m_enabledConditions = SetBit<UInt64>(m_enabledConditions, conditionIndex);
InvalidatePipeline();
}
}
/*!
* \brief Enable/Disable depth buffer for this material
*
@@ -428,9 +437,9 @@ namespace Nz
* \brief Gets the über-shader used by this material
* \return Constant pointer to the über-shader used
*/
inline const std::shared_ptr<ShaderStage>& Material::GetShader(ShaderStageType shaderStage) const
inline const std::shared_ptr<UberShader>& Material::GetShader(ShaderStageType shaderStage) const
{
return m_pipelineInfo.shaders[UnderlyingCast(shaderStage)];
return m_pipelineInfo.shaders[UnderlyingCast(shaderStage)].uberShader;
}
/*!
@@ -507,6 +516,11 @@ namespace Nz
return m_pipelineInfo.colorWrite;
}
inline bool Material::IsConditionEnabled(std::size_t conditionIndex) const
{
return TestBit<UInt64>(m_enabledConditions, conditionIndex);
}
/*!
* \brief Checks whether this material has depth buffer enabled
* \return true If it is the case
@@ -682,22 +696,6 @@ namespace Nz
InvalidatePipeline();
}
/*!
* \brief Sets the shader with a constant reference to a ubershader
*
* \param uberShader Uber shader to apply
*
* \remark Invalidates the pipeline
*
* \see GetShader
*/
inline void Material::SetShader(ShaderStageType shaderStage, std::shared_ptr<ShaderStage> shader)
{
m_pipelineInfo.shaders[UnderlyingCast(shaderStage)] = std::move(shader);
InvalidatePipeline();
}
inline void Material::SetUniformBuffer(std::size_t bufferIndex, UniformBufferRef uniformBuffer)
{
NazaraAssert(bufferIndex < m_uniformBuffers.size(), "Invalid shared uniform buffer index");
@@ -739,6 +737,19 @@ namespace Nz
inline void Material::UpdatePipeline() const
{
for (auto& shader : m_pipelineInfo.shaders)
shader.enabledConditions = 0;
const auto& conditions = m_settings->GetConditions();
for (std::size_t conditionIndex = 0; conditionIndex < conditions.size(); ++conditionIndex)
{
if (TestBit<UInt64>(m_enabledConditions, conditionIndex))
{
for (std::size_t shaderStage = 0; shaderStage < ShaderStageTypeCount; ++shaderStage)
m_pipelineInfo.shaders[shaderStage].enabledConditions |= conditions[conditionIndex].enabledConditions[shaderStage];
}
}
m_pipeline = MaterialPipeline::Get(m_pipelineInfo);
m_pipelineUpdated = true;
}

View File

@@ -17,18 +17,24 @@
namespace Nz
{
class ShaderStage;
class UberShader;
struct MaterialPipelineInfo : RenderStates
{
struct ShaderStage
{
std::shared_ptr<UberShader> uberShader;
Nz::UInt64 enabledConditions = 0;
};
bool alphaTest = false;
bool depthSorting = false;
bool hasVertexColor = false;
bool reflectionMapping = false;
bool shadowReceive = true;
std::array<ShaderStage, ShaderStageTypeCount> shaders;
std::shared_ptr<const MaterialSettings> settings;
std::array<std::shared_ptr<ShaderStage>, ShaderStageTypeCount> shaders;
};
inline bool operator==(const MaterialPipelineInfo& lhs, const MaterialPipelineInfo& rhs);

View File

@@ -40,7 +40,10 @@ namespace Nz
for (std::size_t i = 0; i < lhs.shaders.size(); ++i)
{
if (lhs.shaders[i] != rhs.shaders[i])
if (lhs.shaders[i].enabledConditions != rhs.shaders[i].enabledConditions)
return false;
if (lhs.shaders[i].uberShader != rhs.shaders[i].uberShader)
return false;
}
@@ -82,7 +85,10 @@ namespace std
NazaraPipelineMember(settings.get()); //< Hash pointer
for (const auto& shader : pipelineInfo.shaders)
Nz::HashCombine(seed, shader.get());
{
Nz::HashCombine(seed, shader.enabledConditions);
Nz::HashCombine(seed, shader.uberShader.get());
}
#undef NazaraPipelineMember
#undef NazaraPipelineBoolMember

View File

@@ -19,29 +19,35 @@
namespace Nz
{
class UberShader;
class MaterialSettings
{
public:
using DefaultShaders = std::array<std::shared_ptr<ShaderStage>, ShaderStageTypeCount>;
using PredefinedBinding = std::array<std::size_t, PredefinedShaderBindingCount>;
using Shaders = std::array<std::shared_ptr<UberShader>, ShaderStageTypeCount>;
struct Builder;
struct Condition;
struct SharedUniformBlock;
struct Texture;
struct UniformBlock;
inline MaterialSettings();
inline MaterialSettings(std::vector<Texture> textures, std::vector<UniformBlock> uniformBlocks, std::vector<SharedUniformBlock> sharedUniformBlocks, const PredefinedBinding& predefinedBinding, DefaultShaders defaultShaders);
inline MaterialSettings(Builder builder);
MaterialSettings(const MaterialSettings&) = default;
MaterialSettings(MaterialSettings&&) = delete;
~MaterialSettings() = default;
inline const std::shared_ptr<ShaderStage>& GetDefaultShader(ShaderStageType stage) const;
inline const DefaultShaders& GetDefaultShaders() const;
inline const std::vector<Condition>& GetConditions() const;
inline std::size_t GetConditionIndex(const std::string_view& name) const;
inline std::size_t GetPredefinedBindingIndex(PredefinedShaderBinding binding) const;
inline const std::shared_ptr<RenderPipelineLayout>& GetRenderPipelineLayout() const;
inline const std::shared_ptr<UberShader>& GetShader(ShaderStageType stage) const;
inline const Shaders& GetShaders() const;
inline const std::vector<SharedUniformBlock>& GetSharedUniformBlocks() const;
inline std::size_t GetSharedUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const;
inline std::size_t GetSharedUniformBlockIndex(const std::string_view& name) const;
inline std::size_t GetSharedUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const;
inline const std::vector<Texture>& GetTextures() const;
inline std::size_t GetTextureIndex(const std::string_view& name) const;
inline const std::vector<UniformBlock>& GetUniformBlocks() const;
@@ -53,6 +59,22 @@ namespace Nz
static constexpr std::size_t InvalidIndex = std::numeric_limits<std::size_t>::max();
struct Builder
{
PredefinedBinding predefinedBinding;
Shaders shaders;
std::vector<Condition> conditions;
std::vector<Texture> textures;
std::vector<UniformBlock> uniformBlocks;
std::vector<SharedUniformBlock> sharedUniformBlocks;
};
struct Condition
{
std::string name;
std::array<UInt64, ShaderStageTypeCount> enabledConditions;
};
struct UniformVariable
{
std::string name;
@@ -84,11 +106,7 @@ namespace Nz
private:
std::shared_ptr<RenderPipelineLayout> m_pipelineLayout;
std::vector<SharedUniformBlock> m_sharedUniformBlocks;
std::vector<Texture> m_textures;
std::vector<UniformBlock> m_uniformBlocks;
DefaultShaders m_defaultShaders;
PredefinedBinding m_predefinedBinding;
Builder m_data;
};
}

View File

@@ -10,22 +10,18 @@
namespace Nz
{
inline MaterialSettings::MaterialSettings() :
MaterialSettings({}, {}, {}, { InvalidIndex }, {})
MaterialSettings(Builder{})
{
}
inline MaterialSettings::MaterialSettings(std::vector<Texture> textures, std::vector<UniformBlock> uniformBlocks, std::vector<SharedUniformBlock> sharedUniformBlocks, const PredefinedBinding& predefinedBindings, DefaultShaders defaultShaders) :
m_sharedUniformBlocks(std::move(sharedUniformBlocks)),
m_textures(std::move(textures)),
m_uniformBlocks(std::move(uniformBlocks)),
m_defaultShaders(std::move(defaultShaders)),
m_predefinedBinding(predefinedBindings)
inline MaterialSettings::MaterialSettings(Builder data) :
m_data(std::move(data))
{
RenderPipelineLayoutInfo info;
unsigned int bindingIndex = 0;
for (const Texture& textureInfo : m_textures)
for (const Texture& textureInfo : m_data.textures)
{
info.bindings.push_back({
//textureInfo.bindingPoint,
@@ -35,7 +31,7 @@ namespace Nz
});
}
for (const UniformBlock& ubo : m_uniformBlocks)
for (const UniformBlock& ubo : m_data.uniformBlocks)
{
info.bindings.push_back({
//ubo.bindingPoint,
@@ -45,7 +41,7 @@ namespace Nz
});
}
for (const SharedUniformBlock& ubo : m_sharedUniformBlocks)
for (const SharedUniformBlock& ubo : m_data.sharedUniformBlocks)
{
info.bindings.push_back({
//ubo.bindingPoint,
@@ -58,19 +54,25 @@ namespace Nz
m_pipelineLayout = Graphics::Instance()->GetRenderDevice().InstantiateRenderPipelineLayout(std::move(info));
}
inline const std::shared_ptr<ShaderStage>& MaterialSettings::GetDefaultShader(ShaderStageType stage) const
inline auto MaterialSettings::GetConditions() const -> const std::vector<Condition>&
{
return m_defaultShaders[UnderlyingCast(stage)];
return m_data.conditions;
}
inline auto MaterialSettings::GetDefaultShaders() const -> const DefaultShaders&
inline std::size_t MaterialSettings::GetConditionIndex(const std::string_view& name) const
{
return m_defaultShaders;
for (std::size_t i = 0; i < m_data.conditions.size(); ++i)
{
if (m_data.conditions[i].name == name)
return i;
}
return InvalidIndex;
}
inline std::size_t MaterialSettings::GetPredefinedBindingIndex(PredefinedShaderBinding binding) const
{
return m_predefinedBinding[UnderlyingCast(binding)];
return m_data.predefinedBinding[UnderlyingCast(binding)];
}
inline const std::shared_ptr<RenderPipelineLayout>& MaterialSettings::GetRenderPipelineLayout() const
@@ -78,32 +80,37 @@ namespace Nz
return m_pipelineLayout;
}
inline const std::shared_ptr<UberShader>& MaterialSettings::GetShader(ShaderStageType stage) const
{
return m_data.shaders[UnderlyingCast(stage)];
}
inline auto MaterialSettings::GetShaders() const -> const Shaders&
{
return m_data.shaders;
}
inline auto MaterialSettings::GetSharedUniformBlocks() const -> const std::vector<SharedUniformBlock>&
{
return m_sharedUniformBlocks;
return m_data.sharedUniformBlocks;
}
inline std::size_t MaterialSettings::GetSharedUniformBlockIndex(const std::string_view& name) const
{
for (std::size_t i = 0; i < m_sharedUniformBlocks.size(); ++i)
for (std::size_t i = 0; i < m_data.sharedUniformBlocks.size(); ++i)
{
if (m_sharedUniformBlocks[i].name == name)
if (m_data.sharedUniformBlocks[i].name == name)
return i;
}
return InvalidIndex;
}
inline auto MaterialSettings::GetTextures() const -> const std::vector<Texture>&
{
return m_textures;
}
inline std::size_t MaterialSettings::GetSharedUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const
{
assert(uniformBlockIndex < m_sharedUniformBlocks.size());
assert(uniformBlockIndex < m_data.sharedUniformBlocks.size());
const std::vector<UniformVariable>& variables = m_sharedUniformBlocks[uniformBlockIndex].uniforms;
const std::vector<UniformVariable>& variables = m_data.sharedUniformBlocks[uniformBlockIndex].uniforms;
for (std::size_t i = 0; i < variables.size(); ++i)
{
if (variables[i].name == name)
@@ -113,11 +120,16 @@ namespace Nz
return InvalidIndex;
}
inline auto MaterialSettings::GetTextures() const -> const std::vector<Texture>&
{
return m_data.textures;
}
inline std::size_t MaterialSettings::GetTextureIndex(const std::string_view& name) const
{
for (std::size_t i = 0; i < m_textures.size(); ++i)
for (std::size_t i = 0; i < m_data.textures.size(); ++i)
{
if (m_textures[i].name == name)
if (m_data.textures[i].name == name)
return i;
}
@@ -126,14 +138,14 @@ namespace Nz
inline auto MaterialSettings::GetUniformBlocks() const -> const std::vector<UniformBlock>&
{
return m_uniformBlocks;
return m_data.uniformBlocks;
}
inline std::size_t MaterialSettings::GetUniformBlockIndex(const std::string_view& name) const
{
for (std::size_t i = 0; i < m_uniformBlocks.size(); ++i)
for (std::size_t i = 0; i < m_data.uniformBlocks.size(); ++i)
{
if (m_uniformBlocks[i].name == name)
if (m_data.uniformBlocks[i].name == name)
return i;
}
@@ -142,9 +154,9 @@ namespace Nz
inline std::size_t MaterialSettings::GetUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const
{
assert(uniformBlockIndex < m_uniformBlocks.size());
assert(uniformBlockIndex < m_data.uniformBlocks.size());
const std::vector<UniformVariable>& variables = m_uniformBlocks[uniformBlockIndex].uniforms;
const std::vector<UniformVariable>& variables = m_data.uniformBlocks[uniformBlockIndex].uniforms;
for (std::size_t i = 0; i < variables.size(); ++i)
{
if (variables[i].name == name)

View File

@@ -0,0 +1,39 @@
// Copyright (C) 2017 Jérôme Leclercq
// 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_UBER_SHADER_HPP
#define NAZARA_UBER_SHADER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Bitset.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Shader/ShaderAst.hpp>
#include <unordered_map>
namespace Nz
{
class ShaderStage;
class NAZARA_GRAPHICS_API UberShader
{
public:
inline UberShader(ShaderAst shaderAst);
~UberShader() = default;
UInt64 GetConditionFlagByName(const std::string_view& condition) const;
const std::shared_ptr<ShaderStage>& Get(UInt64 combination);
private:
std::unordered_map<UInt64 /*combination*/, std::shared_ptr<ShaderStage>> m_combinations;
ShaderAst m_shaderAst;
UInt64 m_combinationMask;
};
}
#include <Nazara/Graphics/UberShader.inl>
#endif // NAZARA_UBER_SHADER_HPP

View File

@@ -0,0 +1,12 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/UberShader.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@@ -36,6 +36,7 @@ namespace Nz
std::shared_ptr<CommandPool> InstantiateCommandPool(QueueType queueType) override;
std::shared_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) override;
std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) override;
std::shared_ptr<ShaderStage> InstantiateShaderStage(const ShaderAst& shaderAst, const ShaderWriter::States& states) override;
std::shared_ptr<ShaderStage> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) override;
std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) override;
std::shared_ptr<TextureSampler> InstantiateTextureSampler(const TextureSamplerInfo& params) override;

View File

@@ -52,9 +52,11 @@ namespace Nz
void Release(ShaderBinding& binding);
inline void TryToShrink();
static constexpr UInt32 InvalidIndex = 0xFFFFFFFF;
struct TextureDescriptor
{
UInt32 bindingIndex;
UInt32 bindingIndex = InvalidIndex;
GLuint texture;
GLuint sampler;
GL::TextureTarget textureTarget;
@@ -62,7 +64,7 @@ namespace Nz
struct UniformBufferDescriptor
{
UInt32 bindingIndex;
UInt32 bindingIndex = InvalidIndex;
GLuint buffer;
GLintptr offset;
GLsizeiptr size;

View File

@@ -12,13 +12,17 @@
#include <Nazara/Renderer/ShaderStage.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Context.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Shader.hpp>
#include <Nazara/Shader/ShaderWriter.hpp>
#include <vector>
namespace Nz
{
class ShaderAst;
class NAZARA_OPENGLRENDERER_API OpenGLShaderStage : public ShaderStage
{
public:
OpenGLShaderStage(OpenGLDevice& device, const ShaderAst& shaderAst, const ShaderWriter::States& states);
OpenGLShaderStage(OpenGLDevice& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize);
OpenGLShaderStage(const OpenGLShaderStage&) = delete;
OpenGLShaderStage(OpenGLShaderStage&&) noexcept = default;
@@ -30,6 +34,9 @@ namespace Nz
OpenGLShaderStage& operator=(OpenGLShaderStage&&) noexcept = default;
private:
void CheckCompilationStatus();
void Create(OpenGLDevice& device, const ShaderAst& shaderAst, const ShaderWriter::States& states);
GL::Shader m_shader;
};
}

View File

@@ -9,7 +9,8 @@ namespace Nz::GL
{
inline GL::WGLContext::WGLContext(const OpenGLDevice* device, const WGLLoader& loader) :
Context(device),
m_loader(loader)
m_loader(loader),
m_handle(nullptr)
{
}

View File

@@ -14,6 +14,7 @@
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
#include <Nazara/Renderer/Texture.hpp>
#include <Nazara/Renderer/TextureSampler.hpp>
#include <Nazara/Shader/ShaderWriter.hpp>
#include <Nazara/Utility/AbstractBuffer.hpp>
#include <memory>
#include <string>
@@ -21,6 +22,7 @@
namespace Nz
{
class CommandPool;
class ShaderAst;
class ShaderStage;
class NAZARA_RENDERER_API RenderDevice
@@ -33,6 +35,7 @@ namespace Nz
virtual std::shared_ptr<CommandPool> InstantiateCommandPool(QueueType queueType) = 0;
virtual std::shared_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) = 0;
virtual std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) = 0;
virtual std::shared_ptr<ShaderStage> InstantiateShaderStage(const ShaderAst& shaderAst, const ShaderWriter::States& states) = 0;
virtual std::shared_ptr<ShaderStage> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) = 0;
std::shared_ptr<ShaderStage> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const std::filesystem::path& sourcePath);
virtual std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) = 0;

View File

@@ -41,6 +41,8 @@ namespace Nz
void AddStruct(std::string name, std::vector<StructMember> members);
void AddUniform(std::string name, ShaderExpressionType type, std::optional<std::size_t> bindingIndex = {}, std::optional<ShaderNodes::MemoryLayout> memoryLayout = {});
inline std::size_t FindConditionByName(const std::string_view& conditionName) const;
inline const Condition& GetCondition(std::size_t i) const;
inline std::size_t GetConditionCount() const;
inline const std::vector<Condition>& GetConditions() const;
@@ -110,6 +112,8 @@ namespace Nz
ShaderExpressionType type;
};
static constexpr std::size_t InvalidCondition = std::numeric_limits<std::size_t>::max();
private:
std::vector<Condition> m_conditions;
std::vector<Function> m_functions;

View File

@@ -12,6 +12,17 @@ namespace Nz
{
}
inline std::size_t ShaderAst::FindConditionByName(const std::string_view& conditionName) const
{
for (std::size_t i = 0; i < m_conditions.size(); ++i)
{
if (m_conditions[i].name == conditionName)
return i;
}
return InvalidCondition;
}
inline auto Nz::ShaderAst::GetCondition(std::size_t i) const -> const Condition&
{
assert(i < m_functions.size());

View File

@@ -141,6 +141,7 @@ namespace Nz
};
NAZARA_SHADER_API ByteArray SerializeShader(const ShaderAst& shader);
inline ShaderAst UnserializeShader(const void* data, std::size_t size);
NAZARA_SHADER_API ShaderAst UnserializeShader(ByteStream& stream);
}

View File

@@ -128,6 +128,12 @@ namespace Nz
m_stream(stream)
{
}
inline ShaderAst UnserializeShader(const void* data, std::size_t size)
{
ByteStream byteStream(data, size);
return UnserializeShader(byteStream);
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@@ -56,7 +56,12 @@ namespace Nz::ShaderBuilder
constexpr GenBuilder<ShaderNodes::DeclareVariable> DeclareVariable;
constexpr GenBuilder<ShaderNodes::Discard> Discard;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Divide> Divide;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Equality> Equal;
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompEq> Equal;
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompGt> GreaterThan;
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompGe> GreaterThanOrEqual;
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompLt> LessThan;
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompLe> LessThanOrEqual;
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompNe> NotEqual;
constexpr GenBuilder<ShaderNodes::ExpressionStatement> ExprStatement;
constexpr GenBuilder<ShaderNodes::Identifier> Identifier;
constexpr GenBuilder<ShaderNodes::IntrinsicCall> IntrinsicCall;

View File

@@ -33,7 +33,7 @@ namespace Nz::ShaderNodes
UInt1, //< uint
UInt2, //< uvec2
UInt3, //< uvec3
UInt4 //< uvec4
UInt4 //< uvec4
};
enum class BinaryType
@@ -43,7 +43,12 @@ namespace Nz::ShaderNodes
Multiply, //< *
Divide, //< /
Equality //< ==
CompEq, //< ==
CompGe, //< >=
CompGt, //< >
CompLe, //< <=
CompLt, //< <
CompNe //< <=
};
enum class BuiltinEntry
@@ -87,7 +92,9 @@ namespace Nz::ShaderNodes
IntrinsicCall,
Sample2D,
SwizzleOp,
StatementBlock
StatementBlock,
Max = StatementBlock
};
enum class SsaInstruction

View File

@@ -149,7 +149,7 @@ namespace Nz::ShaderNodes
inline Discard::Discard() :
Statement(NodeType::DeclareVariable)
Statement(NodeType::Discard)
{
}

View File

@@ -28,7 +28,7 @@ namespace Nz
struct States
{
std::unordered_set<std::string> enabledConditions;
Nz::UInt64 enabledConditions = 0;
};
};
}

View File

@@ -3,13 +3,17 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Shader/SpirvWriter.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
inline bool SpirvWriter::IsConditionEnabled(const std::string& condition) const
{
return m_context.states->enabledConditions.find(condition) != m_context.states->enabledConditions.end();
std::size_t conditionIndex = m_context.shader->FindConditionByName(condition);
assert(conditionIndex != ShaderAst::InvalidCondition);
return TestBit<Nz::UInt64>(m_context.states->enabledConditions, conditionIndex);
}
}

View File

@@ -27,6 +27,7 @@ namespace Nz
std::shared_ptr<CommandPool> InstantiateCommandPool(QueueType queueType) override;
std::shared_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) override;
std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) override;
std::shared_ptr<ShaderStage> InstantiateShaderStage(const ShaderAst& shaderAst, const ShaderWriter::States& states) override;
std::shared_ptr<ShaderStage> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) override;
std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) override;
std::shared_ptr<TextureSampler> InstantiateTextureSampler(const TextureSamplerInfo& params) override;

View File

@@ -10,6 +10,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/ShaderStage.hpp>
#include <Nazara/Shader/ShaderWriter.hpp>
#include <Nazara/VulkanRenderer/Wrapper/ShaderModule.hpp>
#include <vector>
@@ -23,6 +24,7 @@ namespace Nz
VulkanShaderStage(VulkanShaderStage&&) = delete;
~VulkanShaderStage() = default;
bool Create(Vk::Device& device, const ShaderAst& shader, const ShaderWriter::States& states);
bool Create(Vk::Device& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize);
inline const Vk::ShaderModule& GetHandle() const;