[Piglit] long-standing wgl pixel format issue
brianp at vmware.com
Fri Jun 17 15:53:34 UTC 2016
I spent a few hours yesterday pulling out my hair trying to understand
why the piglit fbo-mipmap-copypix test was failing on Windows. But it
was only failing when I ran it directly. It passed when I ran it via
The key difference was the -fbo option. With -fbo the test used an
RGBA8 framebuffer but without -fbo the test used an RGB565 framebuffer.
So why is a 565 framebuffer being used? It boils down to the fact that
wglChoosePixelFormatARB() does not work like glXChooseFBConfig().
From the glXChooseFBConfig man page:
GLX_RED_SIZE, GLX_GREEN_SIZE, GLX_BLUE_SIZE, GLX_ALPHA_SIZE
Each attribute, if present, must be followed by a nonnegative
specification or GLX_DONT_CARE.
The largest available total RGBA color buffer size (sum of
GLX_GREEN_SIZE, GLX_BLUE_SIZE, and GLX_ALPHA_SIZE)
of at least the minimum size specified for each color component is
So if you specify GLX_RED_SIZE, BLUE_SIZE, etc to be 1 and there are
both RGB565 and RGBA8 formats available, the _later_ (the largest) will
But the wglChoosePixelFormatARB docs say:
Some attribute values must match the pixel format value exactly when
the attribute is specified while others specify a minimum criteria,
meaning that the pixel format value must meet or exceed the
Attribute Type Match Criteria
WGL_RED_BITS_ARB integer minimum
WGL_GREEN_BITS_ARB integer minimum
WGL_BLUE_BITS_ARB integer minimum
WGL_ALPHA_BITS_ARB integer minimum
So if you specify WGL_RED/GREEN/BLUE_BITS_ARB to be 1 and there are both
RGB565 and RGBA8 formats available, the _former_ may be chosen. Note
that some WGL apps use WGL_COLOR_BITS_ARB=24 and avoid this.
Piglit's call to piglit_wfl_framework_init() uses an attribute list with
WAFFLE_RED/GREEN/BLUE_SIZE = 1 and that winds up going directly to
wglChoosePixelFormatARB and glXChooseFBConfig so this difference in
behavior effects the window's pixel format.
The Waffle docs for waffle_config_choose() say:
The default value for each size attribute is 0. Valid values are
the non-negative integers and WAFFLE_DONT_CARE. If the requested size
for a channel is 0, then any surface created with the config will lack
that channel. If the requested size for a channel is positive, then the
number of bits in that channel for any surface created with the config
will be at least the requested size.
There's some ambiguity here because if several different pixel formats
(such as RGB565 and RGBA8) both meet the WAFFLE_RED/GREEN/BLUE_SIZE
minimums, which should be preferred?
I can fix my Windows Piglit issue by changing Piglit's
choose_config_attribs() function to specify WAFFLE_RED/GREEN/BLUE_SIZE=8
instead of 1, but that's not a final solution.
1. The Waffle docs should be clarified to specify whether the largest or
smallest color format should be used when several meet the WAFFLE_*_SIZE
minimums. My suggesting is "smallest", like WGL.
2. The Waffle code for either GLX or WGL should be modified to follow
that part of the spec. Following my suggestion, the GLX format chooser
code would need to be modified.
3. The Piglit code to specify the Waffle pixel format should be updated,
probably replacing '1' with '8' as above. And maybe falling back to the
former if the later fails (though I doubt anyone runs piglit on less
than a 24-bit display nowadays).
4. If Waffle wants to get fancy, we could consider new attributes like
WAFFLE_MIN_RED_SIZE, WAFFLE_MAX_RED_SIZE and WAFFLE_EXACT_RED_SIZE to
provide more control over format selection. But I think my suggestion
in (1) would avoid this for now.
More information about the Piglit