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. |
