mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 04:50:11 +01:00
amd/common: Add support for modifiers.
Reviewed-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6176>
This commit is contained in:
parent
2cc2b45688
commit
0833dd7d12
4 changed files with 438 additions and 57 deletions
|
|
@ -32,11 +32,13 @@
|
|||
#include "addrlib/src/amdgpu_asic_addr.h"
|
||||
#include "amd_family.h"
|
||||
#include "drm-uapi/amdgpu_drm.h"
|
||||
#include "drm-uapi/drm_fourcc.h"
|
||||
#include "sid.h"
|
||||
#include "util/hash_table.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/simple_mtx.h"
|
||||
#include "util/u_atomic.h"
|
||||
#include "util/format/u_format.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
|
|
@ -326,6 +328,259 @@ static uint32_t *ac_compute_dcc_retile_map(struct ac_addrlib *addrlib,
|
|||
return dcc_retile_map;
|
||||
}
|
||||
|
||||
bool ac_modifier_has_dcc(uint64_t modifier)
|
||||
{
|
||||
return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC, modifier);
|
||||
}
|
||||
|
||||
bool ac_modifier_has_dcc_retile(uint64_t modifier)
|
||||
{
|
||||
return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC_RETILE, modifier);
|
||||
}
|
||||
|
||||
static
|
||||
AddrSwizzleMode ac_modifier_gfx9_swizzle_mode(uint64_t modifier)
|
||||
{
|
||||
if (modifier == DRM_FORMAT_MOD_LINEAR)
|
||||
return ADDR_SW_LINEAR;
|
||||
|
||||
return AMD_FMT_MOD_GET(TILE, modifier);
|
||||
}
|
||||
static void
|
||||
ac_modifier_fill_dcc_params(uint64_t modifier, struct radeon_surf *surf,
|
||||
ADDR2_COMPUTE_SURFACE_INFO_INPUT *surf_info)
|
||||
{
|
||||
assert(ac_modifier_has_dcc(modifier));
|
||||
|
||||
surf_info->flags.metaRbUnaligned = 0;
|
||||
if (AMD_FMT_MOD_GET(DCC_RETILE, modifier)) {
|
||||
surf_info->flags.metaPipeUnaligned = 0;
|
||||
} else {
|
||||
surf_info->flags.metaPipeUnaligned = !AMD_FMT_MOD_GET(DCC_PIPE_ALIGN, modifier);
|
||||
}
|
||||
|
||||
surf->u.gfx9.dcc.independent_64B_blocks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier);
|
||||
surf->u.gfx9.dcc.independent_128B_blocks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_128B, modifier);
|
||||
surf->u.gfx9.dcc.max_compressed_block_size = AMD_FMT_MOD_GET(DCC_MAX_COMPRESSED_BLOCK, modifier);
|
||||
}
|
||||
|
||||
bool ac_is_modifier_supported(const struct radeon_info *info,
|
||||
const struct ac_modifier_options *options,
|
||||
enum pipe_format format,
|
||||
uint64_t modifier)
|
||||
{
|
||||
|
||||
if (util_format_is_compressed(format) ||
|
||||
util_format_is_depth_or_stencil(format) ||
|
||||
util_format_get_blocksize(format) > 8)
|
||||
return false;
|
||||
|
||||
if (info->chip_class < GFX9)
|
||||
return false;
|
||||
|
||||
if(modifier == DRM_FORMAT_MOD_LINEAR)
|
||||
return true;
|
||||
|
||||
if (util_format_get_num_planes(format) > 1)
|
||||
return false;
|
||||
|
||||
uint32_t allowed_swizzles = 0xFFFFFFFF;
|
||||
switch(info->chip_class) {
|
||||
case GFX9:
|
||||
allowed_swizzles = ac_modifier_has_dcc(modifier) ? 0x06000000 : 0x06660660;
|
||||
break;
|
||||
case GFX10:
|
||||
case GFX10_3:
|
||||
allowed_swizzles = ac_modifier_has_dcc(modifier) ? 0x08000000 : 0x0E660660;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!((1u << ac_modifier_gfx9_swizzle_mode(modifier)) & allowed_swizzles))
|
||||
return false;
|
||||
|
||||
if (ac_modifier_has_dcc(modifier)) {
|
||||
if (!info->has_graphics)
|
||||
return false;
|
||||
|
||||
if (!options->dcc)
|
||||
return false;
|
||||
|
||||
if (ac_modifier_has_dcc_retile(modifier) && !options->dcc_retile)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ac_get_supported_modifiers(const struct radeon_info *info,
|
||||
const struct ac_modifier_options *options,
|
||||
enum pipe_format format,
|
||||
unsigned *mod_count,
|
||||
uint64_t *mods)
|
||||
{
|
||||
unsigned current_mod = 0;
|
||||
|
||||
#define ADD_MOD(name) \
|
||||
if (ac_is_modifier_supported(info, options, format, (name))) { \
|
||||
if (mods && current_mod < *mod_count) \
|
||||
mods[current_mod] = (name); \
|
||||
++current_mod; \
|
||||
}
|
||||
|
||||
/* The modifiers have to be added in descending order of estimated
|
||||
* performance. The drivers will prefer modifiers that come earlier
|
||||
* in the list. */
|
||||
switch (info->chip_class) {
|
||||
case GFX9: {
|
||||
unsigned pipe_xor_bits = MIN2(G_0098F8_NUM_PIPES(info->gb_addr_config) +
|
||||
G_0098F8_NUM_SHADER_ENGINES_GFX9(info->gb_addr_config), 8);
|
||||
unsigned bank_xor_bits = MIN2(G_0098F8_NUM_BANKS(info->gb_addr_config), 8 - pipe_xor_bits);
|
||||
unsigned pipes = G_0098F8_NUM_PIPES(info->gb_addr_config);
|
||||
unsigned rb = G_0098F8_NUM_RB_PER_SE(info->gb_addr_config) +
|
||||
G_0098F8_NUM_SHADER_ENGINES_GFX9(info->gb_addr_config);
|
||||
|
||||
uint64_t common_dcc = AMD_FMT_MOD_SET(DCC, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) |
|
||||
AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, info->has_dcc_constant_encode) |
|
||||
AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
|
||||
AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
|
||||
AMD_FMT_MOD_SET(RB, rb);
|
||||
|
||||
ADD_MOD(AMD_FMT_MOD |
|
||||
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D_X) |
|
||||
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
|
||||
AMD_FMT_MOD_SET(DCC_PIPE_ALIGN, 1) |
|
||||
common_dcc |
|
||||
AMD_FMT_MOD_SET(PIPE, pipes))
|
||||
|
||||
ADD_MOD(AMD_FMT_MOD |
|
||||
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
|
||||
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
|
||||
AMD_FMT_MOD_SET(DCC_PIPE_ALIGN, 1) |
|
||||
common_dcc |
|
||||
AMD_FMT_MOD_SET(PIPE, pipes))
|
||||
|
||||
if (util_format_get_blocksize(format) == 4) {
|
||||
if (info->num_render_backends == 1) {
|
||||
ADD_MOD(AMD_FMT_MOD |
|
||||
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
|
||||
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
|
||||
common_dcc);
|
||||
}
|
||||
|
||||
|
||||
ADD_MOD(AMD_FMT_MOD |
|
||||
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
|
||||
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
|
||||
AMD_FMT_MOD_SET(DCC_RETILE, 1) |
|
||||
common_dcc |
|
||||
AMD_FMT_MOD_SET(PIPE, pipes))
|
||||
}
|
||||
|
||||
|
||||
ADD_MOD(AMD_FMT_MOD |
|
||||
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D_X) |
|
||||
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
|
||||
AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
|
||||
AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits));
|
||||
|
||||
ADD_MOD(AMD_FMT_MOD |
|
||||
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
|
||||
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
|
||||
AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
|
||||
AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits));
|
||||
|
||||
ADD_MOD(AMD_FMT_MOD |
|
||||
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) |
|
||||
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
|
||||
|
||||
ADD_MOD(AMD_FMT_MOD |
|
||||
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) |
|
||||
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
|
||||
|
||||
ADD_MOD(DRM_FORMAT_MOD_LINEAR)
|
||||
break;
|
||||
}
|
||||
case GFX10:
|
||||
case GFX10_3: {
|
||||
bool rbplus = info->chip_class >= GFX10_3;
|
||||
unsigned pipe_xor_bits = G_0098F8_NUM_PIPES(info->gb_addr_config);
|
||||
unsigned pkrs = rbplus ? G_0098F8_NUM_PKRS(info->gb_addr_config) : 0;
|
||||
|
||||
unsigned version = rbplus ? AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS : AMD_FMT_MOD_TILE_VER_GFX10;
|
||||
uint64_t common_dcc = AMD_FMT_MOD_SET(TILE_VERSION, version) |
|
||||
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
|
||||
AMD_FMT_MOD_SET(DCC, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
|
||||
AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
|
||||
AMD_FMT_MOD_SET(PACKERS, pkrs);
|
||||
|
||||
ADD_MOD(AMD_FMT_MOD | common_dcc |
|
||||
AMD_FMT_MOD_SET(DCC_PIPE_ALIGN, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B))
|
||||
|
||||
if (info->family == CHIP_NAVI12 || info->family == CHIP_NAVI14 || info->chip_class >= GFX10_3) {
|
||||
bool independent_128b = info->chip_class >= GFX10_3;
|
||||
|
||||
if (info->num_render_backends == 1) {
|
||||
ADD_MOD(AMD_FMT_MOD | common_dcc |
|
||||
AMD_FMT_MOD_SET(DCC_PIPE_ALIGN, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, independent_128b) |
|
||||
AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B))
|
||||
}
|
||||
|
||||
ADD_MOD(AMD_FMT_MOD | common_dcc |
|
||||
AMD_FMT_MOD_SET(DCC_RETILE, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, independent_128b) |
|
||||
AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B))
|
||||
}
|
||||
|
||||
ADD_MOD(AMD_FMT_MOD |
|
||||
AMD_FMT_MOD_SET(TILE_VERSION, version) |
|
||||
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
|
||||
AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
|
||||
AMD_FMT_MOD_SET(PACKERS, pkrs))
|
||||
|
||||
ADD_MOD(AMD_FMT_MOD |
|
||||
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
|
||||
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
|
||||
AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits))
|
||||
|
||||
if (util_format_get_blocksize(format) != 4) {
|
||||
ADD_MOD(AMD_FMT_MOD |
|
||||
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) |
|
||||
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
|
||||
}
|
||||
|
||||
ADD_MOD(AMD_FMT_MOD |
|
||||
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) |
|
||||
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
|
||||
|
||||
ADD_MOD(DRM_FORMAT_MOD_LINEAR)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#undef ADD_MOD
|
||||
|
||||
if (!mods) {
|
||||
*mod_count = current_mod;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool complete = current_mod <= *mod_count;
|
||||
*mod_count = MIN2(*mod_count, current_mod);
|
||||
return complete;
|
||||
}
|
||||
|
||||
static void *ADDR_API allocSysMem(const ADDR_ALLOCSYSMEM_INPUT *pInput)
|
||||
{
|
||||
return malloc(pInput->sizeInBytes);
|
||||
|
|
@ -695,6 +950,13 @@ static bool get_display_flag(const struct ac_surf_config *config, const struct r
|
|||
unsigned num_channels = config->info.num_channels;
|
||||
unsigned bpe = surf->bpe;
|
||||
|
||||
/* With modifiers the kernel is in charge of whether it is displayable.
|
||||
* We need to ensure at least 32 pixels pitch alignment, but this is
|
||||
* always the case when the blocksize >= 4K.
|
||||
*/
|
||||
if (surf->modifier != DRM_FORMAT_MOD_INVALID)
|
||||
return false;
|
||||
|
||||
if (!config->is_3d && !config->is_cube && !(surf->flags & RADEON_SURF_Z_OR_SBUFFER) &&
|
||||
surf->flags & RADEON_SURF_SCANOUT && config->info.samples <= 1 && surf->blk_w <= 2 &&
|
||||
surf->blk_h == 1) {
|
||||
|
|
@ -1497,7 +1759,9 @@ static int gfx9_compute_miptree(struct ac_addrlib *addrlib, const struct radeon_
|
|||
is_dcc_supported_by_CB(info, in->swizzleMode) &&
|
||||
(!in->flags.display ||
|
||||
is_dcc_supported_by_DCN(info, config, surf, !in->flags.metaRbUnaligned,
|
||||
!in->flags.metaPipeUnaligned))) {
|
||||
!in->flags.metaPipeUnaligned)) &&
|
||||
(surf->modifier == DRM_FORMAT_MOD_INVALID ||
|
||||
ac_modifier_has_dcc(surf->modifier))) {
|
||||
ADDR2_COMPUTE_DCCINFO_INPUT din = {0};
|
||||
ADDR2_COMPUTE_DCCINFO_OUTPUT dout = {0};
|
||||
ADDR2_META_MIP_INFO meta_mip_info[RADEON_SURF_MAX_LEVELS] = {0};
|
||||
|
|
@ -1579,7 +1843,8 @@ static int gfx9_compute_miptree(struct ac_addrlib *addrlib, const struct radeon_
|
|||
surf->u.gfx9.dcc_pitch_max = dout.pitch - 1;
|
||||
|
||||
/* Compute displayable DCC. */
|
||||
if (in->flags.display && surf->num_dcc_levels && info->use_display_dcc_with_retile_blit) {
|
||||
if (((in->flags.display && info->use_display_dcc_with_retile_blit) ||
|
||||
ac_modifier_has_dcc_retile(surf->modifier)) && surf->num_dcc_levels) {
|
||||
/* Compute displayable DCC info. */
|
||||
din.dccKeyFlags.pipeAligned = 0;
|
||||
din.dccKeyFlags.rbAligned = 0;
|
||||
|
|
@ -1866,72 +2131,86 @@ static int gfx9_compute_surface(struct ac_addrlib *addrlib, const struct radeon_
|
|||
AddrSurfInfoIn.flags.metaPipeUnaligned = 0;
|
||||
AddrSurfInfoIn.flags.metaRbUnaligned = 0;
|
||||
|
||||
/* Optimal values for the L2 cache. */
|
||||
if (info->chip_class == GFX9) {
|
||||
surf->u.gfx9.dcc.independent_64B_blocks = 1;
|
||||
surf->u.gfx9.dcc.independent_128B_blocks = 0;
|
||||
surf->u.gfx9.dcc.max_compressed_block_size = V_028C78_MAX_BLOCK_SIZE_64B;
|
||||
} else if (info->chip_class >= GFX10) {
|
||||
surf->u.gfx9.dcc.independent_64B_blocks = 0;
|
||||
surf->u.gfx9.dcc.independent_128B_blocks = 1;
|
||||
surf->u.gfx9.dcc.max_compressed_block_size = V_028C78_MAX_BLOCK_SIZE_128B;
|
||||
}
|
||||
|
||||
if (AddrSurfInfoIn.flags.display) {
|
||||
/* The display hardware can only read DCC with RB_ALIGNED=0 and
|
||||
* PIPE_ALIGNED=0. PIPE_ALIGNED really means L2CACHE_ALIGNED.
|
||||
*
|
||||
* The CB block requires RB_ALIGNED=1 except 1 RB chips.
|
||||
* PIPE_ALIGNED is optional, but PIPE_ALIGNED=0 requires L2 flushes
|
||||
* after rendering, so PIPE_ALIGNED=1 is recommended.
|
||||
*/
|
||||
if (info->use_display_dcc_unaligned) {
|
||||
AddrSurfInfoIn.flags.metaPipeUnaligned = 1;
|
||||
AddrSurfInfoIn.flags.metaRbUnaligned = 1;
|
||||
if (ac_modifier_has_dcc(surf->modifier)) {
|
||||
ac_modifier_fill_dcc_params(surf->modifier, surf, &AddrSurfInfoIn);
|
||||
} else {
|
||||
/* Optimal values for the L2 cache. */
|
||||
if (info->chip_class == GFX9) {
|
||||
surf->u.gfx9.dcc.independent_64B_blocks = 1;
|
||||
surf->u.gfx9.dcc.independent_128B_blocks = 0;
|
||||
surf->u.gfx9.dcc.max_compressed_block_size = V_028C78_MAX_BLOCK_SIZE_64B;
|
||||
} else if (info->chip_class >= GFX10) {
|
||||
surf->u.gfx9.dcc.independent_64B_blocks = 0;
|
||||
surf->u.gfx9.dcc.independent_128B_blocks = 1;
|
||||
surf->u.gfx9.dcc.max_compressed_block_size = V_028C78_MAX_BLOCK_SIZE_128B;
|
||||
}
|
||||
|
||||
/* Adjust DCC settings to meet DCN requirements. */
|
||||
if (info->use_display_dcc_unaligned || info->use_display_dcc_with_retile_blit) {
|
||||
/* Only Navi12/14 support independent 64B blocks in L2,
|
||||
* but without DCC image stores.
|
||||
if (AddrSurfInfoIn.flags.display) {
|
||||
/* The display hardware can only read DCC with RB_ALIGNED=0 and
|
||||
* PIPE_ALIGNED=0. PIPE_ALIGNED really means L2CACHE_ALIGNED.
|
||||
*
|
||||
* The CB block requires RB_ALIGNED=1 except 1 RB chips.
|
||||
* PIPE_ALIGNED is optional, but PIPE_ALIGNED=0 requires L2 flushes
|
||||
* after rendering, so PIPE_ALIGNED=1 is recommended.
|
||||
*/
|
||||
if (info->family == CHIP_NAVI12 || info->family == CHIP_NAVI14) {
|
||||
surf->u.gfx9.dcc.independent_64B_blocks = 1;
|
||||
surf->u.gfx9.dcc.independent_128B_blocks = 0;
|
||||
surf->u.gfx9.dcc.max_compressed_block_size = V_028C78_MAX_BLOCK_SIZE_64B;
|
||||
if (info->use_display_dcc_unaligned) {
|
||||
AddrSurfInfoIn.flags.metaPipeUnaligned = 1;
|
||||
AddrSurfInfoIn.flags.metaRbUnaligned = 1;
|
||||
}
|
||||
|
||||
if (info->chip_class >= GFX10_3) {
|
||||
surf->u.gfx9.dcc.independent_64B_blocks = 1;
|
||||
surf->u.gfx9.dcc.independent_128B_blocks = 1;
|
||||
surf->u.gfx9.dcc.max_compressed_block_size = V_028C78_MAX_BLOCK_SIZE_64B;
|
||||
/* Adjust DCC settings to meet DCN requirements. */
|
||||
if (info->use_display_dcc_unaligned || info->use_display_dcc_with_retile_blit) {
|
||||
/* Only Navi12/14 support independent 64B blocks in L2,
|
||||
* but without DCC image stores.
|
||||
*/
|
||||
if (info->family == CHIP_NAVI12 || info->family == CHIP_NAVI14) {
|
||||
surf->u.gfx9.dcc.independent_64B_blocks = 1;
|
||||
surf->u.gfx9.dcc.independent_128B_blocks = 0;
|
||||
surf->u.gfx9.dcc.max_compressed_block_size = V_028C78_MAX_BLOCK_SIZE_64B;
|
||||
}
|
||||
|
||||
if (info->chip_class >= GFX10_3) {
|
||||
surf->u.gfx9.dcc.independent_64B_blocks = 1;
|
||||
surf->u.gfx9.dcc.independent_128B_blocks = 1;
|
||||
surf->u.gfx9.dcc.max_compressed_block_size = V_028C78_MAX_BLOCK_SIZE_64B;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case RADEON_SURF_MODE_LINEAR_ALIGNED:
|
||||
assert(config->info.samples <= 1);
|
||||
assert(!(surf->flags & RADEON_SURF_Z_OR_SBUFFER));
|
||||
AddrSurfInfoIn.swizzleMode = ADDR_SW_LINEAR;
|
||||
break;
|
||||
|
||||
case RADEON_SURF_MODE_1D:
|
||||
case RADEON_SURF_MODE_2D:
|
||||
if (surf->flags & RADEON_SURF_IMPORTED ||
|
||||
(info->chip_class >= GFX10 && surf->flags & RADEON_SURF_FORCE_SWIZZLE_MODE)) {
|
||||
AddrSurfInfoIn.swizzleMode = surf->u.gfx9.surf.swizzle_mode;
|
||||
if (surf->modifier == DRM_FORMAT_MOD_INVALID) {
|
||||
switch (mode) {
|
||||
case RADEON_SURF_MODE_LINEAR_ALIGNED:
|
||||
assert(config->info.samples <= 1);
|
||||
assert(!(surf->flags & RADEON_SURF_Z_OR_SBUFFER));
|
||||
AddrSurfInfoIn.swizzleMode = ADDR_SW_LINEAR;
|
||||
break;
|
||||
|
||||
case RADEON_SURF_MODE_1D:
|
||||
case RADEON_SURF_MODE_2D:
|
||||
if (surf->flags & RADEON_SURF_IMPORTED ||
|
||||
(info->chip_class >= GFX10 && surf->flags & RADEON_SURF_FORCE_SWIZZLE_MODE)) {
|
||||
AddrSurfInfoIn.swizzleMode = surf->u.gfx9.surf.swizzle_mode;
|
||||
break;
|
||||
}
|
||||
|
||||
r = gfx9_get_preferred_swizzle_mode(addrlib->handle, surf, &AddrSurfInfoIn, false,
|
||||
&AddrSurfInfoIn.swizzleMode);
|
||||
if (r)
|
||||
return r;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
} else {
|
||||
/* We have a valid and required modifier here. */
|
||||
|
||||
r = gfx9_get_preferred_swizzle_mode(addrlib->handle, surf, &AddrSurfInfoIn, false,
|
||||
&AddrSurfInfoIn.swizzleMode);
|
||||
if (r)
|
||||
return r;
|
||||
break;
|
||||
assert(!compressed);
|
||||
assert(!ac_modifier_has_dcc(surf->modifier) ||
|
||||
!(surf->flags & RADEON_SURF_DISABLE_DCC));
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
AddrSurfInfoIn.swizzleMode = ac_modifier_gfx9_swizzle_mode(surf->modifier);
|
||||
}
|
||||
|
||||
surf->u.gfx9.resource_type = AddrSurfInfoIn.resourceType;
|
||||
|
|
@ -2013,7 +2292,9 @@ static int gfx9_compute_surface(struct ac_addrlib *addrlib, const struct radeon_
|
|||
AddrSurfInfoIn.flags.color && !surf->is_linear &&
|
||||
surf->surf_alignment >= 64 * 1024 && /* 64KB tiling */
|
||||
!(surf->flags & (RADEON_SURF_DISABLE_DCC | RADEON_SURF_FORCE_SWIZZLE_MODE |
|
||||
RADEON_SURF_FORCE_MICRO_TILE_MODE))) {
|
||||
RADEON_SURF_FORCE_MICRO_TILE_MODE)) &&
|
||||
(surf->modifier == DRM_FORMAT_MOD_INVALID ||
|
||||
ac_modifier_has_dcc(surf->modifier))) {
|
||||
/* Validate that DCC is enabled if DCN can do it. */
|
||||
if ((info->use_display_dcc_unaligned || info->use_display_dcc_with_retile_blit) &&
|
||||
AddrSurfInfoIn.flags.display && surf->bpe == 4) {
|
||||
|
|
@ -2316,6 +2597,9 @@ bool ac_surface_set_umd_metadata(const struct radeon_info *info, struct radeon_s
|
|||
uint32_t *desc = &metadata[2];
|
||||
uint64_t offset;
|
||||
|
||||
if (surf->modifier != DRM_FORMAT_MOD_INVALID)
|
||||
return true;
|
||||
|
||||
if (info->chip_class >= GFX9)
|
||||
offset = surf->u.gfx9.surf_offset;
|
||||
else
|
||||
|
|
@ -2492,3 +2776,61 @@ void ac_surface_override_offset_stride(const struct radeon_info *info, struct ra
|
|||
if (surf->display_dcc_offset)
|
||||
surf->display_dcc_offset += offset;
|
||||
}
|
||||
|
||||
unsigned ac_surface_get_nplanes(const struct radeon_surf *surf)
|
||||
{
|
||||
if (surf->modifier == DRM_FORMAT_MOD_INVALID)
|
||||
return 1;
|
||||
else if (surf->display_dcc_offset)
|
||||
return 3;
|
||||
else if (surf->dcc_offset)
|
||||
return 2;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint64_t ac_surface_get_plane_offset(enum chip_class chip_class,
|
||||
const struct radeon_surf *surf,
|
||||
unsigned plane, unsigned layer)
|
||||
{
|
||||
switch (plane) {
|
||||
case 0:
|
||||
if (chip_class >= GFX9) {
|
||||
return surf->u.gfx9.surf_offset +
|
||||
layer * surf->u.gfx9.surf_slice_size;
|
||||
} else {
|
||||
return surf->u.legacy.level[0].offset +
|
||||
layer * (uint64_t)surf->u.legacy.level[0].slice_size_dw * 4;
|
||||
}
|
||||
case 1:
|
||||
assert(!layer);
|
||||
return surf->display_dcc_offset ?
|
||||
surf->display_dcc_offset : surf->dcc_offset;
|
||||
case 2:
|
||||
assert(!layer);
|
||||
return surf->dcc_offset;
|
||||
default:
|
||||
unreachable("Invalid plane index");
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t ac_surface_get_plane_stride(enum chip_class chip_class,
|
||||
const struct radeon_surf *surf,
|
||||
unsigned plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case 0:
|
||||
if (chip_class >= GFX9) {
|
||||
return surf->u.gfx9.surf_pitch * surf->bpe;
|
||||
} else {
|
||||
return surf->u.legacy.level[0].nblk_x * surf->bpe;
|
||||
}
|
||||
case 1:
|
||||
return 1 + (surf->display_dcc_offset ?
|
||||
surf->u.gfx9.display_dcc_pitch_max : surf->u.gfx9.dcc_pitch_max);
|
||||
case 2:
|
||||
return surf->u.gfx9.dcc_pitch_max + 1;
|
||||
default:
|
||||
unreachable("Invalid plane index");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#define AC_SURFACE_H
|
||||
|
||||
#include "amd_family.h"
|
||||
#include "util/format/u_format.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
|
@ -207,6 +208,12 @@ struct radeon_surf {
|
|||
unsigned micro_tile_mode : 3;
|
||||
uint32_t flags;
|
||||
|
||||
/*
|
||||
* DRM format modifier. Set to DRM_FORMAT_MOD_INVALID to have addrlib
|
||||
* select tiling parameters instead.
|
||||
*/
|
||||
uint64_t modifier;
|
||||
|
||||
/* These are return values. Some of them can be set by the caller, but
|
||||
* they will be treated as hints (e.g. bankw, bankh) and might be
|
||||
* changed by the calculator.
|
||||
|
|
@ -313,6 +320,32 @@ void ac_surface_get_umd_metadata(const struct radeon_info *info, struct radeon_s
|
|||
void ac_surface_override_offset_stride(const struct radeon_info *info, struct radeon_surf *surf,
|
||||
unsigned num_mipmap_levels, uint64_t offset, unsigned pitch);
|
||||
|
||||
|
||||
struct ac_modifier_options {
|
||||
bool dcc; /* Whether to allow DCC. */
|
||||
bool dcc_retile; /* Whether to allow use of a DCC retile map. */
|
||||
};
|
||||
|
||||
bool ac_is_modifier_supported(const struct radeon_info *info,
|
||||
const struct ac_modifier_options *options,
|
||||
enum pipe_format format,
|
||||
uint64_t modifier);
|
||||
bool ac_get_supported_modifiers(const struct radeon_info *info,
|
||||
const struct ac_modifier_options *options,
|
||||
enum pipe_format format,
|
||||
unsigned *mod_count,
|
||||
uint64_t *mods);
|
||||
bool ac_modifier_has_dcc(uint64_t modifier);
|
||||
bool ac_modifier_has_dcc_retile(uint64_t modifier);
|
||||
|
||||
unsigned ac_surface_get_nplanes(const struct radeon_surf *surf);
|
||||
uint64_t ac_surface_get_plane_offset(enum chip_class chip_class,
|
||||
const struct radeon_surf *surf,
|
||||
unsigned plane, unsigned layer);
|
||||
uint64_t ac_surface_get_plane_stride(enum chip_class chip_class,
|
||||
const struct radeon_surf *surf,
|
||||
unsigned plane);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <libdrm/drm_fourcc.h>
|
||||
|
||||
#include "radv_debug.h"
|
||||
#include "radv_private.h"
|
||||
#include "vk_format.h"
|
||||
|
|
@ -452,7 +454,6 @@ radv_get_surface_flags(struct radv_device *device,
|
|||
is_depth = vk_format_has_depth(desc);
|
||||
is_stencil = vk_format_has_stencil(desc);
|
||||
|
||||
|
||||
flags = RADEON_SURF_SET(array_mode, MODE);
|
||||
|
||||
switch (pCreateInfo->imageType){
|
||||
|
|
@ -1317,9 +1318,11 @@ radv_image_reset_layout(struct radv_image *image)
|
|||
VkFormat format = vk_format_get_plane_format(image->vk_format, i);
|
||||
|
||||
uint32_t flags = image->planes[i].surface.flags;
|
||||
uint64_t modifier = image->planes[i].surface.modifier;
|
||||
memset(image->planes + i, 0, sizeof(image->planes[i]));
|
||||
|
||||
image->planes[i].surface.flags = flags;
|
||||
image->planes[i].surface.modifier = modifier;
|
||||
image->planes[i].surface.blk_w = vk_format_get_blockwidth(format);
|
||||
image->planes[i].surface.blk_h = vk_format_get_blockheight(format);
|
||||
image->planes[i].surface.bpe = vk_format_get_blocksize(vk_format_depth_only(format));
|
||||
|
|
@ -1474,6 +1477,7 @@ radv_image_create(VkDevice _device,
|
|||
for (unsigned plane = 0; plane < image->plane_count; ++plane) {
|
||||
image->planes[plane].surface.flags =
|
||||
radv_get_surface_flags(device, image, plane, pCreateInfo, format);
|
||||
image->planes[plane].surface.modifier = DRM_FORMAT_MOD_INVALID;
|
||||
}
|
||||
|
||||
bool delay_layout = external_info &&
|
||||
|
|
|
|||
|
|
@ -316,6 +316,8 @@ static int si_init_surface(struct si_screen *sscreen, struct radeon_surf *surfac
|
|||
surface->u.gfx9.surf.swizzle_mode = ADDR_SW_64KB_R_X;
|
||||
}
|
||||
|
||||
surface->modifier = DRM_FORMAT_MOD_INVALID;
|
||||
|
||||
r = sscreen->ws->surface_init(sscreen->ws, ptex, flags, bpe, array_mode, surface);
|
||||
if (r) {
|
||||
return r;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue