From 262c82b9e13a93c9852aa6c0544b3aa566e3913a Mon Sep 17 00:00:00 2001 From: SirLynix Date: Tue, 5 Apr 2022 08:41:47 +0200 Subject: [PATCH] Shader: Use constexpr maps for static data --- include/Nazara/Shader/ShaderLangParser.hpp | 2 +- src/Nazara/Shader/GlslWriter.cpp | 9 +++--- src/Nazara/Shader/ShaderLangLexer.cpp | 24 ++++++++------- src/Nazara/Shader/ShaderLangParser.cpp | 34 ++++++++++++---------- src/Nazara/Shader/SpirvWriter.cpp | 7 +++-- xmake.lua | 4 +-- 6 files changed, 43 insertions(+), 37 deletions(-) diff --git a/include/Nazara/Shader/ShaderLangParser.hpp b/include/Nazara/Shader/ShaderLangParser.hpp index 6bafa69fd..494ffc3e8 100644 --- a/include/Nazara/Shader/ShaderLangParser.hpp +++ b/include/Nazara/Shader/ShaderLangParser.hpp @@ -87,7 +87,7 @@ namespace Nz::ShaderLang template void HandleUniqueAttribute(ShaderAst::ExpressionValue& targetAttribute, Attribute&& attribute); template void HandleUniqueAttribute(ShaderAst::ExpressionValue& targetAttribute, Attribute&& attribute, T defaultValue); - template void HandleUniqueStringAttribute(ShaderAst::ExpressionValue& targetAttribute, Attribute&& attribute, const std::unordered_map& map, std::optional defaultValue = {}); + template void HandleUniqueStringAttribute(ShaderAst::ExpressionValue& targetAttribute, Attribute&& attribute, const M& map, std::optional defaultValue = {}); static int GetTokenPrecedence(TokenType token); diff --git a/src/Nazara/Shader/GlslWriter.cpp b/src/Nazara/Shader/GlslWriter.cpp index 41687b718..67ad1c02f 100644 --- a/src/Nazara/Shader/GlslWriter.cpp +++ b/src/Nazara/Shader/GlslWriter.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -106,15 +107,15 @@ namespace Nz struct GlslBuiltin { - std::string identifier; + std::string_view identifier; ShaderStageTypeFlags stageFlags; }; - std::unordered_map s_glslBuiltinMapping = { + constexpr auto s_glslBuiltinMapping = frozen::make_unordered_map({ { ShaderAst::BuiltinEntry::FragCoord, { "gl_FragCoord", ShaderStageType::Fragment } }, { ShaderAst::BuiltinEntry::FragDepth, { "gl_FragDepth", ShaderStageType::Fragment } }, { ShaderAst::BuiltinEntry::VertexPosition, { "gl_Position", ShaderStageType::Vertex } } - }; + }); } @@ -722,7 +723,7 @@ namespace Nz fields.push_back({ member.name, - builtin.identifier + std::string(builtin.identifier) }); } else diff --git a/src/Nazara/Shader/ShaderLangLexer.cpp b/src/Nazara/Shader/ShaderLangLexer.cpp index df762ef97..03f077dc1 100644 --- a/src/Nazara/Shader/ShaderLangLexer.cpp +++ b/src/Nazara/Shader/ShaderLangLexer.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include #include @@ -34,14 +36,8 @@ namespace Nz::ShaderLang private: std::locale m_previousLocale; }; - } - std::vector 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::unordered_map reservedKeywords = { + constexpr auto s_reservedKeywords = frozen::make_unordered_map({ { "alias", TokenType::Alias }, { "const", TokenType::Const }, { "const_select", TokenType::ConstSelect }, @@ -61,7 +57,13 @@ namespace Nz::ShaderLang { "struct", TokenType::Struct }, { "true", TokenType::BoolTrue }, { "while", TokenType::While } - }; + }); + } + + std::vector 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; @@ -461,11 +463,11 @@ namespace Nz::ShaderLang while (IsAlphaNum(Peek())) currentPos++; - std::string identifier(str.substr(start, currentPos - start + 1)); - if (auto it = reservedKeywords.find(identifier); it == reservedKeywords.end()) + std::string_view identifier = str.substr(start, currentPos - start + 1); + if (auto it = s_reservedKeywords.find(identifier); it == s_reservedKeywords.end()) { tokenType = TokenType::Identifier; - token.data = std::move(identifier); + token.data = std::string(identifier); } else tokenType = it->second; diff --git a/src/Nazara/Shader/ShaderLangParser.cpp b/src/Nazara/Shader/ShaderLangParser.cpp index d1f1a3496..617961cf3 100644 --- a/src/Nazara/Shader/ShaderLangParser.cpp +++ b/src/Nazara/Shader/ShaderLangParser.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include #include @@ -15,14 +17,14 @@ namespace Nz::ShaderLang { namespace NAZARA_ANONYMOUS_NAMESPACE { - std::unordered_map s_depthWriteModes = { + constexpr auto s_depthWriteModes = frozen::make_unordered_map({ { "greater", ShaderAst::DepthWriteMode::Greater }, { "less", ShaderAst::DepthWriteMode::Less }, { "replace", ShaderAst::DepthWriteMode::Replace }, { "unchanged", ShaderAst::DepthWriteMode::Unchanged }, - }; + }); - std::unordered_map s_identifierToAttributeType = { + constexpr auto s_identifierToAttributeType = frozen::make_unordered_map({ { "binding", ShaderAst::AttributeType::Binding }, { "builtin", ShaderAst::AttributeType::Builtin }, { "cond", ShaderAst::AttributeType::Cond }, @@ -36,28 +38,28 @@ namespace Nz::ShaderLang { "set", ShaderAst::AttributeType::Set }, { "unroll", ShaderAst::AttributeType::Unroll }, { "uuid", ShaderAst::AttributeType::Uuid }, - }; + }); - std::unordered_map s_entryPoints = { + constexpr auto s_entryPoints = frozen::make_unordered_map({ { "frag", ShaderStageType::Fragment }, { "vert", ShaderStageType::Vertex }, - }; + }); - std::unordered_map s_builtinMapping = { + constexpr auto s_builtinMapping = frozen::make_unordered_map({ { "fragcoord", ShaderAst::BuiltinEntry::FragCoord }, { "fragdepth", ShaderAst::BuiltinEntry::FragDepth }, { "position", ShaderAst::BuiltinEntry::VertexPosition } - }; + }); - std::unordered_map s_layoutMapping = { + constexpr auto s_layoutMapping = frozen::make_unordered_map({ { "std140", StructLayout::Std140 } - }; + }); - std::unordered_map s_unrollModes = { + constexpr auto s_unrollModes = frozen::make_unordered_map({ { "always", ShaderAst::LoopUnroll::Always }, { "hint", ShaderAst::LoopUnroll::Hint }, { "never", ShaderAst::LoopUnroll::Never } - }; + }); } ShaderAst::ModulePtr Parser::Parse(const std::vector& tokens) @@ -163,7 +165,7 @@ namespace Nz::ShaderLang Expect(Advance(), TokenType::Comma); const Token& identifierToken = Expect(Advance(), TokenType::Identifier); - const std::string& identifier = std::get(identifierToken.data); + std::string_view identifier = std::get(identifierToken.data); SourceLocation attributeLocation = identifierToken.location; @@ -1495,8 +1497,8 @@ namespace Nz::ShaderLang targetAttribute = std::move(defaultValue); } - template - void Parser::HandleUniqueStringAttribute(ShaderAst::ExpressionValue& targetAttribute, Parser::Attribute&& attribute, const std::unordered_map& map, std::optional defaultValue) + template + void Parser::HandleUniqueStringAttribute(ShaderAst::ExpressionValue& targetAttribute, Parser::Attribute&& attribute, const M& map, std::optional defaultValue) { if (targetAttribute.HasValue()) throw ParserAttributeMultipleUniqueError{ attribute.sourceLocation, attribute.type }; @@ -1507,7 +1509,7 @@ namespace Nz::ShaderLang if (attribute.args->GetType() != ShaderAst::NodeType::IdentifierExpression) throw ParserAttributeParameterIdentifierError{ attribute.args->sourceLocation, attribute.type }; - const std::string& exprStr = static_cast(*attribute.args).identifier; + std::string_view exprStr = static_cast(*attribute.args).identifier; auto it = map.find(exprStr); if (it == map.end()) diff --git a/src/Nazara/Shader/SpirvWriter.cpp b/src/Nazara/Shader/SpirvWriter.cpp index d6f555e02..830ba5be0 100644 --- a/src/Nazara/Shader/SpirvWriter.cpp +++ b/src/Nazara/Shader/SpirvWriter.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -36,11 +37,11 @@ namespace Nz SpirvBuiltIn decoration; }; - std::unordered_map s_spirvBuiltinMapping = { + constexpr auto s_spirvBuiltinMapping = frozen::make_unordered_map({ { ShaderAst::BuiltinEntry::FragCoord, { "FragmentCoordinates", ShaderStageType::Fragment, SpirvBuiltIn::FragCoord } }, { ShaderAst::BuiltinEntry::FragDepth, { "FragmentDepth", ShaderStageType::Fragment, SpirvBuiltIn::FragDepth } }, { ShaderAst::BuiltinEntry::VertexPosition, { "VertexPosition", ShaderStageType::Vertex, SpirvBuiltIn::Position } } - }; + }); class SpirvPreVisitor : public ShaderAst::AstRecursiveVisitor { @@ -400,7 +401,7 @@ namespace Nz auto it = s_spirvBuiltinMapping.find(member.builtin.GetResultingValue()); assert(it != s_spirvBuiltinMapping.end()); - SpirvBuiltin& builtin = it->second; + const SpirvBuiltin& builtin = it->second; if ((builtin.compatibleStages & entryPointType) == 0) return 0; diff --git a/xmake.lua b/xmake.lua index eee3fc7eb..2999bb827 100644 --- a/xmake.lua +++ b/xmake.lua @@ -80,8 +80,8 @@ local modules = { Deps = {"NazaraPlatform", "NazaraShader"} }, Shader = { - Packages = {"efsw", "fmt"}, Deps = {"NazaraCore"}, + Packages = {"efsw", "fmt", "frozen"}, Custom = function() -- Set precise floating-points models to ensure shader optimization leads to correct results set_fpmodels("precise") @@ -131,7 +131,7 @@ option_end() set_project("NazaraEngine") 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("libvorbis", { configs = { with_vorbisenc = false } }) add_requires("openal-soft", { configs = { shared = true }})