mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2024-11-27 12:14:10 +08:00
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:
parent
72bc38cfc5
commit
5de4209f91
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user