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
);
356 m_settings
.isPolaris12
= ASICREV_IS_POLARIS12_V(uChipRevision
);
359 m_settings
.isCarrizo
= 1;
360 m_settings
.isVolcanicIslands
= 1;
363 ADDR_ASSERT(!"This should be a unexpected Fusion");
371 ***************************************************************************************************
372 * CiAddrLib::HwlInitGlobalParams
375 * Initializes global parameters
378 * TRUE if all settings are valid
380 ***************************************************************************************************
382 BOOL_32
CiAddrLib::HwlInitGlobalParams(
383 const ADDR_CREATE_INPUT
* pCreateIn
) ///< [in] create input
385 BOOL_32 valid
= TRUE
;
387 const ADDR_REGISTER_VALUE
* pRegValue
= &pCreateIn
->regValue
;
389 valid
= DecodeGbRegs(pRegValue
);
391 // The following assignments for m_pipes is only for fail-safe, InitTileSettingTable should
392 // read the correct pipes from tile mode table
393 if (m_settings
.isHawaii
)
395 // Hawaii has 16-pipe, see GFXIP_Config_Summary.xls
398 else if (m_settings
.isBonaire
|| m_settings
.isSpectre
)
402 else // Treat other KV asics to be 2-pipe
408 // Move this to VI code path once created
409 if (m_settings
.isTonga
|| m_settings
.isPolaris10
)
413 else if (m_settings
.isIceland
)
417 else if (m_settings
.isFiji
)
421 else if (m_settings
.isPolaris11
|| m_settings
.isPolaris12
)
428 valid
= InitTileSettingTable(pRegValue
->pTileConfig
, pRegValue
->noOfEntries
);
432 valid
= InitMacroTileCfgTable(pRegValue
->pMacroTileConfig
, pRegValue
->noOfMacroEntries
);
439 ***************************************************************************************************
440 * CiAddrLib::HwlPostCheckTileIndex
443 * Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches
444 * tile mode/type/info and change the index if needed
447 ***************************************************************************************************
449 INT_32
CiAddrLib::HwlPostCheckTileIndex(
450 const ADDR_TILEINFO
* pInfo
, ///< [in] Tile Info
451 AddrTileMode mode
, ///< [in] Tile mode
452 AddrTileType type
, ///< [in] Tile type
453 INT curIndex
///< [in] Current index assigned in HwlSetupTileInfo
456 INT_32 index
= curIndex
;
458 if (mode
== ADDR_TM_LINEAR_GENERAL
)
460 index
= TileIndexLinearGeneral
;
464 BOOL_32 macroTiled
= IsMacroTiled(mode
);
466 // We need to find a new index if either of them is true
467 // 1. curIndex is invalid
468 // 2. tile mode is changed
469 // 3. tile info does not match for macro tiled
470 if ((index
== TileIndexInvalid
) ||
471 (mode
!= m_tileTable
[index
].mode
) ||
472 (macroTiled
&& pInfo
->pipeConfig
!= m_tileTable
[index
].info
.pipeConfig
))
474 for (index
= 0; index
< static_cast<INT_32
>(m_noOfEntries
); index
++)
478 // macro tile modes need all to match
479 if ((pInfo
->pipeConfig
== m_tileTable
[index
].info
.pipeConfig
) &&
480 (mode
== m_tileTable
[index
].mode
) &&
481 (type
== m_tileTable
[index
].type
))
483 // tileSplitBytes stored in m_tileTable is only valid for depth entries
484 if (type
== ADDR_DEPTH_SAMPLE_ORDER
)
486 if (pInfo
->tileSplitBytes
== m_tileTable
[index
].info
.tileSplitBytes
)
491 else // other entries are determined by other 3 fields
497 else if (mode
== ADDR_TM_LINEAR_ALIGNED
)
499 // linear mode only needs tile mode to match
500 if (mode
== m_tileTable
[index
].mode
)
507 // micro tile modes only need tile mode and tile type to match
508 if (mode
== m_tileTable
[index
].mode
&&
509 type
== m_tileTable
[index
].type
)
518 ADDR_ASSERT(index
< static_cast<INT_32
>(m_noOfEntries
));
520 if (index
>= static_cast<INT_32
>(m_noOfEntries
))
522 index
= TileIndexInvalid
;
529 ***************************************************************************************************
530 * CiAddrLib::HwlSetupTileCfg
533 * Map tile index to tile setting.
536 ***************************************************************************************************
538 ADDR_E_RETURNCODE
CiAddrLib::HwlSetupTileCfg(
539 INT_32 index
, ///< [in] Tile index
540 INT_32 macroModeIndex
, ///< [in] Index in macro tile mode table(CI)
541 ADDR_TILEINFO
* pInfo
, ///< [out] Tile Info
542 AddrTileMode
* pMode
, ///< [out] Tile mode
543 AddrTileType
* pType
///< [out] Tile type
546 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
548 // Global flag to control usage of tileIndex
549 if (UseTileIndex(index
))
551 if (static_cast<UINT_32
>(index
) >= m_noOfEntries
)
553 returnCode
= ADDR_INVALIDPARAMS
;
557 const ADDR_TILECONFIG
* pCfgTable
= GetTileSetting(index
);
561 if (IsMacroTiled(pCfgTable
->mode
))
563 ADDR_ASSERT(((macroModeIndex
!= TileIndexInvalid
)
564 && (macroModeIndex
!= TileIndexNoMacroIndex
)));
565 // Here we used tile_bytes to replace of tile_split
566 // According info as below:
567 // "tile_split_c = MIN(ROW_SIZE, tile_split)
568 // "tile_bytes = MIN(tile_split_c, num_samples * tile_bytes_1x)
569 // when using tile_bytes replacing of tile_split, the result of
570 // alignment and others(such as slicesPerTile) are unaffected -
571 // since if tile_split_c is larger, split won't happen, otherwise
572 // (num_samples * tile_bytes_1x is larger), a correct tile_split is
574 *pInfo
= m_macroTileTable
[macroModeIndex
];
576 if (pCfgTable
->type
== ADDR_DEPTH_SAMPLE_ORDER
)
578 pInfo
->tileSplitBytes
= pCfgTable
->info
.tileSplitBytes
;
580 pInfo
->pipeConfig
= pCfgTable
->info
.pipeConfig
;
582 else // 1D and linear modes, we return default value stored in table
584 *pInfo
= pCfgTable
->info
;
590 *pMode
= pCfgTable
->mode
;
595 *pType
= pCfgTable
->type
;
604 ***************************************************************************************************
605 * CiAddrLib::HwlComputeSurfaceInfo
608 * Entry of ci's ComputeSurfaceInfo
611 ***************************************************************************************************
613 ADDR_E_RETURNCODE
CiAddrLib::HwlComputeSurfaceInfo(
614 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
615 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
618 // If tileIndex is invalid, force macroModeIndex to be invalid, too
619 if (pIn
->tileIndex
== TileIndexInvalid
)
621 pOut
->macroModeIndex
= TileIndexInvalid
;
624 ADDR_E_RETURNCODE retCode
= SiAddrLib::HwlComputeSurfaceInfo(pIn
,pOut
);
626 if (pOut
->macroModeIndex
== TileIndexNoMacroIndex
)
628 pOut
->macroModeIndex
= TileIndexInvalid
;
635 ***************************************************************************************************
636 * CiAddrLib::HwlFmaskSurfaceInfo
638 * Entry of r800's ComputeFmaskInfo
641 ***************************************************************************************************
643 ADDR_E_RETURNCODE
CiAddrLib::HwlComputeFmaskInfo(
644 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
645 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
648 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
650 ADDR_TILEINFO tileInfo
= {0};
651 ADDR_COMPUTE_FMASK_INFO_INPUT fmaskIn
;
654 AddrTileMode tileMode
= pIn
->tileMode
;
656 // Use internal tile info if pOut does not have a valid pTileInfo
657 if (pOut
->pTileInfo
== NULL
)
659 pOut
->pTileInfo
= &tileInfo
;
662 ADDR_ASSERT(tileMode
== ADDR_TM_2D_TILED_THIN1
||
663 tileMode
== ADDR_TM_3D_TILED_THIN1
||
664 tileMode
== ADDR_TM_PRT_TILED_THIN1
||
665 tileMode
== ADDR_TM_PRT_2D_TILED_THIN1
||
666 tileMode
== ADDR_TM_PRT_3D_TILED_THIN1
);
668 ADDR_ASSERT(m_tileTable
[14].mode
== ADDR_TM_2D_TILED_THIN1
);
669 ADDR_ASSERT(m_tileTable
[15].mode
== ADDR_TM_3D_TILED_THIN1
);
671 // The only valid tile modes for fmask are 2D_THIN1 and 3D_THIN1 plus non-displayable
672 INT_32 tileIndex
= tileMode
== ADDR_TM_2D_TILED_THIN1
? 14 : 15;
673 ADDR_SURFACE_FLAGS flags
= {{0}};
676 INT_32 macroModeIndex
= TileIndexInvalid
;
678 UINT_32 numSamples
= pIn
->numSamples
;
679 UINT_32 numFrags
= pIn
->numFrags
== 0 ? numSamples
: pIn
->numFrags
;
681 UINT_32 bpp
= QLog2(numFrags
);
683 // EQAA needs one more bit
684 if (numSamples
> numFrags
)
694 bpp
= Max(8u, bpp
* numSamples
);
696 macroModeIndex
= HwlComputeMacroModeIndex(tileIndex
, flags
, bpp
, numSamples
, pOut
->pTileInfo
);
698 fmaskIn
.tileIndex
= tileIndex
;
699 fmaskIn
.pTileInfo
= pOut
->pTileInfo
;
700 pOut
->macroModeIndex
= macroModeIndex
;
701 pOut
->tileIndex
= tileIndex
;
703 retCode
= DispatchComputeFmaskInfo(&fmaskIn
, pOut
);
705 if (retCode
== ADDR_OK
)
708 HwlPostCheckTileIndex(pOut
->pTileInfo
, pIn
->tileMode
, ADDR_NON_DISPLAYABLE
,
712 // Resets pTileInfo to NULL if the internal tile info is used
713 if (pOut
->pTileInfo
== &tileInfo
)
715 pOut
->pTileInfo
= NULL
;
722 ***************************************************************************************************
723 * CiAddrLib::HwlFmaskPreThunkSurfInfo
726 * Some preparation before thunking a ComputeSurfaceInfo call for Fmask
729 ***************************************************************************************************
731 VOID
CiAddrLib::HwlFmaskPreThunkSurfInfo(
732 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pFmaskIn
, ///< [in] Input of fmask info
733 const ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pFmaskOut
, ///< [in] Output of fmask info
734 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pSurfIn
, ///< [out] Input of thunked surface info
735 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pSurfOut
///< [out] Output of thunked surface info
738 pSurfIn
->tileIndex
= pFmaskIn
->tileIndex
;
739 pSurfOut
->macroModeIndex
= pFmaskOut
->macroModeIndex
;
743 ***************************************************************************************************
744 * CiAddrLib::HwlFmaskPostThunkSurfInfo
747 * Copy hwl extra field after calling thunked ComputeSurfaceInfo
750 ***************************************************************************************************
752 VOID
CiAddrLib::HwlFmaskPostThunkSurfInfo(
753 const ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pSurfOut
, ///< [in] Output of surface info
754 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pFmaskOut
///< [out] Output of fmask info
757 pFmaskOut
->tileIndex
= pSurfOut
->tileIndex
;
758 pFmaskOut
->macroModeIndex
= pSurfOut
->macroModeIndex
;
762 ***************************************************************************************************
763 * CiAddrLib::HwlDegradeThickTileMode
766 * Degrades valid tile mode for thick modes if needed
770 ***************************************************************************************************
772 AddrTileMode
CiAddrLib::HwlDegradeThickTileMode(
773 AddrTileMode baseTileMode
, ///< [in] base tile mode
774 UINT_32 numSlices
, ///< [in] current number of slices
775 UINT_32
* pBytesPerTile
///< [in/out] pointer to bytes per slice
782 ***************************************************************************************************
783 * CiAddrLib::HwlOverrideTileMode
786 * Override THICK to THIN, for specific formats on CI
791 ***************************************************************************************************
793 BOOL_32
CiAddrLib::HwlOverrideTileMode(
794 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
795 AddrTileMode
* pTileMode
, ///< [in/out] pointer to the tile mode
796 AddrTileType
* pTileType
///< [in/out] pointer to the tile type
799 BOOL_32 bOverrided
= FALSE
;
800 AddrTileMode tileMode
= *pTileMode
;
802 // currently, all CI/VI family do not
803 // support ADDR_TM_PRT_2D_TILED_THICK,ADDR_TM_PRT_3D_TILED_THICK and
804 // ADDR_TM_PRT_2D_TILED_THIN1, ADDR_TM_PRT_3D_TILED_THIN1
807 case ADDR_TM_PRT_2D_TILED_THICK
:
808 case ADDR_TM_PRT_3D_TILED_THICK
:
809 tileMode
= ADDR_TM_PRT_TILED_THICK
;
811 case ADDR_TM_PRT_2D_TILED_THIN1
:
812 case ADDR_TM_PRT_3D_TILED_THIN1
:
813 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
819 // UBTS#404321, we do not need such overriding, as THICK+THICK entries removed from the tile-mode table
820 if (!m_settings
.isBonaire
)
822 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
824 // tile_thickness = (array_mode == XTHICK) ? 8 : ((array_mode == THICK) ? 4 : 1)
829 // see //gfxip/gcB/devel/cds/src/verif/tc/models/csim/tcp.cpp
830 // tcpError("Thick micro tiling is not supported for format...
831 case ADDR_FMT_X24_8_32_FLOAT
:
832 case ADDR_FMT_32_AS_8
:
833 case ADDR_FMT_32_AS_8_8
:
834 case ADDR_FMT_32_AS_32_32_32_32
:
839 case ADDR_FMT_1_REVERSED
:
850 case ADDR_TM_1D_TILED_THICK
:
851 tileMode
= ADDR_TM_1D_TILED_THIN1
;
854 case ADDR_TM_2D_TILED_XTHICK
:
855 case ADDR_TM_2D_TILED_THICK
:
856 tileMode
= ADDR_TM_2D_TILED_THIN1
;
859 case ADDR_TM_3D_TILED_XTHICK
:
860 case ADDR_TM_3D_TILED_THICK
:
861 tileMode
= ADDR_TM_3D_TILED_THIN1
;
864 case ADDR_TM_PRT_TILED_THICK
:
865 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
868 case ADDR_TM_PRT_2D_TILED_THICK
:
869 tileMode
= ADDR_TM_PRT_2D_TILED_THIN1
;
872 case ADDR_TM_PRT_3D_TILED_THICK
:
873 tileMode
= ADDR_TM_PRT_3D_TILED_THIN1
;
881 // Switch tile type from thick to thin
882 if (tileMode
!= *pTileMode
)
884 // see tileIndex: 13-18
885 *pTileType
= ADDR_NON_DISPLAYABLE
;
895 if (tileMode
!= *pTileMode
)
897 *pTileMode
= tileMode
;
905 ***************************************************************************************************
906 * CiAddrLib::GetPrtSwitchP4Threshold
909 * Return the threshold of switching to P4_* instead of P16_* for PRT resources
910 ***************************************************************************************************
912 UINT_32
CiAddrLib::GetPrtSwitchP4Threshold() const
922 if (m_settings
.isFiji
)
926 else if (m_settings
.isHawaii
)
932 ///@todo add for possible new ASICs.
933 ADDR_ASSERT_ALWAYS();
938 ///@todo add for possible new ASICs.
939 ADDR_ASSERT_ALWAYS();
948 ***************************************************************************************************
949 * CiAddrLib::HwlSetupTileInfo
952 * Setup default value of tile info for SI
953 ***************************************************************************************************
955 VOID
CiAddrLib::HwlSetupTileInfo(
956 AddrTileMode tileMode
, ///< [in] Tile mode
957 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface type flags
958 UINT_32 bpp
, ///< [in] Bits per pixel
959 UINT_32 pitch
, ///< [in] Pitch in pixels
960 UINT_32 height
, ///< [in] Height in pixels
961 UINT_32 numSamples
, ///< [in] Number of samples
962 ADDR_TILEINFO
* pTileInfoIn
, ///< [in] Tile info input: NULL for default
963 ADDR_TILEINFO
* pTileInfoOut
, ///< [out] Tile info output
964 AddrTileType inTileType
, ///< [in] Tile type
965 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] Output
968 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
969 ADDR_TILEINFO
* pTileInfo
= pTileInfoOut
;
970 INT index
= TileIndexInvalid
;
971 INT macroModeIndex
= TileIndexInvalid
;
974 if (!IsLinear(tileMode
))
976 // Thick tile modes must use thick micro tile mode but Bonaire does not support due to
977 // old derived netlists (UBTS 404321)
980 if (m_settings
.isBonaire
)
982 inTileType
= ADDR_NON_DISPLAYABLE
;
984 else if ((m_allowNonDispThickModes
== FALSE
) || (inTileType
!= ADDR_NON_DISPLAYABLE
))
986 inTileType
= ADDR_THICK
;
989 // 128 bpp tiling must be non-displayable.
990 // Fmask reuse color buffer's entry but bank-height field can be from another entry
991 // To simplify the logic, fmask entry should be picked from non-displayable ones
992 else if (bpp
== 128 || flags
.fmask
)
994 inTileType
= ADDR_NON_DISPLAYABLE
;
996 // These two modes only have non-disp entries though they can be other micro tile modes
997 else if (tileMode
== ADDR_TM_3D_TILED_THIN1
|| tileMode
== ADDR_TM_PRT_3D_TILED_THIN1
)
999 inTileType
= ADDR_NON_DISPLAYABLE
;
1002 if (flags
.depth
|| flags
.stencil
)
1004 inTileType
= ADDR_DEPTH_SAMPLE_ORDER
;
1008 if (IsTileInfoAllZero(pTileInfo
))
1010 // See table entries 0-4
1011 if (flags
.depth
|| flags
.stencil
)
1013 if (flags
.depth
&& flags
.tcCompatible
)
1015 // tileSize = bpp * numSamples * 8 * 8 / 8
1016 UINT_32 tileSize
= bpp
* numSamples
* 8;
1018 // Texure readable depth surface should not be split
1037 // Depth and stencil need to use the same index, thus the pre-defined tile_split
1038 // can meet the requirement to choose the same macro mode index
1039 // uncompressed depth/stencil are not supported for now
1058 // See table entries 5-6
1059 if (inTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
1063 case ADDR_TM_1D_TILED_THIN1
:
1066 case ADDR_TM_PRT_TILED_THIN1
:
1074 // See table entries 8-12
1075 if (inTileType
== ADDR_DISPLAYABLE
)
1079 case ADDR_TM_1D_TILED_THIN1
:
1082 case ADDR_TM_2D_TILED_THIN1
:
1085 case ADDR_TM_PRT_TILED_THIN1
:
1093 // See table entries 13-18
1094 if (inTileType
== ADDR_NON_DISPLAYABLE
)
1098 case ADDR_TM_1D_TILED_THIN1
:
1101 case ADDR_TM_2D_TILED_THIN1
:
1104 case ADDR_TM_3D_TILED_THIN1
:
1107 case ADDR_TM_PRT_TILED_THIN1
:
1115 // See table entries 19-26
1120 case ADDR_TM_1D_TILED_THICK
:
1121 //special check for bonaire, for the compatablity between old KMD and new UMD for bonaire
1122 index
= ((inTileType
== ADDR_THICK
) || m_settings
.isBonaire
) ? 19 : 18;
1124 case ADDR_TM_2D_TILED_THICK
:
1125 // special check for bonaire, for the compatablity between old KMD and new UMD for bonaire
1126 index
= ((inTileType
== ADDR_THICK
) || m_settings
.isBonaire
) ? 20 : 24;
1128 case ADDR_TM_3D_TILED_THICK
:
1131 case ADDR_TM_PRT_TILED_THICK
:
1134 case ADDR_TM_2D_TILED_XTHICK
:
1137 case ADDR_TM_3D_TILED_XTHICK
:
1145 // See table entries 27-30
1146 if (inTileType
== ADDR_ROTATED
)
1150 case ADDR_TM_1D_TILED_THIN1
:
1153 case ADDR_TM_2D_TILED_THIN1
:
1156 case ADDR_TM_PRT_TILED_THIN1
:
1159 case ADDR_TM_PRT_2D_TILED_THIN1
:
1169 ADDR_ASSERT((index
+ 1) < static_cast<INT_32
>(m_noOfEntries
));
1170 // Only do this when tile mode table is updated.
1171 if (((tileMode
== ADDR_TM_PRT_TILED_THIN1
) || (tileMode
== ADDR_TM_PRT_TILED_THICK
)) &&
1172 (m_tileTable
[index
+1].mode
== tileMode
))
1174 UINT_32 bytesXSamples
= bpp
* numSamples
/ 8;
1175 UINT_32 bytesXThickness
= bpp
* thickness
/ 8;
1176 UINT_32 switchP4Threshold
= GetPrtSwitchP4Threshold();
1178 if ((bytesXSamples
> switchP4Threshold
) || (bytesXThickness
> switchP4Threshold
))
1180 // Pick next 4 pipe entry
1188 // A pre-filled tile info is ready
1189 index
= pOut
->tileIndex
;
1190 macroModeIndex
= pOut
->macroModeIndex
;
1192 // pass tile type back for post tile index compute
1193 pOut
->tileType
= inTileType
;
1196 // We only need to set up tile info if there is a valid index but macroModeIndex is invalid
1197 if (index
!= TileIndexInvalid
&& macroModeIndex
== TileIndexInvalid
)
1199 macroModeIndex
= HwlComputeMacroModeIndex(index
, flags
, bpp
, numSamples
, pTileInfo
);
1201 /// Copy to pOut->tileType/tileIndex/macroModeIndex
1202 pOut
->tileIndex
= index
;
1203 pOut
->tileType
= m_tileTable
[index
].type
; // Or inTileType, the samea
1204 pOut
->macroModeIndex
= macroModeIndex
;
1206 else if (tileMode
== ADDR_TM_LINEAR_GENERAL
)
1208 pOut
->tileIndex
= TileIndexLinearGeneral
;
1210 // Copy linear-aligned entry??
1211 *pTileInfo
= m_tileTable
[8].info
;
1213 else if (tileMode
== ADDR_TM_LINEAR_ALIGNED
)
1215 pOut
->tileIndex
= 8;
1216 *pTileInfo
= m_tileTable
[8].info
;
1221 ***************************************************************************************************
1222 * CiAddrLib::ReadGbTileMode
1225 * Convert GB_TILE_MODE HW value to ADDR_TILE_CONFIG.
1228 ***************************************************************************************************
1230 VOID
CiAddrLib::ReadGbTileMode(
1231 UINT_32 regValue
, ///< [in] GB_TILE_MODE register
1232 ADDR_TILECONFIG
* pCfg
///< [out] output structure
1235 GB_TILE_MODE gbTileMode
;
1236 gbTileMode
.val
= regValue
;
1238 pCfg
->type
= static_cast<AddrTileType
>(gbTileMode
.f
.micro_tile_mode_new
);
1239 pCfg
->info
.pipeConfig
= static_cast<AddrPipeCfg
>(gbTileMode
.f
.pipe_config
+ 1);
1241 if (pCfg
->type
== ADDR_DEPTH_SAMPLE_ORDER
)
1243 pCfg
->info
.tileSplitBytes
= 64 << gbTileMode
.f
.tile_split
;
1247 pCfg
->info
.tileSplitBytes
= 1 << gbTileMode
.f
.sample_split
;
1250 UINT_32 regArrayMode
= gbTileMode
.f
.array_mode
;
1252 pCfg
->mode
= static_cast<AddrTileMode
>(regArrayMode
);
1254 switch (regArrayMode
)
1257 pCfg
->mode
= ADDR_TM_PRT_TILED_THIN1
;
1260 pCfg
->mode
= ADDR_TM_PRT_2D_TILED_THIN1
;
1263 pCfg
->mode
= ADDR_TM_2D_TILED_XTHICK
;
1266 pCfg
->mode
= ADDR_TM_PRT_TILED_THICK
;
1269 pCfg
->mode
= ADDR_TM_PRT_2D_TILED_THICK
;
1272 pCfg
->mode
= ADDR_TM_PRT_3D_TILED_THIN1
;
1275 pCfg
->mode
= ADDR_TM_3D_TILED_XTHICK
;
1278 pCfg
->mode
= ADDR_TM_PRT_3D_TILED_THICK
;
1284 // Fail-safe code for these always convert tile info, as the non-macro modes
1285 // return the entry of tile mode table directly without looking up macro mode table
1286 if (!IsMacroTiled(pCfg
->mode
))
1288 pCfg
->info
.banks
= 2;
1289 pCfg
->info
.bankWidth
= 1;
1290 pCfg
->info
.bankHeight
= 1;
1291 pCfg
->info
.macroAspectRatio
= 1;
1292 pCfg
->info
.tileSplitBytes
= 64;
1297 ***************************************************************************************************
1298 * CiAddrLib::InitTileSettingTable
1301 * Initialize the ADDR_TILE_CONFIG table.
1303 * TRUE if tile table is correctly initialized
1304 ***************************************************************************************************
1306 BOOL_32
CiAddrLib::InitTileSettingTable(
1307 const UINT_32
* pCfg
, ///< [in] Pointer to table of tile configs
1308 UINT_32 noOfEntries
///< [in] Numbe of entries in the table above
1311 BOOL_32 initOk
= TRUE
;
1313 ADDR_ASSERT(noOfEntries
<= TileTableSize
);
1315 memset(m_tileTable
, 0, sizeof(m_tileTable
));
1317 if (noOfEntries
!= 0)
1319 m_noOfEntries
= noOfEntries
;
1323 m_noOfEntries
= TileTableSize
;
1326 if (pCfg
) // From Client
1328 for (UINT_32 i
= 0; i
< m_noOfEntries
; i
++)
1330 ReadGbTileMode(*(pCfg
+ i
), &m_tileTable
[i
]);
1335 ADDR_ASSERT_ALWAYS();
1341 ADDR_ASSERT(m_tileTable
[TILEINDEX_LINEAR_ALIGNED
].mode
== ADDR_TM_LINEAR_ALIGNED
);
1343 if (m_settings
.isBonaire
== FALSE
)
1345 // Check if entry 18 is "thick+thin" combination
1346 if ((m_tileTable
[18].mode
== ADDR_TM_1D_TILED_THICK
) &&
1347 (m_tileTable
[18].type
== ADDR_NON_DISPLAYABLE
))
1349 m_allowNonDispThickModes
= TRUE
;
1350 ADDR_ASSERT(m_tileTable
[24].mode
== ADDR_TM_2D_TILED_THICK
);
1355 m_allowNonDispThickModes
= TRUE
;
1358 // Assume the first entry is always programmed with full pipes
1359 m_pipes
= HwlGetPipes(&m_tileTable
[0].info
);
1366 ***************************************************************************************************
1367 * CiAddrLib::ReadGbMacroTileCfg
1370 * Convert GB_MACRO_TILE_CFG HW value to ADDR_TILE_CONFIG.
1373 ***************************************************************************************************
1375 VOID
CiAddrLib::ReadGbMacroTileCfg(
1376 UINT_32 regValue
, ///< [in] GB_MACRO_TILE_MODE register
1377 ADDR_TILEINFO
* pCfg
///< [out] output structure
1380 GB_MACROTILE_MODE gbTileMode
;
1381 gbTileMode
.val
= regValue
;
1383 pCfg
->bankHeight
= 1 << gbTileMode
.f
.bank_height
;
1384 pCfg
->bankWidth
= 1 << gbTileMode
.f
.bank_width
;
1385 pCfg
->banks
= 1 << (gbTileMode
.f
.num_banks
+ 1);
1386 pCfg
->macroAspectRatio
= 1 << gbTileMode
.f
.macro_tile_aspect
;
1390 ***************************************************************************************************
1391 * CiAddrLib::InitMacroTileCfgTable
1394 * Initialize the ADDR_MACRO_TILE_CONFIG table.
1396 * TRUE if macro tile table is correctly initialized
1397 ***************************************************************************************************
1399 BOOL_32
CiAddrLib::InitMacroTileCfgTable(
1400 const UINT_32
* pCfg
, ///< [in] Pointer to table of tile configs
1401 UINT_32 noOfMacroEntries
///< [in] Numbe of entries in the table above
1404 BOOL_32 initOk
= TRUE
;
1406 ADDR_ASSERT(noOfMacroEntries
<= MacroTileTableSize
);
1408 memset(m_macroTileTable
, 0, sizeof(m_macroTileTable
));
1410 if (noOfMacroEntries
!= 0)
1412 m_noOfMacroEntries
= noOfMacroEntries
;
1416 m_noOfMacroEntries
= MacroTileTableSize
;
1419 if (pCfg
) // From Client
1421 for (UINT_32 i
= 0; i
< m_noOfMacroEntries
; i
++)
1423 ReadGbMacroTileCfg(*(pCfg
+ i
), &m_macroTileTable
[i
]);
1425 m_macroTileTable
[i
].tileSplitBytes
= 64 << (i
% 8);
1430 ADDR_ASSERT_ALWAYS();
1437 ***************************************************************************************************
1438 * CiAddrLib::HwlComputeMacroModeIndex
1441 * Computes macro tile mode index
1443 * TRUE if macro tile table is correctly initialized
1444 ***************************************************************************************************
1446 INT_32
CiAddrLib::HwlComputeMacroModeIndex(
1447 INT_32 tileIndex
, ///< [in] Tile mode index
1448 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface flags
1449 UINT_32 bpp
, ///< [in] Bit per pixel
1450 UINT_32 numSamples
, ///< [in] Number of samples
1451 ADDR_TILEINFO
* pTileInfo
, ///< [out] Pointer to ADDR_TILEINFO
1452 AddrTileMode
* pTileMode
, ///< [out] Pointer to AddrTileMode
1453 AddrTileType
* pTileType
///< [out] Pointer to AddrTileType
1456 INT_32 macroModeIndex
= TileIndexInvalid
;
1458 if (flags
.tcCompatible
&& flags
.stencil
)
1460 // Don't compute macroModeIndex for tc compatible stencil surface
1461 macroModeIndex
= TileIndexNoMacroIndex
;
1465 AddrTileMode tileMode
= m_tileTable
[tileIndex
].mode
;
1466 AddrTileType tileType
= m_tileTable
[tileIndex
].type
;
1467 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
1469 if (!IsMacroTiled(tileMode
))
1471 *pTileInfo
= m_tileTable
[tileIndex
].info
;
1472 macroModeIndex
= TileIndexNoMacroIndex
;
1476 UINT_32 tileBytes1x
= BITS_TO_BYTES(bpp
* MicroTilePixels
* thickness
);
1479 if (m_tileTable
[tileIndex
].type
== ADDR_DEPTH_SAMPLE_ORDER
)
1481 // Depth entries store real tileSplitBytes
1482 tileSplit
= m_tileTable
[tileIndex
].info
.tileSplitBytes
;
1486 // Non-depth entries store a split factor
1487 UINT_32 sampleSplit
= m_tileTable
[tileIndex
].info
.tileSplitBytes
;
1488 UINT_32 colorTileSplit
= Max(256u, sampleSplit
* tileBytes1x
);
1490 tileSplit
= colorTileSplit
;
1493 UINT_32 tileSplitC
= Min(m_rowSize
, tileSplit
);
1498 tileBytes
= Min(tileSplitC
, tileBytes1x
);
1502 tileBytes
= Min(tileSplitC
, numSamples
* tileBytes1x
);
1510 macroModeIndex
= Log2(tileBytes
/ 64);
1512 if (flags
.prt
|| IsPrtTileMode(tileMode
))
1514 // Unknown - assume it is 1/2 of table size
1515 const UINT_32 PrtMacroModeOffset
= MacroTileTableSize
/ 2;
1517 macroModeIndex
+= PrtMacroModeOffset
;
1518 *pTileInfo
= m_macroTileTable
[macroModeIndex
];
1522 *pTileInfo
= m_macroTileTable
[macroModeIndex
];
1525 pTileInfo
->pipeConfig
= m_tileTable
[tileIndex
].info
.pipeConfig
;
1527 if (m_tileTable
[tileIndex
].type
!= ADDR_DEPTH_SAMPLE_ORDER
)
1529 pTileInfo
->tileSplitBytes
= tileSplitC
;
1533 pTileInfo
->tileSplitBytes
= m_tileTable
[tileIndex
].info
.tileSplitBytes
;
1537 if (NULL
!= pTileMode
)
1539 *pTileMode
= tileMode
;
1542 if (NULL
!= pTileType
)
1544 *pTileType
= tileType
;
1548 return macroModeIndex
;
1552 ***************************************************************************************************
1553 * CiAddrLib::HwlComputeTileDataWidthAndHeightLinear
1556 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1562 * MacroWidth and macroHeight are measured in pixels
1563 ***************************************************************************************************
1565 VOID
CiAddrLib::HwlComputeTileDataWidthAndHeightLinear(
1566 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1567 UINT_32
* pMacroHeight
, ///< [out] macro tile height
1568 UINT_32 bpp
, ///< [in] bits per pixel
1569 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
1572 ADDR_ASSERT(pTileInfo
!= NULL
);
1576 switch (pTileInfo
->pipeConfig
)
1578 case ADDR_PIPECFG_P16_32x32_8x16
:
1579 case ADDR_PIPECFG_P16_32x32_16x16
:
1580 case ADDR_PIPECFG_P8_32x64_32x32
:
1581 case ADDR_PIPECFG_P8_32x32_16x32
:
1582 case ADDR_PIPECFG_P8_32x32_16x16
:
1583 case ADDR_PIPECFG_P8_32x32_8x16
:
1584 case ADDR_PIPECFG_P4_32x32
:
1592 *pMacroWidth
= numTiles
* MicroTileWidth
;
1593 *pMacroHeight
= numTiles
* MicroTileHeight
;
1597 ***************************************************************************************************
1598 * CiAddrLib::HwlStereoCheckRightOffsetPadding
1601 * check if the height needs extra padding for stereo right eye offset, to avoid swizzling
1604 * TRUE is the extra padding is needed
1607 * Kalindi (Kabini) is the only one that needs this padding as there is a uncertain
1608 * possible HW issue where the right eye displays incorrectly with some type of swizzles, if
1609 * the right eye offset is not 64KB aligned - EPR#366461
1610 * Other Kaveri APUs also need the padding according to DXX team's report otherwise
1611 * corruption observed. - EPR#374788
1612 ***************************************************************************************************
1614 BOOL_32
CiAddrLib::HwlStereoCheckRightOffsetPadding() const
1616 BOOL_32 bNeedPadding
= FALSE
;
1618 if (m_settings
.isKaveri
)
1620 bNeedPadding
= TRUE
;
1623 return bNeedPadding
;
1627 ***************************************************************************************************
1628 * CiAddrLib::HwlComputeMetadataNibbleAddress
1631 * calculate meta data address based on input information
1634 * uncompressedDataByteAddress - address of a pixel in color surface
1635 * dataBaseByteAddress - base address of color surface
1636 * metadataBaseByteAddress - base address of meta ram
1637 * metadataBitSize - meta key size, 8 for DCC, 4 for cmask
1638 * elementBitSize - element size of color surface
1639 * blockByteSize - compression block size, 256 for DCC
1640 * pipeInterleaveBytes - pipe interleave size
1641 * numOfPipes - number of pipes
1642 * numOfBanks - number of banks
1643 * numOfSamplesPerSplit - number of samples per tile split
1645 * meta data nibble address (nibble address is used to support DCC compatible cmask)
1647 ***************************************************************************************************
1649 UINT_64
CiAddrLib::HwlComputeMetadataNibbleAddress(
1650 UINT_64 uncompressedDataByteAddress
,
1651 UINT_64 dataBaseByteAddress
,
1652 UINT_64 metadataBaseByteAddress
,
1653 UINT_32 metadataBitSize
,
1654 UINT_32 elementBitSize
,
1655 UINT_32 blockByteSize
,
1656 UINT_32 pipeInterleaveBytes
,
1659 UINT_32 numOfSamplesPerSplit
) const
1661 ///--------------------------------------------------------------------------------------------
1662 /// Get pipe interleave, bank and pipe bits
1663 ///--------------------------------------------------------------------------------------------
1664 UINT_32 pipeInterleaveBits
= Log2(pipeInterleaveBytes
);
1665 UINT_32 pipeBits
= Log2(numOfPipes
);
1666 UINT_32 bankBits
= Log2(numOfBanks
);
1668 ///--------------------------------------------------------------------------------------------
1669 /// Clear pipe and bank swizzles
1670 ///--------------------------------------------------------------------------------------------
1671 UINT_32 dataMacrotileBits
= pipeInterleaveBits
+ pipeBits
+ bankBits
;
1672 UINT_32 metadataMacrotileBits
= pipeInterleaveBits
+ pipeBits
+ bankBits
;
1674 UINT_64 dataMacrotileClearMask
= ~((1L << dataMacrotileBits
) - 1);
1675 UINT_64 metadataMacrotileClearMask
= ~((1L << metadataMacrotileBits
) - 1);
1677 UINT_64 dataBaseByteAddressNoSwizzle
= dataBaseByteAddress
& dataMacrotileClearMask
;
1678 UINT_64 metadataBaseByteAddressNoSwizzle
= metadataBaseByteAddress
& metadataMacrotileClearMask
;
1680 ///--------------------------------------------------------------------------------------------
1681 /// Modify metadata base before adding in so that when final address is divided by data ratio,
1682 /// the base address returns to where it should be
1683 ///--------------------------------------------------------------------------------------------
1684 ADDR_ASSERT((0 != metadataBitSize
));
1685 UINT_64 metadataBaseShifted
= metadataBaseByteAddressNoSwizzle
* blockByteSize
* 8 /
1687 UINT_64 offset
= uncompressedDataByteAddress
-
1688 dataBaseByteAddressNoSwizzle
+
1689 metadataBaseShifted
;
1691 ///--------------------------------------------------------------------------------------------
1692 /// Save bank data bits
1693 ///--------------------------------------------------------------------------------------------
1694 UINT_32 lsb
= pipeBits
+ pipeInterleaveBits
;
1695 UINT_32 msb
= bankBits
- 1 + lsb
;
1697 UINT_64 bankDataBits
= AddrGetBits(offset
, msb
, lsb
);
1699 ///--------------------------------------------------------------------------------------------
1700 /// Save pipe data bits
1701 ///--------------------------------------------------------------------------------------------
1702 lsb
= pipeInterleaveBits
;
1703 msb
= pipeBits
- 1 + lsb
;
1705 UINT_64 pipeDataBits
= AddrGetBits(offset
, msb
, lsb
);
1707 ///--------------------------------------------------------------------------------------------
1708 /// Remove pipe and bank bits
1709 ///--------------------------------------------------------------------------------------------
1710 lsb
= pipeInterleaveBits
;
1711 msb
= dataMacrotileBits
- 1;
1713 UINT_64 offsetWithoutPipeBankBits
= AddrRemoveBits(offset
, msb
, lsb
);
1715 ADDR_ASSERT((0 != blockByteSize
));
1716 UINT_64 blockInBankpipe
= offsetWithoutPipeBankBits
/ blockByteSize
;
1718 UINT_32 tileSize
= 8 * 8 * elementBitSize
/8 * numOfSamplesPerSplit
;
1719 UINT_32 blocksInTile
= tileSize
/ blockByteSize
;
1721 if (0 == blocksInTile
)
1727 lsb
= Log2(blocksInTile
);
1729 msb
= bankBits
- 1 + lsb
;
1731 UINT_64 blockInBankpipeWithBankBits
= AddrInsertBits(blockInBankpipe
, bankDataBits
, msb
, lsb
);
1733 /// NOTE *2 because we are converting to Nibble address in this step
1734 UINT_64 metaAddressInPipe
= blockInBankpipeWithBankBits
* 2 * metadataBitSize
/ 8;
1737 ///--------------------------------------------------------------------------------------------
1738 /// Reinsert pipe bits back into the final address
1739 ///--------------------------------------------------------------------------------------------
1740 lsb
= pipeInterleaveBits
+ 1; ///<+1 due to Nibble address now gives interleave bits extra lsb.
1741 msb
= pipeBits
- 1 + lsb
;
1742 UINT_64 metadataAddress
= AddrInsertBits(metaAddressInPipe
, pipeDataBits
, msb
, lsb
);
1744 return metadataAddress
;
1748 ***************************************************************************************************
1749 * CiAddrLib::HwlPadDimensions
1752 * Helper function to pad dimensions
1757 ***************************************************************************************************
1759 VOID
CiAddrLib::HwlPadDimensions(
1760 AddrTileMode tileMode
, ///< [in] tile mode
1761 UINT_32 bpp
, ///< [in] bits per pixel
1762 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
1763 UINT_32 numSamples
, ///< [in] number of samples
1764 ADDR_TILEINFO
* pTileInfo
, ///< [in/out] bank structure.
1765 UINT_32 padDims
, ///< [in] Dimensions to pad valid value 1,2,3
1766 UINT_32 mipLevel
, ///< [in] MipLevel
1767 UINT_32
* pPitch
, ///< [in/out] pitch in pixels
1768 UINT_32 pitchAlign
, ///< [in] pitch alignment
1769 UINT_32
* pHeight
, ///< [in/out] height in pixels
1770 UINT_32 heightAlign
, ///< [in] height alignment
1771 UINT_32
* pSlices
, ///< [in/out] number of slices
1772 UINT_32 sliceAlign
///< [in] number of slice alignment
1775 if (m_settings
.isVolcanicIslands
&&
1776 flags
.dccCompatible
&&
1779 IsMacroTiled(tileMode
))
1781 UINT_32 tileSizePerSample
= BITS_TO_BYTES(bpp
* MicroTileWidth
* MicroTileHeight
);
1782 UINT_32 samplesPerSplit
= pTileInfo
->tileSplitBytes
/ tileSizePerSample
;
1784 if (samplesPerSplit
< numSamples
)
1786 UINT_32 dccFastClearByteAlign
= HwlGetPipes(pTileInfo
) * m_pipeInterleaveBytes
* 256;
1787 UINT_32 bytesPerSplit
= BITS_TO_BYTES((*pPitch
) * (*pHeight
) * bpp
* samplesPerSplit
);
1789 ADDR_ASSERT(IsPow2(dccFastClearByteAlign
));
1791 if (0 != (bytesPerSplit
& (dccFastClearByteAlign
- 1)))
1793 UINT_32 dccFastClearPixelAlign
= dccFastClearByteAlign
/
1794 BITS_TO_BYTES(bpp
) /
1796 UINT_32 macroTilePixelAlign
= pitchAlign
* heightAlign
;
1798 if ((dccFastClearPixelAlign
>= macroTilePixelAlign
) &&
1799 ((dccFastClearPixelAlign
% macroTilePixelAlign
) == 0))
1801 UINT_32 dccFastClearPitchAlignInMacroTile
=
1802 dccFastClearPixelAlign
/ macroTilePixelAlign
;
1803 UINT_32 heightInMacroTile
= *pHeight
/ heightAlign
;
1804 UINT_32 dccFastClearPitchAlignInPixels
;
1806 while ((heightInMacroTile
> 1) &&
1807 ((heightInMacroTile
% 2) == 0) &&
1808 (dccFastClearPitchAlignInMacroTile
> 1) &&
1809 ((dccFastClearPitchAlignInMacroTile
% 2) == 0))
1811 heightInMacroTile
>>= 1;
1812 dccFastClearPitchAlignInMacroTile
>>= 1;
1815 dccFastClearPitchAlignInPixels
= pitchAlign
* dccFastClearPitchAlignInMacroTile
;
1817 if (IsPow2(dccFastClearPitchAlignInPixels
))
1819 *pPitch
= PowTwoAlign((*pPitch
), dccFastClearPitchAlignInPixels
);
1823 *pPitch
+= (dccFastClearPitchAlignInPixels
- 1);
1824 *pPitch
/= dccFastClearPitchAlignInPixels
;
1825 *pPitch
*= dccFastClearPitchAlignInPixels
;