drm/i915: Install fence register for tiled scanout on i915
authorChris Wilson <chris@chris-wilson.co.uk>
Wed, 17 Jun 2009 21:08:52 +0000 (22:08 +0100)
committerEric Anholt <eric@anholt.net>
Thu, 18 Jun 2009 18:47:04 +0000 (11:47 -0700)
With the work by Jesse Barnes to eliminate allocation of fences during
execbuffer, it becomes possible to write to the scan-out buffer with it
never acquiring a fence (simply by only ever writing to the object using
tiled GPU commands and never writing to it via the GTT). So for pre-i965
chipsets which require fenced access for tiled scan-out buffers, we need
to obtain a fence register.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Eric Anholt <eric@anholt.net>
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_display.c

index 8ef6bcec211bbc3f6440ba79b198a3d53e633eb8..451b547352b763c4873217012388fdfc392adc42 100644 (file)
@@ -646,6 +646,7 @@ void i915_gem_object_unpin(struct drm_gem_object *obj);
 int i915_gem_object_unbind(struct drm_gem_object *obj);
 void i915_gem_lastclose(struct drm_device *dev);
 uint32_t i915_get_gem_seqno(struct drm_device *dev);
+int i915_gem_object_get_fence_reg(struct drm_gem_object *obj);
 void i915_gem_retire_requests(struct drm_device *dev);
 void i915_gem_retire_work_handler(struct work_struct *work);
 void i915_gem_clflush_object(struct drm_gem_object *obj);
index a5f95ad3c072a8117ecdb086e507d191336a9e0e..4f345414fe7cb02f749a70ddd53070de22ff5f69 100644 (file)
@@ -46,7 +46,6 @@ static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *o
 static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
 static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
                                           unsigned alignment);
-static int i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write);
 static void i915_gem_clear_fence_reg(struct drm_gem_object *obj);
 static int i915_gem_evict_something(struct drm_device *dev);
 static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
@@ -1158,7 +1157,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        /* Need a new fence register? */
        if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
            obj_priv->tiling_mode != I915_TILING_NONE) {
-               ret = i915_gem_object_get_fence_reg(obj, write);
+               ret = i915_gem_object_get_fence_reg(obj);
                if (ret) {
                        mutex_unlock(&dev->struct_mutex);
                        return VM_FAULT_SIGBUS;
@@ -2169,7 +2168,6 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
 /**
  * i915_gem_object_get_fence_reg - set up a fence reg for an object
  * @obj: object to map through a fence reg
- * @write: object is about to be written
  *
  * When mapping objects through the GTT, userspace wants to be able to write
  * to them without having to worry about swizzling if the object is tiled.
@@ -2180,8 +2178,8 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
  * It then sets up the reg based on the object's properties: address, pitch
  * and tiling format.
  */
-static int
-i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write)
+int
+i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3550,7 +3548,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
        if (!IS_I965G(dev) &&
            obj_priv->fence_reg == I915_FENCE_REG_NONE &&
            obj_priv->tiling_mode != I915_TILING_NONE) {
-               ret = i915_gem_object_get_fence_reg(obj, true);
+               ret = i915_gem_object_get_fence_reg(obj);
                if (ret != 0) {
                        if (ret != -EBUSY && ret != -ERESTARTSYS)
                                DRM_ERROR("Failure to install fence: %d\n",
index 028f5b66e3d83eaedd66eeaea168ca68cde185ef..3e1c7816211904391c1b65a43a7aace7726db5fc 100644 (file)
@@ -828,19 +828,31 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
        }
 
        mutex_lock(&dev->struct_mutex);
-       ret = i915_gem_object_pin(intel_fb->obj, alignment);
+       ret = i915_gem_object_pin(obj, alignment);
        if (ret != 0) {
                mutex_unlock(&dev->struct_mutex);
                return ret;
        }
 
-       ret = i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1);
+       ret = i915_gem_object_set_to_gtt_domain(obj, 1);
        if (ret != 0) {
-               i915_gem_object_unpin(intel_fb->obj);
+               i915_gem_object_unpin(obj);
                mutex_unlock(&dev->struct_mutex);
                return ret;
        }
 
+       /* Pre-i965 needs to install a fence for tiled scan-out */
+       if (!IS_I965G(dev) &&
+           obj_priv->fence_reg == I915_FENCE_REG_NONE &&
+           obj_priv->tiling_mode != I915_TILING_NONE) {
+               ret = i915_gem_object_get_fence_reg(obj);
+               if (ret != 0) {
+                       i915_gem_object_unpin(obj);
+                       mutex_unlock(&dev->struct_mutex);
+                       return ret;
+               }
+       }
+
        dspcntr = I915_READ(dspcntr_reg);
        /* Mask out pixel format bits in case we change it */
        dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
@@ -860,7 +872,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
                break;
        default:
                DRM_ERROR("Unknown color depth\n");
-               i915_gem_object_unpin(intel_fb->obj);
+               i915_gem_object_unpin(obj);
                mutex_unlock(&dev->struct_mutex);
                return -EINVAL;
        }