intel/isl: Pull the uncompressed surface view code from anv
This adds a helper isl_surf_get_uncompressed_surf for creating a surface which provides an uncompressed view into a compressed surface. The code is basically a direct port of the uncompressed surface code from the Vulkan driver which, in turn, was a port from BLORP. Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11647>
This commit is contained in:
committed by
Marge Bot
parent
4bf764d53d
commit
8f281be0ba
@@ -2827,6 +2827,75 @@ isl_surf_get_image_surf(const struct isl_device *dev,
|
||||
assert(ok);
|
||||
}
|
||||
|
||||
void
|
||||
isl_surf_get_uncompressed_surf(const struct isl_device *dev,
|
||||
const struct isl_surf *surf,
|
||||
const struct isl_view *view,
|
||||
struct isl_surf *ucompr_surf,
|
||||
struct isl_view *ucompr_view,
|
||||
uint32_t *offset_B,
|
||||
uint32_t *x_offset_el,
|
||||
uint32_t *y_offset_el)
|
||||
{
|
||||
const struct isl_format_layout *fmtl =
|
||||
isl_format_get_layout(surf->format);
|
||||
|
||||
assert(fmtl->bw > 1 || fmtl->bh > 1 || fmtl->bd > 1);
|
||||
assert(isl_format_is_compressed(surf->format));
|
||||
assert(!isl_format_is_compressed(view->format));
|
||||
assert(isl_format_get_layout(view->format)->bpb == fmtl->bpb);
|
||||
assert(view->levels == 1);
|
||||
|
||||
const uint32_t view_width =
|
||||
isl_minify(surf->logical_level0_px.width, view->base_level);
|
||||
const uint32_t view_height =
|
||||
isl_minify(surf->logical_level0_px.height, view->base_level);
|
||||
|
||||
const uint32_t ucompr_width = isl_align_div_npot(view_width, fmtl->bw);
|
||||
const uint32_t ucompr_height = isl_align_div_npot(view_height, fmtl->bh);
|
||||
|
||||
/* Due to hardware restrictions with intratile offsets, we can only
|
||||
* handle a single slice.
|
||||
*/
|
||||
assert(view->array_len == 1);
|
||||
|
||||
uint32_t x_offset_sa, y_offset_sa;
|
||||
isl_surf_get_image_surf(dev, surf,
|
||||
view->base_level,
|
||||
surf->dim == ISL_SURF_DIM_3D ?
|
||||
0 : view->base_array_layer,
|
||||
surf->dim == ISL_SURF_DIM_3D ?
|
||||
view->base_array_layer : 0,
|
||||
ucompr_surf,
|
||||
offset_B, &x_offset_sa, &y_offset_sa);
|
||||
|
||||
ucompr_surf->format = view->format;
|
||||
|
||||
/* We're making an uncompressed view here. The image dimensions
|
||||
* need to be scaled down by the block size.
|
||||
*/
|
||||
assert(ucompr_surf->logical_level0_px.width == view_width);
|
||||
assert(ucompr_surf->logical_level0_px.height == view_height);
|
||||
assert(ucompr_surf->logical_level0_px.depth == 1);
|
||||
assert(ucompr_surf->logical_level0_px.array_len = 1);
|
||||
ucompr_surf->logical_level0_px.width = ucompr_width;
|
||||
ucompr_surf->logical_level0_px.height = ucompr_height;
|
||||
|
||||
assert(ucompr_surf->phys_level0_sa.depth == 1);
|
||||
assert(ucompr_surf->phys_level0_sa.array_len == 1);
|
||||
ucompr_surf->phys_level0_sa = isl_surf_get_phys_level0_el(surf);
|
||||
|
||||
*x_offset_el = isl_assert_div(x_offset_sa, fmtl->bw);
|
||||
*y_offset_el = isl_assert_div(y_offset_sa, fmtl->bh);
|
||||
|
||||
/* The newly created image represents the one subimage we're referencing
|
||||
* with this view so it only has one array slice and miplevel.
|
||||
*/
|
||||
*ucompr_view = *view;
|
||||
ucompr_view->base_array_layer = 0;
|
||||
ucompr_view->base_level = 0;
|
||||
}
|
||||
|
||||
void
|
||||
isl_tiling_get_intratile_offset_el(enum isl_tiling tiling,
|
||||
uint32_t bpb,
|
||||
|
||||
@@ -2645,6 +2645,35 @@ isl_surf_get_image_surf(const struct isl_device *dev,
|
||||
uint32_t *x_offset_sa,
|
||||
uint32_t *y_offset_sa);
|
||||
|
||||
/**
|
||||
* Create an isl_surf that is an uncompressed view of a compressed isl_surf
|
||||
*
|
||||
* The incoming surface must have a compressed format. The incoming view must
|
||||
* be a valid view for the given surface with the exception that it's format
|
||||
* is an umcompressed format with the same bpb as the surface format. The
|
||||
* incoming view must have isl_view::levels == 1.
|
||||
*
|
||||
* When the function returns, the resulting combination of uncompressed_surf
|
||||
* and uncompressed_view will be a valid view giving an uncompressed view of
|
||||
* the incoming surface. Depending on tiling, uncompressed_surf may have a
|
||||
* different isl_surf::dim from surf and uncompressed_view may or may not have
|
||||
* a zero base_array_layer. For legacy tiling (not Yf or Ys), an intratile
|
||||
* offset is returned in x_offset_sa and y_offset_sa. For standard Y tilings
|
||||
* (Yf and Ys), x_offset_sa and y_offset_sa will be set to zero.
|
||||
*
|
||||
* It is safe to call this function with surf == uncompressed_surf and
|
||||
* view == uncompressed_view.
|
||||
*/
|
||||
void
|
||||
isl_surf_get_uncompressed_surf(const struct isl_device *dev,
|
||||
const struct isl_surf *surf,
|
||||
const struct isl_view *view,
|
||||
struct isl_surf *uncompressed_surf,
|
||||
struct isl_view *uncompressed_view,
|
||||
uint32_t *offset_B,
|
||||
uint32_t *x_offset_el,
|
||||
uint32_t *y_offset_el);
|
||||
|
||||
/**
|
||||
* @brief Calculate the intratile offsets to a surface.
|
||||
*
|
||||
|
||||
@@ -2570,34 +2570,9 @@ anv_image_fill_surface_state(struct anv_device *device,
|
||||
assert(view.levels == 1);
|
||||
assert(view.array_len == 1);
|
||||
|
||||
isl_surf_get_image_surf(&device->isl_dev, isl_surf,
|
||||
view.base_level,
|
||||
surface->isl.dim == ISL_SURF_DIM_3D ?
|
||||
0 : view.base_array_layer,
|
||||
surface->isl.dim == ISL_SURF_DIM_3D ?
|
||||
view.base_array_layer : 0,
|
||||
&tmp_surf,
|
||||
&offset_B, &tile_x_sa, &tile_y_sa);
|
||||
|
||||
/* The newly created image represents the one subimage we're
|
||||
* referencing with this view so it only has one array slice and
|
||||
* miplevel.
|
||||
*/
|
||||
view.base_array_layer = 0;
|
||||
view.base_level = 0;
|
||||
|
||||
/* We're making an uncompressed view here. The image dimensions need
|
||||
* to be scaled down by the block size.
|
||||
*/
|
||||
const struct isl_format_layout *fmtl =
|
||||
isl_format_get_layout(surface->isl.format);
|
||||
tmp_surf.logical_level0_px =
|
||||
isl_surf_get_logical_level0_el(&tmp_surf);
|
||||
tmp_surf.phys_level0_sa = isl_surf_get_phys_level0_el(&tmp_surf);
|
||||
tmp_surf.format = view.format;
|
||||
tile_x_sa /= fmtl->bw;
|
||||
tile_y_sa /= fmtl->bh;
|
||||
|
||||
isl_surf_get_uncompressed_surf(&device->isl_dev, isl_surf, &view,
|
||||
&tmp_surf, &view,
|
||||
&offset_B, &tile_x_sa, &tile_y_sa);
|
||||
isl_surf = &tmp_surf;
|
||||
|
||||
if (device->info.ver <= 8) {
|
||||
|
||||
Reference in New Issue
Block a user