From: Jason Ekstrand Date: Wed, 22 Jan 2020 17:40:00 +0000 (-0600) Subject: isl: Add a helper for calculating subimage memory ranges X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=64ca8a3272ec337bf026d8319b9565441c945c8b;p=mesa.git isl: Add a helper for calculating subimage memory ranges Reviewed-by: Lionel Landwerlin Reviewed-by: Jordan Justen Part-of: --- diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c index 86517f662dd..333f309fefb 100644 --- a/src/intel/isl/isl.c +++ b/src/intel/isl/isl.c @@ -2513,6 +2513,56 @@ isl_surf_get_image_offset_B_tile_sa(const struct isl_surf *surf, } } +void +isl_surf_get_image_range_B_tile(const struct isl_surf *surf, + uint32_t level, + uint32_t logical_array_layer, + uint32_t logical_z_offset_px, + uint32_t *start_tile_B, + uint32_t *end_tile_B) +{ + uint32_t start_x_offset_el, start_y_offset_el; + isl_surf_get_image_offset_el(surf, level, logical_array_layer, + logical_z_offset_px, + &start_x_offset_el, + &start_y_offset_el); + + /* Compute the size of the subimage in surface elements */ + const uint32_t subimage_w_sa = isl_minify(surf->phys_level0_sa.w, level); + const uint32_t subimage_h_sa = isl_minify(surf->phys_level0_sa.h, level); + const struct isl_format_layout *fmtl = isl_format_get_layout(surf->format); + const uint32_t subimage_w_el = isl_align_div_npot(subimage_w_sa, fmtl->bw); + const uint32_t subimage_h_el = isl_align_div_npot(subimage_h_sa, fmtl->bh); + + /* Find the last pixel */ + uint32_t end_x_offset_el = start_x_offset_el + subimage_w_el - 1; + uint32_t end_y_offset_el = start_y_offset_el + subimage_h_el - 1; + + UNUSED uint32_t x_offset_el, y_offset_el; + isl_tiling_get_intratile_offset_el(surf->tiling, fmtl->bpb, + surf->row_pitch_B, + start_x_offset_el, + start_y_offset_el, + start_tile_B, + &x_offset_el, + &y_offset_el); + + isl_tiling_get_intratile_offset_el(surf->tiling, fmtl->bpb, + surf->row_pitch_B, + end_x_offset_el, + end_y_offset_el, + end_tile_B, + &x_offset_el, + &y_offset_el); + + /* We want the range we return to be exclusive but the tile containing the + * last pixel (what we just calculated) is inclusive. Add one. + */ + (*end_tile_B)++; + + assert(*end_tile_B <= surf->size_B); +} + void isl_surf_get_image_surf(const struct isl_device *dev, const struct isl_surf *surf, diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h index d2bd021af57..86fb7f1ad8a 100644 --- a/src/intel/isl/isl.h +++ b/src/intel/isl/isl.h @@ -2104,6 +2104,27 @@ isl_surf_get_image_offset_B_tile_sa(const struct isl_surf *surf, uint32_t *x_offset_sa, uint32_t *y_offset_sa); +/** + * Calculate the range in bytes occupied by a subimage, to the nearest tile. + * + * The range returned will be the smallest memory range in which the give + * subimage fits, rounded to even tiles. Intel images do not usually have a + * direct subimage -> range mapping so the range returned may contain data + * from other sub-images. The returned range is a half-open interval where + * all of the addresses within the subimage are < end_tile_B. + * + * @invariant level < surface levels + * @invariant logical_array_layer < logical array length of surface + * @invariant logical_z_offset_px < logical depth of surface at level + */ +void +isl_surf_get_image_range_B_tile(const struct isl_surf *surf, + uint32_t level, + uint32_t logical_array_layer, + uint32_t logical_z_offset_px, + uint32_t *start_tile_B, + uint32_t *end_tile_B); + /** * Create an isl_surf that represents a particular subimage in the surface. *