aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-04-17 10:31:33 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-04-18 07:40:51 -0400
commit14415745b2518fc7309616a33ce8e656e79a4e05 (patch)
tree61d9026f557823e6db7a3b1b70ea935516c2317c /drivers/gpu
parentada726c734e79c83f72676c02b5d68d4f9faead0 (diff)
drm/i915: Refactor get_fence() to use the common fence writing routine
We can also take advantage of the new 'no retire' mode for seqno waiting to avoid having to take a reference on the old fence object whilst flushing an existing fence. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c70
1 files changed, 27 insertions, 43 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e09ac3a95308..7bc4a40132ad 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2361,7 +2361,7 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj)
2361 if (obj->last_fenced_seqno) { 2361 if (obj->last_fenced_seqno) {
2362 ret = i915_wait_request(obj->ring, 2362 ret = i915_wait_request(obj->ring,
2363 obj->last_fenced_seqno, 2363 obj->last_fenced_seqno,
2364 true); 2364 false);
2365 if (ret) 2365 if (ret)
2366 return ret; 2366 return ret;
2367 2367
@@ -2449,63 +2449,47 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
2449{ 2449{
2450 struct drm_device *dev = obj->base.dev; 2450 struct drm_device *dev = obj->base.dev;
2451 struct drm_i915_private *dev_priv = dev->dev_private; 2451 struct drm_i915_private *dev_priv = dev->dev_private;
2452 bool enable = obj->tiling_mode != I915_TILING_NONE;
2452 struct drm_i915_fence_reg *reg; 2453 struct drm_i915_fence_reg *reg;
2453 int ret; 2454 int ret;
2454 2455
2455 if (obj->tiling_mode == I915_TILING_NONE) 2456 /* Have we updated the tiling parameters upon the object and so
2456 return i915_gem_object_put_fence(obj); 2457 * will need to serialise the write to the associated fence register?
2458 */
2459 if (obj->tiling_changed) {
2460 ret = i915_gem_object_flush_fence(obj);
2461 if (ret)
2462 return ret;
2463 }
2457 2464
2458 /* Just update our place in the LRU if our fence is getting reused. */ 2465 /* Just update our place in the LRU if our fence is getting reused. */
2459 if (obj->fence_reg != I915_FENCE_REG_NONE) { 2466 if (obj->fence_reg != I915_FENCE_REG_NONE) {
2460 reg = &dev_priv->fence_regs[obj->fence_reg]; 2467 reg = &dev_priv->fence_regs[obj->fence_reg];
2461 list_move_tail(&reg->lru_list, &dev_priv->mm.fence_list); 2468 if (!obj->tiling_changed) {
2469 list_move_tail(&reg->lru_list,
2470 &dev_priv->mm.fence_list);
2471 return 0;
2472 }
2473 } else if (enable) {
2474 reg = i915_find_fence_reg(dev);
2475 if (reg == NULL)
2476 return -EDEADLK;
2477
2478 if (reg->obj) {
2479 struct drm_i915_gem_object *old = reg->obj;
2462 2480
2463 if (obj->tiling_changed) { 2481 ret = i915_gem_object_flush_fence(old);
2464 ret = i915_gem_object_flush_fence(obj);
2465 if (ret) 2482 if (ret)
2466 return ret; 2483 return ret;
2467 2484
2468 goto update; 2485 i915_gem_object_fence_lost(old);
2469 } 2486 }
2470 2487 } else
2471 return 0; 2488 return 0;
2472 }
2473
2474 reg = i915_find_fence_reg(dev);
2475 if (reg == NULL)
2476 return -EDEADLK;
2477
2478 ret = i915_gem_object_flush_fence(obj);
2479 if (ret)
2480 return ret;
2481
2482 if (reg->obj) {
2483 struct drm_i915_gem_object *old = reg->obj;
2484 2489
2485 drm_gem_object_reference(&old->base); 2490 i915_gem_object_update_fence(obj, reg, enable);
2486
2487 if (old->tiling_mode)
2488 i915_gem_release_mmap(old);
2489
2490 ret = i915_gem_object_flush_fence(old);
2491 if (ret) {
2492 drm_gem_object_unreference(&old->base);
2493 return ret;
2494 }
2495
2496 old->fence_reg = I915_FENCE_REG_NONE;
2497 old->last_fenced_seqno = 0;
2498
2499 drm_gem_object_unreference(&old->base);
2500 }
2501
2502 reg->obj = obj;
2503 list_move_tail(&reg->lru_list, &dev_priv->mm.fence_list);
2504 obj->fence_reg = reg - dev_priv->fence_regs;
2505
2506update:
2507 obj->tiling_changed = false; 2491 obj->tiling_changed = false;
2508 i915_gem_write_fence(dev, reg - dev_priv->fence_regs, obj); 2492
2509 return 0; 2493 return 0;
2510} 2494}
2511 2495