From: Michel Dänzer <[email protected]>

Now we can share pixmaps with no struct amdgpu_buffer via DRI2.

Fixes VDPAU video playback freezing when using an OpenGL compositor with
DRI3 enabled and mpv VAAPI hardware decoding with OpenGL output.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89755
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93804

(ported from radeon commit f8b0f23e9f4af9f9097ee5e72d53b45173163c41)

Signed-off-by: Michel Dänzer <[email protected]>
---
 src/amdgpu_dri2.c   | 70 +++++++++++++++++++++++------------------------------
 src/amdgpu_pixmap.h |  2 +-
 2 files changed, 31 insertions(+), 41 deletions(-)

diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index d974cb8..7692566 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -45,6 +45,7 @@
 
 #include <gbm.h>
 
+#include "amdgpu_bo_helper.h"
 #include "amdgpu_version.h"
 
 #include "amdgpu_list.h"
@@ -86,6 +87,25 @@ DevPrivateKey dri2_window_private_key = 
&dri2_window_private_key_index;
        ((struct dri2_window_priv*) \
         dixLookupPrivate(&(window)->devPrivates, dri2_window_private_key))
 
+/* Get GEM flink name for a pixmap */
+static Bool
+amdgpu_get_flink_name(AMDGPUEntPtr pAMDGPUEnt, PixmapPtr pixmap, uint32_t 
*name)
+{
+       struct amdgpu_buffer *bo = amdgpu_get_pixmap_bo(pixmap);
+       struct drm_gem_flink flink;
+
+       if (bo && !(bo->flags & AMDGPU_BO_FLAGS_GBM) &&
+           amdgpu_bo_export(bo->bo.amdgpu,
+                            amdgpu_bo_handle_type_gem_flink_name,
+                            name) == 0)
+               return TRUE;
+
+       if (!amdgpu_pixmap_get_handle(pixmap, &flink.handle) ||
+           ioctl(pAMDGPUEnt->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0)
+               return FALSE;
+       *name = flink.name;
+       return TRUE;
+}
 
 static PixmapPtr get_drawable_pixmap(DrawablePtr drawable)
 {
@@ -150,11 +170,11 @@ amdgpu_dri2_create_buffer2(ScreenPtr pScreen,
                           unsigned int attachment, unsigned int format)
 {
        ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+       AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
        AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
        BufferPtr buffers;
        struct dri2_buffer_priv *privates;
        PixmapPtr pixmap;
-       struct amdgpu_buffer *bo = NULL;
        unsigned front_width;
        unsigned aligned_width = drawable->width;
        unsigned height = drawable->height;
@@ -185,10 +205,12 @@ amdgpu_dri2_create_buffer2(ScreenPtr pScreen,
        pixmap = NULL;
 
        if (attachment == DRI2BufferFrontLeft) {
+               uint32_t handle;
+
                pixmap = get_drawable_pixmap(drawable);
                if (pScreen != pixmap->drawable.pScreen)
                        pixmap = NULL;
-               else if (info->use_glamor && !amdgpu_get_pixmap_bo(pixmap)) {
+               else if (info->use_glamor && !amdgpu_pixmap_get_handle(pixmap, 
&handle)) {
                        is_glamor_pixmap = TRUE;
                        aligned_width = pixmap->drawable.width;
                        height = pixmap->drawable.height;
@@ -213,29 +235,11 @@ amdgpu_dri2_create_buffer2(ScreenPtr pScreen,
                goto error;
 
        if (pixmap) {
-               struct drm_gem_flink flink;
-               union gbm_bo_handle bo_handle;
-
                if (is_glamor_pixmap)
                        pixmap = fixup_glamor(drawable, pixmap);
-               bo = amdgpu_get_pixmap_bo(pixmap);
-               if (!bo) {
-                       goto error;
-               }
-
-               if (bo->flags & AMDGPU_BO_FLAGS_GBM) {
-                       AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
 
-                       bo_handle = gbm_bo_get_handle(bo->bo.gbm);
-                       flink.handle = bo_handle.u32;
-                       if (ioctl(pAMDGPUEnt->fd, DRM_IOCTL_GEM_FLINK, &flink) 
< 0)
-                               goto error;
-                       buffers->name = flink.name;
-               } else {
-                       amdgpu_bo_export(bo->bo.amdgpu,
-                               amdgpu_bo_handle_type_gem_flink_name,
-                               &buffers->name);
-               }
+               if (!amdgpu_get_flink_name(pAMDGPUEnt, pixmap, &buffers->name))
+                       goto error;
        }
 
        privates = calloc(1, sizeof(struct dri2_buffer_priv));
@@ -633,31 +637,17 @@ static Bool update_front(DrawablePtr draw, DRI2BufferPtr 
front)
        ScreenPtr screen = draw->pScreen;
        ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
        AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
-       PixmapPtr pixmap;
+       PixmapPtr pixmap = get_drawable_pixmap(draw);
        struct dri2_buffer_priv *priv = front->driverPrivate;
-       struct amdgpu_buffer *bo = NULL;
-       union gbm_bo_handle bo_handle;
-       struct drm_gem_flink flink;
 
-       pixmap = get_drawable_pixmap(draw);
-       pixmap->refcnt++;
+       if (!amdgpu_get_flink_name(pAMDGPUEnt, pixmap, &front->name))
+               return FALSE;
 
-       bo = amdgpu_get_pixmap_bo(pixmap);
-       if (bo->flags & AMDGPU_BO_FLAGS_GBM) {
-               bo_handle = gbm_bo_get_handle(bo->bo.gbm);
-               flink.handle = bo_handle.u32;
-               if (ioctl(pAMDGPUEnt->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0)
-                       return FALSE;
-               front->name = flink.name;
-       } else {
-               amdgpu_bo_export(bo->bo.amdgpu,
-                       amdgpu_bo_handle_type_gem_flink_name,
-                       &front->name);
-       }
        (*draw->pScreen->DestroyPixmap) (priv->pixmap);
        front->pitch = pixmap->devKind;
        front->cpp = pixmap->drawable.bitsPerPixel / 8;
        priv->pixmap = pixmap;
+       pixmap->refcnt++;
 
        return TRUE;
 }
diff --git a/src/amdgpu_pixmap.h b/src/amdgpu_pixmap.h
index 6fd5ef1..6d16628 100644
--- a/src/amdgpu_pixmap.h
+++ b/src/amdgpu_pixmap.h
@@ -34,7 +34,7 @@ struct amdgpu_pixmap {
 
        struct amdgpu_buffer *bo;
 
-       /* GEM handle for pixmaps shared via DRI3 */
+       /* GEM handle for pixmaps shared via DRI2/3 */
        Bool handle_valid;
        uint32_t handle;
 };
-- 
2.7.0

_______________________________________________
xorg-driver-ati mailing list
[email protected]
https://lists.x.org/mailman/listinfo/xorg-driver-ati

Reply via email to