2 * Copyright © 2014 Advanced Micro Devices, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
28 ****************************************************************************************************
29 * @file egbaddrlib.cpp
30 * @brief Contains the EgBasedLib class implementation.
31 ****************************************************************************************************
34 #include "egbaddrlib.h"
42 ****************************************************************************************************
43 * EgBasedLib::EgBasedLib
50 ****************************************************************************************************
52 EgBasedLib::EgBasedLib(const Client
* pClient
)
62 ****************************************************************************************************
63 * EgBasedLib::~EgBasedLib
67 ****************************************************************************************************
69 EgBasedLib::~EgBasedLib()
74 ****************************************************************************************************
75 * EgBasedLib::DispatchComputeSurfaceInfo
78 * Compute surface sizes include padded pitch,height,slices,total size in bytes,
79 * meanwhile output suitable tile mode and base alignment might be changed in this
80 * call as well. Results are returned through output parameters.
83 * TRUE if no error occurs
84 ****************************************************************************************************
86 BOOL_32
EgBasedLib::DispatchComputeSurfaceInfo(
87 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
88 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
91 AddrTileMode tileMode
= pIn
->tileMode
;
92 UINT_32 bpp
= pIn
->bpp
;
93 UINT_32 numSamples
= pIn
->numSamples
;
94 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
95 UINT_32 pitch
= pIn
->width
;
96 UINT_32 height
= pIn
->height
;
97 UINT_32 numSlices
= pIn
->numSlices
;
98 UINT_32 mipLevel
= pIn
->mipLevel
;
99 ADDR_SURFACE_FLAGS flags
= pIn
->flags
;
101 ADDR_TILEINFO tileInfoDef
= {0};
102 ADDR_TILEINFO
* pTileInfo
= &tileInfoDef
;
107 tileMode
= DegradeLargeThickTile(tileMode
, bpp
);
109 // Only override numSamples for NI above
110 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
112 if (numFrags
!= numSamples
) // This means EQAA
114 // The real surface size needed is determined by number of fragments
115 numSamples
= numFrags
;
118 // Save altered numSamples in pOut
119 pOut
->numSamples
= numSamples
;
122 // Caller makes sure pOut->pTileInfo is not NULL, see HwlComputeSurfaceInfo
123 ADDR_ASSERT(pOut
->pTileInfo
);
125 if (pOut
->pTileInfo
!= NULL
)
127 pTileInfo
= pOut
->pTileInfo
;
130 // Set default values
131 if (pIn
->pTileInfo
!= NULL
)
133 if (pTileInfo
!= pIn
->pTileInfo
)
135 *pTileInfo
= *pIn
->pTileInfo
;
140 memset(pTileInfo
, 0, sizeof(ADDR_TILEINFO
));
143 // For macro tile mode, we should calculate default tiling parameters
144 HwlSetupTileInfo(tileMode
,
164 // This is calculating one face, remove cube flag
171 case ADDR_TM_LINEAR_GENERAL
://fall through
172 case ADDR_TM_LINEAR_ALIGNED
:
173 valid
= ComputeSurfaceInfoLinear(pIn
, pOut
, padDims
);
176 case ADDR_TM_1D_TILED_THIN1
://fall through
177 case ADDR_TM_1D_TILED_THICK
:
178 valid
= ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, tileMode
);
181 case ADDR_TM_2D_TILED_THIN1
: //fall through
182 case ADDR_TM_2D_TILED_THICK
: //fall through
183 case ADDR_TM_3D_TILED_THIN1
: //fall through
184 case ADDR_TM_3D_TILED_THICK
: //fall through
185 case ADDR_TM_2D_TILED_XTHICK
: //fall through
186 case ADDR_TM_3D_TILED_XTHICK
: //fall through
187 case ADDR_TM_PRT_TILED_THIN1
: //fall through
188 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
189 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
190 case ADDR_TM_PRT_TILED_THICK
: //fall through
191 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
192 case ADDR_TM_PRT_3D_TILED_THICK
:
193 valid
= ComputeSurfaceInfoMacroTiled(pIn
, pOut
, padDims
, tileMode
);
198 ADDR_ASSERT_ALWAYS();
206 ****************************************************************************************************
207 * EgBasedLib::ComputeSurfaceInfoLinear
210 * Compute linear surface sizes include padded pitch, height, slices, total size in
211 * bytes, meanwhile alignments as well. Since it is linear mode, so output tile mode
212 * will not be changed here. Results are returned through output parameters.
215 * TRUE if no error occurs
216 ****************************************************************************************************
218 BOOL_32
EgBasedLib::ComputeSurfaceInfoLinear(
219 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
220 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
221 UINT_32 padDims
///< [in] Dimensions to padd
224 UINT_32 expPitch
= pIn
->width
;
225 UINT_32 expHeight
= pIn
->height
;
226 UINT_32 expNumSlices
= pIn
->numSlices
;
228 // No linear MSAA on real H/W, keep this for TGL
229 UINT_32 numSamples
= pOut
->numSamples
;
231 const UINT_32 microTileThickness
= 1;
234 // Compute the surface alignments.
236 ComputeSurfaceAlignmentsLinear(pIn
->tileMode
,
243 if ((pIn
->tileMode
== ADDR_TM_LINEAR_GENERAL
) && pIn
->flags
.color
&& (pIn
->height
> 1))
246 // When linear_general surface is accessed in multiple lines, it requires 8 pixels in pitch
247 // alignment since PITCH_TILE_MAX is in unit of 8 pixels.
248 // It is OK if it is accessed per line.
249 ADDR_ASSERT((pIn
->width
% 8) == 0);
253 pOut
->depthAlign
= microTileThickness
;
255 expPitch
= HwlPreHandleBaseLvl3xPitch(pIn
, expPitch
);
258 // Pad pitch and height to the required granularities.
260 PadDimensions(pIn
->tileMode
,
267 &expPitch
, &pOut
->pitchAlign
,
268 &expHeight
, pOut
->heightAlign
,
269 &expNumSlices
, microTileThickness
);
271 expPitch
= HwlPostHandleBaseLvl3xPitch(pIn
, expPitch
);
277 UINT_64 logicalSliceSize
;
279 logicalSliceSize
= HwlGetSizeAdjustmentLinear(pIn
->tileMode
,
288 if ((pIn
->pitchAlign
!= 0) || (pIn
->heightAlign
!= 0))
290 if (pIn
->pitchAlign
!= 0)
292 ADDR_ASSERT((pIn
->pitchAlign
% pOut
->pitchAlign
) == 0);
293 pOut
->pitchAlign
= pIn
->pitchAlign
;
295 if (IsPow2(pOut
->pitchAlign
))
297 expPitch
= PowTwoAlign(expPitch
, pOut
->pitchAlign
);
301 expPitch
+= pOut
->pitchAlign
- 1;
302 expPitch
/= pOut
->pitchAlign
;
303 expPitch
*= pOut
->pitchAlign
;
307 if (pIn
->heightAlign
!= 0)
309 ADDR_ASSERT((pIn
->heightAlign
% pOut
->heightAlign
) == 0);
310 pOut
->heightAlign
= pIn
->heightAlign
;
312 if (IsPow2(pOut
->heightAlign
))
314 expHeight
= PowTwoAlign(expHeight
, pOut
->heightAlign
);
318 expHeight
+= pOut
->heightAlign
- 1;
319 expHeight
/= pOut
->heightAlign
;
320 expHeight
*= pOut
->heightAlign
;
324 logicalSliceSize
= BITS_TO_BYTES(expPitch
* expHeight
* pIn
->bpp
);
327 pOut
->pitch
= expPitch
;
328 pOut
->height
= expHeight
;
329 pOut
->depth
= expNumSlices
;
331 pOut
->surfSize
= logicalSliceSize
* expNumSlices
;
333 pOut
->tileMode
= pIn
->tileMode
;
339 ****************************************************************************************************
340 * EgBasedLib::ComputeSurfaceInfoMicroTiled
343 * Compute 1D/Micro Tiled surface sizes include padded pitch, height, slices, total
344 * size in bytes, meanwhile alignments as well. Results are returned through output
348 * TRUE if no error occurs
349 ****************************************************************************************************
351 BOOL_32
EgBasedLib::ComputeSurfaceInfoMicroTiled(
352 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
353 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
354 UINT_32 padDims
, ///< [in] Dimensions to padd
355 AddrTileMode expTileMode
///< [in] Expected tile mode
358 BOOL_32 valid
= TRUE
;
360 UINT_32 microTileThickness
;
361 UINT_32 expPitch
= pIn
->width
;
362 UINT_32 expHeight
= pIn
->height
;
363 UINT_32 expNumSlices
= pIn
->numSlices
;
365 // No 1D MSAA on real H/W, keep this for TGL
366 UINT_32 numSamples
= pOut
->numSamples
;
369 // Compute the micro tile thickness.
371 microTileThickness
= Thickness(expTileMode
);
374 // Extra override for mip levels
376 if (pIn
->mipLevel
> 0)
379 // Reduce tiling mode from thick to thin if the number of slices is less than the
380 // micro tile thickness.
382 if ((expTileMode
== ADDR_TM_1D_TILED_THICK
) &&
383 (expNumSlices
< ThickTileThickness
))
385 expTileMode
= HwlDegradeThickTileMode(ADDR_TM_1D_TILED_THICK
, expNumSlices
, NULL
);
386 if (expTileMode
!= ADDR_TM_1D_TILED_THICK
)
388 microTileThickness
= 1;
394 // Compute the surface restrictions.
396 ComputeSurfaceAlignmentsMicroTiled(expTileMode
,
405 pOut
->depthAlign
= microTileThickness
;
408 // Pad pitch and height to the required granularities.
409 // Compute surface size.
410 // Return parameters.
412 PadDimensions(expTileMode
,
419 &expPitch
, &pOut
->pitchAlign
,
420 &expHeight
, pOut
->heightAlign
,
421 &expNumSlices
, microTileThickness
);
424 // Get HWL specific pitch adjustment
426 UINT_64 logicalSliceSize
= HwlGetSizeAdjustmentMicroTiled(microTileThickness
,
436 pOut
->pitch
= expPitch
;
437 pOut
->height
= expHeight
;
438 pOut
->depth
= expNumSlices
;
440 pOut
->surfSize
= logicalSliceSize
* expNumSlices
;
442 pOut
->tileMode
= expTileMode
;
449 ****************************************************************************************************
450 * EgBasedLib::ComputeSurfaceInfoMacroTiled
453 * Compute 2D/macro tiled surface sizes include padded pitch, height, slices, total
454 * size in bytes, meanwhile output suitable tile mode and alignments might be changed
455 * in this call as well. Results are returned through output parameters.
458 * TRUE if no error occurs
459 ****************************************************************************************************
461 BOOL_32
EgBasedLib::ComputeSurfaceInfoMacroTiled(
462 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
463 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
464 UINT_32 padDims
, ///< [in] Dimensions to padd
465 AddrTileMode expTileMode
///< [in] Expected tile mode
468 BOOL_32 valid
= TRUE
;
470 AddrTileMode origTileMode
= expTileMode
;
471 UINT_32 microTileThickness
;
474 UINT_32 paddedHeight
;
475 UINT_64 bytesPerSlice
;
477 UINT_32 expPitch
= pIn
->width
;
478 UINT_32 expHeight
= pIn
->height
;
479 UINT_32 expNumSlices
= pIn
->numSlices
;
481 UINT_32 numSamples
= pOut
->numSamples
;
484 // Compute the surface restrictions as base
485 // SanityCheckMacroTiled is called in ComputeSurfaceAlignmentsMacroTiled
487 valid
= ComputeSurfaceAlignmentsMacroTiled(expTileMode
,
497 // Compute the micro tile thickness.
499 microTileThickness
= Thickness(expTileMode
);
502 // Find the correct tiling mode for mip levels
504 if (pIn
->mipLevel
> 0)
507 // Try valid tile mode
509 expTileMode
= ComputeSurfaceMipLevelTileMode(expTileMode
,
519 if (!IsMacroTiled(expTileMode
)) // Downgraded to micro-tiled
521 return ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, expTileMode
);
523 else if (microTileThickness
!= Thickness(expTileMode
))
526 // Re-compute if thickness changed since bank-height may be changed!
528 return ComputeSurfaceInfoMacroTiled(pIn
, pOut
, padDims
, expTileMode
);
532 paddedPitch
= expPitch
;
533 paddedHeight
= expHeight
;
538 if (expTileMode
!= origTileMode
) // Tile mode is changed but still macro-tiled
540 valid
= ComputeSurfaceAlignmentsMacroTiled(expTileMode
,
551 PadDimensions(expTileMode
,
558 &paddedPitch
, &pOut
->pitchAlign
,
559 &paddedHeight
, pOut
->heightAlign
,
560 &expNumSlices
, microTileThickness
);
562 if (pIn
->flags
.qbStereo
&&
563 (pOut
->pStereoInfo
!= NULL
))
565 UINT_32 stereoHeightAlign
= HwlStereoCheckRightOffsetPadding(pOut
->pTileInfo
);
567 if (stereoHeightAlign
!= 0)
569 paddedHeight
= PowTwoAlign(paddedHeight
, stereoHeightAlign
);
573 if ((pIn
->flags
.needEquation
== TRUE
) &&
574 (m_chipFamily
== ADDR_CHIP_FAMILY_SI
) &&
575 (pIn
->numMipLevels
> 1) &&
576 (pIn
->mipLevel
== 0))
578 BOOL_32 convertTo1D
= FALSE
;
580 ADDR_ASSERT(Thickness(expTileMode
) == 1);
582 for (UINT_32 i
= 1; i
< pIn
->numMipLevels
; i
++)
584 UINT_32 mipPitch
= Max(1u, paddedPitch
>> i
);
585 UINT_32 mipHeight
= Max(1u, pIn
->height
>> i
);
586 UINT_32 mipSlices
= pIn
->flags
.volume
?
587 Max(1u, pIn
->numSlices
>> i
) : pIn
->numSlices
;
588 expTileMode
= ComputeSurfaceMipLevelTileMode(expTileMode
,
598 if (IsMacroTiled(expTileMode
))
600 if (PowTwoAlign(mipPitch
, pOut
->blockWidth
) !=
601 PowTwoAlign(mipPitch
, pOut
->pitchAlign
))
615 return ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, ADDR_TM_1D_TILED_THIN1
);
619 pOut
->pitch
= paddedPitch
;
620 // Put this check right here to workaround special mipmap cases which the original height
622 // The original height is pre-stored in pOut->height in PostComputeMipLevel and
623 // pOut->pitch is needed in HwlCheckLastMacroTiledLvl, too.
624 if (m_configFlags
.checkLast2DLevel
&& (numSamples
== 1)) // Don't check MSAA
626 // Set a TRUE in pOut if next Level is the first 1D sub level
627 HwlCheckLastMacroTiledLvl(pIn
, pOut
);
629 pOut
->height
= paddedHeight
;
631 pOut
->depth
= expNumSlices
;
634 // Compute the size of a slice.
636 bytesPerSlice
= BITS_TO_BYTES(static_cast<UINT_64
>(paddedPitch
) *
637 paddedHeight
* NextPow2(pIn
->bpp
) * numSamples
);
639 pOut
->surfSize
= bytesPerSlice
* expNumSlices
;
641 pOut
->tileMode
= expTileMode
;
643 pOut
->depthAlign
= microTileThickness
;
651 ****************************************************************************************************
652 * EgBasedLib::ComputeSurfaceAlignmentsLinear
655 * Compute linear surface alignment, calculation results are returned through
659 * TRUE if no error occurs
660 ****************************************************************************************************
662 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsLinear(
663 AddrTileMode tileMode
, ///< [in] tile mode
664 UINT_32 bpp
, ///< [in] bits per pixel
665 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
666 UINT_32
* pBaseAlign
, ///< [out] base address alignment in bytes
667 UINT_32
* pPitchAlign
, ///< [out] pitch alignment in pixels
668 UINT_32
* pHeightAlign
///< [out] height alignment in pixels
671 BOOL_32 valid
= TRUE
;
675 case ADDR_TM_LINEAR_GENERAL
:
677 // The required base alignment and pitch and height granularities is to 1 element.
679 *pBaseAlign
= (bpp
> 8) ? bpp
/ 8 : 1;
683 case ADDR_TM_LINEAR_ALIGNED
:
685 // The required alignment for base is the pipe interleave size.
686 // The required granularity for pitch is hwl dependent.
687 // The required granularity for height is one row.
689 *pBaseAlign
= m_pipeInterleaveBytes
;
690 *pPitchAlign
= HwlGetPitchAlignmentLinear(bpp
, flags
);
697 ADDR_UNHANDLED_CASE();
701 AdjustPitchAlignment(flags
, pPitchAlign
);
707 ****************************************************************************************************
708 * EgBasedLib::ComputeSurfaceAlignmentsMicroTiled
711 * Compute 1D tiled surface alignment, calculation results are returned through
715 * TRUE if no error occurs
716 ****************************************************************************************************
718 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsMicroTiled(
719 AddrTileMode tileMode
, ///< [in] tile mode
720 UINT_32 bpp
, ///< [in] bits per pixel
721 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
722 UINT_32 mipLevel
, ///< [in] mip level
723 UINT_32 numSamples
, ///< [in] number of samples
724 UINT_32
* pBaseAlign
, ///< [out] base address alignment in bytes
725 UINT_32
* pPitchAlign
, ///< [out] pitch alignment in pixels
726 UINT_32
* pHeightAlign
///< [out] height alignment in pixels
729 BOOL_32 valid
= TRUE
;
732 // The required alignment for base is the pipe interleave size.
734 *pBaseAlign
= m_pipeInterleaveBytes
;
736 *pPitchAlign
= HwlGetPitchAlignmentMicroTiled(tileMode
, bpp
, flags
, numSamples
);
738 *pHeightAlign
= MicroTileHeight
;
740 AdjustPitchAlignment(flags
, pPitchAlign
);
742 // Workaround 2 for 1D tiling - There is HW bug for Carrizo,
743 // where it requires the following alignments for 1D tiling.
744 if (flags
.czDispCompatible
&& (mipLevel
== 0))
746 *pBaseAlign
= PowTwoAlign(*pBaseAlign
, 4096); //Base address MOD 4096 = 0
747 *pPitchAlign
= PowTwoAlign(*pPitchAlign
, 512 / (BITS_TO_BYTES(bpp
))); //(8 lines * pitch * bytes per pixel) MOD 4096 = 0
749 // end Carrizo workaround for 1D tilling
756 ****************************************************************************************************
757 * EgBasedLib::HwlReduceBankWidthHeight
760 * Additional checks, reduce bankHeight/bankWidth if needed and possible
761 * tileSize*BANK_WIDTH*BANK_HEIGHT <= ROW_SIZE
764 * TRUE if no error occurs
765 ****************************************************************************************************
767 BOOL_32
EgBasedLib::HwlReduceBankWidthHeight(
768 UINT_32 tileSize
, ///< [in] tile size
769 UINT_32 bpp
, ///< [in] bits per pixel
770 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
771 UINT_32 numSamples
, ///< [in] number of samples
772 UINT_32 bankHeightAlign
, ///< [in] bank height alignment
773 UINT_32 pipes
, ///< [in] pipes
774 ADDR_TILEINFO
* pTileInfo
///< [in,out] bank structure.
777 UINT_32 macroAspectAlign
;
778 BOOL_32 valid
= TRUE
;
780 if (tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
)
782 BOOL_32 stillGreater
= TRUE
;
784 // Try reducing bankWidth first
785 if (stillGreater
&& pTileInfo
->bankWidth
> 1)
787 while (stillGreater
&& pTileInfo
->bankWidth
> 0)
789 pTileInfo
->bankWidth
>>= 1;
791 if (pTileInfo
->bankWidth
== 0)
793 pTileInfo
->bankWidth
= 1;
798 tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
;
801 // bankWidth is reduced above, so we need to recalculate bankHeight and ratio
802 bankHeightAlign
= Max(1u,
803 m_pipeInterleaveBytes
* m_bankInterleave
/
804 (tileSize
* pTileInfo
->bankWidth
)
807 // We cannot increase bankHeight so just assert this case.
808 ADDR_ASSERT((pTileInfo
->bankHeight
% bankHeightAlign
) == 0);
812 macroAspectAlign
= Max(1u,
813 m_pipeInterleaveBytes
* m_bankInterleave
/
814 (tileSize
* pipes
* pTileInfo
->bankWidth
)
816 pTileInfo
->macroAspectRatio
= PowTwoAlign(pTileInfo
->macroAspectRatio
,
821 // Early quit bank_height degradation for "64" bit z buffer
822 if (flags
.depth
&& bpp
>= 64)
824 stillGreater
= FALSE
;
827 // Then try reducing bankHeight
828 if (stillGreater
&& pTileInfo
->bankHeight
> bankHeightAlign
)
830 while (stillGreater
&& pTileInfo
->bankHeight
> bankHeightAlign
)
832 pTileInfo
->bankHeight
>>= 1;
834 if (pTileInfo
->bankHeight
< bankHeightAlign
)
836 pTileInfo
->bankHeight
= bankHeightAlign
;
841 tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
;
845 valid
= !stillGreater
;
847 // Generate a warning if we still fail to meet this constraint
851 0, ("TILE_SIZE(%d)*BANK_WIDTH(%d)*BANK_HEIGHT(%d) <= ROW_SIZE(%d)",
852 tileSize
, pTileInfo
->bankWidth
, pTileInfo
->bankHeight
, m_rowSize
));
860 ****************************************************************************************************
861 * EgBasedLib::ComputeSurfaceAlignmentsMacroTiled
864 * Compute 2D tiled surface alignment, calculation results are returned through
868 * TRUE if no error occurs
869 ****************************************************************************************************
871 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsMacroTiled(
872 AddrTileMode tileMode
, ///< [in] tile mode
873 UINT_32 bpp
, ///< [in] bits per pixel
874 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
875 UINT_32 mipLevel
, ///< [in] mip level
876 UINT_32 numSamples
, ///< [in] number of samples
877 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in,out] Surface output
880 ADDR_TILEINFO
* pTileInfo
= pOut
->pTileInfo
;
882 BOOL_32 valid
= SanityCheckMacroTiled(pTileInfo
);
886 UINT_32 macroTileWidth
;
887 UINT_32 macroTileHeight
;
890 UINT_32 bankHeightAlign
;
891 UINT_32 macroAspectAlign
;
893 UINT_32 thickness
= Thickness(tileMode
);
894 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
897 // Align bank height first according to latest h/w spec
900 // tile_size = MIN(tile_split, 64 * tile_thickness * element_bytes * num_samples)
901 tileSize
= Min(pTileInfo
->tileSplitBytes
,
902 BITS_TO_BYTES(64 * thickness
* bpp
* numSamples
));
904 // bank_height_align =
905 // MAX(1, (pipe_interleave_bytes * bank_interleave)/(tile_size*bank_width))
906 bankHeightAlign
= Max(1u,
907 m_pipeInterleaveBytes
* m_bankInterleave
/
908 (tileSize
* pTileInfo
->bankWidth
)
911 pTileInfo
->bankHeight
= PowTwoAlign(pTileInfo
->bankHeight
, bankHeightAlign
);
913 // num_pipes * bank_width * macro_tile_aspect >=
914 // (pipe_interleave_size * bank_interleave) / tile_size
917 // this restriction is only for mipmap (mipmap's numSamples must be 1)
918 macroAspectAlign
= Max(1u,
919 m_pipeInterleaveBytes
* m_bankInterleave
/
920 (tileSize
* pipes
* pTileInfo
->bankWidth
)
922 pTileInfo
->macroAspectRatio
= PowTwoAlign(pTileInfo
->macroAspectRatio
, macroAspectAlign
);
925 valid
= HwlReduceBankWidthHeight(tileSize
,
934 // The required granularity for pitch is the macro tile width.
936 macroTileWidth
= MicroTileWidth
* pTileInfo
->bankWidth
* pipes
*
937 pTileInfo
->macroAspectRatio
;
939 pOut
->pitchAlign
= macroTileWidth
;
940 pOut
->blockWidth
= macroTileWidth
;
942 AdjustPitchAlignment(flags
, &pOut
->pitchAlign
);
945 // The required granularity for height is the macro tile height.
947 macroTileHeight
= MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
/
948 pTileInfo
->macroAspectRatio
;
950 pOut
->heightAlign
= macroTileHeight
;
951 pOut
->blockHeight
= macroTileHeight
;
954 // Compute base alignment
957 pipes
* pTileInfo
->bankWidth
* pTileInfo
->banks
* pTileInfo
->bankHeight
* tileSize
;
959 HwlComputeSurfaceAlignmentsMacroTiled(tileMode
, bpp
, flags
, mipLevel
, numSamples
, pOut
);
966 ****************************************************************************************************
967 * EgBasedLib::SanityCheckMacroTiled
970 * Check if macro-tiled parameters are valid
973 ****************************************************************************************************
975 BOOL_32
EgBasedLib::SanityCheckMacroTiled(
976 ADDR_TILEINFO
* pTileInfo
///< [in] macro-tiled parameters
979 BOOL_32 valid
= TRUE
;
980 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
982 switch (pTileInfo
->banks
)
984 case 2: //fall through
985 case 4: //fall through
986 case 8: //fall through
997 switch (pTileInfo
->bankWidth
)
999 case 1: //fall through
1000 case 2: //fall through
1001 case 4: //fall through
1012 switch (pTileInfo
->bankHeight
)
1014 case 1: //fall through
1015 case 2: //fall through
1016 case 4: //fall through
1027 switch (pTileInfo
->macroAspectRatio
)
1029 case 1: //fall through
1030 case 2: //fall through
1031 case 4: //fall through
1042 if (pTileInfo
->banks
< pTileInfo
->macroAspectRatio
)
1044 // This will generate macro tile height <= 1
1051 if (pTileInfo
->tileSplitBytes
> m_rowSize
)
1053 ADDR_WARN(0, ("tileSplitBytes is bigger than row size"));
1059 valid
= HwlSanityCheckMacroTiled(pTileInfo
);
1062 ADDR_ASSERT(valid
== TRUE
);
1064 // Add this assert for guidance
1065 ADDR_ASSERT(numPipes
* pTileInfo
->banks
>= 4);
1071 ****************************************************************************************************
1072 * EgBasedLib::ComputeSurfaceMipLevelTileMode
1075 * Compute valid tile mode for surface mipmap sub-levels
1078 * Suitable tile mode
1079 ****************************************************************************************************
1081 AddrTileMode
EgBasedLib::ComputeSurfaceMipLevelTileMode(
1082 AddrTileMode baseTileMode
, ///< [in] base tile mode
1083 UINT_32 bpp
, ///< [in] bits per pixels
1084 UINT_32 pitch
, ///< [in] current level pitch
1085 UINT_32 height
, ///< [in] current level height
1086 UINT_32 numSlices
, ///< [in] current number of slices
1087 UINT_32 numSamples
, ///< [in] number of samples
1088 UINT_32 pitchAlign
, ///< [in] pitch alignment
1089 UINT_32 heightAlign
, ///< [in] height alignment
1090 ADDR_TILEINFO
* pTileInfo
///< [in] ptr to bank structure
1093 UINT_64 bytesPerSlice
;
1094 (void)bytesPerSlice
;
1095 UINT_32 bytesPerTile
;
1097 AddrTileMode expTileMode
= baseTileMode
;
1098 UINT_32 microTileThickness
= Thickness(expTileMode
);
1099 UINT_32 interleaveSize
= m_pipeInterleaveBytes
* m_bankInterleave
;
1102 // Compute the size of a slice.
1104 bytesPerSlice
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
1105 bytesPerTile
= BITS_TO_BYTES(MicroTilePixels
* microTileThickness
* NextPow2(bpp
) * numSamples
);
1108 // Reduce tiling mode from thick to thin if the number of slices is less than the
1109 // micro tile thickness.
1111 if (numSlices
< microTileThickness
)
1113 expTileMode
= HwlDegradeThickTileMode(expTileMode
, numSlices
, &bytesPerTile
);
1116 if (bytesPerTile
> pTileInfo
->tileSplitBytes
)
1118 bytesPerTile
= pTileInfo
->tileSplitBytes
;
1121 UINT_32 threshold1
=
1122 bytesPerTile
* HwlGetPipes(pTileInfo
) * pTileInfo
->bankWidth
* pTileInfo
->macroAspectRatio
;
1124 UINT_32 threshold2
=
1125 bytesPerTile
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
;
1128 // Reduce the tile mode from 2D/3D to 1D in following conditions
1130 switch (expTileMode
)
1132 case ADDR_TM_2D_TILED_THIN1
: //fall through
1133 case ADDR_TM_3D_TILED_THIN1
:
1134 case ADDR_TM_PRT_TILED_THIN1
:
1135 case ADDR_TM_PRT_2D_TILED_THIN1
:
1136 case ADDR_TM_PRT_3D_TILED_THIN1
:
1137 if ((pitch
< pitchAlign
) ||
1138 (height
< heightAlign
) ||
1139 (interleaveSize
> threshold1
) ||
1140 (interleaveSize
> threshold2
))
1142 expTileMode
= ADDR_TM_1D_TILED_THIN1
;
1145 case ADDR_TM_2D_TILED_THICK
: //fall through
1146 case ADDR_TM_3D_TILED_THICK
:
1147 case ADDR_TM_2D_TILED_XTHICK
:
1148 case ADDR_TM_3D_TILED_XTHICK
:
1149 case ADDR_TM_PRT_TILED_THICK
:
1150 case ADDR_TM_PRT_2D_TILED_THICK
:
1151 case ADDR_TM_PRT_3D_TILED_THICK
:
1152 if ((pitch
< pitchAlign
) ||
1153 (height
< heightAlign
))
1155 expTileMode
= ADDR_TM_1D_TILED_THICK
;
1166 ****************************************************************************************************
1167 * EgBasedLib::HwlGetAlignmentInfoMacroTiled
1169 * Get alignment info for giving tile mode
1171 * TRUE if getting alignment is OK
1172 ****************************************************************************************************
1174 BOOL_32
EgBasedLib::HwlGetAlignmentInfoMacroTiled(
1175 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] create surface info
1176 UINT_32
* pPitchAlign
, ///< [out] pitch alignment
1177 UINT_32
* pHeightAlign
, ///< [out] height alignment
1178 UINT_32
* pSizeAlign
///< [out] size alignment
1181 BOOL_32 valid
= TRUE
;
1183 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
1185 UINT_32 numSamples
= (pIn
->numFrags
== 0) ? pIn
->numSamples
: pIn
->numFrags
;
1187 ADDR_ASSERT(pIn
->pTileInfo
);
1188 ADDR_TILEINFO tileInfo
= *pIn
->pTileInfo
;
1189 ADDR_COMPUTE_SURFACE_INFO_OUTPUT out
= {0};
1190 out
.pTileInfo
= &tileInfo
;
1192 if (UseTileIndex(pIn
->tileIndex
))
1194 out
.tileIndex
= pIn
->tileIndex
;
1195 out
.macroModeIndex
= TileIndexInvalid
;
1198 HwlSetupTileInfo(pIn
->tileMode
,
1209 valid
= ComputeSurfaceAlignmentsMacroTiled(pIn
->tileMode
,
1218 *pPitchAlign
= out
.pitchAlign
;
1219 *pHeightAlign
= out
.heightAlign
;
1220 *pSizeAlign
= out
.baseAlign
;
1227 ****************************************************************************************************
1228 * EgBasedLib::HwlDegradeThickTileMode
1231 * Degrades valid tile mode for thick modes if needed
1234 * Suitable tile mode
1235 ****************************************************************************************************
1237 AddrTileMode
EgBasedLib::HwlDegradeThickTileMode(
1238 AddrTileMode baseTileMode
, ///< [in] base tile mode
1239 UINT_32 numSlices
, ///< [in] current number of slices
1240 UINT_32
* pBytesPerTile
///< [in,out] pointer to bytes per slice
1243 ADDR_ASSERT(numSlices
< Thickness(baseTileMode
));
1244 // if pBytesPerTile is NULL, this is a don't-care....
1245 UINT_32 bytesPerTile
= pBytesPerTile
!= NULL
? *pBytesPerTile
: 64;
1247 AddrTileMode expTileMode
= baseTileMode
;
1248 switch (baseTileMode
)
1250 case ADDR_TM_1D_TILED_THICK
:
1251 expTileMode
= ADDR_TM_1D_TILED_THIN1
;
1254 case ADDR_TM_2D_TILED_THICK
:
1255 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1258 case ADDR_TM_3D_TILED_THICK
:
1259 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1262 case ADDR_TM_2D_TILED_XTHICK
:
1263 if (numSlices
< ThickTileThickness
)
1265 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1270 expTileMode
= ADDR_TM_2D_TILED_THICK
;
1274 case ADDR_TM_3D_TILED_XTHICK
:
1275 if (numSlices
< ThickTileThickness
)
1277 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1282 expTileMode
= ADDR_TM_3D_TILED_THICK
;
1287 ADDR_ASSERT_ALWAYS();
1291 if (pBytesPerTile
!= NULL
)
1293 *pBytesPerTile
= bytesPerTile
;
1300 ****************************************************************************************************
1301 * EgBasedLib::DispatchComputeSurfaceAddrFromCoord
1304 * Compute surface address from given coord (x, y, slice,sample)
1308 ****************************************************************************************************
1310 UINT_64
EgBasedLib::DispatchComputeSurfaceAddrFromCoord(
1311 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1312 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1317 UINT_32 slice
= pIn
->slice
;
1318 UINT_32 sample
= pIn
->sample
;
1319 UINT_32 bpp
= pIn
->bpp
;
1320 UINT_32 pitch
= pIn
->pitch
;
1321 UINT_32 height
= pIn
->height
;
1322 UINT_32 numSlices
= pIn
->numSlices
;
1323 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
1324 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
1325 AddrTileMode tileMode
= pIn
->tileMode
;
1326 AddrTileType microTileType
= pIn
->tileType
;
1327 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
1328 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
1329 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
1331 UINT_32
* pBitPosition
= &pOut
->bitPosition
;
1334 // ADDR_DEPTH_SAMPLE_ORDER = non-disp + depth-sample-order
1335 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
1337 isDepthSampleOrder
= TRUE
;
1340 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
1342 if (numFrags
!= numSamples
)
1344 numSamples
= numFrags
;
1345 ADDR_ASSERT(sample
< numSamples
);
1349 /// 128 bit/thick tiled surface doesn't support display tiling and
1350 /// mipmap chain must have the same tileType, so please fill tileType correctly
1351 if (IsLinear(pIn
->tileMode
) == FALSE
)
1353 if (bpp
>= 128 || Thickness(tileMode
) > 1)
1355 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
1362 case ADDR_TM_LINEAR_GENERAL
://fall through
1363 case ADDR_TM_LINEAR_ALIGNED
:
1364 addr
= ComputeSurfaceAddrFromCoordLinear(x
,
1374 case ADDR_TM_1D_TILED_THIN1
://fall through
1375 case ADDR_TM_1D_TILED_THICK
:
1376 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
1389 case ADDR_TM_2D_TILED_THIN1
: //fall through
1390 case ADDR_TM_2D_TILED_THICK
: //fall through
1391 case ADDR_TM_3D_TILED_THIN1
: //fall through
1392 case ADDR_TM_3D_TILED_THICK
: //fall through
1393 case ADDR_TM_2D_TILED_XTHICK
: //fall through
1394 case ADDR_TM_3D_TILED_XTHICK
: //fall through
1395 case ADDR_TM_PRT_TILED_THIN1
: //fall through
1396 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
1397 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
1398 case ADDR_TM_PRT_TILED_THICK
: //fall through
1399 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
1400 case ADDR_TM_PRT_3D_TILED_THICK
:
1401 UINT_32 pipeSwizzle
;
1402 UINT_32 bankSwizzle
;
1404 if (m_configFlags
.useCombinedSwizzle
)
1406 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
1407 &bankSwizzle
, &pipeSwizzle
);
1411 pipeSwizzle
= pIn
->pipeSwizzle
;
1412 bankSwizzle
= pIn
->bankSwizzle
;
1415 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
1434 ADDR_ASSERT_ALWAYS();
1442 ****************************************************************************************************
1443 * EgBasedLib::ComputeMacroTileEquation
1446 * Computes the address equation in macro tile
1448 * If equation can be computed
1449 ****************************************************************************************************
1451 ADDR_E_RETURNCODE
EgBasedLib::ComputeMacroTileEquation(
1452 UINT_32 log2BytesPP
, ///< [in] log2 of bytes per pixel
1453 AddrTileMode tileMode
, ///< [in] tile mode
1454 AddrTileType microTileType
, ///< [in] micro tiling type
1455 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure
1456 ADDR_EQUATION
* pEquation
///< [out] Equation for addressing in macro tile
1459 ADDR_E_RETURNCODE retCode
;
1461 // Element equation within a tile
1462 retCode
= ComputeMicroTileEquation(log2BytesPP
, tileMode
, microTileType
, pEquation
);
1464 if (retCode
== ADDR_OK
)
1466 // Tile equesiton with signle pipe bank
1467 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1468 UINT_32 numPipeBits
= Log2(numPipes
);
1470 for (UINT_32 i
= 0; i
< Log2(pTileInfo
->bankWidth
); i
++)
1472 pEquation
->addr
[pEquation
->numBits
].valid
= 1;
1473 pEquation
->addr
[pEquation
->numBits
].channel
= 0;
1474 pEquation
->addr
[pEquation
->numBits
].index
= i
+ log2BytesPP
+ 3 + numPipeBits
;
1475 pEquation
->numBits
++;
1478 for (UINT_32 i
= 0; i
< Log2(pTileInfo
->bankHeight
); i
++)
1480 pEquation
->addr
[pEquation
->numBits
].valid
= 1;
1481 pEquation
->addr
[pEquation
->numBits
].channel
= 1;
1482 pEquation
->addr
[pEquation
->numBits
].index
= i
+ 3;
1483 pEquation
->numBits
++;
1486 ADDR_EQUATION equation
;
1487 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
1489 UINT_32 thresholdX
= 32;
1490 UINT_32 thresholdY
= 32;
1492 if (IsPrtNoRotationTileMode(tileMode
))
1494 UINT_32 macroTilePitch
=
1495 (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
) * pTileInfo
->macroAspectRatio
;
1496 UINT_32 macroTileHeight
=
1497 (MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
) /
1498 pTileInfo
->macroAspectRatio
;
1499 thresholdX
= Log2(macroTilePitch
);
1500 thresholdY
= Log2(macroTileHeight
);
1504 retCode
= ComputePipeEquation(log2BytesPP
, thresholdX
, thresholdY
, pTileInfo
, &equation
);
1506 if (retCode
== ADDR_OK
)
1508 UINT_32 pipeBitStart
= Log2(m_pipeInterleaveBytes
);
1510 if (pEquation
->numBits
> pipeBitStart
)
1512 UINT_32 numLeftShift
= pEquation
->numBits
- pipeBitStart
;
1514 for (UINT_32 i
= 0; i
< numLeftShift
; i
++)
1516 pEquation
->addr
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1517 pEquation
->addr
[pEquation
->numBits
- i
- 1];
1518 pEquation
->xor1
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1519 pEquation
->xor1
[pEquation
->numBits
- i
- 1];
1520 pEquation
->xor2
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1521 pEquation
->xor2
[pEquation
->numBits
- i
- 1];
1525 for (UINT_32 i
= 0; i
< equation
.numBits
; i
++)
1527 pEquation
->addr
[pipeBitStart
+ i
] = equation
.addr
[i
];
1528 pEquation
->xor1
[pipeBitStart
+ i
] = equation
.xor1
[i
];
1529 pEquation
->xor2
[pipeBitStart
+ i
] = equation
.xor2
[i
];
1530 pEquation
->numBits
++;
1534 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
1536 retCode
= ComputeBankEquation(log2BytesPP
, thresholdX
, thresholdY
,
1537 pTileInfo
, &equation
);
1539 if (retCode
== ADDR_OK
)
1541 UINT_32 bankBitStart
= pipeBitStart
+ numPipeBits
+ Log2(m_bankInterleave
);
1543 if (pEquation
->numBits
> bankBitStart
)
1545 UINT_32 numLeftShift
= pEquation
->numBits
- bankBitStart
;
1547 for (UINT_32 i
= 0; i
< numLeftShift
; i
++)
1549 pEquation
->addr
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1550 pEquation
->addr
[pEquation
->numBits
- i
- 1];
1551 pEquation
->xor1
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1552 pEquation
->xor1
[pEquation
->numBits
- i
- 1];
1553 pEquation
->xor2
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1554 pEquation
->xor2
[pEquation
->numBits
- i
- 1];
1558 for (UINT_32 i
= 0; i
< equation
.numBits
; i
++)
1560 pEquation
->addr
[bankBitStart
+ i
] = equation
.addr
[i
];
1561 pEquation
->xor1
[bankBitStart
+ i
] = equation
.xor1
[i
];
1562 pEquation
->xor2
[bankBitStart
+ i
] = equation
.xor2
[i
];
1563 pEquation
->numBits
++;
1573 ****************************************************************************************************
1574 * EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1577 * Computes the surface address and bit position from a
1578 * coordinate for 2D tilied (macro tiled)
1581 ****************************************************************************************************
1583 UINT_64
EgBasedLib::ComputeSurfaceAddrFromCoordMacroTiled(
1584 UINT_32 x
, ///< [in] x coordinate
1585 UINT_32 y
, ///< [in] y coordinate
1586 UINT_32 slice
, ///< [in] slice index
1587 UINT_32 sample
, ///< [in] sample index
1588 UINT_32 bpp
, ///< [in] bits per pixel
1589 UINT_32 pitch
, ///< [in] surface pitch, in pixels
1590 UINT_32 height
, ///< [in] surface height, in pixels
1591 UINT_32 numSamples
, ///< [in] number of samples
1592 AddrTileMode tileMode
, ///< [in] tile mode
1593 AddrTileType microTileType
, ///< [in] micro tiling type
1594 BOOL_32 ignoreSE
, ///< [in] TRUE if shader enginers can be ignored
1595 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if it depth sample ordering is used
1596 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
1597 UINT_32 bankSwizzle
, ///< [in] bank swizzle
1598 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure
1599 /// **All fields to be valid on entry**
1600 UINT_32
* pBitPosition
///< [out] bit position, e.g. FMT_1 will use this
1605 UINT_32 microTileBytes
;
1606 UINT_32 microTileBits
;
1607 UINT_32 sampleOffset
;
1609 UINT_32 pixelOffset
;
1610 UINT_32 elementOffset
;
1611 UINT_32 tileSplitSlice
;
1615 UINT_64 sliceOffset
;
1616 UINT_32 macroTilePitch
;
1617 UINT_32 macroTileHeight
;
1618 UINT_32 macroTilesPerRow
;
1619 UINT_32 macroTilesPerSlice
;
1620 UINT_64 macroTileBytes
;
1621 UINT_32 macroTileIndexX
;
1622 UINT_32 macroTileIndexY
;
1623 UINT_64 macroTileOffset
;
1624 UINT_64 totalOffset
;
1625 UINT_64 pipeInterleaveMask
;
1626 UINT_64 bankInterleaveMask
;
1627 UINT_64 pipeInterleaveOffset
;
1628 UINT_32 bankInterleaveOffset
;
1630 UINT_32 tileRowIndex
;
1631 UINT_32 tileColumnIndex
;
1635 UINT_32 microTileThickness
= Thickness(tileMode
);
1638 // Compute the number of group, pipe, and bank bits.
1640 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1641 UINT_32 numPipeInterleaveBits
= Log2(m_pipeInterleaveBytes
);
1642 UINT_32 numPipeBits
= Log2(numPipes
);
1643 UINT_32 numBankInterleaveBits
= Log2(m_bankInterleave
);
1644 UINT_32 numBankBits
= Log2(pTileInfo
->banks
);
1647 // Compute the micro tile size.
1649 microTileBits
= MicroTilePixels
* microTileThickness
* bpp
* numSamples
;
1651 microTileBytes
= microTileBits
/ 8;
1653 // Compute the pixel index within the micro tile.
1655 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
1663 // Compute the sample offset and pixel offset.
1665 if (isDepthSampleOrder
)
1668 // For depth surfaces, samples are stored contiguously for each element, so the sample
1669 // offset is the sample number times the element size.
1671 sampleOffset
= sample
* bpp
;
1672 pixelOffset
= pixelIndex
* bpp
* numSamples
;
1677 // For color surfaces, all elements for a particular sample are stored contiguously, so
1678 // the sample offset is the sample number times the micro tile size divided yBit the number
1681 sampleOffset
= sample
* (microTileBits
/ numSamples
);
1682 pixelOffset
= pixelIndex
* bpp
;
1686 // Compute the element offset.
1688 elementOffset
= pixelOffset
+ sampleOffset
;
1690 *pBitPosition
= static_cast<UINT_32
>(elementOffset
% 8);
1692 elementOffset
/= 8; //bit-to-byte
1695 // Determine if tiles need to be split across slices.
1697 // If the size of the micro tile is larger than the tile split size, then the tile will be
1698 // split across multiple slices.
1700 UINT_32 slicesPerTile
= 1;
1702 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
1703 { //don't support for thick mode
1706 // Compute the number of slices per tile.
1708 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
1711 // Compute the tile split slice number for use in rotating the bank.
1713 tileSplitSlice
= elementOffset
/ pTileInfo
->tileSplitBytes
;
1716 // Adjust the element offset to account for the portion of the tile that is being moved to
1719 elementOffset
%= pTileInfo
->tileSplitBytes
;
1722 // Adjust the microTileBytes size to tileSplitBytes size since
1725 microTileBytes
= pTileInfo
->tileSplitBytes
;
1733 // Compute macro tile pitch and height.
1736 (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
) * pTileInfo
->macroAspectRatio
;
1738 (MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
) / pTileInfo
->macroAspectRatio
;
1741 // Compute the number of bytes per macro tile. Note: bytes of the same bank/pipe actually
1744 static_cast<UINT_64
>(microTileBytes
) *
1745 (macroTilePitch
/ MicroTileWidth
) * (macroTileHeight
/ MicroTileHeight
) /
1746 (numPipes
* pTileInfo
->banks
);
1749 // Compute the number of macro tiles per row.
1751 macroTilesPerRow
= pitch
/ macroTilePitch
;
1754 // Compute the offset to the macro tile containing the specified coordinate.
1756 macroTileIndexX
= x
/ macroTilePitch
;
1757 macroTileIndexY
= y
/ macroTileHeight
;
1758 macroTileOffset
= ((macroTileIndexY
* macroTilesPerRow
) + macroTileIndexX
) * macroTileBytes
;
1761 // Compute the number of macro tiles per slice.
1763 macroTilesPerSlice
= macroTilesPerRow
* (height
/ macroTileHeight
);
1766 // Compute the slice size.
1768 sliceBytes
= macroTilesPerSlice
* macroTileBytes
;
1771 // Compute the slice offset.
1773 sliceOffset
= sliceBytes
* (tileSplitSlice
+ slicesPerTile
* (slice
/ microTileThickness
));
1776 // Compute tile offest
1778 tileRowIndex
= (y
/ MicroTileHeight
) % pTileInfo
->bankHeight
;
1779 tileColumnIndex
= ((x
/ MicroTileWidth
) / numPipes
) % pTileInfo
->bankWidth
;
1780 tileIndex
= (tileRowIndex
* pTileInfo
->bankWidth
) + tileColumnIndex
;
1781 tileOffset
= tileIndex
* microTileBytes
;
1784 // Combine the slice offset and macro tile offset with the pixel and sample offsets, accounting
1785 // for the pipe and bank bits in the middle of the address.
1787 totalOffset
= sliceOffset
+ macroTileOffset
+ elementOffset
+ tileOffset
;
1790 // Get the pipe and bank.
1793 // when the tileMode is PRT type, then adjust x and y coordinates
1794 if (IsPrtNoRotationTileMode(tileMode
))
1796 x
= x
% macroTilePitch
;
1797 y
= y
% macroTileHeight
;
1800 pipe
= ComputePipeFromCoord(x
,
1808 bank
= ComputeBankFromCoord(x
,
1818 // Split the offset to put some bits below the pipe+bank bits and some above.
1820 pipeInterleaveMask
= (1 << numPipeInterleaveBits
) - 1;
1821 bankInterleaveMask
= (1 << numBankInterleaveBits
) - 1;
1822 pipeInterleaveOffset
= totalOffset
& pipeInterleaveMask
;
1823 bankInterleaveOffset
= static_cast<UINT_32
>((totalOffset
>> numPipeInterleaveBits
) &
1824 bankInterleaveMask
);
1825 offset
= totalOffset
>> (numPipeInterleaveBits
+ numBankInterleaveBits
);
1828 // Assemble the address from its components.
1830 addr
= pipeInterleaveOffset
;
1831 // This is to remove /analyze warnings
1832 UINT_32 pipeBits
= pipe
<< numPipeInterleaveBits
;
1833 UINT_32 bankInterleaveBits
= bankInterleaveOffset
<< (numPipeInterleaveBits
+ numPipeBits
);
1834 UINT_32 bankBits
= bank
<< (numPipeInterleaveBits
+ numPipeBits
+
1835 numBankInterleaveBits
);
1836 UINT_64 offsetBits
= offset
<< (numPipeInterleaveBits
+ numPipeBits
+
1837 numBankInterleaveBits
+ numBankBits
);
1840 addr
|= bankInterleaveBits
;
1848 ****************************************************************************************************
1849 * EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1852 * Computes the surface address and bit position from a coordinate for 1D tilied
1856 ****************************************************************************************************
1858 UINT_64
EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled(
1859 UINT_32 x
, ///< [in] x coordinate
1860 UINT_32 y
, ///< [in] y coordinate
1861 UINT_32 slice
, ///< [in] slice index
1862 UINT_32 sample
, ///< [in] sample index
1863 UINT_32 bpp
, ///< [in] bits per pixel
1864 UINT_32 pitch
, ///< [in] pitch, in pixels
1865 UINT_32 height
, ///< [in] height, in pixels
1866 UINT_32 numSamples
, ///< [in] number of samples
1867 AddrTileMode tileMode
, ///< [in] tile mode
1868 AddrTileType microTileType
, ///< [in] micro tiling type
1869 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if depth sample ordering is used
1870 UINT_32
* pBitPosition
///< [out] bit position, e.g. FMT_1 will use this
1875 UINT_32 microTileBytes
;
1877 UINT_32 microTilesPerRow
;
1878 UINT_32 microTileIndexX
;
1879 UINT_32 microTileIndexY
;
1880 UINT_32 microTileIndexZ
;
1881 UINT_64 sliceOffset
;
1882 UINT_64 microTileOffset
;
1883 UINT_32 sampleOffset
;
1885 UINT_32 pixelOffset
;
1887 UINT_32 microTileThickness
= Thickness(tileMode
);
1890 // Compute the micro tile size.
1892 microTileBytes
= BITS_TO_BYTES(MicroTilePixels
* microTileThickness
* bpp
* numSamples
);
1895 // Compute the slice size.
1898 BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* microTileThickness
* bpp
* numSamples
);
1901 // Compute the number of micro tiles per row.
1903 microTilesPerRow
= pitch
/ MicroTileWidth
;
1906 // Compute the micro tile index.
1908 microTileIndexX
= x
/ MicroTileWidth
;
1909 microTileIndexY
= y
/ MicroTileHeight
;
1910 microTileIndexZ
= slice
/ microTileThickness
;
1913 // Compute the slice offset.
1915 sliceOffset
= static_cast<UINT_64
>(microTileIndexZ
) * sliceBytes
;
1918 // Compute the offset to the micro tile containing the specified coordinate.
1920 microTileOffset
= (static_cast<UINT_64
>(microTileIndexY
) * microTilesPerRow
+ microTileIndexX
) *
1924 // Compute the pixel index within the micro tile.
1926 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
1933 // Compute the sample offset.
1935 if (isDepthSampleOrder
)
1938 // For depth surfaces, samples are stored contiguously for each element, so the sample
1939 // offset is the sample number times the element size.
1941 sampleOffset
= sample
* bpp
;
1942 pixelOffset
= pixelIndex
* bpp
* numSamples
;
1947 // For color surfaces, all elements for a particular sample are stored contiguously, so
1948 // the sample offset is the sample number times the micro tile size divided yBit the number
1951 sampleOffset
= sample
* (microTileBytes
*8 / numSamples
);
1952 pixelOffset
= pixelIndex
* bpp
;
1956 // Compute the bit position of the pixel. Each element is stored with one bit per sample.
1959 UINT_32 elemOffset
= sampleOffset
+ pixelOffset
;
1961 *pBitPosition
= elemOffset
% 8;
1965 // Combine the slice offset, micro tile offset, sample offset, and pixel offsets.
1967 addr
= sliceOffset
+ microTileOffset
+ elemOffset
;
1973 ****************************************************************************************************
1974 * EgBasedLib::HwlComputePixelCoordFromOffset
1977 * Compute pixel coordinate from offset inside a micro tile
1980 ****************************************************************************************************
1982 VOID
EgBasedLib::HwlComputePixelCoordFromOffset(
1983 UINT_32 offset
, ///< [in] offset inside micro tile in bits
1984 UINT_32 bpp
, ///< [in] bits per pixel
1985 UINT_32 numSamples
, ///< [in] number of samples
1986 AddrTileMode tileMode
, ///< [in] tile mode
1987 UINT_32 tileBase
, ///< [in] base offset within a tile
1988 UINT_32 compBits
, ///< [in] component bits actually needed(for planar surface)
1989 UINT_32
* pX
, ///< [out] x coordinate
1990 UINT_32
* pY
, ///< [out] y coordinate
1991 UINT_32
* pSlice
, ///< [out] slice index
1992 UINT_32
* pSample
, ///< [out] sample index
1993 AddrTileType microTileType
, ///< [in] micro tiling type
1994 BOOL_32 isDepthSampleOrder
///< [in] TRUE if depth sample order in microtile is used
2000 UINT_32 thickness
= Thickness(tileMode
);
2002 // For planar surface, we adjust offset acoording to tile base
2003 if ((bpp
!= compBits
) && (compBits
!= 0) && isDepthSampleOrder
)
2007 ADDR_ASSERT(microTileType
== ADDR_NON_DISPLAYABLE
||
2008 microTileType
== ADDR_DEPTH_SAMPLE_ORDER
);
2013 UINT_32 sampleTileBits
;
2014 UINT_32 samplePixelBits
;
2017 if (isDepthSampleOrder
)
2019 samplePixelBits
= bpp
* numSamples
;
2020 pixelIndex
= offset
/ samplePixelBits
;
2021 *pSample
= (offset
% samplePixelBits
) / bpp
;
2025 sampleTileBits
= MicroTilePixels
* bpp
* thickness
;
2026 *pSample
= offset
/ sampleTileBits
;
2027 pixelIndex
= (offset
% sampleTileBits
) / bpp
;
2030 if (microTileType
!= ADDR_THICK
)
2032 if (microTileType
== ADDR_DISPLAYABLE
) // displayable
2037 x
= pixelIndex
& 0x7;
2038 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,4));
2041 x
= pixelIndex
& 0x7;
2042 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,3));
2045 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,1),_BIT(pixelIndex
,0));
2046 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,2));
2049 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2050 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
2053 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,2),_BIT(pixelIndex
,1));
2054 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,0));
2060 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2062 x
= Bits2Number(3, _BIT(pixelIndex
,4),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2063 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
2065 else if (microTileType
== ADDR_ROTATED
)
2069 element_index[5:0] = { x[2], x[0], x[1], y[2], y[1], y[0] }
2072 element_index[5:0] = { x[2], x[1], x[0], y[2], y[1], y[0] }
2075 element_index[5:0] = { x[2], x[1], y[2], x[0], y[1], y[0] }
2078 element_index[5:0] = { y[2], x[2], x[1], y[1], x[0], y[0] }
2083 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,4));
2084 y
= pixelIndex
& 0x7;
2087 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,3));
2088 y
= pixelIndex
& 0x7;
2091 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,2));
2092 y
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,1),_BIT(pixelIndex
,0));
2095 x
= Bits2Number(3, _BIT(pixelIndex
,4),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
2096 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2099 ADDR_ASSERT_ALWAYS();
2104 if (thickness
> 1) // thick
2106 z
= Bits2Number(3, _BIT(pixelIndex
,8),_BIT(pixelIndex
,7),_BIT(pixelIndex
,6));
2111 ADDR_ASSERT((m_chipFamily
>= ADDR_CHIP_FAMILY_CI
) && (thickness
> 1));
2113 8-Bit Elements and 16-Bit Elements
2114 element_index[7:0] = { y[2], x[2], z[1], z[0], y[1], x[1], y[0], x[0] }
2117 element_index[7:0] = { y[2], x[2], z[1], y[1], z[0], x[1], y[0], x[0] }
2119 64-Bit Elements and 128-Bit Elements
2120 element_index[7:0] = { y[2], x[2], z[1], y[1], x[1], z[0], y[0], x[0] }
2122 The equation to compute the element index for the extra thick tile:
2123 element_index[8] = z[2]
2128 case 16: // fall-through
2129 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2130 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
2131 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4));
2134 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2135 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
2136 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3));
2139 case 128: // fall-through
2140 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,3),_BIT(pixelIndex
,0));
2141 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
2142 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,2));
2145 ADDR_ASSERT_ALWAYS();
2151 z
+= Bits2Number(3,_BIT(pixelIndex
,8),0,0);
2162 ****************************************************************************************************
2163 * EgBasedLib::DispatchComputeSurfaceCoordFromAddrDispatch
2166 * Compute (x,y,slice,sample) coordinates from surface address
2169 ****************************************************************************************************
2171 VOID
EgBasedLib::DispatchComputeSurfaceCoordFromAddr(
2172 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
2173 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
2176 UINT_64 addr
= pIn
->addr
;
2177 UINT_32 bitPosition
= pIn
->bitPosition
;
2178 UINT_32 bpp
= pIn
->bpp
;
2179 UINT_32 pitch
= pIn
->pitch
;
2180 UINT_32 height
= pIn
->height
;
2181 UINT_32 numSlices
= pIn
->numSlices
;
2182 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
2183 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
2184 AddrTileMode tileMode
= pIn
->tileMode
;
2185 UINT_32 tileBase
= pIn
->tileBase
;
2186 UINT_32 compBits
= pIn
->compBits
;
2187 AddrTileType microTileType
= pIn
->tileType
;
2188 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
2189 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
2190 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2192 UINT_32
* pX
= &pOut
->x
;
2193 UINT_32
* pY
= &pOut
->y
;
2194 UINT_32
* pSlice
= &pOut
->slice
;
2195 UINT_32
* pSample
= &pOut
->sample
;
2197 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2199 isDepthSampleOrder
= TRUE
;
2202 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
2204 if (numFrags
!= numSamples
)
2206 numSamples
= numFrags
;
2210 /// 128 bit/thick tiled surface doesn't support display tiling and
2211 /// mipmap chain must have the same tileType, so please fill tileType correctly
2212 if (IsLinear(pIn
->tileMode
) == FALSE
)
2214 if (bpp
>= 128 || Thickness(tileMode
) > 1)
2216 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
2223 case ADDR_TM_LINEAR_GENERAL
://fall through
2224 case ADDR_TM_LINEAR_ALIGNED
:
2225 ComputeSurfaceCoordFromAddrLinear(addr
,
2236 case ADDR_TM_1D_TILED_THIN1
://fall through
2237 case ADDR_TM_1D_TILED_THICK
:
2238 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
2252 isDepthSampleOrder
);
2254 case ADDR_TM_2D_TILED_THIN1
: //fall through
2255 case ADDR_TM_2D_TILED_THICK
: //fall through
2256 case ADDR_TM_3D_TILED_THIN1
: //fall through
2257 case ADDR_TM_3D_TILED_THICK
: //fall through
2258 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2259 case ADDR_TM_3D_TILED_XTHICK
: //fall through
2260 case ADDR_TM_PRT_TILED_THIN1
: //fall through
2261 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
2262 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
2263 case ADDR_TM_PRT_TILED_THICK
: //fall through
2264 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
2265 case ADDR_TM_PRT_3D_TILED_THICK
:
2266 UINT_32 pipeSwizzle
;
2267 UINT_32 bankSwizzle
;
2269 if (m_configFlags
.useCombinedSwizzle
)
2271 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
2272 &bankSwizzle
, &pipeSwizzle
);
2276 pipeSwizzle
= pIn
->pipeSwizzle
;
2277 bankSwizzle
= pIn
->bankSwizzle
;
2280 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
2301 ADDR_ASSERT_ALWAYS();
2307 ****************************************************************************************************
2308 * EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled
2311 * Compute surface coordinates from address for macro tiled surface
2314 ****************************************************************************************************
2316 VOID
EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled(
2317 UINT_64 addr
, ///< [in] byte address
2318 UINT_32 bitPosition
, ///< [in] bit position
2319 UINT_32 bpp
, ///< [in] bits per pixel
2320 UINT_32 pitch
, ///< [in] pitch in pixels
2321 UINT_32 height
, ///< [in] height in pixels
2322 UINT_32 numSamples
, ///< [in] number of samples
2323 AddrTileMode tileMode
, ///< [in] tile mode
2324 UINT_32 tileBase
, ///< [in] tile base offset
2325 UINT_32 compBits
, ///< [in] component bits (for planar surface)
2326 AddrTileType microTileType
, ///< [in] micro tiling type
2327 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines can be ignored
2328 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if depth sample order is used
2329 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2330 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2331 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure.
2332 /// **All fields to be valid on entry**
2333 UINT_32
* pX
, ///< [out] X coord
2334 UINT_32
* pY
, ///< [out] Y coord
2335 UINT_32
* pSlice
, ///< [out] slice index
2336 UINT_32
* pSample
///< [out] sample index
2342 UINT_64 macroTileBits
;
2345 UINT_64 elementOffset
;
2346 UINT_64 macroTileIndex
;
2348 UINT_64 totalOffset
;
2353 UINT_32 groupBits
= m_pipeInterleaveBytes
<< 3;
2354 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2355 UINT_32 banks
= pTileInfo
->banks
;
2357 UINT_32 bankInterleave
= m_bankInterleave
;
2359 UINT_64 addrBits
= BYTES_TO_BITS(addr
) + bitPosition
;
2362 // remove bits for bank and pipe
2364 totalOffset
= (addrBits
% groupBits
) +
2365 (((addrBits
/ groupBits
/ pipes
) % bankInterleave
) * groupBits
) +
2366 (((addrBits
/ groupBits
/ pipes
) / bankInterleave
) / banks
) * groupBits
* bankInterleave
;
2368 UINT_32 microTileThickness
= Thickness(tileMode
);
2370 UINT_32 microTileBits
= bpp
* microTileThickness
* MicroTilePixels
* numSamples
;
2372 UINT_32 microTileBytes
= BITS_TO_BYTES(microTileBits
);
2374 // Determine if tiles need to be split across slices.
2376 // If the size of the micro tile is larger than the tile split size, then the tile will be
2377 // split across multiple slices.
2379 UINT_32 slicesPerTile
= 1; //_State->TileSlices
2381 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
2382 { //don't support for thick mode
2385 // Compute the number of slices per tile.
2387 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
2390 tileBits
= microTileBits
/ slicesPerTile
; // micro tile bits
2392 // in micro tiles because not MicroTileWidth timed.
2393 UINT_32 macroWidth
= pTileInfo
->bankWidth
* pipes
* pTileInfo
->macroAspectRatio
;
2394 // in micro tiles as well
2395 UINT_32 macroHeight
= pTileInfo
->bankHeight
* banks
/ pTileInfo
->macroAspectRatio
;
2397 UINT_32 pitchInMacroTiles
= pitch
/ MicroTileWidth
/ macroWidth
;
2399 macroTileBits
= (macroWidth
* macroHeight
) * tileBits
/ (banks
* pipes
);
2401 macroTileIndex
= totalOffset
/ macroTileBits
;
2403 // pitchMacros * height / heightMacros; macroTilesPerSlice == _State->SliceMacros
2404 UINT_32 macroTilesPerSlice
= (pitch
/ (macroWidth
* MicroTileWidth
)) * height
/
2405 (macroHeight
* MicroTileWidth
);
2407 slices
= static_cast<UINT_32
>(macroTileIndex
/ macroTilesPerSlice
);
2409 *pSlice
= static_cast<UINT_32
>(slices
/ slicesPerTile
* microTileThickness
);
2412 // calculate element offset and x[2:0], y[2:0], z[1:0] for thick
2414 tileSlices
= slices
% slicesPerTile
;
2416 elementOffset
= tileSlices
* tileBits
;
2417 elementOffset
+= totalOffset
% tileBits
;
2421 HwlComputePixelCoordFromOffset(static_cast<UINT_32
>(elementOffset
),
2432 isDepthSampleOrder
);
2434 macroTileIndex
= macroTileIndex
% macroTilesPerSlice
;
2435 *pY
+= static_cast<UINT_32
>(macroTileIndex
/ pitchInMacroTiles
* macroHeight
* MicroTileHeight
);
2436 *pX
+= static_cast<UINT_32
>(macroTileIndex
% pitchInMacroTiles
* macroWidth
* MicroTileWidth
);
2440 tileIndex
= static_cast<UINT_32
>((totalOffset
% macroTileBits
) / tileBits
);
2442 my
= (tileIndex
/ pTileInfo
->bankWidth
) % pTileInfo
->bankHeight
* MicroTileHeight
;
2443 mx
= (tileIndex
% pTileInfo
->bankWidth
) * pipes
* MicroTileWidth
;
2448 bank
= ComputeBankFromAddr(addr
, banks
, pipes
);
2449 pipe
= ComputePipeFromAddr(addr
, pipes
);
2451 HwlComputeSurfaceCoord2DFromBankPipe(tileMode
,
2465 ****************************************************************************************************
2466 * EgBasedLib::ComputeSurfaceCoord2DFromBankPipe
2469 * Compute surface x,y coordinates from bank/pipe info
2472 ****************************************************************************************************
2474 VOID
EgBasedLib::ComputeSurfaceCoord2DFromBankPipe(
2475 AddrTileMode tileMode
, ///< [in] tile mode
2476 UINT_32 x
, ///< [in] x coordinate
2477 UINT_32 y
, ///< [in] y coordinate
2478 UINT_32 slice
, ///< [in] slice index
2479 UINT_32 bank
, ///< [in] bank number
2480 UINT_32 pipe
, ///< [in] pipe number
2481 UINT_32 bankSwizzle
,///< [in] bank swizzle
2482 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
2483 UINT_32 tileSlices
, ///< [in] slices in a micro tile
2484 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure. **All fields to be valid on entry**
2485 CoordFromBankPipe
* pOutput
///< [out] pointer to extracted x/y bits
2497 UINT_32 tileSplitRotation
;
2499 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2501 UINT_32 bankRotation
= ComputeBankRotation(tileMode
,
2502 pTileInfo
->banks
, numPipes
);
2504 UINT_32 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2506 UINT_32 xBit
= x
/ (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
);
2507 UINT_32 yBit
= y
/ (MicroTileHeight
* pTileInfo
->bankHeight
);
2509 //calculate the bank and pipe before rotation and swizzle
2513 case ADDR_TM_2D_TILED_THIN1
: //fall through
2514 case ADDR_TM_2D_TILED_THICK
: //fall through
2515 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2516 case ADDR_TM_3D_TILED_THIN1
: //fall through
2517 case ADDR_TM_3D_TILED_THICK
: //fall through
2518 case ADDR_TM_3D_TILED_XTHICK
:
2519 tileSplitRotation
= ((pTileInfo
->banks
/ 2) + 1);
2522 tileSplitRotation
= 0;
2526 UINT_32 microTileThickness
= Thickness(tileMode
);
2528 bank
^= tileSplitRotation
* tileSlices
;
2529 if (pipeRotation
== 0)
2531 bank
^= bankRotation
* (slice
/ microTileThickness
) + bankSwizzle
;
2532 bank
%= pTileInfo
->banks
;
2533 pipe
^= pipeSwizzle
;
2537 bank
^= bankRotation
* (slice
/ microTileThickness
) / numPipes
+ bankSwizzle
;
2538 bank
%= pTileInfo
->banks
;
2539 pipe
^= pipeRotation
* (slice
/ microTileThickness
) + pipeSwizzle
;
2542 if (pTileInfo
->macroAspectRatio
== 1)
2544 switch (pTileInfo
->banks
)
2547 yBit3
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2550 yBit4
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2551 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2554 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2555 yBit5
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2556 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ yBit5
;
2559 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3);
2560 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2);
2561 yBit6
= _BIT(bank
, 0) ^ _BIT(xBit
, 0);
2562 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ yBit6
;
2569 else if (pTileInfo
->macroAspectRatio
== 2)
2571 switch (pTileInfo
->banks
)
2573 case 2: //xBit3 = yBit3^b0
2574 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,0);
2576 case 4: //xBit3=yBit4^b0; yBit3=xBit4^b1
2577 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2578 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2580 case 8: //xBit4, xBit5, yBit5 are known
2581 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2582 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2583 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ _BIT(yBit
, 2);
2585 case 16://x4,x5,x6,y6 are known
2586 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3); //x3 = y6 ^ b0
2587 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2588 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = x5 ^ b2
2589 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ _BIT(yBit
, 3); //y5=x4^y6^b1
2595 else if (pTileInfo
->macroAspectRatio
== 4)
2597 switch (pTileInfo
->banks
)
2599 case 4: //yBit3, yBit4
2600 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2601 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,0);
2603 case 8: //xBit5, yBit4, yBit5
2604 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2605 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2606 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
,2);
2608 case 16: //xBit5, xBit6, yBit5, yBit6
2609 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = b0 ^ y6
2610 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = b1 ^ y5 ^ y6;
2611 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = b3 ^ x6;
2612 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = b2 ^ x5;
2618 else if (pTileInfo
->macroAspectRatio
== 8)
2620 switch (pTileInfo
->banks
)
2622 case 8: //yBit3, yBit4, yBit5
2623 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2); //x3 = b0 ^ y5;
2624 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
, 2);//x4 = b1 ^ y4 ^ y5;
2625 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
,0);
2627 case 16: //xBit6, yBit4, yBit5, yBit6
2628 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = y6 ^ b0
2629 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = y5 ^ y6 ^ b1
2630 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
, 1);//x5 = y4 ^ b2
2631 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2638 pOutput
->xBits
= xBit
;
2639 pOutput
->yBits
= yBit
;
2641 pOutput
->xBit3
= xBit3
;
2642 pOutput
->xBit4
= xBit4
;
2643 pOutput
->xBit5
= xBit5
;
2644 pOutput
->yBit3
= yBit3
;
2645 pOutput
->yBit4
= yBit4
;
2646 pOutput
->yBit5
= yBit5
;
2647 pOutput
->yBit6
= yBit6
;
2651 ****************************************************************************************************
2652 * EgBasedLib::HwlExtractBankPipeSwizzle
2654 * Entry of EgBasedLib ExtractBankPipeSwizzle
2657 ****************************************************************************************************
2659 ADDR_E_RETURNCODE
EgBasedLib::HwlExtractBankPipeSwizzle(
2660 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
2661 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
2664 ExtractBankPipeSwizzle(pIn
->base256b
,
2667 &pOut
->pipeSwizzle
);
2674 ****************************************************************************************************
2675 * EgBasedLib::HwlCombineBankPipeSwizzle
2677 * Combine bank/pipe swizzle
2680 ****************************************************************************************************
2682 ADDR_E_RETURNCODE
EgBasedLib::HwlCombineBankPipeSwizzle(
2683 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2684 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2685 ADDR_TILEINFO
* pTileInfo
, ///< [in] tile info
2686 UINT_64 baseAddr
, ///< [in] base address
2687 UINT_32
* pTileSwizzle
///< [out] combined swizzle
2690 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
2694 *pTileSwizzle
= GetBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, baseAddr
, pTileInfo
);
2698 retCode
= ADDR_INVALIDPARAMS
;
2705 ****************************************************************************************************
2706 * EgBasedLib::HwlComputeBaseSwizzle
2708 * Compute base swizzle
2711 ****************************************************************************************************
2713 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeBaseSwizzle(
2714 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT
* pIn
,
2715 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
* pOut
2718 UINT_32 bankSwizzle
= 0;
2719 UINT_32 pipeSwizzle
= 0;
2720 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2722 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
2723 ADDR_ASSERT(pIn
->pTileInfo
);
2725 /// This is a legacy misreading of h/w doc, use it as it doesn't hurt.
2726 static const UINT_8 bankRotationArray
[4][16] = {
2727 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_2_BANK
2728 { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_4_BANK
2729 { 0, 3, 6, 1, 4, 7, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_8_BANK
2730 { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }, // ADDR_SURF_16_BANK
2733 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2735 UINT_32 banks
= pTileInfo
? pTileInfo
->banks
: 2;
2738 // Uses less bank swizzle bits
2739 if (pIn
->option
.reduceBankBit
&& banks
> 2)
2759 ADDR_ASSERT_ALWAYS();
2764 if (pIn
->option
.genOption
== ADDR_SWIZZLE_GEN_LINEAR
)
2766 bankSwizzle
= pIn
->surfIndex
& (banks
- 1);
2768 else // (pIn->option.genOption == ADDR_SWIZZLE_GEN_DEFAULT)
2770 bankSwizzle
= bankRotationArray
[hwNumBanks
][pIn
->surfIndex
& (banks
- 1)];
2773 if (IsMacro3dTiled(pIn
->tileMode
))
2775 pipeSwizzle
= pIn
->surfIndex
& (HwlGetPipes(pTileInfo
) - 1);
2778 return HwlCombineBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, pTileInfo
, 0, &pOut
->tileSwizzle
);
2782 ****************************************************************************************************
2783 * EgBasedLib::ExtractBankPipeSwizzle
2785 * Extract bank/pipe swizzle from base256b
2788 ****************************************************************************************************
2790 VOID
EgBasedLib::ExtractBankPipeSwizzle(
2791 UINT_32 base256b
, ///< [in] input base256b register value
2792 ADDR_TILEINFO
* pTileInfo
, ///< [in] 2D tile parameters. Client must provide all data
2793 UINT_32
* pBankSwizzle
, ///< [out] bank swizzle
2794 UINT_32
* pPipeSwizzle
///< [out] pipe swizzle
2797 UINT_32 bankSwizzle
= 0;
2798 UINT_32 pipeSwizzle
= 0;
2802 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2803 UINT_32 bankBits
= QLog2(pTileInfo
->banks
);
2804 UINT_32 pipeBits
= QLog2(numPipes
);
2805 UINT_32 groupBytes
= m_pipeInterleaveBytes
;
2806 UINT_32 bankInterleave
= m_bankInterleave
;
2809 (base256b
/ (groupBytes
>> 8)) & ((1<<pipeBits
)-1);
2812 (base256b
/ (groupBytes
>> 8) / numPipes
/ bankInterleave
) & ((1 << bankBits
) - 1);
2815 *pPipeSwizzle
= pipeSwizzle
;
2816 *pBankSwizzle
= bankSwizzle
;
2820 ****************************************************************************************************
2821 * EgBasedLib::GetBankPipeSwizzle
2823 * Combine bank/pipe swizzle
2825 * Base256b bits (only filled bank/pipe bits)
2826 ****************************************************************************************************
2828 UINT_32
EgBasedLib::GetBankPipeSwizzle(
2829 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2830 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2831 UINT_64 baseAddr
, ///< [in] base address
2832 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2835 UINT_32 pipeBits
= QLog2(HwlGetPipes(pTileInfo
));
2836 UINT_32 bankInterleaveBits
= QLog2(m_bankInterleave
);
2837 UINT_32 tileSwizzle
= pipeSwizzle
+ ((bankSwizzle
<< bankInterleaveBits
) << pipeBits
);
2839 baseAddr
^= tileSwizzle
* m_pipeInterleaveBytes
;
2842 return static_cast<UINT_32
>(baseAddr
);
2846 ****************************************************************************************************
2847 * EgBasedLib::ComputeSliceTileSwizzle
2849 * Compute cubemap/3d texture faces/slices tile swizzle
2852 ****************************************************************************************************
2854 UINT_32
EgBasedLib::ComputeSliceTileSwizzle(
2855 AddrTileMode tileMode
, ///< [in] Tile mode
2856 UINT_32 baseSwizzle
, ///< [in] Base swizzle
2857 UINT_32 slice
, ///< [in] Slice index, Cubemap face index, 0 means +X
2858 UINT_64 baseAddr
, ///< [in] Base address
2859 ADDR_TILEINFO
* pTileInfo
///< [in] Bank structure
2862 UINT_32 tileSwizzle
= 0;
2864 if (IsMacroTiled(tileMode
)) // Swizzle only for macro tile mode
2866 UINT_32 firstSlice
= slice
/ Thickness(tileMode
);
2868 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2869 UINT_32 numBanks
= pTileInfo
->banks
;
2871 UINT_32 pipeRotation
;
2872 UINT_32 bankRotation
;
2874 UINT_32 bankSwizzle
= 0;
2875 UINT_32 pipeSwizzle
= 0;
2877 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2878 bankRotation
= ComputeBankRotation(tileMode
, numBanks
, numPipes
);
2880 if (baseSwizzle
!= 0)
2882 ExtractBankPipeSwizzle(baseSwizzle
,
2888 if (pipeRotation
== 0) //2D mode
2890 bankSwizzle
+= firstSlice
* bankRotation
;
2891 bankSwizzle
%= numBanks
;
2895 pipeSwizzle
+= firstSlice
* pipeRotation
;
2896 pipeSwizzle
%= numPipes
;
2897 bankSwizzle
+= firstSlice
* bankRotation
/ numPipes
;
2898 bankSwizzle
%= numBanks
;
2901 tileSwizzle
= GetBankPipeSwizzle(bankSwizzle
,
2911 ****************************************************************************************************
2912 * EgBasedLib::HwlComputeQbStereoRightSwizzle
2915 * Compute right eye swizzle
2918 ****************************************************************************************************
2920 UINT_32
EgBasedLib::HwlComputeQbStereoRightSwizzle(
2921 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pInfo
///< [in] Surface info, must be valid
2924 UINT_32 bankBits
= 0;
2925 UINT_32 swizzle
= 0;
2927 // The assumption is default swizzle for left eye is 0
2928 if (IsMacroTiled(pInfo
->tileMode
) && pInfo
->pStereoInfo
&& pInfo
->pTileInfo
)
2930 bankBits
= ComputeBankFromCoord(0, pInfo
->height
, 0,
2931 pInfo
->tileMode
, 0, 0, pInfo
->pTileInfo
);
2935 HwlCombineBankPipeSwizzle(bankBits
, 0, pInfo
->pTileInfo
, 0, &swizzle
);
2943 ****************************************************************************************************
2944 * EgBasedLib::ComputeBankFromCoord
2947 * Compute bank number from coordinates
2950 ****************************************************************************************************
2952 UINT_32
EgBasedLib::ComputeBankFromCoord(
2953 UINT_32 x
, ///< [in] x coordinate
2954 UINT_32 y
, ///< [in] y coordinate
2955 UINT_32 slice
, ///< [in] slice index
2956 AddrTileMode tileMode
, ///< [in] tile mode
2957 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2958 UINT_32 tileSplitSlice
, ///< [in] If the size of the pixel offset is larger than the
2959 /// tile split size, then the pixel will be moved to a separate
2960 /// slice. This value equals pixelOffset / tileSplitBytes
2961 /// in this case. Otherwise this is 0.
2962 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2965 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2966 UINT_32 bankBit0
= 0;
2967 UINT_32 bankBit1
= 0;
2968 UINT_32 bankBit2
= 0;
2969 UINT_32 bankBit3
= 0;
2970 UINT_32 sliceRotation
;
2971 UINT_32 tileSplitRotation
;
2973 UINT_32 numBanks
= pTileInfo
->banks
;
2974 UINT_32 bankWidth
= pTileInfo
->bankWidth
;
2975 UINT_32 bankHeight
= pTileInfo
->bankHeight
;
2977 UINT_32 tx
= x
/ MicroTileWidth
/ (bankWidth
* pipes
);
2978 UINT_32 ty
= y
/ MicroTileHeight
/ bankHeight
;
2980 UINT_32 x3
= _BIT(tx
,0);
2981 UINT_32 x4
= _BIT(tx
,1);
2982 UINT_32 x5
= _BIT(tx
,2);
2983 UINT_32 x6
= _BIT(tx
,3);
2984 UINT_32 y3
= _BIT(ty
,0);
2985 UINT_32 y4
= _BIT(ty
,1);
2986 UINT_32 y5
= _BIT(ty
,2);
2987 UINT_32 y6
= _BIT(ty
,3);
2993 bankBit1
= x4
^ y5
^ y6
;
2999 bankBit1
= x4
^ y4
^ y5
;
3010 ADDR_ASSERT_ALWAYS();
3014 bank
= bankBit0
| (bankBit1
<< 1) | (bankBit2
<< 2) | (bankBit3
<< 3);
3016 //Bits2Number(4, bankBit3, bankBit2, bankBit1, bankBit0);
3018 bank
= HwlPreAdjustBank((x
/ MicroTileWidth
), bank
, pTileInfo
);
3020 // Compute bank rotation for the slice.
3022 UINT_32 microTileThickness
= Thickness(tileMode
);
3026 case ADDR_TM_2D_TILED_THIN1
: // fall through
3027 case ADDR_TM_2D_TILED_THICK
: // fall through
3028 case ADDR_TM_2D_TILED_XTHICK
:
3029 sliceRotation
= ((numBanks
/ 2) - 1) * (slice
/ microTileThickness
);
3031 case ADDR_TM_3D_TILED_THIN1
: // fall through
3032 case ADDR_TM_3D_TILED_THICK
: // fall through
3033 case ADDR_TM_3D_TILED_XTHICK
:
3035 Max(1u, (pipes
/ 2) - 1) * (slice
/ microTileThickness
) / pipes
;
3044 // Compute bank rotation for the tile split slice.
3046 // The sample slice will be non-zero if samples must be split across multiple slices.
3047 // This situation arises when the micro tile size multiplied yBit the number of samples exceeds
3048 // the split size (set in GB_ADDR_CONFIG).
3052 case ADDR_TM_2D_TILED_THIN1
: //fall through
3053 case ADDR_TM_3D_TILED_THIN1
: //fall through
3054 case ADDR_TM_PRT_2D_TILED_THIN1
: //fall through
3055 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
3056 tileSplitRotation
= ((numBanks
/ 2) + 1) * tileSplitSlice
;
3059 tileSplitRotation
= 0;
3064 // Apply bank rotation for the slice and tile split slice.
3066 bank
^= bankSwizzle
+ sliceRotation
;
3067 bank
^= tileSplitRotation
;
3069 bank
&= (numBanks
- 1);
3075 ****************************************************************************************************
3076 * EgBasedLib::ComputeBankFromAddr
3079 * Compute the bank number from an address
3082 ****************************************************************************************************
3084 UINT_32
EgBasedLib::ComputeBankFromAddr(
3085 UINT_64 addr
, ///< [in] address
3086 UINT_32 numBanks
, ///< [in] number of banks
3087 UINT_32 numPipes
///< [in] number of pipes
3093 // The LSBs of the address are arranged as follows:
3094 // bank | bankInterleave | pipe | pipeInterleave
3096 // To get the bank number, shift off the pipe interleave, pipe, and bank interlave bits and
3097 // mask the bank bits.
3099 bank
= static_cast<UINT_32
>(
3100 (addr
>> Log2(m_pipeInterleaveBytes
* numPipes
* m_bankInterleave
)) &
3108 ****************************************************************************************************
3109 * EgBasedLib::ComputePipeRotation
3112 * Compute pipe rotation value
3115 ****************************************************************************************************
3117 UINT_32
EgBasedLib::ComputePipeRotation(
3118 AddrTileMode tileMode
, ///< [in] tile mode
3119 UINT_32 numPipes
///< [in] number of pipes
3126 case ADDR_TM_3D_TILED_THIN1
: //fall through
3127 case ADDR_TM_3D_TILED_THICK
: //fall through
3128 case ADDR_TM_3D_TILED_XTHICK
: //fall through
3129 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
3130 case ADDR_TM_PRT_3D_TILED_THICK
:
3131 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1);
3143 ****************************************************************************************************
3144 * EgBasedLib::ComputeBankRotation
3147 * Compute bank rotation value
3150 ****************************************************************************************************
3152 UINT_32
EgBasedLib::ComputeBankRotation(
3153 AddrTileMode tileMode
, ///< [in] tile mode
3154 UINT_32 numBanks
, ///< [in] number of banks
3155 UINT_32 numPipes
///< [in] number of pipes
3162 case ADDR_TM_2D_TILED_THIN1
: // fall through
3163 case ADDR_TM_2D_TILED_THICK
: // fall through
3164 case ADDR_TM_2D_TILED_XTHICK
:
3165 case ADDR_TM_PRT_2D_TILED_THIN1
:
3166 case ADDR_TM_PRT_2D_TILED_THICK
:
3167 // Rotate banks per Z-slice yBit 1 for 4-bank or 3 for 8-bank
3168 rotation
= numBanks
/ 2 - 1;
3170 case ADDR_TM_3D_TILED_THIN1
: // fall through
3171 case ADDR_TM_3D_TILED_THICK
: // fall through
3172 case ADDR_TM_3D_TILED_XTHICK
:
3173 case ADDR_TM_PRT_3D_TILED_THIN1
:
3174 case ADDR_TM_PRT_3D_TILED_THICK
:
3175 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1); // rotate pipes & banks
3186 ****************************************************************************************************
3187 * EgBasedLib::ComputeHtileBytes
3190 * Compute htile size in bytes
3193 * Htile size in bytes
3194 ****************************************************************************************************
3196 UINT_64
EgBasedLib::ComputeHtileBytes(
3197 UINT_32 pitch
, ///< [in] pitch
3198 UINT_32 height
, ///< [in] height
3199 UINT_32 bpp
, ///< [in] bits per pixel
3200 BOOL_32 isLinear
, ///< [in] if it is linear mode
3201 UINT_32 numSlices
, ///< [in] number of slices
3202 UINT_64
* sliceBytes
, ///< [out] bytes per slice
3203 UINT_32 baseAlign
///< [in] base alignments
3208 const UINT_64 HtileCacheLineSize
= BITS_TO_BYTES(HtileCacheBits
);
3210 *sliceBytes
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
/ 64);
3212 if (m_configFlags
.useHtileSliceAlign
)
3214 // Align the sliceSize to htilecachelinesize * pipes at first
3215 *sliceBytes
= PowTwoAlign(*sliceBytes
, HtileCacheLineSize
* m_pipes
);
3216 surfBytes
= *sliceBytes
* numSlices
;
3220 // Align the surfSize to htilecachelinesize * pipes at last
3221 surfBytes
= *sliceBytes
* numSlices
;
3222 surfBytes
= PowTwoAlign(surfBytes
, HtileCacheLineSize
* m_pipes
);
3229 ****************************************************************************************************
3230 * EgBasedLib::DispatchComputeFmaskInfo
3233 * Compute fmask sizes include padded pitch, height, slices, total size in bytes,
3234 * meanwhile output suitable tile mode and alignments as well. Results are returned
3235 * through output parameters.
3239 ****************************************************************************************************
3241 ADDR_E_RETURNCODE
EgBasedLib::DispatchComputeFmaskInfo(
3242 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3243 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
) ///< [out] output structure
3245 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3247 ADDR_COMPUTE_SURFACE_INFO_INPUT surfIn
= {0};
3248 ADDR_COMPUTE_SURFACE_INFO_OUTPUT surfOut
= {0};
3250 // Setup input structure
3251 surfIn
.tileMode
= pIn
->tileMode
;
3252 surfIn
.width
= pIn
->pitch
;
3253 surfIn
.height
= pIn
->height
;
3254 surfIn
.numSlices
= pIn
->numSlices
;
3255 surfIn
.pTileInfo
= pIn
->pTileInfo
;
3256 surfIn
.tileType
= ADDR_NON_DISPLAYABLE
;
3257 surfIn
.flags
.fmask
= 1;
3259 // Setup output structure
3260 surfOut
.pTileInfo
= pOut
->pTileInfo
;
3262 // Setup hwl specific fields
3263 HwlFmaskPreThunkSurfInfo(pIn
, pOut
, &surfIn
, &surfOut
);
3265 surfIn
.bpp
= HwlComputeFmaskBits(pIn
, &surfIn
.numSamples
);
3267 // ComputeSurfaceInfo needs numSamples in surfOut as surface routines need adjusted numSamples
3268 surfOut
.numSamples
= surfIn
.numSamples
;
3270 retCode
= HwlComputeSurfaceInfo(&surfIn
, &surfOut
);
3272 // Save bpp field for surface dump support
3273 surfOut
.bpp
= surfIn
.bpp
;
3275 if (retCode
== ADDR_OK
)
3277 pOut
->bpp
= surfOut
.bpp
;
3278 pOut
->pitch
= surfOut
.pitch
;
3279 pOut
->height
= surfOut
.height
;
3280 pOut
->numSlices
= surfOut
.depth
;
3281 pOut
->fmaskBytes
= surfOut
.surfSize
;
3282 pOut
->baseAlign
= surfOut
.baseAlign
;
3283 pOut
->pitchAlign
= surfOut
.pitchAlign
;
3284 pOut
->heightAlign
= surfOut
.heightAlign
;
3286 if (surfOut
.depth
> 1)
3288 // For fmask, expNumSlices is stored in depth.
3289 pOut
->sliceSize
= surfOut
.surfSize
/ surfOut
.depth
;
3293 pOut
->sliceSize
= surfOut
.surfSize
;
3296 // Save numSamples field for surface dump support
3297 pOut
->numSamples
= surfOut
.numSamples
;
3299 HwlFmaskPostThunkSurfInfo(&surfOut
, pOut
);
3306 ****************************************************************************************************
3307 * EgBasedLib::HwlFmaskSurfaceInfo
3309 * Entry of EgBasedLib ComputeFmaskInfo
3312 ****************************************************************************************************
3314 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskInfo(
3315 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3316 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
3319 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3321 ADDR_TILEINFO tileInfo
= {0};
3323 // Use internal tile info if pOut does not have a valid pTileInfo
3324 if (pOut
->pTileInfo
== NULL
)
3326 pOut
->pTileInfo
= &tileInfo
;
3329 retCode
= DispatchComputeFmaskInfo(pIn
, pOut
);
3331 if (retCode
== ADDR_OK
)
3334 HwlPostCheckTileIndex(pOut
->pTileInfo
, pIn
->tileMode
, ADDR_NON_DISPLAYABLE
,
3338 // Resets pTileInfo to NULL if the internal tile info is used
3339 if (pOut
->pTileInfo
== &tileInfo
)
3341 pOut
->pTileInfo
= NULL
;
3348 ****************************************************************************************************
3349 * EgBasedLib::HwlComputeFmaskAddrFromCoord
3351 * Entry of EgBasedLib ComputeFmaskAddrFromCoord
3354 ****************************************************************************************************
3356 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskAddrFromCoord(
3357 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3358 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3361 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3367 ****************************************************************************************************
3368 * EgBasedLib::HwlComputeFmaskCoordFromAddr
3370 * Entry of EgBasedLib ComputeFmaskCoordFromAddr
3373 ****************************************************************************************************
3375 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskCoordFromAddr(
3376 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3377 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3380 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3386 ****************************************************************************************************
3387 * EgBasedLib::ComputeFmaskNumPlanesFromNumSamples
3390 * Compute fmask number of planes from number of samples
3394 ****************************************************************************************************
3396 UINT_32
EgBasedLib::ComputeFmaskNumPlanesFromNumSamples(
3397 UINT_32 numSamples
) ///< [in] number of samples
3402 // FMASK is stored such that each micro tile is composed of elements containing N bits, where
3403 // N is the number of samples. There is a micro tile for each bit in the FMASK address, and
3404 // micro tiles for each address bit, sometimes referred to as a plane, are stored sequentially.
3405 // The FMASK for a 2-sample surface looks like a general surface with 2 bits per element.
3406 // The FMASK for a 4-sample surface looks like a general surface with 4 bits per element and
3407 // 2 samples. The FMASK for an 8-sample surface looks like a general surface with 8 bits per
3408 // element and 4 samples. R6xx and R7xx only stored 3 planes for 8-sample FMASK surfaces.
3409 // This was changed for R8xx to simplify the logic in the CB.
3423 ADDR_UNHANDLED_CASE();
3431 ****************************************************************************************************
3432 * EgBasedLib::ComputeFmaskResolvedBppFromNumSamples
3435 * Compute resolved fmask effective bpp based on number of samples
3439 ****************************************************************************************************
3441 UINT_32
EgBasedLib::ComputeFmaskResolvedBppFromNumSamples(
3442 UINT_32 numSamples
) ///< number of samples
3447 // Resolved FMASK surfaces are generated yBit the CB and read yBit the texture unit
3448 // so that the texture unit can read compressed multi-sample color data.
3449 // These surfaces store each index value packed per element.
3450 // Each element contains at least num_samples * log2(num_samples) bits.
3451 // Resolved FMASK surfaces are addressed as follows:
3452 // 2-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3453 // 4-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3454 // 8-sample Addressed similarly to a color surface with 32 bits per element and 1 sample.
3468 ADDR_UNHANDLED_CASE();
3476 ****************************************************************************************************
3477 * EgBasedLib::IsTileInfoAllZero
3480 * Return TRUE if all field are zero
3482 * Since NULL input is consider to be all zero
3483 ****************************************************************************************************
3485 BOOL_32
EgBasedLib::IsTileInfoAllZero(
3486 const ADDR_TILEINFO
* pTileInfo
)
3488 BOOL_32 allZero
= TRUE
;
3492 if ((pTileInfo
->banks
!= 0) ||
3493 (pTileInfo
->bankWidth
!= 0) ||
3494 (pTileInfo
->bankHeight
!= 0) ||
3495 (pTileInfo
->macroAspectRatio
!= 0) ||
3496 (pTileInfo
->tileSplitBytes
!= 0) ||
3497 (pTileInfo
->pipeConfig
!= 0)
3508 ****************************************************************************************************
3509 * EgBasedLib::HwlTileInfoEqual
3512 * Return TRUE if all field are equal
3514 * Only takes care of current HWL's data
3515 ****************************************************************************************************
3517 BOOL_32
EgBasedLib::HwlTileInfoEqual(
3518 const ADDR_TILEINFO
* pLeft
, ///<[in] Left compare operand
3519 const ADDR_TILEINFO
* pRight
///<[in] Right compare operand
3522 BOOL_32 equal
= FALSE
;
3524 if (pLeft
->banks
== pRight
->banks
&&
3525 pLeft
->bankWidth
== pRight
->bankWidth
&&
3526 pLeft
->bankHeight
== pRight
->bankHeight
&&
3527 pLeft
->macroAspectRatio
== pRight
->macroAspectRatio
&&
3528 pLeft
->tileSplitBytes
== pRight
->tileSplitBytes
)
3537 ****************************************************************************************************
3538 * EgBasedLib::HwlConvertTileInfoToHW
3540 * Entry of EgBasedLib ConvertTileInfoToHW
3543 ****************************************************************************************************
3545 ADDR_E_RETURNCODE
EgBasedLib::HwlConvertTileInfoToHW(
3546 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
3547 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
3550 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3552 ADDR_TILEINFO
*pTileInfoIn
= pIn
->pTileInfo
;
3553 ADDR_TILEINFO
*pTileInfoOut
= pOut
->pTileInfo
;
3555 if ((pTileInfoIn
!= NULL
) && (pTileInfoOut
!= NULL
))
3557 if (pIn
->reverse
== FALSE
)
3559 switch (pTileInfoIn
->banks
)
3562 pTileInfoOut
->banks
= 0;
3565 pTileInfoOut
->banks
= 1;
3568 pTileInfoOut
->banks
= 2;
3571 pTileInfoOut
->banks
= 3;
3574 ADDR_ASSERT_ALWAYS();
3575 retCode
= ADDR_INVALIDPARAMS
;
3576 pTileInfoOut
->banks
= 0;
3580 switch (pTileInfoIn
->bankWidth
)
3583 pTileInfoOut
->bankWidth
= 0;
3586 pTileInfoOut
->bankWidth
= 1;
3589 pTileInfoOut
->bankWidth
= 2;
3592 pTileInfoOut
->bankWidth
= 3;
3595 ADDR_ASSERT_ALWAYS();
3596 retCode
= ADDR_INVALIDPARAMS
;
3597 pTileInfoOut
->bankWidth
= 0;
3601 switch (pTileInfoIn
->bankHeight
)
3604 pTileInfoOut
->bankHeight
= 0;
3607 pTileInfoOut
->bankHeight
= 1;
3610 pTileInfoOut
->bankHeight
= 2;
3613 pTileInfoOut
->bankHeight
= 3;
3616 ADDR_ASSERT_ALWAYS();
3617 retCode
= ADDR_INVALIDPARAMS
;
3618 pTileInfoOut
->bankHeight
= 0;
3622 switch (pTileInfoIn
->macroAspectRatio
)
3625 pTileInfoOut
->macroAspectRatio
= 0;
3628 pTileInfoOut
->macroAspectRatio
= 1;
3631 pTileInfoOut
->macroAspectRatio
= 2;
3634 pTileInfoOut
->macroAspectRatio
= 3;
3637 ADDR_ASSERT_ALWAYS();
3638 retCode
= ADDR_INVALIDPARAMS
;
3639 pTileInfoOut
->macroAspectRatio
= 0;
3643 switch (pTileInfoIn
->tileSplitBytes
)
3646 pTileInfoOut
->tileSplitBytes
= 0;
3649 pTileInfoOut
->tileSplitBytes
= 1;
3652 pTileInfoOut
->tileSplitBytes
= 2;
3655 pTileInfoOut
->tileSplitBytes
= 3;
3658 pTileInfoOut
->tileSplitBytes
= 4;
3661 pTileInfoOut
->tileSplitBytes
= 5;
3664 pTileInfoOut
->tileSplitBytes
= 6;
3667 ADDR_ASSERT_ALWAYS();
3668 retCode
= ADDR_INVALIDPARAMS
;
3669 pTileInfoOut
->tileSplitBytes
= 0;
3675 switch (pTileInfoIn
->banks
)
3678 pTileInfoOut
->banks
= 2;
3681 pTileInfoOut
->banks
= 4;
3684 pTileInfoOut
->banks
= 8;
3687 pTileInfoOut
->banks
= 16;
3690 ADDR_ASSERT_ALWAYS();
3691 retCode
= ADDR_INVALIDPARAMS
;
3692 pTileInfoOut
->banks
= 2;
3696 switch (pTileInfoIn
->bankWidth
)
3699 pTileInfoOut
->bankWidth
= 1;
3702 pTileInfoOut
->bankWidth
= 2;
3705 pTileInfoOut
->bankWidth
= 4;
3708 pTileInfoOut
->bankWidth
= 8;
3711 ADDR_ASSERT_ALWAYS();
3712 retCode
= ADDR_INVALIDPARAMS
;
3713 pTileInfoOut
->bankWidth
= 1;
3717 switch (pTileInfoIn
->bankHeight
)
3720 pTileInfoOut
->bankHeight
= 1;
3723 pTileInfoOut
->bankHeight
= 2;
3726 pTileInfoOut
->bankHeight
= 4;
3729 pTileInfoOut
->bankHeight
= 8;
3732 ADDR_ASSERT_ALWAYS();
3733 retCode
= ADDR_INVALIDPARAMS
;
3734 pTileInfoOut
->bankHeight
= 1;
3738 switch (pTileInfoIn
->macroAspectRatio
)
3741 pTileInfoOut
->macroAspectRatio
= 1;
3744 pTileInfoOut
->macroAspectRatio
= 2;
3747 pTileInfoOut
->macroAspectRatio
= 4;
3750 pTileInfoOut
->macroAspectRatio
= 8;
3753 ADDR_ASSERT_ALWAYS();
3754 retCode
= ADDR_INVALIDPARAMS
;
3755 pTileInfoOut
->macroAspectRatio
= 1;
3759 switch (pTileInfoIn
->tileSplitBytes
)
3762 pTileInfoOut
->tileSplitBytes
= 64;
3765 pTileInfoOut
->tileSplitBytes
= 128;
3768 pTileInfoOut
->tileSplitBytes
= 256;
3771 pTileInfoOut
->tileSplitBytes
= 512;
3774 pTileInfoOut
->tileSplitBytes
= 1024;
3777 pTileInfoOut
->tileSplitBytes
= 2048;
3780 pTileInfoOut
->tileSplitBytes
= 4096;
3783 ADDR_ASSERT_ALWAYS();
3784 retCode
= ADDR_INVALIDPARAMS
;
3785 pTileInfoOut
->tileSplitBytes
= 64;
3790 if (pTileInfoIn
!= pTileInfoOut
)
3792 pTileInfoOut
->pipeConfig
= pTileInfoIn
->pipeConfig
;
3797 ADDR_ASSERT_ALWAYS();
3798 retCode
= ADDR_INVALIDPARAMS
;
3805 ****************************************************************************************************
3806 * EgBasedLib::HwlComputeSurfaceInfo
3808 * Entry of EgBasedLib ComputeSurfaceInfo
3811 ****************************************************************************************************
3813 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceInfo(
3814 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
3815 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
3818 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3820 if (pIn
->numSamples
< pIn
->numFrags
)
3822 retCode
= ADDR_INVALIDPARAMS
;
3825 ADDR_TILEINFO tileInfo
= {0};
3827 if (retCode
== ADDR_OK
)
3829 // Uses internal tile info if pOut does not have a valid pTileInfo
3830 if (pOut
->pTileInfo
== NULL
)
3832 pOut
->pTileInfo
= &tileInfo
;
3835 if (DispatchComputeSurfaceInfo(pIn
, pOut
) == FALSE
)
3837 retCode
= ADDR_INVALIDPARAMS
;
3840 // In case client uses tile info as input and would like to calculate a correct size and
3841 // alignment together with tile info as output when the tile info is not suppose to have any
3842 // matching indices in tile mode tables.
3843 if (pIn
->flags
.skipIndicesOutput
== FALSE
)
3846 pOut
->tileIndex
= HwlPostCheckTileIndex(pOut
->pTileInfo
,
3851 if (IsMacroTiled(pOut
->tileMode
) && (pOut
->macroModeIndex
== TileIndexInvalid
))
3853 pOut
->macroModeIndex
= HwlComputeMacroModeIndex(pOut
->tileIndex
,
3861 // Resets pTileInfo to NULL if the internal tile info is used
3862 if (pOut
->pTileInfo
== &tileInfo
)
3865 // Client does not pass in a valid pTileInfo
3866 if (IsMacroTiled(pOut
->tileMode
))
3868 // If a valid index is returned, then no pTileInfo is okay
3869 ADDR_ASSERT((m_configFlags
.useTileIndex
== FALSE
) ||
3870 (pOut
->tileIndex
!= TileIndexInvalid
));
3872 if (IsTileInfoAllZero(pIn
->pTileInfo
) == FALSE
)
3874 // The initial value of pIn->pTileInfo is copied to tileInfo
3875 // We do not expect any of these value to be changed nor any 0 of inputs
3876 ADDR_ASSERT(tileInfo
.banks
== pIn
->pTileInfo
->banks
);
3877 ADDR_ASSERT(tileInfo
.bankWidth
== pIn
->pTileInfo
->bankWidth
);
3878 ADDR_ASSERT(tileInfo
.bankHeight
== pIn
->pTileInfo
->bankHeight
);
3879 ADDR_ASSERT(tileInfo
.macroAspectRatio
== pIn
->pTileInfo
->macroAspectRatio
);
3880 ADDR_ASSERT(tileInfo
.tileSplitBytes
== pIn
->pTileInfo
->tileSplitBytes
);
3884 pOut
->pTileInfo
= NULL
;
3892 ****************************************************************************************************
3893 * EgBasedLib::HwlComputeSurfaceAddrFromCoord
3895 * Entry of EgBasedLib ComputeSurfaceAddrFromCoord
3898 ****************************************************************************************************
3900 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceAddrFromCoord(
3901 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3902 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3905 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3908 #if !ALT_TEST // Overflow test needs this out-of-boundary coord
3909 (pIn
->x
> pIn
->pitch
) ||
3910 (pIn
->y
> pIn
->height
) ||
3912 (pIn
->numSamples
> m_maxSamples
))
3914 retCode
= ADDR_INVALIDPARAMS
;
3918 pOut
->addr
= DispatchComputeSurfaceAddrFromCoord(pIn
, pOut
);
3925 ****************************************************************************************************
3926 * EgBasedLib::HwlComputeSurfaceCoordFromAddr
3928 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
3931 ****************************************************************************************************
3933 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceCoordFromAddr(
3934 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3935 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3938 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3940 if ((pIn
->bitPosition
>= 8) ||
3941 (pIn
->numSamples
> m_maxSamples
))
3943 retCode
= ADDR_INVALIDPARAMS
;
3947 DispatchComputeSurfaceCoordFromAddr(pIn
, pOut
);
3953 ****************************************************************************************************
3954 * EgBasedLib::HwlComputeSliceTileSwizzle
3956 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
3959 ****************************************************************************************************
3961 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSliceTileSwizzle(
3962 const ADDR_COMPUTE_SLICESWIZZLE_INPUT
* pIn
, ///< [in] input structure
3963 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
* pOut
///< [out] output structure
3966 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3968 if (pIn
->pTileInfo
&& (pIn
->pTileInfo
->banks
> 0))
3971 pOut
->tileSwizzle
= ComputeSliceTileSwizzle(pIn
->tileMode
,
3979 retCode
= ADDR_INVALIDPARAMS
;
3986 ****************************************************************************************************
3987 * EgBasedLib::HwlComputeHtileBpp
3994 ****************************************************************************************************
3996 UINT_32
EgBasedLib::HwlComputeHtileBpp(
3997 BOOL_32 isWidth8
, ///< [in] TRUE if block width is 8
3998 BOOL_32 isHeight8
///< [in] TRUE if block height is 8
4001 // only support 8x8 mode
4002 ADDR_ASSERT(isWidth8
&& isHeight8
);
4007 ****************************************************************************************************
4008 * EgBasedLib::HwlComputeHtileBaseAlign
4011 * Compute htile base alignment
4014 * Htile base alignment
4015 ****************************************************************************************************
4017 UINT_32
EgBasedLib::HwlComputeHtileBaseAlign(
4018 BOOL_32 isTcCompatible
, ///< [in] if TC compatible
4019 BOOL_32 isLinear
, ///< [in] if it is linear mode
4020 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
4023 UINT_32 baseAlign
= m_pipeInterleaveBytes
* HwlGetPipes(pTileInfo
);
4027 ADDR_ASSERT(pTileInfo
!= NULL
);
4030 baseAlign
*= pTileInfo
->banks
;
4038 ****************************************************************************************************
4039 * EgBasedLib::HwlGetPitchAlignmentMicroTiled
4042 * Compute 1D tiled surface pitch alignment, calculation results are returned through
4043 * output parameters.
4047 ****************************************************************************************************
4049 UINT_32
EgBasedLib::HwlGetPitchAlignmentMicroTiled(
4050 AddrTileMode tileMode
, ///< [in] tile mode
4051 UINT_32 bpp
, ///< [in] bits per pixel
4052 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4053 UINT_32 numSamples
///< [in] number of samples
4058 UINT_32 microTileThickness
= Thickness(tileMode
);
4060 UINT_32 pixelsPerMicroTile
;
4061 UINT_32 pixelsPerPipeInterleave
;
4062 UINT_32 microTilesPerPipeInterleave
;
4065 // Special workaround for depth/stencil buffer, use 8 bpp to meet larger requirement for
4066 // stencil buffer since pitch alignment is related to bpp.
4067 // For a depth only buffer do not set this.
4069 // Note: this actually does not work for mipmap but mipmap depth texture is not really
4070 // sampled with mipmap.
4072 if (flags
.depth
&& (flags
.noStencil
== FALSE
))
4077 pixelsPerMicroTile
= MicroTilePixels
* microTileThickness
;
4078 pixelsPerPipeInterleave
= BYTES_TO_BITS(m_pipeInterleaveBytes
) / (bpp
* numSamples
);
4079 microTilesPerPipeInterleave
= pixelsPerPipeInterleave
/ pixelsPerMicroTile
;
4081 pitchAlign
= Max(MicroTileWidth
, microTilesPerPipeInterleave
* MicroTileWidth
);
4087 ****************************************************************************************************
4088 * EgBasedLib::HwlGetSizeAdjustmentMicroTiled
4091 * Adjust 1D tiled surface pitch and slice size
4094 * Logical slice size in bytes
4095 ****************************************************************************************************
4097 UINT_64
EgBasedLib::HwlGetSizeAdjustmentMicroTiled(
4098 UINT_32 thickness
, ///< [in] thickness
4099 UINT_32 bpp
, ///< [in] bits per pixel
4100 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4101 UINT_32 numSamples
, ///< [in] number of samples
4102 UINT_32 baseAlign
, ///< [in] base alignment
4103 UINT_32 pitchAlign
, ///< [in] pitch alignment
4104 UINT_32
* pPitch
, ///< [in,out] pointer to pitch
4105 UINT_32
* pHeight
///< [in,out] pointer to height
4108 UINT_64 logicalSliceSize
;
4109 UINT_64 physicalSliceSize
;
4111 UINT_32 pitch
= *pPitch
;
4112 UINT_32 height
= *pHeight
;
4114 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
4115 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
4117 // Physical slice: multiplied by thickness
4118 physicalSliceSize
= logicalSliceSize
* thickness
;
4121 // R800 will always pad physical slice size to baseAlign which is pipe_interleave_bytes
4123 ADDR_ASSERT((physicalSliceSize
% baseAlign
) == 0);
4125 return logicalSliceSize
;
4129 ****************************************************************************************************
4130 * EgBasedLib::HwlStereoCheckRightOffsetPadding
4133 * check if the height needs extra padding for stereo right eye offset, to avoid swizzling
4136 * TRUE is the extra padding is needed
4138 ****************************************************************************************************
4140 UINT_32
EgBasedLib::HwlStereoCheckRightOffsetPadding(
4141 ADDR_TILEINFO
* pTileInfo
///< Tiling info
4144 UINT_32 stereoHeightAlign
= 0;
4146 if (pTileInfo
->macroAspectRatio
> 2)
4148 // Since 3D rendering treats right eye surface starting from y == "eye height" while
4149 // display engine treats it to be 0, so the bank bits may be different.
4150 // Additional padding in height is required to make sure it's possible
4151 // to achieve synonym by adjusting bank swizzle of right eye surface.
4153 static const UINT_32 StereoAspectRatio
= 2;
4154 stereoHeightAlign
= pTileInfo
->banks
*
4155 pTileInfo
->bankHeight
*
4160 return stereoHeightAlign
;