aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-04-14 04:41:17 -0400
committerKeith Packard <keithp@keithp.com>2011-06-10 00:51:19 -0400
commit2da3b9b940e2a18147422c54ed8b29d01e1ade88 (patch)
treeafffe23550ffcc446e70559c4f75cd1f308cca33
parentc411964209508e32cf36f6512ed339996751f55f (diff)
drm/i915: Combine pinning with setting to the display plane
We need to perform a few operations in order to move the object into the display plane (where it can be accessed coherently by the display engine) that are important for future safety to forbid whilst pinned. As a result, we want to need to perform some of the operations before pinning, but some are required once we have been bound into the GTT. So combine the pinning performed by all the callers with set_to_display_plane(), so this complication is contained within the single function. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h3
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c37
-rw-r--r--drivers/gpu/drm/i915/intel_display.c18
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c6
4 files changed, 33 insertions, 31 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e552aa6bc859..8a9fd9177860 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1209,7 +1209,8 @@ int __must_check
1209i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, 1209i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj,
1210 bool write); 1210 bool write);
1211int __must_check 1211int __must_check
1212i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, 1212i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
1213 u32 alignment,
1213 struct intel_ring_buffer *pipelined); 1214 struct intel_ring_buffer *pipelined);
1214int i915_gem_attach_phys_object(struct drm_device *dev, 1215int i915_gem_attach_phys_object(struct drm_device *dev,
1215 struct drm_i915_gem_object *obj, 1216 struct drm_i915_gem_object *obj,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e6915072ba72..8a439f0c21f5 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3095,40 +3095,55 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
3095} 3095}
3096 3096
3097/* 3097/*
3098 * Prepare buffer for display plane. Use uninterruptible for possible flush 3098 * Prepare buffer for display plane (scanout, cursors, etc).
3099 * wait, as in modesetting process we're not supposed to be interrupted. 3099 * Can be called from an uninterruptible phase (modesetting) and allows
3100 * any flushes to be pipelined (for pageflips).
3101 *
3102 * For the display plane, we want to be in the GTT but out of any write
3103 * domains. So in many ways this looks like set_to_gtt_domain() apart from the
3104 * ability to pipeline the waits, pinning and any additional subtleties
3105 * that may differentiate the display plane from ordinary buffers.
3100 */ 3106 */
3101int 3107int
3102i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, 3108i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
3109 u32 alignment,
3103 struct intel_ring_buffer *pipelined) 3110 struct intel_ring_buffer *pipelined)
3104{ 3111{
3105 uint32_t old_read_domains; 3112 u32 old_read_domains, old_write_domain;
3106 int ret; 3113 int ret;
3107 3114
3108 /* Not valid to be called on unbound objects. */
3109 if (obj->gtt_space == NULL)
3110 return -EINVAL;
3111
3112 ret = i915_gem_object_flush_gpu_write_domain(obj); 3115 ret = i915_gem_object_flush_gpu_write_domain(obj);
3113 if (ret) 3116 if (ret)
3114 return ret; 3117 return ret;
3115 3118
3116
3117 /* Currently, we are always called from an non-interruptible context. */
3118 if (pipelined != obj->ring) { 3119 if (pipelined != obj->ring) {
3119 ret = i915_gem_object_wait_rendering(obj); 3120 ret = i915_gem_object_wait_rendering(obj);
3120 if (ret) 3121 if (ret)
3121 return ret; 3122 return ret;
3122 } 3123 }
3123 3124
3125 /* As the user may map the buffer once pinned in the display plane
3126 * (e.g. libkms for the bootup splash), we have to ensure that we
3127 * always use map_and_fenceable for all scanout buffers.
3128 */
3129 ret = i915_gem_object_pin(obj, alignment, true);
3130 if (ret)
3131 return ret;
3132
3124 i915_gem_object_flush_cpu_write_domain(obj); 3133 i915_gem_object_flush_cpu_write_domain(obj);
3125 3134
3135 old_write_domain = obj->base.write_domain;
3126 old_read_domains = obj->base.read_domains; 3136 old_read_domains = obj->base.read_domains;
3137
3138 /* It should now be out of any other write domains, and we can update
3139 * the domain values for our changes.
3140 */
3141 BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) != 0);
3127 obj->base.read_domains |= I915_GEM_DOMAIN_GTT; 3142 obj->base.read_domains |= I915_GEM_DOMAIN_GTT;
3128 3143
3129 trace_i915_gem_object_change_domain(obj, 3144 trace_i915_gem_object_change_domain(obj,
3130 old_read_domains, 3145 old_read_domains,
3131 obj->base.write_domain); 3146 old_write_domain);
3132 3147
3133 return 0; 3148 return 0;
3134} 3149}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f79863a9a693..86a3ec1469ba 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1812,14 +1812,10 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
1812 } 1812 }
1813 1813
1814 dev_priv->mm.interruptible = false; 1814 dev_priv->mm.interruptible = false;
1815 ret = i915_gem_object_pin(obj, alignment, true); 1815 ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined);
1816 if (ret) 1816 if (ret)
1817 goto err_interruptible; 1817 goto err_interruptible;
1818 1818
1819 ret = i915_gem_object_set_to_display_plane(obj, pipelined);
1820 if (ret)
1821 goto err_unpin;
1822
1823 /* Install a fence for tiled scan-out. Pre-i965 always needs a 1819 /* Install a fence for tiled scan-out. Pre-i965 always needs a
1824 * fence, whereas 965+ only requires a fence if using 1820 * fence, whereas 965+ only requires a fence if using
1825 * framebuffer compression. For simplicity, we always install 1821 * framebuffer compression. For simplicity, we always install
@@ -5434,21 +5430,15 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
5434 goto fail_locked; 5430 goto fail_locked;
5435 } 5431 }
5436 5432
5437 ret = i915_gem_object_pin(obj, PAGE_SIZE, true); 5433 ret = i915_gem_object_pin_to_display_plane(obj, 0, NULL);
5438 if (ret) {
5439 DRM_ERROR("failed to pin cursor bo\n");
5440 goto fail_locked;
5441 }
5442
5443 ret = i915_gem_object_set_to_display_plane(obj, NULL);
5444 if (ret) { 5434 if (ret) {
5445 DRM_ERROR("failed to move cursor bo into the GTT\n"); 5435 DRM_ERROR("failed to move cursor bo into the GTT\n");
5446 goto fail_unpin; 5436 goto fail_locked;
5447 } 5437 }
5448 5438
5449 ret = i915_gem_object_put_fence(obj); 5439 ret = i915_gem_object_put_fence(obj);
5450 if (ret) { 5440 if (ret) {
5451 DRM_ERROR("failed to move cursor bo into the GTT\n"); 5441 DRM_ERROR("failed to release fence for cursor");
5452 goto fail_unpin; 5442 goto fail_unpin;
5453 } 5443 }
5454 5444
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index e0903c5f0ca2..fcf6fcb0b482 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -773,14 +773,10 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
773 if (ret != 0) 773 if (ret != 0)
774 return ret; 774 return ret;
775 775
776 ret = i915_gem_object_pin(new_bo, PAGE_SIZE, true); 776 ret = i915_gem_object_pin_to_display_plane(new_bo, 0, NULL);
777 if (ret != 0) 777 if (ret != 0)
778 return ret; 778 return ret;
779 779
780 ret = i915_gem_object_set_to_display_plane(new_bo, NULL);
781 if (ret != 0)
782 goto out_unpin;
783
784 ret = i915_gem_object_put_fence(new_bo); 780 ret = i915_gem_object_put_fence(new_bo);
785 if (ret) 781 if (ret)
786 goto out_unpin; 782 goto out_unpin;