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_*

Reply via email to