Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright  2017 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  addrlib2.cpp
     30 * @brief Contains the implementation for the AddrLib2 base class.
     31 ************************************************************************************************************************
     32 */
     33 
     34 #include "addrinterface.h"
     35 #include "addrlib2.h"
     36 #include "addrcommon.h"
     37 
     38 namespace Addr
     39 {
     40 namespace V2
     41 {
     42 
     43 ////////////////////////////////////////////////////////////////////////////////////////////////////
     44 //                               Static Const Member
     45 ////////////////////////////////////////////////////////////////////////////////////////////////////
     46 
     47 const Dim2d Lib::Block256_2d[] = {{16, 16}, {16, 8}, {8, 8}, {8, 4}, {4, 4}};
     48 
     49 const Dim3d Lib::Block1K_3d[]  = {{16, 8, 8}, {8, 8, 8}, {8, 8, 4}, {8, 4, 4}, {4, 4, 4}};
     50 
     51 ////////////////////////////////////////////////////////////////////////////////////////////////////
     52 //                               Constructor/Destructor
     53 ////////////////////////////////////////////////////////////////////////////////////////////////////
     54 
     55 /**
     56 ************************************************************************************************************************
     57 *   Lib::Lib
     58 *
     59 *   @brief
     60 *       Constructor for the Addr::V2::Lib class
     61 *
     62 ************************************************************************************************************************
     63 */
     64 Lib::Lib()
     65     :
     66     Addr::Lib()
     67 {
     68 }
     69 
     70 /**
     71 ************************************************************************************************************************
     72 *   Lib::Lib
     73 *
     74 *   @brief
     75 *       Constructor for the AddrLib2 class with hClient as parameter
     76 *
     77 ************************************************************************************************************************
     78 */
     79 Lib::Lib(const Client* pClient)
     80     :
     81     Addr::Lib(pClient)
     82 {
     83 }
     84 
     85 /**
     86 ************************************************************************************************************************
     87 *   Lib::~Lib
     88 *
     89 *   @brief
     90 *       Destructor for the AddrLib2 class
     91 *
     92 ************************************************************************************************************************
     93 */
     94 Lib::~Lib()
     95 {
     96 }
     97 
     98 /**
     99 ************************************************************************************************************************
    100 *   Lib::GetLib
    101 *
    102 *   @brief
    103 *       Get Addr::V2::Lib pointer
    104 *
    105 *   @return
    106 *      An Addr::V2::Lib class pointer
    107 ************************************************************************************************************************
    108 */
    109 Lib* Lib::GetLib(
    110     ADDR_HANDLE hLib)   ///< [in] handle of ADDR_HANDLE
    111 {
    112     Addr::Lib* pAddrLib = Addr::Lib::GetLib(hLib);
    113     if ((pAddrLib != NULL) &&
    114         (pAddrLib->GetChipFamily() <= ADDR_CHIP_FAMILY_VI))
    115     {
    116         // only valid and GFX9+ AISC can use AddrLib2 function.
    117         ADDR_ASSERT_ALWAYS();
    118         hLib = NULL;
    119     }
    120     return static_cast<Lib*>(hLib);
    121 }
    122 
    123 
    124 ////////////////////////////////////////////////////////////////////////////////////////////////////
    125 //                               Surface Methods
    126 ////////////////////////////////////////////////////////////////////////////////////////////////////
    127 
    128 
    129 /**
    130 ************************************************************************************************************************
    131 *   Lib::ComputeSurfaceInfo
    132 *
    133 *   @brief
    134 *       Interface function stub of AddrComputeSurfaceInfo.
    135 *
    136 *   @return
    137 *       ADDR_E_RETURNCODE
    138 ************************************************************************************************************************
    139 */
    140 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(
    141      const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
    142      ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure
    143      ) const
    144 {
    145     ADDR_E_RETURNCODE returnCode = ADDR_OK;
    146 
    147     if (GetFillSizeFieldsFlags() == TRUE)
    148     {
    149         if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT)) ||
    150             (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT)))
    151         {
    152             returnCode = ADDR_PARAMSIZEMISMATCH;
    153         }
    154     }
    155 
    156     // Adjust coming parameters.
    157     ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;
    158     localIn.width        = Max(pIn->width, 1u);
    159     localIn.height       = Max(pIn->height, 1u);
    160     localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
    161     localIn.numSlices    = Max(pIn->numSlices, 1u);
    162     localIn.numSamples   = Max(pIn->numSamples, 1u);
    163     localIn.numFrags     = (localIn.numFrags == 0) ? localIn.numSamples : pIn->numFrags;
    164 
    165     UINT_32  expandX  = 1;
    166     UINT_32  expandY  = 1;
    167     ElemMode elemMode = ADDR_UNCOMPRESSED;
    168 
    169     if (returnCode == ADDR_OK)
    170     {
    171         // Set format to INVALID will skip this conversion
    172         if (localIn.format != ADDR_FMT_INVALID)
    173         {
    174             // Get compression/expansion factors and element mode which indicates compression/expansion
    175             localIn.bpp = GetElemLib()->GetBitsPerPixel(localIn.format,
    176                                                         &elemMode,
    177                                                         &expandX,
    178                                                         &expandY);
    179 
    180             // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
    181             // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
    182             // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
    183             // restrictions are different.
    184             // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
    185             // but we use this flag to skip RestoreSurfaceInfo below
    186 
    187             if ((elemMode == ADDR_EXPANDED) && (expandX > 1))
    188             {
    189                 ADDR_ASSERT(IsLinear(localIn.swizzleMode));
    190             }
    191 
    192             UINT_32 basePitch = 0;
    193             GetElemLib()->AdjustSurfaceInfo(elemMode,
    194                                             expandX,
    195                                             expandY,
    196                                             &localIn.bpp,
    197                                             &basePitch,
    198                                             &localIn.width,
    199                                             &localIn.height);
    200 
    201             // Overwrite these parameters if we have a valid format
    202         }
    203 
    204         if (localIn.bpp != 0)
    205         {
    206             localIn.width  = Max(localIn.width, 1u);
    207             localIn.height = Max(localIn.height, 1u);
    208         }
    209         else // Rule out some invalid parameters
    210         {
    211             ADDR_ASSERT_ALWAYS();
    212 
    213             returnCode = ADDR_INVALIDPARAMS;
    214         }
    215     }
    216 
    217     if (returnCode == ADDR_OK)
    218     {
    219         returnCode = ComputeSurfaceInfoSanityCheck(&localIn);
    220     }
    221 
    222     if (returnCode == ADDR_OK)
    223     {
    224         VerifyMipLevelInfo(pIn);
    225 
    226         if (IsLinear(pIn->swizzleMode))
    227         {
    228             // linear mode
    229             returnCode = ComputeSurfaceInfoLinear(&localIn, pOut);
    230         }
    231         else
    232         {
    233             // tiled mode
    234             returnCode = ComputeSurfaceInfoTiled(&localIn, pOut);
    235         }
    236 
    237         if (returnCode == ADDR_OK)
    238         {
    239             pOut->bpp = localIn.bpp;
    240             pOut->pixelPitch = pOut->pitch;
    241             pOut->pixelHeight = pOut->height;
    242             pOut->pixelMipChainPitch = pOut->mipChainPitch;
    243             pOut->pixelMipChainHeight = pOut->mipChainHeight;
    244             pOut->pixelBits = localIn.bpp;
    245 
    246             if (localIn.format != ADDR_FMT_INVALID)
    247             {
    248                 UINT_32 pixelBits = pOut->pixelBits;
    249 
    250                 GetElemLib()->RestoreSurfaceInfo(elemMode,
    251                                                  expandX,
    252                                                  expandY,
    253                                                  &pOut->pixelBits,
    254                                                  &pOut->pixelPitch,
    255                                                  &pOut->pixelHeight);
    256 
    257                 GetElemLib()->RestoreSurfaceInfo(elemMode,
    258                                                  expandX,
    259                                                  expandY,
    260                                                  &pixelBits,
    261                                                  &pOut->pixelMipChainPitch,
    262                                                  &pOut->pixelMipChainHeight);
    263 
    264                 if ((localIn.numMipLevels > 1) && (pOut->pMipInfo != NULL))
    265                 {
    266                     for (UINT_32 i = 0; i < localIn.numMipLevels; i++)
    267                     {
    268                         pOut->pMipInfo[i].pixelPitch  = pOut->pMipInfo[i].pitch;
    269                         pOut->pMipInfo[i].pixelHeight = pOut->pMipInfo[i].height;
    270 
    271                         GetElemLib()->RestoreSurfaceInfo(elemMode,
    272                                                          expandX,
    273                                                          expandY,
    274                                                          &pixelBits,
    275                                                          &pOut->pMipInfo[i].pixelPitch,
    276                                                          &pOut->pMipInfo[i].pixelHeight);
    277                     }
    278                 }
    279             }
    280 
    281             if (localIn.flags.needEquation && (Log2(localIn.numFrags) == 0))
    282             {
    283                 pOut->equationIndex = GetEquationIndex(&localIn, pOut);
    284             }
    285 
    286             if (localIn.flags.qbStereo)
    287             {
    288                 if (pOut->pStereoInfo != NULL)
    289                 {
    290                     ComputeQbStereoInfo(pOut);
    291                 }
    292             }
    293         }
    294     }
    295 
    296     ADDR_ASSERT(pOut->surfSize != 0);
    297 
    298     return returnCode;
    299 }
    300 
    301 /**
    302 ************************************************************************************************************************
    303 *   Lib::ComputeSurfaceInfo
    304 *
    305 *   @brief
    306 *       Interface function stub of AddrComputeSurfaceInfo.
    307 *
    308 *   @return
    309 *       ADDR_E_RETURNCODE
    310 ************************************************************************************************************************
    311 */
    312 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord(
    313     const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
    314     ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
    315     ) const
    316 {
    317     ADDR_E_RETURNCODE returnCode = ADDR_OK;
    318 
    319     if (GetFillSizeFieldsFlags() == TRUE)
    320     {
    321         if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) ||
    322             (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT)))
    323         {
    324             returnCode = ADDR_PARAMSIZEMISMATCH;
    325         }
    326     }
    327 
    328     ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT localIn = *pIn;
    329     localIn.unalignedWidth  = Max(pIn->unalignedWidth, 1u);
    330     localIn.unalignedHeight = Max(pIn->unalignedHeight, 1u);
    331     localIn.numMipLevels    = Max(pIn->numMipLevels, 1u);
    332     localIn.numSlices       = Max(pIn->numSlices, 1u);
    333     localIn.numSamples      = Max(pIn->numSamples, 1u);
    334     localIn.numFrags        = Max(pIn->numFrags, 1u);
    335 
    336     if ((localIn.bpp < 8)        ||
    337         (localIn.bpp > 128)      ||
    338         ((localIn.bpp % 8) != 0) ||
    339         (localIn.sample >= localIn.numSamples)  ||
    340         (localIn.slice >= localIn.numSlices)    ||
    341         (localIn.mipId >= localIn.numMipLevels) ||
    342         (IsTex3d(localIn.resourceType) &&
    343          (Valid3DMipSliceIdConstraint(localIn.numSlices, localIn.mipId, localIn.slice) == FALSE)))
    344     {
    345         returnCode = ADDR_INVALIDPARAMS;
    346     }
    347 
    348     if (returnCode == ADDR_OK)
    349     {
    350         if (IsLinear(localIn.swizzleMode))
    351         {
    352             returnCode = ComputeSurfaceAddrFromCoordLinear(&localIn, pOut);
    353         }
    354         else
    355         {
    356             returnCode = ComputeSurfaceAddrFromCoordTiled(&localIn, pOut);
    357         }
    358 
    359         if (returnCode == ADDR_OK)
    360         {
    361             pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024));
    362         }
    363     }
    364 
    365     return returnCode;
    366 }
    367 
    368 /**
    369 ************************************************************************************************************************
    370 *   Lib::ComputeSurfaceCoordFromAddr
    371 *
    372 *   @brief
    373 *       Interface function stub of ComputeSurfaceCoordFromAddr.
    374 *
    375 *   @return
    376 *       ADDR_E_RETURNCODE
    377 ************************************************************************************************************************
    378 */
    379 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddr(
    380     const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure
    381     ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure
    382     ) const
    383 {
    384     ADDR_E_RETURNCODE returnCode = ADDR_OK;
    385 
    386     if (GetFillSizeFieldsFlags() == TRUE)
    387     {
    388         if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) ||
    389             (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT)))
    390         {
    391             returnCode = ADDR_PARAMSIZEMISMATCH;
    392         }
    393     }
    394 
    395     if ((pIn->bpp < 8)        ||
    396         (pIn->bpp > 128)      ||
    397         ((pIn->bpp % 8) != 0) ||
    398         (pIn->bitPosition >= 8))
    399     {
    400         returnCode = ADDR_INVALIDPARAMS;
    401     }
    402 
    403     if (returnCode == ADDR_OK)
    404     {
    405         if (IsLinear(pIn->swizzleMode))
    406         {
    407             returnCode = ComputeSurfaceCoordFromAddrLinear(pIn, pOut);
    408         }
    409         else
    410         {
    411             returnCode = ComputeSurfaceCoordFromAddrTiled(pIn, pOut);
    412         }
    413     }
    414 
    415     return returnCode;
    416 }
    417 
    418 
    419 ////////////////////////////////////////////////////////////////////////////////////////////////////
    420 //                               CMASK/HTILE
    421 ////////////////////////////////////////////////////////////////////////////////////////////////////
    422 
    423 /**
    424 ************************************************************************************************************************
    425 *   Lib::ComputeHtileInfo
    426 *
    427 *   @brief
    428 *       Interface function stub of AddrComputeHtilenfo
    429 *
    430 *   @return
    431 *       ADDR_E_RETURNCODE
    432 ************************************************************************************************************************
    433 */
    434 ADDR_E_RETURNCODE Lib::ComputeHtileInfo(
    435     const ADDR2_COMPUTE_HTILE_INFO_INPUT*    pIn,    ///< [in] input structure
    436     ADDR2_COMPUTE_HTILE_INFO_OUTPUT*         pOut    ///< [out] output structure
    437     ) const
    438 {
    439     ADDR_E_RETURNCODE returnCode;
    440 
    441     if ((GetFillSizeFieldsFlags() == TRUE) &&
    442         ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT)) ||
    443          (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT))))
    444     {
    445         returnCode = ADDR_INVALIDPARAMS;
    446     }
    447     else
    448     {
    449         returnCode = HwlComputeHtileInfo(pIn, pOut);
    450     }
    451 
    452     return returnCode;
    453 }
    454 
    455 /**
    456 ************************************************************************************************************************
    457 *   Lib::ComputeHtileAddrFromCoord
    458 *
    459 *   @brief
    460 *       Interface function stub of AddrComputeHtileAddrFromCoord
    461 *
    462 *   @return
    463 *       ADDR_E_RETURNCODE
    464 ************************************************************************************************************************
    465 */
    466 ADDR_E_RETURNCODE Lib::ComputeHtileAddrFromCoord(
    467     const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
    468     ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*        pOut)   ///< [out] output structure
    469 {
    470     ADDR_E_RETURNCODE returnCode;
    471 
    472     if ((GetFillSizeFieldsFlags() == TRUE) &&
    473         ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) ||
    474          (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT))))
    475     {
    476         returnCode = ADDR_INVALIDPARAMS;
    477     }
    478     else
    479     {
    480         returnCode = HwlComputeHtileAddrFromCoord(pIn, pOut);
    481     }
    482 
    483     return returnCode;
    484 }
    485 
    486 /**
    487 ************************************************************************************************************************
    488 *   Lib::ComputeHtileCoordFromAddr
    489 *
    490 *   @brief
    491 *       Interface function stub of AddrComputeHtileCoordFromAddr
    492 *
    493 *   @return
    494 *       ADDR_E_RETURNCODE
    495 ************************************************************************************************************************
    496 */
    497 ADDR_E_RETURNCODE Lib::ComputeHtileCoordFromAddr(
    498     const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure
    499     ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*        pOut)   ///< [out] output structure
    500 {
    501     ADDR_E_RETURNCODE returnCode;
    502 
    503     if ((GetFillSizeFieldsFlags() == TRUE) &&
    504         ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT)) ||
    505          (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT))))
    506     {
    507         returnCode = ADDR_INVALIDPARAMS;
    508     }
    509     else
    510     {
    511         returnCode = HwlComputeHtileCoordFromAddr(pIn, pOut);
    512     }
    513 
    514     return returnCode;
    515 }
    516 
    517 /**
    518 ************************************************************************************************************************
    519 *   Lib::ComputeCmaskInfo
    520 *
    521 *   @brief
    522 *       Interface function stub of AddrComputeCmaskInfo
    523 *
    524 *   @return
    525 *       ADDR_E_RETURNCODE
    526 ************************************************************************************************************************
    527 */
    528 ADDR_E_RETURNCODE Lib::ComputeCmaskInfo(
    529     const ADDR2_COMPUTE_CMASK_INFO_INPUT*    pIn,    ///< [in] input structure
    530     ADDR2_COMPUTE_CMASK_INFO_OUTPUT*         pOut    ///< [out] output structure
    531     ) const
    532 {
    533     ADDR_E_RETURNCODE returnCode;
    534 
    535     if ((GetFillSizeFieldsFlags() == TRUE) &&
    536         ((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT)) ||
    537          (pOut->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT))))
    538     {
    539         returnCode = ADDR_INVALIDPARAMS;
    540     }
    541     else if (pIn->cMaskFlags.linear)
    542     {
    543         returnCode = ADDR_INVALIDPARAMS;
    544     }
    545     else
    546     {
    547         returnCode = HwlComputeCmaskInfo(pIn, pOut);
    548     }
    549 
    550     return returnCode;
    551 }
    552 
    553 /**
    554 ************************************************************************************************************************
    555 *   Lib::ComputeCmaskAddrFromCoord
    556 *
    557 *   @brief
    558 *       Interface function stub of AddrComputeCmaskAddrFromCoord
    559 *
    560 *   @return
    561 *       ADDR_E_RETURNCODE
    562 ************************************************************************************************************************
    563 */
    564 ADDR_E_RETURNCODE Lib::ComputeCmaskAddrFromCoord(
    565     const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
    566     ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*        pOut)   ///< [out] output structure
    567 {
    568     ADDR_E_RETURNCODE returnCode;
    569 
    570     if ((GetFillSizeFieldsFlags() == TRUE) &&
    571         ((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) ||
    572          (pOut->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT))))
    573     {
    574         returnCode = ADDR_INVALIDPARAMS;
    575     }
    576     else
    577     {
    578         returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut);
    579     }
    580 
    581     return returnCode;
    582 }
    583 
    584 /**
    585 ************************************************************************************************************************
    586 *   Lib::ComputeCmaskCoordFromAddr
    587 *
    588 *   @brief
    589 *       Interface function stub of AddrComputeCmaskCoordFromAddr
    590 *
    591 *   @return
    592 *       ADDR_E_RETURNCODE
    593 ************************************************************************************************************************
    594 */
    595 ADDR_E_RETURNCODE Lib::ComputeCmaskCoordFromAddr(
    596     const ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure
    597     ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT*        pOut    ///< [out] output structure
    598     ) const
    599 {
    600     ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
    601 
    602     ADDR_NOT_IMPLEMENTED();
    603 
    604     return returnCode;
    605 }
    606 
    607 /**
    608 ************************************************************************************************************************
    609 *   Lib::ComputeFmaskInfo
    610 *
    611 *   @brief
    612 *       Interface function stub of ComputeFmaskInfo.
    613 *
    614 *   @return
    615 *       ADDR_E_RETURNCODE
    616 ************************************************************************************************************************
    617 */
    618 ADDR_E_RETURNCODE Lib::ComputeFmaskInfo(
    619     const ADDR2_COMPUTE_FMASK_INFO_INPUT*    pIn,    ///< [in] input structure
    620     ADDR2_COMPUTE_FMASK_INFO_OUTPUT*         pOut    ///< [out] output structure
    621     )
    622 {
    623     ADDR_E_RETURNCODE returnCode;
    624 
    625     BOOL_32 valid = (IsZOrderSwizzle(pIn->swizzleMode) == TRUE) &&
    626                     ((pIn->numSamples > 0) || (pIn->numFrags > 0));
    627 
    628     if (GetFillSizeFieldsFlags())
    629     {
    630         if ((pIn->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT)) ||
    631             (pOut->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT)))
    632         {
    633             valid = FALSE;
    634         }
    635     }
    636 
    637     if (valid == FALSE)
    638     {
    639         returnCode = ADDR_INVALIDPARAMS;
    640     }
    641     else
    642     {
    643         ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn = {0};
    644         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
    645 
    646         localIn.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT);
    647         localOut.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT);
    648 
    649         localIn.swizzleMode  = pIn->swizzleMode;
    650         localIn.numSlices    = Max(pIn->numSlices, 1u);
    651         localIn.width        = Max(pIn->unalignedWidth, 1u);
    652         localIn.height       = Max(pIn->unalignedHeight, 1u);
    653         localIn.bpp          = GetFmaskBpp(pIn->numSamples, pIn->numFrags);
    654         localIn.flags.fmask  = 1;
    655         localIn.numFrags     = 1;
    656         localIn.numSamples   = 1;
    657         localIn.resourceType = ADDR_RSRC_TEX_2D;
    658 
    659         if (localIn.bpp == 8)
    660         {
    661             localIn.format = ADDR_FMT_8;
    662         }
    663         else if (localIn.bpp == 16)
    664         {
    665             localIn.format = ADDR_FMT_16;
    666         }
    667         else if (localIn.bpp == 32)
    668         {
    669             localIn.format = ADDR_FMT_32;
    670         }
    671         else
    672         {
    673             localIn.format = ADDR_FMT_32_32;
    674         }
    675 
    676         returnCode = ComputeSurfaceInfo(&localIn, &localOut);
    677 
    678         if (returnCode == ADDR_OK)
    679         {
    680             pOut->pitch      = localOut.pitch;
    681             pOut->height     = localOut.height;
    682             pOut->baseAlign  = localOut.baseAlign;
    683             pOut->numSlices  = localOut.numSlices;
    684             pOut->fmaskBytes = static_cast<UINT_32>(localOut.surfSize);
    685             pOut->sliceSize  = static_cast<UINT_32>(localOut.sliceSize);
    686             pOut->bpp        = localIn.bpp;
    687             pOut->numSamples = 1;
    688         }
    689     }
    690 
    691     return returnCode;
    692 }
    693 
    694 /**
    695 ************************************************************************************************************************
    696 *   Lib::ComputeFmaskAddrFromCoord
    697 *
    698 *   @brief
    699 *       Interface function stub of ComputeFmaskAddrFromCoord.
    700 *
    701 *   @return
    702 *       ADDR_E_RETURNCODE
    703 ************************************************************************************************************************
    704 */
    705 ADDR_E_RETURNCODE Lib::ComputeFmaskAddrFromCoord(
    706     const ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
    707     ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure
    708     ) const
    709 {
    710     ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
    711 
    712     ADDR_NOT_IMPLEMENTED();
    713 
    714     return returnCode;
    715 }
    716 
    717 /**
    718 ************************************************************************************************************************
    719 *   Lib::ComputeFmaskCoordFromAddr
    720 *
    721 *   @brief
    722 *       Interface function stub of ComputeFmaskAddrFromCoord.
    723 *
    724 *   @return
    725 *       ADDR_E_RETURNCODE
    726 ************************************************************************************************************************
    727 */
    728 ADDR_E_RETURNCODE Lib::ComputeFmaskCoordFromAddr(
    729     const ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT*  pIn,     ///< [in] input structure
    730     ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT*       pOut     ///< [out] output structure
    731     ) const
    732 {
    733     ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
    734 
    735     ADDR_NOT_IMPLEMENTED();
    736 
    737     return returnCode;
    738 }
    739 
    740 /**
    741 ************************************************************************************************************************
    742 *   Lib::ComputeDccInfo
    743 *
    744 *   @brief
    745 *       Interface function to compute DCC key info
    746 *
    747 *   @return
    748 *       return code of HwlComputeDccInfo
    749 ************************************************************************************************************************
    750 */
    751 ADDR_E_RETURNCODE Lib::ComputeDccInfo(
    752     const ADDR2_COMPUTE_DCCINFO_INPUT*    pIn,    ///< [in] input structure
    753     ADDR2_COMPUTE_DCCINFO_OUTPUT*         pOut    ///< [out] output structure
    754     ) const
    755 {
    756     ADDR_E_RETURNCODE returnCode;
    757 
    758     if ((GetFillSizeFieldsFlags() == TRUE) &&
    759         ((pIn->size != sizeof(ADDR2_COMPUTE_DCCINFO_INPUT)) ||
    760          (pOut->size != sizeof(ADDR2_COMPUTE_DCCINFO_OUTPUT))))
    761     {
    762         returnCode = ADDR_INVALIDPARAMS;
    763     }
    764     else
    765     {
    766         returnCode = HwlComputeDccInfo(pIn, pOut);
    767     }
    768 
    769     return returnCode;
    770 }
    771 
    772 /**
    773 ************************************************************************************************************************
    774 *   Lib::ComputeDccAddrFromCoord
    775 *
    776 *   @brief
    777 *       Interface function stub of ComputeDccAddrFromCoord
    778 *
    779 *   @return
    780 *       ADDR_E_RETURNCODE
    781 ************************************************************************************************************************
    782 */
    783 ADDR_E_RETURNCODE Lib::ComputeDccAddrFromCoord(
    784     const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
    785     ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT*      pOut)   ///< [out] output structure
    786 {
    787     ADDR_E_RETURNCODE returnCode;
    788 
    789     if ((GetFillSizeFieldsFlags() == TRUE) &&
    790         ((pIn->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT)) ||
    791          (pOut->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT))))
    792     {
    793         returnCode = ADDR_INVALIDPARAMS;
    794     }
    795     else
    796     {
    797         returnCode = HwlComputeDccAddrFromCoord(pIn, pOut);
    798     }
    799 
    800     return returnCode;
    801 }
    802 
    803 /**
    804 ************************************************************************************************************************
    805 *   Lib::ComputePipeBankXor
    806 *
    807 *   @brief
    808 *       Interface function stub of Addr2ComputePipeBankXor.
    809 *
    810 *   @return
    811 *       ADDR_E_RETURNCODE
    812 ************************************************************************************************************************
    813 */
    814 ADDR_E_RETURNCODE Lib::ComputePipeBankXor(
    815     const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,
    816     ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut)
    817 {
    818     ADDR_E_RETURNCODE returnCode;
    819 
    820     if ((GetFillSizeFieldsFlags() == TRUE) &&
    821         ((pIn->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT)) ||
    822          (pOut->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT))))
    823     {
    824         returnCode = ADDR_INVALIDPARAMS;
    825     }
    826     else if (IsXor(pIn->swizzleMode) == FALSE)
    827     {
    828         returnCode = ADDR_NOTSUPPORTED;
    829     }
    830     else
    831     {
    832         returnCode = HwlComputePipeBankXor(pIn, pOut);
    833     }
    834 
    835     return returnCode;
    836 }
    837 
    838 /**
    839 ************************************************************************************************************************
    840 *   Lib::ComputeSlicePipeBankXor
    841 *
    842 *   @brief
    843 *       Interface function stub of Addr2ComputeSlicePipeBankXor.
    844 *
    845 *   @return
    846 *       ADDR_E_RETURNCODE
    847 ************************************************************************************************************************
    848 */
    849 ADDR_E_RETURNCODE Lib::ComputeSlicePipeBankXor(
    850     const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,
    851     ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut)
    852 {
    853     ADDR_E_RETURNCODE returnCode;
    854 
    855     if ((GetFillSizeFieldsFlags() == TRUE) &&
    856         ((pIn->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT)) ||
    857          (pOut->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT))))
    858     {
    859         returnCode = ADDR_INVALIDPARAMS;
    860     }
    861     else if ((IsThin(pIn->resourceType, pIn->swizzleMode) == FALSE) ||
    862              (IsNonPrtXor(pIn->swizzleMode) == FALSE) ||
    863              (pIn->numSamples > 1))
    864     {
    865         returnCode = ADDR_NOTSUPPORTED;
    866     }
    867     else
    868     {
    869         returnCode = HwlComputeSlicePipeBankXor(pIn, pOut);
    870     }
    871 
    872     return returnCode;
    873 }
    874 
    875 /**
    876 ************************************************************************************************************************
    877 *   Lib::ComputeSubResourceOffsetForSwizzlePattern
    878 *
    879 *   @brief
    880 *       Interface function stub of Addr2ComputeSubResourceOffsetForSwizzlePattern.
    881 *
    882 *   @return
    883 *       ADDR_E_RETURNCODE
    884 ************************************************************************************************************************
    885 */
    886 ADDR_E_RETURNCODE Lib::ComputeSubResourceOffsetForSwizzlePattern(
    887     const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,
    888     ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut)
    889 {
    890     ADDR_E_RETURNCODE returnCode;
    891 
    892     if ((GetFillSizeFieldsFlags() == TRUE) &&
    893         ((pIn->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT)) ||
    894          (pOut->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT))))
    895     {
    896         returnCode = ADDR_INVALIDPARAMS;
    897     }
    898     else
    899     {
    900         returnCode = HwlComputeSubResourceOffsetForSwizzlePattern(pIn, pOut);
    901     }
    902 
    903     return returnCode;
    904 }
    905 
    906 /**
    907 ************************************************************************************************************************
    908 *   Lib::ExtractPipeBankXor
    909 *
    910 *   @brief
    911 *       Internal function to extract bank and pipe xor bits from combined xor bits.
    912 *
    913 *   @return
    914 *       ADDR_E_RETURNCODE
    915 ************************************************************************************************************************
    916 */
    917 ADDR_E_RETURNCODE Lib::ExtractPipeBankXor(
    918     UINT_32  pipeBankXor,
    919     UINT_32  bankBits,
    920     UINT_32  pipeBits,
    921     UINT_32* pBankX,
    922     UINT_32* pPipeX)
    923 {
    924     ADDR_E_RETURNCODE returnCode;
    925 
    926     if (pipeBankXor < (1u << (pipeBits + bankBits)))
    927     {
    928         *pPipeX = pipeBankXor % (1 << pipeBits);
    929         *pBankX = pipeBankXor >> pipeBits;
    930         returnCode = ADDR_OK;
    931     }
    932     else
    933     {
    934         ADDR_ASSERT_ALWAYS();
    935         returnCode = ADDR_INVALIDPARAMS;
    936     }
    937 
    938     return returnCode;
    939 }
    940 
    941 /**
    942 ************************************************************************************************************************
    943 *   Lib::ComputeSurfaceInfoSanityCheck
    944 *
    945 *   @brief
    946 *       Internal function to do basic sanity check before compute surface info
    947 *
    948 *   @return
    949 *       ADDR_E_RETURNCODE
    950 ************************************************************************************************************************
    951 */
    952 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoSanityCheck(
    953     const ADDR2_COMPUTE_SURFACE_INFO_INPUT*  pIn   ///< [in] input structure
    954     ) const
    955 {
    956     ADDR_E_RETURNCODE returnCode;
    957 
    958     if ((GetFillSizeFieldsFlags() == TRUE) &&
    959         (pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT)))
    960     {
    961         returnCode = ADDR_INVALIDPARAMS;
    962     }
    963     else
    964     {
    965         returnCode = HwlComputeSurfaceInfoSanityCheck(pIn);
    966     }
    967 
    968     return returnCode;
    969 }
    970 
    971 /**
    972 ************************************************************************************************************************
    973 *   Lib::ApplyCustomizedPitchHeight
    974 *
    975 *   @brief
    976 *       Helper function to override hw required row pitch/slice pitch by customrized one
    977 *
    978 *   @return
    979 *       ADDR_E_RETURNCODE
    980 ************************************************************************************************************************
    981 */
    982 ADDR_E_RETURNCODE Lib::ApplyCustomizedPitchHeight(
    983     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
    984     UINT_32  elementBytes,                          ///< [in] element bytes per element
    985     UINT_32  pitchAlignInElement,                   ///< [in] pitch alignment in element
    986     UINT_32* pPitch,                                ///< [in/out] pitch
    987     UINT_32* pHeight                                ///< [in/out] height
    988     ) const
    989 {
    990     ADDR_E_RETURNCODE returnCode = ADDR_OK;
    991 
    992     if (pIn->numMipLevels <= 1)
    993     {
    994         if (pIn->pitchInElement > 0)
    995         {
    996             if ((pIn->pitchInElement % pitchAlignInElement) != 0)
    997             {
    998                 returnCode = ADDR_INVALIDPARAMS;
    999             }
   1000             else if (pIn->pitchInElement < (*pPitch))
   1001             {
   1002                 returnCode = ADDR_INVALIDPARAMS;
   1003             }
   1004             else
   1005             {
   1006                 *pPitch = pIn->pitchInElement;
   1007             }
   1008         }
   1009 
   1010         if (returnCode == ADDR_OK)
   1011         {
   1012             if (pIn->sliceAlign > 0)
   1013             {
   1014                 UINT_32 customizedHeight = pIn->sliceAlign / elementBytes / (*pPitch);
   1015 
   1016                 if (customizedHeight * elementBytes * (*pPitch) != pIn->sliceAlign)
   1017                 {
   1018                     returnCode = ADDR_INVALIDPARAMS;
   1019                 }
   1020                 else if ((pIn->numSlices > 1) && ((*pHeight) != customizedHeight))
   1021                 {
   1022                     returnCode = ADDR_INVALIDPARAMS;
   1023                 }
   1024                 else
   1025                 {
   1026                     *pHeight = customizedHeight;
   1027                 }
   1028             }
   1029         }
   1030     }
   1031 
   1032     return returnCode;
   1033 }
   1034 
   1035 /**
   1036 ************************************************************************************************************************
   1037 *   Lib::ComputeSurfaceInfoLinear
   1038 *
   1039 *   @brief
   1040 *       Internal function to calculate alignment for linear swizzle surface
   1041 *
   1042 *   @return
   1043 *       ADDR_E_RETURNCODE
   1044 ************************************************************************************************************************
   1045 */
   1046 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoLinear(
   1047      const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
   1048      ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure
   1049      ) const
   1050 {
   1051     return HwlComputeSurfaceInfoLinear(pIn, pOut);
   1052 }
   1053 
   1054 /**
   1055 ************************************************************************************************************************
   1056 *   Lib::ComputeSurfaceInfoTiled
   1057 *
   1058 *   @brief
   1059 *       Internal function to calculate alignment for tiled swizzle surface
   1060 *
   1061 *   @return
   1062 *       ADDR_E_RETURNCODE
   1063 ************************************************************************************************************************
   1064 */
   1065 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoTiled(
   1066      const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
   1067      ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure
   1068      ) const
   1069 {
   1070     return HwlComputeSurfaceInfoTiled(pIn, pOut);
   1071 }
   1072 
   1073 /**
   1074 ************************************************************************************************************************
   1075 *   Lib::ComputeSurfaceAddrFromCoordLinear
   1076 *
   1077 *   @brief
   1078 *       Internal function to calculate address from coord for linear swizzle surface
   1079 *
   1080 *   @return
   1081 *       ADDR_E_RETURNCODE
   1082 ************************************************************************************************************************
   1083 */
   1084 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordLinear(
   1085      const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
   1086      ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
   1087      ) const
   1088 {
   1089     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1090     BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1) && (pIn->pipeBankXor == 0);
   1091 
   1092     if (valid)
   1093     {
   1094         if (IsTex1d(pIn->resourceType))
   1095         {
   1096             valid = (pIn->y == 0);
   1097         }
   1098     }
   1099 
   1100     if (valid)
   1101     {
   1102         ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn  = {0};
   1103         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
   1104         ADDR2_MIP_INFO                    mipInfo[MaxMipLevels];
   1105 
   1106         localIn.bpp          = pIn->bpp;
   1107         localIn.flags        = pIn->flags;
   1108         localIn.width        = Max(pIn->unalignedWidth, 1u);
   1109         localIn.height       = Max(pIn->unalignedHeight, 1u);
   1110         localIn.numSlices    = Max(pIn->numSlices, 1u);
   1111         localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
   1112         localIn.resourceType = pIn->resourceType;
   1113 
   1114         if (localIn.numMipLevels <= 1)
   1115         {
   1116             localIn.pitchInElement = pIn->pitchInElement;
   1117         }
   1118 
   1119         localOut.pMipInfo = mipInfo;
   1120 
   1121         returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut);
   1122 
   1123         if (returnCode == ADDR_OK)
   1124         {
   1125             pOut->addr        = (localOut.sliceSize * pIn->slice) +
   1126                                 mipInfo[pIn->mipId].offset +
   1127                                 (pIn->y * mipInfo[pIn->mipId].pitch + pIn->x) * (pIn->bpp >> 3);
   1128             pOut->bitPosition = 0;
   1129         }
   1130         else
   1131         {
   1132             valid = FALSE;
   1133         }
   1134     }
   1135 
   1136     if (valid == FALSE)
   1137     {
   1138         returnCode = ADDR_INVALIDPARAMS;
   1139     }
   1140 
   1141     return returnCode;
   1142 }
   1143 
   1144 /**
   1145 ************************************************************************************************************************
   1146 *   Lib::ComputeSurfaceAddrFromCoordTiled
   1147 *
   1148 *   @brief
   1149 *       Internal function to calculate address from coord for tiled swizzle surface
   1150 *
   1151 *   @return
   1152 *       ADDR_E_RETURNCODE
   1153 ************************************************************************************************************************
   1154 */
   1155 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordTiled(
   1156      const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
   1157      ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
   1158      ) const
   1159 {
   1160     return HwlComputeSurfaceAddrFromCoordTiled(pIn, pOut);
   1161 }
   1162 
   1163 /**
   1164 ************************************************************************************************************************
   1165 *   Lib::ComputeSurfaceCoordFromAddrLinear
   1166 *
   1167 *   @brief
   1168 *       Internal function to calculate coord from address for linear swizzle surface
   1169 *
   1170 *   @return
   1171 *       ADDR_E_RETURNCODE
   1172 ************************************************************************************************************************
   1173 */
   1174 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrLinear(
   1175      const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure
   1176      ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure
   1177      ) const
   1178 {
   1179     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1180 
   1181     BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1);
   1182 
   1183     if (valid)
   1184     {
   1185         if (IsTex1d(pIn->resourceType))
   1186         {
   1187             valid = (pIn->unalignedHeight == 1);
   1188         }
   1189     }
   1190 
   1191     if (valid)
   1192     {
   1193         ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn  = {0};
   1194         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
   1195         localIn.bpp          = pIn->bpp;
   1196         localIn.flags        = pIn->flags;
   1197         localIn.width        = Max(pIn->unalignedWidth, 1u);
   1198         localIn.height       = Max(pIn->unalignedHeight, 1u);
   1199         localIn.numSlices    = Max(pIn->numSlices, 1u);
   1200         localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
   1201         localIn.resourceType = pIn->resourceType;
   1202         if (localIn.numMipLevels <= 1)
   1203         {
   1204             localIn.pitchInElement = pIn->pitchInElement;
   1205         }
   1206         returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut);
   1207 
   1208         if (returnCode == ADDR_OK)
   1209         {
   1210             pOut->slice = static_cast<UINT_32>(pIn->addr / localOut.sliceSize);
   1211             pOut->sample = 0;
   1212 
   1213             UINT_32 offsetInSlice = static_cast<UINT_32>(pIn->addr % localOut.sliceSize);
   1214             UINT_32 elementBytes = pIn->bpp >> 3;
   1215             UINT_32 mipOffsetInSlice = 0;
   1216             UINT_32 mipSize = 0;
   1217             UINT_32 mipId = 0;
   1218             for (; mipId < pIn->numMipLevels ; mipId++)
   1219             {
   1220                 if (IsTex1d(pIn->resourceType))
   1221                 {
   1222                     mipSize = localOut.pitch * elementBytes;
   1223                 }
   1224                 else
   1225                 {
   1226                     UINT_32 currentMipHeight = (PowTwoAlign(localIn.height, (1 << mipId))) >> mipId;
   1227                     mipSize = currentMipHeight * localOut.pitch * elementBytes;
   1228                 }
   1229 
   1230                 if (mipSize == 0)
   1231                 {
   1232                     valid = FALSE;
   1233                     break;
   1234                 }
   1235                 else if ((mipSize + mipOffsetInSlice) > offsetInSlice)
   1236                 {
   1237                     break;
   1238                 }
   1239                 else
   1240                 {
   1241                     mipOffsetInSlice += mipSize;
   1242                     if ((mipId == (pIn->numMipLevels - 1)) ||
   1243                         (mipOffsetInSlice >= localOut.sliceSize))
   1244                     {
   1245                         valid = FALSE;
   1246                     }
   1247                 }
   1248             }
   1249 
   1250             if (valid)
   1251             {
   1252                 pOut->mipId = mipId;
   1253 
   1254                 UINT_32 elemOffsetInMip = (offsetInSlice - mipOffsetInSlice) / elementBytes;
   1255                 if (IsTex1d(pIn->resourceType))
   1256                 {
   1257                     if (elemOffsetInMip < localOut.pitch)
   1258                     {
   1259                         pOut->x = elemOffsetInMip;
   1260                         pOut->y = 0;
   1261                     }
   1262                     else
   1263                     {
   1264                         valid = FALSE;
   1265                     }
   1266                 }
   1267                 else
   1268                 {
   1269                     pOut->y = elemOffsetInMip / localOut.pitch;
   1270                     pOut->x = elemOffsetInMip % localOut.pitch;
   1271                 }
   1272 
   1273                 if ((pOut->slice >= pIn->numSlices)    ||
   1274                     (pOut->mipId >= pIn->numMipLevels) ||
   1275                     (pOut->x >= Max((pIn->unalignedWidth >> pOut->mipId), 1u))  ||
   1276                     (pOut->y >= Max((pIn->unalignedHeight >> pOut->mipId), 1u)) ||
   1277                     (IsTex3d(pIn->resourceType) &&
   1278                      (FALSE == Valid3DMipSliceIdConstraint(pIn->numSlices,
   1279                                                            pOut->mipId,
   1280                                                            pOut->slice))))
   1281                 {
   1282                     valid = FALSE;
   1283                 }
   1284             }
   1285         }
   1286         else
   1287         {
   1288             valid = FALSE;
   1289         }
   1290     }
   1291 
   1292     if (valid == FALSE)
   1293     {
   1294         returnCode = ADDR_INVALIDPARAMS;
   1295     }
   1296 
   1297     return returnCode;
   1298 }
   1299 
   1300 /**
   1301 ************************************************************************************************************************
   1302 *   Lib::ComputeSurfaceCoordFromAddrTiled
   1303 *
   1304 *   @brief
   1305 *       Internal function to calculate coord from address for tiled swizzle surface
   1306 *
   1307 *   @return
   1308 *       ADDR_E_RETURNCODE
   1309 ************************************************************************************************************************
   1310 */
   1311 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrTiled(
   1312      const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure
   1313      ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure
   1314      ) const
   1315 {
   1316     ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
   1317 
   1318     ADDR_NOT_IMPLEMENTED();
   1319 
   1320     return returnCode;
   1321 }
   1322 
   1323 /**
   1324 ************************************************************************************************************************
   1325 *   Lib::ComputeBlockDimensionForSurf
   1326 *
   1327 *   @brief
   1328 *       Internal function to get block width/height/depth in element from surface input params.
   1329 *
   1330 *   @return
   1331 *       ADDR_E_RETURNCODE
   1332 ************************************************************************************************************************
   1333 */
   1334 ADDR_E_RETURNCODE Lib::ComputeBlockDimensionForSurf(
   1335     UINT_32*         pWidth,
   1336     UINT_32*         pHeight,
   1337     UINT_32*         pDepth,
   1338     UINT_32          bpp,
   1339     UINT_32          numSamples,
   1340     AddrResourceType resourceType,
   1341     AddrSwizzleMode  swizzleMode) const
   1342 {
   1343     ADDR_E_RETURNCODE returnCode = ComputeBlockDimension(pWidth,
   1344                                                          pHeight,
   1345                                                          pDepth,
   1346                                                          bpp,
   1347                                                          resourceType,
   1348                                                          swizzleMode);
   1349 
   1350     if ((returnCode == ADDR_OK) && (numSamples > 1) && IsThin(resourceType, swizzleMode))
   1351     {
   1352         const UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode);
   1353         const UINT_32 log2sample  = Log2(numSamples);
   1354         const UINT_32 q           = log2sample >> 1;
   1355         const UINT_32 r           = log2sample & 1;
   1356 
   1357         if (log2blkSize & 1)
   1358         {
   1359             *pWidth  >>= q;
   1360             *pHeight >>= (q + r);
   1361         }
   1362         else
   1363         {
   1364             *pWidth  >>= (q + r);
   1365             *pHeight >>= q;
   1366         }
   1367     }
   1368 
   1369     return returnCode;
   1370 }
   1371 
   1372 /**
   1373 ************************************************************************************************************************
   1374 *   Lib::ComputeBlockDimension
   1375 *
   1376 *   @brief
   1377 *       Internal function to get block width/height/depth in element without considering MSAA case
   1378 *
   1379 *   @return
   1380 *       ADDR_E_RETURNCODE
   1381 ************************************************************************************************************************
   1382 */
   1383 ADDR_E_RETURNCODE Lib::ComputeBlockDimension(
   1384     UINT_32*          pWidth,
   1385     UINT_32*          pHeight,
   1386     UINT_32*          pDepth,
   1387     UINT_32           bpp,
   1388     AddrResourceType  resourceType,
   1389     AddrSwizzleMode   swizzleMode) const
   1390 {
   1391     ADDR_E_RETURNCODE returnCode = ADDR_OK;
   1392 
   1393     UINT_32 eleBytes                 = bpp >> 3;
   1394     UINT_32 microBlockSizeTableIndex = Log2(eleBytes);
   1395     UINT_32 log2blkSize              = GetBlockSizeLog2(swizzleMode);
   1396 
   1397     if (IsThin(resourceType, swizzleMode))
   1398     {
   1399         UINT_32 log2blkSizeIn256B = log2blkSize - 8;
   1400         UINT_32 widthAmp          = log2blkSizeIn256B / 2;
   1401         UINT_32 heightAmp         = log2blkSizeIn256B - widthAmp;
   1402 
   1403         ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block256_2d) / sizeof(Block256_2d[0]));
   1404 
   1405         *pWidth  = (Block256_2d[microBlockSizeTableIndex].w << widthAmp);
   1406         *pHeight = (Block256_2d[microBlockSizeTableIndex].h << heightAmp);
   1407         *pDepth  = 1;
   1408     }
   1409     else if (IsThick(resourceType, swizzleMode))
   1410     {
   1411         UINT_32 log2blkSizeIn1KB = log2blkSize - 10;
   1412         UINT_32 averageAmp       = log2blkSizeIn1KB / 3;
   1413         UINT_32 restAmp          = log2blkSizeIn1KB % 3;
   1414 
   1415         ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block1K_3d) / sizeof(Block1K_3d[0]));
   1416 
   1417         *pWidth  = Block1K_3d[microBlockSizeTableIndex].w << averageAmp;
   1418         *pHeight = Block1K_3d[microBlockSizeTableIndex].h << (averageAmp + (restAmp / 2));
   1419         *pDepth  = Block1K_3d[microBlockSizeTableIndex].d << (averageAmp + ((restAmp != 0) ? 1 : 0));
   1420     }
   1421     else
   1422     {
   1423         ADDR_ASSERT_ALWAYS();
   1424         returnCode = ADDR_INVALIDPARAMS;
   1425     }
   1426 
   1427     return returnCode;
   1428 }
   1429 
   1430 /**
   1431 ************************************************************************************************************************
   1432 *   Lib::GetMipTailDim
   1433 *
   1434 *   @brief
   1435 *       Internal function to get out max dimension of first level in mip tail
   1436 *
   1437 *   @return
   1438 *       Max Width/Height/Depth value of the first mip fitted in mip tail
   1439 ************************************************************************************************************************
   1440 */
   1441 Dim3d Lib::GetMipTailDim(
   1442     AddrResourceType  resourceType,
   1443     AddrSwizzleMode   swizzleMode,
   1444     UINT_32           blockWidth,
   1445     UINT_32           blockHeight,
   1446     UINT_32           blockDepth) const
   1447 {
   1448     Dim3d   out         = {blockWidth, blockHeight, blockDepth};
   1449     UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode);
   1450 
   1451     if (IsThick(resourceType, swizzleMode))
   1452     {
   1453         UINT_32 dim = log2blkSize % 3;
   1454 
   1455         if (dim == 0)
   1456         {
   1457             out.h >>= 1;
   1458         }
   1459         else if (dim == 1)
   1460         {
   1461             out.w >>= 1;
   1462         }
   1463         else
   1464         {
   1465             out.d >>= 1;
   1466         }
   1467     }
   1468     else
   1469     {
   1470         if (log2blkSize & 1)
   1471         {
   1472             out.h >>= 1;
   1473         }
   1474         else
   1475         {
   1476             out.w >>= 1;
   1477         }
   1478     }
   1479 
   1480     return out;
   1481 }
   1482 
   1483 /**
   1484 ************************************************************************************************************************
   1485 *   Lib::ComputeSurface2DMicroBlockOffset
   1486 *
   1487 *   @brief
   1488 *       Internal function to calculate micro block (256B) offset from coord for 2D resource
   1489 *
   1490 *   @return
   1491 *       micro block (256B) offset for 2D resource
   1492 ************************************************************************************************************************
   1493 */
   1494 UINT_32 Lib::ComputeSurface2DMicroBlockOffset(
   1495     const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const
   1496 {
   1497     ADDR_ASSERT(IsThin(pIn->resourceType, pIn->swizzleMode));
   1498 
   1499     UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3);
   1500     UINT_32 microBlockOffset = 0;
   1501     if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode))
   1502     {
   1503         UINT_32 xBits = pIn->x << log2ElementBytes;
   1504         microBlockOffset = (xBits & 0xf) | ((pIn->y & 0x3) << 4);
   1505         if (log2ElementBytes < 3)
   1506         {
   1507             microBlockOffset |= (pIn->y & 0x4) << 4;
   1508             if (log2ElementBytes == 0)
   1509             {
   1510                 microBlockOffset |= (pIn->y & 0x8) << 4;
   1511             }
   1512             else
   1513             {
   1514                 microBlockOffset |= (xBits & 0x10) << 3;
   1515             }
   1516         }
   1517         else
   1518         {
   1519             microBlockOffset |= (xBits & 0x30) << 2;
   1520         }
   1521     }
   1522     else if (IsDisplaySwizzle(pIn->resourceType, pIn->swizzleMode))
   1523     {
   1524         if (log2ElementBytes == 4)
   1525         {
   1526             microBlockOffset = (GetBit(pIn->x, 0) << 4) |
   1527                                (GetBit(pIn->y, 0) << 5) |
   1528                                (GetBit(pIn->x, 1) << 6) |
   1529                                (GetBit(pIn->y, 1) << 7);
   1530         }
   1531         else
   1532         {
   1533             microBlockOffset = GetBits(pIn->x, 0, 3, log2ElementBytes)     |
   1534                                GetBits(pIn->y, 1, 2, 3 + log2ElementBytes) |
   1535                                GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) |
   1536                                GetBits(pIn->y, 3, 1, 6 + log2ElementBytes);
   1537             microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) |
   1538                                (GetBit(pIn->y, 0) << 4) |
   1539                                GetBits(microBlockOffset, 4, 3, 5);
   1540         }
   1541     }
   1542     else if (IsRotateSwizzle(pIn->swizzleMode))
   1543     {
   1544         microBlockOffset = GetBits(pIn->y, 0, 3, log2ElementBytes) |
   1545                            GetBits(pIn->x, 1, 2, 3 + log2ElementBytes) |
   1546                            GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) |
   1547                            GetBits(pIn->y, 3, 1, 6 + log2ElementBytes);
   1548         microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) |
   1549                            (GetBit(pIn->x, 0) << 4) |
   1550                            GetBits(microBlockOffset, 4, 3, 5);
   1551         if (log2ElementBytes == 3)
   1552         {
   1553            microBlockOffset = GetBits(microBlockOffset, 0, 6, 0) |
   1554                               GetBits(pIn->x, 1, 2, 6);
   1555         }
   1556     }
   1557 
   1558     return microBlockOffset;
   1559 }
   1560 
   1561 /**
   1562 ************************************************************************************************************************
   1563 *   Lib::ComputeSurface3DMicroBlockOffset
   1564 *
   1565 *   @brief
   1566 *       Internal function to calculate micro block (1KB) offset from coord for 3D resource
   1567 *
   1568 *   @return
   1569 *       micro block (1KB) offset for 3D resource
   1570 ************************************************************************************************************************
   1571 */
   1572 UINT_32 Lib::ComputeSurface3DMicroBlockOffset(
   1573     const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const
   1574 {
   1575     ADDR_ASSERT(IsThick(pIn->resourceType, pIn->swizzleMode));
   1576 
   1577     UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3);
   1578     UINT_32 microBlockOffset = 0;
   1579     if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode))
   1580     {
   1581         if (log2ElementBytes == 0)
   1582         {
   1583             microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1);
   1584         }
   1585         else if (log2ElementBytes == 1)
   1586         {
   1587             microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1);
   1588         }
   1589         else if (log2ElementBytes == 2)
   1590         {
   1591             microBlockOffset = ((pIn->y & 4) >> 2) | ((pIn->x & 4) >> 1);
   1592         }
   1593         else if (log2ElementBytes == 3)
   1594         {
   1595             microBlockOffset = (pIn->x & 6) >> 1;
   1596         }
   1597         else
   1598         {
   1599             microBlockOffset = pIn->x & 3;
   1600         }
   1601 
   1602         microBlockOffset <<= 8;
   1603 
   1604         UINT_32 xBits = pIn->x << log2ElementBytes;
   1605         microBlockOffset |= (xBits & 0xf) | ((pIn->y & 0x3) << 4) | ((pIn->slice & 0x3) << 6);
   1606     }
   1607     else if (IsZOrderSwizzle(pIn->swizzleMode))
   1608     {
   1609         UINT_32 xh, yh, zh;
   1610 
   1611         if (log2ElementBytes == 0)
   1612         {
   1613             microBlockOffset =
   1614                 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2);
   1615             microBlockOffset = microBlockOffset | ((pIn->slice & 3) << 4) | ((pIn->x & 4) << 4);
   1616 
   1617             xh = pIn->x >> 3;
   1618             yh = pIn->y >> 2;
   1619             zh = pIn->slice >> 2;
   1620         }
   1621         else if (log2ElementBytes == 1)
   1622         {
   1623             microBlockOffset =
   1624                 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2);
   1625             microBlockOffset = (microBlockOffset << 1) | ((pIn->slice & 3) << 5);
   1626 
   1627             xh = pIn->x >> 2;
   1628             yh = pIn->y >> 2;
   1629             zh = pIn->slice >> 2;
   1630         }
   1631         else if (log2ElementBytes == 2)
   1632         {
   1633             microBlockOffset =
   1634                 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->slice & 1) << 3);
   1635             microBlockOffset = (microBlockOffset << 2) | ((pIn->y & 2) << 5);
   1636 
   1637             xh = pIn->x >> 2;
   1638             yh = pIn->y >> 2;
   1639             zh = pIn->slice >> 1;
   1640         }
   1641         else if (log2ElementBytes == 3)
   1642         {
   1643             microBlockOffset =
   1644                 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2) | ((pIn->x & 2) << 2);
   1645             microBlockOffset <<= 3;
   1646 
   1647             xh = pIn->x >> 2;
   1648             yh = pIn->y >> 1;
   1649             zh = pIn->slice >> 1;
   1650         }
   1651         else
   1652         {
   1653             microBlockOffset =
   1654                 (((pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2)) << 4);
   1655 
   1656             xh = pIn->x >> 1;
   1657             yh = pIn->y >> 1;
   1658             zh = pIn->slice >> 1;
   1659         }
   1660 
   1661         microBlockOffset |= ((MortonGen3d(xh, yh, zh, 1) << 7) & 0x380);
   1662     }
   1663 
   1664     return microBlockOffset;
   1665 }
   1666 
   1667 /**
   1668 ************************************************************************************************************************
   1669 *   Lib::GetPipeXorBits
   1670 *
   1671 *   @brief
   1672 *       Internal function to get bits number for pipe/se xor operation
   1673 *
   1674 *   @return
   1675 *       ADDR_E_RETURNCODE
   1676 ************************************************************************************************************************
   1677 */
   1678 UINT_32 Lib::GetPipeXorBits(
   1679     UINT_32 macroBlockBits) const
   1680 {
   1681     ADDR_ASSERT(macroBlockBits >= m_pipeInterleaveLog2);
   1682 
   1683     // Total available xor bits
   1684     UINT_32 xorBits = macroBlockBits - m_pipeInterleaveLog2;
   1685 
   1686     // Pipe/Se xor bits
   1687     UINT_32 pipeBits = Min(xorBits, m_pipesLog2 + m_seLog2);
   1688 
   1689     return pipeBits;
   1690 }
   1691 
   1692 /**
   1693 ************************************************************************************************************************
   1694 *   Lib::GetBankXorBits
   1695 *
   1696 *   @brief
   1697 *       Internal function to get bits number for pipe/se xor operation
   1698 *
   1699 *   @return
   1700 *       ADDR_E_RETURNCODE
   1701 ************************************************************************************************************************
   1702 */
   1703 UINT_32 Lib::GetBankXorBits(
   1704     UINT_32 macroBlockBits) const
   1705 {
   1706     UINT_32 pipeBits = GetPipeXorBits(macroBlockBits);
   1707 
   1708     // Bank xor bits
   1709     UINT_32 bankBits = Min(macroBlockBits - pipeBits - m_pipeInterleaveLog2, m_banksLog2);
   1710 
   1711     return bankBits;
   1712 }
   1713 
   1714 /**
   1715 ************************************************************************************************************************
   1716 *   Lib::Addr2GetPreferredSurfaceSetting
   1717 *
   1718 *   @brief
   1719 *       Internal function to get suggested surface information for cliet to use
   1720 *
   1721 *   @return
   1722 *       ADDR_E_RETURNCODE
   1723 ************************************************************************************************************************
   1724 */
   1725 ADDR_E_RETURNCODE Lib::Addr2GetPreferredSurfaceSetting(
   1726     const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
   1727     ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const
   1728 {
   1729     ADDR_E_RETURNCODE returnCode;
   1730 
   1731     if ((GetFillSizeFieldsFlags() == TRUE) &&
   1732         ((pIn->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_INPUT)) ||
   1733          (pOut->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT))))
   1734     {
   1735         returnCode = ADDR_INVALIDPARAMS;
   1736     }
   1737     else
   1738     {
   1739         returnCode = HwlGetPreferredSurfaceSetting(pIn, pOut);
   1740     }
   1741 
   1742     return returnCode;
   1743 }
   1744 
   1745 /**
   1746 ************************************************************************************************************************
   1747 *   Lib::ComputeBlock256Equation
   1748 *
   1749 *   @brief
   1750 *       Compute equation for block 256B
   1751 *
   1752 *   @return
   1753 *       If equation computed successfully
   1754 *
   1755 ************************************************************************************************************************
   1756 */
   1757 ADDR_E_RETURNCODE Lib::ComputeBlock256Equation(
   1758     AddrResourceType rsrcType,
   1759     AddrSwizzleMode swMode,
   1760     UINT_32 elementBytesLog2,
   1761     ADDR_EQUATION* pEquation) const
   1762 {
   1763     ADDR_E_RETURNCODE ret;
   1764 
   1765     if (IsBlock256b(swMode))
   1766     {
   1767         ret = HwlComputeBlock256Equation(rsrcType, swMode, elementBytesLog2, pEquation);
   1768     }
   1769     else
   1770     {
   1771         ADDR_ASSERT_ALWAYS();
   1772         ret = ADDR_INVALIDPARAMS;
   1773     }
   1774 
   1775     return ret;
   1776 }
   1777 
   1778 /**
   1779 ************************************************************************************************************************
   1780 *   Lib::ComputeThinEquation
   1781 *
   1782 *   @brief
   1783 *       Compute equation for 2D/3D resource which use THIN mode
   1784 *
   1785 *   @return
   1786 *       If equation computed successfully
   1787 *
   1788 ************************************************************************************************************************
   1789 */
   1790 ADDR_E_RETURNCODE Lib::ComputeThinEquation(
   1791     AddrResourceType rsrcType,
   1792     AddrSwizzleMode swMode,
   1793     UINT_32 elementBytesLog2,
   1794     ADDR_EQUATION* pEquation) const
   1795 {
   1796     ADDR_E_RETURNCODE ret;
   1797 
   1798     if (IsThin(rsrcType, swMode))
   1799     {
   1800         ret = HwlComputeThinEquation(rsrcType, swMode, elementBytesLog2, pEquation);
   1801     }
   1802     else
   1803     {
   1804         ADDR_ASSERT_ALWAYS();
   1805         ret = ADDR_INVALIDPARAMS;
   1806     }
   1807 
   1808     return ret;
   1809 }
   1810 
   1811 /**
   1812 ************************************************************************************************************************
   1813 *   Lib::ComputeThickEquation
   1814 *
   1815 *   @brief
   1816 *       Compute equation for 3D resource which use THICK mode
   1817 *
   1818 *   @return
   1819 *       If equation computed successfully
   1820 *
   1821 ************************************************************************************************************************
   1822 */
   1823 ADDR_E_RETURNCODE Lib::ComputeThickEquation(
   1824     AddrResourceType rsrcType,
   1825     AddrSwizzleMode swMode,
   1826     UINT_32 elementBytesLog2,
   1827     ADDR_EQUATION* pEquation) const
   1828 {
   1829     ADDR_E_RETURNCODE ret;
   1830 
   1831     if (IsThick(rsrcType, swMode))
   1832     {
   1833         ret = HwlComputeThickEquation(rsrcType, swMode, elementBytesLog2, pEquation);
   1834     }
   1835     else
   1836     {
   1837         ADDR_ASSERT_ALWAYS();
   1838         ret = ADDR_INVALIDPARAMS;
   1839     }
   1840 
   1841     return ret;
   1842 }
   1843 
   1844 /**
   1845 ************************************************************************************************************************
   1846 *   Lib::ComputeQbStereoInfo
   1847 *
   1848 *   @brief
   1849 *       Get quad buffer stereo information
   1850 *   @return
   1851 *       N/A
   1852 ************************************************************************************************************************
   1853 */
   1854 VOID Lib::ComputeQbStereoInfo(
   1855     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut    ///< [in,out] updated pOut+pStereoInfo
   1856     ) const
   1857 {
   1858     ADDR_ASSERT(pOut->bpp >= 8);
   1859     ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0);
   1860 
   1861     // Save original height
   1862     pOut->pStereoInfo->eyeHeight = pOut->height;
   1863 
   1864     // Right offset
   1865     pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize);
   1866 
   1867     // Double height
   1868     pOut->height <<= 1;
   1869 
   1870     ADDR_ASSERT(pOut->height <= MaxSurfaceHeight);
   1871 
   1872     pOut->pixelHeight <<= 1;
   1873 
   1874     // Double size
   1875     pOut->surfSize <<= 1;
   1876 }
   1877 
   1878 
   1879 } // V2
   1880 } // Addr
   1881 
   1882