diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-11-18 16:17:46 -0500 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2016-11-18 17:33:22 -0500 |
commit | a6a7cc4b7db6deaeca11cdd38844ea147a354c7a (patch) | |
tree | 1188202170d26689db3b3bfc00343c0a16db1ef3 | |
parent | b17993b7b29612369270567643bcff814f4b3d7f (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.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 2 |
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 | ||
3311 | out: | ||
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 | ||