Commit 5a97bcc6 authored by Chris Wilson's avatar Chris Wilson

drm/i915: Amalgamate flushing of display objects

We have three different paths by which userspace wants to flush the
display plane (i.e. objects with obj->pin_display). Use a common helper
to identify those paths and to simplify a later change.

v2: Include the conditional in the name, i915_gem_object_flush_if_display
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170222114049.28456-3-chris@chris-wilson.co.uk
parent e59dc172
...@@ -1613,23 +1613,16 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, ...@@ -1613,23 +1613,16 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
{ {
struct drm_i915_gem_sw_finish *args = data; struct drm_i915_gem_sw_finish *args = data;
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
int err = 0;
obj = i915_gem_object_lookup(file, args->handle); obj = i915_gem_object_lookup(file, args->handle);
if (!obj) if (!obj)
return -ENOENT; return -ENOENT;
/* Pinned buffers may be scanout, so flush the cache */ /* Pinned buffers may be scanout, so flush the cache */
if (READ_ONCE(obj->pin_display)) { i915_gem_object_flush_if_display(obj);
err = i915_mutex_lock_interruptible(dev);
if (!err) {
i915_gem_object_flush_cpu_write_domain(obj);
mutex_unlock(&dev->struct_mutex);
}
}
i915_gem_object_put(obj); i915_gem_object_put(obj);
return err;
return 0;
} }
/** /**
...@@ -3221,6 +3214,27 @@ i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj) ...@@ -3221,6 +3214,27 @@ i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj)
obj->base.write_domain = 0; obj->base.write_domain = 0;
} }
static void __i915_gem_object_flush_for_display(struct drm_i915_gem_object *obj)
{
if (obj->base.write_domain != I915_GEM_DOMAIN_CPU && !obj->cache_dirty)
return;
i915_gem_clflush_object(obj, true);
intel_fb_obj_flush(obj, false, ORIGIN_CPU);
obj->base.write_domain = 0;
}
void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj)
{
if (!READ_ONCE(obj->pin_display))
return;
mutex_lock(&obj->base.dev->struct_mutex);
__i915_gem_object_flush_for_display(obj);
mutex_unlock(&obj->base.dev->struct_mutex);
}
/** /**
* Moves a single object to the GTT read, and possibly write domain. * Moves a single object to the GTT read, and possibly write domain.
* @obj: object to act on * @obj: object to act on
...@@ -3575,15 +3589,12 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, ...@@ -3575,15 +3589,12 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
vma->display_alignment = max_t(u64, vma->display_alignment, alignment); vma->display_alignment = max_t(u64, vma->display_alignment, alignment);
/* Treat this as an end-of-frame, like intel_user_framebuffer_dirty() */ /* Treat this as an end-of-frame, like intel_user_framebuffer_dirty() */
if (obj->cache_dirty || obj->base.write_domain == I915_GEM_DOMAIN_CPU) { __i915_gem_object_flush_for_display(obj);
i915_gem_clflush_object(obj, true);
intel_fb_obj_flush(obj, false, ORIGIN_DIRTYFB); intel_fb_obj_flush(obj, false, ORIGIN_DIRTYFB);
}
/* It should now be out of any other write domains, and we can update /* It should now be out of any other write domains, and we can update
* the domain values for our changes. * the domain values for our changes.
*/ */
obj->base.write_domain = 0;
obj->base.read_domains |= I915_GEM_DOMAIN_GTT; obj->base.read_domains |= I915_GEM_DOMAIN_GTT;
return vma; return vma;
......
...@@ -364,5 +364,7 @@ i915_gem_object_last_write_engine(struct drm_i915_gem_object *obj) ...@@ -364,5 +364,7 @@ i915_gem_object_last_write_engine(struct drm_i915_gem_object *obj)
return engine; return engine;
} }
void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj);
#endif #endif
...@@ -14278,15 +14278,10 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb, ...@@ -14278,15 +14278,10 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
struct drm_clip_rect *clips, struct drm_clip_rect *clips,
unsigned num_clips) unsigned num_clips)
{ {
struct drm_device *dev = fb->dev; struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
struct drm_i915_gem_object *obj = intel_fb->obj;
mutex_lock(&dev->struct_mutex); i915_gem_object_flush_if_display(obj);
if (obj->pin_display && obj->cache_dirty)
i915_gem_clflush_object(obj, true);
intel_fb_obj_flush(obj, false, ORIGIN_DIRTYFB); intel_fb_obj_flush(obj, false, ORIGIN_DIRTYFB);
mutex_unlock(&dev->struct_mutex);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment