[waffle] long-standing wgl pixel format issue
Emil Velikov
emil.l.velikov at gmail.com
Mon Jun 20 23:48:21 UTC 2016
On 20 June 2016 at 15:46, Brian Paul <brianp at vmware.com> wrote:
> 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.
>
Can I put a minor correction - s/that exceeds/that meets or exceeds/.
Should that rule hold true, even if the user have explicitly set some
sizes to zero ... for example if they want an RGB8 (A=0) format ?
> 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,
I hope for cases like this user will set A=2 ;-)
> 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?
>
Seems like I was a bit off - Xwin does not do anything fancy, just
like most of SDL. The latter uses an algorithm [1] only for EGL, while
we'll need to use one for GLX/EGL/WGL/NaCl.
Thanks
Emil
[1] https://github.com/spurious/SDL-mirror/blob/2645c41d08dc70b0d624ec1f30943f8a5a914469/src/video/SDL_egl.c#L387
More information about the waffle
mailing list