Merge pull request #911 from KhronosGroup/debug-info
SPV: Add OpSource shader source code and file name.
This commit is contained in:
commit
44d2728e3d
@ -101,7 +101,7 @@ private:
|
|||||||
//
|
//
|
||||||
class TGlslangToSpvTraverser : public glslang::TIntermTraverser {
|
class TGlslangToSpvTraverser : public glslang::TIntermTraverser {
|
||||||
public:
|
public:
|
||||||
TGlslangToSpvTraverser(const glslang::TIntermediate*, spv::SpvBuildLogger* logger);
|
TGlslangToSpvTraverser(const glslang::TIntermediate*, spv::SpvBuildLogger* logger, glslang::SpvOptions& options);
|
||||||
virtual ~TGlslangToSpvTraverser() { }
|
virtual ~TGlslangToSpvTraverser() { }
|
||||||
|
|
||||||
bool visitAggregate(glslang::TVisit, glslang::TIntermAggregate*);
|
bool visitAggregate(glslang::TVisit, glslang::TIntermAggregate*);
|
||||||
@ -179,6 +179,7 @@ protected:
|
|||||||
spv::Id createShortCircuit(glslang::TOperator, glslang::TIntermTyped& left, glslang::TIntermTyped& right);
|
spv::Id createShortCircuit(glslang::TOperator, glslang::TIntermTyped& left, glslang::TIntermTyped& right);
|
||||||
spv::Id getExtBuiltins(const char* name);
|
spv::Id getExtBuiltins(const char* name);
|
||||||
|
|
||||||
|
glslang::SpvOptions& options;
|
||||||
spv::Function* shaderEntry;
|
spv::Function* shaderEntry;
|
||||||
spv::Function* currentFunction;
|
spv::Function* currentFunction;
|
||||||
spv::Instruction* entryPoint;
|
spv::Instruction* entryPoint;
|
||||||
@ -851,8 +852,11 @@ bool HasNonLayoutQualifiers(const glslang::TType& type, const glslang::TQualifie
|
|||||||
// Implement the TGlslangToSpvTraverser class.
|
// Implement the TGlslangToSpvTraverser class.
|
||||||
//
|
//
|
||||||
|
|
||||||
TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* glslangIntermediate, spv::SpvBuildLogger* buildLogger)
|
TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* glslangIntermediate,
|
||||||
: TIntermTraverser(true, false, true), shaderEntry(nullptr), currentFunction(nullptr),
|
spv::SpvBuildLogger* buildLogger, glslang::SpvOptions& options)
|
||||||
|
: TIntermTraverser(true, false, true),
|
||||||
|
options(options),
|
||||||
|
shaderEntry(nullptr), currentFunction(nullptr),
|
||||||
sequenceDepth(0), logger(buildLogger),
|
sequenceDepth(0), logger(buildLogger),
|
||||||
builder((glslang::GetKhronosToolId() << 16) | GeneratorVersion, logger),
|
builder((glslang::GetKhronosToolId() << 16) | GeneratorVersion, logger),
|
||||||
inEntryPoint(false), entryPointTerminated(false), linkageOnly(false),
|
inEntryPoint(false), entryPointTerminated(false), linkageOnly(false),
|
||||||
@ -862,6 +866,11 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* gls
|
|||||||
|
|
||||||
builder.clearAccessChain();
|
builder.clearAccessChain();
|
||||||
builder.setSource(TranslateSourceLanguage(glslangIntermediate->getSource(), glslangIntermediate->getProfile()), glslangIntermediate->getVersion());
|
builder.setSource(TranslateSourceLanguage(glslangIntermediate->getSource(), glslangIntermediate->getProfile()), glslangIntermediate->getVersion());
|
||||||
|
if (options.generateDebugInfo) {
|
||||||
|
builder.setSourceFile(glslangIntermediate->getSourceFile());
|
||||||
|
builder.setSourceText(glslangIntermediate->getSourceText());
|
||||||
|
builder.setEmitOpLines();
|
||||||
|
}
|
||||||
stdBuiltins = builder.import("GLSL.std.450");
|
stdBuiltins = builder.import("GLSL.std.450");
|
||||||
builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
|
builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
|
||||||
shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str());
|
shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str());
|
||||||
@ -1069,6 +1078,8 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
|
|||||||
|
|
||||||
bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
|
bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
|
||||||
{
|
{
|
||||||
|
builder.setLine(node->getLoc().line);
|
||||||
|
|
||||||
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
|
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
|
||||||
if (node->getType().getQualifier().isSpecConstant())
|
if (node->getType().getQualifier().isSpecConstant())
|
||||||
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
|
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
|
||||||
@ -1256,6 +1267,8 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||||||
|
|
||||||
bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TIntermUnary* node)
|
bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TIntermUnary* node)
|
||||||
{
|
{
|
||||||
|
builder.setLine(node->getLoc().line);
|
||||||
|
|
||||||
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
|
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
|
||||||
if (node->getType().getQualifier().isSpecConstant())
|
if (node->getType().getQualifier().isSpecConstant())
|
||||||
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
|
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
|
||||||
@ -1499,6 +1512,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||||||
return false;
|
return false;
|
||||||
case glslang::EOpFunctionCall:
|
case glslang::EOpFunctionCall:
|
||||||
{
|
{
|
||||||
|
builder.setLine(node->getLoc().line);
|
||||||
if (node->isUserDefined())
|
if (node->isUserDefined())
|
||||||
result = handleUserFunctionCall(node);
|
result = handleUserFunctionCall(node);
|
||||||
// assert(result); // this can happen for bad shaders because the call graph completeness checking is not yet done
|
// assert(result); // this can happen for bad shaders because the call graph completeness checking is not yet done
|
||||||
@ -1605,6 +1619,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||||||
case glslang::EOpConstructStruct:
|
case glslang::EOpConstructStruct:
|
||||||
case glslang::EOpConstructTextureSampler:
|
case glslang::EOpConstructTextureSampler:
|
||||||
{
|
{
|
||||||
|
builder.setLine(node->getLoc().line);
|
||||||
std::vector<spv::Id> arguments;
|
std::vector<spv::Id> arguments;
|
||||||
translateArguments(*node, arguments);
|
translateArguments(*node, arguments);
|
||||||
spv::Id constructed;
|
spv::Id constructed;
|
||||||
@ -1715,6 +1730,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||||||
right->traverse(this);
|
right->traverse(this);
|
||||||
spv::Id rightId = accessChainLoad(right->getType());
|
spv::Id rightId = accessChainLoad(right->getType());
|
||||||
|
|
||||||
|
builder.setLine(node->getLoc().line);
|
||||||
result = createBinaryOperation(binOp, precision, TranslateNoContractionDecoration(node->getType().getQualifier()),
|
result = createBinaryOperation(binOp, precision, TranslateNoContractionDecoration(node->getType().getQualifier()),
|
||||||
resultType(), leftId, rightId,
|
resultType(), leftId, rightId,
|
||||||
left->getType().getBasicType(), reduceComparison);
|
left->getType().getBasicType(), reduceComparison);
|
||||||
@ -1787,10 +1803,13 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||||||
glslangOperands[arg]->traverse(this);
|
glslangOperands[arg]->traverse(this);
|
||||||
if (lvalue)
|
if (lvalue)
|
||||||
operands.push_back(builder.accessChainGetLValue());
|
operands.push_back(builder.accessChainGetLValue());
|
||||||
else
|
else {
|
||||||
|
builder.setLine(node->getLoc().line);
|
||||||
operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
|
operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
builder.setLine(node->getLoc().line);
|
||||||
if (atomic) {
|
if (atomic) {
|
||||||
// Handle all atomics
|
// Handle all atomics
|
||||||
result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType());
|
result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType());
|
||||||
@ -1872,6 +1891,8 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
|||||||
node->getFalseBlock()->traverse(this);
|
node->getFalseBlock()->traverse(this);
|
||||||
spv::Id falseValue = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType());
|
spv::Id falseValue = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType());
|
||||||
|
|
||||||
|
builder.setLine(node->getLoc().line);
|
||||||
|
|
||||||
// smear condition to vector, if necessary (AST is always scalar)
|
// smear condition to vector, if necessary (AST is always scalar)
|
||||||
if (builder.isVector(trueValue))
|
if (builder.isVector(trueValue))
|
||||||
condition = builder.smearScalar(spv::NoPrecision, condition,
|
condition = builder.smearScalar(spv::NoPrecision, condition,
|
||||||
@ -2014,6 +2035,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
|
|||||||
// by a block-ending branch. But we don't want to put any other body/test
|
// by a block-ending branch. But we don't want to put any other body/test
|
||||||
// instructions in it, since the body/test may have arbitrary instructions,
|
// instructions in it, since the body/test may have arbitrary instructions,
|
||||||
// including merges of its own.
|
// including merges of its own.
|
||||||
|
builder.setLine(node->getLoc().line);
|
||||||
builder.setBuildPoint(&blocks.head);
|
builder.setBuildPoint(&blocks.head);
|
||||||
builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control);
|
builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control);
|
||||||
if (node->testFirst() && node->getTest()) {
|
if (node->testFirst() && node->getTest()) {
|
||||||
@ -2022,8 +2044,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
|
|||||||
|
|
||||||
builder.setBuildPoint(&test);
|
builder.setBuildPoint(&test);
|
||||||
node->getTest()->traverse(this);
|
node->getTest()->traverse(this);
|
||||||
spv::Id condition =
|
spv::Id condition = accessChainLoad(node->getTest()->getType());
|
||||||
accessChainLoad(node->getTest()->getType());
|
|
||||||
builder.createConditionalBranch(condition, &blocks.body, &blocks.merge);
|
builder.createConditionalBranch(condition, &blocks.body, &blocks.merge);
|
||||||
|
|
||||||
builder.setBuildPoint(&blocks.body);
|
builder.setBuildPoint(&blocks.body);
|
||||||
@ -2038,6 +2059,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
|
|||||||
node->getTerminal()->traverse(this);
|
node->getTerminal()->traverse(this);
|
||||||
builder.createBranch(&blocks.head);
|
builder.createBranch(&blocks.head);
|
||||||
} else {
|
} else {
|
||||||
|
builder.setLine(node->getLoc().line);
|
||||||
builder.createBranch(&blocks.body);
|
builder.createBranch(&blocks.body);
|
||||||
|
|
||||||
breakForLoop.push(true);
|
breakForLoop.push(true);
|
||||||
@ -2072,6 +2094,8 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
|
|||||||
if (node->getExpression())
|
if (node->getExpression())
|
||||||
node->getExpression()->traverse(this);
|
node->getExpression()->traverse(this);
|
||||||
|
|
||||||
|
builder.setLine(node->getLoc().line);
|
||||||
|
|
||||||
switch (node->getFlowOp()) {
|
switch (node->getFlowOp()) {
|
||||||
case glslang::EOpKill:
|
case glslang::EOpKill:
|
||||||
builder.makeDiscard();
|
builder.makeDiscard();
|
||||||
@ -3049,9 +3073,11 @@ void TGlslangToSpvTraverser::translateArguments(glslang::TIntermUnary& node, std
|
|||||||
|
|
||||||
spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermOperator* node)
|
spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermOperator* node)
|
||||||
{
|
{
|
||||||
if (! node->isImage() && ! node->isTexture()) {
|
if (! node->isImage() && ! node->isTexture())
|
||||||
return spv::NoResult;
|
return spv::NoResult;
|
||||||
}
|
|
||||||
|
builder.setLine(node->getLoc().line);
|
||||||
|
|
||||||
auto resultType = [&node,this]{ return convertGlslangToSpvType(node->getType()); };
|
auto resultType = [&node,this]{ return convertGlslangToSpvType(node->getType()); };
|
||||||
|
|
||||||
// Process a GLSL texturing op (will be SPV image)
|
// Process a GLSL texturing op (will be SPV image)
|
||||||
@ -5561,22 +5587,27 @@ void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName,
|
|||||||
//
|
//
|
||||||
// Set up the glslang traversal
|
// 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;
|
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();
|
TIntermNode* root = intermediate.getTreeRoot();
|
||||||
|
|
||||||
if (root == 0)
|
if (root == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
glslang::SpvOptions defaultOptions;
|
||||||
|
if (options == nullptr)
|
||||||
|
options = &defaultOptions;
|
||||||
|
|
||||||
glslang::GetThreadPoolAllocator().push();
|
glslang::GetThreadPoolAllocator().push();
|
||||||
|
|
||||||
TGlslangToSpvTraverser it(&intermediate, logger);
|
TGlslangToSpvTraverser it(&intermediate, logger, *options);
|
||||||
root->traverse(&it);
|
root->traverse(&it);
|
||||||
it.finishSpv();
|
it.finishSpv();
|
||||||
it.dumpSpv(spirv);
|
it.dumpSpv(spirv);
|
||||||
|
|||||||
@ -47,9 +47,16 @@
|
|||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
|
struct SpvOptions {
|
||||||
|
SpvOptions() : generateDebugInfo(false) { }
|
||||||
|
bool generateDebugInfo;
|
||||||
|
};
|
||||||
|
|
||||||
void GetSpirvVersion(std::string&);
|
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,
|
||||||
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, spv::SpvBuildLogger* logger);
|
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 OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName);
|
||||||
void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName);
|
void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName);
|
||||||
|
|
||||||
|
|||||||
@ -59,6 +59,9 @@ namespace spv {
|
|||||||
Builder::Builder(unsigned int magicNumber, SpvBuildLogger* buildLogger) :
|
Builder::Builder(unsigned int magicNumber, SpvBuildLogger* buildLogger) :
|
||||||
source(SourceLanguageUnknown),
|
source(SourceLanguageUnknown),
|
||||||
sourceVersion(0),
|
sourceVersion(0),
|
||||||
|
sourceFileStringId(NoResult),
|
||||||
|
currentLine(0),
|
||||||
|
emitOpLines(false),
|
||||||
addressModel(AddressingModelLogical),
|
addressModel(AddressingModelLogical),
|
||||||
memoryModel(MemoryModelGLSL450),
|
memoryModel(MemoryModelGLSL450),
|
||||||
builderNumber(magicNumber),
|
builderNumber(magicNumber),
|
||||||
@ -84,6 +87,26 @@ Id Builder::import(const char* name)
|
|||||||
return import->getResultId();
|
return import->getResultId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emit an OpLine if we've been asked to emit OpLines and the line number
|
||||||
|
// has changed since the last time, and is a valid line number.
|
||||||
|
void Builder::setLine(int lineNum)
|
||||||
|
{
|
||||||
|
if (lineNum != 0 && lineNum != currentLine) {
|
||||||
|
currentLine = lineNum;
|
||||||
|
if (emitOpLines)
|
||||||
|
addLine(sourceFileStringId, currentLine, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Builder::addLine(Id fileName, int lineNum, int column)
|
||||||
|
{
|
||||||
|
Instruction* line = new Instruction(OpLine);
|
||||||
|
line->addIdOperand(fileName);
|
||||||
|
line->addImmediateOperand(lineNum);
|
||||||
|
line->addImmediateOperand(column);
|
||||||
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(line));
|
||||||
|
}
|
||||||
|
|
||||||
// For creating new groupedTypes (will return old type if the requested one was already made).
|
// For creating new groupedTypes (will return old type if the requested one was already made).
|
||||||
Id Builder::makeVoidType()
|
Id Builder::makeVoidType()
|
||||||
{
|
{
|
||||||
@ -928,17 +951,6 @@ void Builder::addMemberName(Id id, int memberNumber, const char* string)
|
|||||||
names.push_back(std::unique_ptr<Instruction>(name));
|
names.push_back(std::unique_ptr<Instruction>(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::addLine(Id target, Id fileName, int lineNum, int column)
|
|
||||||
{
|
|
||||||
Instruction* line = new Instruction(OpLine);
|
|
||||||
line->addIdOperand(target);
|
|
||||||
line->addIdOperand(fileName);
|
|
||||||
line->addImmediateOperand(lineNum);
|
|
||||||
line->addImmediateOperand(column);
|
|
||||||
|
|
||||||
lines.push_back(std::unique_ptr<Instruction>(line));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Builder::addDecoration(Id id, Decoration decoration, int num)
|
void Builder::addDecoration(Id id, Decoration decoration, int num)
|
||||||
{
|
{
|
||||||
if (decoration == spv::DecorationMax)
|
if (decoration == spv::DecorationMax)
|
||||||
@ -2411,12 +2423,8 @@ void Builder::dump(std::vector<unsigned int>& out) const
|
|||||||
dumpInstructions(out, executionModes);
|
dumpInstructions(out, executionModes);
|
||||||
|
|
||||||
// Debug instructions
|
// Debug instructions
|
||||||
if (source != SourceLanguageUnknown) {
|
dumpInstructions(out, strings);
|
||||||
Instruction sourceInst(0, 0, OpSource);
|
dumpSourceInstructions(out);
|
||||||
sourceInst.addImmediateOperand(source);
|
|
||||||
sourceInst.addImmediateOperand(sourceVersion);
|
|
||||||
sourceInst.dump(out);
|
|
||||||
}
|
|
||||||
for (int e = 0; e < (int)sourceExtensions.size(); ++e) {
|
for (int e = 0; e < (int)sourceExtensions.size(); ++e) {
|
||||||
Instruction sourceExtInst(0, 0, OpSourceExtension);
|
Instruction sourceExtInst(0, 0, OpSourceExtension);
|
||||||
sourceExtInst.addStringOperand(sourceExtensions[e]);
|
sourceExtInst.addStringOperand(sourceExtensions[e]);
|
||||||
@ -2574,6 +2582,48 @@ void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* els
|
|||||||
elseBlock->addPredecessor(buildPoint);
|
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
|
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) {
|
for (int i = 0; i < (int)instructions.size(); ++i) {
|
||||||
|
|||||||
@ -70,7 +70,16 @@ public:
|
|||||||
source = lang;
|
source = lang;
|
||||||
sourceVersion = version;
|
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 addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); }
|
||||||
|
void setEmitOpLines() { emitOpLines = true; }
|
||||||
void addExtension(const char* ext) { extensions.insert(ext); }
|
void addExtension(const char* ext) { extensions.insert(ext); }
|
||||||
Id import(const char*);
|
Id import(const char*);
|
||||||
void setMemoryModel(spv::AddressingModel addr, spv::MemoryModel mem)
|
void setMemoryModel(spv::AddressingModel addr, spv::MemoryModel mem)
|
||||||
@ -92,6 +101,12 @@ public:
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log the current line, and if different than the last one,
|
||||||
|
// issue a new OpLine, using the current file name.
|
||||||
|
void setLine(int line);
|
||||||
|
// Low-level OpLine. See setLine() for a layered helper.
|
||||||
|
void addLine(Id fileName, int line, int column);
|
||||||
|
|
||||||
// For creating new types (will return old type if the requested one was already made).
|
// For creating new types (will return old type if the requested one was already made).
|
||||||
Id makeVoidType();
|
Id makeVoidType();
|
||||||
Id makeBoolType();
|
Id makeBoolType();
|
||||||
@ -213,7 +228,6 @@ public:
|
|||||||
void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1);
|
void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1);
|
||||||
void addName(Id, const char* name);
|
void addName(Id, const char* name);
|
||||||
void addMemberName(Id, int member, const char* name);
|
void addMemberName(Id, int member, const char* name);
|
||||||
void addLine(Id target, Id fileName, int line, int column);
|
|
||||||
void addDecoration(Id, Decoration, int num = -1);
|
void addDecoration(Id, Decoration, int num = -1);
|
||||||
void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
|
void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
|
||||||
|
|
||||||
@ -561,10 +575,15 @@ public:
|
|||||||
void simplifyAccessChainSwizzle();
|
void simplifyAccessChainSwizzle();
|
||||||
void createAndSetNoPredecessorBlock(const char*);
|
void createAndSetNoPredecessorBlock(const char*);
|
||||||
void createSelectionMerge(Block* mergeBlock, unsigned int control);
|
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;
|
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
|
||||||
|
|
||||||
SourceLanguage source;
|
SourceLanguage source;
|
||||||
int sourceVersion;
|
int sourceVersion;
|
||||||
|
spv::Id sourceFileStringId;
|
||||||
|
std::string sourceText;
|
||||||
|
int currentLine;
|
||||||
|
bool emitOpLines;
|
||||||
std::set<std::string> extensions;
|
std::set<std::string> extensions;
|
||||||
std::vector<const char*> sourceExtensions;
|
std::vector<const char*> sourceExtensions;
|
||||||
AddressingModel addressModel;
|
AddressingModel addressModel;
|
||||||
@ -579,6 +598,7 @@ public:
|
|||||||
AccessChain accessChain;
|
AccessChain accessChain;
|
||||||
|
|
||||||
// special blocks of instructions for output
|
// 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> > imports;
|
||||||
std::vector<std::unique_ptr<Instruction> > entryPoints;
|
std::vector<std::unique_ptr<Instruction> > entryPoints;
|
||||||
std::vector<std::unique_ptr<Instruction> > executionModes;
|
std::vector<std::unique_ptr<Instruction> > executionModes;
|
||||||
@ -599,7 +619,7 @@ public:
|
|||||||
// Our loop stack.
|
// Our loop stack.
|
||||||
std::stack<LoopBlocks> loops;
|
std::stack<LoopBlocks> loops;
|
||||||
|
|
||||||
// The stream for outputing warnings and errors.
|
// The stream for outputting warnings and errors.
|
||||||
SpvBuildLogger* logger;
|
SpvBuildLogger* logger;
|
||||||
}; // end Builder class
|
}; // end Builder class
|
||||||
|
|
||||||
|
|||||||
@ -87,7 +87,6 @@ public:
|
|||||||
void addImmediateOperand(unsigned int immediate) { operands.push_back(immediate); }
|
void addImmediateOperand(unsigned int immediate) { operands.push_back(immediate); }
|
||||||
void addStringOperand(const char* str)
|
void addStringOperand(const char* str)
|
||||||
{
|
{
|
||||||
originalString = str;
|
|
||||||
unsigned int word;
|
unsigned int word;
|
||||||
char* wordString = (char*)&word;
|
char* wordString = (char*)&word;
|
||||||
char* wordPtr = wordString;
|
char* wordPtr = wordString;
|
||||||
@ -120,7 +119,6 @@ public:
|
|||||||
Id getTypeId() const { return typeId; }
|
Id getTypeId() const { return typeId; }
|
||||||
Id getIdOperand(int op) const { return operands[op]; }
|
Id getIdOperand(int op) const { return operands[op]; }
|
||||||
unsigned int getImmediateOperand(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.
|
// Write out the binary form.
|
||||||
void dump(std::vector<unsigned int>& out) const
|
void dump(std::vector<unsigned int>& out) const
|
||||||
@ -151,7 +149,6 @@ protected:
|
|||||||
Id typeId;
|
Id typeId;
|
||||||
Op opCode;
|
Op opCode;
|
||||||
std::vector<Id> operands;
|
std::vector<Id> operands;
|
||||||
std::string originalString; // could be optimized away; convenience for getting string operand
|
|
||||||
Block* block;
|
Block* block;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -91,6 +91,7 @@ enum TOptions {
|
|||||||
EOptionHlslOffsets = (1 << 23),
|
EOptionHlslOffsets = (1 << 23),
|
||||||
EOptionHlslIoMapping = (1 << 24),
|
EOptionHlslIoMapping = (1 << 24),
|
||||||
EOptionAutoMapLocations = (1 << 25),
|
EOptionAutoMapLocations = (1 << 25),
|
||||||
|
EOptionDebug = (1 << 26),
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -448,6 +449,9 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
|||||||
} else
|
} else
|
||||||
Error("no <entry-point> provided for -e");
|
Error("no <entry-point> provided for -e");
|
||||||
break;
|
break;
|
||||||
|
case 'g':
|
||||||
|
Options |= EOptionDebug;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
usage();
|
usage();
|
||||||
break;
|
break;
|
||||||
@ -539,6 +543,8 @@ void SetMessageOptions(EShMessages& messages)
|
|||||||
messages = (EShMessages)(messages | EShMsgKeepUncalled);
|
messages = (EShMessages)(messages | EShMsgKeepUncalled);
|
||||||
if (Options & EOptionHlslOffsets)
|
if (Options & EOptionHlslOffsets)
|
||||||
messages = (EShMessages)(messages | EShMsgHlslOffsets);
|
messages = (EShMessages)(messages | EShMsgHlslOffsets);
|
||||||
|
if (Options & EOptionDebug)
|
||||||
|
messages = (EShMessages)(messages | EShMsgDebugInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -722,7 +728,10 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
|||||||
std::vector<unsigned int> spirv;
|
std::vector<unsigned int> spirv;
|
||||||
std::string warningsErrors;
|
std::string warningsErrors;
|
||||||
spv::SpvBuildLogger logger;
|
spv::SpvBuildLogger logger;
|
||||||
glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), spirv, &logger);
|
glslang::SpvOptions spvOptions;
|
||||||
|
if (Options & EOptionDebug)
|
||||||
|
spvOptions.generateDebugInfo = true;
|
||||||
|
glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), spirv, &logger, &spvOptions);
|
||||||
|
|
||||||
// Dump the spv to a file or stdout, etc., but only if not doing
|
// 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.
|
// memory/perf testing, as it's not internal to programmatic use.
|
||||||
@ -1031,6 +1040,7 @@ void usage()
|
|||||||
" (default is ES version 100)\n"
|
" (default is ES version 100)\n"
|
||||||
" -D input is HLSL\n"
|
" -D input is HLSL\n"
|
||||||
" -e specify entry-point name\n"
|
" -e specify entry-point name\n"
|
||||||
|
" -g generate debug information\n"
|
||||||
" -h print this usage message\n"
|
" -h print this usage message\n"
|
||||||
" -i intermediate tree (glslang AST) is printed out\n"
|
" -i intermediate tree (glslang AST) is printed out\n"
|
||||||
" -l link all input files together to form a single module\n"
|
" -l link all input files together to form a single module\n"
|
||||||
|
|||||||
272
Test/baseResults/spv.debugInfo.frag.out
Normal file
272
Test/baseResults/spv.debugInfo.frag.out
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
spv.debugInfo.frag
|
||||||
|
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
|
||||||
|
|
||||||
|
// Module Version 10000
|
||||||
|
// Generated by (magic number): 80001
|
||||||
|
// Id's are bound by 126
|
||||||
|
|
||||||
|
Capability Shader
|
||||||
|
2: ExtInstImport "GLSL.std.450"
|
||||||
|
MemoryModel Logical GLSL450
|
||||||
|
EntryPoint Fragment 5 "main" 24 52
|
||||||
|
ExecutionMode 5 OriginUpperLeft
|
||||||
|
1: String "spv.debugInfo.frag"
|
||||||
|
Source GLSL 450 1 "#version 450
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
int a;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform ubuf {
|
||||||
|
S s;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform sampler2D s2d;
|
||||||
|
|
||||||
|
layout(location = 0) in vec4 inv;
|
||||||
|
layout(location = 0) out vec4 outv;
|
||||||
|
|
||||||
|
vec4 foo(S s)
|
||||||
|
{
|
||||||
|
vec4 r = s.a * inv;
|
||||||
|
++r;
|
||||||
|
if (r.x > 3.0)
|
||||||
|
--r;
|
||||||
|
else
|
||||||
|
r *= 2;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
outv = foo(s);
|
||||||
|
outv += texture(s2d, vec2(0.5));
|
||||||
|
|
||||||
|
switch (s.a) {
|
||||||
|
case 10:
|
||||||
|
++outv;
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
outv = 2 * outv;
|
||||||
|
++outv;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
--outv;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
outv *= 3.0;
|
||||||
|
|
||||||
|
outv.x < 10.0 ?
|
||||||
|
outv = sin(outv) :
|
||||||
|
outv = cos(outv);
|
||||||
|
}"
|
||||||
|
Name 5 "main"
|
||||||
|
Name 8 "S"
|
||||||
|
MemberName 8(S) 0 "a"
|
||||||
|
Name 14 "foo(struct-S-i11;"
|
||||||
|
Name 13 "s"
|
||||||
|
Name 17 "r"
|
||||||
|
Name 24 "inv"
|
||||||
|
Name 52 "outv"
|
||||||
|
Name 53 "S"
|
||||||
|
MemberName 53(S) 0 "a"
|
||||||
|
Name 54 "ubuf"
|
||||||
|
MemberName 54(ubuf) 0 "s"
|
||||||
|
Name 56 ""
|
||||||
|
Name 57 "S"
|
||||||
|
MemberName 57(S) 0 "a"
|
||||||
|
Name 59 "param"
|
||||||
|
Name 69 "s2d"
|
||||||
|
Name 99 "i"
|
||||||
|
Decorate 24(inv) Location 0
|
||||||
|
Decorate 52(outv) Location 0
|
||||||
|
MemberDecorate 53(S) 0 Offset 0
|
||||||
|
MemberDecorate 54(ubuf) 0 Offset 0
|
||||||
|
Decorate 54(ubuf) Block
|
||||||
|
Decorate 56 DescriptorSet 0
|
||||||
|
Decorate 69(s2d) DescriptorSet 0
|
||||||
|
3: TypeVoid
|
||||||
|
4: TypeFunction 3
|
||||||
|
7: TypeInt 32 1
|
||||||
|
8(S): TypeStruct 7(int)
|
||||||
|
9: TypePointer Function 8(S)
|
||||||
|
10: TypeFloat 32
|
||||||
|
11: TypeVector 10(float) 4
|
||||||
|
12: TypeFunction 11(fvec4) 9(ptr)
|
||||||
|
16: TypePointer Function 11(fvec4)
|
||||||
|
18: 7(int) Constant 0
|
||||||
|
19: TypePointer Function 7(int)
|
||||||
|
23: TypePointer Input 11(fvec4)
|
||||||
|
24(inv): 23(ptr) Variable Input
|
||||||
|
28: 10(float) Constant 1065353216
|
||||||
|
31: TypeInt 32 0
|
||||||
|
32: 31(int) Constant 0
|
||||||
|
33: TypePointer Function 10(float)
|
||||||
|
36: 10(float) Constant 1077936128
|
||||||
|
37: TypeBool
|
||||||
|
45: 10(float) Constant 1073741824
|
||||||
|
51: TypePointer Output 11(fvec4)
|
||||||
|
52(outv): 51(ptr) Variable Output
|
||||||
|
53(S): TypeStruct 7(int)
|
||||||
|
54(ubuf): TypeStruct 53(S)
|
||||||
|
55: TypePointer Uniform 54(ubuf)
|
||||||
|
56: 55(ptr) Variable Uniform
|
||||||
|
57(S): TypeStruct 7(int)
|
||||||
|
58: TypePointer Function 57(S)
|
||||||
|
60: TypePointer Uniform 53(S)
|
||||||
|
66: TypeImage 10(float) 2D sampled format:Unknown
|
||||||
|
67: TypeSampledImage 66
|
||||||
|
68: TypePointer UniformConstant 67
|
||||||
|
69(s2d): 68(ptr) Variable UniformConstant
|
||||||
|
71: TypeVector 10(float) 2
|
||||||
|
72: 10(float) Constant 1056964608
|
||||||
|
73: 71(fvec2) ConstantComposite 72 72
|
||||||
|
77: TypePointer Uniform 7(int)
|
||||||
|
106: 7(int) Constant 10
|
||||||
|
111: 7(int) Constant 1
|
||||||
|
114: TypePointer Output 10(float)
|
||||||
|
117: 10(float) Constant 1092616192
|
||||||
|
5(main): 3 Function None 4
|
||||||
|
6: Label
|
||||||
|
59(param): 58(ptr) Variable Function
|
||||||
|
99(i): 19(ptr) Variable Function
|
||||||
|
113: 16(ptr) Variable Function
|
||||||
|
Line 1 30 0
|
||||||
|
61: 60(ptr) AccessChain 56 18
|
||||||
|
62: 53(S) Load 61
|
||||||
|
63: 7(int) CompositeExtract 62 0
|
||||||
|
64: 19(ptr) AccessChain 59(param) 18
|
||||||
|
Store 64 63
|
||||||
|
65: 11(fvec4) FunctionCall 14(foo(struct-S-i11;) 59(param)
|
||||||
|
Store 52(outv) 65
|
||||||
|
Line 1 31 0
|
||||||
|
70: 67 Load 69(s2d)
|
||||||
|
74: 11(fvec4) ImageSampleImplicitLod 70 73
|
||||||
|
75: 11(fvec4) Load 52(outv)
|
||||||
|
76: 11(fvec4) FAdd 75 74
|
||||||
|
Store 52(outv) 76
|
||||||
|
Line 1 33 0
|
||||||
|
78: 77(ptr) AccessChain 56 18 18
|
||||||
|
79: 7(int) Load 78
|
||||||
|
SelectionMerge 83 None
|
||||||
|
Switch 79 82
|
||||||
|
case 10: 80
|
||||||
|
case 20: 81
|
||||||
|
82: Label
|
||||||
|
Line 1 42 0
|
||||||
|
94: 11(fvec4) Load 52(outv)
|
||||||
|
95: 11(fvec4) CompositeConstruct 28 28 28 28
|
||||||
|
96: 11(fvec4) FSub 94 95
|
||||||
|
Store 52(outv) 96
|
||||||
|
Line 1 43 0
|
||||||
|
Branch 83
|
||||||
|
80: Label
|
||||||
|
Line 1 35 0
|
||||||
|
84: 11(fvec4) Load 52(outv)
|
||||||
|
85: 11(fvec4) CompositeConstruct 28 28 28 28
|
||||||
|
86: 11(fvec4) FAdd 84 85
|
||||||
|
Store 52(outv) 86
|
||||||
|
Line 1 36 0
|
||||||
|
Branch 83
|
||||||
|
81: Label
|
||||||
|
Line 1 38 0
|
||||||
|
88: 11(fvec4) Load 52(outv)
|
||||||
|
89: 11(fvec4) VectorTimesScalar 88 45
|
||||||
|
Store 52(outv) 89
|
||||||
|
Line 1 39 0
|
||||||
|
90: 11(fvec4) Load 52(outv)
|
||||||
|
91: 11(fvec4) CompositeConstruct 28 28 28 28
|
||||||
|
92: 11(fvec4) FAdd 90 91
|
||||||
|
Store 52(outv) 92
|
||||||
|
Line 1 40 0
|
||||||
|
Branch 83
|
||||||
|
83: Label
|
||||||
|
Line 1 46 0
|
||||||
|
Store 99(i) 18
|
||||||
|
Branch 100
|
||||||
|
100: Label
|
||||||
|
LoopMerge 102 103 None
|
||||||
|
Branch 104
|
||||||
|
104: Label
|
||||||
|
105: 7(int) Load 99(i)
|
||||||
|
107: 37(bool) SLessThan 105 106
|
||||||
|
BranchConditional 107 101 102
|
||||||
|
101: Label
|
||||||
|
Line 1 47 0
|
||||||
|
108: 11(fvec4) Load 52(outv)
|
||||||
|
109: 11(fvec4) VectorTimesScalar 108 36
|
||||||
|
Store 52(outv) 109
|
||||||
|
Branch 103
|
||||||
|
103: Label
|
||||||
|
Line 1 46 0
|
||||||
|
110: 7(int) Load 99(i)
|
||||||
|
112: 7(int) IAdd 110 111
|
||||||
|
Store 99(i) 112
|
||||||
|
Branch 100
|
||||||
|
102: Label
|
||||||
|
Line 1 49 0
|
||||||
|
115: 114(ptr) AccessChain 52(outv) 32
|
||||||
|
116: 10(float) Load 115
|
||||||
|
118: 37(bool) FOrdLessThan 116 117
|
||||||
|
SelectionMerge 120 None
|
||||||
|
BranchConditional 118 119 123
|
||||||
|
119: Label
|
||||||
|
Line 1 50 0
|
||||||
|
121: 11(fvec4) Load 52(outv)
|
||||||
|
122: 11(fvec4) ExtInst 2(GLSL.std.450) 13(Sin) 121
|
||||||
|
Store 52(outv) 122
|
||||||
|
Store 113 122
|
||||||
|
Branch 120
|
||||||
|
123: Label
|
||||||
|
Line 1 51 0
|
||||||
|
124: 11(fvec4) Load 52(outv)
|
||||||
|
125: 11(fvec4) ExtInst 2(GLSL.std.450) 14(Cos) 124
|
||||||
|
Store 52(outv) 125
|
||||||
|
Store 113 125
|
||||||
|
Branch 120
|
||||||
|
120: Label
|
||||||
|
Return
|
||||||
|
FunctionEnd
|
||||||
|
14(foo(struct-S-i11;): 11(fvec4) Function None 12
|
||||||
|
13(s): 9(ptr) FunctionParameter
|
||||||
|
15: Label
|
||||||
|
17(r): 16(ptr) Variable Function
|
||||||
|
Line 1 18 0
|
||||||
|
20: 19(ptr) AccessChain 13(s) 18
|
||||||
|
21: 7(int) Load 20
|
||||||
|
22: 10(float) ConvertSToF 21
|
||||||
|
25: 11(fvec4) Load 24(inv)
|
||||||
|
26: 11(fvec4) VectorTimesScalar 25 22
|
||||||
|
Store 17(r) 26
|
||||||
|
Line 1 19 0
|
||||||
|
27: 11(fvec4) Load 17(r)
|
||||||
|
29: 11(fvec4) CompositeConstruct 28 28 28 28
|
||||||
|
30: 11(fvec4) FAdd 27 29
|
||||||
|
Store 17(r) 30
|
||||||
|
Line 1 20 0
|
||||||
|
34: 33(ptr) AccessChain 17(r) 32
|
||||||
|
35: 10(float) Load 34
|
||||||
|
38: 37(bool) FOrdGreaterThan 35 36
|
||||||
|
SelectionMerge 40 None
|
||||||
|
BranchConditional 38 39 44
|
||||||
|
39: Label
|
||||||
|
Line 1 21 0
|
||||||
|
41: 11(fvec4) Load 17(r)
|
||||||
|
42: 11(fvec4) CompositeConstruct 28 28 28 28
|
||||||
|
43: 11(fvec4) FSub 41 42
|
||||||
|
Store 17(r) 43
|
||||||
|
Branch 40
|
||||||
|
44: Label
|
||||||
|
Line 1 23 0
|
||||||
|
46: 11(fvec4) Load 17(r)
|
||||||
|
47: 11(fvec4) VectorTimesScalar 46 45
|
||||||
|
Store 17(r) 47
|
||||||
|
Branch 40
|
||||||
|
40: Label
|
||||||
|
Line 1 25 0
|
||||||
|
48: 11(fvec4) Load 17(r)
|
||||||
|
ReturnValue 48
|
||||||
|
FunctionEnd
|
||||||
@ -90,14 +90,21 @@ diff -b $BASEDIR/hlsl.hlslOffset.vert.out $TARGETDIR/hlsl.hlslOffset.vert.out ||
|
|||||||
#
|
#
|
||||||
echo Configuring HLSL descriptor set and binding number manually
|
echo Configuring HLSL descriptor set and binding number manually
|
||||||
$EXE -V -D -e main -H hlsl.multiDescriptorSet.frag --rsb frag t0 0 0 t1 1 0 s0 0 1 s1 1 1 b0 2 0 b1 2 1 b2 2 2 > $TARGETDIR/hlsl.multiDescriptorSet.frag.out
|
$EXE -V -D -e main -H hlsl.multiDescriptorSet.frag --rsb frag t0 0 0 t1 1 0 s0 0 1 s1 1 1 b0 2 0 b1 2 1 b2 2 2 > $TARGETDIR/hlsl.multiDescriptorSet.frag.out
|
||||||
diff -b $BASEDIR/hlsl.multiDescriptorSet.frag.out $TARGETDIR/hlsl.multiDescriptorSet.frag.out
|
diff -b $BASEDIR/hlsl.multiDescriptorSet.frag.out $TARGETDIR/hlsl.multiDescriptorSet.frag.out || HASERROR=1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Testing location error
|
# Testing location error
|
||||||
#
|
#
|
||||||
echo Testing SPV no location
|
echo Testing SPV no location
|
||||||
$EXE -V -C spv.noLocation.vert > $TARGETDIR/spv.noLocation.vert.out
|
$EXE -V -C spv.noLocation.vert > $TARGETDIR/spv.noLocation.vert.out
|
||||||
diff -b $BASEDIR/spv.noLocation.vert.out $TARGETDIR/spv.noLocation.vert.out
|
diff -b $BASEDIR/spv.noLocation.vert.out $TARGETDIR/spv.noLocation.vert.out || HASERROR=1
|
||||||
|
|
||||||
|
#
|
||||||
|
# Testing debug information
|
||||||
|
#
|
||||||
|
echo Testing SPV Debug Information
|
||||||
|
$EXE -g -H spv.debugInfo.frag > $TARGETDIR/spv.debugInfo.frag.out
|
||||||
|
diff -b $BASEDIR/spv.debugInfo.frag.out $TARGETDIR/spv.debugInfo.frag.out || HASERROR=1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Final checking
|
# Final checking
|
||||||
|
|||||||
52
Test/spv.debugInfo.frag
Normal file
52
Test/spv.debugInfo.frag
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
int a;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform ubuf {
|
||||||
|
S s;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform sampler2D s2d;
|
||||||
|
|
||||||
|
layout(location = 0) in vec4 inv;
|
||||||
|
layout(location = 0) out vec4 outv;
|
||||||
|
|
||||||
|
vec4 foo(S s)
|
||||||
|
{
|
||||||
|
vec4 r = s.a * inv;
|
||||||
|
++r;
|
||||||
|
if (r.x > 3.0)
|
||||||
|
--r;
|
||||||
|
else
|
||||||
|
r *= 2;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
outv = foo(s);
|
||||||
|
outv += texture(s2d, vec2(0.5));
|
||||||
|
|
||||||
|
switch (s.a) {
|
||||||
|
case 10:
|
||||||
|
++outv;
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
outv = 2 * outv;
|
||||||
|
++outv;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
--outv;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
outv *= 3.0;
|
||||||
|
|
||||||
|
outv.x < 10.0 ?
|
||||||
|
outv = sin(outv) :
|
||||||
|
outv = cos(outv);
|
||||||
|
}
|
||||||
@ -728,6 +728,11 @@ bool ProcessDeferred(
|
|||||||
intermediate.setOriginUpperLeft();
|
intermediate.setOriginUpperLeft();
|
||||||
if ((messages & EShMsgHlslOffsets) || (messages & EShMsgReadHlsl))
|
if ((messages & EShMsgHlslOffsets) || (messages & EShMsgReadHlsl))
|
||||||
intermediate.setHlslOffsets();
|
intermediate.setHlslOffsets();
|
||||||
|
if (messages & EShMsgDebugInfo) {
|
||||||
|
intermediate.setSourceFile(names[numPre]);
|
||||||
|
for (int s = 0; s < numStrings; ++s)
|
||||||
|
intermediate.addSourceText(strings[numPre]);
|
||||||
|
}
|
||||||
SetupBuiltinSymbolTable(version, profile, spvVersion, source);
|
SetupBuiltinSymbolTable(version, profile, spvVersion, source);
|
||||||
|
|
||||||
TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
|
TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
|
||||||
|
|||||||
@ -451,6 +451,11 @@ public:
|
|||||||
return semanticNameSet.insert(name).first->c_str();
|
return semanticNameSet.insert(name).first->c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setSourceFile(const char* file) { sourceFile = file; }
|
||||||
|
const std::string& getSourceFile() const { return sourceFile; }
|
||||||
|
void addSourceText(const char* text) { sourceText = sourceText + text; }
|
||||||
|
const std::string& getSourceText() const { return sourceText; }
|
||||||
|
|
||||||
const char* const implicitThisName = "@this";
|
const char* const implicitThisName = "@this";
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -541,6 +546,10 @@ protected:
|
|||||||
|
|
||||||
EShTextureSamplerTransformMode textureSamplerTransformMode;
|
EShTextureSamplerTransformMode textureSamplerTransformMode;
|
||||||
|
|
||||||
|
// source code of shader, useful as part of debug information
|
||||||
|
std::string sourceFile;
|
||||||
|
std::string sourceText;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void operator=(TIntermediate&); // prevent assignments
|
void operator=(TIntermediate&); // prevent assignments
|
||||||
};
|
};
|
||||||
|
|||||||
@ -157,6 +157,7 @@ enum EShMessages {
|
|||||||
EShMsgCascadingErrors = (1 << 7), // get cascading errors; risks error-recovery issues, instead of an early exit
|
EShMsgCascadingErrors = (1 << 7), // get cascading errors; risks error-recovery issues, instead of an early exit
|
||||||
EShMsgKeepUncalled = (1 << 8), // for testing, don't eliminate uncalled functions
|
EShMsgKeepUncalled = (1 << 8), // for testing, don't eliminate uncalled functions
|
||||||
EShMsgHlslOffsets = (1 << 9), // allow block offsets to follow HLSL rules instead of GLSL rules
|
EShMsgHlslOffsets = (1 << 9), // allow block offsets to follow HLSL rules instead of GLSL rules
|
||||||
|
EShMsgDebugInfo = (1 << 10), // save debug information
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user