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
27 #include "addrinterface.h"
29 #include "addrcommon.h"
32 ///////////////////////////////////////////////////////////////////////////////////////////////////
33 // Static Const Member
34 ///////////////////////////////////////////////////////////////////////////////////////////////////
36 const AddrTileModeFlags
AddrLib::m_modeFlags
[ADDR_TM_COUNT
] =
38 {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_GENERAL
39 {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_ALIGNED
40 {1, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THIN1
41 {4, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THICK
42 {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN1
43 {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN2
44 {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN4
45 {4, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THICK
46 {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN1
47 {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN2
48 {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN4
49 {4, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THICK
50 {1, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THIN1
51 {4, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THICK
52 {1, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THIN1
53 {4, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THICK
54 {8, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_XTHICK
55 {8, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_XTHICK
56 {1, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_POWER_SAVE
57 {1, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THIN1
58 {1, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THIN1
59 {1, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THIN1
60 {4, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THICK
61 {4, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THICK
62 {4, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THICK
66 ///////////////////////////////////////////////////////////////////////////////////////////////////
68 ///////////////////////////////////////////////////////////////////////////////////////////////////
72 ***************************************************************************************************
73 * AddrLib::ComputeSurfaceInfo
76 * Interface function stub of AddrComputeSurfaceInfo.
80 ***************************************************************************************************
82 ADDR_E_RETURNCODE
AddrLib::ComputeSurfaceInfo(
83 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
84 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
87 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
89 if (GetFillSizeFieldsFlags() == TRUE
)
91 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT
)) ||
92 (pOut
->size
!= sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT
)))
94 returnCode
= ADDR_PARAMSIZEMISMATCH
;
98 // We suggest client do sanity check but a check here is also good
101 returnCode
= ADDR_INVALIDPARAMS
;
104 // Thick modes don't support multisample
105 if (ComputeSurfaceThickness(pIn
->tileMode
) > 1 && pIn
->numSamples
> 1)
107 returnCode
= ADDR_INVALIDPARAMS
;
110 if (returnCode
== ADDR_OK
)
112 // Get a local copy of input structure and only reference pIn for unadjusted values
113 ADDR_COMPUTE_SURFACE_INFO_INPUT localIn
= *pIn
;
114 ADDR_TILEINFO tileInfoNull
= {0};
118 // If the original input has a valid ADDR_TILEINFO pointer then copy its contents.
119 // Otherwise the default 0's in tileInfoNull are used.
122 tileInfoNull
= *pIn
->pTileInfo
;
124 localIn
.pTileInfo
= &tileInfoNull
;
127 localIn
.numSamples
= pIn
->numSamples
== 0 ? 1 : pIn
->numSamples
;
129 // Do mipmap check first
130 // If format is BCn, pre-pad dimension to power-of-two according to HWL
131 ComputeMipLevel(&localIn
);
133 if (m_configFlags
.checkLast2DLevel
)
135 // Save this level's original height in pixels
136 pOut
->height
= pIn
->height
;
141 AddrElemMode elemMode
;
143 // Save outputs that may not go through HWL
144 pOut
->pixelBits
= localIn
.bpp
;
145 pOut
->numSamples
= localIn
.numSamples
;
146 pOut
->last2DLevel
= FALSE
;
147 pOut
->tcCompatible
= FALSE
;
150 if (localIn
.numSamples
> 1)
152 ADDR_ASSERT(localIn
.mipLevel
== 0);
156 if (localIn
.format
!= ADDR_FMT_INVALID
) // Set format to INVALID will skip this conversion
158 // Get compression/expansion factors and element mode
159 // (which indicates compression/expansion
160 localIn
.bpp
= GetElemLib()->GetBitsPerPixel(localIn
.format
,
165 // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
166 // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
167 // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
168 // restrictions are different.
169 // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
170 // but we use this flag to skip RestoreSurfaceInfo below
172 if ((elemMode
== ADDR_EXPANDED
) &&
175 ADDR_ASSERT(localIn
.tileMode
== ADDR_TM_LINEAR_ALIGNED
|| localIn
.height
== 1);
178 GetElemLib()->AdjustSurfaceInfo(elemMode
,
186 // Overwrite these parameters if we have a valid format
188 else if (localIn
.bpp
!= 0)
190 localIn
.width
= (localIn
.width
!= 0) ? localIn
.width
: 1;
191 localIn
.height
= (localIn
.height
!= 0) ? localIn
.height
: 1;
193 else // Rule out some invalid parameters
195 ADDR_ASSERT_ALWAYS();
197 returnCode
= ADDR_INVALIDPARAMS
;
200 // Check mipmap after surface expansion
201 if (returnCode
== ADDR_OK
)
203 returnCode
= PostComputeMipLevel(&localIn
, pOut
);
206 if (returnCode
== ADDR_OK
)
208 if (UseTileIndex(localIn
.tileIndex
))
210 // Make sure pTileInfo is not NULL
211 ADDR_ASSERT(localIn
.pTileInfo
);
213 UINT_32 numSamples
= GetNumFragments(localIn
.numSamples
, localIn
.numFrags
);
215 INT_32 macroModeIndex
= TileIndexNoMacroIndex
;
217 if (localIn
.tileIndex
!= TileIndexLinearGeneral
)
219 // Try finding a macroModeIndex
220 macroModeIndex
= HwlComputeMacroModeIndex(localIn
.tileIndex
,
229 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
230 if (macroModeIndex
== TileIndexNoMacroIndex
)
232 returnCode
= HwlSetupTileCfg(localIn
.tileIndex
, macroModeIndex
,
234 &localIn
.tileMode
, &localIn
.tileType
);
236 // If macroModeIndex is invalid, then assert this is not macro tiled
237 else if (macroModeIndex
== TileIndexInvalid
)
239 ADDR_ASSERT(!IsMacroTiled(localIn
.tileMode
));
242 pOut
->macroModeIndex
= macroModeIndex
;
246 if (returnCode
== ADDR_OK
)
248 AddrTileMode tileMode
= localIn
.tileMode
;
249 AddrTileType tileType
= localIn
.tileType
;
251 // HWL layer may override tile mode if necessary
252 if (HwlOverrideTileMode(&localIn
, &tileMode
, &tileType
))
254 localIn
.tileMode
= tileMode
;
255 localIn
.tileType
= tileType
;
257 // Optimize tile mode if possible
258 if (OptimizeTileMode(&localIn
, &tileMode
))
260 localIn
.tileMode
= tileMode
;
264 // Call main function to compute surface info
265 if (returnCode
== ADDR_OK
)
267 returnCode
= HwlComputeSurfaceInfo(&localIn
, pOut
);
270 if (returnCode
== ADDR_OK
)
272 // Since bpp might be changed we just pass it through
273 pOut
->bpp
= localIn
.bpp
;
275 // Also original width/height/bpp
276 pOut
->pixelPitch
= pOut
->pitch
;
277 pOut
->pixelHeight
= pOut
->height
;
280 if (localIn
.flags
.display
)
282 ADDR_ASSERT((pOut
->pitchAlign
% 32) == 0);
286 if (localIn
.format
!= ADDR_FMT_INVALID
)
289 // 96 bits surface of level 1+ requires element pitch of 32 bits instead
290 // In hwl function we skip multiplication of 3 then we should skip division of 3
291 // We keep pitch that represents 32 bit element instead of 96 bits since we
292 // will get an odd number if divided by 3.
294 if (!((expandX
== 3) && (localIn
.mipLevel
> 0)))
297 GetElemLib()->RestoreSurfaceInfo(elemMode
,
306 if (localIn
.flags
.qbStereo
)
308 if (pOut
->pStereoInfo
)
310 ComputeQbStereoInfo(pOut
);
314 if (localIn
.flags
.volume
) // For volume sliceSize equals to all z-slices
316 pOut
->sliceSize
= pOut
->surfSize
;
318 else // For array: sliceSize is likely to have slice-padding (the last one)
320 pOut
->sliceSize
= pOut
->surfSize
/ pOut
->depth
;
323 if (pIn
->numSlices
> 1)
325 // If this is the last slice then add the padding size to this slice
326 if (pIn
->slice
== (pIn
->numSlices
- 1))
328 pOut
->sliceSize
+= pOut
->sliceSize
* (pOut
->depth
- pIn
->numSlices
);
330 else if (m_configFlags
.checkLast2DLevel
)
332 // Reset last2DLevel flag if this is not the last array slice
333 pOut
->last2DLevel
= FALSE
;
338 pOut
->pitchTileMax
= pOut
->pitch
/ 8 - 1;
339 pOut
->heightTileMax
= pOut
->height
/ 8 - 1;
340 pOut
->sliceTileMax
= pOut
->pitch
* pOut
->height
/ 64 - 1;
348 ***************************************************************************************************
349 * AddrLib::ComputeSurfaceInfo
352 * Interface function stub of AddrComputeSurfaceInfo.
356 ***************************************************************************************************
358 ADDR_E_RETURNCODE
AddrLib::ComputeSurfaceAddrFromCoord(
359 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
360 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
363 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
365 if (GetFillSizeFieldsFlags() == TRUE
)
367 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
)) ||
368 (pOut
->size
!= sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
)))
370 returnCode
= ADDR_PARAMSIZEMISMATCH
;
374 if (returnCode
== ADDR_OK
)
376 ADDR_TILEINFO tileInfoNull
;
377 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT input
;
379 if (UseTileIndex(pIn
->tileIndex
))
382 // Use temp tile info for calcalation
383 input
.pTileInfo
= &tileInfoNull
;
385 const ADDR_SURFACE_FLAGS flags
= {{0}};
386 UINT_32 numSamples
= GetNumFragments(pIn
->numSamples
, pIn
->numFrags
);
388 // Try finding a macroModeIndex
389 INT_32 macroModeIndex
= HwlComputeMacroModeIndex(input
.tileIndex
,
397 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
398 if (macroModeIndex
== TileIndexNoMacroIndex
)
400 returnCode
= HwlSetupTileCfg(input
.tileIndex
, macroModeIndex
,
401 input
.pTileInfo
, &input
.tileMode
, &input
.tileType
);
403 // If macroModeIndex is invalid, then assert this is not macro tiled
404 else if (macroModeIndex
== TileIndexInvalid
)
406 ADDR_ASSERT(!IsMacroTiled(input
.tileMode
));
409 // Change the input structure
413 if (returnCode
== ADDR_OK
)
415 returnCode
= HwlComputeSurfaceAddrFromCoord(pIn
, pOut
);
417 if (returnCode
== ADDR_OK
)
419 pOut
->prtBlockIndex
= static_cast<UINT_32
>(pOut
->addr
/ (64 * 1024));
428 ***************************************************************************************************
429 * AddrLib::ComputeSurfaceCoordFromAddr
432 * Interface function stub of ComputeSurfaceCoordFromAddr.
436 ***************************************************************************************************
438 ADDR_E_RETURNCODE
AddrLib::ComputeSurfaceCoordFromAddr(
439 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
440 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
443 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
445 if (GetFillSizeFieldsFlags() == TRUE
)
447 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
)) ||
448 (pOut
->size
!= sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
)))
450 returnCode
= ADDR_PARAMSIZEMISMATCH
;
454 if (returnCode
== ADDR_OK
)
456 ADDR_TILEINFO tileInfoNull
;
457 ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT input
;
459 if (UseTileIndex(pIn
->tileIndex
))
462 // Use temp tile info for calcalation
463 input
.pTileInfo
= &tileInfoNull
;
465 const ADDR_SURFACE_FLAGS flags
= {{0}};
466 UINT_32 numSamples
= GetNumFragments(pIn
->numSamples
, pIn
->numFrags
);
468 // Try finding a macroModeIndex
469 INT_32 macroModeIndex
= HwlComputeMacroModeIndex(input
.tileIndex
,
477 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
478 if (macroModeIndex
== TileIndexNoMacroIndex
)
480 returnCode
= HwlSetupTileCfg(input
.tileIndex
, macroModeIndex
,
481 input
.pTileInfo
, &input
.tileMode
, &input
.tileType
);
483 // If macroModeIndex is invalid, then assert this is not macro tiled
484 else if (macroModeIndex
== TileIndexInvalid
)
486 ADDR_ASSERT(!IsMacroTiled(input
.tileMode
));
489 // Change the input structure
493 if (returnCode
== ADDR_OK
)
495 returnCode
= HwlComputeSurfaceCoordFromAddr(pIn
, pOut
);
503 ***************************************************************************************************
504 * AddrLib::ComputeSliceTileSwizzle
507 * Interface function stub of ComputeSliceTileSwizzle.
511 ***************************************************************************************************
513 ADDR_E_RETURNCODE
AddrLib::ComputeSliceTileSwizzle(
514 const ADDR_COMPUTE_SLICESWIZZLE_INPUT
* pIn
, ///< [in] input structure
515 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
* pOut
///< [out] output structure
518 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
520 if (GetFillSizeFieldsFlags() == TRUE
)
522 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_SLICESWIZZLE_INPUT
)) ||
523 (pOut
->size
!= sizeof(ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
)))
525 returnCode
= ADDR_PARAMSIZEMISMATCH
;
529 if (returnCode
== ADDR_OK
)
531 ADDR_TILEINFO tileInfoNull
;
532 ADDR_COMPUTE_SLICESWIZZLE_INPUT input
;
534 if (UseTileIndex(pIn
->tileIndex
))
537 // Use temp tile info for calcalation
538 input
.pTileInfo
= &tileInfoNull
;
540 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
,
541 input
.pTileInfo
, &input
.tileMode
);
542 // Change the input structure
546 if (returnCode
== ADDR_OK
)
548 returnCode
= HwlComputeSliceTileSwizzle(pIn
, pOut
);
556 ***************************************************************************************************
557 * AddrLib::ExtractBankPipeSwizzle
560 * Interface function stub of AddrExtractBankPipeSwizzle.
564 ***************************************************************************************************
566 ADDR_E_RETURNCODE
AddrLib::ExtractBankPipeSwizzle(
567 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
568 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
571 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
573 if (GetFillSizeFieldsFlags() == TRUE
)
575 if ((pIn
->size
!= sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
)) ||
576 (pOut
->size
!= sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
)))
578 returnCode
= ADDR_PARAMSIZEMISMATCH
;
582 if (returnCode
== ADDR_OK
)
584 ADDR_TILEINFO tileInfoNull
;
585 ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT input
;
587 if (UseTileIndex(pIn
->tileIndex
))
590 // Use temp tile info for calcalation
591 input
.pTileInfo
= &tileInfoNull
;
593 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
594 // Change the input structure
598 if (returnCode
== ADDR_OK
)
600 returnCode
= HwlExtractBankPipeSwizzle(pIn
, pOut
);
608 ***************************************************************************************************
609 * AddrLib::CombineBankPipeSwizzle
612 * Interface function stub of AddrCombineBankPipeSwizzle.
616 ***************************************************************************************************
618 ADDR_E_RETURNCODE
AddrLib::CombineBankPipeSwizzle(
619 const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
620 ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
623 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
625 if (GetFillSizeFieldsFlags() == TRUE
)
627 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT
)) ||
628 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT
)))
630 returnCode
= ADDR_PARAMSIZEMISMATCH
;
634 if (returnCode
== ADDR_OK
)
636 ADDR_TILEINFO tileInfoNull
;
637 ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT input
;
639 if (UseTileIndex(pIn
->tileIndex
))
642 // Use temp tile info for calcalation
643 input
.pTileInfo
= &tileInfoNull
;
645 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
646 // Change the input structure
650 if (returnCode
== ADDR_OK
)
652 returnCode
= HwlCombineBankPipeSwizzle(pIn
->bankSwizzle
,
664 ***************************************************************************************************
665 * AddrLib::ComputeBaseSwizzle
668 * Interface function stub of AddrCompueBaseSwizzle.
671 ***************************************************************************************************
673 ADDR_E_RETURNCODE
AddrLib::ComputeBaseSwizzle(
674 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT
* pIn
,
675 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
* pOut
) const
677 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
679 if (GetFillSizeFieldsFlags() == TRUE
)
681 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT
)) ||
682 (pOut
->size
!= sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
)))
684 returnCode
= ADDR_PARAMSIZEMISMATCH
;
688 if (returnCode
== ADDR_OK
)
690 ADDR_TILEINFO tileInfoNull
;
691 ADDR_COMPUTE_BASE_SWIZZLE_INPUT input
;
693 if (UseTileIndex(pIn
->tileIndex
))
696 // Use temp tile info for calcalation
697 input
.pTileInfo
= &tileInfoNull
;
699 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
700 // Change the input structure
704 if (returnCode
== ADDR_OK
)
706 if (IsMacroTiled(pIn
->tileMode
))
708 returnCode
= HwlComputeBaseSwizzle(pIn
, pOut
);
712 pOut
->tileSwizzle
= 0;
721 ***************************************************************************************************
722 * AddrLib::ComputeFmaskInfo
725 * Interface function stub of ComputeFmaskInfo.
729 ***************************************************************************************************
731 ADDR_E_RETURNCODE
AddrLib::ComputeFmaskInfo(
732 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
733 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
736 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
738 if (GetFillSizeFieldsFlags() == TRUE
)
740 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT
)) ||
741 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT
)))
743 returnCode
= ADDR_PARAMSIZEMISMATCH
;
748 if (ComputeSurfaceThickness(pIn
->tileMode
) > 1)
750 returnCode
= ADDR_INVALIDPARAMS
;
753 if (returnCode
== ADDR_OK
)
755 ADDR_TILEINFO tileInfoNull
;
756 ADDR_COMPUTE_FMASK_INFO_INPUT input
;
758 if (UseTileIndex(pIn
->tileIndex
))
764 // Use temp tile info for calcalation
765 input
.pTileInfo
= pOut
->pTileInfo
;
769 input
.pTileInfo
= &tileInfoNull
;
772 ADDR_SURFACE_FLAGS flags
= {{0}};
775 // Try finding a macroModeIndex
776 INT_32 macroModeIndex
= HwlComputeMacroModeIndex(pIn
->tileIndex
,
778 HwlComputeFmaskBits(pIn
, NULL
),
783 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
784 if (macroModeIndex
== TileIndexNoMacroIndex
)
786 returnCode
= HwlSetupTileCfg(input
.tileIndex
, macroModeIndex
,
787 input
.pTileInfo
, &input
.tileMode
);
790 ADDR_ASSERT(macroModeIndex
!= TileIndexInvalid
);
792 // Change the input structure
796 if (returnCode
== ADDR_OK
)
798 if (pIn
->numSamples
> 1)
800 returnCode
= HwlComputeFmaskInfo(pIn
, pOut
);
804 memset(pOut
, 0, sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT
));
806 returnCode
= ADDR_INVALIDPARAMS
;
815 ***************************************************************************************************
816 * AddrLib::ComputeFmaskAddrFromCoord
819 * Interface function stub of ComputeFmaskAddrFromCoord.
823 ***************************************************************************************************
825 ADDR_E_RETURNCODE
AddrLib::ComputeFmaskAddrFromCoord(
826 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
827 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
830 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
832 if (GetFillSizeFieldsFlags() == TRUE
)
834 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
)) ||
835 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
)))
837 returnCode
= ADDR_PARAMSIZEMISMATCH
;
841 if (returnCode
== ADDR_OK
)
843 ADDR_ASSERT(pIn
->numSamples
> 1);
845 if (pIn
->numSamples
> 1)
847 returnCode
= HwlComputeFmaskAddrFromCoord(pIn
, pOut
);
851 returnCode
= ADDR_INVALIDPARAMS
;
859 ***************************************************************************************************
860 * AddrLib::ComputeFmaskCoordFromAddr
863 * Interface function stub of ComputeFmaskAddrFromCoord.
867 ***************************************************************************************************
869 ADDR_E_RETURNCODE
AddrLib::ComputeFmaskCoordFromAddr(
870 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
871 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
874 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
876 if (GetFillSizeFieldsFlags() == TRUE
)
878 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
)) ||
879 (pOut
->size
!= sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
)))
881 returnCode
= ADDR_PARAMSIZEMISMATCH
;
885 if (returnCode
== ADDR_OK
)
887 ADDR_ASSERT(pIn
->numSamples
> 1);
889 if (pIn
->numSamples
> 1)
891 returnCode
= HwlComputeFmaskCoordFromAddr(pIn
, pOut
);
895 returnCode
= ADDR_INVALIDPARAMS
;
903 ***************************************************************************************************
904 * AddrLib::ConvertTileInfoToHW
907 * Convert tile info from real value to HW register value in HW layer
911 ***************************************************************************************************
913 ADDR_E_RETURNCODE
AddrLib::ConvertTileInfoToHW(
914 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
915 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
918 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
920 if (GetFillSizeFieldsFlags() == TRUE
)
922 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT
)) ||
923 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT
)))
925 returnCode
= ADDR_PARAMSIZEMISMATCH
;
929 if (returnCode
== ADDR_OK
)
931 ADDR_TILEINFO tileInfoNull
;
932 ADDR_CONVERT_TILEINFOTOHW_INPUT input
;
933 // if pIn->reverse is TRUE, indices are ignored
934 if (pIn
->reverse
== FALSE
&& UseTileIndex(pIn
->tileIndex
))
937 input
.pTileInfo
= &tileInfoNull
;
939 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
944 if (returnCode
== ADDR_OK
)
946 returnCode
= HwlConvertTileInfoToHW(pIn
, pOut
);
954 ***************************************************************************************************
955 * AddrLib::ConvertTileIndex
958 * Convert tile index to tile mode/type/info
962 ***************************************************************************************************
964 ADDR_E_RETURNCODE
AddrLib::ConvertTileIndex(
965 const ADDR_CONVERT_TILEINDEX_INPUT
* pIn
, ///< [in] input structure
966 ADDR_CONVERT_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
969 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
971 if (GetFillSizeFieldsFlags() == TRUE
)
973 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_INPUT
)) ||
974 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT
)))
976 returnCode
= ADDR_PARAMSIZEMISMATCH
;
980 if (returnCode
== ADDR_OK
)
983 returnCode
= HwlSetupTileCfg(pIn
->tileIndex
, pIn
->macroModeIndex
,
984 pOut
->pTileInfo
, &pOut
->tileMode
, &pOut
->tileType
);
986 if (returnCode
== ADDR_OK
&& pIn
->tileInfoHw
)
988 ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput
= {0};
989 ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput
= {0};
991 hwInput
.pTileInfo
= pOut
->pTileInfo
;
992 hwInput
.tileIndex
= -1;
993 hwOutput
.pTileInfo
= pOut
->pTileInfo
;
995 returnCode
= HwlConvertTileInfoToHW(&hwInput
, &hwOutput
);
1003 ***************************************************************************************************
1004 * AddrLib::ConvertTileIndex1
1007 * Convert tile index to tile mode/type/info
1011 ***************************************************************************************************
1013 ADDR_E_RETURNCODE
AddrLib::ConvertTileIndex1(
1014 const ADDR_CONVERT_TILEINDEX1_INPUT
* pIn
, ///< [in] input structure
1015 ADDR_CONVERT_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1018 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1020 if (GetFillSizeFieldsFlags() == TRUE
)
1022 if ((pIn
->size
!= sizeof(ADDR_CONVERT_TILEINDEX1_INPUT
)) ||
1023 (pOut
->size
!= sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT
)))
1025 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1029 if (returnCode
== ADDR_OK
)
1031 ADDR_SURFACE_FLAGS flags
= {{0}};
1033 HwlComputeMacroModeIndex(pIn
->tileIndex
, flags
, pIn
->bpp
, pIn
->numSamples
,
1034 pOut
->pTileInfo
, &pOut
->tileMode
, &pOut
->tileType
);
1036 if (pIn
->tileInfoHw
)
1038 ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput
= {0};
1039 ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput
= {0};
1041 hwInput
.pTileInfo
= pOut
->pTileInfo
;
1042 hwInput
.tileIndex
= -1;
1043 hwOutput
.pTileInfo
= pOut
->pTileInfo
;
1045 returnCode
= HwlConvertTileInfoToHW(&hwInput
, &hwOutput
);
1053 ***************************************************************************************************
1054 * AddrLib::GetTileIndex
1057 * Get tile index from tile mode/type/info
1061 ***************************************************************************************************
1063 ADDR_E_RETURNCODE
AddrLib::GetTileIndex(
1064 const ADDR_GET_TILEINDEX_INPUT
* pIn
, ///< [in] input structure
1065 ADDR_GET_TILEINDEX_OUTPUT
* pOut
///< [out] output structure
1068 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1070 if (GetFillSizeFieldsFlags() == TRUE
)
1072 if ((pIn
->size
!= sizeof(ADDR_GET_TILEINDEX_INPUT
)) ||
1073 (pOut
->size
!= sizeof(ADDR_GET_TILEINDEX_OUTPUT
)))
1075 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1079 if (returnCode
== ADDR_OK
)
1081 returnCode
= HwlGetTileIndex(pIn
, pOut
);
1088 ***************************************************************************************************
1089 * AddrLib::ComputeSurfaceThickness
1092 * Compute surface thickness
1096 ***************************************************************************************************
1098 UINT_32
AddrLib::ComputeSurfaceThickness(
1099 AddrTileMode tileMode
) ///< [in] tile mode
1101 return m_modeFlags
[tileMode
].thickness
;
1106 ///////////////////////////////////////////////////////////////////////////////////////////////////
1108 ///////////////////////////////////////////////////////////////////////////////////////////////////
1111 ***************************************************************************************************
1112 * AddrLib::ComputeHtileInfo
1115 * Interface function stub of AddrComputeHtilenfo
1119 ***************************************************************************************************
1121 ADDR_E_RETURNCODE
AddrLib::ComputeHtileInfo(
1122 const ADDR_COMPUTE_HTILE_INFO_INPUT
* pIn
, ///< [in] input structure
1123 ADDR_COMPUTE_HTILE_INFO_OUTPUT
* pOut
///< [out] output structure
1126 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1128 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1129 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1131 if (GetFillSizeFieldsFlags() == TRUE
)
1133 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT
)) ||
1134 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT
)))
1136 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1140 if (returnCode
== ADDR_OK
)
1142 ADDR_TILEINFO tileInfoNull
;
1143 ADDR_COMPUTE_HTILE_INFO_INPUT input
;
1145 if (UseTileIndex(pIn
->tileIndex
))
1148 // Use temp tile info for calcalation
1149 input
.pTileInfo
= &tileInfoNull
;
1151 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1153 // Change the input structure
1157 if (returnCode
== ADDR_OK
)
1159 pOut
->bpp
= ComputeHtileInfo(pIn
->flags
,
1181 ***************************************************************************************************
1182 * AddrLib::ComputeCmaskInfo
1185 * Interface function stub of AddrComputeCmaskInfo
1189 ***************************************************************************************************
1191 ADDR_E_RETURNCODE
AddrLib::ComputeCmaskInfo(
1192 const ADDR_COMPUTE_CMASK_INFO_INPUT
* pIn
, ///< [in] input structure
1193 ADDR_COMPUTE_CMASK_INFO_OUTPUT
* pOut
///< [out] output structure
1196 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1198 if (GetFillSizeFieldsFlags() == TRUE
)
1200 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_INFO_INPUT
)) ||
1201 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_INFO_OUTPUT
)))
1203 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1207 if (returnCode
== ADDR_OK
)
1209 ADDR_TILEINFO tileInfoNull
;
1210 ADDR_COMPUTE_CMASK_INFO_INPUT input
;
1212 if (UseTileIndex(pIn
->tileIndex
))
1215 // Use temp tile info for calcalation
1216 input
.pTileInfo
= &tileInfoNull
;
1218 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1220 // Change the input structure
1224 if (returnCode
== ADDR_OK
)
1226 returnCode
= ComputeCmaskInfo(pIn
->flags
,
1247 ***************************************************************************************************
1248 * AddrLib::ComputeDccInfo
1251 * Interface function to compute DCC key info
1254 * return code of HwlComputeDccInfo
1255 ***************************************************************************************************
1257 ADDR_E_RETURNCODE
AddrLib::ComputeDccInfo(
1258 const ADDR_COMPUTE_DCCINFO_INPUT
* pIn
, ///< [in] input structure
1259 ADDR_COMPUTE_DCCINFO_OUTPUT
* pOut
///< [out] output structure
1262 ADDR_E_RETURNCODE ret
= ADDR_OK
;
1264 if (GetFillSizeFieldsFlags() == TRUE
)
1266 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_DCCINFO_INPUT
)) ||
1267 (pOut
->size
!= sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT
)))
1269 ret
= ADDR_PARAMSIZEMISMATCH
;
1275 ADDR_COMPUTE_DCCINFO_INPUT input
;
1277 if (UseTileIndex(pIn
->tileIndex
))
1281 ret
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
,
1282 &input
.tileInfo
, &input
.tileMode
);
1289 ret
= HwlComputeDccInfo(pIn
, pOut
);
1297 ***************************************************************************************************
1298 * AddrLib::ComputeHtileAddrFromCoord
1301 * Interface function stub of AddrComputeHtileAddrFromCoord
1305 ***************************************************************************************************
1307 ADDR_E_RETURNCODE
AddrLib::ComputeHtileAddrFromCoord(
1308 const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1309 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1312 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1314 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1315 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1317 if (GetFillSizeFieldsFlags() == TRUE
)
1319 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
)) ||
1320 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
)))
1322 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1326 if (returnCode
== ADDR_OK
)
1328 ADDR_TILEINFO tileInfoNull
;
1329 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT input
;
1331 if (UseTileIndex(pIn
->tileIndex
))
1334 // Use temp tile info for calcalation
1335 input
.pTileInfo
= &tileInfoNull
;
1337 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1339 // Change the input structure
1343 if (returnCode
== ADDR_OK
)
1345 pOut
->addr
= HwlComputeXmaskAddrFromCoord(pIn
->pitch
,
1356 &pOut
->bitPosition
);
1365 ***************************************************************************************************
1366 * AddrLib::ComputeHtileCoordFromAddr
1369 * Interface function stub of AddrComputeHtileCoordFromAddr
1373 ***************************************************************************************************
1375 ADDR_E_RETURNCODE
AddrLib::ComputeHtileCoordFromAddr(
1376 const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
1377 ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
1380 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1382 BOOL_32 isWidth8
= (pIn
->blockWidth
== 8) ? TRUE
: FALSE
;
1383 BOOL_32 isHeight8
= (pIn
->blockHeight
== 8) ? TRUE
: FALSE
;
1385 if (GetFillSizeFieldsFlags() == TRUE
)
1387 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT
)) ||
1388 (pOut
->size
!= sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
)))
1390 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1394 if (returnCode
== ADDR_OK
)
1396 ADDR_TILEINFO tileInfoNull
;
1397 ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT input
;
1399 if (UseTileIndex(pIn
->tileIndex
))
1402 // Use temp tile info for calcalation
1403 input
.pTileInfo
= &tileInfoNull
;
1405 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1407 // Change the input structure
1411 if (returnCode
== ADDR_OK
)
1413 HwlComputeXmaskCoordFromAddr(pIn
->addr
,
1433 ***************************************************************************************************
1434 * AddrLib::ComputeCmaskAddrFromCoord
1437 * Interface function stub of AddrComputeCmaskAddrFromCoord
1441 ***************************************************************************************************
1443 ADDR_E_RETURNCODE
AddrLib::ComputeCmaskAddrFromCoord(
1444 const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1445 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1448 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1450 if (GetFillSizeFieldsFlags() == TRUE
)
1452 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
)) ||
1453 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
)))
1455 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1459 if (returnCode
== ADDR_OK
)
1461 ADDR_TILEINFO tileInfoNull
;
1462 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT input
;
1464 if (UseTileIndex(pIn
->tileIndex
))
1467 // Use temp tile info for calcalation
1468 input
.pTileInfo
= &tileInfoNull
;
1470 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1472 // Change the input structure
1476 if (returnCode
== ADDR_OK
)
1478 if (pIn
->flags
.tcCompatible
== TRUE
)
1480 returnCode
= HwlComputeCmaskAddrFromCoord(pIn
, pOut
);
1484 pOut
->addr
= HwlComputeXmaskAddrFromCoord(pIn
->pitch
,
1492 FALSE
, //this is cmask, isWidth8 is not needed
1493 FALSE
, //this is cmask, isHeight8 is not needed
1495 &pOut
->bitPosition
);
1505 ***************************************************************************************************
1506 * AddrLib::ComputeCmaskCoordFromAddr
1509 * Interface function stub of AddrComputeCmaskCoordFromAddr
1513 ***************************************************************************************************
1515 ADDR_E_RETURNCODE
AddrLib::ComputeCmaskCoordFromAddr(
1516 const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
1517 ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
1520 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1522 if (GetFillSizeFieldsFlags() == TRUE
)
1524 if ((pIn
->size
!= sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT
)) ||
1525 (pOut
->size
!= sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT
)))
1527 returnCode
= ADDR_PARAMSIZEMISMATCH
;
1531 if (returnCode
== ADDR_OK
)
1533 ADDR_TILEINFO tileInfoNull
;
1534 ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT input
;
1536 if (UseTileIndex(pIn
->tileIndex
))
1539 // Use temp tile info for calcalation
1540 input
.pTileInfo
= &tileInfoNull
;
1542 returnCode
= HwlSetupTileCfg(input
.tileIndex
, input
.macroModeIndex
, input
.pTileInfo
);
1544 // Change the input structure
1548 if (returnCode
== ADDR_OK
)
1550 HwlComputeXmaskCoordFromAddr(pIn
->addr
,
1570 ***************************************************************************************************
1571 * AddrLib::ComputeTileDataWidthAndHeight
1574 * Compute the squared cache shape for per-tile data (CMASK and HTILE)
1580 * MacroWidth and macroHeight are measured in pixels
1581 ***************************************************************************************************
1583 VOID
AddrLib::ComputeTileDataWidthAndHeight(
1584 UINT_32 bpp
, ///< [in] bits per pixel
1585 UINT_32 cacheBits
, ///< [in] bits of cache
1586 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1587 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1588 UINT_32
* pMacroHeight
///< [out] macro tile height
1592 UINT_32 width
= cacheBits
/ bpp
;
1593 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
1595 // Double height until the macro-tile is close to square
1596 // Height can only be doubled if width is even
1598 while ((width
> height
* 2 * pipes
) && !(width
& 1))
1604 *pMacroWidth
= 8 * width
;
1605 *pMacroHeight
= 8 * height
* pipes
;
1607 // Note: The above iterative comptuation is equivalent to the following
1609 //int log2_height = ((log2(cacheBits)-log2(bpp)-log2(pipes))/2);
1610 //int macroHeight = pow2( 3+log2(pipes)+log2_height );
1614 ***************************************************************************************************
1615 * AddrLib::HwlComputeTileDataWidthAndHeightLinear
1618 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1624 * MacroWidth and macroHeight are measured in pixels
1625 ***************************************************************************************************
1627 VOID
AddrLib::HwlComputeTileDataWidthAndHeightLinear(
1628 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1629 UINT_32
* pMacroHeight
, ///< [out] macro tile height
1630 UINT_32 bpp
, ///< [in] bits per pixel
1631 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
1634 ADDR_ASSERT(bpp
!= 4); // Cmask does not support linear layout prior to SI
1635 *pMacroWidth
= 8 * 512 / bpp
; // Align width to 512-bit memory accesses
1636 *pMacroHeight
= 8 * m_pipes
; // Align height to number of pipes
1640 ***************************************************************************************************
1641 * AddrLib::ComputeHtileInfo
1644 * Compute htile pitch,width, bytes per 2D slice
1647 * Htile bpp i.e. How many bits for an 8x8 tile
1648 * Also returns by output parameters:
1649 * *Htile pitch, height, total size in bytes, macro-tile dimensions and slice size*
1650 ***************************************************************************************************
1652 UINT_32
AddrLib::ComputeHtileInfo(
1653 ADDR_HTILE_FLAGS flags
, ///< [in] htile flags
1654 UINT_32 pitchIn
, ///< [in] pitch input
1655 UINT_32 heightIn
, ///< [in] height input
1656 UINT_32 numSlices
, ///< [in] number of slices
1657 BOOL_32 isLinear
, ///< [in] if it is linear mode
1658 BOOL_32 isWidth8
, ///< [in] if htile block width is 8
1659 BOOL_32 isHeight8
, ///< [in] if htile block height is 8
1660 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1661 UINT_32
* pPitchOut
, ///< [out] pitch output
1662 UINT_32
* pHeightOut
, ///< [out] height output
1663 UINT_64
* pHtileBytes
, ///< [out] bytes per 2D slice
1664 UINT_32
* pMacroWidth
, ///< [out] macro-tile width in pixels
1665 UINT_32
* pMacroHeight
, ///< [out] macro-tile width in pixels
1666 UINT_64
* pSliceSize
, ///< [out] slice size in bytes
1667 UINT_32
* pBaseAlign
///< [out] base alignment
1672 UINT_32 macroHeight
;
1677 numSlices
= Max(1u, numSlices
);
1679 const UINT_32 bpp
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
1680 const UINT_32 cacheBits
= HtileCacheBits
;
1684 HwlComputeTileDataWidthAndHeightLinear(¯oWidth
,
1691 ComputeTileDataWidthAndHeight(bpp
,
1698 *pPitchOut
= PowTwoAlign(pitchIn
, macroWidth
);
1699 *pHeightOut
= PowTwoAlign(heightIn
, macroHeight
);
1701 baseAlign
= HwlComputeHtileBaseAlign(flags
.tcCompatible
, isLinear
, pTileInfo
);
1703 surfBytes
= HwlComputeHtileBytes(*pPitchOut
,
1711 *pHtileBytes
= surfBytes
;
1714 // Use SafeAssign since they are optional
1716 SafeAssign(pMacroWidth
, macroWidth
);
1718 SafeAssign(pMacroHeight
, macroHeight
);
1720 SafeAssign(pSliceSize
, sliceBytes
);
1722 SafeAssign(pBaseAlign
, baseAlign
);
1728 ***************************************************************************************************
1729 * AddrLib::ComputeCmaskBaseAlign
1732 * Compute cmask base alignment
1735 * Cmask base alignment
1736 ***************************************************************************************************
1738 UINT_32
AddrLib::ComputeCmaskBaseAlign(
1739 ADDR_CMASK_FLAGS flags
, ///< [in] Cmask flags
1740 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
1743 UINT_32 baseAlign
= m_pipeInterleaveBytes
* HwlGetPipes(pTileInfo
);
1745 if (flags
.tcCompatible
)
1747 ADDR_ASSERT(pTileInfo
!= NULL
);
1750 baseAlign
*= pTileInfo
->banks
;
1758 ***************************************************************************************************
1759 * AddrLib::ComputeCmaskBytes
1762 * Compute cmask size in bytes
1765 * Cmask size in bytes
1766 ***************************************************************************************************
1768 UINT_64
AddrLib::ComputeCmaskBytes(
1769 UINT_32 pitch
, ///< [in] pitch
1770 UINT_32 height
, ///< [in] height
1771 UINT_32 numSlices
///< [in] number of slices
1774 return BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* numSlices
* CmaskElemBits
) /
1779 ***************************************************************************************************
1780 * AddrLib::ComputeCmaskInfo
1783 * Compute cmask pitch,width, bytes per 2D slice
1786 * BlockMax. Also by output parameters: Cmask pitch,height, total size in bytes,
1787 * macro-tile dimensions
1788 ***************************************************************************************************
1790 ADDR_E_RETURNCODE
AddrLib::ComputeCmaskInfo(
1791 ADDR_CMASK_FLAGS flags
, ///< [in] cmask flags
1792 UINT_32 pitchIn
, ///< [in] pitch input
1793 UINT_32 heightIn
, ///< [in] height input
1794 UINT_32 numSlices
, ///< [in] number of slices
1795 BOOL_32 isLinear
, ///< [in] is linear mode
1796 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1797 UINT_32
* pPitchOut
, ///< [out] pitch output
1798 UINT_32
* pHeightOut
, ///< [out] height output
1799 UINT_64
* pCmaskBytes
, ///< [out] bytes per 2D slice
1800 UINT_32
* pMacroWidth
, ///< [out] macro-tile width in pixels
1801 UINT_32
* pMacroHeight
, ///< [out] macro-tile width in pixels
1802 UINT_64
* pSliceSize
, ///< [out] slice size in bytes
1803 UINT_32
* pBaseAlign
, ///< [out] base alignment
1804 UINT_32
* pBlockMax
///< [out] block max == slice / 128 / 128 - 1
1808 UINT_32 macroHeight
;
1813 numSlices
= Max(1u, numSlices
);
1815 const UINT_32 bpp
= CmaskElemBits
;
1816 const UINT_32 cacheBits
= CmaskCacheBits
;
1818 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1822 HwlComputeTileDataWidthAndHeightLinear(¯oWidth
,
1829 ComputeTileDataWidthAndHeight(bpp
,
1836 *pPitchOut
= (pitchIn
+ macroWidth
- 1) & ~(macroWidth
- 1);
1837 *pHeightOut
= (heightIn
+ macroHeight
- 1) & ~(macroHeight
- 1);
1840 sliceBytes
= ComputeCmaskBytes(*pPitchOut
,
1844 baseAlign
= ComputeCmaskBaseAlign(flags
, pTileInfo
);
1846 while (sliceBytes
% baseAlign
)
1848 *pHeightOut
+= macroHeight
;
1850 sliceBytes
= ComputeCmaskBytes(*pPitchOut
,
1855 surfBytes
= sliceBytes
* numSlices
;
1857 *pCmaskBytes
= surfBytes
;
1860 // Use SafeAssign since they are optional
1862 SafeAssign(pMacroWidth
, macroWidth
);
1864 SafeAssign(pMacroHeight
, macroHeight
);
1866 SafeAssign(pBaseAlign
, baseAlign
);
1868 SafeAssign(pSliceSize
, sliceBytes
);
1870 UINT_32 slice
= (*pPitchOut
) * (*pHeightOut
);
1871 UINT_32 blockMax
= slice
/ 128 / 128 - 1;
1874 if (slice
% (64*256) != 0)
1876 ADDR_ASSERT_ALWAYS();
1880 UINT_32 maxBlockMax
= HwlGetMaxCmaskBlockMax();
1882 if (blockMax
> maxBlockMax
)
1884 blockMax
= maxBlockMax
;
1885 returnCode
= ADDR_INVALIDPARAMS
;
1888 SafeAssign(pBlockMax
, blockMax
);
1894 ***************************************************************************************************
1895 * AddrLib::ComputeXmaskCoordYFromPipe
1898 * Compute the Y coord from pipe number for cmask/htile
1903 ***************************************************************************************************
1905 UINT_32
AddrLib::ComputeXmaskCoordYFromPipe(
1906 UINT_32 pipe
, ///< [in] pipe number
1907 UINT_32 x
///< [in] x coordinate
1919 UINT_32 numPipes
= m_pipes
; // SI has its implementation
1921 // Convert pipe + x to y coordinate.
1941 pipeBit0
= pipe
& 0x1;
1945 yBit0
= pipeBit0
^ xBit0
;
1959 pipeBit0
= pipe
& 0x1;
1960 pipeBit1
= (pipe
& 0x2) >> 1;
1963 xBit1
= (x
& 0x2) >> 1;
1965 yBit0
= pipeBit0
^ xBit1
;
1966 yBit1
= pipeBit1
^ xBit0
;
1975 // r600 and r800 have different method
1977 y
= HwlComputeXmaskCoordYFrom8Pipe(pipe
, x
);
1986 ***************************************************************************************************
1987 * AddrLib::HwlComputeXmaskCoordFromAddr
1990 * Compute the coord from an address of a cmask/htile
1996 * This method is reused by htile, so rename to Xmask
1997 ***************************************************************************************************
1999 VOID
AddrLib::HwlComputeXmaskCoordFromAddr(
2000 UINT_64 addr
, ///< [in] address
2001 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2002 UINT_32 pitch
, ///< [in] pitch
2003 UINT_32 height
, ///< [in] height
2004 UINT_32 numSlices
, ///< [in] number of slices
2005 UINT_32 factor
, ///< [in] factor that indicates cmask or htile
2006 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
2007 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2008 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2009 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
2010 UINT_32
* pX
, ///< [out] x coord
2011 UINT_32
* pY
, ///< [out] y coord
2012 UINT_32
* pSlice
///< [out] slice index
2017 UINT_32 numPipeBits
;
2018 UINT_32 macroTilePitch
;
2019 UINT_32 macroTileHeight
;
2023 UINT_32 microTileCoordY
;
2027 UINT_32 pitchAligned
= pitch
;
2028 UINT_32 heightAligned
= height
;
2036 UINT_64 macroNumber
;
2037 UINT_32 microNumber
;
2046 UINT_32 tilesPerMacro
;
2047 UINT_32 macrosPerPitch
;
2048 UINT_32 macrosPerSlice
;
2053 numPipes
= HwlGetPipes(pTileInfo
);
2054 pipe
= ComputePipeFromAddr(addr
, numPipes
);
2057 // Compute the number of group and pipe bits.
2059 numPipeBits
= Log2(numPipes
);
2061 UINT_32 groupBits
= 8 * m_pipeInterleaveBytes
;
2062 UINT_32 pipes
= numPipes
;
2066 // Compute the micro tile size, in bits. And macro tile pitch and height.
2068 if (factor
== 2) //CMASK
2070 ADDR_CMASK_FLAGS flags
= {{0}};
2072 elemBits
= CmaskElemBits
;
2074 ComputeCmaskInfo(flags
,
2088 ADDR_HTILE_FLAGS flags
= {{0}};
2095 elemBits
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
2097 ComputeHtileInfo(flags
,
2112 // Should use aligned dims
2114 pitch
= pitchAligned
;
2115 height
= heightAligned
;
2119 // Convert byte address to bit address.
2121 bitAddr
= BYTES_TO_BITS(addr
) + bitPosition
;
2125 // Remove pipe bits from address.
2128 bitAddr
= (bitAddr
% groupBits
) + ((bitAddr
/groupBits
/pipes
)*groupBits
);
2131 elemOffset
= bitAddr
/ elemBits
;
2133 tilesPerMacro
= (macroTilePitch
/factor
) * macroTileHeight
/ MicroTilePixels
>> numPipeBits
;
2135 macrosPerPitch
= pitch
/ (macroTilePitch
/factor
);
2136 macrosPerSlice
= macrosPerPitch
* height
/ macroTileHeight
;
2138 macroIndex
= elemOffset
/ factor
/ tilesPerMacro
;
2139 microIndex
= static_cast<UINT_32
>(elemOffset
% (tilesPerMacro
* factor
));
2141 macroNumber
= macroIndex
* factor
+ microIndex
% factor
;
2142 microNumber
= microIndex
/ factor
;
2144 macroX
= static_cast<UINT_32
>((macroNumber
% macrosPerPitch
));
2145 macroY
= static_cast<UINT_32
>((macroNumber
% macrosPerSlice
) / macrosPerPitch
);
2146 macroZ
= static_cast<UINT_32
>((macroNumber
/ macrosPerSlice
));
2149 microX
= microNumber
% (macroTilePitch
/ factor
/ MicroTileWidth
);
2150 microY
= (microNumber
/ (macroTilePitch
/ factor
/ MicroTileHeight
));
2152 *pX
= macroX
* (macroTilePitch
/factor
) + microX
* MicroTileWidth
;
2153 *pY
= macroY
* macroTileHeight
+ (microY
* MicroTileHeight
<< numPipeBits
);
2156 microTileCoordY
= ComputeXmaskCoordYFromPipe(pipe
,
2157 *pX
/MicroTileWidth
);
2161 // Assemble final coordinates.
2163 *pY
+= microTileCoordY
* MicroTileHeight
;
2168 ***************************************************************************************************
2169 * AddrLib::HwlComputeXmaskAddrFromCoord
2172 * Compute the address from an address of cmask (prior to si)
2177 ***************************************************************************************************
2179 UINT_64
AddrLib::HwlComputeXmaskAddrFromCoord(
2180 UINT_32 pitch
, ///< [in] pitch
2181 UINT_32 height
, ///< [in] height
2182 UINT_32 x
, ///< [in] x coord
2183 UINT_32 y
, ///< [in] y coord
2184 UINT_32 slice
, ///< [in] slice/depth index
2185 UINT_32 numSlices
, ///< [in] number of slices
2186 UINT_32 factor
, ///< [in] factor that indicates cmask(2) or htile(1)
2187 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
2188 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2189 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2190 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
2191 UINT_32
* pBitPosition
///< [out] bit position inside a byte
2195 UINT_32 numGroupBits
;
2196 UINT_32 numPipeBits
;
2197 UINT_32 newPitch
= 0;
2198 UINT_32 newHeight
= 0;
2199 UINT_64 sliceBytes
= 0;
2200 UINT_64 totalBytes
= 0;
2201 UINT_64 sliceOffset
;
2203 UINT_32 macroTileWidth
;
2204 UINT_32 macroTileHeight
;
2205 UINT_32 macroTilesPerRow
;
2206 UINT_32 macroTileBytes
;
2207 UINT_32 macroTileIndexX
;
2208 UINT_32 macroTileIndexY
;
2209 UINT_64 macroTileOffset
;
2210 UINT_32 pixelBytesPerRow
;
2211 UINT_32 pixelOffsetX
;
2212 UINT_32 pixelOffsetY
;
2213 UINT_32 pixelOffset
;
2214 UINT_64 totalOffset
;
2220 UINT_32 elemBits
= 0;
2222 UINT_32 numPipes
= m_pipes
; // This function is accessed prior to si only
2224 if (factor
== 2) //CMASK
2226 elemBits
= CmaskElemBits
;
2228 // For asics before SI, cmask is always tiled
2233 if (factor
!= 1) // Fix compile warning
2238 elemBits
= HwlComputeHtileBpp(isWidth8
, isHeight8
);
2242 // Compute the number of group bits and pipe bits.
2244 numGroupBits
= Log2(m_pipeInterleaveBytes
);
2245 numPipeBits
= Log2(numPipes
);
2248 // Compute macro tile dimensions.
2250 if (factor
== 2) // CMASK
2252 ADDR_CMASK_FLAGS flags
= {{0}};
2254 ComputeCmaskInfo(flags
,
2266 sliceBytes
= totalBytes
/ numSlices
;
2270 ADDR_HTILE_FLAGS flags
= {{0}};
2272 ComputeHtileInfo(flags
,
2288 sliceOffset
= slice
* sliceBytes
;
2291 // Get the pipe. Note that neither slice rotation nor pipe swizzling apply for CMASK.
2293 pipe
= ComputePipeFromCoord(x
,
2296 ADDR_TM_2D_TILED_THIN1
,
2302 // Compute the number of macro tiles per row.
2304 macroTilesPerRow
= newPitch
/ macroTileWidth
;
2307 // Compute the number of bytes per macro tile.
2309 macroTileBytes
= BITS_TO_BYTES((macroTileWidth
* macroTileHeight
* elemBits
) / MicroTilePixels
);
2312 // Compute the offset to the macro tile containing the specified coordinate.
2314 macroTileIndexX
= x
/ macroTileWidth
;
2315 macroTileIndexY
= y
/ macroTileHeight
;
2316 macroTileOffset
= ((macroTileIndexY
* macroTilesPerRow
) + macroTileIndexX
) * macroTileBytes
;
2319 // Compute the pixel offset within the macro tile.
2321 pixelBytesPerRow
= BITS_TO_BYTES(macroTileWidth
* elemBits
) / MicroTileWidth
;
2324 // The nibbles are interleaved (see below), so the part of the offset relative to the x
2325 // coordinate repeats halfway across the row. (Not for HTILE)
2329 pixelOffsetX
= (x
% (macroTileWidth
/ 2)) / MicroTileWidth
;
2333 pixelOffsetX
= (x
% (macroTileWidth
)) / MicroTileWidth
* BITS_TO_BYTES(elemBits
);
2337 // Compute the y offset within the macro tile.
2339 pixelOffsetY
= (((y
% macroTileHeight
) / MicroTileHeight
) / numPipes
) * pixelBytesPerRow
;
2341 pixelOffset
= pixelOffsetX
+ pixelOffsetY
;
2344 // Combine the slice offset and macro tile offset with the pixel offset, accounting for the
2345 // pipe bits in the middle of the address.
2347 totalOffset
= ((sliceOffset
+ macroTileOffset
) >> numPipeBits
) + pixelOffset
;
2350 // Split the offset to put some bits below the pipe bits and some above.
2352 groupMask
= (1 << numGroupBits
) - 1;
2353 offsetLo
= totalOffset
& groupMask
;
2354 offsetHi
= (totalOffset
& ~groupMask
) << numPipeBits
;
2357 // Assemble the address from its components.
2361 // This is to remove warning with /analyze option
2362 UINT_32 pipeBits
= pipe
<< numGroupBits
;
2366 // Compute the bit position. The lower nibble is used when the x coordinate within the macro
2367 // tile is less than half of the macro tile width, and the upper nibble is used when the x
2368 // coordinate within the macro tile is greater than or equal to half the macro tile width.
2370 *pBitPosition
= ((x
% macroTileWidth
) < (macroTileWidth
/ factor
)) ? 0 : 4;
2375 ///////////////////////////////////////////////////////////////////////////////////////////////////
2376 // Surface Addressing Shared
2377 ///////////////////////////////////////////////////////////////////////////////////////////////////
2380 ***************************************************************************************************
2381 * AddrLib::ComputeSurfaceAddrFromCoordLinear
2384 * Compute address from coord for linear surface
2389 ***************************************************************************************************
2391 UINT_64
AddrLib::ComputeSurfaceAddrFromCoordLinear(
2392 UINT_32 x
, ///< [in] x coord
2393 UINT_32 y
, ///< [in] y coord
2394 UINT_32 slice
, ///< [in] slice/depth index
2395 UINT_32 sample
, ///< [in] sample index
2396 UINT_32 bpp
, ///< [in] bits per pixel
2397 UINT_32 pitch
, ///< [in] pitch
2398 UINT_32 height
, ///< [in] height
2399 UINT_32 numSlices
, ///< [in] number of slices
2400 UINT_32
* pBitPosition
///< [out] bit position inside a byte
2403 const UINT_64 sliceSize
= static_cast<UINT_64
>(pitch
) * height
;
2405 UINT_64 sliceOffset
= (slice
+ sample
* numSlices
)* sliceSize
;
2406 UINT_64 rowOffset
= static_cast<UINT_64
>(y
) * pitch
;
2407 UINT_64 pixOffset
= x
;
2409 UINT_64 addr
= (sliceOffset
+ rowOffset
+ pixOffset
) * bpp
;
2411 *pBitPosition
= static_cast<UINT_32
>(addr
% 8);
2418 ***************************************************************************************************
2419 * AddrLib::ComputeSurfaceCoordFromAddrLinear
2422 * Compute the coord from an address of a linear surface
2426 ***************************************************************************************************
2428 VOID
AddrLib::ComputeSurfaceCoordFromAddrLinear(
2429 UINT_64 addr
, ///< [in] address
2430 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2431 UINT_32 bpp
, ///< [in] bits per pixel
2432 UINT_32 pitch
, ///< [in] pitch
2433 UINT_32 height
, ///< [in] height
2434 UINT_32 numSlices
, ///< [in] number of slices
2435 UINT_32
* pX
, ///< [out] x coord
2436 UINT_32
* pY
, ///< [out] y coord
2437 UINT_32
* pSlice
, ///< [out] slice/depth index
2438 UINT_32
* pSample
///< [out] sample index
2441 const UINT_64 sliceSize
= static_cast<UINT_64
>(pitch
) * height
;
2442 const UINT_64 linearOffset
= (BYTES_TO_BITS(addr
) + bitPosition
) / bpp
;
2444 *pX
= static_cast<UINT_32
>((linearOffset
% sliceSize
) % pitch
);
2445 *pY
= static_cast<UINT_32
>((linearOffset
% sliceSize
) / pitch
% height
);
2446 *pSlice
= static_cast<UINT_32
>((linearOffset
/ sliceSize
) % numSlices
);
2447 *pSample
= static_cast<UINT_32
>((linearOffset
/ sliceSize
) / numSlices
);
2451 ***************************************************************************************************
2452 * AddrLib::ComputeSurfaceCoordFromAddrMicroTiled
2455 * Compute the coord from an address of a micro tiled surface
2459 ***************************************************************************************************
2461 VOID
AddrLib::ComputeSurfaceCoordFromAddrMicroTiled(
2462 UINT_64 addr
, ///< [in] address
2463 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
2464 UINT_32 bpp
, ///< [in] bits per pixel
2465 UINT_32 pitch
, ///< [in] pitch
2466 UINT_32 height
, ///< [in] height
2467 UINT_32 numSamples
, ///< [in] number of samples
2468 AddrTileMode tileMode
, ///< [in] tile mode
2469 UINT_32 tileBase
, ///< [in] base offset within a tile
2470 UINT_32 compBits
, ///< [in] component bits actually needed(for planar surface)
2471 UINT_32
* pX
, ///< [out] x coord
2472 UINT_32
* pY
, ///< [out] y coord
2473 UINT_32
* pSlice
, ///< [out] slice/depth index
2474 UINT_32
* pSample
, ///< [out] sample index,
2475 AddrTileType microTileType
, ///< [in] micro tiling order
2476 BOOL_32 isDepthSampleOrder
///< [in] TRUE if in depth sample order
2480 UINT_32 microTileThickness
;
2481 UINT_32 microTileBits
;
2485 UINT_32 microTileCoordX
;
2486 UINT_32 microTileCoordY
;
2487 UINT_32 pixelOffset
;
2488 UINT_32 pixelCoordX
= 0;
2489 UINT_32 pixelCoordY
= 0;
2490 UINT_32 pixelCoordZ
= 0;
2491 UINT_32 pixelCoordS
= 0;
2494 // Convert byte address to bit address.
2496 bitAddr
= BYTES_TO_BITS(addr
) + bitPosition
;
2499 // Compute the micro tile size, in bits.
2503 case ADDR_TM_1D_TILED_THICK
:
2504 microTileThickness
= ThickTileThickness
;
2507 microTileThickness
= 1;
2511 microTileBits
= MicroTilePixels
* microTileThickness
* bpp
* numSamples
;
2514 // Compute number of bits per slice and number of bits per row of micro tiles.
2516 sliceBits
= static_cast<UINT_64
>(pitch
) * height
* microTileThickness
* bpp
* numSamples
;
2518 rowBits
= (pitch
/ MicroTileWidth
) * microTileBits
;
2521 // Extract the slice index.
2523 sliceIndex
= static_cast<UINT_32
>(bitAddr
/ sliceBits
);
2524 bitAddr
-= sliceIndex
* sliceBits
;
2527 // Extract the y coordinate of the micro tile.
2529 microTileCoordY
= static_cast<UINT_32
>(bitAddr
/ rowBits
) * MicroTileHeight
;
2530 bitAddr
-= (microTileCoordY
/ MicroTileHeight
) * rowBits
;
2533 // Extract the x coordinate of the micro tile.
2535 microTileCoordX
= static_cast<UINT_32
>(bitAddr
/ microTileBits
) * MicroTileWidth
;
2538 // Compute the pixel offset within the micro tile.
2540 pixelOffset
= static_cast<UINT_32
>(bitAddr
% microTileBits
);
2543 // Extract pixel coordinates from the offset.
2545 HwlComputePixelCoordFromOffset(pixelOffset
,
2556 isDepthSampleOrder
);
2559 // Assemble final coordinates.
2561 *pX
= microTileCoordX
+ pixelCoordX
;
2562 *pY
= microTileCoordY
+ pixelCoordY
;
2563 *pSlice
= (sliceIndex
* microTileThickness
) + pixelCoordZ
;
2564 *pSample
= pixelCoordS
;
2566 if (microTileThickness
> 1)
2573 ***************************************************************************************************
2574 * AddrLib::ComputePipeFromAddr
2577 * Compute the pipe number from an address
2582 ***************************************************************************************************
2584 UINT_32
AddrLib::ComputePipeFromAddr(
2585 UINT_64 addr
, ///< [in] address
2586 UINT_32 numPipes
///< [in] number of banks
2591 UINT_32 groupBytes
= m_pipeInterleaveBytes
; //just different terms
2594 // The LSBs of the address are arranged as follows:
2595 // bank | pipe | group
2597 // To get the pipe number, shift off the group bits and mask the pipe bits.
2601 // The LSBs of the address are arranged as follows:
2602 // bank | bankInterleave | pipe | pipeInterleave
2604 // To get the pipe number, shift off the pipe interleave bits and mask the pipe bits.
2607 pipe
= static_cast<UINT_32
>(addr
>> Log2(groupBytes
)) & (numPipes
- 1);
2613 ***************************************************************************************************
2614 * AddrLib::ComputePixelIndexWithinMicroTile
2617 * Compute the pixel index inside a micro tile of surface
2622 ***************************************************************************************************
2624 UINT_32
AddrLib::ComputePixelIndexWithinMicroTile(
2625 UINT_32 x
, ///< [in] x coord
2626 UINT_32 y
, ///< [in] y coord
2627 UINT_32 z
, ///< [in] slice/depth index
2628 UINT_32 bpp
, ///< [in] bits per pixel
2629 AddrTileMode tileMode
, ///< [in] tile mode
2630 AddrTileType microTileType
///< [in] pixel order in display/non-display mode
2633 UINT_32 pixelBit0
= 0;
2634 UINT_32 pixelBit1
= 0;
2635 UINT_32 pixelBit2
= 0;
2636 UINT_32 pixelBit3
= 0;
2637 UINT_32 pixelBit4
= 0;
2638 UINT_32 pixelBit5
= 0;
2639 UINT_32 pixelBit6
= 0;
2640 UINT_32 pixelBit7
= 0;
2641 UINT_32 pixelBit8
= 0;
2642 UINT_32 pixelNumber
;
2644 UINT_32 x0
= _BIT(x
, 0);
2645 UINT_32 x1
= _BIT(x
, 1);
2646 UINT_32 x2
= _BIT(x
, 2);
2647 UINT_32 y0
= _BIT(y
, 0);
2648 UINT_32 y1
= _BIT(y
, 1);
2649 UINT_32 y2
= _BIT(y
, 2);
2650 UINT_32 z0
= _BIT(z
, 0);
2651 UINT_32 z1
= _BIT(z
, 1);
2652 UINT_32 z2
= _BIT(z
, 2);
2654 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
2656 // Compute the pixel number within the micro tile.
2658 if (microTileType
!= ADDR_THICK
)
2660 if (microTileType
== ADDR_DISPLAYABLE
)
2705 ADDR_ASSERT_ALWAYS();
2709 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2718 else if (microTileType
== ADDR_ROTATED
)
2720 ADDR_ASSERT(thickness
== 1);
2757 ADDR_ASSERT_ALWAYS();
2770 ADDR_ASSERT(thickness
> 1);
2801 ADDR_ASSERT_ALWAYS();
2814 pixelNumber
= ((pixelBit0
) |
2828 ***************************************************************************************************
2829 * AddrLib::AdjustPitchAlignment
2832 * Adjusts pitch alignment for flipping surface
2837 ***************************************************************************************************
2839 VOID
AddrLib::AdjustPitchAlignment(
2840 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface flags
2841 UINT_32
* pPitchAlign
///< [out] Pointer to pitch alignment
2844 // Display engine hardwires lower 5 bit of GRPH_PITCH to ZERO which means 32 pixel alignment
2845 // Maybe it will be fixed in future but let's make it general for now.
2846 if (flags
.display
|| flags
.overlay
)
2848 *pPitchAlign
= PowTwoAlign(*pPitchAlign
, 32);
2852 *pPitchAlign
= Max(m_minPitchAlignPixels
, *pPitchAlign
);
2858 ***************************************************************************************************
2859 * AddrLib::PadDimensions
2862 * Helper function to pad dimensions
2867 ***************************************************************************************************
2869 VOID
AddrLib::PadDimensions(
2870 AddrTileMode tileMode
, ///< [in] tile mode
2871 UINT_32 bpp
, ///< [in] bits per pixel
2872 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
2873 UINT_32 numSamples
, ///< [in] number of samples
2874 ADDR_TILEINFO
* pTileInfo
, ///< [in/out] bank structure.
2875 UINT_32 padDims
, ///< [in] Dimensions to pad valid value 1,2,3
2876 UINT_32 mipLevel
, ///< [in] MipLevel
2877 UINT_32
* pPitch
, ///< [in/out] pitch in pixels
2878 UINT_32 pitchAlign
, ///< [in] pitch alignment
2879 UINT_32
* pHeight
, ///< [in/out] height in pixels
2880 UINT_32 heightAlign
, ///< [in] height alignment
2881 UINT_32
* pSlices
, ///< [in/out] number of slices
2882 UINT_32 sliceAlign
///< [in] number of slice alignment
2885 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
2887 ADDR_ASSERT(padDims
<= 3);
2890 // Override padding for mip levels
2896 // for cubemap, we only pad when client call with 6 faces as an identity
2899 padDims
= 3; // we should pad cubemap sub levels when we treat it as 3d texture
2908 // Any possibilities that padDims is 0?
2914 if (IsPow2(pitchAlign
))
2916 *pPitch
= PowTwoAlign((*pPitch
), pitchAlign
);
2918 else // add this code to pass unit test, r600 linear mode is not align bpp to pow2 for linear
2920 *pPitch
+= pitchAlign
- 1;
2921 *pPitch
/= pitchAlign
;
2922 *pPitch
*= pitchAlign
;
2927 *pHeight
= PowTwoAlign((*pHeight
), heightAlign
);
2930 if (padDims
> 2 || thickness
> 1)
2932 // for cubemap single face, we do not pad slices.
2933 // if we pad it, the slice number should be set to 6 and current mip level > 1
2934 if (flags
.cube
&& (!m_configFlags
.noCubeMipSlicesPad
|| flags
.cubeAsArray
))
2936 *pSlices
= NextPow2(*pSlices
);
2939 // normal 3D texture or arrays or cubemap has a thick mode? (Just pass unit test)
2942 *pSlices
= PowTwoAlign((*pSlices
), sliceAlign
);
2947 HwlPadDimensions(tileMode
,
2964 ***************************************************************************************************
2965 * AddrLib::HwlPreHandleBaseLvl3xPitch
2968 * Pre-handler of 3x pitch (96 bit) adjustment
2972 ***************************************************************************************************
2974 UINT_32
AddrLib::HwlPreHandleBaseLvl3xPitch(
2975 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
2976 UINT_32 expPitch
///< [in] pitch
2979 ADDR_ASSERT(pIn
->width
== expPitch
);
2981 // If pitch is pre-multiplied by 3, we retrieve original one here to get correct miplevel size
2983 if (AddrElemLib::IsExpand3x(pIn
->format
) &&
2984 pIn
->mipLevel
== 0 &&
2985 pIn
->tileMode
== ADDR_TM_LINEAR_ALIGNED
)
2988 expPitch
= NextPow2(expPitch
);
2995 ***************************************************************************************************
2996 * AddrLib::HwlPostHandleBaseLvl3xPitch
2999 * Post-handler of 3x pitch adjustment
3003 ***************************************************************************************************
3005 UINT_32
AddrLib::HwlPostHandleBaseLvl3xPitch(
3006 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
3007 UINT_32 expPitch
///< [in] pitch
3011 // 96 bits surface of sub levels require element pitch of 32 bits instead
3012 // So we just return pitch in 32 bit pixels without timing 3
3014 if (AddrElemLib::IsExpand3x(pIn
->format
) &&
3015 pIn
->mipLevel
== 0 &&
3016 pIn
->tileMode
== ADDR_TM_LINEAR_ALIGNED
)
3026 ***************************************************************************************************
3027 * AddrLib::IsMacroTiled
3030 * Check if the tile mode is macro tiled
3033 * TRUE if it is macro tiled (2D/2B/3D/3B)
3034 ***************************************************************************************************
3036 BOOL_32
AddrLib::IsMacroTiled(
3037 AddrTileMode tileMode
) ///< [in] tile mode
3039 return m_modeFlags
[tileMode
].isMacro
;
3043 ***************************************************************************************************
3044 * AddrLib::IsMacro3dTiled
3047 * Check if the tile mode is 3D macro tiled
3050 * TRUE if it is 3D macro tiled
3051 ***************************************************************************************************
3053 BOOL_32
AddrLib::IsMacro3dTiled(
3054 AddrTileMode tileMode
) ///< [in] tile mode
3056 return m_modeFlags
[tileMode
].isMacro3d
;
3060 ***************************************************************************************************
3061 * AddrLib::IsMicroTiled
3064 * Check if the tile mode is micro tiled
3067 * TRUE if micro tiled
3068 ***************************************************************************************************
3070 BOOL_32
AddrLib::IsMicroTiled(
3071 AddrTileMode tileMode
) ///< [in] tile mode
3073 return m_modeFlags
[tileMode
].isMicro
;
3077 ***************************************************************************************************
3081 * Check if the tile mode is linear
3085 ***************************************************************************************************
3087 BOOL_32
AddrLib::IsLinear(
3088 AddrTileMode tileMode
) ///< [in] tile mode
3090 return m_modeFlags
[tileMode
].isLinear
;
3094 ***************************************************************************************************
3095 * AddrLib::IsPrtNoRotationTileMode
3098 * Return TRUE if it is prt tile without rotation
3100 * This function just used by CI
3101 ***************************************************************************************************
3103 BOOL_32
AddrLib::IsPrtNoRotationTileMode(
3104 AddrTileMode tileMode
)
3106 return m_modeFlags
[tileMode
].isPrtNoRotation
;
3110 ***************************************************************************************************
3111 * AddrLib::IsPrtTileMode
3114 * Return TRUE if it is prt tile
3116 * This function just used by CI
3117 ***************************************************************************************************
3119 BOOL_32
AddrLib::IsPrtTileMode(
3120 AddrTileMode tileMode
)
3122 return m_modeFlags
[tileMode
].isPrt
;
3126 ***************************************************************************************************
3127 * AddrLib::ComputeMipLevel
3130 * Compute mipmap level width/height/slices
3133 ***************************************************************************************************
3135 VOID
AddrLib::ComputeMipLevel(
3136 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
///< [in/out] Input structure
3139 if (AddrElemLib::IsBlockCompressed(pIn
->format
))
3141 if (pIn
->mipLevel
== 0)
3143 // DXTn's level 0 must be multiple of 4
3144 // But there are exceptions:
3145 // 1. Internal surface creation in hostblt/vsblt/etc...
3146 // 2. Runtime doesn't reject ATI1/ATI2 whose width/height are not multiple of 4
3147 pIn
->width
= PowTwoAlign(pIn
->width
, 4);
3148 pIn
->height
= PowTwoAlign(pIn
->height
, 4);
3152 HwlComputeMipLevel(pIn
);
3156 ***************************************************************************************************
3157 * AddrLib::OptimizeTileMode
3160 * Check if base level's tile mode can be optimized (degraded)
3162 * TRUE if degraded, also returns degraded tile mode (unchanged if not degraded)
3163 ***************************************************************************************************
3165 BOOL_32
AddrLib::OptimizeTileMode(
3166 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure for surface info
3167 AddrTileMode
* pTileMode
///< [out] Degraded tile mode
3170 AddrTileMode tileMode
= pIn
->tileMode
;
3171 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
3173 // Optimization can only be done on level 0 and samples <= 1
3174 if ((pIn
->flags
.opt4Space
== TRUE
) &&
3175 (pIn
->mipLevel
== 0) &&
3176 (pIn
->numSamples
<= 1) &&
3177 (pIn
->flags
.display
== FALSE
) &&
3178 (IsPrtTileMode(tileMode
) == FALSE
) &&
3179 (pIn
->flags
.prt
== FALSE
))
3181 // Check if linear mode is optimal
3182 if ((pIn
->height
== 1) &&
3183 (IsLinear(tileMode
) == FALSE
) &&
3184 (AddrElemLib::IsBlockCompressed(pIn
->format
) == FALSE
) &&
3185 (pIn
->flags
.depth
== FALSE
) &&
3186 (pIn
->flags
.stencil
== FALSE
) &&
3187 (m_configFlags
.disableLinearOpt
== FALSE
) &&
3188 (pIn
->flags
.disableLinearOpt
== FALSE
))
3190 tileMode
= ADDR_TM_LINEAR_ALIGNED
;
3192 else if (IsMacroTiled(tileMode
))
3194 if (HwlDegradeBaseLevel(pIn
))
3196 tileMode
= (thickness
== 1) ? ADDR_TM_1D_TILED_THIN1
: ADDR_TM_1D_TILED_THICK
;
3198 else if (thickness
> 1)
3200 // As in the following HwlComputeSurfaceInfo, thick modes may be degraded to
3201 // thinner modes, we should re-evaluate whether the corresponding thinner modes
3202 // need to be degraded. If so, we choose 1D thick mode instead.
3203 tileMode
= DegradeLargeThickTile(pIn
->tileMode
, pIn
->bpp
);
3204 if (tileMode
!= pIn
->tileMode
)
3206 ADDR_COMPUTE_SURFACE_INFO_INPUT input
= *pIn
;
3207 input
.tileMode
= tileMode
;
3208 if (HwlDegradeBaseLevel(&input
))
3210 tileMode
= ADDR_TM_1D_TILED_THICK
;
3217 BOOL_32 optimized
= (tileMode
!= pIn
->tileMode
);
3220 *pTileMode
= tileMode
;
3226 ***************************************************************************************************
3227 * AddrLib::DegradeLargeThickTile
3230 * Check if the thickness needs to be reduced if a tile is too large
3232 * The degraded tile mode (unchanged if not degraded)
3233 ***************************************************************************************************
3235 AddrTileMode
AddrLib::DegradeLargeThickTile(
3236 AddrTileMode tileMode
,
3239 // Override tilemode
3240 // When tile_width (8) * tile_height (8) * thickness * element_bytes is > row_size,
3241 // it is better to just use THIN mode in this case
3242 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
3244 if (thickness
> 1 && m_configFlags
.allowLargeThickTile
== 0)
3246 UINT_32 tileSize
= MicroTilePixels
* thickness
* (bpp
>> 3);
3248 if (tileSize
> m_rowSize
)
3252 case ADDR_TM_2D_TILED_XTHICK
:
3253 if ((tileSize
>> 1) <= m_rowSize
)
3255 tileMode
= ADDR_TM_2D_TILED_THICK
;
3258 // else fall through
3259 case ADDR_TM_2D_TILED_THICK
:
3260 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3263 case ADDR_TM_3D_TILED_XTHICK
:
3264 if ((tileSize
>> 1) <= m_rowSize
)
3266 tileMode
= ADDR_TM_3D_TILED_THICK
;
3269 // else fall through
3270 case ADDR_TM_3D_TILED_THICK
:
3271 tileMode
= ADDR_TM_3D_TILED_THIN1
;
3274 case ADDR_TM_PRT_TILED_THICK
:
3275 tileMode
= ADDR_TM_PRT_TILED_THIN1
;
3278 case ADDR_TM_PRT_2D_TILED_THICK
:
3279 tileMode
= ADDR_TM_PRT_2D_TILED_THIN1
;
3282 case ADDR_TM_PRT_3D_TILED_THICK
:
3283 tileMode
= ADDR_TM_PRT_3D_TILED_THIN1
;
3296 ***************************************************************************************************
3297 * AddrLib::PostComputeMipLevel
3299 * Compute MipLevel info (including level 0) after surface adjustment
3302 ***************************************************************************************************
3304 ADDR_E_RETURNCODE
AddrLib::PostComputeMipLevel(
3305 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in/out] Input structure
3306 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] Output structure
3309 // Mipmap including level 0 must be pow2 padded since either SI hw expects so or it is
3310 // required by CFX for Hw Compatibility between NI and SI. Otherwise it is only needed for
3311 // mipLevel > 0. Any h/w has different requirement should implement its own virtual function
3313 if (pIn
->flags
.pow2Pad
)
3315 pIn
->width
= NextPow2(pIn
->width
);
3316 pIn
->height
= NextPow2(pIn
->height
);
3317 pIn
->numSlices
= NextPow2(pIn
->numSlices
);
3319 else if (pIn
->mipLevel
> 0)
3321 pIn
->width
= NextPow2(pIn
->width
);
3322 pIn
->height
= NextPow2(pIn
->height
);
3324 if (!pIn
->flags
.cube
)
3326 pIn
->numSlices
= NextPow2(pIn
->numSlices
);
3329 // for cubemap, we keep its value at first
3336 ***************************************************************************************************
3337 * AddrLib::HwlSetupTileCfg
3340 * Map tile index to tile setting.
3343 ***************************************************************************************************
3345 ADDR_E_RETURNCODE
AddrLib::HwlSetupTileCfg(
3346 INT_32 index
, ///< [in] Tile index
3347 INT_32 macroModeIndex
, ///< [in] Index in macro tile mode table(CI)
3348 ADDR_TILEINFO
* pInfo
, ///< [out] Tile Info
3349 AddrTileMode
* pMode
, ///< [out] Tile mode
3350 AddrTileType
* pType
///< [out] Tile type
3353 return ADDR_NOTSUPPORTED
;
3357 ***************************************************************************************************
3358 * AddrLib::HwlGetPipes
3364 ***************************************************************************************************
3366 UINT_32
AddrLib::HwlGetPipes(
3367 const ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
3370 //pTileInfo can be NULL when asic is 6xx and 8xx.
3375 ***************************************************************************************************
3376 * AddrLib::ComputeQbStereoInfo
3379 * Get quad buffer stereo information
3382 ***************************************************************************************************
3384 BOOL_32
AddrLib::ComputeQbStereoInfo(
3385 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in/out] updated pOut+pStereoInfo
3388 BOOL_32 success
= FALSE
;
3390 if (pOut
->pStereoInfo
)
3392 ADDR_ASSERT(pOut
->bpp
>= 8);
3393 ADDR_ASSERT((pOut
->surfSize
% pOut
->baseAlign
) == 0);
3395 // Save original height
3396 pOut
->pStereoInfo
->eyeHeight
= pOut
->height
;
3399 pOut
->pStereoInfo
->rightOffset
= static_cast<UINT_32
>(pOut
->surfSize
);
3401 pOut
->pStereoInfo
->rightSwizzle
= HwlComputeQbStereoRightSwizzle(pOut
);
3404 pOut
->pixelHeight
<<= 1;
3407 pOut
->surfSize
<<= 1;
3409 // Right start address meets the base align since it is guaranteed by AddrLib
3411 // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo.
3419 ***************************************************************************************************
3420 * AddrLib::ComputePrtInfo
3423 * Compute prt surface related info
3427 ***************************************************************************************************
3429 ADDR_E_RETURNCODE
AddrLib::ComputePrtInfo(
3430 const ADDR_PRT_INFO_INPUT
* pIn
,
3431 ADDR_PRT_INFO_OUTPUT
* pOut
) const
3433 ADDR_ASSERT(pOut
!= NULL
);
3435 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
3437 UINT_32 expandX
= 1;
3438 UINT_32 expandY
= 1;
3439 AddrElemMode elemMode
;
3441 UINT_32 bpp
= GetElemLib()->GetBitsPerPixel(pIn
->format
,
3446 if (bpp
<8 || bpp
== 24 || bpp
== 48 || bpp
== 96 )
3448 returnCode
= ADDR_INVALIDPARAMS
;
3451 UINT_32 numFrags
= pIn
->numFrags
;
3452 ADDR_ASSERT(numFrags
<= 8);
3454 UINT_32 tileWidth
= 0;
3455 UINT_32 tileHeight
= 0;
3456 if (returnCode
== ADDR_OK
)
3458 // 3D texture without depth or 2d texture
3459 if (pIn
->baseMipDepth
> 1 || pIn
->baseMipHeight
> 1)
3478 // assume it is BC1/4
3482 if (elemMode
== ADDR_UNCOMPRESSED
)
3488 else if (bpp
== 128)
3490 // assume it is BC2/3/5/6H/7
3494 if (elemMode
== ADDR_UNCOMPRESSED
)
3503 tileWidth
= tileWidth
/ 2;
3505 else if (numFrags
== 4)
3507 tileWidth
= tileWidth
/ 2;
3508 tileHeight
= tileHeight
/ 2;
3510 else if (numFrags
== 8)
3512 tileWidth
= tileWidth
/ 4;
3513 tileHeight
= tileHeight
/ 2;
3535 else if (bpp
== 128)
3542 pOut
->prtTileWidth
= tileWidth
;
3543 pOut
->prtTileHeight
= tileHeight
;