Shader: Many fixes
This commit is contained in:
parent
1919bd3302
commit
a2f4f3c802
|
|
@ -20,9 +20,14 @@ namespace Nz::ShaderAst
|
||||||
|
|
||||||
struct Module
|
struct Module
|
||||||
{
|
{
|
||||||
MultiStatementPtr rootNode;
|
struct Metadata
|
||||||
|
{
|
||||||
UInt32 shaderLangVersion;
|
UInt32 shaderLangVersion;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<const Metadata> metadata;
|
||||||
|
MultiStatementPtr rootNode;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // NAZARA_SHADER_AST_MODULE_HPP
|
#endif // NAZARA_SHADER_AST_MODULE_HPP
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,6 @@ namespace Nz
|
||||||
struct EntryAttribute;
|
struct EntryAttribute;
|
||||||
struct LayoutAttribute;
|
struct LayoutAttribute;
|
||||||
struct LocationAttribute;
|
struct LocationAttribute;
|
||||||
struct NzslAttribute;
|
|
||||||
struct SetAttribute;
|
struct SetAttribute;
|
||||||
struct UnrollAttribute;
|
struct UnrollAttribute;
|
||||||
|
|
||||||
|
|
@ -76,7 +75,6 @@ namespace Nz
|
||||||
void AppendAttribute(EntryAttribute entry);
|
void AppendAttribute(EntryAttribute entry);
|
||||||
void AppendAttribute(LayoutAttribute layout);
|
void AppendAttribute(LayoutAttribute layout);
|
||||||
void AppendAttribute(LocationAttribute location);
|
void AppendAttribute(LocationAttribute location);
|
||||||
void AppendAttribute(NzslAttribute nzslVersion);
|
|
||||||
void AppendAttribute(SetAttribute set);
|
void AppendAttribute(SetAttribute set);
|
||||||
void AppendAttribute(UnrollAttribute unroll);
|
void AppendAttribute(UnrollAttribute unroll);
|
||||||
void AppendCommentSection(const std::string& section);
|
void AppendCommentSection(const std::string& section);
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ namespace Nz::ShaderBuilder
|
||||||
|
|
||||||
struct DeclareStruct
|
struct DeclareStruct
|
||||||
{
|
{
|
||||||
inline std::unique_ptr<ShaderAst::DeclareStructStatement> operator()(ShaderAst::StructDescription description) const;
|
inline std::unique_ptr<ShaderAst::DeclareStructStatement> operator()(ShaderAst::StructDescription description, ShaderAst::ExpressionValue<bool> isExported) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DeclareVariable
|
struct DeclareVariable
|
||||||
|
|
|
||||||
|
|
@ -189,6 +189,7 @@ namespace Nz::ShaderBuilder
|
||||||
case ShaderAst::PrimitiveType::Float32: return ShaderBuilder::Constant(SafeCast<float>(value));
|
case ShaderAst::PrimitiveType::Float32: return ShaderBuilder::Constant(SafeCast<float>(value));
|
||||||
case ShaderAst::PrimitiveType::Int32: return ShaderBuilder::Constant(SafeCast<Int32>(value));
|
case ShaderAst::PrimitiveType::Int32: return ShaderBuilder::Constant(SafeCast<Int32>(value));
|
||||||
case ShaderAst::PrimitiveType::UInt32: return ShaderBuilder::Constant(SafeCast<UInt32>(value));
|
case ShaderAst::PrimitiveType::UInt32: return ShaderBuilder::Constant(SafeCast<UInt32>(value));
|
||||||
|
case ShaderAst::PrimitiveType::String: return ShaderBuilder::Constant(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::runtime_error("unexpected primitive type");
|
throw std::runtime_error("unexpected primitive type");
|
||||||
|
|
@ -269,10 +270,11 @@ namespace Nz::ShaderBuilder
|
||||||
return declareOptionNode;
|
return declareOptionNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::unique_ptr<ShaderAst::DeclareStructStatement> Impl::DeclareStruct::operator()(ShaderAst::StructDescription description) const
|
inline std::unique_ptr<ShaderAst::DeclareStructStatement> Impl::DeclareStruct::operator()(ShaderAst::StructDescription description, ShaderAst::ExpressionValue<bool> isExported) const
|
||||||
{
|
{
|
||||||
auto declareStructNode = std::make_unique<ShaderAst::DeclareStructStatement>();
|
auto declareStructNode = std::make_unique<ShaderAst::DeclareStructStatement>();
|
||||||
declareStructNode->description = std::move(description);
|
declareStructNode->description = std::move(description);
|
||||||
|
declareStructNode->isExported = std::move(isExported);
|
||||||
|
|
||||||
return declareStructNode;
|
return declareStructNode;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ namespace Nz::ShaderLang
|
||||||
const Token& Peek(std::size_t advance = 0);
|
const Token& Peek(std::size_t advance = 0);
|
||||||
|
|
||||||
std::vector<ShaderAst::ExprValue> ParseAttributes();
|
std::vector<ShaderAst::ExprValue> ParseAttributes();
|
||||||
|
void ParseModuleStatement(std::vector<ShaderAst::ExprValue> attributes);
|
||||||
void ParseVariableDeclaration(std::string& name, ShaderAst::ExpressionValue<ShaderAst::ExpressionType>& type, ShaderAst::ExpressionPtr& initialValue);
|
void ParseVariableDeclaration(std::string& name, ShaderAst::ExpressionValue<ShaderAst::ExpressionType>& type, ShaderAst::ExpressionPtr& initialValue);
|
||||||
|
|
||||||
// Statements
|
// Statements
|
||||||
|
|
@ -93,7 +94,6 @@ namespace Nz::ShaderLang
|
||||||
std::vector<ShaderAst::StatementPtr> ParseFunctionBody();
|
std::vector<ShaderAst::StatementPtr> ParseFunctionBody();
|
||||||
ShaderAst::StatementPtr ParseFunctionDeclaration(std::vector<ShaderAst::ExprValue> attributes = {});
|
ShaderAst::StatementPtr ParseFunctionDeclaration(std::vector<ShaderAst::ExprValue> attributes = {});
|
||||||
ShaderAst::DeclareFunctionStatement::Parameter ParseFunctionParameter();
|
ShaderAst::DeclareFunctionStatement::Parameter ParseFunctionParameter();
|
||||||
void ParseModuleStatement(std::vector<ShaderAst::ExprValue> attributes);
|
|
||||||
ShaderAst::StatementPtr ParseOptionDeclaration();
|
ShaderAst::StatementPtr ParseOptionDeclaration();
|
||||||
ShaderAst::StatementPtr ParseReturnStatement();
|
ShaderAst::StatementPtr ParseReturnStatement();
|
||||||
ShaderAst::StatementPtr ParseRootStatement(std::vector<ShaderAst::ExprValue> attributes = {});
|
ShaderAst::StatementPtr ParseRootStatement(std::vector<ShaderAst::ExprValue> attributes = {});
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include <Nazara/OpenGLRenderer/Utils.hpp>
|
#include <Nazara/OpenGLRenderer/Utils.hpp>
|
||||||
#include <Nazara/Shader/GlslWriter.hpp>
|
#include <Nazara/Shader/GlslWriter.hpp>
|
||||||
#include <Nazara/Shader/ShaderBuilder.hpp>
|
#include <Nazara/Shader/ShaderBuilder.hpp>
|
||||||
|
#include <Nazara/Shader/Ast/Module.hpp>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||||
|
|
@ -50,7 +51,11 @@ namespace Nz
|
||||||
ShaderAst::Module dummyModule;
|
ShaderAst::Module dummyModule;
|
||||||
dummyModule.rootNode = ShaderBuilder::MultiStatement();
|
dummyModule.rootNode = ShaderBuilder::MultiStatement();
|
||||||
dummyModule.rootNode->statements.push_back(ShaderBuilder::DeclareFunction(stage, "main", {}, {}));
|
dummyModule.rootNode->statements.push_back(ShaderBuilder::DeclareFunction(stage, "main", {}, {}));
|
||||||
dummyModule.shaderLangVersion = 100;
|
|
||||||
|
std::shared_ptr<ShaderAst::Module::Metadata> metadata = std::make_shared<ShaderAst::Module::Metadata>();
|
||||||
|
metadata->shaderLangVersion = 100;
|
||||||
|
|
||||||
|
dummyModule.metadata = std::move(metadata);
|
||||||
|
|
||||||
OpenGLShaderModule shaderModule(device, stage, dummyModule);
|
OpenGLShaderModule shaderModule(device, stage, dummyModule);
|
||||||
stageFlags |= shaderModule.Attach(m_program, pipelineLayout.GetBindingMapping());
|
stageFlags |= shaderModule.Attach(m_program, pipelineLayout.GetBindingMapping());
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@ namespace Nz::ShaderAst
|
||||||
{
|
{
|
||||||
m_stream << s_magicNumber << s_currentVersion;
|
m_stream << s_magicNumber << s_currentVersion;
|
||||||
|
|
||||||
m_stream << module.shaderLangVersion;
|
m_stream << module.metadata->shaderLangVersion;
|
||||||
Serialize(*module.rootNode);
|
Serialize(*module.rootNode);
|
||||||
|
|
||||||
m_stream.FlushBits();
|
m_stream.FlushBits();
|
||||||
|
|
@ -531,7 +531,10 @@ namespace Nz::ShaderAst
|
||||||
|
|
||||||
ModulePtr module = std::make_shared<Module>();
|
ModulePtr module = std::make_shared<Module>();
|
||||||
|
|
||||||
m_stream >> module->shaderLangVersion;
|
std::shared_ptr<Module::Metadata> metadata = std::make_shared<Module::Metadata>();
|
||||||
|
m_stream >> metadata->shaderLangVersion;
|
||||||
|
|
||||||
|
module->metadata = std::move(metadata);
|
||||||
|
|
||||||
module->rootNode = ShaderBuilder::MultiStatement();
|
module->rootNode = ShaderBuilder::MultiStatement();
|
||||||
ShaderSerializerVisitor visitor(*this);
|
ShaderSerializerVisitor visitor(*this);
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ namespace Nz::ShaderAst
|
||||||
ModulePtr SanitizeVisitor::Sanitize(const Module& module, const Options& options, std::string* error)
|
ModulePtr SanitizeVisitor::Sanitize(const Module& module, const Options& options, std::string* error)
|
||||||
{
|
{
|
||||||
ModulePtr clone = std::make_shared<Module>();
|
ModulePtr clone = std::make_shared<Module>();
|
||||||
clone->shaderLangVersion = module.shaderLangVersion;
|
clone->metadata = module.metadata;
|
||||||
|
|
||||||
Context currentContext;
|
Context currentContext;
|
||||||
currentContext.options = options;
|
currentContext.options = options;
|
||||||
|
|
|
||||||
|
|
@ -298,7 +298,7 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlslWriter::Append(const ShaderAst::MethodType& methodType)
|
void GlslWriter::Append(const ShaderAst::MethodType& /*methodType*/)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("unexpected method type");
|
throw std::runtime_error("unexpected method type");
|
||||||
}
|
}
|
||||||
|
|
@ -311,6 +311,7 @@ namespace Nz
|
||||||
case ShaderAst::PrimitiveType::Float32: return Append("float");
|
case ShaderAst::PrimitiveType::Float32: return Append("float");
|
||||||
case ShaderAst::PrimitiveType::Int32: return Append("int");
|
case ShaderAst::PrimitiveType::Int32: return Append("int");
|
||||||
case ShaderAst::PrimitiveType::UInt32: return Append("uint");
|
case ShaderAst::PrimitiveType::UInt32: return Append("uint");
|
||||||
|
case ShaderAst::PrimitiveType::String: throw std::runtime_error("unexpected string constant");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -324,6 +325,8 @@ namespace Nz
|
||||||
|
|
||||||
case ShaderAst::PrimitiveType::Int32: Append("i"); break;
|
case ShaderAst::PrimitiveType::Int32: Append("i"); break;
|
||||||
case ShaderAst::PrimitiveType::UInt32: Append("u"); break;
|
case ShaderAst::PrimitiveType::UInt32: Append("u"); break;
|
||||||
|
|
||||||
|
case ShaderAst::PrimitiveType::String: throw std::runtime_error("unexpected string type");
|
||||||
}
|
}
|
||||||
|
|
||||||
Append("sampler");
|
Append("sampler");
|
||||||
|
|
@ -363,6 +366,7 @@ namespace Nz
|
||||||
case ShaderAst::PrimitiveType::Float32: break;
|
case ShaderAst::PrimitiveType::Float32: break;
|
||||||
case ShaderAst::PrimitiveType::Int32: Append("i"); break;
|
case ShaderAst::PrimitiveType::Int32: Append("i"); break;
|
||||||
case ShaderAst::PrimitiveType::UInt32: Append("u"); break;
|
case ShaderAst::PrimitiveType::UInt32: Append("u"); break;
|
||||||
|
case ShaderAst::PrimitiveType::String: throw std::runtime_error("unexpected string type");
|
||||||
}
|
}
|
||||||
|
|
||||||
Append("vec");
|
Append("vec");
|
||||||
|
|
@ -1201,6 +1205,11 @@ namespace Nz
|
||||||
Append(";");
|
Append(";");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GlslWriter::Visit(ShaderAst::ImportStatement& /*node*/)
|
||||||
|
{
|
||||||
|
/* nothing to do */
|
||||||
|
}
|
||||||
|
|
||||||
void GlslWriter::Visit(ShaderAst::MultiStatement& node)
|
void GlslWriter::Visit(ShaderAst::MultiStatement& node)
|
||||||
{
|
{
|
||||||
AppendStatementList(node.statements);
|
AppendStatementList(node.statements);
|
||||||
|
|
|
||||||
|
|
@ -76,13 +76,6 @@ namespace Nz
|
||||||
inline bool HasValue() const { return locationIndex.HasValue(); }
|
inline bool HasValue() const { return locationIndex.HasValue(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LangWriter::NzslAttribute
|
|
||||||
{
|
|
||||||
const ShaderAst::ExpressionValue<UInt32>& version;
|
|
||||||
|
|
||||||
inline bool HasValue() const { return version.HasValue(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LangWriter::SetAttribute
|
struct LangWriter::SetAttribute
|
||||||
{
|
{
|
||||||
const ShaderAst::ExpressionValue<UInt32>& setIndex;
|
const ShaderAst::ExpressionValue<UInt32>& setIndex;
|
||||||
|
|
@ -100,6 +93,7 @@ namespace Nz
|
||||||
struct LangWriter::State
|
struct LangWriter::State
|
||||||
{
|
{
|
||||||
const States* states = nullptr;
|
const States* states = nullptr;
|
||||||
|
ShaderAst::Module* module;
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
std::unordered_map<std::size_t, std::string> constantNames;
|
std::unordered_map<std::size_t, std::string> constantNames;
|
||||||
std::unordered_map<std::size_t, ShaderAst::StructDescription*> structs;
|
std::unordered_map<std::size_t, ShaderAst::StructDescription*> structs;
|
||||||
|
|
@ -118,6 +112,7 @@ namespace Nz
|
||||||
});
|
});
|
||||||
|
|
||||||
ShaderAst::ModulePtr sanitizedModule = ShaderAst::Sanitize(module);
|
ShaderAst::ModulePtr sanitizedModule = ShaderAst::Sanitize(module);
|
||||||
|
state.module = sanitizedModule.get();
|
||||||
|
|
||||||
AppendHeader();
|
AppendHeader();
|
||||||
|
|
||||||
|
|
@ -195,6 +190,7 @@ namespace Nz
|
||||||
case ShaderAst::PrimitiveType::Float32: return Append("f32");
|
case ShaderAst::PrimitiveType::Float32: return Append("f32");
|
||||||
case ShaderAst::PrimitiveType::Int32: return Append("i32");
|
case ShaderAst::PrimitiveType::Int32: return Append("i32");
|
||||||
case ShaderAst::PrimitiveType::UInt32: return Append("u32");
|
case ShaderAst::PrimitiveType::UInt32: return Append("u32");
|
||||||
|
case ShaderAst::PrimitiveType::String: return Append("string");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -460,10 +456,6 @@ namespace Nz
|
||||||
Append(")");
|
Append(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
void LangWriter::AppendAttribute(NzslAttribute nzslVersion)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void LangWriter::AppendAttribute(SetAttribute set)
|
void LangWriter::AppendAttribute(SetAttribute set)
|
||||||
{
|
{
|
||||||
if (!set.HasValue())
|
if (!set.HasValue())
|
||||||
|
|
@ -1101,6 +1093,23 @@ namespace Nz
|
||||||
|
|
||||||
void LangWriter::AppendHeader()
|
void LangWriter::AppendHeader()
|
||||||
{
|
{
|
||||||
// Nothing yet
|
UInt32 shaderLangVersion = m_currentState->module->metadata->shaderLangVersion;
|
||||||
|
UInt32 majorVersion = shaderLangVersion / 100;
|
||||||
|
shaderLangVersion -= majorVersion * 100;
|
||||||
|
|
||||||
|
UInt32 minorVersion = shaderLangVersion / 10;
|
||||||
|
shaderLangVersion -= minorVersion * 100;
|
||||||
|
|
||||||
|
UInt32 patchVersion = shaderLangVersion;
|
||||||
|
|
||||||
|
// nzsl_version
|
||||||
|
Append("[nzsl_version(\"", majorVersion, ".", minorVersion);
|
||||||
|
if (patchVersion != 0)
|
||||||
|
Append(".", patchVersion);
|
||||||
|
|
||||||
|
AppendLine("\")]");
|
||||||
|
|
||||||
|
AppendLine("module;");
|
||||||
|
AppendLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,78 @@ namespace Nz::ShaderLang
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Parser::ParseModuleStatement(std::vector<ShaderAst::ExprValue> attributes)
|
||||||
|
{
|
||||||
|
Expect(Advance(), TokenType::Module);
|
||||||
|
|
||||||
|
if (m_context->module)
|
||||||
|
throw DuplicateModule{ "you must set one module statement per file" };
|
||||||
|
|
||||||
|
std::optional<UInt32> moduleVersion;
|
||||||
|
|
||||||
|
for (auto&& [attributeType, arg] : attributes)
|
||||||
|
{
|
||||||
|
switch (attributeType)
|
||||||
|
{
|
||||||
|
case ShaderAst::AttributeType::LangVersion:
|
||||||
|
{
|
||||||
|
// Version parsing
|
||||||
|
if (moduleVersion.has_value())
|
||||||
|
throw AttributeError{ "attribute " + std::string("nzsl_version") + " must be present once" };
|
||||||
|
|
||||||
|
if (!arg)
|
||||||
|
throw AttributeError{ "attribute " + std::string("nzsl_version") + " requires a parameter"};
|
||||||
|
|
||||||
|
const ShaderAst::ExpressionPtr& expr = *arg;
|
||||||
|
if (expr->GetType() != ShaderAst::NodeType::ConstantValueExpression)
|
||||||
|
throw AttributeError{ "attribute " + std::string("nzsl_version") + " expect a single string parameter" };
|
||||||
|
|
||||||
|
auto& constantValue = SafeCast<ShaderAst::ConstantValueExpression&>(*expr);
|
||||||
|
if (ShaderAst::GetExpressionType(constantValue.value) != ShaderAst::ExpressionType{ ShaderAst::PrimitiveType::String })
|
||||||
|
throw AttributeError{ "attribute " + std::string("nzsl_version") + " expect a single string parameter" };
|
||||||
|
|
||||||
|
const std::string& versionStr = std::get<std::string>(constantValue.value);
|
||||||
|
|
||||||
|
std::regex versionRegex(R"(^(\d+)(\.(\d+)(\.(\d+))?)?$)", std::regex::ECMAScript);
|
||||||
|
|
||||||
|
std::smatch versionMatch;
|
||||||
|
if (!std::regex_match(versionStr, versionMatch, versionRegex))
|
||||||
|
throw AttributeError("invalid version for attribute nzsl");
|
||||||
|
|
||||||
|
assert(versionMatch.size() == 6);
|
||||||
|
|
||||||
|
std::uint32_t version = 0;
|
||||||
|
version += std::stoi(versionMatch[1]) * 100;
|
||||||
|
|
||||||
|
if (versionMatch.length(3) > 0)
|
||||||
|
version += std::stoi(versionMatch[3]) * 10;
|
||||||
|
|
||||||
|
if (versionMatch.length(5) > 0)
|
||||||
|
version += std::stoi(versionMatch[5]) * 1;
|
||||||
|
|
||||||
|
moduleVersion = version;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw AttributeError{ "unhandled attribute for module" };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!moduleVersion.has_value())
|
||||||
|
throw AttributeError{ "missing module version" };
|
||||||
|
|
||||||
|
m_context->module = std::make_shared<ShaderAst::Module>();
|
||||||
|
m_context->module->rootNode = ShaderBuilder::MultiStatement();
|
||||||
|
|
||||||
|
std::shared_ptr<ShaderAst::Module::Metadata> moduleMetadata = std::make_shared<ShaderAst::Module::Metadata>();
|
||||||
|
moduleMetadata->shaderLangVersion = *moduleVersion;
|
||||||
|
|
||||||
|
m_context->module->metadata = std::move(moduleMetadata);
|
||||||
|
|
||||||
|
Expect(Advance(), TokenType::Semicolon);
|
||||||
|
}
|
||||||
|
|
||||||
void Parser::ParseVariableDeclaration(std::string& name, ShaderAst::ExpressionValue<ShaderAst::ExpressionType>& type, ShaderAst::ExpressionPtr& initialValue)
|
void Parser::ParseVariableDeclaration(std::string& name, ShaderAst::ExpressionValue<ShaderAst::ExpressionType>& type, ShaderAst::ExpressionPtr& initialValue)
|
||||||
{
|
{
|
||||||
name = ParseIdentifierAsName();
|
name = ParseIdentifierAsName();
|
||||||
|
|
@ -564,71 +636,13 @@ namespace Nz::ShaderLang
|
||||||
return { parameterName, std::move(parameterType) };
|
return { parameterName, std::move(parameterType) };
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::ParseModuleStatement(std::vector<ShaderAst::ExprValue> attributes)
|
|
||||||
{
|
{
|
||||||
Expect(Advance(), TokenType::Module);
|
|
||||||
|
|
||||||
if (m_context->module)
|
|
||||||
throw DuplicateModule{ "you must set one module statement per file" };
|
|
||||||
|
|
||||||
std::optional<UInt32> moduleVersion;
|
|
||||||
|
|
||||||
for (auto&& [attributeType, arg] : attributes)
|
|
||||||
{
|
{
|
||||||
switch (attributeType)
|
|
||||||
{
|
|
||||||
case ShaderAst::AttributeType::LangVersion:
|
|
||||||
{
|
|
||||||
// Version parsing
|
|
||||||
if (moduleVersion.has_value())
|
|
||||||
throw AttributeError{ "attribute " + std::string("nzsl_version") + " must be present once" };
|
|
||||||
|
|
||||||
if (!arg)
|
|
||||||
throw AttributeError{ "attribute " + std::string("nzsl_version") + " requires a parameter"};
|
|
||||||
|
|
||||||
const ShaderAst::ExpressionPtr& expr = *arg;
|
|
||||||
if (expr->GetType() != ShaderAst::NodeType::ConstantValueExpression)
|
|
||||||
throw AttributeError{ "attribute " + std::string("nzsl_version") + " expect a single string parameter" };
|
|
||||||
|
|
||||||
auto& constantValue = SafeCast<ShaderAst::ConstantValueExpression&>(*expr);
|
|
||||||
if (ShaderAst::GetExpressionType(constantValue.value) != ShaderAst::ExpressionType{ ShaderAst::PrimitiveType::String })
|
|
||||||
throw AttributeError{ "attribute " + std::string("nzsl_version") + " expect a single string parameter" };
|
|
||||||
|
|
||||||
const std::string& versionStr = std::get<std::string>(constantValue.value);
|
|
||||||
|
|
||||||
std::regex versionRegex(R"(^(\d+)(\.(\d+)(\.(\d+))?)?$)", std::regex::ECMAScript);
|
|
||||||
|
|
||||||
std::smatch versionMatch;
|
|
||||||
if (!std::regex_match(versionStr, versionMatch, versionRegex))
|
|
||||||
throw AttributeError("invalid version for attribute nzsl");
|
|
||||||
|
|
||||||
assert(versionMatch.size() == 6);
|
|
||||||
|
|
||||||
std::uint32_t version = 0;
|
|
||||||
version += std::stoi(versionMatch[1]) * 100;
|
|
||||||
|
|
||||||
if (versionMatch.length(3) > 0)
|
|
||||||
version += std::stoi(versionMatch[3]) * 10;
|
|
||||||
|
|
||||||
if (versionMatch.length(5) > 0)
|
|
||||||
version += std::stoi(versionMatch[5]) * 1;
|
|
||||||
|
|
||||||
moduleVersion = version;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
|
||||||
throw AttributeError{ "unhandled attribute for module" };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!moduleVersion.has_value())
|
|
||||||
throw AttributeError{ "missing module version" };
|
|
||||||
|
|
||||||
m_context->module = std::make_shared<ShaderAst::Module>();
|
|
||||||
m_context->module->rootNode = ShaderBuilder::MultiStatement();
|
|
||||||
m_context->module->shaderLangVersion = *moduleVersion;
|
|
||||||
|
|
||||||
Expect(Advance(), TokenType::Semicolon);
|
Expect(Advance(), TokenType::Semicolon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ namespace Nz
|
||||||
return SpirvOp::OpIAdd;
|
return SpirvOp::OpIAdd;
|
||||||
|
|
||||||
case ShaderAst::PrimitiveType::Boolean:
|
case ShaderAst::PrimitiveType::Boolean:
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,6 +125,7 @@ namespace Nz
|
||||||
return SpirvOp::OpISub;
|
return SpirvOp::OpISub;
|
||||||
|
|
||||||
case ShaderAst::PrimitiveType::Boolean:
|
case ShaderAst::PrimitiveType::Boolean:
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,6 +146,7 @@ namespace Nz
|
||||||
return SpirvOp::OpUDiv;
|
return SpirvOp::OpUDiv;
|
||||||
|
|
||||||
case ShaderAst::PrimitiveType::Boolean:
|
case ShaderAst::PrimitiveType::Boolean:
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -197,7 +200,8 @@ namespace Nz
|
||||||
case ShaderAst::PrimitiveType::UInt32:
|
case ShaderAst::PrimitiveType::UInt32:
|
||||||
return SpirvOp::OpIMul;
|
return SpirvOp::OpIMul;
|
||||||
|
|
||||||
default:
|
case ShaderAst::PrimitiveType::Boolean:
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -217,6 +221,9 @@ namespace Nz
|
||||||
case ShaderAst::PrimitiveType::Int32:
|
case ShaderAst::PrimitiveType::Int32:
|
||||||
case ShaderAst::PrimitiveType::UInt32:
|
case ShaderAst::PrimitiveType::UInt32:
|
||||||
return SpirvOp::OpIEqual;
|
return SpirvOp::OpIEqual;
|
||||||
|
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -236,6 +243,7 @@ namespace Nz
|
||||||
return SpirvOp::OpUGreaterThan;
|
return SpirvOp::OpUGreaterThan;
|
||||||
|
|
||||||
case ShaderAst::PrimitiveType::Boolean:
|
case ShaderAst::PrimitiveType::Boolean:
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -256,6 +264,7 @@ namespace Nz
|
||||||
return SpirvOp::OpUGreaterThanEqual;
|
return SpirvOp::OpUGreaterThanEqual;
|
||||||
|
|
||||||
case ShaderAst::PrimitiveType::Boolean:
|
case ShaderAst::PrimitiveType::Boolean:
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -276,6 +285,7 @@ namespace Nz
|
||||||
return SpirvOp::OpULessThanEqual;
|
return SpirvOp::OpULessThanEqual;
|
||||||
|
|
||||||
case ShaderAst::PrimitiveType::Boolean:
|
case ShaderAst::PrimitiveType::Boolean:
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -296,6 +306,7 @@ namespace Nz
|
||||||
return SpirvOp::OpULessThan;
|
return SpirvOp::OpULessThan;
|
||||||
|
|
||||||
case ShaderAst::PrimitiveType::Boolean:
|
case ShaderAst::PrimitiveType::Boolean:
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -315,6 +326,9 @@ namespace Nz
|
||||||
case ShaderAst::PrimitiveType::Int32:
|
case ShaderAst::PrimitiveType::Int32:
|
||||||
case ShaderAst::PrimitiveType::UInt32:
|
case ShaderAst::PrimitiveType::UInt32:
|
||||||
return SpirvOp::OpINotEqual;
|
return SpirvOp::OpINotEqual;
|
||||||
|
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -482,6 +496,9 @@ namespace Nz
|
||||||
case ShaderAst::PrimitiveType::UInt32:
|
case ShaderAst::PrimitiveType::UInt32:
|
||||||
castOp = SpirvOp::OpConvertUToF;
|
castOp = SpirvOp::OpConvertUToF;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
|
throw std::runtime_error("unexpected string type");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -503,6 +520,9 @@ namespace Nz
|
||||||
case ShaderAst::PrimitiveType::UInt32:
|
case ShaderAst::PrimitiveType::UInt32:
|
||||||
castOp = SpirvOp::OpSConvert;
|
castOp = SpirvOp::OpSConvert;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
|
throw std::runtime_error("unexpected string type");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -524,9 +544,15 @@ namespace Nz
|
||||||
|
|
||||||
case ShaderAst::PrimitiveType::UInt32:
|
case ShaderAst::PrimitiveType::UInt32:
|
||||||
break; //< Already handled
|
break; //< Already handled
|
||||||
|
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
|
throw std::runtime_error("unexpected string type");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
|
throw std::runtime_error("unexpected string type");
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(castOp);
|
assert(castOp);
|
||||||
|
|
@ -809,6 +835,9 @@ namespace Nz
|
||||||
case ShaderAst::PrimitiveType::UInt32:
|
case ShaderAst::PrimitiveType::UInt32:
|
||||||
op = (node.intrinsic == ShaderAst::IntrinsicType::Max) ? GLSLstd450UMax : GLSLstd450UMin;
|
op = (node.intrinsic == ShaderAst::IntrinsicType::Max) ? GLSLstd450UMax : GLSLstd450UMin;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
|
throw std::runtime_error("unexpected string type");
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 firstParam = EvaluateExpression(node.parameters[0]);
|
UInt32 firstParam = EvaluateExpression(node.parameters[0]);
|
||||||
|
|
|
||||||
|
|
@ -725,6 +725,9 @@ namespace Nz
|
||||||
|
|
||||||
case ShaderAst::PrimitiveType::UInt32:
|
case ShaderAst::PrimitiveType::UInt32:
|
||||||
return Integer{ 32, false };
|
return Integer{ 32, false };
|
||||||
|
|
||||||
|
case ShaderAst::PrimitiveType::String:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::runtime_error("unexpected type");
|
throw std::runtime_error("unexpected type");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue