summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/drm_gem.c8
-rw-r--r--linux-core/i915_gem.c16
2 files changed, 20 insertions, 4 deletions
diff --git a/linux-core/drm_gem.c b/linux-core/drm_gem.c
index a8253bc5..fb175d7d 100644
--- a/linux-core/drm_gem.c
+++ b/linux-core/drm_gem.c
@@ -100,6 +100,14 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size)
kref_init(&obj->handlecount);
obj->size = size;
+ /*
+ * We've just allocated pages from the kernel,
+ * so they've just been written by the CPU with
+ * zeros. They'll need to be clflushed before we
+ * use them with the GPU.
+ */
+ obj->write_domain = DRM_GEM_DOMAIN_CPU;
+ obj->read_domains = DRM_GEM_DOMAIN_CPU;
if (dev->driver->gem_init_object != NULL &&
dev->driver->gem_init_object(obj) != 0) {
fput(obj->filp);
diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c
index 3214707f..60a8fa58 100644
--- a/linux-core/i915_gem.c
+++ b/linux-core/i915_gem.c
@@ -35,6 +35,11 @@
#define WATCH_LRU 0
#define WATCH_RELOC 0
+static void
+i915_gem_object_set_domain(struct drm_gem_object *obj,
+ uint32_t read_domains,
+ uint32_t write_domain);
+
int
i915_gem_init_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
@@ -456,11 +461,14 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
if (obj_priv->gtt_space == NULL)
return;
- /* Ignore the return value of wait_rendering. If we're here but
- * a wait_rendering hasn't completed, we're in the freeing process,
- * and we want the buffer to go away even if the command queue is hung.
+ /* Move the object to the CPU domain to ensure that
+ * any possible CPU writes while it's not in the GTT
+ * are flushed when we go to remap it. This will
+ * also ensure that all pending GPU writes are finished
+ * before we unbind.
*/
- (void)i915_gem_object_wait_rendering(obj);
+ i915_gem_object_set_domain (obj, DRM_GEM_DOMAIN_CPU,
+ DRM_GEM_DOMAIN_CPU);
if (obj_priv->agp_mem != NULL) {
drm_unbind_agp(obj_priv->agp_mem);