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: ...@@ -144,7 +144,6 @@ protected:
std::unordered_map<const glslang::TTypeList*, spv::Id> structMap[glslang::ElpCount][glslang::ElmCount]; 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::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<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 ...@@ -1390,33 +1389,63 @@ void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* n
bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIntermLoop* node) 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" auto blocks = builder.makeNewLoop();
loopTerminal.push(node->getTerminal()); 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()) { builder.setBuildPoint(&blocks.continue_target);
node->getTest()->traverse(this); if (node->getTerminal())
// the AST only contained the test computation, not the branch, we have to add it node->getTerminal()->traverse(this);
spv::Id condition = builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType())); builder.createBranch(&blocks.head);
builder.createLoopTestBranch(condition);
} else { } 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); 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(); 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(); builder.closeLoop();
loopTerminal.pop();
return false; return false;
} }
...@@ -1436,8 +1465,6 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T ...@@ -1436,8 +1465,6 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
builder.addSwitchBreak(); builder.addSwitchBreak();
break; break;
case glslang::EOpContinue: case glslang::EOpContinue:
if (loopTerminal.top())
loopTerminal.top()->traverse(this);
builder.createLoopContinue(); builder.createLoopContinue();
break; break;
case glslang::EOpReturn: case glslang::EOpReturn:
......
...@@ -67,8 +67,9 @@ class ReadableOrderTraverser { ...@@ -67,8 +67,9 @@ class ReadableOrderTraverser {
public: public:
explicit ReadableOrderTraverser(std::function<void(Block*)> callback) : callback_(callback) {} explicit ReadableOrderTraverser(std::function<void(Block*)> callback) : callback_(callback) {}
// Visits the block if it hasn't been visited already and isn't currently // Visits the block if it hasn't been visited already and isn't currently
// being delayed. Invokes callback(block), then descends into its successors. // being delayed. Invokes callback(block), then descends into its
// Delays merge-block processing until all the branches have been completed. // successors. Delays merge-block and continue-block processing until all
// the branches have been completed.
void visit(Block* block) void visit(Block* block)
{ {
assert(block); assert(block);
...@@ -77,14 +78,25 @@ public: ...@@ -77,14 +78,25 @@ public:
callback_(block); callback_(block);
visited_[block] = true; visited_[block] = true;
Block* mergeBlock = nullptr; Block* mergeBlock = nullptr;
Block* continueBlock = nullptr;
auto mergeInst = block->getMergeInstruction(); auto mergeInst = block->getMergeInstruction();
if (mergeInst) { if (mergeInst) {
Id mergeId = mergeInst->getIdOperand(0); Id mergeId = mergeInst->getIdOperand(0);
mergeBlock = block->getParent().getParent().getInstruction(mergeId)->getBlock(); mergeBlock = block->getParent().getParent().getInstruction(mergeId)->getBlock();
delayed_[mergeBlock] = true; 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()) for (const auto succ : block->getSuccessors())
visit(succ); visit(succ);
if (continueBlock) {
delayed_[continueBlock] = false;
visit(continueBlock);
}
if (mergeBlock) { if (mergeBlock) {
delayed_[mergeBlock] = false; delayed_[mergeBlock] = false;
visit(mergeBlock); visit(mergeBlock);
......
...@@ -862,7 +862,7 @@ void Builder::leaveFunction() ...@@ -862,7 +862,7 @@ void Builder::leaveFunction()
if (unreachable) { if (unreachable) {
// Given that this block is at the end of a function, it must be right after an // Given that this block is at the end of a function, it must be right after an
// explicit return, just remove it. // explicit return, just remove it.
function.popBlock(block); function.removeBlock(block);
} else { } else {
// We'll add a return instruction at the end of the current block, // 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 // which for a non-void function is really error recovery (?), as the source
...@@ -1808,150 +1808,39 @@ void Builder::endSwitch(std::vector<Block*>& /*segmentBlock*/) ...@@ -1808,150 +1808,39 @@ void Builder::endSwitch(std::vector<Block*>& /*segmentBlock*/)
switchMerges.pop(); switchMerges.pop();
} }
// Comments in header Block& Builder::makeNewBlock()
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)
{ {
const Loop& loop = loops.top(); Function& function = buildPoint->getParent();
auto block = new Block(getUniqueId(), function);
// Generate the merge instruction. If the loop test executes before function.addBlock(block);
// the body, then this is a loop merge. Otherwise the loop merge return *block;
// 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();
}
} }
void Builder::createBranchToBody() Builder::LoopBlocks& Builder::makeNewLoop()
{ {
const Loop& loop = loops.top(); loops.push({makeNewBlock(), makeNewBlock(), makeNewBlock(), makeNewBlock()});
assert(loop.body); return loops.top();
// This is a reconvergence of control flow, so no merge instruction
// is required.
createBranch(loop.body);
loop.function->addBlock(loop.body);
setBuildPoint(loop.body);
} }
void Builder::createLoopContinue() void Builder::createLoopContinue()
{ {
createBranchToLoopHeaderFromInside(loops.top()); createBranch(&loops.top().continue_target);
// Set up a block for dead code. // Set up a block for dead code.
createAndSetNoPredecessorBlock("post-loop-continue"); createAndSetNoPredecessorBlock("post-loop-continue");
} }
// Add an exit (e.g. "break") for the innermost loop that you're in
void Builder::createLoopExit() void Builder::createLoopExit()
{ {
createBranch(loops.top().merge); createBranch(&loops.top().merge);
// Set up a block for dead code. // Set up a block for dead code.
createAndSetNoPredecessorBlock("post-loop-break"); createAndSetNoPredecessorBlock("post-loop-break");
} }
// Close the innermost loop
void Builder::closeLoop() 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(); 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() void Builder::clearAccessChain()
{ {
accessChain.base = NoResult; accessChain.base = NoResult;
...@@ -2314,24 +2203,4 @@ void MissingFunctionality(const char* fun) ...@@ -2314,24 +2203,4 @@ void MissingFunctionality(const char* fun)
printf("Missing functionality: %s\n", 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 }; // end spv namespace
...@@ -387,28 +387,24 @@ public: ...@@ -387,28 +387,24 @@ public:
// Finish off the innermost switch. // Finish off the innermost switch.
void endSwitch(std::vector<Block*>& segmentBB); void endSwitch(std::vector<Block*>& segmentBB);
// Start the beginning of a new loop, and prepare the builder to struct LoopBlocks {
// generate code for the loop test. Block &head, &body, &merge, &continue_target;
// The loopTestFirst parameter is true when the loop test executes before };
// the body. (It is false for do-while loops.)
void makeNewLoop(bool loopTestFirst); // Start a new loop and prepare the builder to generate code for it. Until
// closeLoop() is called for this loop, createLoopContinue() and
// Add the branch for the loop test, based on the given condition. // createLoopExit() will target its corresponding blocks.
// The true branch goes to the first block in the loop body, and LoopBlocks& makeNewLoop();
// the false branch goes to the loop's merge block. The builder insertion
// point will be placed at the start of the body. // Create a new block in the function containing the build point. Memory is
void createLoopTestBranch(Id condition); // owned by the function object.
Block& makeNewBlock();
// 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 // Add a branch to the continue_target of the current (innermost) loop.
// 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.
void createLoopContinue(); 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(); void createLoopExit();
// Close the innermost loop that you're in // Close the innermost loop that you're in
...@@ -508,7 +504,11 @@ public: ...@@ -508,7 +504,11 @@ public:
void dump(std::vector<unsigned int>&) const; 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 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 value) const;
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const; Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const;
...@@ -517,15 +517,9 @@ protected: ...@@ -517,15 +517,9 @@ protected:
void transferAccessChainSwizzle(bool dynamic); void transferAccessChainSwizzle(bool dynamic);
void simplifyAccessChainSwizzle(); void simplifyAccessChainSwizzle();
void createAndSetNoPredecessorBlock(const char*); void createAndSetNoPredecessorBlock(const char*);
void createBranch(Block* block);
void createSelectionMerge(Block* mergeBlock, unsigned int control); 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; 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; SourceLanguage source;
int sourceVersion; int sourceVersion;
std::vector<const char*> extensions; std::vector<const char*> extensions;
...@@ -557,47 +551,8 @@ protected: ...@@ -557,47 +551,8 @@ protected:
// stack of switches // stack of switches
std::stack<Block*> switchMerges; 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. // Our loop stack.
std::stack<Loop> loops; std::stack<LoopBlocks> loops;
}; // end Builder class }; // end Builder class
// Use for non-fatal notes about what's not complete // Use for non-fatal notes about what's not complete
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include "spirv.hpp" #include "spirv.hpp"
#include <algorithm>
#include <cassert> #include <cassert>
#include <functional> #include <functional>
#include <iostream> #include <iostream>
...@@ -259,7 +260,13 @@ public: ...@@ -259,7 +260,13 @@ public:
Id getParamId(int p) { return parameterInstructions[p]->getResultId(); } Id getParamId(int p) { return parameterInstructions[p]->getResultId(); }
void addBlock(Block* block) { blocks.push_back(block); } 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; } Module& getParent() const { return parent; }
Block* getEntryBlock() const { return blocks.front(); } Block* getEntryBlock() const { return blocks.front(); }
......
...@@ -8,64 +8,66 @@ Linked vertex stage: ...@@ -8,64 +8,66 @@ Linked vertex stage:
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 38 // Id's are bound by 39
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 23 26 32 37 EntryPoint Vertex 4 "main" 24 27 33 38
Source GLSL 130 Source GLSL 130
Name 4 "main" Name 4 "main"
Name 8 "i" Name 8 "i"
Name 23 "colorOut" Name 24 "colorOut"
Name 26 "color" Name 27 "color"
Name 32 "gl_Position" Name 33 "gl_Position"
Name 37 "gl_VertexID" Name 38 "gl_VertexID"
Decorate 32(gl_Position) BuiltIn Position Decorate 33(gl_Position) BuiltIn Position
Decorate 37(gl_VertexID) BuiltIn VertexId Decorate 38(gl_VertexID) BuiltIn VertexId
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 1 6: TypeInt 32 1
7: TypePointer Function 6(int) 7: TypePointer Function 6(int)
9: 6(int) Constant 1 9: 6(int) Constant 1
14: 6(int) Constant 5 15: 6(int) Constant 5
15: TypeBool 16: TypeBool
17: TypeFloat 32 18: TypeFloat 32
18: TypeVector 17(float) 4 19: TypeVector 18(float) 4
19: TypeInt 32 0 20: TypeInt 32 0
20: 19(int) Constant 6 21: 20(int) Constant 6
21: TypeArray 18(fvec4) 20 22: TypeArray 19(fvec4) 21
22: TypePointer Output 21 23: TypePointer Output 22
23(colorOut): 22(ptr) Variable Output 24(colorOut): 23(ptr) Variable Output
25: TypePointer Input 18(fvec4) 26: TypePointer Input 19(fvec4)
26(color): 25(ptr) Variable Input 27(color): 26(ptr) Variable Input
28: TypePointer Output 18(fvec4) 29: TypePointer Output 19(fvec4)
32(gl_Position): 28(ptr) Variable Output 33(gl_Position): 29(ptr) Variable Output
33: 6(int) Constant 2 34: 6(int) Constant 2
36: TypePointer Input 6(int) 37: TypePointer Input 6(int)
37(gl_VertexID): 36(ptr) Variable Input 38(gl_VertexID): 37(ptr) Variable Input
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
8(i): 7(ptr) Variable Function 8(i): 7(ptr) Variable Function
Store 8(i) 9 Store 8(i) 9
Branch 10 Branch 10
10: Label 10: Label
13: 6(int) Load 8(i) 14: 6(int) Load 8(i)
16: 15(bool) SLessThan 13 14 17: 16(bool) SLessThan 14 15
LoopMerge 11 10 None LoopMerge 12 13 None
BranchConditional 16 12 11 BranchConditional 17 11 12
12: Label 11: Label
24: 6(int) Load 8(i) 25: 6(int) Load 8(i)
27: 18(fvec4) Load 26(color) 28: 19(fvec4) Load 27(color)
29: 28(ptr) AccessChain 23(colorOut) 24 30: 29(ptr) AccessChain 24(colorOut) 25
Store 29 27 Store 30 28
30: 6(int) Load 8(i) Branch 13
31: 6(int) IAdd 30 9 13: Label
Store 8(i) 31 31: 6(int) Load 8(i)
32: 6(int) IAdd 31 9
Store 8(i) 32
Branch 10 Branch 10
11: Label 12: Label
34: 28(ptr) AccessChain 23(colorOut) 33 35: 29(ptr) AccessChain 24(colorOut) 34
35: 18(fvec4) Load 34 36: 19(fvec4) Load 35
Store 32(gl_Position) 35 Store 33(gl_Position) 36
Return Return
FunctionEnd FunctionEnd
...@@ -5,56 +5,47 @@ Linked vertex stage: ...@@ -5,56 +5,47 @@ Linked vertex stage:
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 29 // Id's are bound by 24
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 27 28 EntryPoint Vertex 4 "main" 22 23
Source ESSL 300 Source ESSL 300
Name 4 "main" Name 4 "main"
Name 8 "i" Name 8 "i"
Name 27 "gl_VertexID" Name 22 "gl_VertexID"
Name 28 "gl_InstanceID" Name 23 "gl_InstanceID"
Decorate 27(gl_VertexID) BuiltIn VertexId Decorate 22(gl_VertexID) BuiltIn VertexId
Decorate 28(gl_InstanceID) BuiltIn InstanceId Decorate 23(gl_InstanceID) BuiltIn InstanceId
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 1 6: TypeInt 32 1
7: TypePointer Function 6(int) 7: TypePointer Function 6(int)
9: 6(int) Constant 0 9: 6(int) Constant 0
14: TypeBool 15: 6(int) Constant 1
15: 14(bool) ConstantTrue 18: 6(int) Constant 10
19: 6(int) Constant 10 19: TypeBool
23: 6(int) Constant 1 21: TypePointer Input 6(int)
25: 14(bool) ConstantFalse 22(gl_VertexID): 21(ptr) Variable Input
26: TypePointer Input 6(int) 23(gl_InstanceID): 21(ptr) Variable Input
27(gl_VertexID): 26(ptr) Variable Input
28(gl_InstanceID): 26(ptr) Variable Input
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
8(i): 7(ptr) Variable Function 8(i): 7(ptr) Variable Function
Store 8(i) 9 Store 8(i) 9
Branch 10 Branch 10
10: Label 10: Label
13: 14(bool) Phi 15 5 25 12 LoopMerge 12 13 None
LoopMerge 11 10 None Branch 11
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
11: Label 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 Return
FunctionEnd FunctionEnd
...@@ -5,94 +5,85 @@ Linked vertex stage: ...@@ -5,94 +5,85 @@ Linked vertex stage:
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 51 // Id's are bound by 46
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 49 50 EntryPoint Vertex 4 "main" 44 45
Source ESSL 300 Source ESSL 300
Name 4 "main" Name 4 "main"
Name 8 "i" Name 8 "i"
Name 24 "A" Name 14 "A"
Name 30 "B" Name 21 "B"
Name 33 "C" Name 24 "C"
Name 39 "D" Name 30 "D"
Name 42 "E" Name 33 "E"
Name 44 "F" Name 35 "F"
Name 46 "G" Name 41 "G"
Name 49 "gl_VertexID" Name 44 "gl_VertexID"
Name 50 "gl_InstanceID" Name 45 "gl_InstanceID"
Decorate 49(gl_VertexID) BuiltIn VertexId Decorate 44(gl_VertexID) BuiltIn VertexId
Decorate 50(gl_InstanceID) BuiltIn InstanceId Decorate 45(gl_InstanceID) BuiltIn InstanceId
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 1 6: TypeInt 32 1
7: TypePointer Function 6(int) 7: TypePointer Function 6(int)
9: 6(int) Constant 0 9: 6(int) Constant 0
14: TypeBool 16: 6(int) Constant 2
15: 14(bool) ConstantTrue 17: TypeBool
19: 6(int) Constant 1 22: 6(int) Constant 1
21: 6(int) Constant 19 26: 6(int) Constant 5
26: 6(int) Constant 2 31: 6(int) Constant 3
31: 14(bool) ConstantFalse 34: 6(int) Constant 42
35: 6(int) Constant 5 36: 6(int) Constant 99
40: 6(int) Constant 3 39: 6(int) Constant 19
43: 6(int) Constant 42 42: 6(int) Constant 12
45: 6(int) Constant 99 43: TypePointer Input 6(int)
47: 6(int) Constant 12 44(gl_VertexID): 43(ptr) Variable Input
48: TypePointer Input 6(int) 45(gl_InstanceID): 43(ptr) Variable Input
49(gl_VertexID): 48(ptr) Variable Input
50(gl_InstanceID): 48(ptr) Variable Input
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
8(i): 7(ptr) Variable Function 8(i): 7(ptr) Variable Function
24(A): 7(ptr) Variable Function 14(A): 7(ptr) Variable Function
30(B): 7(ptr) Variable Function 21(B): 7(ptr) Variable Function
33(C): 7(ptr) Variable Function 24(C): 7(ptr) Variable Function
39(D): 7(ptr) Variable Function 30(D): 7(ptr) Variable Function
42(E): 7(ptr) Variable Function 33(E): 7(ptr) Variable Function
44(F): 7(ptr) Variable Function 35(F): 7(ptr) Variable Function
46(G): 7(ptr) Variable Function 41(G): 7(ptr) Variable Function
Store 8(i) 9 Store 8(i) 9
Branch 10 Branch 10
10: Label 10: Label
13: 14(bool) Phi 15 5 31 28 31 38 LoopMerge 12 13 None
LoopMerge 11 10 None Branch 11
Branch 16 11: Label
16: Label Store 14(A) 9
SelectionMerge 12 None 15: 6(int) Load 8(i)
BranchConditional 13 12 17 18: 17(bool) IEqual 15 16
17: Label SelectionMerge 20 None
18: 6(int) Load 8(i) BranchConditional 18 19 20
20: 6(int) IAdd 18 19 19: Label
Store 8(i) 20 Store 21(B) 22
22: 14(bool) SLessThan 20 21 Branch 13
SelectionMerge 23 None 20: Label
BranchConditional 22 23 11
23: Label
Branch 12
12: Label
Store 24(A) 9
25: 6(int) Load 8(i) 25: 6(int) Load 8(i)
27: 14(bool) IEqual 25 26 27: 17(bool) IEqual 25 26
SelectionMerge 29 None SelectionMerge 29 None
BranchConditional 27 28 29 BranchConditional 27 28 29
28: Label 28: Label
Store 30(B) 19 Store 30(D) 31
Branch 10 Branch 12
29: Label 29: Label
34: 6(int) Load 8(i) Store 35(F) 36
36: 14(bool) IEqual 34 35 Branch 13
SelectionMerge 38 None 13: Label
BranchConditional 36 37 38 37: 6(int) Load 8(i)
37: Label 38: 6(int) IAdd 37 22
Store 39(D) 40 Store 8(i) 38
Branch 11 40: 17(bool) SLessThan 38 39
38: Label BranchConditional 40 10 12
Store 44(F) 45 12: Label
Branch 10 Store 41(G) 42
11: Label
Store 46(G) 47
Return Return
FunctionEnd FunctionEnd
...@@ -5,20 +5,20 @@ Linked fragment stage: ...@@ -5,20 +5,20 @@ Linked fragment stage:
// 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 35
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 11 38 EntryPoint Fragment 4 "main" 11 33
ExecutionMode 4 OriginLowerLeft ExecutionMode 4 OriginLowerLeft
Source GLSL 110 Source GLSL 110
Name 4 "main" Name 4 "main"
Name 9 "color" Name 9 "color"
Name 11 "BaseColor" Name 11 "BaseColor"
Name 27 "d" Name 18 "bigColor"
Name 32 "bigColor" Name 28 "d"
Name 38 "gl_FragColor" Name 33 "gl_FragColor"
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeFloat 32 6: TypeFloat 32
...@@ -26,18 +26,16 @@ Linked fragment stage: ...@@ -26,18 +26,16 @@ Linked fragment stage:
8: TypePointer Function 7(fvec4) 8: TypePointer Function 7(fvec4)
10: TypePointer Input 7(fvec4) 10: TypePointer Input 7(fvec4)
11(BaseColor): 10(ptr) Variable Input 11(BaseColor): 10(ptr) Variable Input
17: TypeBool 17: TypePointer UniformConstant 7(fvec4)
18: 17(bool) ConstantTrue 18(bigColor): 17(ptr) Variable UniformConstant
21: TypeInt 32 0 22: TypeInt 32 0
22: 21(int) Constant 0 23: 22(int) Constant 0
23: TypePointer Function 6(float) 24: TypePointer Function 6(float)
26: TypePointer UniformConstant 6(float) 27: TypePointer UniformConstant 6(float)
27(d): 26(ptr) Variable UniformConstant 28(d): 27(ptr) Variable UniformConstant
31: TypePointer UniformConstant 7(fvec4) 30: TypeBool
32(bigColor): 31(ptr) Variable UniformConstant 32: TypePointer Output 7(fvec4)
36: 17(bool) ConstantFalse 33(gl_FragColor): 32(ptr) Variable Output
37: TypePointer Output 7(fvec4)
38(gl_FragColor): 37(ptr) Variable Output
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
9(color): 8(ptr) Variable Function 9(color): 8(ptr) Variable Function
...@@ -45,29 +43,22 @@ Linked fragment stage: ...@@ -45,29 +43,22 @@ Linked fragment stage:
Store 9(color) 12 Store 9(color) 12
Branch 13 Branch 13
13: Label 13: Label
16: 17(bool) Phi 18 5 36 15 LoopMerge 15 16 None
LoopMerge 14 13 None Branch 14
Branch 19 14: Label
19: Label 19: 7(fvec4) Load 18(bigColor)
SelectionMerge 15 None 20: 7(fvec4) Load 9(color)
BranchConditional 16 15 20 21: 7(fvec4) FAdd 20 19
20: Label Store 9(color) 21
24: 23(ptr) AccessChain 9(color) 22 Branch 16
25: 6(float) Load 24 16: Label
28: 6(float) Load 27(d) 25: 24(ptr) AccessChain 9(color) 23
29: 17(bool) FOrdLessThan 25 28 26: 6(float) Load 25
SelectionMerge 30 None 29: 6(float) Load 28(d)
BranchConditional 29 30 14 31: 30(bool) FOrdLessThan 26 29
30: Label BranchConditional 31 13 15
Branch 15
15: Label 15: Label
33: 7(fvec4) Load 32(bigColor)
34: 7(fvec4) Load 9(color) 34: 7(fvec4) Load 9(color)
35: 7(fvec4) FAdd 34 33 Store 33(gl_FragColor) 34
Store 9(color) 35
Branch 13
14: Label
39: 7(fvec4) Load 9(color)
Store 38(gl_FragColor) 39
Return Return
FunctionEnd FunctionEnd
...@@ -5,87 +5,86 @@ Linked vertex stage: ...@@ -5,87 +5,86 @@ Linked vertex stage:
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 48 // Id's are bound by 47
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 46 47 EntryPoint Vertex 4 "main" 45 46
Source ESSL 300 Source ESSL 300
Name 4 "main" Name 4 "main"
Name 8 "i" Name 8 "i"
Name 17 "A" Name 18 "A"
Name 25 "B" Name 26 "B"
Name 29 "C" Name 28 "C"
Name 36 "D" Name 35 "D"
Name 38 "E" Name 37 "E"
Name 39 "F" Name 38 "F"
Name 43 "G" Name 42 "G"
Name 46 "gl_VertexID" Name 45 "gl_VertexID"
Name 47 "gl_InstanceID" Name 46 "gl_InstanceID"
Decorate 46(gl_VertexID) BuiltIn VertexId Decorate 45(gl_VertexID) BuiltIn VertexId
Decorate 47(gl_InstanceID) BuiltIn InstanceId Decorate 46(gl_InstanceID) BuiltIn InstanceId
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 1 6: TypeInt 32 1
7: TypePointer Function 6(int) 7: TypePointer Function 6(int)
9: 6(int) Constant 0 9: 6(int) Constant 0
14: 6(int) Constant 10 15: 6(int) Constant 10
15: TypeBool 16: TypeBool
18: 6(int) Constant 1 19: 6(int) Constant 1
20: 6(int) Constant 2 21: 6(int) Constant 2
31: 6(int) Constant 3 30: 6(int) Constant 3
40: 6(int) Constant 12 39: 6(int) Constant 12
44: 6(int) Constant 99 43: 6(int) Constant 99
45: TypePointer Input 6(int) 44: TypePointer Input 6(int)
46(gl_VertexID): 45(ptr) Variable Input 45(gl_VertexID): 44(ptr) Variable Input
47(gl_InstanceID): 45(ptr) Variable Input 46(gl_InstanceID): 44(ptr) Variable Input
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
8(i): 7(ptr) Variable Function 8(i): 7(ptr) Variable Function
17(A): 7(ptr) Variable Function 18(A): 7(ptr) Variable Function
25(B): 7(ptr) Variable Function 26(B): 7(ptr) Variable Function
29(C): 7(ptr) Variable Function 28(C): 7(ptr) Variable Function
36(D): 7(ptr) Variable Function 35(D): 7(ptr) Variable Function
38(E): 7(ptr) Variable Function 37(E): 7(ptr) Variable Function
39(F): 7(ptr) Variable Function 38(F): 7(ptr) Variable Function
43(G): 7(ptr) Variable Function 42(G): 7(ptr) Variable Function
Store 8(i) 9 Store 8(i) 9
Branch 10 Branch 10
10: Label 10: Label
13: 6(int) Load 8(i) 14: 6(int) Load 8(i)
16: 15(bool) SLessThan 13 14 17: 16(bool) SLessThan 14 15
LoopMerge 11 10 None LoopMerge 12 13 None
BranchConditional 16 12 11 BranchConditional 17 11 12
12: Label 11: Label
Store 17(A) 18 Store 18(A) 19
19: 6(int) Load 8(i) 20: 6(int) Load 8(i)
21: 6(int) SMod 19 20 22: 6(int) SMod 20 21
22: 15(bool) IEqual 21 9 23: 16(bool) IEqual 22 9
SelectionMerge 24 None SelectionMerge 25 None
BranchConditional 22 23 24 BranchConditional 23 24 25
23: Label 24: Label
Store 25(B) 18 Store 26(B) 19
26: 6(int) Load 8(i) Branch 13
27: 6(int) IAdd 26 18 25: Label
Store 8(i) 27 29: 6(int) Load 8(i)
Branch 10 31: 6(int) SMod 29 30
24: Label 32: 16(bool) IEqual 31 9
30: 6(int) Load 8(i) SelectionMerge 34 None
32: 6(int) SMod 30 31 BranchConditional 32 33 34
33: 15(bool) IEqual 32 9 33: Label
SelectionMerge 35 None Store 35(D) 19
BranchConditional 33 34 35 Branch 12
34: Label 34: Label
Store 36(D) 18 Store 38(F) 39
Branch 11 Branch 13
35: Label 13: Label
Store 39(F) 40 40: 6(int) Load 8(i)
41: 6(int) Load 8(i) 41: 6(int) IAdd 40 19
42: 6(int) IAdd 41 18 Store 8(i) 41
Store 8(i) 42
Branch 10 Branch 10
11: Label 12: Label
Store 43(G) 44 Store 42(G) 43
Return Return
FunctionEnd 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: ...@@ -5,49 +5,51 @@ Linked vertex stage:
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 25 // Id's are bound by 26
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 23 24 EntryPoint Vertex 4 "main" 24 25
Source ESSL 300 Source ESSL 300
Name 4 "main" Name 4 "main"
Name 8 "i" Name 8 "i"
Name 17 "j" Name 18 "j"
Name 23 "gl_VertexID" Name 24 "gl_VertexID"
Name 24 "gl_InstanceID" Name 25 "gl_InstanceID"
Decorate 23(gl_VertexID) BuiltIn VertexId Decorate 24(gl_VertexID) BuiltIn VertexId
Decorate 24(gl_InstanceID) BuiltIn InstanceId Decorate 25(gl_InstanceID) BuiltIn InstanceId
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 1 6: TypeInt 32 1
7: TypePointer Function 6(int) 7: TypePointer Function 6(int)
9: 6(int) Constant 0 9: 6(int) Constant 0
14: 6(int) Constant 10 15: 6(int) Constant 10
15: TypeBool 16: TypeBool
18: 6(int) Constant 12 19: 6(int) Constant 12
20: 6(int) Constant 1 21: 6(int) Constant 1
22: TypePointer Input 6(int) 23: TypePointer Input 6(int)
23(gl_VertexID): 22(ptr) Variable Input 24(gl_VertexID): 23(ptr) Variable Input
24(gl_InstanceID): 22(ptr) Variable Input 25(gl_InstanceID): 23(ptr) Variable Input
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
8(i): 7(ptr) Variable Function 8(i): 7(ptr) Variable Function
17(j): 7(ptr) Variable Function 18(j): 7(ptr) Variable Function
Store 8(i) 9 Store 8(i) 9
Branch 10 Branch 10
10: Label 10: Label
13: 6(int) Load 8(i) 14: 6(int) Load 8(i)
16: 15(bool) SLessThan 13 14 17: 16(bool) SLessThan 14 15
LoopMerge 11 10 None LoopMerge 12 13 None
BranchConditional 16 12 11 BranchConditional 17 11 12
12: Label 11: Label
Store 17(j) 18 Store 18(j) 19
19: 6(int) Load 8(i) Branch 13
21: 6(int) IAdd 19 20 13: Label
Store 8(i) 21 20: 6(int) Load 8(i)
22: 6(int) IAdd 20 21
Store 8(i) 22
Branch 10 Branch 10
11: Label 12: Label
Return Return
FunctionEnd FunctionEnd
...@@ -8,12 +8,12 @@ Linked fragment stage: ...@@ -8,12 +8,12 @@ Linked fragment stage:
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 136 // Id's are bound by 137
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 40 96 106 EntryPoint Fragment 4 "main" 40 97 107
ExecutionMode 4 OriginLowerLeft ExecutionMode 4 OriginLowerLeft
Source GLSL 130 Source GLSL 130
Name 4 "main" Name 4 "main"
...@@ -38,14 +38,14 @@ Linked fragment stage: ...@@ -38,14 +38,14 @@ Linked fragment stage:
Name 68 "x" Name 68 "x"
Name 70 "localArray" Name 70 "localArray"
Name 75 "i" Name 75 "i"
Name 82 "a" Name 83 "a"
Name 88 "condition" Name 89 "condition"
Name 96 "color" Name 97 "color"
Name 106 "gl_FragColor" Name 107 "gl_FragColor"
Name 126 "samp2D" Name 127 "samp2D"
Name 132 "foo" Name 133 "foo"
Name 133 "foo2" Name 134 "foo2"
Name 135 "uFloatArray" Name 136 "uFloatArray"
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 1 6: TypeInt 32 1
...@@ -80,26 +80,26 @@ Linked fragment stage: ...@@ -80,26 +80,26 @@ Linked fragment stage:
48: TypePointer Function 47 48: TypePointer Function 47
52: TypePointer Function 6(int) 52: TypePointer Function 6(int)
69: 6(int) Constant 5 69: 6(int) Constant 5
80: 6(int) Constant 16 81: 6(int) Constant 16
84: 7(float) Constant 0 85: 7(float) Constant 0
88(condition): 20(ptr) Variable UniformConstant 89(condition): 20(ptr) Variable UniformConstant
94: 6(int) Constant 3 95: 6(int) Constant 3
95: TypePointer Input 9(fvec4) 96: TypePointer Input 9(fvec4)
96(color): 95(ptr) Variable Input 97(color): 96(ptr) Variable Input
98: TypePointer Function 9(fvec4) 99: TypePointer Function 9(fvec4)
100: 32(int) Constant 1 101: 32(int) Constant 1
103: 32(int) Constant 2 104: 32(int) Constant 2
105: TypePointer Output 9(fvec4) 106: TypePointer Output 9(fvec4)
106(gl_FragColor): 105(ptr) Variable Output 107(gl_FragColor): 106(ptr) Variable Output
123: TypeImage 7(float) 2D sampled format:Unknown 124: TypeImage 7(float) 2D sampled format:Unknown
124: TypeSampledImage 123 125: TypeSampledImage 124
125: TypePointer UniformConstant 124 126: TypePointer UniformConstant 125
126(samp2D): 125(ptr) Variable UniformConstant 127(samp2D): 126(ptr) Variable UniformConstant
131: TypePointer UniformConstant 8(s1) 132: TypePointer UniformConstant 8(s1)
132(foo): 131(ptr) Variable UniformConstant 133(foo): 132(ptr) Variable UniformConstant
133(foo2): 17(ptr) Variable UniformConstant 134(foo2): 17(ptr) Variable UniformConstant
134: TypePointer UniformConstant 34 135: TypePointer UniformConstant 34
135(uFloatArray): 134(ptr) Variable UniformConstant 136(uFloatArray): 135(ptr) Variable UniformConstant
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
12(locals2): 11(ptr) Variable Function 12(locals2): 11(ptr) Variable Function
...@@ -108,7 +108,7 @@ Linked fragment stage: ...@@ -108,7 +108,7 @@ Linked fragment stage:
68(x): 52(ptr) Variable Function 68(x): 52(ptr) Variable Function
70(localArray): 35(ptr) Variable Function 70(localArray): 35(ptr) Variable Function
75(i): 52(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 18: 17(ptr) AccessChain 15(foo3) 16
19: 10(s2) Load 18 19: 10(s2) Load 18
Store 12(locals2) 19 Store 12(locals2) 19
...@@ -161,55 +161,57 @@ Linked fragment stage: ...@@ -161,55 +161,57 @@ Linked fragment stage:
Store 75(i) 16 Store 75(i) 16
Branch 76 Branch 76
76: Label 76: Label
79: 6(int) Load 75(i) 80: 6(int) Load 75(i)
81: 23(bool) SLessThan 79 80 82: 23(bool) SLessThan 80 81
LoopMerge 77 76 None LoopMerge 78 79 None
BranchConditional 81 78 77 BranchConditional 82 77 78
78: Label 77: Label
83: 6(int) Load 75(i) 84: 6(int) Load 75(i)
85: 30(ptr) AccessChain 82(a) 83 86: 30(ptr) AccessChain 83(a) 84
Store 85 84 Store 86 85
86: 6(int) Load 75(i) Branch 79
87: 6(int) IAdd 86 28 79: Label
Store 75(i) 87 87: 6(int) Load 75(i)
88: 6(int) IAdd 87 28
Store 75(i) 88
Branch 76 Branch 76
77: Label 78: Label
89: 6(int) Load 88(condition) 90: 6(int) Load 89(condition)
90: 23(bool) IEqual 89 28 91: 23(bool) IEqual 90 28
SelectionMerge 92 None SelectionMerge 93 None
BranchConditional 90 91 92 BranchConditional 91 92 93
91: Label 92: Label
93: 34 Load 70(localArray) 94: 34 Load 70(localArray)
Store 82(a) 93 Store 83(a) 94
Branch 92 Branch 93
92: Label 93: Label
97: 9(fvec4) Load 96(color) 98: 9(fvec4) Load 97(color)
99: 98(ptr) AccessChain 12(locals2) 94 100: 99(ptr) AccessChain 12(locals2) 95
Store 99 97 Store 100 98
101: 42(ptr) AccessChain 40(coord) 100 102: 42(ptr) AccessChain 40(coord) 101
102: 7(float) Load 101 103: 7(float) Load 102
104: 30(ptr) AccessChain 12(locals2) 94 103 105: 30(ptr) AccessChain 12(locals2) 95 104
Store 104 102 Store 105 103
107: 98(ptr) AccessChain 12(locals2) 94 108: 99(ptr) AccessChain 12(locals2) 95
108: 9(fvec4) Load 107 109: 9(fvec4) Load 108
109: 30(ptr) AccessChain 36(localFArray) 37 110: 30(ptr) AccessChain 36(localFArray) 37
110: 7(float) Load 109 111: 7(float) Load 110
111: 30(ptr) AccessChain 12(locals2) 27 28 112: 30(ptr) AccessChain 12(locals2) 27 28
112: 7(float) Load 111 113: 7(float) Load 112
113: 7(float) FAdd 110 112 114: 7(float) FAdd 111 113
114: 6(int) Load 68(x) 115: 6(int) Load 68(x)
115: 30(ptr) AccessChain 70(localArray) 114 116: 30(ptr) AccessChain 70(localArray) 115
116: 7(float) Load 115 117: 7(float) Load 116
117: 7(float) FAdd 113 116 118: 7(float) FAdd 114 117
118: 6(int) Load 68(x) 119: 6(int) Load 68(x)
119: 30(ptr) AccessChain 82(a) 118 120: 30(ptr) AccessChain 83(a) 119
120: 7(float) Load 119 121: 7(float) Load 120
121: 7(float) FAdd 117 120 122: 7(float) FAdd 118 121
122: 9(fvec4) VectorTimesScalar 108 121 123: 9(fvec4) VectorTimesScalar 109 122
127: 124 Load 126(samp2D) 128: 125 Load 127(samp2D)
128: 38(fvec2) Load 40(coord) 129: 38(fvec2) Load 40(coord)
129: 9(fvec4) ImageSampleImplicitLod 127 128 130: 9(fvec4) ImageSampleImplicitLod 128 129
130: 9(fvec4) FMul 122 129 131: 9(fvec4) FMul 123 130
Store 106(gl_FragColor) 130 Store 107(gl_FragColor) 131
Return Return
FunctionEnd FunctionEnd
...@@ -5,76 +5,78 @@ Linked vertex stage: ...@@ -5,76 +5,78 @@ Linked vertex stage:
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 42 // Id's are bound by 43
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 40 41 EntryPoint Vertex 4 "main" 41 42
Source ESSL 300 Source ESSL 300
Name 4 "main" Name 4 "main"
Name 8 "i" Name 8 "i"
Name 17 "A" Name 18 "A"
Name 25 "B" Name 26 "B"
Name 27 "C" Name 28 "C"
Name 37 "D" Name 38 "D"
Name 40 "gl_VertexID" Name 41 "gl_VertexID"
Name 41 "gl_InstanceID" Name 42 "gl_InstanceID"
Decorate 40(gl_VertexID) BuiltIn VertexId Decorate 41(gl_VertexID) BuiltIn VertexId
Decorate 41(gl_InstanceID) BuiltIn InstanceId Decorate 42(gl_InstanceID) BuiltIn InstanceId
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 1 6: TypeInt 32 1
7: TypePointer Function 6(int) 7: TypePointer Function 6(int)
9: 6(int) Constant 0 9: 6(int) Constant 0
14: 6(int) Constant 10 15: 6(int) Constant 10
15: TypeBool 16: TypeBool
18: 6(int) Constant 1 19: 6(int) Constant 1
20: 6(int) Constant 2 21: 6(int) Constant 2
29: 6(int) Constant 5 30: 6(int) Constant 5
38: 6(int) Constant 3 39: 6(int) Constant 3
39: TypePointer Input 6(int) 40: TypePointer Input 6(int)
40(gl_VertexID): 39(ptr) Variable Input 41(gl_VertexID): 40(ptr) Variable Input
41(gl_InstanceID): 39(ptr) Variable Input 42(gl_InstanceID): 40(ptr) Variable Input
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
8(i): 7(ptr) Variable Function 8(i): 7(ptr) Variable Function
17(A): 7(ptr) Variable Function 18(A): 7(ptr) Variable Function
25(B): 7(ptr) Variable Function 26(B): 7(ptr) Variable Function
27(C): 7(ptr) Variable Function 28(C): 7(ptr) Variable Function
37(D): 7(ptr) Variable Function 38(D): 7(ptr) Variable Function
Store 8(i) 9 Store 8(i) 9
Branch 10 Branch 10
10: Label 10: Label
13: 6(int) Load 8(i) 14: 6(int) Load 8(i)
16: 15(bool) SLessThan 13 14 17: 16(bool) SLessThan 14 15
LoopMerge 11 10 None LoopMerge 12 13 None
BranchConditional 16 12 11 BranchConditional 17 11 12
12: Label 11: Label
Store 17(A) 18 Store 18(A) 19
19: 6(int) Load 8(i) 20: 6(int) Load 8(i)
21: 6(int) SMod 19 20 22: 6(int) SMod 20 21
22: 15(bool) IEqual 21 9 23: 16(bool) IEqual 22 9
SelectionMerge 24 None SelectionMerge 25 None
BranchConditional 22 23 24 BranchConditional 23 24 25
23: Label 24: Label
Store 25(B) 20 Store 26(B) 21
Branch 10 Branch 13
24: Label 25: Label
28: 6(int) Load 8(i) 29: 6(int) Load 8(i)
30: 6(int) SMod 28 29 31: 6(int) SMod 29 30
31: 15(bool) IEqual 30 9 32: 16(bool) IEqual 31 9
SelectionMerge 33 None SelectionMerge 34 None
BranchConditional 31 32 33 BranchConditional 32 33 34
32: Label 33: Label
Store 25(B) 20 Store 26(B) 21
Branch 11 Branch 12
33: Label 34: Label
35: 6(int) Load 8(i) 36: 6(int) Load 8(i)
36: 6(int) IAdd 35 18 37: 6(int) IAdd 36 19
Store 8(i) 36 Store 8(i) 37
Branch 13
13: Label
Branch 10 Branch 10
11: Label 12: Label
Store 37(D) 38 Store 38(D) 39
Return Return
FunctionEnd FunctionEnd
...@@ -5,45 +5,47 @@ Linked vertex stage: ...@@ -5,45 +5,47 @@ Linked vertex stage:
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 23 // Id's are bound by 24
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 21 22 EntryPoint Vertex 4 "main" 22 23
Source ESSL 300 Source ESSL 300
Name 4 "main" Name 4 "main"
Name 8 "i" Name 8 "i"
Name 21 "gl_VertexID" Name 22 "gl_VertexID"
Name 22 "gl_InstanceID" Name 23 "gl_InstanceID"
Decorate 21(gl_VertexID) BuiltIn VertexId Decorate 22(gl_VertexID) BuiltIn VertexId
Decorate 22(gl_InstanceID) BuiltIn InstanceId Decorate 23(gl_InstanceID) BuiltIn InstanceId
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 1 6: TypeInt 32 1
7: TypePointer Function 6(int) 7: TypePointer Function 6(int)
9: 6(int) Constant 0 9: 6(int) Constant 0
14: 6(int) Constant 10 15: 6(int) Constant 10
15: TypeBool 16: TypeBool
18: 6(int) Constant 1 19: 6(int) Constant 1
20: TypePointer Input 6(int) 21: TypePointer Input 6(int)
21(gl_VertexID): 20(ptr) Variable Input 22(gl_VertexID): 21(ptr) Variable Input
22(gl_InstanceID): 20(ptr) Variable Input 23(gl_InstanceID): 21(ptr) Variable Input
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
8(i): 7(ptr) Variable Function 8(i): 7(ptr) Variable Function
Store 8(i) 9 Store 8(i) 9
Branch 10 Branch 10
10: Label 10: Label
13: 6(int) Load 8(i) 14: 6(int) Load 8(i)
16: 15(bool) SLessThan 13 14 17: 16(bool) SLessThan 14 15
LoopMerge 11 10 None LoopMerge 12 13 None
BranchConditional 16 12 11 BranchConditional 17 11 12
12: Label 11: Label
17: 6(int) Load 8(i) 18: 6(int) Load 8(i)
19: 6(int) IAdd 17 18 20: 6(int) IAdd 18 19
Store 8(i) 19 Store 8(i) 20
Branch 13
13: Label
Branch 10 Branch 10
11: Label 12: Label
Return Return
FunctionEnd FunctionEnd
...@@ -5,20 +5,20 @@ Linked fragment stage: ...@@ -5,20 +5,20 @@ Linked fragment stage:
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 34 // Id's are bound by 35
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 11 32 EntryPoint Fragment 4 "main" 11 33
ExecutionMode 4 OriginLowerLeft ExecutionMode 4 OriginLowerLeft
Source GLSL 110 Source GLSL 110
Name 4 "main" Name 4 "main"
Name 9 "color" Name 9 "color"
Name 11 "BaseColor" Name 11 "BaseColor"
Name 22 "d" Name 23 "d"
Name 27 "bigColor" Name 28 "bigColor"
Name 32 "gl_FragColor" Name 33 "gl_FragColor"
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeFloat 32 6: TypeFloat 32
...@@ -26,16 +26,16 @@ Linked fragment stage: ...@@ -26,16 +26,16 @@ Linked fragment stage:
8: TypePointer Function 7(fvec4) 8: TypePointer Function 7(fvec4)
10: TypePointer Input 7(fvec4) 10: TypePointer Input 7(fvec4)
11(BaseColor): 10(ptr) Variable Input 11(BaseColor): 10(ptr) Variable Input
16: TypeInt 32 0 17: TypeInt 32 0
17: 16(int) Constant 0 18: 17(int) Constant 0
18: TypePointer Function 6(float) 19: TypePointer Function 6(float)
21: TypePointer UniformConstant 6(float) 22: TypePointer UniformConstant 6(float)
22(d): 21(ptr) Variable UniformConstant 23(d): 22(ptr) Variable UniformConstant
24: TypeBool 25: TypeBool
26: TypePointer UniformConstant 7(fvec4) 27: TypePointer UniformConstant 7(fvec4)
27(bigColor): 26(ptr) Variable UniformConstant 28(bigColor): 27(ptr) Variable UniformConstant
31: TypePointer Output 7(fvec4) 32: TypePointer Output 7(fvec4)
32(gl_FragColor): 31(ptr) Variable Output 33(gl_FragColor): 32(ptr) Variable Output
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
9(color): 8(ptr) Variable Function 9(color): 8(ptr) Variable Function
...@@ -43,20 +43,22 @@ Linked fragment stage: ...@@ -43,20 +43,22 @@ Linked fragment stage:
Store 9(color) 12 Store 9(color) 12
Branch 13 Branch 13
13: Label 13: Label
19: 18(ptr) AccessChain 9(color) 17 20: 19(ptr) AccessChain 9(color) 18
20: 6(float) Load 19 21: 6(float) Load 20
23: 6(float) Load 22(d) 24: 6(float) Load 23(d)
25: 24(bool) FOrdLessThan 20 23 26: 25(bool) FOrdLessThan 21 24
LoopMerge 14 13 None LoopMerge 15 16 None
BranchConditional 25 15 14 BranchConditional 26 14 15
15: Label 14: Label
28: 7(fvec4) Load 27(bigColor) 29: 7(fvec4) Load 28(bigColor)
29: 7(fvec4) Load 9(color) 30: 7(fvec4) Load 9(color)
30: 7(fvec4) FAdd 29 28 31: 7(fvec4) FAdd 30 29
Store 9(color) 30 Store 9(color) 31
Branch 16
16: Label
Branch 13 Branch 13
14: Label 15: Label
33: 7(fvec4) Load 9(color) 34: 7(fvec4) Load 9(color)
Store 32(gl_FragColor) 33 Store 33(gl_FragColor) 34
Return Return
FunctionEnd 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 ...@@ -5,6 +5,8 @@ spv.do-simple.vert
spv.do-while-continue-break.vert spv.do-while-continue-break.vert
spv.for-continue-break.vert spv.for-continue-break.vert
spv.for-simple.vert spv.for-simple.vert
spv.for-notest.vert
spv.for-nobody.vert
spv.while-continue-break.vert spv.while-continue-break.vert
spv.while-simple.vert spv.while-simple.vert
# vulkan-specific tests # 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