Add saveRawVariants flag to matc (#7949)

This commit is contained in:
Ben Doherty
2024-06-27 14:36:03 -07:00
committed by GitHub
parent a2fe9f745c
commit 44b4de904e
6 changed files with 56 additions and 6 deletions

View File

@@ -64,14 +64,15 @@ First determine the Filament material and variant that causes the problem.
What we want is the "raw" GLSL version of the shader, before any optimizations / cross-compilation
happens.
The easiest way I've found to do this is by adding a `std::cout` statement inside `MaterialBuilder`,
right after `sg.createFragmentProgram` or `sg.createVertexProgram` is called. For example,
We can use the `--save-raw-variants` debug flag in matc to export each GLSL
shader to a file. For example:
```
if (v.variant.key == 8u) { std::cout << shader << std::endl; }
matc --save-raw-variants --optimize-size --variant-filter fog,ssr,vsm,stereo \
-a all -p all -o mymaterial.filamat mymaterial.mat
```
Then, I invoke `matc` and redirect stdout to a .frag or .vert file.
Files will be named like `mymaterial_0x05.frag` or `mymaterial_0x05.vert`.
Note that gltfio material "templates" first go through a build step. After building gltfio, the
gltfio Filament materials are output to:

View File

@@ -134,6 +134,7 @@ protected:
TargetApi mTargetApi = (TargetApi) 0;
Optimization mOptimization = Optimization::PERFORMANCE;
bool mPrintShaders = false;
bool mSaveRawVariants = false;
bool mGenerateDebugInfo = false;
bool mIncludeEssl1 = true;
utils::bitset32 mShaderModels;
@@ -586,6 +587,14 @@ public:
//! If true, will output the generated GLSL shader code to stdout.
MaterialBuilder& printShaders(bool printShaders) noexcept;
/**
* If true, this will write the raw generated GLSL for each variant to a text file in the
* current directory. The file will be named after the material name and the variant name. Its
* extension will be derived from the shader stage. For example, mymaterial_0x0e.frag,
* mymaterial_0x18.vert, etc.
*/
MaterialBuilder& saveRawVariants(bool saveVariants) noexcept;
//! If true, will include debugging information in generated SPIRV.
MaterialBuilder& generateDebugInfo(bool generateDebugInfo) noexcept;

View File

@@ -57,7 +57,7 @@
#include <atomic>
#include <utility>
#include <vector>
#include <fstream>
namespace filamat {
@@ -547,6 +547,11 @@ MaterialBuilder& MaterialBuilder::printShaders(bool printShaders) noexcept {
return *this;
}
MaterialBuilder& MaterialBuilder::saveRawVariants(bool saveRawVariants) noexcept {
mSaveRawVariants = saveRawVariants;
return *this;
}
MaterialBuilder& MaterialBuilder::generateDebugInfo(bool generateDebugInfo) noexcept {
mGenerateDebugInfo = generateDebugInfo;
return *this;
@@ -918,6 +923,30 @@ bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector<Va
shaderModel, targetApi, targetLanguage, featureLevel, info);
}
// Write the variant to a file.
if (mSaveRawVariants) {
int variantKey = v.variant.key;
auto getExtension = [](backend::ShaderStage stage) {
switch (stage) {
case backend::ShaderStage::VERTEX:
return "vert";
case backend::ShaderStage::FRAGMENT:
return "frag";
case backend::ShaderStage::COMPUTE:
return "comp";
}
};
char filename[256];
snprintf(filename, sizeof(filename), "%s_0x%02x.%s", mMaterialName.c_str_safe(),
variantKey, getExtension(v.stage));
printf("Writing variant 0x%02x to %s\n", variantKey, filename);
std::ofstream file(filename);
if (file.is_open()) {
file << shader;
file.close();
}
}
std::string* pGlsl = nullptr;
if (targetApiNeedsGlsl) {
pGlsl = &shader;

View File

@@ -103,6 +103,8 @@ static void usage(char* name) {
" Skip validation of number of sampler used\n\n"
" --print, -t\n"
" Print generated shaders for debugging\n\n"
" --save-raw-variants, -R\n"
" Write the raw generated GLSL for each variant to a text file in the current directory.\n\n"
);
const std::string from("MATC");
for (size_t pos = usage.find(from); pos != std::string::npos; pos = usage.find(from, pos)) {
@@ -179,7 +181,7 @@ static void parseDefine(std::string defineString, Config::StringReplacementMap&
}
bool CommandlineConfig::parse() {
static constexpr const char* OPTSTR = "hLxo:f:dm:a:l:p:D:T:P:OSEr:vV:gtwF1";
static constexpr const char* OPTSTR = "hLxo:f:dm:a:l:p:D:T:P:OSEr:vV:gtwF1R";
static const struct option OPTIONS[] = {
{ "help", no_argument, nullptr, 'h' },
{ "license", no_argument, nullptr, 'L' },
@@ -204,6 +206,7 @@ bool CommandlineConfig::parse() {
{ "version", no_argument, nullptr, 'v' },
{ "raw", no_argument, nullptr, 'w' },
{ "no-sampler-validation", no_argument, nullptr, 'F' },
{ "save-raw-variants", no_argument, nullptr, 'R' },
{ nullptr, 0, nullptr, 0 } // termination of the option list
};
@@ -326,6 +329,8 @@ bool CommandlineConfig::parse() {
break;
case 'F':
mNoSamplerValidation = true;
case 'R':
mSaveRawVariants = true;
break;
}
}

View File

@@ -111,6 +111,10 @@ public:
return mPrintShaders;
}
bool saveRawVariants() const noexcept {
return mSaveRawVariants;
}
bool rawShaderMode() const noexcept {
return mRawShaderMode;
}
@@ -149,6 +153,7 @@ protected:
bool mPrintShaders = false;
bool mRawShaderMode = false;
bool mNoSamplerValidation = false;
bool mSaveRawVariants = false;
Optimization mOptimizationLevel = Optimization::PERFORMANCE;
Metadata mReflectionTarget = Metadata::NONE;
Platform mPlatform = Platform::ALL;

View File

@@ -408,6 +408,7 @@ bool MaterialCompiler::run(const Config& config) {
.targetApi(config.getTargetApi())
.optimization(config.getOptimizationLevel())
.printShaders(config.printShaders())
.saveRawVariants(config.saveRawVariants())
.generateDebugInfo(config.isDebug())
.variantFilter(config.getVariantFilter() | builder.getVariantFilter());