diff options
author | Jonathan Gray <jsg@jsg.id.au> | 2013-03-06 11:18:38 +1100 |
---|---|---|
committer | Jonathan Gray <jsg@jsg.id.au> | 2013-03-06 11:18:38 +1100 |
commit | 237542d8c998c9d93ab705bd8145acc8d4173c8a (patch) | |
tree | 556bbec90cc5f7cb076663052d1f822b40ad4381 /sys/dev | |
parent | 160d380656cc1cca12e0a27340f30a429b9c7e2d (diff) |
enable using gpu semaphores for ring sync
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/drm/i915_drv.c | 3 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_drv.h | 1 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_gem.c | 5 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_gem_execbuffer.c | 40 |
4 files changed, 30 insertions, 19 deletions
diff --git a/sys/dev/pci/drm/i915_drv.c b/sys/dev/pci/drm/i915_drv.c index c720b3869a6..c0b13ffce2e 100644 --- a/sys/dev/pci/drm/i915_drv.c +++ b/sys/dev/pci/drm/i915_drv.c @@ -71,6 +71,9 @@ int i915_panel_ignore_lid = 1; /* Enable powersavings, fbc, downclocking, etc. (default: true) */ unsigned int i915_powersave = 1; +/* Use semaphores for inter-ring sync (default: -1 (use per-chip defaults)) */ +int i915_semaphores = -1; + /* * Enable frame buffer compression for power savings * (default: -1 (use per-chip default)) diff --git a/sys/dev/pci/drm/i915_drv.h b/sys/dev/pci/drm/i915_drv.h index 40665eab1a6..60efe11849d 100644 --- a/sys/dev/pci/drm/i915_drv.h +++ b/sys/dev/pci/drm/i915_drv.h @@ -1501,6 +1501,7 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off) extern unsigned int i915_lvds_downclock; extern int i915_panel_ignore_lid; extern unsigned int i915_powersave; +extern int i915_semaphores; extern int i915_enable_rc6; extern int i915_enable_fbc; diff --git a/sys/dev/pci/drm/i915_gem.c b/sys/dev/pci/drm/i915_gem.c index ef0db7eb69f..3f78da803c6 100644 --- a/sys/dev/pci/drm/i915_gem.c +++ b/sys/dev/pci/drm/i915_gem.c @@ -1195,12 +1195,17 @@ void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring) { uint32_t seqno; + int i; if (list_empty(&ring->request_list)) return; seqno = ring->get_seqno(ring, true); + for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++) + if (seqno >= ring->sync_seqno[i]) + ring->sync_seqno[i] = 0; + while (!list_empty(&ring->request_list)) { struct drm_i915_gem_request *request; diff --git a/sys/dev/pci/drm/i915_gem_execbuffer.c b/sys/dev/pci/drm/i915_gem_execbuffer.c index 6cc802de500..823aed23018 100644 --- a/sys/dev/pci/drm/i915_gem_execbuffer.c +++ b/sys/dev/pci/drm/i915_gem_execbuffer.c @@ -297,8 +297,6 @@ i915_gem_execbuffer_flush(struct drm_device *dev, bool intel_enable_semaphores(struct drm_device *dev) { - return 0; -#ifdef notyet if (INTEL_INFO(dev)->gen < 6) return 0; @@ -310,7 +308,6 @@ intel_enable_semaphores(struct drm_device *dev) return 0; return 1; -#endif } int @@ -318,42 +315,31 @@ i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj, struct intel_ring_buffer *to) { struct intel_ring_buffer *from = obj->ring; -// u32 seqno; -// int ret, idx; + u32 seqno; + int ret, idx; if (from == NULL || to == from) return 0; /* XXX gpu semaphores are implicated in various hard hangs on SNB */ -// if (!intel_enable_semaphores(obj->base.dev)) + if (!intel_enable_semaphores(obj->base.dev)) return i915_gem_object_wait_rendering(obj, false); -#ifdef notyet idx = intel_ring_sync_index(from, to); - seqno = obj->last_rendering_seqno; + seqno = obj->last_read_seqno; if (seqno <= from->sync_seqno[idx]) return 0; if (seqno == from->outstanding_lazy_request) { - struct drm_i915_gem_request *request; - - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request == NULL) - return -ENOMEM; - - ret = i915_add_request(from, NULL, request); + ret = i915_add_request(from, NULL, &seqno); if (ret) { - kfree(request); return ret; } - - seqno = request->seqno; } from->sync_seqno[idx] = seqno; return to->sync_to(to, from, seqno - 1); -#endif } int @@ -532,6 +518,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, int ret, ret2, i; int pinned = 0, pin_tries; uint32_t reloc_index; + uint32_t seqno; /* * Check for valid execbuffer offset. We can do this early because @@ -691,6 +678,21 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, if (ret) goto err; + seqno = i915_gem_next_request_seqno(ring); + for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++) { + if (seqno < ring->sync_seqno[i]) { + /* The GPU can not handle its semaphore value wrapping, + * so every billion or so execbuffers, we need to stall + * the GPU in order to reset the counters. + */ + ret = i915_gpu_idle(dev); + if (ret) + goto err; + + BUG_ON(ring->sync_seqno[i]); + } + } + if (args->flags & I915_EXEC_GEN7_SOL_RESET) { ret = i915_reset_gen7_sol_offsets(dev, ring); if (ret) |