From: Sagar Ghuge Date: Tue, 16 Jul 2019 17:48:19 +0000 (-0700) Subject: iris: Add helper functions to get tile offset X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=61c0637afb4ff760dd8dbe138266820adc921ce5;p=mesa.git iris: Add helper functions to get tile offset All helper functions are ported from i965 driver. Signed-off-by: Sagar Ghuge Reviewed-by: Kenneth Graunke --- diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index ec59436df79..03ffe4d8324 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -1315,6 +1315,109 @@ get_image_offset_el(const struct isl_surf *surf, unsigned level, unsigned z, } } +/** + * 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. * diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h index 707c559025c..7028e01494c 100644 --- a/src/gallium/drivers/iris/iris_resource.h +++ b/src/gallium/drivers/iris/iris_resource.h @@ -395,6 +395,9 @@ iris_resource_access_raw(struct iris_context *ice, enum isl_dim_layout iris_get_isl_dim_layout(const struct gen_device_info *devinfo, enum isl_tiling tiling, enum pipe_texture_target target); +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); enum isl_aux_usage iris_resource_texture_aux_usage(struct iris_context *ice, const struct iris_resource *res, enum isl_format view_fmt,