[Intel-gfx] [PATCH 10/15] drm/i915: track gpu fence usage more precisely

Daniel Vetter daniel.vetter at ffwll.ch
Thu Mar 11 16:58:55 CET 2010


With execbuf2, not every buffer on the active list that has a
fence reg allocated necessarily needs it. Track this usage more
precisely.

Instead of wasting another 30 bits in struct drm_i915_gem_object,
I've decided to put all flags and small integer fields together
and convert them into C bitfields.

v2: Fixes and small cleanups for the fence state tracking.
v3: Add current_execbuffer_needs_fencing to correctly recover
from errors in i915_gem_do_execbuffer. Also clarify the usage
of fenced_gpu_access.

Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
---
 drivers/gpu/drm/i915/i915_drv.h |   55 ++++++++++++++++++++++++--------------
 drivers/gpu/drm/i915/i915_gem.c |   38 ++++++++++++++++++++++++--
 2 files changed, 70 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index db44e61..c32b60c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -128,6 +128,7 @@ struct drm_i915_master_private {
 
 struct drm_i915_fence_reg {
 	struct drm_gem_object *obj;
+	uint32_t last_rendering_seqno;
 	struct list_head lru_list;
 };
 
@@ -652,13 +653,45 @@ struct drm_i915_gem_object {
 	 * (has pending rendering), and is not set if it's on inactive (ready
 	 * to be unbound).
 	 */
-	int active;
+	int active : 1;
 
 	/**
 	 * This is set if the object has been written to since last bound
 	 * to the GTT
 	 */
-	int dirty;
+	int dirty : 1;
+
+	/**
+	 * Used for checking the object doesn't appear more than once
+	 * in an execbuffer object list.
+	 */
+	int in_execbuffer : 1;
+
+	/**
+	 * This is set when the most recent request using this object needs a
+	 * fence. Used to decide whether to update fence lru and seqno when
+	 * flushing gpu writes.
+	 */
+	int fenced_gpu_access : 1;
+
+	/**
+	 * Used in do_execbuffer to update fenced_gpu_access when the execbuffer
+	 * can be executed.
+	 */
+	int current_execbuffer_needs_fencing : 1;
+
+	/**
+	 * Fence register bits (if any) for this object.  Will be set
+	 * as needed when mapped into the GTT.
+	 * Protected by dev->struct_mutex.
+	 * Size: 16 fences + sign (for FENCE_REG_NONE): 5 bits
+	 */
+	int fence_reg : 5;
+
+	/**
+	 * Advice: are the backing pages purgeable?
+	 */
+	int madv : 3;
 
 	/** AGP memory structure for our GTT binding. */
 	DRM_AGP_MEM *agp_mem;
@@ -678,13 +711,6 @@ struct drm_i915_gem_object {
 	 */
 	uint64_t mmap_offset;
 
-	/**
-	 * Fence register bits (if any) for this object.  Will be set
-	 * as needed when mapped into the GTT.
-	 * Protected by dev->struct_mutex.
-	 */
-	int fence_reg;
-
 	/** How many users have pinned this object in GTT space */
 	int pin_count;
 
@@ -715,17 +741,6 @@ struct drm_i915_gem_object {
 	struct drm_i915_gem_phys_object *phys_obj;
 
 	/**
-	 * Used for checking the object doesn't appear more than once
-	 * in an execbuffer object list.
-	 */
-	int in_execbuffer;
-
-	/**
-	 * Advice: are the backing pages purgeable?
-	 */
-	int madv;
-
-	/**
 	 * Number of crtcs where this object is currently the fb, but
 	 * will be page flipped away on the next vblank.  When it
 	 * reaches 0, dev_priv->pending_flip_queue will be woken up.
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 4eeed4e..5183fdd 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1515,10 +1515,31 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj)
 	list_move_tail(&obj_priv->list,
 		       &dev_priv->mm.active_list);
 	spin_unlock(&dev_priv->mm.active_list_lock);
+
+	if (obj_priv->fenced_gpu_access) {
+		struct drm_i915_fence_reg *reg =
+			&dev_priv->fence_regs[obj_priv->fence_reg];
+		reg->last_rendering_seqno = seqno;
+	}
 	obj_priv->last_rendering_seqno = seqno;
 }
 
 static void
+i915_gem_object_move_off_active(struct drm_gem_object *obj)
+{
+	struct drm_device *dev = obj->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+
+	obj_priv->last_rendering_seqno = 0;
+	if (obj_priv->fenced_gpu_access) {
+		struct drm_i915_fence_reg *reg =
+			&dev_priv->fence_regs[obj_priv->fence_reg];
+		reg->last_rendering_seqno = 0;
+	}
+}
+
+static void
 i915_gem_object_move_to_flushing(struct drm_gem_object *obj)
 {
 	struct drm_device *dev = obj->dev;
@@ -1527,7 +1548,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj)
 
 	BUG_ON(!obj_priv->active);
 	list_move_tail(&obj_priv->list, &dev_priv->mm.flushing_list);
-	obj_priv->last_rendering_seqno = 0;
+	i915_gem_object_move_off_active(obj);
 }
 
 /* Immediately discard the backing storage */
@@ -1565,7 +1586,9 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
 
 	BUG_ON(!list_empty(&obj_priv->gpu_write_list));
 
-	obj_priv->last_rendering_seqno = 0;
+	i915_gem_object_move_off_active(obj);
+	obj_priv->fenced_gpu_access = 0;
+
 	if (obj_priv->active) {
 		obj_priv->active = 0;
 		drm_gem_object_unreference(obj);
@@ -3325,7 +3348,9 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
 			i915_gem_object_unpin(obj);
 			return ret;
 		}
-	}
+		obj_priv->current_execbuffer_needs_fencing = 1;
+	} else
+		obj_priv->current_execbuffer_needs_fencing = 0;
 
 	entry->offset = obj_priv->gtt_offset;
 
@@ -3990,6 +4015,12 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	 */
 	for (i = 0; i < args->buffer_count; i++) {
 		struct drm_gem_object *obj = object_list[i];
+		struct drm_i915_gem_object *obj_priv = obj->driver_private;
+
+		if (obj_priv->current_execbuffer_needs_fencing)
+			obj_priv->fenced_gpu_access = 1;
+		else
+			obj_priv->fenced_gpu_access = 0;
 
 		i915_gem_object_move_to_active(obj);
 #if WATCH_LRU
@@ -4011,6 +4042,7 @@ err:
 		if (object_list[i]) {
 			obj_priv = object_list[i]->driver_private;
 			obj_priv->in_execbuffer = false;
+			obj_priv->current_execbuffer_needs_fencing = 0;
 		}
 		drm_gem_object_unreference(object_list[i]);
 	}
-- 
1.6.6.1




More information about the Intel-gfx mailing list