From ecb0f3b75bd03f4732df5a86f27c24b0d0b00bec Mon Sep 17 00:00:00 2001 From: Johannes van Waveren Date: Fri, 27 May 2016 12:55:53 -0500 Subject: [PATCH] Added -x option to save SPIR-V as 32-bit hexadecimal numbers to a text file. --- SPIRV/GlslangToSpv.cpp | 25 ++++++++++++++++++++++++- SPIRV/GlslangToSpv.h | 3 ++- StandAlone/StandAlone.cpp | 26 ++++++++++++++++++++------ 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index d6ae9415..0ca7d6dd 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -49,8 +49,10 @@ namespace spv { #include "../glslang/MachineIndependent/localintermediate.h" #include "../glslang/MachineIndependent/SymbolTable.h" #include "../glslang/Include/Common.h" +#include "../glslang/Include/revision.h" #include +#include #include #include #include @@ -4311,7 +4313,7 @@ void GetSpirvVersion(std::string& version) } // Write SPIR-V out to a binary file -void OutputSpv(const std::vector& spirv, const char* baseName) +void OutputSpvBin(const std::vector& spirv, const char* baseName) { std::ofstream out; out.open(baseName, std::ios::binary | std::ios::out); @@ -4322,6 +4324,27 @@ void OutputSpv(const std::vector& spirv, const char* baseName) out.close(); } +// Write SPIR-V out to a text file with 32-bit hexadecimal words +void OutputSpvHex(const std::vector& spirv, const char* baseName) +{ + std::ofstream out; + out.open(baseName, std::ios::binary | std::ios::out); + out << "\t// " GLSLANG_REVISION " " GLSLANG_DATE << std::endl; + const int WORDS_PER_LINE = 8; + for (int i = 0; i < (int)spirv.size(); i += WORDS_PER_LINE) { + out << "\t"; + for (int j = 0; j < WORDS_PER_LINE && i + j < (int)spirv.size(); ++j) { + const unsigned int word = spirv[i + j]; + out << "0x" << std::hex << std::setw(8) << std::setfill('0') << word; + if (i + j + 1 < (int)spirv.size()) { + out << ","; + } + } + out << std::endl; + } + out.close(); +} + // // Set up the glslang traversal // diff --git a/SPIRV/GlslangToSpv.h b/SPIRV/GlslangToSpv.h index 8d006f38..97b280ca 100644 --- a/SPIRV/GlslangToSpv.h +++ b/SPIRV/GlslangToSpv.h @@ -44,6 +44,7 @@ namespace glslang { void GetSpirvVersion(std::string&); void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector& spirv); void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector& spirv, spv::SpvBuildLogger* logger); -void OutputSpv(const std::vector& spirv, const char* baseName); +void OutputSpvBin(const std::vector& spirv, const char* baseName); +void OutputSpvHex(const std::vector& spirv, const char* baseName); } diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index 3fd7e7d2..229d17db 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -75,7 +75,8 @@ enum TOptions { EOptionVulkanRules = 0x2000, EOptionDefaultDesktop = 0x4000, EOptionOutputPreprocessed = 0x8000, - EOptionReadHlsl = 0x10000, + EOptionOutputHexadecimal = 0x10000, + EOptionReadHlsl = 0x20000, }; // @@ -294,6 +295,15 @@ void ProcessArguments(int argc, char* argv[]) case 'w': Options |= EOptionSuppressWarnings; break; + case 'x': + Options |= EOptionOutputHexadecimal; + binaryFileName = argv[1]; + if (argc > 0) { + argc--; + argv++; + } else + Error("no provided for -x"); + break; default: usage(); break; @@ -311,7 +321,7 @@ void ProcessArguments(int argc, char* argv[]) if ((Options & EOptionOutputPreprocessed) && (Options & EOptionLinkProgram)) Error("can't use -E when linking is selected"); - // -o makes no sense if there is no target binary + // -o or -x makes no sense if there is no target binary if (binaryFileName && (Options & EOptionSpv) == 0) Error("no binary generation requested (e.g., -V)"); } @@ -480,8 +490,12 @@ void CompileAndLinkShaderUnits(std::vector compUnits) // Dump the spv to a file or stdout, etc., but only if not doing // memory/perf testing, as it's not internal to programmatic use. if (! (Options & EOptionMemoryLeakMode)) { - printf("%s", logger.getAllMessages().c_str()); - glslang::OutputSpv(spirv, GetBinaryName((EShLanguage)stage)); + printf("%s", logger.getAllMessages().c_str()); + if (Options & EOptionOutputHexadecimal) { + glslang::OutputSpvHex(spirv, GetBinaryName((EShLanguage)stage)); + } else { + glslang::OutputSpvBin(spirv, GetBinaryName((EShLanguage)stage)); + } if (Options & EOptionHumanReadableSpv) { spv::Disassemble(std::cout, spirv); } @@ -749,7 +763,6 @@ void usage() "Each option must be specified separately.\n" " -V create SPIR-V binary, under Vulkan semantics; turns on -l;\n" " default file name is .spv (-o overrides this)\n" - " (unless -o is specified, which overrides the default file name)\n" " -G create SPIR-V binary, under OpenGL semantics; turns on -l;\n" " default file name is .spv (-o overrides this)\n" " -H print human readable form of SPIR-V; turns on -V\n" @@ -765,13 +778,14 @@ void usage() " -i intermediate tree (glslang AST) is printed out\n" " -l link all input files together to form a single module\n" " -m memory leak mode\n" - " -o save binary into , requires a binary option (e.g., -V)\n" + " -o save binary to , requires a binary option (e.g., -V)\n" " -q dump reflection query database\n" " -r relaxed semantic error-checking mode\n" " -s silent mode\n" " -t multi-threaded mode\n" " -v print version strings\n" " -w suppress warnings (except as required by #extension : warn)\n" + " -x save 32-bit hex numbers as text to , requires a binary option (e.g., -V)\n" ); exit(EFailUsage);