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

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



 man/intel.man        |    8 +++--
 src/intel_device.c   |   10 +++++++
 src/intel_driver.h   |    1 
 src/sna/sna_accel.c  |   72 ++++++++++++++++++++++++---------------------------
 src/sna/sna_dri2.c   |   23 +++++++++-------
 src/sna/sna_driver.c |   33 +++++++++++++++++++++--
 6 files changed, 95 insertions(+), 52 deletions(-)

New commits:
commit 23840bd329cf4da3a4bdd5a1a466125a95473534
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Jun 6 16:10:29 2014 +0100

    sna: Only allow the inplace copy to replace a complete overwritten GPU bo
    
    And double check after recreating the new GPU bo that is still mappable.
    
    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 50e0b2c..47a346c 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -5624,7 +5624,8 @@ static bool
 sna_copy_boxes__inplace(struct sna *sna, RegionPtr region, int alu,
 			PixmapPtr src_pixmap, struct sna_pixmap *src_priv,
 			int dx, int dy,
-			PixmapPtr dst_pixmap, struct sna_pixmap *dst_priv)
+			PixmapPtr dst_pixmap, struct sna_pixmap *dst_priv,
+			bool replaces)
 {
 	const BoxRec *box;
 	char *ptr;
@@ -5765,18 +5766,14 @@ upload_inplace:
 		return false;
 	}
 
-	if (!kgem_bo_can_map__cpu(&sna->kgem, dst_priv->gpu_bo, true)) {
-		DBG(("%s - no, cannot map dst for reads into the CPU\n", __FUNCTION__));
-		return false;
-	}
-
-	if (__kgem_bo_is_busy(&sna->kgem, dst_priv->gpu_bo)) {
-		if (!dst_priv->pinned) {
+	if (!kgem_bo_can_map__cpu(&sna->kgem, dst_priv->gpu_bo, true) ||
+	    __kgem_bo_is_busy(&sna->kgem, dst_priv->gpu_bo)) {
+		if (replaces && !dst_priv->pinned) {
 			unsigned create;
 			struct kgem_bo *bo;
 
 			create = CREATE_CPU_MAP | CREATE_INACTIVE;
-			if (dst_pixmap->usage_hint == SNA_CREATE_FB)
+			if (dst_priv->gpu_bo->scanout)
 				create |= CREATE_SCANOUT;
 
 			bo = kgem_create_2d(&sna->kgem,
@@ -5795,6 +5792,11 @@ upload_inplace:
 			DBG(("%s - no, dst is busy\n", __FUNCTION__));
 			return false;
 		}
+
+		if (!kgem_bo_can_map__cpu(&sna->kgem, dst_priv->gpu_bo, true)) {
+			DBG(("%s - no, cannot map dst for reads into the CPU\n", __FUNCTION__));
+			return false;
+		}
 	}
 
 	if (src_priv &&
@@ -6373,7 +6375,8 @@ fallback:
 	} else if (!sna_copy_boxes__inplace(sna, region, alu,
 					    src_pixmap, src_priv,
 					    src_dx, src_dy,
-					    dst_pixmap, dst_priv)) {
+					    dst_pixmap, dst_priv,
+					    replaces)) {
 		FbBits *dst_bits, *src_bits;
 		int dst_stride, src_stride;
 

commit 283ff8cbe4137f46cc027dd6aadc69d0270cb33d
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Jun 6 15:04:25 2014 +0100

    sna: Rearrange scanout_flush checking to avoid potential crash
    
    With a shadow, we may never attach a GPU bo to the frontbuffer, so be
    careful when checking the scanout not to dereference that NULL pointer.
    
    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 a307d9e..50e0b2c 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -16565,7 +16565,8 @@ static struct sna_pixmap *sna_accel_scanout(struct sna *sna)
 	assert(sna->front);
 
 	priv = sna_pixmap(sna->front);
-	assert(priv->gpu_bo);
+	if (priv->gpu_bo == NULL)
+		return NULL;
 
 	return priv;
 }
@@ -16607,21 +16608,21 @@ static bool has_shadow(struct sna *sna)
 	return RegionNotEmpty(DamageRegion(damage));
 }
 
-static bool start_flush(struct sna *sna, struct sna_pixmap *scanout)
+static bool start_flush(struct sna *sna)
 {
-	DBG(("%s: scanout=%d shadow?=%d, slaves?=%d, (cpu?=%d || gpu?=%d))\n",
-	     __FUNCTION__,
-	     scanout && scanout->gpu_bo ? scanout->gpu_bo->handle : 0,
-	     has_shadow(sna), has_offload_slaves(sna),
-	     scanout && scanout->cpu_damage != NULL,
-	     scanout && scanout->gpu_bo && scanout->gpu_bo->exec != NULL));
+	struct sna_pixmap *scanout;
 
-	if (has_offload_slaves(sna))
+	if (has_offload_slaves(sna)) {
+		DBG(("%s: has offload slaves\n", __FUNCTION__));
 		return true;
+	}
 
-	if (has_shadow(sna))
+	if (has_shadow(sna)) {
+		DBG(("%s: has dirty shadow\n", __FUNCTION__));
 		return true;
+	}
 
+	scanout = sna_accel_scanout(sna);
 	if (!scanout)
 		return false;
 
@@ -16630,7 +16631,11 @@ static bool start_flush(struct sna *sna, struct sna_pixmap *scanout)
 		return true;
 	}
 
-	return scanout->cpu_damage || scanout->gpu_bo->exec;
+	if (scanout->cpu_damage || scanout->gpu_bo->exec)
+		return true;
+
+	kgem_scanout_flush(&sna->kgem, scanout->gpu_bo);
+	return false;
 }
 
 static bool stop_flush(struct sna *sna, struct sna_pixmap *scanout)
@@ -16670,17 +16675,7 @@ static void timer_enable(struct sna *sna, int whom, int interval)
 
 static bool sna_scanout_do_flush(struct sna *sna)
 {
-	struct sna_pixmap *priv;
-	int interval;
-
-	priv = sna_accel_scanout(sna);
-	if (priv == NULL && !sna->mode.shadow_damage && !has_offload_slaves(sna)) {
-		DBG(("%s -- no scanout attached\n", __FUNCTION__));
-		sna_accel_disarm_timer(sna, FLUSH_TIMER);
-		return false;
-	}
-
-	interval = sna->vblank_interval ?: 20;
+	int interval = sna->vblank_interval ?: 20;
 	if (sna->timer_active & (1<<(FLUSH_TIMER))) {
 		int32_t delta = sna->timer_expire[FLUSH_TIMER] - TIME;
 		DBG(("%s: flush timer active: delta=%d\n",
@@ -16690,12 +16685,10 @@ static bool sna_scanout_do_flush(struct sna *sna)
 			sna->timer_expire[FLUSH_TIMER] = TIME + interval;
 			return true;
 		}
-	} else if (!start_flush(sna, priv)) {
-		DBG(("%s -- no pending write to scanout\n", __FUNCTION__));
-		if (priv)
-			kgem_scanout_flush(&sna->kgem, priv->gpu_bo);
-	} else
-		timer_enable(sna, FLUSH_TIMER, interval/2);
+	} else {
+		if (start_flush(sna))
+			timer_enable(sna, FLUSH_TIMER, interval/2);
+	}
 
 	return false;
 }

commit 694ff54aca16ccf39e94d505942eb857b3101d7d
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Jun 6 13:34:18 2014 +0100

    sna: Report KMS driver version
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/intel_device.c b/src/intel_device.c
index c1c6d84..610b223 100644
--- a/src/intel_device.c
+++ b/src/intel_device.c
@@ -376,6 +376,16 @@ err_path:
 	return -1;
 }
 
+int __intel_peek_fd(ScrnInfoPtr scrn)
+{
+	struct intel_device *dev;
+
+	dev = intel_device(scrn);
+	assert(dev && dev->fd != -1);
+
+	return dev->fd;
+}
+
 int intel_get_device(ScrnInfoPtr scrn)
 {
 	struct intel_device *dev;
diff --git a/src/intel_driver.h b/src/intel_driver.h
index 3dc640c..d295250 100644
--- a/src/intel_driver.h
+++ b/src/intel_driver.h
@@ -125,6 +125,7 @@ void intel_detect_chipset(ScrnInfoPtr scrn, EntityInfoPtr ent);
 int intel_open_device(int entity_num,
 		      const struct pci_device *pci,
 		      struct xf86_platform_device *dev);
+int __intel_peek_fd(ScrnInfoPtr scrn);
 int intel_get_device(ScrnInfoPtr scrn);
 const char *intel_get_client_name(ScrnInfoPtr scrn);
 int intel_get_client_fd(ScrnInfoPtr scrn);
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index b923236..3810090 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -1276,9 +1276,31 @@ static void sna_leave_vt__hosted(VT_FUNC_ARGS_DECL)
 {
 }
 
-Bool sna_init_scrn(ScrnInfoPtr scrn, int entity_num)
+static void describe_kms(ScrnInfoPtr scrn)
+{
+	int fd = __intel_peek_fd(scrn);
+	drm_version_t version;
+	char name[128] = "";
+	char date[128] = "";
+
+	memset(&version, 0, sizeof(version));
+	version.name_len = sizeof(name) - 1;
+	version.name = name;
+	version.date_len = sizeof(date) - 1;
+	version.date = date;
+
+	if (drmIoctl(fd, DRM_IOCTL_VERSION, &version))
+		return;
+
+	xf86DrvMsg(scrn->scrnIndex, X_INFO,
+		   "Using Kernel Mode Setting driver: %s, version %d.%d.%d %s\n",
+		   version.name,
+		   version.version_major, version.version_minor, version.version_patchlevel,
+		   version.date);
+}
+
+static void describe_sna(ScrnInfoPtr scrn)
 {
-	DBG(("%s: entity_num=%d\n", __FUNCTION__, entity_num));
 #if defined(USE_GIT_DESCRIBE)
 	xf86DrvMsg(scrn->scrnIndex, X_INFO,
 		   "SNA compiled from %s\n", git_version);
@@ -1303,6 +1325,13 @@ Bool sna_init_scrn(ScrnInfoPtr scrn, int entity_num)
 		   "SNA compiled with extra pixmap/damage validation\n");
 #endif
 	DBG(("pixman version: %s\n", pixman_version_string()));
+}
+
+Bool sna_init_scrn(ScrnInfoPtr scrn, int entity_num)
+{
+	DBG(("%s: entity_num=%d\n", __FUNCTION__, entity_num));
+	describe_kms(scrn);
+	describe_sna(scrn);
 
 	scrn->PreInit = sna_pre_init;
 	scrn->ScreenInit = sna_screen_init;

commit 0ebcef4f2ebe82e9b90589aa4266a9228e2b5fdb
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Jun 6 11:39:57 2014 +0100

    man: Update notes about TearFree
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/man/intel.man b/man/intel.man
index 27206e3..9deac41 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -150,9 +150,11 @@ the screen is then performed synchronously with the vertical refresh of the
 display so that the entire update is completed before the display starts its
 refresh. That is only one frame is ever visible, preventing an unsightly tear
 between two visible and differing frames. Note that this replicates what the
-compositing manager should be doing, so it is not advisable to enable both.
-However, some compositing managers do cause tearing, and if the outputs are
-rotated, there may will still be tearing without TearFree enabled.
+compositing manager should be doing, however TearFree will redirect the
+compositor updates (and those of fullscreen games) directly on to the scanout
+thus incurring no additional overhead in the composited case. Also note that
+not all compositing managers prevent tearing, and if the outputs are
+rotated, there will still be tearing without TearFree enabled.
 .IP
 Default: TearFree is disabled.
 .TP

commit 1f943a7d92d0e3a8895ba7d539cfc5e726bcc8b7
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Jun 6 11:25:47 2014 +0100

    sna/dri2: Restore flush on front buffers after swapping bo
    
    Fallout from commit 8369166349c92a20d9a2e7d0256e63f66fe2682b
    Author: Chris Wilson <chris@chris-wilson.co.uk>
    Date:   Wed Jun 4 08:29:51 2014 +0100
    
        sna/dri2: Enable immediate buffer exchanges
    
    We set the flush hint too early, as we may need to swap the GPU bo for a
    more appropriate buffer for DRI.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 9e591be..e13e626 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -327,13 +327,6 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
 	assert(priv->gpu_bo->proxy == NULL);
 	assert(priv->gpu_bo->flush == false);
 
-	/* Henceforth, we need to broadcast all updates to clients and
-	 * flush our rendering before doing so.
-	 */
-	priv->gpu_bo->flush = true;
-	if (priv->gpu_bo->exec)
-		sna->kgem.flush = 1;
-
 	tiling = color_tiling(sna, &pixmap->drawable);
 	if (tiling < 0)
 		tiling = -tiling;
@@ -377,12 +370,14 @@ sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo)
 	if (private->bo == bo)
 		return;
 
+	DBG(("%s: dropping flush hint from handle=%d\n", __FUNCTION__, private->bo->handle));
 	private->bo->flush = false;
 	kgem_bo_destroy(&sna->kgem, private->bo);
 
 	buffer->name = kgem_bo_flink(&sna->kgem, bo);
 	private->bo = ref(bo);
 
+	DBG(("%s: adding flush hint to handle=%d\n", __FUNCTION__, bo->handle));
 	bo->flush = true;
 	assert(sna_pixmap(pixmap)->flush);
 
@@ -422,6 +417,7 @@ sna_dri2_create_buffer(DrawablePtr draw,
 			     private->bo->handle, buffer->name));
 
 			assert(private->pixmap == pixmap);
+			assert(private->bo->flush);
 			assert(sna_pixmap(pixmap)->flush);
 			assert(sna_pixmap(pixmap)->gpu_bo == private->bo);
 			assert(sna_pixmap(pixmap)->pinned & PIN_DRI2);
@@ -564,6 +560,11 @@ sna_dri2_create_buffer(DrawablePtr draw,
 		 *
 		 * As we don't track which Client, we flush for all.
 		 */
+		DBG(("%s: adding flush hint to handle=%d\n", __FUNCTION__, priv->gpu_bo->handle));
+		priv->gpu_bo->flush = true;
+		if (priv->gpu_bo->exec)
+			sna->kgem.flush = 1;
+
 		priv->flush = true;
 		sna_accel_watch_flush(sna, 1);
 	}
@@ -609,6 +610,7 @@ static void _sna_dri2_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
 
 		list_del(&priv->flush_list);
 
+		DBG(("%s: dropping flush hint from handle=%d\n", __FUNCTION__, private->bo->handle));
 		priv->gpu_bo->flush = false;
 		priv->pinned &= ~PIN_DRI2;
 
@@ -617,8 +619,8 @@ static void _sna_dri2_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
 
 		sna_pixmap_set_buffer(pixmap, NULL);
 		pixmap->drawable.pScreen->DestroyPixmap(pixmap);
-	} else
-		private->bo->flush = false;
+	}
+	assert(private->bo->flush == false);
 
 	kgem_bo_destroy(&sna->kgem, private->bo);
 	free(buffer);
@@ -691,6 +693,7 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo)
 	if (priv->move_to_gpu)
 		priv->move_to_gpu(sna, priv, 0);
 	if (priv->gpu_bo != bo) {
+		DBG(("%s: dropping flush hint from handle=%d\n", __FUNCTION__, priv->gpu_bo->handle));
 		priv->gpu_bo->flush = false;
 		if (priv->cow)
 			sna_pixmap_undo_cow(sna, priv, 0);
@@ -698,6 +701,7 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo)
 			sna_pixmap_unmap(pixmap, priv);
 			kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
 		}
+		DBG(("%s: adding flush hint to handle=%d\n", __FUNCTION__, bo->handle));
 		bo->flush = true;
 		if (bo->exec)
 			sna->kgem.flush = 1;
@@ -705,6 +709,7 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo)
 	}
 	if (bo->domain != DOMAIN_GPU)
 		bo->domain = DOMAIN_NONE;
+	assert(bo->flush);
 
 	DamageRegionProcessPending(&pixmap->drawable);
 }


Reply to: