Added -x option to save SPIR-V as 32-bit hexadecimal numbers to a text file.

This commit is contained in:
Johannes van Waveren 2016-05-27 12:55:53 -05:00
parent 5a7f0eff69
commit ecb0f3b75b
3 changed files with 46 additions and 8 deletions

View File

@ -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 <fstream>
#include <iomanip>
#include <list>
#include <map>
#include <stack>
@ -4311,7 +4313,7 @@ void GetSpirvVersion(std::string& version)
}
// Write SPIR-V out to a binary file
void OutputSpv(const std::vector<unsigned int>& spirv, const char* baseName)
void OutputSpvBin(const std::vector<unsigned int>& 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<unsigned int>& spirv, const char* baseName)
out.close();
}
// Write SPIR-V out to a text file with 32-bit hexadecimal words
void OutputSpvHex(const std::vector<unsigned int>& 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
//

View File

@ -44,6 +44,7 @@ namespace glslang {
void GetSpirvVersion(std::string&);
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv);
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, spv::SpvBuildLogger* logger);
void OutputSpv(const std::vector<unsigned int>& spirv, const char* baseName);
void OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName);
void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName);
}

View File

@ -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 <file> 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<ShaderCompUnit> 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 <stage>.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 <stage>.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 <file> save binary into <file>, requires a binary option (e.g., -V)\n"
" -o <file> save binary to <file>, 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 <file> save 32-bit hex numbers as text to <file>, requires a binary option (e.g., -V)\n"
);
exit(EFailUsage);