diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2010-11-14 22:32:36 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-11-15 05:22:16 +0000 |
commit | 5e78330126e23e009502b21d1efdabd68ab91397 (patch) | |
tree | 91415acc000ae651d12def49c40de89e520c7ead /drivers | |
parent | 8168bd48bb863c00747497aadf13884b2d69d287 (diff) |
drm/i915: fix relaxed tiling for gen <= 3 && !g33
g33/pineview doesn't have any alignment constrains for unfenced tiled
buffers. But older chips have. Fix this.
Problem introduced in a00b10c360b35d6431a94cbf130a4e162870d661.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 52f5c194c50f..f2038f6df3b0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1467,7 +1467,7 @@ i915_gem_free_mmap_offset(struct drm_gem_object *obj) * @obj: object to check * * Return the required GTT alignment for an object, taking into account - * potential fence register mapping if needed. + * potential fence register mapping. */ static uint32_t i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj_priv) @@ -1489,6 +1489,41 @@ i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj_priv) return i915_gem_get_gtt_size(obj_priv); } +/** + * i915_gem_get_unfenced_gtt_alignment - return required GTT alignment for an + * unfenced object + * @obj: object to check + * + * Return the required GTT alignment for an object, only taking into account + * unfenced tiled surface requirements. + */ +static uint32_t +i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj_priv) +{ + struct drm_device *dev = obj_priv->base.dev; + int tile_height; + + /* + * Minimum alignment is 4k (GTT page size) for sane hw. + */ + if (INTEL_INFO(dev)->gen >= 4 || IS_G33(dev) || + obj_priv->tiling_mode == I915_TILING_NONE) + return 4096; + + /* + * Older chips need unfenced tiled buffers to be aligned to the left + * edge of an even tile row (where tile rows are counted as if the bo is + * placed in a fenced gtt region). + */ + if (IS_GEN2(dev) || + (obj_priv->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) + tile_height = 32; + else + tile_height = 8; + + return tile_height * obj_priv->stride * 2; +} + static uint32_t i915_gem_get_gtt_size(struct drm_i915_gem_object *obj_priv) { @@ -2689,7 +2724,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_mm_node *free_space; gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; - u32 size, fence_size, fence_alignment; + u32 size, fence_size, fence_alignment, unfenced_alignment; bool mappable, fenceable; int ret; @@ -2700,9 +2735,11 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, fence_size = i915_gem_get_gtt_size(obj_priv); fence_alignment = i915_gem_get_gtt_alignment(obj_priv); + unfenced_alignment = i915_gem_get_unfenced_gtt_alignment(obj_priv); if (alignment == 0) - alignment = map_and_fenceable ? fence_alignment : 4096; + alignment = map_and_fenceable ? fence_alignment : + unfenced_alignment; if (map_and_fenceable && alignment & (fence_alignment - 1)) { DRM_ERROR("Invalid object alignment requested %u\n", alignment); return -EINVAL; |