2 * Copyright © 2014 Advanced Micro Devices, Inc.
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:
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.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
28 ***************************************************************************************************
30 * @brief Contains the implementation for the CIAddrLib class.
31 ***************************************************************************************************
34 #include "ciaddrlib.h"
36 #include "si_gb_reg.h"
38 #include "si_ci_vi_merged_enum.h"
41 #include "amdgpu_id.h"
48 ///////////////////////////////////////////////////////////////////////////////////////////////////
49 ///////////////////////////////////////////////////////////////////////////////////////////////////
52 ***************************************************************************************************
56 * Gets a mask of "width"
59 ***************************************************************************************************
61 static UINT_64
AddrMask(
62 UINT_32 width
) ///< Width of bits
66 if (width
>= sizeof(UINT_64
)*8)
72 return (((UINT_64
) 1) << width
) - 1;
78 ***************************************************************************************************
82 * Gets bits within a range of [msb, lsb]
85 ***************************************************************************************************
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
96 ret
= (bits
>> lsb
) & (AddrMask(1 + msb
- lsb
));
102 ***************************************************************************************************
106 * Removes bits within the range of [msb, lsb]
109 ***************************************************************************************************
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
120 ret
= AddrGetBits(bits
, lsb
- 1, 0) // low bits
121 | (AddrGetBits(bits
, 8 * sizeof(bits
) - 1, msb
+ 1) << lsb
); //high bits
127 ***************************************************************************************************
131 * Inserts new bits into the range of [msb, lsb]
134 ***************************************************************************************************
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
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
155 ***************************************************************************************************
159 * Creates an CIAddrLib object.
162 * Returns an CIAddrLib object pointer.
163 ***************************************************************************************************
165 AddrLib
* AddrCIHwlInit(const AddrClient
* pClient
)
167 return CIAddrLib::CreateObj(pClient
);
171 ***************************************************************************************************
172 * CIAddrLib::CIAddrLib
177 ***************************************************************************************************
179 CIAddrLib::CIAddrLib(const AddrClient
* pClient
) :
181 m_noOfMacroEntries(0),
182 m_allowNonDispThickModes(FALSE
)
184 m_class
= CI_ADDRLIB
;
185 memset(&m_settings
, 0, sizeof(m_settings
));
189 ***************************************************************************************************
190 * CIAddrLib::~CIAddrLib
194 ***************************************************************************************************
196 CIAddrLib::~CIAddrLib()
201 ***************************************************************************************************
202 * CIAddrLib::HwlComputeDccInfo
205 * Compute DCC key size, base alignment
208 ***************************************************************************************************
210 ADDR_E_RETURNCODE
CIAddrLib::HwlComputeDccInfo(
211 const ADDR_COMPUTE_DCCINFO_INPUT
* pIn
,
212 ADDR_COMPUTE_DCCINFO_OUTPUT
* pOut
) const
214 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
216 if (m_settings
.isVolcanicIslands
&& IsMacroTiled(pIn
->tileMode
))
218 UINT_64 dccFastClearSize
= pIn
->colorSurfSize
>> 8;
220 ADDR_ASSERT(0 == (pIn
->colorSurfSize
& 0xff));
222 if (pIn
->numSamples
> 1)
224 UINT_32 tileSizePerSample
= BITS_TO_BYTES(pIn
->bpp
* MicroTileWidth
* MicroTileHeight
);
225 UINT_32 samplesPerSplit
= pIn
->tileInfo
.tileSplitBytes
/ tileSizePerSample
;
227 if (samplesPerSplit
< pIn
->numSamples
)
229 UINT_32 numSplits
= pIn
->numSamples
/ samplesPerSplit
;
230 UINT_32 fastClearBaseAlign
= HwlGetPipes(&pIn
->tileInfo
) * m_pipeInterleaveBytes
;
232 ADDR_ASSERT(IsPow2(fastClearBaseAlign
));
234 dccFastClearSize
/= numSplits
;
236 if (0 != (dccFastClearSize
& (fastClearBaseAlign
- 1)))
238 // Disable dcc fast clear
239 // if key size of fisrt sample split is not pipe*interleave aligned
240 dccFastClearSize
= 0;
245 pOut
->dccRamSize
= pIn
->colorSurfSize
>> 8;
246 pOut
->dccRamBaseAlign
= pIn
->tileInfo
.banks
*
247 HwlGetPipes(&pIn
->tileInfo
) *
248 m_pipeInterleaveBytes
;
249 pOut
->dccFastClearSize
= dccFastClearSize
;
251 ADDR_ASSERT(IsPow2(pOut
->dccRamBaseAlign
));
253 if (0 == (pOut
->dccRamSize
& (pOut
->dccRamBaseAlign
- 1)))
255 pOut
->subLvlCompressible
= TRUE
;
259 UINT_64 dccRamSizeAlign
= HwlGetPipes(&pIn
->tileInfo
) * m_pipeInterleaveBytes
;
261 if (pOut
->dccRamSize
== pOut
->dccFastClearSize
)
263 pOut
->dccFastClearSize
= PowTwoAlign(pOut
->dccRamSize
, dccRamSizeAlign
);
265 pOut
->dccRamSize
= PowTwoAlign(pOut
->dccRamSize
, dccRamSizeAlign
);
266 pOut
->subLvlCompressible
= FALSE
;
271 returnCode
= ADDR_NOTSUPPORTED
;
278 ***************************************************************************************************
279 * CIAddrLib::HwlComputeCmaskAddrFromCoord
282 * Compute tc compatible Cmask address from fmask ram address
286 ***************************************************************************************************
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
293 ADDR_E_RETURNCODE returnCode
= ADDR_NOTSUPPORTED
;
295 if ((m_settings
.isVolcanicIslands
== TRUE
) &&
296 (pIn
->flags
.tcCompatible
== TRUE
))
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
,
309 m_pipeInterleaveBytes
,
313 pOut
->addr
= (metaNibbleAddress
>> 1);
314 pOut
->bitPosition
= (metaNibbleAddress
% 2) ? 4 : 0;
315 returnCode
= ADDR_OK
;
321 ***************************************************************************************************
322 * CIAddrLib::HwlConvertChipFamily
325 * Convert familyID defined in atiid.h to AddrChipFamily and set m_chipFamily/m_chipRevision
328 ***************************************************************************************************
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
334 AddrChipFamily family
= ADDR_CHIP_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
);
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
);
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
);
358 m_settings
.isCarrizo
= 1;
359 m_settings
.isVolcanicIslands
= 1;
362 ADDR_ASSERT(!"This should be a unexpected Fusion");
370 ***************************************************************************************************
371 * CIAddrLib::HwlInitGlobalParams
374 * Initializes global parameters
377 * TRUE if all settings are valid
379 ***************************************************************************************************
381 BOOL_32
CIAddrLib::HwlInitGlobalParams(
382 const ADDR_CREATE_INPUT
* pCreateIn
) ///< [in] create input
384 BOOL_32 valid
= TRUE
;
386 const ADDR_REGISTER_VALUE
* pRegValue
= &pCreateIn
->regValue
;
388 valid
= DecodeGbRegs(pRegValue
);
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
)
394 // Hawaii has 16-pipe, see GFXIP_Config_Summary.xls
397 else if (m_settings
.isBonaire
|| m_settings
.isSpectre
)
401 else // Treat other KV asics to be 2-pipe
407 // Move this to VI code path once created
408 if (m_settings
.isTonga
|| m_settings
.isPolaris10
)
412 else if (m_settings
.isIceland
)
416 else if (m_settings
.isFiji
)
420 else if (m_settings
.isPolaris11
)
427 valid
= InitTileSettingTable(pRegValue
->pTileConfig
, pRegValue
->noOfEntries
);
431 valid
= InitMacroTileCfgTable(pRegValue
->pMacroTileConfig
, pRegValue
->noOfMacroEntries
);
438 ***************************************************************************************************
439 * CIAddrLib::HwlPostCheckTileIndex
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
446 ***************************************************************************************************
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
455 INT_32 index
= curIndex
;
457 if (mode
== ADDR_TM_LINEAR_GENERAL
)
459 index
= TileIndexLinearGeneral
;
463 BOOL_32 macroTiled
= IsMacroTiled(mode
);
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
))
473 for (index
= 0; index
< static_cast<INT_32
>(m_noOfEntries
); index
++)
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
))
482 // tileSplitBytes stored in m_tileTable is only valid for depth entries
483 if (type
== ADDR_DEPTH_SAMPLE_ORDER
)
485 if (pInfo
->tileSplitBytes
== m_tileTable
[index
].info
.tileSplitBytes
)
490 else // other entries are determined by other 3 fields
496 else if (mode
== ADDR_TM_LINEAR_ALIGNED
)
498 // linear mode only needs tile mode to match
499 if (mode
== m_tileTable
[index
].mode
)
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
)
517 ADDR_ASSERT(index
< static_cast<INT_32
>(m_noOfEntries
));
519 if (index
>= static_cast<INT_32
>(m_noOfEntries
))
521 index
= TileIndexInvalid
;
528 ***************************************************************************************************
529 * CIAddrLib::HwlSetupTileCfg
532 * Map tile index to tile setting.
535 ***************************************************************************************************
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
545 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
547 // Global flag to control usage of tileIndex
548 if (UseTileIndex(index
))
550 if (static_cast<UINT_32
>(index
) >= m_noOfEntries
)
552 returnCode
= ADDR_INVALIDPARAMS
;
556 const ADDR_TILECONFIG
* pCfgTable
= GetTileSetting(index
);
560 if (IsMacroTiled(pCfgTable
->mode
))
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
573 *pInfo
= m_macroTileTable
[macroModeIndex
];
575 if (pCfgTable
->type
== ADDR_DEPTH_SAMPLE_ORDER
)
577 pInfo
->tileSplitBytes
= pCfgTable
->info
.tileSplitBytes
;
579 pInfo
->pipeConfig
= pCfgTable
->info
.pipeConfig
;
581 else // 1D and linear modes, we return default value stored in table
583 *pInfo
= pCfgTable
->info
;
589 *pMode
= pCfgTable
->mode
;
594 *pType
= pCfgTable
->type
;
603 ***************************************************************************************************
604 * CIAddrLib::HwlComputeSurfaceInfo
607 * Entry of ci's ComputeSurfaceInfo
610 ***************************************************************************************************
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
617 // If tileIndex is invalid, force macroModeIndex to be invalid, too
618 if (pIn
->tileIndex
== TileIndexInvalid
)
620 pOut
->macroModeIndex
= TileIndexInvalid
;
623 ADDR_E_RETURNCODE retCode
= SIAddrLib::HwlComputeSurfaceInfo(pIn
,pOut
);
625 if (pOut
->macroModeIndex
== TileIndexNoMacroIndex
)
627 pOut
->macroModeIndex
= TileIndexInvalid
;
634 ***************************************************************************************************
635 * CIAddrLib::HwlFmaskSurfaceInfo
637 * Entry of r800's ComputeFmaskInfo
640 ***************************************************************************************************
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
647 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
649 ADDR_TILEINFO tileInfo
= {0};
650 ADDR_COMPUTE_FMASK_INFO_INPUT fmaskIn
;
653 AddrTileMode tileMode
= pIn
->tileMode
;
655 // Use internal tile info if pOut does not have a valid pTileInfo
656 if (pOut
->pTileInfo
== NULL
)
658 pOut
->pTileInfo
= &tileInfo
;
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
);
667 ADDR_ASSERT(m_tileTable
[14].mode
== ADDR_TM_2D_TILED_THIN1
);
668 ADDR_ASSERT(m_tileTable
[15].mode
== ADDR_TM_3D_TILED_THIN1
);
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}};
675 INT_32 macroModeIndex
= TileIndexInvalid
;
677 UINT_32 numSamples
= pIn
->numSamples
;
678 UINT_32 numFrags
= pIn
->numFrags
== 0 ? numSamples
: pIn
->numFrags
;
680 UINT_32 bpp
= QLog2(numFrags
);
682 // EQAA needs one more bit
683 if (numSamples
> numFrags
)
693 bpp
= Max(8u, bpp
* numSamples
);
695 macroModeIndex
= HwlComputeMacroModeIndex(tileIndex
, flags
, bpp
, numSamples
, pOut
->pTileInfo
);
697 fmaskIn
.tileIndex
= tileIndex
;
698 fmaskIn
.pTileInfo
= pOut
->pTileInfo
;
699 pOut
->macroModeIndex
= macroModeIndex
;
700 pOut
->tileIndex
= tileIndex
;
702 retCode
= DispatchComputeFmaskInfo(&fmaskIn
, pOut
);
704 if (retCode
== ADDR_OK
)
707 HwlPostCheckTileIndex(pOut
->pTileInfo
, pIn
->tileMode
, ADDR_NON_DISPLAYABLE
,
711 // Resets pTileInfo to NULL if the internal tile info is used
712 if (pOut
->pTileInfo
== &tileInfo
)
714 pOut
->pTileInfo
= NULL
;
721 ***************************************************************************************************
722 * CIAddrLib::HwlFmaskPreThunkSurfInfo
725 * Some preparation before thunking a ComputeSurfaceInfo call for Fmask
728 ***************************************************************************************************
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
737 pSurfIn
->tileIndex
= pFmaskIn
->tileIndex
;
738 pSurfOut
->macroModeIndex
= pFmaskOut
->macroModeIndex
;
742 ***************************************************************************************************
743 * CIAddrLib::HwlFmaskPostThunkSurfInfo
746 * Copy hwl extra field after calling thunked ComputeSurfaceInfo
749 ***************************************************************************************************
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
756 pFmaskOut
->tileIndex
= pSurfOut
->tileIndex
;
757 pFmaskOut
->macroModeIndex
= pSurfOut
->macroModeIndex
;
761 ***************************************************************************************************
762 * CIAddrLib::HwlDegradeThickTileMode
765 * Degrades valid tile mode for thick modes if needed
769 ***************************************************************************************************
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
781 ***************************************************************************************************
782 * CIAddrLib::HwlOverrideTileMode
785 * Override THICK to THIN, for specific formats on CI
790 ***************************************************************************************************
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
798 BOOL_32 bOverrided
= FALSE
;
799 AddrTileMode tileMode
= *pTileMode
;
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
806 case ADDR_TM_PRT_2D_TILED_THICK
:
807 case ADDR_TM_PRT_3D_TILED_THICK
:
808 tileMode
= ADDR_TM_PRT_TILED_THICK
;
810 case ADDR_TM_PRT_2D_TILED_THIN1
:
811 case ADDR_TM_PRT_3D_TILED_THIN1
:
812 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
818 // UBTS#404321, we do not need such overriding, as THICK+THICK entries removed from the tile-mode table
819 if (!m_settings
.isBonaire
)
821 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
823 // tile_thickness = (array_mode == XTHICK) ? 8 : ((array_mode == THICK) ? 4 : 1)
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
:
838 case ADDR_FMT_1_REVERSED
:
849 case ADDR_TM_1D_TILED_THICK
:
850 tileMode
= ADDR_TM_1D_TILED_THIN1
;
853 case ADDR_TM_2D_TILED_XTHICK
:
854 case ADDR_TM_2D_TILED_THICK
:
855 tileMode
= ADDR_TM_2D_TILED_THIN1
;
858 case ADDR_TM_3D_TILED_XTHICK
:
859 case ADDR_TM_3D_TILED_THICK
:
860 tileMode
= ADDR_TM_3D_TILED_THIN1
;
863 case ADDR_TM_PRT_TILED_THICK
:
864 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
867 case ADDR_TM_PRT_2D_TILED_THICK
:
868 tileMode
= ADDR_TM_PRT_2D_TILED_THIN1
;
871 case ADDR_TM_PRT_3D_TILED_THICK
:
872 tileMode
= ADDR_TM_PRT_3D_TILED_THIN1
;
880 // Switch tile type from thick to thin
881 if (tileMode
!= *pTileMode
)
883 // see tileIndex: 13-18
884 *pTileType
= ADDR_NON_DISPLAYABLE
;
894 if (tileMode
!= *pTileMode
)
896 *pTileMode
= tileMode
;
904 ***************************************************************************************************
905 * CiAddrLib::GetPrtSwitchP4Threshold
908 * Return the threshold of switching to P4_* instead of P16_* for PRT resources
909 ***************************************************************************************************
911 UINT_32
CIAddrLib::GetPrtSwitchP4Threshold() const
921 if (m_settings
.isFiji
)
925 else if (m_settings
.isHawaii
)
931 ///@todo add for possible new ASICs.
932 ADDR_ASSERT_ALWAYS();
937 ///@todo add for possible new ASICs.
938 ADDR_ASSERT_ALWAYS();
947 ***************************************************************************************************
948 * CIAddrLib::HwlSetupTileInfo
951 * Setup default value of tile info for SI
952 ***************************************************************************************************
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
967 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
968 ADDR_TILEINFO
* pTileInfo
= pTileInfoOut
;
969 INT index
= TileIndexInvalid
;
970 INT macroModeIndex
= TileIndexInvalid
;
973 if (!IsLinear(tileMode
))
975 // Thick tile modes must use thick micro tile mode but Bonaire does not support due to
976 // old derived netlists (UBTS 404321)
979 if (m_settings
.isBonaire
)
981 inTileType
= ADDR_NON_DISPLAYABLE
;
983 else if ((m_allowNonDispThickModes
== FALSE
) || (inTileType
!= ADDR_NON_DISPLAYABLE
))
985 inTileType
= ADDR_THICK
;
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
)
993 inTileType
= ADDR_NON_DISPLAYABLE
;
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
)
998 inTileType
= ADDR_NON_DISPLAYABLE
;
1001 if (flags
.depth
|| flags
.stencil
)
1003 inTileType
= ADDR_DEPTH_SAMPLE_ORDER
;
1007 if (IsTileInfoAllZero(pTileInfo
))
1009 // See table entries 0-4
1010 if (flags
.depth
|| flags
.stencil
)
1012 if (flags
.depth
&& flags
.tcCompatible
)
1014 // tileSize = bpp * numSamples * 8 * 8 / 8
1015 UINT_32 tileSize
= bpp
* numSamples
* 8;
1017 // Texure readable depth surface should not be split
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
1057 // See table entries 5-6
1058 if (inTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
1062 case ADDR_TM_1D_TILED_THIN1
:
1065 case ADDR_TM_PRT_TILED_THIN1
:
1073 // See table entries 8-12
1074 if (inTileType
== ADDR_DISPLAYABLE
)
1078 case ADDR_TM_1D_TILED_THIN1
:
1081 case ADDR_TM_2D_TILED_THIN1
:
1084 case ADDR_TM_PRT_TILED_THIN1
:
1092 // See table entries 13-18
1093 if (inTileType
== ADDR_NON_DISPLAYABLE
)
1097 case ADDR_TM_1D_TILED_THIN1
:
1100 case ADDR_TM_2D_TILED_THIN1
:
1103 case ADDR_TM_3D_TILED_THIN1
:
1106 case ADDR_TM_PRT_TILED_THIN1
:
1114 // See table entries 19-26
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;
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;
1127 case ADDR_TM_3D_TILED_THICK
:
1130 case ADDR_TM_PRT_TILED_THICK
:
1133 case ADDR_TM_2D_TILED_XTHICK
:
1136 case ADDR_TM_3D_TILED_XTHICK
:
1144 // See table entries 27-30
1145 if (inTileType
== ADDR_ROTATED
)
1149 case ADDR_TM_1D_TILED_THIN1
:
1152 case ADDR_TM_2D_TILED_THIN1
:
1155 case ADDR_TM_PRT_TILED_THIN1
:
1158 case ADDR_TM_PRT_2D_TILED_THIN1
:
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
))
1173 UINT_32 bytesXSamples
= bpp
* numSamples
/ 8;
1174 UINT_32 bytesXThickness
= bpp
* thickness
/ 8;
1175 UINT_32 switchP4Threshold
= GetPrtSwitchP4Threshold();
1177 if ((bytesXSamples
> switchP4Threshold
) || (bytesXThickness
> switchP4Threshold
))
1179 // Pick next 4 pipe entry
1187 // A pre-filled tile info is ready
1188 index
= pOut
->tileIndex
;
1189 macroModeIndex
= pOut
->macroModeIndex
;
1191 // pass tile type back for post tile index compute
1192 pOut
->tileType
= inTileType
;
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
)
1198 macroModeIndex
= HwlComputeMacroModeIndex(index
, flags
, bpp
, numSamples
, pTileInfo
);
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
;
1205 else if (tileMode
== ADDR_TM_LINEAR_GENERAL
)
1207 pOut
->tileIndex
= TileIndexLinearGeneral
;
1209 // Copy linear-aligned entry??
1210 *pTileInfo
= m_tileTable
[8].info
;
1212 else if (tileMode
== ADDR_TM_LINEAR_ALIGNED
)
1214 pOut
->tileIndex
= 8;
1215 *pTileInfo
= m_tileTable
[8].info
;
1220 ***************************************************************************************************
1221 * CIAddrLib::ReadGbTileMode
1224 * Convert GB_TILE_MODE HW value to ADDR_TILE_CONFIG.
1227 ***************************************************************************************************
1229 VOID
CIAddrLib::ReadGbTileMode(
1230 UINT_32 regValue
, ///< [in] GB_TILE_MODE register
1231 ADDR_TILECONFIG
* pCfg
///< [out] output structure
1234 GB_TILE_MODE gbTileMode
;
1235 gbTileMode
.val
= regValue
;
1237 pCfg
->type
= static_cast<AddrTileType
>(gbTileMode
.f
.micro_tile_mode_new
);
1238 pCfg
->info
.pipeConfig
= static_cast<AddrPipeCfg
>(gbTileMode
.f
.pipe_config
+ 1);
1240 if (pCfg
->type
== ADDR_DEPTH_SAMPLE_ORDER
)
1242 pCfg
->info
.tileSplitBytes
= 64 << gbTileMode
.f
.tile_split
;
1246 pCfg
->info
.tileSplitBytes
= 1 << gbTileMode
.f
.sample_split
;
1249 UINT_32 regArrayMode
= gbTileMode
.f
.array_mode
;
1251 pCfg
->mode
= static_cast<AddrTileMode
>(regArrayMode
);
1253 switch (regArrayMode
)
1256 pCfg
->mode
= ADDR_TM_PRT_TILED_THIN1
;
1259 pCfg
->mode
= ADDR_TM_PRT_2D_TILED_THIN1
;
1262 pCfg
->mode
= ADDR_TM_2D_TILED_XTHICK
;
1265 pCfg
->mode
= ADDR_TM_PRT_TILED_THICK
;
1268 pCfg
->mode
= ADDR_TM_PRT_2D_TILED_THICK
;
1271 pCfg
->mode
= ADDR_TM_PRT_3D_TILED_THIN1
;
1274 pCfg
->mode
= ADDR_TM_3D_TILED_XTHICK
;
1277 pCfg
->mode
= ADDR_TM_PRT_3D_TILED_THICK
;
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
))
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;
1296 ***************************************************************************************************
1297 * CIAddrLib::InitTileSettingTable
1300 * Initialize the ADDR_TILE_CONFIG table.
1302 * TRUE if tile table is correctly initialized
1303 ***************************************************************************************************
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
1310 BOOL_32 initOk
= TRUE
;
1312 ADDR_ASSERT(noOfEntries
<= TileTableSize
);
1314 memset(m_tileTable
, 0, sizeof(m_tileTable
));
1316 if (noOfEntries
!= 0)
1318 m_noOfEntries
= noOfEntries
;
1322 m_noOfEntries
= TileTableSize
;
1325 if (pCfg
) // From Client
1327 for (UINT_32 i
= 0; i
< m_noOfEntries
; i
++)
1329 ReadGbTileMode(*(pCfg
+ i
), &m_tileTable
[i
]);
1334 ADDR_ASSERT_ALWAYS();
1340 ADDR_ASSERT(m_tileTable
[TILEINDEX_LINEAR_ALIGNED
].mode
== ADDR_TM_LINEAR_ALIGNED
);
1342 if (m_settings
.isBonaire
== FALSE
)
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
))
1348 m_allowNonDispThickModes
= TRUE
;
1349 ADDR_ASSERT(m_tileTable
[24].mode
== ADDR_TM_2D_TILED_THICK
);
1354 m_allowNonDispThickModes
= TRUE
;
1357 // Assume the first entry is always programmed with full pipes
1358 m_pipes
= HwlGetPipes(&m_tileTable
[0].info
);
1365 ***************************************************************************************************
1366 * CIAddrLib::ReadGbMacroTileCfg
1369 * Convert GB_MACRO_TILE_CFG HW value to ADDR_TILE_CONFIG.
1372 ***************************************************************************************************
1374 VOID
CIAddrLib::ReadGbMacroTileCfg(
1375 UINT_32 regValue
, ///< [in] GB_MACRO_TILE_MODE register
1376 ADDR_TILEINFO
* pCfg
///< [out] output structure
1379 GB_MACROTILE_MODE gbTileMode
;
1380 gbTileMode
.val
= regValue
;
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
;
1389 ***************************************************************************************************
1390 * CIAddrLib::InitMacroTileCfgTable
1393 * Initialize the ADDR_MACRO_TILE_CONFIG table.
1395 * TRUE if macro tile table is correctly initialized
1396 ***************************************************************************************************
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
1403 BOOL_32 initOk
= TRUE
;
1405 ADDR_ASSERT(noOfMacroEntries
<= MacroTileTableSize
);
1407 memset(m_macroTileTable
, 0, sizeof(m_macroTileTable
));
1409 if (noOfMacroEntries
!= 0)
1411 m_noOfMacroEntries
= noOfMacroEntries
;
1415 m_noOfMacroEntries
= MacroTileTableSize
;
1418 if (pCfg
) // From Client
1420 for (UINT_32 i
= 0; i
< m_noOfMacroEntries
; i
++)
1422 ReadGbMacroTileCfg(*(pCfg
+ i
), &m_macroTileTable
[i
]);
1424 m_macroTileTable
[i
].tileSplitBytes
= 64 << (i
% 8);
1429 ADDR_ASSERT_ALWAYS();
1436 ***************************************************************************************************
1437 * CIAddrLib::HwlComputeMacroModeIndex
1440 * Computes macro tile mode index
1442 * TRUE if macro tile table is correctly initialized
1443 ***************************************************************************************************
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
1455 INT_32 macroModeIndex
= TileIndexInvalid
;
1457 if (flags
.tcCompatible
&& flags
.stencil
)
1459 // Don't compute macroModeIndex for tc compatible stencil surface
1460 macroModeIndex
= TileIndexNoMacroIndex
;
1464 AddrTileMode tileMode
= m_tileTable
[tileIndex
].mode
;
1465 AddrTileType tileType
= m_tileTable
[tileIndex
].type
;
1466 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
1468 if (!IsMacroTiled(tileMode
))
1470 *pTileInfo
= m_tileTable
[tileIndex
].info
;
1471 macroModeIndex
= TileIndexNoMacroIndex
;
1475 UINT_32 tileBytes1x
= BITS_TO_BYTES(bpp
* MicroTilePixels
* thickness
);
1478 if (m_tileTable
[tileIndex
].type
== ADDR_DEPTH_SAMPLE_ORDER
)
1480 // Depth entries store real tileSplitBytes
1481 tileSplit
= m_tileTable
[tileIndex
].info
.tileSplitBytes
;
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
);
1489 tileSplit
= colorTileSplit
;
1492 UINT_32 tileSplitC
= Min(m_rowSize
, tileSplit
);
1497 tileBytes
= Min(tileSplitC
, tileBytes1x
);
1501 tileBytes
= Min(tileSplitC
, numSamples
* tileBytes1x
);
1509 macroModeIndex
= Log2(tileBytes
/ 64);
1511 if (flags
.prt
|| IsPrtTileMode(tileMode
))
1513 // Unknown - assume it is 1/2 of table size
1514 const UINT_32 PrtMacroModeOffset
= MacroTileTableSize
/ 2;
1516 macroModeIndex
+= PrtMacroModeOffset
;
1517 *pTileInfo
= m_macroTileTable
[macroModeIndex
];
1521 *pTileInfo
= m_macroTileTable
[macroModeIndex
];
1524 pTileInfo
->pipeConfig
= m_tileTable
[tileIndex
].info
.pipeConfig
;
1526 if (m_tileTable
[tileIndex
].type
!= ADDR_DEPTH_SAMPLE_ORDER
)
1528 pTileInfo
->tileSplitBytes
= tileSplitC
;
1532 pTileInfo
->tileSplitBytes
= m_tileTable
[tileIndex
].info
.tileSplitBytes
;
1536 if (NULL
!= pTileMode
)
1538 *pTileMode
= tileMode
;
1541 if (NULL
!= pTileType
)
1543 *pTileType
= tileType
;
1547 return macroModeIndex
;
1551 ***************************************************************************************************
1552 * CIAddrLib::HwlComputeTileDataWidthAndHeightLinear
1555 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1561 * MacroWidth and macroHeight are measured in pixels
1562 ***************************************************************************************************
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
1571 ADDR_ASSERT(pTileInfo
!= NULL
);
1575 switch (pTileInfo
->pipeConfig
)
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
:
1591 *pMacroWidth
= numTiles
* MicroTileWidth
;
1592 *pMacroHeight
= numTiles
* MicroTileHeight
;
1596 ***************************************************************************************************
1597 * CIAddrLib::HwlStereoCheckRightOffsetPadding
1600 * check if the height needs extra padding for stereo right eye offset, to avoid swizzling
1603 * TRUE is the extra padding is needed
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 ***************************************************************************************************
1613 BOOL_32
CIAddrLib::HwlStereoCheckRightOffsetPadding() const
1615 BOOL_32 bNeedPadding
= FALSE
;
1617 if (m_settings
.isKaveri
)
1619 bNeedPadding
= TRUE
;
1622 return bNeedPadding
;
1626 ***************************************************************************************************
1627 * CIAddrLib::HwlComputeMetadataNibbleAddress
1630 * calculate meta data address based on input information
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
1644 * meta data nibble address (nibble address is used to support DCC compatible cmask)
1646 ***************************************************************************************************
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
,
1658 UINT_32 numOfSamplesPerSplit
) const
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
);
1667 ///--------------------------------------------------------------------------------------------
1668 /// Clear pipe and bank swizzles
1669 ///--------------------------------------------------------------------------------------------
1670 UINT_32 dataMacrotileBits
= pipeInterleaveBits
+ pipeBits
+ bankBits
;
1671 UINT_32 metadataMacrotileBits
= pipeInterleaveBits
+ pipeBits
+ bankBits
;
1673 UINT_64 dataMacrotileClearMask
= ~((1L << dataMacrotileBits
) - 1);
1674 UINT_64 metadataMacrotileClearMask
= ~((1L << metadataMacrotileBits
) - 1);
1676 UINT_64 dataBaseByteAddressNoSwizzle
= dataBaseByteAddress
& dataMacrotileClearMask
;
1677 UINT_64 metadataBaseByteAddressNoSwizzle
= metadataBaseByteAddress
& metadataMacrotileClearMask
;
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 /
1686 UINT_64 offset
= uncompressedDataByteAddress
-
1687 dataBaseByteAddressNoSwizzle
+
1688 metadataBaseShifted
;
1690 ///--------------------------------------------------------------------------------------------
1691 /// Save bank data bits
1692 ///--------------------------------------------------------------------------------------------
1693 UINT_32 lsb
= pipeBits
+ pipeInterleaveBits
;
1694 UINT_32 msb
= bankBits
- 1 + lsb
;
1696 UINT_64 bankDataBits
= AddrGetBits(offset
, msb
, lsb
);
1698 ///--------------------------------------------------------------------------------------------
1699 /// Save pipe data bits
1700 ///--------------------------------------------------------------------------------------------
1701 lsb
= pipeInterleaveBits
;
1702 msb
= pipeBits
- 1 + lsb
;
1704 UINT_64 pipeDataBits
= AddrGetBits(offset
, msb
, lsb
);
1706 ///--------------------------------------------------------------------------------------------
1707 /// Remove pipe and bank bits
1708 ///--------------------------------------------------------------------------------------------
1709 lsb
= pipeInterleaveBits
;
1710 msb
= dataMacrotileBits
- 1;
1712 UINT_64 offsetWithoutPipeBankBits
= AddrRemoveBits(offset
, msb
, lsb
);
1714 ADDR_ASSERT((0 != blockByteSize
));
1715 UINT_64 blockInBankpipe
= offsetWithoutPipeBankBits
/ blockByteSize
;
1717 UINT_32 tileSize
= 8 * 8 * elementBitSize
/8 * numOfSamplesPerSplit
;
1718 UINT_32 blocksInTile
= tileSize
/ blockByteSize
;
1720 if (0 == blocksInTile
)
1726 lsb
= Log2(blocksInTile
);
1728 msb
= bankBits
- 1 + lsb
;
1730 UINT_64 blockInBankpipeWithBankBits
= AddrInsertBits(blockInBankpipe
, bankDataBits
, msb
, lsb
);
1732 /// NOTE *2 because we are converting to Nibble address in this step
1733 UINT_64 metaAddressInPipe
= blockInBankpipeWithBankBits
* 2 * metadataBitSize
/ 8;
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
);
1743 return metadataAddress
;
1747 ***************************************************************************************************
1748 * CIAddrLib::HwlPadDimensions
1751 * Helper function to pad dimensions
1756 ***************************************************************************************************
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
1774 if (m_settings
.isVolcanicIslands
&&
1775 flags
.dccCompatible
&&
1778 IsMacroTiled(tileMode
))
1780 UINT_32 tileSizePerSample
= BITS_TO_BYTES(bpp
* MicroTileWidth
* MicroTileHeight
);
1781 UINT_32 samplesPerSplit
= pTileInfo
->tileSplitBytes
/ tileSizePerSample
;
1783 if (samplesPerSplit
< numSamples
)
1785 UINT_32 dccFastClearByteAlign
= HwlGetPipes(pTileInfo
) * m_pipeInterleaveBytes
* 256;
1786 UINT_32 bytesPerSplit
= BITS_TO_BYTES((*pPitch
) * (*pHeight
) * bpp
* samplesPerSplit
);
1788 ADDR_ASSERT(IsPow2(dccFastClearByteAlign
));
1790 if (0 != (bytesPerSplit
& (dccFastClearByteAlign
- 1)))
1792 UINT_32 dccFastClearPixelAlign
= dccFastClearByteAlign
/
1793 BITS_TO_BYTES(bpp
) /
1795 UINT_32 macroTilePixelAlign
= pitchAlign
* heightAlign
;
1797 if ((dccFastClearPixelAlign
>= macroTilePixelAlign
) &&
1798 ((dccFastClearPixelAlign
% macroTilePixelAlign
) == 0))
1800 UINT_32 dccFastClearPitchAlignInMacroTile
=
1801 dccFastClearPixelAlign
/ macroTilePixelAlign
;
1802 UINT_32 heightInMacroTile
= *pHeight
/ heightAlign
;
1803 UINT_32 dccFastClearPitchAlignInPixels
;
1805 while ((heightInMacroTile
> 1) &&
1806 ((heightInMacroTile
% 2) == 0) &&
1807 (dccFastClearPitchAlignInMacroTile
> 1) &&
1808 ((dccFastClearPitchAlignInMacroTile
% 2) == 0))
1810 heightInMacroTile
>>= 1;
1811 dccFastClearPitchAlignInMacroTile
>>= 1;
1814 dccFastClearPitchAlignInPixels
= pitchAlign
* dccFastClearPitchAlignInMacroTile
;
1816 if (IsPow2(dccFastClearPitchAlignInPixels
))
1818 *pPitch
= PowTwoAlign((*pPitch
), dccFastClearPitchAlignInPixels
);
1822 *pPitch
+= (dccFastClearPitchAlignInPixels
- 1);
1823 *pPitch
/= dccFastClearPitchAlignInPixels
;
1824 *pPitch
*= dccFastClearPitchAlignInPixels
;