summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-09-03 13:08:05 +1000
committerDave Airlie <airlied@redhat.com>2012-09-03 13:08:05 +1000
commit8c1bf9d8fe3948b72795984e625ef46b2f0bf654 (patch)
tree56b361130b3ca459aceb98400acfa936fca6d10b /src
parent3add8df8122697acfe126d4857f3946ce44b8305 (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.c5
-rw-r--r--src/evergreen_state.h2
-rw-r--r--src/r600_exa.c4
-rw-r--r--src/r600_state.h4
-rw-r--r--src/radeon.h4
-rw-r--r--src/radeon_exa.c75
-rw-r--r--src/radeon_exa_funcs.c4
-rw-r--r--src/radeon_kms.c40
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;