Module Name:    xsrc
Committed By:   mrg
Date:           Sun Nov 21 07:51:29 UTC 2010

Modified Files:
        xsrc/external/mit/libdrm/dist: xf86drm.c
        xsrc/external/mit/libdrm/dist/intel: intel_bufmgr_gem.c

Log Message:
merge cornflakes for libdrm 2.4.22


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 xsrc/external/mit/libdrm/dist/xf86drm.c
cvs rdiff -u -r1.3 -r1.4 \
    xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c

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/xf86drm.c
diff -u xsrc/external/mit/libdrm/dist/xf86drm.c:1.2 xsrc/external/mit/libdrm/dist/xf86drm.c:1.3
--- xsrc/external/mit/libdrm/dist/xf86drm.c:1.2	Sat May 22 21:47:42 2010
+++ xsrc/external/mit/libdrm/dist/xf86drm.c	Sun Nov 21 07:51:29 2010
@@ -230,7 +230,7 @@
  * PCI:b:d:f format and the newer pci:oooo:bb:dd.f format.  In the format, o is
  * domain, b is bus, d is device, f is function.
  */
-static int drmMatchBusID(const char *id1, const char *id2)
+static int drmMatchBusID(const char *id1, const char *id2, int pci_domain_ok)
 {
     /* First, check if the IDs are exactly the same */
     if (strcasecmp(id1, id2) == 0)
@@ -258,6 +258,13 @@
 		return 0;
 	}
 
+	/* If domains aren't properly supported by the kernel interface,
+	 * just ignore them, which sucks less than picking a totally random
+	 * card with "open by name"
+	 */
+	if (!pci_domain_ok)
+		o1 = o2 = 0;
+
 	if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2))
 	    return 0;
 	else
@@ -483,7 +490,7 @@
  */
 static int drmOpenByBusid(const char *busid)
 {
-    int        i;
+    int        i, pci_domain_ok = 1;
     int        fd;
     const char *buf;
     drmSetVersion sv;
@@ -493,16 +500,27 @@
 	fd = drmOpenMinor(i, 1, DRM_NODE_RENDER);
 	drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
 	if (fd >= 0) {
+	    /* We need to try for 1.4 first for proper PCI domain support
+	     * and if that fails, we know the kernel is busted
+	     */
 	    sv.drm_di_major = 1;
-	    sv.drm_di_minor = 1;
+	    sv.drm_di_minor = 4;
 	    sv.drm_dd_major = -1;	/* Don't care */
 	    sv.drm_dd_minor = -1;	/* Don't care */
-	    if (drmSetInterfaceVersion(fd, &sv) < 0) {
-	        drmMsg("drmOpenByBusid: drmSetInterfaceVersion failed: %s\n", strerror(errno));
+	    if (drmSetInterfaceVersion(fd, &sv)) {
+#ifndef __alpha__
+		pci_domain_ok = 0;
+#endif
+		sv.drm_di_major = 1;
+		sv.drm_di_minor = 1;
+		sv.drm_dd_major = -1;       /* Don't care */
+		sv.drm_dd_minor = -1;       /* Don't care */
+		drmMsg("drmOpenByBusid: Interface 1.4 failed, trying 1.1\n",fd);
+		drmSetInterfaceVersion(fd, &sv);
 	    }
 	    buf = drmGetBusid(fd);
 	    drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf);
-	    if (buf && drmMatchBusID(buf, busid)) {
+	    if (buf && drmMatchBusID(buf, busid, pci_domain_ok)) {
 		drmFreeBusid(buf);
 		return fd;
 	    }

Index: xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c
diff -u xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c:1.3 xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c:1.4
--- xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c:1.3	Sat Aug 14 10:19:32 2010
+++ xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c	Sun Nov 21 07:51:29 2010
@@ -94,6 +94,7 @@
 	/** Array of lists of cached gem objects of power-of-two sizes */
 	struct drm_intel_gem_bo_bucket cache_bucket[14 * 4];
 	int num_buckets;
+	time_t time;
 
 	uint64_t gtt_size;
 	int available_fences;
@@ -133,6 +134,7 @@
 	 */
 	uint32_t tiling_mode;
 	uint32_t swizzle_mode;
+	unsigned long stride;
 
 	time_t free_time;
 
@@ -201,8 +203,9 @@
 			    uint32_t * swizzle_mode);
 
 static int
-drm_intel_gem_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
-			    uint32_t stride);
+drm_intel_gem_bo_set_tiling_internal(drm_intel_bo *bo,
+				     uint32_t tiling_mode,
+				     uint32_t stride);
 
 static void drm_intel_gem_bo_unreference_locked_timed(drm_intel_bo *bo,
 						      time_t time);
@@ -252,7 +255,7 @@
  */
 static unsigned long
 drm_intel_gem_bo_tile_pitch(drm_intel_bufmgr_gem *bufmgr_gem,
-			    unsigned long pitch, uint32_t tiling_mode)
+			    unsigned long pitch, uint32_t *tiling_mode)
 {
 	unsigned long tile_width;
 	unsigned long i;
@@ -260,10 +263,10 @@
 	/* If untiled, then just align it so that we can do rendering
 	 * to it with the 3D engine.
 	 */
-	if (tiling_mode == I915_TILING_NONE)
+	if (*tiling_mode == I915_TILING_NONE)
 		return ALIGN(pitch, 64);
 
-	if (tiling_mode == I915_TILING_X)
+	if (*tiling_mode == I915_TILING_X)
 		tile_width = 512;
 	else
 		tile_width = 128;
@@ -272,6 +275,14 @@
 	if (bufmgr_gem->gen >= 4)
 		return ROUND_UP_TO(pitch, tile_width);
 
+	/* The older hardware has a maximum pitch of 8192 with tiled
+	 * surfaces, so fallback to untiled if it's too large.
+	 */
+	if (pitch > 8192) {
+		*tiling_mode = I915_TILING_NONE;
+		return ALIGN(pitch, 64);
+	}
+
 	/* Pre-965 needs power of two tile width */
 	for (i = tile_width; i < pitch; i <<= 1)
 		;
@@ -497,9 +508,7 @@
 	memset(&busy, 0, sizeof(busy));
 	busy.handle = bo_gem->gem_handle;
 
-	do {
-		ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
-	} while (ret == -1 && errno == EINTR);
+	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
 
 	return (ret == 0 && busy.busy);
 }
@@ -513,7 +522,7 @@
 	madv.handle = bo_gem->gem_handle;
 	madv.madv = state;
 	madv.retained = 1;
-	ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv);
+	drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv);
 
 	return madv.retained;
 }
@@ -550,7 +559,9 @@
 drm_intel_gem_bo_alloc_internal(drm_intel_bufmgr *bufmgr,
 				const char *name,
 				unsigned long size,
-				unsigned long flags)
+				unsigned long flags,
+				uint32_t tiling_mode,
+				unsigned long stride)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
 	drm_intel_bo_gem *bo_gem;
@@ -616,6 +627,13 @@
 								    bucket);
 				goto retry;
 			}
+
+			if (drm_intel_gem_bo_set_tiling_internal(&bo_gem->bo,
+								 tiling_mode,
+								 stride)) {
+				drm_intel_gem_bo_free(&bo_gem->bo);
+				goto retry;
+			}
 		}
 	}
 	pthread_mutex_unlock(&bufmgr_gem->lock);
@@ -631,11 +649,9 @@
 		memset(&create, 0, sizeof(create));
 		create.size = bo_size;
 
-		do {
-			ret = ioctl(bufmgr_gem->fd,
-				    DRM_IOCTL_I915_GEM_CREATE,
-				    &create);
-		} while (ret == -1 && errno == EINTR);
+		ret = drmIoctl(bufmgr_gem->fd,
+			       DRM_IOCTL_I915_GEM_CREATE,
+			       &create);
 		bo_gem->gem_handle = create.handle;
 		bo_gem->bo.handle = bo_gem->gem_handle;
 		if (ret != 0) {
@@ -643,6 +659,17 @@
 			return NULL;
 		}
 		bo_gem->bo.bufmgr = bufmgr;
+
+		bo_gem->tiling_mode = I915_TILING_NONE;
+		bo_gem->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
+		bo_gem->stride = 0;
+
+		if (drm_intel_gem_bo_set_tiling_internal(&bo_gem->bo,
+							 tiling_mode,
+							 stride)) {
+		    drm_intel_gem_bo_free(&bo_gem->bo);
+		    return NULL;
+		}
 	}
 
 	bo_gem->name = name;
@@ -651,8 +678,6 @@
 	bo_gem->reloc_tree_fences = 0;
 	bo_gem->used_as_reloc_target = 0;
 	bo_gem->has_error = 0;
-	bo_gem->tiling_mode = I915_TILING_NONE;
-	bo_gem->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
 	bo_gem->reusable = 1;
 
 	drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem);
@@ -670,7 +695,8 @@
 				  unsigned int alignment)
 {
 	return drm_intel_gem_bo_alloc_internal(bufmgr, name, size,
-					       BO_ALLOC_FOR_RENDER);
+					       BO_ALLOC_FOR_RENDER,
+					       I915_TILING_NONE, 0);
 }
 
 static drm_intel_bo *
@@ -679,7 +705,8 @@
 		       unsigned long size,
 		       unsigned int alignment)
 {
-	return drm_intel_gem_bo_alloc_internal(bufmgr, name, size, 0);
+	return drm_intel_gem_bo_alloc_internal(bufmgr, name, size, 0,
+					       I915_TILING_NONE, 0);
 }
 
 static drm_intel_bo *
@@ -688,10 +715,8 @@
 			     unsigned long *pitch, unsigned long flags)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
-	drm_intel_bo *bo;
 	unsigned long size, stride;
 	uint32_t tiling;
-	int ret;
 
 	do {
 		unsigned long aligned_y;
@@ -718,24 +743,17 @@
 			aligned_y = ALIGN(y, 32);
 
 		stride = x * cpp;
-		stride = drm_intel_gem_bo_tile_pitch(bufmgr_gem, stride, tiling);
+		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);
 	} while (*tiling_mode != tiling);
-
-	bo = drm_intel_gem_bo_alloc_internal(bufmgr, name, size, flags);
-	if (!bo)
-		return NULL;
-
-	ret = drm_intel_gem_bo_set_tiling(bo, tiling_mode, stride);
-	if (ret != 0) {
-		drm_intel_gem_bo_unreference(bo);
-		return NULL;
-	}
-
 	*pitch = stride;
 
-	return bo;
+	if (tiling == I915_TILING_NONE)
+		stride = 0;
+
+	return drm_intel_gem_bo_alloc_internal(bufmgr, name, size, flags,
+					       tiling, stride);
 }
 
 /**
@@ -761,11 +779,9 @@
 
 	memset(&open_arg, 0, sizeof(open_arg));
 	open_arg.name = handle;
-	do {
-		ret = ioctl(bufmgr_gem->fd,
-			    DRM_IOCTL_GEM_OPEN,
-			    &open_arg);
-	} while (ret == -1 && errno == EINTR);
+	ret = drmIoctl(bufmgr_gem->fd,
+		       DRM_IOCTL_GEM_OPEN,
+		       &open_arg);
 	if (ret != 0) {
 		fprintf(stderr, "Couldn't reference %s handle 0x%08x: %s\n",
 			name, handle, strerror(errno));
@@ -785,13 +801,16 @@
 
 	memset(&get_tiling, 0, sizeof(get_tiling));
 	get_tiling.handle = bo_gem->gem_handle;
-	ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &get_tiling);
+	ret = drmIoctl(bufmgr_gem->fd,
+		       DRM_IOCTL_I915_GEM_GET_TILING,
+		       &get_tiling);
 	if (ret != 0) {
 		drm_intel_gem_bo_unreference(&bo_gem->bo);
 		return NULL;
 	}
 	bo_gem->tiling_mode = get_tiling.tiling_mode;
 	bo_gem->swizzle_mode = get_tiling.swizzle_mode;
+	/* XXX stride is unknown */
 	drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem);
 
 	DBG("bo_create_from_handle: %d (%s)\n", handle, bo_gem->name);
@@ -815,7 +834,7 @@
 	/* Close this object */
 	memset(&close, 0, sizeof(close));
 	close.handle = bo_gem->gem_handle;
-	ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close);
+	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close);
 	if (ret != 0) {
 		fprintf(stderr,
 			"DRM_IOCTL_GEM_CLOSE %d failed (%s): %s\n",
@@ -830,6 +849,9 @@
 {
 	int i;
 
+	if (bufmgr_gem->time == time)
+		return;
+
 	for (i = 0; i < bufmgr_gem->num_buckets; i++) {
 		struct drm_intel_gem_bo_bucket *bucket =
 		    &bufmgr_gem->cache_bucket[i];
@@ -847,6 +869,8 @@
 			drm_intel_gem_bo_free(&bo_gem->bo);
 		}
 	}
+
+	bufmgr_gem->time = time;
 }
 
 static void
@@ -855,7 +879,6 @@
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
 	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
 	struct drm_intel_gem_bo_bucket *bucket;
-	uint32_t tiling_mode;
 	int i;
 
 	/* Unreference all the target buffers */
@@ -884,9 +907,7 @@
 
 	bucket = drm_intel_gem_bo_bucket_for_size(bufmgr_gem, bo->size);
 	/* Put the buffer into our internal cache for reuse if we can. */
-	tiling_mode = I915_TILING_NONE;
 	if (bufmgr_gem->bo_reuse && bo_gem->reusable && bucket != NULL &&
-	    drm_intel_gem_bo_set_tiling(bo, &tiling_mode, 0) == 0 &&
 	    drm_intel_gem_bo_madvise_internal(bufmgr_gem, bo_gem,
 					      I915_MADV_DONTNEED)) {
 		bo_gem->free_time = time;
@@ -895,8 +916,6 @@
 		bo_gem->validate_index = -1;
 
 		DRMLISTADDTAIL(&bo_gem->head, &bucket->head);
-
-		drm_intel_gem_cleanup_bo_cache(bufmgr_gem, time);
 	} else {
 		drm_intel_gem_bo_free(bo);
 	}
@@ -926,6 +945,7 @@
 
 		pthread_mutex_lock(&bufmgr_gem->lock);
 		drm_intel_gem_bo_unreference_final(bo, time.tv_sec);
+		drm_intel_gem_cleanup_bo_cache(bufmgr_gem, time.tv_sec);
 		pthread_mutex_unlock(&bufmgr_gem->lock);
 	}
 }
@@ -951,11 +971,9 @@
 		mmap_arg.handle = bo_gem->gem_handle;
 		mmap_arg.offset = 0;
 		mmap_arg.size = bo->size;
-		do {
-			ret = ioctl(bufmgr_gem->fd,
-				    DRM_IOCTL_I915_GEM_MMAP,
-				    &mmap_arg);
-		} while (ret == -1 && errno == EINTR);
+		ret = drmIoctl(bufmgr_gem->fd,
+			       DRM_IOCTL_I915_GEM_MMAP,
+			       &mmap_arg);
 		if (ret != 0) {
 			ret = -errno;
 			fprintf(stderr,
@@ -977,18 +995,13 @@
 		set_domain.write_domain = I915_GEM_DOMAIN_CPU;
 	else
 		set_domain.write_domain = 0;
-	do {
-		ret = ioctl(bufmgr_gem->fd,
-			    DRM_IOCTL_I915_GEM_SET_DOMAIN,
-			    &set_domain);
-	} while (ret == -1 && errno == EINTR);
+	ret = drmIoctl(bufmgr_gem->fd,
+		       DRM_IOCTL_I915_GEM_SET_DOMAIN,
+		       &set_domain);
 	if (ret != 0) {
-		ret = -errno;
 		fprintf(stderr, "%s:%d: Error setting to CPU domain %d: %s\n",
 			__FILE__, __LINE__, bo_gem->gem_handle,
 			strerror(errno));
-		pthread_mutex_unlock(&bufmgr_gem->lock);
-		return ret;
 	}
 
 	pthread_mutex_unlock(&bufmgr_gem->lock);
@@ -1016,11 +1029,9 @@
 		mmap_arg.handle = bo_gem->gem_handle;
 
 		/* Get the fake offset back... */
-		do {
-			ret = ioctl(bufmgr_gem->fd,
-				    DRM_IOCTL_I915_GEM_MMAP_GTT,
-				    &mmap_arg);
-		} while (ret == -1 && errno == EINTR);
+		ret = drmIoctl(bufmgr_gem->fd,
+			       DRM_IOCTL_I915_GEM_MMAP_GTT,
+			       &mmap_arg);
 		if (ret != 0) {
 			ret = -errno;
 			fprintf(stderr,
@@ -1058,14 +1069,10 @@
 	set_domain.handle = bo_gem->gem_handle;
 	set_domain.read_domains = I915_GEM_DOMAIN_GTT;
 	set_domain.write_domain = I915_GEM_DOMAIN_GTT;
-	do {
-		ret = ioctl(bufmgr_gem->fd,
-			    DRM_IOCTL_I915_GEM_SET_DOMAIN,
-			    &set_domain);
-	} while (ret == -1 && errno == EINTR);
-
+	ret = drmIoctl(bufmgr_gem->fd,
+		       DRM_IOCTL_I915_GEM_SET_DOMAIN,
+		       &set_domain);
 	if (ret != 0) {
-		ret = -errno;
 		fprintf(stderr, "%s:%d: Error setting domain %d: %s\n",
 			__FILE__, __LINE__, bo_gem->gem_handle,
 			strerror(errno));
@@ -1073,7 +1080,7 @@
 
 	pthread_mutex_unlock(&bufmgr_gem->lock);
 
-	return ret;
+	return 0;
 }
 
 int drm_intel_gem_bo_unmap_gtt(drm_intel_bo *bo)
@@ -1112,11 +1119,9 @@
 	 * results show up in a timely manner.
 	 */
 	sw_finish.handle = bo_gem->gem_handle;
-	do {
-		ret = ioctl(bufmgr_gem->fd,
-			    DRM_IOCTL_I915_GEM_SW_FINISH,
-			    &sw_finish);
-	} while (ret == -1 && errno == EINTR);
+	ret = drmIoctl(bufmgr_gem->fd,
+		       DRM_IOCTL_I915_GEM_SW_FINISH,
+		       &sw_finish);
 	ret = ret == -1 ? -errno : 0;
 
 	bo->virtual = NULL;
@@ -1139,11 +1144,9 @@
 	pwrite.offset = offset;
 	pwrite.size = size;
 	pwrite.data_ptr = (uint64_t) (uintptr_t) data;
-	do {
-		ret = ioctl(bufmgr_gem->fd,
-			    DRM_IOCTL_I915_GEM_PWRITE,
-			    &pwrite);
-	} while (ret == -1 && errno == EINTR);
+	ret = drmIoctl(bufmgr_gem->fd,
+		       DRM_IOCTL_I915_GEM_PWRITE,
+		       &pwrite);
 	if (ret != 0) {
 		ret = -errno;
 		fprintf(stderr,
@@ -1163,8 +1166,9 @@
 	int ret;
 
 	get_pipe_from_crtc_id.crtc_id = crtc_id;
-	ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID,
-		    &get_pipe_from_crtc_id);
+	ret = drmIoctl(bufmgr_gem->fd,
+		       DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID,
+		       &get_pipe_from_crtc_id);
 	if (ret != 0) {
 		/* We return -1 here to signal that we don't
 		 * know which pipe is associated with this crtc.
@@ -1192,11 +1196,9 @@
 	pread.offset = offset;
 	pread.size = size;
 	pread.data_ptr = (uint64_t) (uintptr_t) data;
-	do {
-		ret = ioctl(bufmgr_gem->fd,
-			    DRM_IOCTL_I915_GEM_PREAD,
-			    &pread);
-	} while (ret == -1 && errno == EINTR);
+	ret = drmIoctl(bufmgr_gem->fd,
+		       DRM_IOCTL_I915_GEM_PREAD,
+		       &pread);
 	if (ret != 0) {
 		ret = -errno;
 		fprintf(stderr,
@@ -1233,11 +1235,9 @@
 	set_domain.handle = bo_gem->gem_handle;
 	set_domain.read_domains = I915_GEM_DOMAIN_GTT;
 	set_domain.write_domain = write_enable ? I915_GEM_DOMAIN_GTT : 0;
-	do {
-		ret = ioctl(bufmgr_gem->fd,
-			    DRM_IOCTL_I915_GEM_SET_DOMAIN,
-			    &set_domain);
-	} while (ret == -1 && errno == EINTR);
+	ret = drmIoctl(bufmgr_gem->fd,
+		       DRM_IOCTL_I915_GEM_SET_DOMAIN,
+		       &set_domain);
 	if (ret != 0) {
 		fprintf(stderr,
 			"%s:%d: Error setting memory domains %d (%08x %08x): %s .\n",
@@ -1508,12 +1508,9 @@
 	execbuf.DR1 = 0;
 	execbuf.DR4 = DR4;
 
-	do {
-		ret = ioctl(bufmgr_gem->fd,
-			    DRM_IOCTL_I915_GEM_EXECBUFFER,
-			    &execbuf);
-	} while (ret != 0 && errno == EINTR);
-
+	ret = drmIoctl(bufmgr_gem->fd,
+		       DRM_IOCTL_I915_GEM_EXECBUFFER,
+		       &execbuf);
 	if (ret != 0) {
 		ret = -errno;
 		if (errno == ENOSPC) {
@@ -1581,14 +1578,12 @@
 	execbuf.rsvd1 = 0;
 	execbuf.rsvd2 = 0;
 
-	do {
-		ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2,
-			    &execbuf);
-	} while (ret != 0 && errno == EINTR);
-
+	ret = drmIoctl(bufmgr_gem->fd,
+		       DRM_IOCTL_I915_GEM_EXECBUFFER2,
+		       &execbuf);
 	if (ret != 0) {
 		ret = -errno;
-		if (ret == -ENOMEM) {
+		if (ret == -ENOSPC) {
 			fprintf(stderr,
 				"Execbuffer fails to pin. "
 				"Estimate: %u. Actual: %u. Available: %u\n",
@@ -1640,12 +1635,9 @@
 	pin.handle = bo_gem->gem_handle;
 	pin.alignment = alignment;
 
-	do {
-		ret = ioctl(bufmgr_gem->fd,
-			    DRM_IOCTL_I915_GEM_PIN,
-			    &pin);
-	} while (ret == -1 && errno == EINTR);
-
+	ret = drmIoctl(bufmgr_gem->fd,
+		       DRM_IOCTL_I915_GEM_PIN,
+		       &pin);
 	if (ret != 0)
 		return -errno;
 
@@ -1664,7 +1656,7 @@
 	memset(&unpin, 0, sizeof(unpin));
 	unpin.handle = bo_gem->gem_handle;
 
-	ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_UNPIN, &unpin);
+	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_UNPIN, &unpin);
 	if (ret != 0)
 		return -errno;
 
@@ -1672,34 +1664,60 @@
 }
 
 static int
-drm_intel_gem_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
-			    uint32_t stride)
+drm_intel_gem_bo_set_tiling_internal(drm_intel_bo *bo,
+				     uint32_t tiling_mode,
+				     uint32_t stride)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
 	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
 	struct drm_i915_gem_set_tiling set_tiling;
 	int ret;
 
-	if (bo_gem->global_name == 0 && *tiling_mode == bo_gem->tiling_mode)
+	if (bo_gem->global_name == 0 &&
+	    tiling_mode == bo_gem->tiling_mode &&
+	    stride == bo_gem->stride)
 		return 0;
 
 	memset(&set_tiling, 0, sizeof(set_tiling));
-	set_tiling.handle = bo_gem->gem_handle;
-
 	do {
-		set_tiling.tiling_mode = *tiling_mode;
+		/* set_tiling is slightly broken and overwrites the
+		 * input on the error path, so we have to open code
+		 * rmIoctl.
+		 */
+		set_tiling.handle = bo_gem->gem_handle;
+		set_tiling.tiling_mode = tiling_mode;
 		set_tiling.stride = stride;
 
 		ret = ioctl(bufmgr_gem->fd,
 			    DRM_IOCTL_I915_GEM_SET_TILING,
 			    &set_tiling);
-	} while (ret == -1 && errno == EINTR);
-	if (ret == 0) {
-		bo_gem->tiling_mode = set_tiling.tiling_mode;
-		bo_gem->swizzle_mode = set_tiling.swizzle_mode;
+	} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+	if (ret == -1)
+		return -errno;
+
+	bo_gem->tiling_mode = set_tiling.tiling_mode;
+	bo_gem->swizzle_mode = set_tiling.swizzle_mode;
+	bo_gem->stride = set_tiling.stride;
+	return 0;
+}
+
+static int
+drm_intel_gem_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
+			    uint32_t stride)
+{
+	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
+	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
+	int ret;
+
+	/* Linear buffers have no stride. By ensuring that we only ever use
+	 * stride 0 with linear buffers, we simplify our code.
+	 */
+	if (*tiling_mode == I915_TILING_NONE)
+		stride = 0;
+
+	ret = drm_intel_gem_bo_set_tiling_internal(bo, *tiling_mode, stride);
+	if (ret == 0)
 		drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem);
-	} else
-		ret = -errno;
 
 	*tiling_mode = bo_gem->tiling_mode;
 	return ret;
@@ -1728,7 +1746,7 @@
 		memset(&flink, 0, sizeof(flink));
 		flink.handle = bo_gem->gem_handle;
 
-		ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_FLINK, &flink);
+		ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_FLINK, &flink);
 		if (ret != 0)
 			return -errno;
 		bo_gem->global_name = flink.name;
@@ -2059,7 +2077,9 @@
 		return NULL;
 	}
 
-	ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
+	ret = drmIoctl(bufmgr_gem->fd,
+		       DRM_IOCTL_I915_GEM_GET_APERTURE,
+		       &aperture);
 
 	if (ret == 0)
 		bufmgr_gem->gtt_size = aperture.aper_available_size;
@@ -2075,7 +2095,7 @@
 
 	gp.param = I915_PARAM_CHIPSET_ID;
 	gp.value = &bufmgr_gem->pci_device;
-	ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
+	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
 	if (ret) {
 		fprintf(stderr, "get chip id failed: %d [%d]\n", ret, errno);
 		fprintf(stderr, "param: %d, val: %d\n", gp.param, *gp.value);
@@ -2091,19 +2111,19 @@
 		bufmgr_gem->gen = 6;
 
 	gp.param = I915_PARAM_HAS_EXECBUF2;
-	ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
+	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
 	if (!ret)
 		exec2 = 1;
 
 	gp.param = I915_PARAM_HAS_BSD;
-	ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
+	ret = drmIoctl(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;
-		ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
+		ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
 		if (ret) {
 			fprintf(stderr, "get fences failed: %d [%d]\n", ret,
 				errno);

Reply via email to