diff options
-rw-r--r-- | configure.ac | 10 | ||||
-rw-r--r-- | man/radeon.man | 16 | ||||
-rw-r--r-- | src/drmmode_display.c | 89 | ||||
-rw-r--r-- | src/drmmode_display.h | 6 | ||||
-rw-r--r-- | src/radeon.h | 2 | ||||
-rw-r--r-- | src/radeon_bo_helper.c | 7 | ||||
-rw-r--r-- | src/radeon_dri3.c | 15 | ||||
-rw-r--r-- | src/radeon_glamor.c | 60 | ||||
-rw-r--r-- | src/radeon_glamor.h | 10 | ||||
-rw-r--r-- | src/radeon_kms.c | 179 |
10 files changed, 372 insertions, 22 deletions
diff --git a/configure.ac b/configure.ac index 57b4c1ca..4ca53525 100644 --- a/configure.ac +++ b/configure.ac @@ -125,6 +125,16 @@ else fi AM_CONDITIONAL(GLAMOR, test x$GLAMOR != xno) +AC_CHECK_DECL(fbGlyphs, + [AC_DEFINE(HAVE_FBGLYPHS, 1, [Have fbGlyphs API])], [], + [#include <X11/Xmd.h> + #include <X11/Xfuncproto.h> + #include <X11/extensions/renderproto.h> + #include <xorg-server.h> + #include <picture.h> + #include <glyphstr.h> + #include <fbpict.h>]) + AC_CHECK_DECL(xorg_list_init, [AC_DEFINE(HAVE_XORG_LIST, 1, [Have xorg_list API])], [], [#include <X11/Xdefs.h> diff --git a/man/radeon.man b/man/radeon.man index 6e46f894..27037730 100644 --- a/man/radeon.man +++ b/man/radeon.man @@ -290,6 +290,22 @@ as of TAHITI, otherwise The following driver .B Options are supported for +.B glamor +: +.TP +.BI "Option \*qShadowPrimary\*q \*q" boolean \*q +This option enables a so-called "shadow primary" buffer for fast CPU access to +pixel data, and separate scanout buffers for each display controller (CRTC). +This may improve performance for some 2D workloads, potentially at the expense +of other (e.g. 3D, video) workloads. +Note in particular that enabling this option currently disables page flipping. +The default is +.B off. + +.PP +The following driver +.B Options +are supported for .B EXA : .TP diff --git a/src/drmmode_display.c b/src/drmmode_display.c index d8d3ca36..1f228698 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -33,6 +33,7 @@ #include <sys/ioctl.h> #include <time.h> #include "cursorstr.h" +#include "damagestr.h" #include "micmap.h" #include "xf86cmap.h" #include "radeon.h" @@ -489,6 +490,26 @@ drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, } +void +drmmode_scanout_free(ScrnInfoPtr scrn) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int c; + + for (c = 0; c < xf86_config->num_crtc; c++) { + drmmode_crtc_private_ptr drmmode_crtc = + xf86_config->crtc[c]->driver_private; + + drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, + &drmmode_crtc->scanout); + + if (drmmode_crtc->scanout_damage) { + DamageDestroy(drmmode_crtc->scanout_damage); + drmmode_crtc->scanout_damage = NULL; + } + } +} + static void * drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, @@ -510,6 +531,13 @@ drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc, return NULL; } + if (scanout->bo) { + if (scanout->width == width && scanout->height == height) + return scanout->bo->ptr; + + drmmode_crtc_scanout_destroy(drmmode, scanout); + } + rotate_pitch = RADEON_ALIGN(width, drmmode_get_pitch_align(pScrn, drmmode->cpp, 0)) * drmmode->cpp; @@ -531,6 +559,8 @@ drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc, if (ret) ErrorF("failed to add scanout fb\n"); + scanout->width = width; + scanout->height = height; return scanout->bo->ptr; } @@ -543,6 +573,13 @@ drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, drmmode_ptr drmmode = drmmode_crtc->drmmode; unsigned long rotate_pitch; + if (scanout->pixmap) { + if (scanout->width == width && scanout->height == height) + return scanout->pixmap; + + drmmode_crtc_scanout_destroy(drmmode, scanout); + } + if (!data) data = drmmode_crtc_scanout_allocate(crtc, scanout, width, height); @@ -562,6 +599,14 @@ drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, return scanout->pixmap; } +static void +radeon_screen_damage_report(DamagePtr damage, RegionPtr region, void *closure) +{ + /* Only keep track of the extents */ + RegionUninit(&damage->damage); + damage->damage.data = NULL; +} + static Bool drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, int x, int y) @@ -631,6 +676,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, } if (mode) { + ScreenPtr pScreen = pScrn->pScreen; + for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; drmmode_output_private_ptr drmmode_output; @@ -656,11 +703,46 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, if (crtc->randr_crtc && crtc->randr_crtc->scanout_pixmap) { x = drmmode_crtc->prime_pixmap_x; y = 0; + + drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout); } else #endif if (drmmode_crtc->rotate.fb_id) { fb_id = drmmode_crtc->rotate.fb_id; x = y = 0; + + drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout); + } else if (info->shadow_primary) { + drmmode_crtc_scanout_create(crtc, + &drmmode_crtc->scanout, + NULL, mode->HDisplay, + mode->VDisplay); + + if (drmmode_crtc->scanout.pixmap) { + RegionPtr pRegion; + BoxPtr pBox; + + if (!drmmode_crtc->scanout_damage) { + drmmode_crtc->scanout_damage = + DamageCreate(radeon_screen_damage_report, + NULL, DamageReportRawRegion, + TRUE, pScreen, NULL); + DamageRegister(&pScreen->GetScreenPixmap(pScreen)->drawable, + drmmode_crtc->scanout_damage); + } + + pRegion = DamageRegion(drmmode_crtc->scanout_damage); + RegionUninit(pRegion); + pRegion->data = NULL; + pBox = RegionExtents(pRegion); + pBox->x1 = min(pBox->x1, x); + pBox->y1 = min(pBox->y1, y); + pBox->x2 = max(pBox->x2, x + mode->HDisplay); + pBox->y2 = max(pBox->y2, y + mode->VDisplay); + + fb_id = drmmode_crtc->scanout.fb_id; + x = y = 0; + } } ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, fb_id, x, y, output_ids, output_count, &kmode); @@ -1689,7 +1771,7 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) if (front_bo) radeon_bo_wait(front_bo); - if (info->allowColorTiling) { + if (info->allowColorTiling && !info->shadow_primary) { if (info->ChipFamily >= CHIP_FAMILY_R600) { if (info->allowColorTiling2D) { tiling_flags |= RADEON_TILING_MACRO; @@ -1770,7 +1852,10 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) scrn->virtualY = height; scrn->displayWidth = pitch / cpp; - info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size, base_align, RADEON_GEM_DOMAIN_VRAM, 0); + info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size, base_align, + info->shadow_primary ? + RADEON_GEM_DOMAIN_GTT : + RADEON_GEM_DOMAIN_VRAM, 0); if (!info->front_bo) goto fail; diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 66078962..43a3a4a3 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -76,6 +76,7 @@ struct drmmode_scanout { struct radeon_bo *bo; PixmapPtr pixmap; unsigned fb_id; + int width, height; }; typedef struct { @@ -84,6 +85,9 @@ typedef struct { int hw_id; struct radeon_bo *cursor_bo; struct drmmode_scanout rotate; + struct drmmode_scanout scanout; + DamagePtr scanout_damage; + Bool scanout_update_pending; int dpms_mode; CARD64 dpms_last_ust; uint32_t dpms_last_seq; @@ -125,6 +129,8 @@ extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode); extern void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode); extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn); +extern void drmmode_scanout_free(ScrnInfoPtr scrn); + extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode); extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode); diff --git a/src/radeon.h b/src/radeon.h index 80adc5d6..afb66b26 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -151,6 +151,7 @@ typedef enum { OPTION_SWAPBUFFERS_WAIT, OPTION_DELETE_DP12, OPTION_DRI3, + OPTION_SHADOW_PRIMARY, } RADEONOpts; @@ -476,6 +477,7 @@ typedef struct { struct radeon_accel_state *accel_state; Bool accelOn; Bool use_glamor; + Bool shadow_primary; Bool exa_pixmaps; Bool exa_force_create; XF86ModReqInfo exaReq; diff --git a/src/radeon_bo_helper.c b/src/radeon_bo_helper.c index fdff0328..ebbb192a 100644 --- a/src/radeon_bo_helper.c +++ b/src/radeon_bo_helper.c @@ -88,12 +88,15 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, if (usage_hint & RADEON_CREATE_PIXMAP_DEPTH) tiling |= RADEON_TILING_MACRO | RADEON_TILING_MICRO; + if ((usage_hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP && + info->shadow_primary) #ifdef CREATE_PIXMAP_USAGE_SHARED - if ((usage_hint & 0xffff) == CREATE_PIXMAP_USAGE_SHARED) { + || (usage_hint & 0xffff) == CREATE_PIXMAP_USAGE_SHARED +#endif + ) { tiling = 0; domain = RADEON_GEM_DOMAIN_GTT; } -#endif } /* Small pixmaps must not be macrotiled on R300, hw cannot sample them diff --git a/src/radeon_dri3.c b/src/radeon_dri3.c index 3a7322e5..1415a0df 100644 --- a/src/radeon_dri3.c +++ b/src/radeon_dri3.c @@ -101,8 +101,17 @@ static PixmapPtr radeon_dri3_pixmap_from_fd(ScreenPtr screen, if (RADEONPTR(xf86ScreenToScrn(screen))->use_glamor) { pixmap = glamor_pixmap_from_fd(screen, fd, width, height, stride, depth, bpp); - if (pixmap) - return pixmap; + if (pixmap) { + struct radeon_pixmap *priv = + calloc(1, sizeof(struct radeon_pixmap)); + + if (priv) { + radeon_set_pixmap_private(pixmap, priv); + return pixmap; + } + + screen->DestroyPixmap(pixmap); + } } #endif @@ -118,7 +127,7 @@ static PixmapPtr radeon_dri3_pixmap_from_fd(ScreenPtr screen, return NULL; } - pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0); + pixmap = screen->CreatePixmap(screen, 0, 0, depth, RADEON_CREATE_PIXMAP_DRI2); if (!pixmap) return NULL; diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index 74d9584b..eccb8f7c 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -166,26 +166,24 @@ radeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_pixmap *pri priv->stride); } -#ifndef CREATE_PIXMAP_USAGE_SHARED -#define CREATE_PIXMAP_USAGE_SHARED RADEON_CREATE_PIXMAP_DRI2 -#endif - -#define RADEON_CREATE_PIXMAP_SHARED(usage) \ - (((usage) & ~RADEON_CREATE_PIXMAP_TILING_FLAGS) == RADEON_CREATE_PIXMAP_DRI2 || \ - (usage) == CREATE_PIXMAP_USAGE_SHARED) - static PixmapPtr radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned usage) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + RADEONInfoPtr info = RADEONPTR(scrn); struct radeon_pixmap *priv; PixmapPtr pixmap, new_pixmap = NULL; if (!RADEON_CREATE_PIXMAP_SHARED(usage)) { - pixmap = glamor_create_pixmap(screen, w, h, depth, usage); - if (pixmap) - return pixmap; + if (info->shadow_primary) { + if (usage != CREATE_PIXMAP_USAGE_BACKING_PIXMAP) + return fbCreatePixmap(screen, w, h, depth, usage); + } else { + pixmap = glamor_create_pixmap(screen, w, h, depth, usage); + if (pixmap) + return pixmap; + } } if (w > 32767 || h > 32767) @@ -220,6 +218,8 @@ radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, if (!radeon_glamor_create_textured_pixmap(pixmap, priv)) goto fallback_glamor; + + pixmap->devPrivate.ptr = NULL; } return pixmap; @@ -258,6 +258,13 @@ fallback_pixmap: static Bool radeon_glamor_destroy_pixmap(PixmapPtr pixmap) { if (pixmap->refcnt == 1) { + if (pixmap->devPrivate.ptr) { + struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap); + + if (bo) + radeon_bo_unmap(bo); + } + glamor_egl_destroy_textured_pixmap(pixmap); radeon_set_pixmap_bo(pixmap, NULL); } @@ -316,6 +323,26 @@ Bool radeon_glamor_init(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + RADEONInfoPtr info = RADEONPTR(scrn); +#ifdef RENDER +#ifdef HAVE_FBGLYPHS + UnrealizeGlyphProcPtr SavedUnrealizeGlyph = NULL; +#endif + PictureScreenPtr ps = NULL; + + if (info->shadow_primary) { + ps = GetPictureScreenIfSet(screen); + + if (ps) { +#ifdef HAVE_FBGLYPHS + SavedUnrealizeGlyph = ps->UnrealizeGlyph; +#endif + info->glamor.SavedGlyphs = ps->Glyphs; + info->glamor.SavedTriangles = ps->Triangles; + info->glamor.SavedTrapezoids = ps->Trapezoids; + } + } +#endif /* RENDER */ if (!glamor_init(screen, GLAMOR_USE_EGL_SCREEN | GLAMOR_USE_SCREEN | GLAMOR_USE_PICTURE_SCREEN | GLAMOR_INVERTED_Y_AXIS | @@ -338,6 +365,17 @@ radeon_glamor_init(ScreenPtr screen) #endif return FALSE; + if (info->shadow_primary) + radeon_glamor_screen_init(screen); + +#if defined(RENDER) && defined(HAVE_FBGLYPHS) + /* For ShadowPrimary, we need fbUnrealizeGlyph instead of + * glamor_unrealize_glyph + */ + if (ps) + ps->UnrealizeGlyph = SavedUnrealizeGlyph; +#endif + screen->CreatePixmap = radeon_glamor_create_pixmap; screen->DestroyPixmap = radeon_glamor_destroy_pixmap; #ifdef RADEON_PIXMAP_SHARING diff --git a/src/radeon_glamor.h b/src/radeon_glamor.h index ea385c76..1ba7049a 100644 --- a/src/radeon_glamor.h +++ b/src/radeon_glamor.h @@ -35,6 +35,16 @@ #include "radeon_surface.h" +#ifndef CREATE_PIXMAP_USAGE_SHARED +#define CREATE_PIXMAP_USAGE_SHARED RADEON_CREATE_PIXMAP_DRI2 +#endif + +#define RADEON_CREATE_PIXMAP_SHARED(usage) \ + (((usage) & ~RADEON_CREATE_PIXMAP_TILING_FLAGS) == RADEON_CREATE_PIXMAP_DRI2 || \ + (usage) == CREATE_PIXMAP_USAGE_SHARED) + +struct radeon_pixmap; + #ifndef GLAMOR_NO_DRI3 #define GLAMOR_NO_DRI3 0 #define glamor_fd_from_pixmap glamor_dri3_fd_from_pixmap diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 3f723d55..64593ab1 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -70,6 +70,7 @@ const OptionInfoRec RADEONOptions_KMS[] = { { OPTION_SUBPIXEL_ORDER, "SubPixelOrder", OPTV_ANYSTR, {0}, FALSE }, #ifdef USE_GLAMOR { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, + { OPTION_SHADOW_PRIMARY, "ShadowPrimary", OPTV_BOOLEAN, {0}, FALSE }, #endif { OPTION_EXA_VSYNC, "EXAVSync", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_EXA_PIXMAPS, "EXAPixmaps", OPTV_BOOLEAN, {0}, FALSE }, @@ -308,6 +309,142 @@ radeon_dirty_update(ScreenPtr screen) } #endif +static Bool +radeon_scanout_extents_intersect(BoxPtr extents, int x, int y, int w, int h) +{ + extents->x1 = max(extents->x1 - x, 0); + extents->y1 = max(extents->y1 - y, 0); + extents->x2 = min(extents->x2 - x, w); + extents->y2 = min(extents->y2 - y, h); + + return (extents->x1 < extents->x2 && extents->y1 < extents->y2); +} + +static void +radeon_scanout_update_abort(ScrnInfoPtr scrn, void *event_data) +{ + xf86CrtcPtr xf86_crtc = event_data; + drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; + + drmmode_crtc->scanout_update_pending = FALSE; +} + +static void +radeon_scanout_update_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec, + void *event_data) +{ + xf86CrtcPtr xf86_crtc = event_data; + drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; + DamagePtr pDamage; + RegionPtr pRegion; + DrawablePtr pDraw; + ScreenPtr pScreen; + GCPtr gc; + BoxRec extents; + RADEONInfoPtr info; + Bool force; + + if (!drmmode_crtc->scanout.pixmap || + drmmode_crtc->dpms_mode != DPMSModeOn) + goto out; + + pDamage = drmmode_crtc->scanout_damage; + if (!pDamage) + goto out; + + pRegion = DamageRegion(pDamage); + if (!RegionNotEmpty(pRegion)) + goto out; + + pDraw = &drmmode_crtc->scanout.pixmap->drawable; + extents = *RegionExtents(pRegion); + if (!radeon_scanout_extents_intersect(&extents, xf86_crtc->x, xf86_crtc->y, + pDraw->width, pDraw->height)) + goto clear_damage; + + pScreen = pDraw->pScreen; + gc = GetScratchGC(pDraw->depth, pScreen); + info = RADEONPTR(scrn); + force = info->accel_state->force; + info->accel_state->force = TRUE; + + ValidateGC(pDraw, gc); + (*gc->ops->CopyArea)(&pScreen->GetScreenPixmap(pScreen)->drawable, + pDraw, gc, + xf86_crtc->x + extents.x1, xf86_crtc->y + extents.y1, + extents.x2 - extents.x1, extents.y2 - extents.y1, + extents.x1, extents.y1); + FreeScratchGC(gc); + + info->accel_state->force = force; + + radeon_cs_flush_indirect(scrn); + +clear_damage: + RegionEmpty(pRegion); + +out: + drmmode_crtc->scanout_update_pending = FALSE; +} + +static void +radeon_scanout_update(xf86CrtcPtr xf86_crtc) +{ + drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; + struct radeon_drm_queue_entry *drm_queue_entry; + ScrnInfoPtr scrn; + drmVBlank vbl; + DamagePtr pDamage; + RegionPtr pRegion; + DrawablePtr pDraw; + BoxRec extents; + + if (drmmode_crtc->scanout_update_pending || + !drmmode_crtc->scanout.pixmap || + drmmode_crtc->dpms_mode != DPMSModeOn) + return; + + pDamage = drmmode_crtc->scanout_damage; + if (!pDamage) + return; + + pRegion = DamageRegion(pDamage); + if (!RegionNotEmpty(pRegion)) + return; + + pDraw = &drmmode_crtc->scanout.pixmap->drawable; + extents = *RegionExtents(pRegion); + if (!radeon_scanout_extents_intersect(&extents, xf86_crtc->x, xf86_crtc->y, + pDraw->width, pDraw->height)) + return; + + scrn = xf86_crtc->scrn; + drm_queue_entry = radeon_drm_queue_alloc(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, + RADEON_DRM_QUEUE_ID_DEFAULT, + xf86_crtc, + radeon_scanout_update_handler, + radeon_scanout_update_abort); + if (!drm_queue_entry) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "radeon_drm_queue_alloc failed for scanout update\n"); + return; + } + + vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT; + vbl.request.type |= radeon_populate_vbl_request_type(xf86_crtc); + vbl.request.sequence = 1; + vbl.request.signal = (unsigned long)drm_queue_entry; + if (drmWaitVBlank(RADEONPTR(scrn)->dri2.drm_fd, &vbl)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "drmWaitVBlank failed for scanout update: %s\n", + strerror(errno)); + radeon_drm_abort_entry(drm_queue_entry); + return; + } + + drmmode_crtc->scanout_update_pending = TRUE; +} + static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) { SCREEN_PTR(arg); @@ -318,7 +455,16 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); pScreen->BlockHandler = RADEONBlockHandler_KMS; + if (info->shadow_primary) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int c; + + for (c = 0; c < xf86_config->num_crtc; c++) + radeon_scanout_update(xf86_config->crtc[c]); + } + radeon_cs_flush_indirect(pScrn); + #ifdef RADEON_PIXMAP_SHARING radeon_dirty_update(pScreen); #endif @@ -936,11 +1082,32 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "KMS Color Tiling 2D: %sabled\n", info->allowColorTiling2D ? "en" : "dis"); +#if USE_GLAMOR + if (info->use_glamor) { + info->shadow_primary = xf86ReturnOptValBool(info->Options, + OPTION_SHADOW_PRIMARY, FALSE); + + if (info->shadow_primary) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowPrimary enabled\n"); + } +#endif + if (info->dri2.pKernelDRMVersion->version_minor >= 8) { info->allowPageFlip = xf86ReturnOptValBool(info->Options, OPTION_PAGE_FLIP, TRUE); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "KMS Pageflipping: %sabled\n", info->allowPageFlip ? "en" : "dis"); +#if USE_GLAMOR + if (info->shadow_primary) { + xf86DrvMsg(pScrn->scrnIndex, + info->allowPageFlip ? X_WARNING : X_DEFAULT, + "KMS Pageflipping: disabled%s\n", + info->allowPageFlip ? " because of ShadowPrimary" : ""); + info->allowPageFlip = FALSE; + } else +#endif + { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "KMS Pageflipping: %sabled\n", info->allowPageFlip ? "en" : "dis"); + } } info->swapBuffersWait = xf86ReturnOptValBool(info->Options, @@ -1506,6 +1673,7 @@ void RADEONLeaveVT_KMS(VT_FUNC_ARGS_DECL) radeon_drop_drm_master(pScrn); xf86RotateFreeShadow(pScrn); + drmmode_scanout_free(pScrn); xf86_hide_cursors (pScrn); info->accel_state->XInited3D = FALSE; @@ -1556,7 +1724,7 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) } } - if (info->allowColorTiling) { + if (info->allowColorTiling && !info->shadow_primary) { if (info->ChipFamily >= CHIP_FAMILY_R600) { if (info->allowColorTiling2D) { tiling_flags |= RADEON_TILING_MACRO; @@ -1659,7 +1827,10 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) if (info->front_bo == NULL) { info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size, - base_align, RADEON_GEM_DOMAIN_VRAM, 0); + base_align, + info->shadow_primary ? + RADEON_GEM_DOMAIN_GTT : + RADEON_GEM_DOMAIN_VRAM, 0); if (info->r600_shadow_fb == TRUE) { if (radeon_bo_map(info->front_bo, 1)) { ErrorF("Failed to map cursor buffer memory\n"); |