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 <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>
This commit is contained in:
Lionel Landwerlin 2021-12-03 12:11:02 +02:00 committed by Marge Bot
parent 7507441430
commit b687cbe36c
7 changed files with 159 additions and 37 deletions

View 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 }
};

View 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)

View file

@ -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 =

View 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;

View 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;

View 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;

View 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))