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
27 ****************************************************************************************************
28 * @file egbaddrlib.cpp
29 * @brief Contains the EgBasedLib class implementation.
30 ****************************************************************************************************
33 #include "egbaddrlib.h"
35 #include "util/macros.h"
43 ****************************************************************************************************
44 * EgBasedLib::EgBasedLib
51 ****************************************************************************************************
53 EgBasedLib::EgBasedLib(const Client
* pClient
)
63 ****************************************************************************************************
64 * EgBasedLib::~EgBasedLib
68 ****************************************************************************************************
70 EgBasedLib::~EgBasedLib()
75 ****************************************************************************************************
76 * EgBasedLib::DispatchComputeSurfaceInfo
79 * Compute surface sizes include padded pitch,height,slices,total size in bytes,
80 * meanwhile output suitable tile mode and base alignment might be changed in this
81 * call as well. Results are returned through output parameters.
84 * TRUE if no error occurs
85 ****************************************************************************************************
87 BOOL_32
EgBasedLib::DispatchComputeSurfaceInfo(
88 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
89 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
92 AddrTileMode tileMode
= pIn
->tileMode
;
93 UINT_32 bpp
= pIn
->bpp
;
94 UINT_32 numSamples
= pIn
->numSamples
;
95 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
96 UINT_32 pitch
= pIn
->width
;
97 UINT_32 height
= pIn
->height
;
98 UINT_32 numSlices
= pIn
->numSlices
;
99 UINT_32 mipLevel
= pIn
->mipLevel
;
100 ADDR_SURFACE_FLAGS flags
= pIn
->flags
;
102 ADDR_TILEINFO tileInfoDef
= {0};
103 ADDR_TILEINFO
* pTileInfo
= &tileInfoDef
;
107 if (pIn
->flags
.disallowLargeThickDegrade
== 0)
109 tileMode
= DegradeLargeThickTile(tileMode
, bpp
);
112 // Only override numSamples for NI above
113 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
115 if (numFrags
!= numSamples
) // This means EQAA
117 // The real surface size needed is determined by number of fragments
118 numSamples
= numFrags
;
121 // Save altered numSamples in pOut
122 pOut
->numSamples
= numSamples
;
125 // Caller makes sure pOut->pTileInfo is not NULL, see HwlComputeSurfaceInfo
126 ADDR_ASSERT(pOut
->pTileInfo
);
128 if (pOut
->pTileInfo
!= NULL
)
130 pTileInfo
= pOut
->pTileInfo
;
133 // Set default values
134 if (pIn
->pTileInfo
!= NULL
)
136 if (pTileInfo
!= pIn
->pTileInfo
)
138 *pTileInfo
= *pIn
->pTileInfo
;
143 memset(pTileInfo
, 0, sizeof(ADDR_TILEINFO
));
146 // For macro tile mode, we should calculate default tiling parameters
147 HwlSetupTileInfo(tileMode
,
167 // This is calculating one face, remove cube flag
174 case ADDR_TM_LINEAR_GENERAL
://fall through
175 case ADDR_TM_LINEAR_ALIGNED
:
176 valid
= ComputeSurfaceInfoLinear(pIn
, pOut
, padDims
);
179 case ADDR_TM_1D_TILED_THIN1
://fall through
180 case ADDR_TM_1D_TILED_THICK
:
181 valid
= ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, tileMode
);
184 case ADDR_TM_2D_TILED_THIN1
: //fall through
185 case ADDR_TM_2D_TILED_THICK
: //fall through
186 case ADDR_TM_3D_TILED_THIN1
: //fall through
187 case ADDR_TM_3D_TILED_THICK
: //fall through
188 case ADDR_TM_2D_TILED_XTHICK
: //fall through
189 case ADDR_TM_3D_TILED_XTHICK
: //fall through
190 case ADDR_TM_PRT_TILED_THIN1
: //fall through
191 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
192 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
193 case ADDR_TM_PRT_TILED_THICK
: //fall through
194 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
195 case ADDR_TM_PRT_3D_TILED_THICK
:
196 valid
= ComputeSurfaceInfoMacroTiled(pIn
, pOut
, padDims
, tileMode
);
201 ADDR_ASSERT_ALWAYS();
209 ****************************************************************************************************
210 * EgBasedLib::ComputeSurfaceInfoLinear
213 * Compute linear surface sizes include padded pitch, height, slices, total size in
214 * bytes, meanwhile alignments as well. Since it is linear mode, so output tile mode
215 * will not be changed here. Results are returned through output parameters.
218 * TRUE if no error occurs
219 ****************************************************************************************************
221 BOOL_32
EgBasedLib::ComputeSurfaceInfoLinear(
222 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
223 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
224 UINT_32 padDims
///< [in] Dimensions to padd
227 UINT_32 expPitch
= pIn
->width
;
228 UINT_32 expHeight
= pIn
->height
;
229 UINT_32 expNumSlices
= pIn
->numSlices
;
231 // No linear MSAA on real H/W, keep this for TGL
232 UINT_32 numSamples
= pOut
->numSamples
;
234 const UINT_32 microTileThickness
= 1;
237 // Compute the surface alignments.
239 ComputeSurfaceAlignmentsLinear(pIn
->tileMode
,
246 if ((pIn
->tileMode
== ADDR_TM_LINEAR_GENERAL
) && pIn
->flags
.color
&& (pIn
->height
> 1))
249 // When linear_general surface is accessed in multiple lines, it requires 8 pixels in pitch
250 // alignment since PITCH_TILE_MAX is in unit of 8 pixels.
251 // It is OK if it is accessed per line.
252 ADDR_ASSERT((pIn
->width
% 8) == 0);
256 pOut
->depthAlign
= microTileThickness
;
258 expPitch
= HwlPreHandleBaseLvl3xPitch(pIn
, expPitch
);
261 // Pad pitch and height to the required granularities.
263 PadDimensions(pIn
->tileMode
,
270 &expPitch
, &pOut
->pitchAlign
,
271 &expHeight
, pOut
->heightAlign
,
272 &expNumSlices
, microTileThickness
);
274 expPitch
= HwlPostHandleBaseLvl3xPitch(pIn
, expPitch
);
280 UINT_64 logicalSliceSize
;
282 logicalSliceSize
= HwlGetSizeAdjustmentLinear(pIn
->tileMode
,
291 if ((pIn
->pitchAlign
!= 0) || (pIn
->heightAlign
!= 0))
293 if (pIn
->pitchAlign
!= 0)
295 ADDR_ASSERT((pIn
->pitchAlign
% pOut
->pitchAlign
) == 0);
296 pOut
->pitchAlign
= pIn
->pitchAlign
;
298 if (IsPow2(pOut
->pitchAlign
))
300 expPitch
= PowTwoAlign(expPitch
, pOut
->pitchAlign
);
304 expPitch
+= pOut
->pitchAlign
- 1;
305 expPitch
/= pOut
->pitchAlign
;
306 expPitch
*= pOut
->pitchAlign
;
310 if (pIn
->heightAlign
!= 0)
312 ADDR_ASSERT((pIn
->heightAlign
% pOut
->heightAlign
) == 0);
313 pOut
->heightAlign
= pIn
->heightAlign
;
315 if (IsPow2(pOut
->heightAlign
))
317 expHeight
= PowTwoAlign(expHeight
, pOut
->heightAlign
);
321 expHeight
+= pOut
->heightAlign
- 1;
322 expHeight
/= pOut
->heightAlign
;
323 expHeight
*= pOut
->heightAlign
;
327 logicalSliceSize
= BITS_TO_BYTES(expPitch
* expHeight
* pIn
->bpp
);
330 pOut
->pitch
= expPitch
;
331 pOut
->height
= expHeight
;
332 pOut
->depth
= expNumSlices
;
334 pOut
->surfSize
= logicalSliceSize
* expNumSlices
;
336 pOut
->tileMode
= pIn
->tileMode
;
342 ****************************************************************************************************
343 * EgBasedLib::ComputeSurfaceInfoMicroTiled
346 * Compute 1D/Micro Tiled surface sizes include padded pitch, height, slices, total
347 * size in bytes, meanwhile alignments as well. Results are returned through output
351 * TRUE if no error occurs
352 ****************************************************************************************************
354 BOOL_32
EgBasedLib::ComputeSurfaceInfoMicroTiled(
355 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
356 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
357 UINT_32 padDims
, ///< [in] Dimensions to padd
358 AddrTileMode expTileMode
///< [in] Expected tile mode
361 BOOL_32 valid
= TRUE
;
363 UINT_32 microTileThickness
;
364 UINT_32 expPitch
= pIn
->width
;
365 UINT_32 expHeight
= pIn
->height
;
366 UINT_32 expNumSlices
= pIn
->numSlices
;
368 // No 1D MSAA on real H/W, keep this for TGL
369 UINT_32 numSamples
= pOut
->numSamples
;
372 // Compute the micro tile thickness.
374 microTileThickness
= Thickness(expTileMode
);
377 // Extra override for mip levels
379 if (pIn
->mipLevel
> 0)
382 // Reduce tiling mode from thick to thin if the number of slices is less than the
383 // micro tile thickness.
385 if ((expTileMode
== ADDR_TM_1D_TILED_THICK
) &&
386 (expNumSlices
< ThickTileThickness
))
388 expTileMode
= HwlDegradeThickTileMode(ADDR_TM_1D_TILED_THICK
, expNumSlices
, NULL
);
389 if (expTileMode
!= ADDR_TM_1D_TILED_THICK
)
391 microTileThickness
= 1;
397 // Compute the surface restrictions.
399 ComputeSurfaceAlignmentsMicroTiled(expTileMode
,
408 pOut
->depthAlign
= microTileThickness
;
411 // Pad pitch and height to the required granularities.
412 // Compute surface size.
413 // Return parameters.
415 PadDimensions(expTileMode
,
422 &expPitch
, &pOut
->pitchAlign
,
423 &expHeight
, pOut
->heightAlign
,
424 &expNumSlices
, microTileThickness
);
427 // Get HWL specific pitch adjustment
429 UINT_64 logicalSliceSize
= HwlGetSizeAdjustmentMicroTiled(microTileThickness
,
438 pOut
->pitch
= expPitch
;
439 pOut
->height
= expHeight
;
440 pOut
->depth
= expNumSlices
;
442 pOut
->surfSize
= logicalSliceSize
* expNumSlices
;
444 pOut
->tileMode
= expTileMode
;
450 ****************************************************************************************************
451 * EgBasedLib::ComputeSurfaceInfoMacroTiled
454 * Compute 2D/macro tiled surface sizes include padded pitch, height, slices, total
455 * size in bytes, meanwhile output suitable tile mode and alignments might be changed
456 * in this call as well. Results are returned through output parameters.
459 * TRUE if no error occurs
460 ****************************************************************************************************
462 BOOL_32
EgBasedLib::ComputeSurfaceInfoMacroTiled(
463 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
464 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
, ///< [out] Output structure
465 UINT_32 padDims
, ///< [in] Dimensions to padd
466 AddrTileMode expTileMode
///< [in] Expected tile mode
469 BOOL_32 valid
= TRUE
;
471 AddrTileMode origTileMode
= expTileMode
;
472 UINT_32 microTileThickness
;
475 UINT_32 paddedHeight
;
476 UINT_64 bytesPerSlice
;
478 UINT_32 expPitch
= pIn
->width
;
479 UINT_32 expHeight
= pIn
->height
;
480 UINT_32 expNumSlices
= pIn
->numSlices
;
482 UINT_32 numSamples
= pOut
->numSamples
;
485 // Compute the surface restrictions as base
486 // SanityCheckMacroTiled is called in ComputeSurfaceAlignmentsMacroTiled
488 valid
= ComputeSurfaceAlignmentsMacroTiled(expTileMode
,
498 // Compute the micro tile thickness.
500 microTileThickness
= Thickness(expTileMode
);
503 // Find the correct tiling mode for mip levels
505 if (pIn
->mipLevel
> 0)
508 // Try valid tile mode
510 expTileMode
= ComputeSurfaceMipLevelTileMode(expTileMode
,
520 if (!IsMacroTiled(expTileMode
)) // Downgraded to micro-tiled
522 return ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, expTileMode
);
524 else if (microTileThickness
!= Thickness(expTileMode
))
527 // Re-compute if thickness changed since bank-height may be changed!
529 return ComputeSurfaceInfoMacroTiled(pIn
, pOut
, padDims
, expTileMode
);
533 paddedPitch
= expPitch
;
534 paddedHeight
= expHeight
;
539 if (expTileMode
!= origTileMode
) // Tile mode is changed but still macro-tiled
541 valid
= ComputeSurfaceAlignmentsMacroTiled(expTileMode
,
552 PadDimensions(expTileMode
,
559 &paddedPitch
, &pOut
->pitchAlign
,
560 &paddedHeight
, pOut
->heightAlign
,
561 &expNumSlices
, microTileThickness
);
563 if (pIn
->flags
.qbStereo
&&
564 (pOut
->pStereoInfo
!= NULL
))
566 UINT_32 stereoHeightAlign
= HwlStereoCheckRightOffsetPadding(pOut
->pTileInfo
);
568 if (stereoHeightAlign
!= 0)
570 paddedHeight
= PowTwoAlign(paddedHeight
, stereoHeightAlign
);
574 if ((pIn
->flags
.needEquation
== TRUE
) &&
575 (m_chipFamily
== ADDR_CHIP_FAMILY_SI
) &&
576 (pIn
->numMipLevels
> 1) &&
577 (pIn
->mipLevel
== 0))
579 BOOL_32 convertTo1D
= FALSE
;
581 ADDR_ASSERT(Thickness(expTileMode
) == 1);
583 for (UINT_32 i
= 1; i
< pIn
->numMipLevels
; i
++)
585 UINT_32 mipPitch
= Max(1u, paddedPitch
>> i
);
586 UINT_32 mipHeight
= Max(1u, pIn
->height
>> i
);
587 UINT_32 mipSlices
= pIn
->flags
.volume
?
588 Max(1u, pIn
->numSlices
>> i
) : pIn
->numSlices
;
589 expTileMode
= ComputeSurfaceMipLevelTileMode(expTileMode
,
599 if (IsMacroTiled(expTileMode
))
601 if (PowTwoAlign(mipPitch
, pOut
->blockWidth
) !=
602 PowTwoAlign(mipPitch
, pOut
->pitchAlign
))
616 return ComputeSurfaceInfoMicroTiled(pIn
, pOut
, padDims
, ADDR_TM_1D_TILED_THIN1
);
620 pOut
->pitch
= paddedPitch
;
621 // Put this check right here to workaround special mipmap cases which the original height
623 // The original height is pre-stored in pOut->height in PostComputeMipLevel and
624 // pOut->pitch is needed in HwlCheckLastMacroTiledLvl, too.
625 if (m_configFlags
.checkLast2DLevel
&& (numSamples
== 1)) // Don't check MSAA
627 // Set a TRUE in pOut if next Level is the first 1D sub level
628 HwlCheckLastMacroTiledLvl(pIn
, pOut
);
630 pOut
->height
= paddedHeight
;
632 pOut
->depth
= expNumSlices
;
635 // Compute the size of a slice.
637 bytesPerSlice
= BITS_TO_BYTES(static_cast<UINT_64
>(paddedPitch
) *
638 paddedHeight
* NextPow2(pIn
->bpp
) * numSamples
);
640 pOut
->surfSize
= bytesPerSlice
* expNumSlices
;
642 pOut
->tileMode
= expTileMode
;
644 pOut
->depthAlign
= microTileThickness
;
652 ****************************************************************************************************
653 * EgBasedLib::ComputeSurfaceAlignmentsLinear
656 * Compute linear surface alignment, calculation results are returned through
660 * TRUE if no error occurs
661 ****************************************************************************************************
663 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsLinear(
664 AddrTileMode tileMode
, ///< [in] tile mode
665 UINT_32 bpp
, ///< [in] bits per pixel
666 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
667 UINT_32
* pBaseAlign
, ///< [out] base address alignment in bytes
668 UINT_32
* pPitchAlign
, ///< [out] pitch alignment in pixels
669 UINT_32
* pHeightAlign
///< [out] height alignment in pixels
672 BOOL_32 valid
= TRUE
;
676 case ADDR_TM_LINEAR_GENERAL
:
678 // The required base alignment and pitch and height granularities is to 1 element.
680 *pBaseAlign
= (bpp
> 8) ? bpp
/ 8 : 1;
684 case ADDR_TM_LINEAR_ALIGNED
:
686 // The required alignment for base is the pipe interleave size.
687 // The required granularity for pitch is hwl dependent.
688 // The required granularity for height is one row.
690 *pBaseAlign
= m_pipeInterleaveBytes
;
691 *pPitchAlign
= HwlGetPitchAlignmentLinear(bpp
, flags
);
698 ADDR_UNHANDLED_CASE();
702 AdjustPitchAlignment(flags
, pPitchAlign
);
708 ****************************************************************************************************
709 * EgBasedLib::ComputeSurfaceAlignmentsMicroTiled
712 * Compute 1D tiled surface alignment, calculation results are returned through
716 * TRUE if no error occurs
717 ****************************************************************************************************
719 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsMicroTiled(
720 AddrTileMode tileMode
, ///< [in] tile mode
721 UINT_32 bpp
, ///< [in] bits per pixel
722 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
723 UINT_32 mipLevel
, ///< [in] mip level
724 UINT_32 numSamples
, ///< [in] number of samples
725 UINT_32
* pBaseAlign
, ///< [out] base address alignment in bytes
726 UINT_32
* pPitchAlign
, ///< [out] pitch alignment in pixels
727 UINT_32
* pHeightAlign
///< [out] height alignment in pixels
730 BOOL_32 valid
= TRUE
;
733 // The required alignment for base is the pipe interleave size.
735 *pBaseAlign
= m_pipeInterleaveBytes
;
737 *pPitchAlign
= HwlGetPitchAlignmentMicroTiled(tileMode
, bpp
, flags
, numSamples
);
739 *pHeightAlign
= MicroTileHeight
;
741 AdjustPitchAlignment(flags
, pPitchAlign
);
743 if (flags
.czDispCompatible
&& (mipLevel
== 0))
745 *pBaseAlign
= PowTwoAlign(*pBaseAlign
, 4096); //Base address MOD 4096 = 0
746 *pPitchAlign
= PowTwoAlign(*pPitchAlign
, 512 / (BITS_TO_BYTES(bpp
))); //(8 lines * pitch * bytes per pixel) MOD 4096 = 0
748 // end Carrizo workaround for 1D tilling
754 ****************************************************************************************************
755 * EgBasedLib::HwlReduceBankWidthHeight
758 * Additional checks, reduce bankHeight/bankWidth if needed and possible
759 * tileSize*BANK_WIDTH*BANK_HEIGHT <= ROW_SIZE
762 * TRUE if no error occurs
763 ****************************************************************************************************
765 BOOL_32
EgBasedLib::HwlReduceBankWidthHeight(
766 UINT_32 tileSize
, ///< [in] tile size
767 UINT_32 bpp
, ///< [in] bits per pixel
768 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
769 UINT_32 numSamples
, ///< [in] number of samples
770 UINT_32 bankHeightAlign
, ///< [in] bank height alignment
771 UINT_32 pipes
, ///< [in] pipes
772 ADDR_TILEINFO
* pTileInfo
///< [in,out] bank structure.
775 UINT_32 macroAspectAlign
;
776 BOOL_32 valid
= TRUE
;
778 if (tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
)
780 BOOL_32 stillGreater
= TRUE
;
782 // Try reducing bankWidth first
783 if (stillGreater
&& pTileInfo
->bankWidth
> 1)
785 while (stillGreater
&& pTileInfo
->bankWidth
> 0)
787 pTileInfo
->bankWidth
>>= 1;
789 if (pTileInfo
->bankWidth
== 0)
791 pTileInfo
->bankWidth
= 1;
796 tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
;
799 // bankWidth is reduced above, so we need to recalculate bankHeight and ratio
800 bankHeightAlign
= Max(1u,
801 m_pipeInterleaveBytes
* m_bankInterleave
/
802 (tileSize
* pTileInfo
->bankWidth
)
805 // We cannot increase bankHeight so just assert this case.
806 ADDR_ASSERT((pTileInfo
->bankHeight
% bankHeightAlign
) == 0);
810 macroAspectAlign
= Max(1u,
811 m_pipeInterleaveBytes
* m_bankInterleave
/
812 (tileSize
* pipes
* pTileInfo
->bankWidth
)
814 pTileInfo
->macroAspectRatio
= PowTwoAlign(pTileInfo
->macroAspectRatio
,
819 // Early quit bank_height degradation for "64" bit z buffer
820 if (flags
.depth
&& bpp
>= 64)
822 stillGreater
= FALSE
;
825 // Then try reducing bankHeight
826 if (stillGreater
&& pTileInfo
->bankHeight
> bankHeightAlign
)
828 while (stillGreater
&& pTileInfo
->bankHeight
> bankHeightAlign
)
830 pTileInfo
->bankHeight
>>= 1;
832 if (pTileInfo
->bankHeight
< bankHeightAlign
)
834 pTileInfo
->bankHeight
= bankHeightAlign
;
839 tileSize
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
> m_rowSize
;
843 valid
= !stillGreater
;
845 // Generate a warning if we still fail to meet this constraint
849 0, ("TILE_SIZE(%d)*BANK_WIDTH(%d)*BANK_HEIGHT(%d) <= ROW_SIZE(%d)",
850 tileSize
, pTileInfo
->bankWidth
, pTileInfo
->bankHeight
, m_rowSize
));
858 ****************************************************************************************************
859 * EgBasedLib::ComputeSurfaceAlignmentsMacroTiled
862 * Compute 2D tiled surface alignment, calculation results are returned through
866 * TRUE if no error occurs
867 ****************************************************************************************************
869 BOOL_32
EgBasedLib::ComputeSurfaceAlignmentsMacroTiled(
870 AddrTileMode tileMode
, ///< [in] tile mode
871 UINT_32 bpp
, ///< [in] bits per pixel
872 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
873 UINT_32 mipLevel
, ///< [in] mip level
874 UINT_32 numSamples
, ///< [in] number of samples
875 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in,out] Surface output
878 ADDR_TILEINFO
* pTileInfo
= pOut
->pTileInfo
;
880 BOOL_32 valid
= SanityCheckMacroTiled(pTileInfo
);
884 UINT_32 macroTileWidth
;
885 UINT_32 macroTileHeight
;
888 UINT_32 bankHeightAlign
;
889 UINT_32 macroAspectAlign
;
891 UINT_32 thickness
= Thickness(tileMode
);
892 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
895 // Align bank height first according to latest h/w spec
898 // tile_size = MIN(tile_split, 64 * tile_thickness * element_bytes * num_samples)
899 tileSize
= Min(pTileInfo
->tileSplitBytes
,
900 BITS_TO_BYTES(64 * thickness
* bpp
* numSamples
));
902 // bank_height_align =
903 // MAX(1, (pipe_interleave_bytes * bank_interleave)/(tile_size*bank_width))
904 bankHeightAlign
= Max(1u,
905 m_pipeInterleaveBytes
* m_bankInterleave
/
906 (tileSize
* pTileInfo
->bankWidth
)
909 pTileInfo
->bankHeight
= PowTwoAlign(pTileInfo
->bankHeight
, bankHeightAlign
);
911 // num_pipes * bank_width * macro_tile_aspect >=
912 // (pipe_interleave_size * bank_interleave) / tile_size
915 // this restriction is only for mipmap (mipmap's numSamples must be 1)
916 macroAspectAlign
= Max(1u,
917 m_pipeInterleaveBytes
* m_bankInterleave
/
918 (tileSize
* pipes
* pTileInfo
->bankWidth
)
920 pTileInfo
->macroAspectRatio
= PowTwoAlign(pTileInfo
->macroAspectRatio
, macroAspectAlign
);
923 valid
= HwlReduceBankWidthHeight(tileSize
,
932 // The required granularity for pitch is the macro tile width.
934 macroTileWidth
= MicroTileWidth
* pTileInfo
->bankWidth
* pipes
*
935 pTileInfo
->macroAspectRatio
;
937 pOut
->pitchAlign
= macroTileWidth
;
938 pOut
->blockWidth
= macroTileWidth
;
940 AdjustPitchAlignment(flags
, &pOut
->pitchAlign
);
943 // The required granularity for height is the macro tile height.
945 macroTileHeight
= MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
/
946 pTileInfo
->macroAspectRatio
;
948 pOut
->heightAlign
= macroTileHeight
;
949 pOut
->blockHeight
= macroTileHeight
;
952 // Compute base alignment
955 pipes
* pTileInfo
->bankWidth
* pTileInfo
->banks
* pTileInfo
->bankHeight
* tileSize
;
957 HwlComputeSurfaceAlignmentsMacroTiled(tileMode
, bpp
, flags
, mipLevel
, numSamples
, pOut
);
964 ****************************************************************************************************
965 * EgBasedLib::SanityCheckMacroTiled
968 * Check if macro-tiled parameters are valid
971 ****************************************************************************************************
973 BOOL_32
EgBasedLib::SanityCheckMacroTiled(
974 ADDR_TILEINFO
* pTileInfo
///< [in] macro-tiled parameters
977 BOOL_32 valid
= TRUE
;
978 MAYBE_UNUSED UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
980 switch (pTileInfo
->banks
)
982 case 2: //fall through
983 case 4: //fall through
984 case 8: //fall through
995 switch (pTileInfo
->bankWidth
)
997 case 1: //fall through
998 case 2: //fall through
999 case 4: //fall through
1010 switch (pTileInfo
->bankHeight
)
1012 case 1: //fall through
1013 case 2: //fall through
1014 case 4: //fall through
1025 switch (pTileInfo
->macroAspectRatio
)
1027 case 1: //fall through
1028 case 2: //fall through
1029 case 4: //fall through
1040 if (pTileInfo
->banks
< pTileInfo
->macroAspectRatio
)
1042 // This will generate macro tile height <= 1
1049 if (pTileInfo
->tileSplitBytes
> m_rowSize
)
1051 ADDR_WARN(0, ("tileSplitBytes is bigger than row size"));
1057 valid
= HwlSanityCheckMacroTiled(pTileInfo
);
1060 ADDR_ASSERT(valid
== TRUE
);
1062 // Add this assert for guidance
1063 ADDR_ASSERT(numPipes
* pTileInfo
->banks
>= 4);
1069 ****************************************************************************************************
1070 * EgBasedLib::ComputeSurfaceMipLevelTileMode
1073 * Compute valid tile mode for surface mipmap sub-levels
1076 * Suitable tile mode
1077 ****************************************************************************************************
1079 AddrTileMode
EgBasedLib::ComputeSurfaceMipLevelTileMode(
1080 AddrTileMode baseTileMode
, ///< [in] base tile mode
1081 UINT_32 bpp
, ///< [in] bits per pixels
1082 UINT_32 pitch
, ///< [in] current level pitch
1083 UINT_32 height
, ///< [in] current level height
1084 UINT_32 numSlices
, ///< [in] current number of slices
1085 UINT_32 numSamples
, ///< [in] number of samples
1086 UINT_32 pitchAlign
, ///< [in] pitch alignment
1087 UINT_32 heightAlign
, ///< [in] height alignment
1088 ADDR_TILEINFO
* pTileInfo
///< [in] ptr to bank structure
1091 UINT_64 bytesPerSlice
;
1092 (void)bytesPerSlice
;
1093 UINT_32 bytesPerTile
;
1095 AddrTileMode expTileMode
= baseTileMode
;
1096 UINT_32 microTileThickness
= Thickness(expTileMode
);
1097 UINT_32 interleaveSize
= m_pipeInterleaveBytes
* m_bankInterleave
;
1100 // Compute the size of a slice.
1102 bytesPerSlice
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
1103 bytesPerTile
= BITS_TO_BYTES(MicroTilePixels
* microTileThickness
* NextPow2(bpp
) * numSamples
);
1106 // Reduce tiling mode from thick to thin if the number of slices is less than the
1107 // micro tile thickness.
1109 if (numSlices
< microTileThickness
)
1111 expTileMode
= HwlDegradeThickTileMode(expTileMode
, numSlices
, &bytesPerTile
);
1114 if (bytesPerTile
> pTileInfo
->tileSplitBytes
)
1116 bytesPerTile
= pTileInfo
->tileSplitBytes
;
1119 UINT_32 threshold1
=
1120 bytesPerTile
* HwlGetPipes(pTileInfo
) * pTileInfo
->bankWidth
* pTileInfo
->macroAspectRatio
;
1122 UINT_32 threshold2
=
1123 bytesPerTile
* pTileInfo
->bankWidth
* pTileInfo
->bankHeight
;
1126 // Reduce the tile mode from 2D/3D to 1D in following conditions
1128 switch (expTileMode
)
1130 case ADDR_TM_2D_TILED_THIN1
: //fall through
1131 case ADDR_TM_3D_TILED_THIN1
:
1132 case ADDR_TM_PRT_TILED_THIN1
:
1133 case ADDR_TM_PRT_2D_TILED_THIN1
:
1134 case ADDR_TM_PRT_3D_TILED_THIN1
:
1135 if ((pitch
< pitchAlign
) ||
1136 (height
< heightAlign
) ||
1137 (interleaveSize
> threshold1
) ||
1138 (interleaveSize
> threshold2
))
1140 expTileMode
= ADDR_TM_1D_TILED_THIN1
;
1143 case ADDR_TM_2D_TILED_THICK
: //fall through
1144 case ADDR_TM_3D_TILED_THICK
:
1145 case ADDR_TM_2D_TILED_XTHICK
:
1146 case ADDR_TM_3D_TILED_XTHICK
:
1147 case ADDR_TM_PRT_TILED_THICK
:
1148 case ADDR_TM_PRT_2D_TILED_THICK
:
1149 case ADDR_TM_PRT_3D_TILED_THICK
:
1150 if ((pitch
< pitchAlign
) ||
1151 (height
< heightAlign
))
1153 expTileMode
= ADDR_TM_1D_TILED_THICK
;
1164 ****************************************************************************************************
1165 * EgBasedLib::HwlGetAlignmentInfoMacroTiled
1167 * Get alignment info for giving tile mode
1169 * TRUE if getting alignment is OK
1170 ****************************************************************************************************
1172 BOOL_32
EgBasedLib::HwlGetAlignmentInfoMacroTiled(
1173 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] create surface info
1174 UINT_32
* pPitchAlign
, ///< [out] pitch alignment
1175 UINT_32
* pHeightAlign
, ///< [out] height alignment
1176 UINT_32
* pSizeAlign
///< [out] size alignment
1179 BOOL_32 valid
= TRUE
;
1181 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
1183 UINT_32 numSamples
= (pIn
->numFrags
== 0) ? pIn
->numSamples
: pIn
->numFrags
;
1185 ADDR_ASSERT(pIn
->pTileInfo
);
1186 ADDR_TILEINFO tileInfo
= *pIn
->pTileInfo
;
1187 ADDR_COMPUTE_SURFACE_INFO_OUTPUT out
= {0};
1188 out
.pTileInfo
= &tileInfo
;
1190 if (UseTileIndex(pIn
->tileIndex
))
1192 out
.tileIndex
= pIn
->tileIndex
;
1193 out
.macroModeIndex
= TileIndexInvalid
;
1196 HwlSetupTileInfo(pIn
->tileMode
,
1207 valid
= ComputeSurfaceAlignmentsMacroTiled(pIn
->tileMode
,
1216 *pPitchAlign
= out
.pitchAlign
;
1217 *pHeightAlign
= out
.heightAlign
;
1218 *pSizeAlign
= out
.baseAlign
;
1225 ****************************************************************************************************
1226 * EgBasedLib::HwlDegradeThickTileMode
1229 * Degrades valid tile mode for thick modes if needed
1232 * Suitable tile mode
1233 ****************************************************************************************************
1235 AddrTileMode
EgBasedLib::HwlDegradeThickTileMode(
1236 AddrTileMode baseTileMode
, ///< [in] base tile mode
1237 UINT_32 numSlices
, ///< [in] current number of slices
1238 UINT_32
* pBytesPerTile
///< [in,out] pointer to bytes per slice
1241 ADDR_ASSERT(numSlices
< Thickness(baseTileMode
));
1242 // if pBytesPerTile is NULL, this is a don't-care....
1243 UINT_32 bytesPerTile
= pBytesPerTile
!= NULL
? *pBytesPerTile
: 64;
1245 AddrTileMode expTileMode
= baseTileMode
;
1246 switch (baseTileMode
)
1248 case ADDR_TM_1D_TILED_THICK
:
1249 expTileMode
= ADDR_TM_1D_TILED_THIN1
;
1252 case ADDR_TM_2D_TILED_THICK
:
1253 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1256 case ADDR_TM_3D_TILED_THICK
:
1257 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1260 case ADDR_TM_2D_TILED_XTHICK
:
1261 if (numSlices
< ThickTileThickness
)
1263 expTileMode
= ADDR_TM_2D_TILED_THIN1
;
1268 expTileMode
= ADDR_TM_2D_TILED_THICK
;
1272 case ADDR_TM_3D_TILED_XTHICK
:
1273 if (numSlices
< ThickTileThickness
)
1275 expTileMode
= ADDR_TM_3D_TILED_THIN1
;
1280 expTileMode
= ADDR_TM_3D_TILED_THICK
;
1285 ADDR_ASSERT_ALWAYS();
1289 if (pBytesPerTile
!= NULL
)
1291 *pBytesPerTile
= bytesPerTile
;
1298 ****************************************************************************************************
1299 * EgBasedLib::DispatchComputeSurfaceAddrFromCoord
1302 * Compute surface address from given coord (x, y, slice,sample)
1306 ****************************************************************************************************
1308 UINT_64
EgBasedLib::DispatchComputeSurfaceAddrFromCoord(
1309 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1310 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1315 UINT_32 slice
= pIn
->slice
;
1316 UINT_32 sample
= pIn
->sample
;
1317 UINT_32 bpp
= pIn
->bpp
;
1318 UINT_32 pitch
= pIn
->pitch
;
1319 UINT_32 height
= pIn
->height
;
1320 UINT_32 numSlices
= pIn
->numSlices
;
1321 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
1322 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
1323 AddrTileMode tileMode
= pIn
->tileMode
;
1324 AddrTileType microTileType
= pIn
->tileType
;
1325 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
1326 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
1327 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
1329 UINT_32
* pBitPosition
= &pOut
->bitPosition
;
1332 // ADDR_DEPTH_SAMPLE_ORDER = non-disp + depth-sample-order
1333 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
1335 isDepthSampleOrder
= TRUE
;
1338 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
1340 if (numFrags
!= numSamples
)
1342 numSamples
= numFrags
;
1343 ADDR_ASSERT(sample
< numSamples
);
1347 /// 128 bit/thick tiled surface doesn't support display tiling and
1348 /// mipmap chain must have the same tileType, so please fill tileType correctly
1349 if (IsLinear(pIn
->tileMode
) == FALSE
)
1351 if (bpp
>= 128 || Thickness(tileMode
) > 1)
1353 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
1360 case ADDR_TM_LINEAR_GENERAL
://fall through
1361 case ADDR_TM_LINEAR_ALIGNED
:
1362 addr
= ComputeSurfaceAddrFromCoordLinear(x
,
1372 case ADDR_TM_1D_TILED_THIN1
://fall through
1373 case ADDR_TM_1D_TILED_THICK
:
1374 addr
= ComputeSurfaceAddrFromCoordMicroTiled(x
,
1387 case ADDR_TM_2D_TILED_THIN1
: //fall through
1388 case ADDR_TM_2D_TILED_THICK
: //fall through
1389 case ADDR_TM_3D_TILED_THIN1
: //fall through
1390 case ADDR_TM_3D_TILED_THICK
: //fall through
1391 case ADDR_TM_2D_TILED_XTHICK
: //fall through
1392 case ADDR_TM_3D_TILED_XTHICK
: //fall through
1393 case ADDR_TM_PRT_TILED_THIN1
: //fall through
1394 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
1395 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
1396 case ADDR_TM_PRT_TILED_THICK
: //fall through
1397 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
1398 case ADDR_TM_PRT_3D_TILED_THICK
:
1399 UINT_32 pipeSwizzle
;
1400 UINT_32 bankSwizzle
;
1402 if (m_configFlags
.useCombinedSwizzle
)
1404 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
1405 &bankSwizzle
, &pipeSwizzle
);
1409 pipeSwizzle
= pIn
->pipeSwizzle
;
1410 bankSwizzle
= pIn
->bankSwizzle
;
1413 addr
= ComputeSurfaceAddrFromCoordMacroTiled(x
,
1432 ADDR_ASSERT_ALWAYS();
1440 ****************************************************************************************************
1441 * EgBasedLib::ComputeMacroTileEquation
1444 * Computes the address equation in macro tile
1446 * If equation can be computed
1447 ****************************************************************************************************
1449 ADDR_E_RETURNCODE
EgBasedLib::ComputeMacroTileEquation(
1450 UINT_32 log2BytesPP
, ///< [in] log2 of bytes per pixel
1451 AddrTileMode tileMode
, ///< [in] tile mode
1452 AddrTileType microTileType
, ///< [in] micro tiling type
1453 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure
1454 ADDR_EQUATION
* pEquation
///< [out] Equation for addressing in macro tile
1457 ADDR_E_RETURNCODE retCode
;
1459 // Element equation within a tile
1460 retCode
= ComputeMicroTileEquation(log2BytesPP
, tileMode
, microTileType
, pEquation
);
1462 if (retCode
== ADDR_OK
)
1464 // Tile equesiton with signle pipe bank
1465 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1466 UINT_32 numPipeBits
= Log2(numPipes
);
1468 for (UINT_32 i
= 0; i
< Log2(pTileInfo
->bankWidth
); i
++)
1470 pEquation
->addr
[pEquation
->numBits
].valid
= 1;
1471 pEquation
->addr
[pEquation
->numBits
].channel
= 0;
1472 pEquation
->addr
[pEquation
->numBits
].index
= i
+ log2BytesPP
+ 3 + numPipeBits
;
1473 pEquation
->numBits
++;
1476 for (UINT_32 i
= 0; i
< Log2(pTileInfo
->bankHeight
); i
++)
1478 pEquation
->addr
[pEquation
->numBits
].valid
= 1;
1479 pEquation
->addr
[pEquation
->numBits
].channel
= 1;
1480 pEquation
->addr
[pEquation
->numBits
].index
= i
+ 3;
1481 pEquation
->numBits
++;
1484 ADDR_EQUATION equation
;
1485 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
1487 UINT_32 thresholdX
= 32;
1488 UINT_32 thresholdY
= 32;
1490 if (IsPrtNoRotationTileMode(tileMode
))
1492 UINT_32 macroTilePitch
=
1493 (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
) * pTileInfo
->macroAspectRatio
;
1494 UINT_32 macroTileHeight
=
1495 (MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
) /
1496 pTileInfo
->macroAspectRatio
;
1497 thresholdX
= Log2(macroTilePitch
);
1498 thresholdY
= Log2(macroTileHeight
);
1502 retCode
= ComputePipeEquation(log2BytesPP
, thresholdX
, thresholdY
, pTileInfo
, &equation
);
1504 if (retCode
== ADDR_OK
)
1506 UINT_32 pipeBitStart
= Log2(m_pipeInterleaveBytes
);
1508 if (pEquation
->numBits
> pipeBitStart
)
1510 UINT_32 numLeftShift
= pEquation
->numBits
- pipeBitStart
;
1512 for (UINT_32 i
= 0; i
< numLeftShift
; i
++)
1514 pEquation
->addr
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1515 pEquation
->addr
[pEquation
->numBits
- i
- 1];
1516 pEquation
->xor1
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1517 pEquation
->xor1
[pEquation
->numBits
- i
- 1];
1518 pEquation
->xor2
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1519 pEquation
->xor2
[pEquation
->numBits
- i
- 1];
1523 for (UINT_32 i
= 0; i
< equation
.numBits
; i
++)
1525 pEquation
->addr
[pipeBitStart
+ i
] = equation
.addr
[i
];
1526 pEquation
->xor1
[pipeBitStart
+ i
] = equation
.xor1
[i
];
1527 pEquation
->xor2
[pipeBitStart
+ i
] = equation
.xor2
[i
];
1528 pEquation
->numBits
++;
1532 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
1534 retCode
= ComputeBankEquation(log2BytesPP
, thresholdX
, thresholdY
,
1535 pTileInfo
, &equation
);
1537 if (retCode
== ADDR_OK
)
1539 UINT_32 bankBitStart
= pipeBitStart
+ numPipeBits
+ Log2(m_bankInterleave
);
1541 if (pEquation
->numBits
> bankBitStart
)
1543 UINT_32 numLeftShift
= pEquation
->numBits
- bankBitStart
;
1545 for (UINT_32 i
= 0; i
< numLeftShift
; i
++)
1547 pEquation
->addr
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1548 pEquation
->addr
[pEquation
->numBits
- i
- 1];
1549 pEquation
->xor1
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1550 pEquation
->xor1
[pEquation
->numBits
- i
- 1];
1551 pEquation
->xor2
[pEquation
->numBits
+ equation
.numBits
- i
- 1] =
1552 pEquation
->xor2
[pEquation
->numBits
- i
- 1];
1556 for (UINT_32 i
= 0; i
< equation
.numBits
; i
++)
1558 pEquation
->addr
[bankBitStart
+ i
] = equation
.addr
[i
];
1559 pEquation
->xor1
[bankBitStart
+ i
] = equation
.xor1
[i
];
1560 pEquation
->xor2
[bankBitStart
+ i
] = equation
.xor2
[i
];
1561 pEquation
->numBits
++;
1571 ****************************************************************************************************
1572 * EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1575 * Computes the surface address and bit position from a
1576 * coordinate for 2D tilied (macro tiled)
1579 ****************************************************************************************************
1581 UINT_64
EgBasedLib::ComputeSurfaceAddrFromCoordMacroTiled(
1582 UINT_32 x
, ///< [in] x coordinate
1583 UINT_32 y
, ///< [in] y coordinate
1584 UINT_32 slice
, ///< [in] slice index
1585 UINT_32 sample
, ///< [in] sample index
1586 UINT_32 bpp
, ///< [in] bits per pixel
1587 UINT_32 pitch
, ///< [in] surface pitch, in pixels
1588 UINT_32 height
, ///< [in] surface height, in pixels
1589 UINT_32 numSamples
, ///< [in] number of samples
1590 AddrTileMode tileMode
, ///< [in] tile mode
1591 AddrTileType microTileType
, ///< [in] micro tiling type
1592 BOOL_32 ignoreSE
, ///< [in] TRUE if shader enginers can be ignored
1593 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if it depth sample ordering is used
1594 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
1595 UINT_32 bankSwizzle
, ///< [in] bank swizzle
1596 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure
1597 /// **All fields to be valid on entry**
1598 UINT_32
* pBitPosition
///< [out] bit position, e.g. FMT_1 will use this
1603 UINT_32 microTileBytes
;
1604 UINT_32 microTileBits
;
1605 UINT_32 sampleOffset
;
1607 UINT_32 pixelOffset
;
1608 UINT_32 elementOffset
;
1609 UINT_32 tileSplitSlice
;
1613 UINT_64 sliceOffset
;
1614 UINT_32 macroTilePitch
;
1615 UINT_32 macroTileHeight
;
1616 UINT_32 macroTilesPerRow
;
1617 UINT_32 macroTilesPerSlice
;
1618 UINT_64 macroTileBytes
;
1619 UINT_32 macroTileIndexX
;
1620 UINT_32 macroTileIndexY
;
1621 UINT_64 macroTileOffset
;
1622 UINT_64 totalOffset
;
1623 UINT_64 pipeInterleaveMask
;
1624 UINT_64 bankInterleaveMask
;
1625 UINT_64 pipeInterleaveOffset
;
1626 UINT_32 bankInterleaveOffset
;
1628 UINT_32 tileRowIndex
;
1629 UINT_32 tileColumnIndex
;
1633 UINT_32 microTileThickness
= Thickness(tileMode
);
1636 // Compute the number of group, pipe, and bank bits.
1638 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1639 UINT_32 numPipeInterleaveBits
= Log2(m_pipeInterleaveBytes
);
1640 UINT_32 numPipeBits
= Log2(numPipes
);
1641 UINT_32 numBankInterleaveBits
= Log2(m_bankInterleave
);
1642 UINT_32 numBankBits
= Log2(pTileInfo
->banks
);
1645 // Compute the micro tile size.
1647 microTileBits
= MicroTilePixels
* microTileThickness
* bpp
* numSamples
;
1649 microTileBytes
= microTileBits
/ 8;
1651 // Compute the pixel index within the micro tile.
1653 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
1661 // Compute the sample offset and pixel offset.
1663 if (isDepthSampleOrder
)
1666 // For depth surfaces, samples are stored contiguously for each element, so the sample
1667 // offset is the sample number times the element size.
1669 sampleOffset
= sample
* bpp
;
1670 pixelOffset
= pixelIndex
* bpp
* numSamples
;
1675 // For color surfaces, all elements for a particular sample are stored contiguously, so
1676 // the sample offset is the sample number times the micro tile size divided yBit the number
1679 sampleOffset
= sample
* (microTileBits
/ numSamples
);
1680 pixelOffset
= pixelIndex
* bpp
;
1684 // Compute the element offset.
1686 elementOffset
= pixelOffset
+ sampleOffset
;
1688 *pBitPosition
= static_cast<UINT_32
>(elementOffset
% 8);
1690 elementOffset
/= 8; //bit-to-byte
1693 // Determine if tiles need to be split across slices.
1695 // If the size of the micro tile is larger than the tile split size, then the tile will be
1696 // split across multiple slices.
1698 UINT_32 slicesPerTile
= 1;
1700 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
1701 { //don't support for thick mode
1704 // Compute the number of slices per tile.
1706 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
1709 // Compute the tile split slice number for use in rotating the bank.
1711 tileSplitSlice
= elementOffset
/ pTileInfo
->tileSplitBytes
;
1714 // Adjust the element offset to account for the portion of the tile that is being moved to
1717 elementOffset
%= pTileInfo
->tileSplitBytes
;
1720 // Adjust the microTileBytes size to tileSplitBytes size since
1723 microTileBytes
= pTileInfo
->tileSplitBytes
;
1731 // Compute macro tile pitch and height.
1734 (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
) * pTileInfo
->macroAspectRatio
;
1736 (MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
) / pTileInfo
->macroAspectRatio
;
1739 // Compute the number of bytes per macro tile. Note: bytes of the same bank/pipe actually
1742 static_cast<UINT_64
>(microTileBytes
) *
1743 (macroTilePitch
/ MicroTileWidth
) * (macroTileHeight
/ MicroTileHeight
) /
1744 (numPipes
* pTileInfo
->banks
);
1747 // Compute the number of macro tiles per row.
1749 macroTilesPerRow
= pitch
/ macroTilePitch
;
1752 // Compute the offset to the macro tile containing the specified coordinate.
1754 macroTileIndexX
= x
/ macroTilePitch
;
1755 macroTileIndexY
= y
/ macroTileHeight
;
1756 macroTileOffset
= ((macroTileIndexY
* macroTilesPerRow
) + macroTileIndexX
) * macroTileBytes
;
1759 // Compute the number of macro tiles per slice.
1761 macroTilesPerSlice
= macroTilesPerRow
* (height
/ macroTileHeight
);
1764 // Compute the slice size.
1766 sliceBytes
= macroTilesPerSlice
* macroTileBytes
;
1769 // Compute the slice offset.
1771 sliceOffset
= sliceBytes
* (tileSplitSlice
+ slicesPerTile
* (slice
/ microTileThickness
));
1774 // Compute tile offest
1776 tileRowIndex
= (y
/ MicroTileHeight
) % pTileInfo
->bankHeight
;
1777 tileColumnIndex
= ((x
/ MicroTileWidth
) / numPipes
) % pTileInfo
->bankWidth
;
1778 tileIndex
= (tileRowIndex
* pTileInfo
->bankWidth
) + tileColumnIndex
;
1779 tileOffset
= tileIndex
* microTileBytes
;
1782 // Combine the slice offset and macro tile offset with the pixel and sample offsets, accounting
1783 // for the pipe and bank bits in the middle of the address.
1785 totalOffset
= sliceOffset
+ macroTileOffset
+ elementOffset
+ tileOffset
;
1788 // Get the pipe and bank.
1791 // when the tileMode is PRT type, then adjust x and y coordinates
1792 if (IsPrtNoRotationTileMode(tileMode
))
1794 x
= x
% macroTilePitch
;
1795 y
= y
% macroTileHeight
;
1798 pipe
= ComputePipeFromCoord(x
,
1806 bank
= ComputeBankFromCoord(x
,
1815 // Split the offset to put some bits below the pipe+bank bits and some above.
1817 pipeInterleaveMask
= (1 << numPipeInterleaveBits
) - 1;
1818 bankInterleaveMask
= (1 << numBankInterleaveBits
) - 1;
1819 pipeInterleaveOffset
= totalOffset
& pipeInterleaveMask
;
1820 bankInterleaveOffset
= static_cast<UINT_32
>((totalOffset
>> numPipeInterleaveBits
) &
1821 bankInterleaveMask
);
1822 offset
= totalOffset
>> (numPipeInterleaveBits
+ numBankInterleaveBits
);
1825 // Assemble the address from its components.
1827 addr
= pipeInterleaveOffset
;
1828 // This is to remove /analyze warnings
1829 UINT_32 pipeBits
= pipe
<< numPipeInterleaveBits
;
1830 UINT_32 bankInterleaveBits
= bankInterleaveOffset
<< (numPipeInterleaveBits
+ numPipeBits
);
1831 UINT_32 bankBits
= bank
<< (numPipeInterleaveBits
+ numPipeBits
+
1832 numBankInterleaveBits
);
1833 UINT_64 offsetBits
= offset
<< (numPipeInterleaveBits
+ numPipeBits
+
1834 numBankInterleaveBits
+ numBankBits
);
1837 addr
|= bankInterleaveBits
;
1845 ****************************************************************************************************
1846 * EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1849 * Computes the surface address and bit position from a coordinate for 1D tilied
1853 ****************************************************************************************************
1855 UINT_64
EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled(
1856 UINT_32 x
, ///< [in] x coordinate
1857 UINT_32 y
, ///< [in] y coordinate
1858 UINT_32 slice
, ///< [in] slice index
1859 UINT_32 sample
, ///< [in] sample index
1860 UINT_32 bpp
, ///< [in] bits per pixel
1861 UINT_32 pitch
, ///< [in] pitch, in pixels
1862 UINT_32 height
, ///< [in] height, in pixels
1863 UINT_32 numSamples
, ///< [in] number of samples
1864 AddrTileMode tileMode
, ///< [in] tile mode
1865 AddrTileType microTileType
, ///< [in] micro tiling type
1866 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if depth sample ordering is used
1867 UINT_32
* pBitPosition
///< [out] bit position, e.g. FMT_1 will use this
1872 UINT_32 microTileBytes
;
1874 UINT_32 microTilesPerRow
;
1875 UINT_32 microTileIndexX
;
1876 UINT_32 microTileIndexY
;
1877 UINT_32 microTileIndexZ
;
1878 UINT_64 sliceOffset
;
1879 UINT_64 microTileOffset
;
1880 UINT_32 sampleOffset
;
1882 UINT_32 pixelOffset
;
1884 UINT_32 microTileThickness
= Thickness(tileMode
);
1887 // Compute the micro tile size.
1889 microTileBytes
= BITS_TO_BYTES(MicroTilePixels
* microTileThickness
* bpp
* numSamples
);
1892 // Compute the slice size.
1895 BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* microTileThickness
* bpp
* numSamples
);
1898 // Compute the number of micro tiles per row.
1900 microTilesPerRow
= pitch
/ MicroTileWidth
;
1903 // Compute the micro tile index.
1905 microTileIndexX
= x
/ MicroTileWidth
;
1906 microTileIndexY
= y
/ MicroTileHeight
;
1907 microTileIndexZ
= slice
/ microTileThickness
;
1910 // Compute the slice offset.
1912 sliceOffset
= static_cast<UINT_64
>(microTileIndexZ
) * sliceBytes
;
1915 // Compute the offset to the micro tile containing the specified coordinate.
1917 microTileOffset
= (static_cast<UINT_64
>(microTileIndexY
) * microTilesPerRow
+ microTileIndexX
) *
1921 // Compute the pixel index within the micro tile.
1923 pixelIndex
= ComputePixelIndexWithinMicroTile(x
,
1930 // Compute the sample offset.
1932 if (isDepthSampleOrder
)
1935 // For depth surfaces, samples are stored contiguously for each element, so the sample
1936 // offset is the sample number times the element size.
1938 sampleOffset
= sample
* bpp
;
1939 pixelOffset
= pixelIndex
* bpp
* numSamples
;
1944 // For color surfaces, all elements for a particular sample are stored contiguously, so
1945 // the sample offset is the sample number times the micro tile size divided yBit the number
1948 sampleOffset
= sample
* (microTileBytes
*8 / numSamples
);
1949 pixelOffset
= pixelIndex
* bpp
;
1953 // Compute the bit position of the pixel. Each element is stored with one bit per sample.
1956 UINT_32 elemOffset
= sampleOffset
+ pixelOffset
;
1958 *pBitPosition
= elemOffset
% 8;
1962 // Combine the slice offset, micro tile offset, sample offset, and pixel offsets.
1964 addr
= sliceOffset
+ microTileOffset
+ elemOffset
;
1970 ****************************************************************************************************
1971 * EgBasedLib::HwlComputePixelCoordFromOffset
1974 * Compute pixel coordinate from offset inside a micro tile
1977 ****************************************************************************************************
1979 VOID
EgBasedLib::HwlComputePixelCoordFromOffset(
1980 UINT_32 offset
, ///< [in] offset inside micro tile in bits
1981 UINT_32 bpp
, ///< [in] bits per pixel
1982 UINT_32 numSamples
, ///< [in] number of samples
1983 AddrTileMode tileMode
, ///< [in] tile mode
1984 UINT_32 tileBase
, ///< [in] base offset within a tile
1985 UINT_32 compBits
, ///< [in] component bits actually needed(for planar surface)
1986 UINT_32
* pX
, ///< [out] x coordinate
1987 UINT_32
* pY
, ///< [out] y coordinate
1988 UINT_32
* pSlice
, ///< [out] slice index
1989 UINT_32
* pSample
, ///< [out] sample index
1990 AddrTileType microTileType
, ///< [in] micro tiling type
1991 BOOL_32 isDepthSampleOrder
///< [in] TRUE if depth sample order in microtile is used
1997 UINT_32 thickness
= Thickness(tileMode
);
1999 // For planar surface, we adjust offset acoording to tile base
2000 if ((bpp
!= compBits
) && (compBits
!= 0) && isDepthSampleOrder
)
2004 ADDR_ASSERT(microTileType
== ADDR_NON_DISPLAYABLE
||
2005 microTileType
== ADDR_DEPTH_SAMPLE_ORDER
);
2010 UINT_32 sampleTileBits
;
2011 UINT_32 samplePixelBits
;
2014 if (isDepthSampleOrder
)
2016 samplePixelBits
= bpp
* numSamples
;
2017 pixelIndex
= offset
/ samplePixelBits
;
2018 *pSample
= (offset
% samplePixelBits
) / bpp
;
2022 sampleTileBits
= MicroTilePixels
* bpp
* thickness
;
2023 *pSample
= offset
/ sampleTileBits
;
2024 pixelIndex
= (offset
% sampleTileBits
) / bpp
;
2027 if (microTileType
!= ADDR_THICK
)
2029 if (microTileType
== ADDR_DISPLAYABLE
) // displayable
2034 x
= pixelIndex
& 0x7;
2035 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,4));
2038 x
= pixelIndex
& 0x7;
2039 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,3));
2042 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,1),_BIT(pixelIndex
,0));
2043 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,2));
2046 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2047 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
2050 x
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,2),_BIT(pixelIndex
,1));
2051 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,0));
2057 else if (microTileType
== ADDR_NON_DISPLAYABLE
|| microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2059 x
= Bits2Number(3, _BIT(pixelIndex
,4),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2060 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
2062 else if (microTileType
== ADDR_ROTATED
)
2066 element_index[5:0] = { x[2], x[0], x[1], y[2], y[1], y[0] }
2069 element_index[5:0] = { x[2], x[1], x[0], y[2], y[1], y[0] }
2072 element_index[5:0] = { x[2], x[1], y[2], x[0], y[1], y[0] }
2075 element_index[5:0] = { y[2], x[2], x[1], y[1], x[0], y[0] }
2080 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3),_BIT(pixelIndex
,4));
2081 y
= pixelIndex
& 0x7;
2084 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,3));
2085 y
= pixelIndex
& 0x7;
2088 x
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4),_BIT(pixelIndex
,2));
2089 y
= Bits2Number(3, _BIT(pixelIndex
,3),_BIT(pixelIndex
,1),_BIT(pixelIndex
,0));
2092 x
= Bits2Number(3, _BIT(pixelIndex
,4),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
2093 y
= Bits2Number(3, _BIT(pixelIndex
,5),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2096 ADDR_ASSERT_ALWAYS();
2101 if (thickness
> 1) // thick
2103 z
= Bits2Number(3, _BIT(pixelIndex
,8),_BIT(pixelIndex
,7),_BIT(pixelIndex
,6));
2108 ADDR_ASSERT((m_chipFamily
>= ADDR_CHIP_FAMILY_CI
) && (thickness
> 1));
2110 8-Bit Elements and 16-Bit Elements
2111 element_index[7:0] = { y[2], x[2], z[1], z[0], y[1], x[1], y[0], x[0] }
2114 element_index[7:0] = { y[2], x[2], z[1], y[1], z[0], x[1], y[0], x[0] }
2116 64-Bit Elements and 128-Bit Elements
2117 element_index[7:0] = { y[2], x[2], z[1], y[1], x[1], z[0], y[0], x[0] }
2119 The equation to compute the element index for the extra thick tile:
2120 element_index[8] = z[2]
2125 case 16: // fall-through
2126 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2127 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,3),_BIT(pixelIndex
,1));
2128 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,4));
2131 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,2),_BIT(pixelIndex
,0));
2132 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
2133 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,3));
2136 case 128: // fall-through
2137 x
= Bits2Number(3, _BIT(pixelIndex
,6),_BIT(pixelIndex
,3),_BIT(pixelIndex
,0));
2138 y
= Bits2Number(3, _BIT(pixelIndex
,7),_BIT(pixelIndex
,4),_BIT(pixelIndex
,1));
2139 z
= Bits2Number(2, _BIT(pixelIndex
,5),_BIT(pixelIndex
,2));
2142 ADDR_ASSERT_ALWAYS();
2148 z
+= Bits2Number(3,_BIT(pixelIndex
,8),0,0);
2158 ****************************************************************************************************
2159 * EgBasedLib::DispatchComputeSurfaceCoordFromAddrDispatch
2162 * Compute (x,y,slice,sample) coordinates from surface address
2165 ****************************************************************************************************
2167 VOID
EgBasedLib::DispatchComputeSurfaceCoordFromAddr(
2168 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
2169 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
2172 UINT_64 addr
= pIn
->addr
;
2173 UINT_32 bitPosition
= pIn
->bitPosition
;
2174 UINT_32 bpp
= pIn
->bpp
;
2175 UINT_32 pitch
= pIn
->pitch
;
2176 UINT_32 height
= pIn
->height
;
2177 UINT_32 numSlices
= pIn
->numSlices
;
2178 UINT_32 numSamples
= ((pIn
->numSamples
== 0) ? 1 : pIn
->numSamples
);
2179 UINT_32 numFrags
= ((pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
);
2180 AddrTileMode tileMode
= pIn
->tileMode
;
2181 UINT_32 tileBase
= pIn
->tileBase
;
2182 UINT_32 compBits
= pIn
->compBits
;
2183 AddrTileType microTileType
= pIn
->tileType
;
2184 BOOL_32 ignoreSE
= pIn
->ignoreSE
;
2185 BOOL_32 isDepthSampleOrder
= pIn
->isDepth
;
2186 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2188 UINT_32
* pX
= &pOut
->x
;
2189 UINT_32
* pY
= &pOut
->y
;
2190 UINT_32
* pSlice
= &pOut
->slice
;
2191 UINT_32
* pSample
= &pOut
->sample
;
2193 if (microTileType
== ADDR_DEPTH_SAMPLE_ORDER
)
2195 isDepthSampleOrder
= TRUE
;
2198 if (m_chipFamily
>= ADDR_CHIP_FAMILY_NI
)
2200 if (numFrags
!= numSamples
)
2202 numSamples
= numFrags
;
2206 /// 128 bit/thick tiled surface doesn't support display tiling and
2207 /// mipmap chain must have the same tileType, so please fill tileType correctly
2208 if (IsLinear(pIn
->tileMode
) == FALSE
)
2210 if (bpp
>= 128 || Thickness(tileMode
) > 1)
2212 ADDR_ASSERT(microTileType
!= ADDR_DISPLAYABLE
);
2219 case ADDR_TM_LINEAR_GENERAL
://fall through
2220 case ADDR_TM_LINEAR_ALIGNED
:
2221 ComputeSurfaceCoordFromAddrLinear(addr
,
2232 case ADDR_TM_1D_TILED_THIN1
://fall through
2233 case ADDR_TM_1D_TILED_THICK
:
2234 ComputeSurfaceCoordFromAddrMicroTiled(addr
,
2248 isDepthSampleOrder
);
2250 case ADDR_TM_2D_TILED_THIN1
: //fall through
2251 case ADDR_TM_2D_TILED_THICK
: //fall through
2252 case ADDR_TM_3D_TILED_THIN1
: //fall through
2253 case ADDR_TM_3D_TILED_THICK
: //fall through
2254 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2255 case ADDR_TM_3D_TILED_XTHICK
: //fall through
2256 case ADDR_TM_PRT_TILED_THIN1
: //fall through
2257 case ADDR_TM_PRT_2D_TILED_THIN1
://fall through
2258 case ADDR_TM_PRT_3D_TILED_THIN1
://fall through
2259 case ADDR_TM_PRT_TILED_THICK
: //fall through
2260 case ADDR_TM_PRT_2D_TILED_THICK
://fall through
2261 case ADDR_TM_PRT_3D_TILED_THICK
:
2262 UINT_32 pipeSwizzle
;
2263 UINT_32 bankSwizzle
;
2265 if (m_configFlags
.useCombinedSwizzle
)
2267 ExtractBankPipeSwizzle(pIn
->tileSwizzle
, pIn
->pTileInfo
,
2268 &bankSwizzle
, &pipeSwizzle
);
2272 pipeSwizzle
= pIn
->pipeSwizzle
;
2273 bankSwizzle
= pIn
->bankSwizzle
;
2276 ComputeSurfaceCoordFromAddrMacroTiled(addr
,
2297 ADDR_ASSERT_ALWAYS();
2302 ****************************************************************************************************
2303 * EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled
2306 * Compute surface coordinates from address for macro tiled surface
2309 ****************************************************************************************************
2311 VOID
EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled(
2312 UINT_64 addr
, ///< [in] byte address
2313 UINT_32 bitPosition
, ///< [in] bit position
2314 UINT_32 bpp
, ///< [in] bits per pixel
2315 UINT_32 pitch
, ///< [in] pitch in pixels
2316 UINT_32 height
, ///< [in] height in pixels
2317 UINT_32 numSamples
, ///< [in] number of samples
2318 AddrTileMode tileMode
, ///< [in] tile mode
2319 UINT_32 tileBase
, ///< [in] tile base offset
2320 UINT_32 compBits
, ///< [in] component bits (for planar surface)
2321 AddrTileType microTileType
, ///< [in] micro tiling type
2322 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines can be ignored
2323 BOOL_32 isDepthSampleOrder
, ///< [in] TRUE if depth sample order is used
2324 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2325 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2326 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure.
2327 /// **All fields to be valid on entry**
2328 UINT_32
* pX
, ///< [out] X coord
2329 UINT_32
* pY
, ///< [out] Y coord
2330 UINT_32
* pSlice
, ///< [out] slice index
2331 UINT_32
* pSample
///< [out] sample index
2337 UINT_64 macroTileBits
;
2340 UINT_64 elementOffset
;
2341 UINT_64 macroTileIndex
;
2343 UINT_64 totalOffset
;
2347 UINT_32 groupBits
= m_pipeInterleaveBytes
<< 3;
2348 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2349 UINT_32 banks
= pTileInfo
->banks
;
2351 UINT_32 bankInterleave
= m_bankInterleave
;
2353 UINT_64 addrBits
= BYTES_TO_BITS(addr
) + bitPosition
;
2356 // remove bits for bank and pipe
2358 totalOffset
= (addrBits
% groupBits
) +
2359 (((addrBits
/ groupBits
/ pipes
) % bankInterleave
) * groupBits
) +
2360 (((addrBits
/ groupBits
/ pipes
) / bankInterleave
) / banks
) * groupBits
* bankInterleave
;
2362 UINT_32 microTileThickness
= Thickness(tileMode
);
2364 UINT_32 microTileBits
= bpp
* microTileThickness
* MicroTilePixels
* numSamples
;
2366 UINT_32 microTileBytes
= BITS_TO_BYTES(microTileBits
);
2368 // Determine if tiles need to be split across slices.
2370 // If the size of the micro tile is larger than the tile split size, then the tile will be
2371 // split across multiple slices.
2373 UINT_32 slicesPerTile
= 1; //_State->TileSlices
2375 if ((microTileBytes
> pTileInfo
->tileSplitBytes
) && (microTileThickness
== 1))
2376 { //don't support for thick mode
2379 // Compute the number of slices per tile.
2381 slicesPerTile
= microTileBytes
/ pTileInfo
->tileSplitBytes
;
2384 tileBits
= microTileBits
/ slicesPerTile
; // micro tile bits
2386 // in micro tiles because not MicroTileWidth timed.
2387 UINT_32 macroWidth
= pTileInfo
->bankWidth
* pipes
* pTileInfo
->macroAspectRatio
;
2388 // in micro tiles as well
2389 UINT_32 macroHeight
= pTileInfo
->bankHeight
* banks
/ pTileInfo
->macroAspectRatio
;
2391 UINT_32 pitchInMacroTiles
= pitch
/ MicroTileWidth
/ macroWidth
;
2393 macroTileBits
= (macroWidth
* macroHeight
) * tileBits
/ (banks
* pipes
);
2395 macroTileIndex
= totalOffset
/ macroTileBits
;
2397 // pitchMacros * height / heightMacros; macroTilesPerSlice == _State->SliceMacros
2398 UINT_32 macroTilesPerSlice
= (pitch
/ (macroWidth
* MicroTileWidth
)) * height
/
2399 (macroHeight
* MicroTileWidth
);
2401 slices
= static_cast<UINT_32
>(macroTileIndex
/ macroTilesPerSlice
);
2403 *pSlice
= static_cast<UINT_32
>(slices
/ slicesPerTile
* microTileThickness
);
2406 // calculate element offset and x[2:0], y[2:0], z[1:0] for thick
2408 tileSlices
= slices
% slicesPerTile
;
2410 elementOffset
= tileSlices
* tileBits
;
2411 elementOffset
+= totalOffset
% tileBits
;
2415 HwlComputePixelCoordFromOffset(static_cast<UINT_32
>(elementOffset
),
2426 isDepthSampleOrder
);
2428 macroTileIndex
= macroTileIndex
% macroTilesPerSlice
;
2429 *pY
+= static_cast<UINT_32
>(macroTileIndex
/ pitchInMacroTiles
* macroHeight
* MicroTileHeight
);
2430 *pX
+= static_cast<UINT_32
>(macroTileIndex
% pitchInMacroTiles
* macroWidth
* MicroTileWidth
);
2434 tileIndex
= static_cast<UINT_32
>((totalOffset
% macroTileBits
) / tileBits
);
2436 my
= (tileIndex
/ pTileInfo
->bankWidth
) % pTileInfo
->bankHeight
* MicroTileHeight
;
2437 mx
= (tileIndex
% pTileInfo
->bankWidth
) * pipes
* MicroTileWidth
;
2442 bank
= ComputeBankFromAddr(addr
, banks
, pipes
);
2443 pipe
= ComputePipeFromAddr(addr
, pipes
);
2445 HwlComputeSurfaceCoord2DFromBankPipe(tileMode
,
2459 ****************************************************************************************************
2460 * EgBasedLib::ComputeSurfaceCoord2DFromBankPipe
2463 * Compute surface x,y coordinates from bank/pipe info
2466 ****************************************************************************************************
2468 VOID
EgBasedLib::ComputeSurfaceCoord2DFromBankPipe(
2469 AddrTileMode tileMode
, ///< [in] tile mode
2470 UINT_32 x
, ///< [in] x coordinate
2471 UINT_32 y
, ///< [in] y coordinate
2472 UINT_32 slice
, ///< [in] slice index
2473 UINT_32 bank
, ///< [in] bank number
2474 UINT_32 pipe
, ///< [in] pipe number
2475 UINT_32 bankSwizzle
,///< [in] bank swizzle
2476 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
2477 UINT_32 tileSlices
, ///< [in] slices in a micro tile
2478 ADDR_TILEINFO
* pTileInfo
, ///< [in] bank structure. **All fields to be valid on entry**
2479 CoordFromBankPipe
* pOutput
///< [out] pointer to extracted x/y bits
2491 UINT_32 tileSplitRotation
;
2493 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2495 UINT_32 bankRotation
= ComputeBankRotation(tileMode
,
2496 pTileInfo
->banks
, numPipes
);
2498 UINT_32 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2500 UINT_32 xBit
= x
/ (MicroTileWidth
* pTileInfo
->bankWidth
* numPipes
);
2501 UINT_32 yBit
= y
/ (MicroTileHeight
* pTileInfo
->bankHeight
);
2503 //calculate the bank and pipe before rotation and swizzle
2507 case ADDR_TM_2D_TILED_THIN1
: //fall through
2508 case ADDR_TM_2D_TILED_THICK
: //fall through
2509 case ADDR_TM_2D_TILED_XTHICK
: //fall through
2510 case ADDR_TM_3D_TILED_THIN1
: //fall through
2511 case ADDR_TM_3D_TILED_THICK
: //fall through
2512 case ADDR_TM_3D_TILED_XTHICK
:
2513 tileSplitRotation
= ((pTileInfo
->banks
/ 2) + 1);
2516 tileSplitRotation
= 0;
2520 UINT_32 microTileThickness
= Thickness(tileMode
);
2522 bank
^= tileSplitRotation
* tileSlices
;
2523 if (pipeRotation
== 0)
2525 bank
^= bankRotation
* (slice
/ microTileThickness
) + bankSwizzle
;
2526 bank
%= pTileInfo
->banks
;
2527 pipe
^= pipeSwizzle
;
2531 bank
^= bankRotation
* (slice
/ microTileThickness
) / numPipes
+ bankSwizzle
;
2532 bank
%= pTileInfo
->banks
;
2533 pipe
^= pipeRotation
* (slice
/ microTileThickness
) + pipeSwizzle
;
2536 if (pTileInfo
->macroAspectRatio
== 1)
2538 switch (pTileInfo
->banks
)
2541 yBit3
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2544 yBit4
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2545 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2548 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2549 yBit5
= _BIT(bank
, 0) ^ _BIT(xBit
,0);
2550 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ yBit5
;
2553 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3);
2554 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2);
2555 yBit6
= _BIT(bank
, 0) ^ _BIT(xBit
, 0);
2556 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ yBit6
;
2563 else if (pTileInfo
->macroAspectRatio
== 2)
2565 switch (pTileInfo
->banks
)
2567 case 2: //xBit3 = yBit3^b0
2568 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,0);
2570 case 4: //xBit3=yBit4^b0; yBit3=xBit4^b1
2571 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2572 yBit3
= _BIT(bank
, 1) ^ _BIT(xBit
,1);
2574 case 8: //xBit4, xBit5, yBit5 are known
2575 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2576 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2577 yBit4
= _BIT(bank
, 1) ^ _BIT(xBit
,1) ^ _BIT(yBit
, 2);
2579 case 16://x4,x5,x6,y6 are known
2580 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3); //x3 = y6 ^ b0
2581 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2582 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = x5 ^ b2
2583 yBit5
= _BIT(bank
, 1) ^ _BIT(xBit
, 1) ^ _BIT(yBit
, 3); //y5=x4^y6^b1
2589 else if (pTileInfo
->macroAspectRatio
== 4)
2591 switch (pTileInfo
->banks
)
2593 case 4: //yBit3, yBit4
2594 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,1);
2595 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,0);
2597 case 8: //xBit5, yBit4, yBit5
2598 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2);
2599 yBit3
= _BIT(bank
, 2) ^ _BIT(xBit
,2);
2600 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
,2);
2602 case 16: //xBit5, xBit6, yBit5, yBit6
2603 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = b0 ^ y6
2604 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = b1 ^ y5 ^ y6;
2605 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = b3 ^ x6;
2606 yBit4
= _BIT(bank
, 2) ^ _BIT(xBit
, 2); //y4 = b2 ^ x5;
2612 else if (pTileInfo
->macroAspectRatio
== 8)
2614 switch (pTileInfo
->banks
)
2616 case 8: //yBit3, yBit4, yBit5
2617 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
,2); //x3 = b0 ^ y5;
2618 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
,1) ^ _BIT(yBit
, 2);//x4 = b1 ^ y4 ^ y5;
2619 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
,0);
2621 case 16: //xBit6, yBit4, yBit5, yBit6
2622 xBit3
= _BIT(bank
, 0) ^ _BIT(yBit
, 3);//x3 = y6 ^ b0
2623 xBit4
= _BIT(bank
, 1) ^ _BIT(yBit
, 2) ^ _BIT(yBit
, 3);//x4 = y5 ^ y6 ^ b1
2624 xBit5
= _BIT(bank
, 2) ^ _BIT(yBit
, 1);//x5 = y4 ^ b2
2625 yBit3
= _BIT(bank
, 3) ^ _BIT(xBit
, 3); //y3 = x6 ^ b3
2632 pOutput
->xBits
= xBit
;
2633 pOutput
->yBits
= yBit
;
2635 pOutput
->xBit3
= xBit3
;
2636 pOutput
->xBit4
= xBit4
;
2637 pOutput
->xBit5
= xBit5
;
2638 pOutput
->yBit3
= yBit3
;
2639 pOutput
->yBit4
= yBit4
;
2640 pOutput
->yBit5
= yBit5
;
2641 pOutput
->yBit6
= yBit6
;
2645 ****************************************************************************************************
2646 * EgBasedLib::HwlExtractBankPipeSwizzle
2648 * Entry of EgBasedLib ExtractBankPipeSwizzle
2651 ****************************************************************************************************
2653 ADDR_E_RETURNCODE
EgBasedLib::HwlExtractBankPipeSwizzle(
2654 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT
* pIn
, ///< [in] input structure
2655 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT
* pOut
///< [out] output structure
2658 ExtractBankPipeSwizzle(pIn
->base256b
,
2661 &pOut
->pipeSwizzle
);
2667 ****************************************************************************************************
2668 * EgBasedLib::HwlCombineBankPipeSwizzle
2670 * Combine bank/pipe swizzle
2673 ****************************************************************************************************
2675 ADDR_E_RETURNCODE
EgBasedLib::HwlCombineBankPipeSwizzle(
2676 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2677 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2678 ADDR_TILEINFO
* pTileInfo
, ///< [in] tile info
2679 UINT_64 baseAddr
, ///< [in] base address
2680 UINT_32
* pTileSwizzle
///< [out] combined swizzle
2683 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
2687 *pTileSwizzle
= GetBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, baseAddr
, pTileInfo
);
2691 retCode
= ADDR_INVALIDPARAMS
;
2698 ****************************************************************************************************
2699 * EgBasedLib::HwlComputeBaseSwizzle
2701 * Compute base swizzle
2704 ****************************************************************************************************
2706 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeBaseSwizzle(
2707 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT
* pIn
,
2708 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT
* pOut
2711 UINT_32 bankSwizzle
= 0;
2712 UINT_32 pipeSwizzle
= 0;
2713 ADDR_TILEINFO
* pTileInfo
= pIn
->pTileInfo
;
2715 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
2716 ADDR_ASSERT(pIn
->pTileInfo
);
2718 /// This is a legacy misreading of h/w doc, use it as it doesn't hurt.
2719 static const UINT_8 bankRotationArray
[4][16] = {
2720 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_2_BANK
2721 { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_4_BANK
2722 { 0, 3, 6, 1, 4, 7, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_8_BANK
2723 { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }, // ADDR_SURF_16_BANK
2726 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2728 UINT_32 banks
= pTileInfo
? pTileInfo
->banks
: 2;
2731 // Uses less bank swizzle bits
2732 if (pIn
->option
.reduceBankBit
&& banks
> 2)
2752 ADDR_ASSERT_ALWAYS();
2757 if (pIn
->option
.genOption
== ADDR_SWIZZLE_GEN_LINEAR
)
2759 bankSwizzle
= pIn
->surfIndex
& (banks
- 1);
2761 else // (pIn->option.genOption == ADDR_SWIZZLE_GEN_DEFAULT)
2763 bankSwizzle
= bankRotationArray
[hwNumBanks
][pIn
->surfIndex
& (banks
- 1)];
2766 if (IsMacro3dTiled(pIn
->tileMode
))
2768 pipeSwizzle
= pIn
->surfIndex
& (HwlGetPipes(pTileInfo
) - 1);
2771 return HwlCombineBankPipeSwizzle(bankSwizzle
, pipeSwizzle
, pTileInfo
, 0, &pOut
->tileSwizzle
);
2775 ****************************************************************************************************
2776 * EgBasedLib::ExtractBankPipeSwizzle
2778 * Extract bank/pipe swizzle from base256b
2781 ****************************************************************************************************
2783 VOID
EgBasedLib::ExtractBankPipeSwizzle(
2784 UINT_32 base256b
, ///< [in] input base256b register value
2785 ADDR_TILEINFO
* pTileInfo
, ///< [in] 2D tile parameters. Client must provide all data
2786 UINT_32
* pBankSwizzle
, ///< [out] bank swizzle
2787 UINT_32
* pPipeSwizzle
///< [out] pipe swizzle
2790 UINT_32 bankSwizzle
= 0;
2791 UINT_32 pipeSwizzle
= 0;
2795 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2796 UINT_32 bankBits
= QLog2(pTileInfo
->banks
);
2797 UINT_32 pipeBits
= QLog2(numPipes
);
2798 UINT_32 groupBytes
= m_pipeInterleaveBytes
;
2799 UINT_32 bankInterleave
= m_bankInterleave
;
2802 (base256b
/ (groupBytes
>> 8)) & ((1<<pipeBits
)-1);
2805 (base256b
/ (groupBytes
>> 8) / numPipes
/ bankInterleave
) & ((1 << bankBits
) - 1);
2808 *pPipeSwizzle
= pipeSwizzle
;
2809 *pBankSwizzle
= bankSwizzle
;
2813 ****************************************************************************************************
2814 * EgBasedLib::GetBankPipeSwizzle
2816 * Combine bank/pipe swizzle
2818 * Base256b bits (only filled bank/pipe bits)
2819 ****************************************************************************************************
2821 UINT_32
EgBasedLib::GetBankPipeSwizzle(
2822 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2823 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
2824 UINT_64 baseAddr
, ///< [in] base address
2825 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2828 UINT_32 pipeBits
= QLog2(HwlGetPipes(pTileInfo
));
2829 UINT_32 bankInterleaveBits
= QLog2(m_bankInterleave
);
2830 UINT_32 tileSwizzle
= pipeSwizzle
+ ((bankSwizzle
<< bankInterleaveBits
) << pipeBits
);
2832 baseAddr
^= tileSwizzle
* m_pipeInterleaveBytes
;
2835 return static_cast<UINT_32
>(baseAddr
);
2839 ****************************************************************************************************
2840 * EgBasedLib::ComputeSliceTileSwizzle
2842 * Compute cubemap/3d texture faces/slices tile swizzle
2845 ****************************************************************************************************
2847 UINT_32
EgBasedLib::ComputeSliceTileSwizzle(
2848 AddrTileMode tileMode
, ///< [in] Tile mode
2849 UINT_32 baseSwizzle
, ///< [in] Base swizzle
2850 UINT_32 slice
, ///< [in] Slice index, Cubemap face index, 0 means +X
2851 UINT_64 baseAddr
, ///< [in] Base address
2852 ADDR_TILEINFO
* pTileInfo
///< [in] Bank structure
2855 UINT_32 tileSwizzle
= 0;
2857 if (IsMacroTiled(tileMode
)) // Swizzle only for macro tile mode
2859 UINT_32 firstSlice
= slice
/ Thickness(tileMode
);
2861 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
2862 UINT_32 numBanks
= pTileInfo
->banks
;
2864 UINT_32 pipeRotation
;
2865 UINT_32 bankRotation
;
2867 UINT_32 bankSwizzle
= 0;
2868 UINT_32 pipeSwizzle
= 0;
2870 pipeRotation
= ComputePipeRotation(tileMode
, numPipes
);
2871 bankRotation
= ComputeBankRotation(tileMode
, numBanks
, numPipes
);
2873 if (baseSwizzle
!= 0)
2875 ExtractBankPipeSwizzle(baseSwizzle
,
2881 if (pipeRotation
== 0) //2D mode
2883 bankSwizzle
+= firstSlice
* bankRotation
;
2884 bankSwizzle
%= numBanks
;
2888 pipeSwizzle
+= firstSlice
* pipeRotation
;
2889 pipeSwizzle
%= numPipes
;
2890 bankSwizzle
+= firstSlice
* bankRotation
/ numPipes
;
2891 bankSwizzle
%= numBanks
;
2894 tileSwizzle
= GetBankPipeSwizzle(bankSwizzle
,
2904 ****************************************************************************************************
2905 * EgBasedLib::HwlComputeQbStereoRightSwizzle
2908 * Compute right eye swizzle
2911 ****************************************************************************************************
2913 UINT_32
EgBasedLib::HwlComputeQbStereoRightSwizzle(
2914 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pInfo
///< [in] Surface info, must be valid
2917 UINT_32 bankBits
= 0;
2918 UINT_32 swizzle
= 0;
2920 // The assumption is default swizzle for left eye is 0
2921 if (IsMacroTiled(pInfo
->tileMode
) && pInfo
->pStereoInfo
&& pInfo
->pTileInfo
)
2923 bankBits
= ComputeBankFromCoord(0, pInfo
->height
, 0,
2924 pInfo
->tileMode
, 0, 0, pInfo
->pTileInfo
);
2928 HwlCombineBankPipeSwizzle(bankBits
, 0, pInfo
->pTileInfo
, 0, &swizzle
);
2936 ****************************************************************************************************
2937 * EgBasedLib::ComputeBankFromCoord
2940 * Compute bank number from coordinates
2943 ****************************************************************************************************
2945 UINT_32
EgBasedLib::ComputeBankFromCoord(
2946 UINT_32 x
, ///< [in] x coordinate
2947 UINT_32 y
, ///< [in] y coordinate
2948 UINT_32 slice
, ///< [in] slice index
2949 AddrTileMode tileMode
, ///< [in] tile mode
2950 UINT_32 bankSwizzle
, ///< [in] bank swizzle
2951 UINT_32 tileSplitSlice
, ///< [in] If the size of the pixel offset is larger than the
2952 /// tile split size, then the pixel will be moved to a separate
2953 /// slice. This value equals pixelOffset / tileSplitBytes
2954 /// in this case. Otherwise this is 0.
2955 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2958 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
2959 UINT_32 bankBit0
= 0;
2960 UINT_32 bankBit1
= 0;
2961 UINT_32 bankBit2
= 0;
2962 UINT_32 bankBit3
= 0;
2963 UINT_32 sliceRotation
;
2964 UINT_32 tileSplitRotation
;
2966 UINT_32 numBanks
= pTileInfo
->banks
;
2967 UINT_32 bankWidth
= pTileInfo
->bankWidth
;
2968 UINT_32 bankHeight
= pTileInfo
->bankHeight
;
2970 UINT_32 tx
= x
/ MicroTileWidth
/ (bankWidth
* pipes
);
2971 UINT_32 ty
= y
/ MicroTileHeight
/ bankHeight
;
2973 UINT_32 x3
= _BIT(tx
,0);
2974 UINT_32 x4
= _BIT(tx
,1);
2975 UINT_32 x5
= _BIT(tx
,2);
2976 UINT_32 x6
= _BIT(tx
,3);
2977 UINT_32 y3
= _BIT(ty
,0);
2978 UINT_32 y4
= _BIT(ty
,1);
2979 UINT_32 y5
= _BIT(ty
,2);
2980 UINT_32 y6
= _BIT(ty
,3);
2986 bankBit1
= x4
^ y5
^ y6
;
2992 bankBit1
= x4
^ y4
^ y5
;
3003 ADDR_ASSERT_ALWAYS();
3007 bank
= bankBit0
| (bankBit1
<< 1) | (bankBit2
<< 2) | (bankBit3
<< 3);
3009 //Bits2Number(4, bankBit3, bankBit2, bankBit1, bankBit0);
3011 bank
= HwlPreAdjustBank((x
/ MicroTileWidth
), bank
, pTileInfo
);
3013 // Compute bank rotation for the slice.
3015 UINT_32 microTileThickness
= Thickness(tileMode
);
3019 case ADDR_TM_2D_TILED_THIN1
: // fall through
3020 case ADDR_TM_2D_TILED_THICK
: // fall through
3021 case ADDR_TM_2D_TILED_XTHICK
:
3022 sliceRotation
= ((numBanks
/ 2) - 1) * (slice
/ microTileThickness
);
3024 case ADDR_TM_3D_TILED_THIN1
: // fall through
3025 case ADDR_TM_3D_TILED_THICK
: // fall through
3026 case ADDR_TM_3D_TILED_XTHICK
:
3028 Max(1u, (pipes
/ 2) - 1) * (slice
/ microTileThickness
) / pipes
;
3036 // Compute bank rotation for the tile split slice.
3038 // The sample slice will be non-zero if samples must be split across multiple slices.
3039 // This situation arises when the micro tile size multiplied yBit the number of samples exceeds
3040 // the split size (set in GB_ADDR_CONFIG).
3044 case ADDR_TM_2D_TILED_THIN1
: //fall through
3045 case ADDR_TM_3D_TILED_THIN1
: //fall through
3046 case ADDR_TM_PRT_2D_TILED_THIN1
: //fall through
3047 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
3048 tileSplitRotation
= ((numBanks
/ 2) + 1) * tileSplitSlice
;
3051 tileSplitRotation
= 0;
3056 // Apply bank rotation for the slice and tile split slice.
3058 bank
^= bankSwizzle
+ sliceRotation
;
3059 bank
^= tileSplitRotation
;
3061 bank
&= (numBanks
- 1);
3067 ****************************************************************************************************
3068 * EgBasedLib::ComputeBankFromAddr
3071 * Compute the bank number from an address
3074 ****************************************************************************************************
3076 UINT_32
EgBasedLib::ComputeBankFromAddr(
3077 UINT_64 addr
, ///< [in] address
3078 UINT_32 numBanks
, ///< [in] number of banks
3079 UINT_32 numPipes
///< [in] number of pipes
3085 // The LSBs of the address are arranged as follows:
3086 // bank | bankInterleave | pipe | pipeInterleave
3088 // To get the bank number, shift off the pipe interleave, pipe, and bank interlave bits and
3089 // mask the bank bits.
3091 bank
= static_cast<UINT_32
>(
3092 (addr
>> Log2(m_pipeInterleaveBytes
* numPipes
* m_bankInterleave
)) &
3100 ****************************************************************************************************
3101 * EgBasedLib::ComputePipeRotation
3104 * Compute pipe rotation value
3107 ****************************************************************************************************
3109 UINT_32
EgBasedLib::ComputePipeRotation(
3110 AddrTileMode tileMode
, ///< [in] tile mode
3111 UINT_32 numPipes
///< [in] number of pipes
3118 case ADDR_TM_3D_TILED_THIN1
: //fall through
3119 case ADDR_TM_3D_TILED_THICK
: //fall through
3120 case ADDR_TM_3D_TILED_XTHICK
: //fall through
3121 case ADDR_TM_PRT_3D_TILED_THIN1
: //fall through
3122 case ADDR_TM_PRT_3D_TILED_THICK
:
3123 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1);
3133 ****************************************************************************************************
3134 * EgBasedLib::ComputeBankRotation
3137 * Compute bank rotation value
3140 ****************************************************************************************************
3142 UINT_32
EgBasedLib::ComputeBankRotation(
3143 AddrTileMode tileMode
, ///< [in] tile mode
3144 UINT_32 numBanks
, ///< [in] number of banks
3145 UINT_32 numPipes
///< [in] number of pipes
3152 case ADDR_TM_2D_TILED_THIN1
: // fall through
3153 case ADDR_TM_2D_TILED_THICK
: // fall through
3154 case ADDR_TM_2D_TILED_XTHICK
:
3155 case ADDR_TM_PRT_2D_TILED_THIN1
:
3156 case ADDR_TM_PRT_2D_TILED_THICK
:
3157 // Rotate banks per Z-slice yBit 1 for 4-bank or 3 for 8-bank
3158 rotation
= numBanks
/ 2 - 1;
3160 case ADDR_TM_3D_TILED_THIN1
: // fall through
3161 case ADDR_TM_3D_TILED_THICK
: // fall through
3162 case ADDR_TM_3D_TILED_XTHICK
:
3163 case ADDR_TM_PRT_3D_TILED_THIN1
:
3164 case ADDR_TM_PRT_3D_TILED_THICK
:
3165 rotation
= (numPipes
< 4) ? 1 : (numPipes
/ 2 - 1); // rotate pipes & banks
3175 ****************************************************************************************************
3176 * EgBasedLib::ComputeHtileBytes
3179 * Compute htile size in bytes
3182 * Htile size in bytes
3183 ****************************************************************************************************
3185 UINT_64
EgBasedLib::ComputeHtileBytes(
3186 UINT_32 pitch
, ///< [in] pitch
3187 UINT_32 height
, ///< [in] height
3188 UINT_32 bpp
, ///< [in] bits per pixel
3189 BOOL_32 isLinear
, ///< [in] if it is linear mode
3190 UINT_32 numSlices
, ///< [in] number of slices
3191 UINT_64
* sliceBytes
, ///< [out] bytes per slice
3192 UINT_32 baseAlign
///< [in] base alignments
3197 const UINT_64 HtileCacheLineSize
= BITS_TO_BYTES(HtileCacheBits
);
3199 *sliceBytes
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
/ 64);
3201 if (m_configFlags
.useHtileSliceAlign
)
3203 // Align the sliceSize to htilecachelinesize * pipes at first
3204 *sliceBytes
= PowTwoAlign(*sliceBytes
, HtileCacheLineSize
* m_pipes
);
3205 surfBytes
= *sliceBytes
* numSlices
;
3209 // Align the surfSize to htilecachelinesize * pipes at last
3210 surfBytes
= *sliceBytes
* numSlices
;
3211 surfBytes
= PowTwoAlign(surfBytes
, HtileCacheLineSize
* m_pipes
);
3218 ****************************************************************************************************
3219 * EgBasedLib::DispatchComputeFmaskInfo
3222 * Compute fmask sizes include padded pitch, height, slices, total size in bytes,
3223 * meanwhile output suitable tile mode and alignments as well. Results are returned
3224 * through output parameters.
3228 ****************************************************************************************************
3230 ADDR_E_RETURNCODE
EgBasedLib::DispatchComputeFmaskInfo(
3231 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3232 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
) ///< [out] output structure
3234 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3236 ADDR_COMPUTE_SURFACE_INFO_INPUT surfIn
= {0};
3237 ADDR_COMPUTE_SURFACE_INFO_OUTPUT surfOut
= {0};
3239 // Setup input structure
3240 surfIn
.tileMode
= pIn
->tileMode
;
3241 surfIn
.width
= pIn
->pitch
;
3242 surfIn
.height
= pIn
->height
;
3243 surfIn
.numSlices
= pIn
->numSlices
;
3244 surfIn
.pTileInfo
= pIn
->pTileInfo
;
3245 surfIn
.tileType
= ADDR_NON_DISPLAYABLE
;
3246 surfIn
.flags
.fmask
= 1;
3248 // Setup output structure
3249 surfOut
.pTileInfo
= pOut
->pTileInfo
;
3251 // Setup hwl specific fields
3252 HwlFmaskPreThunkSurfInfo(pIn
, pOut
, &surfIn
, &surfOut
);
3254 surfIn
.bpp
= HwlComputeFmaskBits(pIn
, &surfIn
.numSamples
);
3256 // ComputeSurfaceInfo needs numSamples in surfOut as surface routines need adjusted numSamples
3257 surfOut
.numSamples
= surfIn
.numSamples
;
3259 retCode
= HwlComputeSurfaceInfo(&surfIn
, &surfOut
);
3261 // Save bpp field for surface dump support
3262 surfOut
.bpp
= surfIn
.bpp
;
3264 if (retCode
== ADDR_OK
)
3266 pOut
->bpp
= surfOut
.bpp
;
3267 pOut
->pitch
= surfOut
.pitch
;
3268 pOut
->height
= surfOut
.height
;
3269 pOut
->numSlices
= surfOut
.depth
;
3270 pOut
->fmaskBytes
= surfOut
.surfSize
;
3271 pOut
->baseAlign
= surfOut
.baseAlign
;
3272 pOut
->pitchAlign
= surfOut
.pitchAlign
;
3273 pOut
->heightAlign
= surfOut
.heightAlign
;
3275 if (surfOut
.depth
> 1)
3277 // For fmask, expNumSlices is stored in depth.
3278 pOut
->sliceSize
= surfOut
.surfSize
/ surfOut
.depth
;
3282 pOut
->sliceSize
= surfOut
.surfSize
;
3285 // Save numSamples field for surface dump support
3286 pOut
->numSamples
= surfOut
.numSamples
;
3288 HwlFmaskPostThunkSurfInfo(&surfOut
, pOut
);
3295 ****************************************************************************************************
3296 * EgBasedLib::HwlFmaskSurfaceInfo
3298 * Entry of EgBasedLib ComputeFmaskInfo
3301 ****************************************************************************************************
3303 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskInfo(
3304 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
3305 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
3308 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3310 ADDR_TILEINFO tileInfo
= {0};
3312 // Use internal tile info if pOut does not have a valid pTileInfo
3313 if (pOut
->pTileInfo
== NULL
)
3315 pOut
->pTileInfo
= &tileInfo
;
3318 retCode
= DispatchComputeFmaskInfo(pIn
, pOut
);
3320 if (retCode
== ADDR_OK
)
3323 HwlPostCheckTileIndex(pOut
->pTileInfo
, pIn
->tileMode
, ADDR_NON_DISPLAYABLE
,
3327 // Resets pTileInfo to NULL if the internal tile info is used
3328 if (pOut
->pTileInfo
== &tileInfo
)
3330 pOut
->pTileInfo
= NULL
;
3337 ****************************************************************************************************
3338 * EgBasedLib::HwlComputeFmaskAddrFromCoord
3340 * Entry of EgBasedLib ComputeFmaskAddrFromCoord
3343 ****************************************************************************************************
3345 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskAddrFromCoord(
3346 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3347 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3350 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3356 ****************************************************************************************************
3357 * EgBasedLib::HwlComputeFmaskCoordFromAddr
3359 * Entry of EgBasedLib ComputeFmaskCoordFromAddr
3362 ****************************************************************************************************
3364 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeFmaskCoordFromAddr(
3365 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3366 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3369 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3375 ****************************************************************************************************
3376 * EgBasedLib::ComputeFmaskNumPlanesFromNumSamples
3379 * Compute fmask number of planes from number of samples
3383 ****************************************************************************************************
3385 UINT_32
EgBasedLib::ComputeFmaskNumPlanesFromNumSamples(
3386 UINT_32 numSamples
) ///< [in] number of samples
3391 // FMASK is stored such that each micro tile is composed of elements containing N bits, where
3392 // N is the number of samples. There is a micro tile for each bit in the FMASK address, and
3393 // micro tiles for each address bit, sometimes referred to as a plane, are stored sequentially.
3394 // The FMASK for a 2-sample surface looks like a general surface with 2 bits per element.
3395 // The FMASK for a 4-sample surface looks like a general surface with 4 bits per element and
3396 // 2 samples. The FMASK for an 8-sample surface looks like a general surface with 8 bits per
3397 // element and 4 samples. R6xx and R7xx only stored 3 planes for 8-sample FMASK surfaces.
3398 // This was changed for R8xx to simplify the logic in the CB.
3412 ADDR_UNHANDLED_CASE();
3420 ****************************************************************************************************
3421 * EgBasedLib::ComputeFmaskResolvedBppFromNumSamples
3424 * Compute resolved fmask effective bpp based on number of samples
3428 ****************************************************************************************************
3430 UINT_32
EgBasedLib::ComputeFmaskResolvedBppFromNumSamples(
3431 UINT_32 numSamples
) ///< number of samples
3436 // Resolved FMASK surfaces are generated yBit the CB and read yBit the texture unit
3437 // so that the texture unit can read compressed multi-sample color data.
3438 // These surfaces store each index value packed per element.
3439 // Each element contains at least num_samples * log2(num_samples) bits.
3440 // Resolved FMASK surfaces are addressed as follows:
3441 // 2-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3442 // 4-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3443 // 8-sample Addressed similarly to a color surface with 32 bits per element and 1 sample.
3457 ADDR_UNHANDLED_CASE();
3465 ****************************************************************************************************
3466 * EgBasedLib::IsTileInfoAllZero
3469 * Return TRUE if all field are zero
3471 * Since NULL input is consider to be all zero
3472 ****************************************************************************************************
3474 BOOL_32
EgBasedLib::IsTileInfoAllZero(
3475 const ADDR_TILEINFO
* pTileInfo
)
3477 BOOL_32 allZero
= TRUE
;
3481 if ((pTileInfo
->banks
!= 0) ||
3482 (pTileInfo
->bankWidth
!= 0) ||
3483 (pTileInfo
->bankHeight
!= 0) ||
3484 (pTileInfo
->macroAspectRatio
!= 0) ||
3485 (pTileInfo
->tileSplitBytes
!= 0) ||
3486 (pTileInfo
->pipeConfig
!= 0)
3497 ****************************************************************************************************
3498 * EgBasedLib::HwlTileInfoEqual
3501 * Return TRUE if all field are equal
3503 * Only takes care of current HWL's data
3504 ****************************************************************************************************
3506 BOOL_32
EgBasedLib::HwlTileInfoEqual(
3507 const ADDR_TILEINFO
* pLeft
, ///<[in] Left compare operand
3508 const ADDR_TILEINFO
* pRight
///<[in] Right compare operand
3511 BOOL_32 equal
= FALSE
;
3513 if (pLeft
->banks
== pRight
->banks
&&
3514 pLeft
->bankWidth
== pRight
->bankWidth
&&
3515 pLeft
->bankHeight
== pRight
->bankHeight
&&
3516 pLeft
->macroAspectRatio
== pRight
->macroAspectRatio
&&
3517 pLeft
->tileSplitBytes
== pRight
->tileSplitBytes
)
3526 ****************************************************************************************************
3527 * EgBasedLib::HwlConvertTileInfoToHW
3529 * Entry of EgBasedLib ConvertTileInfoToHW
3532 ****************************************************************************************************
3534 ADDR_E_RETURNCODE
EgBasedLib::HwlConvertTileInfoToHW(
3535 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
3536 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
3539 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3541 ADDR_TILEINFO
*pTileInfoIn
= pIn
->pTileInfo
;
3542 ADDR_TILEINFO
*pTileInfoOut
= pOut
->pTileInfo
;
3544 if ((pTileInfoIn
!= NULL
) && (pTileInfoOut
!= NULL
))
3546 if (pIn
->reverse
== FALSE
)
3548 switch (pTileInfoIn
->banks
)
3551 pTileInfoOut
->banks
= 0;
3554 pTileInfoOut
->banks
= 1;
3557 pTileInfoOut
->banks
= 2;
3560 pTileInfoOut
->banks
= 3;
3563 ADDR_ASSERT_ALWAYS();
3564 retCode
= ADDR_INVALIDPARAMS
;
3565 pTileInfoOut
->banks
= 0;
3569 switch (pTileInfoIn
->bankWidth
)
3572 pTileInfoOut
->bankWidth
= 0;
3575 pTileInfoOut
->bankWidth
= 1;
3578 pTileInfoOut
->bankWidth
= 2;
3581 pTileInfoOut
->bankWidth
= 3;
3584 ADDR_ASSERT_ALWAYS();
3585 retCode
= ADDR_INVALIDPARAMS
;
3586 pTileInfoOut
->bankWidth
= 0;
3590 switch (pTileInfoIn
->bankHeight
)
3593 pTileInfoOut
->bankHeight
= 0;
3596 pTileInfoOut
->bankHeight
= 1;
3599 pTileInfoOut
->bankHeight
= 2;
3602 pTileInfoOut
->bankHeight
= 3;
3605 ADDR_ASSERT_ALWAYS();
3606 retCode
= ADDR_INVALIDPARAMS
;
3607 pTileInfoOut
->bankHeight
= 0;
3611 switch (pTileInfoIn
->macroAspectRatio
)
3614 pTileInfoOut
->macroAspectRatio
= 0;
3617 pTileInfoOut
->macroAspectRatio
= 1;
3620 pTileInfoOut
->macroAspectRatio
= 2;
3623 pTileInfoOut
->macroAspectRatio
= 3;
3626 ADDR_ASSERT_ALWAYS();
3627 retCode
= ADDR_INVALIDPARAMS
;
3628 pTileInfoOut
->macroAspectRatio
= 0;
3632 switch (pTileInfoIn
->tileSplitBytes
)
3635 pTileInfoOut
->tileSplitBytes
= 0;
3638 pTileInfoOut
->tileSplitBytes
= 1;
3641 pTileInfoOut
->tileSplitBytes
= 2;
3644 pTileInfoOut
->tileSplitBytes
= 3;
3647 pTileInfoOut
->tileSplitBytes
= 4;
3650 pTileInfoOut
->tileSplitBytes
= 5;
3653 pTileInfoOut
->tileSplitBytes
= 6;
3656 ADDR_ASSERT_ALWAYS();
3657 retCode
= ADDR_INVALIDPARAMS
;
3658 pTileInfoOut
->tileSplitBytes
= 0;
3664 switch (pTileInfoIn
->banks
)
3667 pTileInfoOut
->banks
= 2;
3670 pTileInfoOut
->banks
= 4;
3673 pTileInfoOut
->banks
= 8;
3676 pTileInfoOut
->banks
= 16;
3679 ADDR_ASSERT_ALWAYS();
3680 retCode
= ADDR_INVALIDPARAMS
;
3681 pTileInfoOut
->banks
= 2;
3685 switch (pTileInfoIn
->bankWidth
)
3688 pTileInfoOut
->bankWidth
= 1;
3691 pTileInfoOut
->bankWidth
= 2;
3694 pTileInfoOut
->bankWidth
= 4;
3697 pTileInfoOut
->bankWidth
= 8;
3700 ADDR_ASSERT_ALWAYS();
3701 retCode
= ADDR_INVALIDPARAMS
;
3702 pTileInfoOut
->bankWidth
= 1;
3706 switch (pTileInfoIn
->bankHeight
)
3709 pTileInfoOut
->bankHeight
= 1;
3712 pTileInfoOut
->bankHeight
= 2;
3715 pTileInfoOut
->bankHeight
= 4;
3718 pTileInfoOut
->bankHeight
= 8;
3721 ADDR_ASSERT_ALWAYS();
3722 retCode
= ADDR_INVALIDPARAMS
;
3723 pTileInfoOut
->bankHeight
= 1;
3727 switch (pTileInfoIn
->macroAspectRatio
)
3730 pTileInfoOut
->macroAspectRatio
= 1;
3733 pTileInfoOut
->macroAspectRatio
= 2;
3736 pTileInfoOut
->macroAspectRatio
= 4;
3739 pTileInfoOut
->macroAspectRatio
= 8;
3742 ADDR_ASSERT_ALWAYS();
3743 retCode
= ADDR_INVALIDPARAMS
;
3744 pTileInfoOut
->macroAspectRatio
= 1;
3748 switch (pTileInfoIn
->tileSplitBytes
)
3751 pTileInfoOut
->tileSplitBytes
= 64;
3754 pTileInfoOut
->tileSplitBytes
= 128;
3757 pTileInfoOut
->tileSplitBytes
= 256;
3760 pTileInfoOut
->tileSplitBytes
= 512;
3763 pTileInfoOut
->tileSplitBytes
= 1024;
3766 pTileInfoOut
->tileSplitBytes
= 2048;
3769 pTileInfoOut
->tileSplitBytes
= 4096;
3772 ADDR_ASSERT_ALWAYS();
3773 retCode
= ADDR_INVALIDPARAMS
;
3774 pTileInfoOut
->tileSplitBytes
= 64;
3779 if (pTileInfoIn
!= pTileInfoOut
)
3781 pTileInfoOut
->pipeConfig
= pTileInfoIn
->pipeConfig
;
3786 ADDR_ASSERT_ALWAYS();
3787 retCode
= ADDR_INVALIDPARAMS
;
3794 ****************************************************************************************************
3795 * EgBasedLib::HwlComputeSurfaceInfo
3797 * Entry of EgBasedLib ComputeSurfaceInfo
3800 ****************************************************************************************************
3802 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceInfo(
3803 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
3804 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
3807 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3809 if (pIn
->numSamples
< pIn
->numFrags
)
3811 retCode
= ADDR_INVALIDPARAMS
;
3814 ADDR_TILEINFO tileInfo
= {0};
3816 if (retCode
== ADDR_OK
)
3818 // Uses internal tile info if pOut does not have a valid pTileInfo
3819 if (pOut
->pTileInfo
== NULL
)
3821 pOut
->pTileInfo
= &tileInfo
;
3824 if (DispatchComputeSurfaceInfo(pIn
, pOut
) == FALSE
)
3826 retCode
= ADDR_INVALIDPARAMS
;
3829 // In case client uses tile info as input and would like to calculate a correct size and
3830 // alignment together with tile info as output when the tile info is not suppose to have any
3831 // matching indices in tile mode tables.
3832 if (pIn
->flags
.skipIndicesOutput
== FALSE
)
3835 pOut
->tileIndex
= HwlPostCheckTileIndex(pOut
->pTileInfo
,
3840 if (IsMacroTiled(pOut
->tileMode
) && (pOut
->macroModeIndex
== TileIndexInvalid
))
3842 pOut
->macroModeIndex
= HwlComputeMacroModeIndex(pOut
->tileIndex
,
3850 // Resets pTileInfo to NULL if the internal tile info is used
3851 if (pOut
->pTileInfo
== &tileInfo
)
3854 // Client does not pass in a valid pTileInfo
3855 if (IsMacroTiled(pOut
->tileMode
))
3857 // If a valid index is returned, then no pTileInfo is okay
3858 ADDR_ASSERT((m_configFlags
.useTileIndex
== FALSE
) ||
3859 (pOut
->tileIndex
!= TileIndexInvalid
));
3861 if (IsTileInfoAllZero(pIn
->pTileInfo
) == FALSE
)
3863 // The initial value of pIn->pTileInfo is copied to tileInfo
3864 // We do not expect any of these value to be changed nor any 0 of inputs
3865 ADDR_ASSERT(tileInfo
.banks
== pIn
->pTileInfo
->banks
);
3866 ADDR_ASSERT(tileInfo
.bankWidth
== pIn
->pTileInfo
->bankWidth
);
3867 ADDR_ASSERT(tileInfo
.bankHeight
== pIn
->pTileInfo
->bankHeight
);
3868 ADDR_ASSERT(tileInfo
.macroAspectRatio
== pIn
->pTileInfo
->macroAspectRatio
);
3869 ADDR_ASSERT(tileInfo
.tileSplitBytes
== pIn
->pTileInfo
->tileSplitBytes
);
3873 pOut
->pTileInfo
= NULL
;
3881 ****************************************************************************************************
3882 * EgBasedLib::HwlComputeSurfaceAddrFromCoord
3884 * Entry of EgBasedLib ComputeSurfaceAddrFromCoord
3887 ****************************************************************************************************
3889 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceAddrFromCoord(
3890 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3891 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3894 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3897 #if !ALT_TEST // Overflow test needs this out-of-boundary coord
3898 (pIn
->x
> pIn
->pitch
) ||
3899 (pIn
->y
> pIn
->height
) ||
3901 (pIn
->numSamples
> m_maxSamples
))
3903 retCode
= ADDR_INVALIDPARAMS
;
3907 pOut
->addr
= DispatchComputeSurfaceAddrFromCoord(pIn
, pOut
);
3914 ****************************************************************************************************
3915 * EgBasedLib::HwlComputeSurfaceCoordFromAddr
3917 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
3920 ****************************************************************************************************
3922 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSurfaceCoordFromAddr(
3923 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
3924 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
3927 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3929 if ((pIn
->bitPosition
>= 8) ||
3930 (pIn
->numSamples
> m_maxSamples
))
3932 retCode
= ADDR_INVALIDPARAMS
;
3936 DispatchComputeSurfaceCoordFromAddr(pIn
, pOut
);
3942 ****************************************************************************************************
3943 * EgBasedLib::HwlComputeSliceTileSwizzle
3945 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
3948 ****************************************************************************************************
3950 ADDR_E_RETURNCODE
EgBasedLib::HwlComputeSliceTileSwizzle(
3951 const ADDR_COMPUTE_SLICESWIZZLE_INPUT
* pIn
, ///< [in] input structure
3952 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT
* pOut
///< [out] output structure
3955 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
3957 if (pIn
->pTileInfo
&& (pIn
->pTileInfo
->banks
> 0))
3960 pOut
->tileSwizzle
= ComputeSliceTileSwizzle(pIn
->tileMode
,
3968 retCode
= ADDR_INVALIDPARAMS
;
3975 ****************************************************************************************************
3976 * EgBasedLib::HwlComputeHtileBpp
3983 ****************************************************************************************************
3985 UINT_32
EgBasedLib::HwlComputeHtileBpp(
3986 BOOL_32 isWidth8
, ///< [in] TRUE if block width is 8
3987 BOOL_32 isHeight8
///< [in] TRUE if block height is 8
3990 // only support 8x8 mode
3991 ADDR_ASSERT(isWidth8
&& isHeight8
);
3996 ****************************************************************************************************
3997 * EgBasedLib::HwlComputeHtileBaseAlign
4000 * Compute htile base alignment
4003 * Htile base alignment
4004 ****************************************************************************************************
4006 UINT_32
EgBasedLib::HwlComputeHtileBaseAlign(
4007 BOOL_32 isTcCompatible
, ///< [in] if TC compatible
4008 BOOL_32 isLinear
, ///< [in] if it is linear mode
4009 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
4012 UINT_32 baseAlign
= m_pipeInterleaveBytes
* HwlGetPipes(pTileInfo
);
4016 ADDR_ASSERT(pTileInfo
!= NULL
);
4019 baseAlign
*= pTileInfo
->banks
;
4027 ****************************************************************************************************
4028 * EgBasedLib::HwlGetPitchAlignmentMicroTiled
4031 * Compute 1D tiled surface pitch alignment, calculation results are returned through
4032 * output parameters.
4036 ****************************************************************************************************
4038 UINT_32
EgBasedLib::HwlGetPitchAlignmentMicroTiled(
4039 AddrTileMode tileMode
, ///< [in] tile mode
4040 UINT_32 bpp
, ///< [in] bits per pixel
4041 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4042 UINT_32 numSamples
///< [in] number of samples
4047 UINT_32 microTileThickness
= Thickness(tileMode
);
4049 UINT_32 pixelsPerMicroTile
;
4050 UINT_32 pixelsPerPipeInterleave
;
4051 UINT_32 microTilesPerPipeInterleave
;
4054 // Special workaround for depth/stencil buffer, use 8 bpp to meet larger requirement for
4055 // stencil buffer since pitch alignment is related to bpp.
4056 // For a depth only buffer do not set this.
4058 // Note: this actually does not work for mipmap but mipmap depth texture is not really
4059 // sampled with mipmap.
4061 if (flags
.depth
&& (flags
.noStencil
== FALSE
))
4066 pixelsPerMicroTile
= MicroTilePixels
* microTileThickness
;
4067 pixelsPerPipeInterleave
= BYTES_TO_BITS(m_pipeInterleaveBytes
) / (bpp
* numSamples
);
4068 microTilesPerPipeInterleave
= pixelsPerPipeInterleave
/ pixelsPerMicroTile
;
4070 pitchAlign
= Max(MicroTileWidth
, microTilesPerPipeInterleave
* MicroTileWidth
);
4076 ****************************************************************************************************
4077 * EgBasedLib::HwlGetSizeAdjustmentMicroTiled
4080 * Adjust 1D tiled surface pitch and slice size
4083 * Logical slice size in bytes
4084 ****************************************************************************************************
4086 UINT_64
EgBasedLib::HwlGetSizeAdjustmentMicroTiled(
4087 UINT_32 thickness
, ///< [in] thickness
4088 UINT_32 bpp
, ///< [in] bits per pixel
4089 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
4090 UINT_32 numSamples
, ///< [in] number of samples
4091 UINT_32 baseAlign
, ///< [in] base alignment
4092 UINT_32 pitchAlign
, ///< [in] pitch alignment
4093 UINT_32
* pPitch
, ///< [in,out] pointer to pitch
4094 UINT_32
* pHeight
///< [in,out] pointer to height
4097 UINT_64 logicalSliceSize
;
4098 MAYBE_UNUSED UINT_64 physicalSliceSize
;
4100 UINT_32 pitch
= *pPitch
;
4101 UINT_32 height
= *pHeight
;
4103 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
4104 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
4106 // Physical slice: multiplied by thickness
4107 physicalSliceSize
= logicalSliceSize
* thickness
;
4110 // R800 will always pad physical slice size to baseAlign which is pipe_interleave_bytes
4112 ADDR_ASSERT((physicalSliceSize
% baseAlign
) == 0);
4114 return logicalSliceSize
;
4118 ****************************************************************************************************
4119 * EgBasedLib::HwlStereoCheckRightOffsetPadding
4122 * check if the height needs extra padding for stereo right eye offset, to avoid swizzling
4125 * TRUE is the extra padding is needed
4127 ****************************************************************************************************
4129 UINT_32
EgBasedLib::HwlStereoCheckRightOffsetPadding(
4130 ADDR_TILEINFO
* pTileInfo
///< Tiling info
4133 UINT_32 stereoHeightAlign
= 0;
4135 if (pTileInfo
->macroAspectRatio
> 2)
4137 // Since 3D rendering treats right eye surface starting from y == "eye height" while
4138 // display engine treats it to be 0, so the bank bits may be different.
4139 // Additional padding in height is required to make sure it's possible
4140 // to achieve synonym by adjusting bank swizzle of right eye surface.
4142 static const UINT_32 StereoAspectRatio
= 2;
4143 stereoHeightAlign
= pTileInfo
->banks
*
4144 pTileInfo
->bankHeight
*
4149 return stereoHeightAlign
;