Skip to content
Commits on Source (61)
......@@ -26,12 +26,7 @@ INSTALL
install-sh
.libs/
libtool
libtool.m4
ltmain.sh
lt~obsolete.m4
ltoptions.m4
ltsugar.m4
ltversion.m4
Makefile
Makefile.in
mdate-sh
......
......@@ -23,13 +23,13 @@
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([xf86-video-ati],
[18.0.1],
[18.1.0],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon],
[xf86-video-ati])
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIRS([m4])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR(.)
......@@ -70,7 +70,7 @@ XORG_DRIVER_CHECK_EXT(XV, videoproto)
XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
# Checks for libraries.
PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.78])
PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.89])
PKG_CHECK_MODULES(LIBDRM_RADEON, [libdrm_radeon])
# Obtain compiler/linker options for the driver dependencies
......@@ -138,12 +138,22 @@ if test "x$GLAMOR" != "xno"; then
[Have glamor_egl_destroy_textured_pixmap API])], [],
[#include "xorg-server.h"
#include "glamor.h"])
AC_CHECK_DECL(glamor_finish,
[AC_DEFINE(HAVE_GLAMOR_FINISH, 1,
[Have glamor_finish API])],
[PKG_CHECK_MODULES(LIBGL, [gl])],
[#include "xorg-server.h"
#include "glamor.h"])
fi
if test "x$GLAMOR_XSERVER" != xyes; then
PKG_CHECK_MODULES(LIBGLAMOR, [glamor >= 0.6.0])
PKG_CHECK_MODULES(LIBGLAMOR_EGL, [glamor-egl])
fi
PKG_CHECK_MODULES(GBM, [gbm >= 10.6])
AC_DEFINE(USE_GLAMOR, 1, [Enable glamor acceleration])
else
AC_MSG_RESULT([$GLAMOR])
......
libtool.m4
lt~obsolete.m4
ltoptions.m4
ltsugar.m4
ltversion.m4
......@@ -62,8 +62,8 @@ radeon_drv_la_SOURCES = \
$(RADEON_KMS_SRCS)
if GLAMOR
AM_CFLAGS += @LIBGLAMOR_CFLAGS@
radeon_drv_la_LIBADD += @LIBGLAMOR_LIBS@
AM_CFLAGS += @LIBGLAMOR_CFLAGS@ @GBM_CFLAGS@
radeon_drv_la_LIBADD += @LIBGLAMOR_LIBS@ @GBM_LIBS@
radeon_drv_la_SOURCES += \
radeon_glamor_wrappers.c \
radeon_glamor.c
......
......@@ -109,7 +109,7 @@ ati_device_get_primary(void)
device_iter = pci_slot_match_iterator_create(NULL);
while ((device = pci_device_next(device_iter)) != NULL) {
while ((device = pci_device_next(device_iter))) {
if (xf86IsPrimaryPci(device))
break;
}
......@@ -128,7 +128,7 @@ ati_device_get_indexed(int index)
device_iter = pci_slot_match_iterator_create(NULL);
while ((device = pci_device_next(device_iter)) != NULL) {
while ((device = pci_device_next(device_iter))) {
if (device->vendor_id == PCI_VENDOR_ATI) {
if (count == index)
return device;
......
This diff is collapsed.
......@@ -56,7 +56,6 @@ typedef struct {
} drmmode_rec, *drmmode_ptr;
typedef struct {
struct drmmode_fb *fb;
void *event_data;
int flip_count;
unsigned int fe_frame;
......@@ -64,6 +63,7 @@ typedef struct {
xf86CrtcPtr fe_crtc;
radeon_drm_handler_proc handler;
radeon_drm_abort_proc abort;
struct drmmode_fb *fb[0];
} drmmode_flipdata_rec, *drmmode_flipdata_ptr;
struct drmmode_fb {
......@@ -72,7 +72,7 @@ struct drmmode_fb {
};
struct drmmode_scanout {
struct radeon_bo *bo;
struct radeon_buffer *bo;
PixmapPtr pixmap;
int width, height;
};
......@@ -88,7 +88,7 @@ typedef struct {
Bool ignore_damage;
RegionRec scanout_last_region;
unsigned scanout_id;
Bool scanout_update_pending;
uintptr_t scanout_update_pending;
Bool tear_free;
PixmapPtr prime_scanout_pixmap;
......@@ -103,18 +103,14 @@ typedef struct {
* modeset)
*/
Bool need_modeset;
/* For keeping track of nested calls to drm_wait_pending_flip /
* drm_queue_handle_deferred
*/
int wait_flip_nesting_level;
/* A flip to this FB is pending for this CRTC */
struct drmmode_fb *flip_pending;
/* The FB currently being scanned out by this CRTC, if any */
struct drmmode_fb *fb;
#ifdef HAVE_PRESENT_H
/* Deferred processing of Present vblank event */
uint64_t present_vblank_event_id;
uint64_t present_vblank_usec;
unsigned present_vblank_msc;
Bool present_flip_expected;
#endif
} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
typedef struct {
......@@ -139,6 +135,10 @@ typedef struct {
int tear_free;
} drmmode_output_private_rec, *drmmode_output_private_ptr;
typedef struct {
uint32_t lessee_id;
} drmmode_lease_private_rec, *drmmode_lease_private_ptr;
enum drmmode_flip_sync {
FLIP_VSYNC,
......
......@@ -71,7 +71,7 @@ EVERGREENPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
if (!RADEONValidPM(pm, pPix->drawable.bitsPerPixel))
RADEON_FALLBACK(("invalid planemask\n"));
dst.bo = radeon_get_pixmap_bo(pPix);
dst.bo = radeon_get_pixmap_bo(pPix)->bo.radeon;
dst.tiling_flags = radeon_get_pixmap_tiling(pPix);
dst.surface = radeon_get_pixmap_surface(pPix);
......@@ -466,13 +466,13 @@ EVERGREENPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst,
accel_state->same_surface = FALSE;
src_obj.bo = radeon_get_pixmap_bo(pSrc);
dst_obj.bo = radeon_get_pixmap_bo(pDst);
src_obj.bo = radeon_get_pixmap_bo(pSrc)->bo.radeon;
dst_obj.bo = radeon_get_pixmap_bo(pDst)->bo.radeon;
dst_obj.surface = radeon_get_pixmap_surface(pDst);
src_obj.surface = radeon_get_pixmap_surface(pSrc);
dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst);
src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc);
if (radeon_get_pixmap_bo(pSrc) == radeon_get_pixmap_bo(pDst))
if (src_obj.bo == dst_obj.bo)
accel_state->same_surface = TRUE;
src_obj.width = pSrc->drawable.width;
......@@ -511,7 +511,7 @@ EVERGREENPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst,
accel_state->copy_area_bo = radeon_bo_open(info->bufmgr, 0, size, 0,
RADEON_GEM_DOMAIN_VRAM,
0);
if (accel_state->copy_area_bo == NULL)
if (!accel_state->copy_area_bo)
RADEON_FALLBACK(("temp copy surface alloc failed\n"));
radeon_cs_space_add_persistent_bo(info->cs, accel_state->copy_area_bo,
......@@ -1301,7 +1301,7 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture,
return FALSE;
if (pSrc) {
src_obj.bo = radeon_get_pixmap_bo(pSrc);
src_obj.bo = radeon_get_pixmap_bo(pSrc)->bo.radeon;
src_obj.surface = radeon_get_pixmap_surface(pSrc);
src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc);
src_obj.pitch = exaGetPixmapPitch(pSrc) / (pSrc->drawable.bitsPerPixel / 8);
......@@ -1311,7 +1311,7 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture,
src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT;
}
dst_obj.bo = radeon_get_pixmap_bo(pDst);
dst_obj.bo = radeon_get_pixmap_bo(pDst)->bo.radeon;
dst_obj.surface = radeon_get_pixmap_surface(pDst);
dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst);
dst_obj.pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel / 8);
......@@ -1325,7 +1325,7 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture,
if (pMaskPicture) {
if (pMask) {
mask_obj.bo = radeon_get_pixmap_bo(pMask);
mask_obj.bo = radeon_get_pixmap_bo(pMask)->bo.radeon;
mask_obj.tiling_flags = radeon_get_pixmap_tiling(pMask);
mask_obj.pitch = exaGetPixmapPitch(pMask) / (pMask->drawable.bitsPerPixel / 8);
mask_obj.surface = radeon_get_pixmap_surface(pMask);
......@@ -1673,16 +1673,16 @@ EVERGREENUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
return FALSE;
driver_priv = exaGetPixmapDriverPrivate(pDst);
if (!driver_priv || !driver_priv->bo)
if (!driver_priv || !driver_priv->bo->bo.radeon)
return FALSE;
/* If we know the BO won't be busy / in VRAM, don't bother with a scratch */
copy_dst = driver_priv->bo;
copy_dst = driver_priv->bo->bo.radeon;
copy_pitch = pDst->devKind;
if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) {
if (!radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) {
if (!radeon_bo_is_referenced_by_cs(driver_priv->bo->bo.radeon, info->cs)) {
flush = FALSE;
if (!radeon_bo_is_busy(driver_priv->bo, &dst_domain) &&
if (!radeon_bo_is_busy(driver_priv->bo->bo.radeon, &dst_domain) &&
!(dst_domain & RADEON_GEM_DOMAIN_VRAM))
goto copy;
}
......@@ -1693,7 +1693,7 @@ EVERGREENUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
base_align = drmmode_get_base_align(pScrn, (bpp / 8), 0);
size = scratch_pitch * height * (bpp / 8);
scratch = radeon_bo_open(info->bufmgr, 0, size, base_align, RADEON_GEM_DOMAIN_GTT, 0);
if (scratch == NULL) {
if (!scratch) {
goto copy;
}
......@@ -1711,7 +1711,7 @@ EVERGREENUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
dst_obj.height = pDst->drawable.height;
dst_obj.bpp = bpp;
dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
dst_obj.bo = radeon_get_pixmap_bo(pDst);
dst_obj.bo = radeon_get_pixmap_bo(pDst)->bo.radeon;
dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst);
dst_obj.surface = radeon_get_pixmap_surface(pDst);
......@@ -1739,7 +1739,7 @@ copy:
r = TRUE;
size = w * bpp / 8;
dst = copy_dst->ptr;
if (copy_dst == driver_priv->bo)
if (copy_dst == driver_priv->bo->bo.radeon)
dst += y * copy_pitch + x * bpp / 8;
for (i = 0; i < h; i++) {
memcpy(dst + i * copy_pitch, src, size);
......@@ -1789,15 +1789,15 @@ EVERGREENDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w,
return FALSE;
driver_priv = exaGetPixmapDriverPrivate(pSrc);
if (!driver_priv || !driver_priv->bo)
if (!driver_priv || !driver_priv->bo->bo.radeon)
return FALSE;
/* If we know the BO won't end up in VRAM anyway, don't bother with a scratch */
copy_src = driver_priv->bo;
copy_src = driver_priv->bo->bo.radeon;
copy_pitch = pSrc->devKind;
if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) {
if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) {
src_domain = radeon_bo_get_src_domain(driver_priv->bo);
if (radeon_bo_is_referenced_by_cs(driver_priv->bo->bo.radeon, info->cs)) {
src_domain = radeon_bo_get_src_domain(driver_priv->bo->bo.radeon);
if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) ==
(RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM))
src_domain = 0;
......@@ -1806,7 +1806,7 @@ EVERGREENDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w,
}
if (!src_domain)
radeon_bo_is_busy(driver_priv->bo, &src_domain);
radeon_bo_is_busy(driver_priv->bo->bo.radeon, &src_domain);
if (src_domain & ~(uint32_t)RADEON_GEM_DOMAIN_VRAM)
goto copy;
......@@ -1821,7 +1821,7 @@ EVERGREENDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w,
base_align = drmmode_get_base_align(pScrn, (bpp / 8), 0);
size = scratch_pitch * height * (bpp / 8);
scratch = radeon_bo_open(info->bufmgr, 0, size, base_align, RADEON_GEM_DOMAIN_GTT, 0);
if (scratch == NULL) {
if (!scratch) {
goto copy;
}
radeon_cs_space_reset_bos(info->cs);
......@@ -1841,7 +1841,7 @@ EVERGREENDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w,
src_obj.height = pSrc->drawable.height;
src_obj.bpp = bpp;
src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT;
src_obj.bo = radeon_get_pixmap_bo(pSrc);
src_obj.bo = radeon_get_pixmap_bo(pSrc)->bo.radeon;
src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc);
src_obj.surface = radeon_get_pixmap_surface(pSrc);
......@@ -1883,7 +1883,7 @@ copy:
}
r = TRUE;
w *= bpp / 8;
if (copy_src == driver_priv->bo)
if (copy_src == driver_priv->bo->bo.radeon)
size = y * copy_pitch + x * bpp / 8;
else
size = 0;
......@@ -1927,7 +1927,7 @@ EVERGREENAllocShaders(ScrnInfoPtr pScrn, ScreenPtr pScreen)
accel_state->shaders_bo = radeon_bo_open(info->bufmgr, 0, size, 0,
RADEON_GEM_DOMAIN_VRAM, 0);
if (accel_state->shaders_bo == NULL) {
if (!accel_state->shaders_bo) {
ErrorF("Allocating shader failed\n");
return FALSE;
}
......@@ -2046,7 +2046,7 @@ EVERGREENDrawInit(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
RADEONInfoPtr info = RADEONPTR(pScrn);
if (info->accel_state->exa == NULL) {
if (!info->accel_state->exa) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map not set up\n");
return FALSE;
}
......@@ -2065,7 +2065,6 @@ EVERGREENDrawInit(ScreenPtr pScreen)
info->accel_state->exa->MarkSync = EVERGREENMarkSync;
info->accel_state->exa->WaitMarker = EVERGREENSync;
info->accel_state->exa->CreatePixmap = RADEONEXACreatePixmap;
info->accel_state->exa->DestroyPixmap = RADEONEXADestroyPixmap;
info->accel_state->exa->PixmapIsOffscreen = RADEONEXAPixmapIsOffscreen;
info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_CS;
......
......@@ -345,12 +345,10 @@ R600SetAccelState(ScrnInfoPtr pScrn,
extern Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index);
extern void RADEONFinishAccess_CS(PixmapPtr pPix, int index);
extern void *RADEONEXACreatePixmap(ScreenPtr pScreen, int size, int align);
extern void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height,
int depth, int usage_hint, int bitsPerPixel,
int *new_pitch);
extern void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv);
extern struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix);
extern Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix);
extern Bool RADEONEXASharePixmapBacking(PixmapPtr ppix, ScreenPtr slave, void **handle_p);
extern Bool RADEONEXASetSharedPixmapBacking(PixmapPtr ppix, void *handle);
......
......@@ -140,7 +140,7 @@ EVERGREENDisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
CLEAR (vs_const_conf);
CLEAR (ps_const_conf);
dst_obj.bo = radeon_get_pixmap_bo(pPixmap);
dst_obj.bo = radeon_get_pixmap_bo(pPixmap)->bo.radeon;
dst_obj.tiling_flags = radeon_get_pixmap_tiling(pPixmap);
dst_obj.surface = radeon_get_pixmap_surface(pPixmap);
......
......@@ -150,7 +150,7 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
if (!RADEONValidPM(pm, pPix->drawable.bitsPerPixel))
RADEON_FALLBACK(("invalid planemask\n"));
dst.bo = radeon_get_pixmap_bo(pPix);
dst.bo = radeon_get_pixmap_bo(pPix)->bo.radeon;
dst.tiling_flags = radeon_get_pixmap_tiling(pPix);
dst.surface = radeon_get_pixmap_surface(pPix);
......@@ -534,13 +534,13 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst,
accel_state->same_surface = FALSE;
src_obj.bo = radeon_get_pixmap_bo(pSrc);
dst_obj.bo = radeon_get_pixmap_bo(pDst);
src_obj.bo = radeon_get_pixmap_bo(pSrc)->bo.radeon;
dst_obj.bo = radeon_get_pixmap_bo(pDst)->bo.radeon;
dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst);
src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc);
src_obj.surface = radeon_get_pixmap_surface(pSrc);
dst_obj.surface = radeon_get_pixmap_surface(pDst);
if (radeon_get_pixmap_bo(pSrc) == radeon_get_pixmap_bo(pDst))
if (src_obj.bo == dst_obj.bo)
accel_state->same_surface = TRUE;
src_obj.width = pSrc->drawable.width;
......@@ -575,7 +575,7 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst,
accel_state->copy_area_bo = radeon_bo_open(info->bufmgr, 0, size, align,
RADEON_GEM_DOMAIN_VRAM,
0);
if (accel_state->copy_area_bo == NULL)
if (!accel_state->copy_area_bo)
RADEON_FALLBACK(("temp copy surface alloc failed\n"));
radeon_cs_space_add_persistent_bo(info->cs, accel_state->copy_area_bo,
......@@ -1344,7 +1344,7 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
return FALSE;
if (pSrc) {
src_obj.bo = radeon_get_pixmap_bo(pSrc);
src_obj.bo = radeon_get_pixmap_bo(pSrc)->bo.radeon;
src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc);
src_obj.surface = radeon_get_pixmap_surface(pSrc);
src_obj.pitch = exaGetPixmapPitch(pSrc) / (pSrc->drawable.bitsPerPixel / 8);
......@@ -1354,7 +1354,7 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT;
}
dst_obj.bo = radeon_get_pixmap_bo(pDst);
dst_obj.bo = radeon_get_pixmap_bo(pDst)->bo.radeon;
dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst);
dst_obj.surface = radeon_get_pixmap_surface(pDst);
dst_obj.pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel / 8);
......@@ -1368,7 +1368,7 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
if (pMaskPicture) {
if (pMask) {
mask_obj.bo = radeon_get_pixmap_bo(pMask);
mask_obj.bo = radeon_get_pixmap_bo(pMask)->bo.radeon;
mask_obj.tiling_flags = radeon_get_pixmap_tiling(pMask);
mask_obj.surface = radeon_get_pixmap_surface(pMask);
mask_obj.pitch = exaGetPixmapPitch(pMask) / (pMask->drawable.bitsPerPixel / 8);
......@@ -1700,16 +1700,16 @@ R600UploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h,
return FALSE;
driver_priv = exaGetPixmapDriverPrivate(pDst);
if (!driver_priv || !driver_priv->bo)
if (!driver_priv || !driver_priv->bo->bo.radeon)
return FALSE;
/* If we know the BO won't be busy / in VRAM, don't bother with a scratch */
copy_dst = driver_priv->bo;
copy_dst = driver_priv->bo->bo.radeon;
copy_pitch = pDst->devKind;
if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) {
if (!radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) {
if (!radeon_bo_is_referenced_by_cs(driver_priv->bo->bo.radeon, info->cs)) {
flush = FALSE;
if (!radeon_bo_is_busy(driver_priv->bo, &dst_domain) &&
if (!radeon_bo_is_busy(driver_priv->bo->bo.radeon, &dst_domain) &&
!(dst_domain & RADEON_GEM_DOMAIN_VRAM))
goto copy;
}
......@@ -1723,7 +1723,7 @@ R600UploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h,
base_align = drmmode_get_base_align(pScrn, (bpp / 8), 0);
size = scratch_pitch * height * (bpp / 8);
scratch = radeon_bo_open(info->bufmgr, 0, size, base_align, RADEON_GEM_DOMAIN_GTT, 0);
if (scratch == NULL) {
if (!scratch) {
goto copy;
}
......@@ -1741,7 +1741,7 @@ R600UploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h,
dst_obj.height = pDst->drawable.height;
dst_obj.bpp = bpp;
dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
dst_obj.bo = radeon_get_pixmap_bo(pDst);
dst_obj.bo = radeon_get_pixmap_bo(pDst)->bo.radeon;
dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst);
dst_obj.surface = radeon_get_pixmap_surface(pDst);
......@@ -1769,7 +1769,7 @@ copy:
r = TRUE;
size = w * bpp / 8;
dst = copy_dst->ptr;
if (copy_dst == driver_priv->bo)
if (copy_dst == driver_priv->bo->bo.radeon)
dst += y * copy_pitch + x * bpp / 8;
for (i = 0; i < h; i++) {
memcpy(dst + i * copy_pitch, src, size);
......@@ -1819,15 +1819,15 @@ R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
return FALSE;
driver_priv = exaGetPixmapDriverPrivate(pSrc);
if (!driver_priv || !driver_priv->bo)
if (!driver_priv || !driver_priv->bo->bo.radeon)
return FALSE;
/* If we know the BO won't end up in VRAM anyway, don't bother with a scratch */
copy_src = driver_priv->bo;
copy_src = driver_priv->bo->bo.radeon;
copy_pitch = pSrc->devKind;
if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) {
if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) {
src_domain = radeon_bo_get_src_domain(driver_priv->bo);
if (radeon_bo_is_referenced_by_cs(driver_priv->bo->bo.radeon, info->cs)) {
src_domain = radeon_bo_get_src_domain(driver_priv->bo->bo.radeon);
if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) ==
(RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM))
src_domain = 0;
......@@ -1836,7 +1836,7 @@ R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
}
if (!src_domain)
radeon_bo_is_busy(driver_priv->bo, &src_domain);
radeon_bo_is_busy(driver_priv->bo->bo.radeon, &src_domain);
if (src_domain & ~(uint32_t)RADEON_GEM_DOMAIN_VRAM)
goto copy;
......@@ -1847,7 +1847,7 @@ R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
base_align = drmmode_get_base_align(pScrn, (bpp / 8), 0);
size = scratch_pitch * height * (bpp / 8);
scratch = radeon_bo_open(info->bufmgr, 0, size, base_align, RADEON_GEM_DOMAIN_GTT, 0);
if (scratch == NULL) {
if (!scratch) {
goto copy;
}
radeon_cs_space_reset_bos(info->cs);
......@@ -1867,7 +1867,7 @@ R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
src_obj.height = pSrc->drawable.height;
src_obj.bpp = bpp;
src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT;
src_obj.bo = radeon_get_pixmap_bo(pSrc);
src_obj.bo = radeon_get_pixmap_bo(pSrc)->bo.radeon;
src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc);
src_obj.surface = radeon_get_pixmap_surface(pSrc);
......@@ -1909,7 +1909,7 @@ copy:
}
r = TRUE;
w *= bpp / 8;
if (copy_src == driver_priv->bo)
if (copy_src == driver_priv->bo->bo.radeon)
size = y * copy_pitch + x * bpp / 8;
else
size = 0;
......@@ -1960,7 +1960,7 @@ R600AllocShaders(ScrnInfoPtr pScrn, ScreenPtr pScreen)
accel_state->shaders_bo = radeon_bo_open(info->bufmgr, 0, size, 0,
RADEON_GEM_DOMAIN_VRAM, 0);
if (accel_state->shaders_bo == NULL) {
if (!accel_state->shaders_bo) {
ErrorF("Allocating shader failed\n");
return FALSE;
}
......@@ -2025,7 +2025,7 @@ R600DrawInit(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
RADEONInfoPtr info = RADEONPTR(pScrn);
if (info->accel_state->exa == NULL) {
if (!info->accel_state->exa) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map not set up\n");
return FALSE;
}
......@@ -2044,7 +2044,6 @@ R600DrawInit(ScreenPtr pScreen)
info->accel_state->exa->MarkSync = R600MarkSync;
info->accel_state->exa->WaitMarker = R600Sync;
info->accel_state->exa->CreatePixmap = RADEONEXACreatePixmap;
info->accel_state->exa->DestroyPixmap = RADEONEXADestroyPixmap;
info->accel_state->exa->PixmapIsOffscreen = RADEONEXAPixmapIsOffscreen;
info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_CS;
......
......@@ -316,12 +316,10 @@ R600SetAccelState(ScrnInfoPtr pScrn,
extern Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index);
extern void RADEONFinishAccess_CS(PixmapPtr pPix, int index);
extern void *RADEONEXACreatePixmap(ScreenPtr pScreen, int size, int align);
extern void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height,
int depth, int usage_hint, int bitsPerPixel,
int *new_pitch);
extern void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv);
extern struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix);
extern Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix);
extern Bool RADEONEXASharePixmapBacking(PixmapPtr ppix, ScreenPtr slave, void **handle_p);
extern Bool RADEONEXASetSharedPixmapBacking(PixmapPtr ppix, void *handle);
......
......@@ -152,7 +152,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
CLEAR (vs_conf);
CLEAR (ps_conf);
dst_obj.bo = radeon_get_pixmap_bo(pPixmap);
dst_obj.bo = radeon_get_pixmap_bo(pPixmap)->bo.radeon;
dst_obj.tiling_flags = radeon_get_pixmap_tiling(pPixmap);
dst_obj.surface = radeon_get_pixmap_surface(pPixmap);
......
......@@ -83,6 +83,7 @@
#include "radeon_dri2.h"
#include "drmmode_display.h"
#include "radeon_surface.h"
#include "radeon_bo_helper.h"
/* Render support */
#ifdef RENDER
......@@ -300,16 +301,13 @@ radeon_dirty_src_equals(PixmapDirtyUpdatePtr dirty, PixmapPtr pixmap)
#define CURSOR_WIDTH_CIK 128
#define CURSOR_HEIGHT_CIK 128
#ifdef USE_GLAMOR
struct radeon_pixmap {
struct radeon_surface surface;
uint_fast32_t gpu_read;
uint_fast32_t gpu_write;
struct radeon_bo *bo;
struct radeon_buffer *bo;
struct drmmode_fb *fb;
uint32_t tiling_flags;
......@@ -335,7 +333,7 @@ static inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct radeon_pix
struct radeon_exa_pixmap_priv {
struct radeon_bo *bo;
struct radeon_buffer *bo;
struct drmmode_fb *fb;
uint32_t tiling_flags;
struct radeon_surface surface;
......@@ -569,7 +567,7 @@ typedef struct {
void (*reemit_current2d)(ScrnInfoPtr pScrn, int op); // emit the current 2D state into the IB
struct radeon_2d_state state_2d;
struct radeon_bo *front_bo;
struct radeon_buffer *front_buffer;
struct radeon_bo_manager *bufmgr;
struct radeon_cs_manager *csm;
struct radeon_cs *cs;
......@@ -608,6 +606,8 @@ typedef struct {
unsigned hwcursor_disabled;
#ifdef USE_GLAMOR
struct gbm_device *gbm;
struct {
CreateGCProcPtr SavedCreateGC;
RegionPtr (*SavedCopyArea)(DrawablePtr, DrawablePtr, GCPtr, int, int,
......@@ -645,6 +645,11 @@ extern void RADEONInit3DEngine(ScrnInfoPtr pScrn);
extern int radeon_cs_space_remaining(ScrnInfoPtr pScrn);
/* radeon_bo_helper.c */
extern Bool
radeon_surface_initialize(RADEONInfoPtr info, struct radeon_surface *surface,
int width, int height, int cpp, uint32_t tiling_flags,
int usage_hint);
extern Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle);
/* radeon_commonfuncs.c */
......@@ -703,27 +708,14 @@ extern RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn);
static inline struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix)
{
#ifdef USE_GLAMOR
RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
struct radeon_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix);
if (info->use_glamor) {
struct radeon_pixmap *priv;
priv = radeon_get_pixmap_private(pPix);
return priv ? &priv->surface : NULL;
} else
#endif
{
struct radeon_exa_pixmap_priv *driver_priv;
driver_priv = exaGetPixmapDriverPrivate(pPix);
return &driver_priv->surface;
}
return NULL;
}
uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix);
static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_buffer *bo)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pPix->drawable.pScreen);
RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
......@@ -734,7 +726,7 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
struct radeon_pixmap *priv;
priv = radeon_get_pixmap_private(pPix);
if (priv == NULL && bo == NULL)
if (!priv && !bo)
return TRUE;
if (priv) {
......@@ -742,7 +734,8 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
if (priv->bo == bo)
return TRUE;
radeon_bo_unref(priv->bo);
radeon_buffer_unref(&priv->bo);
priv->handle_valid = FALSE;
}
drmmode_fb_reference(pRADEONEnt->fd, &priv->fb, NULL);
......@@ -754,21 +747,18 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
}
if (bo) {
uint32_t pitch;
if (!priv) {
priv = calloc(1, sizeof (struct radeon_pixmap));
if (!priv)
return FALSE;
}
radeon_bo_ref(bo);
radeon_buffer_ref(bo);
priv->bo = bo;
radeon_bo_get_tiling(bo, &priv->tiling_flags, &pitch);
}
radeon_set_pixmap_private(pPix, priv);
radeon_get_pixmap_tiling_flags(pPix);
return TRUE;
} else
#endif /* USE_GLAMOR */
......@@ -779,15 +769,18 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
if (driver_priv) {
uint32_t pitch;
if (driver_priv->bo)
radeon_bo_unref(driver_priv->bo);
radeon_buffer_unref(&driver_priv->bo);
drmmode_fb_reference(pRADEONEnt->fd, &driver_priv->fb, NULL);
radeon_bo_ref(bo);
driver_priv->bo = bo;
radeon_bo_get_tiling(bo, &driver_priv->tiling_flags, &pitch);
if (bo) {
radeon_buffer_ref(bo);
radeon_bo_get_tiling(bo->bo.radeon, &driver_priv->tiling_flags,
&pitch);
} else
driver_priv->tiling_flags = 0;
return TRUE;
}
......@@ -795,7 +788,7 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
}
}
static inline struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix)
static inline struct radeon_buffer *radeon_get_pixmap_bo(PixmapPtr pPix)
{
#ifdef USE_GLAMOR
RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
......@@ -905,6 +898,7 @@ radeon_pixmap_get_fb(PixmapPtr pix)
return *fb_ptr;
}
#define CP_PACKET0(reg, n) \
(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
#define CP_PACKET1(reg0, reg1) \
......@@ -1013,7 +1007,7 @@ do { \
#define EMIT_OFFSET(reg, value, pPix, rd, wd) do { \
driver_priv = exaGetPixmapDriverPrivate(pPix); \
OUT_RING_REG((reg), (value)); \
OUT_RING_RELOC(driver_priv->bo, (rd), (wd)); \
OUT_RING_RELOC(driver_priv->bo->bo.radeon, (rd), (wd)); \
} while(0)
#define EMIT_READ_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, (RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT), 0)
......@@ -1027,7 +1021,7 @@ do { \
#define EMIT_COLORPITCH(reg, value, pPix) do { \
driver_priv = exaGetPixmapDriverPrivate(pPix); \
OUT_RING_REG((reg), value); \
OUT_RING_RELOC(driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); \
OUT_RING_RELOC(driver_priv->bo->bo.radeon, 0, RADEON_GEM_DOMAIN_VRAM); \
} while(0)
static __inline__ void RADEON_SYNC(RADEONInfoPtr info, ScrnInfoPtr pScrn)
......
......@@ -28,6 +28,37 @@
#include "radeon_glamor.h"
#include "radeon_bo_gem.h"
#ifdef USE_GLAMOR
static uint32_t
radeon_get_gbm_format(int depth, int bitsPerPixel)
{
switch (depth) {
#ifdef GBM_FORMAT_R8
case 8:
return GBM_FORMAT_R8;
#endif
case 16:
return GBM_FORMAT_RGB565;
case 32:
return GBM_FORMAT_ARGB8888;
case 30:
return GBM_FORMAT_XRGB2101010;
case 24:
if (bitsPerPixel == 32)
return GBM_FORMAT_XRGB8888;
/* fall through */
default:
ErrorF("%s: Unsupported depth/bpp %d/%d\n", __func__, depth,
bitsPerPixel);
return ~0U;
}
}
#endif /* USE_GLAMOR */
static const unsigned MicroBlockTable[5][3][2] = {
/*linear tiled square-tiled */
{{32, 1}, {8, 4}, {0, 0}}, /* 8 bits per pixel */
......@@ -59,10 +90,93 @@ static Bool RADEONMacroSwitch(int width, int height, int bpp,
}
}
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_surface_initialize(RADEONInfoPtr info, struct radeon_surface *surface,
int width, int height, int cpp, uint32_t tiling_flags,
int usage_hint)
{
memset(surface, 0, sizeof(struct radeon_surface));
surface->npix_x = width;
/* need to align height to 8 for old kernel */
surface->npix_y = RADEON_ALIGN(height, 8);
surface->npix_z = 1;
surface->blk_w = 1;
surface->blk_h = 1;
surface->blk_d = 1;
surface->array_size = 1;
surface->last_level = 0;
surface->bpe = cpp;
surface->nsamples = 1;
if (height < 128) {
/* disable 2d tiling for small surface to work around
* the fact that ddx align height to 8 pixel for old
* obscure reason i can't remember
*/
tiling_flags &= ~RADEON_TILING_MACRO;
}
surface->flags = RADEON_SURF_SCANOUT | RADEON_SURF_HAS_TILE_MODE_INDEX |
RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
if (usage_hint & RADEON_CREATE_PIXMAP_SZBUFFER) {
surface->flags |= RADEON_SURF_ZBUFFER;
surface->flags |= RADEON_SURF_SBUFFER;
}
if ((tiling_flags & RADEON_TILING_MACRO)) {
surface->flags = RADEON_SURF_CLR(surface->flags, MODE);
surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
} else if ((tiling_flags & RADEON_TILING_MICRO)) {
surface->flags = RADEON_SURF_CLR(surface->flags, MODE);
surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
} else
surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
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);
if (surface->flags & RADEON_SURF_SBUFFER) {
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;
if (radeon_surface_init(info->surf_man, surface))
return FALSE;
return TRUE;
}
/* Calculate appropriate tiling and pitch for a pixmap and allocate a BO that
* can hold it.
*/
struct radeon_bo*
struct radeon_buffer *
radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
int usage_hint, int bitsPerPixel, int *new_pitch,
struct radeon_surface *new_surface, uint32_t *new_tiling)
......@@ -73,8 +187,48 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
int cpp = bitsPerPixel / 8;
uint32_t tiling = 0, flags = 0;
struct radeon_surface surface;
struct radeon_bo *bo;
struct radeon_buffer *bo;
int domain = RADEON_GEM_DOMAIN_VRAM;
#ifdef USE_GLAMOR
if (info->use_glamor &&
!(usage_hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP &&
info->shadow_primary)) {
uint32_t bo_use = GBM_BO_USE_RENDERING;
uint32_t gbm_format = radeon_get_gbm_format(depth, bitsPerPixel);
if (gbm_format == ~0U)
return NULL;
bo = calloc(1, sizeof(struct radeon_buffer));
if (!bo)
return NULL;
bo->ref_count = 1;
if (bitsPerPixel == pScrn->bitsPerPixel)
bo_use |= GBM_BO_USE_SCANOUT;
if ((usage_hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP &&
info->shadow_primary) ||
(usage_hint & 0xffff) == CREATE_PIXMAP_USAGE_SHARED)
bo_use |= GBM_BO_USE_LINEAR;
bo->bo.gbm = gbm_bo_create(info->gbm, width, height, gbm_format, bo_use);
if (!bo->bo.gbm) {
free(bo);
return NULL;
}
bo->flags |= RADEON_BO_FLAGS_GBM;
if (new_pitch)
*new_pitch = gbm_bo_get_stride(bo->bo.gbm);
return bo;
}
#endif
if (usage_hint) {
if (info->allowColorTiling) {
if (usage_hint & RADEON_CREATE_PIXMAP_TILING_MACRO)
......@@ -107,51 +261,12 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
pitch = RADEON_ALIGN(width, drmmode_get_pitch_align(pScrn, cpp, tiling)) * cpp;
base_align = drmmode_get_base_align(pScrn, cpp, tiling);
size = RADEON_ALIGN(heighta * pitch, RADEON_GPU_PAGE_SIZE);
memset(&surface, 0, sizeof(struct radeon_surface));
if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) {
if (width) {
surface.npix_x = width;
/* need to align height to 8 for old kernel */
surface.npix_y = RADEON_ALIGN(height, 8);
surface.npix_z = 1;
surface.blk_w = 1;
surface.blk_h = 1;
surface.blk_d = 1;
surface.array_size = 1;
surface.last_level = 0;
surface.bpe = cpp;
surface.nsamples = 1;
if (height < 128) {
/* disable 2d tiling for small surface to work around
* the fact that ddx align height to 8 pixel for old
* obscure reason i can't remember
*/
tiling &= ~RADEON_TILING_MACRO;
}
surface.flags = RADEON_SURF_SCANOUT;
/* 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 & RADEON_TILING_MICRO)) {
surface.flags = RADEON_SURF_CLR(surface.flags, MODE);
surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
}
if ((tiling & RADEON_TILING_MACRO)) {
surface.flags = RADEON_SURF_CLR(surface.flags, MODE);
surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
}
if (usage_hint & RADEON_CREATE_PIXMAP_SZBUFFER) {
surface.flags |= RADEON_SURF_ZBUFFER;
surface.flags |= RADEON_SURF_SBUFFER;
}
if (radeon_surface_best(info->surf_man, &surface)) {
return NULL;
}
if (radeon_surface_init(info->surf_man, &surface)) {
if (width && info->surf_man) {
if (!radeon_surface_initialize(info, &surface, width, height, cpp,
tiling, usage_hint))
return NULL;
}
size = surface.bo_size;
base_align = surface.bo_alignment;
pitch = surface.level[0].pitch_bytes;
......@@ -164,6 +279,7 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
tiling |= surface.mtilea << RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT;
if (surface.tile_split)
tiling |= eg_tile_split(surface.tile_split) << RADEON_TILING_EG_TILE_SPLIT_SHIFT;
if (surface.flags & RADEON_SURF_SBUFFER)
tiling |= eg_tile_split(surface.stencil_tile_split) << RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT;
break;
case RADEON_SURF_MODE_1D:
......@@ -172,23 +288,46 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
default:
break;
}
}
if (new_surface)
*new_surface = surface;
}
if (tiling)
flags |= RADEON_GEM_NO_CPU_ACCESS;
bo = radeon_bo_open(info->bufmgr, 0, size, base_align,
bo = calloc(1, sizeof(struct radeon_buffer));
if (!bo)
return NULL;
bo->ref_count = 1;
bo->bo.radeon = radeon_bo_open(info->bufmgr, 0, size, base_align,
domain, flags);
if (bo && tiling && radeon_bo_set_tiling(bo, tiling, pitch) == 0)
if (bo && tiling && radeon_bo_set_tiling(bo->bo.radeon, tiling, pitch) == 0)
*new_tiling = tiling;
*new_surface = surface;
*new_pitch = pitch;
return bo;
}
/* Flush and wait for the BO to become idle */
void
radeon_finish(ScrnInfoPtr scrn, struct radeon_buffer *bo)
{
RADEONInfoPtr info = RADEONPTR(scrn);
if (info->use_glamor) {
radeon_glamor_finish(scrn);
return;
}
radeon_cs_flush_indirect(scrn);
radeon_bo_wait(bo->bo.radeon);
}
/* Clear the pixmap contents to black */
void
radeon_pixmap_clear(PixmapPtr pixmap)
......@@ -213,7 +352,7 @@ radeon_pixmap_clear(PixmapPtr pixmap)
/* Get GEM handle for the pixmap */
Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle)
{
struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap);
struct radeon_buffer *bo = radeon_get_pixmap_bo(pixmap);
#ifdef USE_GLAMOR
ScreenPtr screen = pixmap->drawable.pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
......@@ -221,8 +360,8 @@ Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle)
RADEONInfoPtr info = RADEONPTR(scrn);
#endif
if (bo) {
*handle = bo->handle;
if (bo && !(bo->flags & RADEON_BO_FLAGS_GBM)) {
*handle = bo->bo.radeon->handle;
return TRUE;
}
......@@ -305,87 +444,85 @@ 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)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen);
RADEONInfoPtr info = RADEONPTR(pScrn);
struct radeon_bo *bo;
struct radeon_buffer *bo;
int ihandle = (int)(long)fd_handle;
uint32_t size = ppix->devKind * ppix->drawable.height;
Bool ret = FALSE;
bo = radeon_gem_bo_open_prime(info->bufmgr, ihandle, size);
if (ihandle == -1)
return radeon_set_pixmap_bo(ppix, NULL);
bo = (struct radeon_buffer *)calloc(1, sizeof(struct radeon_buffer));
if (!bo)
goto error;
memset(surface, 0, sizeof(struct radeon_surface));
#ifdef USE_GLAMOR
if (info->use_glamor) {
struct gbm_import_fd_data data;
uint32_t bo_use = GBM_BO_USE_RENDERING;
ret = radeon_set_pixmap_bo(ppix, bo);
if (!ret)
data.format = radeon_get_gbm_format(ppix->drawable.depth,
ppix->drawable.bitsPerPixel);
if (data.format == ~0U)
goto error;
if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) {
uint32_t tiling_flags;
bo->ref_count = 1;
#ifdef USE_GLAMOR
if (info->use_glamor) {
tiling_flags = radeon_get_pixmap_private(ppix)->tiling_flags;
} else
data.fd = ihandle;
data.width = ppix->drawable.width;
data.height = ppix->drawable.height;
data.stride = ppix->devKind;
if (ppix->drawable.bitsPerPixel == pScrn->bitsPerPixel)
bo_use |= GBM_BO_USE_SCANOUT;
bo->bo.gbm = gbm_bo_import(info->gbm, GBM_BO_IMPORT_FD, &data, bo_use);
if (!bo->bo.gbm)
goto error;
bo->flags |= RADEON_BO_FLAGS_GBM;
if (!radeon_glamor_create_textured_pixmap(ppix, bo)) {
radeon_buffer_unref(&bo);
return FALSE;
}
ret = radeon_set_pixmap_bo(ppix, bo);
/* radeon_set_pixmap_bo increments ref_count if it succeeds */
radeon_buffer_unref(&bo);
return ret;
}
#endif
{
bo->bo.radeon = radeon_gem_bo_open_prime(info->bufmgr, ihandle, size);
if (!bo)
goto error;
bo->ref_count = 1;
ret = radeon_set_pixmap_bo(ppix, bo);
if (!ret)
goto error;
if (surface) {
struct radeon_exa_pixmap_priv *driver_priv;
uint32_t tiling_flags;
driver_priv = exaGetPixmapDriverPrivate(ppix);
tiling_flags = driver_priv->tiling_flags;
}
surface->npix_x = ppix->drawable.width;
surface->npix_y = ppix->drawable.height;
surface->npix_z = 1;
surface->blk_w = 1;
surface->blk_h = 1;
surface->blk_d = 1;
surface->array_size = 1;
surface->bpe = ppix->drawable.bitsPerPixel / 8;
surface->nsamples = 1;
/* 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);
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)) {
ret = FALSE;
goto error;
}
if (radeon_surface_init(info->surf_man, surface)) {
if (!radeon_surface_initialize(info, surface, ppix->drawable.width,
ppix->drawable.height,
ppix->drawable.bitsPerPixel / 8,
tiling_flags, 0)) {
ret = FALSE;
goto error;
}
/* we have to post hack the surface to reflect the actual size
of the shared pixmap */
surface->level[0].pitch_bytes = ppix->devKind;
......@@ -396,6 +533,6 @@ Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle,
close(ihandle);
/* we have a reference from the alloc and one from set pixmap bo,
drop one */
radeon_bo_unref(bo);
radeon_buffer_unref(&bo);
return ret;
}
......@@ -23,11 +23,31 @@
#ifndef RADEON_BO_HELPER_H
#define RADEON_BO_HELPER_H 1
extern struct radeon_bo*
#ifdef USE_GLAMOR
#include <gbm.h>
#endif
#define RADEON_BO_FLAGS_GBM 0x1
struct radeon_buffer {
union {
#ifdef USE_GLAMOR
struct gbm_bo *gbm;
#endif
struct radeon_bo *radeon;
} bo;
uint32_t ref_count;
uint32_t flags;
};
extern struct radeon_buffer *
radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
int usage_hint, int bitsPerPixel, int *new_pitch,
struct radeon_surface *new_surface, uint32_t *new_tiling);
extern void
radeon_finish(ScrnInfoPtr scrn, struct radeon_buffer *bo);
extern void
radeon_pixmap_clear(PixmapPtr pixmap);
......@@ -57,4 +77,37 @@ static inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable)
return drawable->pScreen->GetWindowPixmap((WindowPtr)drawable);
}
static inline void
radeon_buffer_ref(struct radeon_buffer *buffer)
{
buffer->ref_count++;
}
static inline void
radeon_buffer_unref(struct radeon_buffer **buffer)
{
struct radeon_buffer *buf = *buffer;
if (!buf)
return;
if (buf->ref_count > 1) {
buf->ref_count--;
return;
}
#ifdef USE_GLAMOR
if (buf->flags & RADEON_BO_FLAGS_GBM) {
gbm_bo_destroy(buf->bo.gbm);
} else
#endif
{
radeon_bo_unmap(buf->bo.radeon);
radeon_bo_unref(buf->bo.radeon);
}
free(buf);
*buffer = NULL;
}
#endif /* RADEON_BO_HELPER_H */
......@@ -79,11 +79,12 @@ static DevPrivateKeyRec dri2_window_private_key_rec;
static Bool
radeon_get_flink_name(RADEONEntPtr pRADEONEnt, PixmapPtr pixmap, uint32_t *name)
{
struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap);
struct radeon_buffer *bo = radeon_get_pixmap_bo(pixmap);
struct drm_gem_flink flink;
if (bo)
return radeon_gem_get_kernel_name(bo, name) == 0;
if (bo && !(bo->flags & RADEON_BO_FLAGS_GBM) &&
radeon_gem_get_kernel_name(bo->bo.radeon, name) == 0)
return TRUE;
if (radeon_get_pixmap_handle(pixmap, &flink.handle)) {
if (drmIoctl(pRADEONEnt->fd, DRM_IOCTL_GEM_FLINK, &flink) != 0)
......@@ -233,16 +234,18 @@ radeon_dri2_create_buffer2(ScreenPtr pScreen,
flags | RADEON_CREATE_PIXMAP_DRI2);
}
if (!pixmap)
return NULL;
buffers = calloc(1, sizeof *buffers);
if (buffers == NULL)
if (!buffers)
goto error;
if (pixmap) {
if (!info->use_glamor) {
info->exa_force_create = TRUE;
exaMoveInPixmap(pixmap);
info->exa_force_create = FALSE;
if (exaGetPixmapDriverPrivate(pixmap) == NULL) {
if (!exaGetPixmapDriverPrivate(pixmap)) {
/* this happen if pixmap is non accelerable */
goto error;
}
......@@ -253,17 +256,14 @@ radeon_dri2_create_buffer2(ScreenPtr pScreen,
if (!radeon_get_flink_name(pRADEONEnt, pixmap, &buffers->name))
goto error;
}
privates = calloc(1, sizeof(struct dri2_buffer_priv));
if (privates == NULL)
if (!privates)
goto error;
buffers->attachment = attachment;
if (pixmap) {
buffers->pitch = pixmap->devKind;
buffers->cpp = cpp;
}
buffers->driverPrivate = privates;
buffers->format = format;
buffers->flags = 0; /* not tiled */
......@@ -275,7 +275,6 @@ radeon_dri2_create_buffer2(ScreenPtr pScreen,
error:
free(buffers);
if (pixmap)
(*pScreen->DestroyPixmap)(pixmap);
return NULL;
}
......@@ -338,9 +337,7 @@ radeon_dri2_copy_region2(ScreenPtr pScreen,
Bool vsync;
Bool translate = FALSE;
int off_x = 0, off_y = 0;
PixmapPtr dst_ppix;
dst_ppix = dst_private->pixmap;
src_drawable = &src_private->pixmap->drawable;
dst_drawable = &dst_private->pixmap->drawable;
......@@ -357,7 +354,6 @@ radeon_dri2_copy_region2(ScreenPtr pScreen,
dst_drawable = DRI2UpdatePrime(drawable, dest_buffer);
if (!dst_drawable)
return;
dst_ppix = (PixmapPtr)dst_drawable;
if (dst_drawable != drawable)
translate = TRUE;
} else
......@@ -381,26 +377,7 @@ radeon_dri2_copy_region2(ScreenPtr pScreen,
(*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0);
ValidateGC(dst_drawable, gc);
/* If this is a full buffer swap or frontbuffer flush, throttle on the
* previous one
*/
if (dst_private->attachment == DRI2BufferFrontLeft) {
if (REGION_NUM_RECTS(region) == 1) {
BoxPtr extents = REGION_EXTENTS(pScreen, region);
if (extents->x1 == 0 && extents->y1 == 0 &&
extents->x2 == drawable->width &&
extents->y2 == drawable->height) {
struct radeon_bo *bo = radeon_get_pixmap_bo(dst_ppix);
if (bo)
radeon_bo_wait(bo);
}
}
}
vsync = info->accel_state->vsync;
/* Driver option "SwapbuffersWait" defines if we vsync DRI2 copy-swaps. */
info->accel_state->vsync = info->swapBuffersWait;
info->accel_state->force = TRUE;
......@@ -743,9 +720,8 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt
{
struct dri2_buffer_priv *front_priv = front->driverPrivate;
struct dri2_buffer_priv *back_priv = back->driverPrivate;
struct radeon_bo *front_bo, *back_bo;
ScreenPtr screen;
RADEONInfoPtr info;
ScreenPtr screen = draw->pScreen;
RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen));
RegionRec region;
int tmp;
......@@ -760,23 +736,28 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt
front->name = back->name;
back->name = tmp;
/* Swap pixmap bos */
front_bo = radeon_get_pixmap_bo(front_priv->pixmap);
back_bo = radeon_get_pixmap_bo(back_priv->pixmap);
radeon_set_pixmap_bo(front_priv->pixmap, back_bo);
radeon_set_pixmap_bo(back_priv->pixmap, front_bo);
/* Swap pixmap privates */
#ifdef USE_GLAMOR
if (info->use_glamor) {
struct radeon_pixmap *front_pix, *back_pix;
/* Do we need to update the Screen? */
screen = draw->pScreen;
info = RADEONPTR(xf86ScreenToScrn(screen));
if (front_bo == info->front_bo) {
radeon_bo_ref(back_bo);
radeon_bo_unref(info->front_bo);
info->front_bo = back_bo;
radeon_set_pixmap_bo(screen->GetScreenPixmap(screen), back_bo);
}
front_pix = radeon_get_pixmap_private(front_priv->pixmap);
back_pix = radeon_get_pixmap_private(back_priv->pixmap);
radeon_set_pixmap_private(front_priv->pixmap, back_pix);
radeon_set_pixmap_private(back_priv->pixmap, front_pix);
radeon_glamor_exchange_buffers(front_priv->pixmap, back_priv->pixmap);
} else
#endif
{
struct radeon_exa_pixmap_priv driver_priv = *(struct radeon_exa_pixmap_priv*)
exaGetPixmapDriverPrivate(front_priv->pixmap);
*(struct radeon_exa_pixmap_priv*)exaGetPixmapDriverPrivate(front_priv->pixmap) =
*(struct radeon_exa_pixmap_priv*)exaGetPixmapDriverPrivate(back_priv->pixmap);
*(struct radeon_exa_pixmap_priv*)exaGetPixmapDriverPrivate(back_priv->pixmap) =
driver_priv;
}
DamageRegionProcessPending(&front_priv->pixmap->drawable);
}
......@@ -942,7 +923,7 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE);
/* Drawable not displayed, make up a value */
if (crtc == NULL) {
if (!crtc) {
*ust = 0;
*msc = 0;
return TRUE;
......@@ -987,12 +968,14 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
scrn = crtc->scrn;
pRADEONEnt = RADEONEntPriv(scrn);
drmmode_crtc = event_info->crtc->driver_private;
ret = drmmode_get_current_ust(pRADEONEnt->fd, &drm_now);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"%s cannot get current time\n", __func__);
if (event_info->drm_queue_seq)
radeon_drm_queue_handler(pRADEONEnt->fd, 0, 0, 0,
drmmode_crtc->drmmode->event_context.
vblank_handler(pRADEONEnt->fd, 0, 0, 0,
(void*)event_info->drm_queue_seq);
else
radeon_dri2_frame_event_handler(crtc, 0, 0, data);
......@@ -1002,13 +985,13 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
* calculate the frame number from current time
* that would come from CRTC if it were running
*/
drmmode_crtc = event_info->crtc->driver_private;
delta_t = drm_now - (CARD64)drmmode_crtc->dpms_last_ust;
delta_seq = delta_t * drmmode_crtc->dpms_last_fps;
delta_seq /= 1000000;
frame = (CARD64)drmmode_crtc->dpms_last_seq + delta_seq;
if (event_info->drm_queue_seq)
radeon_drm_queue_handler(pRADEONEnt->fd, frame, drm_now / 1000000,
drmmode_crtc->drmmode->event_context.
vblank_handler(pRADEONEnt->fd, frame, drm_now / 1000000,
drm_now % 1000000,
(void*)event_info->drm_queue_seq);
else
......@@ -1053,7 +1036,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
remainder &= 0xffffffff;
/* Drawable not visible, return immediately */
if (crtc == NULL)
if (!crtc)
goto out_complete;
msc_delta = radeon_get_msc_delta(draw, crtc);
......@@ -1212,7 +1195,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
radeon_dri2_ref_buffer(back);
/* either off-screen or CRTC not usable... just complete the swap */
if (crtc == NULL)
if (!crtc)
goto blit_fallback;
msc_delta = radeon_get_msc_delta(draw, crtc);
......
......@@ -169,6 +169,7 @@ static PixmapPtr radeon_dri3_pixmap_from_fd(ScreenPtr screen,
if (priv) {
radeon_set_pixmap_private(pixmap, priv);
pixmap->usage_hint |= RADEON_CREATE_PIXMAP_DRI2;
return pixmap;
}
......@@ -213,9 +214,6 @@ static int radeon_dri3_fd_from_pixmap(ScreenPtr screen,
{
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);
......@@ -224,8 +222,10 @@ static int radeon_dri3_fd_from_pixmap(ScreenPtr screen,
return glamor_fd_from_pixmap(screen, pixmap, stride, size);
#endif
bo = radeon_get_pixmap_bo(pixmap)->bo.radeon;
if (!bo) {
exaMoveInPixmap(pixmap);
bo = radeon_get_pixmap_bo(pixmap);
bo = radeon_get_pixmap_bo(pixmap)->bo.radeon;
if (!bo)
return -1;
}
......
......@@ -40,6 +40,7 @@
struct radeon_drm_queue_entry {
struct xorg_list list;
uint64_t usec;
uint64_t id;
uintptr_t seq;
void *data;
......@@ -47,38 +48,99 @@ struct radeon_drm_queue_entry {
xf86CrtcPtr crtc;
radeon_drm_handler_proc handler;
radeon_drm_abort_proc abort;
unsigned int frame;
};
static int radeon_drm_queue_refcnt;
static struct xorg_list radeon_drm_queue;
static struct xorg_list radeon_drm_flip_signalled;
static struct xorg_list radeon_drm_vblank_signalled;
static uintptr_t radeon_drm_queue_seq;
/*
* Handle a DRM event
* Process a DRM event
*/
void
radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int sec,
unsigned int usec, void *user_ptr)
static void
radeon_drm_queue_handle_one(struct radeon_drm_queue_entry *e)
{
xorg_list_del(&e->list);
if (e->handler) {
e->handler(e->crtc, e->frame, e->usec, e->data);
} else
e->abort(e->crtc, e->data);
free(e);
}
static void
radeon_drm_queue_handler(struct xorg_list *signalled, unsigned int frame,
unsigned int sec, unsigned int usec, void *user_ptr)
{
uintptr_t seq = (uintptr_t)user_ptr;
struct radeon_drm_queue_entry *e, *tmp;
xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) {
if (e->seq == seq) {
if (!e->handler) {
radeon_drm_queue_handle_one(e);
break;
}
xorg_list_del(&e->list);
if (e->handler)
e->handler(e->crtc, frame,
(uint64_t)sec * 1000000 + usec,
e->data);
else
e->abort(e->crtc, e->data);
free(e);
e->usec = (uint64_t)sec * 1000000 + usec;
e->frame = frame;
xorg_list_append(&e->list, signalled);
break;
}
}
}
/*
* Signal a DRM page flip event
*/
static void
radeon_drm_page_flip_handler(int fd, unsigned int frame, unsigned int sec,
unsigned int usec, void *user_ptr)
{
radeon_drm_queue_handler(&radeon_drm_flip_signalled, frame, sec, usec,
user_ptr);
}
/*
* Signal a DRM vblank event
*/
static void
radeon_drm_vblank_handler(int fd, unsigned int frame, unsigned int sec,
unsigned int usec, void *user_ptr)
{
radeon_drm_queue_handler(&radeon_drm_vblank_signalled, frame, sec, usec,
user_ptr);
}
/*
* Handle deferred DRM vblank events
*
* This function must be called after radeon_drm_wait_pending_flip, once
* it's safe to attempt queueing a flip again
*/
void
radeon_drm_queue_handle_deferred(xf86CrtcPtr crtc)
{
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
struct radeon_drm_queue_entry *e, *tmp;
if (drmmode_crtc->wait_flip_nesting_level == 0 ||
--drmmode_crtc->wait_flip_nesting_level > 0)
return;
xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_signalled, list) {
drmmode_crtc_private_ptr drmmode_crtc = e->crtc->driver_private;
if (drmmode_crtc->wait_flip_nesting_level == 0)
radeon_drm_queue_handle_one(e);
}
}
/*
* Enqueue a potential drm response; when the associated response
* appears, we've got data to pass to the handler from here
......@@ -150,6 +212,16 @@ radeon_drm_abort_entry(uintptr_t seq)
{
struct radeon_drm_queue_entry *e, *tmp;
if (seq == RADEON_DRM_QUEUE_ERROR)
return;
xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_signalled, list) {
if (e->seq == seq) {
radeon_drm_abort_one(e);
return;
}
}
xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) {
if (e->seq == seq) {
radeon_drm_abort_one(e);
......@@ -174,16 +246,75 @@ radeon_drm_abort_id(uint64_t id)
}
}
/*
* drmHandleEvent wrapper
*/
int
radeon_drm_handle_event(int fd, drmEventContext *event_context)
{
struct radeon_drm_queue_entry *e, *tmp;
int r;
r = drmHandleEvent(fd, event_context);
while (!xorg_list_is_empty(&radeon_drm_flip_signalled)) {
e = xorg_list_first_entry(&radeon_drm_flip_signalled,
struct radeon_drm_queue_entry, list);
radeon_drm_queue_handle_one(e);
}
xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_signalled, list) {
drmmode_crtc_private_ptr drmmode_crtc = e->crtc->driver_private;
if (drmmode_crtc->wait_flip_nesting_level == 0)
radeon_drm_queue_handle_one(e);
}
return r;
}
/*
* Wait for pending page flip on given CRTC to complete
*/
void radeon_drm_wait_pending_flip(xf86CrtcPtr crtc)
{
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn);
struct radeon_drm_queue_entry *e;
drmmode_crtc->wait_flip_nesting_level++;
while (drmmode_crtc->flip_pending &&
!xorg_list_is_empty(&radeon_drm_flip_signalled)) {
e = xorg_list_first_entry(&radeon_drm_flip_signalled,
struct radeon_drm_queue_entry, list);
radeon_drm_queue_handle_one(e);
}
while (drmmode_crtc->flip_pending
&& radeon_drm_handle_event(pRADEONEnt->fd,
&drmmode_crtc->drmmode->event_context) > 0);
}
/*
* Initialize the DRM event queue
*/
void
radeon_drm_queue_init()
radeon_drm_queue_init(ScrnInfoPtr scrn)
{
RADEONInfoPtr info = RADEONPTR(scrn);
drmmode_ptr drmmode = &info->drmmode;
drmmode->event_context.version = 2;
drmmode->event_context.vblank_handler = radeon_drm_vblank_handler;
drmmode->event_context.page_flip_handler = radeon_drm_page_flip_handler;
if (radeon_drm_queue_refcnt++)
return;
xorg_list_init(&radeon_drm_queue);
xorg_list_init(&radeon_drm_flip_signalled);
xorg_list_init(&radeon_drm_vblank_signalled);
}
/*
......
......@@ -40,9 +40,7 @@ typedef void (*radeon_drm_handler_proc)(xf86CrtcPtr crtc, uint32_t seq,
uint64_t usec, void *data);
typedef void (*radeon_drm_abort_proc)(xf86CrtcPtr crtc, void *data);
void radeon_drm_queue_handler(int fd, unsigned int frame,
unsigned int tv_sec, unsigned int tv_usec,
void *user_ptr);
void radeon_drm_queue_handle_deferred(xf86CrtcPtr crtc);
uintptr_t radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client,
uint64_t id, void *data,
radeon_drm_handler_proc handler,
......@@ -50,7 +48,9 @@ uintptr_t radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client,
void radeon_drm_abort_client(ClientPtr client);
void radeon_drm_abort_entry(uintptr_t seq);
void radeon_drm_abort_id(uint64_t id);
void radeon_drm_queue_init();
int radeon_drm_handle_event(int fd, drmEventContext *event_context);
void radeon_drm_wait_pending_flip(xf86CrtcPtr crtc);
void radeon_drm_queue_init(ScrnInfoPtr scrn);
void radeon_drm_queue_close(ScrnInfoPtr scrn);
#endif /* _RADEON_DRM_QUEUE_H_ */