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 AddrLib1 base class..
31 ***************************************************************************************************
34 #include "addrinterface.h"
36 #include "addrcommon.h"
39 ///////////////////////////////////////////////////////////////////////////////////////////////////
40 // Static Const Member
41 ///////////////////////////////////////////////////////////////////////////////////////////////////
43 const AddrTileModeFlags
AddrLib1::m_modeFlags
[ADDR_TM_COUNT
] =
45 {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_GENERAL
46 {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_ALIGNED
47 {1, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THIN1
48 {4, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THICK
49 {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN1
50 {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN2
51 {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN4
52 {4, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THICK
53 {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN1
54 {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN2
55 {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN4
56 {4, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THICK
57 {1, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THIN1
58 {4, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THICK
59 {1, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THIN1
60 {4, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THICK
61 {8, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_XTHICK
62 {8, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_XTHICK
63 {1, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_POWER_SAVE
64 {1, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THIN1
65 {1, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THIN1
66 {1, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THIN1
67 {4, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THICK
68 {4, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THICK
69 {4, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THICK
72 ///////////////////////////////////////////////////////////////////////////////////////////////////
73 // Constructor/Destructor
74 ///////////////////////////////////////////////////////////////////////////////////////////////////
77 ***************************************************************************************************
81 * Constructor for the AddrLib1 class
83 ***************************************************************************************************
85 AddrLib1::AddrLib1() :
91 ***************************************************************************************************
95 * Constructor for the AddrLib1 class with hClient as parameter
97 ***************************************************************************************************
99 AddrLib1::AddrLib1(const AddrClient
* pClient
) :
105 ***************************************************************************************************
106 * AddrLib1::~AddrLib1
109 * Destructor for the AddrLib1 class
111 ***************************************************************************************************
113 AddrLib1::~AddrLib1()
118 ***************************************************************************************************
119 * AddrLib1::GetAddrLib1
122 * Get AddrLib1 pointer
125 * An AddrLib1 class pointer
126 ***************************************************************************************************
128 AddrLib1
* AddrLib1::GetAddrLib1(
129 ADDR_HANDLE hLib
) ///< [in] handle of ADDR_HANDLE
131 AddrLib
*pAddrLib
= AddrLib::GetAddrLib(hLib
);
132 if ((pAddrLib
!= NULL
) &&
133 ((pAddrLib
->GetAddrChipFamily() == ADDR_CHIP_FAMILY_IVLD
) ||
134 (pAddrLib
->GetAddrChipFamily() > ADDR_CHIP_FAMILY_VI
)))
136 // only valid and pre-VI AISC can use AddrLib1 function.
137 ADDR_ASSERT_ALWAYS();
140 return static_cast<AddrLib1
*>(hLib
);
144 ///////////////////////////////////////////////////////////////////////////////////////////////////
146 ///////////////////////////////////////////////////////////////////////////////////////////////////
150 ***************************************************************************************************
151 * AddrLib1::ComputeSurfaceInfo
154 * Interface function stub of AddrComputeSurfaceInfo.
158 ***************************************************************************************************
160 ADDR_E_RETURNCODE
AddrLib1::ComputeSurfaceInfo(
161 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
162 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
165 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
167 if (GetFillSizeFieldsFlags() == TRUE
)
169 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT
)) ||
170 (pOut
->size
!= sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT
)))
172 returnCode
= ADDR_PARAMSIZEMISMATCH
;
176 // We suggest client do sanity check but a check here is also good
179 returnCode
= ADDR_INVALIDPARAMS
;
182 // Thick modes don't support multisample
183 if (ComputeSurfaceThickness(pIn
->tileMode
) > 1 && pIn
->numSamples
> 1)
185 returnCode
= ADDR_INVALIDPARAMS
;
188 if (returnCode
== ADDR_OK
)
190 // Get a local copy of input structure and only reference pIn for unadjusted values
191 ADDR_COMPUTE_SURFACE_INFO_INPUT localIn
= *pIn
;
192 ADDR_TILEINFO tileInfoNull
= {0};
196 // If the original input has a valid ADDR_TILEINFO pointer then copy its contents.
197 // Otherwise the default 0's in tileInfoNull are used.
200 tileInfoNull
= *pIn
->pTileInfo
;
202 localIn
.pTileInfo
= &tileInfoNull
;
205 localIn
.numSamples
= pIn
->numSamples
== 0 ? 1 : pIn
->numSamples
;
207 // Do mipmap check first
208 // If format is BCn, pre-pad dimension to power-of-two according to HWL
209 ComputeMipLevel(&localIn
);
211 if (m_configFlags
.checkLast2DLevel
)
213 // Save this level's original height in pixels
214 pOut
->height
= pIn
->height
;
219 AddrElemMode elemMode
;
221 // Save outputs that may not go through HWL
222 pOut
->pixelBits
= localIn
.bpp
;
223 pOut
->numSamples
= localIn
.numSamples
;
224 pOut
->last2DLevel
= FALSE
;
225 pOut
->tcCompatible
= FALSE
;
228 if (localIn
.numSamples
> 1)
230 ADDR_ASSERT(localIn
.mipLevel
== 0);
234 if (localIn
.format
!= ADDR_FMT_INVALID
) // Set format to INVALID will skip this conversion
236 // Get compression/expansion factors and element mode
237 // (which indicates compression/expansion
238 localIn
.bpp
= GetElemLib()->GetBitsPerPixel(localIn
.format
,
243 // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
244 // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
245 // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
246 // restrictions are different.
247 // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
248 // but we use this flag to skip RestoreSurfaceInfo below
250 if ((elemMode
== ADDR_EXPANDED
) &&
253 ADDR_ASSERT(localIn
.tileMode
== ADDR_TM_LINEAR_ALIGNED
|| localIn
.height
== 1);
256 GetElemLib()->AdjustSurfaceInfo(elemMode
,
264 // Overwrite these parameters if we have a valid format
266 else if (localIn
.bpp
!= 0)
268 localIn
.width
= (localIn
.width
!= 0) ? localIn
.width
: 1;
269 localIn
.height
= (localIn
.height
!= 0) ? localIn
.height
: 1;
271 else // Rule out some invalid parameters
273 ADDR_ASSERT_ALWAYS();
275 returnCode
= ADDR_INVALIDPARAMS
;
278 // Check mipmap after surface expansion
279 if (returnCode
== ADDR_OK
)
281 returnCode
= PostComputeMipLevel(&localIn
, pOut
);
284 if (returnCode
== ADDR_OK
)
286 if (UseTileIndex(localIn
.tileIndex
))
288 // Make sure pTileInfo is not NULL
289 ADDR_ASSERT(localIn
.pTileInfo
);
291 UINT_32 numSamples
= GetNumFragments(localIn
.numSamples
, localIn
.numFrags
);
293 INT_32 macroModeIndex
= TileIndexNoMacroIndex
;
295 if (localIn
.tileIndex
!= TileIndexLinearGeneral
)
297 // Try finding a macroModeIndex
298 macroModeIndex
= HwlComputeMacroModeIndex(localIn
.tileIndex
,
307 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
308 if (macroModeIndex
== TileIndexNoMacroIndex
)
310 returnCode
= HwlSetupTileCfg(localIn
.tileIndex
, macroModeIndex
,
312 &localIn
.tileMode
, &localIn
.tileType
);
314 // If macroModeIndex is invalid, then assert this is not macro tiled
315 else if (macroModeIndex
== TileIndexInvalid
)
317 ADDR_ASSERT(!IsMacroTiled(localIn
.tileMode
));
320 pOut
->macroModeIndex
= macroModeIndex
;
324 if (returnCode
== ADDR_OK
)
326 AddrTileMode tileMode
= localIn
.tileMode
;
327 AddrTileType tileType
= localIn
.tileType
;
329 // HWL layer may override tile mode if necessary
330 if (HwlOverrideTileMode(&localIn
, &tileMode
, &tileType
))
332 localIn
.tileMode
= tileMode
;
333 localIn
.tileType
= tileType
;
335 // Optimize tile mode if possible
336 if (OptimizeTileMode(&localIn
, &tileMode
))
338 localIn
.tileMode
= tileMode
;
342 // Call main function to compute surface info
343 if (returnCode
== ADDR_OK
)
345 returnCode
= HwlComputeSurfaceInfo(&localIn
, pOut
);
348 if (returnCode
== ADDR_OK
)
350 // Since bpp might be changed we just pass it through
351 pOut
->bpp
= localIn
.bpp
;
353 // Also original width/height/bpp
354 pOut
->pixelPitch
= pOut
->pitch
;
355 pOut
->pixelHeight
= pOut
->height
;
358 if (localIn
.flags
.display
)
360 ADDR_ASSERT((pOut
->pitchAlign
% 32) == 0);
364 if (localIn
.format
!= ADDR_FMT_INVALID
)
367 // 96 bits surface of level 1+ requires element pitch of 32 bits instead
368 // In hwl function we skip multiplication of 3 then we should skip division of 3
369 // We keep pitch that represents 32 bit element instead of 96 bits since we
370 // will get an odd number if divided by 3.
372 if (!((expandX
== 3) && (localIn
.mipLevel
> 0)))
375 GetElemLib()->RestoreSurfaceInfo(elemMode
,
384 if (localIn
.flags
.qbStereo
)
386 if (pOut
->pStereoInfo
)
388 ComputeQbStereoInfo(pOut
);
392 if (localIn
.flags
.volume
) // For volume sliceSize equals to all z-slices
394 pOut
->sliceSize
= pOut
->surfSize
;
396 else // For array: sliceSize is likely to have slice-padding (the last one)
398 pOut
->sliceSize
= pOut
->surfSize
/ pOut
->depth
;
401 if (pIn
->numSlices
> 1)
403 // If this is the last slice then add the padding size to this slice
404 if (pIn
->slice
== (pIn
->numSlices
- 1))
406 pOut
->sliceSize
+= pOut
->sliceSize
* (pOut
->depth
- pIn
->numSlices
);
408 else if (m_configFlags
.checkLast2DLevel
)
410 // Reset last2DLevel flag if this is not the last array slice
411 pOut
->last2DLevel
= FALSE
;
416 pOut
->pitchTileMax
= pOut
->pitch
/ 8 - 1;
417 pOut
->heightTileMax
= pOut
->height
/ 8 - 1;
418 pOut
->sliceTileMax
= pOut
->pitch
* pOut
->height
/ 64 - 1;
426 ***************************************************************************************************
427 * AddrLib1::ComputeSurfaceInfo
430 * Interface function stub of AddrComputeSurfaceInfo.
434 ***************************************************************************************************
436 ADDR_E_RETURNCODE
AddrLib1::ComputeSurfaceAddrFromCoord(
437 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
438 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
441 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
443 if (GetFillSizeFieldsFlags() == TRUE
)
445 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
)) ||
446 (pOut
->size
!= sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
)))
448 returnCode
= ADDR_PARAMSIZEMISMATCH
;
452 if (returnCode
== ADDR_OK
)
454 ADDR_TILEINFO tileInfoNull
;
455 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT input
;
457 if (UseTileIndex(pIn
->tileIndex
))
460 // Use temp tile info for calcalation
461 input
.pTileInfo
= &tileInfoNull
;
463 const ADDR_SURFACE_FLAGS flags
= {{0}};
464 UINT_32 numSamples
= GetNumFragments(pIn
->numSamples
, pIn
->numFrags
);
466 // Try finding a macroModeIndex
467 INT_32 macroModeIndex
= HwlComputeMacroModeIndex(input
.tileIndex
,
475 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
476 if (macroModeIndex
== TileIndexNoMacroIndex
)
478 returnCode
= HwlSetupTileCfg(input
.tileIndex
, macroModeIndex
,
479 input
.pTileInfo
, &input
.tileMode
, &input
.tileType
);
481 // If macroModeIndex is invalid, then assert this is not macro tiled
482 else if (macroModeIndex
== TileIndexInvalid
)
484 ADDR_ASSERT(!IsMacroTiled(input
.tileMode
));
487 // Change the input structure
491 if (returnCode
== ADDR_OK
)
493 returnCode
= HwlComputeSurfaceAddrFromCoord(pIn
, pOut
);
495 if (returnCode
== ADDR_OK
)
497 pOut
->prtBlockIndex
= static_cast<UINT_32
>(pOut
->addr
/ (64 * 1024));
506 ***************************************************************************************************
507 * AddrLib1::ComputeSurfaceCoordFromAddr
510 * Interface function stub of ComputeSurfaceCoordFromAddr.
514 ***************************************************************************************************
516 ADDR_E_RETURNCODE
AddrLib1::ComputeSurfaceCoordFromAddr(
517 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
518 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
521 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
523 if (GetFillSizeFieldsFlags() == TRUE
)
525 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
)) ||
526 (pOut
->size
!= sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
)))
528 returnCode
= ADDR_PARAMSIZEMISMATCH
;
532 if (returnCode
== ADDR_OK
)
534 ADDR_TILEINFO tileInfoNull
;
535 ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT input
;
537 if (UseTileIndex(pIn
->tileIndex
))
540 // Use temp tile info for calcalation
541 input
.pTileInfo
= &tileInfoNull
;
543 const ADDR_SURFACE_FLAGS flags
= {{0}};
544 UINT_32 numSamples
= GetNumFragments(pIn
->numSamples
, pIn
->numFrags
);
546 // Try finding a macroModeIndex
547 INT_32 macroModeIndex
= HwlComputeMacroModeIndex(input
.tileIndex
,
555 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
556 if (macroModeIndex
== TileIndexNoMacroIndex
)
558 returnCode
= HwlSetupTileCfg(input
.tileIndex
, macroModeIndex
,
559 input
.pTileInfo
, &input
.tileMode
, &input
.tileType
);
561 // If macroModeIndex is invalid, then assert this is not macro tiled
562 else if (macroModeIndex
== TileIndexInvalid
)
564 ADDR_ASSERT(!IsMacroTiled(input
.tileMode
));
567 // Change the input structure
571 if (returnCode
== ADDR_OK
)
573 returnCode
= HwlComputeSurfaceCoordFromAddr(pIn
, pOut
);
581 ***************************************************************************************************
582 * AddrLib1::ComputeSliceTileSwizzle
585 * Interface function stub of ComputeSliceTileSwizzle.
589 ***************************************************************************************************
591 ADDR_E_RETURNCODE
AddrLib1::ComputeSliceTileSwizzle(
592 const ADDR_COMPUTE_SLICESWIZZLE_INPUT
* pIn
, ///< [in] input structure
593 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
* pOut
///< [out] output structure
596 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
598 if (GetFillSizeFieldsFlags() == TRUE
)
600 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SLICESWIZZLE_INPUT
)) ||
601 (pOut
->size
!= sizeof(ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
)))
603 returnCode
= ADDR_PARAMSIZEMISMATCH
;
607 if (returnCode
== ADDR_OK
)
609 ADDR_TILEINFO tileInfoNull
;
610 ADDR_COMPUTE_SLICESWIZZLE_INPUT input
;
612 if (UseTileIndex(pIn
->tileIndex
))
615 // Use temp tile info for calcalation
616 input
.pTileInfo
= &tileInfoNull
;
618 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
,
619 input
.pTileInfo
, &input
.tileMode
);
620 // Change the input structure
624 if (returnCode
== ADDR_OK
)
626 returnCode
= HwlComputeSliceTileSwizzle(pIn
, pOut
);
634 ***************************************************************************************************
635 * AddrLib1::ExtractBankPipeSwizzle
638 * Interface function stub of AddrExtractBankPipeSwizzle.
642 ***************************************************************************************************
644 ADDR_E_RETURNCODE
AddrLib1::ExtractBankPipeSwizzle(
645 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
646 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
649 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
651 if (GetFillSizeFieldsFlags() == TRUE
)
653 if ((pIn
->size
!= sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
)) ||
654 (pOut
->size
!= sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
)))
656 returnCode
= ADDR_PARAMSIZEMISMATCH
;
660 if (returnCode
== ADDR_OK
)
662 ADDR_TILEINFO tileInfoNull
;
663 ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT input
;
665 if (UseTileIndex(pIn
->tileIndex
))
668 // Use temp tile info for calcalation
669 input
.pTileInfo
= &tileInfoNull
;
671 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
672 // Change the input structure
676 if (returnCode
== ADDR_OK
)
678 returnCode
= HwlExtractBankPipeSwizzle(pIn
, pOut
);
686 ***************************************************************************************************
687 * AddrLib1::CombineBankPipeSwizzle
690 * Interface function stub of AddrCombineBankPipeSwizzle.
694 ***************************************************************************************************
696 ADDR_E_RETURNCODE
AddrLib1::CombineBankPipeSwizzle(
697 const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
698 ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
701 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
703 if (GetFillSizeFieldsFlags() == TRUE
)
705 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT
)) ||
706 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT
)))
708 returnCode
= ADDR_PARAMSIZEMISMATCH
;
712 if (returnCode
== ADDR_OK
)
714 ADDR_TILEINFO tileInfoNull
;
715 ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT input
;
717 if (UseTileIndex(pIn
->tileIndex
))
720 // Use temp tile info for calcalation
721 input
.pTileInfo
= &tileInfoNull
;
723 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
724 // Change the input structure
728 if (returnCode
== ADDR_OK
)
730 returnCode
= HwlCombineBankPipeSwizzle(pIn
->bankSwizzle
,
742 ***************************************************************************************************
743 * AddrLib1::ComputeBaseSwizzle
746 * Interface function stub of AddrCompueBaseSwizzle.
749 ***************************************************************************************************
751 ADDR_E_RETURNCODE
AddrLib1::ComputeBaseSwizzle(
752 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT
* pIn
,
753 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
* pOut
) const
755 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
757 if (GetFillSizeFieldsFlags() == TRUE
)
759 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT
)) ||
760 (pOut
->size
!= sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
)))
762 returnCode
= ADDR_PARAMSIZEMISMATCH
;
766 if (returnCode
== ADDR_OK
)
768 ADDR_TILEINFO tileInfoNull
;
769 ADDR_COMPUTE_BASE_SWIZZLE_INPUT input
;
771 if (UseTileIndex(pIn
->tileIndex
))
774 // Use temp tile info for calcalation
775 input
.pTileInfo
= &tileInfoNull
;
777 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
778 // Change the input structure
782 if (returnCode
== ADDR_OK
)
784 if (IsMacroTiled(pIn
->tileMode
))
786 returnCode
= HwlComputeBaseSwizzle(pIn
, pOut
);
790 pOut
->tileSwizzle
= 0;
799 ***************************************************************************************************
800 * AddrLib1::ComputeFmaskInfo
803 * Interface function stub of ComputeFmaskInfo.
807 ***************************************************************************************************
809 ADDR_E_RETURNCODE
AddrLib1::ComputeFmaskInfo(
810 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
811 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
814 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
816 if (GetFillSizeFieldsFlags() == TRUE
)
818 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT
)) ||
819 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT
)))
821 returnCode
= ADDR_PARAMSIZEMISMATCH
;
826 if (ComputeSurfaceThickness(pIn
->tileMode
) > 1)
828 returnCode
= ADDR_INVALIDPARAMS
;
831 if (returnCode
== ADDR_OK
)
833 ADDR_TILEINFO tileInfoNull
;
834 ADDR_COMPUTE_FMASK_INFO_INPUT input
;
836 if (UseTileIndex(pIn
->tileIndex
))
842 // Use temp tile info for calcalation
843 input
.pTileInfo
= pOut
->pTileInfo
;
847 input
.pTileInfo
= &tileInfoNull
;
850 ADDR_SURFACE_FLAGS flags
= {{0}};
853 // Try finding a macroModeIndex
854 INT_32 macroModeIndex
= HwlComputeMacroModeIndex(pIn
->tileIndex
,
856 HwlComputeFmaskBits(pIn
, NULL
),
861 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
862 if (macroModeIndex
== TileIndexNoMacroIndex
)
864 returnCode
= HwlSetupTileCfg(input
.tileIndex
, macroModeIndex
,
865 input
.pTileInfo
, &input
.tileMode
);
868 ADDR_ASSERT(macroModeIndex
!= TileIndexInvalid
);
870 // Change the input structure
874 if (returnCode
== ADDR_OK
)
876 if (pIn
->numSamples
> 1)
878 returnCode
= HwlComputeFmaskInfo(pIn
, pOut
);
882 memset(pOut
, 0, sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT
));
884 returnCode
= ADDR_INVALIDPARAMS
;
893 ***************************************************************************************************
894 * AddrLib1::ComputeFmaskAddrFromCoord
897 * Interface function stub of ComputeFmaskAddrFromCoord.
901 ***************************************************************************************************
903 ADDR_E_RETURNCODE
AddrLib1::ComputeFmaskAddrFromCoord(
904 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
905 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
908 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
910 if (GetFillSizeFieldsFlags() == TRUE
)
912 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
)) ||
913 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
)))
915 returnCode
= ADDR_PARAMSIZEMISMATCH
;
919 if (returnCode
== ADDR_OK
)
921 ADDR_ASSERT(pIn
->numSamples
> 1);
923 if (pIn
->numSamples
> 1)
925 returnCode
= HwlComputeFmaskAddrFromCoord(pIn
, pOut
);
929 returnCode
= ADDR_INVALIDPARAMS
;
937 ***************************************************************************************************
938 * AddrLib1::ComputeFmaskCoordFromAddr
941 * Interface function stub of ComputeFmaskAddrFromCoord.
945 ***************************************************************************************************
947 ADDR_E_RETURNCODE
AddrLib1::ComputeFmaskCoordFromAddr(
948 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
949 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
952 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
954 if (GetFillSizeFieldsFlags() == TRUE
)
956 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
)) ||
957 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
)))
959 returnCode
= ADDR_PARAMSIZEMISMATCH
;
963 if (returnCode
== ADDR_OK
)
965 ADDR_ASSERT(pIn
->numSamples
> 1);
967 if (pIn
->numSamples
> 1)
969 returnCode
= HwlComputeFmaskCoordFromAddr(pIn
, pOut
);
973 returnCode
= ADDR_INVALIDPARAMS
;
981 ***************************************************************************************************
982 * AddrLib1::ConvertTileInfoToHW
985 * Convert tile info from real value to HW register value in HW layer
989 ***************************************************************************************************
991 ADDR_E_RETURNCODE
AddrLib1::ConvertTileInfoToHW(
992 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
993 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
996 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
998 if (GetFillSizeFieldsFlags() == TRUE
)
1000 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT
)) ||
1001 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT
)))
1003 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1007 if (returnCode
== ADDR_OK
)
1009 ADDR_TILEINFO tileInfoNull
;
1010 ADDR_CONVERT_TILEINFOTOHW_INPUT input
;
1011 // if pIn->reverse is TRUE, indices are ignored
1012 if (pIn
->reverse
== FALSE
&& UseTileIndex(pIn
->tileIndex
))
1015 input
.pTileInfo
= &tileInfoNull
;
1017 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1022 if (returnCode
== ADDR_OK
)
1024 returnCode
= HwlConvertTileInfoToHW(pIn
, pOut
);
1032 ***************************************************************************************************
1033 * AddrLib1::ConvertTileIndex
1036 * Convert tile index to tile mode/type/info
1040 ***************************************************************************************************
1042 ADDR_E_RETURNCODE
AddrLib1::ConvertTileIndex(
1043 const ADDR_CONVERT_TILEINDEX_INPUT
* pIn
, ///< [in] input structure
1044 ADDR_CONVERT_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1047 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1049 if (GetFillSizeFieldsFlags() == TRUE
)
1051 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_INPUT
)) ||
1052 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT
)))
1054 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1058 if (returnCode
== ADDR_OK
)
1061 returnCode
= HwlSetupTileCfg(pIn
->tileIndex
, pIn
->macroModeIndex
,
1062 pOut
->pTileInfo
, &pOut
->tileMode
, &pOut
->tileType
);
1064 if (returnCode
== ADDR_OK
&& pIn
->tileInfoHw
)
1066 ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput
= {0};
1067 ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput
= {0};
1069 hwInput
.pTileInfo
= pOut
->pTileInfo
;
1070 hwInput
.tileIndex
= -1;
1071 hwOutput
.pTileInfo
= pOut
->pTileInfo
;
1073 returnCode
= HwlConvertTileInfoToHW(&hwInput
, &hwOutput
);
1081 ***************************************************************************************************
1082 * AddrLib1::ConvertTileIndex1
1085 * Convert tile index to tile mode/type/info
1089 ***************************************************************************************************
1091 ADDR_E_RETURNCODE
AddrLib1::ConvertTileIndex1(
1092 const ADDR_CONVERT_TILEINDEX1_INPUT
* pIn
, ///< [in] input structure
1093 ADDR_CONVERT_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1096 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1098 if (GetFillSizeFieldsFlags() == TRUE
)
1100 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINDEX1_INPUT
)) ||
1101 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT
)))
1103 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1107 if (returnCode
== ADDR_OK
)
1109 ADDR_SURFACE_FLAGS flags
= {{0}};
1111 HwlComputeMacroModeIndex(pIn
->tileIndex
, flags
, pIn
->bpp
, pIn
->numSamples
,
1112 pOut
->pTileInfo
, &pOut
->tileMode
, &pOut
->tileType
);
1114 if (pIn
->tileInfoHw
)
1116 ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput
= {0};
1117 ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput
= {0};
1119 hwInput
.pTileInfo
= pOut
->pTileInfo
;
1120 hwInput
.tileIndex
= -1;
1121 hwOutput
.pTileInfo
= pOut
->pTileInfo
;
1123 returnCode
= HwlConvertTileInfoToHW(&hwInput
, &hwOutput
);
1131 ***************************************************************************************************
1132 * AddrLib1::GetTileIndex
1135 * Get tile index from tile mode/type/info
1139 ***************************************************************************************************
1141 ADDR_E_RETURNCODE
AddrLib1::GetTileIndex(
1142 const ADDR_GET_TILEINDEX_INPUT
* pIn
, ///< [in] input structure
1143 ADDR_GET_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1146 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1148 if (GetFillSizeFieldsFlags() == TRUE
)
1150 if ((pIn
->size
!= sizeof(ADDR_GET_TILEINDEX_INPUT
)) ||
1151 (pOut
->size
!= sizeof(ADDR_GET_TILEINDEX_OUTPUT
)))
1153 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1157 if (returnCode
== ADDR_OK
)
1159 returnCode
= HwlGetTileIndex(pIn
, pOut
);
1166 ***************************************************************************************************
1167 * AddrLib1::ComputeSurfaceThickness
1170 * Compute surface thickness
1174 ***************************************************************************************************
1176 UINT_32
AddrLib1::ComputeSurfaceThickness(
1177 AddrTileMode tileMode
) ///< [in] tile mode
1179 return m_modeFlags
[tileMode
].thickness
;
1184 ///////////////////////////////////////////////////////////////////////////////////////////////////
1186 ///////////////////////////////////////////////////////////////////////////////////////////////////
1189 ***************************************************************************************************
1190 * AddrLib1::ComputeHtileInfo
1193 * Interface function stub of AddrComputeHtilenfo
1197 ***************************************************************************************************
1199 ADDR_E_RETURNCODE
AddrLib1::ComputeHtileInfo(
1200 const ADDR_COMPUTE_HTILE_INFO_INPUT
* pIn
, ///< [in] input structure
1201 ADDR_COMPUTE_HTILE_INFO_OUTPUT
* pOut
///< [out] output structure
1204 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1206 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1207 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1209 if (GetFillSizeFieldsFlags() == TRUE
)
1211 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT
)) ||
1212 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT
)))
1214 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1218 if (returnCode
== ADDR_OK
)
1220 ADDR_TILEINFO tileInfoNull
;
1221 ADDR_COMPUTE_HTILE_INFO_INPUT input
;
1223 if (UseTileIndex(pIn
->tileIndex
))
1226 // Use temp tile info for calcalation
1227 input
.pTileInfo
= &tileInfoNull
;
1229 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1231 // Change the input structure
1235 if (returnCode
== ADDR_OK
)
1237 pOut
->bpp
= ComputeHtileInfo(pIn
->flags
,
1259 ***************************************************************************************************
1260 * AddrLib1::ComputeCmaskInfo
1263 * Interface function stub of AddrComputeCmaskInfo
1267 ***************************************************************************************************
1269 ADDR_E_RETURNCODE
AddrLib1::ComputeCmaskInfo(
1270 const ADDR_COMPUTE_CMASK_INFO_INPUT
* pIn
, ///< [in] input structure
1271 ADDR_COMPUTE_CMASK_INFO_OUTPUT
* pOut
///< [out] output structure
1274 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1276 if (GetFillSizeFieldsFlags() == TRUE
)
1278 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_INFO_INPUT
)) ||
1279 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_INFO_OUTPUT
)))
1281 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1285 if (returnCode
== ADDR_OK
)
1287 ADDR_TILEINFO tileInfoNull
;
1288 ADDR_COMPUTE_CMASK_INFO_INPUT input
;
1290 if (UseTileIndex(pIn
->tileIndex
))
1293 // Use temp tile info for calcalation
1294 input
.pTileInfo
= &tileInfoNull
;
1296 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1298 // Change the input structure
1302 if (returnCode
== ADDR_OK
)
1304 returnCode
= ComputeCmaskInfo(pIn
->flags
,
1325 ***************************************************************************************************
1326 * AddrLib1::ComputeDccInfo
1329 * Interface function to compute DCC key info
1332 * return code of HwlComputeDccInfo
1333 ***************************************************************************************************
1335 ADDR_E_RETURNCODE
AddrLib1::ComputeDccInfo(
1336 const ADDR_COMPUTE_DCCINFO_INPUT
* pIn
, ///< [in] input structure
1337 ADDR_COMPUTE_DCCINFO_OUTPUT
* pOut
///< [out] output structure
1340 ADDR_E_RETURNCODE ret
= ADDR_OK
;
1342 if (GetFillSizeFieldsFlags() == TRUE
)
1344 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_DCCINFO_INPUT
)) ||
1345 (pOut
->size
!= sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT
)))
1347 ret
= ADDR_PARAMSIZEMISMATCH
;
1353 ADDR_COMPUTE_DCCINFO_INPUT input
;
1355 if (UseTileIndex(pIn
->tileIndex
))
1359 ret
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
,
1360 &input
.tileInfo
, &input
.tileMode
);
1367 ret
= HwlComputeDccInfo(pIn
, pOut
);
1375 ***************************************************************************************************
1376 * AddrLib1::ComputeHtileAddrFromCoord
1379 * Interface function stub of AddrComputeHtileAddrFromCoord
1383 ***************************************************************************************************
1385 ADDR_E_RETURNCODE
AddrLib1::ComputeHtileAddrFromCoord(
1386 const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1387 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1390 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1392 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1393 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1395 if (GetFillSizeFieldsFlags() == TRUE
)
1397 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
)) ||
1398 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
)))
1400 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1404 if (returnCode
== ADDR_OK
)
1406 ADDR_TILEINFO tileInfoNull
;
1407 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT input
;
1409 if (UseTileIndex(pIn
->tileIndex
))
1412 // Use temp tile info for calcalation
1413 input
.pTileInfo
= &tileInfoNull
;
1415 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1417 // Change the input structure
1421 if (returnCode
== ADDR_OK
)
1423 pOut
->addr
= HwlComputeXmaskAddrFromCoord(pIn
->pitch
,
1434 &pOut
->bitPosition
);
1443 ***************************************************************************************************
1444 * AddrLib1::ComputeHtileCoordFromAddr
1447 * Interface function stub of AddrComputeHtileCoordFromAddr
1451 ***************************************************************************************************
1453 ADDR_E_RETURNCODE
AddrLib1::ComputeHtileCoordFromAddr(
1454 const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
1455 ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
1458 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1460 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1461 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1463 if (GetFillSizeFieldsFlags() == TRUE
)
1465 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT
)) ||
1466 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
)))
1468 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1472 if (returnCode
== ADDR_OK
)
1474 ADDR_TILEINFO tileInfoNull
;
1475 ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT input
;
1477 if (UseTileIndex(pIn
->tileIndex
))
1480 // Use temp tile info for calcalation
1481 input
.pTileInfo
= &tileInfoNull
;
1483 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1485 // Change the input structure
1489 if (returnCode
== ADDR_OK
)
1491 HwlComputeXmaskCoordFromAddr(pIn
->addr
,
1511 ***************************************************************************************************
1512 * AddrLib1::ComputeCmaskAddrFromCoord
1515 * Interface function stub of AddrComputeCmaskAddrFromCoord
1519 ***************************************************************************************************
1521 ADDR_E_RETURNCODE
AddrLib1::ComputeCmaskAddrFromCoord(
1522 const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1523 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1526 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1528 if (GetFillSizeFieldsFlags() == TRUE
)
1530 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
)) ||
1531 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
)))
1533 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1537 if (returnCode
== ADDR_OK
)
1539 ADDR_TILEINFO tileInfoNull
;
1540 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT input
;
1542 if (UseTileIndex(pIn
->tileIndex
))
1545 // Use temp tile info for calcalation
1546 input
.pTileInfo
= &tileInfoNull
;
1548 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1550 // Change the input structure
1554 if (returnCode
== ADDR_OK
)
1556 if (pIn
->flags
.tcCompatible
== TRUE
)
1558 returnCode
= HwlComputeCmaskAddrFromCoord(pIn
, pOut
);
1562 pOut
->addr
= HwlComputeXmaskAddrFromCoord(pIn
->pitch
,
1570 FALSE
, //this is cmask, isWidth8 is not needed
1571 FALSE
, //this is cmask, isHeight8 is not needed
1573 &pOut
->bitPosition
);
1583 ***************************************************************************************************
1584 * AddrLib1::ComputeCmaskCoordFromAddr
1587 * Interface function stub of AddrComputeCmaskCoordFromAddr
1591 ***************************************************************************************************
1593 ADDR_E_RETURNCODE
AddrLib1::ComputeCmaskCoordFromAddr(
1594 const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
1595 ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
1598 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1600 if (GetFillSizeFieldsFlags() == TRUE
)
1602 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT
)) ||
1603 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT
)))
1605 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1609 if (returnCode
== ADDR_OK
)
1611 ADDR_TILEINFO tileInfoNull
;
1612 ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT input
;
1614 if (UseTileIndex(pIn
->tileIndex
))
1617 // Use temp tile info for calcalation
1618 input
.pTileInfo
= &tileInfoNull
;
1620 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1622 // Change the input structure
1626 if (returnCode
== ADDR_OK
)
1628 HwlComputeXmaskCoordFromAddr(pIn
->addr
,
1649 ***************************************************************************************************
1650 * AddrLib1::ComputeTileDataWidthAndHeight
1653 * Compute the squared cache shape for per-tile data (CMASK and HTILE)
1659 * MacroWidth and macroHeight are measured in pixels
1660 ***************************************************************************************************
1662 VOID
AddrLib1::ComputeTileDataWidthAndHeight(
1663 UINT_32 bpp
, ///< [in] bits per pixel
1664 UINT_32 cacheBits
, ///< [in] bits of cache
1665 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1666 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1667 UINT_32
* pMacroHeight
///< [out] macro tile height
1671 UINT_32 width
= cacheBits
/ bpp
;
1672 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
1674 // Double height until the macro-tile is close to square
1675 // Height can only be doubled if width is even
1677 while ((width
> height
* 2 * pipes
) && !(width
& 1))
1683 *pMacroWidth
= 8 * width
;
1684 *pMacroHeight
= 8 * height
* pipes
;
1686 // Note: The above iterative comptuation is equivalent to the following
1688 //int log2_height = ((log2(cacheBits)-log2(bpp)-log2(pipes))/2);
1689 //int macroHeight = pow2( 3+log2(pipes)+log2_height );
1693 ***************************************************************************************************
1694 * AddrLib1::HwlComputeTileDataWidthAndHeightLinear
1697 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1703 * MacroWidth and macroHeight are measured in pixels
1704 ***************************************************************************************************
1706 VOID
AddrLib1::HwlComputeTileDataWidthAndHeightLinear(
1707 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1708 UINT_32
* pMacroHeight
, ///< [out] macro tile height
1709 UINT_32 bpp
, ///< [in] bits per pixel
1710 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
1713 ADDR_ASSERT(bpp
!= 4); // Cmask does not support linear layout prior to SI
1714 *pMacroWidth
= 8 * 512 / bpp
; // Align width to 512-bit memory accesses
1715 *pMacroHeight
= 8 * m_pipes
; // Align height to number of pipes
1719 ***************************************************************************************************
1720 * AddrLib1::ComputeHtileInfo
1723 * Compute htile pitch,width, bytes per 2D slice
1726 * Htile bpp i.e. How many bits for an 8x8 tile
1727 * Also returns by output parameters:
1728 * *Htile pitch, height, total size in bytes, macro-tile dimensions and slice size*
1729 ***************************************************************************************************
1731 UINT_32
AddrLib1::ComputeHtileInfo(
1732 ADDR_HTILE_FLAGS flags
, ///< [in] htile flags
1733 UINT_32 pitchIn
, ///< [in] pitch input
1734 UINT_32 heightIn
, ///< [in] height input
1735 UINT_32 numSlices
, ///< [in] number of slices
1736 BOOL_32 isLinear
, ///< [in] if it is linear mode
1737 BOOL_32 isWidth8
, ///< [in] if htile block width is 8
1738 BOOL_32 isHeight8
, ///< [in] if htile block height is 8
1739 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1740 UINT_32
* pPitchOut
, ///< [out] pitch output
1741 UINT_32
* pHeightOut
, ///< [out] height output
1742 UINT_64
* pHtileBytes
, ///< [out] bytes per 2D slice
1743 UINT_32
* pMacroWidth
, ///< [out] macro-tile width in pixels
1744 UINT_32
* pMacroHeight
, ///< [out] macro-tile width in pixels
1745 UINT_64
* pSliceSize
, ///< [out] slice size in bytes
1746 UINT_32
* pBaseAlign
///< [out] base alignment
1751 UINT_32 macroHeight
;
1756 numSlices
= Max(1u, numSlices
);
1758 const UINT_32 bpp
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
1759 const UINT_32 cacheBits
= HtileCacheBits
;
1763 HwlComputeTileDataWidthAndHeightLinear(¯oWidth
,
1770 ComputeTileDataWidthAndHeight(bpp
,
1777 *pPitchOut
= PowTwoAlign(pitchIn
, macroWidth
);
1778 *pHeightOut
= PowTwoAlign(heightIn
, macroHeight
);
1780 baseAlign
= HwlComputeHtileBaseAlign(flags
.tcCompatible
, isLinear
, pTileInfo
);
1782 surfBytes
= HwlComputeHtileBytes(*pPitchOut
,
1790 *pHtileBytes
= surfBytes
;
1793 // Use SafeAssign since they are optional
1795 SafeAssign(pMacroWidth
, macroWidth
);
1797 SafeAssign(pMacroHeight
, macroHeight
);
1799 SafeAssign(pSliceSize
, sliceBytes
);
1801 SafeAssign(pBaseAlign
, baseAlign
);
1807 ***************************************************************************************************
1808 * AddrLib1::ComputeCmaskBaseAlign
1811 * Compute cmask base alignment
1814 * Cmask base alignment
1815 ***************************************************************************************************
1817 UINT_32
AddrLib1::ComputeCmaskBaseAlign(
1818 ADDR_CMASK_FLAGS flags
, ///< [in] Cmask flags
1819 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
1822 UINT_32 baseAlign
= m_pipeInterleaveBytes
* HwlGetPipes(pTileInfo
);
1824 if (flags
.tcCompatible
)
1826 ADDR_ASSERT(pTileInfo
!= NULL
);
1829 baseAlign
*= pTileInfo
->banks
;
1837 ***************************************************************************************************
1838 * AddrLib1::ComputeCmaskBytes
1841 * Compute cmask size in bytes
1844 * Cmask size in bytes
1845 ***************************************************************************************************
1847 UINT_64
AddrLib1::ComputeCmaskBytes(
1848 UINT_32 pitch
, ///< [in] pitch
1849 UINT_32 height
, ///< [in] height
1850 UINT_32 numSlices
///< [in] number of slices
1853 return BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* numSlices
* CmaskElemBits
) /
1858 ***************************************************************************************************
1859 * AddrLib1::ComputeCmaskInfo
1862 * Compute cmask pitch,width, bytes per 2D slice
1865 * BlockMax. Also by output parameters: Cmask pitch,height, total size in bytes,
1866 * macro-tile dimensions
1867 ***************************************************************************************************
1869 ADDR_E_RETURNCODE
AddrLib1::ComputeCmaskInfo(
1870 ADDR_CMASK_FLAGS flags
, ///< [in] cmask flags
1871 UINT_32 pitchIn
, ///< [in] pitch input
1872 UINT_32 heightIn
, ///< [in] height input
1873 UINT_32 numSlices
, ///< [in] number of slices
1874 BOOL_32 isLinear
, ///< [in] is linear mode
1875 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1876 UINT_32
* pPitchOut
, ///< [out] pitch output
1877 UINT_32
* pHeightOut
, ///< [out] height output
1878 UINT_64
* pCmaskBytes
, ///< [out] bytes per 2D slice
1879 UINT_32
* pMacroWidth
, ///< [out] macro-tile width in pixels
1880 UINT_32
* pMacroHeight
, ///< [out] macro-tile width in pixels
1881 UINT_64
* pSliceSize
, ///< [out] slice size in bytes
1882 UINT_32
* pBaseAlign
, ///< [out] base alignment
1883 UINT_32
* pBlockMax
///< [out] block max == slice / 128 / 128 - 1
1887 UINT_32 macroHeight
;
1892 numSlices
= Max(1u, numSlices
);
1894 const UINT_32 bpp
= CmaskElemBits
;
1895 const UINT_32 cacheBits
= CmaskCacheBits
;
1897 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1901 HwlComputeTileDataWidthAndHeightLinear(¯oWidth
,
1908 ComputeTileDataWidthAndHeight(bpp
,
1915 *pPitchOut
= (pitchIn
+ macroWidth
- 1) & ~(macroWidth
- 1);
1916 *pHeightOut
= (heightIn
+ macroHeight
- 1) & ~(macroHeight
- 1);
1919 sliceBytes
= ComputeCmaskBytes(*pPitchOut
,
1923 baseAlign
= ComputeCmaskBaseAlign(flags
, pTileInfo
);
1925 while (sliceBytes
% baseAlign
)
1927 *pHeightOut
+= macroHeight
;
1929 sliceBytes
= ComputeCmaskBytes(*pPitchOut
,
1934 surfBytes
= sliceBytes
* numSlices
;
1936 *pCmaskBytes
= surfBytes
;
1939 // Use SafeAssign since they are optional
1941 SafeAssign(pMacroWidth
, macroWidth
);
1943 SafeAssign(pMacroHeight
, macroHeight
);
1945 SafeAssign(pBaseAlign
, baseAlign
);
1947 SafeAssign(pSliceSize
, sliceBytes
);
1949 UINT_32 slice
= (*pPitchOut
) * (*pHeightOut
);
1950 UINT_32 blockMax
= slice
/ 128 / 128 - 1;
1953 if (slice
% (64*256) != 0)
1955 ADDR_ASSERT_ALWAYS();
1959 UINT_32 maxBlockMax
= HwlGetMaxCmaskBlockMax();
1961 if (blockMax
> maxBlockMax
)
1963 blockMax
= maxBlockMax
;
1964 returnCode
= ADDR_INVALIDPARAMS
;
1967 SafeAssign(pBlockMax
, blockMax
);
1973 ***************************************************************************************************
1974 * AddrLib1::ComputeXmaskCoordYFromPipe
1977 * Compute the Y coord from pipe number for cmask/htile
1982 ***************************************************************************************************
1984 UINT_32
AddrLib1::ComputeXmaskCoordYFromPipe(
1985 UINT_32 pipe
, ///< [in] pipe number
1986 UINT_32 x
///< [in] x coordinate
1998 UINT_32 numPipes
= m_pipes
; // SI has its implementation
2000 // Convert pipe + x to y coordinate.
2020 pipeBit0
= pipe
& 0x1;
2024 yBit0
= pipeBit0
^ xBit0
;
2038 pipeBit0
= pipe
& 0x1;
2039 pipeBit1
= (pipe
& 0x2) >> 1;
2042 xBit1
= (x
& 0x2) >> 1;
2044 yBit0
= pipeBit0
^ xBit1
;
2045 yBit1
= pipeBit1
^ xBit0
;
2054 // r600 and r800 have different method
2056 y
= HwlComputeXmaskCoordYFrom8Pipe(pipe
, x
);
2065 ***************************************************************************************************
2066 * AddrLib1::HwlComputeXmaskCoordFromAddr
2069 * Compute the coord from an address of a cmask/htile
2075 * This method is reused by htile, so rename to Xmask
2076 ***************************************************************************************************
2078 VOID
AddrLib1::HwlComputeXmaskCoordFromAddr(
2079 UINT_64 addr
, ///< [in] address
2080 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2081 UINT_32 pitch
, ///< [in] pitch
2082 UINT_32 height
, ///< [in] height
2083 UINT_32 numSlices
, ///< [in] number of slices
2084 UINT_32 factor
, ///< [in] factor that indicates cmask or htile
2085 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
2086 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2087 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2088 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
2089 UINT_32
* pX
, ///< [out] x coord
2090 UINT_32
* pY
, ///< [out] y coord
2091 UINT_32
* pSlice
///< [out] slice index
2096 UINT_32 numPipeBits
;
2097 UINT_32 macroTilePitch
;
2098 UINT_32 macroTileHeight
;
2102 UINT_32 microTileCoordY
;
2106 UINT_32 pitchAligned
= pitch
;
2107 UINT_32 heightAligned
= height
;
2115 UINT_64 macroNumber
;
2116 UINT_32 microNumber
;
2125 UINT_32 tilesPerMacro
;
2126 UINT_32 macrosPerPitch
;
2127 UINT_32 macrosPerSlice
;
2132 numPipes
= HwlGetPipes(pTileInfo
);
2133 pipe
= ComputePipeFromAddr(addr
, numPipes
);
2136 // Compute the number of group and pipe bits.
2138 numPipeBits
= Log2(numPipes
);
2140 UINT_32 groupBits
= 8 * m_pipeInterleaveBytes
;
2141 UINT_32 pipes
= numPipes
;
2145 // Compute the micro tile size, in bits. And macro tile pitch and height.
2147 if (factor
== 2) //CMASK
2149 ADDR_CMASK_FLAGS flags
= {{0}};
2151 elemBits
= CmaskElemBits
;
2153 ComputeCmaskInfo(flags
,
2167 ADDR_HTILE_FLAGS flags
= {{0}};
2174 elemBits
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
2176 ComputeHtileInfo(flags
,
2191 // Should use aligned dims
2193 pitch
= pitchAligned
;
2194 height
= heightAligned
;
2198 // Convert byte address to bit address.
2200 bitAddr
= BYTES_TO_BITS(addr
) + bitPosition
;
2204 // Remove pipe bits from address.
2207 bitAddr
= (bitAddr
% groupBits
) + ((bitAddr
/groupBits
/pipes
)*groupBits
);
2210 elemOffset
= bitAddr
/ elemBits
;
2212 tilesPerMacro
= (macroTilePitch
/factor
) * macroTileHeight
/ MicroTilePixels
>> numPipeBits
;
2214 macrosPerPitch
= pitch
/ (macroTilePitch
/factor
);
2215 macrosPerSlice
= macrosPerPitch
* height
/ macroTileHeight
;
2217 macroIndex
= elemOffset
/ factor
/ tilesPerMacro
;
2218 microIndex
= static_cast<UINT_32
>(elemOffset
% (tilesPerMacro
* factor
));
2220 macroNumber
= macroIndex
* factor
+ microIndex
% factor
;
2221 microNumber
= microIndex
/ factor
;
2223 macroX
= static_cast<UINT_32
>((macroNumber
% macrosPerPitch
));
2224 macroY
= static_cast<UINT_32
>((macroNumber
% macrosPerSlice
) / macrosPerPitch
);
2225 macroZ
= static_cast<UINT_32
>((macroNumber
/ macrosPerSlice
));
2228 microX
= microNumber
% (macroTilePitch
/ factor
/ MicroTileWidth
);
2229 microY
= (microNumber
/ (macroTilePitch
/ factor
/ MicroTileHeight
));
2231 *pX
= macroX
* (macroTilePitch
/factor
) + microX
* MicroTileWidth
;
2232 *pY
= macroY
* macroTileHeight
+ (microY
* MicroTileHeight
<< numPipeBits
);
2235 microTileCoordY
= ComputeXmaskCoordYFromPipe(pipe
,
2236 *pX
/MicroTileWidth
);
2240 // Assemble final coordinates.
2242 *pY
+= microTileCoordY
* MicroTileHeight
;
2247 ***************************************************************************************************
2248 * AddrLib1::HwlComputeXmaskAddrFromCoord
2251 * Compute the address from an address of cmask (prior to si)
2256 ***************************************************************************************************
2258 UINT_64
AddrLib1::HwlComputeXmaskAddrFromCoord(
2259 UINT_32 pitch
, ///< [in] pitch
2260 UINT_32 height
, ///< [in] height
2261 UINT_32 x
, ///< [in] x coord
2262 UINT_32 y
, ///< [in] y coord
2263 UINT_32 slice
, ///< [in] slice/depth index
2264 UINT_32 numSlices
, ///< [in] number of slices
2265 UINT_32 factor
, ///< [in] factor that indicates cmask(2) or htile(1)
2266 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
2267 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2268 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2269 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
2270 UINT_32
* pBitPosition
///< [out] bit position inside a byte
2274 UINT_32 numGroupBits
;
2275 UINT_32 numPipeBits
;
2276 UINT_32 newPitch
= 0;
2277 UINT_32 newHeight
= 0;
2278 UINT_64 sliceBytes
= 0;
2279 UINT_64 totalBytes
= 0;
2280 UINT_64 sliceOffset
;
2282 UINT_32 macroTileWidth
;
2283 UINT_32 macroTileHeight
;
2284 UINT_32 macroTilesPerRow
;
2285 UINT_32 macroTileBytes
;
2286 UINT_32 macroTileIndexX
;
2287 UINT_32 macroTileIndexY
;
2288 UINT_64 macroTileOffset
;
2289 UINT_32 pixelBytesPerRow
;
2290 UINT_32 pixelOffsetX
;
2291 UINT_32 pixelOffsetY
;
2292 UINT_32 pixelOffset
;
2293 UINT_64 totalOffset
;
2299 UINT_32 elemBits
= 0;
2301 UINT_32 numPipes
= m_pipes
; // This function is accessed prior to si only
2303 if (factor
== 2) //CMASK
2305 elemBits
= CmaskElemBits
;
2307 // For asics before SI, cmask is always tiled
2312 if (factor
!= 1) // Fix compile warning
2317 elemBits
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
2321 // Compute the number of group bits and pipe bits.
2323 numGroupBits
= Log2(m_pipeInterleaveBytes
);
2324 numPipeBits
= Log2(numPipes
);
2327 // Compute macro tile dimensions.
2329 if (factor
== 2) // CMASK
2331 ADDR_CMASK_FLAGS flags
= {{0}};
2333 ComputeCmaskInfo(flags
,
2345 sliceBytes
= totalBytes
/ numSlices
;
2349 ADDR_HTILE_FLAGS flags
= {{0}};
2351 ComputeHtileInfo(flags
,
2367 sliceOffset
= slice
* sliceBytes
;
2370 // Get the pipe. Note that neither slice rotation nor pipe swizzling apply for CMASK.
2372 pipe
= ComputePipeFromCoord(x
,
2375 ADDR_TM_2D_TILED_THIN1
,
2381 // Compute the number of macro tiles per row.
2383 macroTilesPerRow
= newPitch
/ macroTileWidth
;
2386 // Compute the number of bytes per macro tile.
2388 macroTileBytes
= BITS_TO_BYTES((macroTileWidth
* macroTileHeight
* elemBits
) / MicroTilePixels
);
2391 // Compute the offset to the macro tile containing the specified coordinate.
2393 macroTileIndexX
= x
/ macroTileWidth
;
2394 macroTileIndexY
= y
/ macroTileHeight
;
2395 macroTileOffset
= ((macroTileIndexY
* macroTilesPerRow
) + macroTileIndexX
) * macroTileBytes
;
2398 // Compute the pixel offset within the macro tile.
2400 pixelBytesPerRow
= BITS_TO_BYTES(macroTileWidth
* elemBits
) / MicroTileWidth
;
2403 // The nibbles are interleaved (see below), so the part of the offset relative to the x
2404 // coordinate repeats halfway across the row. (Not for HTILE)
2408 pixelOffsetX
= (x
% (macroTileWidth
/ 2)) / MicroTileWidth
;
2412 pixelOffsetX
= (x
% (macroTileWidth
)) / MicroTileWidth
* BITS_TO_BYTES(elemBits
);
2416 // Compute the y offset within the macro tile.
2418 pixelOffsetY
= (((y
% macroTileHeight
) / MicroTileHeight
) / numPipes
) * pixelBytesPerRow
;
2420 pixelOffset
= pixelOffsetX
+ pixelOffsetY
;
2423 // Combine the slice offset and macro tile offset with the pixel offset, accounting for the
2424 // pipe bits in the middle of the address.
2426 totalOffset
= ((sliceOffset
+ macroTileOffset
) >> numPipeBits
) + pixelOffset
;
2429 // Split the offset to put some bits below the pipe bits and some above.
2431 groupMask
= (1 << numGroupBits
) - 1;
2432 offsetLo
= totalOffset
& groupMask
;
2433 offsetHi
= (totalOffset
& ~groupMask
) << numPipeBits
;
2436 // Assemble the address from its components.
2440 // This is to remove warning with /analyze option
2441 UINT_32 pipeBits
= pipe
<< numGroupBits
;
2445 // Compute the bit position. The lower nibble is used when the x coordinate within the macro
2446 // tile is less than half of the macro tile width, and the upper nibble is used when the x
2447 // coordinate within the macro tile is greater than or equal to half the macro tile width.
2449 *pBitPosition
= ((x
% macroTileWidth
) < (macroTileWidth
/ factor
)) ? 0 : 4;
2454 ///////////////////////////////////////////////////////////////////////////////////////////////////
2455 // Surface Addressing Shared
2456 ///////////////////////////////////////////////////////////////////////////////////////////////////
2459 ***************************************************************************************************
2460 * AddrLib1::ComputeSurfaceAddrFromCoordLinear
2463 * Compute address from coord for linear surface
2468 ***************************************************************************************************
2470 UINT_64
AddrLib1::ComputeSurfaceAddrFromCoordLinear(
2471 UINT_32 x
, ///< [in] x coord
2472 UINT_32 y
, ///< [in] y coord
2473 UINT_32 slice
, ///< [in] slice/depth index
2474 UINT_32 sample
, ///< [in] sample index
2475 UINT_32 bpp
, ///< [in] bits per pixel
2476 UINT_32 pitch
, ///< [in] pitch
2477 UINT_32 height
, ///< [in] height
2478 UINT_32 numSlices
, ///< [in] number of slices
2479 UINT_32
* pBitPosition
///< [out] bit position inside a byte
2482 const UINT_64 sliceSize
= static_cast<UINT_64
>(pitch
) * height
;
2484 UINT_64 sliceOffset
= (slice
+ sample
* numSlices
)* sliceSize
;
2485 UINT_64 rowOffset
= static_cast<UINT_64
>(y
) * pitch
;
2486 UINT_64 pixOffset
= x
;
2488 UINT_64 addr
= (sliceOffset
+ rowOffset
+ pixOffset
) * bpp
;
2490 *pBitPosition
= static_cast<UINT_32
>(addr
% 8);
2497 ***************************************************************************************************
2498 * AddrLib1::ComputeSurfaceCoordFromAddrLinear
2501 * Compute the coord from an address of a linear surface
2505 ***************************************************************************************************
2507 VOID
AddrLib1::ComputeSurfaceCoordFromAddrLinear(
2508 UINT_64 addr
, ///< [in] address
2509 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2510 UINT_32 bpp
, ///< [in] bits per pixel
2511 UINT_32 pitch
, ///< [in] pitch
2512 UINT_32 height
, ///< [in] height
2513 UINT_32 numSlices
, ///< [in] number of slices
2514 UINT_32
* pX
, ///< [out] x coord
2515 UINT_32
* pY
, ///< [out] y coord
2516 UINT_32
* pSlice
, ///< [out] slice/depth index
2517 UINT_32
* pSample
///< [out] sample index
2520 const UINT_64 sliceSize
= static_cast<UINT_64
>(pitch
) * height
;
2521 const UINT_64 linearOffset
= (BYTES_TO_BITS(addr
) + bitPosition
) / bpp
;
2523 *pX
= static_cast<UINT_32
>((linearOffset
% sliceSize
) % pitch
);
2524 *pY
= static_cast<UINT_32
>((linearOffset
% sliceSize
) / pitch
% height
);
2525 *pSlice
= static_cast<UINT_32
>((linearOffset
/ sliceSize
) % numSlices
);
2526 *pSample
= static_cast<UINT_32
>((linearOffset
/ sliceSize
) / numSlices
);
2530 ***************************************************************************************************
2531 * AddrLib1::ComputeSurfaceCoordFromAddrMicroTiled
2534 * Compute the coord from an address of a micro tiled surface
2538 ***************************************************************************************************
2540 VOID
AddrLib1::ComputeSurfaceCoordFromAddrMicroTiled(
2541 UINT_64 addr
, ///< [in] address
2542 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2543 UINT_32 bpp
, ///< [in] bits per pixel
2544 UINT_32 pitch
, ///< [in] pitch
2545 UINT_32 height
, ///< [in] height
2546 UINT_32 numSamples
, ///< [in] number of samples
2547 AddrTileMode tileMode
, ///< [in] tile mode
2548 UINT_32 tileBase
, ///< [in] base offset within a tile
2549 UINT_32 compBits
, ///< [in] component bits actually needed(for planar surface)
2550 UINT_32
* pX
, ///< [out] x coord
2551 UINT_32
* pY
, ///< [out] y coord
2552 UINT_32
* pSlice
, ///< [out] slice/depth index
2553 UINT_32
* pSample
, ///< [out] sample index,
2554 AddrTileType microTileType
, ///< [in] micro tiling order
2555 BOOL_32 isDepthSampleOrder
///< [in] TRUE if in depth sample order
2559 UINT_32 microTileThickness
;
2560 UINT_32 microTileBits
;
2564 UINT_32 microTileCoordX
;
2565 UINT_32 microTileCoordY
;
2566 UINT_32 pixelOffset
;
2567 UINT_32 pixelCoordX
= 0;
2568 UINT_32 pixelCoordY
= 0;
2569 UINT_32 pixelCoordZ
= 0;
2570 UINT_32 pixelCoordS
= 0;
2573 // Convert byte address to bit address.
2575 bitAddr
= BYTES_TO_BITS(addr
) + bitPosition
;
2578 // Compute the micro tile size, in bits.
2582 case ADDR_TM_1D_TILED_THICK
:
2583 microTileThickness
= ThickTileThickness
;
2586 microTileThickness
= 1;
2590 microTileBits
= MicroTilePixels
* microTileThickness
* bpp
* numSamples
;
2593 // Compute number of bits per slice and number of bits per row of micro tiles.
2595 sliceBits
= static_cast<UINT_64
>(pitch
) * height
* microTileThickness
* bpp
* numSamples
;
2597 rowBits
= (pitch
/ MicroTileWidth
) * microTileBits
;
2600 // Extract the slice index.
2602 sliceIndex
= static_cast<UINT_32
>(bitAddr
/ sliceBits
);
2603 bitAddr
-= sliceIndex
* sliceBits
;
2606 // Extract the y coordinate of the micro tile.
2608 microTileCoordY
= static_cast<UINT_32
>(bitAddr
/ rowBits
) * MicroTileHeight
;
2609 bitAddr
-= (microTileCoordY
/ MicroTileHeight
) * rowBits
;
2612 // Extract the x coordinate of the micro tile.
2614 microTileCoordX
= static_cast<UINT_32
>(bitAddr
/ microTileBits
) * MicroTileWidth
;
2617 // Compute the pixel offset within the micro tile.
2619 pixelOffset
= static_cast<UINT_32
>(bitAddr
% microTileBits
);
2622 // Extract pixel coordinates from the offset.
2624 HwlComputePixelCoordFromOffset(pixelOffset
,
2635 isDepthSampleOrder
);
2638 // Assemble final coordinates.
2640 *pX
= microTileCoordX
+ pixelCoordX
;
2641 *pY
= microTileCoordY
+ pixelCoordY
;
2642 *pSlice
= (sliceIndex
* microTileThickness
) + pixelCoordZ
;
2643 *pSample
= pixelCoordS
;
2645 if (microTileThickness
> 1)
2652 ***************************************************************************************************
2653 * AddrLib1::ComputePipeFromAddr
2656 * Compute the pipe number from an address
2661 ***************************************************************************************************
2663 UINT_32
AddrLib1::ComputePipeFromAddr(
2664 UINT_64 addr
, ///< [in] address
2665 UINT_32 numPipes
///< [in] number of banks
2670 UINT_32 groupBytes
= m_pipeInterleaveBytes
; //just different terms
2673 // The LSBs of the address are arranged as follows:
2674 // bank | pipe | group
2676 // To get the pipe number, shift off the group bits and mask the pipe bits.
2680 // The LSBs of the address are arranged as follows:
2681 // bank | bankInterleave | pipe | pipeInterleave
2683 // To get the pipe number, shift off the pipe interleave bits and mask the pipe bits.
2686 pipe
= static_cast<UINT_32
>(addr
>> Log2(groupBytes
)) & (numPipes
- 1);
2692 ***************************************************************************************************
2693 * AddrLib1::ComputePixelIndexWithinMicroTile
2696 * Compute the pixel index inside a micro tile of surface
2701 ***************************************************************************************************
2703 UINT_32
AddrLib1::ComputePixelIndexWithinMicroTile(
2704 UINT_32 x
, ///< [in] x coord
2705 UINT_32 y
, ///< [in] y coord
2706 UINT_32 z
, ///< [in] slice/depth index
2707 UINT_32 bpp
, ///< [in] bits per pixel
2708 AddrTileMode tileMode
, ///< [in] tile mode
2709 AddrTileType microTileType
///< [in] pixel order in display/non-display mode
2712 UINT_32 pixelBit0
= 0;
2713 UINT_32 pixelBit1
= 0;
2714 UINT_32 pixelBit2
= 0;
2715 UINT_32 pixelBit3
= 0;
2716 UINT_32 pixelBit4
= 0;
2717 UINT_32 pixelBit5
= 0;
2718 UINT_32 pixelBit6
= 0;
2719 UINT_32 pixelBit7
= 0;
2720 UINT_32 pixelBit8
= 0;
2721 UINT_32 pixelNumber
;
2723 UINT_32 x0
= _BIT(x
, 0);
2724 UINT_32 x1
= _BIT(x
, 1);
2725 UINT_32 x2
= _BIT(x
, 2);
2726 UINT_32 y0
= _BIT(y
, 0);
2727 UINT_32 y1
= _BIT(y
, 1);
2728 UINT_32 y2
= _BIT(y
, 2);
2729 UINT_32 z0
= _BIT(z
, 0);
2730 UINT_32 z1
= _BIT(z
, 1);
2731 UINT_32 z2
= _BIT(z
, 2);
2733 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
2735 // Compute the pixel number within the micro tile.
2737 if (microTileType
!= ADDR_THICK
)
2739 if (microTileType
== ADDR_DISPLAYABLE
)
2784 ADDR_ASSERT_ALWAYS();
2788 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2797 else if (microTileType
== ADDR_ROTATED
)
2799 ADDR_ASSERT(thickness
== 1);
2836 ADDR_ASSERT_ALWAYS();
2849 ADDR_ASSERT(thickness
> 1);
2880 ADDR_ASSERT_ALWAYS();
2893 pixelNumber
= ((pixelBit0
) |
2907 ***************************************************************************************************
2908 * AddrLib1::AdjustPitchAlignment
2911 * Adjusts pitch alignment for flipping surface
2916 ***************************************************************************************************
2918 VOID
AddrLib1::AdjustPitchAlignment(
2919 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface flags
2920 UINT_32
* pPitchAlign
///< [out] Pointer to pitch alignment
2923 // Display engine hardwires lower 5 bit of GRPH_PITCH to ZERO which means 32 pixel alignment
2924 // Maybe it will be fixed in future but let's make it general for now.
2925 if (flags
.display
|| flags
.overlay
)
2927 *pPitchAlign
= PowTwoAlign(*pPitchAlign
, 32);
2931 *pPitchAlign
= Max(m_minPitchAlignPixels
, *pPitchAlign
);
2937 ***************************************************************************************************
2938 * AddrLib1::PadDimensions
2941 * Helper function to pad dimensions
2946 ***************************************************************************************************
2948 VOID
AddrLib1::PadDimensions(
2949 AddrTileMode tileMode
, ///< [in] tile mode
2950 UINT_32 bpp
, ///< [in] bits per pixel
2951 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
2952 UINT_32 numSamples
, ///< [in] number of samples
2953 ADDR_TILEINFO
* pTileInfo
, ///< [in/out] bank structure.
2954 UINT_32 padDims
, ///< [in] Dimensions to pad valid value 1,2,3
2955 UINT_32 mipLevel
, ///< [in] MipLevel
2956 UINT_32
* pPitch
, ///< [in/out] pitch in pixels
2957 UINT_32 pitchAlign
, ///< [in] pitch alignment
2958 UINT_32
* pHeight
, ///< [in/out] height in pixels
2959 UINT_32 heightAlign
, ///< [in] height alignment
2960 UINT_32
* pSlices
, ///< [in/out] number of slices
2961 UINT_32 sliceAlign
///< [in] number of slice alignment
2964 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
2966 ADDR_ASSERT(padDims
<= 3);
2969 // Override padding for mip levels
2975 // for cubemap, we only pad when client call with 6 faces as an identity
2978 padDims
= 3; // we should pad cubemap sub levels when we treat it as 3d texture
2987 // Any possibilities that padDims is 0?
2993 if (IsPow2(pitchAlign
))
2995 *pPitch
= PowTwoAlign((*pPitch
), pitchAlign
);
2997 else // add this code to pass unit test, r600 linear mode is not align bpp to pow2 for linear
2999 *pPitch
+= pitchAlign
- 1;
3000 *pPitch
/= pitchAlign
;
3001 *pPitch
*= pitchAlign
;
3006 *pHeight
= PowTwoAlign((*pHeight
), heightAlign
);
3009 if (padDims
> 2 || thickness
> 1)
3011 // for cubemap single face, we do not pad slices.
3012 // if we pad it, the slice number should be set to 6 and current mip level > 1
3013 if (flags
.cube
&& (!m_configFlags
.noCubeMipSlicesPad
|| flags
.cubeAsArray
))
3015 *pSlices
= NextPow2(*pSlices
);
3018 // normal 3D texture or arrays or cubemap has a thick mode? (Just pass unit test)
3021 *pSlices
= PowTwoAlign((*pSlices
), sliceAlign
);
3026 HwlPadDimensions(tileMode
,
3043 ***************************************************************************************************
3044 * AddrLib1::HwlPreHandleBaseLvl3xPitch
3047 * Pre-handler of 3x pitch (96 bit) adjustment
3051 ***************************************************************************************************
3053 UINT_32
AddrLib1::HwlPreHandleBaseLvl3xPitch(
3054 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
3055 UINT_32 expPitch
///< [in] pitch
3058 ADDR_ASSERT(pIn
->width
== expPitch
);
3060 // If pitch is pre-multiplied by 3, we retrieve original one here to get correct miplevel size
3062 if (AddrElemLib::IsExpand3x(pIn
->format
) &&
3063 pIn
->mipLevel
== 0 &&
3064 pIn
->tileMode
== ADDR_TM_LINEAR_ALIGNED
)
3067 expPitch
= NextPow2(expPitch
);
3074 ***************************************************************************************************
3075 * AddrLib1::HwlPostHandleBaseLvl3xPitch
3078 * Post-handler of 3x pitch adjustment
3082 ***************************************************************************************************
3084 UINT_32
AddrLib1::HwlPostHandleBaseLvl3xPitch(
3085 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
3086 UINT_32 expPitch
///< [in] pitch
3090 // 96 bits surface of sub levels require element pitch of 32 bits instead
3091 // So we just return pitch in 32 bit pixels without timing 3
3093 if (AddrElemLib::IsExpand3x(pIn
->format
) &&
3094 pIn
->mipLevel
== 0 &&
3095 pIn
->tileMode
== ADDR_TM_LINEAR_ALIGNED
)
3105 ***************************************************************************************************
3106 * AddrLib1::IsMacroTiled
3109 * Check if the tile mode is macro tiled
3112 * TRUE if it is macro tiled (2D/2B/3D/3B)
3113 ***************************************************************************************************
3115 BOOL_32
AddrLib1::IsMacroTiled(
3116 AddrTileMode tileMode
) ///< [in] tile mode
3118 return m_modeFlags
[tileMode
].isMacro
;
3122 ***************************************************************************************************
3123 * AddrLib1::IsMacro3dTiled
3126 * Check if the tile mode is 3D macro tiled
3129 * TRUE if it is 3D macro tiled
3130 ***************************************************************************************************
3132 BOOL_32
AddrLib1::IsMacro3dTiled(
3133 AddrTileMode tileMode
) ///< [in] tile mode
3135 return m_modeFlags
[tileMode
].isMacro3d
;
3139 ***************************************************************************************************
3140 * AddrLib1::IsMicroTiled
3143 * Check if the tile mode is micro tiled
3146 * TRUE if micro tiled
3147 ***************************************************************************************************
3149 BOOL_32
AddrLib1::IsMicroTiled(
3150 AddrTileMode tileMode
) ///< [in] tile mode
3152 return m_modeFlags
[tileMode
].isMicro
;
3156 ***************************************************************************************************
3157 * AddrLib1::IsLinear
3160 * Check if the tile mode is linear
3164 ***************************************************************************************************
3166 BOOL_32
AddrLib1::IsLinear(
3167 AddrTileMode tileMode
) ///< [in] tile mode
3169 return m_modeFlags
[tileMode
].isLinear
;
3173 ***************************************************************************************************
3174 * AddrLib1::IsPrtNoRotationTileMode
3177 * Return TRUE if it is prt tile without rotation
3179 * This function just used by CI
3180 ***************************************************************************************************
3182 BOOL_32
AddrLib1::IsPrtNoRotationTileMode(
3183 AddrTileMode tileMode
)
3185 return m_modeFlags
[tileMode
].isPrtNoRotation
;
3189 ***************************************************************************************************
3190 * AddrLib1::IsPrtTileMode
3193 * Return TRUE if it is prt tile
3195 * This function just used by CI
3196 ***************************************************************************************************
3198 BOOL_32
AddrLib1::IsPrtTileMode(
3199 AddrTileMode tileMode
)
3201 return m_modeFlags
[tileMode
].isPrt
;
3205 ***************************************************************************************************
3206 * AddrLib1::ComputeMipLevel
3209 * Compute mipmap level width/height/slices
3212 ***************************************************************************************************
3214 VOID
AddrLib1::ComputeMipLevel(
3215 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
///< [in/out] Input structure
3218 if (AddrElemLib::IsBlockCompressed(pIn
->format
))
3220 if (pIn
->mipLevel
== 0)
3222 // DXTn's level 0 must be multiple of 4
3223 // But there are exceptions:
3224 // 1. Internal surface creation in hostblt/vsblt/etc...
3225 // 2. Runtime doesn't reject ATI1/ATI2 whose width/height are not multiple of 4
3226 pIn
->width
= PowTwoAlign(pIn
->width
, 4);
3227 pIn
->height
= PowTwoAlign(pIn
->height
, 4);
3231 HwlComputeMipLevel(pIn
);
3235 ***************************************************************************************************
3236 * AddrLib1::OptimizeTileMode
3239 * Check if base level's tile mode can be optimized (degraded)
3241 * TRUE if degraded, also returns degraded tile mode (unchanged if not degraded)
3242 ***************************************************************************************************
3244 BOOL_32
AddrLib1::OptimizeTileMode(
3245 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure for surface info
3246 AddrTileMode
* pTileMode
///< [out] Degraded tile mode
3249 AddrTileMode tileMode
= pIn
->tileMode
;
3250 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
3252 // Optimization can only be done on level 0 and samples <= 1
3253 if ((pIn
->flags
.opt4Space
== TRUE
) &&
3254 (pIn
->mipLevel
== 0) &&
3255 (pIn
->numSamples
<= 1) &&
3256 (pIn
->flags
.display
== FALSE
) &&
3257 (IsPrtTileMode(tileMode
) == FALSE
) &&
3258 (pIn
->flags
.prt
== FALSE
))
3260 // Check if linear mode is optimal
3261 if ((pIn
->height
== 1) &&
3262 (IsLinear(tileMode
) == FALSE
) &&
3263 (AddrElemLib::IsBlockCompressed(pIn
->format
) == FALSE
) &&
3264 (pIn
->flags
.depth
== FALSE
) &&
3265 (pIn
->flags
.stencil
== FALSE
) &&
3266 (m_configFlags
.disableLinearOpt
== FALSE
) &&
3267 (pIn
->flags
.disableLinearOpt
== FALSE
))
3269 tileMode
= ADDR_TM_LINEAR_ALIGNED
;
3271 else if (IsMacroTiled(tileMode
))
3273 if (HwlDegradeBaseLevel(pIn
))
3275 tileMode
= (thickness
== 1) ? ADDR_TM_1D_TILED_THIN1
: ADDR_TM_1D_TILED_THICK
;
3277 else if (thickness
> 1)
3279 // As in the following HwlComputeSurfaceInfo, thick modes may be degraded to
3280 // thinner modes, we should re-evaluate whether the corresponding thinner modes
3281 // need to be degraded. If so, we choose 1D thick mode instead.
3282 tileMode
= DegradeLargeThickTile(pIn
->tileMode
, pIn
->bpp
);
3283 if (tileMode
!= pIn
->tileMode
)
3285 ADDR_COMPUTE_SURFACE_INFO_INPUT input
= *pIn
;
3286 input
.tileMode
= tileMode
;
3287 if (HwlDegradeBaseLevel(&input
))
3289 tileMode
= ADDR_TM_1D_TILED_THICK
;
3296 BOOL_32 optimized
= (tileMode
!= pIn
->tileMode
);
3299 *pTileMode
= tileMode
;
3305 ***************************************************************************************************
3306 * AddrLib1::DegradeLargeThickTile
3309 * Check if the thickness needs to be reduced if a tile is too large
3311 * The degraded tile mode (unchanged if not degraded)
3312 ***************************************************************************************************
3314 AddrTileMode
AddrLib1::DegradeLargeThickTile(
3315 AddrTileMode tileMode
,
3318 // Override tilemode
3319 // When tile_width (8) * tile_height (8) * thickness * element_bytes is > row_size,
3320 // it is better to just use THIN mode in this case
3321 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
3323 if (thickness
> 1 && m_configFlags
.allowLargeThickTile
== 0)
3325 UINT_32 tileSize
= MicroTilePixels
* thickness
* (bpp
>> 3);
3327 if (tileSize
> m_rowSize
)
3331 case ADDR_TM_2D_TILED_XTHICK
:
3332 if ((tileSize
>> 1) <= m_rowSize
)
3334 tileMode
= ADDR_TM_2D_TILED_THICK
;
3337 // else fall through
3338 case ADDR_TM_2D_TILED_THICK
:
3339 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3342 case ADDR_TM_3D_TILED_XTHICK
:
3343 if ((tileSize
>> 1) <= m_rowSize
)
3345 tileMode
= ADDR_TM_3D_TILED_THICK
;
3348 // else fall through
3349 case ADDR_TM_3D_TILED_THICK
:
3350 tileMode
= ADDR_TM_3D_TILED_THIN1
;
3353 case ADDR_TM_PRT_TILED_THICK
:
3354 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
3357 case ADDR_TM_PRT_2D_TILED_THICK
:
3358 tileMode
= ADDR_TM_PRT_2D_TILED_THIN1
;
3361 case ADDR_TM_PRT_3D_TILED_THICK
:
3362 tileMode
= ADDR_TM_PRT_3D_TILED_THIN1
;
3375 ***************************************************************************************************
3376 * AddrLib1::PostComputeMipLevel
3378 * Compute MipLevel info (including level 0) after surface adjustment
3381 ***************************************************************************************************
3383 ADDR_E_RETURNCODE
AddrLib1::PostComputeMipLevel(
3384 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in/out] Input structure
3385 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] Output structure
3388 // Mipmap including level 0 must be pow2 padded since either SI hw expects so or it is
3389 // required by CFX for Hw Compatibility between NI and SI. Otherwise it is only needed for
3390 // mipLevel > 0. Any h/w has different requirement should implement its own virtual function
3392 if (pIn
->flags
.pow2Pad
)
3394 pIn
->width
= NextPow2(pIn
->width
);
3395 pIn
->height
= NextPow2(pIn
->height
);
3396 pIn
->numSlices
= NextPow2(pIn
->numSlices
);
3398 else if (pIn
->mipLevel
> 0)
3400 pIn
->width
= NextPow2(pIn
->width
);
3401 pIn
->height
= NextPow2(pIn
->height
);
3403 if (!pIn
->flags
.cube
)
3405 pIn
->numSlices
= NextPow2(pIn
->numSlices
);
3408 // for cubemap, we keep its value at first
3415 ***************************************************************************************************
3416 * AddrLib1::HwlSetupTileCfg
3419 * Map tile index to tile setting.
3422 ***************************************************************************************************
3424 ADDR_E_RETURNCODE
AddrLib1::HwlSetupTileCfg(
3425 INT_32 index
, ///< [in] Tile index
3426 INT_32 macroModeIndex
, ///< [in] Index in macro tile mode table(CI)
3427 ADDR_TILEINFO
* pInfo
, ///< [out] Tile Info
3428 AddrTileMode
* pMode
, ///< [out] Tile mode
3429 AddrTileType
* pType
///< [out] Tile type
3432 return ADDR_NOTSUPPORTED
;
3436 ***************************************************************************************************
3437 * AddrLib1::HwlGetPipes
3443 ***************************************************************************************************
3445 UINT_32
AddrLib1::HwlGetPipes(
3446 const ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
3449 //pTileInfo can be NULL when asic is 6xx and 8xx.
3454 ***************************************************************************************************
3455 * AddrLib1::ComputeQbStereoInfo
3458 * Get quad buffer stereo information
3461 ***************************************************************************************************
3463 BOOL_32
AddrLib1::ComputeQbStereoInfo(
3464 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in/out] updated pOut+pStereoInfo
3467 BOOL_32 success
= FALSE
;
3469 if (pOut
->pStereoInfo
)
3471 ADDR_ASSERT(pOut
->bpp
>= 8);
3472 ADDR_ASSERT((pOut
->surfSize
% pOut
->baseAlign
) == 0);
3474 // Save original height
3475 pOut
->pStereoInfo
->eyeHeight
= pOut
->height
;
3478 pOut
->pStereoInfo
->rightOffset
= static_cast<UINT_32
>(pOut
->surfSize
);
3480 pOut
->pStereoInfo
->rightSwizzle
= HwlComputeQbStereoRightSwizzle(pOut
);
3483 pOut
->pixelHeight
<<= 1;
3486 pOut
->surfSize
<<= 1;
3488 // Right start address meets the base align since it is guaranteed by AddrLib1
3490 // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo.
3499 ***************************************************************************************************
3500 * AddrLib1::ComputePrtInfo
3503 * Compute prt surface related info
3507 ***************************************************************************************************
3509 ADDR_E_RETURNCODE
AddrLib1::ComputePrtInfo(
3510 const ADDR_PRT_INFO_INPUT
* pIn
,
3511 ADDR_PRT_INFO_OUTPUT
* pOut
) const
3513 ADDR_ASSERT(pOut
!= NULL
);
3515 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
3517 UINT_32 expandX
= 1;
3518 UINT_32 expandY
= 1;
3519 AddrElemMode elemMode
;
3521 UINT_32 bpp
= GetElemLib()->GetBitsPerPixel(pIn
->format
,
3526 if (bpp
<8 || bpp
== 24 || bpp
== 48 || bpp
== 96 )
3528 returnCode
= ADDR_INVALIDPARAMS
;
3531 UINT_32 numFrags
= pIn
->numFrags
;
3532 ADDR_ASSERT(numFrags
<= 8);
3534 UINT_32 tileWidth
= 0;
3535 UINT_32 tileHeight
= 0;
3536 if (returnCode
== ADDR_OK
)
3538 // 3D texture without depth or 2d texture
3539 if (pIn
->baseMipDepth
> 1 || pIn
->baseMipHeight
> 1)
3558 // assume it is BC1/4
3562 if (elemMode
== ADDR_UNCOMPRESSED
)
3568 else if (bpp
== 128)
3570 // assume it is BC2/3/5/6H/7
3574 if (elemMode
== ADDR_UNCOMPRESSED
)
3583 tileWidth
= tileWidth
/ 2;
3585 else if (numFrags
== 4)
3587 tileWidth
= tileWidth
/ 2;
3588 tileHeight
= tileHeight
/ 2;
3590 else if (numFrags
== 8)
3592 tileWidth
= tileWidth
/ 4;
3593 tileHeight
= tileHeight
/ 2;
3615 else if (bpp
== 128)
3622 pOut
->prtTileWidth
= tileWidth
;
3623 pOut
->prtTileHeight
= tileHeight
;