diff options
-rw-r--r-- | linux-core/drm_gem.c | 8 | ||||
-rw-r--r-- | linux-core/i915_gem.c | 16 |
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); |