Linker: Fix #1329: correctly merge unsized arrays, and fix link tests.

This commit is contained in:
John Kessenich 2018-04-01 21:22:34 -06:00
parent ed834895ea
commit 5a867acad5
6 changed files with 355 additions and 47 deletions

View File

@ -942,8 +942,6 @@ ERROR: Linking tessellation control stage: Multiple function bodies in multiple
main(
ERROR: Linking tessellation control stage: Multiple function bodies in multiple compilation units for the same signature in the same stage:
main(
ERROR: Linking tessellation control stage: Types must match:
gl_out: " out 4-element array of block{ out 4-component vector of float Position gl_Position, out float PointSize gl_PointSize, out unsized 2-element array of float ClipDistance gl_ClipDistance}" versus " out unsized 1-element array of block{ out 4-component vector of float Position gl_Position, out float PointSize gl_PointSize, out unsized 1-element array of float ClipDistance gl_ClipDistance}"
ERROR: Linking tessellation control stage: Types must match:
outa: " global 4-element array of int" versus " global 1-element array of int"
ERROR: Linking tessellation control stage: can't handle multiple entry points per stage

View File

@ -2,30 +2,105 @@ link1.vk.frag
Shader version: 450
gl_FragCoord origin is upper left
0:? Sequence
0:7 Function Definition: main( ( global void)
0:7 Function Parameters:
0:9 Sequence
0:9 move second child to first child ( temp highp 4-component vector of float)
0:9 'color' ( out highp 4-component vector of float)
0:9 Function Call: getColor( ( global highp 4-component vector of float)
0:16 Function Definition: main( ( global void)
0:16 Function Parameters:
0:18 Sequence
0:18 move second child to first child ( temp highp 4-component vector of float)
0:18 'color' (layout( location=0) out highp 4-component vector of float)
0:18 Function Call: getColor( ( global highp 4-component vector of float)
0:20 move second child to first child ( temp highp int)
0:20 direct index ( temp highp int)
0:20 'a1' ( global unsized 9-element array of highp int)
0:20 Constant:
0:20 8 (const int)
0:20 Constant:
0:20 1 (const int)
0:21 move second child to first child ( temp highp int)
0:21 direct index ( temp highp int)
0:21 'a2' ( global unsized 2-element array of highp int)
0:21 Constant:
0:21 1 (const int)
0:21 Constant:
0:21 1 (const int)
0:22 move second child to first child ( temp highp int)
0:22 indirect index ( temp highp int)
0:22 'b' ( global 5-element array of highp int)
0:22 'i' ( global highp int)
0:22 Constant:
0:22 1 (const int)
0:23 move second child to first child ( temp highp int)
0:23 direct index ( temp highp int)
0:23 'c' ( global unsized 4-element array of highp int)
0:23 Constant:
0:23 3 (const int)
0:23 Constant:
0:23 1 (const int)
0:? Linker Objects
0:? 'color' ( out highp 4-component vector of float)
0:? 'color' (layout( location=0) out highp 4-component vector of float)
0:? 'a1' ( global unsized 9-element array of highp int)
0:? 'a2' ( global unsized 2-element array of highp int)
0:? 'b' ( global 5-element array of highp int)
0:? 'c' ( global unsized 4-element array of highp int)
0:? 'i' ( global highp int)
0:? 'anon@0' (layout( column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float r})
0:? 'anon@1' (layout( column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float m})
link2.vk.frag
Shader version: 450
gl_FragCoord origin is upper left
0:? Sequence
0:5 Function Definition: getColor( ( global highp 4-component vector of float)
0:5 Function Parameters:
0:7 Sequence
0:7 Branch: Return with expression
0:7 texture ( global highp 4-component vector of float)
0:7 's2D' (layout( binding=1) uniform highp sampler2D)
0:7 Constant:
0:7 0.500000
0:7 0.500000
0:14 Function Definition: getColor( ( global highp 4-component vector of float)
0:14 Function Parameters:
0:16 Sequence
0:16 move second child to first child ( temp highp int)
0:16 direct index ( temp highp int)
0:16 'a1' ( global unsized 3-element array of highp int)
0:16 Constant:
0:16 2 (const int)
0:16 Constant:
0:16 1 (const int)
0:17 move second child to first child ( temp highp int)
0:17 direct index ( temp highp int)
0:17 'a2' ( global unsized 10-element array of highp int)
0:17 Constant:
0:17 9 (const int)
0:17 Constant:
0:17 1 (const int)
0:18 move second child to first child ( temp highp int)
0:18 direct index ( temp highp int)
0:18 'b' ( global unsized 3-element array of highp int)
0:18 Constant:
0:18 2 (const int)
0:18 Constant:
0:18 1 (const int)
0:19 move second child to first child ( temp highp int)
0:19 direct index ( temp highp int)
0:19 'c' ( global 7-element array of highp int)
0:19 Constant:
0:19 3 (const int)
0:19 Constant:
0:19 1 (const int)
0:20 move second child to first child ( temp highp int)
0:20 indirect index ( temp highp int)
0:20 'c' ( global 7-element array of highp int)
0:20 'i' ( global highp int)
0:20 Constant:
0:20 1 (const int)
0:22 Branch: Return with expression
0:22 texture ( global highp 4-component vector of float)
0:22 's2D' (layout( binding=1) uniform highp sampler2D)
0:22 Constant:
0:22 0.500000
0:22 0.500000
0:? Linker Objects
0:? 's2D' (layout( binding=1) uniform highp sampler2D)
0:? 'a1' ( global unsized 3-element array of highp int)
0:? 'a2' ( global unsized 10-element array of highp int)
0:? 'b' ( global unsized 3-element array of highp int)
0:? 'c' ( global 7-element array of highp int)
0:? 'i' ( global highp int)
0:? 'anon@0' (layout( column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float r})
0:? 'anon@1' (layout( column_major std430) buffer block{layout( column_major std430) buffer 4-element array of highp float m})
Linked fragment stage:
@ -34,23 +109,207 @@ Linked fragment stage:
Shader version: 450
gl_FragCoord origin is upper left
0:? Sequence
0:7 Function Definition: main( ( global void)
0:7 Function Parameters:
0:9 Sequence
0:9 move second child to first child ( temp highp 4-component vector of float)
0:9 'color' ( out highp 4-component vector of float)
0:9 Function Call: getColor( ( global highp 4-component vector of float)
0:5 Function Definition: getColor( ( global highp 4-component vector of float)
0:5 Function Parameters:
0:7 Sequence
0:7 Branch: Return with expression
0:7 texture ( global highp 4-component vector of float)
0:7 's2D' (layout( binding=1) uniform highp sampler2D)
0:7 Constant:
0:7 0.500000
0:7 0.500000
0:16 Function Definition: main( ( global void)
0:16 Function Parameters:
0:18 Sequence
0:18 move second child to first child ( temp highp 4-component vector of float)
0:18 'color' (layout( location=0) out highp 4-component vector of float)
0:18 Function Call: getColor( ( global highp 4-component vector of float)
0:20 move second child to first child ( temp highp int)
0:20 direct index ( temp highp int)
0:20 'a1' ( global 9-element array of highp int)
0:20 Constant:
0:20 8 (const int)
0:20 Constant:
0:20 1 (const int)
0:21 move second child to first child ( temp highp int)
0:21 direct index ( temp highp int)
0:21 'a2' ( global 10-element array of highp int)
0:21 Constant:
0:21 1 (const int)
0:21 Constant:
0:21 1 (const int)
0:22 move second child to first child ( temp highp int)
0:22 indirect index ( temp highp int)
0:22 'b' ( global 5-element array of highp int)
0:22 'i' ( global highp int)
0:22 Constant:
0:22 1 (const int)
0:23 move second child to first child ( temp highp int)
0:23 direct index ( temp highp int)
0:23 'c' ( global 7-element array of highp int)
0:23 Constant:
0:23 3 (const int)
0:23 Constant:
0:23 1 (const int)
0:14 Function Definition: getColor( ( global highp 4-component vector of float)
0:14 Function Parameters:
0:16 Sequence
0:16 move second child to first child ( temp highp int)
0:16 direct index ( temp highp int)
0:16 'a1' ( global 3-element array of highp int)
0:16 Constant:
0:16 2 (const int)
0:16 Constant:
0:16 1 (const int)
0:17 move second child to first child ( temp highp int)
0:17 direct index ( temp highp int)
0:17 'a2' ( global 10-element array of highp int)
0:17 Constant:
0:17 9 (const int)
0:17 Constant:
0:17 1 (const int)
0:18 move second child to first child ( temp highp int)
0:18 direct index ( temp highp int)
0:18 'b' ( global 3-element array of highp int)
0:18 Constant:
0:18 2 (const int)
0:18 Constant:
0:18 1 (const int)
0:19 move second child to first child ( temp highp int)
0:19 direct index ( temp highp int)
0:19 'c' ( global 7-element array of highp int)
0:19 Constant:
0:19 3 (const int)
0:19 Constant:
0:19 1 (const int)
0:20 move second child to first child ( temp highp int)
0:20 indirect index ( temp highp int)
0:20 'c' ( global 7-element array of highp int)
0:20 'i' ( global highp int)
0:20 Constant:
0:20 1 (const int)
0:22 Branch: Return with expression
0:22 texture ( global highp 4-component vector of float)
0:22 's2D' (layout( binding=1) uniform highp sampler2D)
0:22 Constant:
0:22 0.500000
0:22 0.500000
0:? Linker Objects
0:? 'color' ( out highp 4-component vector of float)
0:? 'color' (layout( location=0) out highp 4-component vector of float)
0:? 'a1' ( global 9-element array of highp int)
0:? 'a2' ( global 10-element array of highp int)
0:? 'b' ( global 5-element array of highp int)
0:? 'c' ( global 7-element array of highp int)
0:? 'i' ( global highp int)
0:? 'anon@0' (layout( column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float r})
0:? 'anon@1' (layout( column_major std430) buffer block{layout( column_major std430) buffer 4-element array of highp float m})
0:? 's2D' (layout( binding=1) uniform highp sampler2D)
SPIR-V is not generated for failed compile or link
// Module Version 10000
// Generated by (magic number): 80006
// Id's are bound by 71
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 12
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
Name 4 "main"
Name 9 "getColor("
Name 12 "color"
Name 19 "a1"
Name 27 "a2"
Name 32 "b"
Name 33 "i"
Name 39 "c"
Name 54 "s2D"
Name 63 "bnameRuntime"
MemberName 63(bnameRuntime) 0 "r"
Name 65 ""
Name 68 "bnameImplicit"
MemberName 68(bnameImplicit) 0 "m"
Name 70 ""
Decorate 12(color) Location 0
Decorate 54(s2D) DescriptorSet 0
Decorate 54(s2D) Binding 1
Decorate 62 ArrayStride 4
MemberDecorate 63(bnameRuntime) 0 Offset 0
Decorate 63(bnameRuntime) BufferBlock
Decorate 65 DescriptorSet 0
Decorate 67 ArrayStride 4
MemberDecorate 68(bnameImplicit) 0 Offset 0
Decorate 68(bnameImplicit) BufferBlock
Decorate 70 DescriptorSet 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypeFunction 7(fvec4)
11: TypePointer Output 7(fvec4)
12(color): 11(ptr) Variable Output
14: TypeInt 32 1
15: TypeInt 32 0
16: 15(int) Constant 9
17: TypeArray 14(int) 16
18: TypePointer Private 17
19(a1): 18(ptr) Variable Private
20: 14(int) Constant 8
21: 14(int) Constant 1
22: TypePointer Private 14(int)
24: 15(int) Constant 10
25: TypeArray 14(int) 24
26: TypePointer Private 25
27(a2): 26(ptr) Variable Private
29: 15(int) Constant 5
30: TypeArray 14(int) 29
31: TypePointer Private 30
32(b): 31(ptr) Variable Private
33(i): 22(ptr) Variable Private
36: 15(int) Constant 7
37: TypeArray 14(int) 36
38: TypePointer Private 37
39(c): 38(ptr) Variable Private
40: 14(int) Constant 3
42: 14(int) Constant 2
43: TypePointer Output 6(float)
45: 14(int) Constant 9
51: TypeImage 6(float) 2D sampled format:Unknown
52: TypeSampledImage 51
53: TypePointer UniformConstant 52
54(s2D): 53(ptr) Variable UniformConstant
56: TypeVector 6(float) 2
57: 6(float) Constant 1056964608
58: 56(fvec2) ConstantComposite 57 57
62: TypeRuntimeArray 6(float)
63(bnameRuntime): TypeStruct 62
64: TypePointer Uniform 63(bnameRuntime)
65: 64(ptr) Variable Uniform
66: 15(int) Constant 4
67: TypeArray 6(float) 66
68(bnameImplicit): TypeStruct 67
69: TypePointer Uniform 68(bnameImplicit)
70: 69(ptr) Variable Uniform
4(main): 2 Function None 3
5: Label
13: 7(fvec4) FunctionCall 9(getColor()
Store 12(color) 13
23: 22(ptr) AccessChain 19(a1) 20
Store 23 21
28: 22(ptr) AccessChain 27(a2) 21
Store 28 21
34: 14(int) Load 33(i)
35: 22(ptr) AccessChain 32(b) 34
Store 35 21
41: 22(ptr) AccessChain 39(c) 40
Store 41 21
Return
FunctionEnd
9(getColor(): 7(fvec4) Function None 8
10: Label
44: 43(ptr) AccessChain 12(color) 42
Store 44 21
46: 22(ptr) AccessChain 19(a1) 45
Store 46 21
47: 22(ptr) AccessChain 27(a2) 42
Store 47 21
48: 22(ptr) AccessChain 32(b) 40
Store 48 21
49: 37 Load 39(c)
50: 22(ptr) AccessChain 32(b) 49
Store 50 21
55: 52 Load 54(s2D)
59: 7(fvec4) ImageSampleImplicitLod 55 58
ReturnValue 59
FunctionEnd

View File

@ -2,9 +2,23 @@
vec4 getColor();
out vec4 color;
layout(location=0) out vec4 color;
int a1[]; // max size from link1
int a2[]; // max size from link2
int b[5];
int c[];
int i;
buffer bnameRuntime { float r[]; };
buffer bnameImplicit { float m[]; };
void main()
{
color = getColor();
a1[8] = 1;
a2[1] = 1;
b[i] = 1;
c[3] = 1;
}

View File

@ -2,7 +2,22 @@
layout(binding=1) uniform sampler2D s2D;
int a1[]; // max size from link1
int a2[]; // max size from link2
int b[];
int c[7];
int i;
buffer bnameRuntime { float r[]; };
buffer bnameImplicit { float m[4]; };
vec4 getColor()
{
return texture(s2D, vec2(0.5));
a1[2] = 1;
a2[9] = 1;
b[2] = 1;
c[3] = 1;
c[i] = 1;
return texture(s2D, vec2(0.5));
}

View File

@ -268,12 +268,13 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
// Recursively merge the implicit array sizes through the objects' respective type trees.
void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType)
{
if (type.isUnsizedArray() && unitType.isArray()) {
int newImplicitArraySize = unitType.isSizedArray() ? unitType.getOuterArraySize() :
unitType.getImplicitArraySize();
type.updateImplicitArraySize(type.getImplicitArraySize());
if (unitType.isArrayVariablyIndexed())
type.setArrayVariablyIndexed();
if (type.isUnsizedArray()) {
if (unitType.isUnsizedArray()) {
type.updateImplicitArraySize(unitType.getImplicitArraySize());
if (unitType.isArrayVariablyIndexed())
type.setArrayVariablyIndexed();
} else if (unitType.isSizedArray())
type.changeOuterArraySize(unitType.getOuterArraySize());
}
// Type mismatches are caught and reported after this, just be careful for now.
@ -296,8 +297,13 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
// Types have to match
if (symbol.getType() != unitSymbol.getType()) {
error(infoSink, "Types must match:");
writeTypeComparison = true;
// but, we make an exception if one is an implicit array and the other is sized
if (! (symbol.getType().isArray() && unitSymbol.getType().isArray() &&
symbol.getType().sameElementType(unitSymbol.getType()) &&
(symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()))) {
error(infoSink, "Types must match:");
writeTypeComparison = true;
}
}
// Qualifiers have to (almost) match

View File

@ -52,6 +52,7 @@ TEST_P(LinkTestVulkan, FromFile)
GlslangResult result;
// Compile each input shader file.
bool success = true;
std::vector<std::unique_ptr<glslang::TShader>> shaders;
for (size_t i = 0; i < fileCount; ++i) {
std::string contents;
@ -61,7 +62,7 @@ TEST_P(LinkTestVulkan, FromFile)
new glslang::TShader(GetShaderStage(GetSuffix(fileNames[i]))));
auto* shader = shaders.back().get();
shader->setAutoMapLocations(true);
compile(shader, contents, "", controls);
success &= compile(shader, contents, "", controls);
result.shaderResults.push_back(
{fileNames[i], shader->getInfoLog(), shader->getInfoDebugLog()});
}
@ -69,10 +70,25 @@ TEST_P(LinkTestVulkan, FromFile)
// Link all of them.
glslang::TProgram program;
for (const auto& shader : shaders) program.addShader(shader.get());
program.link(controls);
success &= program.link(controls);
result.linkingOutput = program.getInfoLog();
result.linkingError = program.getInfoDebugLog();
if (success && (controls & EShMsgSpvRules)) {
spv::SpvBuildLogger logger;
std::vector<uint32_t> spirv_binary;
glslang::SpvOptions options;
options.disableOptimizer = true;
glslang::GlslangToSpv(*program.getIntermediate(shaders.front()->getStage()),
spirv_binary, &logger, &options);
std::ostringstream disassembly_stream;
spv::Parameterize();
spv::Disassemble(disassembly_stream, spirv_binary);
result.spirvWarningsErrors = logger.getAllMessages();
result.spirv = disassembly_stream.str();
}
std::ostringstream stream;
outputResultToStream(&stream, result, controls);