Add option to preserve text shaders (#7786)
This commit is contained in:
committed by
Benjamin Doherty
parent
76a8f18700
commit
2f36df8d93
@@ -287,7 +287,8 @@ bool compileMetalShaders(const std::vector<filamat::TextEntry>& mslEntries,
|
||||
return true;
|
||||
}
|
||||
|
||||
int externalCompile(utils::Path input, utils::Path output, std::vector<std::string> args) {
|
||||
int externalCompile(utils::Path input, utils::Path output, bool preserveTextShaders,
|
||||
std::vector<std::string> args) {
|
||||
std::ifstream in(input.c_str(), std::ifstream::in | std::ios::binary);
|
||||
if (!in.is_open()) {
|
||||
std::cerr << "Could not open the source material " << input << std::endl;
|
||||
@@ -333,18 +334,7 @@ int externalCompile(utils::Path input, utils::Path output, std::vector<std::stri
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Since we're modifying text shaders, we'll need to regenerate the text dictionary.
|
||||
// We'll also need to re-emit text based shaders that rely on the dictionary.
|
||||
// Here we ONLY add GLSL and ESSL 1 types, as we're removing MSL completely.
|
||||
filamat::LineDictionary textDictionary;
|
||||
for (const auto& s : glslEntries) {
|
||||
textDictionary.addText(s.shader);
|
||||
}
|
||||
for (const auto& s : essl1Entries) {
|
||||
textDictionary.addText(s.shader);
|
||||
}
|
||||
|
||||
// We'll also need to regenerate the SPIRV dictionary and SPIRV shaders.
|
||||
// We always need to regenerate the SPIRV dictionary and SPIRV shaders.
|
||||
// This is required, as the SPIRV blobs have alignment requirements. Since we're modifying other
|
||||
// chunks, their alignment might have changed.
|
||||
filamat::BlobDictionary spirvDictionary;
|
||||
@@ -359,19 +349,28 @@ int externalCompile(utils::Path input, utils::Path output, std::vector<std::stri
|
||||
e.dictionaryIndex = metalBinaryDictionary.addBlob(data);
|
||||
}
|
||||
|
||||
bool removingMslShaders = !preserveTextShaders;
|
||||
|
||||
// Pass through chunks that don't need to change.
|
||||
filamat::ChunkContainer outputChunks;
|
||||
for (int i = 0; i < container.getChunkCount(); i++) {
|
||||
filaflat::ChunkContainer::Chunk c = container.getChunk(i);
|
||||
if (c.type == filamat::ChunkType::MaterialMetal) {
|
||||
// This chunk is being removed, skip it.
|
||||
continue;
|
||||
|
||||
if (removingMslShaders) {
|
||||
if (c.type == filamat::ChunkType::MaterialMetal) {
|
||||
// This chunk is being removed, skip it.
|
||||
continue;
|
||||
}
|
||||
if (c.type == filamat::ChunkType::MaterialGlsl ||
|
||||
c.type == filamat::ChunkType::MaterialEssl1 ||
|
||||
c.type == filamat::ChunkType::DictionaryText) {
|
||||
// These shader / dictionary chunks will be re-added below.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (c.type == filamat::ChunkType::MaterialGlsl ||
|
||||
c.type == filamat::ChunkType::MaterialEssl1 ||
|
||||
c.type == filamat::ChunkType::MaterialSpirv ||
|
||||
c.type == filamat::ChunkType::DictionarySpirv ||
|
||||
c.type == filamat::ChunkType::DictionaryText) {
|
||||
|
||||
if (c.type == filamat::ChunkType::MaterialSpirv ||
|
||||
c.type == filamat::ChunkType::DictionarySpirv) {
|
||||
// These shader / dictionary chunks will be re-added below.
|
||||
continue;
|
||||
}
|
||||
@@ -379,21 +378,34 @@ int externalCompile(utils::Path input, utils::Path output, std::vector<std::stri
|
||||
reinterpret_cast<const char*>(c.desc.start), c.desc.size, c.type);
|
||||
}
|
||||
|
||||
// Add the re-generated text dictionary chunk and text-based shaders.
|
||||
if (!textDictionary.isEmpty()) {
|
||||
const auto& dictionaryChunk = outputChunks.push<filamat::DictionaryTextChunk>(
|
||||
std::move(textDictionary), filamat::ChunkType::DictionaryText);
|
||||
|
||||
// Re-emit GLSL chunk (MaterialTextChunk).
|
||||
if (!glslEntries.empty()) {
|
||||
outputChunks.push<filamat::MaterialTextChunk>(std::move(glslEntries),
|
||||
dictionaryChunk.getDictionary(), filamat::ChunkType::MaterialGlsl);
|
||||
if (removingMslShaders) {
|
||||
// Since we're modifying text shaders, we'll need to regenerate the text dictionary.
|
||||
// We'll also need to re-emit text based shaders that rely on the dictionary.
|
||||
// Here we ONLY add GLSL and ESSL 1 types, as we're removing MSL completely.
|
||||
filamat::LineDictionary textDictionary;
|
||||
for (const auto& s : glslEntries) {
|
||||
textDictionary.addText(s.shader);
|
||||
}
|
||||
for (const auto& s : essl1Entries) {
|
||||
textDictionary.addText(s.shader);
|
||||
}
|
||||
|
||||
// Re-emit ESSL1 chunk (MaterialTextChunk).
|
||||
if (!essl1Entries.empty()) {
|
||||
outputChunks.push<filamat::MaterialTextChunk>(std::move(essl1Entries),
|
||||
dictionaryChunk.getDictionary(), filamat::ChunkType::MaterialEssl1);
|
||||
// Add the re-generated text dictionary chunk and text-based shaders.
|
||||
if (!textDictionary.isEmpty()) {
|
||||
const auto& dictionaryChunk = outputChunks.push<filamat::DictionaryTextChunk>(
|
||||
std::move(textDictionary), filamat::ChunkType::DictionaryText);
|
||||
|
||||
// Re-emit GLSL chunk (MaterialTextChunk).
|
||||
if (!glslEntries.empty()) {
|
||||
outputChunks.push<filamat::MaterialTextChunk>(std::move(glslEntries),
|
||||
dictionaryChunk.getDictionary(), filamat::ChunkType::MaterialGlsl);
|
||||
}
|
||||
|
||||
// Re-emit ESSL1 chunk (MaterialTextChunk).
|
||||
if (!essl1Entries.empty()) {
|
||||
outputChunks.push<filamat::MaterialTextChunk>(std::move(essl1Entries),
|
||||
dictionaryChunk.getDictionary(), filamat::ChunkType::MaterialEssl1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
|
||||
namespace matedit {
|
||||
|
||||
int externalCompile(utils::Path input, utils::Path output, std::vector<std::string> args);
|
||||
int externalCompile(utils::Path input, utils::Path output, bool preserveTextShaders,
|
||||
std::vector<std::string> args);
|
||||
|
||||
} // namespace matedit
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ struct Config {
|
||||
utils::Path inputFile;
|
||||
utils::Path outputFile;
|
||||
std::vector<std::string> commandArgs;
|
||||
bool preserveTextShaders = false;
|
||||
};
|
||||
|
||||
static void printUsage(const char* name) {
|
||||
@@ -55,6 +56,9 @@ static void printUsage(const char* name) {
|
||||
" --type=[shader type], -t\n"
|
||||
" Specify the shader type, currently only metal is supported\n"
|
||||
"\n"
|
||||
" --preserve-text-shaders, -p\n"
|
||||
" Keep the text-based shaders when writing the output file\n"
|
||||
"\n"
|
||||
"Commands:\n"
|
||||
" external-compile\n"
|
||||
" Transforms all the text-based shaders of the specified type in the input file into binaries\n"
|
||||
@@ -76,7 +80,8 @@ static void printUsage(const char* name) {
|
||||
" <input shader> is guaranteed to have a .metal extension.\n"
|
||||
" <output binary> is guaranteed to have a .metallib extension.\n"
|
||||
"\n"
|
||||
" This command will remove the text-based shaders when writing the output material file.\n"
|
||||
" This command will remove the text-based shaders when writing the output material file, unless\n"
|
||||
" the --preserve-text-shaders option is specified.\n"
|
||||
"\n"
|
||||
" If script exits with a non-zero exit code, MATEDIT will terminate with error. Multiple\n"
|
||||
" invocations of script may be launched in parallel.\n"
|
||||
@@ -93,12 +98,13 @@ static void printUsage(const char* name) {
|
||||
}
|
||||
|
||||
static int handleArguments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "hi:o:t:";
|
||||
static constexpr const char* OPTSTR = "hi:o:t:p";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "input", required_argument, nullptr, 'i' },
|
||||
{ "output", required_argument, nullptr, 'o' },
|
||||
{ "type", required_argument, nullptr, 't' },
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "input", required_argument, nullptr, 'i' },
|
||||
{ "output", required_argument, nullptr, 'o' },
|
||||
{ "type", required_argument, nullptr, 't' },
|
||||
{ "preserve-text-shaders", no_argument, nullptr, 'p' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
};
|
||||
|
||||
@@ -126,6 +132,10 @@ static int handleArguments(int argc, char* argv[], Config* config) {
|
||||
<< std::endl;
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
config->preserveTextShaders = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,5 +186,6 @@ int main(int argc, char* argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return matedit::externalCompile(config.inputFile, config.outputFile, config.commandArgs);
|
||||
return matedit::externalCompile(
|
||||
config.inputFile, config.outputFile, config.preserveTextShaders, config.commandArgs);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user