xf86-video-intel: 5 commits - src/common.h src/intel_dri.c src/intel_driver.c src/intel.h src/intel_shadow.c src/intel_uxa.c src/Makefile.am uxa/uxa-glyphs.c

Chris Wilson ickle at kemper.freedesktop.org
Mon Oct 4 12:37:19 PDT 2010


 src/Makefile.am    |    1 
 src/common.h       |    7 -
 src/intel.h        |    4 
 src/intel_dri.c    |  225 ++++++++++++++++++++++++++++++++++++++++-------------
 src/intel_driver.c |   11 +-
 src/intel_shadow.c |  182 ++++++++++++++++++++++++++++++++++++++++++
 src/intel_uxa.c    |  196 ++++------------------------------------------
 uxa/uxa-glyphs.c   |    7 +
 8 files changed, 392 insertions(+), 241 deletions(-)

New commits:
commit b27a521214728052b8b10342aaacbaf1622b8e2c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Oct 4 20:31:44 2010 +0100

    shadow: Enable shadow by default on SandyBridge
    
    SandyBridge 2D support is far from complete, so instead of
    permanently falling back and always using uncached GTT mapping for
    rendering, use the shadow buffer instead.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/intel_driver.c b/src/intel_driver.c
index 2cd50a1..50540dd 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -560,7 +560,6 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
 
 	intel->force_fallback =
 		drmCommandNone(intel->drmSubFD, DRM_I915_GEM_THROTTLE) != 0;
-	intel->use_shadow = FALSE;
 
 	/* Enable tiling by default */
 	intel->tiling = TRUE;
@@ -573,9 +572,15 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
 			intel->tiling = FALSE;
 	}
 
+	intel->use_shadow = FALSE;
+	if (IS_GEN6(intel))
+		intel->use_shadow = TRUE;
+
 	if (xf86IsOptionSet(intel->Options, OPTION_SHADOW)) {
-		if (xf86ReturnOptValBool(intel->Options, OPTION_SHADOW, FALSE))
-			intel->use_shadow = TRUE;
+		intel->use_shadow =
+			xf86ReturnOptValBool(intel->Options,
+					     OPTION_SHADOW,
+					     FALSE);
 	}
 
 	if (intel->use_shadow) {
commit 3e641459f8997f45288cc3cb314e50f2b5a629fd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Oct 4 20:31:01 2010 +0100

    shadow: Disable BLT for SandyBridge
    
    The blitting code is incorrect for SandyBridge so disable until
    the BLT ring is ready.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/intel_shadow.c b/src/intel_shadow.c
index de27348..eb5f1ad 100644
--- a/src/intel_shadow.c
+++ b/src/intel_shadow.c
@@ -139,7 +139,7 @@ void intel_shadow_create(struct intel_screen_private *intel)
 	void *buffer;
 
 	pixmap = screen->GetScreenPixmap(screen);
-	if (IS_I8XX(intel)) {
+	if (IS_I8XX(intel) || IS_GEN6(intel)) {
 		/* Okay, this is a lie. We just use the scanout directly
 		 * via a GTT (uncached) mapping and never attempt anything
 		 * more dangerous...
commit 7c7294ec00d6c3a454a17a1b9983d14d0655162c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Oct 4 11:56:27 2010 +0100

    shadow+dri2: Allow dri2 to be independently enabled with shadow
    
    To enable DRI we create GEM buffers for the client to render into with
    hardware acceleration. In order to maintain coherency between any 2D
    render operations with the independent 3D clients (this includes the
    reading of 2D rasterisation by the direct rendering client, e.g.
    compiz using texture_from_pixmap) we need to replace the shadow pixmap
    with the GTT mapping. Therefore 2D rendering to a DRI buffer will be to
    uncached memory and thus penalised -- but the direct rendering clients
    will have full hardware acceleration.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/common.h b/src/common.h
index f7e4923..6f23cdd 100644
--- a/src/common.h
+++ b/src/common.h
@@ -182,9 +182,10 @@ intel_host_bridge (void);
  * Compare to CREATE_PIXMAP_USAGE_* in the server.
  */
 enum {
-	INTEL_CREATE_PIXMAP_TILING_X = 0x10000000,
-	INTEL_CREATE_PIXMAP_TILING_Y,
-	INTEL_CREATE_PIXMAP_TILING_NONE,
+	INTEL_CREATE_PIXMAP_TILING_X	= 0x10000000,
+	INTEL_CREATE_PIXMAP_TILING_Y	= 0x20000000,
+	INTEL_CREATE_PIXMAP_TILING_NONE	= 0x40000000,
+	INTEL_CREATE_PIXMAP_DRI2	= 0x80000000,
 };
 
 #endif /* _INTEL_COMMON_H_ */
diff --git a/src/intel_dri.c b/src/intel_dri.c
index 9804272..1527dba 100644
--- a/src/intel_dri.c
+++ b/src/intel_dri.c
@@ -58,6 +58,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "windowstr.h"
 #include "shadow.h"
 
+#include "xaarop.h"
+
 #include "intel.h"
 #include "i830_reg.h"
 
@@ -68,11 +70,101 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 typedef struct {
 	int refcnt;
 	PixmapPtr pixmap;
+	DrawablePtr drawable;
 	unsigned int attachment;
 } I830DRI2BufferPrivateRec, *I830DRI2BufferPrivatePtr;
 
-#if DRI2INFOREC_VERSION < 2
+static PixmapPtr get_front_buffer(DrawablePtr drawable, DrawablePtr *ret)
+{
+	ScreenPtr screen = drawable->pScreen;
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	PixmapPtr pixmap;
+
+	pixmap = get_drawable_pixmap(drawable);
+	if (pixmap_is_scanout(pixmap)) {
+		pixmap = fbCreatePixmap(screen, 0, 0, drawable->depth, 0);
+		if (pixmap) {
+			screen->ModifyPixmapHeader(pixmap,
+						   drawable->width,
+						   drawable->height,
+						   0, 0,
+						   intel->front_pitch,
+						   NULL);
+			intel_set_pixmap_bo(pixmap, intel->front_buffer);
+		}
+	} else if (intel_get_pixmap_bo(pixmap)) {
+		pixmap->refcnt++;
+		*ret = drawable;
+	} else
+		pixmap = NULL;
+	return pixmap;
+}
 
+static PixmapPtr fixup_shadow(DrawablePtr drawable, PixmapPtr pixmap)
+{
+	ScreenPtr screen = drawable->pScreen;
+	PixmapPtr old = get_drawable_pixmap(drawable);
+	struct intel_pixmap *priv = intel_get_pixmap_private(pixmap);
+	GCPtr gc;
+
+	/* With an active shadow buffer, 2D pixmaps are created in
+	 * system memory and GPU acceleration of 2D render operations
+	 * is *disabled*. As DRI is still enabled, we create hardware
+	 * buffers for the clients, and need to mix this with the
+	 * 2D rendering. So we replace the system pixmap with a GTT
+	 * mapping (with the kernel enforcing coherency between
+	 * CPU and GPU) for 2D and provide the bo so that clients
+	 * can write directly to it (or read from it in the case
+	 * of TextureFromPixmap) using the GPU.
+	 *
+	 * So for a compositor with a GL backend (i.e. compiz) we have
+	 * smooth wobbly windows but incur the cost of uncached 2D rendering,
+	 * however 3D applications (games and clutter) are still fully
+	 * accelerated.
+	 */
+
+	drm_intel_gem_bo_map_gtt(priv->bo);
+
+	/* Copy the current contents of the pixmap to the bo. */
+	gc = GetScratchGC(drawable->depth, screen);
+	if (gc) {
+		ValidateGC(&pixmap->drawable, gc);
+
+		screen->ModifyPixmapHeader(pixmap,
+					   drawable->width,
+					   drawable->height,
+					   0, 0,
+					   priv->stride,
+					   priv->bo->virtual);
+
+		gc->ops->CopyArea(drawable, &pixmap->drawable,
+				  gc,
+				  0, 0,
+				  drawable->width,
+				  drawable->height,
+				  0, 0);
+		FreeScratchGC(gc);
+	}
+
+	intel_set_pixmap_private(pixmap, NULL);
+	screen->DestroyPixmap(pixmap);
+
+	/* Redirect 2D rendering to the uncached GTT map of the bo */
+	screen->ModifyPixmapHeader(old,
+				   drawable->width,
+				   drawable->height,
+				   0, 0,
+				   priv->stride,
+				   priv->bo->virtual);
+
+	/* And redirect the pixmap to the new bo (for 3D). */
+	intel_set_pixmap_private(old, priv);
+	old->refcnt++;
+	return old;
+}
+
+#if DRI2INFOREC_VERSION < 2
 static DRI2BufferPtr
 I830DRI2CreateBuffers(DrawablePtr drawable, unsigned int *attachments,
 		      int count)
@@ -85,6 +177,7 @@ I830DRI2CreateBuffers(DrawablePtr drawable, unsigned int *attachments,
 	int i;
 	I830DRI2BufferPrivatePtr privates;
 	PixmapPtr pixmap, pDepthPixmap;
+	DrawablePtr target;
 
 	buffers = calloc(count, sizeof *buffers);
 	if (buffers == NULL)
@@ -97,39 +190,49 @@ I830DRI2CreateBuffers(DrawablePtr drawable, unsigned int *attachments,
 
 	pDepthPixmap = NULL;
 	for (i = 0; i < count; i++) {
+		target = NULL;
+		pixmap = NULL;
 		if (attachments[i] == DRI2BufferFrontLeft) {
-			pixmap = get_drawable_pixmap(drawable);
-			pixmap->refcnt++;
+			pixmap = get_front_buffer(drawable, &target);
 		} else if (attachments[i] == DRI2BufferStencil && pDepthPixmap) {
 			pixmap = pDepthPixmap;
 			pixmap->refcnt++;
-		} else {
-			unsigned int hint = 0;
-
-			switch (attachments[i]) {
-			case DRI2BufferDepth:
-				if (SUPPORTS_YTILING(intel))
-					hint = INTEL_CREATE_PIXMAP_TILING_Y;
-				else
-					hint = INTEL_CREATE_PIXMAP_TILING_X;
-				break;
-			case DRI2BufferFakeFrontLeft:
-			case DRI2BufferFakeFrontRight:
-			case DRI2BufferBackLeft:
-			case DRI2BufferBackRight:
-				hint = INTEL_CREATE_PIXMAP_TILING_X;
-				break;
+		}
+		if (pixmap == NULL) {
+			unsigned int hint = INTEL_CREATE_PIXMAP_DRI2;
+
+			if (intel->tiling) {
+				switch (attachments[i]) {
+				case DRI2BufferDepth:
+					if (SUPPORTS_YTILING(intel))
+						hint |= INTEL_CREATE_PIXMAP_TILING_Y;
+					else
+						hint |= INTEL_CREATE_PIXMAP_TILING_X;
+					break;
+				case DRI2BufferFakeFrontLeft:
+				case DRI2BufferFakeFrontRight:
+				case DRI2BufferBackLeft:
+				case DRI2BufferBackRight:
+					hint |= INTEL_CREATE_PIXMAP_TILING_X;
+					break;
+				}
 			}
 
-			if (!intel->tiling)
-				hint = 0;
-
 			pixmap = screen->CreatePixmap(screen,
 						      drawable->width,
 						      drawable->height,
 						      drawable->depth,
 						      hint);
+			if (pixmap == NULL ||
+			    intel_get_pixmap_bo(pixmap) == NULL)
+			{
+				if (pixmap)
+					screen->DestroyPixmap(pixmap);
+				goto unwind;
+			}
 
+			if (attachment == DRI2BufferFrontLeft)
+				pixmap = fixup_shadow(drawable, pixmap);
 		}
 
 		if (attachments[i] == DRI2BufferDepth)
@@ -144,6 +247,8 @@ I830DRI2CreateBuffers(DrawablePtr drawable, unsigned int *attachments,
 		privates[i].pixmap = pixmap;
 		privates[i].attachment = attachments[i];
 
+		privates[i].drawable = target ? target : &pixmap->drawable;
+
 		bo = intel_get_pixmap_bo(pixmap);
 		if (bo == NULL || dri_bo_flink(bo, &buffers[i].name) != 0) {
 			/* failed to name buffer */
@@ -193,6 +298,7 @@ I830DRI2CreateBuffer(DrawablePtr drawable, unsigned int attachment,
 	dri_bo *bo;
 	I830DRI2BufferPrivatePtr privates;
 	PixmapPtr pixmap;
+	DrawablePtr target = NULL;
 
 	buffer = calloc(1, sizeof *buffer);
 	if (buffer == NULL)
@@ -203,30 +309,25 @@ I830DRI2CreateBuffer(DrawablePtr drawable, unsigned int attachment,
 		return NULL;
 	}
 
-	if (attachment == DRI2BufferFrontLeft) {
-		pixmap = get_drawable_pixmap(drawable);
-		pixmap->refcnt++;
-	} else {
-		unsigned int hint = 0;
-
-		switch (attachment) {
-		case DRI2BufferDepth:
-		case DRI2BufferDepthStencil:
-			if (SUPPORTS_YTILING(intel))
-				hint = INTEL_CREATE_PIXMAP_TILING_Y;
-			else
-				hint = INTEL_CREATE_PIXMAP_TILING_X;
-			break;
-		case DRI2BufferFakeFrontLeft:
-		case DRI2BufferFakeFrontRight:
-		case DRI2BufferBackLeft:
-		case DRI2BufferBackRight:
-			hint = INTEL_CREATE_PIXMAP_TILING_X;
-			break;
-		}
+	pixmap = NULL;
+	if (attachment == DRI2BufferFrontLeft)
+		pixmap = get_front_buffer(drawable, &target);
+	if (pixmap == NULL) {
+		unsigned int hint = INTEL_CREATE_PIXMAP_DRI2;
 
-		if (!intel->tiling)
-			hint = 0;
+		if (intel->tiling) {
+			switch (attachment) {
+			case DRI2BufferDepth:
+			case DRI2BufferDepthStencil:
+				if (SUPPORTS_YTILING(intel)) {
+					hint |= INTEL_CREATE_PIXMAP_TILING_Y;
+					break;
+				}
+			default:
+				hint |= INTEL_CREATE_PIXMAP_TILING_X;
+				break;
+			}
+		}
 
 		pixmap = screen->CreatePixmap(screen,
 					      drawable->width,
@@ -234,12 +335,16 @@ I830DRI2CreateBuffer(DrawablePtr drawable, unsigned int attachment,
 					      (format != 0) ? format :
 							      drawable->depth,
 					      hint);
-		if (pixmap == NULL) {
+		if (pixmap == NULL || intel_get_pixmap_bo(pixmap) == NULL) {
+			if (pixmap)
+				screen->DestroyPixmap(pixmap);
 			free(privates);
 			free(buffer);
 			return NULL;
 		}
 
+		if (attachment == DRI2BufferFrontLeft)
+			pixmap = fixup_shadow(drawable, pixmap);
 	}
 
 	buffer->attachment = attachment;
@@ -251,6 +356,7 @@ I830DRI2CreateBuffer(DrawablePtr drawable, unsigned int attachment,
 	privates->refcnt = 1;
 	privates->pixmap = pixmap;
 	privates->attachment = attachment;
+	privates->drawable = target ? target : &pixmap->drawable;
 
 	bo = intel_get_pixmap_bo(pixmap);
 	if (bo == NULL || dri_bo_flink(bo, &buffer->name) != 0) {
@@ -298,11 +404,10 @@ I830DRI2CopyRegion(DrawablePtr drawable, RegionPtr pRegion,
 	ScreenPtr screen = drawable->pScreen;
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 	intel_screen_private *intel = intel_get_screen_private(scrn);
-	DrawablePtr src = (srcPrivate->attachment == DRI2BufferFrontLeft)
-	    ? drawable : &srcPrivate->pixmap->drawable;
-	DrawablePtr dst = (dstPrivate->attachment == DRI2BufferFrontLeft)
-	    ? drawable : &dstPrivate->pixmap->drawable;
+	DrawablePtr src = srcPrivate->drawable;
+	DrawablePtr dst = dstPrivate->drawable;
 	RegionPtr pCopyClip;
+	PixmapPtr src_pixmap, dst_pixmap;
 	GCPtr gc;
 
 	gc = GetScratchGC(dst->depth, screen);
@@ -399,12 +504,22 @@ I830DRI2CopyRegion(DrawablePtr drawable, RegionPtr pRegion,
 	 * that will happen before the client tries to render
 	 * again. */
 
-	(*gc->ops->CopyArea) (src, dst,
-			       gc,
-			       0, 0,
-			       drawable->width, drawable->height,
-			       0, 0);
+	/* Re-enable 2D acceleration... */
+	src_pixmap = get_drawable_pixmap(src);
+	src_pixmap->devPrivate.ptr = NULL;
+
+	dst_pixmap = get_drawable_pixmap(dst);
+	dst_pixmap->devPrivate.ptr = NULL;
+
+	gc->ops->CopyArea(src, dst, gc,
+			  0, 0,
+			  drawable->width, drawable->height,
+			  0, 0);
 	FreeScratchGC(gc);
+
+	/* and restore 2D/3D coherency */
+	src_pixmap->devPrivate.ptr = intel_get_pixmap_bo(src_pixmap)->virtual;
+	dst_pixmap->devPrivate.ptr = intel_get_pixmap_bo(dst_pixmap)->virtual;
 }
 
 #if DRI2INFOREC_VERSION >= 4
diff --git a/src/intel_driver.c b/src/intel_driver.c
index 4391672..2cd50a1 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -575,7 +575,7 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
 
 	if (xf86IsOptionSet(intel->Options, OPTION_SHADOW)) {
 		if (xf86ReturnOptValBool(intel->Options, OPTION_SHADOW, FALSE))
-			intel->force_fallback = intel->use_shadow = TRUE;
+			intel->use_shadow = TRUE;
 	}
 
 	if (intel->use_shadow) {
diff --git a/src/intel_uxa.c b/src/intel_uxa.c
index 067994e..d964a95 100644
--- a/src/intel_uxa.c
+++ b/src/intel_uxa.c
@@ -731,6 +731,9 @@ static Bool intel_uxa_pixmap_put_image(PixmapPtr pixmap,
 	int stride = intel_pixmap_pitch(pixmap);
 	int ret = FALSE;
 
+	if (priv == NULL || priv->bo == NULL)
+		return FALSE;
+
 	if (src_pitch == stride && w == pixmap->drawable.width && priv->tiling == I915_TILING_NONE) {
 		ret = drm_intel_bo_subdata(priv->bo, y * stride, stride * h, src) == 0;
 	} else if (drm_intel_gem_bo_map_gtt(priv->bo) == 0) {
@@ -890,6 +893,11 @@ static Bool intel_uxa_get_image(PixmapPtr pixmap,
 		if (!scratch)
 			return FALSE;
 
+		if (!intel_get_pixmap_bo(scratch)) {
+			screen->DestroyPixmap(scratch);
+			return FALSE;
+		}
+
 		gc = GetScratchGC(pixmap->drawable.depth, screen);
 		if (!gc) {
 			screen->DestroyPixmap(scratch);
@@ -935,7 +943,10 @@ void intel_uxa_block_handler(intel_screen_private *intel)
 
 static Bool intel_uxa_pixmap_is_offscreen(PixmapPtr pixmap)
 {
-	return intel_get_pixmap_private(pixmap) != NULL;
+	if (pixmap->devPrivate.ptr)
+		return FALSE;
+
+	return intel_get_pixmap_bo(pixmap) != NULL;
 }
 
 static PixmapPtr
@@ -952,6 +963,9 @@ intel_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	if (depth == 1 || intel->force_fallback)
 		return fbCreatePixmap(screen, w, h, depth, usage);
 
+	if (intel->use_shadow && (usage & INTEL_CREATE_PIXMAP_DRI2) == 0)
+		return fbCreatePixmap(screen, w, h, depth, usage);
+
 	if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 32 && h <= 32)
 		return fbCreatePixmap(screen, w, h, depth, usage);
 
@@ -967,9 +981,9 @@ intel_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 		 * to be effectively tiled.
 		 */
 		tiling = I915_TILING_X;
-		if (usage == INTEL_CREATE_PIXMAP_TILING_Y)
+		if (usage & INTEL_CREATE_PIXMAP_TILING_Y)
 			tiling = I915_TILING_Y;
-		if (usage == UXA_CREATE_PIXMAP_FOR_MAP || usage == INTEL_CREATE_PIXMAP_TILING_NONE)
+		if (usage == UXA_CREATE_PIXMAP_FOR_MAP || usage & INTEL_CREATE_PIXMAP_TILING_NONE)
 			tiling = I915_TILING_NONE;
 
 		/* if tiling is off force to none */
diff --git a/uxa/uxa-glyphs.c b/uxa/uxa-glyphs.c
index ad4f387..420e891 100644
--- a/uxa/uxa-glyphs.c
+++ b/uxa/uxa-glyphs.c
@@ -164,7 +164,12 @@ static Bool uxa_realize_glyph_caches(ScreenPtr pScreen)
 					       INTEL_CREATE_PIXMAP_TILING_X);
 		if (!pixmap)
 			goto bail;
-		assert (uxa_pixmap_is_offscreen(pixmap));
+		if (!uxa_pixmap_is_offscreen(pixmap)) {
+			/* Presume shadow is in-effect */
+			pScreen->DestroyPixmap(pixmap);
+			uxa_unrealize_glyph_caches(pScreen);
+			return TRUE;
+		}
 
 		component_alpha = NeedsComponent(pPictFormat->format);
 		picture = CreatePicture(0, &pixmap->drawable, pPictFormat,
commit 16a5d0ee3ca4d41af6a6876a8baf81e3f715781d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Oct 4 11:21:17 2010 +0100

    shadow: Map the scanout directly on i8xx
    
    Even with the minimal use of the BLT to copy from the GTT shadow to the
    GTT scanout, i830 was still hanging. Just write to the scanout directly.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/intel_shadow.c b/src/intel_shadow.c
index a4b14f9..de27348 100644
--- a/src/intel_shadow.c
+++ b/src/intel_shadow.c
@@ -101,22 +101,13 @@ void intel_shadow_blt(intel_screen_private *intel)
 	while (n--) {
 		int pitch;
 		dri_bo *bo;
-		int offset;
-
-		if (IS_I8XX(intel)) {
-			bo = intel->shadow_buffer;
-			offset = box->x1 | box->y1 << 16;
-			pitch = intel->shadow_stride;
-		} else {
-			bo = intel_shadow_create_bo(intel,
-						    box->x1, box->y1,
-						    box->x2, box->y2,
-						    &pitch);
-			if (bo == NULL)
-				return;
-
-			offset = 0;
-		}
+
+		bo = intel_shadow_create_bo(intel,
+					    box->x1, box->y1,
+					    box->x2, box->y2,
+					    &pitch);
+		if (bo == NULL)
+			return;
 
 		BEGIN_BATCH(8);
 		OUT_BATCH(blt);
@@ -127,7 +118,7 @@ void intel_shadow_blt(intel_screen_private *intel)
 				I915_GEM_DOMAIN_RENDER,
 				I915_GEM_DOMAIN_RENDER,
 				0);
-		OUT_BATCH(offset);
+		OUT_BATCH(0);
 		OUT_BATCH(pitch);
 		OUT_RELOC(bo, I915_GEM_DOMAIN_RENDER, 0, 0);
 
@@ -145,62 +136,43 @@ void intel_shadow_create(struct intel_screen_private *intel)
 	ScreenPtr screen = scrn->pScreen;
 	PixmapPtr pixmap;
 	int stride;
+	void *buffer;
 
 	pixmap = screen->GetScreenPixmap(screen);
 	if (IS_I8XX(intel)) {
-		dri_bo *bo;
-		int size;
-
-		/* Reduce the incoherency worries for gen2
-		 * by only allocating a static shadow, at about 2-3x
-		 * performance cost for forcing rendering to uncached memory.
+		/* Okay, this is a lie. We just use the scanout directly
+		 * via a GTT (uncached) mapping and never attempt anything
+		 * more dangerous...
 		 */
-		if (intel->shadow_buffer) {
-			drm_intel_gem_bo_unmap_gtt(intel->shadow_buffer);
-			drm_intel_bo_unreference(intel->shadow_buffer);
-			intel->shadow_buffer = NULL;
-		}
-
-		stride = ALIGN(scrn->virtualX * intel->cpp, 4);
-		size = stride * scrn->virtualY;
-		bo = drm_intel_bo_alloc(intel->bufmgr,
-					"shadow", size,
-					0);
-		if (bo && drm_intel_gem_bo_map_gtt(bo) == 0) {
+		if (intel->front_buffer &&
+		    drm_intel_gem_bo_map_gtt(intel->front_buffer) == 0) {
 			screen->ModifyPixmapHeader(pixmap,
 						   scrn->virtualX,
 						   scrn->virtualY,
 						   -1, -1,
-						   stride,
-						   bo->virtual);
-			intel->shadow_buffer = bo;
+						   intel->front_pitch,
+						   intel->front_buffer->virtual);
 		}
-	} else {
-		void *buffer;
-
-		stride = intel->cpp*scrn->virtualX;
-		buffer = malloc(stride * scrn->virtualY);
-
-		if (buffer && screen->ModifyPixmapHeader(pixmap,
-							 scrn->virtualX,
-							 scrn->virtualY,
-							 -1, -1,
-							 stride,
-							 buffer)) {
-			if (intel->shadow_buffer)
-				free(intel->shadow_buffer);
-
-			intel->shadow_buffer = buffer;
-		} else
-			stride = intel->shadow_stride;
+		return;
 	}
 
+	stride = intel->cpp*scrn->virtualX;
+	buffer = malloc(stride * scrn->virtualY);
+	if (buffer &&
+	    screen->ModifyPixmapHeader(pixmap,
+				       scrn->virtualX, scrn->virtualY,
+				       -1, -1,
+				       stride, buffer)) {
+		free(intel->shadow_buffer);
+		intel->shadow_buffer = buffer;
+	} else
+		stride = intel->shadow_stride;
+
 	if (!intel->shadow_damage) {
-		intel->shadow_damage = DamageCreate(NULL, NULL,
-						    DamageReportNone,
-						    TRUE,
-						    screen,
-						    intel);
+		intel->shadow_damage =
+			DamageCreate(NULL, NULL,
+				     DamageReportNone, TRUE,
+				     screen, intel);
 		DamageRegister(&pixmap->drawable, intel->shadow_damage);
 		DamageSetReportAfterOp(intel->shadow_damage, TRUE);
 	}
@@ -208,4 +180,3 @@ void intel_shadow_create(struct intel_screen_private *intel)
 	scrn->displayWidth = stride / intel->cpp;
 	intel->shadow_stride = stride;
 }
-
commit 516d235c5b3bd51e9533925140d95d3b4533129c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Oct 4 11:10:57 2010 +0100

    Split shadow handling routines to their own file.
    
    This is about to get messy, so separate out the shadow from the normal
    code.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/Makefile.am b/src/Makefile.am
index b0a1cf7..7d823ce 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -49,6 +49,7 @@ intel_drv_la_SOURCES = \
          intel_driver.c \
          intel_driver.h \
          intel_memory.c \
+	 intel_shadow.c \
 	 intel_uxa.c \
          intel_video.c \
          intel_video.h \
diff --git a/src/intel.h b/src/intel.h
index b816aeb..83d541e 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -667,4 +667,8 @@ void intel_uxa_block_handler(intel_screen_private *intel);
 Bool intel_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table,
 			      int num_bos);
 
+/* intel_shadow.c */
+void intel_shadow_blt(intel_screen_private *intel);
+void intel_shadow_create(struct intel_screen_private *intel);
+
 #endif /* _I830_H_ */
diff --git a/src/intel_shadow.c b/src/intel_shadow.c
new file mode 100644
index 0000000..a4b14f9
--- /dev/null
+++ b/src/intel_shadow.c
@@ -0,0 +1,211 @@
+/**************************************************************************
+
+Copyright 2010 Intel Corporation
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xaarop.h"
+#include "intel.h"
+#include "i830_reg.h"
+
+static dri_bo *
+intel_shadow_create_bo(intel_screen_private *intel,
+		       int16_t x1, int16_t y1,
+		       int16_t x2, int16_t y2,
+		       int *pitch)
+{
+	int w = x2 - x1, h = y2 - y1;
+	int size = h * w * intel->cpp;
+	dri_bo *bo;
+
+	bo = drm_intel_bo_alloc(intel->bufmgr, "shadow", size, 0);
+	if (bo && drm_intel_gem_bo_map_gtt(bo) == 0) {
+		char *dst = bo->virtual;
+		char *src = intel->shadow_buffer;
+		int src_pitch = intel->shadow_stride;
+		int row_length = w * intel->cpp;
+		int num_rows = h;
+		src += y1 * src_pitch + x1 * intel->cpp;
+		do {
+			memcpy (dst, src, row_length);
+			src += src_pitch;
+			dst += row_length;
+		} while (--num_rows);
+		drm_intel_gem_bo_unmap_gtt(bo);
+	}
+
+	*pitch = w * intel->cpp;
+	return bo;
+}
+
+void intel_shadow_blt(intel_screen_private *intel)
+{
+	ScrnInfoPtr scrn = intel->scrn;
+	unsigned int dst_pitch;
+	uint32_t blt, br13;
+	RegionPtr region;
+	BoxPtr box;
+	int n;
+
+	dst_pitch = intel->front_pitch;
+
+	blt = XY_SRC_COPY_BLT_CMD;
+	if (intel->cpp == 4)
+		blt |= (XY_SRC_COPY_BLT_WRITE_ALPHA |
+				XY_SRC_COPY_BLT_WRITE_RGB);
+
+	if (IS_I965G(intel)) {
+		if (intel->front_tiling) {
+			dst_pitch >>= 2;
+			blt |= XY_SRC_COPY_BLT_DST_TILED;
+		}
+	}
+
+	br13 = ROP_S << 16 | dst_pitch;
+	switch (intel->cpp) {
+		default:
+		case 4: br13 |= 1 << 25; /* RGB8888 */
+		case 2: br13 |= 1 << 24; /* RGB565 */
+		case 1: break;
+	}
+
+	region = DamageRegion(intel->shadow_damage);
+	box = REGION_RECTS(region);
+	n = REGION_NUM_RECTS(region);
+	while (n--) {
+		int pitch;
+		dri_bo *bo;
+		int offset;
+
+		if (IS_I8XX(intel)) {
+			bo = intel->shadow_buffer;
+			offset = box->x1 | box->y1 << 16;
+			pitch = intel->shadow_stride;
+		} else {
+			bo = intel_shadow_create_bo(intel,
+						    box->x1, box->y1,
+						    box->x2, box->y2,
+						    &pitch);
+			if (bo == NULL)
+				return;
+
+			offset = 0;
+		}
+
+		BEGIN_BATCH(8);
+		OUT_BATCH(blt);
+		OUT_BATCH(br13);
+		OUT_BATCH(box->y1 << 16 | box->x1);
+		OUT_BATCH(box->y2 << 16 | box->x2);
+		OUT_RELOC_FENCED(intel->front_buffer,
+				I915_GEM_DOMAIN_RENDER,
+				I915_GEM_DOMAIN_RENDER,
+				0);
+		OUT_BATCH(offset);
+		OUT_BATCH(pitch);
+		OUT_RELOC(bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+
+		ADVANCE_BATCH();
+
+		if (bo != intel->shadow_buffer)
+			drm_intel_bo_unreference(bo);
+		box++;
+	}
+}
+
+void intel_shadow_create(struct intel_screen_private *intel)
+{
+	ScrnInfoPtr scrn = intel->scrn;
+	ScreenPtr screen = scrn->pScreen;
+	PixmapPtr pixmap;
+	int stride;
+
+	pixmap = screen->GetScreenPixmap(screen);
+	if (IS_I8XX(intel)) {
+		dri_bo *bo;
+		int size;
+
+		/* Reduce the incoherency worries for gen2
+		 * by only allocating a static shadow, at about 2-3x
+		 * performance cost for forcing rendering to uncached memory.
+		 */
+		if (intel->shadow_buffer) {
+			drm_intel_gem_bo_unmap_gtt(intel->shadow_buffer);
+			drm_intel_bo_unreference(intel->shadow_buffer);
+			intel->shadow_buffer = NULL;
+		}
+
+		stride = ALIGN(scrn->virtualX * intel->cpp, 4);
+		size = stride * scrn->virtualY;
+		bo = drm_intel_bo_alloc(intel->bufmgr,
+					"shadow", size,
+					0);
+		if (bo && drm_intel_gem_bo_map_gtt(bo) == 0) {
+			screen->ModifyPixmapHeader(pixmap,
+						   scrn->virtualX,
+						   scrn->virtualY,
+						   -1, -1,
+						   stride,
+						   bo->virtual);
+			intel->shadow_buffer = bo;
+		}
+	} else {
+		void *buffer;
+
+		stride = intel->cpp*scrn->virtualX;
+		buffer = malloc(stride * scrn->virtualY);
+
+		if (buffer && screen->ModifyPixmapHeader(pixmap,
+							 scrn->virtualX,
+							 scrn->virtualY,
+							 -1, -1,
+							 stride,
+							 buffer)) {
+			if (intel->shadow_buffer)
+				free(intel->shadow_buffer);
+
+			intel->shadow_buffer = buffer;
+		} else
+			stride = intel->shadow_stride;
+	}
+
+	if (!intel->shadow_damage) {
+		intel->shadow_damage = DamageCreate(NULL, NULL,
+						    DamageReportNone,
+						    TRUE,
+						    screen,
+						    intel);
+		DamageRegister(&pixmap->drawable, intel->shadow_damage);
+		DamageSetReportAfterOp(intel->shadow_damage, TRUE);
+	}
+
+	scrn->displayWidth = stride / intel->cpp;
+	intel->shadow_stride = stride;
+}
+
diff --git a/src/intel_uxa.c b/src/intel_uxa.c
index ef4c553..067994e 100644
--- a/src/intel_uxa.c
+++ b/src/intel_uxa.c
@@ -918,182 +918,6 @@ static Bool intel_uxa_get_image(PixmapPtr pixmap,
 	return ret;
 }
 
-static dri_bo *
-intel_shadow_create_bo(intel_screen_private *intel,
-		       int16_t x1, int16_t y1,
-		       int16_t x2, int16_t y2,
-		       int *pitch)
-{
-	int w = x2 - x1, h = y2 - y1;
-	int size = h * w * intel->cpp;
-	dri_bo *bo;
-
-	bo = drm_intel_bo_alloc(intel->bufmgr, "shadow", size, 0);
-	if (bo && drm_intel_gem_bo_map_gtt(bo) == 0) {
-		char *dst = bo->virtual;
-		char *src = intel->shadow_buffer;
-		int src_pitch = intel->shadow_stride;
-		int row_length = w * intel->cpp;
-		int num_rows = h;
-		src += y1 * src_pitch + x1 * intel->cpp;
-		do {
-			memcpy (dst, src, row_length);
-			src += src_pitch;
-			dst += row_length;
-		} while (--num_rows);
-		drm_intel_gem_bo_unmap_gtt(bo);
-	}
-
-	*pitch = w * intel->cpp;
-	return bo;
-}
-
-static void
-intel_shadow_blt(intel_screen_private *intel)
-{
-	ScrnInfoPtr scrn = intel->scrn;
-	unsigned int dst_pitch;
-	uint32_t blt, br13;
-	RegionPtr region;
-	BoxPtr box;
-	int n;
-
-	dst_pitch = intel->front_pitch;
-
-	blt = XY_SRC_COPY_BLT_CMD;
-	if (intel->cpp == 4)
-		blt |= (XY_SRC_COPY_BLT_WRITE_ALPHA |
-				XY_SRC_COPY_BLT_WRITE_RGB);
-
-	if (IS_I965G(intel)) {
-		if (intel->front_tiling) {
-			dst_pitch >>= 2;
-			blt |= XY_SRC_COPY_BLT_DST_TILED;
-		}
-	}
-
-	br13 = ROP_S << 16 | dst_pitch;
-	switch (intel->cpp) {
-		default:
-		case 4: br13 |= 1 << 25; /* RGB8888 */
-		case 2: br13 |= 1 << 24; /* RGB565 */
-		case 1: break;
-	}
-
-	region = DamageRegion(intel->shadow_damage);
-	box = REGION_RECTS(region);
-	n = REGION_NUM_RECTS(region);
-	while (n--) {
-		int pitch;
-		dri_bo *bo;
-		int offset;
-
-		if (IS_I8XX(intel)) {
-			bo = intel->shadow_buffer;
-			offset = box->x1 | box->y1 << 16;
-			pitch = intel->shadow_stride;
-		} else {
-			bo = intel_shadow_create_bo(intel,
-						    box->x1, box->y1,
-						    box->x2, box->y2,
-						    &pitch);
-			if (bo == NULL)
-				return;
-
-			offset = 0;
-		}
-
-		BEGIN_BATCH(8);
-		OUT_BATCH(blt);
-		OUT_BATCH(br13);
-		OUT_BATCH(box->y1 << 16 | box->x1);
-		OUT_BATCH(box->y2 << 16 | box->x2);
-		OUT_RELOC_FENCED(intel->front_buffer,
-				I915_GEM_DOMAIN_RENDER,
-				I915_GEM_DOMAIN_RENDER,
-				0);
-		OUT_BATCH(offset);
-		OUT_BATCH(pitch);
-		OUT_RELOC(bo, I915_GEM_DOMAIN_RENDER, 0, 0);
-
-		ADVANCE_BATCH();
-
-		if (bo != intel->shadow_buffer)
-			drm_intel_bo_unreference(bo);
-		box++;
-	}
-}
-
-static void intel_shadow_create(struct intel_screen_private *intel)
-{
-	ScrnInfoPtr scrn = intel->scrn;
-	ScreenPtr screen = scrn->pScreen;
-	PixmapPtr pixmap;
-	int stride;
-
-	pixmap = screen->GetScreenPixmap(screen);
-	if (IS_I8XX(intel)) {
-		dri_bo *bo;
-		int size;
-
-		/* Reduce the incoherency worries for gen2
-		 * by only allocating a static shadow, at about 2-3x
-		 * performance cost for forcing rendering to uncached memory.
-		 */
-		if (intel->shadow_buffer) {
-			drm_intel_gem_bo_unmap_gtt(intel->shadow_buffer);
-			drm_intel_bo_unreference(intel->shadow_buffer);
-			intel->shadow_buffer = NULL;
-		}
-
-		stride = ALIGN(scrn->virtualX * intel->cpp, 4);
-		size = stride * scrn->virtualY;
-		bo = drm_intel_bo_alloc(intel->bufmgr,
-					"shadow", size,
-					0);
-		if (bo && drm_intel_gem_bo_map_gtt(bo) == 0) {
-			screen->ModifyPixmapHeader(pixmap,
-						   scrn->virtualX,
-						   scrn->virtualY,
-						   -1, -1,
-						   stride,
-						   bo->virtual);
-			intel->shadow_buffer = bo;
-		}
-	} else {
-		void *buffer;
-
-		stride = intel->cpp*scrn->virtualX;
-		buffer = malloc(stride * scrn->virtualY);
-
-		if (buffer && screen->ModifyPixmapHeader(pixmap,
-							 scrn->virtualX,
-							 scrn->virtualY,
-							 -1, -1,
-							 stride,
-							 buffer)) {
-			if (intel->shadow_buffer)
-				free(intel->shadow_buffer);
-
-			intel->shadow_buffer = buffer;
-		} else
-			stride = intel->shadow_stride;
-	}
-
-	if (!intel->shadow_damage) {
-		intel->shadow_damage = DamageCreate(NULL, NULL,
-						    DamageReportNone,
-						    TRUE,
-						    screen,
-						    intel);
-		DamageRegister(&pixmap->drawable, intel->shadow_damage);
-		DamageSetReportAfterOp(intel->shadow_damage, TRUE);
-	}
-
-	scrn->displayWidth = stride / intel->cpp;
-	intel->shadow_stride = stride;
-}
-
 void intel_uxa_block_handler(intel_screen_private *intel)
 {
 	if (intel->shadow_damage &&


More information about the xorg-commit mailing list