@@ -3105,10 +3105,6 @@ i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj,
uint32_t old_read_domains;
int ret;
- /* If the object is currently unbound, this is a no-op. */
- if (obj->gtt_space)
- return 0;
-
ret = i915_gem_object_flush_gpu_write_domain(obj);
if (ret)
return ret;
@@ -3120,14 +3116,32 @@ i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj,
return ret;
}
+ /* The display engine is not coherent with the LLC cache on gen6. As
+ * a result, we make sure that the pinning that is about to occur is
+ * done with uncached PTEs. This is lowest common denominator for all
+ * chipsets.
+ *
+ * However for gen6+, we could do better by using the GFDT bit instead
+ * of uncaching, which would allow us to flush all the LLC-cached data
+ * with that bit in the PTE to main memory with just one PIPE_CONTROL.
+ */
+ ret = i915_gem_object_set_cache_level(obj, I915_CACHE_NONE);
+ if (ret)
+ return ret;
+
i915_gem_object_flush_cpu_write_domain(obj);
- old_read_domains = obj->base.read_domains;
- obj->base.read_domains |= I915_GEM_DOMAIN_GTT;
+ /* If the object is not bound, it will be moved into the GTT domain
+ * when pinned otherwise do so here.
+ */
+ if (obj->gtt_space) {
+ old_read_domains = obj->base.read_domains;
+ obj->base.read_domains |= I915_GEM_DOMAIN_GTT;
- trace_i915_gem_object_change_domain(obj,
- old_read_domains,
- obj->base.write_domain);
+ trace_i915_gem_object_change_domain(obj,
+ old_read_domains,
+ obj->base.write_domain);
+ }
return 0;
}