From aea3c890d3caeff3f1538c8ae9e6b50d1fbe8626 Mon Sep 17 00:00:00 2001 From: Flavio Date: Mon, 6 Feb 2017 11:46:35 -0800 Subject: [PATCH 1/2] Added --vn option to generate a C header file containing a variable assigned to the hex representation of the shader. This is a standard feature on Microsoft's HLSL compiler and it allows developers to include pre-compiled shaders directly into the code. This option enables "Hex output", so it is NOT required to specify -x as well. The output file name is preserved, so no ".h" extension is added. If you want the output file to have ".h" extension then you have to specify it on the output file name. The generated header file uses the "#pragma once" pragma to avoid multiple inclusions. --- SPIRV/GlslangToSpv.cpp | 9 ++++++++- SPIRV/GlslangToSpv.h | 2 +- StandAlone/StandAlone.cpp | 20 ++++++++++++++++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 0b48dfcd..09566c90 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -5254,11 +5254,15 @@ void OutputSpvBin(const std::vector& spirv, const char* baseName) } // Write SPIR-V out to a text file with 32-bit hexadecimal words -void OutputSpvHex(const std::vector& spirv, const char* baseName) +void OutputSpvHex(const std::vector& spirv, const char* baseName, const char* varName) { std::ofstream out; out.open(baseName, std::ios::binary | std::ios::out); out << "\t// " GLSLANG_REVISION " " GLSLANG_DATE << std::endl; + if (varName != nullptr) { + out << "\t #pragma once" << std::endl; + out << "const uint32_t " << varName << "[] = {" << std::endl; + } const int WORDS_PER_LINE = 8; for (int i = 0; i < (int)spirv.size(); i += WORDS_PER_LINE) { out << "\t"; @@ -5271,6 +5275,9 @@ void OutputSpvHex(const std::vector& spirv, const char* baseName) } out << std::endl; } + if (varName != nullptr) { + out << "};"; + } out.close(); } diff --git a/SPIRV/GlslangToSpv.h b/SPIRV/GlslangToSpv.h index ceb23b5a..11e22f58 100644 --- a/SPIRV/GlslangToSpv.h +++ b/SPIRV/GlslangToSpv.h @@ -49,6 +49,6 @@ 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 OutputSpvBin(const std::vector& spirv, const char* baseName); -void OutputSpvHex(const std::vector& spirv, const char* baseName); +void OutputSpvHex(const std::vector& spirv, const char* baseName, const char* varName); } diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index d133b594..fb37f8f2 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -163,6 +163,7 @@ const char* binaryFileName = nullptr; const char* entryPointName = nullptr; const char* sourceEntryPointName = nullptr; const char* shaderStageName = nullptr; +const char* variableName = nullptr; std::array baseSamplerBinding; std::array baseTextureBinding; @@ -302,7 +303,20 @@ void ProcessArguments(int argc, char* argv[]) } else if (lowerword == "no-storage-format" || // synonyms lowerword == "nsf") { Options |= EOptionNoStorageFormat; - } else if (lowerword == "source-entrypoint" || // synonyms + } + else if (lowerword == "variable-name" || // synonyms + lowerword == "vn") { + Options |= EOptionOutputHexadecimal; + variableName = argv[1]; + if (argc > 0) { + argc--; + argv++; + } + else + Error("no provided for --variable-name"); + break; + } + else if (lowerword == "source-entrypoint" || // synonyms lowerword == "sep") { sourceEntryPointName = argv[1]; if (argc > 0) { @@ -650,7 +664,7 @@ void CompileAndLinkShaderUnits(std::vector compUnits) if (! (Options & EOptionMemoryLeakMode)) { printf("%s", logger.getAllMessages().c_str()); if (Options & EOptionOutputHexadecimal) { - glslang::OutputSpvHex(spirv, GetBinaryName((EShLanguage)stage)); + glslang::OutputSpvHex(spirv, GetBinaryName((EShLanguage)stage), variableName); } else { glslang::OutputSpvBin(spirv, GetBinaryName((EShLanguage)stage)); } @@ -987,6 +1001,8 @@ void usage() "\n" " --keep-uncalled don't eliminate uncalled functions when linking\n" " --ku synonym for --keep-uncalled\n" + " --variable-name Creates a C header file that contains a uint32_t array named initialized with the shader binary code.\n" + " --vn synonym for --variable-name .\n" ); exit(EFailUsage); From 15017db971e8bc4081d79100de5d9ab43908d7cc Mon Sep 17 00:00:00 2001 From: Flavio Date: Wed, 15 Feb 2017 14:29:33 -0800 Subject: [PATCH 2/2] Removed tabs and replaced with spaces. Changed layout for "else if" --- SPIRV/GlslangToSpv.cpp | 14 +++++++------- StandAlone/StandAlone.cpp | 26 ++++++++++++-------------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 09566c90..fcf35687 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -5259,10 +5259,10 @@ 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; - if (varName != nullptr) { - out << "\t #pragma once" << std::endl; - out << "const uint32_t " << varName << "[] = {" << std::endl; - } + if (varName != nullptr) { + out << "\t #pragma once" << std::endl; + out << "const uint32_t " << varName << "[] = {" << std::endl; + } const int WORDS_PER_LINE = 8; for (int i = 0; i < (int)spirv.size(); i += WORDS_PER_LINE) { out << "\t"; @@ -5275,9 +5275,9 @@ void OutputSpvHex(const std::vector& spirv, const char* baseName, } out << std::endl; } - if (varName != nullptr) { - out << "};"; - } + if (varName != nullptr) { + out << "};"; + } out.close(); } diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index fb37f8f2..26f4b6c7 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -303,20 +303,18 @@ void ProcessArguments(int argc, char* argv[]) } else if (lowerword == "no-storage-format" || // synonyms lowerword == "nsf") { Options |= EOptionNoStorageFormat; - } - else if (lowerword == "variable-name" || // synonyms - lowerword == "vn") { - Options |= EOptionOutputHexadecimal; - variableName = argv[1]; - if (argc > 0) { - argc--; - argv++; - } - else - Error("no provided for --variable-name"); - break; - } - else if (lowerword == "source-entrypoint" || // synonyms + } else if (lowerword == "variable-name" || // synonyms + lowerword == "vn") { + Options |= EOptionOutputHexadecimal; + variableName = argv[1]; + if (argc > 0) { + argc--; + argv++; + } else + Error("no provided for --variable-name"); + break; + } + else if (lowerword == "source-entrypoint" || // synonyms lowerword == "sep") { sourceEntryPointName = argv[1]; if (argc > 0) {