2 * Copyright © 2014 Advanced Micro Devices, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
28 ***************************************************************************************************
30 * @brief Contains the implementation for the AddrLib base class..
31 ***************************************************************************************************
34 #include "addrinterface.h"
36 #include "addrcommon.h"
38 #if defined(__APPLE__)
40 UINT_32
div64_32(UINT_64 n
, UINT_32 base
)
45 UINT_32 high
= rem
>> 32;
51 res
= (UINT_64
) high
<< 32;
52 rem
-= (UINT_64
) (high
*base
) << 32;
55 while ((INT_64
)b
> 0 && b
< rem
)
77 UINT_32
__umoddi3(UINT_64 n
, UINT_32 base
)
79 return div64_32(n
, base
);
84 ///////////////////////////////////////////////////////////////////////////////////////////////////
85 // Static Const Member
86 ///////////////////////////////////////////////////////////////////////////////////////////////////
88 const AddrTileModeFlags
AddrLib::m_modeFlags
[ADDR_TM_COUNT
] =
90 {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_GENERAL
91 {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_ALIGNED
92 {1, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THIN1
93 {4, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THICK
94 {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN1
95 {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN2
96 {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN4
97 {4, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THICK
98 {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN1
99 {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN2
100 {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN4
101 {4, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THICK
102 {1, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THIN1
103 {4, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THICK
104 {1, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THIN1
105 {4, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THICK
106 {8, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_XTHICK
107 {8, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_XTHICK
108 {1, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_POWER_SAVE
109 {1, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THIN1
110 {1, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THIN1
111 {1, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THIN1
112 {4, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THICK
113 {4, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THICK
114 {4, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THICK
117 ///////////////////////////////////////////////////////////////////////////////////////////////////
118 // Constructor/Destructor
119 ///////////////////////////////////////////////////////////////////////////////////////////////////
122 ***************************************************************************************************
126 * Constructor for the AddrLib class
128 ***************************************************************************************************
131 m_class(BASE_ADDRLIB
),
132 m_chipFamily(ADDR_CHIP_FAMILY_IVLD
),
134 m_version(ADDRLIB_VERSION
),
137 m_pipeInterleaveBytes(0),
139 m_minPitchAlignPixels(1),
143 m_configFlags
.value
= 0;
147 ***************************************************************************************************
151 * Constructor for the AddrLib class with hClient as parameter
153 ***************************************************************************************************
155 AddrLib::AddrLib(const AddrClient
* pClient
) :
157 m_class(BASE_ADDRLIB
),
158 m_chipFamily(ADDR_CHIP_FAMILY_IVLD
),
160 m_version(ADDRLIB_VERSION
),
163 m_pipeInterleaveBytes(0),
165 m_minPitchAlignPixels(1),
169 m_configFlags
.value
= 0;
173 ***************************************************************************************************
177 * Destructor for the AddrLib class
179 ***************************************************************************************************
191 ///////////////////////////////////////////////////////////////////////////////////////////////////
192 // Initialization/Helper
193 ///////////////////////////////////////////////////////////////////////////////////////////////////
196 ***************************************************************************************************
200 * Creates and initializes AddrLib object.
204 ***************************************************************************************************
206 ADDR_E_RETURNCODE
AddrLib::Create(
207 const ADDR_CREATE_INPUT
* pCreateIn
, ///< [in] pointer to ADDR_CREATE_INPUT
208 ADDR_CREATE_OUTPUT
* pCreateOut
) ///< [out] pointer to ADDR_CREATE_OUTPUT
210 AddrLib
* pLib
= NULL
;
211 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
213 if (pCreateIn
->createFlags
.fillSizeFields
== TRUE
)
215 if ((pCreateIn
->size
!= sizeof(ADDR_CREATE_INPUT
)) ||
216 (pCreateOut
->size
!= sizeof(ADDR_CREATE_OUTPUT
)))
218 returnCode
= ADDR_PARAMSIZEMISMATCH
;
222 if ((returnCode
== ADDR_OK
) &&
223 (pCreateIn
->callbacks
.allocSysMem
!= NULL
) &&
224 (pCreateIn
->callbacks
.freeSysMem
!= NULL
))
226 AddrClient client
= {
231 switch (pCreateIn
->chipEngine
)
233 case CIASICIDGFXENGINE_SOUTHERNISLAND
:
234 switch (pCreateIn
->chipFamily
)
237 pLib
= AddrSIHwlInit(&client
);
240 case FAMILY_CZ
: // VI based fusion(carrizo)
242 case FAMILY_KV
: // CI based fusion
243 pLib
= AddrCIHwlInit(&client
);
246 ADDR_ASSERT_ALWAYS();
251 ADDR_ASSERT_ALWAYS();
260 // Pass createFlags to configFlags first since these flags may be overwritten
261 pLib
->m_configFlags
.noCubeMipSlicesPad
= pCreateIn
->createFlags
.noCubeMipSlicesPad
;
262 pLib
->m_configFlags
.fillSizeFields
= pCreateIn
->createFlags
.fillSizeFields
;
263 pLib
->m_configFlags
.useTileIndex
= pCreateIn
->createFlags
.useTileIndex
;
264 pLib
->m_configFlags
.useCombinedSwizzle
= pCreateIn
->createFlags
.useCombinedSwizzle
;
265 pLib
->m_configFlags
.checkLast2DLevel
= pCreateIn
->createFlags
.checkLast2DLevel
;
266 pLib
->m_configFlags
.useHtileSliceAlign
= pCreateIn
->createFlags
.useHtileSliceAlign
;
267 pLib
->m_configFlags
.degradeBaseLevel
= pCreateIn
->createFlags
.degradeBaseLevel
;
268 pLib
->m_configFlags
.allowLargeThickTile
= pCreateIn
->createFlags
.allowLargeThickTile
;
270 pLib
->SetAddrChipFamily(pCreateIn
->chipFamily
, pCreateIn
->chipRevision
);
272 pLib
->SetMinPitchAlignPixels(pCreateIn
->minPitchAlignPixels
);
274 // Global parameters initialized and remaining configFlags bits are set as well
275 initValid
= pLib
->HwlInitGlobalParams(pCreateIn
);
279 pLib
->m_pElemLib
= AddrElemLib::Create(pLib
);
283 pLib
->m_pElemLib
= NULL
; // Don't go on allocating element lib
284 returnCode
= ADDR_INVALIDGBREGVALUES
;
287 if (pLib
->m_pElemLib
== NULL
)
291 ADDR_ASSERT_ALWAYS();
295 pLib
->m_pElemLib
->SetConfigFlags(pLib
->m_configFlags
);
299 pCreateOut
->hLib
= pLib
;
301 if ((pLib
== NULL
) &&
302 (returnCode
== ADDR_OK
))
304 // Unknown failures, we return the general error code
305 returnCode
= ADDR_ERROR
;
312 ***************************************************************************************************
313 * AddrLib::SetAddrChipFamily
316 * Convert familyID defined in atiid.h to AddrChipFamily and set m_chipFamily/m_chipRevision
319 ***************************************************************************************************
321 VOID
AddrLib::SetAddrChipFamily(
322 UINT_32 uChipFamily
, ///< [in] chip family defined in atiih.h
323 UINT_32 uChipRevision
) ///< [in] chip revision defined in "asic_family"_id.h
325 AddrChipFamily family
= ADDR_CHIP_FAMILY_IVLD
;
327 family
= HwlConvertChipFamily(uChipFamily
, uChipRevision
);
329 ADDR_ASSERT(family
!= ADDR_CHIP_FAMILY_IVLD
);
331 m_chipFamily
= family
;
332 m_chipRevision
= uChipRevision
;
336 ***************************************************************************************************
337 * AddrLib::SetMinPitchAlignPixels
340 * Set m_minPitchAlignPixels with input param
344 ***************************************************************************************************
346 VOID
AddrLib::SetMinPitchAlignPixels(
347 UINT_32 minPitchAlignPixels
) ///< [in] minmum pitch alignment in pixels
349 m_minPitchAlignPixels
= (minPitchAlignPixels
== 0)? 1 : minPitchAlignPixels
;
353 ***************************************************************************************************
354 * AddrLib::GetAddrLib
357 * Get AddrLib pointer
360 * An AddrLib class pointer
361 ***************************************************************************************************
363 AddrLib
* AddrLib::GetAddrLib(
364 ADDR_HANDLE hLib
) ///< [in] handle of ADDR_HANDLE
366 return static_cast<AddrLib
*>(hLib
);
371 ///////////////////////////////////////////////////////////////////////////////////////////////////
373 ///////////////////////////////////////////////////////////////////////////////////////////////////
377 ***************************************************************************************************
378 * AddrLib::ComputeSurfaceInfo
381 * Interface function stub of AddrComputeSurfaceInfo.
385 ***************************************************************************************************
387 ADDR_E_RETURNCODE
AddrLib::ComputeSurfaceInfo(
388 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
389 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
392 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
394 if (GetFillSizeFieldsFlags() == TRUE
)
396 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT
)) ||
397 (pOut
->size
!= sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT
)))
399 returnCode
= ADDR_PARAMSIZEMISMATCH
;
403 // We suggest client do sanity check but a check here is also good
406 returnCode
= ADDR_INVALIDPARAMS
;
409 // Thick modes don't support multisample
410 if (ComputeSurfaceThickness(pIn
->tileMode
) > 1 && pIn
->numSamples
> 1)
412 returnCode
= ADDR_INVALIDPARAMS
;
415 if (returnCode
== ADDR_OK
)
417 // Get a local copy of input structure and only reference pIn for unadjusted values
418 ADDR_COMPUTE_SURFACE_INFO_INPUT localIn
= *pIn
;
419 ADDR_TILEINFO tileInfoNull
= {0};
423 // If the original input has a valid ADDR_TILEINFO pointer then copy its contents.
424 // Otherwise the default 0's in tileInfoNull are used.
427 tileInfoNull
= *pIn
->pTileInfo
;
429 localIn
.pTileInfo
= &tileInfoNull
;
432 localIn
.numSamples
= pIn
->numSamples
== 0 ? 1 : pIn
->numSamples
;
434 // Do mipmap check first
435 // If format is BCn, pre-pad dimension to power-of-two according to HWL
436 ComputeMipLevel(&localIn
);
438 if (m_configFlags
.checkLast2DLevel
)
440 // Save this level's original height in pixels
441 pOut
->height
= pIn
->height
;
446 AddrElemMode elemMode
;
448 // Save outputs that may not go through HWL
449 pOut
->pixelBits
= localIn
.bpp
;
450 pOut
->numSamples
= localIn
.numSamples
;
451 pOut
->last2DLevel
= FALSE
;
452 pOut
->tcCompatible
= FALSE
;
455 if (localIn
.numSamples
> 1)
457 ADDR_ASSERT(localIn
.mipLevel
== 0);
461 if (localIn
.format
!= ADDR_FMT_INVALID
) // Set format to INVALID will skip this conversion
463 // Get compression/expansion factors and element mode
464 // (which indicates compression/expansion
465 localIn
.bpp
= GetElemLib()->GetBitsPerPixel(localIn
.format
,
470 // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
471 // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
472 // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
473 // restrictions are different.
474 // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
475 // but we use this flag to skip RestoreSurfaceInfo below
477 if ((elemMode
== ADDR_EXPANDED
) &&
480 ADDR_ASSERT(localIn
.tileMode
== ADDR_TM_LINEAR_ALIGNED
|| localIn
.height
== 1);
483 GetElemLib()->AdjustSurfaceInfo(elemMode
,
491 // Overwrite these parameters if we have a valid format
493 else if (localIn
.bpp
!= 0)
495 localIn
.width
= (localIn
.width
!= 0) ? localIn
.width
: 1;
496 localIn
.height
= (localIn
.height
!= 0) ? localIn
.height
: 1;
498 else // Rule out some invalid parameters
500 ADDR_ASSERT_ALWAYS();
502 returnCode
= ADDR_INVALIDPARAMS
;
505 // Check mipmap after surface expansion
506 if (returnCode
== ADDR_OK
)
508 returnCode
= PostComputeMipLevel(&localIn
, pOut
);
511 if (returnCode
== ADDR_OK
)
513 if (UseTileIndex(localIn
.tileIndex
))
515 // Make sure pTileInfo is not NULL
516 ADDR_ASSERT(localIn
.pTileInfo
);
518 UINT_32 numSamples
= GetNumFragments(localIn
.numSamples
, localIn
.numFrags
);
520 INT_32 macroModeIndex
= TileIndexNoMacroIndex
;
522 if (localIn
.tileIndex
!= TileIndexLinearGeneral
)
524 // Try finding a macroModeIndex
525 macroModeIndex
= HwlComputeMacroModeIndex(localIn
.tileIndex
,
534 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
535 if (macroModeIndex
== TileIndexNoMacroIndex
)
537 returnCode
= HwlSetupTileCfg(localIn
.tileIndex
, macroModeIndex
,
539 &localIn
.tileMode
, &localIn
.tileType
);
541 // If macroModeIndex is invalid, then assert this is not macro tiled
542 else if (macroModeIndex
== TileIndexInvalid
)
544 ADDR_ASSERT(!IsMacroTiled(localIn
.tileMode
));
547 pOut
->macroModeIndex
= macroModeIndex
;
551 if (returnCode
== ADDR_OK
)
553 AddrTileMode tileMode
= localIn
.tileMode
;
554 AddrTileType tileType
= localIn
.tileType
;
556 // HWL layer may override tile mode if necessary
557 if (HwlOverrideTileMode(&localIn
, &tileMode
, &tileType
))
559 localIn
.tileMode
= tileMode
;
560 localIn
.tileType
= tileType
;
562 // Degrade base level if applicable
563 if (DegradeBaseLevel(&localIn
, &tileMode
))
565 localIn
.tileMode
= tileMode
;
569 // Call main function to compute surface info
570 if (returnCode
== ADDR_OK
)
572 returnCode
= HwlComputeSurfaceInfo(&localIn
, pOut
);
575 if (returnCode
== ADDR_OK
)
577 // Since bpp might be changed we just pass it through
578 pOut
->bpp
= localIn
.bpp
;
580 // Also original width/height/bpp
581 pOut
->pixelPitch
= pOut
->pitch
;
582 pOut
->pixelHeight
= pOut
->height
;
585 if (localIn
.flags
.display
)
587 ADDR_ASSERT((pOut
->pitchAlign
% 32) == 0);
591 if (localIn
.format
!= ADDR_FMT_INVALID
)
594 // 96 bits surface of level 1+ requires element pitch of 32 bits instead
595 // In hwl function we skip multiplication of 3 then we should skip division of 3
596 // We keep pitch that represents 32 bit element instead of 96 bits since we
597 // will get an odd number if divided by 3.
599 if (!((expandX
== 3) && (localIn
.mipLevel
> 0)))
602 GetElemLib()->RestoreSurfaceInfo(elemMode
,
611 if (localIn
.flags
.qbStereo
)
613 if (pOut
->pStereoInfo
)
615 ComputeQbStereoInfo(pOut
);
619 if (localIn
.flags
.volume
) // For volume sliceSize equals to all z-slices
621 pOut
->sliceSize
= pOut
->surfSize
;
623 else // For array: sliceSize is likely to have slice-padding (the last one)
625 pOut
->sliceSize
= pOut
->surfSize
/ pOut
->depth
;
628 if (pIn
->numSlices
> 1)
630 // If this is the last slice then add the padding size to this slice
631 if (pIn
->slice
== (pIn
->numSlices
- 1))
633 pOut
->sliceSize
+= pOut
->sliceSize
* (pOut
->depth
- pIn
->numSlices
);
635 else if (m_configFlags
.checkLast2DLevel
)
637 // Reset last2DLevel flag if this is not the last array slice
638 pOut
->last2DLevel
= FALSE
;
643 pOut
->pitchTileMax
= pOut
->pitch
/ 8 - 1;
644 pOut
->heightTileMax
= pOut
->height
/ 8 - 1;
645 pOut
->sliceTileMax
= pOut
->pitch
* pOut
->height
/ 64 - 1;
653 ***************************************************************************************************
654 * AddrLib::ComputeSurfaceInfo
657 * Interface function stub of AddrComputeSurfaceInfo.
661 ***************************************************************************************************
663 ADDR_E_RETURNCODE
AddrLib::ComputeSurfaceAddrFromCoord(
664 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
665 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
668 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
670 if (GetFillSizeFieldsFlags() == TRUE
)
672 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
)) ||
673 (pOut
->size
!= sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
)))
675 returnCode
= ADDR_PARAMSIZEMISMATCH
;
679 if (returnCode
== ADDR_OK
)
681 ADDR_TILEINFO tileInfoNull
;
682 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT input
;
684 if (UseTileIndex(pIn
->tileIndex
))
687 // Use temp tile info for calcalation
688 input
.pTileInfo
= &tileInfoNull
;
690 const ADDR_SURFACE_FLAGS flags
= {{0}};
691 UINT_32 numSamples
= GetNumFragments(pIn
->numSamples
, pIn
->numFrags
);
693 // Try finding a macroModeIndex
694 INT_32 macroModeIndex
= HwlComputeMacroModeIndex(input
.tileIndex
,
702 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
703 if (macroModeIndex
== TileIndexNoMacroIndex
)
705 returnCode
= HwlSetupTileCfg(input
.tileIndex
, macroModeIndex
,
706 input
.pTileInfo
, &input
.tileMode
, &input
.tileType
);
708 // If macroModeIndex is invalid, then assert this is not macro tiled
709 else if (macroModeIndex
== TileIndexInvalid
)
711 ADDR_ASSERT(!IsMacroTiled(input
.tileMode
));
714 // Change the input structure
718 if (returnCode
== ADDR_OK
)
720 returnCode
= HwlComputeSurfaceAddrFromCoord(pIn
, pOut
);
722 if (returnCode
== ADDR_OK
)
724 pOut
->prtBlockIndex
= static_cast<UINT_32
>(pOut
->addr
/ (64 * 1024));
733 ***************************************************************************************************
734 * AddrLib::ComputeSurfaceCoordFromAddr
737 * Interface function stub of ComputeSurfaceCoordFromAddr.
741 ***************************************************************************************************
743 ADDR_E_RETURNCODE
AddrLib::ComputeSurfaceCoordFromAddr(
744 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
745 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
748 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
750 if (GetFillSizeFieldsFlags() == TRUE
)
752 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
)) ||
753 (pOut
->size
!= sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
)))
755 returnCode
= ADDR_PARAMSIZEMISMATCH
;
759 if (returnCode
== ADDR_OK
)
761 ADDR_TILEINFO tileInfoNull
;
762 ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT input
;
764 if (UseTileIndex(pIn
->tileIndex
))
767 // Use temp tile info for calcalation
768 input
.pTileInfo
= &tileInfoNull
;
770 const ADDR_SURFACE_FLAGS flags
= {{0}};
771 UINT_32 numSamples
= GetNumFragments(pIn
->numSamples
, pIn
->numFrags
);
773 // Try finding a macroModeIndex
774 INT_32 macroModeIndex
= HwlComputeMacroModeIndex(input
.tileIndex
,
782 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
783 if (macroModeIndex
== TileIndexNoMacroIndex
)
785 returnCode
= HwlSetupTileCfg(input
.tileIndex
, macroModeIndex
,
786 input
.pTileInfo
, &input
.tileMode
, &input
.tileType
);
788 // If macroModeIndex is invalid, then assert this is not macro tiled
789 else if (macroModeIndex
== TileIndexInvalid
)
791 ADDR_ASSERT(!IsMacroTiled(input
.tileMode
));
794 // Change the input structure
798 if (returnCode
== ADDR_OK
)
800 returnCode
= HwlComputeSurfaceCoordFromAddr(pIn
, pOut
);
808 ***************************************************************************************************
809 * AddrLib::ComputeSliceTileSwizzle
812 * Interface function stub of ComputeSliceTileSwizzle.
816 ***************************************************************************************************
818 ADDR_E_RETURNCODE
AddrLib::ComputeSliceTileSwizzle(
819 const ADDR_COMPUTE_SLICESWIZZLE_INPUT
* pIn
, ///< [in] input structure
820 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
* pOut
///< [out] output structure
823 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
825 if (GetFillSizeFieldsFlags() == TRUE
)
827 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SLICESWIZZLE_INPUT
)) ||
828 (pOut
->size
!= sizeof(ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
)))
830 returnCode
= ADDR_PARAMSIZEMISMATCH
;
834 if (returnCode
== ADDR_OK
)
836 ADDR_TILEINFO tileInfoNull
;
837 ADDR_COMPUTE_SLICESWIZZLE_INPUT input
;
839 if (UseTileIndex(pIn
->tileIndex
))
842 // Use temp tile info for calcalation
843 input
.pTileInfo
= &tileInfoNull
;
845 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
,
846 input
.pTileInfo
, &input
.tileMode
);
847 // Change the input structure
851 if (returnCode
== ADDR_OK
)
853 returnCode
= HwlComputeSliceTileSwizzle(pIn
, pOut
);
861 ***************************************************************************************************
862 * AddrLib::ExtractBankPipeSwizzle
865 * Interface function stub of AddrExtractBankPipeSwizzle.
869 ***************************************************************************************************
871 ADDR_E_RETURNCODE
AddrLib::ExtractBankPipeSwizzle(
872 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
873 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
876 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
878 if (GetFillSizeFieldsFlags() == TRUE
)
880 if ((pIn
->size
!= sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
)) ||
881 (pOut
->size
!= sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
)))
883 returnCode
= ADDR_PARAMSIZEMISMATCH
;
887 if (returnCode
== ADDR_OK
)
889 ADDR_TILEINFO tileInfoNull
;
890 ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT input
;
892 if (UseTileIndex(pIn
->tileIndex
))
895 // Use temp tile info for calcalation
896 input
.pTileInfo
= &tileInfoNull
;
898 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
899 // Change the input structure
903 if (returnCode
== ADDR_OK
)
905 returnCode
= HwlExtractBankPipeSwizzle(pIn
, pOut
);
913 ***************************************************************************************************
914 * AddrLib::CombineBankPipeSwizzle
917 * Interface function stub of AddrCombineBankPipeSwizzle.
921 ***************************************************************************************************
923 ADDR_E_RETURNCODE
AddrLib::CombineBankPipeSwizzle(
924 const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
925 ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
928 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
930 if (GetFillSizeFieldsFlags() == TRUE
)
932 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT
)) ||
933 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT
)))
935 returnCode
= ADDR_PARAMSIZEMISMATCH
;
939 if (returnCode
== ADDR_OK
)
941 ADDR_TILEINFO tileInfoNull
;
942 ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT input
;
944 if (UseTileIndex(pIn
->tileIndex
))
947 // Use temp tile info for calcalation
948 input
.pTileInfo
= &tileInfoNull
;
950 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
951 // Change the input structure
955 if (returnCode
== ADDR_OK
)
957 returnCode
= HwlCombineBankPipeSwizzle(pIn
->bankSwizzle
,
969 ***************************************************************************************************
970 * AddrLib::ComputeBaseSwizzle
973 * Interface function stub of AddrCompueBaseSwizzle.
976 ***************************************************************************************************
978 ADDR_E_RETURNCODE
AddrLib::ComputeBaseSwizzle(
979 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT
* pIn
,
980 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
* pOut
) const
982 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
984 if (GetFillSizeFieldsFlags() == TRUE
)
986 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT
)) ||
987 (pOut
->size
!= sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
)))
989 returnCode
= ADDR_PARAMSIZEMISMATCH
;
993 if (returnCode
== ADDR_OK
)
995 ADDR_TILEINFO tileInfoNull
;
996 ADDR_COMPUTE_BASE_SWIZZLE_INPUT input
;
998 if (UseTileIndex(pIn
->tileIndex
))
1001 // Use temp tile info for calcalation
1002 input
.pTileInfo
= &tileInfoNull
;
1004 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1005 // Change the input structure
1009 if (returnCode
== ADDR_OK
)
1011 if (IsMacroTiled(pIn
->tileMode
))
1013 returnCode
= HwlComputeBaseSwizzle(pIn
, pOut
);
1017 pOut
->tileSwizzle
= 0;
1026 ***************************************************************************************************
1027 * AddrLib::ComputeFmaskInfo
1030 * Interface function stub of ComputeFmaskInfo.
1034 ***************************************************************************************************
1036 ADDR_E_RETURNCODE
AddrLib::ComputeFmaskInfo(
1037 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
1038 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
1041 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1043 if (GetFillSizeFieldsFlags() == TRUE
)
1045 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT
)) ||
1046 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT
)))
1048 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1053 if (ComputeSurfaceThickness(pIn
->tileMode
) > 1)
1055 returnCode
= ADDR_INVALIDPARAMS
;
1058 if (returnCode
== ADDR_OK
)
1060 ADDR_TILEINFO tileInfoNull
;
1061 ADDR_COMPUTE_FMASK_INFO_INPUT input
;
1063 if (UseTileIndex(pIn
->tileIndex
))
1067 if (pOut
->pTileInfo
)
1069 // Use temp tile info for calcalation
1070 input
.pTileInfo
= pOut
->pTileInfo
;
1074 input
.pTileInfo
= &tileInfoNull
;
1077 ADDR_SURFACE_FLAGS flags
= {{0}};
1080 // Try finding a macroModeIndex
1081 INT_32 macroModeIndex
= HwlComputeMacroModeIndex(pIn
->tileIndex
,
1083 HwlComputeFmaskBits(pIn
, NULL
),
1088 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
1089 if (macroModeIndex
== TileIndexNoMacroIndex
)
1091 returnCode
= HwlSetupTileCfg(input
.tileIndex
, macroModeIndex
,
1092 input
.pTileInfo
, &input
.tileMode
);
1095 ADDR_ASSERT(macroModeIndex
!= TileIndexInvalid
);
1097 // Change the input structure
1101 if (returnCode
== ADDR_OK
)
1103 if (pIn
->numSamples
> 1)
1105 returnCode
= HwlComputeFmaskInfo(pIn
, pOut
);
1109 memset(pOut
, 0, sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT
));
1111 returnCode
= ADDR_INVALIDPARAMS
;
1120 ***************************************************************************************************
1121 * AddrLib::ComputeFmaskAddrFromCoord
1124 * Interface function stub of ComputeFmaskAddrFromCoord.
1128 ***************************************************************************************************
1130 ADDR_E_RETURNCODE
AddrLib::ComputeFmaskAddrFromCoord(
1131 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1132 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1135 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1137 if (GetFillSizeFieldsFlags() == TRUE
)
1139 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
)) ||
1140 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
)))
1142 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1146 if (returnCode
== ADDR_OK
)
1148 ADDR_ASSERT(pIn
->numSamples
> 1);
1150 if (pIn
->numSamples
> 1)
1152 returnCode
= HwlComputeFmaskAddrFromCoord(pIn
, pOut
);
1156 returnCode
= ADDR_INVALIDPARAMS
;
1164 ***************************************************************************************************
1165 * AddrLib::ComputeFmaskCoordFromAddr
1168 * Interface function stub of ComputeFmaskAddrFromCoord.
1172 ***************************************************************************************************
1174 ADDR_E_RETURNCODE
AddrLib::ComputeFmaskCoordFromAddr(
1175 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
1176 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
1179 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1181 if (GetFillSizeFieldsFlags() == TRUE
)
1183 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
)) ||
1184 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
)))
1186 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1190 if (returnCode
== ADDR_OK
)
1192 ADDR_ASSERT(pIn
->numSamples
> 1);
1194 if (pIn
->numSamples
> 1)
1196 returnCode
= HwlComputeFmaskCoordFromAddr(pIn
, pOut
);
1200 returnCode
= ADDR_INVALIDPARAMS
;
1208 ***************************************************************************************************
1209 * AddrLib::ConvertTileInfoToHW
1212 * Convert tile info from real value to HW register value in HW layer
1216 ***************************************************************************************************
1218 ADDR_E_RETURNCODE
AddrLib::ConvertTileInfoToHW(
1219 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
1220 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
1223 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1225 if (GetFillSizeFieldsFlags() == TRUE
)
1227 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT
)) ||
1228 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT
)))
1230 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1234 if (returnCode
== ADDR_OK
)
1236 ADDR_TILEINFO tileInfoNull
;
1237 ADDR_CONVERT_TILEINFOTOHW_INPUT input
;
1238 // if pIn->reverse is TRUE, indices are ignored
1239 if (pIn
->reverse
== FALSE
&& UseTileIndex(pIn
->tileIndex
))
1242 input
.pTileInfo
= &tileInfoNull
;
1244 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1249 if (returnCode
== ADDR_OK
)
1251 returnCode
= HwlConvertTileInfoToHW(pIn
, pOut
);
1259 ***************************************************************************************************
1260 * AddrLib::ConvertTileIndex
1263 * Convert tile index to tile mode/type/info
1267 ***************************************************************************************************
1269 ADDR_E_RETURNCODE
AddrLib::ConvertTileIndex(
1270 const ADDR_CONVERT_TILEINDEX_INPUT
* pIn
, ///< [in] input structure
1271 ADDR_CONVERT_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1274 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1276 if (GetFillSizeFieldsFlags() == TRUE
)
1278 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_INPUT
)) ||
1279 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT
)))
1281 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1285 if (returnCode
== ADDR_OK
)
1288 returnCode
= HwlSetupTileCfg(pIn
->tileIndex
, pIn
->macroModeIndex
,
1289 pOut
->pTileInfo
, &pOut
->tileMode
, &pOut
->tileType
);
1291 if (returnCode
== ADDR_OK
&& pIn
->tileInfoHw
)
1293 ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput
= {0};
1294 ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput
= {0};
1296 hwInput
.pTileInfo
= pOut
->pTileInfo
;
1297 hwInput
.tileIndex
= -1;
1298 hwOutput
.pTileInfo
= pOut
->pTileInfo
;
1300 returnCode
= HwlConvertTileInfoToHW(&hwInput
, &hwOutput
);
1308 ***************************************************************************************************
1309 * AddrLib::ConvertTileIndex1
1312 * Convert tile index to tile mode/type/info
1316 ***************************************************************************************************
1318 ADDR_E_RETURNCODE
AddrLib::ConvertTileIndex1(
1319 const ADDR_CONVERT_TILEINDEX1_INPUT
* pIn
, ///< [in] input structure
1320 ADDR_CONVERT_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1323 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1325 if (GetFillSizeFieldsFlags() == TRUE
)
1327 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINDEX1_INPUT
)) ||
1328 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT
)))
1330 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1334 if (returnCode
== ADDR_OK
)
1336 ADDR_SURFACE_FLAGS flags
= {{0}};
1338 HwlComputeMacroModeIndex(pIn
->tileIndex
, flags
, pIn
->bpp
, pIn
->numSamples
,
1339 pOut
->pTileInfo
, &pOut
->tileMode
, &pOut
->tileType
);
1341 if (pIn
->tileInfoHw
)
1343 ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput
= {0};
1344 ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput
= {0};
1346 hwInput
.pTileInfo
= pOut
->pTileInfo
;
1347 hwInput
.tileIndex
= -1;
1348 hwOutput
.pTileInfo
= pOut
->pTileInfo
;
1350 returnCode
= HwlConvertTileInfoToHW(&hwInput
, &hwOutput
);
1358 ***************************************************************************************************
1359 * AddrLib::GetTileIndex
1362 * Get tile index from tile mode/type/info
1366 ***************************************************************************************************
1368 ADDR_E_RETURNCODE
AddrLib::GetTileIndex(
1369 const ADDR_GET_TILEINDEX_INPUT
* pIn
, ///< [in] input structure
1370 ADDR_GET_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1373 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1375 if (GetFillSizeFieldsFlags() == TRUE
)
1377 if ((pIn
->size
!= sizeof(ADDR_GET_TILEINDEX_INPUT
)) ||
1378 (pOut
->size
!= sizeof(ADDR_GET_TILEINDEX_OUTPUT
)))
1380 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1384 if (returnCode
== ADDR_OK
)
1386 returnCode
= HwlGetTileIndex(pIn
, pOut
);
1393 ***************************************************************************************************
1394 * AddrLib::ComputeSurfaceThickness
1397 * Compute surface thickness
1401 ***************************************************************************************************
1403 UINT_32
AddrLib::ComputeSurfaceThickness(
1404 AddrTileMode tileMode
) ///< [in] tile mode
1406 return m_modeFlags
[tileMode
].thickness
;
1411 ///////////////////////////////////////////////////////////////////////////////////////////////////
1413 ///////////////////////////////////////////////////////////////////////////////////////////////////
1416 ***************************************************************************************************
1417 * AddrLib::ComputeHtileInfo
1420 * Interface function stub of AddrComputeHtilenfo
1424 ***************************************************************************************************
1426 ADDR_E_RETURNCODE
AddrLib::ComputeHtileInfo(
1427 const ADDR_COMPUTE_HTILE_INFO_INPUT
* pIn
, ///< [in] input structure
1428 ADDR_COMPUTE_HTILE_INFO_OUTPUT
* pOut
///< [out] output structure
1431 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1433 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1434 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1436 if (GetFillSizeFieldsFlags() == TRUE
)
1438 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT
)) ||
1439 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT
)))
1441 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1445 if (returnCode
== ADDR_OK
)
1447 ADDR_TILEINFO tileInfoNull
;
1448 ADDR_COMPUTE_HTILE_INFO_INPUT input
;
1450 if (UseTileIndex(pIn
->tileIndex
))
1453 // Use temp tile info for calcalation
1454 input
.pTileInfo
= &tileInfoNull
;
1456 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1458 // Change the input structure
1462 if (returnCode
== ADDR_OK
)
1464 pOut
->bpp
= ComputeHtileInfo(pIn
->flags
,
1486 ***************************************************************************************************
1487 * AddrLib::ComputeCmaskInfo
1490 * Interface function stub of AddrComputeCmaskInfo
1494 ***************************************************************************************************
1496 ADDR_E_RETURNCODE
AddrLib::ComputeCmaskInfo(
1497 const ADDR_COMPUTE_CMASK_INFO_INPUT
* pIn
, ///< [in] input structure
1498 ADDR_COMPUTE_CMASK_INFO_OUTPUT
* pOut
///< [out] output structure
1501 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1503 if (GetFillSizeFieldsFlags() == TRUE
)
1505 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_INFO_INPUT
)) ||
1506 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_INFO_OUTPUT
)))
1508 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1512 if (returnCode
== ADDR_OK
)
1514 ADDR_TILEINFO tileInfoNull
;
1515 ADDR_COMPUTE_CMASK_INFO_INPUT input
;
1517 if (UseTileIndex(pIn
->tileIndex
))
1520 // Use temp tile info for calcalation
1521 input
.pTileInfo
= &tileInfoNull
;
1523 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1525 // Change the input structure
1529 if (returnCode
== ADDR_OK
)
1531 returnCode
= ComputeCmaskInfo(pIn
->flags
,
1552 ***************************************************************************************************
1553 * AddrLib::ComputeDccInfo
1556 * Interface function to compute DCC key info
1559 * return code of HwlComputeDccInfo
1560 ***************************************************************************************************
1562 ADDR_E_RETURNCODE
AddrLib::ComputeDccInfo(
1563 const ADDR_COMPUTE_DCCINFO_INPUT
* pIn
, ///< [in] input structure
1564 ADDR_COMPUTE_DCCINFO_OUTPUT
* pOut
///< [out] output structure
1567 ADDR_E_RETURNCODE ret
= ADDR_OK
;
1569 if (GetFillSizeFieldsFlags() == TRUE
)
1571 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_DCCINFO_INPUT
)) ||
1572 (pOut
->size
!= sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT
)))
1574 ret
= ADDR_PARAMSIZEMISMATCH
;
1580 ADDR_COMPUTE_DCCINFO_INPUT input
;
1582 if (UseTileIndex(pIn
->tileIndex
))
1586 ret
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
,
1587 &input
.tileInfo
, &input
.tileMode
);
1594 ret
= HwlComputeDccInfo(pIn
, pOut
);
1602 ***************************************************************************************************
1603 * AddrLib::ComputeHtileAddrFromCoord
1606 * Interface function stub of AddrComputeHtileAddrFromCoord
1610 ***************************************************************************************************
1612 ADDR_E_RETURNCODE
AddrLib::ComputeHtileAddrFromCoord(
1613 const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1614 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1617 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1619 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1620 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1622 if (GetFillSizeFieldsFlags() == TRUE
)
1624 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
)) ||
1625 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
)))
1627 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1631 if (returnCode
== ADDR_OK
)
1633 ADDR_TILEINFO tileInfoNull
;
1634 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT input
;
1636 if (UseTileIndex(pIn
->tileIndex
))
1639 // Use temp tile info for calcalation
1640 input
.pTileInfo
= &tileInfoNull
;
1642 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1644 // Change the input structure
1648 if (returnCode
== ADDR_OK
)
1650 pOut
->addr
= HwlComputeXmaskAddrFromCoord(pIn
->pitch
,
1661 &pOut
->bitPosition
);
1670 ***************************************************************************************************
1671 * AddrLib::ComputeHtileCoordFromAddr
1674 * Interface function stub of AddrComputeHtileCoordFromAddr
1678 ***************************************************************************************************
1680 ADDR_E_RETURNCODE
AddrLib::ComputeHtileCoordFromAddr(
1681 const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
1682 ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
1685 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1687 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1688 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1690 if (GetFillSizeFieldsFlags() == TRUE
)
1692 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT
)) ||
1693 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
)))
1695 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1699 if (returnCode
== ADDR_OK
)
1701 ADDR_TILEINFO tileInfoNull
;
1702 ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT input
;
1704 if (UseTileIndex(pIn
->tileIndex
))
1707 // Use temp tile info for calcalation
1708 input
.pTileInfo
= &tileInfoNull
;
1710 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1712 // Change the input structure
1716 if (returnCode
== ADDR_OK
)
1718 HwlComputeXmaskCoordFromAddr(pIn
->addr
,
1738 ***************************************************************************************************
1739 * AddrLib::ComputeCmaskAddrFromCoord
1742 * Interface function stub of AddrComputeCmaskAddrFromCoord
1746 ***************************************************************************************************
1748 ADDR_E_RETURNCODE
AddrLib::ComputeCmaskAddrFromCoord(
1749 const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1750 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1753 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1755 if (GetFillSizeFieldsFlags() == TRUE
)
1757 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
)) ||
1758 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
)))
1760 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1764 if (returnCode
== ADDR_OK
)
1766 ADDR_TILEINFO tileInfoNull
;
1767 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT input
;
1769 if (UseTileIndex(pIn
->tileIndex
))
1772 // Use temp tile info for calcalation
1773 input
.pTileInfo
= &tileInfoNull
;
1775 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1777 // Change the input structure
1781 if (returnCode
== ADDR_OK
)
1783 if (pIn
->flags
.tcCompatible
== TRUE
)
1785 returnCode
= HwlComputeCmaskAddrFromCoord(pIn
, pOut
);
1789 pOut
->addr
= HwlComputeXmaskAddrFromCoord(pIn
->pitch
,
1797 FALSE
, //this is cmask, isWidth8 is not needed
1798 FALSE
, //this is cmask, isHeight8 is not needed
1800 &pOut
->bitPosition
);
1810 ***************************************************************************************************
1811 * AddrLib::ComputeCmaskCoordFromAddr
1814 * Interface function stub of AddrComputeCmaskCoordFromAddr
1818 ***************************************************************************************************
1820 ADDR_E_RETURNCODE
AddrLib::ComputeCmaskCoordFromAddr(
1821 const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
1822 ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
1825 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1827 if (GetFillSizeFieldsFlags() == TRUE
)
1829 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT
)) ||
1830 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT
)))
1832 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1836 if (returnCode
== ADDR_OK
)
1838 ADDR_TILEINFO tileInfoNull
;
1839 ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT input
;
1841 if (UseTileIndex(pIn
->tileIndex
))
1844 // Use temp tile info for calcalation
1845 input
.pTileInfo
= &tileInfoNull
;
1847 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1849 // Change the input structure
1853 if (returnCode
== ADDR_OK
)
1855 HwlComputeXmaskCoordFromAddr(pIn
->addr
,
1875 ***************************************************************************************************
1876 * AddrLib::ComputeTileDataWidthAndHeight
1879 * Compute the squared cache shape for per-tile data (CMASK and HTILE)
1885 * MacroWidth and macroHeight are measured in pixels
1886 ***************************************************************************************************
1888 VOID
AddrLib::ComputeTileDataWidthAndHeight(
1889 UINT_32 bpp
, ///< [in] bits per pixel
1890 UINT_32 cacheBits
, ///< [in] bits of cache
1891 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1892 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1893 UINT_32
* pMacroHeight
///< [out] macro tile height
1897 UINT_32 width
= cacheBits
/ bpp
;
1898 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
1900 // Double height until the macro-tile is close to square
1901 // Height can only be doubled if width is even
1903 while ((width
> height
* 2 * pipes
) && !(width
& 1))
1909 *pMacroWidth
= 8 * width
;
1910 *pMacroHeight
= 8 * height
* pipes
;
1912 // Note: The above iterative comptuation is equivalent to the following
1914 //int log2_height = ((log2(cacheBits)-log2(bpp)-log2(pipes))/2);
1915 //int macroHeight = pow2( 3+log2(pipes)+log2_height );
1919 ***************************************************************************************************
1920 * AddrLib::HwlComputeTileDataWidthAndHeightLinear
1923 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1929 * MacroWidth and macroHeight are measured in pixels
1930 ***************************************************************************************************
1932 VOID
AddrLib::HwlComputeTileDataWidthAndHeightLinear(
1933 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1934 UINT_32
* pMacroHeight
, ///< [out] macro tile height
1935 UINT_32 bpp
, ///< [in] bits per pixel
1936 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
1939 ADDR_ASSERT(bpp
!= 4); // Cmask does not support linear layout prior to SI
1940 *pMacroWidth
= 8 * 512 / bpp
; // Align width to 512-bit memory accesses
1941 *pMacroHeight
= 8 * m_pipes
; // Align height to number of pipes
1945 ***************************************************************************************************
1946 * AddrLib::ComputeHtileInfo
1949 * Compute htile pitch,width, bytes per 2D slice
1952 * Htile bpp i.e. How many bits for an 8x8 tile
1953 * Also returns by output parameters:
1954 * *Htile pitch, height, total size in bytes, macro-tile dimensions and slice size*
1955 ***************************************************************************************************
1957 UINT_32
AddrLib::ComputeHtileInfo(
1958 ADDR_HTILE_FLAGS flags
, ///< [in] htile flags
1959 UINT_32 pitchIn
, ///< [in] pitch input
1960 UINT_32 heightIn
, ///< [in] height input
1961 UINT_32 numSlices
, ///< [in] number of slices
1962 BOOL_32 isLinear
, ///< [in] if it is linear mode
1963 BOOL_32 isWidth8
, ///< [in] if htile block width is 8
1964 BOOL_32 isHeight8
, ///< [in] if htile block height is 8
1965 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1966 UINT_32
* pPitchOut
, ///< [out] pitch output
1967 UINT_32
* pHeightOut
, ///< [out] height output
1968 UINT_64
* pHtileBytes
, ///< [out] bytes per 2D slice
1969 UINT_32
* pMacroWidth
, ///< [out] macro-tile width in pixels
1970 UINT_32
* pMacroHeight
, ///< [out] macro-tile width in pixels
1971 UINT_64
* pSliceSize
, ///< [out] slice size in bytes
1972 UINT_32
* pBaseAlign
///< [out] base alignment
1977 UINT_32 macroHeight
;
1982 numSlices
= Max(1u, numSlices
);
1984 const UINT_32 bpp
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
1985 const UINT_32 cacheBits
= HtileCacheBits
;
1989 HwlComputeTileDataWidthAndHeightLinear(¯oWidth
,
1996 ComputeTileDataWidthAndHeight(bpp
,
2003 *pPitchOut
= PowTwoAlign(pitchIn
, macroWidth
);
2004 *pHeightOut
= PowTwoAlign(heightIn
, macroHeight
);
2006 baseAlign
= HwlComputeHtileBaseAlign(flags
.tcCompatible
, isLinear
, pTileInfo
);
2008 surfBytes
= HwlComputeHtileBytes(*pPitchOut
,
2016 *pHtileBytes
= surfBytes
;
2019 // Use SafeAssign since they are optional
2021 SafeAssign(pMacroWidth
, macroWidth
);
2023 SafeAssign(pMacroHeight
, macroHeight
);
2025 SafeAssign(pSliceSize
, sliceBytes
);
2027 SafeAssign(pBaseAlign
, baseAlign
);
2033 ***************************************************************************************************
2034 * AddrLib::ComputeCmaskBaseAlign
2037 * Compute cmask base alignment
2040 * Cmask base alignment
2041 ***************************************************************************************************
2043 UINT_32
AddrLib::ComputeCmaskBaseAlign(
2044 ADDR_CMASK_FLAGS flags
, ///< [in] Cmask flags
2045 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
2048 UINT_32 baseAlign
= m_pipeInterleaveBytes
* HwlGetPipes(pTileInfo
);
2050 if (flags
.tcCompatible
)
2052 ADDR_ASSERT(pTileInfo
!= NULL
);
2055 baseAlign
*= pTileInfo
->banks
;
2063 ***************************************************************************************************
2064 * AddrLib::ComputeCmaskBytes
2067 * Compute cmask size in bytes
2070 * Cmask size in bytes
2071 ***************************************************************************************************
2073 UINT_64
AddrLib::ComputeCmaskBytes(
2074 UINT_32 pitch
, ///< [in] pitch
2075 UINT_32 height
, ///< [in] height
2076 UINT_32 numSlices
///< [in] number of slices
2079 return BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* numSlices
* CmaskElemBits
) /
2084 ***************************************************************************************************
2085 * AddrLib::ComputeCmaskInfo
2088 * Compute cmask pitch,width, bytes per 2D slice
2091 * BlockMax. Also by output parameters: Cmask pitch,height, total size in bytes,
2092 * macro-tile dimensions
2093 ***************************************************************************************************
2095 ADDR_E_RETURNCODE
AddrLib::ComputeCmaskInfo(
2096 ADDR_CMASK_FLAGS flags
, ///< [in] cmask flags
2097 UINT_32 pitchIn
, ///< [in] pitch input
2098 UINT_32 heightIn
, ///< [in] height input
2099 UINT_32 numSlices
, ///< [in] number of slices
2100 BOOL_32 isLinear
, ///< [in] is linear mode
2101 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
2102 UINT_32
* pPitchOut
, ///< [out] pitch output
2103 UINT_32
* pHeightOut
, ///< [out] height output
2104 UINT_64
* pCmaskBytes
, ///< [out] bytes per 2D slice
2105 UINT_32
* pMacroWidth
, ///< [out] macro-tile width in pixels
2106 UINT_32
* pMacroHeight
, ///< [out] macro-tile width in pixels
2107 UINT_64
* pSliceSize
, ///< [out] slice size in bytes
2108 UINT_32
* pBaseAlign
, ///< [out] base alignment
2109 UINT_32
* pBlockMax
///< [out] block max == slice / 128 / 128 - 1
2113 UINT_32 macroHeight
;
2118 numSlices
= Max(1u, numSlices
);
2120 const UINT_32 bpp
= CmaskElemBits
;
2121 const UINT_32 cacheBits
= CmaskCacheBits
;
2123 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
2127 HwlComputeTileDataWidthAndHeightLinear(¯oWidth
,
2134 ComputeTileDataWidthAndHeight(bpp
,
2141 *pPitchOut
= (pitchIn
+ macroWidth
- 1) & ~(macroWidth
- 1);
2142 *pHeightOut
= (heightIn
+ macroHeight
- 1) & ~(macroHeight
- 1);
2145 sliceBytes
= ComputeCmaskBytes(*pPitchOut
,
2149 baseAlign
= ComputeCmaskBaseAlign(flags
, pTileInfo
);
2151 while (sliceBytes
% baseAlign
)
2153 *pHeightOut
+= macroHeight
;
2155 sliceBytes
= ComputeCmaskBytes(*pPitchOut
,
2160 surfBytes
= sliceBytes
* numSlices
;
2162 *pCmaskBytes
= surfBytes
;
2165 // Use SafeAssign since they are optional
2167 SafeAssign(pMacroWidth
, macroWidth
);
2169 SafeAssign(pMacroHeight
, macroHeight
);
2171 SafeAssign(pBaseAlign
, baseAlign
);
2173 SafeAssign(pSliceSize
, sliceBytes
);
2175 UINT_32 slice
= (*pPitchOut
) * (*pHeightOut
);
2176 UINT_32 blockMax
= slice
/ 128 / 128 - 1;
2179 if (slice
% (64*256) != 0)
2181 ADDR_ASSERT_ALWAYS();
2185 UINT_32 maxBlockMax
= HwlGetMaxCmaskBlockMax();
2187 if (blockMax
> maxBlockMax
)
2189 blockMax
= maxBlockMax
;
2190 returnCode
= ADDR_INVALIDPARAMS
;
2193 SafeAssign(pBlockMax
, blockMax
);
2199 ***************************************************************************************************
2200 * AddrLib::ComputeXmaskCoordYFromPipe
2203 * Compute the Y coord from pipe number for cmask/htile
2208 ***************************************************************************************************
2210 UINT_32
AddrLib::ComputeXmaskCoordYFromPipe(
2211 UINT_32 pipe
, ///< [in] pipe number
2212 UINT_32 x
///< [in] x coordinate
2224 UINT_32 numPipes
= m_pipes
; // SI has its implementation
2226 // Convert pipe + x to y coordinate.
2246 pipeBit0
= pipe
& 0x1;
2250 yBit0
= pipeBit0
^ xBit0
;
2264 pipeBit0
= pipe
& 0x1;
2265 pipeBit1
= (pipe
& 0x2) >> 1;
2268 xBit1
= (x
& 0x2) >> 1;
2270 yBit0
= pipeBit0
^ xBit1
;
2271 yBit1
= pipeBit1
^ xBit0
;
2280 // r600 and r800 have different method
2282 y
= HwlComputeXmaskCoordYFrom8Pipe(pipe
, x
);
2291 ***************************************************************************************************
2292 * AddrLib::HwlComputeXmaskCoordFromAddr
2295 * Compute the coord from an address of a cmask/htile
2301 * This method is reused by htile, so rename to Xmask
2302 ***************************************************************************************************
2304 VOID
AddrLib::HwlComputeXmaskCoordFromAddr(
2305 UINT_64 addr
, ///< [in] address
2306 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2307 UINT_32 pitch
, ///< [in] pitch
2308 UINT_32 height
, ///< [in] height
2309 UINT_32 numSlices
, ///< [in] number of slices
2310 UINT_32 factor
, ///< [in] factor that indicates cmask or htile
2311 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
2312 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2313 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2314 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
2315 UINT_32
* pX
, ///< [out] x coord
2316 UINT_32
* pY
, ///< [out] y coord
2317 UINT_32
* pSlice
///< [out] slice index
2322 UINT_32 numPipeBits
;
2323 UINT_32 macroTilePitch
;
2324 UINT_32 macroTileHeight
;
2328 UINT_32 microTileCoordY
;
2332 UINT_32 pitchAligned
= pitch
;
2333 UINT_32 heightAligned
= height
;
2341 UINT_64 macroNumber
;
2342 UINT_32 microNumber
;
2351 UINT_32 tilesPerMacro
;
2352 UINT_32 macrosPerPitch
;
2353 UINT_32 macrosPerSlice
;
2358 numPipes
= HwlGetPipes(pTileInfo
);
2359 pipe
= ComputePipeFromAddr(addr
, numPipes
);
2362 // Compute the number of group and pipe bits.
2364 numPipeBits
= Log2(numPipes
);
2366 UINT_32 groupBits
= 8 * m_pipeInterleaveBytes
;
2367 UINT_32 pipes
= numPipes
;
2371 // Compute the micro tile size, in bits. And macro tile pitch and height.
2373 if (factor
== 2) //CMASK
2375 ADDR_CMASK_FLAGS flags
= {{0}};
2377 elemBits
= CmaskElemBits
;
2379 ComputeCmaskInfo(flags
,
2393 ADDR_HTILE_FLAGS flags
= {{0}};
2400 elemBits
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
2402 ComputeHtileInfo(flags
,
2417 // Should use aligned dims
2419 pitch
= pitchAligned
;
2420 height
= heightAligned
;
2424 // Convert byte address to bit address.
2426 bitAddr
= BYTES_TO_BITS(addr
) + bitPosition
;
2430 // Remove pipe bits from address.
2433 bitAddr
= (bitAddr
% groupBits
) + ((bitAddr
/groupBits
/pipes
)*groupBits
);
2436 elemOffset
= bitAddr
/ elemBits
;
2438 tilesPerMacro
= (macroTilePitch
/factor
) * macroTileHeight
/ MicroTilePixels
>> numPipeBits
;
2440 macrosPerPitch
= pitch
/ (macroTilePitch
/factor
);
2441 macrosPerSlice
= macrosPerPitch
* height
/ macroTileHeight
;
2443 macroIndex
= elemOffset
/ factor
/ tilesPerMacro
;
2444 microIndex
= static_cast<UINT_32
>(elemOffset
% (tilesPerMacro
* factor
));
2446 macroNumber
= macroIndex
* factor
+ microIndex
% factor
;
2447 microNumber
= microIndex
/ factor
;
2449 macroX
= static_cast<UINT_32
>((macroNumber
% macrosPerPitch
));
2450 macroY
= static_cast<UINT_32
>((macroNumber
% macrosPerSlice
) / macrosPerPitch
);
2451 macroZ
= static_cast<UINT_32
>((macroNumber
/ macrosPerSlice
));
2454 microX
= microNumber
% (macroTilePitch
/ factor
/ MicroTileWidth
);
2455 microY
= (microNumber
/ (macroTilePitch
/ factor
/ MicroTileHeight
));
2457 *pX
= macroX
* (macroTilePitch
/factor
) + microX
* MicroTileWidth
;
2458 *pY
= macroY
* macroTileHeight
+ (microY
* MicroTileHeight
<< numPipeBits
);
2461 microTileCoordY
= ComputeXmaskCoordYFromPipe(pipe
,
2462 *pX
/MicroTileWidth
);
2466 // Assemble final coordinates.
2468 *pY
+= microTileCoordY
* MicroTileHeight
;
2473 ***************************************************************************************************
2474 * AddrLib::HwlComputeXmaskAddrFromCoord
2477 * Compute the address from an address of cmask (prior to si)
2482 ***************************************************************************************************
2484 UINT_64
AddrLib::HwlComputeXmaskAddrFromCoord(
2485 UINT_32 pitch
, ///< [in] pitch
2486 UINT_32 height
, ///< [in] height
2487 UINT_32 x
, ///< [in] x coord
2488 UINT_32 y
, ///< [in] y coord
2489 UINT_32 slice
, ///< [in] slice/depth index
2490 UINT_32 numSlices
, ///< [in] number of slices
2491 UINT_32 factor
, ///< [in] factor that indicates cmask(2) or htile(1)
2492 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
2493 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2494 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2495 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
2496 UINT_32
* pBitPosition
///< [out] bit position inside a byte
2500 UINT_32 numGroupBits
;
2501 UINT_32 numPipeBits
;
2502 UINT_32 newPitch
= 0;
2503 UINT_32 newHeight
= 0;
2504 UINT_64 sliceBytes
= 0;
2505 UINT_64 totalBytes
= 0;
2506 UINT_64 sliceOffset
;
2508 UINT_32 macroTileWidth
;
2509 UINT_32 macroTileHeight
;
2510 UINT_32 macroTilesPerRow
;
2511 UINT_32 macroTileBytes
;
2512 UINT_32 macroTileIndexX
;
2513 UINT_32 macroTileIndexY
;
2514 UINT_64 macroTileOffset
;
2515 UINT_32 pixelBytesPerRow
;
2516 UINT_32 pixelOffsetX
;
2517 UINT_32 pixelOffsetY
;
2518 UINT_32 pixelOffset
;
2519 UINT_64 totalOffset
;
2525 UINT_32 elemBits
= 0;
2527 UINT_32 numPipes
= m_pipes
; // This function is accessed prior to si only
2529 if (factor
== 2) //CMASK
2531 elemBits
= CmaskElemBits
;
2533 // For asics before SI, cmask is always tiled
2538 if (factor
!= 1) // Fix compile warning
2543 elemBits
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
2547 // Compute the number of group bits and pipe bits.
2549 numGroupBits
= Log2(m_pipeInterleaveBytes
);
2550 numPipeBits
= Log2(numPipes
);
2553 // Compute macro tile dimensions.
2555 if (factor
== 2) // CMASK
2557 ADDR_CMASK_FLAGS flags
= {{0}};
2559 ComputeCmaskInfo(flags
,
2571 sliceBytes
= totalBytes
/ numSlices
;
2575 ADDR_HTILE_FLAGS flags
= {{0}};
2577 ComputeHtileInfo(flags
,
2593 sliceOffset
= slice
* sliceBytes
;
2596 // Get the pipe. Note that neither slice rotation nor pipe swizzling apply for CMASK.
2598 pipe
= ComputePipeFromCoord(x
,
2601 ADDR_TM_2D_TILED_THIN1
,
2607 // Compute the number of macro tiles per row.
2609 macroTilesPerRow
= newPitch
/ macroTileWidth
;
2612 // Compute the number of bytes per macro tile.
2614 macroTileBytes
= BITS_TO_BYTES((macroTileWidth
* macroTileHeight
* elemBits
) / MicroTilePixels
);
2617 // Compute the offset to the macro tile containing the specified coordinate.
2619 macroTileIndexX
= x
/ macroTileWidth
;
2620 macroTileIndexY
= y
/ macroTileHeight
;
2621 macroTileOffset
= ((macroTileIndexY
* macroTilesPerRow
) + macroTileIndexX
) * macroTileBytes
;
2624 // Compute the pixel offset within the macro tile.
2626 pixelBytesPerRow
= BITS_TO_BYTES(macroTileWidth
* elemBits
) / MicroTileWidth
;
2629 // The nibbles are interleaved (see below), so the part of the offset relative to the x
2630 // coordinate repeats halfway across the row. (Not for HTILE)
2634 pixelOffsetX
= (x
% (macroTileWidth
/ 2)) / MicroTileWidth
;
2638 pixelOffsetX
= (x
% (macroTileWidth
)) / MicroTileWidth
* BITS_TO_BYTES(elemBits
);
2642 // Compute the y offset within the macro tile.
2644 pixelOffsetY
= (((y
% macroTileHeight
) / MicroTileHeight
) / numPipes
) * pixelBytesPerRow
;
2646 pixelOffset
= pixelOffsetX
+ pixelOffsetY
;
2649 // Combine the slice offset and macro tile offset with the pixel offset, accounting for the
2650 // pipe bits in the middle of the address.
2652 totalOffset
= ((sliceOffset
+ macroTileOffset
) >> numPipeBits
) + pixelOffset
;
2655 // Split the offset to put some bits below the pipe bits and some above.
2657 groupMask
= (1 << numGroupBits
) - 1;
2658 offsetLo
= totalOffset
& groupMask
;
2659 offsetHi
= (totalOffset
& ~groupMask
) << numPipeBits
;
2662 // Assemble the address from its components.
2666 // This is to remove warning with /analyze option
2667 UINT_32 pipeBits
= pipe
<< numGroupBits
;
2671 // Compute the bit position. The lower nibble is used when the x coordinate within the macro
2672 // tile is less than half of the macro tile width, and the upper nibble is used when the x
2673 // coordinate within the macro tile is greater than or equal to half the macro tile width.
2675 *pBitPosition
= ((x
% macroTileWidth
) < (macroTileWidth
/ factor
)) ? 0 : 4;
2680 ///////////////////////////////////////////////////////////////////////////////////////////////////
2681 // Surface Addressing Shared
2682 ///////////////////////////////////////////////////////////////////////////////////////////////////
2685 ***************************************************************************************************
2686 * AddrLib::ComputeSurfaceAddrFromCoordLinear
2689 * Compute address from coord for linear surface
2694 ***************************************************************************************************
2696 UINT_64
AddrLib::ComputeSurfaceAddrFromCoordLinear(
2697 UINT_32 x
, ///< [in] x coord
2698 UINT_32 y
, ///< [in] y coord
2699 UINT_32 slice
, ///< [in] slice/depth index
2700 UINT_32 sample
, ///< [in] sample index
2701 UINT_32 bpp
, ///< [in] bits per pixel
2702 UINT_32 pitch
, ///< [in] pitch
2703 UINT_32 height
, ///< [in] height
2704 UINT_32 numSlices
, ///< [in] number of slices
2705 UINT_32
* pBitPosition
///< [out] bit position inside a byte
2708 const UINT_64 sliceSize
= static_cast<UINT_64
>(pitch
) * height
;
2710 UINT_64 sliceOffset
= (slice
+ sample
* numSlices
)* sliceSize
;
2711 UINT_64 rowOffset
= static_cast<UINT_64
>(y
) * pitch
;
2712 UINT_64 pixOffset
= x
;
2714 UINT_64 addr
= (sliceOffset
+ rowOffset
+ pixOffset
) * bpp
;
2716 *pBitPosition
= static_cast<UINT_32
>(addr
% 8);
2723 ***************************************************************************************************
2724 * AddrLib::ComputeSurfaceCoordFromAddrLinear
2727 * Compute the coord from an address of a linear surface
2731 ***************************************************************************************************
2733 VOID
AddrLib::ComputeSurfaceCoordFromAddrLinear(
2734 UINT_64 addr
, ///< [in] address
2735 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2736 UINT_32 bpp
, ///< [in] bits per pixel
2737 UINT_32 pitch
, ///< [in] pitch
2738 UINT_32 height
, ///< [in] height
2739 UINT_32 numSlices
, ///< [in] number of slices
2740 UINT_32
* pX
, ///< [out] x coord
2741 UINT_32
* pY
, ///< [out] y coord
2742 UINT_32
* pSlice
, ///< [out] slice/depth index
2743 UINT_32
* pSample
///< [out] sample index
2746 const UINT_64 sliceSize
= static_cast<UINT_64
>(pitch
) * height
;
2747 const UINT_64 linearOffset
= (BYTES_TO_BITS(addr
) + bitPosition
) / bpp
;
2749 *pX
= static_cast<UINT_32
>((linearOffset
% sliceSize
) % pitch
);
2750 *pY
= static_cast<UINT_32
>((linearOffset
% sliceSize
) / pitch
% height
);
2751 *pSlice
= static_cast<UINT_32
>((linearOffset
/ sliceSize
) % numSlices
);
2752 *pSample
= static_cast<UINT_32
>((linearOffset
/ sliceSize
) / numSlices
);
2756 ***************************************************************************************************
2757 * AddrLib::ComputeSurfaceCoordFromAddrMicroTiled
2760 * Compute the coord from an address of a micro tiled surface
2764 ***************************************************************************************************
2766 VOID
AddrLib::ComputeSurfaceCoordFromAddrMicroTiled(
2767 UINT_64 addr
, ///< [in] address
2768 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2769 UINT_32 bpp
, ///< [in] bits per pixel
2770 UINT_32 pitch
, ///< [in] pitch
2771 UINT_32 height
, ///< [in] height
2772 UINT_32 numSamples
, ///< [in] number of samples
2773 AddrTileMode tileMode
, ///< [in] tile mode
2774 UINT_32 tileBase
, ///< [in] base offset within a tile
2775 UINT_32 compBits
, ///< [in] component bits actually needed(for planar surface)
2776 UINT_32
* pX
, ///< [out] x coord
2777 UINT_32
* pY
, ///< [out] y coord
2778 UINT_32
* pSlice
, ///< [out] slice/depth index
2779 UINT_32
* pSample
, ///< [out] sample index,
2780 AddrTileType microTileType
, ///< [in] micro tiling order
2781 BOOL_32 isDepthSampleOrder
///< [in] TRUE if in depth sample order
2785 UINT_32 microTileThickness
;
2786 UINT_32 microTileBits
;
2790 UINT_32 microTileCoordX
;
2791 UINT_32 microTileCoordY
;
2792 UINT_32 pixelOffset
;
2793 UINT_32 pixelCoordX
= 0;
2794 UINT_32 pixelCoordY
= 0;
2795 UINT_32 pixelCoordZ
= 0;
2796 UINT_32 pixelCoordS
= 0;
2799 // Convert byte address to bit address.
2801 bitAddr
= BYTES_TO_BITS(addr
) + bitPosition
;
2804 // Compute the micro tile size, in bits.
2808 case ADDR_TM_1D_TILED_THICK
:
2809 microTileThickness
= ThickTileThickness
;
2812 microTileThickness
= 1;
2816 microTileBits
= MicroTilePixels
* microTileThickness
* bpp
* numSamples
;
2819 // Compute number of bits per slice and number of bits per row of micro tiles.
2821 sliceBits
= static_cast<UINT_64
>(pitch
) * height
* microTileThickness
* bpp
* numSamples
;
2823 rowBits
= (pitch
/ MicroTileWidth
) * microTileBits
;
2826 // Extract the slice index.
2828 sliceIndex
= static_cast<UINT_32
>(bitAddr
/ sliceBits
);
2829 bitAddr
-= sliceIndex
* sliceBits
;
2832 // Extract the y coordinate of the micro tile.
2834 microTileCoordY
= static_cast<UINT_32
>(bitAddr
/ rowBits
) * MicroTileHeight
;
2835 bitAddr
-= (microTileCoordY
/ MicroTileHeight
) * rowBits
;
2838 // Extract the x coordinate of the micro tile.
2840 microTileCoordX
= static_cast<UINT_32
>(bitAddr
/ microTileBits
) * MicroTileWidth
;
2843 // Compute the pixel offset within the micro tile.
2845 pixelOffset
= static_cast<UINT_32
>(bitAddr
% microTileBits
);
2848 // Extract pixel coordinates from the offset.
2850 HwlComputePixelCoordFromOffset(pixelOffset
,
2861 isDepthSampleOrder
);
2864 // Assemble final coordinates.
2866 *pX
= microTileCoordX
+ pixelCoordX
;
2867 *pY
= microTileCoordY
+ pixelCoordY
;
2868 *pSlice
= (sliceIndex
* microTileThickness
) + pixelCoordZ
;
2869 *pSample
= pixelCoordS
;
2871 if (microTileThickness
> 1)
2878 ***************************************************************************************************
2879 * AddrLib::ComputePipeFromAddr
2882 * Compute the pipe number from an address
2887 ***************************************************************************************************
2889 UINT_32
AddrLib::ComputePipeFromAddr(
2890 UINT_64 addr
, ///< [in] address
2891 UINT_32 numPipes
///< [in] number of banks
2896 UINT_32 groupBytes
= m_pipeInterleaveBytes
; //just different terms
2899 // The LSBs of the address are arranged as follows:
2900 // bank | pipe | group
2902 // To get the pipe number, shift off the group bits and mask the pipe bits.
2906 // The LSBs of the address are arranged as follows:
2907 // bank | bankInterleave | pipe | pipeInterleave
2909 // To get the pipe number, shift off the pipe interleave bits and mask the pipe bits.
2912 pipe
= static_cast<UINT_32
>(addr
>> Log2(groupBytes
)) & (numPipes
- 1);
2918 ***************************************************************************************************
2919 * AddrLib::ComputePixelIndexWithinMicroTile
2922 * Compute the pixel index inside a micro tile of surface
2927 ***************************************************************************************************
2929 UINT_32
AddrLib::ComputePixelIndexWithinMicroTile(
2930 UINT_32 x
, ///< [in] x coord
2931 UINT_32 y
, ///< [in] y coord
2932 UINT_32 z
, ///< [in] slice/depth index
2933 UINT_32 bpp
, ///< [in] bits per pixel
2934 AddrTileMode tileMode
, ///< [in] tile mode
2935 AddrTileType microTileType
///< [in] pixel order in display/non-display mode
2938 UINT_32 pixelBit0
= 0;
2939 UINT_32 pixelBit1
= 0;
2940 UINT_32 pixelBit2
= 0;
2941 UINT_32 pixelBit3
= 0;
2942 UINT_32 pixelBit4
= 0;
2943 UINT_32 pixelBit5
= 0;
2944 UINT_32 pixelBit6
= 0;
2945 UINT_32 pixelBit7
= 0;
2946 UINT_32 pixelBit8
= 0;
2947 UINT_32 pixelNumber
;
2949 UINT_32 x0
= _BIT(x
, 0);
2950 UINT_32 x1
= _BIT(x
, 1);
2951 UINT_32 x2
= _BIT(x
, 2);
2952 UINT_32 y0
= _BIT(y
, 0);
2953 UINT_32 y1
= _BIT(y
, 1);
2954 UINT_32 y2
= _BIT(y
, 2);
2955 UINT_32 z0
= _BIT(z
, 0);
2956 UINT_32 z1
= _BIT(z
, 1);
2957 UINT_32 z2
= _BIT(z
, 2);
2959 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
2961 // Compute the pixel number within the micro tile.
2963 if (microTileType
!= ADDR_THICK
)
2965 if (microTileType
== ADDR_DISPLAYABLE
)
3010 ADDR_ASSERT_ALWAYS();
3014 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
3023 else if (microTileType
== ADDR_ROTATED
)
3025 ADDR_ASSERT(thickness
== 1);
3062 ADDR_ASSERT_ALWAYS();
3075 ADDR_ASSERT(thickness
> 1);
3106 ADDR_ASSERT_ALWAYS();
3119 pixelNumber
= ((pixelBit0
) |
3133 ***************************************************************************************************
3134 * AddrLib::AdjustPitchAlignment
3137 * Adjusts pitch alignment for flipping surface
3142 ***************************************************************************************************
3144 VOID
AddrLib::AdjustPitchAlignment(
3145 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface flags
3146 UINT_32
* pPitchAlign
///< [out] Pointer to pitch alignment
3149 // Display engine hardwires lower 5 bit of GRPH_PITCH to ZERO which means 32 pixel alignment
3150 // Maybe it will be fixed in future but let's make it general for now.
3151 if (flags
.display
|| flags
.overlay
)
3153 *pPitchAlign
= PowTwoAlign(*pPitchAlign
, 32);
3157 *pPitchAlign
= Max(m_minPitchAlignPixels
, *pPitchAlign
);
3163 ***************************************************************************************************
3164 * AddrLib::PadDimensions
3167 * Helper function to pad dimensions
3172 ***************************************************************************************************
3174 VOID
AddrLib::PadDimensions(
3175 AddrTileMode tileMode
, ///< [in] tile mode
3176 UINT_32 bpp
, ///< [in] bits per pixel
3177 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
3178 UINT_32 numSamples
, ///< [in] number of samples
3179 ADDR_TILEINFO
* pTileInfo
, ///< [in/out] bank structure.
3180 UINT_32 padDims
, ///< [in] Dimensions to pad valid value 1,2,3
3181 UINT_32 mipLevel
, ///< [in] MipLevel
3182 UINT_32
* pPitch
, ///< [in/out] pitch in pixels
3183 UINT_32 pitchAlign
, ///< [in] pitch alignment
3184 UINT_32
* pHeight
, ///< [in/out] height in pixels
3185 UINT_32 heightAlign
, ///< [in] height alignment
3186 UINT_32
* pSlices
, ///< [in/out] number of slices
3187 UINT_32 sliceAlign
///< [in] number of slice alignment
3190 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
3192 ADDR_ASSERT(padDims
<= 3);
3195 // Override padding for mip levels
3201 // for cubemap, we only pad when client call with 6 faces as an identity
3204 padDims
= 3; // we should pad cubemap sub levels when we treat it as 3d texture
3213 // Any possibilities that padDims is 0?
3219 if (IsPow2(pitchAlign
))
3221 *pPitch
= PowTwoAlign((*pPitch
), pitchAlign
);
3223 else // add this code to pass unit test, r600 linear mode is not align bpp to pow2 for linear
3225 *pPitch
+= pitchAlign
- 1;
3226 *pPitch
/= pitchAlign
;
3227 *pPitch
*= pitchAlign
;
3232 *pHeight
= PowTwoAlign((*pHeight
), heightAlign
);
3235 if (padDims
> 2 || thickness
> 1)
3237 // for cubemap single face, we do not pad slices.
3238 // if we pad it, the slice number should be set to 6 and current mip level > 1
3239 if (flags
.cube
&& (!m_configFlags
.noCubeMipSlicesPad
|| flags
.cubeAsArray
))
3241 *pSlices
= NextPow2(*pSlices
);
3244 // normal 3D texture or arrays or cubemap has a thick mode? (Just pass unit test)
3247 *pSlices
= PowTwoAlign((*pSlices
), sliceAlign
);
3252 HwlPadDimensions(tileMode
,
3269 ***************************************************************************************************
3270 * AddrLib::HwlPreHandleBaseLvl3xPitch
3273 * Pre-handler of 3x pitch (96 bit) adjustment
3277 ***************************************************************************************************
3279 UINT_32
AddrLib::HwlPreHandleBaseLvl3xPitch(
3280 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
3281 UINT_32 expPitch
///< [in] pitch
3284 ADDR_ASSERT(pIn
->width
== expPitch
);
3286 // If pitch is pre-multiplied by 3, we retrieve original one here to get correct miplevel size
3288 if (AddrElemLib::IsExpand3x(pIn
->format
) &&
3289 pIn
->mipLevel
== 0 &&
3290 pIn
->tileMode
== ADDR_TM_LINEAR_ALIGNED
)
3293 expPitch
= NextPow2(expPitch
);
3300 ***************************************************************************************************
3301 * AddrLib::HwlPostHandleBaseLvl3xPitch
3304 * Post-handler of 3x pitch adjustment
3308 ***************************************************************************************************
3310 UINT_32
AddrLib::HwlPostHandleBaseLvl3xPitch(
3311 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
3312 UINT_32 expPitch
///< [in] pitch
3316 // 96 bits surface of sub levels require element pitch of 32 bits instead
3317 // So we just return pitch in 32 bit pixels without timing 3
3319 if (AddrElemLib::IsExpand3x(pIn
->format
) &&
3320 pIn
->mipLevel
== 0 &&
3321 pIn
->tileMode
== ADDR_TM_LINEAR_ALIGNED
)
3331 ***************************************************************************************************
3332 * AddrLib::IsMacroTiled
3335 * Check if the tile mode is macro tiled
3338 * TRUE if it is macro tiled (2D/2B/3D/3B)
3339 ***************************************************************************************************
3341 BOOL_32
AddrLib::IsMacroTiled(
3342 AddrTileMode tileMode
) ///< [in] tile mode
3344 return m_modeFlags
[tileMode
].isMacro
;
3348 ***************************************************************************************************
3349 * AddrLib::IsMacro3dTiled
3352 * Check if the tile mode is 3D macro tiled
3355 * TRUE if it is 3D macro tiled
3356 ***************************************************************************************************
3358 BOOL_32
AddrLib::IsMacro3dTiled(
3359 AddrTileMode tileMode
) ///< [in] tile mode
3361 return m_modeFlags
[tileMode
].isMacro3d
;
3365 ***************************************************************************************************
3366 * AddrLib::IsMicroTiled
3369 * Check if the tile mode is micro tiled
3372 * TRUE if micro tiled
3373 ***************************************************************************************************
3375 BOOL_32
AddrLib::IsMicroTiled(
3376 AddrTileMode tileMode
) ///< [in] tile mode
3378 return m_modeFlags
[tileMode
].isMicro
;
3382 ***************************************************************************************************
3386 * Check if the tile mode is linear
3390 ***************************************************************************************************
3392 BOOL_32
AddrLib::IsLinear(
3393 AddrTileMode tileMode
) ///< [in] tile mode
3395 return m_modeFlags
[tileMode
].isLinear
;
3399 ***************************************************************************************************
3400 * AddrLib::IsPrtNoRotationTileMode
3403 * Return TRUE if it is prt tile without rotation
3405 * This function just used by CI
3406 ***************************************************************************************************
3408 BOOL_32
AddrLib::IsPrtNoRotationTileMode(
3409 AddrTileMode tileMode
)
3411 return m_modeFlags
[tileMode
].isPrtNoRotation
;
3415 ***************************************************************************************************
3416 * AddrLib::IsPrtTileMode
3419 * Return TRUE if it is prt tile
3421 * This function just used by CI
3422 ***************************************************************************************************
3424 BOOL_32
AddrLib::IsPrtTileMode(
3425 AddrTileMode tileMode
)
3427 return m_modeFlags
[tileMode
].isPrt
;
3431 ***************************************************************************************************
3432 * AddrLib::Bits2Number
3435 * Cat a array of binary bit to a number
3438 * The number combined with the array of bits
3439 ***************************************************************************************************
3441 UINT_32
AddrLib::Bits2Number(
3442 UINT_32 bitNum
, ///< [in] how many bits
3443 ...) ///< [in] varaible bits value starting from MSB
3449 va_start(bits_ptr
, bitNum
);
3451 for(i
= 0; i
< bitNum
; i
++)
3453 number
|= va_arg(bits_ptr
, UINT_32
);
3465 ***************************************************************************************************
3466 * AddrLib::ComputeMipLevel
3469 * Compute mipmap level width/height/slices
3472 ***************************************************************************************************
3474 VOID
AddrLib::ComputeMipLevel(
3475 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
///< [in/out] Input structure
3478 if (AddrElemLib::IsBlockCompressed(pIn
->format
))
3480 if (pIn
->mipLevel
== 0)
3482 // DXTn's level 0 must be multiple of 4
3483 // But there are exceptions:
3484 // 1. Internal surface creation in hostblt/vsblt/etc...
3485 // 2. Runtime doesn't reject ATI1/ATI2 whose width/height are not multiple of 4
3486 pIn
->width
= PowTwoAlign(pIn
->width
, 4);
3487 pIn
->height
= PowTwoAlign(pIn
->height
, 4);
3491 HwlComputeMipLevel(pIn
);
3495 ***************************************************************************************************
3496 * AddrLib::DegradeBaseLevel
3499 * Check if base level's tile mode can be degraded
3501 * TRUE if degraded, also returns degraded tile mode (unchanged if not degraded)
3502 ***************************************************************************************************
3504 BOOL_32
AddrLib::DegradeBaseLevel(
3505 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure for surface info
3506 AddrTileMode
* pTileMode
///< [out] Degraded tile mode
3509 BOOL_32 degraded
= FALSE
;
3510 AddrTileMode tileMode
= pIn
->tileMode
;
3511 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
3513 if (m_configFlags
.degradeBaseLevel
) // This is a global setting
3515 if (pIn
->flags
.degrade4Space
&& // Degradation per surface
3516 pIn
->mipLevel
== 0 &&
3517 pIn
->numSamples
== 1 &&
3518 IsMacroTiled(tileMode
))
3520 if (HwlDegradeBaseLevel(pIn
))
3522 *pTileMode
= thickness
== 1 ? ADDR_TM_1D_TILED_THIN1
: ADDR_TM_1D_TILED_THICK
;
3525 else if (thickness
> 1)
3527 // As in the following HwlComputeSurfaceInfo, thick modes may be degraded to
3528 // thinner modes, we should re-evaluate whether the corresponding thinner modes
3529 // need to be degraded. If so, we choose 1D thick mode instead.
3530 tileMode
= DegradeLargeThickTile(pIn
->tileMode
, pIn
->bpp
);
3531 if (tileMode
!= pIn
->tileMode
)
3533 ADDR_COMPUTE_SURFACE_INFO_INPUT input
= *pIn
;
3534 input
.tileMode
= tileMode
;
3535 if (HwlDegradeBaseLevel(&input
))
3537 *pTileMode
= ADDR_TM_1D_TILED_THICK
;
3549 ***************************************************************************************************
3550 * AddrLib::DegradeLargeThickTile
3553 * Check if the thickness needs to be reduced if a tile is too large
3555 * The degraded tile mode (unchanged if not degraded)
3556 ***************************************************************************************************
3558 AddrTileMode
AddrLib::DegradeLargeThickTile(
3559 AddrTileMode tileMode
,
3562 // Override tilemode
3563 // When tile_width (8) * tile_height (8) * thickness * element_bytes is > row_size,
3564 // it is better to just use THIN mode in this case
3565 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
3567 if (thickness
> 1 && m_configFlags
.allowLargeThickTile
== 0)
3569 UINT_32 tileSize
= MicroTilePixels
* thickness
* (bpp
>> 3);
3571 if (tileSize
> m_rowSize
)
3575 case ADDR_TM_2D_TILED_XTHICK
:
3576 if ((tileSize
>> 1) <= m_rowSize
)
3578 tileMode
= ADDR_TM_2D_TILED_THICK
;
3581 // else fall through
3582 case ADDR_TM_2D_TILED_THICK
:
3583 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3586 case ADDR_TM_3D_TILED_XTHICK
:
3587 if ((tileSize
>> 1) <= m_rowSize
)
3589 tileMode
= ADDR_TM_3D_TILED_THICK
;
3592 // else fall through
3593 case ADDR_TM_3D_TILED_THICK
:
3594 tileMode
= ADDR_TM_3D_TILED_THIN1
;
3597 case ADDR_TM_PRT_TILED_THICK
:
3598 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
3601 case ADDR_TM_PRT_2D_TILED_THICK
:
3602 tileMode
= ADDR_TM_PRT_2D_TILED_THIN1
;
3605 case ADDR_TM_PRT_3D_TILED_THICK
:
3606 tileMode
= ADDR_TM_PRT_3D_TILED_THIN1
;
3619 ***************************************************************************************************
3620 * AddrLib::PostComputeMipLevel
3622 * Compute MipLevel info (including level 0) after surface adjustment
3625 ***************************************************************************************************
3627 ADDR_E_RETURNCODE
AddrLib::PostComputeMipLevel(
3628 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in/out] Input structure
3629 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] Output structure
3632 // Mipmap including level 0 must be pow2 padded since either SI hw expects so or it is
3633 // required by CFX for Hw Compatibility between NI and SI. Otherwise it is only needed for
3634 // mipLevel > 0. Any h/w has different requirement should implement its own virtual function
3636 if (pIn
->flags
.pow2Pad
)
3638 pIn
->width
= NextPow2(pIn
->width
);
3639 pIn
->height
= NextPow2(pIn
->height
);
3640 pIn
->numSlices
= NextPow2(pIn
->numSlices
);
3642 else if (pIn
->mipLevel
> 0)
3644 pIn
->width
= NextPow2(pIn
->width
);
3645 pIn
->height
= NextPow2(pIn
->height
);
3647 if (!pIn
->flags
.cube
)
3649 pIn
->numSlices
= NextPow2(pIn
->numSlices
);
3652 // for cubemap, we keep its value at first
3659 ***************************************************************************************************
3660 * AddrLib::HwlSetupTileCfg
3663 * Map tile index to tile setting.
3666 ***************************************************************************************************
3668 ADDR_E_RETURNCODE
AddrLib::HwlSetupTileCfg(
3669 INT_32 index
, ///< [in] Tile index
3670 INT_32 macroModeIndex
, ///< [in] Index in macro tile mode table(CI)
3671 ADDR_TILEINFO
* pInfo
, ///< [out] Tile Info
3672 AddrTileMode
* pMode
, ///< [out] Tile mode
3673 AddrTileType
* pType
///< [out] Tile type
3676 return ADDR_NOTSUPPORTED
;
3680 ***************************************************************************************************
3681 * AddrLib::HwlGetPipes
3687 ***************************************************************************************************
3689 UINT_32
AddrLib::HwlGetPipes(
3690 const ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
3693 //pTileInfo can be NULL when asic is 6xx and 8xx.
3698 ***************************************************************************************************
3699 * AddrLib::ComputeQbStereoInfo
3702 * Get quad buffer stereo information
3705 ***************************************************************************************************
3707 BOOL_32
AddrLib::ComputeQbStereoInfo(
3708 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in/out] updated pOut+pStereoInfo
3711 BOOL_32 success
= FALSE
;
3713 if (pOut
->pStereoInfo
)
3715 ADDR_ASSERT(pOut
->bpp
>= 8);
3716 ADDR_ASSERT((pOut
->surfSize
% pOut
->baseAlign
) == 0);
3718 // Save original height
3719 pOut
->pStereoInfo
->eyeHeight
= pOut
->height
;
3722 pOut
->pStereoInfo
->rightOffset
= static_cast<UINT_32
>(pOut
->surfSize
);
3724 pOut
->pStereoInfo
->rightSwizzle
= HwlComputeQbStereoRightSwizzle(pOut
);
3727 pOut
->pixelHeight
<<= 1;
3730 pOut
->surfSize
<<= 1;
3732 // Right start address meets the base align since it is guaranteed by AddrLib
3734 // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo.
3741 ///////////////////////////////////////////////////////////////////////////////////////////////////
3743 ///////////////////////////////////////////////////////////////////////////////////////////////////
3747 ***************************************************************************************************
3748 * AddrLib::Flt32ToColorPixel
3751 * Convert a FLT_32 value to a depth/stencil pixel value
3754 ***************************************************************************************************
3756 ADDR_E_RETURNCODE
AddrLib::Flt32ToDepthPixel(
3757 const ELEM_FLT32TODEPTHPIXEL_INPUT
* pIn
,
3758 ELEM_FLT32TODEPTHPIXEL_OUTPUT
* pOut
) const
3760 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
3762 if (GetFillSizeFieldsFlags() == TRUE
)
3764 if ((pIn
->size
!= sizeof(ELEM_FLT32TODEPTHPIXEL_INPUT
)) ||
3765 (pOut
->size
!= sizeof(ELEM_FLT32TODEPTHPIXEL_OUTPUT
)))
3767 returnCode
= ADDR_PARAMSIZEMISMATCH
;
3771 if (returnCode
== ADDR_OK
)
3773 GetElemLib()->Flt32ToDepthPixel(pIn
->format
,
3776 UINT_32 depthBase
= 0;
3777 UINT_32 stencilBase
= 0;
3778 UINT_32 depthBits
= 0;
3779 UINT_32 stencilBits
= 0;
3781 switch (pIn
->format
)
3786 case ADDR_DEPTH_X8_24
:
3787 case ADDR_DEPTH_8_24
:
3788 case ADDR_DEPTH_X8_24_FLOAT
:
3789 case ADDR_DEPTH_8_24_FLOAT
:
3794 case ADDR_DEPTH_32_FLOAT
:
3797 case ADDR_DEPTH_X24_8_32_FLOAT
:
3806 // Overwrite base since R800 has no "tileBase"
3807 if (GetElemLib()->IsDepthStencilTilePlanar() == FALSE
)
3816 pOut
->stencilBase
= stencilBase
;
3817 pOut
->depthBase
= depthBase
;
3818 pOut
->depthBits
= depthBits
;
3819 pOut
->stencilBits
= stencilBits
;
3826 ***************************************************************************************************
3827 * AddrLib::Flt32ToColorPixel
3830 * Convert a FLT_32 value to a red/green/blue/alpha pixel value
3833 ***************************************************************************************************
3835 ADDR_E_RETURNCODE
AddrLib::Flt32ToColorPixel(
3836 const ELEM_FLT32TOCOLORPIXEL_INPUT
* pIn
,
3837 ELEM_FLT32TOCOLORPIXEL_OUTPUT
* pOut
) const
3839 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
3841 if (GetFillSizeFieldsFlags() == TRUE
)
3843 if ((pIn
->size
!= sizeof(ELEM_FLT32TOCOLORPIXEL_INPUT
)) ||
3844 (pOut
->size
!= sizeof(ELEM_FLT32TOCOLORPIXEL_OUTPUT
)))
3846 returnCode
= ADDR_PARAMSIZEMISMATCH
;
3850 if (returnCode
== ADDR_OK
)
3852 GetElemLib()->Flt32ToColorPixel(pIn
->format
,
3864 ***************************************************************************************************
3865 * AddrLib::GetExportNorm
3868 * Check one format can be EXPORT_NUM
3870 * TRUE if EXPORT_NORM can be used
3871 ***************************************************************************************************
3873 BOOL_32
AddrLib::GetExportNorm(
3874 const ELEM_GETEXPORTNORM_INPUT
* pIn
) const
3876 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
3878 BOOL_32 enabled
= FALSE
;
3880 if (GetFillSizeFieldsFlags() == TRUE
)
3882 if (pIn
->size
!= sizeof(ELEM_GETEXPORTNORM_INPUT
))
3884 returnCode
= ADDR_PARAMSIZEMISMATCH
;
3888 if (returnCode
== ADDR_OK
)
3890 enabled
= GetElemLib()->PixGetExportNorm(pIn
->format
,
3899 ***************************************************************************************************
3900 * AddrLib::ComputePrtInfo
3903 * Compute prt surface related info
3907 ***************************************************************************************************
3909 ADDR_E_RETURNCODE
AddrLib::ComputePrtInfo(
3910 const ADDR_PRT_INFO_INPUT
* pIn
,
3911 ADDR_PRT_INFO_OUTPUT
* pOut
) const
3913 ADDR_ASSERT(pOut
!= NULL
);
3915 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
3917 UINT_32 expandX
= 1;
3918 UINT_32 expandY
= 1;
3919 AddrElemMode elemMode
;
3921 UINT_32 bpp
= GetElemLib()->GetBitsPerPixel(pIn
->format
,
3926 if (bpp
<8 || bpp
== 24 || bpp
== 48 || bpp
== 96 )
3928 returnCode
= ADDR_INVALIDPARAMS
;
3931 UINT_32 numFrags
= pIn
->numFrags
;
3932 ADDR_ASSERT(numFrags
<= 8);
3934 UINT_32 tileWidth
= 0;
3935 UINT_32 tileHeight
= 0;
3936 if (returnCode
== ADDR_OK
)
3938 // 3D texture without depth or 2d texture
3939 if (pIn
->baseMipDepth
> 1 || pIn
->baseMipHeight
> 1)
3958 // assume it is BC1/4
3962 if (elemMode
== ADDR_UNCOMPRESSED
)
3968 else if (bpp
== 128)
3970 // assume it is BC2/3/5/6H/7
3974 if (elemMode
== ADDR_UNCOMPRESSED
)
3983 tileWidth
= tileWidth
/ 2;
3985 else if (numFrags
== 4)
3987 tileWidth
= tileWidth
/ 2;
3988 tileHeight
= tileHeight
/ 2;
3990 else if (numFrags
== 8)
3992 tileWidth
= tileWidth
/ 4;
3993 tileHeight
= tileHeight
/ 2;
4015 else if (bpp
== 128)
4022 pOut
->prtTileWidth
= tileWidth
;
4023 pOut
->prtTileHeight
= tileHeight
;