2 * Copyright © 2016 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 AISC can use AddrLib1 function.
144 ADDR_ASSERT_ALWAYS();
147 return static_cast<Lib
*>(hLib
);
151 ////////////////////////////////////////////////////////////////////////////////////////////////////
153 ////////////////////////////////////////////////////////////////////////////////////////////////////
157 ****************************************************************************************************
158 * Lib::ComputeSurfaceInfo
161 * Interface function stub of AddrComputeSurfaceInfo.
165 ****************************************************************************************************
167 ADDR_E_RETURNCODE
Lib::ComputeSurfaceInfo(
168 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
169 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
172 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
174 if (GetFillSizeFieldsFlags() == TRUE
)
176 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT
)) ||
177 (pOut
->size
!= sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT
)))
179 returnCode
= ADDR_PARAMSIZEMISMATCH
;
183 // We suggest client do sanity check but a check here is also good
186 returnCode
= ADDR_INVALIDPARAMS
;
189 if ((pIn
->tileMode
== ADDR_TM_UNKNOWN
) && (pIn
->mipLevel
> 0))
191 returnCode
= ADDR_INVALIDPARAMS
;
194 // Thick modes don't support multisample
195 if ((Thickness(pIn
->tileMode
) > 1) && (pIn
->numSamples
> 1))
197 returnCode
= ADDR_INVALIDPARAMS
;
200 if (returnCode
== ADDR_OK
)
202 // Get a local copy of input structure and only reference pIn for unadjusted values
203 ADDR_COMPUTE_SURFACE_INFO_INPUT localIn
= *pIn
;
204 ADDR_TILEINFO tileInfoNull
= {0};
208 // If the original input has a valid ADDR_TILEINFO pointer then copy its contents.
209 // Otherwise the default 0's in tileInfoNull are used.
212 tileInfoNull
= *pIn
->pTileInfo
;
214 localIn
.pTileInfo
= &tileInfoNull
;
217 localIn
.numSamples
= (pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
;
219 // Do mipmap check first
220 // If format is BCn, pre-pad dimension to power-of-two according to HWL
221 ComputeMipLevel(&localIn
);
223 if (m_configFlags
.checkLast2DLevel
)
225 // Save this level's original height in pixels
226 pOut
->height
= pIn
->height
;
233 // Save outputs that may not go through HWL
234 pOut
->pixelBits
= localIn
.bpp
;
235 pOut
->numSamples
= localIn
.numSamples
;
236 pOut
->last2DLevel
= FALSE
;
237 pOut
->tcCompatible
= FALSE
;
240 if (localIn
.numSamples
> 1)
242 ADDR_ASSERT(localIn
.mipLevel
== 0);
246 if (localIn
.format
!= ADDR_FMT_INVALID
) // Set format to INVALID will skip this conversion
248 // Get compression/expansion factors and element mode
249 // (which indicates compression/expansion
250 localIn
.bpp
= GetElemLib()->GetBitsPerPixel(localIn
.format
,
255 // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
256 // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
257 // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
258 // restrictions are different.
259 // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
260 // but we use this flag to skip RestoreSurfaceInfo below
262 if ((elemMode
== ADDR_EXPANDED
) && (expandX
> 1))
264 ADDR_ASSERT(IsLinear(localIn
.tileMode
));
267 GetElemLib()->AdjustSurfaceInfo(elemMode
,
275 // Overwrite these parameters if we have a valid format
277 else if (localIn
.bpp
!= 0)
279 localIn
.width
= (localIn
.width
!= 0) ? localIn
.width
: 1;
280 localIn
.height
= (localIn
.height
!= 0) ? localIn
.height
: 1;
282 else // Rule out some invalid parameters
284 ADDR_ASSERT_ALWAYS();
286 returnCode
= ADDR_INVALIDPARAMS
;
289 // Check mipmap after surface expansion
290 if (returnCode
== ADDR_OK
)
292 returnCode
= PostComputeMipLevel(&localIn
, pOut
);
295 if (returnCode
== ADDR_OK
)
297 if (UseTileIndex(localIn
.tileIndex
))
299 // Make sure pTileInfo is not NULL
300 ADDR_ASSERT(localIn
.pTileInfo
);
302 UINT_32 numSamples
= GetNumFragments(localIn
.numSamples
, localIn
.numFrags
);
304 INT_32 macroModeIndex
= TileIndexNoMacroIndex
;
306 if (localIn
.tileIndex
!= TileIndexLinearGeneral
)
308 // Try finding a macroModeIndex
309 macroModeIndex
= HwlComputeMacroModeIndex(localIn
.tileIndex
,
318 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
319 if (macroModeIndex
== TileIndexNoMacroIndex
)
321 returnCode
= HwlSetupTileCfg(localIn
.bpp
,
322 localIn
.tileIndex
, macroModeIndex
,
324 &localIn
.tileMode
, &localIn
.tileType
);
326 // If macroModeIndex is invalid, then assert this is not macro tiled
327 else if (macroModeIndex
== TileIndexInvalid
)
329 ADDR_ASSERT(!IsMacroTiled(localIn
.tileMode
));
332 pOut
->macroModeIndex
= macroModeIndex
;
336 if (returnCode
== ADDR_OK
)
338 localIn
.flags
.dccPipeWorkaround
= localIn
.flags
.dccCompatible
;
340 if (localIn
.tileMode
== ADDR_TM_UNKNOWN
)
342 // HWL layer may override tile mode if necessary
343 HwlSelectTileMode(&localIn
);
347 // HWL layer may override tile mode if necessary
348 HwlOverrideTileMode(&localIn
);
350 // Optimize tile mode if possible
351 OptimizeTileMode(&localIn
);
355 // Call main function to compute surface info
356 if (returnCode
== ADDR_OK
)
358 returnCode
= HwlComputeSurfaceInfo(&localIn
, pOut
);
361 if (returnCode
== ADDR_OK
)
363 // Since bpp might be changed we just pass it through
364 pOut
->bpp
= localIn
.bpp
;
366 // Also original width/height/bpp
367 pOut
->pixelPitch
= pOut
->pitch
;
368 pOut
->pixelHeight
= pOut
->height
;
371 if (localIn
.flags
.display
)
373 ADDR_ASSERT((pOut
->pitchAlign
% 32) == 0);
377 if (localIn
.format
!= ADDR_FMT_INVALID
)
380 // Note: For 96 bit surface, the pixelPitch returned might be an odd number, but it
381 // is okay to program texture pitch as HW's mip calculator would multiply 3 first,
382 // then do the appropriate paddings (linear alignment requirement and possible the
383 // nearest power-of-two for mipmaps), which results in the original pitch.
385 GetElemLib()->RestoreSurfaceInfo(elemMode
,
393 if (localIn
.flags
.qbStereo
)
395 if (pOut
->pStereoInfo
)
397 ComputeQbStereoInfo(pOut
);
401 if (localIn
.flags
.volume
) // For volume sliceSize equals to all z-slices
403 pOut
->sliceSize
= pOut
->surfSize
;
405 else // For array: sliceSize is likely to have slice-padding (the last one)
407 pOut
->sliceSize
= pOut
->surfSize
/ pOut
->depth
;
410 if (pIn
->numSlices
> 1)
412 // If this is the last slice then add the padding size to this slice
413 if (pIn
->slice
== (pIn
->numSlices
- 1))
415 pOut
->sliceSize
+= pOut
->sliceSize
* (pOut
->depth
- pIn
->numSlices
);
417 else if (m_configFlags
.checkLast2DLevel
)
419 // Reset last2DLevel flag if this is not the last array slice
420 pOut
->last2DLevel
= FALSE
;
425 pOut
->pitchTileMax
= pOut
->pitch
/ 8 - 1;
426 pOut
->heightTileMax
= pOut
->height
/ 8 - 1;
427 pOut
->sliceTileMax
= pOut
->pitch
* pOut
->height
/ 64 - 1;
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
;
902 ****************************************************************************************************
903 * Lib::ComputeFmaskAddrFromCoord
906 * Interface function stub of ComputeFmaskAddrFromCoord.
910 ****************************************************************************************************
912 ADDR_E_RETURNCODE
Lib::ComputeFmaskAddrFromCoord(
913 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
914 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
917 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
919 if (GetFillSizeFieldsFlags() == TRUE
)
921 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
)) ||
922 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
)))
924 returnCode
= ADDR_PARAMSIZEMISMATCH
;
928 if (returnCode
== ADDR_OK
)
930 ADDR_ASSERT(pIn
->numSamples
> 1);
932 if (pIn
->numSamples
> 1)
934 returnCode
= HwlComputeFmaskAddrFromCoord(pIn
, pOut
);
938 returnCode
= ADDR_INVALIDPARAMS
;
946 ****************************************************************************************************
947 * Lib::ComputeFmaskCoordFromAddr
950 * Interface function stub of ComputeFmaskAddrFromCoord.
954 ****************************************************************************************************
956 ADDR_E_RETURNCODE
Lib::ComputeFmaskCoordFromAddr(
957 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
958 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
961 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
963 if (GetFillSizeFieldsFlags() == TRUE
)
965 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
)) ||
966 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
)))
968 returnCode
= ADDR_PARAMSIZEMISMATCH
;
972 if (returnCode
== ADDR_OK
)
974 ADDR_ASSERT(pIn
->numSamples
> 1);
976 if (pIn
->numSamples
> 1)
978 returnCode
= HwlComputeFmaskCoordFromAddr(pIn
, pOut
);
982 returnCode
= ADDR_INVALIDPARAMS
;
990 ****************************************************************************************************
991 * Lib::ConvertTileInfoToHW
994 * Convert tile info from real value to HW register value in HW layer
998 ****************************************************************************************************
1000 ADDR_E_RETURNCODE
Lib::ConvertTileInfoToHW(
1001 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
1002 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
1005 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1007 if (GetFillSizeFieldsFlags() == TRUE
)
1009 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT
)) ||
1010 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT
)))
1012 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1016 if (returnCode
== ADDR_OK
)
1018 ADDR_TILEINFO tileInfoNull
;
1019 ADDR_CONVERT_TILEINFOTOHW_INPUT input
;
1020 // if pIn->reverse is TRUE, indices are ignored
1021 if (pIn
->reverse
== FALSE
&& UseTileIndex(pIn
->tileIndex
))
1024 input
.pTileInfo
= &tileInfoNull
;
1026 returnCode
= HwlSetupTileCfg(input
.bpp
, input
.tileIndex
,
1027 input
.macroModeIndex
, input
.pTileInfo
);
1032 if (returnCode
== ADDR_OK
)
1034 returnCode
= HwlConvertTileInfoToHW(pIn
, pOut
);
1042 ****************************************************************************************************
1043 * Lib::ConvertTileIndex
1046 * Convert tile index to tile mode/type/info
1050 ****************************************************************************************************
1052 ADDR_E_RETURNCODE
Lib::ConvertTileIndex(
1053 const ADDR_CONVERT_TILEINDEX_INPUT
* pIn
, ///< [in] input structure
1054 ADDR_CONVERT_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1057 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1059 if (GetFillSizeFieldsFlags() == TRUE
)
1061 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_INPUT
)) ||
1062 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT
)))
1064 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1068 if (returnCode
== ADDR_OK
)
1071 returnCode
= HwlSetupTileCfg(pIn
->bpp
, pIn
->tileIndex
, pIn
->macroModeIndex
,
1072 pOut
->pTileInfo
, &pOut
->tileMode
, &pOut
->tileType
);
1074 if (returnCode
== ADDR_OK
&& pIn
->tileInfoHw
)
1076 ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput
= {0};
1077 ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput
= {0};
1079 hwInput
.pTileInfo
= pOut
->pTileInfo
;
1080 hwInput
.tileIndex
= -1;
1081 hwOutput
.pTileInfo
= pOut
->pTileInfo
;
1083 returnCode
= HwlConvertTileInfoToHW(&hwInput
, &hwOutput
);
1091 ****************************************************************************************************
1092 * Lib::GetMacroModeIndex
1095 * Get macro mode index based on input info
1099 ****************************************************************************************************
1101 ADDR_E_RETURNCODE
Lib::GetMacroModeIndex(
1102 const ADDR_GET_MACROMODEINDEX_INPUT
* pIn
, ///< [in] input structure
1103 ADDR_GET_MACROMODEINDEX_OUTPUT
* pOut
///< [out] output structure
1106 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1108 if (GetFillSizeFieldsFlags())
1110 if ((pIn
->size
!= sizeof(ADDR_GET_MACROMODEINDEX_INPUT
)) ||
1111 (pOut
->size
!= sizeof(ADDR_GET_MACROMODEINDEX_OUTPUT
)))
1113 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1117 if (returnCode
== ADDR_OK
)
1119 ADDR_TILEINFO tileInfo
= {0};
1120 pOut
->macroModeIndex
= HwlComputeMacroModeIndex(pIn
->tileIndex
, pIn
->flags
, pIn
->bpp
,
1121 pIn
->numFrags
, &tileInfo
);
1128 ****************************************************************************************************
1129 * Lib::ConvertTileIndex1
1132 * Convert tile index to tile mode/type/info
1136 ****************************************************************************************************
1138 ADDR_E_RETURNCODE
Lib::ConvertTileIndex1(
1139 const ADDR_CONVERT_TILEINDEX1_INPUT
* pIn
, ///< [in] input structure
1140 ADDR_CONVERT_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1143 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1145 if (GetFillSizeFieldsFlags() == TRUE
)
1147 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINDEX1_INPUT
)) ||
1148 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT
)))
1150 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1154 if (returnCode
== ADDR_OK
)
1156 ADDR_SURFACE_FLAGS flags
= {{0}};
1158 HwlComputeMacroModeIndex(pIn
->tileIndex
, flags
, pIn
->bpp
, pIn
->numSamples
,
1159 pOut
->pTileInfo
, &pOut
->tileMode
, &pOut
->tileType
);
1161 if (pIn
->tileInfoHw
)
1163 ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput
= {0};
1164 ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput
= {0};
1166 hwInput
.pTileInfo
= pOut
->pTileInfo
;
1167 hwInput
.tileIndex
= -1;
1168 hwOutput
.pTileInfo
= pOut
->pTileInfo
;
1170 returnCode
= HwlConvertTileInfoToHW(&hwInput
, &hwOutput
);
1178 ****************************************************************************************************
1182 * Get tile index from tile mode/type/info
1186 ****************************************************************************************************
1188 ADDR_E_RETURNCODE
Lib::GetTileIndex(
1189 const ADDR_GET_TILEINDEX_INPUT
* pIn
, ///< [in] input structure
1190 ADDR_GET_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1193 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1195 if (GetFillSizeFieldsFlags() == TRUE
)
1197 if ((pIn
->size
!= sizeof(ADDR_GET_TILEINDEX_INPUT
)) ||
1198 (pOut
->size
!= sizeof(ADDR_GET_TILEINDEX_OUTPUT
)))
1200 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1204 if (returnCode
== ADDR_OK
)
1206 returnCode
= HwlGetTileIndex(pIn
, pOut
);
1213 ****************************************************************************************************
1217 * Get tile mode thickness
1220 * Tile mode thickness
1221 ****************************************************************************************************
1223 UINT_32
Lib::Thickness(
1224 AddrTileMode tileMode
) ///< [in] tile mode
1226 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
,
1340 ****************************************************************************************************
1341 * Lib::ComputeCmaskInfo
1344 * Interface function stub of AddrComputeCmaskInfo
1348 ****************************************************************************************************
1350 ADDR_E_RETURNCODE
Lib::ComputeCmaskInfo(
1351 const ADDR_COMPUTE_CMASK_INFO_INPUT
* pIn
, ///< [in] input structure
1352 ADDR_COMPUTE_CMASK_INFO_OUTPUT
* pOut
///< [out] output structure
1355 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1357 if (GetFillSizeFieldsFlags() == TRUE
)
1359 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_INFO_INPUT
)) ||
1360 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_INFO_OUTPUT
)))
1362 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1366 if (returnCode
== ADDR_OK
)
1368 ADDR_TILEINFO tileInfoNull
;
1369 ADDR_COMPUTE_CMASK_INFO_INPUT input
;
1371 if (UseTileIndex(pIn
->tileIndex
))
1374 // Use temp tile info for calcalation
1375 input
.pTileInfo
= &tileInfoNull
;
1377 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1379 // Change the input structure
1383 if (returnCode
== ADDR_OK
)
1385 returnCode
= ComputeCmaskInfo(pIn
->flags
,
1406 ****************************************************************************************************
1407 * Lib::ComputeDccInfo
1410 * Interface function to compute DCC key info
1413 * return code of HwlComputeDccInfo
1414 ****************************************************************************************************
1416 ADDR_E_RETURNCODE
Lib::ComputeDccInfo(
1417 const ADDR_COMPUTE_DCCINFO_INPUT
* pIn
, ///< [in] input structure
1418 ADDR_COMPUTE_DCCINFO_OUTPUT
* pOut
///< [out] output structure
1421 ADDR_E_RETURNCODE ret
= ADDR_OK
;
1423 if (GetFillSizeFieldsFlags() == TRUE
)
1425 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_DCCINFO_INPUT
)) ||
1426 (pOut
->size
!= sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT
)))
1428 ret
= ADDR_PARAMSIZEMISMATCH
;
1434 ADDR_COMPUTE_DCCINFO_INPUT input
;
1436 if (UseTileIndex(pIn
->tileIndex
))
1440 ret
= HwlSetupTileCfg(input
.bpp
, input
.tileIndex
, input
.macroModeIndex
,
1441 &input
.tileInfo
, &input
.tileMode
);
1448 ret
= HwlComputeDccInfo(pIn
, pOut
);
1456 ****************************************************************************************************
1457 * Lib::ComputeHtileAddrFromCoord
1460 * Interface function stub of AddrComputeHtileAddrFromCoord
1464 ****************************************************************************************************
1466 ADDR_E_RETURNCODE
Lib::ComputeHtileAddrFromCoord(
1467 const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1468 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1471 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1473 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1474 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1476 if (GetFillSizeFieldsFlags() == TRUE
)
1478 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
)) ||
1479 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
)))
1481 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1485 if (returnCode
== ADDR_OK
)
1487 ADDR_TILEINFO tileInfoNull
;
1488 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT input
;
1490 if (UseTileIndex(pIn
->tileIndex
))
1493 // Use temp tile info for calcalation
1494 input
.pTileInfo
= &tileInfoNull
;
1496 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1498 // Change the input structure
1502 if (returnCode
== ADDR_OK
)
1504 if (pIn
->flags
.tcCompatible
)
1506 HwlComputeHtileAddrFromCoord(pIn
, pOut
);
1510 pOut
->addr
= HwlComputeXmaskAddrFromCoord(pIn
->pitch
,
1521 &pOut
->bitPosition
);
1531 ****************************************************************************************************
1532 * Lib::ComputeHtileCoordFromAddr
1535 * Interface function stub of AddrComputeHtileCoordFromAddr
1539 ****************************************************************************************************
1541 ADDR_E_RETURNCODE
Lib::ComputeHtileCoordFromAddr(
1542 const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
1543 ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
1546 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1548 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1549 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1551 if (GetFillSizeFieldsFlags() == TRUE
)
1553 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT
)) ||
1554 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
)))
1556 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1560 if (returnCode
== ADDR_OK
)
1562 ADDR_TILEINFO tileInfoNull
;
1563 ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT input
;
1565 if (UseTileIndex(pIn
->tileIndex
))
1568 // Use temp tile info for calcalation
1569 input
.pTileInfo
= &tileInfoNull
;
1571 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1573 // Change the input structure
1577 if (returnCode
== ADDR_OK
)
1579 HwlComputeXmaskCoordFromAddr(pIn
->addr
,
1599 ****************************************************************************************************
1600 * Lib::ComputeCmaskAddrFromCoord
1603 * Interface function stub of AddrComputeCmaskAddrFromCoord
1607 ****************************************************************************************************
1609 ADDR_E_RETURNCODE
Lib::ComputeCmaskAddrFromCoord(
1610 const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1611 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1614 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1616 if (GetFillSizeFieldsFlags() == TRUE
)
1618 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
)) ||
1619 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
)))
1621 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1625 if (returnCode
== ADDR_OK
)
1627 ADDR_TILEINFO tileInfoNull
;
1628 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT input
;
1630 if (UseTileIndex(pIn
->tileIndex
))
1633 // Use temp tile info for calcalation
1634 input
.pTileInfo
= &tileInfoNull
;
1636 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1638 // Change the input structure
1642 if (returnCode
== ADDR_OK
)
1644 if (pIn
->flags
.tcCompatible
== TRUE
)
1646 returnCode
= HwlComputeCmaskAddrFromCoord(pIn
, pOut
);
1650 pOut
->addr
= HwlComputeXmaskAddrFromCoord(pIn
->pitch
,
1658 FALSE
, //this is cmask, isWidth8 is not needed
1659 FALSE
, //this is cmask, isHeight8 is not needed
1661 &pOut
->bitPosition
);
1671 ****************************************************************************************************
1672 * Lib::ComputeCmaskCoordFromAddr
1675 * Interface function stub of AddrComputeCmaskCoordFromAddr
1679 ****************************************************************************************************
1681 ADDR_E_RETURNCODE
Lib::ComputeCmaskCoordFromAddr(
1682 const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
1683 ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
1686 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1688 if (GetFillSizeFieldsFlags() == TRUE
)
1690 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT
)) ||
1691 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT
)))
1693 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1697 if (returnCode
== ADDR_OK
)
1699 ADDR_TILEINFO tileInfoNull
;
1700 ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT input
;
1702 if (UseTileIndex(pIn
->tileIndex
))
1705 // Use temp tile info for calcalation
1706 input
.pTileInfo
= &tileInfoNull
;
1708 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1710 // Change the input structure
1714 if (returnCode
== ADDR_OK
)
1716 HwlComputeXmaskCoordFromAddr(pIn
->addr
,
1736 ****************************************************************************************************
1737 * Lib::ComputeTileDataWidthAndHeight
1740 * Compute the squared cache shape for per-tile data (CMASK and HTILE)
1746 * MacroWidth and macroHeight are measured in pixels
1747 ****************************************************************************************************
1749 VOID
Lib::ComputeTileDataWidthAndHeight(
1750 UINT_32 bpp
, ///< [in] bits per pixel
1751 UINT_32 cacheBits
, ///< [in] bits of cache
1752 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1753 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1754 UINT_32
* pMacroHeight
///< [out] macro tile height
1758 UINT_32 width
= cacheBits
/ bpp
;
1759 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
1761 // Double height until the macro-tile is close to square
1762 // Height can only be doubled if width is even
1764 while ((width
> height
* 2 * pipes
) && !(width
& 1))
1770 *pMacroWidth
= 8 * width
;
1771 *pMacroHeight
= 8 * height
* pipes
;
1773 // Note: The above iterative comptuation is equivalent to the following
1775 //int log2_height = ((log2(cacheBits)-log2(bpp)-log2(pipes))/2);
1776 //int macroHeight = pow2( 3+log2(pipes)+log2_height );
1780 ****************************************************************************************************
1781 * Lib::HwlComputeTileDataWidthAndHeightLinear
1784 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1790 * MacroWidth and macroHeight are measured in pixels
1791 ****************************************************************************************************
1793 VOID
Lib::HwlComputeTileDataWidthAndHeightLinear(
1794 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1795 UINT_32
* pMacroHeight
, ///< [out] macro tile height
1796 UINT_32 bpp
, ///< [in] bits per pixel
1797 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
1800 ADDR_ASSERT(bpp
!= 4); // Cmask does not support linear layout prior to SI
1801 *pMacroWidth
= 8 * 512 / bpp
; // Align width to 512-bit memory accesses
1802 *pMacroHeight
= 8 * m_pipes
; // Align height to number of pipes
1806 ****************************************************************************************************
1807 * Lib::ComputeHtileInfo
1810 * Compute htile pitch,width, bytes per 2D slice
1813 * Htile bpp i.e. How many bits for an 8x8 tile
1814 * Also returns by output parameters:
1815 * *Htile pitch, height, total size in bytes, macro-tile dimensions and slice size*
1816 ****************************************************************************************************
1818 UINT_32
Lib::ComputeHtileInfo(
1819 ADDR_HTILE_FLAGS flags
, ///< [in] htile flags
1820 UINT_32 pitchIn
, ///< [in] pitch input
1821 UINT_32 heightIn
, ///< [in] height input
1822 UINT_32 numSlices
, ///< [in] number of slices
1823 BOOL_32 isLinear
, ///< [in] if it is linear mode
1824 BOOL_32 isWidth8
, ///< [in] if htile block width is 8
1825 BOOL_32 isHeight8
, ///< [in] if htile block height is 8
1826 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1827 UINT_32
* pPitchOut
, ///< [out] pitch output
1828 UINT_32
* pHeightOut
, ///< [out] height output
1829 UINT_64
* pHtileBytes
, ///< [out] bytes per 2D slice
1830 UINT_32
* pMacroWidth
, ///< [out] macro-tile width in pixels
1831 UINT_32
* pMacroHeight
, ///< [out] macro-tile width in pixels
1832 UINT_64
* pSliceSize
, ///< [out] slice size in bytes
1833 UINT_32
* pBaseAlign
///< [out] base alignment
1838 UINT_32 macroHeight
;
1843 numSlices
= Max(1u, numSlices
);
1845 const UINT_32 bpp
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
1846 const UINT_32 cacheBits
= HtileCacheBits
;
1850 HwlComputeTileDataWidthAndHeightLinear(¯oWidth
,
1857 ComputeTileDataWidthAndHeight(bpp
,
1864 *pPitchOut
= PowTwoAlign(pitchIn
, macroWidth
);
1865 *pHeightOut
= PowTwoAlign(heightIn
, macroHeight
);
1867 baseAlign
= HwlComputeHtileBaseAlign(flags
.tcCompatible
, isLinear
, pTileInfo
);
1869 surfBytes
= HwlComputeHtileBytes(*pPitchOut
,
1877 *pHtileBytes
= surfBytes
;
1880 // Use SafeAssign since they are optional
1882 SafeAssign(pMacroWidth
, macroWidth
);
1884 SafeAssign(pMacroHeight
, macroHeight
);
1886 SafeAssign(pSliceSize
, sliceBytes
);
1888 SafeAssign(pBaseAlign
, baseAlign
);
1894 ****************************************************************************************************
1895 * Lib::ComputeCmaskBaseAlign
1898 * Compute cmask base alignment
1901 * Cmask base alignment
1902 ****************************************************************************************************
1904 UINT_32
Lib::ComputeCmaskBaseAlign(
1905 ADDR_CMASK_FLAGS flags
, ///< [in] Cmask flags
1906 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
1909 UINT_32 baseAlign
= m_pipeInterleaveBytes
* HwlGetPipes(pTileInfo
);
1911 if (flags
.tcCompatible
)
1913 ADDR_ASSERT(pTileInfo
!= NULL
);
1916 baseAlign
*= pTileInfo
->banks
;
1924 ****************************************************************************************************
1925 * Lib::ComputeCmaskBytes
1928 * Compute cmask size in bytes
1931 * Cmask size in bytes
1932 ****************************************************************************************************
1934 UINT_64
Lib::ComputeCmaskBytes(
1935 UINT_32 pitch
, ///< [in] pitch
1936 UINT_32 height
, ///< [in] height
1937 UINT_32 numSlices
///< [in] number of slices
1940 return BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* numSlices
* CmaskElemBits
) /
1945 ****************************************************************************************************
1946 * Lib::ComputeCmaskInfo
1949 * Compute cmask pitch,width, bytes per 2D slice
1952 * BlockMax. Also by output parameters: Cmask pitch,height, total size in bytes,
1953 * macro-tile dimensions
1954 ****************************************************************************************************
1956 ADDR_E_RETURNCODE
Lib::ComputeCmaskInfo(
1957 ADDR_CMASK_FLAGS flags
, ///< [in] cmask flags
1958 UINT_32 pitchIn
, ///< [in] pitch input
1959 UINT_32 heightIn
, ///< [in] height input
1960 UINT_32 numSlices
, ///< [in] number of slices
1961 BOOL_32 isLinear
, ///< [in] is linear mode
1962 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1963 UINT_32
* pPitchOut
, ///< [out] pitch output
1964 UINT_32
* pHeightOut
, ///< [out] height output
1965 UINT_64
* pCmaskBytes
, ///< [out] bytes per 2D slice
1966 UINT_32
* pMacroWidth
, ///< [out] macro-tile width in pixels
1967 UINT_32
* pMacroHeight
, ///< [out] macro-tile width in pixels
1968 UINT_64
* pSliceSize
, ///< [out] slice size in bytes
1969 UINT_32
* pBaseAlign
, ///< [out] base alignment
1970 UINT_32
* pBlockMax
///< [out] block max == slice / 128 / 128 - 1
1974 UINT_32 macroHeight
;
1979 numSlices
= Max(1u, numSlices
);
1981 const UINT_32 bpp
= CmaskElemBits
;
1982 const UINT_32 cacheBits
= CmaskCacheBits
;
1984 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1988 HwlComputeTileDataWidthAndHeightLinear(¯oWidth
,
1995 ComputeTileDataWidthAndHeight(bpp
,
2002 *pPitchOut
= (pitchIn
+ macroWidth
- 1) & ~(macroWidth
- 1);
2003 *pHeightOut
= (heightIn
+ macroHeight
- 1) & ~(macroHeight
- 1);
2006 sliceBytes
= ComputeCmaskBytes(*pPitchOut
,
2010 baseAlign
= ComputeCmaskBaseAlign(flags
, pTileInfo
);
2012 while (sliceBytes
% baseAlign
)
2014 *pHeightOut
+= macroHeight
;
2016 sliceBytes
= ComputeCmaskBytes(*pPitchOut
,
2021 surfBytes
= sliceBytes
* numSlices
;
2023 *pCmaskBytes
= surfBytes
;
2026 // Use SafeAssign since they are optional
2028 SafeAssign(pMacroWidth
, macroWidth
);
2030 SafeAssign(pMacroHeight
, macroHeight
);
2032 SafeAssign(pBaseAlign
, baseAlign
);
2034 SafeAssign(pSliceSize
, sliceBytes
);
2036 UINT_32 slice
= (*pPitchOut
) * (*pHeightOut
);
2037 UINT_32 blockMax
= slice
/ 128 / 128 - 1;
2040 if (slice
% (64*256) != 0)
2042 ADDR_ASSERT_ALWAYS();
2046 UINT_32 maxBlockMax
= HwlGetMaxCmaskBlockMax();
2048 if (blockMax
> maxBlockMax
)
2050 blockMax
= maxBlockMax
;
2051 returnCode
= ADDR_INVALIDPARAMS
;
2054 SafeAssign(pBlockMax
, blockMax
);
2060 ****************************************************************************************************
2061 * Lib::ComputeXmaskCoordYFromPipe
2064 * Compute the Y coord from pipe number for cmask/htile
2069 ****************************************************************************************************
2071 UINT_32
Lib::ComputeXmaskCoordYFromPipe(
2072 UINT_32 pipe
, ///< [in] pipe number
2073 UINT_32 x
///< [in] x coordinate
2085 UINT_32 numPipes
= m_pipes
; // SI has its implementation
2087 // Convert pipe + x to y coordinate.
2107 pipeBit0
= pipe
& 0x1;
2111 yBit0
= pipeBit0
^ xBit0
;
2125 pipeBit0
= pipe
& 0x1;
2126 pipeBit1
= (pipe
& 0x2) >> 1;
2129 xBit1
= (x
& 0x2) >> 1;
2131 yBit0
= pipeBit0
^ xBit1
;
2132 yBit1
= pipeBit1
^ xBit0
;
2141 // r600 and r800 have different method
2143 y
= HwlComputeXmaskCoordYFrom8Pipe(pipe
, x
);
2152 ****************************************************************************************************
2153 * Lib::HwlComputeXmaskCoordFromAddr
2156 * Compute the coord from an address of a cmask/htile
2162 * This method is reused by htile, so rename to Xmask
2163 ****************************************************************************************************
2165 VOID
Lib::HwlComputeXmaskCoordFromAddr(
2166 UINT_64 addr
, ///< [in] address
2167 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2168 UINT_32 pitch
, ///< [in] pitch
2169 UINT_32 height
, ///< [in] height
2170 UINT_32 numSlices
, ///< [in] number of slices
2171 UINT_32 factor
, ///< [in] factor that indicates cmask or htile
2172 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
2173 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2174 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2175 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
2176 UINT_32
* pX
, ///< [out] x coord
2177 UINT_32
* pY
, ///< [out] y coord
2178 UINT_32
* pSlice
///< [out] slice index
2183 UINT_32 numGroupBits
;
2185 UINT_32 numPipeBits
;
2186 UINT_32 macroTilePitch
;
2187 UINT_32 macroTileHeight
;
2191 UINT_32 microTileCoordY
;
2195 UINT_32 pitchAligned
= pitch
;
2196 UINT_32 heightAligned
= height
;
2204 UINT_64 macroNumber
;
2205 UINT_32 microNumber
;
2214 UINT_32 tilesPerMacro
;
2215 UINT_32 macrosPerPitch
;
2216 UINT_32 macrosPerSlice
;
2221 numPipes
= HwlGetPipes(pTileInfo
);
2222 pipe
= ComputePipeFromAddr(addr
, numPipes
);
2225 // Compute the number of group and pipe bits.
2227 numGroupBits
= Log2(m_pipeInterleaveBytes
);
2228 numPipeBits
= Log2(numPipes
);
2230 UINT_32 groupBits
= 8 * m_pipeInterleaveBytes
;
2231 UINT_32 pipes
= numPipes
;
2235 // Compute the micro tile size, in bits. And macro tile pitch and height.
2237 if (factor
== 2) //CMASK
2239 ADDR_CMASK_FLAGS flags
= {{0}};
2241 elemBits
= CmaskElemBits
;
2243 ComputeCmaskInfo(flags
,
2257 ADDR_HTILE_FLAGS flags
= {{0}};
2264 elemBits
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
2266 ComputeHtileInfo(flags
,
2281 // Should use aligned dims
2283 pitch
= pitchAligned
;
2284 height
= heightAligned
;
2288 // Convert byte address to bit address.
2290 bitAddr
= BYTES_TO_BITS(addr
) + bitPosition
;
2294 // Remove pipe bits from address.
2297 bitAddr
= (bitAddr
% groupBits
) + ((bitAddr
/groupBits
/pipes
)*groupBits
);
2300 elemOffset
= bitAddr
/ elemBits
;
2302 tilesPerMacro
= (macroTilePitch
/factor
) * macroTileHeight
/ MicroTilePixels
>> numPipeBits
;
2304 macrosPerPitch
= pitch
/ (macroTilePitch
/factor
);
2305 macrosPerSlice
= macrosPerPitch
* height
/ macroTileHeight
;
2307 macroIndex
= elemOffset
/ factor
/ tilesPerMacro
;
2308 microIndex
= static_cast<UINT_32
>(elemOffset
% (tilesPerMacro
* factor
));
2310 macroNumber
= macroIndex
* factor
+ microIndex
% factor
;
2311 microNumber
= microIndex
/ factor
;
2313 macroX
= static_cast<UINT_32
>((macroNumber
% macrosPerPitch
));
2314 macroY
= static_cast<UINT_32
>((macroNumber
% macrosPerSlice
) / macrosPerPitch
);
2315 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
);
2330 // Assemble final coordinates.
2332 *pY
+= microTileCoordY
* MicroTileHeight
;
2337 ****************************************************************************************************
2338 * Lib::HwlComputeXmaskAddrFromCoord
2341 * Compute the address from an address of cmask (prior to si)
2346 ****************************************************************************************************
2348 UINT_64
Lib::HwlComputeXmaskAddrFromCoord(
2349 UINT_32 pitch
, ///< [in] pitch
2350 UINT_32 height
, ///< [in] height
2351 UINT_32 x
, ///< [in] x coord
2352 UINT_32 y
, ///< [in] y coord
2353 UINT_32 slice
, ///< [in] slice/depth index
2354 UINT_32 numSlices
, ///< [in] number of slices
2355 UINT_32 factor
, ///< [in] factor that indicates cmask(2) or htile(1)
2356 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
2357 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2358 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2359 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
2360 UINT_32
* pBitPosition
///< [out] bit position inside a byte
2364 UINT_32 numGroupBits
;
2365 UINT_32 numPipeBits
;
2366 UINT_32 newPitch
= 0;
2367 UINT_32 newHeight
= 0;
2368 UINT_64 sliceBytes
= 0;
2369 UINT_64 totalBytes
= 0;
2370 UINT_64 sliceOffset
;
2372 UINT_32 macroTileWidth
;
2373 UINT_32 macroTileHeight
;
2374 UINT_32 macroTilesPerRow
;
2375 UINT_32 macroTileBytes
;
2376 UINT_32 macroTileIndexX
;
2377 UINT_32 macroTileIndexY
;
2378 UINT_64 macroTileOffset
;
2379 UINT_32 pixelBytesPerRow
;
2380 UINT_32 pixelOffsetX
;
2381 UINT_32 pixelOffsetY
;
2382 UINT_32 pixelOffset
;
2383 UINT_64 totalOffset
;
2389 UINT_32 elemBits
= 0;
2391 UINT_32 numPipes
= m_pipes
; // This function is accessed prior to si only
2393 if (factor
== 2) //CMASK
2395 elemBits
= CmaskElemBits
;
2397 // For asics before SI, cmask is always tiled
2402 if (factor
!= 1) // Fix compile warning
2407 elemBits
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
2411 // Compute the number of group bits and pipe bits.
2413 numGroupBits
= Log2(m_pipeInterleaveBytes
);
2414 numPipeBits
= Log2(numPipes
);
2417 // Compute macro tile dimensions.
2419 if (factor
== 2) // CMASK
2421 ADDR_CMASK_FLAGS flags
= {{0}};
2423 ComputeCmaskInfo(flags
,
2435 sliceBytes
= totalBytes
/ numSlices
;
2439 ADDR_HTILE_FLAGS flags
= {{0}};
2441 ComputeHtileInfo(flags
,
2457 sliceOffset
= slice
* sliceBytes
;
2460 // Get the pipe. Note that neither slice rotation nor pipe swizzling apply for CMASK.
2462 pipe
= ComputePipeFromCoord(x
,
2465 ADDR_TM_2D_TILED_THIN1
,
2471 // Compute the number of macro tiles per row.
2473 macroTilesPerRow
= newPitch
/ macroTileWidth
;
2476 // Compute the number of bytes per macro tile.
2478 macroTileBytes
= BITS_TO_BYTES((macroTileWidth
* macroTileHeight
* elemBits
) / MicroTilePixels
);
2481 // Compute the offset to the macro tile containing the specified coordinate.
2483 macroTileIndexX
= x
/ macroTileWidth
;
2484 macroTileIndexY
= y
/ macroTileHeight
;
2485 macroTileOffset
= ((macroTileIndexY
* macroTilesPerRow
) + macroTileIndexX
) * macroTileBytes
;
2488 // Compute the pixel offset within the macro tile.
2490 pixelBytesPerRow
= BITS_TO_BYTES(macroTileWidth
* elemBits
) / MicroTileWidth
;
2493 // The nibbles are interleaved (see below), so the part of the offset relative to the x
2494 // coordinate repeats halfway across the row. (Not for HTILE)
2498 pixelOffsetX
= (x
% (macroTileWidth
/ 2)) / MicroTileWidth
;
2502 pixelOffsetX
= (x
% (macroTileWidth
)) / MicroTileWidth
* BITS_TO_BYTES(elemBits
);
2506 // Compute the y offset within the macro tile.
2508 pixelOffsetY
= (((y
% macroTileHeight
) / MicroTileHeight
) / numPipes
) * pixelBytesPerRow
;
2510 pixelOffset
= pixelOffsetX
+ pixelOffsetY
;
2513 // Combine the slice offset and macro tile offset with the pixel offset, accounting for the
2514 // pipe bits in the middle of the address.
2516 totalOffset
= ((sliceOffset
+ macroTileOffset
) >> numPipeBits
) + pixelOffset
;
2519 // Split the offset to put some bits below the pipe bits and some above.
2521 groupMask
= (1 << numGroupBits
) - 1;
2522 offsetLo
= totalOffset
& groupMask
;
2523 offsetHi
= (totalOffset
& ~groupMask
) << numPipeBits
;
2526 // Assemble the address from its components.
2530 // This is to remove warning with /analyze option
2531 UINT_32 pipeBits
= pipe
<< numGroupBits
;
2535 // Compute the bit position. The lower nibble is used when the x coordinate within the macro
2536 // tile is less than half of the macro tile width, and the upper nibble is used when the x
2537 // coordinate within the macro tile is greater than or equal to half the macro tile width.
2539 *pBitPosition
= ((x
% macroTileWidth
) < (macroTileWidth
/ factor
)) ? 0 : 4;
2544 ////////////////////////////////////////////////////////////////////////////////////////////////////
2545 // Surface Addressing Shared
2546 ////////////////////////////////////////////////////////////////////////////////////////////////////
2549 ****************************************************************************************************
2550 * Lib::ComputeSurfaceAddrFromCoordLinear
2553 * Compute address from coord for linear surface
2558 ****************************************************************************************************
2560 UINT_64
Lib::ComputeSurfaceAddrFromCoordLinear(
2561 UINT_32 x
, ///< [in] x coord
2562 UINT_32 y
, ///< [in] y coord
2563 UINT_32 slice
, ///< [in] slice/depth index
2564 UINT_32 sample
, ///< [in] sample index
2565 UINT_32 bpp
, ///< [in] bits per pixel
2566 UINT_32 pitch
, ///< [in] pitch
2567 UINT_32 height
, ///< [in] height
2568 UINT_32 numSlices
, ///< [in] number of slices
2569 UINT_32
* pBitPosition
///< [out] bit position inside a byte
2572 const UINT_64 sliceSize
= static_cast<UINT_64
>(pitch
) * height
;
2574 UINT_64 sliceOffset
= (slice
+ sample
* numSlices
)* sliceSize
;
2575 UINT_64 rowOffset
= static_cast<UINT_64
>(y
) * pitch
;
2576 UINT_64 pixOffset
= x
;
2578 UINT_64 addr
= (sliceOffset
+ rowOffset
+ pixOffset
) * bpp
;
2580 *pBitPosition
= static_cast<UINT_32
>(addr
% 8);
2587 ****************************************************************************************************
2588 * Lib::ComputeSurfaceCoordFromAddrLinear
2591 * Compute the coord from an address of a linear surface
2595 ****************************************************************************************************
2597 VOID
Lib::ComputeSurfaceCoordFromAddrLinear(
2598 UINT_64 addr
, ///< [in] address
2599 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2600 UINT_32 bpp
, ///< [in] bits per pixel
2601 UINT_32 pitch
, ///< [in] pitch
2602 UINT_32 height
, ///< [in] height
2603 UINT_32 numSlices
, ///< [in] number of slices
2604 UINT_32
* pX
, ///< [out] x coord
2605 UINT_32
* pY
, ///< [out] y coord
2606 UINT_32
* pSlice
, ///< [out] slice/depth index
2607 UINT_32
* pSample
///< [out] sample index
2610 const UINT_64 sliceSize
= static_cast<UINT_64
>(pitch
) * height
;
2611 const UINT_64 linearOffset
= (BYTES_TO_BITS(addr
) + bitPosition
) / bpp
;
2613 *pX
= static_cast<UINT_32
>((linearOffset
% sliceSize
) % pitch
);
2614 *pY
= static_cast<UINT_32
>((linearOffset
% sliceSize
) / pitch
% height
);
2615 *pSlice
= static_cast<UINT_32
>((linearOffset
/ sliceSize
) % numSlices
);
2616 *pSample
= static_cast<UINT_32
>((linearOffset
/ sliceSize
) / numSlices
);
2620 ****************************************************************************************************
2621 * Lib::ComputeSurfaceCoordFromAddrMicroTiled
2624 * Compute the coord from an address of a micro tiled surface
2628 ****************************************************************************************************
2630 VOID
Lib::ComputeSurfaceCoordFromAddrMicroTiled(
2631 UINT_64 addr
, ///< [in] address
2632 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2633 UINT_32 bpp
, ///< [in] bits per pixel
2634 UINT_32 pitch
, ///< [in] pitch
2635 UINT_32 height
, ///< [in] height
2636 UINT_32 numSamples
, ///< [in] number of samples
2637 AddrTileMode tileMode
, ///< [in] tile mode
2638 UINT_32 tileBase
, ///< [in] base offset within a tile
2639 UINT_32 compBits
, ///< [in] component bits actually needed(for planar surface)
2640 UINT_32
* pX
, ///< [out] x coord
2641 UINT_32
* pY
, ///< [out] y coord
2642 UINT_32
* pSlice
, ///< [out] slice/depth index
2643 UINT_32
* pSample
, ///< [out] sample index,
2644 AddrTileType microTileType
, ///< [in] micro tiling order
2645 BOOL_32 isDepthSampleOrder
///< [in] TRUE if in depth sample order
2649 UINT_32 microTileThickness
;
2650 UINT_32 microTileBits
;
2654 UINT_32 microTileCoordX
;
2655 UINT_32 microTileCoordY
;
2656 UINT_32 pixelOffset
;
2657 UINT_32 pixelCoordX
= 0;
2658 UINT_32 pixelCoordY
= 0;
2659 UINT_32 pixelCoordZ
= 0;
2660 UINT_32 pixelCoordS
= 0;
2663 // Convert byte address to bit address.
2665 bitAddr
= BYTES_TO_BITS(addr
) + bitPosition
;
2668 // Compute the micro tile size, in bits.
2672 case ADDR_TM_1D_TILED_THICK
:
2673 microTileThickness
= ThickTileThickness
;
2676 microTileThickness
= 1;
2680 microTileBits
= MicroTilePixels
* microTileThickness
* bpp
* numSamples
;
2683 // Compute number of bits per slice and number of bits per row of micro tiles.
2685 sliceBits
= static_cast<UINT_64
>(pitch
) * height
* microTileThickness
* bpp
* numSamples
;
2687 rowBits
= (pitch
/ MicroTileWidth
) * microTileBits
;
2690 // Extract the slice index.
2692 sliceIndex
= static_cast<UINT_32
>(bitAddr
/ sliceBits
);
2693 bitAddr
-= sliceIndex
* sliceBits
;
2696 // Extract the y coordinate of the micro tile.
2698 microTileCoordY
= static_cast<UINT_32
>(bitAddr
/ rowBits
) * MicroTileHeight
;
2699 bitAddr
-= (microTileCoordY
/ MicroTileHeight
) * rowBits
;
2702 // Extract the x coordinate of the micro tile.
2704 microTileCoordX
= static_cast<UINT_32
>(bitAddr
/ microTileBits
) * MicroTileWidth
;
2707 // Compute the pixel offset within the micro tile.
2709 pixelOffset
= static_cast<UINT_32
>(bitAddr
% microTileBits
);
2712 // Extract pixel coordinates from the offset.
2714 HwlComputePixelCoordFromOffset(pixelOffset
,
2725 isDepthSampleOrder
);
2728 // Assemble final coordinates.
2730 *pX
= microTileCoordX
+ pixelCoordX
;
2731 *pY
= microTileCoordY
+ pixelCoordY
;
2732 *pSlice
= (sliceIndex
* microTileThickness
) + pixelCoordZ
;
2733 *pSample
= pixelCoordS
;
2735 if (microTileThickness
> 1)
2742 ****************************************************************************************************
2743 * Lib::ComputePipeFromAddr
2746 * Compute the pipe number from an address
2751 ****************************************************************************************************
2753 UINT_32
Lib::ComputePipeFromAddr(
2754 UINT_64 addr
, ///< [in] address
2755 UINT_32 numPipes
///< [in] number of banks
2760 UINT_32 groupBytes
= m_pipeInterleaveBytes
; //just different terms
2763 // The LSBs of the address are arranged as follows:
2764 // bank | pipe | group
2766 // To get the pipe number, shift off the group bits and mask the pipe bits.
2770 // The LSBs of the address are arranged as follows:
2771 // bank | bankInterleave | pipe | pipeInterleave
2773 // To get the pipe number, shift off the pipe interleave bits and mask the pipe bits.
2776 pipe
= static_cast<UINT_32
>(addr
>> Log2(groupBytes
)) & (numPipes
- 1);
2782 ****************************************************************************************************
2783 * Lib::ComputeMicroTileEquation
2786 * Compute micro tile equation
2789 * If equation can be computed
2791 ****************************************************************************************************
2793 ADDR_E_RETURNCODE
Lib::ComputeMicroTileEquation(
2794 UINT_32 log2BytesPP
, ///< [in] log2 of bytes per pixel
2795 AddrTileMode tileMode
, ///< [in] tile mode
2796 AddrTileType microTileType
, ///< [in] pixel order in display/non-display mode
2797 ADDR_EQUATION
* pEquation
///< [out] equation
2800 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
2802 for (UINT_32 i
= 0; i
< log2BytesPP
; i
++)
2804 pEquation
->addr
[i
].valid
= 1;
2805 pEquation
->addr
[i
].channel
= 0;
2806 pEquation
->addr
[i
].index
= i
;
2809 ADDR_CHANNEL_SETTING
* pixelBit
= &pEquation
->addr
[log2BytesPP
];
2811 ADDR_CHANNEL_SETTING x0
= InitChannel(1, 0, log2BytesPP
+ 0);
2812 ADDR_CHANNEL_SETTING x1
= InitChannel(1, 0, log2BytesPP
+ 1);
2813 ADDR_CHANNEL_SETTING x2
= InitChannel(1, 0, log2BytesPP
+ 2);
2814 ADDR_CHANNEL_SETTING y0
= InitChannel(1, 1, 0);
2815 ADDR_CHANNEL_SETTING y1
= InitChannel(1, 1, 1);
2816 ADDR_CHANNEL_SETTING y2
= InitChannel(1, 1, 2);
2817 ADDR_CHANNEL_SETTING z0
= InitChannel(1, 2, 0);
2818 ADDR_CHANNEL_SETTING z1
= InitChannel(1, 2, 1);
2819 ADDR_CHANNEL_SETTING z2
= InitChannel(1, 2, 2);
2821 UINT_32 thickness
= Thickness(tileMode
);
2822 UINT_32 bpp
= 1 << (log2BytesPP
+ 3);
2824 if (microTileType
!= ADDR_THICK
)
2826 if (microTileType
== ADDR_DISPLAYABLE
)
2871 ADDR_ASSERT_ALWAYS();
2875 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2884 else if (microTileType
== ADDR_ROTATED
)
2886 ADDR_ASSERT(thickness
== 1);
2923 retCode
= ADDR_NOTSUPPORTED
;
2932 pEquation
->numBits
= 8 + log2BytesPP
;
2936 pEquation
->numBits
= 6 + log2BytesPP
;
2941 ADDR_ASSERT(thickness
> 1);
2972 ADDR_ASSERT_ALWAYS();
2978 pEquation
->numBits
= 8 + log2BytesPP
;
2984 pEquation
->numBits
= 9 + log2BytesPP
;
2987 // stackedDepthSlices is used for addressing mode that a tile block contains multiple slices,
2988 // which is not supported by our address lib
2989 pEquation
->stackedDepthSlices
= FALSE
;
2995 ****************************************************************************************************
2996 * Lib::ComputePixelIndexWithinMicroTile
2999 * Compute the pixel index inside a micro tile of surface
3004 ****************************************************************************************************
3006 UINT_32
Lib::ComputePixelIndexWithinMicroTile(
3007 UINT_32 x
, ///< [in] x coord
3008 UINT_32 y
, ///< [in] y coord
3009 UINT_32 z
, ///< [in] slice/depth index
3010 UINT_32 bpp
, ///< [in] bits per pixel
3011 AddrTileMode tileMode
, ///< [in] tile mode
3012 AddrTileType microTileType
///< [in] pixel order in display/non-display mode
3015 UINT_32 pixelBit0
= 0;
3016 UINT_32 pixelBit1
= 0;
3017 UINT_32 pixelBit2
= 0;
3018 UINT_32 pixelBit3
= 0;
3019 UINT_32 pixelBit4
= 0;
3020 UINT_32 pixelBit5
= 0;
3021 UINT_32 pixelBit6
= 0;
3022 UINT_32 pixelBit7
= 0;
3023 UINT_32 pixelBit8
= 0;
3024 UINT_32 pixelNumber
;
3026 UINT_32 x0
= _BIT(x
, 0);
3027 UINT_32 x1
= _BIT(x
, 1);
3028 UINT_32 x2
= _BIT(x
, 2);
3029 UINT_32 y0
= _BIT(y
, 0);
3030 UINT_32 y1
= _BIT(y
, 1);
3031 UINT_32 y2
= _BIT(y
, 2);
3032 UINT_32 z0
= _BIT(z
, 0);
3033 UINT_32 z1
= _BIT(z
, 1);
3034 UINT_32 z2
= _BIT(z
, 2);
3036 UINT_32 thickness
= Thickness(tileMode
);
3038 // Compute the pixel number within the micro tile.
3040 if (microTileType
!= ADDR_THICK
)
3042 if (microTileType
== ADDR_DISPLAYABLE
)
3087 ADDR_ASSERT_ALWAYS();
3091 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
3100 else if (microTileType
== ADDR_ROTATED
)
3102 ADDR_ASSERT(thickness
== 1);
3139 ADDR_ASSERT_ALWAYS();
3152 ADDR_ASSERT(thickness
> 1);
3183 ADDR_ASSERT_ALWAYS();
3196 pixelNumber
= ((pixelBit0
) |
3210 ****************************************************************************************************
3211 * Lib::AdjustPitchAlignment
3214 * Adjusts pitch alignment for flipping surface
3219 ****************************************************************************************************
3221 VOID
Lib::AdjustPitchAlignment(
3222 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface flags
3223 UINT_32
* pPitchAlign
///< [out] Pointer to pitch alignment
3226 // Display engine hardwires lower 5 bit of GRPH_PITCH to ZERO which means 32 pixel alignment
3227 // Maybe it will be fixed in future but let's make it general for now.
3228 if (flags
.display
|| flags
.overlay
)
3230 *pPitchAlign
= PowTwoAlign(*pPitchAlign
, 32);
3234 *pPitchAlign
= Max(m_minPitchAlignPixels
, *pPitchAlign
);
3240 ****************************************************************************************************
3241 * Lib::PadDimensions
3244 * Helper function to pad dimensions
3249 ****************************************************************************************************
3251 VOID
Lib::PadDimensions(
3252 AddrTileMode tileMode
, ///< [in] tile mode
3253 UINT_32 bpp
, ///< [in] bits per pixel
3254 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
3255 UINT_32 numSamples
, ///< [in] number of samples
3256 ADDR_TILEINFO
* pTileInfo
, ///< [in,out] bank structure.
3257 UINT_32 padDims
, ///< [in] Dimensions to pad valid value 1,2,3
3258 UINT_32 mipLevel
, ///< [in] MipLevel
3259 UINT_32
* pPitch
, ///< [in,out] pitch in pixels
3260 UINT_32
* pPitchAlign
, ///< [in,out] pitch align could be changed in HwlPadDimensions
3261 UINT_32
* pHeight
, ///< [in,out] height in pixels
3262 UINT_32 heightAlign
, ///< [in] height alignment
3263 UINT_32
* pSlices
, ///< [in,out] number of slices
3264 UINT_32 sliceAlign
///< [in] number of slice alignment
3267 UINT_32 pitchAlign
= *pPitchAlign
;
3268 UINT_32 thickness
= Thickness(tileMode
);
3270 ADDR_ASSERT(padDims
<= 3);
3273 // Override padding for mip levels
3279 // for cubemap, we only pad when client call with 6 faces as an identity
3282 padDims
= 3; // we should pad cubemap sub levels when we treat it as 3d texture
3291 // Any possibilities that padDims is 0?
3297 if (IsPow2(pitchAlign
))
3299 *pPitch
= PowTwoAlign((*pPitch
), pitchAlign
);
3301 else // add this code to pass unit test, r600 linear mode is not align bpp to pow2 for linear
3303 *pPitch
+= pitchAlign
- 1;
3304 *pPitch
/= pitchAlign
;
3305 *pPitch
*= pitchAlign
;
3310 if (IsPow2(heightAlign
))
3312 *pHeight
= PowTwoAlign((*pHeight
), heightAlign
);
3316 *pHeight
+= heightAlign
- 1;
3317 *pHeight
/= heightAlign
;
3318 *pHeight
*= heightAlign
;
3322 if (padDims
> 2 || thickness
> 1)
3324 // for cubemap single face, we do not pad slices.
3325 // if we pad it, the slice number should be set to 6 and current mip level > 1
3326 if (flags
.cube
&& (!m_configFlags
.noCubeMipSlicesPad
|| flags
.cubeAsArray
))
3328 *pSlices
= NextPow2(*pSlices
);
3331 // normal 3D texture or arrays or cubemap has a thick mode? (Just pass unit test)
3334 *pSlices
= PowTwoAlign((*pSlices
), sliceAlign
);
3339 HwlPadDimensions(tileMode
,
3353 ****************************************************************************************************
3354 * Lib::HwlPreHandleBaseLvl3xPitch
3357 * Pre-handler of 3x pitch (96 bit) adjustment
3361 ****************************************************************************************************
3363 UINT_32
Lib::HwlPreHandleBaseLvl3xPitch(
3364 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
3365 UINT_32 expPitch
///< [in] pitch
3368 ADDR_ASSERT(pIn
->width
== expPitch
);
3370 // If pitch is pre-multiplied by 3, we retrieve original one here to get correct miplevel size
3372 if (ElemLib::IsExpand3x(pIn
->format
) &&
3373 pIn
->mipLevel
== 0 &&
3374 pIn
->tileMode
== ADDR_TM_LINEAR_ALIGNED
)
3377 expPitch
= NextPow2(expPitch
);
3384 ****************************************************************************************************
3385 * Lib::HwlPostHandleBaseLvl3xPitch
3388 * Post-handler of 3x pitch adjustment
3392 ****************************************************************************************************
3394 UINT_32
Lib::HwlPostHandleBaseLvl3xPitch(
3395 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
3396 UINT_32 expPitch
///< [in] pitch
3400 // 96 bits surface of sub levels require element pitch of 32 bits instead
3401 // So we just return pitch in 32 bit pixels without timing 3
3403 if (ElemLib::IsExpand3x(pIn
->format
) &&
3404 pIn
->mipLevel
== 0 &&
3405 pIn
->tileMode
== ADDR_TM_LINEAR_ALIGNED
)
3415 ****************************************************************************************************
3419 * Check if the tile mode is macro tiled
3422 * TRUE if it is macro tiled (2D/2B/3D/3B)
3423 ****************************************************************************************************
3425 BOOL_32
Lib::IsMacroTiled(
3426 AddrTileMode tileMode
) ///< [in] tile mode
3428 return ModeFlags
[tileMode
].isMacro
;
3432 ****************************************************************************************************
3433 * Lib::IsMacro3dTiled
3436 * Check if the tile mode is 3D macro tiled
3439 * TRUE if it is 3D macro tiled
3440 ****************************************************************************************************
3442 BOOL_32
Lib::IsMacro3dTiled(
3443 AddrTileMode tileMode
) ///< [in] tile mode
3445 return ModeFlags
[tileMode
].isMacro3d
;
3449 ****************************************************************************************************
3453 * Check if the tile mode is micro tiled
3456 * TRUE if micro tiled
3457 ****************************************************************************************************
3459 BOOL_32
Lib::IsMicroTiled(
3460 AddrTileMode tileMode
) ///< [in] tile mode
3462 return ModeFlags
[tileMode
].isMicro
;
3466 ****************************************************************************************************
3470 * Check if the tile mode is linear
3474 ****************************************************************************************************
3476 BOOL_32
Lib::IsLinear(
3477 AddrTileMode tileMode
) ///< [in] tile mode
3479 return ModeFlags
[tileMode
].isLinear
;
3483 ****************************************************************************************************
3484 * Lib::IsPrtNoRotationTileMode
3487 * Return TRUE if it is prt tile without rotation
3489 * This function just used by CI
3490 ****************************************************************************************************
3492 BOOL_32
Lib::IsPrtNoRotationTileMode(
3493 AddrTileMode tileMode
)
3495 return ModeFlags
[tileMode
].isPrtNoRotation
;
3499 ****************************************************************************************************
3500 * Lib::IsPrtTileMode
3503 * Return TRUE if it is prt tile
3505 * This function just used by CI
3506 ****************************************************************************************************
3508 BOOL_32
Lib::IsPrtTileMode(
3509 AddrTileMode tileMode
)
3511 return ModeFlags
[tileMode
].isPrt
;
3515 ****************************************************************************************************
3516 * Lib::ComputeMipLevel
3519 * Compute mipmap level width/height/slices
3522 ****************************************************************************************************
3524 VOID
Lib::ComputeMipLevel(
3525 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
///< [in,out] Input structure
3528 // Check if HWL has handled
3529 BOOL_32 hwlHandled
= FALSE
;
3532 if (ElemLib::IsBlockCompressed(pIn
->format
))
3534 if (pIn
->mipLevel
== 0)
3536 // DXTn's level 0 must be multiple of 4
3537 // But there are exceptions:
3538 // 1. Internal surface creation in hostblt/vsblt/etc...
3539 // 2. Runtime doesn't reject ATI1/ATI2 whose width/height are not multiple of 4
3540 pIn
->width
= PowTwoAlign(pIn
->width
, 4);
3541 pIn
->height
= PowTwoAlign(pIn
->height
, 4);
3545 hwlHandled
= HwlComputeMipLevel(pIn
);
3549 ****************************************************************************************************
3553 * Check if surface can be degraded to 1D
3556 ****************************************************************************************************
3558 BOOL_32
Lib::DegradeTo1D(
3559 UINT_32 width
, ///< surface width
3560 UINT_32 height
, ///< surface height
3561 UINT_32 macroTilePitchAlign
, ///< macro tile pitch align
3562 UINT_32 macroTileHeightAlign
///< macro tile height align
3565 BOOL_32 degrade
= ((width
< macroTilePitchAlign
) || (height
< macroTileHeightAlign
));
3567 // Check whether 2D tiling still has too much footprint
3568 if (degrade
== FALSE
)
3570 // Only check width and height as slices are aligned to thickness
3571 UINT_64 unalignedSize
= width
* height
;
3573 UINT_32 alignedPitch
= PowTwoAlign(width
, macroTilePitchAlign
);
3574 UINT_32 alignedHeight
= PowTwoAlign(height
, macroTileHeightAlign
);
3575 UINT_64 alignedSize
= alignedPitch
* alignedHeight
;
3577 // alignedSize > 1.5 * unalignedSize
3578 if (2 * alignedSize
> 3 * unalignedSize
)
3588 ****************************************************************************************************
3589 * Lib::OptimizeTileMode
3592 * Check if base level's tile mode can be optimized (degraded)
3595 ****************************************************************************************************
3597 VOID
Lib::OptimizeTileMode(
3598 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in, out] structure for surface info
3601 AddrTileMode tileMode
= pInOut
->tileMode
;
3603 BOOL_32 doOpt
= (pInOut
->flags
.opt4Space
== TRUE
) ||
3604 (pInOut
->flags
.minimizeAlignment
== TRUE
) ||
3605 (pInOut
->maxBaseAlign
!= 0);
3607 BOOL_32 convertToPrt
= FALSE
;
3609 // Optimization can only be done on level 0 and samples <= 1
3610 if ((doOpt
== TRUE
) &&
3611 (pInOut
->mipLevel
== 0) &&
3612 (IsPrtTileMode(tileMode
) == FALSE
) &&
3613 (pInOut
->flags
.prt
== FALSE
))
3615 UINT_32 width
= pInOut
->width
;
3616 UINT_32 height
= pInOut
->height
;
3617 UINT_32 thickness
= Thickness(tileMode
);
3618 BOOL_32 macroTiledOK
= TRUE
;
3619 UINT_32 macroWidthAlign
= 0;
3620 UINT_32 macroHeightAlign
= 0;
3621 UINT_32 macroSizeAlign
= 0;
3623 if (IsMacroTiled(tileMode
))
3625 macroTiledOK
= HwlGetAlignmentInfoMacroTiled(pInOut
,
3633 if ((pInOut
->flags
.display
== FALSE
) &&
3634 (pInOut
->flags
.opt4Space
== TRUE
) &&
3635 (pInOut
->numSamples
<= 1))
3637 // Check if linear mode is optimal
3638 if ((pInOut
->height
== 1) &&
3639 (IsLinear(tileMode
) == FALSE
) &&
3640 (ElemLib::IsBlockCompressed(pInOut
->format
) == FALSE
) &&
3641 (pInOut
->flags
.depth
== FALSE
) &&
3642 (pInOut
->flags
.stencil
== FALSE
) &&
3643 (m_configFlags
.disableLinearOpt
== FALSE
) &&
3644 (pInOut
->flags
.disableLinearOpt
== FALSE
))
3646 tileMode
= ADDR_TM_LINEAR_ALIGNED
;
3648 else if (IsMacroTiled(tileMode
) && (pInOut
->flags
.tcCompatible
== FALSE
))
3650 if (DegradeTo1D(width
, height
, macroWidthAlign
, macroHeightAlign
))
3652 tileMode
= (thickness
== 1) ?
3653 ADDR_TM_1D_TILED_THIN1
: ADDR_TM_1D_TILED_THICK
;
3655 else if (thickness
> 1)
3657 // As in the following HwlComputeSurfaceInfo, thick modes may be degraded to
3658 // thinner modes, we should re-evaluate whether the corresponding
3659 // thinner modes should be degraded. If so, we choose 1D thick mode instead.
3660 tileMode
= DegradeLargeThickTile(pInOut
->tileMode
, pInOut
->bpp
);
3662 if (tileMode
!= pInOut
->tileMode
)
3664 // Get thickness again after large thick degrade
3665 thickness
= Thickness(tileMode
);
3667 ADDR_COMPUTE_SURFACE_INFO_INPUT input
= *pInOut
;
3668 input
.tileMode
= tileMode
;
3670 macroTiledOK
= HwlGetAlignmentInfoMacroTiled(&input
,
3676 DegradeTo1D(width
, height
, macroWidthAlign
, macroHeightAlign
))
3678 tileMode
= ADDR_TM_1D_TILED_THICK
;
3687 if ((pInOut
->flags
.minimizeAlignment
== TRUE
) &&
3688 (pInOut
->numSamples
<= 1) &&
3689 (IsMacroTiled(tileMode
) == TRUE
))
3691 UINT_32 macroSize
= PowTwoAlign(width
, macroWidthAlign
) *
3692 PowTwoAlign(height
, macroHeightAlign
);
3693 UINT_32 microSize
= PowTwoAlign(width
, MicroTileWidth
) *
3694 PowTwoAlign(height
, MicroTileHeight
);
3696 if (macroSize
> microSize
)
3698 tileMode
= (thickness
== 1) ?
3699 ADDR_TM_1D_TILED_THIN1
: ADDR_TM_1D_TILED_THICK
;
3703 if ((pInOut
->maxBaseAlign
!= 0) &&
3704 (IsMacroTiled(tileMode
) == TRUE
))
3706 if (macroSizeAlign
> pInOut
->maxBaseAlign
)
3708 if (pInOut
->numSamples
> 1)
3710 ADDR_ASSERT(pInOut
->maxBaseAlign
>= Block64K
);
3712 convertToPrt
= TRUE
;
3714 else if (pInOut
->maxBaseAlign
< Block64K
)
3716 tileMode
= (thickness
== 1) ?
3717 ADDR_TM_1D_TILED_THIN1
: ADDR_TM_1D_TILED_THICK
;
3721 convertToPrt
= TRUE
;
3731 if ((pInOut
->flags
.matchStencilTileCfg
== TRUE
) && (pInOut
->numSamples
<= 1))
3733 pInOut
->tileMode
= ADDR_TM_1D_TILED_THIN1
;
3737 HwlSetPrtTileMode(pInOut
);
3740 else if (tileMode
!= pInOut
->tileMode
)
3742 pInOut
->tileMode
= tileMode
;
3745 HwlOptimizeTileMode(pInOut
);
3749 ****************************************************************************************************
3750 * Lib::DegradeLargeThickTile
3753 * Check if the thickness needs to be reduced if a tile is too large
3755 * The degraded tile mode (unchanged if not degraded)
3756 ****************************************************************************************************
3758 AddrTileMode
Lib::DegradeLargeThickTile(
3759 AddrTileMode tileMode
,
3762 // Override tilemode
3763 // When tile_width (8) * tile_height (8) * thickness * element_bytes is > row_size,
3764 // it is better to just use THIN mode in this case
3765 UINT_32 thickness
= Thickness(tileMode
);
3767 if (thickness
> 1 && m_configFlags
.allowLargeThickTile
== 0)
3769 UINT_32 tileSize
= MicroTilePixels
* thickness
* (bpp
>> 3);
3771 if (tileSize
> m_rowSize
)
3775 case ADDR_TM_2D_TILED_XTHICK
:
3776 if ((tileSize
>> 1) <= m_rowSize
)
3778 tileMode
= ADDR_TM_2D_TILED_THICK
;
3781 // else fall through
3782 case ADDR_TM_2D_TILED_THICK
:
3783 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3786 case ADDR_TM_3D_TILED_XTHICK
:
3787 if ((tileSize
>> 1) <= m_rowSize
)
3789 tileMode
= ADDR_TM_3D_TILED_THICK
;
3792 // else fall through
3793 case ADDR_TM_3D_TILED_THICK
:
3794 tileMode
= ADDR_TM_3D_TILED_THIN1
;
3797 case ADDR_TM_PRT_TILED_THICK
:
3798 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
3801 case ADDR_TM_PRT_2D_TILED_THICK
:
3802 tileMode
= ADDR_TM_PRT_2D_TILED_THIN1
;
3805 case ADDR_TM_PRT_3D_TILED_THICK
:
3806 tileMode
= ADDR_TM_PRT_3D_TILED_THIN1
;
3819 ****************************************************************************************************
3820 * Lib::PostComputeMipLevel
3822 * Compute MipLevel info (including level 0) after surface adjustment
3825 ****************************************************************************************************
3827 ADDR_E_RETURNCODE
Lib::PostComputeMipLevel(
3828 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in,out] Input structure
3829 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] Output structure
3832 // Mipmap including level 0 must be pow2 padded since either SI hw expects so or it is
3833 // required by CFX for Hw Compatibility between NI and SI. Otherwise it is only needed for
3834 // mipLevel > 0. Any h/w has different requirement should implement its own virtual function
3836 if (pIn
->flags
.pow2Pad
)
3838 pIn
->width
= NextPow2(pIn
->width
);
3839 pIn
->height
= NextPow2(pIn
->height
);
3840 pIn
->numSlices
= NextPow2(pIn
->numSlices
);
3842 else if (pIn
->mipLevel
> 0)
3844 pIn
->width
= NextPow2(pIn
->width
);
3845 pIn
->height
= NextPow2(pIn
->height
);
3847 if (!pIn
->flags
.cube
)
3849 pIn
->numSlices
= NextPow2(pIn
->numSlices
);
3852 // for cubemap, we keep its value at first
3859 ****************************************************************************************************
3860 * Lib::HwlSetupTileCfg
3863 * Map tile index to tile setting.
3866 ****************************************************************************************************
3868 ADDR_E_RETURNCODE
Lib::HwlSetupTileCfg(
3869 UINT_32 bpp
, ///< Bits per pixel
3870 INT_32 index
, ///< [in] Tile index
3871 INT_32 macroModeIndex
, ///< [in] Index in macro tile mode table(CI)
3872 ADDR_TILEINFO
* pInfo
, ///< [out] Tile Info
3873 AddrTileMode
* pMode
, ///< [out] Tile mode
3874 AddrTileType
* pType
///< [out] Tile type
3877 return ADDR_NOTSUPPORTED
;
3881 ****************************************************************************************************
3888 ****************************************************************************************************
3890 UINT_32
Lib::HwlGetPipes(
3891 const ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
3894 //pTileInfo can be NULL when asic is 6xx and 8xx.
3899 ****************************************************************************************************
3900 * Lib::ComputeQbStereoInfo
3903 * Get quad buffer stereo information
3906 ****************************************************************************************************
3908 VOID
Lib::ComputeQbStereoInfo(
3909 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in,out] updated pOut+pStereoInfo
3912 ADDR_ASSERT(pOut
->bpp
>= 8);
3913 ADDR_ASSERT((pOut
->surfSize
% pOut
->baseAlign
) == 0);
3915 // Save original height
3916 pOut
->pStereoInfo
->eyeHeight
= pOut
->height
;
3919 pOut
->pStereoInfo
->rightOffset
= static_cast<UINT_32
>(pOut
->surfSize
);
3921 pOut
->pStereoInfo
->rightSwizzle
= HwlComputeQbStereoRightSwizzle(pOut
);
3924 pOut
->pixelHeight
<<= 1;
3927 pOut
->surfSize
<<= 1;
3929 // Right start address meets the base align since it is guaranteed by AddrLib1
3931 // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo.
3936 ****************************************************************************************************
3937 * Lib::ComputePrtInfo
3940 * Compute prt surface related info
3944 ****************************************************************************************************
3946 ADDR_E_RETURNCODE
Lib::ComputePrtInfo(
3947 const ADDR_PRT_INFO_INPUT
* pIn
,
3948 ADDR_PRT_INFO_OUTPUT
* pOut
) const
3950 ADDR_ASSERT(pOut
!= NULL
);
3952 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
3954 UINT_32 expandX
= 1;
3955 UINT_32 expandY
= 1;
3958 UINT_32 bpp
= GetElemLib()->GetBitsPerPixel(pIn
->format
,
3963 if (bpp
<8 || bpp
== 24 || bpp
== 48 || bpp
== 96)
3965 returnCode
= ADDR_INVALIDPARAMS
;
3968 UINT_32 numFrags
= pIn
->numFrags
;
3969 ADDR_ASSERT(numFrags
<= 8);
3971 UINT_32 tileWidth
= 0;
3972 UINT_32 tileHeight
= 0;
3973 if (returnCode
== ADDR_OK
)
3975 // 3D texture without depth or 2d texture
3976 if (pIn
->baseMipDepth
> 1 || pIn
->baseMipHeight
> 1)
3995 // assume it is BC1/4
3999 if (elemMode
== ADDR_UNCOMPRESSED
)
4005 else if (bpp
== 128)
4007 // assume it is BC2/3/5/6H/7
4011 if (elemMode
== ADDR_UNCOMPRESSED
)
4020 tileWidth
= tileWidth
/ 2;
4022 else if (numFrags
== 4)
4024 tileWidth
= tileWidth
/ 2;
4025 tileHeight
= tileHeight
/ 2;
4027 else if (numFrags
== 8)
4029 tileWidth
= tileWidth
/ 4;
4030 tileHeight
= tileHeight
/ 2;
4052 else if (bpp
== 128)
4059 pOut
->prtTileWidth
= tileWidth
;
4060 pOut
->prtTileHeight
= tileHeight
;