Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright  2014 Advanced Micro Devices, Inc.
      3  * All Rights Reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sub license, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     14  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
     15  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     16  * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
     17  * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     20  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     21  *
     22  * The above copyright notice and this permission notice (including the
     23  * next paragraph) shall be included in all copies or substantial portions
     24  * of the Software.
     25  */
     26 
     27 /**
     28 ***************************************************************************************************
     29 * @file  addrlib.cpp
     30 * @brief Contains the implementation for the AddrLib base class..
     31 ***************************************************************************************************
     32 */
     33 
     34 #include "addrinterface.h"
     35 #include "addrlib.h"
     36 #include "addrcommon.h"
     37 
     38 #if defined(__APPLE__)
     39 
     40 UINT_32 div64_32(UINT_64 n, UINT_32 base)
     41 {
     42     UINT_64 rem = n;
     43     UINT_64 b = base;
     44     UINT_64 res, d = 1;
     45     UINT_32 high = rem >> 32;
     46 
     47     res = 0;
     48     if (high >= base)
     49     {
     50         high /= base;
     51         res = (UINT_64) high << 32;
     52         rem -= (UINT_64) (high*base) << 32;
     53     }
     54 
     55     while ((INT_64)b > 0 && b < rem)
     56     {
     57         b = b+b;
     58         d = d+d;
     59     }
     60 
     61     do
     62     {
     63         if (rem >= b)
     64         {
     65             rem -= b;
     66             res += d;
     67         }
     68         b >>= 1;
     69         d >>= 1;
     70     } while (d);
     71 
     72     n = res;
     73     return rem;
     74 }
     75 
     76 extern "C"
     77 UINT_32 __umoddi3(UINT_64 n, UINT_32 base)
     78 {
     79     return div64_32(n, base);
     80 }
     81 
     82 #endif // __APPLE__
     83 
     84 ///////////////////////////////////////////////////////////////////////////////////////////////////
     85 //                               Static Const Member
     86 ///////////////////////////////////////////////////////////////////////////////////////////////////
     87 
     88 const AddrTileModeFlags AddrLib::m_modeFlags[ADDR_TM_COUNT] =
     89 {// T   L  1  2  3  P  Pr B
     90     {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_GENERAL
     91     {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_ALIGNED
     92     {1, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THIN1
     93     {4, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THICK
     94     {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN1
     95     {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN2
     96     {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN4
     97     {4, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THICK
     98     {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN1
     99     {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN2
    100     {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN4
    101     {4, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THICK
    102     {1, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THIN1
    103     {4, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THICK
    104     {1, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THIN1
    105     {4, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THICK
    106     {8, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_XTHICK
    107     {8, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_XTHICK
    108     {1, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_POWER_SAVE
    109     {1, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THIN1
    110     {1, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THIN1
    111     {1, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THIN1
    112     {4, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THICK
    113     {4, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THICK
    114     {4, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THICK
    115 };
    116 
    117 ///////////////////////////////////////////////////////////////////////////////////////////////////
    118 //                               Constructor/Destructor
    119 ///////////////////////////////////////////////////////////////////////////////////////////////////
    120 
    121 /**
    122 ***************************************************************************************************
    123 *   AddrLib::AddrLib
    124 *
    125 *   @brief
    126 *       Constructor for the AddrLib class
    127 *
    128 ***************************************************************************************************
    129 */
    130 AddrLib::AddrLib() :
    131     m_class(BASE_ADDRLIB),
    132     m_chipFamily(ADDR_CHIP_FAMILY_IVLD),
    133     m_chipRevision(0),
    134     m_version(ADDRLIB_VERSION),
    135     m_pipes(0),
    136     m_banks(0),
    137     m_pipeInterleaveBytes(0),
    138     m_rowSize(0),
    139     m_minPitchAlignPixels(1),
    140     m_maxSamples(8),
    141     m_pElemLib(NULL)
    142 {
    143     m_configFlags.value = 0;
    144 }
    145 
    146 /**
    147 ***************************************************************************************************
    148 *   AddrLib::AddrLib
    149 *
    150 *   @brief
    151 *       Constructor for the AddrLib class with hClient as parameter
    152 *
    153 ***************************************************************************************************
    154 */
    155 AddrLib::AddrLib(const AddrClient* pClient) :
    156     AddrObject(pClient),
    157     m_class(BASE_ADDRLIB),
    158     m_chipFamily(ADDR_CHIP_FAMILY_IVLD),
    159     m_chipRevision(0),
    160     m_version(ADDRLIB_VERSION),
    161     m_pipes(0),
    162     m_banks(0),
    163     m_pipeInterleaveBytes(0),
    164     m_rowSize(0),
    165     m_minPitchAlignPixels(1),
    166     m_maxSamples(8),
    167     m_pElemLib(NULL)
    168 {
    169     m_configFlags.value = 0;
    170 }
    171 
    172 /**
    173 ***************************************************************************************************
    174 *   AddrLib::~AddrLib
    175 *
    176 *   @brief
    177 *       Destructor for the AddrLib class
    178 *
    179 ***************************************************************************************************
    180 */
    181 AddrLib::~AddrLib()
    182 {
    183     if (m_pElemLib)
    184     {
    185         delete m_pElemLib;
    186     }
    187 }
    188 
    189 
    190 
    191 ///////////////////////////////////////////////////////////////////////////////////////////////////
    192 //                               Initialization/Helper
    193 ///////////////////////////////////////////////////////////////////////////////////////////////////
    194 
    195 /**
    196 ***************************************************************************************************
    197 *   AddrLib::Create
    198 *
    199 *   @brief
    200 *       Creates and initializes AddrLib object.
    201 *
    202 *   @return
    203 *       ADDR_E_RETURNCODE
    204 ***************************************************************************************************
    205 */
    206 ADDR_E_RETURNCODE AddrLib::Create(
    207     const ADDR_CREATE_INPUT* pCreateIn,     ///< [in] pointer to ADDR_CREATE_INPUT
    208     ADDR_CREATE_OUTPUT*      pCreateOut)    ///< [out] pointer to ADDR_CREATE_OUTPUT
    209 {
    210     AddrLib* pLib = NULL;
    211     ADDR_E_RETURNCODE returnCode = ADDR_OK;
    212 
    213     if (pCreateIn->createFlags.fillSizeFields == TRUE)
    214     {
    215         if ((pCreateIn->size != sizeof(ADDR_CREATE_INPUT)) ||
    216             (pCreateOut->size != sizeof(ADDR_CREATE_OUTPUT)))
    217         {
    218             returnCode = ADDR_PARAMSIZEMISMATCH;
    219         }
    220     }
    221 
    222     if ((returnCode == ADDR_OK)                    &&
    223         (pCreateIn->callbacks.allocSysMem != NULL) &&
    224         (pCreateIn->callbacks.freeSysMem != NULL))
    225     {
    226         AddrClient client = {
    227             pCreateIn->hClient,
    228             pCreateIn->callbacks
    229         };
    230 
    231         switch (pCreateIn->chipEngine)
    232         {
    233             case CIASICIDGFXENGINE_SOUTHERNISLAND:
    234                 switch (pCreateIn->chipFamily)
    235                 {
    236                     case FAMILY_SI:
    237                         pLib = AddrSIHwlInit(&client);
    238                         break;
    239                     case FAMILY_VI:
    240                     case FAMILY_CZ: // VI based fusion(carrizo)
    241                     case FAMILY_CI:
    242                     case FAMILY_KV: // CI based fusion
    243                         pLib = AddrCIHwlInit(&client);
    244                         break;
    245                     default:
    246                         ADDR_ASSERT_ALWAYS();
    247                         break;
    248                 }
    249                 break;
    250             default:
    251                 ADDR_ASSERT_ALWAYS();
    252                 break;
    253         }
    254     }
    255 
    256     if ((pLib != NULL))
    257     {
    258         BOOL_32 initValid;
    259 
    260         // Pass createFlags to configFlags first since these flags may be overwritten
    261         pLib->m_configFlags.noCubeMipSlicesPad  = pCreateIn->createFlags.noCubeMipSlicesPad;
    262         pLib->m_configFlags.fillSizeFields      = pCreateIn->createFlags.fillSizeFields;
    263         pLib->m_configFlags.useTileIndex        = pCreateIn->createFlags.useTileIndex;
    264         pLib->m_configFlags.useCombinedSwizzle  = pCreateIn->createFlags.useCombinedSwizzle;
    265         pLib->m_configFlags.checkLast2DLevel    = pCreateIn->createFlags.checkLast2DLevel;
    266         pLib->m_configFlags.useHtileSliceAlign  = pCreateIn->createFlags.useHtileSliceAlign;
    267         pLib->m_configFlags.degradeBaseLevel    = pCreateIn->createFlags.degradeBaseLevel;
    268         pLib->m_configFlags.allowLargeThickTile = pCreateIn->createFlags.allowLargeThickTile;
    269 
    270         pLib->SetAddrChipFamily(pCreateIn->chipFamily, pCreateIn->chipRevision);
    271 
    272         pLib->SetMinPitchAlignPixels(pCreateIn->minPitchAlignPixels);
    273 
    274         // Global parameters initialized and remaining configFlags bits are set as well
    275         initValid = pLib->HwlInitGlobalParams(pCreateIn);
    276 
    277         if (initValid)
    278         {
    279             pLib->m_pElemLib = AddrElemLib::Create(pLib);
    280         }
    281         else
    282         {
    283             pLib->m_pElemLib = NULL; // Don't go on allocating element lib
    284             returnCode = ADDR_INVALIDGBREGVALUES;
    285         }
    286 
    287         if (pLib->m_pElemLib == NULL)
    288         {
    289             delete pLib;
    290             pLib = NULL;
    291             ADDR_ASSERT_ALWAYS();
    292         }
    293         else
    294         {
    295             pLib->m_pElemLib->SetConfigFlags(pLib->m_configFlags);
    296         }
    297     }
    298 
    299     pCreateOut->hLib = pLib;
    300 
    301     if ((pLib == NULL) &&
    302         (returnCode == ADDR_OK))
    303     {
    304         // Unknown failures, we return the general error code
    305         returnCode = ADDR_ERROR;
    306     }
    307 
    308     return returnCode;
    309 }
    310 
    311 /**
    312 ***************************************************************************************************
    313 *   AddrLib::SetAddrChipFamily
    314 *
    315 *   @brief
    316 *       Convert familyID defined in atiid.h to AddrChipFamily and set m_chipFamily/m_chipRevision
    317 *   @return
    318 *      N/A
    319 ***************************************************************************************************
    320 */
    321 VOID AddrLib::SetAddrChipFamily(
    322     UINT_32 uChipFamily,        ///< [in] chip family defined in atiih.h
    323     UINT_32 uChipRevision)      ///< [in] chip revision defined in "asic_family"_id.h
    324 {
    325     AddrChipFamily family = ADDR_CHIP_FAMILY_IVLD;
    326 
    327     family = HwlConvertChipFamily(uChipFamily, uChipRevision);
    328 
    329     ADDR_ASSERT(family != ADDR_CHIP_FAMILY_IVLD);
    330 
    331     m_chipFamily    = family;
    332     m_chipRevision  = uChipRevision;
    333 }
    334 
    335 /**
    336 ***************************************************************************************************
    337 *   AddrLib::SetMinPitchAlignPixels
    338 *
    339 *   @brief
    340 *       Set m_minPitchAlignPixels with input param
    341 *
    342 *   @return
    343 *      N/A
    344 ***************************************************************************************************
    345 */
    346 VOID AddrLib::SetMinPitchAlignPixels(
    347     UINT_32 minPitchAlignPixels)    ///< [in] minmum pitch alignment in pixels
    348 {
    349     m_minPitchAlignPixels = (minPitchAlignPixels == 0)? 1 : minPitchAlignPixels;
    350 }
    351 
    352 /**
    353 ***************************************************************************************************
    354 *   AddrLib::GetAddrLib
    355 *
    356 *   @brief
    357 *       Get AddrLib pointer
    358 *
    359 *   @return
    360 *      An AddrLib class pointer
    361 ***************************************************************************************************
    362 */
    363 AddrLib * AddrLib::GetAddrLib(
    364     ADDR_HANDLE hLib)   ///< [in] handle of ADDR_HANDLE
    365 {
    366     return static_cast<AddrLib *>(hLib);
    367 }
    368 
    369 
    370 
    371 ///////////////////////////////////////////////////////////////////////////////////////////////////
    372 //                               Surface Methods
    373 ///////////////////////////////////////////////////////////////////////////////////////////////////
    374 
    375 
    376 /**
    377 ***************************************************************************************************
    378 *   AddrLib::ComputeSurfaceInfo
    379 *
    380 *   @brief
    381 *       Interface function stub of AddrComputeSurfaceInfo.
    382 *
    383 *   @return
    384 *       ADDR_E_RETURNCODE
    385 ***************************************************************************************************
    386 */
    387 ADDR_E_RETURNCODE AddrLib::ComputeSurfaceInfo(
    388      const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
    389      ADDR_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure
    390      ) const
    391 {
    392     ADDR_E_RETURNCODE returnCode = ADDR_OK;
    393 
    394     if (GetFillSizeFieldsFlags() == TRUE)
    395     {
    396         if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT)) ||
    397             (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT)))
    398         {
    399             returnCode = ADDR_PARAMSIZEMISMATCH;
    400         }
    401     }
    402 
    403     // We suggest client do sanity check but a check here is also good
    404     if (pIn->bpp > 128)
    405     {
    406         returnCode = ADDR_INVALIDPARAMS;
    407     }
    408 
    409     // Thick modes don't support multisample
    410     if (ComputeSurfaceThickness(pIn->tileMode) > 1 && pIn->numSamples > 1)
    411     {
    412         returnCode = ADDR_INVALIDPARAMS;
    413     }
    414 
    415     if (returnCode == ADDR_OK)
    416     {
    417         // Get a local copy of input structure and only reference pIn for unadjusted values
    418         ADDR_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;
    419         ADDR_TILEINFO tileInfoNull = {0};
    420 
    421         if (UseTileInfo())
    422         {
    423             // If the original input has a valid ADDR_TILEINFO pointer then copy its contents.
    424             // Otherwise the default 0's in tileInfoNull are used.
    425             if (pIn->pTileInfo)
    426             {
    427                 tileInfoNull = *pIn->pTileInfo;
    428             }
    429             localIn.pTileInfo  = &tileInfoNull;
    430         }
    431 
    432         localIn.numSamples = pIn->numSamples == 0 ? 1 : pIn->numSamples;
    433 
    434         // Do mipmap check first
    435         // If format is BCn, pre-pad dimension to power-of-two according to HWL
    436         ComputeMipLevel(&localIn);
    437 
    438         if (m_configFlags.checkLast2DLevel)
    439         {
    440             // Save this level's original height in pixels
    441             pOut->height = pIn->height;
    442         }
    443 
    444         UINT_32 expandX = 1;
    445         UINT_32 expandY = 1;
    446         AddrElemMode elemMode;
    447 
    448         // Save outputs that may not go through HWL
    449         pOut->pixelBits = localIn.bpp;
    450         pOut->numSamples = localIn.numSamples;
    451         pOut->last2DLevel = FALSE;
    452 
    453 #if !ALT_TEST
    454         if (localIn.numSamples > 1)
    455         {
    456             ADDR_ASSERT(localIn.mipLevel == 0);
    457         }
    458 #endif
    459 
    460         if (localIn.format != ADDR_FMT_INVALID) // Set format to INVALID will skip this conversion
    461         {
    462             // Get compression/expansion factors and element mode
    463             // (which indicates compression/expansion
    464             localIn.bpp = GetElemLib()->GetBitsPerPixel(localIn.format,
    465                                                         &elemMode,
    466                                                         &expandX,
    467                                                         &expandY);
    468 
    469             // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
    470             // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
    471             // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
    472             // restrictions are different.
    473             // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
    474             // but we use this flag to skip RestoreSurfaceInfo below
    475 
    476             if ((elemMode == ADDR_EXPANDED) &&
    477                 (expandX > 1))
    478             {
    479                 ADDR_ASSERT(localIn.tileMode == ADDR_TM_LINEAR_ALIGNED || localIn.height == 1);
    480             }
    481 
    482             GetElemLib()->AdjustSurfaceInfo(elemMode,
    483                                             expandX,
    484                                             expandY,
    485                                             &localIn.bpp,
    486                                             &localIn.basePitch,
    487                                             &localIn.width,
    488                                             &localIn.height);
    489 
    490             // Overwrite these parameters if we have a valid format
    491         }
    492         else if (localIn.bpp != 0)
    493         {
    494             localIn.width  = (localIn.width != 0) ? localIn.width : 1;
    495             localIn.height = (localIn.height != 0) ? localIn.height : 1;
    496         }
    497         else // Rule out some invalid parameters
    498         {
    499             ADDR_ASSERT_ALWAYS();
    500 
    501             returnCode = ADDR_INVALIDPARAMS;
    502         }
    503 
    504         // Check mipmap after surface expansion
    505         if (returnCode == ADDR_OK)
    506         {
    507             returnCode = PostComputeMipLevel(&localIn, pOut);
    508         }
    509 
    510         if (returnCode == ADDR_OK)
    511         {
    512             if (UseTileIndex(localIn.tileIndex))
    513             {
    514                 // Make sure pTileInfo is not NULL
    515                 ADDR_ASSERT(localIn.pTileInfo);
    516 
    517                 UINT_32 numSamples = GetNumFragments(localIn.numSamples, localIn.numFrags);
    518 
    519                 INT_32 macroModeIndex = TileIndexNoMacroIndex;
    520 
    521                 if (localIn.tileIndex != TileIndexLinearGeneral)
    522                 {
    523                     // Try finding a macroModeIndex
    524                     macroModeIndex = HwlComputeMacroModeIndex(localIn.tileIndex,
    525                                                               localIn.flags,
    526                                                               localIn.bpp,
    527                                                               numSamples,
    528                                                               localIn.pTileInfo,
    529                                                               &localIn.tileMode,
    530                                                               &localIn.tileType);
    531                 }
    532 
    533                 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
    534                 if (macroModeIndex == TileIndexNoMacroIndex)
    535                 {
    536                     returnCode = HwlSetupTileCfg(localIn.tileIndex, macroModeIndex,
    537                                                  localIn.pTileInfo,
    538                                                  &localIn.tileMode, &localIn.tileType);
    539                 }
    540                 // If macroModeIndex is invalid, then assert this is not macro tiled
    541                 else if (macroModeIndex == TileIndexInvalid)
    542                 {
    543                     ADDR_ASSERT(!IsMacroTiled(localIn.tileMode));
    544                 }
    545             }
    546         }
    547 
    548         if (returnCode == ADDR_OK)
    549         {
    550             AddrTileMode tileMode = localIn.tileMode;
    551             AddrTileType tileType = localIn.tileType;
    552 
    553             // HWL layer may override tile mode if necessary
    554             if (HwlOverrideTileMode(&localIn, &tileMode, &tileType))
    555             {
    556                 localIn.tileMode = tileMode;
    557                 localIn.tileType = tileType;
    558             }
    559             // Degrade base level if applicable
    560             if (DegradeBaseLevel(&localIn, &tileMode))
    561             {
    562                 localIn.tileMode = tileMode;
    563             }
    564         }
    565 
    566         // Call main function to compute surface info
    567         if (returnCode == ADDR_OK)
    568         {
    569             returnCode = HwlComputeSurfaceInfo(&localIn, pOut);
    570         }
    571 
    572         if (returnCode == ADDR_OK)
    573         {
    574             // Since bpp might be changed we just pass it through
    575             pOut->bpp  = localIn.bpp;
    576 
    577             // Also original width/height/bpp
    578             pOut->pixelPitch    = pOut->pitch;
    579             pOut->pixelHeight   = pOut->height;
    580 
    581 #if DEBUG
    582             if (localIn.flags.display)
    583             {
    584                 ADDR_ASSERT((pOut->pitchAlign % 32) == 0);
    585             }
    586 #endif //DEBUG
    587 
    588             if (localIn.format != ADDR_FMT_INVALID)
    589             {
    590                 //
    591                 // 96 bits surface of level 1+ requires element pitch of 32 bits instead
    592                 // In hwl function we skip multiplication of 3 then we should skip division of 3
    593                 // We keep pitch that represents 32 bit element instead of 96 bits since we
    594                 // will get an odd number if divided by 3.
    595                 //
    596                 if (!((expandX == 3) && (localIn.mipLevel > 0)))
    597                 {
    598 
    599                     GetElemLib()->RestoreSurfaceInfo(elemMode,
    600                                                      expandX,
    601                                                      expandY,
    602                                                      &localIn.bpp,
    603                                                      &pOut->pixelPitch,
    604                                                      &pOut->pixelHeight);
    605                 }
    606             }
    607 
    608             if (localIn.flags.qbStereo)
    609             {
    610                 if (pOut->pStereoInfo)
    611                 {
    612                     ComputeQbStereoInfo(pOut);
    613                 }
    614             }
    615 
    616             if (localIn.flags.volume) // For volume sliceSize equals to all z-slices
    617             {
    618                 pOut->sliceSize = pOut->surfSize;
    619             }
    620             else // For array: sliceSize is likely to have slice-padding (the last one)
    621             {
    622                 pOut->sliceSize = pOut->surfSize / pOut->depth;
    623 
    624                 // array or cubemap
    625                 if (pIn->numSlices > 1)
    626                 {
    627                     // If this is the last slice then add the padding size to this slice
    628                     if (pIn->slice == (pIn->numSlices - 1))
    629                     {
    630                         pOut->sliceSize += pOut->sliceSize * (pOut->depth - pIn->numSlices);
    631                     }
    632                     else if (m_configFlags.checkLast2DLevel)
    633                     {
    634                         // Reset last2DLevel flag if this is not the last array slice
    635                         pOut->last2DLevel = FALSE;
    636                     }
    637                 }
    638             }
    639 
    640             pOut->pitchTileMax = pOut->pitch / 8 - 1;
    641             pOut->heightTileMax = pOut->height / 8 - 1;
    642             pOut->sliceTileMax = pOut->pitch * pOut->height / 64 - 1;
    643         }
    644     }
    645 
    646     return returnCode;
    647 }
    648 
    649 /**
    650 ***************************************************************************************************
    651 *   AddrLib::ComputeSurfaceInfo
    652 *
    653 *   @brief
    654 *       Interface function stub of AddrComputeSurfaceInfo.
    655 *
    656 *   @return
    657 *       ADDR_E_RETURNCODE
    658 ***************************************************************************************************
    659 */
    660 ADDR_E_RETURNCODE AddrLib::ComputeSurfaceAddrFromCoord(
    661     const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
    662     ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
    663     ) const
    664 {
    665     ADDR_E_RETURNCODE returnCode = ADDR_OK;
    666 
    667     if (GetFillSizeFieldsFlags() == TRUE)
    668     {
    669         if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) ||
    670             (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT)))
    671         {
    672             returnCode = ADDR_PARAMSIZEMISMATCH;
    673         }
    674     }
    675 
    676     if (returnCode == ADDR_OK)
    677     {
    678         ADDR_TILEINFO tileInfoNull;
    679         ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT input;
    680 
    681         if (UseTileIndex(pIn->tileIndex))
    682         {
    683             input = *pIn;
    684             // Use temp tile info for calcalation
    685             input.pTileInfo = &tileInfoNull;
    686 
    687             const ADDR_SURFACE_FLAGS flags = {{0}};
    688             UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags);
    689 
    690             // Try finding a macroModeIndex
    691             INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex,
    692                                                              flags,
    693                                                              input.bpp,
    694                                                              numSamples,
    695                                                              input.pTileInfo,
    696                                                              &input.tileMode,
    697                                                              &input.tileType);
    698 
    699             // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
    700             if (macroModeIndex == TileIndexNoMacroIndex)
    701             {
    702                 returnCode = HwlSetupTileCfg(input.tileIndex, macroModeIndex,
    703                                              input.pTileInfo, &input.tileMode, &input.tileType);
    704             }
    705             // If macroModeIndex is invalid, then assert this is not macro tiled
    706             else if (macroModeIndex == TileIndexInvalid)
    707             {
    708                 ADDR_ASSERT(!IsMacroTiled(input.tileMode));
    709             }
    710 
    711             // Change the input structure
    712             pIn = &input;
    713         }
    714 
    715         if (returnCode == ADDR_OK)
    716         {
    717             returnCode = HwlComputeSurfaceAddrFromCoord(pIn, pOut);
    718 
    719             if (returnCode == ADDR_OK)
    720             {
    721                 pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024));
    722             }
    723         }
    724     }
    725 
    726     return returnCode;
    727 }
    728 
    729 /**
    730 ***************************************************************************************************
    731 *   AddrLib::ComputeSurfaceCoordFromAddr
    732 *
    733 *   @brief
    734 *       Interface function stub of ComputeSurfaceCoordFromAddr.
    735 *
    736 *   @return
    737 *       ADDR_E_RETURNCODE
    738 ***************************************************************************************************
    739 */
    740 ADDR_E_RETURNCODE AddrLib::ComputeSurfaceCoordFromAddr(
    741     const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure
    742     ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure
    743     ) const
    744 {
    745     ADDR_E_RETURNCODE returnCode = ADDR_OK;
    746 
    747     if (GetFillSizeFieldsFlags() == TRUE)
    748     {
    749         if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) ||
    750             (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT)))
    751         {
    752             returnCode = ADDR_PARAMSIZEMISMATCH;
    753         }
    754     }
    755 
    756     if (returnCode == ADDR_OK)
    757     {
    758         ADDR_TILEINFO tileInfoNull;
    759         ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT input;
    760 
    761         if (UseTileIndex(pIn->tileIndex))
    762         {
    763             input = *pIn;
    764             // Use temp tile info for calcalation
    765             input.pTileInfo = &tileInfoNull;
    766 
    767             const ADDR_SURFACE_FLAGS flags = {{0}};
    768             UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags);
    769 
    770             // Try finding a macroModeIndex
    771             INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex,
    772                                                              flags,
    773                                                              input.bpp,
    774                                                              numSamples,
    775                                                              input.pTileInfo,
    776                                                              &input.tileMode,
    777                                                              &input.tileType);
    778 
    779             // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
    780             if (macroModeIndex == TileIndexNoMacroIndex)
    781             {
    782                 returnCode = HwlSetupTileCfg(input.tileIndex, macroModeIndex,
    783                                              input.pTileInfo, &input.tileMode, &input.tileType);
    784             }
    785             // If macroModeIndex is invalid, then assert this is not macro tiled
    786             else if (macroModeIndex == TileIndexInvalid)
    787             {
    788                 ADDR_ASSERT(!IsMacroTiled(input.tileMode));
    789             }
    790 
    791             // Change the input structure
    792             pIn = &input;
    793         }
    794 
    795         if (returnCode == ADDR_OK)
    796         {
    797             returnCode = HwlComputeSurfaceCoordFromAddr(pIn, pOut);
    798         }
    799     }
    800 
    801     return returnCode;
    802 }
    803 
    804 /**
    805 ***************************************************************************************************
    806 *   AddrLib::ComputeSliceTileSwizzle
    807 *
    808 *   @brief
    809 *       Interface function stub of ComputeSliceTileSwizzle.
    810 *
    811 *   @return
    812 *       ADDR_E_RETURNCODE
    813 ***************************************************************************************************
    814 */
    815 ADDR_E_RETURNCODE AddrLib::ComputeSliceTileSwizzle(
    816     const ADDR_COMPUTE_SLICESWIZZLE_INPUT*  pIn,    ///< [in] input structure
    817     ADDR_COMPUTE_SLICESWIZZLE_OUTPUT*       pOut    ///< [out] output structure
    818     ) const
    819 {
    820     ADDR_E_RETURNCODE returnCode = ADDR_OK;
    821 
    822     if (GetFillSizeFieldsFlags() == TRUE)
    823     {
    824         if ((pIn->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_INPUT)) ||
    825             (pOut->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_OUTPUT)))
    826         {
    827             returnCode = ADDR_PARAMSIZEMISMATCH;
    828         }
    829     }
    830 
    831     if (returnCode == ADDR_OK)
    832     {
    833         ADDR_TILEINFO tileInfoNull;
    834         ADDR_COMPUTE_SLICESWIZZLE_INPUT input;
    835 
    836         if (UseTileIndex(pIn->tileIndex))
    837         {
    838             input = *pIn;
    839             // Use temp tile info for calcalation
    840             input.pTileInfo = &tileInfoNull;
    841 
    842             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex,
    843                                          input.pTileInfo, &input.tileMode);
    844             // Change the input structure
    845             pIn = &input;
    846         }
    847 
    848         if (returnCode == ADDR_OK)
    849         {
    850             returnCode = HwlComputeSliceTileSwizzle(pIn, pOut);
    851         }
    852     }
    853 
    854     return returnCode;
    855 }
    856 
    857 /**
    858 ***************************************************************************************************
    859 *   AddrLib::ExtractBankPipeSwizzle
    860 *
    861 *   @brief
    862 *       Interface function stub of AddrExtractBankPipeSwizzle.
    863 *
    864 *   @return
    865 *       ADDR_E_RETURNCODE
    866 ***************************************************************************************************
    867 */
    868 ADDR_E_RETURNCODE AddrLib::ExtractBankPipeSwizzle(
    869     const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT*  pIn,    ///< [in] input structure
    870     ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT*       pOut    ///< [out] output structure
    871     ) const
    872 {
    873     ADDR_E_RETURNCODE returnCode = ADDR_OK;
    874 
    875     if (GetFillSizeFieldsFlags() == TRUE)
    876     {
    877         if ((pIn->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT)) ||
    878             (pOut->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT)))
    879         {
    880             returnCode = ADDR_PARAMSIZEMISMATCH;
    881         }
    882     }
    883 
    884     if (returnCode == ADDR_OK)
    885     {
    886         ADDR_TILEINFO tileInfoNull;
    887         ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT input;
    888 
    889         if (UseTileIndex(pIn->tileIndex))
    890         {
    891             input = *pIn;
    892             // Use temp tile info for calcalation
    893             input.pTileInfo = &tileInfoNull;
    894 
    895             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
    896             // Change the input structure
    897             pIn = &input;
    898         }
    899 
    900         if (returnCode == ADDR_OK)
    901         {
    902             returnCode = HwlExtractBankPipeSwizzle(pIn, pOut);
    903         }
    904     }
    905 
    906     return returnCode;
    907 }
    908 
    909 /**
    910 ***************************************************************************************************
    911 *   AddrLib::CombineBankPipeSwizzle
    912 *
    913 *   @brief
    914 *       Interface function stub of AddrCombineBankPipeSwizzle.
    915 *
    916 *   @return
    917 *       ADDR_E_RETURNCODE
    918 ***************************************************************************************************
    919 */
    920 ADDR_E_RETURNCODE AddrLib::CombineBankPipeSwizzle(
    921     const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT*  pIn,    ///< [in] input structure
    922     ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT*       pOut    ///< [out] output structure
    923     ) const
    924 {
    925     ADDR_E_RETURNCODE returnCode = ADDR_OK;
    926 
    927     if (GetFillSizeFieldsFlags() == TRUE)
    928     {
    929         if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) ||
    930             (pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT)))
    931         {
    932             returnCode = ADDR_PARAMSIZEMISMATCH;
    933         }
    934     }
    935 
    936     if (returnCode == ADDR_OK)
    937     {
    938         ADDR_TILEINFO tileInfoNull;
    939         ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT input;
    940 
    941         if (UseTileIndex(pIn->tileIndex))
    942         {
    943             input = *pIn;
    944             // Use temp tile info for calcalation
    945             input.pTileInfo = &tileInfoNull;
    946 
    947             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
    948             // Change the input structure
    949             pIn = &input;
    950         }
    951 
    952         if (returnCode == ADDR_OK)
    953         {
    954             returnCode = HwlCombineBankPipeSwizzle(pIn->bankSwizzle,
    955                                                    pIn->pipeSwizzle,
    956                                                    pIn->pTileInfo,
    957                                                    pIn->baseAddr,
    958                                                    &pOut->tileSwizzle);
    959         }
    960     }
    961 
    962     return returnCode;
    963 }
    964 
    965 /**
    966 ***************************************************************************************************
    967 *   AddrLib::ComputeBaseSwizzle
    968 *
    969 *   @brief
    970 *       Interface function stub of AddrCompueBaseSwizzle.
    971 *   @return
    972 *       ADDR_E_RETURNCODE
    973 ***************************************************************************************************
    974 */
    975 ADDR_E_RETURNCODE AddrLib::ComputeBaseSwizzle(
    976     const ADDR_COMPUTE_BASE_SWIZZLE_INPUT*  pIn,
    977     ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut) const
    978 {
    979     ADDR_E_RETURNCODE returnCode = ADDR_OK;
    980 
    981     if (GetFillSizeFieldsFlags() == TRUE)
    982     {
    983         if ((pIn->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT)) ||
    984             (pOut->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT)))
    985         {
    986             returnCode = ADDR_PARAMSIZEMISMATCH;
    987         }
    988     }
    989 
    990     if (returnCode == ADDR_OK)
    991     {
    992         ADDR_TILEINFO tileInfoNull;
    993         ADDR_COMPUTE_BASE_SWIZZLE_INPUT input;
    994 
    995         if (UseTileIndex(pIn->tileIndex))
    996         {
    997             input = *pIn;
    998             // Use temp tile info for calcalation
    999             input.pTileInfo = &tileInfoNull;
   1000 
   1001             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
   1002             // Change the input structure
   1003             pIn = &input;
   1004         }
   1005 
   1006         if (returnCode == ADDR_OK)
   1007         {
   1008             if (IsMacroTiled(pIn->tileMode))
   1009             {
   1010                 returnCode = HwlComputeBaseSwizzle(pIn, pOut);
   1011             }
   1012             else
   1013             {
   1014                 pOut->tileSwizzle = 0;
   1015             }
   1016         }
   1017     }
   1018 
   1019     return returnCode;
   1020 }
   1021 
   1022 /**
   1023 ***************************************************************************************************
   1024 *   AddrLib::ComputeFmaskInfo
   1025 *
   1026 *   @brief
   1027 *       Interface function stub of ComputeFmaskInfo.
   1028 *
   1029 *   @return
   1030 *       ADDR_E_RETURNCODE
   1031 ***************************************************************************************************
   1032 */
   1033 ADDR_E_RETURNCODE AddrLib::ComputeFmaskInfo(
   1034     const ADDR_COMPUTE_FMASK_INFO_INPUT*    pIn,    ///< [in] input structure
   1035     ADDR_COMPUTE_FMASK_INFO_OUTPUT*         pOut    ///< [out] output structure
   1036     )
   1037 {
   1038     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1039 
   1040     if (GetFillSizeFieldsFlags() == TRUE)
   1041     {
   1042         if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) ||
   1043             (pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT)))
   1044         {
   1045             returnCode = ADDR_PARAMSIZEMISMATCH;
   1046         }
   1047     }
   1048 
   1049     // No thick MSAA
   1050     if (ComputeSurfaceThickness(pIn->tileMode) > 1)
   1051     {
   1052         returnCode = ADDR_INVALIDPARAMS;
   1053     }
   1054 
   1055     if (returnCode == ADDR_OK)
   1056     {
   1057         ADDR_TILEINFO tileInfoNull;
   1058         ADDR_COMPUTE_FMASK_INFO_INPUT input;
   1059 
   1060         if (UseTileIndex(pIn->tileIndex))
   1061         {
   1062             input = *pIn;
   1063 
   1064             if (pOut->pTileInfo)
   1065             {
   1066                 // Use temp tile info for calcalation
   1067                 input.pTileInfo = pOut->pTileInfo;
   1068             }
   1069             else
   1070             {
   1071                 input.pTileInfo = &tileInfoNull;
   1072             }
   1073 
   1074             ADDR_SURFACE_FLAGS flags = {{0}};
   1075             flags.fmask = 1;
   1076 
   1077             // Try finding a macroModeIndex
   1078             INT_32 macroModeIndex = HwlComputeMacroModeIndex(pIn->tileIndex,
   1079                                                              flags,
   1080                                                              HwlComputeFmaskBits(pIn, NULL),
   1081                                                              pIn->numSamples,
   1082                                                              input.pTileInfo,
   1083                                                              &input.tileMode);
   1084 
   1085             // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
   1086             if (macroModeIndex == TileIndexNoMacroIndex)
   1087             {
   1088                 returnCode = HwlSetupTileCfg(input.tileIndex, macroModeIndex,
   1089                                              input.pTileInfo, &input.tileMode);
   1090             }
   1091 
   1092             ADDR_ASSERT(macroModeIndex != TileIndexInvalid);
   1093 
   1094             // Change the input structure
   1095             pIn = &input;
   1096         }
   1097 
   1098         if (returnCode == ADDR_OK)
   1099         {
   1100             if (pIn->numSamples > 1)
   1101             {
   1102                 returnCode = HwlComputeFmaskInfo(pIn, pOut);
   1103             }
   1104             else
   1105             {
   1106                 memset(pOut, 0, sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT));
   1107 
   1108                 returnCode = ADDR_INVALIDPARAMS;
   1109             }
   1110         }
   1111     }
   1112 
   1113     return returnCode;
   1114 }
   1115 
   1116 /**
   1117 ***************************************************************************************************
   1118 *   AddrLib::ComputeFmaskAddrFromCoord
   1119 *
   1120 *   @brief
   1121 *       Interface function stub of ComputeFmaskAddrFromCoord.
   1122 *
   1123 *   @return
   1124 *       ADDR_E_RETURNCODE
   1125 ***************************************************************************************************
   1126 */
   1127 ADDR_E_RETURNCODE AddrLib::ComputeFmaskAddrFromCoord(
   1128     const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
   1129     ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure
   1130     ) const
   1131 {
   1132     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1133 
   1134     if (GetFillSizeFieldsFlags() == TRUE)
   1135     {
   1136         if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT)) ||
   1137             (pOut->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT)))
   1138         {
   1139             returnCode = ADDR_PARAMSIZEMISMATCH;
   1140         }
   1141     }
   1142 
   1143     if (returnCode == ADDR_OK)
   1144     {
   1145         ADDR_ASSERT(pIn->numSamples > 1);
   1146 
   1147         if (pIn->numSamples > 1)
   1148         {
   1149             returnCode = HwlComputeFmaskAddrFromCoord(pIn, pOut);
   1150         }
   1151         else
   1152         {
   1153             returnCode = ADDR_INVALIDPARAMS;
   1154         }
   1155     }
   1156 
   1157     return returnCode;
   1158 }
   1159 
   1160 /**
   1161 ***************************************************************************************************
   1162 *   AddrLib::ComputeFmaskCoordFromAddr
   1163 *
   1164 *   @brief
   1165 *       Interface function stub of ComputeFmaskAddrFromCoord.
   1166 *
   1167 *   @return
   1168 *       ADDR_E_RETURNCODE
   1169 ***************************************************************************************************
   1170 */
   1171 ADDR_E_RETURNCODE AddrLib::ComputeFmaskCoordFromAddr(
   1172     const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT*  pIn,     ///< [in] input structure
   1173     ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut           ///< [out] output structure
   1174     ) const
   1175 {
   1176     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1177 
   1178     if (GetFillSizeFieldsFlags() == TRUE)
   1179     {
   1180         if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT)) ||
   1181             (pOut->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT)))
   1182         {
   1183             returnCode = ADDR_PARAMSIZEMISMATCH;
   1184         }
   1185     }
   1186 
   1187     if (returnCode == ADDR_OK)
   1188     {
   1189         ADDR_ASSERT(pIn->numSamples > 1);
   1190 
   1191         if (pIn->numSamples > 1)
   1192         {
   1193             returnCode = HwlComputeFmaskCoordFromAddr(pIn, pOut);
   1194         }
   1195         else
   1196         {
   1197             returnCode = ADDR_INVALIDPARAMS;
   1198         }
   1199     }
   1200 
   1201     return returnCode;
   1202 }
   1203 
   1204 /**
   1205 ***************************************************************************************************
   1206 *   AddrLib::ConvertTileInfoToHW
   1207 *
   1208 *   @brief
   1209 *       Convert tile info from real value to HW register value in HW layer
   1210 *
   1211 *   @return
   1212 *       ADDR_E_RETURNCODE
   1213 ***************************************************************************************************
   1214 */
   1215 ADDR_E_RETURNCODE AddrLib::ConvertTileInfoToHW(
   1216     const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure
   1217     ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut      ///< [out] output structure
   1218     ) const
   1219 {
   1220     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1221 
   1222     if (GetFillSizeFieldsFlags() == TRUE)
   1223     {
   1224         if ((pIn->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT)) ||
   1225             (pOut->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT)))
   1226         {
   1227             returnCode = ADDR_PARAMSIZEMISMATCH;
   1228         }
   1229     }
   1230 
   1231     if (returnCode == ADDR_OK)
   1232     {
   1233         ADDR_TILEINFO tileInfoNull;
   1234         ADDR_CONVERT_TILEINFOTOHW_INPUT input;
   1235         // if pIn->reverse is TRUE, indices are ignored
   1236         if (pIn->reverse == FALSE && UseTileIndex(pIn->tileIndex))
   1237         {
   1238             input = *pIn;
   1239             input.pTileInfo = &tileInfoNull;
   1240 
   1241             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
   1242 
   1243             pIn = &input;
   1244         }
   1245 
   1246         if (returnCode == ADDR_OK)
   1247         {
   1248             returnCode = HwlConvertTileInfoToHW(pIn, pOut);
   1249         }
   1250     }
   1251 
   1252     return returnCode;
   1253 }
   1254 
   1255 /**
   1256 ***************************************************************************************************
   1257 *   AddrLib::ConvertTileIndex
   1258 *
   1259 *   @brief
   1260 *       Convert tile index to tile mode/type/info
   1261 *
   1262 *   @return
   1263 *       ADDR_E_RETURNCODE
   1264 ***************************************************************************************************
   1265 */
   1266 ADDR_E_RETURNCODE AddrLib::ConvertTileIndex(
   1267     const ADDR_CONVERT_TILEINDEX_INPUT* pIn, ///< [in] input structure
   1268     ADDR_CONVERT_TILEINDEX_OUTPUT* pOut      ///< [out] output structure
   1269     ) const
   1270 {
   1271     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1272 
   1273     if (GetFillSizeFieldsFlags() == TRUE)
   1274     {
   1275         if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX_INPUT)) ||
   1276             (pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT)))
   1277         {
   1278             returnCode = ADDR_PARAMSIZEMISMATCH;
   1279         }
   1280     }
   1281 
   1282     if (returnCode == ADDR_OK)
   1283     {
   1284 
   1285         returnCode = HwlSetupTileCfg(pIn->tileIndex, pIn->macroModeIndex,
   1286                                      pOut->pTileInfo, &pOut->tileMode, &pOut->tileType);
   1287 
   1288         if (returnCode == ADDR_OK && pIn->tileInfoHw)
   1289         {
   1290             ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0};
   1291             ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0};
   1292 
   1293             hwInput.pTileInfo = pOut->pTileInfo;
   1294             hwInput.tileIndex = -1;
   1295             hwOutput.pTileInfo = pOut->pTileInfo;
   1296 
   1297             returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput);
   1298         }
   1299     }
   1300 
   1301     return returnCode;
   1302 }
   1303 
   1304 /**
   1305 ***************************************************************************************************
   1306 *   AddrLib::ConvertTileIndex1
   1307 *
   1308 *   @brief
   1309 *       Convert tile index to tile mode/type/info
   1310 *
   1311 *   @return
   1312 *       ADDR_E_RETURNCODE
   1313 ***************************************************************************************************
   1314 */
   1315 ADDR_E_RETURNCODE AddrLib::ConvertTileIndex1(
   1316     const ADDR_CONVERT_TILEINDEX1_INPUT* pIn,   ///< [in] input structure
   1317     ADDR_CONVERT_TILEINDEX_OUTPUT* pOut         ///< [out] output structure
   1318     ) const
   1319 {
   1320     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1321 
   1322     if (GetFillSizeFieldsFlags() == TRUE)
   1323     {
   1324         if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX1_INPUT)) ||
   1325             (pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT)))
   1326         {
   1327             returnCode = ADDR_PARAMSIZEMISMATCH;
   1328         }
   1329     }
   1330 
   1331     if (returnCode == ADDR_OK)
   1332     {
   1333         ADDR_SURFACE_FLAGS flags = {{0}};
   1334 
   1335         HwlComputeMacroModeIndex(pIn->tileIndex, flags, pIn->bpp, pIn->numSamples,
   1336                                  pOut->pTileInfo, &pOut->tileMode, &pOut->tileType);
   1337 
   1338         if (pIn->tileInfoHw)
   1339         {
   1340             ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0};
   1341             ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0};
   1342 
   1343             hwInput.pTileInfo = pOut->pTileInfo;
   1344             hwInput.tileIndex = -1;
   1345             hwOutput.pTileInfo = pOut->pTileInfo;
   1346 
   1347             returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput);
   1348         }
   1349     }
   1350 
   1351     return returnCode;
   1352 }
   1353 
   1354 /**
   1355 ***************************************************************************************************
   1356 *   AddrLib::GetTileIndex
   1357 *
   1358 *   @brief
   1359 *       Get tile index from tile mode/type/info
   1360 *
   1361 *   @return
   1362 *       ADDR_E_RETURNCODE
   1363 ***************************************************************************************************
   1364 */
   1365 ADDR_E_RETURNCODE AddrLib::GetTileIndex(
   1366     const ADDR_GET_TILEINDEX_INPUT* pIn, ///< [in] input structure
   1367     ADDR_GET_TILEINDEX_OUTPUT* pOut      ///< [out] output structure
   1368     ) const
   1369 {
   1370     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1371 
   1372     if (GetFillSizeFieldsFlags() == TRUE)
   1373     {
   1374         if ((pIn->size != sizeof(ADDR_GET_TILEINDEX_INPUT)) ||
   1375             (pOut->size != sizeof(ADDR_GET_TILEINDEX_OUTPUT)))
   1376         {
   1377             returnCode = ADDR_PARAMSIZEMISMATCH;
   1378         }
   1379     }
   1380 
   1381     if (returnCode == ADDR_OK)
   1382     {
   1383         returnCode = HwlGetTileIndex(pIn, pOut);
   1384     }
   1385 
   1386     return returnCode;
   1387 }
   1388 
   1389 /**
   1390 ***************************************************************************************************
   1391 *   AddrLib::ComputeSurfaceThickness
   1392 *
   1393 *   @brief
   1394 *       Compute surface thickness
   1395 *
   1396 *   @return
   1397 *       Surface thickness
   1398 ***************************************************************************************************
   1399 */
   1400 UINT_32 AddrLib::ComputeSurfaceThickness(
   1401     AddrTileMode tileMode)    ///< [in] tile mode
   1402 {
   1403     return m_modeFlags[tileMode].thickness;
   1404 }
   1405 
   1406 
   1407 
   1408 ///////////////////////////////////////////////////////////////////////////////////////////////////
   1409 //                               CMASK/HTILE
   1410 ///////////////////////////////////////////////////////////////////////////////////////////////////
   1411 
   1412 /**
   1413 ***************************************************************************************************
   1414 *   AddrLib::ComputeHtileInfo
   1415 *
   1416 *   @brief
   1417 *       Interface function stub of AddrComputeHtilenfo
   1418 *
   1419 *   @return
   1420 *       ADDR_E_RETURNCODE
   1421 ***************************************************************************************************
   1422 */
   1423 ADDR_E_RETURNCODE AddrLib::ComputeHtileInfo(
   1424     const ADDR_COMPUTE_HTILE_INFO_INPUT*    pIn,    ///< [in] input structure
   1425     ADDR_COMPUTE_HTILE_INFO_OUTPUT*         pOut    ///< [out] output structure
   1426     ) const
   1427 {
   1428     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1429 
   1430     BOOL_32 isWidth8  = (pIn->blockWidth == 8) ? TRUE : FALSE;
   1431     BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;
   1432 
   1433     if (GetFillSizeFieldsFlags() == TRUE)
   1434     {
   1435         if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT)) ||
   1436             (pOut->size != sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT)))
   1437         {
   1438             returnCode = ADDR_PARAMSIZEMISMATCH;
   1439         }
   1440     }
   1441 
   1442     if (returnCode == ADDR_OK)
   1443     {
   1444         ADDR_TILEINFO tileInfoNull;
   1445         ADDR_COMPUTE_HTILE_INFO_INPUT input;
   1446 
   1447         if (UseTileIndex(pIn->tileIndex))
   1448         {
   1449             input = *pIn;
   1450             // Use temp tile info for calcalation
   1451             input.pTileInfo = &tileInfoNull;
   1452 
   1453             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
   1454 
   1455             // Change the input structure
   1456             pIn = &input;
   1457         }
   1458 
   1459         if (returnCode == ADDR_OK)
   1460         {
   1461             pOut->bpp = ComputeHtileInfo(pIn->flags,
   1462                                          pIn->pitch,
   1463                                          pIn->height,
   1464                                          pIn->numSlices,
   1465                                          pIn->isLinear,
   1466                                          isWidth8,
   1467                                          isHeight8,
   1468                                          pIn->pTileInfo,
   1469                                          &pOut->pitch,
   1470                                          &pOut->height,
   1471                                          &pOut->htileBytes,
   1472                                          &pOut->macroWidth,
   1473                                          &pOut->macroHeight,
   1474                                          &pOut->sliceSize,
   1475                                          &pOut->baseAlign);
   1476         }
   1477     }
   1478 
   1479     return returnCode;
   1480 }
   1481 
   1482 /**
   1483 ***************************************************************************************************
   1484 *   AddrLib::ComputeCmaskInfo
   1485 *
   1486 *   @brief
   1487 *       Interface function stub of AddrComputeCmaskInfo
   1488 *
   1489 *   @return
   1490 *       ADDR_E_RETURNCODE
   1491 ***************************************************************************************************
   1492 */
   1493 ADDR_E_RETURNCODE AddrLib::ComputeCmaskInfo(
   1494     const ADDR_COMPUTE_CMASK_INFO_INPUT*    pIn,    ///< [in] input structure
   1495     ADDR_COMPUTE_CMASK_INFO_OUTPUT*         pOut    ///< [out] output structure
   1496     ) const
   1497 {
   1498     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1499 
   1500     if (GetFillSizeFieldsFlags() == TRUE)
   1501     {
   1502         if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_INFO_INPUT)) ||
   1503             (pOut->size != sizeof(ADDR_COMPUTE_CMASK_INFO_OUTPUT)))
   1504         {
   1505             returnCode = ADDR_PARAMSIZEMISMATCH;
   1506         }
   1507     }
   1508 
   1509     if (returnCode == ADDR_OK)
   1510     {
   1511         ADDR_TILEINFO tileInfoNull;
   1512         ADDR_COMPUTE_CMASK_INFO_INPUT input;
   1513 
   1514         if (UseTileIndex(pIn->tileIndex))
   1515         {
   1516             input = *pIn;
   1517             // Use temp tile info for calcalation
   1518             input.pTileInfo = &tileInfoNull;
   1519 
   1520             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
   1521 
   1522             // Change the input structure
   1523             pIn = &input;
   1524         }
   1525 
   1526         if (returnCode == ADDR_OK)
   1527         {
   1528             returnCode = ComputeCmaskInfo(pIn->flags,
   1529                                           pIn->pitch,
   1530                                           pIn->height,
   1531                                           pIn->numSlices,
   1532                                           pIn->isLinear,
   1533                                           pIn->pTileInfo,
   1534                                           &pOut->pitch,
   1535                                           &pOut->height,
   1536                                           &pOut->cmaskBytes,
   1537                                           &pOut->macroWidth,
   1538                                           &pOut->macroHeight,
   1539                                           &pOut->sliceSize,
   1540                                           &pOut->baseAlign,
   1541                                           &pOut->blockMax);
   1542         }
   1543     }
   1544 
   1545     return returnCode;
   1546 }
   1547 
   1548 /**
   1549 ***************************************************************************************************
   1550 *   AddrLib::ComputeDccInfo
   1551 *
   1552 *   @brief
   1553 *       Interface function to compute DCC key info
   1554 *
   1555 *   @return
   1556 *       return code of HwlComputeDccInfo
   1557 ***************************************************************************************************
   1558 */
   1559 ADDR_E_RETURNCODE AddrLib::ComputeDccInfo(
   1560     const ADDR_COMPUTE_DCCINFO_INPUT*    pIn,    ///< [in] input structure
   1561     ADDR_COMPUTE_DCCINFO_OUTPUT*         pOut    ///< [out] output structure
   1562     ) const
   1563 {
   1564     ADDR_E_RETURNCODE ret = ADDR_OK;
   1565 
   1566     if (GetFillSizeFieldsFlags() == TRUE)
   1567     {
   1568         if ((pIn->size != sizeof(ADDR_COMPUTE_DCCINFO_INPUT)) ||
   1569             (pOut->size != sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT)))
   1570         {
   1571             ret = ADDR_PARAMSIZEMISMATCH;
   1572         }
   1573     }
   1574 
   1575     if (ret == ADDR_OK)
   1576     {
   1577         ADDR_COMPUTE_DCCINFO_INPUT input;
   1578 
   1579         if (UseTileIndex(pIn->tileIndex))
   1580         {
   1581             input = *pIn;
   1582 
   1583             ret = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex,
   1584                                   &input.tileInfo, &input.tileMode);
   1585 
   1586             pIn = &input;
   1587         }
   1588 
   1589         if (ADDR_OK == ret)
   1590         {
   1591             ret = HwlComputeDccInfo(pIn, pOut);
   1592         }
   1593     }
   1594 
   1595     return ret;
   1596 }
   1597 
   1598 /**
   1599 ***************************************************************************************************
   1600 *   AddrLib::ComputeHtileAddrFromCoord
   1601 *
   1602 *   @brief
   1603 *       Interface function stub of AddrComputeHtileAddrFromCoord
   1604 *
   1605 *   @return
   1606 *       ADDR_E_RETURNCODE
   1607 ***************************************************************************************************
   1608 */
   1609 ADDR_E_RETURNCODE AddrLib::ComputeHtileAddrFromCoord(
   1610     const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
   1611     ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure
   1612     ) const
   1613 {
   1614     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1615 
   1616     BOOL_32 isWidth8  = (pIn->blockWidth == 8) ? TRUE : FALSE;
   1617     BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;
   1618 
   1619     if (GetFillSizeFieldsFlags() == TRUE)
   1620     {
   1621         if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) ||
   1622             (pOut->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT)))
   1623         {
   1624             returnCode = ADDR_PARAMSIZEMISMATCH;
   1625         }
   1626     }
   1627 
   1628     if (returnCode == ADDR_OK)
   1629     {
   1630         ADDR_TILEINFO tileInfoNull;
   1631         ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT input;
   1632 
   1633         if (UseTileIndex(pIn->tileIndex))
   1634         {
   1635             input = *pIn;
   1636             // Use temp tile info for calcalation
   1637             input.pTileInfo = &tileInfoNull;
   1638 
   1639             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
   1640 
   1641             // Change the input structure
   1642             pIn = &input;
   1643         }
   1644 
   1645         if (returnCode == ADDR_OK)
   1646         {
   1647             pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch,
   1648                                                       pIn->height,
   1649                                                       pIn->x,
   1650                                                       pIn->y,
   1651                                                       pIn->slice,
   1652                                                       pIn->numSlices,
   1653                                                       1,
   1654                                                       pIn->isLinear,
   1655                                                       isWidth8,
   1656                                                       isHeight8,
   1657                                                       pIn->pTileInfo,
   1658                                                       &pOut->bitPosition);
   1659         }
   1660     }
   1661 
   1662     return returnCode;
   1663 
   1664 }
   1665 
   1666 /**
   1667 ***************************************************************************************************
   1668 *   AddrLib::ComputeHtileCoordFromAddr
   1669 *
   1670 *   @brief
   1671 *       Interface function stub of AddrComputeHtileCoordFromAddr
   1672 *
   1673 *   @return
   1674 *       ADDR_E_RETURNCODE
   1675 ***************************************************************************************************
   1676 */
   1677 ADDR_E_RETURNCODE AddrLib::ComputeHtileCoordFromAddr(
   1678     const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure
   1679     ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*        pOut    ///< [out] output structure
   1680     ) const
   1681 {
   1682     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1683 
   1684     BOOL_32 isWidth8  = (pIn->blockWidth == 8) ? TRUE : FALSE;
   1685     BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;
   1686 
   1687     if (GetFillSizeFieldsFlags() == TRUE)
   1688     {
   1689         if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT)) ||
   1690             (pOut->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT)))
   1691         {
   1692             returnCode = ADDR_PARAMSIZEMISMATCH;
   1693         }
   1694     }
   1695 
   1696     if (returnCode == ADDR_OK)
   1697     {
   1698         ADDR_TILEINFO tileInfoNull;
   1699         ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT input;
   1700 
   1701         if (UseTileIndex(pIn->tileIndex))
   1702         {
   1703             input = *pIn;
   1704             // Use temp tile info for calcalation
   1705             input.pTileInfo = &tileInfoNull;
   1706 
   1707             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
   1708 
   1709             // Change the input structure
   1710             pIn = &input;
   1711         }
   1712 
   1713         if (returnCode == ADDR_OK)
   1714         {
   1715             HwlComputeXmaskCoordFromAddr(pIn->addr,
   1716                                          pIn->bitPosition,
   1717                                          pIn->pitch,
   1718                                          pIn->height,
   1719                                          pIn->numSlices,
   1720                                          1,
   1721                                          pIn->isLinear,
   1722                                          isWidth8,
   1723                                          isHeight8,
   1724                                          pIn->pTileInfo,
   1725                                          &pOut->x,
   1726                                          &pOut->y,
   1727                                          &pOut->slice);
   1728         }
   1729     }
   1730 
   1731     return returnCode;
   1732 }
   1733 
   1734 /**
   1735 ***************************************************************************************************
   1736 *   AddrLib::ComputeCmaskAddrFromCoord
   1737 *
   1738 *   @brief
   1739 *       Interface function stub of AddrComputeCmaskAddrFromCoord
   1740 *
   1741 *   @return
   1742 *       ADDR_E_RETURNCODE
   1743 ***************************************************************************************************
   1744 */
   1745 ADDR_E_RETURNCODE AddrLib::ComputeCmaskAddrFromCoord(
   1746     const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
   1747     ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure
   1748     ) const
   1749 {
   1750     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1751 
   1752     if (GetFillSizeFieldsFlags() == TRUE)
   1753     {
   1754         if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) ||
   1755             (pOut->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT)))
   1756         {
   1757             returnCode = ADDR_PARAMSIZEMISMATCH;
   1758         }
   1759     }
   1760 
   1761     if (returnCode == ADDR_OK)
   1762     {
   1763         ADDR_TILEINFO tileInfoNull;
   1764         ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT input;
   1765 
   1766         if (UseTileIndex(pIn->tileIndex))
   1767         {
   1768             input = *pIn;
   1769             // Use temp tile info for calcalation
   1770             input.pTileInfo = &tileInfoNull;
   1771 
   1772             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
   1773 
   1774             // Change the input structure
   1775             pIn = &input;
   1776         }
   1777 
   1778         if (returnCode == ADDR_OK)
   1779         {
   1780             if (pIn->flags.tcCompatible == TRUE)
   1781             {
   1782                 returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut);
   1783             }
   1784             else
   1785             {
   1786                 pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch,
   1787                                                           pIn->height,
   1788                                                           pIn->x,
   1789                                                           pIn->y,
   1790                                                           pIn->slice,
   1791                                                           pIn->numSlices,
   1792                                                           2,
   1793                                                           pIn->isLinear,
   1794                                                           FALSE, //this is cmask, isWidth8 is not needed
   1795                                                           FALSE, //this is cmask, isHeight8 is not needed
   1796                                                           pIn->pTileInfo,
   1797                                                           &pOut->bitPosition);
   1798             }
   1799 
   1800         }
   1801     }
   1802 
   1803     return returnCode;
   1804 }
   1805 
   1806 /**
   1807 ***************************************************************************************************
   1808 *   AddrLib::ComputeCmaskCoordFromAddr
   1809 *
   1810 *   @brief
   1811 *       Interface function stub of AddrComputeCmaskCoordFromAddr
   1812 *
   1813 *   @return
   1814 *       ADDR_E_RETURNCODE
   1815 ***************************************************************************************************
   1816 */
   1817 ADDR_E_RETURNCODE AddrLib::ComputeCmaskCoordFromAddr(
   1818     const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure
   1819     ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT*        pOut    ///< [out] output structure
   1820     ) const
   1821 {
   1822     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1823 
   1824     if (GetFillSizeFieldsFlags() == TRUE)
   1825     {
   1826         if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT)) ||
   1827             (pOut->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT)))
   1828         {
   1829             returnCode = ADDR_PARAMSIZEMISMATCH;
   1830         }
   1831     }
   1832 
   1833     if (returnCode == ADDR_OK)
   1834     {
   1835         ADDR_TILEINFO tileInfoNull;
   1836         ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT input;
   1837 
   1838         if (UseTileIndex(pIn->tileIndex))
   1839         {
   1840             input = *pIn;
   1841             // Use temp tile info for calcalation
   1842             input.pTileInfo = &tileInfoNull;
   1843 
   1844             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
   1845 
   1846             // Change the input structure
   1847             pIn = &input;
   1848         }
   1849 
   1850         if (returnCode == ADDR_OK)
   1851         {
   1852             HwlComputeXmaskCoordFromAddr(pIn->addr,
   1853                                          pIn->bitPosition,
   1854                                          pIn->pitch,
   1855                                          pIn->height,
   1856                                          pIn->numSlices,
   1857                                          2,
   1858                                          pIn->isLinear,
   1859                                          FALSE,
   1860                                          FALSE,
   1861                                          pIn->pTileInfo,
   1862                                          &pOut->x,
   1863                                          &pOut->y,
   1864                                          &pOut->slice);
   1865         }
   1866     }
   1867 
   1868     return returnCode;
   1869 }
   1870 
   1871 /**
   1872 ***************************************************************************************************
   1873 *   AddrLib::ComputeTileDataWidthAndHeight
   1874 *
   1875 *   @brief
   1876 *       Compute the squared cache shape for per-tile data (CMASK and HTILE)
   1877 *
   1878 *   @return
   1879 *       N/A
   1880 *
   1881 *   @note
   1882 *       MacroWidth and macroHeight are measured in pixels
   1883 ***************************************************************************************************
   1884 */
   1885 VOID AddrLib::ComputeTileDataWidthAndHeight(
   1886     UINT_32         bpp,             ///< [in] bits per pixel
   1887     UINT_32         cacheBits,       ///< [in] bits of cache
   1888     ADDR_TILEINFO*  pTileInfo,       ///< [in] Tile info
   1889     UINT_32*        pMacroWidth,     ///< [out] macro tile width
   1890     UINT_32*        pMacroHeight     ///< [out] macro tile height
   1891     ) const
   1892 {
   1893     UINT_32 height = 1;
   1894     UINT_32 width  = cacheBits / bpp;
   1895     UINT_32 pipes  = HwlGetPipes(pTileInfo);
   1896 
   1897     // Double height until the macro-tile is close to square
   1898     // Height can only be doubled if width is even
   1899 
   1900     while ((width > height * 2 * pipes) && !(width & 1))
   1901     {
   1902         width  /= 2;
   1903         height *= 2;
   1904     }
   1905 
   1906     *pMacroWidth  = 8 * width;
   1907     *pMacroHeight = 8 * height * pipes;
   1908 
   1909     // Note: The above iterative comptuation is equivalent to the following
   1910     //
   1911     //int log2_height = ((log2(cacheBits)-log2(bpp)-log2(pipes))/2);
   1912     //int macroHeight = pow2( 3+log2(pipes)+log2_height );
   1913 }
   1914 
   1915 /**
   1916 ***************************************************************************************************
   1917 *   AddrLib::HwlComputeTileDataWidthAndHeightLinear
   1918 *
   1919 *   @brief
   1920 *       Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
   1921 *
   1922 *   @return
   1923 *       N/A
   1924 *
   1925 *   @note
   1926 *       MacroWidth and macroHeight are measured in pixels
   1927 ***************************************************************************************************
   1928 */
   1929 VOID AddrLib::HwlComputeTileDataWidthAndHeightLinear(
   1930     UINT_32*        pMacroWidth,     ///< [out] macro tile width
   1931     UINT_32*        pMacroHeight,    ///< [out] macro tile height
   1932     UINT_32         bpp,             ///< [in] bits per pixel
   1933     ADDR_TILEINFO*  pTileInfo        ///< [in] tile info
   1934     ) const
   1935 {
   1936     ADDR_ASSERT(bpp != 4);              // Cmask does not support linear layout prior to SI
   1937     *pMacroWidth  = 8 * 512 / bpp;      // Align width to 512-bit memory accesses
   1938     *pMacroHeight = 8 * m_pipes;        // Align height to number of pipes
   1939 }
   1940 
   1941 /**
   1942 ***************************************************************************************************
   1943 *   AddrLib::ComputeHtileInfo
   1944 *
   1945 *   @brief
   1946 *       Compute htile pitch,width, bytes per 2D slice
   1947 *
   1948 *   @return
   1949 *       Htile bpp i.e. How many bits for an 8x8 tile
   1950 *       Also returns by output parameters:
   1951 *       *Htile pitch, height, total size in bytes, macro-tile dimensions and slice size*
   1952 ***************************************************************************************************
   1953 */
   1954 UINT_32 AddrLib::ComputeHtileInfo(
   1955     ADDR_HTILE_FLAGS flags,             ///< [in] htile flags
   1956     UINT_32          pitchIn,           ///< [in] pitch input
   1957     UINT_32          heightIn,          ///< [in] height input
   1958     UINT_32          numSlices,         ///< [in] number of slices
   1959     BOOL_32          isLinear,          ///< [in] if it is linear mode
   1960     BOOL_32          isWidth8,          ///< [in] if htile block width is 8
   1961     BOOL_32          isHeight8,         ///< [in] if htile block height is 8
   1962     ADDR_TILEINFO*   pTileInfo,         ///< [in] Tile info
   1963     UINT_32*         pPitchOut,         ///< [out] pitch output
   1964     UINT_32*         pHeightOut,        ///< [out] height output
   1965     UINT_64*         pHtileBytes,       ///< [out] bytes per 2D slice
   1966     UINT_32*         pMacroWidth,       ///< [out] macro-tile width in pixels
   1967     UINT_32*         pMacroHeight,      ///< [out] macro-tile width in pixels
   1968     UINT_64*         pSliceSize,        ///< [out] slice size in bytes
   1969     UINT_32*         pBaseAlign         ///< [out] base alignment
   1970     ) const
   1971 {
   1972 
   1973     UINT_32 macroWidth;
   1974     UINT_32 macroHeight;
   1975     UINT_32 baseAlign;
   1976     UINT_64 surfBytes;
   1977     UINT_64 sliceBytes;
   1978 
   1979     numSlices = Max(1u, numSlices);
   1980 
   1981     const UINT_32 bpp = HwlComputeHtileBpp(isWidth8, isHeight8);
   1982     const UINT_32 cacheBits = HtileCacheBits;
   1983 
   1984     if (isLinear)
   1985     {
   1986         HwlComputeTileDataWidthAndHeightLinear(&macroWidth,
   1987                                                &macroHeight,
   1988                                                bpp,
   1989                                                pTileInfo);
   1990     }
   1991     else
   1992     {
   1993         ComputeTileDataWidthAndHeight(bpp,
   1994                                       cacheBits,
   1995                                       pTileInfo,
   1996                                       &macroWidth,
   1997                                       &macroHeight);
   1998     }
   1999 
   2000     *pPitchOut = PowTwoAlign(pitchIn,  macroWidth);
   2001     *pHeightOut = PowTwoAlign(heightIn,  macroHeight);
   2002 
   2003     baseAlign = HwlComputeHtileBaseAlign(flags.tcCompatible, isLinear, pTileInfo);
   2004 
   2005     surfBytes = HwlComputeHtileBytes(*pPitchOut,
   2006                                      *pHeightOut,
   2007                                      bpp,
   2008                                      isLinear,
   2009                                      numSlices,
   2010                                      &sliceBytes,
   2011                                      baseAlign);
   2012 
   2013     *pHtileBytes = surfBytes;
   2014 
   2015     //
   2016     // Use SafeAssign since they are optional
   2017     //
   2018     SafeAssign(pMacroWidth, macroWidth);
   2019 
   2020     SafeAssign(pMacroHeight, macroHeight);
   2021 
   2022     SafeAssign(pSliceSize,  sliceBytes);
   2023 
   2024     SafeAssign(pBaseAlign, baseAlign);
   2025 
   2026     return bpp;
   2027 }
   2028 
   2029 /**
   2030 ***************************************************************************************************
   2031 *   AddrLib::ComputeCmaskBaseAlign
   2032 *
   2033 *   @brief
   2034 *       Compute cmask base alignment
   2035 *
   2036 *   @return
   2037 *       Cmask base alignment
   2038 ***************************************************************************************************
   2039 */
   2040 UINT_32 AddrLib::ComputeCmaskBaseAlign(
   2041     ADDR_CMASK_FLAGS flags,           ///< [in] Cmask flags
   2042     ADDR_TILEINFO*   pTileInfo        ///< [in] Tile info
   2043     ) const
   2044 {
   2045     UINT_32 baseAlign = m_pipeInterleaveBytes * HwlGetPipes(pTileInfo);
   2046 
   2047     if (flags.tcCompatible)
   2048     {
   2049         ADDR_ASSERT(pTileInfo != NULL);
   2050         if (pTileInfo)
   2051         {
   2052             baseAlign *= pTileInfo->banks;
   2053         }
   2054     }
   2055 
   2056     return baseAlign;
   2057 }
   2058 
   2059 /**
   2060 ***************************************************************************************************
   2061 *   AddrLib::ComputeCmaskBytes
   2062 *
   2063 *   @brief
   2064 *       Compute cmask size in bytes
   2065 *
   2066 *   @return
   2067 *       Cmask size in bytes
   2068 ***************************************************************************************************
   2069 */
   2070 UINT_64 AddrLib::ComputeCmaskBytes(
   2071     UINT_32 pitch,        ///< [in] pitch
   2072     UINT_32 height,       ///< [in] height
   2073     UINT_32 numSlices     ///< [in] number of slices
   2074     ) const
   2075 {
   2076     return BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * numSlices * CmaskElemBits) /
   2077         MicroTilePixels;
   2078 }
   2079 
   2080 /**
   2081 ***************************************************************************************************
   2082 *   AddrLib::ComputeCmaskInfo
   2083 *
   2084 *   @brief
   2085 *       Compute cmask pitch,width, bytes per 2D slice
   2086 *
   2087 *   @return
   2088 *       BlockMax. Also by output parameters: Cmask pitch,height, total size in bytes,
   2089 *       macro-tile dimensions
   2090 ***************************************************************************************************
   2091 */
   2092 ADDR_E_RETURNCODE AddrLib::ComputeCmaskInfo(
   2093     ADDR_CMASK_FLAGS flags,            ///< [in] cmask flags
   2094     UINT_32          pitchIn,           ///< [in] pitch input
   2095     UINT_32          heightIn,          ///< [in] height input
   2096     UINT_32          numSlices,         ///< [in] number of slices
   2097     BOOL_32          isLinear,          ///< [in] is linear mode
   2098     ADDR_TILEINFO*   pTileInfo,         ///< [in] Tile info
   2099     UINT_32*         pPitchOut,         ///< [out] pitch output
   2100     UINT_32*         pHeightOut,        ///< [out] height output
   2101     UINT_64*         pCmaskBytes,       ///< [out] bytes per 2D slice
   2102     UINT_32*         pMacroWidth,       ///< [out] macro-tile width in pixels
   2103     UINT_32*         pMacroHeight,      ///< [out] macro-tile width in pixels
   2104     UINT_64*         pSliceSize,        ///< [out] slice size in bytes
   2105     UINT_32*         pBaseAlign,        ///< [out] base alignment
   2106     UINT_32*         pBlockMax          ///< [out] block max == slice / 128 / 128 - 1
   2107     ) const
   2108 {
   2109     UINT_32 macroWidth;
   2110     UINT_32 macroHeight;
   2111     UINT_32 baseAlign;
   2112     UINT_64 surfBytes;
   2113     UINT_64 sliceBytes;
   2114 
   2115     numSlices = Max(1u, numSlices);
   2116 
   2117     const UINT_32 bpp = CmaskElemBits;
   2118     const UINT_32 cacheBits = CmaskCacheBits;
   2119 
   2120     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   2121 
   2122     if (isLinear)
   2123     {
   2124         HwlComputeTileDataWidthAndHeightLinear(&macroWidth,
   2125                                                &macroHeight,
   2126                                                bpp,
   2127                                                pTileInfo);
   2128     }
   2129     else
   2130     {
   2131         ComputeTileDataWidthAndHeight(bpp,
   2132                                       cacheBits,
   2133                                       pTileInfo,
   2134                                       &macroWidth,
   2135                                       &macroHeight);
   2136     }
   2137 
   2138     *pPitchOut = (pitchIn + macroWidth - 1) & ~(macroWidth - 1);
   2139     *pHeightOut = (heightIn + macroHeight - 1) & ~(macroHeight - 1);
   2140 
   2141 
   2142     sliceBytes = ComputeCmaskBytes(*pPitchOut,
   2143                                    *pHeightOut,
   2144                                    1);
   2145 
   2146     baseAlign = ComputeCmaskBaseAlign(flags, pTileInfo);
   2147 
   2148     while (sliceBytes % baseAlign)
   2149     {
   2150         *pHeightOut += macroHeight;
   2151 
   2152         sliceBytes = ComputeCmaskBytes(*pPitchOut,
   2153                                        *pHeightOut,
   2154                                        1);
   2155     }
   2156 
   2157     surfBytes = sliceBytes * numSlices;
   2158 
   2159     *pCmaskBytes = surfBytes;
   2160 
   2161     //
   2162     // Use SafeAssign since they are optional
   2163     //
   2164     SafeAssign(pMacroWidth, macroWidth);
   2165 
   2166     SafeAssign(pMacroHeight, macroHeight);
   2167 
   2168     SafeAssign(pBaseAlign, baseAlign);
   2169 
   2170     SafeAssign(pSliceSize, sliceBytes);
   2171 
   2172     UINT_32 slice = (*pPitchOut) * (*pHeightOut);
   2173     UINT_32 blockMax = slice / 128 / 128 - 1;
   2174 
   2175 #if DEBUG
   2176     if (slice % (64*256) != 0)
   2177     {
   2178         ADDR_ASSERT_ALWAYS();
   2179     }
   2180 #endif //DEBUG
   2181 
   2182     UINT_32 maxBlockMax = HwlGetMaxCmaskBlockMax();
   2183 
   2184     if (blockMax > maxBlockMax)
   2185     {
   2186         blockMax = maxBlockMax;
   2187         returnCode = ADDR_INVALIDPARAMS;
   2188     }
   2189 
   2190     SafeAssign(pBlockMax, blockMax);
   2191 
   2192     return returnCode;
   2193 }
   2194 
   2195 /**
   2196 ***************************************************************************************************
   2197 *   AddrLib::ComputeXmaskCoordYFromPipe
   2198 *
   2199 *   @brief
   2200 *       Compute the Y coord from pipe number for cmask/htile
   2201 *
   2202 *   @return
   2203 *       Y coordinate
   2204 *
   2205 ***************************************************************************************************
   2206 */
   2207 UINT_32 AddrLib::ComputeXmaskCoordYFromPipe(
   2208     UINT_32         pipe,       ///< [in] pipe number
   2209     UINT_32         x           ///< [in] x coordinate
   2210     ) const
   2211 {
   2212     UINT_32 pipeBit0;
   2213     UINT_32 pipeBit1;
   2214     UINT_32 xBit0;
   2215     UINT_32 xBit1;
   2216     UINT_32 yBit0;
   2217     UINT_32 yBit1;
   2218 
   2219     UINT_32 y = 0;
   2220 
   2221     UINT_32 numPipes = m_pipes; // SI has its implementation
   2222     //
   2223     // Convert pipe + x to y coordinate.
   2224     //
   2225     switch (numPipes)
   2226     {
   2227         case 1:
   2228             //
   2229             // 1 pipe
   2230             //
   2231             // p0 = 0
   2232             //
   2233             y = 0;
   2234             break;
   2235         case 2:
   2236             //
   2237             // 2 pipes
   2238             //
   2239             // p0 = x0 ^ y0
   2240             //
   2241             // y0 = p0 ^ x0
   2242             //
   2243             pipeBit0 = pipe & 0x1;
   2244 
   2245             xBit0 = x & 0x1;
   2246 
   2247             yBit0 = pipeBit0 ^ xBit0;
   2248 
   2249             y = yBit0;
   2250             break;
   2251         case 4:
   2252             //
   2253             // 4 pipes
   2254             //
   2255             // p0 = x1 ^ y0
   2256             // p1 = x0 ^ y1
   2257             //
   2258             // y0 = p0 ^ x1
   2259             // y1 = p1 ^ x0
   2260             //
   2261             pipeBit0 =  pipe & 0x1;
   2262             pipeBit1 = (pipe & 0x2) >> 1;
   2263 
   2264             xBit0 =  x & 0x1;
   2265             xBit1 = (x & 0x2) >> 1;
   2266 
   2267             yBit0 = pipeBit0 ^ xBit1;
   2268             yBit1 = pipeBit1 ^ xBit0;
   2269 
   2270             y = (yBit0 |
   2271                  (yBit1 << 1));
   2272             break;
   2273         case 8:
   2274             //
   2275             // 8 pipes
   2276             //
   2277             // r600 and r800 have different method
   2278             //
   2279             y = HwlComputeXmaskCoordYFrom8Pipe(pipe, x);
   2280             break;
   2281         default:
   2282             break;
   2283     }
   2284     return y;
   2285 }
   2286 
   2287 /**
   2288 ***************************************************************************************************
   2289 *   AddrLib::HwlComputeXmaskCoordFromAddr
   2290 *
   2291 *   @brief
   2292 *       Compute the coord from an address of a cmask/htile
   2293 *
   2294 *   @return
   2295 *       N/A
   2296 *
   2297 *   @note
   2298 *       This method is reused by htile, so rename to Xmask
   2299 ***************************************************************************************************
   2300 */
   2301 VOID AddrLib::HwlComputeXmaskCoordFromAddr(
   2302     UINT_64         addr,           ///< [in] address
   2303     UINT_32         bitPosition,    ///< [in] bitPosition in a byte
   2304     UINT_32         pitch,          ///< [in] pitch
   2305     UINT_32         height,         ///< [in] height
   2306     UINT_32         numSlices,      ///< [in] number of slices
   2307     UINT_32         factor,         ///< [in] factor that indicates cmask or htile
   2308     BOOL_32         isLinear,       ///< [in] linear or tiled HTILE layout
   2309     BOOL_32         isWidth8,       ///< [in] TRUE if width is 8, FALSE means 4. It's register value
   2310     BOOL_32         isHeight8,      ///< [in] TRUE if width is 8, FALSE means 4. It's register value
   2311     ADDR_TILEINFO*  pTileInfo,      ///< [in] Tile info
   2312     UINT_32*        pX,             ///< [out] x coord
   2313     UINT_32*        pY,             ///< [out] y coord
   2314     UINT_32*        pSlice          ///< [out] slice index
   2315     ) const
   2316 {
   2317     UINT_32 pipe;
   2318     UINT_32 numPipes;
   2319     UINT_32 numPipeBits;
   2320     UINT_32 macroTilePitch;
   2321     UINT_32 macroTileHeight;
   2322 
   2323     UINT_64 bitAddr;
   2324 
   2325     UINT_32 microTileCoordY;
   2326 
   2327     UINT_32 elemBits;
   2328 
   2329     UINT_32 pitchAligned = pitch;
   2330     UINT_32 heightAligned = height;
   2331     UINT_64 totalBytes;
   2332 
   2333     UINT_64 elemOffset;
   2334 
   2335     UINT_64 macroIndex;
   2336     UINT_32 microIndex;
   2337 
   2338     UINT_64 macroNumber;
   2339     UINT_32 microNumber;
   2340 
   2341     UINT_32 macroX;
   2342     UINT_32 macroY;
   2343     UINT_32 macroZ;
   2344 
   2345     UINT_32 microX;
   2346     UINT_32 microY;
   2347 
   2348     UINT_32 tilesPerMacro;
   2349     UINT_32 macrosPerPitch;
   2350     UINT_32 macrosPerSlice;
   2351 
   2352     //
   2353     // Extract pipe.
   2354     //
   2355     numPipes = HwlGetPipes(pTileInfo);
   2356     pipe = ComputePipeFromAddr(addr, numPipes);
   2357 
   2358     //
   2359     // Compute the number of group and pipe bits.
   2360     //
   2361     numPipeBits  = Log2(numPipes);
   2362 
   2363     UINT_32 groupBits = 8 * m_pipeInterleaveBytes;
   2364     UINT_32 pipes = numPipes;
   2365 
   2366 
   2367     //
   2368     // Compute the micro tile size, in bits. And macro tile pitch and height.
   2369     //
   2370     if (factor == 2) //CMASK
   2371     {
   2372         ADDR_CMASK_FLAGS flags = {{0}};
   2373 
   2374         elemBits = CmaskElemBits;
   2375 
   2376         ComputeCmaskInfo(flags,
   2377                          pitch,
   2378                          height,
   2379                          numSlices,
   2380                          isLinear,
   2381                          pTileInfo,
   2382                          &pitchAligned,
   2383                          &heightAligned,
   2384                          &totalBytes,
   2385                          &macroTilePitch,
   2386                          &macroTileHeight);
   2387     }
   2388     else  //HTILE
   2389     {
   2390         ADDR_HTILE_FLAGS flags = {{0}};
   2391 
   2392         if (factor != 1)
   2393         {
   2394             factor = 1;
   2395         }
   2396 
   2397         elemBits = HwlComputeHtileBpp(isWidth8, isHeight8);
   2398 
   2399         ComputeHtileInfo(flags,
   2400                          pitch,
   2401                          height,
   2402                          numSlices,
   2403                          isLinear,
   2404                          isWidth8,
   2405                          isHeight8,
   2406                          pTileInfo,
   2407                          &pitchAligned,
   2408                          &heightAligned,
   2409                          &totalBytes,
   2410                          &macroTilePitch,
   2411                          &macroTileHeight);
   2412     }
   2413 
   2414     // Should use aligned dims
   2415     //
   2416     pitch = pitchAligned;
   2417     height = heightAligned;
   2418 
   2419 
   2420     //
   2421     // Convert byte address to bit address.
   2422     //
   2423     bitAddr = BYTES_TO_BITS(addr) + bitPosition;
   2424 
   2425 
   2426     //
   2427     // Remove pipe bits from address.
   2428     //
   2429 
   2430     bitAddr = (bitAddr % groupBits) + ((bitAddr/groupBits/pipes)*groupBits);
   2431 
   2432 
   2433     elemOffset = bitAddr / elemBits;
   2434 
   2435     tilesPerMacro = (macroTilePitch/factor) * macroTileHeight / MicroTilePixels >> numPipeBits;
   2436 
   2437     macrosPerPitch = pitch / (macroTilePitch/factor);
   2438     macrosPerSlice = macrosPerPitch * height / macroTileHeight;
   2439 
   2440     macroIndex = elemOffset / factor / tilesPerMacro;
   2441     microIndex = static_cast<UINT_32>(elemOffset % (tilesPerMacro * factor));
   2442 
   2443     macroNumber = macroIndex * factor + microIndex % factor;
   2444     microNumber = microIndex / factor;
   2445 
   2446     macroX = static_cast<UINT_32>((macroNumber % macrosPerPitch));
   2447     macroY = static_cast<UINT_32>((macroNumber % macrosPerSlice) / macrosPerPitch);
   2448     macroZ = static_cast<UINT_32>((macroNumber / macrosPerSlice));
   2449 
   2450 
   2451     microX = microNumber % (macroTilePitch / factor / MicroTileWidth);
   2452     microY = (microNumber / (macroTilePitch / factor / MicroTileHeight));
   2453 
   2454     *pX = macroX * (macroTilePitch/factor) + microX * MicroTileWidth;
   2455     *pY = macroY * macroTileHeight + (microY * MicroTileHeight << numPipeBits);
   2456     *pSlice = macroZ;
   2457 
   2458     microTileCoordY = ComputeXmaskCoordYFromPipe(pipe,
   2459                                                  *pX/MicroTileWidth);
   2460 
   2461 
   2462     //
   2463     // Assemble final coordinates.
   2464     //
   2465     *pY += microTileCoordY * MicroTileHeight;
   2466 
   2467 }
   2468 
   2469 /**
   2470 ***************************************************************************************************
   2471 *   AddrLib::HwlComputeXmaskAddrFromCoord
   2472 *
   2473 *   @brief
   2474 *       Compute the address from an address of cmask (prior to si)
   2475 *
   2476 *   @return
   2477 *       Address in bytes
   2478 *
   2479 ***************************************************************************************************
   2480 */
   2481 UINT_64 AddrLib::HwlComputeXmaskAddrFromCoord(
   2482     UINT_32        pitch,          ///< [in] pitch
   2483     UINT_32        height,         ///< [in] height
   2484     UINT_32        x,              ///< [in] x coord
   2485     UINT_32        y,              ///< [in] y coord
   2486     UINT_32        slice,          ///< [in] slice/depth index
   2487     UINT_32        numSlices,      ///< [in] number of slices
   2488     UINT_32        factor,         ///< [in] factor that indicates cmask(2) or htile(1)
   2489     BOOL_32        isLinear,       ///< [in] linear or tiled HTILE layout
   2490     BOOL_32        isWidth8,       ///< [in] TRUE if width is 8, FALSE means 4. It's register value
   2491     BOOL_32        isHeight8,      ///< [in] TRUE if width is 8, FALSE means 4. It's register value
   2492     ADDR_TILEINFO* pTileInfo,      ///< [in] Tile info
   2493     UINT_32*       pBitPosition    ///< [out] bit position inside a byte
   2494     ) const
   2495 {
   2496     UINT_64 addr;
   2497     UINT_32 numGroupBits;
   2498     UINT_32 numPipeBits;
   2499     UINT_32 newPitch = 0;
   2500     UINT_32 newHeight = 0;
   2501     UINT_64 sliceBytes = 0;
   2502     UINT_64 totalBytes = 0;
   2503     UINT_64 sliceOffset;
   2504     UINT_32 pipe;
   2505     UINT_32 macroTileWidth;
   2506     UINT_32 macroTileHeight;
   2507     UINT_32 macroTilesPerRow;
   2508     UINT_32 macroTileBytes;
   2509     UINT_32 macroTileIndexX;
   2510     UINT_32 macroTileIndexY;
   2511     UINT_64 macroTileOffset;
   2512     UINT_32 pixelBytesPerRow;
   2513     UINT_32 pixelOffsetX;
   2514     UINT_32 pixelOffsetY;
   2515     UINT_32 pixelOffset;
   2516     UINT_64 totalOffset;
   2517     UINT_64 offsetLo;
   2518     UINT_64 offsetHi;
   2519     UINT_64 groupMask;
   2520 
   2521 
   2522     UINT_32 elemBits = 0;
   2523 
   2524     UINT_32 numPipes = m_pipes; // This function is accessed prior to si only
   2525 
   2526     if (factor == 2) //CMASK
   2527     {
   2528         elemBits = CmaskElemBits;
   2529 
   2530         // For asics before SI, cmask is always tiled
   2531         isLinear = FALSE;
   2532     }
   2533     else //HTILE
   2534     {
   2535         if (factor != 1) // Fix compile warning
   2536         {
   2537             factor = 1;
   2538         }
   2539 
   2540         elemBits = HwlComputeHtileBpp(isWidth8, isHeight8);
   2541     }
   2542 
   2543     //
   2544     // Compute the number of group bits and pipe bits.
   2545     //
   2546     numGroupBits = Log2(m_pipeInterleaveBytes);
   2547     numPipeBits  = Log2(numPipes);
   2548 
   2549     //
   2550     // Compute macro tile dimensions.
   2551     //
   2552     if (factor == 2) // CMASK
   2553     {
   2554         ADDR_CMASK_FLAGS flags = {{0}};
   2555 
   2556         ComputeCmaskInfo(flags,
   2557                          pitch,
   2558                          height,
   2559                          numSlices,
   2560                          isLinear,
   2561                          pTileInfo,
   2562                          &newPitch,
   2563                          &newHeight,
   2564                          &totalBytes,
   2565                          &macroTileWidth,
   2566                          &macroTileHeight);
   2567 
   2568         sliceBytes = totalBytes / numSlices;
   2569     }
   2570     else // HTILE
   2571     {
   2572         ADDR_HTILE_FLAGS flags = {{0}};
   2573 
   2574         ComputeHtileInfo(flags,
   2575                          pitch,
   2576                          height,
   2577                          numSlices,
   2578                          isLinear,
   2579                          isWidth8,
   2580                          isHeight8,
   2581                          pTileInfo,
   2582                          &newPitch,
   2583                          &newHeight,
   2584                          &totalBytes,
   2585                          &macroTileWidth,
   2586                          &macroTileHeight,
   2587                          &sliceBytes);
   2588     }
   2589 
   2590     sliceOffset = slice * sliceBytes;
   2591 
   2592     //
   2593     // Get the pipe.  Note that neither slice rotation nor pipe swizzling apply for CMASK.
   2594     //
   2595     pipe = ComputePipeFromCoord(x,
   2596                                 y,
   2597                                 0,
   2598                                 ADDR_TM_2D_TILED_THIN1,
   2599                                 0,
   2600                                 FALSE,
   2601                                 pTileInfo);
   2602 
   2603     //
   2604     // Compute the number of macro tiles per row.
   2605     //
   2606     macroTilesPerRow = newPitch / macroTileWidth;
   2607 
   2608     //
   2609     // Compute the number of bytes per macro tile.
   2610     //
   2611     macroTileBytes = BITS_TO_BYTES((macroTileWidth * macroTileHeight * elemBits) / MicroTilePixels);
   2612 
   2613     //
   2614     // Compute the offset to the macro tile containing the specified coordinate.
   2615     //
   2616     macroTileIndexX = x / macroTileWidth;
   2617     macroTileIndexY = y / macroTileHeight;
   2618     macroTileOffset = ((macroTileIndexY * macroTilesPerRow) + macroTileIndexX) * macroTileBytes;
   2619 
   2620     //
   2621     // Compute the pixel offset within the macro tile.
   2622     //
   2623     pixelBytesPerRow = BITS_TO_BYTES(macroTileWidth * elemBits) / MicroTileWidth;
   2624 
   2625     //
   2626     // The nibbles are interleaved (see below), so the part of the offset relative to the x
   2627     // coordinate repeats halfway across the row. (Not for HTILE)
   2628     //
   2629     if (factor == 2)
   2630     {
   2631         pixelOffsetX = (x % (macroTileWidth / 2)) / MicroTileWidth;
   2632     }
   2633     else
   2634     {
   2635         pixelOffsetX = (x % (macroTileWidth)) / MicroTileWidth * BITS_TO_BYTES(elemBits);
   2636     }
   2637 
   2638     //
   2639     // Compute the y offset within the macro tile.
   2640     //
   2641     pixelOffsetY = (((y % macroTileHeight) / MicroTileHeight) / numPipes) * pixelBytesPerRow;
   2642 
   2643     pixelOffset = pixelOffsetX + pixelOffsetY;
   2644 
   2645     //
   2646     // Combine the slice offset and macro tile offset with the pixel offset, accounting for the
   2647     // pipe bits in the middle of the address.
   2648     //
   2649     totalOffset = ((sliceOffset + macroTileOffset) >> numPipeBits) + pixelOffset;
   2650 
   2651     //
   2652     // Split the offset to put some bits below the pipe bits and some above.
   2653     //
   2654     groupMask = (1 << numGroupBits) - 1;
   2655     offsetLo  = totalOffset &  groupMask;
   2656     offsetHi  = (totalOffset & ~groupMask) << numPipeBits;
   2657 
   2658     //
   2659     // Assemble the address from its components.
   2660     //
   2661     addr  = offsetLo;
   2662     addr |= offsetHi;
   2663     // This is to remove warning with /analyze option
   2664     UINT_32 pipeBits = pipe << numGroupBits;
   2665     addr |= pipeBits;
   2666 
   2667     //
   2668     // Compute the bit position.  The lower nibble is used when the x coordinate within the macro
   2669     // tile is less than half of the macro tile width, and the upper nibble is used when the x
   2670     // coordinate within the macro tile is greater than or equal to half the macro tile width.
   2671     //
   2672     *pBitPosition = ((x % macroTileWidth) < (macroTileWidth / factor)) ? 0 : 4;
   2673 
   2674     return addr;
   2675 }
   2676 
   2677 ///////////////////////////////////////////////////////////////////////////////////////////////////
   2678 //                               Surface Addressing Shared
   2679 ///////////////////////////////////////////////////////////////////////////////////////////////////
   2680 
   2681 /**
   2682 ***************************************************************************************************
   2683 *   AddrLib::ComputeSurfaceAddrFromCoordLinear
   2684 *
   2685 *   @brief
   2686 *       Compute address from coord for linear surface
   2687 *
   2688 *   @return
   2689 *       Address in bytes
   2690 *
   2691 ***************************************************************************************************
   2692 */
   2693 UINT_64 AddrLib::ComputeSurfaceAddrFromCoordLinear(
   2694     UINT_32  x,              ///< [in] x coord
   2695     UINT_32  y,              ///< [in] y coord
   2696     UINT_32  slice,          ///< [in] slice/depth index
   2697     UINT_32  sample,         ///< [in] sample index
   2698     UINT_32  bpp,            ///< [in] bits per pixel
   2699     UINT_32  pitch,          ///< [in] pitch
   2700     UINT_32  height,         ///< [in] height
   2701     UINT_32  numSlices,      ///< [in] number of slices
   2702     UINT_32* pBitPosition    ///< [out] bit position inside a byte
   2703     ) const
   2704 {
   2705     const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height;
   2706 
   2707     UINT_64 sliceOffset = (slice + sample * numSlices)* sliceSize;
   2708     UINT_64 rowOffset   = static_cast<UINT_64>(y) * pitch;
   2709     UINT_64 pixOffset   = x;
   2710 
   2711     UINT_64 addr = (sliceOffset + rowOffset + pixOffset) * bpp;
   2712 
   2713     *pBitPosition = static_cast<UINT_32>(addr % 8);
   2714     addr /= 8;
   2715 
   2716     return addr;
   2717 }
   2718 
   2719 /**
   2720 ***************************************************************************************************
   2721 *   AddrLib::ComputeSurfaceCoordFromAddrLinear
   2722 *
   2723 *   @brief
   2724 *       Compute the coord from an address of a linear surface
   2725 *
   2726 *   @return
   2727 *       N/A
   2728 ***************************************************************************************************
   2729 */
   2730 VOID AddrLib::ComputeSurfaceCoordFromAddrLinear(
   2731     UINT_64  addr,           ///< [in] address
   2732     UINT_32  bitPosition,    ///< [in] bitPosition in a byte
   2733     UINT_32  bpp,            ///< [in] bits per pixel
   2734     UINT_32  pitch,          ///< [in] pitch
   2735     UINT_32  height,         ///< [in] height
   2736     UINT_32  numSlices,      ///< [in] number of slices
   2737     UINT_32* pX,             ///< [out] x coord
   2738     UINT_32* pY,             ///< [out] y coord
   2739     UINT_32* pSlice,         ///< [out] slice/depth index
   2740     UINT_32* pSample         ///< [out] sample index
   2741     ) const
   2742 {
   2743     const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height;
   2744     const UINT_64 linearOffset = (BYTES_TO_BITS(addr) + bitPosition) / bpp;
   2745 
   2746     *pX = static_cast<UINT_32>((linearOffset % sliceSize) % pitch);
   2747     *pY = static_cast<UINT_32>((linearOffset % sliceSize) / pitch % height);
   2748     *pSlice  = static_cast<UINT_32>((linearOffset / sliceSize) % numSlices);
   2749     *pSample = static_cast<UINT_32>((linearOffset / sliceSize) / numSlices);
   2750 }
   2751 
   2752 /**
   2753 ***************************************************************************************************
   2754 *   AddrLib::ComputeSurfaceCoordFromAddrMicroTiled
   2755 *
   2756 *   @brief
   2757 *       Compute the coord from an address of a micro tiled surface
   2758 *
   2759 *   @return
   2760 *       N/A
   2761 ***************************************************************************************************
   2762 */
   2763 VOID AddrLib::ComputeSurfaceCoordFromAddrMicroTiled(
   2764     UINT_64         addr,               ///< [in] address
   2765     UINT_32         bitPosition,        ///< [in] bitPosition in a byte
   2766     UINT_32         bpp,                ///< [in] bits per pixel
   2767     UINT_32         pitch,              ///< [in] pitch
   2768     UINT_32         height,             ///< [in] height
   2769     UINT_32         numSamples,         ///< [in] number of samples
   2770     AddrTileMode    tileMode,           ///< [in] tile mode
   2771     UINT_32         tileBase,           ///< [in] base offset within a tile
   2772     UINT_32         compBits,           ///< [in] component bits actually needed(for planar surface)
   2773     UINT_32*        pX,                 ///< [out] x coord
   2774     UINT_32*        pY,                 ///< [out] y coord
   2775     UINT_32*        pSlice,             ///< [out] slice/depth index
   2776     UINT_32*        pSample,            ///< [out] sample index,
   2777     AddrTileType    microTileType,      ///< [in] micro tiling order
   2778     BOOL_32         isDepthSampleOrder  ///< [in] TRUE if in depth sample order
   2779     ) const
   2780 {
   2781     UINT_64 bitAddr;
   2782     UINT_32 microTileThickness;
   2783     UINT_32 microTileBits;
   2784     UINT_64 sliceBits;
   2785     UINT_64 rowBits;
   2786     UINT_32 sliceIndex;
   2787     UINT_32 microTileCoordX;
   2788     UINT_32 microTileCoordY;
   2789     UINT_32 pixelOffset;
   2790     UINT_32 pixelCoordX = 0;
   2791     UINT_32 pixelCoordY = 0;
   2792     UINT_32 pixelCoordZ = 0;
   2793     UINT_32 pixelCoordS = 0;
   2794 
   2795     //
   2796     // Convert byte address to bit address.
   2797     //
   2798     bitAddr = BYTES_TO_BITS(addr) + bitPosition;
   2799 
   2800     //
   2801     // Compute the micro tile size, in bits.
   2802     //
   2803     switch (tileMode)
   2804     {
   2805         case ADDR_TM_1D_TILED_THICK:
   2806             microTileThickness = ThickTileThickness;
   2807             break;
   2808         default:
   2809             microTileThickness = 1;
   2810             break;
   2811     }
   2812 
   2813     microTileBits = MicroTilePixels * microTileThickness * bpp * numSamples;
   2814 
   2815     //
   2816     // Compute number of bits per slice and number of bits per row of micro tiles.
   2817     //
   2818     sliceBits = static_cast<UINT_64>(pitch) * height * microTileThickness * bpp * numSamples;
   2819 
   2820     rowBits   = (pitch / MicroTileWidth) * microTileBits;
   2821 
   2822     //
   2823     // Extract the slice index.
   2824     //
   2825     sliceIndex = static_cast<UINT_32>(bitAddr / sliceBits);
   2826     bitAddr -= sliceIndex * sliceBits;
   2827 
   2828     //
   2829     // Extract the y coordinate of the micro tile.
   2830     //
   2831     microTileCoordY = static_cast<UINT_32>(bitAddr / rowBits) * MicroTileHeight;
   2832     bitAddr -= (microTileCoordY / MicroTileHeight) * rowBits;
   2833 
   2834     //
   2835     // Extract the x coordinate of the micro tile.
   2836     //
   2837     microTileCoordX = static_cast<UINT_32>(bitAddr / microTileBits) * MicroTileWidth;
   2838 
   2839     //
   2840     // Compute the pixel offset within the micro tile.
   2841     //
   2842     pixelOffset = static_cast<UINT_32>(bitAddr % microTileBits);
   2843 
   2844     //
   2845     // Extract pixel coordinates from the offset.
   2846     //
   2847     HwlComputePixelCoordFromOffset(pixelOffset,
   2848                                    bpp,
   2849                                    numSamples,
   2850                                    tileMode,
   2851                                    tileBase,
   2852                                    compBits,
   2853                                    &pixelCoordX,
   2854                                    &pixelCoordY,
   2855                                    &pixelCoordZ,
   2856                                    &pixelCoordS,
   2857                                    microTileType,
   2858                                    isDepthSampleOrder);
   2859 
   2860     //
   2861     // Assemble final coordinates.
   2862     //
   2863     *pX     = microTileCoordX + pixelCoordX;
   2864     *pY     = microTileCoordY + pixelCoordY;
   2865     *pSlice = (sliceIndex * microTileThickness) + pixelCoordZ;
   2866     *pSample = pixelCoordS;
   2867 
   2868     if (microTileThickness > 1)
   2869     {
   2870         *pSample = 0;
   2871     }
   2872 }
   2873 
   2874 /**
   2875 ***************************************************************************************************
   2876 *   AddrLib::ComputePipeFromAddr
   2877 *
   2878 *   @brief
   2879 *       Compute the pipe number from an address
   2880 *
   2881 *   @return
   2882 *       Pipe number
   2883 *
   2884 ***************************************************************************************************
   2885 */
   2886 UINT_32 AddrLib::ComputePipeFromAddr(
   2887     UINT_64 addr,        ///< [in] address
   2888     UINT_32 numPipes     ///< [in] number of banks
   2889     ) const
   2890 {
   2891     UINT_32 pipe;
   2892 
   2893     UINT_32 groupBytes = m_pipeInterleaveBytes; //just different terms
   2894 
   2895     // R600
   2896     // The LSBs of the address are arranged as follows:
   2897     //   bank | pipe | group
   2898     //
   2899     // To get the pipe number, shift off the group bits and mask the pipe bits.
   2900     //
   2901 
   2902     // R800
   2903     // The LSBs of the address are arranged as follows:
   2904     //   bank | bankInterleave | pipe | pipeInterleave
   2905     //
   2906     // To get the pipe number, shift off the pipe interleave bits and mask the pipe bits.
   2907     //
   2908 
   2909     pipe = static_cast<UINT_32>(addr >> Log2(groupBytes)) & (numPipes - 1);
   2910 
   2911     return pipe;
   2912 }
   2913 
   2914 /**
   2915 ***************************************************************************************************
   2916 *   AddrLib::ComputePixelIndexWithinMicroTile
   2917 *
   2918 *   @brief
   2919 *       Compute the pixel index inside a micro tile of surface
   2920 *
   2921 *   @return
   2922 *       Pixel index
   2923 *
   2924 ***************************************************************************************************
   2925 */
   2926 UINT_32 AddrLib::ComputePixelIndexWithinMicroTile(
   2927     UINT_32         x,              ///< [in] x coord
   2928     UINT_32         y,              ///< [in] y coord
   2929     UINT_32         z,              ///< [in] slice/depth index
   2930     UINT_32         bpp,            ///< [in] bits per pixel
   2931     AddrTileMode    tileMode,       ///< [in] tile mode
   2932     AddrTileType    microTileType   ///< [in] pixel order in display/non-display mode
   2933     ) const
   2934 {
   2935     UINT_32 pixelBit0 = 0;
   2936     UINT_32 pixelBit1 = 0;
   2937     UINT_32 pixelBit2 = 0;
   2938     UINT_32 pixelBit3 = 0;
   2939     UINT_32 pixelBit4 = 0;
   2940     UINT_32 pixelBit5 = 0;
   2941     UINT_32 pixelBit6 = 0;
   2942     UINT_32 pixelBit7 = 0;
   2943     UINT_32 pixelBit8 = 0;
   2944     UINT_32 pixelNumber;
   2945 
   2946     UINT_32 x0 = _BIT(x, 0);
   2947     UINT_32 x1 = _BIT(x, 1);
   2948     UINT_32 x2 = _BIT(x, 2);
   2949     UINT_32 y0 = _BIT(y, 0);
   2950     UINT_32 y1 = _BIT(y, 1);
   2951     UINT_32 y2 = _BIT(y, 2);
   2952     UINT_32 z0 = _BIT(z, 0);
   2953     UINT_32 z1 = _BIT(z, 1);
   2954     UINT_32 z2 = _BIT(z, 2);
   2955 
   2956     UINT_32 thickness = ComputeSurfaceThickness(tileMode);
   2957 
   2958     // Compute the pixel number within the micro tile.
   2959 
   2960     if (microTileType != ADDR_THICK)
   2961     {
   2962         if (microTileType == ADDR_DISPLAYABLE)
   2963         {
   2964             switch (bpp)
   2965             {
   2966                 case 8:
   2967                     pixelBit0 = x0;
   2968                     pixelBit1 = x1;
   2969                     pixelBit2 = x2;
   2970                     pixelBit3 = y1;
   2971                     pixelBit4 = y0;
   2972                     pixelBit5 = y2;
   2973                     break;
   2974                 case 16:
   2975                     pixelBit0 = x0;
   2976                     pixelBit1 = x1;
   2977                     pixelBit2 = x2;
   2978                     pixelBit3 = y0;
   2979                     pixelBit4 = y1;
   2980                     pixelBit5 = y2;
   2981                     break;
   2982                 case 32:
   2983                     pixelBit0 = x0;
   2984                     pixelBit1 = x1;
   2985                     pixelBit2 = y0;
   2986                     pixelBit3 = x2;
   2987                     pixelBit4 = y1;
   2988                     pixelBit5 = y2;
   2989                     break;
   2990                 case 64:
   2991                     pixelBit0 = x0;
   2992                     pixelBit1 = y0;
   2993                     pixelBit2 = x1;
   2994                     pixelBit3 = x2;
   2995                     pixelBit4 = y1;
   2996                     pixelBit5 = y2;
   2997                     break;
   2998                 case 128:
   2999                     pixelBit0 = y0;
   3000                     pixelBit1 = x0;
   3001                     pixelBit2 = x1;
   3002                     pixelBit3 = x2;
   3003                     pixelBit4 = y1;
   3004                     pixelBit5 = y2;
   3005                     break;
   3006                 default:
   3007                     ADDR_ASSERT_ALWAYS();
   3008                     break;
   3009             }
   3010         }
   3011         else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER)
   3012         {
   3013             pixelBit0 = x0;
   3014             pixelBit1 = y0;
   3015             pixelBit2 = x1;
   3016             pixelBit3 = y1;
   3017             pixelBit4 = x2;
   3018             pixelBit5 = y2;
   3019         }
   3020         else if (microTileType == ADDR_ROTATED)
   3021         {
   3022             ADDR_ASSERT(thickness == 1);
   3023 
   3024             switch (bpp)
   3025             {
   3026                 case 8:
   3027                     pixelBit0 = y0;
   3028                     pixelBit1 = y1;
   3029                     pixelBit2 = y2;
   3030                     pixelBit3 = x1;
   3031                     pixelBit4 = x0;
   3032                     pixelBit5 = x2;
   3033                     break;
   3034                 case 16:
   3035                     pixelBit0 = y0;
   3036                     pixelBit1 = y1;
   3037                     pixelBit2 = y2;
   3038                     pixelBit3 = x0;
   3039                     pixelBit4 = x1;
   3040                     pixelBit5 = x2;
   3041                     break;
   3042                 case 32:
   3043                     pixelBit0 = y0;
   3044                     pixelBit1 = y1;
   3045                     pixelBit2 = x0;
   3046                     pixelBit3 = y2;
   3047                     pixelBit4 = x1;
   3048                     pixelBit5 = x2;
   3049                     break;
   3050                 case 64:
   3051                     pixelBit0 = y0;
   3052                     pixelBit1 = x0;
   3053                     pixelBit2 = y1;
   3054                     pixelBit3 = x1;
   3055                     pixelBit4 = x2;
   3056                     pixelBit5 = y2;
   3057                     break;
   3058                 default:
   3059                     ADDR_ASSERT_ALWAYS();
   3060                     break;
   3061             }
   3062         }
   3063 
   3064         if (thickness > 1)
   3065         {
   3066             pixelBit6 = z0;
   3067             pixelBit7 = z1;
   3068         }
   3069     }
   3070     else // ADDR_THICK
   3071     {
   3072         ADDR_ASSERT(thickness > 1);
   3073 
   3074         switch (bpp)
   3075         {
   3076             case 8:
   3077             case 16:
   3078                 pixelBit0 = x0;
   3079                 pixelBit1 = y0;
   3080                 pixelBit2 = x1;
   3081                 pixelBit3 = y1;
   3082                 pixelBit4 = z0;
   3083                 pixelBit5 = z1;
   3084                 break;
   3085             case 32:
   3086                 pixelBit0 = x0;
   3087                 pixelBit1 = y0;
   3088                 pixelBit2 = x1;
   3089                 pixelBit3 = z0;
   3090                 pixelBit4 = y1;
   3091                 pixelBit5 = z1;
   3092                 break;
   3093             case 64:
   3094             case 128:
   3095                 pixelBit0 = y0;
   3096                 pixelBit1 = x0;
   3097                 pixelBit2 = z0;
   3098                 pixelBit3 = x1;
   3099                 pixelBit4 = y1;
   3100                 pixelBit5 = z1;
   3101                 break;
   3102             default:
   3103                 ADDR_ASSERT_ALWAYS();
   3104                 break;
   3105         }
   3106 
   3107         pixelBit6 = x2;
   3108         pixelBit7 = y2;
   3109     }
   3110 
   3111     if (thickness == 8)
   3112     {
   3113         pixelBit8 = z2;
   3114     }
   3115 
   3116     pixelNumber = ((pixelBit0     ) |
   3117                    (pixelBit1 << 1) |
   3118                    (pixelBit2 << 2) |
   3119                    (pixelBit3 << 3) |
   3120                    (pixelBit4 << 4) |
   3121                    (pixelBit5 << 5) |
   3122                    (pixelBit6 << 6) |
   3123                    (pixelBit7 << 7) |
   3124                    (pixelBit8 << 8));
   3125 
   3126     return pixelNumber;
   3127 }
   3128 
   3129 /**
   3130 ***************************************************************************************************
   3131 *   AddrLib::AdjustPitchAlignment
   3132 *
   3133 *   @brief
   3134 *       Adjusts pitch alignment for flipping surface
   3135 *
   3136 *   @return
   3137 *       N/A
   3138 *
   3139 ***************************************************************************************************
   3140 */
   3141 VOID AddrLib::AdjustPitchAlignment(
   3142     ADDR_SURFACE_FLAGS  flags,      ///< [in] Surface flags
   3143     UINT_32*            pPitchAlign ///< [out] Pointer to pitch alignment
   3144     ) const
   3145 {
   3146     // Display engine hardwires lower 5 bit of GRPH_PITCH to ZERO which means 32 pixel alignment
   3147     // Maybe it will be fixed in future but let's make it general for now.
   3148     if (flags.display || flags.overlay)
   3149     {
   3150         *pPitchAlign = PowTwoAlign(*pPitchAlign, 32);
   3151 
   3152         if(flags.display)
   3153         {
   3154             *pPitchAlign = Max(m_minPitchAlignPixels, *pPitchAlign);
   3155         }
   3156     }
   3157 }
   3158 
   3159 /**
   3160 ***************************************************************************************************
   3161 *   AddrLib::PadDimensions
   3162 *
   3163 *   @brief
   3164 *       Helper function to pad dimensions
   3165 *
   3166 *   @return
   3167 *       N/A
   3168 *
   3169 ***************************************************************************************************
   3170 */
   3171 VOID AddrLib::PadDimensions(
   3172     AddrTileMode        tileMode,    ///< [in] tile mode
   3173     UINT_32             bpp,         ///< [in] bits per pixel
   3174     ADDR_SURFACE_FLAGS  flags,       ///< [in] surface flags
   3175     UINT_32             numSamples,  ///< [in] number of samples
   3176     ADDR_TILEINFO*      pTileInfo,   ///< [in/out] bank structure.
   3177     UINT_32             padDims,     ///< [in] Dimensions to pad valid value 1,2,3
   3178     UINT_32             mipLevel,    ///< [in] MipLevel
   3179     UINT_32*            pPitch,      ///< [in/out] pitch in pixels
   3180     UINT_32             pitchAlign,  ///< [in] pitch alignment
   3181     UINT_32*            pHeight,     ///< [in/out] height in pixels
   3182     UINT_32             heightAlign, ///< [in] height alignment
   3183     UINT_32*            pSlices,     ///< [in/out] number of slices
   3184     UINT_32             sliceAlign   ///< [in] number of slice alignment
   3185     ) const
   3186 {
   3187     UINT_32 thickness = ComputeSurfaceThickness(tileMode);
   3188 
   3189     ADDR_ASSERT(padDims <= 3);
   3190 
   3191     //
   3192     // Override padding for mip levels
   3193     //
   3194     if (mipLevel > 0)
   3195     {
   3196         if (flags.cube)
   3197         {
   3198             // for cubemap, we only pad when client call with 6 faces as an identity
   3199             if (*pSlices > 1)
   3200             {
   3201                 padDims = 3; // we should pad cubemap sub levels when we treat it as 3d texture
   3202             }
   3203             else
   3204             {
   3205                 padDims = 2;
   3206             }
   3207         }
   3208     }
   3209 
   3210     // Any possibilities that padDims is 0?
   3211     if (padDims == 0)
   3212     {
   3213         padDims = 3;
   3214     }
   3215 
   3216     if (IsPow2(pitchAlign))
   3217     {
   3218         *pPitch = PowTwoAlign((*pPitch), pitchAlign);
   3219     }
   3220     else // add this code to pass unit test, r600 linear mode is not align bpp to pow2 for linear
   3221     {
   3222         *pPitch += pitchAlign - 1;
   3223         *pPitch /= pitchAlign;
   3224         *pPitch *= pitchAlign;
   3225     }
   3226 
   3227     if (padDims > 1)
   3228     {
   3229         *pHeight = PowTwoAlign((*pHeight), heightAlign);
   3230     }
   3231 
   3232     if (padDims > 2 || thickness > 1)
   3233     {
   3234         // for cubemap single face, we do not pad slices.
   3235         // if we pad it, the slice number should be set to 6 and current mip level > 1
   3236         if (flags.cube && (!m_configFlags.noCubeMipSlicesPad || flags.cubeAsArray))
   3237         {
   3238             *pSlices = NextPow2(*pSlices);
   3239         }
   3240 
   3241         // normal 3D texture or arrays or cubemap has a thick mode? (Just pass unit test)
   3242         if (thickness > 1)
   3243         {
   3244             *pSlices = PowTwoAlign((*pSlices), sliceAlign);
   3245         }
   3246 
   3247     }
   3248 
   3249     HwlPadDimensions(tileMode,
   3250                      bpp,
   3251                      flags,
   3252                      numSamples,
   3253                      pTileInfo,
   3254                      padDims,
   3255                      mipLevel,
   3256                      pPitch,
   3257                      pitchAlign,
   3258                      pHeight,
   3259                      heightAlign,
   3260                      pSlices,
   3261                      sliceAlign);
   3262 }
   3263 
   3264 
   3265 /**
   3266 ***************************************************************************************************
   3267 *   AddrLib::HwlPreHandleBaseLvl3xPitch
   3268 *
   3269 *   @brief
   3270 *       Pre-handler of 3x pitch (96 bit) adjustment
   3271 *
   3272 *   @return
   3273 *       Expected pitch
   3274 ***************************************************************************************************
   3275 */
   3276 UINT_32 AddrLib::HwlPreHandleBaseLvl3xPitch(
   3277     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] input
   3278     UINT_32                                 expPitch    ///< [in] pitch
   3279     ) const
   3280 {
   3281     ADDR_ASSERT(pIn->width == expPitch);
   3282     //
   3283     // If pitch is pre-multiplied by 3, we retrieve original one here to get correct miplevel size
   3284     //
   3285     if (AddrElemLib::IsExpand3x(pIn->format) &&
   3286         pIn->mipLevel == 0 &&
   3287         pIn->tileMode == ADDR_TM_LINEAR_ALIGNED)
   3288     {
   3289         expPitch /= 3;
   3290         expPitch = NextPow2(expPitch);
   3291     }
   3292 
   3293     return expPitch;
   3294 }
   3295 
   3296 /**
   3297 ***************************************************************************************************
   3298 *   AddrLib::HwlPostHandleBaseLvl3xPitch
   3299 *
   3300 *   @brief
   3301 *       Post-handler of 3x pitch adjustment
   3302 *
   3303 *   @return
   3304 *       Expected pitch
   3305 ***************************************************************************************************
   3306 */
   3307 UINT_32 AddrLib::HwlPostHandleBaseLvl3xPitch(
   3308     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] input
   3309     UINT_32                                 expPitch    ///< [in] pitch
   3310     ) const
   3311 {
   3312     //
   3313     // 96 bits surface of sub levels require element pitch of 32 bits instead
   3314     // So we just return pitch in 32 bit pixels without timing 3
   3315     //
   3316     if (AddrElemLib::IsExpand3x(pIn->format) &&
   3317         pIn->mipLevel == 0 &&
   3318         pIn->tileMode == ADDR_TM_LINEAR_ALIGNED)
   3319     {
   3320         expPitch *= 3;
   3321     }
   3322 
   3323     return expPitch;
   3324 }
   3325 
   3326 
   3327 /**
   3328 ***************************************************************************************************
   3329 *   AddrLib::IsMacroTiled
   3330 *
   3331 *   @brief
   3332 *       Check if the tile mode is macro tiled
   3333 *
   3334 *   @return
   3335 *       TRUE if it is macro tiled (2D/2B/3D/3B)
   3336 ***************************************************************************************************
   3337 */
   3338 BOOL_32 AddrLib::IsMacroTiled(
   3339     AddrTileMode tileMode)  ///< [in] tile mode
   3340 {
   3341    return m_modeFlags[tileMode].isMacro;
   3342 }
   3343 
   3344 /**
   3345 ***************************************************************************************************
   3346 *   AddrLib::IsMacro3dTiled
   3347 *
   3348 *   @brief
   3349 *       Check if the tile mode is 3D macro tiled
   3350 *
   3351 *   @return
   3352 *       TRUE if it is 3D macro tiled
   3353 ***************************************************************************************************
   3354 */
   3355 BOOL_32 AddrLib::IsMacro3dTiled(
   3356     AddrTileMode tileMode)  ///< [in] tile mode
   3357 {
   3358     return m_modeFlags[tileMode].isMacro3d;
   3359 }
   3360 
   3361 /**
   3362 ***************************************************************************************************
   3363 *   AddrLib::IsMicroTiled
   3364 *
   3365 *   @brief
   3366 *       Check if the tile mode is micro tiled
   3367 *
   3368 *   @return
   3369 *       TRUE if micro tiled
   3370 ***************************************************************************************************
   3371 */
   3372 BOOL_32 AddrLib::IsMicroTiled(
   3373     AddrTileMode tileMode)  ///< [in] tile mode
   3374 {
   3375     return m_modeFlags[tileMode].isMicro;
   3376 }
   3377 
   3378 /**
   3379 ***************************************************************************************************
   3380 *   AddrLib::IsLinear
   3381 *
   3382 *   @brief
   3383 *       Check if the tile mode is linear
   3384 *
   3385 *   @return
   3386 *       TRUE if linear
   3387 ***************************************************************************************************
   3388 */
   3389 BOOL_32 AddrLib::IsLinear(
   3390     AddrTileMode tileMode)  ///< [in] tile mode
   3391 {
   3392     return m_modeFlags[tileMode].isLinear;
   3393 }
   3394 
   3395 /**
   3396 ***************************************************************************************************
   3397 *   AddrLib::IsPrtNoRotationTileMode
   3398 *
   3399 *   @brief
   3400 *       Return TRUE if it is prt tile without rotation
   3401 *   @note
   3402 *       This function just used by CI
   3403 ***************************************************************************************************
   3404 */
   3405 BOOL_32 AddrLib::IsPrtNoRotationTileMode(
   3406     AddrTileMode tileMode)
   3407 {
   3408     return m_modeFlags[tileMode].isPrtNoRotation;
   3409 }
   3410 
   3411 /**
   3412 ***************************************************************************************************
   3413 *   AddrLib::IsPrtTileMode
   3414 *
   3415 *   @brief
   3416 *       Return TRUE if it is prt tile
   3417 *   @note
   3418 *       This function just used by CI
   3419 ***************************************************************************************************
   3420 */
   3421 BOOL_32 AddrLib::IsPrtTileMode(
   3422     AddrTileMode tileMode)
   3423 {
   3424     return m_modeFlags[tileMode].isPrt;
   3425 }
   3426 
   3427 /**
   3428 ***************************************************************************************************
   3429 *   AddrLib::Bits2Number
   3430 *
   3431 *   @brief
   3432 *       Cat a array of binary bit to a number
   3433 *
   3434 *   @return
   3435 *       The number combined with the array of bits
   3436 ***************************************************************************************************
   3437 */
   3438 UINT_32 AddrLib::Bits2Number(
   3439     UINT_32 bitNum,     ///< [in] how many bits
   3440     ...)                ///< [in] varaible bits value starting from MSB
   3441 {
   3442     UINT_32 number = 0;
   3443     UINT_32 i;
   3444     va_list bits_ptr;
   3445 
   3446     va_start(bits_ptr, bitNum);
   3447 
   3448     for(i = 0; i < bitNum; i++)
   3449     {
   3450         number |= va_arg(bits_ptr, UINT_32);
   3451         number <<= 1;
   3452     }
   3453 
   3454     number>>=1;
   3455 
   3456     va_end(bits_ptr);
   3457 
   3458     return number;
   3459 }
   3460 
   3461 /**
   3462 ***************************************************************************************************
   3463 *   AddrLib::ComputeMipLevel
   3464 *
   3465 *   @brief
   3466 *       Compute mipmap level width/height/slices
   3467 *   @return
   3468 *      N/A
   3469 ***************************************************************************************************
   3470 */
   3471 VOID AddrLib::ComputeMipLevel(
   3472     ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in/out] Input structure
   3473     ) const
   3474 {
   3475     if (AddrElemLib::IsBlockCompressed(pIn->format))
   3476     {
   3477         if (pIn->mipLevel == 0)
   3478         {
   3479             // DXTn's level 0 must be multiple of 4
   3480             // But there are exceptions:
   3481             // 1. Internal surface creation in hostblt/vsblt/etc...
   3482             // 2. Runtime doesn't reject ATI1/ATI2 whose width/height are not multiple of 4
   3483             pIn->width = PowTwoAlign(pIn->width, 4);
   3484             pIn->height = PowTwoAlign(pIn->height, 4);
   3485         }
   3486     }
   3487 
   3488     HwlComputeMipLevel(pIn);
   3489 }
   3490 
   3491 /**
   3492 ***************************************************************************************************
   3493 *   AddrLib::DegradeBaseLevel
   3494 *
   3495 *   @brief
   3496 *       Check if base level's tile mode can be degraded
   3497 *   @return
   3498 *       TRUE if degraded, also returns degraded tile mode (unchanged if not degraded)
   3499 ***************************************************************************************************
   3500 */
   3501 BOOL_32 AddrLib::DegradeBaseLevel(
   3502     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] Input structure for surface info
   3503     AddrTileMode*                           pTileMode   ///< [out] Degraded tile mode
   3504     ) const
   3505 {
   3506     BOOL_32 degraded = FALSE;
   3507     AddrTileMode tileMode = pIn->tileMode;
   3508     UINT_32 thickness = ComputeSurfaceThickness(tileMode);
   3509 
   3510     if (m_configFlags.degradeBaseLevel) // This is a global setting
   3511     {
   3512         if (pIn->flags.degrade4Space        && // Degradation per surface
   3513             pIn->mipLevel == 0              &&
   3514             pIn->numSamples == 1            &&
   3515             IsMacroTiled(tileMode))
   3516         {
   3517             if (HwlDegradeBaseLevel(pIn))
   3518             {
   3519                 *pTileMode = thickness == 1 ? ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
   3520                 degraded = TRUE;
   3521             }
   3522             else if (thickness > 1)
   3523             {
   3524                 // As in the following HwlComputeSurfaceInfo, thick modes may be degraded to
   3525                 // thinner modes, we should re-evaluate whether the corresponding thinner modes
   3526                 // need to be degraded. If so, we choose 1D thick mode instead.
   3527                 tileMode = DegradeLargeThickTile(pIn->tileMode, pIn->bpp);
   3528                 if (tileMode != pIn->tileMode)
   3529                 {
   3530                     ADDR_COMPUTE_SURFACE_INFO_INPUT input = *pIn;
   3531                     input.tileMode = tileMode;
   3532                     if (HwlDegradeBaseLevel(&input))
   3533                     {
   3534                         *pTileMode = ADDR_TM_1D_TILED_THICK;
   3535                         degraded = TRUE;
   3536                     }
   3537                 }
   3538             }
   3539         }
   3540     }
   3541 
   3542     return degraded;
   3543 }
   3544 
   3545 /**
   3546 ***************************************************************************************************
   3547 *   AddrLib::DegradeLargeThickTile
   3548 *
   3549 *   @brief
   3550 *       Check if the thickness needs to be reduced if a tile is too large
   3551 *   @return
   3552 *       The degraded tile mode (unchanged if not degraded)
   3553 ***************************************************************************************************
   3554 */
   3555 AddrTileMode AddrLib::DegradeLargeThickTile(
   3556     AddrTileMode tileMode,
   3557     UINT_32 bpp) const
   3558 {
   3559     // Override tilemode
   3560     // When tile_width (8) * tile_height (8) * thickness * element_bytes is > row_size,
   3561     // it is better to just use THIN mode in this case
   3562     UINT_32 thickness = ComputeSurfaceThickness(tileMode);
   3563 
   3564     if (thickness > 1 && m_configFlags.allowLargeThickTile == 0)
   3565     {
   3566         UINT_32 tileSize = MicroTilePixels * thickness * (bpp >> 3);
   3567 
   3568         if (tileSize > m_rowSize)
   3569         {
   3570             switch (tileMode)
   3571             {
   3572                 case ADDR_TM_2D_TILED_XTHICK:
   3573                     if ((tileSize >> 1) <= m_rowSize)
   3574                     {
   3575                         tileMode = ADDR_TM_2D_TILED_THICK;
   3576                         break;
   3577                     }
   3578                     // else fall through
   3579                 case ADDR_TM_2D_TILED_THICK:
   3580                     tileMode    = ADDR_TM_2D_TILED_THIN1;
   3581                     break;
   3582 
   3583                 case ADDR_TM_3D_TILED_XTHICK:
   3584                     if ((tileSize >> 1) <= m_rowSize)
   3585                     {
   3586                         tileMode = ADDR_TM_3D_TILED_THICK;
   3587                         break;
   3588                     }
   3589                     // else fall through
   3590                 case ADDR_TM_3D_TILED_THICK:
   3591                     tileMode    = ADDR_TM_3D_TILED_THIN1;
   3592                     break;
   3593 
   3594                 case ADDR_TM_PRT_TILED_THICK:
   3595                     tileMode    = ADDR_TM_PRT_TILED_THIN1;
   3596                     break;
   3597 
   3598                 case ADDR_TM_PRT_2D_TILED_THICK:
   3599                     tileMode    = ADDR_TM_PRT_2D_TILED_THIN1;
   3600                     break;
   3601 
   3602                 case ADDR_TM_PRT_3D_TILED_THICK:
   3603                     tileMode    = ADDR_TM_PRT_3D_TILED_THIN1;
   3604                     break;
   3605 
   3606                 default:
   3607                     break;
   3608             }
   3609         }
   3610     }
   3611 
   3612     return tileMode;
   3613 }
   3614 
   3615 /**
   3616 ***************************************************************************************************
   3617 *   AddrLib::PostComputeMipLevel
   3618 *   @brief
   3619 *       Compute MipLevel info (including level 0) after surface adjustment
   3620 *   @return
   3621 *       ADDR_E_RETURNCODE
   3622 ***************************************************************************************************
   3623 */
   3624 ADDR_E_RETURNCODE AddrLib::PostComputeMipLevel(
   3625     ADDR_COMPUTE_SURFACE_INFO_INPUT*    pIn,   ///< [in/out] Input structure
   3626     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*   pOut   ///< [out] Output structure
   3627     ) const
   3628 {
   3629     // Mipmap including level 0 must be pow2 padded since either SI hw expects so or it is
   3630     // required by CFX  for Hw Compatibility between NI and SI. Otherwise it is only needed for
   3631     // mipLevel > 0. Any h/w has different requirement should implement its own virtual function
   3632 
   3633     if (pIn->flags.pow2Pad)
   3634     {
   3635         pIn->width      = NextPow2(pIn->width);
   3636         pIn->height     = NextPow2(pIn->height);
   3637         pIn->numSlices  = NextPow2(pIn->numSlices);
   3638     }
   3639     else if (pIn->mipLevel > 0)
   3640     {
   3641         pIn->width      = NextPow2(pIn->width);
   3642         pIn->height     = NextPow2(pIn->height);
   3643 
   3644         if (!pIn->flags.cube)
   3645         {
   3646             pIn->numSlices = NextPow2(pIn->numSlices);
   3647         }
   3648 
   3649         // for cubemap, we keep its value at first
   3650     }
   3651 
   3652     return ADDR_OK;
   3653 }
   3654 
   3655 /**
   3656 ***************************************************************************************************
   3657 *   AddrLib::HwlSetupTileCfg
   3658 *
   3659 *   @brief
   3660 *       Map tile index to tile setting.
   3661 *   @return
   3662 *       ADDR_E_RETURNCODE
   3663 ***************************************************************************************************
   3664 */
   3665 ADDR_E_RETURNCODE AddrLib::HwlSetupTileCfg(
   3666     INT_32          index,            ///< [in] Tile index
   3667     INT_32          macroModeIndex,   ///< [in] Index in macro tile mode table(CI)
   3668     ADDR_TILEINFO*  pInfo,            ///< [out] Tile Info
   3669     AddrTileMode*   pMode,            ///< [out] Tile mode
   3670     AddrTileType*   pType             ///< [out] Tile type
   3671     ) const
   3672 {
   3673     return ADDR_NOTSUPPORTED;
   3674 }
   3675 
   3676 /**
   3677 ***************************************************************************************************
   3678 *   AddrLib::HwlGetPipes
   3679 *
   3680 *   @brief
   3681 *       Get number pipes
   3682 *   @return
   3683 *       num pipes
   3684 ***************************************************************************************************
   3685 */
   3686 UINT_32 AddrLib::HwlGetPipes(
   3687     const ADDR_TILEINFO* pTileInfo    ///< [in] Tile info
   3688     ) const
   3689 {
   3690     //pTileInfo can be NULL when asic is 6xx and 8xx.
   3691     return m_pipes;
   3692 }
   3693 
   3694 /**
   3695 ***************************************************************************************************
   3696 *   AddrLib::ComputeQbStereoInfo
   3697 *
   3698 *   @brief
   3699 *       Get quad buffer stereo information
   3700 *   @return
   3701 *       TRUE if no error
   3702 ***************************************************************************************************
   3703 */
   3704 BOOL_32 AddrLib::ComputeQbStereoInfo(
   3705     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [in/out] updated pOut+pStereoInfo
   3706     ) const
   3707 {
   3708     BOOL_32 success = FALSE;
   3709 
   3710     if (pOut->pStereoInfo)
   3711     {
   3712         ADDR_ASSERT(pOut->bpp >= 8);
   3713         ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0);
   3714 
   3715         // Save original height
   3716         pOut->pStereoInfo->eyeHeight = pOut->height;
   3717 
   3718         // Right offset
   3719         pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize);
   3720 
   3721         pOut->pStereoInfo->rightSwizzle = HwlComputeQbStereoRightSwizzle(pOut);
   3722         // Double height
   3723         pOut->height <<= 1;
   3724         pOut->pixelHeight <<= 1;
   3725 
   3726         // Double size
   3727         pOut->surfSize <<= 1;
   3728 
   3729         // Right start address meets the base align since it is guaranteed by AddrLib
   3730 
   3731         // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo.
   3732         success = TRUE;
   3733     }
   3734 
   3735     return success;
   3736 }
   3737 
   3738 ///////////////////////////////////////////////////////////////////////////////////////////////////
   3739 //                               Element lib
   3740 ///////////////////////////////////////////////////////////////////////////////////////////////////
   3741 
   3742 
   3743 /**
   3744 ***************************************************************************************************
   3745 *   AddrLib::Flt32ToColorPixel
   3746 *
   3747 *   @brief
   3748 *       Convert a FLT_32 value to a depth/stencil pixel value
   3749 *   @return
   3750 *       ADDR_E_RETURNCODE
   3751 ***************************************************************************************************
   3752 */
   3753 ADDR_E_RETURNCODE AddrLib::Flt32ToDepthPixel(
   3754     const ELEM_FLT32TODEPTHPIXEL_INPUT* pIn,
   3755     ELEM_FLT32TODEPTHPIXEL_OUTPUT* pOut) const
   3756 {
   3757     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   3758 
   3759     if (GetFillSizeFieldsFlags() == TRUE)
   3760     {
   3761         if ((pIn->size != sizeof(ELEM_FLT32TODEPTHPIXEL_INPUT)) ||
   3762             (pOut->size != sizeof(ELEM_FLT32TODEPTHPIXEL_OUTPUT)))
   3763         {
   3764             returnCode = ADDR_PARAMSIZEMISMATCH;
   3765         }
   3766     }
   3767 
   3768     if (returnCode == ADDR_OK)
   3769     {
   3770         GetElemLib()->Flt32ToDepthPixel(pIn->format,
   3771                                         pIn->comps,
   3772                                         pOut->pPixel);
   3773         UINT_32 depthBase = 0;
   3774         UINT_32 stencilBase = 0;
   3775         UINT_32 depthBits = 0;
   3776         UINT_32 stencilBits = 0;
   3777 
   3778         switch (pIn->format)
   3779         {
   3780             case ADDR_DEPTH_16:
   3781                 depthBits = 16;
   3782                 break;
   3783             case ADDR_DEPTH_X8_24:
   3784             case ADDR_DEPTH_8_24:
   3785             case ADDR_DEPTH_X8_24_FLOAT:
   3786             case ADDR_DEPTH_8_24_FLOAT:
   3787                 depthBase = 8;
   3788                 depthBits = 24;
   3789                 stencilBits = 8;
   3790                 break;
   3791             case ADDR_DEPTH_32_FLOAT:
   3792                 depthBits = 32;
   3793                 break;
   3794             case ADDR_DEPTH_X24_8_32_FLOAT:
   3795                 depthBase = 8;
   3796                 depthBits = 32;
   3797                 stencilBits = 8;
   3798                 break;
   3799             default:
   3800                 break;
   3801         }
   3802 
   3803         // Overwrite base since R800 has no "tileBase"
   3804         if (GetElemLib()->IsDepthStencilTilePlanar() == FALSE)
   3805         {
   3806             depthBase = 0;
   3807             stencilBase = 0;
   3808         }
   3809 
   3810         depthBase *= 64;
   3811         stencilBase *= 64;
   3812 
   3813         pOut->stencilBase = stencilBase;
   3814         pOut->depthBase = depthBase;
   3815         pOut->depthBits = depthBits;
   3816         pOut->stencilBits = stencilBits;
   3817     }
   3818 
   3819     return returnCode;
   3820 }
   3821 
   3822 /**
   3823 ***************************************************************************************************
   3824 *   AddrLib::Flt32ToColorPixel
   3825 *
   3826 *   @brief
   3827 *       Convert a FLT_32 value to a red/green/blue/alpha pixel value
   3828 *   @return
   3829 *       ADDR_E_RETURNCODE
   3830 ***************************************************************************************************
   3831 */
   3832 ADDR_E_RETURNCODE AddrLib::Flt32ToColorPixel(
   3833     const ELEM_FLT32TOCOLORPIXEL_INPUT* pIn,
   3834     ELEM_FLT32TOCOLORPIXEL_OUTPUT* pOut) const
   3835 {
   3836     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   3837 
   3838     if (GetFillSizeFieldsFlags() == TRUE)
   3839     {
   3840         if ((pIn->size != sizeof(ELEM_FLT32TOCOLORPIXEL_INPUT)) ||
   3841             (pOut->size != sizeof(ELEM_FLT32TOCOLORPIXEL_OUTPUT)))
   3842         {
   3843             returnCode = ADDR_PARAMSIZEMISMATCH;
   3844         }
   3845     }
   3846 
   3847     if (returnCode == ADDR_OK)
   3848     {
   3849         GetElemLib()->Flt32ToColorPixel(pIn->format,
   3850                                         pIn->surfNum,
   3851                                         pIn->surfSwap,
   3852                                         pIn->comps,
   3853                                         pOut->pPixel);
   3854     }
   3855 
   3856     return returnCode;
   3857 }
   3858 
   3859 
   3860 /**
   3861 ***************************************************************************************************
   3862 *   AddrLib::GetExportNorm
   3863 *
   3864 *   @brief
   3865 *       Check one format can be EXPORT_NUM
   3866 *   @return
   3867 *       TRUE if EXPORT_NORM can be used
   3868 ***************************************************************************************************
   3869 */
   3870 BOOL_32 AddrLib::GetExportNorm(
   3871     const ELEM_GETEXPORTNORM_INPUT* pIn) const
   3872 {
   3873     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   3874 
   3875     BOOL_32 enabled = FALSE;
   3876 
   3877     if (GetFillSizeFieldsFlags() == TRUE)
   3878     {
   3879         if (pIn->size != sizeof(ELEM_GETEXPORTNORM_INPUT))
   3880         {
   3881             returnCode = ADDR_PARAMSIZEMISMATCH;
   3882         }
   3883     }
   3884 
   3885     if (returnCode == ADDR_OK)
   3886     {
   3887         enabled = GetElemLib()->PixGetExportNorm(pIn->format,
   3888                                                  pIn->num,
   3889                                                  pIn->swap);
   3890     }
   3891 
   3892     return enabled;
   3893 }
   3894 
   3895 /**
   3896 ***************************************************************************************************
   3897 *   AddrLib::ComputePrtInfo
   3898 *
   3899 *   @brief
   3900 *       Compute prt surface related info
   3901 *
   3902 *   @return
   3903 *       ADDR_E_RETURNCODE
   3904 ***************************************************************************************************
   3905 */
   3906 ADDR_E_RETURNCODE AddrLib::ComputePrtInfo(
   3907     const ADDR_PRT_INFO_INPUT*  pIn,
   3908     ADDR_PRT_INFO_OUTPUT*       pOut) const
   3909 {
   3910     ADDR_ASSERT(pOut != NULL);
   3911 
   3912     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   3913 
   3914     UINT_32     expandX = 1;
   3915     UINT_32     expandY = 1;
   3916     AddrElemMode elemMode;
   3917 
   3918     UINT_32     bpp = GetElemLib()->GetBitsPerPixel(pIn->format,
   3919                                                 &elemMode,
   3920                                                 &expandX,
   3921                                                 &expandY);
   3922 
   3923     if (bpp <8 || bpp == 24 || bpp == 48 || bpp == 96 )
   3924     {
   3925         returnCode = ADDR_INVALIDPARAMS;
   3926     }
   3927 
   3928     UINT_32     numFrags = pIn->numFrags;
   3929     ADDR_ASSERT(numFrags <= 8);
   3930 
   3931     UINT_32     tileWidth = 0;
   3932     UINT_32     tileHeight = 0;
   3933     if (returnCode == ADDR_OK)
   3934     {
   3935         // 3D texture without depth or 2d texture
   3936         if (pIn->baseMipDepth > 1 || pIn->baseMipHeight > 1)
   3937         {
   3938             if (bpp == 8)
   3939             {
   3940                 tileWidth = 256;
   3941                 tileHeight = 256;
   3942             }
   3943             else if (bpp == 16)
   3944             {
   3945                 tileWidth = 256;
   3946                 tileHeight = 128;
   3947             }
   3948             else if (bpp == 32)
   3949             {
   3950                 tileWidth = 128;
   3951                 tileHeight = 128;
   3952             }
   3953             else if (bpp == 64)
   3954             {
   3955                 // assume it is BC1/4
   3956                 tileWidth = 512;
   3957                 tileHeight = 256;
   3958 
   3959                 if (elemMode == ADDR_UNCOMPRESSED)
   3960                 {
   3961                     tileWidth = 128;
   3962                     tileHeight = 64;
   3963                 }
   3964             }
   3965             else if (bpp == 128)
   3966             {
   3967                 // assume it is BC2/3/5/6H/7
   3968                 tileWidth = 256;
   3969                 tileHeight = 256;
   3970 
   3971                 if (elemMode == ADDR_UNCOMPRESSED)
   3972                 {
   3973                     tileWidth = 64;
   3974                     tileHeight = 64;
   3975                 }
   3976             }
   3977 
   3978             if (numFrags == 2)
   3979             {
   3980                 tileWidth = tileWidth / 2;
   3981             }
   3982             else if (numFrags == 4)
   3983             {
   3984                 tileWidth = tileWidth / 2;
   3985                 tileHeight = tileHeight / 2;
   3986             }
   3987             else if (numFrags == 8)
   3988             {
   3989                 tileWidth = tileWidth / 4;
   3990                 tileHeight = tileHeight / 2;
   3991             }
   3992         }
   3993         else    // 1d
   3994         {
   3995             tileHeight = 1;
   3996             if (bpp == 8)
   3997             {
   3998                 tileWidth = 65536;
   3999             }
   4000             else if (bpp == 16)
   4001             {
   4002                 tileWidth = 32768;
   4003             }
   4004             else if (bpp == 32)
   4005             {
   4006                 tileWidth = 16384;
   4007             }
   4008             else if (bpp == 64)
   4009             {
   4010                 tileWidth = 8192;
   4011             }
   4012             else if (bpp == 128)
   4013             {
   4014                 tileWidth = 4096;
   4015             }
   4016         }
   4017     }
   4018 
   4019     pOut->prtTileWidth = tileWidth;
   4020     pOut->prtTileHeight = tileHeight;
   4021 
   4022     return returnCode;
   4023 }
   4024