• 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 CIAddrLib class.
31 ***************************************************************************************************
32 */
33 
34 #include "ciaddrlib.h"
35 
36 #include "si_gb_reg.h"
37 
38 #include "si_ci_vi_merged_enum.h"
39 
40 #if BRAHMA_BUILD
41 #include "amdgpu_id.h"
42 #else
43 #include "ci_id.h"
44 #include "kv_id.h"
45 #include "vi_id.h"
46 #endif
47 
48 ///////////////////////////////////////////////////////////////////////////////////////////////////
49 ///////////////////////////////////////////////////////////////////////////////////////////////////
50 
51 /**
52 ***************************************************************************************************
53 *   AddrMask
54 *
55 *   @brief
56 *       Gets a mask of "width"
57 *   @return
58 *       Bit mask
59 ***************************************************************************************************
60 */
AddrMask(UINT_32 width)61 static UINT_64 AddrMask(
62     UINT_32 width)  ///< Width of bits
63 {
64     UINT_64 ret;
65 
66     if (width >= sizeof(UINT_64)*8)
67     {
68         ret = ~((UINT_64) 0);
69     }
70     else
71     {
72         return (((UINT_64) 1) << width) - 1;
73     }
74     return ret;
75 }
76 
77 /**
78 ***************************************************************************************************
79 *   AddrGetBits
80 *
81 *   @brief
82 *       Gets bits within a range of [msb, lsb]
83 *   @return
84 *       Bits of this range
85 ***************************************************************************************************
86 */
AddrGetBits(UINT_64 bits,UINT_32 msb,UINT_32 lsb)87 static UINT_64 AddrGetBits(
88     UINT_64 bits,   ///< Source bits
89     UINT_32 msb,    ///< Most signicant bit
90     UINT_32 lsb)    ///< Least signicant bit
91 {
92     UINT_64 ret = 0;
93 
94     if (msb >= lsb)
95     {
96         ret = (bits >> lsb) & (AddrMask(1 + msb - lsb));
97     }
98     return ret;
99 }
100 
101 /**
102 ***************************************************************************************************
103 *   AddrRemoveBits
104 *
105 *   @brief
106 *       Removes bits within the range of [msb, lsb]
107 *   @return
108 *       Modified bits
109 ***************************************************************************************************
110 */
AddrRemoveBits(UINT_64 bits,UINT_32 msb,UINT_32 lsb)111 static UINT_64 AddrRemoveBits(
112     UINT_64 bits,   ///< Source bits
113     UINT_32 msb,    ///< Most signicant bit
114     UINT_32 lsb)    ///< Least signicant bit
115 {
116     UINT_64 ret = bits;
117 
118     if (msb >= lsb)
119     {
120         ret = AddrGetBits(bits, lsb - 1, 0) // low bits
121             | (AddrGetBits(bits, 8 * sizeof(bits) - 1, msb + 1) << lsb); //high bits
122     }
123     return ret;
124 }
125 
126 /**
127 ***************************************************************************************************
128 *   AddrInsertBits
129 *
130 *   @brief
131 *       Inserts new bits into the range of [msb, lsb]
132 *   @return
133 *       Modified bits
134 ***************************************************************************************************
135 */
AddrInsertBits(UINT_64 bits,UINT_64 newBits,UINT_32 msb,UINT_32 lsb)136 static UINT_64 AddrInsertBits(
137     UINT_64 bits,       ///< Source bits
138     UINT_64 newBits,    ///< New bits to be inserted
139     UINT_32 msb,        ///< Most signicant bit
140     UINT_32 lsb)        ///< Least signicant bit
141 {
142     UINT_64 ret = bits;
143 
144     if (msb >= lsb)
145     {
146         ret = AddrGetBits(bits, lsb - 1, 0) // old low bitss
147              | (AddrGetBits(newBits, msb - lsb, 0) << lsb) //new bits
148              | (AddrGetBits(bits, 8 * sizeof(bits) - 1, lsb) << (msb + 1)); //old high bits
149     }
150     return ret;
151 }
152 
153 
154 /**
155 ***************************************************************************************************
156 *   AddrCIHwlInit
157 *
158 *   @brief
159 *       Creates an CIAddrLib object.
160 *
161 *   @return
162 *       Returns an CIAddrLib object pointer.
163 ***************************************************************************************************
164 */
AddrCIHwlInit(const AddrClient * pClient)165 AddrLib* AddrCIHwlInit(const AddrClient* pClient)
166 {
167     return CIAddrLib::CreateObj(pClient);
168 }
169 
170 /**
171 ***************************************************************************************************
172 *   CIAddrLib::CIAddrLib
173 *
174 *   @brief
175 *       Constructor
176 *
177 ***************************************************************************************************
178 */
CIAddrLib(const AddrClient * pClient)179 CIAddrLib::CIAddrLib(const AddrClient* pClient) :
180     SIAddrLib(pClient),
181     m_noOfMacroEntries(0),
182     m_allowNonDispThickModes(FALSE)
183 {
184     m_class = CI_ADDRLIB;
185     memset(&m_settings, 0, sizeof(m_settings));
186 }
187 
188 /**
189 ***************************************************************************************************
190 *   CIAddrLib::~CIAddrLib
191 *
192 *   @brief
193 *       Destructor
194 ***************************************************************************************************
195 */
~CIAddrLib()196 CIAddrLib::~CIAddrLib()
197 {
198 }
199 
200 /**
201 ***************************************************************************************************
202 *   CIAddrLib::HwlComputeDccInfo
203 *
204 *   @brief
205 *       Compute DCC key size, base alignment
206 *   @return
207 *       ADDR_E_RETURNCODE
208 ***************************************************************************************************
209 */
HwlComputeDccInfo(const ADDR_COMPUTE_DCCINFO_INPUT * pIn,ADDR_COMPUTE_DCCINFO_OUTPUT * pOut) const210 ADDR_E_RETURNCODE CIAddrLib::HwlComputeDccInfo(
211     const ADDR_COMPUTE_DCCINFO_INPUT*  pIn,
212     ADDR_COMPUTE_DCCINFO_OUTPUT*       pOut) const
213 {
214     ADDR_E_RETURNCODE returnCode = ADDR_OK;
215 
216     if (m_settings.isVolcanicIslands && IsMacroTiled(pIn->tileMode))
217     {
218         UINT_64 dccFastClearSize = pIn->colorSurfSize >> 8;
219 
220         ADDR_ASSERT(0 == (pIn->colorSurfSize & 0xff));
221 
222         if (pIn->numSamples > 1)
223         {
224             UINT_32 tileSizePerSample = BITS_TO_BYTES(pIn->bpp * MicroTileWidth * MicroTileHeight);
225             UINT_32 samplesPerSplit  = pIn->tileInfo.tileSplitBytes / tileSizePerSample;
226 
227             if (samplesPerSplit < pIn->numSamples)
228             {
229                 UINT_32 numSplits = pIn->numSamples / samplesPerSplit;
230                 UINT_32 fastClearBaseAlign = HwlGetPipes(&pIn->tileInfo) * m_pipeInterleaveBytes;
231 
232                 ADDR_ASSERT(IsPow2(fastClearBaseAlign));
233 
234                 dccFastClearSize /= numSplits;
235 
236                 if (0 != (dccFastClearSize & (fastClearBaseAlign - 1)))
237                 {
238                     // Disable dcc fast clear
239                     // if key size of fisrt sample split is not pipe*interleave aligned
240                     dccFastClearSize = 0;
241                 }
242             }
243         }
244 
245         pOut->dccRamSize          = pIn->colorSurfSize >> 8;
246         pOut->dccRamBaseAlign     = pIn->tileInfo.banks *
247                                     HwlGetPipes(&pIn->tileInfo) *
248                                     m_pipeInterleaveBytes;
249         pOut->dccFastClearSize    = dccFastClearSize;
250 
251         ADDR_ASSERT(IsPow2(pOut->dccRamBaseAlign));
252 
253         if (0 == (pOut->dccRamSize & (pOut->dccRamBaseAlign - 1)))
254         {
255             pOut->subLvlCompressible = TRUE;
256         }
257         else
258         {
259             UINT_64 dccRamSizeAlign = HwlGetPipes(&pIn->tileInfo) * m_pipeInterleaveBytes;
260 
261             if (pOut->dccRamSize == pOut->dccFastClearSize)
262             {
263                 pOut->dccFastClearSize = PowTwoAlign(pOut->dccRamSize, dccRamSizeAlign);
264             }
265             pOut->dccRamSize          = PowTwoAlign(pOut->dccRamSize, dccRamSizeAlign);
266             pOut->subLvlCompressible  = FALSE;
267         }
268     }
269     else
270     {
271         returnCode = ADDR_NOTSUPPORTED;
272     }
273 
274     return returnCode;
275 }
276 
277 /**
278 ***************************************************************************************************
279 *   CIAddrLib::HwlComputeCmaskAddrFromCoord
280 *
281 *   @brief
282 *       Compute tc compatible Cmask address from fmask ram address
283 *
284 *   @return
285 *       ADDR_E_RETURNCODE
286 ***************************************************************************************************
287 */
HwlComputeCmaskAddrFromCoord(const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT * pIn,ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT * pOut) const288 ADDR_E_RETURNCODE CIAddrLib::HwlComputeCmaskAddrFromCoord(
289     const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*  pIn,  ///< [in] fmask addr/bpp/tile input
290     ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*       pOut  ///< [out] cmask address
291     ) const
292 {
293     ADDR_E_RETURNCODE returnCode = ADDR_NOTSUPPORTED;
294 
295     if ((m_settings.isVolcanicIslands == TRUE) &&
296         (pIn->flags.tcCompatible == TRUE))
297     {
298         UINT_32 numOfPipes   = HwlGetPipes(pIn->pTileInfo);
299         UINT_32 numOfBanks   = pIn->pTileInfo->banks;
300         UINT_64 fmaskAddress = pIn->fmaskAddr;
301         UINT_32 elemBits     = pIn->bpp;
302         UINT_32 blockByte    = 64 * elemBits / 8;
303         UINT_64 metaNibbleAddress = HwlComputeMetadataNibbleAddress(fmaskAddress,
304                                                                     0,
305                                                                     0,
306                                                                     4,
307                                                                     elemBits,
308                                                                     blockByte,
309                                                                     m_pipeInterleaveBytes,
310                                                                     numOfPipes,
311                                                                     numOfBanks,
312                                                                     1);
313         pOut->addr = (metaNibbleAddress >> 1);
314         pOut->bitPosition = (metaNibbleAddress % 2) ? 4 : 0;
315         returnCode = ADDR_OK;
316     }
317 
318     return returnCode;
319 }
320 /**
321 ***************************************************************************************************
322 *   CIAddrLib::HwlConvertChipFamily
323 *
324 *   @brief
325 *       Convert familyID defined in atiid.h to AddrChipFamily and set m_chipFamily/m_chipRevision
326 *   @return
327 *       AddrChipFamily
328 ***************************************************************************************************
329 */
HwlConvertChipFamily(UINT_32 uChipFamily,UINT_32 uChipRevision)330 AddrChipFamily CIAddrLib::HwlConvertChipFamily(
331     UINT_32 uChipFamily,        ///< [in] chip family defined in atiih.h
332     UINT_32 uChipRevision)      ///< [in] chip revision defined in "asic_family"_id.h
333 {
334     AddrChipFamily family = ADDR_CHIP_FAMILY_CI;
335 
336     switch (uChipFamily)
337     {
338         case FAMILY_CI:
339             m_settings.isSeaIsland  = 1;
340             m_settings.isBonaire    = ASICREV_IS_BONAIRE_M(uChipRevision);
341             m_settings.isHawaii     = ASICREV_IS_HAWAII_P(uChipRevision);
342             break;
343         case FAMILY_KV:
344             m_settings.isKaveri     = 1;
345             m_settings.isSpectre    = ASICREV_IS_SPECTRE(uChipRevision);
346             m_settings.isSpooky     = ASICREV_IS_SPOOKY(uChipRevision);
347             m_settings.isKalindi    = ASICREV_IS_KALINDI(uChipRevision);
348             break;
349         case FAMILY_VI:
350             m_settings.isVolcanicIslands = 1;
351             m_settings.isIceland         = ASICREV_IS_ICELAND_M(uChipRevision);
352             m_settings.isTonga           = ASICREV_IS_TONGA_P(uChipRevision);
353             m_settings.isFiji            = ASICREV_IS_FIJI_P(uChipRevision);
354             m_settings.isPolaris10       = ASICREV_IS_POLARIS10_P(uChipRevision);
355             m_settings.isPolaris11       = ASICREV_IS_POLARIS11_M(uChipRevision);
356             m_settings.isPolaris12       = ASICREV_IS_POLARIS12_V(uChipRevision);
357             break;
358         case FAMILY_CZ:
359             m_settings.isCarrizo         = 1;
360             m_settings.isVolcanicIslands = 1;
361             break;
362         default:
363             ADDR_ASSERT(!"This should be a unexpected Fusion");
364             break;
365     }
366 
367     return family;
368 }
369 
370 /**
371 ***************************************************************************************************
372 *   CIAddrLib::HwlInitGlobalParams
373 *
374 *   @brief
375 *       Initializes global parameters
376 *
377 *   @return
378 *       TRUE if all settings are valid
379 *
380 ***************************************************************************************************
381 */
HwlInitGlobalParams(const ADDR_CREATE_INPUT * pCreateIn)382 BOOL_32 CIAddrLib::HwlInitGlobalParams(
383     const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input
384 {
385     BOOL_32  valid = TRUE;
386 
387     const ADDR_REGISTER_VALUE* pRegValue = &pCreateIn->regValue;
388 
389     valid = DecodeGbRegs(pRegValue);
390 
391     // The following assignments for m_pipes is only for fail-safe, InitTileSettingTable should
392     // read the correct pipes from tile mode table
393     if (m_settings.isHawaii)
394     {
395         // Hawaii has 16-pipe, see GFXIP_Config_Summary.xls
396         m_pipes = 16;
397     }
398     else if (m_settings.isBonaire || m_settings.isSpectre)
399     {
400         m_pipes = 4;
401     }
402     else // Treat other KV asics to be 2-pipe
403     {
404         m_pipes = 2;
405     }
406 
407     // @todo: VI
408     // Move this to VI code path once created
409     if (m_settings.isTonga || m_settings.isPolaris10)
410     {
411         m_pipes = 8;
412     }
413     else if (m_settings.isIceland)
414     {
415         m_pipes = 2;
416     }
417     else if (m_settings.isFiji)
418     {
419         m_pipes = 16;
420     }
421     else if (m_settings.isPolaris11 || m_settings.isPolaris12)
422     {
423         m_pipes = 4;
424     }
425 
426     if (valid)
427     {
428         valid = InitTileSettingTable(pRegValue->pTileConfig, pRegValue->noOfEntries);
429     }
430     if (valid)
431     {
432         valid = InitMacroTileCfgTable(pRegValue->pMacroTileConfig, pRegValue->noOfMacroEntries);
433     }
434 
435     return valid;
436 }
437 
438 /**
439 ***************************************************************************************************
440 *   CIAddrLib::HwlPostCheckTileIndex
441 *
442 *   @brief
443 *       Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches
444 *       tile mode/type/info and change the index if needed
445 *   @return
446 *       Tile index.
447 ***************************************************************************************************
448 */
HwlPostCheckTileIndex(const ADDR_TILEINFO * pInfo,AddrTileMode mode,AddrTileType type,INT curIndex) const449 INT_32 CIAddrLib::HwlPostCheckTileIndex(
450     const ADDR_TILEINFO* pInfo,     ///< [in] Tile Info
451     AddrTileMode         mode,      ///< [in] Tile mode
452     AddrTileType         type,      ///< [in] Tile type
453     INT                  curIndex   ///< [in] Current index assigned in HwlSetupTileInfo
454     ) const
455 {
456     INT_32 index = curIndex;
457 
458     if (mode == ADDR_TM_LINEAR_GENERAL)
459     {
460         index = TileIndexLinearGeneral;
461     }
462     else
463     {
464         BOOL_32 macroTiled = IsMacroTiled(mode);
465 
466         // We need to find a new index if either of them is true
467         // 1. curIndex is invalid
468         // 2. tile mode is changed
469         // 3. tile info does not match for macro tiled
470         if ((index == TileIndexInvalid)         ||
471             (mode != m_tileTable[index].mode)   ||
472             (macroTiled && pInfo->pipeConfig != m_tileTable[index].info.pipeConfig))
473         {
474             for (index = 0; index < static_cast<INT_32>(m_noOfEntries); index++)
475             {
476                 if (macroTiled)
477                 {
478                     // macro tile modes need all to match
479                     if ((pInfo->pipeConfig == m_tileTable[index].info.pipeConfig) &&
480                         (mode == m_tileTable[index].mode) &&
481                         (type == m_tileTable[index].type))
482                     {
483                         // tileSplitBytes stored in m_tileTable is only valid for depth entries
484                         if (type == ADDR_DEPTH_SAMPLE_ORDER)
485                         {
486                             if (pInfo->tileSplitBytes == m_tileTable[index].info.tileSplitBytes)
487                             {
488                                 break;
489                             }
490                         }
491                         else // other entries are determined by other 3 fields
492                         {
493                             break;
494                         }
495                     }
496                 }
497                 else if (mode == ADDR_TM_LINEAR_ALIGNED)
498                 {
499                     // linear mode only needs tile mode to match
500                     if (mode == m_tileTable[index].mode)
501                     {
502                         break;
503                     }
504                 }
505                 else
506                 {
507                     // micro tile modes only need tile mode and tile type to match
508                     if (mode == m_tileTable[index].mode &&
509                         type == m_tileTable[index].type)
510                     {
511                         break;
512                     }
513                 }
514             }
515         }
516     }
517 
518     ADDR_ASSERT(index < static_cast<INT_32>(m_noOfEntries));
519 
520     if (index >= static_cast<INT_32>(m_noOfEntries))
521     {
522         index = TileIndexInvalid;
523     }
524 
525     return index;
526 }
527 
528 /**
529 ***************************************************************************************************
530 *   CIAddrLib::HwlSetupTileCfg
531 *
532 *   @brief
533 *       Map tile index to tile setting.
534 *   @return
535 *       ADDR_E_RETURNCODE
536 ***************************************************************************************************
537 */
HwlSetupTileCfg(INT_32 index,INT_32 macroModeIndex,ADDR_TILEINFO * pInfo,AddrTileMode * pMode,AddrTileType * pType) const538 ADDR_E_RETURNCODE CIAddrLib::HwlSetupTileCfg(
539     INT_32          index,          ///< [in] Tile index
540     INT_32          macroModeIndex, ///< [in] Index in macro tile mode table(CI)
541     ADDR_TILEINFO*  pInfo,          ///< [out] Tile Info
542     AddrTileMode*   pMode,          ///< [out] Tile mode
543     AddrTileType*   pType           ///< [out] Tile type
544     ) const
545 {
546     ADDR_E_RETURNCODE returnCode = ADDR_OK;
547 
548     // Global flag to control usage of tileIndex
549     if (UseTileIndex(index))
550     {
551         if (static_cast<UINT_32>(index) >= m_noOfEntries)
552         {
553             returnCode = ADDR_INVALIDPARAMS;
554         }
555         else
556         {
557             const ADDR_TILECONFIG* pCfgTable = GetTileSetting(index);
558 
559             if (pInfo != NULL)
560             {
561                 if (IsMacroTiled(pCfgTable->mode))
562                 {
563                     ADDR_ASSERT(((macroModeIndex != TileIndexInvalid)
564                         && (macroModeIndex != TileIndexNoMacroIndex)));
565                     // Here we used tile_bytes to replace of tile_split
566                     // According info as below:
567                     // "tile_split_c = MIN(ROW_SIZE, tile_split)
568                     // "tile_bytes = MIN(tile_split_c, num_samples * tile_bytes_1x)
569                     // when using tile_bytes replacing of tile_split, the result of
570                     // alignment and others(such as slicesPerTile) are unaffected -
571                     // since if tile_split_c is larger, split won't happen, otherwise
572                     // (num_samples * tile_bytes_1x is larger), a correct tile_split is
573                     // returned.
574                     *pInfo = m_macroTileTable[macroModeIndex];
575 
576                     if (pCfgTable->type == ADDR_DEPTH_SAMPLE_ORDER)
577                     {
578                         pInfo->tileSplitBytes = pCfgTable->info.tileSplitBytes;
579                     }
580                     pInfo->pipeConfig = pCfgTable->info.pipeConfig;
581                 }
582                 else // 1D and linear modes, we return default value stored in table
583                 {
584                     *pInfo = pCfgTable->info;
585                 }
586             }
587 
588             if (pMode != NULL)
589             {
590                 *pMode = pCfgTable->mode;
591             }
592 
593             if (pType != NULL)
594             {
595                 *pType = pCfgTable->type;
596             }
597         }
598     }
599 
600     return returnCode;
601 }
602 
603 /**
604 ***************************************************************************************************
605 *   CIAddrLib::HwlComputeSurfaceInfo
606 *
607 *   @brief
608 *       Entry of ci's ComputeSurfaceInfo
609 *   @return
610 *       ADDR_E_RETURNCODE
611 ***************************************************************************************************
612 */
HwlComputeSurfaceInfo(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const613 ADDR_E_RETURNCODE CIAddrLib::HwlComputeSurfaceInfo(
614     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,    ///< [in] input structure
615     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [out] output structure
616     ) const
617 {
618     // If tileIndex is invalid, force macroModeIndex to be invalid, too
619     if (pIn->tileIndex == TileIndexInvalid)
620     {
621         pOut->macroModeIndex = TileIndexInvalid;
622     }
623 
624     ADDR_E_RETURNCODE retCode = SIAddrLib::HwlComputeSurfaceInfo(pIn,pOut);
625 
626     if (pOut->macroModeIndex == TileIndexNoMacroIndex)
627     {
628         pOut->macroModeIndex = TileIndexInvalid;
629     }
630 
631     return retCode;
632 }
633 
634 /**
635 ***************************************************************************************************
636 *   CIAddrLib::HwlFmaskSurfaceInfo
637 *   @brief
638 *       Entry of r800's ComputeFmaskInfo
639 *   @return
640 *       ADDR_E_RETURNCODE
641 ***************************************************************************************************
642 */
HwlComputeFmaskInfo(const ADDR_COMPUTE_FMASK_INFO_INPUT * pIn,ADDR_COMPUTE_FMASK_INFO_OUTPUT * pOut)643 ADDR_E_RETURNCODE CIAddrLib::HwlComputeFmaskInfo(
644     const ADDR_COMPUTE_FMASK_INFO_INPUT*    pIn,   ///< [in] input structure
645     ADDR_COMPUTE_FMASK_INFO_OUTPUT*         pOut   ///< [out] output structure
646     )
647 {
648     ADDR_E_RETURNCODE retCode = ADDR_OK;
649 
650     ADDR_TILEINFO tileInfo = {0};
651     ADDR_COMPUTE_FMASK_INFO_INPUT fmaskIn;
652     fmaskIn = *pIn;
653 
654     AddrTileMode tileMode = pIn->tileMode;
655 
656     // Use internal tile info if pOut does not have a valid pTileInfo
657     if (pOut->pTileInfo == NULL)
658     {
659         pOut->pTileInfo = &tileInfo;
660     }
661 
662     ADDR_ASSERT(tileMode == ADDR_TM_2D_TILED_THIN1     ||
663                 tileMode == ADDR_TM_3D_TILED_THIN1     ||
664                 tileMode == ADDR_TM_PRT_TILED_THIN1    ||
665                 tileMode == ADDR_TM_PRT_2D_TILED_THIN1 ||
666                 tileMode == ADDR_TM_PRT_3D_TILED_THIN1);
667 
668     ADDR_ASSERT(m_tileTable[14].mode == ADDR_TM_2D_TILED_THIN1);
669     ADDR_ASSERT(m_tileTable[15].mode == ADDR_TM_3D_TILED_THIN1);
670 
671     // The only valid tile modes for fmask are 2D_THIN1 and 3D_THIN1 plus non-displayable
672     INT_32 tileIndex = tileMode == ADDR_TM_2D_TILED_THIN1 ? 14 : 15;
673     ADDR_SURFACE_FLAGS flags = {{0}};
674     flags.fmask = 1;
675 
676     INT_32 macroModeIndex = TileIndexInvalid;
677 
678     UINT_32 numSamples = pIn->numSamples;
679     UINT_32 numFrags = pIn->numFrags == 0 ? numSamples : pIn->numFrags;
680 
681     UINT_32 bpp = QLog2(numFrags);
682 
683     // EQAA needs one more bit
684     if (numSamples > numFrags)
685     {
686         bpp++;
687     }
688 
689     if (bpp == 3)
690     {
691         bpp = 4;
692     }
693 
694     bpp = Max(8u, bpp * numSamples);
695 
696     macroModeIndex = HwlComputeMacroModeIndex(tileIndex, flags, bpp, numSamples, pOut->pTileInfo);
697 
698     fmaskIn.tileIndex = tileIndex;
699     fmaskIn.pTileInfo = pOut->pTileInfo;
700     pOut->macroModeIndex = macroModeIndex;
701     pOut->tileIndex = tileIndex;
702 
703     retCode = DispatchComputeFmaskInfo(&fmaskIn, pOut);
704 
705     if (retCode == ADDR_OK)
706     {
707         pOut->tileIndex =
708             HwlPostCheckTileIndex(pOut->pTileInfo, pIn->tileMode, ADDR_NON_DISPLAYABLE,
709                                   pOut->tileIndex);
710     }
711 
712     // Resets pTileInfo to NULL if the internal tile info is used
713     if (pOut->pTileInfo == &tileInfo)
714     {
715         pOut->pTileInfo = NULL;
716     }
717 
718     return retCode;
719 }
720 
721 /**
722 ***************************************************************************************************
723 *   CIAddrLib::HwlFmaskPreThunkSurfInfo
724 *
725 *   @brief
726 *       Some preparation before thunking a ComputeSurfaceInfo call for Fmask
727 *   @return
728 *       ADDR_E_RETURNCODE
729 ***************************************************************************************************
730 */
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) const731 VOID CIAddrLib::HwlFmaskPreThunkSurfInfo(
732     const ADDR_COMPUTE_FMASK_INFO_INPUT*    pFmaskIn,   ///< [in] Input of fmask info
733     const ADDR_COMPUTE_FMASK_INFO_OUTPUT*   pFmaskOut,  ///< [in] Output of fmask info
734     ADDR_COMPUTE_SURFACE_INFO_INPUT*        pSurfIn,    ///< [out] Input of thunked surface info
735     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pSurfOut    ///< [out] Output of thunked surface info
736     ) const
737 {
738     pSurfIn->tileIndex = pFmaskIn->tileIndex;
739     pSurfOut->macroModeIndex  = pFmaskOut->macroModeIndex;
740 }
741 
742 /**
743 ***************************************************************************************************
744 *   CIAddrLib::HwlFmaskPostThunkSurfInfo
745 *
746 *   @brief
747 *       Copy hwl extra field after calling thunked ComputeSurfaceInfo
748 *   @return
749 *       ADDR_E_RETURNCODE
750 ***************************************************************************************************
751 */
HwlFmaskPostThunkSurfInfo(const ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pSurfOut,ADDR_COMPUTE_FMASK_INFO_OUTPUT * pFmaskOut) const752 VOID CIAddrLib::HwlFmaskPostThunkSurfInfo(
753     const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut,   ///< [in] Output of surface info
754     ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut           ///< [out] Output of fmask info
755     ) const
756 {
757     pFmaskOut->tileIndex = pSurfOut->tileIndex;
758     pFmaskOut->macroModeIndex = pSurfOut->macroModeIndex;
759 }
760 
761 /**
762 ***************************************************************************************************
763 *   CIAddrLib::HwlDegradeThickTileMode
764 *
765 *   @brief
766 *       Degrades valid tile mode for thick modes if needed
767 *
768 *   @return
769 *       Suitable tile mode
770 ***************************************************************************************************
771 */
HwlDegradeThickTileMode(AddrTileMode baseTileMode,UINT_32 numSlices,UINT_32 * pBytesPerTile) const772 AddrTileMode CIAddrLib::HwlDegradeThickTileMode(
773     AddrTileMode        baseTileMode,   ///< [in] base tile mode
774     UINT_32             numSlices,      ///< [in] current number of slices
775     UINT_32*            pBytesPerTile   ///< [in/out] pointer to bytes per slice
776     ) const
777 {
778     return baseTileMode;
779 }
780 
781 /**
782 ***************************************************************************************************
783 *   CIAddrLib::HwlOverrideTileMode
784 *
785 *   @brief
786 *       Override THICK to THIN, for specific formats on CI
787 *
788 *   @return
789 *       Suitable tile mode
790 *
791 ***************************************************************************************************
792 */
HwlOverrideTileMode(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,AddrTileMode * pTileMode,AddrTileType * pTileType) const793 BOOL_32 CIAddrLib::HwlOverrideTileMode(
794     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,       ///< [in] input structure
795     AddrTileMode*                           pTileMode, ///< [in/out] pointer to the tile mode
796     AddrTileType*                           pTileType  ///< [in/out] pointer to the tile type
797     ) const
798 {
799     BOOL_32 bOverrided = FALSE;
800     AddrTileMode tileMode = *pTileMode;
801 
802     // currently, all CI/VI family do not
803     // support ADDR_TM_PRT_2D_TILED_THICK,ADDR_TM_PRT_3D_TILED_THICK and
804     // ADDR_TM_PRT_2D_TILED_THIN1, ADDR_TM_PRT_3D_TILED_THIN1
805     switch (tileMode)
806     {
807         case ADDR_TM_PRT_2D_TILED_THICK:
808         case ADDR_TM_PRT_3D_TILED_THICK:
809             tileMode = ADDR_TM_PRT_TILED_THICK;
810             break;
811         case ADDR_TM_PRT_2D_TILED_THIN1:
812         case ADDR_TM_PRT_3D_TILED_THIN1:
813             tileMode = ADDR_TM_PRT_TILED_THIN1;
814             break;
815         default:
816             break;
817     }
818 
819     // UBTS#404321, we do not need such overriding, as THICK+THICK entries removed from the tile-mode table
820     if (!m_settings.isBonaire)
821     {
822         UINT_32 thickness = ComputeSurfaceThickness(tileMode);
823 
824         // tile_thickness = (array_mode == XTHICK) ? 8 : ((array_mode == THICK) ? 4 : 1)
825         if (thickness > 1)
826         {
827             switch (pIn->format)
828             {
829                 // see //gfxip/gcB/devel/cds/src/verif/tc/models/csim/tcp.cpp
830                 // tcpError("Thick micro tiling is not supported for format...
831                 case ADDR_FMT_X24_8_32_FLOAT:
832                 case ADDR_FMT_32_AS_8:
833                 case ADDR_FMT_32_AS_8_8:
834                 case ADDR_FMT_32_AS_32_32_32_32:
835 
836                 // packed formats
837                 case ADDR_FMT_GB_GR:
838                 case ADDR_FMT_BG_RG:
839                 case ADDR_FMT_1_REVERSED:
840                 case ADDR_FMT_1:
841                 case ADDR_FMT_BC1:
842                 case ADDR_FMT_BC2:
843                 case ADDR_FMT_BC3:
844                 case ADDR_FMT_BC4:
845                 case ADDR_FMT_BC5:
846                 case ADDR_FMT_BC6:
847                 case ADDR_FMT_BC7:
848                     switch (tileMode)
849                     {
850                         case ADDR_TM_1D_TILED_THICK:
851                             tileMode    = ADDR_TM_1D_TILED_THIN1;
852                             break;
853 
854                         case ADDR_TM_2D_TILED_XTHICK:
855                         case ADDR_TM_2D_TILED_THICK:
856                             tileMode    = ADDR_TM_2D_TILED_THIN1;
857                             break;
858 
859                         case ADDR_TM_3D_TILED_XTHICK:
860                         case ADDR_TM_3D_TILED_THICK:
861                             tileMode    = ADDR_TM_3D_TILED_THIN1;
862                             break;
863 
864                         case ADDR_TM_PRT_TILED_THICK:
865                             tileMode    = ADDR_TM_PRT_TILED_THIN1;
866                             break;
867 
868                         case ADDR_TM_PRT_2D_TILED_THICK:
869                             tileMode    = ADDR_TM_PRT_2D_TILED_THIN1;
870                             break;
871 
872                         case ADDR_TM_PRT_3D_TILED_THICK:
873                             tileMode    = ADDR_TM_PRT_3D_TILED_THIN1;
874                             break;
875 
876                         default:
877                             break;
878 
879                     }
880 
881                     // Switch tile type from thick to thin
882                     if (tileMode != *pTileMode)
883                     {
884                         // see tileIndex: 13-18
885                         *pTileType = ADDR_NON_DISPLAYABLE;
886                     }
887 
888                     break;
889                 default:
890                     break;
891             }
892         }
893     }
894 
895     if (tileMode != *pTileMode)
896     {
897         *pTileMode = tileMode;
898         bOverrided = TRUE;
899     }
900 
901     return bOverrided;
902 }
903 
904 /**
905 ***************************************************************************************************
906 *   CiAddrLib::GetPrtSwitchP4Threshold
907 *
908 *   @brief
909 *       Return the threshold of switching to P4_* instead of P16_* for PRT resources
910 ***************************************************************************************************
911 */
GetPrtSwitchP4Threshold() const912 UINT_32 CIAddrLib::GetPrtSwitchP4Threshold() const
913 {
914     UINT_32 threshold;
915 
916     switch (m_pipes)
917     {
918         case 8:
919             threshold = 32;
920             break;
921         case 16:
922             if (m_settings.isFiji)
923             {
924                 threshold = 16;
925             }
926             else if (m_settings.isHawaii)
927             {
928                 threshold = 8;
929             }
930             else
931             {
932                 ///@todo add for possible new ASICs.
933                 ADDR_ASSERT_ALWAYS();
934                 threshold = 16;
935             }
936             break;
937         default:
938             ///@todo add for possible new ASICs.
939             ADDR_ASSERT_ALWAYS();
940             threshold = 32;
941             break;
942     }
943 
944     return threshold;
945 }
946 
947 /**
948 ***************************************************************************************************
949 *   CIAddrLib::HwlSetupTileInfo
950 *
951 *   @brief
952 *       Setup default value of tile info for SI
953 ***************************************************************************************************
954 */
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) const955 VOID CIAddrLib::HwlSetupTileInfo(
956     AddrTileMode                        tileMode,       ///< [in] Tile mode
957     ADDR_SURFACE_FLAGS                  flags,          ///< [in] Surface type flags
958     UINT_32                             bpp,            ///< [in] Bits per pixel
959     UINT_32                             pitch,          ///< [in] Pitch in pixels
960     UINT_32                             height,         ///< [in] Height in pixels
961     UINT_32                             numSamples,     ///< [in] Number of samples
962     ADDR_TILEINFO*                      pTileInfoIn,    ///< [in] Tile info input: NULL for default
963     ADDR_TILEINFO*                      pTileInfoOut,   ///< [out] Tile info output
964     AddrTileType                        inTileType,     ///< [in] Tile type
965     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*   pOut            ///< [out] Output
966     ) const
967 {
968     UINT_32 thickness = ComputeSurfaceThickness(tileMode);
969     ADDR_TILEINFO* pTileInfo = pTileInfoOut;
970     INT index = TileIndexInvalid;
971     INT macroModeIndex = TileIndexInvalid;
972 
973     // Fail-safe code
974     if (!IsLinear(tileMode))
975     {
976         // Thick tile modes must use thick micro tile mode but Bonaire does not support due to
977         // old derived netlists (UBTS 404321)
978         if (thickness > 1)
979         {
980             if (m_settings.isBonaire)
981             {
982                 inTileType = ADDR_NON_DISPLAYABLE;
983             }
984             else if ((m_allowNonDispThickModes == FALSE) || (inTileType != ADDR_NON_DISPLAYABLE))
985             {
986                 inTileType = ADDR_THICK;
987             }
988         }
989         // 128 bpp tiling must be non-displayable.
990         // Fmask reuse color buffer's entry but bank-height field can be from another entry
991         // To simplify the logic, fmask entry should be picked from non-displayable ones
992         else if (bpp == 128 || flags.fmask)
993         {
994             inTileType = ADDR_NON_DISPLAYABLE;
995         }
996         // These two modes only have non-disp entries though they can be other micro tile modes
997         else if (tileMode == ADDR_TM_3D_TILED_THIN1 || tileMode == ADDR_TM_PRT_3D_TILED_THIN1)
998         {
999             inTileType = ADDR_NON_DISPLAYABLE;
1000         }
1001 
1002         if (flags.depth || flags.stencil)
1003         {
1004             inTileType = ADDR_DEPTH_SAMPLE_ORDER;
1005         }
1006     }
1007 
1008     if (IsTileInfoAllZero(pTileInfo))
1009     {
1010         // See table entries 0-4
1011         if (flags.depth || flags.stencil)
1012         {
1013             if (flags.depth && flags.tcCompatible)
1014             {
1015                 // tileSize = bpp * numSamples * 8 * 8 / 8
1016                 UINT_32 tileSize = bpp * numSamples * 8;
1017 
1018                 // Texure readable depth surface should not be split
1019                 switch (tileSize)
1020                 {
1021                     case 128:
1022                         index = 1;
1023                         break;
1024                     case 256:
1025                         index = 2;
1026                         break;
1027                     case 512:
1028                         index = 3;
1029                         break;
1030                     default:
1031                         index = 4;
1032                         break;
1033                 }
1034             }
1035             else
1036             {
1037                 // Depth and stencil need to use the same index, thus the pre-defined tile_split
1038                 // can meet the requirement to choose the same macro mode index
1039                 // uncompressed depth/stencil are not supported for now
1040                 switch (numSamples)
1041                 {
1042                     case 1:
1043                         index = 0;
1044                         break;
1045                     case 2:
1046                     case 4:
1047                         index = 1;
1048                         break;
1049                     case 8:
1050                         index = 2;
1051                         break;
1052                     default:
1053                         break;
1054                 }
1055             }
1056         }
1057 
1058         // See table entries 5-6
1059         if (inTileType == ADDR_DEPTH_SAMPLE_ORDER)
1060         {
1061             switch (tileMode)
1062             {
1063                 case ADDR_TM_1D_TILED_THIN1:
1064                     index = 5;
1065                     break;
1066                 case ADDR_TM_PRT_TILED_THIN1:
1067                     index = 6;
1068                     break;
1069                 default:
1070                     break;
1071             }
1072         }
1073 
1074         // See table entries 8-12
1075         if (inTileType == ADDR_DISPLAYABLE)
1076         {
1077             switch (tileMode)
1078             {
1079                 case ADDR_TM_1D_TILED_THIN1:
1080                     index = 9;
1081                     break;
1082                 case ADDR_TM_2D_TILED_THIN1:
1083                     index = 10;
1084                     break;
1085                 case ADDR_TM_PRT_TILED_THIN1:
1086                     index = 11;
1087                     break;
1088                 default:
1089                     break;
1090             }
1091         }
1092 
1093         // See table entries 13-18
1094         if (inTileType == ADDR_NON_DISPLAYABLE)
1095         {
1096             switch (tileMode)
1097             {
1098                 case ADDR_TM_1D_TILED_THIN1:
1099                     index = 13;
1100                     break;
1101                 case ADDR_TM_2D_TILED_THIN1:
1102                     index = 14;
1103                     break;
1104                 case ADDR_TM_3D_TILED_THIN1:
1105                     index = 15;
1106                     break;
1107                 case ADDR_TM_PRT_TILED_THIN1:
1108                     index = 16;
1109                     break;
1110                 default:
1111                     break;
1112             }
1113         }
1114 
1115         // See table entries 19-26
1116         if (thickness > 1)
1117         {
1118             switch (tileMode)
1119             {
1120             case ADDR_TM_1D_TILED_THICK:
1121                     //special check for bonaire, for the compatablity between old KMD and new UMD for bonaire
1122                     index = ((inTileType == ADDR_THICK) || m_settings.isBonaire) ? 19 : 18;
1123                     break;
1124             case ADDR_TM_2D_TILED_THICK:
1125                     // special check for bonaire, for the compatablity between old KMD and new UMD for bonaire
1126                     index = ((inTileType == ADDR_THICK) || m_settings.isBonaire) ? 20 : 24;
1127                     break;
1128                 case ADDR_TM_3D_TILED_THICK:
1129                     index = 21;
1130                     break;
1131                 case ADDR_TM_PRT_TILED_THICK:
1132                     index = 22;
1133                     break;
1134                 case ADDR_TM_2D_TILED_XTHICK:
1135                     index = 25;
1136                     break;
1137                 case ADDR_TM_3D_TILED_XTHICK:
1138                     index = 26;
1139                     break;
1140                 default:
1141                     break;
1142             }
1143         }
1144 
1145         // See table entries 27-30
1146         if (inTileType == ADDR_ROTATED)
1147         {
1148             switch (tileMode)
1149             {
1150                 case ADDR_TM_1D_TILED_THIN1:
1151                     index = 27;
1152                     break;
1153                 case ADDR_TM_2D_TILED_THIN1:
1154                     index = 28;
1155                     break;
1156                 case ADDR_TM_PRT_TILED_THIN1:
1157                     index = 29;
1158                     break;
1159                 case ADDR_TM_PRT_2D_TILED_THIN1:
1160                     index = 30;
1161                     break;
1162                 default:
1163                     break;
1164             }
1165         }
1166 
1167         if (m_pipes >= 8)
1168         {
1169             ADDR_ASSERT((index + 1) < static_cast<INT_32>(m_noOfEntries));
1170             // Only do this when tile mode table is updated.
1171             if (((tileMode == ADDR_TM_PRT_TILED_THIN1) || (tileMode == ADDR_TM_PRT_TILED_THICK)) &&
1172                 (m_tileTable[index+1].mode == tileMode))
1173             {
1174                 UINT_32 bytesXSamples = bpp * numSamples / 8;
1175                 UINT_32 bytesXThickness = bpp * thickness / 8;
1176                 UINT_32 switchP4Threshold = GetPrtSwitchP4Threshold();
1177 
1178                 if ((bytesXSamples > switchP4Threshold) || (bytesXThickness > switchP4Threshold))
1179                 {
1180                     // Pick next 4 pipe entry
1181                     index += 1;
1182                 }
1183             }
1184         }
1185     }
1186     else
1187     {
1188         // A pre-filled tile info is ready
1189         index = pOut->tileIndex;
1190         macroModeIndex = pOut->macroModeIndex;
1191 
1192         // pass tile type back for post tile index compute
1193         pOut->tileType = inTileType;
1194     }
1195 
1196     // We only need to set up tile info if there is a valid index but macroModeIndex is invalid
1197     if (index != TileIndexInvalid && macroModeIndex == TileIndexInvalid)
1198     {
1199         macroModeIndex = HwlComputeMacroModeIndex(index, flags, bpp, numSamples, pTileInfo);
1200 
1201         /// Copy to pOut->tileType/tileIndex/macroModeIndex
1202         pOut->tileIndex = index;
1203         pOut->tileType = m_tileTable[index].type; // Or inTileType, the samea
1204         pOut->macroModeIndex = macroModeIndex;
1205     }
1206     else if (tileMode == ADDR_TM_LINEAR_GENERAL)
1207     {
1208         pOut->tileIndex = TileIndexLinearGeneral;
1209 
1210         // Copy linear-aligned entry??
1211         *pTileInfo = m_tileTable[8].info;
1212     }
1213     else if (tileMode == ADDR_TM_LINEAR_ALIGNED)
1214     {
1215         pOut->tileIndex = 8;
1216         *pTileInfo = m_tileTable[8].info;
1217     }
1218 }
1219 
1220 /**
1221 ***************************************************************************************************
1222 *   CIAddrLib::ReadGbTileMode
1223 *
1224 *   @brief
1225 *       Convert GB_TILE_MODE HW value to ADDR_TILE_CONFIG.
1226 *   @return
1227 *       NA.
1228 ***************************************************************************************************
1229 */
ReadGbTileMode(UINT_32 regValue,ADDR_TILECONFIG * pCfg) const1230 VOID CIAddrLib::ReadGbTileMode(
1231     UINT_32             regValue,   ///< [in] GB_TILE_MODE register
1232     ADDR_TILECONFIG*    pCfg        ///< [out] output structure
1233     ) const
1234 {
1235     GB_TILE_MODE gbTileMode;
1236     gbTileMode.val = regValue;
1237 
1238     pCfg->type = static_cast<AddrTileType>(gbTileMode.f.micro_tile_mode_new);
1239     pCfg->info.pipeConfig = static_cast<AddrPipeCfg>(gbTileMode.f.pipe_config + 1);
1240 
1241     if (pCfg->type == ADDR_DEPTH_SAMPLE_ORDER)
1242     {
1243         pCfg->info.tileSplitBytes = 64 << gbTileMode.f.tile_split;
1244     }
1245     else
1246     {
1247         pCfg->info.tileSplitBytes = 1 << gbTileMode.f.sample_split;
1248     }
1249 
1250     UINT_32 regArrayMode = gbTileMode.f.array_mode;
1251 
1252     pCfg->mode = static_cast<AddrTileMode>(regArrayMode);
1253 
1254     switch (regArrayMode)
1255     {
1256         case 5:
1257             pCfg->mode = ADDR_TM_PRT_TILED_THIN1;
1258             break;
1259         case 6:
1260             pCfg->mode = ADDR_TM_PRT_2D_TILED_THIN1;
1261             break;
1262         case 8:
1263             pCfg->mode = ADDR_TM_2D_TILED_XTHICK;
1264             break;
1265         case 9:
1266             pCfg->mode = ADDR_TM_PRT_TILED_THICK;
1267             break;
1268         case 0xa:
1269             pCfg->mode = ADDR_TM_PRT_2D_TILED_THICK;
1270             break;
1271         case 0xb:
1272             pCfg->mode = ADDR_TM_PRT_3D_TILED_THIN1;
1273             break;
1274         case 0xe:
1275             pCfg->mode = ADDR_TM_3D_TILED_XTHICK;
1276             break;
1277         case 0xf:
1278             pCfg->mode = ADDR_TM_PRT_3D_TILED_THICK;
1279             break;
1280         default:
1281             break;
1282     }
1283 
1284     // Fail-safe code for these always convert tile info, as the non-macro modes
1285     // return the entry of tile mode table directly without looking up macro mode table
1286     if (!IsMacroTiled(pCfg->mode))
1287     {
1288         pCfg->info.banks = 2;
1289         pCfg->info.bankWidth = 1;
1290         pCfg->info.bankHeight = 1;
1291         pCfg->info.macroAspectRatio = 1;
1292         pCfg->info.tileSplitBytes = 64;
1293     }
1294 }
1295 
1296 /**
1297 ***************************************************************************************************
1298 *   CIAddrLib::InitTileSettingTable
1299 *
1300 *   @brief
1301 *       Initialize the ADDR_TILE_CONFIG table.
1302 *   @return
1303 *       TRUE if tile table is correctly initialized
1304 ***************************************************************************************************
1305 */
InitTileSettingTable(const UINT_32 * pCfg,UINT_32 noOfEntries)1306 BOOL_32 CIAddrLib::InitTileSettingTable(
1307     const UINT_32*  pCfg,           ///< [in] Pointer to table of tile configs
1308     UINT_32         noOfEntries     ///< [in] Numbe of entries in the table above
1309     )
1310 {
1311     BOOL_32 initOk = TRUE;
1312 
1313     ADDR_ASSERT(noOfEntries <= TileTableSize);
1314 
1315     memset(m_tileTable, 0, sizeof(m_tileTable));
1316 
1317     if (noOfEntries != 0)
1318     {
1319         m_noOfEntries = noOfEntries;
1320     }
1321     else
1322     {
1323         m_noOfEntries = TileTableSize;
1324     }
1325 
1326     if (pCfg) // From Client
1327     {
1328         for (UINT_32 i = 0; i < m_noOfEntries; i++)
1329         {
1330             ReadGbTileMode(*(pCfg + i), &m_tileTable[i]);
1331         }
1332     }
1333     else
1334     {
1335         ADDR_ASSERT_ALWAYS();
1336         initOk = FALSE;
1337     }
1338 
1339     if (initOk)
1340     {
1341         ADDR_ASSERT(m_tileTable[TILEINDEX_LINEAR_ALIGNED].mode == ADDR_TM_LINEAR_ALIGNED);
1342 
1343         if (m_settings.isBonaire == FALSE)
1344         {
1345             // Check if entry 18 is "thick+thin" combination
1346             if ((m_tileTable[18].mode == ADDR_TM_1D_TILED_THICK) &&
1347                 (m_tileTable[18].type == ADDR_NON_DISPLAYABLE))
1348             {
1349                 m_allowNonDispThickModes = TRUE;
1350                 ADDR_ASSERT(m_tileTable[24].mode == ADDR_TM_2D_TILED_THICK);
1351             }
1352         }
1353         else
1354         {
1355             m_allowNonDispThickModes = TRUE;
1356         }
1357 
1358         // Assume the first entry is always programmed with full pipes
1359         m_pipes = HwlGetPipes(&m_tileTable[0].info);
1360     }
1361 
1362     return initOk;
1363 }
1364 
1365 /**
1366 ***************************************************************************************************
1367 *   CIAddrLib::ReadGbMacroTileCfg
1368 *
1369 *   @brief
1370 *       Convert GB_MACRO_TILE_CFG HW value to ADDR_TILE_CONFIG.
1371 *   @return
1372 *       NA.
1373 ***************************************************************************************************
1374 */
ReadGbMacroTileCfg(UINT_32 regValue,ADDR_TILEINFO * pCfg) const1375 VOID CIAddrLib::ReadGbMacroTileCfg(
1376     UINT_32             regValue,   ///< [in] GB_MACRO_TILE_MODE register
1377     ADDR_TILEINFO*      pCfg        ///< [out] output structure
1378     ) const
1379 {
1380     GB_MACROTILE_MODE gbTileMode;
1381     gbTileMode.val = regValue;
1382 
1383     pCfg->bankHeight = 1 << gbTileMode.f.bank_height;
1384     pCfg->bankWidth = 1 << gbTileMode.f.bank_width;
1385     pCfg->banks = 1 << (gbTileMode.f.num_banks + 1);
1386     pCfg->macroAspectRatio = 1 << gbTileMode.f.macro_tile_aspect;
1387 }
1388 
1389 /**
1390 ***************************************************************************************************
1391 *   CIAddrLib::InitMacroTileCfgTable
1392 *
1393 *   @brief
1394 *       Initialize the ADDR_MACRO_TILE_CONFIG table.
1395 *   @return
1396 *       TRUE if macro tile table is correctly initialized
1397 ***************************************************************************************************
1398 */
InitMacroTileCfgTable(const UINT_32 * pCfg,UINT_32 noOfMacroEntries)1399 BOOL_32 CIAddrLib::InitMacroTileCfgTable(
1400     const UINT_32*  pCfg,           ///< [in] Pointer to table of tile configs
1401     UINT_32         noOfMacroEntries     ///< [in] Numbe of entries in the table above
1402     )
1403 {
1404     BOOL_32 initOk = TRUE;
1405 
1406     ADDR_ASSERT(noOfMacroEntries <= MacroTileTableSize);
1407 
1408     memset(m_macroTileTable, 0, sizeof(m_macroTileTable));
1409 
1410     if (noOfMacroEntries != 0)
1411     {
1412         m_noOfMacroEntries = noOfMacroEntries;
1413     }
1414     else
1415     {
1416         m_noOfMacroEntries = MacroTileTableSize;
1417     }
1418 
1419     if (pCfg) // From Client
1420     {
1421         for (UINT_32 i = 0; i < m_noOfMacroEntries; i++)
1422         {
1423             ReadGbMacroTileCfg(*(pCfg + i), &m_macroTileTable[i]);
1424 
1425             m_macroTileTable[i].tileSplitBytes = 64 << (i % 8);
1426         }
1427     }
1428     else
1429     {
1430         ADDR_ASSERT_ALWAYS();
1431         initOk = FALSE;
1432     }
1433     return initOk;
1434 }
1435 
1436 /**
1437 ***************************************************************************************************
1438 *   CIAddrLib::HwlComputeMacroModeIndex
1439 *
1440 *   @brief
1441 *       Computes macro tile mode index
1442 *   @return
1443 *       TRUE if macro tile table is correctly initialized
1444 ***************************************************************************************************
1445 */
HwlComputeMacroModeIndex(INT_32 tileIndex,ADDR_SURFACE_FLAGS flags,UINT_32 bpp,UINT_32 numSamples,ADDR_TILEINFO * pTileInfo,AddrTileMode * pTileMode,AddrTileType * pTileType) const1446 INT_32 CIAddrLib::HwlComputeMacroModeIndex(
1447     INT_32              tileIndex,      ///< [in] Tile mode index
1448     ADDR_SURFACE_FLAGS  flags,          ///< [in] Surface flags
1449     UINT_32             bpp,            ///< [in] Bit per pixel
1450     UINT_32             numSamples,     ///< [in] Number of samples
1451     ADDR_TILEINFO*      pTileInfo,      ///< [out] Pointer to ADDR_TILEINFO
1452     AddrTileMode*       pTileMode,      ///< [out] Pointer to AddrTileMode
1453     AddrTileType*       pTileType       ///< [out] Pointer to AddrTileType
1454     ) const
1455 {
1456     INT_32 macroModeIndex = TileIndexInvalid;
1457 
1458     if (flags.tcCompatible && flags.stencil)
1459     {
1460         // Don't compute macroModeIndex for tc compatible stencil surface
1461         macroModeIndex = TileIndexNoMacroIndex;
1462     }
1463     else
1464     {
1465         AddrTileMode tileMode = m_tileTable[tileIndex].mode;
1466         AddrTileType tileType = m_tileTable[tileIndex].type;
1467         UINT_32 thickness = ComputeSurfaceThickness(tileMode);
1468 
1469         if (!IsMacroTiled(tileMode))
1470         {
1471             *pTileInfo = m_tileTable[tileIndex].info;
1472             macroModeIndex = TileIndexNoMacroIndex;
1473         }
1474         else
1475         {
1476             UINT_32 tileBytes1x = BITS_TO_BYTES(bpp * MicroTilePixels * thickness);
1477             UINT_32 tileSplit;
1478 
1479             if (m_tileTable[tileIndex].type == ADDR_DEPTH_SAMPLE_ORDER)
1480             {
1481                 // Depth entries store real tileSplitBytes
1482                 tileSplit = m_tileTable[tileIndex].info.tileSplitBytes;
1483             }
1484             else
1485             {
1486                 // Non-depth entries store a split factor
1487                 UINT_32 sampleSplit = m_tileTable[tileIndex].info.tileSplitBytes;
1488                 UINT_32 colorTileSplit = Max(256u, sampleSplit * tileBytes1x);
1489 
1490                 tileSplit = colorTileSplit;
1491             }
1492 
1493             UINT_32 tileSplitC = Min(m_rowSize, tileSplit);
1494             UINT_32 tileBytes;
1495 
1496             if (flags.fmask)
1497             {
1498                 tileBytes = Min(tileSplitC, tileBytes1x);
1499             }
1500             else
1501             {
1502                 tileBytes = Min(tileSplitC, numSamples * tileBytes1x);
1503             }
1504 
1505             if (tileBytes < 64)
1506             {
1507                 tileBytes = 64;
1508             }
1509 
1510             macroModeIndex = Log2(tileBytes / 64);
1511 
1512             if (flags.prt || IsPrtTileMode(tileMode))
1513             {
1514                 // Unknown - assume it is 1/2 of table size
1515                 const UINT_32 PrtMacroModeOffset = MacroTileTableSize / 2;
1516 
1517                 macroModeIndex += PrtMacroModeOffset;
1518                 *pTileInfo = m_macroTileTable[macroModeIndex];
1519             }
1520             else
1521             {
1522                 *pTileInfo = m_macroTileTable[macroModeIndex];
1523             }
1524 
1525             pTileInfo->pipeConfig = m_tileTable[tileIndex].info.pipeConfig;
1526 
1527             if (m_tileTable[tileIndex].type != ADDR_DEPTH_SAMPLE_ORDER)
1528             {
1529                 pTileInfo->tileSplitBytes = tileSplitC;
1530             }
1531             else
1532             {
1533                 pTileInfo->tileSplitBytes = m_tileTable[tileIndex].info.tileSplitBytes;
1534             }
1535         }
1536 
1537         if (NULL != pTileMode)
1538         {
1539             *pTileMode = tileMode;
1540         }
1541 
1542         if (NULL != pTileType)
1543         {
1544             *pTileType = tileType;
1545         }
1546     }
1547 
1548     return macroModeIndex;
1549 }
1550 
1551 /**
1552 ***************************************************************************************************
1553 *   CIAddrLib::HwlComputeTileDataWidthAndHeightLinear
1554 *
1555 *   @brief
1556 *       Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1557 *
1558 *   @return
1559 *       N/A
1560 *
1561 *   @note
1562 *       MacroWidth and macroHeight are measured in pixels
1563 ***************************************************************************************************
1564 */
HwlComputeTileDataWidthAndHeightLinear(UINT_32 * pMacroWidth,UINT_32 * pMacroHeight,UINT_32 bpp,ADDR_TILEINFO * pTileInfo) const1565 VOID CIAddrLib::HwlComputeTileDataWidthAndHeightLinear(
1566     UINT_32*        pMacroWidth,     ///< [out] macro tile width
1567     UINT_32*        pMacroHeight,    ///< [out] macro tile height
1568     UINT_32         bpp,             ///< [in] bits per pixel
1569     ADDR_TILEINFO*  pTileInfo        ///< [in] tile info
1570     ) const
1571 {
1572     ADDR_ASSERT(pTileInfo != NULL);
1573 
1574     UINT_32 numTiles;
1575 
1576     switch (pTileInfo->pipeConfig)
1577     {
1578         case ADDR_PIPECFG_P16_32x32_8x16:
1579         case ADDR_PIPECFG_P16_32x32_16x16:
1580         case ADDR_PIPECFG_P8_32x64_32x32:
1581         case ADDR_PIPECFG_P8_32x32_16x32:
1582         case ADDR_PIPECFG_P8_32x32_16x16:
1583         case ADDR_PIPECFG_P8_32x32_8x16:
1584         case ADDR_PIPECFG_P4_32x32:
1585             numTiles = 8;
1586             break;
1587         default:
1588             numTiles = 4;
1589             break;
1590     }
1591 
1592     *pMacroWidth    = numTiles * MicroTileWidth;
1593     *pMacroHeight   = numTiles * MicroTileHeight;
1594 }
1595 
1596 /**
1597 ***************************************************************************************************
1598 *   CIAddrLib::HwlStereoCheckRightOffsetPadding
1599 *
1600 *   @brief
1601 *       check if the height needs extra padding for stereo right eye offset, to avoid swizzling
1602 *
1603 *   @return
1604 *       TRUE is the extra padding is needed
1605 *
1606 *   @note
1607 *       Kalindi (Kabini) is the only one that needs this padding as there is a uncertain
1608 *       possible HW issue where the right eye displays incorrectly with some type of swizzles, if
1609 *       the right eye offset is not 64KB aligned - EPR#366461
1610 *       Other Kaveri APUs also need the padding according to DXX team's report otherwise
1611 *       corruption observed. - EPR#374788
1612 ***************************************************************************************************
1613 */
HwlStereoCheckRightOffsetPadding() const1614 BOOL_32 CIAddrLib::HwlStereoCheckRightOffsetPadding() const
1615 {
1616     BOOL_32 bNeedPadding = FALSE;
1617 
1618     if (m_settings.isKaveri)
1619     {
1620         bNeedPadding = TRUE;
1621     }
1622 
1623     return bNeedPadding;
1624 }
1625 
1626 /**
1627 ***************************************************************************************************
1628 *   CIAddrLib::HwlComputeMetadataNibbleAddress
1629 *
1630 *   @brief
1631 *        calculate meta data address based on input information
1632 *
1633 *   &parameter
1634 *        uncompressedDataByteAddress - address of a pixel in color surface
1635 *        dataBaseByteAddress         - base address of color surface
1636 *        metadataBaseByteAddress     - base address of meta ram
1637 *        metadataBitSize             - meta key size, 8 for DCC, 4 for cmask
1638 *        elementBitSize              - element size of color surface
1639 *        blockByteSize               - compression block size, 256 for DCC
1640 *        pipeInterleaveBytes         - pipe interleave size
1641 *        numOfPipes                  - number of pipes
1642 *        numOfBanks                  - number of banks
1643 *        numOfSamplesPerSplit        - number of samples per tile split
1644 *   @return
1645 *        meta data nibble address (nibble address is used to support DCC compatible cmask)
1646 *
1647 ***************************************************************************************************
1648 */
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) const1649 UINT_64 CIAddrLib::HwlComputeMetadataNibbleAddress(
1650     UINT_64 uncompressedDataByteAddress,
1651     UINT_64 dataBaseByteAddress,
1652     UINT_64 metadataBaseByteAddress,
1653     UINT_32 metadataBitSize,
1654     UINT_32 elementBitSize,
1655     UINT_32 blockByteSize,
1656     UINT_32 pipeInterleaveBytes,
1657     UINT_32 numOfPipes,
1658     UINT_32 numOfBanks,
1659     UINT_32 numOfSamplesPerSplit) const
1660 {
1661     ///--------------------------------------------------------------------------------------------
1662     /// Get pipe interleave, bank and pipe bits
1663     ///--------------------------------------------------------------------------------------------
1664     UINT_32 pipeInterleaveBits  = Log2(pipeInterleaveBytes);
1665     UINT_32 pipeBits            = Log2(numOfPipes);
1666     UINT_32 bankBits            = Log2(numOfBanks);
1667 
1668     ///--------------------------------------------------------------------------------------------
1669     /// Clear pipe and bank swizzles
1670     ///--------------------------------------------------------------------------------------------
1671     UINT_32 dataMacrotileBits        = pipeInterleaveBits + pipeBits + bankBits;
1672     UINT_32 metadataMacrotileBits    = pipeInterleaveBits + pipeBits + bankBits;
1673 
1674     UINT_64 dataMacrotileClearMask     = ~((1L << dataMacrotileBits) - 1);
1675     UINT_64 metadataMacrotileClearMask = ~((1L << metadataMacrotileBits) - 1);
1676 
1677     UINT_64 dataBaseByteAddressNoSwizzle = dataBaseByteAddress & dataMacrotileClearMask;
1678     UINT_64 metadataBaseByteAddressNoSwizzle = metadataBaseByteAddress & metadataMacrotileClearMask;
1679 
1680     ///--------------------------------------------------------------------------------------------
1681     /// Modify metadata base before adding in so that when final address is divided by data ratio,
1682     /// the base address returns to where it should be
1683     ///--------------------------------------------------------------------------------------------
1684     ADDR_ASSERT((0 != metadataBitSize));
1685     UINT_64 metadataBaseShifted = metadataBaseByteAddressNoSwizzle * blockByteSize * 8 /
1686                                   metadataBitSize;
1687     UINT_64 offset = uncompressedDataByteAddress -
1688                      dataBaseByteAddressNoSwizzle +
1689                      metadataBaseShifted;
1690 
1691     ///--------------------------------------------------------------------------------------------
1692     /// Save bank data bits
1693     ///--------------------------------------------------------------------------------------------
1694     UINT_32 lsb = pipeBits + pipeInterleaveBits;
1695     UINT_32 msb = bankBits - 1 + lsb;
1696 
1697     UINT_64 bankDataBits = AddrGetBits(offset, msb, lsb);
1698 
1699     ///--------------------------------------------------------------------------------------------
1700     /// Save pipe data bits
1701     ///--------------------------------------------------------------------------------------------
1702     lsb = pipeInterleaveBits;
1703     msb = pipeBits - 1 + lsb;
1704 
1705     UINT_64 pipeDataBits = AddrGetBits(offset, msb, lsb);
1706 
1707     ///--------------------------------------------------------------------------------------------
1708     /// Remove pipe and bank bits
1709     ///--------------------------------------------------------------------------------------------
1710     lsb = pipeInterleaveBits;
1711     msb = dataMacrotileBits - 1;
1712 
1713     UINT_64 offsetWithoutPipeBankBits = AddrRemoveBits(offset, msb, lsb);
1714 
1715     ADDR_ASSERT((0 != blockByteSize));
1716     UINT_64 blockInBankpipe = offsetWithoutPipeBankBits / blockByteSize;
1717 
1718     UINT_32 tileSize = 8 * 8 * elementBitSize/8 * numOfSamplesPerSplit;
1719     UINT_32 blocksInTile = tileSize / blockByteSize;
1720 
1721     if (0 == blocksInTile)
1722     {
1723         lsb = 0;
1724     }
1725     else
1726     {
1727         lsb = Log2(blocksInTile);
1728     }
1729     msb = bankBits - 1 + lsb;
1730 
1731     UINT_64 blockInBankpipeWithBankBits = AddrInsertBits(blockInBankpipe, bankDataBits, msb, lsb);
1732 
1733     /// NOTE *2 because we are converting to Nibble address in this step
1734     UINT_64 metaAddressInPipe = blockInBankpipeWithBankBits * 2 * metadataBitSize / 8;
1735 
1736 
1737     ///--------------------------------------------------------------------------------------------
1738     /// Reinsert pipe bits back into the final address
1739     ///--------------------------------------------------------------------------------------------
1740     lsb = pipeInterleaveBits + 1; ///<+1 due to Nibble address now gives interleave bits extra lsb.
1741     msb = pipeBits - 1 + lsb;
1742     UINT_64 metadataAddress = AddrInsertBits(metaAddressInPipe, pipeDataBits, msb, lsb);
1743 
1744     return metadataAddress;
1745 }
1746 
1747 /**
1748 ***************************************************************************************************
1749 *   CIAddrLib::HwlPadDimensions
1750 *
1751 *   @brief
1752 *       Helper function to pad dimensions
1753 *
1754 *   @return
1755 *       N/A
1756 *
1757 ***************************************************************************************************
1758 */
HwlPadDimensions(AddrTileMode tileMode,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 numSamples,ADDR_TILEINFO * pTileInfo,UINT_32 padDims,UINT_32 mipLevel,UINT_32 * pPitch,UINT_32 pitchAlign,UINT_32 * pHeight,UINT_32 heightAlign,UINT_32 * pSlices,UINT_32 sliceAlign) const1759 VOID CIAddrLib::HwlPadDimensions(
1760     AddrTileMode        tileMode,    ///< [in] tile mode
1761     UINT_32             bpp,         ///< [in] bits per pixel
1762     ADDR_SURFACE_FLAGS  flags,       ///< [in] surface flags
1763     UINT_32             numSamples,  ///< [in] number of samples
1764     ADDR_TILEINFO*      pTileInfo,   ///< [in/out] bank structure.
1765     UINT_32             padDims,     ///< [in] Dimensions to pad valid value 1,2,3
1766     UINT_32             mipLevel,    ///< [in] MipLevel
1767     UINT_32*            pPitch,      ///< [in/out] pitch in pixels
1768     UINT_32             pitchAlign,  ///< [in] pitch alignment
1769     UINT_32*            pHeight,     ///< [in/out] height in pixels
1770     UINT_32             heightAlign, ///< [in] height alignment
1771     UINT_32*            pSlices,     ///< [in/out] number of slices
1772     UINT_32             sliceAlign   ///< [in] number of slice alignment
1773     ) const
1774 {
1775     if (m_settings.isVolcanicIslands &&
1776         flags.dccCompatible &&
1777         (numSamples > 1) &&
1778         (mipLevel == 0) &&
1779         IsMacroTiled(tileMode))
1780     {
1781         UINT_32 tileSizePerSample = BITS_TO_BYTES(bpp * MicroTileWidth * MicroTileHeight);
1782         UINT_32 samplesPerSplit  = pTileInfo->tileSplitBytes / tileSizePerSample;
1783 
1784         if (samplesPerSplit < numSamples)
1785         {
1786             UINT_32 dccFastClearByteAlign = HwlGetPipes(pTileInfo) * m_pipeInterleaveBytes * 256;
1787             UINT_32 bytesPerSplit = BITS_TO_BYTES((*pPitch) * (*pHeight) * bpp * samplesPerSplit);
1788 
1789             ADDR_ASSERT(IsPow2(dccFastClearByteAlign));
1790 
1791             if (0 != (bytesPerSplit & (dccFastClearByteAlign - 1)))
1792             {
1793                 UINT_32 dccFastClearPixelAlign = dccFastClearByteAlign /
1794                                                 BITS_TO_BYTES(bpp) /
1795                                                 samplesPerSplit;
1796                 UINT_32 macroTilePixelAlign = pitchAlign * heightAlign;
1797 
1798                 if ((dccFastClearPixelAlign >= macroTilePixelAlign) &&
1799                     ((dccFastClearPixelAlign % macroTilePixelAlign) == 0))
1800                 {
1801                     UINT_32 dccFastClearPitchAlignInMacroTile =
1802                         dccFastClearPixelAlign / macroTilePixelAlign;
1803                     UINT_32 heightInMacroTile = *pHeight / heightAlign;
1804                     UINT_32 dccFastClearPitchAlignInPixels;
1805 
1806                     while ((heightInMacroTile > 1) &&
1807                            ((heightInMacroTile % 2) == 0) &&
1808                            (dccFastClearPitchAlignInMacroTile > 1) &&
1809                            ((dccFastClearPitchAlignInMacroTile % 2) == 0))
1810                     {
1811                         heightInMacroTile >>= 1;
1812                         dccFastClearPitchAlignInMacroTile >>= 1;
1813                     }
1814 
1815                     dccFastClearPitchAlignInPixels = pitchAlign * dccFastClearPitchAlignInMacroTile;
1816 
1817                     if (IsPow2(dccFastClearPitchAlignInPixels))
1818                     {
1819                         *pPitch = PowTwoAlign((*pPitch), dccFastClearPitchAlignInPixels);
1820                     }
1821                     else
1822                     {
1823                         *pPitch += (dccFastClearPitchAlignInPixels - 1);
1824                         *pPitch /= dccFastClearPitchAlignInPixels;
1825                         *pPitch *= dccFastClearPitchAlignInPixels;
1826                     }
1827                 }
1828             }
1829         }
1830     }
1831 }
1832 
1833