29/03/2015 March 2015 OpenGL drivers status and FB sRGB conversions

After a long 8 months pause, once again, I tested my OpenGL samples on available OpenGL desktop drivers. This post is a report on whether these samples ran successfully. My OpenGL samples are not a conformance test, only a set of 212 OpenGL code samples I accumulated over time. I haven't updated MacOSX or Linux results.

Focus on sRGB framebuffer conversion with OpenGL and OpenGL ES

sRGB conversions is typically a pretty buggy area particularly on MacOSX. On Windows, it looks like that every hardware vendors got it somewhat wrong with OpenGL core and compatibility profile. How to explain this? AMD and Intel have followed NVIDIA behaviors which dominates the OpenGL desktop ecosystem.

This is attitude of following NVIDIA behaviors is pretty striking considering for example that Intel behaviors used to make the most sense and used to follow the specification.

However, NVIDIA behavior is not correct to my understanding build from reading the OpenGL specification and many experiments. Not following the specification is not necessary a bad thing as we observe on the point rendering case study, however on the framebuffer sRGB conversion case, NVIDIA behavior only implies rendering garbage as shown in figure 3. So, what the OpenGL core profile specification says?

If FRAMEBUFFER_SRGB is enabled and the value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the framebuffer attachment corresponding to the destination buffer is SRGB (see section 6.1.3), the R, G, and B values after blending are converted into the non-linear sRGB color space. OpenGL core framebuffer sRGB conversion rules

OpenGL ES is slightly different: GL_FRAMEBUFFER_SRGB doesn't exist so that framebuffer sRGB conversion only depends on the GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING.

If the value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the framebuffer attachment corresponding to the destination buffer is SRGB (see section 9.2.3), the R, G, and B values after blending are converted into the non-linear sRGB color space. OpenGL ES framebuffer sRGB conversion rules

This hightlight a OpenGL core and OpenGL ES incompatibility: OpenGL ES behaves as if GL_FRAMEBUFFER_SRGB was already enabled where on desktop GL_FRAMEBUFFER_SRGB is disabled by default.

Following this reasonning a quick interpretation would be that to handle this imcompatibility, we could simply enable GL_FRAMEBUFFER_SRGB at initialization on desktop. Unfortunately, this is not working in practice as shown in figure 3.

Figure 1: Fully linear framebuffer rendering
Figure 1: Fully linear framebuffer rendering
Figure 2: sRGB intermediate framebuffer with explicitly disable conversion on default framebuffer
Figure 2: sRGB intermediate framebuffer with explicitly disable conversion on default framebuffer
Figure 3: Always enabled framebuffer sRGB conversion on OpenGL core profile: What we see here is sRGB data being interpreted as RGB, just as in 5
Figure 3: Always enabled framebuffer sRGB conversion on OpenGL core profile: What we see here is sRGB data being interpreted as RGB, just as in 5
Figure 4: Always enabled framebuffer sRGB conversion on OpenGL ES profile
Figure 4: Always enabled framebuffer sRGB conversion on OpenGL ES profile
Figure 5: Sample a sRGB texture (with sRGB data) without doing a sRGB to linear RGB conversion
Figure 5: Sample a sRGB texture (with sRGB data) without doing a sRGB to linear RGB conversion

As a result, a default behavior on ES profile (4) results in a completely wrong output on core profile (3).

Intel (with only new drivers) and AMD behave just like NVIDIA except regarding the GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING query on the default framebuffer: Intel and AMD returns GL_SRGB and NVIDIA returns GL_LINEAR.

IF FRAMEBUFFER_BINDING is 0 then if FRAMEBUFFER_SRGB is enabled, the R, G, and B values after blending are converted into the non-linear sRGB color space. Otherwise, follow the specification. Observed NVIDIA framebuffer sRGB conversion rule on OpenGL core

Where NVIDIA behavior has obviously a bug, Intel and AMD behavior might be the result of a specification bug: WGL_framebuffer_sRGB despite being ratified in 2008, never had the luxury to get it's specification written.

21) Where's the specification language for the GLX and WGL pixel format selection interface? TO BE DONE. The {GLX,WGL}_FRAMEBUFFER_SRGB_CAPABLE_ARB pixel format attributes are used to select default framebuffers which are sRGB-capable in the fairly obvious way, but this language was missing in the original EXT_framebuffer_sRGB and needs to be added here. framebuffer_sRGB: issue 21

With Windows 7, all the default framebuffers are sRGB capable however there is no way to explicitly request a linear or sRGB color encoding. Additionally, maybe the default framebuffer is effectively sRGB however Windows compositor interprets sRGB values as linear RGB values anyway hence producing the result in figure 3 and 5. This would mean that Windows effectively doesn't support sRGB framebuffer natively which would be shocking but not impossible. If someone has information at OS level, I'll enjoy to get some inputs!

In any case, we need a proper WGL_framebuffer_sRGB specification allowing to create a linear RGB or sRGB default framebuffer explicitly but also defining sRGB conversions on the default framebuffer.

How to workaround sRGB framebuffer conversions issues on Windows?
  • void bindFramebuffer(GLuint FramebufferName)
  • {
  • glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
  • // ES doesn't have GL_FRAMEBUFFER_SRGB unless EXT_sRGB_write_control is supported
  • if(HasFramebufferSRGBEnable)
  • {
  • if(FramebufferName == 0)
  • glDisable(GL_FRAMEBUFFER_SRGB);
  • else
  • glEnable(GL_FRAMEBUFFER_SRGB);
  • }
  • }

Unfortunately, on MacOSX and at least some AMD drivers there are more problematic cases. For example, it may happen that we must disable framebuffer sRGB conversion on framebuffer object if the attachments are not using a sRGB framebuffer. Furthremore, sRGB conversions are performed on none or all framebuffer attachments for multiple framebuffer attachments case so that all attachments must use the same color space.

Considering formats such as RGB10A_UNORM or RGBD we might wonder if it's worth bothering with sRGB framebuffers.

OpenGL drivers summary

March 2015 OpenGL samples passing on available implementations
March 2015 OpenGL samples passing on available implementations
July 2014 OpenGL samples passing on available implementations
July 2014 OpenGL samples passing on available implementations
EuroLLVM slides about SPIR-V >
< OpenGL Samples Pack 4.5.1.0 released
Copyright Christophe Riccio 2002-2016 all rights reserved
Designed for Chrome 9, Firefox 4, Opera 11 and Safari 5