xf86-video-ati: Branch 'master' - 8 commits

Dave Airlie airlied at kemper.freedesktop.org
Sun Sep 2 20:10:39 PDT 2012


 src/ati.c              |   26 ++++++++
 src/drmmode_display.c  |    4 +
 src/evergreen_exa.c    |   15 ++++-
 src/evergreen_state.h  |    2 
 src/r600_exa.c         |   14 ++++
 src/r600_state.h       |    4 -
 src/radeon.h           |   23 +++++++
 src/radeon_bo_helper.c |   10 ++-
 src/radeon_dri2.c      |  146 +++++++++++++++++++++++++++++++++++++------------
 src/radeon_exa.c       |   75 ++++++++++++++++++++++++-
 src/radeon_exa_funcs.c |   13 +++-
 src/radeon_kms.c       |   66 +++++++++++++++++++++-
 src/radeon_probe.c     |   81 ++++++++++++++++++++++++++-
 13 files changed, 429 insertions(+), 50 deletions(-)

New commits:
commit 75c1f62f44d7b3709c1fa103d59733866967b841
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Sep 3 13:09:02 2012 +1000

    radeon: add capability and provider support
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 6a35728..9b9fc83 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1549,6 +1549,10 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
 	/* workout clones */
 	drmmode_clones_init(pScrn, drmmode);
 
+#ifdef RADEON_PIXMAP_SHARING
+	xf86ProviderSetup(pScrn, NULL, "radeon");
+#endif
+
 	xf86InitialConfiguration(pScrn, TRUE);
 
 	drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION;
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 09aea7e..81cb5ba 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -715,6 +715,24 @@ static Bool r600_get_tile_config(ScrnInfoPtr pScrn)
 
 #endif /* EXA_MIXED_PIXMAPS */
 
+static void RADEONSetupCapabilities(ScrnInfoPtr pScrn)
+{
+#ifdef RADEON_PIXMAP_SHARING
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    uint64_t value;
+    int ret;
+
+    pScrn->capabilities = 0;
+    ret = drmGetCap(info->dri2.drm_fd, DRM_CAP_PRIME, &value);
+    if (ret == 0) {
+	if (value & DRM_PRIME_CAP_EXPORT)
+	    pScrn->capabilities |= RR_Capability_SourceOutput | RR_Capability_SinkOffload;
+	if (value & DRM_PRIME_CAP_IMPORT)
+	    pScrn->capabilities |= RR_Capability_SourceOffload;
+    }
+#endif
+}
+
 Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 {
     RADEONInfoPtr     info;
@@ -797,6 +815,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 
     info->allowColorTiling2D = FALSE;
 
+    RADEONSetupCapabilities(pScrn);
 #ifdef EXA_MIXED_PIXMAPS
     /* don't enable tiling if accel is not enabled */
     if (!info->r600_shadow_fb) {
commit ca8b61e916998458203dfa4b9d0c997fa7d90ba9
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Sep 3 13:08:37 2012 +1000

    radeon: allocated shared pixmaps as untiled gtt.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/radeon_bo_helper.c b/src/radeon_bo_helper.c
index ccdf7eb..593c690 100644
--- a/src/radeon_bo_helper.c
+++ b/src/radeon_bo_helper.c
@@ -73,7 +73,7 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
     uint32_t tiling = 0;
     struct radeon_surface surface;
     struct radeon_bo *bo;
-
+    int domain = RADEON_GEM_DOMAIN_VRAM;
     if (usage_hint) {
 	if (info->allowColorTiling) {
 	    if (usage_hint & RADEON_CREATE_PIXMAP_TILING_MACRO)
@@ -84,6 +84,12 @@ 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;
 
+#ifdef CREATE_PIXMAP_USAGE_SHARED
+	if ((usage_hint & 0xffff) == CREATE_PIXMAP_USAGE_SHARED) {
+		tiling = 0;
+		domain = RADEON_GEM_DOMAIN_GTT;
+	}
+#endif
     }
 
     /* Small pixmaps must not be macrotiled on R300, hw cannot sample them
@@ -166,7 +172,7 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
 	}
 
     bo = radeon_bo_open(info->bufmgr, 0, size, base_align,
-			RADEON_GEM_DOMAIN_VRAM, 0);
+			domain, 0);
 
     if (bo && tiling && radeon_bo_set_tiling(bo, tiling, pitch) == 0)
 	*new_tiling = tiling;
commit 8c1bf9d8fe3948b72795984e625ef46b2f0bf654
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Sep 3 13:08:05 2012 +1000

    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 at redhat.com>

diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c
index 40e2e96..883fa5c 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 c92393e..3ce2bf2 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 be0a9fa..21df084 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 74b481c..fa777e8 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 2eac38e..b0676d4 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 5c5d997..0c42735 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 db44d94..2533d78 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 2107640..09aea7e 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;
 
commit 3add8df8122697acfe126d4857f3946ce44b8305
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Sep 3 13:07:07 2012 +1000

    radeon: add dri2 offload support.
    
    This adds the new dri2 interfaces required for radeon to be offloaded to.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 496c669..f6f5fd5 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -315,11 +315,11 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
 }
 #else
 static BufferPtr
-radeon_dri2_create_buffer(DrawablePtr drawable,
-                          unsigned int attachment,
-                          unsigned int format)
+radeon_dri2_create_buffer2(ScreenPtr pScreen,
+			   DrawablePtr drawable,
+			   unsigned int attachment,
+			   unsigned int format)
 {
-    ScreenPtr pScreen = drawable->pScreen;
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
     RADEONInfoPtr info = RADEONPTR(pScrn);
     BufferPtr buffers;
@@ -340,7 +340,9 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
 
     if (attachment == DRI2BufferFrontLeft) {
         pixmap = get_drawable_pixmap(drawable);
-	if (info->use_glamor && !radeon_get_pixmap_bo(pixmap)) {
+	if (pScreen != pixmap->drawable.pScreen)
+	    pixmap = NULL;
+	else if (info->use_glamor && !radeon_get_pixmap_bo(pixmap)) {
 	    is_glamor_pixmap = TRUE;
 	    aligned_width = pixmap->drawable.width;
 	    height = pixmap->drawable.height;
@@ -352,7 +354,7 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
         pixmap->refcnt++;
     }
 
-    if (!pixmap) {
+    if (!pixmap && attachment != DRI2BufferFrontLeft) {
 	/* tile the back buffer */
 	switch(attachment) {
 	case DRI2BufferDepth:
@@ -425,9 +427,6 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
 					      flags | RADEON_CREATE_PIXMAP_DRI2);
     }
 
-    if (!pixmap)
-        return NULL;
-
     buffers = calloc(1, sizeof *buffers);
     if (buffers == NULL)
         goto error;
@@ -435,24 +434,30 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
     if (attachment == DRI2BufferDepth) {
         depth_pixmap = pixmap;
     }
-    if (!info->use_glamor) {
-	info->exa_force_create = TRUE;
-	exaMoveInPixmap(pixmap);
-	info->exa_force_create = FALSE;
+
+    if (pixmap) {
+	if (!info->use_glamor) {
+	    info->exa_force_create = TRUE;
+	    exaMoveInPixmap(pixmap);
+	    info->exa_force_create = FALSE;
+	}
+
+	if (is_glamor_pixmap)
+	    pixmap = fixup_glamor(drawable, pixmap);
+	bo = radeon_get_pixmap_bo(pixmap);
+	if (!bo || radeon_gem_get_kernel_name(bo, &buffers->name) != 0)
+	    goto error;
     }
-    if (is_glamor_pixmap)
-	pixmap = fixup_glamor(drawable, pixmap);
-    bo = radeon_get_pixmap_bo(pixmap);
-    if (!bo || radeon_gem_get_kernel_name(bo, &buffers->name) != 0)
-        goto error;
 
     privates = calloc(1, sizeof(struct dri2_buffer_priv));
     if (privates == NULL)
         goto error;
 
     buffers->attachment = attachment;
-    buffers->pitch = pixmap->devKind;
-    buffers->cpp = pixmap->drawable.bitsPerPixel / 8;
+    if (pixmap) {
+	buffers->pitch = pixmap->devKind;
+	buffers->cpp = pixmap->drawable.bitsPerPixel / 8;
+    }
     buffers->driverPrivate = privates;
     buffers->format = format;
     buffers->flags = 0; /* not tiled */
@@ -468,6 +473,14 @@ error:
         (*pScreen->DestroyPixmap)(pixmap);
     return NULL;
 }
+
+DRI2BufferPtr
+radeon_dri2_create_buffer(DrawablePtr pDraw, unsigned int attachment,
+			   unsigned int format)
+{
+	return radeon_dri2_create_buffer2(pDraw->pScreen, pDraw,
+					  attachment, format);
+}
 #endif
 
 #ifndef USE_DRI2_1_1_0
@@ -491,11 +504,11 @@ radeon_dri2_destroy_buffers(DrawablePtr drawable,
 }
 #else
 static void
-radeon_dri2_destroy_buffer(DrawablePtr drawable, BufferPtr buffers)
+radeon_dri2_destroy_buffer2(ScreenPtr pScreen,
+			    DrawablePtr drawable, BufferPtr buffers)
 {
     if(buffers)
     {
-        ScreenPtr pScreen = drawable->pScreen;
         struct dri2_buffer_priv *private = buffers->driverPrivate;
 
         /* Trying to free an already freed buffer is unlikely to end well */
@@ -511,24 +524,41 @@ radeon_dri2_destroy_buffer(DrawablePtr drawable, BufferPtr buffers)
         private->refcnt--;
         if (private->refcnt == 0)
         {
-            (*pScreen->DestroyPixmap)(private->pixmap);
+	    if (private->pixmap)
+                (*pScreen->DestroyPixmap)(private->pixmap);
 
             free(buffers->driverPrivate);
             free(buffers);
         }
     }
 }
+
+void
+radeon_dri2_destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buf)
+{
+    radeon_dri2_destroy_buffer2(pDraw->pScreen, pDraw, buf);
+}
 #endif
 
+
+static inline PixmapPtr GetDrawablePixmap(DrawablePtr drawable)
+{
+    if (drawable->type == DRAWABLE_PIXMAP)
+        return (PixmapPtr)drawable;
+    else {
+        struct _Window *pWin = (struct _Window *)drawable;
+        return drawable->pScreen->GetWindowPixmap(pWin);
+    }
+}
 static void
-radeon_dri2_copy_region(DrawablePtr drawable,
-                        RegionPtr region,
-                        BufferPtr dest_buffer,
-                        BufferPtr src_buffer)
+radeon_dri2_copy_region2(ScreenPtr pScreen,
+			 DrawablePtr drawable,
+			 RegionPtr region,
+			 BufferPtr dest_buffer,
+			 BufferPtr src_buffer)
 {
     struct dri2_buffer_priv *src_private = src_buffer->driverPrivate;
     struct dri2_buffer_priv *dst_private = dest_buffer->driverPrivate;
-    ScreenPtr pScreen = drawable->pScreen;
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
     DrawablePtr src_drawable;
     DrawablePtr dst_drawable;
@@ -536,20 +566,42 @@ radeon_dri2_copy_region(DrawablePtr drawable,
     GCPtr gc;
     RADEONInfoPtr info = RADEONPTR(pScrn);
     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;
 
     if (src_private->attachment == DRI2BufferFrontLeft) {
         src_drawable = drawable;
-    } else {
-        src_drawable = &src_private->pixmap->drawable;
     }
     if (dst_private->attachment == DRI2BufferFrontLeft) {
-        dst_drawable = drawable;
-    } else {
-        dst_drawable = &dst_private->pixmap->drawable;
+	if (drawable->pScreen != pScreen) {
+	    dst_drawable = DRI2UpdatePrime(drawable, dest_buffer);
+	    if (!dst_drawable)
+		return;
+	    dst_ppix = (PixmapPtr)dst_drawable;
+	    if (dst_drawable != drawable)
+		translate = TRUE;
+	} else
+	    dst_drawable = drawable;
+    }
+
+    if (translate && drawable->type == DRAWABLE_WINDOW) {
+	WindowPtr pWin = (WindowPtr)drawable;
+	off_x = pWin->origin.x;
+	off_y = pWin->origin.y;
     }
     gc = GetScratchGC(dst_drawable->depth, pScreen);
     copy_clip = REGION_CREATE(pScreen, NULL, 0);
     REGION_COPY(pScreen, copy_clip, region);
+
+    if (translate) {
+	REGION_TRANSLATE(pScreen, copy_clip, off_x, off_y);
+    }
+
     (*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0);
     ValidateGC(dst_drawable, gc);
 
@@ -563,7 +615,7 @@ radeon_dri2_copy_region(DrawablePtr drawable,
 	    if (extents->x1 == 0 && extents->y1 == 0 &&
 		extents->x2 == drawable->width &&
 		extents->y2 == drawable->height) {
-		struct radeon_bo *bo = radeon_get_pixmap_bo(dst_private->pixmap);
+		struct radeon_bo *bo = radeon_get_pixmap_bo(dst_ppix);
 
 		if (bo)
 		    radeon_bo_wait(bo);
@@ -577,13 +629,20 @@ radeon_dri2_copy_region(DrawablePtr drawable,
     info->accel_state->vsync = info->swapBuffersWait;
 
     (*gc->ops->CopyArea)(src_drawable, dst_drawable, gc,
-                         0, 0, drawable->width, drawable->height, 0, 0);
+                         0, 0, drawable->width, drawable->height, off_x, off_y);
 
     info->accel_state->vsync = vsync;
 
     FreeScratchGC(gc);
 }
 
+void
+radeon_dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
+			 DRI2BufferPtr pDstBuffer, DRI2BufferPtr pSrcBuffer)
+{
+    return radeon_dri2_copy_region2(pDraw->pScreen, pDraw, pRegion,
+				     pDstBuffer, pSrcBuffer);
+}
 
 #ifdef USE_DRI2_SCHEDULING
 
@@ -1500,6 +1559,13 @@ radeon_dri2_screen_init(ScreenPtr pScreen)
     }
 #endif
 
+#if DRI2INFOREC_VERSION >= 9
+    dri2_info.version = 9;
+    dri2_info.CreateBuffer2 = radeon_dri2_create_buffer2;
+    dri2_info.DestroyBuffer2 = radeon_dri2_destroy_buffer2;
+    dri2_info.CopyRegion2 = radeon_dri2_copy_region2;
+#endif
+
     info->dri2.enabled = DRI2ScreenInit(pScreen, &dri2_info);
     return info->dri2.enabled;
 }
commit f7502a11c8ef9c453ceb40d26109977116df88c2
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Sep 3 12:56:56 2012 +1000

    radeon: add shared support to pixmaps.
    
    this just adds the interface and shared support to the pixmap.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c
index f906cbf..40e2e96 100644
--- a/src/evergreen_exa.c
+++ b/src/evergreen_exa.c
@@ -480,7 +480,10 @@ EVERGREENPrepareCopy(PixmapPtr pSrc,   PixmapPtr pDst,
     dst_obj.width = pDst->drawable.width;
     dst_obj.height = pDst->drawable.height;
     dst_obj.bpp = pDst->drawable.bitsPerPixel;
-    dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
+    if (radeon_get_pixmap_shared(pDst) == TRUE)
+	dst_obj.domain = RADEON_GEM_DOMAIN_GTT;
+    else
+	dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
 
     if (!R600SetAccelState(pScrn,
 			   &src_obj,
@@ -1157,7 +1160,10 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture,
     dst_obj.width = pDst->drawable.width;
     dst_obj.height = pDst->drawable.height;
     dst_obj.bpp = pDst->drawable.bitsPerPixel;
-    dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
+    if (radeon_get_pixmap_shared(pDst) == TRUE)
+	dst_obj.domain = RADEON_GEM_DOMAIN_GTT;
+    else
+	dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
 
     if (pMaskPicture) {
 	if (!pMask) {
diff --git a/src/r600_exa.c b/src/r600_exa.c
index 61b6315..be0a9fa 100644
--- a/src/r600_exa.c
+++ b/src/r600_exa.c
@@ -551,7 +551,10 @@ R600PrepareCopy(PixmapPtr pSrc,   PixmapPtr pDst,
     dst_obj.width = pDst->drawable.width;
     dst_obj.height = pDst->drawable.height;
     dst_obj.bpp = pDst->drawable.bitsPerPixel;
-    dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
+    if (radeon_get_pixmap_shared(pDst) == TRUE) {
+	dst_obj.domain = RADEON_GEM_DOMAIN_GTT;
+    } else
+	dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
 
     if (!R600SetAccelState(pScrn,
 			   &src_obj,
@@ -1203,7 +1206,10 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
     dst_obj.width = pDst->drawable.width;
     dst_obj.height = pDst->drawable.height;
     dst_obj.bpp = pDst->drawable.bitsPerPixel;
-    dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
+    if (radeon_get_pixmap_shared(pDst) == TRUE)
+	dst_obj.domain = RADEON_GEM_DOMAIN_GTT;
+    else
+	dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
 
     if (pMaskPicture) {
 	if (!pMask) {
diff --git a/src/radeon.h b/src/radeon.h
index 2f05249..2eac38e 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -249,6 +249,7 @@ struct radeon_exa_pixmap_priv {
     uint32_t tiling_flags;
     struct radeon_surface surface;
     Bool bo_mapped;
+    Bool shared;
 };
 
 #define RADEON_2D_EXA_COPY 1
@@ -266,6 +267,7 @@ struct radeon_2d_state {
     uint32_t dp_src_frgd_clr;
     uint32_t dp_src_bkgd_clr;
     uint32_t default_sc_bottom_right;
+    uint32_t dst_domain;
     struct radeon_bo *dst_bo;
     struct radeon_bo *src_bo;
 };
@@ -624,6 +626,23 @@ static inline struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix)
     return NULL;
 }
 
+static inline Bool radeon_get_pixmap_shared(PixmapPtr pPix)
+{
+#ifdef USE_GLAMOR
+    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
+
+    if (info->use_glamor) {
+        ErrorF("glamor sharing todo\n");
+	return FALSE:
+    } else
+#endif
+    {
+	struct radeon_exa_pixmap_priv *driver_priv;
+	driver_priv = exaGetPixmapDriverPrivate(pPix);
+	return driver_priv->shared;
+    }
+    return FALSE;
+}
 
 #define CP_PACKET0(reg, n)						\
 	(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index 4c13a00..db44d94 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -80,7 +80,7 @@ static void Emit2DState(ScrnInfoPtr pScrn, int op)
     OUT_RING_REG(RADEON_DP_CNTL, info->state_2d.dp_cntl);
 
     OUT_RING_REG(RADEON_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset);
-    OUT_RING_RELOC(info->state_2d.dst_bo, 0, RADEON_GEM_DOMAIN_VRAM);
+    OUT_RING_RELOC(info->state_2d.dst_bo, 0, info->state_2d.dst_domain);
 
     if (has_src) {
 	OUT_RING_REG(RADEON_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset);
@@ -145,8 +145,10 @@ RADEONPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
 	RADEON_FALLBACK(("Not enough RAM to hw accel solid operation\n"));
 
     driver_priv = exaGetPixmapDriverPrivate(pPix);
-    if (driver_priv)
+    if (driver_priv) {
 	info->state_2d.dst_bo = driver_priv->bo;
+ 	info->state_2d.dst_domain = driver_priv->shared ? RADEON_GEM_DOMAIN_GTT : RADEON_GEM_DOMAIN_VRAM;
+    }
 
     info->state_2d.default_sc_bottom_right = (RADEON_DEFAULT_SC_RIGHT_MAX |
 					       RADEON_DEFAULT_SC_BOTTOM_MAX);
@@ -258,8 +260,9 @@ RADEONPrepareCopy(PixmapPtr pSrc,   PixmapPtr pDst,
     info->state_2d.src_bo = driver_priv->bo;
 
     driver_priv = exaGetPixmapDriverPrivate(pDst);
-    radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM);
     info->state_2d.dst_bo = driver_priv->bo;
+    info->state_2d.dst_domain = driver_priv->shared ? RADEON_GEM_DOMAIN_GTT : RADEON_GEM_DOMAIN_VRAM;
+    radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, info->state_2d.dst_domain);
 
     ret = radeon_cs_space_check(info->cs);
     if (ret)
commit f71139a2afe8fffb628331402bf829a6d67c9fff
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Sep 3 12:37:22 2012 +1000

    radeon: add platform bus loading support.
    
    This allows the radeon driver to be loaded via the platform bus mechanism.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index a4f46d7..2107640 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -698,7 +698,12 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
     info->IsSecondary  = FALSE;
     info->IsPrimary = FALSE;
     info->pEnt         = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
-    if (info->pEnt->location.type != BUS_PCI) goto fail;
+    if (info->pEnt->location.type != BUS_PCI
+#ifdef XSERVER_PLATFORM_BUS
+        && info->pEnt->location.type != BUS_PLATFORM
+#endif
+        )
+        goto fail;
 
     pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
 				 getRADEONEntityIndex());
diff --git a/src/radeon_probe.c b/src/radeon_probe.c
index 6ddfa88..b1471af 100644
--- a/src/radeon_probe.c
+++ b/src/radeon_probe.c
@@ -53,6 +53,10 @@
 #include "xf86drmMode.h"
 #include "dri.h"
 
+#ifdef XSERVER_PLATFORM_BUS
+#include <xf86platformBus.h>
+#endif
+
 #include "radeon_chipset_gen.h"
 
 #include "radeon_pci_chipset_gen.h"
@@ -255,6 +259,78 @@ RADEONDriverFunc(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data)
     }
 }
 
+#ifdef XSERVER_PLATFORM_BUS
+static Bool
+radeon_platform_probe(DriverPtr pDriver,
+		      int entity_num, int flags,
+		      struct xf86_platform_device *dev,
+		      intptr_t match_data)
+{
+    ScrnInfoPtr pScrn;
+    char *path = xf86_get_platform_device_attrib(dev, ODEV_ATTRIB_PATH);
+    int scr_flags = 0;
+    EntityInfoPtr pEnt;
+
+    if (!dev->pdev)
+	return FALSE;
+
+    if (flags & PLATFORM_PROBE_GPU_SCREEN)
+	scr_flags = XF86_ALLOCATE_GPU_SCREEN;
+
+    pScrn = xf86AllocateScreen(pDriver, scr_flags);
+    xf86AddEntityToScreen(pScrn, entity_num);
+
+    if (!radeon_kernel_mode_enabled(pScrn, dev->pdev))
+	return FALSE;
+
+    pScrn->driverVersion = RADEON_VERSION_CURRENT;
+    pScrn->driverName    = RADEON_DRIVER_NAME;
+    pScrn->name          = RADEON_NAME;
+    pScrn->Probe         = NULL;
+    pScrn->PreInit       = RADEONPreInit_KMS;
+    pScrn->ScreenInit    = RADEONScreenInit_KMS;
+    pScrn->SwitchMode    = RADEONSwitchMode_KMS;
+    pScrn->AdjustFrame   = RADEONAdjustFrame_KMS;
+    pScrn->EnterVT       = RADEONEnterVT_KMS;
+    pScrn->LeaveVT       = RADEONLeaveVT_KMS;
+    pScrn->FreeScreen    = RADEONFreeScreen_KMS;
+    pScrn->ValidMode     = RADEONValidMode;
+
+    pEnt = xf86GetEntityInfo(entity_num);
+
+    /* Create a RADEONEntity for all chips, even with old single head
+     * Radeon, need to use pRADEONEnt for new monitor detection routines.
+     */
+    {
+        DevUnion    *pPriv;
+        RADEONEntPtr pRADEONEnt;
+
+        xf86SetEntitySharable(entity_num);
+
+        if (gRADEONEntityIndex == -1)
+            gRADEONEntityIndex = xf86AllocateEntityPrivateIndex();
+
+        pPriv = xf86GetEntityPrivate(pEnt->index,
+                                     gRADEONEntityIndex);
+
+	xf86SetEntityInstanceForScreen(pScrn, pEnt->index, xf86GetNumEntityInstances(pEnt->index) - 1);
+
+        if (!pPriv->ptr) {
+            pPriv->ptr = xnfcalloc(sizeof(RADEONEntRec), 1);
+            pRADEONEnt = pPriv->ptr;
+            pRADEONEnt->HasSecondary = FALSE;
+        } else {
+            pRADEONEnt = pPriv->ptr;
+            pRADEONEnt->HasSecondary = TRUE;
+        }
+    }
+
+    free(pEnt);
+
+    return TRUE;
+}
+#endif
+
 _X_EXPORT DriverRec RADEON =
 {
     RADEON_VERSION_CURRENT,
@@ -271,6 +347,9 @@ _X_EXPORT DriverRec RADEON =
     RADEONDriverFunc,
 #ifdef XSERVER_LIBPCIACCESS
     radeon_device_match,
-    radeon_pci_probe
+    radeon_pci_probe,
+#endif
+#ifdef XSERVER_PLATFORM_BUS
+    radeon_platform_probe
 #endif
 };
commit 9911e72ea79e000ee0492d19a434aa98b83b5066
Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Aug 17 17:02:51 2012 +1000

    radeon: damage full screen after pageflip
    
    in order for offload to work we need to cause a full
    screen damage to be registered after pageflip.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 92241c7..496c669 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -864,6 +864,16 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt
     }
 
     radeon_glamor_exchange_buffers(front_priv->pixmap, back_priv->pixmap);
+
+    {
+        RegionRec region;
+	region.extents.x1 = region.extents.y1 = 0;
+	region.extents.x2 = front_priv->pixmap->drawable.width;
+	region.extents.y2 = front_priv->pixmap->drawable.width;
+	region.data = NULL;
+	DamageRegionAppend(&front_priv->pixmap->drawable, &region);
+	DamageRegionProcessPending(&front_priv->pixmap->drawable);
+    }
 }
 
 void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
commit 0873b8cef21abf1e7286731758f0db1e7f2e7c97
Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Aug 3 16:45:50 2012 +1000

    ati: fix stub driver loader to load all drivers properly
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/ati.c b/src/ati.c
index e1c136f..256fbd8 100644
--- a/src/ati.c
+++ b/src/ati.c
@@ -102,6 +102,7 @@ ati_device_get_from_busid(int bus, int dev, int func)
                                    func);
 }
 
+#ifndef XSERVER_PLATFORM_BUS
 static struct pci_device*
 ati_device_get_primary(void)
 {
@@ -119,6 +120,26 @@ ati_device_get_primary(void)
 
     return device;
 }
+#else
+static struct pci_device *
+ati_device_get_indexed(int index)
+{
+    struct pci_device *device = NULL;
+    struct pci_device_iterator *device_iter;
+    int count = 0;
+
+    device_iter = pci_slot_match_iterator_create(NULL);
+
+    while ((device = pci_device_next(device_iter)) != NULL) {
+        if (device->vendor_id == PCI_VENDOR_ATI) {
+            if (count == index)
+                return device;
+            count++;
+        }
+    }
+    return NULL;
+}
+#endif
 
 #else /* XSERVER_LIBPCIACCESS */
 
@@ -197,9 +218,14 @@ ati_gdev_subdriver(pointer options)
 
             device = ati_device_get_from_busid(bus, dev, func);
         }
+#ifdef XSERVER_PLATFORM_BUS
+        else
+            device = ati_device_get_indexed(i);
+#else
         else {
             device = ati_device_get_primary();
         }
+#endif
 
         if (!device)
             continue;


More information about the xorg-commit mailing list