[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-intel: Changes to 'upstream-experimental'



 NEWS                         |   38 
 configure.ac                 |    2 
 src/intel_driver.c           |    4 
 src/intel_driver.h           |   18 
 src/intel_module.c           |    4 
 src/sna/Makefile.am          |    2 
 src/sna/compiler.h           |   13 
 src/sna/gen2_render.c        |  326 +++++
 src/sna/gen3_render.c        | 2538 ++++++++++++++++++++++++++++++-------------
 src/sna/gen4_render.c        |   55 
 src/sna/gen4_vertex.c        | 1639 +++++++++++++++++++++++----
 src/sna/gen4_vertex.h        |    4 
 src/sna/gen5_render.c        |   52 
 src/sna/gen6_render.c        |   52 
 src/sna/gen7_render.c        |   58 
 src/sna/kgem.c               |   85 +
 src/sna/kgem.h               |    3 
 src/sna/sna.h                |   26 
 src/sna/sna_accel.c          |  208 ++-
 src/sna/sna_blt.c            |    8 
 src/sna/sna_composite.c      |    9 
 src/sna/sna_cpu.c            |  114 +
 src/sna/sna_display.c        |  135 +-
 src/sna/sna_display_fake.c   |  320 +++++
 src/sna/sna_dri.c            |  199 ---
 src/sna/sna_driver.c         |   75 +
 src/sna/sna_glyphs.c         |   17 
 src/sna/sna_gradient.c       |   10 
 src/sna/sna_io.c             |    4 
 src/sna/sna_render.c         |   46 
 src/sna/sna_render.h         |    3 
 src/sna/sna_tiling.c         |   17 
 src/sna/sna_trapezoids.c     |   14 
 src/sna/sna_video.c          |    8 
 src/sna/sna_video_textured.c |    5 
 test/.gitignore              |    2 
 36 files changed, 4619 insertions(+), 1494 deletions(-)

New commits:
commit 4fb7be0a0d4bf027ed254399b6b538e979f525f2
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sun Mar 10 14:34:39 2013 +0000

    2.21.4 release

diff --git a/NEWS b/NEWS
index 4c088bd..cb82e52 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,41 @@
+Release 2.21.4 (2013-03-11)
+===========================
+More bugs, more fixes, more releases. A minor new feature being introduced
+is the runtime detection of CPU instructions sets along with specialised
+paths to take advantage of the available CPU.
+
+ * Honour LinearFramebuffer for clumsy PowerXpress integration
+
+ * Disable read-read optimisations of mappings whilst the root
+   cause of a corruption issue remains elusive.
+   https://bugs.freedesktop.org/show_bug.cgi?id=61628
+
+ * Disable 8-bpp framebuffers in UXA as the regressions therein
+   remain unfixed.
+
+ * Restart vertex checks after lock contention
+   https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1124576
+
+ * Handle Screen Pixmap recreation whilst exported via PRIME.
+
+ * Correct application of scale factors to video source offsets.
+   https://bugs.freedesktop.org/show_bug.cgi?id=61610
+
+ * Chain up CloseScreen so that resources are actually freed across regen
+   https://bugs.freedesktop.org/show_bug.cgi?id=56608
+
+ * Fix Haswell CRW PCI-IDs
+
+ * Handle batch submission failure during DRI copies
+   https://bugs.freedesktop.org/show_bug.cgi?id=61708
+
+ * Probe for kernel support of requested Screen depth
+   https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1135403
+
+ * Correct GPU limits for early gen2 and gen3 architectures and prevent
+   an infinite recursion for particular image sizes.
+
+
 Release 2.21.3 (2013-02-20)
 ===========================
 A few minor bugfixes, another point release.
diff --git a/configure.ac b/configure.ac
index 97daee6..8fea817 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@
 # Initialize Autoconf
 AC_PREREQ([2.60])
 AC_INIT([xf86-video-intel],
-        [2.21.3],
+        [2.21.4],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         [xf86-video-intel])
 AC_CONFIG_SRCDIR([Makefile.am])

commit 25a63b32c7b549ffb3c7f14de4bf2731d044eb39
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Mon Mar 11 10:42:08 2013 +0000

    sna: Tighten checking for coherent maps
    
    Remember all the special cases where we can use a CPU mmap as a
    temporary substitute for a GTT mapping.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index e9f29d0..35c2a90 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1361,6 +1361,20 @@ void sna_pixmap_destroy(PixmapPtr pixmap)
 	sna_destroy_pixmap(pixmap);
 }
 
+static inline bool has_coherent_map(struct sna *sna,
+				    struct kgem_bo *bo)
+{
+	assert(bo->map);
+
+	if (!IS_CPU_MAP(bo->map))
+		return true;
+
+	if (bo->tiling != I915_TILING_NONE)
+		return false;
+
+	return bo->domain == DOMAIN_CPU || sna->kgem.has_llc;
+}
+
 static inline bool pixmap_inplace(struct sna *sna,
 				  PixmapPtr pixmap,
 				  struct sna_pixmap *priv,
@@ -1373,7 +1387,7 @@ static inline bool pixmap_inplace(struct sna *sna,
 		return false;
 
 	if (priv->mapped)
-		return !IS_CPU_MAP(priv->gpu_bo->map) || sna->kgem.has_llc;
+		return has_coherent_map(sna, priv->gpu_bo);
 
 	if (!write_only && priv->cpu_damage)
 		return false;
@@ -1564,7 +1578,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 			if (!priv->mapped)
 				goto skip_inplace_map;
 
-			assert(!IS_CPU_MAP(priv->gpu_bo->map) || sna->kgem.has_llc);
+			assert(has_coherent_map(sna, priv->gpu_bo));
 			pixmap->devKind = priv->gpu_bo->pitch;
 
 			assert(priv->gpu_bo->proxy == NULL);
@@ -1622,7 +1636,7 @@ skip_inplace_map:
 		pixmap->devPrivate.ptr = kgem_bo_map(&sna->kgem, priv->gpu_bo);
 		priv->mapped = pixmap->devPrivate.ptr != NULL;
 		if (priv->mapped) {
-			assert(!IS_CPU_MAP(priv->gpu_bo->map) || sna->kgem.has_llc);
+			assert(has_coherent_map(sna, priv->gpu_bo));
 			pixmap->devKind = priv->gpu_bo->pitch;
 			if (flags & MOVE_WRITE) {
 				assert(priv->gpu_bo->proxy == NULL);
@@ -1869,7 +1883,7 @@ static inline bool region_inplace(struct sna *sna,
 
 	if (priv->mapped) {
 		DBG(("%s: yes, already mapped, continuiung\n", __FUNCTION__));
-		return !IS_CPU_MAP(priv->gpu_bo->map);
+		return has_coherent_map(sna, priv->gpu_bo);
 	}
 
 	if (priv->flush) {
@@ -1984,7 +1998,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		pixmap->devPrivate.ptr = kgem_bo_map(&sna->kgem, priv->gpu_bo);
 		priv->mapped = pixmap->devPrivate.ptr != NULL;
 		if (priv->mapped) {
-			assert(!IS_CPU_MAP(priv->gpu_bo->map) || sna->kgem.has_llc);
+			assert(has_coherent_map(sna, priv->gpu_bo));
 			pixmap->devKind = priv->gpu_bo->pitch;
 			if (flags & MOVE_WRITE) {
 				if (!DAMAGE_IS_ALL(priv->gpu_damage)) {

commit 210d474a96d3adf7338b49ee2c234893b54bbb2c
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sun Mar 10 16:40:35 2013 +0000

    sna: Tweak CPU mappings to be only used if a read is required
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index ae6d3c1..e9f29d0 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1634,6 +1634,7 @@ skip_inplace_map:
 				list_del(&priv->list);
 				priv->clear = false;
 			}
+			priv->cpu = false;
 
 			assert_pixmap_damage(pixmap);
 			DBG(("%s: operate inplace (GTT)\n", __FUNCTION__));
@@ -1649,6 +1650,7 @@ skip_inplace_map:
 	}
 
 	if (priv->gpu_damage && priv->cpu_damage == NULL &&
+	    (flags & MOVE_READ || priv->gpu_bo->domain == DOMAIN_CPU || sna->kgem.has_llc) &&
 	    priv->gpu_bo->tiling == I915_TILING_NONE &&
 	    ((flags & (MOVE_WRITE | MOVE_ASYNC_HINT)) == 0 ||
 	     !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo))) {
@@ -1672,6 +1674,7 @@ skip_inplace_map:
 				priv->clear = false;
 			}
 
+			assert(IS_CPU_MAP(priv->gpu_bo->map));
 			kgem_bo_sync__cpu_full(&sna->kgem, priv->gpu_bo,
 					       FORCE_FULL_SYNC || flags & MOVE_WRITE);
 			assert_pixmap_damage(pixmap);
@@ -1781,6 +1784,7 @@ done:
 	if (priv->cpu_bo) {
 		if ((flags & MOVE_ASYNC_HINT) == 0) {
 			DBG(("%s: syncing CPU bo\n", __FUNCTION__));
+			assert(IS_CPU_MAP(priv->cpu_bo->map));
 			kgem_bo_sync__cpu_full(&sna->kgem, priv->cpu_bo,
 					       FORCE_FULL_SYNC || flags & MOVE_WRITE);
 			assert(!priv->shm || !kgem_bo_is_busy(priv->cpu_bo));
@@ -2312,6 +2316,7 @@ out:
 	}
 	if ((flags & MOVE_ASYNC_HINT) == 0 && priv->cpu_bo) {
 		DBG(("%s: syncing cpu bo\n", __FUNCTION__));
+		assert(IS_CPU_MAP(priv->cpu_bo->map));
 		kgem_bo_sync__cpu_full(&sna->kgem, priv->cpu_bo,
 				       FORCE_FULL_SYNC || flags & MOVE_WRITE);
 	}

commit 35f50a98fde7a4ebe6871bd23475948a2a530633
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sun Mar 10 15:51:45 2013 +0000

    sna/dri: Flatten _sna_dri_destroy_buffer()
    
    One level of indentation can be trivially removed with an earlier return.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 9da27cb..6e60570 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -420,40 +420,41 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
 	     __FUNCTION__, buffer, private->bo->handle, private->refcnt,
 	     private->pixmap ? private->pixmap->drawable.serialNumber : 0));
 	assert(private->refcnt > 0);
+	if (--private->refcnt)
+		return;
 
-	if (--private->refcnt == 0) {
-		if (private->pixmap) {
-			PixmapPtr pixmap = private->pixmap;
-			struct sna_pixmap *priv = sna_pixmap(pixmap);
+	assert(private->bo);
+	if (private->pixmap) {
+		PixmapPtr pixmap = private->pixmap;
+		struct sna_pixmap *priv = sna_pixmap(pixmap);
 
-			assert(sna_pixmap_get_buffer(pixmap) == buffer);
-			assert(priv->gpu_bo == private->bo);
-			assert(priv->gpu_bo->flush);
-			assert(priv->pinned & PIN_DRI);
-			assert(priv->flush);
+		assert(sna_pixmap_get_buffer(pixmap) == buffer);
+		assert(priv->gpu_bo == private->bo);
+		assert(priv->gpu_bo->flush);
+		assert(priv->pinned & PIN_DRI);
+		assert(priv->flush);
 
-			/* Undo the DRI markings on this pixmap */
-			DBG(("%s: releasing last DRI pixmap=%ld, scanout?=%d\n",
-			     __FUNCTION__,
-			     pixmap->drawable.serialNumber,
-			     pixmap == sna->front));
+		/* Undo the DRI markings on this pixmap */
+		DBG(("%s: releasing last DRI pixmap=%ld, scanout?=%d\n",
+		     __FUNCTION__,
+		     pixmap->drawable.serialNumber,
+		     pixmap == sna->front));
 
-			list_del(&priv->list);
+		list_del(&priv->list);
 
-			priv->gpu_bo->flush = false;
-			priv->pinned &= ~PIN_DRI;
+		priv->gpu_bo->flush = false;
+		priv->pinned &= ~PIN_DRI;
 
-			priv->flush = false;
-			sna_accel_watch_flush(sna, -1);
+		priv->flush = false;
+		sna_accel_watch_flush(sna, -1);
 
-			sna_pixmap_set_buffer(pixmap, NULL);
-			pixmap->drawable.pScreen->DestroyPixmap(pixmap);
-		} else
-			private->bo->flush = false;
+		sna_pixmap_set_buffer(pixmap, NULL);
+		pixmap->drawable.pScreen->DestroyPixmap(pixmap);
+	} else
+		private->bo->flush = false;
 
-		kgem_bo_destroy(&sna->kgem, private->bo);
-		free(buffer);
-	}
+	kgem_bo_destroy(&sna->kgem, private->bo);
+	free(buffer);
 }
 
 static void sna_dri_destroy_buffer(DrawablePtr draw, DRI2Buffer2Ptr buffer)

commit b81ee116d36845e55f71be2db391f93c1b681d5d
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sun Mar 10 14:15:46 2013 +0000

    sna/dri: Add a couple more basic assertions
    
    To catch bad reference counting and loss of flush.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index ebcbdcf..9da27cb 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -419,6 +419,7 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
 	DBG(("%s: %p [handle=%d] -- refcnt=%d, pixmap=%ld\n",
 	     __FUNCTION__, buffer, private->bo->handle, private->refcnt,
 	     private->pixmap ? private->pixmap->drawable.serialNumber : 0));
+	assert(private->refcnt > 0);
 
 	if (--private->refcnt == 0) {
 		if (private->pixmap) {
@@ -427,6 +428,8 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
 
 			assert(sna_pixmap_get_buffer(pixmap) == buffer);
 			assert(priv->gpu_bo == private->bo);
+			assert(priv->gpu_bo->flush);
+			assert(priv->pinned & PIN_DRI);
 			assert(priv->flush);
 
 			/* Undo the DRI markings on this pixmap */
@@ -446,7 +449,7 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
 			sna_pixmap_set_buffer(pixmap, NULL);
 			pixmap->drawable.pScreen->DestroyPixmap(pixmap);
 		} else
-			private->bo->flush = 0;
+			private->bo->flush = false;
 
 		kgem_bo_destroy(&sna->kgem, private->bo);
 		free(buffer);

commit 93ecd5606eaf2e1db2b844f39bb04d77fa53cf8d
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Mar 8 23:38:12 2013 +0000

    sna: Only shrink the maximum GPU size to fit into cache
    
    That is be very careful that we do not enlarge it past the aperture size
    on early gen.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 6933b47..d469e51 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1121,7 +1121,7 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
 
 	kgem->max_object_size = 3 * (kgem->aperture_high >> 12) << 10;
 	kgem->max_gpu_size = kgem->max_object_size;
-	if (!kgem->has_llc)
+	if (!kgem->has_llc && kgem->max_gpu_size > MAX_CACHE_SIZE)
 		kgem->max_gpu_size = MAX_CACHE_SIZE;
 
 	totalram = total_ram_size();

commit 78c756120db2e5e174925a92c0a0bba3ff70860c
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Mar 8 16:39:21 2013 +0000

    sna/gen4: Initialise a pair of unimportant variables
    
    Should never actually affect any results.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index f78c5da..67f7b64 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -2814,6 +2814,8 @@ gen4_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
 				sna_rgba_for_color(color,
 						   dst->drawable.depth));
 	tmp.mask.bo = NULL;
+	tmp.mask.filter = SAMPLER_FILTER_NEAREST;
+	tmp.mask.repeat = SAMPLER_EXTEND_NONE;
 
 	tmp.is_affine = true;
 	tmp.floats_per_vertex = 2;

commit dcd52d0c186e8b17569335338232298fbbea2b2d
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Mar 7 23:03:52 2013 +0000

    sna: Fallback if we cannot fit the tiling copy into the aperture
    
    If we cannot fit the source/destination and a tile into the aperture,
    then we cannot perform the copy and must do it using the CPU.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c
index 5bebf00..019b50a 100644
--- a/src/sna/sna_tiling.c
+++ b/src/sna/sna_tiling.c
@@ -690,7 +690,7 @@ bool sna_tiling_blt_copy_boxes(struct sna *sna, uint8_t alu,
 {
 	RegionRec region, tile, this;
 	struct kgem_bo *bo;
-	int step;
+	int max_size, step;
 	bool ret = false;
 
 	if (!kgem_bo_can_blt(&sna->kgem, src_bo) ||
@@ -703,14 +703,27 @@ bool sna_tiling_blt_copy_boxes(struct sna *sna, uint8_t alu,
 		return false;
 	}
 
+	max_size = sna->kgem.aperture_high * PAGE_SIZE;
+	max_size -= MAX(kgem_bo_size(src_bo), kgem_bo_size(dst_bo));
+	if (max_size <= 0) {
+		DBG(("%s: tiles cannot fit into aperture\n", __FUNCTION__));
+		return false;
+	}
+	if (max_size > sna->kgem.max_copy_tile_size)
+		max_size = sna->kgem.max_copy_tile_size;
+
 	pixman_region_init_rects(&region, box, nbox);
 
 	/* Use a small step to accommodate enlargement through tile alignment */
 	step = sna->render.max_3d_size;
 	if (region.extents.x1 & (8*512 / bpp - 1) || region.extents.y1 & 63)
 		step /= 2;
-	while (step * step * 4 > sna->kgem.max_copy_tile_size)
+	while (step * step * 4 > max_size)
 		step /= 2;
+	if (step == 0) {
+		DBG(("%s: tiles cannot fit into aperture\n", __FUNCTION__));
+		return false;
+	}
 
 	DBG(("%s (alu=%d), tile.size=%d, box=%dx[(%d, %d), (%d, %d)])\n",
 	     __FUNCTION__, alu, step, nbox,

commit 50d0ea02b3908156534fc00def55cfca30bbfecc
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Mar 7 22:58:21 2013 +0000

    sna: Trim tile sizes to fit aperture constraints
    
    This is especially important with gen2 where we have no unmappable GTT
    to utilise.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 16f60bb..6933b47 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1149,10 +1149,18 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
 		kgem->max_upload_tile_size = kgem->aperture_mappable / 4;
 	if (kgem->max_upload_tile_size > half_gpu_max)
 		kgem->max_upload_tile_size = half_gpu_max;
+	if (kgem->max_upload_tile_size > kgem->aperture_high/2)
+		kgem->max_upload_tile_size = kgem->aperture_high/2;
+	if (kgem->max_upload_tile_size > kgem->aperture_low)
+		kgem->max_upload_tile_size = kgem->aperture_low;
 
 	kgem->large_object_size = MAX_CACHE_SIZE;
 	if (kgem->large_object_size > kgem->max_gpu_size)
 		kgem->large_object_size = kgem->max_gpu_size;
+	if (kgem->max_copy_tile_size > kgem->aperture_high/2)
+		kgem->max_copy_tile_size = kgem->aperture_high/2;
+	if (kgem->max_copy_tile_size > kgem->aperture_low)
+		kgem->max_copy_tile_size = kgem->aperture_low;
 
 	if (kgem->has_llc | kgem->has_cacheing | kgem->has_userptr) {
 		if (kgem->large_object_size > kgem->max_cpu_size)

commit cd1c14b172b0794f744b304f59b4fc78f0d6f8d6
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Mar 7 10:16:19 2013 +0000

    sna: Remove the unused output and crtc lists
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 8f26be9..a244b97 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -239,9 +239,6 @@ struct sna {
 		DamagePtr shadow_damage;
 		struct kgem_bo *shadow;
 		int shadow_flip;
-
-		struct list outputs;
-		struct list crtcs;
 	} mode;
 
 	struct sna_dri {
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 710d783..5d14af7 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1571,8 +1571,6 @@ sna_crtc_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num)
 	DBG(("%s: created handle=%d for cursor on CRTC:%d\n",
 	     __FUNCTION__, sna_crtc->cursor, sna_crtc->id));
 
-	list_add(&sna_crtc->link, &mode->crtcs);
-
 	DBG(("%s: attached crtc[%d] id=%d, pipe=%d\n",
 	     __FUNCTION__, num, sna_crtc->id, sna_crtc->pipe));
 }
@@ -2307,8 +2305,6 @@ sna_output_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num)
 	output->possible_clones = enc.possible_clones;
 	output->interlaceAllowed = TRUE;
 
-	list_add(&sna_output->link, &mode->outputs);
-
 	return;
 
 cleanup_output:
@@ -2648,9 +2644,6 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
 	struct sna_mode *mode = &sna->mode;
 	int i;
 
-	list_init(&mode->crtcs);
-	list_init(&mode->outputs);
-
 	mode->kmode = drmModeGetResources(sna->kgem.fd);
 	if (!mode->kmode)
 		return sna_mode_fake_init(sna);

commit 1b8fc8715598e7bf756ccfa99a6da59bab48c2a0
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Mar 7 10:12:14 2013 +0000

    sna: Disambiguate sna_crtc_resize()
    
    sna_crtc_resize() operates upon the whole configuration rather than a
    single crtc like the other sna_crtc_* so rename it to make it distinct.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index be6c61d..710d783 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -2462,7 +2462,7 @@ migrate_dirty_tracking(struct sna *sna, PixmapPtr old_front)
 }
 
 static Bool
-sna_crtc_resize(ScrnInfoPtr scrn, int width, int height)
+sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
 {
 	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
 	struct sna *sna = to_sna(scrn);
@@ -2630,8 +2630,8 @@ sna_page_flip(struct sna *sna,
 	return count;
 }
 
-static const xf86CrtcConfigFuncsRec sna_crtc_config_funcs = {
-	sna_crtc_resize
+static const xf86CrtcConfigFuncsRec sna_mode_funcs = {
+	sna_mode_resize
 };
 
 static void set_size_range(struct sna *sna)
@@ -2655,7 +2655,7 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
 	if (!mode->kmode)
 		return sna_mode_fake_init(sna);
 
-	xf86CrtcConfigInit(scrn, &sna_crtc_config_funcs);
+	xf86CrtcConfigInit(scrn, &sna_mode_funcs);
 
 	for (i = 0; i < mode->kmode->count_crtcs; i++)
 		sna_crtc_init(scrn, mode, i);
diff --git a/src/sna/sna_display_fake.c b/src/sna/sna_display_fake.c
index 775810a..b8723a3 100644
--- a/src/sna/sna_display_fake.c
+++ b/src/sna/sna_display_fake.c
@@ -248,7 +248,7 @@ migrate_dirty_tracking(struct sna *sna, PixmapPtr old_front)
 }
 
 static Bool
-sna_crtc_resize(ScrnInfoPtr scrn, int width, int height)
+sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
 {
 	struct sna *sna = to_sna(scrn);
 	ScreenPtr screen = scrn->pScreen;
@@ -298,15 +298,15 @@ sna_crtc_resize(ScrnInfoPtr scrn, int width, int height)
 	return TRUE;
 }
 
-static const xf86CrtcConfigFuncsRec sna_crtc_config_funcs = {
-	sna_crtc_resize
+static const xf86CrtcConfigFuncsRec sna_mode_funcs = {
+	sna_mode_resize
 };
 
 bool sna_mode_fake_init(struct sna *sna)
 {
 	ScrnInfoPtr scrn = sna->scrn;
 
-	xf86CrtcConfigInit(scrn, &sna_crtc_config_funcs);
+	xf86CrtcConfigInit(scrn, &sna_mode_funcs);
 
 	if (!sna_crtc_fake(sna))
 		return false;

commit 5f1c2b3b8bb062a4574e5114b09a33b7e4f0c811
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Mar 7 09:40:06 2013 +0000

    sna: Supply a fake pipe to run completely headless
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/Makefile.am b/src/sna/Makefile.am
index b5da0cf..0fbd19d 100644
--- a/src/sna/Makefile.am
+++ b/src/sna/Makefile.am
@@ -52,6 +52,7 @@ libsna_la_SOURCES = \
 	sna_damage.c \
 	sna_damage.h \
 	sna_display.c \
+	sna_display_fake.c \
 	sna_driver.c \
 	sna_glyphs.c \
 	sna_gradient.c \
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 7dc838c..8f26be9 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -305,6 +305,7 @@ struct sna {
 };
 
 bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna);
+bool sna_mode_fake_init(struct sna *sna);
 void sna_mode_adjust_frame(struct sna *sna, int x, int y);
 extern void sna_mode_update(struct sna *sna);
 extern void sna_mode_disable_unused(struct sna *sna);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 30160a5..be6c61d 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -778,6 +778,9 @@ sna_crtc_disable(xf86CrtcPtr crtc)
 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
 	struct drm_mode_crtc arg;
 
+	if (sna_crtc == NULL)
+		return;
+
 	DBG(("%s: disabling crtc [%d]\n", __FUNCTION__, sna_crtc->id));
 
 	memset(&arg, 0, sizeof(arg));
@@ -802,6 +805,9 @@ static void update_flush_interval(struct sna *sna)
 	for (i = 0; i < xf86_config->num_crtc; i++) {
 		xf86CrtcPtr crtc = xf86_config->crtc[i];
 
+		if (to_sna_crtc(crtc) == NULL)
+			continue;
+
 		if (!crtc->enabled) {
 			DBG(("%s: CRTC:%d (pipe %d) disabled\n",
 			     __FUNCTION__,i, to_sna_crtc(crtc)->pipe));
@@ -899,6 +905,9 @@ void sna_copy_fbcon(struct sna *sna)
 		struct sna_crtc *crtc = to_sna_crtc(xf86_config->crtc[i]);
 		struct drm_mode_crtc mode;
 
+		if (!crtc)
+			continue;
+
 		VG_CLEAR(mode);
 		mode.crtc_id = crtc->id;
 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode))
@@ -1444,7 +1453,7 @@ sna_crtc_destroy(xf86CrtcPtr crtc)
 
 #if HAS_PIXMAP_SHARING
 static Bool
-sna_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr pixmap)
+sna_crtc_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr pixmap)
 {
 	DBG(("%s: CRTC:%d, pipe=%d setting scanout pixmap=%ld\n",
 	     __FUNCTION__,to_sna_crtc(crtc)->id, to_sna_crtc(crtc)->pipe,
@@ -1465,7 +1474,7 @@ static const xf86CrtcFuncsRec sna_crtc_funcs = {
 	.gamma_set = sna_crtc_gamma_set,
 	.destroy = sna_crtc_destroy,
 #if HAS_PIXMAP_SHARING
-	.set_scanout_pixmap = sna_set_scanout_pixmap,
+	.set_scanout_pixmap = sna_crtc_set_scanout_pixmap,
 #endif
 };
 
@@ -2644,12 +2653,10 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
 
 	mode->kmode = drmModeGetResources(sna->kgem.fd);
 	if (!mode->kmode)
-		return true;
+		return sna_mode_fake_init(sna);
 
 	xf86CrtcConfigInit(scrn, &sna_crtc_config_funcs);
 
-	set_size_range(sna);
-
 	for (i = 0; i < mode->kmode->count_crtcs; i++)
 		sna_crtc_init(scrn, mode, i);
 
@@ -2659,6 +2666,8 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
 	if (!xf86IsEntityShared(scrn->entityList[0]))
 		sna_mode_compute_possible_clones(scrn);
 
+	set_size_range(sna);
+
 #if HAS_PIXMAP_SHARING
 	xf86ProviderSetup(scrn, NULL, "Intel");
 #endif
@@ -2757,6 +2766,9 @@ sna_covering_crtc(ScrnInfoPtr scrn,
 		BoxRec cover_box;
 		int coverage;
 
+		if (to_sna_crtc(crtc) == NULL)
+			continue;
+
 		/* If the CRTC is off, treat it as not covering */
 		if (to_sna_crtc(crtc)->bo == NULL) {
 			DBG(("%s: crtc %d off, skipping\n", __FUNCTION__, c));
@@ -3038,6 +3050,9 @@ void sna_mode_update(struct sna *sna)
 	/* Validate CRTC attachments */
 	for (i = 0; i < xf86_config->num_crtc; i++) {
 		xf86CrtcPtr crtc = xf86_config->crtc[i];
+		if (to_sna_crtc(crtc) == NULL)
+			continue;
+
 		if (!crtc->active || !sna_crtc_is_bound(sna, crtc))
 			sna_crtc_disable(crtc);
 	}
diff --git a/src/sna/sna_display_fake.c b/src/sna/sna_display_fake.c
new file mode 100644
index 0000000..775810a
--- /dev/null
+++ b/src/sna/sna_display_fake.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * 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, sublicense,
+ * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ *	Chris Wilson <chris@chris-wilson.co.uk>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sna.h"
+
+static void
+sna_crtc_dpms(xf86CrtcPtr crtc, int mode)
+{
+}
+
+static Bool
+sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
+			Rotation rotation, int x, int y)
+{
+	return TRUE;
+}
+
+static void
+sna_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
+{
+}
+
+static void
+sna_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
+{
+}
+
+static void
+sna_crtc_hide_cursor(xf86CrtcPtr crtc)
+{
+}
+
+static void
+sna_crtc_show_cursor(xf86CrtcPtr crtc)
+{
+}
+
+static void
+sna_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
+{
+}
+
+static void
+sna_crtc_gamma_set(xf86CrtcPtr crtc,
+		       CARD16 *red, CARD16 *green, CARD16 *blue, int size)
+{
+}
+
+static void
+sna_crtc_destroy(xf86CrtcPtr crtc)
+{
+}
+
+#if HAS_PIXMAP_SHARING
+static Bool
+sna_crtc_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr pixmap)
+{
+	return TRUE;
+}
+#endif
+
+static const xf86CrtcFuncsRec sna_crtc_funcs = {
+	.dpms = sna_crtc_dpms,
+	.set_mode_major = sna_crtc_set_mode_major,
+	.set_cursor_colors = sna_crtc_set_cursor_colors,
+	.set_cursor_position = sna_crtc_set_cursor_position,
+	.show_cursor = sna_crtc_show_cursor,
+	.hide_cursor = sna_crtc_hide_cursor,
+	.load_cursor_argb = sna_crtc_load_cursor_argb,
+	.gamma_set = sna_crtc_gamma_set,
+	.destroy = sna_crtc_destroy,
+#if HAS_PIXMAP_SHARING
+	.set_scanout_pixmap = sna_crtc_set_scanout_pixmap,
+#endif
+};
+
+static bool
+sna_crtc_fake(struct sna *sna)
+{
+	ScrnInfoPtr scrn = sna->scrn;
+	xf86CrtcPtr crtc;
+
+	DBG(("%s\n", __FUNCTION__));
+
+	crtc = xf86CrtcCreate(scrn, &sna_crtc_funcs);
+	if (crtc == NULL)
+		return false;
+
+	return true;
+}
+
+static void
+sna_output_create_resources(xf86OutputPtr output)
+{
+}
+
+static Bool
+sna_output_set_property(xf86OutputPtr output, Atom property,
+			    RRPropertyValuePtr value)
+{
+	return TRUE;
+}
+
+static Bool
+sna_output_get_property(xf86OutputPtr output, Atom property)
+{
+	return FALSE;
+}
+
+static void
+sna_output_dpms(xf86OutputPtr output, int dpms)
+{
+}
+
+static xf86OutputStatus
+sna_output_detect(xf86OutputPtr output)
+{
+	return XF86OutputStatusDisconnected;
+}
+
+static Bool
+sna_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
+{
+	return MODE_OK;
+}
+
+static DisplayModePtr
+sna_output_get_modes(xf86OutputPtr output)
+{
+	return xf86GetDefaultModes();
+}
+
+static void
+sna_output_destroy(xf86OutputPtr output)
+{
+}
+
+static const xf86OutputFuncsRec sna_output_funcs = {
+	.create_resources = sna_output_create_resources,
+#ifdef RANDR_12_INTERFACE
+	.set_property = sna_output_set_property,
+	.get_property = sna_output_get_property,
+#endif
+	.dpms = sna_output_dpms,
+	.detect = sna_output_detect,
+	.mode_valid = sna_output_mode_valid,
+
+	.get_modes = sna_output_get_modes,
+	.destroy = sna_output_destroy
+};
+
+static bool
+sna_output_fake(struct sna *sna)
+{
+	ScrnInfoPtr scrn = sna->scrn;
+	xf86OutputPtr output;
+
+	output = xf86OutputCreate(scrn, &sna_output_funcs, "FAKE");
+	if (!output)
+		return false;
+
+	output->mm_width = 0;
+	output->mm_height = 0;
+
+	output->subpixel_order = SubPixelNone;
+
+	output->possible_crtcs = 1;
+	output->possible_clones = 0;
+	output->interlaceAllowed = FALSE;
+
+	return true;
+}
+
+struct sna_visit_set_pixmap_window {
+	PixmapPtr old, new;
+};
+
+static int
+sna_visit_set_window_pixmap(WindowPtr window, pointer data)
+{
+    struct sna_visit_set_pixmap_window *visit = data;
+    ScreenPtr screen = window->drawable.pScreen;
+
+    if (screen->GetWindowPixmap(window) == visit->old) {
+	    screen->SetWindowPixmap(window, visit->new);
+	    return WT_WALKCHILDREN;
+    }
+
+    return WT_DONTWALKCHILDREN;
+}
+
+static void
+migrate_dirty_tracking(struct sna *sna, PixmapPtr old_front)
+{
+#if HAS_PIXMAP_SHARING
+	ScreenPtr screen = sna->scrn->pScreen;
+	PixmapDirtyUpdatePtr dirty, safe;
+
+	xorg_list_for_each_entry_safe(dirty, safe, &screen->pixmap_dirty_list, ent) {
+		assert(dirty->src == old_front);
+		if (dirty->src != old_front)
+			continue;
+
+		DamageUnregister(&dirty->src->drawable, dirty->damage);
+		DamageDestroy(dirty->damage);


Reply to: