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 EgBasedAddrLib class implementation
31 ***************************************************************************************************
34 #include "egbaddrlib.h"
37 ***************************************************************************************************
38 * EgBasedAddrLib::EgBasedAddrLib
45 ***************************************************************************************************
47 EgBasedAddrLib::EgBasedAddrLib(const AddrClient
* pClient
) :
56 ***************************************************************************************************
57 * EgBasedAddrLib::~EgBasedAddrLib
61 ***************************************************************************************************
63 EgBasedAddrLib::~EgBasedAddrLib()
68 ***************************************************************************************************
69 * EgBasedAddrLib::DispatchComputeSurfaceInfo
72 * Compute surface sizes include padded pitch,height,slices,total size in bytes,
73 * meanwhile output suitable tile mode and base alignment might be changed in this
74 * call as well. Results are returned through output parameters.
77 * TRUE if no error occurs
78 ***************************************************************************************************
80 BOOL_32
EgBasedAddrLib::DispatchComputeSurfaceInfo(
81 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
82 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
85 AddrTileMode tileMode
= pIn
->tileMode
;
86 UINT_32 bpp
= pIn
->bpp
;
87 UINT_32 numSamples
= pIn
->numSamples
;
88 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
89 UINT_32 pitch
= pIn
->width
;
90 UINT_32 height
= pIn
->height
;
91 UINT_32 numSlices
= pIn
->numSlices
;
92 UINT_32 mipLevel
= pIn
->mipLevel
;
93 ADDR_SURFACE_FLAGS flags
= pIn
->flags
;
95 ADDR_TILEINFO tileInfoDef
= {0};
96 ADDR_TILEINFO
* pTileInfo
= &tileInfoDef
;
101 tileMode
= DegradeLargeThickTile(tileMode
, bpp
);
103 // Only override numSamples for NI above
104 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
106 if (numFrags
!= numSamples
) // This means EQAA
108 // The real surface size needed is determined by number of fragments
109 numSamples
= numFrags
;
112 // Save altered numSamples in pOut
113 pOut
->numSamples
= numSamples
;
116 // Caller makes sure pOut->pTileInfo is not NULL, see HwlComputeSurfaceInfo
117 ADDR_ASSERT(pOut
->pTileInfo
);
119 if (pOut
->pTileInfo
!= NULL
)
121 pTileInfo
= pOut
->pTileInfo
;
124 // Set default values
125 if (pIn
->pTileInfo
!= NULL
)
127 if (pTileInfo
!= pIn
->pTileInfo
)
129 *pTileInfo
= *pIn
->pTileInfo
;
134 memset(pTileInfo
, 0, sizeof(ADDR_TILEINFO
));
137 // For macro tile mode, we should calculate default tiling parameters
138 HwlSetupTileInfo(tileMode
,
158 // This is calculating one face, remove cube flag
165 case ADDR_TM_LINEAR_GENERAL
://fall through
166 case ADDR_TM_LINEAR_ALIGNED
:
167 valid
= ComputeSurfaceInfoLinear(pIn
, pOut
, padDims
);
170 case ADDR_TM_1D_TILED_THIN1
://fall through
171 case ADDR_TM_1D_TILED_THICK
:
172 valid
= ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, tileMode
);
175 case ADDR_TM_2D_TILED_THIN1
: //fall through
176 case ADDR_TM_2D_TILED_THICK
: //fall through
177 case ADDR_TM_3D_TILED_THIN1
: //fall through
178 case ADDR_TM_3D_TILED_THICK
: //fall through
179 case ADDR_TM_2D_TILED_XTHICK
: //fall through
180 case ADDR_TM_3D_TILED_XTHICK
: //fall through
181 case ADDR_TM_PRT_TILED_THIN1
: //fall through
182 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
183 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
184 case ADDR_TM_PRT_TILED_THICK
: //fall through
185 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
186 case ADDR_TM_PRT_3D_TILED_THICK
:
187 valid
= ComputeSurfaceInfoMacroTiled(pIn
, pOut
, padDims
, tileMode
);
192 ADDR_ASSERT_ALWAYS();
200 ***************************************************************************************************
201 * EgBasedAddrLib::ComputeSurfaceInfoLinear
204 * Compute linear surface sizes include padded pitch, height, slices, total size in
205 * bytes, meanwhile alignments as well. Since it is linear mode, so output tile mode
206 * will not be changed here. Results are returned through output parameters.
209 * TRUE if no error occurs
210 ***************************************************************************************************
212 BOOL_32
EgBasedAddrLib::ComputeSurfaceInfoLinear(
213 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
214 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
215 UINT_32 padDims
///< [in] Dimensions to padd
218 UINT_32 expPitch
= pIn
->width
;
219 UINT_32 expHeight
= pIn
->height
;
220 UINT_32 expNumSlices
= pIn
->numSlices
;
222 // No linear MSAA on real H/W, keep this for TGL
223 UINT_32 numSamples
= pOut
->numSamples
;
225 const UINT_32 microTileThickness
= 1;
228 // Compute the surface alignments.
230 ComputeSurfaceAlignmentsLinear(pIn
->tileMode
,
237 if ((pIn
->tileMode
== ADDR_TM_LINEAR_GENERAL
) && pIn
->flags
.color
&& (pIn
->height
> 1))
240 // When linear_general surface is accessed in multiple lines, it requires 8 pixels in pitch
241 // alignment since PITCH_TILE_MAX is in unit of 8 pixels.
242 // It is OK if it is accessed per line.
243 ADDR_ASSERT((pIn
->width
% 8) == 0);
247 pOut
->depthAlign
= microTileThickness
;
249 expPitch
= HwlPreHandleBaseLvl3xPitch(pIn
, expPitch
);
252 // Pad pitch and height to the required granularities.
254 PadDimensions(pIn
->tileMode
,
261 &expPitch
, pOut
->pitchAlign
,
262 &expHeight
, pOut
->heightAlign
,
263 &expNumSlices
, microTileThickness
);
265 expPitch
= HwlPostHandleBaseLvl3xPitch(pIn
, expPitch
);
271 UINT_64 logicalSliceSize
;
273 logicalSliceSize
= HwlGetSizeAdjustmentLinear(pIn
->tileMode
,
283 pOut
->pitch
= expPitch
;
284 pOut
->height
= expHeight
;
285 pOut
->depth
= expNumSlices
;
287 pOut
->surfSize
= logicalSliceSize
* expNumSlices
;
289 pOut
->tileMode
= pIn
->tileMode
;
295 ***************************************************************************************************
296 * EgBasedAddrLib::ComputeSurfaceInfoMicroTiled
299 * Compute 1D/Micro Tiled surface sizes include padded pitch, height, slices, total
300 * size in bytes, meanwhile alignments as well. Results are returned through output
304 * TRUE if no error occurs
305 ***************************************************************************************************
307 BOOL_32
EgBasedAddrLib::ComputeSurfaceInfoMicroTiled(
308 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
309 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
310 UINT_32 padDims
, ///< [in] Dimensions to padd
311 AddrTileMode expTileMode
///< [in] Expected tile mode
314 BOOL_32 valid
= TRUE
;
316 UINT_32 microTileThickness
;
317 UINT_32 expPitch
= pIn
->width
;
318 UINT_32 expHeight
= pIn
->height
;
319 UINT_32 expNumSlices
= pIn
->numSlices
;
321 // No 1D MSAA on real H/W, keep this for TGL
322 UINT_32 numSamples
= pOut
->numSamples
;
325 // Compute the micro tile thickness.
327 microTileThickness
= ComputeSurfaceThickness(expTileMode
);
330 // Extra override for mip levels
332 if (pIn
->mipLevel
> 0)
335 // Reduce tiling mode from thick to thin if the number of slices is less than the
336 // micro tile thickness.
338 if ((expTileMode
== ADDR_TM_1D_TILED_THICK
) &&
339 (expNumSlices
< ThickTileThickness
))
341 expTileMode
= HwlDegradeThickTileMode(ADDR_TM_1D_TILED_THICK
, expNumSlices
, NULL
);
342 if (expTileMode
!= ADDR_TM_1D_TILED_THICK
)
344 microTileThickness
= 1;
350 // Compute the surface restrictions.
352 ComputeSurfaceAlignmentsMicroTiled(expTileMode
,
361 pOut
->depthAlign
= microTileThickness
;
364 // Pad pitch and height to the required granularities.
365 // Compute surface size.
366 // Return parameters.
368 PadDimensions(expTileMode
,
375 &expPitch
, pOut
->pitchAlign
,
376 &expHeight
, pOut
->heightAlign
,
377 &expNumSlices
, microTileThickness
);
380 // Get HWL specific pitch adjustment
382 UINT_64 logicalSliceSize
= HwlGetSizeAdjustmentMicroTiled(microTileThickness
,
392 pOut
->pitch
= expPitch
;
393 pOut
->height
= expHeight
;
394 pOut
->depth
= expNumSlices
;
396 pOut
->surfSize
= logicalSliceSize
* expNumSlices
;
398 pOut
->tileMode
= expTileMode
;
405 ***************************************************************************************************
406 * EgBasedAddrLib::ComputeSurfaceInfoMacroTiled
409 * Compute 2D/macro tiled surface sizes include padded pitch, height, slices, total
410 * size in bytes, meanwhile output suitable tile mode and alignments might be changed
411 * in this call as well. Results are returned through output parameters.
414 * TRUE if no error occurs
415 ***************************************************************************************************
417 BOOL_32
EgBasedAddrLib::ComputeSurfaceInfoMacroTiled(
418 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
419 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
420 UINT_32 padDims
, ///< [in] Dimensions to padd
421 AddrTileMode expTileMode
///< [in] Expected tile mode
424 BOOL_32 valid
= TRUE
;
426 AddrTileMode origTileMode
= expTileMode
;
427 UINT_32 microTileThickness
;
430 UINT_32 paddedHeight
;
431 UINT_64 bytesPerSlice
;
433 UINT_32 expPitch
= pIn
->width
;
434 UINT_32 expHeight
= pIn
->height
;
435 UINT_32 expNumSlices
= pIn
->numSlices
;
437 UINT_32 numSamples
= pOut
->numSamples
;
440 // Compute the surface restrictions as base
441 // SanityCheckMacroTiled is called in ComputeSurfaceAlignmentsMacroTiled
443 valid
= ComputeSurfaceAlignmentsMacroTiled(expTileMode
,
456 // Compute the micro tile thickness.
458 microTileThickness
= ComputeSurfaceThickness(expTileMode
);
461 // Find the correct tiling mode for mip levels
463 if (pIn
->mipLevel
> 0)
466 // Try valid tile mode
468 expTileMode
= ComputeSurfaceMipLevelTileMode(expTileMode
,
478 if (!IsMacroTiled(expTileMode
)) // Downgraded to micro-tiled
480 return ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, expTileMode
);
484 if (microTileThickness
!= ComputeSurfaceThickness(expTileMode
))
487 // Re-compute if thickness changed since bank-height may be changed!
489 return ComputeSurfaceInfoMacroTiled(pIn
, pOut
, padDims
, expTileMode
);
494 paddedPitch
= expPitch
;
495 paddedHeight
= expHeight
;
500 if (expTileMode
!= origTileMode
) // Tile mode is changed but still macro-tiled
502 valid
= ComputeSurfaceAlignmentsMacroTiled(expTileMode
,
516 PadDimensions(expTileMode
,
523 &paddedPitch
, pOut
->pitchAlign
,
524 &paddedHeight
, pOut
->heightAlign
,
525 &expNumSlices
, microTileThickness
);
527 if (pIn
->flags
.qbStereo
&&
528 (pOut
->pStereoInfo
!= NULL
) &&
529 HwlStereoCheckRightOffsetPadding())
531 // Eye height's bank bits are different from y == 0?
532 // Since 3D rendering treats right eye buffer starting from y == "eye height" while
533 // display engine treats it to be 0, so the bank bits may be different, we pad
534 // more in height to make sure y == "eye height" has the same bank bits as y == 0.
535 UINT_32 checkMask
= pOut
->pTileInfo
->banks
- 1;
536 UINT_32 bankBits
= 0;
539 bankBits
= (paddedHeight
/ 8 / pOut
->pTileInfo
->bankHeight
) & checkMask
;
543 paddedHeight
+= pOut
->heightAlign
;
549 // Compute the size of a slice.
551 bytesPerSlice
= BITS_TO_BYTES(static_cast<UINT_64
>(paddedPitch
) *
552 paddedHeight
* NextPow2(pIn
->bpp
) * numSamples
);
554 pOut
->pitch
= paddedPitch
;
555 // Put this check right here to workaround special mipmap cases which the original height
557 // The original height is pre-stored in pOut->height in PostComputeMipLevel and
558 // pOut->pitch is needed in HwlCheckLastMacroTiledLvl, too.
559 if (m_configFlags
.checkLast2DLevel
&& numSamples
== 1) // Don't check MSAA
561 // Set a TRUE in pOut if next Level is the first 1D sub level
562 HwlCheckLastMacroTiledLvl(pIn
, pOut
);
564 pOut
->height
= paddedHeight
;
566 pOut
->depth
= expNumSlices
;
568 pOut
->surfSize
= bytesPerSlice
* expNumSlices
;
570 pOut
->tileMode
= expTileMode
;
572 pOut
->depthAlign
= microTileThickness
;
580 ***************************************************************************************************
581 * EgBasedAddrLib::ComputeSurfaceAlignmentsLinear
584 * Compute linear surface alignment, calculation results are returned through
588 * TRUE if no error occurs
589 ***************************************************************************************************
591 BOOL_32
EgBasedAddrLib::ComputeSurfaceAlignmentsLinear(
592 AddrTileMode tileMode
, ///< [in] tile mode
593 UINT_32 bpp
, ///< [in] bits per pixel
594 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
595 UINT_32
* pBaseAlign
, ///< [out] base address alignment in bytes
596 UINT_32
* pPitchAlign
, ///< [out] pitch alignment in pixels
597 UINT_32
* pHeightAlign
///< [out] height alignment in pixels
600 BOOL_32 valid
= TRUE
;
604 case ADDR_TM_LINEAR_GENERAL
:
606 // The required base alignment and pitch and height granularities is to 1 element.
608 *pBaseAlign
= (bpp
> 8) ? bpp
/ 8 : 1;
612 case ADDR_TM_LINEAR_ALIGNED
:
614 // The required alignment for base is the pipe interleave size.
615 // The required granularity for pitch is hwl dependent.
616 // The required granularity for height is one row.
618 *pBaseAlign
= m_pipeInterleaveBytes
;
619 *pPitchAlign
= HwlGetPitchAlignmentLinear(bpp
, flags
);
626 ADDR_UNHANDLED_CASE();
630 AdjustPitchAlignment(flags
, pPitchAlign
);
636 ***************************************************************************************************
637 * EgBasedAddrLib::ComputeSurfaceAlignmentsMicroTiled
640 * Compute 1D tiled surface alignment, calculation results are returned through
644 * TRUE if no error occurs
645 ***************************************************************************************************
647 BOOL_32
EgBasedAddrLib::ComputeSurfaceAlignmentsMicroTiled(
648 AddrTileMode tileMode
, ///< [in] tile mode
649 UINT_32 bpp
, ///< [in] bits per pixel
650 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
651 UINT_32 mipLevel
, ///< [in] mip level
652 UINT_32 numSamples
, ///< [in] number of samples
653 UINT_32
* pBaseAlign
, ///< [out] base address alignment in bytes
654 UINT_32
* pPitchAlign
, ///< [out] pitch alignment in pixels
655 UINT_32
* pHeightAlign
///< [out] height alignment in pixels
658 BOOL_32 valid
= TRUE
;
661 // The required alignment for base is the pipe interleave size.
663 *pBaseAlign
= m_pipeInterleaveBytes
;
665 *pPitchAlign
= HwlGetPitchAlignmentMicroTiled(tileMode
, bpp
, flags
, numSamples
);
667 *pHeightAlign
= MicroTileHeight
;
669 AdjustPitchAlignment(flags
, pPitchAlign
);
672 // Workaround 2 for 1D tiling - There is HW bug for Carrizo
673 // where it requires the following alignments for 1D tiling.
674 if (flags
.czDispCompatible
&& (mipLevel
== 0))
676 *pBaseAlign
= PowTwoAlign(*pBaseAlign
, 4096); //Base address MOD 4096 = 0
677 *pPitchAlign
= PowTwoAlign(*pPitchAlign
, 512 / (BITS_TO_BYTES(bpp
))); //(8 lines * pitch * bytes per pixel) MOD 4096 = 0
679 // end Carrizo workaround for 1D tilling
686 ***************************************************************************************************
687 * EgBasedAddrLib::HwlReduceBankWidthHeight
690 * Additional checks, reduce bankHeight/bankWidth if needed and possible
691 * tileSize*BANK_WIDTH*BANK_HEIGHT <= ROW_SIZE
694 * TRUE if no error occurs
695 ***************************************************************************************************
697 BOOL_32
EgBasedAddrLib::HwlReduceBankWidthHeight(
698 UINT_32 tileSize
, ///< [in] tile size
699 UINT_32 bpp
, ///< [in] bits per pixel
700 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
701 UINT_32 numSamples
, ///< [in] number of samples
702 UINT_32 bankHeightAlign
, ///< [in] bank height alignment
703 UINT_32 pipes
, ///< [in] pipes
704 ADDR_TILEINFO
* pTileInfo
///< [in/out] bank structure.
707 UINT_32 macroAspectAlign
;
708 BOOL_32 valid
= TRUE
;
710 if (tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
)
712 BOOL_32 stillGreater
= TRUE
;
714 // Try reducing bankWidth first
715 if (stillGreater
&& pTileInfo
->bankWidth
> 1)
717 while (stillGreater
&& pTileInfo
->bankWidth
> 0)
719 pTileInfo
->bankWidth
>>= 1;
721 if (pTileInfo
->bankWidth
== 0)
723 pTileInfo
->bankWidth
= 1;
728 tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
;
731 // bankWidth is reduced above, so we need to recalculate bankHeight and ratio
732 bankHeightAlign
= Max(1u,
733 m_pipeInterleaveBytes
* m_bankInterleave
/
734 (tileSize
* pTileInfo
->bankWidth
)
737 // We cannot increase bankHeight so just assert this case.
738 ADDR_ASSERT((pTileInfo
->bankHeight
% bankHeightAlign
) == 0);
742 macroAspectAlign
= Max(1u,
743 m_pipeInterleaveBytes
* m_bankInterleave
/
744 (tileSize
* pipes
* pTileInfo
->bankWidth
)
746 pTileInfo
->macroAspectRatio
= PowTwoAlign(pTileInfo
->macroAspectRatio
,
751 // Early quit bank_height degradation for "64" bit z buffer
752 if (flags
.depth
&& bpp
>= 64)
754 stillGreater
= FALSE
;
757 // Then try reducing bankHeight
758 if (stillGreater
&& pTileInfo
->bankHeight
> bankHeightAlign
)
760 while (stillGreater
&& pTileInfo
->bankHeight
> bankHeightAlign
)
762 pTileInfo
->bankHeight
>>= 1;
764 if (pTileInfo
->bankHeight
< bankHeightAlign
)
766 pTileInfo
->bankHeight
= bankHeightAlign
;
771 tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
;
775 valid
= !stillGreater
;
777 // Generate a warning if we still fail to meet this constraint
781 0, ("TILE_SIZE(%d)*BANK_WIDTH(%d)*BANK_HEIGHT(%d) <= ROW_SIZE(%d)",
782 tileSize
, pTileInfo
->bankWidth
, pTileInfo
->bankHeight
, m_rowSize
));
790 ***************************************************************************************************
791 * EgBasedAddrLib::ComputeSurfaceAlignmentsMacroTiled
794 * Compute 2D tiled surface alignment, calculation results are returned through
798 * TRUE if no error occurs
799 ***************************************************************************************************
801 BOOL_32
EgBasedAddrLib::ComputeSurfaceAlignmentsMacroTiled(
802 AddrTileMode tileMode
, ///< [in] tile mode
803 UINT_32 bpp
, ///< [in] bits per pixel
804 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
805 UINT_32 mipLevel
, ///< [in] mip level
806 UINT_32 numSamples
, ///< [in] number of samples
807 ADDR_TILEINFO
* pTileInfo
, ///< [in/out] bank structure.
808 UINT_32
* pBaseAlign
, ///< [out] base address alignment in bytes
809 UINT_32
* pPitchAlign
, ///< [out] pitch alignment in pixels
810 UINT_32
* pHeightAlign
///< [out] height alignment in pixels
813 BOOL_32 valid
= SanityCheckMacroTiled(pTileInfo
);
817 UINT_32 macroTileWidth
;
818 UINT_32 macroTileHeight
;
821 UINT_32 bankHeightAlign
;
822 UINT_32 macroAspectAlign
;
824 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
825 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
828 // Align bank height first according to latest h/w spec
831 // tile_size = MIN(tile_split, 64 * tile_thickness * element_bytes * num_samples)
832 tileSize
= Min(pTileInfo
->tileSplitBytes
,
833 BITS_TO_BYTES(64 * thickness
* bpp
* numSamples
));
835 // bank_height_align =
836 // MAX(1, (pipe_interleave_bytes * bank_interleave)/(tile_size*bank_width))
837 bankHeightAlign
= Max(1u,
838 m_pipeInterleaveBytes
* m_bankInterleave
/
839 (tileSize
* pTileInfo
->bankWidth
)
842 pTileInfo
->bankHeight
= PowTwoAlign(pTileInfo
->bankHeight
, bankHeightAlign
);
844 // num_pipes * bank_width * macro_tile_aspect >=
845 // (pipe_interleave_size * bank_interleave) / tile_size
848 // this restriction is only for mipmap (mipmap's numSamples must be 1)
849 macroAspectAlign
= Max(1u,
850 m_pipeInterleaveBytes
* m_bankInterleave
/
851 (tileSize
* pipes
* pTileInfo
->bankWidth
)
853 pTileInfo
->macroAspectRatio
= PowTwoAlign(pTileInfo
->macroAspectRatio
, macroAspectAlign
);
856 valid
= HwlReduceBankWidthHeight(tileSize
,
865 // The required granularity for pitch is the macro tile width.
867 macroTileWidth
= MicroTileWidth
* pTileInfo
->bankWidth
* pipes
*
868 pTileInfo
->macroAspectRatio
;
870 *pPitchAlign
= macroTileWidth
;
872 AdjustPitchAlignment(flags
, pPitchAlign
);
875 // The required granularity for height is the macro tile height.
877 macroTileHeight
= MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
/
878 pTileInfo
->macroAspectRatio
;
880 *pHeightAlign
= macroTileHeight
;
883 // Compute base alignment
885 *pBaseAlign
= pipes
*
886 pTileInfo
->bankWidth
* pTileInfo
->banks
* pTileInfo
->bankHeight
* tileSize
;
888 if ((mipLevel
== 0) && (flags
.prt
) && (m_chipFamily
== ADDR_CHIP_FAMILY_SI
))
890 static const UINT_32 PrtTileSize
= 0x10000;
892 UINT_32 macroTileSize
= macroTileWidth
* macroTileHeight
* numSamples
* bpp
/ 8;
894 if (macroTileSize
< PrtTileSize
)
896 UINT_32 numMacroTiles
= PrtTileSize
/ macroTileSize
;
898 ADDR_ASSERT((PrtTileSize
% macroTileSize
) == 0);
900 *pPitchAlign
*= numMacroTiles
;
901 *pBaseAlign
*= numMacroTiles
;
910 ***************************************************************************************************
911 * EgBasedAddrLib::SanityCheckMacroTiled
914 * Check if macro-tiled parameters are valid
917 ***************************************************************************************************
919 BOOL_32
EgBasedAddrLib::SanityCheckMacroTiled(
920 ADDR_TILEINFO
* pTileInfo
///< [in] macro-tiled parameters
923 BOOL_32 valid
= TRUE
;
924 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
926 switch (pTileInfo
->banks
)
928 case 2: //fall through
929 case 4: //fall through
930 case 8: //fall through
941 switch (pTileInfo
->bankWidth
)
943 case 1: //fall through
944 case 2: //fall through
945 case 4: //fall through
956 switch (pTileInfo
->bankHeight
)
958 case 1: //fall through
959 case 2: //fall through
960 case 4: //fall through
971 switch (pTileInfo
->macroAspectRatio
)
973 case 1: //fall through
974 case 2: //fall through
975 case 4: //fall through
986 if (pTileInfo
->banks
< pTileInfo
->macroAspectRatio
)
988 // This will generate macro tile height <= 1
995 if (pTileInfo
->tileSplitBytes
> m_rowSize
)
997 ADDR_WARN(0, ("tileSplitBytes is bigger than row size"));
1003 valid
= HwlSanityCheckMacroTiled(pTileInfo
);
1006 ADDR_ASSERT(valid
== TRUE
);
1008 // Add this assert for guidance
1009 ADDR_ASSERT(numPipes
* pTileInfo
->banks
>= 4);
1015 ***************************************************************************************************
1016 * EgBasedAddrLib::ComputeSurfaceMipLevelTileMode
1019 * Compute valid tile mode for surface mipmap sub-levels
1022 * Suitable tile mode
1023 ***************************************************************************************************
1025 AddrTileMode
EgBasedAddrLib::ComputeSurfaceMipLevelTileMode(
1026 AddrTileMode baseTileMode
, ///< [in] base tile mode
1027 UINT_32 bpp
, ///< [in] bits per pixels
1028 UINT_32 pitch
, ///< [in] current level pitch
1029 UINT_32 height
, ///< [in] current level height
1030 UINT_32 numSlices
, ///< [in] current number of slices
1031 UINT_32 numSamples
, ///< [in] number of samples
1032 UINT_32 pitchAlign
, ///< [in] pitch alignment
1033 UINT_32 heightAlign
, ///< [in] height alignment
1034 ADDR_TILEINFO
* pTileInfo
///< [in] ptr to bank structure
1037 UINT_32 bytesPerTile
;
1039 AddrTileMode expTileMode
= baseTileMode
;
1040 UINT_32 microTileThickness
= ComputeSurfaceThickness(expTileMode
);
1041 UINT_32 interleaveSize
= m_pipeInterleaveBytes
* m_bankInterleave
;
1044 // Compute the size of a slice.
1046 bytesPerTile
= BITS_TO_BYTES(MicroTilePixels
* microTileThickness
* NextPow2(bpp
) * numSamples
);
1049 // Reduce tiling mode from thick to thin if the number of slices is less than the
1050 // micro tile thickness.
1052 if (numSlices
< microTileThickness
)
1054 expTileMode
= HwlDegradeThickTileMode(expTileMode
, numSlices
, &bytesPerTile
);
1057 if (bytesPerTile
> pTileInfo
->tileSplitBytes
)
1059 bytesPerTile
= pTileInfo
->tileSplitBytes
;
1062 UINT_32 threshold1
=
1063 bytesPerTile
* HwlGetPipes(pTileInfo
) * pTileInfo
->bankWidth
* pTileInfo
->macroAspectRatio
;
1065 UINT_32 threshold2
=
1066 bytesPerTile
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
;
1069 // Reduce the tile mode from 2D/3D to 1D in following conditions
1071 switch (expTileMode
)
1073 case ADDR_TM_2D_TILED_THIN1
: //fall through
1074 case ADDR_TM_3D_TILED_THIN1
:
1075 case ADDR_TM_PRT_TILED_THIN1
:
1076 case ADDR_TM_PRT_2D_TILED_THIN1
:
1077 case ADDR_TM_PRT_3D_TILED_THIN1
:
1078 if ((pitch
< pitchAlign
) ||
1079 (height
< heightAlign
) ||
1080 (interleaveSize
> threshold1
) ||
1081 (interleaveSize
> threshold2
))
1083 expTileMode
= ADDR_TM_1D_TILED_THIN1
;
1086 case ADDR_TM_2D_TILED_THICK
: //fall through
1087 case ADDR_TM_3D_TILED_THICK
:
1088 case ADDR_TM_2D_TILED_XTHICK
:
1089 case ADDR_TM_3D_TILED_XTHICK
:
1090 case ADDR_TM_PRT_TILED_THICK
:
1091 case ADDR_TM_PRT_2D_TILED_THICK
:
1092 case ADDR_TM_PRT_3D_TILED_THICK
:
1093 if ((pitch
< pitchAlign
) ||
1094 (height
< heightAlign
))
1096 expTileMode
= ADDR_TM_1D_TILED_THICK
;
1107 ***************************************************************************************************
1108 * EgBasedAddrLib::HwlDegradeBaseLevel
1110 * Check if degrade is needed for base level
1112 * TRUE if degrade is suggested
1113 ***************************************************************************************************
1115 BOOL_32
EgBasedAddrLib::HwlDegradeBaseLevel(
1116 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
) const
1118 BOOL_32 degrade
= FALSE
;
1119 BOOL_32 valid
= TRUE
;
1121 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
1125 UINT_32 heightAlign
;
1127 ADDR_ASSERT(pIn
->pTileInfo
);
1128 ADDR_TILEINFO tileInfo
= *pIn
->pTileInfo
;
1129 ADDR_COMPUTE_SURFACE_INFO_OUTPUT out
= {0};
1131 if (UseTileIndex(pIn
->tileIndex
))
1133 out
.tileIndex
= pIn
->tileIndex
;
1134 out
.macroModeIndex
= TileIndexInvalid
;
1137 HwlSetupTileInfo(pIn
->tileMode
,
1148 valid
= ComputeSurfaceAlignmentsMacroTiled(pIn
->tileMode
,
1160 degrade
= (pIn
->width
< pitchAlign
|| pIn
->height
< heightAlign
);
1161 // Check whether 2D tiling still has too much footprint
1162 if (degrade
== FALSE
)
1164 // Only check width and height as slices are aligned to thickness
1165 UINT_64 unalignedSize
= pIn
->width
* pIn
->height
;
1167 UINT_32 alignedPitch
= PowTwoAlign(pIn
->width
, pitchAlign
);
1168 UINT_32 alignedHeight
= PowTwoAlign(pIn
->height
, heightAlign
);
1169 UINT_64 alignedSize
= alignedPitch
* alignedHeight
;
1171 // alignedSize > 1.5 * unalignedSize
1172 if (2 * alignedSize
> 3 * unalignedSize
)
1187 ***************************************************************************************************
1188 * EgBasedAddrLib::HwlDegradeThickTileMode
1191 * Degrades valid tile mode for thick modes if needed
1194 * Suitable tile mode
1195 ***************************************************************************************************
1197 AddrTileMode
EgBasedAddrLib::HwlDegradeThickTileMode(
1198 AddrTileMode baseTileMode
, ///< [in] base tile mode
1199 UINT_32 numSlices
, ///< [in] current number of slices
1200 UINT_32
* pBytesPerTile
///< [in/out] pointer to bytes per slice
1203 ADDR_ASSERT(numSlices
< ComputeSurfaceThickness(baseTileMode
));
1204 // if pBytesPerTile is NULL, this is a don't-care....
1205 UINT_32 bytesPerTile
= pBytesPerTile
!= NULL
? *pBytesPerTile
: 64;
1207 AddrTileMode expTileMode
= baseTileMode
;
1208 switch (baseTileMode
)
1210 case ADDR_TM_1D_TILED_THICK
:
1211 expTileMode
= ADDR_TM_1D_TILED_THIN1
;
1214 case ADDR_TM_2D_TILED_THICK
:
1215 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1218 case ADDR_TM_3D_TILED_THICK
:
1219 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1222 case ADDR_TM_2D_TILED_XTHICK
:
1223 if (numSlices
< ThickTileThickness
)
1225 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1230 expTileMode
= ADDR_TM_2D_TILED_THICK
;
1234 case ADDR_TM_3D_TILED_XTHICK
:
1235 if (numSlices
< ThickTileThickness
)
1237 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1242 expTileMode
= ADDR_TM_3D_TILED_THICK
;
1247 ADDR_ASSERT_ALWAYS();
1251 if (pBytesPerTile
!= NULL
)
1253 *pBytesPerTile
= bytesPerTile
;
1260 ***************************************************************************************************
1261 * EgBasedAddrLib::DispatchComputeSurfaceAddrFromCoord
1264 * Compute surface address from given coord (x, y, slice,sample)
1268 ***************************************************************************************************
1270 UINT_64
EgBasedAddrLib::DispatchComputeSurfaceAddrFromCoord(
1271 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1272 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1277 UINT_32 slice
= pIn
->slice
;
1278 UINT_32 sample
= pIn
->sample
;
1279 UINT_32 bpp
= pIn
->bpp
;
1280 UINT_32 pitch
= pIn
->pitch
;
1281 UINT_32 height
= pIn
->height
;
1282 UINT_32 numSlices
= pIn
->numSlices
;
1283 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
1284 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
1285 AddrTileMode tileMode
= pIn
->tileMode
;
1286 AddrTileType microTileType
= pIn
->tileType
;
1287 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
1288 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
1289 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
1291 UINT_32
* pBitPosition
= &pOut
->bitPosition
;
1295 UINT_32 addr5Bit
= 0;
1296 UINT_32 addr5Swizzle
= pIn
->addr5Swizzle
;
1297 BOOL_32 is32ByteTile
= pIn
->is32ByteTile
;
1300 // ADDR_DEPTH_SAMPLE_ORDER = non-disp + depth-sample-order
1301 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
1303 isDepthSampleOrder
= TRUE
;
1306 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
1308 if (numFrags
!= numSamples
)
1310 numSamples
= numFrags
;
1311 ADDR_ASSERT(sample
< numSamples
);
1315 /// 128 bit/thick tiled surface doesn't support display tiling and
1316 /// mipmap chain must have the same tileType, so please fill tileType correctly
1317 if (!IsLinear(pIn
->tileMode
))
1319 if (bpp
>= 128 || ComputeSurfaceThickness(tileMode
) > 1)
1321 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
1328 case ADDR_TM_LINEAR_GENERAL
://fall through
1329 case ADDR_TM_LINEAR_ALIGNED
:
1330 addr
= ComputeSurfaceAddrFromCoordLinear(x
,
1340 case ADDR_TM_1D_TILED_THIN1
://fall through
1341 case ADDR_TM_1D_TILED_THICK
:
1342 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
1355 case ADDR_TM_2D_TILED_THIN1
: //fall through
1356 case ADDR_TM_2D_TILED_THICK
: //fall through
1357 case ADDR_TM_3D_TILED_THIN1
: //fall through
1358 case ADDR_TM_3D_TILED_THICK
: //fall through
1359 case ADDR_TM_2D_TILED_XTHICK
: //fall through
1360 case ADDR_TM_3D_TILED_XTHICK
: //fall through
1361 case ADDR_TM_PRT_TILED_THIN1
: //fall through
1362 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
1363 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
1364 case ADDR_TM_PRT_TILED_THICK
: //fall through
1365 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
1366 case ADDR_TM_PRT_3D_TILED_THICK
:
1367 UINT_32 pipeSwizzle
;
1368 UINT_32 bankSwizzle
;
1370 if (m_configFlags
.useCombinedSwizzle
)
1372 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
1373 &bankSwizzle
, &pipeSwizzle
);
1377 pipeSwizzle
= pIn
->pipeSwizzle
;
1378 bankSwizzle
= pIn
->bankSwizzle
;
1381 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
1400 ADDR_ASSERT_ALWAYS();
1405 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
1407 if (addr5Swizzle
&& isDepthSampleOrder
&& is32ByteTile
)
1409 UINT_32 tx
= x
>> 3;
1410 UINT_32 ty
= y
>> 3;
1411 UINT_32 tileBits
= ((ty
&0x3) << 2) | (tx
&0x3);
1413 tileBits
= tileBits
& addr5Swizzle
;
1414 addr5Bit
= XorReduce(tileBits
, 4);
1416 addr
= addr
| static_cast<UINT_64
>(addr5Bit
<< 5);
1425 ***************************************************************************************************
1426 * EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled
1429 * Computes the surface address and bit position from a
1430 * coordinate for 2D tilied (macro tiled)
1433 ***************************************************************************************************
1435 UINT_64
EgBasedAddrLib::ComputeSurfaceAddrFromCoordMacroTiled(
1436 UINT_32 x
, ///< [in] x coordinate
1437 UINT_32 y
, ///< [in] y coordinate
1438 UINT_32 slice
, ///< [in] slice index
1439 UINT_32 sample
, ///< [in] sample index
1440 UINT_32 bpp
, ///< [in] bits per pixel
1441 UINT_32 pitch
, ///< [in] surface pitch, in pixels
1442 UINT_32 height
, ///< [in] surface height, in pixels
1443 UINT_32 numSamples
, ///< [in] number of samples
1444 AddrTileMode tileMode
, ///< [in] tile mode
1445 AddrTileType microTileType
, ///< [in] micro tiling type
1446 BOOL_32 ignoreSE
, ///< [in] TRUE if shader enginers can be ignored
1447 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if it depth sample ordering is used
1448 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
1449 UINT_32 bankSwizzle
, ///< [in] bank swizzle
1450 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure
1451 /// **All fields to be valid on entry**
1452 UINT_32
* pBitPosition
///< [out] bit position, e.g. FMT_1 will use this
1457 UINT_32 microTileBytes
;
1458 UINT_32 microTileBits
;
1459 UINT_32 sampleOffset
;
1461 UINT_32 pixelOffset
;
1462 UINT_32 elementOffset
;
1463 UINT_32 tileSplitSlice
;
1467 UINT_64 sliceOffset
;
1468 UINT_32 macroTilePitch
;
1469 UINT_32 macroTileHeight
;
1470 UINT_32 macroTilesPerRow
;
1471 UINT_32 macroTilesPerSlice
;
1472 UINT_64 macroTileBytes
;
1473 UINT_32 macroTileIndexX
;
1474 UINT_32 macroTileIndexY
;
1475 UINT_64 macroTileOffset
;
1476 UINT_64 totalOffset
;
1477 UINT_64 pipeInterleaveMask
;
1478 UINT_64 bankInterleaveMask
;
1479 UINT_64 pipeInterleaveOffset
;
1480 UINT_32 bankInterleaveOffset
;
1482 UINT_32 tileRowIndex
;
1483 UINT_32 tileColumnIndex
;
1487 UINT_32 microTileThickness
= ComputeSurfaceThickness(tileMode
);
1490 // Compute the number of group, pipe, and bank bits.
1492 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1493 UINT_32 numPipeInterleaveBits
= Log2(m_pipeInterleaveBytes
);
1494 UINT_32 numPipeBits
= Log2(numPipes
);
1495 UINT_32 numBankInterleaveBits
= Log2(m_bankInterleave
);
1496 UINT_32 numBankBits
= Log2(pTileInfo
->banks
);
1499 // Compute the micro tile size.
1501 microTileBits
= MicroTilePixels
* microTileThickness
* bpp
* numSamples
;
1503 microTileBytes
= microTileBits
/ 8;
1505 // Compute the pixel index within the micro tile.
1507 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
1515 // Compute the sample offset and pixel offset.
1517 if (isDepthSampleOrder
)
1520 // For depth surfaces, samples are stored contiguously for each element, so the sample
1521 // offset is the sample number times the element size.
1523 sampleOffset
= sample
* bpp
;
1524 pixelOffset
= pixelIndex
* bpp
* numSamples
;
1529 // For color surfaces, all elements for a particular sample are stored contiguously, so
1530 // the sample offset is the sample number times the micro tile size divided yBit the number
1533 sampleOffset
= sample
* (microTileBits
/ numSamples
);
1534 pixelOffset
= pixelIndex
* bpp
;
1538 // Compute the element offset.
1540 elementOffset
= pixelOffset
+ sampleOffset
;
1542 *pBitPosition
= static_cast<UINT_32
>(elementOffset
% 8);
1544 elementOffset
/= 8; //bit-to-byte
1547 // Determine if tiles need to be split across slices.
1549 // If the size of the micro tile is larger than the tile split size, then the tile will be
1550 // split across multiple slices.
1552 UINT_32 slicesPerTile
= 1;
1554 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
1555 { //don't support for thick mode
1558 // Compute the number of slices per tile.
1560 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
1563 // Compute the tile split slice number for use in rotating the bank.
1565 tileSplitSlice
= elementOffset
/ pTileInfo
->tileSplitBytes
;
1568 // Adjust the element offset to account for the portion of the tile that is being moved to
1571 elementOffset
%= pTileInfo
->tileSplitBytes
;
1574 // Adjust the microTileBytes size to tileSplitBytes size since
1577 microTileBytes
= pTileInfo
->tileSplitBytes
;
1585 // Compute macro tile pitch and height.
1588 (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
) * pTileInfo
->macroAspectRatio
;
1590 (MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
) / pTileInfo
->macroAspectRatio
;
1593 // Compute the number of bytes per macro tile. Note: bytes of the same bank/pipe actually
1596 static_cast<UINT_64
>(microTileBytes
) *
1597 (macroTilePitch
/ MicroTileWidth
) * (macroTileHeight
/ MicroTileHeight
) /
1598 (numPipes
* pTileInfo
->banks
);
1601 // Compute the number of macro tiles per row.
1603 macroTilesPerRow
= pitch
/ macroTilePitch
;
1606 // Compute the offset to the macro tile containing the specified coordinate.
1608 macroTileIndexX
= x
/ macroTilePitch
;
1609 macroTileIndexY
= y
/ macroTileHeight
;
1610 macroTileOffset
= ((macroTileIndexY
* macroTilesPerRow
) + macroTileIndexX
) * macroTileBytes
;
1613 // Compute the number of macro tiles per slice.
1615 macroTilesPerSlice
= macroTilesPerRow
* (height
/ macroTileHeight
);
1618 // Compute the slice size.
1620 sliceBytes
= macroTilesPerSlice
* macroTileBytes
;
1623 // Compute the slice offset.
1625 sliceOffset
= sliceBytes
* (tileSplitSlice
+ slicesPerTile
* (slice
/ microTileThickness
));
1628 // Compute tile offest
1630 tileRowIndex
= (y
/ MicroTileHeight
) % pTileInfo
->bankHeight
;
1631 tileColumnIndex
= ((x
/ MicroTileWidth
) / numPipes
) % pTileInfo
->bankWidth
;
1632 tileIndex
= (tileRowIndex
* pTileInfo
->bankWidth
) + tileColumnIndex
;
1633 tileOffset
= tileIndex
* microTileBytes
;
1636 // Combine the slice offset and macro tile offset with the pixel and sample offsets, accounting
1637 // for the pipe and bank bits in the middle of the address.
1639 totalOffset
= sliceOffset
+ macroTileOffset
+ elementOffset
+ tileOffset
;
1642 // Get the pipe and bank.
1645 // when the tileMode is PRT type, then adjust x and y coordinates
1646 if (IsPrtNoRotationTileMode(tileMode
))
1648 x
= x
% macroTilePitch
;
1649 y
= y
% macroTileHeight
;
1652 pipe
= ComputePipeFromCoord(x
,
1660 bank
= ComputeBankFromCoord(x
,
1670 // Split the offset to put some bits below the pipe+bank bits and some above.
1672 pipeInterleaveMask
= (1 << numPipeInterleaveBits
) - 1;
1673 bankInterleaveMask
= (1 << numBankInterleaveBits
) - 1;
1674 pipeInterleaveOffset
= totalOffset
& pipeInterleaveMask
;
1675 bankInterleaveOffset
= static_cast<UINT_32
>((totalOffset
>> numPipeInterleaveBits
) &
1676 bankInterleaveMask
);
1677 offset
= totalOffset
>> (numPipeInterleaveBits
+ numBankInterleaveBits
);
1680 // Assemble the address from its components.
1682 addr
= pipeInterleaveOffset
;
1683 // This is to remove /analyze warnings
1684 UINT_32 pipeBits
= pipe
<< numPipeInterleaveBits
;
1685 UINT_32 bankInterleaveBits
= bankInterleaveOffset
<< (numPipeInterleaveBits
+ numPipeBits
);
1686 UINT_32 bankBits
= bank
<< (numPipeInterleaveBits
+ numPipeBits
+
1687 numBankInterleaveBits
);
1688 UINT_64 offsetBits
= offset
<< (numPipeInterleaveBits
+ numPipeBits
+
1689 numBankInterleaveBits
+ numBankBits
);
1692 addr
|= bankInterleaveBits
;
1700 ***************************************************************************************************
1701 * EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled
1704 * Computes the surface address and bit position from a coordinate for 1D tilied
1708 ***************************************************************************************************
1710 UINT_64
EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled(
1711 UINT_32 x
, ///< [in] x coordinate
1712 UINT_32 y
, ///< [in] y coordinate
1713 UINT_32 slice
, ///< [in] slice index
1714 UINT_32 sample
, ///< [in] sample index
1715 UINT_32 bpp
, ///< [in] bits per pixel
1716 UINT_32 pitch
, ///< [in] pitch, in pixels
1717 UINT_32 height
, ///< [in] height, in pixels
1718 UINT_32 numSamples
, ///< [in] number of samples
1719 AddrTileMode tileMode
, ///< [in] tile mode
1720 AddrTileType microTileType
, ///< [in] micro tiling type
1721 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if depth sample ordering is used
1722 UINT_32
* pBitPosition
///< [out] bit position, e.g. FMT_1 will use this
1727 UINT_32 microTileBytes
;
1729 UINT_32 microTilesPerRow
;
1730 UINT_32 microTileIndexX
;
1731 UINT_32 microTileIndexY
;
1732 UINT_32 microTileIndexZ
;
1733 UINT_64 sliceOffset
;
1734 UINT_64 microTileOffset
;
1735 UINT_32 sampleOffset
;
1737 UINT_32 pixelOffset
;
1739 UINT_32 microTileThickness
= ComputeSurfaceThickness(tileMode
);
1742 // Compute the micro tile size.
1744 microTileBytes
= BITS_TO_BYTES(MicroTilePixels
* microTileThickness
* bpp
* numSamples
);
1747 // Compute the slice size.
1750 BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* microTileThickness
* bpp
* numSamples
);
1753 // Compute the number of micro tiles per row.
1755 microTilesPerRow
= pitch
/ MicroTileWidth
;
1758 // Compute the micro tile index.
1760 microTileIndexX
= x
/ MicroTileWidth
;
1761 microTileIndexY
= y
/ MicroTileHeight
;
1762 microTileIndexZ
= slice
/ microTileThickness
;
1765 // Compute the slice offset.
1767 sliceOffset
= static_cast<UINT_64
>(microTileIndexZ
) * sliceBytes
;
1770 // Compute the offset to the micro tile containing the specified coordinate.
1772 microTileOffset
= (static_cast<UINT_64
>(microTileIndexY
) * microTilesPerRow
+ microTileIndexX
) *
1776 // Compute the pixel index within the micro tile.
1778 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
1785 // Compute the sample offset.
1787 if (isDepthSampleOrder
)
1790 // For depth surfaces, samples are stored contiguously for each element, so the sample
1791 // offset is the sample number times the element size.
1793 sampleOffset
= sample
* bpp
;
1794 pixelOffset
= pixelIndex
* bpp
* numSamples
;
1799 // For color surfaces, all elements for a particular sample are stored contiguously, so
1800 // the sample offset is the sample number times the micro tile size divided yBit the number
1803 sampleOffset
= sample
* (microTileBytes
*8 / numSamples
);
1804 pixelOffset
= pixelIndex
* bpp
;
1808 // Compute the bit position of the pixel. Each element is stored with one bit per sample.
1811 UINT_32 elemOffset
= sampleOffset
+ pixelOffset
;
1813 *pBitPosition
= elemOffset
% 8;
1817 // Combine the slice offset, micro tile offset, sample offset, and pixel offsets.
1819 addr
= sliceOffset
+ microTileOffset
+ elemOffset
;
1825 ***************************************************************************************************
1826 * EgBasedAddrLib::HwlComputePixelCoordFromOffset
1829 * Compute pixel coordinate from offset inside a micro tile
1832 ***************************************************************************************************
1834 VOID
EgBasedAddrLib::HwlComputePixelCoordFromOffset(
1835 UINT_32 offset
, ///< [in] offset inside micro tile in bits
1836 UINT_32 bpp
, ///< [in] bits per pixel
1837 UINT_32 numSamples
, ///< [in] number of samples
1838 AddrTileMode tileMode
, ///< [in] tile mode
1839 UINT_32 tileBase
, ///< [in] base offset within a tile
1840 UINT_32 compBits
, ///< [in] component bits actually needed(for planar surface)
1841 UINT_32
* pX
, ///< [out] x coordinate
1842 UINT_32
* pY
, ///< [out] y coordinate
1843 UINT_32
* pSlice
, ///< [out] slice index
1844 UINT_32
* pSample
, ///< [out] sample index
1845 AddrTileType microTileType
, ///< [in] micro tiling type
1846 BOOL_32 isDepthSampleOrder
///< [in] TRUE if depth sample order in microtile is used
1852 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
1854 // For planar surface, we adjust offset acoording to tile base
1855 if ((bpp
!= compBits
) && (compBits
!= 0) && isDepthSampleOrder
)
1859 ADDR_ASSERT(microTileType
== ADDR_NON_DISPLAYABLE
||
1860 microTileType
== ADDR_DEPTH_SAMPLE_ORDER
);
1865 UINT_32 sampleTileBits
;
1866 UINT_32 samplePixelBits
;
1869 if (isDepthSampleOrder
)
1871 samplePixelBits
= bpp
* numSamples
;
1872 pixelIndex
= offset
/ samplePixelBits
;
1873 *pSample
= (offset
% samplePixelBits
) / bpp
;
1877 sampleTileBits
= MicroTilePixels
* bpp
* thickness
;
1878 *pSample
= offset
/ sampleTileBits
;
1879 pixelIndex
= (offset
% sampleTileBits
) / bpp
;
1882 if (microTileType
!= ADDR_THICK
)
1884 if (microTileType
== ADDR_DISPLAYABLE
) // displayable
1889 x
= pixelIndex
& 0x7;
1890 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,4));
1893 x
= pixelIndex
& 0x7;
1894 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,3));
1897 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,1),_BIT(pixelIndex
,0));
1898 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,2));
1901 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
1902 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
1905 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,2),_BIT(pixelIndex
,1));
1906 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,0));
1912 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
1914 x
= Bits2Number(3, _BIT(pixelIndex
,4),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
1915 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
1917 else if (microTileType
== ADDR_ROTATED
)
1921 element_index[5:0] = { x[2], x[0], x[1], y[2], y[1], y[0] }
1924 element_index[5:0] = { x[2], x[1], x[0], y[2], y[1], y[0] }
1927 element_index[5:0] = { x[2], x[1], y[2], x[0], y[1], y[0] }
1930 element_index[5:0] = { y[2], x[2], x[1], y[1], x[0], y[0] }
1935 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,4));
1936 y
= pixelIndex
& 0x7;
1939 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,3));
1940 y
= pixelIndex
& 0x7;
1943 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,2));
1944 y
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,1),_BIT(pixelIndex
,0));
1947 x
= Bits2Number(3, _BIT(pixelIndex
,4),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
1948 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
1951 ADDR_ASSERT_ALWAYS();
1956 if (thickness
> 1) // thick
1958 z
= Bits2Number(3, _BIT(pixelIndex
,8),_BIT(pixelIndex
,7),_BIT(pixelIndex
,6));
1963 ADDR_ASSERT((m_chipFamily
>= ADDR_CHIP_FAMILY_CI
) && (thickness
> 1));
1965 8-Bit Elements and 16-Bit Elements
1966 element_index[7:0] = { y[2], x[2], z[1], z[0], y[1], x[1], y[0], x[0] }
1969 element_index[7:0] = { y[2], x[2], z[1], y[1], z[0], x[1], y[0], x[0] }
1971 64-Bit Elements and 128-Bit Elements
1972 element_index[7:0] = { y[2], x[2], z[1], y[1], x[1], z[0], y[0], x[0] }
1974 The equation to compute the element index for the extra thick tile:
1975 element_index[8] = z[2]
1980 case 16: // fall-through
1981 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
1982 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
1983 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4));
1986 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
1987 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
1988 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3));
1991 case 128: // fall-through
1992 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,3),_BIT(pixelIndex
,0));
1993 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
1994 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,2));
1997 ADDR_ASSERT_ALWAYS();
2003 z
+= Bits2Number(3,_BIT(pixelIndex
,8),0,0);
2014 ***************************************************************************************************
2015 * EgBasedAddrLib::DispatchComputeSurfaceCoordFromAddrDispatch
2018 * Compute (x,y,slice,sample) coordinates from surface address
2021 ***************************************************************************************************
2023 VOID
EgBasedAddrLib::DispatchComputeSurfaceCoordFromAddr(
2024 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
2025 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
2028 UINT_64 addr
= pIn
->addr
;
2029 UINT_32 bitPosition
= pIn
->bitPosition
;
2030 UINT_32 bpp
= pIn
->bpp
;
2031 UINT_32 pitch
= pIn
->pitch
;
2032 UINT_32 height
= pIn
->height
;
2033 UINT_32 numSlices
= pIn
->numSlices
;
2034 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
2035 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
2036 AddrTileMode tileMode
= pIn
->tileMode
;
2037 UINT_32 tileBase
= pIn
->tileBase
;
2038 UINT_32 compBits
= pIn
->compBits
;
2039 AddrTileType microTileType
= pIn
->tileType
;
2040 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
2041 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
2042 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2044 UINT_32
* pX
= &pOut
->x
;
2045 UINT_32
* pY
= &pOut
->y
;
2046 UINT_32
* pSlice
= &pOut
->slice
;
2047 UINT_32
* pSample
= &pOut
->sample
;
2049 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2051 isDepthSampleOrder
= TRUE
;
2054 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
2056 if (numFrags
!= numSamples
)
2058 numSamples
= numFrags
;
2062 /// 128 bit/thick tiled surface doesn't support display tiling and
2063 /// mipmap chain must have the same tileType, so please fill tileType correctly
2064 if (!IsLinear(pIn
->tileMode
))
2066 if (bpp
>= 128 || ComputeSurfaceThickness(tileMode
) > 1)
2068 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
2075 case ADDR_TM_LINEAR_GENERAL
://fall through
2076 case ADDR_TM_LINEAR_ALIGNED
:
2077 ComputeSurfaceCoordFromAddrLinear(addr
,
2088 case ADDR_TM_1D_TILED_THIN1
://fall through
2089 case ADDR_TM_1D_TILED_THICK
:
2090 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
2104 isDepthSampleOrder
);
2106 case ADDR_TM_2D_TILED_THIN1
: //fall through
2107 case ADDR_TM_2D_TILED_THICK
: //fall through
2108 case ADDR_TM_3D_TILED_THIN1
: //fall through
2109 case ADDR_TM_3D_TILED_THICK
: //fall through
2110 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2111 case ADDR_TM_3D_TILED_XTHICK
: //fall through
2112 case ADDR_TM_PRT_TILED_THIN1
: //fall through
2113 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
2114 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
2115 case ADDR_TM_PRT_TILED_THICK
: //fall through
2116 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
2117 case ADDR_TM_PRT_3D_TILED_THICK
:
2118 UINT_32 pipeSwizzle
;
2119 UINT_32 bankSwizzle
;
2121 if (m_configFlags
.useCombinedSwizzle
)
2123 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
2124 &bankSwizzle
, &pipeSwizzle
);
2128 pipeSwizzle
= pIn
->pipeSwizzle
;
2129 bankSwizzle
= pIn
->bankSwizzle
;
2132 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
2153 ADDR_ASSERT_ALWAYS();
2159 ***************************************************************************************************
2160 * EgBasedAddrLib::ComputeSurfaceCoordFromAddrMacroTiled
2163 * Compute surface coordinates from address for macro tiled surface
2166 ***************************************************************************************************
2168 VOID
EgBasedAddrLib::ComputeSurfaceCoordFromAddrMacroTiled(
2169 UINT_64 addr
, ///< [in] byte address
2170 UINT_32 bitPosition
, ///< [in] bit position
2171 UINT_32 bpp
, ///< [in] bits per pixel
2172 UINT_32 pitch
, ///< [in] pitch in pixels
2173 UINT_32 height
, ///< [in] height in pixels
2174 UINT_32 numSamples
, ///< [in] number of samples
2175 AddrTileMode tileMode
, ///< [in] tile mode
2176 UINT_32 tileBase
, ///< [in] tile base offset
2177 UINT_32 compBits
, ///< [in] component bits (for planar surface)
2178 AddrTileType microTileType
, ///< [in] micro tiling type
2179 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines can be ignored
2180 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if depth sample order is used
2181 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2182 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2183 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure.
2184 /// **All fields to be valid on entry**
2185 UINT_32
* pX
, ///< [out] X coord
2186 UINT_32
* pY
, ///< [out] Y coord
2187 UINT_32
* pSlice
, ///< [out] slice index
2188 UINT_32
* pSample
///< [out] sample index
2194 UINT_64 macroTileBits
;
2197 UINT_64 elementOffset
;
2198 UINT_64 macroTileIndex
;
2200 UINT_64 totalOffset
;
2205 UINT_32 groupBits
= m_pipeInterleaveBytes
<< 3;
2206 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2207 UINT_32 banks
= pTileInfo
->banks
;
2209 UINT_32 bankInterleave
= m_bankInterleave
;
2211 UINT_64 addrBits
= BYTES_TO_BITS(addr
) + bitPosition
;
2214 // remove bits for bank and pipe
2216 totalOffset
= (addrBits
% groupBits
) +
2217 (((addrBits
/ groupBits
/ pipes
) % bankInterleave
) * groupBits
) +
2218 (((addrBits
/ groupBits
/ pipes
) / bankInterleave
) / banks
) * groupBits
* bankInterleave
;
2220 UINT_32 microTileThickness
= ComputeSurfaceThickness(tileMode
);
2222 UINT_32 microTileBits
= bpp
* microTileThickness
* MicroTilePixels
* numSamples
;
2224 UINT_32 microTileBytes
= BITS_TO_BYTES(microTileBits
);
2226 // Determine if tiles need to be split across slices.
2228 // If the size of the micro tile is larger than the tile split size, then the tile will be
2229 // split across multiple slices.
2231 UINT_32 slicesPerTile
= 1; //_State->TileSlices
2233 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
2234 { //don't support for thick mode
2237 // Compute the number of slices per tile.
2239 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
2242 tileBits
= microTileBits
/ slicesPerTile
; // micro tile bits
2244 // in micro tiles because not MicroTileWidth timed.
2245 UINT_32 macroWidth
= pTileInfo
->bankWidth
* pipes
* pTileInfo
->macroAspectRatio
;
2246 // in micro tiles as well
2247 UINT_32 macroHeight
= pTileInfo
->bankHeight
* banks
/ pTileInfo
->macroAspectRatio
;
2249 UINT_32 pitchInMacroTiles
= pitch
/ MicroTileWidth
/ macroWidth
;
2251 macroTileBits
= (macroWidth
* macroHeight
) * tileBits
/ (banks
* pipes
);
2253 macroTileIndex
= totalOffset
/ macroTileBits
;
2255 // pitchMacros * height / heightMacros; macroTilesPerSlice == _State->SliceMacros
2256 UINT_32 macroTilesPerSlice
= (pitch
/ (macroWidth
* MicroTileWidth
)) * height
/
2257 (macroHeight
* MicroTileWidth
);
2259 slices
= static_cast<UINT_32
>(macroTileIndex
/ macroTilesPerSlice
);
2261 *pSlice
= static_cast<UINT_32
>(slices
/ slicesPerTile
* microTileThickness
);
2264 // calculate element offset and x[2:0], y[2:0], z[1:0] for thick
2266 tileSlices
= slices
% slicesPerTile
;
2268 elementOffset
= tileSlices
* tileBits
;
2269 elementOffset
+= totalOffset
% tileBits
;
2273 HwlComputePixelCoordFromOffset(static_cast<UINT_32
>(elementOffset
),
2284 isDepthSampleOrder
);
2286 macroTileIndex
= macroTileIndex
% macroTilesPerSlice
;
2287 *pY
+= static_cast<UINT_32
>(macroTileIndex
/ pitchInMacroTiles
* macroHeight
* MicroTileHeight
);
2288 *pX
+= static_cast<UINT_32
>(macroTileIndex
% pitchInMacroTiles
* macroWidth
* MicroTileWidth
);
2292 tileIndex
= static_cast<UINT_32
>((totalOffset
% macroTileBits
) / tileBits
);
2294 my
= (tileIndex
/ pTileInfo
->bankWidth
) % pTileInfo
->bankHeight
* MicroTileHeight
;
2295 mx
= (tileIndex
% pTileInfo
->bankWidth
) * pipes
* MicroTileWidth
;
2300 bank
= ComputeBankFromAddr(addr
, banks
, pipes
);
2301 pipe
= ComputePipeFromAddr(addr
, pipes
);
2303 HwlComputeSurfaceCoord2DFromBankPipe(tileMode
,
2317 ***************************************************************************************************
2318 * EgBasedAddrLib::ComputeSurfaceCoord2DFromBankPipe
2321 * Compute surface x,y coordinates from bank/pipe info
2324 ***************************************************************************************************
2326 VOID
EgBasedAddrLib::ComputeSurfaceCoord2DFromBankPipe(
2327 AddrTileMode tileMode
, ///< [in] tile mode
2328 UINT_32 x
, ///< [in] x coordinate
2329 UINT_32 y
, ///< [in] y coordinate
2330 UINT_32 slice
, ///< [in] slice index
2331 UINT_32 bank
, ///< [in] bank number
2332 UINT_32 pipe
, ///< [in] pipe number
2333 UINT_32 bankSwizzle
,///< [in] bank swizzle
2334 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
2335 UINT_32 tileSlices
, ///< [in] slices in a micro tile
2336 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure. **All fields to be valid on entry**
2337 CoordFromBankPipe
* pOutput
///< [out] pointer to extracted x/y bits
2349 UINT_32 tileSplitRotation
;
2351 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2353 UINT_32 bankRotation
= ComputeBankRotation(tileMode
,
2354 pTileInfo
->banks
, numPipes
);
2356 UINT_32 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2358 UINT_32 xBit
= x
/ (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
);
2359 UINT_32 yBit
= y
/ (MicroTileHeight
* pTileInfo
->bankHeight
);
2361 //calculate the bank and pipe before rotation and swizzle
2365 case ADDR_TM_2D_TILED_THIN1
: //fall through
2366 case ADDR_TM_2D_TILED_THICK
: //fall through
2367 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2368 case ADDR_TM_3D_TILED_THIN1
: //fall through
2369 case ADDR_TM_3D_TILED_THICK
: //fall through
2370 case ADDR_TM_3D_TILED_XTHICK
:
2371 tileSplitRotation
= ((pTileInfo
->banks
/ 2) + 1);
2374 tileSplitRotation
= 0;
2378 UINT_32 microTileThickness
= ComputeSurfaceThickness(tileMode
);
2380 bank
^= tileSplitRotation
* tileSlices
;
2381 if (pipeRotation
== 0)
2383 bank
^= bankRotation
* (slice
/ microTileThickness
) + bankSwizzle
;
2384 bank
%= pTileInfo
->banks
;
2385 pipe
^= pipeSwizzle
;
2389 bank
^= bankRotation
* (slice
/ microTileThickness
) / numPipes
+ bankSwizzle
;
2390 bank
%= pTileInfo
->banks
;
2391 pipe
^= pipeRotation
* (slice
/ microTileThickness
) + pipeSwizzle
;
2394 if (pTileInfo
->macroAspectRatio
== 1)
2396 switch (pTileInfo
->banks
)
2399 yBit3
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2402 yBit4
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2403 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2406 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2407 yBit5
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2408 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ yBit5
;
2411 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3);
2412 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2);
2413 yBit6
= _BIT(bank
, 0) ^ _BIT(xBit
, 0);
2414 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ yBit6
;
2421 else if (pTileInfo
->macroAspectRatio
== 2)
2423 switch (pTileInfo
->banks
)
2425 case 2: //xBit3 = yBit3^b0
2426 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,0);
2428 case 4: //xBit3=yBit4^b0; yBit3=xBit4^b1
2429 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2430 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2432 case 8: //xBit4, xBit5, yBit5 are known
2433 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2434 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2435 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ _BIT(yBit
, 2);
2437 case 16://x4,x5,x6,y6 are known
2438 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3); //x3 = y6 ^ b0
2439 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2440 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = x5 ^ b2
2441 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ _BIT(yBit
, 3); //y5=x4^y6^b1
2447 else if (pTileInfo
->macroAspectRatio
== 4)
2449 switch (pTileInfo
->banks
)
2451 case 4: //yBit3, yBit4
2452 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2453 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,0);
2455 case 8: //xBit5, yBit4, yBit5
2456 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2457 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2458 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
,2);
2460 case 16: //xBit5, xBit6, yBit5, yBit6
2461 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = b0 ^ y6
2462 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = b1 ^ y5 ^ y6;
2463 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = b3 ^ x6;
2464 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = b2 ^ x5;
2470 else if (pTileInfo
->macroAspectRatio
== 8)
2472 switch (pTileInfo
->banks
)
2474 case 8: //yBit3, yBit4, yBit5
2475 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2); //x3 = b0 ^ y5;
2476 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
, 2);//x4 = b1 ^ y4 ^ y5;
2477 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
,0);
2479 case 16: //xBit6, yBit4, yBit5, yBit6
2480 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = y6 ^ b0
2481 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = y5 ^ y6 ^ b1
2482 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
, 1);//x5 = y4 ^ b2
2483 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2490 pOutput
->xBits
= xBit
;
2491 pOutput
->yBits
= yBit
;
2493 pOutput
->xBit3
= xBit3
;
2494 pOutput
->xBit4
= xBit4
;
2495 pOutput
->xBit5
= xBit5
;
2496 pOutput
->yBit3
= yBit3
;
2497 pOutput
->yBit4
= yBit4
;
2498 pOutput
->yBit5
= yBit5
;
2499 pOutput
->yBit6
= yBit6
;
2503 ***************************************************************************************************
2504 * EgBasedAddrLib::HwlExtractBankPipeSwizzle
2506 * Entry of EgBasedAddrLib ExtractBankPipeSwizzle
2509 ***************************************************************************************************
2511 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlExtractBankPipeSwizzle(
2512 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
2513 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
2516 ExtractBankPipeSwizzle(pIn
->base256b
,
2519 &pOut
->pipeSwizzle
);
2526 ***************************************************************************************************
2527 * EgBasedAddrLib::HwlCombineBankPipeSwizzle
2529 * Combine bank/pipe swizzle
2532 ***************************************************************************************************
2534 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlCombineBankPipeSwizzle(
2535 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2536 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2537 ADDR_TILEINFO
* pTileInfo
, ///< [in] tile info
2538 UINT_64 baseAddr
, ///< [in] base address
2539 UINT_32
* pTileSwizzle
///< [out] combined swizzle
2542 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
2546 *pTileSwizzle
= GetBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, baseAddr
, pTileInfo
);
2550 retCode
= ADDR_INVALIDPARAMS
;
2557 ***************************************************************************************************
2558 * EgBasedAddrLib::HwlComputeBaseSwizzle
2560 * Compute base swizzle
2563 ***************************************************************************************************
2565 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeBaseSwizzle(
2566 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT
* pIn
,
2567 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
* pOut
2570 UINT_32 bankSwizzle
= 0;
2571 UINT_32 pipeSwizzle
= 0;
2572 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2574 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
2575 ADDR_ASSERT(pIn
->pTileInfo
);
2577 /// This is a legacy misreading of h/w doc, use it as it doesn't hurt.
2578 static const UINT_8 bankRotationArray
[4][16] = {
2579 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_2_BANK
2580 { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_4_BANK
2581 { 0, 3, 6, 1, 4, 7, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_8_BANK
2582 { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }, // ADDR_SURF_16_BANK
2585 UINT_32 banks
= pTileInfo
? pTileInfo
->banks
: 2;
2588 // Uses less bank swizzle bits
2589 if (pIn
->option
.reduceBankBit
&& banks
> 2)
2609 ADDR_ASSERT_ALWAYS();
2614 if (pIn
->option
.genOption
== ADDR_SWIZZLE_GEN_LINEAR
)
2616 bankSwizzle
= pIn
->surfIndex
& (banks
- 1);
2618 else // (pIn->option.genOption == ADDR_SWIZZLE_GEN_DEFAULT)
2620 bankSwizzle
= bankRotationArray
[hwNumBanks
][pIn
->surfIndex
& (banks
- 1)];
2623 if (IsMacro3dTiled(pIn
->tileMode
))
2625 pipeSwizzle
= pIn
->surfIndex
& (HwlGetPipes(pTileInfo
) - 1);
2628 return HwlCombineBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, pTileInfo
, 0, &pOut
->tileSwizzle
);
2632 ***************************************************************************************************
2633 * EgBasedAddrLib::ExtractBankPipeSwizzle
2635 * Extract bank/pipe swizzle from base256b
2638 ***************************************************************************************************
2640 VOID
EgBasedAddrLib::ExtractBankPipeSwizzle(
2641 UINT_32 base256b
, ///< [in] input base256b register value
2642 ADDR_TILEINFO
* pTileInfo
, ///< [in] 2D tile parameters. Client must provide all data
2643 UINT_32
* pBankSwizzle
, ///< [out] bank swizzle
2644 UINT_32
* pPipeSwizzle
///< [out] pipe swizzle
2647 UINT_32 bankSwizzle
= 0;
2648 UINT_32 pipeSwizzle
= 0;
2652 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2653 UINT_32 bankBits
= QLog2(pTileInfo
->banks
);
2654 UINT_32 pipeBits
= QLog2(numPipes
);
2655 UINT_32 groupBytes
= m_pipeInterleaveBytes
;
2656 UINT_32 bankInterleave
= m_bankInterleave
;
2659 (base256b
/ (groupBytes
>> 8)) & ((1<<pipeBits
)-1);
2662 (base256b
/ (groupBytes
>> 8) / numPipes
/ bankInterleave
) & ((1 << bankBits
) - 1);
2665 *pPipeSwizzle
= pipeSwizzle
;
2666 *pBankSwizzle
= bankSwizzle
;
2670 ***************************************************************************************************
2671 * EgBasedAddrLib::GetBankPipeSwizzle
2673 * Combine bank/pipe swizzle
2675 * Base256b bits (only filled bank/pipe bits)
2676 ***************************************************************************************************
2678 UINT_32
EgBasedAddrLib::GetBankPipeSwizzle(
2679 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2680 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2681 UINT_64 baseAddr
, ///< [in] base address
2682 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2685 UINT_32 pipeBits
= QLog2(HwlGetPipes(pTileInfo
));
2686 UINT_32 bankInterleaveBits
= QLog2(m_bankInterleave
);
2687 UINT_32 tileSwizzle
= pipeSwizzle
+ ((bankSwizzle
<< bankInterleaveBits
) << pipeBits
);
2689 baseAddr
^= tileSwizzle
* m_pipeInterleaveBytes
;
2692 return static_cast<UINT_32
>(baseAddr
);
2696 ***************************************************************************************************
2697 * EgBasedAddrLib::ComputeSliceTileSwizzle
2699 * Compute cubemap/3d texture faces/slices tile swizzle
2702 ***************************************************************************************************
2704 UINT_32
EgBasedAddrLib::ComputeSliceTileSwizzle(
2705 AddrTileMode tileMode
, ///< [in] Tile mode
2706 UINT_32 baseSwizzle
, ///< [in] Base swizzle
2707 UINT_32 slice
, ///< [in] Slice index, Cubemap face index, 0 means +X
2708 UINT_64 baseAddr
, ///< [in] Base address
2709 ADDR_TILEINFO
* pTileInfo
///< [in] Bank structure
2712 UINT_32 tileSwizzle
= 0;
2714 if (IsMacroTiled(tileMode
)) // Swizzle only for macro tile mode
2716 UINT_32 firstSlice
= slice
/ ComputeSurfaceThickness(tileMode
);
2718 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2719 UINT_32 numBanks
= pTileInfo
->banks
;
2721 UINT_32 pipeRotation
;
2722 UINT_32 bankRotation
;
2724 UINT_32 bankSwizzle
= 0;
2725 UINT_32 pipeSwizzle
= 0;
2727 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2728 bankRotation
= ComputeBankRotation(tileMode
, numBanks
, numPipes
);
2730 if (baseSwizzle
!= 0)
2732 ExtractBankPipeSwizzle(baseSwizzle
,
2738 if (pipeRotation
== 0) //2D mode
2740 bankSwizzle
+= firstSlice
* bankRotation
;
2741 bankSwizzle
%= numBanks
;
2745 pipeSwizzle
+= firstSlice
* pipeRotation
;
2746 pipeSwizzle
%= numPipes
;
2747 bankSwizzle
+= firstSlice
* bankRotation
/ numPipes
;
2748 bankSwizzle
%= numBanks
;
2751 tileSwizzle
= GetBankPipeSwizzle(bankSwizzle
,
2761 ***************************************************************************************************
2762 * EgBasedAddrLib::HwlComputeQbStereoRightSwizzle
2765 * Compute right eye swizzle
2768 ***************************************************************************************************
2770 UINT_32
EgBasedAddrLib::HwlComputeQbStereoRightSwizzle(
2771 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pInfo
///< [in] Surface info, must be valid
2774 UINT_32 bankBits
= 0;
2775 UINT_32 swizzle
= 0;
2777 // The assumption is default swizzle for left eye is 0
2778 if (IsMacroTiled(pInfo
->tileMode
) && pInfo
->pStereoInfo
&& pInfo
->pTileInfo
)
2780 bankBits
= ComputeBankFromCoord(0, pInfo
->height
, 0,
2781 pInfo
->tileMode
, 0, 0, pInfo
->pTileInfo
);
2785 HwlCombineBankPipeSwizzle(bankBits
, 0, pInfo
->pTileInfo
, 0, &swizzle
);
2793 ***************************************************************************************************
2794 * EgBasedAddrLib::ComputeBankFromCoord
2797 * Compute bank number from coordinates
2800 ***************************************************************************************************
2802 UINT_32
EgBasedAddrLib::ComputeBankFromCoord(
2803 UINT_32 x
, ///< [in] x coordinate
2804 UINT_32 y
, ///< [in] y coordinate
2805 UINT_32 slice
, ///< [in] slice index
2806 AddrTileMode tileMode
, ///< [in] tile mode
2807 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2808 UINT_32 tileSplitSlice
, ///< [in] If the size of the pixel offset is larger than the
2809 /// tile split size, then the pixel will be moved to a separate
2810 /// slice. This value equals pixelOffset / tileSplitBytes
2811 /// in this case. Otherwise this is 0.
2812 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2815 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2816 UINT_32 bankBit0
= 0;
2817 UINT_32 bankBit1
= 0;
2818 UINT_32 bankBit2
= 0;
2819 UINT_32 bankBit3
= 0;
2820 UINT_32 sliceRotation
;
2821 UINT_32 tileSplitRotation
;
2823 UINT_32 numBanks
= pTileInfo
->banks
;
2824 UINT_32 bankWidth
= pTileInfo
->bankWidth
;
2825 UINT_32 bankHeight
= pTileInfo
->bankHeight
;
2827 UINT_32 tx
= x
/ MicroTileWidth
/ (bankWidth
* pipes
);
2828 UINT_32 ty
= y
/ MicroTileHeight
/ bankHeight
;
2830 UINT_32 x3
= _BIT(tx
,0);
2831 UINT_32 x4
= _BIT(tx
,1);
2832 UINT_32 x5
= _BIT(tx
,2);
2833 UINT_32 x6
= _BIT(tx
,3);
2834 UINT_32 y3
= _BIT(ty
,0);
2835 UINT_32 y4
= _BIT(ty
,1);
2836 UINT_32 y5
= _BIT(ty
,2);
2837 UINT_32 y6
= _BIT(ty
,3);
2843 bankBit1
= x4
^ y5
^ y6
;
2849 bankBit1
= x4
^ y4
^ y5
;
2860 ADDR_ASSERT_ALWAYS();
2864 bank
= bankBit0
| (bankBit1
<< 1) | (bankBit2
<< 2) | (bankBit3
<< 3);
2866 //Bits2Number(4, bankBit3, bankBit2, bankBit1, bankBit0);
2868 bank
= HwlPreAdjustBank((x
/ MicroTileWidth
), bank
, pTileInfo
);
2870 // Compute bank rotation for the slice.
2872 UINT_32 microTileThickness
= ComputeSurfaceThickness(tileMode
);
2876 case ADDR_TM_2D_TILED_THIN1
: // fall through
2877 case ADDR_TM_2D_TILED_THICK
: // fall through
2878 case ADDR_TM_2D_TILED_XTHICK
:
2879 sliceRotation
= ((numBanks
/ 2) - 1) * (slice
/ microTileThickness
);
2881 case ADDR_TM_3D_TILED_THIN1
: // fall through
2882 case ADDR_TM_3D_TILED_THICK
: // fall through
2883 case ADDR_TM_3D_TILED_XTHICK
:
2885 Max(1u, (pipes
/ 2) - 1) * (slice
/ microTileThickness
) / pipes
;
2894 // Compute bank rotation for the tile split slice.
2896 // The sample slice will be non-zero if samples must be split across multiple slices.
2897 // This situation arises when the micro tile size multiplied yBit the number of samples exceeds
2898 // the split size (set in GB_ADDR_CONFIG).
2902 case ADDR_TM_2D_TILED_THIN1
: //fall through
2903 case ADDR_TM_3D_TILED_THIN1
: //fall through
2904 case ADDR_TM_PRT_2D_TILED_THIN1
: //fall through
2905 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
2906 tileSplitRotation
= ((numBanks
/ 2) + 1) * tileSplitSlice
;
2909 tileSplitRotation
= 0;
2914 // Apply bank rotation for the slice and tile split slice.
2916 bank
^= bankSwizzle
+ sliceRotation
;
2917 bank
^= tileSplitRotation
;
2919 bank
&= (numBanks
- 1);
2925 ***************************************************************************************************
2926 * EgBasedAddrLib::ComputeBankFromAddr
2929 * Compute the bank number from an address
2932 ***************************************************************************************************
2934 UINT_32
EgBasedAddrLib::ComputeBankFromAddr(
2935 UINT_64 addr
, ///< [in] address
2936 UINT_32 numBanks
, ///< [in] number of banks
2937 UINT_32 numPipes
///< [in] number of pipes
2943 // The LSBs of the address are arranged as follows:
2944 // bank | bankInterleave | pipe | pipeInterleave
2946 // To get the bank number, shift off the pipe interleave, pipe, and bank interlave bits and
2947 // mask the bank bits.
2949 bank
= static_cast<UINT_32
>(
2950 (addr
>> Log2(m_pipeInterleaveBytes
* numPipes
* m_bankInterleave
)) &
2958 ***************************************************************************************************
2959 * EgBasedAddrLib::ComputePipeRotation
2962 * Compute pipe rotation value
2965 ***************************************************************************************************
2967 UINT_32
EgBasedAddrLib::ComputePipeRotation(
2968 AddrTileMode tileMode
, ///< [in] tile mode
2969 UINT_32 numPipes
///< [in] number of pipes
2976 case ADDR_TM_3D_TILED_THIN1
: //fall through
2977 case ADDR_TM_3D_TILED_THICK
: //fall through
2978 case ADDR_TM_3D_TILED_XTHICK
: //fall through
2979 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
2980 case ADDR_TM_PRT_3D_TILED_THICK
:
2981 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1);
2993 ***************************************************************************************************
2994 * EgBasedAddrLib::ComputeBankRotation
2997 * Compute bank rotation value
3000 ***************************************************************************************************
3002 UINT_32
EgBasedAddrLib::ComputeBankRotation(
3003 AddrTileMode tileMode
, ///< [in] tile mode
3004 UINT_32 numBanks
, ///< [in] number of banks
3005 UINT_32 numPipes
///< [in] number of pipes
3012 case ADDR_TM_2D_TILED_THIN1
: // fall through
3013 case ADDR_TM_2D_TILED_THICK
: // fall through
3014 case ADDR_TM_2D_TILED_XTHICK
:
3015 case ADDR_TM_PRT_2D_TILED_THIN1
:
3016 case ADDR_TM_PRT_2D_TILED_THICK
:
3017 // Rotate banks per Z-slice yBit 1 for 4-bank or 3 for 8-bank
3018 rotation
= numBanks
/ 2 - 1;
3020 case ADDR_TM_3D_TILED_THIN1
: // fall through
3021 case ADDR_TM_3D_TILED_THICK
: // fall through
3022 case ADDR_TM_3D_TILED_XTHICK
:
3023 case ADDR_TM_PRT_3D_TILED_THIN1
:
3024 case ADDR_TM_PRT_3D_TILED_THICK
:
3025 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1); // rotate pipes & banks
3036 ***************************************************************************************************
3037 * EgBasedAddrLib::ComputeHtileBytes
3040 * Compute htile size in bytes
3043 * Htile size in bytes
3044 ***************************************************************************************************
3046 UINT_64
EgBasedAddrLib::ComputeHtileBytes(
3047 UINT_32 pitch
, ///< [in] pitch
3048 UINT_32 height
, ///< [in] height
3049 UINT_32 bpp
, ///< [in] bits per pixel
3050 BOOL_32 isLinear
, ///< [in] if it is linear mode
3051 UINT_32 numSlices
, ///< [in] number of slices
3052 UINT_64
* sliceBytes
, ///< [out] bytes per slice
3053 UINT_32 baseAlign
///< [in] base alignments
3058 const UINT_64 HtileCacheLineSize
= BITS_TO_BYTES(HtileCacheBits
);
3060 *sliceBytes
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
/ 64);
3062 if (m_configFlags
.useHtileSliceAlign
)
3064 // Align the sliceSize to htilecachelinesize * pipes at first
3065 *sliceBytes
= PowTwoAlign(*sliceBytes
, HtileCacheLineSize
* m_pipes
);
3066 surfBytes
= *sliceBytes
* numSlices
;
3070 // Align the surfSize to htilecachelinesize * pipes at last
3071 surfBytes
= *sliceBytes
* numSlices
;
3072 surfBytes
= PowTwoAlign(surfBytes
, HtileCacheLineSize
* m_pipes
);
3079 ***************************************************************************************************
3080 * EgBasedAddrLib::DispatchComputeFmaskInfo
3083 * Compute fmask sizes include padded pitch, height, slices, total size in bytes,
3084 * meanwhile output suitable tile mode and alignments as well. Results are returned
3085 * through output parameters.
3089 ***************************************************************************************************
3091 ADDR_E_RETURNCODE
EgBasedAddrLib::DispatchComputeFmaskInfo(
3092 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3093 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
) ///< [out] output structure
3095 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3097 ADDR_COMPUTE_SURFACE_INFO_INPUT surfIn
= {0};
3098 ADDR_COMPUTE_SURFACE_INFO_OUTPUT surfOut
= {0};
3100 // Setup input structure
3101 surfIn
.tileMode
= pIn
->tileMode
;
3102 surfIn
.width
= pIn
->pitch
;
3103 surfIn
.height
= pIn
->height
;
3104 surfIn
.numSlices
= pIn
->numSlices
;
3105 surfIn
.pTileInfo
= pIn
->pTileInfo
;
3106 surfIn
.tileType
= ADDR_NON_DISPLAYABLE
;
3107 surfIn
.flags
.fmask
= 1;
3109 // Setup output structure
3110 surfOut
.pTileInfo
= pOut
->pTileInfo
;
3112 // Setup hwl specific fields
3113 HwlFmaskPreThunkSurfInfo(pIn
, pOut
, &surfIn
, &surfOut
);
3115 surfIn
.bpp
= HwlComputeFmaskBits(pIn
, &surfIn
.numSamples
);
3117 // ComputeSurfaceInfo needs numSamples in surfOut as surface routines need adjusted numSamples
3118 surfOut
.numSamples
= surfIn
.numSamples
;
3120 retCode
= HwlComputeSurfaceInfo(&surfIn
, &surfOut
);
3122 // Save bpp field for surface dump support
3123 surfOut
.bpp
= surfIn
.bpp
;
3125 if (retCode
== ADDR_OK
)
3127 pOut
->bpp
= surfOut
.bpp
;
3128 pOut
->pitch
= surfOut
.pitch
;
3129 pOut
->height
= surfOut
.height
;
3130 pOut
->numSlices
= surfOut
.depth
;
3131 pOut
->fmaskBytes
= surfOut
.surfSize
;
3132 pOut
->baseAlign
= surfOut
.baseAlign
;
3133 pOut
->pitchAlign
= surfOut
.pitchAlign
;
3134 pOut
->heightAlign
= surfOut
.heightAlign
;
3136 if (surfOut
.depth
> 1)
3138 // For fmask, expNumSlices is stored in depth.
3139 pOut
->sliceSize
= surfOut
.surfSize
/ surfOut
.depth
;
3143 pOut
->sliceSize
= surfOut
.surfSize
;
3146 // Save numSamples field for surface dump support
3147 pOut
->numSamples
= surfOut
.numSamples
;
3149 HwlFmaskPostThunkSurfInfo(&surfOut
, pOut
);
3156 ***************************************************************************************************
3157 * EgBasedAddrLib::HwlFmaskSurfaceInfo
3159 * Entry of EgBasedAddrLib ComputeFmaskInfo
3162 ***************************************************************************************************
3164 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeFmaskInfo(
3165 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3166 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
3169 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3171 ADDR_TILEINFO tileInfo
= {0};
3173 // Use internal tile info if pOut does not have a valid pTileInfo
3174 if (pOut
->pTileInfo
== NULL
)
3176 pOut
->pTileInfo
= &tileInfo
;
3179 retCode
= DispatchComputeFmaskInfo(pIn
, pOut
);
3181 if (retCode
== ADDR_OK
)
3184 HwlPostCheckTileIndex(pOut
->pTileInfo
, pIn
->tileMode
, ADDR_NON_DISPLAYABLE
,
3188 // Resets pTileInfo to NULL if the internal tile info is used
3189 if (pOut
->pTileInfo
== &tileInfo
)
3191 pOut
->pTileInfo
= NULL
;
3198 ***************************************************************************************************
3199 * EgBasedAddrLib::HwlComputeFmaskAddrFromCoord
3201 * Entry of EgBasedAddrLib ComputeFmaskAddrFromCoord
3204 ***************************************************************************************************
3206 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeFmaskAddrFromCoord(
3207 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3208 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3211 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3214 if ((pIn
->x
> pIn
->pitch
) ||
3215 (pIn
->y
> pIn
->height
) ||
3216 (pIn
->numSamples
> m_maxSamples
) ||
3217 (pIn
->sample
>= m_maxSamples
))
3219 retCode
= ADDR_INVALIDPARAMS
;
3223 pOut
->addr
= DispatchComputeFmaskAddrFromCoord(pIn
, pOut
);
3231 ***************************************************************************************************
3232 * EgBasedAddrLib::HwlComputeFmaskCoordFromAddr
3234 * Entry of EgBasedAddrLib ComputeFmaskCoordFromAddr
3237 ***************************************************************************************************
3239 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeFmaskCoordFromAddr(
3240 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3241 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3244 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3247 if ((pIn
->bitPosition
>= 8) ||
3248 (pIn
->numSamples
> m_maxSamples
))
3250 retCode
= ADDR_INVALIDPARAMS
;
3254 DispatchComputeFmaskCoordFromAddr(pIn
, pOut
);
3263 ***************************************************************************************************
3264 * EgBasedAddrLib::DispatchComputeFmaskAddrFromCoord
3267 * Computes the FMASK address and bit position from a coordinate.
3270 ***************************************************************************************************
3272 UINT_64
EgBasedAddrLib::DispatchComputeFmaskAddrFromCoord(
3273 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3274 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3279 UINT_32 slice
= pIn
->slice
;
3280 UINT_32 sample
= pIn
->sample
;
3281 UINT_32 plane
= pIn
->plane
;
3282 UINT_32 pitch
= pIn
->pitch
;
3283 UINT_32 height
= pIn
->height
;
3284 UINT_32 numSamples
= pIn
->numSamples
;
3285 AddrTileMode tileMode
= pIn
->tileMode
;
3286 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
3287 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
3288 BOOL_32 resolved
= pIn
->resolved
;
3290 UINT_32
* pBitPosition
= &pOut
->bitPosition
;
3293 ADDR_ASSERT(numSamples
> 1);
3294 ADDR_ASSERT(ComputeSurfaceThickness(tileMode
) == 1);
3298 case ADDR_TM_1D_TILED_THIN1
:
3299 addr
= ComputeFmaskAddrFromCoordMicroTiled(x
,
3311 case ADDR_TM_2D_TILED_THIN1
: //fall through
3312 case ADDR_TM_3D_TILED_THIN1
:
3313 UINT_32 pipeSwizzle
;
3314 UINT_32 bankSwizzle
;
3316 if (m_configFlags
.useCombinedSwizzle
)
3318 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
3319 &bankSwizzle
, &pipeSwizzle
);
3323 pipeSwizzle
= pIn
->pipeSwizzle
;
3324 bankSwizzle
= pIn
->bankSwizzle
;
3327 addr
= ComputeFmaskAddrFromCoordMacroTiled(x
,
3352 ***************************************************************************************************
3353 * EgBasedAddrLib::ComputeFmaskAddrFromCoordMicroTiled
3356 * Computes the FMASK address and bit position from a coordinate for 1D tilied (micro
3360 ***************************************************************************************************
3362 UINT_64
EgBasedAddrLib::ComputeFmaskAddrFromCoordMicroTiled(
3363 UINT_32 x
, ///< [in] x coordinate
3364 UINT_32 y
, ///< [in] y coordinate
3365 UINT_32 slice
, ///< [in] slice index
3366 UINT_32 sample
, ///< [in] sample number
3367 UINT_32 plane
, ///< [in] plane number
3368 UINT_32 pitch
, ///< [in] surface pitch in pixels
3369 UINT_32 height
, ///< [in] surface height in pixels
3370 UINT_32 numSamples
, ///< [in] number of samples
3371 AddrTileMode tileMode
, ///< [in] tile mode
3372 BOOL_32 resolved
, ///< [in] TRUE if this is for resolved fmask
3373 UINT_32
* pBitPosition
///< [out] pointer to returned bit position
3377 UINT_32 effectiveBpp
;
3378 UINT_32 effectiveSamples
;
3381 // 2xAA use the same layout as 4xAA
3383 if (numSamples
== 2)
3389 // Compute the number of planes.
3393 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3394 effectiveBpp
= numSamples
;
3397 // Compute the address just like a color surface with numSamples bits per element and
3398 // numPlanes samples.
3400 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
3409 ADDR_NON_DISPLAYABLE
,
3414 // Compute the real bit position. Each (sample, plane) is stored with one bit per sample.
3418 // Compute the pixel index with in the micro tile
3420 UINT_32 pixelIndex
= ComputePixelIndexWithinMicroTile(x
% 8,
3425 ADDR_NON_DISPLAYABLE
);
3427 *pBitPosition
= ((pixelIndex
* numSamples
) + sample
) & (BITS_PER_BYTE
-1);
3429 UINT_64 bitAddr
= BYTES_TO_BITS(addr
) + *pBitPosition
;
3435 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3436 effectiveSamples
= 1;
3439 // Compute the address just like a color surface with numSamples bits per element and
3440 // numPlanes samples.
3442 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
3451 ADDR_NON_DISPLAYABLE
,
3460 ***************************************************************************************************
3461 * EgBasedAddrLib::ComputeFmaskAddrFromCoordMacroTiled
3464 * Computes the FMASK address and bit position from a coordinate for 2D tilied (macro
3468 ***************************************************************************************************
3470 UINT_64
EgBasedAddrLib::ComputeFmaskAddrFromCoordMacroTiled(
3471 UINT_32 x
, ///< [in] x coordinate
3472 UINT_32 y
, ///< [in] y coordinate
3473 UINT_32 slice
, ///< [in] slice index
3474 UINT_32 sample
, ///< [in] sample number
3475 UINT_32 plane
, ///< [in] plane number
3476 UINT_32 pitch
, ///< [in] surface pitch in pixels
3477 UINT_32 height
, ///< [in] surface height in pixels
3478 UINT_32 numSamples
, ///< [in] number of samples
3479 AddrTileMode tileMode
, ///< [in] tile mode
3480 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
3481 UINT_32 bankSwizzle
, ///< [in] bank swizzle
3482 BOOL_32 ignoreSE
, ///< [in] TRUE if ignore shader engine
3483 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure.**All fields to be valid on entry**
3484 BOOL_32 resolved
, ///< [in] TRUE if this is for resolved fmask
3485 UINT_32
* pBitPosition
///< [out] pointer to returned bit position
3489 UINT_32 effectiveBpp
;
3490 UINT_32 effectiveSamples
;
3493 // 2xAA use the same layout as 4xAA
3495 if (numSamples
== 2)
3501 // Compute the number of planes.
3505 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3506 effectiveBpp
= numSamples
;
3509 // Compute the address just like a color surface with numSamples bits per element and
3510 // numPlanes samples.
3512 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
3521 ADDR_NON_DISPLAYABLE
,// isdisp
3522 ignoreSE
,// ignore_shader
3523 FALSE
,// depth_sample_order
3530 // Compute the real bit position. Each (sample, plane) is stored with one bit per sample.
3535 // Compute the pixel index with in the micro tile
3537 UINT_32 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
3542 ADDR_NON_DISPLAYABLE
);
3544 *pBitPosition
= ((pixelIndex
* numSamples
) + sample
) & (BITS_PER_BYTE
-1);
3546 UINT_64 bitAddr
= BYTES_TO_BITS(addr
) + *pBitPosition
;
3553 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3554 effectiveSamples
= 1;
3557 // Compute the address just like a color surface with numSamples bits per element and
3558 // numPlanes samples.
3560 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
3569 ADDR_NON_DISPLAYABLE
,
3582 ***************************************************************************************************
3583 * EgBasedAddrLib::ComputeFmaskCoordFromAddrMicroTiled
3586 * Compute (x,y,slice,sample,plane) coordinates from fmask address
3590 ***************************************************************************************************
3592 VOID
EgBasedAddrLib::ComputeFmaskCoordFromAddrMicroTiled(
3593 UINT_64 addr
, ///< [in] byte address
3594 UINT_32 bitPosition
,///< [in] bit position
3595 UINT_32 pitch
, ///< [in] pitch in pixels
3596 UINT_32 height
, ///< [in] height in pixels
3597 UINT_32 numSamples
, ///< [in] number of samples (of color buffer)
3598 AddrTileMode tileMode
, ///< [in] tile mode
3599 BOOL_32 resolved
, ///< [in] TRUE if it is resolved fmask
3600 UINT_32
* pX
, ///< [out] X coord
3601 UINT_32
* pY
, ///< [out] Y coord
3602 UINT_32
* pSlice
, ///< [out] slice index
3603 UINT_32
* pSample
, ///< [out] sample index
3604 UINT_32
* pPlane
///< [out] plane index
3607 UINT_32 effectiveBpp
;
3608 UINT_32 effectiveSamples
;
3610 // 2xAA use the same layout as 4xAA
3611 if (numSamples
== 2)
3618 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3619 effectiveBpp
= numSamples
;
3621 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
3634 ADDR_NON_DISPLAYABLE
, // microTileType
3635 FALSE
// isDepthSampleOrder
3641 *pSample
= bitPosition
% numSamples
;
3646 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3647 effectiveSamples
= 1;
3649 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
3662 ADDR_NON_DISPLAYABLE
, // microTileType
3663 TRUE
// isDepthSampleOrder
3669 ***************************************************************************************************
3670 * EgBasedAddrLib::ComputeFmaskCoordFromAddrMacroTiled
3673 * Compute (x,y,slice,sample,plane) coordinates from
3678 ***************************************************************************************************
3680 VOID
EgBasedAddrLib::ComputeFmaskCoordFromAddrMacroTiled(
3681 UINT_64 addr
, ///< [in] byte address
3682 UINT_32 bitPosition
,///< [in] bit position
3683 UINT_32 pitch
, ///< [in] pitch in pixels
3684 UINT_32 height
, ///< [in] height in pixels
3685 UINT_32 numSamples
, ///< [in] number of samples (of color buffer)
3686 AddrTileMode tileMode
, ///< [in] tile mode
3687 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
3688 UINT_32 bankSwizzle
,///< [in] bank swizzle
3689 BOOL_32 ignoreSE
, ///< [in] TRUE if ignore shader engine
3690 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure. **All fields to be valid on entry**
3691 BOOL_32 resolved
, ///< [in] TRUE if it is resolved fmask
3692 UINT_32
* pX
, ///< [out] X coord
3693 UINT_32
* pY
, ///< [out] Y coord
3694 UINT_32
* pSlice
, ///< [out] slice index
3695 UINT_32
* pSample
, ///< [out] sample index
3696 UINT_32
* pPlane
///< [out] plane index
3699 UINT_32 effectiveBpp
;
3700 UINT_32 effectiveSamples
;
3702 // 2xAA use the same layout as 4xAA
3703 if (numSamples
== 2)
3709 // Compute the number of planes.
3713 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3714 effectiveBpp
= numSamples
;
3716 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
3725 ADDR_NON_DISPLAYABLE
,
3738 *pSample
= bitPosition
% numSamples
;
3743 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3744 effectiveSamples
= 1;
3746 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
3755 ADDR_NON_DISPLAYABLE
,
3769 ***************************************************************************************************
3770 * EgBasedAddrLib::DispatchComputeFmaskCoordFromAddr
3773 * Compute (x,y,slice,sample,plane) coordinates from
3778 ***************************************************************************************************
3780 VOID
EgBasedAddrLib::DispatchComputeFmaskCoordFromAddr(
3781 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3782 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3785 UINT_64 addr
= pIn
->addr
;
3786 UINT_32 bitPosition
= pIn
->bitPosition
;
3787 UINT_32 pitch
= pIn
->pitch
;
3788 UINT_32 height
= pIn
->height
;
3789 UINT_32 numSamples
= pIn
->numSamples
;
3790 AddrTileMode tileMode
= pIn
->tileMode
;
3791 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
3792 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
3793 BOOL_32 resolved
= pIn
->resolved
;
3795 UINT_32
* pX
= &pOut
->x
;
3796 UINT_32
* pY
= &pOut
->y
;
3797 UINT_32
* pSlice
= &pOut
->slice
;
3798 UINT_32
* pSample
= &pOut
->sample
;
3799 UINT_32
* pPlane
= &pOut
->plane
;
3803 case ADDR_TM_1D_TILED_THIN1
:
3804 ComputeFmaskCoordFromAddrMicroTiled(addr
,
3817 case ADDR_TM_2D_TILED_THIN1
://fall through
3818 case ADDR_TM_3D_TILED_THIN1
:
3819 UINT_32 pipeSwizzle
;
3820 UINT_32 bankSwizzle
;
3822 if (m_configFlags
.useCombinedSwizzle
)
3824 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
3825 &bankSwizzle
, &pipeSwizzle
);
3829 pipeSwizzle
= pIn
->pipeSwizzle
;
3830 bankSwizzle
= pIn
->bankSwizzle
;
3833 ComputeFmaskCoordFromAddrMacroTiled(addr
,
3851 ADDR_ASSERT_ALWAYS();
3859 ***************************************************************************************************
3860 * EgBasedAddrLib::ComputeFmaskNumPlanesFromNumSamples
3863 * Compute fmask number of planes from number of samples
3867 ***************************************************************************************************
3869 UINT_32
EgBasedAddrLib::ComputeFmaskNumPlanesFromNumSamples(
3870 UINT_32 numSamples
) ///< [in] number of samples
3875 // FMASK is stored such that each micro tile is composed of elements containing N bits, where
3876 // N is the number of samples. There is a micro tile for each bit in the FMASK address, and
3877 // micro tiles for each address bit, sometimes referred to as a plane, are stored sequentially.
3878 // The FMASK for a 2-sample surface looks like a general surface with 2 bits per element.
3879 // The FMASK for a 4-sample surface looks like a general surface with 4 bits per element and
3880 // 2 samples. The FMASK for an 8-sample surface looks like a general surface with 8 bits per
3881 // element and 4 samples. R6xx and R7xx only stored 3 planes for 8-sample FMASK surfaces.
3882 // This was changed for R8xx to simplify the logic in the CB.
3896 ADDR_UNHANDLED_CASE();
3904 ***************************************************************************************************
3905 * EgBasedAddrLib::ComputeFmaskResolvedBppFromNumSamples
3908 * Compute resolved fmask effective bpp based on number of samples
3912 ***************************************************************************************************
3914 UINT_32
EgBasedAddrLib::ComputeFmaskResolvedBppFromNumSamples(
3915 UINT_32 numSamples
) ///< number of samples
3920 // Resolved FMASK surfaces are generated yBit the CB and read yBit the texture unit
3921 // so that the texture unit can read compressed multi-sample color data.
3922 // These surfaces store each index value packed per element.
3923 // Each element contains at least num_samples * log2(num_samples) bits.
3924 // Resolved FMASK surfaces are addressed as follows:
3925 // 2-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3926 // 4-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3927 // 8-sample Addressed similarly to a color surface with 32 bits per element and 1 sample.
3941 ADDR_UNHANDLED_CASE();
3949 ***************************************************************************************************
3950 * EgBasedAddrLib::IsTileInfoAllZero
3953 * Return TRUE if all field are zero
3955 * Since NULL input is consider to be all zero
3956 ***************************************************************************************************
3958 BOOL_32
EgBasedAddrLib::IsTileInfoAllZero(
3959 ADDR_TILEINFO
* pTileInfo
)
3961 BOOL_32 allZero
= TRUE
;
3965 if ((pTileInfo
->banks
!= 0) ||
3966 (pTileInfo
->bankWidth
!= 0) ||
3967 (pTileInfo
->bankHeight
!= 0) ||
3968 (pTileInfo
->macroAspectRatio
!= 0) ||
3969 (pTileInfo
->tileSplitBytes
!= 0) ||
3970 (pTileInfo
->pipeConfig
!= 0)
3981 ***************************************************************************************************
3982 * EgBasedAddrLib::HwlTileInfoEqual
3985 * Return TRUE if all field are equal
3987 * Only takes care of current HWL's data
3988 ***************************************************************************************************
3990 BOOL_32
EgBasedAddrLib::HwlTileInfoEqual(
3991 const ADDR_TILEINFO
* pLeft
, ///<[in] Left compare operand
3992 const ADDR_TILEINFO
* pRight
///<[in] Right compare operand
3995 BOOL_32 equal
= FALSE
;
3997 if (pLeft
->banks
== pRight
->banks
&&
3998 pLeft
->bankWidth
== pRight
->bankWidth
&&
3999 pLeft
->bankHeight
== pRight
->bankHeight
&&
4000 pLeft
->macroAspectRatio
== pRight
->macroAspectRatio
&&
4001 pLeft
->tileSplitBytes
== pRight
->tileSplitBytes
)
4010 ***************************************************************************************************
4011 * EgBasedAddrLib::HwlConvertTileInfoToHW
4013 * Entry of EgBasedAddrLib ConvertTileInfoToHW
4016 ***************************************************************************************************
4018 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlConvertTileInfoToHW(
4019 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
4020 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
4023 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4025 ADDR_TILEINFO
*pTileInfoIn
= pIn
->pTileInfo
;
4026 ADDR_TILEINFO
*pTileInfoOut
= pOut
->pTileInfo
;
4028 if ((pTileInfoIn
!= NULL
) && (pTileInfoOut
!= NULL
))
4030 if (pIn
->reverse
== FALSE
)
4032 switch (pTileInfoIn
->banks
)
4035 pTileInfoOut
->banks
= 0;
4038 pTileInfoOut
->banks
= 1;
4041 pTileInfoOut
->banks
= 2;
4044 pTileInfoOut
->banks
= 3;
4047 ADDR_ASSERT_ALWAYS();
4048 retCode
= ADDR_INVALIDPARAMS
;
4049 pTileInfoOut
->banks
= 0;
4053 switch (pTileInfoIn
->bankWidth
)
4056 pTileInfoOut
->bankWidth
= 0;
4059 pTileInfoOut
->bankWidth
= 1;
4062 pTileInfoOut
->bankWidth
= 2;
4065 pTileInfoOut
->bankWidth
= 3;
4068 ADDR_ASSERT_ALWAYS();
4069 retCode
= ADDR_INVALIDPARAMS
;
4070 pTileInfoOut
->bankWidth
= 0;
4074 switch (pTileInfoIn
->bankHeight
)
4077 pTileInfoOut
->bankHeight
= 0;
4080 pTileInfoOut
->bankHeight
= 1;
4083 pTileInfoOut
->bankHeight
= 2;
4086 pTileInfoOut
->bankHeight
= 3;
4089 ADDR_ASSERT_ALWAYS();
4090 retCode
= ADDR_INVALIDPARAMS
;
4091 pTileInfoOut
->bankHeight
= 0;
4095 switch (pTileInfoIn
->macroAspectRatio
)
4098 pTileInfoOut
->macroAspectRatio
= 0;
4101 pTileInfoOut
->macroAspectRatio
= 1;
4104 pTileInfoOut
->macroAspectRatio
= 2;
4107 pTileInfoOut
->macroAspectRatio
= 3;
4110 ADDR_ASSERT_ALWAYS();
4111 retCode
= ADDR_INVALIDPARAMS
;
4112 pTileInfoOut
->macroAspectRatio
= 0;
4116 switch (pTileInfoIn
->tileSplitBytes
)
4119 pTileInfoOut
->tileSplitBytes
= 0;
4122 pTileInfoOut
->tileSplitBytes
= 1;
4125 pTileInfoOut
->tileSplitBytes
= 2;
4128 pTileInfoOut
->tileSplitBytes
= 3;
4131 pTileInfoOut
->tileSplitBytes
= 4;
4134 pTileInfoOut
->tileSplitBytes
= 5;
4137 pTileInfoOut
->tileSplitBytes
= 6;
4140 ADDR_ASSERT_ALWAYS();
4141 retCode
= ADDR_INVALIDPARAMS
;
4142 pTileInfoOut
->tileSplitBytes
= 0;
4148 switch (pTileInfoIn
->banks
)
4151 pTileInfoOut
->banks
= 2;
4154 pTileInfoOut
->banks
= 4;
4157 pTileInfoOut
->banks
= 8;
4160 pTileInfoOut
->banks
= 16;
4163 ADDR_ASSERT_ALWAYS();
4164 retCode
= ADDR_INVALIDPARAMS
;
4165 pTileInfoOut
->banks
= 2;
4169 switch (pTileInfoIn
->bankWidth
)
4172 pTileInfoOut
->bankWidth
= 1;
4175 pTileInfoOut
->bankWidth
= 2;
4178 pTileInfoOut
->bankWidth
= 4;
4181 pTileInfoOut
->bankWidth
= 8;
4184 ADDR_ASSERT_ALWAYS();
4185 retCode
= ADDR_INVALIDPARAMS
;
4186 pTileInfoOut
->bankWidth
= 1;
4190 switch (pTileInfoIn
->bankHeight
)
4193 pTileInfoOut
->bankHeight
= 1;
4196 pTileInfoOut
->bankHeight
= 2;
4199 pTileInfoOut
->bankHeight
= 4;
4202 pTileInfoOut
->bankHeight
= 8;
4205 ADDR_ASSERT_ALWAYS();
4206 retCode
= ADDR_INVALIDPARAMS
;
4207 pTileInfoOut
->bankHeight
= 1;
4211 switch (pTileInfoIn
->macroAspectRatio
)
4214 pTileInfoOut
->macroAspectRatio
= 1;
4217 pTileInfoOut
->macroAspectRatio
= 2;
4220 pTileInfoOut
->macroAspectRatio
= 4;
4223 pTileInfoOut
->macroAspectRatio
= 8;
4226 ADDR_ASSERT_ALWAYS();
4227 retCode
= ADDR_INVALIDPARAMS
;
4228 pTileInfoOut
->macroAspectRatio
= 1;
4232 switch (pTileInfoIn
->tileSplitBytes
)
4235 pTileInfoOut
->tileSplitBytes
= 64;
4238 pTileInfoOut
->tileSplitBytes
= 128;
4241 pTileInfoOut
->tileSplitBytes
= 256;
4244 pTileInfoOut
->tileSplitBytes
= 512;
4247 pTileInfoOut
->tileSplitBytes
= 1024;
4250 pTileInfoOut
->tileSplitBytes
= 2048;
4253 pTileInfoOut
->tileSplitBytes
= 4096;
4256 ADDR_ASSERT_ALWAYS();
4257 retCode
= ADDR_INVALIDPARAMS
;
4258 pTileInfoOut
->tileSplitBytes
= 64;
4263 if (pTileInfoIn
!= pTileInfoOut
)
4265 pTileInfoOut
->pipeConfig
= pTileInfoIn
->pipeConfig
;
4270 ADDR_ASSERT_ALWAYS();
4271 retCode
= ADDR_INVALIDPARAMS
;
4278 ***************************************************************************************************
4279 * EgBasedAddrLib::HwlComputeSurfaceInfo
4281 * Entry of EgBasedAddrLib ComputeSurfaceInfo
4284 ***************************************************************************************************
4286 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeSurfaceInfo(
4287 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
4288 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
4291 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4293 if (pIn
->numSamples
< pIn
->numFrags
)
4295 retCode
= ADDR_INVALIDPARAMS
;
4298 ADDR_TILEINFO tileInfo
= {0};
4300 if (retCode
== ADDR_OK
)
4302 // Uses internal tile info if pOut does not have a valid pTileInfo
4303 if (pOut
->pTileInfo
== NULL
)
4305 pOut
->pTileInfo
= &tileInfo
;
4308 if (!DispatchComputeSurfaceInfo(pIn
, pOut
))
4310 retCode
= ADDR_INVALIDPARAMS
;
4314 pOut
->tileIndex
= HwlPostCheckTileIndex(pOut
->pTileInfo
,
4319 if (IsMacroTiled(pOut
->tileMode
) && (pOut
->macroModeIndex
== TileIndexInvalid
))
4321 pOut
->macroModeIndex
= HwlComputeMacroModeIndex(pOut
->tileIndex
,
4328 // Resets pTileInfo to NULL if the internal tile info is used
4329 if (pOut
->pTileInfo
== &tileInfo
)
4332 // Client does not pass in a valid pTileInfo
4333 if (IsMacroTiled(pOut
->tileMode
))
4335 // If a valid index is returned, then no pTileInfo is okay
4336 ADDR_ASSERT(!m_configFlags
.useTileIndex
|| pOut
->tileIndex
!= TileIndexInvalid
);
4338 if (!IsTileInfoAllZero(pIn
->pTileInfo
))
4340 // The initial value of pIn->pTileInfo is copied to tileInfo
4341 // We do not expect any of these value to be changed nor any 0 of inputs
4342 ADDR_ASSERT(tileInfo
.banks
== pIn
->pTileInfo
->banks
);
4343 ADDR_ASSERT(tileInfo
.bankWidth
== pIn
->pTileInfo
->bankWidth
);
4344 ADDR_ASSERT(tileInfo
.bankHeight
== pIn
->pTileInfo
->bankHeight
);
4345 ADDR_ASSERT(tileInfo
.macroAspectRatio
== pIn
->pTileInfo
->macroAspectRatio
);
4346 ADDR_ASSERT(tileInfo
.tileSplitBytes
== pIn
->pTileInfo
->tileSplitBytes
);
4350 pOut
->pTileInfo
= NULL
;
4358 ***************************************************************************************************
4359 * EgBasedAddrLib::HwlComputeSurfaceAddrFromCoord
4361 * Entry of EgBasedAddrLib ComputeSurfaceAddrFromCoord
4364 ***************************************************************************************************
4366 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeSurfaceAddrFromCoord(
4367 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
4368 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
4371 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4374 #if !ALT_TEST // Overflow test needs this out-of-boundary coord
4375 (pIn
->x
> pIn
->pitch
) ||
4376 (pIn
->y
> pIn
->height
) ||
4378 (pIn
->numSamples
> m_maxSamples
))
4380 retCode
= ADDR_INVALIDPARAMS
;
4384 pOut
->addr
= DispatchComputeSurfaceAddrFromCoord(pIn
, pOut
);
4391 ***************************************************************************************************
4392 * EgBasedAddrLib::HwlComputeSurfaceCoordFromAddr
4394 * Entry of EgBasedAddrLib ComputeSurfaceCoordFromAddr
4397 ***************************************************************************************************
4399 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeSurfaceCoordFromAddr(
4400 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
4401 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
4404 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4406 if ((pIn
->bitPosition
>= 8) ||
4407 (pIn
->numSamples
> m_maxSamples
))
4409 retCode
= ADDR_INVALIDPARAMS
;
4413 DispatchComputeSurfaceCoordFromAddr(pIn
, pOut
);
4419 ***************************************************************************************************
4420 * EgBasedAddrLib::HwlComputeSliceTileSwizzle
4422 * Entry of EgBasedAddrLib ComputeSurfaceCoordFromAddr
4425 ***************************************************************************************************
4427 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeSliceTileSwizzle(
4428 const ADDR_COMPUTE_SLICESWIZZLE_INPUT
* pIn
, ///< [in] input structure
4429 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
* pOut
///< [out] output structure
4432 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4434 if (pIn
->pTileInfo
&& (pIn
->pTileInfo
->banks
> 0))
4437 pOut
->tileSwizzle
= ComputeSliceTileSwizzle(pIn
->tileMode
,
4445 retCode
= ADDR_INVALIDPARAMS
;
4452 ***************************************************************************************************
4453 * EgBasedAddrLib::HwlComputeHtileBpp
4460 ***************************************************************************************************
4462 UINT_32
EgBasedAddrLib::HwlComputeHtileBpp(
4463 BOOL_32 isWidth8
, ///< [in] TRUE if block width is 8
4464 BOOL_32 isHeight8
///< [in] TRUE if block height is 8
4467 // only support 8x8 mode
4468 ADDR_ASSERT(isWidth8
&& isHeight8
);
4473 ***************************************************************************************************
4474 * EgBasedAddrLib::HwlComputeHtileBaseAlign
4477 * Compute htile base alignment
4480 * Htile base alignment
4481 ***************************************************************************************************
4483 UINT_32
EgBasedAddrLib::HwlComputeHtileBaseAlign(
4484 BOOL_32 isTcCompatible
, ///< [in] if TC compatible
4485 BOOL_32 isLinear
, ///< [in] if it is linear mode
4486 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
4489 UINT_32 baseAlign
= m_pipeInterleaveBytes
* HwlGetPipes(pTileInfo
);
4493 ADDR_ASSERT(pTileInfo
!= NULL
);
4496 baseAlign
*= pTileInfo
->banks
;
4504 ***************************************************************************************************
4505 * EgBasedAddrLib::HwlGetPitchAlignmentMicroTiled
4508 * Compute 1D tiled surface pitch alignment, calculation results are returned through
4509 * output parameters.
4513 ***************************************************************************************************
4515 UINT_32
EgBasedAddrLib::HwlGetPitchAlignmentMicroTiled(
4516 AddrTileMode tileMode
, ///< [in] tile mode
4517 UINT_32 bpp
, ///< [in] bits per pixel
4518 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4519 UINT_32 numSamples
///< [in] number of samples
4524 UINT_32 microTileThickness
= ComputeSurfaceThickness(tileMode
);
4526 UINT_32 pixelsPerMicroTile
;
4527 UINT_32 pixelsPerPipeInterleave
;
4528 UINT_32 microTilesPerPipeInterleave
;
4531 // Special workaround for depth/stencil buffer, use 8 bpp to meet larger requirement for
4532 // stencil buffer since pitch alignment is related to bpp.
4533 // For a depth only buffer do not set this.
4535 // Note: this actually does not work for mipmap but mipmap depth texture is not really
4536 // sampled with mipmap.
4538 if (flags
.depth
&& !flags
.noStencil
)
4543 pixelsPerMicroTile
= MicroTilePixels
* microTileThickness
;
4544 pixelsPerPipeInterleave
= BYTES_TO_BITS(m_pipeInterleaveBytes
) / (bpp
* numSamples
);
4545 microTilesPerPipeInterleave
= pixelsPerPipeInterleave
/ pixelsPerMicroTile
;
4547 pitchAlign
= Max(MicroTileWidth
, microTilesPerPipeInterleave
* MicroTileWidth
);
4553 ***************************************************************************************************
4554 * EgBasedAddrLib::HwlGetSizeAdjustmentMicroTiled
4557 * Adjust 1D tiled surface pitch and slice size
4560 * Logical slice size in bytes
4561 ***************************************************************************************************
4563 UINT_64
EgBasedAddrLib::HwlGetSizeAdjustmentMicroTiled(
4564 UINT_32 thickness
, ///< [in] thickness
4565 UINT_32 bpp
, ///< [in] bits per pixel
4566 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4567 UINT_32 numSamples
, ///< [in] number of samples
4568 UINT_32 baseAlign
, ///< [in] base alignment
4569 UINT_32 pitchAlign
, ///< [in] pitch alignment
4570 UINT_32
* pPitch
, ///< [in/out] pointer to pitch
4571 UINT_32
* pHeight
///< [in/out] pointer to height
4574 UINT_64 logicalSliceSize
;
4575 UINT_64 physicalSliceSize
;
4577 UINT_32 pitch
= *pPitch
;
4578 UINT_32 height
= *pHeight
;
4580 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
4581 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
4583 // Physical slice: multiplied by thickness
4584 physicalSliceSize
= logicalSliceSize
* thickness
;
4587 // R800 will always pad physical slice size to baseAlign which is pipe_interleave_bytes
4589 ADDR_ASSERT((physicalSliceSize
% baseAlign
) == 0)
4591 return logicalSliceSize
;