ac_surface.c revision 01e04c3f
1/* 2 * Copyright © 2011 Red Hat All Rights Reserved. 3 * Copyright © 2017 Advanced Micro Devices, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 16 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS 18 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. 22 * 23 * The above copyright notice and this permission notice (including the 24 * next paragraph) shall be included in all copies or substantial portions 25 * of the Software. 26 */ 27 28#include "ac_surface.h" 29#include "amd_family.h" 30#include "addrlib/amdgpu_asic_addr.h" 31#include "ac_gpu_info.h" 32#include "util/macros.h" 33#include "util/u_atomic.h" 34#include "util/u_math.h" 35 36#include <errno.h> 37#include <stdio.h> 38#include <stdlib.h> 39#include <amdgpu.h> 40#include <amdgpu_drm.h> 41 42#include "addrlib/addrinterface.h" 43 44#ifndef CIASICIDGFXENGINE_SOUTHERNISLAND 45#define CIASICIDGFXENGINE_SOUTHERNISLAND 0x0000000A 46#endif 47 48#ifndef CIASICIDGFXENGINE_ARCTICISLAND 49#define CIASICIDGFXENGINE_ARCTICISLAND 0x0000000D 50#endif 51 52static unsigned get_first(unsigned x, unsigned y) 53{ 54 return x; 55} 56 57static void addrlib_family_rev_id(enum radeon_family family, 58 unsigned *addrlib_family, 59 unsigned *addrlib_revid) 60{ 61 switch (family) { 62 case CHIP_TAHITI: 63 *addrlib_family = FAMILY_SI; 64 *addrlib_revid = get_first(AMDGPU_TAHITI_RANGE); 65 break; 66 case CHIP_PITCAIRN: 67 *addrlib_family = FAMILY_SI; 68 *addrlib_revid = get_first(AMDGPU_PITCAIRN_RANGE); 69 break; 70 case CHIP_VERDE: 71 *addrlib_family = FAMILY_SI; 72 *addrlib_revid = get_first(AMDGPU_CAPEVERDE_RANGE); 73 break; 74 case CHIP_OLAND: 75 *addrlib_family = FAMILY_SI; 76 *addrlib_revid = get_first(AMDGPU_OLAND_RANGE); 77 break; 78 case CHIP_HAINAN: 79 *addrlib_family = FAMILY_SI; 80 *addrlib_revid = get_first(AMDGPU_HAINAN_RANGE); 81 break; 82 case CHIP_BONAIRE: 83 *addrlib_family = FAMILY_CI; 84 *addrlib_revid = get_first(AMDGPU_BONAIRE_RANGE); 85 break; 86 case CHIP_KAVERI: 87 *addrlib_family = FAMILY_KV; 88 *addrlib_revid = get_first(AMDGPU_SPECTRE_RANGE); 89 break; 90 case CHIP_KABINI: 91 *addrlib_family = FAMILY_KV; 92 *addrlib_revid = get_first(AMDGPU_KALINDI_RANGE); 93 break; 94 case CHIP_HAWAII: 95 *addrlib_family = FAMILY_CI; 96 *addrlib_revid = get_first(AMDGPU_HAWAII_RANGE); 97 break; 98 case CHIP_MULLINS: 99 *addrlib_family = FAMILY_KV; 100 *addrlib_revid = get_first(AMDGPU_GODAVARI_RANGE); 101 break; 102 case CHIP_TONGA: 103 *addrlib_family = FAMILY_VI; 104 *addrlib_revid = get_first(AMDGPU_TONGA_RANGE); 105 break; 106 case CHIP_ICELAND: 107 *addrlib_family = FAMILY_VI; 108 *addrlib_revid = get_first(AMDGPU_ICELAND_RANGE); 109 break; 110 case CHIP_CARRIZO: 111 *addrlib_family = FAMILY_CZ; 112 *addrlib_revid = get_first(AMDGPU_CARRIZO_RANGE); 113 break; 114 case CHIP_STONEY: 115 *addrlib_family = FAMILY_CZ; 116 *addrlib_revid = get_first(AMDGPU_STONEY_RANGE); 117 break; 118 case CHIP_FIJI: 119 *addrlib_family = FAMILY_VI; 120 *addrlib_revid = get_first(AMDGPU_FIJI_RANGE); 121 break; 122 case CHIP_POLARIS10: 123 *addrlib_family = FAMILY_VI; 124 *addrlib_revid = get_first(AMDGPU_POLARIS10_RANGE); 125 break; 126 case CHIP_POLARIS11: 127 *addrlib_family = FAMILY_VI; 128 *addrlib_revid = get_first(AMDGPU_POLARIS11_RANGE); 129 break; 130 case CHIP_POLARIS12: 131 *addrlib_family = FAMILY_VI; 132 *addrlib_revid = get_first(AMDGPU_POLARIS12_RANGE); 133 break; 134 case CHIP_VEGAM: 135 *addrlib_family = FAMILY_VI; 136 *addrlib_revid = get_first(AMDGPU_VEGAM_RANGE); 137 break; 138 case CHIP_VEGA10: 139 *addrlib_family = FAMILY_AI; 140 *addrlib_revid = get_first(AMDGPU_VEGA10_RANGE); 141 break; 142 case CHIP_VEGA12: 143 *addrlib_family = FAMILY_AI; 144 *addrlib_revid = get_first(AMDGPU_VEGA12_RANGE); 145 break; 146 case CHIP_VEGA20: 147 *addrlib_family = FAMILY_AI; 148 *addrlib_revid = get_first(AMDGPU_VEGA20_RANGE); 149 break; 150 case CHIP_RAVEN: 151 *addrlib_family = FAMILY_RV; 152 *addrlib_revid = get_first(AMDGPU_RAVEN_RANGE); 153 break; 154 case CHIP_RAVEN2: 155 *addrlib_family = FAMILY_RV; 156 *addrlib_revid = get_first(AMDGPU_RAVEN2_RANGE); 157 break; 158 default: 159 fprintf(stderr, "amdgpu: Unknown family.\n"); 160 } 161} 162 163static void *ADDR_API allocSysMem(const ADDR_ALLOCSYSMEM_INPUT * pInput) 164{ 165 return malloc(pInput->sizeInBytes); 166} 167 168static ADDR_E_RETURNCODE ADDR_API freeSysMem(const ADDR_FREESYSMEM_INPUT * pInput) 169{ 170 free(pInput->pVirtAddr); 171 return ADDR_OK; 172} 173 174ADDR_HANDLE amdgpu_addr_create(const struct radeon_info *info, 175 const struct amdgpu_gpu_info *amdinfo, 176 uint64_t *max_alignment) 177{ 178 ADDR_CREATE_INPUT addrCreateInput = {0}; 179 ADDR_CREATE_OUTPUT addrCreateOutput = {0}; 180 ADDR_REGISTER_VALUE regValue = {0}; 181 ADDR_CREATE_FLAGS createFlags = {{0}}; 182 ADDR_GET_MAX_ALINGMENTS_OUTPUT addrGetMaxAlignmentsOutput = {0}; 183 ADDR_E_RETURNCODE addrRet; 184 185 addrCreateInput.size = sizeof(ADDR_CREATE_INPUT); 186 addrCreateOutput.size = sizeof(ADDR_CREATE_OUTPUT); 187 188 regValue.gbAddrConfig = amdinfo->gb_addr_cfg; 189 createFlags.value = 0; 190 191 addrlib_family_rev_id(info->family, &addrCreateInput.chipFamily, &addrCreateInput.chipRevision); 192 if (addrCreateInput.chipFamily == FAMILY_UNKNOWN) 193 return NULL; 194 195 if (addrCreateInput.chipFamily >= FAMILY_AI) { 196 addrCreateInput.chipEngine = CIASICIDGFXENGINE_ARCTICISLAND; 197 regValue.blockVarSizeLog2 = 0; 198 } else { 199 regValue.noOfBanks = amdinfo->mc_arb_ramcfg & 0x3; 200 regValue.noOfRanks = (amdinfo->mc_arb_ramcfg & 0x4) >> 2; 201 202 regValue.backendDisables = amdinfo->enabled_rb_pipes_mask; 203 regValue.pTileConfig = amdinfo->gb_tile_mode; 204 regValue.noOfEntries = ARRAY_SIZE(amdinfo->gb_tile_mode); 205 if (addrCreateInput.chipFamily == FAMILY_SI) { 206 regValue.pMacroTileConfig = NULL; 207 regValue.noOfMacroEntries = 0; 208 } else { 209 regValue.pMacroTileConfig = amdinfo->gb_macro_tile_mode; 210 regValue.noOfMacroEntries = ARRAY_SIZE(amdinfo->gb_macro_tile_mode); 211 } 212 213 createFlags.useTileIndex = 1; 214 createFlags.useHtileSliceAlign = 1; 215 216 addrCreateInput.chipEngine = CIASICIDGFXENGINE_SOUTHERNISLAND; 217 } 218 219 addrCreateInput.callbacks.allocSysMem = allocSysMem; 220 addrCreateInput.callbacks.freeSysMem = freeSysMem; 221 addrCreateInput.callbacks.debugPrint = 0; 222 addrCreateInput.createFlags = createFlags; 223 addrCreateInput.regValue = regValue; 224 225 addrRet = AddrCreate(&addrCreateInput, &addrCreateOutput); 226 if (addrRet != ADDR_OK) 227 return NULL; 228 229 if (max_alignment) { 230 addrRet = AddrGetMaxAlignments(addrCreateOutput.hLib, &addrGetMaxAlignmentsOutput); 231 if (addrRet == ADDR_OK){ 232 *max_alignment = addrGetMaxAlignmentsOutput.baseAlign; 233 } 234 } 235 return addrCreateOutput.hLib; 236} 237 238static int surf_config_sanity(const struct ac_surf_config *config, 239 unsigned flags) 240{ 241 /* FMASK is allocated together with the color surface and can't be 242 * allocated separately. 243 */ 244 assert(!(flags & RADEON_SURF_FMASK)); 245 if (flags & RADEON_SURF_FMASK) 246 return -EINVAL; 247 248 /* all dimension must be at least 1 ! */ 249 if (!config->info.width || !config->info.height || !config->info.depth || 250 !config->info.array_size || !config->info.levels) 251 return -EINVAL; 252 253 switch (config->info.samples) { 254 case 0: 255 case 1: 256 case 2: 257 case 4: 258 case 8: 259 break; 260 case 16: 261 if (flags & RADEON_SURF_Z_OR_SBUFFER) 262 return -EINVAL; 263 break; 264 default: 265 return -EINVAL; 266 } 267 268 if (!(flags & RADEON_SURF_Z_OR_SBUFFER)) { 269 switch (config->info.storage_samples) { 270 case 0: 271 case 1: 272 case 2: 273 case 4: 274 case 8: 275 break; 276 default: 277 return -EINVAL; 278 } 279 } 280 281 if (config->is_3d && config->info.array_size > 1) 282 return -EINVAL; 283 if (config->is_cube && config->info.depth > 1) 284 return -EINVAL; 285 286 return 0; 287} 288 289static int gfx6_compute_level(ADDR_HANDLE addrlib, 290 const struct ac_surf_config *config, 291 struct radeon_surf *surf, bool is_stencil, 292 unsigned level, bool compressed, 293 ADDR_COMPUTE_SURFACE_INFO_INPUT *AddrSurfInfoIn, 294 ADDR_COMPUTE_SURFACE_INFO_OUTPUT *AddrSurfInfoOut, 295 ADDR_COMPUTE_DCCINFO_INPUT *AddrDccIn, 296 ADDR_COMPUTE_DCCINFO_OUTPUT *AddrDccOut, 297 ADDR_COMPUTE_HTILE_INFO_INPUT *AddrHtileIn, 298 ADDR_COMPUTE_HTILE_INFO_OUTPUT *AddrHtileOut) 299{ 300 struct legacy_surf_level *surf_level; 301 ADDR_E_RETURNCODE ret; 302 303 AddrSurfInfoIn->mipLevel = level; 304 AddrSurfInfoIn->width = u_minify(config->info.width, level); 305 AddrSurfInfoIn->height = u_minify(config->info.height, level); 306 307 /* Make GFX6 linear surfaces compatible with GFX9 for hybrid graphics, 308 * because GFX9 needs linear alignment of 256 bytes. 309 */ 310 if (config->info.levels == 1 && 311 AddrSurfInfoIn->tileMode == ADDR_TM_LINEAR_ALIGNED && 312 AddrSurfInfoIn->bpp && 313 util_is_power_of_two_or_zero(AddrSurfInfoIn->bpp)) { 314 unsigned alignment = 256 / (AddrSurfInfoIn->bpp / 8); 315 316 AddrSurfInfoIn->width = align(AddrSurfInfoIn->width, alignment); 317 } 318 319 if (config->is_3d) 320 AddrSurfInfoIn->numSlices = u_minify(config->info.depth, level); 321 else if (config->is_cube) 322 AddrSurfInfoIn->numSlices = 6; 323 else 324 AddrSurfInfoIn->numSlices = config->info.array_size; 325 326 if (level > 0) { 327 /* Set the base level pitch. This is needed for calculation 328 * of non-zero levels. */ 329 if (is_stencil) 330 AddrSurfInfoIn->basePitch = surf->u.legacy.stencil_level[0].nblk_x; 331 else 332 AddrSurfInfoIn->basePitch = surf->u.legacy.level[0].nblk_x; 333 334 /* Convert blocks to pixels for compressed formats. */ 335 if (compressed) 336 AddrSurfInfoIn->basePitch *= surf->blk_w; 337 } 338 339 ret = AddrComputeSurfaceInfo(addrlib, 340 AddrSurfInfoIn, 341 AddrSurfInfoOut); 342 if (ret != ADDR_OK) { 343 return ret; 344 } 345 346 surf_level = is_stencil ? &surf->u.legacy.stencil_level[level] : &surf->u.legacy.level[level]; 347 surf_level->offset = align64(surf->surf_size, AddrSurfInfoOut->baseAlign); 348 surf_level->slice_size_dw = AddrSurfInfoOut->sliceSize / 4; 349 surf_level->nblk_x = AddrSurfInfoOut->pitch; 350 surf_level->nblk_y = AddrSurfInfoOut->height; 351 352 switch (AddrSurfInfoOut->tileMode) { 353 case ADDR_TM_LINEAR_ALIGNED: 354 surf_level->mode = RADEON_SURF_MODE_LINEAR_ALIGNED; 355 break; 356 case ADDR_TM_1D_TILED_THIN1: 357 surf_level->mode = RADEON_SURF_MODE_1D; 358 break; 359 case ADDR_TM_2D_TILED_THIN1: 360 surf_level->mode = RADEON_SURF_MODE_2D; 361 break; 362 default: 363 assert(0); 364 } 365 366 if (is_stencil) 367 surf->u.legacy.stencil_tiling_index[level] = AddrSurfInfoOut->tileIndex; 368 else 369 surf->u.legacy.tiling_index[level] = AddrSurfInfoOut->tileIndex; 370 371 surf->surf_size = surf_level->offset + AddrSurfInfoOut->surfSize; 372 373 /* Clear DCC fields at the beginning. */ 374 surf_level->dcc_offset = 0; 375 376 /* The previous level's flag tells us if we can use DCC for this level. */ 377 if (AddrSurfInfoIn->flags.dccCompatible && 378 (level == 0 || AddrDccOut->subLvlCompressible)) { 379 bool prev_level_clearable = level == 0 || 380 AddrDccOut->dccRamSizeAligned; 381 382 AddrDccIn->colorSurfSize = AddrSurfInfoOut->surfSize; 383 AddrDccIn->tileMode = AddrSurfInfoOut->tileMode; 384 AddrDccIn->tileInfo = *AddrSurfInfoOut->pTileInfo; 385 AddrDccIn->tileIndex = AddrSurfInfoOut->tileIndex; 386 AddrDccIn->macroModeIndex = AddrSurfInfoOut->macroModeIndex; 387 388 ret = AddrComputeDccInfo(addrlib, 389 AddrDccIn, 390 AddrDccOut); 391 392 if (ret == ADDR_OK) { 393 surf_level->dcc_offset = surf->dcc_size; 394 surf->num_dcc_levels = level + 1; 395 surf->dcc_size = surf_level->dcc_offset + AddrDccOut->dccRamSize; 396 surf->dcc_alignment = MAX2(surf->dcc_alignment, AddrDccOut->dccRamBaseAlign); 397 398 /* If the DCC size of a subresource (1 mip level or 1 slice) 399 * is not aligned, the DCC memory layout is not contiguous for 400 * that subresource, which means we can't use fast clear. 401 * 402 * We only do fast clears for whole mipmap levels. If we did 403 * per-slice fast clears, the same restriction would apply. 404 * (i.e. only compute the slice size and see if it's aligned) 405 * 406 * The last level can be non-contiguous and still be clearable 407 * if it's interleaved with the next level that doesn't exist. 408 */ 409 if (AddrDccOut->dccRamSizeAligned || 410 (prev_level_clearable && level == config->info.levels - 1)) 411 surf_level->dcc_fast_clear_size = AddrDccOut->dccFastClearSize; 412 else 413 surf_level->dcc_fast_clear_size = 0; 414 } 415 } 416 417 /* TC-compatible HTILE. */ 418 if (!is_stencil && 419 AddrSurfInfoIn->flags.depth && 420 surf_level->mode == RADEON_SURF_MODE_2D && 421 level == 0) { 422 AddrHtileIn->flags.tcCompatible = AddrSurfInfoIn->flags.tcCompatible; 423 AddrHtileIn->pitch = AddrSurfInfoOut->pitch; 424 AddrHtileIn->height = AddrSurfInfoOut->height; 425 AddrHtileIn->numSlices = AddrSurfInfoOut->depth; 426 AddrHtileIn->blockWidth = ADDR_HTILE_BLOCKSIZE_8; 427 AddrHtileIn->blockHeight = ADDR_HTILE_BLOCKSIZE_8; 428 AddrHtileIn->pTileInfo = AddrSurfInfoOut->pTileInfo; 429 AddrHtileIn->tileIndex = AddrSurfInfoOut->tileIndex; 430 AddrHtileIn->macroModeIndex = AddrSurfInfoOut->macroModeIndex; 431 432 ret = AddrComputeHtileInfo(addrlib, 433 AddrHtileIn, 434 AddrHtileOut); 435 436 if (ret == ADDR_OK) { 437 surf->htile_size = AddrHtileOut->htileBytes; 438 surf->htile_slice_size = AddrHtileOut->sliceSize; 439 surf->htile_alignment = AddrHtileOut->baseAlign; 440 } 441 } 442 443 return 0; 444} 445 446#define G_009910_MICRO_TILE_MODE(x) (((x) >> 0) & 0x03) 447#define V_009910_ADDR_SURF_THICK_MICRO_TILING 0x03 448#define G_009910_MICRO_TILE_MODE_NEW(x) (((x) >> 22) & 0x07) 449 450static void gfx6_set_micro_tile_mode(struct radeon_surf *surf, 451 const struct radeon_info *info) 452{ 453 uint32_t tile_mode = info->si_tile_mode_array[surf->u.legacy.tiling_index[0]]; 454 455 if (info->chip_class >= CIK) 456 surf->micro_tile_mode = G_009910_MICRO_TILE_MODE_NEW(tile_mode); 457 else 458 surf->micro_tile_mode = G_009910_MICRO_TILE_MODE(tile_mode); 459} 460 461static unsigned cik_get_macro_tile_index(struct radeon_surf *surf) 462{ 463 unsigned index, tileb; 464 465 tileb = 8 * 8 * surf->bpe; 466 tileb = MIN2(surf->u.legacy.tile_split, tileb); 467 468 for (index = 0; tileb > 64; index++) 469 tileb >>= 1; 470 471 assert(index < 16); 472 return index; 473} 474 475static bool get_display_flag(const struct ac_surf_config *config, 476 const struct radeon_surf *surf) 477{ 478 unsigned num_channels = config->info.num_channels; 479 unsigned bpe = surf->bpe; 480 481 if (surf->flags & RADEON_SURF_SCANOUT && 482 config->info.samples <= 1 && 483 surf->blk_w <= 2 && surf->blk_h == 1) { 484 /* subsampled */ 485 if (surf->blk_w == 2 && surf->blk_h == 1) 486 return true; 487 488 if (/* RGBA8 or RGBA16F */ 489 (bpe >= 4 && bpe <= 8 && num_channels == 4) || 490 /* R5G6B5 or R5G5B5A1 */ 491 (bpe == 2 && num_channels >= 3) || 492 /* C8 palette */ 493 (bpe == 1 && num_channels == 1)) 494 return true; 495 } 496 return false; 497} 498 499/** 500 * This must be called after the first level is computed. 501 * 502 * Copy surface-global settings like pipe/bank config from level 0 surface 503 * computation, and compute tile swizzle. 504 */ 505static int gfx6_surface_settings(ADDR_HANDLE addrlib, 506 const struct radeon_info *info, 507 const struct ac_surf_config *config, 508 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* csio, 509 struct radeon_surf *surf) 510{ 511 surf->surf_alignment = csio->baseAlign; 512 surf->u.legacy.pipe_config = csio->pTileInfo->pipeConfig - 1; 513 gfx6_set_micro_tile_mode(surf, info); 514 515 /* For 2D modes only. */ 516 if (csio->tileMode >= ADDR_TM_2D_TILED_THIN1) { 517 surf->u.legacy.bankw = csio->pTileInfo->bankWidth; 518 surf->u.legacy.bankh = csio->pTileInfo->bankHeight; 519 surf->u.legacy.mtilea = csio->pTileInfo->macroAspectRatio; 520 surf->u.legacy.tile_split = csio->pTileInfo->tileSplitBytes; 521 surf->u.legacy.num_banks = csio->pTileInfo->banks; 522 surf->u.legacy.macro_tile_index = csio->macroModeIndex; 523 } else { 524 surf->u.legacy.macro_tile_index = 0; 525 } 526 527 /* Compute tile swizzle. */ 528 /* TODO: fix tile swizzle with mipmapping for SI */ 529 if ((info->chip_class >= CIK || config->info.levels == 1) && 530 config->info.surf_index && 531 surf->u.legacy.level[0].mode == RADEON_SURF_MODE_2D && 532 !(surf->flags & (RADEON_SURF_Z_OR_SBUFFER | RADEON_SURF_SHAREABLE)) && 533 !get_display_flag(config, surf)) { 534 ADDR_COMPUTE_BASE_SWIZZLE_INPUT AddrBaseSwizzleIn = {0}; 535 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT AddrBaseSwizzleOut = {0}; 536 537 AddrBaseSwizzleIn.size = sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT); 538 AddrBaseSwizzleOut.size = sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT); 539 540 AddrBaseSwizzleIn.surfIndex = p_atomic_inc_return(config->info.surf_index) - 1; 541 AddrBaseSwizzleIn.tileIndex = csio->tileIndex; 542 AddrBaseSwizzleIn.macroModeIndex = csio->macroModeIndex; 543 AddrBaseSwizzleIn.pTileInfo = csio->pTileInfo; 544 AddrBaseSwizzleIn.tileMode = csio->tileMode; 545 546 int r = AddrComputeBaseSwizzle(addrlib, &AddrBaseSwizzleIn, 547 &AddrBaseSwizzleOut); 548 if (r != ADDR_OK) 549 return r; 550 551 assert(AddrBaseSwizzleOut.tileSwizzle <= 552 u_bit_consecutive(0, sizeof(surf->tile_swizzle) * 8)); 553 surf->tile_swizzle = AddrBaseSwizzleOut.tileSwizzle; 554 } 555 return 0; 556} 557 558void ac_compute_cmask(const struct radeon_info *info, 559 const struct ac_surf_config *config, 560 struct radeon_surf *surf) 561{ 562 unsigned pipe_interleave_bytes = info->pipe_interleave_bytes; 563 unsigned num_pipes = info->num_tile_pipes; 564 unsigned cl_width, cl_height; 565 566 if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) 567 return; 568 569 assert(info->chip_class <= VI); 570 571 switch (num_pipes) { 572 case 2: 573 cl_width = 32; 574 cl_height = 16; 575 break; 576 case 4: 577 cl_width = 32; 578 cl_height = 32; 579 break; 580 case 8: 581 cl_width = 64; 582 cl_height = 32; 583 break; 584 case 16: /* Hawaii */ 585 cl_width = 64; 586 cl_height = 64; 587 break; 588 default: 589 assert(0); 590 return; 591 } 592 593 unsigned base_align = num_pipes * pipe_interleave_bytes; 594 595 unsigned width = align(surf->u.legacy.level[0].nblk_x, cl_width*8); 596 unsigned height = align(surf->u.legacy.level[0].nblk_y, cl_height*8); 597 unsigned slice_elements = (width * height) / (8*8); 598 599 /* Each element of CMASK is a nibble. */ 600 unsigned slice_bytes = slice_elements / 2; 601 602 surf->u.legacy.cmask_slice_tile_max = (width * height) / (128*128); 603 if (surf->u.legacy.cmask_slice_tile_max) 604 surf->u.legacy.cmask_slice_tile_max -= 1; 605 606 unsigned num_layers; 607 if (config->is_3d) 608 num_layers = config->info.depth; 609 else if (config->is_cube) 610 num_layers = 6; 611 else 612 num_layers = config->info.array_size; 613 614 surf->cmask_alignment = MAX2(256, base_align); 615 surf->cmask_size = align(slice_bytes, base_align) * num_layers; 616} 617 618/** 619 * Fill in the tiling information in \p surf based on the given surface config. 620 * 621 * The following fields of \p surf must be initialized by the caller: 622 * blk_w, blk_h, bpe, flags. 623 */ 624static int gfx6_compute_surface(ADDR_HANDLE addrlib, 625 const struct radeon_info *info, 626 const struct ac_surf_config *config, 627 enum radeon_surf_mode mode, 628 struct radeon_surf *surf) 629{ 630 unsigned level; 631 bool compressed; 632 ADDR_COMPUTE_SURFACE_INFO_INPUT AddrSurfInfoIn = {0}; 633 ADDR_COMPUTE_SURFACE_INFO_OUTPUT AddrSurfInfoOut = {0}; 634 ADDR_COMPUTE_DCCINFO_INPUT AddrDccIn = {0}; 635 ADDR_COMPUTE_DCCINFO_OUTPUT AddrDccOut = {0}; 636 ADDR_COMPUTE_HTILE_INFO_INPUT AddrHtileIn = {0}; 637 ADDR_COMPUTE_HTILE_INFO_OUTPUT AddrHtileOut = {0}; 638 ADDR_TILEINFO AddrTileInfoIn = {0}; 639 ADDR_TILEINFO AddrTileInfoOut = {0}; 640 int r; 641 642 AddrSurfInfoIn.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT); 643 AddrSurfInfoOut.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT); 644 AddrDccIn.size = sizeof(ADDR_COMPUTE_DCCINFO_INPUT); 645 AddrDccOut.size = sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT); 646 AddrHtileIn.size = sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT); 647 AddrHtileOut.size = sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT); 648 AddrSurfInfoOut.pTileInfo = &AddrTileInfoOut; 649 650 compressed = surf->blk_w == 4 && surf->blk_h == 4; 651 652 /* MSAA requires 2D tiling. */ 653 if (config->info.samples > 1) 654 mode = RADEON_SURF_MODE_2D; 655 656 /* DB doesn't support linear layouts. */ 657 if (surf->flags & (RADEON_SURF_Z_OR_SBUFFER) && 658 mode < RADEON_SURF_MODE_1D) 659 mode = RADEON_SURF_MODE_1D; 660 661 /* Set the requested tiling mode. */ 662 switch (mode) { 663 case RADEON_SURF_MODE_LINEAR_ALIGNED: 664 AddrSurfInfoIn.tileMode = ADDR_TM_LINEAR_ALIGNED; 665 break; 666 case RADEON_SURF_MODE_1D: 667 AddrSurfInfoIn.tileMode = ADDR_TM_1D_TILED_THIN1; 668 break; 669 case RADEON_SURF_MODE_2D: 670 AddrSurfInfoIn.tileMode = ADDR_TM_2D_TILED_THIN1; 671 break; 672 default: 673 assert(0); 674 } 675 676 /* The format must be set correctly for the allocation of compressed 677 * textures to work. In other cases, setting the bpp is sufficient. 678 */ 679 if (compressed) { 680 switch (surf->bpe) { 681 case 8: 682 AddrSurfInfoIn.format = ADDR_FMT_BC1; 683 break; 684 case 16: 685 AddrSurfInfoIn.format = ADDR_FMT_BC3; 686 break; 687 default: 688 assert(0); 689 } 690 } 691 else { 692 AddrDccIn.bpp = AddrSurfInfoIn.bpp = surf->bpe * 8; 693 } 694 695 AddrDccIn.numSamples = AddrSurfInfoIn.numSamples = 696 MAX2(1, config->info.samples); 697 AddrSurfInfoIn.tileIndex = -1; 698 699 if (!(surf->flags & RADEON_SURF_Z_OR_SBUFFER)) { 700 AddrDccIn.numSamples = AddrSurfInfoIn.numFrags = 701 MAX2(1, config->info.storage_samples); 702 } 703 704 /* Set the micro tile type. */ 705 if (surf->flags & RADEON_SURF_SCANOUT) 706 AddrSurfInfoIn.tileType = ADDR_DISPLAYABLE; 707 else if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) 708 AddrSurfInfoIn.tileType = ADDR_DEPTH_SAMPLE_ORDER; 709 else 710 AddrSurfInfoIn.tileType = ADDR_NON_DISPLAYABLE; 711 712 AddrSurfInfoIn.flags.color = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER); 713 AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0; 714 AddrSurfInfoIn.flags.cube = config->is_cube; 715 AddrSurfInfoIn.flags.display = get_display_flag(config, surf); 716 AddrSurfInfoIn.flags.pow2Pad = config->info.levels > 1; 717 AddrSurfInfoIn.flags.tcCompatible = (surf->flags & RADEON_SURF_TC_COMPATIBLE_HTILE) != 0; 718 719 /* Only degrade the tile mode for space if TC-compatible HTILE hasn't been 720 * requested, because TC-compatible HTILE requires 2D tiling. 721 */ 722 AddrSurfInfoIn.flags.opt4Space = !AddrSurfInfoIn.flags.tcCompatible && 723 !AddrSurfInfoIn.flags.fmask && 724 config->info.samples <= 1 && 725 (surf->flags & RADEON_SURF_OPTIMIZE_FOR_SPACE); 726 727 /* DCC notes: 728 * - If we add MSAA support, keep in mind that CB can't decompress 8bpp 729 * with samples >= 4. 730 * - Mipmapped array textures have low performance (discovered by a closed 731 * driver team). 732 */ 733 AddrSurfInfoIn.flags.dccCompatible = 734 info->chip_class >= VI && 735 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER) && 736 !(surf->flags & RADEON_SURF_DISABLE_DCC) && 737 !compressed && 738 ((config->info.array_size == 1 && config->info.depth == 1) || 739 config->info.levels == 1); 740 741 AddrSurfInfoIn.flags.noStencil = (surf->flags & RADEON_SURF_SBUFFER) == 0; 742 AddrSurfInfoIn.flags.compressZ = !!(surf->flags & RADEON_SURF_Z_OR_SBUFFER); 743 744 /* On CI/VI, the DB uses the same pitch and tile mode (except tilesplit) 745 * for Z and stencil. This can cause a number of problems which we work 746 * around here: 747 * 748 * - a depth part that is incompatible with mipmapped texturing 749 * - at least on Stoney, entirely incompatible Z/S aspects (e.g. 750 * incorrect tiling applied to the stencil part, stencil buffer 751 * memory accesses that go out of bounds) even without mipmapping 752 * 753 * Some piglit tests that are prone to different types of related 754 * failures: 755 * ./bin/ext_framebuffer_multisample-upsample 2 stencil 756 * ./bin/framebuffer-blit-levels {draw,read} stencil 757 * ./bin/ext_framebuffer_multisample-unaligned-blit N {depth,stencil} {msaa,upsample,downsample} 758 * ./bin/fbo-depth-array fs-writes-{depth,stencil} / {depth,stencil}-{clear,layered-clear,draw} 759 * ./bin/depthstencil-render-miplevels 1024 d=s=z24_s8 760 */ 761 int stencil_tile_idx = -1; 762 763 if (AddrSurfInfoIn.flags.depth && !AddrSurfInfoIn.flags.noStencil && 764 (config->info.levels > 1 || info->family == CHIP_STONEY)) { 765 /* Compute stencilTileIdx that is compatible with the (depth) 766 * tileIdx. This degrades the depth surface if necessary to 767 * ensure that a matching stencilTileIdx exists. */ 768 AddrSurfInfoIn.flags.matchStencilTileCfg = 1; 769 770 /* Keep the depth mip-tail compatible with texturing. */ 771 AddrSurfInfoIn.flags.noStencil = 1; 772 } 773 774 /* Set preferred macrotile parameters. This is usually required 775 * for shared resources. This is for 2D tiling only. */ 776 if (AddrSurfInfoIn.tileMode >= ADDR_TM_2D_TILED_THIN1 && 777 surf->u.legacy.bankw && surf->u.legacy.bankh && 778 surf->u.legacy.mtilea && surf->u.legacy.tile_split) { 779 /* If any of these parameters are incorrect, the calculation 780 * will fail. */ 781 AddrTileInfoIn.banks = surf->u.legacy.num_banks; 782 AddrTileInfoIn.bankWidth = surf->u.legacy.bankw; 783 AddrTileInfoIn.bankHeight = surf->u.legacy.bankh; 784 AddrTileInfoIn.macroAspectRatio = surf->u.legacy.mtilea; 785 AddrTileInfoIn.tileSplitBytes = surf->u.legacy.tile_split; 786 AddrTileInfoIn.pipeConfig = surf->u.legacy.pipe_config + 1; /* +1 compared to GB_TILE_MODE */ 787 AddrSurfInfoIn.flags.opt4Space = 0; 788 AddrSurfInfoIn.pTileInfo = &AddrTileInfoIn; 789 790 /* If AddrSurfInfoIn.pTileInfo is set, Addrlib doesn't set 791 * the tile index, because we are expected to know it if 792 * we know the other parameters. 793 * 794 * This is something that can easily be fixed in Addrlib. 795 * For now, just figure it out here. 796 * Note that only 2D_TILE_THIN1 is handled here. 797 */ 798 assert(!(surf->flags & RADEON_SURF_Z_OR_SBUFFER)); 799 assert(AddrSurfInfoIn.tileMode == ADDR_TM_2D_TILED_THIN1); 800 801 if (info->chip_class == SI) { 802 if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE) { 803 if (surf->bpe == 2) 804 AddrSurfInfoIn.tileIndex = 11; /* 16bpp */ 805 else 806 AddrSurfInfoIn.tileIndex = 12; /* 32bpp */ 807 } else { 808 if (surf->bpe == 1) 809 AddrSurfInfoIn.tileIndex = 14; /* 8bpp */ 810 else if (surf->bpe == 2) 811 AddrSurfInfoIn.tileIndex = 15; /* 16bpp */ 812 else if (surf->bpe == 4) 813 AddrSurfInfoIn.tileIndex = 16; /* 32bpp */ 814 else 815 AddrSurfInfoIn.tileIndex = 17; /* 64bpp (and 128bpp) */ 816 } 817 } else { 818 /* CIK - VI */ 819 if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE) 820 AddrSurfInfoIn.tileIndex = 10; /* 2D displayable */ 821 else 822 AddrSurfInfoIn.tileIndex = 14; /* 2D non-displayable */ 823 824 /* Addrlib doesn't set this if tileIndex is forced like above. */ 825 AddrSurfInfoOut.macroModeIndex = cik_get_macro_tile_index(surf); 826 } 827 } 828 829 surf->has_stencil = !!(surf->flags & RADEON_SURF_SBUFFER); 830 surf->num_dcc_levels = 0; 831 surf->surf_size = 0; 832 surf->dcc_size = 0; 833 surf->dcc_alignment = 1; 834 surf->htile_size = 0; 835 surf->htile_slice_size = 0; 836 surf->htile_alignment = 1; 837 838 const bool only_stencil = (surf->flags & RADEON_SURF_SBUFFER) && 839 !(surf->flags & RADEON_SURF_ZBUFFER); 840 841 /* Calculate texture layout information. */ 842 if (!only_stencil) { 843 for (level = 0; level < config->info.levels; level++) { 844 r = gfx6_compute_level(addrlib, config, surf, false, level, compressed, 845 &AddrSurfInfoIn, &AddrSurfInfoOut, 846 &AddrDccIn, &AddrDccOut, &AddrHtileIn, &AddrHtileOut); 847 if (r) 848 return r; 849 850 if (level > 0) 851 continue; 852 853 /* Check that we actually got a TC-compatible HTILE if 854 * we requested it (only for level 0, since we're not 855 * supporting HTILE on higher mip levels anyway). */ 856 assert(AddrSurfInfoOut.tcCompatible || 857 !AddrSurfInfoIn.flags.tcCompatible || 858 AddrSurfInfoIn.flags.matchStencilTileCfg); 859 860 if (AddrSurfInfoIn.flags.matchStencilTileCfg) { 861 if (!AddrSurfInfoOut.tcCompatible) { 862 AddrSurfInfoIn.flags.tcCompatible = 0; 863 surf->flags &= ~RADEON_SURF_TC_COMPATIBLE_HTILE; 864 } 865 866 AddrSurfInfoIn.flags.matchStencilTileCfg = 0; 867 AddrSurfInfoIn.tileIndex = AddrSurfInfoOut.tileIndex; 868 stencil_tile_idx = AddrSurfInfoOut.stencilTileIdx; 869 870 assert(stencil_tile_idx >= 0); 871 } 872 873 r = gfx6_surface_settings(addrlib, info, config, 874 &AddrSurfInfoOut, surf); 875 if (r) 876 return r; 877 } 878 } 879 880 /* Calculate texture layout information for stencil. */ 881 if (surf->flags & RADEON_SURF_SBUFFER) { 882 AddrSurfInfoIn.tileIndex = stencil_tile_idx; 883 AddrSurfInfoIn.bpp = 8; 884 AddrSurfInfoIn.flags.depth = 0; 885 AddrSurfInfoIn.flags.stencil = 1; 886 AddrSurfInfoIn.flags.tcCompatible = 0; 887 /* This will be ignored if AddrSurfInfoIn.pTileInfo is NULL. */ 888 AddrTileInfoIn.tileSplitBytes = surf->u.legacy.stencil_tile_split; 889 890 for (level = 0; level < config->info.levels; level++) { 891 r = gfx6_compute_level(addrlib, config, surf, true, level, compressed, 892 &AddrSurfInfoIn, &AddrSurfInfoOut, 893 &AddrDccIn, &AddrDccOut, 894 NULL, NULL); 895 if (r) 896 return r; 897 898 /* DB uses the depth pitch for both stencil and depth. */ 899 if (!only_stencil) { 900 if (surf->u.legacy.stencil_level[level].nblk_x != 901 surf->u.legacy.level[level].nblk_x) 902 surf->u.legacy.stencil_adjusted = true; 903 } else { 904 surf->u.legacy.level[level].nblk_x = 905 surf->u.legacy.stencil_level[level].nblk_x; 906 } 907 908 if (level == 0) { 909 if (only_stencil) { 910 r = gfx6_surface_settings(addrlib, info, config, 911 &AddrSurfInfoOut, surf); 912 if (r) 913 return r; 914 } 915 916 /* For 2D modes only. */ 917 if (AddrSurfInfoOut.tileMode >= ADDR_TM_2D_TILED_THIN1) { 918 surf->u.legacy.stencil_tile_split = 919 AddrSurfInfoOut.pTileInfo->tileSplitBytes; 920 } 921 } 922 } 923 } 924 925 /* Compute FMASK. */ 926 if (config->info.samples >= 2 && AddrSurfInfoIn.flags.color) { 927 ADDR_COMPUTE_FMASK_INFO_INPUT fin = {0}; 928 ADDR_COMPUTE_FMASK_INFO_OUTPUT fout = {0}; 929 ADDR_TILEINFO fmask_tile_info = {}; 930 931 fin.size = sizeof(fin); 932 fout.size = sizeof(fout); 933 934 fin.tileMode = AddrSurfInfoOut.tileMode; 935 fin.pitch = AddrSurfInfoOut.pitch; 936 fin.height = config->info.height; 937 fin.numSlices = AddrSurfInfoIn.numSlices; 938 fin.numSamples = AddrSurfInfoIn.numSamples; 939 fin.numFrags = AddrSurfInfoIn.numFrags; 940 fin.tileIndex = -1; 941 fout.pTileInfo = &fmask_tile_info; 942 943 r = AddrComputeFmaskInfo(addrlib, &fin, &fout); 944 if (r) 945 return r; 946 947 surf->fmask_size = fout.fmaskBytes; 948 surf->fmask_alignment = fout.baseAlign; 949 surf->fmask_tile_swizzle = 0; 950 951 surf->u.legacy.fmask.slice_tile_max = 952 (fout.pitch * fout.height) / 64; 953 if (surf->u.legacy.fmask.slice_tile_max) 954 surf->u.legacy.fmask.slice_tile_max -= 1; 955 956 surf->u.legacy.fmask.tiling_index = fout.tileIndex; 957 surf->u.legacy.fmask.bankh = fout.pTileInfo->bankHeight; 958 surf->u.legacy.fmask.pitch_in_pixels = fout.pitch; 959 960 /* Compute tile swizzle for FMASK. */ 961 if (config->info.fmask_surf_index && 962 !(surf->flags & RADEON_SURF_SHAREABLE)) { 963 ADDR_COMPUTE_BASE_SWIZZLE_INPUT xin = {0}; 964 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT xout = {0}; 965 966 xin.size = sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT); 967 xout.size = sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT); 968 969 /* This counter starts from 1 instead of 0. */ 970 xin.surfIndex = p_atomic_inc_return(config->info.fmask_surf_index); 971 xin.tileIndex = fout.tileIndex; 972 xin.macroModeIndex = fout.macroModeIndex; 973 xin.pTileInfo = fout.pTileInfo; 974 xin.tileMode = fin.tileMode; 975 976 int r = AddrComputeBaseSwizzle(addrlib, &xin, &xout); 977 if (r != ADDR_OK) 978 return r; 979 980 assert(xout.tileSwizzle <= 981 u_bit_consecutive(0, sizeof(surf->tile_swizzle) * 8)); 982 surf->fmask_tile_swizzle = xout.tileSwizzle; 983 } 984 } 985 986 /* Recalculate the whole DCC miptree size including disabled levels. 987 * This is what addrlib does, but calling addrlib would be a lot more 988 * complicated. 989 */ 990 if (surf->dcc_size && config->info.levels > 1) { 991 /* The smallest miplevels that are never compressed by DCC 992 * still read the DCC buffer via TC if the base level uses DCC, 993 * and for some reason the DCC buffer needs to be larger if 994 * the miptree uses non-zero tile_swizzle. Otherwise there are 995 * VM faults. 996 * 997 * "dcc_alignment * 4" was determined by trial and error. 998 */ 999 surf->dcc_size = align64(surf->surf_size >> 8, 1000 surf->dcc_alignment * 4); 1001 } 1002 1003 /* Make sure HTILE covers the whole miptree, because the shader reads 1004 * TC-compatible HTILE even for levels where it's disabled by DB. 1005 */ 1006 if (surf->htile_size && config->info.levels > 1 && 1007 surf->flags & RADEON_SURF_TC_COMPATIBLE_HTILE) { 1008 /* MSAA can't occur with levels > 1, so ignore the sample count. */ 1009 const unsigned total_pixels = surf->surf_size / surf->bpe; 1010 const unsigned htile_block_size = 8 * 8; 1011 const unsigned htile_element_size = 4; 1012 1013 surf->htile_size = (total_pixels / htile_block_size) * 1014 htile_element_size; 1015 surf->htile_size = align(surf->htile_size, surf->htile_alignment); 1016 } 1017 1018 surf->is_linear = surf->u.legacy.level[0].mode == RADEON_SURF_MODE_LINEAR_ALIGNED; 1019 surf->is_displayable = surf->is_linear || 1020 surf->micro_tile_mode == RADEON_MICRO_MODE_DISPLAY || 1021 surf->micro_tile_mode == RADEON_MICRO_MODE_ROTATED; 1022 1023 /* The rotated micro tile mode doesn't work if both CMASK and RB+ are 1024 * used at the same time. This case is not currently expected to occur 1025 * because we don't use rotated. Enforce this restriction on all chips 1026 * to facilitate testing. 1027 */ 1028 if (surf->micro_tile_mode == RADEON_MICRO_MODE_ROTATED) { 1029 assert(!"rotate micro tile mode is unsupported"); 1030 return ADDR_ERROR; 1031 } 1032 1033 ac_compute_cmask(info, config, surf); 1034 return 0; 1035} 1036 1037/* This is only called when expecting a tiled layout. */ 1038static int 1039gfx9_get_preferred_swizzle_mode(ADDR_HANDLE addrlib, 1040 ADDR2_COMPUTE_SURFACE_INFO_INPUT *in, 1041 bool is_fmask, unsigned flags, 1042 AddrSwizzleMode *swizzle_mode) 1043{ 1044 ADDR_E_RETURNCODE ret; 1045 ADDR2_GET_PREFERRED_SURF_SETTING_INPUT sin = {0}; 1046 ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT sout = {0}; 1047 1048 sin.size = sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_INPUT); 1049 sout.size = sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT); 1050 1051 sin.flags = in->flags; 1052 sin.resourceType = in->resourceType; 1053 sin.format = in->format; 1054 sin.resourceLoction = ADDR_RSRC_LOC_INVIS; 1055 /* TODO: We could allow some of these: */ 1056 sin.forbiddenBlock.micro = 1; /* don't allow the 256B swizzle modes */ 1057 sin.forbiddenBlock.var = 1; /* don't allow the variable-sized swizzle modes */ 1058 sin.forbiddenBlock.linear = 1; /* don't allow linear swizzle modes */ 1059 sin.bpp = in->bpp; 1060 sin.width = in->width; 1061 sin.height = in->height; 1062 sin.numSlices = in->numSlices; 1063 sin.numMipLevels = in->numMipLevels; 1064 sin.numSamples = in->numSamples; 1065 sin.numFrags = in->numFrags; 1066 1067 if (flags & RADEON_SURF_SCANOUT) { 1068 sin.preferredSwSet.sw_D = 1; 1069 /* Raven only allows S for displayable surfaces with < 64 bpp, so 1070 * allow it as fallback */ 1071 sin.preferredSwSet.sw_S = 1; 1072 } else if (in->flags.depth || in->flags.stencil || is_fmask) 1073 sin.preferredSwSet.sw_Z = 1; 1074 else 1075 sin.preferredSwSet.sw_S = 1; 1076 1077 if (is_fmask) { 1078 sin.flags.display = 0; 1079 sin.flags.color = 0; 1080 sin.flags.fmask = 1; 1081 } 1082 1083 ret = Addr2GetPreferredSurfaceSetting(addrlib, &sin, &sout); 1084 if (ret != ADDR_OK) 1085 return ret; 1086 1087 *swizzle_mode = sout.swizzleMode; 1088 return 0; 1089} 1090 1091static int gfx9_compute_miptree(ADDR_HANDLE addrlib, 1092 const struct ac_surf_config *config, 1093 struct radeon_surf *surf, bool compressed, 1094 ADDR2_COMPUTE_SURFACE_INFO_INPUT *in) 1095{ 1096 ADDR2_MIP_INFO mip_info[RADEON_SURF_MAX_LEVELS] = {}; 1097 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT out = {0}; 1098 ADDR_E_RETURNCODE ret; 1099 1100 out.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT); 1101 out.pMipInfo = mip_info; 1102 1103 ret = Addr2ComputeSurfaceInfo(addrlib, in, &out); 1104 if (ret != ADDR_OK) 1105 return ret; 1106 1107 if (in->flags.stencil) { 1108 surf->u.gfx9.stencil.swizzle_mode = in->swizzleMode; 1109 surf->u.gfx9.stencil.epitch = out.epitchIsHeight ? out.mipChainHeight - 1 : 1110 out.mipChainPitch - 1; 1111 surf->surf_alignment = MAX2(surf->surf_alignment, out.baseAlign); 1112 surf->u.gfx9.stencil_offset = align(surf->surf_size, out.baseAlign); 1113 surf->surf_size = surf->u.gfx9.stencil_offset + out.surfSize; 1114 return 0; 1115 } 1116 1117 surf->u.gfx9.surf.swizzle_mode = in->swizzleMode; 1118 surf->u.gfx9.surf.epitch = out.epitchIsHeight ? out.mipChainHeight - 1 : 1119 out.mipChainPitch - 1; 1120 1121 /* CMASK fast clear uses these even if FMASK isn't allocated. 1122 * FMASK only supports the Z swizzle modes, whose numbers are multiples of 4. 1123 */ 1124 surf->u.gfx9.fmask.swizzle_mode = surf->u.gfx9.surf.swizzle_mode & ~0x3; 1125 surf->u.gfx9.fmask.epitch = surf->u.gfx9.surf.epitch; 1126 1127 surf->u.gfx9.surf_slice_size = out.sliceSize; 1128 surf->u.gfx9.surf_pitch = out.pitch; 1129 surf->u.gfx9.surf_height = out.height; 1130 surf->surf_size = out.surfSize; 1131 surf->surf_alignment = out.baseAlign; 1132 1133 if (in->swizzleMode == ADDR_SW_LINEAR) { 1134 for (unsigned i = 0; i < in->numMipLevels; i++) 1135 surf->u.gfx9.offset[i] = mip_info[i].offset; 1136 } 1137 1138 if (in->flags.depth) { 1139 assert(in->swizzleMode != ADDR_SW_LINEAR); 1140 1141 /* HTILE */ 1142 ADDR2_COMPUTE_HTILE_INFO_INPUT hin = {0}; 1143 ADDR2_COMPUTE_HTILE_INFO_OUTPUT hout = {0}; 1144 1145 hin.size = sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT); 1146 hout.size = sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT); 1147 1148 hin.hTileFlags.pipeAligned = !in->flags.metaPipeUnaligned; 1149 hin.hTileFlags.rbAligned = !in->flags.metaRbUnaligned; 1150 hin.depthFlags = in->flags; 1151 hin.swizzleMode = in->swizzleMode; 1152 hin.unalignedWidth = in->width; 1153 hin.unalignedHeight = in->height; 1154 hin.numSlices = in->numSlices; 1155 hin.numMipLevels = in->numMipLevels; 1156 1157 ret = Addr2ComputeHtileInfo(addrlib, &hin, &hout); 1158 if (ret != ADDR_OK) 1159 return ret; 1160 1161 surf->u.gfx9.htile.rb_aligned = hin.hTileFlags.rbAligned; 1162 surf->u.gfx9.htile.pipe_aligned = hin.hTileFlags.pipeAligned; 1163 surf->htile_size = hout.htileBytes; 1164 surf->htile_slice_size = hout.sliceSize; 1165 surf->htile_alignment = hout.baseAlign; 1166 } else { 1167 /* Compute tile swizzle for the color surface. 1168 * All *_X and *_T modes can use the swizzle. 1169 */ 1170 if (config->info.surf_index && 1171 in->swizzleMode >= ADDR_SW_64KB_Z_T && 1172 !out.mipChainInTail && 1173 !(surf->flags & RADEON_SURF_SHAREABLE) && 1174 !in->flags.display) { 1175 ADDR2_COMPUTE_PIPEBANKXOR_INPUT xin = {0}; 1176 ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT xout = {0}; 1177 1178 xin.size = sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT); 1179 xout.size = sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT); 1180 1181 xin.surfIndex = p_atomic_inc_return(config->info.surf_index) - 1; 1182 xin.flags = in->flags; 1183 xin.swizzleMode = in->swizzleMode; 1184 xin.resourceType = in->resourceType; 1185 xin.format = in->format; 1186 xin.numSamples = in->numSamples; 1187 xin.numFrags = in->numFrags; 1188 1189 ret = Addr2ComputePipeBankXor(addrlib, &xin, &xout); 1190 if (ret != ADDR_OK) 1191 return ret; 1192 1193 assert(xout.pipeBankXor <= 1194 u_bit_consecutive(0, sizeof(surf->tile_swizzle) * 8)); 1195 surf->tile_swizzle = xout.pipeBankXor; 1196 } 1197 1198 /* DCC */ 1199 if (!(surf->flags & RADEON_SURF_DISABLE_DCC) && 1200 !compressed && 1201 in->swizzleMode != ADDR_SW_LINEAR) { 1202 ADDR2_COMPUTE_DCCINFO_INPUT din = {0}; 1203 ADDR2_COMPUTE_DCCINFO_OUTPUT dout = {0}; 1204 ADDR2_META_MIP_INFO meta_mip_info[RADEON_SURF_MAX_LEVELS] = {}; 1205 1206 din.size = sizeof(ADDR2_COMPUTE_DCCINFO_INPUT); 1207 dout.size = sizeof(ADDR2_COMPUTE_DCCINFO_OUTPUT); 1208 dout.pMipInfo = meta_mip_info; 1209 1210 din.dccKeyFlags.pipeAligned = !in->flags.metaPipeUnaligned; 1211 din.dccKeyFlags.rbAligned = !in->flags.metaRbUnaligned; 1212 din.colorFlags = in->flags; 1213 din.resourceType = in->resourceType; 1214 din.swizzleMode = in->swizzleMode; 1215 din.bpp = in->bpp; 1216 din.unalignedWidth = in->width; 1217 din.unalignedHeight = in->height; 1218 din.numSlices = in->numSlices; 1219 din.numFrags = in->numFrags; 1220 din.numMipLevels = in->numMipLevels; 1221 din.dataSurfaceSize = out.surfSize; 1222 1223 ret = Addr2ComputeDccInfo(addrlib, &din, &dout); 1224 if (ret != ADDR_OK) 1225 return ret; 1226 1227 surf->u.gfx9.dcc.rb_aligned = din.dccKeyFlags.rbAligned; 1228 surf->u.gfx9.dcc.pipe_aligned = din.dccKeyFlags.pipeAligned; 1229 surf->u.gfx9.dcc_pitch_max = dout.pitch - 1; 1230 surf->dcc_size = dout.dccRamSize; 1231 surf->dcc_alignment = dout.dccRamBaseAlign; 1232 surf->num_dcc_levels = in->numMipLevels; 1233 1234 /* Disable DCC for levels that are in the mip tail. 1235 * 1236 * There are two issues that this is intended to 1237 * address: 1238 * 1239 * 1. Multiple mip levels may share a cache line. This 1240 * can lead to corruption when switching between 1241 * rendering to different mip levels because the 1242 * RBs don't maintain coherency. 1243 * 1244 * 2. Texturing with metadata after rendering sometimes 1245 * fails with corruption, probably for a similar 1246 * reason. 1247 * 1248 * Working around these issues for all levels in the 1249 * mip tail may be overly conservative, but it's what 1250 * Vulkan does. 1251 * 1252 * Alternative solutions that also work but are worse: 1253 * - Disable DCC entirely. 1254 * - Flush TC L2 after rendering. 1255 */ 1256 for (unsigned i = 0; i < in->numMipLevels; i++) { 1257 if (meta_mip_info[i].inMiptail) { 1258 surf->num_dcc_levels = i; 1259 break; 1260 } 1261 } 1262 1263 if (!surf->num_dcc_levels) 1264 surf->dcc_size = 0; 1265 } 1266 1267 /* FMASK */ 1268 if (in->numSamples > 1) { 1269 ADDR2_COMPUTE_FMASK_INFO_INPUT fin = {0}; 1270 ADDR2_COMPUTE_FMASK_INFO_OUTPUT fout = {0}; 1271 1272 fin.size = sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT); 1273 fout.size = sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT); 1274 1275 ret = gfx9_get_preferred_swizzle_mode(addrlib, in, 1276 true, surf->flags, 1277 &fin.swizzleMode); 1278 if (ret != ADDR_OK) 1279 return ret; 1280 1281 fin.unalignedWidth = in->width; 1282 fin.unalignedHeight = in->height; 1283 fin.numSlices = in->numSlices; 1284 fin.numSamples = in->numSamples; 1285 fin.numFrags = in->numFrags; 1286 1287 ret = Addr2ComputeFmaskInfo(addrlib, &fin, &fout); 1288 if (ret != ADDR_OK) 1289 return ret; 1290 1291 surf->u.gfx9.fmask.swizzle_mode = fin.swizzleMode; 1292 surf->u.gfx9.fmask.epitch = fout.pitch - 1; 1293 surf->fmask_size = fout.fmaskBytes; 1294 surf->fmask_alignment = fout.baseAlign; 1295 1296 /* Compute tile swizzle for the FMASK surface. */ 1297 if (config->info.fmask_surf_index && 1298 fin.swizzleMode >= ADDR_SW_64KB_Z_T && 1299 !(surf->flags & RADEON_SURF_SHAREABLE)) { 1300 ADDR2_COMPUTE_PIPEBANKXOR_INPUT xin = {0}; 1301 ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT xout = {0}; 1302 1303 xin.size = sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT); 1304 xout.size = sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT); 1305 1306 /* This counter starts from 1 instead of 0. */ 1307 xin.surfIndex = p_atomic_inc_return(config->info.fmask_surf_index); 1308 xin.flags = in->flags; 1309 xin.swizzleMode = fin.swizzleMode; 1310 xin.resourceType = in->resourceType; 1311 xin.format = in->format; 1312 xin.numSamples = in->numSamples; 1313 xin.numFrags = in->numFrags; 1314 1315 ret = Addr2ComputePipeBankXor(addrlib, &xin, &xout); 1316 if (ret != ADDR_OK) 1317 return ret; 1318 1319 assert(xout.pipeBankXor <= 1320 u_bit_consecutive(0, sizeof(surf->fmask_tile_swizzle) * 8)); 1321 surf->fmask_tile_swizzle = xout.pipeBankXor; 1322 } 1323 } 1324 1325 /* CMASK */ 1326 if (in->swizzleMode != ADDR_SW_LINEAR) { 1327 ADDR2_COMPUTE_CMASK_INFO_INPUT cin = {0}; 1328 ADDR2_COMPUTE_CMASK_INFO_OUTPUT cout = {0}; 1329 1330 cin.size = sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT); 1331 cout.size = sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT); 1332 1333 if (in->numSamples > 1) { 1334 /* FMASK is always aligned. */ 1335 cin.cMaskFlags.pipeAligned = 1; 1336 cin.cMaskFlags.rbAligned = 1; 1337 } else { 1338 cin.cMaskFlags.pipeAligned = !in->flags.metaPipeUnaligned; 1339 cin.cMaskFlags.rbAligned = !in->flags.metaRbUnaligned; 1340 } 1341 cin.colorFlags = in->flags; 1342 cin.resourceType = in->resourceType; 1343 cin.unalignedWidth = in->width; 1344 cin.unalignedHeight = in->height; 1345 cin.numSlices = in->numSlices; 1346 1347 if (in->numSamples > 1) 1348 cin.swizzleMode = surf->u.gfx9.fmask.swizzle_mode; 1349 else 1350 cin.swizzleMode = in->swizzleMode; 1351 1352 ret = Addr2ComputeCmaskInfo(addrlib, &cin, &cout); 1353 if (ret != ADDR_OK) 1354 return ret; 1355 1356 surf->u.gfx9.cmask.rb_aligned = cin.cMaskFlags.rbAligned; 1357 surf->u.gfx9.cmask.pipe_aligned = cin.cMaskFlags.pipeAligned; 1358 surf->cmask_size = cout.cmaskBytes; 1359 surf->cmask_alignment = cout.baseAlign; 1360 } 1361 } 1362 1363 return 0; 1364} 1365 1366static int gfx9_compute_surface(ADDR_HANDLE addrlib, 1367 const struct radeon_info *info, 1368 const struct ac_surf_config *config, 1369 enum radeon_surf_mode mode, 1370 struct radeon_surf *surf) 1371{ 1372 bool compressed; 1373 ADDR2_COMPUTE_SURFACE_INFO_INPUT AddrSurfInfoIn = {0}; 1374 int r; 1375 1376 AddrSurfInfoIn.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT); 1377 1378 compressed = surf->blk_w == 4 && surf->blk_h == 4; 1379 1380 /* The format must be set correctly for the allocation of compressed 1381 * textures to work. In other cases, setting the bpp is sufficient. */ 1382 if (compressed) { 1383 switch (surf->bpe) { 1384 case 8: 1385 AddrSurfInfoIn.format = ADDR_FMT_BC1; 1386 break; 1387 case 16: 1388 AddrSurfInfoIn.format = ADDR_FMT_BC3; 1389 break; 1390 default: 1391 assert(0); 1392 } 1393 } else { 1394 switch (surf->bpe) { 1395 case 1: 1396 assert(!(surf->flags & RADEON_SURF_ZBUFFER)); 1397 AddrSurfInfoIn.format = ADDR_FMT_8; 1398 break; 1399 case 2: 1400 assert(surf->flags & RADEON_SURF_ZBUFFER || 1401 !(surf->flags & RADEON_SURF_SBUFFER)); 1402 AddrSurfInfoIn.format = ADDR_FMT_16; 1403 break; 1404 case 4: 1405 assert(surf->flags & RADEON_SURF_ZBUFFER || 1406 !(surf->flags & RADEON_SURF_SBUFFER)); 1407 AddrSurfInfoIn.format = ADDR_FMT_32; 1408 break; 1409 case 8: 1410 assert(!(surf->flags & RADEON_SURF_Z_OR_SBUFFER)); 1411 AddrSurfInfoIn.format = ADDR_FMT_32_32; 1412 break; 1413 case 12: 1414 assert(!(surf->flags & RADEON_SURF_Z_OR_SBUFFER)); 1415 AddrSurfInfoIn.format = ADDR_FMT_32_32_32; 1416 break; 1417 case 16: 1418 assert(!(surf->flags & RADEON_SURF_Z_OR_SBUFFER)); 1419 AddrSurfInfoIn.format = ADDR_FMT_32_32_32_32; 1420 break; 1421 default: 1422 assert(0); 1423 } 1424 AddrSurfInfoIn.bpp = surf->bpe * 8; 1425 } 1426 1427 AddrSurfInfoIn.flags.color = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER); 1428 AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0; 1429 AddrSurfInfoIn.flags.display = get_display_flag(config, surf); 1430 /* flags.texture currently refers to TC-compatible HTILE */ 1431 AddrSurfInfoIn.flags.texture = AddrSurfInfoIn.flags.color || 1432 surf->flags & RADEON_SURF_TC_COMPATIBLE_HTILE; 1433 AddrSurfInfoIn.flags.opt4space = 1; 1434 1435 AddrSurfInfoIn.numMipLevels = config->info.levels; 1436 AddrSurfInfoIn.numSamples = MAX2(1, config->info.samples); 1437 AddrSurfInfoIn.numFrags = AddrSurfInfoIn.numSamples; 1438 1439 if (!(surf->flags & RADEON_SURF_Z_OR_SBUFFER)) 1440 AddrSurfInfoIn.numFrags = MAX2(1, config->info.storage_samples); 1441 1442 /* GFX9 doesn't support 1D depth textures, so allocate all 1D textures 1443 * as 2D to avoid having shader variants for 1D vs 2D, so all shaders 1444 * must sample 1D textures as 2D. */ 1445 if (config->is_3d) 1446 AddrSurfInfoIn.resourceType = ADDR_RSRC_TEX_3D; 1447 else 1448 AddrSurfInfoIn.resourceType = ADDR_RSRC_TEX_2D; 1449 1450 AddrSurfInfoIn.width = config->info.width; 1451 AddrSurfInfoIn.height = config->info.height; 1452 1453 if (config->is_3d) 1454 AddrSurfInfoIn.numSlices = config->info.depth; 1455 else if (config->is_cube) 1456 AddrSurfInfoIn.numSlices = 6; 1457 else 1458 AddrSurfInfoIn.numSlices = config->info.array_size; 1459 1460 /* This is propagated to HTILE/DCC/CMASK. */ 1461 AddrSurfInfoIn.flags.metaPipeUnaligned = 0; 1462 AddrSurfInfoIn.flags.metaRbUnaligned = 0; 1463 1464 switch (mode) { 1465 case RADEON_SURF_MODE_LINEAR_ALIGNED: 1466 assert(config->info.samples <= 1); 1467 assert(!(surf->flags & RADEON_SURF_Z_OR_SBUFFER)); 1468 AddrSurfInfoIn.swizzleMode = ADDR_SW_LINEAR; 1469 break; 1470 1471 case RADEON_SURF_MODE_1D: 1472 case RADEON_SURF_MODE_2D: 1473 if (surf->flags & RADEON_SURF_IMPORTED) { 1474 AddrSurfInfoIn.swizzleMode = surf->u.gfx9.surf.swizzle_mode; 1475 break; 1476 } 1477 1478 r = gfx9_get_preferred_swizzle_mode(addrlib, &AddrSurfInfoIn, 1479 false, surf->flags, 1480 &AddrSurfInfoIn.swizzleMode); 1481 if (r) 1482 return r; 1483 break; 1484 1485 default: 1486 assert(0); 1487 } 1488 1489 surf->u.gfx9.resource_type = AddrSurfInfoIn.resourceType; 1490 surf->has_stencil = !!(surf->flags & RADEON_SURF_SBUFFER); 1491 1492 surf->num_dcc_levels = 0; 1493 surf->surf_size = 0; 1494 surf->fmask_size = 0; 1495 surf->dcc_size = 0; 1496 surf->htile_size = 0; 1497 surf->htile_slice_size = 0; 1498 surf->u.gfx9.surf_offset = 0; 1499 surf->u.gfx9.stencil_offset = 0; 1500 surf->cmask_size = 0; 1501 1502 /* Calculate texture layout information. */ 1503 r = gfx9_compute_miptree(addrlib, config, surf, compressed, 1504 &AddrSurfInfoIn); 1505 if (r) 1506 return r; 1507 1508 /* Calculate texture layout information for stencil. */ 1509 if (surf->flags & RADEON_SURF_SBUFFER) { 1510 AddrSurfInfoIn.flags.stencil = 1; 1511 AddrSurfInfoIn.bpp = 8; 1512 AddrSurfInfoIn.format = ADDR_FMT_8; 1513 1514 if (!AddrSurfInfoIn.flags.depth) { 1515 r = gfx9_get_preferred_swizzle_mode(addrlib, &AddrSurfInfoIn, 1516 false, surf->flags, 1517 &AddrSurfInfoIn.swizzleMode); 1518 if (r) 1519 return r; 1520 } else 1521 AddrSurfInfoIn.flags.depth = 0; 1522 1523 r = gfx9_compute_miptree(addrlib, config, surf, compressed, 1524 &AddrSurfInfoIn); 1525 if (r) 1526 return r; 1527 } 1528 1529 surf->is_linear = surf->u.gfx9.surf.swizzle_mode == ADDR_SW_LINEAR; 1530 1531 /* Query whether the surface is displayable. */ 1532 bool displayable = false; 1533 r = Addr2IsValidDisplaySwizzleMode(addrlib, surf->u.gfx9.surf.swizzle_mode, 1534 surf->bpe * 8, &displayable); 1535 if (r) 1536 return r; 1537 surf->is_displayable = displayable; 1538 1539 switch (surf->u.gfx9.surf.swizzle_mode) { 1540 /* S = standard. */ 1541 case ADDR_SW_256B_S: 1542 case ADDR_SW_4KB_S: 1543 case ADDR_SW_64KB_S: 1544 case ADDR_SW_VAR_S: 1545 case ADDR_SW_64KB_S_T: 1546 case ADDR_SW_4KB_S_X: 1547 case ADDR_SW_64KB_S_X: 1548 case ADDR_SW_VAR_S_X: 1549 surf->micro_tile_mode = RADEON_MICRO_MODE_THIN; 1550 break; 1551 1552 /* D = display. */ 1553 case ADDR_SW_LINEAR: 1554 case ADDR_SW_256B_D: 1555 case ADDR_SW_4KB_D: 1556 case ADDR_SW_64KB_D: 1557 case ADDR_SW_VAR_D: 1558 case ADDR_SW_64KB_D_T: 1559 case ADDR_SW_4KB_D_X: 1560 case ADDR_SW_64KB_D_X: 1561 case ADDR_SW_VAR_D_X: 1562 surf->micro_tile_mode = RADEON_MICRO_MODE_DISPLAY; 1563 break; 1564 1565 /* R = rotated. */ 1566 case ADDR_SW_256B_R: 1567 case ADDR_SW_4KB_R: 1568 case ADDR_SW_64KB_R: 1569 case ADDR_SW_VAR_R: 1570 case ADDR_SW_64KB_R_T: 1571 case ADDR_SW_4KB_R_X: 1572 case ADDR_SW_64KB_R_X: 1573 case ADDR_SW_VAR_R_X: 1574 /* The rotated micro tile mode doesn't work if both CMASK and RB+ are 1575 * used at the same time. This case is not currently expected to occur 1576 * because we don't use rotated. Enforce this restriction on all chips 1577 * to facilitate testing. 1578 */ 1579 assert(!"rotate micro tile mode is unsupported"); 1580 return ADDR_ERROR; 1581 1582 /* Z = depth. */ 1583 case ADDR_SW_4KB_Z: 1584 case ADDR_SW_64KB_Z: 1585 case ADDR_SW_VAR_Z: 1586 case ADDR_SW_64KB_Z_T: 1587 case ADDR_SW_4KB_Z_X: 1588 case ADDR_SW_64KB_Z_X: 1589 case ADDR_SW_VAR_Z_X: 1590 surf->micro_tile_mode = RADEON_MICRO_MODE_DEPTH; 1591 break; 1592 1593 default: 1594 assert(0); 1595 } 1596 1597 /* Temporary workaround to prevent VM faults and hangs. */ 1598 if (info->family == CHIP_VEGA12) 1599 surf->fmask_size *= 8; 1600 1601 return 0; 1602} 1603 1604int ac_compute_surface(ADDR_HANDLE addrlib, const struct radeon_info *info, 1605 const struct ac_surf_config *config, 1606 enum radeon_surf_mode mode, 1607 struct radeon_surf *surf) 1608{ 1609 int r; 1610 1611 r = surf_config_sanity(config, surf->flags); 1612 if (r) 1613 return r; 1614 1615 if (info->chip_class >= GFX9) 1616 return gfx9_compute_surface(addrlib, info, config, mode, surf); 1617 else 1618 return gfx6_compute_surface(addrlib, info, config, mode, surf); 1619} 1620