RenderingPipeline

from geometry to pixels

MacOS X OpenGL driver bugs

Once in a while I run across a bug in Apples OpenGL implementation. Providing an up-to-date and performant OpenGL implementation is not an easy task, and you have to wonder why Apple tries to do this on there own and not letting Intel, NVidia and AMD provide the drivers as they do on Windows and Linux. Sadly, Apple happens to be not as good as these companies at doing this job.

But hey, you find a bug, report it and the next update will provide you with a fix, right? I wish it would be this quick. Bugs in Apples software can sadly be present for month and even year. So here I want to quickly describe the still open bugs I had to deal with in case you have the same problem (In this case, I guess you googled it, came here and will see that this is in fact a bug).

In case you find a bug, report it at Apples Bug Reporter even if you know it’s already reported – the more reports Apple gets, the higher the bug priority will be set – sad, but true. Oh, and let others know (blogpost, a comment here, the OpenGL forums, Apples forums, wherever, just make it simpler for the next guy to google the problem).

 

Wrong values from uniform structs

I originally found this in December 2011 and filed a report (#10518401). The problem is this: Imagine you have struct in your shader where you mix integer and float types:

struct Defective {
    bool booleanValue; // same with int but not float!
    vec4 color;
};
 
uniform Defective arrayDefective[2];

The problem for Apples implementation is that the bool (or int) comes before the vec4 (it works the other way around). If thisbool gets accessed the value read from the vec4 can be wrong. It also behaves differently if the array arrayDefective gets accessed directly vs. indirectly…

You can try it out with this test app (based on Apples OpenGL example). See the shader character.fsh, depending on the way you access the array (and which you choose) the rendered character will be red (ok) or pink (wrong). Note that the exact behavior of this changed between 10.7.3 and 10.7.4 (less wrong cases) and I can’t reproduce the bug currently on a MacBook Air 2012. I’m not sure whether this is due to the fact that this has the only Intel GPU I tested the problem yet or because the device came with a more recent OpenGL driver (the MBA is way newer than 10.7.4).

 

Wrong names for uniforms in uniform blocks

This bug was reported in april under bug ID #11335828. Uniforms within a uniform block are either just called by there name or you add the block name at the front. What you have to do depends on whether you are dealing with a named or unnamed uniform block. To give an example:

layout(std140) uniform exampleblock
{
    mat4 viewMatrix;
    mat4 projectionMatrix;
};
 
gl_Position = projectionMatrix * viewMatrix * inPosition;

This is an unnamed block, you can query the name of the uniform from the GL with glGetActiveUniformName if you iterate over all active uniforms. This should give you “viewMatrix” and “projectionMatrix”.

layout(std140) uniform exampleblocknamed
{
    mat4 viewMatrix;
    mat4 projectionMatrix;
} nameOfBlock;
 
gl_Position = nameOfBlock.projectionMatrix * nameOfBlock.viewMatrix * inPosition;

Here we have a named block and how to access it in the shader. If you query the name, you should get “exampleblocknamed.viewMatrix” and “exampleblocknamed.projectionMatrix” – yes, “exampleblocknamed…” not “nameOfBlock…”. You can look it up in the GLSL spec 1.50.11, 4.3.7, page 36:

“Outside the shading language (i.e., in the API), members are similarly identified except the block name is always used in place of the instance name (API accesses are to interfaces, not to shaders).
If there is no instance name, then the API does not use the block name to access a member, just the member name.”
 

But Apples drivers don’t know this distinction: They always return the names as if the block would be named! You can test this with this app (also based on Apples example). Note that I don’t set the uniform block but I read values from it (otherwise the uniforms would be trivially detected as not active) so this example might break easily but works on 10.7.4 to show the bug.

 

Rendering to an FBO without fragment data location 0 is not possible

I recently tracked down this issue and filed a bug report: #11826727. As the issue is a bit confusing, I first described the issue in the OpenGL forums but it seems to be in fact a bug.

Lets say we want to draw to one (or more) framebuffer attachments with user defined output names in the fragment shader. We attach the buffers to the FBO and define frag data locations for the user defined fragment shader outputs to start from 1 (and not from 0). To ‘bend’ this frag data locations to the correct attachments, we set glDrawBuffers( 8, {GL_NONE, GL_COLOR_ATTACHMENT0, GL_NONE, …} ) (in case of one attachment).

This should give the same results as not messing with glDrawBuffers and setting the fragment out location to 0 (in case of only one output, 0 is also the default). And it works fine on all systems (Win/Linux, NVidia/AMD) but not on MacOS X. glClear works in this setup and occlusion queries tell me the correct number of fragments being created, but nothing from rendering happens to go into the attached texture.

Again, here’s a test app that shows the issue on 10.7.4. Look at the OpenGLRenderer.m line 1045.

Update: As arekkusu noted in the OpenGL Forums, you have to (re)link the program after changing the fragment data location with glBindFragDataLocation. I did this in my original program but forgot it in the test app, shame on me. It’s now fixed, still with the same bug.

 

Update: I found another one:

Uniform block layout qualifier ‘packed’ results in GLSL compile errors

There are three layout qualifiers: ‘std140’, ‘shared’ and ‘packed’. While ‘std140’ is very clearly defined, ‘shared’ and ‘packed’ can be implementation dependent (giving room for optimizations but sacrificing predictability). A packed block like this one:

layout(packed) uniform exampleblock
{
    mat4 viewMatrix;
    mat4 projectionMatrix;
};

will fail to compile (MacOS X 10.7.4) with the error: “ERROR: 0:123: ‘packed’ : Reserved word. ERROR: 0:123: ‘packed’ : syntax error syntax error” – Yes, the keyword is reserved … for exactly this usage! Bug ID is 11884110.

Seeing this bug is really strange as ‘packed’ is not a new feature and really simple to support – just do the same thing as with ‘std140’ block! The compiler doesn’t have to optimize and ‘shared’ seems to have the same layout as ‘std140’ as well (don’t rely on that, this can change).

See the specs or the OpenGL wiki for further information.

 

Default layouts of Uniform Blocks can’t be changed at global scope

Instead of setting the saw layout per block, one can change the default for all following blocks like this:

layout(shared, column_major) uniform;

This example come right from the GLSL specs for version 150, page 41… but it will give you the GLSL shader compiler error “ERROR: 0:5: Invalid qualifiers ‘uniform’ in global layout context” on MacOS X 10.7.4… Bug ID #11884641.

, , ,

2 thoughts on “MacOS X OpenGL driver bugs
  • Christophe says:

    I tried to reproduce “Wrong names for uniforms in uniform blocks” on a GeForce 9600M and I fail to reproduce it. However, I notice that this bug appears on AMD implementation.

    • Robert says:

      Thanks for the info. I was testing these bugs on an Intel HD 4000. There is some progress in 10.8.3, I will test all bugs again when the final 10.8.3 is out.

Leave a Reply

Your email address will not be published. Required fields are marked *

*