xf86-video-intel: 3 commits - configure.ac src/sna/kgem.c src/sna/kgem.h src/sna/sna_display.c src/sna/sna_dri.c src/sna/sna_video_textured.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Oct 17 06:39:37 PDT 2012


 configure.ac                 |    9 +++
 src/sna/kgem.c               |   24 +++++++++-
 src/sna/kgem.h               |    4 +
 src/sna/sna_display.c        |  103 +++++++++++++++++++++++++++++--------------
 src/sna/sna_dri.c            |    3 +
 src/sna/sna_video_textured.c |    1 
 6 files changed, 110 insertions(+), 34 deletions(-)

New commits:
commit 891bae4aa91e85542dcbe38f6ee92141e3efc801
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 17 11:29:10 2012 +0100

    sna: Use the secure batches to program scanline waits on gen6+
    
    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 ed32375..c8497fc 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -2717,41 +2717,75 @@ sna_covering_crtc(ScrnInfoPtr scrn,
 	return best_crtc;
 }
 
-/* Gen6 wait for scan line support */
 #define MI_LOAD_REGISTER_IMM			(0x22<<23)
 
-/* gen6: Scan lines register */
-#define GEN6_PIPEA_SLC			(0x70004)
-#define GEN6_PIPEB_SLC			(0x71004)
+static bool sna_emit_wait_for_scanline_gen7(struct sna *sna,
+					    int pipe, int y1, int y2,
+					    bool full_height)
+{
+	uint32_t *b;
+
+	if (!sna->kgem.has_secure_batches)
+		return false;
 
-static void sna_emit_wait_for_scanline_gen6(struct sna *sna,
+	assert(y1 >= 0);
+	assert(y2 > y1);
+	assert(sna->kgem.mode);
+
+	b = kgem_get_batch(&sna->kgem, 16);
+	b[0] = MI_LOAD_REGISTER_IMM | 1;
+	b[1] = 0x44050; /* DERRMR */
+	b[2] = ~(1 << (3*full_height + pipe*8));
+	b[3] = MI_LOAD_REGISTER_IMM | 1;
+	b[4] = 0xa188; /* FORCEWAKE_MT */
+	b[5] = 2 << 16 | 2;
+	b[6] = MI_LOAD_REGISTER_IMM | 1;
+	b[7] = 0x70068 + 0x1000 * pipe;
+	b[8] = (1 << 31) | (1 << 30) | (y1 << 16) | (y2 - 1);
+	b[9] = MI_WAIT_FOR_EVENT | 1 << (3*full_height + pipe*5);
+	b[10] = MI_LOAD_REGISTER_IMM | 1;
+	b[11] = 0xa188; /* FORCEWAKE_MT */
+	b[12] = 2 << 16;
+	b[13] = MI_LOAD_REGISTER_IMM | 1;
+	b[14] = 0x44050; /* DERRMR */
+	b[15] = ~0;
+	kgem_advance_batch(&sna->kgem, 16);
+
+	sna->kgem.batch_flags |= I915_EXEC_SECURE;
+	return true;
+}
+
+static bool sna_emit_wait_for_scanline_gen6(struct sna *sna,
 					    int pipe, int y1, int y2,
 					    bool full_height)
 {
-	uint32_t event;
 	uint32_t *b;
 
-	assert (y2 > 0);
+	if (!sna->kgem.has_secure_batches)
+		return false;
 
-	/* We just wait until the trace passes the roi */
-	if (pipe == 0) {
-		pipe = GEN6_PIPEA_SLC;
-		event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
-	} else {
-		pipe = GEN6_PIPEB_SLC;
-		event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
-	}
+	assert(y1 >= 0);
+	assert(y2 > y1);
+	assert(sna->kgem.mode);
 
-	kgem_set_mode(&sna->kgem, KGEM_RENDER);
-	b = kgem_get_batch(&sna->kgem, 4);
+	b = kgem_get_batch(&sna->kgem, 10);
 	b[0] = MI_LOAD_REGISTER_IMM | 1;
-	b[1] = pipe;
-	b[2] = y2 - 1;
-	b[3] = MI_WAIT_FOR_EVENT | event;
-	kgem_advance_batch(&sna->kgem, 4);
+	b[1] = 0x44050; /* DERRMR */
+	b[2] = ~(1 << (3*full_height + pipe*8));
+	b[3] = MI_LOAD_REGISTER_IMM | 1;
+	b[4] = 0x4f100; /* magic */
+	b[5] = (1 << 31) | (1 << 30) | pipe << 29 | (y1 << 16) | (y2 - 1);
+	b[6] = MI_WAIT_FOR_EVENT | 1 << (3*full_height + pipe*5);
+	b[7] = MI_LOAD_REGISTER_IMM | 1;
+	b[8] = 0x44050; /* DERRMR */
+	b[9] = ~0;
+	kgem_advance_batch(&sna->kgem, 10);
+
+	sna->kgem.batch_flags |= I915_EXEC_SECURE;
+	return true;
 }
 
-static void sna_emit_wait_for_scanline_gen4(struct sna *sna,
+static bool sna_emit_wait_for_scanline_gen4(struct sna *sna,
 					    int pipe, int y1, int y2,
 					    bool full_height)
 {
@@ -2778,9 +2812,11 @@ static void sna_emit_wait_for_scanline_gen4(struct sna *sna,
 	b[3] = b[1] = (y1 << 16) | (y2-1);
 	b[4] = MI_WAIT_FOR_EVENT | event;
 	kgem_advance_batch(&sna->kgem, 5);
+
+	return true;
 }
 
-static void sna_emit_wait_for_scanline_gen2(struct sna *sna,
+static bool sna_emit_wait_for_scanline_gen2(struct sna *sna,
 					    int pipe, int y1, int y2,
 					    bool full_height)
 {
@@ -2805,6 +2841,8 @@ static void sna_emit_wait_for_scanline_gen2(struct sna *sna,
 	else
 		b[4] = MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
 	kgem_advance_batch(&sna->kgem, 5);
+
+	return true;
 }
 
 bool
@@ -2815,15 +2853,12 @@ sna_wait_for_scanline(struct sna *sna,
 {
 	bool full_height;
 	int y1, y2, pipe;
+	bool ret;
 
 	assert(crtc);
 	assert(to_sna_crtc(crtc)->bo != NULL);
 	assert(pixmap == sna->front);
 
-	/* XXX WAIT_EVENT is still causing hangs on SNB */
-	if (sna->kgem.gen >= 60)
-		return false;
-
 	/*
 	 * Make sure we don't wait for a scanline that will
 	 * never occur
@@ -2850,14 +2885,18 @@ sna_wait_for_scanline(struct sna *sna,
 	DBG(("%s: pipe=%d, y1=%d, y2=%d, full_height?=%d\n",
 	     __FUNCTION__, pipe, y1, y2, full_height));
 
-	if (sna->kgem.gen >= 60)
-		sna_emit_wait_for_scanline_gen6(sna, pipe, y1, y2, full_height);
+	if (sna->kgem.gen >= 80)
+		ret = false;
+	else if (sna->kgem.gen >= 70)
+		ret = sna_emit_wait_for_scanline_gen7(sna, pipe, y1, y2, full_height);
+	else if (sna->kgem.gen >= 60)
+		ret =sna_emit_wait_for_scanline_gen6(sna, pipe, y1, y2, full_height);
 	else if (sna->kgem.gen >= 40)
-		sna_emit_wait_for_scanline_gen4(sna, pipe, y1, y2, full_height);
+		ret = sna_emit_wait_for_scanline_gen4(sna, pipe, y1, y2, full_height);
 	else
-		sna_emit_wait_for_scanline_gen2(sna, pipe, y1, y2, full_height);
+		ret = sna_emit_wait_for_scanline_gen2(sna, pipe, y1, y2, full_height);
 
-	return true;
+	return ret;
 }
 
 void sna_mode_update(struct sna *sna)
diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c
index 27fc09f..01977ba 100644
--- a/src/sna/sna_video_textured.c
+++ b/src/sna/sna_video_textured.c
@@ -275,6 +275,7 @@ sna_video_textured_put_image(ScrnInfoPtr scrn,
 		}
 	}
 
+	kgem_set_mode(&sna->kgem, KGEM_RENDER);
 	if (crtc && video->SyncToVblank != 0 &&
 	    sna_pixmap_is_scanout(sna, pixmap))
 		flush = sna_wait_for_scanline(sna, pixmap, crtc,
commit 41be80a8cae1eb0e294392e5033511bfdf2895c5
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 17 11:25:52 2012 +0100

    sna: Enable support for SECURE batch buffers
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/configure.ac b/configure.ac
index 972d918..ab3f3d2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -292,6 +292,15 @@ if test "x$USERPTR" = xyes; then
 	AC_DEFINE(USE_USERPTR,1,[Assume USERPTR support])
 fi
 
+AC_ARG_ENABLE(secure-batches,
+	      AS_HELP_STRING([--enable-secure-batches],
+			     [Enable use of secure batches (experimental) [default=no]]),
+	      [SECURE_BATCHES="$enableval"],
+	      [SECURE_BATCHES=no])
+if test "x$SECURE_BATCHES" = xyes; then
+	AC_DEFINE(USE_SECURE_BATCHES,1,[Test for kernel support of secure batches])
+fi
+
 AC_ARG_ENABLE(async-swap,
 	      AS_HELP_STRING([--enable-async-swap],
 			     [Enable use of asynchronous swaps (experimental) [default=no]]),
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 46c898f..ae76a39 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -69,8 +69,14 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
 #define DBG_NO_UPLOAD_ACTIVE 0
 #define DBG_NO_MAP_UPLOAD 0
 #define DBG_NO_RELAXED_FENCING 0
+#define DBG_NO_SECURE_BATCHES 0
 #define DBG_DUMP 0
 
+#ifndef USE_SECURE_BATCHES
+#undef DBG_NO_SECURE_BATCHES
+#define DBG_NO_SECURE_BATCHES 1
+#endif
+
 #define SHOW_BATCH 0
 
 /* Worst case seems to be 965gm where we cannot write within a cacheline that
@@ -93,7 +99,8 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
 #define IS_USER_MAP(ptr) ((uintptr_t)(ptr) & 2)
 #define __MAP_TYPE(ptr) ((uintptr_t)(ptr) & 3)
 
-#define LOCAL_I915_PARAM_HAS_SEMAPHORES	 20
+#define LOCAL_I915_PARAM_HAS_SEMAPHORES	 	20
+#define LOCAL_I915_PARAM_HAS_SECURE_BATCHES	23
 
 #define LOCAL_I915_GEM_USERPTR       0x32
 #define LOCAL_IOCTL_I915_GEM_USERPTR DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_USERPTR, struct local_i915_gem_userptr)
@@ -767,6 +774,14 @@ static bool test_has_userptr(struct kgem *kgem)
 #endif
 }
 
+static bool test_has_secure_batches(struct kgem *kgem)
+{
+	if (DBG_NO_SECURE_BATCHES)
+		return false;
+
+	return gem_param(kgem, LOCAL_I915_PARAM_HAS_SECURE_BATCHES) > 0;
+}
+
 static int kgem_get_screen_index(struct kgem *kgem)
 {
 	struct sna *sna = container_of(kgem, struct sna, kgem);
@@ -822,6 +837,10 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
 	DBG(("%s: can blt to cpu? %d\n", __FUNCTION__,
 	     kgem->can_blt_cpu));
 
+	kgem->has_secure_batches = test_has_secure_batches(kgem);
+	DBG(("%s: can use privileged batchbuffers? %d\n", __FUNCTION__,
+	     kgem->has_secure_batches));
+
 	if (!is_hw_supported(kgem, dev)) {
 		xf86DrvMsg(kgem_get_screen_index(kgem), X_WARNING,
 			   "Detected unsupported/dysfunctional hardware, disabling acceleration.\n");
@@ -2147,6 +2166,7 @@ void kgem_reset(struct kgem *kgem)
 	kgem->nbatch = 0;
 	kgem->surface = kgem->batch_size;
 	kgem->mode = KGEM_NONE;
+	kgem->batch_flags = 0;
 	kgem->flush = 0;
 
 	kgem->next_request = __kgem_request_alloc();
@@ -2258,7 +2278,7 @@ void _kgem_submit(struct kgem *kgem)
 			execbuf.num_cliprects = 0;
 			execbuf.DR1 = 0;
 			execbuf.DR4 = 0;
-			execbuf.flags = kgem->ring;
+			execbuf.flags = kgem->ring | kgem->batch_flags;
 			execbuf.rsvd1 = 0;
 			execbuf.rsvd2 = 0;
 
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index c8813eb..276df4f 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -138,6 +138,9 @@ struct kgem {
 		int16_t count;
 	} vma[NUM_MAP_TYPES];
 
+	uint32_t batch_flags;
+#define I915_EXEC_SECURE (1<<9)
+
 	uint16_t nbatch;
 	uint16_t surface;
 	uint16_t nexec;
@@ -158,6 +161,7 @@ struct kgem {
 	uint32_t has_relaxed_fencing :1;
 	uint32_t has_relaxed_delta :1;
 	uint32_t has_semaphores :1;
+	uint32_t has_secure_batches :1;
 	uint32_t has_cacheing :1;
 	uint32_t has_llc :1;
 
commit ba6c82cd9d8089354b90632ca8edbb35cc09b9c4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 17 13:54:51 2012 +0100

    sna/dri: Defensively check for GTT mmap failure during fallback
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 15ac46a..09ecd29 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -525,6 +525,9 @@ sna_dri_copy_fallback(struct sna *sna, int bpp,
 	void *dst = kgem_bo_map__gtt(&sna->kgem, dst_bo);
 	void *src = kgem_bo_map__gtt(&sna->kgem, src_bo);
 
+	if (dst == NULL || src == NULL)
+		return;
+
 	DBG(("%s: src(%d, %d), dst(%d, %d) x %d\n",
 	     __FUNCTION__, sx, sy, dx, dy, n));
 


More information about the xorg-commit mailing list