Home | History | Annotate | Download | only in r800
      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 *   &parameter
   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