2 * Copyright © 2014 Advanced Micro Devices, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
28 ***************************************************************************************************
30 * @brief Contains the implementation for the SiAddrLib class.
31 ***************************************************************************************************
34 #include "siaddrlib.h"
36 #include "si_gb_reg.h"
38 #include "si_ci_vi_merged_enum.h"
41 #include "amdgpu_id.h"
46 ///////////////////////////////////////////////////////////////////////////////////////////////////
47 ///////////////////////////////////////////////////////////////////////////////////////////////////
50 ***************************************************************************************************
54 * Creates an SiAddrLib object.
57 * Returns an SiAddrLib object pointer.
58 ***************************************************************************************************
60 AddrLib
* AddrSIHwlInit(const AddrClient
* pClient
)
62 return SiAddrLib::CreateObj(pClient
);
66 ***************************************************************************************************
67 * SiAddrLib::SiAddrLib
72 ***************************************************************************************************
74 SiAddrLib::SiAddrLib(const AddrClient
* pClient
) :
75 EgBasedAddrLib(pClient
),
79 memset(&m_settings
, 0, sizeof(m_settings
));
83 ***************************************************************************************************
84 * SiAddrLib::~SiAddrLib
88 ***************************************************************************************************
90 SiAddrLib::~SiAddrLib()
95 ***************************************************************************************************
96 * SiAddrLib::HwlGetPipes
102 ***************************************************************************************************
104 UINT_32
SiAddrLib::HwlGetPipes(
105 const ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
112 numPipes
= GetPipePerSurf(pTileInfo
->pipeConfig
);
116 ADDR_ASSERT_ALWAYS();
117 numPipes
= m_pipes
; // Suppose we should still have a global pipes
124 ***************************************************************************************************
125 * SiAddrLib::GetPipePerSurf
127 * get pipe num base on inputing tileinfo->pipeconfig
130 ***************************************************************************************************
132 UINT_32
SiAddrLib::GetPipePerSurf(
133 AddrPipeCfg pipeConfig
///< [in] pipe config
136 UINT_32 numPipes
= 0;
140 case ADDR_PIPECFG_P2
:
143 case ADDR_PIPECFG_P4_8x16
:
144 case ADDR_PIPECFG_P4_16x16
:
145 case ADDR_PIPECFG_P4_16x32
:
146 case ADDR_PIPECFG_P4_32x32
:
149 case ADDR_PIPECFG_P8_16x16_8x16
:
150 case ADDR_PIPECFG_P8_16x32_8x16
:
151 case ADDR_PIPECFG_P8_32x32_8x16
:
152 case ADDR_PIPECFG_P8_16x32_16x16
:
153 case ADDR_PIPECFG_P8_32x32_16x16
:
154 case ADDR_PIPECFG_P8_32x32_16x32
:
155 case ADDR_PIPECFG_P8_32x64_32x32
:
158 case ADDR_PIPECFG_P16_32x32_8x16
:
159 case ADDR_PIPECFG_P16_32x32_16x16
:
163 ADDR_ASSERT(!"Invalid pipe config");
170 ***************************************************************************************************
171 * SiAddrLib::ComputePipeFromCoord
174 * Compute pipe number from coordinates
177 ***************************************************************************************************
179 UINT_32
SiAddrLib::ComputePipeFromCoord(
180 UINT_32 x
, ///< [in] x coordinate
181 UINT_32 y
, ///< [in] y coordinate
182 UINT_32 slice
, ///< [in] slice index
183 AddrTileMode tileMode
, ///< [in] tile mode
184 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
185 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines are ignored
186 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
190 UINT_32 pipeBit0
= 0;
191 UINT_32 pipeBit1
= 0;
192 UINT_32 pipeBit2
= 0;
193 UINT_32 pipeBit3
= 0;
194 UINT_32 sliceRotation
;
195 UINT_32 numPipes
= 0;
197 UINT_32 tx
= x
/ MicroTileWidth
;
198 UINT_32 ty
= y
/ MicroTileHeight
;
199 UINT_32 x3
= _BIT(tx
,0);
200 UINT_32 x4
= _BIT(tx
,1);
201 UINT_32 x5
= _BIT(tx
,2);
202 UINT_32 x6
= _BIT(tx
,3);
203 UINT_32 y3
= _BIT(ty
,0);
204 UINT_32 y4
= _BIT(ty
,1);
205 UINT_32 y5
= _BIT(ty
,2);
206 UINT_32 y6
= _BIT(ty
,3);
208 switch (pTileInfo
->pipeConfig
)
210 case ADDR_PIPECFG_P2
:
214 case ADDR_PIPECFG_P4_8x16
:
219 case ADDR_PIPECFG_P4_16x16
:
220 pipeBit0
= x3
^ y3
^ x4
;
224 case ADDR_PIPECFG_P4_16x32
:
225 pipeBit0
= x3
^ y3
^ x4
;
229 case ADDR_PIPECFG_P4_32x32
:
230 pipeBit0
= x3
^ y3
^ x5
;
234 case ADDR_PIPECFG_P8_16x16_8x16
:
235 pipeBit0
= x4
^ y3
^ x5
;
239 case ADDR_PIPECFG_P8_16x32_8x16
:
240 pipeBit0
= x4
^ y3
^ x5
;
245 case ADDR_PIPECFG_P8_16x32_16x16
:
246 pipeBit0
= x3
^ y3
^ x4
;
251 case ADDR_PIPECFG_P8_32x32_8x16
:
252 pipeBit0
= x4
^ y3
^ x5
;
257 case ADDR_PIPECFG_P8_32x32_16x16
:
258 pipeBit0
= x3
^ y3
^ x4
;
263 case ADDR_PIPECFG_P8_32x32_16x32
:
264 pipeBit0
= x3
^ y3
^ x4
;
269 case ADDR_PIPECFG_P8_32x64_32x32
:
270 pipeBit0
= x3
^ y3
^ x5
;
275 case ADDR_PIPECFG_P16_32x32_8x16
:
282 case ADDR_PIPECFG_P16_32x32_16x16
:
283 pipeBit0
= x3
^ y3
^ x4
;
290 ADDR_UNHANDLED_CASE();
293 pipe
= pipeBit0
| (pipeBit1
<< 1) | (pipeBit2
<< 2) | (pipeBit3
<< 3);
295 UINT_32 microTileThickness
= Thickness(tileMode
);
298 // Apply pipe rotation for the slice.
302 case ADDR_TM_3D_TILED_THIN1
: //fall through thin
303 case ADDR_TM_3D_TILED_THICK
: //fall through thick
304 case ADDR_TM_3D_TILED_XTHICK
:
306 Max(1, static_cast<INT_32
>(numPipes
/ 2) - 1) * (slice
/ microTileThickness
);
312 pipeSwizzle
+= sliceRotation
;
313 pipeSwizzle
&= (numPipes
- 1);
315 pipe
= pipe
^ pipeSwizzle
;
321 ***************************************************************************************************
322 * SiAddrLib::ComputeTileCoordFromPipeAndElemIdx
325 * Compute (x,y) of a tile within a macro tile from address
328 ***************************************************************************************************
330 VOID
SiAddrLib::ComputeTileCoordFromPipeAndElemIdx(
331 UINT_32 elemIdx
, ///< [in] per pipe element index within a macro tile
332 UINT_32 pipe
, ///< [in] pipe index
333 AddrPipeCfg pipeCfg
, ///< [in] pipe config
334 UINT_32 pitchInMacroTile
, ///< [in] surface pitch in macro tile
335 UINT_32 x
, ///< [in] x coordinate of the (0,0) tile in a macro tile
336 UINT_32 y
, ///< [in] y coordinate of the (0,0) tile in a macro tile
337 UINT_32
* pX
, ///< [out] x coordinate
338 UINT_32
* pY
///< [out] y coordinate
341 UINT_32 pipebit0
= _BIT(pipe
,0);
342 UINT_32 pipebit1
= _BIT(pipe
,1);
343 UINT_32 pipebit2
= _BIT(pipe
,2);
344 UINT_32 pipebit3
= _BIT(pipe
,3);
345 UINT_32 elemIdx0
= _BIT(elemIdx
,0);
346 UINT_32 elemIdx1
= _BIT(elemIdx
,1);
347 UINT_32 elemIdx2
= _BIT(elemIdx
,2);
359 case ADDR_PIPECFG_P2
:
364 *pY
= Bits2Number(2, y4
, y3
);
365 *pX
= Bits2Number(2, x4
, x3
);
367 case ADDR_PIPECFG_P4_8x16
:
372 *pY
= Bits2Number(2, y4
, y3
);
373 *pX
= Bits2Number(2, x4
, x3
);
375 case ADDR_PIPECFG_P4_16x16
:
379 x3
= pipebit0
^ y3
^ x4
;
380 *pY
= Bits2Number(2, y4
, y3
);
381 *pX
= Bits2Number(2, x4
, x3
);
383 case ADDR_PIPECFG_P4_16x32
:
384 x3
= elemIdx0
^ pipebit0
;
387 y3
= pipebit0
^ x3
^ x4
;
389 *pY
= Bits2Number(2, y4
, y3
);
390 *pX
= Bits2Number(2, x4
, x3
);
392 case ADDR_PIPECFG_P4_32x32
:
396 if((pitchInMacroTile
% 2) == 0)
400 x3
= pipebit0
^ y3
^ x5
;
401 *pY
= Bits2Number(2, y4
, y3
);
402 *pX
= Bits2Number(3, x5
, x4
, x3
);
407 x3
= pipebit0
^ y3
^ x5
;
408 *pY
= Bits2Number(2, y4
, y3
);
409 *pX
= Bits2Number(2, x4
, x3
);
412 case ADDR_PIPECFG_P8_16x16_8x16
:
418 y3
= pipebit0
^ x5
^ x4
;
419 *pY
= Bits2Number(2, y4
, y3
);
420 *pX
= Bits2Number(2, x4
, x3
);
422 case ADDR_PIPECFG_P8_16x32_8x16
:
428 y3
= pipebit0
^ x4
^ x5
;
429 *pY
= Bits2Number(2, y4
, y3
);
430 *pX
= Bits2Number(2, x4
, x3
);
432 case ADDR_PIPECFG_P8_32x32_8x16
:
436 if((pitchInMacroTile
% 2) == 0)
441 y3
= pipebit0
^ x4
^ x5
;
442 *pY
= Bits2Number(2, y4
, y3
);
443 *pX
= Bits2Number(3, x5
, x4
, x3
);
448 y3
= pipebit0
^ x4
^ x5
;
449 *pY
= Bits2Number(2, y4
, y3
);
450 *pX
= Bits2Number(2, x4
, x3
);
453 case ADDR_PIPECFG_P8_16x32_16x16
:
459 y3
= pipebit0
^ x3
^ x4
;
460 *pY
= Bits2Number(2, y4
, y3
);
461 *pX
= Bits2Number(2, x4
, x3
);
463 case ADDR_PIPECFG_P8_32x32_16x16
:
468 if((pitchInMacroTile
% 2) == 0)
472 *pY
= Bits2Number(2, y4
, y3
);
473 *pX
= Bits2Number(3, x5
, x4
, x3
);
477 *pY
= Bits2Number(2, y4
, y3
);
478 *pX
= Bits2Number(2, x4
, x3
);
481 case ADDR_PIPECFG_P8_32x32_16x32
:
482 if((pitchInMacroTile
% 2) == 0)
489 x3
= pipebit0
^ y3
^ x4
;
491 *pY
= Bits2Number(2, y4
, y3
);
492 *pX
= Bits2Number(3, x5
, x4
, x3
);
500 x3
= pipebit0
^ y3
^ x4
;
501 *pY
= Bits2Number(2, y4
, y3
);
502 *pX
= Bits2Number(2, x4
, x3
);
505 case ADDR_PIPECFG_P8_32x64_32x32
:
509 if((pitchInMacroTile
% 4) == 0)
515 x3
= pipebit0
^ y3
^ x5
;
516 *pY
= Bits2Number(2, y4
, y3
);
517 *pX
= Bits2Number(4, x6
, x5
, x4
, x3
);
523 x3
= pipebit0
^ y3
^ x5
;
524 *pY
= Bits2Number(2, y4
, y3
);
525 *pX
= Bits2Number(3, x5
, x4
, x3
);
528 case ADDR_PIPECFG_P16_32x32_8x16
:
533 if((pitchInMacroTile
% 4) == 0)
539 *pY
= Bits2Number(2, y4
, y3
);
540 *pX
= Bits2Number(4, x6
, x5
,x4
, x3
);
546 *pY
= Bits2Number(2, y4
, y3
);
547 *pX
= Bits2Number(3, x5
, x4
, x3
);
550 case ADDR_PIPECFG_P16_32x32_16x16
:
554 x3
= pipebit0
^ y3
^ x4
;
555 if((pitchInMacroTile
% 4) == 0)
561 *pY
= Bits2Number(2, y4
, y3
);
562 *pX
= Bits2Number(4, x6
, x5
, x4
, x3
);
568 *pY
= Bits2Number(2, y4
, y3
);
569 *pX
= Bits2Number(3, x5
, x4
, x3
);
573 ADDR_UNHANDLED_CASE();
578 ***************************************************************************************************
579 * SiAddrLib::TileCoordToMaskElementIndex
582 * Compute element index from coordinates in tiles
585 ***************************************************************************************************
587 UINT_32
SiAddrLib::TileCoordToMaskElementIndex(
588 UINT_32 tx
, ///< [in] x coord, in Tiles
589 UINT_32 ty
, ///< [in] y coord, in Tiles
590 AddrPipeCfg pipeConfig
, ///< [in] pipe config
591 UINT_32
* macroShift
, ///< [out] macro shift
592 UINT_32
* elemIdxBits
///< [out] tile offset bits
596 UINT_32 elemIdx0
, elemIdx1
, elemIdx2
;
607 case ADDR_PIPECFG_P2
:
611 elemIdx1
= tx1
^ ty1
;
612 elemIdx0
= tx1
^ ty0
;
613 elemIdx
= Bits2Number(3,elemIdx2
,elemIdx1
,elemIdx0
);
615 case ADDR_PIPECFG_P4_8x16
:
619 elemIdx0
= tx1
^ ty1
;
620 elemIdx
= Bits2Number(2,elemIdx1
,elemIdx0
);
622 case ADDR_PIPECFG_P4_16x16
:
627 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
629 case ADDR_PIPECFG_P4_16x32
:
634 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
636 case ADDR_PIPECFG_P4_32x32
:
642 elemIdx
= Bits2Number(3, elemIdx2
, elemIdx1
, elemIdx0
);
644 case ADDR_PIPECFG_P8_16x16_8x16
:
650 case ADDR_PIPECFG_P8_16x32_8x16
:
656 case ADDR_PIPECFG_P8_32x32_8x16
:
661 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
663 case ADDR_PIPECFG_P8_16x32_16x16
:
669 case ADDR_PIPECFG_P8_32x32_16x16
:
674 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
676 case ADDR_PIPECFG_P8_32x32_16x32
:
681 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
683 case ADDR_PIPECFG_P8_32x64_32x32
:
689 elemIdx
= Bits2Number(3, elemIdx2
, elemIdx1
, elemIdx0
);
691 case ADDR_PIPECFG_P16_32x32_8x16
:
696 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
698 case ADDR_PIPECFG_P16_32x32_16x16
:
703 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
706 ADDR_UNHANDLED_CASE();
714 ***************************************************************************************************
715 * SiAddrLib::HwlComputeTileDataWidthAndHeightLinear
718 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
724 * MacroWidth and macroHeight are measured in pixels
725 ***************************************************************************************************
727 VOID
SiAddrLib::HwlComputeTileDataWidthAndHeightLinear(
728 UINT_32
* pMacroWidth
, ///< [out] macro tile width
729 UINT_32
* pMacroHeight
, ///< [out] macro tile height
730 UINT_32 bpp
, ///< [in] bits per pixel
731 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
734 ADDR_ASSERT(pTileInfo
!= NULL
);
738 /// In linear mode, the htile or cmask buffer must be padded out to 4 tiles
739 /// but for P8_32x64_32x32, it must be padded out to 8 tiles
740 /// Actually there are more pipe configs which need 8-tile padding but SI family
741 /// has a bug which is fixed in CI family
742 if ((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
) ||
743 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P16_32x32_8x16
) ||
744 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x32_16x16
))
746 macroWidth
= 8*MicroTileWidth
;
747 macroHeight
= 8*MicroTileHeight
;
751 macroWidth
= 4*MicroTileWidth
;
752 macroHeight
= 4*MicroTileHeight
;
755 *pMacroWidth
= macroWidth
;
756 *pMacroHeight
= macroHeight
;
760 ***************************************************************************************************
761 * SiAddrLib::HwlComputeHtileBytes
764 * Compute htile size in bytes
767 * Htile size in bytes
768 ***************************************************************************************************
770 UINT_64
SiAddrLib::HwlComputeHtileBytes(
771 UINT_32 pitch
, ///< [in] pitch
772 UINT_32 height
, ///< [in] height
773 UINT_32 bpp
, ///< [in] bits per pixel
774 BOOL_32 isLinear
, ///< [in] if it is linear mode
775 UINT_32 numSlices
, ///< [in] number of slices
776 UINT_64
* pSliceBytes
, ///< [out] bytes per slice
777 UINT_32 baseAlign
///< [in] base alignments
780 return ComputeHtileBytes(pitch
, height
, bpp
, isLinear
, numSlices
, pSliceBytes
, baseAlign
);
784 ***************************************************************************************************
785 * SiAddrLib::HwlComputeXmaskAddrFromCoord
788 * Compute address from coordinates for htile/cmask
791 ***************************************************************************************************
793 UINT_64
SiAddrLib::HwlComputeXmaskAddrFromCoord(
794 UINT_32 pitch
, ///< [in] pitch
795 UINT_32 height
, ///< [in] height
796 UINT_32 x
, ///< [in] x coord
797 UINT_32 y
, ///< [in] y coord
798 UINT_32 slice
, ///< [in] slice/depth index
799 UINT_32 numSlices
, ///< [in] number of slices
800 UINT_32 factor
, ///< [in] factor that indicates cmask(2) or htile(1)
801 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
802 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
803 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
804 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
805 UINT_32
* pBitPosition
///< [out] bit position inside a byte
808 UINT_32 tx
= x
/ MicroTileWidth
;
809 UINT_32 ty
= y
/ MicroTileHeight
;
817 UINT_32 tileNumPerPipe
;
820 if (factor
== 2) //CMASK
822 ADDR_CMASK_FLAGS flags
= {{0}};
824 tileNumPerPipe
= 256;
826 ComputeCmaskInfo(flags
,
837 elemBits
= CmaskElemBits
;
841 ADDR_HTILE_FLAGS flags
= {{0}};
843 tileNumPerPipe
= 512;
845 ComputeHtileInfo(flags
,
863 const UINT_32 pitchInTile
= newPitch
/ MicroTileWidth
;
864 const UINT_32 heightInTile
= newHeight
/ MicroTileWidth
;
865 UINT_64 macroOffset
; // Per pipe starting offset of the macro tile in which this tile lies.
866 UINT_64 microNumber
; // Per pipe starting offset of the macro tile in which this tile lies.
874 TileCoordToMaskElementIndex(tx
, ty
, pTileInfo
->pipeConfig
, µShift
, &elemIdxBits
);
876 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
879 { //linear addressing
880 // Linear addressing is extremelly wasting memory if slice > 1, since each pipe has the full
881 // slice memory foot print instead of divided by numPipes.
882 microX
= tx
/ 4; // Macro Tile is 4x4
884 microNumber
= static_cast<UINT_64
>(microX
+ microY
* (pitchInTile
/ 4)) << microShift
;
886 UINT_32 sliceBits
= pitchInTile
* heightInTile
;
888 // do htile single slice alignment if the flag is true
889 if (m_configFlags
.useHtileSliceAlign
&& (factor
== 1)) //Htile
891 sliceBits
= PowTwoAlign(sliceBits
, BITS_TO_BYTES(HtileCacheBits
) * numPipes
/ elemBits
);
893 macroOffset
= slice
* (sliceBits
/ numPipes
) * elemBits
;
897 const UINT_32 macroWidthInTile
= macroWidth
/ MicroTileWidth
; // Now in unit of Tiles
898 const UINT_32 macroHeightInTile
= macroHeight
/ MicroTileHeight
;
899 const UINT_32 pitchInCL
= pitchInTile
/ macroWidthInTile
;
900 const UINT_32 heightInCL
= heightInTile
/ macroHeightInTile
;
902 const UINT_32 macroX
= x
/ macroWidth
;
903 const UINT_32 macroY
= y
/ macroHeight
;
904 const UINT_32 macroNumber
= macroX
+ macroY
* pitchInCL
+ slice
* pitchInCL
* heightInCL
;
906 // Per pipe starting offset of the cache line in which this tile lies.
907 microX
= (x
% macroWidth
) / MicroTileWidth
/ 4; // Macro Tile is 4x4
908 microY
= (y
% macroHeight
) / MicroTileHeight
/ 4 ;
909 microNumber
= static_cast<UINT_64
>(microX
+ microY
* (macroWidth
/ MicroTileWidth
/ 4)) << microShift
;
911 macroOffset
= macroNumber
* tileNumPerPipe
* elemBits
;
914 if(elemIdxBits
== microShift
)
916 microNumber
+= elemIdx
;
920 microNumber
>>= elemIdxBits
;
921 microNumber
<<= elemIdxBits
;
922 microNumber
+= elemIdx
;
925 microOffset
= elemBits
* microNumber
;
926 totalOffset
= microOffset
+ macroOffset
;
928 UINT_32 pipe
= ComputePipeFromCoord(x
, y
, 0, ADDR_TM_2D_TILED_THIN1
, 0, FALSE
, pTileInfo
);
929 UINT_64 addrInBits
= totalOffset
% (m_pipeInterleaveBytes
* 8) +
930 pipe
* (m_pipeInterleaveBytes
* 8) +
931 totalOffset
/ (m_pipeInterleaveBytes
* 8) * (m_pipeInterleaveBytes
* 8) * numPipes
;
932 *pBitPosition
= static_cast<UINT_32
>(addrInBits
) % 8;
933 UINT_64 addr
= addrInBits
/ 8;
939 ***************************************************************************************************
940 * SiAddrLib::HwlComputeXmaskCoordFromAddr
943 * Compute the coord from an address of a cmask/htile
949 * This method is reused by htile, so rename to Xmask
950 ***************************************************************************************************
952 VOID
SiAddrLib::HwlComputeXmaskCoordFromAddr(
953 UINT_64 addr
, ///< [in] address
954 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
955 UINT_32 pitch
, ///< [in] pitch
956 UINT_32 height
, ///< [in] height
957 UINT_32 numSlices
, ///< [in] number of slices
958 UINT_32 factor
, ///< [in] factor that indicates cmask or htile
959 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
960 BOOL_32 isWidth8
, ///< [in] Not used by SI
961 BOOL_32 isHeight8
, ///< [in] Not used by SI
962 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
963 UINT_32
* pX
, ///< [out] x coord
964 UINT_32
* pY
, ///< [out] y coord
965 UINT_32
* pSlice
///< [out] slice index
973 UINT_32 tileNumPerPipe
;
980 if (factor
== 2) //CMASK
982 ADDR_CMASK_FLAGS flags
= {{0}};
984 tileNumPerPipe
= 256;
986 ComputeCmaskInfo(flags
,
1000 ADDR_HTILE_FLAGS flags
= {{0}};
1002 tileNumPerPipe
= 512;
1004 ComputeHtileInfo(flags
,
1020 const UINT_32 pitchInTile
= newPitch
/ MicroTileWidth
;
1021 const UINT_32 heightInTile
= newHeight
/ MicroTileWidth
;
1022 const UINT_32 pitchInMacroTile
= pitchInTile
/ 4;
1024 UINT_32 elemIdxBits
;
1025 // get macroShift and elemIdxBits
1026 TileCoordToMaskElementIndex(0, 0, pTileInfo
->pipeConfig
, ¯oShift
, &elemIdxBits
);
1028 const UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1029 const UINT_32 pipe
= (UINT_32
)((addr
/ m_pipeInterleaveBytes
) % numPipes
);
1031 UINT_64 localOffset
= (addr
% m_pipeInterleaveBytes
) +
1032 (addr
/ m_pipeInterleaveBytes
/ numPipes
)* m_pipeInterleaveBytes
;
1035 if (factor
== 2) //CMASK
1037 tileIndex
= (UINT_32
)(localOffset
* 2 + (bitPosition
!= 0));
1041 tileIndex
= (UINT_32
)(localOffset
/ 4);
1044 UINT_32 macroOffset
;
1047 UINT_32 sliceSizeInTile
= pitchInTile
* heightInTile
;
1049 // do htile single slice alignment if the flag is true
1050 if (m_configFlags
.useHtileSliceAlign
&& (factor
== 1)) //Htile
1052 sliceSizeInTile
= PowTwoAlign(sliceSizeInTile
, static_cast<UINT_32
>(sliceBytes
) / 64);
1054 *pSlice
= tileIndex
/ (sliceSizeInTile
/ numPipes
);
1055 macroOffset
= tileIndex
% (sliceSizeInTile
/ numPipes
);
1059 const UINT_32 clWidthInTile
= clWidth
/ MicroTileWidth
; // Now in unit of Tiles
1060 const UINT_32 clHeightInTile
= clHeight
/ MicroTileHeight
;
1061 const UINT_32 pitchInCL
= pitchInTile
/ clWidthInTile
;
1062 const UINT_32 heightInCL
= heightInTile
/ clHeightInTile
;
1063 const UINT_32 clIndex
= tileIndex
/ tileNumPerPipe
;
1065 UINT_32 clX
= clIndex
% pitchInCL
;
1066 UINT_32 clY
= (clIndex
% (heightInCL
* pitchInCL
)) / pitchInCL
;
1068 *pX
= clX
* clWidthInTile
* MicroTileWidth
;
1069 *pY
= clY
* clHeightInTile
* MicroTileHeight
;
1070 *pSlice
= clIndex
/ (heightInCL
* pitchInCL
);
1072 macroOffset
= tileIndex
% tileNumPerPipe
;
1075 UINT_32 elemIdx
= macroOffset
& 7;
1076 macroOffset
>>= elemIdxBits
;
1078 if (elemIdxBits
!= macroShift
)
1080 macroOffset
<<= (elemIdxBits
- macroShift
);
1082 UINT_32 pipebit1
= _BIT(pipe
,1);
1083 UINT_32 pipebit2
= _BIT(pipe
,2);
1084 UINT_32 pipebit3
= _BIT(pipe
,3);
1085 if (pitchInMacroTile
% 2)
1087 switch (pTileInfo
->pipeConfig
)
1089 case ADDR_PIPECFG_P4_32x32
:
1090 macroOffset
|= pipebit1
;
1092 case ADDR_PIPECFG_P8_32x32_8x16
:
1093 case ADDR_PIPECFG_P8_32x32_16x16
:
1094 case ADDR_PIPECFG_P8_32x32_16x32
:
1095 macroOffset
|= pipebit2
;
1103 if (pitchInMacroTile
% 4)
1105 if (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
)
1107 macroOffset
|= (pipebit1
<<1);
1109 if((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P16_32x32_8x16
) ||
1110 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P16_32x32_16x16
))
1112 macroOffset
|= (pipebit3
<<1);
1122 macroX
= macroOffset
% pitchInMacroTile
;
1123 macroY
= macroOffset
/ pitchInMacroTile
;
1127 const UINT_32 clWidthInMacroTile
= clWidth
/ (MicroTileWidth
* 4);
1128 macroX
= macroOffset
% clWidthInMacroTile
;
1129 macroY
= macroOffset
/ clWidthInMacroTile
;
1132 *pX
+= macroX
* 4 * MicroTileWidth
;
1133 *pY
+= macroY
* 4 * MicroTileHeight
;
1137 ComputeTileCoordFromPipeAndElemIdx(elemIdx
, pipe
, pTileInfo
->pipeConfig
, pitchInMacroTile
,
1138 *pX
, *pY
, µX
, µY
);
1140 *pX
+= microX
* MicroTileWidth
;
1141 *pY
+= microY
* MicroTileWidth
;
1145 ***************************************************************************************************
1146 * SiAddrLib::HwlGetPitchAlignmentLinear
1148 * Get pitch alignment
1151 ***************************************************************************************************
1153 UINT_32
SiAddrLib::HwlGetPitchAlignmentLinear(
1154 UINT_32 bpp
, ///< [in] bits per pixel
1155 ADDR_SURFACE_FLAGS flags
///< [in] surface flags
1160 // Interleaved access requires a 256B aligned pitch, so fall back to pre-SI alignment
1161 if (flags
.interleaved
)
1163 pitchAlign
= Max(64u, m_pipeInterleaveBytes
/ BITS_TO_BYTES(bpp
));
1168 pitchAlign
= Max(8u, 64 / BITS_TO_BYTES(bpp
));
1175 ***************************************************************************************************
1176 * SiAddrLib::HwlGetSizeAdjustmentLinear
1179 * Adjust linear surface pitch and slice size
1182 * Logical slice size in bytes
1183 ***************************************************************************************************
1185 UINT_64
SiAddrLib::HwlGetSizeAdjustmentLinear(
1186 AddrTileMode tileMode
, ///< [in] tile mode
1187 UINT_32 bpp
, ///< [in] bits per pixel
1188 UINT_32 numSamples
, ///< [in] number of samples
1189 UINT_32 baseAlign
, ///< [in] base alignment
1190 UINT_32 pitchAlign
, ///< [in] pitch alignment
1191 UINT_32
* pPitch
, ///< [in/out] pointer to pitch
1192 UINT_32
* pHeight
, ///< [in/out] pointer to height
1193 UINT_32
* pHeightAlign
///< [in/out] pointer to height align
1197 if (tileMode
== ADDR_TM_LINEAR_GENERAL
)
1199 sliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(*pPitch
) * (*pHeight
) * bpp
* numSamples
);
1203 UINT_32 pitch
= *pPitch
;
1204 UINT_32 height
= *pHeight
;
1206 UINT_32 pixelsPerPipeInterleave
= m_pipeInterleaveBytes
/ BITS_TO_BYTES(bpp
);
1207 UINT_32 sliceAlignInPixel
= pixelsPerPipeInterleave
< 64 ? 64 : pixelsPerPipeInterleave
;
1209 // numSamples should be 1 in real cases (no MSAA for linear but TGL may pass non 1 value)
1210 UINT_64 pixelPerSlice
= static_cast<UINT_64
>(pitch
) * height
* numSamples
;
1212 while (pixelPerSlice
% sliceAlignInPixel
)
1214 pitch
+= pitchAlign
;
1215 pixelPerSlice
= static_cast<UINT_64
>(pitch
) * height
* numSamples
;
1220 UINT_32 heightAlign
= 1;
1222 while ((pitch
* heightAlign
) % sliceAlignInPixel
)
1227 *pHeightAlign
= heightAlign
;
1229 sliceSize
= BITS_TO_BYTES(pixelPerSlice
* bpp
);
1236 ***************************************************************************************************
1237 * SiAddrLib::HwlPreHandleBaseLvl3xPitch
1240 * Pre-handler of 3x pitch (96 bit) adjustment
1244 ***************************************************************************************************
1246 UINT_32
SiAddrLib::HwlPreHandleBaseLvl3xPitch(
1247 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
1248 UINT_32 expPitch
///< [in] pitch
1251 ADDR_ASSERT(pIn
->width
== expPitch
);
1253 // From SI, if pow2Pad is 1 the pitch is expanded 3x first, then padded to pow2, so nothing to
1255 if (pIn
->flags
.pow2Pad
== FALSE
)
1257 AddrLib1::HwlPreHandleBaseLvl3xPitch(pIn
, expPitch
);
1261 ADDR_ASSERT(IsPow2(expPitch
));
1268 ***************************************************************************************************
1269 * SiAddrLib::HwlPostHandleBaseLvl3xPitch
1272 * Post-handler of 3x pitch adjustment
1276 ***************************************************************************************************
1278 UINT_32
SiAddrLib::HwlPostHandleBaseLvl3xPitch(
1279 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
1280 UINT_32 expPitch
///< [in] pitch
1284 * @note The pitch will be divided by 3 in the end so the value will look odd but h/w should
1285 * be able to compute a correct pitch from it as h/w address library is doing the job.
1287 // From SI, the pitch is expanded 3x first, then padded to pow2, so no special handler here
1288 if (pIn
->flags
.pow2Pad
== FALSE
)
1290 AddrLib1::HwlPostHandleBaseLvl3xPitch(pIn
, expPitch
);
1297 ***************************************************************************************************
1298 * SiAddrLib::HwlGetPitchAlignmentMicroTiled
1301 * Compute 1D tiled surface pitch alignment
1305 ***************************************************************************************************
1307 UINT_32
SiAddrLib::HwlGetPitchAlignmentMicroTiled(
1308 AddrTileMode tileMode
, ///< [in] tile mode
1309 UINT_32 bpp
, ///< [in] bits per pixel
1310 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
1311 UINT_32 numSamples
///< [in] number of samples
1318 pitchAlign
= EgBasedAddrLib::HwlGetPitchAlignmentMicroTiled(tileMode
,bpp
,flags
,numSamples
);
1329 ***************************************************************************************************
1330 * SiAddrLib::HwlGetSizeAdjustmentMicroTiled
1333 * Adjust 1D tiled surface pitch and slice size
1336 * Logical slice size in bytes
1337 ***************************************************************************************************
1339 UINT_64
SiAddrLib::HwlGetSizeAdjustmentMicroTiled(
1340 UINT_32 thickness
, ///< [in] thickness
1341 UINT_32 bpp
, ///< [in] bits per pixel
1342 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
1343 UINT_32 numSamples
, ///< [in] number of samples
1344 UINT_32 baseAlign
, ///< [in] base alignment
1345 UINT_32 pitchAlign
, ///< [in] pitch alignment
1346 UINT_32
* pPitch
, ///< [in/out] pointer to pitch
1347 UINT_32
* pHeight
///< [in/out] pointer to height
1350 UINT_64 logicalSliceSize
;
1351 UINT_64 physicalSliceSize
;
1353 UINT_32 pitch
= *pPitch
;
1354 UINT_32 height
= *pHeight
;
1356 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
1357 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
1359 // Physical slice: multiplied by thickness
1360 physicalSliceSize
= logicalSliceSize
* thickness
;
1362 // Pitch alignment is always 8, so if slice size is not padded to base alignment
1363 // (pipe_interleave_size), we need to increase pitch
1364 while ((physicalSliceSize
% baseAlign
) != 0)
1366 pitch
+= pitchAlign
;
1368 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
1370 physicalSliceSize
= logicalSliceSize
* thickness
;
1375 // Special workaround for depth/stencil buffer, use 8 bpp to align depth buffer again since
1376 // the stencil plane may have larger pitch if the slice size is smaller than base alignment.
1378 // Note: this actually does not work for mipmap but mipmap depth texture is not really
1379 // sampled with mipmap.
1381 if (flags
.depth
&& (flags
.noStencil
== FALSE
))
1383 ADDR_ASSERT(numSamples
== 1);
1385 UINT_64 logicalSiceSizeStencil
= static_cast<UINT_64
>(pitch
) * height
; // 1 byte stencil
1387 while ((logicalSiceSizeStencil
% baseAlign
) != 0)
1389 pitch
+= pitchAlign
; // Stencil plane's pitch alignment is the same as depth plane's
1391 logicalSiceSizeStencil
= static_cast<UINT_64
>(pitch
) * height
;
1394 if (pitch
!= *pPitch
)
1396 // If this is a mipmap, this padded one cannot be sampled as a whole mipmap!
1397 logicalSliceSize
= logicalSiceSizeStencil
* BITS_TO_BYTES(bpp
);
1403 // No adjust for pHeight
1405 return logicalSliceSize
;
1409 ***************************************************************************************************
1410 * SiAddrLib::HwlConvertChipFamily
1413 * Convert familyID defined in atiid.h to AddrChipFamily and set m_chipFamily/m_chipRevision
1416 ***************************************************************************************************
1418 AddrChipFamily
SiAddrLib::HwlConvertChipFamily(
1419 UINT_32 uChipFamily
, ///< [in] chip family defined in atiih.h
1420 UINT_32 uChipRevision
) ///< [in] chip revision defined in "asic_family"_id.h
1422 AddrChipFamily family
= ADDR_CHIP_FAMILY_SI
;
1424 switch (uChipFamily
)
1427 m_settings
.isSouthernIsland
= 1;
1428 m_settings
.isTahiti
= ASICREV_IS_TAHITI_P(uChipRevision
);
1429 m_settings
.isPitCairn
= ASICREV_IS_PITCAIRN_PM(uChipRevision
);
1430 m_settings
.isCapeVerde
= ASICREV_IS_CAPEVERDE_M(uChipRevision
);
1431 m_settings
.isOland
= ASICREV_IS_OLAND_M(uChipRevision
);
1432 m_settings
.isHainan
= ASICREV_IS_HAINAN_V(uChipRevision
);
1435 ADDR_ASSERT(!"This should be a Fusion");
1443 ***************************************************************************************************
1444 * SiAddrLib::HwlSetupTileInfo
1447 * Setup default value of tile info for SI
1448 ***************************************************************************************************
1450 VOID
SiAddrLib::HwlSetupTileInfo(
1451 AddrTileMode tileMode
, ///< [in] Tile mode
1452 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface type flags
1453 UINT_32 bpp
, ///< [in] Bits per pixel
1454 UINT_32 pitch
, ///< [in] Pitch in pixels
1455 UINT_32 height
, ///< [in] Height in pixels
1456 UINT_32 numSamples
, ///< [in] Number of samples
1457 ADDR_TILEINFO
* pTileInfoIn
, ///< [in] Tile info input: NULL for default
1458 ADDR_TILEINFO
* pTileInfoOut
, ///< [out] Tile info output
1459 AddrTileType inTileType
, ///< [in] Tile type
1460 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] Output
1463 UINT_32 thickness
= Thickness(tileMode
);
1464 ADDR_TILEINFO
* pTileInfo
= pTileInfoOut
;
1465 INT index
= TileIndexInvalid
;
1468 if (IsLinear(tileMode
) == FALSE
)
1470 // 128 bpp/thick tiling must be non-displayable.
1471 // Fmask reuse color buffer's entry but bank-height field can be from another entry
1472 // To simplify the logic, fmask entry should be picked from non-displayable ones
1473 if (bpp
== 128 || thickness
> 1 || flags
.fmask
|| flags
.prt
)
1475 inTileType
= ADDR_NON_DISPLAYABLE
;
1478 if (flags
.depth
|| flags
.stencil
)
1480 inTileType
= ADDR_DEPTH_SAMPLE_ORDER
;
1484 // Partial valid fields are not allowed for SI.
1485 if (IsTileInfoAllZero(pTileInfo
))
1487 if (IsMacroTiled(tileMode
))
1491 if (numSamples
== 1)
1504 ADDR_ASSERT_ALWAYS();
1533 ADDR_ASSERT(bpp
!= 128);
1540 ADDR_ASSERT(numSamples
== 4);
1553 ADDR_ASSERT_ALWAYS();
1574 ADDR_ASSERT_ALWAYS();
1580 // See table entries 0-7
1581 else if (flags
.depth
|| flags
.stencil
)
1583 if (flags
.compressZ
)
1591 // optimal tile index for compressed depth/stencil.
1614 else //non PRT & non Depth & non Stencil
1616 // See table entries 9-12
1617 if (inTileType
== ADDR_DISPLAYABLE
)
1639 // See table entries 13-17
1644 UINT_32 fmaskPixelSize
= bpp
* numSamples
;
1646 switch (fmaskPixelSize
)
1661 ADDR_ASSERT_ALWAYS();
1688 else // thick tiling - entries 18-20
1707 if (tileMode
== ADDR_TM_LINEAR_ALIGNED
)
1711 else if (tileMode
== ADDR_TM_LINEAR_GENERAL
)
1713 index
= TileIndexLinearGeneral
;
1717 if (flags
.depth
|| flags
.stencil
)
1721 else if (inTileType
== ADDR_DISPLAYABLE
)
1725 else if (thickness
== 1)
1736 if (index
>= 0 && index
<= 31)
1738 *pTileInfo
= m_tileTable
[index
].info
;
1739 pOut
->tileType
= m_tileTable
[index
].type
;
1742 if (index
== TileIndexLinearGeneral
)
1744 *pTileInfo
= m_tileTable
[8].info
;
1745 pOut
->tileType
= m_tileTable
[8].type
;
1752 if (flags
.stencil
&& pTileInfoIn
->tileSplitBytes
== 0)
1754 // Stencil always uses index 0
1755 *pTileInfo
= m_tileTable
[0].info
;
1758 // Pass through tile type
1759 pOut
->tileType
= inTileType
;
1762 pOut
->tileIndex
= index
;
1766 ***************************************************************************************************
1767 * SiAddrLib::DecodeGbRegs
1770 * Decodes GB_ADDR_CONFIG and noOfBanks/noOfRanks
1773 * TRUE if all settings are valid
1775 ***************************************************************************************************
1777 BOOL_32
SiAddrLib::DecodeGbRegs(
1778 const ADDR_REGISTER_VALUE
* pRegValue
) ///< [in] create input
1781 BOOL_32 valid
= TRUE
;
1783 reg
.val
= pRegValue
->gbAddrConfig
;
1785 switch (reg
.f
.pipe_interleave_size
)
1787 case ADDR_CONFIG_PIPE_INTERLEAVE_256B
:
1788 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_256B
;
1790 case ADDR_CONFIG_PIPE_INTERLEAVE_512B
:
1791 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_512B
;
1795 ADDR_UNHANDLED_CASE();
1799 switch (reg
.f
.row_size
)
1801 case ADDR_CONFIG_1KB_ROW
:
1802 m_rowSize
= ADDR_ROWSIZE_1KB
;
1804 case ADDR_CONFIG_2KB_ROW
:
1805 m_rowSize
= ADDR_ROWSIZE_2KB
;
1807 case ADDR_CONFIG_4KB_ROW
:
1808 m_rowSize
= ADDR_ROWSIZE_4KB
;
1812 ADDR_UNHANDLED_CASE();
1816 switch (pRegValue
->noOfBanks
)
1829 ADDR_UNHANDLED_CASE();
1833 switch (pRegValue
->noOfRanks
)
1843 ADDR_UNHANDLED_CASE();
1847 m_logicalBanks
= m_banks
* m_ranks
;
1849 ADDR_ASSERT(m_logicalBanks
<= 16);
1855 ***************************************************************************************************
1856 * SiAddrLib::HwlInitGlobalParams
1859 * Initializes global parameters
1862 * TRUE if all settings are valid
1864 ***************************************************************************************************
1866 BOOL_32
SiAddrLib::HwlInitGlobalParams(
1867 const ADDR_CREATE_INPUT
* pCreateIn
) ///< [in] create input
1869 BOOL_32 valid
= TRUE
;
1870 const ADDR_REGISTER_VALUE
* pRegValue
= &pCreateIn
->regValue
;
1872 valid
= DecodeGbRegs(pRegValue
);
1876 if (m_settings
.isTahiti
|| m_settings
.isPitCairn
)
1880 else if (m_settings
.isCapeVerde
|| m_settings
.isOland
)
1886 // Hainan is 2-pipe (m_settings.isHainan == 1)
1890 valid
= InitTileSettingTable(pRegValue
->pTileConfig
, pRegValue
->noOfEntries
);
1899 ***************************************************************************************************
1900 * SiAddrLib::HwlConvertTileInfoToHW
1902 * Entry of si's ConvertTileInfoToHW
1905 ***************************************************************************************************
1907 ADDR_E_RETURNCODE
SiAddrLib::HwlConvertTileInfoToHW(
1908 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
1909 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
1912 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
1914 retCode
= EgBasedAddrLib::HwlConvertTileInfoToHW(pIn
, pOut
);
1916 if (retCode
== ADDR_OK
)
1918 if (pIn
->reverse
== FALSE
)
1920 if (pIn
->pTileInfo
->pipeConfig
== ADDR_PIPECFG_INVALID
)
1922 retCode
= ADDR_INVALIDPARAMS
;
1926 pOut
->pTileInfo
->pipeConfig
=
1927 static_cast<AddrPipeCfg
>(pIn
->pTileInfo
->pipeConfig
- 1);
1932 pOut
->pTileInfo
->pipeConfig
=
1933 static_cast<AddrPipeCfg
>(pIn
->pTileInfo
->pipeConfig
+ 1);
1941 ***************************************************************************************************
1942 * SiAddrLib::HwlComputeXmaskCoordYFrom8Pipe
1945 * Compute the Y coord which will be added to Xmask Y
1949 ***************************************************************************************************
1951 UINT_32
SiAddrLib::HwlComputeXmaskCoordYFrom8Pipe(
1952 UINT_32 pipe
, ///< [in] pipe id
1953 UINT_32 x
///< [in] tile coord x, which is original x coord / 8
1956 // This function should never be called since it is 6xx/8xx specfic.
1957 // Keep this empty implementation to avoid any mis-use.
1958 ADDR_ASSERT_ALWAYS();
1964 ***************************************************************************************************
1965 * SiAddrLib::HwlComputeSurfaceCoord2DFromBankPipe
1968 * Compute surface x,y coordinates from bank/pipe info
1971 ***************************************************************************************************
1973 VOID
SiAddrLib::HwlComputeSurfaceCoord2DFromBankPipe(
1974 AddrTileMode tileMode
, ///< [in] tile mode
1975 UINT_32
* pX
, ///< [in/out] x coordinate
1976 UINT_32
* pY
, ///< [in/out] y coordinate
1977 UINT_32 slice
, ///< [in] slice index
1978 UINT_32 bank
, ///< [in] bank number
1979 UINT_32 pipe
, ///< [in] pipe number
1980 UINT_32 bankSwizzle
,///< [in] bank swizzle
1981 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
1982 UINT_32 tileSlices
, ///< [in] slices in a micro tile
1983 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines are ignored
1984 ADDR_TILEINFO
* pTileInfo
///< [in] bank structure. **All fields to be valid on entry**
1998 UINT_32 numPipes
= GetPipePerSurf(pTileInfo
->pipeConfig
);
2000 CoordFromBankPipe xyBits
= {0};
2001 ComputeSurfaceCoord2DFromBankPipe(tileMode
, *pX
, *pY
, slice
, bank
, pipe
,
2002 bankSwizzle
, pipeSwizzle
, tileSlices
, pTileInfo
,
2004 yBit3
= xyBits
.yBit3
;
2005 yBit4
= xyBits
.yBit4
;
2006 yBit5
= xyBits
.yBit5
;
2007 yBit6
= xyBits
.yBit6
;
2009 xBit3
= xyBits
.xBit3
;
2010 xBit4
= xyBits
.xBit4
;
2011 xBit5
= xyBits
.xBit5
;
2013 yBit
= xyBits
.yBits
;
2015 UINT_32 yBitTemp
= 0;
2017 if ((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P4_32x32
) ||
2018 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
))
2020 ADDR_ASSERT(pTileInfo
->bankWidth
== 1 && pTileInfo
->macroAspectRatio
> 1);
2021 UINT_32 yBitToCheck
= QLog2(pTileInfo
->banks
) - 1;
2023 ADDR_ASSERT(yBitToCheck
<= 3);
2025 yBitTemp
= _BIT(yBit
, yBitToCheck
);
2030 yBit
= Bits2Number(4, yBit6
, yBit5
, yBit4
, yBit3
);
2031 xBit
= Bits2Number(3, xBit5
, xBit4
, xBit3
);
2033 *pY
+= yBit
* pTileInfo
->bankHeight
* MicroTileHeight
;
2034 *pX
+= xBit
* numPipes
* pTileInfo
->bankWidth
* MicroTileWidth
;
2036 //calculate the bank and pipe bits in x, y
2037 UINT_32 xTile
; //x in micro tile
2044 UINT_32 pipeBit0
= _BIT(pipe
,0);
2045 UINT_32 pipeBit1
= _BIT(pipe
,1);
2046 UINT_32 pipeBit2
= _BIT(pipe
,2);
2048 UINT_32 y3
= _BIT(y
, 3);
2049 UINT_32 y4
= _BIT(y
, 4);
2050 UINT_32 y5
= _BIT(y
, 5);
2051 UINT_32 y6
= _BIT(y
, 6);
2053 // bankbit0 after ^x4^x5
2054 UINT_32 bankBit00
= _BIT(bank
,0);
2055 UINT_32 bankBit0
= 0;
2057 switch (pTileInfo
->pipeConfig
)
2059 case ADDR_PIPECFG_P2
:
2062 case ADDR_PIPECFG_P4_8x16
:
2066 case ADDR_PIPECFG_P4_16x16
:
2068 x3
= pipeBit0
^ y3
^ x4
;
2070 case ADDR_PIPECFG_P4_16x32
:
2072 x3
= pipeBit0
^ y3
^ x4
;
2074 case ADDR_PIPECFG_P4_32x32
:
2076 x3
= pipeBit0
^ y3
^ x5
;
2077 bankBit0
= yBitTemp
^ x5
;
2078 x4
= bankBit00
^ x5
^ bankBit0
;
2079 *pX
+= x5
* 4 * 1 * 8; // x5 * num_pipes * bank_width * 8;
2081 case ADDR_PIPECFG_P8_16x16_8x16
:
2084 x5
= pipeBit0
^ y3
^ x4
;
2086 case ADDR_PIPECFG_P8_16x32_8x16
:
2089 x5
= pipeBit0
^ y3
^ x4
;
2091 case ADDR_PIPECFG_P8_32x32_8x16
:
2094 x4
= pipeBit0
^ y3
^ x5
;
2096 case ADDR_PIPECFG_P8_16x32_16x16
:
2099 x3
= pipeBit0
^ y3
^ x4
;
2101 case ADDR_PIPECFG_P8_32x32_16x16
:
2104 x3
= pipeBit0
^ y3
^ x4
;
2106 case ADDR_PIPECFG_P8_32x32_16x32
:
2109 x3
= pipeBit0
^ y3
^ x4
;
2111 case ADDR_PIPECFG_P8_32x64_32x32
:
2114 x3
= pipeBit0
^ y3
^ x5
;
2115 bankBit0
= yBitTemp
^ x6
;
2116 x4
= bankBit00
^ x5
^ bankBit0
;
2117 *pX
+= x6
* 8 * 1 * 8; // x6 * num_pipes * bank_width * 8;
2120 ADDR_ASSERT_ALWAYS();
2123 xTile
= Bits2Number(3, x5
, x4
, x3
);
2129 ***************************************************************************************************
2130 * SiAddrLib::HwlPreAdjustBank
2133 * Adjust bank before calculating address acoording to bank/pipe
2136 ***************************************************************************************************
2138 UINT_32
SiAddrLib::HwlPreAdjustBank(
2139 UINT_32 tileX
, ///< [in] x coordinate in unit of tile
2140 UINT_32 bank
, ///< [in] bank
2141 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2144 if (((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P4_32x32
) ||
2145 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
)) && (pTileInfo
->bankWidth
== 1))
2147 UINT_32 bankBit0
= _BIT(bank
, 0);
2148 UINT_32 x4
= _BIT(tileX
, 1);
2149 UINT_32 x5
= _BIT(tileX
, 2);
2151 bankBit0
= bankBit0
^ x4
^ x5
;
2154 ADDR_ASSERT(pTileInfo
->macroAspectRatio
> 1);
2161 ***************************************************************************************************
2162 * SiAddrLib::HwlComputeSurfaceInfo
2165 * Entry of si's ComputeSurfaceInfo
2168 ***************************************************************************************************
2170 ADDR_E_RETURNCODE
SiAddrLib::HwlComputeSurfaceInfo(
2171 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
2172 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
2175 pOut
->tileIndex
= pIn
->tileIndex
;
2177 return EgBasedAddrLib::HwlComputeSurfaceInfo(pIn
,pOut
);
2181 ***************************************************************************************************
2182 * SiAddrLib::HwlComputeMipLevel
2184 * Compute MipLevel info (including level 0)
2186 * TRUE if HWL's handled
2187 ***************************************************************************************************
2189 BOOL_32
SiAddrLib::HwlComputeMipLevel(
2190 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
///< [in/out] Input structure
2193 // basePitch is calculated from level 0 so we only check this for mipLevel > 0
2194 if (pIn
->mipLevel
> 0)
2196 // Note: Don't check expand 3x formats(96 bit) as the basePitch is not pow2 even if
2197 // we explicity set pow2Pad flag. The 3x base pitch is padded to pow2 but after being
2198 // divided by expandX factor (3) - to program texture pitch, the basePitch is never pow2.
2199 if (AddrElemLib::IsExpand3x(pIn
->format
) == FALSE
)
2201 // Sublevel pitches are generated from base level pitch instead of width on SI
2202 // If pow2Pad is 0, we don't assert - as this is not really used for a mip chain
2203 ADDR_ASSERT((pIn
->flags
.pow2Pad
== FALSE
) ||
2204 ((pIn
->basePitch
!= 0) && IsPow2(pIn
->basePitch
)));
2207 if (pIn
->basePitch
!= 0)
2209 pIn
->width
= Max(1u, pIn
->basePitch
>> pIn
->mipLevel
);
2213 // pow2Pad is done in PostComputeMipLevel
2219 ***************************************************************************************************
2220 * SiAddrLib::HwlCheckLastMacroTiledLvl
2223 * Sets pOut->last2DLevel to TRUE if it is
2226 ***************************************************************************************************
2228 VOID
SiAddrLib::HwlCheckLastMacroTiledLvl(
2229 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
2230 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in/out] Output structure (used as input, too)
2233 // pow2Pad covers all mipmap cases
2234 if (pIn
->flags
.pow2Pad
)
2236 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
2242 AddrTileMode nextTileMode
;
2244 if (pIn
->mipLevel
== 0 || pIn
->basePitch
== 0)
2246 // Base level or fail-safe case (basePitch == 0)
2247 nextPitch
= pOut
->pitch
>> 1;
2252 nextPitch
= pIn
->basePitch
>> (pIn
->mipLevel
+ 1);
2255 // nextHeight must be shifted from this level's original height rather than a pow2 padded
2256 // one but this requires original height stored somewhere (pOut->height)
2257 ADDR_ASSERT(pOut
->height
!= 0);
2259 // next level's height is just current level's >> 1 in pixels
2260 nextHeight
= pOut
->height
>> 1;
2261 // Special format such as FMT_1 and FMT_32_32_32 can be linear only so we consider block
2262 // compressed foramts
2263 if (AddrElemLib::IsBlockCompressed(pIn
->format
))
2265 nextHeight
= (nextHeight
+ 3) / 4;
2267 nextHeight
= NextPow2(nextHeight
);
2269 // nextSlices may be 0 if this level's is 1
2270 if (pIn
->flags
.volume
)
2272 nextSlices
= Max(1u, pIn
->numSlices
>> 1);
2276 nextSlices
= pIn
->numSlices
;
2279 nextTileMode
= ComputeSurfaceMipLevelTileMode(pIn
->tileMode
,
2289 pOut
->last2DLevel
= IsMicroTiled(nextTileMode
);
2294 ***************************************************************************************************
2295 * SiAddrLib::HwlDegradeThickTileMode
2298 * Degrades valid tile mode for thick modes if needed
2301 * Suitable tile mode
2302 ***************************************************************************************************
2304 AddrTileMode
SiAddrLib::HwlDegradeThickTileMode(
2305 AddrTileMode baseTileMode
, ///< [in] base tile mode
2306 UINT_32 numSlices
, ///< [in] current number of slices
2307 UINT_32
* pBytesPerTile
///< [in/out] pointer to bytes per slice
2310 return EgBasedAddrLib::HwlDegradeThickTileMode(baseTileMode
, numSlices
, pBytesPerTile
);
2314 ***************************************************************************************************
2315 * SiAddrLib::HwlTileInfoEqual
2318 * Return TRUE if all field are equal
2320 * Only takes care of current HWL's data
2321 ***************************************************************************************************
2323 BOOL_32
SiAddrLib::HwlTileInfoEqual(
2324 const ADDR_TILEINFO
* pLeft
, ///<[in] Left compare operand
2325 const ADDR_TILEINFO
* pRight
///<[in] Right compare operand
2328 BOOL_32 equal
= FALSE
;
2330 if (pLeft
->pipeConfig
== pRight
->pipeConfig
)
2332 equal
= EgBasedAddrLib::HwlTileInfoEqual(pLeft
, pRight
);
2339 ***************************************************************************************************
2340 * SiAddrLib::GetTileSettings
2343 * Get tile setting infos by index.
2345 * Tile setting info.
2346 ***************************************************************************************************
2348 const ADDR_TILECONFIG
* SiAddrLib::GetTileSetting(
2349 UINT_32 index
///< [in] Tile index
2352 ADDR_ASSERT(index
< m_noOfEntries
);
2353 return &m_tileTable
[index
];
2357 ***************************************************************************************************
2358 * SiAddrLib::HwlPostCheckTileIndex
2361 * Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches
2362 * tile mode/type/info and change the index if needed
2365 ***************************************************************************************************
2367 INT_32
SiAddrLib::HwlPostCheckTileIndex(
2368 const ADDR_TILEINFO
* pInfo
, ///< [in] Tile Info
2369 AddrTileMode mode
, ///< [in] Tile mode
2370 AddrTileType type
, ///< [in] Tile type
2371 INT curIndex
///< [in] Current index assigned in HwlSetupTileInfo
2374 INT_32 index
= curIndex
;
2376 if (mode
== ADDR_TM_LINEAR_GENERAL
)
2378 index
= TileIndexLinearGeneral
;
2382 BOOL_32 macroTiled
= IsMacroTiled(mode
);
2384 // We need to find a new index if either of them is true
2385 // 1. curIndex is invalid
2386 // 2. tile mode is changed
2387 // 3. tile info does not match for macro tiled
2388 if ((index
== TileIndexInvalid
||
2389 (mode
!= m_tileTable
[index
].mode
) ||
2390 (macroTiled
&& (HwlTileInfoEqual(pInfo
, &m_tileTable
[index
].info
) == FALSE
))))
2392 for (index
= 0; index
< static_cast<INT_32
>(m_noOfEntries
); index
++)
2396 // macro tile modes need all to match
2397 if (HwlTileInfoEqual(pInfo
, &m_tileTable
[index
].info
) &&
2398 (mode
== m_tileTable
[index
].mode
) &&
2399 (type
== m_tileTable
[index
].type
))
2404 else if (mode
== ADDR_TM_LINEAR_ALIGNED
)
2406 // linear mode only needs tile mode to match
2407 if (mode
== m_tileTable
[index
].mode
)
2414 // micro tile modes only need tile mode and tile type to match
2415 if (mode
== m_tileTable
[index
].mode
&&
2416 type
== m_tileTable
[index
].type
)
2425 ADDR_ASSERT(index
< static_cast<INT_32
>(m_noOfEntries
));
2427 if (index
>= static_cast<INT_32
>(m_noOfEntries
))
2429 index
= TileIndexInvalid
;
2436 ***************************************************************************************************
2437 * SiAddrLib::HwlSetupTileCfg
2440 * Map tile index to tile setting.
2443 ***************************************************************************************************
2445 ADDR_E_RETURNCODE
SiAddrLib::HwlSetupTileCfg(
2446 UINT_32 bpp
, ///< [in] Bits per pixel
2447 INT_32 index
, ///< [in] Tile index
2448 INT_32 macroModeIndex
, ///< [in] Index in macro tile mode table(CI)
2449 ADDR_TILEINFO
* pInfo
, ///< [out] Tile Info
2450 AddrTileMode
* pMode
, ///< [out] Tile mode
2451 AddrTileType
* pType
///< [out] Tile type
2454 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
2456 // Global flag to control usage of tileIndex
2457 if (UseTileIndex(index
))
2459 if (index
== TileIndexLinearGeneral
)
2463 *pMode
= ADDR_TM_LINEAR_GENERAL
;
2468 *pType
= ADDR_DISPLAYABLE
;
2474 pInfo
->bankWidth
= 1;
2475 pInfo
->bankHeight
= 1;
2476 pInfo
->macroAspectRatio
= 1;
2477 pInfo
->tileSplitBytes
= 64;
2478 pInfo
->pipeConfig
= ADDR_PIPECFG_P2
;
2481 else if (static_cast<UINT_32
>(index
) >= m_noOfEntries
)
2483 returnCode
= ADDR_INVALIDPARAMS
;
2487 const ADDR_TILECONFIG
* pCfgTable
= GetTileSetting(index
);
2491 *pInfo
= pCfgTable
->info
;
2495 if (IsMacroTiled(pCfgTable
->mode
))
2497 returnCode
= ADDR_INVALIDPARAMS
;
2503 *pMode
= pCfgTable
->mode
;
2508 *pType
= pCfgTable
->type
;
2517 ***************************************************************************************************
2518 * SiAddrLib::ReadGbTileMode
2521 * Convert GB_TILE_MODE HW value to ADDR_TILE_CONFIG.
2524 ***************************************************************************************************
2526 VOID
SiAddrLib::ReadGbTileMode(
2527 UINT_32 regValue
, ///< [in] GB_TILE_MODE register
2528 ADDR_TILECONFIG
* pCfg
///< [out] output structure
2531 GB_TILE_MODE gbTileMode
;
2532 gbTileMode
.val
= regValue
;
2534 pCfg
->type
= static_cast<AddrTileType
>(gbTileMode
.f
.micro_tile_mode
);
2535 pCfg
->info
.bankHeight
= 1 << gbTileMode
.f
.bank_height
;
2536 pCfg
->info
.bankWidth
= 1 << gbTileMode
.f
.bank_width
;
2537 pCfg
->info
.banks
= 1 << (gbTileMode
.f
.num_banks
+ 1);
2538 pCfg
->info
.macroAspectRatio
= 1 << gbTileMode
.f
.macro_tile_aspect
;
2539 pCfg
->info
.tileSplitBytes
= 64 << gbTileMode
.f
.tile_split
;
2540 pCfg
->info
.pipeConfig
= static_cast<AddrPipeCfg
>(gbTileMode
.f
.pipe_config
+ 1);
2542 UINT_32 regArrayMode
= gbTileMode
.f
.array_mode
;
2544 pCfg
->mode
= static_cast<AddrTileMode
>(regArrayMode
);
2546 if (regArrayMode
== 8) //ARRAY_2D_TILED_XTHICK
2548 pCfg
->mode
= ADDR_TM_2D_TILED_XTHICK
;
2550 else if (regArrayMode
>= 14) //ARRAY_3D_TILED_XTHICK
2552 pCfg
->mode
= static_cast<AddrTileMode
>(pCfg
->mode
+ 3);
2557 ***************************************************************************************************
2558 * SiAddrLib::InitTileSettingTable
2561 * Initialize the ADDR_TILE_CONFIG table.
2563 * TRUE if tile table is correctly initialized
2564 ***************************************************************************************************
2566 BOOL_32
SiAddrLib::InitTileSettingTable(
2567 const UINT_32
* pCfg
, ///< [in] Pointer to table of tile configs
2568 UINT_32 noOfEntries
///< [in] Numbe of entries in the table above
2571 BOOL_32 initOk
= TRUE
;
2573 ADDR_ASSERT(noOfEntries
<= TileTableSize
);
2575 memset(m_tileTable
, 0, sizeof(m_tileTable
));
2577 if (noOfEntries
!= 0)
2579 m_noOfEntries
= noOfEntries
;
2583 m_noOfEntries
= TileTableSize
;
2586 if (pCfg
) // From Client
2588 for (UINT_32 i
= 0; i
< m_noOfEntries
; i
++)
2590 ReadGbTileMode(*(pCfg
+ i
), &m_tileTable
[i
]);
2595 ADDR_ASSERT_ALWAYS();
2601 ADDR_ASSERT(m_tileTable
[TILEINDEX_LINEAR_ALIGNED
].mode
== ADDR_TM_LINEAR_ALIGNED
);
2608 ***************************************************************************************************
2609 * SiAddrLib::HwlGetTileIndex
2612 * Return the virtual/real index for given mode/type/info
2614 * ADDR_OK if successful.
2615 ***************************************************************************************************
2617 ADDR_E_RETURNCODE
SiAddrLib::HwlGetTileIndex(
2618 const ADDR_GET_TILEINDEX_INPUT
* pIn
,
2619 ADDR_GET_TILEINDEX_OUTPUT
* pOut
) const
2621 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
2623 pOut
->index
= HwlPostCheckTileIndex(pIn
->pTileInfo
, pIn
->tileMode
, pIn
->tileType
);
2629 ***************************************************************************************************
2630 * SiAddrLib::HwlFmaskPreThunkSurfInfo
2633 * Some preparation before thunking a ComputeSurfaceInfo call for Fmask
2636 ***************************************************************************************************
2638 VOID
SiAddrLib::HwlFmaskPreThunkSurfInfo(
2639 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pFmaskIn
, ///< [in] Input of fmask info
2640 const ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pFmaskOut
, ///< [in] Output of fmask info
2641 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pSurfIn
, ///< [out] Input of thunked surface info
2642 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pSurfOut
///< [out] Output of thunked surface info
2645 pSurfIn
->tileIndex
= pFmaskIn
->tileIndex
;
2649 ***************************************************************************************************
2650 * SiAddrLib::HwlFmaskPostThunkSurfInfo
2653 * Copy hwl extra field after calling thunked ComputeSurfaceInfo
2656 ***************************************************************************************************
2658 VOID
SiAddrLib::HwlFmaskPostThunkSurfInfo(
2659 const ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pSurfOut
, ///< [in] Output of surface info
2660 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pFmaskOut
///< [out] Output of fmask info
2663 pFmaskOut
->macroModeIndex
= TileIndexInvalid
;
2664 pFmaskOut
->tileIndex
= pSurfOut
->tileIndex
;
2668 ***************************************************************************************************
2669 * SiAddrLib::HwlComputeFmaskBits
2671 * Computes fmask bits
2674 ***************************************************************************************************
2676 UINT_32
SiAddrLib::HwlComputeFmaskBits(
2677 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
,
2678 UINT_32
* pNumSamples
2681 UINT_32 numSamples
= pIn
->numSamples
;
2682 UINT_32 numFrags
= GetNumFragments(numSamples
, pIn
->numFrags
);
2685 if (numFrags
!= numSamples
) // EQAA
2687 ADDR_ASSERT(numFrags
<= 8);
2689 if (pIn
->resolved
== FALSE
)
2694 numSamples
= numSamples
== 16 ? 16 : 8;
2696 else if (numFrags
== 2)
2698 ADDR_ASSERT(numSamples
>= 4);
2701 numSamples
= numSamples
;
2703 else if (numFrags
== 4)
2705 ADDR_ASSERT(numSamples
>= 4);
2708 numSamples
= numSamples
;
2710 else // numFrags == 8
2712 ADDR_ASSERT(numSamples
== 16);
2715 numSamples
= numSamples
;
2722 bpp
= (numSamples
== 16) ? 16 : 8;
2725 else if (numFrags
== 2)
2727 ADDR_ASSERT(numSamples
>= 4);
2732 else if (numFrags
== 4)
2734 ADDR_ASSERT(numSamples
>= 4);
2739 else // numFrags == 8
2741 ADDR_ASSERT(numSamples
>= 16);
2750 if (pIn
->resolved
== FALSE
)
2752 bpp
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
2753 numSamples
= numSamples
== 2 ? 8 : numSamples
;
2758 bpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
2759 numSamples
= 1; // 1x sample
2763 SafeAssign(pNumSamples
, numSamples
);
2769 ***************************************************************************************************
2770 * SiAddrLib::HwlOverrideTileMode
2773 * Override tile modes (for PRT only, avoid client passes in an invalid PRT mode for SI.
2776 * Suitable tile mode
2778 ***************************************************************************************************
2780 BOOL_32
SiAddrLib::HwlOverrideTileMode(
2781 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
2782 AddrTileMode
* pTileMode
, ///< [in/out] pointer to the tile mode
2783 AddrTileType
* pTileType
///< [in/out] pointer to the tile type
2786 BOOL_32 bOverrided
= FALSE
;
2787 AddrTileMode tileMode
= *pTileMode
;
2791 case ADDR_TM_PRT_TILED_THIN1
:
2792 tileMode
= ADDR_TM_2D_TILED_THIN1
;
2795 case ADDR_TM_PRT_TILED_THICK
:
2796 tileMode
= ADDR_TM_2D_TILED_THICK
;
2799 case ADDR_TM_PRT_2D_TILED_THICK
:
2800 tileMode
= ADDR_TM_2D_TILED_THICK
;
2803 case ADDR_TM_PRT_3D_TILED_THICK
:
2804 tileMode
= ADDR_TM_3D_TILED_THICK
;
2811 if (tileMode
!= *pTileMode
)
2813 *pTileMode
= tileMode
;
2815 ADDR_ASSERT(pIn
->flags
.prt
== TRUE
);
2822 ***************************************************************************************************
2823 * SiAddrLib::HwlGetMaxAlignments
2826 * Gets maximum alignments
2829 ***************************************************************************************************
2831 ADDR_E_RETURNCODE
SiAddrLib::HwlGetMaxAlignments(
2832 ADDR_GET_MAX_ALINGMENTS_OUTPUT
* pOut
///< [out] output structure
2835 const UINT_32 pipes
= HwlGetPipes(&m_tileTable
[0].info
);
2837 // Initial size is 64 KiB for PRT.
2838 UINT_64 maxBaseAlign
= 64 * 1024;
2840 for (UINT_32 i
= 0; i
< m_noOfEntries
; i
++)
2842 if ((IsMacroTiled(m_tileTable
[i
].mode
) == TRUE
) &&
2843 (IsPrtTileMode(m_tileTable
[i
].mode
) == FALSE
))
2845 // The maximum tile size is 16 byte-per-pixel and either 8-sample or 8-slice.
2846 UINT_32 tileSize
= Min(m_tileTable
[i
].info
.tileSplitBytes
,
2847 MicroTilePixels
* 8 * 16);
2849 UINT_64 baseAlign
= tileSize
* pipes
* m_tileTable
[i
].info
.banks
*
2850 m_tileTable
[i
].info
.bankWidth
* m_tileTable
[i
].info
.bankHeight
;
2852 if (baseAlign
> maxBaseAlign
)
2854 maxBaseAlign
= baseAlign
;
2861 pOut
->baseAlign
= maxBaseAlign
;