[Intel-gfx] [PATCH 11/15] drm/i915: Cleanup handling of last_fenced_seqno
Chris Wilson
chris at chris-wilson.co.uk
Sun Mar 20 09:58:55 CET 2011
Cc: Andy Whitcroft <apw at canonical.com>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_gem.c | 43 +++++++++++++++++++++++++++-----------
1 files changed, 30 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 5201f82..73ede9e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2461,14 +2461,21 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj,
obj->fenced_gpu_access = false;
}
+ if (obj->last_fenced_seqno &&
+ ring_passed_seqno(obj->ring, obj->last_fenced_seqno))
+ obj->last_fenced_seqno = 0;
+
if (obj->last_fenced_seqno && pipelined != obj->ring) {
- if (!ring_passed_seqno(obj->ring, obj->last_fenced_seqno)) {
- ret = i915_wait_request(obj->ring,
- obj->last_fenced_seqno);
- if (ret)
- return ret;
- }
+ ret = i915_wait_request(obj->ring,
+ obj->last_fenced_seqno);
+ if (ret)
+ return ret;
+ /* Since last_fence_seqno can retire much earlier than
+ * last_rendering_seqno, we track that here for efficiency.
+ * (With a catch-all in move_to_inactive() to prevent very
+ * old seqno from lying around.)
+ */
obj->last_fenced_seqno = 0;
}
@@ -2553,7 +2560,6 @@ i915_find_fence_reg(struct drm_device *dev,
* i915_gem_object_get_fence - set up a fence reg for an object
* @obj: object to map through a fence reg
* @pipelined: ring on which to queue the change, or NULL for CPU access
- * @interruptible: must we wait uninterruptibly for the register to retire?
*
* When mapping objects through the GTT, userspace wants to be able to write
* to them without having to worry about swizzling if the object is tiled.
@@ -2561,6 +2567,10 @@ i915_find_fence_reg(struct drm_device *dev,
* This function walks the fence regs looking for a free one for @obj,
* stealing one if it can't find any.
*
+ * Note: if two fence registers point to the same or overlapping memory region
+ * the results are undefined. This is even more fun with asynchronous updates
+ * via the GPU!
+ *
* It then sets up the reg based on the object's properties: address, pitch
* and tiling format.
*/
@@ -2586,9 +2596,6 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
if (ret)
return ret;
- if (!obj->fenced_gpu_access && !obj->last_fenced_seqno)
- pipelined = NULL;
-
goto update;
}
@@ -2606,9 +2613,12 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
reg->setup_ring = NULL;
}
} else if (obj->last_fenced_seqno && obj->ring != pipelined) {
- ret = i915_gem_object_flush_fence(obj, pipelined);
+ ret = i915_wait_request(obj->ring,
+ obj->last_fenced_seqno);
if (ret)
return ret;
+
+ obj->last_fenced_seqno = 0;
}
return 0;
@@ -2648,15 +2658,22 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
old->last_fenced_seqno);
}
+ obj->last_fenced_seqno = old->last_fenced_seqno;
drm_gem_object_unreference(&old->base);
- } else if (obj->last_fenced_seqno == 0)
- pipelined = NULL;
+ }
reg->obj = obj;
list_move_tail(®->lru_list, &dev_priv->mm.fence_list);
obj->fence_reg = reg - dev_priv->fence_regs;
update:
+ /* If we had a pipelined request, but there is no pending GPU access or
+ * update to a fence register for this memory region, we can write
+ * the new fence register immediately.
+ */
+ if (obj->last_fenced_seqno == 0)
+ pipelined = NULL;
+
reg->setup_seqno =
pipelined ? i915_gem_next_request_seqno(pipelined) : 0;
reg->setup_ring = pipelined;
--
1.7.4.1
More information about the Intel-gfx
mailing list