}
}
+/**
+ * This function computes the tile_w (in bytes) and tile_h (in rows) of
+ * different tiling patterns.
+ */
+static void
+iris_resource_get_tile_dims(enum isl_tiling tiling, uint32_t cpp,
+ uint32_t *tile_w, uint32_t *tile_h)
+{
+ switch (tiling) {
+ case ISL_TILING_X:
+ *tile_w = 512;
+ *tile_h = 8;
+ break;
+ case ISL_TILING_Y0:
+ *tile_w = 128;
+ *tile_h = 32;
+ break;
+ case ISL_TILING_LINEAR:
+ *tile_w = cpp;
+ *tile_h = 1;
+ break;
+ default:
+ unreachable("not reached");
+ }
+
+}
+
+/**
+ * This function computes masks that may be used to select the bits of the X
+ * and Y coordinates that indicate the offset within a tile. If the BO is
+ * untiled, the masks are set to 0.
+ */
+static void
+iris_resource_get_tile_masks(enum isl_tiling tiling, uint32_t cpp,
+ uint32_t *mask_x, uint32_t *mask_y)
+{
+ uint32_t tile_w_bytes, tile_h;
+
+ iris_resource_get_tile_dims(tiling, cpp, &tile_w_bytes, &tile_h);
+
+ *mask_x = tile_w_bytes / cpp - 1;
+ *mask_y = tile_h - 1;
+}
+
+/**
+ * Compute the offset (in bytes) from the start of the BO to the given x
+ * and y coordinate. For tiled BOs, caller must ensure that x and y are
+ * multiples of the tile size.
+ */
+static uint32_t
+iris_resource_get_aligned_offset(const struct iris_resource *res,
+ uint32_t x, uint32_t y)
+{
+ const struct isl_format_layout *fmtl = isl_format_get_layout(res->surf.format);
+ unsigned cpp = fmtl->bpb / 8;
+ uint32_t pitch = res->surf.row_pitch_B;
+
+ switch (res->surf.tiling) {
+ default:
+ unreachable("not reached");
+ case ISL_TILING_LINEAR:
+ return y * pitch + x * cpp;
+ case ISL_TILING_X:
+ assert((x % (512 / cpp)) == 0);
+ assert((y % 8) == 0);
+ return y * pitch + x / (512 / cpp) * 4096;
+ case ISL_TILING_Y0:
+ assert((x % (128 / cpp)) == 0);
+ assert((y % 32) == 0);
+ return y * pitch + x / (128 / cpp) * 4096;
+ }
+}
+
+/**
+ * Rendering with tiled buffers requires that the base address of the buffer
+ * be aligned to a page boundary. For renderbuffers, and sometimes with
+ * textures, we may want the surface to point at a texture image level that
+ * isn't at a page boundary.
+ *
+ * This function returns an appropriately-aligned base offset
+ * according to the tiling restrictions, plus any required x/y offset
+ * from there.
+ */
+uint32_t
+iris_resource_get_tile_offsets(const struct iris_resource *res,
+ uint32_t level, uint32_t z,
+ uint32_t *tile_x, uint32_t *tile_y)
+{
+ uint32_t x, y;
+ uint32_t mask_x, mask_y;
+
+ const struct isl_format_layout *fmtl = isl_format_get_layout(res->surf.format);
+ const unsigned cpp = fmtl->bpb / 8;
+
+ iris_resource_get_tile_masks(res->surf.tiling, cpp, &mask_x, &mask_y);
+ get_image_offset_el(&res->surf, level, z, &x, &y);
+
+ *tile_x = x & mask_x;
+ *tile_y = y & mask_y;
+
+ return iris_resource_get_aligned_offset(res, x & ~mask_x, y & ~mask_y);
+}
+
/**
* Get pointer offset into stencil buffer.
*