From b617e14acb3f724ff9d71bf6c5681da3b51e0fcf Mon Sep 17 00:00:00 2001 From: John Kessenich <cepheus@frii.com> Date: Thu, 19 Jul 2018 23:10:32 -0600 Subject: [PATCH] Link: Merge all the settings in TIntermediate. Fixes #1309. --- Test/baseResults/spv.unit1.frag.out | 348 ++++++++++-------- Test/spv.unit1.frag | 2 + Test/spv.unit2.frag | 5 +- Test/spv.unit3.frag | 4 + glslang/Include/Types.h | 16 + glslang/MachineIndependent/linkValidate.cpp | 162 +++++--- .../MachineIndependent/localintermediate.h | 13 +- 7 files changed, 336 insertions(+), 214 deletions(-) diff --git a/Test/baseResults/spv.unit1.frag.out b/Test/baseResults/spv.unit1.frag.out index a92572426..d64d437fc 100755 --- a/Test/baseResults/spv.unit1.frag.out +++ b/Test/baseResults/spv.unit1.frag.out @@ -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 diff --git a/Test/spv.unit1.frag b/Test/spv.unit1.frag index f6c78504d..d84f821e9 100755 --- a/Test/spv.unit1.frag +++ b/Test/spv.unit1.frag @@ -5,6 +5,8 @@ float a1; float foo(); +out float cout; + void main() { f = 10; diff --git a/Test/spv.unit2.frag b/Test/spv.unit2.frag index 6a6d52881..d17e7e7ba 100755 --- a/Test/spv.unit2.frag +++ b/Test/spv.unit2.frag @@ -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; } \ No newline at end of file diff --git a/Test/spv.unit3.frag b/Test/spv.unit3.frag index 0ab667cd4..4c965975f 100755 --- a/Test/spv.unit3.frag +++ b/Test/spv.unit3.frag @@ -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; } diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 2b0c7a1a8..b877c1544 100755 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -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 { diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index f99b5da6e..508906239 100755 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -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(); - 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"); +#define MERGE_MAX(member) member = std::max(member, unit.member) +#define MERGE_TRUE(member) if (unit.member) member = unit.member; - if (! earlyFragmentTests) - earlyFragmentTests = unit.earlyFragmentTests; +void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) +{ + if (language != unit.language) + error(infoSink, "stages must match when linking into a single stage"); - if (!postDepthCoverage) - postDepthCoverage = unit.postDepthCoverage; + if (source == EShSourceNone) + source = unit.source; + if (source != unit.source) + error(infoSink, "can't link compilation units from different source languages"); - if (depthLayout == EldNone) - depthLayout = unit.depthLayout; - else if (depthLayout != unit.depthLayout) - error(infoSink, "Contradictory depth layouts"); + 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()); + } - blendEquations |= unit.blendEquations; + MERGE_MAX(spvVersion.spv); + MERGE_MAX(spvVersion.vulkanGlsl); + MERGE_MAX(spvVersion.vulkan); + MERGE_MAX(spvVersion.openGl); - if (inputPrimitive == ElgNone) - inputPrimitive = unit.inputPrimitive; - else if (inputPrimitive != unit.inputPrimitive) - error(infoSink, "Contradictory input layout primitives"); + numErrors += unit.getNumErrors(); + numPushConstants += unit.numPushConstants; - 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); diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index e593fcda5..9cbc4c8dc 100755 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -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; -- GitLab