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

Chris Wilson ickle at kemper.freedesktop.org
Tue Jul 3 12:09:21 PDT 2012


 configure.ac        |   10 ++++++
 src/sna/kgem.c      |   83 +++++++++++++++++++++++++++++++++++++++++++++++++---
 src/sna/kgem.h      |    2 +
 src/sna/sna.h       |    3 +
 src/sna/sna_accel.c |   15 ++++++---
 5 files changed, 104 insertions(+), 9 deletions(-)

New commits:
commit 9e2ac8a413c05aafd1c69775c5b0fa5f1f37ac23
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jul 3 19:33:55 2012 +0100

    sna: Use set-cache-level ioctl to create CPU bo
    
    As an alternative to vmap, we can use the kernel for all memory
    management through bo, which is much preferred for its simplicity (i.e.
    avoiding introducing even more vm complexity).
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/configure.ac b/configure.ac
index 604db7d..d1ddf95 100644
--- a/configure.ac
+++ b/configure.ac
@@ -205,6 +205,16 @@ if test "x$accel" = xno; then
 	AC_MSG_ERROR([No default acceleration option])
 fi
 
+AC_ARG_ENABLE(cache-level,
+	      AS_HELP_STRING([--enable-cache-level],
+			     [Enable use of cache level ioctl (experimental) [default=no]]),
+	      [CACHE_LEVEL="$enableval"],
+	      [CACHE_LEVEL=no])
+AM_CONDITIONAL(USE_CACHE_LEVEL, test x$CACHE_LEVEL = xyes)
+if test "x$CACHE_LEVEL" = xyes; then
+	AC_DEFINE(USE_CACHE_LEVEL,1,[Assume DRM_I915_GEM_SET_CACHE_LEVEL_IOCTL support])
+fi
+
 AC_ARG_ENABLE(vmap,
 	      AS_HELP_STRING([--enable-vmap],
 			     [Enable use of vmap (experimental) [default=no]]),
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 43fa705..fceb5d2 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -53,9 +53,9 @@
 static struct kgem_bo *
 search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
 
-
 #define DBG_NO_HW 0
 #define DBG_NO_TILING 0
+#define DBG_NO_CACHE_LEVEL 0
 #define DBG_NO_VMAP 0
 #define DBG_NO_LLC 0
 #define DBG_NO_SEMAPHORES 0
@@ -103,6 +103,23 @@ struct drm_i915_gem_vmap {
 };
 #endif
 
+#if !defined(DRM_I915_GEM_SET_CACHE_LEVEL)
+#define I915_CACHE_NONE		0
+#define I915_CACHE_LLC		1
+#define I915_CACHE_LLC_MLC	2 /* gen6+ */
+
+struct drm_i915_gem_cache_level {
+	/** Handle of the buffer to check for busy */
+	__u32 handle;
+
+	/** Cache level to apply or return value */
+	__u32 cache_level;
+};
+
+#define DRM_I915_GEM_SET_CACHE_LEVEL	0x2f
+#define DRM_IOCTL_I915_GEM_SET_CACHE_LEVEL		DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_SET_CACHE_LEVEL, struct drm_i915_gem_cache_level)
+#endif
+
 struct kgem_partial_bo {
 	struct kgem_bo base;
 	void *mem;
@@ -175,6 +192,16 @@ static int gem_set_tiling(int fd, uint32_t handle, int tiling, int stride)
 	return set_tiling.tiling_mode;
 }
 
+static bool gem_set_cache_level(int fd, uint32_t handle, int cache_level)
+{
+	struct drm_i915_gem_cache_level arg;
+
+	VG_CLEAR(arg);
+	arg.handle = handle;
+	arg.cache_level = cache_level;
+	return drmIoctl(fd, DRM_IOCTL_I915_GEM_SET_CACHE_LEVEL, &arg) == 0;
+}
+
 static bool __kgem_throttle_retire(struct kgem *kgem, unsigned flags)
 {
 	if (flags & CREATE_NO_RETIRE) {
@@ -609,6 +636,30 @@ static bool is_hw_supported(struct kgem *kgem)
 	return true;
 }
 
+static bool test_has_cache_level(struct kgem *kgem)
+{
+#if defined(USE_CACHE_LEVEL)
+	uint32_t handle;
+	bool ret;
+
+	if (DBG_NO_CACHE_LEVEL)
+		return false;
+
+	if (kgem->gen == 40) /* XXX sampler dies with snoopable memory */
+		return false;
+
+	handle = gem_create(kgem->fd, 1);
+	if (handle == 0)
+		return false;
+
+	ret = gem_set_cache_level(kgem->fd, handle, I915_CACHE_NONE);
+	gem_close(kgem->fd, handle);
+	return ret;
+#else
+	return false;
+#endif
+}
+
 void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
 {
 	struct drm_i915_gem_get_aperture aperture;
@@ -658,6 +709,9 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
 
 	kgem->next_request = __kgem_request_alloc();
 
+	kgem->has_cache_level = test_has_cache_level(kgem);
+	DBG(("%s: using set-cache-level=%d\n", __FUNCTION__, kgem->has_cache_level));
+
 #if defined(USE_VMAP)
 	if (!DBG_NO_VMAP)
 		kgem->has_vmap = gem_param(kgem, I915_PARAM_HAS_VMAP) > 0;
@@ -688,8 +742,9 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
 		}
 		kgem->has_llc = has_llc;
 	}
-	DBG(("%s: cpu bo enabled %d: llc? %d, vmap? %d\n", __FUNCTION__,
-	     kgem->has_llc | kgem->has_vmap, kgem->has_llc, kgem->has_vmap));
+	DBG(("%s: cpu bo enabled %d: llc? %d, set-cache-level? %d, vmap? %d\n", __FUNCTION__,
+	     kgem->has_llc | kgem->has_vmap | kgem->has_cache_level,
+	     kgem->has_llc, kgem->has_cache_level, kgem->has_vmap));
 
 	kgem->has_semaphores = false;
 	if (gen >= 60 && semaphores_enabled())
@@ -766,7 +821,7 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
 	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->has_llc | kgem->has_vmap) {
+	if (kgem->has_llc | kgem->has_cache_level | kgem->has_vmap) {
 		if (kgem->large_object_size > kgem->max_cpu_size)
 			kgem->large_object_size = kgem->max_cpu_size;
 	} else
@@ -2616,6 +2671,9 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 	size /= PAGE_SIZE;
 	bucket = cache_bucket(size);
 
+	if (flags & CREATE_FORCE)
+		goto create;
+
 	if (bucket >= NUM_CACHE_BUCKETS) {
 		DBG(("%s: large bo num pages=%d, bucket=%d\n",
 		     __FUNCTION__, size, bucket));
@@ -2988,6 +3046,23 @@ struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
 		return bo;
 	}
 
+	if (kgem->has_cache_level) {
+		bo = kgem_create_2d(kgem, width, height, bpp,
+				    I915_TILING_NONE, flags | CREATE_FORCE);
+		if (bo == NULL)
+			return NULL;
+
+		gem_set_cache_level(kgem->fd, bo->handle, I915_CACHE_LLC);
+		bo->reusable = false;
+
+		if (kgem_bo_map__cpu(kgem, bo) == NULL) {
+			kgem_bo_destroy(kgem, bo);
+			return NULL;
+		}
+
+		return bo;
+	}
+
 	if (kgem->has_vmap) {
 		int stride, size;
 		void *ptr;
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index f9b2a33..22ae401 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -155,6 +155,7 @@ struct kgem {
 	uint32_t has_vmap :1;
 	uint32_t has_relaxed_fencing :1;
 	uint32_t has_semaphores :1;
+	uint32_t has_cache_level :1;
 	uint32_t has_llc :1;
 
 	uint16_t fence_max;
@@ -235,6 +236,7 @@ enum {
 	CREATE_TEMPORARY = 0x20,
 	CREATE_NO_RETIRE = 0x40,
 	CREATE_NO_THROTTLE = 0x40,
+	CREATE_FORCE = 0x80,
 };
 struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 			       int width,
commit f26163e916e21f6b64a19c147165f2f2c9c5466d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jul 3 18:51:46 2012 +0100

    sna: Guess when the client is attempting to read back the whole pixmap
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 9d36543..8564cfc 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -438,7 +438,8 @@ struct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling);
 #define MOVE_INPLACE_HINT 0x4
 #define MOVE_ASYNC_HINT 0x8
 #define MOVE_SOURCE_HINT 0x10
-#define __MOVE_FORCE 0x20
+#define MOVE_WHOLE_HINT 0x20
+#define __MOVE_FORCE 0x40
 bool must_check _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags);
 static inline bool must_check sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags)
 {
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 1eae904..537b287 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1187,7 +1187,6 @@ skip_inplace_map:
 		if (priv->cpu_bo && !priv->cpu_bo->sync && kgem_bo_is_busy(priv->cpu_bo))
 			sna_pixmap_free_cpu(sna, priv);
 		sna_damage_destroy(&priv->gpu_damage);
-		priv->undamaged = true;
 	}
 
 	if (pixmap->devPrivate.ptr == NULL &&
@@ -1466,6 +1465,9 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		goto out;
 	}
 
+	if (flags & MOVE_WHOLE_HINT)
+		return _sna_pixmap_move_to_cpu(pixmap, flags);
+
 	if (priv->gpu_bo == NULL &&
 	    (priv->create & KGEM_CAN_CREATE_GPU) == 0 &&
 	    flags & MOVE_WRITE)
@@ -1872,9 +1874,12 @@ done:
 		sna_damage_reduce_all(&priv->cpu_damage,
 				      pixmap->drawable.width,
 				      pixmap->drawable.height);
-		if (priv->gpu_bo && DAMAGE_IS_ALL(priv->cpu_damage)) {
-			DBG(("%s: replaced entire pixmap\n", __FUNCTION__));
-			sna_pixmap_free_gpu(sna, priv);
+		if (DAMAGE_IS_ALL(priv->cpu_damage)) {
+			if (priv->gpu_bo) {
+				DBG(("%s: replaced entire pixmap\n",
+				     __FUNCTION__));
+				sna_pixmap_free_gpu(sna, priv);
+			}
 			priv->undamaged = false;
 		}
 		if (priv->flush)
@@ -12091,6 +12096,8 @@ sna_get_image(DrawablePtr drawable,
 	flags = MOVE_READ;
 	if ((w | h) == 1)
 		flags |= MOVE_INPLACE_HINT;
+	if (w == drawable->width)
+		flags |= MOVE_WHOLE_HINT;
 	if (!sna_drawable_move_region_to_cpu(drawable, &region, flags))
 		return;
 


More information about the xorg-commit mailing list