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:
@@ -112,6 +112,7 @@
|
|||||||
#include "intel/common/intel_genX_state.h"
|
#include "intel/common/intel_genX_state.h"
|
||||||
#include "intel/common/intel_guardband.h"
|
#include "intel/common/intel_guardband.h"
|
||||||
#include "intel/common/intel_pixel_hash.h"
|
#include "intel/common/intel_pixel_hash.h"
|
||||||
|
#include "intel/common/intel_tiled_render.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Statically assert that PIPE_* enums match the hardware packets.
|
* Statically assert that PIPE_* enums match the hardware packets.
|
||||||
@@ -6338,6 +6339,79 @@ genX(emit_depth_state_workarounds)(struct iris_context *ice,
|
|||||||
#endif
|
#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
|
static void
|
||||||
iris_preemption_streamout_wa(struct iris_context *ice,
|
iris_preemption_streamout_wa(struct iris_context *ice,
|
||||||
struct iris_batch *batch,
|
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
|
/* Wa_1604061319
|
||||||
*
|
*
|
||||||
* 3DSTATE_CONSTANT_* needs to be programmed before BTP_*
|
* 3DSTATE_CONSTANT_* needs to be programmed before BTP_*
|
||||||
|
|||||||
Reference in New Issue
Block a user