diff options
author | Daniel Vetter <daniel@biene.ffwll.ch> | 2009-03-29 14:09:41 +0200 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-04-01 11:06:47 -0700 |
commit | 8d7773a32d8aa723030712b0a500a4a402a21c85 (patch) | |
tree | 8b3e9e0449f9c85fa97fbd44c761713a3821858c /drivers/gpu/drm/i915/i915_gem.c | |
parent | c09bca786ff941ed17c5f381c4eca5b106808c51 (diff) |
drm/i915: fix up tiling/fence reg setup on i8xx class hw
This fixes all the tiling problems with the 2d ddx. glxgears still doesn't work.
Changes:
- fix a copy&paste error in i8xx fence reg setup. It resulted in an at most a
512KB offset of the fence reg window, so was only visible sometimes.
- add tests for stride and object size constrains (also for i915 and 1965 class
hw). Userspace seems to have an of-by-one bug there, which changes the fence
size by at most 512KB due to an overflow.
- because i8xx hw is quite old (and therefore not as well-tested) I left 2 debug
WARN_ONs in the i8xx fence reg setup code to hopefully catch any further
overflows in the bit-fields. Lastly there's one small change to make the
alignment checks more consistent.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=20289
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e0389ad1477..0abccb76112 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1990,20 +1990,23 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) int regnum = obj_priv->fence_reg; uint32_t val; uint32_t pitch_val; + uint32_t fence_size_bits; - if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) || + if ((obj_priv->gtt_offset & ~I830_FENCE_START_MASK) || (obj_priv->gtt_offset & (obj->size - 1))) { - WARN(1, "%s: object 0x%08x not 1M or size aligned\n", + WARN(1, "%s: object 0x%08x not 512K or size aligned\n", __func__, obj_priv->gtt_offset); return; } pitch_val = (obj_priv->stride / 128) - 1; - + WARN_ON(pitch_val & ~0x0000000f); val = obj_priv->gtt_offset; if (obj_priv->tiling_mode == I915_TILING_Y) val |= 1 << I830_FENCE_TILING_Y_SHIFT; - val |= I830_FENCE_SIZE_BITS(obj->size); + fence_size_bits = I830_FENCE_SIZE_BITS(obj->size); + WARN_ON(fence_size_bits & ~0x00000f00); + val |= fence_size_bits; val |= pitch_val << I830_FENCE_PITCH_SHIFT; val |= I830_FENCE_REG_VALID; @@ -2194,7 +2197,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) return -EBUSY; if (alignment == 0) alignment = i915_gem_get_gtt_alignment(obj); - if (alignment & (PAGE_SIZE - 1)) { + if (alignment & (i915_gem_get_gtt_alignment(obj) - 1)) { DRM_ERROR("Invalid object alignment requested %u\n", alignment); return -EINVAL; } |