Mesa (main): iris: Use isl_surf_get_image_surf instead of hand-rolling it
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Jun 9 23:44:04 UTC 2021
Module: Mesa
Branch: main
Commit: 2ccdd639c2459cb3738d5ffa0ebcca8cfa0e1532
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=2ccdd639c2459cb3738d5ffa0ebcca8cfa0e1532
Author: Jason Ekstrand <jason at jlekstrand.net>
Date: Thu Jun 3 17:49:02 2021 -0500
iris: Use isl_surf_get_image_surf instead of hand-rolling it
For the 3D RT read case on BDW, we can use the ISL helper. For the 1D
array case, we don't actually need to flatten; we can just smash it to a
2D array surface because the layout for 1D and 2D is the same on BDW.
Reviewed-by: Nanley Chery <nanley.g.chery at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11235>
---
src/gallium/drivers/iris/iris_resource.c | 88 -------------------------
src/gallium/drivers/iris/iris_resource.h | 3 -
src/gallium/drivers/iris/iris_state.c | 108 +++++++++++--------------------
3 files changed, 37 insertions(+), 162 deletions(-)
diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c
index 0d1f493909e..2dfab91cd60 100644
--- a/src/gallium/drivers/iris/iris_resource.c
+++ b/src/gallium/drivers/iris/iris_resource.c
@@ -390,35 +390,6 @@ iris_get_depth_stencil_resources(struct pipe_resource *res,
}
}
-enum isl_dim_layout
-iris_get_isl_dim_layout(const struct intel_device_info *devinfo,
- enum isl_tiling tiling,
- enum pipe_texture_target target)
-{
- switch (target) {
- case PIPE_TEXTURE_1D:
- case PIPE_TEXTURE_1D_ARRAY:
- return (devinfo->ver >= 9 && tiling == ISL_TILING_LINEAR ?
- ISL_DIM_LAYOUT_GFX9_1D : ISL_DIM_LAYOUT_GFX4_2D);
-
- case PIPE_TEXTURE_2D:
- case PIPE_TEXTURE_2D_ARRAY:
- case PIPE_TEXTURE_RECT:
- case PIPE_TEXTURE_CUBE:
- case PIPE_TEXTURE_CUBE_ARRAY:
- return ISL_DIM_LAYOUT_GFX4_2D;
-
- case PIPE_TEXTURE_3D:
- return (devinfo->ver >= 9 ?
- ISL_DIM_LAYOUT_GFX4_2D : ISL_DIM_LAYOUT_GFX4_3D);
-
- case PIPE_MAX_TEXTURE_TYPES:
- case PIPE_BUFFER:
- break;
- }
- unreachable("invalid texture type");
-}
-
void
iris_resource_disable_aux(struct iris_resource *res)
{
@@ -1668,65 +1639,6 @@ get_image_offset_el(const struct isl_surf *surf, unsigned level, unsigned z,
}
}
-/**
- * Compute the offset (in bytes) from the start of the BO to the given x
- * and y coordinate. For tiled BOs, caller must ensure that x and y are
- * multiples of the tile size.
- */
-static uint32_t
-iris_resource_get_aligned_offset(const struct iris_resource *res,
- uint32_t x, uint32_t y)
-{
- const struct isl_format_layout *fmtl = isl_format_get_layout(res->surf.format);
- unsigned cpp = fmtl->bpb / 8;
- uint32_t pitch = res->surf.row_pitch_B;
-
- switch (res->surf.tiling) {
- default:
- unreachable("not reached");
- case ISL_TILING_LINEAR:
- return y * pitch + x * cpp;
- case ISL_TILING_X:
- assert((x % (512 / cpp)) == 0);
- assert((y % 8) == 0);
- return y * pitch + x / (512 / cpp) * 4096;
- case ISL_TILING_Y0:
- assert((x % (128 / cpp)) == 0);
- assert((y % 32) == 0);
- return y * pitch + x / (128 / cpp) * 4096;
- }
-}
-
-/**
- * Rendering with tiled buffers requires that the base address of the buffer
- * be aligned to a page boundary. For renderbuffers, and sometimes with
- * textures, we may want the surface to point at a texture image level that
- * isn't at a page boundary.
- *
- * This function returns an appropriately-aligned base offset
- * according to the tiling restrictions, plus any required x/y offset
- * from there.
- */
-uint32_t
-iris_resource_get_tile_offsets(const struct iris_resource *res,
- uint32_t level, uint32_t z,
- uint32_t *tile_x, uint32_t *tile_y)
-{
- uint32_t x, y;
- uint32_t mask_x, mask_y;
-
- const struct isl_format_layout *fmtl = isl_format_get_layout(res->surf.format);
- const unsigned cpp = fmtl->bpb / 8;
-
- isl_get_tile_masks(res->surf.tiling, cpp, &mask_x, &mask_y);
- get_image_offset_el(&res->surf, level, z, &x, &y);
-
- *tile_x = x & mask_x;
- *tile_y = y & mask_y;
-
- return iris_resource_get_aligned_offset(res, x & ~mask_x, y & ~mask_y);
-}
-
/**
* Get pointer offset into stencil buffer.
*
diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h
index 967ec036fd5..7d5720e5cc5 100644
--- a/src/gallium/drivers/iris/iris_resource.h
+++ b/src/gallium/drivers/iris/iris_resource.h
@@ -491,9 +491,6 @@ target_to_isl_surf_dim(enum pipe_texture_target target)
unreachable("invalid texture type");
}
-uint32_t iris_resource_get_tile_offsets(const struct iris_resource *res,
- uint32_t level, uint32_t z,
- uint32_t *tile_x, uint32_t *tile_y);
enum isl_aux_usage iris_resource_texture_aux_usage(struct iris_context *ice,
const struct iris_resource *res,
enum isl_format view_fmt);
diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c
index 67929dd71bd..abb315ebdb4 100644
--- a/src/gallium/drivers/iris/iris_state.c
+++ b/src/gallium/drivers/iris/iris_state.c
@@ -2307,66 +2307,6 @@ update_surface_state_addrs(struct u_upload_mgr *mgr,
return true;
}
-#if GFX_VER == 8
-/**
- * Return an ISL surface for use with non-coherent render target reads.
- *
- * In a few complex cases, we can't use the SURFACE_STATE for normal render
- * target writes. We need to make a separate one for sampling which refers
- * to the single slice of the texture being read.
- */
-static void
-get_rt_read_isl_surf(const struct intel_device_info *devinfo,
- struct iris_resource *res,
- enum pipe_texture_target target,
- struct isl_view *view,
- uint32_t *offset_to_tile,
- uint32_t *tile_x_sa,
- uint32_t *tile_y_sa,
- struct isl_surf *surf)
-{
- *surf = res->surf;
-
- const enum isl_dim_layout dim_layout =
- iris_get_isl_dim_layout(devinfo, res->surf.tiling, target);
-
- surf->dim = target_to_isl_surf_dim(target);
-
- if (surf->dim_layout == dim_layout)
- return;
-
- /* The layout of the specified texture target is not compatible with the
- * actual layout of the miptree structure in memory -- You're entering
- * dangerous territory, this can only possibly work if you only intended
- * to access a single level and slice of the texture, and the hardware
- * supports the tile offset feature in order to allow non-tile-aligned
- * base offsets, since we'll have to point the hardware to the first
- * texel of the level instead of relying on the usual base level/layer
- * controls.
- */
- assert(view->levels == 1 && view->array_len == 1);
- assert(*tile_x_sa == 0 && *tile_y_sa == 0);
-
- *offset_to_tile = iris_resource_get_tile_offsets(res, view->base_level,
- view->base_array_layer,
- tile_x_sa, tile_y_sa);
- const unsigned l = view->base_level;
-
- surf->logical_level0_px.width = minify(surf->logical_level0_px.width, l);
- surf->logical_level0_px.height = surf->dim <= ISL_SURF_DIM_1D ? 1 :
- minify(surf->logical_level0_px.height, l);
- surf->logical_level0_px.depth = surf->dim <= ISL_SURF_DIM_2D ? 1 :
- minify(surf->logical_level0_px.depth, l);
-
- surf->logical_level0_px.array_len = 1;
- surf->levels = 1;
- surf->dim_layout = dim_layout;
-
- view->base_level = 0;
- view->base_array_layer = 0;
-}
-#endif
-
static void
fill_surface_state(struct isl_device *isl_dev,
void *map,
@@ -2577,11 +2517,6 @@ iris_create_surface(struct pipe_context *ctx,
};
#if GFX_VER == 8
- enum pipe_texture_target target = (tex->target == PIPE_TEXTURE_3D &&
- array_len == 1) ? PIPE_TEXTURE_2D :
- tex->target == PIPE_TEXTURE_1D_ARRAY ?
- PIPE_TEXTURE_2D_ARRAY : tex->target;
-
struct isl_view *read_view = &surf->read_view;
*read_view = (struct isl_view) {
.format = fmt.fmt,
@@ -2592,6 +2527,39 @@ iris_create_surface(struct pipe_context *ctx,
.swizzle = ISL_SWIZZLE_IDENTITY,
.usage = ISL_SURF_USAGE_TEXTURE_BIT,
};
+
+ struct isl_surf read_surf = res->surf;
+ uint32_t read_surf_offset_B = 0;
+ uint32_t read_surf_tile_x_sa = 0, read_surf_tile_y_sa = 0;
+ if (tex->target == PIPE_TEXTURE_3D && array_len == 1) {
+ /* The minimum array element field of the surface state structure is
+ * ignored by the sampler unit for 3D textures on some hardware. If the
+ * render buffer is a single slice of a 3D texture, create a 2D texture
+ * covering that slice.
+ *
+ * TODO: This only handles the case where we're rendering to a single
+ * slice of an array texture. If we have layered rendering combined
+ * with non-coherent FB fetch and a non-zero base_array_layer, then
+ * we're going to run into problems.
+ *
+ * See https://gitlab.freedesktop.org/mesa/mesa/-/issues/4904
+ */
+ isl_surf_get_image_surf(&screen->isl_dev, &res->surf,
+ read_view->base_level,
+ 0, read_view->base_array_layer,
+ &read_surf, &read_surf_offset_B,
+ &read_surf_tile_x_sa, &read_surf_tile_y_sa);
+ read_view->base_level = 0;
+ read_view->base_array_layer = 0;
+ assert(read_view->array_len == 1);
+ } else if (tex->target == PIPE_TEXTURE_1D_ARRAY) {
+ /* Convert 1D array textures to 2D arrays because shaders always provide
+ * the array index coordinate at the Z component to avoid recompiles
+ * when changing the texture target of the framebuffer.
+ */
+ assert(read_surf.dim_layout == ISL_DIM_LAYOUT_GFX4_2D);
+ read_surf.dim = ISL_SURF_DIM_2D;
+ }
#endif
surf->clear_color = res->aux.clear_color;
@@ -2628,12 +2596,10 @@ iris_create_surface(struct pipe_context *ctx,
map += SURFACE_STATE_ALIGNMENT;
#if GFX_VER == 8
- struct isl_surf surf;
- uint32_t offset_to_tile = 0, tile_x_sa = 0, tile_y_sa = 0;
- get_rt_read_isl_surf(devinfo, res, target, read_view,
- &offset_to_tile, &tile_x_sa, &tile_y_sa, &surf);
- fill_surface_state(&screen->isl_dev, map_read, res, &surf, read_view,
- aux_usage, offset_to_tile, tile_x_sa, tile_y_sa);
+ fill_surface_state(&screen->isl_dev, map_read, res,
+ &read_surf, read_view, aux_usage,
+ read_surf_offset_B,
+ read_surf_tile_x_sa, read_surf_tile_y_sa);
map_read += SURFACE_STATE_ALIGNMENT;
#endif
}
More information about the mesa-commit
mailing list