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 CiLib 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 ////////////////////////////////////////////////////////////////////////////////////////////////////
55 ****************************************************************************************************
59 * Creates an CiLib object.
62 * Returns an CiLib object pointer.
63 ****************************************************************************************************
65 Lib
* CiHwlInit(const Client
* pClient
)
67 return V1::CiLib::CreateObj(pClient
);
74 ****************************************************************************************************
78 * Gets a mask of "width"
81 ****************************************************************************************************
84 UINT_32 width
) ///< Width of bits
88 if (width
>= sizeof(UINT_64
)*8)
94 return (((UINT_64
) 1) << width
) - 1;
100 ****************************************************************************************************
104 * Gets bits within a range of [msb, lsb]
107 ****************************************************************************************************
109 static UINT_64
GetBits(
110 UINT_64 bits
, ///< Source bits
111 UINT_32 msb
, ///< Most signicant bit
112 UINT_32 lsb
) ///< Least signicant bit
118 ret
= (bits
>> lsb
) & (Mask(1 + msb
- lsb
));
124 ****************************************************************************************************
128 * Removes bits within the range of [msb, lsb]
131 ****************************************************************************************************
133 static UINT_64
RemoveBits(
134 UINT_64 bits
, ///< Source bits
135 UINT_32 msb
, ///< Most signicant bit
136 UINT_32 lsb
) ///< Least signicant bit
142 ret
= GetBits(bits
, lsb
- 1, 0) // low bits
143 | (GetBits(bits
, 8 * sizeof(bits
) - 1, msb
+ 1) << lsb
); //high bits
149 ****************************************************************************************************
153 * Inserts new bits into the range of [msb, lsb]
156 ****************************************************************************************************
158 static UINT_64
InsertBits(
159 UINT_64 bits
, ///< Source bits
160 UINT_64 newBits
, ///< New bits to be inserted
161 UINT_32 msb
, ///< Most signicant bit
162 UINT_32 lsb
) ///< Least signicant bit
168 ret
= GetBits(bits
, lsb
- 1, 0) // old low bitss
169 | (GetBits(newBits
, msb
- lsb
, 0) << lsb
) //new bits
170 | (GetBits(bits
, 8 * sizeof(bits
) - 1, lsb
) << (msb
+ 1)); //old high bits
176 ****************************************************************************************************
182 ****************************************************************************************************
184 CiLib::CiLib(const Client
* pClient
)
187 m_noOfMacroEntries(0),
188 m_allowNonDispThickModes(FALSE
)
190 m_class
= CI_ADDRLIB
;
191 memset(&m_settings
, 0, sizeof(m_settings
));
195 ****************************************************************************************************
200 ****************************************************************************************************
207 ****************************************************************************************************
208 * CiLib::HwlComputeDccInfo
211 * Compute DCC key size, base alignment
214 ****************************************************************************************************
216 ADDR_E_RETURNCODE
CiLib::HwlComputeDccInfo(
217 const ADDR_COMPUTE_DCCINFO_INPUT
* pIn
,
218 ADDR_COMPUTE_DCCINFO_OUTPUT
* pOut
) const
220 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
222 if (m_settings
.isVolcanicIslands
&& IsMacroTiled(pIn
->tileMode
))
224 UINT_64 dccFastClearSize
= pIn
->colorSurfSize
>> 8;
226 ADDR_ASSERT(0 == (pIn
->colorSurfSize
& 0xff));
228 if (pIn
->numSamples
> 1)
230 UINT_32 tileSizePerSample
= BITS_TO_BYTES(pIn
->bpp
* MicroTileWidth
* MicroTileHeight
);
231 UINT_32 samplesPerSplit
= pIn
->tileInfo
.tileSplitBytes
/ tileSizePerSample
;
233 if (samplesPerSplit
< pIn
->numSamples
)
235 UINT_32 numSplits
= pIn
->numSamples
/ samplesPerSplit
;
236 UINT_32 fastClearBaseAlign
= HwlGetPipes(&pIn
->tileInfo
) * m_pipeInterleaveBytes
;
238 ADDR_ASSERT(IsPow2(fastClearBaseAlign
));
240 dccFastClearSize
/= numSplits
;
242 if (0 != (dccFastClearSize
& (fastClearBaseAlign
- 1)))
244 // Disable dcc fast clear
245 // if key size of fisrt sample split is not pipe*interleave aligned
246 dccFastClearSize
= 0;
251 pOut
->dccRamSize
= pIn
->colorSurfSize
>> 8;
252 pOut
->dccRamBaseAlign
= pIn
->tileInfo
.banks
*
253 HwlGetPipes(&pIn
->tileInfo
) *
254 m_pipeInterleaveBytes
;
255 pOut
->dccFastClearSize
= dccFastClearSize
;
256 pOut
->dccRamSizeAligned
= TRUE
;
258 ADDR_ASSERT(IsPow2(pOut
->dccRamBaseAlign
));
260 if (0 == (pOut
->dccRamSize
& (pOut
->dccRamBaseAlign
- 1)))
262 pOut
->subLvlCompressible
= TRUE
;
266 UINT_64 dccRamSizeAlign
= HwlGetPipes(&pIn
->tileInfo
) * m_pipeInterleaveBytes
;
268 if (pOut
->dccRamSize
== pOut
->dccFastClearSize
)
270 pOut
->dccFastClearSize
= PowTwoAlign(pOut
->dccRamSize
, dccRamSizeAlign
);
272 if ((pOut
->dccRamSize
& (dccRamSizeAlign
- 1)) != 0)
274 pOut
->dccRamSizeAligned
= FALSE
;
276 pOut
->dccRamSize
= PowTwoAlign(pOut
->dccRamSize
, dccRamSizeAlign
);
277 pOut
->subLvlCompressible
= FALSE
;
282 returnCode
= ADDR_NOTSUPPORTED
;
289 ****************************************************************************************************
290 * CiLib::HwlComputeCmaskAddrFromCoord
293 * Compute tc compatible Cmask address from fmask ram address
297 ****************************************************************************************************
299 ADDR_E_RETURNCODE
CiLib::HwlComputeCmaskAddrFromCoord(
300 const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] fmask addr/bpp/tile input
301 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] cmask address
304 ADDR_E_RETURNCODE returnCode
= ADDR_NOTSUPPORTED
;
306 if ((m_settings
.isVolcanicIslands
== TRUE
) &&
307 (pIn
->flags
.tcCompatible
== TRUE
))
309 UINT_32 numOfPipes
= HwlGetPipes(pIn
->pTileInfo
);
310 UINT_32 numOfBanks
= pIn
->pTileInfo
->banks
;
311 UINT_64 fmaskAddress
= pIn
->fmaskAddr
;
312 UINT_32 elemBits
= pIn
->bpp
;
313 UINT_32 blockByte
= 64 * elemBits
/ 8;
314 UINT_64 metaNibbleAddress
= HwlComputeMetadataNibbleAddress(fmaskAddress
,
320 m_pipeInterleaveBytes
,
324 pOut
->addr
= (metaNibbleAddress
>> 1);
325 pOut
->bitPosition
= (metaNibbleAddress
% 2) ? 4 : 0;
326 returnCode
= ADDR_OK
;
333 ****************************************************************************************************
334 * CiLib::HwlComputeHtileAddrFromCoord
337 * Compute tc compatible Htile address from depth/stencil address
341 ****************************************************************************************************
343 ADDR_E_RETURNCODE
CiLib::HwlComputeHtileAddrFromCoord(
344 const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] depth/stencil addr/bpp/tile input
345 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] htile address
348 ADDR_E_RETURNCODE returnCode
= ADDR_NOTSUPPORTED
;
350 if ((m_settings
.isVolcanicIslands
== TRUE
) &&
351 (pIn
->flags
.tcCompatible
== TRUE
))
353 UINT_32 numOfPipes
= HwlGetPipes(pIn
->pTileInfo
);
354 UINT_32 numOfBanks
= pIn
->pTileInfo
->banks
;
355 UINT_64 zStencilAddr
= pIn
->zStencilAddr
;
356 UINT_32 elemBits
= pIn
->bpp
;
357 UINT_32 blockByte
= 64 * elemBits
/ 8;
358 UINT_64 metaNibbleAddress
= HwlComputeMetadataNibbleAddress(zStencilAddr
,
364 m_pipeInterleaveBytes
,
368 pOut
->addr
= (metaNibbleAddress
>> 1);
369 pOut
->bitPosition
= 0;
370 returnCode
= ADDR_OK
;
377 ****************************************************************************************************
378 * CiLib::HwlConvertChipFamily
381 * Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
384 ****************************************************************************************************
386 ChipFamily
CiLib::HwlConvertChipFamily(
387 UINT_32 uChipFamily
, ///< [in] chip family defined in atiih.h
388 UINT_32 uChipRevision
) ///< [in] chip revision defined in "asic_family"_id.h
390 ChipFamily family
= ADDR_CHIP_FAMILY_CI
;
395 m_settings
.isSeaIsland
= 1;
396 m_settings
.isBonaire
= ASICREV_IS_BONAIRE_M(uChipRevision
);
397 m_settings
.isHawaii
= ASICREV_IS_HAWAII_P(uChipRevision
);
400 m_settings
.isKaveri
= 1;
401 m_settings
.isSpectre
= ASICREV_IS_SPECTRE(uChipRevision
);
402 m_settings
.isSpooky
= ASICREV_IS_SPOOKY(uChipRevision
);
403 m_settings
.isKalindi
= ASICREV_IS_KALINDI(uChipRevision
);
406 m_settings
.isVolcanicIslands
= 1;
407 m_settings
.isIceland
= ASICREV_IS_ICELAND_M(uChipRevision
);
408 m_settings
.isTonga
= ASICREV_IS_TONGA_P(uChipRevision
);
409 m_settings
.isFiji
= ASICREV_IS_FIJI_P(uChipRevision
);
410 m_settings
.isPolaris10
= ASICREV_IS_POLARIS10_P(uChipRevision
);
411 m_settings
.isPolaris11
= ASICREV_IS_POLARIS11_M(uChipRevision
);
412 m_settings
.isPolaris12
= ASICREV_IS_POLARIS12_V(uChipRevision
);
413 family
= ADDR_CHIP_FAMILY_VI
;
416 m_settings
.isCarrizo
= 1;
417 m_settings
.isVolcanicIslands
= 1;
418 family
= ADDR_CHIP_FAMILY_VI
;
421 ADDR_ASSERT(!"This should be a unexpected Fusion");
429 ****************************************************************************************************
430 * CiLib::HwlInitGlobalParams
433 * Initializes global parameters
436 * TRUE if all settings are valid
438 ****************************************************************************************************
440 BOOL_32
CiLib::HwlInitGlobalParams(
441 const ADDR_CREATE_INPUT
* pCreateIn
) ///< [in] create input
443 BOOL_32 valid
= TRUE
;
445 const ADDR_REGISTER_VALUE
* pRegValue
= &pCreateIn
->regValue
;
447 valid
= DecodeGbRegs(pRegValue
);
449 // The following assignments for m_pipes is only for fail-safe, InitTileSettingTable should
450 // read the correct pipes from tile mode table
451 if (m_settings
.isHawaii
)
453 // Hawaii has 16-pipe, see GFXIP_Config_Summary.xls
456 else if (m_settings
.isBonaire
|| m_settings
.isSpectre
)
460 else // Treat other KV asics to be 2-pipe
466 // Move this to VI code path once created
467 if (m_settings
.isTonga
|| m_settings
.isPolaris10
)
471 else if (m_settings
.isIceland
)
475 else if (m_settings
.isFiji
)
479 else if (m_settings
.isPolaris11
|| m_settings
.isPolaris12
)
486 valid
= InitTileSettingTable(pRegValue
->pTileConfig
, pRegValue
->noOfEntries
);
490 valid
= InitMacroTileCfgTable(pRegValue
->pMacroTileConfig
, pRegValue
->noOfMacroEntries
);
502 ****************************************************************************************************
503 * CiLib::HwlPostCheckTileIndex
506 * Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches
507 * tile mode/type/info and change the index if needed
510 ****************************************************************************************************
512 INT_32
CiLib::HwlPostCheckTileIndex(
513 const ADDR_TILEINFO
* pInfo
, ///< [in] Tile Info
514 AddrTileMode mode
, ///< [in] Tile mode
515 AddrTileType type
, ///< [in] Tile type
516 INT curIndex
///< [in] Current index assigned in HwlSetupTileInfo
519 INT_32 index
= curIndex
;
521 if (mode
== ADDR_TM_LINEAR_GENERAL
)
523 index
= TileIndexLinearGeneral
;
527 BOOL_32 macroTiled
= IsMacroTiled(mode
);
529 // We need to find a new index if either of them is true
530 // 1. curIndex is invalid
531 // 2. tile mode is changed
532 // 3. tile info does not match for macro tiled
533 if ((index
== TileIndexInvalid
) ||
534 (mode
!= m_tileTable
[index
].mode
) ||
535 (macroTiled
&& pInfo
->pipeConfig
!= m_tileTable
[index
].info
.pipeConfig
))
537 for (index
= 0; index
< static_cast<INT_32
>(m_noOfEntries
); index
++)
541 // macro tile modes need all to match
542 if ((pInfo
->pipeConfig
== m_tileTable
[index
].info
.pipeConfig
) &&
543 (mode
== m_tileTable
[index
].mode
) &&
544 (type
== m_tileTable
[index
].type
))
546 // tileSplitBytes stored in m_tileTable is only valid for depth entries
547 if (type
== ADDR_DEPTH_SAMPLE_ORDER
)
549 if (Min(m_tileTable
[index
].info
.tileSplitBytes
,
550 m_rowSize
) == pInfo
->tileSplitBytes
)
555 else // other entries are determined by other 3 fields
561 else if (mode
== ADDR_TM_LINEAR_ALIGNED
)
563 // linear mode only needs tile mode to match
564 if (mode
== m_tileTable
[index
].mode
)
571 // micro tile modes only need tile mode and tile type to match
572 if (mode
== m_tileTable
[index
].mode
&&
573 type
== m_tileTable
[index
].type
)
582 ADDR_ASSERT(index
< static_cast<INT_32
>(m_noOfEntries
));
584 if (index
>= static_cast<INT_32
>(m_noOfEntries
))
586 index
= TileIndexInvalid
;
593 ****************************************************************************************************
594 * CiLib::HwlSetupTileCfg
597 * Map tile index to tile setting.
600 ****************************************************************************************************
602 ADDR_E_RETURNCODE
CiLib::HwlSetupTileCfg(
603 UINT_32 bpp
, ///< [in] Bits per pixel
604 INT_32 index
, ///< [in] Tile index
605 INT_32 macroModeIndex
, ///< [in] Index in macro tile mode table(CI)
606 ADDR_TILEINFO
* pInfo
, ///< [out] Tile Info
607 AddrTileMode
* pMode
, ///< [out] Tile mode
608 AddrTileType
* pType
///< [out] Tile type
611 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
613 // Global flag to control usage of tileIndex
614 if (UseTileIndex(index
))
616 if (index
== TileIndexLinearGeneral
)
619 pInfo
->bankWidth
= 1;
620 pInfo
->bankHeight
= 1;
621 pInfo
->macroAspectRatio
= 1;
622 pInfo
->tileSplitBytes
= 64;
623 pInfo
->pipeConfig
= ADDR_PIPECFG_P2
;
625 else if (static_cast<UINT_32
>(index
) >= m_noOfEntries
)
627 returnCode
= ADDR_INVALIDPARAMS
;
631 const TileConfig
* pCfgTable
= GetTileSetting(index
);
635 if (IsMacroTiled(pCfgTable
->mode
))
637 ADDR_ASSERT((macroModeIndex
!= TileIndexInvalid
) &&
638 (macroModeIndex
!= TileIndexNoMacroIndex
));
642 *pInfo
= m_macroTileTable
[macroModeIndex
];
644 if (pCfgTable
->type
== ADDR_DEPTH_SAMPLE_ORDER
)
646 tileSplit
= pCfgTable
->info
.tileSplitBytes
;
652 UINT_32 thickness
= Thickness(pCfgTable
->mode
);
653 UINT_32 tileBytes1x
= BITS_TO_BYTES(bpp
* MicroTilePixels
* thickness
);
654 // Non-depth entries store a split factor
655 UINT_32 sampleSplit
= m_tileTable
[index
].info
.tileSplitBytes
;
656 tileSplit
= Max(256u, sampleSplit
* tileBytes1x
);
660 // Return tileBytes instead if not enough info
661 tileSplit
= pInfo
->tileSplitBytes
;
666 pInfo
->tileSplitBytes
= Min(m_rowSize
, tileSplit
);
668 pInfo
->pipeConfig
= pCfgTable
->info
.pipeConfig
;
670 else // 1D and linear modes, we return default value stored in table
672 *pInfo
= pCfgTable
->info
;
678 *pMode
= pCfgTable
->mode
;
683 *pType
= pCfgTable
->type
;
692 ****************************************************************************************************
693 * CiLib::HwlComputeSurfaceInfo
696 * Entry of CI's ComputeSurfaceInfo
699 ****************************************************************************************************
701 ADDR_E_RETURNCODE
CiLib::HwlComputeSurfaceInfo(
702 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
703 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
706 // If tileIndex is invalid, force macroModeIndex to be invalid, too
707 if (pIn
->tileIndex
== TileIndexInvalid
)
709 pOut
->macroModeIndex
= TileIndexInvalid
;
712 // Pass tcCompatible flag from input to output; and turn off it if tile split occurs
713 pOut
->tcCompatible
= pIn
->flags
.tcCompatible
;
715 ADDR_E_RETURNCODE retCode
= SiLib::HwlComputeSurfaceInfo(pIn
,pOut
);
717 if (pOut
->macroModeIndex
== TileIndexNoMacroIndex
)
719 pOut
->macroModeIndex
= TileIndexInvalid
;
726 ****************************************************************************************************
727 * CiLib::HwlFmaskSurfaceInfo
729 * Entry of r800's ComputeFmaskInfo
732 ****************************************************************************************************
734 ADDR_E_RETURNCODE
CiLib::HwlComputeFmaskInfo(
735 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
736 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
739 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
741 ADDR_TILEINFO tileInfo
= {0};
742 ADDR_COMPUTE_FMASK_INFO_INPUT fmaskIn
;
745 AddrTileMode tileMode
= pIn
->tileMode
;
747 // Use internal tile info if pOut does not have a valid pTileInfo
748 if (pOut
->pTileInfo
== NULL
)
750 pOut
->pTileInfo
= &tileInfo
;
753 ADDR_ASSERT(tileMode
== ADDR_TM_2D_TILED_THIN1
||
754 tileMode
== ADDR_TM_3D_TILED_THIN1
||
755 tileMode
== ADDR_TM_PRT_TILED_THIN1
||
756 tileMode
== ADDR_TM_PRT_2D_TILED_THIN1
||
757 tileMode
== ADDR_TM_PRT_3D_TILED_THIN1
);
759 ADDR_ASSERT(m_tileTable
[14].mode
== ADDR_TM_2D_TILED_THIN1
);
760 ADDR_ASSERT(m_tileTable
[15].mode
== ADDR_TM_3D_TILED_THIN1
);
762 // The only valid tile modes for fmask are 2D_THIN1 and 3D_THIN1 plus non-displayable
763 INT_32 tileIndex
= tileMode
== ADDR_TM_2D_TILED_THIN1
? 14 : 15;
764 ADDR_SURFACE_FLAGS flags
= {{0}};
767 INT_32 macroModeIndex
= TileIndexInvalid
;
769 UINT_32 numSamples
= pIn
->numSamples
;
770 UINT_32 numFrags
= pIn
->numFrags
== 0 ? numSamples
: pIn
->numFrags
;
772 UINT_32 bpp
= QLog2(numFrags
);
774 // EQAA needs one more bit
775 if (numSamples
> numFrags
)
785 bpp
= Max(8u, bpp
* numSamples
);
787 macroModeIndex
= HwlComputeMacroModeIndex(tileIndex
, flags
, bpp
, numSamples
, pOut
->pTileInfo
);
789 fmaskIn
.tileIndex
= tileIndex
;
790 fmaskIn
.pTileInfo
= pOut
->pTileInfo
;
791 pOut
->macroModeIndex
= macroModeIndex
;
792 pOut
->tileIndex
= tileIndex
;
794 retCode
= DispatchComputeFmaskInfo(&fmaskIn
, pOut
);
796 if (retCode
== ADDR_OK
)
799 HwlPostCheckTileIndex(pOut
->pTileInfo
, pIn
->tileMode
, ADDR_NON_DISPLAYABLE
,
803 // Resets pTileInfo to NULL if the internal tile info is used
804 if (pOut
->pTileInfo
== &tileInfo
)
806 pOut
->pTileInfo
= NULL
;
813 ****************************************************************************************************
814 * CiLib::HwlFmaskPreThunkSurfInfo
817 * Some preparation before thunking a ComputeSurfaceInfo call for Fmask
820 ****************************************************************************************************
822 VOID
CiLib::HwlFmaskPreThunkSurfInfo(
823 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pFmaskIn
, ///< [in] Input of fmask info
824 const ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pFmaskOut
, ///< [in] Output of fmask info
825 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pSurfIn
, ///< [out] Input of thunked surface info
826 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pSurfOut
///< [out] Output of thunked surface info
829 pSurfIn
->tileIndex
= pFmaskIn
->tileIndex
;
830 pSurfOut
->macroModeIndex
= pFmaskOut
->macroModeIndex
;
834 ****************************************************************************************************
835 * CiLib::HwlFmaskPostThunkSurfInfo
838 * Copy hwl extra field after calling thunked ComputeSurfaceInfo
841 ****************************************************************************************************
843 VOID
CiLib::HwlFmaskPostThunkSurfInfo(
844 const ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pSurfOut
, ///< [in] Output of surface info
845 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pFmaskOut
///< [out] Output of fmask info
848 pFmaskOut
->tileIndex
= pSurfOut
->tileIndex
;
849 pFmaskOut
->macroModeIndex
= pSurfOut
->macroModeIndex
;
853 ****************************************************************************************************
854 * CiLib::HwlDegradeThickTileMode
857 * Degrades valid tile mode for thick modes if needed
861 ****************************************************************************************************
863 AddrTileMode
CiLib::HwlDegradeThickTileMode(
864 AddrTileMode baseTileMode
, ///< [in] base tile mode
865 UINT_32 numSlices
, ///< [in] current number of slices
866 UINT_32
* pBytesPerTile
///< [in,out] pointer to bytes per slice
873 ****************************************************************************************************
874 * CiLib::HwlOptimizeTileMode
877 * Optimize tile mode on CI
882 ****************************************************************************************************
884 VOID
CiLib::HwlOptimizeTileMode(
885 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
888 AddrTileMode tileMode
= pInOut
->tileMode
;
890 // Override 2D/3D macro tile mode to PRT_* tile mode if
891 // client driver requests this surface is equation compatible
892 if ((pInOut
->flags
.needEquation
== TRUE
) &&
893 (pInOut
->numSamples
<= 1) &&
894 (IsMacroTiled(tileMode
) == TRUE
) &&
895 (IsPrtTileMode(tileMode
) == FALSE
))
897 UINT_32 thickness
= Thickness(tileMode
);
899 if (pInOut
->maxBaseAlign
< Block64K
)
901 tileMode
= (thickness
== 1) ? ADDR_TM_1D_TILED_THIN1
: ADDR_TM_1D_TILED_THICK
;
903 else if (thickness
== 1)
905 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
909 static const UINT_32 PrtTileBytes
= 0x10000;
910 // First prt thick tile index in the tile mode table
911 static const UINT_32 PrtThickTileIndex
= 22;
912 ADDR_TILEINFO tileInfo
= {0};
914 HwlComputeMacroModeIndex(PrtThickTileIndex
,
920 UINT_32 macroTileBytes
= ((pInOut
->bpp
) >> 3) * 64 * pInOut
->numSamples
*
921 thickness
* HwlGetPipes(&tileInfo
) *
922 tileInfo
.banks
* tileInfo
.bankWidth
*
925 if (macroTileBytes
<= PrtTileBytes
)
927 tileMode
= ADDR_TM_PRT_TILED_THICK
;
931 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
936 if (tileMode
!= pInOut
->tileMode
)
938 pInOut
->tileMode
= tileMode
;
943 ****************************************************************************************************
944 * CiLib::HwlOverrideTileMode
947 * Override THICK to THIN, for specific formats on CI
952 ****************************************************************************************************
954 VOID
CiLib::HwlOverrideTileMode(
955 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
958 AddrTileMode tileMode
= pInOut
->tileMode
;
959 AddrTileType tileType
= pInOut
->tileType
;
961 // currently, all CI/VI family do not
962 // support ADDR_TM_PRT_2D_TILED_THICK,ADDR_TM_PRT_3D_TILED_THICK and
963 // ADDR_TM_PRT_2D_TILED_THIN1, ADDR_TM_PRT_3D_TILED_THIN1
966 case ADDR_TM_PRT_2D_TILED_THICK
:
967 case ADDR_TM_PRT_3D_TILED_THICK
:
968 tileMode
= ADDR_TM_PRT_TILED_THICK
;
970 case ADDR_TM_PRT_2D_TILED_THIN1
:
971 case ADDR_TM_PRT_3D_TILED_THIN1
:
972 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
978 // UBTS#404321, we do not need such overriding, as THICK+THICK entries removed from the tile-mode table
979 if (!m_settings
.isBonaire
)
981 UINT_32 thickness
= Thickness(tileMode
);
983 // tile_thickness = (array_mode == XTHICK) ? 8 : ((array_mode == THICK) ? 4 : 1)
986 switch (pInOut
->format
)
988 // see //gfxip/gcB/devel/cds/src/verif/tc/models/csim/tcp.cpp
989 // tcpError("Thick micro tiling is not supported for format...
990 case ADDR_FMT_X24_8_32_FLOAT
:
991 case ADDR_FMT_32_AS_8
:
992 case ADDR_FMT_32_AS_8_8
:
993 case ADDR_FMT_32_AS_32_32_32_32
:
998 case ADDR_FMT_1_REVERSED
:
1009 case ADDR_TM_1D_TILED_THICK
:
1010 tileMode
= ADDR_TM_1D_TILED_THIN1
;
1013 case ADDR_TM_2D_TILED_XTHICK
:
1014 case ADDR_TM_2D_TILED_THICK
:
1015 tileMode
= ADDR_TM_2D_TILED_THIN1
;
1018 case ADDR_TM_3D_TILED_XTHICK
:
1019 case ADDR_TM_3D_TILED_THICK
:
1020 tileMode
= ADDR_TM_3D_TILED_THIN1
;
1023 case ADDR_TM_PRT_TILED_THICK
:
1024 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
1027 case ADDR_TM_PRT_2D_TILED_THICK
:
1028 tileMode
= ADDR_TM_PRT_2D_TILED_THIN1
;
1031 case ADDR_TM_PRT_3D_TILED_THICK
:
1032 tileMode
= ADDR_TM_PRT_3D_TILED_THIN1
;
1040 // Switch tile type from thick to thin
1041 if (tileMode
!= pInOut
->tileMode
)
1043 // see tileIndex: 13-18
1044 tileType
= ADDR_NON_DISPLAYABLE
;
1054 if (tileMode
!= pInOut
->tileMode
)
1056 pInOut
->tileMode
= tileMode
;
1057 pInOut
->tileType
= tileType
;
1062 ****************************************************************************************************
1063 * CiLib::HwlSelectTileMode
1066 * Select tile modes.
1071 ****************************************************************************************************
1073 VOID
CiLib::HwlSelectTileMode(
1074 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
1077 AddrTileMode tileMode
;
1078 AddrTileType tileType
;
1080 if (pInOut
->flags
.rotateDisplay
)
1082 tileMode
= ADDR_TM_2D_TILED_THIN1
;
1083 tileType
= ADDR_ROTATED
;
1085 else if (pInOut
->flags
.volume
)
1087 BOOL_32 bThin
= (m_settings
.isBonaire
== TRUE
) ||
1088 ((m_allowNonDispThickModes
== TRUE
) && (pInOut
->flags
.color
== TRUE
));
1090 if (pInOut
->numSlices
>= 8)
1092 tileMode
= ADDR_TM_2D_TILED_XTHICK
;
1093 tileType
= (bThin
== TRUE
) ? ADDR_NON_DISPLAYABLE
: ADDR_THICK
;
1095 else if (pInOut
->numSlices
>= 4)
1097 tileMode
= ADDR_TM_2D_TILED_THICK
;
1098 tileType
= (bThin
== TRUE
) ? ADDR_NON_DISPLAYABLE
: ADDR_THICK
;
1102 tileMode
= ADDR_TM_2D_TILED_THIN1
;
1103 tileType
= ADDR_NON_DISPLAYABLE
;
1108 tileMode
= ADDR_TM_2D_TILED_THIN1
;
1110 if (pInOut
->flags
.depth
|| pInOut
->flags
.stencil
)
1112 tileType
= ADDR_DEPTH_SAMPLE_ORDER
;
1114 else if ((pInOut
->bpp
<= 32) ||
1115 (pInOut
->flags
.display
== TRUE
) ||
1116 (pInOut
->flags
.overlay
== TRUE
))
1118 tileType
= ADDR_DISPLAYABLE
;
1122 tileType
= ADDR_NON_DISPLAYABLE
;
1126 if (pInOut
->flags
.prt
)
1128 if (Thickness(tileMode
) > 1)
1130 tileMode
= ADDR_TM_PRT_TILED_THICK
;
1131 tileType
= (m_settings
.isBonaire
== TRUE
) ? ADDR_NON_DISPLAYABLE
: ADDR_THICK
;
1135 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
1139 pInOut
->tileMode
= tileMode
;
1140 pInOut
->tileType
= tileType
;
1142 if ((pInOut
->flags
.dccCompatible
== FALSE
) &&
1143 (pInOut
->flags
.tcCompatible
== FALSE
))
1145 pInOut
->flags
.opt4Space
= TRUE
;
1146 pInOut
->maxBaseAlign
= Block64K
;
1148 // Optimize tile mode if possible
1149 OptimizeTileMode(pInOut
);
1152 HwlOverrideTileMode(pInOut
);
1156 ****************************************************************************************************
1157 * CiLib::HwlSetPrtTileMode
1160 * Set PRT tile mode.
1165 ****************************************************************************************************
1167 VOID
CiLib::HwlSetPrtTileMode(
1168 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
1171 AddrTileMode tileMode
= pInOut
->tileMode
;
1172 AddrTileType tileType
= pInOut
->tileType
;
1174 if (Thickness(tileMode
) > 1)
1176 tileMode
= ADDR_TM_PRT_TILED_THICK
;
1177 tileType
= (m_settings
.isBonaire
== TRUE
) ? ADDR_NON_DISPLAYABLE
: ADDR_THICK
;
1181 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
1182 tileType
= (tileType
== ADDR_THICK
) ? ADDR_NON_DISPLAYABLE
: tileType
;
1185 pInOut
->tileMode
= tileMode
;
1186 pInOut
->tileType
= tileType
;
1190 ****************************************************************************************************
1191 * CiLib::HwlSetupTileInfo
1194 * Setup default value of tile info for SI
1195 ****************************************************************************************************
1197 VOID
CiLib::HwlSetupTileInfo(
1198 AddrTileMode tileMode
, ///< [in] Tile mode
1199 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface type flags
1200 UINT_32 bpp
, ///< [in] Bits per pixel
1201 UINT_32 pitch
, ///< [in] Pitch in pixels
1202 UINT_32 height
, ///< [in] Height in pixels
1203 UINT_32 numSamples
, ///< [in] Number of samples
1204 ADDR_TILEINFO
* pTileInfoIn
, ///< [in] Tile info input: NULL for default
1205 ADDR_TILEINFO
* pTileInfoOut
, ///< [out] Tile info output
1206 AddrTileType inTileType
, ///< [in] Tile type
1207 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] Output
1210 UINT_32 thickness
= Thickness(tileMode
);
1211 ADDR_TILEINFO
* pTileInfo
= pTileInfoOut
;
1212 INT index
= TileIndexInvalid
;
1213 INT macroModeIndex
= TileIndexInvalid
;
1216 if (!IsLinear(tileMode
))
1218 // Thick tile modes must use thick micro tile mode but Bonaire does not support due to
1219 // old derived netlists (UBTS 404321)
1222 if (m_settings
.isBonaire
)
1224 inTileType
= ADDR_NON_DISPLAYABLE
;
1226 else if ((m_allowNonDispThickModes
== FALSE
) ||
1227 (inTileType
!= ADDR_NON_DISPLAYABLE
) ||
1228 // There is no PRT_THICK + THIN entry in tile mode table except Bonaire
1229 (IsPrtTileMode(tileMode
) == TRUE
))
1231 inTileType
= ADDR_THICK
;
1234 // 128 bpp tiling must be non-displayable.
1235 // Fmask reuse color buffer's entry but bank-height field can be from another entry
1236 // To simplify the logic, fmask entry should be picked from non-displayable ones
1237 else if (bpp
== 128 || flags
.fmask
)
1239 inTileType
= ADDR_NON_DISPLAYABLE
;
1241 // These two modes only have non-disp entries though they can be other micro tile modes
1242 else if (tileMode
== ADDR_TM_3D_TILED_THIN1
|| tileMode
== ADDR_TM_PRT_3D_TILED_THIN1
)
1244 inTileType
= ADDR_NON_DISPLAYABLE
;
1247 if (flags
.depth
|| flags
.stencil
)
1249 inTileType
= ADDR_DEPTH_SAMPLE_ORDER
;
1253 if (IsTileInfoAllZero(pTileInfo
))
1255 // See table entries 0-4
1256 if (flags
.depth
|| flags
.stencil
)
1258 // tileSize = thickness * bpp * numSamples * 8 * 8 / 8
1259 UINT_32 tileSize
= thickness
* bpp
* numSamples
* 8;
1261 // Turn off tc compatible if row_size is smaller than tile size (tile split occurs).
1262 if (m_rowSize
< tileSize
)
1264 flags
.tcCompatible
= FALSE
;
1265 pOut
->tcCompatible
= FALSE
;
1268 if (flags
.depth
&& (flags
.nonSplit
|| flags
.tcCompatible
|| flags
.needEquation
))
1270 // Texture readable depth surface should not be split
1289 // Depth and stencil need to use the same index, thus the pre-defined tile_split
1290 // can meet the requirement to choose the same macro mode index
1291 // uncompressed depth/stencil are not supported for now
1310 // See table entries 5-6
1311 if (inTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
1315 case ADDR_TM_1D_TILED_THIN1
:
1318 case ADDR_TM_PRT_TILED_THIN1
:
1326 // See table entries 8-12
1327 if (inTileType
== ADDR_DISPLAYABLE
)
1331 case ADDR_TM_1D_TILED_THIN1
:
1334 case ADDR_TM_2D_TILED_THIN1
:
1337 case ADDR_TM_PRT_TILED_THIN1
:
1345 // See table entries 13-18
1346 if (inTileType
== ADDR_NON_DISPLAYABLE
)
1350 case ADDR_TM_1D_TILED_THIN1
:
1353 case ADDR_TM_2D_TILED_THIN1
:
1356 case ADDR_TM_3D_TILED_THIN1
:
1359 case ADDR_TM_PRT_TILED_THIN1
:
1367 // See table entries 19-26
1372 case ADDR_TM_1D_TILED_THICK
:
1373 // special check for bonaire, for the compatablity between old KMD and new UMD
1374 index
= ((inTileType
== ADDR_THICK
) || m_settings
.isBonaire
) ? 19 : 18;
1376 case ADDR_TM_2D_TILED_THICK
:
1377 // special check for bonaire, for the compatablity between old KMD and new UMD
1378 index
= ((inTileType
== ADDR_THICK
) || m_settings
.isBonaire
) ? 20 : 24;
1380 case ADDR_TM_3D_TILED_THICK
:
1383 case ADDR_TM_PRT_TILED_THICK
:
1386 case ADDR_TM_2D_TILED_XTHICK
:
1389 case ADDR_TM_3D_TILED_XTHICK
:
1397 // See table entries 27-30
1398 if (inTileType
== ADDR_ROTATED
)
1402 case ADDR_TM_1D_TILED_THIN1
:
1405 case ADDR_TM_2D_TILED_THIN1
:
1408 case ADDR_TM_PRT_TILED_THIN1
:
1411 case ADDR_TM_PRT_2D_TILED_THIN1
:
1421 ADDR_ASSERT((index
+ 1) < static_cast<INT_32
>(m_noOfEntries
));
1422 // Only do this when tile mode table is updated.
1423 if (((tileMode
== ADDR_TM_PRT_TILED_THIN1
) || (tileMode
== ADDR_TM_PRT_TILED_THICK
)) &&
1424 (m_tileTable
[index
+ 1].mode
== tileMode
))
1426 static const UINT_32 PrtTileBytes
= 0x10000;
1427 ADDR_TILEINFO tileInfo
= {0};
1429 HwlComputeMacroModeIndex(index
, flags
, bpp
, numSamples
, &tileInfo
);
1431 UINT_32 macroTileBytes
= (bpp
>> 3) * 64 * numSamples
* thickness
*
1432 HwlGetPipes(&tileInfo
) * tileInfo
.banks
*
1433 tileInfo
.bankWidth
* tileInfo
.bankHeight
;
1435 if (macroTileBytes
!= PrtTileBytes
)
1437 // Switching to next tile mode entry to make sure macro tile size is 64KB
1440 tileInfo
.pipeConfig
= m_tileTable
[index
].info
.pipeConfig
;
1442 macroTileBytes
= (bpp
>> 3) * 64 * numSamples
* thickness
*
1443 HwlGetPipes(&tileInfo
) * tileInfo
.banks
*
1444 tileInfo
.bankWidth
* tileInfo
.bankHeight
;
1446 ADDR_ASSERT(macroTileBytes
== PrtTileBytes
);
1448 pOut
->tcCompatible
= FALSE
;
1449 pOut
->dccUnsupport
= TRUE
;
1456 // A pre-filled tile info is ready
1457 index
= pOut
->tileIndex
;
1458 macroModeIndex
= pOut
->macroModeIndex
;
1460 // pass tile type back for post tile index compute
1461 pOut
->tileType
= inTileType
;
1463 if (flags
.depth
|| flags
.stencil
)
1465 // tileSize = thickness * bpp * numSamples * 8 * 8 / 8
1466 UINT_32 tileSize
= thickness
* bpp
* numSamples
* 8;
1468 // Turn off tc compatible if row_size is smaller than tile size (tile split occurs).
1469 if (m_rowSize
< tileSize
)
1471 flags
.tcCompatible
= FALSE
;
1472 pOut
->tcCompatible
= FALSE
;
1476 UINT_32 numPipes
= GetPipePerSurf(pTileInfo
->pipeConfig
);
1478 if (m_pipes
!= numPipes
)
1480 pOut
->dccUnsupport
= TRUE
;
1484 // We only need to set up tile info if there is a valid index but macroModeIndex is invalid
1485 if ((index
!= TileIndexInvalid
) && (macroModeIndex
== TileIndexInvalid
))
1487 macroModeIndex
= HwlComputeMacroModeIndex(index
, flags
, bpp
, numSamples
, pTileInfo
);
1489 // Copy to pOut->tileType/tileIndex/macroModeIndex
1490 pOut
->tileIndex
= index
;
1491 pOut
->tileType
= m_tileTable
[index
].type
; // Or inTileType, the samea
1492 pOut
->macroModeIndex
= macroModeIndex
;
1494 else if (tileMode
== ADDR_TM_LINEAR_GENERAL
)
1496 pOut
->tileIndex
= TileIndexLinearGeneral
;
1498 // Copy linear-aligned entry??
1499 *pTileInfo
= m_tileTable
[8].info
;
1501 else if (tileMode
== ADDR_TM_LINEAR_ALIGNED
)
1503 pOut
->tileIndex
= 8;
1504 *pTileInfo
= m_tileTable
[8].info
;
1507 if (pOut
->tcCompatible
)
1509 if (IsMacroTiled(tileMode
))
1511 if (inTileType
!= ADDR_DEPTH_SAMPLE_ORDER
)
1513 // Turn off tcCompatible for color surface if tileSplit happens. Depth/stencil
1514 // tileSplit case was handled at tileIndex selecting time.
1515 INT_32 tileIndex
= pOut
->tileIndex
;
1517 if ((tileIndex
== TileIndexInvalid
) && (IsTileInfoAllZero(pTileInfo
) == FALSE
))
1519 tileIndex
= HwlPostCheckTileIndex(pTileInfo
, tileMode
, inTileType
, tileIndex
);
1522 if (tileIndex
!= TileIndexInvalid
)
1524 ADDR_ASSERT(static_cast<UINT_32
>(tileIndex
) < TileTableSize
);
1525 // Non-depth entries store a split factor
1526 UINT_32 sampleSplit
= m_tileTable
[tileIndex
].info
.tileSplitBytes
;
1527 UINT_32 tileBytes1x
= BITS_TO_BYTES(bpp
* MicroTilePixels
* thickness
);
1528 UINT_32 colorTileSplit
= Max(256u, sampleSplit
* tileBytes1x
);
1530 if (m_rowSize
< colorTileSplit
)
1532 pOut
->tcCompatible
= FALSE
;
1539 // Client should not enable tc compatible for linear and 1D tile modes.
1540 pOut
->tcCompatible
= FALSE
;
1546 ****************************************************************************************************
1547 * CiLib::ReadGbTileMode
1550 * Convert GB_TILE_MODE HW value to ADDR_TILE_CONFIG.
1551 ****************************************************************************************************
1553 VOID
CiLib::ReadGbTileMode(
1554 UINT_32 regValue
, ///< [in] GB_TILE_MODE register
1555 TileConfig
* pCfg
///< [out] output structure
1558 GB_TILE_MODE gbTileMode
;
1559 gbTileMode
.val
= regValue
;
1561 pCfg
->type
= static_cast<AddrTileType
>(gbTileMode
.f
.micro_tile_mode_new
);
1562 pCfg
->info
.pipeConfig
= static_cast<AddrPipeCfg
>(gbTileMode
.f
.pipe_config
+ 1);
1564 if (pCfg
->type
== ADDR_DEPTH_SAMPLE_ORDER
)
1566 pCfg
->info
.tileSplitBytes
= 64 << gbTileMode
.f
.tile_split
;
1570 pCfg
->info
.tileSplitBytes
= 1 << gbTileMode
.f
.sample_split
;
1573 UINT_32 regArrayMode
= gbTileMode
.f
.array_mode
;
1575 pCfg
->mode
= static_cast<AddrTileMode
>(regArrayMode
);
1577 switch (regArrayMode
)
1580 pCfg
->mode
= ADDR_TM_PRT_TILED_THIN1
;
1583 pCfg
->mode
= ADDR_TM_PRT_2D_TILED_THIN1
;
1586 pCfg
->mode
= ADDR_TM_2D_TILED_XTHICK
;
1589 pCfg
->mode
= ADDR_TM_PRT_TILED_THICK
;
1592 pCfg
->mode
= ADDR_TM_PRT_2D_TILED_THICK
;
1595 pCfg
->mode
= ADDR_TM_PRT_3D_TILED_THIN1
;
1598 pCfg
->mode
= ADDR_TM_3D_TILED_XTHICK
;
1601 pCfg
->mode
= ADDR_TM_PRT_3D_TILED_THICK
;
1607 // Fail-safe code for these always convert tile info, as the non-macro modes
1608 // return the entry of tile mode table directly without looking up macro mode table
1609 if (!IsMacroTiled(pCfg
->mode
))
1611 pCfg
->info
.banks
= 2;
1612 pCfg
->info
.bankWidth
= 1;
1613 pCfg
->info
.bankHeight
= 1;
1614 pCfg
->info
.macroAspectRatio
= 1;
1615 pCfg
->info
.tileSplitBytes
= 64;
1620 ****************************************************************************************************
1621 * CiLib::InitTileSettingTable
1624 * Initialize the ADDR_TILE_CONFIG table.
1626 * TRUE if tile table is correctly initialized
1627 ****************************************************************************************************
1629 BOOL_32
CiLib::InitTileSettingTable(
1630 const UINT_32
* pCfg
, ///< [in] Pointer to table of tile configs
1631 UINT_32 noOfEntries
///< [in] Numbe of entries in the table above
1634 BOOL_32 initOk
= TRUE
;
1636 ADDR_ASSERT(noOfEntries
<= TileTableSize
);
1638 memset(m_tileTable
, 0, sizeof(m_tileTable
));
1640 if (noOfEntries
!= 0)
1642 m_noOfEntries
= noOfEntries
;
1646 m_noOfEntries
= TileTableSize
;
1649 if (pCfg
) // From Client
1651 for (UINT_32 i
= 0; i
< m_noOfEntries
; i
++)
1653 ReadGbTileMode(*(pCfg
+ i
), &m_tileTable
[i
]);
1658 ADDR_ASSERT_ALWAYS();
1664 ADDR_ASSERT(m_tileTable
[TILEINDEX_LINEAR_ALIGNED
].mode
== ADDR_TM_LINEAR_ALIGNED
);
1666 if (m_settings
.isBonaire
== FALSE
)
1668 // Check if entry 18 is "thick+thin" combination
1669 if ((m_tileTable
[18].mode
== ADDR_TM_1D_TILED_THICK
) &&
1670 (m_tileTable
[18].type
== ADDR_NON_DISPLAYABLE
))
1672 m_allowNonDispThickModes
= TRUE
;
1673 ADDR_ASSERT(m_tileTable
[24].mode
== ADDR_TM_2D_TILED_THICK
);
1678 m_allowNonDispThickModes
= TRUE
;
1681 // Assume the first entry is always programmed with full pipes
1682 m_pipes
= HwlGetPipes(&m_tileTable
[0].info
);
1689 ****************************************************************************************************
1690 * CiLib::ReadGbMacroTileCfg
1693 * Convert GB_MACRO_TILE_CFG HW value to ADDR_TILE_CONFIG.
1694 ****************************************************************************************************
1696 VOID
CiLib::ReadGbMacroTileCfg(
1697 UINT_32 regValue
, ///< [in] GB_MACRO_TILE_MODE register
1698 ADDR_TILEINFO
* pCfg
///< [out] output structure
1701 GB_MACROTILE_MODE gbTileMode
;
1702 gbTileMode
.val
= regValue
;
1704 pCfg
->bankHeight
= 1 << gbTileMode
.f
.bank_height
;
1705 pCfg
->bankWidth
= 1 << gbTileMode
.f
.bank_width
;
1706 pCfg
->banks
= 1 << (gbTileMode
.f
.num_banks
+ 1);
1707 pCfg
->macroAspectRatio
= 1 << gbTileMode
.f
.macro_tile_aspect
;
1711 ****************************************************************************************************
1712 * CiLib::InitMacroTileCfgTable
1715 * Initialize the ADDR_MACRO_TILE_CONFIG table.
1717 * TRUE if macro tile table is correctly initialized
1718 ****************************************************************************************************
1720 BOOL_32
CiLib::InitMacroTileCfgTable(
1721 const UINT_32
* pCfg
, ///< [in] Pointer to table of tile configs
1722 UINT_32 noOfMacroEntries
///< [in] Numbe of entries in the table above
1725 BOOL_32 initOk
= TRUE
;
1727 ADDR_ASSERT(noOfMacroEntries
<= MacroTileTableSize
);
1729 memset(m_macroTileTable
, 0, sizeof(m_macroTileTable
));
1731 if (noOfMacroEntries
!= 0)
1733 m_noOfMacroEntries
= noOfMacroEntries
;
1737 m_noOfMacroEntries
= MacroTileTableSize
;
1740 if (pCfg
) // From Client
1742 for (UINT_32 i
= 0; i
< m_noOfMacroEntries
; i
++)
1744 ReadGbMacroTileCfg(*(pCfg
+ i
), &m_macroTileTable
[i
]);
1746 m_macroTileTable
[i
].tileSplitBytes
= 64 << (i
% 8);
1751 ADDR_ASSERT_ALWAYS();
1758 ****************************************************************************************************
1759 * CiLib::HwlComputeMacroModeIndex
1762 * Computes macro tile mode index
1764 * TRUE if macro tile table is correctly initialized
1765 ****************************************************************************************************
1767 INT_32
CiLib::HwlComputeMacroModeIndex(
1768 INT_32 tileIndex
, ///< [in] Tile mode index
1769 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface flags
1770 UINT_32 bpp
, ///< [in] Bit per pixel
1771 UINT_32 numSamples
, ///< [in] Number of samples
1772 ADDR_TILEINFO
* pTileInfo
, ///< [out] Pointer to ADDR_TILEINFO
1773 AddrTileMode
* pTileMode
, ///< [out] Pointer to AddrTileMode
1774 AddrTileType
* pTileType
///< [out] Pointer to AddrTileType
1777 INT_32 macroModeIndex
= TileIndexInvalid
;
1779 AddrTileMode tileMode
= m_tileTable
[tileIndex
].mode
;
1780 AddrTileType tileType
= m_tileTable
[tileIndex
].type
;
1781 UINT_32 thickness
= Thickness(tileMode
);
1783 if (!IsMacroTiled(tileMode
))
1785 *pTileInfo
= m_tileTable
[tileIndex
].info
;
1786 macroModeIndex
= TileIndexNoMacroIndex
;
1790 UINT_32 tileBytes1x
= BITS_TO_BYTES(bpp
* MicroTilePixels
* thickness
);
1793 if (m_tileTable
[tileIndex
].type
== ADDR_DEPTH_SAMPLE_ORDER
)
1795 // Depth entries store real tileSplitBytes
1796 tileSplit
= m_tileTable
[tileIndex
].info
.tileSplitBytes
;
1800 // Non-depth entries store a split factor
1801 UINT_32 sampleSplit
= m_tileTable
[tileIndex
].info
.tileSplitBytes
;
1802 UINT_32 colorTileSplit
= Max(256u, sampleSplit
* tileBytes1x
);
1804 tileSplit
= colorTileSplit
;
1807 UINT_32 tileSplitC
= Min(m_rowSize
, tileSplit
);
1812 tileBytes
= Min(tileSplitC
, tileBytes1x
);
1816 tileBytes
= Min(tileSplitC
, numSamples
* tileBytes1x
);
1824 macroModeIndex
= Log2(tileBytes
/ 64);
1826 if (flags
.prt
|| IsPrtTileMode(tileMode
))
1828 // Unknown - assume it is 1/2 of table size
1829 const UINT_32 PrtMacroModeOffset
= MacroTileTableSize
/ 2;
1831 macroModeIndex
+= PrtMacroModeOffset
;
1832 *pTileInfo
= m_macroTileTable
[macroModeIndex
];
1836 *pTileInfo
= m_macroTileTable
[macroModeIndex
];
1839 pTileInfo
->pipeConfig
= m_tileTable
[tileIndex
].info
.pipeConfig
;
1841 pTileInfo
->tileSplitBytes
= tileSplitC
;
1844 if (NULL
!= pTileMode
)
1846 *pTileMode
= tileMode
;
1849 if (NULL
!= pTileType
)
1851 *pTileType
= tileType
;
1854 return macroModeIndex
;
1858 ****************************************************************************************************
1859 * CiLib::HwlComputeTileDataWidthAndHeightLinear
1862 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1865 * MacroWidth and macroHeight are measured in pixels
1866 ****************************************************************************************************
1868 VOID
CiLib::HwlComputeTileDataWidthAndHeightLinear(
1869 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1870 UINT_32
* pMacroHeight
, ///< [out] macro tile height
1871 UINT_32 bpp
, ///< [in] bits per pixel
1872 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
1875 ADDR_ASSERT(pTileInfo
!= NULL
);
1879 switch (pTileInfo
->pipeConfig
)
1881 case ADDR_PIPECFG_P16_32x32_8x16
:
1882 case ADDR_PIPECFG_P16_32x32_16x16
:
1883 case ADDR_PIPECFG_P8_32x64_32x32
:
1884 case ADDR_PIPECFG_P8_32x32_16x32
:
1885 case ADDR_PIPECFG_P8_32x32_16x16
:
1886 case ADDR_PIPECFG_P8_32x32_8x16
:
1887 case ADDR_PIPECFG_P4_32x32
:
1895 *pMacroWidth
= numTiles
* MicroTileWidth
;
1896 *pMacroHeight
= numTiles
* MicroTileHeight
;
1900 ****************************************************************************************************
1901 * CiLib::HwlComputeMetadataNibbleAddress
1904 * calculate meta data address based on input information
1907 * uncompressedDataByteAddress - address of a pixel in color surface
1908 * dataBaseByteAddress - base address of color surface
1909 * metadataBaseByteAddress - base address of meta ram
1910 * metadataBitSize - meta key size, 8 for DCC, 4 for cmask
1911 * elementBitSize - element size of color surface
1912 * blockByteSize - compression block size, 256 for DCC
1913 * pipeInterleaveBytes - pipe interleave size
1914 * numOfPipes - number of pipes
1915 * numOfBanks - number of banks
1916 * numOfSamplesPerSplit - number of samples per tile split
1918 * meta data nibble address (nibble address is used to support DCC compatible cmask)
1920 ****************************************************************************************************
1922 UINT_64
CiLib::HwlComputeMetadataNibbleAddress(
1923 UINT_64 uncompressedDataByteAddress
,
1924 UINT_64 dataBaseByteAddress
,
1925 UINT_64 metadataBaseByteAddress
,
1926 UINT_32 metadataBitSize
,
1927 UINT_32 elementBitSize
,
1928 UINT_32 blockByteSize
,
1929 UINT_32 pipeInterleaveBytes
,
1932 UINT_32 numOfSamplesPerSplit
) const
1934 ///--------------------------------------------------------------------------------------------
1935 /// Get pipe interleave, bank and pipe bits
1936 ///--------------------------------------------------------------------------------------------
1937 UINT_32 pipeInterleaveBits
= Log2(pipeInterleaveBytes
);
1938 UINT_32 pipeBits
= Log2(numOfPipes
);
1939 UINT_32 bankBits
= Log2(numOfBanks
);
1941 ///--------------------------------------------------------------------------------------------
1942 /// Clear pipe and bank swizzles
1943 ///--------------------------------------------------------------------------------------------
1944 UINT_32 dataMacrotileBits
= pipeInterleaveBits
+ pipeBits
+ bankBits
;
1945 UINT_32 metadataMacrotileBits
= pipeInterleaveBits
+ pipeBits
+ bankBits
;
1947 UINT_64 dataMacrotileClearMask
= ~((1L << dataMacrotileBits
) - 1);
1948 UINT_64 metadataMacrotileClearMask
= ~((1L << metadataMacrotileBits
) - 1);
1950 UINT_64 dataBaseByteAddressNoSwizzle
= dataBaseByteAddress
& dataMacrotileClearMask
;
1951 UINT_64 metadataBaseByteAddressNoSwizzle
= metadataBaseByteAddress
& metadataMacrotileClearMask
;
1953 ///--------------------------------------------------------------------------------------------
1954 /// Modify metadata base before adding in so that when final address is divided by data ratio,
1955 /// the base address returns to where it should be
1956 ///--------------------------------------------------------------------------------------------
1957 ADDR_ASSERT((0 != metadataBitSize
));
1958 UINT_64 metadataBaseShifted
= metadataBaseByteAddressNoSwizzle
* blockByteSize
* 8 /
1960 UINT_64 offset
= uncompressedDataByteAddress
-
1961 dataBaseByteAddressNoSwizzle
+
1962 metadataBaseShifted
;
1964 ///--------------------------------------------------------------------------------------------
1965 /// Save bank data bits
1966 ///--------------------------------------------------------------------------------------------
1967 UINT_32 lsb
= pipeBits
+ pipeInterleaveBits
;
1968 UINT_32 msb
= bankBits
- 1 + lsb
;
1970 UINT_64 bankDataBits
= GetBits(offset
, msb
, lsb
);
1972 ///--------------------------------------------------------------------------------------------
1973 /// Save pipe data bits
1974 ///--------------------------------------------------------------------------------------------
1975 lsb
= pipeInterleaveBits
;
1976 msb
= pipeBits
- 1 + lsb
;
1978 UINT_64 pipeDataBits
= GetBits(offset
, msb
, lsb
);
1980 ///--------------------------------------------------------------------------------------------
1981 /// Remove pipe and bank bits
1982 ///--------------------------------------------------------------------------------------------
1983 lsb
= pipeInterleaveBits
;
1984 msb
= dataMacrotileBits
- 1;
1986 UINT_64 offsetWithoutPipeBankBits
= RemoveBits(offset
, msb
, lsb
);
1988 ADDR_ASSERT((0 != blockByteSize
));
1989 UINT_64 blockInBankpipe
= offsetWithoutPipeBankBits
/ blockByteSize
;
1991 UINT_32 tileSize
= 8 * 8 * elementBitSize
/8 * numOfSamplesPerSplit
;
1992 UINT_32 blocksInTile
= tileSize
/ blockByteSize
;
1994 if (0 == blocksInTile
)
2000 lsb
= Log2(blocksInTile
);
2002 msb
= bankBits
- 1 + lsb
;
2004 UINT_64 blockInBankpipeWithBankBits
= InsertBits(blockInBankpipe
, bankDataBits
, msb
, lsb
);
2006 /// NOTE *2 because we are converting to Nibble address in this step
2007 UINT_64 metaAddressInPipe
= blockInBankpipeWithBankBits
* 2 * metadataBitSize
/ 8;
2010 ///--------------------------------------------------------------------------------------------
2011 /// Reinsert pipe bits back into the final address
2012 ///--------------------------------------------------------------------------------------------
2013 lsb
= pipeInterleaveBits
+ 1; ///<+1 due to Nibble address now gives interleave bits extra lsb.
2014 msb
= pipeBits
- 1 + lsb
;
2015 UINT_64 metadataAddress
= InsertBits(metaAddressInPipe
, pipeDataBits
, msb
, lsb
);
2017 return metadataAddress
;
2021 ****************************************************************************************************
2022 * CiLib::HwlComputeSurfaceAlignmentsMacroTiled
2025 * Hardware layer function to compute alignment request for macro tile mode
2027 ****************************************************************************************************
2029 VOID
CiLib::HwlComputeSurfaceAlignmentsMacroTiled(
2030 AddrTileMode tileMode
, ///< [in] tile mode
2031 UINT_32 bpp
, ///< [in] bits per pixel
2032 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
2033 UINT_32 mipLevel
, ///< [in] mip level
2034 UINT_32 numSamples
, ///< [in] number of samples
2035 ADDR_TILEINFO
* pTileInfo
, ///< [in,out] bank structure.
2036 UINT_32
* pBaseAlign
, ///< [out] base address alignment in bytes
2037 UINT_32
* pPitchAlign
, ///< [out] pitch alignment in pixels
2038 UINT_32
* pHeightAlign
, ///< [out] height alignment in pixels
2039 UINT_32
* pMacroTileWidth
, ///< [out] macro tile width in pixels
2040 UINT_32
* pMacroTileHeight
///< [out] macro tile height in pixels
2043 if ((m_settings
.isFiji
== TRUE
) &&
2044 (flags
.dccCompatible
== TRUE
) &&
2046 (tileMode
== ADDR_TM_PRT_TILED_THIN1
))
2048 *pPitchAlign
= PowTwoAlign(*pPitchAlign
, 256);
2053 ****************************************************************************************************
2054 * CiLib::HwlPadDimensions
2057 * Helper function to pad dimensions
2059 ****************************************************************************************************
2061 VOID
CiLib::HwlPadDimensions(
2062 AddrTileMode tileMode
, ///< [in] tile mode
2063 UINT_32 bpp
, ///< [in] bits per pixel
2064 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
2065 UINT_32 numSamples
, ///< [in] number of samples
2066 ADDR_TILEINFO
* pTileInfo
, ///< [in] tile info
2067 UINT_32 mipLevel
, ///< [in] mip level
2068 UINT_32
* pPitch
, ///< [in,out] pitch in pixels
2069 UINT_32
* pPitchAlign
, ///< [in,out] pitch alignment
2070 UINT_32 height
, ///< [in] height in pixels
2071 UINT_32 heightAlign
///< [in] height alignment
2074 if ((m_settings
.isVolcanicIslands
== TRUE
) &&
2075 (flags
.dccCompatible
== TRUE
) &&
2078 (IsMacroTiled(tileMode
) == TRUE
))
2080 UINT_32 tileSizePerSample
= BITS_TO_BYTES(bpp
* MicroTileWidth
* MicroTileHeight
);
2081 UINT_32 samplesPerSplit
= pTileInfo
->tileSplitBytes
/ tileSizePerSample
;
2083 if (samplesPerSplit
< numSamples
)
2085 UINT_32 dccFastClearByteAlign
= HwlGetPipes(pTileInfo
) * m_pipeInterleaveBytes
* 256;
2086 UINT_32 bytesPerSplit
= BITS_TO_BYTES((*pPitch
) * height
* bpp
* samplesPerSplit
);
2088 ADDR_ASSERT(IsPow2(dccFastClearByteAlign
));
2090 if (0 != (bytesPerSplit
& (dccFastClearByteAlign
- 1)))
2092 UINT_32 dccFastClearPixelAlign
= dccFastClearByteAlign
/
2093 BITS_TO_BYTES(bpp
) /
2095 UINT_32 macroTilePixelAlign
= (*pPitchAlign
) * heightAlign
;
2097 if ((dccFastClearPixelAlign
>= macroTilePixelAlign
) &&
2098 ((dccFastClearPixelAlign
% macroTilePixelAlign
) == 0))
2100 UINT_32 dccFastClearPitchAlignInMacroTile
=
2101 dccFastClearPixelAlign
/ macroTilePixelAlign
;
2102 UINT_32 heightInMacroTile
= height
/ heightAlign
;
2104 while ((heightInMacroTile
> 1) &&
2105 ((heightInMacroTile
% 2) == 0) &&
2106 (dccFastClearPitchAlignInMacroTile
> 1) &&
2107 ((dccFastClearPitchAlignInMacroTile
% 2) == 0))
2109 heightInMacroTile
>>= 1;
2110 dccFastClearPitchAlignInMacroTile
>>= 1;
2113 UINT_32 dccFastClearPitchAlignInPixels
=
2114 (*pPitchAlign
) * dccFastClearPitchAlignInMacroTile
;
2116 if (IsPow2(dccFastClearPitchAlignInPixels
))
2118 *pPitch
= PowTwoAlign((*pPitch
), dccFastClearPitchAlignInPixels
);
2122 *pPitch
+= (dccFastClearPitchAlignInPixels
- 1);
2123 *pPitch
/= dccFastClearPitchAlignInPixels
;
2124 *pPitch
*= dccFastClearPitchAlignInPixels
;
2127 *pPitchAlign
= dccFastClearPitchAlignInPixels
;
2135 ****************************************************************************************************
2136 * CiLib::HwlGetMaxAlignments
2139 * Gets maximum alignments
2142 ****************************************************************************************************
2144 ADDR_E_RETURNCODE
CiLib::HwlGetMaxAlignments(
2145 ADDR_GET_MAX_ALINGMENTS_OUTPUT
* pOut
///< [out] output structure
2148 const UINT_32 pipes
= HwlGetPipes(&m_tileTable
[0].info
);
2150 // Initial size is 64 KiB for PRT.
2151 UINT_64 maxBaseAlign
= 64 * 1024;
2153 for (UINT_32 i
= 0; i
< m_noOfMacroEntries
; i
++)
2155 // The maximum tile size is 16 byte-per-pixel and either 8-sample or 8-slice.
2156 UINT_32 tileSize
= m_macroTileTable
[i
].tileSplitBytes
;
2158 UINT_64 baseAlign
= tileSize
* pipes
* m_macroTileTable
[i
].banks
*
2159 m_macroTileTable
[i
].bankWidth
* m_macroTileTable
[i
].bankHeight
;
2161 if (baseAlign
> maxBaseAlign
)
2163 maxBaseAlign
= baseAlign
;
2169 pOut
->baseAlign
= maxBaseAlign
;