diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c index 88405210e21..cfaf5f9ae38 100644 --- a/src/intel/isl/isl.c +++ b/src/intel/isl/isl.c @@ -4899,53 +4899,30 @@ isl_surf_get_image_range_B_tile(const struct isl_surf *surf, 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; - - /* We only consider one Z or array slice */ - const uint32_t end_z_offset_el = start_z_offset_el; - const uint32_t end_array_slice = start_array_slice; + const struct isl_extent4d subimage_extent_el = { + .w = subimage_w_el, + .h = subimage_h_el, + .d = 1, + .a = 1, + }; UNUSED uint32_t x_offset_el, y_offset_el, z_offset_el, array_slice; - isl_tiling_get_intratile_offset_el(surf->tiling, surf->dim, - surf->msaa_layout, fmtl->bpb, - surf->samples, - surf->row_pitch_B, - surf->array_pitch_el_rows, - start_x_offset_el, - start_y_offset_el, - start_z_offset_el, - start_array_slice, - start_tile_B, - &x_offset_el, - &y_offset_el, - &z_offset_el, - &array_slice); - - isl_tiling_get_intratile_offset_el(surf->tiling, surf->dim, - surf->msaa_layout, fmtl->bpb, - surf->samples, - surf->row_pitch_B, - surf->array_pitch_el_rows, - end_x_offset_el, - end_y_offset_el, - end_z_offset_el, - end_array_slice, - end_tile_B, - &x_offset_el, - &y_offset_el, - &z_offset_el, - &array_slice); - - struct isl_tile_info tile_info; - isl_surf_get_tile_info(surf, &tile_info); - - /* We want the range we return to be exclusive but the tile containing the - * last pixel (what we just calculated) is inclusive. Add one and round up - * to the tile size. - */ - *end_tile_B = ALIGN_NPOT(*end_tile_B + 1, tile_info.phys_extent_B.w * - tile_info.phys_extent_B.h); + isl_tiling_get_intratile_range_el(surf->tiling, surf->dim, + surf->msaa_layout, fmtl->bpb, + surf->samples, + surf->row_pitch_B, + surf->array_pitch_el_rows, + start_x_offset_el, + start_y_offset_el, + start_z_offset_el, + start_array_slice, + subimage_extent_el, + start_tile_B, + end_tile_B, + &x_offset_el, + &y_offset_el, + &z_offset_el, + &array_slice); assert(*end_tile_B <= surf->size_B); } @@ -5325,6 +5302,72 @@ isl_tiling_get_intratile_offset_el(enum isl_tiling tiling, (uint64_t)x_offset_tl * tile_info.phys_extent_B.h * tile_info.phys_extent_B.w; } +void +isl_tiling_get_intratile_range_el(enum isl_tiling tiling, + enum isl_surf_dim dim, + enum isl_msaa_layout msaa_layout, + uint32_t bpb, + uint32_t samples, + uint32_t row_pitch_B, + uint32_t array_pitch_el_rows, + uint32_t total_x_offset_el, + uint32_t total_y_offset_el, + uint32_t total_z_offset_el, + uint32_t total_array_offset, + struct isl_extent4d total_extent_el, + uint64_t *start_offset_B, + uint64_t *end_offset_B, + uint32_t *x_offset_el, + uint32_t *y_offset_el, + uint32_t *z_offset_el, + uint32_t *array_offset) +{ + isl_tiling_get_intratile_offset_el(tiling, dim, + msaa_layout, bpb, + samples, + row_pitch_B, + array_pitch_el_rows, + total_x_offset_el, + total_y_offset_el, + total_z_offset_el, + total_array_offset, + start_offset_B, + x_offset_el, + y_offset_el, + z_offset_el, + array_offset); + + UNUSED uint32_t _x_offset_el, _y_offset_el, _z_offset_el, _array_slice; + isl_tiling_get_intratile_offset_el(tiling, dim, + msaa_layout, bpb, + samples, + row_pitch_B, + array_pitch_el_rows, + total_x_offset_el + total_extent_el.w - 1, + total_y_offset_el + total_extent_el.h - 1, + total_z_offset_el + total_extent_el.d - 1, + total_array_offset + total_extent_el.a - 1, + end_offset_B, + &_x_offset_el, + &_y_offset_el, + &_z_offset_el, + &_array_slice); + + if (tiling != ISL_TILING_LINEAR) { + struct isl_tile_info tile_info; + isl_tiling_get_info(tiling, dim, msaa_layout, bpb, samples, &tile_info); + + /* We want the range we return to be exclusive but the tile containing the + * last pixel (what we just calculated) is inclusive. Add one and round up + * to the tile size. + */ + *end_offset_B = ALIGN_NPOT(*end_offset_B + 1, tile_info.phys_extent_B.w * + tile_info.phys_extent_B.h); + } else { + *end_offset_B += bpb / 8; + } +} + uint64_t isl_surf_get_sampler_overfetch_size_B(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 1f00d4ec883..0352cf9be57 100644 --- a/src/intel/isl/isl.h +++ b/src/intel/isl/isl.h @@ -3311,6 +3311,139 @@ isl_tiling_get_intratile_offset_sa(enum isl_tiling tiling, *z_offset_sa *= fmtl->bd; } +/** + * Calculate the intratile extent of a slice of a surface, in elements. + * + * This function takes a coordinate and extent in global tile space and + * returns the byte offset to the specific range of tiles as well as the + * offset within those tiles to the given coordinate in tile space. The + * returned x/y/z/array offsets are guaranteed to lie within the first tile. + * + * :param tiling: |in| The tiling of the surface + * :param bpb: |in| The size of the surface format in bits per + * block + * :param array_pitch_el_rows: |in| The array pitch of the surface for flat 2D + * tilings such as ISL_TILING_Y0 + * :param total_x_offset_el: |in| The X offset in tile space, in elements + * :param total_y_offset_el: |in| The Y offset in tile space, in elements + * :param total_z_offset_el: |in| The Z offset in tile space, in elements + * :param total_array_offset: |in| The array offset in tile space + * :param total_extent_el: |in| The extent in tile space + * :param tile_start_B: |out| The returned byte offset to the start of + * the first tile + * :param tile_end_B: |out| The returned byte offset to the end of + * the last tile + * :param x_offset_el: |out| The X offset within the tile, in elements + * :param y_offset_el: |out| The Y offset within the tile, in elements + * :param z_offset_el: |out| The Z offset within the tile, in elements + * :param array_offset: |out| The array offset within the tile + */ +void +isl_tiling_get_intratile_range_el(enum isl_tiling tiling, + enum isl_surf_dim dim, + enum isl_msaa_layout msaa_layout, + uint32_t bpb, + uint32_t samples, + uint32_t row_pitch_B, + uint32_t array_pitch_el_rows, + uint32_t total_x_offset_el, + uint32_t total_y_offset_el, + uint32_t total_z_offset_el, + uint32_t total_array_offset, + struct isl_extent4d total_extent_el, + uint64_t *tile_start_B, + uint64_t *tile_end_B, + uint32_t *x_offset_el, + uint32_t *y_offset_el, + uint32_t *z_offset_el, + uint32_t *array_offset); + +/** + * Calculate the intratile extent of a slice of a surface, in samples. + * + * This function takes a coordinate and extent in global tile space and + * returns the byte offset to the specific range of tiles as well as the + * offset within those tiles to the given coordinate in tile space. The + * returned x/y/z/array offsets are guaranteed to lie within the first tile. + * + * :param tiling: |in| The tiling of the surface + * :param bpb: |in| The size of the surface format in bits per + * block + * :param array_pitch_el_rows: |in| The array pitch of the surface for flat 2D + * tilings such as ISL_TILING_Y0 + * :param total_x_offset_sa: |in| The X offset in tile space, in samples + * :param total_y_offset_sa: |in| The Y offset in tile space, in samples + * :param total_z_offset_sa: |in| The Z offset in tile space, in samples + * :param total_array_offset: |in| The array offset in tile space + * :param total_extent_sa: |in| The extent in tile space + * :param tile_start_B: |out| The returned byte offset to the start of + * the first tile + * :param tile_end_B: |out| The returned byte offset to the end of + * the last tile + * :param x_offset_sa: |out| The X offset within the tile, in samples + * :param y_offset_sa: |out| The Y offset within the tile, in samples + * :param z_offset_sa: |out| The Z offset within the tile, in samples + * :param array_offset: |out| The array offset within the tile + */ +static inline void +isl_tiling_get_intratile_range_sa(enum isl_tiling tiling, + enum isl_surf_dim dim, + enum isl_msaa_layout msaa_layout, + enum isl_format format, + uint32_t samples, + uint32_t row_pitch_B, + uint32_t array_pitch_el_rows, + uint32_t total_x_offset_sa, + uint32_t total_y_offset_sa, + uint32_t total_z_offset_sa, + uint32_t total_array_offset, + struct isl_extent4d total_extent_sa, + uint64_t *tile_start_B, + uint64_t *tile_end_B, + uint32_t *x_offset_sa, + uint32_t *y_offset_sa, + uint32_t *z_offset_sa, + uint32_t *array_offset) +{ + const struct isl_format_layout *fmtl = isl_format_get_layout(format); + + /* For computing the intratile offsets, we actually want a strange unit + * which is samples for multisampled surfaces but elements for compressed + * surfaces. + */ + assert(total_x_offset_sa % fmtl->bw == 0); + assert(total_y_offset_sa % fmtl->bh == 0); + assert(total_z_offset_sa % fmtl->bd == 0); + assert(total_extent_sa.w % fmtl->bw == 0); + assert(total_extent_sa.h % fmtl->bh == 0); + assert(total_extent_sa.d % fmtl->bd == 0); + const uint32_t total_x_offset_el = total_x_offset_sa / fmtl->bw; + const uint32_t total_y_offset_el = total_y_offset_sa / fmtl->bh; + const uint32_t total_z_offset_el = total_z_offset_sa / fmtl->bd; + const struct isl_extent4d total_extent_el = { + .w = total_extent_sa.w / fmtl->bw, + .h = total_extent_sa.h / fmtl->bh, + .d = total_extent_sa.d / fmtl->bd, + .a = total_extent_sa.a + }; + + isl_tiling_get_intratile_range_el(tiling, dim, msaa_layout, fmtl->bpb, + samples, row_pitch_B, + array_pitch_el_rows, + total_x_offset_el, + total_y_offset_el, + total_z_offset_el, + total_array_offset, + total_extent_el, + tile_start_B, + tile_end_B, + x_offset_sa, y_offset_sa, + z_offset_sa, array_offset); + *x_offset_sa *= fmtl->bw; + *y_offset_sa *= fmtl->bh; + *z_offset_sa *= fmtl->bd; +} + /** * Calculates the size of a sampling engine surface, including the maximum * number of extra padding bytes that could be fetched due to caching.