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

View File

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

View File

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

View File

@ -3,9 +3,13 @@
float f;
float h3 = 3.0;
out float cout;
in float cin;
float bar()
{
h3 *= f;
float g3 = 2 * h3;
cout = g3;
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
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)
{
if (source == EShSourceNone)
source = unit.source;
if (source != unit.source)
error(infoSink, "can't link compilation units from different source languages");
mergeCallGraphs(infoSink, unit);
mergeModes(infoSink, unit);
mergeTrees(infoSink, unit);
}
void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit)
{
if (unit.getNumEntryPoints() > 0) {
if (getNumEntryPoints() > 0)
error(infoSink, "can't handle multiple entry points per stage");
@ -92,35 +93,50 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
}
}
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();
numPushConstants += unit.numPushConstants;
callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end());
if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)
error(infoSink, "gl_FragCoord redeclarations must match across shaders");
if (! earlyFragmentTests)
earlyFragmentTests = unit.earlyFragmentTests;
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 (unit.invocations != TQualifier::layoutNotSet) {
if (invocations == TQualifier::layoutNotSet)
invocations = unit.invocations;
else if (invocations != unit.invocations)
error(infoSink, "number of invocations must match between compilation units");
}
if (vertices == TQualifier::layoutNotSet)
vertices = unit.vertices;
@ -133,6 +149,19 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
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)
vertexSpacing = unit.vertexSpacing;
else if (vertexSpacing != unit.vertexSpacing)
@ -143,8 +172,7 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
else if (vertexOrder != unit.vertexOrder)
error(infoSink, "Contradictory triangle ordering");
if (unit.pointMode)
pointMode = true;
MERGE_TRUE(pointMode);
for (int i = 0; i < 3; ++i) {
if (localSize[i] > 1)
@ -158,8 +186,21 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
error(infoSink, "Contradictory local size specialization ids");
}
if (unit.xfbMode)
xfbMode = true;
MERGE_TRUE(earlyFragmentTests);
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) {
if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd)
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
}
if (unit.treeRoot == 0)
return;
MERGE_TRUE(multiStream);
if (treeRoot == 0) {
treeRoot = unit.treeRoot;
version = unit.version;
requestedExtensions = unit.requestedExtensions;
return;
#ifdef NV_EXTENSIONS
MERGE_TRUE(layoutOverrideCoverage);
MERGE_TRUE(geoPassthroughEXT);
#endif
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...
mergeTree(infoSink, unit);
for (unsigned int i = 0; i < unit.shiftBindingForSet.size(); ++i) {
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);
requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end());
ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end());
resourceSetBinding.insert(resourceSetBinding.end(), unit.resourceSetBinding.begin(), unit.resourceSetBinding.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
// 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
TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence();
TIntermSequence& unitGlobals = unit.treeRoot->getAsAggregate()->getSequence();
@ -214,6 +283,7 @@ void TIntermediate::mergeTree(TInfoSink& infoSink, TIntermediate& unit)
mergeBodies(infoSink, globals, unitGlobals);
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
@ -240,7 +310,7 @@ protected:
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
// on having no bodies for the copy-constructor/operator=.)
class TUserIdTraverser : public TIntermTraverser {
@ -250,7 +320,7 @@ public:
virtual void visitSymbol(TIntermSymbol* symbol)
{
const TQualifier& qualifier = symbol->getType().getQualifier();
if (qualifier.storage == EvqGlobal && qualifier.builtIn == EbvNone)
if (qualifier.builtIn == EbvNone)
idMap[symbol->getName()] = symbol->getId();
}
@ -286,7 +356,7 @@ public:
{
const TQualifier& qualifier = symbol->getType().getQualifier();
bool remapped = false;
if (qualifier.storage == EvqGlobal || qualifier.builtIn != EbvNone) {
if (qualifier.isLinkable() || qualifier.builtIn != EbvNone) {
auto it = idMap.find(symbol->getName());
if (it != idMap.end()) {
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&);
void error(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 remapIds(const TMap<TString, int>& idMap, int idShift, TIntermediate&);
void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals);
@ -677,6 +679,8 @@ protected:
EShSource source; // source language, known a bit later
std::string entryPointName;
std::string entryPointMangledName;
typedef std::list<TCall> TGraph;
TGraph callGraph;
EProfile profile; // source profile
int version; // source version
@ -706,6 +710,7 @@ protected:
bool hlslFunctionality1;
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
bool xfbMode;
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
bool multiStream;
#ifdef NV_EXTENSIONS
@ -717,7 +722,7 @@ protected:
std::array<unsigned int, EResCount> shiftBinding;
// 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;
bool autoMapBindings;
@ -729,13 +734,9 @@ protected:
bool useStorageBuffer;
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::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<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
std::unordered_set<int> usedConstantId; // specialization constant ids used
std::set<TString> semanticNameSet;