Commit 33782795 by John Kessenich

Merge pull request #127 from dekimir/loopgen

SPV: Rework loop code generation to match SPIR-V 1.0.
parents 9a0b59c7 f3c63cc3
......@@ -144,7 +144,6 @@ protected:
std::unordered_map<const glslang::TTypeList*, spv::Id> structMap[glslang::ElpCount][glslang::ElmCount];
std::unordered_map<const glslang::TTypeList*, std::vector<int> > memberRemapper; // for mapping glslang block indices to spv indices (e.g., due to hidden members)
std::stack<bool> breakForLoop; // false means break for switch
std::stack<glslang::TIntermTyped*> loopTerminal; // code from the last part of a for loop: for(...; ...; terminal), needed for e.g., continue };
};
//
......@@ -1390,33 +1389,63 @@ void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* n
bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIntermLoop* node)
{
// body emission needs to know what the for-loop terminal is when it sees a "continue"
loopTerminal.push(node->getTerminal());
auto blocks = builder.makeNewLoop();
builder.createBranch(&blocks.head);
if (node->testFirst() && node->getTest()) {
builder.setBuildPoint(&blocks.head);
node->getTest()->traverse(this);
spv::Id condition =
builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType()));
builder.createLoopMerge(&blocks.merge, &blocks.continue_target, spv::LoopControlMaskNone);
builder.createConditionalBranch(condition, &blocks.body, &blocks.merge);
builder.makeNewLoop(node->testFirst());
builder.setBuildPoint(&blocks.body);
breakForLoop.push(true);
if (node->getBody())
node->getBody()->traverse(this);
builder.createBranch(&blocks.continue_target);
breakForLoop.pop();
if (node->getTest()) {
node->getTest()->traverse(this);
// the AST only contained the test computation, not the branch, we have to add it
spv::Id condition = builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType()));
builder.createLoopTestBranch(condition);
builder.setBuildPoint(&blocks.continue_target);
if (node->getTerminal())
node->getTerminal()->traverse(this);
builder.createBranch(&blocks.head);
} else {
builder.createBranchToBody();
}
// Spec requires back edges to target header blocks, and every header
// block must dominate its merge block. Create an empty header block
// here to ensure these conditions are met even when body contains
// non-trivial control flow.
builder.setBuildPoint(&blocks.head);
builder.createLoopMerge(&blocks.merge, &blocks.continue_target, spv::LoopControlMaskNone);
builder.createBranch(&blocks.body);
if (node->getBody()) {
breakForLoop.push(true);
node->getBody()->traverse(this);
builder.setBuildPoint(&blocks.body);
if (node->getBody())
node->getBody()->traverse(this);
builder.createBranch(&blocks.continue_target);
breakForLoop.pop();
}
if (loopTerminal.top())
loopTerminal.top()->traverse(this);
builder.setBuildPoint(&blocks.continue_target);
if (node->getTerminal())
node->getTerminal()->traverse(this);
if (node->getTest()) {
node->getTest()->traverse(this);
spv::Id condition =
builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType()));
builder.createConditionalBranch(condition, &blocks.head, &blocks.merge);
} else {
// TODO: unless there was a break instruction somewhere in the body,
// this is an infinite loop, so we should abort code generation with
// a warning. As it stands now, nothing will jump to the merge
// block, and it may be dropped as unreachable by the SPIR-V dumper.
// That, in turn, will result in a non-existing %ID in the LoopMerge
// above.
builder.createBranch(&blocks.head);
}
}
builder.setBuildPoint(&blocks.merge);
builder.closeLoop();
loopTerminal.pop();
return false;
}
......@@ -1436,8 +1465,6 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
builder.addSwitchBreak();
break;
case glslang::EOpContinue:
if (loopTerminal.top())
loopTerminal.top()->traverse(this);
builder.createLoopContinue();
break;
case glslang::EOpReturn:
......
......@@ -67,8 +67,9 @@ class ReadableOrderTraverser {
public:
explicit ReadableOrderTraverser(std::function<void(Block*)> callback) : callback_(callback) {}
// Visits the block if it hasn't been visited already and isn't currently
// being delayed. Invokes callback(block), then descends into its successors.
// Delays merge-block processing until all the branches have been completed.
// being delayed. Invokes callback(block), then descends into its
// successors. Delays merge-block and continue-block processing until all
// the branches have been completed.
void visit(Block* block)
{
assert(block);
......@@ -77,14 +78,25 @@ public:
callback_(block);
visited_[block] = true;
Block* mergeBlock = nullptr;
Block* continueBlock = nullptr;
auto mergeInst = block->getMergeInstruction();
if (mergeInst) {
Id mergeId = mergeInst->getIdOperand(0);
mergeBlock = block->getParent().getParent().getInstruction(mergeId)->getBlock();
delayed_[mergeBlock] = true;
if (mergeInst->getOpCode() == spv::OpLoopMerge) {
Id continueId = mergeInst->getIdOperand(1);
continueBlock =
block->getParent().getParent().getInstruction(continueId)->getBlock();
delayed_[continueBlock] = true;
}
}
for (const auto succ : block->getSuccessors())
visit(succ);
if (continueBlock) {
delayed_[continueBlock] = false;
visit(continueBlock);
}
if (mergeBlock) {
delayed_[mergeBlock] = false;
visit(mergeBlock);
......
......@@ -862,7 +862,7 @@ void Builder::leaveFunction()
if (unreachable) {
// Given that this block is at the end of a function, it must be right after an
// explicit return, just remove it.
function.popBlock(block);
function.removeBlock(block);
} else {
// We'll add a return instruction at the end of the current block,
// which for a non-void function is really error recovery (?), as the source
......@@ -1808,150 +1808,39 @@ void Builder::endSwitch(std::vector<Block*>& /*segmentBlock*/)
switchMerges.pop();
}
// Comments in header
void Builder::makeNewLoop(bool loopTestFirst)
{
loops.push(Loop(*this, loopTestFirst));
const Loop& loop = loops.top();
// The loop test is always emitted before the loop body.
// But if the loop test executes at the bottom of the loop, then
// execute the test only on the second and subsequent iterations.
// Remember the block that branches to the loop header. This
// is required for the test-after-body case.
Block* preheader = getBuildPoint();
// Branch into the loop
createBranch(loop.header);
// Set ourselves inside the loop
loop.function->addBlock(loop.header);
setBuildPoint(loop.header);
if (!loopTestFirst) {
// Generate code to defer the loop test until the second and
// subsequent iterations.
// It's always the first iteration when coming from the preheader.
// All other branches to this loop header will need to indicate "false",
// but we don't yet know where they will come from.
loop.isFirstIteration->addIdOperand(makeBoolConstant(true));
loop.isFirstIteration->addIdOperand(preheader->getId());
getBuildPoint()->addInstruction(std::unique_ptr<Instruction>(loop.isFirstIteration));
// Mark the end of the structured loop. This must exist in the loop header block.
createLoopMerge(loop.merge, loop.header, LoopControlMaskNone);
// Generate code to see if this is the first iteration of the loop.
// It needs to be in its own block, since the loop merge and
// the selection merge instructions can't both be in the same
// (header) block.
Block* firstIterationCheck = new Block(getUniqueId(), *loop.function);
createBranch(firstIterationCheck);
loop.function->addBlock(firstIterationCheck);
setBuildPoint(firstIterationCheck);
// Control flow after this "if" normally reconverges at the loop body.
// However, the loop test has a "break branch" out of this selection
// construct because it can transfer control to the loop merge block.
createSelectionMerge(loop.body, SelectionControlMaskNone);
Block* loopTest = new Block(getUniqueId(), *loop.function);
createConditionalBranch(loop.isFirstIteration->getResultId(), loop.body, loopTest);
loop.function->addBlock(loopTest);
setBuildPoint(loopTest);
}
}
void Builder::createLoopTestBranch(Id condition)
Block& Builder::makeNewBlock()
{
const Loop& loop = loops.top();
// Generate the merge instruction. If the loop test executes before
// the body, then this is a loop merge. Otherwise the loop merge
// has already been generated and this is a conditional merge.
if (loop.testFirst) {
createLoopMerge(loop.merge, loop.header, LoopControlMaskNone);
// Branching to the "body" block will keep control inside
// the loop.
createConditionalBranch(condition, loop.body, loop.merge);
loop.function->addBlock(loop.body);
setBuildPoint(loop.body);
} else {
// The branch to the loop merge block is the allowed exception
// to the structured control flow. Otherwise, control flow will
// continue to loop.body block. Since that is already the target
// of a merge instruction, and a block can't be the target of more
// than one merge instruction, we need to make an intermediate block.
Block* stayInLoopBlock = new Block(getUniqueId(), *loop.function);
createSelectionMerge(stayInLoopBlock, SelectionControlMaskNone);
// This is the loop test.
createConditionalBranch(condition, stayInLoopBlock, loop.merge);
// The dummy block just branches to the real loop body.
loop.function->addBlock(stayInLoopBlock);
setBuildPoint(stayInLoopBlock);
createBranchToBody();
}
Function& function = buildPoint->getParent();
auto block = new Block(getUniqueId(), function);
function.addBlock(block);
return *block;
}
void Builder::createBranchToBody()
Builder::LoopBlocks& Builder::makeNewLoop()
{
const Loop& loop = loops.top();
assert(loop.body);
// This is a reconvergence of control flow, so no merge instruction
// is required.
createBranch(loop.body);
loop.function->addBlock(loop.body);
setBuildPoint(loop.body);
loops.push({makeNewBlock(), makeNewBlock(), makeNewBlock(), makeNewBlock()});
return loops.top();
}
void Builder::createLoopContinue()
{
createBranchToLoopHeaderFromInside(loops.top());
createBranch(&loops.top().continue_target);
// Set up a block for dead code.
createAndSetNoPredecessorBlock("post-loop-continue");
}
// Add an exit (e.g. "break") for the innermost loop that you're in
void Builder::createLoopExit()
{
createBranch(loops.top().merge);
createBranch(&loops.top().merge);
// Set up a block for dead code.
createAndSetNoPredecessorBlock("post-loop-break");
}
// Close the innermost loop
void Builder::closeLoop()
{
const Loop& loop = loops.top();
// Branch back to the top
createBranchToLoopHeaderFromInside(loop);
// Add the merge block and set the build point to it
loop.function->addBlock(loop.merge);
setBuildPoint(loop.merge);
loops.pop();
}
// Create a branch to the header of the given loop, from inside
// the loop body.
// Adjusts the phi node for the first-iteration value if needeed.
void Builder::createBranchToLoopHeaderFromInside(const Loop& loop)
{
createBranch(loop.header);
if (loop.isFirstIteration) {
loop.isFirstIteration->addIdOperand(makeBoolConstant(false));
loop.isFirstIteration->addIdOperand(getBuildPoint()->getId());
}
}
void Builder::clearAccessChain()
{
accessChain.base = NoResult;
......@@ -2314,24 +2203,4 @@ void MissingFunctionality(const char* fun)
printf("Missing functionality: %s\n", fun);
}
Builder::Loop::Loop(Builder& builder, bool testFirstArg)
: function(&builder.getBuildPoint()->getParent()),
header(new Block(builder.getUniqueId(), *function)),
merge(new Block(builder.getUniqueId(), *function)),
body(new Block(builder.getUniqueId(), *function)),
testFirst(testFirstArg),
isFirstIteration(nullptr)
{
if (!testFirst)
{
// You may be tempted to rewrite this as
// new Instruction(builder.getUniqueId(), builder.makeBoolType(), OpPhi);
// This will cause subtle test failures because builder.getUniqueId(),
// and builder.makeBoolType() can then get run in a compiler-specific
// order making tests fail for certain configurations.
Id instructionId = builder.getUniqueId();
isFirstIteration = new Instruction(instructionId, builder.makeBoolType(), OpPhi);
}
}
}; // end spv namespace
......@@ -387,28 +387,24 @@ public:
// Finish off the innermost switch.
void endSwitch(std::vector<Block*>& segmentBB);
// Start the beginning of a new loop, and prepare the builder to
// generate code for the loop test.
// The loopTestFirst parameter is true when the loop test executes before
// the body. (It is false for do-while loops.)
void makeNewLoop(bool loopTestFirst);
// Add the branch for the loop test, based on the given condition.
// The true branch goes to the first block in the loop body, and
// the false branch goes to the loop's merge block. The builder insertion
// point will be placed at the start of the body.
void createLoopTestBranch(Id condition);
// Generate an unconditional branch to the loop body. The builder insertion
// point will be placed at the start of the body. Use this when there is
// no loop test.
void createBranchToBody();
// Add a branch to the test of the current (innermost) loop.
// The way we generate code, that's also the loop header.
struct LoopBlocks {
Block &head, &body, &merge, &continue_target;
};
// Start a new loop and prepare the builder to generate code for it. Until
// closeLoop() is called for this loop, createLoopContinue() and
// createLoopExit() will target its corresponding blocks.
LoopBlocks& makeNewLoop();
// Create a new block in the function containing the build point. Memory is
// owned by the function object.
Block& makeNewBlock();
// Add a branch to the continue_target of the current (innermost) loop.
void createLoopContinue();
// Add an exit (e.g. "break") for the innermost loop that you're in
// Add an exit (e.g. "break") from the innermost loop that we're currently
// in.
void createLoopExit();
// Close the innermost loop that you're in
......@@ -508,7 +504,11 @@ public:
void dump(std::vector<unsigned int>&) const;
protected:
void createBranch(Block* block);
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control);
protected:
Id makeIntConstant(Id typeId, unsigned value, bool specConstant);
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value) const;
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const;
......@@ -517,15 +517,9 @@ protected:
void transferAccessChainSwizzle(bool dynamic);
void simplifyAccessChainSwizzle();
void createAndSetNoPredecessorBlock(const char*);
void createBranch(Block* block);
void createSelectionMerge(Block* mergeBlock, unsigned int control);
void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control);
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
struct Loop; // Defined below.
void createBranchToLoopHeaderFromInside(const Loop& loop);
SourceLanguage source;
int sourceVersion;
std::vector<const char*> extensions;
......@@ -557,47 +551,8 @@ protected:
// stack of switches
std::stack<Block*> switchMerges;
// Data that needs to be kept in order to properly handle loops.
struct Loop {
// Constructs a default Loop structure containing new header, merge, and
// body blocks for the current function.
// The testFirst argument indicates whether the loop test executes at
// the top of the loop rather than at the bottom. In the latter case,
// also create a phi instruction whose value indicates whether we're on
// the first iteration of the loop. The phi instruction is initialized
// with no values or predecessor operands.
Loop(Builder& builder, bool testFirst);
// The function containing the loop.
Function* const function;
// The header is the first block generated for the loop.
// It dominates all the blocks in the loop, i.e. it is always
// executed before any others.
// If the loop test is executed before the body (as in "while" and
// "for" loops), then the header begins with the test code.
// Otherwise, the loop is a "do-while" loop and the header contains the
// start of the body of the loop (if the body exists).
Block* const header;
// The merge block marks the end of the loop. Control is transferred
// to the merge block when either the loop test fails, or when a
// nested "break" is encountered.
Block* const merge;
// The body block is the first basic block in the body of the loop, i.e.
// the code that is to be repeatedly executed, aside from loop control.
// This member is null until we generate code that references the loop
// body block.
Block* const body;
// True when the loop test executes before the body.
const bool testFirst;
// When the test executes after the body, this is defined as the phi
// instruction that tells us whether we are on the first iteration of
// the loop. Otherwise this is null. This is non-const because
// it has to be initialized outside of the initializer-list.
Instruction* isFirstIteration;
};
// Our loop stack.
std::stack<Loop> loops;
std::stack<LoopBlocks> loops;
}; // end Builder class
// Use for non-fatal notes about what's not complete
......
......@@ -52,6 +52,7 @@
#include "spirv.hpp"
#include <algorithm>
#include <cassert>
#include <functional>
#include <iostream>
......@@ -259,7 +260,13 @@ public:
Id getParamId(int p) { return parameterInstructions[p]->getResultId(); }
void addBlock(Block* block) { blocks.push_back(block); }
void popBlock(Block*) { blocks.pop_back(); }
void removeBlock(Block* block)
{
auto found = find(blocks.begin(), blocks.end(), block);
assert(found != blocks.end());
blocks.erase(found);
delete block;
}
Module& getParent() const { return parent; }
Block* getEntryBlock() const { return blocks.front(); }
......
......@@ -8,64 +8,66 @@ Linked vertex stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 38
// Id's are bound by 39
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 23 26 32 37
EntryPoint Vertex 4 "main" 24 27 33 38
Source GLSL 130
Name 4 "main"
Name 8 "i"
Name 23 "colorOut"
Name 26 "color"
Name 32 "gl_Position"
Name 37 "gl_VertexID"
Decorate 32(gl_Position) BuiltIn Position
Decorate 37(gl_VertexID) BuiltIn VertexId
Name 24 "colorOut"
Name 27 "color"
Name 33 "gl_Position"
Name 38 "gl_VertexID"
Decorate 33(gl_Position) BuiltIn Position
Decorate 38(gl_VertexID) BuiltIn VertexId
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 1
14: 6(int) Constant 5
15: TypeBool
17: TypeFloat 32
18: TypeVector 17(float) 4
19: TypeInt 32 0
20: 19(int) Constant 6
21: TypeArray 18(fvec4) 20
22: TypePointer Output 21
23(colorOut): 22(ptr) Variable Output
25: TypePointer Input 18(fvec4)
26(color): 25(ptr) Variable Input
28: TypePointer Output 18(fvec4)
32(gl_Position): 28(ptr) Variable Output
33: 6(int) Constant 2
36: TypePointer Input 6(int)
37(gl_VertexID): 36(ptr) Variable Input
15: 6(int) Constant 5
16: TypeBool
18: TypeFloat 32
19: TypeVector 18(float) 4
20: TypeInt 32 0
21: 20(int) Constant 6
22: TypeArray 19(fvec4) 21
23: TypePointer Output 22
24(colorOut): 23(ptr) Variable Output
26: TypePointer Input 19(fvec4)
27(color): 26(ptr) Variable Input
29: TypePointer Output 19(fvec4)
33(gl_Position): 29(ptr) Variable Output
34: 6(int) Constant 2
37: TypePointer Input 6(int)
38(gl_VertexID): 37(ptr) Variable Input
4(main): 2 Function None 3
5: Label
8(i): 7(ptr) Variable Function
Store 8(i) 9
Branch 10
10: Label
13: 6(int) Load 8(i)
16: 15(bool) SLessThan 13 14
LoopMerge 11 10 None
BranchConditional 16 12 11
12: Label
24: 6(int) Load 8(i)
27: 18(fvec4) Load 26(color)
29: 28(ptr) AccessChain 23(colorOut) 24
Store 29 27
30: 6(int) Load 8(i)
31: 6(int) IAdd 30 9
Store 8(i) 31
14: 6(int) Load 8(i)
17: 16(bool) SLessThan 14 15
LoopMerge 12 13 None
BranchConditional 17 11 12
11: Label
25: 6(int) Load 8(i)
28: 19(fvec4) Load 27(color)
30: 29(ptr) AccessChain 24(colorOut) 25
Store 30 28
Branch 13
13: Label
31: 6(int) Load 8(i)
32: 6(int) IAdd 31 9
Store 8(i) 32
Branch 10
11: Label
34: 28(ptr) AccessChain 23(colorOut) 33
35: 18(fvec4) Load 34
Store 32(gl_Position) 35
12: Label
35: 29(ptr) AccessChain 24(colorOut) 34
36: 19(fvec4) Load 35
Store 33(gl_Position) 36
Return
FunctionEnd
......@@ -5,56 +5,47 @@ Linked vertex stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 29
// Id's are bound by 24
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 27 28
EntryPoint Vertex 4 "main" 22 23
Source ESSL 300
Name 4 "main"
Name 8 "i"
Name 27 "gl_VertexID"
Name 28 "gl_InstanceID"
Decorate 27(gl_VertexID) BuiltIn VertexId
Decorate 28(gl_InstanceID) BuiltIn InstanceId
Name 22 "gl_VertexID"
Name 23 "gl_InstanceID"
Decorate 22(gl_VertexID) BuiltIn VertexId
Decorate 23(gl_InstanceID) BuiltIn InstanceId
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 0
14: TypeBool
15: 14(bool) ConstantTrue
19: 6(int) Constant 10
23: 6(int) Constant 1
25: 14(bool) ConstantFalse
26: TypePointer Input 6(int)
27(gl_VertexID): 26(ptr) Variable Input
28(gl_InstanceID): 26(ptr) Variable Input
15: 6(int) Constant 1
18: 6(int) Constant 10
19: TypeBool
21: TypePointer Input 6(int)
22(gl_VertexID): 21(ptr) Variable Input
23(gl_InstanceID): 21(ptr) Variable Input
4(main): 2 Function None 3
5: Label
8(i): 7(ptr) Variable Function
Store 8(i) 9
Branch 10
10: Label
13: 14(bool) Phi 15 5 25 12
LoopMerge 11 10 None
Branch 16
16: Label
SelectionMerge 12 None
BranchConditional 13 12 17
17: Label
18: 6(int) Load 8(i)
20: 14(bool) SLessThan 18 19
SelectionMerge 21 None
BranchConditional 20 21 11
21: Label
Branch 12
12: Label
22: 6(int) Load 8(i)
24: 6(int) IAdd 22 23
Store 8(i) 24
Branch 10
LoopMerge 12 13 None
Branch 11
11: Label
14: 6(int) Load 8(i)
16: 6(int) IAdd 14 15
Store 8(i) 16
Branch 13
13: Label
17: 6(int) Load 8(i)
20: 19(bool) SLessThan 17 18
BranchConditional 20 10 12
12: Label
Return
FunctionEnd
......@@ -5,94 +5,85 @@ Linked vertex stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 51
// Id's are bound by 46
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 49 50
EntryPoint Vertex 4 "main" 44 45
Source ESSL 300
Name 4 "main"
Name 8 "i"
Name 24 "A"
Name 30 "B"
Name 33 "C"
Name 39 "D"
Name 42 "E"
Name 44 "F"
Name 46 "G"
Name 49 "gl_VertexID"
Name 50 "gl_InstanceID"
Decorate 49(gl_VertexID) BuiltIn VertexId
Decorate 50(gl_InstanceID) BuiltIn InstanceId
Name 14 "A"
Name 21 "B"
Name 24 "C"
Name 30 "D"
Name 33 "E"
Name 35 "F"
Name 41 "G"
Name 44 "gl_VertexID"
Name 45 "gl_InstanceID"
Decorate 44(gl_VertexID) BuiltIn VertexId
Decorate 45(gl_InstanceID) BuiltIn InstanceId
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 0
14: TypeBool
15: 14(bool) ConstantTrue
19: 6(int) Constant 1
21: 6(int) Constant 19
26: 6(int) Constant 2
31: 14(bool) ConstantFalse
35: 6(int) Constant 5
40: 6(int) Constant 3
43: 6(int) Constant 42
45: 6(int) Constant 99
47: 6(int) Constant 12
48: TypePointer Input 6(int)
49(gl_VertexID): 48(ptr) Variable Input
50(gl_InstanceID): 48(ptr) Variable Input
16: 6(int) Constant 2
17: TypeBool
22: 6(int) Constant 1
26: 6(int) Constant 5
31: 6(int) Constant 3
34: 6(int) Constant 42
36: 6(int) Constant 99
39: 6(int) Constant 19
42: 6(int) Constant 12
43: TypePointer Input 6(int)
44(gl_VertexID): 43(ptr) Variable Input
45(gl_InstanceID): 43(ptr) Variable Input
4(main): 2 Function None 3
5: Label
8(i): 7(ptr) Variable Function
24(A): 7(ptr) Variable Function
30(B): 7(ptr) Variable Function
33(C): 7(ptr) Variable Function
39(D): 7(ptr) Variable Function
42(E): 7(ptr) Variable Function
44(F): 7(ptr) Variable Function
46(G): 7(ptr) Variable Function
14(A): 7(ptr) Variable Function
21(B): 7(ptr) Variable Function
24(C): 7(ptr) Variable Function
30(D): 7(ptr) Variable Function
33(E): 7(ptr) Variable Function
35(F): 7(ptr) Variable Function
41(G): 7(ptr) Variable Function
Store 8(i) 9
Branch 10
10: Label
13: 14(bool) Phi 15 5 31 28 31 38
LoopMerge 11 10 None
Branch 16
16: Label
SelectionMerge 12 None
BranchConditional 13 12 17
17: Label
18: 6(int) Load 8(i)
20: 6(int) IAdd 18 19
Store 8(i) 20
22: 14(bool) SLessThan 20 21
SelectionMerge 23 None
BranchConditional 22 23 11
23: Label
Branch 12
12: Label
Store 24(A) 9
LoopMerge 12 13 None
Branch 11
11: Label
Store 14(A) 9
15: 6(int) Load 8(i)
18: 17(bool) IEqual 15 16
SelectionMerge 20 None
BranchConditional 18 19 20
19: Label
Store 21(B) 22
Branch 13
20: Label
25: 6(int) Load 8(i)
27: 14(bool) IEqual 25 26
27: 17(bool) IEqual 25 26
SelectionMerge 29 None
BranchConditional 27 28 29
28: Label
Store 30(B) 19
Branch 10
Store 30(D) 31
Branch 12
29: Label
34: 6(int) Load 8(i)
36: 14(bool) IEqual 34 35
SelectionMerge 38 None
BranchConditional 36 37 38
37: Label
Store 39(D) 40
Branch 11
38: Label
Store 44(F) 45
Branch 10
11: Label
Store 46(G) 47
Store 35(F) 36
Branch 13
13: Label
37: 6(int) Load 8(i)
38: 6(int) IAdd 37 22
Store 8(i) 38
40: 17(bool) SLessThan 38 39
BranchConditional 40 10 12
12: Label
Store 41(G) 42
Return
FunctionEnd
......@@ -5,20 +5,20 @@ Linked fragment stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 40
// Id's are bound by 35
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 11 38
EntryPoint Fragment 4 "main" 11 33
ExecutionMode 4 OriginLowerLeft
Source GLSL 110
Name 4 "main"
Name 9 "color"
Name 11 "BaseColor"
Name 27 "d"
Name 32 "bigColor"
Name 38 "gl_FragColor"
Name 18 "bigColor"
Name 28 "d"
Name 33 "gl_FragColor"
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
......@@ -26,18 +26,16 @@ Linked fragment stage:
8: TypePointer Function 7(fvec4)
10: TypePointer Input 7(fvec4)
11(BaseColor): 10(ptr) Variable Input
17: TypeBool
18: 17(bool) ConstantTrue
21: TypeInt 32 0
22: 21(int) Constant 0
23: TypePointer Function 6(float)
26: TypePointer UniformConstant 6(float)
27(d): 26(ptr) Variable UniformConstant
31: TypePointer UniformConstant 7(fvec4)
32(bigColor): 31(ptr) Variable UniformConstant
36: 17(bool) ConstantFalse
37: TypePointer Output 7(fvec4)
38(gl_FragColor): 37(ptr) Variable Output
17: TypePointer UniformConstant 7(fvec4)
18(bigColor): 17(ptr) Variable UniformConstant
22: TypeInt 32 0
23: 22(int) Constant 0
24: TypePointer Function 6(float)
27: TypePointer UniformConstant 6(float)
28(d): 27(ptr) Variable UniformConstant
30: TypeBool
32: TypePointer Output 7(fvec4)
33(gl_FragColor): 32(ptr) Variable Output
4(main): 2 Function None 3
5: Label
9(color): 8(ptr) Variable Function
......@@ -45,29 +43,22 @@ Linked fragment stage:
Store 9(color) 12
Branch 13
13: Label
16: 17(bool) Phi 18 5 36 15
LoopMerge 14 13 None
Branch 19
19: Label
SelectionMerge 15 None
BranchConditional 16 15 20
20: Label
24: 23(ptr) AccessChain 9(color) 22
25: 6(float) Load 24
28: 6(float) Load 27(d)
29: 17(bool) FOrdLessThan 25 28
SelectionMerge 30 None
BranchConditional 29 30 14
30: Label
Branch 15
LoopMerge 15 16 None
Branch 14
14: Label
19: 7(fvec4) Load 18(bigColor)
20: 7(fvec4) Load 9(color)
21: 7(fvec4) FAdd 20 19
Store 9(color) 21
Branch 16
16: Label
25: 24(ptr) AccessChain 9(color) 23
26: 6(float) Load 25
29: 6(float) Load 28(d)
31: 30(bool) FOrdLessThan 26 29
BranchConditional 31 13 15
15: Label
33: 7(fvec4) Load 32(bigColor)
34: 7(fvec4) Load 9(color)
35: 7(fvec4) FAdd 34 33
Store 9(color) 35
Branch 13
14: Label
39: 7(fvec4) Load 9(color)
Store 38(gl_FragColor) 39
Store 33(gl_FragColor) 34
Return
FunctionEnd
......@@ -5,87 +5,86 @@ Linked vertex stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 48
// Id's are bound by 47
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 46 47
EntryPoint Vertex 4 "main" 45 46
Source ESSL 300
Name 4 "main"
Name 8 "i"
Name 17 "A"
Name 25 "B"
Name 29 "C"
Name 36 "D"
Name 38 "E"
Name 39 "F"
Name 43 "G"
Name 46 "gl_VertexID"
Name 47 "gl_InstanceID"
Decorate 46(gl_VertexID) BuiltIn VertexId
Decorate 47(gl_InstanceID) BuiltIn InstanceId
Name 18 "A"
Name 26 "B"
Name 28 "C"
Name 35 "D"
Name 37 "E"
Name 38 "F"
Name 42 "G"
Name 45 "gl_VertexID"
Name 46 "gl_InstanceID"
Decorate 45(gl_VertexID) BuiltIn VertexId
Decorate 46(gl_InstanceID) BuiltIn InstanceId
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 0
14: 6(int) Constant 10
15: TypeBool
18: 6(int) Constant 1
20: 6(int) Constant 2
31: 6(int) Constant 3
40: 6(int) Constant 12
44: 6(int) Constant 99
45: TypePointer Input 6(int)
46(gl_VertexID): 45(ptr) Variable Input
47(gl_InstanceID): 45(ptr) Variable Input
15: 6(int) Constant 10
16: TypeBool
19: 6(int) Constant 1
21: 6(int) Constant 2
30: 6(int) Constant 3
39: 6(int) Constant 12
43: 6(int) Constant 99
44: TypePointer Input 6(int)
45(gl_VertexID): 44(ptr) Variable Input
46(gl_InstanceID): 44(ptr) Variable Input
4(main): 2 Function None 3
5: Label
8(i): 7(ptr) Variable Function
17(A): 7(ptr) Variable Function
25(B): 7(ptr) Variable Function
29(C): 7(ptr) Variable Function
36(D): 7(ptr) Variable Function
38(E): 7(ptr) Variable Function
39(F): 7(ptr) Variable Function
43(G): 7(ptr) Variable Function
18(A): 7(ptr) Variable Function
26(B): 7(ptr) Variable Function
28(C): 7(ptr) Variable Function
35(D): 7(ptr) Variable Function
37(E): 7(ptr) Variable Function
38(F): 7(ptr) Variable Function
42(G): 7(ptr) Variable Function
Store 8(i) 9
Branch 10
10: Label
13: 6(int) Load 8(i)
16: 15(bool) SLessThan 13 14
LoopMerge 11 10 None
BranchConditional 16 12 11
12: Label
Store 17(A) 18
19: 6(int) Load 8(i)
21: 6(int) SMod 19 20
22: 15(bool) IEqual 21 9
SelectionMerge 24 None
BranchConditional 22 23 24
23: Label
Store 25(B) 18
26: 6(int) Load 8(i)
27: 6(int) IAdd 26 18
Store 8(i) 27
Branch 10
24: Label
30: 6(int) Load 8(i)
32: 6(int) SMod 30 31
33: 15(bool) IEqual 32 9
SelectionMerge 35 None
BranchConditional 33 34 35
34: Label
Store 36(D) 18
Branch 11
35: Label
Store 39(F) 40
41: 6(int) Load 8(i)
42: 6(int) IAdd 41 18
Store 8(i) 42
14: 6(int) Load 8(i)
17: 16(bool) SLessThan 14 15
LoopMerge 12 13 None
BranchConditional 17 11 12
11: Label
Store 18(A) 19
20: 6(int) Load 8(i)
22: 6(int) SMod 20 21
23: 16(bool) IEqual 22 9
SelectionMerge 25 None
BranchConditional 23 24 25
24: Label
Store 26(B) 19
Branch 13
25: Label
29: 6(int) Load 8(i)
31: 6(int) SMod 29 30
32: 16(bool) IEqual 31 9
SelectionMerge 34 None
BranchConditional 32 33 34
33: Label
Store 35(D) 19
Branch 12
34: Label
Store 38(F) 39
Branch 13
13: Label
40: 6(int) Load 8(i)
41: 6(int) IAdd 40 19
Store 8(i) 41
Branch 10
11: Label
Store 43(G) 44
12: Label
Store 42(G) 43
Return
FunctionEnd
spv.for-nobody.vert
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
Linked vertex stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 27
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 22 25 26
Source GLSL 450
Name 4 "main"
Name 8 "i"
Name 22 "r"
Name 25 "gl_VertexID"
Name 26 "gl_InstanceID"
Decorate 22(r) Location 0
Decorate 25(gl_VertexID) BuiltIn VertexId
Decorate 26(gl_InstanceID) BuiltIn InstanceId
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 0
15: 6(int) Constant 10
16: TypeBool
19: 6(int) Constant 1
21: TypePointer Output 6(int)
22(r): 21(ptr) Variable Output
24: TypePointer Input 6(int)
25(gl_VertexID): 24(ptr) Variable Input
26(gl_InstanceID): 24(ptr) Variable Input
4(main): 2 Function None 3
5: Label
8(i): 7(ptr) Variable Function
Store 8(i) 9
Branch 10
10: Label
14: 6(int) Load 8(i)
17: 16(bool) SLessThan 14 15
LoopMerge 12 13 None
BranchConditional 17 11 12
11: Label
Branch 13
13: Label
18: 6(int) Load 8(i)
20: 6(int) IAdd 18 19
Store 8(i) 20
Branch 10
12: Label
23: 6(int) Load 8(i)
Store 22(r) 23
Return
FunctionEnd
spv.for-notest.vert
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
Linked vertex stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 23
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 15 21 22
Source GLSL 450
Name 4 "main"
Name 8 "i"
Name 15 "r"
Name 21 "gl_VertexID"
Name 22 "gl_InstanceID"
Decorate 15(r) Location 0
Decorate 21(gl_VertexID) BuiltIn VertexId
Decorate 22(gl_InstanceID) BuiltIn InstanceId
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 0
14: TypePointer Output 6(int)
15(r): 14(ptr) Variable Output
18: 6(int) Constant 1
20: TypePointer Input 6(int)
21(gl_VertexID): 20(ptr) Variable Input
22(gl_InstanceID): 20(ptr) Variable Input
4(main): 2 Function None 3
5: Label
8(i): 7(ptr) Variable Function
Store 8(i) 9
Branch 10
10: Label
LoopMerge 12 13 None
Branch 11
11: Label
16: 6(int) Load 8(i)
Store 15(r) 16
Branch 13
13: Label
17: 6(int) Load 8(i)
19: 6(int) IAdd 17 18
Store 8(i) 19
Branch 10
FunctionEnd
......@@ -5,49 +5,51 @@ Linked vertex stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 25
// Id's are bound by 26
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 23 24
EntryPoint Vertex 4 "main" 24 25
Source ESSL 300
Name 4 "main"
Name 8 "i"
Name 17 "j"
Name 23 "gl_VertexID"
Name 24 "gl_InstanceID"
Decorate 23(gl_VertexID) BuiltIn VertexId
Decorate 24(gl_InstanceID) BuiltIn InstanceId
Name 18 "j"
Name 24 "gl_VertexID"
Name 25 "gl_InstanceID"
Decorate 24(gl_VertexID) BuiltIn VertexId
Decorate 25(gl_InstanceID) BuiltIn InstanceId
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 0
14: 6(int) Constant 10
15: TypeBool
18: 6(int) Constant 12
20: 6(int) Constant 1
22: TypePointer Input 6(int)
23(gl_VertexID): 22(ptr) Variable Input
24(gl_InstanceID): 22(ptr) Variable Input
15: 6(int) Constant 10
16: TypeBool
19: 6(int) Constant 12
21: 6(int) Constant 1
23: TypePointer Input 6(int)
24(gl_VertexID): 23(ptr) Variable Input
25(gl_InstanceID): 23(ptr) Variable Input
4(main): 2 Function None 3
5: Label
8(i): 7(ptr) Variable Function
17(j): 7(ptr) Variable Function
18(j): 7(ptr) Variable Function
Store 8(i) 9
Branch 10
10: Label
13: 6(int) Load 8(i)
16: 15(bool) SLessThan 13 14
LoopMerge 11 10 None
BranchConditional 16 12 11
12: Label
Store 17(j) 18
19: 6(int) Load 8(i)
21: 6(int) IAdd 19 20
Store 8(i) 21
14: 6(int) Load 8(i)
17: 16(bool) SLessThan 14 15
LoopMerge 12 13 None
BranchConditional 17 11 12
11: Label
Store 18(j) 19
Branch 13
13: Label
20: 6(int) Load 8(i)
22: 6(int) IAdd 20 21
Store 8(i) 22
Branch 10
11: Label
12: Label
Return
FunctionEnd
......@@ -8,12 +8,12 @@ Linked fragment stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 136
// Id's are bound by 137
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 40 96 106
EntryPoint Fragment 4 "main" 40 97 107
ExecutionMode 4 OriginLowerLeft
Source GLSL 130
Name 4 "main"
......@@ -38,14 +38,14 @@ Linked fragment stage:
Name 68 "x"
Name 70 "localArray"
Name 75 "i"
Name 82 "a"
Name 88 "condition"
Name 96 "color"
Name 106 "gl_FragColor"
Name 126 "samp2D"
Name 132 "foo"
Name 133 "foo2"
Name 135 "uFloatArray"
Name 83 "a"
Name 89 "condition"
Name 97 "color"
Name 107 "gl_FragColor"
Name 127 "samp2D"
Name 133 "foo"
Name 134 "foo2"
Name 136 "uFloatArray"
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
......@@ -80,26 +80,26 @@ Linked fragment stage:
48: TypePointer Function 47
52: TypePointer Function 6(int)
69: 6(int) Constant 5
80: 6(int) Constant 16
84: 7(float) Constant 0
88(condition): 20(ptr) Variable UniformConstant
94: 6(int) Constant 3
95: TypePointer Input 9(fvec4)
96(color): 95(ptr) Variable Input
98: TypePointer Function 9(fvec4)
100: 32(int) Constant 1
103: 32(int) Constant 2
105: TypePointer Output 9(fvec4)
106(gl_FragColor): 105(ptr) Variable Output
123: TypeImage 7(float) 2D sampled format:Unknown
124: TypeSampledImage 123
125: TypePointer UniformConstant 124
126(samp2D): 125(ptr) Variable UniformConstant
131: TypePointer UniformConstant 8(s1)
132(foo): 131(ptr) Variable UniformConstant
133(foo2): 17(ptr) Variable UniformConstant
134: TypePointer UniformConstant 34
135(uFloatArray): 134(ptr) Variable UniformConstant
81: 6(int) Constant 16
85: 7(float) Constant 0
89(condition): 20(ptr) Variable UniformConstant
95: 6(int) Constant 3
96: TypePointer Input 9(fvec4)
97(color): 96(ptr) Variable Input
99: TypePointer Function 9(fvec4)
101: 32(int) Constant 1
104: 32(int) Constant 2
106: TypePointer Output 9(fvec4)
107(gl_FragColor): 106(ptr) Variable Output
124: TypeImage 7(float) 2D sampled format:Unknown
125: TypeSampledImage 124
126: TypePointer UniformConstant 125
127(samp2D): 126(ptr) Variable UniformConstant
132: TypePointer UniformConstant 8(s1)
133(foo): 132(ptr) Variable UniformConstant
134(foo2): 17(ptr) Variable UniformConstant
135: TypePointer UniformConstant 34
136(uFloatArray): 135(ptr) Variable UniformConstant
4(main): 2 Function None 3
5: Label
12(locals2): 11(ptr) Variable Function
......@@ -108,7 +108,7 @@ Linked fragment stage:
68(x): 52(ptr) Variable Function
70(localArray): 35(ptr) Variable Function
75(i): 52(ptr) Variable Function
82(a): 35(ptr) Variable Function
83(a): 35(ptr) Variable Function
18: 17(ptr) AccessChain 15(foo3) 16
19: 10(s2) Load 18
Store 12(locals2) 19
......@@ -161,55 +161,57 @@ Linked fragment stage:
Store 75(i) 16
Branch 76
76: Label
79: 6(int) Load 75(i)
81: 23(bool) SLessThan 79 80
LoopMerge 77 76 None
BranchConditional 81 78 77
78: Label
83: 6(int) Load 75(i)
85: 30(ptr) AccessChain 82(a) 83
Store 85 84
86: 6(int) Load 75(i)
87: 6(int) IAdd 86 28
Store 75(i) 87
80: 6(int) Load 75(i)
82: 23(bool) SLessThan 80 81
LoopMerge 78 79 None
BranchConditional 82 77 78
77: Label
84: 6(int) Load 75(i)
86: 30(ptr) AccessChain 83(a) 84
Store 86 85
Branch 79
79: Label
87: 6(int) Load 75(i)
88: 6(int) IAdd 87 28
Store 75(i) 88
Branch 76
77: Label
89: 6(int) Load 88(condition)
90: 23(bool) IEqual 89 28
SelectionMerge 92 None
BranchConditional 90 91 92
91: Label
93: 34 Load 70(localArray)
Store 82(a) 93
Branch 92
92: Label
97: 9(fvec4) Load 96(color)
99: 98(ptr) AccessChain 12(locals2) 94
Store 99 97
101: 42(ptr) AccessChain 40(coord) 100
102: 7(float) Load 101
104: 30(ptr) AccessChain 12(locals2) 94 103
Store 104 102
107: 98(ptr) AccessChain 12(locals2) 94
108: 9(fvec4) Load 107
109: 30(ptr) AccessChain 36(localFArray) 37
110: 7(float) Load 109
111: 30(ptr) AccessChain 12(locals2) 27 28
112: 7(float) Load 111
113: 7(float) FAdd 110 112
114: 6(int) Load 68(x)
115: 30(ptr) AccessChain 70(localArray) 114
116: 7(float) Load 115
117: 7(float) FAdd 113 116
118: 6(int) Load 68(x)
119: 30(ptr) AccessChain 82(a) 118
120: 7(float) Load 119
121: 7(float) FAdd 117 120
122: 9(fvec4) VectorTimesScalar 108 121
127: 124 Load 126(samp2D)
128: 38(fvec2) Load 40(coord)
129: 9(fvec4) ImageSampleImplicitLod 127 128
130: 9(fvec4) FMul 122 129
Store 106(gl_FragColor) 130
78: Label
90: 6(int) Load 89(condition)
91: 23(bool) IEqual 90 28
SelectionMerge 93 None
BranchConditional 91 92 93
92: Label
94: 34 Load 70(localArray)
Store 83(a) 94
Branch 93
93: Label
98: 9(fvec4) Load 97(color)
100: 99(ptr) AccessChain 12(locals2) 95
Store 100 98
102: 42(ptr) AccessChain 40(coord) 101
103: 7(float) Load 102
105: 30(ptr) AccessChain 12(locals2) 95 104
Store 105 103
108: 99(ptr) AccessChain 12(locals2) 95
109: 9(fvec4) Load 108
110: 30(ptr) AccessChain 36(localFArray) 37
111: 7(float) Load 110
112: 30(ptr) AccessChain 12(locals2) 27 28
113: 7(float) Load 112
114: 7(float) FAdd 111 113
115: 6(int) Load 68(x)
116: 30(ptr) AccessChain 70(localArray) 115
117: 7(float) Load 116
118: 7(float) FAdd 114 117
119: 6(int) Load 68(x)
120: 30(ptr) AccessChain 83(a) 119
121: 7(float) Load 120
122: 7(float) FAdd 118 121
123: 9(fvec4) VectorTimesScalar 109 122
128: 125 Load 127(samp2D)
129: 38(fvec2) Load 40(coord)
130: 9(fvec4) ImageSampleImplicitLod 128 129
131: 9(fvec4) FMul 123 130
Store 107(gl_FragColor) 131
Return
FunctionEnd
......@@ -5,76 +5,78 @@ Linked vertex stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 42
// Id's are bound by 43
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 40 41
EntryPoint Vertex 4 "main" 41 42
Source ESSL 300
Name 4 "main"
Name 8 "i"
Name 17 "A"
Name 25 "B"
Name 27 "C"
Name 37 "D"
Name 40 "gl_VertexID"
Name 41 "gl_InstanceID"
Decorate 40(gl_VertexID) BuiltIn VertexId
Decorate 41(gl_InstanceID) BuiltIn InstanceId
Name 18 "A"
Name 26 "B"
Name 28 "C"
Name 38 "D"
Name 41 "gl_VertexID"
Name 42 "gl_InstanceID"
Decorate 41(gl_VertexID) BuiltIn VertexId
Decorate 42(gl_InstanceID) BuiltIn InstanceId
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 0
14: 6(int) Constant 10
15: TypeBool
18: 6(int) Constant 1
20: 6(int) Constant 2
29: 6(int) Constant 5
38: 6(int) Constant 3
39: TypePointer Input 6(int)
40(gl_VertexID): 39(ptr) Variable Input
41(gl_InstanceID): 39(ptr) Variable Input
15: 6(int) Constant 10
16: TypeBool
19: 6(int) Constant 1
21: 6(int) Constant 2
30: 6(int) Constant 5
39: 6(int) Constant 3
40: TypePointer Input 6(int)
41(gl_VertexID): 40(ptr) Variable Input
42(gl_InstanceID): 40(ptr) Variable Input
4(main): 2 Function None 3
5: Label
8(i): 7(ptr) Variable Function
17(A): 7(ptr) Variable Function
25(B): 7(ptr) Variable Function
27(C): 7(ptr) Variable Function
37(D): 7(ptr) Variable Function
18(A): 7(ptr) Variable Function
26(B): 7(ptr) Variable Function
28(C): 7(ptr) Variable Function
38(D): 7(ptr) Variable Function
Store 8(i) 9
Branch 10
10: Label
13: 6(int) Load 8(i)
16: 15(bool) SLessThan 13 14
LoopMerge 11 10 None
BranchConditional 16 12 11
12: Label
Store 17(A) 18
19: 6(int) Load 8(i)
21: 6(int) SMod 19 20
22: 15(bool) IEqual 21 9
SelectionMerge 24 None
BranchConditional 22 23 24
23: Label
Store 25(B) 20
Branch 10
24: Label
28: 6(int) Load 8(i)
30: 6(int) SMod 28 29
31: 15(bool) IEqual 30 9
SelectionMerge 33 None
BranchConditional 31 32 33
32: Label
Store 25(B) 20
Branch 11
33: Label
35: 6(int) Load 8(i)
36: 6(int) IAdd 35 18
Store 8(i) 36
14: 6(int) Load 8(i)
17: 16(bool) SLessThan 14 15
LoopMerge 12 13 None
BranchConditional 17 11 12
11: Label
Store 18(A) 19
20: 6(int) Load 8(i)
22: 6(int) SMod 20 21
23: 16(bool) IEqual 22 9
SelectionMerge 25 None
BranchConditional 23 24 25
24: Label
Store 26(B) 21
Branch 13
25: Label
29: 6(int) Load 8(i)
31: 6(int) SMod 29 30
32: 16(bool) IEqual 31 9
SelectionMerge 34 None
BranchConditional 32 33 34
33: Label
Store 26(B) 21
Branch 12
34: Label
36: 6(int) Load 8(i)
37: 6(int) IAdd 36 19
Store 8(i) 37
Branch 13
13: Label
Branch 10
11: Label
Store 37(D) 38
12: Label
Store 38(D) 39
Return
FunctionEnd
......@@ -5,45 +5,47 @@ Linked vertex stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 23
// Id's are bound by 24
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 21 22
EntryPoint Vertex 4 "main" 22 23
Source ESSL 300
Name 4 "main"
Name 8 "i"
Name 21 "gl_VertexID"
Name 22 "gl_InstanceID"
Decorate 21(gl_VertexID) BuiltIn VertexId
Decorate 22(gl_InstanceID) BuiltIn InstanceId
Name 22 "gl_VertexID"
Name 23 "gl_InstanceID"
Decorate 22(gl_VertexID) BuiltIn VertexId
Decorate 23(gl_InstanceID) BuiltIn InstanceId
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 0
14: 6(int) Constant 10
15: TypeBool
18: 6(int) Constant 1
20: TypePointer Input 6(int)
21(gl_VertexID): 20(ptr) Variable Input
22(gl_InstanceID): 20(ptr) Variable Input
15: 6(int) Constant 10
16: TypeBool
19: 6(int) Constant 1
21: TypePointer Input 6(int)
22(gl_VertexID): 21(ptr) Variable Input
23(gl_InstanceID): 21(ptr) Variable Input
4(main): 2 Function None 3
5: Label
8(i): 7(ptr) Variable Function
Store 8(i) 9
Branch 10
10: Label
13: 6(int) Load 8(i)
16: 15(bool) SLessThan 13 14
LoopMerge 11 10 None
BranchConditional 16 12 11
12: Label
17: 6(int) Load 8(i)
19: 6(int) IAdd 17 18
Store 8(i) 19
14: 6(int) Load 8(i)
17: 16(bool) SLessThan 14 15
LoopMerge 12 13 None
BranchConditional 17 11 12
11: Label
18: 6(int) Load 8(i)
20: 6(int) IAdd 18 19
Store 8(i) 20
Branch 13
13: Label
Branch 10
11: Label
12: Label
Return
FunctionEnd
......@@ -5,20 +5,20 @@ Linked fragment stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 34
// Id's are bound by 35
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 11 32
EntryPoint Fragment 4 "main" 11 33
ExecutionMode 4 OriginLowerLeft
Source GLSL 110
Name 4 "main"
Name 9 "color"
Name 11 "BaseColor"
Name 22 "d"
Name 27 "bigColor"
Name 32 "gl_FragColor"
Name 23 "d"
Name 28 "bigColor"
Name 33 "gl_FragColor"
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
......@@ -26,16 +26,16 @@ Linked fragment stage:
8: TypePointer Function 7(fvec4)
10: TypePointer Input 7(fvec4)
11(BaseColor): 10(ptr) Variable Input
16: TypeInt 32 0
17: 16(int) Constant 0
18: TypePointer Function 6(float)
21: TypePointer UniformConstant 6(float)
22(d): 21(ptr) Variable UniformConstant
24: TypeBool
26: TypePointer UniformConstant 7(fvec4)
27(bigColor): 26(ptr) Variable UniformConstant
31: TypePointer Output 7(fvec4)
32(gl_FragColor): 31(ptr) Variable Output
17: TypeInt 32 0
18: 17(int) Constant 0
19: TypePointer Function 6(float)
22: TypePointer UniformConstant 6(float)
23(d): 22(ptr) Variable UniformConstant
25: TypeBool
27: TypePointer UniformConstant 7(fvec4)
28(bigColor): 27(ptr) Variable UniformConstant
32: TypePointer Output 7(fvec4)
33(gl_FragColor): 32(ptr) Variable Output
4(main): 2 Function None 3
5: Label
9(color): 8(ptr) Variable Function
......@@ -43,20 +43,22 @@ Linked fragment stage:
Store 9(color) 12
Branch 13
13: Label
19: 18(ptr) AccessChain 9(color) 17
20: 6(float) Load 19
23: 6(float) Load 22(d)
25: 24(bool) FOrdLessThan 20 23
LoopMerge 14 13 None
BranchConditional 25 15 14
15: Label
28: 7(fvec4) Load 27(bigColor)
29: 7(fvec4) Load 9(color)
30: 7(fvec4) FAdd 29 28
Store 9(color) 30
20: 19(ptr) AccessChain 9(color) 18
21: 6(float) Load 20
24: 6(float) Load 23(d)
26: 25(bool) FOrdLessThan 21 24
LoopMerge 15 16 None
BranchConditional 26 14 15
14: Label
29: 7(fvec4) Load 28(bigColor)
30: 7(fvec4) Load 9(color)
31: 7(fvec4) FAdd 30 29
Store 9(color) 31
Branch 16
16: Label
Branch 13
14: Label
33: 7(fvec4) Load 9(color)
Store 32(gl_FragColor) 33
15: Label
34: 7(fvec4) Load 9(color)
Store 33(gl_FragColor) 34
Return
FunctionEnd
#version 450
layout(location=0) out highp int r;
void main() {
int i;
for (i=0; i<10; i++);
r = i;
}
#version 450
layout(location=0) out highp int r;
void main() {
int i;
// This infinite loop results in bad SPIR-V generated, since the merge block
// is dropped as unreachable. It is still useful for testing the rest of the
// code generation.
for (i=0; ; i++) { r = i; }
}
......@@ -5,6 +5,8 @@ spv.do-simple.vert
spv.do-while-continue-break.vert
spv.for-continue-break.vert
spv.for-simple.vert
spv.for-notest.vert
spv.for-nobody.vert
spv.while-continue-break.vert
spv.while-simple.vert
# vulkan-specific tests
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment