drm/i915: Prevent stalling for a GTT read back from a read-only GPU target
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 2 Dec 2010 09:42:56 +0000 (09:42 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 2 Dec 2010 10:00:15 +0000 (10:00 +0000)
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c

index 590d8f2d095878b7e5553012986a403b215529cc..7b37c198cb19586d22b280dbf79db280778ac06d 100644 (file)
@@ -728,6 +728,12 @@ struct drm_i915_gem_object {
         */
        unsigned int dirty : 1;
 
+       /**
+        * This is set if the object has been written to since the last
+        * GPU flush.
+        */
+       unsigned int pending_gpu_write : 1;
+
        /**
         * Fence register bits (if any) for this object.  Will be set
         * as needed when mapped into the GTT.
index eae52de75a4cb1da71f387fbee9d304d319c322f..c3e6d7bda6e18f30a7461856b66a8811740514ee 100644 (file)
@@ -1643,6 +1643,7 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
        obj->last_fenced_ring = NULL;
 
        obj->active = 0;
+       obj->pending_gpu_write = false;
        drm_gem_object_unreference(&obj->base);
 
        WARN_ON(i915_verify_lists(dev));
@@ -2810,9 +2811,11 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
                return -EINVAL;
 
        i915_gem_object_flush_gpu_write_domain(obj);
-       ret = i915_gem_object_wait_rendering(obj, true);
-       if (ret)
-               return ret;
+       if (obj->pending_gpu_write || write) {
+               ret = i915_gem_object_wait_rendering(obj, true);
+               if (ret)
+                       return ret;
+       }
 
        i915_gem_object_flush_cpu_write_domain(obj);
 
index f57536a70a3aa39891d9f7b946f3e325beaab2fd..af01a58a643bdb25146aec604acbc52561b7dc7a 100644 (file)
@@ -775,6 +775,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *objects,
                i915_gem_object_move_to_active(obj, ring);
                if (obj->base.write_domain) {
                        obj->dirty = 1;
+                       obj->pending_gpu_write = true;
                        list_move_tail(&obj->gpu_write_list,
                                       &ring->gpu_write_list);
                        intel_mark_busy(ring->dev, obj);