diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-01-09 16:16:09 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2017-01-10 08:12:20 +0000 |
commit | 5b30694b474d00f8588fa367f9562d8f2e4c7075 (patch) | |
tree | bddd98d76a0ad390e2e592dce15d54db7260a64d /drivers/gpu/drm/i915/i915_gem.c | |
parent | 6649a0b6501d78042fd0fffaaefab1aeee27e75d (diff) |
drm/i915: Align GGTT sizes to a fence tile row
Ensure the view occupies the full tile row so that reads/writes into the
VMA do not escape (via fenced detiling) into neighbouring objects - we
will pad the object with scratch pages to satisfy the fence. This
applies the lazy-tiling we employed on gen2/3 to gen4+.
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/20170109161613.11881-2-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e8e278f6312e..07cc0d01915f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2021,21 +2021,29 @@ void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv) * @dev_priv: i915 device * @size: object size * @tiling_mode: tiling mode + * @stride: tiling stride * * Return the required global GTT size for an object, taking into account * potential fence register mapping. */ u64 i915_gem_get_ggtt_size(struct drm_i915_private *dev_priv, - u64 size, int tiling_mode) + u64 size, int tiling_mode, unsigned int stride) { u64 ggtt_size; - GEM_BUG_ON(size == 0); + GEM_BUG_ON(!size); - if (INTEL_GEN(dev_priv) >= 4 || - tiling_mode == I915_TILING_NONE) + if (tiling_mode == I915_TILING_NONE) return size; + GEM_BUG_ON(!stride); + + if (INTEL_GEN(dev_priv) >= 4) { + stride *= i915_gem_tile_height(tiling_mode); + GEM_BUG_ON(stride & 4095); + return roundup(size, stride); + } + /* Previous chips need a power-of-two fence region when tiling */ if (IS_GEN3(dev_priv)) ggtt_size = 1024*1024; @@ -2053,15 +2061,17 @@ u64 i915_gem_get_ggtt_size(struct drm_i915_private *dev_priv, * @dev_priv: i915 device * @size: object size * @tiling_mode: tiling mode + * @stride: tiling stride * @fenced: is fenced alignment required or not * * Return the required global GTT alignment for an object, taking into account * potential fence register mapping. */ u64 i915_gem_get_ggtt_alignment(struct drm_i915_private *dev_priv, u64 size, - int tiling_mode, bool fenced) + int tiling_mode, unsigned int stride, + bool fenced) { - GEM_BUG_ON(size == 0); + GEM_BUG_ON(!size); /* * Minimum alignment is 4k (GTT page size), but might be greater @@ -2076,7 +2086,7 @@ u64 i915_gem_get_ggtt_alignment(struct drm_i915_private *dev_priv, u64 size, * Previous chips need to be aligned to the size of the smallest * fence register that can contain the object. */ - return i915_gem_get_ggtt_size(dev_priv, size, tiling_mode); + return i915_gem_get_ggtt_size(dev_priv, size, tiling_mode, stride); } static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj) @@ -3696,7 +3706,8 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj, u32 fence_size; fence_size = i915_gem_get_ggtt_size(dev_priv, vma->size, - i915_gem_object_get_tiling(obj)); + i915_gem_object_get_tiling(obj), + i915_gem_object_get_stride(obj)); /* If the required space is larger than the available * aperture, we will not able to find a slot for the * object and unbinding the object now will be in |