xf86-video-intel: 2 commits - configure.ac src/sna/gen7_render.c src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Jul 30 15:06:05 PDT 2013


 configure.ac          |   10 ++++++++++
 src/sna/gen7_render.c |   42 +++++++++++++++++++++++++++++++-----------
 src/sna/kgem.c        |   23 ++++++++++++++++++++++-
 src/sna/kgem.h        |    3 ++-
 src/sna/sna_accel.c   |    5 +++--
 5 files changed, 68 insertions(+), 15 deletions(-)

New commits:
commit 493763301e995d02cb838d14348da46dd26444af
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jul 30 17:38:23 2013 +0100

    sna: Allow CPU access to scanouts if WT cached
    
    On Iris, we may store the framebuffer in the eLLC/LLC and mark it as
    being Write-Through cached. This means that we can treat it as being
    cached for read accesses (either by the GPU or CPU), but must be careful
    to still not write directly to the scanout with the CPU (only the GPU
    writes are cached and coherent with the display).
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/configure.ac b/configure.ac
index 0ae1c40..d5705b9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -362,6 +362,16 @@ if test "x$ASYNC_SWAP" = xyes; then
 	AC_DEFINE(USE_ASYNC_SWAP,1,[Assume asynchronous swap support])
 fi
 
+AC_ARG_ENABLE(wt,
+	      AS_HELP_STRING([--enable-wt],
+			     [Enable use of WT cacheing (experimental) [default=no]]),
+	      [WT="$enableval"],
+	      [WT=no])
+AM_CONDITIONAL(USE_WT, test x$WT = xyes)
+if test "x$WT" = xyes; then
+	AC_DEFINE(USE_WT,1,[Assume WriteThrough cacheing support])
+fi
+
 AC_ARG_ENABLE(debug,
 	      AS_HELP_STRING([--enable-debug],
 			     [Enables internal debugging [default=no]]),
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index be379d8..f056632 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2133,7 +2133,7 @@ static int prefer_blt_bo(struct sna *sna, struct kgem_bo *bo)
 	if (bo->rq)
 		return RQ_IS_BLT(bo->rq) ? 1 : -1;
 
-	return bo->tiling == I915_TILING_NONE || bo->scanout;
+	return bo->tiling == I915_TILING_NONE || (bo->scanout && !sna->kgem.has_wt);
 }
 
 inline static bool prefer_blt_ring(struct sna *sna,
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 863ab8a..27f0089 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -77,6 +77,7 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
 #define DBG_NO_PINNED_BATCHES 0
 #define DBG_NO_FAST_RELOC 0
 #define DBG_NO_HANDLE_LUT 0
+#define DBG_NO_WT 0
 #define DBG_DUMP 0
 
 #define FORCE_MMAP_SYNC 0 /* ((1 << DOMAIN_CPU) | (1 << DOMAIN_GTT)) */
@@ -124,6 +125,7 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
 #define LOCAL_I915_PARAM_HAS_PINNED_BATCHES	24
 #define LOCAL_I915_PARAM_HAS_NO_RELOC		25
 #define LOCAL_I915_PARAM_HAS_HANDLE_LUT		26
+#define LOCAL_I915_PARAM_HAS_WT			27
 
 #define LOCAL_I915_EXEC_IS_PINNED		(1<<10)
 #define LOCAL_I915_EXEC_NO_RELOC		(1<<11)
@@ -818,6 +820,18 @@ static bool test_has_handle_lut(struct kgem *kgem)
 	return gem_param(kgem, LOCAL_I915_PARAM_HAS_HANDLE_LUT) > 0;
 }
 
+static bool test_has_wt(struct kgem *kgem)
+{
+#if defined(USE_WT)
+	if (DBG_NO_WT)
+		return false;
+
+	return gem_param(kgem, LOCAL_I915_PARAM_HAS_WT) > 0;
+#else
+	return false;
+#endif
+}
+
 static bool test_has_semaphores_enabled(struct kgem *kgem)
 {
 	FILE *file;
@@ -1156,6 +1170,10 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
 	DBG(("%s: has shared last-level-cache? %d\n", __FUNCTION__,
 	     kgem->has_llc));
 
+	kgem->has_wt = test_has_wt(kgem);
+	DBG(("%s: has write-through cacheing for scanouts? %d\n", __FUNCTION__,
+	     kgem->has_wt));
+
 	kgem->has_cacheing = test_has_cacheing(kgem);
 	DBG(("%s: has set-cache-level? %d\n", __FUNCTION__,
 	     kgem->has_cacheing));
@@ -4998,7 +5016,7 @@ void *kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo)
 	     __FUNCTION__, bo->handle, bytes(bo), (int)__MAP_TYPE(bo->map)));
 	assert(!bo->purged);
 	assert(list_is_empty(&bo->list));
-	assert(!bo->scanout);
+	assert(!bo->scanout || kgem->has_wt);
 	assert(bo->proxy == NULL);
 
 	if (IS_CPU_MAP(bo->map))
@@ -5047,6 +5065,7 @@ void *__kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo)
 	assert(!bo->purged);
 	assert(list_is_empty(&bo->list));
 	assert(bo->proxy == NULL);
+	assert(!bo->scanout || kgem->has_wt);
 
 	if (IS_CPU_MAP(bo->map))
 		return MAP(bo->map);
@@ -5186,6 +5205,7 @@ struct kgem_bo *kgem_create_map(struct kgem *kgem,
 void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo)
 {
 	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
+	assert(!bo->scanout);
 	kgem_bo_submit(kgem, bo);
 
 	/* SHM pixmaps use proxies for subpage offsets */
@@ -5217,6 +5237,7 @@ void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo)
 void kgem_bo_sync__cpu_full(struct kgem *kgem, struct kgem_bo *bo, bool write)
 {
 	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
+	assert(!bo->scanout || (kgem->has_wt && !write));
 
 	if (write || bo->needs_flush)
 		kgem_bo_submit(kgem, bo);
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 6156b4c..fede4d4 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -179,6 +179,7 @@ struct kgem {
 	uint32_t has_pinned_batches :1;
 	uint32_t has_cacheing :1;
 	uint32_t has_llc :1;
+	uint32_t has_wt :1;
 	uint32_t has_no_reloc :1;
 	uint32_t has_handle_lut :1;
 
@@ -577,7 +578,7 @@ static inline bool kgem_bo_can_map__cpu(struct kgem *kgem,
 					struct kgem_bo *bo,
 					bool write)
 {
-	if (bo->scanout)
+	if (bo->scanout && (!kgem->has_wt || write))
 		return false;
 
 	if (kgem->has_llc)
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 46de0f3..7fef4f2 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1412,7 +1412,7 @@ static inline bool has_coherent_map(struct sna *sna,
 	if (!IS_CPU_MAP(bo->map))
 		return true;
 
-	if (bo->tiling != I915_TILING_NONE)
+	if (bo->tiling == I915_TILING_Y)
 		return false;
 
 	return kgem_bo_can_map__cpu(&sna->kgem, bo, flags & MOVE_WRITE);
@@ -2183,7 +2183,8 @@ static inline bool region_inplace(struct sna *sna,
 	}
 
 	if (priv->mapped) {
-		DBG(("%s: yes, already mapped, continuiung\n", __FUNCTION__));
+		DBG(("%s: %s, already mapped, continuing\n", __FUNCTION__,
+		     has_coherent_map(sna, priv->gpu_bo, flags) ? "yes" : "no"));
 		return has_coherent_map(sna, priv->gpu_bo, flags);
 	}
 
commit cdbc097796b24ab42b60c49d9885a35573c96a89
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jul 30 16:42:54 2013 +0100

    sna/gen7: Set appropriate constants for Haswell GT3
    
    GT3 has twice the number of cores and URB as GT2, and so we can use
    more threads and URB entries.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 3a18f8e..be379d8 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -83,6 +83,7 @@ struct gt_info {
 		int size;
 		int max_vs_entries;
 		int max_gs_entries;
+		int push_ps_size; /* in 1KBs */
 	} urb;
 };
 
@@ -91,7 +92,7 @@ static const struct gt_info ivb_gt_info = {
 	.max_vs_threads = 16,
 	.max_gs_threads = 16,
 	.max_wm_threads = (16-1) << IVB_PS_MAX_THREADS_SHIFT,
-	.urb = { 128, 64, 64 },
+	.urb = { 128, 64, 64, 8 },
 };
 
 static const struct gt_info ivb_gt1_info = {
@@ -99,7 +100,7 @@ static const struct gt_info ivb_gt1_info = {
 	.max_vs_threads = 36,
 	.max_gs_threads = 36,
 	.max_wm_threads = (48-1) << IVB_PS_MAX_THREADS_SHIFT,
-	.urb = { 128, 512, 192 },
+	.urb = { 128, 512, 192, 8 },
 };
 
 static const struct gt_info ivb_gt2_info = {
@@ -107,7 +108,7 @@ static const struct gt_info ivb_gt2_info = {
 	.max_vs_threads = 128,
 	.max_gs_threads = 128,
 	.max_wm_threads = (172-1) << IVB_PS_MAX_THREADS_SHIFT,
-	.urb = { 256, 704, 320 },
+	.urb = { 256, 704, 320, 8 },
 };
 
 static const struct gt_info byt_gt_info = {
@@ -116,7 +117,7 @@ static const struct gt_info byt_gt_info = {
 	.max_vs_threads = 36,
 	.max_gs_threads = 36,
 	.max_wm_threads = (48-1) << IVB_PS_MAX_THREADS_SHIFT,
-	.urb = { 128, 512, 192 },
+	.urb = { 128, 512, 192, 8 },
 };
 
 static const struct gt_info hsw_gt_info = {
@@ -126,7 +127,7 @@ static const struct gt_info hsw_gt_info = {
 	.max_wm_threads =
 		(8 - 1) << HSW_PS_MAX_THREADS_SHIFT |
 		1 << HSW_PS_SAMPLE_MASK_SHIFT,
-	.urb = { 128, 64, 64 },
+	.urb = { 128, 64, 64, 8 },
 };
 
 static const struct gt_info hsw_gt1_info = {
@@ -136,7 +137,7 @@ static const struct gt_info hsw_gt1_info = {
 	.max_wm_threads =
 		(102 - 1) << HSW_PS_MAX_THREADS_SHIFT |
 		1 << HSW_PS_SAMPLE_MASK_SHIFT,
-	.urb = { 128, 640, 256 },
+	.urb = { 128, 640, 256, 8 },
 };
 
 static const struct gt_info hsw_gt2_info = {
@@ -146,7 +147,17 @@ static const struct gt_info hsw_gt2_info = {
 	.max_wm_threads =
 		(140 - 1) << HSW_PS_MAX_THREADS_SHIFT |
 		1 << HSW_PS_SAMPLE_MASK_SHIFT,
-	.urb = { 256, 1664, 640 },
+	.urb = { 256, 1664, 640, 8 },
+};
+
+static const struct gt_info hsw_gt3_info = {
+	.name = "Haswell (gen7.5, gt3)",
+	.max_vs_threads = 280,
+	.max_gs_threads = 280,
+	.max_wm_threads =
+		(280 - 1) << HSW_PS_MAX_THREADS_SHIFT |
+		1 << HSW_PS_SAMPLE_MASK_SHIFT,
+	.urb = { 512, 3328, 1280, 16 },
 };
 
 inline static bool is_ivb(struct sna *sna)
@@ -465,7 +476,7 @@ static void
 gen7_emit_urb(struct sna *sna)
 {
 	OUT_BATCH(GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS | (2 - 2));
-	OUT_BATCH(8); /* in 1KBs */
+	OUT_BATCH(sna->render_state.gen7.info->urb.push_ps_size);
 
 	/* num of VS entries must be divisible by 8 if size < 9 */
 	OUT_BATCH(GEN7_3DSTATE_URB_VS | (2 - 2));
@@ -3754,6 +3765,12 @@ static void gen7_render_fini(struct sna *sna)
 	kgem_bo_destroy(&sna->kgem, sna->render_state.gen7.general_bo);
 }
 
+static bool is_gt3(struct sna *sna)
+{
+	assert(sna->kgem.gen == 075);
+	return sna->PciInfo->device_id & 0x20;
+}
+
 static bool is_gt2(struct sna *sna)
 {
 	return sna->PciInfo->device_id & (is_hsw(sna)? 0x30 : 0x20);
@@ -3783,9 +3800,12 @@ static bool gen7_render_setup(struct sna *sna)
 	} else if (is_hsw(sna)) {
 		state->info = &hsw_gt_info;
 		if (sna->PciInfo->device_id & 0xf) {
-			state->info = &hsw_gt1_info;
-			if (is_gt2(sna))
+			if (is_gt3(sna))
+				state->info = &hsw_gt3_info;
+			else if (is_gt2(sna))
 				state->info = &hsw_gt2_info;
+			else
+				state->info = &hsw_gt1_info;
 		}
 	} else
 		return false;


More information about the xorg-commit mailing list