From 5de4209f91c466af6a28fee9c80c398a8ed9b95d Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Tue, 11 Jul 2017 14:27:25 -0700 Subject: [PATCH] intel/isl: Add a helper to get a subimage surface We already have a helper for doing this in BLORP, this just moves the logic into ISL where we can share it with other components. Reviewed-by: Lionel Landwerlin --- src/intel/blorp/blorp_blit.c | 42 +++++++++++------------------------- src/intel/isl/isl.c | 41 +++++++++++++++++++++++++++++++++++ src/intel/isl/isl.h | 23 ++++++++++++++++++++ 3 files changed, 76 insertions(+), 30 deletions(-) diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c index 91d2a227949..ed005163733 100644 --- a/src/intel/blorp/blorp_blit.c +++ b/src/intel/blorp/blorp_blit.c @@ -1406,42 +1406,24 @@ blorp_surf_convert_to_single_slice(const struct isl_device *isl_dev, layer = info->view.base_array_layer; uint32_t byte_offset; - isl_surf_get_image_offset_B_tile_sa(&info->surf, - info->view.base_level, layer, z, - &byte_offset, - &info->tile_x_sa, &info->tile_y_sa); + isl_surf_get_image_surf(isl_dev, &info->surf, + info->view.base_level, layer, z, + &info->surf, + &byte_offset, &info->tile_x_sa, &info->tile_y_sa); info->addr.offset += byte_offset; - const uint32_t slice_width_px = - minify(info->surf.logical_level0_px.width, info->view.base_level); - const uint32_t slice_height_px = - minify(info->surf.logical_level0_px.height, info->view.base_level); - uint32_t tile_x_px, tile_y_px; surf_get_intratile_offset_px(info, &tile_x_px, &tile_y_px); - /* Even for cube maps there will be only single face, therefore drop the - * corresponding flag if present. + /* Instead of using the X/Y Offset fields in RENDER_SURFACE_STATE, we place + * the image at the tile boundary and offset our sampling or rendering. + * For this reason, we need to grow the image by the offset to ensure that + * the hardware doesn't think we've gone past the edge. */ - const isl_surf_usage_flags_t without_cube_map_flag = - info->surf.usage & (~ISL_SURF_USAGE_CUBE_BIT); - - struct isl_surf_init_info init_info = { - .dim = ISL_SURF_DIM_2D, - .format = info->surf.format, - .width = slice_width_px + tile_x_px, - .height = slice_height_px + tile_y_px, - .depth = 1, - .levels = 1, - .array_len = 1, - .samples = info->surf.samples, - .row_pitch = info->surf.row_pitch, - .usage = without_cube_map_flag, - .tiling_flags = 1 << info->surf.tiling, - }; - - ok = isl_surf_init_s(isl_dev, &info->surf, &init_info); - assert(ok); + info->surf.logical_level0_px.w += tile_x_px; + info->surf.logical_level0_px.h += tile_y_px; + info->surf.phys_level0_sa.w += info->tile_x_sa; + info->surf.phys_level0_sa.h += info->tile_y_sa; /* The view is also different now. */ info->view.base_level = 0; diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c index fba40caff41..5e3d279b0b6 100644 --- a/src/intel/isl/isl.c +++ b/src/intel/isl/isl.c @@ -2317,6 +2317,47 @@ isl_surf_get_image_offset_B_tile_sa(const struct isl_surf *surf, } } +void +isl_surf_get_image_surf(const struct isl_device *dev, + const struct isl_surf *surf, + uint32_t level, + uint32_t logical_array_layer, + uint32_t logical_z_offset_px, + struct isl_surf *image_surf, + uint32_t *offset_B, + uint32_t *x_offset_sa, + uint32_t *y_offset_sa) +{ + isl_surf_get_image_offset_B_tile_sa(surf, + level, + logical_array_layer, + logical_z_offset_px, + offset_B, + x_offset_sa, + y_offset_sa); + + /* Even for cube maps there will be only single face, therefore drop the + * corresponding flag if present. + */ + const isl_surf_usage_flags_t usage = + surf->usage & (~ISL_SURF_USAGE_CUBE_BIT); + + bool ok UNUSED; + ok = isl_surf_init(dev, image_surf, + .dim = ISL_SURF_DIM_2D, + .format = surf->format, + .width = isl_minify(surf->logical_level0_px.w, level), + .height = isl_minify(surf->logical_level0_px.h, level), + .depth = 1, + .levels = 1, + .array_len = 1, + .samples = surf->samples, + .row_pitch = surf->row_pitch, + .usage = usage, + .tiling_flags = (1 << surf->tiling)); + assert(ok); +} + void isl_tiling_get_intratile_offset_el(enum isl_tiling tiling, uint32_t bpb, diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h index 1e5b8689542..dafe952298e 100644 --- a/src/intel/isl/isl.h +++ b/src/intel/isl/isl.h @@ -1841,6 +1841,29 @@ isl_surf_get_image_offset_B_tile_sa(const struct isl_surf *surf, uint32_t *x_offset_sa, uint32_t *y_offset_sa); +/** + * Create an isl_surf that represents a particular subimage in the surface. + * + * The newly created surface will have a single miplevel and array slice. The + * surface lives at the returned byte and intratile offsets, in samples. + * + * It is safe to call this function with surf == image_surf. + * + * @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_surf(const struct isl_device *dev, + const struct isl_surf *surf, + uint32_t level, + uint32_t logical_array_layer, + uint32_t logical_z_offset_px, + struct isl_surf *image_surf, + uint32_t *offset_B, + uint32_t *x_offset_sa, + uint32_t *y_offset_sa); + /** * @brief Calculate the intratile offsets to a surface. * -- 2.30.2