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
)
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
);
1171 ***************************************************************************************************
1172 * EgBasedAddrLib::HwlDegradeThickTileMode
1175 * Degrades valid tile mode for thick modes if needed
1178 * Suitable tile mode
1179 ***************************************************************************************************
1181 AddrTileMode
EgBasedAddrLib::HwlDegradeThickTileMode(
1182 AddrTileMode baseTileMode
, ///< [in] base tile mode
1183 UINT_32 numSlices
, ///< [in] current number of slices
1184 UINT_32
* pBytesPerTile
///< [in/out] pointer to bytes per slice
1187 ADDR_ASSERT(numSlices
< ComputeSurfaceThickness(baseTileMode
));
1188 // if pBytesPerTile is NULL, this is a don't-care....
1189 UINT_32 bytesPerTile
= pBytesPerTile
!= NULL
? *pBytesPerTile
: 64;
1191 AddrTileMode expTileMode
= baseTileMode
;
1192 switch (baseTileMode
)
1194 case ADDR_TM_1D_TILED_THICK
:
1195 expTileMode
= ADDR_TM_1D_TILED_THIN1
;
1198 case ADDR_TM_2D_TILED_THICK
:
1199 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1202 case ADDR_TM_3D_TILED_THICK
:
1203 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1206 case ADDR_TM_2D_TILED_XTHICK
:
1207 if (numSlices
< ThickTileThickness
)
1209 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1214 expTileMode
= ADDR_TM_2D_TILED_THICK
;
1218 case ADDR_TM_3D_TILED_XTHICK
:
1219 if (numSlices
< ThickTileThickness
)
1221 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1226 expTileMode
= ADDR_TM_3D_TILED_THICK
;
1231 ADDR_ASSERT_ALWAYS();
1235 if (pBytesPerTile
!= NULL
)
1237 *pBytesPerTile
= bytesPerTile
;
1244 ***************************************************************************************************
1245 * EgBasedAddrLib::DispatchComputeSurfaceAddrFromCoord
1248 * Compute surface address from given coord (x, y, slice,sample)
1252 ***************************************************************************************************
1254 UINT_64
EgBasedAddrLib::DispatchComputeSurfaceAddrFromCoord(
1255 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1256 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1261 UINT_32 slice
= pIn
->slice
;
1262 UINT_32 sample
= pIn
->sample
;
1263 UINT_32 bpp
= pIn
->bpp
;
1264 UINT_32 pitch
= pIn
->pitch
;
1265 UINT_32 height
= pIn
->height
;
1266 UINT_32 numSlices
= pIn
->numSlices
;
1267 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
1268 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
1269 AddrTileMode tileMode
= pIn
->tileMode
;
1270 AddrTileType microTileType
= pIn
->tileType
;
1271 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
1272 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
1273 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
1275 UINT_32
* pBitPosition
= &pOut
->bitPosition
;
1279 UINT_32 addr5Bit
= 0;
1280 UINT_32 addr5Swizzle
= pIn
->addr5Swizzle
;
1281 BOOL_32 is32ByteTile
= pIn
->is32ByteTile
;
1284 // ADDR_DEPTH_SAMPLE_ORDER = non-disp + depth-sample-order
1285 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
1287 isDepthSampleOrder
= TRUE
;
1290 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
1292 if (numFrags
!= numSamples
)
1294 numSamples
= numFrags
;
1295 ADDR_ASSERT(sample
< numSamples
);
1299 /// 128 bit/thick tiled surface doesn't support display tiling and
1300 /// mipmap chain must have the same tileType, so please fill tileType correctly
1301 if (!IsLinear(pIn
->tileMode
))
1303 if (bpp
>= 128 || ComputeSurfaceThickness(tileMode
) > 1)
1305 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
1312 case ADDR_TM_LINEAR_GENERAL
://fall through
1313 case ADDR_TM_LINEAR_ALIGNED
:
1314 addr
= ComputeSurfaceAddrFromCoordLinear(x
,
1324 case ADDR_TM_1D_TILED_THIN1
://fall through
1325 case ADDR_TM_1D_TILED_THICK
:
1326 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
1339 case ADDR_TM_2D_TILED_THIN1
: //fall through
1340 case ADDR_TM_2D_TILED_THICK
: //fall through
1341 case ADDR_TM_3D_TILED_THIN1
: //fall through
1342 case ADDR_TM_3D_TILED_THICK
: //fall through
1343 case ADDR_TM_2D_TILED_XTHICK
: //fall through
1344 case ADDR_TM_3D_TILED_XTHICK
: //fall through
1345 case ADDR_TM_PRT_TILED_THIN1
: //fall through
1346 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
1347 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
1348 case ADDR_TM_PRT_TILED_THICK
: //fall through
1349 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
1350 case ADDR_TM_PRT_3D_TILED_THICK
:
1351 UINT_32 pipeSwizzle
;
1352 UINT_32 bankSwizzle
;
1354 if (m_configFlags
.useCombinedSwizzle
)
1356 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
1357 &bankSwizzle
, &pipeSwizzle
);
1361 pipeSwizzle
= pIn
->pipeSwizzle
;
1362 bankSwizzle
= pIn
->bankSwizzle
;
1365 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
1384 ADDR_ASSERT_ALWAYS();
1389 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
1391 if (addr5Swizzle
&& isDepthSampleOrder
&& is32ByteTile
)
1393 UINT_32 tx
= x
>> 3;
1394 UINT_32 ty
= y
>> 3;
1395 UINT_32 tileBits
= ((ty
&0x3) << 2) | (tx
&0x3);
1397 tileBits
= tileBits
& addr5Swizzle
;
1398 addr5Bit
= XorReduce(tileBits
, 4);
1400 addr
= addr
| static_cast<UINT_64
>(addr5Bit
<< 5);
1409 ***************************************************************************************************
1410 * EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled
1413 * Computes the surface address and bit position from a
1414 * coordinate for 2D tilied (macro tiled)
1417 ***************************************************************************************************
1419 UINT_64
EgBasedAddrLib::ComputeSurfaceAddrFromCoordMacroTiled(
1420 UINT_32 x
, ///< [in] x coordinate
1421 UINT_32 y
, ///< [in] y coordinate
1422 UINT_32 slice
, ///< [in] slice index
1423 UINT_32 sample
, ///< [in] sample index
1424 UINT_32 bpp
, ///< [in] bits per pixel
1425 UINT_32 pitch
, ///< [in] surface pitch, in pixels
1426 UINT_32 height
, ///< [in] surface height, in pixels
1427 UINT_32 numSamples
, ///< [in] number of samples
1428 AddrTileMode tileMode
, ///< [in] tile mode
1429 AddrTileType microTileType
, ///< [in] micro tiling type
1430 BOOL_32 ignoreSE
, ///< [in] TRUE if shader enginers can be ignored
1431 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if it depth sample ordering is used
1432 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
1433 UINT_32 bankSwizzle
, ///< [in] bank swizzle
1434 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure
1435 /// **All fields to be valid on entry**
1436 UINT_32
* pBitPosition
///< [out] bit position, e.g. FMT_1 will use this
1441 UINT_32 microTileBytes
;
1442 UINT_32 microTileBits
;
1443 UINT_32 sampleOffset
;
1445 UINT_32 pixelOffset
;
1446 UINT_32 elementOffset
;
1447 UINT_32 tileSplitSlice
;
1451 UINT_64 sliceOffset
;
1452 UINT_32 macroTilePitch
;
1453 UINT_32 macroTileHeight
;
1454 UINT_32 macroTilesPerRow
;
1455 UINT_32 macroTilesPerSlice
;
1456 UINT_64 macroTileBytes
;
1457 UINT_32 macroTileIndexX
;
1458 UINT_32 macroTileIndexY
;
1459 UINT_64 macroTileOffset
;
1460 UINT_64 totalOffset
;
1461 UINT_64 pipeInterleaveMask
;
1462 UINT_64 bankInterleaveMask
;
1463 UINT_64 pipeInterleaveOffset
;
1464 UINT_32 bankInterleaveOffset
;
1466 UINT_32 tileRowIndex
;
1467 UINT_32 tileColumnIndex
;
1471 UINT_32 microTileThickness
= ComputeSurfaceThickness(tileMode
);
1474 // Compute the number of group, pipe, and bank bits.
1476 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1477 UINT_32 numPipeInterleaveBits
= Log2(m_pipeInterleaveBytes
);
1478 UINT_32 numPipeBits
= Log2(numPipes
);
1479 UINT_32 numBankInterleaveBits
= Log2(m_bankInterleave
);
1480 UINT_32 numBankBits
= Log2(pTileInfo
->banks
);
1483 // Compute the micro tile size.
1485 microTileBits
= MicroTilePixels
* microTileThickness
* bpp
* numSamples
;
1487 microTileBytes
= microTileBits
/ 8;
1489 // Compute the pixel index within the micro tile.
1491 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
1499 // Compute the sample offset and pixel offset.
1501 if (isDepthSampleOrder
)
1504 // For depth surfaces, samples are stored contiguously for each element, so the sample
1505 // offset is the sample number times the element size.
1507 sampleOffset
= sample
* bpp
;
1508 pixelOffset
= pixelIndex
* bpp
* numSamples
;
1513 // For color surfaces, all elements for a particular sample are stored contiguously, so
1514 // the sample offset is the sample number times the micro tile size divided yBit the number
1517 sampleOffset
= sample
* (microTileBits
/ numSamples
);
1518 pixelOffset
= pixelIndex
* bpp
;
1522 // Compute the element offset.
1524 elementOffset
= pixelOffset
+ sampleOffset
;
1526 *pBitPosition
= static_cast<UINT_32
>(elementOffset
% 8);
1528 elementOffset
/= 8; //bit-to-byte
1531 // Determine if tiles need to be split across slices.
1533 // If the size of the micro tile is larger than the tile split size, then the tile will be
1534 // split across multiple slices.
1536 UINT_32 slicesPerTile
= 1;
1538 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
1539 { //don't support for thick mode
1542 // Compute the number of slices per tile.
1544 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
1547 // Compute the tile split slice number for use in rotating the bank.
1549 tileSplitSlice
= elementOffset
/ pTileInfo
->tileSplitBytes
;
1552 // Adjust the element offset to account for the portion of the tile that is being moved to
1555 elementOffset
%= pTileInfo
->tileSplitBytes
;
1558 // Adjust the microTileBytes size to tileSplitBytes size since
1561 microTileBytes
= pTileInfo
->tileSplitBytes
;
1569 // Compute macro tile pitch and height.
1572 (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
) * pTileInfo
->macroAspectRatio
;
1574 (MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
) / pTileInfo
->macroAspectRatio
;
1577 // Compute the number of bytes per macro tile. Note: bytes of the same bank/pipe actually
1580 static_cast<UINT_64
>(microTileBytes
) *
1581 (macroTilePitch
/ MicroTileWidth
) * (macroTileHeight
/ MicroTileHeight
) /
1582 (numPipes
* pTileInfo
->banks
);
1585 // Compute the number of macro tiles per row.
1587 macroTilesPerRow
= pitch
/ macroTilePitch
;
1590 // Compute the offset to the macro tile containing the specified coordinate.
1592 macroTileIndexX
= x
/ macroTilePitch
;
1593 macroTileIndexY
= y
/ macroTileHeight
;
1594 macroTileOffset
= ((macroTileIndexY
* macroTilesPerRow
) + macroTileIndexX
) * macroTileBytes
;
1597 // Compute the number of macro tiles per slice.
1599 macroTilesPerSlice
= macroTilesPerRow
* (height
/ macroTileHeight
);
1602 // Compute the slice size.
1604 sliceBytes
= macroTilesPerSlice
* macroTileBytes
;
1607 // Compute the slice offset.
1609 sliceOffset
= sliceBytes
* (tileSplitSlice
+ slicesPerTile
* (slice
/ microTileThickness
));
1612 // Compute tile offest
1614 tileRowIndex
= (y
/ MicroTileHeight
) % pTileInfo
->bankHeight
;
1615 tileColumnIndex
= ((x
/ MicroTileWidth
) / numPipes
) % pTileInfo
->bankWidth
;
1616 tileIndex
= (tileRowIndex
* pTileInfo
->bankWidth
) + tileColumnIndex
;
1617 tileOffset
= tileIndex
* microTileBytes
;
1620 // Combine the slice offset and macro tile offset with the pixel and sample offsets, accounting
1621 // for the pipe and bank bits in the middle of the address.
1623 totalOffset
= sliceOffset
+ macroTileOffset
+ elementOffset
+ tileOffset
;
1626 // Get the pipe and bank.
1629 // when the tileMode is PRT type, then adjust x and y coordinates
1630 if (IsPrtNoRotationTileMode(tileMode
))
1632 x
= x
% macroTilePitch
;
1633 y
= y
% macroTileHeight
;
1636 pipe
= ComputePipeFromCoord(x
,
1644 bank
= ComputeBankFromCoord(x
,
1654 // Split the offset to put some bits below the pipe+bank bits and some above.
1656 pipeInterleaveMask
= (1 << numPipeInterleaveBits
) - 1;
1657 bankInterleaveMask
= (1 << numBankInterleaveBits
) - 1;
1658 pipeInterleaveOffset
= totalOffset
& pipeInterleaveMask
;
1659 bankInterleaveOffset
= static_cast<UINT_32
>((totalOffset
>> numPipeInterleaveBits
) &
1660 bankInterleaveMask
);
1661 offset
= totalOffset
>> (numPipeInterleaveBits
+ numBankInterleaveBits
);
1664 // Assemble the address from its components.
1666 addr
= pipeInterleaveOffset
;
1667 // This is to remove /analyze warnings
1668 UINT_32 pipeBits
= pipe
<< numPipeInterleaveBits
;
1669 UINT_32 bankInterleaveBits
= bankInterleaveOffset
<< (numPipeInterleaveBits
+ numPipeBits
);
1670 UINT_32 bankBits
= bank
<< (numPipeInterleaveBits
+ numPipeBits
+
1671 numBankInterleaveBits
);
1672 UINT_64 offsetBits
= offset
<< (numPipeInterleaveBits
+ numPipeBits
+
1673 numBankInterleaveBits
+ numBankBits
);
1676 addr
|= bankInterleaveBits
;
1684 ***************************************************************************************************
1685 * EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled
1688 * Computes the surface address and bit position from a coordinate for 1D tilied
1692 ***************************************************************************************************
1694 UINT_64
EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled(
1695 UINT_32 x
, ///< [in] x coordinate
1696 UINT_32 y
, ///< [in] y coordinate
1697 UINT_32 slice
, ///< [in] slice index
1698 UINT_32 sample
, ///< [in] sample index
1699 UINT_32 bpp
, ///< [in] bits per pixel
1700 UINT_32 pitch
, ///< [in] pitch, in pixels
1701 UINT_32 height
, ///< [in] height, in pixels
1702 UINT_32 numSamples
, ///< [in] number of samples
1703 AddrTileMode tileMode
, ///< [in] tile mode
1704 AddrTileType microTileType
, ///< [in] micro tiling type
1705 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if depth sample ordering is used
1706 UINT_32
* pBitPosition
///< [out] bit position, e.g. FMT_1 will use this
1711 UINT_32 microTileBytes
;
1713 UINT_32 microTilesPerRow
;
1714 UINT_32 microTileIndexX
;
1715 UINT_32 microTileIndexY
;
1716 UINT_32 microTileIndexZ
;
1717 UINT_64 sliceOffset
;
1718 UINT_64 microTileOffset
;
1719 UINT_32 sampleOffset
;
1721 UINT_32 pixelOffset
;
1723 UINT_32 microTileThickness
= ComputeSurfaceThickness(tileMode
);
1726 // Compute the micro tile size.
1728 microTileBytes
= BITS_TO_BYTES(MicroTilePixels
* microTileThickness
* bpp
* numSamples
);
1731 // Compute the slice size.
1734 BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* microTileThickness
* bpp
* numSamples
);
1737 // Compute the number of micro tiles per row.
1739 microTilesPerRow
= pitch
/ MicroTileWidth
;
1742 // Compute the micro tile index.
1744 microTileIndexX
= x
/ MicroTileWidth
;
1745 microTileIndexY
= y
/ MicroTileHeight
;
1746 microTileIndexZ
= slice
/ microTileThickness
;
1749 // Compute the slice offset.
1751 sliceOffset
= static_cast<UINT_64
>(microTileIndexZ
) * sliceBytes
;
1754 // Compute the offset to the micro tile containing the specified coordinate.
1756 microTileOffset
= (static_cast<UINT_64
>(microTileIndexY
) * microTilesPerRow
+ microTileIndexX
) *
1760 // Compute the pixel index within the micro tile.
1762 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
1769 // Compute the sample offset.
1771 if (isDepthSampleOrder
)
1774 // For depth surfaces, samples are stored contiguously for each element, so the sample
1775 // offset is the sample number times the element size.
1777 sampleOffset
= sample
* bpp
;
1778 pixelOffset
= pixelIndex
* bpp
* numSamples
;
1783 // For color surfaces, all elements for a particular sample are stored contiguously, so
1784 // the sample offset is the sample number times the micro tile size divided yBit the number
1787 sampleOffset
= sample
* (microTileBytes
*8 / numSamples
);
1788 pixelOffset
= pixelIndex
* bpp
;
1792 // Compute the bit position of the pixel. Each element is stored with one bit per sample.
1795 UINT_32 elemOffset
= sampleOffset
+ pixelOffset
;
1797 *pBitPosition
= elemOffset
% 8;
1801 // Combine the slice offset, micro tile offset, sample offset, and pixel offsets.
1803 addr
= sliceOffset
+ microTileOffset
+ elemOffset
;
1809 ***************************************************************************************************
1810 * EgBasedAddrLib::HwlComputePixelCoordFromOffset
1813 * Compute pixel coordinate from offset inside a micro tile
1816 ***************************************************************************************************
1818 VOID
EgBasedAddrLib::HwlComputePixelCoordFromOffset(
1819 UINT_32 offset
, ///< [in] offset inside micro tile in bits
1820 UINT_32 bpp
, ///< [in] bits per pixel
1821 UINT_32 numSamples
, ///< [in] number of samples
1822 AddrTileMode tileMode
, ///< [in] tile mode
1823 UINT_32 tileBase
, ///< [in] base offset within a tile
1824 UINT_32 compBits
, ///< [in] component bits actually needed(for planar surface)
1825 UINT_32
* pX
, ///< [out] x coordinate
1826 UINT_32
* pY
, ///< [out] y coordinate
1827 UINT_32
* pSlice
, ///< [out] slice index
1828 UINT_32
* pSample
, ///< [out] sample index
1829 AddrTileType microTileType
, ///< [in] micro tiling type
1830 BOOL_32 isDepthSampleOrder
///< [in] TRUE if depth sample order in microtile is used
1836 UINT_32 thickness
= ComputeSurfaceThickness(tileMode
);
1838 // For planar surface, we adjust offset acoording to tile base
1839 if ((bpp
!= compBits
) && (compBits
!= 0) && isDepthSampleOrder
)
1843 ADDR_ASSERT(microTileType
== ADDR_NON_DISPLAYABLE
||
1844 microTileType
== ADDR_DEPTH_SAMPLE_ORDER
);
1849 UINT_32 sampleTileBits
;
1850 UINT_32 samplePixelBits
;
1853 if (isDepthSampleOrder
)
1855 samplePixelBits
= bpp
* numSamples
;
1856 pixelIndex
= offset
/ samplePixelBits
;
1857 *pSample
= (offset
% samplePixelBits
) / bpp
;
1861 sampleTileBits
= MicroTilePixels
* bpp
* thickness
;
1862 *pSample
= offset
/ sampleTileBits
;
1863 pixelIndex
= (offset
% sampleTileBits
) / bpp
;
1866 if (microTileType
!= ADDR_THICK
)
1868 if (microTileType
== ADDR_DISPLAYABLE
) // displayable
1873 x
= pixelIndex
& 0x7;
1874 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,4));
1877 x
= pixelIndex
& 0x7;
1878 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,3));
1881 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,1),_BIT(pixelIndex
,0));
1882 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,2));
1885 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
1886 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
1889 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,2),_BIT(pixelIndex
,1));
1890 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,0));
1896 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
1898 x
= Bits2Number(3, _BIT(pixelIndex
,4),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
1899 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
1901 else if (microTileType
== ADDR_ROTATED
)
1905 element_index[5:0] = { x[2], x[0], x[1], y[2], y[1], y[0] }
1908 element_index[5:0] = { x[2], x[1], x[0], y[2], y[1], y[0] }
1911 element_index[5:0] = { x[2], x[1], y[2], x[0], y[1], y[0] }
1914 element_index[5:0] = { y[2], x[2], x[1], y[1], x[0], y[0] }
1919 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,4));
1920 y
= pixelIndex
& 0x7;
1923 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,3));
1924 y
= pixelIndex
& 0x7;
1927 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,2));
1928 y
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,1),_BIT(pixelIndex
,0));
1931 x
= Bits2Number(3, _BIT(pixelIndex
,4),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
1932 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
1935 ADDR_ASSERT_ALWAYS();
1940 if (thickness
> 1) // thick
1942 z
= Bits2Number(3, _BIT(pixelIndex
,8),_BIT(pixelIndex
,7),_BIT(pixelIndex
,6));
1947 ADDR_ASSERT((m_chipFamily
>= ADDR_CHIP_FAMILY_CI
) && (thickness
> 1));
1949 8-Bit Elements and 16-Bit Elements
1950 element_index[7:0] = { y[2], x[2], z[1], z[0], y[1], x[1], y[0], x[0] }
1953 element_index[7:0] = { y[2], x[2], z[1], y[1], z[0], x[1], y[0], x[0] }
1955 64-Bit Elements and 128-Bit Elements
1956 element_index[7:0] = { y[2], x[2], z[1], y[1], x[1], z[0], y[0], x[0] }
1958 The equation to compute the element index for the extra thick tile:
1959 element_index[8] = z[2]
1964 case 16: // fall-through
1965 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
1966 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
1967 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4));
1970 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
1971 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
1972 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3));
1975 case 128: // fall-through
1976 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,3),_BIT(pixelIndex
,0));
1977 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
1978 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,2));
1981 ADDR_ASSERT_ALWAYS();
1987 z
+= Bits2Number(3,_BIT(pixelIndex
,8),0,0);
1998 ***************************************************************************************************
1999 * EgBasedAddrLib::DispatchComputeSurfaceCoordFromAddrDispatch
2002 * Compute (x,y,slice,sample) coordinates from surface address
2005 ***************************************************************************************************
2007 VOID
EgBasedAddrLib::DispatchComputeSurfaceCoordFromAddr(
2008 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
2009 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
2012 UINT_64 addr
= pIn
->addr
;
2013 UINT_32 bitPosition
= pIn
->bitPosition
;
2014 UINT_32 bpp
= pIn
->bpp
;
2015 UINT_32 pitch
= pIn
->pitch
;
2016 UINT_32 height
= pIn
->height
;
2017 UINT_32 numSlices
= pIn
->numSlices
;
2018 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
2019 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
2020 AddrTileMode tileMode
= pIn
->tileMode
;
2021 UINT_32 tileBase
= pIn
->tileBase
;
2022 UINT_32 compBits
= pIn
->compBits
;
2023 AddrTileType microTileType
= pIn
->tileType
;
2024 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
2025 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
2026 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2028 UINT_32
* pX
= &pOut
->x
;
2029 UINT_32
* pY
= &pOut
->y
;
2030 UINT_32
* pSlice
= &pOut
->slice
;
2031 UINT_32
* pSample
= &pOut
->sample
;
2033 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2035 isDepthSampleOrder
= TRUE
;
2038 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
2040 if (numFrags
!= numSamples
)
2042 numSamples
= numFrags
;
2046 /// 128 bit/thick tiled surface doesn't support display tiling and
2047 /// mipmap chain must have the same tileType, so please fill tileType correctly
2048 if (!IsLinear(pIn
->tileMode
))
2050 if (bpp
>= 128 || ComputeSurfaceThickness(tileMode
) > 1)
2052 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
2059 case ADDR_TM_LINEAR_GENERAL
://fall through
2060 case ADDR_TM_LINEAR_ALIGNED
:
2061 ComputeSurfaceCoordFromAddrLinear(addr
,
2072 case ADDR_TM_1D_TILED_THIN1
://fall through
2073 case ADDR_TM_1D_TILED_THICK
:
2074 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
2088 isDepthSampleOrder
);
2090 case ADDR_TM_2D_TILED_THIN1
: //fall through
2091 case ADDR_TM_2D_TILED_THICK
: //fall through
2092 case ADDR_TM_3D_TILED_THIN1
: //fall through
2093 case ADDR_TM_3D_TILED_THICK
: //fall through
2094 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2095 case ADDR_TM_3D_TILED_XTHICK
: //fall through
2096 case ADDR_TM_PRT_TILED_THIN1
: //fall through
2097 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
2098 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
2099 case ADDR_TM_PRT_TILED_THICK
: //fall through
2100 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
2101 case ADDR_TM_PRT_3D_TILED_THICK
:
2102 UINT_32 pipeSwizzle
;
2103 UINT_32 bankSwizzle
;
2105 if (m_configFlags
.useCombinedSwizzle
)
2107 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
2108 &bankSwizzle
, &pipeSwizzle
);
2112 pipeSwizzle
= pIn
->pipeSwizzle
;
2113 bankSwizzle
= pIn
->bankSwizzle
;
2116 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
2137 ADDR_ASSERT_ALWAYS();
2143 ***************************************************************************************************
2144 * EgBasedAddrLib::ComputeSurfaceCoordFromAddrMacroTiled
2147 * Compute surface coordinates from address for macro tiled surface
2150 ***************************************************************************************************
2152 VOID
EgBasedAddrLib::ComputeSurfaceCoordFromAddrMacroTiled(
2153 UINT_64 addr
, ///< [in] byte address
2154 UINT_32 bitPosition
, ///< [in] bit position
2155 UINT_32 bpp
, ///< [in] bits per pixel
2156 UINT_32 pitch
, ///< [in] pitch in pixels
2157 UINT_32 height
, ///< [in] height in pixels
2158 UINT_32 numSamples
, ///< [in] number of samples
2159 AddrTileMode tileMode
, ///< [in] tile mode
2160 UINT_32 tileBase
, ///< [in] tile base offset
2161 UINT_32 compBits
, ///< [in] component bits (for planar surface)
2162 AddrTileType microTileType
, ///< [in] micro tiling type
2163 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines can be ignored
2164 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if depth sample order is used
2165 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2166 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2167 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure.
2168 /// **All fields to be valid on entry**
2169 UINT_32
* pX
, ///< [out] X coord
2170 UINT_32
* pY
, ///< [out] Y coord
2171 UINT_32
* pSlice
, ///< [out] slice index
2172 UINT_32
* pSample
///< [out] sample index
2178 UINT_64 macroTileBits
;
2181 UINT_64 elementOffset
;
2182 UINT_64 macroTileIndex
;
2184 UINT_64 totalOffset
;
2189 UINT_32 groupBits
= m_pipeInterleaveBytes
<< 3;
2190 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2191 UINT_32 banks
= pTileInfo
->banks
;
2193 UINT_32 bankInterleave
= m_bankInterleave
;
2195 UINT_64 addrBits
= BYTES_TO_BITS(addr
) + bitPosition
;
2198 // remove bits for bank and pipe
2200 totalOffset
= (addrBits
% groupBits
) +
2201 (((addrBits
/ groupBits
/ pipes
) % bankInterleave
) * groupBits
) +
2202 (((addrBits
/ groupBits
/ pipes
) / bankInterleave
) / banks
) * groupBits
* bankInterleave
;
2204 UINT_32 microTileThickness
= ComputeSurfaceThickness(tileMode
);
2206 UINT_32 microTileBits
= bpp
* microTileThickness
* MicroTilePixels
* numSamples
;
2208 UINT_32 microTileBytes
= BITS_TO_BYTES(microTileBits
);
2210 // Determine if tiles need to be split across slices.
2212 // If the size of the micro tile is larger than the tile split size, then the tile will be
2213 // split across multiple slices.
2215 UINT_32 slicesPerTile
= 1; //_State->TileSlices
2217 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
2218 { //don't support for thick mode
2221 // Compute the number of slices per tile.
2223 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
2226 tileBits
= microTileBits
/ slicesPerTile
; // micro tile bits
2228 // in micro tiles because not MicroTileWidth timed.
2229 UINT_32 macroWidth
= pTileInfo
->bankWidth
* pipes
* pTileInfo
->macroAspectRatio
;
2230 // in micro tiles as well
2231 UINT_32 macroHeight
= pTileInfo
->bankHeight
* banks
/ pTileInfo
->macroAspectRatio
;
2233 UINT_32 pitchInMacroTiles
= pitch
/ MicroTileWidth
/ macroWidth
;
2235 macroTileBits
= (macroWidth
* macroHeight
) * tileBits
/ (banks
* pipes
);
2237 macroTileIndex
= totalOffset
/ macroTileBits
;
2239 // pitchMacros * height / heightMacros; macroTilesPerSlice == _State->SliceMacros
2240 UINT_32 macroTilesPerSlice
= (pitch
/ (macroWidth
* MicroTileWidth
)) * height
/
2241 (macroHeight
* MicroTileWidth
);
2243 slices
= static_cast<UINT_32
>(macroTileIndex
/ macroTilesPerSlice
);
2245 *pSlice
= static_cast<UINT_32
>(slices
/ slicesPerTile
* microTileThickness
);
2248 // calculate element offset and x[2:0], y[2:0], z[1:0] for thick
2250 tileSlices
= slices
% slicesPerTile
;
2252 elementOffset
= tileSlices
* tileBits
;
2253 elementOffset
+= totalOffset
% tileBits
;
2257 HwlComputePixelCoordFromOffset(static_cast<UINT_32
>(elementOffset
),
2268 isDepthSampleOrder
);
2270 macroTileIndex
= macroTileIndex
% macroTilesPerSlice
;
2271 *pY
+= static_cast<UINT_32
>(macroTileIndex
/ pitchInMacroTiles
* macroHeight
* MicroTileHeight
);
2272 *pX
+= static_cast<UINT_32
>(macroTileIndex
% pitchInMacroTiles
* macroWidth
* MicroTileWidth
);
2276 tileIndex
= static_cast<UINT_32
>((totalOffset
% macroTileBits
) / tileBits
);
2278 my
= (tileIndex
/ pTileInfo
->bankWidth
) % pTileInfo
->bankHeight
* MicroTileHeight
;
2279 mx
= (tileIndex
% pTileInfo
->bankWidth
) * pipes
* MicroTileWidth
;
2284 bank
= ComputeBankFromAddr(addr
, banks
, pipes
);
2285 pipe
= ComputePipeFromAddr(addr
, pipes
);
2287 HwlComputeSurfaceCoord2DFromBankPipe(tileMode
,
2301 ***************************************************************************************************
2302 * EgBasedAddrLib::ComputeSurfaceCoord2DFromBankPipe
2305 * Compute surface x,y coordinates from bank/pipe info
2308 ***************************************************************************************************
2310 VOID
EgBasedAddrLib::ComputeSurfaceCoord2DFromBankPipe(
2311 AddrTileMode tileMode
, ///< [in] tile mode
2312 UINT_32 x
, ///< [in] x coordinate
2313 UINT_32 y
, ///< [in] y coordinate
2314 UINT_32 slice
, ///< [in] slice index
2315 UINT_32 bank
, ///< [in] bank number
2316 UINT_32 pipe
, ///< [in] pipe number
2317 UINT_32 bankSwizzle
,///< [in] bank swizzle
2318 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
2319 UINT_32 tileSlices
, ///< [in] slices in a micro tile
2320 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure. **All fields to be valid on entry**
2321 CoordFromBankPipe
* pOutput
///< [out] pointer to extracted x/y bits
2333 UINT_32 tileSplitRotation
;
2335 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2337 UINT_32 bankRotation
= ComputeBankRotation(tileMode
,
2338 pTileInfo
->banks
, numPipes
);
2340 UINT_32 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2342 UINT_32 xBit
= x
/ (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
);
2343 UINT_32 yBit
= y
/ (MicroTileHeight
* pTileInfo
->bankHeight
);
2345 //calculate the bank and pipe before rotation and swizzle
2349 case ADDR_TM_2D_TILED_THIN1
: //fall through
2350 case ADDR_TM_2D_TILED_THICK
: //fall through
2351 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2352 case ADDR_TM_3D_TILED_THIN1
: //fall through
2353 case ADDR_TM_3D_TILED_THICK
: //fall through
2354 case ADDR_TM_3D_TILED_XTHICK
:
2355 tileSplitRotation
= ((pTileInfo
->banks
/ 2) + 1);
2358 tileSplitRotation
= 0;
2362 UINT_32 microTileThickness
= ComputeSurfaceThickness(tileMode
);
2364 bank
^= tileSplitRotation
* tileSlices
;
2365 if (pipeRotation
== 0)
2367 bank
^= bankRotation
* (slice
/ microTileThickness
) + bankSwizzle
;
2368 bank
%= pTileInfo
->banks
;
2369 pipe
^= pipeSwizzle
;
2373 bank
^= bankRotation
* (slice
/ microTileThickness
) / numPipes
+ bankSwizzle
;
2374 bank
%= pTileInfo
->banks
;
2375 pipe
^= pipeRotation
* (slice
/ microTileThickness
) + pipeSwizzle
;
2378 if (pTileInfo
->macroAspectRatio
== 1)
2380 switch (pTileInfo
->banks
)
2383 yBit3
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2386 yBit4
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2387 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2390 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2391 yBit5
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2392 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ yBit5
;
2395 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3);
2396 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2);
2397 yBit6
= _BIT(bank
, 0) ^ _BIT(xBit
, 0);
2398 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ yBit6
;
2405 else if (pTileInfo
->macroAspectRatio
== 2)
2407 switch (pTileInfo
->banks
)
2409 case 2: //xBit3 = yBit3^b0
2410 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,0);
2412 case 4: //xBit3=yBit4^b0; yBit3=xBit4^b1
2413 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2414 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2416 case 8: //xBit4, xBit5, yBit5 are known
2417 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2418 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2419 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ _BIT(yBit
, 2);
2421 case 16://x4,x5,x6,y6 are known
2422 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3); //x3 = y6 ^ b0
2423 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2424 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = x5 ^ b2
2425 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ _BIT(yBit
, 3); //y5=x4^y6^b1
2431 else if (pTileInfo
->macroAspectRatio
== 4)
2433 switch (pTileInfo
->banks
)
2435 case 4: //yBit3, yBit4
2436 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2437 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,0);
2439 case 8: //xBit5, yBit4, yBit5
2440 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2441 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2442 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
,2);
2444 case 16: //xBit5, xBit6, yBit5, yBit6
2445 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = b0 ^ y6
2446 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = b1 ^ y5 ^ y6;
2447 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = b3 ^ x6;
2448 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = b2 ^ x5;
2454 else if (pTileInfo
->macroAspectRatio
== 8)
2456 switch (pTileInfo
->banks
)
2458 case 8: //yBit3, yBit4, yBit5
2459 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2); //x3 = b0 ^ y5;
2460 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
, 2);//x4 = b1 ^ y4 ^ y5;
2461 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
,0);
2463 case 16: //xBit6, yBit4, yBit5, yBit6
2464 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = y6 ^ b0
2465 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = y5 ^ y6 ^ b1
2466 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
, 1);//x5 = y4 ^ b2
2467 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2474 pOutput
->xBits
= xBit
;
2475 pOutput
->yBits
= yBit
;
2477 pOutput
->xBit3
= xBit3
;
2478 pOutput
->xBit4
= xBit4
;
2479 pOutput
->xBit5
= xBit5
;
2480 pOutput
->yBit3
= yBit3
;
2481 pOutput
->yBit4
= yBit4
;
2482 pOutput
->yBit5
= yBit5
;
2483 pOutput
->yBit6
= yBit6
;
2487 ***************************************************************************************************
2488 * EgBasedAddrLib::HwlExtractBankPipeSwizzle
2490 * Entry of EgBasedAddrLib ExtractBankPipeSwizzle
2493 ***************************************************************************************************
2495 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlExtractBankPipeSwizzle(
2496 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
2497 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
2500 ExtractBankPipeSwizzle(pIn
->base256b
,
2503 &pOut
->pipeSwizzle
);
2510 ***************************************************************************************************
2511 * EgBasedAddrLib::HwlCombineBankPipeSwizzle
2513 * Combine bank/pipe swizzle
2516 ***************************************************************************************************
2518 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlCombineBankPipeSwizzle(
2519 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2520 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2521 ADDR_TILEINFO
* pTileInfo
, ///< [in] tile info
2522 UINT_64 baseAddr
, ///< [in] base address
2523 UINT_32
* pTileSwizzle
///< [out] combined swizzle
2526 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
2530 *pTileSwizzle
= GetBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, baseAddr
, pTileInfo
);
2534 retCode
= ADDR_INVALIDPARAMS
;
2541 ***************************************************************************************************
2542 * EgBasedAddrLib::HwlComputeBaseSwizzle
2544 * Compute base swizzle
2547 ***************************************************************************************************
2549 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeBaseSwizzle(
2550 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT
* pIn
,
2551 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
* pOut
2554 UINT_32 bankSwizzle
= 0;
2555 UINT_32 pipeSwizzle
= 0;
2556 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2558 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
2559 ADDR_ASSERT(pIn
->pTileInfo
);
2561 /// This is a legacy misreading of h/w doc, use it as it doesn't hurt.
2562 static const UINT_8 bankRotationArray
[4][16] = {
2563 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_2_BANK
2564 { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_4_BANK
2565 { 0, 3, 6, 1, 4, 7, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_8_BANK
2566 { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }, // ADDR_SURF_16_BANK
2569 UINT_32 banks
= pTileInfo
? pTileInfo
->banks
: 2;
2572 // Uses less bank swizzle bits
2573 if (pIn
->option
.reduceBankBit
&& banks
> 2)
2593 ADDR_ASSERT_ALWAYS();
2598 if (pIn
->option
.genOption
== ADDR_SWIZZLE_GEN_LINEAR
)
2600 bankSwizzle
= pIn
->surfIndex
& (banks
- 1);
2602 else // (pIn->option.genOption == ADDR_SWIZZLE_GEN_DEFAULT)
2604 bankSwizzle
= bankRotationArray
[hwNumBanks
][pIn
->surfIndex
& (banks
- 1)];
2607 if (IsMacro3dTiled(pIn
->tileMode
))
2609 pipeSwizzle
= pIn
->surfIndex
& (HwlGetPipes(pTileInfo
) - 1);
2612 return HwlCombineBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, pTileInfo
, 0, &pOut
->tileSwizzle
);
2616 ***************************************************************************************************
2617 * EgBasedAddrLib::ExtractBankPipeSwizzle
2619 * Extract bank/pipe swizzle from base256b
2622 ***************************************************************************************************
2624 VOID
EgBasedAddrLib::ExtractBankPipeSwizzle(
2625 UINT_32 base256b
, ///< [in] input base256b register value
2626 ADDR_TILEINFO
* pTileInfo
, ///< [in] 2D tile parameters. Client must provide all data
2627 UINT_32
* pBankSwizzle
, ///< [out] bank swizzle
2628 UINT_32
* pPipeSwizzle
///< [out] pipe swizzle
2631 UINT_32 bankSwizzle
= 0;
2632 UINT_32 pipeSwizzle
= 0;
2636 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2637 UINT_32 bankBits
= QLog2(pTileInfo
->banks
);
2638 UINT_32 pipeBits
= QLog2(numPipes
);
2639 UINT_32 groupBytes
= m_pipeInterleaveBytes
;
2640 UINT_32 bankInterleave
= m_bankInterleave
;
2643 (base256b
/ (groupBytes
>> 8)) & ((1<<pipeBits
)-1);
2646 (base256b
/ (groupBytes
>> 8) / numPipes
/ bankInterleave
) & ((1 << bankBits
) - 1);
2649 *pPipeSwizzle
= pipeSwizzle
;
2650 *pBankSwizzle
= bankSwizzle
;
2654 ***************************************************************************************************
2655 * EgBasedAddrLib::GetBankPipeSwizzle
2657 * Combine bank/pipe swizzle
2659 * Base256b bits (only filled bank/pipe bits)
2660 ***************************************************************************************************
2662 UINT_32
EgBasedAddrLib::GetBankPipeSwizzle(
2663 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2664 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2665 UINT_64 baseAddr
, ///< [in] base address
2666 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2669 UINT_32 pipeBits
= QLog2(HwlGetPipes(pTileInfo
));
2670 UINT_32 bankInterleaveBits
= QLog2(m_bankInterleave
);
2671 UINT_32 tileSwizzle
= pipeSwizzle
+ ((bankSwizzle
<< bankInterleaveBits
) << pipeBits
);
2673 baseAddr
^= tileSwizzle
* m_pipeInterleaveBytes
;
2676 return static_cast<UINT_32
>(baseAddr
);
2680 ***************************************************************************************************
2681 * EgBasedAddrLib::ComputeSliceTileSwizzle
2683 * Compute cubemap/3d texture faces/slices tile swizzle
2686 ***************************************************************************************************
2688 UINT_32
EgBasedAddrLib::ComputeSliceTileSwizzle(
2689 AddrTileMode tileMode
, ///< [in] Tile mode
2690 UINT_32 baseSwizzle
, ///< [in] Base swizzle
2691 UINT_32 slice
, ///< [in] Slice index, Cubemap face index, 0 means +X
2692 UINT_64 baseAddr
, ///< [in] Base address
2693 ADDR_TILEINFO
* pTileInfo
///< [in] Bank structure
2696 UINT_32 tileSwizzle
= 0;
2698 if (IsMacroTiled(tileMode
)) // Swizzle only for macro tile mode
2700 UINT_32 firstSlice
= slice
/ ComputeSurfaceThickness(tileMode
);
2702 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2703 UINT_32 numBanks
= pTileInfo
->banks
;
2705 UINT_32 pipeRotation
;
2706 UINT_32 bankRotation
;
2708 UINT_32 bankSwizzle
= 0;
2709 UINT_32 pipeSwizzle
= 0;
2711 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2712 bankRotation
= ComputeBankRotation(tileMode
, numBanks
, numPipes
);
2714 if (baseSwizzle
!= 0)
2716 ExtractBankPipeSwizzle(baseSwizzle
,
2722 if (pipeRotation
== 0) //2D mode
2724 bankSwizzle
+= firstSlice
* bankRotation
;
2725 bankSwizzle
%= numBanks
;
2729 pipeSwizzle
+= firstSlice
* pipeRotation
;
2730 pipeSwizzle
%= numPipes
;
2731 bankSwizzle
+= firstSlice
* bankRotation
/ numPipes
;
2732 bankSwizzle
%= numBanks
;
2735 tileSwizzle
= GetBankPipeSwizzle(bankSwizzle
,
2745 ***************************************************************************************************
2746 * EgBasedAddrLib::HwlComputeQbStereoRightSwizzle
2749 * Compute right eye swizzle
2752 ***************************************************************************************************
2754 UINT_32
EgBasedAddrLib::HwlComputeQbStereoRightSwizzle(
2755 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pInfo
///< [in] Surface info, must be valid
2758 UINT_32 bankBits
= 0;
2759 UINT_32 swizzle
= 0;
2761 // The assumption is default swizzle for left eye is 0
2762 if (IsMacroTiled(pInfo
->tileMode
) && pInfo
->pStereoInfo
&& pInfo
->pTileInfo
)
2764 bankBits
= ComputeBankFromCoord(0, pInfo
->height
, 0,
2765 pInfo
->tileMode
, 0, 0, pInfo
->pTileInfo
);
2769 HwlCombineBankPipeSwizzle(bankBits
, 0, pInfo
->pTileInfo
, 0, &swizzle
);
2777 ***************************************************************************************************
2778 * EgBasedAddrLib::ComputeBankFromCoord
2781 * Compute bank number from coordinates
2784 ***************************************************************************************************
2786 UINT_32
EgBasedAddrLib::ComputeBankFromCoord(
2787 UINT_32 x
, ///< [in] x coordinate
2788 UINT_32 y
, ///< [in] y coordinate
2789 UINT_32 slice
, ///< [in] slice index
2790 AddrTileMode tileMode
, ///< [in] tile mode
2791 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2792 UINT_32 tileSplitSlice
, ///< [in] If the size of the pixel offset is larger than the
2793 /// tile split size, then the pixel will be moved to a separate
2794 /// slice. This value equals pixelOffset / tileSplitBytes
2795 /// in this case. Otherwise this is 0.
2796 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2799 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2800 UINT_32 bankBit0
= 0;
2801 UINT_32 bankBit1
= 0;
2802 UINT_32 bankBit2
= 0;
2803 UINT_32 bankBit3
= 0;
2804 UINT_32 sliceRotation
;
2805 UINT_32 tileSplitRotation
;
2807 UINT_32 numBanks
= pTileInfo
->banks
;
2808 UINT_32 bankWidth
= pTileInfo
->bankWidth
;
2809 UINT_32 bankHeight
= pTileInfo
->bankHeight
;
2811 UINT_32 tx
= x
/ MicroTileWidth
/ (bankWidth
* pipes
);
2812 UINT_32 ty
= y
/ MicroTileHeight
/ bankHeight
;
2814 UINT_32 x3
= _BIT(tx
,0);
2815 UINT_32 x4
= _BIT(tx
,1);
2816 UINT_32 x5
= _BIT(tx
,2);
2817 UINT_32 x6
= _BIT(tx
,3);
2818 UINT_32 y3
= _BIT(ty
,0);
2819 UINT_32 y4
= _BIT(ty
,1);
2820 UINT_32 y5
= _BIT(ty
,2);
2821 UINT_32 y6
= _BIT(ty
,3);
2827 bankBit1
= x4
^ y5
^ y6
;
2833 bankBit1
= x4
^ y4
^ y5
;
2844 ADDR_ASSERT_ALWAYS();
2848 bank
= bankBit0
| (bankBit1
<< 1) | (bankBit2
<< 2) | (bankBit3
<< 3);
2850 //Bits2Number(4, bankBit3, bankBit2, bankBit1, bankBit0);
2852 bank
= HwlPreAdjustBank((x
/ MicroTileWidth
), bank
, pTileInfo
);
2854 // Compute bank rotation for the slice.
2856 UINT_32 microTileThickness
= ComputeSurfaceThickness(tileMode
);
2860 case ADDR_TM_2D_TILED_THIN1
: // fall through
2861 case ADDR_TM_2D_TILED_THICK
: // fall through
2862 case ADDR_TM_2D_TILED_XTHICK
:
2863 sliceRotation
= ((numBanks
/ 2) - 1) * (slice
/ microTileThickness
);
2865 case ADDR_TM_3D_TILED_THIN1
: // fall through
2866 case ADDR_TM_3D_TILED_THICK
: // fall through
2867 case ADDR_TM_3D_TILED_XTHICK
:
2869 Max(1u, (pipes
/ 2) - 1) * (slice
/ microTileThickness
) / pipes
;
2878 // Compute bank rotation for the tile split slice.
2880 // The sample slice will be non-zero if samples must be split across multiple slices.
2881 // This situation arises when the micro tile size multiplied yBit the number of samples exceeds
2882 // the split size (set in GB_ADDR_CONFIG).
2886 case ADDR_TM_2D_TILED_THIN1
: //fall through
2887 case ADDR_TM_3D_TILED_THIN1
: //fall through
2888 case ADDR_TM_PRT_2D_TILED_THIN1
: //fall through
2889 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
2890 tileSplitRotation
= ((numBanks
/ 2) + 1) * tileSplitSlice
;
2893 tileSplitRotation
= 0;
2898 // Apply bank rotation for the slice and tile split slice.
2900 bank
^= bankSwizzle
+ sliceRotation
;
2901 bank
^= tileSplitRotation
;
2903 bank
&= (numBanks
- 1);
2909 ***************************************************************************************************
2910 * EgBasedAddrLib::ComputeBankFromAddr
2913 * Compute the bank number from an address
2916 ***************************************************************************************************
2918 UINT_32
EgBasedAddrLib::ComputeBankFromAddr(
2919 UINT_64 addr
, ///< [in] address
2920 UINT_32 numBanks
, ///< [in] number of banks
2921 UINT_32 numPipes
///< [in] number of pipes
2927 // The LSBs of the address are arranged as follows:
2928 // bank | bankInterleave | pipe | pipeInterleave
2930 // To get the bank number, shift off the pipe interleave, pipe, and bank interlave bits and
2931 // mask the bank bits.
2933 bank
= static_cast<UINT_32
>(
2934 (addr
>> Log2(m_pipeInterleaveBytes
* numPipes
* m_bankInterleave
)) &
2942 ***************************************************************************************************
2943 * EgBasedAddrLib::ComputePipeRotation
2946 * Compute pipe rotation value
2949 ***************************************************************************************************
2951 UINT_32
EgBasedAddrLib::ComputePipeRotation(
2952 AddrTileMode tileMode
, ///< [in] tile mode
2953 UINT_32 numPipes
///< [in] number of pipes
2960 case ADDR_TM_3D_TILED_THIN1
: //fall through
2961 case ADDR_TM_3D_TILED_THICK
: //fall through
2962 case ADDR_TM_3D_TILED_XTHICK
: //fall through
2963 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
2964 case ADDR_TM_PRT_3D_TILED_THICK
:
2965 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1);
2977 ***************************************************************************************************
2978 * EgBasedAddrLib::ComputeBankRotation
2981 * Compute bank rotation value
2984 ***************************************************************************************************
2986 UINT_32
EgBasedAddrLib::ComputeBankRotation(
2987 AddrTileMode tileMode
, ///< [in] tile mode
2988 UINT_32 numBanks
, ///< [in] number of banks
2989 UINT_32 numPipes
///< [in] number of pipes
2996 case ADDR_TM_2D_TILED_THIN1
: // fall through
2997 case ADDR_TM_2D_TILED_THICK
: // fall through
2998 case ADDR_TM_2D_TILED_XTHICK
:
2999 case ADDR_TM_PRT_2D_TILED_THIN1
:
3000 case ADDR_TM_PRT_2D_TILED_THICK
:
3001 // Rotate banks per Z-slice yBit 1 for 4-bank or 3 for 8-bank
3002 rotation
= numBanks
/ 2 - 1;
3004 case ADDR_TM_3D_TILED_THIN1
: // fall through
3005 case ADDR_TM_3D_TILED_THICK
: // fall through
3006 case ADDR_TM_3D_TILED_XTHICK
:
3007 case ADDR_TM_PRT_3D_TILED_THIN1
:
3008 case ADDR_TM_PRT_3D_TILED_THICK
:
3009 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1); // rotate pipes & banks
3020 ***************************************************************************************************
3021 * EgBasedAddrLib::ComputeHtileBytes
3024 * Compute htile size in bytes
3027 * Htile size in bytes
3028 ***************************************************************************************************
3030 UINT_64
EgBasedAddrLib::ComputeHtileBytes(
3031 UINT_32 pitch
, ///< [in] pitch
3032 UINT_32 height
, ///< [in] height
3033 UINT_32 bpp
, ///< [in] bits per pixel
3034 BOOL_32 isLinear
, ///< [in] if it is linear mode
3035 UINT_32 numSlices
, ///< [in] number of slices
3036 UINT_64
* sliceBytes
, ///< [out] bytes per slice
3037 UINT_32 baseAlign
///< [in] base alignments
3042 const UINT_64 HtileCacheLineSize
= BITS_TO_BYTES(HtileCacheBits
);
3044 *sliceBytes
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
/ 64);
3046 if (m_configFlags
.useHtileSliceAlign
)
3048 // Align the sliceSize to htilecachelinesize * pipes at first
3049 *sliceBytes
= PowTwoAlign(*sliceBytes
, HtileCacheLineSize
* m_pipes
);
3050 surfBytes
= *sliceBytes
* numSlices
;
3054 // Align the surfSize to htilecachelinesize * pipes at last
3055 surfBytes
= *sliceBytes
* numSlices
;
3056 surfBytes
= PowTwoAlign(surfBytes
, HtileCacheLineSize
* m_pipes
);
3063 ***************************************************************************************************
3064 * EgBasedAddrLib::DispatchComputeFmaskInfo
3067 * Compute fmask sizes include padded pitch, height, slices, total size in bytes,
3068 * meanwhile output suitable tile mode and alignments as well. Results are returned
3069 * through output parameters.
3073 ***************************************************************************************************
3075 ADDR_E_RETURNCODE
EgBasedAddrLib::DispatchComputeFmaskInfo(
3076 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3077 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
) ///< [out] output structure
3079 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3081 ADDR_COMPUTE_SURFACE_INFO_INPUT surfIn
= {0};
3082 ADDR_COMPUTE_SURFACE_INFO_OUTPUT surfOut
= {0};
3084 // Setup input structure
3085 surfIn
.tileMode
= pIn
->tileMode
;
3086 surfIn
.width
= pIn
->pitch
;
3087 surfIn
.height
= pIn
->height
;
3088 surfIn
.numSlices
= pIn
->numSlices
;
3089 surfIn
.pTileInfo
= pIn
->pTileInfo
;
3090 surfIn
.tileType
= ADDR_NON_DISPLAYABLE
;
3091 surfIn
.flags
.fmask
= 1;
3093 // Setup output structure
3094 surfOut
.pTileInfo
= pOut
->pTileInfo
;
3096 // Setup hwl specific fields
3097 HwlFmaskPreThunkSurfInfo(pIn
, pOut
, &surfIn
, &surfOut
);
3099 surfIn
.bpp
= HwlComputeFmaskBits(pIn
, &surfIn
.numSamples
);
3101 // ComputeSurfaceInfo needs numSamples in surfOut as surface routines need adjusted numSamples
3102 surfOut
.numSamples
= surfIn
.numSamples
;
3104 retCode
= HwlComputeSurfaceInfo(&surfIn
, &surfOut
);
3106 // Save bpp field for surface dump support
3107 surfOut
.bpp
= surfIn
.bpp
;
3109 if (retCode
== ADDR_OK
)
3111 pOut
->bpp
= surfOut
.bpp
;
3112 pOut
->pitch
= surfOut
.pitch
;
3113 pOut
->height
= surfOut
.height
;
3114 pOut
->numSlices
= surfOut
.depth
;
3115 pOut
->fmaskBytes
= surfOut
.surfSize
;
3116 pOut
->baseAlign
= surfOut
.baseAlign
;
3117 pOut
->pitchAlign
= surfOut
.pitchAlign
;
3118 pOut
->heightAlign
= surfOut
.heightAlign
;
3120 if (surfOut
.depth
> 1)
3122 // For fmask, expNumSlices is stored in depth.
3123 pOut
->sliceSize
= surfOut
.surfSize
/ surfOut
.depth
;
3127 pOut
->sliceSize
= surfOut
.surfSize
;
3130 // Save numSamples field for surface dump support
3131 pOut
->numSamples
= surfOut
.numSamples
;
3133 HwlFmaskPostThunkSurfInfo(&surfOut
, pOut
);
3140 ***************************************************************************************************
3141 * EgBasedAddrLib::HwlFmaskSurfaceInfo
3143 * Entry of EgBasedAddrLib ComputeFmaskInfo
3146 ***************************************************************************************************
3148 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeFmaskInfo(
3149 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3150 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
3153 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3155 ADDR_TILEINFO tileInfo
= {0};
3157 // Use internal tile info if pOut does not have a valid pTileInfo
3158 if (pOut
->pTileInfo
== NULL
)
3160 pOut
->pTileInfo
= &tileInfo
;
3163 retCode
= DispatchComputeFmaskInfo(pIn
, pOut
);
3165 if (retCode
== ADDR_OK
)
3168 HwlPostCheckTileIndex(pOut
->pTileInfo
, pIn
->tileMode
, ADDR_NON_DISPLAYABLE
,
3172 // Resets pTileInfo to NULL if the internal tile info is used
3173 if (pOut
->pTileInfo
== &tileInfo
)
3175 pOut
->pTileInfo
= NULL
;
3182 ***************************************************************************************************
3183 * EgBasedAddrLib::HwlComputeFmaskAddrFromCoord
3185 * Entry of EgBasedAddrLib ComputeFmaskAddrFromCoord
3188 ***************************************************************************************************
3190 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeFmaskAddrFromCoord(
3191 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3192 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3195 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3198 if ((pIn
->x
> pIn
->pitch
) ||
3199 (pIn
->y
> pIn
->height
) ||
3200 (pIn
->numSamples
> m_maxSamples
) ||
3201 (pIn
->sample
>= m_maxSamples
))
3203 retCode
= ADDR_INVALIDPARAMS
;
3207 pOut
->addr
= DispatchComputeFmaskAddrFromCoord(pIn
, pOut
);
3215 ***************************************************************************************************
3216 * EgBasedAddrLib::HwlComputeFmaskCoordFromAddr
3218 * Entry of EgBasedAddrLib ComputeFmaskCoordFromAddr
3221 ***************************************************************************************************
3223 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeFmaskCoordFromAddr(
3224 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3225 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3228 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3231 if ((pIn
->bitPosition
>= 8) ||
3232 (pIn
->numSamples
> m_maxSamples
))
3234 retCode
= ADDR_INVALIDPARAMS
;
3238 DispatchComputeFmaskCoordFromAddr(pIn
, pOut
);
3247 ***************************************************************************************************
3248 * EgBasedAddrLib::DispatchComputeFmaskAddrFromCoord
3251 * Computes the FMASK address and bit position from a coordinate.
3254 ***************************************************************************************************
3256 UINT_64
EgBasedAddrLib::DispatchComputeFmaskAddrFromCoord(
3257 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3258 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3263 UINT_32 slice
= pIn
->slice
;
3264 UINT_32 sample
= pIn
->sample
;
3265 UINT_32 plane
= pIn
->plane
;
3266 UINT_32 pitch
= pIn
->pitch
;
3267 UINT_32 height
= pIn
->height
;
3268 UINT_32 numSamples
= pIn
->numSamples
;
3269 AddrTileMode tileMode
= pIn
->tileMode
;
3270 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
3271 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
3272 BOOL_32 resolved
= pIn
->resolved
;
3274 UINT_32
* pBitPosition
= &pOut
->bitPosition
;
3277 ADDR_ASSERT(numSamples
> 1);
3278 ADDR_ASSERT(ComputeSurfaceThickness(tileMode
) == 1);
3282 case ADDR_TM_1D_TILED_THIN1
:
3283 addr
= ComputeFmaskAddrFromCoordMicroTiled(x
,
3295 case ADDR_TM_2D_TILED_THIN1
: //fall through
3296 case ADDR_TM_3D_TILED_THIN1
:
3297 UINT_32 pipeSwizzle
;
3298 UINT_32 bankSwizzle
;
3300 if (m_configFlags
.useCombinedSwizzle
)
3302 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
3303 &bankSwizzle
, &pipeSwizzle
);
3307 pipeSwizzle
= pIn
->pipeSwizzle
;
3308 bankSwizzle
= pIn
->bankSwizzle
;
3311 addr
= ComputeFmaskAddrFromCoordMacroTiled(x
,
3336 ***************************************************************************************************
3337 * EgBasedAddrLib::ComputeFmaskAddrFromCoordMicroTiled
3340 * Computes the FMASK address and bit position from a coordinate for 1D tilied (micro
3344 ***************************************************************************************************
3346 UINT_64
EgBasedAddrLib::ComputeFmaskAddrFromCoordMicroTiled(
3347 UINT_32 x
, ///< [in] x coordinate
3348 UINT_32 y
, ///< [in] y coordinate
3349 UINT_32 slice
, ///< [in] slice index
3350 UINT_32 sample
, ///< [in] sample number
3351 UINT_32 plane
, ///< [in] plane number
3352 UINT_32 pitch
, ///< [in] surface pitch in pixels
3353 UINT_32 height
, ///< [in] surface height in pixels
3354 UINT_32 numSamples
, ///< [in] number of samples
3355 AddrTileMode tileMode
, ///< [in] tile mode
3356 BOOL_32 resolved
, ///< [in] TRUE if this is for resolved fmask
3357 UINT_32
* pBitPosition
///< [out] pointer to returned bit position
3361 UINT_32 effectiveBpp
;
3362 UINT_32 effectiveSamples
;
3365 // 2xAA use the same layout as 4xAA
3367 if (numSamples
== 2)
3373 // Compute the number of planes.
3377 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3378 effectiveBpp
= numSamples
;
3381 // Compute the address just like a color surface with numSamples bits per element and
3382 // numPlanes samples.
3384 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
3393 ADDR_NON_DISPLAYABLE
,
3398 // Compute the real bit position. Each (sample, plane) is stored with one bit per sample.
3402 // Compute the pixel index with in the micro tile
3404 UINT_32 pixelIndex
= ComputePixelIndexWithinMicroTile(x
% 8,
3409 ADDR_NON_DISPLAYABLE
);
3411 *pBitPosition
= ((pixelIndex
* numSamples
) + sample
) & (BITS_PER_BYTE
-1);
3413 UINT_64 bitAddr
= BYTES_TO_BITS(addr
) + *pBitPosition
;
3419 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3420 effectiveSamples
= 1;
3423 // Compute the address just like a color surface with numSamples bits per element and
3424 // numPlanes samples.
3426 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
3435 ADDR_NON_DISPLAYABLE
,
3444 ***************************************************************************************************
3445 * EgBasedAddrLib::ComputeFmaskAddrFromCoordMacroTiled
3448 * Computes the FMASK address and bit position from a coordinate for 2D tilied (macro
3452 ***************************************************************************************************
3454 UINT_64
EgBasedAddrLib::ComputeFmaskAddrFromCoordMacroTiled(
3455 UINT_32 x
, ///< [in] x coordinate
3456 UINT_32 y
, ///< [in] y coordinate
3457 UINT_32 slice
, ///< [in] slice index
3458 UINT_32 sample
, ///< [in] sample number
3459 UINT_32 plane
, ///< [in] plane number
3460 UINT_32 pitch
, ///< [in] surface pitch in pixels
3461 UINT_32 height
, ///< [in] surface height in pixels
3462 UINT_32 numSamples
, ///< [in] number of samples
3463 AddrTileMode tileMode
, ///< [in] tile mode
3464 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
3465 UINT_32 bankSwizzle
, ///< [in] bank swizzle
3466 BOOL_32 ignoreSE
, ///< [in] TRUE if ignore shader engine
3467 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure.**All fields to be valid on entry**
3468 BOOL_32 resolved
, ///< [in] TRUE if this is for resolved fmask
3469 UINT_32
* pBitPosition
///< [out] pointer to returned bit position
3473 UINT_32 effectiveBpp
;
3474 UINT_32 effectiveSamples
;
3477 // 2xAA use the same layout as 4xAA
3479 if (numSamples
== 2)
3485 // Compute the number of planes.
3489 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3490 effectiveBpp
= numSamples
;
3493 // Compute the address just like a color surface with numSamples bits per element and
3494 // numPlanes samples.
3496 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
3505 ADDR_NON_DISPLAYABLE
,// isdisp
3506 ignoreSE
,// ignore_shader
3507 FALSE
,// depth_sample_order
3514 // Compute the real bit position. Each (sample, plane) is stored with one bit per sample.
3519 // Compute the pixel index with in the micro tile
3521 UINT_32 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
3526 ADDR_NON_DISPLAYABLE
);
3528 *pBitPosition
= ((pixelIndex
* numSamples
) + sample
) & (BITS_PER_BYTE
-1);
3530 UINT_64 bitAddr
= BYTES_TO_BITS(addr
) + *pBitPosition
;
3537 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3538 effectiveSamples
= 1;
3541 // Compute the address just like a color surface with numSamples bits per element and
3542 // numPlanes samples.
3544 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
3553 ADDR_NON_DISPLAYABLE
,
3566 ***************************************************************************************************
3567 * EgBasedAddrLib::ComputeFmaskCoordFromAddrMicroTiled
3570 * Compute (x,y,slice,sample,plane) coordinates from fmask address
3574 ***************************************************************************************************
3576 VOID
EgBasedAddrLib::ComputeFmaskCoordFromAddrMicroTiled(
3577 UINT_64 addr
, ///< [in] byte address
3578 UINT_32 bitPosition
,///< [in] bit position
3579 UINT_32 pitch
, ///< [in] pitch in pixels
3580 UINT_32 height
, ///< [in] height in pixels
3581 UINT_32 numSamples
, ///< [in] number of samples (of color buffer)
3582 AddrTileMode tileMode
, ///< [in] tile mode
3583 BOOL_32 resolved
, ///< [in] TRUE if it is resolved fmask
3584 UINT_32
* pX
, ///< [out] X coord
3585 UINT_32
* pY
, ///< [out] Y coord
3586 UINT_32
* pSlice
, ///< [out] slice index
3587 UINT_32
* pSample
, ///< [out] sample index
3588 UINT_32
* pPlane
///< [out] plane index
3591 UINT_32 effectiveBpp
;
3592 UINT_32 effectiveSamples
;
3594 // 2xAA use the same layout as 4xAA
3595 if (numSamples
== 2)
3602 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3603 effectiveBpp
= numSamples
;
3605 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
3618 ADDR_NON_DISPLAYABLE
, // microTileType
3619 FALSE
// isDepthSampleOrder
3625 *pSample
= bitPosition
% numSamples
;
3630 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3631 effectiveSamples
= 1;
3633 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
3646 ADDR_NON_DISPLAYABLE
, // microTileType
3647 TRUE
// isDepthSampleOrder
3653 ***************************************************************************************************
3654 * EgBasedAddrLib::ComputeFmaskCoordFromAddrMacroTiled
3657 * Compute (x,y,slice,sample,plane) coordinates from
3662 ***************************************************************************************************
3664 VOID
EgBasedAddrLib::ComputeFmaskCoordFromAddrMacroTiled(
3665 UINT_64 addr
, ///< [in] byte address
3666 UINT_32 bitPosition
,///< [in] bit position
3667 UINT_32 pitch
, ///< [in] pitch in pixels
3668 UINT_32 height
, ///< [in] height in pixels
3669 UINT_32 numSamples
, ///< [in] number of samples (of color buffer)
3670 AddrTileMode tileMode
, ///< [in] tile mode
3671 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
3672 UINT_32 bankSwizzle
,///< [in] bank swizzle
3673 BOOL_32 ignoreSE
, ///< [in] TRUE if ignore shader engine
3674 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure. **All fields to be valid on entry**
3675 BOOL_32 resolved
, ///< [in] TRUE if it is resolved fmask
3676 UINT_32
* pX
, ///< [out] X coord
3677 UINT_32
* pY
, ///< [out] Y coord
3678 UINT_32
* pSlice
, ///< [out] slice index
3679 UINT_32
* pSample
, ///< [out] sample index
3680 UINT_32
* pPlane
///< [out] plane index
3683 UINT_32 effectiveBpp
;
3684 UINT_32 effectiveSamples
;
3686 // 2xAA use the same layout as 4xAA
3687 if (numSamples
== 2)
3693 // Compute the number of planes.
3697 effectiveSamples
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3698 effectiveBpp
= numSamples
;
3700 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
3709 ADDR_NON_DISPLAYABLE
,
3722 *pSample
= bitPosition
% numSamples
;
3727 effectiveBpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3728 effectiveSamples
= 1;
3730 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
3739 ADDR_NON_DISPLAYABLE
,
3753 ***************************************************************************************************
3754 * EgBasedAddrLib::DispatchComputeFmaskCoordFromAddr
3757 * Compute (x,y,slice,sample,plane) coordinates from
3762 ***************************************************************************************************
3764 VOID
EgBasedAddrLib::DispatchComputeFmaskCoordFromAddr(
3765 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3766 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3769 UINT_64 addr
= pIn
->addr
;
3770 UINT_32 bitPosition
= pIn
->bitPosition
;
3771 UINT_32 pitch
= pIn
->pitch
;
3772 UINT_32 height
= pIn
->height
;
3773 UINT_32 numSamples
= pIn
->numSamples
;
3774 AddrTileMode tileMode
= pIn
->tileMode
;
3775 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
3776 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
3777 BOOL_32 resolved
= pIn
->resolved
;
3779 UINT_32
* pX
= &pOut
->x
;
3780 UINT_32
* pY
= &pOut
->y
;
3781 UINT_32
* pSlice
= &pOut
->slice
;
3782 UINT_32
* pSample
= &pOut
->sample
;
3783 UINT_32
* pPlane
= &pOut
->plane
;
3787 case ADDR_TM_1D_TILED_THIN1
:
3788 ComputeFmaskCoordFromAddrMicroTiled(addr
,
3801 case ADDR_TM_2D_TILED_THIN1
://fall through
3802 case ADDR_TM_3D_TILED_THIN1
:
3803 UINT_32 pipeSwizzle
;
3804 UINT_32 bankSwizzle
;
3806 if (m_configFlags
.useCombinedSwizzle
)
3808 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
3809 &bankSwizzle
, &pipeSwizzle
);
3813 pipeSwizzle
= pIn
->pipeSwizzle
;
3814 bankSwizzle
= pIn
->bankSwizzle
;
3817 ComputeFmaskCoordFromAddrMacroTiled(addr
,
3835 ADDR_ASSERT_ALWAYS();
3843 ***************************************************************************************************
3844 * EgBasedAddrLib::ComputeFmaskNumPlanesFromNumSamples
3847 * Compute fmask number of planes from number of samples
3851 ***************************************************************************************************
3853 UINT_32
EgBasedAddrLib::ComputeFmaskNumPlanesFromNumSamples(
3854 UINT_32 numSamples
) ///< [in] number of samples
3859 // FMASK is stored such that each micro tile is composed of elements containing N bits, where
3860 // N is the number of samples. There is a micro tile for each bit in the FMASK address, and
3861 // micro tiles for each address bit, sometimes referred to as a plane, are stored sequentially.
3862 // The FMASK for a 2-sample surface looks like a general surface with 2 bits per element.
3863 // The FMASK for a 4-sample surface looks like a general surface with 4 bits per element and
3864 // 2 samples. The FMASK for an 8-sample surface looks like a general surface with 8 bits per
3865 // element and 4 samples. R6xx and R7xx only stored 3 planes for 8-sample FMASK surfaces.
3866 // This was changed for R8xx to simplify the logic in the CB.
3880 ADDR_UNHANDLED_CASE();
3888 ***************************************************************************************************
3889 * EgBasedAddrLib::ComputeFmaskResolvedBppFromNumSamples
3892 * Compute resolved fmask effective bpp based on number of samples
3896 ***************************************************************************************************
3898 UINT_32
EgBasedAddrLib::ComputeFmaskResolvedBppFromNumSamples(
3899 UINT_32 numSamples
) ///< number of samples
3904 // Resolved FMASK surfaces are generated yBit the CB and read yBit the texture unit
3905 // so that the texture unit can read compressed multi-sample color data.
3906 // These surfaces store each index value packed per element.
3907 // Each element contains at least num_samples * log2(num_samples) bits.
3908 // Resolved FMASK surfaces are addressed as follows:
3909 // 2-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3910 // 4-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3911 // 8-sample Addressed similarly to a color surface with 32 bits per element and 1 sample.
3925 ADDR_UNHANDLED_CASE();
3933 ***************************************************************************************************
3934 * EgBasedAddrLib::IsTileInfoAllZero
3937 * Return TRUE if all field are zero
3939 * Since NULL input is consider to be all zero
3940 ***************************************************************************************************
3942 BOOL_32
EgBasedAddrLib::IsTileInfoAllZero(
3943 ADDR_TILEINFO
* pTileInfo
)
3945 BOOL_32 allZero
= TRUE
;
3949 if ((pTileInfo
->banks
!= 0) ||
3950 (pTileInfo
->bankWidth
!= 0) ||
3951 (pTileInfo
->bankHeight
!= 0) ||
3952 (pTileInfo
->macroAspectRatio
!= 0) ||
3953 (pTileInfo
->tileSplitBytes
!= 0) ||
3954 (pTileInfo
->pipeConfig
!= 0)
3965 ***************************************************************************************************
3966 * EgBasedAddrLib::HwlTileInfoEqual
3969 * Return TRUE if all field are equal
3971 * Only takes care of current HWL's data
3972 ***************************************************************************************************
3974 BOOL_32
EgBasedAddrLib::HwlTileInfoEqual(
3975 const ADDR_TILEINFO
* pLeft
, ///<[in] Left compare operand
3976 const ADDR_TILEINFO
* pRight
///<[in] Right compare operand
3979 BOOL_32 equal
= FALSE
;
3981 if (pLeft
->banks
== pRight
->banks
&&
3982 pLeft
->bankWidth
== pRight
->bankWidth
&&
3983 pLeft
->bankHeight
== pRight
->bankHeight
&&
3984 pLeft
->macroAspectRatio
== pRight
->macroAspectRatio
&&
3985 pLeft
->tileSplitBytes
== pRight
->tileSplitBytes
)
3994 ***************************************************************************************************
3995 * EgBasedAddrLib::HwlConvertTileInfoToHW
3997 * Entry of EgBasedAddrLib ConvertTileInfoToHW
4000 ***************************************************************************************************
4002 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlConvertTileInfoToHW(
4003 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
4004 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
4007 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4009 ADDR_TILEINFO
*pTileInfoIn
= pIn
->pTileInfo
;
4010 ADDR_TILEINFO
*pTileInfoOut
= pOut
->pTileInfo
;
4012 if ((pTileInfoIn
!= NULL
) && (pTileInfoOut
!= NULL
))
4014 if (pIn
->reverse
== FALSE
)
4016 switch (pTileInfoIn
->banks
)
4019 pTileInfoOut
->banks
= 0;
4022 pTileInfoOut
->banks
= 1;
4025 pTileInfoOut
->banks
= 2;
4028 pTileInfoOut
->banks
= 3;
4031 ADDR_ASSERT_ALWAYS();
4032 retCode
= ADDR_INVALIDPARAMS
;
4033 pTileInfoOut
->banks
= 0;
4037 switch (pTileInfoIn
->bankWidth
)
4040 pTileInfoOut
->bankWidth
= 0;
4043 pTileInfoOut
->bankWidth
= 1;
4046 pTileInfoOut
->bankWidth
= 2;
4049 pTileInfoOut
->bankWidth
= 3;
4052 ADDR_ASSERT_ALWAYS();
4053 retCode
= ADDR_INVALIDPARAMS
;
4054 pTileInfoOut
->bankWidth
= 0;
4058 switch (pTileInfoIn
->bankHeight
)
4061 pTileInfoOut
->bankHeight
= 0;
4064 pTileInfoOut
->bankHeight
= 1;
4067 pTileInfoOut
->bankHeight
= 2;
4070 pTileInfoOut
->bankHeight
= 3;
4073 ADDR_ASSERT_ALWAYS();
4074 retCode
= ADDR_INVALIDPARAMS
;
4075 pTileInfoOut
->bankHeight
= 0;
4079 switch (pTileInfoIn
->macroAspectRatio
)
4082 pTileInfoOut
->macroAspectRatio
= 0;
4085 pTileInfoOut
->macroAspectRatio
= 1;
4088 pTileInfoOut
->macroAspectRatio
= 2;
4091 pTileInfoOut
->macroAspectRatio
= 3;
4094 ADDR_ASSERT_ALWAYS();
4095 retCode
= ADDR_INVALIDPARAMS
;
4096 pTileInfoOut
->macroAspectRatio
= 0;
4100 switch (pTileInfoIn
->tileSplitBytes
)
4103 pTileInfoOut
->tileSplitBytes
= 0;
4106 pTileInfoOut
->tileSplitBytes
= 1;
4109 pTileInfoOut
->tileSplitBytes
= 2;
4112 pTileInfoOut
->tileSplitBytes
= 3;
4115 pTileInfoOut
->tileSplitBytes
= 4;
4118 pTileInfoOut
->tileSplitBytes
= 5;
4121 pTileInfoOut
->tileSplitBytes
= 6;
4124 ADDR_ASSERT_ALWAYS();
4125 retCode
= ADDR_INVALIDPARAMS
;
4126 pTileInfoOut
->tileSplitBytes
= 0;
4132 switch (pTileInfoIn
->banks
)
4135 pTileInfoOut
->banks
= 2;
4138 pTileInfoOut
->banks
= 4;
4141 pTileInfoOut
->banks
= 8;
4144 pTileInfoOut
->banks
= 16;
4147 ADDR_ASSERT_ALWAYS();
4148 retCode
= ADDR_INVALIDPARAMS
;
4149 pTileInfoOut
->banks
= 2;
4153 switch (pTileInfoIn
->bankWidth
)
4156 pTileInfoOut
->bankWidth
= 1;
4159 pTileInfoOut
->bankWidth
= 2;
4162 pTileInfoOut
->bankWidth
= 4;
4165 pTileInfoOut
->bankWidth
= 8;
4168 ADDR_ASSERT_ALWAYS();
4169 retCode
= ADDR_INVALIDPARAMS
;
4170 pTileInfoOut
->bankWidth
= 1;
4174 switch (pTileInfoIn
->bankHeight
)
4177 pTileInfoOut
->bankHeight
= 1;
4180 pTileInfoOut
->bankHeight
= 2;
4183 pTileInfoOut
->bankHeight
= 4;
4186 pTileInfoOut
->bankHeight
= 8;
4189 ADDR_ASSERT_ALWAYS();
4190 retCode
= ADDR_INVALIDPARAMS
;
4191 pTileInfoOut
->bankHeight
= 1;
4195 switch (pTileInfoIn
->macroAspectRatio
)
4198 pTileInfoOut
->macroAspectRatio
= 1;
4201 pTileInfoOut
->macroAspectRatio
= 2;
4204 pTileInfoOut
->macroAspectRatio
= 4;
4207 pTileInfoOut
->macroAspectRatio
= 8;
4210 ADDR_ASSERT_ALWAYS();
4211 retCode
= ADDR_INVALIDPARAMS
;
4212 pTileInfoOut
->macroAspectRatio
= 1;
4216 switch (pTileInfoIn
->tileSplitBytes
)
4219 pTileInfoOut
->tileSplitBytes
= 64;
4222 pTileInfoOut
->tileSplitBytes
= 128;
4225 pTileInfoOut
->tileSplitBytes
= 256;
4228 pTileInfoOut
->tileSplitBytes
= 512;
4231 pTileInfoOut
->tileSplitBytes
= 1024;
4234 pTileInfoOut
->tileSplitBytes
= 2048;
4237 pTileInfoOut
->tileSplitBytes
= 4096;
4240 ADDR_ASSERT_ALWAYS();
4241 retCode
= ADDR_INVALIDPARAMS
;
4242 pTileInfoOut
->tileSplitBytes
= 64;
4247 if (pTileInfoIn
!= pTileInfoOut
)
4249 pTileInfoOut
->pipeConfig
= pTileInfoIn
->pipeConfig
;
4254 ADDR_ASSERT_ALWAYS();
4255 retCode
= ADDR_INVALIDPARAMS
;
4262 ***************************************************************************************************
4263 * EgBasedAddrLib::HwlComputeSurfaceInfo
4265 * Entry of EgBasedAddrLib ComputeSurfaceInfo
4268 ***************************************************************************************************
4270 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeSurfaceInfo(
4271 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
4272 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
4275 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4277 if (pIn
->numSamples
< pIn
->numFrags
)
4279 retCode
= ADDR_INVALIDPARAMS
;
4282 ADDR_TILEINFO tileInfo
= {0};
4284 if (retCode
== ADDR_OK
)
4286 // Uses internal tile info if pOut does not have a valid pTileInfo
4287 if (pOut
->pTileInfo
== NULL
)
4289 pOut
->pTileInfo
= &tileInfo
;
4292 if (!DispatchComputeSurfaceInfo(pIn
, pOut
))
4294 retCode
= ADDR_INVALIDPARAMS
;
4298 pOut
->tileIndex
= HwlPostCheckTileIndex(pOut
->pTileInfo
,
4303 if (IsMacroTiled(pOut
->tileMode
) && (pOut
->macroModeIndex
== TileIndexInvalid
))
4305 pOut
->macroModeIndex
= HwlComputeMacroModeIndex(pOut
->tileIndex
,
4312 // Resets pTileInfo to NULL if the internal tile info is used
4313 if (pOut
->pTileInfo
== &tileInfo
)
4316 // Client does not pass in a valid pTileInfo
4317 if (IsMacroTiled(pOut
->tileMode
))
4319 // If a valid index is returned, then no pTileInfo is okay
4320 ADDR_ASSERT(!m_configFlags
.useTileIndex
|| pOut
->tileIndex
!= TileIndexInvalid
);
4322 if (!IsTileInfoAllZero(pIn
->pTileInfo
))
4324 // The initial value of pIn->pTileInfo is copied to tileInfo
4325 // We do not expect any of these value to be changed nor any 0 of inputs
4326 ADDR_ASSERT(tileInfo
.banks
== pIn
->pTileInfo
->banks
);
4327 ADDR_ASSERT(tileInfo
.bankWidth
== pIn
->pTileInfo
->bankWidth
);
4328 ADDR_ASSERT(tileInfo
.bankHeight
== pIn
->pTileInfo
->bankHeight
);
4329 ADDR_ASSERT(tileInfo
.macroAspectRatio
== pIn
->pTileInfo
->macroAspectRatio
);
4330 ADDR_ASSERT(tileInfo
.tileSplitBytes
== pIn
->pTileInfo
->tileSplitBytes
);
4334 pOut
->pTileInfo
= NULL
;
4342 ***************************************************************************************************
4343 * EgBasedAddrLib::HwlComputeSurfaceAddrFromCoord
4345 * Entry of EgBasedAddrLib ComputeSurfaceAddrFromCoord
4348 ***************************************************************************************************
4350 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeSurfaceAddrFromCoord(
4351 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
4352 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
4355 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4358 #if !ALT_TEST // Overflow test needs this out-of-boundary coord
4359 (pIn
->x
> pIn
->pitch
) ||
4360 (pIn
->y
> pIn
->height
) ||
4362 (pIn
->numSamples
> m_maxSamples
))
4364 retCode
= ADDR_INVALIDPARAMS
;
4368 pOut
->addr
= DispatchComputeSurfaceAddrFromCoord(pIn
, pOut
);
4375 ***************************************************************************************************
4376 * EgBasedAddrLib::HwlComputeSurfaceCoordFromAddr
4378 * Entry of EgBasedAddrLib ComputeSurfaceCoordFromAddr
4381 ***************************************************************************************************
4383 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeSurfaceCoordFromAddr(
4384 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
4385 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
4388 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4390 if ((pIn
->bitPosition
>= 8) ||
4391 (pIn
->numSamples
> m_maxSamples
))
4393 retCode
= ADDR_INVALIDPARAMS
;
4397 DispatchComputeSurfaceCoordFromAddr(pIn
, pOut
);
4403 ***************************************************************************************************
4404 * EgBasedAddrLib::HwlComputeSliceTileSwizzle
4406 * Entry of EgBasedAddrLib ComputeSurfaceCoordFromAddr
4409 ***************************************************************************************************
4411 ADDR_E_RETURNCODE
EgBasedAddrLib::HwlComputeSliceTileSwizzle(
4412 const ADDR_COMPUTE_SLICESWIZZLE_INPUT
* pIn
, ///< [in] input structure
4413 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
* pOut
///< [out] output structure
4416 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
4418 if (pIn
->pTileInfo
&& (pIn
->pTileInfo
->banks
> 0))
4421 pOut
->tileSwizzle
= ComputeSliceTileSwizzle(pIn
->tileMode
,
4429 retCode
= ADDR_INVALIDPARAMS
;
4436 ***************************************************************************************************
4437 * EgBasedAddrLib::HwlComputeHtileBpp
4444 ***************************************************************************************************
4446 UINT_32
EgBasedAddrLib::HwlComputeHtileBpp(
4447 BOOL_32 isWidth8
, ///< [in] TRUE if block width is 8
4448 BOOL_32 isHeight8
///< [in] TRUE if block height is 8
4451 // only support 8x8 mode
4452 ADDR_ASSERT(isWidth8
&& isHeight8
);
4457 ***************************************************************************************************
4458 * EgBasedAddrLib::HwlComputeHtileBaseAlign
4461 * Compute htile base alignment
4464 * Htile base alignment
4465 ***************************************************************************************************
4467 UINT_32
EgBasedAddrLib::HwlComputeHtileBaseAlign(
4468 BOOL_32 isTcCompatible
, ///< [in] if TC compatible
4469 BOOL_32 isLinear
, ///< [in] if it is linear mode
4470 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
4473 UINT_32 baseAlign
= m_pipeInterleaveBytes
* HwlGetPipes(pTileInfo
);
4477 ADDR_ASSERT(pTileInfo
!= NULL
);
4480 baseAlign
*= pTileInfo
->banks
;
4488 ***************************************************************************************************
4489 * EgBasedAddrLib::HwlGetPitchAlignmentMicroTiled
4492 * Compute 1D tiled surface pitch alignment, calculation results are returned through
4493 * output parameters.
4497 ***************************************************************************************************
4499 UINT_32
EgBasedAddrLib::HwlGetPitchAlignmentMicroTiled(
4500 AddrTileMode tileMode
, ///< [in] tile mode
4501 UINT_32 bpp
, ///< [in] bits per pixel
4502 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4503 UINT_32 numSamples
///< [in] number of samples
4508 UINT_32 microTileThickness
= ComputeSurfaceThickness(tileMode
);
4510 UINT_32 pixelsPerMicroTile
;
4511 UINT_32 pixelsPerPipeInterleave
;
4512 UINT_32 microTilesPerPipeInterleave
;
4515 // Special workaround for depth/stencil buffer, use 8 bpp to meet larger requirement for
4516 // stencil buffer since pitch alignment is related to bpp.
4517 // For a depth only buffer do not set this.
4519 // Note: this actually does not work for mipmap but mipmap depth texture is not really
4520 // sampled with mipmap.
4522 if (flags
.depth
&& !flags
.noStencil
)
4527 pixelsPerMicroTile
= MicroTilePixels
* microTileThickness
;
4528 pixelsPerPipeInterleave
= BYTES_TO_BITS(m_pipeInterleaveBytes
) / (bpp
* numSamples
);
4529 microTilesPerPipeInterleave
= pixelsPerPipeInterleave
/ pixelsPerMicroTile
;
4531 pitchAlign
= Max(MicroTileWidth
, microTilesPerPipeInterleave
* MicroTileWidth
);
4537 ***************************************************************************************************
4538 * EgBasedAddrLib::HwlGetSizeAdjustmentMicroTiled
4541 * Adjust 1D tiled surface pitch and slice size
4544 * Logical slice size in bytes
4545 ***************************************************************************************************
4547 UINT_64
EgBasedAddrLib::HwlGetSizeAdjustmentMicroTiled(
4548 UINT_32 thickness
, ///< [in] thickness
4549 UINT_32 bpp
, ///< [in] bits per pixel
4550 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4551 UINT_32 numSamples
, ///< [in] number of samples
4552 UINT_32 baseAlign
, ///< [in] base alignment
4553 UINT_32 pitchAlign
, ///< [in] pitch alignment
4554 UINT_32
* pPitch
, ///< [in/out] pointer to pitch
4555 UINT_32
* pHeight
///< [in/out] pointer to height
4558 UINT_64 logicalSliceSize
;
4559 UINT_64 physicalSliceSize
;
4561 UINT_32 pitch
= *pPitch
;
4562 UINT_32 height
= *pHeight
;
4564 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
4565 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
4567 // Physical slice: multiplied by thickness
4568 physicalSliceSize
= logicalSliceSize
* thickness
;
4571 // R800 will always pad physical slice size to baseAlign which is pipe_interleave_bytes
4573 ADDR_ASSERT((physicalSliceSize
% baseAlign
) == 0)
4575 return logicalSliceSize
;