egl/x11_dri3: implement EGL_KHR_swap_buffers_with_damage Passes all of `dEQP-EGL.functional.swap_buffers_with_damage.*`: Passed: 36/54 (66.7%) Failed: 0/54 (0.0%) Not supported: 18/54 (33.3%) Warnings: 0/54 (0.0%) Waived: 0/54 (0.0%) The "not supported" ones are the `preserve_buffer_*` tests, which is not supported on X11/DRI3. Cc: 20.2 <mesa-stable> Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3030 Signed-off-by: Eric Engestrom <eric@engestrom.ch> Reviewed-by: Michel Dänzer <mdaenzer@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6132>
Revert "loader/dri3: Check for window destruction in dri3_wait_for_event_locked" This reverts commit d7d7687829875e401690219d4a72458fb2bbe4de. It caused freezes with e.g. kwin_x11 due to hitting the 1s timeout. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3214 Reopens: https://gitlab.freedesktop.org/mesa/mesa/-/issues/116 Acked-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5722>
loader/dri3: Check for window destruction in dri3_wait_for_event_locked If the underlying X11 window gets destroyed, the event we're waiting for may never be delivered, in which case xcb_wait_for_special_event would hang indefinitely. Solution: 1. Use xcb_poll_for_special_event to check if an event has arrived yet. 2. If not, Wait up to ~1s for XCB's file descriptor to become readable; if it does, go back to step 1. 3. If the file descriptor didn't become readable, make a round-trip to the X server to check that the window still exists. Go back to step 1 if it does, otherwise bail. Also add an early bail-out when it's known that the window was destroyed. Cc: mesa-stable Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/116 Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5368>
loader/dri3: Add dri3_wait_for_event_locked full_sequence out parameter Preparation for the next commit, no functional change intended. Cc: mesa-stable Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5368>
loader/dri3: Enable adaptive_sync via _VARIABLE_REFRESH property The DDX driver can be notified of adaptive sync suitability by flagging the application's window with the _VARIABLE_REFRESH property. This property is set on the first swap the application performs when adaptive_sync is set to true in the drirc. It's performed here instead of when the loader is initialized for two reasons: (1) The window's drawable can be missing during loader init. This can be observed during the Unigine Superposition benchmark. (2) Adaptive sync will only be enabled closer to when the application actually begins rendering. If adaptive_sync is false then the _VARIABLE_REFRESH property is deleted on loader init. The property is only managed on the glx DRI3 backend for now. This should cover most common applications and games on modern hardware. Vulkan support can be implemented in a similar manner but would likely require splitting the function out into a common helper function. Reviewed-by: Michel Dänzer <michel.daenzer@amd.com> Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
loader_dri3: Handle mismatched depth 30 formats for Prime renderoffload. Detect if the display (X-Server) gpu and Prime renderoffload gpu prefer different channel ordering for color depth 30 formats ([X/A]BGR2101010 vs. [X/A]RGB2101010) and perform format conversion during the blitImage() detiling op from tiled backbuffer -> linear buffer. For this we need to find the visual (= red channel mask) for the X-Drawable used to display on the server gpu. We use the same proven logic for finding that visual as in commit "egl/x11: Handle both depth 30 formats for eglCreateImage()". This is mostly to allow "NVidia Optimus" at depth 30, as Intel/AMD gpu's prefer xRGB2101010 ordering, whereas NVidia gpu's prefer xBGR2101010 ordering, so we can offload to nouveau without getting funky colors. Tested on Intel single gpu, NVidia single gpu, Intel + NVidia prime offload with DRI3/Present. Note: An unintended but pleasant surprise of this patch is that it also seems to make the modesetting-ddx of server 1.20.0 work at depth 30 on nouveau, at least with unredirected "classic" X rendering, and with redirected desktop compositing under XRender accel, and with OpenGL compositing under GLX. Only X11 compositing via OpenGL + EGL still gives funky colors. modesetting-ddx + glamor are not yet ready to deal with nouveau's ABGR2101010 format, and treat it as ARGB2101010, also exposing X-visuals with ARGB2101010 style channel masks. Seems somehow this triggers the logic in this patch on modesetting-ddx + depth 30 + DRI3 buffer sharing and does the "wrong" channel swizzling that then cancels out the "wrong" swizzling of glamor and we end up with the proper pixel formatting in the scanout buffer :). This so far tested on a NVA5 Tesla card under KDE5 Plasma as shipping with Ubuntu 16.04.4 LTS. Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> Cc: Ilia Mirkin <imirkin@alum.mit.edu> Reviewed-by: Eric Engestrom <eric.engestrom@intel.com>
dri3: For 1.2, use root window instead of pixmap drawable get_supported_modifiers() and pixmap_from_buffers() requests both expect a window as drawable, passing a pixmap will fail as the Xserver will fail to match the given drawable to a window. That leads to dri3_alloc_render_buffer() to return NULL and breaks rendering when using GLX_DOUBLEBUFFER on pixmaps. Query the root window of the pixmap on first init, and use the root window instead of the pixmap drawable for get_supported_modifiers() and pixmap_from_buffers(). Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107117 Fixes: 069fdd5 ("egl/x11: Support DRI3 v1.1") Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Reviewed-by: Eric Anholt <eric@anholt.net>
dri3: allow building against older xcb (v3) I'm not sure everyone wants to be updating their dri3 in a forced march setting, this allows a nicer approach, esp when you want to build on distro that aren't brand new. I'm sure there are plenty of ways this patch could be cleaner, and I've also not built it against an updated dri3. For meson I've just left it alone, since if you are using meson you probably don't mind xcb updates, and if you are using meson you can fix this better than me. v3: just don't put a version in for dri3/present without modifiers, should allow building with 1.11 as well (feel free to supply meson followups) Signed-off-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Marek Olšák <marek.olsak@amd.com>
egl/x11: Re-allocate buffers if format is suboptimal If PresentCompleteNotify event says the pixmap was presented with mode PresentCompleteModeSuboptimalCopy, it means the pixmap could possibly have been flipped instead if allocated with a different format/modifier. Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
egl/x11: Support DRI3 v1.1 Add support for DRI3 v1.1, which allows pixmaps to be backed by multi-planar buffers, or those with format modifiers. This is both for allocating render buffers, as well as EGLImage imports from a native pixmap (EGL_NATIVE_PIXMAP_KHR). Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com> Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com> Reviewed-by: Emil Velikov <emil.velikov@collabora.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
x11/dri3: Store raw present completion mode The DRI3 drawable info struct currently stores a boolean for whether the last completed operation was a flip or not. As we need to track the full completion mode for handling suboptimal returns, change the 'flipping' field to the raw present completion mode from the server. Signed-off-by: Daniel Stone <daniels@collabora.com> Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com>
loader_dri3/glx/egl: Reinstate the loader_dri3_vtable get_dri_screen callback Removing this callback caused rendering corruption in some multi-screen cases, so it is reinstated but without the drawable argument which was never used by implementations and was confusing since the drawable could have been created with another screen. Cc: "17.3 18.0" mesa-stable@lists.freedesktop.org Fixes: 5198e48a0d (loader_dri3/glx/egl: Remove the loader_dri3_vtable get_dri_screen callback) Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105013 Reported-by: Daniel van Vugt <daniel.van.vugt@canonical.com> Tested-by: Timo Aaltonen <tjaalton@ubuntu.com> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Brian Paul <brianp@vmware.com>
loader/dri3: Try to make sure we only process our own NotifyMSC events We were using a sequence counter value to wait for a specific NotifyMSC event. However, we can receive events from other clients as well, which may already be using higher sequence numbers than us. In that case, we could stop processing after an event from another client, which could have been received significantly earlier. This would have multiple undesirable effects: * The computed MSC and UST values would be lower than they should be * We could leave a growing number of NotifyMSC events from ourselves and other clients in XCB's special event queue I ran into this with Firefox and Thunderbird, whose VSync threads both seem to use the same window. The result was sluggish screen updates and growing memory consumption in one of them. Fix this by checking the XCB sequence number and MSC value of NotifyMSC events, instead of using our own sequence number. v2: * Use the Present event ID for the sequence parameter of the PresentNotifyMSC request, as another safeguard against processing events from other clients * Rebase on drawable mutex changes Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com> # v1
loader/dri3: Improve dri3 thread-safety It turned out that with recent changes that call into dri3 from glFinish(), it appears like different thread end up waiting for X events simultaneously, causing deadlocks since they steal events from eachoter and update the dri3 counters behind eachothers backs. This patch intends to improve on that. It allows at most one thread at a time to wait on events for a single drawable. If another thread intends to do the same, it's put to sleep until the first thread finishes waiting, and then it rechecks counters and optionally retries the waiting. Threads that poll for X events never pulls X events off the event queue if there are other threads waiting for events on that drawable. Counters in the dri3 drawable structure are protected by a mutex. Finally, the mutex we introduce is never held while waiting for the X server to avoid unnecessary stalls. This does not make dri3 drawables completely thread-safe but at least it's a first step. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102358 Fixes: d5ba75f8881 "st/dri2 Plumb the flush_swapbuffer functionality through to dri3" Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Acked-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
loader_dri3: Make sure we have an updated back v3 With GLX_SWAP_COPY_OML and GLX_SWAP_EXCHANGE_OML it may happen in situations when glXSwapBuffers() is immediately followed by for example another glXSwapBuffers() or glXCopyBuffers() or back buffer age querying, that we haven't yet allocated and initialized a new back buffer because there was no GL rendering in between. Make sure that we have a back buffer in those situations. v2: Eliminate the drawable have_back_format member. v3: Make sure we re-initialize the back even if it exists. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
loader_dri3: Remove buffer_type from buffer metadata It's not used anywhere and now that we're about to exchange back- and fake fronts it doesn't serve a purpose. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
loader_dri3: Support GLX_SWAP_COPY_OML Support the GLX_SWAP_COPY_OML method. When this method is requested, we use the same swapbuffer code path as EGL_BUFFER_PRESERVED. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
loader_dri3: Honor the request to preserve back buffer content EGL uses the force_copy parameter to loader_dri3_swap_buffers_msc() to indicate that it wants to preserve back buffer contents across a buffer swap. While the loader then turns off server-side page-flipping there's nothing to guarantee that a new backbuffer isn't chosen when EGL starts to render again, and that buffer's content is of course undefined. So rework the functionality: If the client supports local blits, allow server-side page flipping and when a new back is grabbed, if needed, blit the old back's content to the new back. If the client doesn't support local blits, disallow server-side page-flipping to avoid a client deadlock and then, when grabbing a new back buffer, sleep until the old back is idle, which may take a substantial time depending on swap interval. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
loader_dri3/glx/egl: Optionally use a blit context for blitting operations The code was relying on us always having a current context for client local image blit operations. Otherwise the blit would be skipped. However, glxSwapBuffers, for example, doesn't require a current context and that was a common problem in the dri1 era. It seems the problem has resurfaced with dri3. If we don't have a current context when we want to blit, try creating a private dri context and maintain a context cache of a single context. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
loader_dri3/glx/egl: Remove the loader_dri3_vtable get_dri_screen callback It's not very usable since in the rare, but definitely existing case that we don't have a current context, it will return NULL. Presumably it will always be safe to use the dri screen the drawable was created with for operations on that drawable. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>