Commit 07939886 by John Kessenich Committed by GitHub

Merge pull request #707 from KhronosGroup/emit-opSelect

SPV: Emit op select
parents f8d0d8c2 8e6c6cef
...@@ -1748,42 +1748,98 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt ...@@ -1748,42 +1748,98 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
} }
} }
// This path handles both if-then-else and ?:
// The if-then-else has a node type of void, while
// ?: has either a void or a non-void node type
//
// Leaving the result, when not void:
// GLSL only has r-values as the result of a :?, but
// if we have an l-value, that can be more efficient if it will
// become the base of a complex r-value expression, because the
// next layer copies r-values into memory to use the access-chain mechanism
bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang::TIntermSelection* node) bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang::TIntermSelection* node)
{ {
// This path handles both if-then-else and ?: // See if it simple and safe to generate OpSelect instead of using control flow.
// The if-then-else has a node type of void, while // Crucially, side effects must be avoided, and there are performance trade-offs.
// ?: has a non-void node type // Return true if good idea (and safe) for OpSelect, false otherwise.
spv::Id result = 0; const auto selectPolicy = [&]() -> bool {
if (node->getBasicType() != glslang::EbtVoid) { if (node->getBasicType() == glslang::EbtVoid)
// don't handle this as just on-the-fly temporaries, because there will be two names return false;
// and better to leave SSA to later passes
result = builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(node->getType())); if (node->getTrueBlock() == nullptr ||
node->getFalseBlock() == nullptr)
return false;
assert(node->getType() == node->getTrueBlock() ->getAsTyped()->getType() &&
node->getType() == node->getFalseBlock()->getAsTyped()->getType());
// return true if a single operand to ? : is okay for OpSelect
const auto operandOkay = [](glslang::TIntermTyped* node) {
return node->getAsSymbolNode() || node->getType().getQualifier().isConstant();
};
return operandOkay(node->getTrueBlock() ->getAsTyped()) &&
operandOkay(node->getFalseBlock()->getAsTyped());
};
// Emit OpSelect for this selection.
const auto handleAsOpSelect = [&]() {
node->getCondition()->traverse(this);
spv::Id condition = accessChainLoad(node->getCondition()->getType());
node->getTrueBlock()->traverse(this);
spv::Id trueValue = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType());
node->getFalseBlock()->traverse(this);
spv::Id falseValue = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType());
spv::Id select = builder.createTriOp(spv::OpSelect, convertGlslangToSpvType(node->getType()), condition, trueValue, falseValue);
builder.clearAccessChain();
builder.setAccessChainRValue(select);
};
// Try for OpSelect
if (selectPolicy()) {
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
if (node->getType().getQualifier().isSpecConstant())
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
handleAsOpSelect();
return false;
} }
// Instead, emit control flow...
// Don't handle results as temporaries, because there will be two names
// and better to leave SSA to later passes.
spv::Id result = (node->getBasicType() == glslang::EbtVoid)
? spv::NoResult
: builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(node->getType()));
// emit the condition before doing anything with selection // emit the condition before doing anything with selection
node->getCondition()->traverse(this); node->getCondition()->traverse(this);
// make an "if" based on the value created by the condition // make an "if" based on the value created by the condition
spv::Builder::If ifBuilder(accessChainLoad(node->getCondition()->getType()), builder); spv::Builder::If ifBuilder(accessChainLoad(node->getCondition()->getType()), builder);
if (node->getTrueBlock()) { // emit the "then" statement
// emit the "then" statement if (node->getTrueBlock() != nullptr) {
node->getTrueBlock()->traverse(this); node->getTrueBlock()->traverse(this);
if (result) if (result != spv::NoResult)
builder.createStore(accessChainLoad(node->getTrueBlock()->getAsTyped()->getType()), result); builder.createStore(accessChainLoad(node->getTrueBlock()->getAsTyped()->getType()), result);
} }
if (node->getFalseBlock()) { if (node->getFalseBlock() != nullptr) {
ifBuilder.makeBeginElse(); ifBuilder.makeBeginElse();
// emit the "else" statement // emit the "else" statement
node->getFalseBlock()->traverse(this); node->getFalseBlock()->traverse(this);
if (result) if (result != spv::NoResult)
builder.createStore(accessChainLoad(node->getFalseBlock()->getAsTyped()->getType()), result); builder.createStore(accessChainLoad(node->getFalseBlock()->getAsTyped()->getType()), result);
} }
// finish off the control flow
ifBuilder.makeEndIf(); ifBuilder.makeEndIf();
if (result) { if (result != spv::NoResult) {
// GLSL only has r-values as the result of a :?, but // GLSL only has r-values as the result of a :?, but
// if we have an l-value, that can be more efficient if it will // if we have an l-value, that can be more efficient if it will
// become the base of a complex r-value expression, because the // become the base of a complex r-value expression, because the
......
...@@ -3,7 +3,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre ...@@ -3,7 +3,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 49 // Id's are bound by 44
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
...@@ -19,18 +19,18 @@ Warning, version 450 is not yet complete; most version-specific features are pre ...@@ -19,18 +19,18 @@ Warning, version 450 is not yet complete; most version-specific features are pre
MemberName 22(gl_PerVertex) 2 "gl_ClipDistance" MemberName 22(gl_PerVertex) 2 "gl_ClipDistance"
MemberName 22(gl_PerVertex) 3 "gl_CullDistance" MemberName 22(gl_PerVertex) 3 "gl_CullDistance"
Name 24 "" Name 24 ""
Name 29 "ubname" Name 27 "ubname"
MemberName 29(ubname) 0 "b" MemberName 27(ubname) 0 "b"
Name 31 "ubinst" Name 29 "ubinst"
Name 32 "param" Name 30 "param"
MemberDecorate 22(gl_PerVertex) 0 BuiltIn Position MemberDecorate 22(gl_PerVertex) 0 BuiltIn Position
MemberDecorate 22(gl_PerVertex) 1 BuiltIn PointSize MemberDecorate 22(gl_PerVertex) 1 BuiltIn PointSize
MemberDecorate 22(gl_PerVertex) 2 BuiltIn ClipDistance MemberDecorate 22(gl_PerVertex) 2 BuiltIn ClipDistance
MemberDecorate 22(gl_PerVertex) 3 BuiltIn CullDistance MemberDecorate 22(gl_PerVertex) 3 BuiltIn CullDistance
Decorate 22(gl_PerVertex) Block Decorate 22(gl_PerVertex) Block
MemberDecorate 29(ubname) 0 Offset 0 MemberDecorate 27(ubname) 0 Offset 0
Decorate 29(ubname) Block Decorate 27(ubname) Block
Decorate 31(ubinst) DescriptorSet 0 Decorate 29(ubinst) DescriptorSet 0
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeBool 6: TypeBool
...@@ -47,38 +47,27 @@ Warning, version 450 is not yet complete; most version-specific features are pre ...@@ -47,38 +47,27 @@ Warning, version 450 is not yet complete; most version-specific features are pre
24: 23(ptr) Variable Output 24: 23(ptr) Variable Output
25: TypeInt 32 1 25: TypeInt 32 1
26: 25(int) Constant 0 26: 25(int) Constant 0
27: TypePointer Function 18(fvec4) 27(ubname): TypeStruct 19(int)
29(ubname): TypeStruct 19(int) 28: TypePointer Uniform 27(ubname)
30: TypePointer Uniform 29(ubname) 29(ubinst): 28(ptr) Variable Uniform
31(ubinst): 30(ptr) Variable Uniform 31: TypePointer Uniform 19(int)
33: TypePointer Uniform 19(int) 34: 19(int) Constant 0
36: 19(int) Constant 0 37: 17(float) Constant 0
41: 17(float) Constant 0 38: 18(fvec4) ConstantComposite 37 37 37 37
42: 18(fvec4) ConstantComposite 41 41 41 41 39: 17(float) Constant 1065353216
44: 17(float) Constant 1065353216 40: 18(fvec4) ConstantComposite 39 39 39 39
45: 18(fvec4) ConstantComposite 44 44 44 44 42: TypePointer Output 18(fvec4)
47: TypePointer Output 18(fvec4)
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
28: 27(ptr) Variable Function 30(param): 7(ptr) Variable Function
32(param): 7(ptr) Variable Function 32: 31(ptr) AccessChain 29(ubinst) 26
34: 33(ptr) AccessChain 31(ubinst) 26 33: 19(int) Load 32
35: 19(int) Load 34 35: 6(bool) INotEqual 33 34
37: 6(bool) INotEqual 35 36 Store 30(param) 35
Store 32(param) 37 36: 6(bool) FunctionCall 10(foo(b1;) 30(param)
38: 6(bool) FunctionCall 10(foo(b1;) 32(param) 41: 18(fvec4) Select 36 38 40
SelectionMerge 40 None 43: 42(ptr) AccessChain 24 26
BranchConditional 38 39 43 Store 43 41
39: Label
Store 28 42
Branch 40
43: Label
Store 28 45
Branch 40
40: Label
46: 18(fvec4) Load 28
48: 47(ptr) AccessChain 24 26
Store 48 46
Return Return
FunctionEnd FunctionEnd
10(foo(b1;): 6(bool) Function None 8 10(foo(b1;): 6(bool) Function None 8
......
spv.deepRvalue.frag spv.deepRvalue.frag
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 155 // Id's are bound by 150
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 149 EntryPoint Fragment 4 "main" 144
ExecutionMode 4 OriginUpperLeft ExecutionMode 4 OriginUpperLeft
Source GLSL 330 Source GLSL 330
Name 4 "main" Name 4 "main"
...@@ -21,12 +21,12 @@ spv.deepRvalue.frag ...@@ -21,12 +21,12 @@ spv.deepRvalue.frag
Name 106 "h" Name 106 "h"
Name 107 "i" Name 107 "i"
Name 111 "samp2D" Name 111 "samp2D"
Name 134 "str" Name 129 "str"
MemberName 134(str) 0 "a" MemberName 129(str) 0 "a"
MemberName 134(str) 1 "b" MemberName 129(str) 1 "b"
MemberName 134(str) 2 "c" MemberName 129(str) 2 "c"
Name 136 "t" Name 131 "t"
Name 149 "gl_FragColor" Name 144 "gl_FragColor"
Decorate 111(samp2D) DescriptorSet 0 Decorate 111(samp2D) DescriptorSet 0
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
...@@ -75,22 +75,21 @@ spv.deepRvalue.frag ...@@ -75,22 +75,21 @@ spv.deepRvalue.frag
113: TypeVector 6(float) 2 113: TypeVector 6(float) 2
114: 6(float) Constant 1056964608 114: 6(float) Constant 1056964608
115: 113(fvec2) ConstantComposite 114 114 115: 113(fvec2) ConstantComposite 114 114
118: TypePointer Function 7(fvec4) 119: 6(float) Constant 1036831949
121: 6(float) Constant 1036831949 120: TypeBool
122: TypeBool 128: TypeArray 113(fvec2) 84
133: TypeArray 113(fvec2) 84 129(str): TypeStruct 81(int) 128 120(bool)
134(str): TypeStruct 81(int) 133 122(bool) 130: TypePointer Function 129(str)
135: TypePointer Function 134(str) 132: 113(fvec2) ConstantComposite 10 11
137: 113(fvec2) ConstantComposite 10 11 133: 6(float) Constant 1082130432
138: 6(float) Constant 1082130432 134: 113(fvec2) ConstantComposite 133 12
139: 113(fvec2) ConstantComposite 138 12 135: 6(float) Constant 1086324736
140: 6(float) Constant 1086324736 136: 113(fvec2) ConstantComposite 135 13
141: 113(fvec2) ConstantComposite 140 13 137: 128 ConstantComposite 132 134 136
142: 133 ConstantComposite 137 139 141 138: 120(bool) ConstantTrue
143: 122(bool) ConstantTrue 139: 129(str) ConstantComposite 82 137 138
144: 134(str) ConstantComposite 82 142 143 143: TypePointer Output 7(fvec4)
148: TypePointer Output 7(fvec4) 144(gl_FragColor): 143(ptr) Variable Output
149(gl_FragColor): 148(ptr) Variable Output
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
35(m): 34(ptr) Variable Function 35(m): 34(ptr) Variable Function
...@@ -99,8 +98,7 @@ spv.deepRvalue.frag ...@@ -99,8 +98,7 @@ spv.deepRvalue.frag
87(g): 79(ptr) Variable Function 87(g): 79(ptr) Variable Function
106(h): 79(ptr) Variable Function 106(h): 79(ptr) Variable Function
107(i): 79(ptr) Variable Function 107(i): 79(ptr) Variable Function
119: 118(ptr) Variable Function 131(t): 130(ptr) Variable Function
136(t): 135(ptr) Variable Function
Store 9(v1) 14 Store 9(v1) 14
Store 15(v2) 20 Store 15(v2) 20
Store 21(v3) 26 Store 21(v3) 26
...@@ -172,34 +170,25 @@ spv.deepRvalue.frag ...@@ -172,34 +170,25 @@ spv.deepRvalue.frag
116: 7(fvec4) ImageSampleImplicitLod 112 115 116: 7(fvec4) ImageSampleImplicitLod 112 115
117: 6(float) CompositeExtract 116 1 117: 6(float) CompositeExtract 116 1
Store 107(i) 117 Store 107(i) 117
120: 6(float) Load 107(i) 118: 6(float) Load 107(i)
123: 122(bool) FOrdGreaterThan 120 121 121: 120(bool) FOrdGreaterThan 118 119
SelectionMerge 125 None 122: 7(fvec4) Load 9(v1)
BranchConditional 123 124 127 123: 7(fvec4) Load 15(v2)
124: Label 124: 7(fvec4) Select 121 122 123
126: 7(fvec4) Load 9(v1) 125: 6(float) CompositeExtract 124 3
Store 119 126 126: 6(float) Load 107(i)
Branch 125 127: 6(float) FAdd 126 125
127: Label Store 107(i) 127
128: 7(fvec4) Load 15(v2) Store 131(t) 139
Store 119 128 140: 6(float) CompositeExtract 139 1 2 1
Branch 125 141: 6(float) Load 107(i)
125: Label 142: 6(float) FAdd 141 140
129: 79(ptr) AccessChain 119 84 Store 107(i) 142
130: 6(float) Load 129 145: 6(float) Load 80(f)
131: 6(float) Load 107(i) 146: 6(float) Load 87(g)
132: 6(float) FAdd 131 130 147: 6(float) Load 106(h)
Store 107(i) 132 148: 6(float) Load 107(i)
Store 136(t) 144 149: 7(fvec4) CompositeConstruct 145 146 147 148
145: 6(float) CompositeExtract 144 1 2 1 Store 144(gl_FragColor) 149
146: 6(float) Load 107(i)
147: 6(float) FAdd 146 145
Store 107(i) 147
150: 6(float) Load 80(f)
151: 6(float) Load 87(g)
152: 6(float) Load 106(h)
153: 6(float) Load 107(i)
154: 7(fvec4) CompositeConstruct 150 151 152 153
Store 149(gl_FragColor) 154
Return Return
FunctionEnd FunctionEnd
...@@ -3,38 +3,37 @@ Warning, version 450 is not yet complete; most version-specific features are pre ...@@ -3,38 +3,37 @@ Warning, version 450 is not yet complete; most version-specific features are pre
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 35 // Id's are bound by 31
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 18 31 EntryPoint Vertex 4 "main" 17 27
Source GLSL 450 Source GLSL 450
Name 4 "main" Name 4 "main"
Name 8 "i" Name 8 "i"
Name 18 "flag" Name 17 "flag"
Name 31 "r" Name 27 "r"
Decorate 18(flag) RelaxedPrecision Decorate 17(flag) RelaxedPrecision
Decorate 18(flag) Location 0 Decorate 17(flag) Location 0
Decorate 19 RelaxedPrecision Decorate 18 RelaxedPrecision
Decorate 31(r) Location 0 Decorate 27(r) Location 0
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
17: TypePointer Input 6(int) 16: TypePointer Input 6(int)
18(flag): 17(ptr) Variable Input 17(flag): 16(ptr) Variable Input
20: 6(int) Constant 1 19: 6(int) Constant 1
21: TypeBool 20: TypeBool
25: 6(int) Constant 10 22: 6(int) Constant 10
27: 6(int) Constant 15 23: 6(int) Constant 15
30: TypePointer Output 6(int) 26: TypePointer Output 6(int)
31(r): 30(ptr) Variable Output 27(r): 26(ptr) Variable Output
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
16: 7(ptr) Variable Function
Store 8(i) 9 Store 8(i) 9
Branch 10 Branch 10
10: Label 10: Label
...@@ -42,29 +41,20 @@ Warning, version 450 is not yet complete; most version-specific features are pre ...@@ -42,29 +41,20 @@ Warning, version 450 is not yet complete; most version-specific features are pre
Branch 14 Branch 14
14: Label 14: Label
15: 6(int) Load 8(i) 15: 6(int) Load 8(i)
19: 6(int) Load 18(flag) 18: 6(int) Load 17(flag)
22: 21(bool) IEqual 19 20 21: 20(bool) IEqual 18 19
SelectionMerge 24 None 24: 6(int) Select 21 22 23
BranchConditional 22 23 26 25: 20(bool) SLessThan 15 24
23: Label BranchConditional 25 11 12
Store 16 25 11: Label
Branch 24 28: 6(int) Load 8(i)
26: Label Store 27(r) 28
Store 16 27 Branch 13
Branch 24 13: Label
24: Label 29: 6(int) Load 8(i)
28: 6(int) Load 16 30: 6(int) IAdd 29 19
29: 21(bool) SLessThan 15 28 Store 8(i) 30
BranchConditional 29 11 12 Branch 10
11: Label
32: 6(int) Load 8(i)
Store 31(r) 32
Branch 13
13: Label
33: 6(int) Load 8(i)
34: 6(int) IAdd 33 20
Store 8(i) 34
Branch 10
12: Label 12: Label
Return Return
FunctionEnd FunctionEnd
...@@ -3,7 +3,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre ...@@ -3,7 +3,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 378 // Id's are bound by 374
Capability Shader Capability Shader
Capability SampledRect Capability SampledRect
...@@ -16,7 +16,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre ...@@ -16,7 +16,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre
Capability StorageImageWriteWithoutFormat Capability StorageImageWriteWithoutFormat
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 132 142 152 248 362 377 EntryPoint Fragment 4 "main" 132 142 152 248 362 373
ExecutionMode 4 OriginUpperLeft ExecutionMode 4 OriginUpperLeft
Source GLSL 450 Source GLSL 450
Name 4 "main" Name 4 "main"
...@@ -42,7 +42,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre ...@@ -42,7 +42,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre
Name 248 "value" Name 248 "value"
Name 357 "wo2D" Name 357 "wo2D"
Name 362 "fragData" Name 362 "fragData"
Name 377 "ic4D" Name 373 "ic4D"
Decorate 15(i1D) DescriptorSet 0 Decorate 15(i1D) DescriptorSet 0
Decorate 15(i1D) Binding 0 Decorate 15(i1D) Binding 0
Decorate 27(i2D) DescriptorSet 0 Decorate 27(i2D) DescriptorSet 0
...@@ -76,7 +76,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre ...@@ -76,7 +76,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre
Decorate 357(wo2D) DescriptorSet 0 Decorate 357(wo2D) DescriptorSet 0
Decorate 357(wo2D) Binding 1 Decorate 357(wo2D) Binding 1
Decorate 357(wo2D) NonReadable Decorate 357(wo2D) NonReadable
Decorate 377(ic4D) Flat Decorate 373(ic4D) Flat
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 1 6: TypeInt 32 1
...@@ -163,16 +163,15 @@ Warning, version 450 is not yet complete; most version-specific features are pre ...@@ -163,16 +163,15 @@ Warning, version 450 is not yet complete; most version-specific features are pre
357(wo2D): 356(ptr) Variable UniformConstant 357(wo2D): 356(ptr) Variable UniformConstant
361: TypePointer Output 125(fvec4) 361: TypePointer Output 125(fvec4)
362(fragData): 361(ptr) Variable Output 362(fragData): 361(ptr) Variable Output
368: TypeBool 367: TypeBool
375: TypeVector 6(int) 4 371: TypeVector 6(int) 4
376: TypePointer Input 375(ivec4) 372: TypePointer Input 371(ivec4)
377(ic4D): 376(ptr) Variable Input 373(ic4D): 372(ptr) Variable Input
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
9(iv): 8(ptr) Variable Function 9(iv): 8(ptr) Variable Function
127(v): 126(ptr) Variable Function 127(v): 126(ptr) Variable Function
229(ui): 228(ptr) Variable Function 229(ui): 228(ptr) Variable Function
363: 126(ptr) Variable Function
Store 9(iv) 11 Store 9(iv) 11
16: 13 Load 15(i1D) 16: 13 Load 15(i1D)
17: 6(int) ImageQuerySize 16 17: 6(int) ImageQuerySize 16
...@@ -498,22 +497,13 @@ Warning, version 450 is not yet complete; most version-specific features are pre ...@@ -498,22 +497,13 @@ Warning, version 450 is not yet complete; most version-specific features are pre
359: 29(ivec2) Load 142(ic2D) 359: 29(ivec2) Load 142(ic2D)
360: 125(fvec4) Load 127(v) 360: 125(fvec4) Load 127(v)
ImageWrite 358 359 360 ImageWrite 358 359 360
364: 18(int) Load 229(ui) 363: 18(int) Load 229(ui)
365: 20(ptr) AccessChain 9(iv) 237 364: 20(ptr) AccessChain 9(iv) 237
366: 6(int) Load 365 365: 6(int) Load 364
367: 18(int) Bitcast 366 366: 18(int) Bitcast 365
369: 368(bool) INotEqual 364 367 368: 367(bool) INotEqual 363 366
SelectionMerge 371 None 369: 125(fvec4) Load 127(v)
BranchConditional 369 370 373 370: 125(fvec4) Select 368 369 129
370: Label Store 362(fragData) 370
372: 125(fvec4) Load 127(v)
Store 363 372
Branch 371
373: Label
Store 363 129
Branch 371
371: Label
374: 125(fvec4) Load 363
Store 362(fragData) 374
Return Return
FunctionEnd FunctionEnd
...@@ -3,7 +3,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre ...@@ -3,7 +3,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 135 // Id's are bound by 160
Capability Shader Capability Shader
Capability Float64 Capability Float64
...@@ -20,11 +20,18 @@ Warning, version 450 is not yet complete; most version-specific features are pre ...@@ -20,11 +20,18 @@ Warning, version 450 is not yet complete; most version-specific features are pre
Name 42 "sp_uint" Name 42 "sp_uint"
Name 43 "sp_sint" Name 43 "sp_sint"
Name 45 "sp_double" Name 45 "sp_double"
Name 135 "a"
Name 136 "b"
Name 137 "c"
Name 142 "ternayArray1"
Decorate 19(sp_int) SpecId 201 Decorate 19(sp_int) SpecId 201
Decorate 40(sp_float) SpecId 200 Decorate 40(sp_float) SpecId 200
Decorate 42(sp_uint) SpecId 202 Decorate 42(sp_uint) SpecId 202
Decorate 43(sp_sint) SpecId 203 Decorate 43(sp_sint) SpecId 203
Decorate 45(sp_double) SpecId 204 Decorate 45(sp_double) SpecId 204
Decorate 135(a) SpecId 210
Decorate 136(b) SpecId 211
Decorate 137(c) SpecId 212
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 1 6: TypeInt 32 1
...@@ -137,6 +144,31 @@ Warning, version 450 is not yet complete; most version-specific features are pre ...@@ -137,6 +144,31 @@ Warning, version 450 is not yet complete; most version-specific features are pre
132: TypeVector 6(int) 3 132: TypeVector 6(int) 3
133: 132(ivec3) SpecConstantOp 79 91 91 2 1(GLSL.std.450) 0 133: 132(ivec3) SpecConstantOp 79 91 91 2 1(GLSL.std.450) 0
134: 90(ivec4) SpecConstantOp 79 91 91 1(GLSL.std.450) 2 0 3 134: 90(ivec4) SpecConstantOp 79 91 91 1(GLSL.std.450) 2 0 3
135(a): 6(int) SpecConstant 4
136(b): 6(int) SpecConstant 6
137(c): 22(bool) SpecConstantTrue
138: 22(bool) SpecConstantOp 173 135(a) 136(b)
139: 6(int) SpecConstantOp 169 138 135(a) 136(b)
140: TypeArray 6(int) 139
141: TypePointer Private 140
142(ternayArray1): 141(ptr) Variable Private
143: 6(int) Constant 13
144: 6(int) Constant 17
145: 6(int) SpecConstantOp 169 137(c) 143 144
146: 6(int) SpecConstantOp 169 137(c) 135(a) 144
147: 22(bool) ConstantTrue
148: 6(int) SpecConstantOp 169 147 135(a) 144
149: 22(bool) SpecConstantOp 173 135(a) 136(b)
150: 6(int) SpecConstantOp 128 143 135(a)
151: 6(int) SpecConstantOp 132 144 136(b)
152: 6(int) SpecConstantOp 169 149 150 151
153: 22(bool) SpecConstantOp 168 137(c)
154: TypeVector 39(float) 2
155: 39(float) Constant 1065353216
156: 154(fvec2) ConstantComposite 155 155
157: 39(float) Constant 1073741824
158: 154(fvec2) ConstantComposite 157 157
159: 154(fvec2) SpecConstantOp 169 153 156 158
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
Return Return
......
...@@ -110,5 +110,15 @@ int non_const_array_size_from_spec_const() { ...@@ -110,5 +110,15 @@ int non_const_array_size_from_spec_const() {
return array[sp_int + 1]; return array[sp_int + 1];
} }
void main() {} // ternary
layout(constant_id = 210) const int a = 4;
layout(constant_id = 211) const int b = 6;
layout(constant_id = 212) const bool c = true;
int ternayArray1[a > b ? a : b];
const int t1 = c ? 13 : 17;
const int t2 = c ? a : 17;
const int t3 = true ? a : 17;
const int t4 = a > b ? 13 + a : 17 * b;
const vec2 v2 = !c ? vec2(1.0) : vec2(2.0);
void main() {}
...@@ -155,14 +155,10 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn ...@@ -155,14 +155,10 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
return folded; return folded;
} }
// If either is a specialization constant, while the other is // If can propagate spec-constantness and if the operation is an allowed
// a constant (or specialization constant), the result is still // specialization-constant operation, make a spec-constant.
// a specialization constant, if the operation is an allowed if (specConstantPropagates(*left, *right) && isSpecializationOperation(*node))
// specialization-constant operation. node->getWritableType().getQualifier().makeSpecConstant();
if (( left->getType().getQualifier().isSpecConstant() && right->getType().getQualifier().isConstant()) ||
(right->getType().getQualifier().isSpecConstant() && left->getType().getQualifier().isConstant()))
if (isSpecializationOperation(*node))
node->getWritableType().getQualifier().makeSpecConstant();
return node; return node;
} }
...@@ -1277,6 +1273,9 @@ TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, ...@@ -1277,6 +1273,9 @@ TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type,
// a true path, and a false path. The two paths are specified // a true path, and a false path. The two paths are specified
// as separate parameters. // as separate parameters.
// //
// Specialization constant operations include
// - The ternary operator ( ? : )
//
// Returns the selection node created, or nullptr if one could not be. // Returns the selection node created, or nullptr if one could not be.
// //
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc) TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc)
...@@ -1320,10 +1319,16 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true ...@@ -1320,10 +1319,16 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
// Make a selection node. // Make a selection node.
// //
TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType()); TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
node->getQualifier().makeTemporary();
node->setLoc(loc); node->setLoc(loc);
node->getQualifier().precision = std::max(trueBlock->getQualifier().precision, falseBlock->getQualifier().precision); node->getQualifier().precision = std::max(trueBlock->getQualifier().precision, falseBlock->getQualifier().precision);
if ((cond->getQualifier().isConstant() && specConstantPropagates(*trueBlock, *falseBlock)) ||
(cond->getQualifier().isSpecConstant() && trueBlock->getQualifier().isConstant() &&
falseBlock->getQualifier().isConstant()))
node->getQualifier().makeSpecConstant();
else
node->getQualifier().makeTemporary();
return node; return node;
} }
...@@ -2645,4 +2650,13 @@ void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable) ...@@ -2645,4 +2650,13 @@ void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable)
*pragmaTable = pTable; *pragmaTable = pTable;
} }
// If either node is a specialization constant, while the other is
// a constant (or specialization constant), the result is still
// a specialization constant.
bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TIntermTyped& node2)
{
return (node1.getType().getQualifier().isSpecConstant() && node2.getType().getQualifier().isConstant()) ||
(node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant());
}
} // end namespace glslang } // end namespace glslang
...@@ -440,6 +440,7 @@ protected: ...@@ -440,6 +440,7 @@ protected:
bool promoteAggregate(TIntermAggregate&); bool promoteAggregate(TIntermAggregate&);
void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&); void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&);
void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&); void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&);
bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
const EShLanguage language; // stage, known at construction time const EShLanguage language; // stage, known at construction time
EShSource source; // source language, known a bit later EShSource source; // source language, known a bit later
......
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