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