SPV: Add OpSource shader source code and file name.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user