Module: Mesa Branch: main Commit: d13c81a2c3bfe9a81c6310d393add7fd0e53b11c URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=d13c81a2c3bfe9a81c6310d393add7fd0e53b11c
Author: Francisco Jerez <curroje...@riseup.net> Date: Fri Sep 29 14:14:54 2023 -0700 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.landwer...@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25493> --- src/gallium/drivers/iris/iris_state.c | 93 +++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 28e293e79ec..c05324422de 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -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_*