Module Name:    xsrc
Committed By:   mrg
Date:           Sat Aug 14 10:19:32 UTC 2010

Modified Files:
        xsrc/external/mit/libdrm/dist: xf86atomic.h
        xsrc/external/mit/libdrm/dist/intel: intel_bufmgr_gem.c
Removed Files:
        xsrc/external/mit/libdrm/dist/nouveau: nouveau_class.h

Log Message:
merge libdrm 2.4.21.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 xsrc/external/mit/libdrm/dist/xf86atomic.h
cvs rdiff -u -r1.2 -r1.3 \
    xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c
cvs rdiff -u -r1.1.1.1 -r0 \
    xsrc/external/mit/libdrm/dist/nouveau/nouveau_class.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: xsrc/external/mit/libdrm/dist/xf86atomic.h
diff -u xsrc/external/mit/libdrm/dist/xf86atomic.h:1.2 xsrc/external/mit/libdrm/dist/xf86atomic.h:1.3
--- xsrc/external/mit/libdrm/dist/xf86atomic.h:1.2	Sat May 22 22:13:17 2010
+++ xsrc/external/mit/libdrm/dist/xf86atomic.h	Sat Aug 14 10:19:31 2010
@@ -86,8 +86,8 @@
 # define atomic_set(x, val) ((x)->atomic = (uint_t)(val))
 # define atomic_inc(x) (atomic_inc_uint (&(x)->atomic))
 # define atomic_dec_and_test(x) (atomic_dec_uint_nv(&(x)->atomic) == 1)
-# define atomic_add(x, v) (atomic_add_uint(&(x)->atomic, (v)))
-# define atomic_dec(x, v) (atomic_dec_uint(&(x)->atomic, (v)))
+# define atomic_add(x, v) (atomic_add_int(&(x)->atomic, (v)))
+# define atomic_dec(x, v) (atomic_add_int(&(x)->atomic, -(v)))
 # define atomic_cmpxchg(x, oldv, newv) atomic_cas_uint (&(x)->atomic, oldv, newv)
 
 #endif

Index: xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c
diff -u xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c:1.2 xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c:1.3
--- xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c:1.2	Sat May 22 21:47:42 2010
+++ xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c	Sat Aug 14 10:19:32 2010
@@ -67,6 +67,8 @@
 		fprintf(stderr, __VA_ARGS__);		\
 } while (0)
 
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
 typedef struct _drm_intel_bo_gem drm_intel_bo_gem;
 
 struct drm_intel_gem_bo_bucket {
@@ -74,10 +76,6 @@
 	unsigned long size;
 };
 
-/* Only cache objects up to 64MB.  Bigger than that, and the rounding of the
- * size makes many operations fail that wouldn't otherwise.
- */
-#define DRM_INTEL_GEM_BO_BUCKETS	14
 typedef struct _drm_intel_bufmgr_gem {
 	drm_intel_bufmgr bufmgr;
 
@@ -94,7 +92,8 @@
 	int exec_count;
 
 	/** Array of lists of cached gem objects of power-of-two sizes */
-	struct drm_intel_gem_bo_bucket cache_bucket[DRM_INTEL_GEM_BO_BUCKETS];
+	struct drm_intel_gem_bo_bucket cache_bucket[14 * 4];
+	int num_buckets;
 
 	uint64_t gtt_size;
 	int available_fences;
@@ -286,7 +285,7 @@
 {
 	int i;
 
-	for (i = 0; i < DRM_INTEL_GEM_BO_BUCKETS; i++) {
+	for (i = 0; i < bufmgr_gem->num_buckets; i++) {
 		struct drm_intel_gem_bo_bucket *bucket =
 		    &bufmgr_gem->cache_bucket[i];
 		if (bucket->size >= size) {
@@ -471,7 +470,7 @@
 	bo_gem->relocs = malloc(max_relocs *
 				sizeof(struct drm_i915_gem_relocation_entry));
 	bo_gem->reloc_target_info = malloc(max_relocs *
-					   sizeof(drm_intel_reloc_target *));
+					   sizeof(drm_intel_reloc_target));
 	if (bo_gem->relocs == NULL || bo_gem->reloc_target_info == NULL) {
 		bo_gem->has_error = 1;
 
@@ -690,31 +689,39 @@
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
 	drm_intel_bo *bo;
-	unsigned long size, stride, aligned_y = y;
+	unsigned long size, stride;
+	uint32_t tiling;
 	int ret;
 
-	/* If we're tiled, our allocations are in 8 or 32-row blocks,
-	 * so failure to align our height means that we won't allocate
-	 * enough pages.
-	 *
-	 * If we're untiled, we still have to align to 2 rows high
-	 * because the data port accesses 2x2 blocks even if the
-	 * bottom row isn't to be rendered, so failure to align means
-	 * we could walk off the end of the GTT and fault.  This is
-	 * documented on 965, and may be the case on older chipsets
-	 * too so we try to be careful.
-	 */
-	if (*tiling_mode == I915_TILING_NONE)
-		aligned_y = ALIGN(y, 2);
-	else if (*tiling_mode == I915_TILING_X)
-		aligned_y = ALIGN(y, 8);
-	else if (*tiling_mode == I915_TILING_Y)
-		aligned_y = ALIGN(y, 32);
-
-	stride = x * cpp;
-	stride = drm_intel_gem_bo_tile_pitch(bufmgr_gem, stride, *tiling_mode);
-	size = stride * aligned_y;
-	size = drm_intel_gem_bo_tile_size(bufmgr_gem, size, tiling_mode);
+	do {
+		unsigned long aligned_y;
+
+		tiling = *tiling_mode;
+
+		/* If we're tiled, our allocations are in 8 or 32-row blocks,
+		 * so failure to align our height means that we won't allocate
+		 * enough pages.
+		 *
+		 * If we're untiled, we still have to align to 2 rows high
+		 * because the data port accesses 2x2 blocks even if the
+		 * bottom row isn't to be rendered, so failure to align means
+		 * we could walk off the end of the GTT and fault.  This is
+		 * documented on 965, and may be the case on older chipsets
+		 * too so we try to be careful.
+		 */
+		aligned_y = y;
+		if (tiling == I915_TILING_NONE)
+			aligned_y = ALIGN(y, 2);
+		else if (tiling == I915_TILING_X)
+			aligned_y = ALIGN(y, 8);
+		else if (tiling == I915_TILING_Y)
+			aligned_y = ALIGN(y, 32);
+
+		stride = x * cpp;
+		stride = drm_intel_gem_bo_tile_pitch(bufmgr_gem, stride, tiling);
+		size = stride * aligned_y;
+		size = drm_intel_gem_bo_tile_size(bufmgr_gem, size, tiling_mode);
+	} while (*tiling_mode != tiling);
 
 	bo = drm_intel_gem_bo_alloc_internal(bufmgr, name, size, flags);
 	if (!bo)
@@ -823,7 +830,7 @@
 {
 	int i;
 
-	for (i = 0; i < DRM_INTEL_GEM_BO_BUCKETS; i++) {
+	for (i = 0; i < bufmgr_gem->num_buckets; i++) {
 		struct drm_intel_gem_bo_bucket *bucket =
 		    &bufmgr_gem->cache_bucket[i];
 
@@ -853,9 +860,11 @@
 
 	/* Unreference all the target buffers */
 	for (i = 0; i < bo_gem->reloc_count; i++) {
-		drm_intel_gem_bo_unreference_locked_timed(bo_gem->
-							  reloc_target_info[i].bo,
-							  time);
+		if (bo_gem->reloc_target_info[i].bo != bo) {
+			drm_intel_gem_bo_unreference_locked_timed(bo_gem->
+								  reloc_target_info[i].bo,
+								  time);
+		}
 	}
 	bo_gem->reloc_count = 0;
 	bo_gem->used_as_reloc_target = 0;
@@ -1251,7 +1260,7 @@
 	pthread_mutex_destroy(&bufmgr_gem->lock);
 
 	/* Free any cached buffer objects we were going to reuse */
-	for (i = 0; i < DRM_INTEL_GEM_BO_BUCKETS; i++) {
+	for (i = 0; i < bufmgr_gem->num_buckets; i++) {
 		struct drm_intel_gem_bo_bucket *bucket =
 		    &bufmgr_gem->cache_bucket[i];
 		drm_intel_bo_gem *bo_gem;
@@ -1317,7 +1326,10 @@
 	 * already been accounted for.
 	 */
 	assert(!bo_gem->used_as_reloc_target);
-	bo_gem->reloc_tree_size += target_bo_gem->reloc_tree_size;
+	if (target_bo_gem != bo_gem) {
+		target_bo_gem->used_as_reloc_target = 1;
+		bo_gem->reloc_tree_size += target_bo_gem->reloc_tree_size;
+	}
 	/* An object needing a fence is a tiled buffer, so it won't have
 	 * relocs to other buffers.
 	 */
@@ -1326,7 +1338,6 @@
 	bo_gem->reloc_tree_fences += target_bo_gem->reloc_tree_fences;
 
 	/* Flag the target to disallow further relocations in it. */
-	target_bo_gem->used_as_reloc_target = 1;
 
 	bo_gem->relocs[bo_gem->reloc_count].offset = offset;
 	bo_gem->relocs[bo_gem->reloc_count].delta = target_offset;
@@ -1337,7 +1348,8 @@
 	bo_gem->relocs[bo_gem->reloc_count].presumed_offset = target_bo->offset;
 
 	bo_gem->reloc_target_info[bo_gem->reloc_count].bo = target_bo;
-	drm_intel_gem_bo_reference(target_bo);
+	if (target_bo != bo)
+		drm_intel_gem_bo_reference(target_bo);
 	if (need_fence)
 		bo_gem->reloc_target_info[bo_gem->reloc_count].flags =
 			DRM_INTEL_RELOC_FENCE;
@@ -1388,6 +1400,9 @@
 	for (i = 0; i < bo_gem->reloc_count; i++) {
 		drm_intel_bo *target_bo = bo_gem->reloc_target_info[i].bo;
 
+		if (target_bo == bo)
+			continue;
+
 		/* Continue walking the tree depth-first. */
 		drm_intel_gem_bo_process_reloc(target_bo);
 
@@ -1409,6 +1424,9 @@
 		drm_intel_bo *target_bo = bo_gem->reloc_target_info[i].bo;
 		int need_fence;
 
+		if (target_bo == bo)
+			continue;
+
 		/* Continue walking the tree depth-first. */
 		drm_intel_gem_bo_process_reloc2(target_bo);
 
@@ -1531,14 +1549,17 @@
 }
 
 static int
-drm_intel_gem_bo_exec2(drm_intel_bo *bo, int used,
-		       drm_clip_rect_t *cliprects, int num_cliprects,
-		       int DR4)
+drm_intel_gem_bo_mrb_exec2(drm_intel_bo *bo, int used,
+			drm_clip_rect_t *cliprects, int num_cliprects, int DR4,
+			int ring_flag)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
 	struct drm_i915_gem_execbuffer2 execbuf;
 	int ret, i;
 
+	if ((ring_flag != I915_EXEC_RENDER) && (ring_flag != I915_EXEC_BSD))
+		return -EINVAL;
+
 	pthread_mutex_lock(&bufmgr_gem->lock);
 	/* Update indices and set up the validate list. */
 	drm_intel_gem_bo_process_reloc2(bo);
@@ -1556,7 +1577,7 @@
 	execbuf.num_cliprects = num_cliprects;
 	execbuf.DR1 = 0;
 	execbuf.DR4 = DR4;
-	execbuf.flags = 0;
+	execbuf.flags = ring_flag;
 	execbuf.rsvd1 = 0;
 	execbuf.rsvd2 = 0;
 
@@ -1598,6 +1619,16 @@
 }
 
 static int
+drm_intel_gem_bo_exec2(drm_intel_bo *bo, int used,
+		       drm_clip_rect_t *cliprects, int num_cliprects,
+		       int DR4)
+{
+	return drm_intel_gem_bo_mrb_exec2(bo, used,
+					cliprects, num_cliprects, DR4,
+					I915_EXEC_RENDER);
+}
+
+static int
 drm_intel_gem_bo_pin(drm_intel_bo *bo, uint32_t alignment)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -1663,13 +1694,15 @@
 			    DRM_IOCTL_I915_GEM_SET_TILING,
 			    &set_tiling);
 	} while (ret == -1 && errno == EINTR);
-	bo_gem->tiling_mode = set_tiling.tiling_mode;
-	bo_gem->swizzle_mode = set_tiling.swizzle_mode;
-
-	drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem);
+	if (ret == 0) {
+		bo_gem->tiling_mode = set_tiling.tiling_mode;
+		bo_gem->swizzle_mode = set_tiling.swizzle_mode;
+		drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem);
+	} else
+		ret = -errno;
 
 	*tiling_mode = bo_gem->tiling_mode;
-	return ret == 0 ? 0 : -errno;
+	return ret;
 }
 
 static int
@@ -1922,6 +1955,14 @@
 }
 
 static int
+drm_intel_gem_bo_is_reusable(drm_intel_bo *bo)
+{
+	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
+
+	return bo_gem->reusable;
+}
+
+static int
 _drm_intel_gem_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo)
 {
 	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
@@ -1930,6 +1971,8 @@
 	for (i = 0; i < bo_gem->reloc_count; i++) {
 		if (bo_gem->reloc_target_info[i].bo == target_bo)
 			return 1;
+		if (bo == bo_gem->reloc_target_info[i].bo)
+			continue;
 		if (_drm_intel_gem_bo_references(bo_gem->reloc_target_info[i].bo,
 						target_bo))
 			return 1;
@@ -1951,6 +1994,45 @@
 	return 0;
 }
 
+static void
+add_bucket(drm_intel_bufmgr_gem *bufmgr_gem, int size)
+{
+	unsigned int i = bufmgr_gem->num_buckets;
+
+	assert(i < ARRAY_SIZE(bufmgr_gem->cache_bucket));
+
+	DRMINITLISTHEAD(&bufmgr_gem->cache_bucket[i].head);
+	bufmgr_gem->cache_bucket[i].size = size;
+	bufmgr_gem->num_buckets++;
+}
+
+static void
+init_cache_buckets(drm_intel_bufmgr_gem *bufmgr_gem)
+{
+	unsigned long size, cache_max_size = 64 * 1024 * 1024;
+
+	/* OK, so power of two buckets was too wasteful of memory.
+	 * Give 3 other sizes between each power of two, to hopefully
+	 * cover things accurately enough.  (The alternative is
+	 * probably to just go for exact matching of sizes, and assume
+	 * that for things like composited window resize the tiled
+	 * width/height alignment and rounding of sizes to pages will
+	 * get us useful cache hit rates anyway)
+	 */
+	add_bucket(bufmgr_gem, 4096);
+	add_bucket(bufmgr_gem, 4096 * 2);
+	add_bucket(bufmgr_gem, 4096 * 3);
+
+	/* Initialize the linked lists for BO reuse cache. */
+	for (size = 4 * 4096; size <= cache_max_size; size *= 2) {
+		add_bucket(bufmgr_gem, size);
+
+		add_bucket(bufmgr_gem, size + size * 1 / 4);
+		add_bucket(bufmgr_gem, size + size * 2 / 4);
+		add_bucket(bufmgr_gem, size + size * 3 / 4);
+	}
+}
+
 /**
  * Initializes the GEM buffer manager, which uses the kernel to allocate, map,
  * and manage map buffer objections.
@@ -1963,9 +2045,8 @@
 	drm_intel_bufmgr_gem *bufmgr_gem;
 	struct drm_i915_gem_get_aperture aperture;
 	drm_i915_getparam_t gp;
-	int ret, i;
-	unsigned long size;
-	int exec2 = 0;
+	int ret;
+	int exec2 = 0, has_bsd = 0;
 
 	bufmgr_gem = calloc(1, sizeof(*bufmgr_gem));
 	if (bufmgr_gem == NULL)
@@ -2014,6 +2095,11 @@
 	if (!ret)
 		exec2 = 1;
 
+	gp.param = I915_PARAM_HAS_BSD;
+	ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
+	if (!ret)
+		has_bsd = 1;
+
 	if (bufmgr_gem->gen < 4) {
 		gp.param = I915_PARAM_NUM_FENCES_AVAIL;
 		gp.value = &bufmgr_gem->available_fences;
@@ -2067,9 +2153,11 @@
 	bufmgr_gem->bufmgr.bo_set_tiling = drm_intel_gem_bo_set_tiling;
 	bufmgr_gem->bufmgr.bo_flink = drm_intel_gem_bo_flink;
 	/* Use the new one if available */
-	if (exec2)
+	if (exec2) {
 		bufmgr_gem->bufmgr.bo_exec = drm_intel_gem_bo_exec2;
-	else
+		if (has_bsd)
+			bufmgr_gem->bufmgr.bo_mrb_exec = drm_intel_gem_bo_mrb_exec2;
+	} else
 		bufmgr_gem->bufmgr.bo_exec = drm_intel_gem_bo_exec;
 	bufmgr_gem->bufmgr.bo_busy = drm_intel_gem_bo_busy;
 	bufmgr_gem->bufmgr.bo_madvise = drm_intel_gem_bo_madvise;
@@ -2078,15 +2166,12 @@
 	bufmgr_gem->bufmgr.check_aperture_space =
 	    drm_intel_gem_check_aperture_space;
 	bufmgr_gem->bufmgr.bo_disable_reuse = drm_intel_gem_bo_disable_reuse;
+	bufmgr_gem->bufmgr.bo_is_reusable = drm_intel_gem_bo_is_reusable;
 	bufmgr_gem->bufmgr.get_pipe_from_crtc_id =
 	    drm_intel_gem_get_pipe_from_crtc_id;
 	bufmgr_gem->bufmgr.bo_references = drm_intel_gem_bo_references;
 
-	/* Initialize the linked lists for BO reuse cache. */
-	for (i = 0, size = 4096; i < DRM_INTEL_GEM_BO_BUCKETS; i++, size *= 2) {
-		DRMINITLISTHEAD(&bufmgr_gem->cache_bucket[i].head);
-		bufmgr_gem->cache_bucket[i].size = size;
-	}
+	init_cache_buckets(bufmgr_gem);
 
 	return &bufmgr_gem->bufmgr;
 }

Reply via email to