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@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11235>
This commit is contained in:
committed by
Marge Bot
parent
5066839ffd
commit
2ccdd639c2
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user