summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem_execbuffer.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-11-10 16:40:20 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2010-12-02 10:07:05 +0000
commitd9e86c0ee60f323e890484628f351bf50fa9a15d (patch)
tree4755a8ec484340bc12e2d1f88f35fbd266df6001 /drivers/gpu/drm/i915/i915_gem_execbuffer.c
parent87ca9c8a7ea9c8c7ce1561edaad1aa8570f1a01e (diff)
downloadop-kernel-dev-d9e86c0ee60f323e890484628f351bf50fa9a15d.zip
op-kernel-dev-d9e86c0ee60f323e890484628f351bf50fa9a15d.tar.gz
drm/i915: Pipelined fencing [infrastructure]
With this change, every batchbuffer can use all available fences (save pinned and scanout, of course) without ever stalling the gpu! In theory. Currently the actual pipelined update of the register is disabled due to some stability issues. However, just the deferred update is a significant win. Based on a series of patches by Daniel Vetter. The premise is that before every access to a buffer through the GTT we have to declare whether we need a register or not. If the access is by the GPU, a pipelined update to the register is made via the ringbuffer, and we track the last seqno of the batches that access it. If by the CPU we wait for the last GPU access and update the register (either to clear or to set it for the current buffer). One advantage of being able to pipeline changes is that we can defer the actual updating of the fence register until we first need to access the object through the GTT, i.e. we can eliminate the stall on set_tiling. This is important as the userspace bo cache does not track the tiling status of active buffers which generate frequent stalls on gen3 when enabling tiling for an already bound buffer. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_execbuffer.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index af01a58..9bdc495 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -424,7 +424,7 @@ i915_gem_execbuffer_relocate(struct drm_device *dev,
}
static int
-i915_gem_execbuffer_reserve(struct drm_device *dev,
+i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
struct drm_file *file,
struct list_head *objects,
struct drm_i915_gem_exec_object2 *exec)
@@ -499,10 +499,15 @@ i915_gem_execbuffer_reserve(struct drm_device *dev,
}
if (need_fence) {
- ret = i915_gem_object_get_fence_reg(obj, true);
+ ret = i915_gem_object_get_fence(obj, ring, 1);
+ if (ret)
+ break;
+ } else if (entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
+ obj->tiling_mode == I915_TILING_NONE) {
+ /* XXX pipelined! */
+ ret = i915_gem_object_put_fence(obj);
if (ret)
break;
-
}
obj->pending_fenced_gpu_access = need_fence;
@@ -522,7 +527,7 @@ i915_gem_execbuffer_reserve(struct drm_device *dev,
/* First attempt, just clear anything that is purgeable.
* Second attempt, clear the entire GTT.
*/
- ret = i915_gem_evict_everything(dev, retry == 0);
+ ret = i915_gem_evict_everything(ring->dev, retry == 0);
if (ret)
return ret;
@@ -548,6 +553,7 @@ err:
static int
i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
struct drm_file *file,
+ struct intel_ring_buffer *ring,
struct list_head *objects,
struct drm_i915_gem_exec_object2 *exec,
int count)
@@ -590,7 +596,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
goto err;
}
- ret = i915_gem_execbuffer_reserve(dev, file, objects, exec);
+ ret = i915_gem_execbuffer_reserve(ring, file, objects, exec);
if (ret)
goto err;
@@ -930,7 +936,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
}
/* Move the objects en-masse into the GTT, evicting if necessary. */
- ret = i915_gem_execbuffer_reserve(dev, file, &objects, exec);
+ ret = i915_gem_execbuffer_reserve(ring, file, &objects, exec);
if (ret)
goto err;
@@ -938,7 +944,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
ret = i915_gem_execbuffer_relocate(dev, file, &objects, exec);
if (ret) {
if (ret == -EFAULT) {
- ret = i915_gem_execbuffer_relocate_slow(dev, file,
+ ret = i915_gem_execbuffer_relocate_slow(dev, file, ring,
&objects, exec,
args->buffer_count);
BUG_ON(!mutex_is_locked(&dev->struct_mutex));
OpenPOWER on IntegriCloud