diff mbox

[13/13] drm/i915: pipelined fencing, part 2: fence setup

Message ID 1265317513-27723-14-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_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 5e90587..483b520 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2339,7 +2339,7 @@  i915_gem_object_get_pages(struct drm_gem_object *obj)
 	return 0;
 }
 
-static void i965_write_fence_reg(struct drm_i915_fence_reg *reg)
+static void i965_write_fence_reg(struct drm_i915_fence_reg *reg, int pipelined)
 {
 	struct drm_gem_object *obj = reg->obj;
 	struct drm_device *dev = obj->dev;
@@ -2347,6 +2347,7 @@  static void i965_write_fence_reg(struct drm_i915_fence_reg *reg)
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
 	int regnum = obj_priv->fence_reg;
 	uint64_t val;
+	RING_LOCALS;
 
 	val = (uint64_t)((obj_priv->gtt_offset + obj->size - 4096) &
 		    0xfffff000) << 32;
@@ -2356,10 +2357,20 @@  static void i965_write_fence_reg(struct drm_i915_fence_reg *reg)
 		val |= 1 << I965_FENCE_TILING_Y_SHIFT;
 	val |= I965_FENCE_REG_VALID;
 
-	I915_WRITE64(FENCE_REG_965_0 + (regnum * 8), val);
+	if (pipelined) {
+		BEGIN_LP_RING(6);
+		OUT_RING(MI_LOAD_REGISTER_IMM);
+		OUT_RING(FENCE_REG_965_0 + (regnum * 8));
+		OUT_RING((uint32_t) val);
+		OUT_RING(MI_LOAD_REGISTER_IMM);
+		OUT_RING(FENCE_REG_965_0 + (regnum * 8) + 4);
+		OUT_RING((uint32_t) (val >> 32));
+		ADVANCE_LP_RING();
+	} else
+		I915_WRITE64(FENCE_REG_965_0 + (regnum * 8), val);
 }
 
-static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
+static void i915_write_fence_reg(struct drm_i915_fence_reg *reg, int pipelined)
 {
 	struct drm_gem_object *obj = reg->obj;
 	struct drm_device *dev = obj->dev;
@@ -2369,6 +2380,7 @@  static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
 	int tile_width;
 	uint32_t fence_reg, val;
 	uint32_t pitch_val;
+	RING_LOCALS;
 
 	if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) ||
 	    (obj_priv->gtt_offset & (obj->size - 1))) {
@@ -2398,10 +2410,18 @@  static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
 		fence_reg = FENCE_REG_830_0 + (regnum * 4);
 	else
 		fence_reg = FENCE_REG_945_8 + ((regnum - 8) * 4);
-	I915_WRITE(fence_reg, val);
+
+	if (pipelined) {
+		BEGIN_LP_RING(3);
+		OUT_RING(MI_LOAD_REGISTER_IMM);
+		OUT_RING(fence_reg);
+		OUT_RING(val);
+		ADVANCE_LP_RING();
+	} else
+		I915_WRITE(fence_reg, val);
 }
 
-static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
+static void i830_write_fence_reg(struct drm_i915_fence_reg *reg, int pipelined)
 {
 	struct drm_gem_object *obj = reg->obj;
 	struct drm_device *dev = obj->dev;
@@ -2411,6 +2431,7 @@  static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
 	uint32_t val;
 	uint32_t pitch_val;
 	uint32_t fence_size_bits;
+	RING_LOCALS;
 
 	if ((obj_priv->gtt_offset & ~I830_FENCE_START_MASK) ||
 	    (obj_priv->gtt_offset & (obj->size - 1))) {
@@ -2432,7 +2453,14 @@  static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
 	val |= pitch_val << I830_FENCE_PITCH_SHIFT;
 	val |= I830_FENCE_REG_VALID;
 
-	I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val);
+	if (pipelined) {
+		BEGIN_LP_RING(3);
+		OUT_RING(MI_LOAD_REGISTER_IMM);
+		OUT_RING(FENCE_REG_830_0 + (regnum * 4));
+		OUT_RING(val);
+		ADVANCE_LP_RING();
+	} else
+		I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val);
 }
 
 static int i915_find_fence_reg(struct drm_device *dev, int pipelined)
@@ -2517,6 +2545,14 @@  i915_gem_object_get_fence_reg(struct drm_gem_object *obj, int pipelined)
 
 		/* Wait for the gpu to setup the fence it it was pipelined. */
 		if (!pipelined && reg->setup_seqno != 0) {
+			/* With certain error conditions, the request might not
+			 * yet have been emitted. */
+			if (reg->setup_seqno == dev_priv->mm.next_gem_seqno) {
+				uint32_t seqno = i915_add_request(dev, NULL);
+				if (seqno == 0)
+					return -ENOMEM;
+			}
+
 			ret = i915_wait_request(dev, reg->setup_seqno);
 			if (ret != 0)
 				return ret;
@@ -2562,18 +2598,12 @@  i915_gem_object_get_fence_reg(struct drm_gem_object *obj, int pipelined)
 	else
 		reg->setup_seqno = 0;
 
-	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);
+		i965_write_fence_reg(reg, pipelined);
 	else if (IS_I9XX(dev))
-		i915_write_fence_reg(reg);
+		i915_write_fence_reg(reg, pipelined);
 	else
-		i830_write_fence_reg(reg);
+		i830_write_fence_reg(reg, pipelined);
 
 	trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg,
 			obj_priv->tiling_mode);