xf86-video-amdgpu: Branch 'master' - 13 commits
Michel Dänzer
daenzer at kemper.freedesktop.org
Mon Jun 8 02:01:40 PDT 2015
configure.ac | 35 ++-
man/amdgpu.man | 4
src/Makefile.am | 5
src/amdgpu_bo_helper.c | 102 ++++++++--
src/amdgpu_dri2.c | 470 ++++++++++++++++++-------------------------------
src/amdgpu_dri2.h | 37 ---
src/amdgpu_dri3.c | 196 ++++++++++++++++++++
src/amdgpu_drm_queue.c | 181 ++++++++++++++++++
src/amdgpu_drm_queue.h | 56 +++++
src/amdgpu_drv.h | 18 +
src/amdgpu_glamor.c | 20 --
src/amdgpu_glamor.h | 5
src/amdgpu_kms.c | 25 ++
src/amdgpu_list.h | 39 ++++
src/amdgpu_present.c | 394 +++++++++++++++++++++++++++++++++++++++++
src/amdgpu_sync.c | 147 +++++++++++++++
src/drmmode_display.c | 120 +++++++++---
src/drmmode_display.h | 14 +
18 files changed, 1445 insertions(+), 423 deletions(-)
New commits:
commit edfff6b1a3a19953644b8052b30076f76f7dc337
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Tue Jun 2 17:04:21 2015 +0900
Add DRI3 support
Must be enabled with
Option "DRI3"
in xorg.conf.
(Cherry picked from radeon commits 64e1e4dbdd3caee6f5d8f6b6c094b4533fa94953,
694e04720b886060fe3eefdce59741f218c8269f,
f940fd741b15f03393037c5bb904cd74f012de9d,
fcd37f65f485291084c174666bd605e215bf1398,
4b0997e56dec0053cb2cb793e0f4ae35055ff7e6,
f68d9b5ba0c91a725b5eec9386c61bea8824c299 and
98fb4199e63fedd4607cddee64bf602d6398df81)
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
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);
commit d295b5b3310bc5c23d232c4be4170165a057c090
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Tue Jun 2 17:01:06 2015 +0900
amdgpu_set_shared_pixmap_backing: Add support for GBM / glamor v2
v2: Initialize reference count of imported GBM BOs to 1, fixes leaking
them.
Reviewed-by: Alex Deucher <alexander.deucher at amd.com> [v1]
diff --git a/src/amdgpu_bo_helper.c b/src/amdgpu_bo_helper.c
index 0487b46..c778796 100644
--- a/src/amdgpu_bo_helper.c
+++ b/src/amdgpu_bo_helper.c
@@ -27,8 +27,32 @@
#include <gbm.h>
#include "amdgpu_drv.h"
#include "amdgpu_bo_helper.h"
+#include "amdgpu_glamor.h"
#include "amdgpu_pixmap.h"
+static uint32_t
+amdgpu_get_gbm_format(int depth, int bitsPerPixel)
+{
+ switch (depth) {
+#ifdef GBM_FORMAT_R8
+ case 8:
+ return GBM_FORMAT_R8;
+#endif
+ case 16:
+ return GBM_FORMAT_RGB565;
+ case 32:
+ return GBM_FORMAT_ARGB8888;
+ case 24:
+ if (bitsPerPixel == 32)
+ return GBM_FORMAT_XRGB8888;
+ /* fall through */
+ default:
+ ErrorF("%s: Unsupported depth/bpp %d/%d\n", __func__,
+ depth, bitsPerPixel);
+ return ~0U;
+ }
+}
+
/* Calculate appropriate pitch for a pixmap and allocate a BO that can hold it.
*/
struct amdgpu_buffer *amdgpu_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width,
@@ -40,31 +64,10 @@ struct amdgpu_buffer *amdgpu_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width,
if (info->gbm) {
uint32_t bo_use = GBM_BO_USE_RENDERING;
- uint32_t gbm_format;
+ uint32_t gbm_format = amdgpu_get_gbm_format(depth, bitsPerPixel);
- switch (depth) {
-#ifdef GBM_FORMAT_R8
- case 8:
- gbm_format = GBM_FORMAT_R8;
- break;
-#endif
- case 16:
- gbm_format = GBM_FORMAT_RGB565;
- break;
- case 32:
- gbm_format = GBM_FORMAT_ARGB8888;
- break;
- case 24:
- if (bitsPerPixel == 32) {
- gbm_format = GBM_FORMAT_XRGB8888;
- break;
- }
- /* fall through */
- default:
- ErrorF("%s: Unsupported depth/bpp %d/%d\n", __func__,
- depth, bitsPerPixel);
+ if (gbm_format == ~0U)
return NULL;
- }
pixmap_buffer = (struct amdgpu_buffer *)calloc(1, sizeof(struct amdgpu_buffer));
if (!pixmap_buffer) {
@@ -310,11 +313,64 @@ Bool amdgpu_share_pixmap_backing(struct amdgpu_buffer *bo, void **handle_p)
Bool amdgpu_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen);
+ AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
struct amdgpu_buffer *pixmap_buffer = NULL;
int ihandle = (int)(long)fd_handle;
uint32_t size = ppix->devKind * ppix->drawable.height;
+ if (info->gbm) {
+ struct amdgpu_pixmap *priv;
+ struct gbm_import_fd_data data;
+ uint32_t bo_use = GBM_BO_USE_RENDERING;
+
+ data.format = amdgpu_get_gbm_format(ppix->drawable.depth,
+ ppix->drawable.bitsPerPixel);
+ if (data.format == ~0U)
+ return FALSE;
+
+ priv = calloc(1, sizeof(struct amdgpu_pixmap));
+ if (!priv)
+ return FALSE;
+
+ priv->bo = calloc(1, sizeof(struct amdgpu_buffer));
+ if (!priv->bo) {
+ free(priv);
+ return FALSE;
+ }
+ priv->bo->ref_count = 1;
+
+ data.fd = ihandle;
+ data.width = ppix->drawable.width;
+ data.height = ppix->drawable.height;
+ data.stride = ppix->devKind;
+
+ if (ppix->drawable.bitsPerPixel == pScrn->bitsPerPixel)
+ bo_use |= GBM_BO_USE_SCANOUT;
+
+ priv->bo->bo.gbm = gbm_bo_import(info->gbm, GBM_BO_IMPORT_FD,
+ &data, bo_use);
+ if (!priv->bo->bo.gbm) {
+ free(priv->bo);
+ free(priv);
+ return FALSE;
+ }
+
+ priv->bo->flags |= AMDGPU_BO_FLAGS_GBM;
+
+#ifdef USE_GLAMOR
+ if (info->use_glamor &&
+ !amdgpu_glamor_create_textured_pixmap(ppix, priv)) {
+ free(priv->bo);
+ free(priv);
+ return FALSE;
+ }
+#endif
+
+ amdgpu_set_pixmap_private(ppix, priv);
+ return TRUE;
+ }
+
pixmap_buffer = amdgpu_gem_bo_open_prime(pAMDGPUEnt->pDev, ihandle, size);
if (!pixmap_buffer) {
return FALSE;
commit 03ad0fa0185d215f7d4234006e04406af1ab63ca
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Fri May 29 18:53:45 2015 +0900
glamor: Add radeon_pixmap parameter to radeon_glamor_create_textured_pixmap
(cherry picked from radeon commit 051d46382656ffc3e6cac1aab3aee7efdf5b623a)
Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
Signed-off-by: Darren Powell <darren.powell at amd.com>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/amdgpu_glamor.c b/src/amdgpu_glamor.c
index 36241ce..79b3d01 100644
--- a/src/amdgpu_glamor.c
+++ b/src/amdgpu_glamor.c
@@ -126,28 +126,22 @@ Bool amdgpu_glamor_pre_init(ScrnInfoPtr scrn)
return TRUE;
}
-Bool amdgpu_glamor_create_textured_pixmap(PixmapPtr pixmap)
+Bool
+amdgpu_glamor_create_textured_pixmap(PixmapPtr pixmap, struct amdgpu_pixmap *priv)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
AMDGPUInfoPtr info = AMDGPUPTR(scrn);
- struct amdgpu_pixmap *priv;
union gbm_bo_handle bo_handle;
if ((info->use_glamor) == 0)
return TRUE;
- priv = amdgpu_get_pixmap_private(pixmap);
- if (!priv->stride) {
+ if (!priv->stride)
priv->stride = pixmap->devKind;
- }
bo_handle = gbm_bo_get_handle(priv->bo->bo.gbm);
- if (glamor_egl_create_textured_pixmap(pixmap, bo_handle.u32,
- priv->stride)) {
- return TRUE;
- } else {
- return FALSE;
- }
+ return glamor_egl_create_textured_pixmap(pixmap, bo_handle.u32,
+ priv->stride);
}
Bool amdgpu_glamor_pixmap_is_offscreen(PixmapPtr pixmap)
@@ -206,7 +200,7 @@ amdgpu_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, priv->stride,
NULL);
- if (!amdgpu_glamor_create_textured_pixmap(pixmap))
+ if (!amdgpu_glamor_create_textured_pixmap(pixmap, priv))
goto fallback_glamor;
}
@@ -280,7 +274,7 @@ amdgpu_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void *handle)
priv = amdgpu_get_pixmap_private(pixmap);
priv->stride = pixmap->devKind;
- if (!amdgpu_glamor_create_textured_pixmap(pixmap)) {
+ if (!amdgpu_glamor_create_textured_pixmap(pixmap, priv)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Failed to get PRIME drawable for glamor pixmap.\n");
return FALSE;
diff --git a/src/amdgpu_glamor.h b/src/amdgpu_glamor.h
index 01b5ce1..f2414da 100644
--- a/src/amdgpu_glamor.h
+++ b/src/amdgpu_glamor.h
@@ -48,6 +48,8 @@
#define GLAMOR_USE_PICTURE_SCREEN 0
#endif
+struct amdgpu_pixmap;
+
Bool amdgpu_glamor_pre_init(ScrnInfoPtr scrn);
Bool amdgpu_glamor_init(ScreenPtr screen);
Bool amdgpu_glamor_create_screen_resources(ScreenPtr screen);
@@ -55,7 +57,8 @@ void amdgpu_glamor_free_screen(int scrnIndex, int flags);
void amdgpu_glamor_flush(ScrnInfoPtr pScrn);
-Bool amdgpu_glamor_create_textured_pixmap(PixmapPtr pixmap);
+Bool
+amdgpu_glamor_create_textured_pixmap(PixmapPtr pixmap, struct amdgpu_pixmap *priv);
void amdgpu_glamor_exchange_buffers(PixmapPtr src, PixmapPtr dst);
Bool amdgpu_glamor_pixmap_is_offscreen(PixmapPtr pixmap);
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 01fe860..870ced6 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -108,7 +108,8 @@ static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn,
amdgpu_set_pixmap_bo(pixmap, bo);
- if (!amdgpu_glamor_create_textured_pixmap(pixmap)) {
+ if (!amdgpu_glamor_create_textured_pixmap(pixmap,
+ amdgpu_get_pixmap_private(pixmap))) {
pScreen->DestroyPixmap(pixmap);
return NULL;
}
commit fafb8c6ac925ad16073e5a60dbf60d5add11bb25
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Tue Jun 2 17:00:46 2015 +0900
Add support for the Present extension
(Cherry picked from radeon commits 3c65fb849e1ba9fb6454bcaa55b696548902f3fc,
694e04720b886060fe3eefdce59741f218c8269f,
e3be8b0a8cf484ff16597413a6172788178e80c8,
80eede245d1eda27eaba108b0761a24bfd69aff6 and
5f82a720374c9c1caebb42bfbeea1f0cf8847d28)
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/configure.ac b/configure.ac
index 2d6d4c7..b91ce17 100644
--- a/configure.ac
+++ b/configure.ac
@@ -162,6 +162,12 @@ AC_CHECK_HEADERS([misyncshm.h], [], [],
#include <xorg-server.h>
#include <screenint.h>])
+AC_CHECK_HEADERS([present.h], [], [],
+ [#include <X11/Xmd.h>
+ #include <X11/Xproto.h>
+ #include <X11/X.h>
+ #include "xorg-server.h"])
+
CPPFLAGS="$SAVE_CPPFLAGS"
PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.8.0])
diff --git a/src/Makefile.am b/src/Makefile.am
index fa3be5c..fc8b77a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,7 +29,7 @@
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_sync.c drmmode_display.c
+ amdgpu_present.c amdgpu_sync.c drmmode_display.c
AM_CFLAGS = \
@GBM_CFLAGS@ \
diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h
index ad51c86..c6c968f 100644
--- a/src/amdgpu_drv.h
+++ b/src/amdgpu_drv.h
@@ -233,6 +233,9 @@ typedef struct {
} AMDGPUInfoRec, *AMDGPUInfoPtr;
+/* amdgpu_present.c */
+Bool amdgpu_present_screen_init(ScreenPtr screen);
+
/* amdgpu_sync.c */
extern Bool amdgpu_sync_init(ScreenPtr screen);
extern void amdgpu_sync_close(ScreenPtr screen);
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 28d9305..05e9adf 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -827,7 +827,8 @@ Bool AMDGPUScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
}
#endif
- amdgpu_sync_init(pScreen);
+ if (amdgpu_sync_init(pScreen))
+ amdgpu_present_screen_init(pScreen);
pScrn->vtSema = TRUE;
xf86SetBackingStore(pScreen);
diff --git a/src/amdgpu_present.c b/src/amdgpu_present.c
new file mode 100644
index 0000000..c0a5a32
--- /dev/null
+++ b/src/amdgpu_present.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright © 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_PRESENT_H
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <sys/time.h>
+#include <time.h>
+#include <errno.h>
+
+#include "amdgpu_glamor.h"
+#include "amdgpu_pixmap.h"
+#include "amdgpu_video.h"
+
+#include "present.h"
+
+struct amdgpu_present_vblank_event {
+ uint64_t event_id;
+};
+
+static uint32_t crtc_select(int crtc_id)
+{
+ if (crtc_id > 1)
+ return crtc_id << DRM_VBLANK_HIGH_CRTC_SHIFT;
+ else if (crtc_id > 0)
+ return DRM_VBLANK_SECONDARY;
+ else
+ return 0;
+}
+
+static RRCrtcPtr
+amdgpu_present_get_crtc(WindowPtr window)
+{
+ ScreenPtr screen = window->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
+ xf86CrtcPtr crtc;
+ RRCrtcPtr randr_crtc = NULL;
+
+ crtc = amdgpu_pick_best_crtc(pScrn, FALSE,
+ window->drawable.x,
+ window->drawable.x + window->drawable.width,
+ window->drawable.y,
+ window->drawable.y + window->drawable.height);
+
+ /* Make sure the CRTC is valid and this is the real front buffer */
+ if (crtc != NULL && !crtc->rotatedData)
+ randr_crtc = crtc->randr_crtc;
+
+ return randr_crtc;
+}
+
+static int
+amdgpu_present_get_ust_msc(RRCrtcPtr crtc, CARD64 *ust, CARD64 *msc)
+{
+ return drmmode_crtc_get_ust_msc(crtc->devPrivate, ust, msc);
+}
+
+/*
+ * Flush the DRM event queue when full; this
+ * makes space for new requests
+ */
+static Bool
+amdgpu_present_flush_drm_events(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[0]->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ struct pollfd p = { .fd = drmmode->fd, .events = POLLIN };
+ int r;
+
+ do {
+ r = poll(&p, 1, 0);
+ } while (r == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (r <= 0)
+ return 0;
+
+ return drmHandleEvent(drmmode->fd, &drmmode->event_context) >= 0;
+}
+
+/*
+ * Called when the queued vblank event has occurred
+ */
+static void
+amdgpu_present_vblank_handler(ScrnInfoPtr scrn, unsigned int msc,
+ uint64_t usec, void *data)
+{
+ struct amdgpu_present_vblank_event *event = data;
+
+ present_event_notify(event->event_id, usec, msc);
+ free(event);
+}
+
+/*
+ * Called when the queued vblank is aborted
+ */
+static void
+amdgpu_present_vblank_abort(ScrnInfoPtr scrn, void *data)
+{
+ struct amdgpu_present_vblank_event *event = data;
+
+ free(event);
+}
+
+/*
+ * Queue an event to report back to the Present extension when the specified
+ * MSC has past
+ */
+static int
+amdgpu_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
+{
+ xf86CrtcPtr xf86_crtc = crtc->devPrivate;
+ ScreenPtr screen = crtc->pScreen;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ AMDGPUInfoPtr info = AMDGPUPTR(scrn);
+ int crtc_id = drmmode_get_crtc_id(xf86_crtc);
+ struct amdgpu_present_vblank_event *event;
+ struct amdgpu_drm_queue_entry *queue;
+ drmVBlank vbl;
+ int ret;
+
+ event = calloc(sizeof(struct amdgpu_present_vblank_event), 1);
+ if (!event)
+ return BadAlloc;
+ event->event_id = event_id;
+ queue = amdgpu_drm_queue_alloc(scrn, AMDGPU_DRM_QUEUE_CLIENT_DEFAULT,
+ event_id, event,
+ amdgpu_present_vblank_handler,
+ amdgpu_present_vblank_abort);
+ if (!queue) {
+ free(event);
+ return BadAlloc;
+ }
+
+ vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | crtc_select(crtc_id);
+ vbl.request.sequence = msc;
+ vbl.request.signal = (unsigned long)queue;
+ for (;;) {
+ ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
+ if (!ret)
+ break;
+ if (errno != EBUSY || !amdgpu_present_flush_drm_events(screen)) {
+ amdgpu_drm_abort_entry(queue);
+ return BadAlloc;
+ }
+ }
+
+ return Success;
+}
+
+/*
+ * Remove a pending vblank event from the DRM queue so that it is not reported
+ * to the extension
+ */
+static void
+amdgpu_present_abort_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
+{
+ amdgpu_drm_abort_id(event_id);
+}
+
+/*
+ * Flush our batch buffer when requested by the Present extension.
+ */
+static void
+amdgpu_present_flush(WindowPtr window)
+{
+ amdgpu_glamor_flush(xf86ScreenToScrn(window->drawable.pScreen));
+}
+
+/*
+ * Test to see if page flipping is possible on the target crtc
+ */
+static Bool
+amdgpu_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,
+ Bool sync_flip)
+{
+ ScreenPtr screen = window->drawable.pScreen;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ AMDGPUInfoPtr info = AMDGPUPTR(scrn);
+
+ if (!scrn->vtSema)
+ return FALSE;
+
+ if (!info->allowPageFlip)
+ return FALSE;
+
+ if (!sync_flip)
+ return FALSE;
+
+ if (crtc) {
+ xf86CrtcPtr xf86_crtc = crtc->devPrivate;
+ drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
+
+ if (!drmmode_crtc ||
+ drmmode_crtc->rotate_buffer != NULL ||
+ drmmode_crtc->dpms_mode != DPMSModeOn)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Once the flip has been completed on all CRTCs, notify the
+ * extension code telling it when that happened
+ */
+static void
+amdgpu_present_flip_event(ScrnInfoPtr scrn, uint32_t msc, uint64_t ust, void *pageflip_data)
+{
+ struct amdgpu_present_vblank_event *event = pageflip_data;
+
+ present_event_notify(event->event_id, ust, msc);
+ free(event);
+}
+
+/*
+ * The flip has been aborted, free the structure
+ */
+static void
+amdgpu_present_flip_abort(ScrnInfoPtr scrn, void *pageflip_data)
+{
+ struct amdgpu_present_vblank_event *event = pageflip_data;
+
+ free(event);
+}
+
+/*
+ * Queue a flip on 'crtc' to 'pixmap' at 'target_msc'. If 'sync_flip' is true,
+ * then wait for vblank. Otherwise, flip immediately
+ */
+static Bool
+amdgpu_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc,
+ PixmapPtr pixmap, Bool sync_flip)
+{
+ ScreenPtr screen = crtc->pScreen;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ struct amdgpu_present_vblank_event *event;
+ xf86CrtcPtr xf86_crtc = crtc->devPrivate;
+ int crtc_id = xf86_crtc ? drmmode_get_crtc_id(xf86_crtc) : -1;
+ struct amdgpu_buffer *bo;
+ Bool ret;
+
+ if (!amdgpu_present_check_flip(crtc, screen->root, pixmap, sync_flip))
+ return FALSE;
+
+ bo = amdgpu_get_pixmap_bo(pixmap);
+ if (!bo)
+ return FALSE;
+
+ event = calloc(1, sizeof(struct amdgpu_present_vblank_event));
+ if (!event)
+ return FALSE;
+
+ event->event_id = event_id;
+
+ ret = amdgpu_do_pageflip(scrn, AMDGPU_DRM_QUEUE_CLIENT_DEFAULT, bo,
+ event_id, event, crtc_id,
+ amdgpu_present_flip_event,
+ amdgpu_present_flip_abort);
+ if (!ret)
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present flip failed\n");
+
+ return ret;
+}
+
+/*
+ * Queue a flip back to the normal frame buffer
+ */
+static void
+amdgpu_present_unflip(ScreenPtr screen, uint64_t event_id)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ struct amdgpu_present_vblank_event *event;
+ PixmapPtr pixmap = screen->GetScreenPixmap(screen);
+ struct amdgpu_buffer *bo;
+ Bool ret;
+
+ if (!amdgpu_present_check_flip(NULL, screen->root, pixmap, TRUE))
+ return;
+
+ bo = amdgpu_get_pixmap_bo(pixmap);
+ if (!bo)
+ return;
+
+ event = calloc(1, sizeof(struct amdgpu_present_vblank_event));
+ if (!event)
+ return;
+
+ event->event_id = event_id;
+
+ ret = amdgpu_do_pageflip(scrn, AMDGPU_DRM_QUEUE_CLIENT_DEFAULT, bo,
+ event_id, event, -1, amdgpu_present_flip_event,
+ amdgpu_present_flip_abort);
+ if (!ret)
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present unflip failed\n");
+}
+
+static present_screen_info_rec amdgpu_present_screen_info = {
+ .version = 0,
+
+ .get_crtc = amdgpu_present_get_crtc,
+ .get_ust_msc = amdgpu_present_get_ust_msc,
+ .queue_vblank = amdgpu_present_queue_vblank,
+ .abort_vblank = amdgpu_present_abort_vblank,
+ .flush = amdgpu_present_flush,
+
+ .capabilities = PresentCapabilityNone,
+ .check_flip = amdgpu_present_check_flip,
+ .flip = amdgpu_present_flip,
+ .unflip = amdgpu_present_unflip,
+};
+
+static Bool
+amdgpu_present_has_async_flip(ScreenPtr screen)
+{
+#ifdef DRM_CAP_ASYNC_PAGE_FLIP
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ AMDGPUInfoPtr info = AMDGPUPTR(scrn);
+ int ret;
+ uint64_t value;
+
+ ret = drmGetCap(info->dri2.drm_fd, DRM_CAP_ASYNC_PAGE_FLIP, &value);
+ if (ret == 0)
+ return value == 1;
+#endif
+ return FALSE;
+}
+
+Bool
+amdgpu_present_screen_init(ScreenPtr screen)
+{
+ if (amdgpu_present_has_async_flip(screen))
+ amdgpu_present_screen_info.capabilities |= PresentCapabilityAsync;
+
+ if (!present_screen_init(screen, &amdgpu_present_screen_info)) {
+ xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_WARNING,
+ "Present extension disabled because present_screen_init failed\n");
+ return FALSE;
+ }
+
+ xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO,
+ "Present extension enabled\n");
+
+ return TRUE;
+}
+
+#else /* !HAVE_PRESENT_H */
+
+Bool
+amdgpu_present_screen_init(ScreenPtr screen)
+{
+ xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO,
+ "Present extension disabled because present.h not available at "
+ "build time\n");
+
+ return FALSE;
+}
+
+#endif
commit 5b51f0e7e396ea946ef85429a8e9be5c1d5c39c3
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Tue Jun 2 16:58:27 2015 +0900
Add support for SYNC extension fences
(Cherry picked from radeon commits 8fc9a241ab59ffbcdc178d6415332c88a54e85fe,
af1862a37570fa512a525ab47d72b30400d2e2d6,
aa7825eb29cdf6ac9d7b28ad18186807ff384687,
af6076241c0d322b295a4e898407ae2472bd8eb4 and
d64a13ebe0ecd241ee3260dbffd8f4a01e254183)
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/configure.ac b/configure.ac
index ff0979e..2d6d4c7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -156,6 +156,12 @@ AC_CHECK_DECL(GBM_BO_USE_LINEAR,
[#include <stdlib.h>
#include <gbm.h>])
+AC_CHECK_HEADERS([misyncshm.h], [], [],
+ [#include <X11/Xdefs.h>
+ #include <X11/Xfuncproto.h>
+ #include <xorg-server.h>
+ #include <screenint.h>])
+
CPPFLAGS="$SAVE_CPPFLAGS"
PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.8.0])
diff --git a/src/Makefile.am b/src/Makefile.am
index 8e91472..fa3be5c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,7 +29,7 @@
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 \
- drmmode_display.c
+ amdgpu_sync.c drmmode_display.c
AM_CFLAGS = \
@GBM_CFLAGS@ \
diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h
index 4b87e6e..ad51c86 100644
--- a/src/amdgpu_drv.h
+++ b/src/amdgpu_drv.h
@@ -88,6 +88,8 @@
#include "simple_list.h"
#include "amdpciids.h"
+struct _SyncFence;
+
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
@@ -185,6 +187,9 @@ typedef struct {
void (*BlockHandler) (BLOCKHANDLER_ARGS_DECL);
+ void (*CreateFence) (ScreenPtr pScreen, struct _SyncFence *pFence,
+ Bool initially_triggered);
+
int pix24bpp; /* Depth of pixmap for 24bpp fb */
Bool dac6bits; /* Use 6 bit DAC? */
@@ -228,6 +233,10 @@ typedef struct {
} AMDGPUInfoRec, *AMDGPUInfoPtr;
+/* amdgpu_sync.c */
+extern Bool amdgpu_sync_init(ScreenPtr screen);
+extern void amdgpu_sync_close(ScreenPtr screen);
+
/* amdgpu_video.c */
extern void AMDGPUInitVideo(ScreenPtr pScreen);
extern void AMDGPUResetVideo(ScrnInfoPtr pScrn);
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 71a4aa7..28d9305 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -703,6 +703,8 @@ static Bool AMDGPUCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL)
DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn);
+ amdgpu_sync_close(pScreen);
+
drmDropMaster(info->dri2.drm_fd);
drmmode_fini(pScrn, &info->drmmode);
@@ -825,6 +827,8 @@ Bool AMDGPUScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
}
#endif
+ amdgpu_sync_init(pScreen);
+
pScrn->vtSema = TRUE;
xf86SetBackingStore(pScreen);
diff --git a/src/amdgpu_sync.c b/src/amdgpu_sync.c
new file mode 100644
index 0000000..baade0e
--- /dev/null
+++ b/src/amdgpu_sync.c
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+#include "amdgpu_drv.h"
+
+#ifdef HAVE_MISYNCSHM_H
+
+#include "misync.h"
+#include "misyncshm.h"
+#include "misyncstr.h"
+
+#include "amdgpu_glamor.h"
+
+/*
+ * This whole file exists to wrap a sync fence trigger operation
+ * so that we can flush the batch buffer to provide serialization
+ * between the server and the shm fence client
+ */
+
+static DevPrivateKeyRec amdgpu_sync_fence_private_key;
+
+typedef struct _amdgpu_sync_fence_private {
+ SyncFenceSetTriggeredFunc set_triggered;
+} amdgpu_sync_fence_private;
+
+#define SYNC_FENCE_PRIV(pFence) \
+ (amdgpu_sync_fence_private *) dixLookupPrivate(&pFence->devPrivates, &amdgpu_sync_fence_private_key)
+
+static void
+amdgpu_sync_fence_set_triggered (SyncFence *fence)
+{
+ ScreenPtr screen = fence->pScreen;
+ amdgpu_sync_fence_private *private = SYNC_FENCE_PRIV(fence);
+
+ /* Flush pending rendering operations */
+ amdgpu_glamor_flush(xf86ScreenToScrn(screen));
+
+ fence->funcs.SetTriggered = private->set_triggered;
+ fence->funcs.SetTriggered(fence);
+ private->set_triggered = fence->funcs.SetTriggered;
+ fence->funcs.SetTriggered = amdgpu_sync_fence_set_triggered;
+}
+
+static void
+amdgpu_sync_create_fence(ScreenPtr screen,
+ SyncFence *fence,
+ Bool initially_triggered)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ AMDGPUInfoPtr info = AMDGPUPTR(scrn);
+ SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
+ amdgpu_sync_fence_private *private = SYNC_FENCE_PRIV(fence);
+
+ screen_funcs->CreateFence = info->CreateFence;
+ screen_funcs->CreateFence(screen, fence, initially_triggered);
+ info->CreateFence = screen_funcs->CreateFence;
+ screen_funcs->CreateFence = amdgpu_sync_create_fence;
+
+ private->set_triggered = fence->funcs.SetTriggered;
+ fence->funcs.SetTriggered = amdgpu_sync_fence_set_triggered;
+}
+
+Bool
+amdgpu_sync_init(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ AMDGPUInfoPtr info = AMDGPUPTR(scrn);
+ SyncScreenFuncsPtr screen_funcs;
+
+ if (!miSyncShmScreenInit(screen)) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "SYNC extension fences disabled because "
+ "miSyncShmScreenInit failed\n");
+ return FALSE;
+ }
+
+ if (!dixPrivateKeyRegistered(&amdgpu_sync_fence_private_key)) {
+ if (!dixRegisterPrivateKey(&amdgpu_sync_fence_private_key,
+ PRIVATE_SYNC_FENCE,
+ sizeof (amdgpu_sync_fence_private))) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "SYNC extension fences disabled because "
+ "dixRegisterPrivateKey failed\n");
+ return FALSE;
+ }
+ }
+
+ xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO,
+ "SYNC extension fences enabled\n");
+
+ screen_funcs = miSyncGetScreenFuncs(screen);
+ info->CreateFence = screen_funcs->CreateFence;
+ screen_funcs->CreateFence = amdgpu_sync_create_fence;
+ return TRUE;
+}
+
+void
+amdgpu_sync_close(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ AMDGPUInfoPtr info = AMDGPUPTR(scrn);
+ SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
+
+ if (screen_funcs && info->CreateFence)
+ screen_funcs->CreateFence = info->CreateFence;
+
+ info->CreateFence = NULL;
+}
+
+#else /* !HAVE_MISYNCSHM_H */
+
+Bool
+amdgpu_sync_init(ScreenPtr screen)
+{
+ xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO,
+ "SYNC extension fences disabled because misyncshm.h not "
+ "available at build time\n");
+
+ return FALSE;
+}
+
+void
+amdgpu_sync_close(ScreenPtr screen)
+{
+}
+
+#endif
commit a30060d22a42688371166a861e5050fdd5ce8f7b
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Mon Jun 1 18:33:33 2015 +0900
DRI2: Split out helper for getting UST and MSC of a specific CRTC
(Cherry picked from radeon commits 76c2923ac5c7230a8b2f9f8329c308d28b44d9c0
and d7c82731a8bf3d381bc571b94d80d9bb2dd6e40d)
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index 95db216..28c56e7 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -851,17 +851,13 @@ CARD32 amdgpu_dri2_extrapolate_msc_delay(xf86CrtcPtr crtc, CARD64 * target_msc,
}
/*
- * Get current frame count and frame count timestamp, based on drawable's
- * crtc.
+ * Get current interpolated frame count and frame count timestamp, based on
+ * drawable's crtc.
*/
static int amdgpu_dri2_get_msc(DrawablePtr draw, CARD64 * ust, CARD64 * msc)
{
- ScreenPtr screen = draw->pScreen;
- ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
- AMDGPUInfoPtr info = AMDGPUPTR(scrn);
- drmVBlank vbl;
- int ret;
xf86CrtcPtr crtc = amdgpu_dri2_drawable_crtc(draw, TRUE);
+ int ret;
/* Drawable not displayed, make up a value */
if (crtc == NULL) {
@@ -869,29 +865,20 @@ static int amdgpu_dri2_get_msc(DrawablePtr draw, CARD64 * ust, CARD64 * msc)
*msc = 0;
return TRUE;
}
+
if (amdgpu_crtc_is_enabled(crtc)) {
/* CRTC is running, read vblank counter and timestamp */
- vbl.request.type = DRM_VBLANK_RELATIVE;
- vbl.request.type |= amdgpu_populate_vbl_request_type(crtc);
- vbl.request.sequence = 0;
-
- ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
- if (ret) {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "get vblank counter failed: %s\n",
- strerror(errno));
+ ret = drmmode_crtc_get_ust_msc(crtc, ust, msc);
+ if (ret != Success)
return FALSE;
- }
- *ust =
- ((CARD64) vbl.reply.tval_sec * 1000000) +
- vbl.reply.tval_usec;
- *msc =
- vbl.reply.sequence + amdgpu_get_interpolated_vblanks(crtc);
+ *msc += amdgpu_get_interpolated_vblanks(crtc);
*msc &= 0xffffffff;
} else {
/* CRTC is not running, extrapolate MSC and timestamp */
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ ScrnInfoPtr scrn = crtc->scrn;
+ AMDGPUInfoPtr info = AMDGPUPTR(scrn);
CARD64 now, delta_t, delta_seq;
if (!drmmode_crtc->dpms_last_ust)
@@ -914,7 +901,8 @@ static int amdgpu_dri2_get_msc(DrawablePtr draw, CARD64 * ust, CARD64 * msc)
*msc += delta_seq;
*msc &= 0xffffffff;
}
- return TRUE;
+
+ return ret == Success;
}
static
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index aa7c8c4..01fe860 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -204,6 +204,33 @@ int drmmode_get_current_ust(int drm_fd, CARD64 * ust)
return 0;
}
+/*
+ * Get current frame count and frame count timestamp of the crtc.
+ */
+int drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc)
+{
+ ScrnInfoPtr scrn = crtc->scrn;
+ AMDGPUInfoPtr info = AMDGPUPTR(scrn);
+ drmVBlank vbl;
+ int ret;
+
+ vbl.request.type = DRM_VBLANK_RELATIVE;
+ vbl.request.type |= amdgpu_populate_vbl_request_type(crtc);
+ vbl.request.sequence = 0;
+
+ ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
+ if (ret) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "get vblank counter failed: %s\n", strerror(errno));
+ return ret;
+ }
+
+ *ust = ((CARD64)vbl.reply.tval_sec * 1000000) + vbl.reply.tval_usec;
+ *msc = vbl.reply.sequence;
+
+ return Success;
+}
+
static void drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
{
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 9cf6932..90ab537 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -125,6 +125,7 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
struct amdgpu_buffer *new_front, uint64_t id, void *data,
int ref_crtc_hw_id, amdgpu_drm_handler_proc handler,
amdgpu_drm_abort_proc abort);
+int drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc);
int drmmode_get_current_ust(int drm_fd, CARD64 * ust);
#endif
commit 9a554a683b970660b467566cf05b921393705a20
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Mon Jun 1 17:32:56 2015 +0900
DRI2: Use helper functions for DRM event queue management
This is mostly in preparation for Present support, but it also simplifies
the DRI2 specific code a little.
(Cherry picked from radeon commit 6c3a721cde9317233072b573f9502348dcd21b16)
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index c139dec..95db216 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -49,6 +49,8 @@
#include "amdgpu_list.h"
+#include <xf86Priv.h>
+
#if DRI2INFOREC_VERSION >= 9
#define USE_DRI2_PRIME
#endif
@@ -370,65 +372,20 @@ typedef struct _DRI2FrameEvent {
XID drawable_id;
ClientPtr client;
enum DRI2FrameEventType type;
- int frame;
+ unsigned frame;
xf86CrtcPtr crtc;
+ OsTimerPtr timer;
+ struct amdgpu_drm_queue_entry *drm_queue;
/* for swaps & flips only */
DRI2SwapEventPtr event_complete;
void *event_data;
DRI2BufferPtr front;
DRI2BufferPtr back;
-
- Bool valid;
-
- struct xorg_list link;
} DRI2FrameEventRec, *DRI2FrameEventPtr;
-typedef struct _DRI2ClientEvents {
- struct xorg_list reference_list;
-} DRI2ClientEventsRec, *DRI2ClientEventsPtr;
-
-#if HAS_DEVPRIVATEKEYREC
-
static int DRI2InfoCnt;
-static DevPrivateKeyRec DRI2ClientEventsPrivateKeyRec;
-#define DRI2ClientEventsPrivateKey (&DRI2ClientEventsPrivateKeyRec)
-
-#else
-
-static int DRI2ClientEventsPrivateKeyIndex;
-DevPrivateKey DRI2ClientEventsPrivateKey = &DRI2ClientEventsPrivateKeyIndex;
-
-#endif /* HAS_DEVPRIVATEKEYREC */
-
-#define GetDRI2ClientEvents(pClient) ((DRI2ClientEventsPtr) \
- dixLookupPrivate(&(pClient)->devPrivates, DRI2ClientEventsPrivateKey))
-
-static int ListAddDRI2ClientEvents(ClientPtr client, struct xorg_list *entry)
-{
- DRI2ClientEventsPtr pClientPriv;
- pClientPriv = GetDRI2ClientEvents(client);
-
- if (!pClientPriv) {
- return BadAlloc;
- }
-
- xorg_list_add(entry, &pClientPriv->reference_list);
- return 0;
-}
-
-static void ListDelDRI2ClientEvents(ClientPtr client, struct xorg_list *entry)
-{
- DRI2ClientEventsPtr pClientPriv;
- pClientPriv = GetDRI2ClientEvents(client);
-
- if (!pClientPriv) {
- return;
- }
- xorg_list_del(entry);
-}
-
static void amdgpu_dri2_ref_buffer(BufferPtr buffer)
{
struct dri2_buffer_priv *private = buffer->driverPrivate;
@@ -448,30 +405,13 @@ static void
amdgpu_dri2_client_state_changed(CallbackListPtr * ClientStateCallback,
pointer data, pointer calldata)
{
- DRI2ClientEventsPtr pClientEventsPriv;
- DRI2FrameEventPtr ref;
NewClientInfoRec *clientinfo = calldata;
ClientPtr pClient = clientinfo->client;
- pClientEventsPriv = GetDRI2ClientEvents(pClient);
switch (pClient->clientState) {
- case ClientStateInitial:
- xorg_list_init(&pClientEventsPriv->reference_list);
- break;
- case ClientStateRunning:
- break;
-
case ClientStateRetained:
case ClientStateGone:
- if (pClientEventsPriv) {
- xorg_list_for_each_entry(ref,
- &pClientEventsPriv->
- reference_list, link) {
- ref->valid = FALSE;
- amdgpu_dri2_unref_buffer(ref->front);
- amdgpu_dri2_unref_buffer(ref->back);
- }
- }
+ amdgpu_drm_abort_client(pClient);
break;
default:
break;
@@ -497,37 +437,42 @@ xf86CrtcPtr amdgpu_dri2_drawable_crtc(DrawablePtr pDraw, Bool consider_disabled)
return NULL;
}
-void amdgpu_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data)
+static void
+amdgpu_dri2_flip_event_abort(ScrnInfoPtr scrn, void *event_data)
+{
+ free(event_data);
+}
+
+static void
+amdgpu_dri2_flip_event_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec,
+ void *event_data)
{
DRI2FrameEventPtr flip = event_data;
+ unsigned tv_sec, tv_usec;
DrawablePtr drawable;
ScreenPtr screen;
- ScrnInfoPtr scrn;
int status;
PixmapPtr pixmap;
status = dixLookupDrawable(&drawable, flip->drawable_id, serverClient,
M_ANY, DixWriteAccess);
- if (status != Success) {
- free(flip);
- return;
- }
- if (!flip->crtc) {
- free(flip);
- return;
- }
- frame += amdgpu_get_interpolated_vblanks(flip->crtc);
+ if (status != Success)
+ goto abort;
- screen = drawable->pScreen;
- scrn = xf86ScreenToScrn(screen);
+ if (!flip->crtc)
+ goto abort;
+ frame += amdgpu_get_interpolated_vblanks(flip->crtc);
+ screen = scrn->pScreen;
pixmap = screen->GetScreenPixmap(screen);
xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
"%s:%d fevent[%p] width %d pitch %d (/4 %d)\n",
__func__, __LINE__, flip, pixmap->drawable.width,
pixmap->devKind, pixmap->devKind / 4);
+ tv_sec = usec / 1000000;
+ tv_usec = usec % 1000000;
+
/* We assume our flips arrive in order, so we don't check the frame */
switch (flip->type) {
case DRI2_SWAP:
@@ -537,7 +482,7 @@ void amdgpu_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
*/
if ((frame < flip->frame) && (flip->frame - frame < 5)) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "%s: Pageflip completion event has impossible msc %d < target_msc %d\n",
+ "%s: Pageflip completion event has impossible msc %u < target_msc %u\n",
__func__, frame, flip->frame);
/* All-Zero values signal failure of (msc, ust) timestamping to client. */
frame = tv_sec = tv_usec = 0;
@@ -554,7 +499,8 @@ void amdgpu_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
break;
}
- free(flip);
+abort:
+ amdgpu_dri2_flip_event_abort(scrn, event_data);
}
static Bool
@@ -589,7 +535,10 @@ amdgpu_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr client,
back_priv = back->driverPrivate;
bo = amdgpu_get_pixmap_bo(back_priv->pixmap);
- return amdgpu_do_pageflip(scrn, bo, flip_info, ref_crtc_hw_id);
+ return amdgpu_do_pageflip(scrn, client, bo, AMDGPU_DRM_QUEUE_ID_DEFAULT,
+ flip_info, ref_crtc_hw_id,
+ amdgpu_dri2_flip_event_handler,
+ amdgpu_dri2_flip_event_abort);
}
static Bool update_front(DrawablePtr draw, DRI2BufferPtr front)
@@ -719,31 +668,36 @@ amdgpu_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front,
DamageRegionProcessPending(&front_priv->pixmap->drawable);
}
-void amdgpu_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data)
+static void amdgpu_dri2_frame_event_abort(ScrnInfoPtr scrn, void *event_data)
+{
+ DRI2FrameEventPtr event = event_data;
+
+ TimerCancel(event->timer);
+ TimerFree(event->timer);
+ amdgpu_dri2_unref_buffer(event->front);
+ amdgpu_dri2_unref_buffer(event->back);
+ free(event);
+}
+
+static void amdgpu_dri2_frame_event_handler(ScrnInfoPtr scrn, uint32_t seq,
+ uint64_t usec, void *event_data)
{
DRI2FrameEventPtr event = event_data;
DrawablePtr drawable;
- ScreenPtr screen;
- ScrnInfoPtr scrn;
int status;
int swap_type;
BoxRec box;
RegionRec region;
- if (!event->valid)
+ if (!event->crtc)
goto cleanup;
status = dixLookupDrawable(&drawable, event->drawable_id, serverClient,
M_ANY, DixWriteAccess);
if (status != Success)
goto cleanup;
- if (!event->crtc)
- goto cleanup;
- frame += amdgpu_get_interpolated_vblanks(event->crtc);
- screen = drawable->pScreen;
- scrn = xf86ScreenToScrn(screen);
+ seq += amdgpu_get_interpolated_vblanks(event->crtc);
switch (event->type) {
case DRI2_FLIP:
@@ -778,14 +732,14 @@ void amdgpu_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
swap_type = DRI2_BLIT_COMPLETE;
}
- DRI2SwapComplete(event->client, drawable, frame, tv_sec,
- tv_usec, swap_type, event->event_complete,
+ DRI2SwapComplete(event->client, drawable, seq, usec / 1000000,
+ usec % 1000000, swap_type, event->event_complete,
event->event_data);
break;
case DRI2_WAITMSC:
- DRI2WaitMSCComplete(event->client, drawable, frame, tv_sec,
- tv_usec);
+ DRI2WaitMSCComplete(event->client, drawable, seq, usec / 1000000,
+ usec % 1000000);
break;
default:
/* Unknown type */
@@ -795,12 +749,7 @@ void amdgpu_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
}
cleanup:
- if (event->valid) {
- amdgpu_dri2_unref_buffer(event->front);
- amdgpu_dri2_unref_buffer(event->back);
- ListDelDRI2ClientEvents(event->client, &event->link);
- }
- free(event);
+ amdgpu_dri2_frame_event_abort(scrn, event_data);
}
drmVBlankSeqType amdgpu_populate_vbl_request_type(xf86CrtcPtr crtc)
@@ -972,17 +921,13 @@ static
CARD32 amdgpu_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
{
DRI2FrameEventPtr event_info = (DRI2FrameEventPtr) data;
- DrawablePtr drawable;
- ScreenPtr screen;
+ xf86CrtcPtr crtc = event_info->crtc;
ScrnInfoPtr scrn;
AMDGPUInfoPtr info;
- int status;
CARD64 drm_now;
int ret;
- unsigned int tv_sec, tv_usec;
CARD64 delta_t, delta_seq, frame;
drmmode_crtc_private_ptr drmmode_crtc;
- TimerFree(timer);
/*
* This is emulated event, so its time is current time, which we
@@ -993,29 +938,26 @@ CARD32 amdgpu_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
*/
if (!event_info->crtc) {
ErrorF("%s no crtc\n", __func__);
- amdgpu_dri2_frame_event_handler(0, 0, 0, data);
+ if (event_info->drm_queue)
+ amdgpu_drm_abort_entry(event_info->drm_queue);
+ else
+ amdgpu_dri2_frame_event_abort(NULL, data);
return 0;
}
- status =
- dixLookupDrawable(&drawable, event_info->drawable_id, serverClient,
- M_ANY, DixWriteAccess);
- if (status != Success) {
- ErrorF("%s cannot lookup drawable\n", __func__);
- amdgpu_dri2_frame_event_handler(0, 0, 0, data);
- return 0;
- }
- screen = drawable->pScreen;
- scrn = xf86ScreenToScrn(screen);
+
+ scrn = crtc->scrn;
info = AMDGPUPTR(scrn);
ret = drmmode_get_current_ust(info->dri2.drm_fd, &drm_now);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"%s cannot get current time\n", __func__);
- amdgpu_dri2_frame_event_handler(0, 0, 0, data);
+ if (event_info->drm_queue)
+ amdgpu_drm_queue_handler(info->dri2.drm_fd, 0, 0, 0,
+ event_info->drm_queue);
+ else
+ amdgpu_dri2_frame_event_handler(scrn, 0, 0, data);
return 0;
}
- tv_sec = (unsigned int)(drm_now / 1000000);
- tv_usec = (unsigned int)(drm_now - (CARD64) tv_sec * 1000000);
/*
* calculate the frame number from current time
* that would come from CRTC if it were running
@@ -1025,21 +967,22 @@ CARD32 amdgpu_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
delta_seq = delta_t * drmmode_crtc->dpms_last_fps;
delta_seq /= 1000000;
frame = (CARD64) drmmode_crtc->dpms_last_seq + delta_seq;
- frame &= 0xffffffff;
- amdgpu_dri2_frame_event_handler((unsigned int)frame, tv_sec, tv_usec,
- data);
+ if (event_info->drm_queue)
+ amdgpu_drm_queue_handler(info->dri2.drm_fd, frame, drm_now / 1000000,
+ drm_now % 1000000, event_info->drm_queue);
+ else
+ amdgpu_dri2_frame_event_handler(scrn, frame, drm_now, data);
return 0;
}
static
-void amdgpu_dri2_schedule_event(CARD32 delay, pointer arg)
+void amdgpu_dri2_schedule_event(CARD32 delay, DRI2FrameEventPtr event_info)
{
- OsTimerPtr timer;
-
- timer = TimerSet(NULL, 0, delay, amdgpu_dri2_deferred_event, arg);
+ event_info->timer = TimerSet(NULL, 0, delay, amdgpu_dri2_deferred_event,
+ event_info);
if (delay == 0) {
CARD32 now = GetTimeInMillis();
- amdgpu_dri2_deferred_event(timer, now, arg);
+ amdgpu_dri2_deferred_event(event_info->timer, now, event_info);
}
}
@@ -1057,6 +1000,7 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
AMDGPUInfoPtr info = AMDGPUPTR(scrn);
DRI2FrameEventPtr wait_info = NULL;
+ struct amdgpu_drm_queue_entry *wait = NULL;
xf86CrtcPtr crtc = amdgpu_dri2_drawable_crtc(draw, TRUE);
drmVBlank vbl;
int ret;
@@ -1079,17 +1023,8 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
wait_info->drawable_id = draw->id;
wait_info->client = client;
wait_info->type = DRI2_WAITMSC;
- wait_info->valid = TRUE;
wait_info->crtc = crtc;
- if (ListAddDRI2ClientEvents(client, &wait_info->link)) {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "add events to client private failed.\n");
- free(wait_info);
- wait_info = NULL;
- goto out_complete;
- }
-
/*
* CRTC is in DPMS off state, calculate wait time from current time,
* target_msc and last vblank time/sequence when CRTC was turned off
@@ -1118,6 +1053,16 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
vbl.reply.sequence + amdgpu_get_interpolated_vblanks(crtc);
current_msc &= 0xffffffff;
+ wait = amdgpu_drm_queue_alloc(scrn, client, AMDGPU_DRM_QUEUE_ID_DEFAULT,
+ wait_info, amdgpu_dri2_frame_event_handler,
+ amdgpu_dri2_frame_event_abort);
+ if (!wait) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "Allocating DRM queue event entry failed.\n");
+ goto out_complete;
+ }
+ wait_info->drm_queue = wait;
+
/*
* If divisor is zero, or current_msc is smaller than target_msc,
* we just need to make sure target_msc passes before waking up the
@@ -1136,7 +1081,7 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
vbl.request.type |= amdgpu_populate_vbl_request_type(crtc);
vbl.request.sequence = target_msc;
vbl.request.sequence -= amdgpu_get_interpolated_vblanks(crtc);
- vbl.request.signal = (unsigned long)wait_info;
+ vbl.request.signal = (unsigned long)wait;
ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1169,7 +1114,7 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
vbl.request.sequence += divisor;
vbl.request.sequence -= amdgpu_get_interpolated_vblanks(crtc);
- vbl.request.signal = (unsigned long)wait_info;
+ vbl.request.signal = (unsigned long)wait;
ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1182,11 +1127,8 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
return TRUE;
out_complete:
- if (wait_info) {
- ListDelDRI2ClientEvents(wait_info->client, &wait_info->link);
- free(wait_info);
- }
- DRI2WaitMSCComplete(client, draw, target_msc, 0, 0);
+ if (wait_info)
+ amdgpu_dri2_deferred_event(NULL, 0, wait_info);
return TRUE;
}
@@ -1223,6 +1165,7 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
drmVBlank vbl;
int ret, flip = 0;
DRI2FrameEventPtr swap_info = NULL;
+ struct amdgpu_drm_queue_entry *swap;
CARD64 current_msc;
BoxRec box;
RegionRec region;
@@ -1255,15 +1198,17 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
swap_info->event_data = data;
swap_info->front = front;
swap_info->back = back;
- swap_info->valid = TRUE;
swap_info->crtc = crtc;
- if (ListAddDRI2ClientEvents(client, &swap_info->link)) {
+
+ swap = amdgpu_drm_queue_alloc(scrn, client, AMDGPU_DRM_QUEUE_ID_DEFAULT,
+ swap_info, amdgpu_dri2_frame_event_handler,
+ amdgpu_dri2_frame_event_abort);
+ if (!swap) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "add events to client private failed.\n");
- free(swap_info);
- swap_info = NULL;
+ "Allocating DRM queue entry failed.\n");
goto blit_fallback;
}
+ swap_info->drm_queue = swap;
/*
* CRTC is in DPMS off state, fallback to blit, but calculate
@@ -1331,7 +1276,7 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
vbl.request.sequence = *target_msc;
vbl.request.sequence -= amdgpu_get_interpolated_vblanks(crtc);
- vbl.request.signal = (unsigned long)swap_info;
+ vbl.request.signal = (unsigned long)swap;
ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1378,7 +1323,7 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
/* Account for 1 frame extra pageflip delay if flip > 0 */
vbl.request.sequence -= flip;
- vbl.request.signal = (unsigned long)swap_info;
+ vbl.request.signal = (unsigned long)swap;
ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1472,26 +1417,6 @@ Bool amdgpu_dri2_screen_init(ScreenPtr pScreen)
driverNames[0] = driverNames[1] = dri2_info.driverName;
if (DRI2InfoCnt == 0) {
-#if HAS_DIXREGISTERPRIVATEKEY
- if (!dixRegisterPrivateKey(DRI2ClientEventsPrivateKey,
- PRIVATE_CLIENT,
- sizeof(DRI2ClientEventsRec)))
- {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "DRI2 registering "
- "private key to client failed\n");
- return FALSE;
- }
-#else
- if (!dixRequestPrivate(DRI2ClientEventsPrivateKey,
- sizeof(DRI2ClientEventsRec))) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "DRI2 requesting "
- "private key to client failed\n");
- return FALSE;
- }
-#endif
-
AddCallback(&ClientStateCallback,
amdgpu_dri2_client_state_changed, 0);
}
diff --git a/src/amdgpu_dri2.h b/src/amdgpu_dri2.h
index 3ca9dd2..d9bec91 100644
--- a/src/amdgpu_dri2.h
+++ b/src/amdgpu_dri2.h
@@ -43,12 +43,6 @@ struct amdgpu_dri2 {
Bool amdgpu_dri2_screen_init(ScreenPtr pScreen);
void amdgpu_dri2_close_screen(ScreenPtr pScreen);
-int drmmode_get_crtc_id(xf86CrtcPtr crtc);
-void amdgpu_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data);
-void amdgpu_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data);
-
#else
static inline Bool amdgpu_dri2_screen_init(ScreenPtr pScreen)
@@ -60,37 +54,6 @@ static inline void amdgpu_dri2_close_screen(ScreenPtr pScreen)
{
}
-static inline void
-amdgpu_dri2_dummy_event_handler(unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data,
- const char *name)
-{
- static Bool warned;
-
- if (!warned) {
- ErrorF("%s called but DRI2 disabled at build time\n", name);
- warned = TRUE;
- }
-
- free(event_data);
-}
-
-static inline void
-amdgpu_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data)
-{
- amdgpu_dri2_dummy_event_handler(frame, tv_sec, tv_usec, event_data,
- __func__);
-}
-
-static inline void
-amdgpu_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data)
-{
- amdgpu_dri2_dummy_event_handler(frame, tv_sec, tv_usec, event_data,
- __func__);
-}
-
#endif
#endif /* AMDGPU_DRI2_H */
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index bb93833..aa7c8c4 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1391,46 +1391,52 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
};
static void
-drmmode_vblank_handler(int fd, unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data)
+drmmode_flip_free(drmmode_flipevtcarrier_ptr flipcarrier)
{
- amdgpu_dri2_frame_event_handler(frame, tv_sec, tv_usec, event_data);
+ drmmode_flipdata_ptr flipdata = flipcarrier->flipdata;
+
+ free(flipcarrier);
+
+ if (--flipdata->flip_count > 0)
+ return;
+
+ /* Release framebuffer */
+ drmModeRmFB(flipdata->drmmode->fd, flipdata->old_fb_id);
+
+ free(flipdata);
+}
+
+static void
+drmmode_flip_abort(ScrnInfoPtr scrn, void *event_data)
+{
+ drmmode_flipevtcarrier_ptr flipcarrier = event_data;
+ drmmode_flipdata_ptr flipdata = flipcarrier->flipdata;
+
+ if (flipdata->flip_count == 1)
+ flipcarrier->abort(scrn, flipdata->event_data);
+
+ drmmode_flip_free(flipcarrier);
}
static void
-drmmode_flip_handler(int fd, unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data)
+drmmode_flip_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec, void *event_data)
{
drmmode_flipevtcarrier_ptr flipcarrier = event_data;
drmmode_flipdata_ptr flipdata = flipcarrier->flipdata;
- drmmode_ptr drmmode = flipdata->drmmode;
/* Is this the event whose info shall be delivered to higher level? */
if (flipcarrier->dispatch_me) {
/* Yes: Cache msc, ust for later delivery. */
flipdata->fe_frame = frame;
- flipdata->fe_tv_sec = tv_sec;
- flipdata->fe_tv_usec = tv_usec;
+ flipdata->fe_usec = usec;
}
- free(flipcarrier);
-
- /* Last crtc completed flip? */
- flipdata->flip_count--;
- if (flipdata->flip_count > 0)
- return;
-
- /* Release framebuffer */
- drmModeRmFB(drmmode->fd, flipdata->old_fb_id);
-
- if (flipdata->event_data == NULL)
- return;
/* Deliver cached msc, ust from reference crtc to flip event handler */
- amdgpu_dri2_flip_event_handler(flipdata->fe_frame, flipdata->fe_tv_sec,
- flipdata->fe_tv_usec,
- flipdata->event_data);
+ if (flipdata->event_data && flipdata->flip_count == 1)
+ flipcarrier->handler(scrn, flipdata->fe_frame, flipdata->fe_usec,
+ flipdata->event_data);
- free(flipdata);
+ drmmode_flip_free(flipcarrier);
}
static void drm_wakeup_handler(pointer data, int err, pointer p)
@@ -1475,8 +1481,8 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
xf86InitialConfiguration(pScrn, TRUE);
drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION;
- drmmode->event_context.vblank_handler = drmmode_vblank_handler;
- drmmode->event_context.page_flip_handler = drmmode_flip_handler;
+ drmmode->event_context.vblank_handler = amdgpu_drm_queue_handler;
+ drmmode->event_context.page_flip_handler = amdgpu_drm_queue_handler;
return TRUE;
}
@@ -1743,8 +1749,10 @@ void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode)
#endif
}
-Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, struct amdgpu_buffer *new_front,
- void *data, int ref_crtc_hw_id)
+Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
+ struct amdgpu_buffer *new_front, uint64_t id, void *data,
+ int ref_crtc_hw_id, amdgpu_drm_handler_proc handler,
+ amdgpu_drm_abort_proc abort)
{
AMDGPUInfoPtr info = AMDGPUPTR(scrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -1754,7 +1762,8 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, struct amdgpu_buffer *new_front,
int i, old_fb_id;
int height, emitted = 0;
drmmode_flipdata_ptr flipdata;
- drmmode_flipevtcarrier_ptr flipcarrier;
+ drmmode_flipevtcarrier_ptr flipcarrier = NULL;
+ struct amdgpu_drm_queue_entry *drm_queue = 0;
union gbm_bo_handle bo_handle;
uint32_t handle;
@@ -1823,10 +1832,22 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, struct amdgpu_buffer *new_front,
flipcarrier->dispatch_me =
(drmmode_crtc->hw_id == ref_crtc_hw_id);
flipcarrier->flipdata = flipdata;
+ flipcarrier->handler = handler;
+ flipcarrier->abort = abort;
+
+ drm_queue = amdgpu_drm_queue_alloc(scrn, client, id,
+ flipcarrier,
+ drmmode_flip_handler,
+ drmmode_flip_abort);
+ if (!drm_queue) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "Allocating DRM queue event entry failed.\n");
+ goto error_undo;
+ }
- if (drmModePageFlip
- (drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
- drmmode->fb_id, DRM_MODE_PAGE_FLIP_EVENT, flipcarrier)) {
+ if (drmModePageFlip(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+ drmmode->fb_id, DRM_MODE_PAGE_FLIP_EVENT,
+ drm_queue)) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"flip queue failed: %s\n", strerror(errno));
free(flipcarrier);
@@ -1841,6 +1862,11 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, struct amdgpu_buffer *new_front,
return TRUE;
error_undo:
+ if (drm_queue)
+ amdgpu_drm_abort_entry(drm_queue);
+ else
+ drmmode_flip_abort(scrn, flipcarrier);
+
drmModeRmFB(drmmode->fd, drmmode->fb_id);
drmmode->fb_id = old_fb_id;
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index c2ec683..9cf6932 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -32,6 +32,7 @@
#include "libudev.h"
#endif
+#include "amdgpu_drm_queue.h"
#include "amdgpu_probe.h"
#include "amdgpu.h"
@@ -59,13 +60,14 @@ typedef struct {
int flip_count;
void *event_data;
unsigned int fe_frame;
- unsigned int fe_tv_sec;
- unsigned int fe_tv_usec;
+ uint64_t fe_usec;
} drmmode_flipdata_rec, *drmmode_flipdata_ptr;
typedef struct {
drmmode_flipdata_ptr flipdata;
Bool dispatch_me;
+ amdgpu_drm_handler_proc handler;
+ amdgpu_drm_abort_proc abort;
} drmmode_flipevtcarrier_rec, *drmmode_flipevtcarrier_ptr;
typedef struct {
@@ -117,9 +119,12 @@ extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode);
extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode);
+extern int drmmode_get_crtc_id(xf86CrtcPtr crtc);
extern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe);
-Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, struct amdgpu_buffer *new_front,
- void *data, int ref_crtc_hw_id);
+Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
+ struct amdgpu_buffer *new_front, uint64_t id, void *data,
+ int ref_crtc_hw_id, amdgpu_drm_handler_proc handler,
+ amdgpu_drm_abort_proc abort);
int drmmode_get_current_ust(int drm_fd, CARD64 * ust);
#endif
commit e6164ad340f65ff8ee6f6a6934302591af875a43
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Mon Jun 1 17:29:30 2015 +0900
DRI2: Move amdgpu_dri2_flip_event_handler
In preparation for the next change, which will modify it to a static
function which needs to be in the new place. No functional change.
(Cherry picked from radeon commit c3fa22a479e61d1899fa9d327d9c4e2a7f64b0c1)
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index fd98fa7..c139dec 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -497,6 +497,66 @@ xf86CrtcPtr amdgpu_dri2_drawable_crtc(DrawablePtr pDraw, Bool consider_disabled)
return NULL;
}
+void amdgpu_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
+ unsigned int tv_usec, void *event_data)
+{
+ DRI2FrameEventPtr flip = event_data;
+ DrawablePtr drawable;
+ ScreenPtr screen;
+ ScrnInfoPtr scrn;
+ int status;
+ PixmapPtr pixmap;
+
+ status = dixLookupDrawable(&drawable, flip->drawable_id, serverClient,
+ M_ANY, DixWriteAccess);
+ if (status != Success) {
+ free(flip);
+ return;
+ }
+ if (!flip->crtc) {
+ free(flip);
+ return;
+ }
+ frame += amdgpu_get_interpolated_vblanks(flip->crtc);
+
+ screen = drawable->pScreen;
+ scrn = xf86ScreenToScrn(screen);
+
+ pixmap = screen->GetScreenPixmap(screen);
+ xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
+ "%s:%d fevent[%p] width %d pitch %d (/4 %d)\n",
+ __func__, __LINE__, flip, pixmap->drawable.width,
+ pixmap->devKind, pixmap->devKind / 4);
+
+ /* We assume our flips arrive in order, so we don't check the frame */
+ switch (flip->type) {
+ case DRI2_SWAP:
+ /* Check for too small vblank count of pageflip completion, taking wraparound
+ * into account. This usually means some defective kms pageflip completion,
+ * causing wrong (msc, ust) return values and possible visual corruption.
+ */
+ if ((frame < flip->frame) && (flip->frame - frame < 5)) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "%s: Pageflip completion event has impossible msc %d < target_msc %d\n",
+ __func__, frame, flip->frame);
+ /* All-Zero values signal failure of (msc, ust) timestamping to client. */
+ frame = tv_sec = tv_usec = 0;
+ }
+
+ DRI2SwapComplete(flip->client, drawable, frame, tv_sec, tv_usec,
+ DRI2_FLIP_COMPLETE, flip->event_complete,
+ flip->event_data);
+ break;
+ default:
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "%s: unknown vblank event received\n", __func__);
+ /* Unknown type */
+ break;
+ }
+
+ free(flip);
+}
+
static Bool
amdgpu_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr client,
DrawablePtr draw, DRI2BufferPtr front,
@@ -1130,66 +1190,6 @@ out_complete:
return TRUE;
}
-void amdgpu_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data)
-{
- DRI2FrameEventPtr flip = event_data;
- DrawablePtr drawable;
- ScreenPtr screen;
- ScrnInfoPtr scrn;
- int status;
- PixmapPtr pixmap;
-
- status = dixLookupDrawable(&drawable, flip->drawable_id, serverClient,
- M_ANY, DixWriteAccess);
- if (status != Success) {
- free(flip);
- return;
- }
- if (!flip->crtc) {
- free(flip);
- return;
- }
- frame += amdgpu_get_interpolated_vblanks(flip->crtc);
-
- screen = drawable->pScreen;
- scrn = xf86ScreenToScrn(screen);
-
- pixmap = screen->GetScreenPixmap(screen);
- xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
- "%s:%d fevent[%p] width %d pitch %d (/4 %d)\n",
- __func__, __LINE__, flip, pixmap->drawable.width,
- pixmap->devKind, pixmap->devKind / 4);
-
- /* We assume our flips arrive in order, so we don't check the frame */
- switch (flip->type) {
- case DRI2_SWAP:
- /* Check for too small vblank count of pageflip completion, taking wraparound
- * into account. This usually means some defective kms pageflip completion,
- * causing wrong (msc, ust) return values and possible visual corruption.
- */
- if ((frame < flip->frame) && (flip->frame - frame < 5)) {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "%s: Pageflip completion event has impossible msc %d < target_msc %d\n",
- __func__, frame, flip->frame);
- /* All-Zero values signal failure of (msc, ust) timestamping to client. */
- frame = tv_sec = tv_usec = 0;
- }
-
- DRI2SwapComplete(flip->client, drawable, frame, tv_sec, tv_usec,
- DRI2_FLIP_COMPLETE, flip->event_complete,
- flip->event_data);
- break;
- default:
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "%s: unknown vblank event received\n", __func__);
- /* Unknown type */
- break;
- }
-
- free(flip);
-}
-
/*
* ScheduleSwap is responsible for requesting a DRM vblank event for the
* appropriate frame.
commit 5419e13da7ec3cffd43510ac88106076ea81124c
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Mon Jun 1 17:25:23 2015 +0900
DRI2: Remove superfluous assignments to *_info->frame
That field is only used for page flipping.
(Cherry picked from radeon commit 65045112fdc8a9fa36e0e00f46739a6152b775ff)
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index 895abcd..fd98fa7 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -1038,7 +1038,6 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
CARD32 delay;
delay = amdgpu_dri2_extrapolate_msc_delay(crtc, &target_msc,
divisor, remainder);
- wait_info->frame = target_msc;
amdgpu_dri2_schedule_event(delay, wait_info);
DRI2BlockClient(client, draw);
return TRUE;
@@ -1086,8 +1085,6 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
goto out_complete;
}
- wait_info->frame = vbl.reply.sequence;
- wait_info->frame += amdgpu_get_interpolated_vblanks(crtc);
DRI2BlockClient(client, draw);
return TRUE;
}
@@ -1120,8 +1117,6 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
goto out_complete;
}
- wait_info->frame = vbl.reply.sequence;
- wait_info->frame += amdgpu_get_interpolated_vblanks(crtc);
DRI2BlockClient(client, draw);
return TRUE;
@@ -1279,7 +1274,6 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
CARD32 delay;
delay = amdgpu_dri2_extrapolate_msc_delay(crtc, target_msc,
divisor, remainder);
- swap_info->frame = *target_msc;
amdgpu_dri2_schedule_event(delay, swap_info);
return TRUE;
}
commit f4c2b640be17ab1f8694b35d4cb74ccfce3d1385
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Mon Jun 1 17:11:30 2015 +0900
DRI2: Simplify blit fallback handling for scheduled swaps
Also use amdgpu_dri2_schedule_event when possible.
(Cherry picked from radeon commit ad27f16f308079d06a2b1c788b3cb0947531253a)
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index f05b742..895abcd 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -1228,7 +1228,6 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
drmVBlank vbl;
int ret, flip = 0;
DRI2FrameEventPtr swap_info = NULL;
- enum DRI2FrameEventType swap_type = DRI2_SWAP;
CARD64 current_msc;
BoxRec box;
RegionRec region;
@@ -1254,6 +1253,7 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
if (!swap_info)
goto blit_fallback;
+ swap_info->type = DRI2_SWAP;
swap_info->drawable_id = draw->id;
swap_info->client = client;
swap_info->event_complete = func;
@@ -1293,9 +1293,7 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"first get vblank counter failed: %s\n",
strerror(errno));
- *target_msc = 0;
- amdgpu_dri2_schedule_event(FALLBACK_SWAP_DELAY, swap_info);
- return TRUE;
+ goto blit_fallback;
}
current_msc =
@@ -1304,13 +1302,11 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
/* Flips need to be submitted one frame before */
if (can_flip(scrn, draw, front, back)) {
- swap_type = DRI2_FLIP;
+ swap_info->type = DRI2_FLIP;
flip = 1;
}
- swap_info->type = swap_type;
-
- /* Correct target_msc by 'flip' if swap_type == DRI2_FLIP.
+ /* Correct target_msc by 'flip' if swap_info->type == DRI2_FLIP.
* Do it early, so handling of different timing constraints
* for divisor, remainder and msc vs. target_msc works.
*/
@@ -1347,10 +1343,7 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"divisor 0 get vblank counter failed: %s\n",
strerror(errno));
- *target_msc = 0;
- amdgpu_dri2_schedule_event(FALLBACK_SWAP_DELAY,
- swap_info);
- return TRUE;
+ goto blit_fallback;
}
*target_msc = vbl.reply.sequence + flip;
@@ -1397,9 +1390,7 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"final get vblank counter failed: %s\n",
strerror(errno));
- *target_msc = 0;
- amdgpu_dri2_schedule_event(FALLBACK_SWAP_DELAY, swap_info);
- return TRUE;
+ goto blit_fallback;
}
/* Adjust returned value for 1 fame pageflip offset of flip > 0 */
@@ -1410,22 +1401,23 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
return TRUE;
blit_fallback:
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = draw->width;
- box.y2 = draw->height;
- REGION_INIT(pScreen, ®ion, &box, 0);
+ if (swap_info) {
+ swap_info->type = DRI2_SWAP;
+ amdgpu_dri2_schedule_event(FALLBACK_SWAP_DELAY, swap_info);
+ } else {
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = draw->width;
+ box.y2 = draw->height;
+ REGION_INIT(pScreen, ®ion, &box, 0);
- amdgpu_dri2_copy_region(draw, ®ion, front, back);
+ amdgpu_dri2_copy_region(draw, ®ion, front, back);
- DRI2SwapComplete(client, draw, 0, 0, 0, DRI2_BLIT_COMPLETE, func, data);
- if (swap_info) {
- ListDelDRI2ClientEvents(swap_info->client, &swap_info->link);
- free(swap_info);
- }
+ DRI2SwapComplete(client, draw, 0, 0, 0, DRI2_BLIT_COMPLETE, func, data);
- amdgpu_dri2_unref_buffer(front);
- amdgpu_dri2_unref_buffer(back);
+ amdgpu_dri2_unref_buffer(front);
+ amdgpu_dri2_unref_buffer(back);
+ }
*target_msc = 0; /* offscreen, so zero out target vblank count */
return TRUE;
commit 13a7284e061081a12180b375d66f9b8394cf8753
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Mon Jun 1 16:58:00 2015 +0900
Add DRM event queue helpers
(Cherry picked from radeon commit b4af8a327ed8420f0ff4ea0f113f4a59406ed4d3)
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/Makefile.am b/src/Makefile.am
index 3fe1cd0..8e91472 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -28,7 +28,8 @@
amdgpu_drv_la_LIBADD = $(PCIACCESS_LIBS) $(LIBDRM_AMDGPU_LIBS) $(GBM_LIBS)
-AMDGPU_KMS_SRCS=amdgpu_dri2.c amdgpu_kms.c drmmode_display.c amdgpu_bo_helper.c
+AMDGPU_KMS_SRCS=amdgpu_bo_helper.c amdgpu_dri2.c amdgpu_drm_queue.c amdgpu_kms.c \
+ drmmode_display.c
AM_CFLAGS = \
@GBM_CFLAGS@ \
@@ -57,6 +58,7 @@ amdgpu_drv_la_SOURCES += \
EXTRA_DIST = \
compat-api.h \
amdgpu_bo_helper.h \
+ amdgpu_drm_queue.h \
amdgpu_glamor.h \
amdgpu_drv.h \
amdgpu_list.h \
diff --git a/src/amdgpu_drm_queue.c b/src/amdgpu_drm_queue.c
new file mode 100644
index 0000000..9bec658
--- /dev/null
+++ b/src/amdgpu_drm_queue.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ * Copyright © 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Dave Airlie <airlied at redhat.com>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <xorg-server.h>
+
+#include "amdgpu_drv.h"
+#include "amdgpu_drm_queue.h"
+#include "amdgpu_list.h"
+
+
+struct amdgpu_drm_queue_entry {
+ struct xorg_list list;
+ uint64_t id;
+ void *data;
+ ClientPtr client;
+ ScrnInfoPtr scrn;
+ amdgpu_drm_handler_proc handler;
+ amdgpu_drm_abort_proc abort;
+};
+
+static int amdgpu_drm_queue_refcnt;
+static struct xorg_list amdgpu_drm_queue;
+
+
+/*
+ * Handle a DRM event
+ */
+void
+amdgpu_drm_queue_handler(int fd, unsigned int frame, unsigned int sec,
+ unsigned int usec, void *user_ptr)
+{
+ struct amdgpu_drm_queue_entry *user_data = user_ptr;
+ struct amdgpu_drm_queue_entry *e, *tmp;
+
+ xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_queue, list) {
+ if (e == user_data) {
+ xorg_list_del(&e->list);
+ e->handler(e->scrn, frame,
+ (uint64_t)sec * 1000000 + usec, e->data);
+ free(e);
+ break;
+ }
+ }
+}
+
+/*
+ * Enqueue a potential drm response; when the associated response
+ * appears, we've got data to pass to the handler from here
+ */
+struct amdgpu_drm_queue_entry *
+amdgpu_drm_queue_alloc(ScrnInfoPtr scrn, ClientPtr client,
+ uint64_t id, void *data,
+ amdgpu_drm_handler_proc handler,
+ amdgpu_drm_abort_proc abort)
+{
+ struct amdgpu_drm_queue_entry *e;
+
+ e = calloc(1, sizeof(struct amdgpu_drm_queue_entry));
+ if (!e)
+ return NULL;
+
+ e->client = client;
+ e->scrn = scrn;
+ e->id = id;
+ e->data = data;
+ e->handler = handler;
+ e->abort = abort;
+
+ xorg_list_add(&e->list, &amdgpu_drm_queue);
+
+ return e;
+}
+
+/*
+ * Abort one queued DRM entry, removing it
+ * from the list, calling the abort function and
+ * freeing the memory
+ */
+static void
+amdgpu_drm_abort_one(struct amdgpu_drm_queue_entry *e)
+{
+ xorg_list_del(&e->list);
+ e->abort(e->scrn, e->data);
+ free(e);
+}
+
+/*
+ * Abort drm queue entries for a client
+ */
+void
+amdgpu_drm_abort_client(ClientPtr client)
+{
+ struct amdgpu_drm_queue_entry *e, *tmp;
+
+ xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_queue, list) {
+ if (e->client == client)
+ amdgpu_drm_abort_one(e);
+ }
+}
+
+/*
+ * Abort specific drm queue entry
+ */
+void
+amdgpu_drm_abort_entry(struct amdgpu_drm_queue_entry *entry)
+{
+ amdgpu_drm_abort_one(entry);
+}
+
+/*
+ * Abort specific drm queue entry by ID
+ */
+void
+amdgpu_drm_abort_id(uint64_t id)
+{
+ struct amdgpu_drm_queue_entry *e, *tmp;
+
+ xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_queue, list) {
+ if (e->id == id) {
+ amdgpu_drm_abort_one(e);
+ break;
+ }
+ }
+}
+
+/*
+ * Initialize the DRM event queue
+ */
+void
+amdgpu_drm_queue_init()
+{
+ if (amdgpu_drm_queue_refcnt++)
+ return;
+
+ xorg_list_init(&amdgpu_drm_queue);
+}
+
+/*
+ * Deinitialize the DRM event queue
+ */
+void
+amdgpu_drm_queue_close(ScrnInfoPtr scrn)
+{
+ struct amdgpu_drm_queue_entry *e, *tmp;
+
+ xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_queue, list) {
+ if (e->scrn == scrn)
+ amdgpu_drm_abort_one(e);
+ }
+
+ amdgpu_drm_queue_refcnt--;
+}
diff --git a/src/amdgpu_drm_queue.h b/src/amdgpu_drm_queue.h
new file mode 100644
index 0000000..96841f6
--- /dev/null
+++ b/src/amdgpu_drm_queue.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ * Copyright © 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Dave Airlie <airlied at redhat.com>
+ *
+ */
+
+#ifndef _AMDGPU_DRM_QUEUE_H_
+#define _AMDGPU_DRM_QUEUE_H_
+
+#define AMDGPU_DRM_QUEUE_CLIENT_DEFAULT serverClient
+#define AMDGPU_DRM_QUEUE_ID_DEFAULT ~0ULL
+
+struct amdgpu_drm_queue_entry;
+
+typedef void (*amdgpu_drm_handler_proc)(ScrnInfoPtr scrn, uint32_t seq,
+ uint64_t usec, void *data);
+typedef void (*amdgpu_drm_abort_proc)(ScrnInfoPtr scrn, void *data);
+
+void amdgpu_drm_queue_handler(int fd, unsigned int frame,
+ unsigned int tv_sec, unsigned int tv_usec,
+ void *user_ptr);
+struct amdgpu_drm_queue_entry *amdgpu_drm_queue_alloc(ScrnInfoPtr scrn,
+ ClientPtr client,
+ uint64_t id,
+ void *data,
+ amdgpu_drm_handler_proc handler,
+ amdgpu_drm_abort_proc abort);
+void amdgpu_drm_abort_client(ClientPtr client);
+void amdgpu_drm_abort_entry(struct amdgpu_drm_queue_entry *entry);
+void amdgpu_drm_abort_id(uint64_t id);
+void amdgpu_drm_queue_init();
+void amdgpu_drm_queue_close(ScrnInfoPtr scrn);
+
+#endif /* _AMDGPU_DRM_QUEUE_H_ */
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 16a7449..71a4aa7 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -32,6 +32,7 @@
#include <sys/ioctl.h>
/* Driver data structures */
#include "amdgpu_drv.h"
+#include "amdgpu_drm_queue.h"
#include "amdgpu_glamor.h"
#include "amdgpu_probe.h"
#include "micmap.h"
@@ -529,6 +530,8 @@ Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
if (!AMDGPUPreInitAccel_KMS(pScrn))
goto fail;
+ amdgpu_drm_queue_init();
+
AMDGPUSetupCapabilities(pScrn);
/* don't enable tiling if accel is not enabled */
@@ -696,6 +699,7 @@ static Bool AMDGPUCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL)
"AMDGPUCloseScreen\n");
drmmode_uevent_fini(pScrn, &info->drmmode);
+ amdgpu_drm_queue_close(pScrn);
DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn);
commit eb7c6958dff5cb8b0aad02d1d5673483dae4e3d4
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Mon Jun 1 16:52:40 2015 +0900
Move xorg_list backwards compatibility to new amdgpu_list.h header
(Cherry picked from radeon commits 7c3470f4b659206ed23f761948936ede3a2dba3d
and 4a98f60117c387a228d5cbaadb6e298fb4e865df)
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/Makefile.am b/src/Makefile.am
index 8715eb3..3fe1cd0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -59,6 +59,7 @@ EXTRA_DIST = \
amdgpu_bo_helper.h \
amdgpu_glamor.h \
amdgpu_drv.h \
+ amdgpu_list.h \
amdgpu_probe.h \
amdgpu_version.h \
amdgpu_video.h \
diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index 32f6171..f05b742 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -47,14 +47,7 @@
#include "amdgpu_version.h"
-#include "list.h"
-#if !HAVE_XORG_LIST
-#define xorg_list list
-#define xorg_list_init list_init
-#define xorg_list_add list_add
-#define xorg_list_del list_del
-#define xorg_list_for_each_entry list_for_each_entry
-#endif
+#include "amdgpu_list.h"
#if DRI2INFOREC_VERSION >= 9
#define USE_DRI2_PRIME
diff --git a/src/amdgpu_list.h b/src/amdgpu_list.h
new file mode 100644
index 0000000..c1e3516
--- /dev/null
+++ b/src/amdgpu_list.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _AMDGPU_LIST_H_
+#define _AMDGPU_LIST_H_
+
+#include <xorg-server.h>
+#include <list.h>
+
+#if !HAVE_XORG_LIST
+#define xorg_list list
+#define xorg_list_init list_init
+#define xorg_list_add list_add
+#define xorg_list_del list_del
+#define xorg_list_for_each_entry list_for_each_entry
+#define xorg_list_for_each_entry_safe list_for_each_entry_safe
+#endif
+
+#endif /* _AMDGPU_LIST_H_ */
commit 69d161a54b4ea0d8033a0873210f2857c91ceae8
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Mon Jun 1 16:46:30 2015 +0900
Require at least xserver 1.8
So we can rely on the list.h header.
xserver 1.8 was released in April 2010.
(Cherry picked from radeon commit 7388d0b6c54b9d536fdb161e3aa61b326627b939)
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/configure.ac b/configure.ac
index b26eebb..ff0979e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -76,7 +76,7 @@ PKG_CHECK_MODULES(LIBDRM_AMDGPU, [libdrm_amdgpu])
PKG_CHECK_MODULES(GBM, [gbm])
# Obtain compiler/linker options for the driver dependencies
-PKG_CHECK_MODULES(XORG, [xorg-server >= 1.7 xproto fontsproto xf86driproto $REQUIRED_MODULES])
+PKG_CHECK_MODULES(XORG, [xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES])
PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
HAVE_XEXTPROTO_71="yes"; AC_DEFINE(HAVE_XEXTPROTO_71, 1, [xextproto 7.1 available]),
HAVE_XEXTPROTO_71="no")
@@ -145,18 +145,11 @@ else
fi
AM_CONDITIONAL(GLAMOR, test x$GLAMOR != xno)
-AC_CHECK_HEADERS([list.h],
- [have_list_h="yes"], [have_list_h="no"],
- [#include <X11/Xdefs.h>
- #include "xorg-server.h"])
-
-if test "x$have_list_h" = xyes; then
- AC_CHECK_DECL(xorg_list_init,
- [AC_DEFINE(HAVE_XORG_LIST, 1, [Have xorg_list API])], [],
- [#include <X11/Xdefs.h>
- #include "xorg-server.h"
- #include "list.h"])
-fi
+AC_CHECK_DECL(xorg_list_init,
+ [AC_DEFINE(HAVE_XORG_LIST, 1, [Have xorg_list API])], [],
+ [#include <X11/Xdefs.h>
+ #include "xorg-server.h"
+ #include "list.h"])
AC_CHECK_DECL(GBM_BO_USE_LINEAR,
[AC_DEFINE(HAVE_GBM_BO_USE_LINEAR, 1, [Have GBM_BO_USE_LINEAR])], [],
diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index 15bb497..32f6171 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -47,7 +47,6 @@
#include "amdgpu_version.h"
-#if HAVE_LIST_H
#include "list.h"
#if !HAVE_XORG_LIST
#define xorg_list list
@@ -56,11 +55,6 @@
#define xorg_list_del list_del
#define xorg_list_for_each_entry list_for_each_entry
#endif
-#endif
-
-#if DRI2INFOREC_VERSION >= 4 && HAVE_LIST_H
-#define USE_DRI2_SCHEDULING
-#endif
#if DRI2INFOREC_VERSION >= 9
#define USE_DRI2_PRIME
@@ -373,8 +367,6 @@ amdgpu_dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
pDstBuffer, pSrcBuffer);
}
-#ifdef USE_DRI2_SCHEDULING
-
enum DRI2FrameEventType {
DRI2_SWAP,
DRI2_FLIP,
@@ -1446,17 +1438,13 @@ blit_fallback:
return TRUE;
}
-#endif /* USE_DRI2_SCHEDULING */
-
Bool amdgpu_dri2_screen_init(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
DRI2InfoRec dri2_info = { 0 };
-#ifdef USE_DRI2_SCHEDULING
const char *driverNames[2];
Bool scheduling_works = TRUE;
-#endif
if (!info->dri2.available)
return FALSE;
@@ -1471,7 +1459,6 @@ Bool amdgpu_dri2_screen_init(ScreenPtr pScreen)
dri2_info.DestroyBuffer = amdgpu_dri2_destroy_buffer;
dri2_info.CopyRegion = amdgpu_dri2_copy_region;
-#ifdef USE_DRI2_SCHEDULING
if (info->drmmode.mode_res->count_crtcs > 2) {
#ifdef DRM_CAP_VBLANK_HIGH_CRTC
uint64_t cap_value;
@@ -1532,7 +1519,6 @@ Bool amdgpu_dri2_screen_init(ScreenPtr pScreen)
DRI2InfoCnt++;
}
-#endif
#if DRI2INFOREC_VERSION >= 9
dri2_info.version = 9;
@@ -1550,11 +1536,9 @@ void amdgpu_dri2_close_screen(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
-#ifdef USE_DRI2_SCHEDULING
if (--DRI2InfoCnt == 0)
DeleteCallback(&ClientStateCallback,
amdgpu_dri2_client_state_changed, 0);
-#endif
DRI2CloseScreen(pScreen);
drmFree(info->dri2.device_name);
More information about the xorg-commit
mailing list