aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-02-11 09:26:47 -0500
committerEric Anholt <eric@anholt.net>2009-03-11 13:33:28 -0400
commitd7619c4b9c95cc9a2e7f0f4f7ae21165ab5cb1e7 (patch)
treebb8ae65f7b4bdfcb6464cf20a57251a063e63c49 /drivers
parentfc7170ba281c041852eeda52d4faf5db720c99ce (diff)
drm/i915: Protect active fences on i915
The i915 also uses the fence registers for GPU access to tiled buffers so we cannot reallocate one whilst it is on the active list. By performing a LRU scan of the fenced buffers we also avoid waiting the possibility of waiting on a pinned, or otherwise unusable, buffer. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers')
-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.