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