From e40e8eb20473cbed9d3bf55a3332f62ae4f71bfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Sun, 13 Mar 2022 15:07:43 +0100 Subject: [PATCH] Shader: Change module system (no longer based on path) --- bin/resources/bloom_bright.nzsl | 2 +- bin/resources/bloom_final.nzsl | 2 +- bin/resources/deferred_frag.nzsl | 4 +- bin/resources/deferred_vert.nzsl | 4 +- bin/resources/gaussian_blur.nzsl | 2 +- bin/resources/god_rays.nzsl | 2 +- bin/resources/lighting.nzsl | 2 +- bin/resources/skybox.nzsl | 2 +- bin/resources/tone_mapping.nzsl | 2 +- examples/RenderTest/main.cpp | 16 ++--- include/Nazara/Graphics/Graphics.hpp | 6 +- include/Nazara/Graphics/Graphics.inl | 2 +- include/Nazara/Shader.hpp | 2 +- include/Nazara/Shader/Ast/AstCompare.inl | 5 +- include/Nazara/Shader/Ast/Module.hpp | 3 +- include/Nazara/Shader/Ast/Module.inl | 3 +- include/Nazara/Shader/Ast/Nodes.hpp | 2 +- .../Nazara/Shader/DirectoryModuleResolver.hpp | 45 -------------- .../Nazara/Shader/DirectoryModuleResolver.inl | 36 ----------- .../Shader/FilesystemModuleResolver.hpp | 44 +++++++++++++ .../Shader/FilesystemModuleResolver.inl | 12 ++++ include/Nazara/Shader/ShaderBuilder.hpp | 2 +- include/Nazara/Shader/ShaderBuilder.inl | 4 +- include/Nazara/Shader/ShaderLangParser.hpp | 1 + .../Nazara/Shader/ShaderModuleResolver.hpp | 2 +- src/Nazara/Graphics/Graphics.cpp | 27 +++----- .../Shaders/Modules/Engine/InstanceData.nzsl | 4 +- .../Shaders/Modules/Engine/LightData.nzsl | 2 +- .../Shaders/Modules/Engine/ViewerData.nzsl | 2 +- .../Resources/Shaders/basic_material.nzsl | 4 +- .../Resources/Shaders/depth_material.nzsl | 4 +- .../Resources/Shaders/phong_material.nzsl | 6 +- src/Nazara/Shader/Ast/AstCloner.cpp | 2 +- src/Nazara/Shader/Ast/AstSerializer.cpp | 6 +- src/Nazara/Shader/Ast/SanitizeVisitor.cpp | 24 +------- src/Nazara/Shader/DirectoryModuleResolver.cpp | 56 ----------------- .../Shader/FilesystemModuleResolver.cpp | 61 +++++++++++++++++++ src/Nazara/Shader/LangWriter.cpp | 15 +---- src/Nazara/Shader/ShaderLangParser.cpp | 47 ++++++++------ tests/Engine/Shader/ModuleTests.cpp | 28 ++++----- 40 files changed, 224 insertions(+), 271 deletions(-) delete mode 100644 include/Nazara/Shader/DirectoryModuleResolver.hpp delete mode 100644 include/Nazara/Shader/DirectoryModuleResolver.inl create mode 100644 include/Nazara/Shader/FilesystemModuleResolver.hpp create mode 100644 include/Nazara/Shader/FilesystemModuleResolver.inl delete mode 100644 src/Nazara/Shader/DirectoryModuleResolver.cpp create mode 100644 src/Nazara/Shader/FilesystemModuleResolver.cpp diff --git a/bin/resources/bloom_bright.nzsl b/bin/resources/bloom_bright.nzsl index 4abd3bb24..620ac821c 100644 --- a/bin/resources/bloom_bright.nzsl +++ b/bin/resources/bloom_bright.nzsl @@ -1,7 +1,7 @@ [nzsl_version("1.0")] module; -import Engine/ViewerData; +import Engine.ViewerData; external { diff --git a/bin/resources/bloom_final.nzsl b/bin/resources/bloom_final.nzsl index d881239da..6cdd0a0ca 100644 --- a/bin/resources/bloom_final.nzsl +++ b/bin/resources/bloom_final.nzsl @@ -1,7 +1,7 @@ [nzsl_version("1.0")] module; -import Engine/ViewerData; +import Engine.ViewerData; external { diff --git a/bin/resources/deferred_frag.nzsl b/bin/resources/deferred_frag.nzsl index 6fecfa484..110788172 100644 --- a/bin/resources/deferred_frag.nzsl +++ b/bin/resources/deferred_frag.nzsl @@ -1,8 +1,8 @@ [nzsl_version("1.0")] module; -import Engine/InstanceData; -import Engine/ViewerData; +import Engine.InstanceData; +import Engine.ViewerData; option HasDiffuseTexture: bool = false; option HasAlphaTexture: bool = false; diff --git a/bin/resources/deferred_vert.nzsl b/bin/resources/deferred_vert.nzsl index 1d6a4f7e2..c9ddffe18 100644 --- a/bin/resources/deferred_vert.nzsl +++ b/bin/resources/deferred_vert.nzsl @@ -1,8 +1,8 @@ [nzsl_version("1.0")] module; -import Engine/InstanceData; -import Engine/ViewerData; +import Engine.InstanceData; +import Engine.ViewerData; [layout(std140)] struct BasicSettings diff --git a/bin/resources/gaussian_blur.nzsl b/bin/resources/gaussian_blur.nzsl index ac69a9ef8..246f95b54 100644 --- a/bin/resources/gaussian_blur.nzsl +++ b/bin/resources/gaussian_blur.nzsl @@ -1,7 +1,7 @@ [nzsl_version("1.0")] module; -import Engine/ViewerData; +import Engine.ViewerData; [layout(std140)] struct BlurData diff --git a/bin/resources/god_rays.nzsl b/bin/resources/god_rays.nzsl index 614a02f83..38d2dc2d1 100644 --- a/bin/resources/god_rays.nzsl +++ b/bin/resources/god_rays.nzsl @@ -1,7 +1,7 @@ [nzsl_version("1.0")] module; -import Engine/ViewerData; +import Engine.ViewerData; [layout(std140)] struct Settings diff --git a/bin/resources/lighting.nzsl b/bin/resources/lighting.nzsl index 72244b0dd..c7c898bf3 100644 --- a/bin/resources/lighting.nzsl +++ b/bin/resources/lighting.nzsl @@ -1,7 +1,7 @@ [nzsl_version("1.0")] module; -import Engine/ViewerData; +import Engine.ViewerData; [layout(std140)] struct PointLight diff --git a/bin/resources/skybox.nzsl b/bin/resources/skybox.nzsl index ca04ecba9..1d9919f22 100644 --- a/bin/resources/skybox.nzsl +++ b/bin/resources/skybox.nzsl @@ -1,7 +1,7 @@ [nzsl_version("1.0")] module; -import Engine/ViewerData; +import Engine.ViewerData; external { diff --git a/bin/resources/tone_mapping.nzsl b/bin/resources/tone_mapping.nzsl index 18747ebc7..07dd49606 100644 --- a/bin/resources/tone_mapping.nzsl +++ b/bin/resources/tone_mapping.nzsl @@ -1,7 +1,7 @@ [nzsl_version("1.0")] module; -import Engine/ViewerData; +import Engine.ViewerData; external { diff --git a/examples/RenderTest/main.cpp b/examples/RenderTest/main.cpp index b19abed6c..e7705b8de 100644 --- a/examples/RenderTest/main.cpp +++ b/examples/RenderTest/main.cpp @@ -12,7 +12,7 @@ NAZARA_REQUEST_DEDICATED_GPU() const char barModuleSource[] = R"( [nzsl_version("1.0")] [uuid("4BB09DEE-F70A-442E-859F-E8F2F3F8583D")] -module; +module Test.Bar; fn dummy() {} @@ -26,9 +26,9 @@ struct Bar const char dataModuleSource[] = R"( [nzsl_version("1.0")] [uuid("E49DC9AD-469C-462C-9719-A6F012372029")] -module; +module Test.Data; -import Test/Bar; +import Test.Bar; struct Foo {} @@ -47,8 +47,8 @@ const char shaderSource[] = R"( [nzsl_version("1.0")] module; -import Test/Data; -import Test/Bar; +import Test.Data; +import Test.Bar; option red: bool = false; @@ -140,9 +140,9 @@ int main() return __LINE__; } - auto directoryModuleResolver = std::make_shared(); - directoryModuleResolver->RegisterModuleFile("Test/Bar", barModuleSource, sizeof(barModuleSource)); - directoryModuleResolver->RegisterModuleFile("Test/Data", dataModuleSource, sizeof(dataModuleSource)); + auto directoryModuleResolver = std::make_shared(); + directoryModuleResolver->RegisterModule(std::string_view(barModuleSource)); + directoryModuleResolver->RegisterModule(std::string_view(dataModuleSource)); Nz::ShaderAst::SanitizeVisitor::Options sanitizeOpt; sanitizeOpt.moduleResolver = directoryModuleResolver; diff --git a/include/Nazara/Graphics/Graphics.hpp b/include/Nazara/Graphics/Graphics.hpp index 8f7076854..e86320954 100644 --- a/include/Nazara/Graphics/Graphics.hpp +++ b/include/Nazara/Graphics/Graphics.hpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include namespace Nz @@ -46,7 +46,7 @@ namespace Nz inline const std::shared_ptr& GetRenderDevice() const; inline const RenderPassCache& GetRenderPassCache() const; inline TextureSamplerCache& GetSamplerCache(); - inline const std::shared_ptr& GetShaderModuleResolver() const; + inline const std::shared_ptr& GetShaderModuleResolver() const; struct Config { @@ -69,7 +69,7 @@ namespace Nz std::optional m_renderPassCache; std::optional m_samplerCache; - std::shared_ptr m_shaderModuleResolver; + std::shared_ptr m_shaderModuleResolver; std::shared_ptr m_fullscreenVertexBuffer; std::shared_ptr m_renderDevice; std::shared_ptr m_blitPipeline; diff --git a/include/Nazara/Graphics/Graphics.inl b/include/Nazara/Graphics/Graphics.inl index b163b5c61..d67184ee4 100644 --- a/include/Nazara/Graphics/Graphics.inl +++ b/include/Nazara/Graphics/Graphics.inl @@ -63,7 +63,7 @@ namespace Nz return *m_samplerCache; } - inline const std::shared_ptr& Graphics::GetShaderModuleResolver() const + inline const std::shared_ptr& Graphics::GetShaderModuleResolver() const { return m_shaderModuleResolver; } diff --git a/include/Nazara/Shader.hpp b/include/Nazara/Shader.hpp index 8c67dd146..4f3225821 100644 --- a/include/Nazara/Shader.hpp +++ b/include/Nazara/Shader.hpp @@ -30,7 +30,7 @@ #define NAZARA_GLOBAL_SHADER_HPP #include -#include +#include #include #include #include diff --git a/include/Nazara/Shader/Ast/AstCompare.inl b/include/Nazara/Shader/Ast/AstCompare.inl index 66ad7e59f..1d4796379 100644 --- a/include/Nazara/Shader/Ast/AstCompare.inl +++ b/include/Nazara/Shader/Ast/AstCompare.inl @@ -56,6 +56,9 @@ namespace Nz::ShaderAst if (!Compare(lhs.moduleId, rhs.moduleId)) return false; + if (!Compare(lhs.moduleName, rhs.moduleName)) + return false; + if (!Compare(lhs.shaderLangVersion, rhs.shaderLangVersion)) return false; @@ -601,7 +604,7 @@ namespace Nz::ShaderAst bool Compare(const ImportStatement& lhs, const ImportStatement& rhs) { - if (!Compare(lhs.modulePath, rhs.modulePath)) + if (!Compare(lhs.moduleName, rhs.moduleName)) return false; return true; diff --git a/include/Nazara/Shader/Ast/Module.hpp b/include/Nazara/Shader/Ast/Module.hpp index b2848ef60..301464d98 100644 --- a/include/Nazara/Shader/Ast/Module.hpp +++ b/include/Nazara/Shader/Ast/Module.hpp @@ -25,7 +25,7 @@ namespace Nz::ShaderAst struct ImportedModule; struct Metadata; - inline Module(UInt32 shaderLangVersion, const Uuid& moduleId = Uuid::Generate()); + inline Module(UInt32 shaderLangVersion, std::string moduleName, const Uuid& moduleId = Uuid::Generate()); inline Module(std::shared_ptr metadata, std::vector importedModules = {}); inline Module(std::shared_ptr metadata, MultiStatementPtr rootNode, std::vector importedModules = {}); Module(const Module&) = default; @@ -43,6 +43,7 @@ namespace Nz::ShaderAst struct Metadata { + std::string moduleName; UInt32 shaderLangVersion; Uuid moduleId; }; diff --git a/include/Nazara/Shader/Ast/Module.inl b/include/Nazara/Shader/Ast/Module.inl index c3595efb8..2f5578496 100644 --- a/include/Nazara/Shader/Ast/Module.inl +++ b/include/Nazara/Shader/Ast/Module.inl @@ -8,10 +8,11 @@ namespace Nz::ShaderAst { - inline Module::Module(UInt32 shaderLangVersion, const Uuid& uuid) + inline Module::Module(UInt32 shaderLangVersion, std::string moduleName, const Uuid& uuid) { auto mutMetadata = std::make_shared(); mutMetadata->moduleId = uuid; + mutMetadata->moduleName = std::move(moduleName); mutMetadata->shaderLangVersion = shaderLangVersion; metadata = std::move(mutMetadata); diff --git a/include/Nazara/Shader/Ast/Nodes.hpp b/include/Nazara/Shader/Ast/Nodes.hpp index 2e6921332..61bc382b2 100644 --- a/include/Nazara/Shader/Ast/Nodes.hpp +++ b/include/Nazara/Shader/Ast/Nodes.hpp @@ -414,7 +414,7 @@ namespace Nz::ShaderAst NodeType GetType() const override; void Visit(AstStatementVisitor& visitor) override; - std::vector modulePath; + std::string moduleName; }; struct NAZARA_SHADER_API MultiStatement : Statement diff --git a/include/Nazara/Shader/DirectoryModuleResolver.hpp b/include/Nazara/Shader/DirectoryModuleResolver.hpp deleted file mode 100644 index 6e3cdc822..000000000 --- a/include/Nazara/Shader/DirectoryModuleResolver.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com) -// This file is part of the "Nazara Engine - Shader module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef NAZARA_SHADER_DIRECTORYMODULERESOLVER_HPP -#define NAZARA_SHADER_DIRECTORYMODULERESOLVER_HPP - -#include -#include -#include -#include -#include -#include - -namespace Nz -{ - class NAZARA_SHADER_API DirectoryModuleResolver : public ShaderModuleResolver - { - public: - inline DirectoryModuleResolver(); - DirectoryModuleResolver(const DirectoryModuleResolver&) = delete; - DirectoryModuleResolver(DirectoryModuleResolver&&) = delete; - ~DirectoryModuleResolver() = default; - - inline void RegisterModuleDirectory(std::string_view path, std::filesystem::path realPath); - inline void RegisterModuleFile(std::string_view path, std::filesystem::path realPath); - inline void RegisterModuleFile(std::string_view path, std::vector fileContent); - inline void RegisterModuleFile(std::string_view path, const void* staticData, std::size_t size); - - ShaderAst::ModulePtr Resolve(const std::vector& modulePath) override; - - DirectoryModuleResolver& operator=(const DirectoryModuleResolver&) = delete; - DirectoryModuleResolver& operator=(DirectoryModuleResolver&&) = delete; - - private: - std::shared_ptr m_searchDirectory; - std::unordered_map m_knownModules; - }; -} - -#include - -#endif // NAZARA_SHADER_DIRECTORYMODULERESOLVER_HPP diff --git a/include/Nazara/Shader/DirectoryModuleResolver.inl b/include/Nazara/Shader/DirectoryModuleResolver.inl deleted file mode 100644 index 97bf0a06a..000000000 --- a/include/Nazara/Shader/DirectoryModuleResolver.inl +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com) -// This file is part of the "Nazara Engine - Shader module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include - -namespace Nz -{ - inline DirectoryModuleResolver::DirectoryModuleResolver() : - m_searchDirectory(std::make_shared()) - { - } - - inline void DirectoryModuleResolver::RegisterModuleDirectory(std::string_view path, std::filesystem::path realPath) - { - m_searchDirectory->StoreDirectory(path, realPath); - } - - inline void DirectoryModuleResolver::RegisterModuleFile(std::string_view path, std::filesystem::path realPath) - { - m_searchDirectory->StoreFile(path, realPath); - } - - inline void DirectoryModuleResolver::RegisterModuleFile(std::string_view path, std::vector fileContent) - { - m_searchDirectory->StoreFile(path, std::move(fileContent)); - } - - inline void DirectoryModuleResolver::RegisterModuleFile(std::string_view path, const void* staticData, std::size_t size) - { - m_searchDirectory->StoreFile(path, staticData, size); - } -} - -#include diff --git a/include/Nazara/Shader/FilesystemModuleResolver.hpp b/include/Nazara/Shader/FilesystemModuleResolver.hpp new file mode 100644 index 000000000..d2ce86ade --- /dev/null +++ b/include/Nazara/Shader/FilesystemModuleResolver.hpp @@ -0,0 +1,44 @@ +// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com) +// This file is part of the "Nazara Engine - Shader module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_SHADER_FILESYSTEMMODULERESOLVER_HPP +#define NAZARA_SHADER_FILESYSTEMMODULERESOLVER_HPP + +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_SHADER_API FilesystemModuleResolver : public ShaderModuleResolver + { + public: + FilesystemModuleResolver() = default; + FilesystemModuleResolver(const FilesystemModuleResolver&) = default; + FilesystemModuleResolver(FilesystemModuleResolver&&) = default; + ~FilesystemModuleResolver() = default; + + void RegisterModule(std::filesystem::path realPath); + void RegisterModule(std::string_view moduleSource); + void RegisterModule(ShaderAst::ModulePtr module); + void RegisterModuleDirectory(std::filesystem::path realPath); + + ShaderAst::ModulePtr Resolve(const std::string& moduleName) override; + + FilesystemModuleResolver& operator=(const FilesystemModuleResolver&) = default; + FilesystemModuleResolver& operator=(FilesystemModuleResolver&&) = default; + + private: + std::unordered_map m_modules; + }; +} + +#include + +#endif // NAZARA_SHADER_FILESYSTEMMODULERESOLVER_HPP diff --git a/include/Nazara/Shader/FilesystemModuleResolver.inl b/include/Nazara/Shader/FilesystemModuleResolver.inl new file mode 100644 index 000000000..8ba355c2f --- /dev/null +++ b/include/Nazara/Shader/FilesystemModuleResolver.inl @@ -0,0 +1,12 @@ +// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com) +// This file is part of the "Nazara Engine - Shader module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ +} + +#include diff --git a/include/Nazara/Shader/ShaderBuilder.hpp b/include/Nazara/Shader/ShaderBuilder.hpp index db39b9a33..9c48a0431 100644 --- a/include/Nazara/Shader/ShaderBuilder.hpp +++ b/include/Nazara/Shader/ShaderBuilder.hpp @@ -139,7 +139,7 @@ namespace Nz::ShaderBuilder struct Import { - inline ShaderAst::ImportStatementPtr operator()(std::vector modulePath) const; + inline ShaderAst::ImportStatementPtr operator()(std::string modulePath) const; }; struct Intrinsic diff --git a/include/Nazara/Shader/ShaderBuilder.inl b/include/Nazara/Shader/ShaderBuilder.inl index 591394f56..bff5bc9a2 100644 --- a/include/Nazara/Shader/ShaderBuilder.inl +++ b/include/Nazara/Shader/ShaderBuilder.inl @@ -365,10 +365,10 @@ namespace Nz::ShaderBuilder return identifierNode; } - inline ShaderAst::ImportStatementPtr Impl::Import::operator()(std::vector modulePath) const + inline ShaderAst::ImportStatementPtr Impl::Import::operator()(std::string moduleName) const { auto importNode = std::make_unique(); - importNode->modulePath = std::move(modulePath); + importNode->moduleName = std::move(moduleName); return importNode; } diff --git a/include/Nazara/Shader/ShaderLangParser.hpp b/include/Nazara/Shader/ShaderLangParser.hpp index d135b31f4..16fd84e53 100644 --- a/include/Nazara/Shader/ShaderLangParser.hpp +++ b/include/Nazara/Shader/ShaderLangParser.hpp @@ -121,6 +121,7 @@ namespace Nz::ShaderLang ShaderAst::AttributeType ParseIdentifierAsAttributeType(); const std::string& ParseIdentifierAsName(); + std::string ParseModuleName(); ShaderAst::ExpressionPtr ParseType(); static int GetTokenPrecedence(TokenType token); diff --git a/include/Nazara/Shader/ShaderModuleResolver.hpp b/include/Nazara/Shader/ShaderModuleResolver.hpp index 0efaaa901..224479d60 100644 --- a/include/Nazara/Shader/ShaderModuleResolver.hpp +++ b/include/Nazara/Shader/ShaderModuleResolver.hpp @@ -28,7 +28,7 @@ namespace Nz ShaderModuleResolver(ShaderModuleResolver&&) = default; virtual ~ShaderModuleResolver(); - virtual ShaderAst::ModulePtr Resolve(const std::vector& /*modulePath*/) = 0; + virtual ShaderAst::ModulePtr Resolve(const std::string& /*moduleName*/) = 0; ShaderModuleResolver& operator=(const ShaderModuleResolver&) = default; ShaderModuleResolver& operator=(ShaderModuleResolver&&) = default; diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index 957c59dfc..28c0c67bd 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -221,27 +221,18 @@ namespace Nz void Graphics::RegisterShaderModules() { - m_shaderModuleResolver = std::make_shared(); - m_shaderModuleResolver->RegisterModuleFile("Engine/InstanceData", r_instanceDataModule, sizeof(r_instanceDataModule)); - m_shaderModuleResolver->RegisterModuleFile("Engine/LightData", r_lightDataModule, sizeof(r_lightDataModule)); - m_shaderModuleResolver->RegisterModuleFile("Engine/ViewerData", r_viewerDataModule, sizeof(r_viewerDataModule)); + m_shaderModuleResolver = std::make_shared(); + m_shaderModuleResolver->RegisterModule(std::string_view(reinterpret_cast(r_instanceDataModule), sizeof(r_instanceDataModule))); + m_shaderModuleResolver->RegisterModule(std::string_view(reinterpret_cast(r_lightDataModule), sizeof(r_lightDataModule))); + m_shaderModuleResolver->RegisterModule(std::string_view(reinterpret_cast(r_viewerDataModule), sizeof(r_viewerDataModule))); + + if (std::filesystem::path shaderPath = "Shaders/Modules"; std::filesystem::is_directory(shaderPath)) + m_shaderModuleResolver->RegisterModuleDirectory(shaderPath); #ifdef NAZARA_DEBUG // Override embed files with dev files in debug - std::filesystem::path modulePath = "../../src/Nazara/Graphics/Resources/Shaders/Modules"; - if (std::filesystem::is_directory(modulePath)) - { - for (const auto& dirEntry : std::filesystem::recursive_directory_iterator(modulePath)) - { - if (!dirEntry.is_regular_file()) - continue; - - std::filesystem::path filePath = std::filesystem::relative(dirEntry.path(), modulePath); - filePath.replace_extension(); - - m_shaderModuleResolver->RegisterModuleFile(filePath.generic_u8string(), dirEntry.path()); - } - } + if (std::filesystem::path modulePath = "../../src/Nazara/Graphics/Resources/Shaders/Modules"; std::filesystem::is_directory(modulePath)) + m_shaderModuleResolver->RegisterModuleDirectory(modulePath); #endif } diff --git a/src/Nazara/Graphics/Resources/Shaders/Modules/Engine/InstanceData.nzsl b/src/Nazara/Graphics/Resources/Shaders/Modules/Engine/InstanceData.nzsl index 9f5f66b49..a3d1f33f3 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Modules/Engine/InstanceData.nzsl +++ b/src/Nazara/Graphics/Resources/Shaders/Modules/Engine/InstanceData.nzsl @@ -1,6 +1,6 @@ [nzsl_version("1.0")] -module; - +module Engine.InstanceData; + [export] [layout(std140)] struct InstanceData diff --git a/src/Nazara/Graphics/Resources/Shaders/Modules/Engine/LightData.nzsl b/src/Nazara/Graphics/Resources/Shaders/Modules/Engine/LightData.nzsl index f7220d00f..a4a2b699a 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Modules/Engine/LightData.nzsl +++ b/src/Nazara/Graphics/Resources/Shaders/Modules/Engine/LightData.nzsl @@ -1,5 +1,5 @@ [nzsl_version("1.0")] -module; +module Engine.LightData; option MaxLightCount: u32 = u32(3); //< FIXME: Fix integral value types diff --git a/src/Nazara/Graphics/Resources/Shaders/Modules/Engine/ViewerData.nzsl b/src/Nazara/Graphics/Resources/Shaders/Modules/Engine/ViewerData.nzsl index 1c2898175..5cbccace8 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Modules/Engine/ViewerData.nzsl +++ b/src/Nazara/Graphics/Resources/Shaders/Modules/Engine/ViewerData.nzsl @@ -1,5 +1,5 @@ [nzsl_version("1.0")] -module; +module Engine.ViewerData; [export] [layout(std140)] diff --git a/src/Nazara/Graphics/Resources/Shaders/basic_material.nzsl b/src/Nazara/Graphics/Resources/Shaders/basic_material.nzsl index 606d8dd71..531929d8a 100644 --- a/src/Nazara/Graphics/Resources/Shaders/basic_material.nzsl +++ b/src/Nazara/Graphics/Resources/Shaders/basic_material.nzsl @@ -1,8 +1,8 @@ [nzsl_version("1.0")] module; -import Engine/InstanceData; -import Engine/ViewerData; +import Engine.InstanceData; +import Engine.ViewerData; option HasDiffuseTexture: bool = false; option HasAlphaTexture: bool = false; diff --git a/src/Nazara/Graphics/Resources/Shaders/depth_material.nzsl b/src/Nazara/Graphics/Resources/Shaders/depth_material.nzsl index 18f4212b5..247ae2f59 100644 --- a/src/Nazara/Graphics/Resources/Shaders/depth_material.nzsl +++ b/src/Nazara/Graphics/Resources/Shaders/depth_material.nzsl @@ -1,8 +1,8 @@ [nzsl_version("1.0")] module; -import Engine/InstanceData; -import Engine/ViewerData; +import Engine.InstanceData; +import Engine.ViewerData; option HasDiffuseTexture: bool = false; option HasAlphaTexture: bool = false; diff --git a/src/Nazara/Graphics/Resources/Shaders/phong_material.nzsl b/src/Nazara/Graphics/Resources/Shaders/phong_material.nzsl index e881fc61b..9065421ff 100644 --- a/src/Nazara/Graphics/Resources/Shaders/phong_material.nzsl +++ b/src/Nazara/Graphics/Resources/Shaders/phong_material.nzsl @@ -1,9 +1,9 @@ [nzsl_version("1.0")] module; -import Engine/InstanceData; -import Engine/LightData; -import Engine/ViewerData; +import Engine.InstanceData; +import Engine.LightData; +import Engine.ViewerData; // Basic material options option HasDiffuseTexture: bool = false; diff --git a/src/Nazara/Shader/Ast/AstCloner.cpp b/src/Nazara/Shader/Ast/AstCloner.cpp index 5dfaf253b..5dc57be47 100644 --- a/src/Nazara/Shader/Ast/AstCloner.cpp +++ b/src/Nazara/Shader/Ast/AstCloner.cpp @@ -228,7 +228,7 @@ namespace Nz::ShaderAst StatementPtr AstCloner::Clone(ImportStatement& node) { auto clone = std::make_unique(); - clone->modulePath = node.modulePath; + clone->moduleName = node.moduleName; return clone; } diff --git a/src/Nazara/Shader/Ast/AstSerializer.cpp b/src/Nazara/Shader/Ast/AstSerializer.cpp index c889d3492..94611d465 100644 --- a/src/Nazara/Shader/Ast/AstSerializer.cpp +++ b/src/Nazara/Shader/Ast/AstSerializer.cpp @@ -340,9 +340,7 @@ namespace Nz::ShaderAst void AstSerializerBase::Serialize(ImportStatement& node) { - Container(node.modulePath); - for (auto& path : node.modulePath) - Value(path); + Value(node.moduleName); } void AstSerializerBase::Serialize(MultiStatement& node) @@ -385,6 +383,7 @@ namespace Nz::ShaderAst void ShaderAstSerializer::SerializeModule(ModulePtr& module) { + m_stream << module->metadata->moduleName; m_stream << module->metadata->moduleId; m_stream << module->metadata->shaderLangVersion; @@ -604,6 +603,7 @@ namespace Nz::ShaderAst void ShaderAstUnserializer::SerializeModule(ModulePtr& module) { std::shared_ptr metadata = std::make_shared(); + m_stream >> metadata->moduleName; m_stream >> metadata->moduleId; m_stream >> metadata->shaderLangVersion; diff --git a/src/Nazara/Shader/Ast/SanitizeVisitor.cpp b/src/Nazara/Shader/Ast/SanitizeVisitor.cpp index 284d81c42..79b5aed88 100644 --- a/src/Nazara/Shader/Ast/SanitizeVisitor.cpp +++ b/src/Nazara/Shader/Ast/SanitizeVisitor.cpp @@ -1448,27 +1448,9 @@ namespace Nz::ShaderAst if (!m_context->options.moduleResolver) return static_unique_pointer_cast(AstCloner::Clone(node)); - auto ModulePathAsString = [&]() -> std::string - { - std::ostringstream ss; - - bool first = true; - for (const std::string& part : node.modulePath) - { - if (!first) - ss << "/"; - - ss << part; - - first = false; - } - - return ss.str(); - }; - - ModulePtr targetModule = m_context->options.moduleResolver->Resolve(node.modulePath); + ModulePtr targetModule = m_context->options.moduleResolver->Resolve(node.moduleName); if (!targetModule) - throw AstError{ "module " + ModulePathAsString() + " not found" }; + throw AstError{ "module " + node.moduleName + " not found" }; std::size_t moduleIndex; @@ -1500,7 +1482,7 @@ namespace Nz::ShaderAst std::string error; sanitizedModule->rootNode = SanitizeInternal(*targetModule->rootNode, &error); if (!sanitizedModule) - throw AstError{ "module " + ModulePathAsString() + " compilation failed: " + error }; + throw AstError{ "module " + node.moduleName + " compilation failed: " + error }; moduleIndex = m_context->modules.size(); diff --git a/src/Nazara/Shader/DirectoryModuleResolver.cpp b/src/Nazara/Shader/DirectoryModuleResolver.cpp deleted file mode 100644 index 4a6e80d6b..000000000 --- a/src/Nazara/Shader/DirectoryModuleResolver.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com) -// This file is part of the "Nazara Engine - Shader module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include - -namespace Nz -{ - ShaderAst::ModulePtr DirectoryModuleResolver::Resolve(const std::vector& modulePath) - { - if (modulePath.empty()) - return {}; - - std::string fullPath; - for (const auto& part : modulePath) - { - if (!fullPath.empty()) - fullPath += '/'; - - fullPath += part; - } - - if (auto it = m_knownModules.find(fullPath); it != m_knownModules.end()) - return it->second; - - ShaderAst::ModulePtr shaderModule; - m_searchDirectory->GetEntry(fullPath, [&](const VirtualDirectory::Entry& entry) - { - if (std::holds_alternative(entry)) - { - const auto& dataContent = std::get(entry); - shaderModule = ShaderLang::Parse(std::string_view(reinterpret_cast(dataContent.data), dataContent.size)); - } - else if (std::holds_alternative(entry)) - { - const auto& fileContent = std::get(entry); - shaderModule = ShaderLang::Parse(std::string_view(reinterpret_cast(fileContent.data.data()), fileContent.data.size())); - } - else if (std::holds_alternative(entry)) - { - const auto& physicalEntry = std::get(entry); - shaderModule = ShaderLang::ParseFromFile(physicalEntry.filePath); - } - }); - - if (!shaderModule) - return {}; - - m_knownModules.emplace(std::move(fullPath), shaderModule); - - return shaderModule; - } -} diff --git a/src/Nazara/Shader/FilesystemModuleResolver.cpp b/src/Nazara/Shader/FilesystemModuleResolver.cpp new file mode 100644 index 000000000..87e39b6ab --- /dev/null +++ b/src/Nazara/Shader/FilesystemModuleResolver.cpp @@ -0,0 +1,61 @@ +// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com) +// This file is part of the "Nazara Engine - Shader module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + void FilesystemModuleResolver::RegisterModule(std::filesystem::path realPath) + { + return RegisterModule(ShaderLang::ParseFromFile(realPath)); + } + + void FilesystemModuleResolver::RegisterModule(std::string_view moduleSource) + { + return RegisterModule(ShaderLang::Parse(moduleSource)); + } + + void FilesystemModuleResolver::RegisterModule(ShaderAst::ModulePtr module) + { + assert(module); + + std::string moduleName = module->metadata->moduleName; + if (moduleName.empty()) + throw std::runtime_error("cannot register anonymous module"); + + m_modules.emplace(std::move(moduleName), std::move(module)); + } + + void FilesystemModuleResolver::RegisterModuleDirectory(std::filesystem::path realPath) + { + for (const auto& entry : std::filesystem::recursive_directory_iterator(realPath)) + { + if (entry.is_regular_file() && StringEqual(entry.path().extension().generic_u8string(), "nzsl", Nz::CaseIndependent{})) + { + try + { + RegisterModule(entry.path()); + } + catch (const std::exception& e) + { + NazaraWarning("failed to register module " + entry.path().generic_u8string() + ": " + e.what()); + } + } + } + } + + ShaderAst::ModulePtr FilesystemModuleResolver::Resolve(const std::string& moduleName) + { + auto it = m_modules.find(moduleName); + if (it == m_modules.end()) + return {}; + + return it->second; + } +} diff --git a/src/Nazara/Shader/LangWriter.cpp b/src/Nazara/Shader/LangWriter.cpp index 1905dd0ac..e3361a581 100644 --- a/src/Nazara/Shader/LangWriter.cpp +++ b/src/Nazara/Shader/LangWriter.cpp @@ -1144,20 +1144,7 @@ namespace Nz void LangWriter::Visit(ShaderAst::ImportStatement& node) { - Append("import "); - - bool first = true; - for (const std::string& path : node.modulePath) - { - if (!first) - Append("/"); - - Append(path); - - first = false; - } - - AppendLine(";"); + Append("import ", node.moduleName, ";"); } void LangWriter::Visit(ShaderAst::IntrinsicExpression& node) diff --git a/src/Nazara/Shader/ShaderLangParser.cpp b/src/Nazara/Shader/ShaderLangParser.cpp index c4d3f9c2d..778f9ba52 100644 --- a/src/Nazara/Shader/ShaderLangParser.cpp +++ b/src/Nazara/Shader/ShaderLangParser.cpp @@ -335,17 +335,12 @@ namespace Nz::ShaderLang if (!moduleId) moduleId = Uuid::Generate(); - auto module = std::make_shared(*moduleVersion, *moduleId); - - if (Peek().type == TokenType::Identifier) + if (m_context->module) { + std::string moduleName = ParseModuleName(); + auto module = std::make_shared(*moduleVersion, std::move(moduleName), *moduleId); + // Imported module - if (!m_context->module) - throw UnexpectedToken{}; //< "unexpected token before module declaration" - - const std::string& identifier = std::get(Peek().data); - Consume(); - Expect(Advance(), TokenType::OpenCurlyBracket); m_context->parsingImportedModule = true; @@ -364,10 +359,17 @@ namespace Nz::ShaderLang auto& importedModule = m_context->module->importedModules.emplace_back(); importedModule.module = std::move(module); - importedModule.identifier = identifier; + importedModule.identifier = importedModule.module->metadata->moduleName; } else { + std::string moduleName; + if (Peek().type == TokenType::Identifier) + moduleName = ParseModuleName(); + + auto module = std::make_shared(*moduleVersion, std::move(moduleName), *moduleId); + + // First declaration Expect(Advance(), TokenType::Semicolon); if (m_context->module) @@ -732,19 +734,11 @@ namespace Nz::ShaderLang { Expect(Advance(), TokenType::Import); - std::vector modulePath; - modulePath.push_back(ParseIdentifierAsName()); - - while (Peek().type == TokenType::Divide) //< / - { - Consume(); - - modulePath.push_back(ParseIdentifierAsName()); - } + std::string moduleName = ParseModuleName(); Expect(Advance(), TokenType::Semicolon); - return ShaderBuilder::Import(std::move(modulePath)); + return ShaderBuilder::Import(std::move(moduleName)); } ShaderAst::StatementPtr Parser::ParseOptionDeclaration() @@ -1371,6 +1365,19 @@ namespace Nz::ShaderLang return std::get(identifierToken.data); } + std::string Parser::ParseModuleName() + { + std::string moduleName = ParseIdentifierAsName(); + while (Peek().type == TokenType::Dot) + { + Consume(); + moduleName += '.'; + moduleName += ParseIdentifierAsName(); + } + + return moduleName; + } + ShaderAst::ExpressionPtr Parser::ParseType() { // Handle () as no type diff --git a/tests/Engine/Shader/ModuleTests.cpp b/tests/Engine/Shader/ModuleTests.cpp index ba0e28441..39270c1c5 100644 --- a/tests/Engine/Shader/ModuleTests.cpp +++ b/tests/Engine/Shader/ModuleTests.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include @@ -17,7 +17,7 @@ TEST_CASE("Modules", "[Shader]") std::string_view importedSource = R"( [nzsl_version("1.0")] [uuid("ad3aed6e-0619-4a26-b5ce-abc2ec0836c4")] -module; +module SimpleModule; [layout(std140)] struct Data @@ -69,8 +69,8 @@ fn main(input: InputData) -> OutputData Nz::ShaderAst::ModulePtr shaderModule = Nz::ShaderLang::Parse(shaderSource); - auto directoryModuleResolver = std::make_shared(); - directoryModuleResolver->RegisterModuleFile("SimpleModule", importedSource.data(), importedSource.size()); + auto directoryModuleResolver = std::make_shared(); + directoryModuleResolver->RegisterModule(importedSource); Nz::ShaderAst::SanitizeVisitor::Options sanitizeOpt; sanitizeOpt.moduleResolver = directoryModuleResolver; @@ -202,7 +202,7 @@ OpFunctionEnd)"); std::string_view dataModule = R"( [nzsl_version("1.0")] [uuid("ad3aed6e-0619-4a26-b5ce-abc2ec0836c4")] -module; +module Modules.Data; fn dummy() {} @@ -217,9 +217,9 @@ struct Data std::string_view blockModule = R"( [nzsl_version("1.0")] [uuid("7a548506-89e6-4944-897f-4f695a8bca01")] -module; +module Modules.Block; -import Modules/Data; +import Modules.Data; [export] [layout(std140)] @@ -234,7 +234,7 @@ struct Unused {} std::string_view inputOutputModule = R"( [nzsl_version("1.0")] [uuid("e66c6e98-fc37-4390-a7e1-c81508ff8e49")] -module; +module Modules.InputOutput; [export] struct InputData @@ -253,8 +253,8 @@ struct OutputData [nzsl_version("1.0")] module; -import Modules/Block; -import Modules/InputOutput; +import Modules.Block; +import Modules.InputOutput; external { @@ -272,10 +272,10 @@ fn main(input: InputData) -> OutputData Nz::ShaderAst::ModulePtr shaderModule = Nz::ShaderLang::Parse(shaderSource); - auto directoryModuleResolver = std::make_shared(); - directoryModuleResolver->RegisterModuleFile("Modules/Data", dataModule.data(), dataModule.size()); - directoryModuleResolver->RegisterModuleFile("Modules/Block", blockModule.data(), blockModule.size()); - directoryModuleResolver->RegisterModuleFile("Modules/InputOutput", inputOutputModule.data(), inputOutputModule.size()); + auto directoryModuleResolver = std::make_shared(); + directoryModuleResolver->RegisterModule(dataModule); + directoryModuleResolver->RegisterModule(blockModule); + directoryModuleResolver->RegisterModule(inputOutputModule); Nz::ShaderAst::SanitizeVisitor::Options sanitizeOpt; sanitizeOpt.moduleResolver = directoryModuleResolver;