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