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