diff options
-rw-r--r-- | intel/intel_bufmgr_gem.c | 54 |
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) |