drm/i915: Track display alignment on VMA
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 18 Aug 2016 16:17:07 +0000 (17:17 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 18 Aug 2016 21:36:56 +0000 (22:36 +0100)
When using the aliasing ppgtt and pageflipping with the shrinker/eviction
active, we note that we often have to rebind the backbuffer before
flipping onto the scanout because it has an invalid alignment. If we
store the worst-case alignment required for a VMA, we can avoid having
to rebind at critical junctures.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20160818161718.27187-28-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_gtt.h

index 69a994bd6afdcb8fe50040edfc8ad40968f3eb57..021f807d7afc1b6b4f3cd93861bcb8a2237c2eb8 100644 (file)
@@ -3050,7 +3050,6 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
        struct drm_i915_private *dev_priv = to_i915(vma->vm->dev);
        struct drm_i915_gem_object *obj = vma->obj;
        u64 start, end;
-       u64 min_alignment;
        int ret;
 
        GEM_BUG_ON(vma->flags & (I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND));
@@ -3061,17 +3060,10 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
                size = i915_gem_get_ggtt_size(dev_priv, size,
                                              i915_gem_object_get_tiling(obj));
 
-       min_alignment =
-               i915_gem_get_ggtt_alignment(dev_priv, size,
-                                           i915_gem_object_get_tiling(obj),
-                                           flags & PIN_MAPPABLE);
-       if (alignment == 0)
-               alignment = min_alignment;
-       if (alignment & (min_alignment - 1)) {
-               DRM_DEBUG("Invalid object alignment requested %llu, minimum %llu\n",
-                         alignment, min_alignment);
-               return -EINVAL;
-       }
+       alignment = max(max(alignment, vma->display_alignment),
+                       i915_gem_get_ggtt_alignment(dev_priv, size,
+                                                   i915_gem_object_get_tiling(obj),
+                                                   flags & PIN_MAPPABLE));
 
        start = flags & PIN_OFFSET_BIAS ? flags & PIN_OFFSET_MASK : 0;
 
@@ -3595,6 +3587,8 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
        if (IS_ERR(vma))
                goto err_unpin_display;
 
+       vma->display_alignment = max_t(u64, vma->display_alignment, alignment);
+
        WARN_ON(obj->pin_display > i915_vma_pin_count(vma));
 
        i915_gem_object_flush_cpu_write_domain(obj);
@@ -3625,7 +3619,8 @@ i915_gem_object_unpin_from_display_plane(struct i915_vma *vma)
        if (WARN_ON(vma->obj->pin_display == 0))
                return;
 
-       vma->obj->pin_display--;
+       if (--vma->obj->pin_display == 0)
+               vma->display_alignment = 0;
 
        i915_vma_unpin(vma);
        WARN_ON(vma->obj->pin_display > i915_vma_pin_count(vma));
index 9248a0e0b28679f8a6f5195a3ddce75e326b11ce..a15cea73f7290997abc668eb4584070304b87340 100644 (file)
@@ -184,6 +184,7 @@ struct i915_vma {
        struct sg_table *pages;
        void __iomem *iomap;
        u64 size;
+       u64 display_alignment;
 
        unsigned int flags;
        /**