[waffle] long-standing wgl pixel format issue
Brian Paul
brianp at vmware.com
Mon Jun 20 14:46:33 UTC 2016
On 06/17/2016 07:59 PM, Emil Velikov wrote:
> On 17 June 2016 at 16:53, Brian Paul <brianp at vmware.com> wrote:
>>
>> 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 piglit-run.py
>>
>> 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 minimum
>> size
>> specification or GLX_DONT_CARE.
>> The largest available total RGBA color buffer size (sum of GLX_RED_SIZE,
>> GLX_GREEN_SIZE, GLX_BLUE_SIZE, and GLX_ALPHA_SIZE)
>> of at least the minimum size specified for each color component is
>> preferred.
>> """
>>
>> 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 be
>> chosen.
>>
>> 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
>> specified value.
>>
>> 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.
>>
> Thanks for this Brian and apologies I did not spot these differences
> as I was writing the WGL backend.
>
> Here's a bit more comprehensive list, listing all the waffle backends
> and attributes.
>
> GLX/EGL:
> Largest - red, green, blue, alpha plus their accum counterparts + depth
> Smallest - buffer, stencil
>
> If requested size is zero - "largest" become "smallest" (but it's not
> said it will be zero), "smallest" become "zero".
>
> CGL
> One that "most closely matches the specified size is preferred"
>
> WGL/NaCL
> "At least", meaning that there's not definition if it's the "smallest"
> or "largest". Furthermore there's not mention that it will give you
> the smallest if you specify 0 :-\
>
>
>> The Waffle docs for waffle_config_choose() say:
>>
>> """
>> WAFFLE_RED_SIZE
>> WAFFLE_GREEN_SIZE
>> WAFFLE_BLUE_SIZE
>> WAFFLE_ALPHA_SIZE
>> WAFFLE_DEPTH_SIZE
>> WAFFLE_STENCIL_SIZE
>>
>> 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.
>>
>>
>> I propose:
>>
>> 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.
>>
>> Thoughts?
>>
> I'm somewhat inclined that the GLX/EGL behaviour might be the better
> choice. Then again I don't might if people choose another route -
> always smallest, always largest, a combination of the two, minimum or
> "most closely matches".
> In each case there's the issue (as each spec has a massive table) of
> how exactly to determine(sort) the config(s).
I think the "choose smallest that exceeds the user-specified minimum" is
the way to go.
Suppose you have a system that has 3 color formats: RGB10_A2, RGBA8 and
R5G6B5. An app could specify WAFFLE_RED/GREEN/BLUE_SIZE=10 to get the
first one, or WAFFLE_RED/GREEN/BLUE_SIZE=8 to get the second, etc.
> Now that I think of it I do recall seeing some heuristics on the topic
> in SDL and Xwin. Perhaps it's worth checking what they do and using
> something identical/close to it ?
Sounds good. Do you want to do that?
-Brian
More information about the waffle
mailing list