glslang -> SPV: Improvements in swizzles on access chains: Bug 14007 (wrong type), simplications, tests, support mixed swizzle with dynamic component selection.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@31277 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2015-05-22 21:57:58 +00:00
parent 6b3fd19d89
commit 06e1d0b434
9 changed files with 531 additions and 54 deletions

View File

@ -573,7 +573,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
// so short circuit the access-chain stuff with a swizzle.
std::vector<unsigned> swizzle;
swizzle.push_back(node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst());
builder.accessChainPushSwizzle(swizzle, node->getLeft()->getVectorSize(), convertGlslangToSpvType(node->getType()));
builder.accessChainPushSwizzle(swizzle, node->getLeft()->getVectorSize());
} else {
// normal case for indexing array or structure or block
builder.accessChainPush(builder.makeIntConstant(index), convertGlslangToSpvType(node->getType()));
@ -615,7 +615,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
std::vector<unsigned> swizzle;
for (int i = 0; i < (int)swizzleSequence.size(); ++i)
swizzle.push_back(swizzleSequence[i]->getAsConstantUnion()->getConstArray()[0].getIConst());
builder.accessChainPushSwizzle(swizzle, node->getLeft()->getVectorSize(), convertGlslangToSpvType(node->getType()));
builder.accessChainPushSwizzle(swizzle, node->getLeft()->getVectorSize());
}
return false;
default:

View File

@ -907,6 +907,27 @@ Id Builder::createCompositeInsert(Id object, Id composite, Id typeId, std::vecto
return insert->getResultId();
}
Id Builder::createVectorExtractDynamic(Id vector, Id typeId, Id componentIndex)
{
Instruction* extract = new Instruction(getUniqueId(), typeId, OpVectorExtractDynamic);
extract->addIdOperand(vector);
extract->addIdOperand(componentIndex);
buildPoint->addInstruction(extract);
return extract->getResultId();
}
Id Builder::createVectorInsertDynamic(Id vector, Id typeId, Id component, Id componentIndex)
{
Instruction* insert = new Instruction(getUniqueId(), typeId, OpVectorInsertDynamic);
insert->addIdOperand(vector);
insert->addIdOperand(component);
insert->addIdOperand(componentIndex);
buildPoint->addInstruction(insert);
return insert->getResultId();
}
// An opcode that has no operands, no result id, and no type
void Builder::createNoResultOp(Op opCode)
{
@ -997,6 +1018,7 @@ Id Builder::createRvalueSwizzle(Id typeId, Id source, std::vector<unsigned>& cha
return createCompositeExtract(source, typeId, channels.front());
Instruction* swizzle = new Instruction(getUniqueId(), typeId, OpVectorShuffle);
assert(isVector(source));
swizzle->addIdOperand(source);
swizzle->addIdOperand(source);
for (int i = 0; i < (int)channels.size(); ++i)
@ -1014,6 +1036,8 @@ Id Builder::createLvalueSwizzle(Id typeId, Id target, Id source, std::vector<uns
return createCompositeInsert(source, target, typeId, channels.front());
Instruction* swizzle = new Instruction(getUniqueId(), typeId, OpVectorShuffle);
assert(isVector(source));
assert(isVector(target));
swizzle->addIdOperand(target);
swizzle->addIdOperand(source);
@ -1813,13 +1837,12 @@ void Builder::clearAccessChain()
accessChain.instr = 0;
accessChain.swizzle.clear();
accessChain.component = 0;
accessChain.swizzleTargetWidth = 0;
accessChain.resultType = NoType;
accessChain.isRValue = false;
}
// Comments in header
void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, int width, Id type)
void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, int width)
{
// if needed, propagate the swizzle for the current access chain
if (accessChain.swizzle.size()) {
@ -1828,15 +1851,8 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, int width,
for (unsigned int i = 0; i < swizzle.size(); ++i) {
accessChain.swizzle.push_back(oldSwizzle[swizzle[i]]);
}
} else {
} else
accessChain.swizzle = swizzle;
}
// track width the swizzle operates on; once known, it does not change
if (accessChain.swizzleTargetWidth == 0)
accessChain.swizzleTargetWidth = width;
accessChain.resultType = type;
// determine if we need to track this swizzle anymore
simplifyAccessChainSwizzle();
@ -1849,23 +1865,24 @@ void Builder::accessChainStore(Id rvalue)
Id base = collapseAccessChain();
if (accessChain.swizzle.size() && accessChain.component)
MissingFunctionality("simultaneous l-value swizzle and dynamic component selection");
// If swizzle exists, it is out-of-order or not full, we must load the target vector,
// extract and insert elements to perform writeMask and/or swizzle.
Id source;
Id source = NoResult;
if (accessChain.swizzle.size()) {
Id tempBaseId = createLoad(base);
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, rvalue, accessChain.swizzle);
} else if (accessChain.component) {
Id tempBaseId = createLoad(base);
Instruction* vectorInsert = new Instruction(getUniqueId(), getTypeId(tempBaseId), OpVectorInsertDynamic);
vectorInsert->addIdOperand(tempBaseId);
vectorInsert->addIdOperand(rvalue);
vectorInsert->addIdOperand(accessChain.component);
buildPoint->addInstruction(vectorInsert);
}
source = vectorInsert->getResultId();
} else
// dynamic component selection
if (accessChain.component) {
Id tempBaseId = (source == NoResult) ? createLoad(base) : source;
source = createVectorInsertDynamic(tempBaseId, getTypeId(tempBaseId), rvalue, accessChain.component);
}
if (source == NoResult)
source = rvalue;
createStore(source, base);
@ -1878,6 +1895,7 @@ Id Builder::accessChainLoad(Decoration /*precision*/)
if (accessChain.isRValue) {
if (accessChain.indexChain.size() > 0) {
mergeAccessChainSwizzle(); // TODO: optimization: look at applying this optimization more widely
// if all the accesses are constants, we can use OpCompositeExtract
std::vector<unsigned> indexes;
bool constant = true;
@ -1913,14 +1931,25 @@ Id Builder::accessChainLoad(Decoration /*precision*/)
id = createLoad(collapseAccessChain());
}
if (accessChain.component) {
Instruction* vectorExtract = new Instruction(getUniqueId(), getScalarTypeId(getTypeId(id)), OpVectorExtractDynamic);
vectorExtract->addIdOperand(id);
vectorExtract->addIdOperand(accessChain.component);
buildPoint->addInstruction(vectorExtract);
id = vectorExtract->getResultId();
} else if (accessChain.swizzle.size())
id = createRvalueSwizzle(accessChain.resultType, id, accessChain.swizzle);
// Done, unless there are swizzles to do
if (accessChain.swizzle.size() == 0 && accessChain.component == 0)
return id;
Id componentType = getScalarTypeId(accessChain.resultType);
// Do remaining swizzling
// First, static swizzling
if (accessChain.swizzle.size()) {
// static swizzle
Id resultType = componentType;
if (accessChain.swizzle.size() > 1)
resultType = makeVectorType(componentType, accessChain.swizzle.size());
id = createRvalueSwizzle(resultType, id, accessChain.swizzle);
}
// dynamic single-component selection
if (accessChain.component)
id = createVectorExtractDynamic(id, componentType, accessChain.component);
return id;
}
@ -2005,8 +2034,9 @@ Id Builder::collapseAccessChain()
// clear out swizzle if it is redundant
void Builder::simplifyAccessChainSwizzle()
{
// if swizzle has fewer components than our target, it is a writemask
if (accessChain.swizzleTargetWidth > (int)accessChain.swizzle.size())
// If the swizzle has fewer components than the vector, it is subsetting, and must stay
// to preserve that fact.
if (getNumTypeComponents(accessChain.resultType) > (int)accessChain.swizzle.size())
return;
// if components are out of order, it is a swizzle
@ -2017,7 +2047,31 @@ void Builder::simplifyAccessChainSwizzle()
// otherwise, there is no need to track this swizzle
accessChain.swizzle.clear();
accessChain.swizzleTargetWidth = 0;
}
// clear out swizzle if it can become part of the indexes
void Builder::mergeAccessChainSwizzle()
{
// is there even a chance of doing something? Need a single-component swizzle
if (accessChain.swizzle.size() > 1 ||
accessChain.swizzle.size() == 0 && accessChain.component == 0)
return;
// TODO: optimization: remove this, but for now confine this to non-dynamic accesses
// (the above test is correct when this is removed.)
if (accessChain.component)
return;
// move the swizzle over to the indexes
if (accessChain.swizzle.size() == 1)
accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle.front()));
else
accessChain.indexChain.push_back(accessChain.component);
accessChain.resultType = getScalarTypeId(accessChain.resultType);
// now there is no need to track this swizzle
accessChain.component = NoResult;
accessChain.swizzle.clear();
}
// Utility method for creating a new block and setting the insert point to

View File

@ -228,6 +228,9 @@ public:
Id createCompositeInsert(Id object, Id composite, Id typeId, unsigned index);
Id createCompositeInsert(Id object, Id composite, Id typeId, std::vector<unsigned>& indexes);
Id createVectorExtractDynamic(Id vector, Id typeId, Id componentIndex);
Id createVectorInsertDynamic(Id vector, Id typeId, Id component, Id componentIndex);
void createNoResultOp(Op);
void createNoResultOp(Op, Id operand);
void createControlBarrier(unsigned executionScope);
@ -244,7 +247,7 @@ public:
// Take a copy of an lvalue (target) and a source of components, and set the
// source components into the lvalue where the 'channels' say to put them.
// An update version of the target is returned.
// An updated version of the target is returned.
// (No true lvalue or stores are used.)
Id createLvalueSwizzle(Id typeId, Id target, Id source, std::vector<unsigned>& channels);
@ -426,9 +429,8 @@ public:
std::vector<Id> indexChain;
Id instr; // the instruction that generates this access chain
std::vector<unsigned> swizzle;
Id component; // a dynamic component index
int swizzleTargetWidth;
Id resultType; // dereferenced type, to be inclusive of swizzles, which can't have a pointer
Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle
Id resultType; // dereferenced type, to be exclusive of swizzles
bool isRValue;
};
@ -449,6 +451,7 @@ public:
{
assert(isPointer(lValue));
accessChain.base = lValue;
accessChain.resultType = getContainedTypeId(getTypeId(lValue));
}
// set new base value as an r-value
@ -467,7 +470,7 @@ public:
}
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, int width, Id type);
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, int width);
// push a variable component selection onto the access chain; supporting only one, so unsided
void accessChainPushComponent(Id component) { accessChain.component = component; }
@ -489,6 +492,7 @@ protected:
Id findCompositeConstant(Op typeClass, std::vector<Id>& comps) const;
Id collapseAccessChain();
void simplifyAccessChainSwizzle();
void mergeAccessChainSwizzle();
void createAndSetNoPredecessorBlock(const char*);
void createBranch(Block* block);
void createMerge(Op, Block*, unsigned int control);

View File

@ -52,7 +52,7 @@ Linked fragment stage:
292: 19(int) Constant 2
299: 19(int) Constant 1
301: TypePointer Function 7(float)
331: TypeVector 7(float) 3
332: TypeVector 7(float) 3
347: 7(float) Constant 1073741824
354: 7(float) Constant 1065353216
359: 19(int) Constant 66
@ -435,11 +435,11 @@ Linked fragment stage:
329: 7(float) Load 302(f)
330: 7(float) FAdd 329 328
Store 302(f) 330
332: 8(fvec4) Load 10(v)
333: 331(fvec3) VectorShuffle 332 332 0 1 2
331: 8(fvec4) Load 10(v)
333: 332(fvec3) VectorShuffle 331 331 0 1 2
334: 8(fvec4) Load 10(v)
335: 331(fvec3) VectorShuffle 334 334 0 1 2
336: 331(fvec3) ExtInst 1(GLSL.std.450) 60(cross) 333 335
335: 332(fvec3) VectorShuffle 334 334 0 1 2
336: 332(fvec3) ExtInst 1(GLSL.std.450) 60(cross) 333 335
337: 7(float) CompositeExtract 336 0
338: 7(float) Load 302(f)
339: 7(float) FAdd 338 337

View File

@ -0,0 +1,324 @@
spv.accessChain.frag
Warning, version 420 is not yet complete; most version-specific features are present, but some are missing.
Linked fragment stage:
// Module Version 99
// Generated by (magic number): 51a00bb
// Id's are bound by 198
Source GLSL 420
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4
Name 4 "main"
Name 9 "S"
MemberName 9(S) 0 "color"
Name 12 "GetColor1(struct-S-vf31;"
Name 11 "i"
Name 19 "GetColor2(struct-S-vf31;i1;"
Name 17 "i"
Name 18 "comp"
Name 23 "GetColor3(struct-S-vf31;i1;"
Name 21 "i"
Name 22 "comp"
Name 27 "GetColor4(struct-S-vf31;i1;"
Name 25 "i"
Name 26 "comp"
Name 31 "GetColor5(struct-S-vf31;i1;"
Name 29 "i"
Name 30 "comp"
Name 35 "GetColor6(struct-S-vf31;i1;"
Name 33 "i"
Name 34 "comp"
Name 39 "GetColor7(struct-S-vf31;i1;"
Name 37 "i"
Name 38 "comp"
Name 43 "GetColor8(struct-S-vf31;i1;"
Name 41 "i"
Name 42 "comp"
Name 47 "GetColor9(struct-S-vf31;i1;"
Name 45 "i"
Name 46 "comp"
Name 51 "GetColor10(struct-S-vf31;i1;"
Name 49 "i"
Name 50 "comp"
Name 55 "GetColor11(struct-S-vf31;i1;"
Name 53 "i"
Name 54 "comp"
Name 59 "GetColor12(struct-S-vf31;i1;"
Name 57 "i"
Name 58 "comp"
Name 63 "GetColor13(struct-S-vf31;i1;"
Name 61 "i"
Name 62 "comp"
Name 66 "OutColor"
Name 145 "s"
Name 150 "u"
Name 151 "param"
Name 155 "param"
Name 159 "param"
Name 163 "param"
Name 167 "param"
Name 171 "param"
Name 175 "param"
Name 179 "param"
Name 183 "param"
Name 187 "param"
Name 191 "param"
Name 195 "param"
Decorate 66(OutColor) Location 0
2: TypeVoid
3: TypeFunction 2
7: TypeFloat 32
8: TypeVector 7(float) 3
9(S): TypeStruct 8(fvec3)
10: TypeFunction 2 9(S)
14: TypeInt 32 1
15: TypePointer Function 14(int)
16: TypeFunction 2 9(S) 15(ptr)
65: TypePointer Output 8(fvec3)
66(OutColor): 65(ptr) Variable Output
67: 14(int) Constant 0
68: TypeInt 32 0
69: 68(int) Constant 0
97: TypeVector 7(float) 2
110: 68(int) Constant 2
142: 7(float) Constant 0
143: 8(fvec3) ConstantComposite 142 142 142
144: TypePointer Function 9(S)
149: TypePointer UniformConstant 14(int)
150(u): 149(ptr) Variable UniformConstant
4(main): 2 Function None 3
5: Label
145(s): 144(ptr) Variable Function
151(param): 15(ptr) Variable Function
155(param): 15(ptr) Variable Function
159(param): 15(ptr) Variable Function
163(param): 15(ptr) Variable Function
167(param): 15(ptr) Variable Function
171(param): 15(ptr) Variable Function
175(param): 15(ptr) Variable Function
179(param): 15(ptr) Variable Function
183(param): 15(ptr) Variable Function
187(param): 15(ptr) Variable Function
191(param): 15(ptr) Variable Function
195(param): 15(ptr) Variable Function
Store 66(OutColor) 143
146: 9(S) Load 145(s)
147: 2 FunctionCall 12(GetColor1(struct-S-vf31;) 146
148: 9(S) Load 145(s)
152: 14(int) Load 150(u)
Store 151(param) 152
153: 2 FunctionCall 19(GetColor2(struct-S-vf31;i1;) 148 151(param)
154: 9(S) Load 145(s)
156: 14(int) Load 150(u)
Store 155(param) 156
157: 2 FunctionCall 23(GetColor3(struct-S-vf31;i1;) 154 155(param)
158: 9(S) Load 145(s)
160: 14(int) Load 150(u)
Store 159(param) 160
161: 2 FunctionCall 27(GetColor4(struct-S-vf31;i1;) 158 159(param)
162: 9(S) Load 145(s)
164: 14(int) Load 150(u)
Store 163(param) 164
165: 2 FunctionCall 31(GetColor5(struct-S-vf31;i1;) 162 163(param)
166: 9(S) Load 145(s)
168: 14(int) Load 150(u)
Store 167(param) 168
169: 2 FunctionCall 35(GetColor6(struct-S-vf31;i1;) 166 167(param)
170: 9(S) Load 145(s)
172: 14(int) Load 150(u)
Store 171(param) 172
173: 2 FunctionCall 39(GetColor7(struct-S-vf31;i1;) 170 171(param)
174: 9(S) Load 145(s)
176: 14(int) Load 150(u)
Store 175(param) 176
177: 2 FunctionCall 43(GetColor8(struct-S-vf31;i1;) 174 175(param)
178: 9(S) Load 145(s)
180: 14(int) Load 150(u)
Store 179(param) 180
181: 2 FunctionCall 47(GetColor9(struct-S-vf31;i1;) 178 179(param)
182: 9(S) Load 145(s)
184: 14(int) Load 150(u)
Store 183(param) 184
185: 2 FunctionCall 51(GetColor10(struct-S-vf31;i1;) 182 183(param)
186: 9(S) Load 145(s)
188: 14(int) Load 150(u)
Store 187(param) 188
189: 2 FunctionCall 55(GetColor11(struct-S-vf31;i1;) 186 187(param)
190: 9(S) Load 145(s)
192: 14(int) Load 150(u)
Store 191(param) 192
193: 2 FunctionCall 59(GetColor12(struct-S-vf31;i1;) 190 191(param)
194: 9(S) Load 145(s)
196: 14(int) Load 150(u)
Store 195(param) 196
197: 2 FunctionCall 63(GetColor13(struct-S-vf31;i1;) 194 195(param)
Branch 6
6: Label
Return
FunctionEnd
12(GetColor1(struct-S-vf31;): 2 Function None 10
11(i): 9(S) FunctionParameter
13: Label
70: 7(float) CompositeExtract 11(i) 0 0
71: 8(fvec3) Load 66(OutColor)
72: 8(fvec3) CompositeConstruct 70 70 70
73: 8(fvec3) FAdd 71 72
Store 66(OutColor) 73
Return
FunctionEnd
19(GetColor2(struct-S-vf31;i1;): 2 Function None 16
17(i): 9(S) FunctionParameter
18(comp): 15(ptr) FunctionParameter
20: Label
74: 14(int) Load 18(comp)
75: 8(fvec3) CompositeExtract 17(i) 0
76: 7(float) VectorExtractDynamic 75 74
77: 8(fvec3) Load 66(OutColor)
78: 8(fvec3) CompositeConstruct 76 76 76
79: 8(fvec3) FAdd 77 78
Store 66(OutColor) 79
Return
FunctionEnd
23(GetColor3(struct-S-vf31;i1;): 2 Function None 16
21(i): 9(S) FunctionParameter
22(comp): 15(ptr) FunctionParameter
24: Label
80: 14(int) Load 22(comp)
81: 8(fvec3) CompositeExtract 21(i) 0
82: 7(float) VectorExtractDynamic 81 80
83: 8(fvec3) Load 66(OutColor)
84: 8(fvec3) CompositeConstruct 82 82 82
85: 8(fvec3) FAdd 83 84
Store 66(OutColor) 85
Return
FunctionEnd
27(GetColor4(struct-S-vf31;i1;): 2 Function None 16
25(i): 9(S) FunctionParameter
26(comp): 15(ptr) FunctionParameter
28: Label
86: 14(int) Load 26(comp)
87: 8(fvec3) CompositeExtract 25(i) 0
88: 7(float) VectorExtractDynamic 87 86
89: 8(fvec3) Load 66(OutColor)
90: 8(fvec3) CompositeConstruct 88 88 88
91: 8(fvec3) FAdd 89 90
Store 66(OutColor) 91
Return
FunctionEnd
31(GetColor5(struct-S-vf31;i1;): 2 Function None 16
29(i): 9(S) FunctionParameter
30(comp): 15(ptr) FunctionParameter
32: Label
92: 8(fvec3) CompositeExtract 29(i) 0
93: 8(fvec3) Load 66(OutColor)
94: 8(fvec3) FAdd 93 92
Store 66(OutColor) 94
Return
FunctionEnd
35(GetColor6(struct-S-vf31;i1;): 2 Function None 16
33(i): 9(S) FunctionParameter
34(comp): 15(ptr) FunctionParameter
36: Label
95: 14(int) Load 34(comp)
96: 8(fvec3) CompositeExtract 33(i) 0
98: 97(fvec2) VectorShuffle 96 96 1 0
99: 7(float) VectorExtractDynamic 98 95
100: 8(fvec3) Load 66(OutColor)
101: 8(fvec3) CompositeConstruct 99 99 99
102: 8(fvec3) FAdd 100 101
Store 66(OutColor) 102
Return
FunctionEnd
39(GetColor7(struct-S-vf31;i1;): 2 Function None 16
37(i): 9(S) FunctionParameter
38(comp): 15(ptr) FunctionParameter
40: Label
103: 8(fvec3) CompositeExtract 37(i) 0
104: 97(fvec2) VectorShuffle 103 103 0 1
105: 8(fvec3) Load 66(OutColor)
106: 97(fvec2) VectorShuffle 105 105 0 1
107: 97(fvec2) FAdd 106 104
108: 8(fvec3) Load 66(OutColor)
109: 8(fvec3) VectorShuffle 108 107 3 4 2
Store 66(OutColor) 109
Return
FunctionEnd
43(GetColor8(struct-S-vf31;i1;): 2 Function None 16
41(i): 9(S) FunctionParameter
42(comp): 15(ptr) FunctionParameter
44: Label
111: 7(float) CompositeExtract 41(i) 0 2
112: 8(fvec3) Load 66(OutColor)
113: 8(fvec3) CompositeConstruct 111 111 111
114: 8(fvec3) FAdd 112 113
Store 66(OutColor) 114
Return
FunctionEnd
47(GetColor9(struct-S-vf31;i1;): 2 Function None 16
45(i): 9(S) FunctionParameter
46(comp): 15(ptr) FunctionParameter
48: Label
115: 8(fvec3) CompositeExtract 45(i) 0
116: 8(fvec3) Load 66(OutColor)
117: 8(fvec3) VectorShuffle 116 116 2 0 1
118: 8(fvec3) FAdd 117 115
119: 8(fvec3) Load 66(OutColor)
120: 8(fvec3) VectorShuffle 119 118 4 5 3
Store 66(OutColor) 120
Return
FunctionEnd
51(GetColor10(struct-S-vf31;i1;): 2 Function None 16
49(i): 9(S) FunctionParameter
50(comp): 15(ptr) FunctionParameter
52: Label
121: 8(fvec3) CompositeExtract 49(i) 0
122: 97(fvec2) VectorShuffle 121 121 0 1
123: 8(fvec3) Load 66(OutColor)
124: 97(fvec2) VectorShuffle 123 123 2 1
125: 97(fvec2) FAdd 124 122
126: 8(fvec3) Load 66(OutColor)
127: 8(fvec3) VectorShuffle 126 125 0 4 3
Store 66(OutColor) 127
Return
FunctionEnd
55(GetColor11(struct-S-vf31;i1;): 2 Function None 16
53(i): 9(S) FunctionParameter
54(comp): 15(ptr) FunctionParameter
56: Label
128: 8(fvec3) CompositeExtract 53(i) 0
129: 97(fvec2) VectorShuffle 128 128 0 1
130: 8(fvec3) Load 66(OutColor)
131: 97(fvec2) VectorShuffle 130 130 0 2
132: 97(fvec2) FAdd 131 129
133: 8(fvec3) Load 66(OutColor)
134: 8(fvec3) VectorShuffle 133 132 3 1 4
Store 66(OutColor) 134
Return
FunctionEnd
59(GetColor12(struct-S-vf31;i1;): 2 Function None 16
57(i): 9(S) FunctionParameter
58(comp): 15(ptr) FunctionParameter
60: Label
135: 14(int) Load 58(comp)
136: 7(float) CompositeExtract 57(i) 0 0
137: 8(fvec3) Load 66(OutColor)
138: 7(float) VectorExtractDynamic 137 135
139: 7(float) FAdd 138 136
140: 8(fvec3) Load 66(OutColor)
141: 8(fvec3) VectorInsertDynamic 140 139 135
Store 66(OutColor) 141
Return
FunctionEnd
63(GetColor13(struct-S-vf31;i1;): 2 Function None 16
61(i): 9(S) FunctionParameter
62(comp): 15(ptr) FunctionParameter
64: Label
Return
FunctionEnd

View File

@ -58,7 +58,7 @@ Linked compute stage:
25: TypeVector 24(int) 3
26: TypePointer Input 25(ivec3)
27(gl_GlobalInvocationID): 26(ptr) Variable Input
28: TypeVector 24(int) 2
29: TypeVector 24(int) 2
32: TypePointer Function 8(float)
34(gl_LocalInvocationID): 26(ptr) Variable Input
38: 12(int) Constant 8
@ -87,12 +87,12 @@ Linked compute stage:
Store 16 14
20: 19(ptr) AccessChain 11(bufInst) 17
Store 20 18
29: 25(ivec3) Load 27(gl_GlobalInvocationID)
30: 28(ivec2) VectorShuffle 29 29 0 1
28: 25(ivec3) Load 27(gl_GlobalInvocationID)
30: 29(ivec2) VectorShuffle 28 28 0 1
31: 21(ivec2) Bitcast 30
Store 23(storePos) 31
35: 25(ivec3) Load 34(gl_LocalInvocationID)
36: 28(ivec2) VectorShuffle 35 35 0 1
36: 29(ivec2) VectorShuffle 35 35 0 1
37: 21(ivec2) Bitcast 36
39: 21(ivec2) CompositeConstruct 38 38
40: 21(ivec2) ISub 37 39

View File

@ -59,7 +59,7 @@ Linked fragment stage:
50: TypePointer UniformConstant 49(ivec4)
51(v4): 50(ptr) Variable UniformConstant
71: 48(int) Constant 4
85: TypeVector 7(float) 3
86: TypeVector 7(float) 3
97: TypePointer Input 7(float)
98(f): 97(ptr) Variable Input
115: 14(int) Constant 16
@ -146,8 +146,8 @@ Linked fragment stage:
82: 8(fvec4) Load 36(gl_FragColor)
83: 8(fvec4) FAdd 82 81
Store 36(gl_FragColor) 83
86: 8(fvec4) Load 12(BaseColor)
87: 85(fvec3) VectorShuffle 86 86 0 1 2
85: 8(fvec4) Load 12(BaseColor)
87: 86(fvec3) VectorShuffle 85 85 0 1 2
88: 8(fvec4) Load 84(r)
89: 8(fvec4) VectorShuffle 88 87 4 5 6 3
Store 84(r) 89
@ -170,10 +170,10 @@ Linked fragment stage:
Branch 91
92: Label
104: 8(fvec4) Load 84(r)
105: 85(fvec3) VectorShuffle 104 104 0 1 2
105: 86(fvec3) VectorShuffle 104 104 0 1 2
106: 8(fvec4) Load 36(gl_FragColor)
107: 85(fvec3) VectorShuffle 106 106 0 1 2
108: 85(fvec3) FAdd 107 105
107: 86(fvec3) VectorShuffle 106 106 0 1 2
108: 86(fvec3) FAdd 107 105
109: 8(fvec4) Load 36(gl_FragColor)
110: 8(fvec4) VectorShuffle 109 108 4 5 6 3
Store 36(gl_FragColor) 110

94
Test/spv.accessChain.frag Normal file
View File

@ -0,0 +1,94 @@
#version 420
struct S
{
vec3 color;
};
layout(location = 0) out vec3 OutColor;
uniform int u;
void GetColor1(const S i)
{
OutColor += i.color.x;
}
void GetColor2(const S i, int comp)
{
OutColor += i.color[comp];
}
void GetColor3(const S i, int comp)
{
OutColor += i.color[comp].x;
}
void GetColor4(const S i, int comp)
{
OutColor += i.color[comp].x;
}
void GetColor5(const S i, int comp)
{
OutColor += i.color;
}
void GetColor6(const S i, int comp)
{
OutColor += i.color.yx[comp];
}
void GetColor7(const S i, int comp)
{
OutColor.xy += i.color.yxz.yx;
}
void GetColor8(const S i, int comp)
{
OutColor += i.color.yzx.yx.x.x;
}
void GetColor9(const S i, int comp)
{
OutColor.zxy += i.color;
}
void GetColor10(const S i, int comp)
{
OutColor.zy += i.color.xy;
}
void GetColor11(const S i, int comp)
{
OutColor.zxy.yx += i.color.xy;
}
void GetColor12(const S i, int comp)
{
OutColor[comp] += i.color.x;
}
void GetColor13(const S i, int comp)
{
// OutColor.zy[comp] += i.color.x; // not yet supported
}
void main()
{
S s;
OutColor = vec3(0.0);
GetColor1(s);
GetColor2(s, u);
GetColor3(s, u);
GetColor4(s, u);
GetColor5(s, u);
GetColor6(s, u);
GetColor7(s, u);
GetColor8(s, u);
GetColor9(s, u);
GetColor10(s, u);
GetColor11(s, u);
GetColor12(s, u);
GetColor13(s, u);
}

View File

@ -28,6 +28,7 @@ spv.400.tesc
spv.400.tese
spv.420.geom
spv.430.vert
spv.accessChain.frag
spv.aggOps.frag
spv.always-discard.frag
spv.always-discard2.frag