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
);
70 // We don't support MSAA for equation
71 const BOOL_32
SiLib::m_EquationSupport
[SiLib::TileTableSize
][SiLib::MaxNumElementBytes
] =
73 {TRUE
, TRUE
, TRUE
, FALSE
, FALSE
}, // 0, non-AA compressed depth or any stencil
74 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 1, 2xAA/4xAA compressed depth with or without stencil
75 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 2, 8xAA compressed depth with or without stencil
76 {FALSE
, TRUE
, FALSE
, FALSE
, FALSE
}, // 3, 16 bpp depth PRT (non-MSAA), don't support uncompressed depth
77 {TRUE
, TRUE
, TRUE
, FALSE
, FALSE
}, // 4, 1D depth
78 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 5, 16 bpp depth PRT (4xMSAA)
79 {FALSE
, FALSE
, TRUE
, FALSE
, FALSE
}, // 6, 32 bpp depth PRT (non-MSAA)
80 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 7, 32 bpp depth PRT (4xMSAA)
81 {TRUE
, TRUE
, TRUE
, TRUE
, TRUE
}, // 8, Linear
82 {TRUE
, TRUE
, TRUE
, TRUE
, TRUE
}, // 9, 1D display
83 {TRUE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 10, 8 bpp color (displayable)
84 {FALSE
, TRUE
, FALSE
, FALSE
, FALSE
}, // 11, 16 bpp color (displayable)
85 {FALSE
, FALSE
, TRUE
, TRUE
, FALSE
}, // 12, 32/64 bpp color (displayable)
86 {TRUE
, TRUE
, TRUE
, TRUE
, TRUE
}, // 13, 1D thin
87 {TRUE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 14, 8 bpp color non-displayable
88 {FALSE
, TRUE
, FALSE
, FALSE
, FALSE
}, // 15, 16 bpp color non-displayable
89 {FALSE
, FALSE
, TRUE
, FALSE
, FALSE
}, // 16, 32 bpp color non-displayable
90 {FALSE
, FALSE
, FALSE
, TRUE
, TRUE
}, // 17, 64/128 bpp color non-displayable
91 {TRUE
, TRUE
, TRUE
, TRUE
, TRUE
}, // 18, 1D THICK
92 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 19, 2D XTHICK
93 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 20, 2D THICK
94 {TRUE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 21, 8 bpp 2D PRTs (non-MSAA)
95 {FALSE
, TRUE
, FALSE
, FALSE
, FALSE
}, // 22, 16 bpp 2D PRTs (non-MSAA)
96 {FALSE
, FALSE
, TRUE
, FALSE
, FALSE
}, // 23, 32 bpp 2D PRTs (non-MSAA)
97 {FALSE
, FALSE
, FALSE
, TRUE
, FALSE
}, // 24, 64 bpp 2D PRTs (non-MSAA)
98 {FALSE
, FALSE
, FALSE
, FALSE
, TRUE
}, // 25, 128bpp 2D PRTs (non-MSAA)
99 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 26, none
100 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 27, none
101 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 28, none
102 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 29, none
103 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 30, 64bpp 2D PRTs (4xMSAA)
104 {FALSE
, FALSE
, FALSE
, FALSE
, FALSE
}, // 31, none
108 ****************************************************************************************************
114 ****************************************************************************************************
116 SiLib::SiLib(const Client
* pClient
)
122 m_class
= SI_ADDRLIB
;
123 memset(&m_settings
, 0, sizeof(m_settings
));
127 ****************************************************************************************************
132 ****************************************************************************************************
139 ****************************************************************************************************
146 ****************************************************************************************************
148 UINT_32
SiLib::HwlGetPipes(
149 const ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
156 numPipes
= GetPipePerSurf(pTileInfo
->pipeConfig
);
160 ADDR_ASSERT_ALWAYS();
161 numPipes
= m_pipes
; // Suppose we should still have a global pipes
168 ****************************************************************************************************
169 * SiLib::GetPipePerSurf
171 * get pipe num base on inputing tileinfo->pipeconfig
174 ****************************************************************************************************
176 UINT_32
SiLib::GetPipePerSurf(
177 AddrPipeCfg pipeConfig
///< [in] pipe config
180 UINT_32 numPipes
= 0;
184 case ADDR_PIPECFG_P2
:
187 case ADDR_PIPECFG_P4_8x16
:
188 case ADDR_PIPECFG_P4_16x16
:
189 case ADDR_PIPECFG_P4_16x32
:
190 case ADDR_PIPECFG_P4_32x32
:
193 case ADDR_PIPECFG_P8_16x16_8x16
:
194 case ADDR_PIPECFG_P8_16x32_8x16
:
195 case ADDR_PIPECFG_P8_32x32_8x16
:
196 case ADDR_PIPECFG_P8_16x32_16x16
:
197 case ADDR_PIPECFG_P8_32x32_16x16
:
198 case ADDR_PIPECFG_P8_32x32_16x32
:
199 case ADDR_PIPECFG_P8_32x64_32x32
:
202 case ADDR_PIPECFG_P16_32x32_8x16
:
203 case ADDR_PIPECFG_P16_32x32_16x16
:
207 ADDR_ASSERT(!"Invalid pipe config");
214 ****************************************************************************************************
215 * SiLib::ComputeBankEquation
218 * Compute bank equation
221 * If equation can be computed
222 ****************************************************************************************************
224 ADDR_E_RETURNCODE
SiLib::ComputeBankEquation(
225 UINT_32 log2BytesPP
, ///< [in] log2 of bytes per pixel
226 UINT_32 threshX
, ///< [in] threshold for x channel
227 UINT_32 threshY
, ///< [in] threshold for y channel
228 ADDR_TILEINFO
* pTileInfo
, ///< [in] tile info
229 ADDR_EQUATION
* pEquation
///< [out] bank equation
232 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
234 UINT_32 pipes
= HwlGetPipes(pTileInfo
);
235 UINT_32 bankXStart
= 3 + Log2(pipes
) + Log2(pTileInfo
->bankWidth
);
236 UINT_32 bankYStart
= 3 + Log2(pTileInfo
->bankHeight
);
238 ADDR_CHANNEL_SETTING x3
= InitChannel(1, 0, log2BytesPP
+ bankXStart
);
239 ADDR_CHANNEL_SETTING x4
= InitChannel(1, 0, log2BytesPP
+ bankXStart
+ 1);
240 ADDR_CHANNEL_SETTING x5
= InitChannel(1, 0, log2BytesPP
+ bankXStart
+ 2);
241 ADDR_CHANNEL_SETTING x6
= InitChannel(1, 0, log2BytesPP
+ bankXStart
+ 3);
242 ADDR_CHANNEL_SETTING y3
= InitChannel(1, 1, bankYStart
);
243 ADDR_CHANNEL_SETTING y4
= InitChannel(1, 1, bankYStart
+ 1);
244 ADDR_CHANNEL_SETTING y5
= InitChannel(1, 1, bankYStart
+ 2);
245 ADDR_CHANNEL_SETTING y6
= InitChannel(1, 1, bankYStart
+ 3);
247 x3
.value
= (threshX
> bankXStart
) ? x3
.value
: 0;
248 x4
.value
= (threshX
> bankXStart
+ 1) ? x4
.value
: 0;
249 x5
.value
= (threshX
> bankXStart
+ 2) ? x5
.value
: 0;
250 x6
.value
= (threshX
> bankXStart
+ 3) ? x6
.value
: 0;
251 y3
.value
= (threshY
> bankYStart
) ? y3
.value
: 0;
252 y4
.value
= (threshY
> bankYStart
+ 1) ? y4
.value
: 0;
253 y5
.value
= (threshY
> bankYStart
+ 2) ? y5
.value
: 0;
254 y6
.value
= (threshY
> bankYStart
+ 3) ? y6
.value
: 0;
256 switch (pTileInfo
->banks
)
259 if (pTileInfo
->macroAspectRatio
== 1)
261 pEquation
->addr
[0] = y6
;
262 pEquation
->xor1
[0] = x3
;
263 pEquation
->addr
[1] = y5
;
264 pEquation
->xor1
[1] = y6
;
265 pEquation
->xor2
[1] = x4
;
266 pEquation
->addr
[2] = y4
;
267 pEquation
->xor1
[2] = x5
;
268 pEquation
->addr
[3] = y3
;
269 pEquation
->xor1
[3] = x6
;
271 else if (pTileInfo
->macroAspectRatio
== 2)
273 pEquation
->addr
[0] = x3
;
274 pEquation
->xor1
[0] = y6
;
275 pEquation
->addr
[1] = y5
;
276 pEquation
->xor1
[1] = y6
;
277 pEquation
->xor2
[1] = x4
;
278 pEquation
->addr
[2] = y4
;
279 pEquation
->xor1
[2] = x5
;
280 pEquation
->addr
[3] = y3
;
281 pEquation
->xor1
[3] = x6
;
283 else if (pTileInfo
->macroAspectRatio
== 4)
285 pEquation
->addr
[0] = x3
;
286 pEquation
->xor1
[0] = y6
;
287 pEquation
->addr
[1] = x4
;
288 pEquation
->xor1
[1] = y5
;
289 pEquation
->xor2
[1] = y6
;
290 pEquation
->addr
[2] = y4
;
291 pEquation
->xor1
[2] = x5
;
292 pEquation
->addr
[3] = y3
;
293 pEquation
->xor1
[3] = x6
;
295 else if (pTileInfo
->macroAspectRatio
== 8)
297 pEquation
->addr
[0] = x3
;
298 pEquation
->xor1
[0] = y6
;
299 pEquation
->addr
[1] = x4
;
300 pEquation
->xor1
[1] = y5
;
301 pEquation
->xor2
[1] = y6
;
302 pEquation
->addr
[2] = x5
;
303 pEquation
->xor1
[2] = y4
;
304 pEquation
->addr
[3] = y3
;
305 pEquation
->xor1
[3] = x6
;
309 ADDR_ASSERT_ALWAYS();
311 pEquation
->numBits
= 4;
314 if (pTileInfo
->macroAspectRatio
== 1)
316 pEquation
->addr
[0] = y5
;
317 pEquation
->xor1
[0] = x3
;
318 pEquation
->addr
[1] = y4
;
319 pEquation
->xor1
[1] = y5
;
320 pEquation
->xor2
[1] = x4
;
321 pEquation
->addr
[2] = y3
;
322 pEquation
->xor1
[2] = x5
;
324 else if (pTileInfo
->macroAspectRatio
== 2)
326 pEquation
->addr
[0] = x3
;
327 pEquation
->xor1
[0] = y5
;
328 pEquation
->addr
[1] = y4
;
329 pEquation
->xor1
[1] = y5
;
330 pEquation
->xor2
[1] = x4
;
331 pEquation
->addr
[2] = y3
;
332 pEquation
->xor1
[2] = x5
;
334 else if (pTileInfo
->macroAspectRatio
== 4)
336 pEquation
->addr
[0] = x3
;
337 pEquation
->xor1
[0] = y5
;
338 pEquation
->addr
[1] = x4
;
339 pEquation
->xor1
[1] = y4
;
340 pEquation
->xor2
[1] = y5
;
341 pEquation
->addr
[2] = y3
;
342 pEquation
->xor1
[2] = x5
;
346 ADDR_ASSERT_ALWAYS();
348 pEquation
->numBits
= 3;
351 if (pTileInfo
->macroAspectRatio
== 1)
353 pEquation
->addr
[0] = y4
;
354 pEquation
->xor1
[0] = x3
;
355 pEquation
->addr
[1] = y3
;
356 pEquation
->xor1
[1] = x4
;
358 else if (pTileInfo
->macroAspectRatio
== 2)
360 pEquation
->addr
[0] = x3
;
361 pEquation
->xor1
[0] = y4
;
362 pEquation
->addr
[1] = y3
;
363 pEquation
->xor1
[1] = x4
;
367 pEquation
->addr
[0] = x3
;
368 pEquation
->xor1
[0] = y4
;
369 pEquation
->addr
[1] = x4
;
370 pEquation
->xor1
[1] = y3
;
372 pEquation
->numBits
= 2;
375 if (pTileInfo
->macroAspectRatio
== 1)
377 pEquation
->addr
[0] = y3
;
378 pEquation
->xor1
[0] = x3
;
382 pEquation
->addr
[0] = x3
;
383 pEquation
->xor1
[0] = y3
;
385 pEquation
->numBits
= 1;
388 pEquation
->numBits
= 0;
389 retCode
= ADDR_NOTSUPPORTED
;
390 ADDR_ASSERT_ALWAYS();
394 for (UINT_32 i
= 0; i
< pEquation
->numBits
; i
++)
396 if (pEquation
->addr
[i
].value
== 0)
398 if (pEquation
->xor1
[i
].value
== 0)
401 pEquation
->addr
[i
].value
= pEquation
->xor2
[i
].value
;
402 pEquation
->xor2
[i
].value
= 0;
406 pEquation
->addr
[i
].value
= pEquation
->xor1
[i
].value
;
408 if (pEquation
->xor2
[i
].value
!= 0)
411 pEquation
->xor1
[i
].value
= pEquation
->xor2
[i
].value
;
412 pEquation
->xor2
[i
].value
= 0;
417 pEquation
->xor1
[i
].value
= 0;
421 else if (pEquation
->xor1
[i
].value
== 0)
423 if (pEquation
->xor2
[i
].value
!= 0)
426 pEquation
->xor1
[i
].value
= pEquation
->xor2
[i
].value
;
427 pEquation
->xor2
[i
].value
= 0;
432 if ((pTileInfo
->bankWidth
== 1) &&
433 ((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P4_32x32
) ||
434 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
)))
436 retCode
= ADDR_NOTSUPPORTED
;
443 ****************************************************************************************************
444 * SiLib::ComputePipeEquation
447 * Compute pipe equation
450 * If equation can be computed
451 ****************************************************************************************************
453 ADDR_E_RETURNCODE
SiLib::ComputePipeEquation(
454 UINT_32 log2BytesPP
, ///< [in] Log2 of bytes per pixel
455 UINT_32 threshX
, ///< [in] Threshold for X channel
456 UINT_32 threshY
, ///< [in] Threshold for Y channel
457 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
458 ADDR_EQUATION
* pEquation
///< [out] Pipe configure
461 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
463 ADDR_CHANNEL_SETTING
* pAddr
= pEquation
->addr
;
464 ADDR_CHANNEL_SETTING
* pXor1
= pEquation
->xor1
;
465 ADDR_CHANNEL_SETTING
* pXor2
= pEquation
->xor2
;
467 ADDR_CHANNEL_SETTING x3
= InitChannel(1, 0, 3 + log2BytesPP
);
468 ADDR_CHANNEL_SETTING x4
= InitChannel(1, 0, 4 + log2BytesPP
);
469 ADDR_CHANNEL_SETTING x5
= InitChannel(1, 0, 5 + log2BytesPP
);
470 ADDR_CHANNEL_SETTING x6
= InitChannel(1, 0, 6 + log2BytesPP
);
471 ADDR_CHANNEL_SETTING y3
= InitChannel(1, 1, 3);
472 ADDR_CHANNEL_SETTING y4
= InitChannel(1, 1, 4);
473 ADDR_CHANNEL_SETTING y5
= InitChannel(1, 1, 5);
474 ADDR_CHANNEL_SETTING y6
= InitChannel(1, 1, 6);
476 x3
.value
= (threshX
> 3) ? x3
.value
: 0;
477 x4
.value
= (threshX
> 4) ? x4
.value
: 0;
478 x5
.value
= (threshX
> 5) ? x5
.value
: 0;
479 x6
.value
= (threshX
> 6) ? x6
.value
: 0;
480 y3
.value
= (threshY
> 3) ? y3
.value
: 0;
481 y4
.value
= (threshY
> 4) ? y4
.value
: 0;
482 y5
.value
= (threshY
> 5) ? y5
.value
: 0;
483 y6
.value
= (threshY
> 6) ? y6
.value
: 0;
485 switch (pTileInfo
->pipeConfig
)
487 case ADDR_PIPECFG_P2
:
490 pEquation
->numBits
= 1;
492 case ADDR_PIPECFG_P4_8x16
:
497 pEquation
->numBits
= 2;
499 case ADDR_PIPECFG_P4_16x16
:
505 pEquation
->numBits
= 2;
507 case ADDR_PIPECFG_P4_16x32
:
513 pEquation
->numBits
= 2;
515 case ADDR_PIPECFG_P4_32x32
:
521 pEquation
->numBits
= 2;
523 case ADDR_PIPECFG_P8_16x16_8x16
:
529 pEquation
->numBits
= 3;
531 case ADDR_PIPECFG_P8_16x32_8x16
:
539 pEquation
->numBits
= 3;
541 case ADDR_PIPECFG_P8_16x32_16x16
:
549 pEquation
->numBits
= 3;
551 case ADDR_PIPECFG_P8_32x32_8x16
:
559 pEquation
->numBits
= 3;
561 case ADDR_PIPECFG_P8_32x32_16x16
:
569 pEquation
->numBits
= 3;
571 case ADDR_PIPECFG_P8_32x32_16x32
:
579 pEquation
->numBits
= 3;
581 case ADDR_PIPECFG_P8_32x64_32x32
:
589 pEquation
->numBits
= 3;
591 case ADDR_PIPECFG_P16_32x32_8x16
:
600 pEquation
->numBits
= 4;
602 case ADDR_PIPECFG_P16_32x32_16x16
:
612 pEquation
->numBits
= 4;
615 ADDR_UNHANDLED_CASE();
616 pEquation
->numBits
= 0;
617 retCode
= ADDR_NOTSUPPORTED
;
621 for (UINT_32 i
= 0; i
< pEquation
->numBits
; i
++)
623 if (pAddr
[i
].value
== 0)
625 if (pXor1
[i
].value
== 0)
627 pAddr
[i
].value
= pXor2
[i
].value
;
631 pAddr
[i
].value
= pXor1
[i
].value
;
641 ****************************************************************************************************
642 * SiLib::ComputePipeFromCoord
645 * Compute pipe number from coordinates
648 ****************************************************************************************************
650 UINT_32
SiLib::ComputePipeFromCoord(
651 UINT_32 x
, ///< [in] x coordinate
652 UINT_32 y
, ///< [in] y coordinate
653 UINT_32 slice
, ///< [in] slice index
654 AddrTileMode tileMode
, ///< [in] tile mode
655 UINT_32 pipeSwizzle
, ///< [in] pipe swizzle
656 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines are ignored
657 ADDR_TILEINFO
* pTileInfo
///< [in] Tile info
661 UINT_32 pipeBit0
= 0;
662 UINT_32 pipeBit1
= 0;
663 UINT_32 pipeBit2
= 0;
664 UINT_32 pipeBit3
= 0;
665 UINT_32 sliceRotation
;
666 UINT_32 numPipes
= 0;
668 UINT_32 tx
= x
/ MicroTileWidth
;
669 UINT_32 ty
= y
/ MicroTileHeight
;
670 UINT_32 x3
= _BIT(tx
,0);
671 UINT_32 x4
= _BIT(tx
,1);
672 UINT_32 x5
= _BIT(tx
,2);
673 UINT_32 x6
= _BIT(tx
,3);
674 UINT_32 y3
= _BIT(ty
,0);
675 UINT_32 y4
= _BIT(ty
,1);
676 UINT_32 y5
= _BIT(ty
,2);
677 UINT_32 y6
= _BIT(ty
,3);
679 switch (pTileInfo
->pipeConfig
)
681 case ADDR_PIPECFG_P2
:
685 case ADDR_PIPECFG_P4_8x16
:
690 case ADDR_PIPECFG_P4_16x16
:
691 pipeBit0
= x3
^ y3
^ x4
;
695 case ADDR_PIPECFG_P4_16x32
:
696 pipeBit0
= x3
^ y3
^ x4
;
700 case ADDR_PIPECFG_P4_32x32
:
701 pipeBit0
= x3
^ y3
^ x5
;
705 case ADDR_PIPECFG_P8_16x16_8x16
:
706 pipeBit0
= x4
^ y3
^ x5
;
710 case ADDR_PIPECFG_P8_16x32_8x16
:
711 pipeBit0
= x4
^ y3
^ x5
;
716 case ADDR_PIPECFG_P8_16x32_16x16
:
717 pipeBit0
= x3
^ y3
^ x4
;
722 case ADDR_PIPECFG_P8_32x32_8x16
:
723 pipeBit0
= x4
^ y3
^ x5
;
728 case ADDR_PIPECFG_P8_32x32_16x16
:
729 pipeBit0
= x3
^ y3
^ x4
;
734 case ADDR_PIPECFG_P8_32x32_16x32
:
735 pipeBit0
= x3
^ y3
^ x4
;
740 case ADDR_PIPECFG_P8_32x64_32x32
:
741 pipeBit0
= x3
^ y3
^ x5
;
746 case ADDR_PIPECFG_P16_32x32_8x16
:
753 case ADDR_PIPECFG_P16_32x32_16x16
:
754 pipeBit0
= x3
^ y3
^ x4
;
761 ADDR_UNHANDLED_CASE();
764 pipe
= pipeBit0
| (pipeBit1
<< 1) | (pipeBit2
<< 2) | (pipeBit3
<< 3);
766 UINT_32 microTileThickness
= Thickness(tileMode
);
769 // Apply pipe rotation for the slice.
773 case ADDR_TM_3D_TILED_THIN1
: //fall through thin
774 case ADDR_TM_3D_TILED_THICK
: //fall through thick
775 case ADDR_TM_3D_TILED_XTHICK
:
777 Max(1, static_cast<INT_32
>(numPipes
/ 2) - 1) * (slice
/ microTileThickness
);
783 pipeSwizzle
+= sliceRotation
;
784 pipeSwizzle
&= (numPipes
- 1);
786 pipe
= pipe
^ pipeSwizzle
;
792 ****************************************************************************************************
793 * SiLib::ComputeTileCoordFromPipeAndElemIdx
796 * Compute (x,y) of a tile within a macro tile from address
799 ****************************************************************************************************
801 VOID
SiLib::ComputeTileCoordFromPipeAndElemIdx(
802 UINT_32 elemIdx
, ///< [in] per pipe element index within a macro tile
803 UINT_32 pipe
, ///< [in] pipe index
804 AddrPipeCfg pipeCfg
, ///< [in] pipe config
805 UINT_32 pitchInMacroTile
, ///< [in] surface pitch in macro tile
806 UINT_32 x
, ///< [in] x coordinate of the (0,0) tile in a macro tile
807 UINT_32 y
, ///< [in] y coordinate of the (0,0) tile in a macro tile
808 UINT_32
* pX
, ///< [out] x coordinate
809 UINT_32
* pY
///< [out] y coordinate
812 UINT_32 pipebit0
= _BIT(pipe
,0);
813 UINT_32 pipebit1
= _BIT(pipe
,1);
814 UINT_32 pipebit2
= _BIT(pipe
,2);
815 UINT_32 pipebit3
= _BIT(pipe
,3);
816 UINT_32 elemIdx0
= _BIT(elemIdx
,0);
817 UINT_32 elemIdx1
= _BIT(elemIdx
,1);
818 UINT_32 elemIdx2
= _BIT(elemIdx
,2);
830 case ADDR_PIPECFG_P2
:
835 *pY
= Bits2Number(2, y4
, y3
);
836 *pX
= Bits2Number(2, x4
, x3
);
838 case ADDR_PIPECFG_P4_8x16
:
843 *pY
= Bits2Number(2, y4
, y3
);
844 *pX
= Bits2Number(2, x4
, x3
);
846 case ADDR_PIPECFG_P4_16x16
:
850 x3
= pipebit0
^ y3
^ x4
;
851 *pY
= Bits2Number(2, y4
, y3
);
852 *pX
= Bits2Number(2, x4
, x3
);
854 case ADDR_PIPECFG_P4_16x32
:
855 x3
= elemIdx0
^ pipebit0
;
858 y3
= pipebit0
^ x3
^ x4
;
860 *pY
= Bits2Number(2, y4
, y3
);
861 *pX
= Bits2Number(2, x4
, x3
);
863 case ADDR_PIPECFG_P4_32x32
:
867 if((pitchInMacroTile
% 2) == 0)
871 x3
= pipebit0
^ y3
^ x5
;
872 *pY
= Bits2Number(2, y4
, y3
);
873 *pX
= Bits2Number(3, x5
, x4
, x3
);
878 x3
= pipebit0
^ y3
^ x5
;
879 *pY
= Bits2Number(2, y4
, y3
);
880 *pX
= Bits2Number(2, x4
, x3
);
883 case ADDR_PIPECFG_P8_16x16_8x16
:
889 y3
= pipebit0
^ x5
^ x4
;
890 *pY
= Bits2Number(2, y4
, y3
);
891 *pX
= Bits2Number(2, x4
, x3
);
893 case ADDR_PIPECFG_P8_16x32_8x16
:
899 y3
= pipebit0
^ x4
^ x5
;
900 *pY
= Bits2Number(2, y4
, y3
);
901 *pX
= Bits2Number(2, x4
, x3
);
903 case ADDR_PIPECFG_P8_32x32_8x16
:
907 if((pitchInMacroTile
% 2) == 0)
912 y3
= pipebit0
^ x4
^ x5
;
913 *pY
= Bits2Number(2, y4
, y3
);
914 *pX
= Bits2Number(3, x5
, x4
, x3
);
919 y3
= pipebit0
^ x4
^ x5
;
920 *pY
= Bits2Number(2, y4
, y3
);
921 *pX
= Bits2Number(2, x4
, x3
);
924 case ADDR_PIPECFG_P8_16x32_16x16
:
930 y3
= pipebit0
^ x3
^ x4
;
931 *pY
= Bits2Number(2, y4
, y3
);
932 *pX
= Bits2Number(2, x4
, x3
);
934 case ADDR_PIPECFG_P8_32x32_16x16
:
939 if((pitchInMacroTile
% 2) == 0)
943 *pY
= Bits2Number(2, y4
, y3
);
944 *pX
= Bits2Number(3, x5
, x4
, x3
);
948 *pY
= Bits2Number(2, y4
, y3
);
949 *pX
= Bits2Number(2, x4
, x3
);
952 case ADDR_PIPECFG_P8_32x32_16x32
:
953 if((pitchInMacroTile
% 2) == 0)
960 x3
= pipebit0
^ y3
^ x4
;
962 *pY
= Bits2Number(2, y4
, y3
);
963 *pX
= Bits2Number(3, x5
, x4
, x3
);
971 x3
= pipebit0
^ y3
^ x4
;
972 *pY
= Bits2Number(2, y4
, y3
);
973 *pX
= Bits2Number(2, x4
, x3
);
976 case ADDR_PIPECFG_P8_32x64_32x32
:
980 if((pitchInMacroTile
% 4) == 0)
986 x3
= pipebit0
^ y3
^ x5
;
987 *pY
= Bits2Number(2, y4
, y3
);
988 *pX
= Bits2Number(4, x6
, x5
, x4
, x3
);
994 x3
= pipebit0
^ y3
^ x5
;
995 *pY
= Bits2Number(2, y4
, y3
);
996 *pX
= Bits2Number(3, x5
, x4
, x3
);
999 case ADDR_PIPECFG_P16_32x32_8x16
:
1004 if((pitchInMacroTile
% 4) == 0)
1010 *pY
= Bits2Number(2, y4
, y3
);
1011 *pX
= Bits2Number(4, x6
, x5
,x4
, x3
);
1017 *pY
= Bits2Number(2, y4
, y3
);
1018 *pX
= Bits2Number(3, x5
, x4
, x3
);
1021 case ADDR_PIPECFG_P16_32x32_16x16
:
1025 x3
= pipebit0
^ y3
^ x4
;
1026 if((pitchInMacroTile
% 4) == 0)
1032 *pY
= Bits2Number(2, y4
, y3
);
1033 *pX
= Bits2Number(4, x6
, x5
, x4
, x3
);
1039 *pY
= Bits2Number(2, y4
, y3
);
1040 *pX
= Bits2Number(3, x5
, x4
, x3
);
1044 ADDR_UNHANDLED_CASE();
1049 ****************************************************************************************************
1050 * SiLib::TileCoordToMaskElementIndex
1053 * Compute element index from coordinates in tiles
1056 ****************************************************************************************************
1058 UINT_32
SiLib::TileCoordToMaskElementIndex(
1059 UINT_32 tx
, ///< [in] x coord, in Tiles
1060 UINT_32 ty
, ///< [in] y coord, in Tiles
1061 AddrPipeCfg pipeConfig
, ///< [in] pipe config
1062 UINT_32
* macroShift
, ///< [out] macro shift
1063 UINT_32
* elemIdxBits
///< [out] tile offset bits
1066 UINT_32 elemIdx
= 0;
1067 UINT_32 elemIdx0
, elemIdx1
, elemIdx2
;
1078 case ADDR_PIPECFG_P2
:
1082 elemIdx1
= tx1
^ ty1
;
1083 elemIdx0
= tx1
^ ty0
;
1084 elemIdx
= Bits2Number(3,elemIdx2
,elemIdx1
,elemIdx0
);
1086 case ADDR_PIPECFG_P4_8x16
:
1090 elemIdx0
= tx1
^ ty1
;
1091 elemIdx
= Bits2Number(2,elemIdx1
,elemIdx0
);
1093 case ADDR_PIPECFG_P4_16x16
:
1098 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1100 case ADDR_PIPECFG_P4_16x32
:
1105 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1107 case ADDR_PIPECFG_P4_32x32
:
1113 elemIdx
= Bits2Number(3, elemIdx2
, elemIdx1
, elemIdx0
);
1115 case ADDR_PIPECFG_P8_16x16_8x16
:
1121 case ADDR_PIPECFG_P8_16x32_8x16
:
1127 case ADDR_PIPECFG_P8_32x32_8x16
:
1132 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1134 case ADDR_PIPECFG_P8_16x32_16x16
:
1140 case ADDR_PIPECFG_P8_32x32_16x16
:
1145 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1147 case ADDR_PIPECFG_P8_32x32_16x32
:
1152 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1154 case ADDR_PIPECFG_P8_32x64_32x32
:
1160 elemIdx
= Bits2Number(3, elemIdx2
, elemIdx1
, elemIdx0
);
1162 case ADDR_PIPECFG_P16_32x32_8x16
:
1167 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1169 case ADDR_PIPECFG_P16_32x32_16x16
:
1174 elemIdx
= Bits2Number(2, elemIdx1
, elemIdx0
);
1177 ADDR_UNHANDLED_CASE();
1185 ****************************************************************************************************
1186 * SiLib::HwlComputeTileDataWidthAndHeightLinear
1189 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1195 * MacroWidth and macroHeight are measured in pixels
1196 ****************************************************************************************************
1198 VOID
SiLib::HwlComputeTileDataWidthAndHeightLinear(
1199 UINT_32
* pMacroWidth
, ///< [out] macro tile width
1200 UINT_32
* pMacroHeight
, ///< [out] macro tile height
1201 UINT_32 bpp
, ///< [in] bits per pixel
1202 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
1205 ADDR_ASSERT(pTileInfo
!= NULL
);
1207 UINT_32 macroHeight
;
1209 /// In linear mode, the htile or cmask buffer must be padded out to 4 tiles
1210 /// but for P8_32x64_32x32, it must be padded out to 8 tiles
1211 /// Actually there are more pipe configs which need 8-tile padding but SI family
1212 /// has a bug which is fixed in CI family
1213 if ((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
) ||
1214 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P16_32x32_8x16
) ||
1215 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x32_16x16
))
1217 macroWidth
= 8*MicroTileWidth
;
1218 macroHeight
= 8*MicroTileHeight
;
1222 macroWidth
= 4*MicroTileWidth
;
1223 macroHeight
= 4*MicroTileHeight
;
1226 *pMacroWidth
= macroWidth
;
1227 *pMacroHeight
= macroHeight
;
1231 ****************************************************************************************************
1232 * SiLib::HwlComputeHtileBytes
1235 * Compute htile size in bytes
1238 * Htile size in bytes
1239 ****************************************************************************************************
1241 UINT_64
SiLib::HwlComputeHtileBytes(
1242 UINT_32 pitch
, ///< [in] pitch
1243 UINT_32 height
, ///< [in] height
1244 UINT_32 bpp
, ///< [in] bits per pixel
1245 BOOL_32 isLinear
, ///< [in] if it is linear mode
1246 UINT_32 numSlices
, ///< [in] number of slices
1247 UINT_64
* pSliceBytes
, ///< [out] bytes per slice
1248 UINT_32 baseAlign
///< [in] base alignments
1251 return ComputeHtileBytes(pitch
, height
, bpp
, isLinear
, numSlices
, pSliceBytes
, baseAlign
);
1255 ****************************************************************************************************
1256 * SiLib::HwlComputeXmaskAddrFromCoord
1259 * Compute address from coordinates for htile/cmask
1262 ****************************************************************************************************
1264 UINT_64
SiLib::HwlComputeXmaskAddrFromCoord(
1265 UINT_32 pitch
, ///< [in] pitch
1266 UINT_32 height
, ///< [in] height
1267 UINT_32 x
, ///< [in] x coord
1268 UINT_32 y
, ///< [in] y coord
1269 UINT_32 slice
, ///< [in] slice/depth index
1270 UINT_32 numSlices
, ///< [in] number of slices
1271 UINT_32 factor
, ///< [in] factor that indicates cmask(2) or htile(1)
1272 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
1273 BOOL_32 isWidth8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
1274 BOOL_32 isHeight8
, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
1275 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1276 UINT_32
* pBitPosition
///< [out] bit position inside a byte
1279 UINT_32 tx
= x
/ MicroTileWidth
;
1280 UINT_32 ty
= y
/ MicroTileHeight
;
1285 UINT_32 macroHeight
;
1286 UINT_64 pSliceBytes
;
1288 UINT_32 tileNumPerPipe
;
1291 if (factor
== 2) //CMASK
1293 ADDR_CMASK_FLAGS flags
= {{0}};
1295 tileNumPerPipe
= 256;
1297 ComputeCmaskInfo(flags
,
1308 elemBits
= CmaskElemBits
;
1312 ADDR_HTILE_FLAGS flags
= {{0}};
1314 tileNumPerPipe
= 512;
1316 ComputeHtileInfo(flags
,
1334 const UINT_32 pitchInTile
= newPitch
/ MicroTileWidth
;
1335 const UINT_32 heightInTile
= newHeight
/ MicroTileWidth
;
1336 UINT_64 macroOffset
; // Per pipe starting offset of the macro tile in which this tile lies.
1337 UINT_64 microNumber
; // Per pipe starting offset of the macro tile in which this tile lies.
1340 UINT_64 microOffset
;
1342 UINT_64 totalOffset
;
1343 UINT_32 elemIdxBits
;
1345 TileCoordToMaskElementIndex(tx
, ty
, pTileInfo
->pipeConfig
, µShift
, &elemIdxBits
);
1347 UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1350 { //linear addressing
1351 // Linear addressing is extremelly wasting memory if slice > 1, since each pipe has the full
1352 // slice memory foot print instead of divided by numPipes.
1353 microX
= tx
/ 4; // Macro Tile is 4x4
1355 microNumber
= static_cast<UINT_64
>(microX
+ microY
* (pitchInTile
/ 4)) << microShift
;
1357 UINT_32 sliceBits
= pitchInTile
* heightInTile
;
1359 // do htile single slice alignment if the flag is true
1360 if (m_configFlags
.useHtileSliceAlign
&& (factor
== 1)) //Htile
1362 sliceBits
= PowTwoAlign(sliceBits
, BITS_TO_BYTES(HtileCacheBits
) * numPipes
/ elemBits
);
1364 macroOffset
= slice
* (sliceBits
/ numPipes
) * elemBits
;
1367 { //tiled addressing
1368 const UINT_32 macroWidthInTile
= macroWidth
/ MicroTileWidth
; // Now in unit of Tiles
1369 const UINT_32 macroHeightInTile
= macroHeight
/ MicroTileHeight
;
1370 const UINT_32 pitchInCL
= pitchInTile
/ macroWidthInTile
;
1371 const UINT_32 heightInCL
= heightInTile
/ macroHeightInTile
;
1373 const UINT_32 macroX
= x
/ macroWidth
;
1374 const UINT_32 macroY
= y
/ macroHeight
;
1375 const UINT_32 macroNumber
= macroX
+ macroY
* pitchInCL
+ slice
* pitchInCL
* heightInCL
;
1377 // Per pipe starting offset of the cache line in which this tile lies.
1378 microX
= (x
% macroWidth
) / MicroTileWidth
/ 4; // Macro Tile is 4x4
1379 microY
= (y
% macroHeight
) / MicroTileHeight
/ 4 ;
1380 microNumber
= static_cast<UINT_64
>(microX
+ microY
* (macroWidth
/ MicroTileWidth
/ 4)) << microShift
;
1382 macroOffset
= macroNumber
* tileNumPerPipe
* elemBits
;
1385 if(elemIdxBits
== microShift
)
1387 microNumber
+= elemIdx
;
1391 microNumber
>>= elemIdxBits
;
1392 microNumber
<<= elemIdxBits
;
1393 microNumber
+= elemIdx
;
1396 microOffset
= elemBits
* microNumber
;
1397 totalOffset
= microOffset
+ macroOffset
;
1399 UINT_32 pipe
= ComputePipeFromCoord(x
, y
, 0, ADDR_TM_2D_TILED_THIN1
, 0, FALSE
, pTileInfo
);
1400 UINT_64 addrInBits
= totalOffset
% (m_pipeInterleaveBytes
* 8) +
1401 pipe
* (m_pipeInterleaveBytes
* 8) +
1402 totalOffset
/ (m_pipeInterleaveBytes
* 8) * (m_pipeInterleaveBytes
* 8) * numPipes
;
1403 *pBitPosition
= static_cast<UINT_32
>(addrInBits
) % 8;
1404 UINT_64 addr
= addrInBits
/ 8;
1410 ****************************************************************************************************
1411 * SiLib::HwlComputeXmaskCoordFromAddr
1414 * Compute the coord from an address of a cmask/htile
1420 * This method is reused by htile, so rename to Xmask
1421 ****************************************************************************************************
1423 VOID
SiLib::HwlComputeXmaskCoordFromAddr(
1424 UINT_64 addr
, ///< [in] address
1425 UINT_32 bitPosition
, ///< [in] bitPosition in a byte
1426 UINT_32 pitch
, ///< [in] pitch
1427 UINT_32 height
, ///< [in] height
1428 UINT_32 numSlices
, ///< [in] number of slices
1429 UINT_32 factor
, ///< [in] factor that indicates cmask or htile
1430 BOOL_32 isLinear
, ///< [in] linear or tiled HTILE layout
1431 BOOL_32 isWidth8
, ///< [in] Not used by SI
1432 BOOL_32 isHeight8
, ///< [in] Not used by SI
1433 ADDR_TILEINFO
* pTileInfo
, ///< [in] Tile info
1434 UINT_32
* pX
, ///< [out] x coord
1435 UINT_32
* pY
, ///< [out] y coord
1436 UINT_32
* pSlice
///< [out] slice index
1444 UINT_32 tileNumPerPipe
;
1451 if (factor
== 2) //CMASK
1453 ADDR_CMASK_FLAGS flags
= {{0}};
1455 tileNumPerPipe
= 256;
1457 ComputeCmaskInfo(flags
,
1471 ADDR_HTILE_FLAGS flags
= {{0}};
1473 tileNumPerPipe
= 512;
1475 ComputeHtileInfo(flags
,
1491 const UINT_32 pitchInTile
= newPitch
/ MicroTileWidth
;
1492 const UINT_32 heightInTile
= newHeight
/ MicroTileWidth
;
1493 const UINT_32 pitchInMacroTile
= pitchInTile
/ 4;
1495 UINT_32 elemIdxBits
;
1496 // get macroShift and elemIdxBits
1497 TileCoordToMaskElementIndex(0, 0, pTileInfo
->pipeConfig
, ¯oShift
, &elemIdxBits
);
1499 const UINT_32 numPipes
= HwlGetPipes(pTileInfo
);
1500 const UINT_32 pipe
= (UINT_32
)((addr
/ m_pipeInterleaveBytes
) % numPipes
);
1502 UINT_64 localOffset
= (addr
% m_pipeInterleaveBytes
) +
1503 (addr
/ m_pipeInterleaveBytes
/ numPipes
)* m_pipeInterleaveBytes
;
1506 if (factor
== 2) //CMASK
1508 tileIndex
= (UINT_32
)(localOffset
* 2 + (bitPosition
!= 0));
1512 tileIndex
= (UINT_32
)(localOffset
/ 4);
1515 UINT_32 macroOffset
;
1518 UINT_32 sliceSizeInTile
= pitchInTile
* heightInTile
;
1520 // do htile single slice alignment if the flag is true
1521 if (m_configFlags
.useHtileSliceAlign
&& (factor
== 1)) //Htile
1523 sliceSizeInTile
= PowTwoAlign(sliceSizeInTile
, static_cast<UINT_32
>(sliceBytes
) / 64);
1525 *pSlice
= tileIndex
/ (sliceSizeInTile
/ numPipes
);
1526 macroOffset
= tileIndex
% (sliceSizeInTile
/ numPipes
);
1530 const UINT_32 clWidthInTile
= clWidth
/ MicroTileWidth
; // Now in unit of Tiles
1531 const UINT_32 clHeightInTile
= clHeight
/ MicroTileHeight
;
1532 const UINT_32 pitchInCL
= pitchInTile
/ clWidthInTile
;
1533 const UINT_32 heightInCL
= heightInTile
/ clHeightInTile
;
1534 const UINT_32 clIndex
= tileIndex
/ tileNumPerPipe
;
1536 UINT_32 clX
= clIndex
% pitchInCL
;
1537 UINT_32 clY
= (clIndex
% (heightInCL
* pitchInCL
)) / pitchInCL
;
1539 *pX
= clX
* clWidthInTile
* MicroTileWidth
;
1540 *pY
= clY
* clHeightInTile
* MicroTileHeight
;
1541 *pSlice
= clIndex
/ (heightInCL
* pitchInCL
);
1543 macroOffset
= tileIndex
% tileNumPerPipe
;
1546 UINT_32 elemIdx
= macroOffset
& 7;
1547 macroOffset
>>= elemIdxBits
;
1549 if (elemIdxBits
!= macroShift
)
1551 macroOffset
<<= (elemIdxBits
- macroShift
);
1553 UINT_32 pipebit1
= _BIT(pipe
,1);
1554 UINT_32 pipebit2
= _BIT(pipe
,2);
1555 UINT_32 pipebit3
= _BIT(pipe
,3);
1556 if (pitchInMacroTile
% 2)
1558 switch (pTileInfo
->pipeConfig
)
1560 case ADDR_PIPECFG_P4_32x32
:
1561 macroOffset
|= pipebit1
;
1563 case ADDR_PIPECFG_P8_32x32_8x16
:
1564 case ADDR_PIPECFG_P8_32x32_16x16
:
1565 case ADDR_PIPECFG_P8_32x32_16x32
:
1566 macroOffset
|= pipebit2
;
1574 if (pitchInMacroTile
% 4)
1576 if (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
)
1578 macroOffset
|= (pipebit1
<<1);
1580 if((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P16_32x32_8x16
) ||
1581 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P16_32x32_16x16
))
1583 macroOffset
|= (pipebit3
<<1);
1593 macroX
= macroOffset
% pitchInMacroTile
;
1594 macroY
= macroOffset
/ pitchInMacroTile
;
1598 const UINT_32 clWidthInMacroTile
= clWidth
/ (MicroTileWidth
* 4);
1599 macroX
= macroOffset
% clWidthInMacroTile
;
1600 macroY
= macroOffset
/ clWidthInMacroTile
;
1603 *pX
+= macroX
* 4 * MicroTileWidth
;
1604 *pY
+= macroY
* 4 * MicroTileHeight
;
1608 ComputeTileCoordFromPipeAndElemIdx(elemIdx
, pipe
, pTileInfo
->pipeConfig
, pitchInMacroTile
,
1609 *pX
, *pY
, µX
, µY
);
1611 *pX
+= microX
* MicroTileWidth
;
1612 *pY
+= microY
* MicroTileWidth
;
1616 ****************************************************************************************************
1617 * SiLib::HwlGetPitchAlignmentLinear
1619 * Get pitch alignment
1622 ****************************************************************************************************
1624 UINT_32
SiLib::HwlGetPitchAlignmentLinear(
1625 UINT_32 bpp
, ///< [in] bits per pixel
1626 ADDR_SURFACE_FLAGS flags
///< [in] surface flags
1631 // Interleaved access requires a 256B aligned pitch, so fall back to pre-SI alignment
1632 if (flags
.interleaved
)
1634 pitchAlign
= Max(64u, m_pipeInterleaveBytes
/ BITS_TO_BYTES(bpp
));
1639 pitchAlign
= Max(8u, 64 / BITS_TO_BYTES(bpp
));
1646 ****************************************************************************************************
1647 * SiLib::HwlGetSizeAdjustmentLinear
1650 * Adjust linear surface pitch and slice size
1653 * Logical slice size in bytes
1654 ****************************************************************************************************
1656 UINT_64
SiLib::HwlGetSizeAdjustmentLinear(
1657 AddrTileMode tileMode
, ///< [in] tile mode
1658 UINT_32 bpp
, ///< [in] bits per pixel
1659 UINT_32 numSamples
, ///< [in] number of samples
1660 UINT_32 baseAlign
, ///< [in] base alignment
1661 UINT_32 pitchAlign
, ///< [in] pitch alignment
1662 UINT_32
* pPitch
, ///< [in,out] pointer to pitch
1663 UINT_32
* pHeight
, ///< [in,out] pointer to height
1664 UINT_32
* pHeightAlign
///< [in,out] pointer to height align
1668 if (tileMode
== ADDR_TM_LINEAR_GENERAL
)
1670 sliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(*pPitch
) * (*pHeight
) * bpp
* numSamples
);
1674 UINT_32 pitch
= *pPitch
;
1675 UINT_32 height
= *pHeight
;
1677 UINT_32 pixelsPerPipeInterleave
= m_pipeInterleaveBytes
/ BITS_TO_BYTES(bpp
);
1678 UINT_32 sliceAlignInPixel
= pixelsPerPipeInterleave
< 64 ? 64 : pixelsPerPipeInterleave
;
1680 // numSamples should be 1 in real cases (no MSAA for linear but TGL may pass non 1 value)
1681 UINT_64 pixelPerSlice
= static_cast<UINT_64
>(pitch
) * height
* numSamples
;
1683 while (pixelPerSlice
% sliceAlignInPixel
)
1685 pitch
+= pitchAlign
;
1686 pixelPerSlice
= static_cast<UINT_64
>(pitch
) * height
* numSamples
;
1691 UINT_32 heightAlign
= 1;
1693 while ((pitch
* heightAlign
) % sliceAlignInPixel
)
1698 *pHeightAlign
= heightAlign
;
1700 sliceSize
= BITS_TO_BYTES(pixelPerSlice
* bpp
);
1707 ****************************************************************************************************
1708 * SiLib::HwlPreHandleBaseLvl3xPitch
1711 * Pre-handler of 3x pitch (96 bit) adjustment
1715 ****************************************************************************************************
1717 UINT_32
SiLib::HwlPreHandleBaseLvl3xPitch(
1718 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
1719 UINT_32 expPitch
///< [in] pitch
1722 ADDR_ASSERT(pIn
->width
== expPitch
);
1724 // From SI, if pow2Pad is 1 the pitch is expanded 3x first, then padded to pow2, so nothing to
1726 if (pIn
->flags
.pow2Pad
== FALSE
)
1728 Addr::V1::Lib::HwlPreHandleBaseLvl3xPitch(pIn
, expPitch
);
1732 ADDR_ASSERT(IsPow2(expPitch
));
1739 ****************************************************************************************************
1740 * SiLib::HwlPostHandleBaseLvl3xPitch
1743 * Post-handler of 3x pitch adjustment
1747 ****************************************************************************************************
1749 UINT_32
SiLib::HwlPostHandleBaseLvl3xPitch(
1750 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input
1751 UINT_32 expPitch
///< [in] pitch
1755 * @note The pitch will be divided by 3 in the end so the value will look odd but h/w should
1756 * be able to compute a correct pitch from it as h/w address library is doing the job.
1758 // From SI, the pitch is expanded 3x first, then padded to pow2, so no special handler here
1759 if (pIn
->flags
.pow2Pad
== FALSE
)
1761 Addr::V1::Lib::HwlPostHandleBaseLvl3xPitch(pIn
, expPitch
);
1768 ****************************************************************************************************
1769 * SiLib::HwlGetPitchAlignmentMicroTiled
1772 * Compute 1D tiled surface pitch alignment
1776 ****************************************************************************************************
1778 UINT_32
SiLib::HwlGetPitchAlignmentMicroTiled(
1779 AddrTileMode tileMode
, ///< [in] tile mode
1780 UINT_32 bpp
, ///< [in] bits per pixel
1781 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
1782 UINT_32 numSamples
///< [in] number of samples
1789 pitchAlign
= EgBasedLib::HwlGetPitchAlignmentMicroTiled(tileMode
,bpp
,flags
,numSamples
);
1800 ****************************************************************************************************
1801 * SiLib::HwlGetSizeAdjustmentMicroTiled
1804 * Adjust 1D tiled surface pitch and slice size
1807 * Logical slice size in bytes
1808 ****************************************************************************************************
1810 UINT_64
SiLib::HwlGetSizeAdjustmentMicroTiled(
1811 UINT_32 thickness
, ///< [in] thickness
1812 UINT_32 bpp
, ///< [in] bits per pixel
1813 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
1814 UINT_32 numSamples
, ///< [in] number of samples
1815 UINT_32 baseAlign
, ///< [in] base alignment
1816 UINT_32 pitchAlign
, ///< [in] pitch alignment
1817 UINT_32
* pPitch
, ///< [in,out] pointer to pitch
1818 UINT_32
* pHeight
///< [in,out] pointer to height
1821 UINT_64 logicalSliceSize
;
1822 UINT_64 physicalSliceSize
;
1824 UINT_32 pitch
= *pPitch
;
1825 UINT_32 height
= *pHeight
;
1827 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
1828 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
1830 // Physical slice: multiplied by thickness
1831 physicalSliceSize
= logicalSliceSize
* thickness
;
1833 // Pitch alignment is always 8, so if slice size is not padded to base alignment
1834 // (pipe_interleave_size), we need to increase pitch
1835 while ((physicalSliceSize
% baseAlign
) != 0)
1837 pitch
+= pitchAlign
;
1839 logicalSliceSize
= BITS_TO_BYTES(static_cast<UINT_64
>(pitch
) * height
* bpp
* numSamples
);
1841 physicalSliceSize
= logicalSliceSize
* thickness
;
1846 // Special workaround for depth/stencil buffer, use 8 bpp to align depth buffer again since
1847 // the stencil plane may have larger pitch if the slice size is smaller than base alignment.
1849 // Note: this actually does not work for mipmap but mipmap depth texture is not really
1850 // sampled with mipmap.
1852 if (flags
.depth
&& (flags
.noStencil
== FALSE
))
1854 ADDR_ASSERT(numSamples
== 1);
1856 UINT_64 logicalSiceSizeStencil
= static_cast<UINT_64
>(pitch
) * height
; // 1 byte stencil
1858 while ((logicalSiceSizeStencil
% baseAlign
) != 0)
1860 pitch
+= pitchAlign
; // Stencil plane's pitch alignment is the same as depth plane's
1862 logicalSiceSizeStencil
= static_cast<UINT_64
>(pitch
) * height
;
1865 if (pitch
!= *pPitch
)
1867 // If this is a mipmap, this padded one cannot be sampled as a whole mipmap!
1868 logicalSliceSize
= logicalSiceSizeStencil
* BITS_TO_BYTES(bpp
);
1874 // No adjust for pHeight
1876 return logicalSliceSize
;
1880 ****************************************************************************************************
1881 * SiLib::HwlConvertChipFamily
1884 * Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
1887 ****************************************************************************************************
1889 ChipFamily
SiLib::HwlConvertChipFamily(
1890 UINT_32 uChipFamily
, ///< [in] chip family defined in atiih.h
1891 UINT_32 uChipRevision
) ///< [in] chip revision defined in "asic_family"_id.h
1893 ChipFamily family
= ADDR_CHIP_FAMILY_SI
;
1895 switch (uChipFamily
)
1898 m_settings
.isSouthernIsland
= 1;
1899 m_settings
.isTahiti
= ASICREV_IS_TAHITI_P(uChipRevision
);
1900 m_settings
.isPitCairn
= ASICREV_IS_PITCAIRN_PM(uChipRevision
);
1901 m_settings
.isCapeVerde
= ASICREV_IS_CAPEVERDE_M(uChipRevision
);
1902 m_settings
.isOland
= ASICREV_IS_OLAND_M(uChipRevision
);
1903 m_settings
.isHainan
= ASICREV_IS_HAINAN_V(uChipRevision
);
1906 ADDR_ASSERT(!"This should be a Fusion");
1914 ****************************************************************************************************
1915 * SiLib::HwlSetupTileInfo
1918 * Setup default value of tile info for SI
1919 ****************************************************************************************************
1921 VOID
SiLib::HwlSetupTileInfo(
1922 AddrTileMode tileMode
, ///< [in] Tile mode
1923 ADDR_SURFACE_FLAGS flags
, ///< [in] Surface type flags
1924 UINT_32 bpp
, ///< [in] Bits per pixel
1925 UINT_32 pitch
, ///< [in] Pitch in pixels
1926 UINT_32 height
, ///< [in] Height in pixels
1927 UINT_32 numSamples
, ///< [in] Number of samples
1928 ADDR_TILEINFO
* pTileInfoIn
, ///< [in] Tile info input: NULL for default
1929 ADDR_TILEINFO
* pTileInfoOut
, ///< [out] Tile info output
1930 AddrTileType inTileType
, ///< [in] Tile type
1931 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] Output
1934 UINT_32 thickness
= Thickness(tileMode
);
1935 ADDR_TILEINFO
* pTileInfo
= pTileInfoOut
;
1936 INT index
= TileIndexInvalid
;
1939 if (IsLinear(tileMode
) == FALSE
)
1941 // 128 bpp/thick tiling must be non-displayable.
1942 // Fmask reuse color buffer's entry but bank-height field can be from another entry
1943 // To simplify the logic, fmask entry should be picked from non-displayable ones
1944 if (bpp
== 128 || thickness
> 1 || flags
.fmask
|| flags
.prt
)
1946 inTileType
= ADDR_NON_DISPLAYABLE
;
1949 if (flags
.depth
|| flags
.stencil
)
1951 inTileType
= ADDR_DEPTH_SAMPLE_ORDER
;
1955 // Partial valid fields are not allowed for SI.
1956 if (IsTileInfoAllZero(pTileInfo
))
1958 if (IsMacroTiled(tileMode
))
1962 if (numSamples
== 1)
1975 ADDR_ASSERT_ALWAYS();
2004 ADDR_ASSERT(bpp
!= 128);
2011 ADDR_ASSERT(numSamples
== 4);
2024 ADDR_ASSERT_ALWAYS();
2045 ADDR_ASSERT_ALWAYS();
2051 // See table entries 0-7
2052 else if (flags
.depth
|| flags
.stencil
)
2054 if (flags
.compressZ
)
2062 // optimal tile index for compressed depth/stencil.
2085 else //non PRT & non Depth & non Stencil
2087 // See table entries 9-12
2088 if (inTileType
== ADDR_DISPLAYABLE
)
2110 // See table entries 13-17
2115 UINT_32 fmaskPixelSize
= bpp
* numSamples
;
2117 switch (fmaskPixelSize
)
2132 ADDR_ASSERT_ALWAYS();
2159 else // thick tiling - entries 18-20
2178 if (tileMode
== ADDR_TM_LINEAR_ALIGNED
)
2182 else if (tileMode
== ADDR_TM_LINEAR_GENERAL
)
2184 index
= TileIndexLinearGeneral
;
2188 if (flags
.depth
|| flags
.stencil
)
2192 else if (inTileType
== ADDR_DISPLAYABLE
)
2196 else if (thickness
== 1)
2207 if (index
>= 0 && index
<= 31)
2209 *pTileInfo
= m_tileTable
[index
].info
;
2210 pOut
->tileType
= m_tileTable
[index
].type
;
2213 if (index
== TileIndexLinearGeneral
)
2215 *pTileInfo
= m_tileTable
[8].info
;
2216 pOut
->tileType
= m_tileTable
[8].type
;
2223 if (flags
.stencil
&& pTileInfoIn
->tileSplitBytes
== 0)
2225 // Stencil always uses index 0
2226 *pTileInfo
= m_tileTable
[0].info
;
2229 // Pass through tile type
2230 pOut
->tileType
= inTileType
;
2233 pOut
->tileIndex
= index
;
2234 pOut
->prtTileIndex
= flags
.prt
;
2238 ****************************************************************************************************
2239 * SiLib::DecodeGbRegs
2242 * Decodes GB_ADDR_CONFIG and noOfBanks/noOfRanks
2245 * TRUE if all settings are valid
2247 ****************************************************************************************************
2249 BOOL_32
SiLib::DecodeGbRegs(
2250 const ADDR_REGISTER_VALUE
* pRegValue
) ///< [in] create input
2253 BOOL_32 valid
= TRUE
;
2255 reg
.val
= pRegValue
->gbAddrConfig
;
2257 switch (reg
.f
.pipe_interleave_size
)
2259 case ADDR_CONFIG_PIPE_INTERLEAVE_256B
:
2260 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_256B
;
2262 case ADDR_CONFIG_PIPE_INTERLEAVE_512B
:
2263 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_512B
;
2267 ADDR_UNHANDLED_CASE();
2271 switch (reg
.f
.row_size
)
2273 case ADDR_CONFIG_1KB_ROW
:
2274 m_rowSize
= ADDR_ROWSIZE_1KB
;
2276 case ADDR_CONFIG_2KB_ROW
:
2277 m_rowSize
= ADDR_ROWSIZE_2KB
;
2279 case ADDR_CONFIG_4KB_ROW
:
2280 m_rowSize
= ADDR_ROWSIZE_4KB
;
2284 ADDR_UNHANDLED_CASE();
2288 switch (pRegValue
->noOfBanks
)
2301 ADDR_UNHANDLED_CASE();
2305 switch (pRegValue
->noOfRanks
)
2315 ADDR_UNHANDLED_CASE();
2319 m_logicalBanks
= m_banks
* m_ranks
;
2321 ADDR_ASSERT(m_logicalBanks
<= 16);
2327 ****************************************************************************************************
2328 * SiLib::HwlInitGlobalParams
2331 * Initializes global parameters
2334 * TRUE if all settings are valid
2336 ****************************************************************************************************
2338 BOOL_32
SiLib::HwlInitGlobalParams(
2339 const ADDR_CREATE_INPUT
* pCreateIn
) ///< [in] create input
2341 BOOL_32 valid
= TRUE
;
2342 const ADDR_REGISTER_VALUE
* pRegValue
= &pCreateIn
->regValue
;
2344 valid
= DecodeGbRegs(pRegValue
);
2348 if (m_settings
.isTahiti
|| m_settings
.isPitCairn
)
2352 else if (m_settings
.isCapeVerde
|| m_settings
.isOland
)
2358 // Hainan is 2-pipe (m_settings.isHainan == 1)
2362 valid
= InitTileSettingTable(pRegValue
->pTileConfig
, pRegValue
->noOfEntries
);
2366 InitEquationTable();
2376 ****************************************************************************************************
2377 * SiLib::HwlConvertTileInfoToHW
2379 * Entry of si's ConvertTileInfoToHW
2382 ****************************************************************************************************
2384 ADDR_E_RETURNCODE
SiLib::HwlConvertTileInfoToHW(
2385 const ADDR_CONVERT_TILEINFOTOHW_INPUT
* pIn
, ///< [in] input structure
2386 ADDR_CONVERT_TILEINFOTOHW_OUTPUT
* pOut
///< [out] output structure
2389 ADDR_E_RETURNCODE retCode
= ADDR_OK
;
2391 retCode
= EgBasedLib::HwlConvertTileInfoToHW(pIn
, pOut
);
2393 if (retCode
== ADDR_OK
)
2395 if (pIn
->reverse
== FALSE
)
2397 if (pIn
->pTileInfo
->pipeConfig
== ADDR_PIPECFG_INVALID
)
2399 retCode
= ADDR_INVALIDPARAMS
;
2403 pOut
->pTileInfo
->pipeConfig
=
2404 static_cast<AddrPipeCfg
>(pIn
->pTileInfo
->pipeConfig
- 1);
2409 pOut
->pTileInfo
->pipeConfig
=
2410 static_cast<AddrPipeCfg
>(pIn
->pTileInfo
->pipeConfig
+ 1);
2418 ****************************************************************************************************
2419 * SiLib::HwlComputeXmaskCoordYFrom8Pipe
2422 * Compute the Y coord which will be added to Xmask Y
2426 ****************************************************************************************************
2428 UINT_32
SiLib::HwlComputeXmaskCoordYFrom8Pipe(
2429 UINT_32 pipe
, ///< [in] pipe id
2430 UINT_32 x
///< [in] tile coord x, which is original x coord / 8
2433 // This function should never be called since it is 6xx/8xx specfic.
2434 // Keep this empty implementation to avoid any mis-use.
2435 ADDR_ASSERT_ALWAYS();
2441 ****************************************************************************************************
2442 * SiLib::HwlComputeSurfaceCoord2DFromBankPipe
2445 * Compute surface x,y coordinates from bank/pipe info
2448 ****************************************************************************************************
2450 VOID
SiLib::HwlComputeSurfaceCoord2DFromBankPipe(
2451 AddrTileMode tileMode
, ///< [in] tile mode
2452 UINT_32
* pX
, ///< [in,out] x coordinate
2453 UINT_32
* pY
, ///< [in,out] y coordinate
2454 UINT_32 slice
, ///< [in] slice index
2455 UINT_32 bank
, ///< [in] bank number
2456 UINT_32 pipe
, ///< [in] pipe number
2457 UINT_32 bankSwizzle
,///< [in] bank swizzle
2458 UINT_32 pipeSwizzle
,///< [in] pipe swizzle
2459 UINT_32 tileSlices
, ///< [in] slices in a micro tile
2460 BOOL_32 ignoreSE
, ///< [in] TRUE if shader engines are ignored
2461 ADDR_TILEINFO
* pTileInfo
///< [in] bank structure. **All fields to be valid on entry**
2475 UINT_32 numPipes
= GetPipePerSurf(pTileInfo
->pipeConfig
);
2477 CoordFromBankPipe xyBits
= {0};
2478 ComputeSurfaceCoord2DFromBankPipe(tileMode
, *pX
, *pY
, slice
, bank
, pipe
,
2479 bankSwizzle
, pipeSwizzle
, tileSlices
, pTileInfo
,
2481 yBit3
= xyBits
.yBit3
;
2482 yBit4
= xyBits
.yBit4
;
2483 yBit5
= xyBits
.yBit5
;
2484 yBit6
= xyBits
.yBit6
;
2486 xBit3
= xyBits
.xBit3
;
2487 xBit4
= xyBits
.xBit4
;
2488 xBit5
= xyBits
.xBit5
;
2490 yBit
= xyBits
.yBits
;
2492 UINT_32 yBitTemp
= 0;
2494 if ((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P4_32x32
) ||
2495 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
))
2497 ADDR_ASSERT(pTileInfo
->bankWidth
== 1 && pTileInfo
->macroAspectRatio
> 1);
2498 UINT_32 yBitToCheck
= QLog2(pTileInfo
->banks
) - 1;
2500 ADDR_ASSERT(yBitToCheck
<= 3);
2502 yBitTemp
= _BIT(yBit
, yBitToCheck
);
2507 yBit
= Bits2Number(4, yBit6
, yBit5
, yBit4
, yBit3
);
2508 xBit
= Bits2Number(3, xBit5
, xBit4
, xBit3
);
2510 *pY
+= yBit
* pTileInfo
->bankHeight
* MicroTileHeight
;
2511 *pX
+= xBit
* numPipes
* pTileInfo
->bankWidth
* MicroTileWidth
;
2513 //calculate the bank and pipe bits in x, y
2514 UINT_32 xTile
; //x in micro tile
2521 UINT_32 pipeBit0
= _BIT(pipe
,0);
2522 UINT_32 pipeBit1
= _BIT(pipe
,1);
2523 UINT_32 pipeBit2
= _BIT(pipe
,2);
2525 UINT_32 y3
= _BIT(y
, 3);
2526 UINT_32 y4
= _BIT(y
, 4);
2527 UINT_32 y5
= _BIT(y
, 5);
2528 UINT_32 y6
= _BIT(y
, 6);
2530 // bankbit0 after ^x4^x5
2531 UINT_32 bankBit00
= _BIT(bank
,0);
2532 UINT_32 bankBit0
= 0;
2534 switch (pTileInfo
->pipeConfig
)
2536 case ADDR_PIPECFG_P2
:
2539 case ADDR_PIPECFG_P4_8x16
:
2543 case ADDR_PIPECFG_P4_16x16
:
2545 x3
= pipeBit0
^ y3
^ x4
;
2547 case ADDR_PIPECFG_P4_16x32
:
2549 x3
= pipeBit0
^ y3
^ x4
;
2551 case ADDR_PIPECFG_P4_32x32
:
2553 x3
= pipeBit0
^ y3
^ x5
;
2554 bankBit0
= yBitTemp
^ x5
;
2555 x4
= bankBit00
^ x5
^ bankBit0
;
2556 *pX
+= x5
* 4 * 1 * 8; // x5 * num_pipes * bank_width * 8;
2558 case ADDR_PIPECFG_P8_16x16_8x16
:
2561 x5
= pipeBit0
^ y3
^ x4
;
2563 case ADDR_PIPECFG_P8_16x32_8x16
:
2566 x5
= pipeBit0
^ y3
^ x4
;
2568 case ADDR_PIPECFG_P8_32x32_8x16
:
2571 x4
= pipeBit0
^ y3
^ x5
;
2573 case ADDR_PIPECFG_P8_16x32_16x16
:
2576 x3
= pipeBit0
^ y3
^ x4
;
2578 case ADDR_PIPECFG_P8_32x32_16x16
:
2581 x3
= pipeBit0
^ y3
^ x4
;
2583 case ADDR_PIPECFG_P8_32x32_16x32
:
2586 x3
= pipeBit0
^ y3
^ x4
;
2588 case ADDR_PIPECFG_P8_32x64_32x32
:
2591 x3
= pipeBit0
^ y3
^ x5
;
2592 bankBit0
= yBitTemp
^ x6
;
2593 x4
= bankBit00
^ x5
^ bankBit0
;
2594 *pX
+= x6
* 8 * 1 * 8; // x6 * num_pipes * bank_width * 8;
2597 ADDR_ASSERT_ALWAYS();
2600 xTile
= Bits2Number(3, x5
, x4
, x3
);
2606 ****************************************************************************************************
2607 * SiLib::HwlPreAdjustBank
2610 * Adjust bank before calculating address acoording to bank/pipe
2613 ****************************************************************************************************
2615 UINT_32
SiLib::HwlPreAdjustBank(
2616 UINT_32 tileX
, ///< [in] x coordinate in unit of tile
2617 UINT_32 bank
, ///< [in] bank
2618 ADDR_TILEINFO
* pTileInfo
///< [in] tile info
2621 if (((pTileInfo
->pipeConfig
== ADDR_PIPECFG_P4_32x32
) ||
2622 (pTileInfo
->pipeConfig
== ADDR_PIPECFG_P8_32x64_32x32
)) && (pTileInfo
->bankWidth
== 1))
2624 UINT_32 bankBit0
= _BIT(bank
, 0);
2625 UINT_32 x4
= _BIT(tileX
, 1);
2626 UINT_32 x5
= _BIT(tileX
, 2);
2628 bankBit0
= bankBit0
^ x4
^ x5
;
2631 ADDR_ASSERT(pTileInfo
->macroAspectRatio
> 1);
2638 ****************************************************************************************************
2639 * SiLib::HwlComputeSurfaceInfo
2642 * Entry of si's ComputeSurfaceInfo
2645 ****************************************************************************************************
2647 ADDR_E_RETURNCODE
SiLib::HwlComputeSurfaceInfo(
2648 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
2649 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
2652 pOut
->tileIndex
= pIn
->tileIndex
;
2654 ADDR_E_RETURNCODE retCode
= EgBasedLib::HwlComputeSurfaceInfo(pIn
, pOut
);
2656 UINT_32 tileIndex
= static_cast<UINT_32
>(pOut
->tileIndex
);
2658 if (((pIn
->flags
.needEquation
== TRUE
) ||
2659 (pIn
->flags
.preferEquation
== TRUE
)) &&
2660 (pIn
->numSamples
<= 1) &&
2661 (tileIndex
< TileTableSize
))
2663 static const UINT_32 SiUncompressDepthTileIndex
= 3;
2665 if ((pIn
->numSlices
> 1) &&
2666 (IsMacroTiled(pOut
->tileMode
) == TRUE
) &&
2667 (m_chipFamily
== ADDR_CHIP_FAMILY_SI
))
2669 pOut
->equationIndex
= ADDR_INVALID_EQUATION_INDEX
;
2671 else if ((pIn
->flags
.prt
== FALSE
) &&
2672 (m_uncompressDepthEqIndex
!= 0) &&
2673 (tileIndex
== SiUncompressDepthTileIndex
))
2675 pOut
->equationIndex
= m_uncompressDepthEqIndex
+ Log2(pIn
->bpp
>> 3);
2680 pOut
->equationIndex
= m_equationLookupTable
[Log2(pIn
->bpp
>> 3)][tileIndex
];
2683 if (pOut
->equationIndex
!= ADDR_INVALID_EQUATION_INDEX
)
2685 pOut
->blockWidth
= m_blockWidth
[pOut
->equationIndex
];
2687 pOut
->blockHeight
= m_blockHeight
[pOut
->equationIndex
];
2689 pOut
->blockSlices
= m_blockSlices
[pOut
->equationIndex
];
2694 pOut
->equationIndex
= ADDR_INVALID_EQUATION_INDEX
;
2701 ****************************************************************************************************
2702 * SiLib::HwlComputeMipLevel
2704 * Compute MipLevel info (including level 0)
2706 * TRUE if HWL's handled
2707 ****************************************************************************************************
2709 BOOL_32
SiLib::HwlComputeMipLevel(
2710 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
///< [in,out] Input structure
2713 // basePitch is calculated from level 0 so we only check this for mipLevel > 0
2714 if (pIn
->mipLevel
> 0)
2716 // Note: Don't check expand 3x formats(96 bit) as the basePitch is not pow2 even if
2717 // we explicity set pow2Pad flag. The 3x base pitch is padded to pow2 but after being
2718 // divided by expandX factor (3) - to program texture pitch, the basePitch is never pow2.
2719 if (ElemLib::IsExpand3x(pIn
->format
) == FALSE
)
2721 // Sublevel pitches are generated from base level pitch instead of width on SI
2722 // If pow2Pad is 0, we don't assert - as this is not really used for a mip chain
2723 ADDR_ASSERT((pIn
->flags
.pow2Pad
== FALSE
) ||
2724 ((pIn
->basePitch
!= 0) && IsPow2(pIn
->basePitch
)));
2727 if (pIn
->basePitch
!= 0)
2729 pIn
->width
= Max(1u, pIn
->basePitch
>> pIn
->mipLevel
);
2733 // pow2Pad is done in PostComputeMipLevel
2739 ****************************************************************************************************
2740 * SiLib::HwlCheckLastMacroTiledLvl
2743 * Sets pOut->last2DLevel to TRUE if it is
2746 ****************************************************************************************************
2748 VOID
SiLib::HwlCheckLastMacroTiledLvl(
2749 const ADDR_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] Input structure
2750 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in,out] Output structure (used as input, too)
2753 // pow2Pad covers all mipmap cases
2754 if (pIn
->flags
.pow2Pad
)
2756 ADDR_ASSERT(IsMacroTiled(pIn
->tileMode
));
2762 AddrTileMode nextTileMode
;
2764 if (pIn
->mipLevel
== 0 || pIn
->basePitch
== 0)
2766 // Base level or fail-safe case (basePitch == 0)
2767 nextPitch
= pOut
->pitch
>> 1;
2772 nextPitch
= pIn
->basePitch
>> (pIn
->mipLevel
+ 1);
2775 // nextHeight must be shifted from this level's original height rather than a pow2 padded
2776 // one but this requires original height stored somewhere (pOut->height)
2777 ADDR_ASSERT(pOut
->height
!= 0);
2779 // next level's height is just current level's >> 1 in pixels
2780 nextHeight
= pOut
->height
>> 1;
2781 // Special format such as FMT_1 and FMT_32_32_32 can be linear only so we consider block
2782 // compressed foramts
2783 if (ElemLib::IsBlockCompressed(pIn
->format
))
2785 nextHeight
= (nextHeight
+ 3) / 4;
2787 nextHeight
= NextPow2(nextHeight
);
2789 // nextSlices may be 0 if this level's is 1
2790 if (pIn
->flags
.volume
)
2792 nextSlices
= Max(1u, pIn
->numSlices
>> 1);
2796 nextSlices
= pIn
->numSlices
;
2799 nextTileMode
= ComputeSurfaceMipLevelTileMode(pIn
->tileMode
,
2809 pOut
->last2DLevel
= IsMicroTiled(nextTileMode
);
2814 ****************************************************************************************************
2815 * SiLib::HwlDegradeThickTileMode
2818 * Degrades valid tile mode for thick modes if needed
2821 * Suitable tile mode
2822 ****************************************************************************************************
2824 AddrTileMode
SiLib::HwlDegradeThickTileMode(
2825 AddrTileMode baseTileMode
, ///< [in] base tile mode
2826 UINT_32 numSlices
, ///< [in] current number of slices
2827 UINT_32
* pBytesPerTile
///< [in,out] pointer to bytes per slice
2830 return EgBasedLib::HwlDegradeThickTileMode(baseTileMode
, numSlices
, pBytesPerTile
);
2834 ****************************************************************************************************
2835 * SiLib::HwlTileInfoEqual
2838 * Return TRUE if all field are equal
2840 * Only takes care of current HWL's data
2841 ****************************************************************************************************
2843 BOOL_32
SiLib::HwlTileInfoEqual(
2844 const ADDR_TILEINFO
* pLeft
, ///<[in] Left compare operand
2845 const ADDR_TILEINFO
* pRight
///<[in] Right compare operand
2848 BOOL_32 equal
= FALSE
;
2850 if (pLeft
->pipeConfig
== pRight
->pipeConfig
)
2852 equal
= EgBasedLib::HwlTileInfoEqual(pLeft
, pRight
);
2859 ****************************************************************************************************
2860 * SiLib::GetTileSettings
2863 * Get tile setting infos by index.
2865 * Tile setting info.
2866 ****************************************************************************************************
2868 const TileConfig
* SiLib::GetTileSetting(
2869 UINT_32 index
///< [in] Tile index
2872 ADDR_ASSERT(index
< m_noOfEntries
);
2873 return &m_tileTable
[index
];
2877 ****************************************************************************************************
2878 * SiLib::HwlPostCheckTileIndex
2881 * Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches
2882 * tile mode/type/info and change the index if needed
2885 ****************************************************************************************************
2887 INT_32
SiLib::HwlPostCheckTileIndex(
2888 const ADDR_TILEINFO
* pInfo
, ///< [in] Tile Info
2889 AddrTileMode mode
, ///< [in] Tile mode
2890 AddrTileType type
, ///< [in] Tile type
2891 INT curIndex
///< [in] Current index assigned in HwlSetupTileInfo
2894 INT_32 index
= curIndex
;
2896 if (mode
== ADDR_TM_LINEAR_GENERAL
)
2898 index
= TileIndexLinearGeneral
;
2902 BOOL_32 macroTiled
= IsMacroTiled(mode
);
2904 // We need to find a new index if either of them is true
2905 // 1. curIndex is invalid
2906 // 2. tile mode is changed
2907 // 3. tile info does not match for macro tiled
2908 if ((index
== TileIndexInvalid
||
2909 (mode
!= m_tileTable
[index
].mode
) ||
2910 (macroTiled
&& (HwlTileInfoEqual(pInfo
, &m_tileTable
[index
].info
) == FALSE
))))
2912 for (index
= 0; index
< static_cast<INT_32
>(m_noOfEntries
); index
++)
2916 // macro tile modes need all to match
2917 if (HwlTileInfoEqual(pInfo
, &m_tileTable
[index
].info
) &&
2918 (mode
== m_tileTable
[index
].mode
) &&
2919 (type
== m_tileTable
[index
].type
))
2924 else if (mode
== ADDR_TM_LINEAR_ALIGNED
)
2926 // linear mode only needs tile mode to match
2927 if (mode
== m_tileTable
[index
].mode
)
2934 // micro tile modes only need tile mode and tile type to match
2935 if (mode
== m_tileTable
[index
].mode
&&
2936 type
== m_tileTable
[index
].type
)
2945 ADDR_ASSERT(index
< static_cast<INT_32
>(m_noOfEntries
));
2947 if (index
>= static_cast<INT_32
>(m_noOfEntries
))
2949 index
= TileIndexInvalid
;
2956 ****************************************************************************************************
2957 * SiLib::HwlSetupTileCfg
2960 * Map tile index to tile setting.
2963 ****************************************************************************************************
2965 ADDR_E_RETURNCODE
SiLib::HwlSetupTileCfg(
2966 UINT_32 bpp
, ///< [in] Bits per pixel
2967 INT_32 index
, ///< [in] Tile index
2968 INT_32 macroModeIndex
, ///< [in] Index in macro tile mode table(CI)
2969 ADDR_TILEINFO
* pInfo
, ///< [out] Tile Info
2970 AddrTileMode
* pMode
, ///< [out] Tile mode
2971 AddrTileType
* pType
///< [out] Tile type
2974 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
2976 // Global flag to control usage of tileIndex
2977 if (UseTileIndex(index
))
2979 if (index
== TileIndexLinearGeneral
)
2983 *pMode
= ADDR_TM_LINEAR_GENERAL
;
2988 *pType
= ADDR_DISPLAYABLE
;
2994 pInfo
->bankWidth
= 1;
2995 pInfo
->bankHeight
= 1;
2996 pInfo
->macroAspectRatio
= 1;
2997 pInfo
->tileSplitBytes
= 64;
2998 pInfo
->pipeConfig
= ADDR_PIPECFG_P2
;
3001 else if (static_cast<UINT_32
>(index
) >= m_noOfEntries
)
3003 returnCode
= ADDR_INVALIDPARAMS
;
3007 const TileConfig
* pCfgTable
= GetTileSetting(index
);
3011 *pInfo
= pCfgTable
->info
;
3015 if (IsMacroTiled(pCfgTable
->mode
))
3017 returnCode
= ADDR_INVALIDPARAMS
;
3023 *pMode
= pCfgTable
->mode
;
3028 *pType
= pCfgTable
->type
;
3037 ****************************************************************************************************
3038 * SiLib::ReadGbTileMode
3041 * Convert GB_TILE_MODE HW value to TileConfig.
3044 ****************************************************************************************************
3046 VOID
SiLib::ReadGbTileMode(
3047 UINT_32 regValue
, ///< [in] GB_TILE_MODE register
3048 TileConfig
* pCfg
///< [out] output structure
3051 GB_TILE_MODE gbTileMode
;
3052 gbTileMode
.val
= regValue
;
3054 pCfg
->type
= static_cast<AddrTileType
>(gbTileMode
.f
.micro_tile_mode
);
3055 pCfg
->info
.bankHeight
= 1 << gbTileMode
.f
.bank_height
;
3056 pCfg
->info
.bankWidth
= 1 << gbTileMode
.f
.bank_width
;
3057 pCfg
->info
.banks
= 1 << (gbTileMode
.f
.num_banks
+ 1);
3058 pCfg
->info
.macroAspectRatio
= 1 << gbTileMode
.f
.macro_tile_aspect
;
3059 pCfg
->info
.tileSplitBytes
= 64 << gbTileMode
.f
.tile_split
;
3060 pCfg
->info
.pipeConfig
= static_cast<AddrPipeCfg
>(gbTileMode
.f
.pipe_config
+ 1);
3062 UINT_32 regArrayMode
= gbTileMode
.f
.array_mode
;
3064 pCfg
->mode
= static_cast<AddrTileMode
>(regArrayMode
);
3066 if (regArrayMode
== 8) //ARRAY_2D_TILED_XTHICK
3068 pCfg
->mode
= ADDR_TM_2D_TILED_XTHICK
;
3070 else if (regArrayMode
>= 14) //ARRAY_3D_TILED_XTHICK
3072 pCfg
->mode
= static_cast<AddrTileMode
>(pCfg
->mode
+ 3);
3077 ****************************************************************************************************
3078 * SiLib::InitTileSettingTable
3081 * Initialize the ADDR_TILE_CONFIG table.
3083 * TRUE if tile table is correctly initialized
3084 ****************************************************************************************************
3086 BOOL_32
SiLib::InitTileSettingTable(
3087 const UINT_32
* pCfg
, ///< [in] Pointer to table of tile configs
3088 UINT_32 noOfEntries
///< [in] Numbe of entries in the table above
3091 BOOL_32 initOk
= TRUE
;
3093 ADDR_ASSERT(noOfEntries
<= TileTableSize
);
3095 memset(m_tileTable
, 0, sizeof(m_tileTable
));
3097 if (noOfEntries
!= 0)
3099 m_noOfEntries
= noOfEntries
;
3103 m_noOfEntries
= TileTableSize
;
3106 if (pCfg
) // From Client
3108 for (UINT_32 i
= 0; i
< m_noOfEntries
; i
++)
3110 ReadGbTileMode(*(pCfg
+ i
), &m_tileTable
[i
]);
3115 ADDR_ASSERT_ALWAYS();
3121 ADDR_ASSERT(m_tileTable
[TILEINDEX_LINEAR_ALIGNED
].mode
== ADDR_TM_LINEAR_ALIGNED
);
3128 ****************************************************************************************************
3129 * SiLib::HwlGetTileIndex
3132 * Return the virtual/real index for given mode/type/info
3134 * ADDR_OK if successful.
3135 ****************************************************************************************************
3137 ADDR_E_RETURNCODE
SiLib::HwlGetTileIndex(
3138 const ADDR_GET_TILEINDEX_INPUT
* pIn
,
3139 ADDR_GET_TILEINDEX_OUTPUT
* pOut
) const
3141 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
3143 pOut
->index
= HwlPostCheckTileIndex(pIn
->pTileInfo
, pIn
->tileMode
, pIn
->tileType
);
3149 ****************************************************************************************************
3150 * SiLib::HwlFmaskPreThunkSurfInfo
3153 * Some preparation before thunking a ComputeSurfaceInfo call for Fmask
3156 ****************************************************************************************************
3158 VOID
SiLib::HwlFmaskPreThunkSurfInfo(
3159 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pFmaskIn
, ///< [in] Input of fmask info
3160 const ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pFmaskOut
, ///< [in] Output of fmask info
3161 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pSurfIn
, ///< [out] Input of thunked surface info
3162 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pSurfOut
///< [out] Output of thunked surface info
3165 pSurfIn
->tileIndex
= pFmaskIn
->tileIndex
;
3169 ****************************************************************************************************
3170 * SiLib::HwlFmaskPostThunkSurfInfo
3173 * Copy hwl extra field after calling thunked ComputeSurfaceInfo
3176 ****************************************************************************************************
3178 VOID
SiLib::HwlFmaskPostThunkSurfInfo(
3179 const ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pSurfOut
, ///< [in] Output of surface info
3180 ADDR_COMPUTE_FMASK_INFO_OUTPUT
* pFmaskOut
///< [out] Output of fmask info
3183 pFmaskOut
->macroModeIndex
= TileIndexInvalid
;
3184 pFmaskOut
->tileIndex
= pSurfOut
->tileIndex
;
3188 ****************************************************************************************************
3189 * SiLib::HwlComputeFmaskBits
3191 * Computes fmask bits
3194 ****************************************************************************************************
3196 UINT_32
SiLib::HwlComputeFmaskBits(
3197 const ADDR_COMPUTE_FMASK_INFO_INPUT
* pIn
,
3198 UINT_32
* pNumSamples
3201 UINT_32 numSamples
= pIn
->numSamples
;
3202 UINT_32 numFrags
= GetNumFragments(numSamples
, pIn
->numFrags
);
3205 if (numFrags
!= numSamples
) // EQAA
3207 ADDR_ASSERT(numFrags
<= 8);
3209 if (pIn
->resolved
== FALSE
)
3214 numSamples
= numSamples
== 16 ? 16 : 8;
3216 else if (numFrags
== 2)
3218 ADDR_ASSERT(numSamples
>= 4);
3221 numSamples
= numSamples
;
3223 else if (numFrags
== 4)
3225 ADDR_ASSERT(numSamples
>= 4);
3228 numSamples
= numSamples
;
3230 else // numFrags == 8
3232 ADDR_ASSERT(numSamples
== 16);
3235 numSamples
= numSamples
;
3242 bpp
= (numSamples
== 16) ? 16 : 8;
3245 else if (numFrags
== 2)
3247 ADDR_ASSERT(numSamples
>= 4);
3252 else if (numFrags
== 4)
3254 ADDR_ASSERT(numSamples
>= 4);
3259 else // numFrags == 8
3261 ADDR_ASSERT(numSamples
>= 16);
3270 if (pIn
->resolved
== FALSE
)
3272 bpp
= ComputeFmaskNumPlanesFromNumSamples(numSamples
);
3273 numSamples
= numSamples
== 2 ? 8 : numSamples
;
3278 bpp
= ComputeFmaskResolvedBppFromNumSamples(numSamples
);
3279 numSamples
= 1; // 1x sample
3283 SafeAssign(pNumSamples
, numSamples
);
3289 ****************************************************************************************************
3290 * SiLib::HwlOptimizeTileMode
3293 * Optimize tile mode on SI
3298 ****************************************************************************************************
3300 VOID
SiLib::HwlOptimizeTileMode(
3301 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
3304 AddrTileMode tileMode
= pInOut
->tileMode
;
3306 if ((pInOut
->flags
.needEquation
== TRUE
) &&
3307 (IsMacroTiled(tileMode
) == TRUE
) &&
3308 (pInOut
->numSamples
<= 1))
3310 UINT_32 thickness
= Thickness(tileMode
);
3314 tileMode
= ADDR_TM_1D_TILED_THICK
;
3316 else if (pInOut
->numSlices
> 1)
3318 tileMode
= ADDR_TM_1D_TILED_THIN1
;
3322 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3326 if (tileMode
!= pInOut
->tileMode
)
3328 pInOut
->tileMode
= tileMode
;
3333 ****************************************************************************************************
3334 * SiLib::HwlOverrideTileMode
3337 * Override tile modes (for PRT only, avoid client passes in an invalid PRT mode for SI.
3342 ****************************************************************************************************
3344 VOID
SiLib::HwlOverrideTileMode(
3345 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
3348 AddrTileMode tileMode
= pInOut
->tileMode
;
3352 case ADDR_TM_PRT_TILED_THIN1
:
3353 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3356 case ADDR_TM_PRT_TILED_THICK
:
3357 tileMode
= ADDR_TM_2D_TILED_THICK
;
3360 case ADDR_TM_PRT_2D_TILED_THICK
:
3361 tileMode
= ADDR_TM_2D_TILED_THICK
;
3364 case ADDR_TM_PRT_3D_TILED_THICK
:
3365 tileMode
= ADDR_TM_3D_TILED_THICK
;
3372 if (tileMode
!= pInOut
->tileMode
)
3374 pInOut
->tileMode
= tileMode
;
3375 // Only PRT tile modes are overridden for now. Revisit this once new modes are added above.
3376 pInOut
->flags
.prt
= TRUE
;
3381 ****************************************************************************************************
3382 * SiLib::HwlSetPrtTileMode
3385 * Set prt tile modes.
3390 ****************************************************************************************************
3392 VOID
SiLib::HwlSetPrtTileMode(
3393 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
3396 pInOut
->tileMode
= ADDR_TM_2D_TILED_THIN1
;
3397 pInOut
->tileType
= (pInOut
->tileType
== ADDR_DEPTH_SAMPLE_ORDER
) ?
3398 ADDR_DEPTH_SAMPLE_ORDER
: ADDR_NON_DISPLAYABLE
;
3399 pInOut
->flags
.prt
= TRUE
;
3403 ****************************************************************************************************
3404 * SiLib::HwlSelectTileMode
3407 * Select tile modes.
3412 ****************************************************************************************************
3414 VOID
SiLib::HwlSelectTileMode(
3415 ADDR_COMPUTE_SURFACE_INFO_INPUT
* pInOut
///< [in,out] input output structure
3418 AddrTileMode tileMode
;
3419 AddrTileType tileType
;
3421 if (pInOut
->flags
.volume
)
3423 if (pInOut
->numSlices
>= 8)
3425 tileMode
= ADDR_TM_2D_TILED_XTHICK
;
3427 else if (pInOut
->numSlices
>= 4)
3429 tileMode
= ADDR_TM_2D_TILED_THICK
;
3433 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3435 tileType
= ADDR_NON_DISPLAYABLE
;
3439 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3441 if (pInOut
->flags
.depth
|| pInOut
->flags
.stencil
)
3443 tileType
= ADDR_DEPTH_SAMPLE_ORDER
;
3445 else if ((pInOut
->bpp
<= 32) ||
3446 (pInOut
->flags
.display
== TRUE
) ||
3447 (pInOut
->flags
.overlay
== TRUE
))
3449 tileType
= ADDR_DISPLAYABLE
;
3453 tileType
= ADDR_NON_DISPLAYABLE
;
3457 if (pInOut
->flags
.prt
)
3459 tileMode
= ADDR_TM_2D_TILED_THIN1
;
3460 tileType
= (tileType
== ADDR_DISPLAYABLE
) ? ADDR_NON_DISPLAYABLE
: tileType
;
3463 pInOut
->tileMode
= tileMode
;
3464 pInOut
->tileType
= tileType
;
3466 // Optimize tile mode if possible
3467 pInOut
->flags
.opt4Space
= TRUE
;
3469 // Optimize tile mode if possible
3470 OptimizeTileMode(pInOut
);
3472 HwlOverrideTileMode(pInOut
);
3476 ****************************************************************************************************
3477 * SiLib::HwlGetMaxAlignments
3480 * Gets maximum alignments
3483 ****************************************************************************************************
3485 ADDR_E_RETURNCODE
SiLib::HwlGetMaxAlignments(
3486 ADDR_GET_MAX_ALINGMENTS_OUTPUT
* pOut
///< [out] output structure
3489 const UINT_32 pipes
= HwlGetPipes(&m_tileTable
[0].info
);
3491 // Initial size is 64 KiB for PRT.
3492 UINT_64 maxBaseAlign
= 64 * 1024;
3494 for (UINT_32 i
= 0; i
< m_noOfEntries
; i
++)
3496 if ((IsMacroTiled(m_tileTable
[i
].mode
) == TRUE
) &&
3497 (IsPrtTileMode(m_tileTable
[i
].mode
) == FALSE
))
3499 // The maximum tile size is 16 byte-per-pixel and either 8-sample or 8-slice.
3500 UINT_32 tileSize
= Min(m_tileTable
[i
].info
.tileSplitBytes
,
3501 MicroTilePixels
* 8 * 16);
3503 UINT_64 baseAlign
= tileSize
* pipes
* m_tileTable
[i
].info
.banks
*
3504 m_tileTable
[i
].info
.bankWidth
* m_tileTable
[i
].info
.bankHeight
;
3506 if (baseAlign
> maxBaseAlign
)
3508 maxBaseAlign
= baseAlign
;
3515 pOut
->baseAlign
= maxBaseAlign
;
3522 ****************************************************************************************************
3523 * SiLib::HwlComputeSurfaceAlignmentsMacroTiled
3526 * Hardware layer function to compute alignment request for macro tile mode
3531 ****************************************************************************************************
3533 VOID
SiLib::HwlComputeSurfaceAlignmentsMacroTiled(
3534 AddrTileMode tileMode
, ///< [in] tile mode
3535 UINT_32 bpp
, ///< [in] bits per pixel
3536 ADDR_SURFACE_FLAGS flags
, ///< [in] surface flags
3537 UINT_32 mipLevel
, ///< [in] mip level
3538 UINT_32 numSamples
, ///< [in] number of samples
3539 ADDR_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [in,out] Surface output
3542 if ((mipLevel
== 0) && (flags
.prt
))
3544 UINT_32 macroTileSize
= pOut
->blockWidth
* pOut
->blockHeight
* numSamples
* bpp
/ 8;
3546 if (macroTileSize
< PrtTileSize
)
3548 UINT_32 numMacroTiles
= PrtTileSize
/ macroTileSize
;
3550 ADDR_ASSERT((PrtTileSize
% macroTileSize
) == 0);
3552 pOut
->pitchAlign
*= numMacroTiles
;
3553 pOut
->baseAlign
*= numMacroTiles
;
3559 ****************************************************************************************************
3560 * SiLib::InitEquationTable
3563 * Initialize Equation table.
3567 ****************************************************************************************************
3569 VOID
SiLib::InitEquationTable()
3571 ADDR_EQUATION_KEY equationKeyTable
[EquationTableSize
];
3572 memset(equationKeyTable
, 0, sizeof(equationKeyTable
));
3574 memset(m_equationTable
, 0, sizeof(m_equationTable
));
3576 memset(m_blockWidth
, 0, sizeof(m_blockWidth
));
3578 memset(m_blockHeight
, 0, sizeof(m_blockHeight
));
3580 memset(m_blockSlices
, 0, sizeof(m_blockSlices
));
3582 // Loop all possible bpp
3583 for (UINT_32 log2ElementBytes
= 0; log2ElementBytes
< MaxNumElementBytes
; log2ElementBytes
++)
3585 // Get bits per pixel
3586 UINT_32 bpp
= 1 << (log2ElementBytes
+ 3);
3588 // Loop all possible tile index
3589 for (INT_32 tileIndex
= 0; tileIndex
< static_cast<INT_32
>(m_noOfEntries
); tileIndex
++)
3591 UINT_32 equationIndex
= ADDR_INVALID_EQUATION_INDEX
;
3593 TileConfig tileConfig
= m_tileTable
[tileIndex
];
3595 ADDR_SURFACE_FLAGS flags
= {{0}};
3597 // Compute tile info, hardcode numSamples to 1 because MSAA is not supported
3598 // in swizzle pattern equation
3599 HwlComputeMacroModeIndex(tileIndex
, flags
, bpp
, 1, &tileConfig
.info
, NULL
, NULL
);
3601 // Check if the input is supported
3602 if (IsEquationSupported(bpp
, tileConfig
, tileIndex
, log2ElementBytes
) == TRUE
)
3604 ADDR_EQUATION_KEY key
= {{0}};
3606 // Generate swizzle equation key from bpp and tile config
3607 key
.fields
.log2ElementBytes
= log2ElementBytes
;
3608 key
.fields
.tileMode
= tileConfig
.mode
;
3609 // Treat depth micro tile type and non-display micro tile type as the same key
3610 // because they have the same equation actually
3611 key
.fields
.microTileType
= (tileConfig
.type
== ADDR_DEPTH_SAMPLE_ORDER
) ?
3612 ADDR_NON_DISPLAYABLE
: tileConfig
.type
;
3613 key
.fields
.pipeConfig
= tileConfig
.info
.pipeConfig
;
3614 key
.fields
.numBanksLog2
= Log2(tileConfig
.info
.banks
);
3615 key
.fields
.bankWidth
= tileConfig
.info
.bankWidth
;
3616 key
.fields
.bankHeight
= tileConfig
.info
.bankHeight
;
3617 key
.fields
.macroAspectRatio
= tileConfig
.info
.macroAspectRatio
;
3618 key
.fields
.prt
= ((m_chipFamily
== ADDR_CHIP_FAMILY_SI
) &&
3619 ((1 << tileIndex
) & SiPrtTileIndexMask
)) ? 1 : 0;
3621 // Find in the table if the equation has been built based on the key
3622 for (UINT_32 i
= 0; i
< m_numEquations
; i
++)
3624 if (key
.value
== equationKeyTable
[i
].value
)
3631 // If found, just fill the index into the lookup table and no need
3632 // to generate the equation again. Otherwise, generate the equation.
3633 if (equationIndex
== ADDR_INVALID_EQUATION_INDEX
)
3635 ADDR_EQUATION equation
;
3636 ADDR_E_RETURNCODE retCode
;
3638 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
3640 // Generate the equation
3641 if (IsMicroTiled(tileConfig
.mode
))
3643 retCode
= ComputeMicroTileEquation(log2ElementBytes
,
3650 retCode
= ComputeMacroTileEquation(log2ElementBytes
,
3656 // Only fill the equation into the table if the return code is ADDR_OK,
3657 // otherwise if the return code is not ADDR_OK, it indicates this is not
3658 // a valid input, we do nothing but just fill invalid equation index
3659 // into the lookup table.
3660 if (retCode
== ADDR_OK
)
3662 equationIndex
= m_numEquations
;
3663 ADDR_ASSERT(equationIndex
< EquationTableSize
);
3665 m_blockSlices
[equationIndex
] = Thickness(tileConfig
.mode
);
3667 if (IsMicroTiled(tileConfig
.mode
))
3669 m_blockWidth
[equationIndex
] = MicroTileWidth
;
3670 m_blockHeight
[equationIndex
] = MicroTileHeight
;
3674 const ADDR_TILEINFO
* pTileInfo
= &tileConfig
.info
;
3676 m_blockWidth
[equationIndex
] =
3677 HwlGetPipes(pTileInfo
) * MicroTileWidth
* pTileInfo
->bankWidth
*
3678 pTileInfo
->macroAspectRatio
;
3679 m_blockHeight
[equationIndex
] =
3680 MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
/
3681 pTileInfo
->macroAspectRatio
;
3685 UINT_32 macroTileSize
=
3686 m_blockWidth
[equationIndex
] * m_blockHeight
[equationIndex
] *
3689 if (macroTileSize
< PrtTileSize
)
3691 UINT_32 numMacroTiles
= PrtTileSize
/ macroTileSize
;
3693 ADDR_ASSERT(macroTileSize
== (1u << equation
.numBits
));
3694 ADDR_ASSERT((PrtTileSize
% macroTileSize
) == 0);
3696 UINT_32 numBits
= Log2(numMacroTiles
);
3698 UINT_32 xStart
= Log2(m_blockWidth
[equationIndex
]) +
3701 m_blockWidth
[equationIndex
] *= numMacroTiles
;
3703 for (UINT_32 i
= 0; i
< numBits
; i
++)
3705 equation
.addr
[equation
.numBits
+ i
].valid
= 1;
3706 equation
.addr
[equation
.numBits
+ i
].index
= xStart
+ i
;
3709 equation
.numBits
+= numBits
;
3714 equationKeyTable
[equationIndex
] = key
;
3715 m_equationTable
[equationIndex
] = equation
;
3722 // Fill the index into the lookup table, if the combination is not supported
3723 // fill the invalid equation index
3724 m_equationLookupTable
[log2ElementBytes
][tileIndex
] = equationIndex
;
3727 if (m_chipFamily
== ADDR_CHIP_FAMILY_SI
)
3729 // For tile index 3 which is shared between PRT depth and uncompressed depth
3730 m_uncompressDepthEqIndex
= m_numEquations
;
3732 for (UINT_32 log2ElemBytes
= 0; log2ElemBytes
< MaxNumElementBytes
; log2ElemBytes
++)
3734 TileConfig tileConfig
= m_tileTable
[3];
3735 ADDR_EQUATION equation
;
3736 ADDR_E_RETURNCODE retCode
;
3738 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
3740 retCode
= ComputeMacroTileEquation(log2ElemBytes
,
3746 if (retCode
== ADDR_OK
)
3748 UINT_32 equationIndex
= m_numEquations
;
3749 ADDR_ASSERT(equationIndex
< EquationTableSize
);
3751 m_blockSlices
[equationIndex
] = 1;
3753 const ADDR_TILEINFO
* pTileInfo
= &tileConfig
.info
;
3755 m_blockWidth
[equationIndex
] =
3756 HwlGetPipes(pTileInfo
) * MicroTileWidth
* pTileInfo
->bankWidth
*
3757 pTileInfo
->macroAspectRatio
;
3758 m_blockHeight
[equationIndex
] =
3759 MicroTileHeight
* pTileInfo
->bankHeight
* pTileInfo
->banks
/
3760 pTileInfo
->macroAspectRatio
;
3762 m_equationTable
[equationIndex
] = equation
;
3772 ****************************************************************************************************
3773 * SiLib::IsEquationSupported
3776 * Check if it is supported for given bpp and tile config to generate a equation.
3780 ****************************************************************************************************
3782 BOOL_32
SiLib::IsEquationSupported(
3783 UINT_32 bpp
, ///< Bits per pixel
3784 TileConfig tileConfig
, ///< Tile config
3785 INT_32 tileIndex
, ///< Tile index
3786 UINT_32 elementBytesLog2
///< Log2 of element bytes
3789 BOOL_32 supported
= TRUE
;
3791 // Linear tile mode is not supported in swizzle pattern equation
3792 if (IsLinear(tileConfig
.mode
))
3796 // These tile modes are for Tex2DArray and Tex3D which has depth (num_slice > 1) use,
3797 // which is not supported in swizzle pattern equation due to slice rotation
3798 else if ((tileConfig
.mode
== ADDR_TM_2D_TILED_THICK
) ||
3799 (tileConfig
.mode
== ADDR_TM_2D_TILED_XTHICK
) ||
3800 (tileConfig
.mode
== ADDR_TM_3D_TILED_THIN1
) ||
3801 (tileConfig
.mode
== ADDR_TM_3D_TILED_THICK
) ||
3802 (tileConfig
.mode
== ADDR_TM_3D_TILED_XTHICK
))
3806 // Only 8bpp(stencil), 16bpp and 32bpp is supported for depth
3807 else if ((tileConfig
.type
== ADDR_DEPTH_SAMPLE_ORDER
) && (bpp
> 32))
3811 // Tile split is not supported in swizzle pattern equation
3812 else if (IsMacroTiled(tileConfig
.mode
))
3814 UINT_32 thickness
= Thickness(tileConfig
.mode
);
3815 if (((bpp
>> 3) * MicroTilePixels
* thickness
) > tileConfig
.info
.tileSplitBytes
)
3820 if ((supported
== TRUE
) && (m_chipFamily
== ADDR_CHIP_FAMILY_SI
))
3822 supported
= m_EquationSupport
[tileIndex
][elementBytesLog2
];