[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