Home | History | Annotate | Download | only in r800
      1 /*
      2  * Copyright  2014 Advanced Micro Devices, Inc.
      3  * All Rights Reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sub license, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     14  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
     15  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     16  * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
     17  * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     20  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     21  *
     22  * The above copyright notice and this permission notice (including the
     23  * next paragraph) shall be included in all copies or substantial portions
     24  * of the Software.
     25  */
     26 
     27 /**
     28 ****************************************************************************************************
     29 * @file  egbaddrlib.cpp
     30 * @brief Contains the EgBasedLib class implementation.
     31 ****************************************************************************************************
     32 */
     33 
     34 #include "egbaddrlib.h"
     35 
     36 namespace Addr
     37 {
     38 namespace V1
     39 {
     40 
     41 /**
     42 ****************************************************************************************************
     43 *   EgBasedLib::EgBasedLib
     44 *
     45 *   @brief
     46 *       Constructor
     47 *
     48 *   @note
     49 *
     50 ****************************************************************************************************
     51 */
     52 EgBasedLib::EgBasedLib(const Client* pClient)
     53     :
     54     Lib(pClient),
     55     m_ranks(0),
     56     m_logicalBanks(0),
     57     m_bankInterleave(1)
     58 {
     59 }
     60 
     61 /**
     62 ****************************************************************************************************
     63 *   EgBasedLib::~EgBasedLib
     64 *
     65 *   @brief
     66 *       Destructor
     67 ****************************************************************************************************
     68 */
     69 EgBasedLib::~EgBasedLib()
     70 {
     71 }
     72 
     73 /**
     74 ****************************************************************************************************
     75 *   EgBasedLib::DispatchComputeSurfaceInfo
     76 *
     77 *   @brief
     78 *       Compute surface sizes include padded pitch,height,slices,total size in bytes,
     79 *       meanwhile output suitable tile mode and base alignment might be changed in this
     80 *       call as well. Results are returned through output parameters.
     81 *
     82 *   @return
     83 *       TRUE if no error occurs
     84 ****************************************************************************************************
     85 */
     86 BOOL_32 EgBasedLib::DispatchComputeSurfaceInfo(
     87     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,    ///< [in] input structure
     88     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [out] output structure
     89     ) const
     90 {
     91     AddrTileMode        tileMode      = pIn->tileMode;
     92     UINT_32             bpp           = pIn->bpp;
     93     UINT_32             numSamples    = pIn->numSamples;
     94     UINT_32             numFrags      = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
     95     UINT_32             pitch         = pIn->width;
     96     UINT_32             height        = pIn->height;
     97     UINT_32             numSlices     = pIn->numSlices;
     98     UINT_32             mipLevel      = pIn->mipLevel;
     99     ADDR_SURFACE_FLAGS  flags         = pIn->flags;
    100 
    101     ADDR_TILEINFO       tileInfoDef   = {0};
    102     ADDR_TILEINFO*      pTileInfo     = &tileInfoDef;
    103 
    104     UINT_32             padDims = 0;
    105     BOOL_32             valid;
    106 
    107     tileMode = DegradeLargeThickTile(tileMode, bpp);
    108 
    109     // Only override numSamples for NI above
    110     if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
    111     {
    112         if (numFrags != numSamples) // This means EQAA
    113         {
    114             // The real surface size needed is determined by number of fragments
    115             numSamples = numFrags;
    116         }
    117 
    118         // Save altered numSamples in pOut
    119         pOut->numSamples = numSamples;
    120     }
    121 
    122     // Caller makes sure pOut->pTileInfo is not NULL, see HwlComputeSurfaceInfo
    123     ADDR_ASSERT(pOut->pTileInfo);
    124 
    125     if (pOut->pTileInfo != NULL)
    126     {
    127         pTileInfo = pOut->pTileInfo;
    128     }
    129 
    130     // Set default values
    131     if (pIn->pTileInfo != NULL)
    132     {
    133         if (pTileInfo != pIn->pTileInfo)
    134         {
    135             *pTileInfo = *pIn->pTileInfo;
    136         }
    137     }
    138     else
    139     {
    140         memset(pTileInfo, 0, sizeof(ADDR_TILEINFO));
    141     }
    142 
    143     // For macro tile mode, we should calculate default tiling parameters
    144     HwlSetupTileInfo(tileMode,
    145                      flags,
    146                      bpp,
    147                      pitch,
    148                      height,
    149                      numSamples,
    150                      pIn->pTileInfo,
    151                      pTileInfo,
    152                      pIn->tileType,
    153                      pOut);
    154 
    155     if (flags.cube)
    156     {
    157         if (mipLevel == 0)
    158         {
    159             padDims = 2;
    160         }
    161 
    162         if (numSlices == 1)
    163         {
    164             // This is calculating one face, remove cube flag
    165             flags.cube = 0;
    166         }
    167     }
    168 
    169     switch (tileMode)
    170     {
    171         case ADDR_TM_LINEAR_GENERAL://fall through
    172         case ADDR_TM_LINEAR_ALIGNED:
    173             valid = ComputeSurfaceInfoLinear(pIn, pOut, padDims);
    174             break;
    175 
    176         case ADDR_TM_1D_TILED_THIN1://fall through
    177         case ADDR_TM_1D_TILED_THICK:
    178             valid = ComputeSurfaceInfoMicroTiled(pIn, pOut, padDims, tileMode);
    179             break;
    180 
    181         case ADDR_TM_2D_TILED_THIN1:    //fall through
    182         case ADDR_TM_2D_TILED_THICK:    //fall through
    183         case ADDR_TM_3D_TILED_THIN1:    //fall through
    184         case ADDR_TM_3D_TILED_THICK:    //fall through
    185         case ADDR_TM_2D_TILED_XTHICK:   //fall through
    186         case ADDR_TM_3D_TILED_XTHICK:   //fall through
    187         case ADDR_TM_PRT_TILED_THIN1:   //fall through
    188         case ADDR_TM_PRT_2D_TILED_THIN1://fall through
    189         case ADDR_TM_PRT_3D_TILED_THIN1://fall through
    190         case ADDR_TM_PRT_TILED_THICK:   //fall through
    191         case ADDR_TM_PRT_2D_TILED_THICK://fall through
    192         case ADDR_TM_PRT_3D_TILED_THICK:
    193             valid = ComputeSurfaceInfoMacroTiled(pIn, pOut, padDims, tileMode);
    194             break;
    195 
    196         default:
    197             valid = FALSE;
    198             ADDR_ASSERT_ALWAYS();
    199             break;
    200     }
    201 
    202     return valid;
    203 }
    204 
    205 /**
    206 ****************************************************************************************************
    207 *   EgBasedLib::ComputeSurfaceInfoLinear
    208 *
    209 *   @brief
    210 *       Compute linear surface sizes include padded pitch, height, slices, total size in
    211 *       bytes, meanwhile alignments as well. Since it is linear mode, so output tile mode
    212 *       will not be changed here. Results are returned through output parameters.
    213 *
    214 *   @return
    215 *       TRUE if no error occurs
    216 ****************************************************************************************************
    217 */
    218 BOOL_32 EgBasedLib::ComputeSurfaceInfoLinear(
    219     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,    ///< [in] Input structure
    220     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut,   ///< [out] Output structure
    221     UINT_32                                 padDims ///< [in] Dimensions to padd
    222     ) const
    223 {
    224     UINT_32 expPitch = pIn->width;
    225     UINT_32 expHeight = pIn->height;
    226     UINT_32 expNumSlices = pIn->numSlices;
    227 
    228     // No linear MSAA on real H/W, keep this for TGL
    229     UINT_32 numSamples = pOut->numSamples;
    230 
    231     const UINT_32 microTileThickness = 1;
    232 
    233     //
    234     // Compute the surface alignments.
    235     //
    236     ComputeSurfaceAlignmentsLinear(pIn->tileMode,
    237                                    pIn->bpp,
    238                                    pIn->flags,
    239                                    &pOut->baseAlign,
    240                                    &pOut->pitchAlign,
    241                                    &pOut->heightAlign);
    242 
    243     if ((pIn->tileMode == ADDR_TM_LINEAR_GENERAL) && pIn->flags.color && (pIn->height > 1))
    244     {
    245 #if !ALT_TEST
    246         // When linear_general surface is accessed in multiple lines, it requires 8 pixels in pitch
    247         // alignment since PITCH_TILE_MAX is in unit of 8 pixels.
    248         // It is OK if it is accessed per line.
    249         ADDR_ASSERT((pIn->width % 8) == 0);
    250 #endif
    251     }
    252 
    253     pOut->depthAlign = microTileThickness;
    254 
    255     expPitch = HwlPreHandleBaseLvl3xPitch(pIn, expPitch);
    256 
    257     //
    258     // Pad pitch and height to the required granularities.
    259     //
    260     PadDimensions(pIn->tileMode,
    261                   pIn->bpp,
    262                   pIn->flags,
    263                   numSamples,
    264                   pOut->pTileInfo,
    265                   padDims,
    266                   pIn->mipLevel,
    267                   &expPitch, &pOut->pitchAlign,
    268                   &expHeight, pOut->heightAlign,
    269                   &expNumSlices, microTileThickness);
    270 
    271     expPitch = HwlPostHandleBaseLvl3xPitch(pIn, expPitch);
    272 
    273     //
    274     // Adjust per HWL
    275     //
    276 
    277     UINT_64 logicalSliceSize;
    278 
    279     logicalSliceSize = HwlGetSizeAdjustmentLinear(pIn->tileMode,
    280                                                   pIn->bpp,
    281                                                   numSamples,
    282                                                   pOut->baseAlign,
    283                                                   pOut->pitchAlign,
    284                                                   &expPitch,
    285                                                   &expHeight,
    286                                                   &pOut->heightAlign);
    287 
    288     if ((pIn->pitchAlign != 0) || (pIn->heightAlign != 0))
    289     {
    290         if (pIn->pitchAlign != 0)
    291         {
    292            ADDR_ASSERT((pIn->pitchAlign % pOut->pitchAlign) == 0);
    293            pOut->pitchAlign = pIn->pitchAlign;
    294 
    295             if (IsPow2(pOut->pitchAlign))
    296             {
    297                 expPitch = PowTwoAlign(expPitch, pOut->pitchAlign);
    298             }
    299             else
    300             {
    301                 expPitch += pOut->pitchAlign - 1;
    302                 expPitch /= pOut->pitchAlign;
    303                 expPitch *= pOut->pitchAlign;
    304             }
    305         }
    306 
    307         if (pIn->heightAlign != 0)
    308         {
    309            ADDR_ASSERT((pIn->heightAlign % pOut->heightAlign) == 0);
    310            pOut->heightAlign = pIn->heightAlign;
    311 
    312             if (IsPow2(pOut->heightAlign))
    313             {
    314                 expHeight = PowTwoAlign(expHeight, pOut->heightAlign);
    315             }
    316             else
    317             {
    318                 expHeight += pOut->heightAlign - 1;
    319                 expHeight /= pOut->heightAlign;
    320                 expHeight *= pOut->heightAlign;
    321             }
    322         }
    323 
    324         logicalSliceSize = BITS_TO_BYTES(expPitch * expHeight * pIn->bpp);
    325     }
    326 
    327     pOut->pitch = expPitch;
    328     pOut->height = expHeight;
    329     pOut->depth = expNumSlices;
    330 
    331     pOut->surfSize = logicalSliceSize * expNumSlices;
    332 
    333     pOut->tileMode = pIn->tileMode;
    334 
    335     return TRUE;
    336 }
    337 
    338 /**
    339 ****************************************************************************************************
    340 *   EgBasedLib::ComputeSurfaceInfoMicroTiled
    341 *
    342 *   @brief
    343 *       Compute 1D/Micro Tiled surface sizes include padded pitch, height, slices, total
    344 *       size in bytes, meanwhile alignments as well. Results are returned through output
    345 *       parameters.
    346 *
    347 *   @return
    348 *       TRUE if no error occurs
    349 ****************************************************************************************************
    350 */
    351 BOOL_32 EgBasedLib::ComputeSurfaceInfoMicroTiled(
    352     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] Input structure
    353     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut,       ///< [out] Output structure
    354     UINT_32                                 padDims,    ///< [in] Dimensions to padd
    355     AddrTileMode                            expTileMode ///< [in] Expected tile mode
    356     ) const
    357 {
    358     BOOL_32 valid = TRUE;
    359 
    360     UINT_32 microTileThickness;
    361     UINT_32 expPitch = pIn->width;
    362     UINT_32 expHeight = pIn->height;
    363     UINT_32 expNumSlices = pIn->numSlices;
    364 
    365     // No 1D MSAA on real H/W, keep this for TGL
    366     UINT_32 numSamples = pOut->numSamples;
    367 
    368     //
    369     // Compute the micro tile thickness.
    370     //
    371     microTileThickness = Thickness(expTileMode);
    372 
    373     //
    374     // Extra override for mip levels
    375     //
    376     if (pIn->mipLevel > 0)
    377     {
    378         //
    379         // Reduce tiling mode from thick to thin if the number of slices is less than the
    380         // micro tile thickness.
    381         //
    382         if ((expTileMode == ADDR_TM_1D_TILED_THICK) &&
    383             (expNumSlices < ThickTileThickness))
    384         {
    385             expTileMode = HwlDegradeThickTileMode(ADDR_TM_1D_TILED_THICK, expNumSlices, NULL);
    386             if (expTileMode != ADDR_TM_1D_TILED_THICK)
    387             {
    388                 microTileThickness = 1;
    389             }
    390         }
    391     }
    392 
    393     //
    394     // Compute the surface restrictions.
    395     //
    396     ComputeSurfaceAlignmentsMicroTiled(expTileMode,
    397                                        pIn->bpp,
    398                                        pIn->flags,
    399                                        pIn->mipLevel,
    400                                        numSamples,
    401                                        &pOut->baseAlign,
    402                                        &pOut->pitchAlign,
    403                                        &pOut->heightAlign);
    404 
    405     pOut->depthAlign = microTileThickness;
    406 
    407     //
    408     // Pad pitch and height to the required granularities.
    409     // Compute surface size.
    410     // Return parameters.
    411     //
    412     PadDimensions(expTileMode,
    413                   pIn->bpp,
    414                   pIn->flags,
    415                   numSamples,
    416                   pOut->pTileInfo,
    417                   padDims,
    418                   pIn->mipLevel,
    419                   &expPitch, &pOut->pitchAlign,
    420                   &expHeight, pOut->heightAlign,
    421                   &expNumSlices, microTileThickness);
    422 
    423     //
    424     // Get HWL specific pitch adjustment
    425     //
    426     UINT_64 logicalSliceSize = HwlGetSizeAdjustmentMicroTiled(microTileThickness,
    427                                                               pIn->bpp,
    428                                                               pIn->flags,
    429                                                               numSamples,
    430                                                               pOut->baseAlign,
    431                                                               pOut->pitchAlign,
    432                                                               &expPitch,
    433                                                               &expHeight);
    434 
    435 
    436     pOut->pitch = expPitch;
    437     pOut->height = expHeight;
    438     pOut->depth = expNumSlices;
    439 
    440     pOut->surfSize = logicalSliceSize * expNumSlices;
    441 
    442     pOut->tileMode = expTileMode;
    443 
    444     return valid;
    445 }
    446 
    447 
    448 /**
    449 ****************************************************************************************************
    450 *   EgBasedLib::ComputeSurfaceInfoMacroTiled
    451 *
    452 *   @brief
    453 *       Compute 2D/macro tiled surface sizes include padded pitch, height, slices, total
    454 *       size in bytes, meanwhile output suitable tile mode and alignments might be changed
    455 *       in this call as well. Results are returned through output parameters.
    456 *
    457 *   @return
    458 *       TRUE if no error occurs
    459 ****************************************************************************************************
    460 */
    461 BOOL_32 EgBasedLib::ComputeSurfaceInfoMacroTiled(
    462     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] Input structure
    463     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut,       ///< [out] Output structure
    464     UINT_32                                 padDims,    ///< [in] Dimensions to padd
    465     AddrTileMode                            expTileMode ///< [in] Expected tile mode
    466     ) const
    467 {
    468     BOOL_32 valid = TRUE;
    469 
    470     AddrTileMode origTileMode = expTileMode;
    471     UINT_32 microTileThickness;
    472 
    473     UINT_32 paddedPitch;
    474     UINT_32 paddedHeight;
    475     UINT_64 bytesPerSlice;
    476 
    477     UINT_32 expPitch     = pIn->width;
    478     UINT_32 expHeight    = pIn->height;
    479     UINT_32 expNumSlices = pIn->numSlices;
    480 
    481     UINT_32 numSamples = pOut->numSamples;
    482 
    483     //
    484     // Compute the surface restrictions as base
    485     // SanityCheckMacroTiled is called in ComputeSurfaceAlignmentsMacroTiled
    486     //
    487     valid = ComputeSurfaceAlignmentsMacroTiled(expTileMode,
    488                                                pIn->bpp,
    489                                                pIn->flags,
    490                                                pIn->mipLevel,
    491                                                numSamples,
    492                                                pOut);
    493 
    494     if (valid)
    495     {
    496         //
    497         // Compute the micro tile thickness.
    498         //
    499         microTileThickness = Thickness(expTileMode);
    500 
    501         //
    502         // Find the correct tiling mode for mip levels
    503         //
    504         if (pIn->mipLevel > 0)
    505         {
    506             //
    507             // Try valid tile mode
    508             //
    509             expTileMode = ComputeSurfaceMipLevelTileMode(expTileMode,
    510                                                          pIn->bpp,
    511                                                          expPitch,
    512                                                          expHeight,
    513                                                          expNumSlices,
    514                                                          numSamples,
    515                                                          pOut->blockWidth,
    516                                                          pOut->blockHeight,
    517                                                          pOut->pTileInfo);
    518 
    519             if (!IsMacroTiled(expTileMode)) // Downgraded to micro-tiled
    520             {
    521                 return ComputeSurfaceInfoMicroTiled(pIn, pOut, padDims, expTileMode);
    522             }
    523             else if (microTileThickness != Thickness(expTileMode))
    524             {
    525                 //
    526                 // Re-compute if thickness changed since bank-height may be changed!
    527                 //
    528                 return ComputeSurfaceInfoMacroTiled(pIn, pOut, padDims, expTileMode);
    529             }
    530         }
    531 
    532         paddedPitch     = expPitch;
    533         paddedHeight    = expHeight;
    534 
    535         //
    536         // Re-cal alignment
    537         //
    538         if (expTileMode != origTileMode) // Tile mode is changed but still macro-tiled
    539         {
    540             valid = ComputeSurfaceAlignmentsMacroTiled(expTileMode,
    541                                                        pIn->bpp,
    542                                                        pIn->flags,
    543                                                        pIn->mipLevel,
    544                                                        numSamples,
    545                                                        pOut);
    546         }
    547 
    548         //
    549         // Do padding
    550         //
    551         PadDimensions(expTileMode,
    552                       pIn->bpp,
    553                       pIn->flags,
    554                       numSamples,
    555                       pOut->pTileInfo,
    556                       padDims,
    557                       pIn->mipLevel,
    558                       &paddedPitch, &pOut->pitchAlign,
    559                       &paddedHeight, pOut->heightAlign,
    560                       &expNumSlices, microTileThickness);
    561 
    562         if (pIn->flags.qbStereo &&
    563             (pOut->pStereoInfo != NULL))
    564         {
    565             UINT_32 stereoHeightAlign = HwlStereoCheckRightOffsetPadding(pOut->pTileInfo);
    566 
    567             if (stereoHeightAlign != 0)
    568             {
    569                 paddedHeight = PowTwoAlign(paddedHeight, stereoHeightAlign);
    570             }
    571         }
    572 
    573         if ((pIn->flags.needEquation == TRUE) &&
    574             (m_chipFamily == ADDR_CHIP_FAMILY_SI) &&
    575             (pIn->numMipLevels > 1) &&
    576             (pIn->mipLevel == 0))
    577         {
    578             BOOL_32 convertTo1D = FALSE;
    579 
    580             ADDR_ASSERT(Thickness(expTileMode) == 1);
    581 
    582             for (UINT_32 i = 1; i < pIn->numMipLevels; i++)
    583             {
    584                 UINT_32 mipPitch = Max(1u, paddedPitch >> i);
    585                 UINT_32 mipHeight = Max(1u, pIn->height >> i);
    586                 UINT_32 mipSlices = pIn->flags.volume ?
    587                                     Max(1u, pIn->numSlices >> i) : pIn->numSlices;
    588                 expTileMode = ComputeSurfaceMipLevelTileMode(expTileMode,
    589                                                              pIn->bpp,
    590                                                              mipPitch,
    591                                                              mipHeight,
    592                                                              mipSlices,
    593                                                              numSamples,
    594                                                              pOut->blockWidth,
    595                                                              pOut->blockHeight,
    596                                                              pOut->pTileInfo);
    597 
    598                 if (IsMacroTiled(expTileMode))
    599                 {
    600                     if (PowTwoAlign(mipPitch, pOut->blockWidth) !=
    601                         PowTwoAlign(mipPitch, pOut->pitchAlign))
    602                     {
    603                         convertTo1D = TRUE;
    604                         break;
    605                     }
    606                 }
    607                 else
    608                 {
    609                     break;
    610                 }
    611             }
    612 
    613             if (convertTo1D)
    614             {
    615                 return ComputeSurfaceInfoMicroTiled(pIn, pOut, padDims, ADDR_TM_1D_TILED_THIN1);
    616             }
    617         }
    618 
    619         pOut->pitch = paddedPitch;
    620         // Put this check right here to workaround special mipmap cases which the original height
    621         // is needed.
    622         // The original height is pre-stored in pOut->height in PostComputeMipLevel and
    623         // pOut->pitch is needed in HwlCheckLastMacroTiledLvl, too.
    624         if (m_configFlags.checkLast2DLevel && (numSamples == 1)) // Don't check MSAA
    625         {
    626             // Set a TRUE in pOut if next Level is the first 1D sub level
    627             HwlCheckLastMacroTiledLvl(pIn, pOut);
    628         }
    629         pOut->height = paddedHeight;
    630 
    631         pOut->depth = expNumSlices;
    632 
    633         //
    634         // Compute the size of a slice.
    635         //
    636         bytesPerSlice = BITS_TO_BYTES(static_cast<UINT_64>(paddedPitch) *
    637                                       paddedHeight * NextPow2(pIn->bpp) * numSamples);
    638 
    639         pOut->surfSize = bytesPerSlice * expNumSlices;
    640 
    641         pOut->tileMode = expTileMode;
    642 
    643         pOut->depthAlign = microTileThickness;
    644 
    645     } // if (valid)
    646 
    647     return valid;
    648 }
    649 
    650 /**
    651 ****************************************************************************************************
    652 *   EgBasedLib::ComputeSurfaceAlignmentsLinear
    653 *
    654 *   @brief
    655 *       Compute linear surface alignment, calculation results are returned through
    656 *       output parameters.
    657 *
    658 *   @return
    659 *       TRUE if no error occurs
    660 ****************************************************************************************************
    661 */
    662 BOOL_32 EgBasedLib::ComputeSurfaceAlignmentsLinear(
    663     AddrTileMode        tileMode,          ///< [in] tile mode
    664     UINT_32             bpp,               ///< [in] bits per pixel
    665     ADDR_SURFACE_FLAGS  flags,             ///< [in] surface flags
    666     UINT_32*            pBaseAlign,        ///< [out] base address alignment in bytes
    667     UINT_32*            pPitchAlign,       ///< [out] pitch alignment in pixels
    668     UINT_32*            pHeightAlign       ///< [out] height alignment in pixels
    669     ) const
    670 {
    671     BOOL_32 valid = TRUE;
    672 
    673     switch (tileMode)
    674     {
    675         case ADDR_TM_LINEAR_GENERAL:
    676             //
    677             // The required base alignment and pitch and height granularities is to 1 element.
    678             //
    679             *pBaseAlign   = (bpp > 8) ? bpp / 8 : 1;
    680             *pPitchAlign  = 1;
    681             *pHeightAlign = 1;
    682             break;
    683         case ADDR_TM_LINEAR_ALIGNED:
    684             //
    685             // The required alignment for base is the pipe interleave size.
    686             // The required granularity for pitch is hwl dependent.
    687             // The required granularity for height is one row.
    688             //
    689             *pBaseAlign     = m_pipeInterleaveBytes;
    690             *pPitchAlign    = HwlGetPitchAlignmentLinear(bpp, flags);
    691             *pHeightAlign   = 1;
    692             break;
    693         default:
    694             *pBaseAlign     = 1;
    695             *pPitchAlign    = 1;
    696             *pHeightAlign   = 1;
    697             ADDR_UNHANDLED_CASE();
    698             break;
    699     }
    700 
    701     AdjustPitchAlignment(flags, pPitchAlign);
    702 
    703     return valid;
    704 }
    705 
    706 /**
    707 ****************************************************************************************************
    708 *   EgBasedLib::ComputeSurfaceAlignmentsMicroTiled
    709 *
    710 *   @brief
    711 *       Compute 1D tiled surface alignment, calculation results are returned through
    712 *       output parameters.
    713 *
    714 *   @return
    715 *       TRUE if no error occurs
    716 ****************************************************************************************************
    717 */
    718 BOOL_32 EgBasedLib::ComputeSurfaceAlignmentsMicroTiled(
    719     AddrTileMode        tileMode,          ///< [in] tile mode
    720     UINT_32             bpp,               ///< [in] bits per pixel
    721     ADDR_SURFACE_FLAGS  flags,             ///< [in] surface flags
    722     UINT_32             mipLevel,          ///< [in] mip level
    723     UINT_32             numSamples,        ///< [in] number of samples
    724     UINT_32*            pBaseAlign,        ///< [out] base address alignment in bytes
    725     UINT_32*            pPitchAlign,       ///< [out] pitch alignment in pixels
    726     UINT_32*            pHeightAlign       ///< [out] height alignment in pixels
    727     ) const
    728 {
    729     BOOL_32 valid = TRUE;
    730 
    731     //
    732     // The required alignment for base is the pipe interleave size.
    733     //
    734     *pBaseAlign   = m_pipeInterleaveBytes;
    735 
    736     *pPitchAlign  = HwlGetPitchAlignmentMicroTiled(tileMode, bpp, flags, numSamples);
    737 
    738     *pHeightAlign = MicroTileHeight;
    739 
    740     AdjustPitchAlignment(flags, pPitchAlign);
    741 
    742     // Workaround 2 for 1D tiling -  There is HW bug for Carrizo,
    743     // where it requires the following alignments for 1D tiling.
    744     if (flags.czDispCompatible && (mipLevel == 0))
    745     {
    746         *pBaseAlign  = PowTwoAlign(*pBaseAlign, 4096);                         //Base address MOD 4096 = 0
    747         *pPitchAlign = PowTwoAlign(*pPitchAlign, 512 / (BITS_TO_BYTES(bpp)));  //(8 lines * pitch * bytes per pixel) MOD 4096 = 0
    748     }
    749     // end Carrizo workaround for 1D tilling
    750 
    751     return valid;
    752 }
    753 
    754 
    755 /**
    756 ****************************************************************************************************
    757 *   EgBasedLib::HwlReduceBankWidthHeight
    758 *
    759 *   @brief
    760 *       Additional checks, reduce bankHeight/bankWidth if needed and possible
    761 *       tileSize*BANK_WIDTH*BANK_HEIGHT <= ROW_SIZE
    762 *
    763 *   @return
    764 *       TRUE if no error occurs
    765 ****************************************************************************************************
    766 */
    767 BOOL_32 EgBasedLib::HwlReduceBankWidthHeight(
    768     UINT_32             tileSize,           ///< [in] tile size
    769     UINT_32             bpp,                ///< [in] bits per pixel
    770     ADDR_SURFACE_FLAGS  flags,              ///< [in] surface flags
    771     UINT_32             numSamples,         ///< [in] number of samples
    772     UINT_32             bankHeightAlign,    ///< [in] bank height alignment
    773     UINT_32             pipes,              ///< [in] pipes
    774     ADDR_TILEINFO*      pTileInfo           ///< [in,out] bank structure.
    775     ) const
    776 {
    777     UINT_32 macroAspectAlign;
    778     BOOL_32 valid = TRUE;
    779 
    780     if (tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize)
    781     {
    782         BOOL_32 stillGreater = TRUE;
    783 
    784         // Try reducing bankWidth first
    785         if (stillGreater && pTileInfo->bankWidth > 1)
    786         {
    787             while (stillGreater && pTileInfo->bankWidth > 0)
    788             {
    789                 pTileInfo->bankWidth >>= 1;
    790 
    791                 if (pTileInfo->bankWidth == 0)
    792                 {
    793                     pTileInfo->bankWidth = 1;
    794                     break;
    795                 }
    796 
    797                 stillGreater =
    798                     tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize;
    799             }
    800 
    801             // bankWidth is reduced above, so we need to recalculate bankHeight and ratio
    802             bankHeightAlign = Max(1u,
    803                                   m_pipeInterleaveBytes * m_bankInterleave /
    804                                   (tileSize * pTileInfo->bankWidth)
    805                                   );
    806 
    807             // We cannot increase bankHeight so just assert this case.
    808             ADDR_ASSERT((pTileInfo->bankHeight % bankHeightAlign) == 0);
    809 
    810             if (numSamples == 1)
    811             {
    812                 macroAspectAlign = Max(1u,
    813                                    m_pipeInterleaveBytes * m_bankInterleave /
    814                                    (tileSize * pipes * pTileInfo->bankWidth)
    815                                    );
    816                 pTileInfo->macroAspectRatio = PowTwoAlign(pTileInfo->macroAspectRatio,
    817                                                           macroAspectAlign);
    818             }
    819         }
    820 
    821         // Early quit bank_height degradation for "64" bit z buffer
    822         if (flags.depth && bpp >= 64)
    823         {
    824             stillGreater = FALSE;
    825         }
    826 
    827         // Then try reducing bankHeight
    828         if (stillGreater && pTileInfo->bankHeight > bankHeightAlign)
    829         {
    830             while (stillGreater && pTileInfo->bankHeight > bankHeightAlign)
    831             {
    832                 pTileInfo->bankHeight >>= 1;
    833 
    834                 if (pTileInfo->bankHeight < bankHeightAlign)
    835                 {
    836                     pTileInfo->bankHeight = bankHeightAlign;
    837                     break;
    838                 }
    839 
    840                 stillGreater =
    841                     tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize;
    842             }
    843         }
    844 
    845         valid = !stillGreater;
    846 
    847         // Generate a warning if we still fail to meet this constraint
    848         if (valid == FALSE)
    849         {
    850             ADDR_WARN(
    851                 0, ("TILE_SIZE(%d)*BANK_WIDTH(%d)*BANK_HEIGHT(%d) <= ROW_SIZE(%d)",
    852                 tileSize, pTileInfo->bankWidth, pTileInfo->bankHeight, m_rowSize));
    853         }
    854     }
    855 
    856     return valid;
    857 }
    858 
    859 /**
    860 ****************************************************************************************************
    861 *   EgBasedLib::ComputeSurfaceAlignmentsMacroTiled
    862 *
    863 *   @brief
    864 *       Compute 2D tiled surface alignment, calculation results are returned through
    865 *       output parameters.
    866 *
    867 *   @return
    868 *       TRUE if no error occurs
    869 ****************************************************************************************************
    870 */
    871 BOOL_32 EgBasedLib::ComputeSurfaceAlignmentsMacroTiled(
    872     AddrTileMode                      tileMode,           ///< [in] tile mode
    873     UINT_32                           bpp,                ///< [in] bits per pixel
    874     ADDR_SURFACE_FLAGS                flags,              ///< [in] surface flags
    875     UINT_32                           mipLevel,           ///< [in] mip level
    876     UINT_32                           numSamples,         ///< [in] number of samples
    877     ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut                ///< [in,out] Surface output
    878     ) const
    879 {
    880     ADDR_TILEINFO* pTileInfo = pOut->pTileInfo;
    881 
    882     BOOL_32 valid = SanityCheckMacroTiled(pTileInfo);
    883 
    884     if (valid)
    885     {
    886         UINT_32 macroTileWidth;
    887         UINT_32 macroTileHeight;
    888 
    889         UINT_32 tileSize;
    890         UINT_32 bankHeightAlign;
    891         UINT_32 macroAspectAlign;
    892 
    893         UINT_32 thickness = Thickness(tileMode);
    894         UINT_32 pipes = HwlGetPipes(pTileInfo);
    895 
    896         //
    897         // Align bank height first according to latest h/w spec
    898         //
    899 
    900         // tile_size = MIN(tile_split, 64 * tile_thickness * element_bytes * num_samples)
    901         tileSize = Min(pTileInfo->tileSplitBytes,
    902                        BITS_TO_BYTES(64 * thickness * bpp * numSamples));
    903 
    904         // bank_height_align =
    905         // MAX(1, (pipe_interleave_bytes * bank_interleave)/(tile_size*bank_width))
    906         bankHeightAlign = Max(1u,
    907                               m_pipeInterleaveBytes * m_bankInterleave /
    908                               (tileSize * pTileInfo->bankWidth)
    909                               );
    910 
    911         pTileInfo->bankHeight = PowTwoAlign(pTileInfo->bankHeight, bankHeightAlign);
    912 
    913         // num_pipes * bank_width * macro_tile_aspect >=
    914         // (pipe_interleave_size * bank_interleave) / tile_size
    915         if (numSamples == 1)
    916         {
    917             // this restriction is only for mipmap (mipmap's numSamples must be 1)
    918             macroAspectAlign = Max(1u,
    919                                    m_pipeInterleaveBytes * m_bankInterleave /
    920                                    (tileSize * pipes * pTileInfo->bankWidth)
    921                                    );
    922             pTileInfo->macroAspectRatio = PowTwoAlign(pTileInfo->macroAspectRatio, macroAspectAlign);
    923         }
    924 
    925         valid = HwlReduceBankWidthHeight(tileSize,
    926                                          bpp,
    927                                          flags,
    928                                          numSamples,
    929                                          bankHeightAlign,
    930                                          pipes,
    931                                          pTileInfo);
    932 
    933         //
    934         // The required granularity for pitch is the macro tile width.
    935         //
    936         macroTileWidth = MicroTileWidth * pTileInfo->bankWidth * pipes *
    937             pTileInfo->macroAspectRatio;
    938 
    939         pOut->pitchAlign = macroTileWidth;
    940         pOut->blockWidth = macroTileWidth;
    941 
    942         AdjustPitchAlignment(flags, &pOut->pitchAlign);
    943 
    944         //
    945         // The required granularity for height is the macro tile height.
    946         //
    947         macroTileHeight = MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks /
    948             pTileInfo->macroAspectRatio;
    949 
    950         pOut->heightAlign = macroTileHeight;
    951         pOut->blockHeight = macroTileHeight;
    952 
    953         //
    954         // Compute base alignment
    955         //
    956         pOut->baseAlign =
    957             pipes * pTileInfo->bankWidth * pTileInfo->banks * pTileInfo->bankHeight * tileSize;
    958 
    959         HwlComputeSurfaceAlignmentsMacroTiled(tileMode, bpp, flags, mipLevel, numSamples, pOut);
    960     }
    961 
    962     return valid;
    963 }
    964 
    965 /**
    966 ****************************************************************************************************
    967 *   EgBasedLib::SanityCheckMacroTiled
    968 *
    969 *   @brief
    970 *       Check if macro-tiled parameters are valid
    971 *   @return
    972 *       TRUE if valid
    973 ****************************************************************************************************
    974 */
    975 BOOL_32 EgBasedLib::SanityCheckMacroTiled(
    976     ADDR_TILEINFO* pTileInfo   ///< [in] macro-tiled parameters
    977     ) const
    978 {
    979     BOOL_32 valid       = TRUE;
    980     UINT_32 numPipes    = HwlGetPipes(pTileInfo);
    981 
    982     switch (pTileInfo->banks)
    983     {
    984         case 2: //fall through
    985         case 4: //fall through
    986         case 8: //fall through
    987         case 16:
    988             break;
    989         default:
    990             valid = FALSE;
    991             break;
    992 
    993     }
    994 
    995     if (valid)
    996     {
    997         switch (pTileInfo->bankWidth)
    998         {
    999             case 1: //fall through
   1000             case 2: //fall through
   1001             case 4: //fall through
   1002             case 8:
   1003                 break;
   1004             default:
   1005                 valid = FALSE;
   1006                 break;
   1007         }
   1008     }
   1009 
   1010     if (valid)
   1011     {
   1012         switch (pTileInfo->bankHeight)
   1013         {
   1014             case 1: //fall through
   1015             case 2: //fall through
   1016             case 4: //fall through
   1017             case 8:
   1018                 break;
   1019             default:
   1020                 valid = FALSE;
   1021                 break;
   1022         }
   1023     }
   1024 
   1025     if (valid)
   1026     {
   1027         switch (pTileInfo->macroAspectRatio)
   1028         {
   1029             case 1: //fall through
   1030             case 2: //fall through
   1031             case 4: //fall through
   1032             case 8:
   1033                 break;
   1034             default:
   1035                 valid = FALSE;
   1036                 break;
   1037         }
   1038     }
   1039 
   1040     if (valid)
   1041     {
   1042         if (pTileInfo->banks < pTileInfo->macroAspectRatio)
   1043         {
   1044             // This will generate macro tile height <= 1
   1045             valid = FALSE;
   1046         }
   1047     }
   1048 
   1049     if (valid)
   1050     {
   1051         if (pTileInfo->tileSplitBytes > m_rowSize)
   1052         {
   1053             ADDR_WARN(0, ("tileSplitBytes is bigger than row size"));
   1054         }
   1055     }
   1056 
   1057     if (valid)
   1058     {
   1059         valid = HwlSanityCheckMacroTiled(pTileInfo);
   1060     }
   1061 
   1062     ADDR_ASSERT(valid == TRUE);
   1063 
   1064     // Add this assert for guidance
   1065     ADDR_ASSERT(numPipes * pTileInfo->banks >= 4);
   1066 
   1067     return valid;
   1068 }
   1069 
   1070 /**
   1071 ****************************************************************************************************
   1072 *   EgBasedLib::ComputeSurfaceMipLevelTileMode
   1073 *
   1074 *   @brief
   1075 *       Compute valid tile mode for surface mipmap sub-levels
   1076 *
   1077 *   @return
   1078 *       Suitable tile mode
   1079 ****************************************************************************************************
   1080 */
   1081 AddrTileMode EgBasedLib::ComputeSurfaceMipLevelTileMode(
   1082     AddrTileMode        baseTileMode,   ///< [in] base tile mode
   1083     UINT_32             bpp,            ///< [in] bits per pixels
   1084     UINT_32             pitch,          ///< [in] current level pitch
   1085     UINT_32             height,         ///< [in] current level height
   1086     UINT_32             numSlices,      ///< [in] current number of slices
   1087     UINT_32             numSamples,     ///< [in] number of samples
   1088     UINT_32             pitchAlign,     ///< [in] pitch alignment
   1089     UINT_32             heightAlign,    ///< [in] height alignment
   1090     ADDR_TILEINFO*      pTileInfo       ///< [in] ptr to bank structure
   1091     ) const
   1092 {
   1093     UINT_64 bytesPerSlice;
   1094     (void)bytesPerSlice;
   1095     UINT_32 bytesPerTile;
   1096 
   1097     AddrTileMode expTileMode = baseTileMode;
   1098     UINT_32 microTileThickness = Thickness(expTileMode);
   1099     UINT_32 interleaveSize = m_pipeInterleaveBytes * m_bankInterleave;
   1100 
   1101     //
   1102     // Compute the size of a slice.
   1103     //
   1104     bytesPerSlice = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
   1105     bytesPerTile = BITS_TO_BYTES(MicroTilePixels * microTileThickness * NextPow2(bpp) * numSamples);
   1106 
   1107     //
   1108     // Reduce tiling mode from thick to thin if the number of slices is less than the
   1109     // micro tile thickness.
   1110     //
   1111     if (numSlices < microTileThickness)
   1112     {
   1113         expTileMode = HwlDegradeThickTileMode(expTileMode, numSlices, &bytesPerTile);
   1114     }
   1115 
   1116     if (bytesPerTile > pTileInfo->tileSplitBytes)
   1117     {
   1118         bytesPerTile = pTileInfo->tileSplitBytes;
   1119     }
   1120 
   1121     UINT_32 threshold1 =
   1122         bytesPerTile * HwlGetPipes(pTileInfo) * pTileInfo->bankWidth * pTileInfo->macroAspectRatio;
   1123 
   1124     UINT_32 threshold2 =
   1125         bytesPerTile * pTileInfo->bankWidth * pTileInfo->bankHeight;
   1126 
   1127     //
   1128     // Reduce the tile mode from 2D/3D to 1D in following conditions
   1129     //
   1130     switch (expTileMode)
   1131     {
   1132         case ADDR_TM_2D_TILED_THIN1: //fall through
   1133         case ADDR_TM_3D_TILED_THIN1:
   1134         case ADDR_TM_PRT_TILED_THIN1:
   1135         case ADDR_TM_PRT_2D_TILED_THIN1:
   1136         case ADDR_TM_PRT_3D_TILED_THIN1:
   1137             if ((pitch < pitchAlign) ||
   1138                 (height < heightAlign) ||
   1139                 (interleaveSize > threshold1) ||
   1140                 (interleaveSize > threshold2))
   1141             {
   1142                 expTileMode = ADDR_TM_1D_TILED_THIN1;
   1143             }
   1144             break;
   1145         case ADDR_TM_2D_TILED_THICK: //fall through
   1146         case ADDR_TM_3D_TILED_THICK:
   1147         case ADDR_TM_2D_TILED_XTHICK:
   1148         case ADDR_TM_3D_TILED_XTHICK:
   1149         case ADDR_TM_PRT_TILED_THICK:
   1150         case ADDR_TM_PRT_2D_TILED_THICK:
   1151         case ADDR_TM_PRT_3D_TILED_THICK:
   1152             if ((pitch < pitchAlign) ||
   1153                 (height < heightAlign))
   1154             {
   1155                 expTileMode = ADDR_TM_1D_TILED_THICK;
   1156             }
   1157             break;
   1158         default:
   1159             break;
   1160     }
   1161 
   1162     return expTileMode;
   1163 }
   1164 
   1165 /**
   1166 ****************************************************************************************************
   1167 *   EgBasedLib::HwlGetAlignmentInfoMacroTiled
   1168 *   @brief
   1169 *       Get alignment info for giving tile mode
   1170 *   @return
   1171 *       TRUE if getting alignment is OK
   1172 ****************************************************************************************************
   1173 */
   1174 BOOL_32 EgBasedLib::HwlGetAlignmentInfoMacroTiled(
   1175     const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,             ///< [in] create surface info
   1176     UINT_32*                               pPitchAlign,     ///< [out] pitch alignment
   1177     UINT_32*                               pHeightAlign,    ///< [out] height alignment
   1178     UINT_32*                               pSizeAlign       ///< [out] size alignment
   1179     ) const
   1180 {
   1181     BOOL_32 valid = TRUE;
   1182 
   1183     ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
   1184 
   1185     UINT_32 numSamples = (pIn->numFrags == 0) ? pIn->numSamples : pIn->numFrags;
   1186 
   1187     ADDR_ASSERT(pIn->pTileInfo);
   1188     ADDR_TILEINFO tileInfo = *pIn->pTileInfo;
   1189     ADDR_COMPUTE_SURFACE_INFO_OUTPUT out = {0};
   1190     out.pTileInfo = &tileInfo;
   1191 
   1192     if (UseTileIndex(pIn->tileIndex))
   1193     {
   1194         out.tileIndex = pIn->tileIndex;
   1195         out.macroModeIndex = TileIndexInvalid;
   1196     }
   1197 
   1198     HwlSetupTileInfo(pIn->tileMode,
   1199                      pIn->flags,
   1200                      pIn->bpp,
   1201                      pIn->width,
   1202                      pIn->height,
   1203                      numSamples,
   1204                      &tileInfo,
   1205                      &tileInfo,
   1206                      pIn->tileType,
   1207                      &out);
   1208 
   1209     valid = ComputeSurfaceAlignmentsMacroTiled(pIn->tileMode,
   1210                                                pIn->bpp,
   1211                                                pIn->flags,
   1212                                                pIn->mipLevel,
   1213                                                numSamples,
   1214                                                &out);
   1215 
   1216     if (valid)
   1217     {
   1218         *pPitchAlign  = out.pitchAlign;
   1219         *pHeightAlign = out.heightAlign;
   1220         *pSizeAlign   = out.baseAlign;
   1221     }
   1222 
   1223     return valid;
   1224 }
   1225 
   1226 /**
   1227 ****************************************************************************************************
   1228 *   EgBasedLib::HwlDegradeThickTileMode
   1229 *
   1230 *   @brief
   1231 *       Degrades valid tile mode for thick modes if needed
   1232 *
   1233 *   @return
   1234 *       Suitable tile mode
   1235 ****************************************************************************************************
   1236 */
   1237 AddrTileMode EgBasedLib::HwlDegradeThickTileMode(
   1238     AddrTileMode        baseTileMode,   ///< [in] base tile mode
   1239     UINT_32             numSlices,      ///< [in] current number of slices
   1240     UINT_32*            pBytesPerTile   ///< [in,out] pointer to bytes per slice
   1241     ) const
   1242 {
   1243     ADDR_ASSERT(numSlices < Thickness(baseTileMode));
   1244     // if pBytesPerTile is NULL, this is a don't-care....
   1245     UINT_32 bytesPerTile = pBytesPerTile != NULL ? *pBytesPerTile : 64;
   1246 
   1247     AddrTileMode expTileMode = baseTileMode;
   1248     switch (baseTileMode)
   1249     {
   1250         case ADDR_TM_1D_TILED_THICK:
   1251             expTileMode = ADDR_TM_1D_TILED_THIN1;
   1252             bytesPerTile >>= 2;
   1253             break;
   1254         case ADDR_TM_2D_TILED_THICK:
   1255             expTileMode = ADDR_TM_2D_TILED_THIN1;
   1256             bytesPerTile >>= 2;
   1257             break;
   1258         case ADDR_TM_3D_TILED_THICK:
   1259             expTileMode = ADDR_TM_3D_TILED_THIN1;
   1260             bytesPerTile >>= 2;
   1261             break;
   1262         case ADDR_TM_2D_TILED_XTHICK:
   1263             if (numSlices < ThickTileThickness)
   1264             {
   1265                 expTileMode = ADDR_TM_2D_TILED_THIN1;
   1266                 bytesPerTile >>= 3;
   1267             }
   1268             else
   1269             {
   1270                 expTileMode = ADDR_TM_2D_TILED_THICK;
   1271                 bytesPerTile >>= 1;
   1272             }
   1273             break;
   1274         case ADDR_TM_3D_TILED_XTHICK:
   1275             if (numSlices < ThickTileThickness)
   1276             {
   1277                 expTileMode = ADDR_TM_3D_TILED_THIN1;
   1278                 bytesPerTile >>= 3;
   1279             }
   1280             else
   1281             {
   1282                 expTileMode = ADDR_TM_3D_TILED_THICK;
   1283                 bytesPerTile >>= 1;
   1284             }
   1285             break;
   1286         default:
   1287             ADDR_ASSERT_ALWAYS();
   1288             break;
   1289     }
   1290 
   1291     if (pBytesPerTile != NULL)
   1292     {
   1293         *pBytesPerTile = bytesPerTile;
   1294     }
   1295 
   1296     return expTileMode;
   1297 }
   1298 
   1299 /**
   1300 ****************************************************************************************************
   1301 *   EgBasedLib::DispatchComputeSurfaceAddrFromCoord
   1302 *
   1303 *   @brief
   1304 *       Compute surface address from given coord (x, y, slice,sample)
   1305 *
   1306 *   @return
   1307 *       Address in bytes
   1308 ****************************************************************************************************
   1309 */
   1310 UINT_64 EgBasedLib::DispatchComputeSurfaceAddrFromCoord(
   1311     const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
   1312     ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
   1313     ) const
   1314 {
   1315     UINT_32             x                  = pIn->x;
   1316     UINT_32             y                  = pIn->y;
   1317     UINT_32             slice              = pIn->slice;
   1318     UINT_32             sample             = pIn->sample;
   1319     UINT_32             bpp                = pIn->bpp;
   1320     UINT_32             pitch              = pIn->pitch;
   1321     UINT_32             height             = pIn->height;
   1322     UINT_32             numSlices          = pIn->numSlices;
   1323     UINT_32             numSamples         = ((pIn->numSamples == 0) ? 1 : pIn->numSamples);
   1324     UINT_32             numFrags           = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
   1325     AddrTileMode        tileMode           = pIn->tileMode;
   1326     AddrTileType        microTileType      = pIn->tileType;
   1327     BOOL_32             ignoreSE           = pIn->ignoreSE;
   1328     BOOL_32             isDepthSampleOrder = pIn->isDepth;
   1329     ADDR_TILEINFO*      pTileInfo          = pIn->pTileInfo;
   1330 
   1331     UINT_32*            pBitPosition       = &pOut->bitPosition;
   1332     UINT_64             addr;
   1333 
   1334     // ADDR_DEPTH_SAMPLE_ORDER = non-disp + depth-sample-order
   1335     if (microTileType == ADDR_DEPTH_SAMPLE_ORDER)
   1336     {
   1337         isDepthSampleOrder = TRUE;
   1338     }
   1339 
   1340     if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
   1341     {
   1342         if (numFrags != numSamples)
   1343         {
   1344             numSamples = numFrags;
   1345             ADDR_ASSERT(sample < numSamples);
   1346         }
   1347 
   1348         /// @note
   1349         /// 128 bit/thick tiled surface doesn't support display tiling and
   1350         /// mipmap chain must have the same tileType, so please fill tileType correctly
   1351         if (IsLinear(pIn->tileMode) == FALSE)
   1352         {
   1353             if (bpp >= 128 || Thickness(tileMode) > 1)
   1354             {
   1355                 ADDR_ASSERT(microTileType != ADDR_DISPLAYABLE);
   1356             }
   1357         }
   1358     }
   1359 
   1360     switch (tileMode)
   1361     {
   1362         case ADDR_TM_LINEAR_GENERAL://fall through
   1363         case ADDR_TM_LINEAR_ALIGNED:
   1364             addr = ComputeSurfaceAddrFromCoordLinear(x,
   1365                                                      y,
   1366                                                      slice,
   1367                                                      sample,
   1368                                                      bpp,
   1369                                                      pitch,
   1370                                                      height,
   1371                                                      numSlices,
   1372                                                      pBitPosition);
   1373             break;
   1374         case ADDR_TM_1D_TILED_THIN1://fall through
   1375         case ADDR_TM_1D_TILED_THICK:
   1376             addr = ComputeSurfaceAddrFromCoordMicroTiled(x,
   1377                                                          y,
   1378                                                          slice,
   1379                                                          sample,
   1380                                                          bpp,
   1381                                                          pitch,
   1382                                                          height,
   1383                                                          numSamples,
   1384                                                          tileMode,
   1385                                                          microTileType,
   1386                                                          isDepthSampleOrder,
   1387                                                          pBitPosition);
   1388             break;
   1389         case ADDR_TM_2D_TILED_THIN1:    //fall through
   1390         case ADDR_TM_2D_TILED_THICK:    //fall through
   1391         case ADDR_TM_3D_TILED_THIN1:    //fall through
   1392         case ADDR_TM_3D_TILED_THICK:    //fall through
   1393         case ADDR_TM_2D_TILED_XTHICK:   //fall through
   1394         case ADDR_TM_3D_TILED_XTHICK:   //fall through
   1395         case ADDR_TM_PRT_TILED_THIN1:   //fall through
   1396         case ADDR_TM_PRT_2D_TILED_THIN1://fall through
   1397         case ADDR_TM_PRT_3D_TILED_THIN1://fall through
   1398         case ADDR_TM_PRT_TILED_THICK:   //fall through
   1399         case ADDR_TM_PRT_2D_TILED_THICK://fall through
   1400         case ADDR_TM_PRT_3D_TILED_THICK:
   1401             UINT_32 pipeSwizzle;
   1402             UINT_32 bankSwizzle;
   1403 
   1404             if (m_configFlags.useCombinedSwizzle)
   1405             {
   1406                 ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo,
   1407                                        &bankSwizzle, &pipeSwizzle);
   1408             }
   1409             else
   1410             {
   1411                 pipeSwizzle = pIn->pipeSwizzle;
   1412                 bankSwizzle = pIn->bankSwizzle;
   1413             }
   1414 
   1415             addr = ComputeSurfaceAddrFromCoordMacroTiled(x,
   1416                                                          y,
   1417                                                          slice,
   1418                                                          sample,
   1419                                                          bpp,
   1420                                                          pitch,
   1421                                                          height,
   1422                                                          numSamples,
   1423                                                          tileMode,
   1424                                                          microTileType,
   1425                                                          ignoreSE,
   1426                                                          isDepthSampleOrder,
   1427                                                          pipeSwizzle,
   1428                                                          bankSwizzle,
   1429                                                          pTileInfo,
   1430                                                          pBitPosition);
   1431             break;
   1432         default:
   1433             addr = 0;
   1434             ADDR_ASSERT_ALWAYS();
   1435             break;
   1436     }
   1437 
   1438     return addr;
   1439 }
   1440 
   1441 /**
   1442 ****************************************************************************************************
   1443 *   EgBasedLib::ComputeMacroTileEquation
   1444 *
   1445 *   @brief
   1446 *       Computes the address equation in macro tile
   1447 *   @return
   1448 *       If equation can be computed
   1449 ****************************************************************************************************
   1450 */
   1451 ADDR_E_RETURNCODE EgBasedLib::ComputeMacroTileEquation(
   1452     UINT_32             log2BytesPP,            ///< [in] log2 of bytes per pixel
   1453     AddrTileMode        tileMode,               ///< [in] tile mode
   1454     AddrTileType        microTileType,          ///< [in] micro tiling type
   1455     ADDR_TILEINFO*      pTileInfo,              ///< [in] bank structure
   1456     ADDR_EQUATION*      pEquation               ///< [out] Equation for addressing in macro tile
   1457     ) const
   1458 {
   1459     ADDR_E_RETURNCODE retCode;
   1460 
   1461     // Element equation within a tile
   1462     retCode = ComputeMicroTileEquation(log2BytesPP, tileMode, microTileType, pEquation);
   1463 
   1464     if (retCode == ADDR_OK)
   1465     {
   1466         // Tile equesiton with signle pipe bank
   1467         UINT_32 numPipes              = HwlGetPipes(pTileInfo);
   1468         UINT_32 numPipeBits           = Log2(numPipes);
   1469 
   1470         for (UINT_32 i = 0; i < Log2(pTileInfo->bankWidth); i++)
   1471         {
   1472             pEquation->addr[pEquation->numBits].valid = 1;
   1473             pEquation->addr[pEquation->numBits].channel = 0;
   1474             pEquation->addr[pEquation->numBits].index = i + log2BytesPP + 3 + numPipeBits;
   1475             pEquation->numBits++;
   1476         }
   1477 
   1478         for (UINT_32 i = 0; i < Log2(pTileInfo->bankHeight); i++)
   1479         {
   1480             pEquation->addr[pEquation->numBits].valid = 1;
   1481             pEquation->addr[pEquation->numBits].channel = 1;
   1482             pEquation->addr[pEquation->numBits].index = i + 3;
   1483             pEquation->numBits++;
   1484         }
   1485 
   1486         ADDR_EQUATION equation;
   1487         memset(&equation, 0, sizeof(ADDR_EQUATION));
   1488 
   1489         UINT_32 thresholdX = 32;
   1490         UINT_32 thresholdY = 32;
   1491 
   1492         if (IsPrtNoRotationTileMode(tileMode))
   1493         {
   1494             UINT_32 macroTilePitch  =
   1495                 (MicroTileWidth  * pTileInfo->bankWidth  * numPipes) * pTileInfo->macroAspectRatio;
   1496             UINT_32 macroTileHeight =
   1497                 (MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks) /
   1498                 pTileInfo->macroAspectRatio;
   1499             thresholdX = Log2(macroTilePitch);
   1500             thresholdY = Log2(macroTileHeight);
   1501         }
   1502 
   1503         // Pipe equation
   1504         retCode = ComputePipeEquation(log2BytesPP, thresholdX, thresholdY, pTileInfo, &equation);
   1505 
   1506         if (retCode == ADDR_OK)
   1507         {
   1508             UINT_32 pipeBitStart = Log2(m_pipeInterleaveBytes);
   1509 
   1510             if (pEquation->numBits > pipeBitStart)
   1511             {
   1512                 UINT_32 numLeftShift = pEquation->numBits - pipeBitStart;
   1513 
   1514                 for (UINT_32 i = 0; i < numLeftShift; i++)
   1515                 {
   1516                     pEquation->addr[pEquation->numBits + equation.numBits - i - 1] =
   1517                         pEquation->addr[pEquation->numBits - i - 1];
   1518                     pEquation->xor1[pEquation->numBits + equation.numBits - i - 1] =
   1519                         pEquation->xor1[pEquation->numBits - i - 1];
   1520                     pEquation->xor2[pEquation->numBits + equation.numBits - i - 1] =
   1521                         pEquation->xor2[pEquation->numBits - i - 1];
   1522                 }
   1523             }
   1524 
   1525             for (UINT_32 i = 0; i < equation.numBits; i++)
   1526             {
   1527                 pEquation->addr[pipeBitStart + i] = equation.addr[i];
   1528                 pEquation->xor1[pipeBitStart + i] = equation.xor1[i];
   1529                 pEquation->xor2[pipeBitStart + i] = equation.xor2[i];
   1530                 pEquation->numBits++;
   1531             }
   1532 
   1533             // Bank equation
   1534             memset(&equation, 0, sizeof(ADDR_EQUATION));
   1535 
   1536             retCode = ComputeBankEquation(log2BytesPP, thresholdX, thresholdY,
   1537                                           pTileInfo, &equation);
   1538 
   1539             if (retCode == ADDR_OK)
   1540             {
   1541                 UINT_32 bankBitStart = pipeBitStart + numPipeBits + Log2(m_bankInterleave);
   1542 
   1543                 if (pEquation->numBits > bankBitStart)
   1544                 {
   1545                     UINT_32 numLeftShift = pEquation->numBits - bankBitStart;
   1546 
   1547                     for (UINT_32 i = 0; i < numLeftShift; i++)
   1548                     {
   1549                         pEquation->addr[pEquation->numBits + equation.numBits - i - 1] =
   1550                             pEquation->addr[pEquation->numBits - i - 1];
   1551                         pEquation->xor1[pEquation->numBits + equation.numBits - i - 1] =
   1552                             pEquation->xor1[pEquation->numBits - i - 1];
   1553                         pEquation->xor2[pEquation->numBits + equation.numBits - i - 1] =
   1554                             pEquation->xor2[pEquation->numBits - i - 1];
   1555                     }
   1556                 }
   1557 
   1558                 for (UINT_32 i = 0; i < equation.numBits; i++)
   1559                 {
   1560                     pEquation->addr[bankBitStart + i] = equation.addr[i];
   1561                     pEquation->xor1[bankBitStart + i] = equation.xor1[i];
   1562                     pEquation->xor2[bankBitStart + i] = equation.xor2[i];
   1563                     pEquation->numBits++;
   1564                 }
   1565             }
   1566         }
   1567     }
   1568 
   1569     return retCode;
   1570 }
   1571 
   1572 /**
   1573 ****************************************************************************************************
   1574 *   EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
   1575 *
   1576 *   @brief
   1577 *       Computes the surface address and bit position from a
   1578 *       coordinate for 2D tilied (macro tiled)
   1579 *   @return
   1580 *       The byte address
   1581 ****************************************************************************************************
   1582 */
   1583 UINT_64 EgBasedLib::ComputeSurfaceAddrFromCoordMacroTiled(
   1584     UINT_32             x,                      ///< [in] x coordinate
   1585     UINT_32             y,                      ///< [in] y coordinate
   1586     UINT_32             slice,                  ///< [in] slice index
   1587     UINT_32             sample,                 ///< [in] sample index
   1588     UINT_32             bpp,                    ///< [in] bits per pixel
   1589     UINT_32             pitch,                  ///< [in] surface pitch, in pixels
   1590     UINT_32             height,                 ///< [in] surface height, in pixels
   1591     UINT_32             numSamples,             ///< [in] number of samples
   1592     AddrTileMode        tileMode,               ///< [in] tile mode
   1593     AddrTileType        microTileType,          ///< [in] micro tiling type
   1594     BOOL_32             ignoreSE,               ///< [in] TRUE if shader enginers can be ignored
   1595     BOOL_32             isDepthSampleOrder,     ///< [in] TRUE if it depth sample ordering is used
   1596     UINT_32             pipeSwizzle,            ///< [in] pipe swizzle
   1597     UINT_32             bankSwizzle,            ///< [in] bank swizzle
   1598     ADDR_TILEINFO*      pTileInfo,              ///< [in] bank structure
   1599                                                 ///  **All fields to be valid on entry**
   1600     UINT_32*            pBitPosition            ///< [out] bit position, e.g. FMT_1 will use this
   1601     ) const
   1602 {
   1603     UINT_64 addr;
   1604 
   1605     UINT_32 microTileBytes;
   1606     UINT_32 microTileBits;
   1607     UINT_32 sampleOffset;
   1608     UINT_32 pixelIndex;
   1609     UINT_32 pixelOffset;
   1610     UINT_32 elementOffset;
   1611     UINT_32 tileSplitSlice;
   1612     UINT_32 pipe;
   1613     UINT_32 bank;
   1614     UINT_64 sliceBytes;
   1615     UINT_64 sliceOffset;
   1616     UINT_32 macroTilePitch;
   1617     UINT_32 macroTileHeight;
   1618     UINT_32 macroTilesPerRow;
   1619     UINT_32 macroTilesPerSlice;
   1620     UINT_64 macroTileBytes;
   1621     UINT_32 macroTileIndexX;
   1622     UINT_32 macroTileIndexY;
   1623     UINT_64 macroTileOffset;
   1624     UINT_64 totalOffset;
   1625     UINT_64 pipeInterleaveMask;
   1626     UINT_64 bankInterleaveMask;
   1627     UINT_64 pipeInterleaveOffset;
   1628     UINT_32 bankInterleaveOffset;
   1629     UINT_64 offset;
   1630     UINT_32 tileRowIndex;
   1631     UINT_32 tileColumnIndex;
   1632     UINT_32 tileIndex;
   1633     UINT_32 tileOffset;
   1634 
   1635     UINT_32 microTileThickness = Thickness(tileMode);
   1636 
   1637     //
   1638     // Compute the number of group, pipe, and bank bits.
   1639     //
   1640     UINT_32 numPipes              = HwlGetPipes(pTileInfo);
   1641     UINT_32 numPipeInterleaveBits = Log2(m_pipeInterleaveBytes);
   1642     UINT_32 numPipeBits           = Log2(numPipes);
   1643     UINT_32 numBankInterleaveBits = Log2(m_bankInterleave);
   1644     UINT_32 numBankBits           = Log2(pTileInfo->banks);
   1645 
   1646     //
   1647     // Compute the micro tile size.
   1648     //
   1649     microTileBits = MicroTilePixels * microTileThickness * bpp * numSamples;
   1650 
   1651     microTileBytes = microTileBits / 8;
   1652     //
   1653     // Compute the pixel index within the micro tile.
   1654     //
   1655     pixelIndex = ComputePixelIndexWithinMicroTile(x,
   1656                                                   y,
   1657                                                   slice,
   1658                                                   bpp,
   1659                                                   tileMode,
   1660                                                   microTileType);
   1661 
   1662     //
   1663     // Compute the sample offset and pixel offset.
   1664     //
   1665     if (isDepthSampleOrder)
   1666     {
   1667         //
   1668         // For depth surfaces, samples are stored contiguously for each element, so the sample
   1669         // offset is the sample number times the element size.
   1670         //
   1671         sampleOffset = sample * bpp;
   1672         pixelOffset  = pixelIndex * bpp * numSamples;
   1673     }
   1674     else
   1675     {
   1676         //
   1677         // For color surfaces, all elements for a particular sample are stored contiguously, so
   1678         // the sample offset is the sample number times the micro tile size divided yBit the number
   1679         // of samples.
   1680         //
   1681         sampleOffset = sample * (microTileBits / numSamples);
   1682         pixelOffset  = pixelIndex * bpp;
   1683     }
   1684 
   1685     //
   1686     // Compute the element offset.
   1687     //
   1688     elementOffset = pixelOffset + sampleOffset;
   1689 
   1690     *pBitPosition = static_cast<UINT_32>(elementOffset % 8);
   1691 
   1692     elementOffset /= 8; //bit-to-byte
   1693 
   1694     //
   1695     // Determine if tiles need to be split across slices.
   1696     //
   1697     // If the size of the micro tile is larger than the tile split size, then the tile will be
   1698     // split across multiple slices.
   1699     //
   1700     UINT_32 slicesPerTile = 1;
   1701 
   1702     if ((microTileBytes > pTileInfo->tileSplitBytes) && (microTileThickness == 1))
   1703     {   //don't support for thick mode
   1704 
   1705         //
   1706         // Compute the number of slices per tile.
   1707         //
   1708         slicesPerTile = microTileBytes / pTileInfo->tileSplitBytes;
   1709 
   1710         //
   1711         // Compute the tile split slice number for use in rotating the bank.
   1712         //
   1713         tileSplitSlice = elementOffset / pTileInfo->tileSplitBytes;
   1714 
   1715         //
   1716         // Adjust the element offset to account for the portion of the tile that is being moved to
   1717         // a new slice..
   1718         //
   1719         elementOffset %= pTileInfo->tileSplitBytes;
   1720 
   1721         //
   1722         // Adjust the microTileBytes size to tileSplitBytes size since
   1723         // a new slice..
   1724         //
   1725         microTileBytes = pTileInfo->tileSplitBytes;
   1726     }
   1727     else
   1728     {
   1729         tileSplitSlice = 0;
   1730     }
   1731 
   1732     //
   1733     // Compute macro tile pitch and height.
   1734     //
   1735     macroTilePitch  =
   1736         (MicroTileWidth  * pTileInfo->bankWidth  * numPipes) * pTileInfo->macroAspectRatio;
   1737     macroTileHeight =
   1738         (MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks) / pTileInfo->macroAspectRatio;
   1739 
   1740     //
   1741     // Compute the number of bytes per macro tile. Note: bytes of the same bank/pipe actually
   1742     //
   1743     macroTileBytes =
   1744         static_cast<UINT_64>(microTileBytes) *
   1745         (macroTilePitch / MicroTileWidth) * (macroTileHeight / MicroTileHeight) /
   1746         (numPipes * pTileInfo->banks);
   1747 
   1748     //
   1749     // Compute the number of macro tiles per row.
   1750     //
   1751     macroTilesPerRow = pitch / macroTilePitch;
   1752 
   1753     //
   1754     // Compute the offset to the macro tile containing the specified coordinate.
   1755     //
   1756     macroTileIndexX = x / macroTilePitch;
   1757     macroTileIndexY = y / macroTileHeight;
   1758     macroTileOffset = ((macroTileIndexY * macroTilesPerRow) + macroTileIndexX) * macroTileBytes;
   1759 
   1760     //
   1761     // Compute the number of macro tiles per slice.
   1762     //
   1763     macroTilesPerSlice = macroTilesPerRow  * (height / macroTileHeight);
   1764 
   1765     //
   1766     // Compute the slice size.
   1767     //
   1768     sliceBytes = macroTilesPerSlice * macroTileBytes;
   1769 
   1770     //
   1771     // Compute the slice offset.
   1772     //
   1773     sliceOffset = sliceBytes * (tileSplitSlice + slicesPerTile * (slice / microTileThickness));
   1774 
   1775     //
   1776     // Compute tile offest
   1777     //
   1778     tileRowIndex    = (y / MicroTileHeight) % pTileInfo->bankHeight;
   1779     tileColumnIndex = ((x / MicroTileWidth) / numPipes) % pTileInfo->bankWidth;
   1780     tileIndex        = (tileRowIndex * pTileInfo->bankWidth) + tileColumnIndex;
   1781     tileOffset       = tileIndex * microTileBytes;
   1782 
   1783     //
   1784     // Combine the slice offset and macro tile offset with the pixel and sample offsets, accounting
   1785     // for the pipe and bank bits in the middle of the address.
   1786     //
   1787     totalOffset = sliceOffset + macroTileOffset + elementOffset + tileOffset;
   1788 
   1789     //
   1790     // Get the pipe and bank.
   1791     //
   1792 
   1793     // when the tileMode is PRT type, then adjust x and y coordinates
   1794     if (IsPrtNoRotationTileMode(tileMode))
   1795     {
   1796         x = x % macroTilePitch;
   1797         y = y % macroTileHeight;
   1798     }
   1799 
   1800     pipe = ComputePipeFromCoord(x,
   1801                                 y,
   1802                                 slice,
   1803                                 tileMode,
   1804                                 pipeSwizzle,
   1805                                 ignoreSE,
   1806                                 pTileInfo);
   1807 
   1808     bank = ComputeBankFromCoord(x,
   1809                                 y,
   1810                                 slice,
   1811                                 tileMode,
   1812                                 bankSwizzle,
   1813                                 tileSplitSlice,
   1814                                 pTileInfo);
   1815 
   1816 
   1817     //
   1818     // Split the offset to put some bits below the pipe+bank bits and some above.
   1819     //
   1820     pipeInterleaveMask = (1 << numPipeInterleaveBits) - 1;
   1821     bankInterleaveMask = (1 << numBankInterleaveBits) - 1;
   1822     pipeInterleaveOffset = totalOffset & pipeInterleaveMask;
   1823     bankInterleaveOffset = static_cast<UINT_32>((totalOffset >> numPipeInterleaveBits) &
   1824                                                 bankInterleaveMask);
   1825     offset               =  totalOffset >> (numPipeInterleaveBits + numBankInterleaveBits);
   1826 
   1827     //
   1828     // Assemble the address from its components.
   1829     //
   1830     addr  = pipeInterleaveOffset;
   1831     // This is to remove /analyze warnings
   1832     UINT_32 pipeBits            = pipe                 <<  numPipeInterleaveBits;
   1833     UINT_32 bankInterleaveBits  = bankInterleaveOffset << (numPipeInterleaveBits + numPipeBits);
   1834     UINT_32 bankBits            = bank                 << (numPipeInterleaveBits + numPipeBits +
   1835                                                            numBankInterleaveBits);
   1836     UINT_64 offsetBits          = offset               << (numPipeInterleaveBits + numPipeBits +
   1837                                                            numBankInterleaveBits + numBankBits);
   1838 
   1839     addr |= pipeBits;
   1840     addr |= bankInterleaveBits;
   1841     addr |= bankBits;
   1842     addr |= offsetBits;
   1843 
   1844     return addr;
   1845 }
   1846 
   1847 /**
   1848 ****************************************************************************************************
   1849 *   EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
   1850 *
   1851 *   @brief
   1852 *       Computes the surface address and bit position from a coordinate for 1D tilied
   1853 *       (micro tiled)
   1854 *   @return
   1855 *       The byte address
   1856 ****************************************************************************************************
   1857 */
   1858 UINT_64 EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled(
   1859     UINT_32             x,                      ///< [in] x coordinate
   1860     UINT_32             y,                      ///< [in] y coordinate
   1861     UINT_32             slice,                  ///< [in] slice index
   1862     UINT_32             sample,                 ///< [in] sample index
   1863     UINT_32             bpp,                    ///< [in] bits per pixel
   1864     UINT_32             pitch,                  ///< [in] pitch, in pixels
   1865     UINT_32             height,                 ///< [in] height, in pixels
   1866     UINT_32             numSamples,             ///< [in] number of samples
   1867     AddrTileMode        tileMode,               ///< [in] tile mode
   1868     AddrTileType        microTileType,          ///< [in] micro tiling type
   1869     BOOL_32             isDepthSampleOrder,     ///< [in] TRUE if depth sample ordering is used
   1870     UINT_32*            pBitPosition            ///< [out] bit position, e.g. FMT_1 will use this
   1871     ) const
   1872 {
   1873     UINT_64 addr = 0;
   1874 
   1875     UINT_32 microTileBytes;
   1876     UINT_64 sliceBytes;
   1877     UINT_32 microTilesPerRow;
   1878     UINT_32 microTileIndexX;
   1879     UINT_32 microTileIndexY;
   1880     UINT_32 microTileIndexZ;
   1881     UINT_64 sliceOffset;
   1882     UINT_64 microTileOffset;
   1883     UINT_32 sampleOffset;
   1884     UINT_32 pixelIndex;
   1885     UINT_32 pixelOffset;
   1886 
   1887     UINT_32 microTileThickness = Thickness(tileMode);
   1888 
   1889     //
   1890     // Compute the micro tile size.
   1891     //
   1892     microTileBytes = BITS_TO_BYTES(MicroTilePixels * microTileThickness * bpp * numSamples);
   1893 
   1894     //
   1895     // Compute the slice size.
   1896     //
   1897     sliceBytes =
   1898         BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * microTileThickness * bpp * numSamples);
   1899 
   1900     //
   1901     // Compute the number of micro tiles per row.
   1902     //
   1903     microTilesPerRow = pitch / MicroTileWidth;
   1904 
   1905     //
   1906     // Compute the micro tile index.
   1907     //
   1908     microTileIndexX = x     / MicroTileWidth;
   1909     microTileIndexY = y     / MicroTileHeight;
   1910     microTileIndexZ = slice / microTileThickness;
   1911 
   1912     //
   1913     // Compute the slice offset.
   1914     //
   1915     sliceOffset = static_cast<UINT_64>(microTileIndexZ) * sliceBytes;
   1916 
   1917     //
   1918     // Compute the offset to the micro tile containing the specified coordinate.
   1919     //
   1920     microTileOffset = (static_cast<UINT_64>(microTileIndexY) * microTilesPerRow + microTileIndexX) *
   1921         microTileBytes;
   1922 
   1923     //
   1924     // Compute the pixel index within the micro tile.
   1925     //
   1926     pixelIndex = ComputePixelIndexWithinMicroTile(x,
   1927                                                   y,
   1928                                                   slice,
   1929                                                   bpp,
   1930                                                   tileMode,
   1931                                                   microTileType);
   1932 
   1933     // Compute the sample offset.
   1934     //
   1935     if (isDepthSampleOrder)
   1936     {
   1937         //
   1938         // For depth surfaces, samples are stored contiguously for each element, so the sample
   1939         // offset is the sample number times the element size.
   1940         //
   1941         sampleOffset = sample * bpp;
   1942         pixelOffset = pixelIndex * bpp * numSamples;
   1943     }
   1944     else
   1945     {
   1946         //
   1947         // For color surfaces, all elements for a particular sample are stored contiguously, so
   1948         // the sample offset is the sample number times the micro tile size divided yBit the number
   1949         // of samples.
   1950         //
   1951         sampleOffset = sample * (microTileBytes*8 / numSamples);
   1952         pixelOffset = pixelIndex * bpp;
   1953     }
   1954 
   1955     //
   1956     // Compute the bit position of the pixel.  Each element is stored with one bit per sample.
   1957     //
   1958 
   1959     UINT_32 elemOffset = sampleOffset + pixelOffset;
   1960 
   1961     *pBitPosition = elemOffset % 8;
   1962     elemOffset /= 8;
   1963 
   1964     //
   1965     // Combine the slice offset, micro tile offset, sample offset, and pixel offsets.
   1966     //
   1967     addr = sliceOffset + microTileOffset + elemOffset;
   1968 
   1969     return addr;
   1970 }
   1971 
   1972 /**
   1973 ****************************************************************************************************
   1974 *   EgBasedLib::HwlComputePixelCoordFromOffset
   1975 *
   1976 *   @brief
   1977 *       Compute pixel coordinate from offset inside a micro tile
   1978 *   @return
   1979 *       N/A
   1980 ****************************************************************************************************
   1981 */
   1982 VOID EgBasedLib::HwlComputePixelCoordFromOffset(
   1983     UINT_32         offset,             ///< [in] offset inside micro tile in bits
   1984     UINT_32         bpp,                ///< [in] bits per pixel
   1985     UINT_32         numSamples,         ///< [in] number of samples
   1986     AddrTileMode    tileMode,           ///< [in] tile mode
   1987     UINT_32         tileBase,           ///< [in] base offset within a tile
   1988     UINT_32         compBits,           ///< [in] component bits actually needed(for planar surface)
   1989     UINT_32*        pX,                 ///< [out] x coordinate
   1990     UINT_32*        pY,                 ///< [out] y coordinate
   1991     UINT_32*        pSlice,             ///< [out] slice index
   1992     UINT_32*        pSample,            ///< [out] sample index
   1993     AddrTileType    microTileType,      ///< [in] micro tiling type
   1994     BOOL_32         isDepthSampleOrder  ///< [in] TRUE if depth sample order in microtile is used
   1995     ) const
   1996 {
   1997     UINT_32 x = 0;
   1998     UINT_32 y = 0;
   1999     UINT_32 z = 0;
   2000     UINT_32 thickness = Thickness(tileMode);
   2001 
   2002     // For planar surface, we adjust offset acoording to tile base
   2003     if ((bpp != compBits) && (compBits != 0) && isDepthSampleOrder)
   2004     {
   2005         offset -= tileBase;
   2006 
   2007         ADDR_ASSERT(microTileType == ADDR_NON_DISPLAYABLE ||
   2008                     microTileType == ADDR_DEPTH_SAMPLE_ORDER);
   2009 
   2010         bpp = compBits;
   2011     }
   2012 
   2013     UINT_32 sampleTileBits;
   2014     UINT_32 samplePixelBits;
   2015     UINT_32 pixelIndex;
   2016 
   2017     if (isDepthSampleOrder)
   2018     {
   2019         samplePixelBits = bpp * numSamples;
   2020         pixelIndex = offset / samplePixelBits;
   2021         *pSample = (offset % samplePixelBits) / bpp;
   2022     }
   2023     else
   2024     {
   2025         sampleTileBits = MicroTilePixels * bpp * thickness;
   2026         *pSample = offset / sampleTileBits;
   2027         pixelIndex = (offset % sampleTileBits) / bpp;
   2028     }
   2029 
   2030     if (microTileType != ADDR_THICK)
   2031     {
   2032         if (microTileType == ADDR_DISPLAYABLE) // displayable
   2033         {
   2034             switch (bpp)
   2035             {
   2036                 case 8:
   2037                     x = pixelIndex & 0x7;
   2038                     y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,4));
   2039                     break;
   2040                 case 16:
   2041                     x = pixelIndex & 0x7;
   2042                     y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,3));
   2043                     break;
   2044                 case 32:
   2045                     x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,1),_BIT(pixelIndex,0));
   2046                     y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,2));
   2047                     break;
   2048                 case 64:
   2049                     x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
   2050                     y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
   2051                     break;
   2052                 case 128:
   2053                     x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,2),_BIT(pixelIndex,1));
   2054                     y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,0));
   2055                     break;
   2056                 default:
   2057                     break;
   2058             }
   2059         }
   2060         else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER)
   2061         {
   2062             x = Bits2Number(3, _BIT(pixelIndex,4),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
   2063             y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
   2064         }
   2065         else if (microTileType == ADDR_ROTATED)
   2066         {
   2067             /*
   2068                 8-Bit Elements
   2069                 element_index[5:0] = { x[2], x[0], x[1], y[2], y[1], y[0] }
   2070 
   2071                 16-Bit Elements
   2072                 element_index[5:0] = { x[2], x[1], x[0], y[2], y[1], y[0] }
   2073 
   2074                 32-Bit Elements
   2075                 element_index[5:0] = { x[2], x[1], y[2], x[0], y[1], y[0] }
   2076 
   2077                 64-Bit Elements
   2078                 element_index[5:0] = { y[2], x[2], x[1], y[1], x[0], y[0] }
   2079             */
   2080             switch(bpp)
   2081             {
   2082                 case 8:
   2083                     x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,4));
   2084                     y = pixelIndex & 0x7;
   2085                     break;
   2086                 case 16:
   2087                     x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,3));
   2088                     y = pixelIndex & 0x7;
   2089                     break;
   2090                 case 32:
   2091                     x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,2));
   2092                     y = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,1),_BIT(pixelIndex,0));
   2093                     break;
   2094                 case 64:
   2095                     x = Bits2Number(3, _BIT(pixelIndex,4),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
   2096                     y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
   2097                     break;
   2098                 default:
   2099                     ADDR_ASSERT_ALWAYS();
   2100                     break;
   2101             }
   2102         }
   2103 
   2104         if (thickness > 1) // thick
   2105         {
   2106             z = Bits2Number(3, _BIT(pixelIndex,8),_BIT(pixelIndex,7),_BIT(pixelIndex,6));
   2107         }
   2108     }
   2109     else
   2110     {
   2111         ADDR_ASSERT((m_chipFamily >= ADDR_CHIP_FAMILY_CI) && (thickness > 1));
   2112         /*
   2113             8-Bit Elements and 16-Bit Elements
   2114             element_index[7:0] = { y[2], x[2], z[1], z[0], y[1], x[1], y[0], x[0] }
   2115 
   2116             32-Bit Elements
   2117             element_index[7:0] = { y[2], x[2], z[1], y[1], z[0], x[1], y[0], x[0] }
   2118 
   2119             64-Bit Elements and 128-Bit Elements
   2120             element_index[7:0] = { y[2], x[2], z[1], y[1], x[1], z[0], y[0], x[0] }
   2121 
   2122             The equation to compute the element index for the extra thick tile:
   2123             element_index[8] = z[2]
   2124         */
   2125         switch (bpp)
   2126         {
   2127             case 8:
   2128             case 16: // fall-through
   2129                 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
   2130                 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
   2131                 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,4));
   2132                 break;
   2133             case 32:
   2134                 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
   2135                 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
   2136                 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,3));
   2137                 break;
   2138             case 64:
   2139             case 128: // fall-through
   2140                 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,3),_BIT(pixelIndex,0));
   2141                 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
   2142                 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,2));
   2143                 break;
   2144             default:
   2145                 ADDR_ASSERT_ALWAYS();
   2146                 break;
   2147         }
   2148 
   2149         if (thickness == 8)
   2150         {
   2151             z += Bits2Number(3,_BIT(pixelIndex,8),0,0);
   2152         }
   2153     }
   2154 
   2155     *pX = x;
   2156     *pY = y;
   2157     *pSlice += z;
   2158 }
   2159 
   2160 
   2161 /**
   2162 ****************************************************************************************************
   2163 *   EgBasedLib::DispatchComputeSurfaceCoordFromAddrDispatch
   2164 *
   2165 *   @brief
   2166 *       Compute (x,y,slice,sample) coordinates from surface address
   2167 *   @return
   2168 *       N/A
   2169 ****************************************************************************************************
   2170 */
   2171 VOID EgBasedLib::DispatchComputeSurfaceCoordFromAddr(
   2172     const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure
   2173     ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure
   2174     ) const
   2175 {
   2176     UINT_64             addr               = pIn->addr;
   2177     UINT_32             bitPosition        = pIn->bitPosition;
   2178     UINT_32             bpp                = pIn->bpp;
   2179     UINT_32             pitch              = pIn->pitch;
   2180     UINT_32             height             = pIn->height;
   2181     UINT_32             numSlices          = pIn->numSlices;
   2182     UINT_32             numSamples         = ((pIn->numSamples == 0) ? 1 : pIn->numSamples);
   2183     UINT_32             numFrags           = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
   2184     AddrTileMode        tileMode           = pIn->tileMode;
   2185     UINT_32             tileBase           = pIn->tileBase;
   2186     UINT_32             compBits           = pIn->compBits;
   2187     AddrTileType        microTileType      = pIn->tileType;
   2188     BOOL_32             ignoreSE           = pIn->ignoreSE;
   2189     BOOL_32             isDepthSampleOrder = pIn->isDepth;
   2190     ADDR_TILEINFO*      pTileInfo          = pIn->pTileInfo;
   2191 
   2192     UINT_32*            pX                 = &pOut->x;
   2193     UINT_32*            pY                 = &pOut->y;
   2194     UINT_32*            pSlice             = &pOut->slice;
   2195     UINT_32*            pSample            = &pOut->sample;
   2196 
   2197     if (microTileType == ADDR_DEPTH_SAMPLE_ORDER)
   2198     {
   2199         isDepthSampleOrder = TRUE;
   2200     }
   2201 
   2202     if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
   2203     {
   2204         if (numFrags != numSamples)
   2205         {
   2206             numSamples = numFrags;
   2207         }
   2208 
   2209         /// @note
   2210         /// 128 bit/thick tiled surface doesn't support display tiling and
   2211         /// mipmap chain must have the same tileType, so please fill tileType correctly
   2212         if (IsLinear(pIn->tileMode) == FALSE)
   2213         {
   2214             if (bpp >= 128 || Thickness(tileMode) > 1)
   2215             {
   2216                 ADDR_ASSERT(microTileType != ADDR_DISPLAYABLE);
   2217             }
   2218         }
   2219     }
   2220 
   2221     switch (tileMode)
   2222     {
   2223         case ADDR_TM_LINEAR_GENERAL://fall through
   2224         case ADDR_TM_LINEAR_ALIGNED:
   2225             ComputeSurfaceCoordFromAddrLinear(addr,
   2226                                               bitPosition,
   2227                                               bpp,
   2228                                               pitch,
   2229                                               height,
   2230                                               numSlices,
   2231                                               pX,
   2232                                               pY,
   2233                                               pSlice,
   2234                                               pSample);
   2235             break;
   2236         case ADDR_TM_1D_TILED_THIN1://fall through
   2237         case ADDR_TM_1D_TILED_THICK:
   2238             ComputeSurfaceCoordFromAddrMicroTiled(addr,
   2239                                                   bitPosition,
   2240                                                   bpp,
   2241                                                   pitch,
   2242                                                   height,
   2243                                                   numSamples,
   2244                                                   tileMode,
   2245                                                   tileBase,
   2246                                                   compBits,
   2247                                                   pX,
   2248                                                   pY,
   2249                                                   pSlice,
   2250                                                   pSample,
   2251                                                   microTileType,
   2252                                                   isDepthSampleOrder);
   2253             break;
   2254         case ADDR_TM_2D_TILED_THIN1:    //fall through
   2255         case ADDR_TM_2D_TILED_THICK:    //fall through
   2256         case ADDR_TM_3D_TILED_THIN1:    //fall through
   2257         case ADDR_TM_3D_TILED_THICK:    //fall through
   2258         case ADDR_TM_2D_TILED_XTHICK:   //fall through
   2259         case ADDR_TM_3D_TILED_XTHICK:   //fall through
   2260         case ADDR_TM_PRT_TILED_THIN1:   //fall through
   2261         case ADDR_TM_PRT_2D_TILED_THIN1://fall through
   2262         case ADDR_TM_PRT_3D_TILED_THIN1://fall through
   2263         case ADDR_TM_PRT_TILED_THICK:   //fall through
   2264         case ADDR_TM_PRT_2D_TILED_THICK://fall through
   2265         case ADDR_TM_PRT_3D_TILED_THICK:
   2266             UINT_32 pipeSwizzle;
   2267             UINT_32 bankSwizzle;
   2268 
   2269             if (m_configFlags.useCombinedSwizzle)
   2270             {
   2271                 ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo,
   2272                                        &bankSwizzle, &pipeSwizzle);
   2273             }
   2274             else
   2275             {
   2276                 pipeSwizzle = pIn->pipeSwizzle;
   2277                 bankSwizzle = pIn->bankSwizzle;
   2278             }
   2279 
   2280             ComputeSurfaceCoordFromAddrMacroTiled(addr,
   2281                                                   bitPosition,
   2282                                                   bpp,
   2283                                                   pitch,
   2284                                                   height,
   2285                                                   numSamples,
   2286                                                   tileMode,
   2287                                                   tileBase,
   2288                                                   compBits,
   2289                                                   microTileType,
   2290                                                   ignoreSE,
   2291                                                   isDepthSampleOrder,
   2292                                                   pipeSwizzle,
   2293                                                   bankSwizzle,
   2294                                                   pTileInfo,
   2295                                                   pX,
   2296                                                   pY,
   2297                                                   pSlice,
   2298                                                   pSample);
   2299             break;
   2300         default:
   2301             ADDR_ASSERT_ALWAYS();
   2302     }
   2303 }
   2304 
   2305 
   2306 /**
   2307 ****************************************************************************************************
   2308 *   EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled
   2309 *
   2310 *   @brief
   2311 *       Compute surface coordinates from address for macro tiled surface
   2312 *   @return
   2313 *       N/A
   2314 ****************************************************************************************************
   2315 */
   2316 VOID EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled(
   2317     UINT_64             addr,               ///< [in] byte address
   2318     UINT_32             bitPosition,        ///< [in] bit position
   2319     UINT_32             bpp,                ///< [in] bits per pixel
   2320     UINT_32             pitch,              ///< [in] pitch in pixels
   2321     UINT_32             height,             ///< [in] height in pixels
   2322     UINT_32             numSamples,         ///< [in] number of samples
   2323     AddrTileMode        tileMode,           ///< [in] tile mode
   2324     UINT_32             tileBase,           ///< [in] tile base offset
   2325     UINT_32             compBits,           ///< [in] component bits (for planar surface)
   2326     AddrTileType        microTileType,      ///< [in] micro tiling type
   2327     BOOL_32             ignoreSE,           ///< [in] TRUE if shader engines can be ignored
   2328     BOOL_32             isDepthSampleOrder, ///< [in] TRUE if depth sample order is used
   2329     UINT_32             pipeSwizzle,        ///< [in] pipe swizzle
   2330     UINT_32             bankSwizzle,        ///< [in] bank swizzle
   2331     ADDR_TILEINFO*      pTileInfo,          ///< [in] bank structure.
   2332                                             ///  **All fields to be valid on entry**
   2333     UINT_32*            pX,                 ///< [out] X coord
   2334     UINT_32*            pY,                 ///< [out] Y coord
   2335     UINT_32*            pSlice,             ///< [out] slice index
   2336     UINT_32*            pSample             ///< [out] sample index
   2337     ) const
   2338 {
   2339     UINT_32 mx;
   2340     UINT_32 my;
   2341     UINT_64 tileBits;
   2342     UINT_64 macroTileBits;
   2343     UINT_32 slices;
   2344     UINT_32 tileSlices;
   2345     UINT_64 elementOffset;
   2346     UINT_64 macroTileIndex;
   2347     UINT_32 tileIndex;
   2348     UINT_64 totalOffset;
   2349 
   2350 
   2351     UINT_32 bank;
   2352     UINT_32 pipe;
   2353     UINT_32 groupBits = m_pipeInterleaveBytes << 3;
   2354     UINT_32 pipes = HwlGetPipes(pTileInfo);
   2355     UINT_32 banks = pTileInfo->banks;
   2356 
   2357     UINT_32 bankInterleave = m_bankInterleave;
   2358 
   2359     UINT_64 addrBits = BYTES_TO_BITS(addr) + bitPosition;
   2360 
   2361     //
   2362     // remove bits for bank and pipe
   2363     //
   2364     totalOffset = (addrBits % groupBits) +
   2365         (((addrBits / groupBits / pipes) % bankInterleave) * groupBits) +
   2366         (((addrBits / groupBits / pipes) / bankInterleave) / banks) * groupBits * bankInterleave;
   2367 
   2368     UINT_32 microTileThickness = Thickness(tileMode);
   2369 
   2370     UINT_32 microTileBits = bpp * microTileThickness * MicroTilePixels * numSamples;
   2371 
   2372     UINT_32 microTileBytes = BITS_TO_BYTES(microTileBits);
   2373     //
   2374     // Determine if tiles need to be split across slices.
   2375     //
   2376     // If the size of the micro tile is larger than the tile split size, then the tile will be
   2377     // split across multiple slices.
   2378     //
   2379     UINT_32 slicesPerTile = 1; //_State->TileSlices
   2380 
   2381     if ((microTileBytes > pTileInfo->tileSplitBytes) && (microTileThickness == 1))
   2382     {   //don't support for thick mode
   2383 
   2384         //
   2385         // Compute the number of slices per tile.
   2386         //
   2387         slicesPerTile = microTileBytes / pTileInfo->tileSplitBytes;
   2388     }
   2389 
   2390     tileBits = microTileBits / slicesPerTile; // micro tile bits
   2391 
   2392     // in micro tiles because not MicroTileWidth timed.
   2393     UINT_32 macroWidth  = pTileInfo->bankWidth * pipes * pTileInfo->macroAspectRatio;
   2394     // in micro tiles as well
   2395     UINT_32 macroHeight = pTileInfo->bankHeight * banks / pTileInfo->macroAspectRatio;
   2396 
   2397     UINT_32 pitchInMacroTiles = pitch / MicroTileWidth / macroWidth;
   2398 
   2399     macroTileBits = (macroWidth * macroHeight) * tileBits / (banks * pipes);
   2400 
   2401     macroTileIndex = totalOffset / macroTileBits;
   2402 
   2403     // pitchMacros * height / heightMacros;  macroTilesPerSlice == _State->SliceMacros
   2404     UINT_32 macroTilesPerSlice = (pitch / (macroWidth * MicroTileWidth)) * height /
   2405         (macroHeight * MicroTileWidth);
   2406 
   2407     slices = static_cast<UINT_32>(macroTileIndex / macroTilesPerSlice);
   2408 
   2409     *pSlice = static_cast<UINT_32>(slices / slicesPerTile * microTileThickness);
   2410 
   2411     //
   2412     // calculate element offset and x[2:0], y[2:0], z[1:0] for thick
   2413     //
   2414     tileSlices = slices % slicesPerTile;
   2415 
   2416     elementOffset  = tileSlices * tileBits;
   2417     elementOffset += totalOffset % tileBits;
   2418 
   2419     UINT_32 coordZ = 0;
   2420 
   2421     HwlComputePixelCoordFromOffset(static_cast<UINT_32>(elementOffset),
   2422                                    bpp,
   2423                                    numSamples,
   2424                                    tileMode,
   2425                                    tileBase,
   2426                                    compBits,
   2427                                    pX,
   2428                                    pY,
   2429                                    &coordZ,
   2430                                    pSample,
   2431                                    microTileType,
   2432                                    isDepthSampleOrder);
   2433 
   2434     macroTileIndex = macroTileIndex % macroTilesPerSlice;
   2435     *pY += static_cast<UINT_32>(macroTileIndex / pitchInMacroTiles * macroHeight * MicroTileHeight);
   2436     *pX += static_cast<UINT_32>(macroTileIndex % pitchInMacroTiles * macroWidth * MicroTileWidth);
   2437 
   2438     *pSlice += coordZ;
   2439 
   2440     tileIndex = static_cast<UINT_32>((totalOffset % macroTileBits) / tileBits);
   2441 
   2442     my = (tileIndex / pTileInfo->bankWidth) % pTileInfo->bankHeight * MicroTileHeight;
   2443     mx = (tileIndex % pTileInfo->bankWidth) * pipes * MicroTileWidth;
   2444 
   2445     *pY += my;
   2446     *pX += mx;
   2447 
   2448     bank = ComputeBankFromAddr(addr, banks, pipes);
   2449     pipe = ComputePipeFromAddr(addr, pipes);
   2450 
   2451     HwlComputeSurfaceCoord2DFromBankPipe(tileMode,
   2452                                          pX,
   2453                                          pY,
   2454                                          *pSlice,
   2455                                          bank,
   2456                                          pipe,
   2457                                          bankSwizzle,
   2458                                          pipeSwizzle,
   2459                                          tileSlices,
   2460                                          ignoreSE,
   2461                                          pTileInfo);
   2462 }
   2463 
   2464 /**
   2465 ****************************************************************************************************
   2466 *   EgBasedLib::ComputeSurfaceCoord2DFromBankPipe
   2467 *
   2468 *   @brief
   2469 *       Compute surface x,y coordinates from bank/pipe info
   2470 *   @return
   2471 *       N/A
   2472 ****************************************************************************************************
   2473 */
   2474 VOID EgBasedLib::ComputeSurfaceCoord2DFromBankPipe(
   2475     AddrTileMode        tileMode,   ///< [in] tile mode
   2476     UINT_32             x,          ///< [in] x coordinate
   2477     UINT_32             y,          ///< [in] y coordinate
   2478     UINT_32             slice,      ///< [in] slice index
   2479     UINT_32             bank,       ///< [in] bank number
   2480     UINT_32             pipe,       ///< [in] pipe number
   2481     UINT_32             bankSwizzle,///< [in] bank swizzle
   2482     UINT_32             pipeSwizzle,///< [in] pipe swizzle
   2483     UINT_32             tileSlices, ///< [in] slices in a micro tile
   2484     ADDR_TILEINFO*      pTileInfo,  ///< [in] bank structure. **All fields to be valid on entry**
   2485     CoordFromBankPipe*  pOutput     ///< [out] pointer to extracted x/y bits
   2486     ) const
   2487 {
   2488     UINT_32 yBit3 = 0;
   2489     UINT_32 yBit4 = 0;
   2490     UINT_32 yBit5 = 0;
   2491     UINT_32 yBit6 = 0;
   2492 
   2493     UINT_32 xBit3 = 0;
   2494     UINT_32 xBit4 = 0;
   2495     UINT_32 xBit5 = 0;
   2496 
   2497     UINT_32 tileSplitRotation;
   2498 
   2499     UINT_32 numPipes = HwlGetPipes(pTileInfo);
   2500 
   2501     UINT_32 bankRotation = ComputeBankRotation(tileMode,
   2502                                                pTileInfo->banks, numPipes);
   2503 
   2504     UINT_32 pipeRotation = ComputePipeRotation(tileMode, numPipes);
   2505 
   2506     UINT_32 xBit = x / (MicroTileWidth * pTileInfo->bankWidth * numPipes);
   2507     UINT_32 yBit = y / (MicroTileHeight * pTileInfo->bankHeight);
   2508 
   2509     //calculate the bank and pipe before rotation and swizzle
   2510 
   2511     switch (tileMode)
   2512     {
   2513         case ADDR_TM_2D_TILED_THIN1:  //fall through
   2514         case ADDR_TM_2D_TILED_THICK:  //fall through
   2515         case ADDR_TM_2D_TILED_XTHICK: //fall through
   2516         case ADDR_TM_3D_TILED_THIN1:  //fall through
   2517         case ADDR_TM_3D_TILED_THICK:  //fall through
   2518         case ADDR_TM_3D_TILED_XTHICK:
   2519             tileSplitRotation = ((pTileInfo->banks / 2) + 1);
   2520             break;
   2521         default:
   2522             tileSplitRotation =  0;
   2523             break;
   2524     }
   2525 
   2526     UINT_32 microTileThickness = Thickness(tileMode);
   2527 
   2528     bank ^= tileSplitRotation * tileSlices;
   2529     if (pipeRotation == 0)
   2530     {
   2531         bank ^= bankRotation * (slice / microTileThickness) + bankSwizzle;
   2532         bank %= pTileInfo->banks;
   2533         pipe ^= pipeSwizzle;
   2534     }
   2535     else
   2536     {
   2537         bank ^= bankRotation * (slice / microTileThickness) / numPipes + bankSwizzle;
   2538         bank %= pTileInfo->banks;
   2539         pipe ^= pipeRotation * (slice / microTileThickness) + pipeSwizzle;
   2540     }
   2541 
   2542     if (pTileInfo->macroAspectRatio == 1)
   2543     {
   2544         switch (pTileInfo->banks)
   2545         {
   2546             case 2:
   2547                 yBit3 = _BIT(bank, 0) ^ _BIT(xBit,0);
   2548                 break;
   2549             case 4:
   2550                 yBit4 = _BIT(bank, 0) ^ _BIT(xBit,0);
   2551                 yBit3 = _BIT(bank, 1) ^ _BIT(xBit,1);
   2552                 break;
   2553             case 8:
   2554                 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
   2555                 yBit5 = _BIT(bank, 0) ^ _BIT(xBit,0);
   2556                 yBit4 = _BIT(bank, 1) ^ _BIT(xBit,1) ^ yBit5;
   2557                 break;
   2558             case 16:
   2559                 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3);
   2560                 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2);
   2561                 yBit6 = _BIT(bank, 0) ^ _BIT(xBit, 0);
   2562                 yBit5 = _BIT(bank, 1) ^ _BIT(xBit, 1) ^ yBit6;
   2563                 break;
   2564             default:
   2565                 break;
   2566         }
   2567 
   2568     }
   2569     else if (pTileInfo->macroAspectRatio == 2)
   2570     {
   2571         switch (pTileInfo->banks)
   2572         {
   2573             case 2: //xBit3 = yBit3^b0
   2574                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,0);
   2575                 break;
   2576             case 4: //xBit3=yBit4^b0; yBit3=xBit4^b1
   2577                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,1);
   2578                 yBit3 = _BIT(bank, 1) ^ _BIT(xBit,1);
   2579                 break;
   2580             case 8: //xBit4, xBit5, yBit5 are known
   2581                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2);
   2582                 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
   2583                 yBit4 = _BIT(bank, 1) ^ _BIT(xBit,1) ^ _BIT(yBit, 2);
   2584                 break;
   2585             case 16://x4,x5,x6,y6 are known
   2586                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3); //x3 = y6 ^ b0
   2587                 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = x6 ^ b3
   2588                 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2); //y4 = x5 ^ b2
   2589                 yBit5 = _BIT(bank, 1) ^ _BIT(xBit, 1) ^ _BIT(yBit, 3); //y5=x4^y6^b1
   2590                 break;
   2591             default:
   2592                 break;
   2593         }
   2594     }
   2595     else if (pTileInfo->macroAspectRatio == 4)
   2596     {
   2597         switch (pTileInfo->banks)
   2598         {
   2599             case 4: //yBit3, yBit4
   2600                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,1);
   2601                 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,0);
   2602                 break;
   2603             case 8: //xBit5, yBit4, yBit5
   2604                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2);
   2605                 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
   2606                 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,1) ^  _BIT(yBit,2);
   2607                 break;
   2608             case 16: //xBit5, xBit6, yBit5, yBit6
   2609                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3);//x3 = b0 ^ y6
   2610                 xBit4 = _BIT(bank, 1) ^ _BIT(yBit, 2) ^ _BIT(yBit, 3);//x4 = b1 ^ y5 ^ y6;
   2611                 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = b3 ^ x6;
   2612                 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2); //y4 = b2 ^ x5;
   2613                 break;
   2614             default:
   2615                 break;
   2616         }
   2617     }
   2618     else if (pTileInfo->macroAspectRatio == 8)
   2619     {
   2620         switch (pTileInfo->banks)
   2621         {
   2622             case 8: //yBit3, yBit4, yBit5
   2623                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2); //x3 = b0 ^ y5;
   2624                 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,1) ^ _BIT(yBit, 2);//x4 = b1 ^ y4 ^ y5;
   2625                 xBit5 = _BIT(bank, 2) ^ _BIT(yBit,0);
   2626                 break;
   2627             case 16: //xBit6, yBit4, yBit5, yBit6
   2628                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3);//x3 = y6 ^ b0
   2629                 xBit4 = _BIT(bank, 1) ^ _BIT(yBit, 2) ^ _BIT(yBit, 3);//x4 = y5 ^ y6 ^ b1
   2630                 xBit5 = _BIT(bank, 2) ^ _BIT(yBit, 1);//x5 = y4 ^ b2
   2631                 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = x6 ^ b3
   2632                 break;
   2633             default:
   2634                 break;
   2635         }
   2636     }
   2637 
   2638     pOutput->xBits = xBit;
   2639     pOutput->yBits = yBit;
   2640 
   2641     pOutput->xBit3 = xBit3;
   2642     pOutput->xBit4 = xBit4;
   2643     pOutput->xBit5 = xBit5;
   2644     pOutput->yBit3 = yBit3;
   2645     pOutput->yBit4 = yBit4;
   2646     pOutput->yBit5 = yBit5;
   2647     pOutput->yBit6 = yBit6;
   2648 }
   2649 
   2650 /**
   2651 ****************************************************************************************************
   2652 *   EgBasedLib::HwlExtractBankPipeSwizzle
   2653 *   @brief
   2654 *       Entry of EgBasedLib ExtractBankPipeSwizzle
   2655 *   @return
   2656 *       ADDR_E_RETURNCODE
   2657 ****************************************************************************************************
   2658 */
   2659 ADDR_E_RETURNCODE EgBasedLib::HwlExtractBankPipeSwizzle(
   2660     const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT*  pIn,   ///< [in] input structure
   2661     ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT*       pOut   ///< [out] output structure
   2662     ) const
   2663 {
   2664     ExtractBankPipeSwizzle(pIn->base256b,
   2665                            pIn->pTileInfo,
   2666                            &pOut->bankSwizzle,
   2667                            &pOut->pipeSwizzle);
   2668 
   2669     return ADDR_OK;
   2670 }
   2671 
   2672 
   2673 /**
   2674 ****************************************************************************************************
   2675 *   EgBasedLib::HwlCombineBankPipeSwizzle
   2676 *   @brief
   2677 *       Combine bank/pipe swizzle
   2678 *   @return
   2679 *       ADDR_E_RETURNCODE
   2680 ****************************************************************************************************
   2681 */
   2682 ADDR_E_RETURNCODE EgBasedLib::HwlCombineBankPipeSwizzle(
   2683     UINT_32         bankSwizzle,    ///< [in] bank swizzle
   2684     UINT_32         pipeSwizzle,    ///< [in] pipe swizzle
   2685     ADDR_TILEINFO*  pTileInfo,      ///< [in] tile info
   2686     UINT_64         baseAddr,       ///< [in] base address
   2687     UINT_32*        pTileSwizzle    ///< [out] combined swizzle
   2688     ) const
   2689 {
   2690     ADDR_E_RETURNCODE retCode = ADDR_OK;
   2691 
   2692     if (pTileSwizzle)
   2693     {
   2694         *pTileSwizzle = GetBankPipeSwizzle(bankSwizzle, pipeSwizzle, baseAddr, pTileInfo);
   2695     }
   2696     else
   2697     {
   2698         retCode = ADDR_INVALIDPARAMS;
   2699     }
   2700 
   2701     return retCode;
   2702 }
   2703 
   2704 /**
   2705 ****************************************************************************************************
   2706 *   EgBasedLib::HwlComputeBaseSwizzle
   2707 *   @brief
   2708 *       Compute base swizzle
   2709 *   @return
   2710 *       ADDR_E_RETURNCODE
   2711 ****************************************************************************************************
   2712 */
   2713 ADDR_E_RETURNCODE EgBasedLib::HwlComputeBaseSwizzle(
   2714     const ADDR_COMPUTE_BASE_SWIZZLE_INPUT* pIn,
   2715     ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut
   2716     ) const
   2717 {
   2718     UINT_32 bankSwizzle = 0;
   2719     UINT_32 pipeSwizzle = 0;
   2720     ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
   2721 
   2722     ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
   2723     ADDR_ASSERT(pIn->pTileInfo);
   2724 
   2725     /// This is a legacy misreading of h/w doc, use it as it doesn't hurt.
   2726     static const UINT_8 bankRotationArray[4][16] = {
   2727         { 0, 0,  0, 0,  0, 0,  0, 0, 0,  0, 0,  0, 0,  0, 0, 0 }, // ADDR_SURF_2_BANK
   2728         { 0, 1,  2, 3,  0, 0,  0, 0, 0,  0, 0,  0, 0,  0, 0, 0 }, // ADDR_SURF_4_BANK
   2729         { 0, 3,  6, 1,  4, 7,  2, 5, 0,  0, 0,  0, 0,  0, 0, 0 }, // ADDR_SURF_8_BANK
   2730         { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }, // ADDR_SURF_16_BANK
   2731     };
   2732 
   2733     UINT_32 pipes = HwlGetPipes(pTileInfo);
   2734     (void)pipes;
   2735     UINT_32 banks = pTileInfo ? pTileInfo->banks : 2;
   2736     UINT_32 hwNumBanks;
   2737 
   2738     // Uses less bank swizzle bits
   2739     if (pIn->option.reduceBankBit && banks > 2)
   2740     {
   2741         banks >>= 1;
   2742     }
   2743 
   2744     switch (banks)
   2745     {
   2746         case 2:
   2747             hwNumBanks = 0;
   2748             break;
   2749         case 4:
   2750             hwNumBanks = 1;
   2751             break;
   2752         case 8:
   2753             hwNumBanks = 2;
   2754             break;
   2755         case 16:
   2756             hwNumBanks = 3;
   2757             break;
   2758         default:
   2759             ADDR_ASSERT_ALWAYS();
   2760             hwNumBanks = 0;
   2761             break;
   2762     }
   2763 
   2764     if (pIn->option.genOption == ADDR_SWIZZLE_GEN_LINEAR)
   2765     {
   2766         bankSwizzle = pIn->surfIndex & (banks - 1);
   2767     }
   2768     else // (pIn->option.genOption == ADDR_SWIZZLE_GEN_DEFAULT)
   2769     {
   2770         bankSwizzle = bankRotationArray[hwNumBanks][pIn->surfIndex & (banks - 1)];
   2771     }
   2772 
   2773     if (IsMacro3dTiled(pIn->tileMode))
   2774     {
   2775         pipeSwizzle = pIn->surfIndex & (HwlGetPipes(pTileInfo) - 1);
   2776     }
   2777 
   2778     return HwlCombineBankPipeSwizzle(bankSwizzle, pipeSwizzle, pTileInfo, 0, &pOut->tileSwizzle);
   2779 }
   2780 
   2781 /**
   2782 ****************************************************************************************************
   2783 *   EgBasedLib::ExtractBankPipeSwizzle
   2784 *   @brief
   2785 *       Extract bank/pipe swizzle from base256b
   2786 *   @return
   2787 *       N/A
   2788 ****************************************************************************************************
   2789 */
   2790 VOID EgBasedLib::ExtractBankPipeSwizzle(
   2791     UINT_32         base256b,       ///< [in] input base256b register value
   2792     ADDR_TILEINFO*  pTileInfo,      ///< [in] 2D tile parameters. Client must provide all data
   2793     UINT_32*        pBankSwizzle,   ///< [out] bank swizzle
   2794     UINT_32*        pPipeSwizzle    ///< [out] pipe swizzle
   2795     ) const
   2796 {
   2797     UINT_32 bankSwizzle = 0;
   2798     UINT_32 pipeSwizzle = 0;
   2799 
   2800     if (base256b != 0)
   2801     {
   2802         UINT_32 numPipes        = HwlGetPipes(pTileInfo);
   2803         UINT_32 bankBits        = QLog2(pTileInfo->banks);
   2804         UINT_32 pipeBits        = QLog2(numPipes);
   2805         UINT_32 groupBytes      = m_pipeInterleaveBytes;
   2806         UINT_32 bankInterleave  = m_bankInterleave;
   2807 
   2808         pipeSwizzle =
   2809             (base256b / (groupBytes >> 8)) & ((1<<pipeBits)-1);
   2810 
   2811         bankSwizzle =
   2812             (base256b / (groupBytes >> 8) / numPipes / bankInterleave) & ((1 << bankBits) - 1);
   2813     }
   2814 
   2815     *pPipeSwizzle = pipeSwizzle;
   2816     *pBankSwizzle = bankSwizzle;
   2817 }
   2818 
   2819 /**
   2820 ****************************************************************************************************
   2821 *   EgBasedLib::GetBankPipeSwizzle
   2822 *   @brief
   2823 *       Combine bank/pipe swizzle
   2824 *   @return
   2825 *       Base256b bits (only filled bank/pipe bits)
   2826 ****************************************************************************************************
   2827 */
   2828 UINT_32 EgBasedLib::GetBankPipeSwizzle(
   2829     UINT_32         bankSwizzle,    ///< [in] bank swizzle
   2830     UINT_32         pipeSwizzle,    ///< [in] pipe swizzle
   2831     UINT_64         baseAddr,       ///< [in] base address
   2832     ADDR_TILEINFO*  pTileInfo       ///< [in] tile info
   2833     ) const
   2834 {
   2835     UINT_32 pipeBits = QLog2(HwlGetPipes(pTileInfo));
   2836     UINT_32 bankInterleaveBits = QLog2(m_bankInterleave);
   2837     UINT_32 tileSwizzle = pipeSwizzle + ((bankSwizzle << bankInterleaveBits) << pipeBits);
   2838 
   2839     baseAddr ^= tileSwizzle * m_pipeInterleaveBytes;
   2840     baseAddr >>= 8;
   2841 
   2842     return static_cast<UINT_32>(baseAddr);
   2843 }
   2844 
   2845 /**
   2846 ****************************************************************************************************
   2847 *   EgBasedLib::ComputeSliceTileSwizzle
   2848 *   @brief
   2849 *       Compute cubemap/3d texture faces/slices tile swizzle
   2850 *   @return
   2851 *       Tile swizzle
   2852 ****************************************************************************************************
   2853 */
   2854 UINT_32 EgBasedLib::ComputeSliceTileSwizzle(
   2855     AddrTileMode        tileMode,       ///< [in] Tile mode
   2856     UINT_32             baseSwizzle,    ///< [in] Base swizzle
   2857     UINT_32             slice,          ///< [in] Slice index, Cubemap face index, 0 means +X
   2858     UINT_64             baseAddr,       ///< [in] Base address
   2859     ADDR_TILEINFO* pTileInfo       ///< [in] Bank structure
   2860     ) const
   2861 {
   2862     UINT_32 tileSwizzle = 0;
   2863 
   2864     if (IsMacroTiled(tileMode)) // Swizzle only for macro tile mode
   2865     {
   2866         UINT_32 firstSlice = slice / Thickness(tileMode);
   2867 
   2868         UINT_32 numPipes = HwlGetPipes(pTileInfo);
   2869         UINT_32 numBanks = pTileInfo->banks;
   2870 
   2871         UINT_32 pipeRotation;
   2872         UINT_32 bankRotation;
   2873 
   2874         UINT_32 bankSwizzle = 0;
   2875         UINT_32 pipeSwizzle = 0;
   2876 
   2877         pipeRotation = ComputePipeRotation(tileMode, numPipes);
   2878         bankRotation = ComputeBankRotation(tileMode, numBanks, numPipes);
   2879 
   2880         if (baseSwizzle != 0)
   2881         {
   2882             ExtractBankPipeSwizzle(baseSwizzle,
   2883                                    pTileInfo,
   2884                                    &bankSwizzle,
   2885                                    &pipeSwizzle);
   2886         }
   2887 
   2888         if (pipeRotation == 0) //2D mode
   2889         {
   2890             bankSwizzle += firstSlice * bankRotation;
   2891             bankSwizzle %= numBanks;
   2892         }
   2893         else //3D mode
   2894         {
   2895             pipeSwizzle += firstSlice * pipeRotation;
   2896             pipeSwizzle %= numPipes;
   2897             bankSwizzle += firstSlice * bankRotation / numPipes;
   2898             bankSwizzle %= numBanks;
   2899         }
   2900 
   2901         tileSwizzle = GetBankPipeSwizzle(bankSwizzle,
   2902                                          pipeSwizzle,
   2903                                          baseAddr,
   2904                                          pTileInfo);
   2905     }
   2906 
   2907     return tileSwizzle;
   2908 }
   2909 
   2910 /**
   2911 ****************************************************************************************************
   2912 *   EgBasedLib::HwlComputeQbStereoRightSwizzle
   2913 *
   2914 *   @brief
   2915 *       Compute right eye swizzle
   2916 *   @return
   2917 *       swizzle
   2918 ****************************************************************************************************
   2919 */
   2920 UINT_32 EgBasedLib::HwlComputeQbStereoRightSwizzle(
   2921     ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pInfo  ///< [in] Surface info, must be valid
   2922     ) const
   2923 {
   2924     UINT_32 bankBits    = 0;
   2925     UINT_32 swizzle     = 0;
   2926 
   2927     // The assumption is default swizzle for left eye is 0
   2928     if (IsMacroTiled(pInfo->tileMode) && pInfo->pStereoInfo && pInfo->pTileInfo)
   2929     {
   2930         bankBits = ComputeBankFromCoord(0, pInfo->height, 0,
   2931                                         pInfo->tileMode, 0, 0, pInfo->pTileInfo);
   2932 
   2933         if (bankBits)
   2934         {
   2935             HwlCombineBankPipeSwizzle(bankBits, 0, pInfo->pTileInfo, 0, &swizzle);
   2936         }
   2937     }
   2938 
   2939     return swizzle;
   2940 }
   2941 
   2942 /**
   2943 ****************************************************************************************************
   2944 *   EgBasedLib::ComputeBankFromCoord
   2945 *
   2946 *   @brief
   2947 *       Compute bank number from coordinates
   2948 *   @return
   2949 *       Bank number
   2950 ****************************************************************************************************
   2951 */
   2952 UINT_32 EgBasedLib::ComputeBankFromCoord(
   2953     UINT_32         x,              ///< [in] x coordinate
   2954     UINT_32         y,              ///< [in] y coordinate
   2955     UINT_32         slice,          ///< [in] slice index
   2956     AddrTileMode    tileMode,       ///< [in] tile mode
   2957     UINT_32         bankSwizzle,    ///< [in] bank swizzle
   2958     UINT_32         tileSplitSlice, ///< [in] If the size of the pixel offset is larger than the
   2959                                     ///  tile split size, then the pixel will be moved to a separate
   2960                                     ///  slice. This value equals pixelOffset / tileSplitBytes
   2961                                     ///  in this case. Otherwise this is 0.
   2962     ADDR_TILEINFO*  pTileInfo       ///< [in] tile info
   2963     ) const
   2964 {
   2965     UINT_32 pipes = HwlGetPipes(pTileInfo);
   2966     UINT_32 bankBit0 = 0;
   2967     UINT_32 bankBit1 = 0;
   2968     UINT_32 bankBit2 = 0;
   2969     UINT_32 bankBit3 = 0;
   2970     UINT_32 sliceRotation;
   2971     UINT_32 tileSplitRotation;
   2972     UINT_32 bank;
   2973     UINT_32 numBanks    = pTileInfo->banks;
   2974     UINT_32 bankWidth   = pTileInfo->bankWidth;
   2975     UINT_32 bankHeight  = pTileInfo->bankHeight;
   2976 
   2977     UINT_32 tx = x / MicroTileWidth / (bankWidth * pipes);
   2978     UINT_32 ty = y / MicroTileHeight / bankHeight;
   2979 
   2980     UINT_32 x3 = _BIT(tx,0);
   2981     UINT_32 x4 = _BIT(tx,1);
   2982     UINT_32 x5 = _BIT(tx,2);
   2983     UINT_32 x6 = _BIT(tx,3);
   2984     UINT_32 y3 = _BIT(ty,0);
   2985     UINT_32 y4 = _BIT(ty,1);
   2986     UINT_32 y5 = _BIT(ty,2);
   2987     UINT_32 y6 = _BIT(ty,3);
   2988 
   2989     switch (numBanks)
   2990     {
   2991         case 16:
   2992             bankBit0 = x3 ^ y6;
   2993             bankBit1 = x4 ^ y5 ^ y6;
   2994             bankBit2 = x5 ^ y4;
   2995             bankBit3 = x6 ^ y3;
   2996             break;
   2997         case 8:
   2998             bankBit0 = x3 ^ y5;
   2999             bankBit1 = x4 ^ y4 ^ y5;
   3000             bankBit2 = x5 ^ y3;
   3001             break;
   3002         case 4:
   3003             bankBit0 = x3 ^ y4;
   3004             bankBit1 = x4 ^ y3;
   3005             break;
   3006         case 2:
   3007             bankBit0 = x3 ^ y3;
   3008             break;
   3009         default:
   3010             ADDR_ASSERT_ALWAYS();
   3011             break;
   3012     }
   3013 
   3014     bank = bankBit0 | (bankBit1 << 1) | (bankBit2 << 2) | (bankBit3 << 3);
   3015 
   3016     //Bits2Number(4, bankBit3, bankBit2, bankBit1, bankBit0);
   3017 
   3018     bank = HwlPreAdjustBank((x / MicroTileWidth), bank, pTileInfo);
   3019     //
   3020     // Compute bank rotation for the slice.
   3021     //
   3022     UINT_32 microTileThickness = Thickness(tileMode);
   3023 
   3024     switch (tileMode)
   3025     {
   3026         case ADDR_TM_2D_TILED_THIN1:  // fall through
   3027         case ADDR_TM_2D_TILED_THICK:  // fall through
   3028         case ADDR_TM_2D_TILED_XTHICK:
   3029             sliceRotation = ((numBanks / 2) - 1) * (slice / microTileThickness);
   3030             break;
   3031         case ADDR_TM_3D_TILED_THIN1:  // fall through
   3032         case ADDR_TM_3D_TILED_THICK:  // fall through
   3033         case ADDR_TM_3D_TILED_XTHICK:
   3034             sliceRotation =
   3035                 Max(1u, (pipes / 2) - 1) * (slice / microTileThickness) / pipes;
   3036             break;
   3037         default:
   3038             sliceRotation =  0;
   3039             break;
   3040     }
   3041 
   3042 
   3043     //
   3044     // Compute bank rotation for the tile split slice.
   3045     //
   3046     // The sample slice will be non-zero if samples must be split across multiple slices.
   3047     // This situation arises when the micro tile size multiplied yBit the number of samples exceeds
   3048     // the split size (set in GB_ADDR_CONFIG).
   3049     //
   3050     switch (tileMode)
   3051     {
   3052         case ADDR_TM_2D_TILED_THIN1: //fall through
   3053         case ADDR_TM_3D_TILED_THIN1: //fall through
   3054         case ADDR_TM_PRT_2D_TILED_THIN1: //fall through
   3055         case ADDR_TM_PRT_3D_TILED_THIN1: //fall through
   3056             tileSplitRotation = ((numBanks / 2) + 1) * tileSplitSlice;
   3057             break;
   3058         default:
   3059             tileSplitRotation =  0;
   3060             break;
   3061     }
   3062 
   3063     //
   3064     // Apply bank rotation for the slice and tile split slice.
   3065     //
   3066     bank ^= bankSwizzle + sliceRotation;
   3067     bank ^= tileSplitRotation;
   3068 
   3069     bank &= (numBanks - 1);
   3070 
   3071     return bank;
   3072 }
   3073 
   3074 /**
   3075 ****************************************************************************************************
   3076 *   EgBasedLib::ComputeBankFromAddr
   3077 *
   3078 *   @brief
   3079 *       Compute the bank number from an address
   3080 *   @return
   3081 *       Bank number
   3082 ****************************************************************************************************
   3083 */
   3084 UINT_32 EgBasedLib::ComputeBankFromAddr(
   3085     UINT_64 addr,       ///< [in] address
   3086     UINT_32 numBanks,   ///< [in] number of banks
   3087     UINT_32 numPipes    ///< [in] number of pipes
   3088     ) const
   3089 {
   3090     UINT_32 bank;
   3091 
   3092     //
   3093     // The LSBs of the address are arranged as follows:
   3094     //   bank | bankInterleave | pipe | pipeInterleave
   3095     //
   3096     // To get the bank number, shift off the pipe interleave, pipe, and bank interlave bits and
   3097     // mask the bank bits.
   3098     //
   3099     bank = static_cast<UINT_32>(
   3100         (addr >> Log2(m_pipeInterleaveBytes * numPipes * m_bankInterleave)) &
   3101         (numBanks - 1)
   3102         );
   3103 
   3104     return bank;
   3105 }
   3106 
   3107 /**
   3108 ****************************************************************************************************
   3109 *   EgBasedLib::ComputePipeRotation
   3110 *
   3111 *   @brief
   3112 *       Compute pipe rotation value
   3113 *   @return
   3114 *       Pipe rotation
   3115 ****************************************************************************************************
   3116 */
   3117 UINT_32 EgBasedLib::ComputePipeRotation(
   3118     AddrTileMode tileMode,  ///< [in] tile mode
   3119     UINT_32      numPipes   ///< [in] number of pipes
   3120     ) const
   3121 {
   3122    UINT_32 rotation;
   3123 
   3124     switch (tileMode)
   3125     {
   3126         case ADDR_TM_3D_TILED_THIN1:        //fall through
   3127         case ADDR_TM_3D_TILED_THICK:        //fall through
   3128         case ADDR_TM_3D_TILED_XTHICK:       //fall through
   3129         case ADDR_TM_PRT_3D_TILED_THIN1:    //fall through
   3130         case ADDR_TM_PRT_3D_TILED_THICK:
   3131             rotation = (numPipes < 4) ? 1 : (numPipes / 2 - 1);
   3132             break;
   3133         default:
   3134             rotation = 0;
   3135     }
   3136 
   3137     return rotation;
   3138 }
   3139 
   3140 
   3141 
   3142 /**
   3143 ****************************************************************************************************
   3144 *   EgBasedLib::ComputeBankRotation
   3145 *
   3146 *   @brief
   3147 *       Compute bank rotation value
   3148 *   @return
   3149 *       Bank rotation
   3150 ****************************************************************************************************
   3151 */
   3152 UINT_32 EgBasedLib::ComputeBankRotation(
   3153     AddrTileMode tileMode,  ///< [in] tile mode
   3154     UINT_32      numBanks,  ///< [in] number of banks
   3155     UINT_32      numPipes   ///< [in] number of pipes
   3156     ) const
   3157 {
   3158     UINT_32 rotation;
   3159 
   3160     switch (tileMode)
   3161     {
   3162         case ADDR_TM_2D_TILED_THIN1: // fall through
   3163         case ADDR_TM_2D_TILED_THICK: // fall through
   3164         case ADDR_TM_2D_TILED_XTHICK:
   3165         case ADDR_TM_PRT_2D_TILED_THIN1:
   3166         case ADDR_TM_PRT_2D_TILED_THICK:
   3167             // Rotate banks per Z-slice yBit 1 for 4-bank or 3 for 8-bank
   3168             rotation =  numBanks / 2 - 1;
   3169             break;
   3170         case ADDR_TM_3D_TILED_THIN1: // fall through
   3171         case ADDR_TM_3D_TILED_THICK: // fall through
   3172         case ADDR_TM_3D_TILED_XTHICK:
   3173         case ADDR_TM_PRT_3D_TILED_THIN1:
   3174         case ADDR_TM_PRT_3D_TILED_THICK:
   3175             rotation = (numPipes < 4) ? 1 : (numPipes / 2 - 1);    // rotate pipes & banks
   3176             break;
   3177         default:
   3178             rotation = 0;
   3179     }
   3180 
   3181     return rotation;
   3182 }
   3183 
   3184 
   3185 /**
   3186 ****************************************************************************************************
   3187 *   EgBasedLib::ComputeHtileBytes
   3188 *
   3189 *   @brief
   3190 *       Compute htile size in bytes
   3191 *
   3192 *   @return
   3193 *       Htile size in bytes
   3194 ****************************************************************************************************
   3195 */
   3196 UINT_64 EgBasedLib::ComputeHtileBytes(
   3197     UINT_32 pitch,        ///< [in] pitch
   3198     UINT_32 height,       ///< [in] height
   3199     UINT_32 bpp,          ///< [in] bits per pixel
   3200     BOOL_32 isLinear,     ///< [in] if it is linear mode
   3201     UINT_32 numSlices,    ///< [in] number of slices
   3202     UINT_64* sliceBytes,  ///< [out] bytes per slice
   3203     UINT_32 baseAlign     ///< [in] base alignments
   3204     ) const
   3205 {
   3206     UINT_64 surfBytes;
   3207 
   3208     const UINT_64 HtileCacheLineSize = BITS_TO_BYTES(HtileCacheBits);
   3209 
   3210     *sliceBytes = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp / 64);
   3211 
   3212     if (m_configFlags.useHtileSliceAlign)
   3213     {
   3214         // Align the sliceSize to htilecachelinesize * pipes at first
   3215         *sliceBytes = PowTwoAlign(*sliceBytes, HtileCacheLineSize * m_pipes);
   3216         surfBytes  = *sliceBytes * numSlices;
   3217     }
   3218     else
   3219     {
   3220         // Align the surfSize to htilecachelinesize * pipes at last
   3221         surfBytes  = *sliceBytes * numSlices;
   3222         surfBytes  = PowTwoAlign(surfBytes, HtileCacheLineSize * m_pipes);
   3223     }
   3224 
   3225     return surfBytes;
   3226 }
   3227 
   3228 /**
   3229 ****************************************************************************************************
   3230 *   EgBasedLib::DispatchComputeFmaskInfo
   3231 *
   3232 *   @brief
   3233 *       Compute fmask sizes include padded pitch, height, slices, total size in bytes,
   3234 *       meanwhile output suitable tile mode and alignments as well. Results are returned
   3235 *       through output parameters.
   3236 *
   3237 *   @return
   3238 *       ADDR_E_RETURNCODE
   3239 ****************************************************************************************************
   3240 */
   3241 ADDR_E_RETURNCODE EgBasedLib::DispatchComputeFmaskInfo(
   3242     const ADDR_COMPUTE_FMASK_INFO_INPUT*    pIn,   ///< [in] input structure
   3243     ADDR_COMPUTE_FMASK_INFO_OUTPUT*         pOut)  ///< [out] output structure
   3244 {
   3245     ADDR_E_RETURNCODE retCode = ADDR_OK;
   3246 
   3247     ADDR_COMPUTE_SURFACE_INFO_INPUT  surfIn     = {0};
   3248     ADDR_COMPUTE_SURFACE_INFO_OUTPUT surfOut    = {0};
   3249 
   3250     // Setup input structure
   3251     surfIn.tileMode          = pIn->tileMode;
   3252     surfIn.width             = pIn->pitch;
   3253     surfIn.height            = pIn->height;
   3254     surfIn.numSlices         = pIn->numSlices;
   3255     surfIn.pTileInfo         = pIn->pTileInfo;
   3256     surfIn.tileType          = ADDR_NON_DISPLAYABLE;
   3257     surfIn.flags.fmask       = 1;
   3258 
   3259     // Setup output structure
   3260     surfOut.pTileInfo       = pOut->pTileInfo;
   3261 
   3262     // Setup hwl specific fields
   3263     HwlFmaskPreThunkSurfInfo(pIn, pOut, &surfIn, &surfOut);
   3264 
   3265     surfIn.bpp = HwlComputeFmaskBits(pIn, &surfIn.numSamples);
   3266 
   3267     // ComputeSurfaceInfo needs numSamples in surfOut as surface routines need adjusted numSamples
   3268     surfOut.numSamples = surfIn.numSamples;
   3269 
   3270     retCode = HwlComputeSurfaceInfo(&surfIn, &surfOut);
   3271 
   3272     // Save bpp field for surface dump support
   3273     surfOut.bpp = surfIn.bpp;
   3274 
   3275     if (retCode == ADDR_OK)
   3276     {
   3277         pOut->bpp               = surfOut.bpp;
   3278         pOut->pitch             = surfOut.pitch;
   3279         pOut->height            = surfOut.height;
   3280         pOut->numSlices         = surfOut.depth;
   3281         pOut->fmaskBytes        = surfOut.surfSize;
   3282         pOut->baseAlign         = surfOut.baseAlign;
   3283         pOut->pitchAlign        = surfOut.pitchAlign;
   3284         pOut->heightAlign       = surfOut.heightAlign;
   3285 
   3286         if (surfOut.depth > 1)
   3287         {
   3288             // For fmask, expNumSlices is stored in depth.
   3289             pOut->sliceSize = surfOut.surfSize / surfOut.depth;
   3290         }
   3291         else
   3292         {
   3293             pOut->sliceSize = surfOut.surfSize;
   3294         }
   3295 
   3296         // Save numSamples field for surface dump support
   3297         pOut->numSamples        = surfOut.numSamples;
   3298 
   3299         HwlFmaskPostThunkSurfInfo(&surfOut, pOut);
   3300     }
   3301 
   3302     return retCode;
   3303 }
   3304 
   3305 /**
   3306 ****************************************************************************************************
   3307 *   EgBasedLib::HwlFmaskSurfaceInfo
   3308 *   @brief
   3309 *       Entry of EgBasedLib ComputeFmaskInfo
   3310 *   @return
   3311 *       ADDR_E_RETURNCODE
   3312 ****************************************************************************************************
   3313 */
   3314 ADDR_E_RETURNCODE EgBasedLib::HwlComputeFmaskInfo(
   3315     const ADDR_COMPUTE_FMASK_INFO_INPUT*    pIn,   ///< [in] input structure
   3316     ADDR_COMPUTE_FMASK_INFO_OUTPUT*         pOut   ///< [out] output structure
   3317     )
   3318 {
   3319     ADDR_E_RETURNCODE retCode = ADDR_OK;
   3320 
   3321     ADDR_TILEINFO tileInfo = {0};
   3322 
   3323     // Use internal tile info if pOut does not have a valid pTileInfo
   3324     if (pOut->pTileInfo == NULL)
   3325     {
   3326         pOut->pTileInfo = &tileInfo;
   3327     }
   3328 
   3329     retCode = DispatchComputeFmaskInfo(pIn, pOut);
   3330 
   3331     if (retCode == ADDR_OK)
   3332     {
   3333         pOut->tileIndex =
   3334             HwlPostCheckTileIndex(pOut->pTileInfo, pIn->tileMode, ADDR_NON_DISPLAYABLE,
   3335                                   pOut->tileIndex);
   3336     }
   3337 
   3338     // Resets pTileInfo to NULL if the internal tile info is used
   3339     if (pOut->pTileInfo == &tileInfo)
   3340     {
   3341         pOut->pTileInfo = NULL;
   3342     }
   3343 
   3344     return retCode;
   3345 }
   3346 
   3347 /**
   3348 ****************************************************************************************************
   3349 *   EgBasedLib::HwlComputeFmaskAddrFromCoord
   3350 *   @brief
   3351 *       Entry of EgBasedLib ComputeFmaskAddrFromCoord
   3352 *   @return
   3353 *       ADDR_E_RETURNCODE
   3354 ****************************************************************************************************
   3355 */
   3356 ADDR_E_RETURNCODE EgBasedLib::HwlComputeFmaskAddrFromCoord(
   3357     const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
   3358     ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure
   3359     ) const
   3360 {
   3361     ADDR_E_RETURNCODE retCode = ADDR_OK;
   3362 
   3363     return retCode;
   3364 }
   3365 
   3366 /**
   3367 ****************************************************************************************************
   3368 *   EgBasedLib::HwlComputeFmaskCoordFromAddr
   3369 *   @brief
   3370 *       Entry of EgBasedLib ComputeFmaskCoordFromAddr
   3371 *   @return
   3372 *       ADDR_E_RETURNCODE
   3373 ****************************************************************************************************
   3374 */
   3375 ADDR_E_RETURNCODE EgBasedLib::HwlComputeFmaskCoordFromAddr(
   3376     const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure
   3377     ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT*        pOut    ///< [out] output structure
   3378     ) const
   3379 {
   3380     ADDR_E_RETURNCODE retCode = ADDR_OK;
   3381 
   3382     return retCode;
   3383 }
   3384 
   3385 /**
   3386 ****************************************************************************************************
   3387 *   EgBasedLib::ComputeFmaskNumPlanesFromNumSamples
   3388 *
   3389 *   @brief
   3390 *       Compute fmask number of planes from number of samples
   3391 *
   3392 *   @return
   3393 *       Number of planes
   3394 ****************************************************************************************************
   3395 */
   3396 UINT_32 EgBasedLib::ComputeFmaskNumPlanesFromNumSamples(
   3397     UINT_32 numSamples)     ///< [in] number of samples
   3398 {
   3399     UINT_32 numPlanes;
   3400 
   3401     //
   3402     // FMASK is stored such that each micro tile is composed of elements containing N bits, where
   3403     // N is the number of samples.  There is a micro tile for each bit in the FMASK address, and
   3404     // micro tiles for each address bit, sometimes referred to as a plane, are stored sequentially.
   3405     // The FMASK for a 2-sample surface looks like a general surface with 2 bits per element.
   3406     // The FMASK for a 4-sample surface looks like a general surface with 4 bits per element and
   3407     // 2 samples.  The FMASK for an 8-sample surface looks like a general surface with 8 bits per
   3408     // element and 4 samples.  R6xx and R7xx only stored 3 planes for 8-sample FMASK surfaces.
   3409     // This was changed for R8xx to simplify the logic in the CB.
   3410     //
   3411     switch (numSamples)
   3412     {
   3413         case 2:
   3414             numPlanes = 1;
   3415             break;
   3416         case 4:
   3417             numPlanes = 2;
   3418             break;
   3419         case 8:
   3420             numPlanes = 4;
   3421             break;
   3422         default:
   3423             ADDR_UNHANDLED_CASE();
   3424             numPlanes = 0;
   3425             break;
   3426     }
   3427     return numPlanes;
   3428 }
   3429 
   3430 /**
   3431 ****************************************************************************************************
   3432 *   EgBasedLib::ComputeFmaskResolvedBppFromNumSamples
   3433 *
   3434 *   @brief
   3435 *       Compute resolved fmask effective bpp based on number of samples
   3436 *
   3437 *   @return
   3438 *       bpp
   3439 ****************************************************************************************************
   3440 */
   3441 UINT_32 EgBasedLib::ComputeFmaskResolvedBppFromNumSamples(
   3442     UINT_32 numSamples)     ///< number of samples
   3443 {
   3444     UINT_32 bpp;
   3445 
   3446     //
   3447     // Resolved FMASK surfaces are generated yBit the CB and read yBit the texture unit
   3448     // so that the texture unit can read compressed multi-sample color data.
   3449     // These surfaces store each index value packed per element.
   3450     // Each element contains at least num_samples * log2(num_samples) bits.
   3451     // Resolved FMASK surfaces are addressed as follows:
   3452     // 2-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
   3453     // 4-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
   3454     // 8-sample Addressed similarly to a color surface with 32 bits per element and 1 sample.
   3455 
   3456     switch (numSamples)
   3457     {
   3458         case 2:
   3459             bpp = 8;
   3460             break;
   3461         case 4:
   3462             bpp = 8;
   3463             break;
   3464         case 8:
   3465             bpp = 32;
   3466             break;
   3467         default:
   3468             ADDR_UNHANDLED_CASE();
   3469             bpp = 0;
   3470             break;
   3471     }
   3472     return bpp;
   3473 }
   3474 
   3475 /**
   3476 ****************************************************************************************************
   3477 *   EgBasedLib::IsTileInfoAllZero
   3478 *
   3479 *   @brief
   3480 *       Return TRUE if all field are zero
   3481 *   @note
   3482 *       Since NULL input is consider to be all zero
   3483 ****************************************************************************************************
   3484 */
   3485 BOOL_32 EgBasedLib::IsTileInfoAllZero(
   3486     const ADDR_TILEINFO* pTileInfo)
   3487 {
   3488     BOOL_32 allZero = TRUE;
   3489 
   3490     if (pTileInfo)
   3491     {
   3492         if ((pTileInfo->banks            != 0)  ||
   3493             (pTileInfo->bankWidth        != 0)  ||
   3494             (pTileInfo->bankHeight       != 0)  ||
   3495             (pTileInfo->macroAspectRatio != 0)  ||
   3496             (pTileInfo->tileSplitBytes   != 0)  ||
   3497             (pTileInfo->pipeConfig       != 0)
   3498             )
   3499         {
   3500             allZero = FALSE;
   3501         }
   3502     }
   3503 
   3504     return allZero;
   3505 }
   3506 
   3507 /**
   3508 ****************************************************************************************************
   3509 *   EgBasedLib::HwlTileInfoEqual
   3510 *
   3511 *   @brief
   3512 *       Return TRUE if all field are equal
   3513 *   @note
   3514 *       Only takes care of current HWL's data
   3515 ****************************************************************************************************
   3516 */
   3517 BOOL_32 EgBasedLib::HwlTileInfoEqual(
   3518     const ADDR_TILEINFO* pLeft, ///<[in] Left compare operand
   3519     const ADDR_TILEINFO* pRight ///<[in] Right compare operand
   3520     ) const
   3521 {
   3522     BOOL_32 equal = FALSE;
   3523 
   3524     if (pLeft->banks == pRight->banks           &&
   3525         pLeft->bankWidth == pRight->bankWidth   &&
   3526         pLeft->bankHeight == pRight->bankHeight &&
   3527         pLeft->macroAspectRatio == pRight->macroAspectRatio &&
   3528         pLeft->tileSplitBytes == pRight->tileSplitBytes)
   3529     {
   3530         equal = TRUE;
   3531     }
   3532 
   3533     return equal;
   3534 }
   3535 
   3536 /**
   3537 ****************************************************************************************************
   3538 *   EgBasedLib::HwlConvertTileInfoToHW
   3539 *   @brief
   3540 *       Entry of EgBasedLib ConvertTileInfoToHW
   3541 *   @return
   3542 *       ADDR_E_RETURNCODE
   3543 ****************************************************************************************************
   3544 */
   3545 ADDR_E_RETURNCODE EgBasedLib::HwlConvertTileInfoToHW(
   3546     const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure
   3547     ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut      ///< [out] output structure
   3548     ) const
   3549 {
   3550     ADDR_E_RETURNCODE retCode   = ADDR_OK;
   3551 
   3552     ADDR_TILEINFO *pTileInfoIn  = pIn->pTileInfo;
   3553     ADDR_TILEINFO *pTileInfoOut = pOut->pTileInfo;
   3554 
   3555     if ((pTileInfoIn != NULL) && (pTileInfoOut != NULL))
   3556     {
   3557         if (pIn->reverse == FALSE)
   3558         {
   3559             switch (pTileInfoIn->banks)
   3560             {
   3561                 case 2:
   3562                     pTileInfoOut->banks = 0;
   3563                     break;
   3564                 case 4:
   3565                     pTileInfoOut->banks = 1;
   3566                     break;
   3567                 case 8:
   3568                     pTileInfoOut->banks = 2;
   3569                     break;
   3570                 case 16:
   3571                     pTileInfoOut->banks = 3;
   3572                     break;
   3573                 default:
   3574                     ADDR_ASSERT_ALWAYS();
   3575                     retCode = ADDR_INVALIDPARAMS;
   3576                     pTileInfoOut->banks = 0;
   3577                     break;
   3578             }
   3579 
   3580             switch (pTileInfoIn->bankWidth)
   3581             {
   3582                 case 1:
   3583                     pTileInfoOut->bankWidth = 0;
   3584                     break;
   3585                 case 2:
   3586                     pTileInfoOut->bankWidth = 1;
   3587                     break;
   3588                 case 4:
   3589                     pTileInfoOut->bankWidth = 2;
   3590                     break;
   3591                 case 8:
   3592                     pTileInfoOut->bankWidth = 3;
   3593                     break;
   3594                 default:
   3595                     ADDR_ASSERT_ALWAYS();
   3596                     retCode = ADDR_INVALIDPARAMS;
   3597                     pTileInfoOut->bankWidth = 0;
   3598                     break;
   3599             }
   3600 
   3601             switch (pTileInfoIn->bankHeight)
   3602             {
   3603                 case 1:
   3604                     pTileInfoOut->bankHeight = 0;
   3605                     break;
   3606                 case 2:
   3607                     pTileInfoOut->bankHeight = 1;
   3608                     break;
   3609                 case 4:
   3610                     pTileInfoOut->bankHeight = 2;
   3611                     break;
   3612                 case 8:
   3613                     pTileInfoOut->bankHeight = 3;
   3614                     break;
   3615                 default:
   3616                     ADDR_ASSERT_ALWAYS();
   3617                     retCode = ADDR_INVALIDPARAMS;
   3618                     pTileInfoOut->bankHeight = 0;
   3619                     break;
   3620             }
   3621 
   3622             switch (pTileInfoIn->macroAspectRatio)
   3623             {
   3624                 case 1:
   3625                     pTileInfoOut->macroAspectRatio = 0;
   3626                     break;
   3627                 case 2:
   3628                     pTileInfoOut->macroAspectRatio = 1;
   3629                     break;
   3630                 case 4:
   3631                     pTileInfoOut->macroAspectRatio = 2;
   3632                     break;
   3633                 case 8:
   3634                     pTileInfoOut->macroAspectRatio = 3;
   3635                     break;
   3636                 default:
   3637                     ADDR_ASSERT_ALWAYS();
   3638                     retCode = ADDR_INVALIDPARAMS;
   3639                     pTileInfoOut->macroAspectRatio = 0;
   3640                     break;
   3641             }
   3642 
   3643             switch (pTileInfoIn->tileSplitBytes)
   3644             {
   3645                 case 64:
   3646                     pTileInfoOut->tileSplitBytes = 0;
   3647                     break;
   3648                 case 128:
   3649                     pTileInfoOut->tileSplitBytes = 1;
   3650                     break;
   3651                 case 256:
   3652                     pTileInfoOut->tileSplitBytes = 2;
   3653                     break;
   3654                 case 512:
   3655                     pTileInfoOut->tileSplitBytes = 3;
   3656                     break;
   3657                 case 1024:
   3658                     pTileInfoOut->tileSplitBytes = 4;
   3659                     break;
   3660                 case 2048:
   3661                     pTileInfoOut->tileSplitBytes = 5;
   3662                     break;
   3663                 case 4096:
   3664                     pTileInfoOut->tileSplitBytes = 6;
   3665                     break;
   3666                 default:
   3667                     ADDR_ASSERT_ALWAYS();
   3668                     retCode = ADDR_INVALIDPARAMS;
   3669                     pTileInfoOut->tileSplitBytes = 0;
   3670                     break;
   3671             }
   3672         }
   3673         else
   3674         {
   3675             switch (pTileInfoIn->banks)
   3676             {
   3677                 case 0:
   3678                     pTileInfoOut->banks = 2;
   3679                     break;
   3680                 case 1:
   3681                     pTileInfoOut->banks = 4;
   3682                     break;
   3683                 case 2:
   3684                     pTileInfoOut->banks = 8;
   3685                     break;
   3686                 case 3:
   3687                     pTileInfoOut->banks = 16;
   3688                     break;
   3689                 default:
   3690                     ADDR_ASSERT_ALWAYS();
   3691                     retCode = ADDR_INVALIDPARAMS;
   3692                     pTileInfoOut->banks = 2;
   3693                     break;
   3694             }
   3695 
   3696             switch (pTileInfoIn->bankWidth)
   3697             {
   3698                 case 0:
   3699                     pTileInfoOut->bankWidth = 1;
   3700                     break;
   3701                 case 1:
   3702                     pTileInfoOut->bankWidth = 2;
   3703                     break;
   3704                 case 2:
   3705                     pTileInfoOut->bankWidth = 4;
   3706                     break;
   3707                 case 3:
   3708                     pTileInfoOut->bankWidth = 8;
   3709                     break;
   3710                 default:
   3711                     ADDR_ASSERT_ALWAYS();
   3712                     retCode = ADDR_INVALIDPARAMS;
   3713                     pTileInfoOut->bankWidth = 1;
   3714                     break;
   3715             }
   3716 
   3717             switch (pTileInfoIn->bankHeight)
   3718             {
   3719                 case 0:
   3720                     pTileInfoOut->bankHeight = 1;
   3721                     break;
   3722                 case 1:
   3723                     pTileInfoOut->bankHeight = 2;
   3724                     break;
   3725                 case 2:
   3726                     pTileInfoOut->bankHeight = 4;
   3727                     break;
   3728                 case 3:
   3729                     pTileInfoOut->bankHeight = 8;
   3730                     break;
   3731                 default:
   3732                     ADDR_ASSERT_ALWAYS();
   3733                     retCode = ADDR_INVALIDPARAMS;
   3734                     pTileInfoOut->bankHeight = 1;
   3735                     break;
   3736             }
   3737 
   3738             switch (pTileInfoIn->macroAspectRatio)
   3739             {
   3740                 case 0:
   3741                     pTileInfoOut->macroAspectRatio = 1;
   3742                     break;
   3743                 case 1:
   3744                     pTileInfoOut->macroAspectRatio = 2;
   3745                     break;
   3746                 case 2:
   3747                     pTileInfoOut->macroAspectRatio = 4;
   3748                     break;
   3749                 case 3:
   3750                     pTileInfoOut->macroAspectRatio = 8;
   3751                     break;
   3752                 default:
   3753                     ADDR_ASSERT_ALWAYS();
   3754                     retCode = ADDR_INVALIDPARAMS;
   3755                     pTileInfoOut->macroAspectRatio = 1;
   3756                     break;
   3757             }
   3758 
   3759             switch (pTileInfoIn->tileSplitBytes)
   3760             {
   3761                 case 0:
   3762                     pTileInfoOut->tileSplitBytes = 64;
   3763                     break;
   3764                 case 1:
   3765                     pTileInfoOut->tileSplitBytes = 128;
   3766                     break;
   3767                 case 2:
   3768                     pTileInfoOut->tileSplitBytes = 256;
   3769                     break;
   3770                 case 3:
   3771                     pTileInfoOut->tileSplitBytes = 512;
   3772                     break;
   3773                 case 4:
   3774                     pTileInfoOut->tileSplitBytes = 1024;
   3775                     break;
   3776                 case 5:
   3777                     pTileInfoOut->tileSplitBytes = 2048;
   3778                     break;
   3779                 case 6:
   3780                     pTileInfoOut->tileSplitBytes = 4096;
   3781                     break;
   3782                 default:
   3783                     ADDR_ASSERT_ALWAYS();
   3784                     retCode = ADDR_INVALIDPARAMS;
   3785                     pTileInfoOut->tileSplitBytes = 64;
   3786                     break;
   3787             }
   3788         }
   3789 
   3790         if (pTileInfoIn != pTileInfoOut)
   3791         {
   3792             pTileInfoOut->pipeConfig = pTileInfoIn->pipeConfig;
   3793         }
   3794     }
   3795     else
   3796     {
   3797         ADDR_ASSERT_ALWAYS();
   3798         retCode = ADDR_INVALIDPARAMS;
   3799     }
   3800 
   3801     return retCode;
   3802 }
   3803 
   3804 /**
   3805 ****************************************************************************************************
   3806 *   EgBasedLib::HwlComputeSurfaceInfo
   3807 *   @brief
   3808 *       Entry of EgBasedLib ComputeSurfaceInfo
   3809 *   @return
   3810 *       ADDR_E_RETURNCODE
   3811 ****************************************************************************************************
   3812 */
   3813 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSurfaceInfo(
   3814     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,    ///< [in] input structure
   3815     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [out] output structure
   3816     ) const
   3817 {
   3818     ADDR_E_RETURNCODE retCode = ADDR_OK;
   3819 
   3820     if (pIn->numSamples < pIn->numFrags)
   3821     {
   3822         retCode = ADDR_INVALIDPARAMS;
   3823     }
   3824 
   3825     ADDR_TILEINFO tileInfo = {0};
   3826 
   3827     if (retCode == ADDR_OK)
   3828     {
   3829         // Uses internal tile info if pOut does not have a valid pTileInfo
   3830         if (pOut->pTileInfo == NULL)
   3831         {
   3832             pOut->pTileInfo = &tileInfo;
   3833         }
   3834 
   3835         if (DispatchComputeSurfaceInfo(pIn, pOut) == FALSE)
   3836         {
   3837             retCode = ADDR_INVALIDPARAMS;
   3838         }
   3839 
   3840         // In case client uses tile info as input and would like to calculate a correct size and
   3841         // alignment together with tile info as output when the tile info is not suppose to have any
   3842         // matching indices in tile mode tables.
   3843         if (pIn->flags.skipIndicesOutput == FALSE)
   3844         {
   3845             // Returns an index
   3846             pOut->tileIndex = HwlPostCheckTileIndex(pOut->pTileInfo,
   3847                                                     pOut->tileMode,
   3848                                                     pOut->tileType,
   3849                                                     pOut->tileIndex);
   3850 
   3851             if (IsMacroTiled(pOut->tileMode) && (pOut->macroModeIndex == TileIndexInvalid))
   3852             {
   3853                 pOut->macroModeIndex = HwlComputeMacroModeIndex(pOut->tileIndex,
   3854                                                                 pIn->flags,
   3855                                                                 pIn->bpp,
   3856                                                                 pIn->numSamples,
   3857                                                                 pOut->pTileInfo);
   3858             }
   3859         }
   3860 
   3861         // Resets pTileInfo to NULL if the internal tile info is used
   3862         if (pOut->pTileInfo == &tileInfo)
   3863         {
   3864 #if DEBUG
   3865             // Client does not pass in a valid pTileInfo
   3866             if (IsMacroTiled(pOut->tileMode))
   3867             {
   3868                 // If a valid index is returned, then no pTileInfo is okay
   3869                 ADDR_ASSERT((m_configFlags.useTileIndex == FALSE) ||
   3870                             (pOut->tileIndex != TileIndexInvalid));
   3871 
   3872                 if (IsTileInfoAllZero(pIn->pTileInfo) == FALSE)
   3873                 {
   3874                     // The initial value of pIn->pTileInfo is copied to tileInfo
   3875                     // We do not expect any of these value to be changed nor any 0 of inputs
   3876                     ADDR_ASSERT(tileInfo.banks == pIn->pTileInfo->banks);
   3877                     ADDR_ASSERT(tileInfo.bankWidth == pIn->pTileInfo->bankWidth);
   3878                     ADDR_ASSERT(tileInfo.bankHeight == pIn->pTileInfo->bankHeight);
   3879                     ADDR_ASSERT(tileInfo.macroAspectRatio == pIn->pTileInfo->macroAspectRatio);
   3880                     ADDR_ASSERT(tileInfo.tileSplitBytes == pIn->pTileInfo->tileSplitBytes);
   3881                 }
   3882             }
   3883 #endif
   3884             pOut->pTileInfo = NULL;
   3885         }
   3886     }
   3887 
   3888     return retCode;
   3889 }
   3890 
   3891 /**
   3892 ****************************************************************************************************
   3893 *   EgBasedLib::HwlComputeSurfaceAddrFromCoord
   3894 *   @brief
   3895 *       Entry of EgBasedLib ComputeSurfaceAddrFromCoord
   3896 *   @return
   3897 *       ADDR_E_RETURNCODE
   3898 ****************************************************************************************************
   3899 */
   3900 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSurfaceAddrFromCoord(
   3901     const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
   3902     ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
   3903     ) const
   3904 {
   3905     ADDR_E_RETURNCODE retCode = ADDR_OK;
   3906 
   3907     if (
   3908 #if !ALT_TEST // Overflow test needs this out-of-boundary coord
   3909         (pIn->x > pIn->pitch)   ||
   3910         (pIn->y > pIn->height)  ||
   3911 #endif
   3912         (pIn->numSamples > m_maxSamples))
   3913     {
   3914         retCode = ADDR_INVALIDPARAMS;
   3915     }
   3916     else
   3917     {
   3918         pOut->addr = DispatchComputeSurfaceAddrFromCoord(pIn, pOut);
   3919     }
   3920 
   3921     return retCode;
   3922 }
   3923 
   3924 /**
   3925 ****************************************************************************************************
   3926 *   EgBasedLib::HwlComputeSurfaceCoordFromAddr
   3927 *   @brief
   3928 *       Entry of EgBasedLib ComputeSurfaceCoordFromAddr
   3929 *   @return
   3930 *       ADDR_E_RETURNCODE
   3931 ****************************************************************************************************
   3932 */
   3933 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSurfaceCoordFromAddr(
   3934     const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure
   3935     ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure
   3936     ) const
   3937 {
   3938     ADDR_E_RETURNCODE retCode = ADDR_OK;
   3939 
   3940     if ((pIn->bitPosition >= 8) ||
   3941         (pIn->numSamples > m_maxSamples))
   3942     {
   3943         retCode = ADDR_INVALIDPARAMS;
   3944     }
   3945     else
   3946     {
   3947         DispatchComputeSurfaceCoordFromAddr(pIn, pOut);
   3948     }
   3949     return retCode;
   3950 }
   3951 
   3952 /**
   3953 ****************************************************************************************************
   3954 *   EgBasedLib::HwlComputeSliceTileSwizzle
   3955 *   @brief
   3956 *       Entry of EgBasedLib ComputeSurfaceCoordFromAddr
   3957 *   @return
   3958 *       ADDR_E_RETURNCODE
   3959 ****************************************************************************************************
   3960 */
   3961 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSliceTileSwizzle(
   3962     const ADDR_COMPUTE_SLICESWIZZLE_INPUT*  pIn,    ///< [in] input structure
   3963     ADDR_COMPUTE_SLICESWIZZLE_OUTPUT*       pOut    ///< [out] output structure
   3964     ) const
   3965 {
   3966     ADDR_E_RETURNCODE retCode = ADDR_OK;
   3967 
   3968     if (pIn->pTileInfo && (pIn->pTileInfo->banks > 0))
   3969     {
   3970 
   3971         pOut->tileSwizzle = ComputeSliceTileSwizzle(pIn->tileMode,
   3972                                                     pIn->baseSwizzle,
   3973                                                     pIn->slice,
   3974                                                     pIn->baseAddr,
   3975                                                     pIn->pTileInfo);
   3976     }
   3977     else
   3978     {
   3979         retCode = ADDR_INVALIDPARAMS;
   3980     }
   3981 
   3982     return retCode;
   3983 }
   3984 
   3985 /**
   3986 ****************************************************************************************************
   3987 *   EgBasedLib::HwlComputeHtileBpp
   3988 *
   3989 *   @brief
   3990 *       Compute htile bpp
   3991 *
   3992 *   @return
   3993 *       Htile bpp
   3994 ****************************************************************************************************
   3995 */
   3996 UINT_32 EgBasedLib::HwlComputeHtileBpp(
   3997     BOOL_32 isWidth8,   ///< [in] TRUE if block width is 8
   3998     BOOL_32 isHeight8   ///< [in] TRUE if block height is 8
   3999     ) const
   4000 {
   4001     // only support 8x8 mode
   4002     ADDR_ASSERT(isWidth8 && isHeight8);
   4003     return 32;
   4004 }
   4005 
   4006 /**
   4007 ****************************************************************************************************
   4008 *   EgBasedLib::HwlComputeHtileBaseAlign
   4009 *
   4010 *   @brief
   4011 *       Compute htile base alignment
   4012 *
   4013 *   @return
   4014 *       Htile base alignment
   4015 ****************************************************************************************************
   4016 */
   4017 UINT_32 EgBasedLib::HwlComputeHtileBaseAlign(
   4018     BOOL_32         isTcCompatible, ///< [in] if TC compatible
   4019     BOOL_32         isLinear,       ///< [in] if it is linear mode
   4020     ADDR_TILEINFO*  pTileInfo       ///< [in] Tile info
   4021     ) const
   4022 {
   4023     UINT_32 baseAlign = m_pipeInterleaveBytes * HwlGetPipes(pTileInfo);
   4024 
   4025     if (isTcCompatible)
   4026     {
   4027         ADDR_ASSERT(pTileInfo != NULL);
   4028         if (pTileInfo)
   4029         {
   4030             baseAlign *= pTileInfo->banks;
   4031         }
   4032     }
   4033 
   4034     return baseAlign;
   4035 }
   4036 
   4037 /**
   4038 ****************************************************************************************************
   4039 *   EgBasedLib::HwlGetPitchAlignmentMicroTiled
   4040 *
   4041 *   @brief
   4042 *       Compute 1D tiled surface pitch alignment, calculation results are returned through
   4043 *       output parameters.
   4044 *
   4045 *   @return
   4046 *       pitch alignment
   4047 ****************************************************************************************************
   4048 */
   4049 UINT_32 EgBasedLib::HwlGetPitchAlignmentMicroTiled(
   4050     AddrTileMode        tileMode,          ///< [in] tile mode
   4051     UINT_32             bpp,               ///< [in] bits per pixel
   4052     ADDR_SURFACE_FLAGS  flags,             ///< [in] surface flags
   4053     UINT_32             numSamples         ///< [in] number of samples
   4054     ) const
   4055 {
   4056     UINT_32 pitchAlign;
   4057 
   4058     UINT_32 microTileThickness = Thickness(tileMode);
   4059 
   4060     UINT_32 pixelsPerMicroTile;
   4061     UINT_32 pixelsPerPipeInterleave;
   4062     UINT_32 microTilesPerPipeInterleave;
   4063 
   4064     //
   4065     // Special workaround for depth/stencil buffer, use 8 bpp to meet larger requirement for
   4066     // stencil buffer since pitch alignment is related to bpp.
   4067     // For a depth only buffer do not set this.
   4068     //
   4069     // Note: this actually does not work for mipmap but mipmap depth texture is not really
   4070     // sampled with mipmap.
   4071     //
   4072     if (flags.depth && (flags.noStencil == FALSE))
   4073     {
   4074         bpp = 8;
   4075     }
   4076 
   4077     pixelsPerMicroTile = MicroTilePixels * microTileThickness;
   4078     pixelsPerPipeInterleave = BYTES_TO_BITS(m_pipeInterleaveBytes) / (bpp * numSamples);
   4079     microTilesPerPipeInterleave = pixelsPerPipeInterleave / pixelsPerMicroTile;
   4080 
   4081     pitchAlign = Max(MicroTileWidth, microTilesPerPipeInterleave * MicroTileWidth);
   4082 
   4083     return pitchAlign;
   4084 }
   4085 
   4086 /**
   4087 ****************************************************************************************************
   4088 *   EgBasedLib::HwlGetSizeAdjustmentMicroTiled
   4089 *
   4090 *   @brief
   4091 *       Adjust 1D tiled surface pitch and slice size
   4092 *
   4093 *   @return
   4094 *       Logical slice size in bytes
   4095 ****************************************************************************************************
   4096 */
   4097 UINT_64 EgBasedLib::HwlGetSizeAdjustmentMicroTiled(
   4098     UINT_32             thickness,      ///< [in] thickness
   4099     UINT_32             bpp,            ///< [in] bits per pixel
   4100     ADDR_SURFACE_FLAGS  flags,          ///< [in] surface flags
   4101     UINT_32             numSamples,     ///< [in] number of samples
   4102     UINT_32             baseAlign,      ///< [in] base alignment
   4103     UINT_32             pitchAlign,     ///< [in] pitch alignment
   4104     UINT_32*            pPitch,         ///< [in,out] pointer to pitch
   4105     UINT_32*            pHeight         ///< [in,out] pointer to height
   4106     ) const
   4107 {
   4108     UINT_64 logicalSliceSize;
   4109     UINT_64 physicalSliceSize;
   4110 
   4111     UINT_32 pitch   = *pPitch;
   4112     UINT_32 height  = *pHeight;
   4113 
   4114     // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
   4115     logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
   4116 
   4117     // Physical slice: multiplied by thickness
   4118     physicalSliceSize =  logicalSliceSize * thickness;
   4119 
   4120     //
   4121     // R800 will always pad physical slice size to baseAlign which is pipe_interleave_bytes
   4122     //
   4123     ADDR_ASSERT((physicalSliceSize % baseAlign) == 0);
   4124 
   4125     return logicalSliceSize;
   4126 }
   4127 
   4128 /**
   4129 ****************************************************************************************************
   4130 *   EgBasedLib::HwlStereoCheckRightOffsetPadding
   4131 *
   4132 *   @brief
   4133 *       check if the height needs extra padding for stereo right eye offset, to avoid swizzling
   4134 *
   4135 *   @return
   4136 *       TRUE is the extra padding is needed
   4137 *
   4138 ****************************************************************************************************
   4139 */
   4140 UINT_32 EgBasedLib::HwlStereoCheckRightOffsetPadding(
   4141     ADDR_TILEINFO* pTileInfo    ///< Tiling info
   4142     ) const
   4143 {
   4144     UINT_32 stereoHeightAlign = 0;
   4145 
   4146     if (pTileInfo->macroAspectRatio > 2)
   4147     {
   4148         // Since 3D rendering treats right eye surface starting from y == "eye height" while
   4149         // display engine treats it to be 0, so the bank bits may be different.
   4150         // Additional padding in height is required to make sure it's possible
   4151         // to achieve synonym by adjusting bank swizzle of right eye surface.
   4152 
   4153         static const UINT_32 StereoAspectRatio = 2;
   4154         stereoHeightAlign = pTileInfo->banks *
   4155             pTileInfo->bankHeight *
   4156             MicroTileHeight /
   4157             StereoAspectRatio;
   4158     }
   4159 
   4160     return stereoHeightAlign;
   4161 }
   4162 
   4163 } // V1
   4164 } // Addr
   4165