2 * Copyright © 2007-2019 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 if (flags
.czDispCompatible
&& (mipLevel
== 0))
746 *pBaseAlign
= PowTwoAlign(*pBaseAlign
, 4096); //Base address MOD 4096 = 0
747 *pPitchAlign
= PowTwoAlign(*pPitchAlign
, 512 / (BITS_TO_BYTES(bpp
))); //(8 lines * pitch * bytes per pixel) MOD 4096 = 0
749 // end Carrizo workaround for 1D tilling
755 ****************************************************************************************************
756 * EgBasedLib::HwlReduceBankWidthHeight
759 * Additional checks, reduce bankHeight/bankWidth if needed and possible
760 * tileSize*BANK_WIDTH*BANK_HEIGHT <= ROW_SIZE
763 * TRUE if no error occurs
764 ****************************************************************************************************
766 BOOL_32
EgBasedLib::HwlReduceBankWidthHeight(
767 UINT_32 tileSize
, ///< [in] tile size
768 UINT_32 bpp
, ///< [in] bits per pixel
769 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
770 UINT_32 numSamples
, ///< [in] number of samples
771 UINT_32 bankHeightAlign
, ///< [in] bank height alignment
772 UINT_32 pipes
, ///< [in] pipes
773 ADDR_TILEINFO
* pTileInfo
///< [in,out] bank structure.
776 UINT_32 macroAspectAlign
;
777 BOOL_32 valid
= TRUE
;
779 if (tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
)
781 BOOL_32 stillGreater
= TRUE
;
783 // Try reducing bankWidth first
784 if (stillGreater
&& pTileInfo
->bankWidth
> 1)
786 while (stillGreater
&& pTileInfo
->bankWidth
> 0)
788 pTileInfo
->bankWidth
>>= 1;
790 if (pTileInfo
->bankWidth
== 0)
792 pTileInfo
->bankWidth
= 1;
797 tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
;
800 // bankWidth is reduced above, so we need to recalculate bankHeight and ratio
801 bankHeightAlign
= Max(1u,
802 m_pipeInterleaveBytes
* m_bankInterleave
/
803 (tileSize
* pTileInfo
->bankWidth
)
806 // We cannot increase bankHeight so just assert this case.
807 ADDR_ASSERT((pTileInfo
->bankHeight
% bankHeightAlign
) == 0);
811 macroAspectAlign
= Max(1u,
812 m_pipeInterleaveBytes
* m_bankInterleave
/
813 (tileSize
* pipes
* pTileInfo
->bankWidth
)
815 pTileInfo
->macroAspectRatio
= PowTwoAlign(pTileInfo
->macroAspectRatio
,
820 // Early quit bank_height degradation for "64" bit z buffer
821 if (flags
.depth
&& bpp
>= 64)
823 stillGreater
= FALSE
;
826 // Then try reducing bankHeight
827 if (stillGreater
&& pTileInfo
->bankHeight
> bankHeightAlign
)
829 while (stillGreater
&& pTileInfo
->bankHeight
> bankHeightAlign
)
831 pTileInfo
->bankHeight
>>= 1;
833 if (pTileInfo
->bankHeight
< bankHeightAlign
)
835 pTileInfo
->bankHeight
= bankHeightAlign
;
840 tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
;
844 valid
= !stillGreater
;
846 // Generate a warning if we still fail to meet this constraint
850 0, ("TILE_SIZE(%d)*BANK_WIDTH(%d)*BANK_HEIGHT(%d) <= ROW_SIZE(%d)",
851 tileSize
, pTileInfo
->bankWidth
, pTileInfo
->bankHeight
, m_rowSize
));
859 ****************************************************************************************************
860 * EgBasedLib::ComputeSurfaceAlignmentsMacroTiled
863 * Compute 2D tiled surface alignment, calculation results are returned through
867 * TRUE if no error occurs
868 ****************************************************************************************************
870 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsMacroTiled(
871 AddrTileMode tileMode
, ///< [in] tile mode
872 UINT_32 bpp
, ///< [in] bits per pixel
873 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
874 UINT_32 mipLevel
, ///< [in] mip level
875 UINT_32 numSamples
, ///< [in] number of samples
876 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in,out] Surface output
879 ADDR_TILEINFO
* pTileInfo
= pOut
->pTileInfo
;
881 BOOL_32 valid
= SanityCheckMacroTiled(pTileInfo
);
885 UINT_32 macroTileWidth
;
886 UINT_32 macroTileHeight
;
889 UINT_32 bankHeightAlign
;
890 UINT_32 macroAspectAlign
;
892 UINT_32 thickness
= Thickness(tileMode
);
893 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
896 // Align bank height first according to latest h/w spec
899 // tile_size = MIN(tile_split, 64 * tile_thickness * element_bytes * num_samples)
900 tileSize
= Min(pTileInfo
->tileSplitBytes
,
901 BITS_TO_BYTES(64 * thickness
* bpp
* numSamples
));
903 // bank_height_align =
904 // MAX(1, (pipe_interleave_bytes * bank_interleave)/(tile_size*bank_width))
905 bankHeightAlign
= Max(1u,
906 m_pipeInterleaveBytes
* m_bankInterleave
/
907 (tileSize
* pTileInfo
->bankWidth
)
910 pTileInfo
->bankHeight
= PowTwoAlign(pTileInfo
->bankHeight
, bankHeightAlign
);
912 // num_pipes * bank_width * macro_tile_aspect >=
913 // (pipe_interleave_size * bank_interleave) / tile_size
916 // this restriction is only for mipmap (mipmap's numSamples must be 1)
917 macroAspectAlign
= Max(1u,
918 m_pipeInterleaveBytes
* m_bankInterleave
/
919 (tileSize
* pipes
* pTileInfo
->bankWidth
)
921 pTileInfo
->macroAspectRatio
= PowTwoAlign(pTileInfo
->macroAspectRatio
, macroAspectAlign
);
924 valid
= HwlReduceBankWidthHeight(tileSize
,
933 // The required granularity for pitch is the macro tile width.
935 macroTileWidth
= MicroTileWidth
* pTileInfo
->bankWidth
* pipes
*
936 pTileInfo
->macroAspectRatio
;
938 pOut
->pitchAlign
= macroTileWidth
;
939 pOut
->blockWidth
= macroTileWidth
;
941 AdjustPitchAlignment(flags
, &pOut
->pitchAlign
);
944 // The required granularity for height is the macro tile height.
946 macroTileHeight
= MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
/
947 pTileInfo
->macroAspectRatio
;
949 pOut
->heightAlign
= macroTileHeight
;
950 pOut
->blockHeight
= macroTileHeight
;
953 // Compute base alignment
956 pipes
* pTileInfo
->bankWidth
* pTileInfo
->banks
* pTileInfo
->bankHeight
* tileSize
;
958 HwlComputeSurfaceAlignmentsMacroTiled(tileMode
, bpp
, flags
, mipLevel
, numSamples
, pOut
);
965 ****************************************************************************************************
966 * EgBasedLib::SanityCheckMacroTiled
969 * Check if macro-tiled parameters are valid
972 ****************************************************************************************************
974 BOOL_32
EgBasedLib::SanityCheckMacroTiled(
975 ADDR_TILEINFO
* pTileInfo
///< [in] macro-tiled parameters
978 BOOL_32 valid
= TRUE
;
979 MAYBE_UNUSED UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
981 switch (pTileInfo
->banks
)
983 case 2: //fall through
984 case 4: //fall through
985 case 8: //fall through
996 switch (pTileInfo
->bankWidth
)
998 case 1: //fall through
999 case 2: //fall through
1000 case 4: //fall through
1011 switch (pTileInfo
->bankHeight
)
1013 case 1: //fall through
1014 case 2: //fall through
1015 case 4: //fall through
1026 switch (pTileInfo
->macroAspectRatio
)
1028 case 1: //fall through
1029 case 2: //fall through
1030 case 4: //fall through
1041 if (pTileInfo
->banks
< pTileInfo
->macroAspectRatio
)
1043 // This will generate macro tile height <= 1
1050 if (pTileInfo
->tileSplitBytes
> m_rowSize
)
1052 ADDR_WARN(0, ("tileSplitBytes is bigger than row size"));
1058 valid
= HwlSanityCheckMacroTiled(pTileInfo
);
1061 ADDR_ASSERT(valid
== TRUE
);
1063 // Add this assert for guidance
1064 ADDR_ASSERT(numPipes
* pTileInfo
->banks
>= 4);
1070 ****************************************************************************************************
1071 * EgBasedLib::ComputeSurfaceMipLevelTileMode
1074 * Compute valid tile mode for surface mipmap sub-levels
1077 * Suitable tile mode
1078 ****************************************************************************************************
1080 AddrTileMode
EgBasedLib::ComputeSurfaceMipLevelTileMode(
1081 AddrTileMode baseTileMode
, ///< [in] base tile mode
1082 UINT_32 bpp
, ///< [in] bits per pixels
1083 UINT_32 pitch
, ///< [in] current level pitch
1084 UINT_32 height
, ///< [in] current level height
1085 UINT_32 numSlices
, ///< [in] current number of slices
1086 UINT_32 numSamples
, ///< [in] number of samples
1087 UINT_32 pitchAlign
, ///< [in] pitch alignment
1088 UINT_32 heightAlign
, ///< [in] height alignment
1089 ADDR_TILEINFO
* pTileInfo
///< [in] ptr to bank structure
1092 UINT_64 bytesPerSlice
;
1093 (void)bytesPerSlice
;
1094 UINT_32 bytesPerTile
;
1096 AddrTileMode expTileMode
= baseTileMode
;
1097 UINT_32 microTileThickness
= Thickness(expTileMode
);
1098 UINT_32 interleaveSize
= m_pipeInterleaveBytes
* m_bankInterleave
;
1101 // Compute the size of a slice.
1103 bytesPerSlice
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
1104 bytesPerTile
= BITS_TO_BYTES(MicroTilePixels
* microTileThickness
* NextPow2(bpp
) * numSamples
);
1107 // Reduce tiling mode from thick to thin if the number of slices is less than the
1108 // micro tile thickness.
1110 if (numSlices
< microTileThickness
)
1112 expTileMode
= HwlDegradeThickTileMode(expTileMode
, numSlices
, &bytesPerTile
);
1115 if (bytesPerTile
> pTileInfo
->tileSplitBytes
)
1117 bytesPerTile
= pTileInfo
->tileSplitBytes
;
1120 UINT_32 threshold1
=
1121 bytesPerTile
* HwlGetPipes(pTileInfo
) * pTileInfo
->bankWidth
* pTileInfo
->macroAspectRatio
;
1123 UINT_32 threshold2
=
1124 bytesPerTile
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
;
1127 // Reduce the tile mode from 2D/3D to 1D in following conditions
1129 switch (expTileMode
)
1131 case ADDR_TM_2D_TILED_THIN1
: //fall through
1132 case ADDR_TM_3D_TILED_THIN1
:
1133 case ADDR_TM_PRT_TILED_THIN1
:
1134 case ADDR_TM_PRT_2D_TILED_THIN1
:
1135 case ADDR_TM_PRT_3D_TILED_THIN1
:
1136 if ((pitch
< pitchAlign
) ||
1137 (height
< heightAlign
) ||
1138 (interleaveSize
> threshold1
) ||
1139 (interleaveSize
> threshold2
))
1141 expTileMode
= ADDR_TM_1D_TILED_THIN1
;
1144 case ADDR_TM_2D_TILED_THICK
: //fall through
1145 case ADDR_TM_3D_TILED_THICK
:
1146 case ADDR_TM_2D_TILED_XTHICK
:
1147 case ADDR_TM_3D_TILED_XTHICK
:
1148 case ADDR_TM_PRT_TILED_THICK
:
1149 case ADDR_TM_PRT_2D_TILED_THICK
:
1150 case ADDR_TM_PRT_3D_TILED_THICK
:
1151 if ((pitch
< pitchAlign
) ||
1152 (height
< heightAlign
))
1154 expTileMode
= ADDR_TM_1D_TILED_THICK
;
1165 ****************************************************************************************************
1166 * EgBasedLib::HwlGetAlignmentInfoMacroTiled
1168 * Get alignment info for giving tile mode
1170 * TRUE if getting alignment is OK
1171 ****************************************************************************************************
1173 BOOL_32
EgBasedLib::HwlGetAlignmentInfoMacroTiled(
1174 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] create surface info
1175 UINT_32
* pPitchAlign
, ///< [out] pitch alignment
1176 UINT_32
* pHeightAlign
, ///< [out] height alignment
1177 UINT_32
* pSizeAlign
///< [out] size alignment
1180 BOOL_32 valid
= TRUE
;
1182 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
1184 UINT_32 numSamples
= (pIn
->numFrags
== 0) ? pIn
->numSamples
: pIn
->numFrags
;
1186 ADDR_ASSERT(pIn
->pTileInfo
);
1187 ADDR_TILEINFO tileInfo
= *pIn
->pTileInfo
;
1188 ADDR_COMPUTE_SURFACE_INFO_OUTPUT out
= {0};
1189 out
.pTileInfo
= &tileInfo
;
1191 if (UseTileIndex(pIn
->tileIndex
))
1193 out
.tileIndex
= pIn
->tileIndex
;
1194 out
.macroModeIndex
= TileIndexInvalid
;
1197 HwlSetupTileInfo(pIn
->tileMode
,
1208 valid
= ComputeSurfaceAlignmentsMacroTiled(pIn
->tileMode
,
1217 *pPitchAlign
= out
.pitchAlign
;
1218 *pHeightAlign
= out
.heightAlign
;
1219 *pSizeAlign
= out
.baseAlign
;
1226 ****************************************************************************************************
1227 * EgBasedLib::HwlDegradeThickTileMode
1230 * Degrades valid tile mode for thick modes if needed
1233 * Suitable tile mode
1234 ****************************************************************************************************
1236 AddrTileMode
EgBasedLib::HwlDegradeThickTileMode(
1237 AddrTileMode baseTileMode
, ///< [in] base tile mode
1238 UINT_32 numSlices
, ///< [in] current number of slices
1239 UINT_32
* pBytesPerTile
///< [in,out] pointer to bytes per slice
1242 ADDR_ASSERT(numSlices
< Thickness(baseTileMode
));
1243 // if pBytesPerTile is NULL, this is a don't-care....
1244 UINT_32 bytesPerTile
= pBytesPerTile
!= NULL
? *pBytesPerTile
: 64;
1246 AddrTileMode expTileMode
= baseTileMode
;
1247 switch (baseTileMode
)
1249 case ADDR_TM_1D_TILED_THICK
:
1250 expTileMode
= ADDR_TM_1D_TILED_THIN1
;
1253 case ADDR_TM_2D_TILED_THICK
:
1254 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1257 case ADDR_TM_3D_TILED_THICK
:
1258 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1261 case ADDR_TM_2D_TILED_XTHICK
:
1262 if (numSlices
< ThickTileThickness
)
1264 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1269 expTileMode
= ADDR_TM_2D_TILED_THICK
;
1273 case ADDR_TM_3D_TILED_XTHICK
:
1274 if (numSlices
< ThickTileThickness
)
1276 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1281 expTileMode
= ADDR_TM_3D_TILED_THICK
;
1286 ADDR_ASSERT_ALWAYS();
1290 if (pBytesPerTile
!= NULL
)
1292 *pBytesPerTile
= bytesPerTile
;
1299 ****************************************************************************************************
1300 * EgBasedLib::DispatchComputeSurfaceAddrFromCoord
1303 * Compute surface address from given coord (x, y, slice,sample)
1307 ****************************************************************************************************
1309 UINT_64
EgBasedLib::DispatchComputeSurfaceAddrFromCoord(
1310 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1311 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1316 UINT_32 slice
= pIn
->slice
;
1317 UINT_32 sample
= pIn
->sample
;
1318 UINT_32 bpp
= pIn
->bpp
;
1319 UINT_32 pitch
= pIn
->pitch
;
1320 UINT_32 height
= pIn
->height
;
1321 UINT_32 numSlices
= pIn
->numSlices
;
1322 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
1323 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
1324 AddrTileMode tileMode
= pIn
->tileMode
;
1325 AddrTileType microTileType
= pIn
->tileType
;
1326 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
1327 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
1328 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
1330 UINT_32
* pBitPosition
= &pOut
->bitPosition
;
1333 // ADDR_DEPTH_SAMPLE_ORDER = non-disp + depth-sample-order
1334 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
1336 isDepthSampleOrder
= TRUE
;
1339 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
1341 if (numFrags
!= numSamples
)
1343 numSamples
= numFrags
;
1344 ADDR_ASSERT(sample
< numSamples
);
1348 /// 128 bit/thick tiled surface doesn't support display tiling and
1349 /// mipmap chain must have the same tileType, so please fill tileType correctly
1350 if (IsLinear(pIn
->tileMode
) == FALSE
)
1352 if (bpp
>= 128 || Thickness(tileMode
) > 1)
1354 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
1361 case ADDR_TM_LINEAR_GENERAL
://fall through
1362 case ADDR_TM_LINEAR_ALIGNED
:
1363 addr
= ComputeSurfaceAddrFromCoordLinear(x
,
1373 case ADDR_TM_1D_TILED_THIN1
://fall through
1374 case ADDR_TM_1D_TILED_THICK
:
1375 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
1388 case ADDR_TM_2D_TILED_THIN1
: //fall through
1389 case ADDR_TM_2D_TILED_THICK
: //fall through
1390 case ADDR_TM_3D_TILED_THIN1
: //fall through
1391 case ADDR_TM_3D_TILED_THICK
: //fall through
1392 case ADDR_TM_2D_TILED_XTHICK
: //fall through
1393 case ADDR_TM_3D_TILED_XTHICK
: //fall through
1394 case ADDR_TM_PRT_TILED_THIN1
: //fall through
1395 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
1396 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
1397 case ADDR_TM_PRT_TILED_THICK
: //fall through
1398 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
1399 case ADDR_TM_PRT_3D_TILED_THICK
:
1400 UINT_32 pipeSwizzle
;
1401 UINT_32 bankSwizzle
;
1403 if (m_configFlags
.useCombinedSwizzle
)
1405 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
1406 &bankSwizzle
, &pipeSwizzle
);
1410 pipeSwizzle
= pIn
->pipeSwizzle
;
1411 bankSwizzle
= pIn
->bankSwizzle
;
1414 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
1433 ADDR_ASSERT_ALWAYS();
1441 ****************************************************************************************************
1442 * EgBasedLib::ComputeMacroTileEquation
1445 * Computes the address equation in macro tile
1447 * If equation can be computed
1448 ****************************************************************************************************
1450 ADDR_E_RETURNCODE
EgBasedLib::ComputeMacroTileEquation(
1451 UINT_32 log2BytesPP
, ///< [in] log2 of bytes per pixel
1452 AddrTileMode tileMode
, ///< [in] tile mode
1453 AddrTileType microTileType
, ///< [in] micro tiling type
1454 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure
1455 ADDR_EQUATION
* pEquation
///< [out] Equation for addressing in macro tile
1458 ADDR_E_RETURNCODE retCode
;
1460 // Element equation within a tile
1461 retCode
= ComputeMicroTileEquation(log2BytesPP
, tileMode
, microTileType
, pEquation
);
1463 if (retCode
== ADDR_OK
)
1465 // Tile equesiton with signle pipe bank
1466 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1467 UINT_32 numPipeBits
= Log2(numPipes
);
1469 for (UINT_32 i
= 0; i
< Log2(pTileInfo
->bankWidth
); i
++)
1471 pEquation
->addr
[pEquation
->numBits
].valid
= 1;
1472 pEquation
->addr
[pEquation
->numBits
].channel
= 0;
1473 pEquation
->addr
[pEquation
->numBits
].index
= i
+ log2BytesPP
+ 3 + numPipeBits
;
1474 pEquation
->numBits
++;
1477 for (UINT_32 i
= 0; i
< Log2(pTileInfo
->bankHeight
); i
++)
1479 pEquation
->addr
[pEquation
->numBits
].valid
= 1;
1480 pEquation
->addr
[pEquation
->numBits
].channel
= 1;
1481 pEquation
->addr
[pEquation
->numBits
].index
= i
+ 3;
1482 pEquation
->numBits
++;
1485 ADDR_EQUATION equation
;
1486 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
1488 UINT_32 thresholdX
= 32;
1489 UINT_32 thresholdY
= 32;
1491 if (IsPrtNoRotationTileMode(tileMode
))
1493 UINT_32 macroTilePitch
=
1494 (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
) * pTileInfo
->macroAspectRatio
;
1495 UINT_32 macroTileHeight
=
1496 (MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
) /
1497 pTileInfo
->macroAspectRatio
;
1498 thresholdX
= Log2(macroTilePitch
);
1499 thresholdY
= Log2(macroTileHeight
);
1503 retCode
= ComputePipeEquation(log2BytesPP
, thresholdX
, thresholdY
, pTileInfo
, &equation
);
1505 if (retCode
== ADDR_OK
)
1507 UINT_32 pipeBitStart
= Log2(m_pipeInterleaveBytes
);
1509 if (pEquation
->numBits
> pipeBitStart
)
1511 UINT_32 numLeftShift
= pEquation
->numBits
- pipeBitStart
;
1513 for (UINT_32 i
= 0; i
< numLeftShift
; i
++)
1515 pEquation
->addr
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1516 pEquation
->addr
[pEquation
->numBits
- i
- 1];
1517 pEquation
->xor1
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1518 pEquation
->xor1
[pEquation
->numBits
- i
- 1];
1519 pEquation
->xor2
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1520 pEquation
->xor2
[pEquation
->numBits
- i
- 1];
1524 for (UINT_32 i
= 0; i
< equation
.numBits
; i
++)
1526 pEquation
->addr
[pipeBitStart
+ i
] = equation
.addr
[i
];
1527 pEquation
->xor1
[pipeBitStart
+ i
] = equation
.xor1
[i
];
1528 pEquation
->xor2
[pipeBitStart
+ i
] = equation
.xor2
[i
];
1529 pEquation
->numBits
++;
1533 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
1535 retCode
= ComputeBankEquation(log2BytesPP
, thresholdX
, thresholdY
,
1536 pTileInfo
, &equation
);
1538 if (retCode
== ADDR_OK
)
1540 UINT_32 bankBitStart
= pipeBitStart
+ numPipeBits
+ Log2(m_bankInterleave
);
1542 if (pEquation
->numBits
> bankBitStart
)
1544 UINT_32 numLeftShift
= pEquation
->numBits
- bankBitStart
;
1546 for (UINT_32 i
= 0; i
< numLeftShift
; i
++)
1548 pEquation
->addr
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1549 pEquation
->addr
[pEquation
->numBits
- i
- 1];
1550 pEquation
->xor1
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1551 pEquation
->xor1
[pEquation
->numBits
- i
- 1];
1552 pEquation
->xor2
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1553 pEquation
->xor2
[pEquation
->numBits
- i
- 1];
1557 for (UINT_32 i
= 0; i
< equation
.numBits
; i
++)
1559 pEquation
->addr
[bankBitStart
+ i
] = equation
.addr
[i
];
1560 pEquation
->xor1
[bankBitStart
+ i
] = equation
.xor1
[i
];
1561 pEquation
->xor2
[bankBitStart
+ i
] = equation
.xor2
[i
];
1562 pEquation
->numBits
++;
1572 ****************************************************************************************************
1573 * EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1576 * Computes the surface address and bit position from a
1577 * coordinate for 2D tilied (macro tiled)
1580 ****************************************************************************************************
1582 UINT_64
EgBasedLib::ComputeSurfaceAddrFromCoordMacroTiled(
1583 UINT_32 x
, ///< [in] x coordinate
1584 UINT_32 y
, ///< [in] y coordinate
1585 UINT_32 slice
, ///< [in] slice index
1586 UINT_32 sample
, ///< [in] sample index
1587 UINT_32 bpp
, ///< [in] bits per pixel
1588 UINT_32 pitch
, ///< [in] surface pitch, in pixels
1589 UINT_32 height
, ///< [in] surface height, in pixels
1590 UINT_32 numSamples
, ///< [in] number of samples
1591 AddrTileMode tileMode
, ///< [in] tile mode
1592 AddrTileType microTileType
, ///< [in] micro tiling type
1593 BOOL_32 ignoreSE
, ///< [in] TRUE if shader enginers can be ignored
1594 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if it depth sample ordering is used
1595 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
1596 UINT_32 bankSwizzle
, ///< [in] bank swizzle
1597 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure
1598 /// **All fields to be valid on entry**
1599 UINT_32
* pBitPosition
///< [out] bit position, e.g. FMT_1 will use this
1604 UINT_32 microTileBytes
;
1605 UINT_32 microTileBits
;
1606 UINT_32 sampleOffset
;
1608 UINT_32 pixelOffset
;
1609 UINT_32 elementOffset
;
1610 UINT_32 tileSplitSlice
;
1614 UINT_64 sliceOffset
;
1615 UINT_32 macroTilePitch
;
1616 UINT_32 macroTileHeight
;
1617 UINT_32 macroTilesPerRow
;
1618 UINT_32 macroTilesPerSlice
;
1619 UINT_64 macroTileBytes
;
1620 UINT_32 macroTileIndexX
;
1621 UINT_32 macroTileIndexY
;
1622 UINT_64 macroTileOffset
;
1623 UINT_64 totalOffset
;
1624 UINT_64 pipeInterleaveMask
;
1625 UINT_64 bankInterleaveMask
;
1626 UINT_64 pipeInterleaveOffset
;
1627 UINT_32 bankInterleaveOffset
;
1629 UINT_32 tileRowIndex
;
1630 UINT_32 tileColumnIndex
;
1634 UINT_32 microTileThickness
= Thickness(tileMode
);
1637 // Compute the number of group, pipe, and bank bits.
1639 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1640 UINT_32 numPipeInterleaveBits
= Log2(m_pipeInterleaveBytes
);
1641 UINT_32 numPipeBits
= Log2(numPipes
);
1642 UINT_32 numBankInterleaveBits
= Log2(m_bankInterleave
);
1643 UINT_32 numBankBits
= Log2(pTileInfo
->banks
);
1646 // Compute the micro tile size.
1648 microTileBits
= MicroTilePixels
* microTileThickness
* bpp
* numSamples
;
1650 microTileBytes
= microTileBits
/ 8;
1652 // Compute the pixel index within the micro tile.
1654 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
1662 // Compute the sample offset and pixel offset.
1664 if (isDepthSampleOrder
)
1667 // For depth surfaces, samples are stored contiguously for each element, so the sample
1668 // offset is the sample number times the element size.
1670 sampleOffset
= sample
* bpp
;
1671 pixelOffset
= pixelIndex
* bpp
* numSamples
;
1676 // For color surfaces, all elements for a particular sample are stored contiguously, so
1677 // the sample offset is the sample number times the micro tile size divided yBit the number
1680 sampleOffset
= sample
* (microTileBits
/ numSamples
);
1681 pixelOffset
= pixelIndex
* bpp
;
1685 // Compute the element offset.
1687 elementOffset
= pixelOffset
+ sampleOffset
;
1689 *pBitPosition
= static_cast<UINT_32
>(elementOffset
% 8);
1691 elementOffset
/= 8; //bit-to-byte
1694 // Determine if tiles need to be split across slices.
1696 // If the size of the micro tile is larger than the tile split size, then the tile will be
1697 // split across multiple slices.
1699 UINT_32 slicesPerTile
= 1;
1701 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
1702 { //don't support for thick mode
1705 // Compute the number of slices per tile.
1707 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
1710 // Compute the tile split slice number for use in rotating the bank.
1712 tileSplitSlice
= elementOffset
/ pTileInfo
->tileSplitBytes
;
1715 // Adjust the element offset to account for the portion of the tile that is being moved to
1718 elementOffset
%= pTileInfo
->tileSplitBytes
;
1721 // Adjust the microTileBytes size to tileSplitBytes size since
1724 microTileBytes
= pTileInfo
->tileSplitBytes
;
1732 // Compute macro tile pitch and height.
1735 (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
) * pTileInfo
->macroAspectRatio
;
1737 (MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
) / pTileInfo
->macroAspectRatio
;
1740 // Compute the number of bytes per macro tile. Note: bytes of the same bank/pipe actually
1743 static_cast<UINT_64
>(microTileBytes
) *
1744 (macroTilePitch
/ MicroTileWidth
) * (macroTileHeight
/ MicroTileHeight
) /
1745 (numPipes
* pTileInfo
->banks
);
1748 // Compute the number of macro tiles per row.
1750 macroTilesPerRow
= pitch
/ macroTilePitch
;
1753 // Compute the offset to the macro tile containing the specified coordinate.
1755 macroTileIndexX
= x
/ macroTilePitch
;
1756 macroTileIndexY
= y
/ macroTileHeight
;
1757 macroTileOffset
= ((macroTileIndexY
* macroTilesPerRow
) + macroTileIndexX
) * macroTileBytes
;
1760 // Compute the number of macro tiles per slice.
1762 macroTilesPerSlice
= macroTilesPerRow
* (height
/ macroTileHeight
);
1765 // Compute the slice size.
1767 sliceBytes
= macroTilesPerSlice
* macroTileBytes
;
1770 // Compute the slice offset.
1772 sliceOffset
= sliceBytes
* (tileSplitSlice
+ slicesPerTile
* (slice
/ microTileThickness
));
1775 // Compute tile offest
1777 tileRowIndex
= (y
/ MicroTileHeight
) % pTileInfo
->bankHeight
;
1778 tileColumnIndex
= ((x
/ MicroTileWidth
) / numPipes
) % pTileInfo
->bankWidth
;
1779 tileIndex
= (tileRowIndex
* pTileInfo
->bankWidth
) + tileColumnIndex
;
1780 tileOffset
= tileIndex
* microTileBytes
;
1783 // Combine the slice offset and macro tile offset with the pixel and sample offsets, accounting
1784 // for the pipe and bank bits in the middle of the address.
1786 totalOffset
= sliceOffset
+ macroTileOffset
+ elementOffset
+ tileOffset
;
1789 // Get the pipe and bank.
1792 // when the tileMode is PRT type, then adjust x and y coordinates
1793 if (IsPrtNoRotationTileMode(tileMode
))
1795 x
= x
% macroTilePitch
;
1796 y
= y
% macroTileHeight
;
1799 pipe
= ComputePipeFromCoord(x
,
1807 bank
= ComputeBankFromCoord(x
,
1816 // Split the offset to put some bits below the pipe+bank bits and some above.
1818 pipeInterleaveMask
= (1 << numPipeInterleaveBits
) - 1;
1819 bankInterleaveMask
= (1 << numBankInterleaveBits
) - 1;
1820 pipeInterleaveOffset
= totalOffset
& pipeInterleaveMask
;
1821 bankInterleaveOffset
= static_cast<UINT_32
>((totalOffset
>> numPipeInterleaveBits
) &
1822 bankInterleaveMask
);
1823 offset
= totalOffset
>> (numPipeInterleaveBits
+ numBankInterleaveBits
);
1826 // Assemble the address from its components.
1828 addr
= pipeInterleaveOffset
;
1829 // This is to remove /analyze warnings
1830 UINT_32 pipeBits
= pipe
<< numPipeInterleaveBits
;
1831 UINT_32 bankInterleaveBits
= bankInterleaveOffset
<< (numPipeInterleaveBits
+ numPipeBits
);
1832 UINT_32 bankBits
= bank
<< (numPipeInterleaveBits
+ numPipeBits
+
1833 numBankInterleaveBits
);
1834 UINT_64 offsetBits
= offset
<< (numPipeInterleaveBits
+ numPipeBits
+
1835 numBankInterleaveBits
+ numBankBits
);
1838 addr
|= bankInterleaveBits
;
1846 ****************************************************************************************************
1847 * EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1850 * Computes the surface address and bit position from a coordinate for 1D tilied
1854 ****************************************************************************************************
1856 UINT_64
EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled(
1857 UINT_32 x
, ///< [in] x coordinate
1858 UINT_32 y
, ///< [in] y coordinate
1859 UINT_32 slice
, ///< [in] slice index
1860 UINT_32 sample
, ///< [in] sample index
1861 UINT_32 bpp
, ///< [in] bits per pixel
1862 UINT_32 pitch
, ///< [in] pitch, in pixels
1863 UINT_32 height
, ///< [in] height, in pixels
1864 UINT_32 numSamples
, ///< [in] number of samples
1865 AddrTileMode tileMode
, ///< [in] tile mode
1866 AddrTileType microTileType
, ///< [in] micro tiling type
1867 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if depth sample ordering is used
1868 UINT_32
* pBitPosition
///< [out] bit position, e.g. FMT_1 will use this
1873 UINT_32 microTileBytes
;
1875 UINT_32 microTilesPerRow
;
1876 UINT_32 microTileIndexX
;
1877 UINT_32 microTileIndexY
;
1878 UINT_32 microTileIndexZ
;
1879 UINT_64 sliceOffset
;
1880 UINT_64 microTileOffset
;
1881 UINT_32 sampleOffset
;
1883 UINT_32 pixelOffset
;
1885 UINT_32 microTileThickness
= Thickness(tileMode
);
1888 // Compute the micro tile size.
1890 microTileBytes
= BITS_TO_BYTES(MicroTilePixels
* microTileThickness
* bpp
* numSamples
);
1893 // Compute the slice size.
1896 BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* microTileThickness
* bpp
* numSamples
);
1899 // Compute the number of micro tiles per row.
1901 microTilesPerRow
= pitch
/ MicroTileWidth
;
1904 // Compute the micro tile index.
1906 microTileIndexX
= x
/ MicroTileWidth
;
1907 microTileIndexY
= y
/ MicroTileHeight
;
1908 microTileIndexZ
= slice
/ microTileThickness
;
1911 // Compute the slice offset.
1913 sliceOffset
= static_cast<UINT_64
>(microTileIndexZ
) * sliceBytes
;
1916 // Compute the offset to the micro tile containing the specified coordinate.
1918 microTileOffset
= (static_cast<UINT_64
>(microTileIndexY
) * microTilesPerRow
+ microTileIndexX
) *
1922 // Compute the pixel index within the micro tile.
1924 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
1931 // Compute the sample offset.
1933 if (isDepthSampleOrder
)
1936 // For depth surfaces, samples are stored contiguously for each element, so the sample
1937 // offset is the sample number times the element size.
1939 sampleOffset
= sample
* bpp
;
1940 pixelOffset
= pixelIndex
* bpp
* numSamples
;
1945 // For color surfaces, all elements for a particular sample are stored contiguously, so
1946 // the sample offset is the sample number times the micro tile size divided yBit the number
1949 sampleOffset
= sample
* (microTileBytes
*8 / numSamples
);
1950 pixelOffset
= pixelIndex
* bpp
;
1954 // Compute the bit position of the pixel. Each element is stored with one bit per sample.
1957 UINT_32 elemOffset
= sampleOffset
+ pixelOffset
;
1959 *pBitPosition
= elemOffset
% 8;
1963 // Combine the slice offset, micro tile offset, sample offset, and pixel offsets.
1965 addr
= sliceOffset
+ microTileOffset
+ elemOffset
;
1971 ****************************************************************************************************
1972 * EgBasedLib::HwlComputePixelCoordFromOffset
1975 * Compute pixel coordinate from offset inside a micro tile
1978 ****************************************************************************************************
1980 VOID
EgBasedLib::HwlComputePixelCoordFromOffset(
1981 UINT_32 offset
, ///< [in] offset inside micro tile in bits
1982 UINT_32 bpp
, ///< [in] bits per pixel
1983 UINT_32 numSamples
, ///< [in] number of samples
1984 AddrTileMode tileMode
, ///< [in] tile mode
1985 UINT_32 tileBase
, ///< [in] base offset within a tile
1986 UINT_32 compBits
, ///< [in] component bits actually needed(for planar surface)
1987 UINT_32
* pX
, ///< [out] x coordinate
1988 UINT_32
* pY
, ///< [out] y coordinate
1989 UINT_32
* pSlice
, ///< [out] slice index
1990 UINT_32
* pSample
, ///< [out] sample index
1991 AddrTileType microTileType
, ///< [in] micro tiling type
1992 BOOL_32 isDepthSampleOrder
///< [in] TRUE if depth sample order in microtile is used
1998 UINT_32 thickness
= Thickness(tileMode
);
2000 // For planar surface, we adjust offset acoording to tile base
2001 if ((bpp
!= compBits
) && (compBits
!= 0) && isDepthSampleOrder
)
2005 ADDR_ASSERT(microTileType
== ADDR_NON_DISPLAYABLE
||
2006 microTileType
== ADDR_DEPTH_SAMPLE_ORDER
);
2011 UINT_32 sampleTileBits
;
2012 UINT_32 samplePixelBits
;
2015 if (isDepthSampleOrder
)
2017 samplePixelBits
= bpp
* numSamples
;
2018 pixelIndex
= offset
/ samplePixelBits
;
2019 *pSample
= (offset
% samplePixelBits
) / bpp
;
2023 sampleTileBits
= MicroTilePixels
* bpp
* thickness
;
2024 *pSample
= offset
/ sampleTileBits
;
2025 pixelIndex
= (offset
% sampleTileBits
) / bpp
;
2028 if (microTileType
!= ADDR_THICK
)
2030 if (microTileType
== ADDR_DISPLAYABLE
) // displayable
2035 x
= pixelIndex
& 0x7;
2036 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,4));
2039 x
= pixelIndex
& 0x7;
2040 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,3));
2043 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,1),_BIT(pixelIndex
,0));
2044 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,2));
2047 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2048 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
2051 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,2),_BIT(pixelIndex
,1));
2052 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,0));
2058 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2060 x
= Bits2Number(3, _BIT(pixelIndex
,4),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2061 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
2063 else if (microTileType
== ADDR_ROTATED
)
2067 element_index[5:0] = { x[2], x[0], x[1], y[2], y[1], y[0] }
2070 element_index[5:0] = { x[2], x[1], x[0], y[2], y[1], y[0] }
2073 element_index[5:0] = { x[2], x[1], y[2], x[0], y[1], y[0] }
2076 element_index[5:0] = { y[2], x[2], x[1], y[1], x[0], y[0] }
2081 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,4));
2082 y
= pixelIndex
& 0x7;
2085 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,3));
2086 y
= pixelIndex
& 0x7;
2089 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,2));
2090 y
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,1),_BIT(pixelIndex
,0));
2093 x
= Bits2Number(3, _BIT(pixelIndex
,4),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
2094 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2097 ADDR_ASSERT_ALWAYS();
2102 if (thickness
> 1) // thick
2104 z
= Bits2Number(3, _BIT(pixelIndex
,8),_BIT(pixelIndex
,7),_BIT(pixelIndex
,6));
2109 ADDR_ASSERT((m_chipFamily
>= ADDR_CHIP_FAMILY_CI
) && (thickness
> 1));
2111 8-Bit Elements and 16-Bit Elements
2112 element_index[7:0] = { y[2], x[2], z[1], z[0], y[1], x[1], y[0], x[0] }
2115 element_index[7:0] = { y[2], x[2], z[1], y[1], z[0], x[1], y[0], x[0] }
2117 64-Bit Elements and 128-Bit Elements
2118 element_index[7:0] = { y[2], x[2], z[1], y[1], x[1], z[0], y[0], x[0] }
2120 The equation to compute the element index for the extra thick tile:
2121 element_index[8] = z[2]
2126 case 16: // fall-through
2127 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2128 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
2129 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4));
2132 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2133 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
2134 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3));
2137 case 128: // fall-through
2138 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,3),_BIT(pixelIndex
,0));
2139 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
2140 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,2));
2143 ADDR_ASSERT_ALWAYS();
2149 z
+= Bits2Number(3,_BIT(pixelIndex
,8),0,0);
2159 ****************************************************************************************************
2160 * EgBasedLib::DispatchComputeSurfaceCoordFromAddrDispatch
2163 * Compute (x,y,slice,sample) coordinates from surface address
2166 ****************************************************************************************************
2168 VOID
EgBasedLib::DispatchComputeSurfaceCoordFromAddr(
2169 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
2170 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
2173 UINT_64 addr
= pIn
->addr
;
2174 UINT_32 bitPosition
= pIn
->bitPosition
;
2175 UINT_32 bpp
= pIn
->bpp
;
2176 UINT_32 pitch
= pIn
->pitch
;
2177 UINT_32 height
= pIn
->height
;
2178 UINT_32 numSlices
= pIn
->numSlices
;
2179 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
2180 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
2181 AddrTileMode tileMode
= pIn
->tileMode
;
2182 UINT_32 tileBase
= pIn
->tileBase
;
2183 UINT_32 compBits
= pIn
->compBits
;
2184 AddrTileType microTileType
= pIn
->tileType
;
2185 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
2186 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
2187 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2189 UINT_32
* pX
= &pOut
->x
;
2190 UINT_32
* pY
= &pOut
->y
;
2191 UINT_32
* pSlice
= &pOut
->slice
;
2192 UINT_32
* pSample
= &pOut
->sample
;
2194 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2196 isDepthSampleOrder
= TRUE
;
2199 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
2201 if (numFrags
!= numSamples
)
2203 numSamples
= numFrags
;
2207 /// 128 bit/thick tiled surface doesn't support display tiling and
2208 /// mipmap chain must have the same tileType, so please fill tileType correctly
2209 if (IsLinear(pIn
->tileMode
) == FALSE
)
2211 if (bpp
>= 128 || Thickness(tileMode
) > 1)
2213 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
2220 case ADDR_TM_LINEAR_GENERAL
://fall through
2221 case ADDR_TM_LINEAR_ALIGNED
:
2222 ComputeSurfaceCoordFromAddrLinear(addr
,
2233 case ADDR_TM_1D_TILED_THIN1
://fall through
2234 case ADDR_TM_1D_TILED_THICK
:
2235 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
2249 isDepthSampleOrder
);
2251 case ADDR_TM_2D_TILED_THIN1
: //fall through
2252 case ADDR_TM_2D_TILED_THICK
: //fall through
2253 case ADDR_TM_3D_TILED_THIN1
: //fall through
2254 case ADDR_TM_3D_TILED_THICK
: //fall through
2255 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2256 case ADDR_TM_3D_TILED_XTHICK
: //fall through
2257 case ADDR_TM_PRT_TILED_THIN1
: //fall through
2258 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
2259 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
2260 case ADDR_TM_PRT_TILED_THICK
: //fall through
2261 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
2262 case ADDR_TM_PRT_3D_TILED_THICK
:
2263 UINT_32 pipeSwizzle
;
2264 UINT_32 bankSwizzle
;
2266 if (m_configFlags
.useCombinedSwizzle
)
2268 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
2269 &bankSwizzle
, &pipeSwizzle
);
2273 pipeSwizzle
= pIn
->pipeSwizzle
;
2274 bankSwizzle
= pIn
->bankSwizzle
;
2277 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
2298 ADDR_ASSERT_ALWAYS();
2303 ****************************************************************************************************
2304 * EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled
2307 * Compute surface coordinates from address for macro tiled surface
2310 ****************************************************************************************************
2312 VOID
EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled(
2313 UINT_64 addr
, ///< [in] byte address
2314 UINT_32 bitPosition
, ///< [in] bit position
2315 UINT_32 bpp
, ///< [in] bits per pixel
2316 UINT_32 pitch
, ///< [in] pitch in pixels
2317 UINT_32 height
, ///< [in] height in pixels
2318 UINT_32 numSamples
, ///< [in] number of samples
2319 AddrTileMode tileMode
, ///< [in] tile mode
2320 UINT_32 tileBase
, ///< [in] tile base offset
2321 UINT_32 compBits
, ///< [in] component bits (for planar surface)
2322 AddrTileType microTileType
, ///< [in] micro tiling type
2323 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines can be ignored
2324 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if depth sample order is used
2325 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2326 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2327 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure.
2328 /// **All fields to be valid on entry**
2329 UINT_32
* pX
, ///< [out] X coord
2330 UINT_32
* pY
, ///< [out] Y coord
2331 UINT_32
* pSlice
, ///< [out] slice index
2332 UINT_32
* pSample
///< [out] sample index
2338 UINT_64 macroTileBits
;
2341 UINT_64 elementOffset
;
2342 UINT_64 macroTileIndex
;
2344 UINT_64 totalOffset
;
2348 UINT_32 groupBits
= m_pipeInterleaveBytes
<< 3;
2349 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2350 UINT_32 banks
= pTileInfo
->banks
;
2352 UINT_32 bankInterleave
= m_bankInterleave
;
2354 UINT_64 addrBits
= BYTES_TO_BITS(addr
) + bitPosition
;
2357 // remove bits for bank and pipe
2359 totalOffset
= (addrBits
% groupBits
) +
2360 (((addrBits
/ groupBits
/ pipes
) % bankInterleave
) * groupBits
) +
2361 (((addrBits
/ groupBits
/ pipes
) / bankInterleave
) / banks
) * groupBits
* bankInterleave
;
2363 UINT_32 microTileThickness
= Thickness(tileMode
);
2365 UINT_32 microTileBits
= bpp
* microTileThickness
* MicroTilePixels
* numSamples
;
2367 UINT_32 microTileBytes
= BITS_TO_BYTES(microTileBits
);
2369 // Determine if tiles need to be split across slices.
2371 // If the size of the micro tile is larger than the tile split size, then the tile will be
2372 // split across multiple slices.
2374 UINT_32 slicesPerTile
= 1; //_State->TileSlices
2376 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
2377 { //don't support for thick mode
2380 // Compute the number of slices per tile.
2382 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
2385 tileBits
= microTileBits
/ slicesPerTile
; // micro tile bits
2387 // in micro tiles because not MicroTileWidth timed.
2388 UINT_32 macroWidth
= pTileInfo
->bankWidth
* pipes
* pTileInfo
->macroAspectRatio
;
2389 // in micro tiles as well
2390 UINT_32 macroHeight
= pTileInfo
->bankHeight
* banks
/ pTileInfo
->macroAspectRatio
;
2392 UINT_32 pitchInMacroTiles
= pitch
/ MicroTileWidth
/ macroWidth
;
2394 macroTileBits
= (macroWidth
* macroHeight
) * tileBits
/ (banks
* pipes
);
2396 macroTileIndex
= totalOffset
/ macroTileBits
;
2398 // pitchMacros * height / heightMacros; macroTilesPerSlice == _State->SliceMacros
2399 UINT_32 macroTilesPerSlice
= (pitch
/ (macroWidth
* MicroTileWidth
)) * height
/
2400 (macroHeight
* MicroTileWidth
);
2402 slices
= static_cast<UINT_32
>(macroTileIndex
/ macroTilesPerSlice
);
2404 *pSlice
= static_cast<UINT_32
>(slices
/ slicesPerTile
* microTileThickness
);
2407 // calculate element offset and x[2:0], y[2:0], z[1:0] for thick
2409 tileSlices
= slices
% slicesPerTile
;
2411 elementOffset
= tileSlices
* tileBits
;
2412 elementOffset
+= totalOffset
% tileBits
;
2416 HwlComputePixelCoordFromOffset(static_cast<UINT_32
>(elementOffset
),
2427 isDepthSampleOrder
);
2429 macroTileIndex
= macroTileIndex
% macroTilesPerSlice
;
2430 *pY
+= static_cast<UINT_32
>(macroTileIndex
/ pitchInMacroTiles
* macroHeight
* MicroTileHeight
);
2431 *pX
+= static_cast<UINT_32
>(macroTileIndex
% pitchInMacroTiles
* macroWidth
* MicroTileWidth
);
2435 tileIndex
= static_cast<UINT_32
>((totalOffset
% macroTileBits
) / tileBits
);
2437 my
= (tileIndex
/ pTileInfo
->bankWidth
) % pTileInfo
->bankHeight
* MicroTileHeight
;
2438 mx
= (tileIndex
% pTileInfo
->bankWidth
) * pipes
* MicroTileWidth
;
2443 bank
= ComputeBankFromAddr(addr
, banks
, pipes
);
2444 pipe
= ComputePipeFromAddr(addr
, pipes
);
2446 HwlComputeSurfaceCoord2DFromBankPipe(tileMode
,
2460 ****************************************************************************************************
2461 * EgBasedLib::ComputeSurfaceCoord2DFromBankPipe
2464 * Compute surface x,y coordinates from bank/pipe info
2467 ****************************************************************************************************
2469 VOID
EgBasedLib::ComputeSurfaceCoord2DFromBankPipe(
2470 AddrTileMode tileMode
, ///< [in] tile mode
2471 UINT_32 x
, ///< [in] x coordinate
2472 UINT_32 y
, ///< [in] y coordinate
2473 UINT_32 slice
, ///< [in] slice index
2474 UINT_32 bank
, ///< [in] bank number
2475 UINT_32 pipe
, ///< [in] pipe number
2476 UINT_32 bankSwizzle
,///< [in] bank swizzle
2477 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
2478 UINT_32 tileSlices
, ///< [in] slices in a micro tile
2479 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure. **All fields to be valid on entry**
2480 CoordFromBankPipe
* pOutput
///< [out] pointer to extracted x/y bits
2492 UINT_32 tileSplitRotation
;
2494 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2496 UINT_32 bankRotation
= ComputeBankRotation(tileMode
,
2497 pTileInfo
->banks
, numPipes
);
2499 UINT_32 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2501 UINT_32 xBit
= x
/ (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
);
2502 UINT_32 yBit
= y
/ (MicroTileHeight
* pTileInfo
->bankHeight
);
2504 //calculate the bank and pipe before rotation and swizzle
2508 case ADDR_TM_2D_TILED_THIN1
: //fall through
2509 case ADDR_TM_2D_TILED_THICK
: //fall through
2510 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2511 case ADDR_TM_3D_TILED_THIN1
: //fall through
2512 case ADDR_TM_3D_TILED_THICK
: //fall through
2513 case ADDR_TM_3D_TILED_XTHICK
:
2514 tileSplitRotation
= ((pTileInfo
->banks
/ 2) + 1);
2517 tileSplitRotation
= 0;
2521 UINT_32 microTileThickness
= Thickness(tileMode
);
2523 bank
^= tileSplitRotation
* tileSlices
;
2524 if (pipeRotation
== 0)
2526 bank
^= bankRotation
* (slice
/ microTileThickness
) + bankSwizzle
;
2527 bank
%= pTileInfo
->banks
;
2528 pipe
^= pipeSwizzle
;
2532 bank
^= bankRotation
* (slice
/ microTileThickness
) / numPipes
+ bankSwizzle
;
2533 bank
%= pTileInfo
->banks
;
2534 pipe
^= pipeRotation
* (slice
/ microTileThickness
) + pipeSwizzle
;
2537 if (pTileInfo
->macroAspectRatio
== 1)
2539 switch (pTileInfo
->banks
)
2542 yBit3
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2545 yBit4
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2546 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2549 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2550 yBit5
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2551 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ yBit5
;
2554 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3);
2555 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2);
2556 yBit6
= _BIT(bank
, 0) ^ _BIT(xBit
, 0);
2557 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ yBit6
;
2564 else if (pTileInfo
->macroAspectRatio
== 2)
2566 switch (pTileInfo
->banks
)
2568 case 2: //xBit3 = yBit3^b0
2569 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,0);
2571 case 4: //xBit3=yBit4^b0; yBit3=xBit4^b1
2572 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2573 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2575 case 8: //xBit4, xBit5, yBit5 are known
2576 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2577 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2578 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ _BIT(yBit
, 2);
2580 case 16://x4,x5,x6,y6 are known
2581 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3); //x3 = y6 ^ b0
2582 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2583 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = x5 ^ b2
2584 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ _BIT(yBit
, 3); //y5=x4^y6^b1
2590 else if (pTileInfo
->macroAspectRatio
== 4)
2592 switch (pTileInfo
->banks
)
2594 case 4: //yBit3, yBit4
2595 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2596 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,0);
2598 case 8: //xBit5, yBit4, yBit5
2599 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2600 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2601 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
,2);
2603 case 16: //xBit5, xBit6, yBit5, yBit6
2604 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = b0 ^ y6
2605 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = b1 ^ y5 ^ y6;
2606 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = b3 ^ x6;
2607 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = b2 ^ x5;
2613 else if (pTileInfo
->macroAspectRatio
== 8)
2615 switch (pTileInfo
->banks
)
2617 case 8: //yBit3, yBit4, yBit5
2618 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2); //x3 = b0 ^ y5;
2619 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
, 2);//x4 = b1 ^ y4 ^ y5;
2620 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
,0);
2622 case 16: //xBit6, yBit4, yBit5, yBit6
2623 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = y6 ^ b0
2624 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = y5 ^ y6 ^ b1
2625 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
, 1);//x5 = y4 ^ b2
2626 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2633 pOutput
->xBits
= xBit
;
2634 pOutput
->yBits
= yBit
;
2636 pOutput
->xBit3
= xBit3
;
2637 pOutput
->xBit4
= xBit4
;
2638 pOutput
->xBit5
= xBit5
;
2639 pOutput
->yBit3
= yBit3
;
2640 pOutput
->yBit4
= yBit4
;
2641 pOutput
->yBit5
= yBit5
;
2642 pOutput
->yBit6
= yBit6
;
2646 ****************************************************************************************************
2647 * EgBasedLib::HwlExtractBankPipeSwizzle
2649 * Entry of EgBasedLib ExtractBankPipeSwizzle
2652 ****************************************************************************************************
2654 ADDR_E_RETURNCODE
EgBasedLib::HwlExtractBankPipeSwizzle(
2655 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
2656 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
2659 ExtractBankPipeSwizzle(pIn
->base256b
,
2662 &pOut
->pipeSwizzle
);
2668 ****************************************************************************************************
2669 * EgBasedLib::HwlCombineBankPipeSwizzle
2671 * Combine bank/pipe swizzle
2674 ****************************************************************************************************
2676 ADDR_E_RETURNCODE
EgBasedLib::HwlCombineBankPipeSwizzle(
2677 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2678 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2679 ADDR_TILEINFO
* pTileInfo
, ///< [in] tile info
2680 UINT_64 baseAddr
, ///< [in] base address
2681 UINT_32
* pTileSwizzle
///< [out] combined swizzle
2684 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
2688 *pTileSwizzle
= GetBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, baseAddr
, pTileInfo
);
2692 retCode
= ADDR_INVALIDPARAMS
;
2699 ****************************************************************************************************
2700 * EgBasedLib::HwlComputeBaseSwizzle
2702 * Compute base swizzle
2705 ****************************************************************************************************
2707 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeBaseSwizzle(
2708 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT
* pIn
,
2709 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
* pOut
2712 UINT_32 bankSwizzle
= 0;
2713 UINT_32 pipeSwizzle
= 0;
2714 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2716 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
2717 ADDR_ASSERT(pIn
->pTileInfo
);
2719 /// This is a legacy misreading of h/w doc, use it as it doesn't hurt.
2720 static const UINT_8 bankRotationArray
[4][16] = {
2721 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_2_BANK
2722 { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_4_BANK
2723 { 0, 3, 6, 1, 4, 7, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_8_BANK
2724 { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }, // ADDR_SURF_16_BANK
2727 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2729 UINT_32 banks
= pTileInfo
? pTileInfo
->banks
: 2;
2732 // Uses less bank swizzle bits
2733 if (pIn
->option
.reduceBankBit
&& banks
> 2)
2753 ADDR_ASSERT_ALWAYS();
2758 if (pIn
->option
.genOption
== ADDR_SWIZZLE_GEN_LINEAR
)
2760 bankSwizzle
= pIn
->surfIndex
& (banks
- 1);
2762 else // (pIn->option.genOption == ADDR_SWIZZLE_GEN_DEFAULT)
2764 bankSwizzle
= bankRotationArray
[hwNumBanks
][pIn
->surfIndex
& (banks
- 1)];
2767 if (IsMacro3dTiled(pIn
->tileMode
))
2769 pipeSwizzle
= pIn
->surfIndex
& (HwlGetPipes(pTileInfo
) - 1);
2772 return HwlCombineBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, pTileInfo
, 0, &pOut
->tileSwizzle
);
2776 ****************************************************************************************************
2777 * EgBasedLib::ExtractBankPipeSwizzle
2779 * Extract bank/pipe swizzle from base256b
2782 ****************************************************************************************************
2784 VOID
EgBasedLib::ExtractBankPipeSwizzle(
2785 UINT_32 base256b
, ///< [in] input base256b register value
2786 ADDR_TILEINFO
* pTileInfo
, ///< [in] 2D tile parameters. Client must provide all data
2787 UINT_32
* pBankSwizzle
, ///< [out] bank swizzle
2788 UINT_32
* pPipeSwizzle
///< [out] pipe swizzle
2791 UINT_32 bankSwizzle
= 0;
2792 UINT_32 pipeSwizzle
= 0;
2796 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2797 UINT_32 bankBits
= QLog2(pTileInfo
->banks
);
2798 UINT_32 pipeBits
= QLog2(numPipes
);
2799 UINT_32 groupBytes
= m_pipeInterleaveBytes
;
2800 UINT_32 bankInterleave
= m_bankInterleave
;
2803 (base256b
/ (groupBytes
>> 8)) & ((1<<pipeBits
)-1);
2806 (base256b
/ (groupBytes
>> 8) / numPipes
/ bankInterleave
) & ((1 << bankBits
) - 1);
2809 *pPipeSwizzle
= pipeSwizzle
;
2810 *pBankSwizzle
= bankSwizzle
;
2814 ****************************************************************************************************
2815 * EgBasedLib::GetBankPipeSwizzle
2817 * Combine bank/pipe swizzle
2819 * Base256b bits (only filled bank/pipe bits)
2820 ****************************************************************************************************
2822 UINT_32
EgBasedLib::GetBankPipeSwizzle(
2823 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2824 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2825 UINT_64 baseAddr
, ///< [in] base address
2826 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2829 UINT_32 pipeBits
= QLog2(HwlGetPipes(pTileInfo
));
2830 UINT_32 bankInterleaveBits
= QLog2(m_bankInterleave
);
2831 UINT_32 tileSwizzle
= pipeSwizzle
+ ((bankSwizzle
<< bankInterleaveBits
) << pipeBits
);
2833 baseAddr
^= tileSwizzle
* m_pipeInterleaveBytes
;
2836 return static_cast<UINT_32
>(baseAddr
);
2840 ****************************************************************************************************
2841 * EgBasedLib::ComputeSliceTileSwizzle
2843 * Compute cubemap/3d texture faces/slices tile swizzle
2846 ****************************************************************************************************
2848 UINT_32
EgBasedLib::ComputeSliceTileSwizzle(
2849 AddrTileMode tileMode
, ///< [in] Tile mode
2850 UINT_32 baseSwizzle
, ///< [in] Base swizzle
2851 UINT_32 slice
, ///< [in] Slice index, Cubemap face index, 0 means +X
2852 UINT_64 baseAddr
, ///< [in] Base address
2853 ADDR_TILEINFO
* pTileInfo
///< [in] Bank structure
2856 UINT_32 tileSwizzle
= 0;
2858 if (IsMacroTiled(tileMode
)) // Swizzle only for macro tile mode
2860 UINT_32 firstSlice
= slice
/ Thickness(tileMode
);
2862 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2863 UINT_32 numBanks
= pTileInfo
->banks
;
2865 UINT_32 pipeRotation
;
2866 UINT_32 bankRotation
;
2868 UINT_32 bankSwizzle
= 0;
2869 UINT_32 pipeSwizzle
= 0;
2871 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2872 bankRotation
= ComputeBankRotation(tileMode
, numBanks
, numPipes
);
2874 if (baseSwizzle
!= 0)
2876 ExtractBankPipeSwizzle(baseSwizzle
,
2882 if (pipeRotation
== 0) //2D mode
2884 bankSwizzle
+= firstSlice
* bankRotation
;
2885 bankSwizzle
%= numBanks
;
2889 pipeSwizzle
+= firstSlice
* pipeRotation
;
2890 pipeSwizzle
%= numPipes
;
2891 bankSwizzle
+= firstSlice
* bankRotation
/ numPipes
;
2892 bankSwizzle
%= numBanks
;
2895 tileSwizzle
= GetBankPipeSwizzle(bankSwizzle
,
2905 ****************************************************************************************************
2906 * EgBasedLib::HwlComputeQbStereoRightSwizzle
2909 * Compute right eye swizzle
2912 ****************************************************************************************************
2914 UINT_32
EgBasedLib::HwlComputeQbStereoRightSwizzle(
2915 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pInfo
///< [in] Surface info, must be valid
2918 UINT_32 bankBits
= 0;
2919 UINT_32 swizzle
= 0;
2921 // The assumption is default swizzle for left eye is 0
2922 if (IsMacroTiled(pInfo
->tileMode
) && pInfo
->pStereoInfo
&& pInfo
->pTileInfo
)
2924 bankBits
= ComputeBankFromCoord(0, pInfo
->height
, 0,
2925 pInfo
->tileMode
, 0, 0, pInfo
->pTileInfo
);
2929 HwlCombineBankPipeSwizzle(bankBits
, 0, pInfo
->pTileInfo
, 0, &swizzle
);
2937 ****************************************************************************************************
2938 * EgBasedLib::ComputeBankFromCoord
2941 * Compute bank number from coordinates
2944 ****************************************************************************************************
2946 UINT_32
EgBasedLib::ComputeBankFromCoord(
2947 UINT_32 x
, ///< [in] x coordinate
2948 UINT_32 y
, ///< [in] y coordinate
2949 UINT_32 slice
, ///< [in] slice index
2950 AddrTileMode tileMode
, ///< [in] tile mode
2951 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2952 UINT_32 tileSplitSlice
, ///< [in] If the size of the pixel offset is larger than the
2953 /// tile split size, then the pixel will be moved to a separate
2954 /// slice. This value equals pixelOffset / tileSplitBytes
2955 /// in this case. Otherwise this is 0.
2956 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2959 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2960 UINT_32 bankBit0
= 0;
2961 UINT_32 bankBit1
= 0;
2962 UINT_32 bankBit2
= 0;
2963 UINT_32 bankBit3
= 0;
2964 UINT_32 sliceRotation
;
2965 UINT_32 tileSplitRotation
;
2967 UINT_32 numBanks
= pTileInfo
->banks
;
2968 UINT_32 bankWidth
= pTileInfo
->bankWidth
;
2969 UINT_32 bankHeight
= pTileInfo
->bankHeight
;
2971 UINT_32 tx
= x
/ MicroTileWidth
/ (bankWidth
* pipes
);
2972 UINT_32 ty
= y
/ MicroTileHeight
/ bankHeight
;
2974 UINT_32 x3
= _BIT(tx
,0);
2975 UINT_32 x4
= _BIT(tx
,1);
2976 UINT_32 x5
= _BIT(tx
,2);
2977 UINT_32 x6
= _BIT(tx
,3);
2978 UINT_32 y3
= _BIT(ty
,0);
2979 UINT_32 y4
= _BIT(ty
,1);
2980 UINT_32 y5
= _BIT(ty
,2);
2981 UINT_32 y6
= _BIT(ty
,3);
2987 bankBit1
= x4
^ y5
^ y6
;
2993 bankBit1
= x4
^ y4
^ y5
;
3004 ADDR_ASSERT_ALWAYS();
3008 bank
= bankBit0
| (bankBit1
<< 1) | (bankBit2
<< 2) | (bankBit3
<< 3);
3010 //Bits2Number(4, bankBit3, bankBit2, bankBit1, bankBit0);
3012 bank
= HwlPreAdjustBank((x
/ MicroTileWidth
), bank
, pTileInfo
);
3014 // Compute bank rotation for the slice.
3016 UINT_32 microTileThickness
= Thickness(tileMode
);
3020 case ADDR_TM_2D_TILED_THIN1
: // fall through
3021 case ADDR_TM_2D_TILED_THICK
: // fall through
3022 case ADDR_TM_2D_TILED_XTHICK
:
3023 sliceRotation
= ((numBanks
/ 2) - 1) * (slice
/ microTileThickness
);
3025 case ADDR_TM_3D_TILED_THIN1
: // fall through
3026 case ADDR_TM_3D_TILED_THICK
: // fall through
3027 case ADDR_TM_3D_TILED_XTHICK
:
3029 Max(1u, (pipes
/ 2) - 1) * (slice
/ microTileThickness
) / pipes
;
3037 // Compute bank rotation for the tile split slice.
3039 // The sample slice will be non-zero if samples must be split across multiple slices.
3040 // This situation arises when the micro tile size multiplied yBit the number of samples exceeds
3041 // the split size (set in GB_ADDR_CONFIG).
3045 case ADDR_TM_2D_TILED_THIN1
: //fall through
3046 case ADDR_TM_3D_TILED_THIN1
: //fall through
3047 case ADDR_TM_PRT_2D_TILED_THIN1
: //fall through
3048 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
3049 tileSplitRotation
= ((numBanks
/ 2) + 1) * tileSplitSlice
;
3052 tileSplitRotation
= 0;
3057 // Apply bank rotation for the slice and tile split slice.
3059 bank
^= bankSwizzle
+ sliceRotation
;
3060 bank
^= tileSplitRotation
;
3062 bank
&= (numBanks
- 1);
3068 ****************************************************************************************************
3069 * EgBasedLib::ComputeBankFromAddr
3072 * Compute the bank number from an address
3075 ****************************************************************************************************
3077 UINT_32
EgBasedLib::ComputeBankFromAddr(
3078 UINT_64 addr
, ///< [in] address
3079 UINT_32 numBanks
, ///< [in] number of banks
3080 UINT_32 numPipes
///< [in] number of pipes
3086 // The LSBs of the address are arranged as follows:
3087 // bank | bankInterleave | pipe | pipeInterleave
3089 // To get the bank number, shift off the pipe interleave, pipe, and bank interlave bits and
3090 // mask the bank bits.
3092 bank
= static_cast<UINT_32
>(
3093 (addr
>> Log2(m_pipeInterleaveBytes
* numPipes
* m_bankInterleave
)) &
3101 ****************************************************************************************************
3102 * EgBasedLib::ComputePipeRotation
3105 * Compute pipe rotation value
3108 ****************************************************************************************************
3110 UINT_32
EgBasedLib::ComputePipeRotation(
3111 AddrTileMode tileMode
, ///< [in] tile mode
3112 UINT_32 numPipes
///< [in] number of pipes
3119 case ADDR_TM_3D_TILED_THIN1
: //fall through
3120 case ADDR_TM_3D_TILED_THICK
: //fall through
3121 case ADDR_TM_3D_TILED_XTHICK
: //fall through
3122 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
3123 case ADDR_TM_PRT_3D_TILED_THICK
:
3124 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1);
3134 ****************************************************************************************************
3135 * EgBasedLib::ComputeBankRotation
3138 * Compute bank rotation value
3141 ****************************************************************************************************
3143 UINT_32
EgBasedLib::ComputeBankRotation(
3144 AddrTileMode tileMode
, ///< [in] tile mode
3145 UINT_32 numBanks
, ///< [in] number of banks
3146 UINT_32 numPipes
///< [in] number of pipes
3153 case ADDR_TM_2D_TILED_THIN1
: // fall through
3154 case ADDR_TM_2D_TILED_THICK
: // fall through
3155 case ADDR_TM_2D_TILED_XTHICK
:
3156 case ADDR_TM_PRT_2D_TILED_THIN1
:
3157 case ADDR_TM_PRT_2D_TILED_THICK
:
3158 // Rotate banks per Z-slice yBit 1 for 4-bank or 3 for 8-bank
3159 rotation
= numBanks
/ 2 - 1;
3161 case ADDR_TM_3D_TILED_THIN1
: // fall through
3162 case ADDR_TM_3D_TILED_THICK
: // fall through
3163 case ADDR_TM_3D_TILED_XTHICK
:
3164 case ADDR_TM_PRT_3D_TILED_THIN1
:
3165 case ADDR_TM_PRT_3D_TILED_THICK
:
3166 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1); // rotate pipes & banks
3176 ****************************************************************************************************
3177 * EgBasedLib::ComputeHtileBytes
3180 * Compute htile size in bytes
3183 * Htile size in bytes
3184 ****************************************************************************************************
3186 UINT_64
EgBasedLib::ComputeHtileBytes(
3187 UINT_32 pitch
, ///< [in] pitch
3188 UINT_32 height
, ///< [in] height
3189 UINT_32 bpp
, ///< [in] bits per pixel
3190 BOOL_32 isLinear
, ///< [in] if it is linear mode
3191 UINT_32 numSlices
, ///< [in] number of slices
3192 UINT_64
* sliceBytes
, ///< [out] bytes per slice
3193 UINT_32 baseAlign
///< [in] base alignments
3198 const UINT_64 HtileCacheLineSize
= BITS_TO_BYTES(HtileCacheBits
);
3200 *sliceBytes
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
/ 64);
3202 if (m_configFlags
.useHtileSliceAlign
)
3204 // Align the sliceSize to htilecachelinesize * pipes at first
3205 *sliceBytes
= PowTwoAlign(*sliceBytes
, HtileCacheLineSize
* m_pipes
);
3206 surfBytes
= *sliceBytes
* numSlices
;
3210 // Align the surfSize to htilecachelinesize * pipes at last
3211 surfBytes
= *sliceBytes
* numSlices
;
3212 surfBytes
= PowTwoAlign(surfBytes
, HtileCacheLineSize
* m_pipes
);
3219 ****************************************************************************************************
3220 * EgBasedLib::DispatchComputeFmaskInfo
3223 * Compute fmask sizes include padded pitch, height, slices, total size in bytes,
3224 * meanwhile output suitable tile mode and alignments as well. Results are returned
3225 * through output parameters.
3229 ****************************************************************************************************
3231 ADDR_E_RETURNCODE
EgBasedLib::DispatchComputeFmaskInfo(
3232 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3233 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
) ///< [out] output structure
3235 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3237 ADDR_COMPUTE_SURFACE_INFO_INPUT surfIn
= {0};
3238 ADDR_COMPUTE_SURFACE_INFO_OUTPUT surfOut
= {0};
3240 // Setup input structure
3241 surfIn
.tileMode
= pIn
->tileMode
;
3242 surfIn
.width
= pIn
->pitch
;
3243 surfIn
.height
= pIn
->height
;
3244 surfIn
.numSlices
= pIn
->numSlices
;
3245 surfIn
.pTileInfo
= pIn
->pTileInfo
;
3246 surfIn
.tileType
= ADDR_NON_DISPLAYABLE
;
3247 surfIn
.flags
.fmask
= 1;
3249 // Setup output structure
3250 surfOut
.pTileInfo
= pOut
->pTileInfo
;
3252 // Setup hwl specific fields
3253 HwlFmaskPreThunkSurfInfo(pIn
, pOut
, &surfIn
, &surfOut
);
3255 surfIn
.bpp
= HwlComputeFmaskBits(pIn
, &surfIn
.numSamples
);
3257 // ComputeSurfaceInfo needs numSamples in surfOut as surface routines need adjusted numSamples
3258 surfOut
.numSamples
= surfIn
.numSamples
;
3260 retCode
= HwlComputeSurfaceInfo(&surfIn
, &surfOut
);
3262 // Save bpp field for surface dump support
3263 surfOut
.bpp
= surfIn
.bpp
;
3265 if (retCode
== ADDR_OK
)
3267 pOut
->bpp
= surfOut
.bpp
;
3268 pOut
->pitch
= surfOut
.pitch
;
3269 pOut
->height
= surfOut
.height
;
3270 pOut
->numSlices
= surfOut
.depth
;
3271 pOut
->fmaskBytes
= surfOut
.surfSize
;
3272 pOut
->baseAlign
= surfOut
.baseAlign
;
3273 pOut
->pitchAlign
= surfOut
.pitchAlign
;
3274 pOut
->heightAlign
= surfOut
.heightAlign
;
3276 if (surfOut
.depth
> 1)
3278 // For fmask, expNumSlices is stored in depth.
3279 pOut
->sliceSize
= surfOut
.surfSize
/ surfOut
.depth
;
3283 pOut
->sliceSize
= surfOut
.surfSize
;
3286 // Save numSamples field for surface dump support
3287 pOut
->numSamples
= surfOut
.numSamples
;
3289 HwlFmaskPostThunkSurfInfo(&surfOut
, pOut
);
3296 ****************************************************************************************************
3297 * EgBasedLib::HwlFmaskSurfaceInfo
3299 * Entry of EgBasedLib ComputeFmaskInfo
3302 ****************************************************************************************************
3304 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskInfo(
3305 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3306 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
3309 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3311 ADDR_TILEINFO tileInfo
= {0};
3313 // Use internal tile info if pOut does not have a valid pTileInfo
3314 if (pOut
->pTileInfo
== NULL
)
3316 pOut
->pTileInfo
= &tileInfo
;
3319 retCode
= DispatchComputeFmaskInfo(pIn
, pOut
);
3321 if (retCode
== ADDR_OK
)
3324 HwlPostCheckTileIndex(pOut
->pTileInfo
, pIn
->tileMode
, ADDR_NON_DISPLAYABLE
,
3328 // Resets pTileInfo to NULL if the internal tile info is used
3329 if (pOut
->pTileInfo
== &tileInfo
)
3331 pOut
->pTileInfo
= NULL
;
3338 ****************************************************************************************************
3339 * EgBasedLib::HwlComputeFmaskAddrFromCoord
3341 * Entry of EgBasedLib ComputeFmaskAddrFromCoord
3344 ****************************************************************************************************
3346 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskAddrFromCoord(
3347 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3348 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3351 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3357 ****************************************************************************************************
3358 * EgBasedLib::HwlComputeFmaskCoordFromAddr
3360 * Entry of EgBasedLib ComputeFmaskCoordFromAddr
3363 ****************************************************************************************************
3365 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskCoordFromAddr(
3366 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3367 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3370 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3376 ****************************************************************************************************
3377 * EgBasedLib::ComputeFmaskNumPlanesFromNumSamples
3380 * Compute fmask number of planes from number of samples
3384 ****************************************************************************************************
3386 UINT_32
EgBasedLib::ComputeFmaskNumPlanesFromNumSamples(
3387 UINT_32 numSamples
) ///< [in] number of samples
3392 // FMASK is stored such that each micro tile is composed of elements containing N bits, where
3393 // N is the number of samples. There is a micro tile for each bit in the FMASK address, and
3394 // micro tiles for each address bit, sometimes referred to as a plane, are stored sequentially.
3395 // The FMASK for a 2-sample surface looks like a general surface with 2 bits per element.
3396 // The FMASK for a 4-sample surface looks like a general surface with 4 bits per element and
3397 // 2 samples. The FMASK for an 8-sample surface looks like a general surface with 8 bits per
3398 // element and 4 samples. R6xx and R7xx only stored 3 planes for 8-sample FMASK surfaces.
3399 // This was changed for R8xx to simplify the logic in the CB.
3413 ADDR_UNHANDLED_CASE();
3421 ****************************************************************************************************
3422 * EgBasedLib::ComputeFmaskResolvedBppFromNumSamples
3425 * Compute resolved fmask effective bpp based on number of samples
3429 ****************************************************************************************************
3431 UINT_32
EgBasedLib::ComputeFmaskResolvedBppFromNumSamples(
3432 UINT_32 numSamples
) ///< number of samples
3437 // Resolved FMASK surfaces are generated yBit the CB and read yBit the texture unit
3438 // so that the texture unit can read compressed multi-sample color data.
3439 // These surfaces store each index value packed per element.
3440 // Each element contains at least num_samples * log2(num_samples) bits.
3441 // Resolved FMASK surfaces are addressed as follows:
3442 // 2-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3443 // 4-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3444 // 8-sample Addressed similarly to a color surface with 32 bits per element and 1 sample.
3458 ADDR_UNHANDLED_CASE();
3466 ****************************************************************************************************
3467 * EgBasedLib::IsTileInfoAllZero
3470 * Return TRUE if all field are zero
3472 * Since NULL input is consider to be all zero
3473 ****************************************************************************************************
3475 BOOL_32
EgBasedLib::IsTileInfoAllZero(
3476 const ADDR_TILEINFO
* pTileInfo
)
3478 BOOL_32 allZero
= TRUE
;
3482 if ((pTileInfo
->banks
!= 0) ||
3483 (pTileInfo
->bankWidth
!= 0) ||
3484 (pTileInfo
->bankHeight
!= 0) ||
3485 (pTileInfo
->macroAspectRatio
!= 0) ||
3486 (pTileInfo
->tileSplitBytes
!= 0) ||
3487 (pTileInfo
->pipeConfig
!= 0)
3498 ****************************************************************************************************
3499 * EgBasedLib::HwlTileInfoEqual
3502 * Return TRUE if all field are equal
3504 * Only takes care of current HWL's data
3505 ****************************************************************************************************
3507 BOOL_32
EgBasedLib::HwlTileInfoEqual(
3508 const ADDR_TILEINFO
* pLeft
, ///<[in] Left compare operand
3509 const ADDR_TILEINFO
* pRight
///<[in] Right compare operand
3512 BOOL_32 equal
= FALSE
;
3514 if (pLeft
->banks
== pRight
->banks
&&
3515 pLeft
->bankWidth
== pRight
->bankWidth
&&
3516 pLeft
->bankHeight
== pRight
->bankHeight
&&
3517 pLeft
->macroAspectRatio
== pRight
->macroAspectRatio
&&
3518 pLeft
->tileSplitBytes
== pRight
->tileSplitBytes
)
3527 ****************************************************************************************************
3528 * EgBasedLib::HwlConvertTileInfoToHW
3530 * Entry of EgBasedLib ConvertTileInfoToHW
3533 ****************************************************************************************************
3535 ADDR_E_RETURNCODE
EgBasedLib::HwlConvertTileInfoToHW(
3536 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
3537 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
3540 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3542 ADDR_TILEINFO
*pTileInfoIn
= pIn
->pTileInfo
;
3543 ADDR_TILEINFO
*pTileInfoOut
= pOut
->pTileInfo
;
3545 if ((pTileInfoIn
!= NULL
) && (pTileInfoOut
!= NULL
))
3547 if (pIn
->reverse
== FALSE
)
3549 switch (pTileInfoIn
->banks
)
3552 pTileInfoOut
->banks
= 0;
3555 pTileInfoOut
->banks
= 1;
3558 pTileInfoOut
->banks
= 2;
3561 pTileInfoOut
->banks
= 3;
3564 ADDR_ASSERT_ALWAYS();
3565 retCode
= ADDR_INVALIDPARAMS
;
3566 pTileInfoOut
->banks
= 0;
3570 switch (pTileInfoIn
->bankWidth
)
3573 pTileInfoOut
->bankWidth
= 0;
3576 pTileInfoOut
->bankWidth
= 1;
3579 pTileInfoOut
->bankWidth
= 2;
3582 pTileInfoOut
->bankWidth
= 3;
3585 ADDR_ASSERT_ALWAYS();
3586 retCode
= ADDR_INVALIDPARAMS
;
3587 pTileInfoOut
->bankWidth
= 0;
3591 switch (pTileInfoIn
->bankHeight
)
3594 pTileInfoOut
->bankHeight
= 0;
3597 pTileInfoOut
->bankHeight
= 1;
3600 pTileInfoOut
->bankHeight
= 2;
3603 pTileInfoOut
->bankHeight
= 3;
3606 ADDR_ASSERT_ALWAYS();
3607 retCode
= ADDR_INVALIDPARAMS
;
3608 pTileInfoOut
->bankHeight
= 0;
3612 switch (pTileInfoIn
->macroAspectRatio
)
3615 pTileInfoOut
->macroAspectRatio
= 0;
3618 pTileInfoOut
->macroAspectRatio
= 1;
3621 pTileInfoOut
->macroAspectRatio
= 2;
3624 pTileInfoOut
->macroAspectRatio
= 3;
3627 ADDR_ASSERT_ALWAYS();
3628 retCode
= ADDR_INVALIDPARAMS
;
3629 pTileInfoOut
->macroAspectRatio
= 0;
3633 switch (pTileInfoIn
->tileSplitBytes
)
3636 pTileInfoOut
->tileSplitBytes
= 0;
3639 pTileInfoOut
->tileSplitBytes
= 1;
3642 pTileInfoOut
->tileSplitBytes
= 2;
3645 pTileInfoOut
->tileSplitBytes
= 3;
3648 pTileInfoOut
->tileSplitBytes
= 4;
3651 pTileInfoOut
->tileSplitBytes
= 5;
3654 pTileInfoOut
->tileSplitBytes
= 6;
3657 ADDR_ASSERT_ALWAYS();
3658 retCode
= ADDR_INVALIDPARAMS
;
3659 pTileInfoOut
->tileSplitBytes
= 0;
3665 switch (pTileInfoIn
->banks
)
3668 pTileInfoOut
->banks
= 2;
3671 pTileInfoOut
->banks
= 4;
3674 pTileInfoOut
->banks
= 8;
3677 pTileInfoOut
->banks
= 16;
3680 ADDR_ASSERT_ALWAYS();
3681 retCode
= ADDR_INVALIDPARAMS
;
3682 pTileInfoOut
->banks
= 2;
3686 switch (pTileInfoIn
->bankWidth
)
3689 pTileInfoOut
->bankWidth
= 1;
3692 pTileInfoOut
->bankWidth
= 2;
3695 pTileInfoOut
->bankWidth
= 4;
3698 pTileInfoOut
->bankWidth
= 8;
3701 ADDR_ASSERT_ALWAYS();
3702 retCode
= ADDR_INVALIDPARAMS
;
3703 pTileInfoOut
->bankWidth
= 1;
3707 switch (pTileInfoIn
->bankHeight
)
3710 pTileInfoOut
->bankHeight
= 1;
3713 pTileInfoOut
->bankHeight
= 2;
3716 pTileInfoOut
->bankHeight
= 4;
3719 pTileInfoOut
->bankHeight
= 8;
3722 ADDR_ASSERT_ALWAYS();
3723 retCode
= ADDR_INVALIDPARAMS
;
3724 pTileInfoOut
->bankHeight
= 1;
3728 switch (pTileInfoIn
->macroAspectRatio
)
3731 pTileInfoOut
->macroAspectRatio
= 1;
3734 pTileInfoOut
->macroAspectRatio
= 2;
3737 pTileInfoOut
->macroAspectRatio
= 4;
3740 pTileInfoOut
->macroAspectRatio
= 8;
3743 ADDR_ASSERT_ALWAYS();
3744 retCode
= ADDR_INVALIDPARAMS
;
3745 pTileInfoOut
->macroAspectRatio
= 1;
3749 switch (pTileInfoIn
->tileSplitBytes
)
3752 pTileInfoOut
->tileSplitBytes
= 64;
3755 pTileInfoOut
->tileSplitBytes
= 128;
3758 pTileInfoOut
->tileSplitBytes
= 256;
3761 pTileInfoOut
->tileSplitBytes
= 512;
3764 pTileInfoOut
->tileSplitBytes
= 1024;
3767 pTileInfoOut
->tileSplitBytes
= 2048;
3770 pTileInfoOut
->tileSplitBytes
= 4096;
3773 ADDR_ASSERT_ALWAYS();
3774 retCode
= ADDR_INVALIDPARAMS
;
3775 pTileInfoOut
->tileSplitBytes
= 64;
3780 if (pTileInfoIn
!= pTileInfoOut
)
3782 pTileInfoOut
->pipeConfig
= pTileInfoIn
->pipeConfig
;
3787 ADDR_ASSERT_ALWAYS();
3788 retCode
= ADDR_INVALIDPARAMS
;
3795 ****************************************************************************************************
3796 * EgBasedLib::HwlComputeSurfaceInfo
3798 * Entry of EgBasedLib ComputeSurfaceInfo
3801 ****************************************************************************************************
3803 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceInfo(
3804 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
3805 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
3808 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3810 if (pIn
->numSamples
< pIn
->numFrags
)
3812 retCode
= ADDR_INVALIDPARAMS
;
3815 ADDR_TILEINFO tileInfo
= {0};
3817 if (retCode
== ADDR_OK
)
3819 // Uses internal tile info if pOut does not have a valid pTileInfo
3820 if (pOut
->pTileInfo
== NULL
)
3822 pOut
->pTileInfo
= &tileInfo
;
3825 if (DispatchComputeSurfaceInfo(pIn
, pOut
) == FALSE
)
3827 retCode
= ADDR_INVALIDPARAMS
;
3830 // In case client uses tile info as input and would like to calculate a correct size and
3831 // alignment together with tile info as output when the tile info is not suppose to have any
3832 // matching indices in tile mode tables.
3833 if (pIn
->flags
.skipIndicesOutput
== FALSE
)
3836 pOut
->tileIndex
= HwlPostCheckTileIndex(pOut
->pTileInfo
,
3841 if (IsMacroTiled(pOut
->tileMode
) && (pOut
->macroModeIndex
== TileIndexInvalid
))
3843 pOut
->macroModeIndex
= HwlComputeMacroModeIndex(pOut
->tileIndex
,
3851 // Resets pTileInfo to NULL if the internal tile info is used
3852 if (pOut
->pTileInfo
== &tileInfo
)
3855 // Client does not pass in a valid pTileInfo
3856 if (IsMacroTiled(pOut
->tileMode
))
3858 // If a valid index is returned, then no pTileInfo is okay
3859 ADDR_ASSERT((m_configFlags
.useTileIndex
== FALSE
) ||
3860 (pOut
->tileIndex
!= TileIndexInvalid
));
3862 if (IsTileInfoAllZero(pIn
->pTileInfo
) == FALSE
)
3864 // The initial value of pIn->pTileInfo is copied to tileInfo
3865 // We do not expect any of these value to be changed nor any 0 of inputs
3866 ADDR_ASSERT(tileInfo
.banks
== pIn
->pTileInfo
->banks
);
3867 ADDR_ASSERT(tileInfo
.bankWidth
== pIn
->pTileInfo
->bankWidth
);
3868 ADDR_ASSERT(tileInfo
.bankHeight
== pIn
->pTileInfo
->bankHeight
);
3869 ADDR_ASSERT(tileInfo
.macroAspectRatio
== pIn
->pTileInfo
->macroAspectRatio
);
3870 ADDR_ASSERT(tileInfo
.tileSplitBytes
== pIn
->pTileInfo
->tileSplitBytes
);
3874 pOut
->pTileInfo
= NULL
;
3882 ****************************************************************************************************
3883 * EgBasedLib::HwlComputeSurfaceAddrFromCoord
3885 * Entry of EgBasedLib ComputeSurfaceAddrFromCoord
3888 ****************************************************************************************************
3890 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceAddrFromCoord(
3891 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3892 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3895 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3898 #if !ALT_TEST // Overflow test needs this out-of-boundary coord
3899 (pIn
->x
> pIn
->pitch
) ||
3900 (pIn
->y
> pIn
->height
) ||
3902 (pIn
->numSamples
> m_maxSamples
))
3904 retCode
= ADDR_INVALIDPARAMS
;
3908 pOut
->addr
= DispatchComputeSurfaceAddrFromCoord(pIn
, pOut
);
3915 ****************************************************************************************************
3916 * EgBasedLib::HwlComputeSurfaceCoordFromAddr
3918 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
3921 ****************************************************************************************************
3923 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceCoordFromAddr(
3924 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3925 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3928 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3930 if ((pIn
->bitPosition
>= 8) ||
3931 (pIn
->numSamples
> m_maxSamples
))
3933 retCode
= ADDR_INVALIDPARAMS
;
3937 DispatchComputeSurfaceCoordFromAddr(pIn
, pOut
);
3943 ****************************************************************************************************
3944 * EgBasedLib::HwlComputeSliceTileSwizzle
3946 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
3949 ****************************************************************************************************
3951 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSliceTileSwizzle(
3952 const ADDR_COMPUTE_SLICESWIZZLE_INPUT
* pIn
, ///< [in] input structure
3953 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
* pOut
///< [out] output structure
3956 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3958 if (pIn
->pTileInfo
&& (pIn
->pTileInfo
->banks
> 0))
3961 pOut
->tileSwizzle
= ComputeSliceTileSwizzle(pIn
->tileMode
,
3969 retCode
= ADDR_INVALIDPARAMS
;
3976 ****************************************************************************************************
3977 * EgBasedLib::HwlComputeHtileBpp
3984 ****************************************************************************************************
3986 UINT_32
EgBasedLib::HwlComputeHtileBpp(
3987 BOOL_32 isWidth8
, ///< [in] TRUE if block width is 8
3988 BOOL_32 isHeight8
///< [in] TRUE if block height is 8
3991 // only support 8x8 mode
3992 ADDR_ASSERT(isWidth8
&& isHeight8
);
3997 ****************************************************************************************************
3998 * EgBasedLib::HwlComputeHtileBaseAlign
4001 * Compute htile base alignment
4004 * Htile base alignment
4005 ****************************************************************************************************
4007 UINT_32
EgBasedLib::HwlComputeHtileBaseAlign(
4008 BOOL_32 isTcCompatible
, ///< [in] if TC compatible
4009 BOOL_32 isLinear
, ///< [in] if it is linear mode
4010 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
4013 UINT_32 baseAlign
= m_pipeInterleaveBytes
* HwlGetPipes(pTileInfo
);
4017 ADDR_ASSERT(pTileInfo
!= NULL
);
4020 baseAlign
*= pTileInfo
->banks
;
4028 ****************************************************************************************************
4029 * EgBasedLib::HwlGetPitchAlignmentMicroTiled
4032 * Compute 1D tiled surface pitch alignment, calculation results are returned through
4033 * output parameters.
4037 ****************************************************************************************************
4039 UINT_32
EgBasedLib::HwlGetPitchAlignmentMicroTiled(
4040 AddrTileMode tileMode
, ///< [in] tile mode
4041 UINT_32 bpp
, ///< [in] bits per pixel
4042 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4043 UINT_32 numSamples
///< [in] number of samples
4048 UINT_32 microTileThickness
= Thickness(tileMode
);
4050 UINT_32 pixelsPerMicroTile
;
4051 UINT_32 pixelsPerPipeInterleave
;
4052 UINT_32 microTilesPerPipeInterleave
;
4055 // Special workaround for depth/stencil buffer, use 8 bpp to meet larger requirement for
4056 // stencil buffer since pitch alignment is related to bpp.
4057 // For a depth only buffer do not set this.
4059 // Note: this actually does not work for mipmap but mipmap depth texture is not really
4060 // sampled with mipmap.
4062 if (flags
.depth
&& (flags
.noStencil
== FALSE
))
4067 pixelsPerMicroTile
= MicroTilePixels
* microTileThickness
;
4068 pixelsPerPipeInterleave
= BYTES_TO_BITS(m_pipeInterleaveBytes
) / (bpp
* numSamples
);
4069 microTilesPerPipeInterleave
= pixelsPerPipeInterleave
/ pixelsPerMicroTile
;
4071 pitchAlign
= Max(MicroTileWidth
, microTilesPerPipeInterleave
* MicroTileWidth
);
4077 ****************************************************************************************************
4078 * EgBasedLib::HwlGetSizeAdjustmentMicroTiled
4081 * Adjust 1D tiled surface pitch and slice size
4084 * Logical slice size in bytes
4085 ****************************************************************************************************
4087 UINT_64
EgBasedLib::HwlGetSizeAdjustmentMicroTiled(
4088 UINT_32 thickness
, ///< [in] thickness
4089 UINT_32 bpp
, ///< [in] bits per pixel
4090 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4091 UINT_32 numSamples
, ///< [in] number of samples
4092 UINT_32 baseAlign
, ///< [in] base alignment
4093 UINT_32 pitchAlign
, ///< [in] pitch alignment
4094 UINT_32
* pPitch
, ///< [in,out] pointer to pitch
4095 UINT_32
* pHeight
///< [in,out] pointer to height
4098 UINT_64 logicalSliceSize
;
4099 MAYBE_UNUSED UINT_64 physicalSliceSize
;
4101 UINT_32 pitch
= *pPitch
;
4102 UINT_32 height
= *pHeight
;
4104 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
4105 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
4107 // Physical slice: multiplied by thickness
4108 physicalSliceSize
= logicalSliceSize
* thickness
;
4111 // R800 will always pad physical slice size to baseAlign which is pipe_interleave_bytes
4113 ADDR_ASSERT((physicalSliceSize
% baseAlign
) == 0);
4115 return logicalSliceSize
;
4119 ****************************************************************************************************
4120 * EgBasedLib::HwlStereoCheckRightOffsetPadding
4123 * check if the height needs extra padding for stereo right eye offset, to avoid swizzling
4126 * TRUE is the extra padding is needed
4128 ****************************************************************************************************
4130 UINT_32
EgBasedLib::HwlStereoCheckRightOffsetPadding(
4131 ADDR_TILEINFO
* pTileInfo
///< Tiling info
4134 UINT_32 stereoHeightAlign
= 0;
4136 if (pTileInfo
->macroAspectRatio
> 2)
4138 // Since 3D rendering treats right eye surface starting from y == "eye height" while
4139 // display engine treats it to be 0, so the bank bits may be different.
4140 // Additional padding in height is required to make sure it's possible
4141 // to achieve synonym by adjusting bank swizzle of right eye surface.
4143 static const UINT_32 StereoAspectRatio
= 2;
4144 stereoHeightAlign
= pTileInfo
->banks
*
4145 pTileInfo
->bankHeight
*
4150 return stereoHeightAlign
;