#define CIASICIDGFXENGINE_ARCTICISLAND 0x0000000D
#endif
-static unsigned get_first(unsigned x, unsigned y)
-{
- return x;
-}
-
-static void addrlib_family_rev_id(enum radeon_family family,
- unsigned *addrlib_family,
- unsigned *addrlib_revid)
-{
- switch (family) {
- case CHIP_TAHITI:
- *addrlib_family = FAMILY_SI;
- *addrlib_revid = get_first(AMDGPU_TAHITI_RANGE);
- break;
- case CHIP_PITCAIRN:
- *addrlib_family = FAMILY_SI;
- *addrlib_revid = get_first(AMDGPU_PITCAIRN_RANGE);
- break;
- case CHIP_VERDE:
- *addrlib_family = FAMILY_SI;
- *addrlib_revid = get_first(AMDGPU_CAPEVERDE_RANGE);
- break;
- case CHIP_OLAND:
- *addrlib_family = FAMILY_SI;
- *addrlib_revid = get_first(AMDGPU_OLAND_RANGE);
- break;
- case CHIP_HAINAN:
- *addrlib_family = FAMILY_SI;
- *addrlib_revid = get_first(AMDGPU_HAINAN_RANGE);
- break;
- case CHIP_BONAIRE:
- *addrlib_family = FAMILY_CI;
- *addrlib_revid = get_first(AMDGPU_BONAIRE_RANGE);
- break;
- case CHIP_KAVERI:
- *addrlib_family = FAMILY_KV;
- *addrlib_revid = get_first(AMDGPU_SPECTRE_RANGE);
- break;
- case CHIP_KABINI:
- *addrlib_family = FAMILY_KV;
- *addrlib_revid = get_first(AMDGPU_KALINDI_RANGE);
- break;
- case CHIP_HAWAII:
- *addrlib_family = FAMILY_CI;
- *addrlib_revid = get_first(AMDGPU_HAWAII_RANGE);
- break;
- case CHIP_MULLINS:
- *addrlib_family = FAMILY_KV;
- *addrlib_revid = get_first(AMDGPU_GODAVARI_RANGE);
- break;
- case CHIP_TONGA:
- *addrlib_family = FAMILY_VI;
- *addrlib_revid = get_first(AMDGPU_TONGA_RANGE);
- break;
- case CHIP_ICELAND:
- *addrlib_family = FAMILY_VI;
- *addrlib_revid = get_first(AMDGPU_ICELAND_RANGE);
- break;
- case CHIP_CARRIZO:
- *addrlib_family = FAMILY_CZ;
- *addrlib_revid = get_first(AMDGPU_CARRIZO_RANGE);
- break;
- case CHIP_STONEY:
- *addrlib_family = FAMILY_CZ;
- *addrlib_revid = get_first(AMDGPU_STONEY_RANGE);
- break;
- case CHIP_FIJI:
- *addrlib_family = FAMILY_VI;
- *addrlib_revid = get_first(AMDGPU_FIJI_RANGE);
- break;
- case CHIP_POLARIS10:
- *addrlib_family = FAMILY_VI;
- *addrlib_revid = get_first(AMDGPU_POLARIS10_RANGE);
- break;
- case CHIP_POLARIS11:
- *addrlib_family = FAMILY_VI;
- *addrlib_revid = get_first(AMDGPU_POLARIS11_RANGE);
- break;
- case CHIP_POLARIS12:
- *addrlib_family = FAMILY_VI;
- *addrlib_revid = get_first(AMDGPU_POLARIS12_RANGE);
- break;
- case CHIP_VEGAM:
- *addrlib_family = FAMILY_VI;
- *addrlib_revid = get_first(AMDGPU_VEGAM_RANGE);
- break;
- case CHIP_VEGA10:
- *addrlib_family = FAMILY_AI;
- *addrlib_revid = get_first(AMDGPU_VEGA10_RANGE);
- break;
- case CHIP_VEGA12:
- *addrlib_family = FAMILY_AI;
- *addrlib_revid = get_first(AMDGPU_VEGA12_RANGE);
- break;
- case CHIP_VEGA20:
- *addrlib_family = FAMILY_AI;
- *addrlib_revid = get_first(AMDGPU_VEGA20_RANGE);
- break;
- case CHIP_RAVEN:
- *addrlib_family = FAMILY_RV;
- *addrlib_revid = get_first(AMDGPU_RAVEN_RANGE);
- break;
- case CHIP_RAVEN2:
- *addrlib_family = FAMILY_RV;
- *addrlib_revid = get_first(AMDGPU_RAVEN2_RANGE);
- break;
- default:
- fprintf(stderr, "amdgpu: Unknown family.\n");
- }
-}
-
static void *ADDR_API allocSysMem(const ADDR_ALLOCSYSMEM_INPUT * pInput)
{
return malloc(pInput->sizeInBytes);
ADDR_CREATE_OUTPUT addrCreateOutput = {0};
ADDR_REGISTER_VALUE regValue = {0};
ADDR_CREATE_FLAGS createFlags = {{0}};
- ADDR_GET_MAX_ALINGMENTS_OUTPUT addrGetMaxAlignmentsOutput = {0};
+ ADDR_GET_MAX_ALIGNMENTS_OUTPUT addrGetMaxAlignmentsOutput = {0};
ADDR_E_RETURNCODE addrRet;
addrCreateInput.size = sizeof(ADDR_CREATE_INPUT);
regValue.gbAddrConfig = amdinfo->gb_addr_cfg;
createFlags.value = 0;
- addrlib_family_rev_id(info->family, &addrCreateInput.chipFamily, &addrCreateInput.chipRevision);
+ addrCreateInput.chipFamily = info->family_id;
+ addrCreateInput.chipRevision = info->chip_external_rev;
+
if (addrCreateInput.chipFamily == FAMILY_UNKNOWN)
return NULL;
surf_level->dcc_fast_clear_size = AddrDccOut->dccFastClearSize;
else
surf_level->dcc_fast_clear_size = 0;
+
+ /* Compute the DCC slice size because addrlib doesn't
+ * provide this info. As DCC memory is linear (each
+ * slice is the same size) it's easy to compute.
+ */
+ surf->dcc_slice_size = AddrDccOut->dccRamSize / config->info.array_size;
+
+ /* For arrays, we have to compute the DCC info again
+ * with one slice size to get a correct fast clear
+ * size.
+ */
+ if (config->info.array_size > 1) {
+ AddrDccIn->colorSurfSize = AddrSurfInfoOut->sliceSize;
+ AddrDccIn->tileMode = AddrSurfInfoOut->tileMode;
+ AddrDccIn->tileInfo = *AddrSurfInfoOut->pTileInfo;
+ AddrDccIn->tileIndex = AddrSurfInfoOut->tileIndex;
+ AddrDccIn->macroModeIndex = AddrSurfInfoOut->macroModeIndex;
+
+ ret = AddrComputeDccInfo(addrlib,
+ AddrDccIn, AddrDccOut);
+ if (ret == ADDR_OK) {
+ /* If the DCC memory isn't properly
+ * aligned, the data are interleaved
+ * accross slices.
+ */
+ if (AddrDccOut->dccRamSizeAligned)
+ surf_level->dcc_slice_fast_clear_size = AddrDccOut->dccFastClearSize;
+ else
+ surf_level->dcc_slice_fast_clear_size = 0;
+ }
+ } else {
+ surf_level->dcc_slice_fast_clear_size = surf_level->dcc_fast_clear_size;
+ }
}
}
- /* TC-compatible HTILE. */
+ /* HTILE. */
if (!is_stencil &&
AddrSurfInfoIn->flags.depth &&
surf_level->mode == RADEON_SURF_MODE_2D &&
- level == 0) {
+ level == 0 &&
+ !(surf->flags & RADEON_SURF_NO_HTILE)) {
AddrHtileIn->flags.tcCompatible = AddrSurfInfoIn->flags.tcCompatible;
AddrHtileIn->pitch = AddrSurfInfoOut->pitch;
AddrHtileIn->height = AddrSurfInfoOut->height;
{
uint32_t tile_mode = info->si_tile_mode_array[surf->u.legacy.tiling_index[0]];
- if (info->chip_class >= CIK)
+ if (info->chip_class >= GFX7)
surf->micro_tile_mode = G_009910_MICRO_TILE_MODE_NEW(tile_mode);
else
surf->micro_tile_mode = G_009910_MICRO_TILE_MODE(tile_mode);
}
/* Compute tile swizzle. */
- /* TODO: fix tile swizzle with mipmapping for SI */
- if ((info->chip_class >= CIK || config->info.levels == 1) &&
+ /* TODO: fix tile swizzle with mipmapping for GFX6 */
+ if ((info->chip_class >= GFX7 || config->info.levels == 1) &&
config->info.surf_index &&
surf->u.legacy.level[0].mode == RADEON_SURF_MODE_2D &&
!(surf->flags & (RADEON_SURF_Z_OR_SBUFFER | RADEON_SURF_SHAREABLE)) &&
return 0;
}
-void ac_compute_cmask(const struct radeon_info *info,
- const struct ac_surf_config *config,
- struct radeon_surf *surf)
+static void ac_compute_cmask(const struct radeon_info *info,
+ const struct ac_surf_config *config,
+ struct radeon_surf *surf)
{
unsigned pipe_interleave_bytes = info->pipe_interleave_bytes;
unsigned num_pipes = info->num_tile_pipes;
unsigned cl_width, cl_height;
- if (surf->flags & RADEON_SURF_Z_OR_SBUFFER)
+ if (surf->flags & RADEON_SURF_Z_OR_SBUFFER ||
+ (config->info.samples >= 2 && !surf->fmask_size))
return;
- assert(info->chip_class <= VI);
+ assert(info->chip_class <= GFX8);
switch (num_pipes) {
case 2:
num_layers = config->info.array_size;
surf->cmask_alignment = MAX2(256, base_align);
- surf->cmask_size = align(slice_bytes, base_align) * num_layers;
+ surf->cmask_slice_size = align(slice_bytes, base_align);
+ surf->cmask_size = surf->cmask_slice_size * num_layers;
}
/**
* driver team).
*/
AddrSurfInfoIn.flags.dccCompatible =
- info->chip_class >= VI &&
+ info->chip_class >= GFX8 &&
+ info->has_graphics && /* disable DCC on compute-only chips */
!(surf->flags & RADEON_SURF_Z_OR_SBUFFER) &&
!(surf->flags & RADEON_SURF_DISABLE_DCC) &&
!compressed &&
AddrSurfInfoIn.flags.noStencil = (surf->flags & RADEON_SURF_SBUFFER) == 0;
AddrSurfInfoIn.flags.compressZ = !!(surf->flags & RADEON_SURF_Z_OR_SBUFFER);
- /* On CI/VI, the DB uses the same pitch and tile mode (except tilesplit)
+ /* On GFX7-GFX8, the DB uses the same pitch and tile mode (except tilesplit)
* for Z and stencil. This can cause a number of problems which we work
* around here:
*
assert(!(surf->flags & RADEON_SURF_Z_OR_SBUFFER));
assert(AddrSurfInfoIn.tileMode == ADDR_TM_2D_TILED_THIN1);
- if (info->chip_class == SI) {
+ if (info->chip_class == GFX6) {
if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE) {
if (surf->bpe == 2)
AddrSurfInfoIn.tileIndex = 11; /* 16bpp */
AddrSurfInfoIn.tileIndex = 17; /* 64bpp (and 128bpp) */
}
} else {
- /* CIK - VI */
+ /* GFX7 - GFX8 */
if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE)
AddrSurfInfoIn.tileIndex = 10; /* 2D displayable */
else
}
/* Compute FMASK. */
- if (config->info.samples >= 2 && AddrSurfInfoIn.flags.color) {
+ if (config->info.samples >= 2 && AddrSurfInfoIn.flags.color &&
+ info->has_graphics && !(surf->flags & RADEON_SURF_NO_FMASK)) {
ADDR_COMPUTE_FMASK_INFO_INPUT fin = {0};
ADDR_COMPUTE_FMASK_INFO_OUTPUT fout = {0};
ADDR_TILEINFO fmask_tile_info = {};
surf->u.legacy.fmask.tiling_index = fout.tileIndex;
surf->u.legacy.fmask.bankh = fout.pTileInfo->bankHeight;
surf->u.legacy.fmask.pitch_in_pixels = fout.pitch;
+ surf->u.legacy.fmask.slice_size = fout.sliceSize;
/* Compute tile swizzle for FMASK. */
if (config->info.fmask_surf_index &&
/* TODO: We could allow some of these: */
sin.forbiddenBlock.micro = 1; /* don't allow the 256B swizzle modes */
sin.forbiddenBlock.var = 1; /* don't allow the variable-sized swizzle modes */
- sin.forbiddenBlock.linear = 1; /* don't allow linear swizzle modes */
sin.bpp = in->bpp;
sin.width = in->width;
sin.height = in->height;
return 0;
}
+static bool gfx9_is_dcc_capable(const struct radeon_info *info, unsigned sw_mode)
+{
+ if (info->chip_class >= GFX10)
+ return sw_mode == ADDR_SW_64KB_Z_X || sw_mode == ADDR_SW_64KB_R_X;
+
+ return sw_mode != ADDR_SW_LINEAR;
+}
+
static int gfx9_compute_miptree(ADDR_HANDLE addrlib,
const struct radeon_info *info,
const struct ac_surf_config *config,
if (in->flags.depth) {
assert(in->swizzleMode != ADDR_SW_LINEAR);
+ if (surf->flags & RADEON_SURF_NO_HTILE)
+ return 0;
+
/* HTILE */
ADDR2_COMPUTE_HTILE_INFO_INPUT hin = {0};
ADDR2_COMPUTE_HTILE_INFO_OUTPUT hout = {0};
surf->htile_size = hout.htileBytes;
surf->htile_slice_size = hout.sliceSize;
surf->htile_alignment = hout.baseAlign;
- } else {
+ return 0;
+ }
+
+ {
/* Compute tile swizzle for the color surface.
* All *_X and *_T modes can use the swizzle.
*/
}
/* DCC */
- if (!(surf->flags & RADEON_SURF_DISABLE_DCC) &&
+ if (info->has_graphics &&
+ !(surf->flags & RADEON_SURF_DISABLE_DCC) &&
!compressed &&
- in->swizzleMode != ADDR_SW_LINEAR) {
+ gfx9_is_dcc_capable(info, in->swizzleMode)) {
ADDR2_COMPUTE_DCCINFO_INPUT din = {0};
ADDR2_COMPUTE_DCCINFO_OUTPUT dout = {0};
ADDR2_META_MIP_INFO meta_mip_info[RADEON_SURF_MAX_LEVELS] = {};
return ret;
surf->u.gfx9.dcc_retile_map[index * 2] = addrout.addr;
- if (addrout.addr > USHRT_MAX)
+ if (addrout.addr > UINT16_MAX)
surf->u.gfx9.dcc_retile_use_uint16 = false;
/* Compute dst DCC address */
return ret;
surf->u.gfx9.dcc_retile_map[index * 2 + 1] = addrout.addr;
- if (addrout.addr > USHRT_MAX)
+ if (addrout.addr > UINT16_MAX)
surf->u.gfx9.dcc_retile_use_uint16 = false;
assert(index * 2 + 1 < surf->u.gfx9.dcc_retile_num_elements);
}
/* FMASK */
- if (in->numSamples > 1) {
+ if (in->numSamples > 1 && info->has_graphics &&
+ !(surf->flags & RADEON_SURF_NO_FMASK)) {
ADDR2_COMPUTE_FMASK_INFO_INPUT fin = {0};
ADDR2_COMPUTE_FMASK_INFO_OUTPUT fout = {0};
}
}
- /* CMASK */
- if (in->swizzleMode != ADDR_SW_LINEAR) {
+ /* CMASK -- on GFX10 only for FMASK */
+ if (in->swizzleMode != ADDR_SW_LINEAR &&
+ ((info->chip_class <= GFX9 && in->numSamples == 1) ||
+ (surf->fmask_size && in->numSamples >= 2))) {
ADDR2_COMPUTE_CMASK_INFO_INPUT cin = {0};
ADDR2_COMPUTE_CMASK_INFO_OUTPUT cout = {0};
* must sample 1D textures as 2D. */
if (config->is_3d)
AddrSurfInfoIn.resourceType = ADDR_RSRC_TEX_3D;
+ else if (info->chip_class != GFX9 && config->is_1d)
+ AddrSurfInfoIn.resourceType = ADDR_RSRC_TEX_1D;
else
AddrSurfInfoIn.resourceType = ADDR_RSRC_TEX_2D;
case RADEON_SURF_MODE_1D:
case RADEON_SURF_MODE_2D:
- if (surf->flags & RADEON_SURF_IMPORTED) {
+ if (surf->flags & (RADEON_SURF_IMPORTED | RADEON_SURF_FORCE_SWIZZLE_MODE)) {
AddrSurfInfoIn.swizzleMode = surf->u.gfx9.surf.swizzle_mode;
break;
}
surf->micro_tile_mode = RADEON_MICRO_MODE_DISPLAY;
break;
- /* R = rotated. */
+ /* R = rotated (gfx9), render target (gfx10). */
case ADDR_SW_256B_R:
case ADDR_SW_4KB_R:
case ADDR_SW_64KB_R:
case ADDR_SW_64KB_R_X:
case ADDR_SW_VAR_R_X:
/* The rotated micro tile mode doesn't work if both CMASK and RB+ are
- * used at the same time. This case is not currently expected to occur
- * because we don't use rotated. Enforce this restriction on all chips
- * to facilitate testing.
+ * used at the same time. We currently do not use rotated
+ * in gfx9.
*/
- assert(!"rotate micro tile mode is unsupported");
- r = ADDR_ERROR;
- goto error;
+ assert(info->chip_class >= GFX10 ||
+ !"rotate micro tile mode is unsupported");
+ surf->micro_tile_mode = RADEON_MICRO_MODE_ROTATED;
+ break;
/* Z = depth. */
case ADDR_SW_4KB_Z:
return r;
if (info->chip_class >= GFX9)
- return gfx9_compute_surface(addrlib, info, config, mode, surf);
+ r = gfx9_compute_surface(addrlib, info, config, mode, surf);
else
- return gfx6_compute_surface(addrlib, info, config, mode, surf);
+ r = gfx6_compute_surface(addrlib, info, config, mode, surf);
+
+ if (r)
+ return r;
+
+ /* Determine the memory layout of multiple allocations in one buffer. */
+ surf->total_size = surf->surf_size;
+
+ if (surf->htile_size) {
+ surf->htile_offset = align64(surf->total_size, surf->htile_alignment);
+ surf->total_size = surf->htile_offset + surf->htile_size;
+ }
+
+ if (surf->fmask_size) {
+ assert(config->info.samples >= 2);
+ surf->fmask_offset = align64(surf->total_size, surf->fmask_alignment);
+ surf->total_size = surf->fmask_offset + surf->fmask_size;
+ }
+
+ /* Single-sample CMASK is in a separate buffer. */
+ if (surf->cmask_size && config->info.samples >= 2) {
+ surf->cmask_offset = align64(surf->total_size, surf->cmask_alignment);
+ surf->total_size = surf->cmask_offset + surf->cmask_size;
+ }
+
+ if (surf->dcc_size &&
+ (info->use_display_dcc_unaligned ||
+ info->use_display_dcc_with_retile_blit ||
+ !(surf->flags & RADEON_SURF_SCANOUT))) {
+ surf->dcc_offset = align64(surf->total_size, surf->dcc_alignment);
+ surf->total_size = surf->dcc_offset + surf->dcc_size;
+
+ if (info->chip_class >= GFX9 &&
+ surf->u.gfx9.dcc_retile_num_elements) {
+ /* Add space for the displayable DCC buffer. */
+ surf->display_dcc_offset =
+ align64(surf->total_size, surf->u.gfx9.display_dcc_alignment);
+ surf->total_size = surf->display_dcc_offset +
+ surf->u.gfx9.display_dcc_size;
+
+ /* Add space for the DCC retile buffer. (16-bit or 32-bit elements) */
+ surf->dcc_retile_map_offset =
+ align64(surf->total_size, info->tcc_cache_line_size);
+
+ if (surf->u.gfx9.dcc_retile_use_uint16) {
+ surf->total_size = surf->dcc_retile_map_offset +
+ surf->u.gfx9.dcc_retile_num_elements * 2;
+ } else {
+ surf->total_size = surf->dcc_retile_map_offset +
+ surf->u.gfx9.dcc_retile_num_elements * 4;
+ }
+ }
+ }
+
+ return 0;
}