2 * Copyright © 2007-2018 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 Addr::V1::Lib base class.
31 ****************************************************************************************************
34 #include "addrinterface.h"
36 #include "addrcommon.h"
43 ////////////////////////////////////////////////////////////////////////////////////////////////////
44 // Static Const Member
45 ////////////////////////////////////////////////////////////////////////////////////////////////////
47 const TileModeFlags
Lib::ModeFlags
[ADDR_TM_COUNT
] =
49 {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_GENERAL
50 {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_ALIGNED
51 {1, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THIN1
52 {4, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THICK
53 {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN1
54 {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN2
55 {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN4
56 {4, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THICK
57 {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN1
58 {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN2
59 {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN4
60 {4, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THICK
61 {1, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THIN1
62 {4, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THICK
63 {1, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THIN1
64 {4, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THICK
65 {8, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_XTHICK
66 {8, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_XTHICK
67 {1, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_POWER_SAVE
68 {1, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THIN1
69 {1, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THIN1
70 {1, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THIN1
71 {4, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THICK
72 {4, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THICK
73 {4, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THICK
74 {0, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_UNKNOWN
77 ////////////////////////////////////////////////////////////////////////////////////////////////////
78 // Constructor/Destructor
79 ////////////////////////////////////////////////////////////////////////////////////////////////////
82 ****************************************************************************************************
86 * Constructor for the AddrLib1 class
88 ****************************************************************************************************
97 ****************************************************************************************************
101 * Constructor for the Addr::V1::Lib class with hClient as parameter
103 ****************************************************************************************************
105 Lib::Lib(const Client
* pClient
)
112 ****************************************************************************************************
116 * Destructor for the AddrLib1 class
118 ****************************************************************************************************
125 ****************************************************************************************************
129 * Get AddrLib1 pointer
132 * An Addr::V1::Lib class pointer
133 ****************************************************************************************************
136 ADDR_HANDLE hLib
) ///< [in] handle of ADDR_HANDLE
138 Addr::Lib
* pAddrLib
= Addr::Lib::GetLib(hLib
);
139 if ((pAddrLib
!= NULL
) &&
140 ((pAddrLib
->GetChipFamily() == ADDR_CHIP_FAMILY_IVLD
) ||
141 (pAddrLib
->GetChipFamily() > ADDR_CHIP_FAMILY_VI
)))
143 // only valid and pre-VI ASIC can use AddrLib1 function.
144 ADDR_ASSERT_ALWAYS();
147 return static_cast<Lib
*>(hLib
);
150 ////////////////////////////////////////////////////////////////////////////////////////////////////
152 ////////////////////////////////////////////////////////////////////////////////////////////////////
155 ****************************************************************************************************
156 * Lib::ComputeSurfaceInfo
159 * Interface function stub of AddrComputeSurfaceInfo.
163 ****************************************************************************************************
165 ADDR_E_RETURNCODE
Lib::ComputeSurfaceInfo(
166 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
167 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
170 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
172 if (GetFillSizeFieldsFlags() == TRUE
)
174 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT
)) ||
175 (pOut
->size
!= sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT
)))
177 returnCode
= ADDR_PARAMSIZEMISMATCH
;
181 // We suggest client do sanity check but a check here is also good
184 returnCode
= ADDR_INVALIDPARAMS
;
187 if ((pIn
->tileMode
== ADDR_TM_UNKNOWN
) && (pIn
->mipLevel
> 0))
189 returnCode
= ADDR_INVALIDPARAMS
;
192 // Thick modes don't support multisample
193 if ((Thickness(pIn
->tileMode
) > 1) && (pIn
->numSamples
> 1))
195 returnCode
= ADDR_INVALIDPARAMS
;
198 if (returnCode
== ADDR_OK
)
200 // Get a local copy of input structure and only reference pIn for unadjusted values
201 ADDR_COMPUTE_SURFACE_INFO_INPUT localIn
= *pIn
;
202 ADDR_TILEINFO tileInfoNull
= {0};
206 // If the original input has a valid ADDR_TILEINFO pointer then copy its contents.
207 // Otherwise the default 0's in tileInfoNull are used.
210 tileInfoNull
= *pIn
->pTileInfo
;
212 localIn
.pTileInfo
= &tileInfoNull
;
215 localIn
.numSamples
= (pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
;
217 // Do mipmap check first
218 // If format is BCn, pre-pad dimension to power-of-two according to HWL
219 ComputeMipLevel(&localIn
);
221 if (m_configFlags
.checkLast2DLevel
)
223 // Save this level's original height in pixels
224 pOut
->height
= pIn
->height
;
231 // Save outputs that may not go through HWL
232 pOut
->pixelBits
= localIn
.bpp
;
233 pOut
->numSamples
= localIn
.numSamples
;
234 pOut
->last2DLevel
= FALSE
;
235 pOut
->tcCompatible
= FALSE
;
238 if (localIn
.numSamples
> 1)
240 ADDR_ASSERT(localIn
.mipLevel
== 0);
244 if (localIn
.format
!= ADDR_FMT_INVALID
) // Set format to INVALID will skip this conversion
246 // Get compression/expansion factors and element mode
247 // (which indicates compression/expansion
248 localIn
.bpp
= GetElemLib()->GetBitsPerPixel(localIn
.format
,
253 // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
254 // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
255 // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
256 // restrictions are different.
257 // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
258 // but we use this flag to skip RestoreSurfaceInfo below
260 if ((elemMode
== ADDR_EXPANDED
) && (expandX
> 1))
262 ADDR_ASSERT(IsLinear(localIn
.tileMode
));
265 GetElemLib()->AdjustSurfaceInfo(elemMode
,
273 // Overwrite these parameters if we have a valid format
275 else if (localIn
.bpp
!= 0)
277 localIn
.width
= (localIn
.width
!= 0) ? localIn
.width
: 1;
278 localIn
.height
= (localIn
.height
!= 0) ? localIn
.height
: 1;
280 else // Rule out some invalid parameters
282 ADDR_ASSERT_ALWAYS();
284 returnCode
= ADDR_INVALIDPARAMS
;
287 // Check mipmap after surface expansion
288 if (returnCode
== ADDR_OK
)
290 returnCode
= PostComputeMipLevel(&localIn
, pOut
);
293 if (returnCode
== ADDR_OK
)
295 if (UseTileIndex(localIn
.tileIndex
))
297 // Make sure pTileInfo is not NULL
298 ADDR_ASSERT(localIn
.pTileInfo
);
300 UINT_32 numSamples
= GetNumFragments(localIn
.numSamples
, localIn
.numFrags
);
302 INT_32 macroModeIndex
= TileIndexNoMacroIndex
;
304 if (localIn
.tileIndex
!= TileIndexLinearGeneral
)
306 // Try finding a macroModeIndex
307 macroModeIndex
= HwlComputeMacroModeIndex(localIn
.tileIndex
,
316 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
317 if (macroModeIndex
== TileIndexNoMacroIndex
)
319 returnCode
= HwlSetupTileCfg(localIn
.bpp
,
320 localIn
.tileIndex
, macroModeIndex
,
322 &localIn
.tileMode
, &localIn
.tileType
);
324 // If macroModeIndex is invalid, then assert this is not macro tiled
325 else if (macroModeIndex
== TileIndexInvalid
)
327 ADDR_ASSERT(!IsMacroTiled(localIn
.tileMode
));
330 pOut
->macroModeIndex
= macroModeIndex
;
334 if (returnCode
== ADDR_OK
)
336 localIn
.flags
.dccPipeWorkaround
= localIn
.flags
.dccCompatible
;
338 if (localIn
.tileMode
== ADDR_TM_UNKNOWN
)
340 // HWL layer may override tile mode if necessary
341 HwlSelectTileMode(&localIn
);
345 // HWL layer may override tile mode if necessary
346 HwlOverrideTileMode(&localIn
);
348 // Optimize tile mode if possible
349 OptimizeTileMode(&localIn
);
353 // Call main function to compute surface info
354 if (returnCode
== ADDR_OK
)
356 returnCode
= HwlComputeSurfaceInfo(&localIn
, pOut
);
359 if (returnCode
== ADDR_OK
)
361 // Since bpp might be changed we just pass it through
362 pOut
->bpp
= localIn
.bpp
;
364 // Also original width/height/bpp
365 pOut
->pixelPitch
= pOut
->pitch
;
366 pOut
->pixelHeight
= pOut
->height
;
369 if (localIn
.flags
.display
)
371 ADDR_ASSERT((pOut
->pitchAlign
% 32) == 0);
375 if (localIn
.format
!= ADDR_FMT_INVALID
)
378 // Note: For 96 bit surface, the pixelPitch returned might be an odd number, but it
379 // is okay to program texture pitch as HW's mip calculator would multiply 3 first,
380 // then do the appropriate paddings (linear alignment requirement and possible the
381 // nearest power-of-two for mipmaps), which results in the original pitch.
383 GetElemLib()->RestoreSurfaceInfo(elemMode
,
391 if (localIn
.flags
.qbStereo
)
393 if (pOut
->pStereoInfo
)
395 ComputeQbStereoInfo(pOut
);
399 if (localIn
.flags
.volume
) // For volume sliceSize equals to all z-slices
401 pOut
->sliceSize
= pOut
->surfSize
;
403 else // For array: sliceSize is likely to have slice-padding (the last one)
405 pOut
->sliceSize
= pOut
->surfSize
/ pOut
->depth
;
408 if (pIn
->numSlices
> 1)
410 // If this is the last slice then add the padding size to this slice
411 if (pIn
->slice
== (pIn
->numSlices
- 1))
413 pOut
->sliceSize
+= pOut
->sliceSize
* (pOut
->depth
- pIn
->numSlices
);
415 else if (m_configFlags
.checkLast2DLevel
)
417 // Reset last2DLevel flag if this is not the last array slice
418 pOut
->last2DLevel
= FALSE
;
423 pOut
->pitchTileMax
= pOut
->pitch
/ 8 - 1;
424 pOut
->heightTileMax
= pOut
->height
/ 8 - 1;
425 pOut
->sliceTileMax
= pOut
->pitch
* pOut
->height
/ 64 - 1;
429 ValidBaseAlignments(pOut
->baseAlign
);
435 ****************************************************************************************************
436 * Lib::ComputeSurfaceInfo
439 * Interface function stub of AddrComputeSurfaceInfo.
443 ****************************************************************************************************
445 ADDR_E_RETURNCODE
Lib::ComputeSurfaceAddrFromCoord(
446 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
447 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
450 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
452 if (GetFillSizeFieldsFlags() == TRUE
)
454 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
)) ||
455 (pOut
->size
!= sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
)))
457 returnCode
= ADDR_PARAMSIZEMISMATCH
;
461 if (returnCode
== ADDR_OK
)
463 ADDR_TILEINFO tileInfoNull
;
464 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT input
;
466 if (UseTileIndex(pIn
->tileIndex
))
469 // Use temp tile info for calcalation
470 input
.pTileInfo
= &tileInfoNull
;
472 const ADDR_SURFACE_FLAGS flags
= {{0}};
473 UINT_32 numSamples
= GetNumFragments(pIn
->numSamples
, pIn
->numFrags
);
475 // Try finding a macroModeIndex
476 INT_32 macroModeIndex
= HwlComputeMacroModeIndex(input
.tileIndex
,
484 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
485 if (macroModeIndex
== TileIndexNoMacroIndex
)
487 returnCode
= HwlSetupTileCfg(input
.bpp
, input
.tileIndex
, macroModeIndex
,
488 input
.pTileInfo
, &input
.tileMode
, &input
.tileType
);
490 // If macroModeIndex is invalid, then assert this is not macro tiled
491 else if (macroModeIndex
== TileIndexInvalid
)
493 ADDR_ASSERT(!IsMacroTiled(input
.tileMode
));
496 // Change the input structure
500 if (returnCode
== ADDR_OK
)
502 returnCode
= HwlComputeSurfaceAddrFromCoord(pIn
, pOut
);
504 if (returnCode
== ADDR_OK
)
506 pOut
->prtBlockIndex
= static_cast<UINT_32
>(pOut
->addr
/ (64 * 1024));
515 ****************************************************************************************************
516 * Lib::ComputeSurfaceCoordFromAddr
519 * Interface function stub of ComputeSurfaceCoordFromAddr.
523 ****************************************************************************************************
525 ADDR_E_RETURNCODE
Lib::ComputeSurfaceCoordFromAddr(
526 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
527 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
530 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
532 if (GetFillSizeFieldsFlags() == TRUE
)
534 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
)) ||
535 (pOut
->size
!= sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
)))
537 returnCode
= ADDR_PARAMSIZEMISMATCH
;
541 if (returnCode
== ADDR_OK
)
543 ADDR_TILEINFO tileInfoNull
;
544 ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT input
;
546 if (UseTileIndex(pIn
->tileIndex
))
549 // Use temp tile info for calcalation
550 input
.pTileInfo
= &tileInfoNull
;
552 const ADDR_SURFACE_FLAGS flags
= {{0}};
553 UINT_32 numSamples
= GetNumFragments(pIn
->numSamples
, pIn
->numFrags
);
555 // Try finding a macroModeIndex
556 INT_32 macroModeIndex
= HwlComputeMacroModeIndex(input
.tileIndex
,
564 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
565 if (macroModeIndex
== TileIndexNoMacroIndex
)
567 returnCode
= HwlSetupTileCfg(input
.bpp
, input
.tileIndex
, macroModeIndex
,
568 input
.pTileInfo
, &input
.tileMode
, &input
.tileType
);
570 // If macroModeIndex is invalid, then assert this is not macro tiled
571 else if (macroModeIndex
== TileIndexInvalid
)
573 ADDR_ASSERT(!IsMacroTiled(input
.tileMode
));
576 // Change the input structure
580 if (returnCode
== ADDR_OK
)
582 returnCode
= HwlComputeSurfaceCoordFromAddr(pIn
, pOut
);
590 ****************************************************************************************************
591 * Lib::ComputeSliceTileSwizzle
594 * Interface function stub of ComputeSliceTileSwizzle.
598 ****************************************************************************************************
600 ADDR_E_RETURNCODE
Lib::ComputeSliceTileSwizzle(
601 const ADDR_COMPUTE_SLICESWIZZLE_INPUT
* pIn
, ///< [in] input structure
602 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
* pOut
///< [out] output structure
605 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
607 if (GetFillSizeFieldsFlags() == TRUE
)
609 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SLICESWIZZLE_INPUT
)) ||
610 (pOut
->size
!= sizeof(ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
)))
612 returnCode
= ADDR_PARAMSIZEMISMATCH
;
616 if (returnCode
== ADDR_OK
)
618 ADDR_TILEINFO tileInfoNull
;
619 ADDR_COMPUTE_SLICESWIZZLE_INPUT input
;
621 if (UseTileIndex(pIn
->tileIndex
))
624 // Use temp tile info for calcalation
625 input
.pTileInfo
= &tileInfoNull
;
627 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
,
628 input
.pTileInfo
, &input
.tileMode
);
629 // Change the input structure
633 if (returnCode
== ADDR_OK
)
635 returnCode
= HwlComputeSliceTileSwizzle(pIn
, pOut
);
643 ****************************************************************************************************
644 * Lib::ExtractBankPipeSwizzle
647 * Interface function stub of AddrExtractBankPipeSwizzle.
651 ****************************************************************************************************
653 ADDR_E_RETURNCODE
Lib::ExtractBankPipeSwizzle(
654 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
655 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
658 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
660 if (GetFillSizeFieldsFlags() == TRUE
)
662 if ((pIn
->size
!= sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
)) ||
663 (pOut
->size
!= sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
)))
665 returnCode
= ADDR_PARAMSIZEMISMATCH
;
669 if (returnCode
== ADDR_OK
)
671 ADDR_TILEINFO tileInfoNull
;
672 ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT input
;
674 if (UseTileIndex(pIn
->tileIndex
))
677 // Use temp tile info for calcalation
678 input
.pTileInfo
= &tileInfoNull
;
680 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
681 // Change the input structure
685 if (returnCode
== ADDR_OK
)
687 returnCode
= HwlExtractBankPipeSwizzle(pIn
, pOut
);
695 ****************************************************************************************************
696 * Lib::CombineBankPipeSwizzle
699 * Interface function stub of AddrCombineBankPipeSwizzle.
703 ****************************************************************************************************
705 ADDR_E_RETURNCODE
Lib::CombineBankPipeSwizzle(
706 const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
707 ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
710 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
712 if (GetFillSizeFieldsFlags() == TRUE
)
714 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT
)) ||
715 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT
)))
717 returnCode
= ADDR_PARAMSIZEMISMATCH
;
721 if (returnCode
== ADDR_OK
)
723 ADDR_TILEINFO tileInfoNull
;
724 ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT input
;
726 if (UseTileIndex(pIn
->tileIndex
))
729 // Use temp tile info for calcalation
730 input
.pTileInfo
= &tileInfoNull
;
732 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
733 // Change the input structure
737 if (returnCode
== ADDR_OK
)
739 returnCode
= HwlCombineBankPipeSwizzle(pIn
->bankSwizzle
,
751 ****************************************************************************************************
752 * Lib::ComputeBaseSwizzle
755 * Interface function stub of AddrCompueBaseSwizzle.
758 ****************************************************************************************************
760 ADDR_E_RETURNCODE
Lib::ComputeBaseSwizzle(
761 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT
* pIn
,
762 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
* pOut
) const
764 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
766 if (GetFillSizeFieldsFlags() == TRUE
)
768 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT
)) ||
769 (pOut
->size
!= sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
)))
771 returnCode
= ADDR_PARAMSIZEMISMATCH
;
775 if (returnCode
== ADDR_OK
)
777 ADDR_TILEINFO tileInfoNull
;
778 ADDR_COMPUTE_BASE_SWIZZLE_INPUT input
;
780 if (UseTileIndex(pIn
->tileIndex
))
783 // Use temp tile info for calcalation
784 input
.pTileInfo
= &tileInfoNull
;
786 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
787 // Change the input structure
791 if (returnCode
== ADDR_OK
)
793 if (IsMacroTiled(pIn
->tileMode
))
795 returnCode
= HwlComputeBaseSwizzle(pIn
, pOut
);
799 pOut
->tileSwizzle
= 0;
808 ****************************************************************************************************
809 * Lib::ComputeFmaskInfo
812 * Interface function stub of ComputeFmaskInfo.
816 ****************************************************************************************************
818 ADDR_E_RETURNCODE
Lib::ComputeFmaskInfo(
819 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
820 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
823 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
825 if (GetFillSizeFieldsFlags() == TRUE
)
827 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT
)) ||
828 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT
)))
830 returnCode
= ADDR_PARAMSIZEMISMATCH
;
835 if (Thickness(pIn
->tileMode
) > 1)
837 returnCode
= ADDR_INVALIDPARAMS
;
840 if (returnCode
== ADDR_OK
)
842 ADDR_TILEINFO tileInfoNull
;
843 ADDR_COMPUTE_FMASK_INFO_INPUT input
;
845 if (UseTileIndex(pIn
->tileIndex
))
851 // Use temp tile info for calcalation
852 input
.pTileInfo
= pOut
->pTileInfo
;
856 input
.pTileInfo
= &tileInfoNull
;
859 ADDR_SURFACE_FLAGS flags
= {{0}};
862 // Try finding a macroModeIndex
863 INT_32 macroModeIndex
= HwlComputeMacroModeIndex(pIn
->tileIndex
,
865 HwlComputeFmaskBits(pIn
, NULL
),
870 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
871 if (macroModeIndex
== TileIndexNoMacroIndex
)
873 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, macroModeIndex
,
874 input
.pTileInfo
, &input
.tileMode
);
877 ADDR_ASSERT(macroModeIndex
!= TileIndexInvalid
);
879 // Change the input structure
883 if (returnCode
== ADDR_OK
)
885 if (pIn
->numSamples
> 1)
887 returnCode
= HwlComputeFmaskInfo(pIn
, pOut
);
891 memset(pOut
, 0, sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT
));
893 returnCode
= ADDR_INVALIDPARAMS
;
898 ValidBaseAlignments(pOut
->baseAlign
);
904 ****************************************************************************************************
905 * Lib::ComputeFmaskAddrFromCoord
908 * Interface function stub of ComputeFmaskAddrFromCoord.
912 ****************************************************************************************************
914 ADDR_E_RETURNCODE
Lib::ComputeFmaskAddrFromCoord(
915 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
916 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
919 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
921 if (GetFillSizeFieldsFlags() == TRUE
)
923 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
)) ||
924 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
)))
926 returnCode
= ADDR_PARAMSIZEMISMATCH
;
930 if (returnCode
== ADDR_OK
)
932 ADDR_ASSERT(pIn
->numSamples
> 1);
934 if (pIn
->numSamples
> 1)
936 returnCode
= HwlComputeFmaskAddrFromCoord(pIn
, pOut
);
940 returnCode
= ADDR_INVALIDPARAMS
;
948 ****************************************************************************************************
949 * Lib::ComputeFmaskCoordFromAddr
952 * Interface function stub of ComputeFmaskAddrFromCoord.
956 ****************************************************************************************************
958 ADDR_E_RETURNCODE
Lib::ComputeFmaskCoordFromAddr(
959 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
960 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
963 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
965 if (GetFillSizeFieldsFlags() == TRUE
)
967 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
)) ||
968 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
)))
970 returnCode
= ADDR_PARAMSIZEMISMATCH
;
974 if (returnCode
== ADDR_OK
)
976 ADDR_ASSERT(pIn
->numSamples
> 1);
978 if (pIn
->numSamples
> 1)
980 returnCode
= HwlComputeFmaskCoordFromAddr(pIn
, pOut
);
984 returnCode
= ADDR_INVALIDPARAMS
;
992 ****************************************************************************************************
993 * Lib::ConvertTileInfoToHW
996 * Convert tile info from real value to HW register value in HW layer
1000 ****************************************************************************************************
1002 ADDR_E_RETURNCODE
Lib::ConvertTileInfoToHW(
1003 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
1004 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
1007 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1009 if (GetFillSizeFieldsFlags() == TRUE
)
1011 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT
)) ||
1012 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT
)))
1014 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1018 if (returnCode
== ADDR_OK
)
1020 ADDR_TILEINFO tileInfoNull
;
1021 ADDR_CONVERT_TILEINFOTOHW_INPUT input
;
1022 // if pIn->reverse is TRUE, indices are ignored
1023 if (pIn
->reverse
== FALSE
&& UseTileIndex(pIn
->tileIndex
))
1026 input
.pTileInfo
= &tileInfoNull
;
1028 returnCode
= HwlSetupTileCfg(input
.bpp
, input
.tileIndex
,
1029 input
.macroModeIndex
, input
.pTileInfo
);
1034 if (returnCode
== ADDR_OK
)
1036 returnCode
= HwlConvertTileInfoToHW(pIn
, pOut
);
1044 ****************************************************************************************************
1045 * Lib::ConvertTileIndex
1048 * Convert tile index to tile mode/type/info
1052 ****************************************************************************************************
1054 ADDR_E_RETURNCODE
Lib::ConvertTileIndex(
1055 const ADDR_CONVERT_TILEINDEX_INPUT
* pIn
, ///< [in] input structure
1056 ADDR_CONVERT_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1059 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1061 if (GetFillSizeFieldsFlags() == TRUE
)
1063 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_INPUT
)) ||
1064 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT
)))
1066 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1070 if (returnCode
== ADDR_OK
)
1073 returnCode
= HwlSetupTileCfg(pIn
->bpp
, pIn
->tileIndex
, pIn
->macroModeIndex
,
1074 pOut
->pTileInfo
, &pOut
->tileMode
, &pOut
->tileType
);
1076 if (returnCode
== ADDR_OK
&& pIn
->tileInfoHw
)
1078 ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput
= {0};
1079 ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput
= {0};
1081 hwInput
.pTileInfo
= pOut
->pTileInfo
;
1082 hwInput
.tileIndex
= -1;
1083 hwOutput
.pTileInfo
= pOut
->pTileInfo
;
1085 returnCode
= HwlConvertTileInfoToHW(&hwInput
, &hwOutput
);
1093 ****************************************************************************************************
1094 * Lib::GetMacroModeIndex
1097 * Get macro mode index based on input info
1101 ****************************************************************************************************
1103 ADDR_E_RETURNCODE
Lib::GetMacroModeIndex(
1104 const ADDR_GET_MACROMODEINDEX_INPUT
* pIn
, ///< [in] input structure
1105 ADDR_GET_MACROMODEINDEX_OUTPUT
* pOut
///< [out] output structure
1108 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1110 if (GetFillSizeFieldsFlags())
1112 if ((pIn
->size
!= sizeof(ADDR_GET_MACROMODEINDEX_INPUT
)) ||
1113 (pOut
->size
!= sizeof(ADDR_GET_MACROMODEINDEX_OUTPUT
)))
1115 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1119 if (returnCode
== ADDR_OK
)
1121 ADDR_TILEINFO tileInfo
= {0};
1122 pOut
->macroModeIndex
= HwlComputeMacroModeIndex(pIn
->tileIndex
, pIn
->flags
, pIn
->bpp
,
1123 pIn
->numFrags
, &tileInfo
);
1130 ****************************************************************************************************
1131 * Lib::ConvertTileIndex1
1134 * Convert tile index to tile mode/type/info
1138 ****************************************************************************************************
1140 ADDR_E_RETURNCODE
Lib::ConvertTileIndex1(
1141 const ADDR_CONVERT_TILEINDEX1_INPUT
* pIn
, ///< [in] input structure
1142 ADDR_CONVERT_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1145 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1147 if (GetFillSizeFieldsFlags() == TRUE
)
1149 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINDEX1_INPUT
)) ||
1150 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT
)))
1152 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1156 if (returnCode
== ADDR_OK
)
1158 ADDR_SURFACE_FLAGS flags
= {{0}};
1160 HwlComputeMacroModeIndex(pIn
->tileIndex
, flags
, pIn
->bpp
, pIn
->numSamples
,
1161 pOut
->pTileInfo
, &pOut
->tileMode
, &pOut
->tileType
);
1163 if (pIn
->tileInfoHw
)
1165 ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput
= {0};
1166 ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput
= {0};
1168 hwInput
.pTileInfo
= pOut
->pTileInfo
;
1169 hwInput
.tileIndex
= -1;
1170 hwOutput
.pTileInfo
= pOut
->pTileInfo
;
1172 returnCode
= HwlConvertTileInfoToHW(&hwInput
, &hwOutput
);
1180 ****************************************************************************************************
1184 * Get tile index from tile mode/type/info
1188 ****************************************************************************************************
1190 ADDR_E_RETURNCODE
Lib::GetTileIndex(
1191 const ADDR_GET_TILEINDEX_INPUT
* pIn
, ///< [in] input structure
1192 ADDR_GET_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1195 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1197 if (GetFillSizeFieldsFlags() == TRUE
)
1199 if ((pIn
->size
!= sizeof(ADDR_GET_TILEINDEX_INPUT
)) ||
1200 (pOut
->size
!= sizeof(ADDR_GET_TILEINDEX_OUTPUT
)))
1202 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1206 if (returnCode
== ADDR_OK
)
1208 returnCode
= HwlGetTileIndex(pIn
, pOut
);
1215 ****************************************************************************************************
1219 * Get tile mode thickness
1222 * Tile mode thickness
1223 ****************************************************************************************************
1225 UINT_32
Lib::Thickness(
1226 AddrTileMode tileMode
) ///< [in] tile mode
1228 return ModeFlags
[tileMode
].thickness
;
1231 ////////////////////////////////////////////////////////////////////////////////////////////////////
1233 ////////////////////////////////////////////////////////////////////////////////////////////////////
1236 ****************************************************************************************************
1237 * Lib::ComputeHtileInfo
1240 * Interface function stub of AddrComputeHtilenfo
1244 ****************************************************************************************************
1246 ADDR_E_RETURNCODE
Lib::ComputeHtileInfo(
1247 const ADDR_COMPUTE_HTILE_INFO_INPUT
* pIn
, ///< [in] input structure
1248 ADDR_COMPUTE_HTILE_INFO_OUTPUT
* pOut
///< [out] output structure
1251 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1253 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1254 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1256 if (GetFillSizeFieldsFlags() == TRUE
)
1258 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT
)) ||
1259 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT
)))
1261 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1265 if (returnCode
== ADDR_OK
)
1267 ADDR_TILEINFO tileInfoNull
;
1268 ADDR_COMPUTE_HTILE_INFO_INPUT input
;
1270 if (UseTileIndex(pIn
->tileIndex
))
1273 // Use temp tile info for calcalation
1274 input
.pTileInfo
= &tileInfoNull
;
1276 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1278 // Change the input structure
1282 if (returnCode
== ADDR_OK
)
1284 if (pIn
->flags
.tcCompatible
)
1286 const UINT_32 sliceSize
= pIn
->pitch
* pIn
->height
* 4 / (8 * 8);
1287 const UINT_32 align
= HwlGetPipes(pIn
->pTileInfo
) * pIn
->pTileInfo
->banks
* m_pipeInterleaveBytes
;
1289 if (pIn
->numSlices
> 1)
1291 const UINT_32 surfBytes
= (sliceSize
* pIn
->numSlices
);
1293 pOut
->sliceSize
= sliceSize
;
1294 pOut
->htileBytes
= pIn
->flags
.skipTcCompatSizeAlign
?
1295 surfBytes
: PowTwoAlign(surfBytes
, align
);
1296 pOut
->sliceInterleaved
= ((sliceSize
% align
) != 0) ? TRUE
: FALSE
;
1300 pOut
->sliceSize
= pIn
->flags
.skipTcCompatSizeAlign
?
1301 sliceSize
: PowTwoAlign(sliceSize
, align
);
1302 pOut
->htileBytes
= pOut
->sliceSize
;
1303 pOut
->sliceInterleaved
= FALSE
;
1306 pOut
->nextMipLevelCompressible
= ((sliceSize
% align
) == 0) ? TRUE
: FALSE
;
1308 pOut
->pitch
= pIn
->pitch
;
1309 pOut
->height
= pIn
->height
;
1310 pOut
->baseAlign
= align
;
1311 pOut
->macroWidth
= 0;
1312 pOut
->macroHeight
= 0;
1317 pOut
->bpp
= ComputeHtileInfo(pIn
->flags
,
1336 ValidMetaBaseAlignments(pOut
->baseAlign
);
1342 ****************************************************************************************************
1343 * Lib::ComputeCmaskInfo
1346 * Interface function stub of AddrComputeCmaskInfo
1350 ****************************************************************************************************
1352 ADDR_E_RETURNCODE
Lib::ComputeCmaskInfo(
1353 const ADDR_COMPUTE_CMASK_INFO_INPUT
* pIn
, ///< [in] input structure
1354 ADDR_COMPUTE_CMASK_INFO_OUTPUT
* pOut
///< [out] output structure
1357 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1359 if (GetFillSizeFieldsFlags() == TRUE
)
1361 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_INFO_INPUT
)) ||
1362 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_INFO_OUTPUT
)))
1364 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1368 if (returnCode
== ADDR_OK
)
1370 ADDR_TILEINFO tileInfoNull
;
1371 ADDR_COMPUTE_CMASK_INFO_INPUT input
;
1373 if (UseTileIndex(pIn
->tileIndex
))
1376 // Use temp tile info for calcalation
1377 input
.pTileInfo
= &tileInfoNull
;
1379 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1381 // Change the input structure
1385 if (returnCode
== ADDR_OK
)
1387 returnCode
= ComputeCmaskInfo(pIn
->flags
,
1404 ValidMetaBaseAlignments(pOut
->baseAlign
);
1410 ****************************************************************************************************
1411 * Lib::ComputeDccInfo
1414 * Interface function to compute DCC key info
1417 * return code of HwlComputeDccInfo
1418 ****************************************************************************************************
1420 ADDR_E_RETURNCODE
Lib::ComputeDccInfo(
1421 const ADDR_COMPUTE_DCCINFO_INPUT
* pIn
, ///< [in] input structure
1422 ADDR_COMPUTE_DCCINFO_OUTPUT
* pOut
///< [out] output structure
1425 ADDR_E_RETURNCODE ret
= ADDR_OK
;
1427 if (GetFillSizeFieldsFlags() == TRUE
)
1429 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_DCCINFO_INPUT
)) ||
1430 (pOut
->size
!= sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT
)))
1432 ret
= ADDR_PARAMSIZEMISMATCH
;
1438 ADDR_COMPUTE_DCCINFO_INPUT input
;
1440 if (UseTileIndex(pIn
->tileIndex
))
1444 ret
= HwlSetupTileCfg(input
.bpp
, input
.tileIndex
, input
.macroModeIndex
,
1445 &input
.tileInfo
, &input
.tileMode
);
1452 ret
= HwlComputeDccInfo(pIn
, pOut
);
1454 ValidMetaBaseAlignments(pOut
->dccRamBaseAlign
);
1462 ****************************************************************************************************
1463 * Lib::ComputeHtileAddrFromCoord
1466 * Interface function stub of AddrComputeHtileAddrFromCoord
1470 ****************************************************************************************************
1472 ADDR_E_RETURNCODE
Lib::ComputeHtileAddrFromCoord(
1473 const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1474 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1477 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1479 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1480 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1482 if (GetFillSizeFieldsFlags() == TRUE
)
1484 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
)) ||
1485 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
)))
1487 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1491 if (returnCode
== ADDR_OK
)
1493 ADDR_TILEINFO tileInfoNull
;
1494 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT input
;
1496 if (UseTileIndex(pIn
->tileIndex
))
1499 // Use temp tile info for calcalation
1500 input
.pTileInfo
= &tileInfoNull
;
1502 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1504 // Change the input structure
1508 if (returnCode
== ADDR_OK
)
1510 if (pIn
->flags
.tcCompatible
)
1512 HwlComputeHtileAddrFromCoord(pIn
, pOut
);
1516 pOut
->addr
= HwlComputeXmaskAddrFromCoord(pIn
->pitch
,
1527 &pOut
->bitPosition
);
1537 ****************************************************************************************************
1538 * Lib::ComputeHtileCoordFromAddr
1541 * Interface function stub of AddrComputeHtileCoordFromAddr
1545 ****************************************************************************************************
1547 ADDR_E_RETURNCODE
Lib::ComputeHtileCoordFromAddr(
1548 const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
1549 ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
1552 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1554 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1555 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1557 if (GetFillSizeFieldsFlags() == TRUE
)
1559 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT
)) ||
1560 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
)))
1562 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1566 if (returnCode
== ADDR_OK
)
1568 ADDR_TILEINFO tileInfoNull
;
1569 ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT input
;
1571 if (UseTileIndex(pIn
->tileIndex
))
1574 // Use temp tile info for calcalation
1575 input
.pTileInfo
= &tileInfoNull
;
1577 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1579 // Change the input structure
1583 if (returnCode
== ADDR_OK
)
1585 HwlComputeXmaskCoordFromAddr(pIn
->addr
,
1605 ****************************************************************************************************
1606 * Lib::ComputeCmaskAddrFromCoord
1609 * Interface function stub of AddrComputeCmaskAddrFromCoord
1613 ****************************************************************************************************
1615 ADDR_E_RETURNCODE
Lib::ComputeCmaskAddrFromCoord(
1616 const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1617 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1620 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1622 if (GetFillSizeFieldsFlags() == TRUE
)
1624 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
)) ||
1625 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
)))
1627 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1631 if (returnCode
== ADDR_OK
)
1633 ADDR_TILEINFO tileInfoNull
;
1634 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT input
;
1636 if (UseTileIndex(pIn
->tileIndex
))
1639 // Use temp tile info for calcalation
1640 input
.pTileInfo
= &tileInfoNull
;
1642 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1644 // Change the input structure
1648 if (returnCode
== ADDR_OK
)
1650 if (pIn
->flags
.tcCompatible
== TRUE
)
1652 returnCode
= HwlComputeCmaskAddrFromCoord(pIn
, pOut
);
1656 pOut
->addr
= HwlComputeXmaskAddrFromCoord(pIn
->pitch
,
1664 FALSE
, //this is cmask, isWidth8 is not needed
1665 FALSE
, //this is cmask, isHeight8 is not needed
1667 &pOut
->bitPosition
);
1677 ****************************************************************************************************
1678 * Lib::ComputeCmaskCoordFromAddr
1681 * Interface function stub of AddrComputeCmaskCoordFromAddr
1685 ****************************************************************************************************
1687 ADDR_E_RETURNCODE
Lib::ComputeCmaskCoordFromAddr(
1688 const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
1689 ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
1692 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1694 if (GetFillSizeFieldsFlags() == TRUE
)
1696 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT
)) ||
1697 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT
)))
1699 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1703 if (returnCode
== ADDR_OK
)
1705 ADDR_TILEINFO tileInfoNull
;
1706 ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT input
;
1708 if (UseTileIndex(pIn
->tileIndex
))
1711 // Use temp tile info for calcalation
1712 input
.pTileInfo
= &tileInfoNull
;
1714 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1716 // Change the input structure
1720 if (returnCode
== ADDR_OK
)
1722 HwlComputeXmaskCoordFromAddr(pIn
->addr
,
1742 ****************************************************************************************************
1743 * Lib::ComputeTileDataWidthAndHeight
1746 * Compute the squared cache shape for per-tile data (CMASK and HTILE)
1752 * MacroWidth and macroHeight are measured in pixels
1753 ****************************************************************************************************
1755 VOID
Lib::ComputeTileDataWidthAndHeight(
1756 UINT_32 bpp
, ///< [in] bits per pixel
1757 UINT_32 cacheBits
, ///< [in] bits of cache
1758 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1759 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1760 UINT_32
* pMacroHeight
///< [out] macro tile height
1764 UINT_32 width
= cacheBits
/ bpp
;
1765 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
1767 // Double height until the macro-tile is close to square
1768 // Height can only be doubled if width is even
1770 while ((width
> height
* 2 * pipes
) && !(width
& 1))
1776 *pMacroWidth
= 8 * width
;
1777 *pMacroHeight
= 8 * height
* pipes
;
1779 // Note: The above iterative comptuation is equivalent to the following
1781 //int log2_height = ((log2(cacheBits)-log2(bpp)-log2(pipes))/2);
1782 //int macroHeight = pow2( 3+log2(pipes)+log2_height );
1786 ****************************************************************************************************
1787 * Lib::HwlComputeTileDataWidthAndHeightLinear
1790 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1796 * MacroWidth and macroHeight are measured in pixels
1797 ****************************************************************************************************
1799 VOID
Lib::HwlComputeTileDataWidthAndHeightLinear(
1800 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1801 UINT_32
* pMacroHeight
, ///< [out] macro tile height
1802 UINT_32 bpp
, ///< [in] bits per pixel
1803 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
1806 ADDR_ASSERT(bpp
!= 4); // Cmask does not support linear layout prior to SI
1807 *pMacroWidth
= 8 * 512 / bpp
; // Align width to 512-bit memory accesses
1808 *pMacroHeight
= 8 * m_pipes
; // Align height to number of pipes
1812 ****************************************************************************************************
1813 * Lib::ComputeHtileInfo
1816 * Compute htile pitch,width, bytes per 2D slice
1819 * Htile bpp i.e. How many bits for an 8x8 tile
1820 * Also returns by output parameters:
1821 * *Htile pitch, height, total size in bytes, macro-tile dimensions and slice size*
1822 ****************************************************************************************************
1824 UINT_32
Lib::ComputeHtileInfo(
1825 ADDR_HTILE_FLAGS flags
, ///< [in] htile flags
1826 UINT_32 pitchIn
, ///< [in] pitch input
1827 UINT_32 heightIn
, ///< [in] height input
1828 UINT_32 numSlices
, ///< [in] number of slices
1829 BOOL_32 isLinear
, ///< [in] if it is linear mode
1830 BOOL_32 isWidth8
, ///< [in] if htile block width is 8
1831 BOOL_32 isHeight8
, ///< [in] if htile block height is 8
1832 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1833 UINT_32
* pPitchOut
, ///< [out] pitch output
1834 UINT_32
* pHeightOut
, ///< [out] height output
1835 UINT_64
* pHtileBytes
, ///< [out] bytes per 2D slice
1836 UINT_32
* pMacroWidth
, ///< [out] macro-tile width in pixels
1837 UINT_32
* pMacroHeight
, ///< [out] macro-tile width in pixels
1838 UINT_64
* pSliceSize
, ///< [out] slice size in bytes
1839 UINT_32
* pBaseAlign
///< [out] base alignment
1844 UINT_32 macroHeight
;
1849 numSlices
= Max(1u, numSlices
);
1851 const UINT_32 bpp
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
1852 const UINT_32 cacheBits
= HtileCacheBits
;
1856 HwlComputeTileDataWidthAndHeightLinear(¯oWidth
,
1863 ComputeTileDataWidthAndHeight(bpp
,
1870 *pPitchOut
= PowTwoAlign(pitchIn
, macroWidth
);
1871 *pHeightOut
= PowTwoAlign(heightIn
, macroHeight
);
1873 baseAlign
= HwlComputeHtileBaseAlign(flags
.tcCompatible
, isLinear
, pTileInfo
);
1875 surfBytes
= HwlComputeHtileBytes(*pPitchOut
,
1883 *pHtileBytes
= surfBytes
;
1886 // Use SafeAssign since they are optional
1888 SafeAssign(pMacroWidth
, macroWidth
);
1890 SafeAssign(pMacroHeight
, macroHeight
);
1892 SafeAssign(pSliceSize
, sliceBytes
);
1894 SafeAssign(pBaseAlign
, baseAlign
);
1900 ****************************************************************************************************
1901 * Lib::ComputeCmaskBaseAlign
1904 * Compute cmask base alignment
1907 * Cmask base alignment
1908 ****************************************************************************************************
1910 UINT_32
Lib::ComputeCmaskBaseAlign(
1911 ADDR_CMASK_FLAGS flags
, ///< [in] Cmask flags
1912 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
1915 UINT_32 baseAlign
= m_pipeInterleaveBytes
* HwlGetPipes(pTileInfo
);
1917 if (flags
.tcCompatible
)
1919 ADDR_ASSERT(pTileInfo
!= NULL
);
1922 baseAlign
*= pTileInfo
->banks
;
1930 ****************************************************************************************************
1931 * Lib::ComputeCmaskBytes
1934 * Compute cmask size in bytes
1937 * Cmask size in bytes
1938 ****************************************************************************************************
1940 UINT_64
Lib::ComputeCmaskBytes(
1941 UINT_32 pitch
, ///< [in] pitch
1942 UINT_32 height
, ///< [in] height
1943 UINT_32 numSlices
///< [in] number of slices
1946 return BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* numSlices
* CmaskElemBits
) /
1951 ****************************************************************************************************
1952 * Lib::ComputeCmaskInfo
1955 * Compute cmask pitch,width, bytes per 2D slice
1958 * BlockMax. Also by output parameters: Cmask pitch,height, total size in bytes,
1959 * macro-tile dimensions
1960 ****************************************************************************************************
1962 ADDR_E_RETURNCODE
Lib::ComputeCmaskInfo(
1963 ADDR_CMASK_FLAGS flags
, ///< [in] cmask flags
1964 UINT_32 pitchIn
, ///< [in] pitch input
1965 UINT_32 heightIn
, ///< [in] height input
1966 UINT_32 numSlices
, ///< [in] number of slices
1967 BOOL_32 isLinear
, ///< [in] is linear mode
1968 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1969 UINT_32
* pPitchOut
, ///< [out] pitch output
1970 UINT_32
* pHeightOut
, ///< [out] height output
1971 UINT_64
* pCmaskBytes
, ///< [out] bytes per 2D slice
1972 UINT_32
* pMacroWidth
, ///< [out] macro-tile width in pixels
1973 UINT_32
* pMacroHeight
, ///< [out] macro-tile width in pixels
1974 UINT_64
* pSliceSize
, ///< [out] slice size in bytes
1975 UINT_32
* pBaseAlign
, ///< [out] base alignment
1976 UINT_32
* pBlockMax
///< [out] block max == slice / 128 / 128 - 1
1980 UINT_32 macroHeight
;
1985 numSlices
= Max(1u, numSlices
);
1987 const UINT_32 bpp
= CmaskElemBits
;
1988 const UINT_32 cacheBits
= CmaskCacheBits
;
1990 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1994 HwlComputeTileDataWidthAndHeightLinear(¯oWidth
,
2001 ComputeTileDataWidthAndHeight(bpp
,
2008 *pPitchOut
= (pitchIn
+ macroWidth
- 1) & ~(macroWidth
- 1);
2009 *pHeightOut
= (heightIn
+ macroHeight
- 1) & ~(macroHeight
- 1);
2011 sliceBytes
= ComputeCmaskBytes(*pPitchOut
,
2015 baseAlign
= ComputeCmaskBaseAlign(flags
, pTileInfo
);
2017 while (sliceBytes
% baseAlign
)
2019 *pHeightOut
+= macroHeight
;
2021 sliceBytes
= ComputeCmaskBytes(*pPitchOut
,
2026 surfBytes
= sliceBytes
* numSlices
;
2028 *pCmaskBytes
= surfBytes
;
2031 // Use SafeAssign since they are optional
2033 SafeAssign(pMacroWidth
, macroWidth
);
2035 SafeAssign(pMacroHeight
, macroHeight
);
2037 SafeAssign(pBaseAlign
, baseAlign
);
2039 SafeAssign(pSliceSize
, sliceBytes
);
2041 UINT_32 slice
= (*pPitchOut
) * (*pHeightOut
);
2042 UINT_32 blockMax
= slice
/ 128 / 128 - 1;
2045 if (slice
% (64*256) != 0)
2047 ADDR_ASSERT_ALWAYS();
2051 UINT_32 maxBlockMax
= HwlGetMaxCmaskBlockMax();
2053 if (blockMax
> maxBlockMax
)
2055 blockMax
= maxBlockMax
;
2056 returnCode
= ADDR_INVALIDPARAMS
;
2059 SafeAssign(pBlockMax
, blockMax
);
2065 ****************************************************************************************************
2066 * Lib::ComputeXmaskCoordYFromPipe
2069 * Compute the Y coord from pipe number for cmask/htile
2074 ****************************************************************************************************
2076 UINT_32
Lib::ComputeXmaskCoordYFromPipe(
2077 UINT_32 pipe
, ///< [in] pipe number
2078 UINT_32 x
///< [in] x coordinate
2090 UINT_32 numPipes
= m_pipes
; // SI has its implementation
2092 // Convert pipe + x to y coordinate.
2112 pipeBit0
= pipe
& 0x1;
2116 yBit0
= pipeBit0
^ xBit0
;
2130 pipeBit0
= pipe
& 0x1;
2131 pipeBit1
= (pipe
& 0x2) >> 1;
2134 xBit1
= (x
& 0x2) >> 1;
2136 yBit0
= pipeBit0
^ xBit1
;
2137 yBit1
= pipeBit1
^ xBit0
;
2146 // r600 and r800 have different method
2148 y
= HwlComputeXmaskCoordYFrom8Pipe(pipe
, x
);
2157 ****************************************************************************************************
2158 * Lib::HwlComputeXmaskCoordFromAddr
2161 * Compute the coord from an address of a cmask/htile
2167 * This method is reused by htile, so rename to Xmask
2168 ****************************************************************************************************
2170 VOID
Lib::HwlComputeXmaskCoordFromAddr(
2171 UINT_64 addr
, ///< [in] address
2172 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2173 UINT_32 pitch
, ///< [in] pitch
2174 UINT_32 height
, ///< [in] height
2175 UINT_32 numSlices
, ///< [in] number of slices
2176 UINT_32 factor
, ///< [in] factor that indicates cmask or htile
2177 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
2178 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2179 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2180 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
2181 UINT_32
* pX
, ///< [out] x coord
2182 UINT_32
* pY
, ///< [out] y coord
2183 UINT_32
* pSlice
///< [out] slice index
2188 UINT_32 numGroupBits
;
2190 UINT_32 numPipeBits
;
2191 UINT_32 macroTilePitch
;
2192 UINT_32 macroTileHeight
;
2196 UINT_32 microTileCoordY
;
2200 UINT_32 pitchAligned
= pitch
;
2201 UINT_32 heightAligned
= height
;
2209 UINT_64 macroNumber
;
2210 UINT_32 microNumber
;
2219 UINT_32 tilesPerMacro
;
2220 UINT_32 macrosPerPitch
;
2221 UINT_32 macrosPerSlice
;
2226 numPipes
= HwlGetPipes(pTileInfo
);
2227 pipe
= ComputePipeFromAddr(addr
, numPipes
);
2230 // Compute the number of group and pipe bits.
2232 numGroupBits
= Log2(m_pipeInterleaveBytes
);
2233 numPipeBits
= Log2(numPipes
);
2235 UINT_32 groupBits
= 8 * m_pipeInterleaveBytes
;
2236 UINT_32 pipes
= numPipes
;
2239 // Compute the micro tile size, in bits. And macro tile pitch and height.
2241 if (factor
== 2) //CMASK
2243 ADDR_CMASK_FLAGS flags
= {{0}};
2245 elemBits
= CmaskElemBits
;
2247 ComputeCmaskInfo(flags
,
2261 ADDR_HTILE_FLAGS flags
= {{0}};
2268 elemBits
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
2270 ComputeHtileInfo(flags
,
2285 // Should use aligned dims
2287 pitch
= pitchAligned
;
2288 height
= heightAligned
;
2291 // Convert byte address to bit address.
2293 bitAddr
= BYTES_TO_BITS(addr
) + bitPosition
;
2296 // Remove pipe bits from address.
2299 bitAddr
= (bitAddr
% groupBits
) + ((bitAddr
/groupBits
/pipes
)*groupBits
);
2301 elemOffset
= bitAddr
/ elemBits
;
2303 tilesPerMacro
= (macroTilePitch
/factor
) * macroTileHeight
/ MicroTilePixels
>> numPipeBits
;
2305 macrosPerPitch
= pitch
/ (macroTilePitch
/factor
);
2306 macrosPerSlice
= macrosPerPitch
* height
/ macroTileHeight
;
2308 macroIndex
= elemOffset
/ factor
/ tilesPerMacro
;
2309 microIndex
= static_cast<UINT_32
>(elemOffset
% (tilesPerMacro
* factor
));
2311 macroNumber
= macroIndex
* factor
+ microIndex
% factor
;
2312 microNumber
= microIndex
/ factor
;
2314 macroX
= static_cast<UINT_32
>((macroNumber
% macrosPerPitch
));
2315 macroY
= static_cast<UINT_32
>((macroNumber
% macrosPerSlice
) / macrosPerPitch
);
2316 macroZ
= static_cast<UINT_32
>((macroNumber
/ macrosPerSlice
));
2318 microX
= microNumber
% (macroTilePitch
/ factor
/ MicroTileWidth
);
2319 microY
= (microNumber
/ (macroTilePitch
/ factor
/ MicroTileHeight
));
2321 *pX
= macroX
* (macroTilePitch
/factor
) + microX
* MicroTileWidth
;
2322 *pY
= macroY
* macroTileHeight
+ (microY
* MicroTileHeight
<< numPipeBits
);
2325 microTileCoordY
= ComputeXmaskCoordYFromPipe(pipe
,
2326 *pX
/MicroTileWidth
);
2329 // Assemble final coordinates.
2331 *pY
+= microTileCoordY
* MicroTileHeight
;
2336 ****************************************************************************************************
2337 * Lib::HwlComputeXmaskAddrFromCoord
2340 * Compute the address from an address of cmask (prior to si)
2345 ****************************************************************************************************
2347 UINT_64
Lib::HwlComputeXmaskAddrFromCoord(
2348 UINT_32 pitch
, ///< [in] pitch
2349 UINT_32 height
, ///< [in] height
2350 UINT_32 x
, ///< [in] x coord
2351 UINT_32 y
, ///< [in] y coord
2352 UINT_32 slice
, ///< [in] slice/depth index
2353 UINT_32 numSlices
, ///< [in] number of slices
2354 UINT_32 factor
, ///< [in] factor that indicates cmask(2) or htile(1)
2355 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
2356 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2357 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2358 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
2359 UINT_32
* pBitPosition
///< [out] bit position inside a byte
2363 UINT_32 numGroupBits
;
2364 UINT_32 numPipeBits
;
2365 UINT_32 newPitch
= 0;
2366 UINT_32 newHeight
= 0;
2367 UINT_64 sliceBytes
= 0;
2368 UINT_64 totalBytes
= 0;
2369 UINT_64 sliceOffset
;
2371 UINT_32 macroTileWidth
;
2372 UINT_32 macroTileHeight
;
2373 UINT_32 macroTilesPerRow
;
2374 UINT_32 macroTileBytes
;
2375 UINT_32 macroTileIndexX
;
2376 UINT_32 macroTileIndexY
;
2377 UINT_64 macroTileOffset
;
2378 UINT_32 pixelBytesPerRow
;
2379 UINT_32 pixelOffsetX
;
2380 UINT_32 pixelOffsetY
;
2381 UINT_32 pixelOffset
;
2382 UINT_64 totalOffset
;
2387 UINT_32 elemBits
= 0;
2389 UINT_32 numPipes
= m_pipes
; // This function is accessed prior to si only
2391 if (factor
== 2) //CMASK
2393 elemBits
= CmaskElemBits
;
2395 // For asics before SI, cmask is always tiled
2400 if (factor
!= 1) // Fix compile warning
2405 elemBits
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
2409 // Compute the number of group bits and pipe bits.
2411 numGroupBits
= Log2(m_pipeInterleaveBytes
);
2412 numPipeBits
= Log2(numPipes
);
2415 // Compute macro tile dimensions.
2417 if (factor
== 2) // CMASK
2419 ADDR_CMASK_FLAGS flags
= {{0}};
2421 ComputeCmaskInfo(flags
,
2433 sliceBytes
= totalBytes
/ numSlices
;
2437 ADDR_HTILE_FLAGS flags
= {{0}};
2439 ComputeHtileInfo(flags
,
2455 sliceOffset
= slice
* sliceBytes
;
2458 // Get the pipe. Note that neither slice rotation nor pipe swizzling apply for CMASK.
2460 pipe
= ComputePipeFromCoord(x
,
2463 ADDR_TM_2D_TILED_THIN1
,
2469 // Compute the number of macro tiles per row.
2471 macroTilesPerRow
= newPitch
/ macroTileWidth
;
2474 // Compute the number of bytes per macro tile.
2476 macroTileBytes
= BITS_TO_BYTES((macroTileWidth
* macroTileHeight
* elemBits
) / MicroTilePixels
);
2479 // Compute the offset to the macro tile containing the specified coordinate.
2481 macroTileIndexX
= x
/ macroTileWidth
;
2482 macroTileIndexY
= y
/ macroTileHeight
;
2483 macroTileOffset
= ((macroTileIndexY
* macroTilesPerRow
) + macroTileIndexX
) * macroTileBytes
;
2486 // Compute the pixel offset within the macro tile.
2488 pixelBytesPerRow
= BITS_TO_BYTES(macroTileWidth
* elemBits
) / MicroTileWidth
;
2491 // The nibbles are interleaved (see below), so the part of the offset relative to the x
2492 // coordinate repeats halfway across the row. (Not for HTILE)
2496 pixelOffsetX
= (x
% (macroTileWidth
/ 2)) / MicroTileWidth
;
2500 pixelOffsetX
= (x
% (macroTileWidth
)) / MicroTileWidth
* BITS_TO_BYTES(elemBits
);
2504 // Compute the y offset within the macro tile.
2506 pixelOffsetY
= (((y
% macroTileHeight
) / MicroTileHeight
) / numPipes
) * pixelBytesPerRow
;
2508 pixelOffset
= pixelOffsetX
+ pixelOffsetY
;
2511 // Combine the slice offset and macro tile offset with the pixel offset, accounting for the
2512 // pipe bits in the middle of the address.
2514 totalOffset
= ((sliceOffset
+ macroTileOffset
) >> numPipeBits
) + pixelOffset
;
2517 // Split the offset to put some bits below the pipe bits and some above.
2519 groupMask
= (1 << numGroupBits
) - 1;
2520 offsetLo
= totalOffset
& groupMask
;
2521 offsetHi
= (totalOffset
& ~groupMask
) << numPipeBits
;
2524 // Assemble the address from its components.
2528 // This is to remove warning with /analyze option
2529 UINT_32 pipeBits
= pipe
<< numGroupBits
;
2533 // Compute the bit position. The lower nibble is used when the x coordinate within the macro
2534 // tile is less than half of the macro tile width, and the upper nibble is used when the x
2535 // coordinate within the macro tile is greater than or equal to half the macro tile width.
2537 *pBitPosition
= ((x
% macroTileWidth
) < (macroTileWidth
/ factor
)) ? 0 : 4;
2542 ////////////////////////////////////////////////////////////////////////////////////////////////////
2543 // Surface Addressing Shared
2544 ////////////////////////////////////////////////////////////////////////////////////////////////////
2547 ****************************************************************************************************
2548 * Lib::ComputeSurfaceAddrFromCoordLinear
2551 * Compute address from coord for linear surface
2556 ****************************************************************************************************
2558 UINT_64
Lib::ComputeSurfaceAddrFromCoordLinear(
2559 UINT_32 x
, ///< [in] x coord
2560 UINT_32 y
, ///< [in] y coord
2561 UINT_32 slice
, ///< [in] slice/depth index
2562 UINT_32 sample
, ///< [in] sample index
2563 UINT_32 bpp
, ///< [in] bits per pixel
2564 UINT_32 pitch
, ///< [in] pitch
2565 UINT_32 height
, ///< [in] height
2566 UINT_32 numSlices
, ///< [in] number of slices
2567 UINT_32
* pBitPosition
///< [out] bit position inside a byte
2570 const UINT_64 sliceSize
= static_cast<UINT_64
>(pitch
) * height
;
2572 UINT_64 sliceOffset
= (slice
+ sample
* numSlices
)* sliceSize
;
2573 UINT_64 rowOffset
= static_cast<UINT_64
>(y
) * pitch
;
2574 UINT_64 pixOffset
= x
;
2576 UINT_64 addr
= (sliceOffset
+ rowOffset
+ pixOffset
) * bpp
;
2578 *pBitPosition
= static_cast<UINT_32
>(addr
% 8);
2585 ****************************************************************************************************
2586 * Lib::ComputeSurfaceCoordFromAddrLinear
2589 * Compute the coord from an address of a linear surface
2593 ****************************************************************************************************
2595 VOID
Lib::ComputeSurfaceCoordFromAddrLinear(
2596 UINT_64 addr
, ///< [in] address
2597 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2598 UINT_32 bpp
, ///< [in] bits per pixel
2599 UINT_32 pitch
, ///< [in] pitch
2600 UINT_32 height
, ///< [in] height
2601 UINT_32 numSlices
, ///< [in] number of slices
2602 UINT_32
* pX
, ///< [out] x coord
2603 UINT_32
* pY
, ///< [out] y coord
2604 UINT_32
* pSlice
, ///< [out] slice/depth index
2605 UINT_32
* pSample
///< [out] sample index
2608 const UINT_64 sliceSize
= static_cast<UINT_64
>(pitch
) * height
;
2609 const UINT_64 linearOffset
= (BYTES_TO_BITS(addr
) + bitPosition
) / bpp
;
2611 *pX
= static_cast<UINT_32
>((linearOffset
% sliceSize
) % pitch
);
2612 *pY
= static_cast<UINT_32
>((linearOffset
% sliceSize
) / pitch
% height
);
2613 *pSlice
= static_cast<UINT_32
>((linearOffset
/ sliceSize
) % numSlices
);
2614 *pSample
= static_cast<UINT_32
>((linearOffset
/ sliceSize
) / numSlices
);
2618 ****************************************************************************************************
2619 * Lib::ComputeSurfaceCoordFromAddrMicroTiled
2622 * Compute the coord from an address of a micro tiled surface
2626 ****************************************************************************************************
2628 VOID
Lib::ComputeSurfaceCoordFromAddrMicroTiled(
2629 UINT_64 addr
, ///< [in] address
2630 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2631 UINT_32 bpp
, ///< [in] bits per pixel
2632 UINT_32 pitch
, ///< [in] pitch
2633 UINT_32 height
, ///< [in] height
2634 UINT_32 numSamples
, ///< [in] number of samples
2635 AddrTileMode tileMode
, ///< [in] tile mode
2636 UINT_32 tileBase
, ///< [in] base offset within a tile
2637 UINT_32 compBits
, ///< [in] component bits actually needed(for planar surface)
2638 UINT_32
* pX
, ///< [out] x coord
2639 UINT_32
* pY
, ///< [out] y coord
2640 UINT_32
* pSlice
, ///< [out] slice/depth index
2641 UINT_32
* pSample
, ///< [out] sample index,
2642 AddrTileType microTileType
, ///< [in] micro tiling order
2643 BOOL_32 isDepthSampleOrder
///< [in] TRUE if in depth sample order
2647 UINT_32 microTileThickness
;
2648 UINT_32 microTileBits
;
2652 UINT_32 microTileCoordX
;
2653 UINT_32 microTileCoordY
;
2654 UINT_32 pixelOffset
;
2655 UINT_32 pixelCoordX
= 0;
2656 UINT_32 pixelCoordY
= 0;
2657 UINT_32 pixelCoordZ
= 0;
2658 UINT_32 pixelCoordS
= 0;
2661 // Convert byte address to bit address.
2663 bitAddr
= BYTES_TO_BITS(addr
) + bitPosition
;
2666 // Compute the micro tile size, in bits.
2670 case ADDR_TM_1D_TILED_THICK
:
2671 microTileThickness
= ThickTileThickness
;
2674 microTileThickness
= 1;
2678 microTileBits
= MicroTilePixels
* microTileThickness
* bpp
* numSamples
;
2681 // Compute number of bits per slice and number of bits per row of micro tiles.
2683 sliceBits
= static_cast<UINT_64
>(pitch
) * height
* microTileThickness
* bpp
* numSamples
;
2685 rowBits
= (pitch
/ MicroTileWidth
) * microTileBits
;
2688 // Extract the slice index.
2690 sliceIndex
= static_cast<UINT_32
>(bitAddr
/ sliceBits
);
2691 bitAddr
-= sliceIndex
* sliceBits
;
2694 // Extract the y coordinate of the micro tile.
2696 microTileCoordY
= static_cast<UINT_32
>(bitAddr
/ rowBits
) * MicroTileHeight
;
2697 bitAddr
-= (microTileCoordY
/ MicroTileHeight
) * rowBits
;
2700 // Extract the x coordinate of the micro tile.
2702 microTileCoordX
= static_cast<UINT_32
>(bitAddr
/ microTileBits
) * MicroTileWidth
;
2705 // Compute the pixel offset within the micro tile.
2707 pixelOffset
= static_cast<UINT_32
>(bitAddr
% microTileBits
);
2710 // Extract pixel coordinates from the offset.
2712 HwlComputePixelCoordFromOffset(pixelOffset
,
2723 isDepthSampleOrder
);
2726 // Assemble final coordinates.
2728 *pX
= microTileCoordX
+ pixelCoordX
;
2729 *pY
= microTileCoordY
+ pixelCoordY
;
2730 *pSlice
= (sliceIndex
* microTileThickness
) + pixelCoordZ
;
2731 *pSample
= pixelCoordS
;
2733 if (microTileThickness
> 1)
2740 ****************************************************************************************************
2741 * Lib::ComputePipeFromAddr
2744 * Compute the pipe number from an address
2749 ****************************************************************************************************
2751 UINT_32
Lib::ComputePipeFromAddr(
2752 UINT_64 addr
, ///< [in] address
2753 UINT_32 numPipes
///< [in] number of banks
2758 UINT_32 groupBytes
= m_pipeInterleaveBytes
; //just different terms
2761 // The LSBs of the address are arranged as follows:
2762 // bank | pipe | group
2764 // To get the pipe number, shift off the group bits and mask the pipe bits.
2768 // The LSBs of the address are arranged as follows:
2769 // bank | bankInterleave | pipe | pipeInterleave
2771 // To get the pipe number, shift off the pipe interleave bits and mask the pipe bits.
2774 pipe
= static_cast<UINT_32
>(addr
>> Log2(groupBytes
)) & (numPipes
- 1);
2780 ****************************************************************************************************
2781 * Lib::ComputeMicroTileEquation
2784 * Compute micro tile equation
2787 * If equation can be computed
2789 ****************************************************************************************************
2791 ADDR_E_RETURNCODE
Lib::ComputeMicroTileEquation(
2792 UINT_32 log2BytesPP
, ///< [in] log2 of bytes per pixel
2793 AddrTileMode tileMode
, ///< [in] tile mode
2794 AddrTileType microTileType
, ///< [in] pixel order in display/non-display mode
2795 ADDR_EQUATION
* pEquation
///< [out] equation
2798 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
2800 for (UINT_32 i
= 0; i
< log2BytesPP
; i
++)
2802 pEquation
->addr
[i
].valid
= 1;
2803 pEquation
->addr
[i
].channel
= 0;
2804 pEquation
->addr
[i
].index
= i
;
2807 ADDR_CHANNEL_SETTING
* pixelBit
= &pEquation
->addr
[log2BytesPP
];
2809 ADDR_CHANNEL_SETTING x0
= InitChannel(1, 0, log2BytesPP
+ 0);
2810 ADDR_CHANNEL_SETTING x1
= InitChannel(1, 0, log2BytesPP
+ 1);
2811 ADDR_CHANNEL_SETTING x2
= InitChannel(1, 0, log2BytesPP
+ 2);
2812 ADDR_CHANNEL_SETTING y0
= InitChannel(1, 1, 0);
2813 ADDR_CHANNEL_SETTING y1
= InitChannel(1, 1, 1);
2814 ADDR_CHANNEL_SETTING y2
= InitChannel(1, 1, 2);
2815 ADDR_CHANNEL_SETTING z0
= InitChannel(1, 2, 0);
2816 ADDR_CHANNEL_SETTING z1
= InitChannel(1, 2, 1);
2817 ADDR_CHANNEL_SETTING z2
= InitChannel(1, 2, 2);
2819 UINT_32 thickness
= Thickness(tileMode
);
2820 UINT_32 bpp
= 1 << (log2BytesPP
+ 3);
2822 if (microTileType
!= ADDR_THICK
)
2824 if (microTileType
== ADDR_DISPLAYABLE
)
2869 ADDR_ASSERT_ALWAYS();
2873 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2882 else if (microTileType
== ADDR_ROTATED
)
2884 ADDR_ASSERT(thickness
== 1);
2921 retCode
= ADDR_NOTSUPPORTED
;
2930 pEquation
->numBits
= 8 + log2BytesPP
;
2934 pEquation
->numBits
= 6 + log2BytesPP
;
2939 ADDR_ASSERT(thickness
> 1);
2970 ADDR_ASSERT_ALWAYS();
2976 pEquation
->numBits
= 8 + log2BytesPP
;
2982 pEquation
->numBits
= 9 + log2BytesPP
;
2985 // stackedDepthSlices is used for addressing mode that a tile block contains multiple slices,
2986 // which is not supported by our address lib
2987 pEquation
->stackedDepthSlices
= FALSE
;
2993 ****************************************************************************************************
2994 * Lib::ComputePixelIndexWithinMicroTile
2997 * Compute the pixel index inside a micro tile of surface
3002 ****************************************************************************************************
3004 UINT_32
Lib::ComputePixelIndexWithinMicroTile(
3005 UINT_32 x
, ///< [in] x coord
3006 UINT_32 y
, ///< [in] y coord
3007 UINT_32 z
, ///< [in] slice/depth index
3008 UINT_32 bpp
, ///< [in] bits per pixel
3009 AddrTileMode tileMode
, ///< [in] tile mode
3010 AddrTileType microTileType
///< [in] pixel order in display/non-display mode
3013 UINT_32 pixelBit0
= 0;
3014 UINT_32 pixelBit1
= 0;
3015 UINT_32 pixelBit2
= 0;
3016 UINT_32 pixelBit3
= 0;
3017 UINT_32 pixelBit4
= 0;
3018 UINT_32 pixelBit5
= 0;
3019 UINT_32 pixelBit6
= 0;
3020 UINT_32 pixelBit7
= 0;
3021 UINT_32 pixelBit8
= 0;
3022 UINT_32 pixelNumber
;
3024 UINT_32 x0
= _BIT(x
, 0);
3025 UINT_32 x1
= _BIT(x
, 1);
3026 UINT_32 x2
= _BIT(x
, 2);
3027 UINT_32 y0
= _BIT(y
, 0);
3028 UINT_32 y1
= _BIT(y
, 1);
3029 UINT_32 y2
= _BIT(y
, 2);
3030 UINT_32 z0
= _BIT(z
, 0);
3031 UINT_32 z1
= _BIT(z
, 1);
3032 UINT_32 z2
= _BIT(z
, 2);
3034 UINT_32 thickness
= Thickness(tileMode
);
3036 // Compute the pixel number within the micro tile.
3038 if (microTileType
!= ADDR_THICK
)
3040 if (microTileType
== ADDR_DISPLAYABLE
)
3085 ADDR_ASSERT_ALWAYS();
3089 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
3098 else if (microTileType
== ADDR_ROTATED
)
3100 ADDR_ASSERT(thickness
== 1);
3137 ADDR_ASSERT_ALWAYS();
3150 ADDR_ASSERT(thickness
> 1);
3181 ADDR_ASSERT_ALWAYS();
3194 pixelNumber
= ((pixelBit0
) |
3208 ****************************************************************************************************
3209 * Lib::AdjustPitchAlignment
3212 * Adjusts pitch alignment for flipping surface
3217 ****************************************************************************************************
3219 VOID
Lib::AdjustPitchAlignment(
3220 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface flags
3221 UINT_32
* pPitchAlign
///< [out] Pointer to pitch alignment
3224 // Display engine hardwires lower 5 bit of GRPH_PITCH to ZERO which means 32 pixel alignment
3225 // Maybe it will be fixed in future but let's make it general for now.
3226 if (flags
.display
|| flags
.overlay
)
3228 *pPitchAlign
= PowTwoAlign(*pPitchAlign
, 32);
3232 *pPitchAlign
= Max(m_minPitchAlignPixels
, *pPitchAlign
);
3238 ****************************************************************************************************
3239 * Lib::PadDimensions
3242 * Helper function to pad dimensions
3247 ****************************************************************************************************
3249 VOID
Lib::PadDimensions(
3250 AddrTileMode tileMode
, ///< [in] tile mode
3251 UINT_32 bpp
, ///< [in] bits per pixel
3252 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
3253 UINT_32 numSamples
, ///< [in] number of samples
3254 ADDR_TILEINFO
* pTileInfo
, ///< [in,out] bank structure.
3255 UINT_32 padDims
, ///< [in] Dimensions to pad valid value 1,2,3
3256 UINT_32 mipLevel
, ///< [in] MipLevel
3257 UINT_32
* pPitch
, ///< [in,out] pitch in pixels
3258 UINT_32
* pPitchAlign
, ///< [in,out] pitch align could be changed in HwlPadDimensions
3259 UINT_32
* pHeight
, ///< [in,out] height in pixels
3260 UINT_32 heightAlign
, ///< [in] height alignment
3261 UINT_32
* pSlices
, ///< [in,out] number of slices
3262 UINT_32 sliceAlign
///< [in] number of slice alignment
3265 UINT_32 pitchAlign
= *pPitchAlign
;
3266 UINT_32 thickness
= Thickness(tileMode
);
3268 ADDR_ASSERT(padDims
<= 3);
3271 // Override padding for mip levels
3277 // for cubemap, we only pad when client call with 6 faces as an identity
3280 padDims
= 3; // we should pad cubemap sub levels when we treat it as 3d texture
3289 // Any possibilities that padDims is 0?
3295 if (IsPow2(pitchAlign
))
3297 *pPitch
= PowTwoAlign((*pPitch
), pitchAlign
);
3299 else // add this code to pass unit test, r600 linear mode is not align bpp to pow2 for linear
3301 *pPitch
+= pitchAlign
- 1;
3302 *pPitch
/= pitchAlign
;
3303 *pPitch
*= pitchAlign
;
3308 if (IsPow2(heightAlign
))
3310 *pHeight
= PowTwoAlign((*pHeight
), heightAlign
);
3314 *pHeight
+= heightAlign
- 1;
3315 *pHeight
/= heightAlign
;
3316 *pHeight
*= heightAlign
;
3320 if (padDims
> 2 || thickness
> 1)
3322 // for cubemap single face, we do not pad slices.
3323 // if we pad it, the slice number should be set to 6 and current mip level > 1
3324 if (flags
.cube
&& (!m_configFlags
.noCubeMipSlicesPad
|| flags
.cubeAsArray
))
3326 *pSlices
= NextPow2(*pSlices
);
3329 // normal 3D texture or arrays or cubemap has a thick mode? (Just pass unit test)
3332 *pSlices
= PowTwoAlign((*pSlices
), sliceAlign
);
3337 HwlPadDimensions(tileMode
,
3350 ****************************************************************************************************
3351 * Lib::HwlPreHandleBaseLvl3xPitch
3354 * Pre-handler of 3x pitch (96 bit) adjustment
3358 ****************************************************************************************************
3360 UINT_32
Lib::HwlPreHandleBaseLvl3xPitch(
3361 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
3362 UINT_32 expPitch
///< [in] pitch
3365 ADDR_ASSERT(pIn
->width
== expPitch
);
3367 // If pitch is pre-multiplied by 3, we retrieve original one here to get correct miplevel size
3369 if (ElemLib::IsExpand3x(pIn
->format
) &&
3370 pIn
->mipLevel
== 0 &&
3371 pIn
->tileMode
== ADDR_TM_LINEAR_ALIGNED
)
3374 expPitch
= NextPow2(expPitch
);
3381 ****************************************************************************************************
3382 * Lib::HwlPostHandleBaseLvl3xPitch
3385 * Post-handler of 3x pitch adjustment
3389 ****************************************************************************************************
3391 UINT_32
Lib::HwlPostHandleBaseLvl3xPitch(
3392 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
3393 UINT_32 expPitch
///< [in] pitch
3397 // 96 bits surface of sub levels require element pitch of 32 bits instead
3398 // So we just return pitch in 32 bit pixels without timing 3
3400 if (ElemLib::IsExpand3x(pIn
->format
) &&
3401 pIn
->mipLevel
== 0 &&
3402 pIn
->tileMode
== ADDR_TM_LINEAR_ALIGNED
)
3411 ****************************************************************************************************
3415 * Check if the tile mode is macro tiled
3418 * TRUE if it is macro tiled (2D/2B/3D/3B)
3419 ****************************************************************************************************
3421 BOOL_32
Lib::IsMacroTiled(
3422 AddrTileMode tileMode
) ///< [in] tile mode
3424 return ModeFlags
[tileMode
].isMacro
;
3428 ****************************************************************************************************
3429 * Lib::IsMacro3dTiled
3432 * Check if the tile mode is 3D macro tiled
3435 * TRUE if it is 3D macro tiled
3436 ****************************************************************************************************
3438 BOOL_32
Lib::IsMacro3dTiled(
3439 AddrTileMode tileMode
) ///< [in] tile mode
3441 return ModeFlags
[tileMode
].isMacro3d
;
3445 ****************************************************************************************************
3449 * Check if the tile mode is micro tiled
3452 * TRUE if micro tiled
3453 ****************************************************************************************************
3455 BOOL_32
Lib::IsMicroTiled(
3456 AddrTileMode tileMode
) ///< [in] tile mode
3458 return ModeFlags
[tileMode
].isMicro
;
3462 ****************************************************************************************************
3466 * Check if the tile mode is linear
3470 ****************************************************************************************************
3472 BOOL_32
Lib::IsLinear(
3473 AddrTileMode tileMode
) ///< [in] tile mode
3475 return ModeFlags
[tileMode
].isLinear
;
3479 ****************************************************************************************************
3480 * Lib::IsPrtNoRotationTileMode
3483 * Return TRUE if it is prt tile without rotation
3485 * This function just used by CI
3486 ****************************************************************************************************
3488 BOOL_32
Lib::IsPrtNoRotationTileMode(
3489 AddrTileMode tileMode
)
3491 return ModeFlags
[tileMode
].isPrtNoRotation
;
3495 ****************************************************************************************************
3496 * Lib::IsPrtTileMode
3499 * Return TRUE if it is prt tile
3501 * This function just used by CI
3502 ****************************************************************************************************
3504 BOOL_32
Lib::IsPrtTileMode(
3505 AddrTileMode tileMode
)
3507 return ModeFlags
[tileMode
].isPrt
;
3511 ****************************************************************************************************
3512 * Lib::ComputeMipLevel
3515 * Compute mipmap level width/height/slices
3518 ****************************************************************************************************
3520 VOID
Lib::ComputeMipLevel(
3521 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
///< [in,out] Input structure
3524 // Check if HWL has handled
3525 BOOL_32 hwlHandled
= FALSE
;
3528 if (ElemLib::IsBlockCompressed(pIn
->format
))
3530 if (pIn
->mipLevel
== 0)
3532 // DXTn's level 0 must be multiple of 4
3533 // But there are exceptions:
3534 // 1. Internal surface creation in hostblt/vsblt/etc...
3535 // 2. Runtime doesn't reject ATI1/ATI2 whose width/height are not multiple of 4
3536 pIn
->width
= PowTwoAlign(pIn
->width
, 4);
3537 pIn
->height
= PowTwoAlign(pIn
->height
, 4);
3541 hwlHandled
= HwlComputeMipLevel(pIn
);
3545 ****************************************************************************************************
3549 * Check if surface can be degraded to 1D
3552 ****************************************************************************************************
3554 BOOL_32
Lib::DegradeTo1D(
3555 UINT_32 width
, ///< surface width
3556 UINT_32 height
, ///< surface height
3557 UINT_32 macroTilePitchAlign
, ///< macro tile pitch align
3558 UINT_32 macroTileHeightAlign
///< macro tile height align
3561 BOOL_32 degrade
= ((width
< macroTilePitchAlign
) || (height
< macroTileHeightAlign
));
3563 // Check whether 2D tiling still has too much footprint
3564 if (degrade
== FALSE
)
3566 // Only check width and height as slices are aligned to thickness
3567 UINT_64 unalignedSize
= width
* height
;
3569 UINT_32 alignedPitch
= PowTwoAlign(width
, macroTilePitchAlign
);
3570 UINT_32 alignedHeight
= PowTwoAlign(height
, macroTileHeightAlign
);
3571 UINT_64 alignedSize
= alignedPitch
* alignedHeight
;
3573 // alignedSize > 1.5 * unalignedSize
3574 if (2 * alignedSize
> 3 * unalignedSize
)
3584 ****************************************************************************************************
3585 * Lib::OptimizeTileMode
3588 * Check if base level's tile mode can be optimized (degraded)
3591 ****************************************************************************************************
3593 VOID
Lib::OptimizeTileMode(
3594 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in, out] structure for surface info
3597 AddrTileMode tileMode
= pInOut
->tileMode
;
3599 BOOL_32 doOpt
= (pInOut
->flags
.opt4Space
== TRUE
) ||
3600 (pInOut
->flags
.minimizeAlignment
== TRUE
) ||
3601 (pInOut
->maxBaseAlign
!= 0);
3603 BOOL_32 convertToPrt
= FALSE
;
3605 // Optimization can only be done on level 0 and samples <= 1
3606 if ((doOpt
== TRUE
) &&
3607 (pInOut
->mipLevel
== 0) &&
3608 (IsPrtTileMode(tileMode
) == FALSE
) &&
3609 (pInOut
->flags
.prt
== FALSE
))
3611 UINT_32 width
= pInOut
->width
;
3612 UINT_32 height
= pInOut
->height
;
3613 UINT_32 thickness
= Thickness(tileMode
);
3614 BOOL_32 macroTiledOK
= TRUE
;
3615 UINT_32 macroWidthAlign
= 0;
3616 UINT_32 macroHeightAlign
= 0;
3617 UINT_32 macroSizeAlign
= 0;
3619 if (IsMacroTiled(tileMode
))
3621 macroTiledOK
= HwlGetAlignmentInfoMacroTiled(pInOut
,
3629 if ((pInOut
->flags
.display
== FALSE
) &&
3630 (pInOut
->flags
.opt4Space
== TRUE
) &&
3631 (pInOut
->numSamples
<= 1))
3633 // Check if linear mode is optimal
3634 if ((pInOut
->height
== 1) &&
3635 (IsLinear(tileMode
) == FALSE
) &&
3636 (ElemLib::IsBlockCompressed(pInOut
->format
) == FALSE
) &&
3637 (pInOut
->flags
.depth
== FALSE
) &&
3638 (pInOut
->flags
.stencil
== FALSE
) &&
3639 (m_configFlags
.disableLinearOpt
== FALSE
) &&
3640 (pInOut
->flags
.disableLinearOpt
== FALSE
))
3642 tileMode
= ADDR_TM_LINEAR_ALIGNED
;
3644 else if (IsMacroTiled(tileMode
) && (pInOut
->flags
.tcCompatible
== FALSE
))
3646 if (DegradeTo1D(width
, height
, macroWidthAlign
, macroHeightAlign
))
3648 tileMode
= (thickness
== 1) ?
3649 ADDR_TM_1D_TILED_THIN1
: ADDR_TM_1D_TILED_THICK
;
3651 else if ((thickness
> 1) && (pInOut
->flags
.disallowLargeThickDegrade
== 0))
3653 // As in the following HwlComputeSurfaceInfo, thick modes may be degraded to
3654 // thinner modes, we should re-evaluate whether the corresponding
3655 // thinner modes should be degraded. If so, we choose 1D thick mode instead.
3656 tileMode
= DegradeLargeThickTile(pInOut
->tileMode
, pInOut
->bpp
);
3658 if (tileMode
!= pInOut
->tileMode
)
3660 // Get thickness again after large thick degrade
3661 thickness
= Thickness(tileMode
);
3663 ADDR_COMPUTE_SURFACE_INFO_INPUT input
= *pInOut
;
3664 input
.tileMode
= tileMode
;
3666 macroTiledOK
= HwlGetAlignmentInfoMacroTiled(&input
,
3672 DegradeTo1D(width
, height
, macroWidthAlign
, macroHeightAlign
))
3674 tileMode
= ADDR_TM_1D_TILED_THICK
;
3683 if ((pInOut
->flags
.minimizeAlignment
== TRUE
) &&
3684 (pInOut
->numSamples
<= 1) &&
3685 (IsMacroTiled(tileMode
) == TRUE
))
3687 UINT_32 macroSize
= PowTwoAlign(width
, macroWidthAlign
) *
3688 PowTwoAlign(height
, macroHeightAlign
);
3689 UINT_32 microSize
= PowTwoAlign(width
, MicroTileWidth
) *
3690 PowTwoAlign(height
, MicroTileHeight
);
3692 if (macroSize
> microSize
)
3694 tileMode
= (thickness
== 1) ?
3695 ADDR_TM_1D_TILED_THIN1
: ADDR_TM_1D_TILED_THICK
;
3699 if ((pInOut
->maxBaseAlign
!= 0) &&
3700 (IsMacroTiled(tileMode
) == TRUE
))
3702 if (macroSizeAlign
> pInOut
->maxBaseAlign
)
3704 if (pInOut
->numSamples
> 1)
3706 ADDR_ASSERT(pInOut
->maxBaseAlign
>= Block64K
);
3708 convertToPrt
= TRUE
;
3710 else if (pInOut
->maxBaseAlign
< Block64K
)
3712 tileMode
= (thickness
== 1) ?
3713 ADDR_TM_1D_TILED_THIN1
: ADDR_TM_1D_TILED_THICK
;
3717 convertToPrt
= TRUE
;
3727 if ((pInOut
->flags
.matchStencilTileCfg
== TRUE
) && (pInOut
->numSamples
<= 1))
3729 pInOut
->tileMode
= ADDR_TM_1D_TILED_THIN1
;
3733 HwlSetPrtTileMode(pInOut
);
3736 else if (tileMode
!= pInOut
->tileMode
)
3738 pInOut
->tileMode
= tileMode
;
3741 HwlOptimizeTileMode(pInOut
);
3745 ****************************************************************************************************
3746 * Lib::DegradeLargeThickTile
3749 * Check if the thickness needs to be reduced if a tile is too large
3751 * The degraded tile mode (unchanged if not degraded)
3752 ****************************************************************************************************
3754 AddrTileMode
Lib::DegradeLargeThickTile(
3755 AddrTileMode tileMode
,
3758 // Override tilemode
3759 // When tile_width (8) * tile_height (8) * thickness * element_bytes is > row_size,
3760 // it is better to just use THIN mode in this case
3761 UINT_32 thickness
= Thickness(tileMode
);
3763 if (thickness
> 1 && m_configFlags
.allowLargeThickTile
== 0)
3765 UINT_32 tileSize
= MicroTilePixels
* thickness
* (bpp
>> 3);
3767 if (tileSize
> m_rowSize
)
3771 case ADDR_TM_2D_TILED_XTHICK
:
3772 if ((tileSize
>> 1) <= m_rowSize
)
3774 tileMode
= ADDR_TM_2D_TILED_THICK
;
3777 // else fall through
3778 case ADDR_TM_2D_TILED_THICK
:
3779 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3782 case ADDR_TM_3D_TILED_XTHICK
:
3783 if ((tileSize
>> 1) <= m_rowSize
)
3785 tileMode
= ADDR_TM_3D_TILED_THICK
;
3788 // else fall through
3789 case ADDR_TM_3D_TILED_THICK
:
3790 tileMode
= ADDR_TM_3D_TILED_THIN1
;
3793 case ADDR_TM_PRT_TILED_THICK
:
3794 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
3797 case ADDR_TM_PRT_2D_TILED_THICK
:
3798 tileMode
= ADDR_TM_PRT_2D_TILED_THIN1
;
3801 case ADDR_TM_PRT_3D_TILED_THICK
:
3802 tileMode
= ADDR_TM_PRT_3D_TILED_THIN1
;
3815 ****************************************************************************************************
3816 * Lib::PostComputeMipLevel
3818 * Compute MipLevel info (including level 0) after surface adjustment
3821 ****************************************************************************************************
3823 ADDR_E_RETURNCODE
Lib::PostComputeMipLevel(
3824 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in,out] Input structure
3825 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] Output structure
3828 // Mipmap including level 0 must be pow2 padded since either SI hw expects so or it is
3829 // required by CFX for Hw Compatibility between NI and SI. Otherwise it is only needed for
3830 // mipLevel > 0. Any h/w has different requirement should implement its own virtual function
3832 if (pIn
->flags
.pow2Pad
)
3834 pIn
->width
= NextPow2(pIn
->width
);
3835 pIn
->height
= NextPow2(pIn
->height
);
3836 pIn
->numSlices
= NextPow2(pIn
->numSlices
);
3838 else if (pIn
->mipLevel
> 0)
3840 pIn
->width
= NextPow2(pIn
->width
);
3841 pIn
->height
= NextPow2(pIn
->height
);
3843 if (!pIn
->flags
.cube
)
3845 pIn
->numSlices
= NextPow2(pIn
->numSlices
);
3848 // for cubemap, we keep its value at first
3855 ****************************************************************************************************
3856 * Lib::HwlSetupTileCfg
3859 * Map tile index to tile setting.
3862 ****************************************************************************************************
3864 ADDR_E_RETURNCODE
Lib::HwlSetupTileCfg(
3865 UINT_32 bpp
, ///< Bits per pixel
3866 INT_32 index
, ///< [in] Tile index
3867 INT_32 macroModeIndex
, ///< [in] Index in macro tile mode table(CI)
3868 ADDR_TILEINFO
* pInfo
, ///< [out] Tile Info
3869 AddrTileMode
* pMode
, ///< [out] Tile mode
3870 AddrTileType
* pType
///< [out] Tile type
3873 return ADDR_NOTSUPPORTED
;
3877 ****************************************************************************************************
3884 ****************************************************************************************************
3886 UINT_32
Lib::HwlGetPipes(
3887 const ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
3890 //pTileInfo can be NULL when asic is 6xx and 8xx.
3895 ****************************************************************************************************
3896 * Lib::ComputeQbStereoInfo
3899 * Get quad buffer stereo information
3902 ****************************************************************************************************
3904 VOID
Lib::ComputeQbStereoInfo(
3905 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in,out] updated pOut+pStereoInfo
3908 ADDR_ASSERT(pOut
->bpp
>= 8);
3909 ADDR_ASSERT((pOut
->surfSize
% pOut
->baseAlign
) == 0);
3911 // Save original height
3912 pOut
->pStereoInfo
->eyeHeight
= pOut
->height
;
3915 pOut
->pStereoInfo
->rightOffset
= static_cast<UINT_32
>(pOut
->surfSize
);
3917 pOut
->pStereoInfo
->rightSwizzle
= HwlComputeQbStereoRightSwizzle(pOut
);
3920 pOut
->pixelHeight
<<= 1;
3923 pOut
->surfSize
<<= 1;
3925 // Right start address meets the base align since it is guaranteed by AddrLib1
3927 // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo.
3931 ****************************************************************************************************
3932 * Lib::ComputePrtInfo
3935 * Compute prt surface related info
3939 ****************************************************************************************************
3941 ADDR_E_RETURNCODE
Lib::ComputePrtInfo(
3942 const ADDR_PRT_INFO_INPUT
* pIn
,
3943 ADDR_PRT_INFO_OUTPUT
* pOut
) const
3945 ADDR_ASSERT(pOut
!= NULL
);
3947 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
3949 UINT_32 expandX
= 1;
3950 UINT_32 expandY
= 1;
3953 UINT_32 bpp
= GetElemLib()->GetBitsPerPixel(pIn
->format
,
3958 if (bpp
<8 || bpp
== 24 || bpp
== 48 || bpp
== 96)
3960 returnCode
= ADDR_INVALIDPARAMS
;
3963 UINT_32 numFrags
= pIn
->numFrags
;
3964 ADDR_ASSERT(numFrags
<= 8);
3966 UINT_32 tileWidth
= 0;
3967 UINT_32 tileHeight
= 0;
3968 if (returnCode
== ADDR_OK
)
3970 // 3D texture without depth or 2d texture
3971 if (pIn
->baseMipDepth
> 1 || pIn
->baseMipHeight
> 1)
3990 // assume it is BC1/4
3994 if (elemMode
== ADDR_UNCOMPRESSED
)
4000 else if (bpp
== 128)
4002 // assume it is BC2/3/5/6H/7
4006 if (elemMode
== ADDR_UNCOMPRESSED
)
4015 tileWidth
= tileWidth
/ 2;
4017 else if (numFrags
== 4)
4019 tileWidth
= tileWidth
/ 2;
4020 tileHeight
= tileHeight
/ 2;
4022 else if (numFrags
== 8)
4024 tileWidth
= tileWidth
/ 4;
4025 tileHeight
= tileHeight
/ 2;
4047 else if (bpp
== 128)
4054 pOut
->prtTileWidth
= tileWidth
;
4055 pOut
->prtTileHeight
= tileHeight
;