|
@@ -2837,6 +2837,57 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Prepare buffer for display plane. Use uninterruptible for possible flush
|
|
|
+ * wait, as in modesetting process we're not supposed to be interrupted.
|
|
|
+ */
|
|
|
+int
|
|
|
+i915_gem_object_set_to_display_plane(struct drm_gem_object *obj)
|
|
|
+{
|
|
|
+ struct drm_device *dev = obj->dev;
|
|
|
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
|
|
|
+ uint32_t old_write_domain, old_read_domains;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ /* Not valid to be called on unbound objects. */
|
|
|
+ if (obj_priv->gtt_space == NULL)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ i915_gem_object_flush_gpu_write_domain(obj);
|
|
|
+
|
|
|
+ /* Wait on any GPU rendering and flushing to occur. */
|
|
|
+ if (obj_priv->active) {
|
|
|
+#if WATCH_BUF
|
|
|
+ DRM_INFO("%s: object %p wait for seqno %08x\n",
|
|
|
+ __func__, obj, obj_priv->last_rendering_seqno);
|
|
|
+#endif
|
|
|
+ ret = i915_do_wait_request(dev, obj_priv->last_rendering_seqno, 0);
|
|
|
+ if (ret != 0)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ old_write_domain = obj->write_domain;
|
|
|
+ old_read_domains = obj->read_domains;
|
|
|
+
|
|
|
+ obj->read_domains &= I915_GEM_DOMAIN_GTT;
|
|
|
+
|
|
|
+ i915_gem_object_flush_cpu_write_domain(obj);
|
|
|
+
|
|
|
+ /* It should now be out of any other write domains, and we can update
|
|
|
+ * the domain values for our changes.
|
|
|
+ */
|
|
|
+ BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0);
|
|
|
+ obj->read_domains |= I915_GEM_DOMAIN_GTT;
|
|
|
+ obj->write_domain = I915_GEM_DOMAIN_GTT;
|
|
|
+ obj_priv->dirty = 1;
|
|
|
+
|
|
|
+ trace_i915_gem_object_change_domain(obj,
|
|
|
+ old_read_domains,
|
|
|
+ old_write_domain);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Moves a single object to the CPU read, and possibly write domain.
|
|
|
*
|