aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/intel/intel_regions.c
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2011-05-13 12:13:40 -0700
committerEric Anholt <[email protected]>2011-05-18 13:57:18 -0700
commit3e43adef95ee24dd218279d2de56939b90edcb4c (patch)
treebab3d389ad1df2baa29223b6dd7d0ecb0f5855f4 /src/mesa/drivers/dri/intel/intel_regions.c
parenta98dd64af750fb6dae54b2dc02e0c5a3711156af (diff)
i965: Add support for rendering to depthbuffer mipmap levels > 0.
Fixes GL_ARB_depth_texture/fbo-clear-formats GL_EXT_packed_depth_stencil/fbo-clear-formats
Diffstat (limited to 'src/mesa/drivers/dri/intel/intel_regions.c')
-rw-r--r--src/mesa/drivers/dri/intel/intel_regions.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index a4da1ce4fa5..0253bbc2aa0 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -524,3 +524,38 @@ intel_region_buffer(struct intel_context *intel,
return region->buffer;
}
+
+/**
+ * Rendering to tiled buffers requires that the base address of the
+ * buffer be aligned to a page boundary. We generally render to
+ * textures by pointing the surface at the mipmap image level, which
+ * may not be aligned to a tile boundary.
+ *
+ * This function returns an appropriately-aligned base offset
+ * according to the tiling restrictions, plus any required x/y offset
+ * from there.
+ */
+uint32_t
+intel_region_tile_offsets(struct intel_region *region,
+ uint32_t *tile_x,
+ uint32_t *tile_y)
+{
+ uint32_t pitch = region->pitch * region->cpp;
+
+ if (region->tiling == I915_TILING_NONE) {
+ *tile_x = 0;
+ *tile_y = 0;
+ return region->draw_x * region->cpp + region->draw_y * pitch;
+ } else if (region->tiling == I915_TILING_X) {
+ *tile_x = region->draw_x % (512 / region->cpp);
+ *tile_y = region->draw_y % 8;
+ return ((region->draw_y / 8) * (8 * pitch) +
+ (region->draw_x - *tile_x) / (512 / region->cpp) * 4096);
+ } else {
+ assert(region->tiling == I915_TILING_Y);
+ *tile_x = region->draw_x % (128 / region->cpp);
+ *tile_y = region->draw_y % 32;
+ return ((region->draw_y / 32) * (32 * pitch) +
+ (region->draw_x - *tile_x) / (128 / region->cpp) * 4096);
+ }
+}