"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/amd/addrlib/src/r800/ciaddrlib.cpp" (16 Sep 2020, 79309 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ciaddrlib.cpp" see the Fossies "Dox" file reference documentation.

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