aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 2b5c7ad9e64a..b0ff5c44e61e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1595,18 +1595,32 @@ try_again:
1595 1595
1596 /* None available, try to steal one or wait for a user to finish */ 1596 /* None available, try to steal one or wait for a user to finish */
1597 if (i == dev_priv->num_fence_regs) { 1597 if (i == dev_priv->num_fence_regs) {
1598 uint32_t seqno = dev_priv->mm.next_gem_seqno;
1598 loff_t offset; 1599 loff_t offset;
1599 1600
1600 if (avail == 0) 1601 if (avail == 0)
1601 return -ENOMEM; 1602 return -ENOMEM;
1602 1603
1603 /* Could try to use LRU here instead... */
1604 for (i = dev_priv->fence_reg_start; 1604 for (i = dev_priv->fence_reg_start;
1605 i < dev_priv->num_fence_regs; i++) { 1605 i < dev_priv->num_fence_regs; i++) {
1606 uint32_t this_seqno;
1607
1606 reg = &dev_priv->fence_regs[i]; 1608 reg = &dev_priv->fence_regs[i];
1607 old_obj_priv = reg->obj->driver_private; 1609 old_obj_priv = reg->obj->driver_private;
1608 if (!old_obj_priv->pin_count) 1610
1611 if (old_obj_priv->pin_count)
1612 continue;
1613
1614 /* i915 uses fences for GPU access to tiled buffers */
1615 if (IS_I965G(dev) || !old_obj_priv->active)
1609 break; 1616 break;
1617
1618 /* find the seqno of the first available fence */
1619 this_seqno = old_obj_priv->last_rendering_seqno;
1620 if (this_seqno != 0 &&
1621 reg->obj->write_domain == 0 &&
1622 i915_seqno_passed(seqno, this_seqno))
1623 seqno = this_seqno;
1610 } 1624 }
1611 1625
1612 /* 1626 /*
@@ -1614,15 +1628,25 @@ try_again:
1614 * objects to finish before trying again. 1628 * objects to finish before trying again.
1615 */ 1629 */
1616 if (i == dev_priv->num_fence_regs) { 1630 if (i == dev_priv->num_fence_regs) {
1617 ret = i915_gem_object_set_to_gtt_domain(reg->obj, 0); 1631 if (seqno == dev_priv->mm.next_gem_seqno) {
1618 if (ret) { 1632 i915_gem_flush(dev,
1619 WARN(ret != -ERESTARTSYS, 1633 I915_GEM_GPU_DOMAINS,
1620 "switch to GTT domain failed: %d\n", ret); 1634 I915_GEM_GPU_DOMAINS);
1621 return ret; 1635 seqno = i915_add_request(dev,
1636 I915_GEM_GPU_DOMAINS);
1637 if (seqno == 0)
1638 return -ENOMEM;
1622 } 1639 }
1640
1641 ret = i915_wait_request(dev, seqno);
1642 if (ret)
1643 return ret;
1623 goto try_again; 1644 goto try_again;
1624 } 1645 }
1625 1646
1647 BUG_ON(old_obj_priv->active ||
1648 (reg->obj->write_domain & I915_GEM_GPU_DOMAINS));
1649
1626 /* 1650 /*
1627 * Zap this virtual mapping so we can set up a fence again 1651 * Zap this virtual mapping so we can set up a fence again
1628 * for this object next time we need it. 1652 * for this object next time we need it.