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