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