1 /* 2 * Copyright 2014 Advanced Micro Devices, Inc. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS 17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 * USE OR OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * The above copyright notice and this permission notice (including the 23 * next paragraph) shall be included in all copies or substantial portions 24 * of the Software. 25 */ 26 27 /** 28 *************************************************************************************************** 29 * @file ciaddrlib.cpp 30 * @brief Contains the implementation for the CIAddrLib class. 31 *************************************************************************************************** 32 */ 33 34 #include "ciaddrlib.h" 35 36 #include "si_gb_reg.h" 37 38 #include "si_ci_vi_merged_enum.h" 39 40 #if BRAHMA_BUILD 41 #include "amdgpu_id.h" 42 #else 43 #include "ci_id.h" 44 #include "kv_id.h" 45 #include "vi_id.h" 46 #endif 47 48 /////////////////////////////////////////////////////////////////////////////////////////////////// 49 /////////////////////////////////////////////////////////////////////////////////////////////////// 50 51 /** 52 *************************************************************************************************** 53 * AddrMask 54 * 55 * @brief 56 * Gets a mask of "width" 57 * @return 58 * Bit mask 59 *************************************************************************************************** 60 */ 61 static UINT_64 AddrMask( 62 UINT_32 width) ///< Width of bits 63 { 64 UINT_64 ret; 65 66 if (width >= sizeof(UINT_64)*8) 67 { 68 ret = ~((UINT_64) 0); 69 } 70 else 71 { 72 return (((UINT_64) 1) << width) - 1; 73 } 74 return ret; 75 } 76 77 /** 78 *************************************************************************************************** 79 * AddrGetBits 80 * 81 * @brief 82 * Gets bits within a range of [msb, lsb] 83 * @return 84 * Bits of this range 85 *************************************************************************************************** 86 */ 87 static UINT_64 AddrGetBits( 88 UINT_64 bits, ///< Source bits 89 UINT_32 msb, ///< Most signicant bit 90 UINT_32 lsb) ///< Least signicant bit 91 { 92 UINT_64 ret = 0; 93 94 if (msb >= lsb) 95 { 96 ret = (bits >> lsb) & (AddrMask(1 + msb - lsb)); 97 } 98 return ret; 99 } 100 101 /** 102 *************************************************************************************************** 103 * AddrRemoveBits 104 * 105 * @brief 106 * Removes bits within the range of [msb, lsb] 107 * @return 108 * Modified bits 109 *************************************************************************************************** 110 */ 111 static UINT_64 AddrRemoveBits( 112 UINT_64 bits, ///< Source bits 113 UINT_32 msb, ///< Most signicant bit 114 UINT_32 lsb) ///< Least signicant bit 115 { 116 UINT_64 ret = bits; 117 118 if (msb >= lsb) 119 { 120 ret = AddrGetBits(bits, lsb - 1, 0) // low bits 121 | (AddrGetBits(bits, 8 * sizeof(bits) - 1, msb + 1) << lsb); //high bits 122 } 123 return ret; 124 } 125 126 /** 127 *************************************************************************************************** 128 * AddrInsertBits 129 * 130 * @brief 131 * Inserts new bits into the range of [msb, lsb] 132 * @return 133 * Modified bits 134 *************************************************************************************************** 135 */ 136 static UINT_64 AddrInsertBits( 137 UINT_64 bits, ///< Source bits 138 UINT_64 newBits, ///< New bits to be inserted 139 UINT_32 msb, ///< Most signicant bit 140 UINT_32 lsb) ///< Least signicant bit 141 { 142 UINT_64 ret = bits; 143 144 if (msb >= lsb) 145 { 146 ret = AddrGetBits(bits, lsb - 1, 0) // old low bitss 147 | (AddrGetBits(newBits, msb - lsb, 0) << lsb) //new bits 148 | (AddrGetBits(bits, 8 * sizeof(bits) - 1, lsb) << (msb + 1)); //old high bits 149 } 150 return ret; 151 } 152 153 154 /** 155 *************************************************************************************************** 156 * AddrCIHwlInit 157 * 158 * @brief 159 * Creates an CIAddrLib object. 160 * 161 * @return 162 * Returns an CIAddrLib object pointer. 163 *************************************************************************************************** 164 */ 165 AddrLib* AddrCIHwlInit(const AddrClient* pClient) 166 { 167 return CIAddrLib::CreateObj(pClient); 168 } 169 170 /** 171 *************************************************************************************************** 172 * CIAddrLib::CIAddrLib 173 * 174 * @brief 175 * Constructor 176 * 177 *************************************************************************************************** 178 */ 179 CIAddrLib::CIAddrLib(const AddrClient* pClient) : 180 SIAddrLib(pClient), 181 m_noOfMacroEntries(0), 182 m_allowNonDispThickModes(FALSE) 183 { 184 m_class = CI_ADDRLIB; 185 memset(&m_settings, 0, sizeof(m_settings)); 186 } 187 188 /** 189 *************************************************************************************************** 190 * CIAddrLib::~CIAddrLib 191 * 192 * @brief 193 * Destructor 194 *************************************************************************************************** 195 */ 196 CIAddrLib::~CIAddrLib() 197 { 198 } 199 200 /** 201 *************************************************************************************************** 202 * CIAddrLib::HwlComputeDccInfo 203 * 204 * @brief 205 * Compute DCC key size, base alignment 206 * @return 207 * ADDR_E_RETURNCODE 208 *************************************************************************************************** 209 */ 210 ADDR_E_RETURNCODE CIAddrLib::HwlComputeDccInfo( 211 const ADDR_COMPUTE_DCCINFO_INPUT* pIn, 212 ADDR_COMPUTE_DCCINFO_OUTPUT* pOut) const 213 { 214 ADDR_E_RETURNCODE returnCode = ADDR_OK; 215 216 if (m_settings.isVolcanicIslands && IsMacroTiled(pIn->tileMode)) 217 { 218 UINT_64 dccFastClearSize = pIn->colorSurfSize >> 8; 219 220 ADDR_ASSERT(0 == (pIn->colorSurfSize & 0xff)); 221 222 if (pIn->numSamples > 1) 223 { 224 UINT_32 tileSizePerSample = BITS_TO_BYTES(pIn->bpp * MicroTileWidth * MicroTileHeight); 225 UINT_32 samplesPerSplit = pIn->tileInfo.tileSplitBytes / tileSizePerSample; 226 227 if (samplesPerSplit < pIn->numSamples) 228 { 229 UINT_32 numSplits = pIn->numSamples / samplesPerSplit; 230 UINT_32 fastClearBaseAlign = HwlGetPipes(&pIn->tileInfo) * m_pipeInterleaveBytes; 231 232 ADDR_ASSERT(IsPow2(fastClearBaseAlign)); 233 234 dccFastClearSize /= numSplits; 235 236 if (0 != (dccFastClearSize & (fastClearBaseAlign - 1))) 237 { 238 // Disable dcc fast clear 239 // if key size of fisrt sample split is not pipe*interleave aligned 240 dccFastClearSize = 0; 241 } 242 } 243 } 244 245 pOut->dccRamSize = pIn->colorSurfSize >> 8; 246 pOut->dccRamBaseAlign = pIn->tileInfo.banks * 247 HwlGetPipes(&pIn->tileInfo) * 248 m_pipeInterleaveBytes; 249 pOut->dccFastClearSize = dccFastClearSize; 250 251 ADDR_ASSERT(IsPow2(pOut->dccRamBaseAlign)); 252 253 if (0 == (pOut->dccRamSize & (pOut->dccRamBaseAlign - 1))) 254 { 255 pOut->subLvlCompressible = TRUE; 256 } 257 else 258 { 259 UINT_64 dccRamSizeAlign = HwlGetPipes(&pIn->tileInfo) * m_pipeInterleaveBytes; 260 261 if (pOut->dccRamSize == pOut->dccFastClearSize) 262 { 263 pOut->dccFastClearSize = PowTwoAlign(pOut->dccRamSize, dccRamSizeAlign); 264 } 265 pOut->dccRamSize = PowTwoAlign(pOut->dccRamSize, dccRamSizeAlign); 266 pOut->subLvlCompressible = FALSE; 267 } 268 } 269 else 270 { 271 returnCode = ADDR_NOTSUPPORTED; 272 } 273 274 return returnCode; 275 } 276 277 /** 278 *************************************************************************************************** 279 * CIAddrLib::HwlComputeCmaskAddrFromCoord 280 * 281 * @brief 282 * Compute tc compatible Cmask address from fmask ram address 283 * 284 * @return 285 * ADDR_E_RETURNCODE 286 *************************************************************************************************** 287 */ 288 ADDR_E_RETURNCODE CIAddrLib::HwlComputeCmaskAddrFromCoord( 289 const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] fmask addr/bpp/tile input 290 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] cmask address 291 ) const 292 { 293 ADDR_E_RETURNCODE returnCode = ADDR_NOTSUPPORTED; 294 295 if ((m_settings.isVolcanicIslands == TRUE) && 296 (pIn->flags.tcCompatible == TRUE)) 297 { 298 UINT_32 numOfPipes = HwlGetPipes(pIn->pTileInfo); 299 UINT_32 numOfBanks = pIn->pTileInfo->banks; 300 UINT_64 fmaskAddress = pIn->fmaskAddr; 301 UINT_32 elemBits = pIn->bpp; 302 UINT_32 blockByte = 64 * elemBits / 8; 303 UINT_64 metaNibbleAddress = HwlComputeMetadataNibbleAddress(fmaskAddress, 304 0, 305 0, 306 4, 307 elemBits, 308 blockByte, 309 m_pipeInterleaveBytes, 310 numOfPipes, 311 numOfBanks, 312 1); 313 pOut->addr = (metaNibbleAddress >> 1); 314 pOut->bitPosition = (metaNibbleAddress % 2) ? 4 : 0; 315 returnCode = ADDR_OK; 316 } 317 318 return returnCode; 319 } 320 /** 321 *************************************************************************************************** 322 * CIAddrLib::HwlConvertChipFamily 323 * 324 * @brief 325 * Convert familyID defined in atiid.h to AddrChipFamily and set m_chipFamily/m_chipRevision 326 * @return 327 * AddrChipFamily 328 *************************************************************************************************** 329 */ 330 AddrChipFamily CIAddrLib::HwlConvertChipFamily( 331 UINT_32 uChipFamily, ///< [in] chip family defined in atiih.h 332 UINT_32 uChipRevision) ///< [in] chip revision defined in "asic_family"_id.h 333 { 334 AddrChipFamily family = ADDR_CHIP_FAMILY_CI; 335 336 switch (uChipFamily) 337 { 338 case FAMILY_CI: 339 m_settings.isSeaIsland = 1; 340 m_settings.isBonaire = ASICREV_IS_BONAIRE_M(uChipRevision); 341 m_settings.isHawaii = ASICREV_IS_HAWAII_P(uChipRevision); 342 break; 343 case FAMILY_KV: 344 m_settings.isKaveri = 1; 345 m_settings.isSpectre = ASICREV_IS_SPECTRE(uChipRevision); 346 m_settings.isSpooky = ASICREV_IS_SPOOKY(uChipRevision); 347 m_settings.isKalindi = ASICREV_IS_KALINDI(uChipRevision); 348 break; 349 case FAMILY_VI: 350 m_settings.isVolcanicIslands = 1; 351 m_settings.isIceland = ASICREV_IS_ICELAND_M(uChipRevision); 352 m_settings.isTonga = ASICREV_IS_TONGA_P(uChipRevision); 353 m_settings.isFiji = ASICREV_IS_FIJI_P(uChipRevision); 354 m_settings.isPolaris10 = ASICREV_IS_POLARIS10_P(uChipRevision); 355 m_settings.isPolaris11 = ASICREV_IS_POLARIS11_M(uChipRevision); 356 m_settings.isPolaris12 = ASICREV_IS_POLARIS12_V(uChipRevision); 357 break; 358 case FAMILY_CZ: 359 m_settings.isCarrizo = 1; 360 m_settings.isVolcanicIslands = 1; 361 break; 362 default: 363 ADDR_ASSERT(!"This should be a unexpected Fusion"); 364 break; 365 } 366 367 return family; 368 } 369 370 /** 371 *************************************************************************************************** 372 * CIAddrLib::HwlInitGlobalParams 373 * 374 * @brief 375 * Initializes global parameters 376 * 377 * @return 378 * TRUE if all settings are valid 379 * 380 *************************************************************************************************** 381 */ 382 BOOL_32 CIAddrLib::HwlInitGlobalParams( 383 const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input 384 { 385 BOOL_32 valid = TRUE; 386 387 const ADDR_REGISTER_VALUE* pRegValue = &pCreateIn->regValue; 388 389 valid = DecodeGbRegs(pRegValue); 390 391 // The following assignments for m_pipes is only for fail-safe, InitTileSettingTable should 392 // read the correct pipes from tile mode table 393 if (m_settings.isHawaii) 394 { 395 // Hawaii has 16-pipe, see GFXIP_Config_Summary.xls 396 m_pipes = 16; 397 } 398 else if (m_settings.isBonaire || m_settings.isSpectre) 399 { 400 m_pipes = 4; 401 } 402 else // Treat other KV asics to be 2-pipe 403 { 404 m_pipes = 2; 405 } 406 407 // @todo: VI 408 // Move this to VI code path once created 409 if (m_settings.isTonga || m_settings.isPolaris10) 410 { 411 m_pipes = 8; 412 } 413 else if (m_settings.isIceland) 414 { 415 m_pipes = 2; 416 } 417 else if (m_settings.isFiji) 418 { 419 m_pipes = 16; 420 } 421 else if (m_settings.isPolaris11 || m_settings.isPolaris12) 422 { 423 m_pipes = 4; 424 } 425 426 if (valid) 427 { 428 valid = InitTileSettingTable(pRegValue->pTileConfig, pRegValue->noOfEntries); 429 } 430 if (valid) 431 { 432 valid = InitMacroTileCfgTable(pRegValue->pMacroTileConfig, pRegValue->noOfMacroEntries); 433 } 434 435 return valid; 436 } 437 438 /** 439 *************************************************************************************************** 440 * CIAddrLib::HwlPostCheckTileIndex 441 * 442 * @brief 443 * Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches 444 * tile mode/type/info and change the index if needed 445 * @return 446 * Tile index. 447 *************************************************************************************************** 448 */ 449 INT_32 CIAddrLib::HwlPostCheckTileIndex( 450 const ADDR_TILEINFO* pInfo, ///< [in] Tile Info 451 AddrTileMode mode, ///< [in] Tile mode 452 AddrTileType type, ///< [in] Tile type 453 INT curIndex ///< [in] Current index assigned in HwlSetupTileInfo 454 ) const 455 { 456 INT_32 index = curIndex; 457 458 if (mode == ADDR_TM_LINEAR_GENERAL) 459 { 460 index = TileIndexLinearGeneral; 461 } 462 else 463 { 464 BOOL_32 macroTiled = IsMacroTiled(mode); 465 466 // We need to find a new index if either of them is true 467 // 1. curIndex is invalid 468 // 2. tile mode is changed 469 // 3. tile info does not match for macro tiled 470 if ((index == TileIndexInvalid) || 471 (mode != m_tileTable[index].mode) || 472 (macroTiled && pInfo->pipeConfig != m_tileTable[index].info.pipeConfig)) 473 { 474 for (index = 0; index < static_cast<INT_32>(m_noOfEntries); index++) 475 { 476 if (macroTiled) 477 { 478 // macro tile modes need all to match 479 if ((pInfo->pipeConfig == m_tileTable[index].info.pipeConfig) && 480 (mode == m_tileTable[index].mode) && 481 (type == m_tileTable[index].type)) 482 { 483 // tileSplitBytes stored in m_tileTable is only valid for depth entries 484 if (type == ADDR_DEPTH_SAMPLE_ORDER) 485 { 486 if (pInfo->tileSplitBytes == m_tileTable[index].info.tileSplitBytes) 487 { 488 break; 489 } 490 } 491 else // other entries are determined by other 3 fields 492 { 493 break; 494 } 495 } 496 } 497 else if (mode == ADDR_TM_LINEAR_ALIGNED) 498 { 499 // linear mode only needs tile mode to match 500 if (mode == m_tileTable[index].mode) 501 { 502 break; 503 } 504 } 505 else 506 { 507 // micro tile modes only need tile mode and tile type to match 508 if (mode == m_tileTable[index].mode && 509 type == m_tileTable[index].type) 510 { 511 break; 512 } 513 } 514 } 515 } 516 } 517 518 ADDR_ASSERT(index < static_cast<INT_32>(m_noOfEntries)); 519 520 if (index >= static_cast<INT_32>(m_noOfEntries)) 521 { 522 index = TileIndexInvalid; 523 } 524 525 return index; 526 } 527 528 /** 529 *************************************************************************************************** 530 * CIAddrLib::HwlSetupTileCfg 531 * 532 * @brief 533 * Map tile index to tile setting. 534 * @return 535 * ADDR_E_RETURNCODE 536 *************************************************************************************************** 537 */ 538 ADDR_E_RETURNCODE CIAddrLib::HwlSetupTileCfg( 539 INT_32 index, ///< [in] Tile index 540 INT_32 macroModeIndex, ///< [in] Index in macro tile mode table(CI) 541 ADDR_TILEINFO* pInfo, ///< [out] Tile Info 542 AddrTileMode* pMode, ///< [out] Tile mode 543 AddrTileType* pType ///< [out] Tile type 544 ) const 545 { 546 ADDR_E_RETURNCODE returnCode = ADDR_OK; 547 548 // Global flag to control usage of tileIndex 549 if (UseTileIndex(index)) 550 { 551 if (static_cast<UINT_32>(index) >= m_noOfEntries) 552 { 553 returnCode = ADDR_INVALIDPARAMS; 554 } 555 else 556 { 557 const ADDR_TILECONFIG* pCfgTable = GetTileSetting(index); 558 559 if (pInfo != NULL) 560 { 561 if (IsMacroTiled(pCfgTable->mode)) 562 { 563 ADDR_ASSERT(((macroModeIndex != TileIndexInvalid) 564 && (macroModeIndex != TileIndexNoMacroIndex))); 565 // Here we used tile_bytes to replace of tile_split 566 // According info as below: 567 // "tile_split_c = MIN(ROW_SIZE, tile_split) 568 // "tile_bytes = MIN(tile_split_c, num_samples * tile_bytes_1x) 569 // when using tile_bytes replacing of tile_split, the result of 570 // alignment and others(such as slicesPerTile) are unaffected - 571 // since if tile_split_c is larger, split won't happen, otherwise 572 // (num_samples * tile_bytes_1x is larger), a correct tile_split is 573 // returned. 574 *pInfo = m_macroTileTable[macroModeIndex]; 575 576 if (pCfgTable->type == ADDR_DEPTH_SAMPLE_ORDER) 577 { 578 pInfo->tileSplitBytes = pCfgTable->info.tileSplitBytes; 579 } 580 pInfo->pipeConfig = pCfgTable->info.pipeConfig; 581 } 582 else // 1D and linear modes, we return default value stored in table 583 { 584 *pInfo = pCfgTable->info; 585 } 586 } 587 588 if (pMode != NULL) 589 { 590 *pMode = pCfgTable->mode; 591 } 592 593 if (pType != NULL) 594 { 595 *pType = pCfgTable->type; 596 } 597 } 598 } 599 600 return returnCode; 601 } 602 603 /** 604 *************************************************************************************************** 605 * CIAddrLib::HwlComputeSurfaceInfo 606 * 607 * @brief 608 * Entry of ci's ComputeSurfaceInfo 609 * @return 610 * ADDR_E_RETURNCODE 611 *************************************************************************************************** 612 */ 613 ADDR_E_RETURNCODE CIAddrLib::HwlComputeSurfaceInfo( 614 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure 615 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure 616 ) const 617 { 618 // If tileIndex is invalid, force macroModeIndex to be invalid, too 619 if (pIn->tileIndex == TileIndexInvalid) 620 { 621 pOut->macroModeIndex = TileIndexInvalid; 622 } 623 624 ADDR_E_RETURNCODE retCode = SIAddrLib::HwlComputeSurfaceInfo(pIn,pOut); 625 626 if (pOut->macroModeIndex == TileIndexNoMacroIndex) 627 { 628 pOut->macroModeIndex = TileIndexInvalid; 629 } 630 631 return retCode; 632 } 633 634 /** 635 *************************************************************************************************** 636 * CIAddrLib::HwlFmaskSurfaceInfo 637 * @brief 638 * Entry of r800's ComputeFmaskInfo 639 * @return 640 * ADDR_E_RETURNCODE 641 *************************************************************************************************** 642 */ 643 ADDR_E_RETURNCODE CIAddrLib::HwlComputeFmaskInfo( 644 const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure 645 ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure 646 ) 647 { 648 ADDR_E_RETURNCODE retCode = ADDR_OK; 649 650 ADDR_TILEINFO tileInfo = {0}; 651 ADDR_COMPUTE_FMASK_INFO_INPUT fmaskIn; 652 fmaskIn = *pIn; 653 654 AddrTileMode tileMode = pIn->tileMode; 655 656 // Use internal tile info if pOut does not have a valid pTileInfo 657 if (pOut->pTileInfo == NULL) 658 { 659 pOut->pTileInfo = &tileInfo; 660 } 661 662 ADDR_ASSERT(tileMode == ADDR_TM_2D_TILED_THIN1 || 663 tileMode == ADDR_TM_3D_TILED_THIN1 || 664 tileMode == ADDR_TM_PRT_TILED_THIN1 || 665 tileMode == ADDR_TM_PRT_2D_TILED_THIN1 || 666 tileMode == ADDR_TM_PRT_3D_TILED_THIN1); 667 668 ADDR_ASSERT(m_tileTable[14].mode == ADDR_TM_2D_TILED_THIN1); 669 ADDR_ASSERT(m_tileTable[15].mode == ADDR_TM_3D_TILED_THIN1); 670 671 // The only valid tile modes for fmask are 2D_THIN1 and 3D_THIN1 plus non-displayable 672 INT_32 tileIndex = tileMode == ADDR_TM_2D_TILED_THIN1 ? 14 : 15; 673 ADDR_SURFACE_FLAGS flags = {{0}}; 674 flags.fmask = 1; 675 676 INT_32 macroModeIndex = TileIndexInvalid; 677 678 UINT_32 numSamples = pIn->numSamples; 679 UINT_32 numFrags = pIn->numFrags == 0 ? numSamples : pIn->numFrags; 680 681 UINT_32 bpp = QLog2(numFrags); 682 683 // EQAA needs one more bit 684 if (numSamples > numFrags) 685 { 686 bpp++; 687 } 688 689 if (bpp == 3) 690 { 691 bpp = 4; 692 } 693 694 bpp = Max(8u, bpp * numSamples); 695 696 macroModeIndex = HwlComputeMacroModeIndex(tileIndex, flags, bpp, numSamples, pOut->pTileInfo); 697 698 fmaskIn.tileIndex = tileIndex; 699 fmaskIn.pTileInfo = pOut->pTileInfo; 700 pOut->macroModeIndex = macroModeIndex; 701 pOut->tileIndex = tileIndex; 702 703 retCode = DispatchComputeFmaskInfo(&fmaskIn, pOut); 704 705 if (retCode == ADDR_OK) 706 { 707 pOut->tileIndex = 708 HwlPostCheckTileIndex(pOut->pTileInfo, pIn->tileMode, ADDR_NON_DISPLAYABLE, 709 pOut->tileIndex); 710 } 711 712 // Resets pTileInfo to NULL if the internal tile info is used 713 if (pOut->pTileInfo == &tileInfo) 714 { 715 pOut->pTileInfo = NULL; 716 } 717 718 return retCode; 719 } 720 721 /** 722 *************************************************************************************************** 723 * CIAddrLib::HwlFmaskPreThunkSurfInfo 724 * 725 * @brief 726 * Some preparation before thunking a ComputeSurfaceInfo call for Fmask 727 * @return 728 * ADDR_E_RETURNCODE 729 *************************************************************************************************** 730 */ 731 VOID CIAddrLib::HwlFmaskPreThunkSurfInfo( 732 const ADDR_COMPUTE_FMASK_INFO_INPUT* pFmaskIn, ///< [in] Input of fmask info 733 const ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut, ///< [in] Output of fmask info 734 ADDR_COMPUTE_SURFACE_INFO_INPUT* pSurfIn, ///< [out] Input of thunked surface info 735 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut ///< [out] Output of thunked surface info 736 ) const 737 { 738 pSurfIn->tileIndex = pFmaskIn->tileIndex; 739 pSurfOut->macroModeIndex = pFmaskOut->macroModeIndex; 740 } 741 742 /** 743 *************************************************************************************************** 744 * CIAddrLib::HwlFmaskPostThunkSurfInfo 745 * 746 * @brief 747 * Copy hwl extra field after calling thunked ComputeSurfaceInfo 748 * @return 749 * ADDR_E_RETURNCODE 750 *************************************************************************************************** 751 */ 752 VOID CIAddrLib::HwlFmaskPostThunkSurfInfo( 753 const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut, ///< [in] Output of surface info 754 ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut ///< [out] Output of fmask info 755 ) const 756 { 757 pFmaskOut->tileIndex = pSurfOut->tileIndex; 758 pFmaskOut->macroModeIndex = pSurfOut->macroModeIndex; 759 } 760 761 /** 762 *************************************************************************************************** 763 * CIAddrLib::HwlDegradeThickTileMode 764 * 765 * @brief 766 * Degrades valid tile mode for thick modes if needed 767 * 768 * @return 769 * Suitable tile mode 770 *************************************************************************************************** 771 */ 772 AddrTileMode CIAddrLib::HwlDegradeThickTileMode( 773 AddrTileMode baseTileMode, ///< [in] base tile mode 774 UINT_32 numSlices, ///< [in] current number of slices 775 UINT_32* pBytesPerTile ///< [in/out] pointer to bytes per slice 776 ) const 777 { 778 return baseTileMode; 779 } 780 781 /** 782 *************************************************************************************************** 783 * CIAddrLib::HwlOverrideTileMode 784 * 785 * @brief 786 * Override THICK to THIN, for specific formats on CI 787 * 788 * @return 789 * Suitable tile mode 790 * 791 *************************************************************************************************** 792 */ 793 BOOL_32 CIAddrLib::HwlOverrideTileMode( 794 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure 795 AddrTileMode* pTileMode, ///< [in/out] pointer to the tile mode 796 AddrTileType* pTileType ///< [in/out] pointer to the tile type 797 ) const 798 { 799 BOOL_32 bOverrided = FALSE; 800 AddrTileMode tileMode = *pTileMode; 801 802 // currently, all CI/VI family do not 803 // support ADDR_TM_PRT_2D_TILED_THICK,ADDR_TM_PRT_3D_TILED_THICK and 804 // ADDR_TM_PRT_2D_TILED_THIN1, ADDR_TM_PRT_3D_TILED_THIN1 805 switch (tileMode) 806 { 807 case ADDR_TM_PRT_2D_TILED_THICK: 808 case ADDR_TM_PRT_3D_TILED_THICK: 809 tileMode = ADDR_TM_PRT_TILED_THICK; 810 break; 811 case ADDR_TM_PRT_2D_TILED_THIN1: 812 case ADDR_TM_PRT_3D_TILED_THIN1: 813 tileMode = ADDR_TM_PRT_TILED_THIN1; 814 break; 815 default: 816 break; 817 } 818 819 // UBTS#404321, we do not need such overriding, as THICK+THICK entries removed from the tile-mode table 820 if (!m_settings.isBonaire) 821 { 822 UINT_32 thickness = ComputeSurfaceThickness(tileMode); 823 824 // tile_thickness = (array_mode == XTHICK) ? 8 : ((array_mode == THICK) ? 4 : 1) 825 if (thickness > 1) 826 { 827 switch (pIn->format) 828 { 829 // see //gfxip/gcB/devel/cds/src/verif/tc/models/csim/tcp.cpp 830 // tcpError("Thick micro tiling is not supported for format... 831 case ADDR_FMT_X24_8_32_FLOAT: 832 case ADDR_FMT_32_AS_8: 833 case ADDR_FMT_32_AS_8_8: 834 case ADDR_FMT_32_AS_32_32_32_32: 835 836 // packed formats 837 case ADDR_FMT_GB_GR: 838 case ADDR_FMT_BG_RG: 839 case ADDR_FMT_1_REVERSED: 840 case ADDR_FMT_1: 841 case ADDR_FMT_BC1: 842 case ADDR_FMT_BC2: 843 case ADDR_FMT_BC3: 844 case ADDR_FMT_BC4: 845 case ADDR_FMT_BC5: 846 case ADDR_FMT_BC6: 847 case ADDR_FMT_BC7: 848 switch (tileMode) 849 { 850 case ADDR_TM_1D_TILED_THICK: 851 tileMode = ADDR_TM_1D_TILED_THIN1; 852 break; 853 854 case ADDR_TM_2D_TILED_XTHICK: 855 case ADDR_TM_2D_TILED_THICK: 856 tileMode = ADDR_TM_2D_TILED_THIN1; 857 break; 858 859 case ADDR_TM_3D_TILED_XTHICK: 860 case ADDR_TM_3D_TILED_THICK: 861 tileMode = ADDR_TM_3D_TILED_THIN1; 862 break; 863 864 case ADDR_TM_PRT_TILED_THICK: 865 tileMode = ADDR_TM_PRT_TILED_THIN1; 866 break; 867 868 case ADDR_TM_PRT_2D_TILED_THICK: 869 tileMode = ADDR_TM_PRT_2D_TILED_THIN1; 870 break; 871 872 case ADDR_TM_PRT_3D_TILED_THICK: 873 tileMode = ADDR_TM_PRT_3D_TILED_THIN1; 874 break; 875 876 default: 877 break; 878 879 } 880 881 // Switch tile type from thick to thin 882 if (tileMode != *pTileMode) 883 { 884 // see tileIndex: 13-18 885 *pTileType = ADDR_NON_DISPLAYABLE; 886 } 887 888 break; 889 default: 890 break; 891 } 892 } 893 } 894 895 if (tileMode != *pTileMode) 896 { 897 *pTileMode = tileMode; 898 bOverrided = TRUE; 899 } 900 901 return bOverrided; 902 } 903 904 /** 905 *************************************************************************************************** 906 * CiAddrLib::GetPrtSwitchP4Threshold 907 * 908 * @brief 909 * Return the threshold of switching to P4_* instead of P16_* for PRT resources 910 *************************************************************************************************** 911 */ 912 UINT_32 CIAddrLib::GetPrtSwitchP4Threshold() const 913 { 914 UINT_32 threshold; 915 916 switch (m_pipes) 917 { 918 case 8: 919 threshold = 32; 920 break; 921 case 16: 922 if (m_settings.isFiji) 923 { 924 threshold = 16; 925 } 926 else if (m_settings.isHawaii) 927 { 928 threshold = 8; 929 } 930 else 931 { 932 ///@todo add for possible new ASICs. 933 ADDR_ASSERT_ALWAYS(); 934 threshold = 16; 935 } 936 break; 937 default: 938 ///@todo add for possible new ASICs. 939 ADDR_ASSERT_ALWAYS(); 940 threshold = 32; 941 break; 942 } 943 944 return threshold; 945 } 946 947 /** 948 *************************************************************************************************** 949 * CIAddrLib::HwlSetupTileInfo 950 * 951 * @brief 952 * Setup default value of tile info for SI 953 *************************************************************************************************** 954 */ 955 VOID CIAddrLib::HwlSetupTileInfo( 956 AddrTileMode tileMode, ///< [in] Tile mode 957 ADDR_SURFACE_FLAGS flags, ///< [in] Surface type flags 958 UINT_32 bpp, ///< [in] Bits per pixel 959 UINT_32 pitch, ///< [in] Pitch in pixels 960 UINT_32 height, ///< [in] Height in pixels 961 UINT_32 numSamples, ///< [in] Number of samples 962 ADDR_TILEINFO* pTileInfoIn, ///< [in] Tile info input: NULL for default 963 ADDR_TILEINFO* pTileInfoOut, ///< [out] Tile info output 964 AddrTileType inTileType, ///< [in] Tile type 965 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] Output 966 ) const 967 { 968 UINT_32 thickness = ComputeSurfaceThickness(tileMode); 969 ADDR_TILEINFO* pTileInfo = pTileInfoOut; 970 INT index = TileIndexInvalid; 971 INT macroModeIndex = TileIndexInvalid; 972 973 // Fail-safe code 974 if (!IsLinear(tileMode)) 975 { 976 // Thick tile modes must use thick micro tile mode but Bonaire does not support due to 977 // old derived netlists (UBTS 404321) 978 if (thickness > 1) 979 { 980 if (m_settings.isBonaire) 981 { 982 inTileType = ADDR_NON_DISPLAYABLE; 983 } 984 else if ((m_allowNonDispThickModes == FALSE) || (inTileType != ADDR_NON_DISPLAYABLE)) 985 { 986 inTileType = ADDR_THICK; 987 } 988 } 989 // 128 bpp tiling must be non-displayable. 990 // Fmask reuse color buffer's entry but bank-height field can be from another entry 991 // To simplify the logic, fmask entry should be picked from non-displayable ones 992 else if (bpp == 128 || flags.fmask) 993 { 994 inTileType = ADDR_NON_DISPLAYABLE; 995 } 996 // These two modes only have non-disp entries though they can be other micro tile modes 997 else if (tileMode == ADDR_TM_3D_TILED_THIN1 || tileMode == ADDR_TM_PRT_3D_TILED_THIN1) 998 { 999 inTileType = ADDR_NON_DISPLAYABLE; 1000 } 1001 1002 if (flags.depth || flags.stencil) 1003 { 1004 inTileType = ADDR_DEPTH_SAMPLE_ORDER; 1005 } 1006 } 1007 1008 if (IsTileInfoAllZero(pTileInfo)) 1009 { 1010 // See table entries 0-4 1011 if (flags.depth || flags.stencil) 1012 { 1013 if (flags.depth && flags.tcCompatible) 1014 { 1015 // tileSize = bpp * numSamples * 8 * 8 / 8 1016 UINT_32 tileSize = bpp * numSamples * 8; 1017 1018 // Texure readable depth surface should not be split 1019 switch (tileSize) 1020 { 1021 case 128: 1022 index = 1; 1023 break; 1024 case 256: 1025 index = 2; 1026 break; 1027 case 512: 1028 index = 3; 1029 break; 1030 default: 1031 index = 4; 1032 break; 1033 } 1034 } 1035 else 1036 { 1037 // Depth and stencil need to use the same index, thus the pre-defined tile_split 1038 // can meet the requirement to choose the same macro mode index 1039 // uncompressed depth/stencil are not supported for now 1040 switch (numSamples) 1041 { 1042 case 1: 1043 index = 0; 1044 break; 1045 case 2: 1046 case 4: 1047 index = 1; 1048 break; 1049 case 8: 1050 index = 2; 1051 break; 1052 default: 1053 break; 1054 } 1055 } 1056 } 1057 1058 // See table entries 5-6 1059 if (inTileType == ADDR_DEPTH_SAMPLE_ORDER) 1060 { 1061 switch (tileMode) 1062 { 1063 case ADDR_TM_1D_TILED_THIN1: 1064 index = 5; 1065 break; 1066 case ADDR_TM_PRT_TILED_THIN1: 1067 index = 6; 1068 break; 1069 default: 1070 break; 1071 } 1072 } 1073 1074 // See table entries 8-12 1075 if (inTileType == ADDR_DISPLAYABLE) 1076 { 1077 switch (tileMode) 1078 { 1079 case ADDR_TM_1D_TILED_THIN1: 1080 index = 9; 1081 break; 1082 case ADDR_TM_2D_TILED_THIN1: 1083 index = 10; 1084 break; 1085 case ADDR_TM_PRT_TILED_THIN1: 1086 index = 11; 1087 break; 1088 default: 1089 break; 1090 } 1091 } 1092 1093 // See table entries 13-18 1094 if (inTileType == ADDR_NON_DISPLAYABLE) 1095 { 1096 switch (tileMode) 1097 { 1098 case ADDR_TM_1D_TILED_THIN1: 1099 index = 13; 1100 break; 1101 case ADDR_TM_2D_TILED_THIN1: 1102 index = 14; 1103 break; 1104 case ADDR_TM_3D_TILED_THIN1: 1105 index = 15; 1106 break; 1107 case ADDR_TM_PRT_TILED_THIN1: 1108 index = 16; 1109 break; 1110 default: 1111 break; 1112 } 1113 } 1114 1115 // See table entries 19-26 1116 if (thickness > 1) 1117 { 1118 switch (tileMode) 1119 { 1120 case ADDR_TM_1D_TILED_THICK: 1121 //special check for bonaire, for the compatablity between old KMD and new UMD for bonaire 1122 index = ((inTileType == ADDR_THICK) || m_settings.isBonaire) ? 19 : 18; 1123 break; 1124 case ADDR_TM_2D_TILED_THICK: 1125 // special check for bonaire, for the compatablity between old KMD and new UMD for bonaire 1126 index = ((inTileType == ADDR_THICK) || m_settings.isBonaire) ? 20 : 24; 1127 break; 1128 case ADDR_TM_3D_TILED_THICK: 1129 index = 21; 1130 break; 1131 case ADDR_TM_PRT_TILED_THICK: 1132 index = 22; 1133 break; 1134 case ADDR_TM_2D_TILED_XTHICK: 1135 index = 25; 1136 break; 1137 case ADDR_TM_3D_TILED_XTHICK: 1138 index = 26; 1139 break; 1140 default: 1141 break; 1142 } 1143 } 1144 1145 // See table entries 27-30 1146 if (inTileType == ADDR_ROTATED) 1147 { 1148 switch (tileMode) 1149 { 1150 case ADDR_TM_1D_TILED_THIN1: 1151 index = 27; 1152 break; 1153 case ADDR_TM_2D_TILED_THIN1: 1154 index = 28; 1155 break; 1156 case ADDR_TM_PRT_TILED_THIN1: 1157 index = 29; 1158 break; 1159 case ADDR_TM_PRT_2D_TILED_THIN1: 1160 index = 30; 1161 break; 1162 default: 1163 break; 1164 } 1165 } 1166 1167 if (m_pipes >= 8) 1168 { 1169 ADDR_ASSERT((index + 1) < static_cast<INT_32>(m_noOfEntries)); 1170 // Only do this when tile mode table is updated. 1171 if (((tileMode == ADDR_TM_PRT_TILED_THIN1) || (tileMode == ADDR_TM_PRT_TILED_THICK)) && 1172 (m_tileTable[index+1].mode == tileMode)) 1173 { 1174 UINT_32 bytesXSamples = bpp * numSamples / 8; 1175 UINT_32 bytesXThickness = bpp * thickness / 8; 1176 UINT_32 switchP4Threshold = GetPrtSwitchP4Threshold(); 1177 1178 if ((bytesXSamples > switchP4Threshold) || (bytesXThickness > switchP4Threshold)) 1179 { 1180 // Pick next 4 pipe entry 1181 index += 1; 1182 } 1183 } 1184 } 1185 } 1186 else 1187 { 1188 // A pre-filled tile info is ready 1189 index = pOut->tileIndex; 1190 macroModeIndex = pOut->macroModeIndex; 1191 1192 // pass tile type back for post tile index compute 1193 pOut->tileType = inTileType; 1194 } 1195 1196 // We only need to set up tile info if there is a valid index but macroModeIndex is invalid 1197 if (index != TileIndexInvalid && macroModeIndex == TileIndexInvalid) 1198 { 1199 macroModeIndex = HwlComputeMacroModeIndex(index, flags, bpp, numSamples, pTileInfo); 1200 1201 /// Copy to pOut->tileType/tileIndex/macroModeIndex 1202 pOut->tileIndex = index; 1203 pOut->tileType = m_tileTable[index].type; // Or inTileType, the samea 1204 pOut->macroModeIndex = macroModeIndex; 1205 } 1206 else if (tileMode == ADDR_TM_LINEAR_GENERAL) 1207 { 1208 pOut->tileIndex = TileIndexLinearGeneral; 1209 1210 // Copy linear-aligned entry?? 1211 *pTileInfo = m_tileTable[8].info; 1212 } 1213 else if (tileMode == ADDR_TM_LINEAR_ALIGNED) 1214 { 1215 pOut->tileIndex = 8; 1216 *pTileInfo = m_tileTable[8].info; 1217 } 1218 } 1219 1220 /** 1221 *************************************************************************************************** 1222 * CIAddrLib::ReadGbTileMode 1223 * 1224 * @brief 1225 * Convert GB_TILE_MODE HW value to ADDR_TILE_CONFIG. 1226 * @return 1227 * NA. 1228 *************************************************************************************************** 1229 */ 1230 VOID CIAddrLib::ReadGbTileMode( 1231 UINT_32 regValue, ///< [in] GB_TILE_MODE register 1232 ADDR_TILECONFIG* pCfg ///< [out] output structure 1233 ) const 1234 { 1235 GB_TILE_MODE gbTileMode; 1236 gbTileMode.val = regValue; 1237 1238 pCfg->type = static_cast<AddrTileType>(gbTileMode.f.micro_tile_mode_new); 1239 pCfg->info.pipeConfig = static_cast<AddrPipeCfg>(gbTileMode.f.pipe_config + 1); 1240 1241 if (pCfg->type == ADDR_DEPTH_SAMPLE_ORDER) 1242 { 1243 pCfg->info.tileSplitBytes = 64 << gbTileMode.f.tile_split; 1244 } 1245 else 1246 { 1247 pCfg->info.tileSplitBytes = 1 << gbTileMode.f.sample_split; 1248 } 1249 1250 UINT_32 regArrayMode = gbTileMode.f.array_mode; 1251 1252 pCfg->mode = static_cast<AddrTileMode>(regArrayMode); 1253 1254 switch (regArrayMode) 1255 { 1256 case 5: 1257 pCfg->mode = ADDR_TM_PRT_TILED_THIN1; 1258 break; 1259 case 6: 1260 pCfg->mode = ADDR_TM_PRT_2D_TILED_THIN1; 1261 break; 1262 case 8: 1263 pCfg->mode = ADDR_TM_2D_TILED_XTHICK; 1264 break; 1265 case 9: 1266 pCfg->mode = ADDR_TM_PRT_TILED_THICK; 1267 break; 1268 case 0xa: 1269 pCfg->mode = ADDR_TM_PRT_2D_TILED_THICK; 1270 break; 1271 case 0xb: 1272 pCfg->mode = ADDR_TM_PRT_3D_TILED_THIN1; 1273 break; 1274 case 0xe: 1275 pCfg->mode = ADDR_TM_3D_TILED_XTHICK; 1276 break; 1277 case 0xf: 1278 pCfg->mode = ADDR_TM_PRT_3D_TILED_THICK; 1279 break; 1280 default: 1281 break; 1282 } 1283 1284 // Fail-safe code for these always convert tile info, as the non-macro modes 1285 // return the entry of tile mode table directly without looking up macro mode table 1286 if (!IsMacroTiled(pCfg->mode)) 1287 { 1288 pCfg->info.banks = 2; 1289 pCfg->info.bankWidth = 1; 1290 pCfg->info.bankHeight = 1; 1291 pCfg->info.macroAspectRatio = 1; 1292 pCfg->info.tileSplitBytes = 64; 1293 } 1294 } 1295 1296 /** 1297 *************************************************************************************************** 1298 * CIAddrLib::InitTileSettingTable 1299 * 1300 * @brief 1301 * Initialize the ADDR_TILE_CONFIG table. 1302 * @return 1303 * TRUE if tile table is correctly initialized 1304 *************************************************************************************************** 1305 */ 1306 BOOL_32 CIAddrLib::InitTileSettingTable( 1307 const UINT_32* pCfg, ///< [in] Pointer to table of tile configs 1308 UINT_32 noOfEntries ///< [in] Numbe of entries in the table above 1309 ) 1310 { 1311 BOOL_32 initOk = TRUE; 1312 1313 ADDR_ASSERT(noOfEntries <= TileTableSize); 1314 1315 memset(m_tileTable, 0, sizeof(m_tileTable)); 1316 1317 if (noOfEntries != 0) 1318 { 1319 m_noOfEntries = noOfEntries; 1320 } 1321 else 1322 { 1323 m_noOfEntries = TileTableSize; 1324 } 1325 1326 if (pCfg) // From Client 1327 { 1328 for (UINT_32 i = 0; i < m_noOfEntries; i++) 1329 { 1330 ReadGbTileMode(*(pCfg + i), &m_tileTable[i]); 1331 } 1332 } 1333 else 1334 { 1335 ADDR_ASSERT_ALWAYS(); 1336 initOk = FALSE; 1337 } 1338 1339 if (initOk) 1340 { 1341 ADDR_ASSERT(m_tileTable[TILEINDEX_LINEAR_ALIGNED].mode == ADDR_TM_LINEAR_ALIGNED); 1342 1343 if (m_settings.isBonaire == FALSE) 1344 { 1345 // Check if entry 18 is "thick+thin" combination 1346 if ((m_tileTable[18].mode == ADDR_TM_1D_TILED_THICK) && 1347 (m_tileTable[18].type == ADDR_NON_DISPLAYABLE)) 1348 { 1349 m_allowNonDispThickModes = TRUE; 1350 ADDR_ASSERT(m_tileTable[24].mode == ADDR_TM_2D_TILED_THICK); 1351 } 1352 } 1353 else 1354 { 1355 m_allowNonDispThickModes = TRUE; 1356 } 1357 1358 // Assume the first entry is always programmed with full pipes 1359 m_pipes = HwlGetPipes(&m_tileTable[0].info); 1360 } 1361 1362 return initOk; 1363 } 1364 1365 /** 1366 *************************************************************************************************** 1367 * CIAddrLib::ReadGbMacroTileCfg 1368 * 1369 * @brief 1370 * Convert GB_MACRO_TILE_CFG HW value to ADDR_TILE_CONFIG. 1371 * @return 1372 * NA. 1373 *************************************************************************************************** 1374 */ 1375 VOID CIAddrLib::ReadGbMacroTileCfg( 1376 UINT_32 regValue, ///< [in] GB_MACRO_TILE_MODE register 1377 ADDR_TILEINFO* pCfg ///< [out] output structure 1378 ) const 1379 { 1380 GB_MACROTILE_MODE gbTileMode; 1381 gbTileMode.val = regValue; 1382 1383 pCfg->bankHeight = 1 << gbTileMode.f.bank_height; 1384 pCfg->bankWidth = 1 << gbTileMode.f.bank_width; 1385 pCfg->banks = 1 << (gbTileMode.f.num_banks + 1); 1386 pCfg->macroAspectRatio = 1 << gbTileMode.f.macro_tile_aspect; 1387 } 1388 1389 /** 1390 *************************************************************************************************** 1391 * CIAddrLib::InitMacroTileCfgTable 1392 * 1393 * @brief 1394 * Initialize the ADDR_MACRO_TILE_CONFIG table. 1395 * @return 1396 * TRUE if macro tile table is correctly initialized 1397 *************************************************************************************************** 1398 */ 1399 BOOL_32 CIAddrLib::InitMacroTileCfgTable( 1400 const UINT_32* pCfg, ///< [in] Pointer to table of tile configs 1401 UINT_32 noOfMacroEntries ///< [in] Numbe of entries in the table above 1402 ) 1403 { 1404 BOOL_32 initOk = TRUE; 1405 1406 ADDR_ASSERT(noOfMacroEntries <= MacroTileTableSize); 1407 1408 memset(m_macroTileTable, 0, sizeof(m_macroTileTable)); 1409 1410 if (noOfMacroEntries != 0) 1411 { 1412 m_noOfMacroEntries = noOfMacroEntries; 1413 } 1414 else 1415 { 1416 m_noOfMacroEntries = MacroTileTableSize; 1417 } 1418 1419 if (pCfg) // From Client 1420 { 1421 for (UINT_32 i = 0; i < m_noOfMacroEntries; i++) 1422 { 1423 ReadGbMacroTileCfg(*(pCfg + i), &m_macroTileTable[i]); 1424 1425 m_macroTileTable[i].tileSplitBytes = 64 << (i % 8); 1426 } 1427 } 1428 else 1429 { 1430 ADDR_ASSERT_ALWAYS(); 1431 initOk = FALSE; 1432 } 1433 return initOk; 1434 } 1435 1436 /** 1437 *************************************************************************************************** 1438 * CIAddrLib::HwlComputeMacroModeIndex 1439 * 1440 * @brief 1441 * Computes macro tile mode index 1442 * @return 1443 * TRUE if macro tile table is correctly initialized 1444 *************************************************************************************************** 1445 */ 1446 INT_32 CIAddrLib::HwlComputeMacroModeIndex( 1447 INT_32 tileIndex, ///< [in] Tile mode index 1448 ADDR_SURFACE_FLAGS flags, ///< [in] Surface flags 1449 UINT_32 bpp, ///< [in] Bit per pixel 1450 UINT_32 numSamples, ///< [in] Number of samples 1451 ADDR_TILEINFO* pTileInfo, ///< [out] Pointer to ADDR_TILEINFO 1452 AddrTileMode* pTileMode, ///< [out] Pointer to AddrTileMode 1453 AddrTileType* pTileType ///< [out] Pointer to AddrTileType 1454 ) const 1455 { 1456 INT_32 macroModeIndex = TileIndexInvalid; 1457 1458 if (flags.tcCompatible && flags.stencil) 1459 { 1460 // Don't compute macroModeIndex for tc compatible stencil surface 1461 macroModeIndex = TileIndexNoMacroIndex; 1462 } 1463 else 1464 { 1465 AddrTileMode tileMode = m_tileTable[tileIndex].mode; 1466 AddrTileType tileType = m_tileTable[tileIndex].type; 1467 UINT_32 thickness = ComputeSurfaceThickness(tileMode); 1468 1469 if (!IsMacroTiled(tileMode)) 1470 { 1471 *pTileInfo = m_tileTable[tileIndex].info; 1472 macroModeIndex = TileIndexNoMacroIndex; 1473 } 1474 else 1475 { 1476 UINT_32 tileBytes1x = BITS_TO_BYTES(bpp * MicroTilePixels * thickness); 1477 UINT_32 tileSplit; 1478 1479 if (m_tileTable[tileIndex].type == ADDR_DEPTH_SAMPLE_ORDER) 1480 { 1481 // Depth entries store real tileSplitBytes 1482 tileSplit = m_tileTable[tileIndex].info.tileSplitBytes; 1483 } 1484 else 1485 { 1486 // Non-depth entries store a split factor 1487 UINT_32 sampleSplit = m_tileTable[tileIndex].info.tileSplitBytes; 1488 UINT_32 colorTileSplit = Max(256u, sampleSplit * tileBytes1x); 1489 1490 tileSplit = colorTileSplit; 1491 } 1492 1493 UINT_32 tileSplitC = Min(m_rowSize, tileSplit); 1494 UINT_32 tileBytes; 1495 1496 if (flags.fmask) 1497 { 1498 tileBytes = Min(tileSplitC, tileBytes1x); 1499 } 1500 else 1501 { 1502 tileBytes = Min(tileSplitC, numSamples * tileBytes1x); 1503 } 1504 1505 if (tileBytes < 64) 1506 { 1507 tileBytes = 64; 1508 } 1509 1510 macroModeIndex = Log2(tileBytes / 64); 1511 1512 if (flags.prt || IsPrtTileMode(tileMode)) 1513 { 1514 // Unknown - assume it is 1/2 of table size 1515 const UINT_32 PrtMacroModeOffset = MacroTileTableSize / 2; 1516 1517 macroModeIndex += PrtMacroModeOffset; 1518 *pTileInfo = m_macroTileTable[macroModeIndex]; 1519 } 1520 else 1521 { 1522 *pTileInfo = m_macroTileTable[macroModeIndex]; 1523 } 1524 1525 pTileInfo->pipeConfig = m_tileTable[tileIndex].info.pipeConfig; 1526 1527 if (m_tileTable[tileIndex].type != ADDR_DEPTH_SAMPLE_ORDER) 1528 { 1529 pTileInfo->tileSplitBytes = tileSplitC; 1530 } 1531 else 1532 { 1533 pTileInfo->tileSplitBytes = m_tileTable[tileIndex].info.tileSplitBytes; 1534 } 1535 } 1536 1537 if (NULL != pTileMode) 1538 { 1539 *pTileMode = tileMode; 1540 } 1541 1542 if (NULL != pTileType) 1543 { 1544 *pTileType = tileType; 1545 } 1546 } 1547 1548 return macroModeIndex; 1549 } 1550 1551 /** 1552 *************************************************************************************************** 1553 * CIAddrLib::HwlComputeTileDataWidthAndHeightLinear 1554 * 1555 * @brief 1556 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout 1557 * 1558 * @return 1559 * N/A 1560 * 1561 * @note 1562 * MacroWidth and macroHeight are measured in pixels 1563 *************************************************************************************************** 1564 */ 1565 VOID CIAddrLib::HwlComputeTileDataWidthAndHeightLinear( 1566 UINT_32* pMacroWidth, ///< [out] macro tile width 1567 UINT_32* pMacroHeight, ///< [out] macro tile height 1568 UINT_32 bpp, ///< [in] bits per pixel 1569 ADDR_TILEINFO* pTileInfo ///< [in] tile info 1570 ) const 1571 { 1572 ADDR_ASSERT(pTileInfo != NULL); 1573 1574 UINT_32 numTiles; 1575 1576 switch (pTileInfo->pipeConfig) 1577 { 1578 case ADDR_PIPECFG_P16_32x32_8x16: 1579 case ADDR_PIPECFG_P16_32x32_16x16: 1580 case ADDR_PIPECFG_P8_32x64_32x32: 1581 case ADDR_PIPECFG_P8_32x32_16x32: 1582 case ADDR_PIPECFG_P8_32x32_16x16: 1583 case ADDR_PIPECFG_P8_32x32_8x16: 1584 case ADDR_PIPECFG_P4_32x32: 1585 numTiles = 8; 1586 break; 1587 default: 1588 numTiles = 4; 1589 break; 1590 } 1591 1592 *pMacroWidth = numTiles * MicroTileWidth; 1593 *pMacroHeight = numTiles * MicroTileHeight; 1594 } 1595 1596 /** 1597 *************************************************************************************************** 1598 * CIAddrLib::HwlStereoCheckRightOffsetPadding 1599 * 1600 * @brief 1601 * check if the height needs extra padding for stereo right eye offset, to avoid swizzling 1602 * 1603 * @return 1604 * TRUE is the extra padding is needed 1605 * 1606 * @note 1607 * Kalindi (Kabini) is the only one that needs this padding as there is a uncertain 1608 * possible HW issue where the right eye displays incorrectly with some type of swizzles, if 1609 * the right eye offset is not 64KB aligned - EPR#366461 1610 * Other Kaveri APUs also need the padding according to DXX team's report otherwise 1611 * corruption observed. - EPR#374788 1612 *************************************************************************************************** 1613 */ 1614 BOOL_32 CIAddrLib::HwlStereoCheckRightOffsetPadding() const 1615 { 1616 BOOL_32 bNeedPadding = FALSE; 1617 1618 if (m_settings.isKaveri) 1619 { 1620 bNeedPadding = TRUE; 1621 } 1622 1623 return bNeedPadding; 1624 } 1625 1626 /** 1627 *************************************************************************************************** 1628 * CIAddrLib::HwlComputeMetadataNibbleAddress 1629 * 1630 * @brief 1631 * calculate meta data address based on input information 1632 * 1633 * ¶meter 1634 * uncompressedDataByteAddress - address of a pixel in color surface 1635 * dataBaseByteAddress - base address of color surface 1636 * metadataBaseByteAddress - base address of meta ram 1637 * metadataBitSize - meta key size, 8 for DCC, 4 for cmask 1638 * elementBitSize - element size of color surface 1639 * blockByteSize - compression block size, 256 for DCC 1640 * pipeInterleaveBytes - pipe interleave size 1641 * numOfPipes - number of pipes 1642 * numOfBanks - number of banks 1643 * numOfSamplesPerSplit - number of samples per tile split 1644 * @return 1645 * meta data nibble address (nibble address is used to support DCC compatible cmask) 1646 * 1647 *************************************************************************************************** 1648 */ 1649 UINT_64 CIAddrLib::HwlComputeMetadataNibbleAddress( 1650 UINT_64 uncompressedDataByteAddress, 1651 UINT_64 dataBaseByteAddress, 1652 UINT_64 metadataBaseByteAddress, 1653 UINT_32 metadataBitSize, 1654 UINT_32 elementBitSize, 1655 UINT_32 blockByteSize, 1656 UINT_32 pipeInterleaveBytes, 1657 UINT_32 numOfPipes, 1658 UINT_32 numOfBanks, 1659 UINT_32 numOfSamplesPerSplit) const 1660 { 1661 ///-------------------------------------------------------------------------------------------- 1662 /// Get pipe interleave, bank and pipe bits 1663 ///-------------------------------------------------------------------------------------------- 1664 UINT_32 pipeInterleaveBits = Log2(pipeInterleaveBytes); 1665 UINT_32 pipeBits = Log2(numOfPipes); 1666 UINT_32 bankBits = Log2(numOfBanks); 1667 1668 ///-------------------------------------------------------------------------------------------- 1669 /// Clear pipe and bank swizzles 1670 ///-------------------------------------------------------------------------------------------- 1671 UINT_32 dataMacrotileBits = pipeInterleaveBits + pipeBits + bankBits; 1672 UINT_32 metadataMacrotileBits = pipeInterleaveBits + pipeBits + bankBits; 1673 1674 UINT_64 dataMacrotileClearMask = ~((1L << dataMacrotileBits) - 1); 1675 UINT_64 metadataMacrotileClearMask = ~((1L << metadataMacrotileBits) - 1); 1676 1677 UINT_64 dataBaseByteAddressNoSwizzle = dataBaseByteAddress & dataMacrotileClearMask; 1678 UINT_64 metadataBaseByteAddressNoSwizzle = metadataBaseByteAddress & metadataMacrotileClearMask; 1679 1680 ///-------------------------------------------------------------------------------------------- 1681 /// Modify metadata base before adding in so that when final address is divided by data ratio, 1682 /// the base address returns to where it should be 1683 ///-------------------------------------------------------------------------------------------- 1684 ADDR_ASSERT((0 != metadataBitSize)); 1685 UINT_64 metadataBaseShifted = metadataBaseByteAddressNoSwizzle * blockByteSize * 8 / 1686 metadataBitSize; 1687 UINT_64 offset = uncompressedDataByteAddress - 1688 dataBaseByteAddressNoSwizzle + 1689 metadataBaseShifted; 1690 1691 ///-------------------------------------------------------------------------------------------- 1692 /// Save bank data bits 1693 ///-------------------------------------------------------------------------------------------- 1694 UINT_32 lsb = pipeBits + pipeInterleaveBits; 1695 UINT_32 msb = bankBits - 1 + lsb; 1696 1697 UINT_64 bankDataBits = AddrGetBits(offset, msb, lsb); 1698 1699 ///-------------------------------------------------------------------------------------------- 1700 /// Save pipe data bits 1701 ///-------------------------------------------------------------------------------------------- 1702 lsb = pipeInterleaveBits; 1703 msb = pipeBits - 1 + lsb; 1704 1705 UINT_64 pipeDataBits = AddrGetBits(offset, msb, lsb); 1706 1707 ///-------------------------------------------------------------------------------------------- 1708 /// Remove pipe and bank bits 1709 ///-------------------------------------------------------------------------------------------- 1710 lsb = pipeInterleaveBits; 1711 msb = dataMacrotileBits - 1; 1712 1713 UINT_64 offsetWithoutPipeBankBits = AddrRemoveBits(offset, msb, lsb); 1714 1715 ADDR_ASSERT((0 != blockByteSize)); 1716 UINT_64 blockInBankpipe = offsetWithoutPipeBankBits / blockByteSize; 1717 1718 UINT_32 tileSize = 8 * 8 * elementBitSize/8 * numOfSamplesPerSplit; 1719 UINT_32 blocksInTile = tileSize / blockByteSize; 1720 1721 if (0 == blocksInTile) 1722 { 1723 lsb = 0; 1724 } 1725 else 1726 { 1727 lsb = Log2(blocksInTile); 1728 } 1729 msb = bankBits - 1 + lsb; 1730 1731 UINT_64 blockInBankpipeWithBankBits = AddrInsertBits(blockInBankpipe, bankDataBits, msb, lsb); 1732 1733 /// NOTE *2 because we are converting to Nibble address in this step 1734 UINT_64 metaAddressInPipe = blockInBankpipeWithBankBits * 2 * metadataBitSize / 8; 1735 1736 1737 ///-------------------------------------------------------------------------------------------- 1738 /// Reinsert pipe bits back into the final address 1739 ///-------------------------------------------------------------------------------------------- 1740 lsb = pipeInterleaveBits + 1; ///<+1 due to Nibble address now gives interleave bits extra lsb. 1741 msb = pipeBits - 1 + lsb; 1742 UINT_64 metadataAddress = AddrInsertBits(metaAddressInPipe, pipeDataBits, msb, lsb); 1743 1744 return metadataAddress; 1745 } 1746 1747 /** 1748 *************************************************************************************************** 1749 * CIAddrLib::HwlPadDimensions 1750 * 1751 * @brief 1752 * Helper function to pad dimensions 1753 * 1754 * @return 1755 * N/A 1756 * 1757 *************************************************************************************************** 1758 */ 1759 VOID CIAddrLib::HwlPadDimensions( 1760 AddrTileMode tileMode, ///< [in] tile mode 1761 UINT_32 bpp, ///< [in] bits per pixel 1762 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags 1763 UINT_32 numSamples, ///< [in] number of samples 1764 ADDR_TILEINFO* pTileInfo, ///< [in/out] bank structure. 1765 UINT_32 padDims, ///< [in] Dimensions to pad valid value 1,2,3 1766 UINT_32 mipLevel, ///< [in] MipLevel 1767 UINT_32* pPitch, ///< [in/out] pitch in pixels 1768 UINT_32 pitchAlign, ///< [in] pitch alignment 1769 UINT_32* pHeight, ///< [in/out] height in pixels 1770 UINT_32 heightAlign, ///< [in] height alignment 1771 UINT_32* pSlices, ///< [in/out] number of slices 1772 UINT_32 sliceAlign ///< [in] number of slice alignment 1773 ) const 1774 { 1775 if (m_settings.isVolcanicIslands && 1776 flags.dccCompatible && 1777 (numSamples > 1) && 1778 (mipLevel == 0) && 1779 IsMacroTiled(tileMode)) 1780 { 1781 UINT_32 tileSizePerSample = BITS_TO_BYTES(bpp * MicroTileWidth * MicroTileHeight); 1782 UINT_32 samplesPerSplit = pTileInfo->tileSplitBytes / tileSizePerSample; 1783 1784 if (samplesPerSplit < numSamples) 1785 { 1786 UINT_32 dccFastClearByteAlign = HwlGetPipes(pTileInfo) * m_pipeInterleaveBytes * 256; 1787 UINT_32 bytesPerSplit = BITS_TO_BYTES((*pPitch) * (*pHeight) * bpp * samplesPerSplit); 1788 1789 ADDR_ASSERT(IsPow2(dccFastClearByteAlign)); 1790 1791 if (0 != (bytesPerSplit & (dccFastClearByteAlign - 1))) 1792 { 1793 UINT_32 dccFastClearPixelAlign = dccFastClearByteAlign / 1794 BITS_TO_BYTES(bpp) / 1795 samplesPerSplit; 1796 UINT_32 macroTilePixelAlign = pitchAlign * heightAlign; 1797 1798 if ((dccFastClearPixelAlign >= macroTilePixelAlign) && 1799 ((dccFastClearPixelAlign % macroTilePixelAlign) == 0)) 1800 { 1801 UINT_32 dccFastClearPitchAlignInMacroTile = 1802 dccFastClearPixelAlign / macroTilePixelAlign; 1803 UINT_32 heightInMacroTile = *pHeight / heightAlign; 1804 UINT_32 dccFastClearPitchAlignInPixels; 1805 1806 while ((heightInMacroTile > 1) && 1807 ((heightInMacroTile % 2) == 0) && 1808 (dccFastClearPitchAlignInMacroTile > 1) && 1809 ((dccFastClearPitchAlignInMacroTile % 2) == 0)) 1810 { 1811 heightInMacroTile >>= 1; 1812 dccFastClearPitchAlignInMacroTile >>= 1; 1813 } 1814 1815 dccFastClearPitchAlignInPixels = pitchAlign * dccFastClearPitchAlignInMacroTile; 1816 1817 if (IsPow2(dccFastClearPitchAlignInPixels)) 1818 { 1819 *pPitch = PowTwoAlign((*pPitch), dccFastClearPitchAlignInPixels); 1820 } 1821 else 1822 { 1823 *pPitch += (dccFastClearPitchAlignInPixels - 1); 1824 *pPitch /= dccFastClearPitchAlignInPixels; 1825 *pPitch *= dccFastClearPitchAlignInPixels; 1826 } 1827 } 1828 } 1829 } 1830 } 1831 } 1832 1833