]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/gpu/drm/i915/i915_gem.c
drm/i915: Don't return busy for buffers left on the flushing list.
[linux-2.6-omap-h63xx.git] / drivers / gpu / drm / i915 / i915_gem.c
index 174c0c3ba0b0f25079c9ae39db250fdbfe256612..24fe8c10b4b22c6bac1cfa17d79d55f02dd59179 100644 (file)
@@ -435,6 +435,13 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
 #endif
        if (read_domains & I915_GEM_DOMAIN_GTT) {
                ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0);
+
+               /* Silently promote "you're not bound, there was nothing to do"
+                * to success, since the client was just asking us to
+                * make sure everything was done.
+                */
+               if (ret == -EINVAL)
+                       ret = 0;
        } else {
                ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0);
        }
@@ -1097,6 +1104,8 @@ i915_gem_evict_everything(struct drm_device *dev)
                if (ret != 0)
                        break;
        }
+       if (ret == -ENOMEM)
+               return 0;
        return ret;
 }
 
@@ -1304,6 +1313,10 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
        struct drm_i915_gem_object *obj_priv = obj->driver_private;
        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. */
        ret = i915_gem_object_wait_rendering(obj);
@@ -2296,7 +2309,14 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
        }
 
        obj_priv = obj->driver_private;
-       args->busy = obj_priv->active;
+       /* Don't count being on the flushing list against the object being
+        * done.  Otherwise, a buffer left on the flushing list but not getting
+        * flushed (because nobody's flushing that domain) won't ever return
+        * unbusy and get reused by libdrm's bo cache.  The other expected
+        * consumer of this interface, OpenGL's occlusion queries, also specs
+        * that the objects get unbusy "eventually" without any interference.
+        */
+       args->busy = obj_priv->active && obj_priv->last_rendering_seqno != 0;
 
        drm_gem_object_unreference(obj);
        mutex_unlock(&dev->struct_mutex);