I've got an application that runs an OpenGL 4.5 core context (let's call it context A), and then due to some Qt issues, ends up creating an OpenGL 2.0 context (context B) that's sharing with A.
The bug goes about as follows, if I have my thoughts ordered correctly:
1. A compiles a vertex shader 1 (#version 150) and a fragment shader 2, and links it into a program 3. Mesa looks into its GLSL cache index, and figures that compilation succeeded once, so glCompileShader() returns true without even checking. (However, 1 and 2 have actually disappeared out of the cache already.)
2. B wants to use 3, but can't since it's in use by some other thread and that might disturb its uniforms (I can't use UBOs, since they're very slow in Mesa on Haswell), so it asks to re-link 1+2 into a new program.
3. Mesa notices that it needs to _actually_ compile 1+2, since it can't find them in the disk cache. However, it does so in the context of B, which can't handle #version 150 programs. The compilation fails with a syntax error, but nothing in Mesa actually checks the return value.
4. Mesa tries to link 1+2, even though both failed and thus are empty internally. The error it returns is
Error linking program: error: vertex shader lacks `main'
which is an obviously bogus error.
It's unclear from the spec what should happen, but given that 1 and 2 were compiled in the context of A, I would say that linking them in B should be legal, and it does work if I disable the cache (export MESA_GLSL_CACHE_DISABLE=1). At the very least, it shouldn't complain about the lack of main when main is indeed there.
(In reply to Steinar H. Gunderson from comment #0)
> It's unclear from the spec what should happen, but given that 1 and 2 were
> compiled in the context of A, I would say that linking them in B should be
I disagree. Compiling in one context with a high GL version then linking those compiled shaders in a different context with a lower GL version is asking for trouble. The features that are missing/disabled when compiling in a lower version are likely to not be correctly handled when linking either. Just because it seems to be working with your use case when the cache is disabled doesn't mean it should or always will.
Just to add the missing details here. The reason for the version mismatch is because one context is core and the other is compat were the i965 driver has a maximum compat version of 3.0, but up to 4.5 is support in core. Most other (non-mesa) drivers have always had matched core/compat versions which is likely why the spec has never bothered to cover this mismatch case.
IMO the best solution is to add proper compat support to all drivers. We could improve the error messages but IMO that effort could be better spent working on adding support.
I don't think there is any Mesa bug here and IMO your application needs to check the context version work around the problem.
Well, at the very least, the re-linking should check the return value of the compilation. That could fail for pretty much any reason, no?