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 SiLib 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 ////////////////////////////////////////////////////////////////////////////////////////////////////
52 ****************************************************************************************************
56 * Creates an SiLib object.
59 * Returns an SiLib object pointer.
60 ****************************************************************************************************
62 Lib
* SiHwlInit(const Client
* pClient
)
64 return V1::SiLib::CreateObj(pClient
);
71 ****************************************************************************************************
77 ****************************************************************************************************
79 SiLib::SiLib(const Client
* pClient
)
86 memset(&m_settings
, 0, sizeof(m_settings
));
90 ****************************************************************************************************
95 ****************************************************************************************************
102 ****************************************************************************************************
109 ****************************************************************************************************
111 UINT_32
SiLib::HwlGetPipes(
112 const ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
119 numPipes
= GetPipePerSurf(pTileInfo
->pipeConfig
);
123 ADDR_ASSERT_ALWAYS();
124 numPipes
= m_pipes
; // Suppose we should still have a global pipes
131 ****************************************************************************************************
132 * SiLib::GetPipePerSurf
134 * get pipe num base on inputing tileinfo->pipeconfig
137 ****************************************************************************************************
139 UINT_32
SiLib::GetPipePerSurf(
140 AddrPipeCfg pipeConfig
///< [in] pipe config
143 UINT_32 numPipes
= 0;
147 case ADDR_PIPECFG_P2
:
150 case ADDR_PIPECFG_P4_8x16
:
151 case ADDR_PIPECFG_P4_16x16
:
152 case ADDR_PIPECFG_P4_16x32
:
153 case ADDR_PIPECFG_P4_32x32
:
156 case ADDR_PIPECFG_P8_16x16_8x16
:
157 case ADDR_PIPECFG_P8_16x32_8x16
:
158 case ADDR_PIPECFG_P8_32x32_8x16
:
159 case ADDR_PIPECFG_P8_16x32_16x16
:
160 case ADDR_PIPECFG_P8_32x32_16x16
:
161 case ADDR_PIPECFG_P8_32x32_16x32
:
162 case ADDR_PIPECFG_P8_32x64_32x32
:
165 case ADDR_PIPECFG_P16_32x32_8x16
:
166 case ADDR_PIPECFG_P16_32x32_16x16
:
170 ADDR_ASSERT(!"Invalid pipe config");
177 ****************************************************************************************************
178 * SiLib::ComputeBankEquation
181 * Compute bank equation
184 * If equation can be computed
185 ****************************************************************************************************
187 ADDR_E_RETURNCODE
SiLib::ComputeBankEquation(
188 UINT_32 log2BytesPP
, ///< [in] log2 of bytes per pixel
189 UINT_32 threshX
, ///< [in] threshold for x channel
190 UINT_32 threshY
, ///< [in] threshold for y channel
191 ADDR_TILEINFO
* pTileInfo
, ///< [in] tile info
192 ADDR_EQUATION
* pEquation
///< [out] bank equation
195 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
197 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
198 UINT_32 bankXStart
= 3 + Log2(pipes
) + Log2(pTileInfo
->bankWidth
);
199 UINT_32 bankYStart
= 3 + Log2(pTileInfo
->bankHeight
);
201 ADDR_CHANNEL_SETTING x3
= InitChannel(1, 0, log2BytesPP
+ bankXStart
);
202 ADDR_CHANNEL_SETTING x4
= InitChannel(1, 0, log2BytesPP
+ bankXStart
+ 1);
203 ADDR_CHANNEL_SETTING x5
= InitChannel(1, 0, log2BytesPP
+ bankXStart
+ 2);
204 ADDR_CHANNEL_SETTING x6
= InitChannel(1, 0, log2BytesPP
+ bankXStart
+ 3);
205 ADDR_CHANNEL_SETTING y3
= InitChannel(1, 1, bankYStart
);
206 ADDR_CHANNEL_SETTING y4
= InitChannel(1, 1, bankYStart
+ 1);
207 ADDR_CHANNEL_SETTING y5
= InitChannel(1, 1, bankYStart
+ 2);
208 ADDR_CHANNEL_SETTING y6
= InitChannel(1, 1, bankYStart
+ 3);
210 x3
.value
= (threshX
> bankXStart
) ? x3
.value
: 0;
211 x4
.value
= (threshX
> bankXStart
+ 1) ? x4
.value
: 0;
212 x5
.value
= (threshX
> bankXStart
+ 2) ? x5
.value
: 0;
213 x6
.value
= (threshX
> bankXStart
+ 3) ? x6
.value
: 0;
214 y3
.value
= (threshY
> bankYStart
) ? y3
.value
: 0;
215 y4
.value
= (threshY
> bankYStart
+ 1) ? y4
.value
: 0;
216 y5
.value
= (threshY
> bankYStart
+ 2) ? y5
.value
: 0;
217 y6
.value
= (threshY
> bankYStart
+ 3) ? y6
.value
: 0;
219 switch (pTileInfo
->banks
)
222 pEquation
->addr
[0] = y6
;
223 pEquation
->xor1
[0] = x3
;
224 pEquation
->addr
[1] = y5
;
225 pEquation
->xor1
[1] = y6
;
226 pEquation
->xor2
[1] = x4
;
227 pEquation
->addr
[2] = y4
;
228 pEquation
->xor1
[2] = x5
;
229 pEquation
->addr
[3] = y3
;
230 pEquation
->xor1
[3] = x6
;
231 pEquation
->numBits
= 4;
234 pEquation
->addr
[0] = y5
;
235 pEquation
->xor1
[0] = x3
;
236 pEquation
->addr
[1] = y4
;
237 pEquation
->xor1
[1] = y5
;
238 pEquation
->xor2
[1] = x4
;
239 pEquation
->addr
[2] = y3
;
240 pEquation
->xor1
[2] = x5
;
241 pEquation
->numBits
= 3;
244 pEquation
->addr
[0] = y4
;
245 pEquation
->xor1
[0] = x3
;
246 pEquation
->addr
[1] = y3
;
247 pEquation
->xor1
[1] = x4
;
248 pEquation
->numBits
= 2;
251 pEquation
->addr
[0] = y3
;
252 pEquation
->xor1
[0] = x3
;
253 pEquation
->numBits
= 1;
256 pEquation
->numBits
= 0;
257 retCode
= ADDR_NOTSUPPORTED
;
258 ADDR_ASSERT_ALWAYS();
262 for (UINT_32 i
= 0; i
< pEquation
->numBits
; i
++)
264 if (pEquation
->addr
[i
].value
== 0)
266 if (pEquation
->xor1
[i
].value
== 0)
269 pEquation
->addr
[i
].value
= pEquation
->xor2
[i
].value
;
270 pEquation
->xor2
[i
].value
= 0;
274 pEquation
->addr
[i
].value
= pEquation
->xor1
[i
].value
;
276 if (pEquation
->xor2
[i
].value
!= 0)
279 pEquation
->xor1
[i
].value
= pEquation
->xor2
[i
].value
;
280 pEquation
->xor2
[i
].value
= 0;
285 pEquation
->xor1
[i
].value
= 0;
289 else if (pEquation
->xor1
[i
].value
== 0)
291 if (pEquation
->xor2
[i
].value
!= 0)
294 pEquation
->xor1
[i
].value
= pEquation
->xor2
[i
].value
;
295 pEquation
->xor2
[i
].value
= 0;
300 if ((pTileInfo
->bankWidth
== 1) &&
301 ((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P4_32x32
) ||
302 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
)))
304 retCode
= ADDR_NOTSUPPORTED
;
311 ****************************************************************************************************
312 * SiLib::ComputePipeEquation
315 * Compute pipe equation
318 * If equation can be computed
319 ****************************************************************************************************
321 ADDR_E_RETURNCODE
SiLib::ComputePipeEquation(
322 UINT_32 log2BytesPP
, ///< [in] Log2 of bytes per pixel
323 UINT_32 threshX
, ///< [in] Threshold for X channel
324 UINT_32 threshY
, ///< [in] Threshold for Y channel
325 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
326 ADDR_EQUATION
* pEquation
///< [out] Pipe configure
329 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
331 ADDR_CHANNEL_SETTING
* pAddr
= pEquation
->addr
;
332 ADDR_CHANNEL_SETTING
* pXor1
= pEquation
->xor1
;
333 ADDR_CHANNEL_SETTING
* pXor2
= pEquation
->xor2
;
335 ADDR_CHANNEL_SETTING x3
= InitChannel(1, 0, 3 + log2BytesPP
);
336 ADDR_CHANNEL_SETTING x4
= InitChannel(1, 0, 4 + log2BytesPP
);
337 ADDR_CHANNEL_SETTING x5
= InitChannel(1, 0, 5 + log2BytesPP
);
338 ADDR_CHANNEL_SETTING x6
= InitChannel(1, 0, 6 + log2BytesPP
);
339 ADDR_CHANNEL_SETTING y3
= InitChannel(1, 1, 3);
340 ADDR_CHANNEL_SETTING y4
= InitChannel(1, 1, 4);
341 ADDR_CHANNEL_SETTING y5
= InitChannel(1, 1, 5);
342 ADDR_CHANNEL_SETTING y6
= InitChannel(1, 1, 6);
344 x3
.value
= (threshX
> 3) ? x3
.value
: 0;
345 x4
.value
= (threshX
> 4) ? x4
.value
: 0;
346 x5
.value
= (threshX
> 5) ? x5
.value
: 0;
347 x6
.value
= (threshX
> 6) ? x6
.value
: 0;
348 y3
.value
= (threshY
> 3) ? y3
.value
: 0;
349 y4
.value
= (threshY
> 4) ? y4
.value
: 0;
350 y5
.value
= (threshY
> 5) ? y5
.value
: 0;
351 y6
.value
= (threshY
> 6) ? y6
.value
: 0;
353 switch (pTileInfo
->pipeConfig
)
355 case ADDR_PIPECFG_P2
:
358 pEquation
->numBits
= 1;
360 case ADDR_PIPECFG_P4_8x16
:
365 pEquation
->numBits
= 2;
367 case ADDR_PIPECFG_P4_16x16
:
373 pEquation
->numBits
= 2;
375 case ADDR_PIPECFG_P4_16x32
:
381 pEquation
->numBits
= 2;
383 case ADDR_PIPECFG_P4_32x32
:
389 pEquation
->numBits
= 2;
391 case ADDR_PIPECFG_P8_16x16_8x16
:
397 pEquation
->numBits
= 3;
399 case ADDR_PIPECFG_P8_16x32_8x16
:
407 pEquation
->numBits
= 3;
409 case ADDR_PIPECFG_P8_16x32_16x16
:
417 pEquation
->numBits
= 3;
419 case ADDR_PIPECFG_P8_32x32_8x16
:
427 pEquation
->numBits
= 3;
429 case ADDR_PIPECFG_P8_32x32_16x16
:
437 pEquation
->numBits
= 3;
439 case ADDR_PIPECFG_P8_32x32_16x32
:
447 pEquation
->numBits
= 3;
449 case ADDR_PIPECFG_P8_32x64_32x32
:
457 pEquation
->numBits
= 3;
459 case ADDR_PIPECFG_P16_32x32_8x16
:
468 pEquation
->numBits
= 4;
470 case ADDR_PIPECFG_P16_32x32_16x16
:
480 pEquation
->numBits
= 4;
483 ADDR_UNHANDLED_CASE();
484 pEquation
->numBits
= 0;
485 retCode
= ADDR_NOTSUPPORTED
;
489 for (UINT_32 i
= 0; i
< pEquation
->numBits
; i
++)
491 if (pAddr
[i
].value
== 0)
493 if (pXor1
[i
].value
== 0)
495 pAddr
[i
].value
= pXor2
[i
].value
;
499 pAddr
[i
].value
= pXor1
[i
].value
;
509 ****************************************************************************************************
510 * SiLib::ComputePipeFromCoord
513 * Compute pipe number from coordinates
516 ****************************************************************************************************
518 UINT_32
SiLib::ComputePipeFromCoord(
519 UINT_32 x
, ///< [in] x coordinate
520 UINT_32 y
, ///< [in] y coordinate
521 UINT_32 slice
, ///< [in] slice index
522 AddrTileMode tileMode
, ///< [in] tile mode
523 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
524 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines are ignored
525 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
529 UINT_32 pipeBit0
= 0;
530 UINT_32 pipeBit1
= 0;
531 UINT_32 pipeBit2
= 0;
532 UINT_32 pipeBit3
= 0;
533 UINT_32 sliceRotation
;
534 UINT_32 numPipes
= 0;
536 UINT_32 tx
= x
/ MicroTileWidth
;
537 UINT_32 ty
= y
/ MicroTileHeight
;
538 UINT_32 x3
= _BIT(tx
,0);
539 UINT_32 x4
= _BIT(tx
,1);
540 UINT_32 x5
= _BIT(tx
,2);
541 UINT_32 x6
= _BIT(tx
,3);
542 UINT_32 y3
= _BIT(ty
,0);
543 UINT_32 y4
= _BIT(ty
,1);
544 UINT_32 y5
= _BIT(ty
,2);
545 UINT_32 y6
= _BIT(ty
,3);
547 switch (pTileInfo
->pipeConfig
)
549 case ADDR_PIPECFG_P2
:
553 case ADDR_PIPECFG_P4_8x16
:
558 case ADDR_PIPECFG_P4_16x16
:
559 pipeBit0
= x3
^ y3
^ x4
;
563 case ADDR_PIPECFG_P4_16x32
:
564 pipeBit0
= x3
^ y3
^ x4
;
568 case ADDR_PIPECFG_P4_32x32
:
569 pipeBit0
= x3
^ y3
^ x5
;
573 case ADDR_PIPECFG_P8_16x16_8x16
:
574 pipeBit0
= x4
^ y3
^ x5
;
578 case ADDR_PIPECFG_P8_16x32_8x16
:
579 pipeBit0
= x4
^ y3
^ x5
;
584 case ADDR_PIPECFG_P8_16x32_16x16
:
585 pipeBit0
= x3
^ y3
^ x4
;
590 case ADDR_PIPECFG_P8_32x32_8x16
:
591 pipeBit0
= x4
^ y3
^ x5
;
596 case ADDR_PIPECFG_P8_32x32_16x16
:
597 pipeBit0
= x3
^ y3
^ x4
;
602 case ADDR_PIPECFG_P8_32x32_16x32
:
603 pipeBit0
= x3
^ y3
^ x4
;
608 case ADDR_PIPECFG_P8_32x64_32x32
:
609 pipeBit0
= x3
^ y3
^ x5
;
614 case ADDR_PIPECFG_P16_32x32_8x16
:
621 case ADDR_PIPECFG_P16_32x32_16x16
:
622 pipeBit0
= x3
^ y3
^ x4
;
629 ADDR_UNHANDLED_CASE();
632 pipe
= pipeBit0
| (pipeBit1
<< 1) | (pipeBit2
<< 2) | (pipeBit3
<< 3);
634 UINT_32 microTileThickness
= Thickness(tileMode
);
637 // Apply pipe rotation for the slice.
641 case ADDR_TM_3D_TILED_THIN1
: //fall through thin
642 case ADDR_TM_3D_TILED_THICK
: //fall through thick
643 case ADDR_TM_3D_TILED_XTHICK
:
645 Max(1, static_cast<INT_32
>(numPipes
/ 2) - 1) * (slice
/ microTileThickness
);
651 pipeSwizzle
+= sliceRotation
;
652 pipeSwizzle
&= (numPipes
- 1);
654 pipe
= pipe
^ pipeSwizzle
;
660 ****************************************************************************************************
661 * SiLib::ComputeTileCoordFromPipeAndElemIdx
664 * Compute (x,y) of a tile within a macro tile from address
667 ****************************************************************************************************
669 VOID
SiLib::ComputeTileCoordFromPipeAndElemIdx(
670 UINT_32 elemIdx
, ///< [in] per pipe element index within a macro tile
671 UINT_32 pipe
, ///< [in] pipe index
672 AddrPipeCfg pipeCfg
, ///< [in] pipe config
673 UINT_32 pitchInMacroTile
, ///< [in] surface pitch in macro tile
674 UINT_32 x
, ///< [in] x coordinate of the (0,0) tile in a macro tile
675 UINT_32 y
, ///< [in] y coordinate of the (0,0) tile in a macro tile
676 UINT_32
* pX
, ///< [out] x coordinate
677 UINT_32
* pY
///< [out] y coordinate
680 UINT_32 pipebit0
= _BIT(pipe
,0);
681 UINT_32 pipebit1
= _BIT(pipe
,1);
682 UINT_32 pipebit2
= _BIT(pipe
,2);
683 UINT_32 pipebit3
= _BIT(pipe
,3);
684 UINT_32 elemIdx0
= _BIT(elemIdx
,0);
685 UINT_32 elemIdx1
= _BIT(elemIdx
,1);
686 UINT_32 elemIdx2
= _BIT(elemIdx
,2);
698 case ADDR_PIPECFG_P2
:
703 *pY
= Bits2Number(2, y4
, y3
);
704 *pX
= Bits2Number(2, x4
, x3
);
706 case ADDR_PIPECFG_P4_8x16
:
711 *pY
= Bits2Number(2, y4
, y3
);
712 *pX
= Bits2Number(2, x4
, x3
);
714 case ADDR_PIPECFG_P4_16x16
:
718 x3
= pipebit0
^ y3
^ x4
;
719 *pY
= Bits2Number(2, y4
, y3
);
720 *pX
= Bits2Number(2, x4
, x3
);
722 case ADDR_PIPECFG_P4_16x32
:
723 x3
= elemIdx0
^ pipebit0
;
726 y3
= pipebit0
^ x3
^ x4
;
728 *pY
= Bits2Number(2, y4
, y3
);
729 *pX
= Bits2Number(2, x4
, x3
);
731 case ADDR_PIPECFG_P4_32x32
:
735 if((pitchInMacroTile
% 2) == 0)
739 x3
= pipebit0
^ y3
^ x5
;
740 *pY
= Bits2Number(2, y4
, y3
);
741 *pX
= Bits2Number(3, x5
, x4
, x3
);
746 x3
= pipebit0
^ y3
^ x5
;
747 *pY
= Bits2Number(2, y4
, y3
);
748 *pX
= Bits2Number(2, x4
, x3
);
751 case ADDR_PIPECFG_P8_16x16_8x16
:
757 y3
= pipebit0
^ x5
^ x4
;
758 *pY
= Bits2Number(2, y4
, y3
);
759 *pX
= Bits2Number(2, x4
, x3
);
761 case ADDR_PIPECFG_P8_16x32_8x16
:
767 y3
= pipebit0
^ x4
^ x5
;
768 *pY
= Bits2Number(2, y4
, y3
);
769 *pX
= Bits2Number(2, x4
, x3
);
771 case ADDR_PIPECFG_P8_32x32_8x16
:
775 if((pitchInMacroTile
% 2) == 0)
780 y3
= pipebit0
^ x4
^ x5
;
781 *pY
= Bits2Number(2, y4
, y3
);
782 *pX
= Bits2Number(3, x5
, x4
, x3
);
787 y3
= pipebit0
^ x4
^ x5
;
788 *pY
= Bits2Number(2, y4
, y3
);
789 *pX
= Bits2Number(2, x4
, x3
);
792 case ADDR_PIPECFG_P8_16x32_16x16
:
798 y3
= pipebit0
^ x3
^ x4
;
799 *pY
= Bits2Number(2, y4
, y3
);
800 *pX
= Bits2Number(2, x4
, x3
);
802 case ADDR_PIPECFG_P8_32x32_16x16
:
807 if((pitchInMacroTile
% 2) == 0)
811 *pY
= Bits2Number(2, y4
, y3
);
812 *pX
= Bits2Number(3, x5
, x4
, x3
);
816 *pY
= Bits2Number(2, y4
, y3
);
817 *pX
= Bits2Number(2, x4
, x3
);
820 case ADDR_PIPECFG_P8_32x32_16x32
:
821 if((pitchInMacroTile
% 2) == 0)
828 x3
= pipebit0
^ y3
^ x4
;
830 *pY
= Bits2Number(2, y4
, y3
);
831 *pX
= Bits2Number(3, x5
, x4
, x3
);
839 x3
= pipebit0
^ y3
^ x4
;
840 *pY
= Bits2Number(2, y4
, y3
);
841 *pX
= Bits2Number(2, x4
, x3
);
844 case ADDR_PIPECFG_P8_32x64_32x32
:
848 if((pitchInMacroTile
% 4) == 0)
854 x3
= pipebit0
^ y3
^ x5
;
855 *pY
= Bits2Number(2, y4
, y3
);
856 *pX
= Bits2Number(4, x6
, x5
, x4
, x3
);
862 x3
= pipebit0
^ y3
^ x5
;
863 *pY
= Bits2Number(2, y4
, y3
);
864 *pX
= Bits2Number(3, x5
, x4
, x3
);
867 case ADDR_PIPECFG_P16_32x32_8x16
:
872 if((pitchInMacroTile
% 4) == 0)
878 *pY
= Bits2Number(2, y4
, y3
);
879 *pX
= Bits2Number(4, x6
, x5
,x4
, x3
);
885 *pY
= Bits2Number(2, y4
, y3
);
886 *pX
= Bits2Number(3, x5
, x4
, x3
);
889 case ADDR_PIPECFG_P16_32x32_16x16
:
893 x3
= pipebit0
^ y3
^ x4
;
894 if((pitchInMacroTile
% 4) == 0)
900 *pY
= Bits2Number(2, y4
, y3
);
901 *pX
= Bits2Number(4, x6
, x5
, x4
, x3
);
907 *pY
= Bits2Number(2, y4
, y3
);
908 *pX
= Bits2Number(3, x5
, x4
, x3
);
912 ADDR_UNHANDLED_CASE();
917 ****************************************************************************************************
918 * SiLib::TileCoordToMaskElementIndex
921 * Compute element index from coordinates in tiles
924 ****************************************************************************************************
926 UINT_32
SiLib::TileCoordToMaskElementIndex(
927 UINT_32 tx
, ///< [in] x coord, in Tiles
928 UINT_32 ty
, ///< [in] y coord, in Tiles
929 AddrPipeCfg pipeConfig
, ///< [in] pipe config
930 UINT_32
* macroShift
, ///< [out] macro shift
931 UINT_32
* elemIdxBits
///< [out] tile offset bits
935 UINT_32 elemIdx0
, elemIdx1
, elemIdx2
;
946 case ADDR_PIPECFG_P2
:
950 elemIdx1
= tx1
^ ty1
;
951 elemIdx0
= tx1
^ ty0
;
952 elemIdx
= Bits2Number(3,elemIdx2
,elemIdx1
,elemIdx0
);
954 case ADDR_PIPECFG_P4_8x16
:
958 elemIdx0
= tx1
^ ty1
;
959 elemIdx
= Bits2Number(2,elemIdx1
,elemIdx0
);
961 case ADDR_PIPECFG_P4_16x16
:
966 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
968 case ADDR_PIPECFG_P4_16x32
:
973 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
975 case ADDR_PIPECFG_P4_32x32
:
981 elemIdx
= Bits2Number(3, elemIdx2
, elemIdx1
, elemIdx0
);
983 case ADDR_PIPECFG_P8_16x16_8x16
:
989 case ADDR_PIPECFG_P8_16x32_8x16
:
995 case ADDR_PIPECFG_P8_32x32_8x16
:
1000 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1002 case ADDR_PIPECFG_P8_16x32_16x16
:
1008 case ADDR_PIPECFG_P8_32x32_16x16
:
1013 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1015 case ADDR_PIPECFG_P8_32x32_16x32
:
1020 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1022 case ADDR_PIPECFG_P8_32x64_32x32
:
1028 elemIdx
= Bits2Number(3, elemIdx2
, elemIdx1
, elemIdx0
);
1030 case ADDR_PIPECFG_P16_32x32_8x16
:
1035 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1037 case ADDR_PIPECFG_P16_32x32_16x16
:
1042 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1045 ADDR_UNHANDLED_CASE();
1053 ****************************************************************************************************
1054 * SiLib::HwlComputeTileDataWidthAndHeightLinear
1057 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1063 * MacroWidth and macroHeight are measured in pixels
1064 ****************************************************************************************************
1066 VOID
SiLib::HwlComputeTileDataWidthAndHeightLinear(
1067 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1068 UINT_32
* pMacroHeight
, ///< [out] macro tile height
1069 UINT_32 bpp
, ///< [in] bits per pixel
1070 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
1073 ADDR_ASSERT(pTileInfo
!= NULL
);
1075 UINT_32 macroHeight
;
1077 /// In linear mode, the htile or cmask buffer must be padded out to 4 tiles
1078 /// but for P8_32x64_32x32, it must be padded out to 8 tiles
1079 /// Actually there are more pipe configs which need 8-tile padding but SI family
1080 /// has a bug which is fixed in CI family
1081 if ((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
) ||
1082 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P16_32x32_8x16
) ||
1083 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x32_16x16
))
1085 macroWidth
= 8*MicroTileWidth
;
1086 macroHeight
= 8*MicroTileHeight
;
1090 macroWidth
= 4*MicroTileWidth
;
1091 macroHeight
= 4*MicroTileHeight
;
1094 *pMacroWidth
= macroWidth
;
1095 *pMacroHeight
= macroHeight
;
1099 ****************************************************************************************************
1100 * SiLib::HwlComputeHtileBytes
1103 * Compute htile size in bytes
1106 * Htile size in bytes
1107 ****************************************************************************************************
1109 UINT_64
SiLib::HwlComputeHtileBytes(
1110 UINT_32 pitch
, ///< [in] pitch
1111 UINT_32 height
, ///< [in] height
1112 UINT_32 bpp
, ///< [in] bits per pixel
1113 BOOL_32 isLinear
, ///< [in] if it is linear mode
1114 UINT_32 numSlices
, ///< [in] number of slices
1115 UINT_64
* pSliceBytes
, ///< [out] bytes per slice
1116 UINT_32 baseAlign
///< [in] base alignments
1119 return ComputeHtileBytes(pitch
, height
, bpp
, isLinear
, numSlices
, pSliceBytes
, baseAlign
);
1123 ****************************************************************************************************
1124 * SiLib::HwlComputeXmaskAddrFromCoord
1127 * Compute address from coordinates for htile/cmask
1130 ****************************************************************************************************
1132 UINT_64
SiLib::HwlComputeXmaskAddrFromCoord(
1133 UINT_32 pitch
, ///< [in] pitch
1134 UINT_32 height
, ///< [in] height
1135 UINT_32 x
, ///< [in] x coord
1136 UINT_32 y
, ///< [in] y coord
1137 UINT_32 slice
, ///< [in] slice/depth index
1138 UINT_32 numSlices
, ///< [in] number of slices
1139 UINT_32 factor
, ///< [in] factor that indicates cmask(2) or htile(1)
1140 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
1141 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
1142 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
1143 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1144 UINT_32
* pBitPosition
///< [out] bit position inside a byte
1147 UINT_32 tx
= x
/ MicroTileWidth
;
1148 UINT_32 ty
= y
/ MicroTileHeight
;
1153 UINT_32 macroHeight
;
1154 UINT_64 pSliceBytes
;
1156 UINT_32 tileNumPerPipe
;
1159 if (factor
== 2) //CMASK
1161 ADDR_CMASK_FLAGS flags
= {{0}};
1163 tileNumPerPipe
= 256;
1165 ComputeCmaskInfo(flags
,
1176 elemBits
= CmaskElemBits
;
1180 ADDR_HTILE_FLAGS flags
= {{0}};
1182 tileNumPerPipe
= 512;
1184 ComputeHtileInfo(flags
,
1202 const UINT_32 pitchInTile
= newPitch
/ MicroTileWidth
;
1203 const UINT_32 heightInTile
= newHeight
/ MicroTileWidth
;
1204 UINT_64 macroOffset
; // Per pipe starting offset of the macro tile in which this tile lies.
1205 UINT_64 microNumber
; // Per pipe starting offset of the macro tile in which this tile lies.
1208 UINT_64 microOffset
;
1210 UINT_64 totalOffset
;
1211 UINT_32 elemIdxBits
;
1213 TileCoordToMaskElementIndex(tx
, ty
, pTileInfo
->pipeConfig
, µShift
, &elemIdxBits
);
1215 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1218 { //linear addressing
1219 // Linear addressing is extremelly wasting memory if slice > 1, since each pipe has the full
1220 // slice memory foot print instead of divided by numPipes.
1221 microX
= tx
/ 4; // Macro Tile is 4x4
1223 microNumber
= static_cast<UINT_64
>(microX
+ microY
* (pitchInTile
/ 4)) << microShift
;
1225 UINT_32 sliceBits
= pitchInTile
* heightInTile
;
1227 // do htile single slice alignment if the flag is true
1228 if (m_configFlags
.useHtileSliceAlign
&& (factor
== 1)) //Htile
1230 sliceBits
= PowTwoAlign(sliceBits
, BITS_TO_BYTES(HtileCacheBits
) * numPipes
/ elemBits
);
1232 macroOffset
= slice
* (sliceBits
/ numPipes
) * elemBits
;
1235 { //tiled addressing
1236 const UINT_32 macroWidthInTile
= macroWidth
/ MicroTileWidth
; // Now in unit of Tiles
1237 const UINT_32 macroHeightInTile
= macroHeight
/ MicroTileHeight
;
1238 const UINT_32 pitchInCL
= pitchInTile
/ macroWidthInTile
;
1239 const UINT_32 heightInCL
= heightInTile
/ macroHeightInTile
;
1241 const UINT_32 macroX
= x
/ macroWidth
;
1242 const UINT_32 macroY
= y
/ macroHeight
;
1243 const UINT_32 macroNumber
= macroX
+ macroY
* pitchInCL
+ slice
* pitchInCL
* heightInCL
;
1245 // Per pipe starting offset of the cache line in which this tile lies.
1246 microX
= (x
% macroWidth
) / MicroTileWidth
/ 4; // Macro Tile is 4x4
1247 microY
= (y
% macroHeight
) / MicroTileHeight
/ 4 ;
1248 microNumber
= static_cast<UINT_64
>(microX
+ microY
* (macroWidth
/ MicroTileWidth
/ 4)) << microShift
;
1250 macroOffset
= macroNumber
* tileNumPerPipe
* elemBits
;
1253 if(elemIdxBits
== microShift
)
1255 microNumber
+= elemIdx
;
1259 microNumber
>>= elemIdxBits
;
1260 microNumber
<<= elemIdxBits
;
1261 microNumber
+= elemIdx
;
1264 microOffset
= elemBits
* microNumber
;
1265 totalOffset
= microOffset
+ macroOffset
;
1267 UINT_32 pipe
= ComputePipeFromCoord(x
, y
, 0, ADDR_TM_2D_TILED_THIN1
, 0, FALSE
, pTileInfo
);
1268 UINT_64 addrInBits
= totalOffset
% (m_pipeInterleaveBytes
* 8) +
1269 pipe
* (m_pipeInterleaveBytes
* 8) +
1270 totalOffset
/ (m_pipeInterleaveBytes
* 8) * (m_pipeInterleaveBytes
* 8) * numPipes
;
1271 *pBitPosition
= static_cast<UINT_32
>(addrInBits
) % 8;
1272 UINT_64 addr
= addrInBits
/ 8;
1278 ****************************************************************************************************
1279 * SiLib::HwlComputeXmaskCoordFromAddr
1282 * Compute the coord from an address of a cmask/htile
1288 * This method is reused by htile, so rename to Xmask
1289 ****************************************************************************************************
1291 VOID
SiLib::HwlComputeXmaskCoordFromAddr(
1292 UINT_64 addr
, ///< [in] address
1293 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
1294 UINT_32 pitch
, ///< [in] pitch
1295 UINT_32 height
, ///< [in] height
1296 UINT_32 numSlices
, ///< [in] number of slices
1297 UINT_32 factor
, ///< [in] factor that indicates cmask or htile
1298 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
1299 BOOL_32 isWidth8
, ///< [in] Not used by SI
1300 BOOL_32 isHeight8
, ///< [in] Not used by SI
1301 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1302 UINT_32
* pX
, ///< [out] x coord
1303 UINT_32
* pY
, ///< [out] y coord
1304 UINT_32
* pSlice
///< [out] slice index
1312 UINT_32 tileNumPerPipe
;
1319 if (factor
== 2) //CMASK
1321 ADDR_CMASK_FLAGS flags
= {{0}};
1323 tileNumPerPipe
= 256;
1325 ComputeCmaskInfo(flags
,
1339 ADDR_HTILE_FLAGS flags
= {{0}};
1341 tileNumPerPipe
= 512;
1343 ComputeHtileInfo(flags
,
1359 const UINT_32 pitchInTile
= newPitch
/ MicroTileWidth
;
1360 const UINT_32 heightInTile
= newHeight
/ MicroTileWidth
;
1361 const UINT_32 pitchInMacroTile
= pitchInTile
/ 4;
1363 UINT_32 elemIdxBits
;
1364 // get macroShift and elemIdxBits
1365 TileCoordToMaskElementIndex(0, 0, pTileInfo
->pipeConfig
, ¯oShift
, &elemIdxBits
);
1367 const UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1368 const UINT_32 pipe
= (UINT_32
)((addr
/ m_pipeInterleaveBytes
) % numPipes
);
1370 UINT_64 localOffset
= (addr
% m_pipeInterleaveBytes
) +
1371 (addr
/ m_pipeInterleaveBytes
/ numPipes
)* m_pipeInterleaveBytes
;
1374 if (factor
== 2) //CMASK
1376 tileIndex
= (UINT_32
)(localOffset
* 2 + (bitPosition
!= 0));
1380 tileIndex
= (UINT_32
)(localOffset
/ 4);
1383 UINT_32 macroOffset
;
1386 UINT_32 sliceSizeInTile
= pitchInTile
* heightInTile
;
1388 // do htile single slice alignment if the flag is true
1389 if (m_configFlags
.useHtileSliceAlign
&& (factor
== 1)) //Htile
1391 sliceSizeInTile
= PowTwoAlign(sliceSizeInTile
, static_cast<UINT_32
>(sliceBytes
) / 64);
1393 *pSlice
= tileIndex
/ (sliceSizeInTile
/ numPipes
);
1394 macroOffset
= tileIndex
% (sliceSizeInTile
/ numPipes
);
1398 const UINT_32 clWidthInTile
= clWidth
/ MicroTileWidth
; // Now in unit of Tiles
1399 const UINT_32 clHeightInTile
= clHeight
/ MicroTileHeight
;
1400 const UINT_32 pitchInCL
= pitchInTile
/ clWidthInTile
;
1401 const UINT_32 heightInCL
= heightInTile
/ clHeightInTile
;
1402 const UINT_32 clIndex
= tileIndex
/ tileNumPerPipe
;
1404 UINT_32 clX
= clIndex
% pitchInCL
;
1405 UINT_32 clY
= (clIndex
% (heightInCL
* pitchInCL
)) / pitchInCL
;
1407 *pX
= clX
* clWidthInTile
* MicroTileWidth
;
1408 *pY
= clY
* clHeightInTile
* MicroTileHeight
;
1409 *pSlice
= clIndex
/ (heightInCL
* pitchInCL
);
1411 macroOffset
= tileIndex
% tileNumPerPipe
;
1414 UINT_32 elemIdx
= macroOffset
& 7;
1415 macroOffset
>>= elemIdxBits
;
1417 if (elemIdxBits
!= macroShift
)
1419 macroOffset
<<= (elemIdxBits
- macroShift
);
1421 UINT_32 pipebit1
= _BIT(pipe
,1);
1422 UINT_32 pipebit2
= _BIT(pipe
,2);
1423 UINT_32 pipebit3
= _BIT(pipe
,3);
1424 if (pitchInMacroTile
% 2)
1426 switch (pTileInfo
->pipeConfig
)
1428 case ADDR_PIPECFG_P4_32x32
:
1429 macroOffset
|= pipebit1
;
1431 case ADDR_PIPECFG_P8_32x32_8x16
:
1432 case ADDR_PIPECFG_P8_32x32_16x16
:
1433 case ADDR_PIPECFG_P8_32x32_16x32
:
1434 macroOffset
|= pipebit2
;
1442 if (pitchInMacroTile
% 4)
1444 if (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
)
1446 macroOffset
|= (pipebit1
<<1);
1448 if((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P16_32x32_8x16
) ||
1449 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P16_32x32_16x16
))
1451 macroOffset
|= (pipebit3
<<1);
1461 macroX
= macroOffset
% pitchInMacroTile
;
1462 macroY
= macroOffset
/ pitchInMacroTile
;
1466 const UINT_32 clWidthInMacroTile
= clWidth
/ (MicroTileWidth
* 4);
1467 macroX
= macroOffset
% clWidthInMacroTile
;
1468 macroY
= macroOffset
/ clWidthInMacroTile
;
1471 *pX
+= macroX
* 4 * MicroTileWidth
;
1472 *pY
+= macroY
* 4 * MicroTileHeight
;
1476 ComputeTileCoordFromPipeAndElemIdx(elemIdx
, pipe
, pTileInfo
->pipeConfig
, pitchInMacroTile
,
1477 *pX
, *pY
, µX
, µY
);
1479 *pX
+= microX
* MicroTileWidth
;
1480 *pY
+= microY
* MicroTileWidth
;
1484 ****************************************************************************************************
1485 * SiLib::HwlGetPitchAlignmentLinear
1487 * Get pitch alignment
1490 ****************************************************************************************************
1492 UINT_32
SiLib::HwlGetPitchAlignmentLinear(
1493 UINT_32 bpp
, ///< [in] bits per pixel
1494 ADDR_SURFACE_FLAGS flags
///< [in] surface flags
1499 // Interleaved access requires a 256B aligned pitch, so fall back to pre-SI alignment
1500 if (flags
.interleaved
)
1502 pitchAlign
= Max(64u, m_pipeInterleaveBytes
/ BITS_TO_BYTES(bpp
));
1507 pitchAlign
= Max(8u, 64 / BITS_TO_BYTES(bpp
));
1514 ****************************************************************************************************
1515 * SiLib::HwlGetSizeAdjustmentLinear
1518 * Adjust linear surface pitch and slice size
1521 * Logical slice size in bytes
1522 ****************************************************************************************************
1524 UINT_64
SiLib::HwlGetSizeAdjustmentLinear(
1525 AddrTileMode tileMode
, ///< [in] tile mode
1526 UINT_32 bpp
, ///< [in] bits per pixel
1527 UINT_32 numSamples
, ///< [in] number of samples
1528 UINT_32 baseAlign
, ///< [in] base alignment
1529 UINT_32 pitchAlign
, ///< [in] pitch alignment
1530 UINT_32
* pPitch
, ///< [in,out] pointer to pitch
1531 UINT_32
* pHeight
, ///< [in,out] pointer to height
1532 UINT_32
* pHeightAlign
///< [in,out] pointer to height align
1536 if (tileMode
== ADDR_TM_LINEAR_GENERAL
)
1538 sliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(*pPitch
) * (*pHeight
) * bpp
* numSamples
);
1542 UINT_32 pitch
= *pPitch
;
1543 UINT_32 height
= *pHeight
;
1545 UINT_32 pixelsPerPipeInterleave
= m_pipeInterleaveBytes
/ BITS_TO_BYTES(bpp
);
1546 UINT_32 sliceAlignInPixel
= pixelsPerPipeInterleave
< 64 ? 64 : pixelsPerPipeInterleave
;
1548 // numSamples should be 1 in real cases (no MSAA for linear but TGL may pass non 1 value)
1549 UINT_64 pixelPerSlice
= static_cast<UINT_64
>(pitch
) * height
* numSamples
;
1551 while (pixelPerSlice
% sliceAlignInPixel
)
1553 pitch
+= pitchAlign
;
1554 pixelPerSlice
= static_cast<UINT_64
>(pitch
) * height
* numSamples
;
1559 UINT_32 heightAlign
= 1;
1561 while ((pitch
* heightAlign
) % sliceAlignInPixel
)
1566 *pHeightAlign
= heightAlign
;
1568 sliceSize
= BITS_TO_BYTES(pixelPerSlice
* bpp
);
1575 ****************************************************************************************************
1576 * SiLib::HwlPreHandleBaseLvl3xPitch
1579 * Pre-handler of 3x pitch (96 bit) adjustment
1583 ****************************************************************************************************
1585 UINT_32
SiLib::HwlPreHandleBaseLvl3xPitch(
1586 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
1587 UINT_32 expPitch
///< [in] pitch
1590 ADDR_ASSERT(pIn
->width
== expPitch
);
1592 // From SI, if pow2Pad is 1 the pitch is expanded 3x first, then padded to pow2, so nothing to
1594 if (pIn
->flags
.pow2Pad
== FALSE
)
1596 Addr::V1::Lib::HwlPreHandleBaseLvl3xPitch(pIn
, expPitch
);
1600 ADDR_ASSERT(IsPow2(expPitch
));
1607 ****************************************************************************************************
1608 * SiLib::HwlPostHandleBaseLvl3xPitch
1611 * Post-handler of 3x pitch adjustment
1615 ****************************************************************************************************
1617 UINT_32
SiLib::HwlPostHandleBaseLvl3xPitch(
1618 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
1619 UINT_32 expPitch
///< [in] pitch
1623 * @note The pitch will be divided by 3 in the end so the value will look odd but h/w should
1624 * be able to compute a correct pitch from it as h/w address library is doing the job.
1626 // From SI, the pitch is expanded 3x first, then padded to pow2, so no special handler here
1627 if (pIn
->flags
.pow2Pad
== FALSE
)
1629 Addr::V1::Lib::HwlPostHandleBaseLvl3xPitch(pIn
, expPitch
);
1636 ****************************************************************************************************
1637 * SiLib::HwlGetPitchAlignmentMicroTiled
1640 * Compute 1D tiled surface pitch alignment
1644 ****************************************************************************************************
1646 UINT_32
SiLib::HwlGetPitchAlignmentMicroTiled(
1647 AddrTileMode tileMode
, ///< [in] tile mode
1648 UINT_32 bpp
, ///< [in] bits per pixel
1649 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
1650 UINT_32 numSamples
///< [in] number of samples
1657 pitchAlign
= EgBasedLib::HwlGetPitchAlignmentMicroTiled(tileMode
,bpp
,flags
,numSamples
);
1668 ****************************************************************************************************
1669 * SiLib::HwlGetSizeAdjustmentMicroTiled
1672 * Adjust 1D tiled surface pitch and slice size
1675 * Logical slice size in bytes
1676 ****************************************************************************************************
1678 UINT_64
SiLib::HwlGetSizeAdjustmentMicroTiled(
1679 UINT_32 thickness
, ///< [in] thickness
1680 UINT_32 bpp
, ///< [in] bits per pixel
1681 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
1682 UINT_32 numSamples
, ///< [in] number of samples
1683 UINT_32 baseAlign
, ///< [in] base alignment
1684 UINT_32 pitchAlign
, ///< [in] pitch alignment
1685 UINT_32
* pPitch
, ///< [in,out] pointer to pitch
1686 UINT_32
* pHeight
///< [in,out] pointer to height
1689 UINT_64 logicalSliceSize
;
1690 UINT_64 physicalSliceSize
;
1692 UINT_32 pitch
= *pPitch
;
1693 UINT_32 height
= *pHeight
;
1695 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
1696 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
1698 // Physical slice: multiplied by thickness
1699 physicalSliceSize
= logicalSliceSize
* thickness
;
1701 // Pitch alignment is always 8, so if slice size is not padded to base alignment
1702 // (pipe_interleave_size), we need to increase pitch
1703 while ((physicalSliceSize
% baseAlign
) != 0)
1705 pitch
+= pitchAlign
;
1707 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
1709 physicalSliceSize
= logicalSliceSize
* thickness
;
1714 // Special workaround for depth/stencil buffer, use 8 bpp to align depth buffer again since
1715 // the stencil plane may have larger pitch if the slice size is smaller than base alignment.
1717 // Note: this actually does not work for mipmap but mipmap depth texture is not really
1718 // sampled with mipmap.
1720 if (flags
.depth
&& (flags
.noStencil
== FALSE
))
1722 ADDR_ASSERT(numSamples
== 1);
1724 UINT_64 logicalSiceSizeStencil
= static_cast<UINT_64
>(pitch
) * height
; // 1 byte stencil
1726 while ((logicalSiceSizeStencil
% baseAlign
) != 0)
1728 pitch
+= pitchAlign
; // Stencil plane's pitch alignment is the same as depth plane's
1730 logicalSiceSizeStencil
= static_cast<UINT_64
>(pitch
) * height
;
1733 if (pitch
!= *pPitch
)
1735 // If this is a mipmap, this padded one cannot be sampled as a whole mipmap!
1736 logicalSliceSize
= logicalSiceSizeStencil
* BITS_TO_BYTES(bpp
);
1742 // No adjust for pHeight
1744 return logicalSliceSize
;
1748 ****************************************************************************************************
1749 * SiLib::HwlConvertChipFamily
1752 * Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
1755 ****************************************************************************************************
1757 ChipFamily
SiLib::HwlConvertChipFamily(
1758 UINT_32 uChipFamily
, ///< [in] chip family defined in atiih.h
1759 UINT_32 uChipRevision
) ///< [in] chip revision defined in "asic_family"_id.h
1761 ChipFamily family
= ADDR_CHIP_FAMILY_SI
;
1763 switch (uChipFamily
)
1766 m_settings
.isSouthernIsland
= 1;
1767 m_settings
.isTahiti
= ASICREV_IS_TAHITI_P(uChipRevision
);
1768 m_settings
.isPitCairn
= ASICREV_IS_PITCAIRN_PM(uChipRevision
);
1769 m_settings
.isCapeVerde
= ASICREV_IS_CAPEVERDE_M(uChipRevision
);
1770 m_settings
.isOland
= ASICREV_IS_OLAND_M(uChipRevision
);
1771 m_settings
.isHainan
= ASICREV_IS_HAINAN_V(uChipRevision
);
1774 ADDR_ASSERT(!"This should be a Fusion");
1782 ****************************************************************************************************
1783 * SiLib::HwlSetupTileInfo
1786 * Setup default value of tile info for SI
1787 ****************************************************************************************************
1789 VOID
SiLib::HwlSetupTileInfo(
1790 AddrTileMode tileMode
, ///< [in] Tile mode
1791 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface type flags
1792 UINT_32 bpp
, ///< [in] Bits per pixel
1793 UINT_32 pitch
, ///< [in] Pitch in pixels
1794 UINT_32 height
, ///< [in] Height in pixels
1795 UINT_32 numSamples
, ///< [in] Number of samples
1796 ADDR_TILEINFO
* pTileInfoIn
, ///< [in] Tile info input: NULL for default
1797 ADDR_TILEINFO
* pTileInfoOut
, ///< [out] Tile info output
1798 AddrTileType inTileType
, ///< [in] Tile type
1799 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] Output
1802 UINT_32 thickness
= Thickness(tileMode
);
1803 ADDR_TILEINFO
* pTileInfo
= pTileInfoOut
;
1804 INT index
= TileIndexInvalid
;
1807 if (IsLinear(tileMode
) == FALSE
)
1809 // 128 bpp/thick tiling must be non-displayable.
1810 // Fmask reuse color buffer's entry but bank-height field can be from another entry
1811 // To simplify the logic, fmask entry should be picked from non-displayable ones
1812 if (bpp
== 128 || thickness
> 1 || flags
.fmask
|| flags
.prt
)
1814 inTileType
= ADDR_NON_DISPLAYABLE
;
1817 if (flags
.depth
|| flags
.stencil
)
1819 inTileType
= ADDR_DEPTH_SAMPLE_ORDER
;
1823 // Partial valid fields are not allowed for SI.
1824 if (IsTileInfoAllZero(pTileInfo
))
1826 if (IsMacroTiled(tileMode
))
1830 if (numSamples
== 1)
1843 ADDR_ASSERT_ALWAYS();
1872 ADDR_ASSERT(bpp
!= 128);
1879 ADDR_ASSERT(numSamples
== 4);
1892 ADDR_ASSERT_ALWAYS();
1913 ADDR_ASSERT_ALWAYS();
1919 // See table entries 0-7
1920 else if (flags
.depth
|| flags
.stencil
)
1922 if (flags
.compressZ
)
1930 // optimal tile index for compressed depth/stencil.
1953 else //non PRT & non Depth & non Stencil
1955 // See table entries 9-12
1956 if (inTileType
== ADDR_DISPLAYABLE
)
1978 // See table entries 13-17
1983 UINT_32 fmaskPixelSize
= bpp
* numSamples
;
1985 switch (fmaskPixelSize
)
2000 ADDR_ASSERT_ALWAYS();
2027 else // thick tiling - entries 18-20
2046 if (tileMode
== ADDR_TM_LINEAR_ALIGNED
)
2050 else if (tileMode
== ADDR_TM_LINEAR_GENERAL
)
2052 index
= TileIndexLinearGeneral
;
2056 if (flags
.depth
|| flags
.stencil
)
2060 else if (inTileType
== ADDR_DISPLAYABLE
)
2064 else if (thickness
== 1)
2075 if (index
>= 0 && index
<= 31)
2077 *pTileInfo
= m_tileTable
[index
].info
;
2078 pOut
->tileType
= m_tileTable
[index
].type
;
2081 if (index
== TileIndexLinearGeneral
)
2083 *pTileInfo
= m_tileTable
[8].info
;
2084 pOut
->tileType
= m_tileTable
[8].type
;
2091 if (flags
.stencil
&& pTileInfoIn
->tileSplitBytes
== 0)
2093 // Stencil always uses index 0
2094 *pTileInfo
= m_tileTable
[0].info
;
2097 // Pass through tile type
2098 pOut
->tileType
= inTileType
;
2101 pOut
->tileIndex
= index
;
2105 ****************************************************************************************************
2106 * SiLib::DecodeGbRegs
2109 * Decodes GB_ADDR_CONFIG and noOfBanks/noOfRanks
2112 * TRUE if all settings are valid
2114 ****************************************************************************************************
2116 BOOL_32
SiLib::DecodeGbRegs(
2117 const ADDR_REGISTER_VALUE
* pRegValue
) ///< [in] create input
2120 BOOL_32 valid
= TRUE
;
2122 reg
.val
= pRegValue
->gbAddrConfig
;
2124 switch (reg
.f
.pipe_interleave_size
)
2126 case ADDR_CONFIG_PIPE_INTERLEAVE_256B
:
2127 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_256B
;
2129 case ADDR_CONFIG_PIPE_INTERLEAVE_512B
:
2130 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_512B
;
2134 ADDR_UNHANDLED_CASE();
2138 switch (reg
.f
.row_size
)
2140 case ADDR_CONFIG_1KB_ROW
:
2141 m_rowSize
= ADDR_ROWSIZE_1KB
;
2143 case ADDR_CONFIG_2KB_ROW
:
2144 m_rowSize
= ADDR_ROWSIZE_2KB
;
2146 case ADDR_CONFIG_4KB_ROW
:
2147 m_rowSize
= ADDR_ROWSIZE_4KB
;
2151 ADDR_UNHANDLED_CASE();
2155 switch (pRegValue
->noOfBanks
)
2168 ADDR_UNHANDLED_CASE();
2172 switch (pRegValue
->noOfRanks
)
2182 ADDR_UNHANDLED_CASE();
2186 m_logicalBanks
= m_banks
* m_ranks
;
2188 ADDR_ASSERT(m_logicalBanks
<= 16);
2194 ****************************************************************************************************
2195 * SiLib::HwlInitGlobalParams
2198 * Initializes global parameters
2201 * TRUE if all settings are valid
2203 ****************************************************************************************************
2205 BOOL_32
SiLib::HwlInitGlobalParams(
2206 const ADDR_CREATE_INPUT
* pCreateIn
) ///< [in] create input
2208 BOOL_32 valid
= TRUE
;
2209 const ADDR_REGISTER_VALUE
* pRegValue
= &pCreateIn
->regValue
;
2211 valid
= DecodeGbRegs(pRegValue
);
2215 if (m_settings
.isTahiti
|| m_settings
.isPitCairn
)
2219 else if (m_settings
.isCapeVerde
|| m_settings
.isOland
)
2225 // Hainan is 2-pipe (m_settings.isHainan == 1)
2229 valid
= InitTileSettingTable(pRegValue
->pTileConfig
, pRegValue
->noOfEntries
);
2233 InitEquationTable();
2243 ****************************************************************************************************
2244 * SiLib::HwlConvertTileInfoToHW
2246 * Entry of si's ConvertTileInfoToHW
2249 ****************************************************************************************************
2251 ADDR_E_RETURNCODE
SiLib::HwlConvertTileInfoToHW(
2252 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
2253 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
2256 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
2258 retCode
= EgBasedLib::HwlConvertTileInfoToHW(pIn
, pOut
);
2260 if (retCode
== ADDR_OK
)
2262 if (pIn
->reverse
== FALSE
)
2264 if (pIn
->pTileInfo
->pipeConfig
== ADDR_PIPECFG_INVALID
)
2266 retCode
= ADDR_INVALIDPARAMS
;
2270 pOut
->pTileInfo
->pipeConfig
=
2271 static_cast<AddrPipeCfg
>(pIn
->pTileInfo
->pipeConfig
- 1);
2276 pOut
->pTileInfo
->pipeConfig
=
2277 static_cast<AddrPipeCfg
>(pIn
->pTileInfo
->pipeConfig
+ 1);
2285 ****************************************************************************************************
2286 * SiLib::HwlComputeXmaskCoordYFrom8Pipe
2289 * Compute the Y coord which will be added to Xmask Y
2293 ****************************************************************************************************
2295 UINT_32
SiLib::HwlComputeXmaskCoordYFrom8Pipe(
2296 UINT_32 pipe
, ///< [in] pipe id
2297 UINT_32 x
///< [in] tile coord x, which is original x coord / 8
2300 // This function should never be called since it is 6xx/8xx specfic.
2301 // Keep this empty implementation to avoid any mis-use.
2302 ADDR_ASSERT_ALWAYS();
2308 ****************************************************************************************************
2309 * SiLib::HwlComputeSurfaceCoord2DFromBankPipe
2312 * Compute surface x,y coordinates from bank/pipe info
2315 ****************************************************************************************************
2317 VOID
SiLib::HwlComputeSurfaceCoord2DFromBankPipe(
2318 AddrTileMode tileMode
, ///< [in] tile mode
2319 UINT_32
* pX
, ///< [in,out] x coordinate
2320 UINT_32
* pY
, ///< [in,out] y coordinate
2321 UINT_32 slice
, ///< [in] slice index
2322 UINT_32 bank
, ///< [in] bank number
2323 UINT_32 pipe
, ///< [in] pipe number
2324 UINT_32 bankSwizzle
,///< [in] bank swizzle
2325 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
2326 UINT_32 tileSlices
, ///< [in] slices in a micro tile
2327 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines are ignored
2328 ADDR_TILEINFO
* pTileInfo
///< [in] bank structure. **All fields to be valid on entry**
2342 UINT_32 numPipes
= GetPipePerSurf(pTileInfo
->pipeConfig
);
2344 CoordFromBankPipe xyBits
= {0};
2345 ComputeSurfaceCoord2DFromBankPipe(tileMode
, *pX
, *pY
, slice
, bank
, pipe
,
2346 bankSwizzle
, pipeSwizzle
, tileSlices
, pTileInfo
,
2348 yBit3
= xyBits
.yBit3
;
2349 yBit4
= xyBits
.yBit4
;
2350 yBit5
= xyBits
.yBit5
;
2351 yBit6
= xyBits
.yBit6
;
2353 xBit3
= xyBits
.xBit3
;
2354 xBit4
= xyBits
.xBit4
;
2355 xBit5
= xyBits
.xBit5
;
2357 yBit
= xyBits
.yBits
;
2359 UINT_32 yBitTemp
= 0;
2361 if ((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P4_32x32
) ||
2362 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
))
2364 ADDR_ASSERT(pTileInfo
->bankWidth
== 1 && pTileInfo
->macroAspectRatio
> 1);
2365 UINT_32 yBitToCheck
= QLog2(pTileInfo
->banks
) - 1;
2367 ADDR_ASSERT(yBitToCheck
<= 3);
2369 yBitTemp
= _BIT(yBit
, yBitToCheck
);
2374 yBit
= Bits2Number(4, yBit6
, yBit5
, yBit4
, yBit3
);
2375 xBit
= Bits2Number(3, xBit5
, xBit4
, xBit3
);
2377 *pY
+= yBit
* pTileInfo
->bankHeight
* MicroTileHeight
;
2378 *pX
+= xBit
* numPipes
* pTileInfo
->bankWidth
* MicroTileWidth
;
2380 //calculate the bank and pipe bits in x, y
2381 UINT_32 xTile
; //x in micro tile
2388 UINT_32 pipeBit0
= _BIT(pipe
,0);
2389 UINT_32 pipeBit1
= _BIT(pipe
,1);
2390 UINT_32 pipeBit2
= _BIT(pipe
,2);
2392 UINT_32 y3
= _BIT(y
, 3);
2393 UINT_32 y4
= _BIT(y
, 4);
2394 UINT_32 y5
= _BIT(y
, 5);
2395 UINT_32 y6
= _BIT(y
, 6);
2397 // bankbit0 after ^x4^x5
2398 UINT_32 bankBit00
= _BIT(bank
,0);
2399 UINT_32 bankBit0
= 0;
2401 switch (pTileInfo
->pipeConfig
)
2403 case ADDR_PIPECFG_P2
:
2406 case ADDR_PIPECFG_P4_8x16
:
2410 case ADDR_PIPECFG_P4_16x16
:
2412 x3
= pipeBit0
^ y3
^ x4
;
2414 case ADDR_PIPECFG_P4_16x32
:
2416 x3
= pipeBit0
^ y3
^ x4
;
2418 case ADDR_PIPECFG_P4_32x32
:
2420 x3
= pipeBit0
^ y3
^ x5
;
2421 bankBit0
= yBitTemp
^ x5
;
2422 x4
= bankBit00
^ x5
^ bankBit0
;
2423 *pX
+= x5
* 4 * 1 * 8; // x5 * num_pipes * bank_width * 8;
2425 case ADDR_PIPECFG_P8_16x16_8x16
:
2428 x5
= pipeBit0
^ y3
^ x4
;
2430 case ADDR_PIPECFG_P8_16x32_8x16
:
2433 x5
= pipeBit0
^ y3
^ x4
;
2435 case ADDR_PIPECFG_P8_32x32_8x16
:
2438 x4
= pipeBit0
^ y3
^ x5
;
2440 case ADDR_PIPECFG_P8_16x32_16x16
:
2443 x3
= pipeBit0
^ y3
^ x4
;
2445 case ADDR_PIPECFG_P8_32x32_16x16
:
2448 x3
= pipeBit0
^ y3
^ x4
;
2450 case ADDR_PIPECFG_P8_32x32_16x32
:
2453 x3
= pipeBit0
^ y3
^ x4
;
2455 case ADDR_PIPECFG_P8_32x64_32x32
:
2458 x3
= pipeBit0
^ y3
^ x5
;
2459 bankBit0
= yBitTemp
^ x6
;
2460 x4
= bankBit00
^ x5
^ bankBit0
;
2461 *pX
+= x6
* 8 * 1 * 8; // x6 * num_pipes * bank_width * 8;
2464 ADDR_ASSERT_ALWAYS();
2467 xTile
= Bits2Number(3, x5
, x4
, x3
);
2473 ****************************************************************************************************
2474 * SiLib::HwlPreAdjustBank
2477 * Adjust bank before calculating address acoording to bank/pipe
2480 ****************************************************************************************************
2482 UINT_32
SiLib::HwlPreAdjustBank(
2483 UINT_32 tileX
, ///< [in] x coordinate in unit of tile
2484 UINT_32 bank
, ///< [in] bank
2485 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2488 if (((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P4_32x32
) ||
2489 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
)) && (pTileInfo
->bankWidth
== 1))
2491 UINT_32 bankBit0
= _BIT(bank
, 0);
2492 UINT_32 x4
= _BIT(tileX
, 1);
2493 UINT_32 x5
= _BIT(tileX
, 2);
2495 bankBit0
= bankBit0
^ x4
^ x5
;
2498 ADDR_ASSERT(pTileInfo
->macroAspectRatio
> 1);
2505 ****************************************************************************************************
2506 * SiLib::HwlComputeSurfaceInfo
2509 * Entry of si's ComputeSurfaceInfo
2512 ****************************************************************************************************
2514 ADDR_E_RETURNCODE
SiLib::HwlComputeSurfaceInfo(
2515 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
2516 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
2519 pOut
->tileIndex
= pIn
->tileIndex
;
2521 ADDR_E_RETURNCODE retCode
= EgBasedLib::HwlComputeSurfaceInfo(pIn
, pOut
);
2523 UINT_32 tileIndex
= static_cast<UINT_32
>(pOut
->tileIndex
);
2525 if ((pIn
->flags
.needEquation
== TRUE
) &&
2526 (pIn
->numSamples
<= 1) &&
2527 (tileIndex
< TileTableSize
))
2529 pOut
->equationIndex
= m_equationLookupTable
[Log2(pIn
->bpp
>> 3)][tileIndex
];
2531 if (pOut
->equationIndex
!= ADDR_INVALID_EQUATION_INDEX
)
2533 pOut
->blockWidth
= m_blockWidth
[pOut
->equationIndex
];
2535 pOut
->blockHeight
= m_blockHeight
[pOut
->equationIndex
];
2537 pOut
->blockSlices
= m_blockSlices
[pOut
->equationIndex
];
2542 pOut
->equationIndex
= ADDR_INVALID_EQUATION_INDEX
;
2549 ****************************************************************************************************
2550 * SiLib::HwlComputeMipLevel
2552 * Compute MipLevel info (including level 0)
2554 * TRUE if HWL's handled
2555 ****************************************************************************************************
2557 BOOL_32
SiLib::HwlComputeMipLevel(
2558 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
///< [in,out] Input structure
2561 // basePitch is calculated from level 0 so we only check this for mipLevel > 0
2562 if (pIn
->mipLevel
> 0)
2564 // Note: Don't check expand 3x formats(96 bit) as the basePitch is not pow2 even if
2565 // we explicity set pow2Pad flag. The 3x base pitch is padded to pow2 but after being
2566 // divided by expandX factor (3) - to program texture pitch, the basePitch is never pow2.
2567 if (ElemLib::IsExpand3x(pIn
->format
) == FALSE
)
2569 // Sublevel pitches are generated from base level pitch instead of width on SI
2570 // If pow2Pad is 0, we don't assert - as this is not really used for a mip chain
2571 ADDR_ASSERT((pIn
->flags
.pow2Pad
== FALSE
) ||
2572 ((pIn
->basePitch
!= 0) && IsPow2(pIn
->basePitch
)));
2575 if (pIn
->basePitch
!= 0)
2577 pIn
->width
= Max(1u, pIn
->basePitch
>> pIn
->mipLevel
);
2581 // pow2Pad is done in PostComputeMipLevel
2587 ****************************************************************************************************
2588 * SiLib::HwlCheckLastMacroTiledLvl
2591 * Sets pOut->last2DLevel to TRUE if it is
2594 ****************************************************************************************************
2596 VOID
SiLib::HwlCheckLastMacroTiledLvl(
2597 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
2598 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in,out] Output structure (used as input, too)
2601 // pow2Pad covers all mipmap cases
2602 if (pIn
->flags
.pow2Pad
)
2604 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
2610 AddrTileMode nextTileMode
;
2612 if (pIn
->mipLevel
== 0 || pIn
->basePitch
== 0)
2614 // Base level or fail-safe case (basePitch == 0)
2615 nextPitch
= pOut
->pitch
>> 1;
2620 nextPitch
= pIn
->basePitch
>> (pIn
->mipLevel
+ 1);
2623 // nextHeight must be shifted from this level's original height rather than a pow2 padded
2624 // one but this requires original height stored somewhere (pOut->height)
2625 ADDR_ASSERT(pOut
->height
!= 0);
2627 // next level's height is just current level's >> 1 in pixels
2628 nextHeight
= pOut
->height
>> 1;
2629 // Special format such as FMT_1 and FMT_32_32_32 can be linear only so we consider block
2630 // compressed foramts
2631 if (ElemLib::IsBlockCompressed(pIn
->format
))
2633 nextHeight
= (nextHeight
+ 3) / 4;
2635 nextHeight
= NextPow2(nextHeight
);
2637 // nextSlices may be 0 if this level's is 1
2638 if (pIn
->flags
.volume
)
2640 nextSlices
= Max(1u, pIn
->numSlices
>> 1);
2644 nextSlices
= pIn
->numSlices
;
2647 nextTileMode
= ComputeSurfaceMipLevelTileMode(pIn
->tileMode
,
2657 pOut
->last2DLevel
= IsMicroTiled(nextTileMode
);
2662 ****************************************************************************************************
2663 * SiLib::HwlDegradeThickTileMode
2666 * Degrades valid tile mode for thick modes if needed
2669 * Suitable tile mode
2670 ****************************************************************************************************
2672 AddrTileMode
SiLib::HwlDegradeThickTileMode(
2673 AddrTileMode baseTileMode
, ///< [in] base tile mode
2674 UINT_32 numSlices
, ///< [in] current number of slices
2675 UINT_32
* pBytesPerTile
///< [in,out] pointer to bytes per slice
2678 return EgBasedLib::HwlDegradeThickTileMode(baseTileMode
, numSlices
, pBytesPerTile
);
2682 ****************************************************************************************************
2683 * SiLib::HwlTileInfoEqual
2686 * Return TRUE if all field are equal
2688 * Only takes care of current HWL's data
2689 ****************************************************************************************************
2691 BOOL_32
SiLib::HwlTileInfoEqual(
2692 const ADDR_TILEINFO
* pLeft
, ///<[in] Left compare operand
2693 const ADDR_TILEINFO
* pRight
///<[in] Right compare operand
2696 BOOL_32 equal
= FALSE
;
2698 if (pLeft
->pipeConfig
== pRight
->pipeConfig
)
2700 equal
= EgBasedLib::HwlTileInfoEqual(pLeft
, pRight
);
2707 ****************************************************************************************************
2708 * SiLib::GetTileSettings
2711 * Get tile setting infos by index.
2713 * Tile setting info.
2714 ****************************************************************************************************
2716 const TileConfig
* SiLib::GetTileSetting(
2717 UINT_32 index
///< [in] Tile index
2720 ADDR_ASSERT(index
< m_noOfEntries
);
2721 return &m_tileTable
[index
];
2725 ****************************************************************************************************
2726 * SiLib::HwlPostCheckTileIndex
2729 * Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches
2730 * tile mode/type/info and change the index if needed
2733 ****************************************************************************************************
2735 INT_32
SiLib::HwlPostCheckTileIndex(
2736 const ADDR_TILEINFO
* pInfo
, ///< [in] Tile Info
2737 AddrTileMode mode
, ///< [in] Tile mode
2738 AddrTileType type
, ///< [in] Tile type
2739 INT curIndex
///< [in] Current index assigned in HwlSetupTileInfo
2742 INT_32 index
= curIndex
;
2744 if (mode
== ADDR_TM_LINEAR_GENERAL
)
2746 index
= TileIndexLinearGeneral
;
2750 BOOL_32 macroTiled
= IsMacroTiled(mode
);
2752 // We need to find a new index if either of them is true
2753 // 1. curIndex is invalid
2754 // 2. tile mode is changed
2755 // 3. tile info does not match for macro tiled
2756 if ((index
== TileIndexInvalid
||
2757 (mode
!= m_tileTable
[index
].mode
) ||
2758 (macroTiled
&& (HwlTileInfoEqual(pInfo
, &m_tileTable
[index
].info
) == FALSE
))))
2760 for (index
= 0; index
< static_cast<INT_32
>(m_noOfEntries
); index
++)
2764 // macro tile modes need all to match
2765 if (HwlTileInfoEqual(pInfo
, &m_tileTable
[index
].info
) &&
2766 (mode
== m_tileTable
[index
].mode
) &&
2767 (type
== m_tileTable
[index
].type
))
2772 else if (mode
== ADDR_TM_LINEAR_ALIGNED
)
2774 // linear mode only needs tile mode to match
2775 if (mode
== m_tileTable
[index
].mode
)
2782 // micro tile modes only need tile mode and tile type to match
2783 if (mode
== m_tileTable
[index
].mode
&&
2784 type
== m_tileTable
[index
].type
)
2793 ADDR_ASSERT(index
< static_cast<INT_32
>(m_noOfEntries
));
2795 if (index
>= static_cast<INT_32
>(m_noOfEntries
))
2797 index
= TileIndexInvalid
;
2804 ****************************************************************************************************
2805 * SiLib::HwlSetupTileCfg
2808 * Map tile index to tile setting.
2811 ****************************************************************************************************
2813 ADDR_E_RETURNCODE
SiLib::HwlSetupTileCfg(
2814 UINT_32 bpp
, ///< [in] Bits per pixel
2815 INT_32 index
, ///< [in] Tile index
2816 INT_32 macroModeIndex
, ///< [in] Index in macro tile mode table(CI)
2817 ADDR_TILEINFO
* pInfo
, ///< [out] Tile Info
2818 AddrTileMode
* pMode
, ///< [out] Tile mode
2819 AddrTileType
* pType
///< [out] Tile type
2822 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
2824 // Global flag to control usage of tileIndex
2825 if (UseTileIndex(index
))
2827 if (index
== TileIndexLinearGeneral
)
2831 *pMode
= ADDR_TM_LINEAR_GENERAL
;
2836 *pType
= ADDR_DISPLAYABLE
;
2842 pInfo
->bankWidth
= 1;
2843 pInfo
->bankHeight
= 1;
2844 pInfo
->macroAspectRatio
= 1;
2845 pInfo
->tileSplitBytes
= 64;
2846 pInfo
->pipeConfig
= ADDR_PIPECFG_P2
;
2849 else if (static_cast<UINT_32
>(index
) >= m_noOfEntries
)
2851 returnCode
= ADDR_INVALIDPARAMS
;
2855 const TileConfig
* pCfgTable
= GetTileSetting(index
);
2859 *pInfo
= pCfgTable
->info
;
2863 if (IsMacroTiled(pCfgTable
->mode
))
2865 returnCode
= ADDR_INVALIDPARAMS
;
2871 *pMode
= pCfgTable
->mode
;
2876 *pType
= pCfgTable
->type
;
2885 ****************************************************************************************************
2886 * SiLib::ReadGbTileMode
2889 * Convert GB_TILE_MODE HW value to TileConfig.
2892 ****************************************************************************************************
2894 VOID
SiLib::ReadGbTileMode(
2895 UINT_32 regValue
, ///< [in] GB_TILE_MODE register
2896 TileConfig
* pCfg
///< [out] output structure
2899 GB_TILE_MODE gbTileMode
;
2900 gbTileMode
.val
= regValue
;
2902 pCfg
->type
= static_cast<AddrTileType
>(gbTileMode
.f
.micro_tile_mode
);
2903 pCfg
->info
.bankHeight
= 1 << gbTileMode
.f
.bank_height
;
2904 pCfg
->info
.bankWidth
= 1 << gbTileMode
.f
.bank_width
;
2905 pCfg
->info
.banks
= 1 << (gbTileMode
.f
.num_banks
+ 1);
2906 pCfg
->info
.macroAspectRatio
= 1 << gbTileMode
.f
.macro_tile_aspect
;
2907 pCfg
->info
.tileSplitBytes
= 64 << gbTileMode
.f
.tile_split
;
2908 pCfg
->info
.pipeConfig
= static_cast<AddrPipeCfg
>(gbTileMode
.f
.pipe_config
+ 1);
2910 UINT_32 regArrayMode
= gbTileMode
.f
.array_mode
;
2912 pCfg
->mode
= static_cast<AddrTileMode
>(regArrayMode
);
2914 if (regArrayMode
== 8) //ARRAY_2D_TILED_XTHICK
2916 pCfg
->mode
= ADDR_TM_2D_TILED_XTHICK
;
2918 else if (regArrayMode
>= 14) //ARRAY_3D_TILED_XTHICK
2920 pCfg
->mode
= static_cast<AddrTileMode
>(pCfg
->mode
+ 3);
2925 ****************************************************************************************************
2926 * SiLib::InitTileSettingTable
2929 * Initialize the ADDR_TILE_CONFIG table.
2931 * TRUE if tile table is correctly initialized
2932 ****************************************************************************************************
2934 BOOL_32
SiLib::InitTileSettingTable(
2935 const UINT_32
* pCfg
, ///< [in] Pointer to table of tile configs
2936 UINT_32 noOfEntries
///< [in] Numbe of entries in the table above
2939 BOOL_32 initOk
= TRUE
;
2941 ADDR_ASSERT(noOfEntries
<= TileTableSize
);
2943 memset(m_tileTable
, 0, sizeof(m_tileTable
));
2945 if (noOfEntries
!= 0)
2947 m_noOfEntries
= noOfEntries
;
2951 m_noOfEntries
= TileTableSize
;
2954 if (pCfg
) // From Client
2956 for (UINT_32 i
= 0; i
< m_noOfEntries
; i
++)
2958 ReadGbTileMode(*(pCfg
+ i
), &m_tileTable
[i
]);
2963 ADDR_ASSERT_ALWAYS();
2969 ADDR_ASSERT(m_tileTable
[TILEINDEX_LINEAR_ALIGNED
].mode
== ADDR_TM_LINEAR_ALIGNED
);
2976 ****************************************************************************************************
2977 * SiLib::HwlGetTileIndex
2980 * Return the virtual/real index for given mode/type/info
2982 * ADDR_OK if successful.
2983 ****************************************************************************************************
2985 ADDR_E_RETURNCODE
SiLib::HwlGetTileIndex(
2986 const ADDR_GET_TILEINDEX_INPUT
* pIn
,
2987 ADDR_GET_TILEINDEX_OUTPUT
* pOut
) const
2989 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
2991 pOut
->index
= HwlPostCheckTileIndex(pIn
->pTileInfo
, pIn
->tileMode
, pIn
->tileType
);
2997 ****************************************************************************************************
2998 * SiLib::HwlFmaskPreThunkSurfInfo
3001 * Some preparation before thunking a ComputeSurfaceInfo call for Fmask
3004 ****************************************************************************************************
3006 VOID
SiLib::HwlFmaskPreThunkSurfInfo(
3007 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pFmaskIn
, ///< [in] Input of fmask info
3008 const ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pFmaskOut
, ///< [in] Output of fmask info
3009 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pSurfIn
, ///< [out] Input of thunked surface info
3010 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pSurfOut
///< [out] Output of thunked surface info
3013 pSurfIn
->tileIndex
= pFmaskIn
->tileIndex
;
3017 ****************************************************************************************************
3018 * SiLib::HwlFmaskPostThunkSurfInfo
3021 * Copy hwl extra field after calling thunked ComputeSurfaceInfo
3024 ****************************************************************************************************
3026 VOID
SiLib::HwlFmaskPostThunkSurfInfo(
3027 const ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pSurfOut
, ///< [in] Output of surface info
3028 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pFmaskOut
///< [out] Output of fmask info
3031 pFmaskOut
->macroModeIndex
= TileIndexInvalid
;
3032 pFmaskOut
->tileIndex
= pSurfOut
->tileIndex
;
3036 ****************************************************************************************************
3037 * SiLib::HwlComputeFmaskBits
3039 * Computes fmask bits
3042 ****************************************************************************************************
3044 UINT_32
SiLib::HwlComputeFmaskBits(
3045 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
,
3046 UINT_32
* pNumSamples
3049 UINT_32 numSamples
= pIn
->numSamples
;
3050 UINT_32 numFrags
= GetNumFragments(numSamples
, pIn
->numFrags
);
3053 if (numFrags
!= numSamples
) // EQAA
3055 ADDR_ASSERT(numFrags
<= 8);
3057 if (pIn
->resolved
== FALSE
)
3062 numSamples
= numSamples
== 16 ? 16 : 8;
3064 else if (numFrags
== 2)
3066 ADDR_ASSERT(numSamples
>= 4);
3069 numSamples
= numSamples
;
3071 else if (numFrags
== 4)
3073 ADDR_ASSERT(numSamples
>= 4);
3076 numSamples
= numSamples
;
3078 else // numFrags == 8
3080 ADDR_ASSERT(numSamples
== 16);
3083 numSamples
= numSamples
;
3090 bpp
= (numSamples
== 16) ? 16 : 8;
3093 else if (numFrags
== 2)
3095 ADDR_ASSERT(numSamples
>= 4);
3100 else if (numFrags
== 4)
3102 ADDR_ASSERT(numSamples
>= 4);
3107 else // numFrags == 8
3109 ADDR_ASSERT(numSamples
>= 16);
3118 if (pIn
->resolved
== FALSE
)
3120 bpp
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3121 numSamples
= numSamples
== 2 ? 8 : numSamples
;
3126 bpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3127 numSamples
= 1; // 1x sample
3131 SafeAssign(pNumSamples
, numSamples
);
3137 ****************************************************************************************************
3138 * SiLib::HwlOptimizeTileMode
3141 * Optimize tile mode on SI
3146 ****************************************************************************************************
3148 VOID
SiLib::HwlOptimizeTileMode(
3149 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
3152 AddrTileMode tileMode
= pInOut
->tileMode
;
3154 if ((pInOut
->flags
.needEquation
== TRUE
) &&
3155 (IsMacroTiled(tileMode
) == TRUE
) &&
3156 (pInOut
->numSamples
<= 1))
3158 UINT_32 thickness
= Thickness(tileMode
);
3160 pInOut
->flags
.prt
= TRUE
;
3164 tileMode
= ADDR_TM_1D_TILED_THICK
;
3166 else if (pInOut
->numSlices
> 1)
3168 tileMode
= ADDR_TM_1D_TILED_THIN1
;
3172 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3176 if (tileMode
!= pInOut
->tileMode
)
3178 pInOut
->tileMode
= tileMode
;
3183 ****************************************************************************************************
3184 * SiLib::HwlOverrideTileMode
3187 * Override tile modes (for PRT only, avoid client passes in an invalid PRT mode for SI.
3192 ****************************************************************************************************
3194 VOID
SiLib::HwlOverrideTileMode(
3195 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
3198 AddrTileMode tileMode
= pInOut
->tileMode
;
3202 case ADDR_TM_PRT_TILED_THIN1
:
3203 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3206 case ADDR_TM_PRT_TILED_THICK
:
3207 tileMode
= ADDR_TM_2D_TILED_THICK
;
3210 case ADDR_TM_PRT_2D_TILED_THICK
:
3211 tileMode
= ADDR_TM_2D_TILED_THICK
;
3214 case ADDR_TM_PRT_3D_TILED_THICK
:
3215 tileMode
= ADDR_TM_3D_TILED_THICK
;
3222 if (tileMode
!= pInOut
->tileMode
)
3224 pInOut
->tileMode
= tileMode
;
3226 ADDR_ASSERT(pInOut
->flags
.prt
== TRUE
);
3231 ****************************************************************************************************
3232 * SiLib::HwlSetPrtTileMode
3235 * Set prt tile modes.
3240 ****************************************************************************************************
3242 VOID
SiLib::HwlSetPrtTileMode(
3243 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
3246 pInOut
->tileMode
= ADDR_TM_2D_TILED_THIN1
;
3247 pInOut
->tileType
= (pInOut
->tileType
== ADDR_DEPTH_SAMPLE_ORDER
) ?
3248 ADDR_DEPTH_SAMPLE_ORDER
: ADDR_NON_DISPLAYABLE
;
3249 pInOut
->flags
.prt
= TRUE
;
3253 ****************************************************************************************************
3254 * SiLib::HwlSelectTileMode
3257 * Select tile modes.
3262 ****************************************************************************************************
3264 VOID
SiLib::HwlSelectTileMode(
3265 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
3268 AddrTileMode tileMode
;
3269 AddrTileType tileType
;
3271 if (pInOut
->flags
.volume
)
3273 if (pInOut
->numSlices
>= 8)
3275 tileMode
= ADDR_TM_2D_TILED_XTHICK
;
3277 else if (pInOut
->numSlices
>= 4)
3279 tileMode
= ADDR_TM_2D_TILED_THICK
;
3283 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3285 tileType
= ADDR_NON_DISPLAYABLE
;
3289 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3291 if (pInOut
->flags
.depth
|| pInOut
->flags
.stencil
)
3293 tileType
= ADDR_DEPTH_SAMPLE_ORDER
;
3295 else if ((pInOut
->bpp
<= 32) ||
3296 (pInOut
->flags
.display
== TRUE
) ||
3297 (pInOut
->flags
.overlay
== TRUE
))
3299 tileType
= ADDR_DISPLAYABLE
;
3303 tileType
= ADDR_NON_DISPLAYABLE
;
3307 if (pInOut
->flags
.prt
)
3309 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3310 tileType
= (tileType
== ADDR_DISPLAYABLE
) ? ADDR_NON_DISPLAYABLE
: tileType
;
3313 pInOut
->tileMode
= tileMode
;
3314 pInOut
->tileType
= tileType
;
3316 // Optimize tile mode if possible
3317 pInOut
->flags
.opt4Space
= TRUE
;
3319 // Optimize tile mode if possible
3320 OptimizeTileMode(pInOut
);
3322 HwlOverrideTileMode(pInOut
);
3326 ****************************************************************************************************
3327 * SiLib::HwlGetMaxAlignments
3330 * Gets maximum alignments
3333 ****************************************************************************************************
3335 ADDR_E_RETURNCODE
SiLib::HwlGetMaxAlignments(
3336 ADDR_GET_MAX_ALINGMENTS_OUTPUT
* pOut
///< [out] output structure
3339 const UINT_32 pipes
= HwlGetPipes(&m_tileTable
[0].info
);
3341 // Initial size is 64 KiB for PRT.
3342 UINT_64 maxBaseAlign
= 64 * 1024;
3344 for (UINT_32 i
= 0; i
< m_noOfEntries
; i
++)
3346 if ((IsMacroTiled(m_tileTable
[i
].mode
) == TRUE
) &&
3347 (IsPrtTileMode(m_tileTable
[i
].mode
) == FALSE
))
3349 // The maximum tile size is 16 byte-per-pixel and either 8-sample or 8-slice.
3350 UINT_32 tileSize
= Min(m_tileTable
[i
].info
.tileSplitBytes
,
3351 MicroTilePixels
* 8 * 16);
3353 UINT_64 baseAlign
= tileSize
* pipes
* m_tileTable
[i
].info
.banks
*
3354 m_tileTable
[i
].info
.bankWidth
* m_tileTable
[i
].info
.bankHeight
;
3356 if (baseAlign
> maxBaseAlign
)
3358 maxBaseAlign
= baseAlign
;
3365 pOut
->baseAlign
= maxBaseAlign
;
3372 ****************************************************************************************************
3373 * SiLib::HwlComputeSurfaceAlignmentsMacroTiled
3376 * Hardware layer function to compute alignment request for macro tile mode
3381 ****************************************************************************************************
3383 VOID
SiLib::HwlComputeSurfaceAlignmentsMacroTiled(
3384 AddrTileMode tileMode
, ///< [in] tile mode
3385 UINT_32 bpp
, ///< [in] bits per pixel
3386 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
3387 UINT_32 mipLevel
, ///< [in] mip level
3388 UINT_32 numSamples
, ///< [in] number of samples
3389 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in,out] Surface output
3392 if ((mipLevel
== 0) && (flags
.prt
))
3394 UINT_32 macroTileSize
= pOut
->blockWidth
* pOut
->blockHeight
* numSamples
* bpp
/ 8;
3396 if (macroTileSize
< PrtTileSize
)
3398 UINT_32 numMacroTiles
= PrtTileSize
/ macroTileSize
;
3400 ADDR_ASSERT((PrtTileSize
% macroTileSize
) == 0);
3402 pOut
->pitchAlign
*= numMacroTiles
;
3403 pOut
->baseAlign
*= numMacroTiles
;
3409 ****************************************************************************************************
3410 * SiLib::InitEquationTable
3413 * Initialize Equation table.
3417 ****************************************************************************************************
3419 VOID
SiLib::InitEquationTable()
3421 ADDR_EQUATION_KEY equationKeyTable
[EquationTableSize
];
3422 memset(equationKeyTable
, 0, sizeof(equationKeyTable
));
3424 memset(m_equationTable
, 0, sizeof(m_equationTable
));
3426 memset(m_blockWidth
, 0, sizeof(m_blockWidth
));
3428 memset(m_blockHeight
, 0, sizeof(m_blockHeight
));
3430 memset(m_blockSlices
, 0, sizeof(m_blockSlices
));
3432 // Loop all possible bpp
3433 for (UINT_32 log2ElementBytes
= 0; log2ElementBytes
< MaxNumElementBytes
; log2ElementBytes
++)
3435 // Get bits per pixel
3436 UINT_32 bpp
= 1 << (log2ElementBytes
+ 3);
3438 // Loop all possible tile index
3439 for (INT_32 tileIndex
= 0; tileIndex
< static_cast<INT_32
>(m_noOfEntries
); tileIndex
++)
3441 UINT_32 equationIndex
= ADDR_INVALID_EQUATION_INDEX
;
3443 TileConfig tileConfig
= m_tileTable
[tileIndex
];
3445 ADDR_SURFACE_FLAGS flags
= {{0}};
3447 // Compute tile info, hardcode numSamples to 1 because MSAA is not supported
3448 // in swizzle pattern equation
3449 HwlComputeMacroModeIndex(tileIndex
, flags
, bpp
, 1, &tileConfig
.info
, NULL
, NULL
);
3451 // Check if the input is supported
3452 if (IsEquationSupported(bpp
, tileConfig
, tileIndex
) == TRUE
)
3454 ADDR_EQUATION_KEY key
= {{0}};
3456 // Generate swizzle equation key from bpp and tile config
3457 key
.fields
.log2ElementBytes
= log2ElementBytes
;
3458 key
.fields
.tileMode
= tileConfig
.mode
;
3459 // Treat depth micro tile type and non-display micro tile type as the same key
3460 // because they have the same equation actually
3461 key
.fields
.microTileType
= (tileConfig
.type
== ADDR_DEPTH_SAMPLE_ORDER
) ?
3462 ADDR_NON_DISPLAYABLE
: tileConfig
.type
;
3463 key
.fields
.pipeConfig
= tileConfig
.info
.pipeConfig
;
3464 key
.fields
.numBanks
= tileConfig
.info
.banks
;
3465 key
.fields
.bankWidth
= tileConfig
.info
.bankWidth
;
3466 key
.fields
.bankHeight
= tileConfig
.info
.bankHeight
;
3467 key
.fields
.macroAspectRatio
= tileConfig
.info
.macroAspectRatio
;
3469 // Find in the table if the equation has been built based on the key
3470 for (UINT_32 i
= 0; i
< m_numEquations
; i
++)
3472 if (key
.value
== equationKeyTable
[i
].value
)
3479 // If found, just fill the index into the lookup table and no need
3480 // to generate the equation again. Otherwise, generate the equation.
3481 if (equationIndex
== ADDR_INVALID_EQUATION_INDEX
)
3483 ADDR_EQUATION equation
;
3484 ADDR_E_RETURNCODE retCode
;
3486 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
3488 // Generate the equation
3489 if (IsMicroTiled(tileConfig
.mode
))
3491 retCode
= ComputeMicroTileEquation(log2ElementBytes
,
3498 retCode
= ComputeMacroTileEquation(log2ElementBytes
,
3504 // Only fill the equation into the table if the return code is ADDR_OK,
3505 // otherwise if the return code is not ADDR_OK, it indicates this is not
3506 // a valid input, we do nothing but just fill invalid equation index
3507 // into the lookup table.
3508 if (retCode
== ADDR_OK
)
3510 equationIndex
= m_numEquations
;
3511 ADDR_ASSERT(equationIndex
< EquationTableSize
);
3513 m_blockSlices
[equationIndex
] = Thickness(tileConfig
.mode
);
3515 if (IsMicroTiled(tileConfig
.mode
))
3517 m_blockWidth
[equationIndex
] = MicroTileWidth
;
3518 m_blockHeight
[equationIndex
] = MicroTileHeight
;
3522 const ADDR_TILEINFO
* pTileInfo
= &tileConfig
.info
;
3524 m_blockWidth
[equationIndex
] =
3525 HwlGetPipes(pTileInfo
) * MicroTileWidth
* pTileInfo
->bankWidth
*
3526 pTileInfo
->macroAspectRatio
;
3527 m_blockHeight
[equationIndex
] =
3528 MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
/
3529 pTileInfo
->macroAspectRatio
;
3531 if (m_chipFamily
== ADDR_CHIP_FAMILY_SI
)
3533 UINT_32 macroTileSize
=
3534 m_blockWidth
[equationIndex
] * m_blockHeight
[equationIndex
] *
3537 if (macroTileSize
< PrtTileSize
)
3539 UINT_32 numMacroTiles
= PrtTileSize
/ macroTileSize
;
3541 ADDR_ASSERT(macroTileSize
== (1u << equation
.numBits
));
3542 ADDR_ASSERT((PrtTileSize
% macroTileSize
) == 0);
3544 UINT_32 numBits
= Log2(numMacroTiles
);
3546 UINT_32 xStart
= Log2(m_blockWidth
[equationIndex
]) +
3549 m_blockWidth
[equationIndex
] *= numMacroTiles
;
3551 for (UINT_32 i
= 0; i
< numBits
; i
++)
3553 equation
.addr
[equation
.numBits
+ i
].valid
= 1;
3554 equation
.addr
[equation
.numBits
+ i
].index
= xStart
+ i
;
3557 equation
.numBits
+= numBits
;
3562 equationKeyTable
[equationIndex
] = key
;
3563 m_equationTable
[equationIndex
] = equation
;
3570 // Fill the index into the lookup table, if the combination is not supported
3571 // fill the invalid equation index
3572 m_equationLookupTable
[log2ElementBytes
][tileIndex
] = equationIndex
;
3578 ****************************************************************************************************
3579 * SiLib::IsEquationSupported
3582 * Check if it is supported for given bpp and tile config to generate a equation.
3586 ****************************************************************************************************
3588 BOOL_32
SiLib::IsEquationSupported(
3589 UINT_32 bpp
, ///< Bits per pixel
3590 TileConfig tileConfig
, ///< Tile config
3591 INT_32 tileIndex
///< Tile index
3594 BOOL_32 supported
= TRUE
;
3596 // Linear tile mode is not supported in swizzle pattern equation
3597 if (IsLinear(tileConfig
.mode
))
3601 // These tile modes are for Tex2DArray and Tex3D which has depth (num_slice > 1) use,
3602 // which is not supported in swizzle pattern equation due to slice rotation
3603 else if ((tileConfig
.mode
== ADDR_TM_2D_TILED_THICK
) ||
3604 (tileConfig
.mode
== ADDR_TM_2D_TILED_XTHICK
) ||
3605 (tileConfig
.mode
== ADDR_TM_3D_TILED_THIN1
) ||
3606 (tileConfig
.mode
== ADDR_TM_3D_TILED_THICK
) ||
3607 (tileConfig
.mode
== ADDR_TM_3D_TILED_XTHICK
))
3611 // Only 8bpp(stencil), 16bpp and 32bpp is supported for depth
3612 else if ((tileConfig
.type
== ADDR_DEPTH_SAMPLE_ORDER
) && (bpp
> 32))
3616 // Tile split is not supported in swizzle pattern equation
3617 else if (IsMacroTiled(tileConfig
.mode
))
3619 UINT_32 thickness
= Thickness(tileConfig
.mode
);
3620 if (((bpp
>> 3) * MicroTilePixels
* thickness
) > tileConfig
.info
.tileSplitBytes
)
3625 if ((supported
== TRUE
) && (m_chipFamily
== ADDR_CHIP_FAMILY_SI
))
3627 // Please refer to SiLib::HwlSetupTileInfo for PRT tile index selecting
3628 // Tile index 3, 6, 21-25 are for PRT single sample
3631 supported
= (bpp
== 16);
3633 else if (tileIndex
== 6)
3635 supported
= (bpp
== 32);
3637 else if ((tileIndex
>= 21) && (tileIndex
<= 25))
3639 supported
= (bpp
== 8u * (1u << (static_cast<UINT_32
>(tileIndex
) - 21u)));