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