OSDN Git Service

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 590d8f2..7b37c19 100644 (file)
@@ -729,6 +729,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.
         * Protected by dev->struct_mutex.
index eae52de..c3e6d7b 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 f57536a..af01a58 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);