iris/xehp: Implement TBIMR tile pass setup and pipeline bandwidth estimation.

This sets up the basic parameters needed for tiled rendering based on
a back-of-the-envelope estimate of the amount of memory used by the
pixel pipeline during the tile pass.  The actual cache footprint of a
tile can vary wildly based on runtime factors which aren't easily
predictable based on static analysis, so this is only intended to
provide a rough approximation within the right order of magnitude.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25493>
This commit is contained in:
Francisco Jerez 2023-09-29 14:14:54 -07:00
parent 694d64188b
commit d13c81a2c3

View file

@ -112,6 +112,7 @@
#include "intel/common/intel_genX_state.h"
#include "intel/common/intel_guardband.h"
#include "intel/common/intel_pixel_hash.h"
#include "intel/common/intel_tiled_render.h"
/**
* Statically assert that PIPE_* enums match the hardware packets.
@ -6338,6 +6339,79 @@ genX(emit_depth_state_workarounds)(struct iris_context *ice,
#endif
}
/* Calculate TBIMR tiling parameters adequate for the current pipeline
* setup. Return true if TBIMR should be enabled.
*/
UNUSED static bool
calculate_tile_dimensions(struct iris_context *ice,
unsigned *tile_width, unsigned *tile_height)
{
struct iris_screen *screen = (void *)ice->ctx.screen;
const struct intel_device_info *devinfo = screen->devinfo;
/* Perform a rough calculation of the tile cache footprint of the
* pixel pipeline, approximating it as the sum of the amount of
* memory used per pixel by every render target, depth, stencil and
* auxiliary surfaces bound to the pipeline.
*/
unsigned pixel_size = 0;
struct pipe_framebuffer_state *cso = &ice->state.framebuffer;
for (unsigned i = 0; i < cso->nr_cbufs; i++) {
const struct iris_surface *surf = (void *)cso->cbufs[i];
if (surf) {
const struct iris_resource *res = (void *)surf->base.texture;
pixel_size += intel_calculate_surface_pixel_size(&res->surf);
/* XXX - Pessimistic, in some cases it might be helpful to neglect
* aux surface traffic.
*/
if (ice->state.draw_aux_usage[i]) {
pixel_size += intel_calculate_surface_pixel_size(&res->aux.surf);
pixel_size += intel_calculate_surface_pixel_size(&res->aux.extra_aux.surf);
}
}
}
if (cso->zsbuf) {
struct iris_resource *zres;
struct iris_resource *sres;
iris_get_depth_stencil_resources(cso->zsbuf->texture, &zres, &sres);
if (zres) {
pixel_size += intel_calculate_surface_pixel_size(&zres->surf);
/* XXX - Pessimistic, in some cases it might be helpful to neglect
* aux surface traffic.
*/
if (iris_resource_level_has_hiz(devinfo, zres, cso->zsbuf->u.tex.level)) {
pixel_size += intel_calculate_surface_pixel_size(&zres->aux.surf);
pixel_size += intel_calculate_surface_pixel_size(&zres->aux.extra_aux.surf);
}
}
if (sres) {
pixel_size += intel_calculate_surface_pixel_size(&sres->surf);
}
}
/* Compute a tile layout that allows reasonable utilization of the
* tile cache based on the per-pixel cache footprint estimated
* above.
*/
intel_calculate_tile_dimensions(devinfo, screen->l3_config_3d,
32, 32, cso->width, cso->height, pixel_size,
tile_width, tile_height);
/* Perform TBIMR tile passes only if the framebuffer covers more
* than a single tile.
*/
return *tile_width < cso->width || *tile_height < cso->height;
}
static void
iris_preemption_streamout_wa(struct iris_context *ice,
struct iris_batch *batch,
@ -6662,6 +6736,25 @@ iris_upload_dirty_render_state(struct iris_context *ice,
}
}
#if GFX_VERx10 == 125
if (dirty & (IRIS_DIRTY_RENDER_BUFFER | IRIS_DIRTY_DEPTH_BUFFER)) {
struct pipe_framebuffer_state *cso_fb = &ice->state.framebuffer;
unsigned tile_width, tile_height;
ice->state.use_tbimr = batch->screen->driconf.enable_tbimr &&
calculate_tile_dimensions(ice, &tile_width, &tile_height);
if (ice->state.use_tbimr) {
iris_emit_cmd(batch, GENX(3DSTATE_TBIMR_TILE_PASS_INFO), tbimr) {
tbimr.TileRectangleHeight = tile_height;
tbimr.TileRectangleWidth = tile_width;
tbimr.VerticalTileCount = DIV_ROUND_UP(cso_fb->height, tile_height);
tbimr.HorizontalTileCount = DIV_ROUND_UP(cso_fb->width, tile_width);
}
}
}
#endif
/* Wa_1604061319
*
* 3DSTATE_CONSTANT_* needs to be programmed before BTP_*