From e4a57cedf9b0e8af53e535a2c4ad9a04f1fff90b Mon Sep 17 00:00:00 2001 From: Eliza Velasquez Date: Tue, 10 Oct 2023 16:51:15 -0700 Subject: [PATCH] matinfo: add support for viewing ESSL1 code --- NEW_RELEASE_NOTES.md | 1 + libs/matdbg/include/matdbg/ShaderExtractor.h | 2 +- libs/matdbg/include/matdbg/ShaderInfo.h | 2 +- libs/matdbg/src/DebugServer.cpp | 10 ++-- libs/matdbg/src/JsonWriter.cpp | 4 +- libs/matdbg/src/ShaderExtractor.cpp | 16 ++--- libs/matdbg/src/ShaderInfo.cpp | 6 +- libs/matdbg/src/TextWriter.cpp | 21 +++++-- tools/matinfo/src/main.cpp | 62 ++++++++++++++++---- 9 files changed, 91 insertions(+), 33 deletions(-) diff --git a/NEW_RELEASE_NOTES.md b/NEW_RELEASE_NOTES.md index 5b74000c76..2261ab10d7 100644 --- a/NEW_RELEASE_NOTES.md +++ b/NEW_RELEASE_NOTES.md @@ -10,3 +10,4 @@ appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md). - engine: Added parameter for configuring JobSystem thread count - engine: In Java, introduce Engine.Builder +- matinfo: Add support for viewing ESSL 1.0 shaders diff --git a/libs/matdbg/include/matdbg/ShaderExtractor.h b/libs/matdbg/include/matdbg/ShaderExtractor.h index 0d1848de90..3669b50bf4 100644 --- a/libs/matdbg/include/matdbg/ShaderExtractor.h +++ b/libs/matdbg/include/matdbg/ShaderExtractor.h @@ -31,7 +31,7 @@ namespace matdbg { // in a manner similar to ShaderReplacer. class ShaderExtractor { public: - ShaderExtractor(backend::Backend backend, const void* data, size_t size); + ShaderExtractor(backend::ShaderLanguage target, const void* data, size_t size); bool parse() noexcept; bool getShader(backend::ShaderModel shaderModel, Variant variant, backend::ShaderStage stage, filaflat::ShaderContent& shader) noexcept; diff --git a/libs/matdbg/include/matdbg/ShaderInfo.h b/libs/matdbg/include/matdbg/ShaderInfo.h index fc571c734a..2960b28e1c 100644 --- a/libs/matdbg/include/matdbg/ShaderInfo.h +++ b/libs/matdbg/include/matdbg/ShaderInfo.h @@ -36,7 +36,7 @@ struct ShaderInfo { size_t getShaderCount(const filaflat::ChunkContainer& container, filamat::ChunkType type); bool getMetalShaderInfo(const filaflat::ChunkContainer& container, ShaderInfo* info); -bool getGlShaderInfo(const filaflat::ChunkContainer& container, ShaderInfo* info); +bool getGlShaderInfo(const filaflat::ChunkContainer& container, ShaderInfo* info, filamat::ChunkType chunkType); bool getVkShaderInfo(const filaflat::ChunkContainer& container, ShaderInfo* info); } // namespace matdbg diff --git a/libs/matdbg/src/DebugServer.cpp b/libs/matdbg/src/DebugServer.cpp index 1ccd12bf20..219959d3c1 100644 --- a/libs/matdbg/src/DebugServer.cpp +++ b/libs/matdbg/src/DebugServer.cpp @@ -280,7 +280,7 @@ public: } FixedCapacityVector info(getShaderCount(package, ChunkType::MaterialGlsl)); - if (!getGlShaderInfo(package, info.data())) { + if (!getGlShaderInfo(package, info.data(), ChunkType::MaterialGlsl)) { return error(__LINE__); } @@ -289,7 +289,7 @@ public: return error(__LINE__); } - ShaderExtractor extractor(Backend::OPENGL, result->package, result->packageSize); + ShaderExtractor extractor(ShaderLanguage::ESSL3, result->package, result->packageSize); if (!extractor.parse()) { return error(__LINE__); } @@ -304,7 +304,7 @@ public: } if (vkindex[0]) { - ShaderExtractor extractor(Backend::VULKAN, result->package, result->packageSize); + ShaderExtractor extractor(ShaderLanguage::SPIRV, result->package, result->packageSize); if (!extractor.parse()) { return error(__LINE__); } @@ -337,7 +337,7 @@ public: } if (metalindex[0]) { - ShaderExtractor extractor(Backend::METAL, result->package, result->packageSize); + ShaderExtractor extractor(ShaderLanguage::MSL, result->package, result->packageSize); if (!extractor.parse()) { return error(__LINE__); } @@ -600,7 +600,7 @@ bool DebugServer::handleEditCommand(const MaterialKey& key, backend::Backend api shaderCount = getShaderCount(package, ChunkType::MaterialGlsl); infos.reserve(shaderCount); infos.resize(shaderCount); - if (!getGlShaderInfo(package, infos.data())) { + if (!getGlShaderInfo(package, infos.data(), ChunkType::MaterialGlsl)) { return error(__LINE__); } break; diff --git a/libs/matdbg/src/JsonWriter.cpp b/libs/matdbg/src/JsonWriter.cpp index ba052252c2..619022dd92 100644 --- a/libs/matdbg/src/JsonWriter.cpp +++ b/libs/matdbg/src/JsonWriter.cpp @@ -139,7 +139,7 @@ static void printShaderInfo(ostream& json, const vector& info, const static bool printGlslInfo(ostream& json, const ChunkContainer& container) { std::vector info; info.resize(getShaderCount(container, ChunkType::MaterialGlsl)); - if (!getGlShaderInfo(container, info.data())) { + if (!getGlShaderInfo(container, info.data(), ChunkType::MaterialGlsl)) { return false; } json << "\"opengl\": [\n"; @@ -227,7 +227,7 @@ bool JsonWriter::writeActiveInfo(const filaflat::ChunkContainer& package, switch (backend) { case Backend::OPENGL: shaders.resize(getShaderCount(package, ChunkType::MaterialGlsl)); - getGlShaderInfo(package, shaders.data()); + getGlShaderInfo(package, shaders.data(), ChunkType::MaterialGlsl); json << "opengl"; break; case Backend::VULKAN: diff --git a/libs/matdbg/src/ShaderExtractor.cpp b/libs/matdbg/src/ShaderExtractor.cpp index 3f10b60a01..f9dbe0ea1e 100644 --- a/libs/matdbg/src/ShaderExtractor.cpp +++ b/libs/matdbg/src/ShaderExtractor.cpp @@ -38,23 +38,25 @@ using namespace utils; namespace filament { namespace matdbg { -ShaderExtractor::ShaderExtractor(Backend backend, const void* data, size_t size) +ShaderExtractor::ShaderExtractor(backend::ShaderLanguage target, const void* data, size_t size) : mChunkContainer(data, size), mMaterialChunk(mChunkContainer) { - switch (backend) { - case Backend::OPENGL: + switch (target) { + case backend::ShaderLanguage::ESSL1: + mMaterialTag = ChunkType::MaterialEssl1; + mDictionaryTag = ChunkType::DictionaryText; + break; + case backend::ShaderLanguage::ESSL3: mMaterialTag = ChunkType::MaterialGlsl; mDictionaryTag = ChunkType::DictionaryText; break; - case Backend::METAL: + case backend::ShaderLanguage::MSL: mMaterialTag = ChunkType::MaterialMetal; mDictionaryTag = ChunkType::DictionaryText; break; - case Backend::VULKAN: + case backend::ShaderLanguage::SPIRV: mMaterialTag = ChunkType::MaterialSpirv; mDictionaryTag = ChunkType::DictionarySpirv; break; - default: - break; } } diff --git a/libs/matdbg/src/ShaderInfo.cpp b/libs/matdbg/src/ShaderInfo.cpp index 6b857a5b9d..2c39e8f9dc 100644 --- a/libs/matdbg/src/ShaderInfo.cpp +++ b/libs/matdbg/src/ShaderInfo.cpp @@ -94,12 +94,12 @@ bool getMetalShaderInfo(const ChunkContainer& container, ShaderInfo* info) { return true; } -bool getGlShaderInfo(const ChunkContainer& container, ShaderInfo* info) { - if (!container.hasChunk(ChunkType::MaterialGlsl)) { +bool getGlShaderInfo(const ChunkContainer& container, ShaderInfo* info, ChunkType chunkType) { + if (!container.hasChunk(chunkType)) { return true; } - auto [start, end] = container.getChunkRange(ChunkType::MaterialGlsl); + auto [start, end] = container.getChunkRange(chunkType); Unflattener unflattener(start, end); uint64_t shaderCount; diff --git a/libs/matdbg/src/TextWriter.cpp b/libs/matdbg/src/TextWriter.cpp index d71a093347..a6ebcc5d6b 100644 --- a/libs/matdbg/src/TextWriter.cpp +++ b/libs/matdbg/src/TextWriter.cpp @@ -402,13 +402,23 @@ static void printShaderInfo(ostream& text, const vector& info, text << endl; } -static bool printGlslInfo(ostream& text, const ChunkContainer& container) { +static bool printGlslInfo(ostream& text, const ChunkContainer& container, ChunkType chunkType) { vector info; info.resize(getShaderCount(container, ChunkType::MaterialGlsl)); - if (!getGlShaderInfo(container, info.data())) { + if (!getGlShaderInfo(container, info.data(), ChunkType::MaterialGlsl)) { return false; } - text << "GLSL shaders:" << endl; + switch (chunkType) { + case ChunkType::MaterialGlsl: + text << "GLSL shaders:" << endl; + break; + case ChunkType::MaterialEssl1: + text << "ESSL1 shaders:" << endl; + break; + default: + assert(false && "Invalid GLSL ChunkType"); + break; + } printShaderInfo(text, info, container); return true; } @@ -449,7 +459,10 @@ bool TextWriter::writeMaterialInfo(const filaflat::ChunkContainer& container) { if (!printSubpassesInfo(text, container)) { return false; } - if (!printGlslInfo(text, container)) { + if (!printGlslInfo(text, container, ChunkType::MaterialGlsl)) { + return false; + } + if (!printGlslInfo(text, container, ChunkType::MaterialEssl1)) { return false; } if (!printVkInfo(text, container)) { diff --git a/tools/matinfo/src/main.cpp b/tools/matinfo/src/main.cpp index 15a458335b..f9fff121c3 100644 --- a/tools/matinfo/src/main.cpp +++ b/tools/matinfo/src/main.cpp @@ -47,9 +47,11 @@ using utils::Path; struct Config { bool printGLSL = false; + bool printESSL1 = false; bool printSPIRV = false; bool printMetal = false; bool printDictionaryGLSL = false; + bool printDictionaryESSL1 = false; bool printDictionarySPIRV = false; bool printDictionaryMetal = false; bool transpile = false; @@ -76,6 +78,8 @@ static void printUsage(const char* name) { " Print this message\n\n" " --print-glsl=[index], -g\n" " Print GLSL for the nth shader (0 is the first OpenGL shader)\n\n" + " --print-essl1=[index], -G\n" + " Print GLES SL version 1 shader for the nth shader (0 is the first ESSL shader)\n\n" " --print-spirv=[index], -s\n" " Validate and print disasm for the nth shader (0 is the first Vulkan shader)\n\n" " --print-metal=[index], -m\n" @@ -84,6 +88,8 @@ static void printUsage(const char* name) { " Print the nth Vulkan shader transpiled into GLSL\n\n" " --print-dic-glsl\n" " Print the GLSL dictionary\n\n" + " --print-dic-essl1\n" + " Print the ESSL1 dictionary\n\n" " --print-dic-metal\n" " Print the Metal dictionary\n\n" " --print-dic-vk\n" @@ -117,16 +123,18 @@ static void license() { } static int handleArguments(int argc, char* argv[], Config* config) { - static constexpr const char* OPTSTR = "hla:g:s:v:b:m:b:w:xyz"; + static constexpr const char* OPTSTR = "hla:g:G:s:v:b:m:b:w:Xxyz"; static const struct option OPTIONS[] = { { "help", no_argument, nullptr, 'h' }, { "license", no_argument, nullptr, 'l' }, { "analyze-spirv", required_argument, nullptr, 'a' }, { "print-glsl", required_argument, nullptr, 'g' }, + { "print-essl1", required_argument, nullptr, 'G' }, { "print-spirv", required_argument, nullptr, 's' }, { "print-vkglsl", required_argument, nullptr, 'v' }, { "print-metal", required_argument, nullptr, 'm' }, { "print-dic-glsl", no_argument, nullptr, 'x' }, + { "print-dic-essl1", no_argument, nullptr, 'X' }, { "print-dic-metal", no_argument, nullptr, 'y' }, { "print-dic-vk", no_argument, nullptr, 'z' }, { "dump-binary", required_argument, nullptr, 'b' }, @@ -151,6 +159,10 @@ static int handleArguments(int argc, char* argv[], Config* config) { config->printGLSL = true; config->shaderIndex = static_cast(std::stoi(arg)); break; + case 'G': + config->printESSL1 = true; + config->shaderIndex = static_cast(std::stoi(arg)); + break; case 's': config->printSPIRV = true; config->shaderIndex = static_cast(std::stoi(arg)); @@ -180,6 +192,9 @@ static int handleArguments(int argc, char* argv[], Config* config) { case 'x': config->printDictionaryGLSL = true; break; + case 'X': + config->printDictionaryESSL1 = true; + break; case 'y': config->printDictionaryMetal = true; break; @@ -409,18 +424,18 @@ static bool parseChunks(Config config, void* data, size_t size) { return true; } - if (config.printGLSL || config.printSPIRV || config.printMetal) { + if (config.printGLSL || config.printESSL1 || config.printSPIRV || config.printMetal) { filaflat::ShaderContent content; std::vector info; if (config.printGLSL) { - ShaderExtractor parser(Backend::OPENGL, data, size); + ShaderExtractor parser(filament::backend::ShaderLanguage::ESSL3, data, size); if (!parser.parse()) { return false; } info.resize(getShaderCount(container, filamat::ChunkType::MaterialGlsl)); - if (!getGlShaderInfo(container, info.data())) { + if (!getGlShaderInfo(container, info.data(), filamat::ChunkType::MaterialGlsl)) { std::cerr << "Failed to parse GLSL chunk." << std::endl; return false; } @@ -439,8 +454,34 @@ static bool parseChunks(Config config, void* data, size_t size) { return true; } + if (config.printESSL1) { + ShaderExtractor parser(filament::backend::ShaderLanguage::ESSL1, data, size); + if (!parser.parse()) { + return false; + } + + info.resize(getShaderCount(container, filamat::ChunkType::MaterialEssl1)); + if (!getGlShaderInfo(container, info.data(), filamat::ChunkType::MaterialEssl1)) { + std::cerr << "Failed to parse ESSL1 chunk." << std::endl; + return false; + } + + if (config.shaderIndex >= info.size()) { + std::cerr << "Shader index out of range." << std::endl; + return false; + } + + const auto& item = info[config.shaderIndex]; + parser.getShader(item.shaderModel, item.variant, item.pipelineStage, content); + + // Cast to char* to print as a string rather than hex value. + std::cout << (const char*) content.data(); + + return true; + } + if (config.printSPIRV) { - ShaderExtractor parser(Backend::VULKAN, data, size); + ShaderExtractor parser(filament::backend::ShaderLanguage::SPIRV, data, size); if (!parser.parse()) { return false; } @@ -476,7 +517,7 @@ static bool parseChunks(Config config, void* data, size_t size) { } if (config.printMetal) { - ShaderExtractor parser(Backend::METAL, data, size); + ShaderExtractor parser(filament::backend::ShaderLanguage::MSL, data, size); if (!parser.parse()) { return false; } @@ -502,11 +543,12 @@ static bool parseChunks(Config config, void* data, size_t size) { TextWriter writer; - if (config.printDictionaryGLSL || config.printDictionarySPIRV || config.printDictionaryMetal) { + if (config.printDictionaryGLSL || config.printDictionaryESSL1 || config.printDictionarySPIRV || config.printDictionaryMetal) { ShaderExtractor parser( - (config.printDictionaryGLSL ? Backend::OPENGL : - (config.printDictionarySPIRV ? Backend::VULKAN : - (config.printDictionaryMetal ? Backend::METAL : Backend::DEFAULT))), data, size); + (config.printDictionaryGLSL ? filament::backend::ShaderLanguage::ESSL3 : + (config.printDictionaryESSL1 ? filament::backend::ShaderLanguage::ESSL1 : + (config.printDictionarySPIRV ? filament::backend::ShaderLanguage::SPIRV : + filament::backend::ShaderLanguage::MSL))), data, size); if (!parser.parse()) { return false;