SPV: Debug output: Include OpLine information for execution path.

Note that declaratives are not handled, only procedurals.
This commit is contained in:
John Kessenich 2017-05-31 18:50:53 -06:00
parent 121853f4df
commit e485c7af58
5 changed files with 310 additions and 70 deletions

View File

@ -869,6 +869,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* gls
if (options.generateDebugInfo) { if (options.generateDebugInfo) {
builder.setSourceFile(glslangIntermediate->getSourceFile()); builder.setSourceFile(glslangIntermediate->getSourceFile());
builder.setSourceText(glslangIntermediate->getSourceText()); 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);
@ -1077,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();
@ -1264,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();
@ -1507,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
@ -1613,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;
@ -1723,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);
@ -1795,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());
@ -1880,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,
@ -2022,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()) {
@ -2030,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);
@ -2046,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);
@ -2080,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();
@ -3057,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)

View File

@ -60,6 +60,8 @@ Builder::Builder(unsigned int magicNumber, SpvBuildLogger* buildLogger) :
source(SourceLanguageUnknown), source(SourceLanguageUnknown),
sourceVersion(0), sourceVersion(0),
sourceFileStringId(NoResult), sourceFileStringId(NoResult),
currentLine(0),
emitOpLines(false),
addressModel(AddressingModelLogical), addressModel(AddressingModelLogical),
memoryModel(MemoryModelGLSL450), memoryModel(MemoryModelGLSL450),
builderNumber(magicNumber), builderNumber(magicNumber),
@ -85,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()
{ {
@ -929,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)

View File

@ -79,6 +79,7 @@ public:
} }
void setSourceText(const std::string& text) { sourceText = text; } 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)
@ -100,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();
@ -221,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);
@ -576,6 +582,8 @@ public:
int sourceVersion; int sourceVersion;
spv::Id sourceFileStringId; spv::Id sourceFileStringId;
std::string sourceText; 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;

View File

@ -3,12 +3,12 @@ Warning, version 450 is not yet complete; most version-specific features are pre
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 40 // Id's are bound by 126
Capability Shader Capability Shader
2: ExtInstImport "GLSL.std.450" 2: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Fragment 5 "main" 17 24 EntryPoint Fragment 5 "main" 24 52
ExecutionMode 5 OriginUpperLeft ExecutionMode 5 OriginUpperLeft
1: String "spv.debugInfo.frag" 1: String "spv.debugInfo.frag"
Source GLSL 450 1 "#version 450 Source GLSL 450 1 "#version 450
@ -21,79 +21,252 @@ uniform ubuf {
S s; S s;
}; };
uniform sampler2D s2d;
layout(location = 0) in vec4 inv; layout(location = 0) in vec4 inv;
layout(location = 0) out vec4 outv; layout(location = 0) out vec4 outv;
void foo(S s) vec4 foo(S s)
{ {
outv = s.a * inv; vec4 r = s.a * inv;
++r;
if (r.x > 3.0)
--r;
else
r *= 2;
return r;
} }
void main() void main()
{ {
foo(s); 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 5 "main"
Name 8 "S" Name 8 "S"
MemberName 8(S) 0 "a" MemberName 8(S) 0 "a"
Name 12 "foo(struct-S-i11;" Name 14 "foo(struct-S-i11;"
Name 11 "s" Name 13 "s"
Name 17 "outv" Name 17 "r"
Name 24 "inv" Name 24 "inv"
Name 27 "S" Name 52 "outv"
MemberName 27(S) 0 "a" Name 53 "S"
Name 28 "ubuf" MemberName 53(S) 0 "a"
MemberName 28(ubuf) 0 "s" Name 54 "ubuf"
Name 30 "" MemberName 54(ubuf) 0 "s"
Name 31 "S" Name 56 ""
MemberName 31(S) 0 "a" Name 57 "S"
Name 33 "param" MemberName 57(S) 0 "a"
Decorate 17(outv) Location 0 Name 59 "param"
Name 69 "s2d"
Name 99 "i"
Decorate 24(inv) Location 0 Decorate 24(inv) Location 0
MemberDecorate 27(S) 0 Offset 0 Decorate 52(outv) Location 0
MemberDecorate 28(ubuf) 0 Offset 0 MemberDecorate 53(S) 0 Offset 0
Decorate 28(ubuf) Block MemberDecorate 54(ubuf) 0 Offset 0
Decorate 30 DescriptorSet 0 Decorate 54(ubuf) Block
Decorate 56 DescriptorSet 0
Decorate 69(s2d) DescriptorSet 0
3: TypeVoid 3: TypeVoid
4: TypeFunction 3 4: TypeFunction 3
7: TypeInt 32 1 7: TypeInt 32 1
8(S): TypeStruct 7(int) 8(S): TypeStruct 7(int)
9: TypePointer Function 8(S) 9: TypePointer Function 8(S)
10: TypeFunction 3 9(ptr) 10: TypeFloat 32
14: TypeFloat 32 11: TypeVector 10(float) 4
15: TypeVector 14(float) 4 12: TypeFunction 11(fvec4) 9(ptr)
16: TypePointer Output 15(fvec4) 16: TypePointer Function 11(fvec4)
17(outv): 16(ptr) Variable Output
18: 7(int) Constant 0 18: 7(int) Constant 0
19: TypePointer Function 7(int) 19: TypePointer Function 7(int)
23: TypePointer Input 15(fvec4) 23: TypePointer Input 11(fvec4)
24(inv): 23(ptr) Variable Input 24(inv): 23(ptr) Variable Input
27(S): TypeStruct 7(int) 28: 10(float) Constant 1065353216
28(ubuf): TypeStruct 27(S) 31: TypeInt 32 0
29: TypePointer Uniform 28(ubuf) 32: 31(int) Constant 0
30: 29(ptr) Variable Uniform 33: TypePointer Function 10(float)
31(S): TypeStruct 7(int) 36: 10(float) Constant 1077936128
32: TypePointer Function 31(S) 37: TypeBool
34: TypePointer Uniform 27(S) 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 5(main): 3 Function None 4
6: Label 6: Label
33(param): 32(ptr) Variable Function 59(param): 58(ptr) Variable Function
35: 34(ptr) AccessChain 30 18 99(i): 19(ptr) Variable Function
36: 27(S) Load 35 113: 16(ptr) Variable Function
37: 7(int) CompositeExtract 36 0 Line 1 30 0
38: 19(ptr) AccessChain 33(param) 18 61: 60(ptr) AccessChain 56 18
Store 38 37 62: 53(S) Load 61
39: 3 FunctionCall 12(foo(struct-S-i11;) 33(param) 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 Return
FunctionEnd FunctionEnd
12(foo(struct-S-i11;): 3 Function None 10 14(foo(struct-S-i11;): 11(fvec4) Function None 12
11(s): 9(ptr) FunctionParameter 13(s): 9(ptr) FunctionParameter
13: Label 15: Label
20: 19(ptr) AccessChain 11(s) 18 17(r): 16(ptr) Variable Function
Line 1 18 0
20: 19(ptr) AccessChain 13(s) 18
21: 7(int) Load 20 21: 7(int) Load 20
22: 14(float) ConvertSToF 21 22: 10(float) ConvertSToF 21
25: 15(fvec4) Load 24(inv) 25: 11(fvec4) Load 24(inv)
26: 15(fvec4) VectorTimesScalar 25 22 26: 11(fvec4) VectorTimesScalar 25 22
Store 17(outv) 26 Store 17(r) 26
Return 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 FunctionEnd

View File

@ -8,15 +8,45 @@ uniform ubuf {
S s; S s;
}; };
uniform sampler2D s2d;
layout(location = 0) in vec4 inv; layout(location = 0) in vec4 inv;
layout(location = 0) out vec4 outv; layout(location = 0) out vec4 outv;
void foo(S s) vec4 foo(S s)
{ {
outv = s.a * inv; vec4 r = s.a * inv;
++r;
if (r.x > 3.0)
--r;
else
r *= 2;
return r;
} }
void main() void main()
{ {
foo(s); 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);
} }