Mesa (main): loader/dri3: support glx pbuffer swap

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Dec 7 05:14:56 UTC 2021


Module: Mesa
Branch: main
Commit: df6ff88fd01c84974e5b864b6cd32bd9b524a48a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=df6ff88fd01c84974e5b864b6cd32bd9b524a48a

Author: Qiang Yu <yuq825 at gmail.com>
Date:   Wed Nov 10 18:59:34 2021 +0800

loader/dri3: support glx pbuffer swap

Double buffered pbuffer need to update the front buffer,
otherwise we always get wrong value when glReadPixels().

Reviewed-by: Adam Jackson <ajax at redhat.com>
Signed-off-by: Qiang Yu <yuq825 at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13750>

---

 src/loader/loader_dri3_helper.c | 71 ++++++++++++++++++++++++++++-------------
 1 file changed, 49 insertions(+), 22 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 18cf58a678b..8e775a4735f 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -996,7 +996,6 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
 {
    struct loader_dri3_buffer *back;
    int64_t ret = 0;
-   uint32_t options = XCB_PRESENT_OPTION_NONE;
 
    /* GLX spec:
     *   void glXSwapBuffers(Display *dpy, GLXDrawable draw);
@@ -1114,8 +1113,9 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
        * behaviour by not using XCB_PRESENT_OPTION_ASYNC, but this should not be
        * the default.
        */
+      uint32_t options = XCB_PRESENT_OPTION_NONE;
       if (draw->swap_interval <= 0)
-          options |= XCB_PRESENT_OPTION_ASYNC;
+         options |= XCB_PRESENT_OPTION_ASYNC;
 
       /* If we need to populate the new back, but need to reuse the back
        * buffer slot due to lack of local blit capabilities, make sure
@@ -1166,32 +1166,59 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
                          target_msc,
                          divisor,
                          remainder, 0, NULL);
-      ret = (int64_t) draw->send_sbc;
-
-      /* Schedule a server-side back-preserving blit if necessary.
-       * This happens iff all conditions below are satisfied:
-       * a) We have a fake front,
-       * b) We need to preserve the back buffer,
-       * c) We don't have local blit capabilities.
+   } else {
+      /* This can only be reached by double buffered GLXPbuffer. */
+      assert(draw->type == LOADER_DRI3_DRAWABLE_PBUFFER);
+      /* GLX does not have damage regions. */
+      assert(n_rects == 0);
+
+      /* For wait and buffer age usage. */
+      draw->send_sbc++;
+      draw->recv_sbc = back->last_swap = draw->send_sbc;
+
+      /* Pixmap is imported as front buffer image when same GPU case, so just
+       * locally blit back buffer image to it is enough. Otherwise front buffer
+       * is a fake one which needs to be synced with pixmap by xserver remotely.
        */
-      if (!loader_dri3_have_image_blit(draw) && draw->cur_blit_source != -1 &&
-          draw->cur_blit_source != LOADER_DRI3_BACK_ID(draw->cur_back)) {
-         struct loader_dri3_buffer *new_back = dri3_back_buffer(draw);
-         struct loader_dri3_buffer *src = draw->buffers[draw->cur_blit_source];
-
-         dri3_fence_reset(draw->conn, new_back);
-         dri3_copy_area(draw->conn, src->pixmap,
-                        new_back->pixmap,
+      if (draw->is_different_gpu ||
+          !loader_dri3_blit_image(draw,
+                                  dri3_front_buffer(draw)->image,
+                                  back->image,
+                                  0, 0, draw->width, draw->height,
+                                  0, 0, __BLIT_FLAG_FLUSH)) {
+         dri3_copy_area(draw->conn, back->pixmap,
+                        draw->drawable,
                         dri3_drawable_gc(draw),
                         0, 0, 0, 0, draw->width, draw->height);
-         dri3_fence_trigger(draw->conn, new_back);
-         new_back->last_swap = src->last_swap;
       }
+   }
+
+   ret = (int64_t) draw->send_sbc;
 
-      xcb_flush(draw->conn);
-      if (draw->stamp)
-         ++(*draw->stamp);
+   /* Schedule a server-side back-preserving blit if necessary.
+    * This happens iff all conditions below are satisfied:
+    * a) We have a fake front,
+    * b) We need to preserve the back buffer,
+    * c) We don't have local blit capabilities.
+    */
+   if (!loader_dri3_have_image_blit(draw) && draw->cur_blit_source != -1 &&
+       draw->cur_blit_source != LOADER_DRI3_BACK_ID(draw->cur_back)) {
+      struct loader_dri3_buffer *new_back = dri3_back_buffer(draw);
+      struct loader_dri3_buffer *src = draw->buffers[draw->cur_blit_source];
+
+      dri3_fence_reset(draw->conn, new_back);
+      dri3_copy_area(draw->conn, src->pixmap,
+                     new_back->pixmap,
+                     dri3_drawable_gc(draw),
+                     0, 0, 0, 0, draw->width, draw->height);
+      dri3_fence_trigger(draw->conn, new_back);
+      new_back->last_swap = src->last_swap;
    }
+
+   xcb_flush(draw->conn);
+   if (draw->stamp)
+      ++(*draw->stamp);
+
    mtx_unlock(&draw->mtx);
 
    draw->ext->flush->invalidate(draw->dri_drawable);



More information about the mesa-commit mailing list