diff options
author | Dave Airlie <airlied@redhat.com> | 2012-09-03 13:08:05 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-09-03 13:08:05 +1000 |
commit | 8c1bf9d8fe3948b72795984e625ef46b2f0bf654 (patch) | |
tree | 56b361130b3ca459aceb98400acfa936fca6d10b /src | |
parent | 3add8df8122697acfe126d4857f3946ce44b8305 (diff) |
radeon: add pixmap sharing hooks.
This hooks into EXA and the dirty tracking to add sharing and output
offload support.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/evergreen_exa.c | 5 | ||||
-rw-r--r-- | src/evergreen_state.h | 2 | ||||
-rw-r--r-- | src/r600_exa.c | 4 | ||||
-rw-r--r-- | src/r600_state.h | 4 | ||||
-rw-r--r-- | src/radeon.h | 4 | ||||
-rw-r--r-- | src/radeon_exa.c | 75 | ||||
-rw-r--r-- | src/radeon_exa_funcs.c | 4 | ||||
-rw-r--r-- | src/radeon_kms.c | 40 |
8 files changed, 134 insertions, 4 deletions
diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c index 40e2e96e..883fa5ce 100644 --- a/src/evergreen_exa.c +++ b/src/evergreen_exa.c @@ -1908,7 +1908,10 @@ EVERGREENDrawInit(ScreenPtr pScreen) #if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 5) info->accel_state->exa->CreatePixmap2 = RADEONEXACreatePixmap2; #endif - +#if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 6) + info->accel_state->exa->SharePixmapBacking = RADEONEXASharePixmapBacking; + info->accel_state->exa->SetSharedPixmapBacking = RADEONEXASetSharedPixmapBacking; +#endif info->accel_state->exa->flags = EXA_OFFSCREEN_PIXMAPS; #ifdef EXA_SUPPORTS_PREPARE_AUX info->accel_state->exa->flags |= EXA_SUPPORTS_PREPARE_AUX; diff --git a/src/evergreen_state.h b/src/evergreen_state.h index c92393ec..3ce2bf2b 100644 --- a/src/evergreen_state.h +++ b/src/evergreen_state.h @@ -350,5 +350,7 @@ extern void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, 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); #endif diff --git a/src/r600_exa.c b/src/r600_exa.c index be0a9fae..21df084d 100644 --- a/src/r600_exa.c +++ b/src/r600_exa.c @@ -1888,6 +1888,10 @@ R600DrawInit(ScreenPtr pScreen) info->accel_state->exa->DownloadFromScreen = R600DownloadFromScreenCS; #if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 5) info->accel_state->exa->CreatePixmap2 = RADEONEXACreatePixmap2; +#if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 6) + info->accel_state->exa->SharePixmapBacking = RADEONEXASharePixmapBacking; + info->accel_state->exa->SetSharedPixmapBacking = RADEONEXASetSharedPixmapBacking; +#endif #endif #endif diff --git a/src/r600_state.h b/src/r600_state.h index 74b481cc..fa777e8b 100644 --- a/src/r600_state.h +++ b/src/r600_state.h @@ -321,6 +321,6 @@ extern void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, 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); #endif diff --git a/src/radeon.h b/src/radeon.h index 2eac38e5..b0676d40 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -527,6 +527,10 @@ extern void radeon_ddx_cs_start(ScrnInfoPtr pScrn, const char *func, int line); void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, int new_fb_size); +#if XF86_CRTC_VERSION >= 5 +#define RADEON_PIXMAP_SHARING 1 +#endif + static inline struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix) { #ifdef USE_GLAMOR diff --git a/src/radeon_exa.c b/src/radeon_exa.c index 5c5d9979..0c427355 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -41,7 +41,7 @@ #include "radeon_probe.h" #include "radeon_version.h" #include "radeon_exa_shared.h" - +#include "radeon_bo_gem.h" #include "xf86.h" @@ -325,6 +325,79 @@ void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv) free(driverPriv); } +#ifdef RADEON_PIXMAP_SHARING +Bool RADEONEXASharePixmapBacking(PixmapPtr ppix, ScreenPtr slave, void **fd_handle) +{ + struct radeon_exa_pixmap_priv *driver_priv; + int ret; + int handle; + + driver_priv = exaGetPixmapDriverPrivate(ppix); + + ret = radeon_gem_prime_share_bo(driver_priv->bo, &handle); + if (ret) + return FALSE; + + driver_priv->shared = TRUE; + *fd_handle = (void *)(long)handle; + return TRUE; +} + +Bool RADEONEXASetSharedPixmapBacking(PixmapPtr ppix, void *fd_handle) +{ + ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen); + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_exa_pixmap_priv *driver_priv; + struct radeon_bo *bo; + int ihandle = (int)(long)fd_handle; + uint32_t size = ppix->devKind * ppix->drawable.height; + struct radeon_surface surface; + + driver_priv = exaGetPixmapDriverPrivate(ppix); + + bo = radeon_gem_bo_open_prime(info->bufmgr, ihandle, size); + if (!bo) + return FALSE; + + memset(&surface, 0, sizeof(struct radeon_surface)); + + if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) { + + 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; + surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); + surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE); + if (radeon_surface_best(info->surf_man, &surface)) { + return FALSE; + } + if (radeon_surface_init(info->surf_man, &surface)) { + return FALSE; + } + /* we have to post hack the surface to reflect the actual size + of the shared pixmap */ + surface.level[0].pitch_bytes = ppix->devKind; + surface.level[0].nblk_x = ppix->devKind / surface.bpe; + } + driver_priv->surface = surface; + driver_priv->shared = TRUE; + driver_priv->tiling_flags = 0; + radeon_set_pixmap_bo(ppix, bo); + + close(ihandle); + /* we have a reference from the alloc and one from set pixmap bo, + drop one */ + radeon_bo_unref(bo); + return TRUE; +} +#endif + uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix) { struct radeon_exa_pixmap_priv *driver_priv; diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c index db44d948..2533d786 100644 --- a/src/radeon_exa_funcs.c +++ b/src/radeon_exa_funcs.c @@ -655,6 +655,10 @@ Bool RADEONDrawInit(ScreenPtr pScreen) info->accel_state->exa->FinishAccess = RADEONFinishAccess_CS; #if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 5) info->accel_state->exa->CreatePixmap2 = RADEONEXACreatePixmap2; +#if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 6) + info->accel_state->exa->SharePixmapBacking = RADEONEXASharePixmapBacking; + info->accel_state->exa->SetSharedPixmapBacking = RADEONEXASetSharedPixmapBacking; +#endif #endif #endif diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 21076408..09aea7e4 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -241,6 +241,40 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen) return TRUE; } +#ifdef RADEON_PIXMAP_SHARING +static void +redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty) +{ + ScrnInfoPtr pScrn = xf86ScreenToScrn(screen); + RegionRec pixregion; + + PixmapRegionInit(&pixregion, dirty->slave_dst->master_pixmap); + PixmapSyncDirtyHelper(dirty, &pixregion); + + radeon_cs_flush_indirect(pScrn); + DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion); + RegionUninit(&pixregion); +} + +static void +radeon_dirty_update(ScreenPtr screen) +{ + RegionPtr region; + PixmapDirtyUpdatePtr ent; + + if (xorg_list_is_empty(&screen->pixmap_dirty_list)) + return; + + xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) { + region = DamageRegion(ent->damage); + if (RegionNotEmpty(region)) { + redisplay_dirty(screen, ent); + DamageEmpty(ent->damage); + } + } +} +#endif + static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) { SCREEN_PTR(arg); @@ -255,6 +289,7 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) radeon_glamor_flush(pScrn); radeon_cs_flush_indirect(pScrn); + radeon_dirty_update(pScreen); } static void @@ -1242,6 +1277,11 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) info->CreateScreenResources = pScreen->CreateScreenResources; pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS; +#ifdef RADEON_PIXMAP_SHARING + pScreen->StartPixmapTracking = PixmapStartDirtyTracking; + pScreen->StopPixmapTracking = PixmapStopDirtyTracking; +#endif + if (!xf86CrtcScreenInit (pScreen)) return FALSE; |