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 ****************************************************************************************************
29 * @file egbaddrlib.cpp
30 * @brief Contains the EgBasedLib class implementation.
31 ****************************************************************************************************
34 #include "egbaddrlib.h"
42 ****************************************************************************************************
43 * EgBasedLib::EgBasedLib
50 ****************************************************************************************************
52 EgBasedLib::EgBasedLib(const Client
* pClient
)
62 ****************************************************************************************************
63 * EgBasedLib::~EgBasedLib
67 ****************************************************************************************************
69 EgBasedLib::~EgBasedLib()
74 ****************************************************************************************************
75 * EgBasedLib::DispatchComputeSurfaceInfo
78 * Compute surface sizes include padded pitch,height,slices,total size in bytes,
79 * meanwhile output suitable tile mode and base alignment might be changed in this
80 * call as well. Results are returned through output parameters.
83 * TRUE if no error occurs
84 ****************************************************************************************************
86 BOOL_32
EgBasedLib::DispatchComputeSurfaceInfo(
87 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
88 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
91 AddrTileMode tileMode
= pIn
->tileMode
;
92 UINT_32 bpp
= pIn
->bpp
;
93 UINT_32 numSamples
= pIn
->numSamples
;
94 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
95 UINT_32 pitch
= pIn
->width
;
96 UINT_32 height
= pIn
->height
;
97 UINT_32 numSlices
= pIn
->numSlices
;
98 UINT_32 mipLevel
= pIn
->mipLevel
;
99 ADDR_SURFACE_FLAGS flags
= pIn
->flags
;
101 ADDR_TILEINFO tileInfoDef
= {0};
102 ADDR_TILEINFO
* pTileInfo
= &tileInfoDef
;
107 tileMode
= DegradeLargeThickTile(tileMode
, bpp
);
109 // Only override numSamples for NI above
110 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
112 if (numFrags
!= numSamples
) // This means EQAA
114 // The real surface size needed is determined by number of fragments
115 numSamples
= numFrags
;
118 // Save altered numSamples in pOut
119 pOut
->numSamples
= numSamples
;
122 // Caller makes sure pOut->pTileInfo is not NULL, see HwlComputeSurfaceInfo
123 ADDR_ASSERT(pOut
->pTileInfo
);
125 if (pOut
->pTileInfo
!= NULL
)
127 pTileInfo
= pOut
->pTileInfo
;
130 // Set default values
131 if (pIn
->pTileInfo
!= NULL
)
133 if (pTileInfo
!= pIn
->pTileInfo
)
135 *pTileInfo
= *pIn
->pTileInfo
;
140 memset(pTileInfo
, 0, sizeof(ADDR_TILEINFO
));
143 // For macro tile mode, we should calculate default tiling parameters
144 HwlSetupTileInfo(tileMode
,
164 // This is calculating one face, remove cube flag
171 case ADDR_TM_LINEAR_GENERAL
://fall through
172 case ADDR_TM_LINEAR_ALIGNED
:
173 valid
= ComputeSurfaceInfoLinear(pIn
, pOut
, padDims
);
176 case ADDR_TM_1D_TILED_THIN1
://fall through
177 case ADDR_TM_1D_TILED_THICK
:
178 valid
= ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, tileMode
);
181 case ADDR_TM_2D_TILED_THIN1
: //fall through
182 case ADDR_TM_2D_TILED_THICK
: //fall through
183 case ADDR_TM_3D_TILED_THIN1
: //fall through
184 case ADDR_TM_3D_TILED_THICK
: //fall through
185 case ADDR_TM_2D_TILED_XTHICK
: //fall through
186 case ADDR_TM_3D_TILED_XTHICK
: //fall through
187 case ADDR_TM_PRT_TILED_THIN1
: //fall through
188 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
189 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
190 case ADDR_TM_PRT_TILED_THICK
: //fall through
191 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
192 case ADDR_TM_PRT_3D_TILED_THICK
:
193 valid
= ComputeSurfaceInfoMacroTiled(pIn
, pOut
, padDims
, tileMode
);
198 ADDR_ASSERT_ALWAYS();
206 ****************************************************************************************************
207 * EgBasedLib::ComputeSurfaceInfoLinear
210 * Compute linear surface sizes include padded pitch, height, slices, total size in
211 * bytes, meanwhile alignments as well. Since it is linear mode, so output tile mode
212 * will not be changed here. Results are returned through output parameters.
215 * TRUE if no error occurs
216 ****************************************************************************************************
218 BOOL_32
EgBasedLib::ComputeSurfaceInfoLinear(
219 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
220 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
221 UINT_32 padDims
///< [in] Dimensions to padd
224 UINT_32 expPitch
= pIn
->width
;
225 UINT_32 expHeight
= pIn
->height
;
226 UINT_32 expNumSlices
= pIn
->numSlices
;
228 // No linear MSAA on real H/W, keep this for TGL
229 UINT_32 numSamples
= pOut
->numSamples
;
231 const UINT_32 microTileThickness
= 1;
234 // Compute the surface alignments.
236 ComputeSurfaceAlignmentsLinear(pIn
->tileMode
,
243 if (pIn
->pitchAlign
!= 0)
245 ADDR_ASSERT((pIn
->pitchAlign
% pOut
->pitchAlign
) == 0);
246 pOut
->pitchAlign
= pIn
->pitchAlign
;
249 if (pIn
->heightAlign
!= 0)
251 ADDR_ASSERT((pIn
->heightAlign
% pOut
->heightAlign
) == 0);
252 pOut
->heightAlign
= pIn
->heightAlign
;
255 if ((pIn
->tileMode
== ADDR_TM_LINEAR_GENERAL
) && pIn
->flags
.color
&& (pIn
->height
> 1))
258 // When linear_general surface is accessed in multiple lines, it requires 8 pixels in pitch
259 // alignment since PITCH_TILE_MAX is in unit of 8 pixels.
260 // It is OK if it is accessed per line.
261 ADDR_ASSERT((pIn
->width
% 8) == 0);
265 pOut
->depthAlign
= microTileThickness
;
267 expPitch
= HwlPreHandleBaseLvl3xPitch(pIn
, expPitch
);
270 // Pad pitch and height to the required granularities.
272 PadDimensions(pIn
->tileMode
,
279 &expPitch
, &pOut
->pitchAlign
,
280 &expHeight
, pOut
->heightAlign
,
281 &expNumSlices
, microTileThickness
);
283 expPitch
= HwlPostHandleBaseLvl3xPitch(pIn
, expPitch
);
289 UINT_64 logicalSliceSize
;
291 logicalSliceSize
= HwlGetSizeAdjustmentLinear(pIn
->tileMode
,
301 pOut
->pitch
= expPitch
;
302 pOut
->height
= expHeight
;
303 pOut
->depth
= expNumSlices
;
305 pOut
->surfSize
= logicalSliceSize
* expNumSlices
;
307 pOut
->tileMode
= pIn
->tileMode
;
313 ****************************************************************************************************
314 * EgBasedLib::ComputeSurfaceInfoMicroTiled
317 * Compute 1D/Micro Tiled surface sizes include padded pitch, height, slices, total
318 * size in bytes, meanwhile alignments as well. Results are returned through output
322 * TRUE if no error occurs
323 ****************************************************************************************************
325 BOOL_32
EgBasedLib::ComputeSurfaceInfoMicroTiled(
326 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
327 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
328 UINT_32 padDims
, ///< [in] Dimensions to padd
329 AddrTileMode expTileMode
///< [in] Expected tile mode
332 BOOL_32 valid
= TRUE
;
334 UINT_32 microTileThickness
;
335 UINT_32 expPitch
= pIn
->width
;
336 UINT_32 expHeight
= pIn
->height
;
337 UINT_32 expNumSlices
= pIn
->numSlices
;
339 // No 1D MSAA on real H/W, keep this for TGL
340 UINT_32 numSamples
= pOut
->numSamples
;
343 // Compute the micro tile thickness.
345 microTileThickness
= Thickness(expTileMode
);
348 // Extra override for mip levels
350 if (pIn
->mipLevel
> 0)
353 // Reduce tiling mode from thick to thin if the number of slices is less than the
354 // micro tile thickness.
356 if ((expTileMode
== ADDR_TM_1D_TILED_THICK
) &&
357 (expNumSlices
< ThickTileThickness
))
359 expTileMode
= HwlDegradeThickTileMode(ADDR_TM_1D_TILED_THICK
, expNumSlices
, NULL
);
360 if (expTileMode
!= ADDR_TM_1D_TILED_THICK
)
362 microTileThickness
= 1;
368 // Compute the surface restrictions.
370 ComputeSurfaceAlignmentsMicroTiled(expTileMode
,
379 pOut
->depthAlign
= microTileThickness
;
382 // Pad pitch and height to the required granularities.
383 // Compute surface size.
384 // Return parameters.
386 PadDimensions(expTileMode
,
393 &expPitch
, &pOut
->pitchAlign
,
394 &expHeight
, pOut
->heightAlign
,
395 &expNumSlices
, microTileThickness
);
398 // Get HWL specific pitch adjustment
400 UINT_64 logicalSliceSize
= HwlGetSizeAdjustmentMicroTiled(microTileThickness
,
410 pOut
->pitch
= expPitch
;
411 pOut
->height
= expHeight
;
412 pOut
->depth
= expNumSlices
;
414 pOut
->surfSize
= logicalSliceSize
* expNumSlices
;
416 pOut
->tileMode
= expTileMode
;
423 ****************************************************************************************************
424 * EgBasedLib::ComputeSurfaceInfoMacroTiled
427 * Compute 2D/macro tiled surface sizes include padded pitch, height, slices, total
428 * size in bytes, meanwhile output suitable tile mode and alignments might be changed
429 * in this call as well. Results are returned through output parameters.
432 * TRUE if no error occurs
433 ****************************************************************************************************
435 BOOL_32
EgBasedLib::ComputeSurfaceInfoMacroTiled(
436 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
437 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
438 UINT_32 padDims
, ///< [in] Dimensions to padd
439 AddrTileMode expTileMode
///< [in] Expected tile mode
442 BOOL_32 valid
= TRUE
;
444 AddrTileMode origTileMode
= expTileMode
;
445 UINT_32 microTileThickness
;
448 UINT_32 paddedHeight
;
449 UINT_64 bytesPerSlice
;
451 UINT_32 expPitch
= pIn
->width
;
452 UINT_32 expHeight
= pIn
->height
;
453 UINT_32 expNumSlices
= pIn
->numSlices
;
455 UINT_32 numSamples
= pOut
->numSamples
;
458 // Compute the surface restrictions as base
459 // SanityCheckMacroTiled is called in ComputeSurfaceAlignmentsMacroTiled
461 valid
= ComputeSurfaceAlignmentsMacroTiled(expTileMode
,
476 // Compute the micro tile thickness.
478 microTileThickness
= Thickness(expTileMode
);
481 // Find the correct tiling mode for mip levels
483 if (pIn
->mipLevel
> 0)
486 // Try valid tile mode
488 expTileMode
= ComputeSurfaceMipLevelTileMode(expTileMode
,
498 if (!IsMacroTiled(expTileMode
)) // Downgraded to micro-tiled
500 return ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, expTileMode
);
502 else if (microTileThickness
!= Thickness(expTileMode
))
505 // Re-compute if thickness changed since bank-height may be changed!
507 return ComputeSurfaceInfoMacroTiled(pIn
, pOut
, padDims
, expTileMode
);
511 paddedPitch
= expPitch
;
512 paddedHeight
= expHeight
;
517 if (expTileMode
!= origTileMode
) // Tile mode is changed but still macro-tiled
519 valid
= ComputeSurfaceAlignmentsMacroTiled(expTileMode
,
535 PadDimensions(expTileMode
,
542 &paddedPitch
, &pOut
->pitchAlign
,
543 &paddedHeight
, pOut
->heightAlign
,
544 &expNumSlices
, microTileThickness
);
546 if (pIn
->flags
.qbStereo
&&
547 (pOut
->pStereoInfo
!= NULL
))
549 UINT_32 stereoHeightAlign
= HwlStereoCheckRightOffsetPadding(pOut
->pTileInfo
);
551 if (stereoHeightAlign
!= 0)
553 paddedHeight
= PowTwoAlign(paddedHeight
, stereoHeightAlign
);
557 if ((pIn
->flags
.needEquation
== TRUE
) &&
558 (m_chipFamily
== ADDR_CHIP_FAMILY_SI
) &&
559 (pIn
->numMipLevels
> 1) &&
560 (pIn
->mipLevel
== 0))
562 BOOL_32 convertTo1D
= FALSE
;
564 ADDR_ASSERT(Thickness(expTileMode
) == 1);
566 for (UINT_32 i
= 1; i
< pIn
->numMipLevels
; i
++)
568 UINT_32 mipPitch
= Max(1u, paddedPitch
>> i
);
569 UINT_32 mipHeight
= Max(1u, pIn
->height
>> i
);
570 UINT_32 mipSlices
= pIn
->flags
.volume
?
571 Max(1u, pIn
->numSlices
>> i
) : pIn
->numSlices
;
572 expTileMode
= ComputeSurfaceMipLevelTileMode(expTileMode
,
582 if (IsMacroTiled(expTileMode
))
584 if (PowTwoAlign(mipPitch
, pOut
->blockWidth
) !=
585 PowTwoAlign(mipPitch
, pOut
->pitchAlign
))
599 return ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, ADDR_TM_1D_TILED_THIN1
);
603 pOut
->pitch
= paddedPitch
;
604 // Put this check right here to workaround special mipmap cases which the original height
606 // The original height is pre-stored in pOut->height in PostComputeMipLevel and
607 // pOut->pitch is needed in HwlCheckLastMacroTiledLvl, too.
608 if (m_configFlags
.checkLast2DLevel
&& (numSamples
== 1)) // Don't check MSAA
610 // Set a TRUE in pOut if next Level is the first 1D sub level
611 HwlCheckLastMacroTiledLvl(pIn
, pOut
);
613 pOut
->height
= paddedHeight
;
615 pOut
->depth
= expNumSlices
;
618 // Compute the size of a slice.
620 bytesPerSlice
= BITS_TO_BYTES(static_cast<UINT_64
>(paddedPitch
) *
621 paddedHeight
* NextPow2(pIn
->bpp
) * numSamples
);
623 pOut
->surfSize
= bytesPerSlice
* expNumSlices
;
625 pOut
->tileMode
= expTileMode
;
627 pOut
->depthAlign
= microTileThickness
;
635 ****************************************************************************************************
636 * EgBasedLib::ComputeSurfaceAlignmentsLinear
639 * Compute linear surface alignment, calculation results are returned through
643 * TRUE if no error occurs
644 ****************************************************************************************************
646 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsLinear(
647 AddrTileMode tileMode
, ///< [in] tile mode
648 UINT_32 bpp
, ///< [in] bits per pixel
649 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
650 UINT_32
* pBaseAlign
, ///< [out] base address alignment in bytes
651 UINT_32
* pPitchAlign
, ///< [out] pitch alignment in pixels
652 UINT_32
* pHeightAlign
///< [out] height alignment in pixels
655 BOOL_32 valid
= TRUE
;
659 case ADDR_TM_LINEAR_GENERAL
:
661 // The required base alignment and pitch and height granularities is to 1 element.
663 *pBaseAlign
= (bpp
> 8) ? bpp
/ 8 : 1;
667 case ADDR_TM_LINEAR_ALIGNED
:
669 // The required alignment for base is the pipe interleave size.
670 // The required granularity for pitch is hwl dependent.
671 // The required granularity for height is one row.
673 *pBaseAlign
= m_pipeInterleaveBytes
;
674 *pPitchAlign
= HwlGetPitchAlignmentLinear(bpp
, flags
);
681 ADDR_UNHANDLED_CASE();
685 AdjustPitchAlignment(flags
, pPitchAlign
);
691 ****************************************************************************************************
692 * EgBasedLib::ComputeSurfaceAlignmentsMicroTiled
695 * Compute 1D tiled surface alignment, calculation results are returned through
699 * TRUE if no error occurs
700 ****************************************************************************************************
702 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsMicroTiled(
703 AddrTileMode tileMode
, ///< [in] tile mode
704 UINT_32 bpp
, ///< [in] bits per pixel
705 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
706 UINT_32 mipLevel
, ///< [in] mip level
707 UINT_32 numSamples
, ///< [in] number of samples
708 UINT_32
* pBaseAlign
, ///< [out] base address alignment in bytes
709 UINT_32
* pPitchAlign
, ///< [out] pitch alignment in pixels
710 UINT_32
* pHeightAlign
///< [out] height alignment in pixels
713 BOOL_32 valid
= TRUE
;
716 // The required alignment for base is the pipe interleave size.
718 *pBaseAlign
= m_pipeInterleaveBytes
;
720 *pPitchAlign
= HwlGetPitchAlignmentMicroTiled(tileMode
, bpp
, flags
, numSamples
);
722 *pHeightAlign
= MicroTileHeight
;
724 AdjustPitchAlignment(flags
, pPitchAlign
);
727 // Workaround 2 for 1D tiling - There is HW bug for Carrizo
728 // where it requires the following alignments for 1D tiling.
729 if (flags
.czDispCompatible
&& (mipLevel
== 0))
731 *pBaseAlign
= PowTwoAlign(*pBaseAlign
, 4096); //Base address MOD 4096 = 0
732 *pPitchAlign
= PowTwoAlign(*pPitchAlign
, 512 / (BITS_TO_BYTES(bpp
))); //(8 lines * pitch * bytes per pixel) MOD 4096 = 0
734 // end Carrizo workaround for 1D tilling
741 ****************************************************************************************************
742 * EgBasedLib::HwlReduceBankWidthHeight
745 * Additional checks, reduce bankHeight/bankWidth if needed and possible
746 * tileSize*BANK_WIDTH*BANK_HEIGHT <= ROW_SIZE
749 * TRUE if no error occurs
750 ****************************************************************************************************
752 BOOL_32
EgBasedLib::HwlReduceBankWidthHeight(
753 UINT_32 tileSize
, ///< [in] tile size
754 UINT_32 bpp
, ///< [in] bits per pixel
755 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
756 UINT_32 numSamples
, ///< [in] number of samples
757 UINT_32 bankHeightAlign
, ///< [in] bank height alignment
758 UINT_32 pipes
, ///< [in] pipes
759 ADDR_TILEINFO
* pTileInfo
///< [in,out] bank structure.
762 UINT_32 macroAspectAlign
;
763 BOOL_32 valid
= TRUE
;
765 if (tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
)
767 BOOL_32 stillGreater
= TRUE
;
769 // Try reducing bankWidth first
770 if (stillGreater
&& pTileInfo
->bankWidth
> 1)
772 while (stillGreater
&& pTileInfo
->bankWidth
> 0)
774 pTileInfo
->bankWidth
>>= 1;
776 if (pTileInfo
->bankWidth
== 0)
778 pTileInfo
->bankWidth
= 1;
783 tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
;
786 // bankWidth is reduced above, so we need to recalculate bankHeight and ratio
787 bankHeightAlign
= Max(1u,
788 m_pipeInterleaveBytes
* m_bankInterleave
/
789 (tileSize
* pTileInfo
->bankWidth
)
792 // We cannot increase bankHeight so just assert this case.
793 ADDR_ASSERT((pTileInfo
->bankHeight
% bankHeightAlign
) == 0);
797 macroAspectAlign
= Max(1u,
798 m_pipeInterleaveBytes
* m_bankInterleave
/
799 (tileSize
* pipes
* pTileInfo
->bankWidth
)
801 pTileInfo
->macroAspectRatio
= PowTwoAlign(pTileInfo
->macroAspectRatio
,
806 // Early quit bank_height degradation for "64" bit z buffer
807 if (flags
.depth
&& bpp
>= 64)
809 stillGreater
= FALSE
;
812 // Then try reducing bankHeight
813 if (stillGreater
&& pTileInfo
->bankHeight
> bankHeightAlign
)
815 while (stillGreater
&& pTileInfo
->bankHeight
> bankHeightAlign
)
817 pTileInfo
->bankHeight
>>= 1;
819 if (pTileInfo
->bankHeight
< bankHeightAlign
)
821 pTileInfo
->bankHeight
= bankHeightAlign
;
826 tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
;
830 valid
= !stillGreater
;
832 // Generate a warning if we still fail to meet this constraint
836 0, ("TILE_SIZE(%d)*BANK_WIDTH(%d)*BANK_HEIGHT(%d) <= ROW_SIZE(%d)",
837 tileSize
, pTileInfo
->bankWidth
, pTileInfo
->bankHeight
, m_rowSize
));
845 ****************************************************************************************************
846 * EgBasedLib::ComputeSurfaceAlignmentsMacroTiled
849 * Compute 2D tiled surface alignment, calculation results are returned through
853 * TRUE if no error occurs
854 ****************************************************************************************************
856 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsMacroTiled(
857 AddrTileMode tileMode
, ///< [in] tile mode
858 UINT_32 bpp
, ///< [in] bits per pixel
859 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
860 UINT_32 mipLevel
, ///< [in] mip level
861 UINT_32 numSamples
, ///< [in] number of samples
862 ADDR_TILEINFO
* pTileInfo
, ///< [in,out] bank structure.
863 UINT_32
* pBaseAlign
, ///< [out] base address alignment in bytes
864 UINT_32
* pPitchAlign
, ///< [out] pitch alignment in pixels
865 UINT_32
* pHeightAlign
, ///< [out] height alignment in pixels
866 UINT_32
* pMacroTileWidth
, ///< [out] macro tile width in pixels
867 UINT_32
* pMacroTileHeight
///< [out] macro tile height in pixels
870 BOOL_32 valid
= SanityCheckMacroTiled(pTileInfo
);
874 UINT_32 macroTileWidth
;
875 UINT_32 macroTileHeight
;
878 UINT_32 bankHeightAlign
;
879 UINT_32 macroAspectAlign
;
881 UINT_32 thickness
= Thickness(tileMode
);
882 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
885 // Align bank height first according to latest h/w spec
888 // tile_size = MIN(tile_split, 64 * tile_thickness * element_bytes * num_samples)
889 tileSize
= Min(pTileInfo
->tileSplitBytes
,
890 BITS_TO_BYTES(64 * thickness
* bpp
* numSamples
));
892 // bank_height_align =
893 // MAX(1, (pipe_interleave_bytes * bank_interleave)/(tile_size*bank_width))
894 bankHeightAlign
= Max(1u,
895 m_pipeInterleaveBytes
* m_bankInterleave
/
896 (tileSize
* pTileInfo
->bankWidth
)
899 pTileInfo
->bankHeight
= PowTwoAlign(pTileInfo
->bankHeight
, bankHeightAlign
);
901 // num_pipes * bank_width * macro_tile_aspect >=
902 // (pipe_interleave_size * bank_interleave) / tile_size
905 // this restriction is only for mipmap (mipmap's numSamples must be 1)
906 macroAspectAlign
= Max(1u,
907 m_pipeInterleaveBytes
* m_bankInterleave
/
908 (tileSize
* pipes
* pTileInfo
->bankWidth
)
910 pTileInfo
->macroAspectRatio
= PowTwoAlign(pTileInfo
->macroAspectRatio
, macroAspectAlign
);
913 valid
= HwlReduceBankWidthHeight(tileSize
,
922 // The required granularity for pitch is the macro tile width.
924 macroTileWidth
= MicroTileWidth
* pTileInfo
->bankWidth
* pipes
*
925 pTileInfo
->macroAspectRatio
;
927 *pPitchAlign
= macroTileWidth
;
928 *pMacroTileWidth
= macroTileWidth
;
930 AdjustPitchAlignment(flags
, pPitchAlign
);
933 // The required granularity for height is the macro tile height.
935 macroTileHeight
= MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
/
936 pTileInfo
->macroAspectRatio
;
938 *pHeightAlign
= macroTileHeight
;
939 *pMacroTileHeight
= macroTileHeight
;
942 // Compute base alignment
944 *pBaseAlign
= pipes
*
945 pTileInfo
->bankWidth
* pTileInfo
->banks
* pTileInfo
->bankHeight
* tileSize
;
947 HwlComputeSurfaceAlignmentsMacroTiled(tileMode
, bpp
, flags
, mipLevel
, numSamples
,
948 pTileInfo
, pBaseAlign
, pPitchAlign
, pHeightAlign
,
949 pMacroTileWidth
, pMacroTileHeight
);
956 ****************************************************************************************************
957 * EgBasedLib::SanityCheckMacroTiled
960 * Check if macro-tiled parameters are valid
963 ****************************************************************************************************
965 BOOL_32
EgBasedLib::SanityCheckMacroTiled(
966 ADDR_TILEINFO
* pTileInfo
///< [in] macro-tiled parameters
969 BOOL_32 valid
= TRUE
;
970 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
972 switch (pTileInfo
->banks
)
974 case 2: //fall through
975 case 4: //fall through
976 case 8: //fall through
987 switch (pTileInfo
->bankWidth
)
989 case 1: //fall through
990 case 2: //fall through
991 case 4: //fall through
1002 switch (pTileInfo
->bankHeight
)
1004 case 1: //fall through
1005 case 2: //fall through
1006 case 4: //fall through
1017 switch (pTileInfo
->macroAspectRatio
)
1019 case 1: //fall through
1020 case 2: //fall through
1021 case 4: //fall through
1032 if (pTileInfo
->banks
< pTileInfo
->macroAspectRatio
)
1034 // This will generate macro tile height <= 1
1041 if (pTileInfo
->tileSplitBytes
> m_rowSize
)
1043 ADDR_WARN(0, ("tileSplitBytes is bigger than row size"));
1049 valid
= HwlSanityCheckMacroTiled(pTileInfo
);
1052 ADDR_ASSERT(valid
== TRUE
);
1054 // Add this assert for guidance
1055 ADDR_ASSERT(numPipes
* pTileInfo
->banks
>= 4);
1061 ****************************************************************************************************
1062 * EgBasedLib::ComputeSurfaceMipLevelTileMode
1065 * Compute valid tile mode for surface mipmap sub-levels
1068 * Suitable tile mode
1069 ****************************************************************************************************
1071 AddrTileMode
EgBasedLib::ComputeSurfaceMipLevelTileMode(
1072 AddrTileMode baseTileMode
, ///< [in] base tile mode
1073 UINT_32 bpp
, ///< [in] bits per pixels
1074 UINT_32 pitch
, ///< [in] current level pitch
1075 UINT_32 height
, ///< [in] current level height
1076 UINT_32 numSlices
, ///< [in] current number of slices
1077 UINT_32 numSamples
, ///< [in] number of samples
1078 UINT_32 pitchAlign
, ///< [in] pitch alignment
1079 UINT_32 heightAlign
, ///< [in] height alignment
1080 ADDR_TILEINFO
* pTileInfo
///< [in] ptr to bank structure
1083 UINT_32 bytesPerTile
;
1085 AddrTileMode expTileMode
= baseTileMode
;
1086 UINT_32 microTileThickness
= Thickness(expTileMode
);
1087 UINT_32 interleaveSize
= m_pipeInterleaveBytes
* m_bankInterleave
;
1090 // Compute the size of a slice.
1092 bytesPerTile
= BITS_TO_BYTES(MicroTilePixels
* microTileThickness
* NextPow2(bpp
) * numSamples
);
1095 // Reduce tiling mode from thick to thin if the number of slices is less than the
1096 // micro tile thickness.
1098 if (numSlices
< microTileThickness
)
1100 expTileMode
= HwlDegradeThickTileMode(expTileMode
, numSlices
, &bytesPerTile
);
1103 if (bytesPerTile
> pTileInfo
->tileSplitBytes
)
1105 bytesPerTile
= pTileInfo
->tileSplitBytes
;
1108 UINT_32 threshold1
=
1109 bytesPerTile
* HwlGetPipes(pTileInfo
) * pTileInfo
->bankWidth
* pTileInfo
->macroAspectRatio
;
1111 UINT_32 threshold2
=
1112 bytesPerTile
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
;
1115 // Reduce the tile mode from 2D/3D to 1D in following conditions
1117 switch (expTileMode
)
1119 case ADDR_TM_2D_TILED_THIN1
: //fall through
1120 case ADDR_TM_3D_TILED_THIN1
:
1121 case ADDR_TM_PRT_TILED_THIN1
:
1122 case ADDR_TM_PRT_2D_TILED_THIN1
:
1123 case ADDR_TM_PRT_3D_TILED_THIN1
:
1124 if ((pitch
< pitchAlign
) ||
1125 (height
< heightAlign
) ||
1126 (interleaveSize
> threshold1
) ||
1127 (interleaveSize
> threshold2
))
1129 expTileMode
= ADDR_TM_1D_TILED_THIN1
;
1132 case ADDR_TM_2D_TILED_THICK
: //fall through
1133 case ADDR_TM_3D_TILED_THICK
:
1134 case ADDR_TM_2D_TILED_XTHICK
:
1135 case ADDR_TM_3D_TILED_XTHICK
:
1136 case ADDR_TM_PRT_TILED_THICK
:
1137 case ADDR_TM_PRT_2D_TILED_THICK
:
1138 case ADDR_TM_PRT_3D_TILED_THICK
:
1139 if ((pitch
< pitchAlign
) ||
1140 (height
< heightAlign
))
1142 expTileMode
= ADDR_TM_1D_TILED_THICK
;
1153 ****************************************************************************************************
1154 * EgBasedLib::HwlGetAlignmentInfoMacroTiled
1156 * Get alignment info for giving tile mode
1158 * TRUE if getting alignment is OK
1159 ****************************************************************************************************
1161 BOOL_32
EgBasedLib::HwlGetAlignmentInfoMacroTiled(
1162 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] create surface info
1163 UINT_32
* pPitchAlign
, ///< [out] pitch alignment
1164 UINT_32
* pHeightAlign
, ///< [out] height alignment
1165 UINT_32
* pSizeAlign
///< [out] size alignment
1168 BOOL_32 valid
= TRUE
;
1170 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
1174 UINT_32 heightAlign
;
1175 UINT_32 macroTileWidth
;
1176 UINT_32 macroTileHeight
;
1177 UINT_32 numSamples
= (pIn
->numFrags
== 0) ? pIn
->numSamples
: pIn
->numFrags
;
1179 ADDR_ASSERT(pIn
->pTileInfo
);
1180 ADDR_TILEINFO tileInfo
= *pIn
->pTileInfo
;
1181 ADDR_COMPUTE_SURFACE_INFO_OUTPUT out
= {0};
1183 if (UseTileIndex(pIn
->tileIndex
))
1185 out
.tileIndex
= pIn
->tileIndex
;
1186 out
.macroModeIndex
= TileIndexInvalid
;
1189 HwlSetupTileInfo(pIn
->tileMode
,
1200 valid
= ComputeSurfaceAlignmentsMacroTiled(pIn
->tileMode
,
1214 *pPitchAlign
= pitchAlign
;
1215 *pHeightAlign
= heightAlign
;
1216 *pSizeAlign
= baseAlign
;
1223 ****************************************************************************************************
1224 * EgBasedLib::HwlDegradeThickTileMode
1227 * Degrades valid tile mode for thick modes if needed
1230 * Suitable tile mode
1231 ****************************************************************************************************
1233 AddrTileMode
EgBasedLib::HwlDegradeThickTileMode(
1234 AddrTileMode baseTileMode
, ///< [in] base tile mode
1235 UINT_32 numSlices
, ///< [in] current number of slices
1236 UINT_32
* pBytesPerTile
///< [in,out] pointer to bytes per slice
1239 ADDR_ASSERT(numSlices
< Thickness(baseTileMode
));
1240 // if pBytesPerTile is NULL, this is a don't-care....
1241 UINT_32 bytesPerTile
= pBytesPerTile
!= NULL
? *pBytesPerTile
: 64;
1243 AddrTileMode expTileMode
= baseTileMode
;
1244 switch (baseTileMode
)
1246 case ADDR_TM_1D_TILED_THICK
:
1247 expTileMode
= ADDR_TM_1D_TILED_THIN1
;
1250 case ADDR_TM_2D_TILED_THICK
:
1251 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1254 case ADDR_TM_3D_TILED_THICK
:
1255 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1258 case ADDR_TM_2D_TILED_XTHICK
:
1259 if (numSlices
< ThickTileThickness
)
1261 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1266 expTileMode
= ADDR_TM_2D_TILED_THICK
;
1270 case ADDR_TM_3D_TILED_XTHICK
:
1271 if (numSlices
< ThickTileThickness
)
1273 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1278 expTileMode
= ADDR_TM_3D_TILED_THICK
;
1283 ADDR_ASSERT_ALWAYS();
1287 if (pBytesPerTile
!= NULL
)
1289 *pBytesPerTile
= bytesPerTile
;
1296 ****************************************************************************************************
1297 * EgBasedLib::DispatchComputeSurfaceAddrFromCoord
1300 * Compute surface address from given coord (x, y, slice,sample)
1304 ****************************************************************************************************
1306 UINT_64
EgBasedLib::DispatchComputeSurfaceAddrFromCoord(
1307 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1308 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1313 UINT_32 slice
= pIn
->slice
;
1314 UINT_32 sample
= pIn
->sample
;
1315 UINT_32 bpp
= pIn
->bpp
;
1316 UINT_32 pitch
= pIn
->pitch
;
1317 UINT_32 height
= pIn
->height
;
1318 UINT_32 numSlices
= pIn
->numSlices
;
1319 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
1320 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
1321 AddrTileMode tileMode
= pIn
->tileMode
;
1322 AddrTileType microTileType
= pIn
->tileType
;
1323 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
1324 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
1325 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
1327 UINT_32
* pBitPosition
= &pOut
->bitPosition
;
1331 UINT_32 addr5Bit
= 0;
1332 UINT_32 addr5Swizzle
= pIn
->addr5Swizzle
;
1333 BOOL_32 is32ByteTile
= pIn
->is32ByteTile
;
1336 // ADDR_DEPTH_SAMPLE_ORDER = non-disp + depth-sample-order
1337 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
1339 isDepthSampleOrder
= TRUE
;
1342 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
1344 if (numFrags
!= numSamples
)
1346 numSamples
= numFrags
;
1347 ADDR_ASSERT(sample
< numSamples
);
1351 /// 128 bit/thick tiled surface doesn't support display tiling and
1352 /// mipmap chain must have the same tileType, so please fill tileType correctly
1353 if (IsLinear(pIn
->tileMode
) == FALSE
)
1355 if (bpp
>= 128 || Thickness(tileMode
) > 1)
1357 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
1364 case ADDR_TM_LINEAR_GENERAL
://fall through
1365 case ADDR_TM_LINEAR_ALIGNED
:
1366 addr
= ComputeSurfaceAddrFromCoordLinear(x
,
1376 case ADDR_TM_1D_TILED_THIN1
://fall through
1377 case ADDR_TM_1D_TILED_THICK
:
1378 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
1391 case ADDR_TM_2D_TILED_THIN1
: //fall through
1392 case ADDR_TM_2D_TILED_THICK
: //fall through
1393 case ADDR_TM_3D_TILED_THIN1
: //fall through
1394 case ADDR_TM_3D_TILED_THICK
: //fall through
1395 case ADDR_TM_2D_TILED_XTHICK
: //fall through
1396 case ADDR_TM_3D_TILED_XTHICK
: //fall through
1397 case ADDR_TM_PRT_TILED_THIN1
: //fall through
1398 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
1399 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
1400 case ADDR_TM_PRT_TILED_THICK
: //fall through
1401 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
1402 case ADDR_TM_PRT_3D_TILED_THICK
:
1403 UINT_32 pipeSwizzle
;
1404 UINT_32 bankSwizzle
;
1406 if (m_configFlags
.useCombinedSwizzle
)
1408 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
1409 &bankSwizzle
, &pipeSwizzle
);
1413 pipeSwizzle
= pIn
->pipeSwizzle
;
1414 bankSwizzle
= pIn
->bankSwizzle
;
1417 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
1436 ADDR_ASSERT_ALWAYS();
1441 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
1443 if (addr5Swizzle
&& isDepthSampleOrder
&& is32ByteTile
)
1445 UINT_32 tx
= x
>> 3;
1446 UINT_32 ty
= y
>> 3;
1447 UINT_32 tileBits
= ((ty
&0x3) << 2) | (tx
&0x3);
1449 tileBits
= tileBits
& addr5Swizzle
;
1450 addr5Bit
= XorReduce(tileBits
, 4);
1452 addr
= addr
| static_cast<UINT_64
>(addr5Bit
<< 5);
1461 ****************************************************************************************************
1462 * EgBasedLib::ComputeMacroTileEquation
1465 * Computes the address equation in macro tile
1467 * If equation can be computed
1468 ****************************************************************************************************
1470 ADDR_E_RETURNCODE
EgBasedLib::ComputeMacroTileEquation(
1471 UINT_32 log2BytesPP
, ///< [in] log2 of bytes per pixel
1472 AddrTileMode tileMode
, ///< [in] tile mode
1473 AddrTileType microTileType
, ///< [in] micro tiling type
1474 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure
1475 ADDR_EQUATION
* pEquation
///< [out] Equation for addressing in macro tile
1478 ADDR_E_RETURNCODE retCode
;
1480 // Element equation within a tile
1481 retCode
= ComputeMicroTileEquation(log2BytesPP
, tileMode
, microTileType
, pEquation
);
1483 if (retCode
== ADDR_OK
)
1485 // Tile equesiton with signle pipe bank
1486 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1487 UINT_32 numPipeBits
= Log2(numPipes
);
1489 for (UINT_32 i
= 0; i
< Log2(pTileInfo
->bankWidth
); i
++)
1491 pEquation
->addr
[pEquation
->numBits
].valid
= 1;
1492 pEquation
->addr
[pEquation
->numBits
].channel
= 0;
1493 pEquation
->addr
[pEquation
->numBits
].index
= i
+ log2BytesPP
+ 3 + numPipeBits
;
1494 pEquation
->numBits
++;
1497 for (UINT_32 i
= 0; i
< Log2(pTileInfo
->bankHeight
); i
++)
1499 pEquation
->addr
[pEquation
->numBits
].valid
= 1;
1500 pEquation
->addr
[pEquation
->numBits
].channel
= 1;
1501 pEquation
->addr
[pEquation
->numBits
].index
= i
+ 3;
1502 pEquation
->numBits
++;
1505 ADDR_EQUATION equation
;
1506 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
1508 UINT_32 thresholdX
= 32;
1509 UINT_32 thresholdY
= 32;
1511 if (IsPrtNoRotationTileMode(tileMode
))
1513 UINT_32 macroTilePitch
=
1514 (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
) * pTileInfo
->macroAspectRatio
;
1515 UINT_32 macroTileHeight
=
1516 (MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
) /
1517 pTileInfo
->macroAspectRatio
;
1518 thresholdX
= Log2(macroTilePitch
);
1519 thresholdY
= Log2(macroTileHeight
);
1523 retCode
= ComputePipeEquation(log2BytesPP
, thresholdX
, thresholdY
, pTileInfo
, &equation
);
1525 if (retCode
== ADDR_OK
)
1527 UINT_32 pipeBitStart
= Log2(m_pipeInterleaveBytes
);
1529 if (pEquation
->numBits
> pipeBitStart
)
1531 UINT_32 numLeftShift
= pEquation
->numBits
- pipeBitStart
;
1533 for (UINT_32 i
= 0; i
< numLeftShift
; i
++)
1535 pEquation
->addr
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1536 pEquation
->addr
[pEquation
->numBits
- i
- 1];
1537 pEquation
->xor1
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1538 pEquation
->xor1
[pEquation
->numBits
- i
- 1];
1539 pEquation
->xor2
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1540 pEquation
->xor2
[pEquation
->numBits
- i
- 1];
1544 for (UINT_32 i
= 0; i
< equation
.numBits
; i
++)
1546 pEquation
->addr
[pipeBitStart
+ i
] = equation
.addr
[i
];
1547 pEquation
->xor1
[pipeBitStart
+ i
] = equation
.xor1
[i
];
1548 pEquation
->xor2
[pipeBitStart
+ i
] = equation
.xor2
[i
];
1549 pEquation
->numBits
++;
1553 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
1555 retCode
= ComputeBankEquation(log2BytesPP
, thresholdX
, thresholdY
,
1556 pTileInfo
, &equation
);
1558 if (retCode
== ADDR_OK
)
1560 UINT_32 bankBitStart
= pipeBitStart
+ numPipeBits
+ Log2(m_bankInterleave
);
1562 if (pEquation
->numBits
> bankBitStart
)
1564 UINT_32 numLeftShift
= pEquation
->numBits
- bankBitStart
;
1566 for (UINT_32 i
= 0; i
< numLeftShift
; i
++)
1568 pEquation
->addr
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1569 pEquation
->addr
[pEquation
->numBits
- i
- 1];
1570 pEquation
->xor1
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1571 pEquation
->xor1
[pEquation
->numBits
- i
- 1];
1572 pEquation
->xor2
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1573 pEquation
->xor2
[pEquation
->numBits
- i
- 1];
1577 for (UINT_32 i
= 0; i
< equation
.numBits
; i
++)
1579 pEquation
->addr
[bankBitStart
+ i
] = equation
.addr
[i
];
1580 pEquation
->xor1
[bankBitStart
+ i
] = equation
.xor1
[i
];
1581 pEquation
->xor2
[bankBitStart
+ i
] = equation
.xor2
[i
];
1582 pEquation
->numBits
++;
1592 ****************************************************************************************************
1593 * EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1596 * Computes the surface address and bit position from a
1597 * coordinate for 2D tilied (macro tiled)
1600 ****************************************************************************************************
1602 UINT_64
EgBasedLib::ComputeSurfaceAddrFromCoordMacroTiled(
1603 UINT_32 x
, ///< [in] x coordinate
1604 UINT_32 y
, ///< [in] y coordinate
1605 UINT_32 slice
, ///< [in] slice index
1606 UINT_32 sample
, ///< [in] sample index
1607 UINT_32 bpp
, ///< [in] bits per pixel
1608 UINT_32 pitch
, ///< [in] surface pitch, in pixels
1609 UINT_32 height
, ///< [in] surface height, in pixels
1610 UINT_32 numSamples
, ///< [in] number of samples
1611 AddrTileMode tileMode
, ///< [in] tile mode
1612 AddrTileType microTileType
, ///< [in] micro tiling type
1613 BOOL_32 ignoreSE
, ///< [in] TRUE if shader enginers can be ignored
1614 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if it depth sample ordering is used
1615 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
1616 UINT_32 bankSwizzle
, ///< [in] bank swizzle
1617 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure
1618 /// **All fields to be valid on entry**
1619 UINT_32
* pBitPosition
///< [out] bit position, e.g. FMT_1 will use this
1624 UINT_32 microTileBytes
;
1625 UINT_32 microTileBits
;
1626 UINT_32 sampleOffset
;
1628 UINT_32 pixelOffset
;
1629 UINT_32 elementOffset
;
1630 UINT_32 tileSplitSlice
;
1634 UINT_64 sliceOffset
;
1635 UINT_32 macroTilePitch
;
1636 UINT_32 macroTileHeight
;
1637 UINT_32 macroTilesPerRow
;
1638 UINT_32 macroTilesPerSlice
;
1639 UINT_64 macroTileBytes
;
1640 UINT_32 macroTileIndexX
;
1641 UINT_32 macroTileIndexY
;
1642 UINT_64 macroTileOffset
;
1643 UINT_64 totalOffset
;
1644 UINT_64 pipeInterleaveMask
;
1645 UINT_64 bankInterleaveMask
;
1646 UINT_64 pipeInterleaveOffset
;
1647 UINT_32 bankInterleaveOffset
;
1649 UINT_32 tileRowIndex
;
1650 UINT_32 tileColumnIndex
;
1654 UINT_32 microTileThickness
= Thickness(tileMode
);
1657 // Compute the number of group, pipe, and bank bits.
1659 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1660 UINT_32 numPipeInterleaveBits
= Log2(m_pipeInterleaveBytes
);
1661 UINT_32 numPipeBits
= Log2(numPipes
);
1662 UINT_32 numBankInterleaveBits
= Log2(m_bankInterleave
);
1663 UINT_32 numBankBits
= Log2(pTileInfo
->banks
);
1666 // Compute the micro tile size.
1668 microTileBits
= MicroTilePixels
* microTileThickness
* bpp
* numSamples
;
1670 microTileBytes
= microTileBits
/ 8;
1672 // Compute the pixel index within the micro tile.
1674 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
1682 // Compute the sample offset and pixel offset.
1684 if (isDepthSampleOrder
)
1687 // For depth surfaces, samples are stored contiguously for each element, so the sample
1688 // offset is the sample number times the element size.
1690 sampleOffset
= sample
* bpp
;
1691 pixelOffset
= pixelIndex
* bpp
* numSamples
;
1696 // For color surfaces, all elements for a particular sample are stored contiguously, so
1697 // the sample offset is the sample number times the micro tile size divided yBit the number
1700 sampleOffset
= sample
* (microTileBits
/ numSamples
);
1701 pixelOffset
= pixelIndex
* bpp
;
1705 // Compute the element offset.
1707 elementOffset
= pixelOffset
+ sampleOffset
;
1709 *pBitPosition
= static_cast<UINT_32
>(elementOffset
% 8);
1711 elementOffset
/= 8; //bit-to-byte
1714 // Determine if tiles need to be split across slices.
1716 // If the size of the micro tile is larger than the tile split size, then the tile will be
1717 // split across multiple slices.
1719 UINT_32 slicesPerTile
= 1;
1721 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
1722 { //don't support for thick mode
1725 // Compute the number of slices per tile.
1727 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
1730 // Compute the tile split slice number for use in rotating the bank.
1732 tileSplitSlice
= elementOffset
/ pTileInfo
->tileSplitBytes
;
1735 // Adjust the element offset to account for the portion of the tile that is being moved to
1738 elementOffset
%= pTileInfo
->tileSplitBytes
;
1741 // Adjust the microTileBytes size to tileSplitBytes size since
1744 microTileBytes
= pTileInfo
->tileSplitBytes
;
1752 // Compute macro tile pitch and height.
1755 (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
) * pTileInfo
->macroAspectRatio
;
1757 (MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
) / pTileInfo
->macroAspectRatio
;
1760 // Compute the number of bytes per macro tile. Note: bytes of the same bank/pipe actually
1763 static_cast<UINT_64
>(microTileBytes
) *
1764 (macroTilePitch
/ MicroTileWidth
) * (macroTileHeight
/ MicroTileHeight
) /
1765 (numPipes
* pTileInfo
->banks
);
1768 // Compute the number of macro tiles per row.
1770 macroTilesPerRow
= pitch
/ macroTilePitch
;
1773 // Compute the offset to the macro tile containing the specified coordinate.
1775 macroTileIndexX
= x
/ macroTilePitch
;
1776 macroTileIndexY
= y
/ macroTileHeight
;
1777 macroTileOffset
= ((macroTileIndexY
* macroTilesPerRow
) + macroTileIndexX
) * macroTileBytes
;
1780 // Compute the number of macro tiles per slice.
1782 macroTilesPerSlice
= macroTilesPerRow
* (height
/ macroTileHeight
);
1785 // Compute the slice size.
1787 sliceBytes
= macroTilesPerSlice
* macroTileBytes
;
1790 // Compute the slice offset.
1792 sliceOffset
= sliceBytes
* (tileSplitSlice
+ slicesPerTile
* (slice
/ microTileThickness
));
1795 // Compute tile offest
1797 tileRowIndex
= (y
/ MicroTileHeight
) % pTileInfo
->bankHeight
;
1798 tileColumnIndex
= ((x
/ MicroTileWidth
) / numPipes
) % pTileInfo
->bankWidth
;
1799 tileIndex
= (tileRowIndex
* pTileInfo
->bankWidth
) + tileColumnIndex
;
1800 tileOffset
= tileIndex
* microTileBytes
;
1803 // Combine the slice offset and macro tile offset with the pixel and sample offsets, accounting
1804 // for the pipe and bank bits in the middle of the address.
1806 totalOffset
= sliceOffset
+ macroTileOffset
+ elementOffset
+ tileOffset
;
1809 // Get the pipe and bank.
1812 // when the tileMode is PRT type, then adjust x and y coordinates
1813 if (IsPrtNoRotationTileMode(tileMode
))
1815 x
= x
% macroTilePitch
;
1816 y
= y
% macroTileHeight
;
1819 pipe
= ComputePipeFromCoord(x
,
1827 bank
= ComputeBankFromCoord(x
,
1837 // Split the offset to put some bits below the pipe+bank bits and some above.
1839 pipeInterleaveMask
= (1 << numPipeInterleaveBits
) - 1;
1840 bankInterleaveMask
= (1 << numBankInterleaveBits
) - 1;
1841 pipeInterleaveOffset
= totalOffset
& pipeInterleaveMask
;
1842 bankInterleaveOffset
= static_cast<UINT_32
>((totalOffset
>> numPipeInterleaveBits
) &
1843 bankInterleaveMask
);
1844 offset
= totalOffset
>> (numPipeInterleaveBits
+ numBankInterleaveBits
);
1847 // Assemble the address from its components.
1849 addr
= pipeInterleaveOffset
;
1850 // This is to remove /analyze warnings
1851 UINT_32 pipeBits
= pipe
<< numPipeInterleaveBits
;
1852 UINT_32 bankInterleaveBits
= bankInterleaveOffset
<< (numPipeInterleaveBits
+ numPipeBits
);
1853 UINT_32 bankBits
= bank
<< (numPipeInterleaveBits
+ numPipeBits
+
1854 numBankInterleaveBits
);
1855 UINT_64 offsetBits
= offset
<< (numPipeInterleaveBits
+ numPipeBits
+
1856 numBankInterleaveBits
+ numBankBits
);
1859 addr
|= bankInterleaveBits
;
1867 ****************************************************************************************************
1868 * EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1871 * Computes the surface address and bit position from a coordinate for 1D tilied
1875 ****************************************************************************************************
1877 UINT_64
EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled(
1878 UINT_32 x
, ///< [in] x coordinate
1879 UINT_32 y
, ///< [in] y coordinate
1880 UINT_32 slice
, ///< [in] slice index
1881 UINT_32 sample
, ///< [in] sample index
1882 UINT_32 bpp
, ///< [in] bits per pixel
1883 UINT_32 pitch
, ///< [in] pitch, in pixels
1884 UINT_32 height
, ///< [in] height, in pixels
1885 UINT_32 numSamples
, ///< [in] number of samples
1886 AddrTileMode tileMode
, ///< [in] tile mode
1887 AddrTileType microTileType
, ///< [in] micro tiling type
1888 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if depth sample ordering is used
1889 UINT_32
* pBitPosition
///< [out] bit position, e.g. FMT_1 will use this
1894 UINT_32 microTileBytes
;
1896 UINT_32 microTilesPerRow
;
1897 UINT_32 microTileIndexX
;
1898 UINT_32 microTileIndexY
;
1899 UINT_32 microTileIndexZ
;
1900 UINT_64 sliceOffset
;
1901 UINT_64 microTileOffset
;
1902 UINT_32 sampleOffset
;
1904 UINT_32 pixelOffset
;
1906 UINT_32 microTileThickness
= Thickness(tileMode
);
1909 // Compute the micro tile size.
1911 microTileBytes
= BITS_TO_BYTES(MicroTilePixels
* microTileThickness
* bpp
* numSamples
);
1914 // Compute the slice size.
1917 BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* microTileThickness
* bpp
* numSamples
);
1920 // Compute the number of micro tiles per row.
1922 microTilesPerRow
= pitch
/ MicroTileWidth
;
1925 // Compute the micro tile index.
1927 microTileIndexX
= x
/ MicroTileWidth
;
1928 microTileIndexY
= y
/ MicroTileHeight
;
1929 microTileIndexZ
= slice
/ microTileThickness
;
1932 // Compute the slice offset.
1934 sliceOffset
= static_cast<UINT_64
>(microTileIndexZ
) * sliceBytes
;
1937 // Compute the offset to the micro tile containing the specified coordinate.
1939 microTileOffset
= (static_cast<UINT_64
>(microTileIndexY
) * microTilesPerRow
+ microTileIndexX
) *
1943 // Compute the pixel index within the micro tile.
1945 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
1952 // Compute the sample offset.
1954 if (isDepthSampleOrder
)
1957 // For depth surfaces, samples are stored contiguously for each element, so the sample
1958 // offset is the sample number times the element size.
1960 sampleOffset
= sample
* bpp
;
1961 pixelOffset
= pixelIndex
* bpp
* numSamples
;
1966 // For color surfaces, all elements for a particular sample are stored contiguously, so
1967 // the sample offset is the sample number times the micro tile size divided yBit the number
1970 sampleOffset
= sample
* (microTileBytes
*8 / numSamples
);
1971 pixelOffset
= pixelIndex
* bpp
;
1975 // Compute the bit position of the pixel. Each element is stored with one bit per sample.
1978 UINT_32 elemOffset
= sampleOffset
+ pixelOffset
;
1980 *pBitPosition
= elemOffset
% 8;
1984 // Combine the slice offset, micro tile offset, sample offset, and pixel offsets.
1986 addr
= sliceOffset
+ microTileOffset
+ elemOffset
;
1992 ****************************************************************************************************
1993 * EgBasedLib::HwlComputePixelCoordFromOffset
1996 * Compute pixel coordinate from offset inside a micro tile
1999 ****************************************************************************************************
2001 VOID
EgBasedLib::HwlComputePixelCoordFromOffset(
2002 UINT_32 offset
, ///< [in] offset inside micro tile in bits
2003 UINT_32 bpp
, ///< [in] bits per pixel
2004 UINT_32 numSamples
, ///< [in] number of samples
2005 AddrTileMode tileMode
, ///< [in] tile mode
2006 UINT_32 tileBase
, ///< [in] base offset within a tile
2007 UINT_32 compBits
, ///< [in] component bits actually needed(for planar surface)
2008 UINT_32
* pX
, ///< [out] x coordinate
2009 UINT_32
* pY
, ///< [out] y coordinate
2010 UINT_32
* pSlice
, ///< [out] slice index
2011 UINT_32
* pSample
, ///< [out] sample index
2012 AddrTileType microTileType
, ///< [in] micro tiling type
2013 BOOL_32 isDepthSampleOrder
///< [in] TRUE if depth sample order in microtile is used
2019 UINT_32 thickness
= Thickness(tileMode
);
2021 // For planar surface, we adjust offset acoording to tile base
2022 if ((bpp
!= compBits
) && (compBits
!= 0) && isDepthSampleOrder
)
2026 ADDR_ASSERT(microTileType
== ADDR_NON_DISPLAYABLE
||
2027 microTileType
== ADDR_DEPTH_SAMPLE_ORDER
);
2032 UINT_32 sampleTileBits
;
2033 UINT_32 samplePixelBits
;
2036 if (isDepthSampleOrder
)
2038 samplePixelBits
= bpp
* numSamples
;
2039 pixelIndex
= offset
/ samplePixelBits
;
2040 *pSample
= (offset
% samplePixelBits
) / bpp
;
2044 sampleTileBits
= MicroTilePixels
* bpp
* thickness
;
2045 *pSample
= offset
/ sampleTileBits
;
2046 pixelIndex
= (offset
% sampleTileBits
) / bpp
;
2049 if (microTileType
!= ADDR_THICK
)
2051 if (microTileType
== ADDR_DISPLAYABLE
) // displayable
2056 x
= pixelIndex
& 0x7;
2057 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,4));
2060 x
= pixelIndex
& 0x7;
2061 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,3));
2064 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,1),_BIT(pixelIndex
,0));
2065 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,2));
2068 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2069 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
2072 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,2),_BIT(pixelIndex
,1));
2073 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,0));
2079 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2081 x
= Bits2Number(3, _BIT(pixelIndex
,4),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2082 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
2084 else if (microTileType
== ADDR_ROTATED
)
2088 element_index[5:0] = { x[2], x[0], x[1], y[2], y[1], y[0] }
2091 element_index[5:0] = { x[2], x[1], x[0], y[2], y[1], y[0] }
2094 element_index[5:0] = { x[2], x[1], y[2], x[0], y[1], y[0] }
2097 element_index[5:0] = { y[2], x[2], x[1], y[1], x[0], y[0] }
2102 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,4));
2103 y
= pixelIndex
& 0x7;
2106 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,3));
2107 y
= pixelIndex
& 0x7;
2110 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,2));
2111 y
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,1),_BIT(pixelIndex
,0));
2114 x
= Bits2Number(3, _BIT(pixelIndex
,4),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
2115 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2118 ADDR_ASSERT_ALWAYS();
2123 if (thickness
> 1) // thick
2125 z
= Bits2Number(3, _BIT(pixelIndex
,8),_BIT(pixelIndex
,7),_BIT(pixelIndex
,6));
2130 ADDR_ASSERT((m_chipFamily
>= ADDR_CHIP_FAMILY_CI
) && (thickness
> 1));
2132 8-Bit Elements and 16-Bit Elements
2133 element_index[7:0] = { y[2], x[2], z[1], z[0], y[1], x[1], y[0], x[0] }
2136 element_index[7:0] = { y[2], x[2], z[1], y[1], z[0], x[1], y[0], x[0] }
2138 64-Bit Elements and 128-Bit Elements
2139 element_index[7:0] = { y[2], x[2], z[1], y[1], x[1], z[0], y[0], x[0] }
2141 The equation to compute the element index for the extra thick tile:
2142 element_index[8] = z[2]
2147 case 16: // fall-through
2148 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2149 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
2150 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4));
2153 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2154 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
2155 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3));
2158 case 128: // fall-through
2159 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,3),_BIT(pixelIndex
,0));
2160 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
2161 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,2));
2164 ADDR_ASSERT_ALWAYS();
2170 z
+= Bits2Number(3,_BIT(pixelIndex
,8),0,0);
2181 ****************************************************************************************************
2182 * EgBasedLib::DispatchComputeSurfaceCoordFromAddrDispatch
2185 * Compute (x,y,slice,sample) coordinates from surface address
2188 ****************************************************************************************************
2190 VOID
EgBasedLib::DispatchComputeSurfaceCoordFromAddr(
2191 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
2192 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
2195 UINT_64 addr
= pIn
->addr
;
2196 UINT_32 bitPosition
= pIn
->bitPosition
;
2197 UINT_32 bpp
= pIn
->bpp
;
2198 UINT_32 pitch
= pIn
->pitch
;
2199 UINT_32 height
= pIn
->height
;
2200 UINT_32 numSlices
= pIn
->numSlices
;
2201 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
2202 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
2203 AddrTileMode tileMode
= pIn
->tileMode
;
2204 UINT_32 tileBase
= pIn
->tileBase
;
2205 UINT_32 compBits
= pIn
->compBits
;
2206 AddrTileType microTileType
= pIn
->tileType
;
2207 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
2208 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
2209 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2211 UINT_32
* pX
= &pOut
->x
;
2212 UINT_32
* pY
= &pOut
->y
;
2213 UINT_32
* pSlice
= &pOut
->slice
;
2214 UINT_32
* pSample
= &pOut
->sample
;
2216 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2218 isDepthSampleOrder
= TRUE
;
2221 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
2223 if (numFrags
!= numSamples
)
2225 numSamples
= numFrags
;
2229 /// 128 bit/thick tiled surface doesn't support display tiling and
2230 /// mipmap chain must have the same tileType, so please fill tileType correctly
2231 if (IsLinear(pIn
->tileMode
) == FALSE
)
2233 if (bpp
>= 128 || Thickness(tileMode
) > 1)
2235 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
2242 case ADDR_TM_LINEAR_GENERAL
://fall through
2243 case ADDR_TM_LINEAR_ALIGNED
:
2244 ComputeSurfaceCoordFromAddrLinear(addr
,
2255 case ADDR_TM_1D_TILED_THIN1
://fall through
2256 case ADDR_TM_1D_TILED_THICK
:
2257 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
2271 isDepthSampleOrder
);
2273 case ADDR_TM_2D_TILED_THIN1
: //fall through
2274 case ADDR_TM_2D_TILED_THICK
: //fall through
2275 case ADDR_TM_3D_TILED_THIN1
: //fall through
2276 case ADDR_TM_3D_TILED_THICK
: //fall through
2277 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2278 case ADDR_TM_3D_TILED_XTHICK
: //fall through
2279 case ADDR_TM_PRT_TILED_THIN1
: //fall through
2280 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
2281 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
2282 case ADDR_TM_PRT_TILED_THICK
: //fall through
2283 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
2284 case ADDR_TM_PRT_3D_TILED_THICK
:
2285 UINT_32 pipeSwizzle
;
2286 UINT_32 bankSwizzle
;
2288 if (m_configFlags
.useCombinedSwizzle
)
2290 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
2291 &bankSwizzle
, &pipeSwizzle
);
2295 pipeSwizzle
= pIn
->pipeSwizzle
;
2296 bankSwizzle
= pIn
->bankSwizzle
;
2299 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
2320 ADDR_ASSERT_ALWAYS();
2326 ****************************************************************************************************
2327 * EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled
2330 * Compute surface coordinates from address for macro tiled surface
2333 ****************************************************************************************************
2335 VOID
EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled(
2336 UINT_64 addr
, ///< [in] byte address
2337 UINT_32 bitPosition
, ///< [in] bit position
2338 UINT_32 bpp
, ///< [in] bits per pixel
2339 UINT_32 pitch
, ///< [in] pitch in pixels
2340 UINT_32 height
, ///< [in] height in pixels
2341 UINT_32 numSamples
, ///< [in] number of samples
2342 AddrTileMode tileMode
, ///< [in] tile mode
2343 UINT_32 tileBase
, ///< [in] tile base offset
2344 UINT_32 compBits
, ///< [in] component bits (for planar surface)
2345 AddrTileType microTileType
, ///< [in] micro tiling type
2346 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines can be ignored
2347 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if depth sample order is used
2348 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2349 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2350 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure.
2351 /// **All fields to be valid on entry**
2352 UINT_32
* pX
, ///< [out] X coord
2353 UINT_32
* pY
, ///< [out] Y coord
2354 UINT_32
* pSlice
, ///< [out] slice index
2355 UINT_32
* pSample
///< [out] sample index
2361 UINT_64 macroTileBits
;
2364 UINT_64 elementOffset
;
2365 UINT_64 macroTileIndex
;
2367 UINT_64 totalOffset
;
2372 UINT_32 groupBits
= m_pipeInterleaveBytes
<< 3;
2373 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2374 UINT_32 banks
= pTileInfo
->banks
;
2376 UINT_32 bankInterleave
= m_bankInterleave
;
2378 UINT_64 addrBits
= BYTES_TO_BITS(addr
) + bitPosition
;
2381 // remove bits for bank and pipe
2383 totalOffset
= (addrBits
% groupBits
) +
2384 (((addrBits
/ groupBits
/ pipes
) % bankInterleave
) * groupBits
) +
2385 (((addrBits
/ groupBits
/ pipes
) / bankInterleave
) / banks
) * groupBits
* bankInterleave
;
2387 UINT_32 microTileThickness
= Thickness(tileMode
);
2389 UINT_32 microTileBits
= bpp
* microTileThickness
* MicroTilePixels
* numSamples
;
2391 UINT_32 microTileBytes
= BITS_TO_BYTES(microTileBits
);
2393 // Determine if tiles need to be split across slices.
2395 // If the size of the micro tile is larger than the tile split size, then the tile will be
2396 // split across multiple slices.
2398 UINT_32 slicesPerTile
= 1; //_State->TileSlices
2400 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
2401 { //don't support for thick mode
2404 // Compute the number of slices per tile.
2406 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
2409 tileBits
= microTileBits
/ slicesPerTile
; // micro tile bits
2411 // in micro tiles because not MicroTileWidth timed.
2412 UINT_32 macroWidth
= pTileInfo
->bankWidth
* pipes
* pTileInfo
->macroAspectRatio
;
2413 // in micro tiles as well
2414 UINT_32 macroHeight
= pTileInfo
->bankHeight
* banks
/ pTileInfo
->macroAspectRatio
;
2416 UINT_32 pitchInMacroTiles
= pitch
/ MicroTileWidth
/ macroWidth
;
2418 macroTileBits
= (macroWidth
* macroHeight
) * tileBits
/ (banks
* pipes
);
2420 macroTileIndex
= totalOffset
/ macroTileBits
;
2422 // pitchMacros * height / heightMacros; macroTilesPerSlice == _State->SliceMacros
2423 UINT_32 macroTilesPerSlice
= (pitch
/ (macroWidth
* MicroTileWidth
)) * height
/
2424 (macroHeight
* MicroTileWidth
);
2426 slices
= static_cast<UINT_32
>(macroTileIndex
/ macroTilesPerSlice
);
2428 *pSlice
= static_cast<UINT_32
>(slices
/ slicesPerTile
* microTileThickness
);
2431 // calculate element offset and x[2:0], y[2:0], z[1:0] for thick
2433 tileSlices
= slices
% slicesPerTile
;
2435 elementOffset
= tileSlices
* tileBits
;
2436 elementOffset
+= totalOffset
% tileBits
;
2440 HwlComputePixelCoordFromOffset(static_cast<UINT_32
>(elementOffset
),
2451 isDepthSampleOrder
);
2453 macroTileIndex
= macroTileIndex
% macroTilesPerSlice
;
2454 *pY
+= static_cast<UINT_32
>(macroTileIndex
/ pitchInMacroTiles
* macroHeight
* MicroTileHeight
);
2455 *pX
+= static_cast<UINT_32
>(macroTileIndex
% pitchInMacroTiles
* macroWidth
* MicroTileWidth
);
2459 tileIndex
= static_cast<UINT_32
>((totalOffset
% macroTileBits
) / tileBits
);
2461 my
= (tileIndex
/ pTileInfo
->bankWidth
) % pTileInfo
->bankHeight
* MicroTileHeight
;
2462 mx
= (tileIndex
% pTileInfo
->bankWidth
) * pipes
* MicroTileWidth
;
2467 bank
= ComputeBankFromAddr(addr
, banks
, pipes
);
2468 pipe
= ComputePipeFromAddr(addr
, pipes
);
2470 HwlComputeSurfaceCoord2DFromBankPipe(tileMode
,
2484 ****************************************************************************************************
2485 * EgBasedLib::ComputeSurfaceCoord2DFromBankPipe
2488 * Compute surface x,y coordinates from bank/pipe info
2491 ****************************************************************************************************
2493 VOID
EgBasedLib::ComputeSurfaceCoord2DFromBankPipe(
2494 AddrTileMode tileMode
, ///< [in] tile mode
2495 UINT_32 x
, ///< [in] x coordinate
2496 UINT_32 y
, ///< [in] y coordinate
2497 UINT_32 slice
, ///< [in] slice index
2498 UINT_32 bank
, ///< [in] bank number
2499 UINT_32 pipe
, ///< [in] pipe number
2500 UINT_32 bankSwizzle
,///< [in] bank swizzle
2501 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
2502 UINT_32 tileSlices
, ///< [in] slices in a micro tile
2503 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure. **All fields to be valid on entry**
2504 CoordFromBankPipe
* pOutput
///< [out] pointer to extracted x/y bits
2516 UINT_32 tileSplitRotation
;
2518 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2520 UINT_32 bankRotation
= ComputeBankRotation(tileMode
,
2521 pTileInfo
->banks
, numPipes
);
2523 UINT_32 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2525 UINT_32 xBit
= x
/ (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
);
2526 UINT_32 yBit
= y
/ (MicroTileHeight
* pTileInfo
->bankHeight
);
2528 //calculate the bank and pipe before rotation and swizzle
2532 case ADDR_TM_2D_TILED_THIN1
: //fall through
2533 case ADDR_TM_2D_TILED_THICK
: //fall through
2534 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2535 case ADDR_TM_3D_TILED_THIN1
: //fall through
2536 case ADDR_TM_3D_TILED_THICK
: //fall through
2537 case ADDR_TM_3D_TILED_XTHICK
:
2538 tileSplitRotation
= ((pTileInfo
->banks
/ 2) + 1);
2541 tileSplitRotation
= 0;
2545 UINT_32 microTileThickness
= Thickness(tileMode
);
2547 bank
^= tileSplitRotation
* tileSlices
;
2548 if (pipeRotation
== 0)
2550 bank
^= bankRotation
* (slice
/ microTileThickness
) + bankSwizzle
;
2551 bank
%= pTileInfo
->banks
;
2552 pipe
^= pipeSwizzle
;
2556 bank
^= bankRotation
* (slice
/ microTileThickness
) / numPipes
+ bankSwizzle
;
2557 bank
%= pTileInfo
->banks
;
2558 pipe
^= pipeRotation
* (slice
/ microTileThickness
) + pipeSwizzle
;
2561 if (pTileInfo
->macroAspectRatio
== 1)
2563 switch (pTileInfo
->banks
)
2566 yBit3
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2569 yBit4
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2570 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2573 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2574 yBit5
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2575 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ yBit5
;
2578 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3);
2579 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2);
2580 yBit6
= _BIT(bank
, 0) ^ _BIT(xBit
, 0);
2581 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ yBit6
;
2588 else if (pTileInfo
->macroAspectRatio
== 2)
2590 switch (pTileInfo
->banks
)
2592 case 2: //xBit3 = yBit3^b0
2593 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,0);
2595 case 4: //xBit3=yBit4^b0; yBit3=xBit4^b1
2596 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2597 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2599 case 8: //xBit4, xBit5, yBit5 are known
2600 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2601 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2602 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ _BIT(yBit
, 2);
2604 case 16://x4,x5,x6,y6 are known
2605 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3); //x3 = y6 ^ b0
2606 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2607 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = x5 ^ b2
2608 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ _BIT(yBit
, 3); //y5=x4^y6^b1
2614 else if (pTileInfo
->macroAspectRatio
== 4)
2616 switch (pTileInfo
->banks
)
2618 case 4: //yBit3, yBit4
2619 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2620 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,0);
2622 case 8: //xBit5, yBit4, yBit5
2623 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2624 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2625 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
,2);
2627 case 16: //xBit5, xBit6, yBit5, yBit6
2628 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = b0 ^ y6
2629 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = b1 ^ y5 ^ y6;
2630 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = b3 ^ x6;
2631 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = b2 ^ x5;
2637 else if (pTileInfo
->macroAspectRatio
== 8)
2639 switch (pTileInfo
->banks
)
2641 case 8: //yBit3, yBit4, yBit5
2642 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2); //x3 = b0 ^ y5;
2643 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
, 2);//x4 = b1 ^ y4 ^ y5;
2644 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
,0);
2646 case 16: //xBit6, yBit4, yBit5, yBit6
2647 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = y6 ^ b0
2648 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = y5 ^ y6 ^ b1
2649 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
, 1);//x5 = y4 ^ b2
2650 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2657 pOutput
->xBits
= xBit
;
2658 pOutput
->yBits
= yBit
;
2660 pOutput
->xBit3
= xBit3
;
2661 pOutput
->xBit4
= xBit4
;
2662 pOutput
->xBit5
= xBit5
;
2663 pOutput
->yBit3
= yBit3
;
2664 pOutput
->yBit4
= yBit4
;
2665 pOutput
->yBit5
= yBit5
;
2666 pOutput
->yBit6
= yBit6
;
2670 ****************************************************************************************************
2671 * EgBasedLib::HwlExtractBankPipeSwizzle
2673 * Entry of EgBasedLib ExtractBankPipeSwizzle
2676 ****************************************************************************************************
2678 ADDR_E_RETURNCODE
EgBasedLib::HwlExtractBankPipeSwizzle(
2679 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
2680 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
2683 ExtractBankPipeSwizzle(pIn
->base256b
,
2686 &pOut
->pipeSwizzle
);
2693 ****************************************************************************************************
2694 * EgBasedLib::HwlCombineBankPipeSwizzle
2696 * Combine bank/pipe swizzle
2699 ****************************************************************************************************
2701 ADDR_E_RETURNCODE
EgBasedLib::HwlCombineBankPipeSwizzle(
2702 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2703 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2704 ADDR_TILEINFO
* pTileInfo
, ///< [in] tile info
2705 UINT_64 baseAddr
, ///< [in] base address
2706 UINT_32
* pTileSwizzle
///< [out] combined swizzle
2709 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
2713 *pTileSwizzle
= GetBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, baseAddr
, pTileInfo
);
2717 retCode
= ADDR_INVALIDPARAMS
;
2724 ****************************************************************************************************
2725 * EgBasedLib::HwlComputeBaseSwizzle
2727 * Compute base swizzle
2730 ****************************************************************************************************
2732 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeBaseSwizzle(
2733 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT
* pIn
,
2734 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
* pOut
2737 UINT_32 bankSwizzle
= 0;
2738 UINT_32 pipeSwizzle
= 0;
2739 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2741 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
2742 ADDR_ASSERT(pIn
->pTileInfo
);
2744 /// This is a legacy misreading of h/w doc, use it as it doesn't hurt.
2745 static const UINT_8 bankRotationArray
[4][16] = {
2746 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_2_BANK
2747 { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_4_BANK
2748 { 0, 3, 6, 1, 4, 7, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_8_BANK
2749 { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }, // ADDR_SURF_16_BANK
2752 UINT_32 banks
= pTileInfo
? pTileInfo
->banks
: 2;
2755 // Uses less bank swizzle bits
2756 if (pIn
->option
.reduceBankBit
&& banks
> 2)
2776 ADDR_ASSERT_ALWAYS();
2781 if (pIn
->option
.genOption
== ADDR_SWIZZLE_GEN_LINEAR
)
2783 bankSwizzle
= pIn
->surfIndex
& (banks
- 1);
2785 else // (pIn->option.genOption == ADDR_SWIZZLE_GEN_DEFAULT)
2787 bankSwizzle
= bankRotationArray
[hwNumBanks
][pIn
->surfIndex
& (banks
- 1)];
2790 if (IsMacro3dTiled(pIn
->tileMode
))
2792 pipeSwizzle
= pIn
->surfIndex
& (HwlGetPipes(pTileInfo
) - 1);
2795 return HwlCombineBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, pTileInfo
, 0, &pOut
->tileSwizzle
);
2799 ****************************************************************************************************
2800 * EgBasedLib::ExtractBankPipeSwizzle
2802 * Extract bank/pipe swizzle from base256b
2805 ****************************************************************************************************
2807 VOID
EgBasedLib::ExtractBankPipeSwizzle(
2808 UINT_32 base256b
, ///< [in] input base256b register value
2809 ADDR_TILEINFO
* pTileInfo
, ///< [in] 2D tile parameters. Client must provide all data
2810 UINT_32
* pBankSwizzle
, ///< [out] bank swizzle
2811 UINT_32
* pPipeSwizzle
///< [out] pipe swizzle
2814 UINT_32 bankSwizzle
= 0;
2815 UINT_32 pipeSwizzle
= 0;
2819 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2820 UINT_32 bankBits
= QLog2(pTileInfo
->banks
);
2821 UINT_32 pipeBits
= QLog2(numPipes
);
2822 UINT_32 groupBytes
= m_pipeInterleaveBytes
;
2823 UINT_32 bankInterleave
= m_bankInterleave
;
2826 (base256b
/ (groupBytes
>> 8)) & ((1<<pipeBits
)-1);
2829 (base256b
/ (groupBytes
>> 8) / numPipes
/ bankInterleave
) & ((1 << bankBits
) - 1);
2832 *pPipeSwizzle
= pipeSwizzle
;
2833 *pBankSwizzle
= bankSwizzle
;
2837 ****************************************************************************************************
2838 * EgBasedLib::GetBankPipeSwizzle
2840 * Combine bank/pipe swizzle
2842 * Base256b bits (only filled bank/pipe bits)
2843 ****************************************************************************************************
2845 UINT_32
EgBasedLib::GetBankPipeSwizzle(
2846 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2847 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2848 UINT_64 baseAddr
, ///< [in] base address
2849 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2852 UINT_32 pipeBits
= QLog2(HwlGetPipes(pTileInfo
));
2853 UINT_32 bankInterleaveBits
= QLog2(m_bankInterleave
);
2854 UINT_32 tileSwizzle
= pipeSwizzle
+ ((bankSwizzle
<< bankInterleaveBits
) << pipeBits
);
2856 baseAddr
^= tileSwizzle
* m_pipeInterleaveBytes
;
2859 return static_cast<UINT_32
>(baseAddr
);
2863 ****************************************************************************************************
2864 * EgBasedLib::ComputeSliceTileSwizzle
2866 * Compute cubemap/3d texture faces/slices tile swizzle
2869 ****************************************************************************************************
2871 UINT_32
EgBasedLib::ComputeSliceTileSwizzle(
2872 AddrTileMode tileMode
, ///< [in] Tile mode
2873 UINT_32 baseSwizzle
, ///< [in] Base swizzle
2874 UINT_32 slice
, ///< [in] Slice index, Cubemap face index, 0 means +X
2875 UINT_64 baseAddr
, ///< [in] Base address
2876 ADDR_TILEINFO
* pTileInfo
///< [in] Bank structure
2879 UINT_32 tileSwizzle
= 0;
2881 if (IsMacroTiled(tileMode
)) // Swizzle only for macro tile mode
2883 UINT_32 firstSlice
= slice
/ Thickness(tileMode
);
2885 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2886 UINT_32 numBanks
= pTileInfo
->banks
;
2888 UINT_32 pipeRotation
;
2889 UINT_32 bankRotation
;
2891 UINT_32 bankSwizzle
= 0;
2892 UINT_32 pipeSwizzle
= 0;
2894 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2895 bankRotation
= ComputeBankRotation(tileMode
, numBanks
, numPipes
);
2897 if (baseSwizzle
!= 0)
2899 ExtractBankPipeSwizzle(baseSwizzle
,
2905 if (pipeRotation
== 0) //2D mode
2907 bankSwizzle
+= firstSlice
* bankRotation
;
2908 bankSwizzle
%= numBanks
;
2912 pipeSwizzle
+= firstSlice
* pipeRotation
;
2913 pipeSwizzle
%= numPipes
;
2914 bankSwizzle
+= firstSlice
* bankRotation
/ numPipes
;
2915 bankSwizzle
%= numBanks
;
2918 tileSwizzle
= GetBankPipeSwizzle(bankSwizzle
,
2928 ****************************************************************************************************
2929 * EgBasedLib::HwlComputeQbStereoRightSwizzle
2932 * Compute right eye swizzle
2935 ****************************************************************************************************
2937 UINT_32
EgBasedLib::HwlComputeQbStereoRightSwizzle(
2938 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pInfo
///< [in] Surface info, must be valid
2941 UINT_32 bankBits
= 0;
2942 UINT_32 swizzle
= 0;
2944 // The assumption is default swizzle for left eye is 0
2945 if (IsMacroTiled(pInfo
->tileMode
) && pInfo
->pStereoInfo
&& pInfo
->pTileInfo
)
2947 bankBits
= ComputeBankFromCoord(0, pInfo
->height
, 0,
2948 pInfo
->tileMode
, 0, 0, pInfo
->pTileInfo
);
2952 HwlCombineBankPipeSwizzle(bankBits
, 0, pInfo
->pTileInfo
, 0, &swizzle
);
2960 ****************************************************************************************************
2961 * EgBasedLib::ComputeBankFromCoord
2964 * Compute bank number from coordinates
2967 ****************************************************************************************************
2969 UINT_32
EgBasedLib::ComputeBankFromCoord(
2970 UINT_32 x
, ///< [in] x coordinate
2971 UINT_32 y
, ///< [in] y coordinate
2972 UINT_32 slice
, ///< [in] slice index
2973 AddrTileMode tileMode
, ///< [in] tile mode
2974 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2975 UINT_32 tileSplitSlice
, ///< [in] If the size of the pixel offset is larger than the
2976 /// tile split size, then the pixel will be moved to a separate
2977 /// slice. This value equals pixelOffset / tileSplitBytes
2978 /// in this case. Otherwise this is 0.
2979 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2982 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2983 UINT_32 bankBit0
= 0;
2984 UINT_32 bankBit1
= 0;
2985 UINT_32 bankBit2
= 0;
2986 UINT_32 bankBit3
= 0;
2987 UINT_32 sliceRotation
;
2988 UINT_32 tileSplitRotation
;
2990 UINT_32 numBanks
= pTileInfo
->banks
;
2991 UINT_32 bankWidth
= pTileInfo
->bankWidth
;
2992 UINT_32 bankHeight
= pTileInfo
->bankHeight
;
2994 UINT_32 tx
= x
/ MicroTileWidth
/ (bankWidth
* pipes
);
2995 UINT_32 ty
= y
/ MicroTileHeight
/ bankHeight
;
2997 UINT_32 x3
= _BIT(tx
,0);
2998 UINT_32 x4
= _BIT(tx
,1);
2999 UINT_32 x5
= _BIT(tx
,2);
3000 UINT_32 x6
= _BIT(tx
,3);
3001 UINT_32 y3
= _BIT(ty
,0);
3002 UINT_32 y4
= _BIT(ty
,1);
3003 UINT_32 y5
= _BIT(ty
,2);
3004 UINT_32 y6
= _BIT(ty
,3);
3010 bankBit1
= x4
^ y5
^ y6
;
3016 bankBit1
= x4
^ y4
^ y5
;
3027 ADDR_ASSERT_ALWAYS();
3031 bank
= bankBit0
| (bankBit1
<< 1) | (bankBit2
<< 2) | (bankBit3
<< 3);
3033 //Bits2Number(4, bankBit3, bankBit2, bankBit1, bankBit0);
3035 bank
= HwlPreAdjustBank((x
/ MicroTileWidth
), bank
, pTileInfo
);
3037 // Compute bank rotation for the slice.
3039 UINT_32 microTileThickness
= Thickness(tileMode
);
3043 case ADDR_TM_2D_TILED_THIN1
: // fall through
3044 case ADDR_TM_2D_TILED_THICK
: // fall through
3045 case ADDR_TM_2D_TILED_XTHICK
:
3046 sliceRotation
= ((numBanks
/ 2) - 1) * (slice
/ microTileThickness
);
3048 case ADDR_TM_3D_TILED_THIN1
: // fall through
3049 case ADDR_TM_3D_TILED_THICK
: // fall through
3050 case ADDR_TM_3D_TILED_XTHICK
:
3052 Max(1u, (pipes
/ 2) - 1) * (slice
/ microTileThickness
) / pipes
;
3061 // Compute bank rotation for the tile split slice.
3063 // The sample slice will be non-zero if samples must be split across multiple slices.
3064 // This situation arises when the micro tile size multiplied yBit the number of samples exceeds
3065 // the split size (set in GB_ADDR_CONFIG).
3069 case ADDR_TM_2D_TILED_THIN1
: //fall through
3070 case ADDR_TM_3D_TILED_THIN1
: //fall through
3071 case ADDR_TM_PRT_2D_TILED_THIN1
: //fall through
3072 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
3073 tileSplitRotation
= ((numBanks
/ 2) + 1) * tileSplitSlice
;
3076 tileSplitRotation
= 0;
3081 // Apply bank rotation for the slice and tile split slice.
3083 bank
^= bankSwizzle
+ sliceRotation
;
3084 bank
^= tileSplitRotation
;
3086 bank
&= (numBanks
- 1);
3092 ****************************************************************************************************
3093 * EgBasedLib::ComputeBankFromAddr
3096 * Compute the bank number from an address
3099 ****************************************************************************************************
3101 UINT_32
EgBasedLib::ComputeBankFromAddr(
3102 UINT_64 addr
, ///< [in] address
3103 UINT_32 numBanks
, ///< [in] number of banks
3104 UINT_32 numPipes
///< [in] number of pipes
3110 // The LSBs of the address are arranged as follows:
3111 // bank | bankInterleave | pipe | pipeInterleave
3113 // To get the bank number, shift off the pipe interleave, pipe, and bank interlave bits and
3114 // mask the bank bits.
3116 bank
= static_cast<UINT_32
>(
3117 (addr
>> Log2(m_pipeInterleaveBytes
* numPipes
* m_bankInterleave
)) &
3125 ****************************************************************************************************
3126 * EgBasedLib::ComputePipeRotation
3129 * Compute pipe rotation value
3132 ****************************************************************************************************
3134 UINT_32
EgBasedLib::ComputePipeRotation(
3135 AddrTileMode tileMode
, ///< [in] tile mode
3136 UINT_32 numPipes
///< [in] number of pipes
3143 case ADDR_TM_3D_TILED_THIN1
: //fall through
3144 case ADDR_TM_3D_TILED_THICK
: //fall through
3145 case ADDR_TM_3D_TILED_XTHICK
: //fall through
3146 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
3147 case ADDR_TM_PRT_3D_TILED_THICK
:
3148 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1);
3160 ****************************************************************************************************
3161 * EgBasedLib::ComputeBankRotation
3164 * Compute bank rotation value
3167 ****************************************************************************************************
3169 UINT_32
EgBasedLib::ComputeBankRotation(
3170 AddrTileMode tileMode
, ///< [in] tile mode
3171 UINT_32 numBanks
, ///< [in] number of banks
3172 UINT_32 numPipes
///< [in] number of pipes
3179 case ADDR_TM_2D_TILED_THIN1
: // fall through
3180 case ADDR_TM_2D_TILED_THICK
: // fall through
3181 case ADDR_TM_2D_TILED_XTHICK
:
3182 case ADDR_TM_PRT_2D_TILED_THIN1
:
3183 case ADDR_TM_PRT_2D_TILED_THICK
:
3184 // Rotate banks per Z-slice yBit 1 for 4-bank or 3 for 8-bank
3185 rotation
= numBanks
/ 2 - 1;
3187 case ADDR_TM_3D_TILED_THIN1
: // fall through
3188 case ADDR_TM_3D_TILED_THICK
: // fall through
3189 case ADDR_TM_3D_TILED_XTHICK
:
3190 case ADDR_TM_PRT_3D_TILED_THIN1
:
3191 case ADDR_TM_PRT_3D_TILED_THICK
:
3192 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1); // rotate pipes & banks
3203 ****************************************************************************************************
3204 * EgBasedLib::ComputeHtileBytes
3207 * Compute htile size in bytes
3210 * Htile size in bytes
3211 ****************************************************************************************************
3213 UINT_64
EgBasedLib::ComputeHtileBytes(
3214 UINT_32 pitch
, ///< [in] pitch
3215 UINT_32 height
, ///< [in] height
3216 UINT_32 bpp
, ///< [in] bits per pixel
3217 BOOL_32 isLinear
, ///< [in] if it is linear mode
3218 UINT_32 numSlices
, ///< [in] number of slices
3219 UINT_64
* sliceBytes
, ///< [out] bytes per slice
3220 UINT_32 baseAlign
///< [in] base alignments
3225 const UINT_64 HtileCacheLineSize
= BITS_TO_BYTES(HtileCacheBits
);
3227 *sliceBytes
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
/ 64);
3229 if (m_configFlags
.useHtileSliceAlign
)
3231 // Align the sliceSize to htilecachelinesize * pipes at first
3232 *sliceBytes
= PowTwoAlign(*sliceBytes
, HtileCacheLineSize
* m_pipes
);
3233 surfBytes
= *sliceBytes
* numSlices
;
3237 // Align the surfSize to htilecachelinesize * pipes at last
3238 surfBytes
= *sliceBytes
* numSlices
;
3239 surfBytes
= PowTwoAlign(surfBytes
, HtileCacheLineSize
* m_pipes
);
3246 ****************************************************************************************************
3247 * EgBasedLib::DispatchComputeFmaskInfo
3250 * Compute fmask sizes include padded pitch, height, slices, total size in bytes,
3251 * meanwhile output suitable tile mode and alignments as well. Results are returned
3252 * through output parameters.
3256 ****************************************************************************************************
3258 ADDR_E_RETURNCODE
EgBasedLib::DispatchComputeFmaskInfo(
3259 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3260 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
) ///< [out] output structure
3262 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3264 ADDR_COMPUTE_SURFACE_INFO_INPUT surfIn
= {0};
3265 ADDR_COMPUTE_SURFACE_INFO_OUTPUT surfOut
= {0};
3267 // Setup input structure
3268 surfIn
.tileMode
= pIn
->tileMode
;
3269 surfIn
.width
= pIn
->pitch
;
3270 surfIn
.height
= pIn
->height
;
3271 surfIn
.numSlices
= pIn
->numSlices
;
3272 surfIn
.pTileInfo
= pIn
->pTileInfo
;
3273 surfIn
.tileType
= ADDR_NON_DISPLAYABLE
;
3274 surfIn
.flags
.fmask
= 1;
3276 // Setup output structure
3277 surfOut
.pTileInfo
= pOut
->pTileInfo
;
3279 // Setup hwl specific fields
3280 HwlFmaskPreThunkSurfInfo(pIn
, pOut
, &surfIn
, &surfOut
);
3282 surfIn
.bpp
= HwlComputeFmaskBits(pIn
, &surfIn
.numSamples
);
3284 // ComputeSurfaceInfo needs numSamples in surfOut as surface routines need adjusted numSamples
3285 surfOut
.numSamples
= surfIn
.numSamples
;
3287 retCode
= HwlComputeSurfaceInfo(&surfIn
, &surfOut
);
3289 // Save bpp field for surface dump support
3290 surfOut
.bpp
= surfIn
.bpp
;
3292 if (retCode
== ADDR_OK
)
3294 pOut
->bpp
= surfOut
.bpp
;
3295 pOut
->pitch
= surfOut
.pitch
;
3296 pOut
->height
= surfOut
.height
;
3297 pOut
->numSlices
= surfOut
.depth
;
3298 pOut
->fmaskBytes
= surfOut
.surfSize
;
3299 pOut
->baseAlign
= surfOut
.baseAlign
;
3300 pOut
->pitchAlign
= surfOut
.pitchAlign
;
3301 pOut
->heightAlign
= surfOut
.heightAlign
;
3303 if (surfOut
.depth
> 1)
3305 // For fmask, expNumSlices is stored in depth.
3306 pOut
->sliceSize
= surfOut
.surfSize
/ surfOut
.depth
;
3310 pOut
->sliceSize
= surfOut
.surfSize
;
3313 // Save numSamples field for surface dump support
3314 pOut
->numSamples
= surfOut
.numSamples
;
3316 HwlFmaskPostThunkSurfInfo(&surfOut
, pOut
);
3323 ****************************************************************************************************
3324 * EgBasedLib::HwlFmaskSurfaceInfo
3326 * Entry of EgBasedLib ComputeFmaskInfo
3329 ****************************************************************************************************
3331 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskInfo(
3332 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3333 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
3336 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3338 ADDR_TILEINFO tileInfo
= {0};
3340 // Use internal tile info if pOut does not have a valid pTileInfo
3341 if (pOut
->pTileInfo
== NULL
)
3343 pOut
->pTileInfo
= &tileInfo
;
3346 retCode
= DispatchComputeFmaskInfo(pIn
, pOut
);
3348 if (retCode
== ADDR_OK
)
3351 HwlPostCheckTileIndex(pOut
->pTileInfo
, pIn
->tileMode
, ADDR_NON_DISPLAYABLE
,
3355 // Resets pTileInfo to NULL if the internal tile info is used
3356 if (pOut
->pTileInfo
== &tileInfo
)
3358 pOut
->pTileInfo
= NULL
;
3365 ****************************************************************************************************
3366 * EgBasedLib::HwlComputeFmaskAddrFromCoord
3368 * Entry of EgBasedLib ComputeFmaskAddrFromCoord
3371 ****************************************************************************************************
3373 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskAddrFromCoord(
3374 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3375 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3378 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3381 if ((pIn
->x
> pIn
->pitch
) ||
3382 (pIn
->y
> pIn
->height
) ||
3383 (pIn
->numSamples
> m_maxSamples
) ||
3384 (pIn
->sample
>= m_maxSamples
))
3386 retCode
= ADDR_INVALIDPARAMS
;
3390 pOut
->addr
= DispatchComputeFmaskAddrFromCoord(pIn
, pOut
);
3398 ****************************************************************************************************
3399 * EgBasedLib::HwlComputeFmaskCoordFromAddr
3401 * Entry of EgBasedLib ComputeFmaskCoordFromAddr
3404 ****************************************************************************************************
3406 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskCoordFromAddr(
3407 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3408 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3411 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3414 if ((pIn
->bitPosition
>= 8) ||
3415 (pIn
->numSamples
> m_maxSamples
))
3417 retCode
= ADDR_INVALIDPARAMS
;
3421 DispatchComputeFmaskCoordFromAddr(pIn
, pOut
);
3430 ****************************************************************************************************
3431 * EgBasedLib::DispatchComputeFmaskAddrFromCoord
3434 * Computes the FMASK address and bit position from a coordinate.
3437 ****************************************************************************************************
3439 UINT_64
EgBasedLib::DispatchComputeFmaskAddrFromCoord(
3440 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3441 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3446 UINT_32 slice
= pIn
->slice
;
3447 UINT_32 sample
= pIn
->sample
;
3448 UINT_32 plane
= pIn
->plane
;
3449 UINT_32 pitch
= pIn
->pitch
;
3450 UINT_32 height
= pIn
->height
;
3451 UINT_32 numSamples
= pIn
->numSamples
;
3452 AddrTileMode tileMode
= pIn
->tileMode
;
3453 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
3454 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
3455 BOOL_32 resolved
= pIn
->resolved
;
3457 UINT_32
* pBitPosition
= &pOut
->bitPosition
;
3460 ADDR_ASSERT(numSamples
> 1);
3461 ADDR_ASSERT(Thickness(tileMode
) == 1);
3465 case ADDR_TM_1D_TILED_THIN1
:
3466 addr
= ComputeFmaskAddrFromCoordMicroTiled(x
,
3478 case ADDR_TM_2D_TILED_THIN1
: //fall through
3479 case ADDR_TM_3D_TILED_THIN1
:
3480 UINT_32 pipeSwizzle
;
3481 UINT_32 bankSwizzle
;
3483 if (m_configFlags
.useCombinedSwizzle
)
3485 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
3486 &bankSwizzle
, &pipeSwizzle
);
3490 pipeSwizzle
= pIn
->pipeSwizzle
;
3491 bankSwizzle
= pIn
->bankSwizzle
;
3494 addr
= ComputeFmaskAddrFromCoordMacroTiled(x
,
3519 ****************************************************************************************************
3520 * EgBasedLib::ComputeFmaskAddrFromCoordMicroTiled
3523 * Computes the FMASK address and bit position from a coordinate for 1D tilied (micro
3527 ****************************************************************************************************
3529 UINT_64
EgBasedLib::ComputeFmaskAddrFromCoordMicroTiled(
3530 UINT_32 x
, ///< [in] x coordinate
3531 UINT_32 y
, ///< [in] y coordinate
3532 UINT_32 slice
, ///< [in] slice index
3533 UINT_32 sample
, ///< [in] sample number
3534 UINT_32 plane
, ///< [in] plane number
3535 UINT_32 pitch
, ///< [in] surface pitch in pixels
3536 UINT_32 height
, ///< [in] surface height in pixels
3537 UINT_32 numSamples
, ///< [in] number of samples
3538 AddrTileMode tileMode
, ///< [in] tile mode
3539 BOOL_32 resolved
, ///< [in] TRUE if this is for resolved fmask
3540 UINT_32
* pBitPosition
///< [out] pointer to returned bit position
3544 UINT_32 effectiveBpp
;
3545 UINT_32 effectiveSamples
;
3548 // 2xAA use the same layout as 4xAA
3550 if (numSamples
== 2)
3556 // Compute the number of planes.
3558 if (resolved
== FALSE
)
3560 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3561 effectiveBpp
= numSamples
;
3564 // Compute the address just like a color surface with numSamples bits per element and
3565 // numPlanes samples.
3567 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
3576 ADDR_NON_DISPLAYABLE
,
3581 // Compute the real bit position. Each (sample, plane) is stored with one bit per sample.
3585 // Compute the pixel index with in the micro tile
3587 UINT_32 pixelIndex
= ComputePixelIndexWithinMicroTile(x
% 8,
3592 ADDR_NON_DISPLAYABLE
);
3594 *pBitPosition
= ((pixelIndex
* numSamples
) + sample
) & (BITS_PER_BYTE
-1);
3596 UINT_64 bitAddr
= BYTES_TO_BITS(addr
) + *pBitPosition
;
3602 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3603 effectiveSamples
= 1;
3606 // Compute the address just like a color surface with numSamples bits per element and
3607 // numPlanes samples.
3609 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
3618 ADDR_NON_DISPLAYABLE
,
3627 ****************************************************************************************************
3628 * EgBasedLib::ComputeFmaskAddrFromCoordMacroTiled
3631 * Computes the FMASK address and bit position from a coordinate for 2D tilied (macro
3635 ****************************************************************************************************
3637 UINT_64
EgBasedLib::ComputeFmaskAddrFromCoordMacroTiled(
3638 UINT_32 x
, ///< [in] x coordinate
3639 UINT_32 y
, ///< [in] y coordinate
3640 UINT_32 slice
, ///< [in] slice index
3641 UINT_32 sample
, ///< [in] sample number
3642 UINT_32 plane
, ///< [in] plane number
3643 UINT_32 pitch
, ///< [in] surface pitch in pixels
3644 UINT_32 height
, ///< [in] surface height in pixels
3645 UINT_32 numSamples
, ///< [in] number of samples
3646 AddrTileMode tileMode
, ///< [in] tile mode
3647 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
3648 UINT_32 bankSwizzle
, ///< [in] bank swizzle
3649 BOOL_32 ignoreSE
, ///< [in] TRUE if ignore shader engine
3650 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure.**All fields to be valid on entry**
3651 BOOL_32 resolved
, ///< [in] TRUE if this is for resolved fmask
3652 UINT_32
* pBitPosition
///< [out] pointer to returned bit position
3656 UINT_32 effectiveBpp
;
3657 UINT_32 effectiveSamples
;
3660 // 2xAA use the same layout as 4xAA
3662 if (numSamples
== 2)
3668 // Compute the number of planes.
3670 if (resolved
== FALSE
)
3672 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3673 effectiveBpp
= numSamples
;
3676 // Compute the address just like a color surface with numSamples bits per element and
3677 // numPlanes samples.
3679 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
3688 ADDR_NON_DISPLAYABLE
,// isdisp
3689 ignoreSE
,// ignore_shader
3690 FALSE
,// depth_sample_order
3697 // Compute the real bit position. Each (sample, plane) is stored with one bit per sample.
3702 // Compute the pixel index with in the micro tile
3704 UINT_32 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
3709 ADDR_NON_DISPLAYABLE
);
3711 *pBitPosition
= ((pixelIndex
* numSamples
) + sample
) & (BITS_PER_BYTE
-1);
3713 UINT_64 bitAddr
= BYTES_TO_BITS(addr
) + *pBitPosition
;
3720 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3721 effectiveSamples
= 1;
3724 // Compute the address just like a color surface with numSamples bits per element and
3725 // numPlanes samples.
3727 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
3736 ADDR_NON_DISPLAYABLE
,
3749 ****************************************************************************************************
3750 * EgBasedLib::ComputeFmaskCoordFromAddrMicroTiled
3753 * Compute (x,y,slice,sample,plane) coordinates from fmask address
3757 ****************************************************************************************************
3759 VOID
EgBasedLib::ComputeFmaskCoordFromAddrMicroTiled(
3760 UINT_64 addr
, ///< [in] byte address
3761 UINT_32 bitPosition
,///< [in] bit position
3762 UINT_32 pitch
, ///< [in] pitch in pixels
3763 UINT_32 height
, ///< [in] height in pixels
3764 UINT_32 numSamples
, ///< [in] number of samples (of color buffer)
3765 AddrTileMode tileMode
, ///< [in] tile mode
3766 BOOL_32 resolved
, ///< [in] TRUE if it is resolved fmask
3767 UINT_32
* pX
, ///< [out] X coord
3768 UINT_32
* pY
, ///< [out] Y coord
3769 UINT_32
* pSlice
, ///< [out] slice index
3770 UINT_32
* pSample
, ///< [out] sample index
3771 UINT_32
* pPlane
///< [out] plane index
3774 UINT_32 effectiveBpp
;
3775 UINT_32 effectiveSamples
;
3777 // 2xAA use the same layout as 4xAA
3778 if (numSamples
== 2)
3783 if (resolved
== FALSE
)
3785 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3786 effectiveBpp
= numSamples
;
3788 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
3801 ADDR_NON_DISPLAYABLE
, // microTileType
3802 FALSE
// isDepthSampleOrder
3808 *pSample
= bitPosition
% numSamples
;
3813 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3814 effectiveSamples
= 1;
3816 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
3829 ADDR_NON_DISPLAYABLE
, // microTileType
3830 TRUE
// isDepthSampleOrder
3836 ****************************************************************************************************
3837 * EgBasedLib::ComputeFmaskCoordFromAddrMacroTiled
3840 * Compute (x,y,slice,sample,plane) coordinates from
3845 ****************************************************************************************************
3847 VOID
EgBasedLib::ComputeFmaskCoordFromAddrMacroTiled(
3848 UINT_64 addr
, ///< [in] byte address
3849 UINT_32 bitPosition
,///< [in] bit position
3850 UINT_32 pitch
, ///< [in] pitch in pixels
3851 UINT_32 height
, ///< [in] height in pixels
3852 UINT_32 numSamples
, ///< [in] number of samples (of color buffer)
3853 AddrTileMode tileMode
, ///< [in] tile mode
3854 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
3855 UINT_32 bankSwizzle
,///< [in] bank swizzle
3856 BOOL_32 ignoreSE
, ///< [in] TRUE if ignore shader engine
3857 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure. **All fields to be valid on entry**
3858 BOOL_32 resolved
, ///< [in] TRUE if it is resolved fmask
3859 UINT_32
* pX
, ///< [out] X coord
3860 UINT_32
* pY
, ///< [out] Y coord
3861 UINT_32
* pSlice
, ///< [out] slice index
3862 UINT_32
* pSample
, ///< [out] sample index
3863 UINT_32
* pPlane
///< [out] plane index
3866 UINT_32 effectiveBpp
;
3867 UINT_32 effectiveSamples
;
3869 // 2xAA use the same layout as 4xAA
3870 if (numSamples
== 2)
3876 // Compute the number of planes.
3878 if (resolved
== FALSE
)
3880 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3881 effectiveBpp
= numSamples
;
3883 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
3892 ADDR_NON_DISPLAYABLE
,
3905 *pSample
= bitPosition
% numSamples
;
3910 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3911 effectiveSamples
= 1;
3913 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
3922 ADDR_NON_DISPLAYABLE
,
3936 ****************************************************************************************************
3937 * EgBasedLib::DispatchComputeFmaskCoordFromAddr
3940 * Compute (x,y,slice,sample,plane) coordinates from
3945 ****************************************************************************************************
3947 VOID
EgBasedLib::DispatchComputeFmaskCoordFromAddr(
3948 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3949 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3952 UINT_64 addr
= pIn
->addr
;
3953 UINT_32 bitPosition
= pIn
->bitPosition
;
3954 UINT_32 pitch
= pIn
->pitch
;
3955 UINT_32 height
= pIn
->height
;
3956 UINT_32 numSamples
= pIn
->numSamples
;
3957 AddrTileMode tileMode
= pIn
->tileMode
;
3958 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
3959 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
3960 BOOL_32 resolved
= pIn
->resolved
;
3962 UINT_32
* pX
= &pOut
->x
;
3963 UINT_32
* pY
= &pOut
->y
;
3964 UINT_32
* pSlice
= &pOut
->slice
;
3965 UINT_32
* pSample
= &pOut
->sample
;
3966 UINT_32
* pPlane
= &pOut
->plane
;
3970 case ADDR_TM_1D_TILED_THIN1
:
3971 ComputeFmaskCoordFromAddrMicroTiled(addr
,
3984 case ADDR_TM_2D_TILED_THIN1
://fall through
3985 case ADDR_TM_3D_TILED_THIN1
:
3986 UINT_32 pipeSwizzle
;
3987 UINT_32 bankSwizzle
;
3989 if (m_configFlags
.useCombinedSwizzle
)
3991 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
3992 &bankSwizzle
, &pipeSwizzle
);
3996 pipeSwizzle
= pIn
->pipeSwizzle
;
3997 bankSwizzle
= pIn
->bankSwizzle
;
4000 ComputeFmaskCoordFromAddrMacroTiled(addr
,
4018 ADDR_ASSERT_ALWAYS();
4026 ****************************************************************************************************
4027 * EgBasedLib::ComputeFmaskNumPlanesFromNumSamples
4030 * Compute fmask number of planes from number of samples
4034 ****************************************************************************************************
4036 UINT_32
EgBasedLib::ComputeFmaskNumPlanesFromNumSamples(
4037 UINT_32 numSamples
) ///< [in] number of samples
4042 // FMASK is stored such that each micro tile is composed of elements containing N bits, where
4043 // N is the number of samples. There is a micro tile for each bit in the FMASK address, and
4044 // micro tiles for each address bit, sometimes referred to as a plane, are stored sequentially.
4045 // The FMASK for a 2-sample surface looks like a general surface with 2 bits per element.
4046 // The FMASK for a 4-sample surface looks like a general surface with 4 bits per element and
4047 // 2 samples. The FMASK for an 8-sample surface looks like a general surface with 8 bits per
4048 // element and 4 samples. R6xx and R7xx only stored 3 planes for 8-sample FMASK surfaces.
4049 // This was changed for R8xx to simplify the logic in the CB.
4063 ADDR_UNHANDLED_CASE();
4071 ****************************************************************************************************
4072 * EgBasedLib::ComputeFmaskResolvedBppFromNumSamples
4075 * Compute resolved fmask effective bpp based on number of samples
4079 ****************************************************************************************************
4081 UINT_32
EgBasedLib::ComputeFmaskResolvedBppFromNumSamples(
4082 UINT_32 numSamples
) ///< number of samples
4087 // Resolved FMASK surfaces are generated yBit the CB and read yBit the texture unit
4088 // so that the texture unit can read compressed multi-sample color data.
4089 // These surfaces store each index value packed per element.
4090 // Each element contains at least num_samples * log2(num_samples) bits.
4091 // Resolved FMASK surfaces are addressed as follows:
4092 // 2-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
4093 // 4-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
4094 // 8-sample Addressed similarly to a color surface with 32 bits per element and 1 sample.
4108 ADDR_UNHANDLED_CASE();
4116 ****************************************************************************************************
4117 * EgBasedLib::IsTileInfoAllZero
4120 * Return TRUE if all field are zero
4122 * Since NULL input is consider to be all zero
4123 ****************************************************************************************************
4125 BOOL_32
EgBasedLib::IsTileInfoAllZero(
4126 ADDR_TILEINFO
* pTileInfo
)
4128 BOOL_32 allZero
= TRUE
;
4132 if ((pTileInfo
->banks
!= 0) ||
4133 (pTileInfo
->bankWidth
!= 0) ||
4134 (pTileInfo
->bankHeight
!= 0) ||
4135 (pTileInfo
->macroAspectRatio
!= 0) ||
4136 (pTileInfo
->tileSplitBytes
!= 0) ||
4137 (pTileInfo
->pipeConfig
!= 0)
4148 ****************************************************************************************************
4149 * EgBasedLib::HwlTileInfoEqual
4152 * Return TRUE if all field are equal
4154 * Only takes care of current HWL's data
4155 ****************************************************************************************************
4157 BOOL_32
EgBasedLib::HwlTileInfoEqual(
4158 const ADDR_TILEINFO
* pLeft
, ///<[in] Left compare operand
4159 const ADDR_TILEINFO
* pRight
///<[in] Right compare operand
4162 BOOL_32 equal
= FALSE
;
4164 if (pLeft
->banks
== pRight
->banks
&&
4165 pLeft
->bankWidth
== pRight
->bankWidth
&&
4166 pLeft
->bankHeight
== pRight
->bankHeight
&&
4167 pLeft
->macroAspectRatio
== pRight
->macroAspectRatio
&&
4168 pLeft
->tileSplitBytes
== pRight
->tileSplitBytes
)
4177 ****************************************************************************************************
4178 * EgBasedLib::HwlConvertTileInfoToHW
4180 * Entry of EgBasedLib ConvertTileInfoToHW
4183 ****************************************************************************************************
4185 ADDR_E_RETURNCODE
EgBasedLib::HwlConvertTileInfoToHW(
4186 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
4187 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
4190 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4192 ADDR_TILEINFO
*pTileInfoIn
= pIn
->pTileInfo
;
4193 ADDR_TILEINFO
*pTileInfoOut
= pOut
->pTileInfo
;
4195 if ((pTileInfoIn
!= NULL
) && (pTileInfoOut
!= NULL
))
4197 if (pIn
->reverse
== FALSE
)
4199 switch (pTileInfoIn
->banks
)
4202 pTileInfoOut
->banks
= 0;
4205 pTileInfoOut
->banks
= 1;
4208 pTileInfoOut
->banks
= 2;
4211 pTileInfoOut
->banks
= 3;
4214 ADDR_ASSERT_ALWAYS();
4215 retCode
= ADDR_INVALIDPARAMS
;
4216 pTileInfoOut
->banks
= 0;
4220 switch (pTileInfoIn
->bankWidth
)
4223 pTileInfoOut
->bankWidth
= 0;
4226 pTileInfoOut
->bankWidth
= 1;
4229 pTileInfoOut
->bankWidth
= 2;
4232 pTileInfoOut
->bankWidth
= 3;
4235 ADDR_ASSERT_ALWAYS();
4236 retCode
= ADDR_INVALIDPARAMS
;
4237 pTileInfoOut
->bankWidth
= 0;
4241 switch (pTileInfoIn
->bankHeight
)
4244 pTileInfoOut
->bankHeight
= 0;
4247 pTileInfoOut
->bankHeight
= 1;
4250 pTileInfoOut
->bankHeight
= 2;
4253 pTileInfoOut
->bankHeight
= 3;
4256 ADDR_ASSERT_ALWAYS();
4257 retCode
= ADDR_INVALIDPARAMS
;
4258 pTileInfoOut
->bankHeight
= 0;
4262 switch (pTileInfoIn
->macroAspectRatio
)
4265 pTileInfoOut
->macroAspectRatio
= 0;
4268 pTileInfoOut
->macroAspectRatio
= 1;
4271 pTileInfoOut
->macroAspectRatio
= 2;
4274 pTileInfoOut
->macroAspectRatio
= 3;
4277 ADDR_ASSERT_ALWAYS();
4278 retCode
= ADDR_INVALIDPARAMS
;
4279 pTileInfoOut
->macroAspectRatio
= 0;
4283 switch (pTileInfoIn
->tileSplitBytes
)
4286 pTileInfoOut
->tileSplitBytes
= 0;
4289 pTileInfoOut
->tileSplitBytes
= 1;
4292 pTileInfoOut
->tileSplitBytes
= 2;
4295 pTileInfoOut
->tileSplitBytes
= 3;
4298 pTileInfoOut
->tileSplitBytes
= 4;
4301 pTileInfoOut
->tileSplitBytes
= 5;
4304 pTileInfoOut
->tileSplitBytes
= 6;
4307 ADDR_ASSERT_ALWAYS();
4308 retCode
= ADDR_INVALIDPARAMS
;
4309 pTileInfoOut
->tileSplitBytes
= 0;
4315 switch (pTileInfoIn
->banks
)
4318 pTileInfoOut
->banks
= 2;
4321 pTileInfoOut
->banks
= 4;
4324 pTileInfoOut
->banks
= 8;
4327 pTileInfoOut
->banks
= 16;
4330 ADDR_ASSERT_ALWAYS();
4331 retCode
= ADDR_INVALIDPARAMS
;
4332 pTileInfoOut
->banks
= 2;
4336 switch (pTileInfoIn
->bankWidth
)
4339 pTileInfoOut
->bankWidth
= 1;
4342 pTileInfoOut
->bankWidth
= 2;
4345 pTileInfoOut
->bankWidth
= 4;
4348 pTileInfoOut
->bankWidth
= 8;
4351 ADDR_ASSERT_ALWAYS();
4352 retCode
= ADDR_INVALIDPARAMS
;
4353 pTileInfoOut
->bankWidth
= 1;
4357 switch (pTileInfoIn
->bankHeight
)
4360 pTileInfoOut
->bankHeight
= 1;
4363 pTileInfoOut
->bankHeight
= 2;
4366 pTileInfoOut
->bankHeight
= 4;
4369 pTileInfoOut
->bankHeight
= 8;
4372 ADDR_ASSERT_ALWAYS();
4373 retCode
= ADDR_INVALIDPARAMS
;
4374 pTileInfoOut
->bankHeight
= 1;
4378 switch (pTileInfoIn
->macroAspectRatio
)
4381 pTileInfoOut
->macroAspectRatio
= 1;
4384 pTileInfoOut
->macroAspectRatio
= 2;
4387 pTileInfoOut
->macroAspectRatio
= 4;
4390 pTileInfoOut
->macroAspectRatio
= 8;
4393 ADDR_ASSERT_ALWAYS();
4394 retCode
= ADDR_INVALIDPARAMS
;
4395 pTileInfoOut
->macroAspectRatio
= 1;
4399 switch (pTileInfoIn
->tileSplitBytes
)
4402 pTileInfoOut
->tileSplitBytes
= 64;
4405 pTileInfoOut
->tileSplitBytes
= 128;
4408 pTileInfoOut
->tileSplitBytes
= 256;
4411 pTileInfoOut
->tileSplitBytes
= 512;
4414 pTileInfoOut
->tileSplitBytes
= 1024;
4417 pTileInfoOut
->tileSplitBytes
= 2048;
4420 pTileInfoOut
->tileSplitBytes
= 4096;
4423 ADDR_ASSERT_ALWAYS();
4424 retCode
= ADDR_INVALIDPARAMS
;
4425 pTileInfoOut
->tileSplitBytes
= 64;
4430 if (pTileInfoIn
!= pTileInfoOut
)
4432 pTileInfoOut
->pipeConfig
= pTileInfoIn
->pipeConfig
;
4437 ADDR_ASSERT_ALWAYS();
4438 retCode
= ADDR_INVALIDPARAMS
;
4445 ****************************************************************************************************
4446 * EgBasedLib::HwlComputeSurfaceInfo
4448 * Entry of EgBasedLib ComputeSurfaceInfo
4451 ****************************************************************************************************
4453 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceInfo(
4454 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
4455 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
4458 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4460 if (pIn
->numSamples
< pIn
->numFrags
)
4462 retCode
= ADDR_INVALIDPARAMS
;
4465 ADDR_TILEINFO tileInfo
= {0};
4467 if (retCode
== ADDR_OK
)
4469 // Uses internal tile info if pOut does not have a valid pTileInfo
4470 if (pOut
->pTileInfo
== NULL
)
4472 pOut
->pTileInfo
= &tileInfo
;
4475 if (DispatchComputeSurfaceInfo(pIn
, pOut
) == FALSE
)
4477 retCode
= ADDR_INVALIDPARAMS
;
4480 // In case client uses tile info as input and would like to calculate a correct size and
4481 // alignment together with tile info as output when the tile info is not suppose to have any
4482 // matching indices in tile mode tables.
4483 if (pIn
->flags
.skipIndicesOutput
== FALSE
)
4486 pOut
->tileIndex
= HwlPostCheckTileIndex(pOut
->pTileInfo
,
4491 if (IsMacroTiled(pOut
->tileMode
) && (pOut
->macroModeIndex
== TileIndexInvalid
))
4493 pOut
->macroModeIndex
= HwlComputeMacroModeIndex(pOut
->tileIndex
,
4501 // Resets pTileInfo to NULL if the internal tile info is used
4502 if (pOut
->pTileInfo
== &tileInfo
)
4505 // Client does not pass in a valid pTileInfo
4506 if (IsMacroTiled(pOut
->tileMode
))
4508 // If a valid index is returned, then no pTileInfo is okay
4509 ADDR_ASSERT((m_configFlags
.useTileIndex
== FALSE
) ||
4510 (pOut
->tileIndex
!= TileIndexInvalid
));
4512 if (IsTileInfoAllZero(pIn
->pTileInfo
) == FALSE
)
4514 // The initial value of pIn->pTileInfo is copied to tileInfo
4515 // We do not expect any of these value to be changed nor any 0 of inputs
4516 ADDR_ASSERT(tileInfo
.banks
== pIn
->pTileInfo
->banks
);
4517 ADDR_ASSERT(tileInfo
.bankWidth
== pIn
->pTileInfo
->bankWidth
);
4518 ADDR_ASSERT(tileInfo
.bankHeight
== pIn
->pTileInfo
->bankHeight
);
4519 ADDR_ASSERT(tileInfo
.macroAspectRatio
== pIn
->pTileInfo
->macroAspectRatio
);
4520 ADDR_ASSERT(tileInfo
.tileSplitBytes
== pIn
->pTileInfo
->tileSplitBytes
);
4524 pOut
->pTileInfo
= NULL
;
4532 ****************************************************************************************************
4533 * EgBasedLib::HwlComputeSurfaceAddrFromCoord
4535 * Entry of EgBasedLib ComputeSurfaceAddrFromCoord
4538 ****************************************************************************************************
4540 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceAddrFromCoord(
4541 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
4542 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
4545 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4548 #if !ALT_TEST // Overflow test needs this out-of-boundary coord
4549 (pIn
->x
> pIn
->pitch
) ||
4550 (pIn
->y
> pIn
->height
) ||
4552 (pIn
->numSamples
> m_maxSamples
))
4554 retCode
= ADDR_INVALIDPARAMS
;
4558 pOut
->addr
= DispatchComputeSurfaceAddrFromCoord(pIn
, pOut
);
4565 ****************************************************************************************************
4566 * EgBasedLib::HwlComputeSurfaceCoordFromAddr
4568 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
4571 ****************************************************************************************************
4573 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceCoordFromAddr(
4574 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
4575 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
4578 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4580 if ((pIn
->bitPosition
>= 8) ||
4581 (pIn
->numSamples
> m_maxSamples
))
4583 retCode
= ADDR_INVALIDPARAMS
;
4587 DispatchComputeSurfaceCoordFromAddr(pIn
, pOut
);
4593 ****************************************************************************************************
4594 * EgBasedLib::HwlComputeSliceTileSwizzle
4596 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
4599 ****************************************************************************************************
4601 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSliceTileSwizzle(
4602 const ADDR_COMPUTE_SLICESWIZZLE_INPUT
* pIn
, ///< [in] input structure
4603 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
* pOut
///< [out] output structure
4606 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4608 if (pIn
->pTileInfo
&& (pIn
->pTileInfo
->banks
> 0))
4611 pOut
->tileSwizzle
= ComputeSliceTileSwizzle(pIn
->tileMode
,
4619 retCode
= ADDR_INVALIDPARAMS
;
4626 ****************************************************************************************************
4627 * EgBasedLib::HwlComputeHtileBpp
4634 ****************************************************************************************************
4636 UINT_32
EgBasedLib::HwlComputeHtileBpp(
4637 BOOL_32 isWidth8
, ///< [in] TRUE if block width is 8
4638 BOOL_32 isHeight8
///< [in] TRUE if block height is 8
4641 // only support 8x8 mode
4642 ADDR_ASSERT(isWidth8
&& isHeight8
);
4647 ****************************************************************************************************
4648 * EgBasedLib::HwlComputeHtileBaseAlign
4651 * Compute htile base alignment
4654 * Htile base alignment
4655 ****************************************************************************************************
4657 UINT_32
EgBasedLib::HwlComputeHtileBaseAlign(
4658 BOOL_32 isTcCompatible
, ///< [in] if TC compatible
4659 BOOL_32 isLinear
, ///< [in] if it is linear mode
4660 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
4663 UINT_32 baseAlign
= m_pipeInterleaveBytes
* HwlGetPipes(pTileInfo
);
4667 ADDR_ASSERT(pTileInfo
!= NULL
);
4670 baseAlign
*= pTileInfo
->banks
;
4678 ****************************************************************************************************
4679 * EgBasedLib::HwlGetPitchAlignmentMicroTiled
4682 * Compute 1D tiled surface pitch alignment, calculation results are returned through
4683 * output parameters.
4687 ****************************************************************************************************
4689 UINT_32
EgBasedLib::HwlGetPitchAlignmentMicroTiled(
4690 AddrTileMode tileMode
, ///< [in] tile mode
4691 UINT_32 bpp
, ///< [in] bits per pixel
4692 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4693 UINT_32 numSamples
///< [in] number of samples
4698 UINT_32 microTileThickness
= Thickness(tileMode
);
4700 UINT_32 pixelsPerMicroTile
;
4701 UINT_32 pixelsPerPipeInterleave
;
4702 UINT_32 microTilesPerPipeInterleave
;
4705 // Special workaround for depth/stencil buffer, use 8 bpp to meet larger requirement for
4706 // stencil buffer since pitch alignment is related to bpp.
4707 // For a depth only buffer do not set this.
4709 // Note: this actually does not work for mipmap but mipmap depth texture is not really
4710 // sampled with mipmap.
4712 if (flags
.depth
&& (flags
.noStencil
== FALSE
))
4717 pixelsPerMicroTile
= MicroTilePixels
* microTileThickness
;
4718 pixelsPerPipeInterleave
= BYTES_TO_BITS(m_pipeInterleaveBytes
) / (bpp
* numSamples
);
4719 microTilesPerPipeInterleave
= pixelsPerPipeInterleave
/ pixelsPerMicroTile
;
4721 pitchAlign
= Max(MicroTileWidth
, microTilesPerPipeInterleave
* MicroTileWidth
);
4727 ****************************************************************************************************
4728 * EgBasedLib::HwlGetSizeAdjustmentMicroTiled
4731 * Adjust 1D tiled surface pitch and slice size
4734 * Logical slice size in bytes
4735 ****************************************************************************************************
4737 UINT_64
EgBasedLib::HwlGetSizeAdjustmentMicroTiled(
4738 UINT_32 thickness
, ///< [in] thickness
4739 UINT_32 bpp
, ///< [in] bits per pixel
4740 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4741 UINT_32 numSamples
, ///< [in] number of samples
4742 UINT_32 baseAlign
, ///< [in] base alignment
4743 UINT_32 pitchAlign
, ///< [in] pitch alignment
4744 UINT_32
* pPitch
, ///< [in,out] pointer to pitch
4745 UINT_32
* pHeight
///< [in,out] pointer to height
4748 UINT_64 logicalSliceSize
;
4749 UINT_64 physicalSliceSize
;
4751 UINT_32 pitch
= *pPitch
;
4752 UINT_32 height
= *pHeight
;
4754 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
4755 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
4757 // Physical slice: multiplied by thickness
4758 physicalSliceSize
= logicalSliceSize
* thickness
;
4761 // R800 will always pad physical slice size to baseAlign which is pipe_interleave_bytes
4763 ADDR_ASSERT((physicalSliceSize
% baseAlign
) == 0);
4765 return logicalSliceSize
;
4769 ****************************************************************************************************
4770 * EgBasedLib::HwlStereoCheckRightOffsetPadding
4773 * check if the height needs extra padding for stereo right eye offset, to avoid swizzling
4776 * TRUE is the extra padding is needed
4778 ****************************************************************************************************
4780 UINT_32
EgBasedLib::HwlStereoCheckRightOffsetPadding(
4781 ADDR_TILEINFO
* pTileInfo
///< Tiling info
4784 UINT_32 stereoHeightAlign
= 0;
4786 if (pTileInfo
->macroAspectRatio
> 2)
4788 // Since 3D rendering treats right eye surface starting from y == "eye height" while
4789 // display engine treats it to be 0, so the bank bits may be different.
4790 // Additional padding in height is required to make sure it's possible
4791 // to achieve synonym by adjusting bank swizzle of right eye surface.
4793 static const UINT_32 StereoAspectRatio
= 2;
4794 stereoHeightAlign
= pTileInfo
->banks
*
4795 pTileInfo
->bankHeight
*
4800 return stereoHeightAlign
;