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