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

Daniel Vetter daniel.vetter at ffwll.ch
Thu Feb 4 22:05:09 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 31 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.

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

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b4e2f95..f26a037 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;
 };
 
@@ -617,13 +618,38 @@ 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;
+
+	/**
+	 * Used to decide whether to update fence lru and seqno when flushing
+	 * gpu writes.
+	 * */
+	int fenced_gpu_access : 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;
@@ -643,13 +669,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;
 
@@ -680,17 +699,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 72a5308..9af6e9c 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1520,6 +1520,12 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj)
 		obj_priv->active = 1;
 	}
 
+	if (obj_priv->fenced_gpu_access) {
+		struct drm_i915_fence_reg *reg =
+			&dev_priv->fence_regs[obj_priv->fence_reg];
+		reg->last_rendering_seqno = obj_priv->last_rendering_seqno;
+	}
+
 	/* Move from whatever list we were on to the tail of execution. */
 	spin_lock(&dev_priv->mm.active_list_lock);
 	list_move_tail(&obj_priv->list,
@@ -1566,6 +1572,8 @@ i915_gem_object_move_to_inactive(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;
+	struct drm_i915_fence_reg *reg =
+		&dev_priv->fence_regs[obj_priv->fence_reg];
 
 	i915_verify_inactive(dev, __FILE__, __LINE__);
 	if (obj_priv->pin_count != 0)
@@ -1576,6 +1584,8 @@ 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;
+	obj_priv->fenced_gpu_access = 0;
+	reg->last_rendering_seqno = 0;
 	if (obj_priv->active) {
 		obj_priv->active = 0;
 		drm_gem_object_unreference(obj);
@@ -3320,7 +3330,9 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
 			i915_gem_object_unpin(obj);
 			return ret;
 		}
-	}
+		obj_priv->fenced_gpu_access = 1;
+	} else
+		obj_priv->fenced_gpu_access = 0;
 
 	entry->offset = obj_priv->gtt_offset;
 
@@ -3722,7 +3734,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	struct drm_i915_gem_object *obj_priv;
 	struct drm_clip_rect *cliprects = NULL;
 	struct drm_i915_gem_relocation_entry *relocs;
-	int ret = 0, ret2, i, pinned = 0;
+	int ret = 0, ret2, i, pinned = 0, fixup_pinned = 1;
 	uint64_t exec_offset;
 	uint32_t seqno, reloc_index;
 	int pin_tries, flips;
@@ -3987,7 +3999,20 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 
 	i915_verify_inactive(dev, __FILE__, __LINE__);
 
+	fixup_pinned = 0;
 err:
+	if (fixup_pinned) {
+		for (i = 0; i < pinned; i++) {
+			obj_priv = object_list[i]->driver_private;
+			/* we have clobbered obj_priv->fenced_gpu_access
+			 * set it to a save value */
+			if (obj_priv->active)
+				obj_priv->fenced_gpu_access = 1;
+			else
+				obj_priv->fenced_gpu_access = 0;
+		}
+	}
+
 	for (i = 0; i < pinned; i++)
 		i915_gem_object_unpin(object_list[i]);
 
-- 
1.6.6.1




More information about the Intel-gfx mailing list