summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-06-09 10:08:41 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-06-09 10:18:31 +0100
commite65caeba9ed0e6c53830d944248aaae2228351ab (patch)
treecc8c2f3fc95d1e8ddeffcccceeccfdadfd18df7d
parentf179137f8f5bf272b79266575121c7a04038290c (diff)
intel: Convert to untiled pitches if surface is too large for tiling.
If the pitch is too large for the hardware to tile, recompute the required surface size based on the untiled pitch and alignments. For the older hardware, which has smaller limits and greater restrictions, this may be a considerable saving in allocation size. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--intel/intel_bufmgr_gem.c54
1 files changed, 31 insertions, 23 deletions
diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index b125c129..861cf0e8 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -689,31 +689,39 @@ drm_intel_gem_bo_alloc_tiled(drm_intel_bufmgr *bufmgr, const char *name,
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
drm_intel_bo *bo;
- unsigned long size, stride, aligned_y = y;
+ unsigned long size, stride;
+ uint32_t tiling;
int ret;
- /* If we're tiled, our allocations are in 8 or 32-row blocks,
- * so failure to align our height means that we won't allocate
- * enough pages.
- *
- * If we're untiled, we still have to align to 2 rows high
- * because the data port accesses 2x2 blocks even if the
- * bottom row isn't to be rendered, so failure to align means
- * we could walk off the end of the GTT and fault. This is
- * documented on 965, and may be the case on older chipsets
- * too so we try to be careful.
- */
- if (*tiling_mode == I915_TILING_NONE)
- aligned_y = ALIGN(y, 2);
- else if (*tiling_mode == I915_TILING_X)
- aligned_y = ALIGN(y, 8);
- else if (*tiling_mode == I915_TILING_Y)
- aligned_y = ALIGN(y, 32);
-
- stride = x * cpp;
- stride = drm_intel_gem_bo_tile_pitch(bufmgr_gem, stride, *tiling_mode);
- size = stride * aligned_y;
- size = drm_intel_gem_bo_tile_size(bufmgr_gem, size, tiling_mode);
+ do {
+ unsigned long aligned_y;
+
+ tiling = *tiling_mode;
+
+ /* If we're tiled, our allocations are in 8 or 32-row blocks,
+ * so failure to align our height means that we won't allocate
+ * enough pages.
+ *
+ * If we're untiled, we still have to align to 2 rows high
+ * because the data port accesses 2x2 blocks even if the
+ * bottom row isn't to be rendered, so failure to align means
+ * we could walk off the end of the GTT and fault. This is
+ * documented on 965, and may be the case on older chipsets
+ * too so we try to be careful.
+ */
+ aligned_y = y;
+ if (tiling == I915_TILING_NONE)
+ aligned_y = ALIGN(y, 2);
+ else if (tiling == I915_TILING_X)
+ aligned_y = ALIGN(y, 8);
+ else if (tiling == I915_TILING_Y)
+ aligned_y = ALIGN(y, 32);
+
+ stride = x * cpp;
+ stride = drm_intel_gem_bo_tile_pitch(bufmgr_gem, stride, tiling);
+ size = stride * aligned_y;
+ size = drm_intel_gem_bo_tile_size(bufmgr_gem, size, tiling_mode);
+ } while (*tiling_mode != tiling);
bo = drm_intel_gem_bo_alloc_internal(bufmgr, name, size, flags);
if (!bo)