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
->tileMode
== ADDR_TM_LINEAR_GENERAL
) && pIn
->flags
.color
&& (pIn
->height
> 1))
246 // When linear_general surface is accessed in multiple lines, it requires 8 pixels in pitch
247 // alignment since PITCH_TILE_MAX is in unit of 8 pixels.
248 // It is OK if it is accessed per line.
249 ADDR_ASSERT((pIn
->width
% 8) == 0);
253 pOut
->depthAlign
= microTileThickness
;
255 expPitch
= HwlPreHandleBaseLvl3xPitch(pIn
, expPitch
);
258 // Pad pitch and height to the required granularities.
260 PadDimensions(pIn
->tileMode
,
267 &expPitch
, &pOut
->pitchAlign
,
268 &expHeight
, pOut
->heightAlign
,
269 &expNumSlices
, microTileThickness
);
271 expPitch
= HwlPostHandleBaseLvl3xPitch(pIn
, expPitch
);
277 UINT_64 logicalSliceSize
;
279 logicalSliceSize
= HwlGetSizeAdjustmentLinear(pIn
->tileMode
,
288 if ((pIn
->pitchAlign
!= 0) || (pIn
->heightAlign
!= 0))
290 if (pIn
->pitchAlign
!= 0)
292 ADDR_ASSERT((pIn
->pitchAlign
% pOut
->pitchAlign
) == 0);
293 pOut
->pitchAlign
= pIn
->pitchAlign
;
295 if (IsPow2(pOut
->pitchAlign
))
297 expPitch
= PowTwoAlign(expPitch
, pOut
->pitchAlign
);
301 expPitch
+= pOut
->pitchAlign
- 1;
302 expPitch
/= pOut
->pitchAlign
;
303 expPitch
*= pOut
->pitchAlign
;
307 if (pIn
->heightAlign
!= 0)
309 ADDR_ASSERT((pIn
->heightAlign
% pOut
->heightAlign
) == 0);
310 pOut
->heightAlign
= pIn
->heightAlign
;
312 if (IsPow2(pOut
->heightAlign
))
314 expHeight
= PowTwoAlign(expHeight
, pOut
->heightAlign
);
318 expHeight
+= pOut
->heightAlign
- 1;
319 expHeight
/= pOut
->heightAlign
;
320 expHeight
*= pOut
->heightAlign
;
324 logicalSliceSize
= BITS_TO_BYTES(expPitch
* expHeight
* pIn
->bpp
);
327 pOut
->pitch
= expPitch
;
328 pOut
->height
= expHeight
;
329 pOut
->depth
= expNumSlices
;
331 pOut
->surfSize
= logicalSliceSize
* expNumSlices
;
333 pOut
->tileMode
= pIn
->tileMode
;
339 ****************************************************************************************************
340 * EgBasedLib::ComputeSurfaceInfoMicroTiled
343 * Compute 1D/Micro Tiled surface sizes include padded pitch, height, slices, total
344 * size in bytes, meanwhile alignments as well. Results are returned through output
348 * TRUE if no error occurs
349 ****************************************************************************************************
351 BOOL_32
EgBasedLib::ComputeSurfaceInfoMicroTiled(
352 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
353 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
354 UINT_32 padDims
, ///< [in] Dimensions to padd
355 AddrTileMode expTileMode
///< [in] Expected tile mode
358 BOOL_32 valid
= TRUE
;
360 UINT_32 microTileThickness
;
361 UINT_32 expPitch
= pIn
->width
;
362 UINT_32 expHeight
= pIn
->height
;
363 UINT_32 expNumSlices
= pIn
->numSlices
;
365 // No 1D MSAA on real H/W, keep this for TGL
366 UINT_32 numSamples
= pOut
->numSamples
;
369 // Compute the micro tile thickness.
371 microTileThickness
= Thickness(expTileMode
);
374 // Extra override for mip levels
376 if (pIn
->mipLevel
> 0)
379 // Reduce tiling mode from thick to thin if the number of slices is less than the
380 // micro tile thickness.
382 if ((expTileMode
== ADDR_TM_1D_TILED_THICK
) &&
383 (expNumSlices
< ThickTileThickness
))
385 expTileMode
= HwlDegradeThickTileMode(ADDR_TM_1D_TILED_THICK
, expNumSlices
, NULL
);
386 if (expTileMode
!= ADDR_TM_1D_TILED_THICK
)
388 microTileThickness
= 1;
394 // Compute the surface restrictions.
396 ComputeSurfaceAlignmentsMicroTiled(expTileMode
,
405 pOut
->depthAlign
= microTileThickness
;
408 // Pad pitch and height to the required granularities.
409 // Compute surface size.
410 // Return parameters.
412 PadDimensions(expTileMode
,
419 &expPitch
, &pOut
->pitchAlign
,
420 &expHeight
, pOut
->heightAlign
,
421 &expNumSlices
, microTileThickness
);
424 // Get HWL specific pitch adjustment
426 UINT_64 logicalSliceSize
= HwlGetSizeAdjustmentMicroTiled(microTileThickness
,
436 pOut
->pitch
= expPitch
;
437 pOut
->height
= expHeight
;
438 pOut
->depth
= expNumSlices
;
440 pOut
->surfSize
= logicalSliceSize
* expNumSlices
;
442 pOut
->tileMode
= expTileMode
;
449 ****************************************************************************************************
450 * EgBasedLib::ComputeSurfaceInfoMacroTiled
453 * Compute 2D/macro tiled surface sizes include padded pitch, height, slices, total
454 * size in bytes, meanwhile output suitable tile mode and alignments might be changed
455 * in this call as well. Results are returned through output parameters.
458 * TRUE if no error occurs
459 ****************************************************************************************************
461 BOOL_32
EgBasedLib::ComputeSurfaceInfoMacroTiled(
462 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
463 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
464 UINT_32 padDims
, ///< [in] Dimensions to padd
465 AddrTileMode expTileMode
///< [in] Expected tile mode
468 BOOL_32 valid
= TRUE
;
470 AddrTileMode origTileMode
= expTileMode
;
471 UINT_32 microTileThickness
;
474 UINT_32 paddedHeight
;
475 UINT_64 bytesPerSlice
;
477 UINT_32 expPitch
= pIn
->width
;
478 UINT_32 expHeight
= pIn
->height
;
479 UINT_32 expNumSlices
= pIn
->numSlices
;
481 UINT_32 numSamples
= pOut
->numSamples
;
484 // Compute the surface restrictions as base
485 // SanityCheckMacroTiled is called in ComputeSurfaceAlignmentsMacroTiled
487 valid
= ComputeSurfaceAlignmentsMacroTiled(expTileMode
,
497 // Compute the micro tile thickness.
499 microTileThickness
= Thickness(expTileMode
);
502 // Find the correct tiling mode for mip levels
504 if (pIn
->mipLevel
> 0)
507 // Try valid tile mode
509 expTileMode
= ComputeSurfaceMipLevelTileMode(expTileMode
,
519 if (!IsMacroTiled(expTileMode
)) // Downgraded to micro-tiled
521 return ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, expTileMode
);
523 else if (microTileThickness
!= Thickness(expTileMode
))
526 // Re-compute if thickness changed since bank-height may be changed!
528 return ComputeSurfaceInfoMacroTiled(pIn
, pOut
, padDims
, expTileMode
);
532 paddedPitch
= expPitch
;
533 paddedHeight
= expHeight
;
538 if (expTileMode
!= origTileMode
) // Tile mode is changed but still macro-tiled
540 valid
= ComputeSurfaceAlignmentsMacroTiled(expTileMode
,
551 PadDimensions(expTileMode
,
558 &paddedPitch
, &pOut
->pitchAlign
,
559 &paddedHeight
, pOut
->heightAlign
,
560 &expNumSlices
, microTileThickness
);
562 if (pIn
->flags
.qbStereo
&&
563 (pOut
->pStereoInfo
!= NULL
))
565 UINT_32 stereoHeightAlign
= HwlStereoCheckRightOffsetPadding(pOut
->pTileInfo
);
567 if (stereoHeightAlign
!= 0)
569 paddedHeight
= PowTwoAlign(paddedHeight
, stereoHeightAlign
);
573 if ((pIn
->flags
.needEquation
== TRUE
) &&
574 (m_chipFamily
== ADDR_CHIP_FAMILY_SI
) &&
575 (pIn
->numMipLevels
> 1) &&
576 (pIn
->mipLevel
== 0))
578 BOOL_32 convertTo1D
= FALSE
;
580 ADDR_ASSERT(Thickness(expTileMode
) == 1);
582 for (UINT_32 i
= 1; i
< pIn
->numMipLevels
; i
++)
584 UINT_32 mipPitch
= Max(1u, paddedPitch
>> i
);
585 UINT_32 mipHeight
= Max(1u, pIn
->height
>> i
);
586 UINT_32 mipSlices
= pIn
->flags
.volume
?
587 Max(1u, pIn
->numSlices
>> i
) : pIn
->numSlices
;
588 expTileMode
= ComputeSurfaceMipLevelTileMode(expTileMode
,
598 if (IsMacroTiled(expTileMode
))
600 if (PowTwoAlign(mipPitch
, pOut
->blockWidth
) !=
601 PowTwoAlign(mipPitch
, pOut
->pitchAlign
))
615 return ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, ADDR_TM_1D_TILED_THIN1
);
619 pOut
->pitch
= paddedPitch
;
620 // Put this check right here to workaround special mipmap cases which the original height
622 // The original height is pre-stored in pOut->height in PostComputeMipLevel and
623 // pOut->pitch is needed in HwlCheckLastMacroTiledLvl, too.
624 if (m_configFlags
.checkLast2DLevel
&& (numSamples
== 1)) // Don't check MSAA
626 // Set a TRUE in pOut if next Level is the first 1D sub level
627 HwlCheckLastMacroTiledLvl(pIn
, pOut
);
629 pOut
->height
= paddedHeight
;
631 pOut
->depth
= expNumSlices
;
634 // Compute the size of a slice.
636 bytesPerSlice
= BITS_TO_BYTES(static_cast<UINT_64
>(paddedPitch
) *
637 paddedHeight
* NextPow2(pIn
->bpp
) * numSamples
);
639 pOut
->surfSize
= bytesPerSlice
* expNumSlices
;
641 pOut
->tileMode
= expTileMode
;
643 pOut
->depthAlign
= microTileThickness
;
651 ****************************************************************************************************
652 * EgBasedLib::ComputeSurfaceAlignmentsLinear
655 * Compute linear surface alignment, calculation results are returned through
659 * TRUE if no error occurs
660 ****************************************************************************************************
662 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsLinear(
663 AddrTileMode tileMode
, ///< [in] tile mode
664 UINT_32 bpp
, ///< [in] bits per pixel
665 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
666 UINT_32
* pBaseAlign
, ///< [out] base address alignment in bytes
667 UINT_32
* pPitchAlign
, ///< [out] pitch alignment in pixels
668 UINT_32
* pHeightAlign
///< [out] height alignment in pixels
671 BOOL_32 valid
= TRUE
;
675 case ADDR_TM_LINEAR_GENERAL
:
677 // The required base alignment and pitch and height granularities is to 1 element.
679 *pBaseAlign
= (bpp
> 8) ? bpp
/ 8 : 1;
683 case ADDR_TM_LINEAR_ALIGNED
:
685 // The required alignment for base is the pipe interleave size.
686 // The required granularity for pitch is hwl dependent.
687 // The required granularity for height is one row.
689 *pBaseAlign
= m_pipeInterleaveBytes
;
690 *pPitchAlign
= HwlGetPitchAlignmentLinear(bpp
, flags
);
697 ADDR_UNHANDLED_CASE();
701 AdjustPitchAlignment(flags
, pPitchAlign
);
707 ****************************************************************************************************
708 * EgBasedLib::ComputeSurfaceAlignmentsMicroTiled
711 * Compute 1D tiled surface alignment, calculation results are returned through
715 * TRUE if no error occurs
716 ****************************************************************************************************
718 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsMicroTiled(
719 AddrTileMode tileMode
, ///< [in] tile mode
720 UINT_32 bpp
, ///< [in] bits per pixel
721 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
722 UINT_32 mipLevel
, ///< [in] mip level
723 UINT_32 numSamples
, ///< [in] number of samples
724 UINT_32
* pBaseAlign
, ///< [out] base address alignment in bytes
725 UINT_32
* pPitchAlign
, ///< [out] pitch alignment in pixels
726 UINT_32
* pHeightAlign
///< [out] height alignment in pixels
729 BOOL_32 valid
= TRUE
;
732 // The required alignment for base is the pipe interleave size.
734 *pBaseAlign
= m_pipeInterleaveBytes
;
736 *pPitchAlign
= HwlGetPitchAlignmentMicroTiled(tileMode
, bpp
, flags
, numSamples
);
738 *pHeightAlign
= MicroTileHeight
;
740 AdjustPitchAlignment(flags
, pPitchAlign
);
743 // Workaround 2 for 1D tiling - There is HW bug for Carrizo
744 // where it requires the following alignments for 1D tiling.
745 if (flags
.czDispCompatible
&& (mipLevel
== 0))
747 *pBaseAlign
= PowTwoAlign(*pBaseAlign
, 4096); //Base address MOD 4096 = 0
748 *pPitchAlign
= PowTwoAlign(*pPitchAlign
, 512 / (BITS_TO_BYTES(bpp
))); //(8 lines * pitch * bytes per pixel) MOD 4096 = 0
750 // end Carrizo workaround for 1D tilling
757 ****************************************************************************************************
758 * EgBasedLib::HwlReduceBankWidthHeight
761 * Additional checks, reduce bankHeight/bankWidth if needed and possible
762 * tileSize*BANK_WIDTH*BANK_HEIGHT <= ROW_SIZE
765 * TRUE if no error occurs
766 ****************************************************************************************************
768 BOOL_32
EgBasedLib::HwlReduceBankWidthHeight(
769 UINT_32 tileSize
, ///< [in] tile size
770 UINT_32 bpp
, ///< [in] bits per pixel
771 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
772 UINT_32 numSamples
, ///< [in] number of samples
773 UINT_32 bankHeightAlign
, ///< [in] bank height alignment
774 UINT_32 pipes
, ///< [in] pipes
775 ADDR_TILEINFO
* pTileInfo
///< [in,out] bank structure.
778 UINT_32 macroAspectAlign
;
779 BOOL_32 valid
= TRUE
;
781 if (tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
)
783 BOOL_32 stillGreater
= TRUE
;
785 // Try reducing bankWidth first
786 if (stillGreater
&& pTileInfo
->bankWidth
> 1)
788 while (stillGreater
&& pTileInfo
->bankWidth
> 0)
790 pTileInfo
->bankWidth
>>= 1;
792 if (pTileInfo
->bankWidth
== 0)
794 pTileInfo
->bankWidth
= 1;
799 tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
;
802 // bankWidth is reduced above, so we need to recalculate bankHeight and ratio
803 bankHeightAlign
= Max(1u,
804 m_pipeInterleaveBytes
* m_bankInterleave
/
805 (tileSize
* pTileInfo
->bankWidth
)
808 // We cannot increase bankHeight so just assert this case.
809 ADDR_ASSERT((pTileInfo
->bankHeight
% bankHeightAlign
) == 0);
813 macroAspectAlign
= Max(1u,
814 m_pipeInterleaveBytes
* m_bankInterleave
/
815 (tileSize
* pipes
* pTileInfo
->bankWidth
)
817 pTileInfo
->macroAspectRatio
= PowTwoAlign(pTileInfo
->macroAspectRatio
,
822 // Early quit bank_height degradation for "64" bit z buffer
823 if (flags
.depth
&& bpp
>= 64)
825 stillGreater
= FALSE
;
828 // Then try reducing bankHeight
829 if (stillGreater
&& pTileInfo
->bankHeight
> bankHeightAlign
)
831 while (stillGreater
&& pTileInfo
->bankHeight
> bankHeightAlign
)
833 pTileInfo
->bankHeight
>>= 1;
835 if (pTileInfo
->bankHeight
< bankHeightAlign
)
837 pTileInfo
->bankHeight
= bankHeightAlign
;
842 tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
;
846 valid
= !stillGreater
;
848 // Generate a warning if we still fail to meet this constraint
852 0, ("TILE_SIZE(%d)*BANK_WIDTH(%d)*BANK_HEIGHT(%d) <= ROW_SIZE(%d)",
853 tileSize
, pTileInfo
->bankWidth
, pTileInfo
->bankHeight
, m_rowSize
));
861 ****************************************************************************************************
862 * EgBasedLib::ComputeSurfaceAlignmentsMacroTiled
865 * Compute 2D tiled surface alignment, calculation results are returned through
869 * TRUE if no error occurs
870 ****************************************************************************************************
872 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsMacroTiled(
873 AddrTileMode tileMode
, ///< [in] tile mode
874 UINT_32 bpp
, ///< [in] bits per pixel
875 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
876 UINT_32 mipLevel
, ///< [in] mip level
877 UINT_32 numSamples
, ///< [in] number of samples
878 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in,out] Surface output
881 ADDR_TILEINFO
* pTileInfo
= pOut
->pTileInfo
;
883 BOOL_32 valid
= SanityCheckMacroTiled(pTileInfo
);
887 UINT_32 macroTileWidth
;
888 UINT_32 macroTileHeight
;
891 UINT_32 bankHeightAlign
;
892 UINT_32 macroAspectAlign
;
894 UINT_32 thickness
= Thickness(tileMode
);
895 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
898 // Align bank height first according to latest h/w spec
901 // tile_size = MIN(tile_split, 64 * tile_thickness * element_bytes * num_samples)
902 tileSize
= Min(pTileInfo
->tileSplitBytes
,
903 BITS_TO_BYTES(64 * thickness
* bpp
* numSamples
));
905 // bank_height_align =
906 // MAX(1, (pipe_interleave_bytes * bank_interleave)/(tile_size*bank_width))
907 bankHeightAlign
= Max(1u,
908 m_pipeInterleaveBytes
* m_bankInterleave
/
909 (tileSize
* pTileInfo
->bankWidth
)
912 pTileInfo
->bankHeight
= PowTwoAlign(pTileInfo
->bankHeight
, bankHeightAlign
);
914 // num_pipes * bank_width * macro_tile_aspect >=
915 // (pipe_interleave_size * bank_interleave) / tile_size
918 // this restriction is only for mipmap (mipmap's numSamples must be 1)
919 macroAspectAlign
= Max(1u,
920 m_pipeInterleaveBytes
* m_bankInterleave
/
921 (tileSize
* pipes
* pTileInfo
->bankWidth
)
923 pTileInfo
->macroAspectRatio
= PowTwoAlign(pTileInfo
->macroAspectRatio
, macroAspectAlign
);
926 valid
= HwlReduceBankWidthHeight(tileSize
,
935 // The required granularity for pitch is the macro tile width.
937 macroTileWidth
= MicroTileWidth
* pTileInfo
->bankWidth
* pipes
*
938 pTileInfo
->macroAspectRatio
;
940 pOut
->pitchAlign
= macroTileWidth
;
941 pOut
->blockWidth
= macroTileWidth
;
943 AdjustPitchAlignment(flags
, &pOut
->pitchAlign
);
946 // The required granularity for height is the macro tile height.
948 macroTileHeight
= MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
/
949 pTileInfo
->macroAspectRatio
;
951 pOut
->heightAlign
= macroTileHeight
;
952 pOut
->blockHeight
= macroTileHeight
;
955 // Compute base alignment
958 pipes
* pTileInfo
->bankWidth
* pTileInfo
->banks
* pTileInfo
->bankHeight
* tileSize
;
960 HwlComputeSurfaceAlignmentsMacroTiled(tileMode
, bpp
, flags
, mipLevel
, numSamples
, pOut
);
967 ****************************************************************************************************
968 * EgBasedLib::SanityCheckMacroTiled
971 * Check if macro-tiled parameters are valid
974 ****************************************************************************************************
976 BOOL_32
EgBasedLib::SanityCheckMacroTiled(
977 ADDR_TILEINFO
* pTileInfo
///< [in] macro-tiled parameters
980 BOOL_32 valid
= TRUE
;
981 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
983 switch (pTileInfo
->banks
)
985 case 2: //fall through
986 case 4: //fall through
987 case 8: //fall through
998 switch (pTileInfo
->bankWidth
)
1000 case 1: //fall through
1001 case 2: //fall through
1002 case 4: //fall through
1013 switch (pTileInfo
->bankHeight
)
1015 case 1: //fall through
1016 case 2: //fall through
1017 case 4: //fall through
1028 switch (pTileInfo
->macroAspectRatio
)
1030 case 1: //fall through
1031 case 2: //fall through
1032 case 4: //fall through
1043 if (pTileInfo
->banks
< pTileInfo
->macroAspectRatio
)
1045 // This will generate macro tile height <= 1
1052 if (pTileInfo
->tileSplitBytes
> m_rowSize
)
1054 ADDR_WARN(0, ("tileSplitBytes is bigger than row size"));
1060 valid
= HwlSanityCheckMacroTiled(pTileInfo
);
1063 ADDR_ASSERT(valid
== TRUE
);
1065 // Add this assert for guidance
1066 ADDR_ASSERT(numPipes
* pTileInfo
->banks
>= 4);
1072 ****************************************************************************************************
1073 * EgBasedLib::ComputeSurfaceMipLevelTileMode
1076 * Compute valid tile mode for surface mipmap sub-levels
1079 * Suitable tile mode
1080 ****************************************************************************************************
1082 AddrTileMode
EgBasedLib::ComputeSurfaceMipLevelTileMode(
1083 AddrTileMode baseTileMode
, ///< [in] base tile mode
1084 UINT_32 bpp
, ///< [in] bits per pixels
1085 UINT_32 pitch
, ///< [in] current level pitch
1086 UINT_32 height
, ///< [in] current level height
1087 UINT_32 numSlices
, ///< [in] current number of slices
1088 UINT_32 numSamples
, ///< [in] number of samples
1089 UINT_32 pitchAlign
, ///< [in] pitch alignment
1090 UINT_32 heightAlign
, ///< [in] height alignment
1091 ADDR_TILEINFO
* pTileInfo
///< [in] ptr to bank structure
1094 UINT_32 bytesPerTile
;
1096 AddrTileMode expTileMode
= baseTileMode
;
1097 UINT_32 microTileThickness
= Thickness(expTileMode
);
1098 UINT_32 interleaveSize
= m_pipeInterleaveBytes
* m_bankInterleave
;
1101 // Compute the size of a slice.
1103 bytesPerTile
= BITS_TO_BYTES(MicroTilePixels
* microTileThickness
* NextPow2(bpp
) * numSamples
);
1106 // Reduce tiling mode from thick to thin if the number of slices is less than the
1107 // micro tile thickness.
1109 if (numSlices
< microTileThickness
)
1111 expTileMode
= HwlDegradeThickTileMode(expTileMode
, numSlices
, &bytesPerTile
);
1114 if (bytesPerTile
> pTileInfo
->tileSplitBytes
)
1116 bytesPerTile
= pTileInfo
->tileSplitBytes
;
1119 UINT_32 threshold1
=
1120 bytesPerTile
* HwlGetPipes(pTileInfo
) * pTileInfo
->bankWidth
* pTileInfo
->macroAspectRatio
;
1122 UINT_32 threshold2
=
1123 bytesPerTile
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
;
1126 // Reduce the tile mode from 2D/3D to 1D in following conditions
1128 switch (expTileMode
)
1130 case ADDR_TM_2D_TILED_THIN1
: //fall through
1131 case ADDR_TM_3D_TILED_THIN1
:
1132 case ADDR_TM_PRT_TILED_THIN1
:
1133 case ADDR_TM_PRT_2D_TILED_THIN1
:
1134 case ADDR_TM_PRT_3D_TILED_THIN1
:
1135 if ((pitch
< pitchAlign
) ||
1136 (height
< heightAlign
) ||
1137 (interleaveSize
> threshold1
) ||
1138 (interleaveSize
> threshold2
))
1140 expTileMode
= ADDR_TM_1D_TILED_THIN1
;
1143 case ADDR_TM_2D_TILED_THICK
: //fall through
1144 case ADDR_TM_3D_TILED_THICK
:
1145 case ADDR_TM_2D_TILED_XTHICK
:
1146 case ADDR_TM_3D_TILED_XTHICK
:
1147 case ADDR_TM_PRT_TILED_THICK
:
1148 case ADDR_TM_PRT_2D_TILED_THICK
:
1149 case ADDR_TM_PRT_3D_TILED_THICK
:
1150 if ((pitch
< pitchAlign
) ||
1151 (height
< heightAlign
))
1153 expTileMode
= ADDR_TM_1D_TILED_THICK
;
1164 ****************************************************************************************************
1165 * EgBasedLib::HwlGetAlignmentInfoMacroTiled
1167 * Get alignment info for giving tile mode
1169 * TRUE if getting alignment is OK
1170 ****************************************************************************************************
1172 BOOL_32
EgBasedLib::HwlGetAlignmentInfoMacroTiled(
1173 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] create surface info
1174 UINT_32
* pPitchAlign
, ///< [out] pitch alignment
1175 UINT_32
* pHeightAlign
, ///< [out] height alignment
1176 UINT_32
* pSizeAlign
///< [out] size alignment
1179 BOOL_32 valid
= TRUE
;
1181 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
1183 UINT_32 numSamples
= (pIn
->numFrags
== 0) ? pIn
->numSamples
: pIn
->numFrags
;
1185 ADDR_ASSERT(pIn
->pTileInfo
);
1186 ADDR_TILEINFO tileInfo
= *pIn
->pTileInfo
;
1187 ADDR_COMPUTE_SURFACE_INFO_OUTPUT out
= {0};
1188 out
.pTileInfo
= &tileInfo
;
1190 if (UseTileIndex(pIn
->tileIndex
))
1192 out
.tileIndex
= pIn
->tileIndex
;
1193 out
.macroModeIndex
= TileIndexInvalid
;
1196 HwlSetupTileInfo(pIn
->tileMode
,
1207 valid
= ComputeSurfaceAlignmentsMacroTiled(pIn
->tileMode
,
1216 *pPitchAlign
= out
.pitchAlign
;
1217 *pHeightAlign
= out
.heightAlign
;
1218 *pSizeAlign
= out
.baseAlign
;
1225 ****************************************************************************************************
1226 * EgBasedLib::HwlDegradeThickTileMode
1229 * Degrades valid tile mode for thick modes if needed
1232 * Suitable tile mode
1233 ****************************************************************************************************
1235 AddrTileMode
EgBasedLib::HwlDegradeThickTileMode(
1236 AddrTileMode baseTileMode
, ///< [in] base tile mode
1237 UINT_32 numSlices
, ///< [in] current number of slices
1238 UINT_32
* pBytesPerTile
///< [in,out] pointer to bytes per slice
1241 ADDR_ASSERT(numSlices
< Thickness(baseTileMode
));
1242 // if pBytesPerTile is NULL, this is a don't-care....
1243 UINT_32 bytesPerTile
= pBytesPerTile
!= NULL
? *pBytesPerTile
: 64;
1245 AddrTileMode expTileMode
= baseTileMode
;
1246 switch (baseTileMode
)
1248 case ADDR_TM_1D_TILED_THICK
:
1249 expTileMode
= ADDR_TM_1D_TILED_THIN1
;
1252 case ADDR_TM_2D_TILED_THICK
:
1253 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1256 case ADDR_TM_3D_TILED_THICK
:
1257 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1260 case ADDR_TM_2D_TILED_XTHICK
:
1261 if (numSlices
< ThickTileThickness
)
1263 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1268 expTileMode
= ADDR_TM_2D_TILED_THICK
;
1272 case ADDR_TM_3D_TILED_XTHICK
:
1273 if (numSlices
< ThickTileThickness
)
1275 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1280 expTileMode
= ADDR_TM_3D_TILED_THICK
;
1285 ADDR_ASSERT_ALWAYS();
1289 if (pBytesPerTile
!= NULL
)
1291 *pBytesPerTile
= bytesPerTile
;
1298 ****************************************************************************************************
1299 * EgBasedLib::DispatchComputeSurfaceAddrFromCoord
1302 * Compute surface address from given coord (x, y, slice,sample)
1306 ****************************************************************************************************
1308 UINT_64
EgBasedLib::DispatchComputeSurfaceAddrFromCoord(
1309 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1310 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1315 UINT_32 slice
= pIn
->slice
;
1316 UINT_32 sample
= pIn
->sample
;
1317 UINT_32 bpp
= pIn
->bpp
;
1318 UINT_32 pitch
= pIn
->pitch
;
1319 UINT_32 height
= pIn
->height
;
1320 UINT_32 numSlices
= pIn
->numSlices
;
1321 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
1322 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
1323 AddrTileMode tileMode
= pIn
->tileMode
;
1324 AddrTileType microTileType
= pIn
->tileType
;
1325 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
1326 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
1327 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
1329 UINT_32
* pBitPosition
= &pOut
->bitPosition
;
1333 UINT_32 addr5Bit
= 0;
1334 UINT_32 addr5Swizzle
= pIn
->addr5Swizzle
;
1335 BOOL_32 is32ByteTile
= pIn
->is32ByteTile
;
1338 // ADDR_DEPTH_SAMPLE_ORDER = non-disp + depth-sample-order
1339 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
1341 isDepthSampleOrder
= TRUE
;
1344 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
1346 if (numFrags
!= numSamples
)
1348 numSamples
= numFrags
;
1349 ADDR_ASSERT(sample
< numSamples
);
1353 /// 128 bit/thick tiled surface doesn't support display tiling and
1354 /// mipmap chain must have the same tileType, so please fill tileType correctly
1355 if (IsLinear(pIn
->tileMode
) == FALSE
)
1357 if (bpp
>= 128 || Thickness(tileMode
) > 1)
1359 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
1366 case ADDR_TM_LINEAR_GENERAL
://fall through
1367 case ADDR_TM_LINEAR_ALIGNED
:
1368 addr
= ComputeSurfaceAddrFromCoordLinear(x
,
1378 case ADDR_TM_1D_TILED_THIN1
://fall through
1379 case ADDR_TM_1D_TILED_THICK
:
1380 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
1393 case ADDR_TM_2D_TILED_THIN1
: //fall through
1394 case ADDR_TM_2D_TILED_THICK
: //fall through
1395 case ADDR_TM_3D_TILED_THIN1
: //fall through
1396 case ADDR_TM_3D_TILED_THICK
: //fall through
1397 case ADDR_TM_2D_TILED_XTHICK
: //fall through
1398 case ADDR_TM_3D_TILED_XTHICK
: //fall through
1399 case ADDR_TM_PRT_TILED_THIN1
: //fall through
1400 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
1401 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
1402 case ADDR_TM_PRT_TILED_THICK
: //fall through
1403 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
1404 case ADDR_TM_PRT_3D_TILED_THICK
:
1405 UINT_32 pipeSwizzle
;
1406 UINT_32 bankSwizzle
;
1408 if (m_configFlags
.useCombinedSwizzle
)
1410 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
1411 &bankSwizzle
, &pipeSwizzle
);
1415 pipeSwizzle
= pIn
->pipeSwizzle
;
1416 bankSwizzle
= pIn
->bankSwizzle
;
1419 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
1438 ADDR_ASSERT_ALWAYS();
1443 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
1445 if (addr5Swizzle
&& isDepthSampleOrder
&& is32ByteTile
)
1447 UINT_32 tx
= x
>> 3;
1448 UINT_32 ty
= y
>> 3;
1449 UINT_32 tileBits
= ((ty
&0x3) << 2) | (tx
&0x3);
1451 tileBits
= tileBits
& addr5Swizzle
;
1452 addr5Bit
= XorReduce(tileBits
, 4);
1454 addr
= addr
| static_cast<UINT_64
>(addr5Bit
<< 5);
1463 ****************************************************************************************************
1464 * EgBasedLib::ComputeMacroTileEquation
1467 * Computes the address equation in macro tile
1469 * If equation can be computed
1470 ****************************************************************************************************
1472 ADDR_E_RETURNCODE
EgBasedLib::ComputeMacroTileEquation(
1473 UINT_32 log2BytesPP
, ///< [in] log2 of bytes per pixel
1474 AddrTileMode tileMode
, ///< [in] tile mode
1475 AddrTileType microTileType
, ///< [in] micro tiling type
1476 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure
1477 ADDR_EQUATION
* pEquation
///< [out] Equation for addressing in macro tile
1480 ADDR_E_RETURNCODE retCode
;
1482 // Element equation within a tile
1483 retCode
= ComputeMicroTileEquation(log2BytesPP
, tileMode
, microTileType
, pEquation
);
1485 if (retCode
== ADDR_OK
)
1487 // Tile equesiton with signle pipe bank
1488 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1489 UINT_32 numPipeBits
= Log2(numPipes
);
1491 for (UINT_32 i
= 0; i
< Log2(pTileInfo
->bankWidth
); i
++)
1493 pEquation
->addr
[pEquation
->numBits
].valid
= 1;
1494 pEquation
->addr
[pEquation
->numBits
].channel
= 0;
1495 pEquation
->addr
[pEquation
->numBits
].index
= i
+ log2BytesPP
+ 3 + numPipeBits
;
1496 pEquation
->numBits
++;
1499 for (UINT_32 i
= 0; i
< Log2(pTileInfo
->bankHeight
); i
++)
1501 pEquation
->addr
[pEquation
->numBits
].valid
= 1;
1502 pEquation
->addr
[pEquation
->numBits
].channel
= 1;
1503 pEquation
->addr
[pEquation
->numBits
].index
= i
+ 3;
1504 pEquation
->numBits
++;
1507 ADDR_EQUATION equation
;
1508 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
1510 UINT_32 thresholdX
= 32;
1511 UINT_32 thresholdY
= 32;
1513 if (IsPrtNoRotationTileMode(tileMode
))
1515 UINT_32 macroTilePitch
=
1516 (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
) * pTileInfo
->macroAspectRatio
;
1517 UINT_32 macroTileHeight
=
1518 (MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
) /
1519 pTileInfo
->macroAspectRatio
;
1520 thresholdX
= Log2(macroTilePitch
);
1521 thresholdY
= Log2(macroTileHeight
);
1525 retCode
= ComputePipeEquation(log2BytesPP
, thresholdX
, thresholdY
, pTileInfo
, &equation
);
1527 if (retCode
== ADDR_OK
)
1529 UINT_32 pipeBitStart
= Log2(m_pipeInterleaveBytes
);
1531 if (pEquation
->numBits
> pipeBitStart
)
1533 UINT_32 numLeftShift
= pEquation
->numBits
- pipeBitStart
;
1535 for (UINT_32 i
= 0; i
< numLeftShift
; i
++)
1537 pEquation
->addr
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1538 pEquation
->addr
[pEquation
->numBits
- i
- 1];
1539 pEquation
->xor1
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1540 pEquation
->xor1
[pEquation
->numBits
- i
- 1];
1541 pEquation
->xor2
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1542 pEquation
->xor2
[pEquation
->numBits
- i
- 1];
1546 for (UINT_32 i
= 0; i
< equation
.numBits
; i
++)
1548 pEquation
->addr
[pipeBitStart
+ i
] = equation
.addr
[i
];
1549 pEquation
->xor1
[pipeBitStart
+ i
] = equation
.xor1
[i
];
1550 pEquation
->xor2
[pipeBitStart
+ i
] = equation
.xor2
[i
];
1551 pEquation
->numBits
++;
1555 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
1557 retCode
= ComputeBankEquation(log2BytesPP
, thresholdX
, thresholdY
,
1558 pTileInfo
, &equation
);
1560 if (retCode
== ADDR_OK
)
1562 UINT_32 bankBitStart
= pipeBitStart
+ numPipeBits
+ Log2(m_bankInterleave
);
1564 if (pEquation
->numBits
> bankBitStart
)
1566 UINT_32 numLeftShift
= pEquation
->numBits
- bankBitStart
;
1568 for (UINT_32 i
= 0; i
< numLeftShift
; i
++)
1570 pEquation
->addr
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1571 pEquation
->addr
[pEquation
->numBits
- i
- 1];
1572 pEquation
->xor1
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1573 pEquation
->xor1
[pEquation
->numBits
- i
- 1];
1574 pEquation
->xor2
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1575 pEquation
->xor2
[pEquation
->numBits
- i
- 1];
1579 for (UINT_32 i
= 0; i
< equation
.numBits
; i
++)
1581 pEquation
->addr
[bankBitStart
+ i
] = equation
.addr
[i
];
1582 pEquation
->xor1
[bankBitStart
+ i
] = equation
.xor1
[i
];
1583 pEquation
->xor2
[bankBitStart
+ i
] = equation
.xor2
[i
];
1584 pEquation
->numBits
++;
1594 ****************************************************************************************************
1595 * EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1598 * Computes the surface address and bit position from a
1599 * coordinate for 2D tilied (macro tiled)
1602 ****************************************************************************************************
1604 UINT_64
EgBasedLib::ComputeSurfaceAddrFromCoordMacroTiled(
1605 UINT_32 x
, ///< [in] x coordinate
1606 UINT_32 y
, ///< [in] y coordinate
1607 UINT_32 slice
, ///< [in] slice index
1608 UINT_32 sample
, ///< [in] sample index
1609 UINT_32 bpp
, ///< [in] bits per pixel
1610 UINT_32 pitch
, ///< [in] surface pitch, in pixels
1611 UINT_32 height
, ///< [in] surface height, in pixels
1612 UINT_32 numSamples
, ///< [in] number of samples
1613 AddrTileMode tileMode
, ///< [in] tile mode
1614 AddrTileType microTileType
, ///< [in] micro tiling type
1615 BOOL_32 ignoreSE
, ///< [in] TRUE if shader enginers can be ignored
1616 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if it depth sample ordering is used
1617 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
1618 UINT_32 bankSwizzle
, ///< [in] bank swizzle
1619 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure
1620 /// **All fields to be valid on entry**
1621 UINT_32
* pBitPosition
///< [out] bit position, e.g. FMT_1 will use this
1626 UINT_32 microTileBytes
;
1627 UINT_32 microTileBits
;
1628 UINT_32 sampleOffset
;
1630 UINT_32 pixelOffset
;
1631 UINT_32 elementOffset
;
1632 UINT_32 tileSplitSlice
;
1636 UINT_64 sliceOffset
;
1637 UINT_32 macroTilePitch
;
1638 UINT_32 macroTileHeight
;
1639 UINT_32 macroTilesPerRow
;
1640 UINT_32 macroTilesPerSlice
;
1641 UINT_64 macroTileBytes
;
1642 UINT_32 macroTileIndexX
;
1643 UINT_32 macroTileIndexY
;
1644 UINT_64 macroTileOffset
;
1645 UINT_64 totalOffset
;
1646 UINT_64 pipeInterleaveMask
;
1647 UINT_64 bankInterleaveMask
;
1648 UINT_64 pipeInterleaveOffset
;
1649 UINT_32 bankInterleaveOffset
;
1651 UINT_32 tileRowIndex
;
1652 UINT_32 tileColumnIndex
;
1656 UINT_32 microTileThickness
= Thickness(tileMode
);
1659 // Compute the number of group, pipe, and bank bits.
1661 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1662 UINT_32 numPipeInterleaveBits
= Log2(m_pipeInterleaveBytes
);
1663 UINT_32 numPipeBits
= Log2(numPipes
);
1664 UINT_32 numBankInterleaveBits
= Log2(m_bankInterleave
);
1665 UINT_32 numBankBits
= Log2(pTileInfo
->banks
);
1668 // Compute the micro tile size.
1670 microTileBits
= MicroTilePixels
* microTileThickness
* bpp
* numSamples
;
1672 microTileBytes
= microTileBits
/ 8;
1674 // Compute the pixel index within the micro tile.
1676 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
1684 // Compute the sample offset and pixel offset.
1686 if (isDepthSampleOrder
)
1689 // For depth surfaces, samples are stored contiguously for each element, so the sample
1690 // offset is the sample number times the element size.
1692 sampleOffset
= sample
* bpp
;
1693 pixelOffset
= pixelIndex
* bpp
* numSamples
;
1698 // For color surfaces, all elements for a particular sample are stored contiguously, so
1699 // the sample offset is the sample number times the micro tile size divided yBit the number
1702 sampleOffset
= sample
* (microTileBits
/ numSamples
);
1703 pixelOffset
= pixelIndex
* bpp
;
1707 // Compute the element offset.
1709 elementOffset
= pixelOffset
+ sampleOffset
;
1711 *pBitPosition
= static_cast<UINT_32
>(elementOffset
% 8);
1713 elementOffset
/= 8; //bit-to-byte
1716 // Determine if tiles need to be split across slices.
1718 // If the size of the micro tile is larger than the tile split size, then the tile will be
1719 // split across multiple slices.
1721 UINT_32 slicesPerTile
= 1;
1723 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
1724 { //don't support for thick mode
1727 // Compute the number of slices per tile.
1729 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
1732 // Compute the tile split slice number for use in rotating the bank.
1734 tileSplitSlice
= elementOffset
/ pTileInfo
->tileSplitBytes
;
1737 // Adjust the element offset to account for the portion of the tile that is being moved to
1740 elementOffset
%= pTileInfo
->tileSplitBytes
;
1743 // Adjust the microTileBytes size to tileSplitBytes size since
1746 microTileBytes
= pTileInfo
->tileSplitBytes
;
1754 // Compute macro tile pitch and height.
1757 (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
) * pTileInfo
->macroAspectRatio
;
1759 (MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
) / pTileInfo
->macroAspectRatio
;
1762 // Compute the number of bytes per macro tile. Note: bytes of the same bank/pipe actually
1765 static_cast<UINT_64
>(microTileBytes
) *
1766 (macroTilePitch
/ MicroTileWidth
) * (macroTileHeight
/ MicroTileHeight
) /
1767 (numPipes
* pTileInfo
->banks
);
1770 // Compute the number of macro tiles per row.
1772 macroTilesPerRow
= pitch
/ macroTilePitch
;
1775 // Compute the offset to the macro tile containing the specified coordinate.
1777 macroTileIndexX
= x
/ macroTilePitch
;
1778 macroTileIndexY
= y
/ macroTileHeight
;
1779 macroTileOffset
= ((macroTileIndexY
* macroTilesPerRow
) + macroTileIndexX
) * macroTileBytes
;
1782 // Compute the number of macro tiles per slice.
1784 macroTilesPerSlice
= macroTilesPerRow
* (height
/ macroTileHeight
);
1787 // Compute the slice size.
1789 sliceBytes
= macroTilesPerSlice
* macroTileBytes
;
1792 // Compute the slice offset.
1794 sliceOffset
= sliceBytes
* (tileSplitSlice
+ slicesPerTile
* (slice
/ microTileThickness
));
1797 // Compute tile offest
1799 tileRowIndex
= (y
/ MicroTileHeight
) % pTileInfo
->bankHeight
;
1800 tileColumnIndex
= ((x
/ MicroTileWidth
) / numPipes
) % pTileInfo
->bankWidth
;
1801 tileIndex
= (tileRowIndex
* pTileInfo
->bankWidth
) + tileColumnIndex
;
1802 tileOffset
= tileIndex
* microTileBytes
;
1805 // Combine the slice offset and macro tile offset with the pixel and sample offsets, accounting
1806 // for the pipe and bank bits in the middle of the address.
1808 totalOffset
= sliceOffset
+ macroTileOffset
+ elementOffset
+ tileOffset
;
1811 // Get the pipe and bank.
1814 // when the tileMode is PRT type, then adjust x and y coordinates
1815 if (IsPrtNoRotationTileMode(tileMode
))
1817 x
= x
% macroTilePitch
;
1818 y
= y
% macroTileHeight
;
1821 pipe
= ComputePipeFromCoord(x
,
1829 bank
= ComputeBankFromCoord(x
,
1839 // Split the offset to put some bits below the pipe+bank bits and some above.
1841 pipeInterleaveMask
= (1 << numPipeInterleaveBits
) - 1;
1842 bankInterleaveMask
= (1 << numBankInterleaveBits
) - 1;
1843 pipeInterleaveOffset
= totalOffset
& pipeInterleaveMask
;
1844 bankInterleaveOffset
= static_cast<UINT_32
>((totalOffset
>> numPipeInterleaveBits
) &
1845 bankInterleaveMask
);
1846 offset
= totalOffset
>> (numPipeInterleaveBits
+ numBankInterleaveBits
);
1849 // Assemble the address from its components.
1851 addr
= pipeInterleaveOffset
;
1852 // This is to remove /analyze warnings
1853 UINT_32 pipeBits
= pipe
<< numPipeInterleaveBits
;
1854 UINT_32 bankInterleaveBits
= bankInterleaveOffset
<< (numPipeInterleaveBits
+ numPipeBits
);
1855 UINT_32 bankBits
= bank
<< (numPipeInterleaveBits
+ numPipeBits
+
1856 numBankInterleaveBits
);
1857 UINT_64 offsetBits
= offset
<< (numPipeInterleaveBits
+ numPipeBits
+
1858 numBankInterleaveBits
+ numBankBits
);
1861 addr
|= bankInterleaveBits
;
1869 ****************************************************************************************************
1870 * EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1873 * Computes the surface address and bit position from a coordinate for 1D tilied
1877 ****************************************************************************************************
1879 UINT_64
EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled(
1880 UINT_32 x
, ///< [in] x coordinate
1881 UINT_32 y
, ///< [in] y coordinate
1882 UINT_32 slice
, ///< [in] slice index
1883 UINT_32 sample
, ///< [in] sample index
1884 UINT_32 bpp
, ///< [in] bits per pixel
1885 UINT_32 pitch
, ///< [in] pitch, in pixels
1886 UINT_32 height
, ///< [in] height, in pixels
1887 UINT_32 numSamples
, ///< [in] number of samples
1888 AddrTileMode tileMode
, ///< [in] tile mode
1889 AddrTileType microTileType
, ///< [in] micro tiling type
1890 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if depth sample ordering is used
1891 UINT_32
* pBitPosition
///< [out] bit position, e.g. FMT_1 will use this
1896 UINT_32 microTileBytes
;
1898 UINT_32 microTilesPerRow
;
1899 UINT_32 microTileIndexX
;
1900 UINT_32 microTileIndexY
;
1901 UINT_32 microTileIndexZ
;
1902 UINT_64 sliceOffset
;
1903 UINT_64 microTileOffset
;
1904 UINT_32 sampleOffset
;
1906 UINT_32 pixelOffset
;
1908 UINT_32 microTileThickness
= Thickness(tileMode
);
1911 // Compute the micro tile size.
1913 microTileBytes
= BITS_TO_BYTES(MicroTilePixels
* microTileThickness
* bpp
* numSamples
);
1916 // Compute the slice size.
1919 BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* microTileThickness
* bpp
* numSamples
);
1922 // Compute the number of micro tiles per row.
1924 microTilesPerRow
= pitch
/ MicroTileWidth
;
1927 // Compute the micro tile index.
1929 microTileIndexX
= x
/ MicroTileWidth
;
1930 microTileIndexY
= y
/ MicroTileHeight
;
1931 microTileIndexZ
= slice
/ microTileThickness
;
1934 // Compute the slice offset.
1936 sliceOffset
= static_cast<UINT_64
>(microTileIndexZ
) * sliceBytes
;
1939 // Compute the offset to the micro tile containing the specified coordinate.
1941 microTileOffset
= (static_cast<UINT_64
>(microTileIndexY
) * microTilesPerRow
+ microTileIndexX
) *
1945 // Compute the pixel index within the micro tile.
1947 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
1954 // Compute the sample offset.
1956 if (isDepthSampleOrder
)
1959 // For depth surfaces, samples are stored contiguously for each element, so the sample
1960 // offset is the sample number times the element size.
1962 sampleOffset
= sample
* bpp
;
1963 pixelOffset
= pixelIndex
* bpp
* numSamples
;
1968 // For color surfaces, all elements for a particular sample are stored contiguously, so
1969 // the sample offset is the sample number times the micro tile size divided yBit the number
1972 sampleOffset
= sample
* (microTileBytes
*8 / numSamples
);
1973 pixelOffset
= pixelIndex
* bpp
;
1977 // Compute the bit position of the pixel. Each element is stored with one bit per sample.
1980 UINT_32 elemOffset
= sampleOffset
+ pixelOffset
;
1982 *pBitPosition
= elemOffset
% 8;
1986 // Combine the slice offset, micro tile offset, sample offset, and pixel offsets.
1988 addr
= sliceOffset
+ microTileOffset
+ elemOffset
;
1994 ****************************************************************************************************
1995 * EgBasedLib::HwlComputePixelCoordFromOffset
1998 * Compute pixel coordinate from offset inside a micro tile
2001 ****************************************************************************************************
2003 VOID
EgBasedLib::HwlComputePixelCoordFromOffset(
2004 UINT_32 offset
, ///< [in] offset inside micro tile in bits
2005 UINT_32 bpp
, ///< [in] bits per pixel
2006 UINT_32 numSamples
, ///< [in] number of samples
2007 AddrTileMode tileMode
, ///< [in] tile mode
2008 UINT_32 tileBase
, ///< [in] base offset within a tile
2009 UINT_32 compBits
, ///< [in] component bits actually needed(for planar surface)
2010 UINT_32
* pX
, ///< [out] x coordinate
2011 UINT_32
* pY
, ///< [out] y coordinate
2012 UINT_32
* pSlice
, ///< [out] slice index
2013 UINT_32
* pSample
, ///< [out] sample index
2014 AddrTileType microTileType
, ///< [in] micro tiling type
2015 BOOL_32 isDepthSampleOrder
///< [in] TRUE if depth sample order in microtile is used
2021 UINT_32 thickness
= Thickness(tileMode
);
2023 // For planar surface, we adjust offset acoording to tile base
2024 if ((bpp
!= compBits
) && (compBits
!= 0) && isDepthSampleOrder
)
2028 ADDR_ASSERT(microTileType
== ADDR_NON_DISPLAYABLE
||
2029 microTileType
== ADDR_DEPTH_SAMPLE_ORDER
);
2034 UINT_32 sampleTileBits
;
2035 UINT_32 samplePixelBits
;
2038 if (isDepthSampleOrder
)
2040 samplePixelBits
= bpp
* numSamples
;
2041 pixelIndex
= offset
/ samplePixelBits
;
2042 *pSample
= (offset
% samplePixelBits
) / bpp
;
2046 sampleTileBits
= MicroTilePixels
* bpp
* thickness
;
2047 *pSample
= offset
/ sampleTileBits
;
2048 pixelIndex
= (offset
% sampleTileBits
) / bpp
;
2051 if (microTileType
!= ADDR_THICK
)
2053 if (microTileType
== ADDR_DISPLAYABLE
) // displayable
2058 x
= pixelIndex
& 0x7;
2059 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,4));
2062 x
= pixelIndex
& 0x7;
2063 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,3));
2066 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,1),_BIT(pixelIndex
,0));
2067 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,2));
2070 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2071 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
2074 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,2),_BIT(pixelIndex
,1));
2075 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,0));
2081 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2083 x
= Bits2Number(3, _BIT(pixelIndex
,4),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2084 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
2086 else if (microTileType
== ADDR_ROTATED
)
2090 element_index[5:0] = { x[2], x[0], x[1], y[2], y[1], y[0] }
2093 element_index[5:0] = { x[2], x[1], x[0], y[2], y[1], y[0] }
2096 element_index[5:0] = { x[2], x[1], y[2], x[0], y[1], y[0] }
2099 element_index[5:0] = { y[2], x[2], x[1], y[1], x[0], y[0] }
2104 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,4));
2105 y
= pixelIndex
& 0x7;
2108 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,3));
2109 y
= pixelIndex
& 0x7;
2112 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,2));
2113 y
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,1),_BIT(pixelIndex
,0));
2116 x
= Bits2Number(3, _BIT(pixelIndex
,4),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
2117 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2120 ADDR_ASSERT_ALWAYS();
2125 if (thickness
> 1) // thick
2127 z
= Bits2Number(3, _BIT(pixelIndex
,8),_BIT(pixelIndex
,7),_BIT(pixelIndex
,6));
2132 ADDR_ASSERT((m_chipFamily
>= ADDR_CHIP_FAMILY_CI
) && (thickness
> 1));
2134 8-Bit Elements and 16-Bit Elements
2135 element_index[7:0] = { y[2], x[2], z[1], z[0], y[1], x[1], y[0], x[0] }
2138 element_index[7:0] = { y[2], x[2], z[1], y[1], z[0], x[1], y[0], x[0] }
2140 64-Bit Elements and 128-Bit Elements
2141 element_index[7:0] = { y[2], x[2], z[1], y[1], x[1], z[0], y[0], x[0] }
2143 The equation to compute the element index for the extra thick tile:
2144 element_index[8] = z[2]
2149 case 16: // fall-through
2150 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2151 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
2152 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4));
2155 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2156 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
2157 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3));
2160 case 128: // fall-through
2161 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,3),_BIT(pixelIndex
,0));
2162 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
2163 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,2));
2166 ADDR_ASSERT_ALWAYS();
2172 z
+= Bits2Number(3,_BIT(pixelIndex
,8),0,0);
2183 ****************************************************************************************************
2184 * EgBasedLib::DispatchComputeSurfaceCoordFromAddrDispatch
2187 * Compute (x,y,slice,sample) coordinates from surface address
2190 ****************************************************************************************************
2192 VOID
EgBasedLib::DispatchComputeSurfaceCoordFromAddr(
2193 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
2194 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
2197 UINT_64 addr
= pIn
->addr
;
2198 UINT_32 bitPosition
= pIn
->bitPosition
;
2199 UINT_32 bpp
= pIn
->bpp
;
2200 UINT_32 pitch
= pIn
->pitch
;
2201 UINT_32 height
= pIn
->height
;
2202 UINT_32 numSlices
= pIn
->numSlices
;
2203 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
2204 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
2205 AddrTileMode tileMode
= pIn
->tileMode
;
2206 UINT_32 tileBase
= pIn
->tileBase
;
2207 UINT_32 compBits
= pIn
->compBits
;
2208 AddrTileType microTileType
= pIn
->tileType
;
2209 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
2210 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
2211 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2213 UINT_32
* pX
= &pOut
->x
;
2214 UINT_32
* pY
= &pOut
->y
;
2215 UINT_32
* pSlice
= &pOut
->slice
;
2216 UINT_32
* pSample
= &pOut
->sample
;
2218 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2220 isDepthSampleOrder
= TRUE
;
2223 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
2225 if (numFrags
!= numSamples
)
2227 numSamples
= numFrags
;
2231 /// 128 bit/thick tiled surface doesn't support display tiling and
2232 /// mipmap chain must have the same tileType, so please fill tileType correctly
2233 if (IsLinear(pIn
->tileMode
) == FALSE
)
2235 if (bpp
>= 128 || Thickness(tileMode
) > 1)
2237 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
2244 case ADDR_TM_LINEAR_GENERAL
://fall through
2245 case ADDR_TM_LINEAR_ALIGNED
:
2246 ComputeSurfaceCoordFromAddrLinear(addr
,
2257 case ADDR_TM_1D_TILED_THIN1
://fall through
2258 case ADDR_TM_1D_TILED_THICK
:
2259 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
2273 isDepthSampleOrder
);
2275 case ADDR_TM_2D_TILED_THIN1
: //fall through
2276 case ADDR_TM_2D_TILED_THICK
: //fall through
2277 case ADDR_TM_3D_TILED_THIN1
: //fall through
2278 case ADDR_TM_3D_TILED_THICK
: //fall through
2279 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2280 case ADDR_TM_3D_TILED_XTHICK
: //fall through
2281 case ADDR_TM_PRT_TILED_THIN1
: //fall through
2282 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
2283 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
2284 case ADDR_TM_PRT_TILED_THICK
: //fall through
2285 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
2286 case ADDR_TM_PRT_3D_TILED_THICK
:
2287 UINT_32 pipeSwizzle
;
2288 UINT_32 bankSwizzle
;
2290 if (m_configFlags
.useCombinedSwizzle
)
2292 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
2293 &bankSwizzle
, &pipeSwizzle
);
2297 pipeSwizzle
= pIn
->pipeSwizzle
;
2298 bankSwizzle
= pIn
->bankSwizzle
;
2301 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
2322 ADDR_ASSERT_ALWAYS();
2328 ****************************************************************************************************
2329 * EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled
2332 * Compute surface coordinates from address for macro tiled surface
2335 ****************************************************************************************************
2337 VOID
EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled(
2338 UINT_64 addr
, ///< [in] byte address
2339 UINT_32 bitPosition
, ///< [in] bit position
2340 UINT_32 bpp
, ///< [in] bits per pixel
2341 UINT_32 pitch
, ///< [in] pitch in pixels
2342 UINT_32 height
, ///< [in] height in pixels
2343 UINT_32 numSamples
, ///< [in] number of samples
2344 AddrTileMode tileMode
, ///< [in] tile mode
2345 UINT_32 tileBase
, ///< [in] tile base offset
2346 UINT_32 compBits
, ///< [in] component bits (for planar surface)
2347 AddrTileType microTileType
, ///< [in] micro tiling type
2348 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines can be ignored
2349 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if depth sample order is used
2350 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2351 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2352 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure.
2353 /// **All fields to be valid on entry**
2354 UINT_32
* pX
, ///< [out] X coord
2355 UINT_32
* pY
, ///< [out] Y coord
2356 UINT_32
* pSlice
, ///< [out] slice index
2357 UINT_32
* pSample
///< [out] sample index
2363 UINT_64 macroTileBits
;
2366 UINT_64 elementOffset
;
2367 UINT_64 macroTileIndex
;
2369 UINT_64 totalOffset
;
2374 UINT_32 groupBits
= m_pipeInterleaveBytes
<< 3;
2375 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2376 UINT_32 banks
= pTileInfo
->banks
;
2378 UINT_32 bankInterleave
= m_bankInterleave
;
2380 UINT_64 addrBits
= BYTES_TO_BITS(addr
) + bitPosition
;
2383 // remove bits for bank and pipe
2385 totalOffset
= (addrBits
% groupBits
) +
2386 (((addrBits
/ groupBits
/ pipes
) % bankInterleave
) * groupBits
) +
2387 (((addrBits
/ groupBits
/ pipes
) / bankInterleave
) / banks
) * groupBits
* bankInterleave
;
2389 UINT_32 microTileThickness
= Thickness(tileMode
);
2391 UINT_32 microTileBits
= bpp
* microTileThickness
* MicroTilePixels
* numSamples
;
2393 UINT_32 microTileBytes
= BITS_TO_BYTES(microTileBits
);
2395 // Determine if tiles need to be split across slices.
2397 // If the size of the micro tile is larger than the tile split size, then the tile will be
2398 // split across multiple slices.
2400 UINT_32 slicesPerTile
= 1; //_State->TileSlices
2402 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
2403 { //don't support for thick mode
2406 // Compute the number of slices per tile.
2408 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
2411 tileBits
= microTileBits
/ slicesPerTile
; // micro tile bits
2413 // in micro tiles because not MicroTileWidth timed.
2414 UINT_32 macroWidth
= pTileInfo
->bankWidth
* pipes
* pTileInfo
->macroAspectRatio
;
2415 // in micro tiles as well
2416 UINT_32 macroHeight
= pTileInfo
->bankHeight
* banks
/ pTileInfo
->macroAspectRatio
;
2418 UINT_32 pitchInMacroTiles
= pitch
/ MicroTileWidth
/ macroWidth
;
2420 macroTileBits
= (macroWidth
* macroHeight
) * tileBits
/ (banks
* pipes
);
2422 macroTileIndex
= totalOffset
/ macroTileBits
;
2424 // pitchMacros * height / heightMacros; macroTilesPerSlice == _State->SliceMacros
2425 UINT_32 macroTilesPerSlice
= (pitch
/ (macroWidth
* MicroTileWidth
)) * height
/
2426 (macroHeight
* MicroTileWidth
);
2428 slices
= static_cast<UINT_32
>(macroTileIndex
/ macroTilesPerSlice
);
2430 *pSlice
= static_cast<UINT_32
>(slices
/ slicesPerTile
* microTileThickness
);
2433 // calculate element offset and x[2:0], y[2:0], z[1:0] for thick
2435 tileSlices
= slices
% slicesPerTile
;
2437 elementOffset
= tileSlices
* tileBits
;
2438 elementOffset
+= totalOffset
% tileBits
;
2442 HwlComputePixelCoordFromOffset(static_cast<UINT_32
>(elementOffset
),
2453 isDepthSampleOrder
);
2455 macroTileIndex
= macroTileIndex
% macroTilesPerSlice
;
2456 *pY
+= static_cast<UINT_32
>(macroTileIndex
/ pitchInMacroTiles
* macroHeight
* MicroTileHeight
);
2457 *pX
+= static_cast<UINT_32
>(macroTileIndex
% pitchInMacroTiles
* macroWidth
* MicroTileWidth
);
2461 tileIndex
= static_cast<UINT_32
>((totalOffset
% macroTileBits
) / tileBits
);
2463 my
= (tileIndex
/ pTileInfo
->bankWidth
) % pTileInfo
->bankHeight
* MicroTileHeight
;
2464 mx
= (tileIndex
% pTileInfo
->bankWidth
) * pipes
* MicroTileWidth
;
2469 bank
= ComputeBankFromAddr(addr
, banks
, pipes
);
2470 pipe
= ComputePipeFromAddr(addr
, pipes
);
2472 HwlComputeSurfaceCoord2DFromBankPipe(tileMode
,
2486 ****************************************************************************************************
2487 * EgBasedLib::ComputeSurfaceCoord2DFromBankPipe
2490 * Compute surface x,y coordinates from bank/pipe info
2493 ****************************************************************************************************
2495 VOID
EgBasedLib::ComputeSurfaceCoord2DFromBankPipe(
2496 AddrTileMode tileMode
, ///< [in] tile mode
2497 UINT_32 x
, ///< [in] x coordinate
2498 UINT_32 y
, ///< [in] y coordinate
2499 UINT_32 slice
, ///< [in] slice index
2500 UINT_32 bank
, ///< [in] bank number
2501 UINT_32 pipe
, ///< [in] pipe number
2502 UINT_32 bankSwizzle
,///< [in] bank swizzle
2503 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
2504 UINT_32 tileSlices
, ///< [in] slices in a micro tile
2505 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure. **All fields to be valid on entry**
2506 CoordFromBankPipe
* pOutput
///< [out] pointer to extracted x/y bits
2518 UINT_32 tileSplitRotation
;
2520 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2522 UINT_32 bankRotation
= ComputeBankRotation(tileMode
,
2523 pTileInfo
->banks
, numPipes
);
2525 UINT_32 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2527 UINT_32 xBit
= x
/ (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
);
2528 UINT_32 yBit
= y
/ (MicroTileHeight
* pTileInfo
->bankHeight
);
2530 //calculate the bank and pipe before rotation and swizzle
2534 case ADDR_TM_2D_TILED_THIN1
: //fall through
2535 case ADDR_TM_2D_TILED_THICK
: //fall through
2536 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2537 case ADDR_TM_3D_TILED_THIN1
: //fall through
2538 case ADDR_TM_3D_TILED_THICK
: //fall through
2539 case ADDR_TM_3D_TILED_XTHICK
:
2540 tileSplitRotation
= ((pTileInfo
->banks
/ 2) + 1);
2543 tileSplitRotation
= 0;
2547 UINT_32 microTileThickness
= Thickness(tileMode
);
2549 bank
^= tileSplitRotation
* tileSlices
;
2550 if (pipeRotation
== 0)
2552 bank
^= bankRotation
* (slice
/ microTileThickness
) + bankSwizzle
;
2553 bank
%= pTileInfo
->banks
;
2554 pipe
^= pipeSwizzle
;
2558 bank
^= bankRotation
* (slice
/ microTileThickness
) / numPipes
+ bankSwizzle
;
2559 bank
%= pTileInfo
->banks
;
2560 pipe
^= pipeRotation
* (slice
/ microTileThickness
) + pipeSwizzle
;
2563 if (pTileInfo
->macroAspectRatio
== 1)
2565 switch (pTileInfo
->banks
)
2568 yBit3
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2571 yBit4
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2572 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2575 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2576 yBit5
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2577 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ yBit5
;
2580 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3);
2581 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2);
2582 yBit6
= _BIT(bank
, 0) ^ _BIT(xBit
, 0);
2583 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ yBit6
;
2590 else if (pTileInfo
->macroAspectRatio
== 2)
2592 switch (pTileInfo
->banks
)
2594 case 2: //xBit3 = yBit3^b0
2595 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,0);
2597 case 4: //xBit3=yBit4^b0; yBit3=xBit4^b1
2598 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2599 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2601 case 8: //xBit4, xBit5, yBit5 are known
2602 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2603 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2604 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ _BIT(yBit
, 2);
2606 case 16://x4,x5,x6,y6 are known
2607 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3); //x3 = y6 ^ b0
2608 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2609 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = x5 ^ b2
2610 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ _BIT(yBit
, 3); //y5=x4^y6^b1
2616 else if (pTileInfo
->macroAspectRatio
== 4)
2618 switch (pTileInfo
->banks
)
2620 case 4: //yBit3, yBit4
2621 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2622 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,0);
2624 case 8: //xBit5, yBit4, yBit5
2625 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2626 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2627 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
,2);
2629 case 16: //xBit5, xBit6, yBit5, yBit6
2630 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = b0 ^ y6
2631 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = b1 ^ y5 ^ y6;
2632 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = b3 ^ x6;
2633 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = b2 ^ x5;
2639 else if (pTileInfo
->macroAspectRatio
== 8)
2641 switch (pTileInfo
->banks
)
2643 case 8: //yBit3, yBit4, yBit5
2644 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2); //x3 = b0 ^ y5;
2645 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
, 2);//x4 = b1 ^ y4 ^ y5;
2646 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
,0);
2648 case 16: //xBit6, yBit4, yBit5, yBit6
2649 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = y6 ^ b0
2650 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = y5 ^ y6 ^ b1
2651 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
, 1);//x5 = y4 ^ b2
2652 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2659 pOutput
->xBits
= xBit
;
2660 pOutput
->yBits
= yBit
;
2662 pOutput
->xBit3
= xBit3
;
2663 pOutput
->xBit4
= xBit4
;
2664 pOutput
->xBit5
= xBit5
;
2665 pOutput
->yBit3
= yBit3
;
2666 pOutput
->yBit4
= yBit4
;
2667 pOutput
->yBit5
= yBit5
;
2668 pOutput
->yBit6
= yBit6
;
2672 ****************************************************************************************************
2673 * EgBasedLib::HwlExtractBankPipeSwizzle
2675 * Entry of EgBasedLib ExtractBankPipeSwizzle
2678 ****************************************************************************************************
2680 ADDR_E_RETURNCODE
EgBasedLib::HwlExtractBankPipeSwizzle(
2681 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
2682 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
2685 ExtractBankPipeSwizzle(pIn
->base256b
,
2688 &pOut
->pipeSwizzle
);
2695 ****************************************************************************************************
2696 * EgBasedLib::HwlCombineBankPipeSwizzle
2698 * Combine bank/pipe swizzle
2701 ****************************************************************************************************
2703 ADDR_E_RETURNCODE
EgBasedLib::HwlCombineBankPipeSwizzle(
2704 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2705 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2706 ADDR_TILEINFO
* pTileInfo
, ///< [in] tile info
2707 UINT_64 baseAddr
, ///< [in] base address
2708 UINT_32
* pTileSwizzle
///< [out] combined swizzle
2711 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
2715 *pTileSwizzle
= GetBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, baseAddr
, pTileInfo
);
2719 retCode
= ADDR_INVALIDPARAMS
;
2726 ****************************************************************************************************
2727 * EgBasedLib::HwlComputeBaseSwizzle
2729 * Compute base swizzle
2732 ****************************************************************************************************
2734 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeBaseSwizzle(
2735 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT
* pIn
,
2736 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
* pOut
2739 UINT_32 bankSwizzle
= 0;
2740 UINT_32 pipeSwizzle
= 0;
2741 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2743 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
2744 ADDR_ASSERT(pIn
->pTileInfo
);
2746 /// This is a legacy misreading of h/w doc, use it as it doesn't hurt.
2747 static const UINT_8 bankRotationArray
[4][16] = {
2748 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_2_BANK
2749 { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_4_BANK
2750 { 0, 3, 6, 1, 4, 7, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_8_BANK
2751 { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }, // ADDR_SURF_16_BANK
2754 UINT_32 banks
= pTileInfo
? pTileInfo
->banks
: 2;
2757 // Uses less bank swizzle bits
2758 if (pIn
->option
.reduceBankBit
&& banks
> 2)
2778 ADDR_ASSERT_ALWAYS();
2783 if (pIn
->option
.genOption
== ADDR_SWIZZLE_GEN_LINEAR
)
2785 bankSwizzle
= pIn
->surfIndex
& (banks
- 1);
2787 else // (pIn->option.genOption == ADDR_SWIZZLE_GEN_DEFAULT)
2789 bankSwizzle
= bankRotationArray
[hwNumBanks
][pIn
->surfIndex
& (banks
- 1)];
2792 if (IsMacro3dTiled(pIn
->tileMode
))
2794 pipeSwizzle
= pIn
->surfIndex
& (HwlGetPipes(pTileInfo
) - 1);
2797 return HwlCombineBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, pTileInfo
, 0, &pOut
->tileSwizzle
);
2801 ****************************************************************************************************
2802 * EgBasedLib::ExtractBankPipeSwizzle
2804 * Extract bank/pipe swizzle from base256b
2807 ****************************************************************************************************
2809 VOID
EgBasedLib::ExtractBankPipeSwizzle(
2810 UINT_32 base256b
, ///< [in] input base256b register value
2811 ADDR_TILEINFO
* pTileInfo
, ///< [in] 2D tile parameters. Client must provide all data
2812 UINT_32
* pBankSwizzle
, ///< [out] bank swizzle
2813 UINT_32
* pPipeSwizzle
///< [out] pipe swizzle
2816 UINT_32 bankSwizzle
= 0;
2817 UINT_32 pipeSwizzle
= 0;
2821 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2822 UINT_32 bankBits
= QLog2(pTileInfo
->banks
);
2823 UINT_32 pipeBits
= QLog2(numPipes
);
2824 UINT_32 groupBytes
= m_pipeInterleaveBytes
;
2825 UINT_32 bankInterleave
= m_bankInterleave
;
2828 (base256b
/ (groupBytes
>> 8)) & ((1<<pipeBits
)-1);
2831 (base256b
/ (groupBytes
>> 8) / numPipes
/ bankInterleave
) & ((1 << bankBits
) - 1);
2834 *pPipeSwizzle
= pipeSwizzle
;
2835 *pBankSwizzle
= bankSwizzle
;
2839 ****************************************************************************************************
2840 * EgBasedLib::GetBankPipeSwizzle
2842 * Combine bank/pipe swizzle
2844 * Base256b bits (only filled bank/pipe bits)
2845 ****************************************************************************************************
2847 UINT_32
EgBasedLib::GetBankPipeSwizzle(
2848 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2849 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2850 UINT_64 baseAddr
, ///< [in] base address
2851 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2854 UINT_32 pipeBits
= QLog2(HwlGetPipes(pTileInfo
));
2855 UINT_32 bankInterleaveBits
= QLog2(m_bankInterleave
);
2856 UINT_32 tileSwizzle
= pipeSwizzle
+ ((bankSwizzle
<< bankInterleaveBits
) << pipeBits
);
2858 baseAddr
^= tileSwizzle
* m_pipeInterleaveBytes
;
2861 return static_cast<UINT_32
>(baseAddr
);
2865 ****************************************************************************************************
2866 * EgBasedLib::ComputeSliceTileSwizzle
2868 * Compute cubemap/3d texture faces/slices tile swizzle
2871 ****************************************************************************************************
2873 UINT_32
EgBasedLib::ComputeSliceTileSwizzle(
2874 AddrTileMode tileMode
, ///< [in] Tile mode
2875 UINT_32 baseSwizzle
, ///< [in] Base swizzle
2876 UINT_32 slice
, ///< [in] Slice index, Cubemap face index, 0 means +X
2877 UINT_64 baseAddr
, ///< [in] Base address
2878 ADDR_TILEINFO
* pTileInfo
///< [in] Bank structure
2881 UINT_32 tileSwizzle
= 0;
2883 if (IsMacroTiled(tileMode
)) // Swizzle only for macro tile mode
2885 UINT_32 firstSlice
= slice
/ Thickness(tileMode
);
2887 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2888 UINT_32 numBanks
= pTileInfo
->banks
;
2890 UINT_32 pipeRotation
;
2891 UINT_32 bankRotation
;
2893 UINT_32 bankSwizzle
= 0;
2894 UINT_32 pipeSwizzle
= 0;
2896 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2897 bankRotation
= ComputeBankRotation(tileMode
, numBanks
, numPipes
);
2899 if (baseSwizzle
!= 0)
2901 ExtractBankPipeSwizzle(baseSwizzle
,
2907 if (pipeRotation
== 0) //2D mode
2909 bankSwizzle
+= firstSlice
* bankRotation
;
2910 bankSwizzle
%= numBanks
;
2914 pipeSwizzle
+= firstSlice
* pipeRotation
;
2915 pipeSwizzle
%= numPipes
;
2916 bankSwizzle
+= firstSlice
* bankRotation
/ numPipes
;
2917 bankSwizzle
%= numBanks
;
2920 tileSwizzle
= GetBankPipeSwizzle(bankSwizzle
,
2930 ****************************************************************************************************
2931 * EgBasedLib::HwlComputeQbStereoRightSwizzle
2934 * Compute right eye swizzle
2937 ****************************************************************************************************
2939 UINT_32
EgBasedLib::HwlComputeQbStereoRightSwizzle(
2940 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pInfo
///< [in] Surface info, must be valid
2943 UINT_32 bankBits
= 0;
2944 UINT_32 swizzle
= 0;
2946 // The assumption is default swizzle for left eye is 0
2947 if (IsMacroTiled(pInfo
->tileMode
) && pInfo
->pStereoInfo
&& pInfo
->pTileInfo
)
2949 bankBits
= ComputeBankFromCoord(0, pInfo
->height
, 0,
2950 pInfo
->tileMode
, 0, 0, pInfo
->pTileInfo
);
2954 HwlCombineBankPipeSwizzle(bankBits
, 0, pInfo
->pTileInfo
, 0, &swizzle
);
2962 ****************************************************************************************************
2963 * EgBasedLib::ComputeBankFromCoord
2966 * Compute bank number from coordinates
2969 ****************************************************************************************************
2971 UINT_32
EgBasedLib::ComputeBankFromCoord(
2972 UINT_32 x
, ///< [in] x coordinate
2973 UINT_32 y
, ///< [in] y coordinate
2974 UINT_32 slice
, ///< [in] slice index
2975 AddrTileMode tileMode
, ///< [in] tile mode
2976 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2977 UINT_32 tileSplitSlice
, ///< [in] If the size of the pixel offset is larger than the
2978 /// tile split size, then the pixel will be moved to a separate
2979 /// slice. This value equals pixelOffset / tileSplitBytes
2980 /// in this case. Otherwise this is 0.
2981 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2984 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2985 UINT_32 bankBit0
= 0;
2986 UINT_32 bankBit1
= 0;
2987 UINT_32 bankBit2
= 0;
2988 UINT_32 bankBit3
= 0;
2989 UINT_32 sliceRotation
;
2990 UINT_32 tileSplitRotation
;
2992 UINT_32 numBanks
= pTileInfo
->banks
;
2993 UINT_32 bankWidth
= pTileInfo
->bankWidth
;
2994 UINT_32 bankHeight
= pTileInfo
->bankHeight
;
2996 UINT_32 tx
= x
/ MicroTileWidth
/ (bankWidth
* pipes
);
2997 UINT_32 ty
= y
/ MicroTileHeight
/ bankHeight
;
2999 UINT_32 x3
= _BIT(tx
,0);
3000 UINT_32 x4
= _BIT(tx
,1);
3001 UINT_32 x5
= _BIT(tx
,2);
3002 UINT_32 x6
= _BIT(tx
,3);
3003 UINT_32 y3
= _BIT(ty
,0);
3004 UINT_32 y4
= _BIT(ty
,1);
3005 UINT_32 y5
= _BIT(ty
,2);
3006 UINT_32 y6
= _BIT(ty
,3);
3012 bankBit1
= x4
^ y5
^ y6
;
3018 bankBit1
= x4
^ y4
^ y5
;
3029 ADDR_ASSERT_ALWAYS();
3033 bank
= bankBit0
| (bankBit1
<< 1) | (bankBit2
<< 2) | (bankBit3
<< 3);
3035 //Bits2Number(4, bankBit3, bankBit2, bankBit1, bankBit0);
3037 bank
= HwlPreAdjustBank((x
/ MicroTileWidth
), bank
, pTileInfo
);
3039 // Compute bank rotation for the slice.
3041 UINT_32 microTileThickness
= Thickness(tileMode
);
3045 case ADDR_TM_2D_TILED_THIN1
: // fall through
3046 case ADDR_TM_2D_TILED_THICK
: // fall through
3047 case ADDR_TM_2D_TILED_XTHICK
:
3048 sliceRotation
= ((numBanks
/ 2) - 1) * (slice
/ microTileThickness
);
3050 case ADDR_TM_3D_TILED_THIN1
: // fall through
3051 case ADDR_TM_3D_TILED_THICK
: // fall through
3052 case ADDR_TM_3D_TILED_XTHICK
:
3054 Max(1u, (pipes
/ 2) - 1) * (slice
/ microTileThickness
) / pipes
;
3063 // Compute bank rotation for the tile split slice.
3065 // The sample slice will be non-zero if samples must be split across multiple slices.
3066 // This situation arises when the micro tile size multiplied yBit the number of samples exceeds
3067 // the split size (set in GB_ADDR_CONFIG).
3071 case ADDR_TM_2D_TILED_THIN1
: //fall through
3072 case ADDR_TM_3D_TILED_THIN1
: //fall through
3073 case ADDR_TM_PRT_2D_TILED_THIN1
: //fall through
3074 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
3075 tileSplitRotation
= ((numBanks
/ 2) + 1) * tileSplitSlice
;
3078 tileSplitRotation
= 0;
3083 // Apply bank rotation for the slice and tile split slice.
3085 bank
^= bankSwizzle
+ sliceRotation
;
3086 bank
^= tileSplitRotation
;
3088 bank
&= (numBanks
- 1);
3094 ****************************************************************************************************
3095 * EgBasedLib::ComputeBankFromAddr
3098 * Compute the bank number from an address
3101 ****************************************************************************************************
3103 UINT_32
EgBasedLib::ComputeBankFromAddr(
3104 UINT_64 addr
, ///< [in] address
3105 UINT_32 numBanks
, ///< [in] number of banks
3106 UINT_32 numPipes
///< [in] number of pipes
3112 // The LSBs of the address are arranged as follows:
3113 // bank | bankInterleave | pipe | pipeInterleave
3115 // To get the bank number, shift off the pipe interleave, pipe, and bank interlave bits and
3116 // mask the bank bits.
3118 bank
= static_cast<UINT_32
>(
3119 (addr
>> Log2(m_pipeInterleaveBytes
* numPipes
* m_bankInterleave
)) &
3127 ****************************************************************************************************
3128 * EgBasedLib::ComputePipeRotation
3131 * Compute pipe rotation value
3134 ****************************************************************************************************
3136 UINT_32
EgBasedLib::ComputePipeRotation(
3137 AddrTileMode tileMode
, ///< [in] tile mode
3138 UINT_32 numPipes
///< [in] number of pipes
3145 case ADDR_TM_3D_TILED_THIN1
: //fall through
3146 case ADDR_TM_3D_TILED_THICK
: //fall through
3147 case ADDR_TM_3D_TILED_XTHICK
: //fall through
3148 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
3149 case ADDR_TM_PRT_3D_TILED_THICK
:
3150 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1);
3162 ****************************************************************************************************
3163 * EgBasedLib::ComputeBankRotation
3166 * Compute bank rotation value
3169 ****************************************************************************************************
3171 UINT_32
EgBasedLib::ComputeBankRotation(
3172 AddrTileMode tileMode
, ///< [in] tile mode
3173 UINT_32 numBanks
, ///< [in] number of banks
3174 UINT_32 numPipes
///< [in] number of pipes
3181 case ADDR_TM_2D_TILED_THIN1
: // fall through
3182 case ADDR_TM_2D_TILED_THICK
: // fall through
3183 case ADDR_TM_2D_TILED_XTHICK
:
3184 case ADDR_TM_PRT_2D_TILED_THIN1
:
3185 case ADDR_TM_PRT_2D_TILED_THICK
:
3186 // Rotate banks per Z-slice yBit 1 for 4-bank or 3 for 8-bank
3187 rotation
= numBanks
/ 2 - 1;
3189 case ADDR_TM_3D_TILED_THIN1
: // fall through
3190 case ADDR_TM_3D_TILED_THICK
: // fall through
3191 case ADDR_TM_3D_TILED_XTHICK
:
3192 case ADDR_TM_PRT_3D_TILED_THIN1
:
3193 case ADDR_TM_PRT_3D_TILED_THICK
:
3194 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1); // rotate pipes & banks
3205 ****************************************************************************************************
3206 * EgBasedLib::ComputeHtileBytes
3209 * Compute htile size in bytes
3212 * Htile size in bytes
3213 ****************************************************************************************************
3215 UINT_64
EgBasedLib::ComputeHtileBytes(
3216 UINT_32 pitch
, ///< [in] pitch
3217 UINT_32 height
, ///< [in] height
3218 UINT_32 bpp
, ///< [in] bits per pixel
3219 BOOL_32 isLinear
, ///< [in] if it is linear mode
3220 UINT_32 numSlices
, ///< [in] number of slices
3221 UINT_64
* sliceBytes
, ///< [out] bytes per slice
3222 UINT_32 baseAlign
///< [in] base alignments
3227 const UINT_64 HtileCacheLineSize
= BITS_TO_BYTES(HtileCacheBits
);
3229 *sliceBytes
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
/ 64);
3231 if (m_configFlags
.useHtileSliceAlign
)
3233 // Align the sliceSize to htilecachelinesize * pipes at first
3234 *sliceBytes
= PowTwoAlign(*sliceBytes
, HtileCacheLineSize
* m_pipes
);
3235 surfBytes
= *sliceBytes
* numSlices
;
3239 // Align the surfSize to htilecachelinesize * pipes at last
3240 surfBytes
= *sliceBytes
* numSlices
;
3241 surfBytes
= PowTwoAlign(surfBytes
, HtileCacheLineSize
* m_pipes
);
3248 ****************************************************************************************************
3249 * EgBasedLib::DispatchComputeFmaskInfo
3252 * Compute fmask sizes include padded pitch, height, slices, total size in bytes,
3253 * meanwhile output suitable tile mode and alignments as well. Results are returned
3254 * through output parameters.
3258 ****************************************************************************************************
3260 ADDR_E_RETURNCODE
EgBasedLib::DispatchComputeFmaskInfo(
3261 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3262 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
) ///< [out] output structure
3264 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3266 ADDR_COMPUTE_SURFACE_INFO_INPUT surfIn
= {0};
3267 ADDR_COMPUTE_SURFACE_INFO_OUTPUT surfOut
= {0};
3269 // Setup input structure
3270 surfIn
.tileMode
= pIn
->tileMode
;
3271 surfIn
.width
= pIn
->pitch
;
3272 surfIn
.height
= pIn
->height
;
3273 surfIn
.numSlices
= pIn
->numSlices
;
3274 surfIn
.pTileInfo
= pIn
->pTileInfo
;
3275 surfIn
.tileType
= ADDR_NON_DISPLAYABLE
;
3276 surfIn
.flags
.fmask
= 1;
3278 // Setup output structure
3279 surfOut
.pTileInfo
= pOut
->pTileInfo
;
3281 // Setup hwl specific fields
3282 HwlFmaskPreThunkSurfInfo(pIn
, pOut
, &surfIn
, &surfOut
);
3284 surfIn
.bpp
= HwlComputeFmaskBits(pIn
, &surfIn
.numSamples
);
3286 // ComputeSurfaceInfo needs numSamples in surfOut as surface routines need adjusted numSamples
3287 surfOut
.numSamples
= surfIn
.numSamples
;
3289 retCode
= HwlComputeSurfaceInfo(&surfIn
, &surfOut
);
3291 // Save bpp field for surface dump support
3292 surfOut
.bpp
= surfIn
.bpp
;
3294 if (retCode
== ADDR_OK
)
3296 pOut
->bpp
= surfOut
.bpp
;
3297 pOut
->pitch
= surfOut
.pitch
;
3298 pOut
->height
= surfOut
.height
;
3299 pOut
->numSlices
= surfOut
.depth
;
3300 pOut
->fmaskBytes
= surfOut
.surfSize
;
3301 pOut
->baseAlign
= surfOut
.baseAlign
;
3302 pOut
->pitchAlign
= surfOut
.pitchAlign
;
3303 pOut
->heightAlign
= surfOut
.heightAlign
;
3305 if (surfOut
.depth
> 1)
3307 // For fmask, expNumSlices is stored in depth.
3308 pOut
->sliceSize
= surfOut
.surfSize
/ surfOut
.depth
;
3312 pOut
->sliceSize
= surfOut
.surfSize
;
3315 // Save numSamples field for surface dump support
3316 pOut
->numSamples
= surfOut
.numSamples
;
3318 HwlFmaskPostThunkSurfInfo(&surfOut
, pOut
);
3325 ****************************************************************************************************
3326 * EgBasedLib::HwlFmaskSurfaceInfo
3328 * Entry of EgBasedLib ComputeFmaskInfo
3331 ****************************************************************************************************
3333 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskInfo(
3334 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3335 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
3338 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3340 ADDR_TILEINFO tileInfo
= {0};
3342 // Use internal tile info if pOut does not have a valid pTileInfo
3343 if (pOut
->pTileInfo
== NULL
)
3345 pOut
->pTileInfo
= &tileInfo
;
3348 retCode
= DispatchComputeFmaskInfo(pIn
, pOut
);
3350 if (retCode
== ADDR_OK
)
3353 HwlPostCheckTileIndex(pOut
->pTileInfo
, pIn
->tileMode
, ADDR_NON_DISPLAYABLE
,
3357 // Resets pTileInfo to NULL if the internal tile info is used
3358 if (pOut
->pTileInfo
== &tileInfo
)
3360 pOut
->pTileInfo
= NULL
;
3367 ****************************************************************************************************
3368 * EgBasedLib::HwlComputeFmaskAddrFromCoord
3370 * Entry of EgBasedLib ComputeFmaskAddrFromCoord
3373 ****************************************************************************************************
3375 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskAddrFromCoord(
3376 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3377 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3380 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3383 if ((pIn
->x
> pIn
->pitch
) ||
3384 (pIn
->y
> pIn
->height
) ||
3385 (pIn
->numSamples
> m_maxSamples
) ||
3386 (pIn
->sample
>= m_maxSamples
))
3388 retCode
= ADDR_INVALIDPARAMS
;
3392 pOut
->addr
= DispatchComputeFmaskAddrFromCoord(pIn
, pOut
);
3400 ****************************************************************************************************
3401 * EgBasedLib::HwlComputeFmaskCoordFromAddr
3403 * Entry of EgBasedLib ComputeFmaskCoordFromAddr
3406 ****************************************************************************************************
3408 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskCoordFromAddr(
3409 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3410 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3413 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3416 if ((pIn
->bitPosition
>= 8) ||
3417 (pIn
->numSamples
> m_maxSamples
))
3419 retCode
= ADDR_INVALIDPARAMS
;
3423 DispatchComputeFmaskCoordFromAddr(pIn
, pOut
);
3432 ****************************************************************************************************
3433 * EgBasedLib::DispatchComputeFmaskAddrFromCoord
3436 * Computes the FMASK address and bit position from a coordinate.
3439 ****************************************************************************************************
3441 UINT_64
EgBasedLib::DispatchComputeFmaskAddrFromCoord(
3442 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3443 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3448 UINT_32 slice
= pIn
->slice
;
3449 UINT_32 sample
= pIn
->sample
;
3450 UINT_32 plane
= pIn
->plane
;
3451 UINT_32 pitch
= pIn
->pitch
;
3452 UINT_32 height
= pIn
->height
;
3453 UINT_32 numSamples
= pIn
->numSamples
;
3454 AddrTileMode tileMode
= pIn
->tileMode
;
3455 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
3456 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
3457 BOOL_32 resolved
= pIn
->resolved
;
3459 UINT_32
* pBitPosition
= &pOut
->bitPosition
;
3462 ADDR_ASSERT(numSamples
> 1);
3463 ADDR_ASSERT(Thickness(tileMode
) == 1);
3467 case ADDR_TM_1D_TILED_THIN1
:
3468 addr
= ComputeFmaskAddrFromCoordMicroTiled(x
,
3480 case ADDR_TM_2D_TILED_THIN1
: //fall through
3481 case ADDR_TM_3D_TILED_THIN1
:
3482 UINT_32 pipeSwizzle
;
3483 UINT_32 bankSwizzle
;
3485 if (m_configFlags
.useCombinedSwizzle
)
3487 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
3488 &bankSwizzle
, &pipeSwizzle
);
3492 pipeSwizzle
= pIn
->pipeSwizzle
;
3493 bankSwizzle
= pIn
->bankSwizzle
;
3496 addr
= ComputeFmaskAddrFromCoordMacroTiled(x
,
3521 ****************************************************************************************************
3522 * EgBasedLib::ComputeFmaskAddrFromCoordMicroTiled
3525 * Computes the FMASK address and bit position from a coordinate for 1D tilied (micro
3529 ****************************************************************************************************
3531 UINT_64
EgBasedLib::ComputeFmaskAddrFromCoordMicroTiled(
3532 UINT_32 x
, ///< [in] x coordinate
3533 UINT_32 y
, ///< [in] y coordinate
3534 UINT_32 slice
, ///< [in] slice index
3535 UINT_32 sample
, ///< [in] sample number
3536 UINT_32 plane
, ///< [in] plane number
3537 UINT_32 pitch
, ///< [in] surface pitch in pixels
3538 UINT_32 height
, ///< [in] surface height in pixels
3539 UINT_32 numSamples
, ///< [in] number of samples
3540 AddrTileMode tileMode
, ///< [in] tile mode
3541 BOOL_32 resolved
, ///< [in] TRUE if this is for resolved fmask
3542 UINT_32
* pBitPosition
///< [out] pointer to returned bit position
3546 UINT_32 effectiveBpp
;
3547 UINT_32 effectiveSamples
;
3550 // 2xAA use the same layout as 4xAA
3552 if (numSamples
== 2)
3558 // Compute the number of planes.
3560 if (resolved
== FALSE
)
3562 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3563 effectiveBpp
= numSamples
;
3566 // Compute the address just like a color surface with numSamples bits per element and
3567 // numPlanes samples.
3569 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
3578 ADDR_NON_DISPLAYABLE
,
3583 // Compute the real bit position. Each (sample, plane) is stored with one bit per sample.
3587 // Compute the pixel index with in the micro tile
3589 UINT_32 pixelIndex
= ComputePixelIndexWithinMicroTile(x
% 8,
3594 ADDR_NON_DISPLAYABLE
);
3596 *pBitPosition
= ((pixelIndex
* numSamples
) + sample
) & (BITS_PER_BYTE
-1);
3598 UINT_64 bitAddr
= BYTES_TO_BITS(addr
) + *pBitPosition
;
3604 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3605 effectiveSamples
= 1;
3608 // Compute the address just like a color surface with numSamples bits per element and
3609 // numPlanes samples.
3611 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
3620 ADDR_NON_DISPLAYABLE
,
3629 ****************************************************************************************************
3630 * EgBasedLib::ComputeFmaskAddrFromCoordMacroTiled
3633 * Computes the FMASK address and bit position from a coordinate for 2D tilied (macro
3637 ****************************************************************************************************
3639 UINT_64
EgBasedLib::ComputeFmaskAddrFromCoordMacroTiled(
3640 UINT_32 x
, ///< [in] x coordinate
3641 UINT_32 y
, ///< [in] y coordinate
3642 UINT_32 slice
, ///< [in] slice index
3643 UINT_32 sample
, ///< [in] sample number
3644 UINT_32 plane
, ///< [in] plane number
3645 UINT_32 pitch
, ///< [in] surface pitch in pixels
3646 UINT_32 height
, ///< [in] surface height in pixels
3647 UINT_32 numSamples
, ///< [in] number of samples
3648 AddrTileMode tileMode
, ///< [in] tile mode
3649 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
3650 UINT_32 bankSwizzle
, ///< [in] bank swizzle
3651 BOOL_32 ignoreSE
, ///< [in] TRUE if ignore shader engine
3652 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure.**All fields to be valid on entry**
3653 BOOL_32 resolved
, ///< [in] TRUE if this is for resolved fmask
3654 UINT_32
* pBitPosition
///< [out] pointer to returned bit position
3658 UINT_32 effectiveBpp
;
3659 UINT_32 effectiveSamples
;
3662 // 2xAA use the same layout as 4xAA
3664 if (numSamples
== 2)
3670 // Compute the number of planes.
3672 if (resolved
== FALSE
)
3674 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3675 effectiveBpp
= numSamples
;
3678 // Compute the address just like a color surface with numSamples bits per element and
3679 // numPlanes samples.
3681 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
3690 ADDR_NON_DISPLAYABLE
,// isdisp
3691 ignoreSE
,// ignore_shader
3692 FALSE
,// depth_sample_order
3699 // Compute the real bit position. Each (sample, plane) is stored with one bit per sample.
3704 // Compute the pixel index with in the micro tile
3706 UINT_32 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
3711 ADDR_NON_DISPLAYABLE
);
3713 *pBitPosition
= ((pixelIndex
* numSamples
) + sample
) & (BITS_PER_BYTE
-1);
3715 UINT_64 bitAddr
= BYTES_TO_BITS(addr
) + *pBitPosition
;
3722 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3723 effectiveSamples
= 1;
3726 // Compute the address just like a color surface with numSamples bits per element and
3727 // numPlanes samples.
3729 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
3738 ADDR_NON_DISPLAYABLE
,
3751 ****************************************************************************************************
3752 * EgBasedLib::ComputeFmaskCoordFromAddrMicroTiled
3755 * Compute (x,y,slice,sample,plane) coordinates from fmask address
3759 ****************************************************************************************************
3761 VOID
EgBasedLib::ComputeFmaskCoordFromAddrMicroTiled(
3762 UINT_64 addr
, ///< [in] byte address
3763 UINT_32 bitPosition
,///< [in] bit position
3764 UINT_32 pitch
, ///< [in] pitch in pixels
3765 UINT_32 height
, ///< [in] height in pixels
3766 UINT_32 numSamples
, ///< [in] number of samples (of color buffer)
3767 AddrTileMode tileMode
, ///< [in] tile mode
3768 BOOL_32 resolved
, ///< [in] TRUE if it is resolved fmask
3769 UINT_32
* pX
, ///< [out] X coord
3770 UINT_32
* pY
, ///< [out] Y coord
3771 UINT_32
* pSlice
, ///< [out] slice index
3772 UINT_32
* pSample
, ///< [out] sample index
3773 UINT_32
* pPlane
///< [out] plane index
3776 UINT_32 effectiveBpp
;
3777 UINT_32 effectiveSamples
;
3779 // 2xAA use the same layout as 4xAA
3780 if (numSamples
== 2)
3785 if (resolved
== FALSE
)
3787 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3788 effectiveBpp
= numSamples
;
3790 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
3803 ADDR_NON_DISPLAYABLE
, // microTileType
3804 FALSE
// isDepthSampleOrder
3810 *pSample
= bitPosition
% numSamples
;
3815 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3816 effectiveSamples
= 1;
3818 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
3831 ADDR_NON_DISPLAYABLE
, // microTileType
3832 TRUE
// isDepthSampleOrder
3838 ****************************************************************************************************
3839 * EgBasedLib::ComputeFmaskCoordFromAddrMacroTiled
3842 * Compute (x,y,slice,sample,plane) coordinates from
3847 ****************************************************************************************************
3849 VOID
EgBasedLib::ComputeFmaskCoordFromAddrMacroTiled(
3850 UINT_64 addr
, ///< [in] byte address
3851 UINT_32 bitPosition
,///< [in] bit position
3852 UINT_32 pitch
, ///< [in] pitch in pixels
3853 UINT_32 height
, ///< [in] height in pixels
3854 UINT_32 numSamples
, ///< [in] number of samples (of color buffer)
3855 AddrTileMode tileMode
, ///< [in] tile mode
3856 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
3857 UINT_32 bankSwizzle
,///< [in] bank swizzle
3858 BOOL_32 ignoreSE
, ///< [in] TRUE if ignore shader engine
3859 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure. **All fields to be valid on entry**
3860 BOOL_32 resolved
, ///< [in] TRUE if it is resolved fmask
3861 UINT_32
* pX
, ///< [out] X coord
3862 UINT_32
* pY
, ///< [out] Y coord
3863 UINT_32
* pSlice
, ///< [out] slice index
3864 UINT_32
* pSample
, ///< [out] sample index
3865 UINT_32
* pPlane
///< [out] plane index
3868 UINT_32 effectiveBpp
;
3869 UINT_32 effectiveSamples
;
3871 // 2xAA use the same layout as 4xAA
3872 if (numSamples
== 2)
3878 // Compute the number of planes.
3880 if (resolved
== FALSE
)
3882 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3883 effectiveBpp
= numSamples
;
3885 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
3894 ADDR_NON_DISPLAYABLE
,
3907 *pSample
= bitPosition
% numSamples
;
3912 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3913 effectiveSamples
= 1;
3915 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
3924 ADDR_NON_DISPLAYABLE
,
3938 ****************************************************************************************************
3939 * EgBasedLib::DispatchComputeFmaskCoordFromAddr
3942 * Compute (x,y,slice,sample,plane) coordinates from
3947 ****************************************************************************************************
3949 VOID
EgBasedLib::DispatchComputeFmaskCoordFromAddr(
3950 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3951 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3954 UINT_64 addr
= pIn
->addr
;
3955 UINT_32 bitPosition
= pIn
->bitPosition
;
3956 UINT_32 pitch
= pIn
->pitch
;
3957 UINT_32 height
= pIn
->height
;
3958 UINT_32 numSamples
= pIn
->numSamples
;
3959 AddrTileMode tileMode
= pIn
->tileMode
;
3960 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
3961 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
3962 BOOL_32 resolved
= pIn
->resolved
;
3964 UINT_32
* pX
= &pOut
->x
;
3965 UINT_32
* pY
= &pOut
->y
;
3966 UINT_32
* pSlice
= &pOut
->slice
;
3967 UINT_32
* pSample
= &pOut
->sample
;
3968 UINT_32
* pPlane
= &pOut
->plane
;
3972 case ADDR_TM_1D_TILED_THIN1
:
3973 ComputeFmaskCoordFromAddrMicroTiled(addr
,
3986 case ADDR_TM_2D_TILED_THIN1
://fall through
3987 case ADDR_TM_3D_TILED_THIN1
:
3988 UINT_32 pipeSwizzle
;
3989 UINT_32 bankSwizzle
;
3991 if (m_configFlags
.useCombinedSwizzle
)
3993 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
3994 &bankSwizzle
, &pipeSwizzle
);
3998 pipeSwizzle
= pIn
->pipeSwizzle
;
3999 bankSwizzle
= pIn
->bankSwizzle
;
4002 ComputeFmaskCoordFromAddrMacroTiled(addr
,
4020 ADDR_ASSERT_ALWAYS();
4028 ****************************************************************************************************
4029 * EgBasedLib::ComputeFmaskNumPlanesFromNumSamples
4032 * Compute fmask number of planes from number of samples
4036 ****************************************************************************************************
4038 UINT_32
EgBasedLib::ComputeFmaskNumPlanesFromNumSamples(
4039 UINT_32 numSamples
) ///< [in] number of samples
4044 // FMASK is stored such that each micro tile is composed of elements containing N bits, where
4045 // N is the number of samples. There is a micro tile for each bit in the FMASK address, and
4046 // micro tiles for each address bit, sometimes referred to as a plane, are stored sequentially.
4047 // The FMASK for a 2-sample surface looks like a general surface with 2 bits per element.
4048 // The FMASK for a 4-sample surface looks like a general surface with 4 bits per element and
4049 // 2 samples. The FMASK for an 8-sample surface looks like a general surface with 8 bits per
4050 // element and 4 samples. R6xx and R7xx only stored 3 planes for 8-sample FMASK surfaces.
4051 // This was changed for R8xx to simplify the logic in the CB.
4065 ADDR_UNHANDLED_CASE();
4073 ****************************************************************************************************
4074 * EgBasedLib::ComputeFmaskResolvedBppFromNumSamples
4077 * Compute resolved fmask effective bpp based on number of samples
4081 ****************************************************************************************************
4083 UINT_32
EgBasedLib::ComputeFmaskResolvedBppFromNumSamples(
4084 UINT_32 numSamples
) ///< number of samples
4089 // Resolved FMASK surfaces are generated yBit the CB and read yBit the texture unit
4090 // so that the texture unit can read compressed multi-sample color data.
4091 // These surfaces store each index value packed per element.
4092 // Each element contains at least num_samples * log2(num_samples) bits.
4093 // Resolved FMASK surfaces are addressed as follows:
4094 // 2-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
4095 // 4-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
4096 // 8-sample Addressed similarly to a color surface with 32 bits per element and 1 sample.
4110 ADDR_UNHANDLED_CASE();
4118 ****************************************************************************************************
4119 * EgBasedLib::IsTileInfoAllZero
4122 * Return TRUE if all field are zero
4124 * Since NULL input is consider to be all zero
4125 ****************************************************************************************************
4127 BOOL_32
EgBasedLib::IsTileInfoAllZero(
4128 const ADDR_TILEINFO
* pTileInfo
)
4130 BOOL_32 allZero
= TRUE
;
4134 if ((pTileInfo
->banks
!= 0) ||
4135 (pTileInfo
->bankWidth
!= 0) ||
4136 (pTileInfo
->bankHeight
!= 0) ||
4137 (pTileInfo
->macroAspectRatio
!= 0) ||
4138 (pTileInfo
->tileSplitBytes
!= 0) ||
4139 (pTileInfo
->pipeConfig
!= 0)
4150 ****************************************************************************************************
4151 * EgBasedLib::HwlTileInfoEqual
4154 * Return TRUE if all field are equal
4156 * Only takes care of current HWL's data
4157 ****************************************************************************************************
4159 BOOL_32
EgBasedLib::HwlTileInfoEqual(
4160 const ADDR_TILEINFO
* pLeft
, ///<[in] Left compare operand
4161 const ADDR_TILEINFO
* pRight
///<[in] Right compare operand
4164 BOOL_32 equal
= FALSE
;
4166 if (pLeft
->banks
== pRight
->banks
&&
4167 pLeft
->bankWidth
== pRight
->bankWidth
&&
4168 pLeft
->bankHeight
== pRight
->bankHeight
&&
4169 pLeft
->macroAspectRatio
== pRight
->macroAspectRatio
&&
4170 pLeft
->tileSplitBytes
== pRight
->tileSplitBytes
)
4179 ****************************************************************************************************
4180 * EgBasedLib::HwlConvertTileInfoToHW
4182 * Entry of EgBasedLib ConvertTileInfoToHW
4185 ****************************************************************************************************
4187 ADDR_E_RETURNCODE
EgBasedLib::HwlConvertTileInfoToHW(
4188 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
4189 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
4192 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4194 ADDR_TILEINFO
*pTileInfoIn
= pIn
->pTileInfo
;
4195 ADDR_TILEINFO
*pTileInfoOut
= pOut
->pTileInfo
;
4197 if ((pTileInfoIn
!= NULL
) && (pTileInfoOut
!= NULL
))
4199 if (pIn
->reverse
== FALSE
)
4201 switch (pTileInfoIn
->banks
)
4204 pTileInfoOut
->banks
= 0;
4207 pTileInfoOut
->banks
= 1;
4210 pTileInfoOut
->banks
= 2;
4213 pTileInfoOut
->banks
= 3;
4216 ADDR_ASSERT_ALWAYS();
4217 retCode
= ADDR_INVALIDPARAMS
;
4218 pTileInfoOut
->banks
= 0;
4222 switch (pTileInfoIn
->bankWidth
)
4225 pTileInfoOut
->bankWidth
= 0;
4228 pTileInfoOut
->bankWidth
= 1;
4231 pTileInfoOut
->bankWidth
= 2;
4234 pTileInfoOut
->bankWidth
= 3;
4237 ADDR_ASSERT_ALWAYS();
4238 retCode
= ADDR_INVALIDPARAMS
;
4239 pTileInfoOut
->bankWidth
= 0;
4243 switch (pTileInfoIn
->bankHeight
)
4246 pTileInfoOut
->bankHeight
= 0;
4249 pTileInfoOut
->bankHeight
= 1;
4252 pTileInfoOut
->bankHeight
= 2;
4255 pTileInfoOut
->bankHeight
= 3;
4258 ADDR_ASSERT_ALWAYS();
4259 retCode
= ADDR_INVALIDPARAMS
;
4260 pTileInfoOut
->bankHeight
= 0;
4264 switch (pTileInfoIn
->macroAspectRatio
)
4267 pTileInfoOut
->macroAspectRatio
= 0;
4270 pTileInfoOut
->macroAspectRatio
= 1;
4273 pTileInfoOut
->macroAspectRatio
= 2;
4276 pTileInfoOut
->macroAspectRatio
= 3;
4279 ADDR_ASSERT_ALWAYS();
4280 retCode
= ADDR_INVALIDPARAMS
;
4281 pTileInfoOut
->macroAspectRatio
= 0;
4285 switch (pTileInfoIn
->tileSplitBytes
)
4288 pTileInfoOut
->tileSplitBytes
= 0;
4291 pTileInfoOut
->tileSplitBytes
= 1;
4294 pTileInfoOut
->tileSplitBytes
= 2;
4297 pTileInfoOut
->tileSplitBytes
= 3;
4300 pTileInfoOut
->tileSplitBytes
= 4;
4303 pTileInfoOut
->tileSplitBytes
= 5;
4306 pTileInfoOut
->tileSplitBytes
= 6;
4309 ADDR_ASSERT_ALWAYS();
4310 retCode
= ADDR_INVALIDPARAMS
;
4311 pTileInfoOut
->tileSplitBytes
= 0;
4317 switch (pTileInfoIn
->banks
)
4320 pTileInfoOut
->banks
= 2;
4323 pTileInfoOut
->banks
= 4;
4326 pTileInfoOut
->banks
= 8;
4329 pTileInfoOut
->banks
= 16;
4332 ADDR_ASSERT_ALWAYS();
4333 retCode
= ADDR_INVALIDPARAMS
;
4334 pTileInfoOut
->banks
= 2;
4338 switch (pTileInfoIn
->bankWidth
)
4341 pTileInfoOut
->bankWidth
= 1;
4344 pTileInfoOut
->bankWidth
= 2;
4347 pTileInfoOut
->bankWidth
= 4;
4350 pTileInfoOut
->bankWidth
= 8;
4353 ADDR_ASSERT_ALWAYS();
4354 retCode
= ADDR_INVALIDPARAMS
;
4355 pTileInfoOut
->bankWidth
= 1;
4359 switch (pTileInfoIn
->bankHeight
)
4362 pTileInfoOut
->bankHeight
= 1;
4365 pTileInfoOut
->bankHeight
= 2;
4368 pTileInfoOut
->bankHeight
= 4;
4371 pTileInfoOut
->bankHeight
= 8;
4374 ADDR_ASSERT_ALWAYS();
4375 retCode
= ADDR_INVALIDPARAMS
;
4376 pTileInfoOut
->bankHeight
= 1;
4380 switch (pTileInfoIn
->macroAspectRatio
)
4383 pTileInfoOut
->macroAspectRatio
= 1;
4386 pTileInfoOut
->macroAspectRatio
= 2;
4389 pTileInfoOut
->macroAspectRatio
= 4;
4392 pTileInfoOut
->macroAspectRatio
= 8;
4395 ADDR_ASSERT_ALWAYS();
4396 retCode
= ADDR_INVALIDPARAMS
;
4397 pTileInfoOut
->macroAspectRatio
= 1;
4401 switch (pTileInfoIn
->tileSplitBytes
)
4404 pTileInfoOut
->tileSplitBytes
= 64;
4407 pTileInfoOut
->tileSplitBytes
= 128;
4410 pTileInfoOut
->tileSplitBytes
= 256;
4413 pTileInfoOut
->tileSplitBytes
= 512;
4416 pTileInfoOut
->tileSplitBytes
= 1024;
4419 pTileInfoOut
->tileSplitBytes
= 2048;
4422 pTileInfoOut
->tileSplitBytes
= 4096;
4425 ADDR_ASSERT_ALWAYS();
4426 retCode
= ADDR_INVALIDPARAMS
;
4427 pTileInfoOut
->tileSplitBytes
= 64;
4432 if (pTileInfoIn
!= pTileInfoOut
)
4434 pTileInfoOut
->pipeConfig
= pTileInfoIn
->pipeConfig
;
4439 ADDR_ASSERT_ALWAYS();
4440 retCode
= ADDR_INVALIDPARAMS
;
4447 ****************************************************************************************************
4448 * EgBasedLib::HwlComputeSurfaceInfo
4450 * Entry of EgBasedLib ComputeSurfaceInfo
4453 ****************************************************************************************************
4455 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceInfo(
4456 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
4457 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
4460 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4462 if (pIn
->numSamples
< pIn
->numFrags
)
4464 retCode
= ADDR_INVALIDPARAMS
;
4467 ADDR_TILEINFO tileInfo
= {0};
4469 if (retCode
== ADDR_OK
)
4471 // Uses internal tile info if pOut does not have a valid pTileInfo
4472 if (pOut
->pTileInfo
== NULL
)
4474 pOut
->pTileInfo
= &tileInfo
;
4477 if (DispatchComputeSurfaceInfo(pIn
, pOut
) == FALSE
)
4479 retCode
= ADDR_INVALIDPARAMS
;
4482 // In case client uses tile info as input and would like to calculate a correct size and
4483 // alignment together with tile info as output when the tile info is not suppose to have any
4484 // matching indices in tile mode tables.
4485 if (pIn
->flags
.skipIndicesOutput
== FALSE
)
4488 pOut
->tileIndex
= HwlPostCheckTileIndex(pOut
->pTileInfo
,
4493 if (IsMacroTiled(pOut
->tileMode
) && (pOut
->macroModeIndex
== TileIndexInvalid
))
4495 pOut
->macroModeIndex
= HwlComputeMacroModeIndex(pOut
->tileIndex
,
4503 // Resets pTileInfo to NULL if the internal tile info is used
4504 if (pOut
->pTileInfo
== &tileInfo
)
4507 // Client does not pass in a valid pTileInfo
4508 if (IsMacroTiled(pOut
->tileMode
))
4510 // If a valid index is returned, then no pTileInfo is okay
4511 ADDR_ASSERT((m_configFlags
.useTileIndex
== FALSE
) ||
4512 (pOut
->tileIndex
!= TileIndexInvalid
));
4514 if (IsTileInfoAllZero(pIn
->pTileInfo
) == FALSE
)
4516 // The initial value of pIn->pTileInfo is copied to tileInfo
4517 // We do not expect any of these value to be changed nor any 0 of inputs
4518 ADDR_ASSERT(tileInfo
.banks
== pIn
->pTileInfo
->banks
);
4519 ADDR_ASSERT(tileInfo
.bankWidth
== pIn
->pTileInfo
->bankWidth
);
4520 ADDR_ASSERT(tileInfo
.bankHeight
== pIn
->pTileInfo
->bankHeight
);
4521 ADDR_ASSERT(tileInfo
.macroAspectRatio
== pIn
->pTileInfo
->macroAspectRatio
);
4522 ADDR_ASSERT(tileInfo
.tileSplitBytes
== pIn
->pTileInfo
->tileSplitBytes
);
4526 pOut
->pTileInfo
= NULL
;
4534 ****************************************************************************************************
4535 * EgBasedLib::HwlComputeSurfaceAddrFromCoord
4537 * Entry of EgBasedLib ComputeSurfaceAddrFromCoord
4540 ****************************************************************************************************
4542 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceAddrFromCoord(
4543 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
4544 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
4547 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4550 #if !ALT_TEST // Overflow test needs this out-of-boundary coord
4551 (pIn
->x
> pIn
->pitch
) ||
4552 (pIn
->y
> pIn
->height
) ||
4554 (pIn
->numSamples
> m_maxSamples
))
4556 retCode
= ADDR_INVALIDPARAMS
;
4560 pOut
->addr
= DispatchComputeSurfaceAddrFromCoord(pIn
, pOut
);
4567 ****************************************************************************************************
4568 * EgBasedLib::HwlComputeSurfaceCoordFromAddr
4570 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
4573 ****************************************************************************************************
4575 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceCoordFromAddr(
4576 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
4577 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
4580 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4582 if ((pIn
->bitPosition
>= 8) ||
4583 (pIn
->numSamples
> m_maxSamples
))
4585 retCode
= ADDR_INVALIDPARAMS
;
4589 DispatchComputeSurfaceCoordFromAddr(pIn
, pOut
);
4595 ****************************************************************************************************
4596 * EgBasedLib::HwlComputeSliceTileSwizzle
4598 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
4601 ****************************************************************************************************
4603 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSliceTileSwizzle(
4604 const ADDR_COMPUTE_SLICESWIZZLE_INPUT
* pIn
, ///< [in] input structure
4605 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
* pOut
///< [out] output structure
4608 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4610 if (pIn
->pTileInfo
&& (pIn
->pTileInfo
->banks
> 0))
4613 pOut
->tileSwizzle
= ComputeSliceTileSwizzle(pIn
->tileMode
,
4621 retCode
= ADDR_INVALIDPARAMS
;
4628 ****************************************************************************************************
4629 * EgBasedLib::HwlComputeHtileBpp
4636 ****************************************************************************************************
4638 UINT_32
EgBasedLib::HwlComputeHtileBpp(
4639 BOOL_32 isWidth8
, ///< [in] TRUE if block width is 8
4640 BOOL_32 isHeight8
///< [in] TRUE if block height is 8
4643 // only support 8x8 mode
4644 ADDR_ASSERT(isWidth8
&& isHeight8
);
4649 ****************************************************************************************************
4650 * EgBasedLib::HwlComputeHtileBaseAlign
4653 * Compute htile base alignment
4656 * Htile base alignment
4657 ****************************************************************************************************
4659 UINT_32
EgBasedLib::HwlComputeHtileBaseAlign(
4660 BOOL_32 isTcCompatible
, ///< [in] if TC compatible
4661 BOOL_32 isLinear
, ///< [in] if it is linear mode
4662 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
4665 UINT_32 baseAlign
= m_pipeInterleaveBytes
* HwlGetPipes(pTileInfo
);
4669 ADDR_ASSERT(pTileInfo
!= NULL
);
4672 baseAlign
*= pTileInfo
->banks
;
4680 ****************************************************************************************************
4681 * EgBasedLib::HwlGetPitchAlignmentMicroTiled
4684 * Compute 1D tiled surface pitch alignment, calculation results are returned through
4685 * output parameters.
4689 ****************************************************************************************************
4691 UINT_32
EgBasedLib::HwlGetPitchAlignmentMicroTiled(
4692 AddrTileMode tileMode
, ///< [in] tile mode
4693 UINT_32 bpp
, ///< [in] bits per pixel
4694 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4695 UINT_32 numSamples
///< [in] number of samples
4700 UINT_32 microTileThickness
= Thickness(tileMode
);
4702 UINT_32 pixelsPerMicroTile
;
4703 UINT_32 pixelsPerPipeInterleave
;
4704 UINT_32 microTilesPerPipeInterleave
;
4707 // Special workaround for depth/stencil buffer, use 8 bpp to meet larger requirement for
4708 // stencil buffer since pitch alignment is related to bpp.
4709 // For a depth only buffer do not set this.
4711 // Note: this actually does not work for mipmap but mipmap depth texture is not really
4712 // sampled with mipmap.
4714 if (flags
.depth
&& (flags
.noStencil
== FALSE
))
4719 pixelsPerMicroTile
= MicroTilePixels
* microTileThickness
;
4720 pixelsPerPipeInterleave
= BYTES_TO_BITS(m_pipeInterleaveBytes
) / (bpp
* numSamples
);
4721 microTilesPerPipeInterleave
= pixelsPerPipeInterleave
/ pixelsPerMicroTile
;
4723 pitchAlign
= Max(MicroTileWidth
, microTilesPerPipeInterleave
* MicroTileWidth
);
4729 ****************************************************************************************************
4730 * EgBasedLib::HwlGetSizeAdjustmentMicroTiled
4733 * Adjust 1D tiled surface pitch and slice size
4736 * Logical slice size in bytes
4737 ****************************************************************************************************
4739 UINT_64
EgBasedLib::HwlGetSizeAdjustmentMicroTiled(
4740 UINT_32 thickness
, ///< [in] thickness
4741 UINT_32 bpp
, ///< [in] bits per pixel
4742 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4743 UINT_32 numSamples
, ///< [in] number of samples
4744 UINT_32 baseAlign
, ///< [in] base alignment
4745 UINT_32 pitchAlign
, ///< [in] pitch alignment
4746 UINT_32
* pPitch
, ///< [in,out] pointer to pitch
4747 UINT_32
* pHeight
///< [in,out] pointer to height
4750 UINT_64 logicalSliceSize
;
4751 UINT_64 physicalSliceSize
;
4753 UINT_32 pitch
= *pPitch
;
4754 UINT_32 height
= *pHeight
;
4756 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
4757 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
4759 // Physical slice: multiplied by thickness
4760 physicalSliceSize
= logicalSliceSize
* thickness
;
4763 // R800 will always pad physical slice size to baseAlign which is pipe_interleave_bytes
4765 ADDR_ASSERT((physicalSliceSize
% baseAlign
) == 0);
4767 return logicalSliceSize
;
4771 ****************************************************************************************************
4772 * EgBasedLib::HwlStereoCheckRightOffsetPadding
4775 * check if the height needs extra padding for stereo right eye offset, to avoid swizzling
4778 * TRUE is the extra padding is needed
4780 ****************************************************************************************************
4782 UINT_32
EgBasedLib::HwlStereoCheckRightOffsetPadding(
4783 ADDR_TILEINFO
* pTileInfo
///< Tiling info
4786 UINT_32 stereoHeightAlign
= 0;
4788 if (pTileInfo
->macroAspectRatio
> 2)
4790 // Since 3D rendering treats right eye surface starting from y == "eye height" while
4791 // display engine treats it to be 0, so the bank bits may be different.
4792 // Additional padding in height is required to make sure it's possible
4793 // to achieve synonym by adjusting bank swizzle of right eye surface.
4795 static const UINT_32 StereoAspectRatio
= 2;
4796 stereoHeightAlign
= pTileInfo
->banks
*
4797 pTileInfo
->bankHeight
*
4802 return stereoHeightAlign
;