isl: avoid gfx version switch cases on the hot path
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Sun, 2 Oct 2022 16:20:30 +0000 (19:20 +0300)
committerMarge Bot <emma+marge@anholt.net>
Fri, 14 Oct 2022 23:03:16 +0000 (23:03 +0000)
Some of the surface state packing functions are called from the hot
path in Anv. We can use function pointers to avoid repeatedly going
through switch/case.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19050>

src/intel/isl/isl.c
src/intel/isl/isl.h
src/intel/isl/isl_emit_cpb.c
src/intel/isl/isl_emit_depth_stencil.c
src/intel/isl/isl_genX_priv.h
src/intel/isl/isl_priv.h
src/intel/isl/isl_surface_state.c

index 14a5349..5504c7d 100644 (file)
 #include "isl_gfx12.h"
 #include "isl_priv.h"
 
+isl_genX_declare_get_func(surf_fill_state_s)
+isl_genX_declare_get_func(buffer_fill_state_s)
+isl_genX_declare_get_func(emit_depth_stencil_hiz_s)
+isl_genX_declare_get_func(null_fill_state_s)
+isl_genX_declare_get_func(emit_cpb_control_s)
+
 void
 isl_memcpy_linear_to_tiled(uint32_t xt1, uint32_t xt2,
                            uint32_t yt1, uint32_t yt2,
@@ -315,6 +321,12 @@ isl_device_init(struct isl_device *dev,
       _3DSTATE_CPSIZE_CONTROL_BUFFER_SurfaceBaseAddress_start(info) / 8;
 
    isl_device_setup_mocs(dev);
+
+   dev->surf_fill_state_s = isl_surf_fill_state_s_get_func(dev);
+   dev->buffer_fill_state_s = isl_buffer_fill_state_s_get_func(dev);
+   dev->emit_depth_stencil_hiz_s = isl_emit_depth_stencil_hiz_s_get_func(dev);
+   dev->null_fill_state_s = isl_null_fill_state_s_get_func(dev);
+   dev->emit_cpb_control_s = isl_emit_cpb_control_s_get_func(dev);
 }
 
 /**
@@ -2410,98 +2422,6 @@ isl_surf_get_ccs_surf(const struct isl_device *dev,
       assert(!"Unknown hardware generation");      \
    }
 
-void
-isl_surf_fill_state_s(const struct isl_device *dev, void *state,
-                      const struct isl_surf_fill_state_info *restrict info)
-{
-#ifndef NDEBUG
-   isl_surf_usage_flags_t _base_usage =
-      info->view->usage & (ISL_SURF_USAGE_RENDER_TARGET_BIT |
-                           ISL_SURF_USAGE_TEXTURE_BIT |
-                           ISL_SURF_USAGE_STORAGE_BIT);
-   /* They may only specify one of the above bits at a time */
-   assert(__builtin_popcount(_base_usage) == 1);
-   /* The only other allowed bit is ISL_SURF_USAGE_CUBE_BIT */
-   assert((info->view->usage & ~ISL_SURF_USAGE_CUBE_BIT) == _base_usage);
-#endif
-
-   if (info->surf->dim == ISL_SURF_DIM_3D) {
-      assert(info->view->base_array_layer + info->view->array_len <=
-             info->surf->logical_level0_px.depth);
-   } else {
-      assert(info->view->base_array_layer + info->view->array_len <=
-             info->surf->logical_level0_px.array_len);
-   }
-
-   isl_genX_call(dev, surf_fill_state_s, dev, state, info);
-}
-
-void
-isl_buffer_fill_state_s(const struct isl_device *dev, void *state,
-                        const struct isl_buffer_fill_state_info *restrict info)
-{
-   isl_genX_call(dev, buffer_fill_state_s, dev, state, info);
-}
-
-void
-isl_null_fill_state_s(const struct isl_device *dev, void *state,
-                      const struct isl_null_fill_state_info *restrict info)
-{
-   isl_genX_call(dev, null_fill_state, dev, state, info);
-}
-
-void
-isl_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
-                             const struct isl_depth_stencil_hiz_emit_info *restrict info)
-{
-   if (info->depth_surf && info->stencil_surf) {
-      if (!dev->info->has_hiz_and_separate_stencil) {
-         assert(info->depth_surf == info->stencil_surf);
-         assert(info->depth_address == info->stencil_address);
-      }
-      assert(info->depth_surf->dim == info->stencil_surf->dim);
-   }
-
-   if (info->depth_surf) {
-      assert((info->depth_surf->usage & ISL_SURF_USAGE_DEPTH_BIT));
-      if (info->depth_surf->dim == ISL_SURF_DIM_3D) {
-         assert(info->view->base_array_layer + info->view->array_len <=
-                info->depth_surf->logical_level0_px.depth);
-      } else {
-         assert(info->view->base_array_layer + info->view->array_len <=
-                info->depth_surf->logical_level0_px.array_len);
-      }
-   }
-
-   if (info->stencil_surf) {
-      assert((info->stencil_surf->usage & ISL_SURF_USAGE_STENCIL_BIT));
-      if (info->stencil_surf->dim == ISL_SURF_DIM_3D) {
-         assert(info->view->base_array_layer + info->view->array_len <=
-                info->stencil_surf->logical_level0_px.depth);
-      } else {
-         assert(info->view->base_array_layer + info->view->array_len <=
-                info->stencil_surf->logical_level0_px.array_len);
-      }
-   }
-
-   isl_genX_call(dev, emit_depth_stencil_hiz_s, dev, batch, info);
-}
-
-void
-isl_emit_cpb_control_s(const struct isl_device *dev, void *batch,
-                       const struct isl_cpb_emit_info *restrict info)
-{
-   if (info->surf) {
-      assert((info->surf->usage & ISL_SURF_USAGE_CPB_BIT));
-      assert(info->surf->dim != ISL_SURF_DIM_3D);
-      assert(info->surf->tiling == ISL_TILING_4 ||
-             info->surf->tiling == ISL_TILING_64);
-      assert(info->surf->format == ISL_FORMAT_R8_UINT);
-   }
-
-   isl_genX_call(dev, emit_cpb_control_s, dev, batch, info);
-}
-
 /**
  * A variant of isl_surf_get_image_offset_sa() specific to
  * ISL_DIM_LAYOUT_GFX4_2D.
index 6c60872..7cfe145 100644 (file)
@@ -1230,6 +1230,12 @@ typedef enum {
   ISL_MEMCPY_INVALID,
 } isl_memcpy_type;
 
+struct isl_surf_fill_state_info;
+struct isl_buffer_fill_state_info;
+struct isl_depth_stencil_hiz_emit_info;
+struct isl_null_fill_state_info;
+struct isl_cpb_emit_info;
+
 struct isl_device {
    const struct intel_device_info *info;
    bool use_separate_stencil;
@@ -1285,6 +1291,21 @@ struct isl_device {
       uint32_t blitter_src;
       uint32_t blitter_dst;
    } mocs;
+
+   void (*surf_fill_state_s)(const struct isl_device *dev, void *state,
+                             const struct isl_surf_fill_state_info *restrict info);
+
+   void (*buffer_fill_state_s)(const struct isl_device *dev, void *state,
+                               const struct isl_buffer_fill_state_info *restrict info);
+
+   void (*emit_depth_stencil_hiz_s)(const struct isl_device *dev, void *batch,
+                                    const struct isl_depth_stencil_hiz_emit_info *restrict info);
+
+   void (*null_fill_state_s)(const struct isl_device *dev, void *state,
+                             const struct isl_null_fill_state_info *restrict info);
+
+   void (*emit_cpb_control_s)(const struct isl_device *dev, void *batch,
+                              const struct isl_cpb_emit_info *restrict info);
 };
 
 struct isl_extent2d {
@@ -2469,40 +2490,35 @@ isl_surf_get_ccs_surf(const struct isl_device *dev,
                       uint32_t row_pitch_B);
 
 #define isl_surf_fill_state(dev, state, ...) \
-   isl_surf_fill_state_s((dev), (state), \
+   (dev)->surf_fill_state_s(dev, state, \
                          &(struct isl_surf_fill_state_info) {  __VA_ARGS__ });
 
-void
-isl_surf_fill_state_s(const struct isl_device *dev, void *state,
-                      const struct isl_surf_fill_state_info *restrict info);
+#define isl_surf_fill_state_s(dev, state, info) \
+   (dev)->surf_fill_state_s(dev, state, info)
 
 #define isl_buffer_fill_state(dev, state, ...) \
-   isl_buffer_fill_state_s((dev), (state), \
-                           &(struct isl_buffer_fill_state_info) {  __VA_ARGS__ });
+   (dev)->buffer_fill_state_s(dev, state, \
+                              &(struct isl_buffer_fill_state_info) {  __VA_ARGS__ });
 
-void
-isl_buffer_fill_state_s(const struct isl_device *dev, void *state,
-                        const struct isl_buffer_fill_state_info *restrict info);
-
-void
-isl_null_fill_state_s(const struct isl_device *dev, void *state,
-                      const struct isl_null_fill_state_info *restrict info);
+#define isl_buffer_fill_state_s(dev, state, info) \
+   (dev)->buffer_fill_state_s(dev, state, info);
 
 #define isl_null_fill_state(dev, state, ...) \
-   isl_null_fill_state_s((dev), (state), \
-                           &(struct isl_null_fill_state_info) {  __VA_ARGS__ });
+   (dev)->null_fill_state_s(dev, state, \
+                            &(struct isl_null_fill_state_info) {  __VA_ARGS__ });
+
+#define isl_null_fill_state_s(dev, state, info) \
+   (dev)->null_fill_state_s(dev, state, info);
 
 #define isl_emit_depth_stencil_hiz(dev, batch, ...) \
-   isl_emit_depth_stencil_hiz_s((dev), (batch), \
-                                &(struct isl_depth_stencil_hiz_emit_info) {  __VA_ARGS__ })
+   (dev)->emit_depth_stencil_hiz_s(dev, batch, \
+                                   &(struct isl_depth_stencil_hiz_emit_info) {  __VA_ARGS__ })
 
-void
-isl_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
-                             const struct isl_depth_stencil_hiz_emit_info *restrict info);
+#define isl_emit_depth_stencil_hiz_s(dev, batch, info) \
+   (dev)->emit_depth_stencil_hiz_s(dev, batch, info)
 
-void
-isl_emit_cpb_control_s(const struct isl_device *dev, void *batch,
-                       const struct isl_cpb_emit_info *restrict info);
+#define isl_emit_cpb_control_s(dev, batch, info) \
+   (dev)->emit_cpb_control_s(dev, batch, info)
 
 void
 isl_surf_fill_image_param(const struct isl_device *dev,
index eeb3337..54d2c1f 100644 (file)
@@ -51,6 +51,14 @@ isl_genX(emit_cpb_control_s)(const struct isl_device *dev, void *batch,
                              const struct isl_cpb_emit_info *restrict info)
 {
 #if GFX_VERx10 >= 125
+   if (info->surf) {
+      assert((info->surf->usage & ISL_SURF_USAGE_CPB_BIT));
+      assert(info->surf->dim != ISL_SURF_DIM_3D);
+      assert(info->surf->tiling == ISL_TILING_4 ||
+             info->surf->tiling == ISL_TILING_64);
+      assert(info->surf->format == ISL_FORMAT_R8_UINT);
+   }
+
    struct GENX(3DSTATE_CPSIZE_CONTROL_BUFFER) cpb = {
       GENX(3DSTATE_CPSIZE_CONTROL_BUFFER_header),
    };
index 655f4df..f1863fe 100644 (file)
@@ -69,6 +69,36 @@ void
 isl_genX(emit_depth_stencil_hiz_s)(const struct isl_device *dev, void *batch,
                                    const struct isl_depth_stencil_hiz_emit_info *restrict info)
 {
+   if (info->depth_surf && info->stencil_surf) {
+      if (!dev->info->has_hiz_and_separate_stencil) {
+         assert(info->depth_surf == info->stencil_surf);
+         assert(info->depth_address == info->stencil_address);
+      }
+      assert(info->depth_surf->dim == info->stencil_surf->dim);
+   }
+
+   if (info->depth_surf) {
+      assert((info->depth_surf->usage & ISL_SURF_USAGE_DEPTH_BIT));
+      if (info->depth_surf->dim == ISL_SURF_DIM_3D) {
+         assert(info->view->base_array_layer + info->view->array_len <=
+                info->depth_surf->logical_level0_px.depth);
+      } else {
+         assert(info->view->base_array_layer + info->view->array_len <=
+                info->depth_surf->logical_level0_px.array_len);
+      }
+   }
+
+   if (info->stencil_surf) {
+      assert((info->stencil_surf->usage & ISL_SURF_USAGE_STENCIL_BIT));
+      if (info->stencil_surf->dim == ISL_SURF_DIM_3D) {
+         assert(info->view->base_array_layer + info->view->array_len <=
+                info->stencil_surf->logical_level0_px.depth);
+      } else {
+         assert(info->view->base_array_layer + info->view->array_len <=
+                info->stencil_surf->logical_level0_px.array_len);
+      }
+   }
+
    struct GENX(3DSTATE_DEPTH_BUFFER) db = {
       GENX(3DSTATE_DEPTH_BUFFER_header),
 #if GFX_VER >= 6
index 258dd8d..2a1ebcc 100644 (file)
@@ -45,8 +45,8 @@ isl_genX(emit_depth_stencil_hiz_s)(const struct isl_device *dev, void *batch,
                                    const struct isl_depth_stencil_hiz_emit_info *restrict info);
 
 void
-isl_genX(null_fill_state)(const struct isl_device *dev, void *state,
-                          const struct isl_null_fill_state_info *restrict info);
+isl_genX(null_fill_state_s)(const struct isl_device *dev, void *state,
+                            const struct isl_null_fill_state_info *restrict info);
 
 void
 isl_genX(emit_cpb_control_s)(const struct isl_device *dev, void *batch,
index 3b807d7..a215bb9 100644 (file)
 
 #include "isl.h"
 
+typedef void (*isl_surf_fill_state_s_func)(
+   const struct isl_device *dev, void *state,
+   const struct isl_surf_fill_state_info *restrict info);
+
+typedef void (*isl_buffer_fill_state_s_func)(
+   const struct isl_device *dev, void *state,
+   const struct isl_buffer_fill_state_info *restrict info);
+
+typedef void (*isl_emit_depth_stencil_hiz_s_func)(
+   const struct isl_device *dev, void *state,
+   const struct isl_depth_stencil_hiz_emit_info *restrict info);
+
+typedef void (*isl_null_fill_state_s_func)(const struct isl_device *dev, void *state,
+                                           const struct isl_null_fill_state_info *restrict info);
+
+typedef void (*isl_emit_cpb_control_s_func)(const struct isl_device *dev, void *batch,
+                                            const struct isl_cpb_emit_info *restrict info);
+
+#define isl_genX_declare_get_func(func)                                 \
+   static inline isl_##func##_func                                      \
+   isl_##func##_get_func(const struct isl_device *dev) {                \
+      switch (ISL_GFX_VERX10(dev)) {                                    \
+      case 40:                                                          \
+         return isl_gfx4_##func;                                        \
+      case 45:                                                          \
+         /* G45 surface state is the same as gfx5 */                    \
+      case 50:                                                          \
+         return isl_gfx5_##func;                                        \
+      case 60:                                                          \
+         return isl_gfx6_##func;                                        \
+      case 70:                                                          \
+         return isl_gfx7_##func;                                        \
+      case 75:                                                          \
+         return isl_gfx75_##func;                                       \
+      case 80:                                                          \
+         return isl_gfx8_##func;                                        \
+      case 90:                                                          \
+         return isl_gfx9_##func;                                        \
+      case 110:                                                         \
+         return isl_gfx11_##func;                                       \
+      case 120:                                                         \
+         return isl_gfx12_##func;                                       \
+      case 125:                                                         \
+         return isl_gfx125_##func;                                      \
+      default:                                                          \
+         assert(!"Unknown hardware generation");                        \
+         return NULL;                                                   \
+      }                                                                 \
+   }
+
 #define isl_finishme(format, ...) \
    do { \
       static bool reported = false; \
index 4129356..139c196 100644 (file)
@@ -158,6 +158,25 @@ void
 isl_genX(surf_fill_state_s)(const struct isl_device *dev, void *state,
                             const struct isl_surf_fill_state_info *restrict info)
 {
+#ifndef NDEBUG
+   isl_surf_usage_flags_t _base_usage =
+      info->view->usage & (ISL_SURF_USAGE_RENDER_TARGET_BIT |
+                           ISL_SURF_USAGE_TEXTURE_BIT |
+                           ISL_SURF_USAGE_STORAGE_BIT);
+   /* They may only specify one of the above bits at a time */
+   assert(__builtin_popcount(_base_usage) == 1);
+   /* The only other allowed bit is ISL_SURF_USAGE_CUBE_BIT */
+   assert((info->view->usage & ~ISL_SURF_USAGE_CUBE_BIT) == _base_usage);
+#endif
+
+   if (info->surf->dim == ISL_SURF_DIM_3D) {
+      assert(info->view->base_array_layer + info->view->array_len <=
+             info->surf->logical_level0_px.depth);
+   } else {
+      assert(info->view->base_array_layer + info->view->array_len <=
+             info->surf->logical_level0_px.array_len);
+   }
+
    struct GENX(RENDER_SURFACE_STATE) s = { 0 };
 
    s.SurfaceType = get_surftype(info->surf->dim, info->view->usage);
@@ -933,8 +952,8 @@ isl_genX(buffer_fill_state_s)(const struct isl_device *dev, void *state,
 }
 
 void
-isl_genX(null_fill_state)(const struct isl_device *dev, void *state,
-                          const struct isl_null_fill_state_info *restrict info)
+isl_genX(null_fill_state_s)(const struct isl_device *dev, void *state,
+                            const struct isl_null_fill_state_info *restrict info)
 {
    struct GENX(RENDER_SURFACE_STATE) s = {
       .SurfaceType = SURFTYPE_NULL,