Mesa (main): isl: add support for coarse pixel control surfaces

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Feb 2 17:39:54 UTC 2022


Module: Mesa
Branch: main
Commit: dff08cbf8e7f9d9656b3c260b115ae9951a0b99c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=dff08cbf8e7f9d9656b3c260b115ae9951a0b99c

Author: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Date:   Fri Nov  6 17:03:33 2020 +0200

isl: add support for coarse pixel control surfaces

Those surfaces are used as attachment to rendering passes and describe
the rate of coarse pixel shading for the pass.

v2: Move CPB_BIT tile filtering to isl_gfx125_filter_tiling() (Nanley)

v3: Drop unused macro (Nanley)
    s/isl_to_gen/isl_encode/ (Nanley)
    Remove pitch alignment 128B constraint already covered by tiling (Nanley)
    Move some asserts together (Nanley)

v4: Disable miptail for now (Nanley)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Reviewed-by: Nanley Chery <nanley.g.chery at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13739>

---

 src/intel/genxml/meson.build  |   2 +
 src/intel/isl/isl.c           |  33 +++++++++++++
 src/intel/isl/isl.h           |  42 ++++++++++++++++
 src/intel/isl/isl_emit_cpb.c  | 110 ++++++++++++++++++++++++++++++++++++++++++
 src/intel/isl/isl_genX_priv.h |   4 ++
 src/intel/isl/isl_gfx12.c     |   9 ++++
 src/intel/isl/meson.build     |   1 +
 7 files changed, 201 insertions(+)

diff --git a/src/intel/genxml/meson.build b/src/intel/genxml/meson.build
index 4202c138a36..0932e2c0179 100644
--- a/src/intel/genxml/meson.build
+++ b/src/intel/genxml/meson.build
@@ -56,6 +56,8 @@ genX_bits_included_symbols = [
   '3DSTATE_CLEAR_PARAMS',
   '3DSTATE_SO_BUFFER::Surface Base Address',
   '3DSTATE_SO_BUFFER::Stream Offset',
+  '3DSTATE_CPSIZE_CONTROL_BUFFER::Surface Base Address',
+  '3DSTATE_CPSIZE_CONTROL_BUFFER::Surface Pitch',
   # structures
   'RENDER_SURFACE_STATE::Surface Base Address',
   'RENDER_SURFACE_STATE::Surface Pitch',
diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c
index b2de1544f76..e16661dcc15 100644
--- a/src/intel/isl/isl.c
+++ b/src/intel/isl/isl.c
@@ -198,6 +198,9 @@ isl_mocs(const struct isl_device *dev, isl_surf_usage_flags_t usage,
       if (usage & ISL_SURF_USAGE_STAGING_BIT)
          return dev->mocs.internal;
 
+      if (usage & ISL_SURF_USAGE_CPB_BIT)
+         return dev->mocs.internal;
+
       /* Using L1:HDC for storage buffers breaks Vulkan memory model
        * tests that use shader atomics.  This isn't likely to work out,
        * and we can't know a priori whether they'll be used.  So just
@@ -307,6 +310,10 @@ isl_device_init(struct isl_device *dev,
       dev->max_buffer_size = 1ull << 27;
    }
 
+   dev->cpb.size = _3DSTATE_CPSIZE_CONTROL_BUFFER_length(info) * 4;
+   dev->cpb.offset =
+      _3DSTATE_CPSIZE_CONTROL_BUFFER_SurfaceBaseAddress_start(info) / 8;
+
    isl_device_setup_mocs(dev);
 }
 
@@ -1599,6 +1606,9 @@ isl_calc_row_pitch_alignment(const struct isl_device *dev,
       return tile_info->phys_extent_B.width;
    }
 
+   /* We only support tiled fragment shading rate buffers. */
+   assert((surf_info->usage & ISL_SURF_USAGE_CPB_BIT) == 0);
+
    /* From the Broadwel PRM >> Volume 2d: Command Reference: Structures >>
     * RENDER_SURFACE_STATE Surface Pitch (p349):
     *
@@ -1782,6 +1792,10 @@ isl_calc_row_pitch(const struct isl_device *dev,
        !pitch_in_range(row_pitch_B, stencil_pitch_bits))
       return false;
 
+   if ((surf_info->usage & ISL_SURF_USAGE_CPB_BIT) &&
+       !pitch_in_range(row_pitch_B, _3DSTATE_CPSIZE_CONTROL_BUFFER_SurfacePitch_bits(dev->info)))
+      return false;
+
  done:
    *out_row_pitch_B = row_pitch_B;
    return true;
@@ -1792,6 +1806,10 @@ isl_surf_init_s(const struct isl_device *dev,
                 struct isl_surf *surf,
                 const struct isl_surf_init_info *restrict info)
 {
+   /* Some sanity checks */
+   assert(!(info->usage & ISL_SURF_USAGE_CPB_BIT) ||
+          dev->info->has_coarse_pixel_primitive_and_cb);
+
    const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);
 
    const struct isl_extent4d logical_level0_px = {
@@ -2459,6 +2477,21 @@ isl_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
    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.
diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h
index 799b5e035dd..3f84a3a5988 100644
--- a/src/intel/isl/isl.h
+++ b/src/intel/isl/isl.h
@@ -1115,6 +1115,7 @@ typedef uint64_t isl_surf_usage_flags_t;
 #define ISL_SURF_USAGE_INDEX_BUFFER_BIT        (1u << 12)
 #define ISL_SURF_USAGE_CONSTANT_BUFFER_BIT     (1u << 13)
 #define ISL_SURF_USAGE_STAGING_BIT             (1u << 14)
+#define ISL_SURF_USAGE_CPB_BIT                 (1u << 15)
 /** @} */
 
 /**
@@ -1269,6 +1270,15 @@ struct isl_device {
       uint8_t hiz_offset;
    } ds;
 
+   /**
+    * Describes the layout of the coarse pixel control commands as emitted by
+    * isl_emit_cpb_control.
+    */
+   struct {
+      uint8_t size;
+      uint8_t offset;
+   } cpb;
+
    struct {
       uint32_t internal;
       uint32_t external;
@@ -1770,6 +1780,28 @@ struct isl_null_fill_state_info {
    uint32_t minimum_array_element;
 };
 
+struct isl_cpb_emit_info {
+   /**
+    * The coarse pixel shading control surface.
+    */
+   const struct isl_surf *surf;
+
+   /**
+    * The view into the control surface.
+    */
+   const struct isl_view *view;
+
+   /**
+    * The address of the control surface in GPU memory.
+    */
+   uint64_t address;
+
+   /**
+    * The Memory Object Control state for the surface.
+    */
+   uint32_t mocs;
+};
+
 extern const struct isl_format_layout isl_format_layouts[];
 extern const char isl_format_names[];
 extern const uint16_t isl_format_name_offsets[];
@@ -2236,6 +2268,12 @@ isl_surf_usage_is_depth_or_stencil(isl_surf_usage_flags_t usage)
    return usage & (ISL_SURF_USAGE_DEPTH_BIT | ISL_SURF_USAGE_STENCIL_BIT);
 }
 
+static inline bool
+isl_surf_usage_is_cpb(isl_surf_usage_flags_t usage)
+{
+   return usage & ISL_SURF_USAGE_CPB_BIT;
+}
+
 static inline bool
 isl_surf_info_is_z16(const struct isl_surf_init_info *info)
 {
@@ -2423,6 +2461,10 @@ void
 isl_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
                              const struct isl_depth_stencil_hiz_emit_info *restrict info);
 
+void
+isl_emit_cpb_control_s(const struct isl_device *dev, void *batch,
+                       const struct isl_cpb_emit_info *restrict info);
+
 void
 isl_surf_fill_image_param(const struct isl_device *dev,
                           struct brw_image_param *param,
diff --git a/src/intel/isl/isl_emit_cpb.c b/src/intel/isl/isl_emit_cpb.c
new file mode 100644
index 00000000000..024fba9e478
--- /dev/null
+++ b/src/intel/isl/isl_emit_cpb.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2020 Intel Corporation
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"),
+ *  to deal in the Software without restriction, including without limitation
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ *  and/or sell copies of the Software, and to permit persons to whom the
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice (including the next
+ *  paragraph) shall be included in all copies or substantial portions of the
+ *  Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ *  IN THE SOFTWARE.
+ */
+
+#include <stdint.h>
+
+#define __gen_address_type uint64_t
+#define __gen_user_data void
+
+static uint64_t
+__gen_combine_address(__attribute__((unused)) void *data,
+                      __attribute__((unused)) void *loc, uint64_t addr,
+                      uint32_t delta)
+{
+   return addr + delta;
+}
+
+#include "genxml/gen_macros.h"
+#include "genxml/genX_pack.h"
+
+#include "isl_priv.h"
+
+#if GFX_VERx10 >= 125
+static const uint8_t isl_encode_tiling[] = {
+   [ISL_TILING_4]  = TILE4,
+   [ISL_TILING_64] = TILE64,
+};
+#endif
+
+void
+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
+   struct GENX(3DSTATE_CPSIZE_CONTROL_BUFFER) cpb = {
+      GENX(3DSTATE_CPSIZE_CONTROL_BUFFER_header),
+   };
+
+   if (info->surf) {
+      /* BSpec 46962 has a number of restriction on the fields of this packet
+       * like :
+       *
+       *   "The Width specified by this field must be less than or equal to
+       *    the surface pitch (specified in bytes via the Surface Pitch field).
+       *    For cube maps, Width must be set equal to Height.
+       *
+       *    1. The Width ofthis buffer must be the same as the Width of the
+       *       render target(s) (defined in SURFACE_STATE), unless Surface
+       *       Type is SURFTYPE_1D or SURFTYPE_2D with Depth = 0 (non-array)
+       *       and LOD = 0 (non-mip mapped).
+       *
+       *    2. Depth buffer (defined in 3DSTATE_DEPTH_BUFFER) unless either
+       *       the depth buffer or this buffer surf_typeare SURFTYPE_NULL"
+       *
+       * Unfortunately APIs like Vulkan do not give guarantees that every
+       * framebuffer attachment will match in size (RT & CPB surfaces for
+       * example). But at least it gives a guarantee that all the attachments
+       * of a render pass will be at least be large enough to handle the
+       * rendered area. So here we use the CPB surface values, even if they
+       * don't strictly match the various BSpec restrictions.
+       */
+      cpb.Width                  = (info->surf->logical_level0_px.width * 8) - 1;
+      cpb.Height                 = (info->surf->logical_level0_px.height * 8) - 1;
+      cpb.Depth                  = info->view->array_len - 1;
+      cpb.RenderTargetViewExtent = cpb.Depth;
+
+      cpb.SurfLOD                = info->view->base_level;
+      cpb.MinimumArrayElement    = info->view->base_array_layer;
+      cpb.SurfaceType            = SURFTYPE_2D;
+      cpb.SurfacePitch           = info->surf->row_pitch_B - 1;
+      cpb.MOCS                   = info->mocs;
+      cpb.SurfaceQPitch          = isl_surf_get_array_pitch_sa_rows(info->surf) >> 2;
+      cpb.TiledMode              = isl_encode_tiling[info->surf->tiling];
+      cpb.SurfaceBaseAddress     = info->address;
+
+      /* We don't use miptails yet. The PRM recommends that you set "Mip Tail
+       * Start LOD" to 15 to prevent the hardware from trying to use them.
+       */
+      cpb.MipTailStartLOD        = 15;
+   } else {
+      cpb.SurfaceType  = SURFTYPE_NULL;
+      cpb.TiledMode    = TILE64;
+   }
+
+   /* Pack everything into the batch */
+   uint32_t *dw = batch;
+   GENX(3DSTATE_CPSIZE_CONTROL_BUFFER_pack)(NULL, dw, &cpb);
+#else
+   unreachable("Coarse pixel shading not supported");
+#endif
+}
diff --git a/src/intel/isl/isl_genX_priv.h b/src/intel/isl/isl_genX_priv.h
index 5fa545a501c..258dd8db740 100644
--- a/src/intel/isl/isl_genX_priv.h
+++ b/src/intel/isl/isl_genX_priv.h
@@ -47,3 +47,7 @@ isl_genX(emit_depth_stencil_hiz_s)(const struct isl_device *dev, void *batch,
 void
 isl_genX(null_fill_state)(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,
+                             const struct isl_cpb_emit_info *restrict info);
diff --git a/src/intel/isl/isl_gfx12.c b/src/intel/isl/isl_gfx12.c
index df541e6504a..959139ca923 100644
--- a/src/intel/isl/isl_gfx12.c
+++ b/src/intel/isl/isl_gfx12.c
@@ -88,6 +88,15 @@ isl_gfx125_filter_tiling(const struct isl_device *dev,
    /* Tile64 is not defined for format sizes that are 24, 48, and 96 bpb. */
    if (isl_format_get_layout(info->format)->bpb % 3 == 0)
       *flags &= ~ISL_TILING_64_BIT;
+
+   /* BSpec 46962: 3DSTATE_CPSIZE_CONTROL_BUFFER::Tiled Mode : TILE4 & TILE64
+    * are the only 2 valid values.
+    *
+    * TODO: For now we only TILE64 as we need to figure out potential
+    *       additional requirements for TILE4.
+    */
+   if (info->usage & ISL_SURF_USAGE_CPB_BIT)
+      *flags &= ISL_TILING_64_BIT;
 }
 
 void
diff --git a/src/intel/isl/meson.build b/src/intel/isl/meson.build
index 891360fdd6d..50c60f87511 100644
--- a/src/intel/isl/meson.build
+++ b/src/intel/isl/meson.build
@@ -19,6 +19,7 @@
 # SOFTWARE.
 
 isl_per_hw_ver_files = files(
+  'isl_emit_cpb.c',
   'isl_emit_depth_stencil.c',
   'isl_surface_state.c',
   'isl_genX_helpers.h',



More information about the mesa-commit mailing list