xf86-video-ati: Branch 'master' - 14 commits
Michel Dänzer
daenzer at kemper.freedesktop.org
Mon Mar 16 19:12:37 PDT 2015
configure.ac | 35 ++-
man/radeon.man | 4
src/Makefile.am | 7
src/drmmode_display.c | 114 ++++++++----
src/drmmode_display.h | 13 +
src/radeon.h | 52 +++++
src/radeon_accel.c | 1
src/radeon_bo_helper.c | 43 ++++
src/radeon_dri2.c | 463 ++++++++++++++++++-------------------------------
src/radeon_dri2.h | 37 ---
src/radeon_dri3.c | 201 +++++++++++++++++++++
src/radeon_drm_queue.c | 181 +++++++++++++++++++
src/radeon_drm_queue.h | 56 +++++
src/radeon_exa.c | 1
src/radeon_glamor.c | 13 -
src/radeon_glamor.h | 35 ---
src/radeon_kms.c | 47 ++++
src/radeon_list.h | 38 ++++
src/radeon_present.c | 418 ++++++++++++++++++++++++++++++++++++++++++++
src/radeon_sync.c | 144 +++++++++++++++
src/radeon_video.c | 1
21 files changed, 1475 insertions(+), 429 deletions(-)
New commits:
commit 64e1e4dbdd3caee6f5d8f6b6c094b4533fa94953
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Tue Mar 10 16:53:11 2015 +0900
Add DRI3 support v2
Must be enabled with
Option "DRI3"
in xorg.conf.
v2: Adapt to v2 of patches 11/12.
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/configure.ac b/configure.ac
index 71d8ff0..acd9fe0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -143,6 +143,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/radeon.man b/man/radeon.man
index 7dde040..6e46f89 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -267,6 +267,10 @@ The default value is
for R/RV6XX, R/RV7XX, RS780, RS880, EVERGREEN, CAYMAN, ARUBA, Southern Islands, and
Sea Islands.
.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 a3d732a..697c08c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,8 +29,9 @@
ati_drv_la_LIBADD = $(PCIACCESS_LIBS)
radeon_drv_la_LIBADD = $(LIBDRM_RADEON_LIBS) $(PCIACCESS_LIBS)
-RADEON_KMS_SRCS=radeon_dri2.c radeon_drm_queue.c radeon_kms.c radeon_present.c \
- radeon_sync.c radeon_vbo.c radeon_bo_helper.c drmmode_display.c
+RADEON_KMS_SRCS=radeon_dri2.c radeon_dri3.c radeon_drm_queue.c radeon_kms.c \
+ radeon_present.c radeon_sync.c radeon_vbo.c radeon_bo_helper.c \
+ drmmode_display.c
RADEON_EXA_SOURCES = radeon_exa.c r600_exa.c r6xx_accel.c r600_textured_videofuncs.c r600_shader.c radeon_exa_shared.c \
evergreen_exa.c evergreen_accel.c evergreen_shader.c evergreen_textured_videofuncs.c cayman_accel.c cayman_shader.c
diff --git a/src/radeon.h b/src/radeon.h
index 9346fbd..6084cfe 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -150,6 +150,7 @@ typedef enum {
OPTION_ZAPHOD_HEADS,
OPTION_SWAPBUFFERS_WAIT,
OPTION_DELETE_DP12,
+ OPTION_DRI3,
} RADEONOpts;
@@ -549,6 +550,9 @@ extern Bool RADEONGetDatatypeBpp(int bpp, uint32_t *type);
extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
uint32_t *pitch_offset);
+/* radeon_dri3.c */
+Bool radeon_dri3_screen_init(ScreenPtr screen);
+
/* radeon_present.c */
Bool radeon_present_screen_init(ScreenPtr screen);
diff --git a/src/radeon_dri3.c b/src/radeon_dri3.c
new file mode 100644
index 0000000..83bffae
--- /dev/null
+++ b/src/radeon_dri3.c
@@ -0,0 +1,201 @@
+/*
+ * 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 "xorg-server.h"
+#include "xf86.h"
+#include "fb.h"
+
+#ifdef HAVE_DRI3_H
+
+#include "radeon.h"
+#include "radeon_bo_gem.h"
+#include "radeon_glamor.h"
+#include "dri3.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+
+static int
+radeon_dri3_open_client(ClientPtr client,
+ ScreenPtr screen,
+ RRProviderPtr provider,
+ int *out)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ RADEONInfoPtr info = RADEONPTR(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 radeon_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 = fbCreatePixmap(screen, 0, 0, depth, 0);
+ if (!pixmap)
+ return NULL;
+
+ if (!screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL))
+ goto free_pixmap;
+
+ if (screen->SetSharedPixmapBacking(pixmap, (void*)(intptr_t)fd))
+ return pixmap;
+
+free_pixmap:
+ fbDestroyPixmap(pixmap);
+ return NULL;
+}
+
+static int radeon_dri3_fd_from_pixmap(ScreenPtr screen,
+ PixmapPtr pixmap,
+ CARD16 *stride,
+ CARD32 *size)
+{
+ struct radeon_bo *bo;
+ int fd;
+
+ bo = radeon_get_pixmap_bo(pixmap);
+ if (!bo) {
+#ifdef USE_GLAMOR
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ RADEONInfoPtr info = RADEONPTR(scrn);
+
+ if (info->use_glamor)
+ return glamor_fd_from_pixmap(screen, pixmap, stride, size);
+#endif
+
+ exaMoveInPixmap(pixmap);
+ bo = radeon_get_pixmap_bo(pixmap);
+ if (!bo)
+ return -1;
+ }
+
+ if (pixmap->devKind > UINT16_MAX)
+ return -1;
+
+ if (radeon_gem_prime_share_bo(bo, &fd) < 0)
+ return -1;
+
+ *stride = pixmap->devKind;
+ *size = bo->size;
+ return fd;
+}
+
+static dri3_screen_info_rec radeon_dri3_screen_info = {
+ .version = 1,
+
+ .open_client = radeon_dri3_open_client,
+ .pixmap_from_fd = radeon_dri3_pixmap_from_fd,
+ .fd_from_pixmap = radeon_dri3_fd_from_pixmap
+};
+
+Bool
+radeon_dri3_screen_init(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+
+ if (!dri3_screen_init(screen, &radeon_dri3_screen_info)) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "dri3_screen_init failed\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#else /* !HAVE_DRI3_H */
+
+Bool
+radeon_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/radeon_kms.c b/src/radeon_kms.c
index f4452bc..b32086e 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -76,6 +76,7 @@ const OptionInfoRec RADEONOptions_KMS[] = {
{ OPTION_ZAPHOD_HEADS, "ZaphodHeads", OPTV_STRING, {0}, FALSE },
{ OPTION_SWAPBUFFERS_WAIT,"SwapbuffersWait", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_DELETE_DP12, "DeleteUnusedDP12Displays", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_DRI3, "DRI3", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -1230,6 +1231,8 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
RADEONInfoPtr info = RADEONPTR(pScrn);
int subPixelOrder = SubPixelUnknown;
+ MessageType from;
+ Bool have_present = FALSE, value;
const char *s;
void *front_ptr;
@@ -1341,7 +1344,23 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
#endif
if (radeon_sync_init(pScreen))
- radeon_present_screen_init(pScreen);
+ have_present = radeon_present_screen_init(pScreen);
+
+ if (xf86GetOptValBool(info->Options, OPTION_DRI3, &value))
+ from = X_CONFIG;
+ else
+ from = X_DEFAULT;
+
+ if (value) {
+ if (have_present)
+ value = radeon_dri3_screen_init(pScreen);
+ else
+ value = FALSE;
+
+ if (!value)
+ from = X_WARNING;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "DRI3 %sabled\n", value ? "en" : "dis");
pScrn->vtSema = TRUE;
xf86SetBackingStore(pScreen);
commit 69ae0194778fe4276895839db92383f63f0b5de4
Author: David Heidelberger <david.heidelberger at ixit.cz>
Date: Fri Mar 6 17:57:22 2015 +0900
Handle tiling in radeon_set_shared_pixmap_backing
[ Michel Dänzer: Fixups for glamor ]
Signed-off-by: David Heidelberger <david.heidelberger at ixit.cz>
Signed-off-by: Axel Davy <axel.davy at ens.fr>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/radeon_bo_helper.c b/src/radeon_bo_helper.c
index ed964d7..c3a2d63 100644
--- a/src/radeon_bo_helper.c
+++ b/src/radeon_bo_helper.c
@@ -200,6 +200,21 @@ Bool radeon_share_pixmap_backing(struct radeon_bo *bo, void **handle_p)
return TRUE;
}
+static unsigned eg_tile_split_opp(unsigned tile_split)
+{
+ switch (tile_split) {
+ case 0: tile_split = 64; break;
+ case 1: tile_split = 128; break;
+ case 2: tile_split = 256; break;
+ case 3: tile_split = 512; break;
+ default:
+ case 4: tile_split = 1024; break;
+ case 5: tile_split = 2048; break;
+ case 6: tile_split = 4096; break;
+ }
+ return tile_split;
+}
+
Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle,
struct radeon_surface *surface)
{
@@ -215,7 +230,22 @@ Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle,
memset(surface, 0, sizeof(struct radeon_surface));
+ radeon_set_pixmap_bo(ppix, bo);
+
if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) {
+ uint32_t tiling_flags;
+
+#ifdef USE_GLAMOR
+ if (info->use_glamor) {
+ tiling_flags = radeon_get_pixmap_private(ppix)->tiling_flags;
+ } else
+#endif
+ {
+ struct radeon_exa_pixmap_priv *driver_priv;
+
+ driver_priv = exaGetPixmapDriverPrivate(ppix);
+ tiling_flags = driver_priv->tiling_flags;
+ }
surface->npix_x = ppix->drawable.width;
surface->npix_y = ppix->drawable.height;
@@ -229,7 +259,17 @@ Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle,
/* we are requiring a recent enough libdrm version */
surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
- surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
+ if (tiling_flags & RADEON_TILING_MACRO)
+ surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
+ else if (tiling_flags & RADEON_TILING_MICRO)
+ surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
+ else
+ surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
+ surface->bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK;
+ surface->bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK;
+ surface->tile_split = eg_tile_split_opp((tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK);
+ surface->stencil_tile_split = (tiling_flags >> RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK;
+ surface->mtilea = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
if (radeon_surface_best(info->surf_man, surface)) {
return FALSE;
}
@@ -241,7 +281,6 @@ Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle,
surface->level[0].pitch_bytes = ppix->devKind;
surface->level[0].nblk_x = ppix->devKind / surface->bpe;
}
- radeon_set_pixmap_bo(ppix, bo);
close(ihandle);
/* we have a reference from the alloc and one from set pixmap bo,
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index 0d6cd24..1e457a8 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -330,7 +330,6 @@ Bool RADEONEXASetSharedPixmapBacking(PixmapPtr ppix, void *fd_handle)
return FALSE;
driver_priv->shared = TRUE;
- driver_priv->tiling_flags = 0;
return TRUE;
}
#endif
diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c
index f0996fe..c49c7f6 100644
--- a/src/radeon_glamor.c
+++ b/src/radeon_glamor.c
@@ -303,7 +303,6 @@ radeon_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void *handle)
priv = radeon_get_pixmap_private(pixmap);
priv->stride = pixmap->devKind;
priv->surface = surface;
- priv->tiling_flags = 0;
if (!radeon_glamor_create_textured_pixmap(pixmap)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
commit 3c65fb849e1ba9fb6454bcaa55b696548902f3fc
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Tue Mar 10 16:52:54 2015 +0900
Add support for the Present extension v2
v2: Fix up for struct radeon_drm_queue -> radeon_drm_queue_entry.
Swapped order of patches 11 & 12 because the Present extension uses
SYNC fences.
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/configure.ac b/configure.ac
index c2e5a20..71d8ff0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -137,6 +137,12 @@ AC_CHECK_HEADERS([misyncshm.h], [], [],
#include "screenint.h"
#include "xorg-server.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 acb83f1..a3d732a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,8 +29,8 @@
ati_drv_la_LIBADD = $(PCIACCESS_LIBS)
radeon_drv_la_LIBADD = $(LIBDRM_RADEON_LIBS) $(PCIACCESS_LIBS)
-RADEON_KMS_SRCS=radeon_dri2.c radeon_drm_queue.c radeon_kms.c radeon_sync.c \
- radeon_vbo.c radeon_bo_helper.c drmmode_display.c
+RADEON_KMS_SRCS=radeon_dri2.c radeon_drm_queue.c radeon_kms.c radeon_present.c \
+ radeon_sync.c radeon_vbo.c radeon_bo_helper.c drmmode_display.c
RADEON_EXA_SOURCES = radeon_exa.c r600_exa.c r6xx_accel.c r600_textured_videofuncs.c r600_shader.c radeon_exa_shared.c \
evergreen_exa.c evergreen_accel.c evergreen_shader.c evergreen_textured_videofuncs.c cayman_accel.c cayman_shader.c
diff --git a/src/radeon.h b/src/radeon.h
index cc52bd9..9346fbd 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -549,6 +549,9 @@ extern Bool RADEONGetDatatypeBpp(int bpp, uint32_t *type);
extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
uint32_t *pitch_offset);
+/* radeon_present.c */
+Bool radeon_present_screen_init(ScreenPtr screen);
+
/* radeon_sync.c */
extern Bool radeon_sync_init(ScreenPtr screen);
extern void radeon_sync_close(ScreenPtr screen);
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 521f3b9..f4452bc 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -1340,7 +1340,8 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
}
#endif
- radeon_sync_init(pScreen);
+ if (radeon_sync_init(pScreen))
+ radeon_present_screen_init(pScreen);
pScrn->vtSema = TRUE;
xf86SetBackingStore(pScreen);
diff --git a/src/radeon_present.c b/src/radeon_present.c
new file mode 100644
index 0000000..d884548
--- /dev/null
+++ b/src/radeon_present.c
@@ -0,0 +1,418 @@
+/*
+ * 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 <xorg-server.h>
+#include <xf86.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 "xf86_OSproc.h"
+
+#include "xf86Pci.h"
+#include "xf86drm.h"
+
+#include "windowstr.h"
+#include "shadow.h"
+#include "fb.h"
+
+#include "radeon.h"
+#include "radeon_video.h"
+
+#include "present.h"
+
+struct radeon_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
+radeon_present_get_crtc(WindowPtr window)
+{
+ ScreenPtr screen = window->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
+ xf86CrtcPtr crtc;
+ RRCrtcPtr randr_crtc = NULL;
+
+ crtc = radeon_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
+radeon_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
+radeon_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
+radeon_present_vblank_handler(ScrnInfoPtr scrn, unsigned int msc,
+ uint64_t usec, void *data)
+{
+ struct radeon_present_vblank_event *event = data;
+
+ present_event_notify(event->event_id, usec, msc);
+ free(event);
+}
+
+/*
+ * Called when the queued vblank is aborted
+ */
+static void
+radeon_present_vblank_abort(ScrnInfoPtr scrn, void *data)
+{
+ struct radeon_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
+radeon_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);
+ RADEONInfoPtr info = RADEONPTR(scrn);
+ int crtc_id = drmmode_get_crtc_id(xf86_crtc);
+ struct radeon_present_vblank_event *event;
+ struct radeon_drm_queue_entry *queue;
+ drmVBlank vbl;
+ int ret;
+
+ event = calloc(sizeof(struct radeon_present_vblank_event), 1);
+ if (!event)
+ return BadAlloc;
+ event->event_id = event_id;
+ queue = radeon_drm_queue_alloc(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT,
+ event_id, event,
+ radeon_present_vblank_handler,
+ radeon_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 || !radeon_present_flush_drm_events(screen)) {
+ radeon_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
+radeon_present_abort_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
+{
+ radeon_drm_abort_id(event_id);
+}
+
+/*
+ * Flush our batch buffer when requested by the Present extension.
+ */
+static void
+radeon_present_flush(WindowPtr window)
+{
+ radeon_cs_flush_indirect(xf86ScreenToScrn(window->drawable.pScreen));
+}
+
+static drmmode_crtc_private_ptr
+get_drmmode_crtc(ScrnInfoPtr scrn, RRCrtcPtr crtc)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int i;
+
+ for (i = 0; i < config->num_crtc; i++) {
+ xf86CrtcPtr xf86crtc = config->crtc[i];
+
+ if (xf86crtc->randr_crtc == crtc)
+ return xf86crtc->driver_private;
+ }
+
+ return NULL;
+}
+
+/*
+ * Test to see if page flipping is possible on the target crtc
+ */
+static Bool
+radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,
+ Bool sync_flip)
+{
+ ScreenPtr screen = window->drawable.pScreen;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ RADEONInfoPtr info = RADEONPTR(scrn);
+
+ if (!scrn->vtSema)
+ return FALSE;
+
+ if (!info->allowPageFlip)
+ return FALSE;
+
+ if (crtc) {
+ drmmode_crtc_private_ptr drmmode_crtc = get_drmmode_crtc(scrn, crtc);
+
+ if (!drmmode_crtc ||
+ drmmode_crtc->rotate_bo != 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
+radeon_present_flip_event(ScrnInfoPtr scrn, uint32_t msc, uint64_t ust, void *pageflip_data)
+{
+ struct radeon_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
+radeon_present_flip_abort(ScrnInfoPtr scrn, void *pageflip_data)
+{
+ struct radeon_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
+radeon_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 radeon_present_vblank_event *event;
+ drmmode_crtc_private_ptr drmmode_crtc = get_drmmode_crtc(scrn, crtc);
+ int crtc_id = drmmode_crtc->mode_crtc->crtc_id;
+ struct radeon_bo *bo;
+ Bool ret;
+
+ if (!sync_flip)
+ return FALSE;
+
+ if (!radeon_present_check_flip(crtc, screen->root, pixmap, sync_flip))
+ return FALSE;
+
+ bo = radeon_get_pixmap_bo(pixmap);
+ if (!bo)
+ return FALSE;
+
+ event = calloc(1, sizeof(struct radeon_present_vblank_event));
+ if (!event)
+ return FALSE;
+
+ event->event_id = event_id;
+
+ ret = radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, bo,
+ event_id, event, crtc_id,
+ radeon_present_flip_event,
+ radeon_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
+radeon_present_unflip(ScreenPtr screen, uint64_t event_id)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ struct radeon_present_vblank_event *event;
+ PixmapPtr pixmap = screen->GetScreenPixmap(screen);
+ struct radeon_bo *bo;
+ Bool ret;
+
+ if (!radeon_present_check_flip(NULL, screen->root, pixmap, TRUE))
+ return;
+
+ bo = radeon_get_pixmap_bo(pixmap);
+ if (!bo)
+ return;
+
+ event = calloc(1, sizeof(struct radeon_present_vblank_event));
+ if (!event)
+ return;
+
+ event->event_id = event_id;
+
+ ret = radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, bo,
+ event_id, event, -1, radeon_present_flip_event,
+ radeon_present_flip_abort);
+ if (!ret)
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present unflip failed\n");
+}
+
+static present_screen_info_rec radeon_present_screen_info = {
+ .version = 0,
+
+ .get_crtc = radeon_present_get_crtc,
+ .get_ust_msc = radeon_present_get_ust_msc,
+ .queue_vblank = radeon_present_queue_vblank,
+ .abort_vblank = radeon_present_abort_vblank,
+ .flush = radeon_present_flush,
+
+ .capabilities = PresentCapabilityNone,
+ .check_flip = radeon_present_check_flip,
+ .flip = radeon_present_flip,
+ .unflip = radeon_present_unflip,
+};
+
+static Bool
+radeon_present_has_async_flip(ScreenPtr screen)
+{
+#ifdef DRM_CAP_ASYNC_PAGE_FLIP
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ RADEONInfoPtr info = RADEONPTR(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
+radeon_present_screen_init(ScreenPtr screen)
+{
+ if (radeon_present_has_async_flip(screen))
+ radeon_present_screen_info.capabilities |= PresentCapabilityAsync;
+
+ if (!present_screen_init(screen, &radeon_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
+radeon_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 8fc9a241ab59ffbcdc178d6415332c88a54e85fe
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Thu Mar 5 18:18:56 2015 +0900
Add support for SYNC extension fences v2
v2: Swapped order of patches 11 & 12 because the Present extension uses
SYNC fences.
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/configure.ac b/configure.ac
index 891da03..c2e5a20 100644
--- a/configure.ac
+++ b/configure.ac
@@ -131,6 +131,12 @@ AC_CHECK_DECL(xorg_list_init,
#include "xorg-server.h"
#include "list.h"])
+AC_CHECK_HEADERS([misyncshm.h], [], [],
+ [#include <X11/Xdefs.h>
+ #include <X11/Xfuncproto.h>
+ #include "screenint.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 9cc8a2d..acb83f1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,8 +29,8 @@
ati_drv_la_LIBADD = $(PCIACCESS_LIBS)
radeon_drv_la_LIBADD = $(LIBDRM_RADEON_LIBS) $(PCIACCESS_LIBS)
-RADEON_KMS_SRCS=radeon_dri2.c radeon_drm_queue.c radeon_kms.c drmmode_display.c \
- radeon_vbo.c radeon_bo_helper.c
+RADEON_KMS_SRCS=radeon_dri2.c radeon_drm_queue.c radeon_kms.c radeon_sync.c \
+ radeon_vbo.c radeon_bo_helper.c drmmode_display.c
RADEON_EXA_SOURCES = radeon_exa.c r600_exa.c r6xx_accel.c r600_textured_videofuncs.c r600_shader.c radeon_exa_shared.c \
evergreen_exa.c evergreen_accel.c evergreen_shader.c evergreen_textured_videofuncs.c cayman_accel.c cayman_shader.c
diff --git a/src/radeon.h b/src/radeon.h
index e503cbb..cc52bd9 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -90,6 +90,8 @@
#include "simple_list.h"
#include "atipcirename.h"
+typedef struct _SyncFence SyncFence;
+
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
@@ -445,6 +447,9 @@ typedef struct {
void (*BlockHandler)(BLOCKHANDLER_ARGS_DECL);
+ void (*CreateFence) (ScreenPtr pScreen, SyncFence *pFence,
+ Bool initially_triggered);
+
int pix24bpp; /* Depth of pixmap for 24bpp fb */
Bool dac6bits; /* Use 6 bit DAC? */
@@ -544,6 +549,10 @@ extern Bool RADEONGetDatatypeBpp(int bpp, uint32_t *type);
extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
uint32_t *pitch_offset);
+/* radeon_sync.c */
+extern Bool radeon_sync_init(ScreenPtr screen);
+extern void radeon_sync_close(ScreenPtr screen);
+
/* radeon_video.c */
extern void RADEONInitVideo(ScreenPtr pScreen);
extern void RADEONResetVideo(ScrnInfoPtr pScrn);
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index d25d7f5..521f3b9 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -1192,6 +1192,8 @@ static Bool RADEONCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL)
info->accel_state->exa = NULL;
}
+ radeon_sync_close(pScreen);
+
if (info->accel_state->use_vbos)
radeon_vbo_free_lists(pScrn);
@@ -1338,6 +1340,8 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
}
#endif
+ radeon_sync_init(pScreen);
+
pScrn->vtSema = TRUE;
xf86SetBackingStore(pScreen);
diff --git a/src/radeon_sync.c b/src/radeon_sync.c
new file mode 100644
index 0000000..d8ab5bc
--- /dev/null
+++ b/src/radeon_sync.c
@@ -0,0 +1,144 @@
+/*
+ * 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 "radeon.h"
+
+#ifdef HAVE_MISYNCSHM_H
+
+#include "misyncshm.h"
+#include "misyncstr.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 radeon_sync_fence_private_key;
+
+typedef struct _radeon_sync_fence_private {
+ SyncFenceSetTriggeredFunc set_triggered;
+} radeon_sync_fence_private;
+
+#define SYNC_FENCE_PRIV(pFence) \
+ (radeon_sync_fence_private *) dixLookupPrivate(&pFence->devPrivates, &radeon_sync_fence_private_key)
+
+static void
+radeon_sync_fence_set_triggered (SyncFence *fence)
+{
+ ScreenPtr screen = fence->pScreen;
+ radeon_sync_fence_private *private = SYNC_FENCE_PRIV(fence);
+
+ /* Flush pending rendering operations */
+ radeon_cs_flush_indirect(xf86ScreenToScrn(screen));
+
+ fence->funcs.SetTriggered = private->set_triggered;
+ fence->funcs.SetTriggered(fence);
+ private->set_triggered = fence->funcs.SetTriggered;
+ fence->funcs.SetTriggered = radeon_sync_fence_set_triggered;
+}
+
+static void
+radeon_sync_create_fence(ScreenPtr screen,
+ SyncFence *fence,
+ Bool initially_triggered)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ RADEONInfoPtr info = RADEONPTR(scrn);
+ SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
+ radeon_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 = radeon_sync_create_fence;
+
+ private->set_triggered = fence->funcs.SetTriggered;
+ fence->funcs.SetTriggered = radeon_sync_fence_set_triggered;
+}
+
+Bool
+radeon_sync_init(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ RADEONInfoPtr info = RADEONPTR(scrn);
+ SyncScreenFuncsPtr screen_funcs;
+
+ if (!miSyncShmScreenInit(screen)) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "SYNC extension fences disabled because "
+ "miSyncShmScreenInit failed\n");
+ return FALSE;
+ }
+
+ if (!dixPrivateKeyRegistered(&radeon_sync_fence_private_key)) {
+ if (!dixRegisterPrivateKey(&radeon_sync_fence_private_key,
+ PRIVATE_SYNC_FENCE,
+ sizeof (radeon_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 = radeon_sync_create_fence;
+ return TRUE;
+}
+
+void
+radeon_sync_close(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ RADEONInfoPtr info = RADEONPTR(scrn);
+ SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
+
+ if (screen_funcs && info->CreateFence)
+ screen_funcs->CreateFence = info->CreateFence;
+
+ info->CreateFence = NULL;
+}
+
+#else /* !HAVE_MISYNCSHM_H */
+
+Bool
+radeon_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
+radeon_sync_close(ScreenPtr screen)
+{
+}
+
+#endif
commit 4a35e2f33d9cdfb608423046391311109f96fb6b
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Thu Mar 5 18:34:07 2015 +0900
Fold radeon_glamor_flush into radeon_cs_flush_indirect
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c
index 950f891..f0996fe 100644
--- a/src/radeon_glamor.c
+++ b/src/radeon_glamor.c
@@ -363,15 +363,6 @@ radeon_glamor_init(ScreenPtr screen)
return TRUE;
}
-void
-radeon_glamor_flush(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- if (info->use_glamor)
- glamor_block_handler(pScrn->pScreen);
-}
-
XF86VideoAdaptorPtr radeon_glamor_xv_init(ScreenPtr pScreen, int num_adapt)
{
return glamor_xv_init(pScreen, num_adapt);
diff --git a/src/radeon_glamor.h b/src/radeon_glamor.h
index 548ea98..c402a10 100644
--- a/src/radeon_glamor.h
+++ b/src/radeon_glamor.h
@@ -40,8 +40,6 @@ Bool radeon_glamor_init(ScreenPtr screen);
Bool radeon_glamor_create_screen_resources(ScreenPtr screen);
void radeon_glamor_free_screen(int scrnIndex, int flags);
-void radeon_glamor_flush(ScrnInfoPtr pScrn);
-
Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap);
void radeon_glamor_exchange_buffers(PixmapPtr src, PixmapPtr dst);
@@ -56,8 +54,6 @@ static inline Bool radeon_glamor_init(ScreenPtr screen) { return FALSE; }
static inline Bool radeon_glamor_create_screen_resources(ScreenPtr screen) { return FALSE; }
static inline void radeon_glamor_free_screen(int scrnIndex, int flags) { }
-static inline void radeon_glamor_flush(ScrnInfoPtr pScrn) { }
-
static inline Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap) { return TRUE; }
static inline void radeon_glamor_exchange_buffers(PixmapPtr src, PixmapPtr dst) {}
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 23c0694..d25d7f5 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -84,12 +84,21 @@ const OptionInfoRec *RADEONOptionsWeak(void) { return RADEONOptions_KMS; }
void radeon_cs_flush_indirect(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- struct radeon_accel_state *accel_state = info->accel_state;
+ struct radeon_accel_state *accel_state;
int ret;
+#ifdef USE_GLAMOR
+ if (info->use_glamor) {
+ glamor_block_handler(pScrn->pScreen);
+ return;
+ }
+#endif
+
if (!info->cs->cdw)
return;
+ accel_state = info->accel_state;
+
/* release the current VBO so we don't block on mapping it later */
if (info->accel_state->vbo.vb_offset && info->accel_state->vbo.vb_bo) {
radeon_vbo_put(pScrn, &info->accel_state->vbo);
@@ -307,9 +316,6 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
(*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
pScreen->BlockHandler = RADEONBlockHandler_KMS;
- if (info->use_glamor)
- radeon_glamor_flush(pScrn);
-
radeon_cs_flush_indirect(pScrn);
#ifdef RADEON_PIXMAP_SHARING
radeon_dirty_update(pScreen);
@@ -322,10 +328,8 @@ radeon_flush_callback(CallbackListPtr *list,
{
ScrnInfoPtr pScrn = user_data;
- if (pScrn->vtSema) {
+ if (pScrn->vtSema)
radeon_cs_flush_indirect(pScrn);
- radeon_glamor_flush(pScrn);
- }
}
static Bool RADEONIsFastFBWorking(ScrnInfoPtr pScrn)
commit 4b8adebb80158bcf81ada83bb88517febe931b12
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Thu Mar 5 18:40:23 2015 +0900
Move #include "radeon_glamor.h" from radeon.h to where it's needed
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index bb3d989..86bc446 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -36,6 +36,7 @@
#include "micmap.h"
#include "xf86cmap.h"
#include "radeon.h"
+#include "radeon_glamor.h"
#include "radeon_reg.h"
#include "drmmode_display.h"
diff --git a/src/radeon.h b/src/radeon.h
index 88a0bd5..e503cbb 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -51,8 +51,6 @@
#include "exa.h"
-#include "radeon_glamor.h"
-
/* Exa and Cursor Support */
#include "xf86Cursor.h"
@@ -242,6 +240,40 @@ typedef enum {
#define CURSOR_WIDTH_CIK 128
#define CURSOR_HEIGHT_CIK 128
+
+#ifdef USE_GLAMOR
+
+struct radeon_pixmap {
+ struct radeon_surface surface;
+ struct radeon_bo *bo;
+
+ uint32_t tiling_flags;
+ int stride;
+};
+
+#if HAS_DEVPRIVATEKEYREC
+extern DevPrivateKeyRec glamor_pixmap_index;
+#else
+extern int glamor_pixmap_index;
+#endif
+
+static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap)
+{
+#if HAS_DEVPRIVATEKEYREC
+ return dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
+#else
+ return dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
+#endif
+}
+
+static inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct radeon_pixmap *priv)
+{
+ dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_index, priv);
+}
+
+#endif /* USE_GLAMOR */
+
+
struct radeon_exa_pixmap_priv {
struct radeon_bo *bo;
uint32_t tiling_flags;
diff --git a/src/radeon_accel.c b/src/radeon_accel.c
index 8eff5c5..1def2a3 100644
--- a/src/radeon_accel.c
+++ b/src/radeon_accel.c
@@ -78,6 +78,7 @@
#include <assert.h>
/* Driver data structures */
#include "radeon.h"
+#include "radeon_glamor.h"
#include "radeon_reg.h"
#include "r600_reg.h"
#include "radeon_probe.h"
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 0577d8f..02e8e8f 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -53,9 +53,7 @@
#define FALLBACK_SWAP_DELAY 16
-#ifdef USE_GLAMOR
-#include <glamor.h>
-#endif
+#include "radeon_glamor.h"
typedef DRI2BufferPtr BufferPtr;
diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c
index 210ddcf..950f891 100644
--- a/src/radeon_glamor.c
+++ b/src/radeon_glamor.c
@@ -29,11 +29,10 @@
#endif
#include <xf86.h>
-#define GLAMOR_FOR_XORG 1
-#include <glamor.h>
#include "radeon.h"
#include "radeon_bo_helper.h"
+#include "radeon_glamor.h"
#if HAS_DEVPRIVATEKEYREC
DevPrivateKeyRec glamor_pixmap_index;
diff --git a/src/radeon_glamor.h b/src/radeon_glamor.h
index 36addd7..548ea98 100644
--- a/src/radeon_glamor.h
+++ b/src/radeon_glamor.h
@@ -30,6 +30,9 @@
#include "xf86xv.h"
#ifdef USE_GLAMOR
+#define GLAMOR_FOR_XORG 1
+#include <glamor.h>
+
#include "radeon_surface.h"
Bool radeon_glamor_pre_init(ScrnInfoPtr scrn);
@@ -46,34 +49,6 @@ Bool radeon_glamor_pixmap_is_offscreen(PixmapPtr pixmap);
XF86VideoAdaptorPtr radeon_glamor_xv_init(ScreenPtr pScreen, int num_adapt);
-struct radeon_pixmap {
- struct radeon_surface surface;
- struct radeon_bo *bo;
-
- uint32_t tiling_flags;
- int stride;
-};
-
-#if HAS_DEVPRIVATEKEYREC
-extern DevPrivateKeyRec glamor_pixmap_index;
-#else
-extern int glamor_pixmap_index;
-#endif
-
-static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap)
-{
-#if HAS_DEVPRIVATEKEYREC
- return dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
-#else
- return dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
-#endif
-}
-
-static inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct radeon_pixmap *priv)
-{
- dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_index, priv);
-}
-
#else
static inline Bool radeon_glamor_pre_init(ScrnInfoPtr scrn) { return FALSE; }
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index ced3594..23c0694 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -33,6 +33,7 @@
/* Driver data structures */
#include "radeon.h"
#include "radeon_drm_queue.h"
+#include "radeon_glamor.h"
#include "radeon_reg.h"
#include "radeon_probe.h"
#include "micmap.h"
diff --git a/src/radeon_video.c b/src/radeon_video.c
index cbfd554..f66ba55 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -9,6 +9,7 @@
#include <math.h>
#include "radeon.h"
+#include "radeon_glamor.h"
#include "radeon_reg.h"
#include "radeon_probe.h"
#include "radeon_video.h"
commit 76c2923ac5c7230a8b2f9f8329c308d28b44d9c0
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Wed Mar 4 10:30:19 2015 +0900
DRI2: Split out helper for getting UST and MSC of a specific CRTC
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 5ea2344..bb3d989 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -245,6 +245,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;
+ RADEONInfoPtr info = RADEONPTR(scrn);
+ drmVBlank vbl;
+ int ret;
+
+ vbl.request.type = DRM_VBLANK_RELATIVE;
+ vbl.request.type |= radeon_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_do_crtc_dpms(xf86CrtcPtr crtc, int mode)
{
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index b313460..6f883c0 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -132,6 +132,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
struct radeon_bo *new_front, uint64_t id, void *data,
int ref_crtc_hw_id, radeon_drm_handler_proc handler,
radeon_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
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 5134154..0577d8f 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -952,17 +952,13 @@ CARD32 radeon_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 radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
{
- ScreenPtr screen = draw->pScreen;
- ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
- RADEONInfoPtr info = RADEONPTR(scrn);
- drmVBlank vbl;
- int ret;
xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE);
+ int ret;
/* Drawable not displayed, make up a value */
if (crtc == NULL) {
@@ -970,25 +966,20 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
*msc = 0;
return TRUE;
}
+
if (radeon_crtc_is_enabled(crtc)) {
/* CRTC is running, read vblank counter and timestamp */
- vbl.request.type = DRM_VBLANK_RELATIVE;
- vbl.request.type |= radeon_populate_vbl_request_type(crtc);
- vbl.request.sequence = 0;
+ ret = drmmode_crtc_get_ust_msc(crtc, ust, msc);
- ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
- if (ret) {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "get vblank counter failed: %s\n", strerror(errno));
- return FALSE;
+ if (ret != Success) {
+ *msc += radeon_get_interpolated_vblanks(crtc);
+ *msc &= 0xffffffff;
}
-
- *ust = ((CARD64)vbl.reply.tval_sec * 1000000) + vbl.reply.tval_usec;
- *msc = vbl.reply.sequence + radeon_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;
+ RADEONInfoPtr info = RADEONPTR(scrn);
CARD64 now, delta_t, delta_seq;
if (!drmmode_crtc->dpms_last_ust)
@@ -1011,7 +1002,8 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
*msc += delta_seq;
*msc &= 0xffffffff;
}
- return TRUE;
+
+ return ret == Success;
}
static
commit 6c3a721cde9317233072b573f9502348dcd21b16
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Tue Mar 10 16:52:18 2015 +0900
DRI2: Use helper functions for DRM event queue management v3
This is mostly in preparation for Present support, but it also simplifies
the DRI2 specific code a little.
v2: Fix up for struct radeon_drm_queue -> radeon_drm_queue_entry.
v3: Removed excess 0s from conversion from microseconds to seconds,
thanks to Richard Wilbur <richard.wilbur at gmail.com> for the catch!
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index cebd206..5ea2344 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1799,45 +1799,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)
{
- radeon_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_handler(int fd, unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data)
+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(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 */
- radeon_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);
}
@@ -1884,8 +1891,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 = radeon_drm_queue_handler;
+ drmmode->event_context.page_flip_handler = radeon_drm_queue_handler;
drmModeFreeResources(mode_res);
return TRUE;
@@ -2229,7 +2236,10 @@ void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode)
#endif
}
-Bool radeon_do_pageflip(ScrnInfoPtr scrn, struct radeon_bo *new_front, void *data, int ref_crtc_hw_id)
+Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
+ struct radeon_bo *new_front, uint64_t id, void *data,
+ int ref_crtc_hw_id, radeon_drm_handler_proc handler,
+ radeon_drm_abort_proc abort)
{
RADEONInfoPtr info = RADEONPTR(scrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -2240,7 +2250,8 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, struct radeon_bo *new_front, void *dat
uint32_t tiling_flags = 0;
int height, emitted = 0;
drmmode_flipdata_ptr flipdata;
- drmmode_flipevtcarrier_ptr flipcarrier;
+ drmmode_flipevtcarrier_ptr flipcarrier = NULL;
+ struct radeon_drm_queue_entry *drm_queue = 0;
if (info->allowColorTiling) {
if (info->ChipFamily >= CHIP_FAMILY_R600)
@@ -2305,9 +2316,22 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, struct radeon_bo *new_front, void *dat
*/
flipcarrier->dispatch_me = (drmmode_crtc->hw_id == ref_crtc_hw_id);
flipcarrier->flipdata = flipdata;
+ flipcarrier->handler = handler;
+ flipcarrier->abort = abort;
+
+ drm_queue = radeon_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)) {
+ drmmode->fb_id, DRM_MODE_PAGE_FLIP_EVENT,
+ drm_queue)) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"flip queue failed: %s\n", strerror(errno));
free(flipcarrier);
@@ -2322,6 +2346,11 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, struct radeon_bo *new_front, void *dat
return TRUE;
error_undo:
+ if (drm_queue)
+ radeon_drm_abort_entry(drm_queue);
+ else
+ drmmode_flip_abort(scrn, flipcarrier);
+
drmModeRmFB(drmmode->fd, drmmode->fb_id);
drmmode->fb_id = old_fb_id;
@@ -2330,4 +2359,3 @@ error_out:
strerror(errno));
return FALSE;
}
-
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index c9920e0..b313460 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -32,6 +32,7 @@
#include "libudev.h"
#endif
+#include "radeon_drm_queue.h"
#include "radeon_probe.h"
#ifndef DRM_CAP_TIMESTAMP_MONOTONIC
@@ -61,13 +62,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;
+ radeon_drm_handler_proc handler;
+ radeon_drm_abort_proc abort;
} drmmode_flipevtcarrier_rec, *drmmode_flipevtcarrier_ptr;
typedef struct {
@@ -121,11 +123,15 @@ 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_height_align(ScrnInfoPtr scrn, uint32_t tiling);
extern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
extern int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
-Bool radeon_do_pageflip(ScrnInfoPtr scrn, struct radeon_bo *new_front, void *data, int ref_crtc_hw_id);
+Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
+ struct radeon_bo *new_front, uint64_t id, void *data,
+ int ref_crtc_hw_id, radeon_drm_handler_proc handler,
+ radeon_drm_abort_proc abort);
int drmmode_get_current_ust(int drm_fd, CARD64 *ust);
#endif
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index a3f0776..5134154 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -45,6 +45,8 @@
#include "radeon_bo_gem.h"
+#include <xf86Priv.h>
+
#if DRI2INFOREC_VERSION >= 9
#define USE_DRI2_PRIME
#endif
@@ -485,67 +487,20 @@ typedef struct _DRI2FrameEvent {
XID drawable_id;
ClientPtr client;
enum DRI2FrameEventType type;
- int frame;
+ unsigned frame;
xf86CrtcPtr crtc;
+ OsTimerPtr timer;
+ struct radeon_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
radeon_dri2_ref_buffer(BufferPtr buffer)
{
@@ -565,28 +520,13 @@ radeon_dri2_unref_buffer(BufferPtr buffer)
static void
radeon_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;
- radeon_dri2_unref_buffer(ref->front);
- radeon_dri2_unref_buffer(ref->back);
- }
- }
+ radeon_drm_abort_client(pClient);
break;
default:
break;
@@ -613,36 +553,41 @@ xf86CrtcPtr radeon_dri2_drawable_crtc(DrawablePtr pDraw, Bool consider_disabled)
return NULL;
}
-void radeon_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data)
+static void
+radeon_dri2_flip_event_abort(ScrnInfoPtr scrn, void *event_data)
+{
+ free(event_data);
+}
+
+static void
+radeon_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 += radeon_get_interpolated_vblanks(flip->crtc);
+ if (status != Success)
+ goto abort;
- screen = drawable->pScreen;
- scrn = xf86ScreenToScrn(screen);
+ if (!flip->crtc)
+ goto abort;
+ frame += radeon_get_interpolated_vblanks(flip->crtc);
+ screen = scrn->pScreen;
pixmap = screen->GetScreenPixmap(screen);
xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, RADEON_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:
@@ -652,8 +597,8 @@ void radeon_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",
- __func__, frame, flip->frame);
+ "%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;
}
@@ -668,7 +613,8 @@ void radeon_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
break;
}
- free(flip);
+abort:
+ radeon_dri2_flip_event_abort(scrn, event_data);
}
static Bool
@@ -703,7 +649,10 @@ radeon_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr client,
back_priv = back->driverPrivate;
bo = radeon_get_pixmap_bo(back_priv->pixmap);
- return radeon_do_pageflip(scrn, bo, flip_info, ref_crtc_hw_id);
+ return radeon_do_pageflip(scrn, client, bo, RADEON_DRM_QUEUE_ID_DEFAULT,
+ flip_info, ref_crtc_hw_id,
+ radeon_dri2_flip_event_handler,
+ radeon_dri2_flip_event_abort);
}
static Bool
@@ -825,31 +774,36 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt
DamageRegionProcessPending(&front_priv->pixmap->drawable);
}
-void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data)
+static void radeon_dri2_frame_event_abort(ScrnInfoPtr scrn, void *event_data)
+{
+ DRI2FrameEventPtr event = event_data;
+
+ TimerCancel(event->timer);
+ TimerFree(event->timer);
+ radeon_dri2_unref_buffer(event->front);
+ radeon_dri2_unref_buffer(event->back);
+ free(event);
+}
+
+static void radeon_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 += radeon_get_interpolated_vblanks(event->crtc);
- screen = drawable->pScreen;
- scrn = xf86ScreenToScrn(screen);
+ seq += radeon_get_interpolated_vblanks(event->crtc);
switch (event->type) {
case DRI2_FLIP:
@@ -881,12 +835,14 @@ void radeon_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, event->event_data);
+ 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 */
@@ -896,12 +852,7 @@ void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
}
cleanup:
- if (event->valid) {
- radeon_dri2_unref_buffer(event->front);
- radeon_dri2_unref_buffer(event->back);
- ListDelDRI2ClientEvents(event->client, &event->link);
- }
- free(event);
+ radeon_dri2_frame_event_abort(scrn, event_data);
}
drmVBlankSeqType radeon_populate_vbl_request_type(xf86CrtcPtr crtc)
@@ -1067,17 +1018,13 @@ static
CARD32 radeon_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;
RADEONInfoPtr 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
@@ -1088,28 +1035,26 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
*/
if (!event_info->crtc) {
ErrorF("%s no crtc\n", __func__);
- radeon_dri2_frame_event_handler(0, 0, 0, data);
- return 0;
- }
- status = dixLookupDrawable(&drawable, event_info->drawable_id, serverClient,
- M_ANY, DixWriteAccess);
- if (status != Success) {
- ErrorF("%s cannot lookup drawable\n", __func__);
- radeon_dri2_frame_event_handler(0, 0, 0, data);
+ if (event_info->drm_queue)
+ radeon_drm_abort_entry(event_info->drm_queue);
+ else
+ radeon_dri2_frame_event_abort(NULL, data);
return 0;
}
- screen = drawable->pScreen;
- scrn = xf86ScreenToScrn(screen);
+
+ scrn = crtc->scrn;
info = RADEONPTR(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__);
- radeon_dri2_frame_event_handler(0, 0, 0, data);
+ if (event_info->drm_queue)
+ radeon_drm_queue_handler(info->dri2.drm_fd, 0, 0, 0,
+ event_info->drm_queue);
+ else
+ radeon_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
@@ -1119,20 +1064,22 @@ CARD32 radeon_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;
- radeon_dri2_frame_event_handler((unsigned int)frame, tv_sec, tv_usec, data);
+ if (event_info->drm_queue)
+ radeon_drm_queue_handler(info->dri2.drm_fd, frame, drm_now / 1000000,
+ drm_now % 1000000, event_info->drm_queue);
+ else
+ radeon_dri2_frame_event_handler(scrn, frame, drm_now, data);
return 0;
}
static
-void radeon_dri2_schedule_event(CARD32 delay, pointer arg)
+void radeon_dri2_schedule_event(CARD32 delay, DRI2FrameEventPtr event_info)
{
- OsTimerPtr timer;
-
- timer = TimerSet(NULL, 0, delay, radeon_dri2_deferred_event, arg);
+ event_info->timer = TimerSet(NULL, 0, delay, radeon_dri2_deferred_event,
+ event_info);
if (delay == 0) {
CARD32 now = GetTimeInMillis();
- radeon_dri2_deferred_event(timer, now, arg);
+ radeon_dri2_deferred_event(event_info->timer, now, event_info);
}
}
@@ -1150,6 +1097,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
DRI2FrameEventPtr wait_info = NULL;
+ struct radeon_drm_queue_entry *wait = NULL;
xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE);
drmVBlank vbl;
int ret;
@@ -1172,17 +1120,8 @@ static int radeon_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
@@ -1210,6 +1149,16 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
current_msc = vbl.reply.sequence + radeon_get_interpolated_vblanks(crtc);
current_msc &= 0xffffffff;
+ wait = radeon_drm_queue_alloc(scrn, client, RADEON_DRM_QUEUE_ID_DEFAULT,
+ wait_info, radeon_dri2_frame_event_handler,
+ radeon_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
@@ -1228,7 +1177,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
vbl.request.type |= radeon_populate_vbl_request_type(crtc);
vbl.request.sequence = target_msc;
vbl.request.sequence -= radeon_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,
@@ -1260,7 +1209,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
vbl.request.sequence += divisor;
vbl.request.sequence -= radeon_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,
@@ -1273,11 +1222,8 @@ static int radeon_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)
+ radeon_dri2_deferred_event(NULL, 0, wait_info);
return TRUE;
}
@@ -1314,6 +1260,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
drmVBlank vbl;
int ret, flip = 0;
DRI2FrameEventPtr swap_info = NULL;
+ struct radeon_drm_queue_entry *swap;
CARD64 current_msc;
BoxRec box;
RegionRec region;
@@ -1346,15 +1293,17 @@ static int radeon_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 = radeon_drm_queue_alloc(scrn, client, RADEON_DRM_QUEUE_ID_DEFAULT,
+ swap_info, radeon_dri2_frame_event_handler,
+ radeon_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
@@ -1421,7 +1370,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
vbl.request.sequence = *target_msc;
vbl.request.sequence -= radeon_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,
@@ -1468,7 +1417,7 @@ static int radeon_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,
@@ -1581,22 +1530,6 @@ radeon_dri2_screen_init(ScreenPtr pScreen)
driverNames[1] = NULL; /* no VDPAU support */
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, radeon_dri2_client_state_changed, 0);
}
diff --git a/src/radeon_dri2.h b/src/radeon_dri2.h
index 37d46f3..9ba47c7 100644
--- a/src/radeon_dri2.h
+++ b/src/radeon_dri2.h
@@ -43,48 +43,11 @@ struct radeon_dri2 {
Bool radeon_dri2_screen_init(ScreenPtr pScreen);
void radeon_dri2_close_screen(ScreenPtr pScreen);
-int drmmode_get_crtc_id(xf86CrtcPtr crtc);
-void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data);
-void radeon_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data);
-
#else
static inline Bool radeon_dri2_screen_init(ScreenPtr pScreen) { return FALSE; }
static inline void radeon_dri2_close_screen(ScreenPtr pScreen) {}
-static inline void
-radeon_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
-radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data)
-{
- radeon_dri2_dummy_event_handler(frame, tv_sec, tv_usec, event_data,
- __func__);
-}
-
-static inline void
-radeon_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
- unsigned int tv_usec, void *event_data)
-{
- radeon_dri2_dummy_event_handler(frame, tv_sec, tv_usec, event_data,
- __func__);
-}
-
#endif
#endif /* RADEON_DRI2_H */
commit c3fa22a479e61d1899fa9d327d9c4e2a7f64b0c1
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Wed Mar 11 17:47:59 2015 +0900
DRI2: Move radeon_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.
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index a0eecac..a3f0776 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -613,6 +613,64 @@ xf86CrtcPtr radeon_dri2_drawable_crtc(DrawablePtr pDraw, Bool consider_disabled)
return NULL;
}
+void radeon_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 += radeon_get_interpolated_vblanks(flip->crtc);
+
+ screen = drawable->pScreen;
+ scrn = xf86ScreenToScrn(screen);
+
+ pixmap = screen->GetScreenPixmap(screen);
+ xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, RADEON_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
radeon_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr client,
DrawablePtr draw, DRI2BufferPtr front,
@@ -1223,64 +1281,6 @@ out_complete:
return TRUE;
}
-void radeon_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 += radeon_get_interpolated_vblanks(flip->crtc);
-
- screen = drawable->pScreen;
- scrn = xf86ScreenToScrn(screen);
-
- pixmap = screen->GetScreenPixmap(screen);
- xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, RADEON_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 65045112fdc8a9fa36e0e00f46739a6152b775ff
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Wed Mar 11 17:33:54 2015 +0900
DRI2: Remove superfluous assignments to *_info->frame
That field is only used for page flipping.
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 31bd73c..a0eecac 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -1133,7 +1133,6 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
CARD32 delay;
delay = radeon_dri2_extrapolate_msc_delay(crtc, &target_msc,
divisor, remainder);
- wait_info->frame = target_msc;
radeon_dri2_schedule_event(delay, wait_info);
DRI2BlockClient(client, draw);
return TRUE;
@@ -1179,8 +1178,6 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
goto out_complete;
}
- wait_info->frame = vbl.reply.sequence;
- wait_info->frame += radeon_get_interpolated_vblanks(crtc);
DRI2BlockClient(client, draw);
return TRUE;
}
@@ -1213,8 +1210,6 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
goto out_complete;
}
- wait_info->frame = vbl.reply.sequence;
- wait_info->frame += radeon_get_interpolated_vblanks(crtc);
DRI2BlockClient(client, draw);
return TRUE;
@@ -1370,7 +1365,6 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
CARD32 delay;
delay = radeon_dri2_extrapolate_msc_delay(crtc, target_msc,
divisor, remainder);
- swap_info->frame = *target_msc;
radeon_dri2_schedule_event(delay, swap_info);
return TRUE;
}
commit ad27f16f308079d06a2b1c788b3cb0947531253a
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Wed Mar 11 17:30:11 2015 +0900
DRI2: Simplify blit fallback handling for scheduled swaps
Also use radeon_dri2_schedule_event when possible.
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 36ab4d0..31bd73c 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -1319,7 +1319,6 @@ static int radeon_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;
@@ -1345,6 +1344,7 @@ static int radeon_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;
@@ -1384,9 +1384,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"first get vblank counter failed: %s\n",
strerror(errno));
- *target_msc = 0;
- radeon_dri2_schedule_event(FALLBACK_SWAP_DELAY, swap_info);
- return TRUE;
+ goto blit_fallback;
}
current_msc = vbl.reply.sequence + radeon_get_interpolated_vblanks(crtc);
@@ -1394,13 +1392,11 @@ static int radeon_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.
*/
@@ -1437,9 +1433,7 @@ static int radeon_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;
- radeon_dri2_schedule_event(FALLBACK_SWAP_DELAY, swap_info);
- return TRUE;
+ goto blit_fallback;
}
*target_msc = vbl.reply.sequence + flip;
@@ -1486,9 +1480,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"final get vblank counter failed: %s\n",
strerror(errno));
- *target_msc = 0;
- radeon_dri2_schedule_event(FALLBACK_SWAP_DELAY, swap_info);
- return TRUE;
+ goto blit_fallback;
}
/* Adjust returned value for 1 fame pageflip offset of flip > 0 */
@@ -1499,22 +1491,23 @@ static int radeon_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;
+ radeon_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);
- radeon_dri2_copy_region(draw, ®ion, front, back);
+ radeon_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);
- radeon_dri2_unref_buffer(front);
- radeon_dri2_unref_buffer(back);
+ radeon_dri2_unref_buffer(front);
+ radeon_dri2_unref_buffer(back);
+ }
*target_msc = 0; /* offscreen, so zero out target vblank count */
return TRUE;
commit b4af8a327ed8420f0ff4ea0f113f4a59406ed4d3
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Mon Mar 2 18:59:54 2015 +0900
Add DRM event queue helpers v2
v2: Rename struct radeon_drm_queue to struct radeon_drm_queue_event,
thanks to Richard Wilbur <richard.wilbur at gmail.com> for the suggestion.
Also changed the corresponding parameter and local variable names from
'q' to 'e'.
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/Makefile.am b/src/Makefile.am
index 708f2ad..9cc8a2d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,8 +29,8 @@
ati_drv_la_LIBADD = $(PCIACCESS_LIBS)
radeon_drv_la_LIBADD = $(LIBDRM_RADEON_LIBS) $(PCIACCESS_LIBS)
-RADEON_KMS_SRCS=radeon_dri2.c radeon_kms.c drmmode_display.c radeon_vbo.c \
- radeon_bo_helper.c
+RADEON_KMS_SRCS=radeon_dri2.c radeon_drm_queue.c radeon_kms.c drmmode_display.c \
+ radeon_vbo.c radeon_bo_helper.c
RADEON_EXA_SOURCES = radeon_exa.c r600_exa.c r6xx_accel.c r600_textured_videofuncs.c r600_shader.c radeon_exa_shared.c \
evergreen_exa.c evergreen_accel.c evergreen_shader.c evergreen_textured_videofuncs.c cayman_accel.c cayman_shader.c
@@ -88,6 +88,7 @@ EXTRA_DIST = \
bicubic_table.h \
bicubic_table.py \
radeon_bo_helper.h \
+ radeon_drm_queue.h \
radeon_exa_render.c \
radeon_exa_funcs.c \
radeon_exa_shared.h \
diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c
new file mode 100644
index 0000000..5e54ef8
--- /dev/null
+++ b/src/radeon_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 "radeon.h"
+#include "radeon_drm_queue.h"
+#include "radeon_list.h"
+
+
+struct radeon_drm_queue_entry {
+ struct xorg_list list;
+ uint64_t id;
+ void *data;
+ ClientPtr client;
+ ScrnInfoPtr scrn;
+ radeon_drm_handler_proc handler;
+ radeon_drm_abort_proc abort;
+};
+
+static int radeon_drm_queue_refcnt;
+static struct xorg_list radeon_drm_queue;
+
+
+/*
+ * Handle a DRM event
+ */
+void
+radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int sec,
+ unsigned int usec, void *user_ptr)
+{
+ struct radeon_drm_queue_entry *user_data = user_ptr;
+ struct radeon_drm_queue_entry *e, *tmp;
+
+ xorg_list_for_each_entry_safe(e, tmp, &radeon_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 radeon_drm_queue_entry *
+radeon_drm_queue_alloc(ScrnInfoPtr scrn, ClientPtr client,
+ uint64_t id, void *data,
+ radeon_drm_handler_proc handler,
+ radeon_drm_abort_proc abort)
+{
+ struct radeon_drm_queue_entry *e;
+
+ e = calloc(1, sizeof(struct radeon_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, &radeon_drm_queue);
+
+ return e;
+}
+
+/*
+ * Abort one queued DRM entry, removing it
+ * from the list, calling the abort function and
+ * freeing the memory
+ */
+static void
+radeon_drm_abort_one(struct radeon_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
+radeon_drm_abort_client(ClientPtr client)
+{
+ struct radeon_drm_queue_entry *e, *tmp;
+
+ xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) {
+ if (e->client == client)
+ radeon_drm_abort_one(e);
+ }
+}
+
+/*
+ * Abort specific drm queue entry
+ */
+void
+radeon_drm_abort_entry(struct radeon_drm_queue_entry *entry)
+{
+ radeon_drm_abort_one(entry);
+}
+
+/*
+ * Abort specific drm queue entry by ID
+ */
+void
+radeon_drm_abort_id(uint64_t id)
+{
+ struct radeon_drm_queue_entry *e, *tmp;
+
+ xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) {
+ if (e->id == id) {
+ radeon_drm_abort_one(e);
+ break;
+ }
+ }
+}
+
+/*
+ * Initialize the DRM event queue
+ */
+void
+radeon_drm_queue_init()
+{
+ if (radeon_drm_queue_refcnt++)
+ return;
+
+ xorg_list_init(&radeon_drm_queue);
+}
+
+/*
+ * Deinitialize the DRM event queue
+ */
+void
+radeon_drm_queue_close(ScrnInfoPtr scrn)
+{
+ struct radeon_drm_queue_entry *e, *tmp;
+
+ xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) {
+ if (e->scrn == scrn)
+ radeon_drm_abort_one(e);
+ }
+
+ radeon_drm_queue_refcnt--;
+}
diff --git a/src/radeon_drm_queue.h b/src/radeon_drm_queue.h
new file mode 100644
index 0000000..8fc1c42
--- /dev/null
+++ b/src/radeon_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 _RADEON_DRM_QUEUE_H_
+#define _RADEON_DRM_QUEUE_H_
+
+#define RADEON_DRM_QUEUE_CLIENT_DEFAULT serverClient
+#define RADEON_DRM_QUEUE_ID_DEFAULT ~0ULL
+
+struct radeon_drm_queue_entry;
+
+typedef void (*radeon_drm_handler_proc)(ScrnInfoPtr scrn, uint32_t seq,
+ uint64_t usec, void *data);
+typedef void (*radeon_drm_abort_proc)(ScrnInfoPtr scrn, void *data);
+
+void radeon_drm_queue_handler(int fd, unsigned int frame,
+ unsigned int tv_sec, unsigned int tv_usec,
+ void *user_ptr);
+struct radeon_drm_queue_entry *radeon_drm_queue_alloc(ScrnInfoPtr scrn,
+ ClientPtr client,
+ uint64_t id,
+ void *data,
+ radeon_drm_handler_proc handler,
+ radeon_drm_abort_proc abort);
+void radeon_drm_abort_client(ClientPtr client);
+void radeon_drm_abort_entry(struct radeon_drm_queue_entry *entry);
+void radeon_drm_abort_id(uint64_t id);
+void radeon_drm_queue_init();
+void radeon_drm_queue_close(ScrnInfoPtr scrn);
+
+#endif /* _RADEON_DRM_QUEUE_H_ */
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 62364d9..ced3594 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -32,6 +32,7 @@
#include <sys/ioctl.h>
/* Driver data structures */
#include "radeon.h"
+#include "radeon_drm_queue.h"
#include "radeon_reg.h"
#include "radeon_probe.h"
#include "micmap.h"
@@ -876,6 +877,8 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
if (!RADEONPreInitAccel_KMS(pScrn)) goto fail;
+ radeon_drm_queue_init();
+
info->allowColorTiling2D = FALSE;
RADEONSetupCapabilities(pScrn);
@@ -1173,6 +1176,7 @@ static Bool RADEONCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL)
"RADEONCloseScreen\n");
drmmode_uevent_fini(pScrn, &info->drmmode);
+ radeon_drm_queue_close(pScrn);
radeon_cs_flush_indirect(pScrn);
DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
commit 7c3470f4b659206ed23f761948936ede3a2dba3d
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Fri Mar 6 18:51:29 2015 +0900
Move xorg_list backwards compatibility to new radeon_list.h header
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/Makefile.am b/src/Makefile.am
index 9ff1ffb..708f2ad 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -93,6 +93,7 @@ EXTRA_DIST = \
radeon_exa_shared.h \
radeon_glamor.h \
radeon.h \
+ radeon_list.h \
radeon_probe.h \
radeon_reg.h \
radeon_version.h \
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 8cc7e56..36ab4d0 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -41,15 +41,7 @@
#include <errno.h>
#include "radeon_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 "radeon_list.h"
#include "radeon_bo_gem.h"
diff --git a/src/radeon_list.h b/src/radeon_list.h
new file mode 100644
index 0000000..4002013
--- /dev/null
+++ b/src/radeon_list.h
@@ -0,0 +1,38 @@
+/*
+ * 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 _RADEON_LIST_H_
+#define _RADEON_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
+#endif
+
+#endif /* _RADEON_LIST_H_ */
commit 7388d0b6c54b9d536fdb161e3aa61b326627b939
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Thu Mar 5 17:35:06 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.
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/configure.ac b/configure.ac
index c471ff5..891da03 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,7 +75,7 @@ PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.58])
PKG_CHECK_MODULES(LIBDRM_RADEON, [libdrm_radeon])
# 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")
@@ -125,18 +125,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"])
CPPFLAGS="$SAVE_CPPFLAGS"
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 56beeec..8cc7e56 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -42,7 +42,6 @@
#include "radeon_version.h"
-#if HAVE_LIST_H
#include "list.h"
#if !HAVE_XORG_LIST
#define xorg_list list
@@ -51,15 +50,9 @@
#define xorg_list_del list_del
#define xorg_list_for_each_entry list_for_each_entry
#endif
-#endif
-
#include "radeon_bo_gem.h"
-#if DRI2INFOREC_VERSION >= 4 && HAVE_LIST_H
-#define USE_DRI2_SCHEDULING
-#endif
-
#if DRI2INFOREC_VERSION >= 9
#define USE_DRI2_PRIME
#endif
@@ -490,8 +483,6 @@ radeon_dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
pDstBuffer, pSrcBuffer);
}
-#ifdef USE_DRI2_SCHEDULING
-
enum DRI2FrameEventType {
DRI2_SWAP,
DRI2_FLIP,
@@ -1537,8 +1528,6 @@ blit_fallback:
return TRUE;
}
-#endif /* USE_DRI2_SCHEDULING */
-
Bool
radeon_dri2_screen_init(ScreenPtr pScreen)
@@ -1546,10 +1535,8 @@ radeon_dri2_screen_init(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
RADEONInfoPtr info = RADEONPTR(pScrn);
DRI2InfoRec dri2_info = { 0 };
-#ifdef USE_DRI2_SCHEDULING
const char *driverNames[2];
Bool scheduling_works = TRUE;
-#endif
if (!info->dri2.available)
return FALSE;
@@ -1574,7 +1561,6 @@ radeon_dri2_screen_init(ScreenPtr pScreen)
dri2_info.DestroyBuffer = radeon_dri2_destroy_buffer;
dri2_info.CopyRegion = radeon_dri2_copy_region;
-#ifdef USE_DRI2_SCHEDULING
if (info->dri2.pKernelDRMVersion->version_minor < 4) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You need a newer kernel for "
"sync extension\n");
@@ -1637,7 +1623,6 @@ radeon_dri2_screen_init(ScreenPtr pScreen)
DRI2InfoCnt++;
}
-#endif
#if DRI2INFOREC_VERSION >= 9
dri2_info.version = 9;
@@ -1655,10 +1640,8 @@ void radeon_dri2_close_screen(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
RADEONInfoPtr info = RADEONPTR(pScrn);
-#ifdef USE_DRI2_SCHEDULING
if (--DRI2InfoCnt == 0)
DeleteCallback(&ClientStateCallback, radeon_dri2_client_state_changed, 0);
-#endif
DRI2CloseScreen(pScreen);
drmFree(info->dri2.device_name);
More information about the xorg-commit
mailing list