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