SPV: Add OpSource shader source code and file name.

This commit is contained in:
John Kessenich
2017-05-31 17:11:16 -06:00
parent 136b1e2d5d
commit 121853f4df
12 changed files with 243 additions and 22 deletions

View File

@@ -101,7 +101,7 @@ private:
//
class TGlslangToSpvTraverser : public glslang::TIntermTraverser {
public:
TGlslangToSpvTraverser(const glslang::TIntermediate*, spv::SpvBuildLogger* logger);
TGlslangToSpvTraverser(const glslang::TIntermediate*, spv::SpvBuildLogger* logger, glslang::SpvOptions& options);
virtual ~TGlslangToSpvTraverser() { }
bool visitAggregate(glslang::TVisit, glslang::TIntermAggregate*);
@@ -179,6 +179,7 @@ protected:
spv::Id createShortCircuit(glslang::TOperator, glslang::TIntermTyped& left, glslang::TIntermTyped& right);
spv::Id getExtBuiltins(const char* name);
glslang::SpvOptions& options;
spv::Function* shaderEntry;
spv::Function* currentFunction;
spv::Instruction* entryPoint;
@@ -851,8 +852,11 @@ bool HasNonLayoutQualifiers(const glslang::TType& type, const glslang::TQualifie
// Implement the TGlslangToSpvTraverser class.
//
TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* glslangIntermediate, spv::SpvBuildLogger* buildLogger)
: TIntermTraverser(true, false, true), shaderEntry(nullptr), currentFunction(nullptr),
TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* glslangIntermediate,
spv::SpvBuildLogger* buildLogger, glslang::SpvOptions& options)
: TIntermTraverser(true, false, true),
options(options),
shaderEntry(nullptr), currentFunction(nullptr),
sequenceDepth(0), logger(buildLogger),
builder((glslang::GetKhronosToolId() << 16) | GeneratorVersion, logger),
inEntryPoint(false), entryPointTerminated(false), linkageOnly(false),
@@ -862,6 +866,10 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* gls
builder.clearAccessChain();
builder.setSource(TranslateSourceLanguage(glslangIntermediate->getSource(), glslangIntermediate->getProfile()), glslangIntermediate->getVersion());
if (options.generateDebugInfo) {
builder.setSourceFile(glslangIntermediate->getSourceFile());
builder.setSourceText(glslangIntermediate->getSourceText());
}
stdBuiltins = builder.import("GLSL.std.450");
builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str());
@@ -5561,22 +5569,27 @@ void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName,
//
// Set up the glslang traversal
//
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv)
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, SpvOptions* options)
{
spv::SpvBuildLogger logger;
GlslangToSpv(intermediate, spirv, &logger);
GlslangToSpv(intermediate, spirv, &logger, options);
}
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, spv::SpvBuildLogger* logger)
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
spv::SpvBuildLogger* logger, SpvOptions* options)
{
TIntermNode* root = intermediate.getTreeRoot();
if (root == 0)
return;
glslang::SpvOptions defaultOptions;
if (options == nullptr)
options = &defaultOptions;
glslang::GetThreadPoolAllocator().push();
TGlslangToSpvTraverser it(&intermediate, logger);
TGlslangToSpvTraverser it(&intermediate, logger, *options);
root->traverse(&it);
it.finishSpv();
it.dumpSpv(spirv);

View File

@@ -47,9 +47,16 @@
namespace glslang {
struct SpvOptions {
SpvOptions() : generateDebugInfo(false) { }
bool generateDebugInfo;
};
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 GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
SpvOptions* options = nullptr);
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
spv::SpvBuildLogger* logger, SpvOptions* options = nullptr);
void OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName);
void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName);

View File

@@ -59,6 +59,7 @@ namespace spv {
Builder::Builder(unsigned int magicNumber, SpvBuildLogger* buildLogger) :
source(SourceLanguageUnknown),
sourceVersion(0),
sourceFileStringId(NoResult),
addressModel(AddressingModelLogical),
memoryModel(MemoryModelGLSL450),
builderNumber(magicNumber),
@@ -2411,12 +2412,8 @@ void Builder::dump(std::vector<unsigned int>& out) const
dumpInstructions(out, executionModes);
// Debug instructions
if (source != SourceLanguageUnknown) {
Instruction sourceInst(0, 0, OpSource);
sourceInst.addImmediateOperand(source);
sourceInst.addImmediateOperand(sourceVersion);
sourceInst.dump(out);
}
dumpInstructions(out, strings);
dumpSourceInstructions(out);
for (int e = 0; e < (int)sourceExtensions.size(); ++e) {
Instruction sourceExtInst(0, 0, OpSourceExtension);
sourceExtInst.addStringOperand(sourceExtensions[e]);
@@ -2574,6 +2571,48 @@ void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* els
elseBlock->addPredecessor(buildPoint);
}
// OpSource
// [OpSourceContinued]
// ...
void Builder::dumpSourceInstructions(std::vector<unsigned int>& out) const
{
const int maxWordCount = 0xFFFF;
const int opSourceWordCount = 4;
const int nonNullBytesPerInstruction = 4 * (maxWordCount - opSourceWordCount) - 1;
if (source != SourceLanguageUnknown) {
// OpSource Language Version File Source
Instruction sourceInst(NoResult, NoType, OpSource);
sourceInst.addImmediateOperand(source);
sourceInst.addImmediateOperand(sourceVersion);
// File operand
if (sourceFileStringId != NoResult) {
sourceInst.addIdOperand(sourceFileStringId);
// Source operand
if (sourceText.size() > 0) {
int nextByte = 0;
std::string subString;
while ((int)sourceText.size() - nextByte > 0) {
subString = sourceText.substr(nextByte, nonNullBytesPerInstruction);
if (nextByte == 0) {
// OpSource
sourceInst.addStringOperand(subString.c_str());
sourceInst.dump(out);
} else {
// OpSourcContinued
Instruction sourceContinuedInst(OpSourceContinued);
sourceContinuedInst.addStringOperand(subString.c_str());
sourceContinuedInst.dump(out);
}
nextByte += nonNullBytesPerInstruction;
}
} else
sourceInst.dump(out);
} else
sourceInst.dump(out);
}
}
void Builder::dumpInstructions(std::vector<unsigned int>& out, const std::vector<std::unique_ptr<Instruction> >& instructions) const
{
for (int i = 0; i < (int)instructions.size(); ++i) {

View File

@@ -70,6 +70,14 @@ public:
source = lang;
sourceVersion = version;
}
void setSourceFile(const std::string& file)
{
Instruction* fileString = new Instruction(getUniqueId(), NoType, OpString);
fileString->addStringOperand(file.c_str());
sourceFileStringId = fileString->getResultId();
strings.push_back(std::unique_ptr<Instruction>(fileString));
}
void setSourceText(const std::string& text) { sourceText = text; }
void addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); }
void addExtension(const char* ext) { extensions.insert(ext); }
Id import(const char*);
@@ -561,10 +569,13 @@ public:
void simplifyAccessChainSwizzle();
void createAndSetNoPredecessorBlock(const char*);
void createSelectionMerge(Block* mergeBlock, unsigned int control);
void dumpSourceInstructions(std::vector<unsigned int>&) const;
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
SourceLanguage source;
int sourceVersion;
spv::Id sourceFileStringId;
std::string sourceText;
std::set<std::string> extensions;
std::vector<const char*> sourceExtensions;
AddressingModel addressModel;
@@ -579,6 +590,7 @@ public:
AccessChain accessChain;
// special blocks of instructions for output
std::vector<std::unique_ptr<Instruction> > strings;
std::vector<std::unique_ptr<Instruction> > imports;
std::vector<std::unique_ptr<Instruction> > entryPoints;
std::vector<std::unique_ptr<Instruction> > executionModes;
@@ -599,7 +611,7 @@ public:
// Our loop stack.
std::stack<LoopBlocks> loops;
// The stream for outputing warnings and errors.
// The stream for outputting warnings and errors.
SpvBuildLogger* logger;
}; // end Builder class

View File

@@ -87,7 +87,6 @@ public:
void addImmediateOperand(unsigned int immediate) { operands.push_back(immediate); }
void addStringOperand(const char* str)
{
originalString = str;
unsigned int word;
char* wordString = (char*)&word;
char* wordPtr = wordString;
@@ -120,7 +119,6 @@ public:
Id getTypeId() const { return typeId; }
Id getIdOperand(int op) const { return operands[op]; }
unsigned int getImmediateOperand(int op) const { return operands[op]; }
const char* getStringOperand() const { return originalString.c_str(); }
// Write out the binary form.
void dump(std::vector<unsigned int>& out) const
@@ -151,7 +149,6 @@ protected:
Id typeId;
Op opCode;
std::vector<Id> operands;
std::string originalString; // could be optimized away; convenience for getting string operand
Block* block;
};