Commit 5a867aca by John Kessenich

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

parent ed834895
......@@ -943,8 +943,6 @@ ERROR: Linking tessellation control stage: Multiple function bodies in multiple
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
ERROR: Linking tessellation control stage: Multiple function bodies in multiple compilation units for the same signature in the same stage:
......
......@@ -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;
}
......@@ -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));
}
......@@ -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
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment