diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-09-24 21:15:47 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-10-29 11:15:07 +0100 |
commit | a00b10c360b35d6431a94cbf130a4e162870d661 (patch) | |
tree | e1c06b90d161bc81e8d2c819da3b676f75527dda /drivers/gpu/drm/i915/i915_gem_tiling.c | |
parent | 7465378fd7c681f6cf2b74b3494c4f0991d8c8ac (diff) |
drm/i915: Only enforce fence limits inside the GTT.
So long as we adhere to the fence registers rules for alignment and no
overlaps (including with unfenced accesses to linear memory) and account
for the tiled access in our size allocation, we do not have to allocate
the full fenced region for the object. This allows us to fight the bloat
tiling imposed on pre-i965 chipsets and frees up RAM for real use. [Inside
the GTT we still suffer the additional alignment constraints, so it doesn't
magic allow us to render larger scenes without stalls -- we need the
expanded GTT and fence pipelining to overcome those...]
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_tiling.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_tiling.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index af352de70be1..0597a737ebad 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -181,7 +181,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) } /* Check pitch constriants for all chips & tiling formats */ -bool +static bool i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) { int tile_width; @@ -232,25 +232,35 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) return true; } -bool -i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode) +/* Is the current GTT allocation valid for the change in tiling? */ +static bool +i915_gem_object_fence_ok(struct drm_gem_object *obj, int tiling_mode) { - struct drm_device *dev = obj->dev; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - - if (obj_priv->gtt_space == NULL) - return true; + u32 size; if (tiling_mode == I915_TILING_NONE) return true; - if (INTEL_INFO(dev)->gen >= 4) + if (INTEL_INFO(obj->dev)->gen >= 4) return true; - if (obj_priv->gtt_offset & (obj->size - 1)) + /* + * Previous chips need to be aligned to the size of the smallest + * fence register that can contain the object. + */ + if (INTEL_INFO(obj->dev)->gen == 3) + size = 1024*1024; + else + size = 512*1024; + + while (size < obj_priv->base.size) + size <<= 1; + + if (obj_priv->gtt_offset & (size - 1)) return false; - if (IS_GEN3(dev)) { + if (INTEL_INFO(obj->dev)->gen == 3) { if (obj_priv->gtt_offset & ~I915_FENCE_START_MASK) return false; } else { @@ -331,7 +341,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, * tiling mode. Otherwise we can just leave it alone, but * need to ensure that any fence register is cleared. */ - if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode)) + if (!i915_gem_object_fence_ok(obj, args->tiling_mode)) ret = i915_gem_object_unbind(obj); else if (obj_priv->fence_reg != I915_FENCE_REG_NONE) ret = i915_gem_object_put_fence_reg(obj, true); |