aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-03-17 11:23:22 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2011-03-23 05:12:24 -0400
commit29c5a587284195278e233eec5c2234c24fb2c204 (patch)
tree3f9f5774baea370effce277e42a312285a0b2327 /drivers/gpu/drm/i915/i915_gem.c
parent7ccb4a53eb03c9196646ca0c2a97558313e886f1 (diff)
drm/i915: Fix tiling corruption from pipelined fencing
... even though it was disabled. A mistake in the handling of fence reuse caused us to skip the vital delay of waiting for the object to finish rendering before changing the register. This resulted in us changing the fence register whilst the bo was active and so causing the blits to complete using the wrong stride or even the wrong tiling. (Visually the effect is that small blocks of the screen look like they have been interlaced). The fix is to wait for the GPU to finish using the memory region pointed to by the fence before changing it. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=34584 Cc: Andy Whitcroft <apw@canonical.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> [Note for 2.6.38-stable, we need to reintroduce the interruptible passing] Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Tested-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c44
1 files changed, 17 insertions, 27 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d4bf061dbaf1..c5dfb59e13d3 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2581,8 +2581,23 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
2581 reg = &dev_priv->fence_regs[obj->fence_reg]; 2581 reg = &dev_priv->fence_regs[obj->fence_reg];
2582 list_move_tail(&reg->lru_list, &dev_priv->mm.fence_list); 2582 list_move_tail(&reg->lru_list, &dev_priv->mm.fence_list);
2583 2583
2584 if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) 2584 if (obj->tiling_changed) {
2585 pipelined = NULL; 2585 ret = i915_gem_object_flush_fence(obj, pipelined);
2586 if (ret)
2587 return ret;
2588
2589 if (!obj->fenced_gpu_access && !obj->last_fenced_seqno)
2590 pipelined = NULL;
2591
2592 if (pipelined) {
2593 reg->setup_seqno =
2594 i915_gem_next_request_seqno(pipelined);
2595 obj->last_fenced_seqno = reg->setup_seqno;
2596 obj->last_fenced_ring = pipelined;
2597 }
2598
2599 goto update;
2600 }
2586 2601
2587 if (!pipelined) { 2602 if (!pipelined) {
2588 if (reg->setup_seqno) { 2603 if (reg->setup_seqno) {
@@ -2601,31 +2616,6 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
2601 ret = i915_gem_object_flush_fence(obj, pipelined); 2616 ret = i915_gem_object_flush_fence(obj, pipelined);
2602 if (ret) 2617 if (ret)
2603 return ret; 2618 return ret;
2604 } else if (obj->tiling_changed) {
2605 if (obj->fenced_gpu_access) {
2606 if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) {
2607 ret = i915_gem_flush_ring(obj->ring,
2608 0, obj->base.write_domain);
2609 if (ret)
2610 return ret;
2611 }
2612
2613 obj->fenced_gpu_access = false;
2614 }
2615 }
2616
2617 if (!obj->fenced_gpu_access && !obj->last_fenced_seqno)
2618 pipelined = NULL;
2619 BUG_ON(!pipelined && reg->setup_seqno);
2620
2621 if (obj->tiling_changed) {
2622 if (pipelined) {
2623 reg->setup_seqno =
2624 i915_gem_next_request_seqno(pipelined);
2625 obj->last_fenced_seqno = reg->setup_seqno;
2626 obj->last_fenced_ring = pipelined;
2627 }
2628 goto update;
2629 } 2619 }
2630 2620
2631 return 0; 2621 return 0;