2 * Copyright © 2007-2018 Advanced Micro Devices, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
28 ****************************************************************************************************
30 * @brief Contains the implementation for the SiLib class.
31 ****************************************************************************************************
34 #include "siaddrlib.h"
35 #include "si_gb_reg.h"
37 #include "amdgpu_asic_addr.h"
39 ////////////////////////////////////////////////////////////////////////////////////////////////////
40 ////////////////////////////////////////////////////////////////////////////////////////////////////
45 ****************************************************************************************************
49 * Creates an SiLib object.
52 * Returns an SiLib object pointer.
53 ****************************************************************************************************
55 Lib
* SiHwlInit(const Client
* pClient
)
57 return V1::SiLib::CreateObj(pClient
);
63 // We don't support MSAA for equation
64 const BOOL_32
SiLib::m_EquationSupport
[SiLib::TileTableSize
][SiLib::MaxNumElementBytes
] =
66 {TRUE
, TRUE
, TRUE
, FALSE
, FALSE
}, // 0, non-AA compressed depth or any stencil
67 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 1, 2xAA/4xAA compressed depth with or without stencil
68 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 2, 8xAA compressed depth with or without stencil
69 {FALSE
, TRUE
, FALSE
, FALSE
, FALSE
}, // 3, 16 bpp depth PRT (non-MSAA), don't support uncompressed depth
70 {TRUE
, TRUE
, TRUE
, FALSE
, FALSE
}, // 4, 1D depth
71 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 5, 16 bpp depth PRT (4xMSAA)
72 {FALSE
, FALSE
, TRUE
, FALSE
, FALSE
}, // 6, 32 bpp depth PRT (non-MSAA)
73 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 7, 32 bpp depth PRT (4xMSAA)
74 {TRUE
, TRUE
, TRUE
, TRUE
, TRUE
}, // 8, Linear
75 {TRUE
, TRUE
, TRUE
, TRUE
, TRUE
}, // 9, 1D display
76 {TRUE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 10, 8 bpp color (displayable)
77 {FALSE
, TRUE
, FALSE
, FALSE
, FALSE
}, // 11, 16 bpp color (displayable)
78 {FALSE
, FALSE
, TRUE
, TRUE
, FALSE
}, // 12, 32/64 bpp color (displayable)
79 {TRUE
, TRUE
, TRUE
, TRUE
, TRUE
}, // 13, 1D thin
80 {TRUE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 14, 8 bpp color non-displayable
81 {FALSE
, TRUE
, FALSE
, FALSE
, FALSE
}, // 15, 16 bpp color non-displayable
82 {FALSE
, FALSE
, TRUE
, FALSE
, FALSE
}, // 16, 32 bpp color non-displayable
83 {FALSE
, FALSE
, FALSE
, TRUE
, TRUE
}, // 17, 64/128 bpp color non-displayable
84 {TRUE
, TRUE
, TRUE
, TRUE
, TRUE
}, // 18, 1D THICK
85 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 19, 2D XTHICK
86 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 20, 2D THICK
87 {TRUE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 21, 8 bpp 2D PRTs (non-MSAA)
88 {FALSE
, TRUE
, FALSE
, FALSE
, FALSE
}, // 22, 16 bpp 2D PRTs (non-MSAA)
89 {FALSE
, FALSE
, TRUE
, FALSE
, FALSE
}, // 23, 32 bpp 2D PRTs (non-MSAA)
90 {FALSE
, FALSE
, FALSE
, TRUE
, FALSE
}, // 24, 64 bpp 2D PRTs (non-MSAA)
91 {FALSE
, FALSE
, FALSE
, FALSE
, TRUE
}, // 25, 128bpp 2D PRTs (non-MSAA)
92 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 26, none
93 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 27, none
94 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 28, none
95 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 29, none
96 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 30, 64bpp 2D PRTs (4xMSAA)
97 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 31, none
101 ****************************************************************************************************
107 ****************************************************************************************************
109 SiLib::SiLib(const Client
* pClient
)
115 m_class
= SI_ADDRLIB
;
116 memset(&m_settings
, 0, sizeof(m_settings
));
120 ****************************************************************************************************
125 ****************************************************************************************************
132 ****************************************************************************************************
139 ****************************************************************************************************
141 UINT_32
SiLib::HwlGetPipes(
142 const ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
149 numPipes
= GetPipePerSurf(pTileInfo
->pipeConfig
);
153 ADDR_ASSERT_ALWAYS();
154 numPipes
= m_pipes
; // Suppose we should still have a global pipes
161 ****************************************************************************************************
162 * SiLib::GetPipePerSurf
164 * get pipe num base on inputing tileinfo->pipeconfig
167 ****************************************************************************************************
169 UINT_32
SiLib::GetPipePerSurf(
170 AddrPipeCfg pipeConfig
///< [in] pipe config
173 UINT_32 numPipes
= 0;
177 case ADDR_PIPECFG_P2
:
180 case ADDR_PIPECFG_P4_8x16
:
181 case ADDR_PIPECFG_P4_16x16
:
182 case ADDR_PIPECFG_P4_16x32
:
183 case ADDR_PIPECFG_P4_32x32
:
186 case ADDR_PIPECFG_P8_16x16_8x16
:
187 case ADDR_PIPECFG_P8_16x32_8x16
:
188 case ADDR_PIPECFG_P8_32x32_8x16
:
189 case ADDR_PIPECFG_P8_16x32_16x16
:
190 case ADDR_PIPECFG_P8_32x32_16x16
:
191 case ADDR_PIPECFG_P8_32x32_16x32
:
192 case ADDR_PIPECFG_P8_32x64_32x32
:
195 case ADDR_PIPECFG_P16_32x32_8x16
:
196 case ADDR_PIPECFG_P16_32x32_16x16
:
200 ADDR_ASSERT(!"Invalid pipe config");
207 ****************************************************************************************************
208 * SiLib::ComputeBankEquation
211 * Compute bank equation
214 * If equation can be computed
215 ****************************************************************************************************
217 ADDR_E_RETURNCODE
SiLib::ComputeBankEquation(
218 UINT_32 log2BytesPP
, ///< [in] log2 of bytes per pixel
219 UINT_32 threshX
, ///< [in] threshold for x channel
220 UINT_32 threshY
, ///< [in] threshold for y channel
221 ADDR_TILEINFO
* pTileInfo
, ///< [in] tile info
222 ADDR_EQUATION
* pEquation
///< [out] bank equation
225 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
227 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
228 UINT_32 bankXStart
= 3 + Log2(pipes
) + Log2(pTileInfo
->bankWidth
);
229 UINT_32 bankYStart
= 3 + Log2(pTileInfo
->bankHeight
);
231 ADDR_CHANNEL_SETTING x3
= InitChannel(1, 0, log2BytesPP
+ bankXStart
);
232 ADDR_CHANNEL_SETTING x4
= InitChannel(1, 0, log2BytesPP
+ bankXStart
+ 1);
233 ADDR_CHANNEL_SETTING x5
= InitChannel(1, 0, log2BytesPP
+ bankXStart
+ 2);
234 ADDR_CHANNEL_SETTING x6
= InitChannel(1, 0, log2BytesPP
+ bankXStart
+ 3);
235 ADDR_CHANNEL_SETTING y3
= InitChannel(1, 1, bankYStart
);
236 ADDR_CHANNEL_SETTING y4
= InitChannel(1, 1, bankYStart
+ 1);
237 ADDR_CHANNEL_SETTING y5
= InitChannel(1, 1, bankYStart
+ 2);
238 ADDR_CHANNEL_SETTING y6
= InitChannel(1, 1, bankYStart
+ 3);
240 x3
.value
= (threshX
> bankXStart
) ? x3
.value
: 0;
241 x4
.value
= (threshX
> bankXStart
+ 1) ? x4
.value
: 0;
242 x5
.value
= (threshX
> bankXStart
+ 2) ? x5
.value
: 0;
243 x6
.value
= (threshX
> bankXStart
+ 3) ? x6
.value
: 0;
244 y3
.value
= (threshY
> bankYStart
) ? y3
.value
: 0;
245 y4
.value
= (threshY
> bankYStart
+ 1) ? y4
.value
: 0;
246 y5
.value
= (threshY
> bankYStart
+ 2) ? y5
.value
: 0;
247 y6
.value
= (threshY
> bankYStart
+ 3) ? y6
.value
: 0;
249 switch (pTileInfo
->banks
)
252 if (pTileInfo
->macroAspectRatio
== 1)
254 pEquation
->addr
[0] = y6
;
255 pEquation
->xor1
[0] = x3
;
256 pEquation
->addr
[1] = y5
;
257 pEquation
->xor1
[1] = y6
;
258 pEquation
->xor2
[1] = x4
;
259 pEquation
->addr
[2] = y4
;
260 pEquation
->xor1
[2] = x5
;
261 pEquation
->addr
[3] = y3
;
262 pEquation
->xor1
[3] = x6
;
264 else if (pTileInfo
->macroAspectRatio
== 2)
266 pEquation
->addr
[0] = x3
;
267 pEquation
->xor1
[0] = y6
;
268 pEquation
->addr
[1] = y5
;
269 pEquation
->xor1
[1] = y6
;
270 pEquation
->xor2
[1] = x4
;
271 pEquation
->addr
[2] = y4
;
272 pEquation
->xor1
[2] = x5
;
273 pEquation
->addr
[3] = y3
;
274 pEquation
->xor1
[3] = x6
;
276 else if (pTileInfo
->macroAspectRatio
== 4)
278 pEquation
->addr
[0] = x3
;
279 pEquation
->xor1
[0] = y6
;
280 pEquation
->addr
[1] = x4
;
281 pEquation
->xor1
[1] = y5
;
282 pEquation
->xor2
[1] = y6
;
283 pEquation
->addr
[2] = y4
;
284 pEquation
->xor1
[2] = x5
;
285 pEquation
->addr
[3] = y3
;
286 pEquation
->xor1
[3] = x6
;
288 else if (pTileInfo
->macroAspectRatio
== 8)
290 pEquation
->addr
[0] = x3
;
291 pEquation
->xor1
[0] = y6
;
292 pEquation
->addr
[1] = x4
;
293 pEquation
->xor1
[1] = y5
;
294 pEquation
->xor2
[1] = y6
;
295 pEquation
->addr
[2] = x5
;
296 pEquation
->xor1
[2] = y4
;
297 pEquation
->addr
[3] = y3
;
298 pEquation
->xor1
[3] = x6
;
302 ADDR_ASSERT_ALWAYS();
304 pEquation
->numBits
= 4;
307 if (pTileInfo
->macroAspectRatio
== 1)
309 pEquation
->addr
[0] = y5
;
310 pEquation
->xor1
[0] = x3
;
311 pEquation
->addr
[1] = y4
;
312 pEquation
->xor1
[1] = y5
;
313 pEquation
->xor2
[1] = x4
;
314 pEquation
->addr
[2] = y3
;
315 pEquation
->xor1
[2] = x5
;
317 else if (pTileInfo
->macroAspectRatio
== 2)
319 pEquation
->addr
[0] = x3
;
320 pEquation
->xor1
[0] = y5
;
321 pEquation
->addr
[1] = y4
;
322 pEquation
->xor1
[1] = y5
;
323 pEquation
->xor2
[1] = x4
;
324 pEquation
->addr
[2] = y3
;
325 pEquation
->xor1
[2] = x5
;
327 else if (pTileInfo
->macroAspectRatio
== 4)
329 pEquation
->addr
[0] = x3
;
330 pEquation
->xor1
[0] = y5
;
331 pEquation
->addr
[1] = x4
;
332 pEquation
->xor1
[1] = y4
;
333 pEquation
->xor2
[1] = y5
;
334 pEquation
->addr
[2] = y3
;
335 pEquation
->xor1
[2] = x5
;
339 ADDR_ASSERT_ALWAYS();
341 pEquation
->numBits
= 3;
344 if (pTileInfo
->macroAspectRatio
== 1)
346 pEquation
->addr
[0] = y4
;
347 pEquation
->xor1
[0] = x3
;
348 pEquation
->addr
[1] = y3
;
349 pEquation
->xor1
[1] = x4
;
351 else if (pTileInfo
->macroAspectRatio
== 2)
353 pEquation
->addr
[0] = x3
;
354 pEquation
->xor1
[0] = y4
;
355 pEquation
->addr
[1] = y3
;
356 pEquation
->xor1
[1] = x4
;
360 pEquation
->addr
[0] = x3
;
361 pEquation
->xor1
[0] = y4
;
362 pEquation
->addr
[1] = x4
;
363 pEquation
->xor1
[1] = y3
;
365 pEquation
->numBits
= 2;
368 if (pTileInfo
->macroAspectRatio
== 1)
370 pEquation
->addr
[0] = y3
;
371 pEquation
->xor1
[0] = x3
;
375 pEquation
->addr
[0] = x3
;
376 pEquation
->xor1
[0] = y3
;
378 pEquation
->numBits
= 1;
381 pEquation
->numBits
= 0;
382 retCode
= ADDR_NOTSUPPORTED
;
383 ADDR_ASSERT_ALWAYS();
387 for (UINT_32 i
= 0; i
< pEquation
->numBits
; i
++)
389 if (pEquation
->addr
[i
].value
== 0)
391 if (pEquation
->xor1
[i
].value
== 0)
394 pEquation
->addr
[i
].value
= pEquation
->xor2
[i
].value
;
395 pEquation
->xor2
[i
].value
= 0;
399 pEquation
->addr
[i
].value
= pEquation
->xor1
[i
].value
;
401 if (pEquation
->xor2
[i
].value
!= 0)
404 pEquation
->xor1
[i
].value
= pEquation
->xor2
[i
].value
;
405 pEquation
->xor2
[i
].value
= 0;
410 pEquation
->xor1
[i
].value
= 0;
414 else if (pEquation
->xor1
[i
].value
== 0)
416 if (pEquation
->xor2
[i
].value
!= 0)
419 pEquation
->xor1
[i
].value
= pEquation
->xor2
[i
].value
;
420 pEquation
->xor2
[i
].value
= 0;
425 if ((pTileInfo
->bankWidth
== 1) &&
426 ((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P4_32x32
) ||
427 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
)))
429 retCode
= ADDR_NOTSUPPORTED
;
436 ****************************************************************************************************
437 * SiLib::ComputePipeEquation
440 * Compute pipe equation
443 * If equation can be computed
444 ****************************************************************************************************
446 ADDR_E_RETURNCODE
SiLib::ComputePipeEquation(
447 UINT_32 log2BytesPP
, ///< [in] Log2 of bytes per pixel
448 UINT_32 threshX
, ///< [in] Threshold for X channel
449 UINT_32 threshY
, ///< [in] Threshold for Y channel
450 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
451 ADDR_EQUATION
* pEquation
///< [out] Pipe configure
454 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
456 ADDR_CHANNEL_SETTING
* pAddr
= pEquation
->addr
;
457 ADDR_CHANNEL_SETTING
* pXor1
= pEquation
->xor1
;
458 ADDR_CHANNEL_SETTING
* pXor2
= pEquation
->xor2
;
460 ADDR_CHANNEL_SETTING x3
= InitChannel(1, 0, 3 + log2BytesPP
);
461 ADDR_CHANNEL_SETTING x4
= InitChannel(1, 0, 4 + log2BytesPP
);
462 ADDR_CHANNEL_SETTING x5
= InitChannel(1, 0, 5 + log2BytesPP
);
463 ADDR_CHANNEL_SETTING x6
= InitChannel(1, 0, 6 + log2BytesPP
);
464 ADDR_CHANNEL_SETTING y3
= InitChannel(1, 1, 3);
465 ADDR_CHANNEL_SETTING y4
= InitChannel(1, 1, 4);
466 ADDR_CHANNEL_SETTING y5
= InitChannel(1, 1, 5);
467 ADDR_CHANNEL_SETTING y6
= InitChannel(1, 1, 6);
469 x3
.value
= (threshX
> 3) ? x3
.value
: 0;
470 x4
.value
= (threshX
> 4) ? x4
.value
: 0;
471 x5
.value
= (threshX
> 5) ? x5
.value
: 0;
472 x6
.value
= (threshX
> 6) ? x6
.value
: 0;
473 y3
.value
= (threshY
> 3) ? y3
.value
: 0;
474 y4
.value
= (threshY
> 4) ? y4
.value
: 0;
475 y5
.value
= (threshY
> 5) ? y5
.value
: 0;
476 y6
.value
= (threshY
> 6) ? y6
.value
: 0;
478 switch (pTileInfo
->pipeConfig
)
480 case ADDR_PIPECFG_P2
:
483 pEquation
->numBits
= 1;
485 case ADDR_PIPECFG_P4_8x16
:
490 pEquation
->numBits
= 2;
492 case ADDR_PIPECFG_P4_16x16
:
498 pEquation
->numBits
= 2;
500 case ADDR_PIPECFG_P4_16x32
:
506 pEquation
->numBits
= 2;
508 case ADDR_PIPECFG_P4_32x32
:
514 pEquation
->numBits
= 2;
516 case ADDR_PIPECFG_P8_16x16_8x16
:
522 pEquation
->numBits
= 3;
524 case ADDR_PIPECFG_P8_16x32_8x16
:
532 pEquation
->numBits
= 3;
534 case ADDR_PIPECFG_P8_16x32_16x16
:
542 pEquation
->numBits
= 3;
544 case ADDR_PIPECFG_P8_32x32_8x16
:
552 pEquation
->numBits
= 3;
554 case ADDR_PIPECFG_P8_32x32_16x16
:
562 pEquation
->numBits
= 3;
564 case ADDR_PIPECFG_P8_32x32_16x32
:
572 pEquation
->numBits
= 3;
574 case ADDR_PIPECFG_P8_32x64_32x32
:
582 pEquation
->numBits
= 3;
584 case ADDR_PIPECFG_P16_32x32_8x16
:
593 pEquation
->numBits
= 4;
595 case ADDR_PIPECFG_P16_32x32_16x16
:
605 pEquation
->numBits
= 4;
608 ADDR_UNHANDLED_CASE();
609 pEquation
->numBits
= 0;
610 retCode
= ADDR_NOTSUPPORTED
;
614 if (m_settings
.isVegaM
&& (pEquation
->numBits
== 4))
616 ADDR_CHANNEL_SETTING addeMsb
= pAddr
[0];
617 ADDR_CHANNEL_SETTING xor1Msb
= pXor1
[0];
618 ADDR_CHANNEL_SETTING xor2Msb
= pXor2
[0];
637 for (UINT_32 i
= 0; i
< pEquation
->numBits
; i
++)
639 if (pAddr
[i
].value
== 0)
641 if (pXor1
[i
].value
== 0)
643 pAddr
[i
].value
= pXor2
[i
].value
;
647 pAddr
[i
].value
= pXor1
[i
].value
;
657 ****************************************************************************************************
658 * SiLib::ComputePipeFromCoord
661 * Compute pipe number from coordinates
664 ****************************************************************************************************
666 UINT_32
SiLib::ComputePipeFromCoord(
667 UINT_32 x
, ///< [in] x coordinate
668 UINT_32 y
, ///< [in] y coordinate
669 UINT_32 slice
, ///< [in] slice index
670 AddrTileMode tileMode
, ///< [in] tile mode
671 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
672 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines are ignored
673 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
677 UINT_32 pipeBit0
= 0;
678 UINT_32 pipeBit1
= 0;
679 UINT_32 pipeBit2
= 0;
680 UINT_32 pipeBit3
= 0;
681 UINT_32 sliceRotation
;
682 UINT_32 numPipes
= 0;
684 UINT_32 tx
= x
/ MicroTileWidth
;
685 UINT_32 ty
= y
/ MicroTileHeight
;
686 UINT_32 x3
= _BIT(tx
,0);
687 UINT_32 x4
= _BIT(tx
,1);
688 UINT_32 x5
= _BIT(tx
,2);
689 UINT_32 x6
= _BIT(tx
,3);
690 UINT_32 y3
= _BIT(ty
,0);
691 UINT_32 y4
= _BIT(ty
,1);
692 UINT_32 y5
= _BIT(ty
,2);
693 UINT_32 y6
= _BIT(ty
,3);
695 switch (pTileInfo
->pipeConfig
)
697 case ADDR_PIPECFG_P2
:
701 case ADDR_PIPECFG_P4_8x16
:
706 case ADDR_PIPECFG_P4_16x16
:
707 pipeBit0
= x3
^ y3
^ x4
;
711 case ADDR_PIPECFG_P4_16x32
:
712 pipeBit0
= x3
^ y3
^ x4
;
716 case ADDR_PIPECFG_P4_32x32
:
717 pipeBit0
= x3
^ y3
^ x5
;
721 case ADDR_PIPECFG_P8_16x16_8x16
:
722 pipeBit0
= x4
^ y3
^ x5
;
726 case ADDR_PIPECFG_P8_16x32_8x16
:
727 pipeBit0
= x4
^ y3
^ x5
;
732 case ADDR_PIPECFG_P8_16x32_16x16
:
733 pipeBit0
= x3
^ y3
^ x4
;
738 case ADDR_PIPECFG_P8_32x32_8x16
:
739 pipeBit0
= x4
^ y3
^ x5
;
744 case ADDR_PIPECFG_P8_32x32_16x16
:
745 pipeBit0
= x3
^ y3
^ x4
;
750 case ADDR_PIPECFG_P8_32x32_16x32
:
751 pipeBit0
= x3
^ y3
^ x4
;
756 case ADDR_PIPECFG_P8_32x64_32x32
:
757 pipeBit0
= x3
^ y3
^ x5
;
762 case ADDR_PIPECFG_P16_32x32_8x16
:
769 case ADDR_PIPECFG_P16_32x32_16x16
:
770 pipeBit0
= x3
^ y3
^ x4
;
777 ADDR_UNHANDLED_CASE();
781 if (m_settings
.isVegaM
&& (numPipes
== 16))
783 UINT_32 pipeMsb
= pipeBit0
;
790 pipe
= pipeBit0
| (pipeBit1
<< 1) | (pipeBit2
<< 2) | (pipeBit3
<< 3);
792 UINT_32 microTileThickness
= Thickness(tileMode
);
795 // Apply pipe rotation for the slice.
799 case ADDR_TM_3D_TILED_THIN1
: //fall through thin
800 case ADDR_TM_3D_TILED_THICK
: //fall through thick
801 case ADDR_TM_3D_TILED_XTHICK
:
803 Max(1, static_cast<INT_32
>(numPipes
/ 2) - 1) * (slice
/ microTileThickness
);
809 pipeSwizzle
+= sliceRotation
;
810 pipeSwizzle
&= (numPipes
- 1);
812 pipe
= pipe
^ pipeSwizzle
;
818 ****************************************************************************************************
819 * SiLib::ComputeTileCoordFromPipeAndElemIdx
822 * Compute (x,y) of a tile within a macro tile from address
825 ****************************************************************************************************
827 VOID
SiLib::ComputeTileCoordFromPipeAndElemIdx(
828 UINT_32 elemIdx
, ///< [in] per pipe element index within a macro tile
829 UINT_32 pipe
, ///< [in] pipe index
830 AddrPipeCfg pipeCfg
, ///< [in] pipe config
831 UINT_32 pitchInMacroTile
, ///< [in] surface pitch in macro tile
832 UINT_32 x
, ///< [in] x coordinate of the (0,0) tile in a macro tile
833 UINT_32 y
, ///< [in] y coordinate of the (0,0) tile in a macro tile
834 UINT_32
* pX
, ///< [out] x coordinate
835 UINT_32
* pY
///< [out] y coordinate
838 UINT_32 pipebit0
= _BIT(pipe
,0);
839 UINT_32 pipebit1
= _BIT(pipe
,1);
840 UINT_32 pipebit2
= _BIT(pipe
,2);
841 UINT_32 pipebit3
= _BIT(pipe
,3);
842 UINT_32 elemIdx0
= _BIT(elemIdx
,0);
843 UINT_32 elemIdx1
= _BIT(elemIdx
,1);
844 UINT_32 elemIdx2
= _BIT(elemIdx
,2);
856 case ADDR_PIPECFG_P2
:
861 *pY
= Bits2Number(2, y4
, y3
);
862 *pX
= Bits2Number(2, x4
, x3
);
864 case ADDR_PIPECFG_P4_8x16
:
869 *pY
= Bits2Number(2, y4
, y3
);
870 *pX
= Bits2Number(2, x4
, x3
);
872 case ADDR_PIPECFG_P4_16x16
:
876 x3
= pipebit0
^ y3
^ x4
;
877 *pY
= Bits2Number(2, y4
, y3
);
878 *pX
= Bits2Number(2, x4
, x3
);
880 case ADDR_PIPECFG_P4_16x32
:
881 x3
= elemIdx0
^ pipebit0
;
884 y3
= pipebit0
^ x3
^ x4
;
886 *pY
= Bits2Number(2, y4
, y3
);
887 *pX
= Bits2Number(2, x4
, x3
);
889 case ADDR_PIPECFG_P4_32x32
:
893 if((pitchInMacroTile
% 2) == 0)
897 x3
= pipebit0
^ y3
^ x5
;
898 *pY
= Bits2Number(2, y4
, y3
);
899 *pX
= Bits2Number(3, x5
, x4
, x3
);
904 x3
= pipebit0
^ y3
^ x5
;
905 *pY
= Bits2Number(2, y4
, y3
);
906 *pX
= Bits2Number(2, x4
, x3
);
909 case ADDR_PIPECFG_P8_16x16_8x16
:
915 y3
= pipebit0
^ x5
^ x4
;
916 *pY
= Bits2Number(2, y4
, y3
);
917 *pX
= Bits2Number(2, x4
, x3
);
919 case ADDR_PIPECFG_P8_16x32_8x16
:
925 y3
= pipebit0
^ x4
^ x5
;
926 *pY
= Bits2Number(2, y4
, y3
);
927 *pX
= Bits2Number(2, x4
, x3
);
929 case ADDR_PIPECFG_P8_32x32_8x16
:
933 if((pitchInMacroTile
% 2) == 0)
938 y3
= pipebit0
^ x4
^ x5
;
939 *pY
= Bits2Number(2, y4
, y3
);
940 *pX
= Bits2Number(3, x5
, x4
, x3
);
945 y3
= pipebit0
^ x4
^ x5
;
946 *pY
= Bits2Number(2, y4
, y3
);
947 *pX
= Bits2Number(2, x4
, x3
);
950 case ADDR_PIPECFG_P8_16x32_16x16
:
956 y3
= pipebit0
^ x3
^ x4
;
957 *pY
= Bits2Number(2, y4
, y3
);
958 *pX
= Bits2Number(2, x4
, x3
);
960 case ADDR_PIPECFG_P8_32x32_16x16
:
965 if((pitchInMacroTile
% 2) == 0)
969 *pY
= Bits2Number(2, y4
, y3
);
970 *pX
= Bits2Number(3, x5
, x4
, x3
);
974 *pY
= Bits2Number(2, y4
, y3
);
975 *pX
= Bits2Number(2, x4
, x3
);
978 case ADDR_PIPECFG_P8_32x32_16x32
:
979 if((pitchInMacroTile
% 2) == 0)
986 x3
= pipebit0
^ y3
^ x4
;
988 *pY
= Bits2Number(2, y4
, y3
);
989 *pX
= Bits2Number(3, x5
, x4
, x3
);
997 x3
= pipebit0
^ y3
^ x4
;
998 *pY
= Bits2Number(2, y4
, y3
);
999 *pX
= Bits2Number(2, x4
, x3
);
1002 case ADDR_PIPECFG_P8_32x64_32x32
:
1006 if((pitchInMacroTile
% 4) == 0)
1012 x3
= pipebit0
^ y3
^ x5
;
1013 *pY
= Bits2Number(2, y4
, y3
);
1014 *pX
= Bits2Number(4, x6
, x5
, x4
, x3
);
1020 x3
= pipebit0
^ y3
^ x5
;
1021 *pY
= Bits2Number(2, y4
, y3
);
1022 *pX
= Bits2Number(3, x5
, x4
, x3
);
1025 case ADDR_PIPECFG_P16_32x32_8x16
:
1030 if((pitchInMacroTile
% 4) == 0)
1036 *pY
= Bits2Number(2, y4
, y3
);
1037 *pX
= Bits2Number(4, x6
, x5
,x4
, x3
);
1043 *pY
= Bits2Number(2, y4
, y3
);
1044 *pX
= Bits2Number(3, x5
, x4
, x3
);
1047 case ADDR_PIPECFG_P16_32x32_16x16
:
1051 x3
= pipebit0
^ y3
^ x4
;
1052 if((pitchInMacroTile
% 4) == 0)
1058 *pY
= Bits2Number(2, y4
, y3
);
1059 *pX
= Bits2Number(4, x6
, x5
, x4
, x3
);
1065 *pY
= Bits2Number(2, y4
, y3
);
1066 *pX
= Bits2Number(3, x5
, x4
, x3
);
1070 ADDR_UNHANDLED_CASE();
1075 ****************************************************************************************************
1076 * SiLib::TileCoordToMaskElementIndex
1079 * Compute element index from coordinates in tiles
1082 ****************************************************************************************************
1084 UINT_32
SiLib::TileCoordToMaskElementIndex(
1085 UINT_32 tx
, ///< [in] x coord, in Tiles
1086 UINT_32 ty
, ///< [in] y coord, in Tiles
1087 AddrPipeCfg pipeConfig
, ///< [in] pipe config
1088 UINT_32
* macroShift
, ///< [out] macro shift
1089 UINT_32
* elemIdxBits
///< [out] tile offset bits
1092 UINT_32 elemIdx
= 0;
1093 UINT_32 elemIdx0
, elemIdx1
, elemIdx2
;
1104 case ADDR_PIPECFG_P2
:
1108 elemIdx1
= tx1
^ ty1
;
1109 elemIdx0
= tx1
^ ty0
;
1110 elemIdx
= Bits2Number(3,elemIdx2
,elemIdx1
,elemIdx0
);
1112 case ADDR_PIPECFG_P4_8x16
:
1116 elemIdx0
= tx1
^ ty1
;
1117 elemIdx
= Bits2Number(2,elemIdx1
,elemIdx0
);
1119 case ADDR_PIPECFG_P4_16x16
:
1124 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1126 case ADDR_PIPECFG_P4_16x32
:
1131 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1133 case ADDR_PIPECFG_P4_32x32
:
1139 elemIdx
= Bits2Number(3, elemIdx2
, elemIdx1
, elemIdx0
);
1141 case ADDR_PIPECFG_P8_16x16_8x16
:
1147 case ADDR_PIPECFG_P8_16x32_8x16
:
1153 case ADDR_PIPECFG_P8_32x32_8x16
:
1158 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1160 case ADDR_PIPECFG_P8_16x32_16x16
:
1166 case ADDR_PIPECFG_P8_32x32_16x16
:
1171 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1173 case ADDR_PIPECFG_P8_32x32_16x32
:
1178 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1180 case ADDR_PIPECFG_P8_32x64_32x32
:
1186 elemIdx
= Bits2Number(3, elemIdx2
, elemIdx1
, elemIdx0
);
1188 case ADDR_PIPECFG_P16_32x32_8x16
:
1193 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1195 case ADDR_PIPECFG_P16_32x32_16x16
:
1200 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1203 ADDR_UNHANDLED_CASE();
1211 ****************************************************************************************************
1212 * SiLib::HwlComputeTileDataWidthAndHeightLinear
1215 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1221 * MacroWidth and macroHeight are measured in pixels
1222 ****************************************************************************************************
1224 VOID
SiLib::HwlComputeTileDataWidthAndHeightLinear(
1225 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1226 UINT_32
* pMacroHeight
, ///< [out] macro tile height
1227 UINT_32 bpp
, ///< [in] bits per pixel
1228 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
1231 ADDR_ASSERT(pTileInfo
!= NULL
);
1233 UINT_32 macroHeight
;
1235 /// In linear mode, the htile or cmask buffer must be padded out to 4 tiles
1236 /// but for P8_32x64_32x32, it must be padded out to 8 tiles
1237 /// Actually there are more pipe configs which need 8-tile padding but SI family
1238 /// has a bug which is fixed in CI family
1239 if ((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
) ||
1240 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P16_32x32_8x16
) ||
1241 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x32_16x16
))
1243 macroWidth
= 8*MicroTileWidth
;
1244 macroHeight
= 8*MicroTileHeight
;
1248 macroWidth
= 4*MicroTileWidth
;
1249 macroHeight
= 4*MicroTileHeight
;
1252 *pMacroWidth
= macroWidth
;
1253 *pMacroHeight
= macroHeight
;
1257 ****************************************************************************************************
1258 * SiLib::HwlComputeHtileBytes
1261 * Compute htile size in bytes
1264 * Htile size in bytes
1265 ****************************************************************************************************
1267 UINT_64
SiLib::HwlComputeHtileBytes(
1268 UINT_32 pitch
, ///< [in] pitch
1269 UINT_32 height
, ///< [in] height
1270 UINT_32 bpp
, ///< [in] bits per pixel
1271 BOOL_32 isLinear
, ///< [in] if it is linear mode
1272 UINT_32 numSlices
, ///< [in] number of slices
1273 UINT_64
* pSliceBytes
, ///< [out] bytes per slice
1274 UINT_32 baseAlign
///< [in] base alignments
1277 return ComputeHtileBytes(pitch
, height
, bpp
, isLinear
, numSlices
, pSliceBytes
, baseAlign
);
1281 ****************************************************************************************************
1282 * SiLib::HwlComputeXmaskAddrFromCoord
1285 * Compute address from coordinates for htile/cmask
1288 ****************************************************************************************************
1290 UINT_64
SiLib::HwlComputeXmaskAddrFromCoord(
1291 UINT_32 pitch
, ///< [in] pitch
1292 UINT_32 height
, ///< [in] height
1293 UINT_32 x
, ///< [in] x coord
1294 UINT_32 y
, ///< [in] y coord
1295 UINT_32 slice
, ///< [in] slice/depth index
1296 UINT_32 numSlices
, ///< [in] number of slices
1297 UINT_32 factor
, ///< [in] factor that indicates cmask(2) or htile(1)
1298 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
1299 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
1300 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
1301 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1302 UINT_32
* pBitPosition
///< [out] bit position inside a byte
1305 UINT_32 tx
= x
/ MicroTileWidth
;
1306 UINT_32 ty
= y
/ MicroTileHeight
;
1311 UINT_32 macroHeight
;
1312 UINT_64 pSliceBytes
;
1314 UINT_32 tileNumPerPipe
;
1317 if (factor
== 2) //CMASK
1319 ADDR_CMASK_FLAGS flags
= {{0}};
1321 tileNumPerPipe
= 256;
1323 ComputeCmaskInfo(flags
,
1334 elemBits
= CmaskElemBits
;
1338 ADDR_HTILE_FLAGS flags
= {{0}};
1340 tileNumPerPipe
= 512;
1342 ComputeHtileInfo(flags
,
1360 const UINT_32 pitchInTile
= newPitch
/ MicroTileWidth
;
1361 const UINT_32 heightInTile
= newHeight
/ MicroTileWidth
;
1362 UINT_64 macroOffset
; // Per pipe starting offset of the macro tile in which this tile lies.
1363 UINT_64 microNumber
; // Per pipe starting offset of the macro tile in which this tile lies.
1366 UINT_64 microOffset
;
1368 UINT_64 totalOffset
;
1369 UINT_32 elemIdxBits
;
1371 TileCoordToMaskElementIndex(tx
, ty
, pTileInfo
->pipeConfig
, µShift
, &elemIdxBits
);
1373 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1376 { //linear addressing
1377 // Linear addressing is extremelly wasting memory if slice > 1, since each pipe has the full
1378 // slice memory foot print instead of divided by numPipes.
1379 microX
= tx
/ 4; // Macro Tile is 4x4
1381 microNumber
= static_cast<UINT_64
>(microX
+ microY
* (pitchInTile
/ 4)) << microShift
;
1383 UINT_32 sliceBits
= pitchInTile
* heightInTile
;
1385 // do htile single slice alignment if the flag is true
1386 if (m_configFlags
.useHtileSliceAlign
&& (factor
== 1)) //Htile
1388 sliceBits
= PowTwoAlign(sliceBits
, BITS_TO_BYTES(HtileCacheBits
) * numPipes
/ elemBits
);
1390 macroOffset
= slice
* (sliceBits
/ numPipes
) * elemBits
;
1393 { //tiled addressing
1394 const UINT_32 macroWidthInTile
= macroWidth
/ MicroTileWidth
; // Now in unit of Tiles
1395 const UINT_32 macroHeightInTile
= macroHeight
/ MicroTileHeight
;
1396 const UINT_32 pitchInCL
= pitchInTile
/ macroWidthInTile
;
1397 const UINT_32 heightInCL
= heightInTile
/ macroHeightInTile
;
1399 const UINT_32 macroX
= x
/ macroWidth
;
1400 const UINT_32 macroY
= y
/ macroHeight
;
1401 const UINT_32 macroNumber
= macroX
+ macroY
* pitchInCL
+ slice
* pitchInCL
* heightInCL
;
1403 // Per pipe starting offset of the cache line in which this tile lies.
1404 microX
= (x
% macroWidth
) / MicroTileWidth
/ 4; // Macro Tile is 4x4
1405 microY
= (y
% macroHeight
) / MicroTileHeight
/ 4 ;
1406 microNumber
= static_cast<UINT_64
>(microX
+ microY
* (macroWidth
/ MicroTileWidth
/ 4)) << microShift
;
1408 macroOffset
= macroNumber
* tileNumPerPipe
* elemBits
;
1411 if(elemIdxBits
== microShift
)
1413 microNumber
+= elemIdx
;
1417 microNumber
>>= elemIdxBits
;
1418 microNumber
<<= elemIdxBits
;
1419 microNumber
+= elemIdx
;
1422 microOffset
= elemBits
* microNumber
;
1423 totalOffset
= microOffset
+ macroOffset
;
1425 UINT_32 pipe
= ComputePipeFromCoord(x
, y
, 0, ADDR_TM_2D_TILED_THIN1
, 0, FALSE
, pTileInfo
);
1426 UINT_64 addrInBits
= totalOffset
% (m_pipeInterleaveBytes
* 8) +
1427 pipe
* (m_pipeInterleaveBytes
* 8) +
1428 totalOffset
/ (m_pipeInterleaveBytes
* 8) * (m_pipeInterleaveBytes
* 8) * numPipes
;
1429 *pBitPosition
= static_cast<UINT_32
>(addrInBits
) % 8;
1430 UINT_64 addr
= addrInBits
/ 8;
1436 ****************************************************************************************************
1437 * SiLib::HwlComputeXmaskCoordFromAddr
1440 * Compute the coord from an address of a cmask/htile
1446 * This method is reused by htile, so rename to Xmask
1447 ****************************************************************************************************
1449 VOID
SiLib::HwlComputeXmaskCoordFromAddr(
1450 UINT_64 addr
, ///< [in] address
1451 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
1452 UINT_32 pitch
, ///< [in] pitch
1453 UINT_32 height
, ///< [in] height
1454 UINT_32 numSlices
, ///< [in] number of slices
1455 UINT_32 factor
, ///< [in] factor that indicates cmask or htile
1456 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
1457 BOOL_32 isWidth8
, ///< [in] Not used by SI
1458 BOOL_32 isHeight8
, ///< [in] Not used by SI
1459 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1460 UINT_32
* pX
, ///< [out] x coord
1461 UINT_32
* pY
, ///< [out] y coord
1462 UINT_32
* pSlice
///< [out] slice index
1470 UINT_32 tileNumPerPipe
;
1477 if (factor
== 2) //CMASK
1479 ADDR_CMASK_FLAGS flags
= {{0}};
1481 tileNumPerPipe
= 256;
1483 ComputeCmaskInfo(flags
,
1497 ADDR_HTILE_FLAGS flags
= {{0}};
1499 tileNumPerPipe
= 512;
1501 ComputeHtileInfo(flags
,
1517 const UINT_32 pitchInTile
= newPitch
/ MicroTileWidth
;
1518 const UINT_32 heightInTile
= newHeight
/ MicroTileWidth
;
1519 const UINT_32 pitchInMacroTile
= pitchInTile
/ 4;
1521 UINT_32 elemIdxBits
;
1522 // get macroShift and elemIdxBits
1523 TileCoordToMaskElementIndex(0, 0, pTileInfo
->pipeConfig
, ¯oShift
, &elemIdxBits
);
1525 const UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1526 const UINT_32 pipe
= (UINT_32
)((addr
/ m_pipeInterleaveBytes
) % numPipes
);
1528 UINT_64 localOffset
= (addr
% m_pipeInterleaveBytes
) +
1529 (addr
/ m_pipeInterleaveBytes
/ numPipes
)* m_pipeInterleaveBytes
;
1532 if (factor
== 2) //CMASK
1534 tileIndex
= (UINT_32
)(localOffset
* 2 + (bitPosition
!= 0));
1538 tileIndex
= (UINT_32
)(localOffset
/ 4);
1541 UINT_32 macroOffset
;
1544 UINT_32 sliceSizeInTile
= pitchInTile
* heightInTile
;
1546 // do htile single slice alignment if the flag is true
1547 if (m_configFlags
.useHtileSliceAlign
&& (factor
== 1)) //Htile
1549 sliceSizeInTile
= PowTwoAlign(sliceSizeInTile
, static_cast<UINT_32
>(sliceBytes
) / 64);
1551 *pSlice
= tileIndex
/ (sliceSizeInTile
/ numPipes
);
1552 macroOffset
= tileIndex
% (sliceSizeInTile
/ numPipes
);
1556 const UINT_32 clWidthInTile
= clWidth
/ MicroTileWidth
; // Now in unit of Tiles
1557 const UINT_32 clHeightInTile
= clHeight
/ MicroTileHeight
;
1558 const UINT_32 pitchInCL
= pitchInTile
/ clWidthInTile
;
1559 const UINT_32 heightInCL
= heightInTile
/ clHeightInTile
;
1560 const UINT_32 clIndex
= tileIndex
/ tileNumPerPipe
;
1562 UINT_32 clX
= clIndex
% pitchInCL
;
1563 UINT_32 clY
= (clIndex
% (heightInCL
* pitchInCL
)) / pitchInCL
;
1565 *pX
= clX
* clWidthInTile
* MicroTileWidth
;
1566 *pY
= clY
* clHeightInTile
* MicroTileHeight
;
1567 *pSlice
= clIndex
/ (heightInCL
* pitchInCL
);
1569 macroOffset
= tileIndex
% tileNumPerPipe
;
1572 UINT_32 elemIdx
= macroOffset
& 7;
1573 macroOffset
>>= elemIdxBits
;
1575 if (elemIdxBits
!= macroShift
)
1577 macroOffset
<<= (elemIdxBits
- macroShift
);
1579 UINT_32 pipebit1
= _BIT(pipe
,1);
1580 UINT_32 pipebit2
= _BIT(pipe
,2);
1581 UINT_32 pipebit3
= _BIT(pipe
,3);
1582 if (pitchInMacroTile
% 2)
1584 switch (pTileInfo
->pipeConfig
)
1586 case ADDR_PIPECFG_P4_32x32
:
1587 macroOffset
|= pipebit1
;
1589 case ADDR_PIPECFG_P8_32x32_8x16
:
1590 case ADDR_PIPECFG_P8_32x32_16x16
:
1591 case ADDR_PIPECFG_P8_32x32_16x32
:
1592 macroOffset
|= pipebit2
;
1600 if (pitchInMacroTile
% 4)
1602 if (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
)
1604 macroOffset
|= (pipebit1
<<1);
1606 if((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P16_32x32_8x16
) ||
1607 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P16_32x32_16x16
))
1609 macroOffset
|= (pipebit3
<<1);
1619 macroX
= macroOffset
% pitchInMacroTile
;
1620 macroY
= macroOffset
/ pitchInMacroTile
;
1624 const UINT_32 clWidthInMacroTile
= clWidth
/ (MicroTileWidth
* 4);
1625 macroX
= macroOffset
% clWidthInMacroTile
;
1626 macroY
= macroOffset
/ clWidthInMacroTile
;
1629 *pX
+= macroX
* 4 * MicroTileWidth
;
1630 *pY
+= macroY
* 4 * MicroTileHeight
;
1634 ComputeTileCoordFromPipeAndElemIdx(elemIdx
, pipe
, pTileInfo
->pipeConfig
, pitchInMacroTile
,
1635 *pX
, *pY
, µX
, µY
);
1637 *pX
+= microX
* MicroTileWidth
;
1638 *pY
+= microY
* MicroTileWidth
;
1642 ****************************************************************************************************
1643 * SiLib::HwlGetPitchAlignmentLinear
1645 * Get pitch alignment
1648 ****************************************************************************************************
1650 UINT_32
SiLib::HwlGetPitchAlignmentLinear(
1651 UINT_32 bpp
, ///< [in] bits per pixel
1652 ADDR_SURFACE_FLAGS flags
///< [in] surface flags
1657 // Interleaved access requires a 256B aligned pitch, so fall back to pre-SI alignment
1658 if (flags
.interleaved
)
1660 pitchAlign
= Max(64u, m_pipeInterleaveBytes
/ BITS_TO_BYTES(bpp
));
1665 pitchAlign
= Max(8u, 64 / BITS_TO_BYTES(bpp
));
1672 ****************************************************************************************************
1673 * SiLib::HwlGetSizeAdjustmentLinear
1676 * Adjust linear surface pitch and slice size
1679 * Logical slice size in bytes
1680 ****************************************************************************************************
1682 UINT_64
SiLib::HwlGetSizeAdjustmentLinear(
1683 AddrTileMode tileMode
, ///< [in] tile mode
1684 UINT_32 bpp
, ///< [in] bits per pixel
1685 UINT_32 numSamples
, ///< [in] number of samples
1686 UINT_32 baseAlign
, ///< [in] base alignment
1687 UINT_32 pitchAlign
, ///< [in] pitch alignment
1688 UINT_32
* pPitch
, ///< [in,out] pointer to pitch
1689 UINT_32
* pHeight
, ///< [in,out] pointer to height
1690 UINT_32
* pHeightAlign
///< [in,out] pointer to height align
1694 if (tileMode
== ADDR_TM_LINEAR_GENERAL
)
1696 sliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(*pPitch
) * (*pHeight
) * bpp
* numSamples
);
1700 UINT_32 pitch
= *pPitch
;
1701 UINT_32 height
= *pHeight
;
1703 UINT_32 pixelsPerPipeInterleave
= m_pipeInterleaveBytes
/ BITS_TO_BYTES(bpp
);
1704 UINT_32 sliceAlignInPixel
= pixelsPerPipeInterleave
< 64 ? 64 : pixelsPerPipeInterleave
;
1706 // numSamples should be 1 in real cases (no MSAA for linear but TGL may pass non 1 value)
1707 UINT_64 pixelPerSlice
= static_cast<UINT_64
>(pitch
) * height
* numSamples
;
1709 while (pixelPerSlice
% sliceAlignInPixel
)
1711 pitch
+= pitchAlign
;
1712 pixelPerSlice
= static_cast<UINT_64
>(pitch
) * height
* numSamples
;
1717 UINT_32 heightAlign
= 1;
1719 while ((pitch
* heightAlign
) % sliceAlignInPixel
)
1724 *pHeightAlign
= heightAlign
;
1726 sliceSize
= BITS_TO_BYTES(pixelPerSlice
* bpp
);
1733 ****************************************************************************************************
1734 * SiLib::HwlPreHandleBaseLvl3xPitch
1737 * Pre-handler of 3x pitch (96 bit) adjustment
1741 ****************************************************************************************************
1743 UINT_32
SiLib::HwlPreHandleBaseLvl3xPitch(
1744 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
1745 UINT_32 expPitch
///< [in] pitch
1748 ADDR_ASSERT(pIn
->width
== expPitch
);
1750 // From SI, if pow2Pad is 1 the pitch is expanded 3x first, then padded to pow2, so nothing to
1752 if (pIn
->flags
.pow2Pad
== FALSE
)
1754 Addr::V1::Lib::HwlPreHandleBaseLvl3xPitch(pIn
, expPitch
);
1758 ADDR_ASSERT(IsPow2(expPitch
));
1765 ****************************************************************************************************
1766 * SiLib::HwlPostHandleBaseLvl3xPitch
1769 * Post-handler of 3x pitch adjustment
1773 ****************************************************************************************************
1775 UINT_32
SiLib::HwlPostHandleBaseLvl3xPitch(
1776 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
1777 UINT_32 expPitch
///< [in] pitch
1781 * @note The pitch will be divided by 3 in the end so the value will look odd but h/w should
1782 * be able to compute a correct pitch from it as h/w address library is doing the job.
1784 // From SI, the pitch is expanded 3x first, then padded to pow2, so no special handler here
1785 if (pIn
->flags
.pow2Pad
== FALSE
)
1787 Addr::V1::Lib::HwlPostHandleBaseLvl3xPitch(pIn
, expPitch
);
1794 ****************************************************************************************************
1795 * SiLib::HwlGetPitchAlignmentMicroTiled
1798 * Compute 1D tiled surface pitch alignment
1802 ****************************************************************************************************
1804 UINT_32
SiLib::HwlGetPitchAlignmentMicroTiled(
1805 AddrTileMode tileMode
, ///< [in] tile mode
1806 UINT_32 bpp
, ///< [in] bits per pixel
1807 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
1808 UINT_32 numSamples
///< [in] number of samples
1815 pitchAlign
= EgBasedLib::HwlGetPitchAlignmentMicroTiled(tileMode
,bpp
,flags
,numSamples
);
1826 ****************************************************************************************************
1827 * SiLib::HwlGetSizeAdjustmentMicroTiled
1830 * Adjust 1D tiled surface pitch and slice size
1833 * Logical slice size in bytes
1834 ****************************************************************************************************
1836 UINT_64
SiLib::HwlGetSizeAdjustmentMicroTiled(
1837 UINT_32 thickness
, ///< [in] thickness
1838 UINT_32 bpp
, ///< [in] bits per pixel
1839 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
1840 UINT_32 numSamples
, ///< [in] number of samples
1841 UINT_32 baseAlign
, ///< [in] base alignment
1842 UINT_32 pitchAlign
, ///< [in] pitch alignment
1843 UINT_32
* pPitch
, ///< [in,out] pointer to pitch
1844 UINT_32
* pHeight
///< [in,out] pointer to height
1847 UINT_64 logicalSliceSize
;
1848 UINT_64 physicalSliceSize
;
1850 UINT_32 pitch
= *pPitch
;
1851 UINT_32 height
= *pHeight
;
1853 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
1854 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
1856 // Physical slice: multiplied by thickness
1857 physicalSliceSize
= logicalSliceSize
* thickness
;
1859 // Pitch alignment is always 8, so if slice size is not padded to base alignment
1860 // (pipe_interleave_size), we need to increase pitch
1861 while ((physicalSliceSize
% baseAlign
) != 0)
1863 pitch
+= pitchAlign
;
1865 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
1867 physicalSliceSize
= logicalSliceSize
* thickness
;
1872 // Special workaround for depth/stencil buffer, use 8 bpp to align depth buffer again since
1873 // the stencil plane may have larger pitch if the slice size is smaller than base alignment.
1875 // Note: this actually does not work for mipmap but mipmap depth texture is not really
1876 // sampled with mipmap.
1878 if (flags
.depth
&& (flags
.noStencil
== FALSE
))
1880 ADDR_ASSERT(numSamples
== 1);
1882 UINT_64 logicalSiceSizeStencil
= static_cast<UINT_64
>(pitch
) * height
; // 1 byte stencil
1884 while ((logicalSiceSizeStencil
% baseAlign
) != 0)
1886 pitch
+= pitchAlign
; // Stencil plane's pitch alignment is the same as depth plane's
1888 logicalSiceSizeStencil
= static_cast<UINT_64
>(pitch
) * height
;
1891 if (pitch
!= *pPitch
)
1893 // If this is a mipmap, this padded one cannot be sampled as a whole mipmap!
1894 logicalSliceSize
= logicalSiceSizeStencil
* BITS_TO_BYTES(bpp
);
1900 // No adjust for pHeight
1902 return logicalSliceSize
;
1906 ****************************************************************************************************
1907 * SiLib::HwlConvertChipFamily
1910 * Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
1913 ****************************************************************************************************
1915 ChipFamily
SiLib::HwlConvertChipFamily(
1916 UINT_32 uChipFamily
, ///< [in] chip family defined in atiih.h
1917 UINT_32 uChipRevision
) ///< [in] chip revision defined in "asic_family"_id.h
1919 ChipFamily family
= ADDR_CHIP_FAMILY_SI
;
1921 switch (uChipFamily
)
1924 m_settings
.isSouthernIsland
= 1;
1925 m_settings
.isTahiti
= ASICREV_IS_TAHITI_P(uChipRevision
);
1926 m_settings
.isPitCairn
= ASICREV_IS_PITCAIRN_PM(uChipRevision
);
1927 m_settings
.isCapeVerde
= ASICREV_IS_CAPEVERDE_M(uChipRevision
);
1928 m_settings
.isOland
= ASICREV_IS_OLAND_M(uChipRevision
);
1929 m_settings
.isHainan
= ASICREV_IS_HAINAN_V(uChipRevision
);
1932 ADDR_ASSERT(!"This should be a Fusion");
1940 ****************************************************************************************************
1941 * SiLib::HwlSetupTileInfo
1944 * Setup default value of tile info for SI
1945 ****************************************************************************************************
1947 VOID
SiLib::HwlSetupTileInfo(
1948 AddrTileMode tileMode
, ///< [in] Tile mode
1949 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface type flags
1950 UINT_32 bpp
, ///< [in] Bits per pixel
1951 UINT_32 pitch
, ///< [in] Pitch in pixels
1952 UINT_32 height
, ///< [in] Height in pixels
1953 UINT_32 numSamples
, ///< [in] Number of samples
1954 ADDR_TILEINFO
* pTileInfoIn
, ///< [in] Tile info input: NULL for default
1955 ADDR_TILEINFO
* pTileInfoOut
, ///< [out] Tile info output
1956 AddrTileType inTileType
, ///< [in] Tile type
1957 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] Output
1960 UINT_32 thickness
= Thickness(tileMode
);
1961 ADDR_TILEINFO
* pTileInfo
= pTileInfoOut
;
1962 INT index
= TileIndexInvalid
;
1965 if (IsLinear(tileMode
) == FALSE
)
1967 // 128 bpp/thick tiling must be non-displayable.
1968 // Fmask reuse color buffer's entry but bank-height field can be from another entry
1969 // To simplify the logic, fmask entry should be picked from non-displayable ones
1970 if (bpp
== 128 || thickness
> 1 || flags
.fmask
|| flags
.prt
)
1972 inTileType
= ADDR_NON_DISPLAYABLE
;
1975 if (flags
.depth
|| flags
.stencil
)
1977 inTileType
= ADDR_DEPTH_SAMPLE_ORDER
;
1981 // Partial valid fields are not allowed for SI.
1982 if (IsTileInfoAllZero(pTileInfo
))
1984 if (IsMacroTiled(tileMode
))
1988 if (numSamples
== 1)
2001 ADDR_ASSERT_ALWAYS();
2030 ADDR_ASSERT(bpp
!= 128);
2037 ADDR_ASSERT(numSamples
== 4);
2050 ADDR_ASSERT_ALWAYS();
2071 ADDR_ASSERT_ALWAYS();
2077 // See table entries 0-7
2078 else if (flags
.depth
|| flags
.stencil
)
2080 if (flags
.compressZ
)
2088 // optimal tile index for compressed depth/stencil.
2111 else //non PRT & non Depth & non Stencil
2113 // See table entries 9-12
2114 if (inTileType
== ADDR_DISPLAYABLE
)
2136 // See table entries 13-17
2141 UINT_32 fmaskPixelSize
= bpp
* numSamples
;
2143 switch (fmaskPixelSize
)
2158 ADDR_ASSERT_ALWAYS();
2185 else // thick tiling - entries 18-20
2204 if (tileMode
== ADDR_TM_LINEAR_ALIGNED
)
2208 else if (tileMode
== ADDR_TM_LINEAR_GENERAL
)
2210 index
= TileIndexLinearGeneral
;
2214 if (flags
.depth
|| flags
.stencil
)
2218 else if (inTileType
== ADDR_DISPLAYABLE
)
2222 else if (thickness
== 1)
2233 if (index
>= 0 && index
<= 31)
2235 *pTileInfo
= m_tileTable
[index
].info
;
2236 pOut
->tileType
= m_tileTable
[index
].type
;
2239 if (index
== TileIndexLinearGeneral
)
2241 *pTileInfo
= m_tileTable
[8].info
;
2242 pOut
->tileType
= m_tileTable
[8].type
;
2249 if (flags
.stencil
&& pTileInfoIn
->tileSplitBytes
== 0)
2251 // Stencil always uses index 0
2252 *pTileInfo
= m_tileTable
[0].info
;
2255 // Pass through tile type
2256 pOut
->tileType
= inTileType
;
2259 pOut
->tileIndex
= index
;
2260 pOut
->prtTileIndex
= flags
.prt
;
2264 ****************************************************************************************************
2265 * SiLib::DecodeGbRegs
2268 * Decodes GB_ADDR_CONFIG and noOfBanks/noOfRanks
2271 * TRUE if all settings are valid
2273 ****************************************************************************************************
2275 BOOL_32
SiLib::DecodeGbRegs(
2276 const ADDR_REGISTER_VALUE
* pRegValue
) ///< [in] create input
2279 BOOL_32 valid
= TRUE
;
2281 reg
.val
= pRegValue
->gbAddrConfig
;
2283 switch (reg
.f
.pipe_interleave_size
)
2285 case ADDR_CONFIG_PIPE_INTERLEAVE_256B
:
2286 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_256B
;
2288 case ADDR_CONFIG_PIPE_INTERLEAVE_512B
:
2289 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_512B
;
2293 ADDR_UNHANDLED_CASE();
2297 switch (reg
.f
.row_size
)
2299 case ADDR_CONFIG_1KB_ROW
:
2300 m_rowSize
= ADDR_ROWSIZE_1KB
;
2302 case ADDR_CONFIG_2KB_ROW
:
2303 m_rowSize
= ADDR_ROWSIZE_2KB
;
2305 case ADDR_CONFIG_4KB_ROW
:
2306 m_rowSize
= ADDR_ROWSIZE_4KB
;
2310 ADDR_UNHANDLED_CASE();
2314 switch (pRegValue
->noOfBanks
)
2327 ADDR_UNHANDLED_CASE();
2331 switch (pRegValue
->noOfRanks
)
2341 ADDR_UNHANDLED_CASE();
2345 m_logicalBanks
= m_banks
* m_ranks
;
2347 ADDR_ASSERT(m_logicalBanks
<= 16);
2353 ****************************************************************************************************
2354 * SiLib::HwlInitGlobalParams
2357 * Initializes global parameters
2360 * TRUE if all settings are valid
2362 ****************************************************************************************************
2364 BOOL_32
SiLib::HwlInitGlobalParams(
2365 const ADDR_CREATE_INPUT
* pCreateIn
) ///< [in] create input
2367 BOOL_32 valid
= TRUE
;
2368 const ADDR_REGISTER_VALUE
* pRegValue
= &pCreateIn
->regValue
;
2370 valid
= DecodeGbRegs(pRegValue
);
2374 if (m_settings
.isTahiti
|| m_settings
.isPitCairn
)
2378 else if (m_settings
.isCapeVerde
|| m_settings
.isOland
)
2384 // Hainan is 2-pipe (m_settings.isHainan == 1)
2388 valid
= InitTileSettingTable(pRegValue
->pTileConfig
, pRegValue
->noOfEntries
);
2392 InitEquationTable();
2402 ****************************************************************************************************
2403 * SiLib::HwlConvertTileInfoToHW
2405 * Entry of si's ConvertTileInfoToHW
2408 ****************************************************************************************************
2410 ADDR_E_RETURNCODE
SiLib::HwlConvertTileInfoToHW(
2411 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
2412 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
2415 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
2417 retCode
= EgBasedLib::HwlConvertTileInfoToHW(pIn
, pOut
);
2419 if (retCode
== ADDR_OK
)
2421 if (pIn
->reverse
== FALSE
)
2423 if (pIn
->pTileInfo
->pipeConfig
== ADDR_PIPECFG_INVALID
)
2425 retCode
= ADDR_INVALIDPARAMS
;
2429 pOut
->pTileInfo
->pipeConfig
=
2430 static_cast<AddrPipeCfg
>(pIn
->pTileInfo
->pipeConfig
- 1);
2435 pOut
->pTileInfo
->pipeConfig
=
2436 static_cast<AddrPipeCfg
>(pIn
->pTileInfo
->pipeConfig
+ 1);
2444 ****************************************************************************************************
2445 * SiLib::HwlComputeXmaskCoordYFrom8Pipe
2448 * Compute the Y coord which will be added to Xmask Y
2452 ****************************************************************************************************
2454 UINT_32
SiLib::HwlComputeXmaskCoordYFrom8Pipe(
2455 UINT_32 pipe
, ///< [in] pipe id
2456 UINT_32 x
///< [in] tile coord x, which is original x coord / 8
2459 // This function should never be called since it is 6xx/8xx specfic.
2460 // Keep this empty implementation to avoid any mis-use.
2461 ADDR_ASSERT_ALWAYS();
2467 ****************************************************************************************************
2468 * SiLib::HwlComputeSurfaceCoord2DFromBankPipe
2471 * Compute surface x,y coordinates from bank/pipe info
2474 ****************************************************************************************************
2476 VOID
SiLib::HwlComputeSurfaceCoord2DFromBankPipe(
2477 AddrTileMode tileMode
, ///< [in] tile mode
2478 UINT_32
* pX
, ///< [in,out] x coordinate
2479 UINT_32
* pY
, ///< [in,out] y coordinate
2480 UINT_32 slice
, ///< [in] slice index
2481 UINT_32 bank
, ///< [in] bank number
2482 UINT_32 pipe
, ///< [in] pipe number
2483 UINT_32 bankSwizzle
,///< [in] bank swizzle
2484 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
2485 UINT_32 tileSlices
, ///< [in] slices in a micro tile
2486 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines are ignored
2487 ADDR_TILEINFO
* pTileInfo
///< [in] bank structure. **All fields to be valid on entry**
2501 UINT_32 numPipes
= GetPipePerSurf(pTileInfo
->pipeConfig
);
2503 CoordFromBankPipe xyBits
= {0};
2504 ComputeSurfaceCoord2DFromBankPipe(tileMode
, *pX
, *pY
, slice
, bank
, pipe
,
2505 bankSwizzle
, pipeSwizzle
, tileSlices
, pTileInfo
,
2507 yBit3
= xyBits
.yBit3
;
2508 yBit4
= xyBits
.yBit4
;
2509 yBit5
= xyBits
.yBit5
;
2510 yBit6
= xyBits
.yBit6
;
2512 xBit3
= xyBits
.xBit3
;
2513 xBit4
= xyBits
.xBit4
;
2514 xBit5
= xyBits
.xBit5
;
2516 yBit
= xyBits
.yBits
;
2518 UINT_32 yBitTemp
= 0;
2520 if ((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P4_32x32
) ||
2521 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
))
2523 ADDR_ASSERT(pTileInfo
->bankWidth
== 1 && pTileInfo
->macroAspectRatio
> 1);
2524 UINT_32 yBitToCheck
= QLog2(pTileInfo
->banks
) - 1;
2526 ADDR_ASSERT(yBitToCheck
<= 3);
2528 yBitTemp
= _BIT(yBit
, yBitToCheck
);
2533 yBit
= Bits2Number(4, yBit6
, yBit5
, yBit4
, yBit3
);
2534 xBit
= Bits2Number(3, xBit5
, xBit4
, xBit3
);
2536 *pY
+= yBit
* pTileInfo
->bankHeight
* MicroTileHeight
;
2537 *pX
+= xBit
* numPipes
* pTileInfo
->bankWidth
* MicroTileWidth
;
2539 //calculate the bank and pipe bits in x, y
2540 UINT_32 xTile
; //x in micro tile
2547 UINT_32 pipeBit0
= _BIT(pipe
,0);
2548 UINT_32 pipeBit1
= _BIT(pipe
,1);
2549 UINT_32 pipeBit2
= _BIT(pipe
,2);
2551 UINT_32 y3
= _BIT(y
, 3);
2552 UINT_32 y4
= _BIT(y
, 4);
2553 UINT_32 y5
= _BIT(y
, 5);
2554 UINT_32 y6
= _BIT(y
, 6);
2556 // bankbit0 after ^x4^x5
2557 UINT_32 bankBit00
= _BIT(bank
,0);
2558 UINT_32 bankBit0
= 0;
2560 switch (pTileInfo
->pipeConfig
)
2562 case ADDR_PIPECFG_P2
:
2565 case ADDR_PIPECFG_P4_8x16
:
2569 case ADDR_PIPECFG_P4_16x16
:
2571 x3
= pipeBit0
^ y3
^ x4
;
2573 case ADDR_PIPECFG_P4_16x32
:
2575 x3
= pipeBit0
^ y3
^ x4
;
2577 case ADDR_PIPECFG_P4_32x32
:
2579 x3
= pipeBit0
^ y3
^ x5
;
2580 bankBit0
= yBitTemp
^ x5
;
2581 x4
= bankBit00
^ x5
^ bankBit0
;
2582 *pX
+= x5
* 4 * 1 * 8; // x5 * num_pipes * bank_width * 8;
2584 case ADDR_PIPECFG_P8_16x16_8x16
:
2587 x5
= pipeBit0
^ y3
^ x4
;
2589 case ADDR_PIPECFG_P8_16x32_8x16
:
2592 x5
= pipeBit0
^ y3
^ x4
;
2594 case ADDR_PIPECFG_P8_32x32_8x16
:
2597 x4
= pipeBit0
^ y3
^ x5
;
2599 case ADDR_PIPECFG_P8_16x32_16x16
:
2602 x3
= pipeBit0
^ y3
^ x4
;
2604 case ADDR_PIPECFG_P8_32x32_16x16
:
2607 x3
= pipeBit0
^ y3
^ x4
;
2609 case ADDR_PIPECFG_P8_32x32_16x32
:
2612 x3
= pipeBit0
^ y3
^ x4
;
2614 case ADDR_PIPECFG_P8_32x64_32x32
:
2617 x3
= pipeBit0
^ y3
^ x5
;
2618 bankBit0
= yBitTemp
^ x6
;
2619 x4
= bankBit00
^ x5
^ bankBit0
;
2620 *pX
+= x6
* 8 * 1 * 8; // x6 * num_pipes * bank_width * 8;
2623 ADDR_ASSERT_ALWAYS();
2626 xTile
= Bits2Number(3, x5
, x4
, x3
);
2632 ****************************************************************************************************
2633 * SiLib::HwlPreAdjustBank
2636 * Adjust bank before calculating address acoording to bank/pipe
2639 ****************************************************************************************************
2641 UINT_32
SiLib::HwlPreAdjustBank(
2642 UINT_32 tileX
, ///< [in] x coordinate in unit of tile
2643 UINT_32 bank
, ///< [in] bank
2644 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2647 if (((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P4_32x32
) ||
2648 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
)) && (pTileInfo
->bankWidth
== 1))
2650 UINT_32 bankBit0
= _BIT(bank
, 0);
2651 UINT_32 x4
= _BIT(tileX
, 1);
2652 UINT_32 x5
= _BIT(tileX
, 2);
2654 bankBit0
= bankBit0
^ x4
^ x5
;
2657 ADDR_ASSERT(pTileInfo
->macroAspectRatio
> 1);
2664 ****************************************************************************************************
2665 * SiLib::HwlComputeSurfaceInfo
2668 * Entry of si's ComputeSurfaceInfo
2671 ****************************************************************************************************
2673 ADDR_E_RETURNCODE
SiLib::HwlComputeSurfaceInfo(
2674 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
2675 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
2678 pOut
->tileIndex
= pIn
->tileIndex
;
2680 ADDR_E_RETURNCODE retCode
= EgBasedLib::HwlComputeSurfaceInfo(pIn
, pOut
);
2682 UINT_32 tileIndex
= static_cast<UINT_32
>(pOut
->tileIndex
);
2684 if (((pIn
->flags
.needEquation
== TRUE
) ||
2685 (pIn
->flags
.preferEquation
== TRUE
)) &&
2686 (pIn
->numSamples
<= 1) &&
2687 (tileIndex
< TileTableSize
))
2689 static const UINT_32 SiUncompressDepthTileIndex
= 3;
2691 if ((pIn
->numSlices
> 1) &&
2692 (IsMacroTiled(pOut
->tileMode
) == TRUE
) &&
2693 ((m_chipFamily
== ADDR_CHIP_FAMILY_SI
) ||
2694 (IsPrtTileMode(pOut
->tileMode
) == FALSE
)))
2696 pOut
->equationIndex
= ADDR_INVALID_EQUATION_INDEX
;
2698 else if ((pIn
->flags
.prt
== FALSE
) &&
2699 (m_uncompressDepthEqIndex
!= 0) &&
2700 (tileIndex
== SiUncompressDepthTileIndex
))
2702 pOut
->equationIndex
= m_uncompressDepthEqIndex
+ Log2(pIn
->bpp
>> 3);
2707 pOut
->equationIndex
= m_equationLookupTable
[Log2(pIn
->bpp
>> 3)][tileIndex
];
2710 if (pOut
->equationIndex
!= ADDR_INVALID_EQUATION_INDEX
)
2712 pOut
->blockWidth
= m_blockWidth
[pOut
->equationIndex
];
2714 pOut
->blockHeight
= m_blockHeight
[pOut
->equationIndex
];
2716 pOut
->blockSlices
= m_blockSlices
[pOut
->equationIndex
];
2721 pOut
->equationIndex
= ADDR_INVALID_EQUATION_INDEX
;
2728 ****************************************************************************************************
2729 * SiLib::HwlComputeMipLevel
2731 * Compute MipLevel info (including level 0)
2733 * TRUE if HWL's handled
2734 ****************************************************************************************************
2736 BOOL_32
SiLib::HwlComputeMipLevel(
2737 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
///< [in,out] Input structure
2740 // basePitch is calculated from level 0 so we only check this for mipLevel > 0
2741 if (pIn
->mipLevel
> 0)
2743 // Note: Don't check expand 3x formats(96 bit) as the basePitch is not pow2 even if
2744 // we explicity set pow2Pad flag. The 3x base pitch is padded to pow2 but after being
2745 // divided by expandX factor (3) - to program texture pitch, the basePitch is never pow2.
2746 if (ElemLib::IsExpand3x(pIn
->format
) == FALSE
)
2748 // Sublevel pitches are generated from base level pitch instead of width on SI
2749 // If pow2Pad is 0, we don't assert - as this is not really used for a mip chain
2750 ADDR_ASSERT((pIn
->flags
.pow2Pad
== FALSE
) ||
2751 ((pIn
->basePitch
!= 0) && IsPow2(pIn
->basePitch
)));
2754 if (pIn
->basePitch
!= 0)
2756 pIn
->width
= Max(1u, pIn
->basePitch
>> pIn
->mipLevel
);
2760 // pow2Pad is done in PostComputeMipLevel
2766 ****************************************************************************************************
2767 * SiLib::HwlCheckLastMacroTiledLvl
2770 * Sets pOut->last2DLevel to TRUE if it is
2773 ****************************************************************************************************
2775 VOID
SiLib::HwlCheckLastMacroTiledLvl(
2776 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
2777 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in,out] Output structure (used as input, too)
2780 // pow2Pad covers all mipmap cases
2781 if (pIn
->flags
.pow2Pad
)
2783 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
2789 AddrTileMode nextTileMode
;
2791 if (pIn
->mipLevel
== 0 || pIn
->basePitch
== 0)
2793 // Base level or fail-safe case (basePitch == 0)
2794 nextPitch
= pOut
->pitch
>> 1;
2799 nextPitch
= pIn
->basePitch
>> (pIn
->mipLevel
+ 1);
2802 // nextHeight must be shifted from this level's original height rather than a pow2 padded
2803 // one but this requires original height stored somewhere (pOut->height)
2804 ADDR_ASSERT(pOut
->height
!= 0);
2806 // next level's height is just current level's >> 1 in pixels
2807 nextHeight
= pOut
->height
>> 1;
2808 // Special format such as FMT_1 and FMT_32_32_32 can be linear only so we consider block
2809 // compressed foramts
2810 if (ElemLib::IsBlockCompressed(pIn
->format
))
2812 nextHeight
= (nextHeight
+ 3) / 4;
2814 nextHeight
= NextPow2(nextHeight
);
2816 // nextSlices may be 0 if this level's is 1
2817 if (pIn
->flags
.volume
)
2819 nextSlices
= Max(1u, pIn
->numSlices
>> 1);
2823 nextSlices
= pIn
->numSlices
;
2826 nextTileMode
= ComputeSurfaceMipLevelTileMode(pIn
->tileMode
,
2836 pOut
->last2DLevel
= IsMicroTiled(nextTileMode
);
2841 ****************************************************************************************************
2842 * SiLib::HwlDegradeThickTileMode
2845 * Degrades valid tile mode for thick modes if needed
2848 * Suitable tile mode
2849 ****************************************************************************************************
2851 AddrTileMode
SiLib::HwlDegradeThickTileMode(
2852 AddrTileMode baseTileMode
, ///< base tile mode
2853 UINT_32 numSlices
, ///< current number of slices
2854 UINT_32
* pBytesPerTile
///< [in,out] pointer to bytes per slice
2857 return EgBasedLib::HwlDegradeThickTileMode(baseTileMode
, numSlices
, pBytesPerTile
);
2861 ****************************************************************************************************
2862 * SiLib::HwlTileInfoEqual
2865 * Return TRUE if all field are equal
2867 * Only takes care of current HWL's data
2868 ****************************************************************************************************
2870 BOOL_32
SiLib::HwlTileInfoEqual(
2871 const ADDR_TILEINFO
* pLeft
, ///<[in] Left compare operand
2872 const ADDR_TILEINFO
* pRight
///<[in] Right compare operand
2875 BOOL_32 equal
= FALSE
;
2877 if (pLeft
->pipeConfig
== pRight
->pipeConfig
)
2879 equal
= EgBasedLib::HwlTileInfoEqual(pLeft
, pRight
);
2886 ****************************************************************************************************
2887 * SiLib::GetTileSettings
2890 * Get tile setting infos by index.
2892 * Tile setting info.
2893 ****************************************************************************************************
2895 const TileConfig
* SiLib::GetTileSetting(
2896 UINT_32 index
///< [in] Tile index
2899 ADDR_ASSERT(index
< m_noOfEntries
);
2900 return &m_tileTable
[index
];
2904 ****************************************************************************************************
2905 * SiLib::HwlPostCheckTileIndex
2908 * Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches
2909 * tile mode/type/info and change the index if needed
2912 ****************************************************************************************************
2914 INT_32
SiLib::HwlPostCheckTileIndex(
2915 const ADDR_TILEINFO
* pInfo
, ///< [in] Tile Info
2916 AddrTileMode mode
, ///< [in] Tile mode
2917 AddrTileType type
, ///< [in] Tile type
2918 INT curIndex
///< [in] Current index assigned in HwlSetupTileInfo
2921 INT_32 index
= curIndex
;
2923 if (mode
== ADDR_TM_LINEAR_GENERAL
)
2925 index
= TileIndexLinearGeneral
;
2929 BOOL_32 macroTiled
= IsMacroTiled(mode
);
2931 // We need to find a new index if either of them is true
2932 // 1. curIndex is invalid
2933 // 2. tile mode is changed
2934 // 3. tile info does not match for macro tiled
2935 if ((index
== TileIndexInvalid
||
2936 (mode
!= m_tileTable
[index
].mode
) ||
2937 (macroTiled
&& (HwlTileInfoEqual(pInfo
, &m_tileTable
[index
].info
) == FALSE
))))
2939 for (index
= 0; index
< static_cast<INT_32
>(m_noOfEntries
); index
++)
2943 // macro tile modes need all to match
2944 if (HwlTileInfoEqual(pInfo
, &m_tileTable
[index
].info
) &&
2945 (mode
== m_tileTable
[index
].mode
) &&
2946 (type
== m_tileTable
[index
].type
))
2951 else if (mode
== ADDR_TM_LINEAR_ALIGNED
)
2953 // linear mode only needs tile mode to match
2954 if (mode
== m_tileTable
[index
].mode
)
2961 // micro tile modes only need tile mode and tile type to match
2962 if (mode
== m_tileTable
[index
].mode
&&
2963 type
== m_tileTable
[index
].type
)
2972 ADDR_ASSERT(index
< static_cast<INT_32
>(m_noOfEntries
));
2974 if (index
>= static_cast<INT_32
>(m_noOfEntries
))
2976 index
= TileIndexInvalid
;
2983 ****************************************************************************************************
2984 * SiLib::HwlSetupTileCfg
2987 * Map tile index to tile setting.
2990 ****************************************************************************************************
2992 ADDR_E_RETURNCODE
SiLib::HwlSetupTileCfg(
2993 UINT_32 bpp
, ///< Bits per pixel
2994 INT_32 index
, ///< Tile index
2995 INT_32 macroModeIndex
, ///< Index in macro tile mode table(CI)
2996 ADDR_TILEINFO
* pInfo
, ///< [out] Tile Info
2997 AddrTileMode
* pMode
, ///< [out] Tile mode
2998 AddrTileType
* pType
///< [out] Tile type
3001 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
3003 // Global flag to control usage of tileIndex
3004 if (UseTileIndex(index
))
3006 if (index
== TileIndexLinearGeneral
)
3010 *pMode
= ADDR_TM_LINEAR_GENERAL
;
3015 *pType
= ADDR_DISPLAYABLE
;
3021 pInfo
->bankWidth
= 1;
3022 pInfo
->bankHeight
= 1;
3023 pInfo
->macroAspectRatio
= 1;
3024 pInfo
->tileSplitBytes
= 64;
3025 pInfo
->pipeConfig
= ADDR_PIPECFG_P2
;
3028 else if (static_cast<UINT_32
>(index
) >= m_noOfEntries
)
3030 returnCode
= ADDR_INVALIDPARAMS
;
3034 const TileConfig
* pCfgTable
= GetTileSetting(index
);
3038 *pInfo
= pCfgTable
->info
;
3042 if (IsMacroTiled(pCfgTable
->mode
))
3044 returnCode
= ADDR_INVALIDPARAMS
;
3050 *pMode
= pCfgTable
->mode
;
3055 *pType
= pCfgTable
->type
;
3064 ****************************************************************************************************
3065 * SiLib::ReadGbTileMode
3068 * Convert GB_TILE_MODE HW value to TileConfig.
3071 ****************************************************************************************************
3073 VOID
SiLib::ReadGbTileMode(
3074 UINT_32 regValue
, ///< [in] GB_TILE_MODE register
3075 TileConfig
* pCfg
///< [out] output structure
3078 GB_TILE_MODE gbTileMode
;
3079 gbTileMode
.val
= regValue
;
3081 pCfg
->type
= static_cast<AddrTileType
>(gbTileMode
.f
.micro_tile_mode
);
3082 pCfg
->info
.bankHeight
= 1 << gbTileMode
.f
.bank_height
;
3083 pCfg
->info
.bankWidth
= 1 << gbTileMode
.f
.bank_width
;
3084 pCfg
->info
.banks
= 1 << (gbTileMode
.f
.num_banks
+ 1);
3085 pCfg
->info
.macroAspectRatio
= 1 << gbTileMode
.f
.macro_tile_aspect
;
3086 pCfg
->info
.tileSplitBytes
= 64 << gbTileMode
.f
.tile_split
;
3087 pCfg
->info
.pipeConfig
= static_cast<AddrPipeCfg
>(gbTileMode
.f
.pipe_config
+ 1);
3089 UINT_32 regArrayMode
= gbTileMode
.f
.array_mode
;
3091 pCfg
->mode
= static_cast<AddrTileMode
>(regArrayMode
);
3093 if (regArrayMode
== 8) //ARRAY_2D_TILED_XTHICK
3095 pCfg
->mode
= ADDR_TM_2D_TILED_XTHICK
;
3097 else if (regArrayMode
>= 14) //ARRAY_3D_TILED_XTHICK
3099 pCfg
->mode
= static_cast<AddrTileMode
>(pCfg
->mode
+ 3);
3104 ****************************************************************************************************
3105 * SiLib::InitTileSettingTable
3108 * Initialize the ADDR_TILE_CONFIG table.
3110 * TRUE if tile table is correctly initialized
3111 ****************************************************************************************************
3113 BOOL_32
SiLib::InitTileSettingTable(
3114 const UINT_32
* pCfg
, ///< [in] Pointer to table of tile configs
3115 UINT_32 noOfEntries
///< [in] Numbe of entries in the table above
3118 BOOL_32 initOk
= TRUE
;
3120 ADDR_ASSERT(noOfEntries
<= TileTableSize
);
3122 memset(m_tileTable
, 0, sizeof(m_tileTable
));
3124 if (noOfEntries
!= 0)
3126 m_noOfEntries
= noOfEntries
;
3130 m_noOfEntries
= TileTableSize
;
3133 if (pCfg
) // From Client
3135 for (UINT_32 i
= 0; i
< m_noOfEntries
; i
++)
3137 ReadGbTileMode(*(pCfg
+ i
), &m_tileTable
[i
]);
3142 ADDR_ASSERT_ALWAYS();
3148 ADDR_ASSERT(m_tileTable
[TILEINDEX_LINEAR_ALIGNED
].mode
== ADDR_TM_LINEAR_ALIGNED
);
3155 ****************************************************************************************************
3156 * SiLib::HwlGetTileIndex
3159 * Return the virtual/real index for given mode/type/info
3161 * ADDR_OK if successful.
3162 ****************************************************************************************************
3164 ADDR_E_RETURNCODE
SiLib::HwlGetTileIndex(
3165 const ADDR_GET_TILEINDEX_INPUT
* pIn
,
3166 ADDR_GET_TILEINDEX_OUTPUT
* pOut
) const
3168 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
3170 pOut
->index
= HwlPostCheckTileIndex(pIn
->pTileInfo
, pIn
->tileMode
, pIn
->tileType
);
3176 ****************************************************************************************************
3177 * SiLib::HwlFmaskPreThunkSurfInfo
3180 * Some preparation before thunking a ComputeSurfaceInfo call for Fmask
3183 ****************************************************************************************************
3185 VOID
SiLib::HwlFmaskPreThunkSurfInfo(
3186 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pFmaskIn
, ///< [in] Input of fmask info
3187 const ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pFmaskOut
, ///< [in] Output of fmask info
3188 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pSurfIn
, ///< [out] Input of thunked surface info
3189 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pSurfOut
///< [out] Output of thunked surface info
3192 pSurfIn
->tileIndex
= pFmaskIn
->tileIndex
;
3196 ****************************************************************************************************
3197 * SiLib::HwlFmaskPostThunkSurfInfo
3200 * Copy hwl extra field after calling thunked ComputeSurfaceInfo
3203 ****************************************************************************************************
3205 VOID
SiLib::HwlFmaskPostThunkSurfInfo(
3206 const ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pSurfOut
, ///< [in] Output of surface info
3207 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pFmaskOut
///< [out] Output of fmask info
3210 pFmaskOut
->macroModeIndex
= TileIndexInvalid
;
3211 pFmaskOut
->tileIndex
= pSurfOut
->tileIndex
;
3215 ****************************************************************************************************
3216 * SiLib::HwlComputeFmaskBits
3218 * Computes fmask bits
3221 ****************************************************************************************************
3223 UINT_32
SiLib::HwlComputeFmaskBits(
3224 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
,
3225 UINT_32
* pNumSamples
3228 UINT_32 numSamples
= pIn
->numSamples
;
3229 UINT_32 numFrags
= GetNumFragments(numSamples
, pIn
->numFrags
);
3232 if (numFrags
!= numSamples
) // EQAA
3234 ADDR_ASSERT(numFrags
<= 8);
3236 if (pIn
->resolved
== FALSE
)
3241 numSamples
= numSamples
== 16 ? 16 : 8;
3243 else if (numFrags
== 2)
3245 ADDR_ASSERT(numSamples
>= 4);
3248 numSamples
= numSamples
;
3250 else if (numFrags
== 4)
3252 ADDR_ASSERT(numSamples
>= 4);
3255 numSamples
= numSamples
;
3257 else // numFrags == 8
3259 ADDR_ASSERT(numSamples
== 16);
3262 numSamples
= numSamples
;
3269 bpp
= (numSamples
== 16) ? 16 : 8;
3272 else if (numFrags
== 2)
3274 ADDR_ASSERT(numSamples
>= 4);
3279 else if (numFrags
== 4)
3281 ADDR_ASSERT(numSamples
>= 4);
3286 else // numFrags == 8
3288 ADDR_ASSERT(numSamples
>= 16);
3297 if (pIn
->resolved
== FALSE
)
3299 bpp
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3300 numSamples
= numSamples
== 2 ? 8 : numSamples
;
3305 bpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3306 numSamples
= 1; // 1x sample
3310 SafeAssign(pNumSamples
, numSamples
);
3316 ****************************************************************************************************
3317 * SiLib::HwlOptimizeTileMode
3320 * Optimize tile mode on SI
3325 ****************************************************************************************************
3327 VOID
SiLib::HwlOptimizeTileMode(
3328 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
3331 AddrTileMode tileMode
= pInOut
->tileMode
;
3333 if ((pInOut
->flags
.needEquation
== TRUE
) &&
3334 (IsMacroTiled(tileMode
) == TRUE
) &&
3335 (pInOut
->numSamples
<= 1))
3337 UINT_32 thickness
= Thickness(tileMode
);
3341 tileMode
= ADDR_TM_1D_TILED_THICK
;
3343 else if (pInOut
->numSlices
> 1)
3345 tileMode
= ADDR_TM_1D_TILED_THIN1
;
3349 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3353 if (tileMode
!= pInOut
->tileMode
)
3355 pInOut
->tileMode
= tileMode
;
3360 ****************************************************************************************************
3361 * SiLib::HwlOverrideTileMode
3364 * Override tile modes (for PRT only, avoid client passes in an invalid PRT mode for SI.
3369 ****************************************************************************************************
3371 VOID
SiLib::HwlOverrideTileMode(
3372 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
3375 AddrTileMode tileMode
= pInOut
->tileMode
;
3379 case ADDR_TM_PRT_TILED_THIN1
:
3380 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3383 case ADDR_TM_PRT_TILED_THICK
:
3384 tileMode
= ADDR_TM_2D_TILED_THICK
;
3387 case ADDR_TM_PRT_2D_TILED_THICK
:
3388 tileMode
= ADDR_TM_2D_TILED_THICK
;
3391 case ADDR_TM_PRT_3D_TILED_THICK
:
3392 tileMode
= ADDR_TM_3D_TILED_THICK
;
3399 if (tileMode
!= pInOut
->tileMode
)
3401 pInOut
->tileMode
= tileMode
;
3402 // Only PRT tile modes are overridden for now. Revisit this once new modes are added above.
3403 pInOut
->flags
.prt
= TRUE
;
3408 ****************************************************************************************************
3409 * SiLib::HwlSetPrtTileMode
3412 * Set prt tile modes.
3417 ****************************************************************************************************
3419 VOID
SiLib::HwlSetPrtTileMode(
3420 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
3423 pInOut
->tileMode
= ADDR_TM_2D_TILED_THIN1
;
3424 pInOut
->tileType
= (pInOut
->tileType
== ADDR_DEPTH_SAMPLE_ORDER
) ?
3425 ADDR_DEPTH_SAMPLE_ORDER
: ADDR_NON_DISPLAYABLE
;
3426 pInOut
->flags
.prt
= TRUE
;
3430 ****************************************************************************************************
3431 * SiLib::HwlSelectTileMode
3434 * Select tile modes.
3439 ****************************************************************************************************
3441 VOID
SiLib::HwlSelectTileMode(
3442 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
3445 AddrTileMode tileMode
;
3446 AddrTileType tileType
;
3448 if (pInOut
->flags
.volume
)
3450 if (pInOut
->numSlices
>= 8)
3452 tileMode
= ADDR_TM_2D_TILED_XTHICK
;
3454 else if (pInOut
->numSlices
>= 4)
3456 tileMode
= ADDR_TM_2D_TILED_THICK
;
3460 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3462 tileType
= ADDR_NON_DISPLAYABLE
;
3466 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3468 if (pInOut
->flags
.depth
|| pInOut
->flags
.stencil
)
3470 tileType
= ADDR_DEPTH_SAMPLE_ORDER
;
3472 else if ((pInOut
->bpp
<= 32) ||
3473 (pInOut
->flags
.display
== TRUE
) ||
3474 (pInOut
->flags
.overlay
== TRUE
))
3476 tileType
= ADDR_DISPLAYABLE
;
3480 tileType
= ADDR_NON_DISPLAYABLE
;
3484 if (pInOut
->flags
.prt
)
3486 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3487 tileType
= (tileType
== ADDR_DISPLAYABLE
) ? ADDR_NON_DISPLAYABLE
: tileType
;
3490 pInOut
->tileMode
= tileMode
;
3491 pInOut
->tileType
= tileType
;
3493 // Optimize tile mode if possible
3494 pInOut
->flags
.opt4Space
= TRUE
;
3496 // Optimize tile mode if possible
3497 OptimizeTileMode(pInOut
);
3499 HwlOverrideTileMode(pInOut
);
3503 ****************************************************************************************************
3504 * SiLib::HwlComputeMaxBaseAlignments
3507 * Gets maximum alignments
3509 * maximum alignments
3510 ****************************************************************************************************
3512 UINT_32
SiLib::HwlComputeMaxBaseAlignments() const
3514 const UINT_32 pipes
= HwlGetPipes(&m_tileTable
[0].info
);
3516 // Initial size is 64 KiB for PRT.
3517 UINT_32 maxBaseAlign
= 64 * 1024;
3519 for (UINT_32 i
= 0; i
< m_noOfEntries
; i
++)
3521 if ((IsMacroTiled(m_tileTable
[i
].mode
) == TRUE
) &&
3522 (IsPrtTileMode(m_tileTable
[i
].mode
) == FALSE
))
3524 // The maximum tile size is 16 byte-per-pixel and either 8-sample or 8-slice.
3525 UINT_32 tileSize
= Min(m_tileTable
[i
].info
.tileSplitBytes
,
3526 MicroTilePixels
* 8 * 16);
3528 UINT_32 baseAlign
= tileSize
* pipes
* m_tileTable
[i
].info
.banks
*
3529 m_tileTable
[i
].info
.bankWidth
* m_tileTable
[i
].info
.bankHeight
;
3531 if (baseAlign
> maxBaseAlign
)
3533 maxBaseAlign
= baseAlign
;
3538 return maxBaseAlign
;
3542 ****************************************************************************************************
3543 * SiLib::HwlComputeMaxMetaBaseAlignments
3546 * Gets maximum alignments for metadata
3548 * maximum alignments for metadata
3549 ****************************************************************************************************
3551 UINT_32
SiLib::HwlComputeMaxMetaBaseAlignments() const
3553 UINT_32 maxPipe
= 1;
3555 for (UINT_32 i
= 0; i
< m_noOfEntries
; i
++)
3557 maxPipe
= Max(maxPipe
, HwlGetPipes(&m_tileTable
[i
].info
));
3560 return m_pipeInterleaveBytes
* maxPipe
;
3564 ****************************************************************************************************
3565 * SiLib::HwlComputeSurfaceAlignmentsMacroTiled
3568 * Hardware layer function to compute alignment request for macro tile mode
3573 ****************************************************************************************************
3575 VOID
SiLib::HwlComputeSurfaceAlignmentsMacroTiled(
3576 AddrTileMode tileMode
, ///< [in] tile mode
3577 UINT_32 bpp
, ///< [in] bits per pixel
3578 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
3579 UINT_32 mipLevel
, ///< [in] mip level
3580 UINT_32 numSamples
, ///< [in] number of samples
3581 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in,out] Surface output
3584 if ((mipLevel
== 0) && (flags
.prt
))
3586 UINT_32 macroTileSize
= pOut
->blockWidth
* pOut
->blockHeight
* numSamples
* bpp
/ 8;
3588 if (macroTileSize
< PrtTileSize
)
3590 UINT_32 numMacroTiles
= PrtTileSize
/ macroTileSize
;
3592 ADDR_ASSERT((PrtTileSize
% macroTileSize
) == 0);
3594 pOut
->pitchAlign
*= numMacroTiles
;
3595 pOut
->baseAlign
*= numMacroTiles
;
3601 ****************************************************************************************************
3602 * SiLib::InitEquationTable
3605 * Initialize Equation table.
3609 ****************************************************************************************************
3611 VOID
SiLib::InitEquationTable()
3613 ADDR_EQUATION_KEY equationKeyTable
[EquationTableSize
];
3614 memset(equationKeyTable
, 0, sizeof(equationKeyTable
));
3616 memset(m_equationTable
, 0, sizeof(m_equationTable
));
3618 memset(m_blockWidth
, 0, sizeof(m_blockWidth
));
3620 memset(m_blockHeight
, 0, sizeof(m_blockHeight
));
3622 memset(m_blockSlices
, 0, sizeof(m_blockSlices
));
3624 // Loop all possible bpp
3625 for (UINT_32 log2ElementBytes
= 0; log2ElementBytes
< MaxNumElementBytes
; log2ElementBytes
++)
3627 // Get bits per pixel
3628 UINT_32 bpp
= 1 << (log2ElementBytes
+ 3);
3630 // Loop all possible tile index
3631 for (INT_32 tileIndex
= 0; tileIndex
< static_cast<INT_32
>(m_noOfEntries
); tileIndex
++)
3633 UINT_32 equationIndex
= ADDR_INVALID_EQUATION_INDEX
;
3635 TileConfig tileConfig
= m_tileTable
[tileIndex
];
3637 ADDR_SURFACE_FLAGS flags
= {{0}};
3639 // Compute tile info, hardcode numSamples to 1 because MSAA is not supported
3640 // in swizzle pattern equation
3641 HwlComputeMacroModeIndex(tileIndex
, flags
, bpp
, 1, &tileConfig
.info
, NULL
, NULL
);
3643 // Check if the input is supported
3644 if (IsEquationSupported(bpp
, tileConfig
, tileIndex
, log2ElementBytes
) == TRUE
)
3646 ADDR_EQUATION_KEY key
= {{0}};
3648 // Generate swizzle equation key from bpp and tile config
3649 key
.fields
.log2ElementBytes
= log2ElementBytes
;
3650 key
.fields
.tileMode
= tileConfig
.mode
;
3651 // Treat depth micro tile type and non-display micro tile type as the same key
3652 // because they have the same equation actually
3653 key
.fields
.microTileType
= (tileConfig
.type
== ADDR_DEPTH_SAMPLE_ORDER
) ?
3654 ADDR_NON_DISPLAYABLE
: tileConfig
.type
;
3655 key
.fields
.pipeConfig
= tileConfig
.info
.pipeConfig
;
3656 key
.fields
.numBanksLog2
= Log2(tileConfig
.info
.banks
);
3657 key
.fields
.bankWidth
= tileConfig
.info
.bankWidth
;
3658 key
.fields
.bankHeight
= tileConfig
.info
.bankHeight
;
3659 key
.fields
.macroAspectRatio
= tileConfig
.info
.macroAspectRatio
;
3660 key
.fields
.prt
= ((m_chipFamily
== ADDR_CHIP_FAMILY_SI
) &&
3661 ((1 << tileIndex
) & SiPrtTileIndexMask
)) ? 1 : 0;
3663 // Find in the table if the equation has been built based on the key
3664 for (UINT_32 i
= 0; i
< m_numEquations
; i
++)
3666 if (key
.value
== equationKeyTable
[i
].value
)
3673 // If found, just fill the index into the lookup table and no need
3674 // to generate the equation again. Otherwise, generate the equation.
3675 if (equationIndex
== ADDR_INVALID_EQUATION_INDEX
)
3677 ADDR_EQUATION equation
;
3678 ADDR_E_RETURNCODE retCode
;
3680 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
3682 // Generate the equation
3683 if (IsMicroTiled(tileConfig
.mode
))
3685 retCode
= ComputeMicroTileEquation(log2ElementBytes
,
3692 retCode
= ComputeMacroTileEquation(log2ElementBytes
,
3698 // Only fill the equation into the table if the return code is ADDR_OK,
3699 // otherwise if the return code is not ADDR_OK, it indicates this is not
3700 // a valid input, we do nothing but just fill invalid equation index
3701 // into the lookup table.
3702 if (retCode
== ADDR_OK
)
3704 equationIndex
= m_numEquations
;
3705 ADDR_ASSERT(equationIndex
< EquationTableSize
);
3707 m_blockSlices
[equationIndex
] = Thickness(tileConfig
.mode
);
3709 if (IsMicroTiled(tileConfig
.mode
))
3711 m_blockWidth
[equationIndex
] = MicroTileWidth
;
3712 m_blockHeight
[equationIndex
] = MicroTileHeight
;
3716 const ADDR_TILEINFO
* pTileInfo
= &tileConfig
.info
;
3718 m_blockWidth
[equationIndex
] =
3719 HwlGetPipes(pTileInfo
) * MicroTileWidth
* pTileInfo
->bankWidth
*
3720 pTileInfo
->macroAspectRatio
;
3721 m_blockHeight
[equationIndex
] =
3722 MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
/
3723 pTileInfo
->macroAspectRatio
;
3727 UINT_32 macroTileSize
=
3728 m_blockWidth
[equationIndex
] * m_blockHeight
[equationIndex
] *
3731 if (macroTileSize
< PrtTileSize
)
3733 UINT_32 numMacroTiles
= PrtTileSize
/ macroTileSize
;
3735 ADDR_ASSERT(macroTileSize
== (1u << equation
.numBits
));
3736 ADDR_ASSERT((PrtTileSize
% macroTileSize
) == 0);
3738 UINT_32 numBits
= Log2(numMacroTiles
);
3740 UINT_32 xStart
= Log2(m_blockWidth
[equationIndex
]) +
3743 m_blockWidth
[equationIndex
] *= numMacroTiles
;
3745 for (UINT_32 i
= 0; i
< numBits
; i
++)
3747 equation
.addr
[equation
.numBits
+ i
].valid
= 1;
3748 equation
.addr
[equation
.numBits
+ i
].index
= xStart
+ i
;
3751 equation
.numBits
+= numBits
;
3756 equationKeyTable
[equationIndex
] = key
;
3757 m_equationTable
[equationIndex
] = equation
;
3764 // Fill the index into the lookup table, if the combination is not supported
3765 // fill the invalid equation index
3766 m_equationLookupTable
[log2ElementBytes
][tileIndex
] = equationIndex
;
3769 if (m_chipFamily
== ADDR_CHIP_FAMILY_SI
)
3771 // For tile index 3 which is shared between PRT depth and uncompressed depth
3772 m_uncompressDepthEqIndex
= m_numEquations
;
3774 for (UINT_32 log2ElemBytes
= 0; log2ElemBytes
< MaxNumElementBytes
; log2ElemBytes
++)
3776 TileConfig tileConfig
= m_tileTable
[3];
3777 ADDR_EQUATION equation
;
3778 ADDR_E_RETURNCODE retCode
;
3780 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
3782 retCode
= ComputeMacroTileEquation(log2ElemBytes
,
3788 if (retCode
== ADDR_OK
)
3790 UINT_32 equationIndex
= m_numEquations
;
3791 ADDR_ASSERT(equationIndex
< EquationTableSize
);
3793 m_blockSlices
[equationIndex
] = 1;
3795 const ADDR_TILEINFO
* pTileInfo
= &tileConfig
.info
;
3797 m_blockWidth
[equationIndex
] =
3798 HwlGetPipes(pTileInfo
) * MicroTileWidth
* pTileInfo
->bankWidth
*
3799 pTileInfo
->macroAspectRatio
;
3800 m_blockHeight
[equationIndex
] =
3801 MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
/
3802 pTileInfo
->macroAspectRatio
;
3804 m_equationTable
[equationIndex
] = equation
;
3814 ****************************************************************************************************
3815 * SiLib::IsEquationSupported
3818 * Check if it is supported for given bpp and tile config to generate a equation.
3822 ****************************************************************************************************
3824 BOOL_32
SiLib::IsEquationSupported(
3825 UINT_32 bpp
, ///< Bits per pixel
3826 TileConfig tileConfig
, ///< Tile config
3827 INT_32 tileIndex
, ///< Tile index
3828 UINT_32 elementBytesLog2
///< Log2 of element bytes
3831 BOOL_32 supported
= TRUE
;
3833 // Linear tile mode is not supported in swizzle pattern equation
3834 if (IsLinear(tileConfig
.mode
))
3838 // These tile modes are for Tex2DArray and Tex3D which has depth (num_slice > 1) use,
3839 // which is not supported in swizzle pattern equation due to slice rotation
3840 else if ((tileConfig
.mode
== ADDR_TM_2D_TILED_THICK
) ||
3841 (tileConfig
.mode
== ADDR_TM_2D_TILED_XTHICK
) ||
3842 (tileConfig
.mode
== ADDR_TM_3D_TILED_THIN1
) ||
3843 (tileConfig
.mode
== ADDR_TM_3D_TILED_THICK
) ||
3844 (tileConfig
.mode
== ADDR_TM_3D_TILED_XTHICK
))
3848 // Only 8bpp(stencil), 16bpp and 32bpp is supported for depth
3849 else if ((tileConfig
.type
== ADDR_DEPTH_SAMPLE_ORDER
) && (bpp
> 32))
3853 // Tile split is not supported in swizzle pattern equation
3854 else if (IsMacroTiled(tileConfig
.mode
))
3856 UINT_32 thickness
= Thickness(tileConfig
.mode
);
3857 if (((bpp
>> 3) * MicroTilePixels
* thickness
) > tileConfig
.info
.tileSplitBytes
)
3862 if ((supported
== TRUE
) && (m_chipFamily
== ADDR_CHIP_FAMILY_SI
))
3864 supported
= m_EquationSupport
[tileIndex
][elementBytesLog2
];