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 <lionel.g.landwerlin@intel.com>
This commit is contained in:
Jason Ekstrand 2017-07-11 14:27:25 -07:00
parent 72bc38cfc5
commit 5de4209f91
3 changed files with 76 additions and 30 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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.
*