diff --git a/bin/resources/deferred_frag.nzsl b/bin/resources/deferred_frag.nzsl index f307c7617..731e77541 100644 --- a/bin/resources/deferred_frag.nzsl +++ b/bin/resources/deferred_frag.nzsl @@ -1,6 +1,6 @@ -option HAS_DIFFUSE_TEXTURE: bool; -option HAS_ALPHA_TEXTURE: bool; -option ALPHA_TEST: bool; +option HasDiffuseTexture: bool = false; +option HasAlphaTexture: bool = false; +option AlphaTest: bool = false; [layout(std140)] struct BasicSettings @@ -57,15 +57,15 @@ struct OutputData fn main(input: InputData) -> OutputData { let diffuseColor = settings.DiffuseColor; - const if (HAS_DIFFUSE_TEXTURE) + const if (HasDiffuseTexture) // TODO: diffuseColor *= MaterialDiffuseMap.Sample(input.uv) diffuseColor = diffuseColor * MaterialDiffuseMap.Sample(input.uv); - const if (HAS_ALPHA_TEXTURE) + const if (HasAlphaTexture) // TODO: diffuseColor.w *= MaterialAlphaMap.Sample(input.uv)).x diffuseColor = vec4(diffuseColor.x, diffuseColor.y, diffuseColor.z, (MaterialAlphaMap.Sample(input.uv)).x * diffuseColor.w); - const if (ALPHA_TEST) + const if (AlphaTest) { if (diffuseColor.w < settings.AlphaThreshold) discard; diff --git a/examples/RenderTest/main.cpp b/examples/RenderTest/main.cpp index 93ac746f2..6a8024c88 100644 --- a/examples/RenderTest/main.cpp +++ b/examples/RenderTest/main.cpp @@ -12,7 +12,7 @@ NAZARA_REQUEST_DEDICATED_GPU() const char shaderSource[] = R"( -option red: bool; +option red: bool = false; [layout(std140)] struct Data @@ -109,7 +109,6 @@ int main() } Nz::ShaderWriter::States states; - states.enabledOptions = 0; states.optimize = true; auto fragVertShader = device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, shaderSource, sizeof(shaderSource), states); diff --git a/include/Nazara/Graphics/BasicMaterial.inl b/include/Nazara/Graphics/BasicMaterial.inl index 17ad313ad..a0620ed0f 100644 --- a/include/Nazara/Graphics/BasicMaterial.inl +++ b/include/Nazara/Graphics/BasicMaterial.inl @@ -26,7 +26,7 @@ namespace Nz inline void BasicMaterial::EnableAlphaTest(bool alphaTest) { NazaraAssert(HasAlphaTest(), "Material has no alpha test option"); - m_material.EnableOption(m_optionIndexes.alphaTest, alphaTest); + m_material.SetOptionValue(m_optionIndexes.alphaTest, alphaTest); } inline const std::shared_ptr& BasicMaterial::GetAlphaMap() const @@ -56,7 +56,11 @@ namespace Nz inline bool BasicMaterial::IsAlphaTestEnabled() const { NazaraAssert(HasAlphaTest(), "Material has no alpha test option"); - return m_material.IsOptionEnabled(m_optionIndexes.alphaTest); + const auto& optionOpt = m_material.GetOptionValue(m_optionIndexes.alphaTest); + if (std::holds_alternative(optionOpt)) + return false; + + return std::get(optionOpt); } inline bool BasicMaterial::HasAlphaMap() const @@ -91,7 +95,7 @@ namespace Nz m_material.SetTexture(m_textureIndexes.alpha, std::move(alphaMap)); if (m_optionIndexes.hasDiffuseMap != MaterialSettings::InvalidIndex) - m_material.EnableOption(m_optionIndexes.hasAlphaMap, hasAlphaMap); + m_material.SetOptionValue(m_optionIndexes.hasAlphaMap, hasAlphaMap); } inline void BasicMaterial::SetAlphaSampler(TextureSamplerInfo alphaSampler) @@ -107,7 +111,7 @@ namespace Nz m_material.SetTexture(m_textureIndexes.diffuse, std::move(diffuseMap)); if (m_optionIndexes.hasDiffuseMap != MaterialSettings::InvalidIndex) - m_material.EnableOption(m_optionIndexes.hasDiffuseMap, hasDiffuseMap); + m_material.SetOptionValue(m_optionIndexes.hasDiffuseMap, hasDiffuseMap); } inline void BasicMaterial::SetDiffuseSampler(TextureSamplerInfo diffuseSampler) diff --git a/include/Nazara/Graphics/MaterialPass.hpp b/include/Nazara/Graphics/MaterialPass.hpp index c289975a7..5c800d9d1 100644 --- a/include/Nazara/Graphics/MaterialPass.hpp +++ b/include/Nazara/Graphics/MaterialPass.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -45,7 +46,6 @@ namespace Nz inline void EnableDepthClamp(bool depthClamp); inline void EnableDepthWrite(bool depthWrite); inline void EnableFaceCulling(bool faceCulling); - inline void EnableOption(std::size_t optionIndex, bool enable); inline void EnableScissorTest(bool scissorTest); inline void EnableStencilTest(bool stencilTest); @@ -61,6 +61,7 @@ namespace Nz inline FaceSide GetFaceCulling() const; inline FaceFilling GetFaceFilling() const; inline float GetLineWidth() const; + inline const ShaderAst::ConstantValue& GetOptionValue(std::size_t optionIndex) const; inline const std::shared_ptr& GetPipeline() const; inline const MaterialPipelineInfo& GetPipelineInfo() const; inline float GetPointSize() const; @@ -82,7 +83,6 @@ namespace Nz inline bool IsDepthClampEnabled() const; inline bool IsDepthWriteEnabled() const; inline bool IsFaceCullingEnabled() const; - inline bool IsOptionEnabled(std::size_t optionIndex) const; inline bool IsScissorTestEnabled() const; inline bool IsStencilTestEnabled() const; @@ -92,6 +92,7 @@ namespace Nz inline void SetFaceCulling(FaceSide faceSide); inline void SetFaceFilling(FaceFilling filling); inline void SetLineWidth(float lineWidth); + inline void SetOptionValue(std::size_t optionIndex, ShaderAst::ConstantValue value); inline void SetPointSize(float pointSize); inline void SetPrimitiveMode(PrimitiveMode mode); inline void SetTexture(std::size_t textureIndex, std::shared_ptr texture); @@ -126,11 +127,11 @@ namespace Nz bool dataInvalidated = true; }; + std::array m_optionValues; std::shared_ptr m_settings; std::vector m_textures; std::vector m_uniformBuffers; mutable std::shared_ptr m_pipeline; - UInt64 m_enabledOptions; mutable MaterialPipelineInfo m_pipelineInfo; ShaderBindingPtr m_shaderBinding; bool m_forceCommandBufferRegeneration; diff --git a/include/Nazara/Graphics/MaterialPass.inl b/include/Nazara/Graphics/MaterialPass.inl index af8f9a0a3..491a55018 100644 --- a/include/Nazara/Graphics/MaterialPass.inl +++ b/include/Nazara/Graphics/MaterialPass.inl @@ -182,15 +182,6 @@ namespace Nz InvalidatePipeline(); } - inline void MaterialPass::EnableOption(std::size_t optionIndex, bool enable) - { - if (TestBit(m_enabledOptions, optionIndex) != enable) - { - m_enabledOptions = ToggleBit(m_enabledOptions, optionIndex); - InvalidatePipeline(); - } - } - /*! * \brief Enable/Disable scissor test for this material * @@ -315,6 +306,12 @@ namespace Nz return m_pipelineInfo.lineWidth; } + inline const ShaderAst::ConstantValue& MaterialPass::GetOptionValue(std::size_t optionIndex) const + { + assert(optionIndex < m_optionValues.size()); + return m_optionValues[optionIndex]; + } + /*! * \brief Gets the render states * \return Constant reference to the render states @@ -461,11 +458,6 @@ namespace Nz return m_pipelineInfo.faceCulling; } - inline bool MaterialPass::IsOptionEnabled(std::size_t optionIndex) const - { - return TestBit(m_enabledOptions, optionIndex); - } - /*! * \brief Checks whether this material has scissor test enabled * \return true If it is the case @@ -562,6 +554,16 @@ namespace Nz InvalidatePipeline(); } + inline void MaterialPass::SetOptionValue(std::size_t optionIndex, ShaderAst::ConstantValue value) + { + assert(optionIndex < m_optionValues.size()); + if (m_optionValues[optionIndex] != value) + { + m_optionValues[optionIndex] = std::move(value); + InvalidatePipeline(); + } + } + /*! * \brief Sets the point size for this material * @@ -654,3 +656,4 @@ namespace Nz } #include +#include "MaterialPass.hpp" diff --git a/include/Nazara/Graphics/MaterialPipeline.hpp b/include/Nazara/Graphics/MaterialPipeline.hpp index c636b4e89..fa4d75c9f 100644 --- a/include/Nazara/Graphics/MaterialPipeline.hpp +++ b/include/Nazara/Graphics/MaterialPipeline.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -23,8 +24,8 @@ namespace Nz { struct Shader { + std::array optionValues; std::shared_ptr uberShader; - Nz::UInt64 enabledOptions = 0; }; std::vector shaders; diff --git a/include/Nazara/Graphics/MaterialPipeline.inl b/include/Nazara/Graphics/MaterialPipeline.inl index b4ef58c6a..f72fd0646 100644 --- a/include/Nazara/Graphics/MaterialPipeline.inl +++ b/include/Nazara/Graphics/MaterialPipeline.inl @@ -34,7 +34,7 @@ namespace Nz for (std::size_t i = 0; i < lhs.shaders.size(); ++i) { - if (lhs.shaders[i].enabledOptions != rhs.shaders[i].enabledOptions) + if (lhs.shaders[i].optionValues != rhs.shaders[i].optionValues) return false; if (lhs.shaders[i].uberShader != rhs.shaders[i].uberShader) @@ -73,7 +73,9 @@ namespace std for (const auto& shader : pipelineInfo.shaders) { - Nz::HashCombine(seed, shader.enabledOptions); + for (const auto& value : shader.optionValues) + Nz::HashCombine(seed, value); + Nz::HashCombine(seed, shader.uberShader.get()); } diff --git a/include/Nazara/Graphics/MaterialSettings.hpp b/include/Nazara/Graphics/MaterialSettings.hpp index 6f06f83cf..0d7041fdc 100644 --- a/include/Nazara/Graphics/MaterialSettings.hpp +++ b/include/Nazara/Graphics/MaterialSettings.hpp @@ -55,7 +55,7 @@ namespace Nz static constexpr std::size_t InvalidIndex = std::numeric_limits::max(); - static void BuildOption(std::vector