isl: add surface creation reporting mechanism
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Fri, 3 Dec 2021 10:11:02 +0000 (12:11 +0200)
committerMarge Bot <emma+marge@anholt.net>
Wed, 21 Jun 2023 13:28:34 +0000 (13:28 +0000)
We have a number of users reporting surface creation issues with
modifiers etc...

This makes Anv & Iris printout the reason of the failure with
INTEL_DEBUG=isl Failure example in Iris :

MESA: debug: ISL surface failed: ../src/intel/isl/isl.c:1729: requested row pitch (42B) less than minimum alignment requirement (1024B) extent=160x160x1 dim=2d msaa=1x levels=1 rpitch=42 fmt=B8G8R8X8_UNORM usage=+rt+tex+disp

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

src/intel/dev/intel_debug.c
src/intel/dev/intel_debug.h
src/intel/isl/isl.c
src/intel/isl/isl_gfx6.c
src/intel/isl/isl_gfx7.c
src/intel/isl/isl_gfx8.c
src/intel/isl/isl_priv.h

index 95bb1a7..b488fdd 100644 (file)
@@ -102,6 +102,7 @@ static const struct debug_control debug_control[] = {
    { "perf-symbol-names", DEBUG_PERF_SYMBOL_NAMES },
    { "swsb-stall",  DEBUG_SWSB_STALL },
    { "heaps",       DEBUG_HEAPS },
+   { "isl",         DEBUG_ISL },
    { NULL,    0 }
 };
 
index 03a423d..99e28da 100644 (file)
@@ -92,6 +92,7 @@ extern uint64_t intel_debug;
 #define DEBUG_PERF_SYMBOL_NAMES   (1ull << 44)
 #define DEBUG_SWSB_STALL          (1ull << 45)
 #define DEBUG_HEAPS               (1ull << 46)
+#define DEBUG_ISL                 (1ull << 47)
 
 #define DEBUG_ANY                 (~0ull)
 
index 7d69bc7..2960c9a 100644 (file)
 #include <assert.h>
 #include <stdarg.h>
 #include <stdio.h>
+#include <inttypes.h>
 
+#include "dev/intel_debug.h"
 #include "genxml/genX_bits.h"
+#include "util/log.h"
 
 #include "isl.h"
 #include "isl_gfx4.h"
@@ -715,7 +718,8 @@ isl_surf_choose_tiling(const struct isl_device *dev,
    #undef CHOOSE
 
    /* No tiling mode accommodates the inputs. */
-   return false;
+   assert(tiling_flags == 0);
+   return notify_failure(info, "no supported tiling");
 }
 
 static bool
@@ -1771,6 +1775,71 @@ pitch_in_range(uint32_t n, uint32_t bits)
    return likely(bits != 0 && 1 <= n && n <= (1 << bits));
 }
 
+void PRINTFLIKE(4, 5)
+_isl_notify_failure(const struct isl_surf_init_info *surf_info,
+                    const char *file, int line, const char *fmt, ...)
+{
+   if (!INTEL_DEBUG(DEBUG_ISL))
+      return;
+
+   char msg[512];
+   va_list ap;
+   va_start(ap, fmt);
+   int ret = vsnprintf(msg, sizeof(msg), fmt, ap);
+   assert(ret < sizeof(msg));
+   va_end(ap);
+
+#define PRINT_USAGE(bit, str) \
+            (surf_info->usage & ISL_SURF_USAGE_##bit##_BIT) ? ("+"str) : ""
+#define PRINT_TILING(bit, str) \
+            (surf_info->tiling_flags & ISL_TILING_##bit##_BIT) ? ("+"str) : ""
+
+   snprintf(msg + ret, sizeof(msg) - ret,
+            " extent=%ux%ux%u dim=%s msaa=%ux levels=%u rpitch=%u fmt=%s "
+            "usages=%s%s%s%s%s%s%s%s%s%s%s%s%s%s "
+            "tiling_flags=%s%s%s%s%s%s%s%s%s%s%s",
+            surf_info->width, surf_info->height,
+            surf_info->dim == ISL_SURF_DIM_3D ?
+            surf_info->depth : surf_info->array_len,
+            surf_info->dim == ISL_SURF_DIM_1D ? "1d" :
+            surf_info->dim == ISL_SURF_DIM_2D ? "2d" : "3d",
+            surf_info->samples, surf_info->levels,
+            surf_info->row_pitch_B,
+            isl_format_get_name(surf_info->format) + strlen("ISL_FORMAT_"),
+
+            PRINT_USAGE(RENDER_TARGET,   "rt"),
+            PRINT_USAGE(DEPTH,           "depth"),
+            PRINT_USAGE(STENCIL,         "stenc"),
+            PRINT_USAGE(TEXTURE,         "tex"),
+            PRINT_USAGE(CUBE,            "cube"),
+            PRINT_USAGE(DISABLE_AUX,     "noaux"),
+            PRINT_USAGE(DISPLAY,         "disp"),
+            PRINT_USAGE(HIZ,             "hiz"),
+            PRINT_USAGE(MCS,             "mcs"),
+            PRINT_USAGE(CCS,             "ccs"),
+            PRINT_USAGE(VERTEX_BUFFER,   "vb"),
+            PRINT_USAGE(INDEX_BUFFER,    "ib"),
+            PRINT_USAGE(CONSTANT_BUFFER, "const"),
+            PRINT_USAGE(STAGING,         "stage"),
+
+            PRINT_TILING(LINEAR,         "linear"),
+            PRINT_TILING(W,              "W"),
+            PRINT_TILING(X,              "X"),
+            PRINT_TILING(Y0,             "Y0"),
+            PRINT_TILING(Yf,             "Yf"),
+            PRINT_TILING(Ys,             "Ys"),
+            PRINT_TILING(4,              "4"),
+            PRINT_TILING(64,             "64"),
+            PRINT_TILING(HIZ,            "hiz"),
+            PRINT_TILING(CCS,            "ccs"),
+            PRINT_TILING(GFX12_CCS,      "ccs12"));
+
+#undef PRINT_USAGE
+#undef PRINT_TILING
+
+   mesa_logd("%s:%i: %s", file, line, msg);
+}
+
 static bool
 isl_calc_row_pitch(const struct isl_device *dev,
                    const struct isl_surf_init_info *surf_info,
@@ -1787,11 +1856,19 @@ isl_calc_row_pitch(const struct isl_device *dev,
                              alignment_B);
 
    if (surf_info->row_pitch_B != 0) {
-      if (surf_info->row_pitch_B < min_row_pitch_B)
-         return false;
+      if (surf_info->row_pitch_B < min_row_pitch_B) {
+         return notify_failure(surf_info,
+                               "requested row pitch (%uB) less than minimum "
+                               "allowed (%uB)",
+                               surf_info->row_pitch_B, min_row_pitch_B);
+      }
 
-      if (surf_info->row_pitch_B % alignment_B != 0)
-         return false;
+      if (surf_info->row_pitch_B % alignment_B != 0) {
+         return notify_failure(surf_info,
+                               "requested row pitch (%uB) doesn't satisfy the "
+                               "minimum alignment requirement (%uB)",
+                               surf_info->row_pitch_B, alignment_B);
+      }
    }
 
    const uint32_t row_pitch_B =
@@ -1800,7 +1877,7 @@ isl_calc_row_pitch(const struct isl_device *dev,
    const uint32_t row_pitch_tl = row_pitch_B / tile_info->phys_extent_B.width;
 
    if (row_pitch_B == 0)
-      return false;
+      return notify_failure(surf_info, "calculated row pitch is zero");
 
    if (dim_layout == ISL_DIM_LAYOUT_GFX9_1D) {
       /* SurfacePitch is ignored for this layout. */
@@ -1810,29 +1887,49 @@ isl_calc_row_pitch(const struct isl_device *dev,
    if ((surf_info->usage & (ISL_SURF_USAGE_RENDER_TARGET_BIT |
                             ISL_SURF_USAGE_TEXTURE_BIT |
                             ISL_SURF_USAGE_STORAGE_BIT)) &&
-       !pitch_in_range(row_pitch_B, RENDER_SURFACE_STATE_SurfacePitch_bits(dev->info)))
-      return false;
+       !pitch_in_range(row_pitch_B, RENDER_SURFACE_STATE_SurfacePitch_bits(dev->info))) {
+      return notify_failure(surf_info,
+                            "row pitch (%uB) not in range of "
+                            "RENDER_SURFACE_STATE::SurfacePitch",
+                            row_pitch_B);
+   }
 
    if ((surf_info->usage & (ISL_SURF_USAGE_CCS_BIT |
                             ISL_SURF_USAGE_MCS_BIT)) &&
-       !pitch_in_range(row_pitch_tl, RENDER_SURFACE_STATE_AuxiliarySurfacePitch_bits(dev->info)))
-      return false;
+       !pitch_in_range(row_pitch_tl, RENDER_SURFACE_STATE_AuxiliarySurfacePitch_bits(dev->info))) {
+      return notify_failure(surf_info,
+                            "row_pitch_tl=%u not in range of "
+                            "RENDER_SURFACE_STATE::AuxiliarySurfacePitch",
+                            row_pitch_tl);
+   }
 
    if ((surf_info->usage & ISL_SURF_USAGE_DEPTH_BIT) &&
-       !pitch_in_range(row_pitch_B, _3DSTATE_DEPTH_BUFFER_SurfacePitch_bits(dev->info)))
-      return false;
+       !pitch_in_range(row_pitch_B, _3DSTATE_DEPTH_BUFFER_SurfacePitch_bits(dev->info))) {
+      return notify_failure(surf_info,
+                            "row pitch (%uB) not in range of "
+                            "3DSTATE_DEPTH_BUFFER::SurfacePitch",
+                            row_pitch_B);
+   }
 
    if ((surf_info->usage & ISL_SURF_USAGE_HIZ_BIT) &&
-       !pitch_in_range(row_pitch_B, _3DSTATE_HIER_DEPTH_BUFFER_SurfacePitch_bits(dev->info)))
-      return false;
+       !pitch_in_range(row_pitch_B, _3DSTATE_HIER_DEPTH_BUFFER_SurfacePitch_bits(dev->info))) {
+      return notify_failure(surf_info,
+                            "row pitch (%uB) not in range of "
+                            "3DSTATE_HIER_DEPTH_BUFFER::SurfacePitch",
+                            row_pitch_B);
+   }
 
    const uint32_t stencil_pitch_bits = dev->use_separate_stencil ?
       _3DSTATE_STENCIL_BUFFER_SurfacePitch_bits(dev->info) :
       _3DSTATE_DEPTH_BUFFER_SurfacePitch_bits(dev->info);
 
    if ((surf_info->usage & ISL_SURF_USAGE_STENCIL_BIT) &&
-       !pitch_in_range(row_pitch_B, stencil_pitch_bits))
-      return false;
+       !pitch_in_range(row_pitch_B, stencil_pitch_bits)) {
+      return notify_failure(surf_info,
+                            "row pitch (%uB) not in range of "
+                            "3DSTATE_STENCIL_BUFFER/3DSTATE_DEPTH_BUFFER::SurfacePitch",
+                            row_pitch_B);
+   }
 
    if ((surf_info->usage & ISL_SURF_USAGE_CPB_BIT) &&
        !pitch_in_range(row_pitch_B, _3DSTATE_CPSIZE_CONTROL_BUFFER_SurfacePitch_bits(dev->info)))
@@ -1845,6 +1942,7 @@ isl_calc_row_pitch(const struct isl_device *dev,
 
 static bool
 isl_calc_size(const struct isl_device *dev,
+              const struct isl_surf_init_info *info,
               const struct isl_tile_info *tile_info,
               const struct isl_extent4d *phys_total_el,
               uint32_t array_pitch_el_rows,
@@ -1898,8 +1996,12 @@ isl_calc_size(const struct isl_device *dev,
        *
        * This comment is applicable to all Pre-gfx9 platforms.
        */
-      if (size_B > (uint64_t) 1 << 31)
-         return false;
+      if (size_B > (uint64_t) 1 << 31) {
+         return notify_failure(
+            info,
+            "calculated size (%"PRIu64"B) exceeds platform limit of (1 << 31)",
+            size_B);
+      }
    } else if (ISL_GFX_VER(dev) < 11) {
       /* From the Skylake PRM Vol 5, Maximum Surface Size in Bytes:
        *    "In addition to restrictions on maximum height, width, and depth,
@@ -1907,12 +2009,20 @@ isl_calc_size(const struct isl_device *dev,
        *     All pixels within the surface must be contained within 2^38 bytes
        *     of the base address."
        */
-      if (size_B > (uint64_t) 1 << 38)
-         return false;
+      if (size_B > (uint64_t) 1 << 38) {
+         return notify_failure(
+            info,
+            "calculated size (%"PRIu64"B) exceeds platform limit of (1 << 38)",
+            size_B);
+      }
    } else {
       /* gfx11+ platforms raised this limit to 2^44 bytes. */
-      if (size_B > (uint64_t) 1 << 44)
-         return false;
+      if (size_B > (uint64_t) 1 << 44) {
+         return notify_failure(
+            info,
+            "calculated size (%"PRIu64"B) exceeds platform limit of (1 << 44)",
+            size_B);
+      }
    }
 
    *out_size_B = size_B;
@@ -2050,8 +2160,8 @@ isl_surf_init_s(const struct isl_device *dev,
       return false;
 
    uint64_t size_B;
-   if (!isl_calc_size(dev, &tile_info, &phys_total_el, array_pitch_el_rows,
-                      row_pitch_B, &size_B))
+   if (!isl_calc_size(dev, info, &tile_info, &phys_total_el,
+                      array_pitch_el_rows, row_pitch_B, &size_B))
       return false;
 
    const uint32_t base_alignment_B =
index 80a404a..5052cd6 100644 (file)
@@ -39,7 +39,7 @@ isl_gfx6_choose_msaa_layout(const struct isl_device *dev,
    }
 
    if (!isl_format_supports_multisampling(dev->info, info->format))
-      return false;
+      return notify_failure(info, "format does not support msaa");
 
    /* From the Sandybridge PRM, Volume 4 Part 1 p85, SURFACE_STATE, Number of
     * Multisamples:
@@ -51,7 +51,7 @@ isl_gfx6_choose_msaa_layout(const struct isl_device *dev,
     *       - [...]
     */
    if (info->dim != ISL_SURF_DIM_2D)
-      return false;
+      return notify_failure(info, "msaa only supported on 2D surfaces");
 
    /* Should have been filtered by isl_gfx6_filter_tiling() */
    assert(!isl_surf_usage_is_display(info->usage));
@@ -59,7 +59,7 @@ isl_gfx6_choose_msaa_layout(const struct isl_device *dev,
 
    /* More obvious restrictions */
    if (info->levels > 1)
-      return false;
+      return notify_failure(info, "msaa not supported with LOD > 1");
 
    *msaa_layout = ISL_MSAA_LAYOUT_INTERLEAVED;
    return true;
index 4cfcf0b..45b8bf2 100644 (file)
@@ -67,7 +67,7 @@ isl_gfx7_choose_msaa_layout(const struct isl_device *dev,
    assert(tiling != ISL_TILING_LINEAR);
 
    if (!isl_format_supports_multisampling(dev->info, info->format))
-      return false;
+      return notify_failure(info, "format does not support msaa");
 
    /* From the Ivybridge PRM, Volume 4 Part 1 p73, SURFACE_STATE, Number of
     * Multisamples:
@@ -79,9 +79,9 @@ isl_gfx7_choose_msaa_layout(const struct isl_device *dev,
     *      Min LOD, Mip Count / LOD, and Resource Min LOD must be set to zero
     */
    if (info->dim != ISL_SURF_DIM_2D)
-      return false;
+      return notify_failure(info, "msaa only supported on 2D surfaces");
    if (info->levels > 1)
-      return false;
+      return notify_failure(info, "msaa not supported with LOD > 1");
 
    /* The Ivyrbridge PRM insists twice that signed integer formats cannot be
     * multisampled.
@@ -107,8 +107,10 @@ isl_gfx7_choose_msaa_layout(const struct isl_device *dev,
     */
 
    /* Multisampling requires vertical alignment of four. */
-   if (info->samples > 1 && gfx7_format_needs_valign2(dev, info->format))
-      return false;
+   if (info->samples > 1 && gfx7_format_needs_valign2(dev, info->format)) {
+      return notify_failure(info, "msaa requires vertical alignment of four, "
+                                  "but format requires vertical alignment of two");
+   }
 
    /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
     * Surface Storage Format:
@@ -161,7 +163,7 @@ isl_gfx7_choose_msaa_layout(const struct isl_device *dev,
       require_interleaved = true;
 
    if (require_array && require_interleaved)
-      return false;
+      return notify_failure(info, "cannot require array & interleaved msaa layouts");
 
    if (require_interleaved) {
       *msaa_layout = ISL_MSAA_LAYOUT_INTERLEAVED;
index e91d30c..362bbba 100644 (file)
@@ -61,23 +61,23 @@ isl_gfx8_choose_msaa_layout(const struct isl_device *dev,
     *      Min LOD, Mip Count / LOD, and Resource Min LOD must be set to zero.
     */
    if (info->dim != ISL_SURF_DIM_2D)
-      return false;
+      return notify_failure(info, "msaa only supported on 2D surfaces");
    if (info->levels > 1)
-      return false;
+      return notify_failure(info, "msaa not supported with LOD > 1");
 
    /* More obvious restrictions */
    assert(!isl_surf_usage_is_display(info->usage));
    assert(tiling != ISL_TILING_LINEAR);
 
    if (!isl_format_supports_multisampling(dev->info, info->format))
-      return false;
+      return notify_failure(info, "format does not support msaa");
 
    if (isl_surf_usage_is_depth_or_stencil(info->usage) ||
        (info->usage & ISL_SURF_USAGE_HIZ_BIT))
       require_interleaved = true;
 
    if (require_array && require_interleaved)
-      return false;
+      return notify_failure(info, "cannot require array & interleaved msaa layouts");
 
    if (require_interleaved) {
       *msaa_layout = ISL_MSAA_LAYOUT_INTERLEAVED;
index 130ff61..db1cd7e 100644 (file)
@@ -247,6 +247,14 @@ _isl_memcpy_tiled_to_linear_sse41(uint32_t xt1, uint32_t xt2,
                                   enum isl_tiling tiling,
                                   isl_memcpy_type copy_type);
 
+void PRINTFLIKE(4, 5)
+_isl_notify_failure(const struct isl_surf_init_info *surf_info,
+                    const char *file, int line, const char *fmt, ...);
+
+#define notify_failure(surf_info, ...) \
+   (_isl_notify_failure(surf_info, __FILE__, __LINE__, __VA_ARGS__), false)
+
+
 /* This is useful for adding the isl_prefix to genX functions */
 #define isl_genX(x) CONCAT2(isl_, genX(x))