Link: Merge all the settings in TIntermediate.

Fixes #1309.
This commit is contained in:
John Kessenich 2018-07-19 23:10:32 -06:00
parent 5d6b567950
commit b617e14acb
7 changed files with 341 additions and 219 deletions

View File

@ -2,60 +2,65 @@ spv.unit1.frag
Shader version: 460 Shader version: 460
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
0:8 Function Definition: main( ( global void) 0:10 Function Definition: main( ( global void)
0:8 Function Parameters: 0:10 Function Parameters:
0:10 Sequence 0:12 Sequence
0:10 move second child to first child ( temp highp float) 0:12 move second child to first child ( temp highp float)
0:10 'f' ( global highp float)
0:10 Constant:
0:10 10.000000
0:11 Sequence
0:11 move second child to first child ( temp highp float)
0:11 'g' ( temp highp float)
0:11 Function Call: foo( ( global highp float)
0:12 add second child into first child ( temp highp float)
0:12 'f' ( global highp float) 0:12 'f' ( global highp float)
0:12 'g' ( temp highp float) 0:12 Constant:
0:13 add second child into first child ( temp highp float) 0:12 10.000000
0:13 'f' ( global highp float) 0:13 Sequence
0:13 direct index ( temp highp float) 0:13 move second child to first child ( temp highp float)
0:13 'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord) 0:13 'g' ( temp highp float)
0:13 Constant: 0:13 Function Call: foo( ( global highp float)
0:13 1 (const int) 0:14 add second child into first child ( temp highp float)
0:14 'f' ( global highp float)
0:14 'g' ( temp highp float)
0:15 add second child into first child ( temp highp float)
0:15 'f' ( global highp float)
0:15 direct index ( temp highp float)
0:15 'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
0:15 Constant:
0:15 1 (const int)
0:? Linker Objects 0:? Linker Objects
0:? 'f' ( global highp float) 0:? 'f' ( global highp float)
0:? 'a1' ( global highp float) 0:? 'a1' ( global highp float)
0:? 'cout' ( out highp float)
spv.unit2.frag spv.unit2.frag
Shader version: 410 Shader version: 410
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
0:9 Function Definition: foo( ( global highp float) 0:12 Function Definition: foo( ( global highp float)
0:9 Function Parameters: 0:12 Function Parameters:
0:11 Sequence 0:14 Sequence
0:11 Sequence 0:14 Sequence
0:11 move second child to first child ( temp highp float) 0:14 move second child to first child ( temp highp float)
0:11 'h2' ( temp highp float) 0:14 'h2' ( temp highp float)
0:11 component-wise multiply ( temp highp float) 0:14 add ( temp highp float)
0:11 Constant: 0:14 component-wise multiply ( temp highp float)
0:11 2.000000 0:14 Constant:
0:11 'f' ( global highp float) 0:14 2.000000
0:12 Sequence 0:14 'f' ( global highp float)
0:12 move second child to first child ( temp highp float) 0:14 'cin' ( smooth in highp float)
0:12 'g2' ( temp highp float) 0:15 Sequence
0:12 Function Call: bar( ( global highp float) 0:15 move second child to first child ( temp highp float)
0:13 Branch: Return with expression 0:15 'g2' ( temp highp float)
0:13 add ( temp highp float) 0:15 Function Call: bar( ( global highp float)
0:13 add ( temp highp float) 0:16 Branch: Return with expression
0:13 'h2' ( temp highp float) 0:16 add ( temp highp float)
0:13 'g2' ( temp highp float) 0:16 add ( temp highp float)
0:13 direct index ( temp highp float) 0:16 'h2' ( temp highp float)
0:13 'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord) 0:16 'g2' ( temp highp float)
0:13 Constant: 0:16 direct index ( temp highp float)
0:13 1 (const int) 0:16 'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
0:16 Constant:
0:16 1 (const int)
0:? Linker Objects 0:? Linker Objects
0:? 'a2' ( global highp float) 0:? 'a2' ( global highp float)
0:? 'f' ( global highp float) 0:? 'f' ( global highp float)
0:? 'cout' ( out highp float)
0:? 'cin' ( smooth in highp float)
spv.unit3.frag spv.unit3.frag
Shader version: 460 Shader version: 460
@ -66,31 +71,36 @@ gl_FragCoord origin is upper left
0:4 'h3' ( global highp float) 0:4 'h3' ( global highp float)
0:4 Constant: 0:4 Constant:
0:4 3.000000 0:4 3.000000
0:6 Function Definition: bar( ( global highp float) 0:9 Function Definition: bar( ( global highp float)
0:6 Function Parameters: 0:9 Function Parameters:
0:8 Sequence 0:11 Sequence
0:8 multiply second child into first child ( temp highp float) 0:11 multiply second child into first child ( temp highp float)
0:8 'h3' ( global highp float) 0:11 'h3' ( global highp float)
0:8 'f' ( global highp float) 0:11 'f' ( global highp float)
0:9 Sequence 0:12 Sequence
0:9 move second child to first child ( temp highp float) 0:12 move second child to first child ( temp highp float)
0:9 'g3' ( temp highp float) 0:12 'g3' ( temp highp float)
0:9 component-wise multiply ( temp highp float) 0:12 component-wise multiply ( temp highp float)
0:9 Constant: 0:12 Constant:
0:9 2.000000 0:12 2.000000
0:9 'h3' ( global highp float) 0:12 'h3' ( global highp float)
0:10 Branch: Return with expression 0:13 move second child to first child ( temp highp float)
0:10 add ( temp highp float) 0:13 'cout' ( out highp float)
0:10 add ( temp highp float) 0:13 'g3' ( temp highp float)
0:10 'h3' ( global highp float) 0:14 Branch: Return with expression
0:10 'g3' ( temp highp float) 0:14 add ( temp highp float)
0:10 direct index ( temp highp float) 0:14 add ( temp highp float)
0:10 'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord) 0:14 'h3' ( global highp float)
0:10 Constant: 0:14 'g3' ( temp highp float)
0:10 1 (const int) 0:14 direct index ( temp highp float)
0:14 'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
0:14 Constant:
0:14 1 (const int)
0:? Linker Objects 0:? Linker Objects
0:? 'f' ( global highp float) 0:? 'f' ( global highp float)
0:? 'h3' ( global highp float) 0:? 'h3' ( global highp float)
0:? 'cout' ( out highp float)
0:? 'cin' ( smooth in highp float)
Linked fragment stage: Linked fragment stage:
@ -99,90 +109,97 @@ Linked fragment stage:
Shader version: 460 Shader version: 460
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
0:8 Function Definition: main( ( global void) 0:10 Function Definition: main( ( global void)
0:8 Function Parameters: 0:10 Function Parameters:
0:10 Sequence 0:12 Sequence
0:10 move second child to first child ( temp highp float) 0:12 move second child to first child ( temp highp float)
0:10 'f' ( global highp float)
0:10 Constant:
0:10 10.000000
0:11 Sequence
0:11 move second child to first child ( temp highp float)
0:11 'g' ( temp highp float)
0:11 Function Call: foo( ( global highp float)
0:12 add second child into first child ( temp highp float)
0:12 'f' ( global highp float) 0:12 'f' ( global highp float)
0:12 'g' ( temp highp float) 0:12 Constant:
0:13 add second child into first child ( temp highp float) 0:12 10.000000
0:13 'f' ( global highp float) 0:13 Sequence
0:13 direct index ( temp highp float) 0:13 move second child to first child ( temp highp float)
0:13 'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord) 0:13 'g' ( temp highp float)
0:13 Constant: 0:13 Function Call: foo( ( global highp float)
0:13 1 (const int) 0:14 add second child into first child ( temp highp float)
0:9 Function Definition: foo( ( global highp float) 0:14 'f' ( global highp float)
0:9 Function Parameters: 0:14 'g' ( temp highp float)
0:11 Sequence 0:15 add second child into first child ( temp highp float)
0:11 Sequence 0:15 'f' ( global highp float)
0:11 move second child to first child ( temp highp float) 0:15 direct index ( temp highp float)
0:11 'h2' ( temp highp float) 0:15 'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
0:11 component-wise multiply ( temp highp float) 0:15 Constant:
0:11 Constant: 0:15 1 (const int)
0:11 2.000000 0:12 Function Definition: foo( ( global highp float)
0:11 'f' ( global highp float) 0:12 Function Parameters:
0:12 Sequence 0:14 Sequence
0:12 move second child to first child ( temp highp float) 0:14 Sequence
0:12 'g2' ( temp highp float) 0:14 move second child to first child ( temp highp float)
0:12 Function Call: bar( ( global highp float) 0:14 'h2' ( temp highp float)
0:13 Branch: Return with expression 0:14 add ( temp highp float)
0:13 add ( temp highp float) 0:14 component-wise multiply ( temp highp float)
0:13 add ( temp highp float) 0:14 Constant:
0:13 'h2' ( temp highp float) 0:14 2.000000
0:13 'g2' ( temp highp float) 0:14 'f' ( global highp float)
0:13 direct index ( temp highp float) 0:14 'cin' ( smooth in highp float)
0:13 'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord) 0:15 Sequence
0:13 Constant: 0:15 move second child to first child ( temp highp float)
0:13 1 (const int) 0:15 'g2' ( temp highp float)
0:15 Function Call: bar( ( global highp float)
0:16 Branch: Return with expression
0:16 add ( temp highp float)
0:16 add ( temp highp float)
0:16 'h2' ( temp highp float)
0:16 'g2' ( temp highp float)
0:16 direct index ( temp highp float)
0:16 'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
0:16 Constant:
0:16 1 (const int)
0:4 Sequence 0:4 Sequence
0:4 move second child to first child ( temp highp float) 0:4 move second child to first child ( temp highp float)
0:4 'h3' ( global highp float) 0:4 'h3' ( global highp float)
0:4 Constant: 0:4 Constant:
0:4 3.000000 0:4 3.000000
0:6 Function Definition: bar( ( global highp float) 0:9 Function Definition: bar( ( global highp float)
0:6 Function Parameters: 0:9 Function Parameters:
0:8 Sequence 0:11 Sequence
0:8 multiply second child into first child ( temp highp float) 0:11 multiply second child into first child ( temp highp float)
0:8 'h3' ( global highp float) 0:11 'h3' ( global highp float)
0:8 'f' ( global highp float) 0:11 'f' ( global highp float)
0:9 Sequence 0:12 Sequence
0:9 move second child to first child ( temp highp float) 0:12 move second child to first child ( temp highp float)
0:9 'g3' ( temp highp float) 0:12 'g3' ( temp highp float)
0:9 component-wise multiply ( temp highp float) 0:12 component-wise multiply ( temp highp float)
0:9 Constant: 0:12 Constant:
0:9 2.000000 0:12 2.000000
0:9 'h3' ( global highp float) 0:12 'h3' ( global highp float)
0:10 Branch: Return with expression 0:13 move second child to first child ( temp highp float)
0:10 add ( temp highp float) 0:13 'cout' ( out highp float)
0:10 add ( temp highp float) 0:13 'g3' ( temp highp float)
0:10 'h3' ( global highp float) 0:14 Branch: Return with expression
0:10 'g3' ( temp highp float) 0:14 add ( temp highp float)
0:10 direct index ( temp highp float) 0:14 add ( temp highp float)
0:10 'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord) 0:14 'h3' ( global highp float)
0:10 Constant: 0:14 'g3' ( temp highp float)
0:10 1 (const int) 0:14 direct index ( temp highp float)
0:14 'gl_FragCoord' ( gl_FragCoord highp 4-component vector of float FragCoord)
0:14 Constant:
0:14 1 (const int)
0:? Linker Objects 0:? Linker Objects
0:? 'f' ( global highp float) 0:? 'f' ( global highp float)
0:? 'a1' ( global highp float) 0:? 'a1' ( global highp float)
0:? 'cout' ( out highp float)
0:? 'a2' ( global highp float) 0:? 'a2' ( global highp float)
0:? 'cin' ( smooth in highp float)
0:? 'h3' ( global highp float) 0:? 'h3' ( global highp float)
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80007 // Generated by (magic number): 80007
// Id's are bound by 63 // Id's are bound by 69
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 25 EntryPoint Fragment 4 "main" 25 37 57
ExecutionMode 4 OriginUpperLeft ExecutionMode 4 OriginUpperLeft
Source GLSL 460 Source GLSL 460
Name 4 "main" Name 4 "main"
@ -193,10 +210,12 @@ gl_FragCoord origin is upper left
Name 18 "g" Name 18 "g"
Name 25 "gl_FragCoord" Name 25 "gl_FragCoord"
Name 33 "h2" Name 33 "h2"
Name 37 "g2" Name 37 "cin"
Name 50 "g3" Name 40 "g2"
Name 61 "a1" Name 53 "g3"
Name 62 "a2" Name 57 "cout"
Name 67 "a1"
Name 68 "a2"
Decorate 25(gl_FragCoord) BuiltIn FragCoord Decorate 25(gl_FragCoord) BuiltIn FragCoord
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
@ -215,8 +234,11 @@ gl_FragCoord origin is upper left
27: 26(int) Constant 1 27: 26(int) Constant 1
28: TypePointer Input 6(float) 28: TypePointer Input 6(float)
34: 6(float) Constant 1073741824 34: 6(float) Constant 1073741824
61(a1): 12(ptr) Variable Private 37(cin): 28(ptr) Variable Input
62(a2): 12(ptr) Variable Private 56: TypePointer Output 6(float)
57(cout): 56(ptr) Variable Output
67(a1): 12(ptr) Variable Private
68(a2): 12(ptr) Variable Private
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
18(g): 17(ptr) Variable Function 18(g): 17(ptr) Variable Function
@ -238,35 +260,39 @@ gl_FragCoord origin is upper left
8(foo(): 6(float) Function None 7 8(foo(): 6(float) Function None 7
9: Label 9: Label
33(h2): 17(ptr) Variable Function 33(h2): 17(ptr) Variable Function
37(g2): 17(ptr) Variable Function 40(g2): 17(ptr) Variable Function
35: 6(float) Load 15(f) 35: 6(float) Load 15(f)
36: 6(float) FMul 34 35 36: 6(float) FMul 34 35
Store 33(h2) 36 38: 6(float) Load 37(cin)
38: 6(float) FunctionCall 10(bar() 39: 6(float) FAdd 36 38
Store 37(g2) 38 Store 33(h2) 39
39: 6(float) Load 33(h2) 41: 6(float) FunctionCall 10(bar()
40: 6(float) Load 37(g2) Store 40(g2) 41
41: 6(float) FAdd 39 40 42: 6(float) Load 33(h2)
42: 28(ptr) AccessChain 25(gl_FragCoord) 27 43: 6(float) Load 40(g2)
43: 6(float) Load 42 44: 6(float) FAdd 42 43
44: 6(float) FAdd 41 43 45: 28(ptr) AccessChain 25(gl_FragCoord) 27
ReturnValue 44 46: 6(float) Load 45
47: 6(float) FAdd 44 46
ReturnValue 47
FunctionEnd FunctionEnd
10(bar(): 6(float) Function None 7 10(bar(): 6(float) Function None 7
11: Label 11: Label
50(g3): 17(ptr) Variable Function 53(g3): 17(ptr) Variable Function
47: 6(float) Load 15(f) 50: 6(float) Load 15(f)
48: 6(float) Load 13(h3)
49: 6(float) FMul 48 47
Store 13(h3) 49
51: 6(float) Load 13(h3) 51: 6(float) Load 13(h3)
52: 6(float) FMul 34 51 52: 6(float) FMul 51 50
Store 50(g3) 52 Store 13(h3) 52
53: 6(float) Load 13(h3) 54: 6(float) Load 13(h3)
54: 6(float) Load 50(g3) 55: 6(float) FMul 34 54
55: 6(float) FAdd 53 54 Store 53(g3) 55
56: 28(ptr) AccessChain 25(gl_FragCoord) 27 58: 6(float) Load 53(g3)
57: 6(float) Load 56 Store 57(cout) 58
58: 6(float) FAdd 55 57 59: 6(float) Load 13(h3)
ReturnValue 58 60: 6(float) Load 53(g3)
61: 6(float) FAdd 59 60
62: 28(ptr) AccessChain 25(gl_FragCoord) 27
63: 6(float) Load 62
64: 6(float) FAdd 61 63
ReturnValue 64
FunctionEnd FunctionEnd

View File

@ -5,6 +5,8 @@ float a1;
float foo(); float foo();
out float cout;
void main() void main()
{ {
f = 10; f = 10;

View File

@ -6,9 +6,12 @@ float f;
float bar(); float bar();
out float cout;
in float cin;
float foo() float foo()
{ {
float h2 = 2 * f; float h2 = 2 * f + cin;
float g2 = bar(); float g2 = bar();
return h2 + g2 + gl_FragCoord.y; return h2 + g2 + gl_FragCoord.y;
} }

View File

@ -3,9 +3,13 @@
float f; float f;
float h3 = 3.0; float h3 = 3.0;
out float cout;
in float cin;
float bar() float bar()
{ {
h3 *= f; h3 *= f;
float g3 = 2 * h3; float g3 = 2 * h3;
cout = g3;
return h3 + g3 + gl_FragCoord.y; return h3 + g3 + gl_FragCoord.y;
} }

View File

@ -616,6 +616,22 @@ public:
} }
} }
// non-built-in symbols that might link between compilation units
bool isLinkable() const
{
switch (storage) {
case EvqGlobal:
case EvqVaryingIn:
case EvqVaryingOut:
case EvqUniform:
case EvqBuffer:
case EvqShared:
return true;
default:
return false;
}
}
// True if this type of IO is supposed to be arrayed with extra level for per-vertex data // True if this type of IO is supposed to be arrayed with extra level for per-vertex data
bool isArrayedIo(EShLanguage language) const bool isArrayedIo(EShLanguage language) const
{ {

View File

@ -77,12 +77,13 @@ void TIntermediate::warn(TInfoSink& infoSink, const char* message)
// //
void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
{ {
if (source == EShSourceNone) mergeCallGraphs(infoSink, unit);
source = unit.source; mergeModes(infoSink, unit);
mergeTrees(infoSink, unit);
if (source != unit.source) }
error(infoSink, "can't link compilation units from different source languages");
void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit)
{
if (unit.getNumEntryPoints() > 0) { if (unit.getNumEntryPoints() > 0) {
if (getNumEntryPoints() > 0) if (getNumEntryPoints() > 0)
error(infoSink, "can't handle multiple entry points per stage"); error(infoSink, "can't handle multiple entry points per stage");
@ -92,35 +93,50 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
} }
} }
numEntryPoints += unit.getNumEntryPoints(); numEntryPoints += unit.getNumEntryPoints();
callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end());
}
#define MERGE_MAX(member) member = std::max(member, unit.member)
#define MERGE_TRUE(member) if (unit.member) member = unit.member;
void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
{
if (language != unit.language)
error(infoSink, "stages must match when linking into a single stage");
if (source == EShSourceNone)
source = unit.source;
if (source != unit.source)
error(infoSink, "can't link compilation units from different source languages");
if (treeRoot == nullptr) {
profile = unit.profile;
version = unit.version;
requestedExtensions = unit.requestedExtensions;
} else {
if ((profile == EEsProfile) != (unit.profile == EEsProfile))
error(infoSink, "Cannot cross link ES and desktop profiles");
else if (unit.profile == ECompatibilityProfile)
profile = ECompatibilityProfile;
version = std::max(version, unit.version);
requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end());
}
MERGE_MAX(spvVersion.spv);
MERGE_MAX(spvVersion.vulkanGlsl);
MERGE_MAX(spvVersion.vulkan);
MERGE_MAX(spvVersion.openGl);
numErrors += unit.getNumErrors(); numErrors += unit.getNumErrors();
numPushConstants += unit.numPushConstants; numPushConstants += unit.numPushConstants;
callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end());
if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger) if (unit.invocations != TQualifier::layoutNotSet) {
error(infoSink, "gl_FragCoord redeclarations must match across shaders"); if (invocations == TQualifier::layoutNotSet)
invocations = unit.invocations;
if (! earlyFragmentTests) else if (invocations != unit.invocations)
earlyFragmentTests = unit.earlyFragmentTests; error(infoSink, "number of invocations must match between compilation units");
}
if (!postDepthCoverage)
postDepthCoverage = unit.postDepthCoverage;
if (depthLayout == EldNone)
depthLayout = unit.depthLayout;
else if (depthLayout != unit.depthLayout)
error(infoSink, "Contradictory depth layouts");
blendEquations |= unit.blendEquations;
if (inputPrimitive == ElgNone)
inputPrimitive = unit.inputPrimitive;
else if (inputPrimitive != unit.inputPrimitive)
error(infoSink, "Contradictory input layout primitives");
if (outputPrimitive == ElgNone)
outputPrimitive = unit.outputPrimitive;
else if (outputPrimitive != unit.outputPrimitive)
error(infoSink, "Contradictory output layout primitives");
if (vertices == TQualifier::layoutNotSet) if (vertices == TQualifier::layoutNotSet)
vertices = unit.vertices; vertices = unit.vertices;
@ -133,6 +149,19 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
assert(0); assert(0);
} }
if (inputPrimitive == ElgNone)
inputPrimitive = unit.inputPrimitive;
else if (inputPrimitive != unit.inputPrimitive)
error(infoSink, "Contradictory input layout primitives");
if (outputPrimitive == ElgNone)
outputPrimitive = unit.outputPrimitive;
else if (outputPrimitive != unit.outputPrimitive)
error(infoSink, "Contradictory output layout primitives");
if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)
error(infoSink, "gl_FragCoord redeclarations must match across shaders");
if (vertexSpacing == EvsNone) if (vertexSpacing == EvsNone)
vertexSpacing = unit.vertexSpacing; vertexSpacing = unit.vertexSpacing;
else if (vertexSpacing != unit.vertexSpacing) else if (vertexSpacing != unit.vertexSpacing)
@ -143,8 +172,7 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
else if (vertexOrder != unit.vertexOrder) else if (vertexOrder != unit.vertexOrder)
error(infoSink, "Contradictory triangle ordering"); error(infoSink, "Contradictory triangle ordering");
if (unit.pointMode) MERGE_TRUE(pointMode);
pointMode = true;
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
if (localSize[i] > 1) if (localSize[i] > 1)
@ -158,8 +186,21 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
error(infoSink, "Contradictory local size specialization ids"); error(infoSink, "Contradictory local size specialization ids");
} }
if (unit.xfbMode) MERGE_TRUE(earlyFragmentTests);
xfbMode = true; MERGE_TRUE(postDepthCoverage);
if (depthLayout == EldNone)
depthLayout = unit.depthLayout;
else if (depthLayout != unit.depthLayout)
error(infoSink, "Contradictory depth layouts");
MERGE_TRUE(depthReplacing);
MERGE_TRUE(hlslFunctionality1);
blendEquations |= unit.blendEquations;
MERGE_TRUE(xfbMode);
for (size_t b = 0; b < xfbBuffers.size(); ++b) { for (size_t b = 0; b < xfbBuffers.size(); ++b) {
if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd) if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd)
xfbBuffers[b].stride = unit.xfbBuffers[b].stride; xfbBuffers[b].stride = unit.xfbBuffers[b].stride;
@ -171,22 +212,40 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
// TODO: 4.4 link: enhanced layouts: compare ranges // TODO: 4.4 link: enhanced layouts: compare ranges
} }
if (unit.treeRoot == 0) MERGE_TRUE(multiStream);
return;
if (treeRoot == 0) { #ifdef NV_EXTENSIONS
treeRoot = unit.treeRoot; MERGE_TRUE(layoutOverrideCoverage);
version = unit.version; MERGE_TRUE(geoPassthroughEXT);
requestedExtensions = unit.requestedExtensions; #endif
return;
for (unsigned int i = 0; i < unit.shiftBinding.size(); ++i) {
if (unit.shiftBinding[i] > 0)
setShiftBinding((TResourceType)i, unit.shiftBinding[i]);
} }
// Getting this far means we have two existing trees to merge... for (unsigned int i = 0; i < unit.shiftBindingForSet.size(); ++i) {
mergeTree(infoSink, unit); for (auto it = unit.shiftBindingForSet[i].begin(); it != unit.shiftBindingForSet[i].end(); ++it)
setShiftBindingForSet((TResourceType)i, it->second, it->first);
}
version = std::max(version, unit.version); resourceSetBinding.insert(resourceSetBinding.end(), unit.resourceSetBinding.begin(), unit.resourceSetBinding.end());
requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end());
ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end()); MERGE_TRUE(autoMapBindings);
MERGE_TRUE(autoMapLocations);
MERGE_TRUE(invertY);
MERGE_TRUE(flattenUniformArrays);
MERGE_TRUE(useUnknownFormat);
MERGE_TRUE(hlslOffsets);
MERGE_TRUE(useStorageBuffer);
MERGE_TRUE(hlslIoMapping);
// TODO: sourceFile
// TODO: sourceText
// TODO: processes
MERGE_TRUE(needToLegalize);
MERGE_TRUE(binaryDoubleOutput);
} }
// //
@ -195,8 +254,18 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
// and might have overlaps that are not the same symbol, or might have different // and might have overlaps that are not the same symbol, or might have different
// IDs for what should be the same shared symbol. // IDs for what should be the same shared symbol.
// //
void TIntermediate::mergeTree(TInfoSink& infoSink, TIntermediate& unit) void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit)
{ {
if (unit.treeRoot == nullptr)
return;
if (treeRoot == nullptr) {
treeRoot = unit.treeRoot;
return;
}
// Getting this far means we have two existing trees to merge...
// Get the top-level globals of each unit // Get the top-level globals of each unit
TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence(); TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence();
TIntermSequence& unitGlobals = unit.treeRoot->getAsAggregate()->getSequence(); TIntermSequence& unitGlobals = unit.treeRoot->getAsAggregate()->getSequence();
@ -214,6 +283,7 @@ void TIntermediate::mergeTree(TInfoSink& infoSink, TIntermediate& unit)
mergeBodies(infoSink, globals, unitGlobals); mergeBodies(infoSink, globals, unitGlobals);
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects); mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects);
ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end());
} }
// Traverser that seeds an ID map with all built-ins, and tracks the // Traverser that seeds an ID map with all built-ins, and tracks the
@ -240,7 +310,7 @@ protected:
int maxId; int maxId;
}; };
// Traverser that seeds an ID map with non-builtin globals. // Traverser that seeds an ID map with non-builtins.
// (It would be nice to put this in a function, but that causes warnings // (It would be nice to put this in a function, but that causes warnings
// on having no bodies for the copy-constructor/operator=.) // on having no bodies for the copy-constructor/operator=.)
class TUserIdTraverser : public TIntermTraverser { class TUserIdTraverser : public TIntermTraverser {
@ -250,7 +320,7 @@ public:
virtual void visitSymbol(TIntermSymbol* symbol) virtual void visitSymbol(TIntermSymbol* symbol)
{ {
const TQualifier& qualifier = symbol->getType().getQualifier(); const TQualifier& qualifier = symbol->getType().getQualifier();
if (qualifier.storage == EvqGlobal && qualifier.builtIn == EbvNone) if (qualifier.builtIn == EbvNone)
idMap[symbol->getName()] = symbol->getId(); idMap[symbol->getName()] = symbol->getId();
} }
@ -286,7 +356,7 @@ public:
{ {
const TQualifier& qualifier = symbol->getType().getQualifier(); const TQualifier& qualifier = symbol->getType().getQualifier();
bool remapped = false; bool remapped = false;
if (qualifier.storage == EvqGlobal || qualifier.builtIn != EbvNone) { if (qualifier.isLinkable() || qualifier.builtIn != EbvNone) {
auto it = idMap.find(symbol->getName()); auto it = idMap.find(symbol->getName());
if (it != idMap.end()) { if (it != idMap.end()) {
symbol->changeId(it->second); symbol->changeId(it->second);

View File

@ -645,7 +645,9 @@ protected:
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&); TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
void error(TInfoSink& infoSink, const char*); void error(TInfoSink& infoSink, const char*);
void warn(TInfoSink& infoSink, const char*); void warn(TInfoSink& infoSink, const char*);
void mergeTree(TInfoSink&, TIntermediate&); void mergeCallGraphs(TInfoSink&, TIntermediate&);
void mergeModes(TInfoSink&, TIntermediate&);
void mergeTrees(TInfoSink&, TIntermediate&);
void seedIdMap(TMap<TString, int>& idMap, int& maxId); void seedIdMap(TMap<TString, int>& idMap, int& maxId);
void remapIds(const TMap<TString, int>& idMap, int idShift, TIntermediate&); void remapIds(const TMap<TString, int>& idMap, int idShift, TIntermediate&);
void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals); void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals);
@ -677,6 +679,8 @@ protected:
EShSource source; // source language, known a bit later EShSource source; // source language, known a bit later
std::string entryPointName; std::string entryPointName;
std::string entryPointMangledName; std::string entryPointMangledName;
typedef std::list<TCall> TGraph;
TGraph callGraph;
EProfile profile; // source profile EProfile profile; // source profile
int version; // source version int version; // source version
@ -706,6 +710,7 @@ protected:
bool hlslFunctionality1; bool hlslFunctionality1;
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
bool xfbMode; bool xfbMode;
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
bool multiStream; bool multiStream;
#ifdef NV_EXTENSIONS #ifdef NV_EXTENSIONS
@ -717,7 +722,7 @@ protected:
std::array<unsigned int, EResCount> shiftBinding; std::array<unsigned int, EResCount> shiftBinding;
// Per-descriptor-set shift values // Per-descriptor-set shift values
std::array<std::map<int, int>, EResCount> shiftBindingForSet; std::array<std::map<int, int>, EResCount> shiftBindingForSet;
std::vector<std::string> resourceSetBinding; std::vector<std::string> resourceSetBinding;
bool autoMapBindings; bool autoMapBindings;
@ -729,13 +734,9 @@ protected:
bool useStorageBuffer; bool useStorageBuffer;
bool hlslIoMapping; bool hlslIoMapping;
typedef std::list<TCall> TGraph;
TGraph callGraph;
std::set<TString> ioAccessed; // set of names of statically read/written I/O that might need extra checking std::set<TString> ioAccessed; // set of names of statically read/written I/O that might need extra checking
std::vector<TIoRange> usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers std::vector<TIoRange> usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers
std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
std::unordered_set<int> usedConstantId; // specialization constant ids used std::unordered_set<int> usedConstantId; // specialization constant ids used
std::set<TString> semanticNameSet; std::set<TString> semanticNameSet;