[PATCH 08/10] drm/i915: Track display alignment on VMA

Chris Wilson
2016-08-12T10:28:39Z

When using the aliasing ppgtt and pagefliping 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>
---
drivers/gpu/drm/i915/i915_gem.c | 21 ++++++++-------------
drivers/gpu/drm/i915/i915_gem_gtt.h | 2 +-
2 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6459e2766145..d8f2fc282041 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2973,7 +2973,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));
@@ -2984,17 +2983,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;

@@ -3518,6 +3510,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);
@@ -3548,7 +3542,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));
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 3d85a1959bd1..d2f79a1fb75f 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -183,7 +183,7 @@ struct i915_vma {
struct drm_i915_fence_reg *fence;
struct sg_table *pages;
void __iomem *iomap;
- u64 size;
+ u64 size, display_alignment;

unsigned int flags;
/**
--
2.8.1