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