From e48690bdf92ced40638bc58d994f50edf2ceae8a Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 3 Apr 2023 13:20:10 -0700 Subject: [PATCH] matc: new feature-level options The feature-level option sets the maximum feature level allowed for the material. matc will fail if the specified material has a higher feature level than the value set with the feature-level option. The default is 3 (max). This can be used to ensure that materials don't use features above a specified level. --- .../filamat/include/filamat/MaterialBuilder.h | 1 + libs/filamat/src/MaterialBuilder.cpp | 2 +- tools/matc/src/matc/CommandlineConfig.cpp | 21 ++++++++++++++++--- tools/matc/src/matc/Config.h | 5 +++++ tools/matc/src/matc/MaterialCompiler.cpp | 6 ++++++ 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/libs/filamat/include/filamat/MaterialBuilder.h b/libs/filamat/include/filamat/MaterialBuilder.h index 2456951a6a..8cbeba4728 100644 --- a/libs/filamat/include/filamat/MaterialBuilder.h +++ b/libs/filamat/include/filamat/MaterialBuilder.h @@ -694,6 +694,7 @@ public: filament::UserVariantFilterMask getVariantFilter() const { return mVariantFilter; } + FeatureLevel getFeatureLevel() const noexcept { return mFeatureLevel; } /// @endcond private: diff --git a/libs/filamat/src/MaterialBuilder.cpp b/libs/filamat/src/MaterialBuilder.cpp index f8eb0811f2..70dea00f61 100644 --- a/libs/filamat/src/MaterialBuilder.cpp +++ b/libs/filamat/src/MaterialBuilder.cpp @@ -1187,7 +1187,7 @@ std::string MaterialBuilder::peek(backend::ShaderStage stage, void MaterialBuilder::writeCommonChunks(ChunkContainer& container, MaterialInfo& info) const noexcept { container.addSimpleChild(ChunkType::MaterialVersion, MATERIAL_VERSION); - container.addSimpleChild(ChunkType::MaterialFeatureLevel, (uint8_t)mFeatureLevel); + container.addSimpleChild(ChunkType::MaterialFeatureLevel, (uint8_t)info.featureLevel); container.addSimpleChild(ChunkType::MaterialName, mMaterialName.c_str_safe()); container.addSimpleChild(ChunkType::MaterialShaderModels, mShaderModels.getValue()); container.addSimpleChild(ChunkType::MaterialDomain, static_cast(mMaterialDomain)); diff --git a/tools/matc/src/matc/CommandlineConfig.cpp b/tools/matc/src/matc/CommandlineConfig.cpp index 5390ee8ade..5d18fd46a6 100644 --- a/tools/matc/src/matc/CommandlineConfig.cpp +++ b/tools/matc/src/matc/CommandlineConfig.cpp @@ -60,6 +60,8 @@ static void usage(char* name) { " Specify the target API: opengl (default), vulkan, metal, or all\n" " This flag can be repeated to individually select APIs for inclusion:\n" " MATC --api opengl --api metal ...\n\n" + " --feature-level, -l\n" + " Specify the maximum feature level allowed (default is 3).\n\n" " --define, -D\n" " Add a preprocessor define macro via =. defaults to 1 if omitted.\n" " Can be repeated to specify multiple definitions:\n" @@ -165,10 +167,10 @@ static void parseDefine(std::string defineString, Config::StringReplacementMap& } bool CommandlineConfig::parse() { - static constexpr const char* OPTSTR = "hlxo:f:dm:a:p:D:T:OSEr:vV:gtw"; + static constexpr const char* OPTSTR = "hLxo:f:dm:a:l:p:D:T:OSEr:vV:gtw"; static const struct option OPTIONS[] = { { "help", no_argument, nullptr, 'h' }, - { "license", no_argument, nullptr, 'l' }, + { "license", no_argument, nullptr, 'L' }, { "output", required_argument, nullptr, 'o' }, { "output-format", required_argument, nullptr, 'f' }, { "debug", no_argument, nullptr, 'd' }, @@ -180,6 +182,7 @@ bool CommandlineConfig::parse() { { "optimize-none", no_argument, nullptr, 'g' }, { "preprocessor-only", no_argument, nullptr, 'E' }, { "api", required_argument, nullptr, 'a' }, + { "feature-level", required_argument, nullptr, 'l' }, { "define", required_argument, nullptr, 'D' }, { "template", required_argument, nullptr, 'T' }, { "reflect", required_argument, nullptr, 'r' }, @@ -200,7 +203,7 @@ bool CommandlineConfig::parse() { usage(mArgv[0]); exit(0); break; - case 'l': + case 'L': license(); exit(0); break; @@ -249,6 +252,18 @@ bool CommandlineConfig::parse() { return false; } break; + case 'l': { + auto featureLevel = filament::backend::FeatureLevel(std::atoi(arg.c_str())); + mFeatureLevel = filament::backend::FeatureLevel::FEATURE_LEVEL_3; + switch (featureLevel) { + case filament::backend::FeatureLevel::FEATURE_LEVEL_1: + case filament::backend::FeatureLevel::FEATURE_LEVEL_2: + case filament::backend::FeatureLevel::FEATURE_LEVEL_3: + mFeatureLevel = featureLevel; + break; + } + break; + } case 'D': parseDefine(arg, mDefines); break; diff --git a/tools/matc/src/matc/Config.h b/tools/matc/src/matc/Config.h index 0ceb051669..07b2c80626 100644 --- a/tools/matc/src/matc/Config.h +++ b/tools/matc/src/matc/Config.h @@ -127,6 +127,10 @@ public: return mTemplateMap; } + filament::backend::FeatureLevel getFeatureLevel() const noexcept { + return mFeatureLevel; + } + protected: bool mDebug = false; bool mIsValid = true; @@ -137,6 +141,7 @@ protected: Platform mPlatform = Platform::ALL; OutputFormat mOutputFormat = OutputFormat::BLOB; TargetApi mTargetApi = (TargetApi) 0; + filament::backend::FeatureLevel mFeatureLevel = filament::backend::FeatureLevel::FEATURE_LEVEL_3; StringReplacementMap mDefines; StringReplacementMap mTemplateMap; filament::UserVariantFilterMask mVariantFilter = 0; diff --git a/tools/matc/src/matc/MaterialCompiler.cpp b/tools/matc/src/matc/MaterialCompiler.cpp index 14470e9fe6..92f67265a5 100644 --- a/tools/matc/src/matc/MaterialCompiler.cpp +++ b/tools/matc/src/matc/MaterialCompiler.cpp @@ -379,6 +379,12 @@ bool MaterialCompiler::run(const Config& config) { return false; } + if (builder.getFeatureLevel() > config.getFeatureLevel()) { + std::cerr << "Material feature level (" << +builder.getFeatureLevel() << ") is higher " + "than maximum allowed (" << +config.getFeatureLevel() << ")" << std::endl; + return false; + } + switch (config.getReflectionTarget()) { case Config::Metadata::NONE: break;