Shader: Add module resolver + use modules for engine shaders
This commit is contained in:
@@ -1398,7 +1398,7 @@ namespace Nz::ShaderAst
|
||||
|
||||
StatementPtr SanitizeVisitor::Clone(ImportStatement& node)
|
||||
{
|
||||
if (!m_context->options.moduleCallback)
|
||||
if (!m_context->options.moduleResolver)
|
||||
return static_unique_pointer_cast<ImportStatement>(AstCloner::Clone(node));
|
||||
|
||||
auto ModulePathAsString = [&]() -> std::string
|
||||
@@ -1419,7 +1419,7 @@ namespace Nz::ShaderAst
|
||||
return ss.str();
|
||||
};
|
||||
|
||||
ModulePtr targetModule = m_context->options.moduleCallback(node.modulePath);
|
||||
ModulePtr targetModule = m_context->options.moduleResolver->Resolve(node.modulePath);
|
||||
if (!targetModule)
|
||||
throw AstError{ "module " + ModulePathAsString() + " not found" };
|
||||
|
||||
@@ -1506,16 +1506,20 @@ namespace Nz::ShaderAst
|
||||
AstExportVisitor exportVisitor;
|
||||
exportVisitor.Visit(*m_context->currentModule->importedModules[moduleIndex].module->rootNode, callbacks);
|
||||
|
||||
if (aliasStatements.empty() || m_context->options.removeAliases)
|
||||
if (aliasStatements.empty())
|
||||
return ShaderBuilder::NoOp();
|
||||
|
||||
// Register module and aliases
|
||||
// Register aliases
|
||||
for (auto& aliasPtr : aliasStatements)
|
||||
Validate(*aliasPtr);
|
||||
|
||||
if (m_context->options.removeAliases)
|
||||
return ShaderBuilder::NoOp();
|
||||
|
||||
// Generate alias statements
|
||||
MultiStatementPtr aliasBlock = std::make_unique<MultiStatement>();
|
||||
for (auto& aliasPtr : aliasStatements)
|
||||
{
|
||||
Validate(*aliasPtr);
|
||||
aliasBlock->statements.push_back(std::move(aliasPtr));
|
||||
}
|
||||
|
||||
return aliasBlock;
|
||||
}
|
||||
|
||||
57
src/Nazara/Shader/DirectoryModuleResolver.cpp
Normal file
57
src/Nazara/Shader/DirectoryModuleResolver.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
// 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 <Nazara/Shader/DirectoryModuleResolver.hpp>
|
||||
#include <Nazara/Shader/ShaderLangParser.hpp>
|
||||
#include <filesystem>
|
||||
#include <Nazara/Shader/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
ShaderAst::ModulePtr DirectoryModuleResolver::Resolve(const std::vector<std::string>& 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;
|
||||
|
||||
VirtualDirectory::Entry entry;
|
||||
if (!m_searchDirectory->GetEntry(fullPath, &entry))
|
||||
return {};
|
||||
|
||||
ShaderAst::ModulePtr shaderModule;
|
||||
if (std::holds_alternative<VirtualDirectory::DataPointerEntry>(entry))
|
||||
{
|
||||
const auto& content = std::get<VirtualDirectory::DataPointerEntry>(entry);
|
||||
shaderModule = ShaderLang::Parse(std::string_view(reinterpret_cast<const char*>(content.data), content.size));
|
||||
}
|
||||
else if (std::holds_alternative<VirtualDirectory::FileContentEntry>(entry))
|
||||
{
|
||||
const auto& content = std::get<VirtualDirectory::FileContentEntry>(entry);
|
||||
shaderModule = ShaderLang::Parse(std::string_view(reinterpret_cast<const char*>(content.data->data()), content.data->size()));
|
||||
}
|
||||
else if (std::holds_alternative<VirtualDirectory::PhysicalFileEntry>(entry))
|
||||
{
|
||||
const auto& filePath = std::get<VirtualDirectory::PhysicalFileEntry>(entry);
|
||||
shaderModule = ShaderLang::ParseFromFile(filePath);
|
||||
}
|
||||
|
||||
if (!shaderModule)
|
||||
return {};
|
||||
|
||||
m_knownModules.emplace(fullPath, shaderModule);
|
||||
|
||||
return shaderModule;
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <Nazara/Shader/Ast/AstRecursiveVisitor.hpp>
|
||||
#include <Nazara/Shader/Ast/AstUtils.hpp>
|
||||
#include <Nazara/Shader/Ast/EliminateUnusedPassVisitor.hpp>
|
||||
#include <Nazara/Shader/Ast/SanitizeVisitor.hpp>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
@@ -173,7 +172,11 @@ namespace Nz
|
||||
const ShaderAst::Module* targetModule;
|
||||
if (!states.sanitized)
|
||||
{
|
||||
sanitizedModule = Sanitize(module, states.optionValues);
|
||||
ShaderAst::SanitizeVisitor::Options options = GetSanitizeOptions();
|
||||
options.optionValues = states.optionValues;
|
||||
options.moduleResolver = states.shaderModuleResolver;
|
||||
|
||||
sanitizedModule = ShaderAst::Sanitize(module, options);
|
||||
targetModule = sanitizedModule.get();
|
||||
}
|
||||
else
|
||||
@@ -227,11 +230,10 @@ namespace Nz
|
||||
return s_flipYUniformName;
|
||||
}
|
||||
|
||||
ShaderAst::ModulePtr GlslWriter::Sanitize(const ShaderAst::Module& module, std::unordered_map<UInt32, ShaderAst::ConstantValue> optionValues, std::string* error)
|
||||
ShaderAst::SanitizeVisitor::Options GlslWriter::GetSanitizeOptions()
|
||||
{
|
||||
// Always sanitize for reserved identifiers
|
||||
ShaderAst::SanitizeVisitor::Options options;
|
||||
options.optionValues = std::move(optionValues);
|
||||
options.makeVariableNameUnique = true;
|
||||
options.reduceLoopsToWhile = true;
|
||||
options.removeAliases = true;
|
||||
@@ -246,7 +248,7 @@ namespace Nz
|
||||
"cross", "dot", "exp", "length", "max", "min", "pow", "texture"
|
||||
};
|
||||
|
||||
return ShaderAst::Sanitize(module, options, error);
|
||||
return options;
|
||||
}
|
||||
|
||||
void GlslWriter::Append(const ShaderAst::AliasType& /*aliasType*/)
|
||||
|
||||
11
src/Nazara/Shader/ShaderModuleResolver.cpp
Normal file
11
src/Nazara/Shader/ShaderModuleResolver.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
// 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 <Nazara/Shader/ShaderModuleResolver.hpp>
|
||||
#include <Nazara/Shader/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
ShaderModuleResolver::~ShaderModuleResolver() = default;
|
||||
}
|
||||
@@ -503,10 +503,12 @@ namespace Nz
|
||||
if (!states.sanitized)
|
||||
{
|
||||
ShaderAst::SanitizeVisitor::Options options;
|
||||
options.moduleResolver = states.shaderModuleResolver;
|
||||
options.optionValues = states.optionValues;
|
||||
options.reduceLoopsToWhile = true;
|
||||
options.removeAliases = true;
|
||||
options.removeCompoundAssignments = true;
|
||||
options.removeConstDeclaration = true;
|
||||
options.removeMatrixCast = true;
|
||||
options.removeOptionDeclaration = true;
|
||||
options.splitMultipleBranches = true;
|
||||
|
||||
Reference in New Issue
Block a user