aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-11-01 09:39:24 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-11-01 09:39:24 -0400
commitc6afd658073f9fdb4cc80664dac71fa9db6fdf35 (patch)
tree80dad4b719a2900195491669da178ababcb80c40 /drivers/gpu/drm
parent30c56660fc4ba9bad7847ad43bb059d2447001d4 (diff)
drm/i915: Apply big hammer to serialise buffer access between rings
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: stable@kernel.org
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c80
1 files changed, 52 insertions, 28 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 469a5b1a48aa..984eb6e9db03 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3106,7 +3106,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
3106 * write domain 3106 * write domain
3107 */ 3107 */
3108 if (obj->write_domain && 3108 if (obj->write_domain &&
3109 obj->write_domain != obj->pending_read_domains) { 3109 (obj->write_domain != obj->pending_read_domains ||
3110 obj_priv->ring != ring)) {
3110 flush_domains |= obj->write_domain; 3111 flush_domains |= obj->write_domain;
3111 invalidate_domains |= 3112 invalidate_domains |=
3112 obj->pending_read_domains & ~obj->write_domain; 3113 obj->pending_read_domains & ~obj->write_domain;
@@ -3495,6 +3496,52 @@ i915_gem_execbuffer_pin(struct drm_device *dev,
3495 return 0; 3496 return 0;
3496} 3497}
3497 3498
3499static int
3500i915_gem_execbuffer_move_to_gpu(struct drm_device *dev,
3501 struct drm_file *file,
3502 struct intel_ring_buffer *ring,
3503 struct drm_gem_object **objects,
3504 int count)
3505{
3506 struct drm_i915_private *dev_priv = dev->dev_private;
3507 int ret, i;
3508
3509 /* Zero the global flush/invalidate flags. These
3510 * will be modified as new domains are computed
3511 * for each object
3512 */
3513 dev->invalidate_domains = 0;
3514 dev->flush_domains = 0;
3515 dev_priv->mm.flush_rings = 0;
3516 for (i = 0; i < count; i++)
3517 i915_gem_object_set_to_gpu_domain(objects[i], ring);
3518
3519 if (dev->invalidate_domains | dev->flush_domains) {
3520#if WATCH_EXEC
3521 DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
3522 __func__,
3523 dev->invalidate_domains,
3524 dev->flush_domains);
3525#endif
3526 i915_gem_flush(dev, file,
3527 dev->invalidate_domains,
3528 dev->flush_domains,
3529 dev_priv->mm.flush_rings);
3530 }
3531
3532 for (i = 0; i < count; i++) {
3533 struct drm_i915_gem_object *obj = to_intel_bo(objects[i]);
3534 /* XXX replace with semaphores */
3535 if (obj->ring && ring != obj->ring) {
3536 ret = i915_gem_object_wait_rendering(&obj->base, true);
3537 if (ret)
3538 return ret;
3539 }
3540 }
3541
3542 return 0;
3543}
3544
3498/* Throttle our rendering by waiting until the ring has completed our requests 3545/* Throttle our rendering by waiting until the ring has completed our requests
3499 * emitted over 20 msec ago. 3546 * emitted over 20 msec ago.
3500 * 3547 *
@@ -3755,33 +3802,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
3755 goto err; 3802 goto err;
3756 } 3803 }
3757 3804
3758 /* Zero the global flush/invalidate flags. These 3805 ret = i915_gem_execbuffer_move_to_gpu(dev, file, ring,
3759 * will be modified as new domains are computed 3806 object_list, args->buffer_count);
3760 * for each object 3807 if (ret)
3761 */ 3808 goto err;
3762 dev->invalidate_domains = 0;
3763 dev->flush_domains = 0;
3764 dev_priv->mm.flush_rings = 0;
3765
3766 for (i = 0; i < args->buffer_count; i++) {
3767 struct drm_gem_object *obj = object_list[i];
3768
3769 /* Compute new gpu domains and update invalidate/flush */
3770 i915_gem_object_set_to_gpu_domain(obj, ring);
3771 }
3772
3773 if (dev->invalidate_domains | dev->flush_domains) {
3774#if WATCH_EXEC
3775 DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
3776 __func__,
3777 dev->invalidate_domains,
3778 dev->flush_domains);
3779#endif
3780 i915_gem_flush(dev, file,
3781 dev->invalidate_domains,
3782 dev->flush_domains,
3783 dev_priv->mm.flush_rings);
3784 }
3785 3809
3786 for (i = 0; i < args->buffer_count; i++) { 3810 for (i = 0; i < args->buffer_count; i++) {
3787 struct drm_gem_object *obj = object_list[i]; 3811 struct drm_gem_object *obj = object_list[i];