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;
431 ValidBaseAlignments(pOut
->baseAlign
);
437 ****************************************************************************************************
438 * Lib::ComputeSurfaceInfo
441 * Interface function stub of AddrComputeSurfaceInfo.
445 ****************************************************************************************************
447 ADDR_E_RETURNCODE
Lib::ComputeSurfaceAddrFromCoord(
448 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
449 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
452 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
454 if (GetFillSizeFieldsFlags() == TRUE
)
456 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
)) ||
457 (pOut
->size
!= sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
)))
459 returnCode
= ADDR_PARAMSIZEMISMATCH
;
463 if (returnCode
== ADDR_OK
)
465 ADDR_TILEINFO tileInfoNull
;
466 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT input
;
468 if (UseTileIndex(pIn
->tileIndex
))
471 // Use temp tile info for calcalation
472 input
.pTileInfo
= &tileInfoNull
;
474 const ADDR_SURFACE_FLAGS flags
= {{0}};
475 UINT_32 numSamples
= GetNumFragments(pIn
->numSamples
, pIn
->numFrags
);
477 // Try finding a macroModeIndex
478 INT_32 macroModeIndex
= HwlComputeMacroModeIndex(input
.tileIndex
,
486 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
487 if (macroModeIndex
== TileIndexNoMacroIndex
)
489 returnCode
= HwlSetupTileCfg(input
.bpp
, input
.tileIndex
, macroModeIndex
,
490 input
.pTileInfo
, &input
.tileMode
, &input
.tileType
);
492 // If macroModeIndex is invalid, then assert this is not macro tiled
493 else if (macroModeIndex
== TileIndexInvalid
)
495 ADDR_ASSERT(!IsMacroTiled(input
.tileMode
));
498 // Change the input structure
502 if (returnCode
== ADDR_OK
)
504 returnCode
= HwlComputeSurfaceAddrFromCoord(pIn
, pOut
);
506 if (returnCode
== ADDR_OK
)
508 pOut
->prtBlockIndex
= static_cast<UINT_32
>(pOut
->addr
/ (64 * 1024));
517 ****************************************************************************************************
518 * Lib::ComputeSurfaceCoordFromAddr
521 * Interface function stub of ComputeSurfaceCoordFromAddr.
525 ****************************************************************************************************
527 ADDR_E_RETURNCODE
Lib::ComputeSurfaceCoordFromAddr(
528 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
529 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
532 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
534 if (GetFillSizeFieldsFlags() == TRUE
)
536 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
)) ||
537 (pOut
->size
!= sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
)))
539 returnCode
= ADDR_PARAMSIZEMISMATCH
;
543 if (returnCode
== ADDR_OK
)
545 ADDR_TILEINFO tileInfoNull
;
546 ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT input
;
548 if (UseTileIndex(pIn
->tileIndex
))
551 // Use temp tile info for calcalation
552 input
.pTileInfo
= &tileInfoNull
;
554 const ADDR_SURFACE_FLAGS flags
= {{0}};
555 UINT_32 numSamples
= GetNumFragments(pIn
->numSamples
, pIn
->numFrags
);
557 // Try finding a macroModeIndex
558 INT_32 macroModeIndex
= HwlComputeMacroModeIndex(input
.tileIndex
,
566 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
567 if (macroModeIndex
== TileIndexNoMacroIndex
)
569 returnCode
= HwlSetupTileCfg(input
.bpp
, input
.tileIndex
, macroModeIndex
,
570 input
.pTileInfo
, &input
.tileMode
, &input
.tileType
);
572 // If macroModeIndex is invalid, then assert this is not macro tiled
573 else if (macroModeIndex
== TileIndexInvalid
)
575 ADDR_ASSERT(!IsMacroTiled(input
.tileMode
));
578 // Change the input structure
582 if (returnCode
== ADDR_OK
)
584 returnCode
= HwlComputeSurfaceCoordFromAddr(pIn
, pOut
);
592 ****************************************************************************************************
593 * Lib::ComputeSliceTileSwizzle
596 * Interface function stub of ComputeSliceTileSwizzle.
600 ****************************************************************************************************
602 ADDR_E_RETURNCODE
Lib::ComputeSliceTileSwizzle(
603 const ADDR_COMPUTE_SLICESWIZZLE_INPUT
* pIn
, ///< [in] input structure
604 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
* pOut
///< [out] output structure
607 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
609 if (GetFillSizeFieldsFlags() == TRUE
)
611 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SLICESWIZZLE_INPUT
)) ||
612 (pOut
->size
!= sizeof(ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
)))
614 returnCode
= ADDR_PARAMSIZEMISMATCH
;
618 if (returnCode
== ADDR_OK
)
620 ADDR_TILEINFO tileInfoNull
;
621 ADDR_COMPUTE_SLICESWIZZLE_INPUT input
;
623 if (UseTileIndex(pIn
->tileIndex
))
626 // Use temp tile info for calcalation
627 input
.pTileInfo
= &tileInfoNull
;
629 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
,
630 input
.pTileInfo
, &input
.tileMode
);
631 // Change the input structure
635 if (returnCode
== ADDR_OK
)
637 returnCode
= HwlComputeSliceTileSwizzle(pIn
, pOut
);
645 ****************************************************************************************************
646 * Lib::ExtractBankPipeSwizzle
649 * Interface function stub of AddrExtractBankPipeSwizzle.
653 ****************************************************************************************************
655 ADDR_E_RETURNCODE
Lib::ExtractBankPipeSwizzle(
656 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
657 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
660 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
662 if (GetFillSizeFieldsFlags() == TRUE
)
664 if ((pIn
->size
!= sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
)) ||
665 (pOut
->size
!= sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
)))
667 returnCode
= ADDR_PARAMSIZEMISMATCH
;
671 if (returnCode
== ADDR_OK
)
673 ADDR_TILEINFO tileInfoNull
;
674 ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT input
;
676 if (UseTileIndex(pIn
->tileIndex
))
679 // Use temp tile info for calcalation
680 input
.pTileInfo
= &tileInfoNull
;
682 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
683 // Change the input structure
687 if (returnCode
== ADDR_OK
)
689 returnCode
= HwlExtractBankPipeSwizzle(pIn
, pOut
);
697 ****************************************************************************************************
698 * Lib::CombineBankPipeSwizzle
701 * Interface function stub of AddrCombineBankPipeSwizzle.
705 ****************************************************************************************************
707 ADDR_E_RETURNCODE
Lib::CombineBankPipeSwizzle(
708 const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
709 ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
712 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
714 if (GetFillSizeFieldsFlags() == TRUE
)
716 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT
)) ||
717 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT
)))
719 returnCode
= ADDR_PARAMSIZEMISMATCH
;
723 if (returnCode
== ADDR_OK
)
725 ADDR_TILEINFO tileInfoNull
;
726 ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT input
;
728 if (UseTileIndex(pIn
->tileIndex
))
731 // Use temp tile info for calcalation
732 input
.pTileInfo
= &tileInfoNull
;
734 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
735 // Change the input structure
739 if (returnCode
== ADDR_OK
)
741 returnCode
= HwlCombineBankPipeSwizzle(pIn
->bankSwizzle
,
753 ****************************************************************************************************
754 * Lib::ComputeBaseSwizzle
757 * Interface function stub of AddrCompueBaseSwizzle.
760 ****************************************************************************************************
762 ADDR_E_RETURNCODE
Lib::ComputeBaseSwizzle(
763 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT
* pIn
,
764 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
* pOut
) const
766 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
768 if (GetFillSizeFieldsFlags() == TRUE
)
770 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT
)) ||
771 (pOut
->size
!= sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
)))
773 returnCode
= ADDR_PARAMSIZEMISMATCH
;
777 if (returnCode
== ADDR_OK
)
779 ADDR_TILEINFO tileInfoNull
;
780 ADDR_COMPUTE_BASE_SWIZZLE_INPUT input
;
782 if (UseTileIndex(pIn
->tileIndex
))
785 // Use temp tile info for calcalation
786 input
.pTileInfo
= &tileInfoNull
;
788 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
789 // Change the input structure
793 if (returnCode
== ADDR_OK
)
795 if (IsMacroTiled(pIn
->tileMode
))
797 returnCode
= HwlComputeBaseSwizzle(pIn
, pOut
);
801 pOut
->tileSwizzle
= 0;
810 ****************************************************************************************************
811 * Lib::ComputeFmaskInfo
814 * Interface function stub of ComputeFmaskInfo.
818 ****************************************************************************************************
820 ADDR_E_RETURNCODE
Lib::ComputeFmaskInfo(
821 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
822 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
825 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
827 if (GetFillSizeFieldsFlags() == TRUE
)
829 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT
)) ||
830 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT
)))
832 returnCode
= ADDR_PARAMSIZEMISMATCH
;
837 if (Thickness(pIn
->tileMode
) > 1)
839 returnCode
= ADDR_INVALIDPARAMS
;
842 if (returnCode
== ADDR_OK
)
844 ADDR_TILEINFO tileInfoNull
;
845 ADDR_COMPUTE_FMASK_INFO_INPUT input
;
847 if (UseTileIndex(pIn
->tileIndex
))
853 // Use temp tile info for calcalation
854 input
.pTileInfo
= pOut
->pTileInfo
;
858 input
.pTileInfo
= &tileInfoNull
;
861 ADDR_SURFACE_FLAGS flags
= {{0}};
864 // Try finding a macroModeIndex
865 INT_32 macroModeIndex
= HwlComputeMacroModeIndex(pIn
->tileIndex
,
867 HwlComputeFmaskBits(pIn
, NULL
),
872 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
873 if (macroModeIndex
== TileIndexNoMacroIndex
)
875 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, macroModeIndex
,
876 input
.pTileInfo
, &input
.tileMode
);
879 ADDR_ASSERT(macroModeIndex
!= TileIndexInvalid
);
881 // Change the input structure
885 if (returnCode
== ADDR_OK
)
887 if (pIn
->numSamples
> 1)
889 returnCode
= HwlComputeFmaskInfo(pIn
, pOut
);
893 memset(pOut
, 0, sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT
));
895 returnCode
= ADDR_INVALIDPARAMS
;
900 ValidBaseAlignments(pOut
->baseAlign
);
906 ****************************************************************************************************
907 * Lib::ComputeFmaskAddrFromCoord
910 * Interface function stub of ComputeFmaskAddrFromCoord.
914 ****************************************************************************************************
916 ADDR_E_RETURNCODE
Lib::ComputeFmaskAddrFromCoord(
917 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
918 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
921 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
923 if (GetFillSizeFieldsFlags() == TRUE
)
925 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
)) ||
926 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
)))
928 returnCode
= ADDR_PARAMSIZEMISMATCH
;
932 if (returnCode
== ADDR_OK
)
934 ADDR_ASSERT(pIn
->numSamples
> 1);
936 if (pIn
->numSamples
> 1)
938 returnCode
= HwlComputeFmaskAddrFromCoord(pIn
, pOut
);
942 returnCode
= ADDR_INVALIDPARAMS
;
950 ****************************************************************************************************
951 * Lib::ComputeFmaskCoordFromAddr
954 * Interface function stub of ComputeFmaskAddrFromCoord.
958 ****************************************************************************************************
960 ADDR_E_RETURNCODE
Lib::ComputeFmaskCoordFromAddr(
961 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
962 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
965 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
967 if (GetFillSizeFieldsFlags() == TRUE
)
969 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
)) ||
970 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
)))
972 returnCode
= ADDR_PARAMSIZEMISMATCH
;
976 if (returnCode
== ADDR_OK
)
978 ADDR_ASSERT(pIn
->numSamples
> 1);
980 if (pIn
->numSamples
> 1)
982 returnCode
= HwlComputeFmaskCoordFromAddr(pIn
, pOut
);
986 returnCode
= ADDR_INVALIDPARAMS
;
994 ****************************************************************************************************
995 * Lib::ConvertTileInfoToHW
998 * Convert tile info from real value to HW register value in HW layer
1002 ****************************************************************************************************
1004 ADDR_E_RETURNCODE
Lib::ConvertTileInfoToHW(
1005 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
1006 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
1009 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1011 if (GetFillSizeFieldsFlags() == TRUE
)
1013 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT
)) ||
1014 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT
)))
1016 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1020 if (returnCode
== ADDR_OK
)
1022 ADDR_TILEINFO tileInfoNull
;
1023 ADDR_CONVERT_TILEINFOTOHW_INPUT input
;
1024 // if pIn->reverse is TRUE, indices are ignored
1025 if (pIn
->reverse
== FALSE
&& UseTileIndex(pIn
->tileIndex
))
1028 input
.pTileInfo
= &tileInfoNull
;
1030 returnCode
= HwlSetupTileCfg(input
.bpp
, input
.tileIndex
,
1031 input
.macroModeIndex
, input
.pTileInfo
);
1036 if (returnCode
== ADDR_OK
)
1038 returnCode
= HwlConvertTileInfoToHW(pIn
, pOut
);
1046 ****************************************************************************************************
1047 * Lib::ConvertTileIndex
1050 * Convert tile index to tile mode/type/info
1054 ****************************************************************************************************
1056 ADDR_E_RETURNCODE
Lib::ConvertTileIndex(
1057 const ADDR_CONVERT_TILEINDEX_INPUT
* pIn
, ///< [in] input structure
1058 ADDR_CONVERT_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1061 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1063 if (GetFillSizeFieldsFlags() == TRUE
)
1065 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_INPUT
)) ||
1066 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT
)))
1068 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1072 if (returnCode
== ADDR_OK
)
1075 returnCode
= HwlSetupTileCfg(pIn
->bpp
, pIn
->tileIndex
, pIn
->macroModeIndex
,
1076 pOut
->pTileInfo
, &pOut
->tileMode
, &pOut
->tileType
);
1078 if (returnCode
== ADDR_OK
&& pIn
->tileInfoHw
)
1080 ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput
= {0};
1081 ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput
= {0};
1083 hwInput
.pTileInfo
= pOut
->pTileInfo
;
1084 hwInput
.tileIndex
= -1;
1085 hwOutput
.pTileInfo
= pOut
->pTileInfo
;
1087 returnCode
= HwlConvertTileInfoToHW(&hwInput
, &hwOutput
);
1095 ****************************************************************************************************
1096 * Lib::GetMacroModeIndex
1099 * Get macro mode index based on input info
1103 ****************************************************************************************************
1105 ADDR_E_RETURNCODE
Lib::GetMacroModeIndex(
1106 const ADDR_GET_MACROMODEINDEX_INPUT
* pIn
, ///< [in] input structure
1107 ADDR_GET_MACROMODEINDEX_OUTPUT
* pOut
///< [out] output structure
1110 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1112 if (GetFillSizeFieldsFlags())
1114 if ((pIn
->size
!= sizeof(ADDR_GET_MACROMODEINDEX_INPUT
)) ||
1115 (pOut
->size
!= sizeof(ADDR_GET_MACROMODEINDEX_OUTPUT
)))
1117 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1121 if (returnCode
== ADDR_OK
)
1123 ADDR_TILEINFO tileInfo
= {0};
1124 pOut
->macroModeIndex
= HwlComputeMacroModeIndex(pIn
->tileIndex
, pIn
->flags
, pIn
->bpp
,
1125 pIn
->numFrags
, &tileInfo
);
1132 ****************************************************************************************************
1133 * Lib::ConvertTileIndex1
1136 * Convert tile index to tile mode/type/info
1140 ****************************************************************************************************
1142 ADDR_E_RETURNCODE
Lib::ConvertTileIndex1(
1143 const ADDR_CONVERT_TILEINDEX1_INPUT
* pIn
, ///< [in] input structure
1144 ADDR_CONVERT_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1147 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1149 if (GetFillSizeFieldsFlags() == TRUE
)
1151 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINDEX1_INPUT
)) ||
1152 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT
)))
1154 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1158 if (returnCode
== ADDR_OK
)
1160 ADDR_SURFACE_FLAGS flags
= {{0}};
1162 HwlComputeMacroModeIndex(pIn
->tileIndex
, flags
, pIn
->bpp
, pIn
->numSamples
,
1163 pOut
->pTileInfo
, &pOut
->tileMode
, &pOut
->tileType
);
1165 if (pIn
->tileInfoHw
)
1167 ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput
= {0};
1168 ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput
= {0};
1170 hwInput
.pTileInfo
= pOut
->pTileInfo
;
1171 hwInput
.tileIndex
= -1;
1172 hwOutput
.pTileInfo
= pOut
->pTileInfo
;
1174 returnCode
= HwlConvertTileInfoToHW(&hwInput
, &hwOutput
);
1182 ****************************************************************************************************
1186 * Get tile index from tile mode/type/info
1190 ****************************************************************************************************
1192 ADDR_E_RETURNCODE
Lib::GetTileIndex(
1193 const ADDR_GET_TILEINDEX_INPUT
* pIn
, ///< [in] input structure
1194 ADDR_GET_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1197 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1199 if (GetFillSizeFieldsFlags() == TRUE
)
1201 if ((pIn
->size
!= sizeof(ADDR_GET_TILEINDEX_INPUT
)) ||
1202 (pOut
->size
!= sizeof(ADDR_GET_TILEINDEX_OUTPUT
)))
1204 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1208 if (returnCode
== ADDR_OK
)
1210 returnCode
= HwlGetTileIndex(pIn
, pOut
);
1217 ****************************************************************************************************
1221 * Get tile mode thickness
1224 * Tile mode thickness
1225 ****************************************************************************************************
1227 UINT_32
Lib::Thickness(
1228 AddrTileMode tileMode
) ///< [in] tile mode
1230 return ModeFlags
[tileMode
].thickness
;
1235 ////////////////////////////////////////////////////////////////////////////////////////////////////
1237 ////////////////////////////////////////////////////////////////////////////////////////////////////
1240 ****************************************************************************************************
1241 * Lib::ComputeHtileInfo
1244 * Interface function stub of AddrComputeHtilenfo
1248 ****************************************************************************************************
1250 ADDR_E_RETURNCODE
Lib::ComputeHtileInfo(
1251 const ADDR_COMPUTE_HTILE_INFO_INPUT
* pIn
, ///< [in] input structure
1252 ADDR_COMPUTE_HTILE_INFO_OUTPUT
* pOut
///< [out] output structure
1255 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1257 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1258 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1260 if (GetFillSizeFieldsFlags() == TRUE
)
1262 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT
)) ||
1263 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT
)))
1265 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1269 if (returnCode
== ADDR_OK
)
1271 ADDR_TILEINFO tileInfoNull
;
1272 ADDR_COMPUTE_HTILE_INFO_INPUT input
;
1274 if (UseTileIndex(pIn
->tileIndex
))
1277 // Use temp tile info for calcalation
1278 input
.pTileInfo
= &tileInfoNull
;
1280 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1282 // Change the input structure
1286 if (returnCode
== ADDR_OK
)
1288 if (pIn
->flags
.tcCompatible
)
1290 const UINT_32 sliceSize
= pIn
->pitch
* pIn
->height
* 4 / (8 * 8);
1291 const UINT_32 align
= HwlGetPipes(pIn
->pTileInfo
) * pIn
->pTileInfo
->banks
* m_pipeInterleaveBytes
;
1293 if (pIn
->numSlices
> 1)
1295 const UINT_32 surfBytes
= (sliceSize
* pIn
->numSlices
);
1297 pOut
->sliceSize
= sliceSize
;
1298 pOut
->htileBytes
= pIn
->flags
.skipTcCompatSizeAlign
?
1299 surfBytes
: PowTwoAlign(surfBytes
, align
);
1300 pOut
->sliceInterleaved
= ((sliceSize
% align
) != 0) ? TRUE
: FALSE
;
1304 pOut
->sliceSize
= pIn
->flags
.skipTcCompatSizeAlign
?
1305 sliceSize
: PowTwoAlign(sliceSize
, align
);
1306 pOut
->htileBytes
= pOut
->sliceSize
;
1307 pOut
->sliceInterleaved
= FALSE
;
1310 pOut
->nextMipLevelCompressible
= ((sliceSize
% align
) == 0) ? TRUE
: FALSE
;
1312 pOut
->pitch
= pIn
->pitch
;
1313 pOut
->height
= pIn
->height
;
1314 pOut
->baseAlign
= align
;
1315 pOut
->macroWidth
= 0;
1316 pOut
->macroHeight
= 0;
1321 pOut
->bpp
= ComputeHtileInfo(pIn
->flags
,
1340 ValidMetaBaseAlignments(pOut
->baseAlign
);
1346 ****************************************************************************************************
1347 * Lib::ComputeCmaskInfo
1350 * Interface function stub of AddrComputeCmaskInfo
1354 ****************************************************************************************************
1356 ADDR_E_RETURNCODE
Lib::ComputeCmaskInfo(
1357 const ADDR_COMPUTE_CMASK_INFO_INPUT
* pIn
, ///< [in] input structure
1358 ADDR_COMPUTE_CMASK_INFO_OUTPUT
* pOut
///< [out] output structure
1361 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1363 if (GetFillSizeFieldsFlags() == TRUE
)
1365 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_INFO_INPUT
)) ||
1366 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_INFO_OUTPUT
)))
1368 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1372 if (returnCode
== ADDR_OK
)
1374 ADDR_TILEINFO tileInfoNull
;
1375 ADDR_COMPUTE_CMASK_INFO_INPUT input
;
1377 if (UseTileIndex(pIn
->tileIndex
))
1380 // Use temp tile info for calcalation
1381 input
.pTileInfo
= &tileInfoNull
;
1383 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1385 // Change the input structure
1389 if (returnCode
== ADDR_OK
)
1391 returnCode
= ComputeCmaskInfo(pIn
->flags
,
1408 ValidMetaBaseAlignments(pOut
->baseAlign
);
1414 ****************************************************************************************************
1415 * Lib::ComputeDccInfo
1418 * Interface function to compute DCC key info
1421 * return code of HwlComputeDccInfo
1422 ****************************************************************************************************
1424 ADDR_E_RETURNCODE
Lib::ComputeDccInfo(
1425 const ADDR_COMPUTE_DCCINFO_INPUT
* pIn
, ///< [in] input structure
1426 ADDR_COMPUTE_DCCINFO_OUTPUT
* pOut
///< [out] output structure
1429 ADDR_E_RETURNCODE ret
= ADDR_OK
;
1431 if (GetFillSizeFieldsFlags() == TRUE
)
1433 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_DCCINFO_INPUT
)) ||
1434 (pOut
->size
!= sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT
)))
1436 ret
= ADDR_PARAMSIZEMISMATCH
;
1442 ADDR_COMPUTE_DCCINFO_INPUT input
;
1444 if (UseTileIndex(pIn
->tileIndex
))
1448 ret
= HwlSetupTileCfg(input
.bpp
, input
.tileIndex
, input
.macroModeIndex
,
1449 &input
.tileInfo
, &input
.tileMode
);
1456 ret
= HwlComputeDccInfo(pIn
, pOut
);
1458 ValidMetaBaseAlignments(pOut
->dccRamBaseAlign
);
1466 ****************************************************************************************************
1467 * Lib::ComputeHtileAddrFromCoord
1470 * Interface function stub of AddrComputeHtileAddrFromCoord
1474 ****************************************************************************************************
1476 ADDR_E_RETURNCODE
Lib::ComputeHtileAddrFromCoord(
1477 const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1478 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1481 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1483 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1484 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1486 if (GetFillSizeFieldsFlags() == TRUE
)
1488 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
)) ||
1489 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
)))
1491 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1495 if (returnCode
== ADDR_OK
)
1497 ADDR_TILEINFO tileInfoNull
;
1498 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT input
;
1500 if (UseTileIndex(pIn
->tileIndex
))
1503 // Use temp tile info for calcalation
1504 input
.pTileInfo
= &tileInfoNull
;
1506 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1508 // Change the input structure
1512 if (returnCode
== ADDR_OK
)
1514 if (pIn
->flags
.tcCompatible
)
1516 HwlComputeHtileAddrFromCoord(pIn
, pOut
);
1520 pOut
->addr
= HwlComputeXmaskAddrFromCoord(pIn
->pitch
,
1531 &pOut
->bitPosition
);
1541 ****************************************************************************************************
1542 * Lib::ComputeHtileCoordFromAddr
1545 * Interface function stub of AddrComputeHtileCoordFromAddr
1549 ****************************************************************************************************
1551 ADDR_E_RETURNCODE
Lib::ComputeHtileCoordFromAddr(
1552 const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
1553 ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
1556 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1558 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1559 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1561 if (GetFillSizeFieldsFlags() == TRUE
)
1563 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT
)) ||
1564 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
)))
1566 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1570 if (returnCode
== ADDR_OK
)
1572 ADDR_TILEINFO tileInfoNull
;
1573 ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT input
;
1575 if (UseTileIndex(pIn
->tileIndex
))
1578 // Use temp tile info for calcalation
1579 input
.pTileInfo
= &tileInfoNull
;
1581 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1583 // Change the input structure
1587 if (returnCode
== ADDR_OK
)
1589 HwlComputeXmaskCoordFromAddr(pIn
->addr
,
1609 ****************************************************************************************************
1610 * Lib::ComputeCmaskAddrFromCoord
1613 * Interface function stub of AddrComputeCmaskAddrFromCoord
1617 ****************************************************************************************************
1619 ADDR_E_RETURNCODE
Lib::ComputeCmaskAddrFromCoord(
1620 const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1621 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1624 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1626 if (GetFillSizeFieldsFlags() == TRUE
)
1628 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
)) ||
1629 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
)))
1631 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1635 if (returnCode
== ADDR_OK
)
1637 ADDR_TILEINFO tileInfoNull
;
1638 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT input
;
1640 if (UseTileIndex(pIn
->tileIndex
))
1643 // Use temp tile info for calcalation
1644 input
.pTileInfo
= &tileInfoNull
;
1646 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1648 // Change the input structure
1652 if (returnCode
== ADDR_OK
)
1654 if (pIn
->flags
.tcCompatible
== TRUE
)
1656 returnCode
= HwlComputeCmaskAddrFromCoord(pIn
, pOut
);
1660 pOut
->addr
= HwlComputeXmaskAddrFromCoord(pIn
->pitch
,
1668 FALSE
, //this is cmask, isWidth8 is not needed
1669 FALSE
, //this is cmask, isHeight8 is not needed
1671 &pOut
->bitPosition
);
1681 ****************************************************************************************************
1682 * Lib::ComputeCmaskCoordFromAddr
1685 * Interface function stub of AddrComputeCmaskCoordFromAddr
1689 ****************************************************************************************************
1691 ADDR_E_RETURNCODE
Lib::ComputeCmaskCoordFromAddr(
1692 const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
1693 ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
1696 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1698 if (GetFillSizeFieldsFlags() == TRUE
)
1700 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT
)) ||
1701 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT
)))
1703 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1707 if (returnCode
== ADDR_OK
)
1709 ADDR_TILEINFO tileInfoNull
;
1710 ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT input
;
1712 if (UseTileIndex(pIn
->tileIndex
))
1715 // Use temp tile info for calcalation
1716 input
.pTileInfo
= &tileInfoNull
;
1718 returnCode
= HwlSetupTileCfg(0, input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1720 // Change the input structure
1724 if (returnCode
== ADDR_OK
)
1726 HwlComputeXmaskCoordFromAddr(pIn
->addr
,
1746 ****************************************************************************************************
1747 * Lib::ComputeTileDataWidthAndHeight
1750 * Compute the squared cache shape for per-tile data (CMASK and HTILE)
1756 * MacroWidth and macroHeight are measured in pixels
1757 ****************************************************************************************************
1759 VOID
Lib::ComputeTileDataWidthAndHeight(
1760 UINT_32 bpp
, ///< [in] bits per pixel
1761 UINT_32 cacheBits
, ///< [in] bits of cache
1762 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1763 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1764 UINT_32
* pMacroHeight
///< [out] macro tile height
1768 UINT_32 width
= cacheBits
/ bpp
;
1769 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
1771 // Double height until the macro-tile is close to square
1772 // Height can only be doubled if width is even
1774 while ((width
> height
* 2 * pipes
) && !(width
& 1))
1780 *pMacroWidth
= 8 * width
;
1781 *pMacroHeight
= 8 * height
* pipes
;
1783 // Note: The above iterative comptuation is equivalent to the following
1785 //int log2_height = ((log2(cacheBits)-log2(bpp)-log2(pipes))/2);
1786 //int macroHeight = pow2( 3+log2(pipes)+log2_height );
1790 ****************************************************************************************************
1791 * Lib::HwlComputeTileDataWidthAndHeightLinear
1794 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1800 * MacroWidth and macroHeight are measured in pixels
1801 ****************************************************************************************************
1803 VOID
Lib::HwlComputeTileDataWidthAndHeightLinear(
1804 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1805 UINT_32
* pMacroHeight
, ///< [out] macro tile height
1806 UINT_32 bpp
, ///< [in] bits per pixel
1807 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
1810 ADDR_ASSERT(bpp
!= 4); // Cmask does not support linear layout prior to SI
1811 *pMacroWidth
= 8 * 512 / bpp
; // Align width to 512-bit memory accesses
1812 *pMacroHeight
= 8 * m_pipes
; // Align height to number of pipes
1816 ****************************************************************************************************
1817 * Lib::ComputeHtileInfo
1820 * Compute htile pitch,width, bytes per 2D slice
1823 * Htile bpp i.e. How many bits for an 8x8 tile
1824 * Also returns by output parameters:
1825 * *Htile pitch, height, total size in bytes, macro-tile dimensions and slice size*
1826 ****************************************************************************************************
1828 UINT_32
Lib::ComputeHtileInfo(
1829 ADDR_HTILE_FLAGS flags
, ///< [in] htile flags
1830 UINT_32 pitchIn
, ///< [in] pitch input
1831 UINT_32 heightIn
, ///< [in] height input
1832 UINT_32 numSlices
, ///< [in] number of slices
1833 BOOL_32 isLinear
, ///< [in] if it is linear mode
1834 BOOL_32 isWidth8
, ///< [in] if htile block width is 8
1835 BOOL_32 isHeight8
, ///< [in] if htile block height is 8
1836 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1837 UINT_32
* pPitchOut
, ///< [out] pitch output
1838 UINT_32
* pHeightOut
, ///< [out] height output
1839 UINT_64
* pHtileBytes
, ///< [out] bytes per 2D slice
1840 UINT_32
* pMacroWidth
, ///< [out] macro-tile width in pixels
1841 UINT_32
* pMacroHeight
, ///< [out] macro-tile width in pixels
1842 UINT_64
* pSliceSize
, ///< [out] slice size in bytes
1843 UINT_32
* pBaseAlign
///< [out] base alignment
1848 UINT_32 macroHeight
;
1853 numSlices
= Max(1u, numSlices
);
1855 const UINT_32 bpp
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
1856 const UINT_32 cacheBits
= HtileCacheBits
;
1860 HwlComputeTileDataWidthAndHeightLinear(¯oWidth
,
1867 ComputeTileDataWidthAndHeight(bpp
,
1874 *pPitchOut
= PowTwoAlign(pitchIn
, macroWidth
);
1875 *pHeightOut
= PowTwoAlign(heightIn
, macroHeight
);
1877 baseAlign
= HwlComputeHtileBaseAlign(flags
.tcCompatible
, isLinear
, pTileInfo
);
1879 surfBytes
= HwlComputeHtileBytes(*pPitchOut
,
1887 *pHtileBytes
= surfBytes
;
1890 // Use SafeAssign since they are optional
1892 SafeAssign(pMacroWidth
, macroWidth
);
1894 SafeAssign(pMacroHeight
, macroHeight
);
1896 SafeAssign(pSliceSize
, sliceBytes
);
1898 SafeAssign(pBaseAlign
, baseAlign
);
1904 ****************************************************************************************************
1905 * Lib::ComputeCmaskBaseAlign
1908 * Compute cmask base alignment
1911 * Cmask base alignment
1912 ****************************************************************************************************
1914 UINT_32
Lib::ComputeCmaskBaseAlign(
1915 ADDR_CMASK_FLAGS flags
, ///< [in] Cmask flags
1916 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
1919 UINT_32 baseAlign
= m_pipeInterleaveBytes
* HwlGetPipes(pTileInfo
);
1921 if (flags
.tcCompatible
)
1923 ADDR_ASSERT(pTileInfo
!= NULL
);
1926 baseAlign
*= pTileInfo
->banks
;
1934 ****************************************************************************************************
1935 * Lib::ComputeCmaskBytes
1938 * Compute cmask size in bytes
1941 * Cmask size in bytes
1942 ****************************************************************************************************
1944 UINT_64
Lib::ComputeCmaskBytes(
1945 UINT_32 pitch
, ///< [in] pitch
1946 UINT_32 height
, ///< [in] height
1947 UINT_32 numSlices
///< [in] number of slices
1950 return BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* numSlices
* CmaskElemBits
) /
1955 ****************************************************************************************************
1956 * Lib::ComputeCmaskInfo
1959 * Compute cmask pitch,width, bytes per 2D slice
1962 * BlockMax. Also by output parameters: Cmask pitch,height, total size in bytes,
1963 * macro-tile dimensions
1964 ****************************************************************************************************
1966 ADDR_E_RETURNCODE
Lib::ComputeCmaskInfo(
1967 ADDR_CMASK_FLAGS flags
, ///< [in] cmask flags
1968 UINT_32 pitchIn
, ///< [in] pitch input
1969 UINT_32 heightIn
, ///< [in] height input
1970 UINT_32 numSlices
, ///< [in] number of slices
1971 BOOL_32 isLinear
, ///< [in] is linear mode
1972 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1973 UINT_32
* pPitchOut
, ///< [out] pitch output
1974 UINT_32
* pHeightOut
, ///< [out] height output
1975 UINT_64
* pCmaskBytes
, ///< [out] bytes per 2D slice
1976 UINT_32
* pMacroWidth
, ///< [out] macro-tile width in pixels
1977 UINT_32
* pMacroHeight
, ///< [out] macro-tile width in pixels
1978 UINT_64
* pSliceSize
, ///< [out] slice size in bytes
1979 UINT_32
* pBaseAlign
, ///< [out] base alignment
1980 UINT_32
* pBlockMax
///< [out] block max == slice / 128 / 128 - 1
1984 UINT_32 macroHeight
;
1989 numSlices
= Max(1u, numSlices
);
1991 const UINT_32 bpp
= CmaskElemBits
;
1992 const UINT_32 cacheBits
= CmaskCacheBits
;
1994 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1998 HwlComputeTileDataWidthAndHeightLinear(¯oWidth
,
2005 ComputeTileDataWidthAndHeight(bpp
,
2012 *pPitchOut
= (pitchIn
+ macroWidth
- 1) & ~(macroWidth
- 1);
2013 *pHeightOut
= (heightIn
+ macroHeight
- 1) & ~(macroHeight
- 1);
2016 sliceBytes
= ComputeCmaskBytes(*pPitchOut
,
2020 baseAlign
= ComputeCmaskBaseAlign(flags
, pTileInfo
);
2022 while (sliceBytes
% baseAlign
)
2024 *pHeightOut
+= macroHeight
;
2026 sliceBytes
= ComputeCmaskBytes(*pPitchOut
,
2031 surfBytes
= sliceBytes
* numSlices
;
2033 *pCmaskBytes
= surfBytes
;
2036 // Use SafeAssign since they are optional
2038 SafeAssign(pMacroWidth
, macroWidth
);
2040 SafeAssign(pMacroHeight
, macroHeight
);
2042 SafeAssign(pBaseAlign
, baseAlign
);
2044 SafeAssign(pSliceSize
, sliceBytes
);
2046 UINT_32 slice
= (*pPitchOut
) * (*pHeightOut
);
2047 UINT_32 blockMax
= slice
/ 128 / 128 - 1;
2050 if (slice
% (64*256) != 0)
2052 ADDR_ASSERT_ALWAYS();
2056 UINT_32 maxBlockMax
= HwlGetMaxCmaskBlockMax();
2058 if (blockMax
> maxBlockMax
)
2060 blockMax
= maxBlockMax
;
2061 returnCode
= ADDR_INVALIDPARAMS
;
2064 SafeAssign(pBlockMax
, blockMax
);
2070 ****************************************************************************************************
2071 * Lib::ComputeXmaskCoordYFromPipe
2074 * Compute the Y coord from pipe number for cmask/htile
2079 ****************************************************************************************************
2081 UINT_32
Lib::ComputeXmaskCoordYFromPipe(
2082 UINT_32 pipe
, ///< [in] pipe number
2083 UINT_32 x
///< [in] x coordinate
2095 UINT_32 numPipes
= m_pipes
; // SI has its implementation
2097 // Convert pipe + x to y coordinate.
2117 pipeBit0
= pipe
& 0x1;
2121 yBit0
= pipeBit0
^ xBit0
;
2135 pipeBit0
= pipe
& 0x1;
2136 pipeBit1
= (pipe
& 0x2) >> 1;
2139 xBit1
= (x
& 0x2) >> 1;
2141 yBit0
= pipeBit0
^ xBit1
;
2142 yBit1
= pipeBit1
^ xBit0
;
2151 // r600 and r800 have different method
2153 y
= HwlComputeXmaskCoordYFrom8Pipe(pipe
, x
);
2162 ****************************************************************************************************
2163 * Lib::HwlComputeXmaskCoordFromAddr
2166 * Compute the coord from an address of a cmask/htile
2172 * This method is reused by htile, so rename to Xmask
2173 ****************************************************************************************************
2175 VOID
Lib::HwlComputeXmaskCoordFromAddr(
2176 UINT_64 addr
, ///< [in] address
2177 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2178 UINT_32 pitch
, ///< [in] pitch
2179 UINT_32 height
, ///< [in] height
2180 UINT_32 numSlices
, ///< [in] number of slices
2181 UINT_32 factor
, ///< [in] factor that indicates cmask or htile
2182 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
2183 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2184 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2185 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
2186 UINT_32
* pX
, ///< [out] x coord
2187 UINT_32
* pY
, ///< [out] y coord
2188 UINT_32
* pSlice
///< [out] slice index
2193 UINT_32 numGroupBits
;
2195 UINT_32 numPipeBits
;
2196 UINT_32 macroTilePitch
;
2197 UINT_32 macroTileHeight
;
2201 UINT_32 microTileCoordY
;
2205 UINT_32 pitchAligned
= pitch
;
2206 UINT_32 heightAligned
= height
;
2214 UINT_64 macroNumber
;
2215 UINT_32 microNumber
;
2224 UINT_32 tilesPerMacro
;
2225 UINT_32 macrosPerPitch
;
2226 UINT_32 macrosPerSlice
;
2231 numPipes
= HwlGetPipes(pTileInfo
);
2232 pipe
= ComputePipeFromAddr(addr
, numPipes
);
2235 // Compute the number of group and pipe bits.
2237 numGroupBits
= Log2(m_pipeInterleaveBytes
);
2238 numPipeBits
= Log2(numPipes
);
2240 UINT_32 groupBits
= 8 * m_pipeInterleaveBytes
;
2241 UINT_32 pipes
= numPipes
;
2245 // Compute the micro tile size, in bits. And macro tile pitch and height.
2247 if (factor
== 2) //CMASK
2249 ADDR_CMASK_FLAGS flags
= {{0}};
2251 elemBits
= CmaskElemBits
;
2253 ComputeCmaskInfo(flags
,
2267 ADDR_HTILE_FLAGS flags
= {{0}};
2274 elemBits
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
2276 ComputeHtileInfo(flags
,
2291 // Should use aligned dims
2293 pitch
= pitchAligned
;
2294 height
= heightAligned
;
2298 // Convert byte address to bit address.
2300 bitAddr
= BYTES_TO_BITS(addr
) + bitPosition
;
2304 // Remove pipe bits from address.
2307 bitAddr
= (bitAddr
% groupBits
) + ((bitAddr
/groupBits
/pipes
)*groupBits
);
2310 elemOffset
= bitAddr
/ elemBits
;
2312 tilesPerMacro
= (macroTilePitch
/factor
) * macroTileHeight
/ MicroTilePixels
>> numPipeBits
;
2314 macrosPerPitch
= pitch
/ (macroTilePitch
/factor
);
2315 macrosPerSlice
= macrosPerPitch
* height
/ macroTileHeight
;
2317 macroIndex
= elemOffset
/ factor
/ tilesPerMacro
;
2318 microIndex
= static_cast<UINT_32
>(elemOffset
% (tilesPerMacro
* factor
));
2320 macroNumber
= macroIndex
* factor
+ microIndex
% factor
;
2321 microNumber
= microIndex
/ factor
;
2323 macroX
= static_cast<UINT_32
>((macroNumber
% macrosPerPitch
));
2324 macroY
= static_cast<UINT_32
>((macroNumber
% macrosPerSlice
) / macrosPerPitch
);
2325 macroZ
= static_cast<UINT_32
>((macroNumber
/ macrosPerSlice
));
2328 microX
= microNumber
% (macroTilePitch
/ factor
/ MicroTileWidth
);
2329 microY
= (microNumber
/ (macroTilePitch
/ factor
/ MicroTileHeight
));
2331 *pX
= macroX
* (macroTilePitch
/factor
) + microX
* MicroTileWidth
;
2332 *pY
= macroY
* macroTileHeight
+ (microY
* MicroTileHeight
<< numPipeBits
);
2335 microTileCoordY
= ComputeXmaskCoordYFromPipe(pipe
,
2336 *pX
/MicroTileWidth
);
2340 // Assemble final coordinates.
2342 *pY
+= microTileCoordY
* MicroTileHeight
;
2347 ****************************************************************************************************
2348 * Lib::HwlComputeXmaskAddrFromCoord
2351 * Compute the address from an address of cmask (prior to si)
2356 ****************************************************************************************************
2358 UINT_64
Lib::HwlComputeXmaskAddrFromCoord(
2359 UINT_32 pitch
, ///< [in] pitch
2360 UINT_32 height
, ///< [in] height
2361 UINT_32 x
, ///< [in] x coord
2362 UINT_32 y
, ///< [in] y coord
2363 UINT_32 slice
, ///< [in] slice/depth index
2364 UINT_32 numSlices
, ///< [in] number of slices
2365 UINT_32 factor
, ///< [in] factor that indicates cmask(2) or htile(1)
2366 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
2367 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2368 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2369 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
2370 UINT_32
* pBitPosition
///< [out] bit position inside a byte
2374 UINT_32 numGroupBits
;
2375 UINT_32 numPipeBits
;
2376 UINT_32 newPitch
= 0;
2377 UINT_32 newHeight
= 0;
2378 UINT_64 sliceBytes
= 0;
2379 UINT_64 totalBytes
= 0;
2380 UINT_64 sliceOffset
;
2382 UINT_32 macroTileWidth
;
2383 UINT_32 macroTileHeight
;
2384 UINT_32 macroTilesPerRow
;
2385 UINT_32 macroTileBytes
;
2386 UINT_32 macroTileIndexX
;
2387 UINT_32 macroTileIndexY
;
2388 UINT_64 macroTileOffset
;
2389 UINT_32 pixelBytesPerRow
;
2390 UINT_32 pixelOffsetX
;
2391 UINT_32 pixelOffsetY
;
2392 UINT_32 pixelOffset
;
2393 UINT_64 totalOffset
;
2399 UINT_32 elemBits
= 0;
2401 UINT_32 numPipes
= m_pipes
; // This function is accessed prior to si only
2403 if (factor
== 2) //CMASK
2405 elemBits
= CmaskElemBits
;
2407 // For asics before SI, cmask is always tiled
2412 if (factor
!= 1) // Fix compile warning
2417 elemBits
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
2421 // Compute the number of group bits and pipe bits.
2423 numGroupBits
= Log2(m_pipeInterleaveBytes
);
2424 numPipeBits
= Log2(numPipes
);
2427 // Compute macro tile dimensions.
2429 if (factor
== 2) // CMASK
2431 ADDR_CMASK_FLAGS flags
= {{0}};
2433 ComputeCmaskInfo(flags
,
2445 sliceBytes
= totalBytes
/ numSlices
;
2449 ADDR_HTILE_FLAGS flags
= {{0}};
2451 ComputeHtileInfo(flags
,
2467 sliceOffset
= slice
* sliceBytes
;
2470 // Get the pipe. Note that neither slice rotation nor pipe swizzling apply for CMASK.
2472 pipe
= ComputePipeFromCoord(x
,
2475 ADDR_TM_2D_TILED_THIN1
,
2481 // Compute the number of macro tiles per row.
2483 macroTilesPerRow
= newPitch
/ macroTileWidth
;
2486 // Compute the number of bytes per macro tile.
2488 macroTileBytes
= BITS_TO_BYTES((macroTileWidth
* macroTileHeight
* elemBits
) / MicroTilePixels
);
2491 // Compute the offset to the macro tile containing the specified coordinate.
2493 macroTileIndexX
= x
/ macroTileWidth
;
2494 macroTileIndexY
= y
/ macroTileHeight
;
2495 macroTileOffset
= ((macroTileIndexY
* macroTilesPerRow
) + macroTileIndexX
) * macroTileBytes
;
2498 // Compute the pixel offset within the macro tile.
2500 pixelBytesPerRow
= BITS_TO_BYTES(macroTileWidth
* elemBits
) / MicroTileWidth
;
2503 // The nibbles are interleaved (see below), so the part of the offset relative to the x
2504 // coordinate repeats halfway across the row. (Not for HTILE)
2508 pixelOffsetX
= (x
% (macroTileWidth
/ 2)) / MicroTileWidth
;
2512 pixelOffsetX
= (x
% (macroTileWidth
)) / MicroTileWidth
* BITS_TO_BYTES(elemBits
);
2516 // Compute the y offset within the macro tile.
2518 pixelOffsetY
= (((y
% macroTileHeight
) / MicroTileHeight
) / numPipes
) * pixelBytesPerRow
;
2520 pixelOffset
= pixelOffsetX
+ pixelOffsetY
;
2523 // Combine the slice offset and macro tile offset with the pixel offset, accounting for the
2524 // pipe bits in the middle of the address.
2526 totalOffset
= ((sliceOffset
+ macroTileOffset
) >> numPipeBits
) + pixelOffset
;
2529 // Split the offset to put some bits below the pipe bits and some above.
2531 groupMask
= (1 << numGroupBits
) - 1;
2532 offsetLo
= totalOffset
& groupMask
;
2533 offsetHi
= (totalOffset
& ~groupMask
) << numPipeBits
;
2536 // Assemble the address from its components.
2540 // This is to remove warning with /analyze option
2541 UINT_32 pipeBits
= pipe
<< numGroupBits
;
2545 // Compute the bit position. The lower nibble is used when the x coordinate within the macro
2546 // tile is less than half of the macro tile width, and the upper nibble is used when the x
2547 // coordinate within the macro tile is greater than or equal to half the macro tile width.
2549 *pBitPosition
= ((x
% macroTileWidth
) < (macroTileWidth
/ factor
)) ? 0 : 4;
2554 ////////////////////////////////////////////////////////////////////////////////////////////////////
2555 // Surface Addressing Shared
2556 ////////////////////////////////////////////////////////////////////////////////////////////////////
2559 ****************************************************************************************************
2560 * Lib::ComputeSurfaceAddrFromCoordLinear
2563 * Compute address from coord for linear surface
2568 ****************************************************************************************************
2570 UINT_64
Lib::ComputeSurfaceAddrFromCoordLinear(
2571 UINT_32 x
, ///< [in] x coord
2572 UINT_32 y
, ///< [in] y coord
2573 UINT_32 slice
, ///< [in] slice/depth index
2574 UINT_32 sample
, ///< [in] sample index
2575 UINT_32 bpp
, ///< [in] bits per pixel
2576 UINT_32 pitch
, ///< [in] pitch
2577 UINT_32 height
, ///< [in] height
2578 UINT_32 numSlices
, ///< [in] number of slices
2579 UINT_32
* pBitPosition
///< [out] bit position inside a byte
2582 const UINT_64 sliceSize
= static_cast<UINT_64
>(pitch
) * height
;
2584 UINT_64 sliceOffset
= (slice
+ sample
* numSlices
)* sliceSize
;
2585 UINT_64 rowOffset
= static_cast<UINT_64
>(y
) * pitch
;
2586 UINT_64 pixOffset
= x
;
2588 UINT_64 addr
= (sliceOffset
+ rowOffset
+ pixOffset
) * bpp
;
2590 *pBitPosition
= static_cast<UINT_32
>(addr
% 8);
2597 ****************************************************************************************************
2598 * Lib::ComputeSurfaceCoordFromAddrLinear
2601 * Compute the coord from an address of a linear surface
2605 ****************************************************************************************************
2607 VOID
Lib::ComputeSurfaceCoordFromAddrLinear(
2608 UINT_64 addr
, ///< [in] address
2609 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2610 UINT_32 bpp
, ///< [in] bits per pixel
2611 UINT_32 pitch
, ///< [in] pitch
2612 UINT_32 height
, ///< [in] height
2613 UINT_32 numSlices
, ///< [in] number of slices
2614 UINT_32
* pX
, ///< [out] x coord
2615 UINT_32
* pY
, ///< [out] y coord
2616 UINT_32
* pSlice
, ///< [out] slice/depth index
2617 UINT_32
* pSample
///< [out] sample index
2620 const UINT_64 sliceSize
= static_cast<UINT_64
>(pitch
) * height
;
2621 const UINT_64 linearOffset
= (BYTES_TO_BITS(addr
) + bitPosition
) / bpp
;
2623 *pX
= static_cast<UINT_32
>((linearOffset
% sliceSize
) % pitch
);
2624 *pY
= static_cast<UINT_32
>((linearOffset
% sliceSize
) / pitch
% height
);
2625 *pSlice
= static_cast<UINT_32
>((linearOffset
/ sliceSize
) % numSlices
);
2626 *pSample
= static_cast<UINT_32
>((linearOffset
/ sliceSize
) / numSlices
);
2630 ****************************************************************************************************
2631 * Lib::ComputeSurfaceCoordFromAddrMicroTiled
2634 * Compute the coord from an address of a micro tiled surface
2638 ****************************************************************************************************
2640 VOID
Lib::ComputeSurfaceCoordFromAddrMicroTiled(
2641 UINT_64 addr
, ///< [in] address
2642 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2643 UINT_32 bpp
, ///< [in] bits per pixel
2644 UINT_32 pitch
, ///< [in] pitch
2645 UINT_32 height
, ///< [in] height
2646 UINT_32 numSamples
, ///< [in] number of samples
2647 AddrTileMode tileMode
, ///< [in] tile mode
2648 UINT_32 tileBase
, ///< [in] base offset within a tile
2649 UINT_32 compBits
, ///< [in] component bits actually needed(for planar surface)
2650 UINT_32
* pX
, ///< [out] x coord
2651 UINT_32
* pY
, ///< [out] y coord
2652 UINT_32
* pSlice
, ///< [out] slice/depth index
2653 UINT_32
* pSample
, ///< [out] sample index,
2654 AddrTileType microTileType
, ///< [in] micro tiling order
2655 BOOL_32 isDepthSampleOrder
///< [in] TRUE if in depth sample order
2659 UINT_32 microTileThickness
;
2660 UINT_32 microTileBits
;
2664 UINT_32 microTileCoordX
;
2665 UINT_32 microTileCoordY
;
2666 UINT_32 pixelOffset
;
2667 UINT_32 pixelCoordX
= 0;
2668 UINT_32 pixelCoordY
= 0;
2669 UINT_32 pixelCoordZ
= 0;
2670 UINT_32 pixelCoordS
= 0;
2673 // Convert byte address to bit address.
2675 bitAddr
= BYTES_TO_BITS(addr
) + bitPosition
;
2678 // Compute the micro tile size, in bits.
2682 case ADDR_TM_1D_TILED_THICK
:
2683 microTileThickness
= ThickTileThickness
;
2686 microTileThickness
= 1;
2690 microTileBits
= MicroTilePixels
* microTileThickness
* bpp
* numSamples
;
2693 // Compute number of bits per slice and number of bits per row of micro tiles.
2695 sliceBits
= static_cast<UINT_64
>(pitch
) * height
* microTileThickness
* bpp
* numSamples
;
2697 rowBits
= (pitch
/ MicroTileWidth
) * microTileBits
;
2700 // Extract the slice index.
2702 sliceIndex
= static_cast<UINT_32
>(bitAddr
/ sliceBits
);
2703 bitAddr
-= sliceIndex
* sliceBits
;
2706 // Extract the y coordinate of the micro tile.
2708 microTileCoordY
= static_cast<UINT_32
>(bitAddr
/ rowBits
) * MicroTileHeight
;
2709 bitAddr
-= (microTileCoordY
/ MicroTileHeight
) * rowBits
;
2712 // Extract the x coordinate of the micro tile.
2714 microTileCoordX
= static_cast<UINT_32
>(bitAddr
/ microTileBits
) * MicroTileWidth
;
2717 // Compute the pixel offset within the micro tile.
2719 pixelOffset
= static_cast<UINT_32
>(bitAddr
% microTileBits
);
2722 // Extract pixel coordinates from the offset.
2724 HwlComputePixelCoordFromOffset(pixelOffset
,
2735 isDepthSampleOrder
);
2738 // Assemble final coordinates.
2740 *pX
= microTileCoordX
+ pixelCoordX
;
2741 *pY
= microTileCoordY
+ pixelCoordY
;
2742 *pSlice
= (sliceIndex
* microTileThickness
) + pixelCoordZ
;
2743 *pSample
= pixelCoordS
;
2745 if (microTileThickness
> 1)
2752 ****************************************************************************************************
2753 * Lib::ComputePipeFromAddr
2756 * Compute the pipe number from an address
2761 ****************************************************************************************************
2763 UINT_32
Lib::ComputePipeFromAddr(
2764 UINT_64 addr
, ///< [in] address
2765 UINT_32 numPipes
///< [in] number of banks
2770 UINT_32 groupBytes
= m_pipeInterleaveBytes
; //just different terms
2773 // The LSBs of the address are arranged as follows:
2774 // bank | pipe | group
2776 // To get the pipe number, shift off the group bits and mask the pipe bits.
2780 // The LSBs of the address are arranged as follows:
2781 // bank | bankInterleave | pipe | pipeInterleave
2783 // To get the pipe number, shift off the pipe interleave bits and mask the pipe bits.
2786 pipe
= static_cast<UINT_32
>(addr
>> Log2(groupBytes
)) & (numPipes
- 1);
2792 ****************************************************************************************************
2793 * Lib::ComputeMicroTileEquation
2796 * Compute micro tile equation
2799 * If equation can be computed
2801 ****************************************************************************************************
2803 ADDR_E_RETURNCODE
Lib::ComputeMicroTileEquation(
2804 UINT_32 log2BytesPP
, ///< [in] log2 of bytes per pixel
2805 AddrTileMode tileMode
, ///< [in] tile mode
2806 AddrTileType microTileType
, ///< [in] pixel order in display/non-display mode
2807 ADDR_EQUATION
* pEquation
///< [out] equation
2810 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
2812 for (UINT_32 i
= 0; i
< log2BytesPP
; i
++)
2814 pEquation
->addr
[i
].valid
= 1;
2815 pEquation
->addr
[i
].channel
= 0;
2816 pEquation
->addr
[i
].index
= i
;
2819 ADDR_CHANNEL_SETTING
* pixelBit
= &pEquation
->addr
[log2BytesPP
];
2821 ADDR_CHANNEL_SETTING x0
= InitChannel(1, 0, log2BytesPP
+ 0);
2822 ADDR_CHANNEL_SETTING x1
= InitChannel(1, 0, log2BytesPP
+ 1);
2823 ADDR_CHANNEL_SETTING x2
= InitChannel(1, 0, log2BytesPP
+ 2);
2824 ADDR_CHANNEL_SETTING y0
= InitChannel(1, 1, 0);
2825 ADDR_CHANNEL_SETTING y1
= InitChannel(1, 1, 1);
2826 ADDR_CHANNEL_SETTING y2
= InitChannel(1, 1, 2);
2827 ADDR_CHANNEL_SETTING z0
= InitChannel(1, 2, 0);
2828 ADDR_CHANNEL_SETTING z1
= InitChannel(1, 2, 1);
2829 ADDR_CHANNEL_SETTING z2
= InitChannel(1, 2, 2);
2831 UINT_32 thickness
= Thickness(tileMode
);
2832 UINT_32 bpp
= 1 << (log2BytesPP
+ 3);
2834 if (microTileType
!= ADDR_THICK
)
2836 if (microTileType
== ADDR_DISPLAYABLE
)
2881 ADDR_ASSERT_ALWAYS();
2885 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2894 else if (microTileType
== ADDR_ROTATED
)
2896 ADDR_ASSERT(thickness
== 1);
2933 retCode
= ADDR_NOTSUPPORTED
;
2942 pEquation
->numBits
= 8 + log2BytesPP
;
2946 pEquation
->numBits
= 6 + log2BytesPP
;
2951 ADDR_ASSERT(thickness
> 1);
2982 ADDR_ASSERT_ALWAYS();
2988 pEquation
->numBits
= 8 + log2BytesPP
;
2994 pEquation
->numBits
= 9 + log2BytesPP
;
2997 // stackedDepthSlices is used for addressing mode that a tile block contains multiple slices,
2998 // which is not supported by our address lib
2999 pEquation
->stackedDepthSlices
= FALSE
;
3005 ****************************************************************************************************
3006 * Lib::ComputePixelIndexWithinMicroTile
3009 * Compute the pixel index inside a micro tile of surface
3014 ****************************************************************************************************
3016 UINT_32
Lib::ComputePixelIndexWithinMicroTile(
3017 UINT_32 x
, ///< [in] x coord
3018 UINT_32 y
, ///< [in] y coord
3019 UINT_32 z
, ///< [in] slice/depth index
3020 UINT_32 bpp
, ///< [in] bits per pixel
3021 AddrTileMode tileMode
, ///< [in] tile mode
3022 AddrTileType microTileType
///< [in] pixel order in display/non-display mode
3025 UINT_32 pixelBit0
= 0;
3026 UINT_32 pixelBit1
= 0;
3027 UINT_32 pixelBit2
= 0;
3028 UINT_32 pixelBit3
= 0;
3029 UINT_32 pixelBit4
= 0;
3030 UINT_32 pixelBit5
= 0;
3031 UINT_32 pixelBit6
= 0;
3032 UINT_32 pixelBit7
= 0;
3033 UINT_32 pixelBit8
= 0;
3034 UINT_32 pixelNumber
;
3036 UINT_32 x0
= _BIT(x
, 0);
3037 UINT_32 x1
= _BIT(x
, 1);
3038 UINT_32 x2
= _BIT(x
, 2);
3039 UINT_32 y0
= _BIT(y
, 0);
3040 UINT_32 y1
= _BIT(y
, 1);
3041 UINT_32 y2
= _BIT(y
, 2);
3042 UINT_32 z0
= _BIT(z
, 0);
3043 UINT_32 z1
= _BIT(z
, 1);
3044 UINT_32 z2
= _BIT(z
, 2);
3046 UINT_32 thickness
= Thickness(tileMode
);
3048 // Compute the pixel number within the micro tile.
3050 if (microTileType
!= ADDR_THICK
)
3052 if (microTileType
== ADDR_DISPLAYABLE
)
3097 ADDR_ASSERT_ALWAYS();
3101 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
3110 else if (microTileType
== ADDR_ROTATED
)
3112 ADDR_ASSERT(thickness
== 1);
3149 ADDR_ASSERT_ALWAYS();
3162 ADDR_ASSERT(thickness
> 1);
3193 ADDR_ASSERT_ALWAYS();
3206 pixelNumber
= ((pixelBit0
) |
3220 ****************************************************************************************************
3221 * Lib::AdjustPitchAlignment
3224 * Adjusts pitch alignment for flipping surface
3229 ****************************************************************************************************
3231 VOID
Lib::AdjustPitchAlignment(
3232 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface flags
3233 UINT_32
* pPitchAlign
///< [out] Pointer to pitch alignment
3236 // Display engine hardwires lower 5 bit of GRPH_PITCH to ZERO which means 32 pixel alignment
3237 // Maybe it will be fixed in future but let's make it general for now.
3238 if (flags
.display
|| flags
.overlay
)
3240 *pPitchAlign
= PowTwoAlign(*pPitchAlign
, 32);
3244 *pPitchAlign
= Max(m_minPitchAlignPixels
, *pPitchAlign
);
3250 ****************************************************************************************************
3251 * Lib::PadDimensions
3254 * Helper function to pad dimensions
3259 ****************************************************************************************************
3261 VOID
Lib::PadDimensions(
3262 AddrTileMode tileMode
, ///< [in] tile mode
3263 UINT_32 bpp
, ///< [in] bits per pixel
3264 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
3265 UINT_32 numSamples
, ///< [in] number of samples
3266 ADDR_TILEINFO
* pTileInfo
, ///< [in,out] bank structure.
3267 UINT_32 padDims
, ///< [in] Dimensions to pad valid value 1,2,3
3268 UINT_32 mipLevel
, ///< [in] MipLevel
3269 UINT_32
* pPitch
, ///< [in,out] pitch in pixels
3270 UINT_32
* pPitchAlign
, ///< [in,out] pitch align could be changed in HwlPadDimensions
3271 UINT_32
* pHeight
, ///< [in,out] height in pixels
3272 UINT_32 heightAlign
, ///< [in] height alignment
3273 UINT_32
* pSlices
, ///< [in,out] number of slices
3274 UINT_32 sliceAlign
///< [in] number of slice alignment
3277 UINT_32 pitchAlign
= *pPitchAlign
;
3278 UINT_32 thickness
= Thickness(tileMode
);
3280 ADDR_ASSERT(padDims
<= 3);
3283 // Override padding for mip levels
3289 // for cubemap, we only pad when client call with 6 faces as an identity
3292 padDims
= 3; // we should pad cubemap sub levels when we treat it as 3d texture
3301 // Any possibilities that padDims is 0?
3307 if (IsPow2(pitchAlign
))
3309 *pPitch
= PowTwoAlign((*pPitch
), pitchAlign
);
3311 else // add this code to pass unit test, r600 linear mode is not align bpp to pow2 for linear
3313 *pPitch
+= pitchAlign
- 1;
3314 *pPitch
/= pitchAlign
;
3315 *pPitch
*= pitchAlign
;
3320 if (IsPow2(heightAlign
))
3322 *pHeight
= PowTwoAlign((*pHeight
), heightAlign
);
3326 *pHeight
+= heightAlign
- 1;
3327 *pHeight
/= heightAlign
;
3328 *pHeight
*= heightAlign
;
3332 if (padDims
> 2 || thickness
> 1)
3334 // for cubemap single face, we do not pad slices.
3335 // if we pad it, the slice number should be set to 6 and current mip level > 1
3336 if (flags
.cube
&& (!m_configFlags
.noCubeMipSlicesPad
|| flags
.cubeAsArray
))
3338 *pSlices
= NextPow2(*pSlices
);
3341 // normal 3D texture or arrays or cubemap has a thick mode? (Just pass unit test)
3344 *pSlices
= PowTwoAlign((*pSlices
), sliceAlign
);
3349 HwlPadDimensions(tileMode
,
3363 ****************************************************************************************************
3364 * Lib::HwlPreHandleBaseLvl3xPitch
3367 * Pre-handler of 3x pitch (96 bit) adjustment
3371 ****************************************************************************************************
3373 UINT_32
Lib::HwlPreHandleBaseLvl3xPitch(
3374 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
3375 UINT_32 expPitch
///< [in] pitch
3378 ADDR_ASSERT(pIn
->width
== expPitch
);
3380 // If pitch is pre-multiplied by 3, we retrieve original one here to get correct miplevel size
3382 if (ElemLib::IsExpand3x(pIn
->format
) &&
3383 pIn
->mipLevel
== 0 &&
3384 pIn
->tileMode
== ADDR_TM_LINEAR_ALIGNED
)
3387 expPitch
= NextPow2(expPitch
);
3394 ****************************************************************************************************
3395 * Lib::HwlPostHandleBaseLvl3xPitch
3398 * Post-handler of 3x pitch adjustment
3402 ****************************************************************************************************
3404 UINT_32
Lib::HwlPostHandleBaseLvl3xPitch(
3405 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
3406 UINT_32 expPitch
///< [in] pitch
3410 // 96 bits surface of sub levels require element pitch of 32 bits instead
3411 // So we just return pitch in 32 bit pixels without timing 3
3413 if (ElemLib::IsExpand3x(pIn
->format
) &&
3414 pIn
->mipLevel
== 0 &&
3415 pIn
->tileMode
== ADDR_TM_LINEAR_ALIGNED
)
3425 ****************************************************************************************************
3429 * Check if the tile mode is macro tiled
3432 * TRUE if it is macro tiled (2D/2B/3D/3B)
3433 ****************************************************************************************************
3435 BOOL_32
Lib::IsMacroTiled(
3436 AddrTileMode tileMode
) ///< [in] tile mode
3438 return ModeFlags
[tileMode
].isMacro
;
3442 ****************************************************************************************************
3443 * Lib::IsMacro3dTiled
3446 * Check if the tile mode is 3D macro tiled
3449 * TRUE if it is 3D macro tiled
3450 ****************************************************************************************************
3452 BOOL_32
Lib::IsMacro3dTiled(
3453 AddrTileMode tileMode
) ///< [in] tile mode
3455 return ModeFlags
[tileMode
].isMacro3d
;
3459 ****************************************************************************************************
3463 * Check if the tile mode is micro tiled
3466 * TRUE if micro tiled
3467 ****************************************************************************************************
3469 BOOL_32
Lib::IsMicroTiled(
3470 AddrTileMode tileMode
) ///< [in] tile mode
3472 return ModeFlags
[tileMode
].isMicro
;
3476 ****************************************************************************************************
3480 * Check if the tile mode is linear
3484 ****************************************************************************************************
3486 BOOL_32
Lib::IsLinear(
3487 AddrTileMode tileMode
) ///< [in] tile mode
3489 return ModeFlags
[tileMode
].isLinear
;
3493 ****************************************************************************************************
3494 * Lib::IsPrtNoRotationTileMode
3497 * Return TRUE if it is prt tile without rotation
3499 * This function just used by CI
3500 ****************************************************************************************************
3502 BOOL_32
Lib::IsPrtNoRotationTileMode(
3503 AddrTileMode tileMode
)
3505 return ModeFlags
[tileMode
].isPrtNoRotation
;
3509 ****************************************************************************************************
3510 * Lib::IsPrtTileMode
3513 * Return TRUE if it is prt tile
3515 * This function just used by CI
3516 ****************************************************************************************************
3518 BOOL_32
Lib::IsPrtTileMode(
3519 AddrTileMode tileMode
)
3521 return ModeFlags
[tileMode
].isPrt
;
3525 ****************************************************************************************************
3526 * Lib::ComputeMipLevel
3529 * Compute mipmap level width/height/slices
3532 ****************************************************************************************************
3534 VOID
Lib::ComputeMipLevel(
3535 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
///< [in,out] Input structure
3538 // Check if HWL has handled
3539 BOOL_32 hwlHandled
= FALSE
;
3542 if (ElemLib::IsBlockCompressed(pIn
->format
))
3544 if (pIn
->mipLevel
== 0)
3546 // DXTn's level 0 must be multiple of 4
3547 // But there are exceptions:
3548 // 1. Internal surface creation in hostblt/vsblt/etc...
3549 // 2. Runtime doesn't reject ATI1/ATI2 whose width/height are not multiple of 4
3550 pIn
->width
= PowTwoAlign(pIn
->width
, 4);
3551 pIn
->height
= PowTwoAlign(pIn
->height
, 4);
3555 hwlHandled
= HwlComputeMipLevel(pIn
);
3559 ****************************************************************************************************
3563 * Check if surface can be degraded to 1D
3566 ****************************************************************************************************
3568 BOOL_32
Lib::DegradeTo1D(
3569 UINT_32 width
, ///< surface width
3570 UINT_32 height
, ///< surface height
3571 UINT_32 macroTilePitchAlign
, ///< macro tile pitch align
3572 UINT_32 macroTileHeightAlign
///< macro tile height align
3575 BOOL_32 degrade
= ((width
< macroTilePitchAlign
) || (height
< macroTileHeightAlign
));
3577 // Check whether 2D tiling still has too much footprint
3578 if (degrade
== FALSE
)
3580 // Only check width and height as slices are aligned to thickness
3581 UINT_64 unalignedSize
= width
* height
;
3583 UINT_32 alignedPitch
= PowTwoAlign(width
, macroTilePitchAlign
);
3584 UINT_32 alignedHeight
= PowTwoAlign(height
, macroTileHeightAlign
);
3585 UINT_64 alignedSize
= alignedPitch
* alignedHeight
;
3587 // alignedSize > 1.5 * unalignedSize
3588 if (2 * alignedSize
> 3 * unalignedSize
)
3598 ****************************************************************************************************
3599 * Lib::OptimizeTileMode
3602 * Check if base level's tile mode can be optimized (degraded)
3605 ****************************************************************************************************
3607 VOID
Lib::OptimizeTileMode(
3608 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in, out] structure for surface info
3611 AddrTileMode tileMode
= pInOut
->tileMode
;
3613 BOOL_32 doOpt
= (pInOut
->flags
.opt4Space
== TRUE
) ||
3614 (pInOut
->flags
.minimizeAlignment
== TRUE
) ||
3615 (pInOut
->maxBaseAlign
!= 0);
3617 BOOL_32 convertToPrt
= FALSE
;
3619 // Optimization can only be done on level 0 and samples <= 1
3620 if ((doOpt
== TRUE
) &&
3621 (pInOut
->mipLevel
== 0) &&
3622 (IsPrtTileMode(tileMode
) == FALSE
) &&
3623 (pInOut
->flags
.prt
== FALSE
))
3625 UINT_32 width
= pInOut
->width
;
3626 UINT_32 height
= pInOut
->height
;
3627 UINT_32 thickness
= Thickness(tileMode
);
3628 BOOL_32 macroTiledOK
= TRUE
;
3629 UINT_32 macroWidthAlign
= 0;
3630 UINT_32 macroHeightAlign
= 0;
3631 UINT_32 macroSizeAlign
= 0;
3633 if (IsMacroTiled(tileMode
))
3635 macroTiledOK
= HwlGetAlignmentInfoMacroTiled(pInOut
,
3643 if ((pInOut
->flags
.display
== FALSE
) &&
3644 (pInOut
->flags
.opt4Space
== TRUE
) &&
3645 (pInOut
->numSamples
<= 1))
3647 // Check if linear mode is optimal
3648 if ((pInOut
->height
== 1) &&
3649 (IsLinear(tileMode
) == FALSE
) &&
3650 (ElemLib::IsBlockCompressed(pInOut
->format
) == FALSE
) &&
3651 (pInOut
->flags
.depth
== FALSE
) &&
3652 (pInOut
->flags
.stencil
== FALSE
) &&
3653 (m_configFlags
.disableLinearOpt
== FALSE
) &&
3654 (pInOut
->flags
.disableLinearOpt
== FALSE
))
3656 tileMode
= ADDR_TM_LINEAR_ALIGNED
;
3658 else if (IsMacroTiled(tileMode
) && (pInOut
->flags
.tcCompatible
== FALSE
))
3660 if (DegradeTo1D(width
, height
, macroWidthAlign
, macroHeightAlign
))
3662 tileMode
= (thickness
== 1) ?
3663 ADDR_TM_1D_TILED_THIN1
: ADDR_TM_1D_TILED_THICK
;
3665 else if ((thickness
> 1) && (pInOut
->flags
.disallowLargeThickDegrade
== 0))
3667 // As in the following HwlComputeSurfaceInfo, thick modes may be degraded to
3668 // thinner modes, we should re-evaluate whether the corresponding
3669 // thinner modes should be degraded. If so, we choose 1D thick mode instead.
3670 tileMode
= DegradeLargeThickTile(pInOut
->tileMode
, pInOut
->bpp
);
3672 if (tileMode
!= pInOut
->tileMode
)
3674 // Get thickness again after large thick degrade
3675 thickness
= Thickness(tileMode
);
3677 ADDR_COMPUTE_SURFACE_INFO_INPUT input
= *pInOut
;
3678 input
.tileMode
= tileMode
;
3680 macroTiledOK
= HwlGetAlignmentInfoMacroTiled(&input
,
3686 DegradeTo1D(width
, height
, macroWidthAlign
, macroHeightAlign
))
3688 tileMode
= ADDR_TM_1D_TILED_THICK
;
3697 if ((pInOut
->flags
.minimizeAlignment
== TRUE
) &&
3698 (pInOut
->numSamples
<= 1) &&
3699 (IsMacroTiled(tileMode
) == TRUE
))
3701 UINT_32 macroSize
= PowTwoAlign(width
, macroWidthAlign
) *
3702 PowTwoAlign(height
, macroHeightAlign
);
3703 UINT_32 microSize
= PowTwoAlign(width
, MicroTileWidth
) *
3704 PowTwoAlign(height
, MicroTileHeight
);
3706 if (macroSize
> microSize
)
3708 tileMode
= (thickness
== 1) ?
3709 ADDR_TM_1D_TILED_THIN1
: ADDR_TM_1D_TILED_THICK
;
3713 if ((pInOut
->maxBaseAlign
!= 0) &&
3714 (IsMacroTiled(tileMode
) == TRUE
))
3716 if (macroSizeAlign
> pInOut
->maxBaseAlign
)
3718 if (pInOut
->numSamples
> 1)
3720 ADDR_ASSERT(pInOut
->maxBaseAlign
>= Block64K
);
3722 convertToPrt
= TRUE
;
3724 else if (pInOut
->maxBaseAlign
< Block64K
)
3726 tileMode
= (thickness
== 1) ?
3727 ADDR_TM_1D_TILED_THIN1
: ADDR_TM_1D_TILED_THICK
;
3731 convertToPrt
= TRUE
;
3741 if ((pInOut
->flags
.matchStencilTileCfg
== TRUE
) && (pInOut
->numSamples
<= 1))
3743 pInOut
->tileMode
= ADDR_TM_1D_TILED_THIN1
;
3747 HwlSetPrtTileMode(pInOut
);
3750 else if (tileMode
!= pInOut
->tileMode
)
3752 pInOut
->tileMode
= tileMode
;
3755 HwlOptimizeTileMode(pInOut
);
3759 ****************************************************************************************************
3760 * Lib::DegradeLargeThickTile
3763 * Check if the thickness needs to be reduced if a tile is too large
3765 * The degraded tile mode (unchanged if not degraded)
3766 ****************************************************************************************************
3768 AddrTileMode
Lib::DegradeLargeThickTile(
3769 AddrTileMode tileMode
,
3772 // Override tilemode
3773 // When tile_width (8) * tile_height (8) * thickness * element_bytes is > row_size,
3774 // it is better to just use THIN mode in this case
3775 UINT_32 thickness
= Thickness(tileMode
);
3777 if (thickness
> 1 && m_configFlags
.allowLargeThickTile
== 0)
3779 UINT_32 tileSize
= MicroTilePixels
* thickness
* (bpp
>> 3);
3781 if (tileSize
> m_rowSize
)
3785 case ADDR_TM_2D_TILED_XTHICK
:
3786 if ((tileSize
>> 1) <= m_rowSize
)
3788 tileMode
= ADDR_TM_2D_TILED_THICK
;
3791 // else fall through
3792 case ADDR_TM_2D_TILED_THICK
:
3793 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3796 case ADDR_TM_3D_TILED_XTHICK
:
3797 if ((tileSize
>> 1) <= m_rowSize
)
3799 tileMode
= ADDR_TM_3D_TILED_THICK
;
3802 // else fall through
3803 case ADDR_TM_3D_TILED_THICK
:
3804 tileMode
= ADDR_TM_3D_TILED_THIN1
;
3807 case ADDR_TM_PRT_TILED_THICK
:
3808 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
3811 case ADDR_TM_PRT_2D_TILED_THICK
:
3812 tileMode
= ADDR_TM_PRT_2D_TILED_THIN1
;
3815 case ADDR_TM_PRT_3D_TILED_THICK
:
3816 tileMode
= ADDR_TM_PRT_3D_TILED_THIN1
;
3829 ****************************************************************************************************
3830 * Lib::PostComputeMipLevel
3832 * Compute MipLevel info (including level 0) after surface adjustment
3835 ****************************************************************************************************
3837 ADDR_E_RETURNCODE
Lib::PostComputeMipLevel(
3838 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in,out] Input structure
3839 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] Output structure
3842 // Mipmap including level 0 must be pow2 padded since either SI hw expects so or it is
3843 // required by CFX for Hw Compatibility between NI and SI. Otherwise it is only needed for
3844 // mipLevel > 0. Any h/w has different requirement should implement its own virtual function
3846 if (pIn
->flags
.pow2Pad
)
3848 pIn
->width
= NextPow2(pIn
->width
);
3849 pIn
->height
= NextPow2(pIn
->height
);
3850 pIn
->numSlices
= NextPow2(pIn
->numSlices
);
3852 else if (pIn
->mipLevel
> 0)
3854 pIn
->width
= NextPow2(pIn
->width
);
3855 pIn
->height
= NextPow2(pIn
->height
);
3857 if (!pIn
->flags
.cube
)
3859 pIn
->numSlices
= NextPow2(pIn
->numSlices
);
3862 // for cubemap, we keep its value at first
3869 ****************************************************************************************************
3870 * Lib::HwlSetupTileCfg
3873 * Map tile index to tile setting.
3876 ****************************************************************************************************
3878 ADDR_E_RETURNCODE
Lib::HwlSetupTileCfg(
3879 UINT_32 bpp
, ///< Bits per pixel
3880 INT_32 index
, ///< [in] Tile index
3881 INT_32 macroModeIndex
, ///< [in] Index in macro tile mode table(CI)
3882 ADDR_TILEINFO
* pInfo
, ///< [out] Tile Info
3883 AddrTileMode
* pMode
, ///< [out] Tile mode
3884 AddrTileType
* pType
///< [out] Tile type
3887 return ADDR_NOTSUPPORTED
;
3891 ****************************************************************************************************
3898 ****************************************************************************************************
3900 UINT_32
Lib::HwlGetPipes(
3901 const ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
3904 //pTileInfo can be NULL when asic is 6xx and 8xx.
3909 ****************************************************************************************************
3910 * Lib::ComputeQbStereoInfo
3913 * Get quad buffer stereo information
3916 ****************************************************************************************************
3918 VOID
Lib::ComputeQbStereoInfo(
3919 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in,out] updated pOut+pStereoInfo
3922 ADDR_ASSERT(pOut
->bpp
>= 8);
3923 ADDR_ASSERT((pOut
->surfSize
% pOut
->baseAlign
) == 0);
3925 // Save original height
3926 pOut
->pStereoInfo
->eyeHeight
= pOut
->height
;
3929 pOut
->pStereoInfo
->rightOffset
= static_cast<UINT_32
>(pOut
->surfSize
);
3931 pOut
->pStereoInfo
->rightSwizzle
= HwlComputeQbStereoRightSwizzle(pOut
);
3934 pOut
->pixelHeight
<<= 1;
3937 pOut
->surfSize
<<= 1;
3939 // Right start address meets the base align since it is guaranteed by AddrLib1
3941 // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo.
3946 ****************************************************************************************************
3947 * Lib::ComputePrtInfo
3950 * Compute prt surface related info
3954 ****************************************************************************************************
3956 ADDR_E_RETURNCODE
Lib::ComputePrtInfo(
3957 const ADDR_PRT_INFO_INPUT
* pIn
,
3958 ADDR_PRT_INFO_OUTPUT
* pOut
) const
3960 ADDR_ASSERT(pOut
!= NULL
);
3962 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
3964 UINT_32 expandX
= 1;
3965 UINT_32 expandY
= 1;
3968 UINT_32 bpp
= GetElemLib()->GetBitsPerPixel(pIn
->format
,
3973 if (bpp
<8 || bpp
== 24 || bpp
== 48 || bpp
== 96)
3975 returnCode
= ADDR_INVALIDPARAMS
;
3978 UINT_32 numFrags
= pIn
->numFrags
;
3979 ADDR_ASSERT(numFrags
<= 8);
3981 UINT_32 tileWidth
= 0;
3982 UINT_32 tileHeight
= 0;
3983 if (returnCode
== ADDR_OK
)
3985 // 3D texture without depth or 2d texture
3986 if (pIn
->baseMipDepth
> 1 || pIn
->baseMipHeight
> 1)
4005 // assume it is BC1/4
4009 if (elemMode
== ADDR_UNCOMPRESSED
)
4015 else if (bpp
== 128)
4017 // assume it is BC2/3/5/6H/7
4021 if (elemMode
== ADDR_UNCOMPRESSED
)
4030 tileWidth
= tileWidth
/ 2;
4032 else if (numFrags
== 4)
4034 tileWidth
= tileWidth
/ 2;
4035 tileHeight
= tileHeight
/ 2;
4037 else if (numFrags
== 8)
4039 tileWidth
= tileWidth
/ 4;
4040 tileHeight
= tileHeight
/ 2;
4062 else if (bpp
== 128)
4069 pOut
->prtTileWidth
= tileWidth
;
4070 pOut
->prtTileHeight
= tileHeight
;