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 CiLib class. 31 **************************************************************************************************** 32 */ 33 34 #include "ciaddrlib.h" 35 36 #include "si_gb_reg.h" 37 38 #include "amdgpu_asic_addr.h" 39 40 //////////////////////////////////////////////////////////////////////////////////////////////////// 41 //////////////////////////////////////////////////////////////////////////////////////////////////// 42 43 namespace Addr 44 { 45 46 /** 47 **************************************************************************************************** 48 * CiHwlInit 49 * 50 * @brief 51 * Creates an CiLib object. 52 * 53 * @return 54 * Returns an CiLib object pointer. 55 **************************************************************************************************** 56 */ 57 Lib* CiHwlInit(const Client* pClient) 58 { 59 return V1::CiLib::CreateObj(pClient); 60 } 61 62 namespace V1 63 { 64 65 /** 66 **************************************************************************************************** 67 * Mask 68 * 69 * @brief 70 * Gets a mask of "width" 71 * @return 72 * Bit mask 73 **************************************************************************************************** 74 */ 75 static UINT_64 Mask( 76 UINT_32 width) ///< Width of bits 77 { 78 UINT_64 ret; 79 80 if (width >= sizeof(UINT_64)*8) 81 { 82 ret = ~((UINT_64) 0); 83 } 84 else 85 { 86 return (((UINT_64) 1) << width) - 1; 87 } 88 return ret; 89 } 90 91 /** 92 **************************************************************************************************** 93 * GetBits 94 * 95 * @brief 96 * Gets bits within a range of [msb, lsb] 97 * @return 98 * Bits of this range 99 **************************************************************************************************** 100 */ 101 static UINT_64 GetBits( 102 UINT_64 bits, ///< Source bits 103 UINT_32 msb, ///< Most signicant bit 104 UINT_32 lsb) ///< Least signicant bit 105 { 106 UINT_64 ret = 0; 107 108 if (msb >= lsb) 109 { 110 ret = (bits >> lsb) & (Mask(1 + msb - lsb)); 111 } 112 return ret; 113 } 114 115 /** 116 **************************************************************************************************** 117 * RemoveBits 118 * 119 * @brief 120 * Removes bits within the range of [msb, lsb] 121 * @return 122 * Modified bits 123 **************************************************************************************************** 124 */ 125 static UINT_64 RemoveBits( 126 UINT_64 bits, ///< Source bits 127 UINT_32 msb, ///< Most signicant bit 128 UINT_32 lsb) ///< Least signicant bit 129 { 130 UINT_64 ret = bits; 131 132 if (msb >= lsb) 133 { 134 ret = GetBits(bits, lsb - 1, 0) // low bits 135 | (GetBits(bits, 8 * sizeof(bits) - 1, msb + 1) << lsb); //high bits 136 } 137 return ret; 138 } 139 140 /** 141 **************************************************************************************************** 142 * InsertBits 143 * 144 * @brief 145 * Inserts new bits into the range of [msb, lsb] 146 * @return 147 * Modified bits 148 **************************************************************************************************** 149 */ 150 static UINT_64 InsertBits( 151 UINT_64 bits, ///< Source bits 152 UINT_64 newBits, ///< New bits to be inserted 153 UINT_32 msb, ///< Most signicant bit 154 UINT_32 lsb) ///< Least signicant bit 155 { 156 UINT_64 ret = bits; 157 158 if (msb >= lsb) 159 { 160 ret = GetBits(bits, lsb - 1, 0) // old low bitss 161 | (GetBits(newBits, msb - lsb, 0) << lsb) //new bits 162 | (GetBits(bits, 8 * sizeof(bits) - 1, lsb) << (msb + 1)); //old high bits 163 } 164 return ret; 165 } 166 167 /** 168 **************************************************************************************************** 169 * CiLib::CiLib 170 * 171 * @brief 172 * Constructor 173 * 174 **************************************************************************************************** 175 */ 176 CiLib::CiLib(const Client* pClient) 177 : 178 SiLib(pClient), 179 m_noOfMacroEntries(0), 180 m_allowNonDispThickModes(FALSE) 181 { 182 m_class = CI_ADDRLIB; 183 } 184 185 /** 186 **************************************************************************************************** 187 * CiLib::~CiLib 188 * 189 * @brief 190 * Destructor 191 **************************************************************************************************** 192 */ 193 CiLib::~CiLib() 194 { 195 } 196 197 /** 198 **************************************************************************************************** 199 * CiLib::HwlComputeDccInfo 200 * 201 * @brief 202 * Compute DCC key size, base alignment 203 * @return 204 * ADDR_E_RETURNCODE 205 **************************************************************************************************** 206 */ 207 ADDR_E_RETURNCODE CiLib::HwlComputeDccInfo( 208 const ADDR_COMPUTE_DCCINFO_INPUT* pIn, 209 ADDR_COMPUTE_DCCINFO_OUTPUT* pOut) const 210 { 211 ADDR_E_RETURNCODE returnCode = ADDR_OK; 212 213 if (m_settings.isVolcanicIslands && IsMacroTiled(pIn->tileMode)) 214 { 215 UINT_64 dccFastClearSize = pIn->colorSurfSize >> 8; 216 217 ADDR_ASSERT(0 == (pIn->colorSurfSize & 0xff)); 218 219 if (pIn->numSamples > 1) 220 { 221 UINT_32 tileSizePerSample = BITS_TO_BYTES(pIn->bpp * MicroTileWidth * MicroTileHeight); 222 UINT_32 samplesPerSplit = pIn->tileInfo.tileSplitBytes / tileSizePerSample; 223 224 if (samplesPerSplit < pIn->numSamples) 225 { 226 UINT_32 numSplits = pIn->numSamples / samplesPerSplit; 227 UINT_32 fastClearBaseAlign = HwlGetPipes(&pIn->tileInfo) * m_pipeInterleaveBytes; 228 229 ADDR_ASSERT(IsPow2(fastClearBaseAlign)); 230 231 dccFastClearSize /= numSplits; 232 233 if (0 != (dccFastClearSize & (fastClearBaseAlign - 1))) 234 { 235 // Disable dcc fast clear 236 // if key size of fisrt sample split is not pipe*interleave aligned 237 dccFastClearSize = 0; 238 } 239 } 240 } 241 242 pOut->dccRamSize = pIn->colorSurfSize >> 8; 243 pOut->dccRamBaseAlign = pIn->tileInfo.banks * 244 HwlGetPipes(&pIn->tileInfo) * 245 m_pipeInterleaveBytes; 246 pOut->dccFastClearSize = dccFastClearSize; 247 pOut->dccRamSizeAligned = TRUE; 248 249 ADDR_ASSERT(IsPow2(pOut->dccRamBaseAlign)); 250 251 if (0 == (pOut->dccRamSize & (pOut->dccRamBaseAlign - 1))) 252 { 253 pOut->subLvlCompressible = TRUE; 254 } 255 else 256 { 257 UINT_64 dccRamSizeAlign = HwlGetPipes(&pIn->tileInfo) * m_pipeInterleaveBytes; 258 259 if (pOut->dccRamSize == pOut->dccFastClearSize) 260 { 261 pOut->dccFastClearSize = PowTwoAlign(pOut->dccRamSize, dccRamSizeAlign); 262 } 263 if ((pOut->dccRamSize & (dccRamSizeAlign - 1)) != 0) 264 { 265 pOut->dccRamSizeAligned = FALSE; 266 } 267 pOut->dccRamSize = PowTwoAlign(pOut->dccRamSize, dccRamSizeAlign); 268 pOut->subLvlCompressible = FALSE; 269 } 270 } 271 else 272 { 273 returnCode = ADDR_NOTSUPPORTED; 274 } 275 276 return returnCode; 277 } 278 279 /** 280 **************************************************************************************************** 281 * CiLib::HwlComputeCmaskAddrFromCoord 282 * 283 * @brief 284 * Compute tc compatible Cmask address from fmask ram address 285 * 286 * @return 287 * ADDR_E_RETURNCODE 288 **************************************************************************************************** 289 */ 290 ADDR_E_RETURNCODE CiLib::HwlComputeCmaskAddrFromCoord( 291 const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] fmask addr/bpp/tile input 292 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] cmask address 293 ) const 294 { 295 ADDR_E_RETURNCODE returnCode = ADDR_NOTSUPPORTED; 296 297 if ((m_settings.isVolcanicIslands == TRUE) && 298 (pIn->flags.tcCompatible == TRUE)) 299 { 300 UINT_32 numOfPipes = HwlGetPipes(pIn->pTileInfo); 301 UINT_32 numOfBanks = pIn->pTileInfo->banks; 302 UINT_64 fmaskAddress = pIn->fmaskAddr; 303 UINT_32 elemBits = pIn->bpp; 304 UINT_32 blockByte = 64 * elemBits / 8; 305 UINT_64 metaNibbleAddress = HwlComputeMetadataNibbleAddress(fmaskAddress, 306 0, 307 0, 308 4, // cmask 4 bits 309 elemBits, 310 blockByte, 311 m_pipeInterleaveBytes, 312 numOfPipes, 313 numOfBanks, 314 1); 315 pOut->addr = (metaNibbleAddress >> 1); 316 pOut->bitPosition = (metaNibbleAddress % 2) ? 4 : 0; 317 returnCode = ADDR_OK; 318 } 319 320 return returnCode; 321 } 322 323 /** 324 **************************************************************************************************** 325 * CiLib::HwlComputeHtileAddrFromCoord 326 * 327 * @brief 328 * Compute tc compatible Htile address from depth/stencil address 329 * 330 * @return 331 * ADDR_E_RETURNCODE 332 **************************************************************************************************** 333 */ 334 ADDR_E_RETURNCODE CiLib::HwlComputeHtileAddrFromCoord( 335 const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn, ///< [in] depth/stencil addr/bpp/tile input 336 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] htile address 337 ) const 338 { 339 ADDR_E_RETURNCODE returnCode = ADDR_NOTSUPPORTED; 340 341 if ((m_settings.isVolcanicIslands == TRUE) && 342 (pIn->flags.tcCompatible == TRUE)) 343 { 344 UINT_32 numOfPipes = HwlGetPipes(pIn->pTileInfo); 345 UINT_32 numOfBanks = pIn->pTileInfo->banks; 346 UINT_64 zStencilAddr = pIn->zStencilAddr; 347 UINT_32 elemBits = pIn->bpp; 348 UINT_32 blockByte = 64 * elemBits / 8; 349 UINT_64 metaNibbleAddress = HwlComputeMetadataNibbleAddress(zStencilAddr, 350 0, 351 0, 352 32, // htile 32 bits 353 elemBits, 354 blockByte, 355 m_pipeInterleaveBytes, 356 numOfPipes, 357 numOfBanks, 358 1); 359 pOut->addr = (metaNibbleAddress >> 1); 360 pOut->bitPosition = 0; 361 returnCode = ADDR_OK; 362 } 363 364 return returnCode; 365 } 366 367 /** 368 **************************************************************************************************** 369 * CiLib::HwlConvertChipFamily 370 * 371 * @brief 372 * Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision 373 * @return 374 * ChipFamily 375 **************************************************************************************************** 376 */ 377 ChipFamily CiLib::HwlConvertChipFamily( 378 UINT_32 uChipFamily, ///< [in] chip family defined in atiih.h 379 UINT_32 uChipRevision) ///< [in] chip revision defined in "asic_family"_id.h 380 { 381 ChipFamily family = ADDR_CHIP_FAMILY_CI; 382 383 switch (uChipFamily) 384 { 385 case FAMILY_CI: 386 m_settings.isSeaIsland = 1; 387 m_settings.isBonaire = ASICREV_IS_BONAIRE_M(uChipRevision); 388 m_settings.isHawaii = ASICREV_IS_HAWAII_P(uChipRevision); 389 break; 390 case FAMILY_KV: 391 m_settings.isKaveri = 1; 392 m_settings.isSpectre = ASICREV_IS_SPECTRE(uChipRevision); 393 m_settings.isSpooky = ASICREV_IS_SPOOKY(uChipRevision); 394 m_settings.isKalindi = ASICREV_IS_KALINDI(uChipRevision); 395 break; 396 case FAMILY_VI: 397 m_settings.isVolcanicIslands = 1; 398 m_settings.isIceland = ASICREV_IS_ICELAND_M(uChipRevision); 399 m_settings.isTonga = ASICREV_IS_TONGA_P(uChipRevision); 400 m_settings.isFiji = ASICREV_IS_FIJI_P(uChipRevision); 401 m_settings.isPolaris10 = ASICREV_IS_POLARIS10_P(uChipRevision); 402 m_settings.isPolaris11 = ASICREV_IS_POLARIS11_M(uChipRevision); 403 m_settings.isPolaris12 = ASICREV_IS_POLARIS12_V(uChipRevision); 404 family = ADDR_CHIP_FAMILY_VI; 405 break; 406 case FAMILY_CZ: 407 m_settings.isCarrizo = 1; 408 m_settings.isVolcanicIslands = 1; 409 family = ADDR_CHIP_FAMILY_VI; 410 break; 411 default: 412 ADDR_ASSERT(!"This should be a unexpected Fusion"); 413 break; 414 } 415 416 return family; 417 } 418 419 /** 420 **************************************************************************************************** 421 * CiLib::HwlInitGlobalParams 422 * 423 * @brief 424 * Initializes global parameters 425 * 426 * @return 427 * TRUE if all settings are valid 428 * 429 **************************************************************************************************** 430 */ 431 BOOL_32 CiLib::HwlInitGlobalParams( 432 const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input 433 { 434 BOOL_32 valid = TRUE; 435 436 const ADDR_REGISTER_VALUE* pRegValue = &pCreateIn->regValue; 437 438 valid = DecodeGbRegs(pRegValue); 439 440 // The following assignments for m_pipes is only for fail-safe, InitTileSettingTable should 441 // read the correct pipes from tile mode table 442 if (m_settings.isHawaii) 443 { 444 m_pipes = 16; 445 } 446 else if (m_settings.isBonaire || m_settings.isSpectre) 447 { 448 m_pipes = 4; 449 } 450 else // Treat other KV asics to be 2-pipe 451 { 452 m_pipes = 2; 453 } 454 455 // @todo: VI 456 // Move this to VI code path once created 457 if (m_settings.isTonga || m_settings.isPolaris10) 458 { 459 m_pipes = 8; 460 } 461 else if (m_settings.isIceland) 462 { 463 m_pipes = 2; 464 } 465 else if (m_settings.isFiji) 466 { 467 m_pipes = 16; 468 } 469 else if (m_settings.isPolaris11 || m_settings.isPolaris12) 470 { 471 m_pipes = 4; 472 } 473 474 if (valid) 475 { 476 valid = InitTileSettingTable(pRegValue->pTileConfig, pRegValue->noOfEntries); 477 } 478 if (valid) 479 { 480 valid = InitMacroTileCfgTable(pRegValue->pMacroTileConfig, pRegValue->noOfMacroEntries); 481 } 482 483 if (valid) 484 { 485 InitEquationTable(); 486 } 487 488 return valid; 489 } 490 491 /** 492 **************************************************************************************************** 493 * CiLib::HwlPostCheckTileIndex 494 * 495 * @brief 496 * Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches 497 * tile mode/type/info and change the index if needed 498 * @return 499 * Tile index. 500 **************************************************************************************************** 501 */ 502 INT_32 CiLib::HwlPostCheckTileIndex( 503 const ADDR_TILEINFO* pInfo, ///< [in] Tile Info 504 AddrTileMode mode, ///< [in] Tile mode 505 AddrTileType type, ///< [in] Tile type 506 INT curIndex ///< [in] Current index assigned in HwlSetupTileInfo 507 ) const 508 { 509 INT_32 index = curIndex; 510 511 if (mode == ADDR_TM_LINEAR_GENERAL) 512 { 513 index = TileIndexLinearGeneral; 514 } 515 else 516 { 517 BOOL_32 macroTiled = IsMacroTiled(mode); 518 519 // We need to find a new index if either of them is true 520 // 1. curIndex is invalid 521 // 2. tile mode is changed 522 // 3. tile info does not match for macro tiled 523 if ((index == TileIndexInvalid) || 524 (mode != m_tileTable[index].mode) || 525 (macroTiled && pInfo->pipeConfig != m_tileTable[index].info.pipeConfig)) 526 { 527 for (index = 0; index < static_cast<INT_32>(m_noOfEntries); index++) 528 { 529 if (macroTiled) 530 { 531 // macro tile modes need all to match 532 if ((pInfo->pipeConfig == m_tileTable[index].info.pipeConfig) && 533 (mode == m_tileTable[index].mode) && 534 (type == m_tileTable[index].type)) 535 { 536 // tileSplitBytes stored in m_tileTable is only valid for depth entries 537 if (type == ADDR_DEPTH_SAMPLE_ORDER) 538 { 539 if (Min(m_tileTable[index].info.tileSplitBytes, 540 m_rowSize) == pInfo->tileSplitBytes) 541 { 542 break; 543 } 544 } 545 else // other entries are determined by other 3 fields 546 { 547 break; 548 } 549 } 550 } 551 else if (mode == ADDR_TM_LINEAR_ALIGNED) 552 { 553 // linear mode only needs tile mode to match 554 if (mode == m_tileTable[index].mode) 555 { 556 break; 557 } 558 } 559 else 560 { 561 // micro tile modes only need tile mode and tile type to match 562 if (mode == m_tileTable[index].mode && 563 type == m_tileTable[index].type) 564 { 565 break; 566 } 567 } 568 } 569 } 570 } 571 572 ADDR_ASSERT(index < static_cast<INT_32>(m_noOfEntries)); 573 574 if (index >= static_cast<INT_32>(m_noOfEntries)) 575 { 576 index = TileIndexInvalid; 577 } 578 579 return index; 580 } 581 582 /** 583 **************************************************************************************************** 584 * CiLib::HwlSetupTileCfg 585 * 586 * @brief 587 * Map tile index to tile setting. 588 * @return 589 * ADDR_E_RETURNCODE 590 **************************************************************************************************** 591 */ 592 ADDR_E_RETURNCODE CiLib::HwlSetupTileCfg( 593 UINT_32 bpp, ///< Bits per pixel 594 INT_32 index, ///< Tile index 595 INT_32 macroModeIndex, ///< Index in macro tile mode table(CI) 596 ADDR_TILEINFO* pInfo, ///< [out] Tile Info 597 AddrTileMode* pMode, ///< [out] Tile mode 598 AddrTileType* pType ///< [out] Tile type 599 ) const 600 { 601 ADDR_E_RETURNCODE returnCode = ADDR_OK; 602 603 // Global flag to control usage of tileIndex 604 if (UseTileIndex(index)) 605 { 606 if (index == TileIndexLinearGeneral) 607 { 608 pInfo->banks = 2; 609 pInfo->bankWidth = 1; 610 pInfo->bankHeight = 1; 611 pInfo->macroAspectRatio = 1; 612 pInfo->tileSplitBytes = 64; 613 pInfo->pipeConfig = ADDR_PIPECFG_P2; 614 } 615 else if (static_cast<UINT_32>(index) >= m_noOfEntries) 616 { 617 returnCode = ADDR_INVALIDPARAMS; 618 } 619 else 620 { 621 const TileConfig* pCfgTable = GetTileSetting(index); 622 623 if (pInfo != NULL) 624 { 625 if (IsMacroTiled(pCfgTable->mode)) 626 { 627 ADDR_ASSERT((macroModeIndex != TileIndexInvalid) && 628 (macroModeIndex != TileIndexNoMacroIndex)); 629 630 UINT_32 tileSplit; 631 632 *pInfo = m_macroTileTable[macroModeIndex]; 633 634 if (pCfgTable->type == ADDR_DEPTH_SAMPLE_ORDER) 635 { 636 tileSplit = pCfgTable->info.tileSplitBytes; 637 } 638 else 639 { 640 if (bpp > 0) 641 { 642 UINT_32 thickness = Thickness(pCfgTable->mode); 643 UINT_32 tileBytes1x = BITS_TO_BYTES(bpp * MicroTilePixels * thickness); 644 // Non-depth entries store a split factor 645 UINT_32 sampleSplit = m_tileTable[index].info.tileSplitBytes; 646 tileSplit = Max(256u, sampleSplit * tileBytes1x); 647 } 648 else 649 { 650 // Return tileBytes instead if not enough info 651 tileSplit = pInfo->tileSplitBytes; 652 } 653 } 654 655 // Clamp to row_size 656 pInfo->tileSplitBytes = Min(m_rowSize, tileSplit); 657 658 pInfo->pipeConfig = pCfgTable->info.pipeConfig; 659 } 660 else // 1D and linear modes, we return default value stored in table 661 { 662 *pInfo = pCfgTable->info; 663 } 664 } 665 666 if (pMode != NULL) 667 { 668 *pMode = pCfgTable->mode; 669 } 670 671 if (pType != NULL) 672 { 673 *pType = pCfgTable->type; 674 } 675 } 676 } 677 678 return returnCode; 679 } 680 681 /** 682 **************************************************************************************************** 683 * CiLib::HwlComputeSurfaceInfo 684 * 685 * @brief 686 * Entry of CI's ComputeSurfaceInfo 687 * @return 688 * ADDR_E_RETURNCODE 689 **************************************************************************************************** 690 */ 691 ADDR_E_RETURNCODE CiLib::HwlComputeSurfaceInfo( 692 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure 693 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure 694 ) const 695 { 696 // If tileIndex is invalid, force macroModeIndex to be invalid, too 697 if (pIn->tileIndex == TileIndexInvalid) 698 { 699 pOut->macroModeIndex = TileIndexInvalid; 700 } 701 702 ADDR_E_RETURNCODE retCode = SiLib::HwlComputeSurfaceInfo(pIn, pOut); 703 704 if ((pIn->mipLevel > 0) && 705 (pOut->tcCompatible == TRUE) && 706 (pOut->tileMode != pIn->tileMode) && 707 (m_settings.isVolcanicIslands == TRUE)) 708 { 709 pOut->tcCompatible = CheckTcCompatibility(pOut->pTileInfo, pIn->bpp, pOut->tileMode, pOut->tileType, pOut); 710 } 711 712 if (pOut->macroModeIndex == TileIndexNoMacroIndex) 713 { 714 pOut->macroModeIndex = TileIndexInvalid; 715 } 716 717 if ((pIn->flags.matchStencilTileCfg == TRUE) && 718 (pIn->flags.depth == TRUE)) 719 { 720 pOut->stencilTileIdx = TileIndexInvalid; 721 722 if ((MinDepth2DThinIndex <= pOut->tileIndex) && 723 (MaxDepth2DThinIndex >= pOut->tileIndex)) 724 { 725 BOOL_32 depthStencil2DTileConfigMatch = DepthStencilTileCfgMatch(pIn, pOut); 726 727 if ((depthStencil2DTileConfigMatch == FALSE) && 728 (pOut->tcCompatible == TRUE)) 729 { 730 pOut->macroModeIndex = TileIndexInvalid; 731 732 ADDR_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn; 733 localIn.tileIndex = TileIndexInvalid; 734 localIn.pTileInfo = NULL; 735 localIn.flags.tcCompatible = FALSE; 736 737 SiLib::HwlComputeSurfaceInfo(&localIn, pOut); 738 739 ADDR_ASSERT(((MinDepth2DThinIndex <= pOut->tileIndex) && (MaxDepth2DThinIndex >= pOut->tileIndex)) || pOut->tileIndex == Depth1DThinIndex); 740 741 depthStencil2DTileConfigMatch = DepthStencilTileCfgMatch(pIn, pOut); 742 } 743 744 if ((depthStencil2DTileConfigMatch == FALSE) && 745 (pIn->numSamples <= 1)) 746 { 747 pOut->macroModeIndex = TileIndexInvalid; 748 749 ADDR_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn; 750 localIn.tileMode = ADDR_TM_1D_TILED_THIN1; 751 localIn.tileIndex = TileIndexInvalid; 752 localIn.pTileInfo = NULL; 753 754 retCode = SiLib::HwlComputeSurfaceInfo(&localIn, pOut); 755 } 756 } 757 758 if (pOut->tileIndex == Depth1DThinIndex) 759 { 760 pOut->stencilTileIdx = Depth1DThinIndex; 761 } 762 } 763 764 return retCode; 765 } 766 767 /** 768 **************************************************************************************************** 769 * CiLib::HwlFmaskSurfaceInfo 770 * @brief 771 * Entry of r800's ComputeFmaskInfo 772 * @return 773 * ADDR_E_RETURNCODE 774 **************************************************************************************************** 775 */ 776 ADDR_E_RETURNCODE CiLib::HwlComputeFmaskInfo( 777 const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure 778 ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure 779 ) 780 { 781 ADDR_E_RETURNCODE retCode = ADDR_OK; 782 783 ADDR_TILEINFO tileInfo = {0}; 784 ADDR_COMPUTE_FMASK_INFO_INPUT fmaskIn; 785 fmaskIn = *pIn; 786 787 AddrTileMode tileMode = pIn->tileMode; 788 789 // Use internal tile info if pOut does not have a valid pTileInfo 790 if (pOut->pTileInfo == NULL) 791 { 792 pOut->pTileInfo = &tileInfo; 793 } 794 795 ADDR_ASSERT(tileMode == ADDR_TM_2D_TILED_THIN1 || 796 tileMode == ADDR_TM_3D_TILED_THIN1 || 797 tileMode == ADDR_TM_PRT_TILED_THIN1 || 798 tileMode == ADDR_TM_PRT_2D_TILED_THIN1 || 799 tileMode == ADDR_TM_PRT_3D_TILED_THIN1); 800 801 ADDR_ASSERT(m_tileTable[14].mode == ADDR_TM_2D_TILED_THIN1); 802 ADDR_ASSERT(m_tileTable[15].mode == ADDR_TM_3D_TILED_THIN1); 803 804 // The only valid tile modes for fmask are 2D_THIN1 and 3D_THIN1 plus non-displayable 805 INT_32 tileIndex = tileMode == ADDR_TM_2D_TILED_THIN1 ? 14 : 15; 806 ADDR_SURFACE_FLAGS flags = {{0}}; 807 flags.fmask = 1; 808 809 INT_32 macroModeIndex = TileIndexInvalid; 810 811 UINT_32 numSamples = pIn->numSamples; 812 UINT_32 numFrags = pIn->numFrags == 0 ? numSamples : pIn->numFrags; 813 814 UINT_32 bpp = QLog2(numFrags); 815 816 // EQAA needs one more bit 817 if (numSamples > numFrags) 818 { 819 bpp++; 820 } 821 822 if (bpp == 3) 823 { 824 bpp = 4; 825 } 826 827 bpp = Max(8u, bpp * numSamples); 828 829 macroModeIndex = HwlComputeMacroModeIndex(tileIndex, flags, bpp, numSamples, pOut->pTileInfo); 830 831 fmaskIn.tileIndex = tileIndex; 832 fmaskIn.pTileInfo = pOut->pTileInfo; 833 pOut->macroModeIndex = macroModeIndex; 834 pOut->tileIndex = tileIndex; 835 836 retCode = DispatchComputeFmaskInfo(&fmaskIn, pOut); 837 838 if (retCode == ADDR_OK) 839 { 840 pOut->tileIndex = 841 HwlPostCheckTileIndex(pOut->pTileInfo, pIn->tileMode, ADDR_NON_DISPLAYABLE, 842 pOut->tileIndex); 843 } 844 845 // Resets pTileInfo to NULL if the internal tile info is used 846 if (pOut->pTileInfo == &tileInfo) 847 { 848 pOut->pTileInfo = NULL; 849 } 850 851 return retCode; 852 } 853 854 /** 855 **************************************************************************************************** 856 * CiLib::HwlFmaskPreThunkSurfInfo 857 * 858 * @brief 859 * Some preparation before thunking a ComputeSurfaceInfo call for Fmask 860 * @return 861 * ADDR_E_RETURNCODE 862 **************************************************************************************************** 863 */ 864 VOID CiLib::HwlFmaskPreThunkSurfInfo( 865 const ADDR_COMPUTE_FMASK_INFO_INPUT* pFmaskIn, ///< [in] Input of fmask info 866 const ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut, ///< [in] Output of fmask info 867 ADDR_COMPUTE_SURFACE_INFO_INPUT* pSurfIn, ///< [out] Input of thunked surface info 868 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut ///< [out] Output of thunked surface info 869 ) const 870 { 871 pSurfIn->tileIndex = pFmaskIn->tileIndex; 872 pSurfOut->macroModeIndex = pFmaskOut->macroModeIndex; 873 } 874 875 /** 876 **************************************************************************************************** 877 * CiLib::HwlFmaskPostThunkSurfInfo 878 * 879 * @brief 880 * Copy hwl extra field after calling thunked ComputeSurfaceInfo 881 * @return 882 * ADDR_E_RETURNCODE 883 **************************************************************************************************** 884 */ 885 VOID CiLib::HwlFmaskPostThunkSurfInfo( 886 const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut, ///< [in] Output of surface info 887 ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut ///< [out] Output of fmask info 888 ) const 889 { 890 pFmaskOut->tileIndex = pSurfOut->tileIndex; 891 pFmaskOut->macroModeIndex = pSurfOut->macroModeIndex; 892 } 893 894 /** 895 **************************************************************************************************** 896 * CiLib::HwlDegradeThickTileMode 897 * 898 * @brief 899 * Degrades valid tile mode for thick modes if needed 900 * 901 * @return 902 * Suitable tile mode 903 **************************************************************************************************** 904 */ 905 AddrTileMode CiLib::HwlDegradeThickTileMode( 906 AddrTileMode baseTileMode, ///< [in] base tile mode 907 UINT_32 numSlices, ///< [in] current number of slices 908 UINT_32* pBytesPerTile ///< [in,out] pointer to bytes per slice 909 ) const 910 { 911 return baseTileMode; 912 } 913 914 /** 915 **************************************************************************************************** 916 * CiLib::HwlOptimizeTileMode 917 * 918 * @brief 919 * Optimize tile mode on CI 920 * 921 * @return 922 * N/A 923 * 924 **************************************************************************************************** 925 */ 926 VOID CiLib::HwlOptimizeTileMode( 927 ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in,out] input output structure 928 ) const 929 { 930 AddrTileMode tileMode = pInOut->tileMode; 931 932 // Override 2D/3D macro tile mode to PRT_* tile mode if 933 // client driver requests this surface is equation compatible 934 if (IsMacroTiled(tileMode) == TRUE) 935 { 936 if ((pInOut->flags.needEquation == TRUE) && 937 (pInOut->numSamples <= 1) && 938 (IsPrtTileMode(tileMode) == FALSE)) 939 { 940 if ((pInOut->numSlices > 1) && ((pInOut->maxBaseAlign == 0) || (pInOut->maxBaseAlign >= Block64K))) 941 { 942 UINT_32 thickness = Thickness(tileMode); 943 944 if (thickness == 1) 945 { 946 tileMode = ADDR_TM_PRT_TILED_THIN1; 947 } 948 else 949 { 950 static const UINT_32 PrtTileBytes = 0x10000; 951 // First prt thick tile index in the tile mode table 952 static const UINT_32 PrtThickTileIndex = 22; 953 ADDR_TILEINFO tileInfo = {0}; 954 955 HwlComputeMacroModeIndex(PrtThickTileIndex, 956 pInOut->flags, 957 pInOut->bpp, 958 pInOut->numSamples, 959 &tileInfo); 960 961 UINT_32 macroTileBytes = ((pInOut->bpp) >> 3) * 64 * pInOut->numSamples * 962 thickness * HwlGetPipes(&tileInfo) * 963 tileInfo.banks * tileInfo.bankWidth * 964 tileInfo.bankHeight; 965 966 if (macroTileBytes <= PrtTileBytes) 967 { 968 tileMode = ADDR_TM_PRT_TILED_THICK; 969 } 970 else 971 { 972 tileMode = ADDR_TM_PRT_TILED_THIN1; 973 } 974 } 975 } 976 } 977 978 if (pInOut->maxBaseAlign != 0) 979 { 980 pInOut->flags.dccPipeWorkaround = FALSE; 981 } 982 } 983 984 if (tileMode != pInOut->tileMode) 985 { 986 pInOut->tileMode = tileMode; 987 } 988 } 989 990 /** 991 **************************************************************************************************** 992 * CiLib::HwlOverrideTileMode 993 * 994 * @brief 995 * Override THICK to THIN, for specific formats on CI 996 * 997 * @return 998 * N/A 999 * 1000 **************************************************************************************************** 1001 */ 1002 VOID CiLib::HwlOverrideTileMode( 1003 ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in,out] input output structure 1004 ) const 1005 { 1006 AddrTileMode tileMode = pInOut->tileMode; 1007 AddrTileType tileType = pInOut->tileType; 1008 1009 // currently, all CI/VI family do not 1010 // support ADDR_TM_PRT_2D_TILED_THICK,ADDR_TM_PRT_3D_TILED_THICK and 1011 // ADDR_TM_PRT_2D_TILED_THIN1, ADDR_TM_PRT_3D_TILED_THIN1 1012 switch (tileMode) 1013 { 1014 case ADDR_TM_PRT_2D_TILED_THICK: 1015 case ADDR_TM_PRT_3D_TILED_THICK: 1016 tileMode = ADDR_TM_PRT_TILED_THICK; 1017 break; 1018 case ADDR_TM_PRT_2D_TILED_THIN1: 1019 case ADDR_TM_PRT_3D_TILED_THIN1: 1020 tileMode = ADDR_TM_PRT_TILED_THIN1; 1021 break; 1022 default: 1023 break; 1024 } 1025 1026 // UBTS#404321, we do not need such overriding, as THICK+THICK entries removed from the tile-mode table 1027 if (!m_settings.isBonaire) 1028 { 1029 UINT_32 thickness = Thickness(tileMode); 1030 1031 // tile_thickness = (array_mode == XTHICK) ? 8 : ((array_mode == THICK) ? 4 : 1) 1032 if (thickness > 1) 1033 { 1034 switch (pInOut->format) 1035 { 1036 // see //gfxip/gcB/devel/cds/src/verif/tc/models/csim/tcp.cpp 1037 // tcpError("Thick micro tiling is not supported for format... 1038 case ADDR_FMT_X24_8_32_FLOAT: 1039 case ADDR_FMT_32_AS_8: 1040 case ADDR_FMT_32_AS_8_8: 1041 case ADDR_FMT_32_AS_32_32_32_32: 1042 1043 // packed formats 1044 case ADDR_FMT_GB_GR: 1045 case ADDR_FMT_BG_RG: 1046 case ADDR_FMT_1_REVERSED: 1047 case ADDR_FMT_1: 1048 case ADDR_FMT_BC1: 1049 case ADDR_FMT_BC2: 1050 case ADDR_FMT_BC3: 1051 case ADDR_FMT_BC4: 1052 case ADDR_FMT_BC5: 1053 case ADDR_FMT_BC6: 1054 case ADDR_FMT_BC7: 1055 switch (tileMode) 1056 { 1057 case ADDR_TM_1D_TILED_THICK: 1058 tileMode = ADDR_TM_1D_TILED_THIN1; 1059 break; 1060 1061 case ADDR_TM_2D_TILED_XTHICK: 1062 case ADDR_TM_2D_TILED_THICK: 1063 tileMode = ADDR_TM_2D_TILED_THIN1; 1064 break; 1065 1066 case ADDR_TM_3D_TILED_XTHICK: 1067 case ADDR_TM_3D_TILED_THICK: 1068 tileMode = ADDR_TM_3D_TILED_THIN1; 1069 break; 1070 1071 case ADDR_TM_PRT_TILED_THICK: 1072 tileMode = ADDR_TM_PRT_TILED_THIN1; 1073 break; 1074 1075 case ADDR_TM_PRT_2D_TILED_THICK: 1076 tileMode = ADDR_TM_PRT_2D_TILED_THIN1; 1077 break; 1078 1079 case ADDR_TM_PRT_3D_TILED_THICK: 1080 tileMode = ADDR_TM_PRT_3D_TILED_THIN1; 1081 break; 1082 1083 default: 1084 break; 1085 1086 } 1087 1088 // Switch tile type from thick to thin 1089 if (tileMode != pInOut->tileMode) 1090 { 1091 // see tileIndex: 13-18 1092 tileType = ADDR_NON_DISPLAYABLE; 1093 } 1094 1095 break; 1096 default: 1097 break; 1098 } 1099 } 1100 } 1101 1102 if (tileMode != pInOut->tileMode) 1103 { 1104 pInOut->tileMode = tileMode; 1105 pInOut->tileType = tileType; 1106 } 1107 } 1108 1109 /** 1110 **************************************************************************************************** 1111 * CiLib::HwlSelectTileMode 1112 * 1113 * @brief 1114 * Select tile modes. 1115 * 1116 * @return 1117 * N/A 1118 * 1119 **************************************************************************************************** 1120 */ 1121 VOID CiLib::HwlSelectTileMode( 1122 ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in,out] input output structure 1123 ) const 1124 { 1125 AddrTileMode tileMode; 1126 AddrTileType tileType; 1127 1128 if (pInOut->flags.rotateDisplay) 1129 { 1130 tileMode = ADDR_TM_2D_TILED_THIN1; 1131 tileType = ADDR_ROTATED; 1132 } 1133 else if (pInOut->flags.volume) 1134 { 1135 BOOL_32 bThin = (m_settings.isBonaire == TRUE) || 1136 ((m_allowNonDispThickModes == TRUE) && (pInOut->flags.color == TRUE)); 1137 1138 if (pInOut->numSlices >= 8) 1139 { 1140 tileMode = ADDR_TM_2D_TILED_XTHICK; 1141 tileType = (bThin == TRUE) ? ADDR_NON_DISPLAYABLE : ADDR_THICK; 1142 } 1143 else if (pInOut->numSlices >= 4) 1144 { 1145 tileMode = ADDR_TM_2D_TILED_THICK; 1146 tileType = (bThin == TRUE) ? ADDR_NON_DISPLAYABLE : ADDR_THICK; 1147 } 1148 else 1149 { 1150 tileMode = ADDR_TM_2D_TILED_THIN1; 1151 tileType = ADDR_NON_DISPLAYABLE; 1152 } 1153 } 1154 else 1155 { 1156 tileMode = ADDR_TM_2D_TILED_THIN1; 1157 1158 if (pInOut->flags.depth || pInOut->flags.stencil) 1159 { 1160 tileType = ADDR_DEPTH_SAMPLE_ORDER; 1161 } 1162 else if ((pInOut->bpp <= 32) || 1163 (pInOut->flags.display == TRUE) || 1164 (pInOut->flags.overlay == TRUE)) 1165 { 1166 tileType = ADDR_DISPLAYABLE; 1167 } 1168 else 1169 { 1170 tileType = ADDR_NON_DISPLAYABLE; 1171 } 1172 } 1173 1174 if (pInOut->flags.prt) 1175 { 1176 if (Thickness(tileMode) > 1) 1177 { 1178 tileMode = ADDR_TM_PRT_TILED_THICK; 1179 tileType = (m_settings.isBonaire == TRUE) ? ADDR_NON_DISPLAYABLE : ADDR_THICK; 1180 } 1181 else 1182 { 1183 tileMode = ADDR_TM_PRT_TILED_THIN1; 1184 } 1185 } 1186 1187 pInOut->tileMode = tileMode; 1188 pInOut->tileType = tileType; 1189 1190 if ((pInOut->flags.dccCompatible == FALSE) && 1191 (pInOut->flags.tcCompatible == FALSE)) 1192 { 1193 pInOut->flags.opt4Space = TRUE; 1194 pInOut->maxBaseAlign = Block64K; 1195 } 1196 1197 // Optimize tile mode if possible 1198 OptimizeTileMode(pInOut); 1199 1200 HwlOverrideTileMode(pInOut); 1201 } 1202 1203 /** 1204 **************************************************************************************************** 1205 * CiLib::HwlSetPrtTileMode 1206 * 1207 * @brief 1208 * Set PRT tile mode. 1209 * 1210 * @return 1211 * N/A 1212 * 1213 **************************************************************************************************** 1214 */ 1215 VOID CiLib::HwlSetPrtTileMode( 1216 ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in,out] input output structure 1217 ) const 1218 { 1219 AddrTileMode tileMode = pInOut->tileMode; 1220 AddrTileType tileType = pInOut->tileType; 1221 1222 if (Thickness(tileMode) > 1) 1223 { 1224 tileMode = ADDR_TM_PRT_TILED_THICK; 1225 tileType = (m_settings.isBonaire == TRUE) ? ADDR_NON_DISPLAYABLE : ADDR_THICK; 1226 } 1227 else 1228 { 1229 tileMode = ADDR_TM_PRT_TILED_THIN1; 1230 tileType = (tileType == ADDR_THICK) ? ADDR_NON_DISPLAYABLE : tileType; 1231 } 1232 1233 pInOut->tileMode = tileMode; 1234 pInOut->tileType = tileType; 1235 } 1236 1237 /** 1238 **************************************************************************************************** 1239 * CiLib::HwlSetupTileInfo 1240 * 1241 * @brief 1242 * Setup default value of tile info for SI 1243 **************************************************************************************************** 1244 */ 1245 VOID CiLib::HwlSetupTileInfo( 1246 AddrTileMode tileMode, ///< [in] Tile mode 1247 ADDR_SURFACE_FLAGS flags, ///< [in] Surface type flags 1248 UINT_32 bpp, ///< [in] Bits per pixel 1249 UINT_32 pitch, ///< [in] Pitch in pixels 1250 UINT_32 height, ///< [in] Height in pixels 1251 UINT_32 numSamples, ///< [in] Number of samples 1252 ADDR_TILEINFO* pTileInfoIn, ///< [in] Tile info input: NULL for default 1253 ADDR_TILEINFO* pTileInfoOut, ///< [out] Tile info output 1254 AddrTileType inTileType, ///< [in] Tile type 1255 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] Output 1256 ) const 1257 { 1258 UINT_32 thickness = Thickness(tileMode); 1259 ADDR_TILEINFO* pTileInfo = pTileInfoOut; 1260 INT index = TileIndexInvalid; 1261 INT macroModeIndex = TileIndexInvalid; 1262 1263 // Fail-safe code 1264 if (IsLinear(tileMode) == FALSE) 1265 { 1266 // Thick tile modes must use thick micro tile mode but Bonaire does not support due to 1267 // old derived netlists (UBTS 404321) 1268 if (thickness > 1) 1269 { 1270 if (m_settings.isBonaire) 1271 { 1272 inTileType = ADDR_NON_DISPLAYABLE; 1273 } 1274 else if ((m_allowNonDispThickModes == FALSE) || 1275 (inTileType != ADDR_NON_DISPLAYABLE) || 1276 // There is no PRT_THICK + THIN entry in tile mode table except Bonaire 1277 (IsPrtTileMode(tileMode) == TRUE)) 1278 { 1279 inTileType = ADDR_THICK; 1280 } 1281 } 1282 // 128 bpp tiling must be non-displayable. 1283 // Fmask reuse color buffer's entry but bank-height field can be from another entry 1284 // To simplify the logic, fmask entry should be picked from non-displayable ones 1285 else if (bpp == 128 || flags.fmask) 1286 { 1287 inTileType = ADDR_NON_DISPLAYABLE; 1288 } 1289 // These two modes only have non-disp entries though they can be other micro tile modes 1290 else if (tileMode == ADDR_TM_3D_TILED_THIN1 || tileMode == ADDR_TM_PRT_3D_TILED_THIN1) 1291 { 1292 inTileType = ADDR_NON_DISPLAYABLE; 1293 } 1294 1295 if (flags.depth || flags.stencil) 1296 { 1297 inTileType = ADDR_DEPTH_SAMPLE_ORDER; 1298 } 1299 } 1300 1301 // tcCompatible flag is only meaningful for gfx8. 1302 if (m_settings.isVolcanicIslands == FALSE) 1303 { 1304 flags.tcCompatible = FALSE; 1305 } 1306 1307 if (IsTileInfoAllZero(pTileInfo)) 1308 { 1309 // See table entries 0-4 1310 if (flags.depth || flags.stencil) 1311 { 1312 // tileSize = thickness * bpp * numSamples * 8 * 8 / 8 1313 UINT_32 tileSize = thickness * bpp * numSamples * 8; 1314 1315 // Turn off tc compatible if row_size is smaller than tile size (tile split occurs). 1316 if (m_rowSize < tileSize) 1317 { 1318 flags.tcCompatible = FALSE; 1319 } 1320 1321 if (flags.nonSplit | flags.tcCompatible | flags.needEquation) 1322 { 1323 // Texture readable depth surface should not be split 1324 switch (tileSize) 1325 { 1326 case 64: 1327 index = 0; 1328 break; 1329 case 128: 1330 index = 1; 1331 break; 1332 case 256: 1333 index = 2; 1334 break; 1335 case 512: 1336 index = 3; 1337 break; 1338 default: 1339 index = 4; 1340 break; 1341 } 1342 } 1343 else 1344 { 1345 // Depth and stencil need to use the same index, thus the pre-defined tile_split 1346 // can meet the requirement to choose the same macro mode index 1347 // uncompressed depth/stencil are not supported for now 1348 switch (numSamples) 1349 { 1350 case 1: 1351 index = 0; 1352 break; 1353 case 2: 1354 case 4: 1355 index = 1; 1356 break; 1357 case 8: 1358 index = 2; 1359 break; 1360 default: 1361 break; 1362 } 1363 } 1364 } 1365 1366 // See table entries 5-6 1367 if (inTileType == ADDR_DEPTH_SAMPLE_ORDER) 1368 { 1369 switch (tileMode) 1370 { 1371 case ADDR_TM_1D_TILED_THIN1: 1372 index = 5; 1373 break; 1374 case ADDR_TM_PRT_TILED_THIN1: 1375 index = 6; 1376 break; 1377 default: 1378 break; 1379 } 1380 } 1381 1382 // See table entries 8-12 1383 if (inTileType == ADDR_DISPLAYABLE) 1384 { 1385 switch (tileMode) 1386 { 1387 case ADDR_TM_1D_TILED_THIN1: 1388 index = 9; 1389 break; 1390 case ADDR_TM_2D_TILED_THIN1: 1391 index = 10; 1392 break; 1393 case ADDR_TM_PRT_TILED_THIN1: 1394 index = 11; 1395 break; 1396 default: 1397 break; 1398 } 1399 } 1400 1401 // See table entries 13-18 1402 if (inTileType == ADDR_NON_DISPLAYABLE) 1403 { 1404 switch (tileMode) 1405 { 1406 case ADDR_TM_1D_TILED_THIN1: 1407 index = 13; 1408 break; 1409 case ADDR_TM_2D_TILED_THIN1: 1410 index = 14; 1411 break; 1412 case ADDR_TM_3D_TILED_THIN1: 1413 index = 15; 1414 break; 1415 case ADDR_TM_PRT_TILED_THIN1: 1416 index = 16; 1417 break; 1418 default: 1419 break; 1420 } 1421 } 1422 1423 // See table entries 19-26 1424 if (thickness > 1) 1425 { 1426 switch (tileMode) 1427 { 1428 case ADDR_TM_1D_TILED_THICK: 1429 // special check for bonaire, for the compatablity between old KMD and new UMD 1430 index = ((inTileType == ADDR_THICK) || m_settings.isBonaire) ? 19 : 18; 1431 break; 1432 case ADDR_TM_2D_TILED_THICK: 1433 // special check for bonaire, for the compatablity between old KMD and new UMD 1434 index = ((inTileType == ADDR_THICK) || m_settings.isBonaire) ? 20 : 24; 1435 break; 1436 case ADDR_TM_3D_TILED_THICK: 1437 index = 21; 1438 break; 1439 case ADDR_TM_PRT_TILED_THICK: 1440 index = 22; 1441 break; 1442 case ADDR_TM_2D_TILED_XTHICK: 1443 index = 25; 1444 break; 1445 case ADDR_TM_3D_TILED_XTHICK: 1446 index = 26; 1447 break; 1448 default: 1449 break; 1450 } 1451 } 1452 1453 // See table entries 27-30 1454 if (inTileType == ADDR_ROTATED) 1455 { 1456 switch (tileMode) 1457 { 1458 case ADDR_TM_1D_TILED_THIN1: 1459 index = 27; 1460 break; 1461 case ADDR_TM_2D_TILED_THIN1: 1462 index = 28; 1463 break; 1464 case ADDR_TM_PRT_TILED_THIN1: 1465 index = 29; 1466 break; 1467 case ADDR_TM_PRT_2D_TILED_THIN1: 1468 index = 30; 1469 break; 1470 default: 1471 break; 1472 } 1473 } 1474 1475 if (m_pipes >= 8) 1476 { 1477 ADDR_ASSERT((index + 1) < static_cast<INT_32>(m_noOfEntries)); 1478 // Only do this when tile mode table is updated. 1479 if (((tileMode == ADDR_TM_PRT_TILED_THIN1) || (tileMode == ADDR_TM_PRT_TILED_THICK)) && 1480 (m_tileTable[index + 1].mode == tileMode)) 1481 { 1482 static const UINT_32 PrtTileBytes = 0x10000; 1483 ADDR_TILEINFO tileInfo = {0}; 1484 1485 HwlComputeMacroModeIndex(index, flags, bpp, numSamples, &tileInfo); 1486 1487 UINT_32 macroTileBytes = (bpp >> 3) * 64 * numSamples * thickness * 1488 HwlGetPipes(&tileInfo) * tileInfo.banks * 1489 tileInfo.bankWidth * tileInfo.bankHeight; 1490 1491 if (macroTileBytes != PrtTileBytes) 1492 { 1493 // Switching to next tile mode entry to make sure macro tile size is 64KB 1494 index += 1; 1495 1496 tileInfo.pipeConfig = m_tileTable[index].info.pipeConfig; 1497 1498 macroTileBytes = (bpp >> 3) * 64 * numSamples * thickness * 1499 HwlGetPipes(&tileInfo) * tileInfo.banks * 1500 tileInfo.bankWidth * tileInfo.bankHeight; 1501 1502 ADDR_ASSERT(macroTileBytes == PrtTileBytes); 1503 1504 flags.tcCompatible = FALSE; 1505 pOut->dccUnsupport = TRUE; 1506 } 1507 } 1508 } 1509 } 1510 else 1511 { 1512 // A pre-filled tile info is ready 1513 index = pOut->tileIndex; 1514 macroModeIndex = pOut->macroModeIndex; 1515 1516 // pass tile type back for post tile index compute 1517 pOut->tileType = inTileType; 1518 1519 if (flags.depth || flags.stencil) 1520 { 1521 // tileSize = thickness * bpp * numSamples * 8 * 8 / 8 1522 UINT_32 tileSize = thickness * bpp * numSamples * 8; 1523 1524 // Turn off tc compatible if row_size is smaller than tile size (tile split occurs). 1525 if (m_rowSize < tileSize) 1526 { 1527 flags.tcCompatible = FALSE; 1528 } 1529 } 1530 1531 UINT_32 numPipes = GetPipePerSurf(pTileInfo->pipeConfig); 1532 1533 if (m_pipes != numPipes) 1534 { 1535 pOut->dccUnsupport = TRUE; 1536 } 1537 } 1538 1539 // We only need to set up tile info if there is a valid index but macroModeIndex is invalid 1540 if ((index != TileIndexInvalid) && (macroModeIndex == TileIndexInvalid)) 1541 { 1542 macroModeIndex = HwlComputeMacroModeIndex(index, flags, bpp, numSamples, pTileInfo); 1543 1544 // Copy to pOut->tileType/tileIndex/macroModeIndex 1545 pOut->tileIndex = index; 1546 pOut->tileType = m_tileTable[index].type; // Or inTileType, the samea 1547 pOut->macroModeIndex = macroModeIndex; 1548 } 1549 else if (tileMode == ADDR_TM_LINEAR_GENERAL) 1550 { 1551 pOut->tileIndex = TileIndexLinearGeneral; 1552 1553 // Copy linear-aligned entry?? 1554 *pTileInfo = m_tileTable[8].info; 1555 } 1556 else if (tileMode == ADDR_TM_LINEAR_ALIGNED) 1557 { 1558 pOut->tileIndex = 8; 1559 *pTileInfo = m_tileTable[8].info; 1560 } 1561 1562 if (flags.tcCompatible) 1563 { 1564 flags.tcCompatible = CheckTcCompatibility(pTileInfo, bpp, tileMode, inTileType, pOut); 1565 } 1566 1567 pOut->tcCompatible = flags.tcCompatible; 1568 } 1569 1570 /** 1571 **************************************************************************************************** 1572 * CiLib::ReadGbTileMode 1573 * 1574 * @brief 1575 * Convert GB_TILE_MODE HW value to ADDR_TILE_CONFIG. 1576 **************************************************************************************************** 1577 */ 1578 VOID CiLib::ReadGbTileMode( 1579 UINT_32 regValue, ///< [in] GB_TILE_MODE register 1580 TileConfig* pCfg ///< [out] output structure 1581 ) const 1582 { 1583 GB_TILE_MODE gbTileMode; 1584 gbTileMode.val = regValue; 1585 1586 pCfg->type = static_cast<AddrTileType>(gbTileMode.f.micro_tile_mode_new); 1587 pCfg->info.pipeConfig = static_cast<AddrPipeCfg>(gbTileMode.f.pipe_config + 1); 1588 1589 if (pCfg->type == ADDR_DEPTH_SAMPLE_ORDER) 1590 { 1591 pCfg->info.tileSplitBytes = 64 << gbTileMode.f.tile_split; 1592 } 1593 else 1594 { 1595 pCfg->info.tileSplitBytes = 1 << gbTileMode.f.sample_split; 1596 } 1597 1598 UINT_32 regArrayMode = gbTileMode.f.array_mode; 1599 1600 pCfg->mode = static_cast<AddrTileMode>(regArrayMode); 1601 1602 switch (regArrayMode) 1603 { 1604 case 5: 1605 pCfg->mode = ADDR_TM_PRT_TILED_THIN1; 1606 break; 1607 case 6: 1608 pCfg->mode = ADDR_TM_PRT_2D_TILED_THIN1; 1609 break; 1610 case 8: 1611 pCfg->mode = ADDR_TM_2D_TILED_XTHICK; 1612 break; 1613 case 9: 1614 pCfg->mode = ADDR_TM_PRT_TILED_THICK; 1615 break; 1616 case 0xa: 1617 pCfg->mode = ADDR_TM_PRT_2D_TILED_THICK; 1618 break; 1619 case 0xb: 1620 pCfg->mode = ADDR_TM_PRT_3D_TILED_THIN1; 1621 break; 1622 case 0xe: 1623 pCfg->mode = ADDR_TM_3D_TILED_XTHICK; 1624 break; 1625 case 0xf: 1626 pCfg->mode = ADDR_TM_PRT_3D_TILED_THICK; 1627 break; 1628 default: 1629 break; 1630 } 1631 1632 // Fail-safe code for these always convert tile info, as the non-macro modes 1633 // return the entry of tile mode table directly without looking up macro mode table 1634 if (!IsMacroTiled(pCfg->mode)) 1635 { 1636 pCfg->info.banks = 2; 1637 pCfg->info.bankWidth = 1; 1638 pCfg->info.bankHeight = 1; 1639 pCfg->info.macroAspectRatio = 1; 1640 pCfg->info.tileSplitBytes = 64; 1641 } 1642 } 1643 1644 /** 1645 **************************************************************************************************** 1646 * CiLib::InitTileSettingTable 1647 * 1648 * @brief 1649 * Initialize the ADDR_TILE_CONFIG table. 1650 * @return 1651 * TRUE if tile table is correctly initialized 1652 **************************************************************************************************** 1653 */ 1654 BOOL_32 CiLib::InitTileSettingTable( 1655 const UINT_32* pCfg, ///< [in] Pointer to table of tile configs 1656 UINT_32 noOfEntries ///< [in] Numbe of entries in the table above 1657 ) 1658 { 1659 BOOL_32 initOk = TRUE; 1660 1661 ADDR_ASSERT(noOfEntries <= TileTableSize); 1662 1663 memset(m_tileTable, 0, sizeof(m_tileTable)); 1664 1665 if (noOfEntries != 0) 1666 { 1667 m_noOfEntries = noOfEntries; 1668 } 1669 else 1670 { 1671 m_noOfEntries = TileTableSize; 1672 } 1673 1674 if (pCfg) // From Client 1675 { 1676 for (UINT_32 i = 0; i < m_noOfEntries; i++) 1677 { 1678 ReadGbTileMode(*(pCfg + i), &m_tileTable[i]); 1679 } 1680 } 1681 else 1682 { 1683 ADDR_ASSERT_ALWAYS(); 1684 initOk = FALSE; 1685 } 1686 1687 if (initOk) 1688 { 1689 ADDR_ASSERT(m_tileTable[TILEINDEX_LINEAR_ALIGNED].mode == ADDR_TM_LINEAR_ALIGNED); 1690 1691 if (m_settings.isBonaire == FALSE) 1692 { 1693 // Check if entry 18 is "thick+thin" combination 1694 if ((m_tileTable[18].mode == ADDR_TM_1D_TILED_THICK) && 1695 (m_tileTable[18].type == ADDR_NON_DISPLAYABLE)) 1696 { 1697 m_allowNonDispThickModes = TRUE; 1698 ADDR_ASSERT(m_tileTable[24].mode == ADDR_TM_2D_TILED_THICK); 1699 } 1700 } 1701 else 1702 { 1703 m_allowNonDispThickModes = TRUE; 1704 } 1705 1706 // Assume the first entry is always programmed with full pipes 1707 m_pipes = HwlGetPipes(&m_tileTable[0].info); 1708 } 1709 1710 return initOk; 1711 } 1712 1713 /** 1714 **************************************************************************************************** 1715 * CiLib::ReadGbMacroTileCfg 1716 * 1717 * @brief 1718 * Convert GB_MACRO_TILE_CFG HW value to ADDR_TILE_CONFIG. 1719 **************************************************************************************************** 1720 */ 1721 VOID CiLib::ReadGbMacroTileCfg( 1722 UINT_32 regValue, ///< [in] GB_MACRO_TILE_MODE register 1723 ADDR_TILEINFO* pCfg ///< [out] output structure 1724 ) const 1725 { 1726 GB_MACROTILE_MODE gbTileMode; 1727 gbTileMode.val = regValue; 1728 1729 pCfg->bankHeight = 1 << gbTileMode.f.bank_height; 1730 pCfg->bankWidth = 1 << gbTileMode.f.bank_width; 1731 pCfg->banks = 1 << (gbTileMode.f.num_banks + 1); 1732 pCfg->macroAspectRatio = 1 << gbTileMode.f.macro_tile_aspect; 1733 } 1734 1735 /** 1736 **************************************************************************************************** 1737 * CiLib::InitMacroTileCfgTable 1738 * 1739 * @brief 1740 * Initialize the ADDR_MACRO_TILE_CONFIG table. 1741 * @return 1742 * TRUE if macro tile table is correctly initialized 1743 **************************************************************************************************** 1744 */ 1745 BOOL_32 CiLib::InitMacroTileCfgTable( 1746 const UINT_32* pCfg, ///< [in] Pointer to table of tile configs 1747 UINT_32 noOfMacroEntries ///< [in] Numbe of entries in the table above 1748 ) 1749 { 1750 BOOL_32 initOk = TRUE; 1751 1752 ADDR_ASSERT(noOfMacroEntries <= MacroTileTableSize); 1753 1754 memset(m_macroTileTable, 0, sizeof(m_macroTileTable)); 1755 1756 if (noOfMacroEntries != 0) 1757 { 1758 m_noOfMacroEntries = noOfMacroEntries; 1759 } 1760 else 1761 { 1762 m_noOfMacroEntries = MacroTileTableSize; 1763 } 1764 1765 if (pCfg) // From Client 1766 { 1767 for (UINT_32 i = 0; i < m_noOfMacroEntries; i++) 1768 { 1769 ReadGbMacroTileCfg(*(pCfg + i), &m_macroTileTable[i]); 1770 1771 m_macroTileTable[i].tileSplitBytes = 64 << (i % 8); 1772 } 1773 } 1774 else 1775 { 1776 ADDR_ASSERT_ALWAYS(); 1777 initOk = FALSE; 1778 } 1779 return initOk; 1780 } 1781 1782 /** 1783 **************************************************************************************************** 1784 * CiLib::HwlComputeMacroModeIndex 1785 * 1786 * @brief 1787 * Computes macro tile mode index 1788 * @return 1789 * TRUE if macro tile table is correctly initialized 1790 **************************************************************************************************** 1791 */ 1792 INT_32 CiLib::HwlComputeMacroModeIndex( 1793 INT_32 tileIndex, ///< [in] Tile mode index 1794 ADDR_SURFACE_FLAGS flags, ///< [in] Surface flags 1795 UINT_32 bpp, ///< [in] Bit per pixel 1796 UINT_32 numSamples, ///< [in] Number of samples 1797 ADDR_TILEINFO* pTileInfo, ///< [out] Pointer to ADDR_TILEINFO 1798 AddrTileMode* pTileMode, ///< [out] Pointer to AddrTileMode 1799 AddrTileType* pTileType ///< [out] Pointer to AddrTileType 1800 ) const 1801 { 1802 INT_32 macroModeIndex = TileIndexInvalid; 1803 1804 AddrTileMode tileMode = m_tileTable[tileIndex].mode; 1805 AddrTileType tileType = m_tileTable[tileIndex].type; 1806 UINT_32 thickness = Thickness(tileMode); 1807 1808 if (!IsMacroTiled(tileMode)) 1809 { 1810 *pTileInfo = m_tileTable[tileIndex].info; 1811 macroModeIndex = TileIndexNoMacroIndex; 1812 } 1813 else 1814 { 1815 UINT_32 tileBytes1x = BITS_TO_BYTES(bpp * MicroTilePixels * thickness); 1816 UINT_32 tileSplit; 1817 1818 if (m_tileTable[tileIndex].type == ADDR_DEPTH_SAMPLE_ORDER) 1819 { 1820 // Depth entries store real tileSplitBytes 1821 tileSplit = m_tileTable[tileIndex].info.tileSplitBytes; 1822 } 1823 else 1824 { 1825 // Non-depth entries store a split factor 1826 UINT_32 sampleSplit = m_tileTable[tileIndex].info.tileSplitBytes; 1827 UINT_32 colorTileSplit = Max(256u, sampleSplit * tileBytes1x); 1828 1829 tileSplit = colorTileSplit; 1830 } 1831 1832 UINT_32 tileSplitC = Min(m_rowSize, tileSplit); 1833 UINT_32 tileBytes; 1834 1835 if (flags.fmask) 1836 { 1837 tileBytes = Min(tileSplitC, tileBytes1x); 1838 } 1839 else 1840 { 1841 tileBytes = Min(tileSplitC, numSamples * tileBytes1x); 1842 } 1843 1844 if (tileBytes < 64) 1845 { 1846 tileBytes = 64; 1847 } 1848 1849 macroModeIndex = Log2(tileBytes / 64); 1850 1851 if (flags.prt || IsPrtTileMode(tileMode)) 1852 { 1853 macroModeIndex += PrtMacroModeOffset; 1854 *pTileInfo = m_macroTileTable[macroModeIndex]; 1855 } 1856 else 1857 { 1858 *pTileInfo = m_macroTileTable[macroModeIndex]; 1859 } 1860 1861 pTileInfo->pipeConfig = m_tileTable[tileIndex].info.pipeConfig; 1862 1863 pTileInfo->tileSplitBytes = tileSplitC; 1864 } 1865 1866 if (NULL != pTileMode) 1867 { 1868 *pTileMode = tileMode; 1869 } 1870 1871 if (NULL != pTileType) 1872 { 1873 *pTileType = tileType; 1874 } 1875 1876 return macroModeIndex; 1877 } 1878 1879 /** 1880 **************************************************************************************************** 1881 * CiLib::HwlComputeTileDataWidthAndHeightLinear 1882 * 1883 * @brief 1884 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout 1885 * 1886 * @note 1887 * MacroWidth and macroHeight are measured in pixels 1888 **************************************************************************************************** 1889 */ 1890 VOID CiLib::HwlComputeTileDataWidthAndHeightLinear( 1891 UINT_32* pMacroWidth, ///< [out] macro tile width 1892 UINT_32* pMacroHeight, ///< [out] macro tile height 1893 UINT_32 bpp, ///< [in] bits per pixel 1894 ADDR_TILEINFO* pTileInfo ///< [in] tile info 1895 ) const 1896 { 1897 ADDR_ASSERT(pTileInfo != NULL); 1898 1899 UINT_32 numTiles; 1900 1901 switch (pTileInfo->pipeConfig) 1902 { 1903 case ADDR_PIPECFG_P16_32x32_8x16: 1904 case ADDR_PIPECFG_P16_32x32_16x16: 1905 case ADDR_PIPECFG_P8_32x64_32x32: 1906 case ADDR_PIPECFG_P8_32x32_16x32: 1907 case ADDR_PIPECFG_P8_32x32_16x16: 1908 case ADDR_PIPECFG_P8_32x32_8x16: 1909 case ADDR_PIPECFG_P4_32x32: 1910 numTiles = 8; 1911 break; 1912 default: 1913 numTiles = 4; 1914 break; 1915 } 1916 1917 *pMacroWidth = numTiles * MicroTileWidth; 1918 *pMacroHeight = numTiles * MicroTileHeight; 1919 } 1920 1921 /** 1922 **************************************************************************************************** 1923 * CiLib::HwlComputeMetadataNibbleAddress 1924 * 1925 * @brief 1926 * calculate meta data address based on input information 1927 * 1928 * ¶meter 1929 * uncompressedDataByteAddress - address of a pixel in color surface 1930 * dataBaseByteAddress - base address of color surface 1931 * metadataBaseByteAddress - base address of meta ram 1932 * metadataBitSize - meta key size, 8 for DCC, 4 for cmask 1933 * elementBitSize - element size of color surface 1934 * blockByteSize - compression block size, 256 for DCC 1935 * pipeInterleaveBytes - pipe interleave size 1936 * numOfPipes - number of pipes 1937 * numOfBanks - number of banks 1938 * numOfSamplesPerSplit - number of samples per tile split 1939 * @return 1940 * meta data nibble address (nibble address is used to support DCC compatible cmask) 1941 * 1942 **************************************************************************************************** 1943 */ 1944 UINT_64 CiLib::HwlComputeMetadataNibbleAddress( 1945 UINT_64 uncompressedDataByteAddress, 1946 UINT_64 dataBaseByteAddress, 1947 UINT_64 metadataBaseByteAddress, 1948 UINT_32 metadataBitSize, 1949 UINT_32 elementBitSize, 1950 UINT_32 blockByteSize, 1951 UINT_32 pipeInterleaveBytes, 1952 UINT_32 numOfPipes, 1953 UINT_32 numOfBanks, 1954 UINT_32 numOfSamplesPerSplit) const 1955 { 1956 ///-------------------------------------------------------------------------------------------- 1957 /// Get pipe interleave, bank and pipe bits 1958 ///-------------------------------------------------------------------------------------------- 1959 UINT_32 pipeInterleaveBits = Log2(pipeInterleaveBytes); 1960 UINT_32 pipeBits = Log2(numOfPipes); 1961 UINT_32 bankBits = Log2(numOfBanks); 1962 1963 ///-------------------------------------------------------------------------------------------- 1964 /// Clear pipe and bank swizzles 1965 ///-------------------------------------------------------------------------------------------- 1966 UINT_32 dataMacrotileBits = pipeInterleaveBits + pipeBits + bankBits; 1967 UINT_32 metadataMacrotileBits = pipeInterleaveBits + pipeBits + bankBits; 1968 1969 UINT_64 dataMacrotileClearMask = ~((1L << dataMacrotileBits) - 1); 1970 UINT_64 metadataMacrotileClearMask = ~((1L << metadataMacrotileBits) - 1); 1971 1972 UINT_64 dataBaseByteAddressNoSwizzle = dataBaseByteAddress & dataMacrotileClearMask; 1973 UINT_64 metadataBaseByteAddressNoSwizzle = metadataBaseByteAddress & metadataMacrotileClearMask; 1974 1975 ///-------------------------------------------------------------------------------------------- 1976 /// Modify metadata base before adding in so that when final address is divided by data ratio, 1977 /// the base address returns to where it should be 1978 ///-------------------------------------------------------------------------------------------- 1979 ADDR_ASSERT((0 != metadataBitSize)); 1980 UINT_64 metadataBaseShifted = metadataBaseByteAddressNoSwizzle * blockByteSize * 8 / 1981 metadataBitSize; 1982 UINT_64 offset = uncompressedDataByteAddress - 1983 dataBaseByteAddressNoSwizzle + 1984 metadataBaseShifted; 1985 1986 ///-------------------------------------------------------------------------------------------- 1987 /// Save bank data bits 1988 ///-------------------------------------------------------------------------------------------- 1989 UINT_32 lsb = pipeBits + pipeInterleaveBits; 1990 UINT_32 msb = bankBits - 1 + lsb; 1991 1992 UINT_64 bankDataBits = GetBits(offset, msb, lsb); 1993 1994 ///-------------------------------------------------------------------------------------------- 1995 /// Save pipe data bits 1996 ///-------------------------------------------------------------------------------------------- 1997 lsb = pipeInterleaveBits; 1998 msb = pipeBits - 1 + lsb; 1999 2000 UINT_64 pipeDataBits = GetBits(offset, msb, lsb); 2001 2002 ///-------------------------------------------------------------------------------------------- 2003 /// Remove pipe and bank bits 2004 ///-------------------------------------------------------------------------------------------- 2005 lsb = pipeInterleaveBits; 2006 msb = dataMacrotileBits - 1; 2007 2008 UINT_64 offsetWithoutPipeBankBits = RemoveBits(offset, msb, lsb); 2009 2010 ADDR_ASSERT((0 != blockByteSize)); 2011 UINT_64 blockInBankpipe = offsetWithoutPipeBankBits / blockByteSize; 2012 2013 UINT_32 tileSize = 8 * 8 * elementBitSize/8 * numOfSamplesPerSplit; 2014 UINT_32 blocksInTile = tileSize / blockByteSize; 2015 2016 if (0 == blocksInTile) 2017 { 2018 lsb = 0; 2019 } 2020 else 2021 { 2022 lsb = Log2(blocksInTile); 2023 } 2024 msb = bankBits - 1 + lsb; 2025 2026 UINT_64 blockInBankpipeWithBankBits = InsertBits(blockInBankpipe, bankDataBits, msb, lsb); 2027 2028 /// NOTE *2 because we are converting to Nibble address in this step 2029 UINT_64 metaAddressInPipe = blockInBankpipeWithBankBits * 2 * metadataBitSize / 8; 2030 2031 2032 ///-------------------------------------------------------------------------------------------- 2033 /// Reinsert pipe bits back into the final address 2034 ///-------------------------------------------------------------------------------------------- 2035 lsb = pipeInterleaveBits + 1; ///<+1 due to Nibble address now gives interleave bits extra lsb. 2036 msb = pipeBits - 1 + lsb; 2037 UINT_64 metadataAddress = InsertBits(metaAddressInPipe, pipeDataBits, msb, lsb); 2038 2039 return metadataAddress; 2040 } 2041 2042 /** 2043 **************************************************************************************************** 2044 * CiLib::HwlComputeSurfaceAlignmentsMacroTiled 2045 * 2046 * @brief 2047 * Hardware layer function to compute alignment request for macro tile mode 2048 * 2049 **************************************************************************************************** 2050 */ 2051 VOID CiLib::HwlComputeSurfaceAlignmentsMacroTiled( 2052 AddrTileMode tileMode, ///< [in] tile mode 2053 UINT_32 bpp, ///< [in] bits per pixel 2054 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags 2055 UINT_32 mipLevel, ///< [in] mip level 2056 UINT_32 numSamples, ///< [in] number of samples 2057 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in,out] Surface output 2058 ) const 2059 { 2060 // This is to workaround a H/W limitation that DCC doesn't work when pipe config is switched to 2061 // P4. In theory, all asics that have such switching should be patched but we now only know what 2062 // to pad for Fiji. 2063 if ((m_settings.isFiji == TRUE) && 2064 (flags.dccPipeWorkaround == TRUE) && 2065 (flags.prt == FALSE) && 2066 (mipLevel == 0) && 2067 (tileMode == ADDR_TM_PRT_TILED_THIN1) && 2068 (pOut->dccUnsupport == TRUE)) 2069 { 2070 pOut->pitchAlign = PowTwoAlign(pOut->pitchAlign, 256); 2071 // In case the client still requests DCC usage. 2072 pOut->dccUnsupport = FALSE; 2073 } 2074 } 2075 2076 /** 2077 **************************************************************************************************** 2078 * CiLib::HwlPadDimensions 2079 * 2080 * @brief 2081 * Helper function to pad dimensions 2082 * 2083 **************************************************************************************************** 2084 */ 2085 VOID CiLib::HwlPadDimensions( 2086 AddrTileMode tileMode, ///< [in] tile mode 2087 UINT_32 bpp, ///< [in] bits per pixel 2088 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags 2089 UINT_32 numSamples, ///< [in] number of samples 2090 ADDR_TILEINFO* pTileInfo, ///< [in] tile info 2091 UINT_32 mipLevel, ///< [in] mip level 2092 UINT_32* pPitch, ///< [in,out] pitch in pixels 2093 UINT_32* pPitchAlign, ///< [in,out] pitch alignment 2094 UINT_32 height, ///< [in] height in pixels 2095 UINT_32 heightAlign ///< [in] height alignment 2096 ) const 2097 { 2098 if ((m_settings.isVolcanicIslands == TRUE) && 2099 (flags.dccCompatible == TRUE) && 2100 (numSamples > 1) && 2101 (mipLevel == 0) && 2102 (IsMacroTiled(tileMode) == TRUE)) 2103 { 2104 UINT_32 tileSizePerSample = BITS_TO_BYTES(bpp * MicroTileWidth * MicroTileHeight); 2105 UINT_32 samplesPerSplit = pTileInfo->tileSplitBytes / tileSizePerSample; 2106 2107 if (samplesPerSplit < numSamples) 2108 { 2109 UINT_32 dccFastClearByteAlign = HwlGetPipes(pTileInfo) * m_pipeInterleaveBytes * 256; 2110 UINT_32 bytesPerSplit = BITS_TO_BYTES((*pPitch) * height * bpp * samplesPerSplit); 2111 2112 ADDR_ASSERT(IsPow2(dccFastClearByteAlign)); 2113 2114 if (0 != (bytesPerSplit & (dccFastClearByteAlign - 1))) 2115 { 2116 UINT_32 dccFastClearPixelAlign = dccFastClearByteAlign / 2117 BITS_TO_BYTES(bpp) / 2118 samplesPerSplit; 2119 UINT_32 macroTilePixelAlign = (*pPitchAlign) * heightAlign; 2120 2121 if ((dccFastClearPixelAlign >= macroTilePixelAlign) && 2122 ((dccFastClearPixelAlign % macroTilePixelAlign) == 0)) 2123 { 2124 UINT_32 dccFastClearPitchAlignInMacroTile = 2125 dccFastClearPixelAlign / macroTilePixelAlign; 2126 UINT_32 heightInMacroTile = height / heightAlign; 2127 2128 while ((heightInMacroTile > 1) && 2129 ((heightInMacroTile % 2) == 0) && 2130 (dccFastClearPitchAlignInMacroTile > 1) && 2131 ((dccFastClearPitchAlignInMacroTile % 2) == 0)) 2132 { 2133 heightInMacroTile >>= 1; 2134 dccFastClearPitchAlignInMacroTile >>= 1; 2135 } 2136 2137 UINT_32 dccFastClearPitchAlignInPixels = 2138 (*pPitchAlign) * dccFastClearPitchAlignInMacroTile; 2139 2140 if (IsPow2(dccFastClearPitchAlignInPixels)) 2141 { 2142 *pPitch = PowTwoAlign((*pPitch), dccFastClearPitchAlignInPixels); 2143 } 2144 else 2145 { 2146 *pPitch += (dccFastClearPitchAlignInPixels - 1); 2147 *pPitch /= dccFastClearPitchAlignInPixels; 2148 *pPitch *= dccFastClearPitchAlignInPixels; 2149 } 2150 2151 *pPitchAlign = dccFastClearPitchAlignInPixels; 2152 } 2153 } 2154 } 2155 } 2156 } 2157 2158 /** 2159 **************************************************************************************************** 2160 * CiLib::HwlGetMaxAlignments 2161 * 2162 * @brief 2163 * Gets maximum alignments 2164 * @return 2165 * ADDR_E_RETURNCODE 2166 **************************************************************************************************** 2167 */ 2168 ADDR_E_RETURNCODE CiLib::HwlGetMaxAlignments( 2169 ADDR_GET_MAX_ALIGNMENTS_OUTPUT* pOut ///< [out] output structure 2170 ) const 2171 { 2172 const UINT_32 pipes = HwlGetPipes(&m_tileTable[0].info); 2173 2174 // Initial size is 64 KiB for PRT. 2175 UINT_64 maxBaseAlign = 64 * 1024; 2176 2177 for (UINT_32 i = 0; i < m_noOfMacroEntries; i++) 2178 { 2179 // The maximum tile size is 16 byte-per-pixel and either 8-sample or 8-slice. 2180 UINT_32 tileSize = m_macroTileTable[i].tileSplitBytes; 2181 2182 UINT_64 baseAlign = tileSize * pipes * m_macroTileTable[i].banks * 2183 m_macroTileTable[i].bankWidth * m_macroTileTable[i].bankHeight; 2184 2185 if (baseAlign > maxBaseAlign) 2186 { 2187 maxBaseAlign = baseAlign; 2188 } 2189 } 2190 2191 if (pOut != NULL) 2192 { 2193 pOut->baseAlign = maxBaseAlign; 2194 } 2195 2196 return ADDR_OK; 2197 } 2198 2199 /** 2200 **************************************************************************************************** 2201 * CiLib::DepthStencilTileCfgMatch 2202 * 2203 * @brief 2204 * Try to find a tile index for stencil which makes its tile config parameters matches to depth 2205 * @return 2206 * TRUE if such tile index for stencil can be found 2207 **************************************************************************************************** 2208 */ 2209 BOOL_32 CiLib::DepthStencilTileCfgMatch( 2210 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure 2211 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure 2212 ) const 2213 { 2214 BOOL_32 depthStencil2DTileConfigMatch = FALSE; 2215 2216 for (INT_32 stencilTileIndex = MinDepth2DThinIndex; 2217 stencilTileIndex <= MaxDepth2DThinIndex; 2218 stencilTileIndex++) 2219 { 2220 ADDR_TILEINFO tileInfo = {0}; 2221 INT_32 stencilMacroIndex = HwlComputeMacroModeIndex(stencilTileIndex, 2222 pIn->flags, 2223 8, 2224 pIn->numSamples, 2225 &tileInfo); 2226 2227 if (stencilMacroIndex != TileIndexNoMacroIndex) 2228 { 2229 if ((m_macroTileTable[stencilMacroIndex].banks == 2230 m_macroTileTable[pOut->macroModeIndex].banks) && 2231 (m_macroTileTable[stencilMacroIndex].bankWidth == 2232 m_macroTileTable[pOut->macroModeIndex].bankWidth) && 2233 (m_macroTileTable[stencilMacroIndex].bankHeight == 2234 m_macroTileTable[pOut->macroModeIndex].bankHeight) && 2235 (m_macroTileTable[stencilMacroIndex].macroAspectRatio == 2236 m_macroTileTable[pOut->macroModeIndex].macroAspectRatio) && 2237 (m_macroTileTable[stencilMacroIndex].pipeConfig == 2238 m_macroTileTable[pOut->macroModeIndex].pipeConfig)) 2239 { 2240 if ((pOut->tcCompatible == FALSE) || 2241 (tileInfo.tileSplitBytes >= MicroTileWidth * MicroTileHeight * pIn->numSamples)) 2242 { 2243 depthStencil2DTileConfigMatch = TRUE; 2244 pOut->stencilTileIdx = stencilTileIndex; 2245 break; 2246 } 2247 } 2248 } 2249 else 2250 { 2251 ADDR_ASSERT_ALWAYS(); 2252 } 2253 } 2254 2255 return depthStencil2DTileConfigMatch; 2256 } 2257 2258 /** 2259 **************************************************************************************************** 2260 * CiLib::DepthStencilTileCfgMatch 2261 * 2262 * @brief 2263 * Check if tc compatibility is available 2264 * @return 2265 * If tc compatibility is not available 2266 **************************************************************************************************** 2267 */ 2268 BOOL_32 CiLib::CheckTcCompatibility( 2269 const ADDR_TILEINFO* pTileInfo, ///< [in] input tile info 2270 UINT_32 bpp, ///< [in] Bits per pixel 2271 AddrTileMode tileMode, ///< [in] input tile mode 2272 AddrTileType tileType, ///< [in] input tile type 2273 const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in] output surf info 2274 ) const 2275 { 2276 BOOL_32 tcCompatible = TRUE; 2277 2278 if (IsMacroTiled(tileMode)) 2279 { 2280 if (tileType != ADDR_DEPTH_SAMPLE_ORDER) 2281 { 2282 // Turn off tcCompatible for color surface if tileSplit happens. Depth/stencil 2283 // tileSplit case was handled at tileIndex selecting time. 2284 INT_32 tileIndex = pOut->tileIndex; 2285 2286 if ((tileIndex == TileIndexInvalid) && (IsTileInfoAllZero(pTileInfo) == FALSE)) 2287 { 2288 tileIndex = HwlPostCheckTileIndex(pTileInfo, tileMode, tileType, tileIndex); 2289 } 2290 2291 if (tileIndex != TileIndexInvalid) 2292 { 2293 UINT_32 thickness = Thickness(tileMode); 2294 2295 ADDR_ASSERT(static_cast<UINT_32>(tileIndex) < TileTableSize); 2296 // Non-depth entries store a split factor 2297 UINT_32 sampleSplit = m_tileTable[tileIndex].info.tileSplitBytes; 2298 UINT_32 tileBytes1x = BITS_TO_BYTES(bpp * MicroTilePixels * thickness); 2299 UINT_32 colorTileSplit = Max(256u, sampleSplit * tileBytes1x); 2300 2301 if (m_rowSize < colorTileSplit) 2302 { 2303 tcCompatible = FALSE; 2304 } 2305 } 2306 } 2307 } 2308 else 2309 { 2310 // Client should not enable tc compatible for linear and 1D tile modes. 2311 tcCompatible = FALSE; 2312 } 2313 2314 return tcCompatible; 2315 } 2316 2317 } // V1 2318 } // Addr 2319