aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-11-18 16:17:46 -0500
committerChris Wilson <chris@chris-wilson.co.uk>2016-11-18 17:33:22 -0500
commita6a7cc4b7db6deaeca11cdd38844ea147a354c7a (patch)
tree1188202170d26689db3b3bfc00343c0a16db1ef3
parentb17993b7b29612369270567643bcff814f4b3d7f (diff)
drm/i915: Always flush the dirty CPU cache when pinning the scanout
Currently we only clflush the scanout if it is in the CPU domain. Also flush if we have a pending CPU clflush. We also want to treat the dirtyfb path similar, and flush any pending writes there as well. v2: Only send the fb flush message if flushing the dirt on flip v3: Make flush-for-flip and dirtyfb look more alike since they serve similar roles as end-of-frame marker. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> #v2 Link: http://patchwork.freedesktop.org/patch/msgid/20161118211747.25197-1-chris@chris-wilson.co.uk
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c22
-rw-r--r--drivers/gpu/drm/i915/intel_display.c2
2 files changed, 13 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 4500731fed10..b6ad1bae5a15 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3204,12 +3204,12 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
3204 enum i915_cache_level cache_level) 3204 enum i915_cache_level cache_level)
3205{ 3205{
3206 struct i915_vma *vma; 3206 struct i915_vma *vma;
3207 int ret = 0; 3207 int ret;
3208 3208
3209 lockdep_assert_held(&obj->base.dev->struct_mutex); 3209 lockdep_assert_held(&obj->base.dev->struct_mutex);
3210 3210
3211 if (obj->cache_level == cache_level) 3211 if (obj->cache_level == cache_level)
3212 goto out; 3212 return 0;
3213 3213
3214 /* Inspect the list of currently bound VMA and unbind any that would 3214 /* Inspect the list of currently bound VMA and unbind any that would
3215 * be invalid given the new cache-level. This is principally to 3215 * be invalid given the new cache-level. This is principally to
@@ -3304,18 +3304,14 @@ restart:
3304 } 3304 }
3305 } 3305 }
3306 3306
3307 if (obj->base.write_domain == I915_GEM_DOMAIN_CPU &&
3308 cpu_cache_is_coherent(obj->base.dev, obj->cache_level))
3309 obj->cache_dirty = true;
3310
3307 list_for_each_entry(vma, &obj->vma_list, obj_link) 3311 list_for_each_entry(vma, &obj->vma_list, obj_link)
3308 vma->node.color = cache_level; 3312 vma->node.color = cache_level;
3309 obj->cache_level = cache_level; 3313 obj->cache_level = cache_level;
3310 3314
3311out:
3312 /* Flush the dirty CPU caches to the backing storage so that the
3313 * object is now coherent at its new cache level (with respect
3314 * to the access domain).
3315 */
3316 if (obj->cache_dirty && cpu_write_needs_clflush(obj))
3317 i915_gem_clflush_object(obj, true);
3318
3319 return 0; 3315 return 0;
3320} 3316}
3321 3317
@@ -3471,7 +3467,11 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
3471 3467
3472 vma->display_alignment = max_t(u64, vma->display_alignment, alignment); 3468 vma->display_alignment = max_t(u64, vma->display_alignment, alignment);
3473 3469
3474 i915_gem_object_flush_cpu_write_domain(obj); 3470 /* Treat this as an end-of-frame, like intel_user_framebuffer_dirty() */
3471 if (obj->cache_dirty) {
3472 i915_gem_clflush_object(obj, true);
3473 intel_fb_obj_flush(obj, false, ORIGIN_DIRTYFB);
3474 }
3475 3475
3476 old_write_domain = obj->base.write_domain; 3476 old_write_domain = obj->base.write_domain;
3477 old_read_domains = obj->base.read_domains; 3477 old_read_domains = obj->base.read_domains;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3bd0e6765fca..8d270f7650de 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -15679,6 +15679,8 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
15679 struct drm_i915_gem_object *obj = intel_fb->obj; 15679 struct drm_i915_gem_object *obj = intel_fb->obj;
15680 15680
15681 mutex_lock(&dev->struct_mutex); 15681 mutex_lock(&dev->struct_mutex);
15682 if (obj->pin_display && obj->cache_dirty)
15683 i915_gem_clflush_object(obj, true);
15682 intel_fb_obj_flush(obj, false, ORIGIN_DIRTYFB); 15684 intel_fb_obj_flush(obj, false, ORIGIN_DIRTYFB);
15683 mutex_unlock(&dev->struct_mutex); 15685 mutex_unlock(&dev->struct_mutex);
15684 15686