mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 02:28:10 +02:00
intel/blorp: Add blorp_surf_convert_to_single_level_tile()
Convert a Tile64/Yf/Ys surface to a single level or a single miptail. Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39974>
This commit is contained in:
parent
9351dbfb25
commit
73796c7245
1 changed files with 127 additions and 0 deletions
|
|
@ -1717,6 +1717,133 @@ blorp_surf_convert_to_single_slice(const struct isl_device *isl_dev,
|
||||||
info->z_offset = 0;
|
info->z_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convert a Tile64/Yf/Ys surface to a single level or a single miptail. */
|
||||||
|
static void
|
||||||
|
blorp_surf_convert_to_single_level_tile(const struct isl_device *isl_dev,
|
||||||
|
struct blorp_surface_info *info,
|
||||||
|
bool with_scaling)
|
||||||
|
{
|
||||||
|
if (!isl_tiling_is_64(info->surf.tiling) &&
|
||||||
|
!isl_tiling_is_std_y(info->surf.tiling)) {
|
||||||
|
UNREACHABLE("Use blorp_surf_convert_to_single_slice() instead");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the requested level is not part of the miptail, we just offset to the
|
||||||
|
* requested level. Because we're using standard tilings and aren't in the
|
||||||
|
* miptail, arrays and 3D textures should just work so long as we have the
|
||||||
|
* right array stride in the end.
|
||||||
|
*
|
||||||
|
* If the requested level is in the miptail, we instead offset to the base
|
||||||
|
* of the miptail. Because offsets into the miptail are fixed by the
|
||||||
|
* tiling and don't depend on the actual size of the image, we can set the
|
||||||
|
* level in the view to offset into the miptail regardless of the fact
|
||||||
|
* minification yields different results for the unscaled and scaled
|
||||||
|
* surface.
|
||||||
|
*/
|
||||||
|
const struct isl_surf *surf = &info->surf;
|
||||||
|
const struct isl_view *view = &info->view;
|
||||||
|
const uint32_t base_level =
|
||||||
|
MIN2(view->base_level, surf->miptail_start_level);
|
||||||
|
assert(view->levels == 1);
|
||||||
|
|
||||||
|
uint64_t offset_B;
|
||||||
|
uint32_t x_offset_el;
|
||||||
|
uint32_t y_offset_el;
|
||||||
|
isl_surf_get_image_offset_B_tile_el(surf, base_level, 0, 0,
|
||||||
|
&offset_B, &x_offset_el, &y_offset_el);
|
||||||
|
|
||||||
|
/* Tile64, Ys and Yf should have no intratile X or Y offset */
|
||||||
|
assert(x_offset_el == 0 && y_offset_el == 0);
|
||||||
|
assert(info->tile_x_sa == 0 && info->tile_y_sa == 0);
|
||||||
|
info->addr.offset += offset_B;
|
||||||
|
|
||||||
|
/* Save off the array pitch */
|
||||||
|
const uint32_t array_pitch_el_rows = surf->array_pitch_el_rows;
|
||||||
|
|
||||||
|
const struct isl_format_layout *surf_fmtl =
|
||||||
|
isl_format_get_layout(surf->format);
|
||||||
|
const struct isl_format_layout *view_fmtl =
|
||||||
|
isl_format_get_layout(view->format);
|
||||||
|
assert(isl_format_block_is_1x1x1(view->format));
|
||||||
|
assert(isl_format_block_is_1x1x1(surf->format));
|
||||||
|
|
||||||
|
const uint32_t view_height_el =
|
||||||
|
u_minify(surf->logical_level0_px.height, view->base_level);
|
||||||
|
const uint32_t view_depth_el =
|
||||||
|
u_minify(surf->logical_level0_px.depth, view->base_level);
|
||||||
|
uint32_t view_width_el =
|
||||||
|
u_minify(surf->logical_level0_px.width, view->base_level);
|
||||||
|
|
||||||
|
if (with_scaling) {
|
||||||
|
const int scale = view_fmtl->bpb / surf_fmtl->bpb;
|
||||||
|
view_width_el = DIV_ROUND_UP(view_width_el, scale);
|
||||||
|
} else {
|
||||||
|
assert(view_fmtl->bpb == surf_fmtl->bpb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We need to compute the size of the scaled surface we will create. If
|
||||||
|
* we're not in the miptail, it is just the view size in surface
|
||||||
|
* elements. If we are in a miptail, we need a size that will minify to
|
||||||
|
* the view size in surface elements. This may not be the same as the
|
||||||
|
* size of base_level, but that's not a problem. Slot offsets are fixed
|
||||||
|
* in HW (see the tables used in isl_get_miptail_level_offset_el).
|
||||||
|
*/
|
||||||
|
const uint32_t scaled_level = view->base_level - base_level;
|
||||||
|
|
||||||
|
/* The > 1 check is here to prevent a change in the surface's overall
|
||||||
|
* dimension (e.g. 2D->3D).
|
||||||
|
*
|
||||||
|
* Also having a base_level dimension = 1 doesn´t mean the HW will
|
||||||
|
* ignore higher mip level. Once the dimension has reached 1, it'll stay
|
||||||
|
* at 1 in the higher mip levels.
|
||||||
|
*/
|
||||||
|
struct isl_extent3d scaled_surf_extent_el = {
|
||||||
|
.w = view_width_el > 1 ? view_width_el << scaled_level : 1,
|
||||||
|
.h = view_height_el > 1 ? view_height_el << scaled_level : 1,
|
||||||
|
.d = view_depth_el > 1 ? view_depth_el << scaled_level : 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
isl_surf_usage_flags_t usage = surf->usage;
|
||||||
|
/* CCS-enabled surfaces can have different layout requirements than
|
||||||
|
* surfaces without CCS support. Disable CCS support if the original
|
||||||
|
* surface lacked it.
|
||||||
|
*/
|
||||||
|
if (info->aux_usage == ISL_AUX_USAGE_NONE)
|
||||||
|
usage |= ISL_SURF_USAGE_DISABLE_AUX_BIT;
|
||||||
|
|
||||||
|
struct isl_surf *scaled_surf = &info->surf;
|
||||||
|
struct isl_view *scaled_view = &info->view;
|
||||||
|
bool ok UNUSED;
|
||||||
|
ok = isl_surf_init(isl_dev, scaled_surf,
|
||||||
|
.dim = surf->dim,
|
||||||
|
.format = view->format,
|
||||||
|
.width = scaled_surf_extent_el.width,
|
||||||
|
.height = scaled_surf_extent_el.height,
|
||||||
|
.depth = scaled_surf_extent_el.depth,
|
||||||
|
.levels = scaled_level + 1,
|
||||||
|
.array_len = surf->logical_level0_px.array_len,
|
||||||
|
.samples = surf->samples,
|
||||||
|
.min_miptail_start_level =
|
||||||
|
(int) (view->base_level < surf->miptail_start_level),
|
||||||
|
.row_pitch_B = surf->row_pitch_B,
|
||||||
|
.usage = usage,
|
||||||
|
.tiling_flags = (1u << surf->tiling));
|
||||||
|
assert(ok);
|
||||||
|
|
||||||
|
/* Use the array pitch from the original surface. This way 2D arrays and
|
||||||
|
* 3D textures should work properly, just with one LOD.
|
||||||
|
*/
|
||||||
|
assert(scaled_surf->array_pitch_el_rows <= array_pitch_el_rows);
|
||||||
|
scaled_surf->array_pitch_el_rows = array_pitch_el_rows;
|
||||||
|
|
||||||
|
/* The newly created image represents only the one miplevel so we need to
|
||||||
|
* adjust the view accordingly. Because we offset it to miplevel but used
|
||||||
|
* a Z and array slice of 0, the array range can be left alone.
|
||||||
|
*/
|
||||||
|
*scaled_view = *view;
|
||||||
|
scaled_view->base_level -= base_level;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
blorp_surf_fake_interleaved_msaa(const struct isl_device *isl_dev,
|
blorp_surf_fake_interleaved_msaa(const struct isl_device *isl_dev,
|
||||||
struct blorp_surface_info *info)
|
struct blorp_surface_info *info)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue