@@ -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.
@@ -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]);