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

Must be enabled with

        Option  "DRI3"

in xorg.conf.

(Cherry picked from radeon commits 64e1e4dbdd3caee6f5d8f6b6c094b4533fa94953,
694e04720b886060fe3eefdce59741f218c8269f,
f940fd741b15f03393037c5bb904cd74f012de9d,
fcd37f65f485291084c174666bd605e215bf1398,
4b0997e56dec0053cb2cb793e0f4ae35055ff7e6,
f68d9b5ba0c91a725b5eec9386c61bea8824c299 and
98fb4199e63fedd4607cddee64bf602d6398df81)

Signed-off-by: Michel Dänzer <[email protected]>
---
 configure.ac      |   4 ++
 man/amdgpu.man    |   4 ++
 src/Makefile.am   |   4 +-
 src/amdgpu_dri3.c | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/amdgpu_drv.h  |   6 +-
 src/amdgpu_kms.c  |  20 +++++-
 6 files changed, 229 insertions(+), 5 deletions(-)
 create mode 100644 src/amdgpu_dri3.c

diff --git a/configure.ac b/configure.ac
index b91ce17..d9d97ef 100644
--- a/configure.ac
+++ b/configure.ac
@@ -168,6 +168,10 @@ AC_CHECK_HEADERS([present.h], [], [],
                 #include <X11/X.h>
                 #include "xorg-server.h"])
 
+AC_CHECK_HEADERS([dri3.h], [], [],
+                [#include <X11/Xmd.h>
+                #include <xorg-server.h>])
+
 CPPFLAGS="$SAVE_CPPFLAGS"
 
 PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.8.0])
diff --git a/man/amdgpu.man b/man/amdgpu.man
index 64633b3..bc7bf30 100644
--- a/man/amdgpu.man
+++ b/man/amdgpu.man
@@ -70,6 +70,10 @@ For example:
 Option \*qZaphodHeads\*q \*qLVDS,VGA-0\*q
 will assign xrandr outputs LVDS and VGA-0 to this instance of the driver.
 .TP
+.BI "Option \*qDRI3\*q \*q" boolean \*q
+Enable the DRI3 extension. The default is
+.B off.
+.TP
 .BI "Option \*qEnablePageFlip\*q \*q" boolean \*q
 Enable DRI2 page flipping.  The default is
 .B on.
diff --git a/src/Makefile.am b/src/Makefile.am
index fc8b77a..b953d4c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -28,8 +28,8 @@
 
 amdgpu_drv_la_LIBADD = $(PCIACCESS_LIBS) $(LIBDRM_AMDGPU_LIBS) $(GBM_LIBS)
 
-AMDGPU_KMS_SRCS=amdgpu_bo_helper.c amdgpu_dri2.c amdgpu_drm_queue.c 
amdgpu_kms.c \
-       amdgpu_present.c amdgpu_sync.c drmmode_display.c
+AMDGPU_KMS_SRCS=amdgpu_bo_helper.c amdgpu_dri2.c amdgpu_dri3.c 
amdgpu_drm_queue.c \
+       amdgpu_kms.c amdgpu_present.c amdgpu_sync.c drmmode_display.c
 
 AM_CFLAGS = \
             @GBM_CFLAGS@ \
diff --git a/src/amdgpu_dri3.c b/src/amdgpu_dri3.c
new file mode 100644
index 0000000..ce0f8e7
--- /dev/null
+++ b/src/amdgpu_dri3.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright © 2013-2014 Intel Corporation
+ * Copyright © 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "amdgpu_drv.h"
+
+#ifdef HAVE_DRI3_H
+
+#include "amdgpu_glamor.h"
+#include "amdgpu_pixmap.h"
+#include "dri3.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+
+static int
+amdgpu_dri3_open(ScreenPtr screen, RRProviderPtr provider, int *out)
+{
+       ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+       AMDGPUInfoPtr info = AMDGPUPTR(scrn);
+       drm_magic_t magic;
+       int fd;
+
+       fd = open(info->dri2.device_name, O_RDWR | O_CLOEXEC);
+       if (fd < 0)
+               return BadAlloc;
+
+       /* Before FD passing in the X protocol with DRI3 (and increased
+        * security of rendering with per-process address spaces on the
+        * GPU), the kernel had to come up with a way to have the server
+        * decide which clients got to access the GPU, which was done by
+        * each client getting a unique (magic) number from the kernel,
+        * passing it to the server, and the server then telling the
+        * kernel which clients were authenticated for using the device.
+        *
+        * Now that we have FD passing, the server can just set up the
+        * authentication on its own and hand the prepared FD off to the
+        * client.
+        */
+       if (drmGetMagic(fd, &magic) < 0) {
+               if (errno == EACCES) {
+                       /* Assume that we're on a render node, and the fd is
+                        * already as authenticated as it should be.
+                        */
+                       *out = fd;
+                       return Success;
+               } else {
+                       close(fd);
+                       return BadMatch;
+               }
+       }
+
+       if (drmAuthMagic(info->dri2.drm_fd, magic) < 0) {
+               close(fd);
+               return BadMatch;
+       }
+
+       *out = fd;
+       return Success;
+}
+
+static PixmapPtr amdgpu_dri3_pixmap_from_fd(ScreenPtr screen,
+                                           int fd,
+                                           CARD16 width,
+                                           CARD16 height,
+                                           CARD16 stride,
+                                           CARD8 depth,
+                                           CARD8 bpp)
+{
+       PixmapPtr pixmap;
+
+       if (depth < 8)
+               return NULL;
+
+       switch (bpp) {
+       case 8:
+       case 16:
+       case 32:
+               break;
+       default:
+               return NULL;
+       }
+
+       pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0);
+       if (!pixmap)
+               return NULL;
+
+       if (!screen->ModifyPixmapHeader(pixmap, width, height, 0, bpp, stride,
+                                       NULL))
+               goto free_pixmap;
+
+       if (screen->SetSharedPixmapBacking(pixmap, (void*)(intptr_t)fd))
+               return pixmap;
+
+free_pixmap:
+       fbDestroyPixmap(pixmap);
+       return NULL;
+}
+
+static int amdgpu_dri3_fd_from_pixmap(ScreenPtr screen,
+                                     PixmapPtr pixmap,
+                                     CARD16 *stride,
+                                     CARD32 *size)
+{
+       ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+       AMDGPUInfoPtr info = AMDGPUPTR(scrn);
+       struct amdgpu_buffer *bo;
+       struct amdgpu_bo_info bo_info;
+       uint32_t fd;
+
+#ifdef USE_GLAMOR
+       if (info->use_glamor)
+               return glamor_fd_from_pixmap(screen, pixmap, stride, size);
+#endif
+
+       bo = amdgpu_get_pixmap_bo(pixmap);
+       if (!bo)
+               return -1;
+
+       if (pixmap->devKind > UINT16_MAX)
+               return -1;
+
+       if (amdgpu_bo_query_info(bo->bo.amdgpu, &bo_info) != 0)
+               return -1;
+
+       if (amdgpu_bo_export(bo->bo.amdgpu, amdgpu_bo_handle_type_dma_buf_fd,
+                            &fd) != 0)
+               return -1;
+
+       *stride = pixmap->devKind;
+       *size = bo_info.alloc_size;
+       return fd;
+}
+
+static dri3_screen_info_rec amdgpu_dri3_screen_info = {
+       .version = 0,
+
+       .open = amdgpu_dri3_open,
+       .pixmap_from_fd = amdgpu_dri3_pixmap_from_fd,
+       .fd_from_pixmap = amdgpu_dri3_fd_from_pixmap
+};
+
+Bool
+amdgpu_dri3_screen_init(ScreenPtr screen)
+{
+       ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+
+       if (!dri3_screen_init(screen, &amdgpu_dri3_screen_info)) {
+               xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+                          "dri3_screen_init failed\n");
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+#else /* !HAVE_DRI3_H */
+
+Bool
+amdgpu_dri3_screen_init(ScreenPtr screen)
+{
+       xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO,
+                  "Can't initialize DRI3 because dri3.h not available at "
+                  "build time\n");
+
+       return FALSE;
+}
+
+#endif
diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h
index c6c968f..5ffbc6a 100644
--- a/src/amdgpu_drv.h
+++ b/src/amdgpu_drv.h
@@ -140,7 +140,8 @@ typedef enum {
        OPTION_SUBPIXEL_ORDER,
 #endif
        OPTION_ZAPHOD_HEADS,
-       OPTION_ACCEL_METHOD
+       OPTION_ACCEL_METHOD,
+       OPTION_DRI3,
 } AMDGPUOpts;
 
 #define AMDGPU_VSYNC_TIMEOUT   20000   /* Maximum wait for VSYNC (in usecs) */
@@ -233,6 +234,9 @@ typedef struct {
 } AMDGPUInfoRec, *AMDGPUInfoPtr;
 
 
+/* amdgpu_dri3.c */
+Bool amdgpu_dri3_screen_init(ScreenPtr screen);
+
 /* amdgpu_present.c */
 Bool amdgpu_present_screen_init(ScreenPtr screen);
 
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 05e9adf..1e256af 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -66,6 +66,7 @@ const OptionInfoRec AMDGPUOptions_KMS[] = {
        {OPTION_SUBPIXEL_ORDER, "SubPixelOrder", OPTV_ANYSTR, {0}, FALSE},
        {OPTION_ZAPHOD_HEADS, "ZaphodHeads", OPTV_STRING, {0}, FALSE},
        {OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE},
+       { OPTION_DRI3, "DRI3", OPTV_BOOLEAN, {0}, FALSE },
        {-1, NULL, OPTV_NONE, {0}, FALSE}
 };
 
@@ -738,6 +739,8 @@ Bool AMDGPUScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
        ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
        AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
        int subPixelOrder = SubPixelUnknown;
+       MessageType from;
+       Bool value;
        char *s;
        void *front_ptr;
        int ret;
@@ -827,8 +830,21 @@ Bool AMDGPUScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
        }
 #endif
 
-       if (amdgpu_sync_init(pScreen))
-               amdgpu_present_screen_init(pScreen);
+       value = FALSE;
+       if (xf86GetOptValBool(info->Options, OPTION_DRI3, &value))
+               from = X_CONFIG;
+       else
+               from = X_DEFAULT;
+
+       if (value) {
+               value = amdgpu_sync_init(pScreen) &&
+                       amdgpu_present_screen_init(pScreen) &&
+                       amdgpu_dri3_screen_init(pScreen);
+
+               if (!value)
+                       from = X_WARNING;
+       }
+       xf86DrvMsg(pScrn->scrnIndex, from, "DRI3 %sabled\n", value ? "en" : 
"dis");
 
        pScrn->vtSema = TRUE;
        xf86SetBackingStore(pScreen);
-- 
2.1.4

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

Reply via email to