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 }