Module: Mesa Branch: main Commit: b687cbe36c12081921e03c8633fedea334642105 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b687cbe36c12081921e03c8633fedea334642105
Author: Lionel Landwerlin <[email protected]> Date: Fri Dec 3 12:11:02 2021 +0200 isl: add surface creation reporting mechanism 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 <[email protected]> Reviewed-by: Nanley Chery <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14039> --- src/intel/dev/intel_debug.c | 1 + src/intel/dev/intel_debug.h | 1 + src/intel/isl/isl.c | 158 +++++++++++++++++++++++++++++++++++++------- src/intel/isl/isl_gfx6.c | 6 +- src/intel/isl/isl_gfx7.c | 14 ++-- src/intel/isl/isl_gfx8.c | 8 +-- src/intel/isl/isl_priv.h | 8 +++ 7 files changed, 159 insertions(+), 37 deletions(-) diff --git a/src/intel/dev/intel_debug.c b/src/intel/dev/intel_debug.c index 95bb1a795fc..b488fdd1847 100644 --- a/src/intel/dev/intel_debug.c +++ b/src/intel/dev/intel_debug.c @@ -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 } }; diff --git a/src/intel/dev/intel_debug.h b/src/intel/dev/intel_debug.h index 03a423d18d8..99e28dac5b5 100644 --- a/src/intel/dev/intel_debug.h +++ b/src/intel/dev/intel_debug.h @@ -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) diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c index 7d69bc7428d..2960c9acd91 100644 --- a/src/intel/isl/isl.c +++ b/src/intel/isl/isl.c @@ -24,8 +24,11 @@ #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 = diff --git a/src/intel/isl/isl_gfx6.c b/src/intel/isl/isl_gfx6.c index 80a404ac8cb..5052cd666cb 100644 --- a/src/intel/isl/isl_gfx6.c +++ b/src/intel/isl/isl_gfx6.c @@ -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; diff --git a/src/intel/isl/isl_gfx7.c b/src/intel/isl/isl_gfx7.c index 4cfcf0ba843..45b8bf299bf 100644 --- a/src/intel/isl/isl_gfx7.c +++ b/src/intel/isl/isl_gfx7.c @@ -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; diff --git a/src/intel/isl/isl_gfx8.c b/src/intel/isl/isl_gfx8.c index e91d30c339f..362bbbac9c1 100644 --- a/src/intel/isl/isl_gfx8.c +++ b/src/intel/isl/isl_gfx8.c @@ -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; diff --git a/src/intel/isl/isl_priv.h b/src/intel/isl/isl_priv.h index 130ff61e159..db1cd7e4a40 100644 --- a/src/intel/isl/isl_priv.h +++ b/src/intel/isl/isl_priv.h @@ -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))
