aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-11-01 08:22:48 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-11-01 08:31:19 -0400
commit13b2928933919c5344716d49620a52493a243f8c (patch)
tree902d90ee3a9a7fbb92e082107cfbdf230f4fb098
parente5c652603680404683fd1f262b511340545179a2 (diff)
drm/i915: Apply big hammer to serialise buffer access between rings
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c75
1 files changed, 52 insertions, 23 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index c8e516d3f8bc..c797d2b9b233 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3189,7 +3189,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
3189 * write domain 3189 * write domain
3190 */ 3190 */
3191 if (obj->write_domain && 3191 if (obj->write_domain &&
3192 obj->write_domain != obj->pending_read_domains) { 3192 (obj->write_domain != obj->pending_read_domains ||
3193 obj_priv->ring != ring)) {
3193 flush_domains |= obj->write_domain; 3194 flush_domains |= obj->write_domain;
3194 invalidate_domains |= 3195 invalidate_domains |=
3195 obj->pending_read_domains & ~obj->write_domain; 3196 obj->pending_read_domains & ~obj->write_domain;
@@ -3582,6 +3583,52 @@ i915_gem_execbuffer_pin(struct drm_device *dev,
3582 } while (1); 3583 } while (1);
3583} 3584}
3584 3585
3586static int
3587i915_gem_execbuffer_move_to_gpu(struct drm_device *dev,
3588 struct drm_file *file,
3589 struct intel_ring_buffer *ring,
3590 struct drm_gem_object **objects,
3591 int count)
3592{
3593 struct drm_i915_private *dev_priv = dev->dev_private;
3594 int ret, i;
3595
3596 /* Zero the global flush/invalidate flags. These
3597 * will be modified as new domains are computed
3598 * for each object
3599 */
3600 dev->invalidate_domains = 0;
3601 dev->flush_domains = 0;
3602 dev_priv->mm.flush_rings = 0;
3603 for (i = 0; i < count; i++)
3604 i915_gem_object_set_to_gpu_domain(objects[i], ring);
3605
3606 if (dev->invalidate_domains | dev->flush_domains) {
3607#if WATCH_EXEC
3608 DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
3609 __func__,
3610 dev->invalidate_domains,
3611 dev->flush_domains);
3612#endif
3613 i915_gem_flush(dev, file,
3614 dev->invalidate_domains,
3615 dev->flush_domains,
3616 dev_priv->mm.flush_rings);
3617 }
3618
3619 for (i = 0; i < count; i++) {
3620 struct drm_i915_gem_object *obj = to_intel_bo(objects[i]);
3621 /* XXX replace with semaphores */
3622 if (obj->ring && ring != obj->ring) {
3623 ret = i915_gem_object_wait_rendering(&obj->base, true);
3624 if (ret)
3625 return ret;
3626 }
3627 }
3628
3629 return 0;
3630}
3631
3585/* Throttle our rendering by waiting until the ring has completed our requests 3632/* Throttle our rendering by waiting until the ring has completed our requests
3586 * emitted over 20 msec ago. 3633 * emitted over 20 msec ago.
3587 * 3634 *
@@ -3843,28 +3890,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
3843 goto err; 3890 goto err;
3844 } 3891 }
3845 3892
3846 /* Zero the global flush/invalidate flags. These 3893 ret = i915_gem_execbuffer_move_to_gpu(dev, file, ring,
3847 * will be modified as new domains are computed 3894 object_list, args->buffer_count);
3848 * for each object 3895 if (ret)
3849 */ 3896 goto err;
3850 dev->invalidate_domains = 0;
3851 dev->flush_domains = 0;
3852 dev_priv->mm.flush_rings = 0;
3853 for (i = 0; i < args->buffer_count; i++)
3854 i915_gem_object_set_to_gpu_domain(object_list[i], ring);
3855
3856 if (dev->invalidate_domains | dev->flush_domains) {
3857#if WATCH_EXEC
3858 DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
3859 __func__,
3860 dev->invalidate_domains,
3861 dev->flush_domains);
3862#endif
3863 i915_gem_flush(dev, file,
3864 dev->invalidate_domains,
3865 dev->flush_domains,
3866 dev_priv->mm.flush_rings);
3867 }
3868 3897
3869#if WATCH_COHERENCY 3898#if WATCH_COHERENCY
3870 for (i = 0; i < args->buffer_count; i++) { 3899 for (i = 0; i < args->buffer_count; i++) {