Skip to content

Commit

Permalink
drm/i915: Fix tiling corruption from pipelined fencing
Browse files Browse the repository at this point in the history
... 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>
  • Loading branch information
Chris Wilson committed Mar 23, 2011
1 parent 7ccb4a5 commit 29c5a58
Showing 1 changed file with 17 additions and 27 deletions.
44 changes: 17 additions & 27 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -2581,8 +2581,23 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
reg = &dev_priv->fence_regs[obj->fence_reg];
list_move_tail(&reg->lru_list, &dev_priv->mm.fence_list);

if (!obj->fenced_gpu_access && !obj->last_fenced_seqno)
pipelined = NULL;
if (obj->tiling_changed) {
ret = i915_gem_object_flush_fence(obj, pipelined);
if (ret)
return ret;

if (!obj->fenced_gpu_access && !obj->last_fenced_seqno)
pipelined = NULL;

if (pipelined) {
reg->setup_seqno =
i915_gem_next_request_seqno(pipelined);
obj->last_fenced_seqno = reg->setup_seqno;
obj->last_fenced_ring = pipelined;
}

goto update;
}

if (!pipelined) {
if (reg->setup_seqno) {
Expand All @@ -2601,31 +2616,6 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
ret = i915_gem_object_flush_fence(obj, pipelined);
if (ret)
return ret;
} else if (obj->tiling_changed) {
if (obj->fenced_gpu_access) {
if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) {
ret = i915_gem_flush_ring(obj->ring,
0, obj->base.write_domain);
if (ret)
return ret;
}

obj->fenced_gpu_access = false;
}
}

if (!obj->fenced_gpu_access && !obj->last_fenced_seqno)
pipelined = NULL;
BUG_ON(!pipelined && reg->setup_seqno);

if (obj->tiling_changed) {
if (pipelined) {
reg->setup_seqno =
i915_gem_next_request_seqno(pipelined);
obj->last_fenced_seqno = reg->setup_seqno;
obj->last_fenced_ring = pipelined;
}
goto update;
}

return 0;
Expand Down

0 comments on commit 29c5a58

Please sign in to comment.