diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-11-01 09:39:24 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-11-01 09:39:24 -0400 |
commit | c6afd658073f9fdb4cc80664dac71fa9db6fdf35 (patch) | |
tree | 80dad4b719a2900195491669da178ababcb80c40 /drivers/gpu/drm | |
parent | 30c56660fc4ba9bad7847ad43bb059d2447001d4 (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.c | 80 |
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 | ||
3499 | static int | ||
3500 | i915_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]; |