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