2 * Copyright © 2007-2018 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"
36 #include "util/macros.h"
44 ****************************************************************************************************
45 * EgBasedLib::EgBasedLib
52 ****************************************************************************************************
54 EgBasedLib::EgBasedLib(const Client
* pClient
)
64 ****************************************************************************************************
65 * EgBasedLib::~EgBasedLib
69 ****************************************************************************************************
71 EgBasedLib::~EgBasedLib()
76 ****************************************************************************************************
77 * EgBasedLib::DispatchComputeSurfaceInfo
80 * Compute surface sizes include padded pitch,height,slices,total size in bytes,
81 * meanwhile output suitable tile mode and base alignment might be changed in this
82 * call as well. Results are returned through output parameters.
85 * TRUE if no error occurs
86 ****************************************************************************************************
88 BOOL_32
EgBasedLib::DispatchComputeSurfaceInfo(
89 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
90 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
93 AddrTileMode tileMode
= pIn
->tileMode
;
94 UINT_32 bpp
= pIn
->bpp
;
95 UINT_32 numSamples
= pIn
->numSamples
;
96 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
97 UINT_32 pitch
= pIn
->width
;
98 UINT_32 height
= pIn
->height
;
99 UINT_32 numSlices
= pIn
->numSlices
;
100 UINT_32 mipLevel
= pIn
->mipLevel
;
101 ADDR_SURFACE_FLAGS flags
= pIn
->flags
;
103 ADDR_TILEINFO tileInfoDef
= {0};
104 ADDR_TILEINFO
* pTileInfo
= &tileInfoDef
;
108 if (pIn
->flags
.disallowLargeThickDegrade
== 0)
110 tileMode
= DegradeLargeThickTile(tileMode
, bpp
);
113 // Only override numSamples for NI above
114 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
116 if (numFrags
!= numSamples
) // This means EQAA
118 // The real surface size needed is determined by number of fragments
119 numSamples
= numFrags
;
122 // Save altered numSamples in pOut
123 pOut
->numSamples
= numSamples
;
126 // Caller makes sure pOut->pTileInfo is not NULL, see HwlComputeSurfaceInfo
127 ADDR_ASSERT(pOut
->pTileInfo
);
129 if (pOut
->pTileInfo
!= NULL
)
131 pTileInfo
= pOut
->pTileInfo
;
134 // Set default values
135 if (pIn
->pTileInfo
!= NULL
)
137 if (pTileInfo
!= pIn
->pTileInfo
)
139 *pTileInfo
= *pIn
->pTileInfo
;
144 memset(pTileInfo
, 0, sizeof(ADDR_TILEINFO
));
147 // For macro tile mode, we should calculate default tiling parameters
148 HwlSetupTileInfo(tileMode
,
168 // This is calculating one face, remove cube flag
175 case ADDR_TM_LINEAR_GENERAL
://fall through
176 case ADDR_TM_LINEAR_ALIGNED
:
177 valid
= ComputeSurfaceInfoLinear(pIn
, pOut
, padDims
);
180 case ADDR_TM_1D_TILED_THIN1
://fall through
181 case ADDR_TM_1D_TILED_THICK
:
182 valid
= ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, tileMode
);
185 case ADDR_TM_2D_TILED_THIN1
: //fall through
186 case ADDR_TM_2D_TILED_THICK
: //fall through
187 case ADDR_TM_3D_TILED_THIN1
: //fall through
188 case ADDR_TM_3D_TILED_THICK
: //fall through
189 case ADDR_TM_2D_TILED_XTHICK
: //fall through
190 case ADDR_TM_3D_TILED_XTHICK
: //fall through
191 case ADDR_TM_PRT_TILED_THIN1
: //fall through
192 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
193 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
194 case ADDR_TM_PRT_TILED_THICK
: //fall through
195 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
196 case ADDR_TM_PRT_3D_TILED_THICK
:
197 valid
= ComputeSurfaceInfoMacroTiled(pIn
, pOut
, padDims
, tileMode
);
202 ADDR_ASSERT_ALWAYS();
210 ****************************************************************************************************
211 * EgBasedLib::ComputeSurfaceInfoLinear
214 * Compute linear surface sizes include padded pitch, height, slices, total size in
215 * bytes, meanwhile alignments as well. Since it is linear mode, so output tile mode
216 * will not be changed here. Results are returned through output parameters.
219 * TRUE if no error occurs
220 ****************************************************************************************************
222 BOOL_32
EgBasedLib::ComputeSurfaceInfoLinear(
223 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
224 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
225 UINT_32 padDims
///< [in] Dimensions to padd
228 UINT_32 expPitch
= pIn
->width
;
229 UINT_32 expHeight
= pIn
->height
;
230 UINT_32 expNumSlices
= pIn
->numSlices
;
232 // No linear MSAA on real H/W, keep this for TGL
233 UINT_32 numSamples
= pOut
->numSamples
;
235 const UINT_32 microTileThickness
= 1;
238 // Compute the surface alignments.
240 ComputeSurfaceAlignmentsLinear(pIn
->tileMode
,
247 if ((pIn
->tileMode
== ADDR_TM_LINEAR_GENERAL
) && pIn
->flags
.color
&& (pIn
->height
> 1))
250 // When linear_general surface is accessed in multiple lines, it requires 8 pixels in pitch
251 // alignment since PITCH_TILE_MAX is in unit of 8 pixels.
252 // It is OK if it is accessed per line.
253 ADDR_ASSERT((pIn
->width
% 8) == 0);
257 pOut
->depthAlign
= microTileThickness
;
259 expPitch
= HwlPreHandleBaseLvl3xPitch(pIn
, expPitch
);
262 // Pad pitch and height to the required granularities.
264 PadDimensions(pIn
->tileMode
,
271 &expPitch
, &pOut
->pitchAlign
,
272 &expHeight
, pOut
->heightAlign
,
273 &expNumSlices
, microTileThickness
);
275 expPitch
= HwlPostHandleBaseLvl3xPitch(pIn
, expPitch
);
281 UINT_64 logicalSliceSize
;
283 logicalSliceSize
= HwlGetSizeAdjustmentLinear(pIn
->tileMode
,
292 if ((pIn
->pitchAlign
!= 0) || (pIn
->heightAlign
!= 0))
294 if (pIn
->pitchAlign
!= 0)
296 ADDR_ASSERT((pIn
->pitchAlign
% pOut
->pitchAlign
) == 0);
297 pOut
->pitchAlign
= pIn
->pitchAlign
;
299 if (IsPow2(pOut
->pitchAlign
))
301 expPitch
= PowTwoAlign(expPitch
, pOut
->pitchAlign
);
305 expPitch
+= pOut
->pitchAlign
- 1;
306 expPitch
/= pOut
->pitchAlign
;
307 expPitch
*= pOut
->pitchAlign
;
311 if (pIn
->heightAlign
!= 0)
313 ADDR_ASSERT((pIn
->heightAlign
% pOut
->heightAlign
) == 0);
314 pOut
->heightAlign
= pIn
->heightAlign
;
316 if (IsPow2(pOut
->heightAlign
))
318 expHeight
= PowTwoAlign(expHeight
, pOut
->heightAlign
);
322 expHeight
+= pOut
->heightAlign
- 1;
323 expHeight
/= pOut
->heightAlign
;
324 expHeight
*= pOut
->heightAlign
;
328 logicalSliceSize
= BITS_TO_BYTES(expPitch
* expHeight
* pIn
->bpp
);
331 pOut
->pitch
= expPitch
;
332 pOut
->height
= expHeight
;
333 pOut
->depth
= expNumSlices
;
335 pOut
->surfSize
= logicalSliceSize
* expNumSlices
;
337 pOut
->tileMode
= pIn
->tileMode
;
343 ****************************************************************************************************
344 * EgBasedLib::ComputeSurfaceInfoMicroTiled
347 * Compute 1D/Micro Tiled surface sizes include padded pitch, height, slices, total
348 * size in bytes, meanwhile alignments as well. Results are returned through output
352 * TRUE if no error occurs
353 ****************************************************************************************************
355 BOOL_32
EgBasedLib::ComputeSurfaceInfoMicroTiled(
356 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
357 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
358 UINT_32 padDims
, ///< [in] Dimensions to padd
359 AddrTileMode expTileMode
///< [in] Expected tile mode
362 BOOL_32 valid
= TRUE
;
364 UINT_32 microTileThickness
;
365 UINT_32 expPitch
= pIn
->width
;
366 UINT_32 expHeight
= pIn
->height
;
367 UINT_32 expNumSlices
= pIn
->numSlices
;
369 // No 1D MSAA on real H/W, keep this for TGL
370 UINT_32 numSamples
= pOut
->numSamples
;
373 // Compute the micro tile thickness.
375 microTileThickness
= Thickness(expTileMode
);
378 // Extra override for mip levels
380 if (pIn
->mipLevel
> 0)
383 // Reduce tiling mode from thick to thin if the number of slices is less than the
384 // micro tile thickness.
386 if ((expTileMode
== ADDR_TM_1D_TILED_THICK
) &&
387 (expNumSlices
< ThickTileThickness
))
389 expTileMode
= HwlDegradeThickTileMode(ADDR_TM_1D_TILED_THICK
, expNumSlices
, NULL
);
390 if (expTileMode
!= ADDR_TM_1D_TILED_THICK
)
392 microTileThickness
= 1;
398 // Compute the surface restrictions.
400 ComputeSurfaceAlignmentsMicroTiled(expTileMode
,
409 pOut
->depthAlign
= microTileThickness
;
412 // Pad pitch and height to the required granularities.
413 // Compute surface size.
414 // Return parameters.
416 PadDimensions(expTileMode
,
423 &expPitch
, &pOut
->pitchAlign
,
424 &expHeight
, pOut
->heightAlign
,
425 &expNumSlices
, microTileThickness
);
428 // Get HWL specific pitch adjustment
430 UINT_64 logicalSliceSize
= HwlGetSizeAdjustmentMicroTiled(microTileThickness
,
439 pOut
->pitch
= expPitch
;
440 pOut
->height
= expHeight
;
441 pOut
->depth
= expNumSlices
;
443 pOut
->surfSize
= logicalSliceSize
* expNumSlices
;
445 pOut
->tileMode
= expTileMode
;
451 ****************************************************************************************************
452 * EgBasedLib::ComputeSurfaceInfoMacroTiled
455 * Compute 2D/macro tiled surface sizes include padded pitch, height, slices, total
456 * size in bytes, meanwhile output suitable tile mode and alignments might be changed
457 * in this call as well. Results are returned through output parameters.
460 * TRUE if no error occurs
461 ****************************************************************************************************
463 BOOL_32
EgBasedLib::ComputeSurfaceInfoMacroTiled(
464 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
465 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
466 UINT_32 padDims
, ///< [in] Dimensions to padd
467 AddrTileMode expTileMode
///< [in] Expected tile mode
470 BOOL_32 valid
= TRUE
;
472 AddrTileMode origTileMode
= expTileMode
;
473 UINT_32 microTileThickness
;
476 UINT_32 paddedHeight
;
477 UINT_64 bytesPerSlice
;
479 UINT_32 expPitch
= pIn
->width
;
480 UINT_32 expHeight
= pIn
->height
;
481 UINT_32 expNumSlices
= pIn
->numSlices
;
483 UINT_32 numSamples
= pOut
->numSamples
;
486 // Compute the surface restrictions as base
487 // SanityCheckMacroTiled is called in ComputeSurfaceAlignmentsMacroTiled
489 valid
= ComputeSurfaceAlignmentsMacroTiled(expTileMode
,
499 // Compute the micro tile thickness.
501 microTileThickness
= Thickness(expTileMode
);
504 // Find the correct tiling mode for mip levels
506 if (pIn
->mipLevel
> 0)
509 // Try valid tile mode
511 expTileMode
= ComputeSurfaceMipLevelTileMode(expTileMode
,
521 if (!IsMacroTiled(expTileMode
)) // Downgraded to micro-tiled
523 return ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, expTileMode
);
525 else if (microTileThickness
!= Thickness(expTileMode
))
528 // Re-compute if thickness changed since bank-height may be changed!
530 return ComputeSurfaceInfoMacroTiled(pIn
, pOut
, padDims
, expTileMode
);
534 paddedPitch
= expPitch
;
535 paddedHeight
= expHeight
;
540 if (expTileMode
!= origTileMode
) // Tile mode is changed but still macro-tiled
542 valid
= ComputeSurfaceAlignmentsMacroTiled(expTileMode
,
553 PadDimensions(expTileMode
,
560 &paddedPitch
, &pOut
->pitchAlign
,
561 &paddedHeight
, pOut
->heightAlign
,
562 &expNumSlices
, microTileThickness
);
564 if (pIn
->flags
.qbStereo
&&
565 (pOut
->pStereoInfo
!= NULL
))
567 UINT_32 stereoHeightAlign
= HwlStereoCheckRightOffsetPadding(pOut
->pTileInfo
);
569 if (stereoHeightAlign
!= 0)
571 paddedHeight
= PowTwoAlign(paddedHeight
, stereoHeightAlign
);
575 if ((pIn
->flags
.needEquation
== TRUE
) &&
576 (m_chipFamily
== ADDR_CHIP_FAMILY_SI
) &&
577 (pIn
->numMipLevels
> 1) &&
578 (pIn
->mipLevel
== 0))
580 BOOL_32 convertTo1D
= FALSE
;
582 ADDR_ASSERT(Thickness(expTileMode
) == 1);
584 for (UINT_32 i
= 1; i
< pIn
->numMipLevels
; i
++)
586 UINT_32 mipPitch
= Max(1u, paddedPitch
>> i
);
587 UINT_32 mipHeight
= Max(1u, pIn
->height
>> i
);
588 UINT_32 mipSlices
= pIn
->flags
.volume
?
589 Max(1u, pIn
->numSlices
>> i
) : pIn
->numSlices
;
590 expTileMode
= ComputeSurfaceMipLevelTileMode(expTileMode
,
600 if (IsMacroTiled(expTileMode
))
602 if (PowTwoAlign(mipPitch
, pOut
->blockWidth
) !=
603 PowTwoAlign(mipPitch
, pOut
->pitchAlign
))
617 return ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, ADDR_TM_1D_TILED_THIN1
);
621 pOut
->pitch
= paddedPitch
;
622 // Put this check right here to workaround special mipmap cases which the original height
624 // The original height is pre-stored in pOut->height in PostComputeMipLevel and
625 // pOut->pitch is needed in HwlCheckLastMacroTiledLvl, too.
626 if (m_configFlags
.checkLast2DLevel
&& (numSamples
== 1)) // Don't check MSAA
628 // Set a TRUE in pOut if next Level is the first 1D sub level
629 HwlCheckLastMacroTiledLvl(pIn
, pOut
);
631 pOut
->height
= paddedHeight
;
633 pOut
->depth
= expNumSlices
;
636 // Compute the size of a slice.
638 bytesPerSlice
= BITS_TO_BYTES(static_cast<UINT_64
>(paddedPitch
) *
639 paddedHeight
* NextPow2(pIn
->bpp
) * numSamples
);
641 pOut
->surfSize
= bytesPerSlice
* expNumSlices
;
643 pOut
->tileMode
= expTileMode
;
645 pOut
->depthAlign
= microTileThickness
;
653 ****************************************************************************************************
654 * EgBasedLib::ComputeSurfaceAlignmentsLinear
657 * Compute linear surface alignment, calculation results are returned through
661 * TRUE if no error occurs
662 ****************************************************************************************************
664 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsLinear(
665 AddrTileMode tileMode
, ///< [in] tile mode
666 UINT_32 bpp
, ///< [in] bits per pixel
667 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
668 UINT_32
* pBaseAlign
, ///< [out] base address alignment in bytes
669 UINT_32
* pPitchAlign
, ///< [out] pitch alignment in pixels
670 UINT_32
* pHeightAlign
///< [out] height alignment in pixels
673 BOOL_32 valid
= TRUE
;
677 case ADDR_TM_LINEAR_GENERAL
:
679 // The required base alignment and pitch and height granularities is to 1 element.
681 *pBaseAlign
= (bpp
> 8) ? bpp
/ 8 : 1;
685 case ADDR_TM_LINEAR_ALIGNED
:
687 // The required alignment for base is the pipe interleave size.
688 // The required granularity for pitch is hwl dependent.
689 // The required granularity for height is one row.
691 *pBaseAlign
= m_pipeInterleaveBytes
;
692 *pPitchAlign
= HwlGetPitchAlignmentLinear(bpp
, flags
);
699 ADDR_UNHANDLED_CASE();
703 AdjustPitchAlignment(flags
, pPitchAlign
);
709 ****************************************************************************************************
710 * EgBasedLib::ComputeSurfaceAlignmentsMicroTiled
713 * Compute 1D tiled surface alignment, calculation results are returned through
717 * TRUE if no error occurs
718 ****************************************************************************************************
720 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsMicroTiled(
721 AddrTileMode tileMode
, ///< [in] tile mode
722 UINT_32 bpp
, ///< [in] bits per pixel
723 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
724 UINT_32 mipLevel
, ///< [in] mip level
725 UINT_32 numSamples
, ///< [in] number of samples
726 UINT_32
* pBaseAlign
, ///< [out] base address alignment in bytes
727 UINT_32
* pPitchAlign
, ///< [out] pitch alignment in pixels
728 UINT_32
* pHeightAlign
///< [out] height alignment in pixels
731 BOOL_32 valid
= TRUE
;
734 // The required alignment for base is the pipe interleave size.
736 *pBaseAlign
= m_pipeInterleaveBytes
;
738 *pPitchAlign
= HwlGetPitchAlignmentMicroTiled(tileMode
, bpp
, flags
, numSamples
);
740 *pHeightAlign
= MicroTileHeight
;
742 AdjustPitchAlignment(flags
, pPitchAlign
);
744 // Workaround 2 for 1D tiling - There is HW bug for Carrizo,
745 // where it requires the following alignments for 1D tiling.
746 if (flags
.czDispCompatible
&& (mipLevel
== 0))
748 *pBaseAlign
= PowTwoAlign(*pBaseAlign
, 4096); //Base address MOD 4096 = 0
749 *pPitchAlign
= PowTwoAlign(*pPitchAlign
, 512 / (BITS_TO_BYTES(bpp
))); //(8 lines * pitch * bytes per pixel) MOD 4096 = 0
751 // end Carrizo workaround for 1D tilling
757 ****************************************************************************************************
758 * EgBasedLib::HwlReduceBankWidthHeight
761 * Additional checks, reduce bankHeight/bankWidth if needed and possible
762 * tileSize*BANK_WIDTH*BANK_HEIGHT <= ROW_SIZE
765 * TRUE if no error occurs
766 ****************************************************************************************************
768 BOOL_32
EgBasedLib::HwlReduceBankWidthHeight(
769 UINT_32 tileSize
, ///< [in] tile size
770 UINT_32 bpp
, ///< [in] bits per pixel
771 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
772 UINT_32 numSamples
, ///< [in] number of samples
773 UINT_32 bankHeightAlign
, ///< [in] bank height alignment
774 UINT_32 pipes
, ///< [in] pipes
775 ADDR_TILEINFO
* pTileInfo
///< [in,out] bank structure.
778 UINT_32 macroAspectAlign
;
779 BOOL_32 valid
= TRUE
;
781 if (tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
)
783 BOOL_32 stillGreater
= TRUE
;
785 // Try reducing bankWidth first
786 if (stillGreater
&& pTileInfo
->bankWidth
> 1)
788 while (stillGreater
&& pTileInfo
->bankWidth
> 0)
790 pTileInfo
->bankWidth
>>= 1;
792 if (pTileInfo
->bankWidth
== 0)
794 pTileInfo
->bankWidth
= 1;
799 tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
;
802 // bankWidth is reduced above, so we need to recalculate bankHeight and ratio
803 bankHeightAlign
= Max(1u,
804 m_pipeInterleaveBytes
* m_bankInterleave
/
805 (tileSize
* pTileInfo
->bankWidth
)
808 // We cannot increase bankHeight so just assert this case.
809 ADDR_ASSERT((pTileInfo
->bankHeight
% bankHeightAlign
) == 0);
813 macroAspectAlign
= Max(1u,
814 m_pipeInterleaveBytes
* m_bankInterleave
/
815 (tileSize
* pipes
* pTileInfo
->bankWidth
)
817 pTileInfo
->macroAspectRatio
= PowTwoAlign(pTileInfo
->macroAspectRatio
,
822 // Early quit bank_height degradation for "64" bit z buffer
823 if (flags
.depth
&& bpp
>= 64)
825 stillGreater
= FALSE
;
828 // Then try reducing bankHeight
829 if (stillGreater
&& pTileInfo
->bankHeight
> bankHeightAlign
)
831 while (stillGreater
&& pTileInfo
->bankHeight
> bankHeightAlign
)
833 pTileInfo
->bankHeight
>>= 1;
835 if (pTileInfo
->bankHeight
< bankHeightAlign
)
837 pTileInfo
->bankHeight
= bankHeightAlign
;
842 tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
;
846 valid
= !stillGreater
;
848 // Generate a warning if we still fail to meet this constraint
852 0, ("TILE_SIZE(%d)*BANK_WIDTH(%d)*BANK_HEIGHT(%d) <= ROW_SIZE(%d)",
853 tileSize
, pTileInfo
->bankWidth
, pTileInfo
->bankHeight
, m_rowSize
));
861 ****************************************************************************************************
862 * EgBasedLib::ComputeSurfaceAlignmentsMacroTiled
865 * Compute 2D tiled surface alignment, calculation results are returned through
869 * TRUE if no error occurs
870 ****************************************************************************************************
872 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsMacroTiled(
873 AddrTileMode tileMode
, ///< [in] tile mode
874 UINT_32 bpp
, ///< [in] bits per pixel
875 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
876 UINT_32 mipLevel
, ///< [in] mip level
877 UINT_32 numSamples
, ///< [in] number of samples
878 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in,out] Surface output
881 ADDR_TILEINFO
* pTileInfo
= pOut
->pTileInfo
;
883 BOOL_32 valid
= SanityCheckMacroTiled(pTileInfo
);
887 UINT_32 macroTileWidth
;
888 UINT_32 macroTileHeight
;
891 UINT_32 bankHeightAlign
;
892 UINT_32 macroAspectAlign
;
894 UINT_32 thickness
= Thickness(tileMode
);
895 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
898 // Align bank height first according to latest h/w spec
901 // tile_size = MIN(tile_split, 64 * tile_thickness * element_bytes * num_samples)
902 tileSize
= Min(pTileInfo
->tileSplitBytes
,
903 BITS_TO_BYTES(64 * thickness
* bpp
* numSamples
));
905 // bank_height_align =
906 // MAX(1, (pipe_interleave_bytes * bank_interleave)/(tile_size*bank_width))
907 bankHeightAlign
= Max(1u,
908 m_pipeInterleaveBytes
* m_bankInterleave
/
909 (tileSize
* pTileInfo
->bankWidth
)
912 pTileInfo
->bankHeight
= PowTwoAlign(pTileInfo
->bankHeight
, bankHeightAlign
);
914 // num_pipes * bank_width * macro_tile_aspect >=
915 // (pipe_interleave_size * bank_interleave) / tile_size
918 // this restriction is only for mipmap (mipmap's numSamples must be 1)
919 macroAspectAlign
= Max(1u,
920 m_pipeInterleaveBytes
* m_bankInterleave
/
921 (tileSize
* pipes
* pTileInfo
->bankWidth
)
923 pTileInfo
->macroAspectRatio
= PowTwoAlign(pTileInfo
->macroAspectRatio
, macroAspectAlign
);
926 valid
= HwlReduceBankWidthHeight(tileSize
,
935 // The required granularity for pitch is the macro tile width.
937 macroTileWidth
= MicroTileWidth
* pTileInfo
->bankWidth
* pipes
*
938 pTileInfo
->macroAspectRatio
;
940 pOut
->pitchAlign
= macroTileWidth
;
941 pOut
->blockWidth
= macroTileWidth
;
943 AdjustPitchAlignment(flags
, &pOut
->pitchAlign
);
946 // The required granularity for height is the macro tile height.
948 macroTileHeight
= MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
/
949 pTileInfo
->macroAspectRatio
;
951 pOut
->heightAlign
= macroTileHeight
;
952 pOut
->blockHeight
= macroTileHeight
;
955 // Compute base alignment
958 pipes
* pTileInfo
->bankWidth
* pTileInfo
->banks
* pTileInfo
->bankHeight
* tileSize
;
960 HwlComputeSurfaceAlignmentsMacroTiled(tileMode
, bpp
, flags
, mipLevel
, numSamples
, pOut
);
967 ****************************************************************************************************
968 * EgBasedLib::SanityCheckMacroTiled
971 * Check if macro-tiled parameters are valid
974 ****************************************************************************************************
976 BOOL_32
EgBasedLib::SanityCheckMacroTiled(
977 ADDR_TILEINFO
* pTileInfo
///< [in] macro-tiled parameters
980 BOOL_32 valid
= TRUE
;
981 MAYBE_UNUSED UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
983 switch (pTileInfo
->banks
)
985 case 2: //fall through
986 case 4: //fall through
987 case 8: //fall through
998 switch (pTileInfo
->bankWidth
)
1000 case 1: //fall through
1001 case 2: //fall through
1002 case 4: //fall through
1013 switch (pTileInfo
->bankHeight
)
1015 case 1: //fall through
1016 case 2: //fall through
1017 case 4: //fall through
1028 switch (pTileInfo
->macroAspectRatio
)
1030 case 1: //fall through
1031 case 2: //fall through
1032 case 4: //fall through
1043 if (pTileInfo
->banks
< pTileInfo
->macroAspectRatio
)
1045 // This will generate macro tile height <= 1
1052 if (pTileInfo
->tileSplitBytes
> m_rowSize
)
1054 ADDR_WARN(0, ("tileSplitBytes is bigger than row size"));
1060 valid
= HwlSanityCheckMacroTiled(pTileInfo
);
1063 ADDR_ASSERT(valid
== TRUE
);
1065 // Add this assert for guidance
1066 ADDR_ASSERT(numPipes
* pTileInfo
->banks
>= 4);
1072 ****************************************************************************************************
1073 * EgBasedLib::ComputeSurfaceMipLevelTileMode
1076 * Compute valid tile mode for surface mipmap sub-levels
1079 * Suitable tile mode
1080 ****************************************************************************************************
1082 AddrTileMode
EgBasedLib::ComputeSurfaceMipLevelTileMode(
1083 AddrTileMode baseTileMode
, ///< [in] base tile mode
1084 UINT_32 bpp
, ///< [in] bits per pixels
1085 UINT_32 pitch
, ///< [in] current level pitch
1086 UINT_32 height
, ///< [in] current level height
1087 UINT_32 numSlices
, ///< [in] current number of slices
1088 UINT_32 numSamples
, ///< [in] number of samples
1089 UINT_32 pitchAlign
, ///< [in] pitch alignment
1090 UINT_32 heightAlign
, ///< [in] height alignment
1091 ADDR_TILEINFO
* pTileInfo
///< [in] ptr to bank structure
1094 UINT_64 bytesPerSlice
;
1095 (void)bytesPerSlice
;
1096 UINT_32 bytesPerTile
;
1098 AddrTileMode expTileMode
= baseTileMode
;
1099 UINT_32 microTileThickness
= Thickness(expTileMode
);
1100 UINT_32 interleaveSize
= m_pipeInterleaveBytes
* m_bankInterleave
;
1103 // Compute the size of a slice.
1105 bytesPerSlice
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
1106 bytesPerTile
= BITS_TO_BYTES(MicroTilePixels
* microTileThickness
* NextPow2(bpp
) * numSamples
);
1109 // Reduce tiling mode from thick to thin if the number of slices is less than the
1110 // micro tile thickness.
1112 if (numSlices
< microTileThickness
)
1114 expTileMode
= HwlDegradeThickTileMode(expTileMode
, numSlices
, &bytesPerTile
);
1117 if (bytesPerTile
> pTileInfo
->tileSplitBytes
)
1119 bytesPerTile
= pTileInfo
->tileSplitBytes
;
1122 UINT_32 threshold1
=
1123 bytesPerTile
* HwlGetPipes(pTileInfo
) * pTileInfo
->bankWidth
* pTileInfo
->macroAspectRatio
;
1125 UINT_32 threshold2
=
1126 bytesPerTile
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
;
1129 // Reduce the tile mode from 2D/3D to 1D in following conditions
1131 switch (expTileMode
)
1133 case ADDR_TM_2D_TILED_THIN1
: //fall through
1134 case ADDR_TM_3D_TILED_THIN1
:
1135 case ADDR_TM_PRT_TILED_THIN1
:
1136 case ADDR_TM_PRT_2D_TILED_THIN1
:
1137 case ADDR_TM_PRT_3D_TILED_THIN1
:
1138 if ((pitch
< pitchAlign
) ||
1139 (height
< heightAlign
) ||
1140 (interleaveSize
> threshold1
) ||
1141 (interleaveSize
> threshold2
))
1143 expTileMode
= ADDR_TM_1D_TILED_THIN1
;
1146 case ADDR_TM_2D_TILED_THICK
: //fall through
1147 case ADDR_TM_3D_TILED_THICK
:
1148 case ADDR_TM_2D_TILED_XTHICK
:
1149 case ADDR_TM_3D_TILED_XTHICK
:
1150 case ADDR_TM_PRT_TILED_THICK
:
1151 case ADDR_TM_PRT_2D_TILED_THICK
:
1152 case ADDR_TM_PRT_3D_TILED_THICK
:
1153 if ((pitch
< pitchAlign
) ||
1154 (height
< heightAlign
))
1156 expTileMode
= ADDR_TM_1D_TILED_THICK
;
1167 ****************************************************************************************************
1168 * EgBasedLib::HwlGetAlignmentInfoMacroTiled
1170 * Get alignment info for giving tile mode
1172 * TRUE if getting alignment is OK
1173 ****************************************************************************************************
1175 BOOL_32
EgBasedLib::HwlGetAlignmentInfoMacroTiled(
1176 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] create surface info
1177 UINT_32
* pPitchAlign
, ///< [out] pitch alignment
1178 UINT_32
* pHeightAlign
, ///< [out] height alignment
1179 UINT_32
* pSizeAlign
///< [out] size alignment
1182 BOOL_32 valid
= TRUE
;
1184 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
1186 UINT_32 numSamples
= (pIn
->numFrags
== 0) ? pIn
->numSamples
: pIn
->numFrags
;
1188 ADDR_ASSERT(pIn
->pTileInfo
);
1189 ADDR_TILEINFO tileInfo
= *pIn
->pTileInfo
;
1190 ADDR_COMPUTE_SURFACE_INFO_OUTPUT out
= {0};
1191 out
.pTileInfo
= &tileInfo
;
1193 if (UseTileIndex(pIn
->tileIndex
))
1195 out
.tileIndex
= pIn
->tileIndex
;
1196 out
.macroModeIndex
= TileIndexInvalid
;
1199 HwlSetupTileInfo(pIn
->tileMode
,
1210 valid
= ComputeSurfaceAlignmentsMacroTiled(pIn
->tileMode
,
1219 *pPitchAlign
= out
.pitchAlign
;
1220 *pHeightAlign
= out
.heightAlign
;
1221 *pSizeAlign
= out
.baseAlign
;
1228 ****************************************************************************************************
1229 * EgBasedLib::HwlDegradeThickTileMode
1232 * Degrades valid tile mode for thick modes if needed
1235 * Suitable tile mode
1236 ****************************************************************************************************
1238 AddrTileMode
EgBasedLib::HwlDegradeThickTileMode(
1239 AddrTileMode baseTileMode
, ///< [in] base tile mode
1240 UINT_32 numSlices
, ///< [in] current number of slices
1241 UINT_32
* pBytesPerTile
///< [in,out] pointer to bytes per slice
1244 ADDR_ASSERT(numSlices
< Thickness(baseTileMode
));
1245 // if pBytesPerTile is NULL, this is a don't-care....
1246 UINT_32 bytesPerTile
= pBytesPerTile
!= NULL
? *pBytesPerTile
: 64;
1248 AddrTileMode expTileMode
= baseTileMode
;
1249 switch (baseTileMode
)
1251 case ADDR_TM_1D_TILED_THICK
:
1252 expTileMode
= ADDR_TM_1D_TILED_THIN1
;
1255 case ADDR_TM_2D_TILED_THICK
:
1256 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1259 case ADDR_TM_3D_TILED_THICK
:
1260 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1263 case ADDR_TM_2D_TILED_XTHICK
:
1264 if (numSlices
< ThickTileThickness
)
1266 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1271 expTileMode
= ADDR_TM_2D_TILED_THICK
;
1275 case ADDR_TM_3D_TILED_XTHICK
:
1276 if (numSlices
< ThickTileThickness
)
1278 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1283 expTileMode
= ADDR_TM_3D_TILED_THICK
;
1288 ADDR_ASSERT_ALWAYS();
1292 if (pBytesPerTile
!= NULL
)
1294 *pBytesPerTile
= bytesPerTile
;
1301 ****************************************************************************************************
1302 * EgBasedLib::DispatchComputeSurfaceAddrFromCoord
1305 * Compute surface address from given coord (x, y, slice,sample)
1309 ****************************************************************************************************
1311 UINT_64
EgBasedLib::DispatchComputeSurfaceAddrFromCoord(
1312 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1313 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1318 UINT_32 slice
= pIn
->slice
;
1319 UINT_32 sample
= pIn
->sample
;
1320 UINT_32 bpp
= pIn
->bpp
;
1321 UINT_32 pitch
= pIn
->pitch
;
1322 UINT_32 height
= pIn
->height
;
1323 UINT_32 numSlices
= pIn
->numSlices
;
1324 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
1325 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
1326 AddrTileMode tileMode
= pIn
->tileMode
;
1327 AddrTileType microTileType
= pIn
->tileType
;
1328 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
1329 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
1330 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
1332 UINT_32
* pBitPosition
= &pOut
->bitPosition
;
1335 // ADDR_DEPTH_SAMPLE_ORDER = non-disp + depth-sample-order
1336 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
1338 isDepthSampleOrder
= TRUE
;
1341 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
1343 if (numFrags
!= numSamples
)
1345 numSamples
= numFrags
;
1346 ADDR_ASSERT(sample
< numSamples
);
1350 /// 128 bit/thick tiled surface doesn't support display tiling and
1351 /// mipmap chain must have the same tileType, so please fill tileType correctly
1352 if (IsLinear(pIn
->tileMode
) == FALSE
)
1354 if (bpp
>= 128 || Thickness(tileMode
) > 1)
1356 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
1363 case ADDR_TM_LINEAR_GENERAL
://fall through
1364 case ADDR_TM_LINEAR_ALIGNED
:
1365 addr
= ComputeSurfaceAddrFromCoordLinear(x
,
1375 case ADDR_TM_1D_TILED_THIN1
://fall through
1376 case ADDR_TM_1D_TILED_THICK
:
1377 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
1390 case ADDR_TM_2D_TILED_THIN1
: //fall through
1391 case ADDR_TM_2D_TILED_THICK
: //fall through
1392 case ADDR_TM_3D_TILED_THIN1
: //fall through
1393 case ADDR_TM_3D_TILED_THICK
: //fall through
1394 case ADDR_TM_2D_TILED_XTHICK
: //fall through
1395 case ADDR_TM_3D_TILED_XTHICK
: //fall through
1396 case ADDR_TM_PRT_TILED_THIN1
: //fall through
1397 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
1398 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
1399 case ADDR_TM_PRT_TILED_THICK
: //fall through
1400 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
1401 case ADDR_TM_PRT_3D_TILED_THICK
:
1402 UINT_32 pipeSwizzle
;
1403 UINT_32 bankSwizzle
;
1405 if (m_configFlags
.useCombinedSwizzle
)
1407 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
1408 &bankSwizzle
, &pipeSwizzle
);
1412 pipeSwizzle
= pIn
->pipeSwizzle
;
1413 bankSwizzle
= pIn
->bankSwizzle
;
1416 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
1435 ADDR_ASSERT_ALWAYS();
1443 ****************************************************************************************************
1444 * EgBasedLib::ComputeMacroTileEquation
1447 * Computes the address equation in macro tile
1449 * If equation can be computed
1450 ****************************************************************************************************
1452 ADDR_E_RETURNCODE
EgBasedLib::ComputeMacroTileEquation(
1453 UINT_32 log2BytesPP
, ///< [in] log2 of bytes per pixel
1454 AddrTileMode tileMode
, ///< [in] tile mode
1455 AddrTileType microTileType
, ///< [in] micro tiling type
1456 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure
1457 ADDR_EQUATION
* pEquation
///< [out] Equation for addressing in macro tile
1460 ADDR_E_RETURNCODE retCode
;
1462 // Element equation within a tile
1463 retCode
= ComputeMicroTileEquation(log2BytesPP
, tileMode
, microTileType
, pEquation
);
1465 if (retCode
== ADDR_OK
)
1467 // Tile equesiton with signle pipe bank
1468 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1469 UINT_32 numPipeBits
= Log2(numPipes
);
1471 for (UINT_32 i
= 0; i
< Log2(pTileInfo
->bankWidth
); i
++)
1473 pEquation
->addr
[pEquation
->numBits
].valid
= 1;
1474 pEquation
->addr
[pEquation
->numBits
].channel
= 0;
1475 pEquation
->addr
[pEquation
->numBits
].index
= i
+ log2BytesPP
+ 3 + numPipeBits
;
1476 pEquation
->numBits
++;
1479 for (UINT_32 i
= 0; i
< Log2(pTileInfo
->bankHeight
); i
++)
1481 pEquation
->addr
[pEquation
->numBits
].valid
= 1;
1482 pEquation
->addr
[pEquation
->numBits
].channel
= 1;
1483 pEquation
->addr
[pEquation
->numBits
].index
= i
+ 3;
1484 pEquation
->numBits
++;
1487 ADDR_EQUATION equation
;
1488 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
1490 UINT_32 thresholdX
= 32;
1491 UINT_32 thresholdY
= 32;
1493 if (IsPrtNoRotationTileMode(tileMode
))
1495 UINT_32 macroTilePitch
=
1496 (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
) * pTileInfo
->macroAspectRatio
;
1497 UINT_32 macroTileHeight
=
1498 (MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
) /
1499 pTileInfo
->macroAspectRatio
;
1500 thresholdX
= Log2(macroTilePitch
);
1501 thresholdY
= Log2(macroTileHeight
);
1505 retCode
= ComputePipeEquation(log2BytesPP
, thresholdX
, thresholdY
, pTileInfo
, &equation
);
1507 if (retCode
== ADDR_OK
)
1509 UINT_32 pipeBitStart
= Log2(m_pipeInterleaveBytes
);
1511 if (pEquation
->numBits
> pipeBitStart
)
1513 UINT_32 numLeftShift
= pEquation
->numBits
- pipeBitStart
;
1515 for (UINT_32 i
= 0; i
< numLeftShift
; i
++)
1517 pEquation
->addr
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1518 pEquation
->addr
[pEquation
->numBits
- i
- 1];
1519 pEquation
->xor1
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1520 pEquation
->xor1
[pEquation
->numBits
- i
- 1];
1521 pEquation
->xor2
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1522 pEquation
->xor2
[pEquation
->numBits
- i
- 1];
1526 for (UINT_32 i
= 0; i
< equation
.numBits
; i
++)
1528 pEquation
->addr
[pipeBitStart
+ i
] = equation
.addr
[i
];
1529 pEquation
->xor1
[pipeBitStart
+ i
] = equation
.xor1
[i
];
1530 pEquation
->xor2
[pipeBitStart
+ i
] = equation
.xor2
[i
];
1531 pEquation
->numBits
++;
1535 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
1537 retCode
= ComputeBankEquation(log2BytesPP
, thresholdX
, thresholdY
,
1538 pTileInfo
, &equation
);
1540 if (retCode
== ADDR_OK
)
1542 UINT_32 bankBitStart
= pipeBitStart
+ numPipeBits
+ Log2(m_bankInterleave
);
1544 if (pEquation
->numBits
> bankBitStart
)
1546 UINT_32 numLeftShift
= pEquation
->numBits
- bankBitStart
;
1548 for (UINT_32 i
= 0; i
< numLeftShift
; i
++)
1550 pEquation
->addr
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1551 pEquation
->addr
[pEquation
->numBits
- i
- 1];
1552 pEquation
->xor1
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1553 pEquation
->xor1
[pEquation
->numBits
- i
- 1];
1554 pEquation
->xor2
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1555 pEquation
->xor2
[pEquation
->numBits
- i
- 1];
1559 for (UINT_32 i
= 0; i
< equation
.numBits
; i
++)
1561 pEquation
->addr
[bankBitStart
+ i
] = equation
.addr
[i
];
1562 pEquation
->xor1
[bankBitStart
+ i
] = equation
.xor1
[i
];
1563 pEquation
->xor2
[bankBitStart
+ i
] = equation
.xor2
[i
];
1564 pEquation
->numBits
++;
1574 ****************************************************************************************************
1575 * EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1578 * Computes the surface address and bit position from a
1579 * coordinate for 2D tilied (macro tiled)
1582 ****************************************************************************************************
1584 UINT_64
EgBasedLib::ComputeSurfaceAddrFromCoordMacroTiled(
1585 UINT_32 x
, ///< [in] x coordinate
1586 UINT_32 y
, ///< [in] y coordinate
1587 UINT_32 slice
, ///< [in] slice index
1588 UINT_32 sample
, ///< [in] sample index
1589 UINT_32 bpp
, ///< [in] bits per pixel
1590 UINT_32 pitch
, ///< [in] surface pitch, in pixels
1591 UINT_32 height
, ///< [in] surface height, in pixels
1592 UINT_32 numSamples
, ///< [in] number of samples
1593 AddrTileMode tileMode
, ///< [in] tile mode
1594 AddrTileType microTileType
, ///< [in] micro tiling type
1595 BOOL_32 ignoreSE
, ///< [in] TRUE if shader enginers can be ignored
1596 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if it depth sample ordering is used
1597 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
1598 UINT_32 bankSwizzle
, ///< [in] bank swizzle
1599 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure
1600 /// **All fields to be valid on entry**
1601 UINT_32
* pBitPosition
///< [out] bit position, e.g. FMT_1 will use this
1606 UINT_32 microTileBytes
;
1607 UINT_32 microTileBits
;
1608 UINT_32 sampleOffset
;
1610 UINT_32 pixelOffset
;
1611 UINT_32 elementOffset
;
1612 UINT_32 tileSplitSlice
;
1616 UINT_64 sliceOffset
;
1617 UINT_32 macroTilePitch
;
1618 UINT_32 macroTileHeight
;
1619 UINT_32 macroTilesPerRow
;
1620 UINT_32 macroTilesPerSlice
;
1621 UINT_64 macroTileBytes
;
1622 UINT_32 macroTileIndexX
;
1623 UINT_32 macroTileIndexY
;
1624 UINT_64 macroTileOffset
;
1625 UINT_64 totalOffset
;
1626 UINT_64 pipeInterleaveMask
;
1627 UINT_64 bankInterleaveMask
;
1628 UINT_64 pipeInterleaveOffset
;
1629 UINT_32 bankInterleaveOffset
;
1631 UINT_32 tileRowIndex
;
1632 UINT_32 tileColumnIndex
;
1636 UINT_32 microTileThickness
= Thickness(tileMode
);
1639 // Compute the number of group, pipe, and bank bits.
1641 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1642 UINT_32 numPipeInterleaveBits
= Log2(m_pipeInterleaveBytes
);
1643 UINT_32 numPipeBits
= Log2(numPipes
);
1644 UINT_32 numBankInterleaveBits
= Log2(m_bankInterleave
);
1645 UINT_32 numBankBits
= Log2(pTileInfo
->banks
);
1648 // Compute the micro tile size.
1650 microTileBits
= MicroTilePixels
* microTileThickness
* bpp
* numSamples
;
1652 microTileBytes
= microTileBits
/ 8;
1654 // Compute the pixel index within the micro tile.
1656 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
1664 // Compute the sample offset and pixel offset.
1666 if (isDepthSampleOrder
)
1669 // For depth surfaces, samples are stored contiguously for each element, so the sample
1670 // offset is the sample number times the element size.
1672 sampleOffset
= sample
* bpp
;
1673 pixelOffset
= pixelIndex
* bpp
* numSamples
;
1678 // For color surfaces, all elements for a particular sample are stored contiguously, so
1679 // the sample offset is the sample number times the micro tile size divided yBit the number
1682 sampleOffset
= sample
* (microTileBits
/ numSamples
);
1683 pixelOffset
= pixelIndex
* bpp
;
1687 // Compute the element offset.
1689 elementOffset
= pixelOffset
+ sampleOffset
;
1691 *pBitPosition
= static_cast<UINT_32
>(elementOffset
% 8);
1693 elementOffset
/= 8; //bit-to-byte
1696 // Determine if tiles need to be split across slices.
1698 // If the size of the micro tile is larger than the tile split size, then the tile will be
1699 // split across multiple slices.
1701 UINT_32 slicesPerTile
= 1;
1703 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
1704 { //don't support for thick mode
1707 // Compute the number of slices per tile.
1709 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
1712 // Compute the tile split slice number for use in rotating the bank.
1714 tileSplitSlice
= elementOffset
/ pTileInfo
->tileSplitBytes
;
1717 // Adjust the element offset to account for the portion of the tile that is being moved to
1720 elementOffset
%= pTileInfo
->tileSplitBytes
;
1723 // Adjust the microTileBytes size to tileSplitBytes size since
1726 microTileBytes
= pTileInfo
->tileSplitBytes
;
1734 // Compute macro tile pitch and height.
1737 (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
) * pTileInfo
->macroAspectRatio
;
1739 (MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
) / pTileInfo
->macroAspectRatio
;
1742 // Compute the number of bytes per macro tile. Note: bytes of the same bank/pipe actually
1745 static_cast<UINT_64
>(microTileBytes
) *
1746 (macroTilePitch
/ MicroTileWidth
) * (macroTileHeight
/ MicroTileHeight
) /
1747 (numPipes
* pTileInfo
->banks
);
1750 // Compute the number of macro tiles per row.
1752 macroTilesPerRow
= pitch
/ macroTilePitch
;
1755 // Compute the offset to the macro tile containing the specified coordinate.
1757 macroTileIndexX
= x
/ macroTilePitch
;
1758 macroTileIndexY
= y
/ macroTileHeight
;
1759 macroTileOffset
= ((macroTileIndexY
* macroTilesPerRow
) + macroTileIndexX
) * macroTileBytes
;
1762 // Compute the number of macro tiles per slice.
1764 macroTilesPerSlice
= macroTilesPerRow
* (height
/ macroTileHeight
);
1767 // Compute the slice size.
1769 sliceBytes
= macroTilesPerSlice
* macroTileBytes
;
1772 // Compute the slice offset.
1774 sliceOffset
= sliceBytes
* (tileSplitSlice
+ slicesPerTile
* (slice
/ microTileThickness
));
1777 // Compute tile offest
1779 tileRowIndex
= (y
/ MicroTileHeight
) % pTileInfo
->bankHeight
;
1780 tileColumnIndex
= ((x
/ MicroTileWidth
) / numPipes
) % pTileInfo
->bankWidth
;
1781 tileIndex
= (tileRowIndex
* pTileInfo
->bankWidth
) + tileColumnIndex
;
1782 tileOffset
= tileIndex
* microTileBytes
;
1785 // Combine the slice offset and macro tile offset with the pixel and sample offsets, accounting
1786 // for the pipe and bank bits in the middle of the address.
1788 totalOffset
= sliceOffset
+ macroTileOffset
+ elementOffset
+ tileOffset
;
1791 // Get the pipe and bank.
1794 // when the tileMode is PRT type, then adjust x and y coordinates
1795 if (IsPrtNoRotationTileMode(tileMode
))
1797 x
= x
% macroTilePitch
;
1798 y
= y
% macroTileHeight
;
1801 pipe
= ComputePipeFromCoord(x
,
1809 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);
2161 ****************************************************************************************************
2162 * EgBasedLib::DispatchComputeSurfaceCoordFromAddrDispatch
2165 * Compute (x,y,slice,sample) coordinates from surface address
2168 ****************************************************************************************************
2170 VOID
EgBasedLib::DispatchComputeSurfaceCoordFromAddr(
2171 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
2172 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
2175 UINT_64 addr
= pIn
->addr
;
2176 UINT_32 bitPosition
= pIn
->bitPosition
;
2177 UINT_32 bpp
= pIn
->bpp
;
2178 UINT_32 pitch
= pIn
->pitch
;
2179 UINT_32 height
= pIn
->height
;
2180 UINT_32 numSlices
= pIn
->numSlices
;
2181 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
2182 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
2183 AddrTileMode tileMode
= pIn
->tileMode
;
2184 UINT_32 tileBase
= pIn
->tileBase
;
2185 UINT_32 compBits
= pIn
->compBits
;
2186 AddrTileType microTileType
= pIn
->tileType
;
2187 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
2188 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
2189 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2191 UINT_32
* pX
= &pOut
->x
;
2192 UINT_32
* pY
= &pOut
->y
;
2193 UINT_32
* pSlice
= &pOut
->slice
;
2194 UINT_32
* pSample
= &pOut
->sample
;
2196 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2198 isDepthSampleOrder
= TRUE
;
2201 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
2203 if (numFrags
!= numSamples
)
2205 numSamples
= numFrags
;
2209 /// 128 bit/thick tiled surface doesn't support display tiling and
2210 /// mipmap chain must have the same tileType, so please fill tileType correctly
2211 if (IsLinear(pIn
->tileMode
) == FALSE
)
2213 if (bpp
>= 128 || Thickness(tileMode
) > 1)
2215 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
2222 case ADDR_TM_LINEAR_GENERAL
://fall through
2223 case ADDR_TM_LINEAR_ALIGNED
:
2224 ComputeSurfaceCoordFromAddrLinear(addr
,
2235 case ADDR_TM_1D_TILED_THIN1
://fall through
2236 case ADDR_TM_1D_TILED_THICK
:
2237 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
2251 isDepthSampleOrder
);
2253 case ADDR_TM_2D_TILED_THIN1
: //fall through
2254 case ADDR_TM_2D_TILED_THICK
: //fall through
2255 case ADDR_TM_3D_TILED_THIN1
: //fall through
2256 case ADDR_TM_3D_TILED_THICK
: //fall through
2257 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2258 case ADDR_TM_3D_TILED_XTHICK
: //fall through
2259 case ADDR_TM_PRT_TILED_THIN1
: //fall through
2260 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
2261 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
2262 case ADDR_TM_PRT_TILED_THICK
: //fall through
2263 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
2264 case ADDR_TM_PRT_3D_TILED_THICK
:
2265 UINT_32 pipeSwizzle
;
2266 UINT_32 bankSwizzle
;
2268 if (m_configFlags
.useCombinedSwizzle
)
2270 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
2271 &bankSwizzle
, &pipeSwizzle
);
2275 pipeSwizzle
= pIn
->pipeSwizzle
;
2276 bankSwizzle
= pIn
->bankSwizzle
;
2279 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
2300 ADDR_ASSERT_ALWAYS();
2305 ****************************************************************************************************
2306 * EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled
2309 * Compute surface coordinates from address for macro tiled surface
2312 ****************************************************************************************************
2314 VOID
EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled(
2315 UINT_64 addr
, ///< [in] byte address
2316 UINT_32 bitPosition
, ///< [in] bit position
2317 UINT_32 bpp
, ///< [in] bits per pixel
2318 UINT_32 pitch
, ///< [in] pitch in pixels
2319 UINT_32 height
, ///< [in] height in pixels
2320 UINT_32 numSamples
, ///< [in] number of samples
2321 AddrTileMode tileMode
, ///< [in] tile mode
2322 UINT_32 tileBase
, ///< [in] tile base offset
2323 UINT_32 compBits
, ///< [in] component bits (for planar surface)
2324 AddrTileType microTileType
, ///< [in] micro tiling type
2325 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines can be ignored
2326 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if depth sample order is used
2327 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2328 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2329 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure.
2330 /// **All fields to be valid on entry**
2331 UINT_32
* pX
, ///< [out] X coord
2332 UINT_32
* pY
, ///< [out] Y coord
2333 UINT_32
* pSlice
, ///< [out] slice index
2334 UINT_32
* pSample
///< [out] sample index
2340 UINT_64 macroTileBits
;
2343 UINT_64 elementOffset
;
2344 UINT_64 macroTileIndex
;
2346 UINT_64 totalOffset
;
2350 UINT_32 groupBits
= m_pipeInterleaveBytes
<< 3;
2351 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2352 UINT_32 banks
= pTileInfo
->banks
;
2354 UINT_32 bankInterleave
= m_bankInterleave
;
2356 UINT_64 addrBits
= BYTES_TO_BITS(addr
) + bitPosition
;
2359 // remove bits for bank and pipe
2361 totalOffset
= (addrBits
% groupBits
) +
2362 (((addrBits
/ groupBits
/ pipes
) % bankInterleave
) * groupBits
) +
2363 (((addrBits
/ groupBits
/ pipes
) / bankInterleave
) / banks
) * groupBits
* bankInterleave
;
2365 UINT_32 microTileThickness
= Thickness(tileMode
);
2367 UINT_32 microTileBits
= bpp
* microTileThickness
* MicroTilePixels
* numSamples
;
2369 UINT_32 microTileBytes
= BITS_TO_BYTES(microTileBits
);
2371 // Determine if tiles need to be split across slices.
2373 // If the size of the micro tile is larger than the tile split size, then the tile will be
2374 // split across multiple slices.
2376 UINT_32 slicesPerTile
= 1; //_State->TileSlices
2378 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
2379 { //don't support for thick mode
2382 // Compute the number of slices per tile.
2384 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
2387 tileBits
= microTileBits
/ slicesPerTile
; // micro tile bits
2389 // in micro tiles because not MicroTileWidth timed.
2390 UINT_32 macroWidth
= pTileInfo
->bankWidth
* pipes
* pTileInfo
->macroAspectRatio
;
2391 // in micro tiles as well
2392 UINT_32 macroHeight
= pTileInfo
->bankHeight
* banks
/ pTileInfo
->macroAspectRatio
;
2394 UINT_32 pitchInMacroTiles
= pitch
/ MicroTileWidth
/ macroWidth
;
2396 macroTileBits
= (macroWidth
* macroHeight
) * tileBits
/ (banks
* pipes
);
2398 macroTileIndex
= totalOffset
/ macroTileBits
;
2400 // pitchMacros * height / heightMacros; macroTilesPerSlice == _State->SliceMacros
2401 UINT_32 macroTilesPerSlice
= (pitch
/ (macroWidth
* MicroTileWidth
)) * height
/
2402 (macroHeight
* MicroTileWidth
);
2404 slices
= static_cast<UINT_32
>(macroTileIndex
/ macroTilesPerSlice
);
2406 *pSlice
= static_cast<UINT_32
>(slices
/ slicesPerTile
* microTileThickness
);
2409 // calculate element offset and x[2:0], y[2:0], z[1:0] for thick
2411 tileSlices
= slices
% slicesPerTile
;
2413 elementOffset
= tileSlices
* tileBits
;
2414 elementOffset
+= totalOffset
% tileBits
;
2418 HwlComputePixelCoordFromOffset(static_cast<UINT_32
>(elementOffset
),
2429 isDepthSampleOrder
);
2431 macroTileIndex
= macroTileIndex
% macroTilesPerSlice
;
2432 *pY
+= static_cast<UINT_32
>(macroTileIndex
/ pitchInMacroTiles
* macroHeight
* MicroTileHeight
);
2433 *pX
+= static_cast<UINT_32
>(macroTileIndex
% pitchInMacroTiles
* macroWidth
* MicroTileWidth
);
2437 tileIndex
= static_cast<UINT_32
>((totalOffset
% macroTileBits
) / tileBits
);
2439 my
= (tileIndex
/ pTileInfo
->bankWidth
) % pTileInfo
->bankHeight
* MicroTileHeight
;
2440 mx
= (tileIndex
% pTileInfo
->bankWidth
) * pipes
* MicroTileWidth
;
2445 bank
= ComputeBankFromAddr(addr
, banks
, pipes
);
2446 pipe
= ComputePipeFromAddr(addr
, pipes
);
2448 HwlComputeSurfaceCoord2DFromBankPipe(tileMode
,
2462 ****************************************************************************************************
2463 * EgBasedLib::ComputeSurfaceCoord2DFromBankPipe
2466 * Compute surface x,y coordinates from bank/pipe info
2469 ****************************************************************************************************
2471 VOID
EgBasedLib::ComputeSurfaceCoord2DFromBankPipe(
2472 AddrTileMode tileMode
, ///< [in] tile mode
2473 UINT_32 x
, ///< [in] x coordinate
2474 UINT_32 y
, ///< [in] y coordinate
2475 UINT_32 slice
, ///< [in] slice index
2476 UINT_32 bank
, ///< [in] bank number
2477 UINT_32 pipe
, ///< [in] pipe number
2478 UINT_32 bankSwizzle
,///< [in] bank swizzle
2479 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
2480 UINT_32 tileSlices
, ///< [in] slices in a micro tile
2481 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure. **All fields to be valid on entry**
2482 CoordFromBankPipe
* pOutput
///< [out] pointer to extracted x/y bits
2494 UINT_32 tileSplitRotation
;
2496 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2498 UINT_32 bankRotation
= ComputeBankRotation(tileMode
,
2499 pTileInfo
->banks
, numPipes
);
2501 UINT_32 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2503 UINT_32 xBit
= x
/ (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
);
2504 UINT_32 yBit
= y
/ (MicroTileHeight
* pTileInfo
->bankHeight
);
2506 //calculate the bank and pipe before rotation and swizzle
2510 case ADDR_TM_2D_TILED_THIN1
: //fall through
2511 case ADDR_TM_2D_TILED_THICK
: //fall through
2512 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2513 case ADDR_TM_3D_TILED_THIN1
: //fall through
2514 case ADDR_TM_3D_TILED_THICK
: //fall through
2515 case ADDR_TM_3D_TILED_XTHICK
:
2516 tileSplitRotation
= ((pTileInfo
->banks
/ 2) + 1);
2519 tileSplitRotation
= 0;
2523 UINT_32 microTileThickness
= Thickness(tileMode
);
2525 bank
^= tileSplitRotation
* tileSlices
;
2526 if (pipeRotation
== 0)
2528 bank
^= bankRotation
* (slice
/ microTileThickness
) + bankSwizzle
;
2529 bank
%= pTileInfo
->banks
;
2530 pipe
^= pipeSwizzle
;
2534 bank
^= bankRotation
* (slice
/ microTileThickness
) / numPipes
+ bankSwizzle
;
2535 bank
%= pTileInfo
->banks
;
2536 pipe
^= pipeRotation
* (slice
/ microTileThickness
) + pipeSwizzle
;
2539 if (pTileInfo
->macroAspectRatio
== 1)
2541 switch (pTileInfo
->banks
)
2544 yBit3
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2547 yBit4
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2548 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2551 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2552 yBit5
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2553 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ yBit5
;
2556 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3);
2557 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2);
2558 yBit6
= _BIT(bank
, 0) ^ _BIT(xBit
, 0);
2559 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ yBit6
;
2566 else if (pTileInfo
->macroAspectRatio
== 2)
2568 switch (pTileInfo
->banks
)
2570 case 2: //xBit3 = yBit3^b0
2571 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,0);
2573 case 4: //xBit3=yBit4^b0; yBit3=xBit4^b1
2574 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2575 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2577 case 8: //xBit4, xBit5, yBit5 are known
2578 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2579 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2580 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ _BIT(yBit
, 2);
2582 case 16://x4,x5,x6,y6 are known
2583 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3); //x3 = y6 ^ b0
2584 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2585 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = x5 ^ b2
2586 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ _BIT(yBit
, 3); //y5=x4^y6^b1
2592 else if (pTileInfo
->macroAspectRatio
== 4)
2594 switch (pTileInfo
->banks
)
2596 case 4: //yBit3, yBit4
2597 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2598 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,0);
2600 case 8: //xBit5, yBit4, yBit5
2601 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2602 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2603 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
,2);
2605 case 16: //xBit5, xBit6, yBit5, yBit6
2606 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = b0 ^ y6
2607 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = b1 ^ y5 ^ y6;
2608 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = b3 ^ x6;
2609 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = b2 ^ x5;
2615 else if (pTileInfo
->macroAspectRatio
== 8)
2617 switch (pTileInfo
->banks
)
2619 case 8: //yBit3, yBit4, yBit5
2620 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2); //x3 = b0 ^ y5;
2621 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
, 2);//x4 = b1 ^ y4 ^ y5;
2622 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
,0);
2624 case 16: //xBit6, yBit4, yBit5, yBit6
2625 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = y6 ^ b0
2626 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = y5 ^ y6 ^ b1
2627 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
, 1);//x5 = y4 ^ b2
2628 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2635 pOutput
->xBits
= xBit
;
2636 pOutput
->yBits
= yBit
;
2638 pOutput
->xBit3
= xBit3
;
2639 pOutput
->xBit4
= xBit4
;
2640 pOutput
->xBit5
= xBit5
;
2641 pOutput
->yBit3
= yBit3
;
2642 pOutput
->yBit4
= yBit4
;
2643 pOutput
->yBit5
= yBit5
;
2644 pOutput
->yBit6
= yBit6
;
2648 ****************************************************************************************************
2649 * EgBasedLib::HwlExtractBankPipeSwizzle
2651 * Entry of EgBasedLib ExtractBankPipeSwizzle
2654 ****************************************************************************************************
2656 ADDR_E_RETURNCODE
EgBasedLib::HwlExtractBankPipeSwizzle(
2657 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
2658 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
2661 ExtractBankPipeSwizzle(pIn
->base256b
,
2664 &pOut
->pipeSwizzle
);
2670 ****************************************************************************************************
2671 * EgBasedLib::HwlCombineBankPipeSwizzle
2673 * Combine bank/pipe swizzle
2676 ****************************************************************************************************
2678 ADDR_E_RETURNCODE
EgBasedLib::HwlCombineBankPipeSwizzle(
2679 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2680 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2681 ADDR_TILEINFO
* pTileInfo
, ///< [in] tile info
2682 UINT_64 baseAddr
, ///< [in] base address
2683 UINT_32
* pTileSwizzle
///< [out] combined swizzle
2686 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
2690 *pTileSwizzle
= GetBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, baseAddr
, pTileInfo
);
2694 retCode
= ADDR_INVALIDPARAMS
;
2701 ****************************************************************************************************
2702 * EgBasedLib::HwlComputeBaseSwizzle
2704 * Compute base swizzle
2707 ****************************************************************************************************
2709 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeBaseSwizzle(
2710 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT
* pIn
,
2711 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
* pOut
2714 UINT_32 bankSwizzle
= 0;
2715 UINT_32 pipeSwizzle
= 0;
2716 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2718 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
2719 ADDR_ASSERT(pIn
->pTileInfo
);
2721 /// This is a legacy misreading of h/w doc, use it as it doesn't hurt.
2722 static const UINT_8 bankRotationArray
[4][16] = {
2723 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_2_BANK
2724 { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_4_BANK
2725 { 0, 3, 6, 1, 4, 7, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_8_BANK
2726 { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }, // ADDR_SURF_16_BANK
2729 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2731 UINT_32 banks
= pTileInfo
? pTileInfo
->banks
: 2;
2734 // Uses less bank swizzle bits
2735 if (pIn
->option
.reduceBankBit
&& banks
> 2)
2755 ADDR_ASSERT_ALWAYS();
2760 if (pIn
->option
.genOption
== ADDR_SWIZZLE_GEN_LINEAR
)
2762 bankSwizzle
= pIn
->surfIndex
& (banks
- 1);
2764 else // (pIn->option.genOption == ADDR_SWIZZLE_GEN_DEFAULT)
2766 bankSwizzle
= bankRotationArray
[hwNumBanks
][pIn
->surfIndex
& (banks
- 1)];
2769 if (IsMacro3dTiled(pIn
->tileMode
))
2771 pipeSwizzle
= pIn
->surfIndex
& (HwlGetPipes(pTileInfo
) - 1);
2774 return HwlCombineBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, pTileInfo
, 0, &pOut
->tileSwizzle
);
2778 ****************************************************************************************************
2779 * EgBasedLib::ExtractBankPipeSwizzle
2781 * Extract bank/pipe swizzle from base256b
2784 ****************************************************************************************************
2786 VOID
EgBasedLib::ExtractBankPipeSwizzle(
2787 UINT_32 base256b
, ///< [in] input base256b register value
2788 ADDR_TILEINFO
* pTileInfo
, ///< [in] 2D tile parameters. Client must provide all data
2789 UINT_32
* pBankSwizzle
, ///< [out] bank swizzle
2790 UINT_32
* pPipeSwizzle
///< [out] pipe swizzle
2793 UINT_32 bankSwizzle
= 0;
2794 UINT_32 pipeSwizzle
= 0;
2798 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2799 UINT_32 bankBits
= QLog2(pTileInfo
->banks
);
2800 UINT_32 pipeBits
= QLog2(numPipes
);
2801 UINT_32 groupBytes
= m_pipeInterleaveBytes
;
2802 UINT_32 bankInterleave
= m_bankInterleave
;
2805 (base256b
/ (groupBytes
>> 8)) & ((1<<pipeBits
)-1);
2808 (base256b
/ (groupBytes
>> 8) / numPipes
/ bankInterleave
) & ((1 << bankBits
) - 1);
2811 *pPipeSwizzle
= pipeSwizzle
;
2812 *pBankSwizzle
= bankSwizzle
;
2816 ****************************************************************************************************
2817 * EgBasedLib::GetBankPipeSwizzle
2819 * Combine bank/pipe swizzle
2821 * Base256b bits (only filled bank/pipe bits)
2822 ****************************************************************************************************
2824 UINT_32
EgBasedLib::GetBankPipeSwizzle(
2825 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2826 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2827 UINT_64 baseAddr
, ///< [in] base address
2828 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2831 UINT_32 pipeBits
= QLog2(HwlGetPipes(pTileInfo
));
2832 UINT_32 bankInterleaveBits
= QLog2(m_bankInterleave
);
2833 UINT_32 tileSwizzle
= pipeSwizzle
+ ((bankSwizzle
<< bankInterleaveBits
) << pipeBits
);
2835 baseAddr
^= tileSwizzle
* m_pipeInterleaveBytes
;
2838 return static_cast<UINT_32
>(baseAddr
);
2842 ****************************************************************************************************
2843 * EgBasedLib::ComputeSliceTileSwizzle
2845 * Compute cubemap/3d texture faces/slices tile swizzle
2848 ****************************************************************************************************
2850 UINT_32
EgBasedLib::ComputeSliceTileSwizzle(
2851 AddrTileMode tileMode
, ///< [in] Tile mode
2852 UINT_32 baseSwizzle
, ///< [in] Base swizzle
2853 UINT_32 slice
, ///< [in] Slice index, Cubemap face index, 0 means +X
2854 UINT_64 baseAddr
, ///< [in] Base address
2855 ADDR_TILEINFO
* pTileInfo
///< [in] Bank structure
2858 UINT_32 tileSwizzle
= 0;
2860 if (IsMacroTiled(tileMode
)) // Swizzle only for macro tile mode
2862 UINT_32 firstSlice
= slice
/ Thickness(tileMode
);
2864 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2865 UINT_32 numBanks
= pTileInfo
->banks
;
2867 UINT_32 pipeRotation
;
2868 UINT_32 bankRotation
;
2870 UINT_32 bankSwizzle
= 0;
2871 UINT_32 pipeSwizzle
= 0;
2873 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2874 bankRotation
= ComputeBankRotation(tileMode
, numBanks
, numPipes
);
2876 if (baseSwizzle
!= 0)
2878 ExtractBankPipeSwizzle(baseSwizzle
,
2884 if (pipeRotation
== 0) //2D mode
2886 bankSwizzle
+= firstSlice
* bankRotation
;
2887 bankSwizzle
%= numBanks
;
2891 pipeSwizzle
+= firstSlice
* pipeRotation
;
2892 pipeSwizzle
%= numPipes
;
2893 bankSwizzle
+= firstSlice
* bankRotation
/ numPipes
;
2894 bankSwizzle
%= numBanks
;
2897 tileSwizzle
= GetBankPipeSwizzle(bankSwizzle
,
2907 ****************************************************************************************************
2908 * EgBasedLib::HwlComputeQbStereoRightSwizzle
2911 * Compute right eye swizzle
2914 ****************************************************************************************************
2916 UINT_32
EgBasedLib::HwlComputeQbStereoRightSwizzle(
2917 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pInfo
///< [in] Surface info, must be valid
2920 UINT_32 bankBits
= 0;
2921 UINT_32 swizzle
= 0;
2923 // The assumption is default swizzle for left eye is 0
2924 if (IsMacroTiled(pInfo
->tileMode
) && pInfo
->pStereoInfo
&& pInfo
->pTileInfo
)
2926 bankBits
= ComputeBankFromCoord(0, pInfo
->height
, 0,
2927 pInfo
->tileMode
, 0, 0, pInfo
->pTileInfo
);
2931 HwlCombineBankPipeSwizzle(bankBits
, 0, pInfo
->pTileInfo
, 0, &swizzle
);
2939 ****************************************************************************************************
2940 * EgBasedLib::ComputeBankFromCoord
2943 * Compute bank number from coordinates
2946 ****************************************************************************************************
2948 UINT_32
EgBasedLib::ComputeBankFromCoord(
2949 UINT_32 x
, ///< [in] x coordinate
2950 UINT_32 y
, ///< [in] y coordinate
2951 UINT_32 slice
, ///< [in] slice index
2952 AddrTileMode tileMode
, ///< [in] tile mode
2953 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2954 UINT_32 tileSplitSlice
, ///< [in] If the size of the pixel offset is larger than the
2955 /// tile split size, then the pixel will be moved to a separate
2956 /// slice. This value equals pixelOffset / tileSplitBytes
2957 /// in this case. Otherwise this is 0.
2958 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2961 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2962 UINT_32 bankBit0
= 0;
2963 UINT_32 bankBit1
= 0;
2964 UINT_32 bankBit2
= 0;
2965 UINT_32 bankBit3
= 0;
2966 UINT_32 sliceRotation
;
2967 UINT_32 tileSplitRotation
;
2969 UINT_32 numBanks
= pTileInfo
->banks
;
2970 UINT_32 bankWidth
= pTileInfo
->bankWidth
;
2971 UINT_32 bankHeight
= pTileInfo
->bankHeight
;
2973 UINT_32 tx
= x
/ MicroTileWidth
/ (bankWidth
* pipes
);
2974 UINT_32 ty
= y
/ MicroTileHeight
/ bankHeight
;
2976 UINT_32 x3
= _BIT(tx
,0);
2977 UINT_32 x4
= _BIT(tx
,1);
2978 UINT_32 x5
= _BIT(tx
,2);
2979 UINT_32 x6
= _BIT(tx
,3);
2980 UINT_32 y3
= _BIT(ty
,0);
2981 UINT_32 y4
= _BIT(ty
,1);
2982 UINT_32 y5
= _BIT(ty
,2);
2983 UINT_32 y6
= _BIT(ty
,3);
2989 bankBit1
= x4
^ y5
^ y6
;
2995 bankBit1
= x4
^ y4
^ y5
;
3006 ADDR_ASSERT_ALWAYS();
3010 bank
= bankBit0
| (bankBit1
<< 1) | (bankBit2
<< 2) | (bankBit3
<< 3);
3012 //Bits2Number(4, bankBit3, bankBit2, bankBit1, bankBit0);
3014 bank
= HwlPreAdjustBank((x
/ MicroTileWidth
), bank
, pTileInfo
);
3016 // Compute bank rotation for the slice.
3018 UINT_32 microTileThickness
= Thickness(tileMode
);
3022 case ADDR_TM_2D_TILED_THIN1
: // fall through
3023 case ADDR_TM_2D_TILED_THICK
: // fall through
3024 case ADDR_TM_2D_TILED_XTHICK
:
3025 sliceRotation
= ((numBanks
/ 2) - 1) * (slice
/ microTileThickness
);
3027 case ADDR_TM_3D_TILED_THIN1
: // fall through
3028 case ADDR_TM_3D_TILED_THICK
: // fall through
3029 case ADDR_TM_3D_TILED_XTHICK
:
3031 Max(1u, (pipes
/ 2) - 1) * (slice
/ microTileThickness
) / pipes
;
3039 // Compute bank rotation for the tile split slice.
3041 // The sample slice will be non-zero if samples must be split across multiple slices.
3042 // This situation arises when the micro tile size multiplied yBit the number of samples exceeds
3043 // the split size (set in GB_ADDR_CONFIG).
3047 case ADDR_TM_2D_TILED_THIN1
: //fall through
3048 case ADDR_TM_3D_TILED_THIN1
: //fall through
3049 case ADDR_TM_PRT_2D_TILED_THIN1
: //fall through
3050 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
3051 tileSplitRotation
= ((numBanks
/ 2) + 1) * tileSplitSlice
;
3054 tileSplitRotation
= 0;
3059 // Apply bank rotation for the slice and tile split slice.
3061 bank
^= bankSwizzle
+ sliceRotation
;
3062 bank
^= tileSplitRotation
;
3064 bank
&= (numBanks
- 1);
3070 ****************************************************************************************************
3071 * EgBasedLib::ComputeBankFromAddr
3074 * Compute the bank number from an address
3077 ****************************************************************************************************
3079 UINT_32
EgBasedLib::ComputeBankFromAddr(
3080 UINT_64 addr
, ///< [in] address
3081 UINT_32 numBanks
, ///< [in] number of banks
3082 UINT_32 numPipes
///< [in] number of pipes
3088 // The LSBs of the address are arranged as follows:
3089 // bank | bankInterleave | pipe | pipeInterleave
3091 // To get the bank number, shift off the pipe interleave, pipe, and bank interlave bits and
3092 // mask the bank bits.
3094 bank
= static_cast<UINT_32
>(
3095 (addr
>> Log2(m_pipeInterleaveBytes
* numPipes
* m_bankInterleave
)) &
3103 ****************************************************************************************************
3104 * EgBasedLib::ComputePipeRotation
3107 * Compute pipe rotation value
3110 ****************************************************************************************************
3112 UINT_32
EgBasedLib::ComputePipeRotation(
3113 AddrTileMode tileMode
, ///< [in] tile mode
3114 UINT_32 numPipes
///< [in] number of pipes
3121 case ADDR_TM_3D_TILED_THIN1
: //fall through
3122 case ADDR_TM_3D_TILED_THICK
: //fall through
3123 case ADDR_TM_3D_TILED_XTHICK
: //fall through
3124 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
3125 case ADDR_TM_PRT_3D_TILED_THICK
:
3126 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1);
3136 ****************************************************************************************************
3137 * EgBasedLib::ComputeBankRotation
3140 * Compute bank rotation value
3143 ****************************************************************************************************
3145 UINT_32
EgBasedLib::ComputeBankRotation(
3146 AddrTileMode tileMode
, ///< [in] tile mode
3147 UINT_32 numBanks
, ///< [in] number of banks
3148 UINT_32 numPipes
///< [in] number of pipes
3155 case ADDR_TM_2D_TILED_THIN1
: // fall through
3156 case ADDR_TM_2D_TILED_THICK
: // fall through
3157 case ADDR_TM_2D_TILED_XTHICK
:
3158 case ADDR_TM_PRT_2D_TILED_THIN1
:
3159 case ADDR_TM_PRT_2D_TILED_THICK
:
3160 // Rotate banks per Z-slice yBit 1 for 4-bank or 3 for 8-bank
3161 rotation
= numBanks
/ 2 - 1;
3163 case ADDR_TM_3D_TILED_THIN1
: // fall through
3164 case ADDR_TM_3D_TILED_THICK
: // fall through
3165 case ADDR_TM_3D_TILED_XTHICK
:
3166 case ADDR_TM_PRT_3D_TILED_THIN1
:
3167 case ADDR_TM_PRT_3D_TILED_THICK
:
3168 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1); // rotate pipes & banks
3178 ****************************************************************************************************
3179 * EgBasedLib::ComputeHtileBytes
3182 * Compute htile size in bytes
3185 * Htile size in bytes
3186 ****************************************************************************************************
3188 UINT_64
EgBasedLib::ComputeHtileBytes(
3189 UINT_32 pitch
, ///< [in] pitch
3190 UINT_32 height
, ///< [in] height
3191 UINT_32 bpp
, ///< [in] bits per pixel
3192 BOOL_32 isLinear
, ///< [in] if it is linear mode
3193 UINT_32 numSlices
, ///< [in] number of slices
3194 UINT_64
* sliceBytes
, ///< [out] bytes per slice
3195 UINT_32 baseAlign
///< [in] base alignments
3200 const UINT_64 HtileCacheLineSize
= BITS_TO_BYTES(HtileCacheBits
);
3202 *sliceBytes
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
/ 64);
3204 if (m_configFlags
.useHtileSliceAlign
)
3206 // Align the sliceSize to htilecachelinesize * pipes at first
3207 *sliceBytes
= PowTwoAlign(*sliceBytes
, HtileCacheLineSize
* m_pipes
);
3208 surfBytes
= *sliceBytes
* numSlices
;
3212 // Align the surfSize to htilecachelinesize * pipes at last
3213 surfBytes
= *sliceBytes
* numSlices
;
3214 surfBytes
= PowTwoAlign(surfBytes
, HtileCacheLineSize
* m_pipes
);
3221 ****************************************************************************************************
3222 * EgBasedLib::DispatchComputeFmaskInfo
3225 * Compute fmask sizes include padded pitch, height, slices, total size in bytes,
3226 * meanwhile output suitable tile mode and alignments as well. Results are returned
3227 * through output parameters.
3231 ****************************************************************************************************
3233 ADDR_E_RETURNCODE
EgBasedLib::DispatchComputeFmaskInfo(
3234 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3235 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
) ///< [out] output structure
3237 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3239 ADDR_COMPUTE_SURFACE_INFO_INPUT surfIn
= {0};
3240 ADDR_COMPUTE_SURFACE_INFO_OUTPUT surfOut
= {0};
3242 // Setup input structure
3243 surfIn
.tileMode
= pIn
->tileMode
;
3244 surfIn
.width
= pIn
->pitch
;
3245 surfIn
.height
= pIn
->height
;
3246 surfIn
.numSlices
= pIn
->numSlices
;
3247 surfIn
.pTileInfo
= pIn
->pTileInfo
;
3248 surfIn
.tileType
= ADDR_NON_DISPLAYABLE
;
3249 surfIn
.flags
.fmask
= 1;
3251 // Setup output structure
3252 surfOut
.pTileInfo
= pOut
->pTileInfo
;
3254 // Setup hwl specific fields
3255 HwlFmaskPreThunkSurfInfo(pIn
, pOut
, &surfIn
, &surfOut
);
3257 surfIn
.bpp
= HwlComputeFmaskBits(pIn
, &surfIn
.numSamples
);
3259 // ComputeSurfaceInfo needs numSamples in surfOut as surface routines need adjusted numSamples
3260 surfOut
.numSamples
= surfIn
.numSamples
;
3262 retCode
= HwlComputeSurfaceInfo(&surfIn
, &surfOut
);
3264 // Save bpp field for surface dump support
3265 surfOut
.bpp
= surfIn
.bpp
;
3267 if (retCode
== ADDR_OK
)
3269 pOut
->bpp
= surfOut
.bpp
;
3270 pOut
->pitch
= surfOut
.pitch
;
3271 pOut
->height
= surfOut
.height
;
3272 pOut
->numSlices
= surfOut
.depth
;
3273 pOut
->fmaskBytes
= surfOut
.surfSize
;
3274 pOut
->baseAlign
= surfOut
.baseAlign
;
3275 pOut
->pitchAlign
= surfOut
.pitchAlign
;
3276 pOut
->heightAlign
= surfOut
.heightAlign
;
3278 if (surfOut
.depth
> 1)
3280 // For fmask, expNumSlices is stored in depth.
3281 pOut
->sliceSize
= surfOut
.surfSize
/ surfOut
.depth
;
3285 pOut
->sliceSize
= surfOut
.surfSize
;
3288 // Save numSamples field for surface dump support
3289 pOut
->numSamples
= surfOut
.numSamples
;
3291 HwlFmaskPostThunkSurfInfo(&surfOut
, pOut
);
3298 ****************************************************************************************************
3299 * EgBasedLib::HwlFmaskSurfaceInfo
3301 * Entry of EgBasedLib ComputeFmaskInfo
3304 ****************************************************************************************************
3306 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskInfo(
3307 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3308 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
3311 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3313 ADDR_TILEINFO tileInfo
= {0};
3315 // Use internal tile info if pOut does not have a valid pTileInfo
3316 if (pOut
->pTileInfo
== NULL
)
3318 pOut
->pTileInfo
= &tileInfo
;
3321 retCode
= DispatchComputeFmaskInfo(pIn
, pOut
);
3323 if (retCode
== ADDR_OK
)
3326 HwlPostCheckTileIndex(pOut
->pTileInfo
, pIn
->tileMode
, ADDR_NON_DISPLAYABLE
,
3330 // Resets pTileInfo to NULL if the internal tile info is used
3331 if (pOut
->pTileInfo
== &tileInfo
)
3333 pOut
->pTileInfo
= NULL
;
3340 ****************************************************************************************************
3341 * EgBasedLib::HwlComputeFmaskAddrFromCoord
3343 * Entry of EgBasedLib ComputeFmaskAddrFromCoord
3346 ****************************************************************************************************
3348 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskAddrFromCoord(
3349 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3350 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3353 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3359 ****************************************************************************************************
3360 * EgBasedLib::HwlComputeFmaskCoordFromAddr
3362 * Entry of EgBasedLib ComputeFmaskCoordFromAddr
3365 ****************************************************************************************************
3367 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskCoordFromAddr(
3368 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3369 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3372 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3378 ****************************************************************************************************
3379 * EgBasedLib::ComputeFmaskNumPlanesFromNumSamples
3382 * Compute fmask number of planes from number of samples
3386 ****************************************************************************************************
3388 UINT_32
EgBasedLib::ComputeFmaskNumPlanesFromNumSamples(
3389 UINT_32 numSamples
) ///< [in] number of samples
3394 // FMASK is stored such that each micro tile is composed of elements containing N bits, where
3395 // N is the number of samples. There is a micro tile for each bit in the FMASK address, and
3396 // micro tiles for each address bit, sometimes referred to as a plane, are stored sequentially.
3397 // The FMASK for a 2-sample surface looks like a general surface with 2 bits per element.
3398 // The FMASK for a 4-sample surface looks like a general surface with 4 bits per element and
3399 // 2 samples. The FMASK for an 8-sample surface looks like a general surface with 8 bits per
3400 // element and 4 samples. R6xx and R7xx only stored 3 planes for 8-sample FMASK surfaces.
3401 // This was changed for R8xx to simplify the logic in the CB.
3415 ADDR_UNHANDLED_CASE();
3423 ****************************************************************************************************
3424 * EgBasedLib::ComputeFmaskResolvedBppFromNumSamples
3427 * Compute resolved fmask effective bpp based on number of samples
3431 ****************************************************************************************************
3433 UINT_32
EgBasedLib::ComputeFmaskResolvedBppFromNumSamples(
3434 UINT_32 numSamples
) ///< number of samples
3439 // Resolved FMASK surfaces are generated yBit the CB and read yBit the texture unit
3440 // so that the texture unit can read compressed multi-sample color data.
3441 // These surfaces store each index value packed per element.
3442 // Each element contains at least num_samples * log2(num_samples) bits.
3443 // Resolved FMASK surfaces are addressed as follows:
3444 // 2-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3445 // 4-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3446 // 8-sample Addressed similarly to a color surface with 32 bits per element and 1 sample.
3460 ADDR_UNHANDLED_CASE();
3468 ****************************************************************************************************
3469 * EgBasedLib::IsTileInfoAllZero
3472 * Return TRUE if all field are zero
3474 * Since NULL input is consider to be all zero
3475 ****************************************************************************************************
3477 BOOL_32
EgBasedLib::IsTileInfoAllZero(
3478 const ADDR_TILEINFO
* pTileInfo
)
3480 BOOL_32 allZero
= TRUE
;
3484 if ((pTileInfo
->banks
!= 0) ||
3485 (pTileInfo
->bankWidth
!= 0) ||
3486 (pTileInfo
->bankHeight
!= 0) ||
3487 (pTileInfo
->macroAspectRatio
!= 0) ||
3488 (pTileInfo
->tileSplitBytes
!= 0) ||
3489 (pTileInfo
->pipeConfig
!= 0)
3500 ****************************************************************************************************
3501 * EgBasedLib::HwlTileInfoEqual
3504 * Return TRUE if all field are equal
3506 * Only takes care of current HWL's data
3507 ****************************************************************************************************
3509 BOOL_32
EgBasedLib::HwlTileInfoEqual(
3510 const ADDR_TILEINFO
* pLeft
, ///<[in] Left compare operand
3511 const ADDR_TILEINFO
* pRight
///<[in] Right compare operand
3514 BOOL_32 equal
= FALSE
;
3516 if (pLeft
->banks
== pRight
->banks
&&
3517 pLeft
->bankWidth
== pRight
->bankWidth
&&
3518 pLeft
->bankHeight
== pRight
->bankHeight
&&
3519 pLeft
->macroAspectRatio
== pRight
->macroAspectRatio
&&
3520 pLeft
->tileSplitBytes
== pRight
->tileSplitBytes
)
3529 ****************************************************************************************************
3530 * EgBasedLib::HwlConvertTileInfoToHW
3532 * Entry of EgBasedLib ConvertTileInfoToHW
3535 ****************************************************************************************************
3537 ADDR_E_RETURNCODE
EgBasedLib::HwlConvertTileInfoToHW(
3538 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
3539 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
3542 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3544 ADDR_TILEINFO
*pTileInfoIn
= pIn
->pTileInfo
;
3545 ADDR_TILEINFO
*pTileInfoOut
= pOut
->pTileInfo
;
3547 if ((pTileInfoIn
!= NULL
) && (pTileInfoOut
!= NULL
))
3549 if (pIn
->reverse
== FALSE
)
3551 switch (pTileInfoIn
->banks
)
3554 pTileInfoOut
->banks
= 0;
3557 pTileInfoOut
->banks
= 1;
3560 pTileInfoOut
->banks
= 2;
3563 pTileInfoOut
->banks
= 3;
3566 ADDR_ASSERT_ALWAYS();
3567 retCode
= ADDR_INVALIDPARAMS
;
3568 pTileInfoOut
->banks
= 0;
3572 switch (pTileInfoIn
->bankWidth
)
3575 pTileInfoOut
->bankWidth
= 0;
3578 pTileInfoOut
->bankWidth
= 1;
3581 pTileInfoOut
->bankWidth
= 2;
3584 pTileInfoOut
->bankWidth
= 3;
3587 ADDR_ASSERT_ALWAYS();
3588 retCode
= ADDR_INVALIDPARAMS
;
3589 pTileInfoOut
->bankWidth
= 0;
3593 switch (pTileInfoIn
->bankHeight
)
3596 pTileInfoOut
->bankHeight
= 0;
3599 pTileInfoOut
->bankHeight
= 1;
3602 pTileInfoOut
->bankHeight
= 2;
3605 pTileInfoOut
->bankHeight
= 3;
3608 ADDR_ASSERT_ALWAYS();
3609 retCode
= ADDR_INVALIDPARAMS
;
3610 pTileInfoOut
->bankHeight
= 0;
3614 switch (pTileInfoIn
->macroAspectRatio
)
3617 pTileInfoOut
->macroAspectRatio
= 0;
3620 pTileInfoOut
->macroAspectRatio
= 1;
3623 pTileInfoOut
->macroAspectRatio
= 2;
3626 pTileInfoOut
->macroAspectRatio
= 3;
3629 ADDR_ASSERT_ALWAYS();
3630 retCode
= ADDR_INVALIDPARAMS
;
3631 pTileInfoOut
->macroAspectRatio
= 0;
3635 switch (pTileInfoIn
->tileSplitBytes
)
3638 pTileInfoOut
->tileSplitBytes
= 0;
3641 pTileInfoOut
->tileSplitBytes
= 1;
3644 pTileInfoOut
->tileSplitBytes
= 2;
3647 pTileInfoOut
->tileSplitBytes
= 3;
3650 pTileInfoOut
->tileSplitBytes
= 4;
3653 pTileInfoOut
->tileSplitBytes
= 5;
3656 pTileInfoOut
->tileSplitBytes
= 6;
3659 ADDR_ASSERT_ALWAYS();
3660 retCode
= ADDR_INVALIDPARAMS
;
3661 pTileInfoOut
->tileSplitBytes
= 0;
3667 switch (pTileInfoIn
->banks
)
3670 pTileInfoOut
->banks
= 2;
3673 pTileInfoOut
->banks
= 4;
3676 pTileInfoOut
->banks
= 8;
3679 pTileInfoOut
->banks
= 16;
3682 ADDR_ASSERT_ALWAYS();
3683 retCode
= ADDR_INVALIDPARAMS
;
3684 pTileInfoOut
->banks
= 2;
3688 switch (pTileInfoIn
->bankWidth
)
3691 pTileInfoOut
->bankWidth
= 1;
3694 pTileInfoOut
->bankWidth
= 2;
3697 pTileInfoOut
->bankWidth
= 4;
3700 pTileInfoOut
->bankWidth
= 8;
3703 ADDR_ASSERT_ALWAYS();
3704 retCode
= ADDR_INVALIDPARAMS
;
3705 pTileInfoOut
->bankWidth
= 1;
3709 switch (pTileInfoIn
->bankHeight
)
3712 pTileInfoOut
->bankHeight
= 1;
3715 pTileInfoOut
->bankHeight
= 2;
3718 pTileInfoOut
->bankHeight
= 4;
3721 pTileInfoOut
->bankHeight
= 8;
3724 ADDR_ASSERT_ALWAYS();
3725 retCode
= ADDR_INVALIDPARAMS
;
3726 pTileInfoOut
->bankHeight
= 1;
3730 switch (pTileInfoIn
->macroAspectRatio
)
3733 pTileInfoOut
->macroAspectRatio
= 1;
3736 pTileInfoOut
->macroAspectRatio
= 2;
3739 pTileInfoOut
->macroAspectRatio
= 4;
3742 pTileInfoOut
->macroAspectRatio
= 8;
3745 ADDR_ASSERT_ALWAYS();
3746 retCode
= ADDR_INVALIDPARAMS
;
3747 pTileInfoOut
->macroAspectRatio
= 1;
3751 switch (pTileInfoIn
->tileSplitBytes
)
3754 pTileInfoOut
->tileSplitBytes
= 64;
3757 pTileInfoOut
->tileSplitBytes
= 128;
3760 pTileInfoOut
->tileSplitBytes
= 256;
3763 pTileInfoOut
->tileSplitBytes
= 512;
3766 pTileInfoOut
->tileSplitBytes
= 1024;
3769 pTileInfoOut
->tileSplitBytes
= 2048;
3772 pTileInfoOut
->tileSplitBytes
= 4096;
3775 ADDR_ASSERT_ALWAYS();
3776 retCode
= ADDR_INVALIDPARAMS
;
3777 pTileInfoOut
->tileSplitBytes
= 64;
3782 if (pTileInfoIn
!= pTileInfoOut
)
3784 pTileInfoOut
->pipeConfig
= pTileInfoIn
->pipeConfig
;
3789 ADDR_ASSERT_ALWAYS();
3790 retCode
= ADDR_INVALIDPARAMS
;
3797 ****************************************************************************************************
3798 * EgBasedLib::HwlComputeSurfaceInfo
3800 * Entry of EgBasedLib ComputeSurfaceInfo
3803 ****************************************************************************************************
3805 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceInfo(
3806 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
3807 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
3810 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3812 if (pIn
->numSamples
< pIn
->numFrags
)
3814 retCode
= ADDR_INVALIDPARAMS
;
3817 ADDR_TILEINFO tileInfo
= {0};
3819 if (retCode
== ADDR_OK
)
3821 // Uses internal tile info if pOut does not have a valid pTileInfo
3822 if (pOut
->pTileInfo
== NULL
)
3824 pOut
->pTileInfo
= &tileInfo
;
3827 if (DispatchComputeSurfaceInfo(pIn
, pOut
) == FALSE
)
3829 retCode
= ADDR_INVALIDPARAMS
;
3832 // In case client uses tile info as input and would like to calculate a correct size and
3833 // alignment together with tile info as output when the tile info is not suppose to have any
3834 // matching indices in tile mode tables.
3835 if (pIn
->flags
.skipIndicesOutput
== FALSE
)
3838 pOut
->tileIndex
= HwlPostCheckTileIndex(pOut
->pTileInfo
,
3843 if (IsMacroTiled(pOut
->tileMode
) && (pOut
->macroModeIndex
== TileIndexInvalid
))
3845 pOut
->macroModeIndex
= HwlComputeMacroModeIndex(pOut
->tileIndex
,
3853 // Resets pTileInfo to NULL if the internal tile info is used
3854 if (pOut
->pTileInfo
== &tileInfo
)
3857 // Client does not pass in a valid pTileInfo
3858 if (IsMacroTiled(pOut
->tileMode
))
3860 // If a valid index is returned, then no pTileInfo is okay
3861 ADDR_ASSERT((m_configFlags
.useTileIndex
== FALSE
) ||
3862 (pOut
->tileIndex
!= TileIndexInvalid
));
3864 if (IsTileInfoAllZero(pIn
->pTileInfo
) == FALSE
)
3866 // The initial value of pIn->pTileInfo is copied to tileInfo
3867 // We do not expect any of these value to be changed nor any 0 of inputs
3868 ADDR_ASSERT(tileInfo
.banks
== pIn
->pTileInfo
->banks
);
3869 ADDR_ASSERT(tileInfo
.bankWidth
== pIn
->pTileInfo
->bankWidth
);
3870 ADDR_ASSERT(tileInfo
.bankHeight
== pIn
->pTileInfo
->bankHeight
);
3871 ADDR_ASSERT(tileInfo
.macroAspectRatio
== pIn
->pTileInfo
->macroAspectRatio
);
3872 ADDR_ASSERT(tileInfo
.tileSplitBytes
== pIn
->pTileInfo
->tileSplitBytes
);
3876 pOut
->pTileInfo
= NULL
;
3884 ****************************************************************************************************
3885 * EgBasedLib::HwlComputeSurfaceAddrFromCoord
3887 * Entry of EgBasedLib ComputeSurfaceAddrFromCoord
3890 ****************************************************************************************************
3892 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceAddrFromCoord(
3893 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3894 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3897 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3900 #if !ALT_TEST // Overflow test needs this out-of-boundary coord
3901 (pIn
->x
> pIn
->pitch
) ||
3902 (pIn
->y
> pIn
->height
) ||
3904 (pIn
->numSamples
> m_maxSamples
))
3906 retCode
= ADDR_INVALIDPARAMS
;
3910 pOut
->addr
= DispatchComputeSurfaceAddrFromCoord(pIn
, pOut
);
3917 ****************************************************************************************************
3918 * EgBasedLib::HwlComputeSurfaceCoordFromAddr
3920 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
3923 ****************************************************************************************************
3925 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceCoordFromAddr(
3926 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3927 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3930 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3932 if ((pIn
->bitPosition
>= 8) ||
3933 (pIn
->numSamples
> m_maxSamples
))
3935 retCode
= ADDR_INVALIDPARAMS
;
3939 DispatchComputeSurfaceCoordFromAddr(pIn
, pOut
);
3945 ****************************************************************************************************
3946 * EgBasedLib::HwlComputeSliceTileSwizzle
3948 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
3951 ****************************************************************************************************
3953 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSliceTileSwizzle(
3954 const ADDR_COMPUTE_SLICESWIZZLE_INPUT
* pIn
, ///< [in] input structure
3955 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
* pOut
///< [out] output structure
3958 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3960 if (pIn
->pTileInfo
&& (pIn
->pTileInfo
->banks
> 0))
3963 pOut
->tileSwizzle
= ComputeSliceTileSwizzle(pIn
->tileMode
,
3971 retCode
= ADDR_INVALIDPARAMS
;
3978 ****************************************************************************************************
3979 * EgBasedLib::HwlComputeHtileBpp
3986 ****************************************************************************************************
3988 UINT_32
EgBasedLib::HwlComputeHtileBpp(
3989 BOOL_32 isWidth8
, ///< [in] TRUE if block width is 8
3990 BOOL_32 isHeight8
///< [in] TRUE if block height is 8
3993 // only support 8x8 mode
3994 ADDR_ASSERT(isWidth8
&& isHeight8
);
3999 ****************************************************************************************************
4000 * EgBasedLib::HwlComputeHtileBaseAlign
4003 * Compute htile base alignment
4006 * Htile base alignment
4007 ****************************************************************************************************
4009 UINT_32
EgBasedLib::HwlComputeHtileBaseAlign(
4010 BOOL_32 isTcCompatible
, ///< [in] if TC compatible
4011 BOOL_32 isLinear
, ///< [in] if it is linear mode
4012 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
4015 UINT_32 baseAlign
= m_pipeInterleaveBytes
* HwlGetPipes(pTileInfo
);
4019 ADDR_ASSERT(pTileInfo
!= NULL
);
4022 baseAlign
*= pTileInfo
->banks
;
4030 ****************************************************************************************************
4031 * EgBasedLib::HwlGetPitchAlignmentMicroTiled
4034 * Compute 1D tiled surface pitch alignment, calculation results are returned through
4035 * output parameters.
4039 ****************************************************************************************************
4041 UINT_32
EgBasedLib::HwlGetPitchAlignmentMicroTiled(
4042 AddrTileMode tileMode
, ///< [in] tile mode
4043 UINT_32 bpp
, ///< [in] bits per pixel
4044 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4045 UINT_32 numSamples
///< [in] number of samples
4050 UINT_32 microTileThickness
= Thickness(tileMode
);
4052 UINT_32 pixelsPerMicroTile
;
4053 UINT_32 pixelsPerPipeInterleave
;
4054 UINT_32 microTilesPerPipeInterleave
;
4057 // Special workaround for depth/stencil buffer, use 8 bpp to meet larger requirement for
4058 // stencil buffer since pitch alignment is related to bpp.
4059 // For a depth only buffer do not set this.
4061 // Note: this actually does not work for mipmap but mipmap depth texture is not really
4062 // sampled with mipmap.
4064 if (flags
.depth
&& (flags
.noStencil
== FALSE
))
4069 pixelsPerMicroTile
= MicroTilePixels
* microTileThickness
;
4070 pixelsPerPipeInterleave
= BYTES_TO_BITS(m_pipeInterleaveBytes
) / (bpp
* numSamples
);
4071 microTilesPerPipeInterleave
= pixelsPerPipeInterleave
/ pixelsPerMicroTile
;
4073 pitchAlign
= Max(MicroTileWidth
, microTilesPerPipeInterleave
* MicroTileWidth
);
4079 ****************************************************************************************************
4080 * EgBasedLib::HwlGetSizeAdjustmentMicroTiled
4083 * Adjust 1D tiled surface pitch and slice size
4086 * Logical slice size in bytes
4087 ****************************************************************************************************
4089 UINT_64
EgBasedLib::HwlGetSizeAdjustmentMicroTiled(
4090 UINT_32 thickness
, ///< [in] thickness
4091 UINT_32 bpp
, ///< [in] bits per pixel
4092 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4093 UINT_32 numSamples
, ///< [in] number of samples
4094 UINT_32 baseAlign
, ///< [in] base alignment
4095 UINT_32 pitchAlign
, ///< [in] pitch alignment
4096 UINT_32
* pPitch
, ///< [in,out] pointer to pitch
4097 UINT_32
* pHeight
///< [in,out] pointer to height
4100 UINT_64 logicalSliceSize
;
4101 MAYBE_UNUSED UINT_64 physicalSliceSize
;
4103 UINT_32 pitch
= *pPitch
;
4104 UINT_32 height
= *pHeight
;
4106 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
4107 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
4109 // Physical slice: multiplied by thickness
4110 physicalSliceSize
= logicalSliceSize
* thickness
;
4113 // R800 will always pad physical slice size to baseAlign which is pipe_interleave_bytes
4115 ADDR_ASSERT((physicalSliceSize
% baseAlign
) == 0);
4117 return logicalSliceSize
;
4121 ****************************************************************************************************
4122 * EgBasedLib::HwlStereoCheckRightOffsetPadding
4125 * check if the height needs extra padding for stereo right eye offset, to avoid swizzling
4128 * TRUE is the extra padding is needed
4130 ****************************************************************************************************
4132 UINT_32
EgBasedLib::HwlStereoCheckRightOffsetPadding(
4133 ADDR_TILEINFO
* pTileInfo
///< Tiling info
4136 UINT_32 stereoHeightAlign
= 0;
4138 if (pTileInfo
->macroAspectRatio
> 2)
4140 // Since 3D rendering treats right eye surface starting from y == "eye height" while
4141 // display engine treats it to be 0, so the bank bits may be different.
4142 // Additional padding in height is required to make sure it's possible
4143 // to achieve synonym by adjusting bank swizzle of right eye surface.
4145 static const UINT_32 StereoAspectRatio
= 2;
4146 stereoHeightAlign
= pTileInfo
->banks
*
4147 pTileInfo
->bankHeight
*
4152 return stereoHeightAlign
;