mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-09 12:00:05 +00:00
add cross-stage check for missing outputs
If an 'in' is present in a shader stage, make sure a matching 'out' is present in the previous stage. Only enabled when doing Vulkan. This commit also fixes a bug where previous stage's linkerObjects got polluted with 'in' variables from the next stage when merging linker objects.
This commit is contained in:
parent
6a28e226c7
commit
69249e46b6
313
Test/baseResults/iomap.crossStage.vk.2.vert.out
Executable file
313
Test/baseResults/iomap.crossStage.vk.2.vert.out
Executable file
@ -0,0 +1,313 @@
|
||||
iomap.crossStage.vk.2.vert
|
||||
Shader version: 460
|
||||
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 4-component vector of float)
|
||||
0:10 val: direct index for structure ( out highp 4-component vector of float)
|
||||
0:10 'anon@0' ( out block{ out highp 4-component vector of float val})
|
||||
0:10 Constant:
|
||||
0:10 0 (const uint)
|
||||
0:10 Constant:
|
||||
0:10 0.500000
|
||||
0:10 0.500000
|
||||
0:10 0.500000
|
||||
0:10 0.500000
|
||||
0:11 move second child to first child ( temp highp 4-component vector of float)
|
||||
0:11 'color' ( smooth out highp 4-component vector of float)
|
||||
0:11 Constant:
|
||||
0:11 1.000000
|
||||
0:11 1.000000
|
||||
0:11 1.000000
|
||||
0:11 1.000000
|
||||
0:12 move second child to first child ( temp 4-component vector of float)
|
||||
0:12 gl_Position: direct index for structure ( gl_Position 4-component vector of float Position)
|
||||
0:12 'anon@1' ( out block{ gl_Position 4-component vector of float Position gl_Position, gl_PointSize float PointSize gl_PointSize, out unsized 1-element array of float ClipDistance gl_ClipDistance, out unsized 1-element array of float CullDistance gl_CullDistance})
|
||||
0:12 Constant:
|
||||
0:12 0 (const uint)
|
||||
0:12 Constant:
|
||||
0:12 1.000000
|
||||
0:12 1.000000
|
||||
0:12 1.000000
|
||||
0:12 1.000000
|
||||
0:? Linker Objects
|
||||
0:? 'anon@0' ( out block{ out highp 4-component vector of float val})
|
||||
0:? 'color' ( smooth out highp 4-component vector of float)
|
||||
0:? 'anon@1' ( out block{ gl_Position 4-component vector of float Position gl_Position, gl_PointSize float PointSize gl_PointSize, out unsized 1-element array of float ClipDistance gl_ClipDistance, out unsized 1-element array of float CullDistance gl_CullDistance})
|
||||
|
||||
iomap.crossStage.vk.2.geom
|
||||
Shader version: 460
|
||||
invocations = -1
|
||||
max_vertices = 3
|
||||
input primitive = points
|
||||
output primitive = triangle_strip
|
||||
0:? Sequence
|
||||
0:23 Function Definition: main( ( global void)
|
||||
0:23 Function Parameters:
|
||||
0:25 Sequence
|
||||
0:25 Sequence
|
||||
0:25 Sequence
|
||||
0:25 move second child to first child ( temp highp int)
|
||||
0:25 'i' ( temp highp int)
|
||||
0:25 Constant:
|
||||
0:25 0 (const int)
|
||||
0:25 Loop with condition tested first
|
||||
0:25 Loop Condition
|
||||
0:25 Compare Less Than ( temp bool)
|
||||
0:25 'i' ( temp highp int)
|
||||
0:25 Constant:
|
||||
0:25 3 (const int)
|
||||
0:25 Loop Body
|
||||
0:26 Sequence
|
||||
0:26 move second child to first child ( temp highp 4-component vector of float)
|
||||
0:26 'colorOut' (layout( stream=0) out highp 4-component vector of float)
|
||||
0:26 component-wise multiply ( temp highp 4-component vector of float)
|
||||
0:26 indirect index ( temp highp 4-component vector of float)
|
||||
0:26 'color' ( in 1-element array of highp 4-component vector of float)
|
||||
0:26 'i' ( temp highp int)
|
||||
0:26 val: direct index for structure ( in highp 4-component vector of float)
|
||||
0:26 indirect index ( temp block{ in highp 4-component vector of float val})
|
||||
0:26 'vv' ( in 1-element array of block{ in highp 4-component vector of float val})
|
||||
0:26 'i' ( temp highp int)
|
||||
0:26 Constant:
|
||||
0:26 0 (const int)
|
||||
0:27 move second child to first child ( temp highp 4-component vector of float)
|
||||
0:27 vv2Val: direct index for structure (layout( stream=0) out highp 4-component vector of float)
|
||||
0:27 'anon@0' (layout( stream=0) out block{layout( stream=0) out highp 4-component vector of float vv2Val})
|
||||
0:27 Constant:
|
||||
0:27 0 (const uint)
|
||||
0:27 Constant:
|
||||
0:27 1.000000
|
||||
0:27 1.000000
|
||||
0:27 1.000000
|
||||
0:27 1.000000
|
||||
0:28 EmitVertex ( global void)
|
||||
0:25 Loop Terminal Expression
|
||||
0:25 Post-Increment ( temp highp int)
|
||||
0:25 'i' ( temp highp int)
|
||||
0:30 EndPrimitive ( global void)
|
||||
0:? Linker Objects
|
||||
0:? 'vgo1' ( in 1-element array of highp 4-component vector of float)
|
||||
0:? 'color' ( in 1-element array of highp 4-component vector of float)
|
||||
0:? 'colorOut' (layout( stream=0) out highp 4-component vector of float)
|
||||
0:? 'vv' ( in 1-element array of block{ in highp 4-component vector of float val})
|
||||
0:? 'anon@0' (layout( stream=0) out block{layout( stream=0) out highp 4-component vector of float vv2Val})
|
||||
|
||||
iomap.crossStage.vk.2.frag
|
||||
Shader version: 460
|
||||
gl_FragCoord origin is upper left
|
||||
0:? Sequence
|
||||
0:19 Function Definition: main( ( global void)
|
||||
0:19 Function Parameters:
|
||||
0:21 Sequence
|
||||
0:21 move second child to first child ( temp highp 4-component vector of float)
|
||||
0:21 'fragColor' ( out highp 4-component vector of float)
|
||||
0:21 add ( temp highp 4-component vector of float)
|
||||
0:21 'colorOut' ( smooth in highp 4-component vector of float)
|
||||
0:21 component-wise multiply ( temp highp 4-component vector of float)
|
||||
0:21 component-wise multiply ( temp highp 4-component vector of float)
|
||||
0:21 component-wise multiply ( temp highp 4-component vector of float)
|
||||
0:21 'unsetColor' ( smooth in highp 4-component vector of float)
|
||||
0:21 Construct vec4 ( temp highp 4-component vector of float)
|
||||
0:21 vector swizzle ( temp highp 4-component vector of float)
|
||||
0:21 val: direct index for structure ( in highp 2-component vector of float)
|
||||
0:21 'iVert' ( in block{ in highp 2-component vector of float val})
|
||||
0:21 Constant:
|
||||
0:21 0 (const int)
|
||||
0:21 Sequence
|
||||
0:21 Constant:
|
||||
0:21 0 (const int)
|
||||
0:21 Constant:
|
||||
0:21 0 (const int)
|
||||
0:21 Constant:
|
||||
0:21 1 (const int)
|
||||
0:21 Constant:
|
||||
0:21 1 (const int)
|
||||
0:21 Construct vec4 ( temp highp 4-component vector of float)
|
||||
0:21 vector swizzle ( temp highp 4-component vector of float)
|
||||
0:21 val2: direct index for structure ( in highp 2-component vector of float)
|
||||
0:21 'anon@0' ( in block{ in highp 2-component vector of float val2})
|
||||
0:21 Constant:
|
||||
0:21 0 (const uint)
|
||||
0:21 Sequence
|
||||
0:21 Constant:
|
||||
0:21 0 (const int)
|
||||
0:21 Constant:
|
||||
0:21 0 (const int)
|
||||
0:21 Constant:
|
||||
0:21 1 (const int)
|
||||
0:21 Constant:
|
||||
0:21 1 (const int)
|
||||
0:22 'vv2Val' ( smooth in highp 4-component vector of float)
|
||||
0:? Linker Objects
|
||||
0:? 'unsetColor' ( smooth in highp 4-component vector of float)
|
||||
0:? 'colorOut' ( smooth in highp 4-component vector of float)
|
||||
0:? 'fragColor' ( out highp 4-component vector of float)
|
||||
0:? 'iVert' ( in block{ in highp 2-component vector of float val})
|
||||
0:? 'anon@0' ( in block{ in highp 2-component vector of float val2})
|
||||
0:? 'vv2Val' ( smooth in highp 4-component vector of float)
|
||||
|
||||
|
||||
Linked vertex stage:
|
||||
|
||||
|
||||
Linked geometry stage:
|
||||
|
||||
|
||||
Linked fragment stage:
|
||||
|
||||
ERROR: Linking vertex and geometry stages: Input 'vgo1' in geometry shader has no corresponding output in vertex shader.
|
||||
ERROR: Linking geometry and fragment stages: Input 'unsetColor' in fragment shader has no corresponding output in geometry shader.
|
||||
ERROR: Linking geometry and fragment stages: Input 'Vertex' in fragment shader has no corresponding output in geometry shader.
|
||||
ERROR: Linking geometry and fragment stages: Input 'Vertex2' in fragment shader has no corresponding output in geometry shader.
|
||||
ERROR: Linking geometry and fragment stages: Input 'vv2Val' in fragment shader has no corresponding output in geometry shader.
|
||||
|
||||
Shader version: 460
|
||||
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 4-component vector of float)
|
||||
0:10 val: direct index for structure ( out highp 4-component vector of float)
|
||||
0:10 'anon@0' ( out block{ out highp 4-component vector of float val})
|
||||
0:10 Constant:
|
||||
0:10 0 (const uint)
|
||||
0:10 Constant:
|
||||
0:10 0.500000
|
||||
0:10 0.500000
|
||||
0:10 0.500000
|
||||
0:10 0.500000
|
||||
0:11 move second child to first child ( temp highp 4-component vector of float)
|
||||
0:11 'color' ( smooth out highp 4-component vector of float)
|
||||
0:11 Constant:
|
||||
0:11 1.000000
|
||||
0:11 1.000000
|
||||
0:11 1.000000
|
||||
0:11 1.000000
|
||||
0:12 move second child to first child ( temp 4-component vector of float)
|
||||
0:12 gl_Position: direct index for structure ( gl_Position 4-component vector of float Position)
|
||||
0:12 'anon@1' ( out block{ gl_Position 4-component vector of float Position gl_Position, gl_PointSize float PointSize gl_PointSize, out 1-element array of float ClipDistance gl_ClipDistance, out 1-element array of float CullDistance gl_CullDistance})
|
||||
0:12 Constant:
|
||||
0:12 0 (const uint)
|
||||
0:12 Constant:
|
||||
0:12 1.000000
|
||||
0:12 1.000000
|
||||
0:12 1.000000
|
||||
0:12 1.000000
|
||||
0:? Linker Objects
|
||||
0:? 'anon@0' ( out block{ out highp 4-component vector of float val})
|
||||
0:? 'color' ( smooth out highp 4-component vector of float)
|
||||
0:? 'anon@1' ( out block{ gl_Position 4-component vector of float Position gl_Position, gl_PointSize float PointSize gl_PointSize, out 1-element array of float ClipDistance gl_ClipDistance, out 1-element array of float CullDistance gl_CullDistance})
|
||||
Shader version: 460
|
||||
invocations = 1
|
||||
max_vertices = 3
|
||||
input primitive = points
|
||||
output primitive = triangle_strip
|
||||
0:? Sequence
|
||||
0:23 Function Definition: main( ( global void)
|
||||
0:23 Function Parameters:
|
||||
0:25 Sequence
|
||||
0:25 Sequence
|
||||
0:25 Sequence
|
||||
0:25 move second child to first child ( temp highp int)
|
||||
0:25 'i' ( temp highp int)
|
||||
0:25 Constant:
|
||||
0:25 0 (const int)
|
||||
0:25 Loop with condition tested first
|
||||
0:25 Loop Condition
|
||||
0:25 Compare Less Than ( temp bool)
|
||||
0:25 'i' ( temp highp int)
|
||||
0:25 Constant:
|
||||
0:25 3 (const int)
|
||||
0:25 Loop Body
|
||||
0:26 Sequence
|
||||
0:26 move second child to first child ( temp highp 4-component vector of float)
|
||||
0:26 'colorOut' (layout( stream=0) out highp 4-component vector of float)
|
||||
0:26 component-wise multiply ( temp highp 4-component vector of float)
|
||||
0:26 indirect index ( temp highp 4-component vector of float)
|
||||
0:26 'color' ( in 1-element array of highp 4-component vector of float)
|
||||
0:26 'i' ( temp highp int)
|
||||
0:26 val: direct index for structure ( in highp 4-component vector of float)
|
||||
0:26 indirect index ( temp block{ in highp 4-component vector of float val})
|
||||
0:26 'vv' ( in 1-element array of block{ in highp 4-component vector of float val})
|
||||
0:26 'i' ( temp highp int)
|
||||
0:26 Constant:
|
||||
0:26 0 (const int)
|
||||
0:27 move second child to first child ( temp highp 4-component vector of float)
|
||||
0:27 vv2Val: direct index for structure (layout( stream=0) out highp 4-component vector of float)
|
||||
0:27 'anon@0' (layout( stream=0) out block{layout( stream=0) out highp 4-component vector of float vv2Val})
|
||||
0:27 Constant:
|
||||
0:27 0 (const uint)
|
||||
0:27 Constant:
|
||||
0:27 1.000000
|
||||
0:27 1.000000
|
||||
0:27 1.000000
|
||||
0:27 1.000000
|
||||
0:28 EmitVertex ( global void)
|
||||
0:25 Loop Terminal Expression
|
||||
0:25 Post-Increment ( temp highp int)
|
||||
0:25 'i' ( temp highp int)
|
||||
0:30 EndPrimitive ( global void)
|
||||
0:? Linker Objects
|
||||
0:? 'vgo1' ( in 1-element array of highp 4-component vector of float)
|
||||
0:? 'color' ( in 1-element array of highp 4-component vector of float)
|
||||
0:? 'colorOut' (layout( stream=0) out highp 4-component vector of float)
|
||||
0:? 'vv' ( in 1-element array of block{ in highp 4-component vector of float val})
|
||||
0:? 'anon@0' (layout( stream=0) out block{layout( stream=0) out highp 4-component vector of float vv2Val})
|
||||
Shader version: 460
|
||||
gl_FragCoord origin is upper left
|
||||
0:? Sequence
|
||||
0:19 Function Definition: main( ( global void)
|
||||
0:19 Function Parameters:
|
||||
0:21 Sequence
|
||||
0:21 move second child to first child ( temp highp 4-component vector of float)
|
||||
0:21 'fragColor' ( out highp 4-component vector of float)
|
||||
0:21 add ( temp highp 4-component vector of float)
|
||||
0:21 'colorOut' ( smooth in highp 4-component vector of float)
|
||||
0:21 component-wise multiply ( temp highp 4-component vector of float)
|
||||
0:21 component-wise multiply ( temp highp 4-component vector of float)
|
||||
0:21 component-wise multiply ( temp highp 4-component vector of float)
|
||||
0:21 'unsetColor' ( smooth in highp 4-component vector of float)
|
||||
0:21 Construct vec4 ( temp highp 4-component vector of float)
|
||||
0:21 vector swizzle ( temp highp 4-component vector of float)
|
||||
0:21 val: direct index for structure ( in highp 2-component vector of float)
|
||||
0:21 'iVert' ( in block{ in highp 2-component vector of float val})
|
||||
0:21 Constant:
|
||||
0:21 0 (const int)
|
||||
0:21 Sequence
|
||||
0:21 Constant:
|
||||
0:21 0 (const int)
|
||||
0:21 Constant:
|
||||
0:21 0 (const int)
|
||||
0:21 Constant:
|
||||
0:21 1 (const int)
|
||||
0:21 Constant:
|
||||
0:21 1 (const int)
|
||||
0:21 Construct vec4 ( temp highp 4-component vector of float)
|
||||
0:21 vector swizzle ( temp highp 4-component vector of float)
|
||||
0:21 val2: direct index for structure ( in highp 2-component vector of float)
|
||||
0:21 'anon@0' ( in block{ in highp 2-component vector of float val2})
|
||||
0:21 Constant:
|
||||
0:21 0 (const uint)
|
||||
0:21 Sequence
|
||||
0:21 Constant:
|
||||
0:21 0 (const int)
|
||||
0:21 Constant:
|
||||
0:21 0 (const int)
|
||||
0:21 Constant:
|
||||
0:21 1 (const int)
|
||||
0:21 Constant:
|
||||
0:21 1 (const int)
|
||||
0:22 'vv2Val' ( smooth in highp 4-component vector of float)
|
||||
0:? Linker Objects
|
||||
0:? 'unsetColor' ( smooth in highp 4-component vector of float)
|
||||
0:? 'colorOut' ( smooth in highp 4-component vector of float)
|
||||
0:? 'fragColor' ( out highp 4-component vector of float)
|
||||
0:? 'iVert' ( in block{ in highp 2-component vector of float val})
|
||||
0:? 'anon@0' ( in block{ in highp 2-component vector of float val2})
|
||||
0:? 'vv2Val' ( smooth in highp 4-component vector of float)
|
||||
Mismatched cross-stage IO
|
||||
|
||||
Validation failed
|
||||
SPIR-V is not generated for failed compile or link
|
24
Test/iomap.crossStage.vk.2.frag
Executable file
24
Test/iomap.crossStage.vk.2.frag
Executable file
@ -0,0 +1,24 @@
|
||||
#version 460
|
||||
|
||||
in vec4 unsetColor;
|
||||
in vec4 colorOut;
|
||||
out vec4 fragColor;
|
||||
|
||||
in Vertex
|
||||
{
|
||||
vec2 val;
|
||||
} iVert;
|
||||
|
||||
in Vertex2
|
||||
{
|
||||
vec2 val2;
|
||||
};
|
||||
|
||||
in vec4 vv2Val;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = colorOut + unsetColor * vec4(iVert.val.xxyy) * vec4(val2.xxyy) *
|
||||
vv2Val;
|
||||
}
|
||||
|
32
Test/iomap.crossStage.vk.2.geom
Executable file
32
Test/iomap.crossStage.vk.2.geom
Executable file
@ -0,0 +1,32 @@
|
||||
#version 460
|
||||
|
||||
layout(points) in;
|
||||
layout(triangle_strip, max_vertices=3) out;
|
||||
|
||||
// Not written by vertex shader
|
||||
in vec4 vgo1[];
|
||||
|
||||
in vec4 color[];
|
||||
|
||||
out vec4 colorOut;
|
||||
|
||||
in VV
|
||||
{
|
||||
vec4 val;
|
||||
} vv[];
|
||||
|
||||
out VV2
|
||||
{
|
||||
vec4 vv2Val;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
for (int i = 0; i < 3; i++) {
|
||||
colorOut = color[i] * vv[i].val;
|
||||
vv2Val = vec4(1.0);
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
|
14
Test/iomap.crossStage.vk.2.vert
Executable file
14
Test/iomap.crossStage.vk.2.vert
Executable file
@ -0,0 +1,14 @@
|
||||
#version 460
|
||||
|
||||
out VV
|
||||
{
|
||||
vec4 val;
|
||||
};
|
||||
out vec4 color;
|
||||
void main()
|
||||
{
|
||||
val = vec4(0.5);
|
||||
color = vec4(1.0);
|
||||
gl_Position = vec4(1.0);
|
||||
}
|
||||
|
@ -113,6 +113,28 @@ void TIntermediate::mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit
|
||||
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage());
|
||||
}
|
||||
|
||||
static inline bool isSameInterface(TIntermSymbol* symbol, EShLanguage stage, TIntermSymbol* unitSymbol, EShLanguage unitStage) {
|
||||
return // 1) same stage and same shader interface
|
||||
(stage == unitStage && symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) ||
|
||||
// 2) accross stages and both are uniform or buffer
|
||||
(symbol->getQualifier().storage == EvqUniform && unitSymbol->getQualifier().storage == EvqUniform) ||
|
||||
(symbol->getQualifier().storage == EvqBuffer && unitSymbol->getQualifier().storage == EvqBuffer) ||
|
||||
// 3) in/out matched across stage boundary
|
||||
(stage < unitStage && symbol->getQualifier().storage == EvqVaryingOut && unitSymbol->getQualifier().storage == EvqVaryingIn) ||
|
||||
(unitStage < stage && symbol->getQualifier().storage == EvqVaryingIn && unitSymbol->getQualifier().storage == EvqVaryingOut);
|
||||
}
|
||||
|
||||
static bool isSameSymbol(TIntermSymbol* symbol1, EShLanguage stage1, TIntermSymbol* symbol2, EShLanguage stage2) {
|
||||
// If they are both blocks in the same shader interface,
|
||||
// match by the block-name, not the identifier name.
|
||||
if (symbol1->getType().getBasicType() == EbtBlock && symbol2->getType().getBasicType() == EbtBlock) {
|
||||
if (isSameInterface(symbol1, stage1, symbol2, stage2)) {
|
||||
return symbol1->getType().getTypeName() == symbol2->getType().getTypeName();
|
||||
}
|
||||
} else if (symbol1->getName() == symbol2->getName())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
//
|
||||
// do error checking on the shader boundary in / out vars
|
||||
//
|
||||
@ -137,7 +159,32 @@ void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit) {
|
||||
// do matching and error checking
|
||||
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage());
|
||||
|
||||
// TODO: final check; make sure that any statically used `in` have matching `out` written to
|
||||
// Check that all of our inputs have matching outputs from the previous stage.
|
||||
// Only do this for Vulkan, since GL_ARB_separate_shader_objects allows for
|
||||
// the in/out to not match
|
||||
if (spvVersion.vulkan > 0) {
|
||||
for (auto& nextStageInterm : unitLinkerObjects) {
|
||||
auto* nextStageSymbol = nextStageInterm->getAsSymbolNode();
|
||||
bool found = false;
|
||||
for (auto& curStageInterm : linkerObjects) {
|
||||
if (isSameSymbol(curStageInterm->getAsSymbolNode(), getStage(), nextStageSymbol, unit.getStage())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
TString errmsg;
|
||||
errmsg.append("Input '");
|
||||
if (nextStageSymbol->getType().getBasicType() == EbtBlock)
|
||||
errmsg.append(nextStageSymbol->getType().getTypeName());
|
||||
else
|
||||
errmsg.append(nextStageSymbol->getName());
|
||||
errmsg.append("' in ").append(StageName(unit.getStage()));
|
||||
errmsg.append(" shader has no corresponding output in ").append(StageName(getStage())).append(" shader.");
|
||||
error(infoSink, errmsg.c_str(), unit.getStage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit)
|
||||
@ -511,17 +558,6 @@ void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, c
|
||||
globals.insert(globals.end() - 1, unitGlobals.begin(), unitGlobals.end() - 1);
|
||||
}
|
||||
|
||||
static inline bool isSameInterface(TIntermSymbol* symbol, EShLanguage stage, TIntermSymbol* unitSymbol, EShLanguage unitStage) {
|
||||
return // 1) same stage and same shader interface
|
||||
(stage == unitStage && symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) ||
|
||||
// 2) accross stages and both are uniform or buffer
|
||||
(symbol->getQualifier().storage == EvqUniform && unitSymbol->getQualifier().storage == EvqUniform) ||
|
||||
(symbol->getQualifier().storage == EvqBuffer && unitSymbol->getQualifier().storage == EvqBuffer) ||
|
||||
// 3) in/out matched across stage boundary
|
||||
(stage < unitStage && symbol->getQualifier().storage == EvqVaryingOut && unitSymbol->getQualifier().storage == EvqVaryingIn) ||
|
||||
(unitStage < stage && symbol->getQualifier().storage == EvqVaryingIn && unitSymbol->getQualifier().storage == EvqVaryingOut);
|
||||
}
|
||||
|
||||
//
|
||||
// Global Unfiform block stores any default uniforms (i.e. uniforms without a block)
|
||||
// If two linked stages declare the same member, they are meant to be the same uniform
|
||||
@ -707,24 +743,18 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
|
||||
// Error check and merge the linker objects (duplicates should not be created)
|
||||
std::size_t initialNumLinkerObjects = linkerObjects.size();
|
||||
for (unsigned int unitLinkObj = 0; unitLinkObj < unitLinkerObjects.size(); ++unitLinkObj) {
|
||||
TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode();
|
||||
bool merge = true;
|
||||
|
||||
// Don't merge inputs backwards into previous stages
|
||||
if (getStage() != unitStage && unitSymbol->getQualifier().storage == EvqVaryingIn)
|
||||
merge = false;
|
||||
|
||||
for (std::size_t linkObj = 0; linkObj < initialNumLinkerObjects; ++linkObj) {
|
||||
TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode();
|
||||
TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode();
|
||||
assert(symbol && unitSymbol);
|
||||
|
||||
bool isSameSymbol = false;
|
||||
// If they are both blocks in the same shader interface,
|
||||
// match by the block-name, not the identifier name.
|
||||
if (symbol->getType().getBasicType() == EbtBlock && unitSymbol->getType().getBasicType() == EbtBlock) {
|
||||
if (isSameInterface(symbol, getStage(), unitSymbol, unitStage)) {
|
||||
isSameSymbol = symbol->getType().getTypeName() == unitSymbol->getType().getTypeName();
|
||||
}
|
||||
}
|
||||
else if (symbol->getName() == unitSymbol->getName())
|
||||
isSameSymbol = true;
|
||||
|
||||
if (isSameSymbol) {
|
||||
if (isSameSymbol(symbol, getStage(), unitSymbol, unitStage)) {
|
||||
// filter out copy
|
||||
merge = false;
|
||||
|
||||
|
@ -345,6 +345,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
{{"iomap.variableOutBlockIn.2.vert", "iomap.variableOutBlockIn.geom"}, Semantics::OpenGL},
|
||||
// vulkan semantics
|
||||
{{"iomap.crossStage.vk.vert", "iomap.crossStage.vk.geom", "iomap.crossStage.vk.frag" }, Semantics::Vulkan},
|
||||
{{"iomap.crossStage.vk.2.vert", "iomap.crossStage.vk.2.geom", "iomap.crossStage.vk.2.frag" }, Semantics::Vulkan},
|
||||
}))
|
||||
);
|
||||
// clang-format on
|
||||
|
Loading…
Reference in New Issue
Block a user