Shader: Use constexpr maps for static data
This commit is contained in:
parent
18edd41048
commit
262c82b9e1
|
|
@ -87,7 +87,7 @@ namespace Nz::ShaderLang
|
||||||
|
|
||||||
template<typename T> void HandleUniqueAttribute(ShaderAst::ExpressionValue<T>& targetAttribute, Attribute&& attribute);
|
template<typename T> void HandleUniqueAttribute(ShaderAst::ExpressionValue<T>& targetAttribute, Attribute&& attribute);
|
||||||
template<typename T> void HandleUniqueAttribute(ShaderAst::ExpressionValue<T>& targetAttribute, Attribute&& attribute, T defaultValue);
|
template<typename T> void HandleUniqueAttribute(ShaderAst::ExpressionValue<T>& targetAttribute, Attribute&& attribute, T defaultValue);
|
||||||
template<typename T> void HandleUniqueStringAttribute(ShaderAst::ExpressionValue<T>& targetAttribute, Attribute&& attribute, const std::unordered_map<std::string, T>& map, std::optional<T> defaultValue = {});
|
template<typename T, typename M> void HandleUniqueStringAttribute(ShaderAst::ExpressionValue<T>& targetAttribute, Attribute&& attribute, const M& map, std::optional<T> defaultValue = {});
|
||||||
|
|
||||||
static int GetTokenPrecedence(TokenType token);
|
static int GetTokenPrecedence(TokenType token);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include <Nazara/Shader/Ast/AstRecursiveVisitor.hpp>
|
#include <Nazara/Shader/Ast/AstRecursiveVisitor.hpp>
|
||||||
#include <Nazara/Shader/Ast/AstUtils.hpp>
|
#include <Nazara/Shader/Ast/AstUtils.hpp>
|
||||||
#include <Nazara/Shader/Ast/EliminateUnusedPassVisitor.hpp>
|
#include <Nazara/Shader/Ast/EliminateUnusedPassVisitor.hpp>
|
||||||
|
#include <frozen/unordered_map.h>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
@ -106,15 +107,15 @@ namespace Nz
|
||||||
|
|
||||||
struct GlslBuiltin
|
struct GlslBuiltin
|
||||||
{
|
{
|
||||||
std::string identifier;
|
std::string_view identifier;
|
||||||
ShaderStageTypeFlags stageFlags;
|
ShaderStageTypeFlags stageFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_map<ShaderAst::BuiltinEntry, GlslBuiltin> s_glslBuiltinMapping = {
|
constexpr auto s_glslBuiltinMapping = frozen::make_unordered_map<ShaderAst::BuiltinEntry, GlslBuiltin>({
|
||||||
{ ShaderAst::BuiltinEntry::FragCoord, { "gl_FragCoord", ShaderStageType::Fragment } },
|
{ ShaderAst::BuiltinEntry::FragCoord, { "gl_FragCoord", ShaderStageType::Fragment } },
|
||||||
{ ShaderAst::BuiltinEntry::FragDepth, { "gl_FragDepth", ShaderStageType::Fragment } },
|
{ ShaderAst::BuiltinEntry::FragDepth, { "gl_FragDepth", ShaderStageType::Fragment } },
|
||||||
{ ShaderAst::BuiltinEntry::VertexPosition, { "gl_Position", ShaderStageType::Vertex } }
|
{ ShaderAst::BuiltinEntry::VertexPosition, { "gl_Position", ShaderStageType::Vertex } }
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -722,7 +723,7 @@ namespace Nz
|
||||||
|
|
||||||
fields.push_back({
|
fields.push_back({
|
||||||
member.name,
|
member.name,
|
||||||
builtin.identifier
|
std::string(builtin.identifier)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
#include <Nazara/Shader/ShaderLangLexer.hpp>
|
#include <Nazara/Shader/ShaderLangLexer.hpp>
|
||||||
#include <Nazara/Core/Algorithm.hpp>
|
#include <Nazara/Core/Algorithm.hpp>
|
||||||
#include <Nazara/Shader/ShaderLangErrors.hpp>
|
#include <Nazara/Shader/ShaderLangErrors.hpp>
|
||||||
|
#include <frozen/string.h>
|
||||||
|
#include <frozen/unordered_map.h>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
|
@ -34,14 +36,8 @@ namespace Nz::ShaderLang
|
||||||
private:
|
private:
|
||||||
std::locale m_previousLocale;
|
std::locale m_previousLocale;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Token> Tokenize(const std::string_view& str, const std::string& filePath)
|
constexpr auto s_reservedKeywords = frozen::make_unordered_map<frozen::string, TokenType>({
|
||||||
{
|
|
||||||
// Can't use std::from_chars for double, thanks to libc++ and libstdc++ developers for being lazy, so we have to force C locale
|
|
||||||
ForceCLocale forceCLocale;
|
|
||||||
|
|
||||||
std::unordered_map<std::string, TokenType> reservedKeywords = {
|
|
||||||
{ "alias", TokenType::Alias },
|
{ "alias", TokenType::Alias },
|
||||||
{ "const", TokenType::Const },
|
{ "const", TokenType::Const },
|
||||||
{ "const_select", TokenType::ConstSelect },
|
{ "const_select", TokenType::ConstSelect },
|
||||||
|
|
@ -61,7 +57,13 @@ namespace Nz::ShaderLang
|
||||||
{ "struct", TokenType::Struct },
|
{ "struct", TokenType::Struct },
|
||||||
{ "true", TokenType::BoolTrue },
|
{ "true", TokenType::BoolTrue },
|
||||||
{ "while", TokenType::While }
|
{ "while", TokenType::While }
|
||||||
};
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Token> Tokenize(const std::string_view& str, const std::string& filePath)
|
||||||
|
{
|
||||||
|
// Can't use std::from_chars for double, thanks to libc++ and libstdc++ developers for being lazy, so we have to force C locale
|
||||||
|
ForceCLocale forceCLocale;
|
||||||
|
|
||||||
std::size_t currentPos = 0;
|
std::size_t currentPos = 0;
|
||||||
|
|
||||||
|
|
@ -461,11 +463,11 @@ namespace Nz::ShaderLang
|
||||||
while (IsAlphaNum(Peek()))
|
while (IsAlphaNum(Peek()))
|
||||||
currentPos++;
|
currentPos++;
|
||||||
|
|
||||||
std::string identifier(str.substr(start, currentPos - start + 1));
|
std::string_view identifier = str.substr(start, currentPos - start + 1);
|
||||||
if (auto it = reservedKeywords.find(identifier); it == reservedKeywords.end())
|
if (auto it = s_reservedKeywords.find(identifier); it == s_reservedKeywords.end())
|
||||||
{
|
{
|
||||||
tokenType = TokenType::Identifier;
|
tokenType = TokenType::Identifier;
|
||||||
token.data = std::move(identifier);
|
token.data = std::string(identifier);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tokenType = it->second;
|
tokenType = it->second;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
#include <Nazara/Core/File.hpp>
|
#include <Nazara/Core/File.hpp>
|
||||||
#include <Nazara/Shader/ShaderBuilder.hpp>
|
#include <Nazara/Shader/ShaderBuilder.hpp>
|
||||||
#include <Nazara/Shader/ShaderLangErrors.hpp>
|
#include <Nazara/Shader/ShaderLangErrors.hpp>
|
||||||
|
#include <frozen/string.h>
|
||||||
|
#include <frozen/unordered_map.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <Nazara/Shader/Debug.hpp>
|
#include <Nazara/Shader/Debug.hpp>
|
||||||
|
|
@ -15,14 +17,14 @@ namespace Nz::ShaderLang
|
||||||
{
|
{
|
||||||
namespace NAZARA_ANONYMOUS_NAMESPACE
|
namespace NAZARA_ANONYMOUS_NAMESPACE
|
||||||
{
|
{
|
||||||
std::unordered_map<std::string, ShaderAst::DepthWriteMode> s_depthWriteModes = {
|
constexpr auto s_depthWriteModes = frozen::make_unordered_map<frozen::string, ShaderAst::DepthWriteMode>({
|
||||||
{ "greater", ShaderAst::DepthWriteMode::Greater },
|
{ "greater", ShaderAst::DepthWriteMode::Greater },
|
||||||
{ "less", ShaderAst::DepthWriteMode::Less },
|
{ "less", ShaderAst::DepthWriteMode::Less },
|
||||||
{ "replace", ShaderAst::DepthWriteMode::Replace },
|
{ "replace", ShaderAst::DepthWriteMode::Replace },
|
||||||
{ "unchanged", ShaderAst::DepthWriteMode::Unchanged },
|
{ "unchanged", ShaderAst::DepthWriteMode::Unchanged },
|
||||||
};
|
});
|
||||||
|
|
||||||
std::unordered_map<std::string, ShaderAst::AttributeType> s_identifierToAttributeType = {
|
constexpr auto s_identifierToAttributeType = frozen::make_unordered_map<frozen::string, ShaderAst::AttributeType>({
|
||||||
{ "binding", ShaderAst::AttributeType::Binding },
|
{ "binding", ShaderAst::AttributeType::Binding },
|
||||||
{ "builtin", ShaderAst::AttributeType::Builtin },
|
{ "builtin", ShaderAst::AttributeType::Builtin },
|
||||||
{ "cond", ShaderAst::AttributeType::Cond },
|
{ "cond", ShaderAst::AttributeType::Cond },
|
||||||
|
|
@ -36,28 +38,28 @@ namespace Nz::ShaderLang
|
||||||
{ "set", ShaderAst::AttributeType::Set },
|
{ "set", ShaderAst::AttributeType::Set },
|
||||||
{ "unroll", ShaderAst::AttributeType::Unroll },
|
{ "unroll", ShaderAst::AttributeType::Unroll },
|
||||||
{ "uuid", ShaderAst::AttributeType::Uuid },
|
{ "uuid", ShaderAst::AttributeType::Uuid },
|
||||||
};
|
});
|
||||||
|
|
||||||
std::unordered_map<std::string, ShaderStageType> s_entryPoints = {
|
constexpr auto s_entryPoints = frozen::make_unordered_map<frozen::string, ShaderStageType>({
|
||||||
{ "frag", ShaderStageType::Fragment },
|
{ "frag", ShaderStageType::Fragment },
|
||||||
{ "vert", ShaderStageType::Vertex },
|
{ "vert", ShaderStageType::Vertex },
|
||||||
};
|
});
|
||||||
|
|
||||||
std::unordered_map<std::string, ShaderAst::BuiltinEntry> s_builtinMapping = {
|
constexpr auto s_builtinMapping = frozen::make_unordered_map<frozen::string, ShaderAst::BuiltinEntry>({
|
||||||
{ "fragcoord", ShaderAst::BuiltinEntry::FragCoord },
|
{ "fragcoord", ShaderAst::BuiltinEntry::FragCoord },
|
||||||
{ "fragdepth", ShaderAst::BuiltinEntry::FragDepth },
|
{ "fragdepth", ShaderAst::BuiltinEntry::FragDepth },
|
||||||
{ "position", ShaderAst::BuiltinEntry::VertexPosition }
|
{ "position", ShaderAst::BuiltinEntry::VertexPosition }
|
||||||
};
|
});
|
||||||
|
|
||||||
std::unordered_map<std::string, StructLayout> s_layoutMapping = {
|
constexpr auto s_layoutMapping = frozen::make_unordered_map<frozen::string, StructLayout>({
|
||||||
{ "std140", StructLayout::Std140 }
|
{ "std140", StructLayout::Std140 }
|
||||||
};
|
});
|
||||||
|
|
||||||
std::unordered_map<std::string, ShaderAst::LoopUnroll> s_unrollModes = {
|
constexpr auto s_unrollModes = frozen::make_unordered_map<frozen::string, ShaderAst::LoopUnroll>({
|
||||||
{ "always", ShaderAst::LoopUnroll::Always },
|
{ "always", ShaderAst::LoopUnroll::Always },
|
||||||
{ "hint", ShaderAst::LoopUnroll::Hint },
|
{ "hint", ShaderAst::LoopUnroll::Hint },
|
||||||
{ "never", ShaderAst::LoopUnroll::Never }
|
{ "never", ShaderAst::LoopUnroll::Never }
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderAst::ModulePtr Parser::Parse(const std::vector<Token>& tokens)
|
ShaderAst::ModulePtr Parser::Parse(const std::vector<Token>& tokens)
|
||||||
|
|
@ -163,7 +165,7 @@ namespace Nz::ShaderLang
|
||||||
Expect(Advance(), TokenType::Comma);
|
Expect(Advance(), TokenType::Comma);
|
||||||
|
|
||||||
const Token& identifierToken = Expect(Advance(), TokenType::Identifier);
|
const Token& identifierToken = Expect(Advance(), TokenType::Identifier);
|
||||||
const std::string& identifier = std::get<std::string>(identifierToken.data);
|
std::string_view identifier = std::get<std::string>(identifierToken.data);
|
||||||
|
|
||||||
SourceLocation attributeLocation = identifierToken.location;
|
SourceLocation attributeLocation = identifierToken.location;
|
||||||
|
|
||||||
|
|
@ -1495,8 +1497,8 @@ namespace Nz::ShaderLang
|
||||||
targetAttribute = std::move(defaultValue);
|
targetAttribute = std::move(defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename M>
|
||||||
void Parser::HandleUniqueStringAttribute(ShaderAst::ExpressionValue<T>& targetAttribute, Parser::Attribute&& attribute, const std::unordered_map<std::string, T>& map, std::optional<T> defaultValue)
|
void Parser::HandleUniqueStringAttribute(ShaderAst::ExpressionValue<T>& targetAttribute, Parser::Attribute&& attribute, const M& map, std::optional<T> defaultValue)
|
||||||
{
|
{
|
||||||
if (targetAttribute.HasValue())
|
if (targetAttribute.HasValue())
|
||||||
throw ParserAttributeMultipleUniqueError{ attribute.sourceLocation, attribute.type };
|
throw ParserAttributeMultipleUniqueError{ attribute.sourceLocation, attribute.type };
|
||||||
|
|
@ -1507,7 +1509,7 @@ namespace Nz::ShaderLang
|
||||||
if (attribute.args->GetType() != ShaderAst::NodeType::IdentifierExpression)
|
if (attribute.args->GetType() != ShaderAst::NodeType::IdentifierExpression)
|
||||||
throw ParserAttributeParameterIdentifierError{ attribute.args->sourceLocation, attribute.type };
|
throw ParserAttributeParameterIdentifierError{ attribute.args->sourceLocation, attribute.type };
|
||||||
|
|
||||||
const std::string& exprStr = static_cast<ShaderAst::IdentifierExpression&>(*attribute.args).identifier;
|
std::string_view exprStr = static_cast<ShaderAst::IdentifierExpression&>(*attribute.args).identifier;
|
||||||
|
|
||||||
auto it = map.find(exprStr);
|
auto it = map.find(exprStr);
|
||||||
if (it == map.end())
|
if (it == map.end())
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
#include <Nazara/Shader/Ast/EliminateUnusedPassVisitor.hpp>
|
#include <Nazara/Shader/Ast/EliminateUnusedPassVisitor.hpp>
|
||||||
#include <Nazara/Shader/Ast/SanitizeVisitor.hpp>
|
#include <Nazara/Shader/Ast/SanitizeVisitor.hpp>
|
||||||
#include <SpirV/GLSL.std.450.h>
|
#include <SpirV/GLSL.std.450.h>
|
||||||
|
#include <frozen/unordered_map.h>
|
||||||
#include <tsl/ordered_map.h>
|
#include <tsl/ordered_map.h>
|
||||||
#include <tsl/ordered_set.h>
|
#include <tsl/ordered_set.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
@ -36,11 +37,11 @@ namespace Nz
|
||||||
SpirvBuiltIn decoration;
|
SpirvBuiltIn decoration;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_map<ShaderAst::BuiltinEntry, SpirvBuiltin> s_spirvBuiltinMapping = {
|
constexpr auto s_spirvBuiltinMapping = frozen::make_unordered_map<ShaderAst::BuiltinEntry, SpirvBuiltin>({
|
||||||
{ ShaderAst::BuiltinEntry::FragCoord, { "FragmentCoordinates", ShaderStageType::Fragment, SpirvBuiltIn::FragCoord } },
|
{ ShaderAst::BuiltinEntry::FragCoord, { "FragmentCoordinates", ShaderStageType::Fragment, SpirvBuiltIn::FragCoord } },
|
||||||
{ ShaderAst::BuiltinEntry::FragDepth, { "FragmentDepth", ShaderStageType::Fragment, SpirvBuiltIn::FragDepth } },
|
{ ShaderAst::BuiltinEntry::FragDepth, { "FragmentDepth", ShaderStageType::Fragment, SpirvBuiltIn::FragDepth } },
|
||||||
{ ShaderAst::BuiltinEntry::VertexPosition, { "VertexPosition", ShaderStageType::Vertex, SpirvBuiltIn::Position } }
|
{ ShaderAst::BuiltinEntry::VertexPosition, { "VertexPosition", ShaderStageType::Vertex, SpirvBuiltIn::Position } }
|
||||||
};
|
});
|
||||||
|
|
||||||
class SpirvPreVisitor : public ShaderAst::AstRecursiveVisitor
|
class SpirvPreVisitor : public ShaderAst::AstRecursiveVisitor
|
||||||
{
|
{
|
||||||
|
|
@ -400,7 +401,7 @@ namespace Nz
|
||||||
auto it = s_spirvBuiltinMapping.find(member.builtin.GetResultingValue());
|
auto it = s_spirvBuiltinMapping.find(member.builtin.GetResultingValue());
|
||||||
assert(it != s_spirvBuiltinMapping.end());
|
assert(it != s_spirvBuiltinMapping.end());
|
||||||
|
|
||||||
SpirvBuiltin& builtin = it->second;
|
const SpirvBuiltin& builtin = it->second;
|
||||||
if ((builtin.compatibleStages & entryPointType) == 0)
|
if ((builtin.compatibleStages & entryPointType) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,8 +80,8 @@ local modules = {
|
||||||
Deps = {"NazaraPlatform", "NazaraShader"}
|
Deps = {"NazaraPlatform", "NazaraShader"}
|
||||||
},
|
},
|
||||||
Shader = {
|
Shader = {
|
||||||
Packages = {"efsw", "fmt"},
|
|
||||||
Deps = {"NazaraCore"},
|
Deps = {"NazaraCore"},
|
||||||
|
Packages = {"efsw", "fmt", "frozen"},
|
||||||
Custom = function()
|
Custom = function()
|
||||||
-- Set precise floating-points models to ensure shader optimization leads to correct results
|
-- Set precise floating-points models to ensure shader optimization leads to correct results
|
||||||
set_fpmodels("precise")
|
set_fpmodels("precise")
|
||||||
|
|
@ -131,7 +131,7 @@ option_end()
|
||||||
set_project("NazaraEngine")
|
set_project("NazaraEngine")
|
||||||
set_xmakever("2.6.3")
|
set_xmakever("2.6.3")
|
||||||
|
|
||||||
add_requires("chipmunk2d", "dr_wav", "efsw", "entt >=3.9", "fmt", "kiwisolver", "libflac", "libsdl", "minimp3", "stb")
|
add_requires("chipmunk2d", "dr_wav", "efsw", "entt >=3.9", "fmt", "frozen", "kiwisolver", "libflac", "libsdl", "minimp3", "stb")
|
||||||
add_requires("freetype", { configs = { bzip2 = true, png = true, woff2 = true, zlib = true, debug = is_mode("debug") } })
|
add_requires("freetype", { configs = { bzip2 = true, png = true, woff2 = true, zlib = true, debug = is_mode("debug") } })
|
||||||
add_requires("libvorbis", { configs = { with_vorbisenc = false } })
|
add_requires("libvorbis", { configs = { with_vorbisenc = false } })
|
||||||
add_requires("openal-soft", { configs = { shared = true }})
|
add_requires("openal-soft", { configs = { shared = true }})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue