diff mbox

[11/13] drm/i915: pipelined fencing, part 1: fence stealing

Message ID 1265317513-27723-12-git-send-email-daniel.vetter@ffwll.ch (mailing list archive)
State Rejected
Headers show

Commit Message

Daniel Vetter Feb. 4, 2010, 9:05 p.m. UTC
None
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f26a037..c684d0e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -871,8 +871,8 @@  void i915_gem_release_mmap(struct drm_gem_object *obj);
 void i915_gem_lastclose(struct drm_device *dev);
 uint32_t i915_get_gem_seqno(struct drm_device *dev);
 bool i915_seqno_passed(uint32_t seq1, uint32_t seq2);
-int i915_gem_object_get_fence_reg(struct drm_gem_object *obj);
-int i915_gem_object_put_fence_reg(struct drm_gem_object *obj);
+int i915_gem_object_get_fence_reg(struct drm_gem_object *obj, int pipelined);
+int i915_gem_object_put_fence_reg(struct drm_gem_object *obj, int pipelined);
 void i915_gem_retire_requests(struct drm_device *dev);
 void i915_gem_retire_work_handler(struct work_struct *work);
 void i915_gem_clflush_object(struct drm_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 83c7d58..1fd7a65 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -49,7 +49,8 @@  static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *o
 static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
 static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
 					   unsigned alignment);
-static void i915_gem_clear_fence_reg(struct drm_gem_object *obj);
+static void i915_gem_clear_fence_reg(struct drm_gem_object *obj,
+				     int pipelined);
 static int i915_gem_evict_something(struct drm_device *dev, int min_size);
 static int i915_gem_evict_from_inactive_list(struct drm_device *dev);
 static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
@@ -1215,7 +1216,7 @@  int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 
 	/* Need a new fence register? */
 	if (obj_priv->tiling_mode != I915_TILING_NONE) {
-		ret = i915_gem_object_get_fence_reg(obj);
+		ret = i915_gem_object_get_fence_reg(obj, 0);
 		if (ret)
 			goto unlock;
 	}
@@ -2075,7 +2076,7 @@  i915_gem_object_unbind(struct drm_gem_object *obj)
 
 	/* release the fence reg _after_ flushing */
 	if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
-		i915_gem_clear_fence_reg(obj);
+		i915_gem_clear_fence_reg(obj, 0);
 
 	if (obj_priv->agp_mem != NULL) {
 		drm_unbind_agp(obj_priv->agp_mem);
@@ -2426,7 +2427,7 @@  static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
 	I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val);
 }
 
-static int i915_find_fence_reg(struct drm_device *dev)
+static int i915_find_fence_reg(struct drm_device *dev, int pipelined)
 {
 	struct drm_i915_fence_reg *reg = NULL;
 	struct drm_i915_gem_object *obj_priv = NULL;
@@ -2471,7 +2472,7 @@  static int i915_find_fence_reg(struct drm_device *dev)
 	 * under us.
 	 */
 	drm_gem_object_reference(obj);
-	ret = i915_gem_object_put_fence_reg(obj);
+	ret = i915_gem_object_put_fence_reg(obj, pipelined);
 	drm_gem_object_unreference(obj);
 	if (ret != 0)
 		return ret;
@@ -2493,7 +2494,7 @@  static int i915_find_fence_reg(struct drm_device *dev)
  * and tiling format.
  */
 int
-i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
+i915_gem_object_get_fence_reg(struct drm_gem_object *obj, int pipelined)
 {
 	struct drm_device *dev = obj->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2528,7 +2529,7 @@  i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
 		break;
 	}
 
-	ret = i915_find_fence_reg(dev);
+	ret = i915_find_fence_reg(dev, pipelined);
 	if (ret < 0)
 		return ret;
 
@@ -2538,6 +2539,12 @@  i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
 
 	reg->obj = obj;
 
+	if (pipelined && reg->last_rendering_seqno != 0) {
+		ret = i915_wait_request(dev, reg->last_rendering_seqno);
+		if (ret != 0)
+			return ret;
+	}
+
 	if (IS_I965G(dev))
 		i965_write_fence_reg(reg);
 	else if (IS_I9XX(dev))
@@ -2559,7 +2566,7 @@  i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
  * data structures in dev_priv and obj_priv.
  */
 static void
-i915_gem_clear_fence_reg(struct drm_gem_object *obj)
+i915_gem_clear_fence_reg(struct drm_gem_object *obj, int pipelined)
 {
 	struct drm_device *dev = obj->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -2567,6 +2574,8 @@  i915_gem_clear_fence_reg(struct drm_gem_object *obj)
 	struct drm_i915_fence_reg *reg =
 		&dev_priv->fence_regs[obj_priv->fence_reg];
 
+	if (pipelined)
+		goto end;
 	if (IS_I965G(dev))
 		I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0);
 	else {
@@ -2581,6 +2590,7 @@  i915_gem_clear_fence_reg(struct drm_gem_object *obj)
 		I915_WRITE(fence_reg, 0);
 	}
 
+end:
 	reg->obj = NULL;
 	obj_priv->fence_reg = I915_FENCE_REG_NONE;
 	list_del_init(&reg->lru_list);
@@ -2595,7 +2605,8 @@  i915_gem_clear_fence_reg(struct drm_gem_object *obj)
  * data structures in dev_priv and obj_priv.
  */
 int
-i915_gem_object_put_fence_reg(struct drm_gem_object *obj)
+i915_gem_object_put_fence_reg(struct drm_gem_object *obj,
+			      int pipelined)
 {
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
 
@@ -2611,13 +2622,13 @@  i915_gem_object_put_fence_reg(struct drm_gem_object *obj)
 	if (obj_priv->fenced_gpu_access) {
 		int ret;
 
-		ret = i915_gem_object_flush_gpu_write_domain(obj, 0);
+		ret = i915_gem_object_flush_gpu_write_domain(obj, pipelined);
 		if (ret != 0)
 			return ret;
 	}
 
 	i915_gem_object_flush_gtt_write_domain(obj);
-	i915_gem_clear_fence_reg (obj);
+	i915_gem_clear_fence_reg(obj, pipelined);
 
 	return 0;
 }
@@ -3317,7 +3328,7 @@  i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
 	 * properly handle blits to/from tiled surfaces.
 	 */
 	if (need_fence) {
-		ret = i915_gem_object_get_fence_reg(obj);
+		ret = i915_gem_object_get_fence_reg(obj, 1);
 		if (ret != 0) {
 			if (ret != -EBUSY && ret != -ERESTARTSYS)
 				DRM_ERROR("Failure to install fence: %d\n",
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index b0cbe3a..6879f04 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -362,7 +362,7 @@  i915_gem_set_tiling(struct drm_device *dev, void *data,
 		if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode))
 		    ret = i915_gem_object_unbind(obj);
 		else
-		    ret = i915_gem_object_put_fence_reg(obj);
+		    ret = i915_gem_object_put_fence_reg(obj, 0);
 		if (ret != 0) {
 			WARN(ret != -ERESTARTSYS,
 			     "failed to reset object for tiling switch");
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9dc2eed..fd870d0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1149,7 +1149,9 @@  intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
 	 */
 	if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
 	    obj_priv->tiling_mode != I915_TILING_NONE) {
-		ret = i915_gem_object_get_fence_reg(obj);
+		/* FIXME: Check whether pipelined fencing makes
+		 * sense for the pageflip. */
+		ret = i915_gem_object_get_fence_reg(obj, 0);
 		if (ret != 0) {
 			i915_gem_object_unpin(obj);
 			return ret;