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
;
250 pOut
->dccRamSizeAligned
= TRUE
;
252 ADDR_ASSERT(IsPow2(pOut
->dccRamBaseAlign
));
254 if (0 == (pOut
->dccRamSize
& (pOut
->dccRamBaseAlign
- 1)))
256 pOut
->subLvlCompressible
= TRUE
;
260 UINT_64 dccRamSizeAlign
= HwlGetPipes(&pIn
->tileInfo
) * m_pipeInterleaveBytes
;
262 if (pOut
->dccRamSize
== pOut
->dccFastClearSize
)
264 pOut
->dccFastClearSize
= PowTwoAlign(pOut
->dccRamSize
, dccRamSizeAlign
);
266 if ((pOut
->dccRamSize
& (dccRamSizeAlign
- 1)) != 0)
268 pOut
->dccRamSizeAligned
= FALSE
;
270 pOut
->dccRamSize
= PowTwoAlign(pOut
->dccRamSize
, dccRamSizeAlign
);
271 pOut
->subLvlCompressible
= FALSE
;
276 returnCode
= ADDR_NOTSUPPORTED
;
283 ***************************************************************************************************
284 * CiAddrLib::HwlComputeCmaskAddrFromCoord
287 * Compute tc compatible Cmask address from fmask ram address
291 ***************************************************************************************************
293 ADDR_E_RETURNCODE
CiAddrLib::HwlComputeCmaskAddrFromCoord(
294 const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] fmask addr/bpp/tile input
295 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] cmask address
298 ADDR_E_RETURNCODE returnCode
= ADDR_NOTSUPPORTED
;
300 if ((m_settings
.isVolcanicIslands
== TRUE
) &&
301 (pIn
->flags
.tcCompatible
== TRUE
))
303 UINT_32 numOfPipes
= HwlGetPipes(pIn
->pTileInfo
);
304 UINT_32 numOfBanks
= pIn
->pTileInfo
->banks
;
305 UINT_64 fmaskAddress
= pIn
->fmaskAddr
;
306 UINT_32 elemBits
= pIn
->bpp
;
307 UINT_32 blockByte
= 64 * elemBits
/ 8;
308 UINT_64 metaNibbleAddress
= HwlComputeMetadataNibbleAddress(fmaskAddress
,
314 m_pipeInterleaveBytes
,
318 pOut
->addr
= (metaNibbleAddress
>> 1);
319 pOut
->bitPosition
= (metaNibbleAddress
% 2) ? 4 : 0;
320 returnCode
= ADDR_OK
;
327 ***************************************************************************************************
328 * CiAddrLib::HwlComputeHtileAddrFromCoord
331 * Compute tc compatible Htile address from depth/stencil address
335 ***************************************************************************************************
337 ADDR_E_RETURNCODE
CiAddrLib::HwlComputeHtileAddrFromCoord(
338 const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] depth/stencil addr/bpp/tile input
339 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] htile address
342 ADDR_E_RETURNCODE returnCode
= ADDR_NOTSUPPORTED
;
344 if ((m_settings
.isVolcanicIslands
== TRUE
) &&
345 (pIn
->flags
.tcCompatible
== TRUE
))
347 UINT_32 numOfPipes
= HwlGetPipes(pIn
->pTileInfo
);
348 UINT_32 numOfBanks
= pIn
->pTileInfo
->banks
;
349 UINT_64 zStencilAddr
= pIn
->zStencilAddr
;
350 UINT_32 elemBits
= pIn
->bpp
;
351 UINT_32 blockByte
= 64 * elemBits
/ 8;
352 UINT_64 metaNibbleAddress
= HwlComputeMetadataNibbleAddress(zStencilAddr
,
358 m_pipeInterleaveBytes
,
362 pOut
->addr
= (metaNibbleAddress
>> 1);
363 pOut
->bitPosition
= 0;
364 returnCode
= ADDR_OK
;
371 ***************************************************************************************************
372 * CiAddrLib::HwlConvertChipFamily
375 * Convert familyID defined in atiid.h to AddrChipFamily and set m_chipFamily/m_chipRevision
378 ***************************************************************************************************
380 AddrChipFamily
CiAddrLib::HwlConvertChipFamily(
381 UINT_32 uChipFamily
, ///< [in] chip family defined in atiih.h
382 UINT_32 uChipRevision
) ///< [in] chip revision defined in "asic_family"_id.h
384 AddrChipFamily family
= ADDR_CHIP_FAMILY_CI
;
389 m_settings
.isSeaIsland
= 1;
390 m_settings
.isBonaire
= ASICREV_IS_BONAIRE_M(uChipRevision
);
391 m_settings
.isHawaii
= ASICREV_IS_HAWAII_P(uChipRevision
);
394 m_settings
.isKaveri
= 1;
395 m_settings
.isSpectre
= ASICREV_IS_SPECTRE(uChipRevision
);
396 m_settings
.isSpooky
= ASICREV_IS_SPOOKY(uChipRevision
);
397 m_settings
.isKalindi
= ASICREV_IS_KALINDI(uChipRevision
);
400 m_settings
.isVolcanicIslands
= 1;
401 m_settings
.isIceland
= ASICREV_IS_ICELAND_M(uChipRevision
);
402 m_settings
.isTonga
= ASICREV_IS_TONGA_P(uChipRevision
);
403 m_settings
.isFiji
= ASICREV_IS_FIJI_P(uChipRevision
);
404 m_settings
.isPolaris10
= ASICREV_IS_POLARIS10_P(uChipRevision
);
405 m_settings
.isPolaris11
= ASICREV_IS_POLARIS11_M(uChipRevision
);
406 m_settings
.isPolaris12
= ASICREV_IS_POLARIS12_V(uChipRevision
);
409 m_settings
.isCarrizo
= 1;
410 m_settings
.isVolcanicIslands
= 1;
413 ADDR_ASSERT(!"This should be a unexpected Fusion");
421 ***************************************************************************************************
422 * CiAddrLib::HwlInitGlobalParams
425 * Initializes global parameters
428 * TRUE if all settings are valid
430 ***************************************************************************************************
432 BOOL_32
CiAddrLib::HwlInitGlobalParams(
433 const ADDR_CREATE_INPUT
* pCreateIn
) ///< [in] create input
435 BOOL_32 valid
= TRUE
;
437 const ADDR_REGISTER_VALUE
* pRegValue
= &pCreateIn
->regValue
;
439 valid
= DecodeGbRegs(pRegValue
);
441 // The following assignments for m_pipes is only for fail-safe, InitTileSettingTable should
442 // read the correct pipes from tile mode table
443 if (m_settings
.isHawaii
)
445 // Hawaii has 16-pipe, see GFXIP_Config_Summary.xls
448 else if (m_settings
.isBonaire
|| m_settings
.isSpectre
)
452 else // Treat other KV asics to be 2-pipe
458 // Move this to VI code path once created
459 if (m_settings
.isTonga
|| m_settings
.isPolaris10
)
463 else if (m_settings
.isIceland
)
467 else if (m_settings
.isFiji
)
471 else if (m_settings
.isPolaris11
|| m_settings
.isPolaris12
)
478 valid
= InitTileSettingTable(pRegValue
->pTileConfig
, pRegValue
->noOfEntries
);
482 valid
= InitMacroTileCfgTable(pRegValue
->pMacroTileConfig
, pRegValue
->noOfMacroEntries
);
494 ***************************************************************************************************
495 * CiAddrLib::HwlPostCheckTileIndex
498 * Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches
499 * tile mode/type/info and change the index if needed
502 ***************************************************************************************************
504 INT_32
CiAddrLib::HwlPostCheckTileIndex(
505 const ADDR_TILEINFO
* pInfo
, ///< [in] Tile Info
506 AddrTileMode mode
, ///< [in] Tile mode
507 AddrTileType type
, ///< [in] Tile type
508 INT curIndex
///< [in] Current index assigned in HwlSetupTileInfo
511 INT_32 index
= curIndex
;
513 if (mode
== ADDR_TM_LINEAR_GENERAL
)
515 index
= TileIndexLinearGeneral
;
519 BOOL_32 macroTiled
= IsMacroTiled(mode
);
521 // We need to find a new index if either of them is true
522 // 1. curIndex is invalid
523 // 2. tile mode is changed
524 // 3. tile info does not match for macro tiled
525 if ((index
== TileIndexInvalid
) ||
526 (mode
!= m_tileTable
[index
].mode
) ||
527 (macroTiled
&& pInfo
->pipeConfig
!= m_tileTable
[index
].info
.pipeConfig
))
529 for (index
= 0; index
< static_cast<INT_32
>(m_noOfEntries
); index
++)
533 // macro tile modes need all to match
534 if ((pInfo
->pipeConfig
== m_tileTable
[index
].info
.pipeConfig
) &&
535 (mode
== m_tileTable
[index
].mode
) &&
536 (type
== m_tileTable
[index
].type
))
538 // tileSplitBytes stored in m_tileTable is only valid for depth entries
539 if (type
== ADDR_DEPTH_SAMPLE_ORDER
)
541 if (Min(m_tileTable
[index
].info
.tileSplitBytes
,
542 m_rowSize
) == pInfo
->tileSplitBytes
)
547 else // other entries are determined by other 3 fields
553 else if (mode
== ADDR_TM_LINEAR_ALIGNED
)
555 // linear mode only needs tile mode to match
556 if (mode
== m_tileTable
[index
].mode
)
563 // micro tile modes only need tile mode and tile type to match
564 if (mode
== m_tileTable
[index
].mode
&&
565 type
== m_tileTable
[index
].type
)
574 ADDR_ASSERT(index
< static_cast<INT_32
>(m_noOfEntries
));
576 if (index
>= static_cast<INT_32
>(m_noOfEntries
))
578 index
= TileIndexInvalid
;
585 ***************************************************************************************************
586 * CiAddrLib::HwlSetupTileCfg
589 * Map tile index to tile setting.
592 ***************************************************************************************************
594 ADDR_E_RETURNCODE
CiAddrLib::HwlSetupTileCfg(
595 UINT_32 bpp
, ///< [in] Bits per pixel
596 INT_32 index
, ///< [in] Tile index
597 INT_32 macroModeIndex
, ///< [in] Index in macro tile mode table(CI)
598 ADDR_TILEINFO
* pInfo
, ///< [out] Tile Info
599 AddrTileMode
* pMode
, ///< [out] Tile mode
600 AddrTileType
* pType
///< [out] Tile type
603 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
605 // Global flag to control usage of tileIndex
606 if (UseTileIndex(index
))
608 if (index
== TileIndexLinearGeneral
)
611 pInfo
->bankWidth
= 1;
612 pInfo
->bankHeight
= 1;
613 pInfo
->macroAspectRatio
= 1;
614 pInfo
->tileSplitBytes
= 64;
615 pInfo
->pipeConfig
= ADDR_PIPECFG_P2
;
617 else if (static_cast<UINT_32
>(index
) >= m_noOfEntries
)
619 returnCode
= ADDR_INVALIDPARAMS
;
623 const AddrTileConfig
* pCfgTable
= GetTileSetting(index
);
627 if (IsMacroTiled(pCfgTable
->mode
))
629 ADDR_ASSERT((macroModeIndex
!= TileIndexInvalid
) &&
630 (macroModeIndex
!= TileIndexNoMacroIndex
));
634 *pInfo
= m_macroTileTable
[macroModeIndex
];
636 if (pCfgTable
->type
== ADDR_DEPTH_SAMPLE_ORDER
)
638 tileSplit
= pCfgTable
->info
.tileSplitBytes
;
644 UINT_32 thickness
= Thickness(pCfgTable
->mode
);
645 UINT_32 tileBytes1x
= BITS_TO_BYTES(bpp
* MicroTilePixels
* thickness
);
646 // Non-depth entries store a split factor
647 UINT_32 sampleSplit
= m_tileTable
[index
].info
.tileSplitBytes
;
648 tileSplit
= Max(256u, sampleSplit
* tileBytes1x
);
652 // Return tileBytes instead if not enough info
653 tileSplit
= pInfo
->tileSplitBytes
;
658 pInfo
->tileSplitBytes
= Min(m_rowSize
, tileSplit
);
660 pInfo
->pipeConfig
= pCfgTable
->info
.pipeConfig
;
662 else // 1D and linear modes, we return default value stored in table
664 *pInfo
= pCfgTable
->info
;
670 *pMode
= pCfgTable
->mode
;
675 *pType
= pCfgTable
->type
;
684 ***************************************************************************************************
685 * CiAddrLib::HwlComputeSurfaceInfo
688 * Entry of ci's ComputeSurfaceInfo
691 ***************************************************************************************************
693 ADDR_E_RETURNCODE
CiAddrLib::HwlComputeSurfaceInfo(
694 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
695 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
698 // If tileIndex is invalid, force macroModeIndex to be invalid, too
699 if (pIn
->tileIndex
== TileIndexInvalid
)
701 pOut
->macroModeIndex
= TileIndexInvalid
;
704 // Pass tcCompatible flag from input to output; and turn off it if tile split occurs
705 pOut
->tcCompatible
= pIn
->flags
.tcCompatible
;
707 ADDR_E_RETURNCODE retCode
= SiAddrLib::HwlComputeSurfaceInfo(pIn
,pOut
);
709 if (pOut
->macroModeIndex
== TileIndexNoMacroIndex
)
711 pOut
->macroModeIndex
= TileIndexInvalid
;
718 ***************************************************************************************************
719 * CiAddrLib::HwlFmaskSurfaceInfo
721 * Entry of r800's ComputeFmaskInfo
724 ***************************************************************************************************
726 ADDR_E_RETURNCODE
CiAddrLib::HwlComputeFmaskInfo(
727 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
728 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
731 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
733 ADDR_TILEINFO tileInfo
= {0};
734 ADDR_COMPUTE_FMASK_INFO_INPUT fmaskIn
;
737 AddrTileMode tileMode
= pIn
->tileMode
;
739 // Use internal tile info if pOut does not have a valid pTileInfo
740 if (pOut
->pTileInfo
== NULL
)
742 pOut
->pTileInfo
= &tileInfo
;
745 ADDR_ASSERT(tileMode
== ADDR_TM_2D_TILED_THIN1
||
746 tileMode
== ADDR_TM_3D_TILED_THIN1
||
747 tileMode
== ADDR_TM_PRT_TILED_THIN1
||
748 tileMode
== ADDR_TM_PRT_2D_TILED_THIN1
||
749 tileMode
== ADDR_TM_PRT_3D_TILED_THIN1
);
751 ADDR_ASSERT(m_tileTable
[14].mode
== ADDR_TM_2D_TILED_THIN1
);
752 ADDR_ASSERT(m_tileTable
[15].mode
== ADDR_TM_3D_TILED_THIN1
);
754 // The only valid tile modes for fmask are 2D_THIN1 and 3D_THIN1 plus non-displayable
755 INT_32 tileIndex
= tileMode
== ADDR_TM_2D_TILED_THIN1
? 14 : 15;
756 ADDR_SURFACE_FLAGS flags
= {{0}};
759 INT_32 macroModeIndex
= TileIndexInvalid
;
761 UINT_32 numSamples
= pIn
->numSamples
;
762 UINT_32 numFrags
= pIn
->numFrags
== 0 ? numSamples
: pIn
->numFrags
;
764 UINT_32 bpp
= QLog2(numFrags
);
766 // EQAA needs one more bit
767 if (numSamples
> numFrags
)
777 bpp
= Max(8u, bpp
* numSamples
);
779 macroModeIndex
= HwlComputeMacroModeIndex(tileIndex
, flags
, bpp
, numSamples
, pOut
->pTileInfo
);
781 fmaskIn
.tileIndex
= tileIndex
;
782 fmaskIn
.pTileInfo
= pOut
->pTileInfo
;
783 pOut
->macroModeIndex
= macroModeIndex
;
784 pOut
->tileIndex
= tileIndex
;
786 retCode
= DispatchComputeFmaskInfo(&fmaskIn
, pOut
);
788 if (retCode
== ADDR_OK
)
791 HwlPostCheckTileIndex(pOut
->pTileInfo
, pIn
->tileMode
, ADDR_NON_DISPLAYABLE
,
795 // Resets pTileInfo to NULL if the internal tile info is used
796 if (pOut
->pTileInfo
== &tileInfo
)
798 pOut
->pTileInfo
= NULL
;
805 ***************************************************************************************************
806 * CiAddrLib::HwlFmaskPreThunkSurfInfo
809 * Some preparation before thunking a ComputeSurfaceInfo call for Fmask
812 ***************************************************************************************************
814 VOID
CiAddrLib::HwlFmaskPreThunkSurfInfo(
815 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pFmaskIn
, ///< [in] Input of fmask info
816 const ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pFmaskOut
, ///< [in] Output of fmask info
817 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pSurfIn
, ///< [out] Input of thunked surface info
818 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pSurfOut
///< [out] Output of thunked surface info
821 pSurfIn
->tileIndex
= pFmaskIn
->tileIndex
;
822 pSurfOut
->macroModeIndex
= pFmaskOut
->macroModeIndex
;
826 ***************************************************************************************************
827 * CiAddrLib::HwlFmaskPostThunkSurfInfo
830 * Copy hwl extra field after calling thunked ComputeSurfaceInfo
833 ***************************************************************************************************
835 VOID
CiAddrLib::HwlFmaskPostThunkSurfInfo(
836 const ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pSurfOut
, ///< [in] Output of surface info
837 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pFmaskOut
///< [out] Output of fmask info
840 pFmaskOut
->tileIndex
= pSurfOut
->tileIndex
;
841 pFmaskOut
->macroModeIndex
= pSurfOut
->macroModeIndex
;
845 ***************************************************************************************************
846 * CiAddrLib::HwlDegradeThickTileMode
849 * Degrades valid tile mode for thick modes if needed
853 ***************************************************************************************************
855 AddrTileMode
CiAddrLib::HwlDegradeThickTileMode(
856 AddrTileMode baseTileMode
, ///< [in] base tile mode
857 UINT_32 numSlices
, ///< [in] current number of slices
858 UINT_32
* pBytesPerTile
///< [in/out] pointer to bytes per slice
865 ***************************************************************************************************
866 * CiAddrLib::HwlOverrideTileMode
869 * Override THICK to THIN, for specific formats on CI
874 ***************************************************************************************************
876 VOID
CiAddrLib::HwlOverrideTileMode(
877 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in/out] input output structure
880 AddrTileMode tileMode
= pInOut
->tileMode
;
881 AddrTileType tileType
= pInOut
->tileType
;
883 // currently, all CI/VI family do not
884 // support ADDR_TM_PRT_2D_TILED_THICK,ADDR_TM_PRT_3D_TILED_THICK and
885 // ADDR_TM_PRT_2D_TILED_THIN1, ADDR_TM_PRT_3D_TILED_THIN1
888 case ADDR_TM_PRT_2D_TILED_THICK
:
889 case ADDR_TM_PRT_3D_TILED_THICK
:
890 tileMode
= ADDR_TM_PRT_TILED_THICK
;
892 case ADDR_TM_PRT_2D_TILED_THIN1
:
893 case ADDR_TM_PRT_3D_TILED_THIN1
:
894 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
900 // UBTS#404321, we do not need such overriding, as THICK+THICK entries removed from the tile-mode table
901 if (!m_settings
.isBonaire
)
903 UINT_32 thickness
= Thickness(tileMode
);
905 // tile_thickness = (array_mode == XTHICK) ? 8 : ((array_mode == THICK) ? 4 : 1)
908 switch (pInOut
->format
)
910 // see //gfxip/gcB/devel/cds/src/verif/tc/models/csim/tcp.cpp
911 // tcpError("Thick micro tiling is not supported for format...
912 case ADDR_FMT_X24_8_32_FLOAT
:
913 case ADDR_FMT_32_AS_8
:
914 case ADDR_FMT_32_AS_8_8
:
915 case ADDR_FMT_32_AS_32_32_32_32
:
920 case ADDR_FMT_1_REVERSED
:
931 case ADDR_TM_1D_TILED_THICK
:
932 tileMode
= ADDR_TM_1D_TILED_THIN1
;
935 case ADDR_TM_2D_TILED_XTHICK
:
936 case ADDR_TM_2D_TILED_THICK
:
937 tileMode
= ADDR_TM_2D_TILED_THIN1
;
940 case ADDR_TM_3D_TILED_XTHICK
:
941 case ADDR_TM_3D_TILED_THICK
:
942 tileMode
= ADDR_TM_3D_TILED_THIN1
;
945 case ADDR_TM_PRT_TILED_THICK
:
946 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
949 case ADDR_TM_PRT_2D_TILED_THICK
:
950 tileMode
= ADDR_TM_PRT_2D_TILED_THIN1
;
953 case ADDR_TM_PRT_3D_TILED_THICK
:
954 tileMode
= ADDR_TM_PRT_3D_TILED_THIN1
;
962 // Switch tile type from thick to thin
963 if (tileMode
!= pInOut
->tileMode
)
965 // see tileIndex: 13-18
966 tileType
= ADDR_NON_DISPLAYABLE
;
976 // Override 2D/3D macro tile mode to PRT_* tile mode if
977 // client driver requests this surface is equation compatible
978 if ((pInOut
->flags
.needEquation
== TRUE
) &&
979 (pInOut
->numSamples
<= 1) &&
980 (IsMacroTiled(tileMode
) == TRUE
) &&
981 (IsPrtTileMode(tileMode
) == FALSE
))
983 UINT_32 thickness
= Thickness(tileMode
);
987 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
991 static const UINT_32 PrtTileBytes
= 0x10000;
992 // First prt thick tile index in the tile mode table
993 static const UINT_32 PrtThickTileIndex
= 22;
994 ADDR_TILEINFO tileInfo
= {0};
996 HwlComputeMacroModeIndex(PrtThickTileIndex
,
1002 UINT_32 macroTileBytes
= ((pInOut
->bpp
) >> 3) * 64 * pInOut
->numSamples
*
1003 thickness
* HwlGetPipes(&tileInfo
) *
1004 tileInfo
.banks
* tileInfo
.bankWidth
*
1005 tileInfo
.bankHeight
;
1007 if (macroTileBytes
<= PrtTileBytes
)
1009 tileMode
= ADDR_TM_PRT_TILED_THICK
;
1013 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
1018 if (tileMode
!= pInOut
->tileMode
)
1020 pInOut
->tileMode
= tileMode
;
1021 pInOut
->tileType
= tileType
;
1026 ***************************************************************************************************
1027 * CiAddrLib::HwlSetupTileInfo
1030 * Setup default value of tile info for SI
1031 ***************************************************************************************************
1033 VOID
CiAddrLib::HwlSetupTileInfo(
1034 AddrTileMode tileMode
, ///< [in] Tile mode
1035 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface type flags
1036 UINT_32 bpp
, ///< [in] Bits per pixel
1037 UINT_32 pitch
, ///< [in] Pitch in pixels
1038 UINT_32 height
, ///< [in] Height in pixels
1039 UINT_32 numSamples
, ///< [in] Number of samples
1040 ADDR_TILEINFO
* pTileInfoIn
, ///< [in] Tile info input: NULL for default
1041 ADDR_TILEINFO
* pTileInfoOut
, ///< [out] Tile info output
1042 AddrTileType inTileType
, ///< [in] Tile type
1043 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] Output
1046 UINT_32 thickness
= Thickness(tileMode
);
1047 ADDR_TILEINFO
* pTileInfo
= pTileInfoOut
;
1048 INT index
= TileIndexInvalid
;
1049 INT macroModeIndex
= TileIndexInvalid
;
1052 if (!IsLinear(tileMode
))
1054 // Thick tile modes must use thick micro tile mode but Bonaire does not support due to
1055 // old derived netlists (UBTS 404321)
1058 if (m_settings
.isBonaire
)
1060 inTileType
= ADDR_NON_DISPLAYABLE
;
1062 else if ((m_allowNonDispThickModes
== FALSE
) ||
1063 (inTileType
!= ADDR_NON_DISPLAYABLE
) ||
1064 // There is no PRT_THICK + THIN entry in tile mode table except Bonaire
1065 (IsPrtTileMode(tileMode
) == TRUE
))
1067 inTileType
= ADDR_THICK
;
1070 // 128 bpp tiling must be non-displayable.
1071 // Fmask reuse color buffer's entry but bank-height field can be from another entry
1072 // To simplify the logic, fmask entry should be picked from non-displayable ones
1073 else if (bpp
== 128 || flags
.fmask
)
1075 inTileType
= ADDR_NON_DISPLAYABLE
;
1077 // These two modes only have non-disp entries though they can be other micro tile modes
1078 else if (tileMode
== ADDR_TM_3D_TILED_THIN1
|| tileMode
== ADDR_TM_PRT_3D_TILED_THIN1
)
1080 inTileType
= ADDR_NON_DISPLAYABLE
;
1083 if (flags
.depth
|| flags
.stencil
)
1085 inTileType
= ADDR_DEPTH_SAMPLE_ORDER
;
1089 if (IsTileInfoAllZero(pTileInfo
))
1091 // See table entries 0-4
1092 if (flags
.depth
|| flags
.stencil
)
1094 // tileSize = thickness * bpp * numSamples * 8 * 8 / 8
1095 UINT_32 tileSize
= thickness
* bpp
* numSamples
* 8;
1097 // Turn off tc compatible if row_size is smaller than tile size (tile split occurs).
1098 if (m_rowSize
< tileSize
)
1100 flags
.tcCompatible
= FALSE
;
1101 pOut
->tcCompatible
= FALSE
;
1104 if (flags
.depth
&& (flags
.nonSplit
|| flags
.tcCompatible
|| flags
.needEquation
))
1106 // Texure readable depth surface should not be split
1125 // Depth and stencil need to use the same index, thus the pre-defined tile_split
1126 // can meet the requirement to choose the same macro mode index
1127 // uncompressed depth/stencil are not supported for now
1146 // See table entries 5-6
1147 if (inTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
1151 case ADDR_TM_1D_TILED_THIN1
:
1154 case ADDR_TM_PRT_TILED_THIN1
:
1162 // See table entries 8-12
1163 if (inTileType
== ADDR_DISPLAYABLE
)
1167 case ADDR_TM_1D_TILED_THIN1
:
1170 case ADDR_TM_2D_TILED_THIN1
:
1173 case ADDR_TM_PRT_TILED_THIN1
:
1181 // See table entries 13-18
1182 if (inTileType
== ADDR_NON_DISPLAYABLE
)
1186 case ADDR_TM_1D_TILED_THIN1
:
1189 case ADDR_TM_2D_TILED_THIN1
:
1192 case ADDR_TM_3D_TILED_THIN1
:
1195 case ADDR_TM_PRT_TILED_THIN1
:
1203 // See table entries 19-26
1208 case ADDR_TM_1D_TILED_THICK
:
1209 //special check for bonaire, for the compatablity between old KMD and new UMD for bonaire
1210 index
= ((inTileType
== ADDR_THICK
) || m_settings
.isBonaire
) ? 19 : 18;
1212 case ADDR_TM_2D_TILED_THICK
:
1213 // special check for bonaire, for the compatablity between old KMD and new UMD for bonaire
1214 index
= ((inTileType
== ADDR_THICK
) || m_settings
.isBonaire
) ? 20 : 24;
1216 case ADDR_TM_3D_TILED_THICK
:
1219 case ADDR_TM_PRT_TILED_THICK
:
1222 case ADDR_TM_2D_TILED_XTHICK
:
1225 case ADDR_TM_3D_TILED_XTHICK
:
1233 // See table entries 27-30
1234 if (inTileType
== ADDR_ROTATED
)
1238 case ADDR_TM_1D_TILED_THIN1
:
1241 case ADDR_TM_2D_TILED_THIN1
:
1244 case ADDR_TM_PRT_TILED_THIN1
:
1247 case ADDR_TM_PRT_2D_TILED_THIN1
:
1257 ADDR_ASSERT((index
+ 1) < static_cast<INT_32
>(m_noOfEntries
));
1258 // Only do this when tile mode table is updated.
1259 if (((tileMode
== ADDR_TM_PRT_TILED_THIN1
) || (tileMode
== ADDR_TM_PRT_TILED_THICK
)) &&
1260 (m_tileTable
[index
+ 1].mode
== tileMode
))
1262 static const UINT_32 PrtTileBytes
= 0x10000;
1263 ADDR_TILEINFO tileInfo
= {0};
1265 HwlComputeMacroModeIndex(index
, flags
, bpp
, numSamples
, &tileInfo
);
1267 UINT_32 macroTileBytes
= (bpp
>> 3) * 64 * numSamples
* thickness
*
1268 HwlGetPipes(&tileInfo
) * tileInfo
.banks
*
1269 tileInfo
.bankWidth
* tileInfo
.bankHeight
;
1271 if (macroTileBytes
!= PrtTileBytes
)
1273 // Switching to next tile mode entry to make sure macro tile size is 64KB
1276 tileInfo
.pipeConfig
= m_tileTable
[index
].info
.pipeConfig
;
1278 macroTileBytes
= (bpp
>> 3) * 64 * numSamples
* thickness
*
1279 HwlGetPipes(&tileInfo
) * tileInfo
.banks
*
1280 tileInfo
.bankWidth
* tileInfo
.bankHeight
;
1282 ADDR_ASSERT(macroTileBytes
== PrtTileBytes
);
1289 // A pre-filled tile info is ready
1290 index
= pOut
->tileIndex
;
1291 macroModeIndex
= pOut
->macroModeIndex
;
1293 // pass tile type back for post tile index compute
1294 pOut
->tileType
= inTileType
;
1297 // We only need to set up tile info if there is a valid index but macroModeIndex is invalid
1298 if (index
!= TileIndexInvalid
&& macroModeIndex
== TileIndexInvalid
)
1300 macroModeIndex
= HwlComputeMacroModeIndex(index
, flags
, bpp
, numSamples
, pTileInfo
);
1302 /// Copy to pOut->tileType/tileIndex/macroModeIndex
1303 pOut
->tileIndex
= index
;
1304 pOut
->tileType
= m_tileTable
[index
].type
; // Or inTileType, the samea
1305 pOut
->macroModeIndex
= macroModeIndex
;
1307 else if (tileMode
== ADDR_TM_LINEAR_GENERAL
)
1309 pOut
->tileIndex
= TileIndexLinearGeneral
;
1311 // Copy linear-aligned entry??
1312 *pTileInfo
= m_tileTable
[8].info
;
1314 else if (tileMode
== ADDR_TM_LINEAR_ALIGNED
)
1316 pOut
->tileIndex
= 8;
1317 *pTileInfo
= m_tileTable
[8].info
;
1320 // Turn off tcCompatible for color surface if tileSplit happens. Depth/stencil is
1321 // handled at tileIndex selecting time.
1322 if (pOut
->tcCompatible
&& (inTileType
!= ADDR_DEPTH_SAMPLE_ORDER
))
1324 if (IsMacroTiled(tileMode
))
1326 INT_32 tileIndex
= pOut
->tileIndex
;
1328 if ((tileIndex
== TileIndexInvalid
) && (IsTileInfoAllZero(pTileInfo
) == FALSE
))
1330 tileIndex
= HwlPostCheckTileIndex(pTileInfo
, tileMode
, inTileType
, tileIndex
);
1333 if (tileIndex
!= TileIndexInvalid
)
1335 ADDR_ASSERT(static_cast<UINT_32
>(tileIndex
) < TileTableSize
);
1336 // Non-depth entries store a split factor
1337 UINT_32 sampleSplit
= m_tileTable
[tileIndex
].info
.tileSplitBytes
;
1338 UINT_32 tileBytes1x
= BITS_TO_BYTES(bpp
* MicroTilePixels
* thickness
);
1339 UINT_32 colorTileSplit
= Max(256u, sampleSplit
* tileBytes1x
);
1341 if (m_rowSize
< colorTileSplit
)
1343 pOut
->tcCompatible
= FALSE
;
1349 // Client should not enable tc compatible for linear and 1D tile modes.
1350 pOut
->tcCompatible
= FALSE
;
1356 ***************************************************************************************************
1357 * CiAddrLib::ReadGbTileMode
1360 * Convert GB_TILE_MODE HW value to ADDR_TILE_CONFIG.
1363 ***************************************************************************************************
1365 VOID
CiAddrLib::ReadGbTileMode(
1366 UINT_32 regValue
, ///< [in] GB_TILE_MODE register
1367 AddrTileConfig
* pCfg
///< [out] output structure
1370 GB_TILE_MODE gbTileMode
;
1371 gbTileMode
.val
= regValue
;
1373 pCfg
->type
= static_cast<AddrTileType
>(gbTileMode
.f
.micro_tile_mode_new
);
1374 pCfg
->info
.pipeConfig
= static_cast<AddrPipeCfg
>(gbTileMode
.f
.pipe_config
+ 1);
1376 if (pCfg
->type
== ADDR_DEPTH_SAMPLE_ORDER
)
1378 pCfg
->info
.tileSplitBytes
= 64 << gbTileMode
.f
.tile_split
;
1382 pCfg
->info
.tileSplitBytes
= 1 << gbTileMode
.f
.sample_split
;
1385 UINT_32 regArrayMode
= gbTileMode
.f
.array_mode
;
1387 pCfg
->mode
= static_cast<AddrTileMode
>(regArrayMode
);
1389 switch (regArrayMode
)
1392 pCfg
->mode
= ADDR_TM_PRT_TILED_THIN1
;
1395 pCfg
->mode
= ADDR_TM_PRT_2D_TILED_THIN1
;
1398 pCfg
->mode
= ADDR_TM_2D_TILED_XTHICK
;
1401 pCfg
->mode
= ADDR_TM_PRT_TILED_THICK
;
1404 pCfg
->mode
= ADDR_TM_PRT_2D_TILED_THICK
;
1407 pCfg
->mode
= ADDR_TM_PRT_3D_TILED_THIN1
;
1410 pCfg
->mode
= ADDR_TM_3D_TILED_XTHICK
;
1413 pCfg
->mode
= ADDR_TM_PRT_3D_TILED_THICK
;
1419 // Fail-safe code for these always convert tile info, as the non-macro modes
1420 // return the entry of tile mode table directly without looking up macro mode table
1421 if (!IsMacroTiled(pCfg
->mode
))
1423 pCfg
->info
.banks
= 2;
1424 pCfg
->info
.bankWidth
= 1;
1425 pCfg
->info
.bankHeight
= 1;
1426 pCfg
->info
.macroAspectRatio
= 1;
1427 pCfg
->info
.tileSplitBytes
= 64;
1432 ***************************************************************************************************
1433 * CiAddrLib::InitTileSettingTable
1436 * Initialize the ADDR_TILE_CONFIG table.
1438 * TRUE if tile table is correctly initialized
1439 ***************************************************************************************************
1441 BOOL_32
CiAddrLib::InitTileSettingTable(
1442 const UINT_32
* pCfg
, ///< [in] Pointer to table of tile configs
1443 UINT_32 noOfEntries
///< [in] Numbe of entries in the table above
1446 BOOL_32 initOk
= TRUE
;
1448 ADDR_ASSERT(noOfEntries
<= TileTableSize
);
1450 memset(m_tileTable
, 0, sizeof(m_tileTable
));
1452 if (noOfEntries
!= 0)
1454 m_noOfEntries
= noOfEntries
;
1458 m_noOfEntries
= TileTableSize
;
1461 if (pCfg
) // From Client
1463 for (UINT_32 i
= 0; i
< m_noOfEntries
; i
++)
1465 ReadGbTileMode(*(pCfg
+ i
), &m_tileTable
[i
]);
1470 ADDR_ASSERT_ALWAYS();
1476 ADDR_ASSERT(m_tileTable
[TILEINDEX_LINEAR_ALIGNED
].mode
== ADDR_TM_LINEAR_ALIGNED
);
1478 if (m_settings
.isBonaire
== FALSE
)
1480 // Check if entry 18 is "thick+thin" combination
1481 if ((m_tileTable
[18].mode
== ADDR_TM_1D_TILED_THICK
) &&
1482 (m_tileTable
[18].type
== ADDR_NON_DISPLAYABLE
))
1484 m_allowNonDispThickModes
= TRUE
;
1485 ADDR_ASSERT(m_tileTable
[24].mode
== ADDR_TM_2D_TILED_THICK
);
1490 m_allowNonDispThickModes
= TRUE
;
1493 // Assume the first entry is always programmed with full pipes
1494 m_pipes
= HwlGetPipes(&m_tileTable
[0].info
);
1501 ***************************************************************************************************
1502 * CiAddrLib::ReadGbMacroTileCfg
1505 * Convert GB_MACRO_TILE_CFG HW value to ADDR_TILE_CONFIG.
1508 ***************************************************************************************************
1510 VOID
CiAddrLib::ReadGbMacroTileCfg(
1511 UINT_32 regValue
, ///< [in] GB_MACRO_TILE_MODE register
1512 ADDR_TILEINFO
* pCfg
///< [out] output structure
1515 GB_MACROTILE_MODE gbTileMode
;
1516 gbTileMode
.val
= regValue
;
1518 pCfg
->bankHeight
= 1 << gbTileMode
.f
.bank_height
;
1519 pCfg
->bankWidth
= 1 << gbTileMode
.f
.bank_width
;
1520 pCfg
->banks
= 1 << (gbTileMode
.f
.num_banks
+ 1);
1521 pCfg
->macroAspectRatio
= 1 << gbTileMode
.f
.macro_tile_aspect
;
1525 ***************************************************************************************************
1526 * CiAddrLib::InitMacroTileCfgTable
1529 * Initialize the ADDR_MACRO_TILE_CONFIG table.
1531 * TRUE if macro tile table is correctly initialized
1532 ***************************************************************************************************
1534 BOOL_32
CiAddrLib::InitMacroTileCfgTable(
1535 const UINT_32
* pCfg
, ///< [in] Pointer to table of tile configs
1536 UINT_32 noOfMacroEntries
///< [in] Numbe of entries in the table above
1539 BOOL_32 initOk
= TRUE
;
1541 ADDR_ASSERT(noOfMacroEntries
<= MacroTileTableSize
);
1543 memset(m_macroTileTable
, 0, sizeof(m_macroTileTable
));
1545 if (noOfMacroEntries
!= 0)
1547 m_noOfMacroEntries
= noOfMacroEntries
;
1551 m_noOfMacroEntries
= MacroTileTableSize
;
1554 if (pCfg
) // From Client
1556 for (UINT_32 i
= 0; i
< m_noOfMacroEntries
; i
++)
1558 ReadGbMacroTileCfg(*(pCfg
+ i
), &m_macroTileTable
[i
]);
1560 m_macroTileTable
[i
].tileSplitBytes
= 64 << (i
% 8);
1565 ADDR_ASSERT_ALWAYS();
1572 ***************************************************************************************************
1573 * CiAddrLib::HwlComputeMacroModeIndex
1576 * Computes macro tile mode index
1578 * TRUE if macro tile table is correctly initialized
1579 ***************************************************************************************************
1581 INT_32
CiAddrLib::HwlComputeMacroModeIndex(
1582 INT_32 tileIndex
, ///< [in] Tile mode index
1583 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface flags
1584 UINT_32 bpp
, ///< [in] Bit per pixel
1585 UINT_32 numSamples
, ///< [in] Number of samples
1586 ADDR_TILEINFO
* pTileInfo
, ///< [out] Pointer to ADDR_TILEINFO
1587 AddrTileMode
* pTileMode
, ///< [out] Pointer to AddrTileMode
1588 AddrTileType
* pTileType
///< [out] Pointer to AddrTileType
1591 INT_32 macroModeIndex
= TileIndexInvalid
;
1593 AddrTileMode tileMode
= m_tileTable
[tileIndex
].mode
;
1594 AddrTileType tileType
= m_tileTable
[tileIndex
].type
;
1595 UINT_32 thickness
= Thickness(tileMode
);
1597 if (!IsMacroTiled(tileMode
))
1599 *pTileInfo
= m_tileTable
[tileIndex
].info
;
1600 macroModeIndex
= TileIndexNoMacroIndex
;
1604 UINT_32 tileBytes1x
= BITS_TO_BYTES(bpp
* MicroTilePixels
* thickness
);
1607 if (m_tileTable
[tileIndex
].type
== ADDR_DEPTH_SAMPLE_ORDER
)
1609 // Depth entries store real tileSplitBytes
1610 tileSplit
= m_tileTable
[tileIndex
].info
.tileSplitBytes
;
1614 // Non-depth entries store a split factor
1615 UINT_32 sampleSplit
= m_tileTable
[tileIndex
].info
.tileSplitBytes
;
1616 UINT_32 colorTileSplit
= Max(256u, sampleSplit
* tileBytes1x
);
1618 tileSplit
= colorTileSplit
;
1621 UINT_32 tileSplitC
= Min(m_rowSize
, tileSplit
);
1626 tileBytes
= Min(tileSplitC
, tileBytes1x
);
1630 tileBytes
= Min(tileSplitC
, numSamples
* tileBytes1x
);
1638 macroModeIndex
= Log2(tileBytes
/ 64);
1640 if (flags
.prt
|| IsPrtTileMode(tileMode
))
1642 // Unknown - assume it is 1/2 of table size
1643 const UINT_32 PrtMacroModeOffset
= MacroTileTableSize
/ 2;
1645 macroModeIndex
+= PrtMacroModeOffset
;
1646 *pTileInfo
= m_macroTileTable
[macroModeIndex
];
1650 *pTileInfo
= m_macroTileTable
[macroModeIndex
];
1653 pTileInfo
->pipeConfig
= m_tileTable
[tileIndex
].info
.pipeConfig
;
1655 pTileInfo
->tileSplitBytes
= tileSplitC
;
1658 if (NULL
!= pTileMode
)
1660 *pTileMode
= tileMode
;
1663 if (NULL
!= pTileType
)
1665 *pTileType
= tileType
;
1668 return macroModeIndex
;
1672 ***************************************************************************************************
1673 * CiAddrLib::HwlComputeTileDataWidthAndHeightLinear
1676 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1682 * MacroWidth and macroHeight are measured in pixels
1683 ***************************************************************************************************
1685 VOID
CiAddrLib::HwlComputeTileDataWidthAndHeightLinear(
1686 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1687 UINT_32
* pMacroHeight
, ///< [out] macro tile height
1688 UINT_32 bpp
, ///< [in] bits per pixel
1689 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
1692 ADDR_ASSERT(pTileInfo
!= NULL
);
1696 switch (pTileInfo
->pipeConfig
)
1698 case ADDR_PIPECFG_P16_32x32_8x16
:
1699 case ADDR_PIPECFG_P16_32x32_16x16
:
1700 case ADDR_PIPECFG_P8_32x64_32x32
:
1701 case ADDR_PIPECFG_P8_32x32_16x32
:
1702 case ADDR_PIPECFG_P8_32x32_16x16
:
1703 case ADDR_PIPECFG_P8_32x32_8x16
:
1704 case ADDR_PIPECFG_P4_32x32
:
1712 *pMacroWidth
= numTiles
* MicroTileWidth
;
1713 *pMacroHeight
= numTiles
* MicroTileHeight
;
1717 ***************************************************************************************************
1718 * CiAddrLib::HwlComputeMetadataNibbleAddress
1721 * calculate meta data address based on input information
1724 * uncompressedDataByteAddress - address of a pixel in color surface
1725 * dataBaseByteAddress - base address of color surface
1726 * metadataBaseByteAddress - base address of meta ram
1727 * metadataBitSize - meta key size, 8 for DCC, 4 for cmask
1728 * elementBitSize - element size of color surface
1729 * blockByteSize - compression block size, 256 for DCC
1730 * pipeInterleaveBytes - pipe interleave size
1731 * numOfPipes - number of pipes
1732 * numOfBanks - number of banks
1733 * numOfSamplesPerSplit - number of samples per tile split
1735 * meta data nibble address (nibble address is used to support DCC compatible cmask)
1737 ***************************************************************************************************
1739 UINT_64
CiAddrLib::HwlComputeMetadataNibbleAddress(
1740 UINT_64 uncompressedDataByteAddress
,
1741 UINT_64 dataBaseByteAddress
,
1742 UINT_64 metadataBaseByteAddress
,
1743 UINT_32 metadataBitSize
,
1744 UINT_32 elementBitSize
,
1745 UINT_32 blockByteSize
,
1746 UINT_32 pipeInterleaveBytes
,
1749 UINT_32 numOfSamplesPerSplit
) const
1751 ///--------------------------------------------------------------------------------------------
1752 /// Get pipe interleave, bank and pipe bits
1753 ///--------------------------------------------------------------------------------------------
1754 UINT_32 pipeInterleaveBits
= Log2(pipeInterleaveBytes
);
1755 UINT_32 pipeBits
= Log2(numOfPipes
);
1756 UINT_32 bankBits
= Log2(numOfBanks
);
1758 ///--------------------------------------------------------------------------------------------
1759 /// Clear pipe and bank swizzles
1760 ///--------------------------------------------------------------------------------------------
1761 UINT_32 dataMacrotileBits
= pipeInterleaveBits
+ pipeBits
+ bankBits
;
1762 UINT_32 metadataMacrotileBits
= pipeInterleaveBits
+ pipeBits
+ bankBits
;
1764 UINT_64 dataMacrotileClearMask
= ~((1L << dataMacrotileBits
) - 1);
1765 UINT_64 metadataMacrotileClearMask
= ~((1L << metadataMacrotileBits
) - 1);
1767 UINT_64 dataBaseByteAddressNoSwizzle
= dataBaseByteAddress
& dataMacrotileClearMask
;
1768 UINT_64 metadataBaseByteAddressNoSwizzle
= metadataBaseByteAddress
& metadataMacrotileClearMask
;
1770 ///--------------------------------------------------------------------------------------------
1771 /// Modify metadata base before adding in so that when final address is divided by data ratio,
1772 /// the base address returns to where it should be
1773 ///--------------------------------------------------------------------------------------------
1774 ADDR_ASSERT((0 != metadataBitSize
));
1775 UINT_64 metadataBaseShifted
= metadataBaseByteAddressNoSwizzle
* blockByteSize
* 8 /
1777 UINT_64 offset
= uncompressedDataByteAddress
-
1778 dataBaseByteAddressNoSwizzle
+
1779 metadataBaseShifted
;
1781 ///--------------------------------------------------------------------------------------------
1782 /// Save bank data bits
1783 ///--------------------------------------------------------------------------------------------
1784 UINT_32 lsb
= pipeBits
+ pipeInterleaveBits
;
1785 UINT_32 msb
= bankBits
- 1 + lsb
;
1787 UINT_64 bankDataBits
= AddrGetBits(offset
, msb
, lsb
);
1789 ///--------------------------------------------------------------------------------------------
1790 /// Save pipe data bits
1791 ///--------------------------------------------------------------------------------------------
1792 lsb
= pipeInterleaveBits
;
1793 msb
= pipeBits
- 1 + lsb
;
1795 UINT_64 pipeDataBits
= AddrGetBits(offset
, msb
, lsb
);
1797 ///--------------------------------------------------------------------------------------------
1798 /// Remove pipe and bank bits
1799 ///--------------------------------------------------------------------------------------------
1800 lsb
= pipeInterleaveBits
;
1801 msb
= dataMacrotileBits
- 1;
1803 UINT_64 offsetWithoutPipeBankBits
= AddrRemoveBits(offset
, msb
, lsb
);
1805 ADDR_ASSERT((0 != blockByteSize
));
1806 UINT_64 blockInBankpipe
= offsetWithoutPipeBankBits
/ blockByteSize
;
1808 UINT_32 tileSize
= 8 * 8 * elementBitSize
/8 * numOfSamplesPerSplit
;
1809 UINT_32 blocksInTile
= tileSize
/ blockByteSize
;
1811 if (0 == blocksInTile
)
1817 lsb
= Log2(blocksInTile
);
1819 msb
= bankBits
- 1 + lsb
;
1821 UINT_64 blockInBankpipeWithBankBits
= AddrInsertBits(blockInBankpipe
, bankDataBits
, msb
, lsb
);
1823 /// NOTE *2 because we are converting to Nibble address in this step
1824 UINT_64 metaAddressInPipe
= blockInBankpipeWithBankBits
* 2 * metadataBitSize
/ 8;
1827 ///--------------------------------------------------------------------------------------------
1828 /// Reinsert pipe bits back into the final address
1829 ///--------------------------------------------------------------------------------------------
1830 lsb
= pipeInterleaveBits
+ 1; ///<+1 due to Nibble address now gives interleave bits extra lsb.
1831 msb
= pipeBits
- 1 + lsb
;
1832 UINT_64 metadataAddress
= AddrInsertBits(metaAddressInPipe
, pipeDataBits
, msb
, lsb
);
1834 return metadataAddress
;
1838 ***************************************************************************************************
1839 * CiAddrLib::HwlPadDimensions
1842 * Helper function to pad dimensions
1847 ***************************************************************************************************
1849 VOID
CiAddrLib::HwlPadDimensions(
1850 AddrTileMode tileMode
, ///< [in] tile mode
1851 UINT_32 bpp
, ///< [in] bits per pixel
1852 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
1853 UINT_32 numSamples
, ///< [in] number of samples
1854 ADDR_TILEINFO
* pTileInfo
, ///< [in/out] bank structure.
1855 UINT_32 padDims
, ///< [in] Dimensions to pad valid value 1,2,3
1856 UINT_32 mipLevel
, ///< [in] MipLevel
1857 UINT_32
* pPitch
, ///< [in/out] pitch in pixels
1858 UINT_32 pitchAlign
, ///< [in] pitch alignment
1859 UINT_32
* pHeight
, ///< [in/out] height in pixels
1860 UINT_32 heightAlign
, ///< [in] height alignment
1861 UINT_32
* pSlices
, ///< [in/out] number of slices
1862 UINT_32 sliceAlign
///< [in] number of slice alignment
1865 if (m_settings
.isVolcanicIslands
&&
1866 flags
.dccCompatible
&&
1869 IsMacroTiled(tileMode
))
1871 UINT_32 tileSizePerSample
= BITS_TO_BYTES(bpp
* MicroTileWidth
* MicroTileHeight
);
1872 UINT_32 samplesPerSplit
= pTileInfo
->tileSplitBytes
/ tileSizePerSample
;
1874 if (samplesPerSplit
< numSamples
)
1876 UINT_32 dccFastClearByteAlign
= HwlGetPipes(pTileInfo
) * m_pipeInterleaveBytes
* 256;
1877 UINT_32 bytesPerSplit
= BITS_TO_BYTES((*pPitch
) * (*pHeight
) * bpp
* samplesPerSplit
);
1879 ADDR_ASSERT(IsPow2(dccFastClearByteAlign
));
1881 if (0 != (bytesPerSplit
& (dccFastClearByteAlign
- 1)))
1883 UINT_32 dccFastClearPixelAlign
= dccFastClearByteAlign
/
1884 BITS_TO_BYTES(bpp
) /
1886 UINT_32 macroTilePixelAlign
= pitchAlign
* heightAlign
;
1888 if ((dccFastClearPixelAlign
>= macroTilePixelAlign
) &&
1889 ((dccFastClearPixelAlign
% macroTilePixelAlign
) == 0))
1891 UINT_32 dccFastClearPitchAlignInMacroTile
=
1892 dccFastClearPixelAlign
/ macroTilePixelAlign
;
1893 UINT_32 heightInMacroTile
= *pHeight
/ heightAlign
;
1894 UINT_32 dccFastClearPitchAlignInPixels
;
1896 while ((heightInMacroTile
> 1) &&
1897 ((heightInMacroTile
% 2) == 0) &&
1898 (dccFastClearPitchAlignInMacroTile
> 1) &&
1899 ((dccFastClearPitchAlignInMacroTile
% 2) == 0))
1901 heightInMacroTile
>>= 1;
1902 dccFastClearPitchAlignInMacroTile
>>= 1;
1905 dccFastClearPitchAlignInPixels
= pitchAlign
* dccFastClearPitchAlignInMacroTile
;
1907 if (IsPow2(dccFastClearPitchAlignInPixels
))
1909 *pPitch
= PowTwoAlign((*pPitch
), dccFastClearPitchAlignInPixels
);
1913 *pPitch
+= (dccFastClearPitchAlignInPixels
- 1);
1914 *pPitch
/= dccFastClearPitchAlignInPixels
;
1915 *pPitch
*= dccFastClearPitchAlignInPixels
;
1924 ***************************************************************************************************
1925 * CiAddrLib::HwlGetMaxAlignments
1928 * Gets maximum alignments
1931 ***************************************************************************************************
1933 ADDR_E_RETURNCODE
CiAddrLib::HwlGetMaxAlignments(
1934 ADDR_GET_MAX_ALINGMENTS_OUTPUT
* pOut
///< [out] output structure
1937 const UINT_32 pipes
= HwlGetPipes(&m_tileTable
[0].info
);
1939 // Initial size is 64 KiB for PRT.
1940 UINT_64 maxBaseAlign
= 64 * 1024;
1942 for (UINT_32 i
= 0; i
< m_noOfMacroEntries
; i
++)
1944 // The maximum tile size is 16 byte-per-pixel and either 8-sample or 8-slice.
1945 UINT_32 tileSize
= m_macroTileTable
[i
].tileSplitBytes
;
1947 UINT_64 baseAlign
= tileSize
* pipes
* m_macroTileTable
[i
].banks
*
1948 m_macroTileTable
[i
].bankWidth
* m_macroTileTable
[i
].bankHeight
;
1950 if (baseAlign
> maxBaseAlign
)
1952 maxBaseAlign
= baseAlign
;
1958 pOut
->baseAlign
= maxBaseAlign
;