xf86-video-intel: 3 commits - src/sna/kgem.c src/sna/kgem.h src/sna/sna_display.c src/sna/sna_driver.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Feb 18 14:01:10 UTC 2016


 src/sna/kgem.c        |   54 +++++++++++++++++++++++++++++++++++++++++++++++++-
 src/sna/kgem.h        |    3 ++
 src/sna/sna_display.c |   42 +++++++++++++++++++++++++++++++++++++-
 src/sna/sna_driver.c  |    8 ++++---
 4 files changed, 102 insertions(+), 5 deletions(-)

New commits:
commit 05320318fb940247d8749da8330215d19f41d84e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Feb 18 13:54:11 2016 +0000

    sna: Prefer to avoid direct rendering with FBC
    
    If FBC is enabled, avoid the overhead of tracking rendering into the
    frontbuffer by rendering into a backbuffer and flipping. Again, we have
    no actual flag to indicate when FBC is enabled, so take a guess from the
    module parameter.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index f2fca7c..a1e1ffb 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -7105,6 +7105,22 @@ sna_mode_wants_tear_free(struct sna *sna)
 	FILE *file;
 	int i;
 
+	file = fopen("/sys/module/i915/parameters/enable_fbc", "r");
+	if (file) {
+		int fbc_enabled = 0;
+		int value;
+
+		if (fscanf(file, "%d", &value) == 1)
+			fbc_enabled = value > 0;
+		fclose(file);
+
+		DBG(("%s: module parameter 'enable_fbc' enabled? %d\n",
+		     __FUNCTION__, fbc_enabled));
+
+		if (fbc_enabled)
+			return true;
+	}
+
 	for (i = 0; i < sna->mode.num_real_output; i++) {
 		struct sna_output *output = to_sna_output(config->output[i]);
 		int id = find_property(sna, output, "Panel Self-Refresh");
commit b99e8b022c4aaf586ae49e0eb597f0c34bc0e165
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Feb 18 13:53:07 2016 +0000

    sna: Use dirtyfb for fallback direct rendering
    
    The preferred solution when direct rendering is too costly is to render
    into the backbuffer and flip. However, if the user insists, we need to
    tell the kernel when to flush the scanout due to direct rendering.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index aceedd4..abb9e02 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -86,6 +86,7 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
 #define DBG_NO_WC_MMAP 0
 #define DBG_NO_BLT_Y 0
 #define DBG_NO_SCANOUT_Y 0
+#define DBG_NO_DIRTYFB 0
 #define DBG_NO_DETILING 0
 #define DBG_DUMP 0
 #define DBG_NO_MALLOC_CACHE 0
@@ -1499,6 +1500,47 @@ static bool test_can_scanout_y(struct kgem *kgem)
 	return ret;
 }
 
+static bool test_has_dirtyfb(struct kgem *kgem)
+{
+	struct drm_mode_fb_cmd create;
+	bool ret = false;
+
+	if (DBG_NO_DIRTYFB)
+		return false;
+
+	VG_CLEAR(create);
+	create.width = 32;
+	create.height = 32;
+	create.pitch = 4*32;
+	create.bpp = 32;
+	create.depth = 32;
+	create.handle = gem_create(kgem->fd, 1);
+	if (create.handle == 0)
+		return false;
+
+	if (drmIoctl(kgem->fd, DRM_IOCTL_MODE_ADDFB, &create) == 0) {
+		struct drm_mode_fb_dirty_cmd dirty;
+
+		memset(&dirty, 0, sizeof(dirty));
+		dirty.fb_id = create.fb_id;
+		ret = drmIoctl(kgem->fd,
+			       DRM_IOCTL_MODE_DIRTYFB,
+			       &dirty) == 0;
+
+		/* XXX There may be multiple levels of DIRTYFB, depending on
+		 * whether the kernel thinks tracking dirty regions is
+		 * beneficial vs flagging the whole fb as dirty.
+		 */
+
+		drmIoctl(kgem->fd,
+			 DRM_IOCTL_MODE_RMFB,
+			 &create.fb_id);
+	}
+	gem_close(kgem->fd, create.handle);
+
+	return ret;
+}
+
 static bool test_has_secure_batches(struct kgem *kgem)
 {
 	if (DBG_NO_SECURE_BATCHES)
@@ -1981,6 +2023,9 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
 	DBG(("%s: can scanout Y-tiled surfaces? %d\n", __FUNCTION__,
 	     kgem->can_scanout_y));
 
+	kgem->has_dirtyfb = test_has_dirtyfb(kgem);
+	DBG(("%s: has dirty fb? %d\n", __FUNCTION__, kgem->has_dirtyfb));
+
 	kgem->has_secure_batches = test_has_secure_batches(kgem);
 	DBG(("%s: can use privileged batchbuffers? %d\n", __FUNCTION__,
 	     kgem->has_secure_batches));
@@ -6090,7 +6135,7 @@ static void __kgem_flush(struct kgem *kgem, struct kgem_bo *bo)
 
 void kgem_scanout_flush(struct kgem *kgem, struct kgem_bo *bo)
 {
-	if (!bo->needs_flush)
+	if (!bo->needs_flush && !bo->gtt_dirty)
 		return;
 
 	kgem_bo_submit(kgem, bo);
@@ -6103,6 +6148,13 @@ void kgem_scanout_flush(struct kgem *kgem, struct kgem_bo *bo)
 	if (bo->rq)
 		__kgem_flush(kgem, bo);
 
+	if (bo->scanout && kgem->needs_dirtyfb) {
+		struct drm_mode_fb_dirty_cmd cmd;
+		memset(&cmd, 0, sizeof(cmd));
+		cmd.fb_id = bo->delta;
+		(void)drmIoctl(kgem->fd, DRM_IOCTL_MODE_DIRTYFB, &cmd);
+	}
+
 	/* Whatever actually happens, we can regard the GTT write domain
 	 * as being flushed.
 	 */
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 6cf877c..8bea755 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -189,6 +189,7 @@ struct kgem {
 	uint32_t has_no_reloc :1;
 	uint32_t has_handle_lut :1;
 	uint32_t has_wc_mmap :1;
+	uint32_t has_dirtyfb :1;
 
 	uint32_t can_fence :1;
 	uint32_t can_blt_cpu :1;
@@ -196,6 +197,8 @@ struct kgem {
 	uint32_t can_render_y :1;
 	uint32_t can_scanout_y :1;
 
+	uint32_t needs_dirtyfb :1;
+
 	uint16_t fence_max;
 	uint16_t half_cpu_cache_pages;
 	uint32_t aperture_total, aperture_high, aperture_low, aperture_mappable, aperture_fenceable;
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 14ec2f6..b245594 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -461,13 +461,13 @@ static bool enable_tear_free(struct sna *sna)
 	return ENABLE_TEAR_FREE;
 }
 
-static void setup_tear_free(struct sna *sna)
+static bool setup_tear_free(struct sna *sna)
 {
 	MessageType from;
 	Bool enable;
 
 	if (sna->flags & SNA_LINEAR_FB)
-		return;
+		return false;
 
 	if ((sna->flags & SNA_HAS_FLIP) == 0) {
 		from = X_PROBED;
@@ -486,6 +486,7 @@ static void setup_tear_free(struct sna *sna)
 done:
 	xf86DrvMsg(sna->scrn->scrnIndex, from, "TearFree %sabled\n",
 		   sna->flags & SNA_TEAR_FREE ? "en" : "dis");
+	return sna->flags & SNA_TEAR_FREE;
 }
 
 /**
@@ -653,7 +654,8 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int probe)
 	}
 	scrn->currentMode = scrn->modes;
 
-	setup_tear_free(sna);
+	if (!setup_tear_free(sna) && sna_mode_wants_tear_free(sna))
+		sna->kgem.needs_dirtyfb = sna->kgem.has_dirtyfb;
 
 	xf86SetGamma(scrn, zeros);
 	xf86SetDpi(scrn, 0, 0);
commit c4382c5e5b28a60261986b00bf0fcb8da4b78625
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Feb 18 13:51:13 2016 +0000

    sna: Check enable_psr module parameters
    
    Despite protestations over the last 2 years, PSR was enabled by default
    upstream with no way for userspace to detect the change in behaviour.
    Have a look at the module parameter and take a guess.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 9215b23..f2fca7c 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -7101,18 +7101,42 @@ bool
 sna_mode_wants_tear_free(struct sna *sna)
 {
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
+	bool found = false;
+	FILE *file;
 	int i;
 
 	for (i = 0; i < sna->mode.num_real_output; i++) {
 		struct sna_output *output = to_sna_output(config->output[i]);
 		int id = find_property(sna, output, "Panel Self-Refresh");
-		if (id !=-1 && output->prop_values[id] != -1) {
+		if (id == -1)
+			continue;
+
+		found = true;
+		if (output->prop_values[id] != -1) {
 			DBG(("%s: Panel Self-Refresh detected on %s\n",
 			     __FUNCTION__, config->output[i]->name));
 			return true;
 		}
 	}
 
+	if (!found) {
+		file = fopen("/sys/module/i915/parameters/enable_psr", "r");
+		if (file) {
+			int psr_enabled = 0;
+			int value;
+
+			if (fscanf(file, "%d", &value) == 1)
+				psr_enabled = value > 0;
+			fclose(file);
+
+			DBG(("%s: module parameter 'enable_psr' enabled? %d\n",
+			     __FUNCTION__, psr_enabled));
+
+			if (psr_enabled)
+				return true;
+		}
+	}
+
 	return false;
 }
 


More information about the xorg-commit mailing list