[Mesa-dev] [PATCH 3/3] glx/dri3: Request non-vsynced Present for swapinterval zero.

Mario Kleiner mario.kleiner.de at gmail.com
Sun Nov 30 03:47:16 PST 2014

On 11/25/2014 07:52 AM, Axel Davy wrote:
> Hi,

Sorry for the late reply, seems my e-mail filters hate me - i was 
already worried about the lack of replies.

> This patch removes the tripple buffering behaviour that the GLX 
> implementation
> has with DRI3. I understand your concern for Medical softwares,
> but perhaps this would be better handled with an user option.
> Axel Davy

I don't think it does that?

For swapinterval > 0 all the triple-buffering etc. is left active as 
usual, and swaps are supposed to be vsynced and tear-free. swapinterval 
is 1 by default, so this is the case by default.

For a client or user selected swapinterval = 0, the code in Mesa 
schedules glXSwapBuffers calls to occur immediately, and the Present 
implementation in the server schedules them in a way so they are 
supposed to occur immediately/asap - assuming no vsync, otherwise the 
logic there wouldn't make much sense.

Due to what i'm pretty sure is a bug (see my other 2 patches on top of 
the xserver dri3/present implementation) the PresentOptionAsync isn't 
handled correctly by the server for pagelfips as it should be, and as 
result vsync is always on on intel-ddx, and always off on nouveau-ddx 
(or any future driver which exposes PresentCapabilityAsync as nouveau 
does), which causes massive tearing on nouveau all the time under 

On any os/graphics-stack i'm familiar with (Windows and OSX all versions 
and drivers, Linux proprietary drivers, DRI2 with intel-ddx and 
nouveau-ddx) a swapinterval zero meant to swap immediately without 
vsync, so this just restores what probably any OpenGL client expects to 
happen. The MESA_swap_control spec even states that "If <interval> is 
set to a value of 0, buffer swaps are not synchronized to a video frame."

For medical or neuro-science applications like mine, or multi-display 
stereo/VR applications it is crucial to have this for users being able 
to easily diagnose multi-display synchronization issues without the need 
to learn how to use git and compilers and how graphics stacks work. For 
gamers and gaming benchmarks it's the "ego-shooter mode" and "squeeze 
out max fps" they like so much.

Btw., digging deeper into the ddx'es i realized that my posted patch for 
the x-server bug is both incomplete and too complex. I've written a new 
patch which is only a simple one-liner but solves more problems than the 
old one. I'll send it out after giving it some testing.


> On 25/11/2014 04:00, Mario Kleiner wrote :
>> Restores proper immediate tearing swap behaviour for
>> OpenGL bufferswap under DRI3/Present.
>> Cc: "10.3 10.4" <mesa-stable at lists.freedesktop.org>
>> Signed-off-by: Mario Kleiner <mario.kleiner.de at gmail.com>
>> ---
>>   src/glx/dri3_glx.c | 6 +++++-
>>   1 file changed, 5 insertions(+), 1 deletion(-)
>> diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
>> index 5796491..c53be1b 100644
>> --- a/src/glx/dri3_glx.c
>> +++ b/src/glx/dri3_glx.c
>> @@ -1518,6 +1518,7 @@ dri3_swap_buffers(__GLXDRIdrawable *pdraw, 
>> int64_t target_msc, int64_t divisor,
>>      xcb_connection_t *c = XGetXCBConnection(dpy);
>>      struct dri3_buffer *back;
>>      int64_t ret = 0;
>> +   uint32_t options = XCB_PRESENT_OPTION_NONE;
>>        unsigned flags = __DRI2_FLUSH_DRAWABLE;
>>      if (flush)
>> @@ -1557,6 +1558,9 @@ dri3_swap_buffers(__GLXDRIdrawable *pdraw, 
>> int64_t target_msc, int64_t divisor,
>>         if (target_msc == 0)
>>            target_msc = priv->msc + priv->swap_interval * 
>> (priv->send_sbc - priv->recv_sbc);
>>   +      if (priv->swap_interval == 0)
>> +          options |= XCB_PRESENT_OPTION_ASYNC;
>> +
>>         back->busy = 1;
>>         back->last_swap = priv->send_sbc;
>>         xcb_present_pixmap(c,
>> @@ -1570,7 +1574,7 @@ dri3_swap_buffers(__GLXDRIdrawable *pdraw, 
>> int64_t target_msc, int64_t divisor,
>>                            None, /* target_crtc */
>>                            None,
>>                            back->sync_fence,
>> -                         XCB_PRESENT_OPTION_NONE,
>> +                         options,
>>                            target_msc,
>>                            divisor,
>>                            remainder, 0, NULL);

More information about the mesa-dev mailing list