diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 38 |
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. |