@@ -129,6 +129,7 @@ struct drm_i915_master_private {
struct drm_i915_fence_reg {
struct drm_gem_object *obj;
uint32_t last_rendering_seqno;
+ uint32_t setup_seqno;
struct list_head lru_list;
};
@@ -1795,6 +1795,7 @@ i915_gem_retire_requests(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
uint32_t seqno;
+ int i;
if (!dev_priv->hw_status_page || list_empty(&dev_priv->mm.request_list))
return;
@@ -1826,6 +1827,13 @@ i915_gem_retire_requests(struct drm_device *dev)
i915_user_irq_put(dev);
dev_priv->trace_irq_seqno = 0;
}
+
+ /* Update pipelined fences that have been setup by the gpu. */
+ for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) {
+ struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i];
+ if (i915_seqno_passed(seqno, reg->setup_seqno))
+ reg->setup_seqno = 0;
+ }
}
void
@@ -2506,6 +2514,16 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj, int pipelined)
if (obj_priv->fence_reg != I915_FENCE_REG_NONE) {
reg = &dev_priv->fence_regs[obj_priv->fence_reg];
list_move_tail(®->lru_list, &dev_priv->mm.fence_list);
+
+ /* Wait for the gpu to setup the fence it it was pipelined. */
+ if (!pipelined && reg->setup_seqno != 0) {
+ ret = i915_wait_request(dev, reg->setup_seqno);
+ if (ret != 0)
+ return ret;
+
+ reg->setup_seqno = 0;
+ }
+
return 0;
}
@@ -2539,6 +2557,11 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj, int pipelined)
reg->obj = obj;
+ if (pipelined)
+ reg->setup_seqno = dev_priv->mm.next_gem_seqno;
+ else
+ reg->setup_seqno = 0;
+
if (pipelined && reg->last_rendering_seqno != 0) {
ret = i915_wait_request(dev, reg->last_rendering_seqno);
if (ret != 0)