Re: [PATCH 1/4] drm/fourcc: Add modifiers for AMD GFX6-8
Christian König <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx,org.freedesktop.lists.dri-devel |
|---|---|
| Message-ID | <[email protected]> |
On 7/15/26 12:57, Timur Kristóf wrote: > GFX6-8 are the oldest GPUs supported by the amdgpu > kernel driver, and the last ones that didn't support > DRM format modifiers until now. These are the Southern > Islands, Sea Islands and Volcanic Islands families > of GPUs. > > On GFX6-8, the GFX block can only use pre-determined tiling > modes which are programmed by the kernel according to the > tiling mode table. GFX6 uses the GB_TILE_MODE0...31 registers, > and GFX7-8 also has GB_MACROTILE_MODE0...15 registers. > DCC is also supported on GFX8, albeit not displayable. > > Note that the tiling table is uAPI and userspace relies on > specific modes being present at specific indices. > > How the tiling works is primarily determined by the > so-called array mode. > Use the TILE field to specify the array mode. > > Pixel data is organized into micro tiles. > Each micro tile may be 8x8 / 8x8x4 / 8x8x8 pixels, > depending on the array mode. > Add the MICROTILE field to specify microtile mode. > > Microtiles may be further organized into macro tiles, > which have many configurable parameters. Macro tile mode > selection depends on how many bits per pixel an image has. > Add the PIPE_CONFIG, TILE_SPLIT, BANK_WIDTH, BANK_HEIGHT, > MACRO_TILE_ASPECT, NUM_BANKS fields to specify parameters > of macro tiled modes. > > Furthermore, tiling is also influenced by memory > configuration. Old RFC patches received feedback > concerning that, so I looked into it specifically: > GB_ADDR_CONFIG.ROW_SIZE needs to be considered when > calculating TILE_SPLIT, but does not need to be included > in the modifiers, and also PIPE_INTERLEAVE matters, > but it's hardcoded to the same value on all GFX6-8 GPUs > and changing it would break userspace, so let's assume > it isn't going to change. Therefore we don't need to > include that in modifiers. Mesa also reads NUM_RANKS > but actually doesn't use its value on GFX6-8. > > As a side note, tiling works similarly on GFX4-5 > (that is Evergreen and Northern Islands). But that > will need some additional PIPE_CONFIG enum values > as well as some extra fields not relevant to GFX6-8. > > Initially, let's only expose the tiling modes that are > most relevant to sharing buffers between different > processes: > > Exposed array modes (TILE field): > - 1D_TILED_THIN1: micro tiled only > - 2D_TILED_THIN1: macro tiled > > Exposed micro tile modes (MICROTILE field): > - DISPLAY: supported by DCE (the display engine) > - THIN: more efficient but not displayable > > Exposed macro tile modes: > All possible parameters (25088 permutations). > > More modes may be exposed in the future as needed. > > Technically, the amount of possible combinations > of all possible tiling parameters is in the range > of hundreds of thousands, but in practice, there are > just a handful of possible modifiers for a surface. > > For example on GFX8, a surface would have these > modifiers, from best to worst performance: > > - 2D_TILED_THIN1 + THIN + DCC + macrotile params [1] > - 2D_TILED_THIN1 + THIN + macrotile params [1] > - 2D_TILED_THIN1 + DISPLAY + macrotile params [1] > - 1D_TILED_THIN1 + THIN > - 1D_TILED_THIN1 + DISPLAY > - LINEAR > > [1] The macro tiling parameters depend on how many > bits per pixel of the specific surface has and > how the chip is configured. There is only one set > of valid macrotile params for a given surface. > > DCC is only supported by GFX8 and newer, and only > with non-displayable macrotiling modes. > > When sharing buffers between different GFX6-8 GPUs, > it is very unlikely that they support the exact same > macrotiling configuration, so they will likely need > to use micro tiled modes, which are still much better > than using linear buffers. (Note that currently Mesa > always uses LINEAR when copying between two GPUs.) > > Suggested-by: Bas Nieuwenhuizen <[email protected]> > Signed-off-by: Timur Kristóf <[email protected]> > Reviewed-by: Marek Olšák <[email protected]> > Reviewed-by: Daniel Stone <[email protected]> > Reviewed-by: Alex Deucher <[email protected]> Feel free to add Acked-by: Christian König <[email protected]> to the entire series. > --- > include/uapi/drm/drm_fourcc.h | 209 +++++++++++++++++++++++++++++++--- > 1 file changed, 191 insertions(+), 18 deletions(-) > > diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h > index e527b24bd824..7a0a1e5dac75 100644 > --- a/include/uapi/drm/drm_fourcc.h > +++ b/include/uapi/drm/drm_fourcc.h > @@ -1620,36 +1620,69 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) > * For multi-plane formats the above surfaces get merged into one plane for > * each format plane, based on the required alignment only. > * > - * Bits Parameter Notes > - * ----- ------------------------ --------------------------------------------- > + * Bits Parameter Notes > + * ------- ------------------------ --------------------------------------------- > + * > + * DRM format modifier fields on AMD GPUs: > + * 7:0 TILE_VERSION Values are AMD_FMT_MOD_TILE_VER_* > + * 12:8 TILE Values are AMD_FMT_MOD_TILE_<version>_* > + * 13 DCC Delta Color Compression, supported on GFX8 and newer > + 55:14 (chip specific) See below for details, depends on GFX block version > + * 63:56 Vendor Value is DRM_FORMAT_MOD_VENDOR_AMD > + * > + * Chip specific fields on Gfx9 and newer: > + * 14 DCC_RETILE > + * 15 DCC_PIPE_ALIGN > + * 16 DCC_INDEPENDENT_64B > + * 17 DCC_INDEPENDENT_128B > + * 19:18 DCC_MAX_COMPRESSED_BLOCK Values are AMD_FMT_MOD_DCC_BLOCK_* > + * 20 DCC_CONSTANT_ENCODE > + * 23:21 PIPE_XOR_BITS Only for some chips > + * 26:24 BANK_XOR_BITS Only for some chips > + * 29:27 PACKERS Only for some chips > + * 32:30 RB Only for some chips > + * 35:33 PIPE Only for some chips > + * 55:36 - Reserved for future use, must be zero > + * > + * Chip specific fields on Gfx6-8: > + * 16:14 MICROTILE Micro tile format > + * 21:17 PIPE_CONFIG Number of pipes and how pipes are interleaved > + * 24:22 TILE_SPLIT Tile split size > + * 26:25 BANK_WIDTH Number of tiles in the X direction in the same bank > + * 28:27 BANK_HEIGHT Number of tiles in the Y direction in the same bank > + * 30:29 MACRO_TILE_ASPECT Macro tile aspect ratio > + * 32:31 NUM_BANKS Number of banks > + * 55:33 - Reserved for future use, must be zero > * > - * 7:0 TILE_VERSION Values are AMD_FMT_MOD_TILE_VER_* > - * 12:8 TILE Values are AMD_FMT_MOD_TILE_<version>_* > - * 13 DCC > - * 14 DCC_RETILE > - * 15 DCC_PIPE_ALIGN > - * 16 DCC_INDEPENDENT_64B > - * 17 DCC_INDEPENDENT_128B > - * 19:18 DCC_MAX_COMPRESSED_BLOCK Values are AMD_FMT_MOD_DCC_BLOCK_* > - * 20 DCC_CONSTANT_ENCODE > - * 23:21 PIPE_XOR_BITS Only for some chips > - * 26:24 BANK_XOR_BITS Only for some chips > - * 29:27 PACKERS Only for some chips > - * 32:30 RB Only for some chips > - * 35:33 PIPE Only for some chips > - * 55:36 - Reserved for future use, must be zero > */ > #define AMD_FMT_MOD fourcc_mod_code(AMD, 0) > > #define IS_AMD_FMT_MOD(val) (((val) >> 56) == DRM_FORMAT_MOD_VENDOR_AMD) > > -/* Reserve 0 for GFX8 and older */ > +#define AMD_FMT_MOD_TILE_VER_GFX6 0 > #define AMD_FMT_MOD_TILE_VER_GFX9 1 > #define AMD_FMT_MOD_TILE_VER_GFX10 2 > #define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3 > #define AMD_FMT_MOD_TILE_VER_GFX11 4 > #define AMD_FMT_MOD_TILE_VER_GFX12 5 > > +/* > + * Gfx6-8 tiling modes. > + * A complete reference implementation is found in addrlib in the Mesa code base. > + * > + * - Microtiled modes (1D): > + * Pixel data is organized into micro tiles of 8x8 pixels. > + * > + * - Macrotiled modes (2D): > + * Micro tiles are further organized into macro tiles. > + * These are optimized for even load distribution among memory channels. > + * > + * Note that only THIN1 modes are exposed here. > + * THICK and XTHICK are for 3D images and not relevant to DRM format modifiers. > + */ > +#define AMD_FMT_MOD_TILE_GFX6_1D_TILED_THIN1 0x2 > +#define AMD_FMT_MOD_TILE_GFX6_2D_TILED_THIN1 0x4 > + > /* > * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical > * version. > @@ -1748,6 +1781,146 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) > #define AMD_FMT_MOD_PIPE_SHIFT 33 > #define AMD_FMT_MOD_PIPE_MASK 0x7 > > +/* > + * MICRO_TILE_MODE, 3 bits. Determines the micro tile format. > + * Only relevant to Gfx6-8. > + * > + * DISPLAY - Displayable tiling > + * THIN - Non-displayable tiling, a.k.a thin micro tiling > + * DEPTH, THICK - not exposed, not relevant to DRM format modifier use cases > + * ROTATED - not exposed, not implemented in Linux or Mesa > + */ > +#define AMD_FMT_MOD_MICROTILE_SHIFT 14ULL > +#define AMD_FMT_MOD_MICROTILE_MASK 0x7 > + > +#define AMD_FMT_MOD_MICROTILE_DISPLAY 0x0 > +#define AMD_FMT_MOD_MICROTILE_THIN 0x1 > + > +/* > + * PIPE_CONFIG, 5 bits. Number of pipes and how pipes are interleaved on the surface, > + * which means the shader engine tile size and packer tile size. > + * Typically matches the number of memory channels, or number of RBs. > + * Only relevant to Gfx6-8 macro tiled modes. > + * > + * P<n>_<a>x<b>_<c>x<d> > + * where: > + * <n> - number of pipes > + * <a>x<b> - shader engine tile size > + * <c>x<d> - packer tile size > + */ > +#define AMD_FMT_MOD_PIPE_CONFIG_SHIFT 17ULL > +#define AMD_FMT_MOD_PIPE_CONFIG_MASK 0x1f > + > +#define AMD_FMT_MOD_PIPE_CONFIG_P2 0x0 > +#define AMD_FMT_MOD_PIPE_CONFIG_P4_8x16 0x4 > +#define AMD_FMT_MOD_PIPE_CONFIG_P4_16x16 0x5 > +#define AMD_FMT_MOD_PIPE_CONFIG_P4_16x32 0x6 > +#define AMD_FMT_MOD_PIPE_CONFIG_P4_32x32 0x7 > +#define AMD_FMT_MOD_PIPE_CONFIG_P8_16x16_8x16 0x8 > +#define AMD_FMT_MOD_PIPE_CONFIG_P8_16x32_8x16 0x9 > +#define AMD_FMT_MOD_PIPE_CONFIG_P8_32x32_8x16 0xa > +#define AMD_FMT_MOD_PIPE_CONFIG_P8_16x32_16x16 0xb > +#define AMD_FMT_MOD_PIPE_CONFIG_P8_32x32_16x16 0xc > +#define AMD_FMT_MOD_PIPE_CONFIG_P8_32x32_16x32 0xd > +#define AMD_FMT_MOD_PIPE_CONFIG_P8_32x64_32x32 0xe > +#define AMD_FMT_MOD_PIPE_CONFIG_P16_32x32_8x16 0x10 > +#define AMD_FMT_MOD_PIPE_CONFIG_P16_32x32_16x16 0x11 > + > +/* > + * TILE_SPLIT, 3 bits. > + * Only relevant to Gfx6-8 macro tiled modes. > + * > + * On GFX6 (or with depth tiling modes on GFX7 and newer), > + * the GFX block uses the GB_TILE_MODE.TILE_SPLIT field directly. > + * > + * On GFX7 and newer with non-depth tiling modes, the GFX block uses a > + * split factor which is stored in the GB_TILE_MODE.SAMPLE_SPLIT field. > + * SAMPLE_SPLIT may be: 0 - 1 byte; 1 - 2 bytes; 2 - 4 bytes; 3 - 8 bytes. > + * The actual tile size and tile split bytes are calculated as follows: > + * > + * bpp = ... <- bits per pixel in the current image > + * thickness = ... <- depends on array mode; may be: 1, 4, 8 > + * num_samples = ... <- number of samples in the current image > + * tile_size_pixels = 8 * 8 > + * tile_bytes_1x = thickness * tile_size_pixels * bpp / 8 > + * sample_split_factor = 1 << SAMPLE_SPLIT > + * tile_split_bytes = clamp(tile_bytes_1x * sample_split_factor, 256, dram_row_size_bytes) > + * tile_bytes = clamp(tile_bytes_1x * num_samples, 64, tile_split_bytes) > + * > + * In both cases, the display block (DCE) has no SAMPLE_SPLIT > + * and just needs the tile split bytes in the GRPH_CONTROL.GRPH_TILE_SPLIT field. > + * To maximize compatibility between GFX6-7, we don't include the SAMPLE_SPLIT > + * in the format modifiers. > + * > + * The actual tile split in bytes is: 64 << field value > + * Possible values of this field: > + * > + * 0 - Tile split is 64 bytes > + * 1 - Tile split is 128 bytes > + * 2 - Tile split is 256 bytes > + * 3 - Tile split is 512 bytes > + * 4 - Tile split is 1 KiB > + * 5 - Tile split is 2 KiB > + * 6 - Tile split is 4 KiB > + */ > +#define AMD_FMT_MOD_TILE_SPLIT_SHIFT 22ULL > +#define AMD_FMT_MOD_TILE_SPLIT_MASK 0x7 > + > +/* > + * BANK_WIDTH, 2 bits. Number of tiles in the X direction in the same bank. > + * Only relevant to Gfx6-8 macro tiled modes. > + * The actual bank width is: 1 << field value > + * Possible values: > + * > + * 0 - bank width is 1 > + * 1 - bank width is 2 > + * 2 - bank width is 4 > + * 3 - bank width is 8 > + */ > +#define AMD_FMT_MOD_BANK_WIDTH_SHIFT 25ULL > +#define AMD_FMT_MOD_BANK_WIDTH_MASK 0x3 > + > +/* > + * BANK_HEIGHT, 2 bits. Number of tiles in the Y direction in the same bank. > + * Only relevant to Gfx6-8 macro tiled modes. > + * The actual bank height is: 1 << field value > + * Possible values: > + * > + * 0 - bank height is 1 > + * 1 - bank height is 2 > + * 2 - bank height is 4 > + * 3 - bank height is 8 > + */ > +#define AMD_FMT_MOD_BANK_HEIGHT_SHIFT 27ULL > +#define AMD_FMT_MOD_BANK_HEIGHT_MASK 0x3 > + > +/* > + * MACRO_TILE_ASPECT, 2 bits. Macro tile aspect ratio. > + * Only relevant to Gfx6-8 macro tiled modes. > + * Possible values: > + * > + * 0 - aspect ratio is 1:1 > + * 1 - aspect ratio is 4:1 > + * 2 - aspect ratio is 16:1 > + * 3 - aspect ratio is 64:1 > + */ > +#define AMD_FMT_MOD_MACRO_TILE_ASPECT_SHIFT 29ULL > +#define AMD_FMT_MOD_MACRO_TILE_ASPECT_MASK 0x3 > + > +/* > + * NUM_BANKS, 2 bits. Number of banks. > + * Only relevant to Gfx6-8 macro tiled modes. > + * The actual number of banks is: 2 << field value > + * Possible values: > + * > + * 0 - number of banks is 2 > + * 1 - number of banks is 4 > + * 2 - number of banks is 8 > + * 3 - number of banks is 16 > + */ > +#define AMD_FMT_MOD_NUM_BANKS_SHIFT 31ULL > +#define AMD_FMT_MOD_NUM_BANKS_MASK 0x3 > + > #define AMD_FMT_MOD_SET(field, value) \ > ((__u64)(value) << AMD_FMT_MOD_##field##_SHIFT) > #define AMD_FMT_MOD_GET(field, value) \