xf86drm: print AMD modifiers properly

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
This commit is contained in:
Marek Olšák 2024-09-23 17:20:52 -04:00
parent c0a08f06ae
commit 50da61eebd

281
xf86drm.c
View file

@ -201,18 +201,6 @@ static const struct drmFormatVendorModifierInfo arm_mode_value_table[] = {
{ AFBC_FORMAT_MOD_USM, "USM" }, { AFBC_FORMAT_MOD_USM, "USM" },
}; };
static bool is_x_t_amd_gfx9_tile(uint64_t tile)
{
switch (tile) {
case AMD_FMT_MOD_TILE_GFX9_64K_S_X:
case AMD_FMT_MOD_TILE_GFX9_64K_D_X:
case AMD_FMT_MOD_TILE_GFX9_64K_R_X:
return true;
}
return false;
}
static bool static bool
drmGetAfbcFormatModifierNameFromArm(uint64_t modifier, FILE *fp) drmGetAfbcFormatModifierNameFromArm(uint64_t modifier, FILE *fp)
{ {
@ -368,22 +356,142 @@ drmGetFormatModifierNameFromNvidia(uint64_t modifier)
return NULL; return NULL;
} }
static void static char *
drmGetFormatModifierNameFromAmdDcc(uint64_t modifier, FILE *fp) drmGetFormatModifierNameFromAmd(uint64_t modifier)
{ {
uint64_t dcc_max_compressed_block = static const char *gfx9_gfx11_tile_strings[32] = {
AMD_FMT_MOD_GET(DCC_MAX_COMPRESSED_BLOCK, modifier); "LINEAR",
uint64_t dcc_retile = AMD_FMT_MOD_GET(DCC_RETILE, modifier); "256B_S",
"256B_D",
"256B_R",
"4KB_Z",
"4KB_S",
"4KB_D",
"4KB_R",
"64KB_Z",
"64KB_S",
"64KB_D",
"64KB_R",
"INVALID12",
"INVALID13",
"INVALID14",
"INVALID15",
"64KB_Z_T",
"64KB_S_T",
"64KB_D_T",
"64KB_R_T",
"4KB_Z_X",
"4KB_S_X",
"4KB_D_X",
"4KB_R_X",
"64KB_Z_X",
"64KB_S_X",
"64KB_D_X",
"64KB_R_X",
"256KB_Z_X",
"256KB_S_X",
"256KB_D_X",
"256KB_R_X",
};
static const char *gfx12_tile_strings[32] = {
"LINEAR",
"256B_2D",
"4KB_2D",
"64KB_2D",
"256KB_2D",
"4KB_3D",
"64KB_3D",
"256KB_3D",
/* other values are unused */
};
uint64_t tile_version = AMD_FMT_MOD_GET(TILE_VERSION, modifier);
FILE *fp;
char *mod_amd = NULL;
size_t size = 0;
const char *dcc_max_compressed_block_str = NULL; fp = open_memstream(&mod_amd, &size);
if (!fp)
return NULL;
fprintf(fp, ",DCC"); switch (tile_version) {
case AMD_FMT_MOD_TILE_VER_GFX9:
fprintf(fp, "GFX9");
break;
case AMD_FMT_MOD_TILE_VER_GFX10:
fprintf(fp, "GFX10");
break;
case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
fprintf(fp, "GFX10_RBPLUS");
break;
case AMD_FMT_MOD_TILE_VER_GFX11:
fprintf(fp, "GFX11");
break;
case AMD_FMT_MOD_TILE_VER_GFX12:
fprintf(fp, "GFX12");
break;
default:
fclose(fp);
free(mod_amd);
return NULL;
}
if (dcc_retile) if (tile_version >= AMD_FMT_MOD_TILE_VER_GFX12) {
fprintf(fp, ",DCC_RETILE"); unsigned tile = AMD_FMT_MOD_GET(TILE, modifier);
if (!dcc_retile && AMD_FMT_MOD_GET(DCC_PIPE_ALIGN, modifier)) fprintf(fp, ",%s", gfx12_tile_strings[tile]);
fprintf(fp, ",DCC_PIPE_ALIGN");
if (AMD_FMT_MOD_GET(DCC, modifier)) {
fprintf(fp, ",DCC,DCC_MAX_COMPRESSED_BLOCK=%uB",
64 << AMD_FMT_MOD_GET(DCC_MAX_COMPRESSED_BLOCK, modifier));
/* Other DCC fields are unused by GFX12. */
}
} else {
unsigned tile = AMD_FMT_MOD_GET(TILE, modifier);
fprintf(fp, ",%s", gfx9_gfx11_tile_strings[tile]);
/* All *_T and *_X modes are affected by chip-specific fields. */
if (tile >= 16) {
fprintf(fp, ",PIPE_XOR_BITS=%u",
(unsigned)AMD_FMT_MOD_GET(PIPE_XOR_BITS, modifier));
switch (tile_version) {
case AMD_FMT_MOD_TILE_VER_GFX9:
fprintf(fp, ",BANK_XOR_BITS=%u",
(unsigned)AMD_FMT_MOD_GET(BANK_XOR_BITS, modifier));
break;
case AMD_FMT_MOD_TILE_VER_GFX10:
/* Nothing else for GFX10. */
break;
case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
case AMD_FMT_MOD_TILE_VER_GFX11:
/* This also determines the DCC layout, but DCC is only legal
* with tile=27 and tile=31 (*_R_X modes).
*/
fprintf(fp, ",PACKERS=%u",
(unsigned)AMD_FMT_MOD_GET(PACKERS, modifier));
break;
}
}
if (AMD_FMT_MOD_GET(DCC, modifier)) {
if (tile_version == AMD_FMT_MOD_TILE_VER_GFX9 &&
(AMD_FMT_MOD_GET(DCC_PIPE_ALIGN, modifier) ||
AMD_FMT_MOD_GET(DCC_RETILE, modifier))) {
/* These two only determine the layout of
* the non-displayable DCC plane.
*/
fprintf(fp, ",RB=%u",
(unsigned)AMD_FMT_MOD_GET(RB, modifier));
fprintf(fp, ",PIPE=%u",
(unsigned)AMD_FMT_MOD_GET(PIPE, modifier));
}
fprintf(fp, ",DCC,DCC_MAX_COMPRESSED_BLOCK=%uB",
64 << AMD_FMT_MOD_GET(DCC_MAX_COMPRESSED_BLOCK, modifier));
if (AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier)) if (AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier))
fprintf(fp, ",DCC_INDEPENDENT_64B"); fprintf(fp, ",DCC_INDEPENDENT_64B");
@ -391,136 +499,17 @@ drmGetFormatModifierNameFromAmdDcc(uint64_t modifier, FILE *fp)
if (AMD_FMT_MOD_GET(DCC_INDEPENDENT_128B, modifier)) if (AMD_FMT_MOD_GET(DCC_INDEPENDENT_128B, modifier))
fprintf(fp, ",DCC_INDEPENDENT_128B"); fprintf(fp, ",DCC_INDEPENDENT_128B");
switch (dcc_max_compressed_block) {
case AMD_FMT_MOD_DCC_BLOCK_64B:
dcc_max_compressed_block_str = "64B";
break;
case AMD_FMT_MOD_DCC_BLOCK_128B:
dcc_max_compressed_block_str = "128B";
break;
case AMD_FMT_MOD_DCC_BLOCK_256B:
dcc_max_compressed_block_str = "256B";
break;
}
if (dcc_max_compressed_block_str)
fprintf(fp, ",DCC_MAX_COMPRESSED_BLOCK=%s",
dcc_max_compressed_block_str);
if (AMD_FMT_MOD_GET(DCC_CONSTANT_ENCODE, modifier)) if (AMD_FMT_MOD_GET(DCC_CONSTANT_ENCODE, modifier))
fprintf(fp, ",DCC_CONSTANT_ENCODE"); fprintf(fp, ",DCC_CONSTANT_ENCODE");
}
static void if (AMD_FMT_MOD_GET(DCC_PIPE_ALIGN, modifier))
drmGetFormatModifierNameFromAmdTile(uint64_t modifier, FILE *fp) fprintf(fp, ",DCC_PIPE_ALIGN");
{
uint64_t pipe_xor_bits, bank_xor_bits, packers, rb;
uint64_t pipe, pipe_align, dcc, dcc_retile, tile_version;
pipe_align = AMD_FMT_MOD_GET(DCC_PIPE_ALIGN, modifier); if (AMD_FMT_MOD_GET(DCC_RETILE, modifier))
pipe_xor_bits = AMD_FMT_MOD_GET(PIPE_XOR_BITS, modifier); fprintf(fp, ",DCC_RETILE");
dcc = AMD_FMT_MOD_GET(DCC, modifier);
dcc_retile = AMD_FMT_MOD_GET(DCC_RETILE, modifier);
tile_version = AMD_FMT_MOD_GET(TILE_VERSION, modifier);
fprintf(fp, ",PIPE_XOR_BITS=%"PRIu64, pipe_xor_bits);
if (tile_version == AMD_FMT_MOD_TILE_VER_GFX9) {
bank_xor_bits = AMD_FMT_MOD_GET(BANK_XOR_BITS, modifier);
fprintf(fp, ",BANK_XOR_BITS=%"PRIu64, bank_xor_bits);
}
if (tile_version == AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) {
packers = AMD_FMT_MOD_GET(PACKERS, modifier);
fprintf(fp, ",PACKERS=%"PRIu64, packers);
}
if (dcc && tile_version == AMD_FMT_MOD_TILE_VER_GFX9) {
rb = AMD_FMT_MOD_GET(RB, modifier);
fprintf(fp, ",RB=%"PRIu64, rb);
}
if (dcc && tile_version == AMD_FMT_MOD_TILE_VER_GFX9 &&
(dcc_retile || pipe_align)) {
pipe = AMD_FMT_MOD_GET(PIPE, modifier);
fprintf(fp, ",PIPE_%"PRIu64, pipe);
} }
} }
static char *
drmGetFormatModifierNameFromAmd(uint64_t modifier)
{
uint64_t tile, tile_version, dcc;
FILE *fp;
char *mod_amd = NULL;
size_t size = 0;
const char *str_tile = NULL;
const char *str_tile_version = NULL;
tile = AMD_FMT_MOD_GET(TILE, modifier);
tile_version = AMD_FMT_MOD_GET(TILE_VERSION, modifier);
dcc = AMD_FMT_MOD_GET(DCC, modifier);
fp = open_memstream(&mod_amd, &size);
if (!fp)
return NULL;
/* add tile */
switch (tile_version) {
case AMD_FMT_MOD_TILE_VER_GFX9:
str_tile_version = "GFX9";
break;
case AMD_FMT_MOD_TILE_VER_GFX10:
str_tile_version = "GFX10";
break;
case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
str_tile_version = "GFX10_RBPLUS";
break;
case AMD_FMT_MOD_TILE_VER_GFX11:
str_tile_version = "GFX11";
break;
}
if (str_tile_version) {
fprintf(fp, "%s", str_tile_version);
} else {
fclose(fp);
free(mod_amd);
return NULL;
}
/* add tile str */
switch (tile) {
case AMD_FMT_MOD_TILE_GFX9_64K_S:
str_tile = "GFX9_64K_S";
break;
case AMD_FMT_MOD_TILE_GFX9_64K_D:
str_tile = "GFX9_64K_D";
break;
case AMD_FMT_MOD_TILE_GFX9_64K_S_X:
str_tile = "GFX9_64K_S_X";
break;
case AMD_FMT_MOD_TILE_GFX9_64K_D_X:
str_tile = "GFX9_64K_D_X";
break;
case AMD_FMT_MOD_TILE_GFX9_64K_R_X:
str_tile = "GFX9_64K_R_X";
break;
case AMD_FMT_MOD_TILE_GFX11_256K_R_X:
str_tile = "GFX11_256K_R_X";
break;
}
if (str_tile)
fprintf(fp, ",%s", str_tile);
if (dcc)
drmGetFormatModifierNameFromAmdDcc(modifier, fp);
if (tile_version >= AMD_FMT_MOD_TILE_VER_GFX9 && is_x_t_amd_gfx9_tile(tile))
drmGetFormatModifierNameFromAmdTile(modifier, fp);
fclose(fp); fclose(fp);
return mod_amd; return mod_amd;
} }