xref: /aosp_15_r20/external/mesa3d/src/amd/addrlib/src/r800/siaddrlib.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2 ************************************************************************************************************************
3 *
4 *  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.
5 *  SPDX-License-Identifier: MIT
6 *
7 ***********************************************************************************************************************/
8 
9 /**
10 ****************************************************************************************************
11 * @file  siaddrlib.cpp
12 * @brief Contains the implementation for the SiLib class.
13 ****************************************************************************************************
14 */
15 
16 #include "siaddrlib.h"
17 #include "si_gb_reg.h"
18 
19 #include "amdgpu_asic_addr.h"
20 
21 ////////////////////////////////////////////////////////////////////////////////////////////////////
22 ////////////////////////////////////////////////////////////////////////////////////////////////////
23 namespace Addr
24 {
25 
26 /**
27 ****************************************************************************************************
28 *   SiHwlInit
29 *
30 *   @brief
31 *       Creates an SiLib object.
32 *
33 *   @return
34 *       Returns an SiLib object pointer.
35 ****************************************************************************************************
36 */
SiHwlInit(const Client * pClient)37 Lib* SiHwlInit(const Client* pClient)
38 {
39     return V1::SiLib::CreateObj(pClient);
40 }
41 
42 namespace V1
43 {
44 
45 // We don't support MSAA for equation
46 const BOOL_32 SiLib::m_EquationSupport[SiLib::TileTableSize][SiLib::MaxNumElementBytes] =
47 {
48     {TRUE,  TRUE,  TRUE,  FALSE, FALSE},    //  0, non-AA compressed depth or any stencil
49     {FALSE, FALSE, FALSE, FALSE, FALSE},    //  1, 2xAA/4xAA compressed depth with or without stencil
50     {FALSE, FALSE, FALSE, FALSE, FALSE},    //  2, 8xAA compressed depth with or without stencil
51     {FALSE, TRUE,  FALSE, FALSE, FALSE},    //  3, 16 bpp depth PRT (non-MSAA), don't support uncompressed depth
52     {TRUE,  TRUE,  TRUE,  FALSE, FALSE},    //  4, 1D depth
53     {FALSE, FALSE, FALSE, FALSE, FALSE},    //  5, 16 bpp depth PRT (4xMSAA)
54     {FALSE, FALSE, TRUE,  FALSE, FALSE},    //  6, 32 bpp depth PRT (non-MSAA)
55     {FALSE, FALSE, FALSE, FALSE, FALSE},    //  7, 32 bpp depth PRT (4xMSAA)
56     {TRUE,  TRUE,  TRUE,  TRUE,  TRUE },    //  8, Linear
57     {TRUE,  TRUE,  TRUE,  TRUE,  TRUE },    //  9, 1D display
58     {TRUE,  FALSE, FALSE, FALSE, FALSE},    // 10, 8 bpp color (displayable)
59     {FALSE, TRUE,  FALSE, FALSE, FALSE},    // 11, 16 bpp color (displayable)
60     {FALSE, FALSE, TRUE,  TRUE,  FALSE},    // 12, 32/64 bpp color (displayable)
61     {TRUE,  TRUE,  TRUE,  TRUE,  TRUE },    // 13, 1D thin
62     {TRUE,  FALSE, FALSE, FALSE, FALSE},    // 14, 8 bpp color non-displayable
63     {FALSE, TRUE,  FALSE, FALSE, FALSE},    // 15, 16 bpp color non-displayable
64     {FALSE, FALSE, TRUE,  FALSE, FALSE},    // 16, 32 bpp color non-displayable
65     {FALSE, FALSE, FALSE, TRUE,  TRUE },    // 17, 64/128 bpp color non-displayable
66     {TRUE,  TRUE,  TRUE,  TRUE,  TRUE },    // 18, 1D THICK
67     {FALSE, FALSE, FALSE, FALSE, FALSE},    // 19, 2D XTHICK
68     {FALSE, FALSE, FALSE, FALSE, FALSE},    // 20, 2D THICK
69     {TRUE,  FALSE, FALSE, FALSE, FALSE},    // 21, 8 bpp 2D PRTs (non-MSAA)
70     {FALSE, TRUE,  FALSE, FALSE, FALSE},    // 22, 16 bpp 2D PRTs (non-MSAA)
71     {FALSE, FALSE, TRUE,  FALSE, FALSE},    // 23, 32 bpp 2D PRTs (non-MSAA)
72     {FALSE, FALSE, FALSE, TRUE,  FALSE},    // 24, 64 bpp 2D PRTs (non-MSAA)
73     {FALSE, FALSE, FALSE, FALSE, TRUE },    // 25, 128bpp 2D PRTs (non-MSAA)
74     {FALSE, FALSE, FALSE, FALSE, FALSE},    // 26, none
75     {FALSE, FALSE, FALSE, FALSE, FALSE},    // 27, none
76     {FALSE, FALSE, FALSE, FALSE, FALSE},    // 28, none
77     {FALSE, FALSE, FALSE, FALSE, FALSE},    // 29, none
78     {FALSE, FALSE, FALSE, FALSE, FALSE},    // 30, 64bpp 2D PRTs (4xMSAA)
79     {FALSE, FALSE, FALSE, FALSE, FALSE},    // 31, none
80 };
81 
82 /**
83 ****************************************************************************************************
84 *   SiLib::SiLib
85 *
86 *   @brief
87 *       Constructor
88 *
89 ****************************************************************************************************
90 */
SiLib(const Client * pClient)91 SiLib::SiLib(const Client* pClient)
92     :
93     EgBasedLib(pClient),
94     m_noOfEntries(0),
95     m_numEquations(0)
96 {
97     memset(&m_settings, 0, sizeof(m_settings));
98 }
99 
100 /**
101 ****************************************************************************************************
102 *   SiLib::~SiLib
103 *
104 *   @brief
105 *       Destructor
106 ****************************************************************************************************
107 */
~SiLib()108 SiLib::~SiLib()
109 {
110 }
111 
112 /**
113 ****************************************************************************************************
114 *   SiLib::HwlGetPipes
115 *
116 *   @brief
117 *       Get number pipes
118 *   @return
119 *       num pipes
120 ****************************************************************************************************
121 */
HwlGetPipes(const ADDR_TILEINFO * pTileInfo) const122 UINT_32 SiLib::HwlGetPipes(
123     const ADDR_TILEINFO* pTileInfo    ///< [in] Tile info
124     ) const
125 {
126     UINT_32 numPipes;
127 
128     if (pTileInfo)
129     {
130         numPipes = GetPipePerSurf(pTileInfo->pipeConfig);
131     }
132     else
133     {
134         ADDR_ASSERT_ALWAYS();
135         numPipes = m_pipes; // Suppose we should still have a global pipes
136     }
137 
138     return numPipes;
139 }
140 
141 /**
142 ****************************************************************************************************
143 *   SiLib::GetPipePerSurf
144 *   @brief
145 *       get pipe num base on inputing tileinfo->pipeconfig
146 *   @return
147 *       pipe number
148 ****************************************************************************************************
149 */
GetPipePerSurf(AddrPipeCfg pipeConfig) const150 UINT_32 SiLib::GetPipePerSurf(
151     AddrPipeCfg pipeConfig   ///< [in] pipe config
152     ) const
153 {
154     UINT_32 numPipes = 0;
155 
156     switch (pipeConfig)
157     {
158         case ADDR_PIPECFG_P2:
159             numPipes = 2;
160             break;
161         case ADDR_PIPECFG_P4_8x16:
162         case ADDR_PIPECFG_P4_16x16:
163         case ADDR_PIPECFG_P4_16x32:
164         case ADDR_PIPECFG_P4_32x32:
165             numPipes = 4;
166             break;
167         case ADDR_PIPECFG_P8_16x16_8x16:
168         case ADDR_PIPECFG_P8_16x32_8x16:
169         case ADDR_PIPECFG_P8_32x32_8x16:
170         case ADDR_PIPECFG_P8_16x32_16x16:
171         case ADDR_PIPECFG_P8_32x32_16x16:
172         case ADDR_PIPECFG_P8_32x32_16x32:
173         case ADDR_PIPECFG_P8_32x64_32x32:
174             numPipes = 8;
175             break;
176         case ADDR_PIPECFG_P16_32x32_8x16:
177         case ADDR_PIPECFG_P16_32x32_16x16:
178             numPipes = 16;
179             break;
180         default:
181             ADDR_ASSERT(!"Invalid pipe config");
182             numPipes = m_pipes;
183     }
184     return numPipes;
185 }
186 
187 /**
188 ****************************************************************************************************
189 *   SiLib::ComputeBankEquation
190 *
191 *   @brief
192 *       Compute bank equation
193 *
194 *   @return
195 *       If equation can be computed
196 ****************************************************************************************************
197 */
ComputeBankEquation(UINT_32 log2BytesPP,UINT_32 threshX,UINT_32 threshY,ADDR_TILEINFO * pTileInfo,ADDR_EQUATION * pEquation) const198 ADDR_E_RETURNCODE SiLib::ComputeBankEquation(
199     UINT_32         log2BytesPP,    ///< [in] log2 of bytes per pixel
200     UINT_32         threshX,        ///< [in] threshold for x channel
201     UINT_32         threshY,        ///< [in] threshold for y channel
202     ADDR_TILEINFO*  pTileInfo,      ///< [in] tile info
203     ADDR_EQUATION*  pEquation       ///< [out] bank equation
204     ) const
205 {
206     ADDR_E_RETURNCODE retCode = ADDR_OK;
207 
208     UINT_32 pipes = HwlGetPipes(pTileInfo);
209     UINT_32 bankXStart = 3 + Log2(pipes) + Log2(pTileInfo->bankWidth);
210     UINT_32 bankYStart = 3 + Log2(pTileInfo->bankHeight);
211 
212     ADDR_CHANNEL_SETTING x3 = InitChannel(1, 0, log2BytesPP + bankXStart);
213     ADDR_CHANNEL_SETTING x4 = InitChannel(1, 0, log2BytesPP + bankXStart + 1);
214     ADDR_CHANNEL_SETTING x5 = InitChannel(1, 0, log2BytesPP + bankXStart + 2);
215     ADDR_CHANNEL_SETTING x6 = InitChannel(1, 0, log2BytesPP + bankXStart + 3);
216     ADDR_CHANNEL_SETTING y3 = InitChannel(1, 1, bankYStart);
217     ADDR_CHANNEL_SETTING y4 = InitChannel(1, 1, bankYStart + 1);
218     ADDR_CHANNEL_SETTING y5 = InitChannel(1, 1, bankYStart + 2);
219     ADDR_CHANNEL_SETTING y6 = InitChannel(1, 1, bankYStart + 3);
220 
221     x3.value = (threshX > bankXStart)     ? x3.value : 0;
222     x4.value = (threshX > bankXStart + 1) ? x4.value : 0;
223     x5.value = (threshX > bankXStart + 2) ? x5.value : 0;
224     x6.value = (threshX > bankXStart + 3) ? x6.value : 0;
225     y3.value = (threshY > bankYStart)     ? y3.value : 0;
226     y4.value = (threshY > bankYStart + 1) ? y4.value : 0;
227     y5.value = (threshY > bankYStart + 2) ? y5.value : 0;
228     y6.value = (threshY > bankYStart + 3) ? y6.value : 0;
229 
230     switch (pTileInfo->banks)
231     {
232         case 16:
233             if (pTileInfo->macroAspectRatio == 1)
234             {
235                 pEquation->addr[0] = y6;
236                 pEquation->xor1[0] = x3;
237                 pEquation->addr[1] = y5;
238                 pEquation->xor1[1] = y6;
239                 pEquation->xor2[1] = x4;
240                 pEquation->addr[2] = y4;
241                 pEquation->xor1[2] = x5;
242                 pEquation->addr[3] = y3;
243                 pEquation->xor1[3] = x6;
244             }
245             else if (pTileInfo->macroAspectRatio == 2)
246             {
247                 pEquation->addr[0] = x3;
248                 pEquation->xor1[0] = y6;
249                 pEquation->addr[1] = y5;
250                 pEquation->xor1[1] = y6;
251                 pEquation->xor2[1] = x4;
252                 pEquation->addr[2] = y4;
253                 pEquation->xor1[2] = x5;
254                 pEquation->addr[3] = y3;
255                 pEquation->xor1[3] = x6;
256             }
257             else if (pTileInfo->macroAspectRatio == 4)
258             {
259                 pEquation->addr[0] = x3;
260                 pEquation->xor1[0] = y6;
261                 pEquation->addr[1] = x4;
262                 pEquation->xor1[1] = y5;
263                 pEquation->xor2[1] = y6;
264                 pEquation->addr[2] = y4;
265                 pEquation->xor1[2] = x5;
266                 pEquation->addr[3] = y3;
267                 pEquation->xor1[3] = x6;
268             }
269             else if (pTileInfo->macroAspectRatio == 8)
270             {
271                 pEquation->addr[0] = x3;
272                 pEquation->xor1[0] = y6;
273                 pEquation->addr[1] = x4;
274                 pEquation->xor1[1] = y5;
275                 pEquation->xor2[1] = y6;
276                 pEquation->addr[2] = x5;
277                 pEquation->xor1[2] = y4;
278                 pEquation->addr[3] = y3;
279                 pEquation->xor1[3] = x6;
280             }
281             else
282             {
283                 ADDR_ASSERT_ALWAYS();
284             }
285             pEquation->numBits = 4;
286             break;
287         case 8:
288             if (pTileInfo->macroAspectRatio == 1)
289             {
290                 pEquation->addr[0] = y5;
291                 pEquation->xor1[0] = x3;
292                 pEquation->addr[1] = y4;
293                 pEquation->xor1[1] = y5;
294                 pEquation->xor2[1] = x4;
295                 pEquation->addr[2] = y3;
296                 pEquation->xor1[2] = x5;
297             }
298             else if (pTileInfo->macroAspectRatio == 2)
299             {
300                 pEquation->addr[0] = x3;
301                 pEquation->xor1[0] = y5;
302                 pEquation->addr[1] = y4;
303                 pEquation->xor1[1] = y5;
304                 pEquation->xor2[1] = x4;
305                 pEquation->addr[2] = y3;
306                 pEquation->xor1[2] = x5;
307             }
308             else if (pTileInfo->macroAspectRatio == 4)
309             {
310                 pEquation->addr[0] = x3;
311                 pEquation->xor1[0] = y5;
312                 pEquation->addr[1] = x4;
313                 pEquation->xor1[1] = y4;
314                 pEquation->xor2[1] = y5;
315                 pEquation->addr[2] = y3;
316                 pEquation->xor1[2] = x5;
317             }
318             else
319             {
320                 ADDR_ASSERT_ALWAYS();
321             }
322             pEquation->numBits = 3;
323             break;
324         case 4:
325             if (pTileInfo->macroAspectRatio == 1)
326             {
327                 pEquation->addr[0] = y4;
328                 pEquation->xor1[0] = x3;
329                 pEquation->addr[1] = y3;
330                 pEquation->xor1[1] = x4;
331             }
332             else if (pTileInfo->macroAspectRatio == 2)
333             {
334                 pEquation->addr[0] = x3;
335                 pEquation->xor1[0] = y4;
336                 pEquation->addr[1] = y3;
337                 pEquation->xor1[1] = x4;
338             }
339             else
340             {
341                 pEquation->addr[0] = x3;
342                 pEquation->xor1[0] = y4;
343                 pEquation->addr[1] = x4;
344                 pEquation->xor1[1] = y3;
345             }
346             pEquation->numBits = 2;
347             break;
348         case 2:
349             if (pTileInfo->macroAspectRatio == 1)
350             {
351                 pEquation->addr[0] = y3;
352                 pEquation->xor1[0] = x3;
353             }
354             else
355             {
356                 pEquation->addr[0] = x3;
357                 pEquation->xor1[0] = y3;
358             }
359             pEquation->numBits = 1;
360             break;
361         default:
362             pEquation->numBits = 0;
363             retCode = ADDR_NOTSUPPORTED;
364             ADDR_ASSERT_ALWAYS();
365             break;
366     }
367 
368     for (UINT_32 i = 0; i < pEquation->numBits; i++)
369     {
370         if (pEquation->addr[i].value == 0)
371         {
372             if (pEquation->xor1[i].value == 0)
373             {
374                 // 00X -> X00
375                 pEquation->addr[i].value = pEquation->xor2[i].value;
376                 pEquation->xor2[i].value = 0;
377             }
378             else
379             {
380                 pEquation->addr[i].value = pEquation->xor1[i].value;
381 
382                 if (pEquation->xor2[i].value != 0)
383                 {
384                     // 0XY -> XY0
385                     pEquation->xor1[i].value = pEquation->xor2[i].value;
386                     pEquation->xor2[i].value = 0;
387                 }
388                 else
389                 {
390                     // 0X0 -> X00
391                     pEquation->xor1[i].value = 0;
392                 }
393             }
394         }
395         else if (pEquation->xor1[i].value == 0)
396         {
397             if (pEquation->xor2[i].value != 0)
398             {
399                 // X0Y -> XY0
400                 pEquation->xor1[i].value = pEquation->xor2[i].value;
401                 pEquation->xor2[i].value = 0;
402             }
403         }
404     }
405     FillEqBitComponents(pEquation);
406 
407     if ((pTileInfo->bankWidth == 1) &&
408         ((pTileInfo->pipeConfig == ADDR_PIPECFG_P4_32x32) ||
409          (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32)))
410     {
411         retCode = ADDR_NOTSUPPORTED;
412     }
413 
414     return retCode;
415 }
416 
417 /**
418 ****************************************************************************************************
419 *   SiLib::ComputePipeEquation
420 *
421 *   @brief
422 *       Compute pipe equation
423 *
424 *   @return
425 *       If equation can be computed
426 ****************************************************************************************************
427 */
ComputePipeEquation(UINT_32 log2BytesPP,UINT_32 threshX,UINT_32 threshY,ADDR_TILEINFO * pTileInfo,ADDR_EQUATION * pEquation) const428 ADDR_E_RETURNCODE SiLib::ComputePipeEquation(
429     UINT_32        log2BytesPP, ///< [in] Log2 of bytes per pixel
430     UINT_32        threshX,     ///< [in] Threshold for X channel
431     UINT_32        threshY,     ///< [in] Threshold for Y channel
432     ADDR_TILEINFO* pTileInfo,   ///< [in] Tile info
433     ADDR_EQUATION* pEquation    ///< [out] Pipe configure
434     ) const
435 {
436     ADDR_E_RETURNCODE retCode = ADDR_OK;
437 
438     ADDR_CHANNEL_SETTING* pAddr = pEquation->addr;
439     ADDR_CHANNEL_SETTING* pXor1 = pEquation->xor1;
440     ADDR_CHANNEL_SETTING* pXor2 = pEquation->xor2;
441 
442     ADDR_CHANNEL_SETTING x3 = InitChannel(1, 0, 3 + log2BytesPP);
443     ADDR_CHANNEL_SETTING x4 = InitChannel(1, 0, 4 + log2BytesPP);
444     ADDR_CHANNEL_SETTING x5 = InitChannel(1, 0, 5 + log2BytesPP);
445     ADDR_CHANNEL_SETTING x6 = InitChannel(1, 0, 6 + log2BytesPP);
446     ADDR_CHANNEL_SETTING y3 = InitChannel(1, 1, 3);
447     ADDR_CHANNEL_SETTING y4 = InitChannel(1, 1, 4);
448     ADDR_CHANNEL_SETTING y5 = InitChannel(1, 1, 5);
449     ADDR_CHANNEL_SETTING y6 = InitChannel(1, 1, 6);
450 
451     x3.value = (threshX > 3) ? x3.value : 0;
452     x4.value = (threshX > 4) ? x4.value : 0;
453     x5.value = (threshX > 5) ? x5.value : 0;
454     x6.value = (threshX > 6) ? x6.value : 0;
455     y3.value = (threshY > 3) ? y3.value : 0;
456     y4.value = (threshY > 4) ? y4.value : 0;
457     y5.value = (threshY > 5) ? y5.value : 0;
458     y6.value = (threshY > 6) ? y6.value : 0;
459 
460     switch (pTileInfo->pipeConfig)
461     {
462         case ADDR_PIPECFG_P2:
463             pAddr[0] = x3;
464             pXor1[0] = y3;
465             pEquation->numBits = 1;
466             break;
467         case ADDR_PIPECFG_P4_8x16:
468             pAddr[0] = x4;
469             pXor1[0] = y3;
470             pAddr[1] = x3;
471             pXor1[1] = y4;
472             pEquation->numBits = 2;
473             break;
474         case ADDR_PIPECFG_P4_16x16:
475             pAddr[0] = x3;
476             pXor1[0] = y3;
477             pXor2[0] = x4;
478             pAddr[1] = x4;
479             pXor1[1] = y4;
480             pEquation->numBits = 2;
481             break;
482         case ADDR_PIPECFG_P4_16x32:
483             pAddr[0] = x3;
484             pXor1[0] = y3;
485             pXor2[0] = x4;
486             pAddr[1] = x4;
487             pXor1[1] = y5;
488             pEquation->numBits = 2;
489             break;
490         case ADDR_PIPECFG_P4_32x32:
491             pAddr[0] = x3;
492             pXor1[0] = y3;
493             pXor2[0] = x5;
494             pAddr[1] = x5;
495             pXor1[1] = y5;
496             pEquation->numBits = 2;
497             break;
498         case ADDR_PIPECFG_P8_16x16_8x16:
499             pAddr[0] = x4;
500             pXor1[0] = y3;
501             pXor2[0] = x5;
502             pAddr[1] = x3;
503             pXor1[1] = y5;
504             pEquation->numBits = 3;
505             break;
506         case ADDR_PIPECFG_P8_16x32_8x16:
507             pAddr[0] = x4;
508             pXor1[0] = y3;
509             pXor2[0] = x5;
510             pAddr[1] = x3;
511             pXor1[1] = y4;
512             pAddr[2] = x4;
513             pXor1[2] = y5;
514             pEquation->numBits = 3;
515             break;
516         case ADDR_PIPECFG_P8_16x32_16x16:
517             pAddr[0] = x3;
518             pXor1[0] = y3;
519             pXor2[0] = x4;
520             pAddr[1] = x5;
521             pXor1[1] = y4;
522             pAddr[2] = x4;
523             pXor1[2] = y5;
524             pEquation->numBits = 3;
525             break;
526         case ADDR_PIPECFG_P8_32x32_8x16:
527             pAddr[0] = x4;
528             pXor1[0] = y3;
529             pXor2[0] = x5;
530             pAddr[1] = x3;
531             pXor1[1] = y4;
532             pAddr[2] = x5;
533             pXor1[2] = y5;
534             pEquation->numBits = 3;
535             break;
536         case ADDR_PIPECFG_P8_32x32_16x16:
537             pAddr[0] = x3;
538             pXor1[0] = y3;
539             pXor2[0] = x4;
540             pAddr[1] = x4;
541             pXor1[1] = y4;
542             pAddr[2] = x5;
543             pXor1[2] = y5;
544             pEquation->numBits = 3;
545             break;
546         case ADDR_PIPECFG_P8_32x32_16x32:
547             pAddr[0] = x3;
548             pXor1[0] = y3;
549             pXor2[0] = x4;
550             pAddr[1] = x4;
551             pXor1[1] = y6;
552             pAddr[2] = x5;
553             pXor1[2] = y5;
554             pEquation->numBits = 3;
555             break;
556         case ADDR_PIPECFG_P8_32x64_32x32:
557             pAddr[0] = x3;
558             pXor1[0] = y3;
559             pXor2[0] = x5;
560             pAddr[1] = x6;
561             pXor1[1] = y5;
562             pAddr[2] = x5;
563             pXor1[2] = y6;
564             pEquation->numBits = 3;
565             break;
566         case ADDR_PIPECFG_P16_32x32_8x16:
567             pAddr[0] = x4;
568             pXor1[0] = y3;
569             pAddr[1] = x3;
570             pXor1[1] = y4;
571             pAddr[2] = x5;
572             pXor1[2] = y6;
573             pAddr[3] = x6;
574             pXor1[3] = y5;
575             pEquation->numBits = 4;
576             break;
577         case ADDR_PIPECFG_P16_32x32_16x16:
578             pAddr[0] = x3;
579             pXor1[0] = y3;
580             pXor2[0] = x4;
581             pAddr[1] = x4;
582             pXor1[1] = y4;
583             pAddr[2] = x5;
584             pXor1[2] = y6;
585             pAddr[3] = x6;
586             pXor1[3] = y5;
587             pEquation->numBits = 4;
588             break;
589         default:
590             ADDR_UNHANDLED_CASE();
591             pEquation->numBits = 0;
592             retCode = ADDR_NOTSUPPORTED;
593             break;
594     }
595 
596     if (m_settings.isVegaM && (pEquation->numBits == 4))
597     {
598         ADDR_CHANNEL_SETTING addeMsb = pAddr[0];
599         ADDR_CHANNEL_SETTING xor1Msb = pXor1[0];
600         ADDR_CHANNEL_SETTING xor2Msb = pXor2[0];
601 
602         pAddr[0] = pAddr[1];
603         pXor1[0] = pXor1[1];
604         pXor2[0] = pXor2[1];
605 
606         pAddr[1] = pAddr[2];
607         pXor1[1] = pXor1[2];
608         pXor2[1] = pXor2[2];
609 
610         pAddr[2] = pAddr[3];
611         pXor1[2] = pXor1[3];
612         pXor2[2] = pXor2[3];
613 
614         pAddr[3] = addeMsb;
615         pXor1[3] = xor1Msb;
616         pXor2[3] = xor2Msb;
617     }
618 
619     for (UINT_32 i = 0; i < pEquation->numBits; i++)
620     {
621         if (pAddr[i].value == 0)
622         {
623             if (pXor1[i].value == 0)
624             {
625                 pAddr[i].value = pXor2[i].value;
626             }
627             else
628             {
629                 pAddr[i].value = pXor1[i].value;
630                 pXor1[i].value = 0;
631             }
632         }
633     }
634 
635     return retCode;
636 }
637 
638 /**
639 ****************************************************************************************************
640 *   SiLib::ComputePipeFromCoord
641 *
642 *   @brief
643 *       Compute pipe number from coordinates
644 *   @return
645 *       Pipe number
646 ****************************************************************************************************
647 */
ComputePipeFromCoord(UINT_32 x,UINT_32 y,UINT_32 slice,AddrTileMode tileMode,UINT_32 pipeSwizzle,BOOL_32 ignoreSE,ADDR_TILEINFO * pTileInfo) const648 UINT_32 SiLib::ComputePipeFromCoord(
649     UINT_32         x,              ///< [in] x coordinate
650     UINT_32         y,              ///< [in] y coordinate
651     UINT_32         slice,          ///< [in] slice index
652     AddrTileMode    tileMode,       ///< [in] tile mode
653     UINT_32         pipeSwizzle,    ///< [in] pipe swizzle
654     BOOL_32         ignoreSE,       ///< [in] TRUE if shader engines are ignored
655     ADDR_TILEINFO*  pTileInfo       ///< [in] Tile info
656     ) const
657 {
658     UINT_32 pipe;
659     UINT_32 pipeBit0 = 0;
660     UINT_32 pipeBit1 = 0;
661     UINT_32 pipeBit2 = 0;
662     UINT_32 pipeBit3 = 0;
663     UINT_32 sliceRotation;
664     UINT_32 numPipes = 0;
665 
666     UINT_32 tx = x / MicroTileWidth;
667     UINT_32 ty = y / MicroTileHeight;
668     UINT_32 x3 = _BIT(tx,0);
669     UINT_32 x4 = _BIT(tx,1);
670     UINT_32 x5 = _BIT(tx,2);
671     UINT_32 x6 = _BIT(tx,3);
672     UINT_32 y3 = _BIT(ty,0);
673     UINT_32 y4 = _BIT(ty,1);
674     UINT_32 y5 = _BIT(ty,2);
675     UINT_32 y6 = _BIT(ty,3);
676 
677     switch (pTileInfo->pipeConfig)
678     {
679         case ADDR_PIPECFG_P2:
680             pipeBit0 = x3 ^ y3;
681             numPipes = 2;
682             break;
683         case ADDR_PIPECFG_P4_8x16:
684             pipeBit0 = x4 ^ y3;
685             pipeBit1 = x3 ^ y4;
686             numPipes = 4;
687             break;
688         case ADDR_PIPECFG_P4_16x16:
689             pipeBit0 = x3 ^ y3 ^ x4;
690             pipeBit1 = x4 ^ y4;
691             numPipes = 4;
692             break;
693         case ADDR_PIPECFG_P4_16x32:
694             pipeBit0 = x3 ^ y3 ^ x4;
695             pipeBit1 = x4 ^ y5;
696             numPipes = 4;
697             break;
698         case ADDR_PIPECFG_P4_32x32:
699             pipeBit0 = x3 ^ y3 ^ x5;
700             pipeBit1 = x5 ^ y5;
701             numPipes = 4;
702             break;
703         case ADDR_PIPECFG_P8_16x16_8x16:
704             pipeBit0 = x4 ^ y3 ^ x5;
705             pipeBit1 = x3 ^ y5;
706             numPipes = 8;
707             break;
708         case ADDR_PIPECFG_P8_16x32_8x16:
709             pipeBit0 = x4 ^ y3 ^ x5;
710             pipeBit1 = x3 ^ y4;
711             pipeBit2 = x4 ^ y5;
712             numPipes = 8;
713             break;
714         case ADDR_PIPECFG_P8_16x32_16x16:
715             pipeBit0 = x3 ^ y3 ^ x4;
716             pipeBit1 = x5 ^ y4;
717             pipeBit2 = x4 ^ y5;
718             numPipes = 8;
719             break;
720         case ADDR_PIPECFG_P8_32x32_8x16:
721             pipeBit0 = x4 ^ y3 ^ x5;
722             pipeBit1 = x3 ^ y4;
723             pipeBit2 = x5 ^ y5;
724             numPipes = 8;
725             break;
726         case ADDR_PIPECFG_P8_32x32_16x16:
727             pipeBit0 = x3 ^ y3 ^ x4;
728             pipeBit1 = x4 ^ y4;
729             pipeBit2 = x5 ^ y5;
730             numPipes = 8;
731             break;
732         case ADDR_PIPECFG_P8_32x32_16x32:
733             pipeBit0 = x3 ^ y3 ^ x4;
734             pipeBit1 = x4 ^ y6;
735             pipeBit2 = x5 ^ y5;
736             numPipes = 8;
737             break;
738         case ADDR_PIPECFG_P8_32x64_32x32:
739             pipeBit0 = x3 ^ y3 ^ x5;
740             pipeBit1 = x6 ^ y5;
741             pipeBit2 = x5 ^ y6;
742             numPipes = 8;
743             break;
744         case ADDR_PIPECFG_P16_32x32_8x16:
745             pipeBit0 = x4 ^ y3;
746             pipeBit1 = x3 ^ y4;
747             pipeBit2 = x5 ^ y6;
748             pipeBit3 = x6 ^ y5;
749             numPipes = 16;
750             break;
751         case ADDR_PIPECFG_P16_32x32_16x16:
752             pipeBit0 = x3 ^ y3 ^ x4;
753             pipeBit1 = x4 ^ y4;
754             pipeBit2 = x5 ^ y6;
755             pipeBit3 = x6 ^ y5;
756             numPipes = 16;
757             break;
758         default:
759             ADDR_UNHANDLED_CASE();
760             break;
761     }
762 
763     if (m_settings.isVegaM && (numPipes == 16))
764     {
765         UINT_32 pipeMsb = pipeBit0;
766         pipeBit0 = pipeBit1;
767         pipeBit1 = pipeBit2;
768         pipeBit2 = pipeBit3;
769         pipeBit3 = pipeMsb;
770     }
771 
772     pipe = pipeBit0 | (pipeBit1 << 1) | (pipeBit2 << 2) | (pipeBit3 << 3);
773 
774     UINT_32 microTileThickness = Thickness(tileMode);
775 
776     //
777     // Apply pipe rotation for the slice.
778     //
779     switch (tileMode)
780     {
781         case ADDR_TM_3D_TILED_THIN1:    //fall through thin
782         case ADDR_TM_3D_TILED_THICK:    //fall through thick
783         case ADDR_TM_3D_TILED_XTHICK:
784             sliceRotation =
785                 Max(1, static_cast<INT_32>(numPipes / 2) - 1) * (slice / microTileThickness);
786             break;
787         default:
788             sliceRotation = 0;
789             break;
790     }
791     pipeSwizzle += sliceRotation;
792     pipeSwizzle &= (numPipes - 1);
793 
794     pipe = pipe ^ pipeSwizzle;
795 
796     return pipe;
797 }
798 
799 /**
800 ****************************************************************************************************
801 *   SiLib::ComputeTileCoordFromPipeAndElemIdx
802 *
803 *   @brief
804 *       Compute (x,y) of a tile within a macro tile from address
805 *   @return
806 *       Pipe number
807 ****************************************************************************************************
808 */
ComputeTileCoordFromPipeAndElemIdx(UINT_32 elemIdx,UINT_32 pipe,AddrPipeCfg pipeCfg,UINT_32 pitchInMacroTile,UINT_32 x,UINT_32 y,UINT_32 * pX,UINT_32 * pY) const809 VOID SiLib::ComputeTileCoordFromPipeAndElemIdx(
810     UINT_32         elemIdx,          ///< [in] per pipe element index within a macro tile
811     UINT_32         pipe,             ///< [in] pipe index
812     AddrPipeCfg     pipeCfg,          ///< [in] pipe config
813     UINT_32         pitchInMacroTile, ///< [in] surface pitch in macro tile
814     UINT_32         x,                ///< [in] x coordinate of the (0,0) tile in a macro tile
815     UINT_32         y,                ///< [in] y coordinate of the (0,0) tile in a macro tile
816     UINT_32*        pX,               ///< [out] x coordinate
817     UINT_32*        pY                ///< [out] y coordinate
818     ) const
819 {
820     UINT_32 pipebit0 = _BIT(pipe,0);
821     UINT_32 pipebit1 = _BIT(pipe,1);
822     UINT_32 pipebit2 = _BIT(pipe,2);
823     UINT_32 pipebit3 = _BIT(pipe,3);
824     UINT_32 elemIdx0 = _BIT(elemIdx,0);
825     UINT_32 elemIdx1 = _BIT(elemIdx,1);
826     UINT_32 elemIdx2 = _BIT(elemIdx,2);
827     UINT_32 x3 = 0;
828     UINT_32 x4 = 0;
829     UINT_32 x5 = 0;
830     UINT_32 x6 = 0;
831     UINT_32 y3 = 0;
832     UINT_32 y4 = 0;
833     UINT_32 y5 = 0;
834     UINT_32 y6 = 0;
835 
836     switch(pipeCfg)
837     {
838         case ADDR_PIPECFG_P2:
839             x4 = elemIdx2;
840             y4 = elemIdx1 ^ x4;
841             y3 = elemIdx0 ^ x4;
842             x3 = pipebit0 ^ y3;
843             *pY = Bits2Number(2, y4, y3);
844             *pX = Bits2Number(2, x4, x3);
845             break;
846         case ADDR_PIPECFG_P4_8x16:
847             x4 = elemIdx1;
848             y4 = elemIdx0 ^ x4;
849             x3 = pipebit1 ^ y4;
850             y3 = pipebit0 ^ x4;
851             *pY = Bits2Number(2, y4, y3);
852             *pX = Bits2Number(2, x4, x3);
853             break;
854         case ADDR_PIPECFG_P4_16x16:
855             x4 = elemIdx1;
856             y3 = elemIdx0 ^ x4;
857             y4 = pipebit1 ^ x4;
858             x3 = pipebit0 ^ y3 ^ x4;
859             *pY = Bits2Number(2, y4, y3);
860             *pX = Bits2Number(2, x4, x3);
861             break;
862         case ADDR_PIPECFG_P4_16x32:
863             x3 = elemIdx0 ^ pipebit0;
864             y5 = _BIT(y,5);
865             x4 = pipebit1 ^ y5;
866             y3 = pipebit0 ^ x3 ^ x4;
867             y4 = elemIdx1 ^ x4;
868             *pY = Bits2Number(2, y4, y3);
869             *pX = Bits2Number(2, x4, x3);
870             break;
871         case ADDR_PIPECFG_P4_32x32:
872             x4 = elemIdx2;
873             y3 = elemIdx0 ^ x4;
874             y4 = elemIdx1 ^ x4;
875             if((pitchInMacroTile % 2) == 0)
876             {   //even
877                 y5 = _BIT(y,5);
878                 x5 = pipebit1 ^ y5;
879                 x3 = pipebit0 ^ y3 ^ x5;
880                 *pY = Bits2Number(2, y4, y3);
881                 *pX = Bits2Number(3, x5, x4, x3);
882             }
883             else
884             {   //odd
885                 x5 = _BIT(x,5);
886                 x3 = pipebit0 ^ y3 ^ x5;
887                 *pY = Bits2Number(2, y4, y3);
888                 *pX = Bits2Number(2, x4, x3);
889             }
890             break;
891         case ADDR_PIPECFG_P8_16x16_8x16:
892             x4 = elemIdx0;
893             y5 = _BIT(y,5);
894             x5 = _BIT(x,5);
895             x3 = pipebit1 ^ y5;
896             y4 = pipebit2 ^ x4;
897             y3 = pipebit0 ^ x5 ^ x4;
898             *pY = Bits2Number(2, y4, y3);
899             *pX = Bits2Number(2, x4, x3);
900             break;
901         case ADDR_PIPECFG_P8_16x32_8x16:
902             x3 = elemIdx0;
903             y4 = pipebit1 ^ x3;
904             y5 = _BIT(y,5);
905             x5 = _BIT(x,5);
906             x4 = pipebit2 ^ y5;
907             y3 = pipebit0 ^ x4 ^ x5;
908             *pY = Bits2Number(2, y4, y3);
909             *pX = Bits2Number(2, x4, x3);
910             break;
911         case ADDR_PIPECFG_P8_32x32_8x16:
912             x4 = elemIdx1;
913             y4 = elemIdx0 ^ x4;
914             x3 = pipebit1 ^ y4;
915             if((pitchInMacroTile % 2) == 0)
916             {  //even
917                 y5 = _BIT(y,5);
918                 x5 = _BIT(x,5);
919                 x5 = pipebit2 ^ y5;
920                 y3 = pipebit0 ^ x4 ^ x5;
921                 *pY = Bits2Number(2, y4, y3);
922                 *pX = Bits2Number(3, x5, x4, x3);
923             }
924             else
925             {  //odd
926                 x5 = _BIT(x,5);
927                 y3 = pipebit0 ^ x4 ^ x5;
928                 *pY = Bits2Number(2, y4, y3);
929                 *pX = Bits2Number(2, x4, x3);
930             }
931             break;
932         case ADDR_PIPECFG_P8_16x32_16x16:
933             x3 = elemIdx0;
934             x5 = _BIT(x,5);
935             y5 = _BIT(y,5);
936             x4 = pipebit2 ^ y5;
937             y4 = pipebit1 ^ x5;
938             y3 = pipebit0 ^ x3 ^ x4;
939             *pY = Bits2Number(2, y4, y3);
940             *pX = Bits2Number(2, x4, x3);
941             break;
942         case ADDR_PIPECFG_P8_32x32_16x16:
943             x4 = elemIdx1;
944             y3 = elemIdx0 ^ x4;
945             x3 = y3^x4^pipebit0;
946             y4 = pipebit1 ^ x4;
947             if((pitchInMacroTile % 2) == 0)
948             {   //even
949                 y5 = _BIT(y,5);
950                 x5 = pipebit2 ^ y5;
951                 *pY = Bits2Number(2, y4, y3);
952                 *pX = Bits2Number(3, x5, x4, x3);
953             }
954             else
955             {   //odd
956                 *pY = Bits2Number(2, y4, y3);
957                 *pX = Bits2Number(2, x4, x3);
958             }
959             break;
960         case ADDR_PIPECFG_P8_32x32_16x32:
961             if((pitchInMacroTile % 2) == 0)
962             {   //even
963                 y5 = _BIT(y,5);
964                 y6 = _BIT(y,6);
965                 x4 = pipebit1 ^ y6;
966                 y3 = elemIdx0 ^ x4;
967                 y4 = elemIdx1 ^ x4;
968                 x3 = pipebit0 ^ y3 ^ x4;
969                 x5 = pipebit2 ^ y5;
970                 *pY = Bits2Number(2, y4, y3);
971                 *pX = Bits2Number(3, x5, x4, x3);
972             }
973             else
974             {   //odd
975                 y6 = _BIT(y,6);
976                 x4 = pipebit1 ^ y6;
977                 y3 = elemIdx0 ^ x4;
978                 y4 = elemIdx1 ^ x4;
979                 x3 = pipebit0 ^ y3 ^ x4;
980                 *pY = Bits2Number(2, y4, y3);
981                 *pX = Bits2Number(2, x4, x3);
982             }
983             break;
984         case ADDR_PIPECFG_P8_32x64_32x32:
985             x4 = elemIdx2;
986             y3 = elemIdx0 ^ x4;
987             y4 = elemIdx1 ^ x4;
988             if((pitchInMacroTile % 4) == 0)
989             {   //multiple of 4
990                 y5 = _BIT(y,5);
991                 y6 = _BIT(y,6);
992                 x5 = pipebit2 ^ y6;
993                 x6 = pipebit1 ^ y5;
994                 x3 = pipebit0 ^ y3 ^ x5;
995                 *pY = Bits2Number(2, y4, y3);
996                 *pX = Bits2Number(4, x6, x5, x4, x3);
997             }
998             else
999             {
1000                 y6 = _BIT(y,6);
1001                 x5 = pipebit2 ^ y6;
1002                 x3 = pipebit0 ^ y3 ^ x5;
1003                 *pY = Bits2Number(2, y4, y3);
1004                 *pX = Bits2Number(3, x5, x4, x3);
1005             }
1006             break;
1007         case ADDR_PIPECFG_P16_32x32_8x16:
1008             x4 = elemIdx1;
1009             y4 = elemIdx0 ^ x4;
1010             y3 = pipebit0 ^ x4;
1011             x3 = pipebit1 ^ y4;
1012             if((pitchInMacroTile % 4) == 0)
1013             {   //multiple of 4
1014                 y5 = _BIT(y,5);
1015                 y6 = _BIT(y,6);
1016                 x5 = pipebit2 ^ y6;
1017                 x6 = pipebit3 ^ y5;
1018                 *pY = Bits2Number(2, y4, y3);
1019                 *pX = Bits2Number(4, x6, x5,x4, x3);
1020             }
1021             else
1022             {
1023                 y6 = _BIT(y,6);
1024                 x5 = pipebit2 ^ y6;
1025                 *pY = Bits2Number(2, y4, y3);
1026                 *pX = Bits2Number(3, x5, x4, x3);
1027             }
1028             break;
1029         case ADDR_PIPECFG_P16_32x32_16x16:
1030             x4 = elemIdx1;
1031             y3 = elemIdx0 ^ x4;
1032             y4 = pipebit1 ^ x4;
1033             x3 = pipebit0 ^ y3 ^ x4;
1034             if((pitchInMacroTile % 4) == 0)
1035             {   //multiple of 4
1036                 y5 = _BIT(y,5);
1037                 y6 = _BIT(y,6);
1038                 x5 = pipebit2 ^ y6;
1039                 x6 = pipebit3 ^ y5;
1040                 *pY = Bits2Number(2, y4, y3);
1041                 *pX = Bits2Number(4, x6, x5, x4, x3);
1042             }
1043             else
1044             {
1045                 y6 = _BIT(y,6);
1046                 x5 = pipebit2 ^ y6;
1047                 *pY = Bits2Number(2, y4, y3);
1048                 *pX = Bits2Number(3, x5, x4, x3);
1049             }
1050             break;
1051         default:
1052             ADDR_UNHANDLED_CASE();
1053     }
1054 }
1055 
1056 /**
1057 ****************************************************************************************************
1058 *   SiLib::TileCoordToMaskElementIndex
1059 *
1060 *   @brief
1061 *       Compute element index from coordinates in tiles
1062 *   @return
1063 *       Element index
1064 ****************************************************************************************************
1065 */
TileCoordToMaskElementIndex(UINT_32 tx,UINT_32 ty,AddrPipeCfg pipeConfig,UINT_32 * macroShift,UINT_32 * elemIdxBits) const1066 UINT_32 SiLib::TileCoordToMaskElementIndex(
1067     UINT_32         tx,                 ///< [in] x coord, in Tiles
1068     UINT_32         ty,                 ///< [in] y coord, in Tiles
1069     AddrPipeCfg     pipeConfig,         ///< [in] pipe config
1070     UINT_32*        macroShift,         ///< [out] macro shift
1071     UINT_32*        elemIdxBits         ///< [out] tile offset bits
1072     ) const
1073 {
1074     UINT_32 elemIdx = 0;
1075     UINT_32 elemIdx0, elemIdx1, elemIdx2;
1076     UINT_32 tx0, tx1;
1077     UINT_32 ty0, ty1;
1078 
1079     tx0 = _BIT(tx,0);
1080     tx1 = _BIT(tx,1);
1081     ty0 = _BIT(ty,0);
1082     ty1 = _BIT(ty,1);
1083 
1084     switch(pipeConfig)
1085     {
1086         case ADDR_PIPECFG_P2:
1087             *macroShift = 3;
1088             *elemIdxBits =3;
1089             elemIdx2 = tx1;
1090             elemIdx1 = tx1 ^ ty1;
1091             elemIdx0 = tx1 ^ ty0;
1092             elemIdx = Bits2Number(3,elemIdx2,elemIdx1,elemIdx0);
1093             break;
1094         case ADDR_PIPECFG_P4_8x16:
1095             *macroShift = 2;
1096             *elemIdxBits =2;
1097             elemIdx1 = tx1;
1098             elemIdx0 = tx1 ^ ty1;
1099             elemIdx = Bits2Number(2,elemIdx1,elemIdx0);
1100             break;
1101         case ADDR_PIPECFG_P4_16x16:
1102             *macroShift = 2;
1103             *elemIdxBits =2;
1104             elemIdx0 = tx1^ty0;
1105             elemIdx1 = tx1;
1106             elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
1107             break;
1108         case ADDR_PIPECFG_P4_16x32:
1109             *macroShift = 2;
1110             *elemIdxBits =2;
1111             elemIdx0 = tx1^ty0;
1112             elemIdx1 = tx1^ty1;
1113             elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
1114             break;
1115         case ADDR_PIPECFG_P4_32x32:
1116             *macroShift = 2;
1117             *elemIdxBits =3;
1118             elemIdx0 = tx1^ty0;
1119             elemIdx1 = tx1^ty1;
1120             elemIdx2 = tx1;
1121             elemIdx = Bits2Number(3, elemIdx2, elemIdx1, elemIdx0);
1122             break;
1123         case ADDR_PIPECFG_P8_16x16_8x16:
1124             *macroShift = 1;
1125             *elemIdxBits =1;
1126             elemIdx0 = tx1;
1127             elemIdx = elemIdx0;
1128             break;
1129         case ADDR_PIPECFG_P8_16x32_8x16:
1130             *macroShift = 1;
1131             *elemIdxBits =1;
1132             elemIdx0 = tx0;
1133             elemIdx = elemIdx0;
1134             break;
1135         case ADDR_PIPECFG_P8_32x32_8x16:
1136             *macroShift = 1;
1137             *elemIdxBits =2;
1138             elemIdx1 = tx1;
1139             elemIdx0 = tx1^ty1;
1140             elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
1141             break;
1142         case ADDR_PIPECFG_P8_16x32_16x16:
1143             *macroShift = 1;
1144             *elemIdxBits =1;
1145             elemIdx0 = tx0;
1146             elemIdx = elemIdx0;
1147             break;
1148         case ADDR_PIPECFG_P8_32x32_16x16:
1149             *macroShift = 1;
1150             *elemIdxBits =2;
1151             elemIdx0 = tx1^ty0;
1152             elemIdx1 = tx1;
1153             elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
1154             break;
1155         case ADDR_PIPECFG_P8_32x32_16x32:
1156             *macroShift = 1;
1157             *elemIdxBits =2;
1158             elemIdx0 =  tx1^ty0;
1159             elemIdx1 = tx1^ty1;
1160             elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
1161             break;
1162         case ADDR_PIPECFG_P8_32x64_32x32:
1163             *macroShift = 1;
1164             *elemIdxBits =3;
1165             elemIdx0 = tx1^ty0;
1166             elemIdx1 = tx1^ty1;
1167             elemIdx2 = tx1;
1168             elemIdx = Bits2Number(3, elemIdx2, elemIdx1, elemIdx0);
1169             break;
1170         case ADDR_PIPECFG_P16_32x32_8x16:
1171             *macroShift = 0;
1172             *elemIdxBits =2;
1173             elemIdx0 = tx1^ty1;
1174             elemIdx1 = tx1;
1175             elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
1176             break;
1177         case ADDR_PIPECFG_P16_32x32_16x16:
1178             *macroShift = 0;
1179             *elemIdxBits =2;
1180             elemIdx0 = tx1^ty0;
1181             elemIdx1 = tx1;
1182             elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
1183             break;
1184         default:
1185             ADDR_UNHANDLED_CASE();
1186             break;
1187     }
1188 
1189     return elemIdx;
1190 }
1191 
1192 /**
1193 ****************************************************************************************************
1194 *   SiLib::HwlComputeTileDataWidthAndHeightLinear
1195 *
1196 *   @brief
1197 *       Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1198 *
1199 *   @return
1200 *       N/A
1201 *
1202 *   @note
1203 *       MacroWidth and macroHeight are measured in pixels
1204 ****************************************************************************************************
1205 */
HwlComputeTileDataWidthAndHeightLinear(UINT_32 * pMacroWidth,UINT_32 * pMacroHeight,UINT_32 bpp,ADDR_TILEINFO * pTileInfo) const1206 VOID SiLib::HwlComputeTileDataWidthAndHeightLinear(
1207     UINT_32*        pMacroWidth,     ///< [out] macro tile width
1208     UINT_32*        pMacroHeight,    ///< [out] macro tile height
1209     UINT_32         bpp,             ///< [in] bits per pixel
1210     ADDR_TILEINFO*  pTileInfo        ///< [in] tile info
1211     ) const
1212 {
1213     ADDR_ASSERT(pTileInfo != NULL);
1214     UINT_32 macroWidth;
1215     UINT_32 macroHeight;
1216 
1217     /// In linear mode, the htile or cmask buffer must be padded out to 4 tiles
1218     /// but for P8_32x64_32x32, it must be padded out to 8 tiles
1219     /// Actually there are more pipe configs which need 8-tile padding but SI family
1220     /// has a bug which is fixed in CI family
1221     if ((pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32) ||
1222         (pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_8x16) ||
1223         (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x32_16x16))
1224     {
1225         macroWidth  = 8*MicroTileWidth;
1226         macroHeight = 8*MicroTileHeight;
1227     }
1228     else
1229     {
1230         macroWidth  = 4*MicroTileWidth;
1231         macroHeight = 4*MicroTileHeight;
1232     }
1233 
1234     *pMacroWidth    = macroWidth;
1235     *pMacroHeight   = macroHeight;
1236 }
1237 
1238 /**
1239 ****************************************************************************************************
1240 *   SiLib::HwlComputeHtileBytes
1241 *
1242 *   @brief
1243 *       Compute htile size in bytes
1244 *
1245 *   @return
1246 *       Htile size in bytes
1247 ****************************************************************************************************
1248 */
HwlComputeHtileBytes(UINT_32 pitch,UINT_32 height,UINT_32 bpp,BOOL_32 isLinear,UINT_32 numSlices,UINT_64 * pSliceBytes,UINT_32 baseAlign) const1249 UINT_64 SiLib::HwlComputeHtileBytes(
1250     UINT_32     pitch,          ///< [in] pitch
1251     UINT_32     height,         ///< [in] height
1252     UINT_32     bpp,            ///< [in] bits per pixel
1253     BOOL_32     isLinear,       ///< [in] if it is linear mode
1254     UINT_32     numSlices,      ///< [in] number of slices
1255     UINT_64*    pSliceBytes,    ///< [out] bytes per slice
1256     UINT_32     baseAlign       ///< [in] base alignments
1257     ) const
1258 {
1259     return ComputeHtileBytes(pitch, height, bpp, isLinear, numSlices, pSliceBytes, baseAlign);
1260 }
1261 
1262 /**
1263 ****************************************************************************************************
1264 *   SiLib::HwlComputeXmaskAddrFromCoord
1265 *
1266 *   @brief
1267 *       Compute address from coordinates for htile/cmask
1268 *   @return
1269 *       Byte address
1270 ****************************************************************************************************
1271 */
HwlComputeXmaskAddrFromCoord(UINT_32 pitch,UINT_32 height,UINT_32 x,UINT_32 y,UINT_32 slice,UINT_32 numSlices,UINT_32 factor,BOOL_32 isLinear,BOOL_32 isWidth8,BOOL_32 isHeight8,ADDR_TILEINFO * pTileInfo,UINT_32 * pBitPosition) const1272 UINT_64 SiLib::HwlComputeXmaskAddrFromCoord(
1273     UINT_32        pitch,          ///< [in] pitch
1274     UINT_32        height,         ///< [in] height
1275     UINT_32        x,              ///< [in] x coord
1276     UINT_32        y,              ///< [in] y coord
1277     UINT_32        slice,          ///< [in] slice/depth index
1278     UINT_32        numSlices,      ///< [in] number of slices
1279     UINT_32        factor,         ///< [in] factor that indicates cmask(2) or htile(1)
1280     BOOL_32        isLinear,       ///< [in] linear or tiled HTILE layout
1281     BOOL_32        isWidth8,       ///< [in] TRUE if width is 8, FALSE means 4. It's register value
1282     BOOL_32        isHeight8,      ///< [in] TRUE if width is 8, FALSE means 4. It's register value
1283     ADDR_TILEINFO* pTileInfo,      ///< [in] Tile info
1284     UINT_32*       pBitPosition    ///< [out] bit position inside a byte
1285     ) const
1286 {
1287     UINT_32 tx = x / MicroTileWidth;
1288     UINT_32 ty = y / MicroTileHeight;
1289     UINT_32 newPitch;
1290     UINT_32 newHeight;
1291     UINT_64 totalBytes;
1292     UINT_32 macroWidth;
1293     UINT_32 macroHeight;
1294     UINT_64 pSliceBytes;
1295     UINT_32 pBaseAlign;
1296     UINT_32 tileNumPerPipe;
1297     UINT_32 elemBits;
1298 
1299     if (factor == 2) //CMASK
1300     {
1301         ADDR_CMASK_FLAGS flags = {{0}};
1302 
1303         tileNumPerPipe = 256;
1304 
1305         ComputeCmaskInfo(flags,
1306                          pitch,
1307                          height,
1308                          numSlices,
1309                          isLinear,
1310                          pTileInfo,
1311                          &newPitch,
1312                          &newHeight,
1313                          &totalBytes,
1314                          &macroWidth,
1315                          &macroHeight);
1316         elemBits = CmaskElemBits;
1317     }
1318     else //HTile
1319     {
1320         ADDR_HTILE_FLAGS flags = {{0}};
1321 
1322         tileNumPerPipe = 512;
1323 
1324         ComputeHtileInfo(flags,
1325                          pitch,
1326                          height,
1327                          numSlices,
1328                          isLinear,
1329                          TRUE,
1330                          TRUE,
1331                          pTileInfo,
1332                          &newPitch,
1333                          &newHeight,
1334                          &totalBytes,
1335                          &macroWidth,
1336                          &macroHeight,
1337                          &pSliceBytes,
1338                          &pBaseAlign);
1339         elemBits = 32;
1340     }
1341 
1342     const UINT_32 pitchInTile = newPitch / MicroTileWidth;
1343     const UINT_32 heightInTile = newHeight / MicroTileWidth;
1344     UINT_64 macroOffset; // Per pipe starting offset of the macro tile in which this tile lies.
1345     UINT_64 microNumber; // Per pipe starting offset of the macro tile in which this tile lies.
1346     UINT_32 microX;
1347     UINT_32 microY;
1348     UINT_64 microOffset;
1349     UINT_32 microShift;
1350     UINT_64 totalOffset;
1351     UINT_32 elemIdxBits;
1352     UINT_32 elemIdx =
1353         TileCoordToMaskElementIndex(tx, ty, pTileInfo->pipeConfig, &microShift, &elemIdxBits);
1354 
1355     UINT_32 numPipes = HwlGetPipes(pTileInfo);
1356 
1357     if (isLinear)
1358     {   //linear addressing
1359         // Linear addressing is extremelly wasting memory if slice > 1, since each pipe has the full
1360         // slice memory foot print instead of divided by numPipes.
1361         microX = tx / 4; // Macro Tile is 4x4
1362         microY = ty / 4 ;
1363         microNumber = static_cast<UINT_64>(microX + microY * (pitchInTile / 4)) << microShift;
1364 
1365         UINT_32 sliceBits = pitchInTile * heightInTile;
1366 
1367         // do htile single slice alignment if the flag is true
1368         if (m_configFlags.useHtileSliceAlign && (factor == 1))  //Htile
1369         {
1370             sliceBits = PowTwoAlign(sliceBits, BITS_TO_BYTES(HtileCacheBits) * numPipes / elemBits);
1371         }
1372         macroOffset = slice * (sliceBits / numPipes) * elemBits ;
1373     }
1374     else
1375     {   //tiled addressing
1376         const UINT_32 macroWidthInTile = macroWidth / MicroTileWidth; // Now in unit of Tiles
1377         const UINT_32 macroHeightInTile = macroHeight / MicroTileHeight;
1378         const UINT_32 pitchInCL = pitchInTile / macroWidthInTile;
1379         const UINT_32 heightInCL = heightInTile / macroHeightInTile;
1380 
1381         const UINT_32 macroX = x / macroWidth;
1382         const UINT_32 macroY = y / macroHeight;
1383         const UINT_32 macroNumber = macroX + macroY * pitchInCL + slice * pitchInCL * heightInCL;
1384 
1385         // Per pipe starting offset of the cache line in which this tile lies.
1386         microX = (x % macroWidth) / MicroTileWidth / 4; // Macro Tile is 4x4
1387         microY = (y % macroHeight) / MicroTileHeight / 4 ;
1388         microNumber = static_cast<UINT_64>(microX + microY * (macroWidth / MicroTileWidth / 4)) << microShift;
1389 
1390         macroOffset = macroNumber * tileNumPerPipe * elemBits;
1391     }
1392 
1393     if(elemIdxBits == microShift)
1394     {
1395         microNumber += elemIdx;
1396     }
1397     else
1398     {
1399         microNumber >>= elemIdxBits;
1400         microNumber <<= elemIdxBits;
1401         microNumber += elemIdx;
1402     }
1403 
1404     microOffset = elemBits * microNumber;
1405     totalOffset = microOffset + macroOffset;
1406 
1407     UINT_32 pipe = ComputePipeFromCoord(x, y, 0, ADDR_TM_2D_TILED_THIN1, 0, FALSE, pTileInfo);
1408     UINT_64 addrInBits = totalOffset % (m_pipeInterleaveBytes * 8) +
1409                    pipe * (m_pipeInterleaveBytes * 8) +
1410                    totalOffset / (m_pipeInterleaveBytes * 8) * (m_pipeInterleaveBytes * 8) * numPipes;
1411     *pBitPosition = static_cast<UINT_32>(addrInBits) % 8;
1412     UINT_64 addr = addrInBits / 8;
1413 
1414     return addr;
1415 }
1416 
1417 /**
1418 ****************************************************************************************************
1419 *   SiLib::HwlComputeXmaskCoordFromAddr
1420 *
1421 *   @brief
1422 *       Compute the coord from an address of a cmask/htile
1423 *
1424 *   @return
1425 *       N/A
1426 *
1427 *   @note
1428 *       This method is reused by htile, so rename to Xmask
1429 ****************************************************************************************************
1430 */
HwlComputeXmaskCoordFromAddr(UINT_64 addr,UINT_32 bitPosition,UINT_32 pitch,UINT_32 height,UINT_32 numSlices,UINT_32 factor,BOOL_32 isLinear,BOOL_32 isWidth8,BOOL_32 isHeight8,ADDR_TILEINFO * pTileInfo,UINT_32 * pX,UINT_32 * pY,UINT_32 * pSlice) const1431 VOID SiLib::HwlComputeXmaskCoordFromAddr(
1432     UINT_64         addr,           ///< [in] address
1433     UINT_32         bitPosition,    ///< [in] bitPosition in a byte
1434     UINT_32         pitch,          ///< [in] pitch
1435     UINT_32         height,         ///< [in] height
1436     UINT_32         numSlices,      ///< [in] number of slices
1437     UINT_32         factor,         ///< [in] factor that indicates cmask or htile
1438     BOOL_32         isLinear,       ///< [in] linear or tiled HTILE layout
1439     BOOL_32         isWidth8,       ///< [in] Not used by SI
1440     BOOL_32         isHeight8,      ///< [in] Not used by SI
1441     ADDR_TILEINFO*  pTileInfo,      ///< [in] Tile info
1442     UINT_32*        pX,             ///< [out] x coord
1443     UINT_32*        pY,             ///< [out] y coord
1444     UINT_32*        pSlice          ///< [out] slice index
1445     ) const
1446 {
1447     UINT_32 newPitch;
1448     UINT_32 newHeight;
1449     UINT_64 totalBytes;
1450     UINT_32 clWidth;
1451     UINT_32 clHeight;
1452     UINT_32 tileNumPerPipe;
1453     UINT_64 sliceBytes;
1454 
1455     *pX = 0;
1456     *pY = 0;
1457     *pSlice = 0;
1458 
1459     if (factor == 2) //CMASK
1460     {
1461         ADDR_CMASK_FLAGS flags = {{0}};
1462 
1463         tileNumPerPipe = 256;
1464 
1465         ComputeCmaskInfo(flags,
1466                          pitch,
1467                          height,
1468                          numSlices,
1469                          isLinear,
1470                          pTileInfo,
1471                          &newPitch,
1472                          &newHeight,
1473                          &totalBytes,
1474                          &clWidth,
1475                          &clHeight);
1476     }
1477     else //HTile
1478     {
1479         ADDR_HTILE_FLAGS flags = {{0}};
1480 
1481         tileNumPerPipe = 512;
1482 
1483         ComputeHtileInfo(flags,
1484                          pitch,
1485                          height,
1486                          numSlices,
1487                          isLinear,
1488                          TRUE,
1489                          TRUE,
1490                          pTileInfo,
1491                          &newPitch,
1492                          &newHeight,
1493                          &totalBytes,
1494                          &clWidth,
1495                          &clHeight,
1496                          &sliceBytes);
1497     }
1498 
1499     const UINT_32 pitchInTile = newPitch / MicroTileWidth;
1500     const UINT_32 heightInTile = newHeight / MicroTileWidth;
1501     const UINT_32 pitchInMacroTile = pitchInTile / 4;
1502     UINT_32 macroShift;
1503     UINT_32 elemIdxBits;
1504     // get macroShift and elemIdxBits
1505     TileCoordToMaskElementIndex(0, 0, pTileInfo->pipeConfig, &macroShift, &elemIdxBits);
1506 
1507     const UINT_32 numPipes = HwlGetPipes(pTileInfo);
1508     const UINT_32 pipe = (UINT_32)((addr / m_pipeInterleaveBytes) % numPipes);
1509     // per pipe
1510     UINT_64 localOffset = (addr % m_pipeInterleaveBytes) +
1511         (addr / m_pipeInterleaveBytes / numPipes)* m_pipeInterleaveBytes;
1512 
1513     UINT_32 tileIndex;
1514     if (factor == 2) //CMASK
1515     {
1516         tileIndex = (UINT_32)(localOffset * 2 + (bitPosition != 0));
1517     }
1518     else
1519     {
1520         tileIndex = (UINT_32)(localOffset / 4);
1521     }
1522 
1523     UINT_32 macroOffset;
1524     if (isLinear)
1525     {
1526         UINT_32 sliceSizeInTile = pitchInTile * heightInTile;
1527 
1528         // do htile single slice alignment if the flag is true
1529         if (m_configFlags.useHtileSliceAlign && (factor == 1))  //Htile
1530         {
1531             sliceSizeInTile = PowTwoAlign(sliceSizeInTile, static_cast<UINT_32>(sliceBytes) / 64);
1532         }
1533         *pSlice = tileIndex / (sliceSizeInTile / numPipes);
1534         macroOffset = tileIndex % (sliceSizeInTile / numPipes);
1535     }
1536     else
1537     {
1538         const UINT_32 clWidthInTile = clWidth / MicroTileWidth; // Now in unit of Tiles
1539         const UINT_32 clHeightInTile = clHeight / MicroTileHeight;
1540         const UINT_32 pitchInCL = pitchInTile / clWidthInTile;
1541         const UINT_32 heightInCL = heightInTile / clHeightInTile;
1542         const UINT_32 clIndex = tileIndex / tileNumPerPipe;
1543 
1544         UINT_32 clX = clIndex % pitchInCL;
1545         UINT_32 clY = (clIndex % (heightInCL * pitchInCL)) / pitchInCL;
1546 
1547         *pX = clX * clWidthInTile * MicroTileWidth;
1548         *pY = clY * clHeightInTile * MicroTileHeight;
1549         *pSlice = clIndex / (heightInCL * pitchInCL);
1550 
1551         macroOffset = tileIndex % tileNumPerPipe;
1552     }
1553 
1554     UINT_32 elemIdx = macroOffset & 7;
1555     macroOffset >>= elemIdxBits;
1556 
1557     if (elemIdxBits != macroShift)
1558     {
1559         macroOffset <<= (elemIdxBits - macroShift);
1560 
1561         UINT_32 pipebit1 = _BIT(pipe,1);
1562         UINT_32 pipebit2 = _BIT(pipe,2);
1563         UINT_32 pipebit3 = _BIT(pipe,3);
1564         if (pitchInMacroTile % 2)
1565         {   //odd
1566             switch (pTileInfo->pipeConfig)
1567             {
1568                 case ADDR_PIPECFG_P4_32x32:
1569                     macroOffset |= pipebit1;
1570                     break;
1571                 case ADDR_PIPECFG_P8_32x32_8x16:
1572                 case ADDR_PIPECFG_P8_32x32_16x16:
1573                 case ADDR_PIPECFG_P8_32x32_16x32:
1574                     macroOffset |= pipebit2;
1575                     break;
1576                 default:
1577                     break;
1578             }
1579 
1580         }
1581 
1582         if (pitchInMacroTile % 4)
1583         {
1584             if (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32)
1585             {
1586                 macroOffset |= (pipebit1<<1);
1587             }
1588             if ((pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_8x16) ||
1589                 (pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_16x16)
1590                )
1591             {
1592                 macroOffset |= (pipebit3<<1);
1593             }
1594         }
1595     }
1596 
1597     UINT_32 macroX;
1598     UINT_32 macroY;
1599 
1600     if (isLinear)
1601     {
1602         macroX = macroOffset % pitchInMacroTile;
1603         macroY = macroOffset / pitchInMacroTile;
1604     }
1605     else
1606     {
1607         const UINT_32 clWidthInMacroTile = clWidth / (MicroTileWidth * 4);
1608         macroX = macroOffset % clWidthInMacroTile;
1609         macroY = macroOffset / clWidthInMacroTile;
1610     }
1611 
1612     *pX += macroX * 4 * MicroTileWidth;
1613     *pY += macroY * 4 * MicroTileHeight;
1614 
1615     UINT_32 microX;
1616     UINT_32 microY;
1617     ComputeTileCoordFromPipeAndElemIdx(elemIdx, pipe, pTileInfo->pipeConfig, pitchInMacroTile,
1618                                        *pX, *pY, &microX, &microY);
1619 
1620     *pX += microX * MicroTileWidth;
1621     *pY += microY * MicroTileWidth;
1622 }
1623 
1624 /**
1625 ****************************************************************************************************
1626 *   SiLib::HwlGetPitchAlignmentLinear
1627 *   @brief
1628 *       Get pitch alignment
1629 *   @return
1630 *       pitch alignment
1631 ****************************************************************************************************
1632 */
HwlGetPitchAlignmentLinear(UINT_32 bpp,ADDR_SURFACE_FLAGS flags) const1633 UINT_32 SiLib::HwlGetPitchAlignmentLinear(
1634     UINT_32             bpp,    ///< [in] bits per pixel
1635     ADDR_SURFACE_FLAGS  flags   ///< [in] surface flags
1636     ) const
1637 {
1638     UINT_32 pitchAlign;
1639 
1640     // Interleaved access requires a 256B aligned pitch, so fall back to pre-SI alignment
1641     if (flags.interleaved)
1642     {
1643         pitchAlign = Max(64u, m_pipeInterleaveBytes / BITS_TO_BYTES(bpp));
1644 
1645     }
1646     else
1647     {
1648         {
1649             pitchAlign = Max(8u, 64 / BITS_TO_BYTES(bpp));
1650         }
1651     }
1652 
1653     return pitchAlign;
1654 }
1655 
1656 /**
1657 ****************************************************************************************************
1658 *   SiLib::HwlGetSizeAdjustmentLinear
1659 *
1660 *   @brief
1661 *       Adjust linear surface pitch and slice size
1662 *
1663 *   @return
1664 *       Logical slice size in bytes
1665 ****************************************************************************************************
1666 */
HwlGetSizeAdjustmentLinear(AddrTileMode tileMode,UINT_32 bpp,UINT_32 numSamples,UINT_32 baseAlign,UINT_32 pitchAlign,UINT_32 * pPitch,UINT_32 * pHeight,UINT_32 * pHeightAlign) const1667 UINT_64 SiLib::HwlGetSizeAdjustmentLinear(
1668     AddrTileMode        tileMode,       ///< [in] tile mode
1669     UINT_32             bpp,            ///< [in] bits per pixel
1670     UINT_32             numSamples,     ///< [in] number of samples
1671     UINT_32             baseAlign,      ///< [in] base alignment
1672     UINT_32             pitchAlign,     ///< [in] pitch alignment
1673     UINT_32*            pPitch,         ///< [in,out] pointer to pitch
1674     UINT_32*            pHeight,        ///< [in,out] pointer to height
1675     UINT_32*            pHeightAlign    ///< [in,out] pointer to height align
1676     ) const
1677 {
1678     UINT_64 sliceSize;
1679     if (tileMode == ADDR_TM_LINEAR_GENERAL)
1680     {
1681         sliceSize = BITS_TO_BYTES(static_cast<UINT_64>(*pPitch) * (*pHeight) * bpp * numSamples);
1682     }
1683     else
1684     {
1685         UINT_32 pitch   = *pPitch;
1686         UINT_32 height  = *pHeight;
1687 
1688         UINT_32 pixelsPerPipeInterleave = m_pipeInterleaveBytes / BITS_TO_BYTES(bpp);
1689         UINT_32 sliceAlignInPixel = pixelsPerPipeInterleave < 64 ? 64 : pixelsPerPipeInterleave;
1690 
1691         // numSamples should be 1 in real cases (no MSAA for linear but TGL may pass non 1 value)
1692         UINT_64 pixelPerSlice = static_cast<UINT_64>(pitch) * height * numSamples;
1693 
1694         while (pixelPerSlice % sliceAlignInPixel)
1695         {
1696             pitch += pitchAlign;
1697             pixelPerSlice = static_cast<UINT_64>(pitch) * height * numSamples;
1698         }
1699 
1700         *pPitch = pitch;
1701 
1702         UINT_32 heightAlign = 1;
1703 
1704         while ((pitch * heightAlign) % sliceAlignInPixel)
1705         {
1706             heightAlign++;
1707         }
1708 
1709         *pHeightAlign = heightAlign;
1710 
1711         sliceSize = BITS_TO_BYTES(pixelPerSlice * bpp);
1712     }
1713 
1714     return sliceSize;
1715 }
1716 
1717 /**
1718 ****************************************************************************************************
1719 *   SiLib::HwlPreHandleBaseLvl3xPitch
1720 *
1721 *   @brief
1722 *       Pre-handler of 3x pitch (96 bit) adjustment
1723 *
1724 *   @return
1725 *       Expected pitch
1726 ****************************************************************************************************
1727 */
HwlPreHandleBaseLvl3xPitch(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,UINT_32 expPitch) const1728 UINT_32 SiLib::HwlPreHandleBaseLvl3xPitch(
1729     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] input
1730     UINT_32                                 expPitch    ///< [in] pitch
1731     ) const
1732 {
1733     ADDR_ASSERT(pIn->width == expPitch);
1734 
1735     // From SI, if pow2Pad is 1 the pitch is expanded 3x first, then padded to pow2, so nothing to
1736     // do here
1737     if (pIn->flags.pow2Pad == FALSE)
1738     {
1739         Addr::V1::Lib::HwlPreHandleBaseLvl3xPitch(pIn, expPitch);
1740     }
1741     else
1742     {
1743         ADDR_ASSERT(IsPow2(expPitch));
1744     }
1745 
1746     return expPitch;
1747 }
1748 
1749 /**
1750 ****************************************************************************************************
1751 *   SiLib::HwlPostHandleBaseLvl3xPitch
1752 *
1753 *   @brief
1754 *       Post-handler of 3x pitch adjustment
1755 *
1756 *   @return
1757 *       Expected pitch
1758 ****************************************************************************************************
1759 */
HwlPostHandleBaseLvl3xPitch(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,UINT_32 expPitch) const1760 UINT_32 SiLib::HwlPostHandleBaseLvl3xPitch(
1761     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] input
1762     UINT_32                                 expPitch    ///< [in] pitch
1763     ) const
1764 {
1765     /**
1766      * @note The pitch will be divided by 3 in the end so the value will look odd but h/w should
1767      *  be able to compute a correct pitch from it as h/w address library is doing the job.
1768      */
1769     // From SI, the pitch is expanded 3x first, then padded to pow2, so no special handler here
1770     if (pIn->flags.pow2Pad == FALSE)
1771     {
1772         Addr::V1::Lib::HwlPostHandleBaseLvl3xPitch(pIn, expPitch);
1773     }
1774 
1775     return expPitch;
1776 }
1777 
1778 /**
1779 ****************************************************************************************************
1780 *   SiLib::HwlGetPitchAlignmentMicroTiled
1781 *
1782 *   @brief
1783 *       Compute 1D tiled surface pitch alignment
1784 *
1785 *   @return
1786 *       pitch alignment
1787 ****************************************************************************************************
1788 */
HwlGetPitchAlignmentMicroTiled(AddrTileMode tileMode,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 numSamples) const1789 UINT_32 SiLib::HwlGetPitchAlignmentMicroTiled(
1790     AddrTileMode        tileMode,          ///< [in] tile mode
1791     UINT_32             bpp,               ///< [in] bits per pixel
1792     ADDR_SURFACE_FLAGS  flags,             ///< [in] surface flags
1793     UINT_32             numSamples         ///< [in] number of samples
1794     ) const
1795 {
1796     UINT_32 pitchAlign;
1797 
1798     if (flags.qbStereo)
1799     {
1800         pitchAlign = EgBasedLib::HwlGetPitchAlignmentMicroTiled(tileMode,bpp,flags,numSamples);
1801     }
1802     else
1803     {
1804         pitchAlign = 8;
1805     }
1806 
1807     return pitchAlign;
1808 }
1809 
1810 /**
1811 ****************************************************************************************************
1812 *   SiLib::HwlGetSizeAdjustmentMicroTiled
1813 *
1814 *   @brief
1815 *       Adjust 1D tiled surface pitch and slice size
1816 *
1817 *   @return
1818 *       Logical slice size in bytes
1819 ****************************************************************************************************
1820 */
HwlGetSizeAdjustmentMicroTiled(UINT_32 thickness,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 numSamples,UINT_32 baseAlign,UINT_32 pitchAlign,UINT_32 * pPitch,UINT_32 * pHeight) const1821 UINT_64 SiLib::HwlGetSizeAdjustmentMicroTiled(
1822     UINT_32             thickness,      ///< [in] thickness
1823     UINT_32             bpp,            ///< [in] bits per pixel
1824     ADDR_SURFACE_FLAGS  flags,          ///< [in] surface flags
1825     UINT_32             numSamples,     ///< [in] number of samples
1826     UINT_32             baseAlign,      ///< [in] base alignment
1827     UINT_32             pitchAlign,     ///< [in] pitch alignment
1828     UINT_32*            pPitch,         ///< [in,out] pointer to pitch
1829     UINT_32*            pHeight         ///< [in,out] pointer to height
1830     ) const
1831 {
1832     UINT_64 logicalSliceSize;
1833     UINT_64 physicalSliceSize;
1834 
1835     UINT_32 pitch   = *pPitch;
1836     UINT_32 height  = *pHeight;
1837 
1838     // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
1839     logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
1840 
1841     // Physical slice: multiplied by thickness
1842     physicalSliceSize =  logicalSliceSize * thickness;
1843 
1844     // Pitch alignment is always 8, so if slice size is not padded to base alignment
1845     // (pipe_interleave_size), we need to increase pitch
1846     while ((physicalSliceSize % baseAlign) != 0)
1847     {
1848         pitch += pitchAlign;
1849 
1850         logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
1851 
1852         physicalSliceSize =  logicalSliceSize * thickness;
1853     }
1854 
1855 #if !ALT_TEST
1856     //
1857     // Special workaround for depth/stencil buffer, use 8 bpp to align depth buffer again since
1858     // the stencil plane may have larger pitch if the slice size is smaller than base alignment.
1859     //
1860     // Note: this actually does not work for mipmap but mipmap depth texture is not really
1861     // sampled with mipmap.
1862     //
1863     if (flags.depth && (flags.noStencil == FALSE))
1864     {
1865         ADDR_ASSERT(numSamples == 1);
1866 
1867         UINT_64 logicalSiceSizeStencil = static_cast<UINT_64>(pitch) * height; // 1 byte stencil
1868 
1869         while ((logicalSiceSizeStencil % baseAlign) != 0)
1870         {
1871             pitch += pitchAlign; // Stencil plane's pitch alignment is the same as depth plane's
1872 
1873             logicalSiceSizeStencil = static_cast<UINT_64>(pitch) * height;
1874         }
1875 
1876         if (pitch != *pPitch)
1877         {
1878             // If this is a mipmap, this padded one cannot be sampled as a whole mipmap!
1879             logicalSliceSize = logicalSiceSizeStencil * BITS_TO_BYTES(bpp);
1880         }
1881     }
1882 #endif
1883     *pPitch = pitch;
1884 
1885     // No adjust for pHeight
1886 
1887     return logicalSliceSize;
1888 }
1889 
1890 /**
1891 ****************************************************************************************************
1892 *   SiLib::HwlConvertChipFamily
1893 *
1894 *   @brief
1895 *       Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
1896 *   @return
1897 *       ChipFamily
1898 ****************************************************************************************************
1899 */
HwlConvertChipFamily(UINT_32 uChipFamily,UINT_32 uChipRevision)1900 ChipFamily SiLib::HwlConvertChipFamily(
1901     UINT_32 uChipFamily,        ///< [in] chip family defined in atiih.h
1902     UINT_32 uChipRevision)      ///< [in] chip revision defined in "asic_family"_id.h
1903 {
1904     ChipFamily family = ADDR_CHIP_FAMILY_SI;
1905 
1906     switch (uChipFamily)
1907     {
1908         case FAMILY_SI:
1909             m_settings.isSouthernIsland = 1;
1910             m_settings.isTahiti     = ASICREV_IS_TAHITI_P(uChipRevision);
1911             m_settings.isPitCairn   = ASICREV_IS_PITCAIRN_PM(uChipRevision);
1912             m_settings.isCapeVerde  = ASICREV_IS_CAPEVERDE_M(uChipRevision);
1913             m_settings.isOland      = ASICREV_IS_OLAND_M(uChipRevision);
1914             m_settings.isHainan     = ASICREV_IS_HAINAN_V(uChipRevision);
1915             break;
1916         default:
1917             ADDR_ASSERT(!"No Chip found");
1918             break;
1919     }
1920 
1921     return family;
1922 }
1923 
1924 /**
1925 ****************************************************************************************************
1926 *   SiLib::HwlSetupTileInfo
1927 *
1928 *   @brief
1929 *       Setup default value of tile info for SI
1930 ****************************************************************************************************
1931 */
HwlSetupTileInfo(AddrTileMode tileMode,ADDR_SURFACE_FLAGS flags,UINT_32 bpp,UINT_32 pitch,UINT_32 height,UINT_32 numSamples,ADDR_TILEINFO * pTileInfoIn,ADDR_TILEINFO * pTileInfoOut,AddrTileType inTileType,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const1932 VOID SiLib::HwlSetupTileInfo(
1933     AddrTileMode                        tileMode,       ///< [in] Tile mode
1934     ADDR_SURFACE_FLAGS                  flags,          ///< [in] Surface type flags
1935     UINT_32                             bpp,            ///< [in] Bits per pixel
1936     UINT_32                             pitch,          ///< [in] Pitch in pixels
1937     UINT_32                             height,         ///< [in] Height in pixels
1938     UINT_32                             numSamples,     ///< [in] Number of samples
1939     ADDR_TILEINFO*                      pTileInfoIn,    ///< [in] Tile info input: NULL for default
1940     ADDR_TILEINFO*                      pTileInfoOut,   ///< [out] Tile info output
1941     AddrTileType                        inTileType,     ///< [in] Tile type
1942     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*   pOut            ///< [out] Output
1943     ) const
1944 {
1945     UINT_32 thickness = Thickness(tileMode);
1946     ADDR_TILEINFO* pTileInfo = pTileInfoOut;
1947     INT index = TileIndexInvalid;
1948 
1949     // Fail-safe code
1950     if (IsLinear(tileMode) == FALSE)
1951     {
1952         // 128 bpp/thick tiling must be non-displayable.
1953         // Fmask reuse color buffer's entry but bank-height field can be from another entry
1954         // To simplify the logic, fmask entry should be picked from non-displayable ones
1955         if (bpp == 128 || thickness > 1 || flags.fmask || flags.prt)
1956         {
1957             inTileType = ADDR_NON_DISPLAYABLE;
1958         }
1959 
1960         if (flags.depth || flags.stencil)
1961         {
1962             inTileType = ADDR_DEPTH_SAMPLE_ORDER;
1963         }
1964     }
1965 
1966     // Partial valid fields are not allowed for SI.
1967     if (IsTileInfoAllZero(pTileInfo))
1968     {
1969         if (IsMacroTiled(tileMode))
1970         {
1971             if (flags.prt)
1972             {
1973                 if (numSamples == 1)
1974                 {
1975                     if (flags.depth)
1976                     {
1977                         switch (bpp)
1978                         {
1979                             case 16:
1980                                 index = 3;
1981                                 break;
1982                             case 32:
1983                                 index = 6;
1984                                 break;
1985                             default:
1986                                 ADDR_ASSERT_ALWAYS();
1987                                 break;
1988                         }
1989                     }
1990                     else
1991                     {
1992                         switch (bpp)
1993                         {
1994                             case 8:
1995                                 index = 21;
1996                                 break;
1997                             case 16:
1998                                 index = 22;
1999                                 break;
2000                             case 32:
2001                                 index = 23;
2002                                 break;
2003                             case 64:
2004                                 index = 24;
2005                                 break;
2006                             case 128:
2007                                 index = 25;
2008                                 break;
2009                             default:
2010                                 break;
2011                         }
2012 
2013                         if (thickness > 1)
2014                         {
2015                             ADDR_ASSERT(bpp != 128);
2016                             index += 5;
2017                         }
2018                     }
2019                 }
2020                 else
2021                 {
2022                     ADDR_ASSERT(numSamples == 4);
2023 
2024                     if (flags.depth)
2025                     {
2026                         switch (bpp)
2027                         {
2028                             case 16:
2029                                 index = 5;
2030                                 break;
2031                             case 32:
2032                                 index = 7;
2033                                 break;
2034                             default:
2035                                 ADDR_ASSERT_ALWAYS();
2036                                 break;
2037                         }
2038                     }
2039                     else
2040                     {
2041                         switch (bpp)
2042                         {
2043                             case 8:
2044                                 index = 23;
2045                                 break;
2046                             case 16:
2047                                 index = 24;
2048                                 break;
2049                             case 32:
2050                                 index = 25;
2051                                 break;
2052                             case 64:
2053                                 index = 30;
2054                                 break;
2055                             default:
2056                                 ADDR_ASSERT_ALWAYS();
2057                                 break;
2058                         }
2059                     }
2060                 }
2061             }//end of PRT part
2062             // See table entries 0-7
2063             else if (flags.depth || flags.stencil)
2064             {
2065                 if (flags.compressZ)
2066                 {
2067                     if (flags.stencil)
2068                     {
2069                         index = 0;
2070                     }
2071                     else
2072                     {
2073                         // optimal tile index for compressed depth/stencil.
2074                         switch (numSamples)
2075                         {
2076                             case 1:
2077                                 index = 0;
2078                                 break;
2079                             case 2:
2080                             case 4:
2081                                 index = 1;
2082                                 break;
2083                             case 8:
2084                                 index = 2;
2085                                 break;
2086                             default:
2087                                 break;
2088                         }
2089                     }
2090                 }
2091                 else // unCompressZ
2092                 {
2093                     index = 3;
2094                 }
2095             }
2096             else //non PRT & non Depth & non Stencil
2097             {
2098                 // See table entries 9-12
2099                 if (inTileType == ADDR_DISPLAYABLE)
2100                 {
2101                     switch (bpp)
2102                     {
2103                         case 8:
2104                             index = 10;
2105                             break;
2106                         case 16:
2107                             index = 11;
2108                             break;
2109                         case 32:
2110                             index = 12;
2111                             break;
2112                         case 64:
2113                             index = 12;
2114                             break;
2115                         default:
2116                             break;
2117                     }
2118                 }
2119                 else
2120                 {
2121                     // See table entries 13-17
2122                     if (thickness == 1)
2123                     {
2124                         if (flags.fmask)
2125                         {
2126                             UINT_32 fmaskPixelSize = bpp * numSamples;
2127 
2128                             switch (fmaskPixelSize)
2129                             {
2130                                 case 8:
2131                                     index = 14;
2132                                     break;
2133                                 case 16:
2134                                     index = 15;
2135                                     break;
2136                                 case 32:
2137                                     index = 16;
2138                                     break;
2139                                 case 64:
2140                                     index = 17;
2141                                     break;
2142                                 default:
2143                                     ADDR_ASSERT_ALWAYS();
2144                             }
2145                         }
2146                         else
2147                         {
2148                             switch (bpp)
2149                             {
2150                                 case 8:
2151                                     index = 14;
2152                                     break;
2153                                 case 16:
2154                                     index = 15;
2155                                     break;
2156                                 case 32:
2157                                     index = 16;
2158                                     break;
2159                                 case 64:
2160                                     index = 17;
2161                                     break;
2162                                 case 128:
2163                                     index = 17;
2164                                     break;
2165                                 default:
2166                                     break;
2167                             }
2168                         }
2169                     }
2170                     else // thick tiling - entries 18-20
2171                     {
2172                         switch (thickness)
2173                         {
2174                             case 4:
2175                                 index = 20;
2176                                 break;
2177                             case 8:
2178                                 index = 19;
2179                                 break;
2180                             default:
2181                                 break;
2182                         }
2183                     }
2184                 }
2185             }
2186         }
2187         else
2188         {
2189             if (tileMode == ADDR_TM_LINEAR_ALIGNED)
2190             {
2191                 index = 8;
2192             }
2193             else if (tileMode == ADDR_TM_LINEAR_GENERAL)
2194             {
2195                 index = TileIndexLinearGeneral;
2196             }
2197             else
2198             {
2199                 if (flags.depth || flags.stencil)
2200                 {
2201                     index = 4;
2202                 }
2203                 else if (inTileType == ADDR_DISPLAYABLE)
2204                 {
2205                     index = 9;
2206                 }
2207                 else if (thickness == 1)
2208                 {
2209                     index = 13;
2210                 }
2211                 else
2212                 {
2213                     index = 18;
2214                 }
2215             }
2216         }
2217 
2218         if (index >= 0 && index <= 31)
2219         {
2220             *pTileInfo      = m_tileTable[index].info;
2221             pOut->tileType  = m_tileTable[index].type;
2222         }
2223 
2224         if (index == TileIndexLinearGeneral)
2225         {
2226             *pTileInfo      = m_tileTable[8].info;
2227             pOut->tileType  = m_tileTable[8].type;
2228         }
2229     }
2230     else
2231     {
2232         if (pTileInfoIn)
2233         {
2234             if (flags.stencil && pTileInfoIn->tileSplitBytes == 0)
2235             {
2236                 // Stencil always uses index 0
2237                 *pTileInfo = m_tileTable[0].info;
2238             }
2239         }
2240         // Pass through tile type
2241         pOut->tileType = inTileType;
2242     }
2243 
2244     pOut->tileIndex = index;
2245     pOut->prtTileIndex = flags.prt;
2246 }
2247 
2248 /**
2249 ****************************************************************************************************
2250 *   SiLib::DecodeGbRegs
2251 *
2252 *   @brief
2253 *       Decodes GB_ADDR_CONFIG and noOfBanks/noOfRanks
2254 *
2255 *   @return
2256 *       TRUE if all settings are valid
2257 *
2258 ****************************************************************************************************
2259 */
DecodeGbRegs(const ADDR_REGISTER_VALUE * pRegValue)2260 BOOL_32 SiLib::DecodeGbRegs(
2261     const ADDR_REGISTER_VALUE* pRegValue) ///< [in] create input
2262 {
2263     GB_ADDR_CONFIG  reg;
2264     BOOL_32         valid = TRUE;
2265 
2266     reg.val = pRegValue->gbAddrConfig;
2267 
2268     UINT_32 pipe_interleave_size = reg.f.pipe_interleave_size;
2269     UINT_32 row_size             = reg.f.row_size;
2270 
2271     switch (pipe_interleave_size)
2272     {
2273         case ADDR_CONFIG_PIPE_INTERLEAVE_256B:
2274             m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_256B;
2275             break;
2276         case ADDR_CONFIG_PIPE_INTERLEAVE_512B:
2277             m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_512B;
2278             break;
2279         default:
2280             valid = FALSE;
2281             ADDR_UNHANDLED_CASE();
2282             break;
2283     }
2284 
2285     switch (row_size)
2286     {
2287         case ADDR_CONFIG_1KB_ROW:
2288             m_rowSize = ADDR_ROWSIZE_1KB;
2289             break;
2290         case ADDR_CONFIG_2KB_ROW:
2291             m_rowSize = ADDR_ROWSIZE_2KB;
2292             break;
2293         case ADDR_CONFIG_4KB_ROW:
2294             m_rowSize = ADDR_ROWSIZE_4KB;
2295             break;
2296         default:
2297             valid = FALSE;
2298             ADDR_UNHANDLED_CASE();
2299             break;
2300     }
2301 
2302     switch (pRegValue->noOfBanks)
2303     {
2304         case 0:
2305             m_banks = 4;
2306             break;
2307         case 1:
2308             m_banks = 8;
2309             break;
2310         case 2:
2311             m_banks = 16;
2312             break;
2313         default:
2314             valid = FALSE;
2315             ADDR_UNHANDLED_CASE();
2316             break;
2317     }
2318 
2319     switch (pRegValue->noOfRanks)
2320     {
2321         case 0:
2322             m_ranks = 1;
2323             break;
2324         case 1:
2325             m_ranks = 2;
2326             break;
2327         default:
2328             valid = FALSE;
2329             ADDR_UNHANDLED_CASE();
2330             break;
2331     }
2332 
2333     m_logicalBanks = m_banks * m_ranks;
2334 
2335     ADDR_ASSERT(m_logicalBanks <= 16);
2336 
2337     return valid;
2338 }
2339 
2340 /**
2341 ****************************************************************************************************
2342 *   SiLib::HwlInitGlobalParams
2343 *
2344 *   @brief
2345 *       Initializes global parameters
2346 *
2347 *   @return
2348 *       TRUE if all settings are valid
2349 *
2350 ****************************************************************************************************
2351 */
HwlInitGlobalParams(const ADDR_CREATE_INPUT * pCreateIn)2352 BOOL_32 SiLib::HwlInitGlobalParams(
2353     const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input
2354 {
2355     BOOL_32 valid = TRUE;
2356     const ADDR_REGISTER_VALUE* pRegValue = &pCreateIn->regValue;
2357 
2358     valid = DecodeGbRegs(pRegValue);
2359 
2360     if (valid)
2361     {
2362         if (m_settings.isTahiti || m_settings.isPitCairn)
2363         {
2364             m_pipes = 8;
2365         }
2366         else if (m_settings.isCapeVerde || m_settings.isOland)
2367         {
2368             m_pipes = 4;
2369         }
2370         else
2371         {
2372             // Hainan is 2-pipe (m_settings.isHainan == 1)
2373             m_pipes = 2;
2374         }
2375 
2376         valid = InitTileSettingTable(pRegValue->pTileConfig, pRegValue->noOfEntries);
2377 
2378         if (valid)
2379         {
2380             InitEquationTable();
2381         }
2382 
2383         m_maxSamples = 16;
2384     }
2385 
2386     return valid;
2387 }
2388 
2389 /**
2390 ****************************************************************************************************
2391 *   SiLib::HwlConvertTileInfoToHW
2392 *   @brief
2393 *       Entry of si's ConvertTileInfoToHW
2394 *   @return
2395 *       ADDR_E_RETURNCODE
2396 ****************************************************************************************************
2397 */
HwlConvertTileInfoToHW(const ADDR_CONVERT_TILEINFOTOHW_INPUT * pIn,ADDR_CONVERT_TILEINFOTOHW_OUTPUT * pOut) const2398 ADDR_E_RETURNCODE SiLib::HwlConvertTileInfoToHW(
2399     const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure
2400     ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut      ///< [out] output structure
2401     ) const
2402 {
2403     ADDR_E_RETURNCODE retCode   = ADDR_OK;
2404 
2405     retCode = EgBasedLib::HwlConvertTileInfoToHW(pIn, pOut);
2406 
2407     if (retCode == ADDR_OK)
2408     {
2409         if (pIn->reverse == FALSE)
2410         {
2411             if (pIn->pTileInfo->pipeConfig == ADDR_PIPECFG_INVALID)
2412             {
2413                 retCode = ADDR_INVALIDPARAMS;
2414             }
2415             else
2416             {
2417                 pOut->pTileInfo->pipeConfig =
2418                     static_cast<AddrPipeCfg>(pIn->pTileInfo->pipeConfig - 1);
2419             }
2420         }
2421         else
2422         {
2423             pOut->pTileInfo->pipeConfig =
2424                 static_cast<AddrPipeCfg>(pIn->pTileInfo->pipeConfig + 1);
2425         }
2426     }
2427 
2428     return retCode;
2429 }
2430 
2431 /**
2432 ****************************************************************************************************
2433 *   SiLib::HwlComputeXmaskCoordYFrom8Pipe
2434 *
2435 *   @brief
2436 *       Compute the Y coord which will be added to Xmask Y
2437 *       coord.
2438 *   @return
2439 *       Y coord
2440 ****************************************************************************************************
2441 */
HwlComputeXmaskCoordYFrom8Pipe(UINT_32 pipe,UINT_32 x) const2442 UINT_32 SiLib::HwlComputeXmaskCoordYFrom8Pipe(
2443     UINT_32         pipe,       ///< [in] pipe id
2444     UINT_32         x           ///< [in] tile coord x, which is original x coord / 8
2445     ) const
2446 {
2447     // This function should never be called since it is 6xx/8xx specfic.
2448     // Keep this empty implementation to avoid any mis-use.
2449     ADDR_ASSERT_ALWAYS();
2450 
2451     return 0;
2452 }
2453 
2454 /**
2455 ****************************************************************************************************
2456 *   SiLib::HwlComputeSurfaceCoord2DFromBankPipe
2457 *
2458 *   @brief
2459 *       Compute surface x,y coordinates from bank/pipe info
2460 *   @return
2461 *       N/A
2462 ****************************************************************************************************
2463 */
HwlComputeSurfaceCoord2DFromBankPipe(AddrTileMode tileMode,UINT_32 * pX,UINT_32 * pY,UINT_32 slice,UINT_32 bank,UINT_32 pipe,UINT_32 bankSwizzle,UINT_32 pipeSwizzle,UINT_32 tileSlices,BOOL_32 ignoreSE,ADDR_TILEINFO * pTileInfo) const2464 VOID SiLib::HwlComputeSurfaceCoord2DFromBankPipe(
2465     AddrTileMode        tileMode,   ///< [in] tile mode
2466     UINT_32*            pX,         ///< [in,out] x coordinate
2467     UINT_32*            pY,         ///< [in,out] y coordinate
2468     UINT_32             slice,      ///< [in] slice index
2469     UINT_32             bank,       ///< [in] bank number
2470     UINT_32             pipe,       ///< [in] pipe number
2471     UINT_32             bankSwizzle,///< [in] bank swizzle
2472     UINT_32             pipeSwizzle,///< [in] pipe swizzle
2473     UINT_32             tileSlices, ///< [in] slices in a micro tile
2474     BOOL_32             ignoreSE,   ///< [in] TRUE if shader engines are ignored
2475     ADDR_TILEINFO*      pTileInfo   ///< [in] bank structure. **All fields to be valid on entry**
2476     ) const
2477 {
2478     UINT_32 xBit;
2479     UINT_32 yBit;
2480     UINT_32 yBit3 = 0;
2481     UINT_32 yBit4 = 0;
2482     UINT_32 yBit5 = 0;
2483     UINT_32 yBit6 = 0;
2484 
2485     UINT_32 xBit3 = 0;
2486     UINT_32 xBit4 = 0;
2487     UINT_32 xBit5 = 0;
2488 
2489     UINT_32 numPipes = GetPipePerSurf(pTileInfo->pipeConfig);
2490 
2491     CoordFromBankPipe xyBits = {0};
2492     ComputeSurfaceCoord2DFromBankPipe(tileMode, *pX, *pY, slice, bank, pipe,
2493                                       bankSwizzle, pipeSwizzle, tileSlices, pTileInfo,
2494                                       &xyBits);
2495     yBit3 = xyBits.yBit3;
2496     yBit4 = xyBits.yBit4;
2497     yBit5 = xyBits.yBit5;
2498     yBit6 = xyBits.yBit6;
2499 
2500     xBit3 = xyBits.xBit3;
2501     xBit4 = xyBits.xBit4;
2502     xBit5 = xyBits.xBit5;
2503 
2504     yBit = xyBits.yBits;
2505 
2506     UINT_32 yBitTemp = 0;
2507 
2508     if ((pTileInfo->pipeConfig == ADDR_PIPECFG_P4_32x32) ||
2509         (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32))
2510     {
2511         ADDR_ASSERT(pTileInfo->bankWidth == 1 && pTileInfo->macroAspectRatio > 1);
2512         UINT_32 yBitToCheck = QLog2(pTileInfo->banks) - 1;
2513 
2514         ADDR_ASSERT(yBitToCheck <= 3);
2515 
2516         yBitTemp = _BIT(yBit, yBitToCheck);
2517 
2518         xBit3 = 0;
2519     }
2520 
2521     yBit = Bits2Number(4, yBit6, yBit5, yBit4, yBit3);
2522     xBit = Bits2Number(3, xBit5, xBit4, xBit3);
2523 
2524     *pY += yBit * pTileInfo->bankHeight * MicroTileHeight;
2525     *pX += xBit * numPipes * pTileInfo->bankWidth * MicroTileWidth;
2526 
2527     //calculate the bank and pipe bits in x, y
2528     UINT_32 xTile; //x in micro tile
2529     UINT_32 x3 = 0;
2530     UINT_32 x4 = 0;
2531     UINT_32 x5 = 0;
2532     UINT_32 x6 = 0;
2533     UINT_32 y = *pY;
2534 
2535     UINT_32 pipeBit0 = _BIT(pipe,0);
2536     UINT_32 pipeBit1 = _BIT(pipe,1);
2537     UINT_32 pipeBit2 = _BIT(pipe,2);
2538 
2539     UINT_32 y3 = _BIT(y, 3);
2540     UINT_32 y4 = _BIT(y, 4);
2541     UINT_32 y5 = _BIT(y, 5);
2542     UINT_32 y6 = _BIT(y, 6);
2543 
2544     // bankbit0 after ^x4^x5
2545     UINT_32 bankBit00 = _BIT(bank,0);
2546     UINT_32 bankBit0 = 0;
2547 
2548     switch (pTileInfo->pipeConfig)
2549     {
2550         case ADDR_PIPECFG_P2:
2551             x3 = pipeBit0 ^ y3;
2552             break;
2553         case ADDR_PIPECFG_P4_8x16:
2554             x4 = pipeBit0 ^ y3;
2555             x3 = pipeBit0 ^ y4;
2556             break;
2557         case ADDR_PIPECFG_P4_16x16:
2558             x4 = pipeBit1 ^ y4;
2559             x3 = pipeBit0 ^ y3 ^ x4;
2560             break;
2561         case ADDR_PIPECFG_P4_16x32:
2562             x4 = pipeBit1 ^ y4;
2563             x3 = pipeBit0 ^ y3 ^ x4;
2564             break;
2565         case ADDR_PIPECFG_P4_32x32:
2566             x5 = pipeBit1 ^ y5;
2567             x3 = pipeBit0 ^ y3 ^ x5;
2568             bankBit0 = yBitTemp ^ x5;
2569             x4 = bankBit00 ^ x5 ^ bankBit0;
2570             *pX += x5 * 4 * 1 * 8; // x5 * num_pipes * bank_width * 8;
2571             break;
2572         case ADDR_PIPECFG_P8_16x16_8x16:
2573             x3 = pipeBit1 ^ y5;
2574             x4 = pipeBit2 ^ y4;
2575             x5 = pipeBit0 ^ y3 ^ x4;
2576             break;
2577         case ADDR_PIPECFG_P8_16x32_8x16:
2578             x3 = pipeBit1 ^ y4;
2579             x4 = pipeBit2 ^ y5;
2580             x5 = pipeBit0 ^ y3 ^ x4;
2581             break;
2582         case ADDR_PIPECFG_P8_32x32_8x16:
2583             x3 = pipeBit1 ^ y4;
2584             x5 = pipeBit2 ^ y5;
2585             x4 = pipeBit0 ^ y3 ^ x5;
2586             break;
2587         case ADDR_PIPECFG_P8_16x32_16x16:
2588             x4 = pipeBit2 ^ y5;
2589             x5 = pipeBit1 ^ y4;
2590             x3 = pipeBit0 ^ y3 ^ x4;
2591             break;
2592         case ADDR_PIPECFG_P8_32x32_16x16:
2593             x5 = pipeBit2 ^ y5;
2594             x4 = pipeBit1 ^ y4;
2595             x3 = pipeBit0 ^ y3 ^ x4;
2596             break;
2597         case ADDR_PIPECFG_P8_32x32_16x32:
2598             x5 = pipeBit2 ^ y5;
2599             x4 = pipeBit1 ^ y6;
2600             x3 = pipeBit0 ^ y3 ^ x4;
2601             break;
2602         case ADDR_PIPECFG_P8_32x64_32x32:
2603             x6 = pipeBit1 ^ y5;
2604             x5 = pipeBit2 ^ y6;
2605             x3 = pipeBit0 ^ y3 ^ x5;
2606             bankBit0 = yBitTemp ^ x6;
2607             x4 = bankBit00 ^ x5 ^ bankBit0;
2608             *pX += x6 * 8 * 1 * 8; // x6 * num_pipes * bank_width * 8;
2609             break;
2610         default:
2611             ADDR_ASSERT_ALWAYS();
2612     }
2613 
2614     xTile = Bits2Number(3, x5, x4, x3);
2615 
2616     *pX += xTile << 3;
2617 }
2618 
2619 /**
2620 ****************************************************************************************************
2621 *   SiLib::HwlPreAdjustBank
2622 *
2623 *   @brief
2624 *       Adjust bank before calculating address acoording to bank/pipe
2625 *   @return
2626 *       Adjusted bank
2627 ****************************************************************************************************
2628 */
HwlPreAdjustBank(UINT_32 tileX,UINT_32 bank,ADDR_TILEINFO * pTileInfo) const2629 UINT_32 SiLib::HwlPreAdjustBank(
2630     UINT_32         tileX,      ///< [in] x coordinate in unit of tile
2631     UINT_32         bank,       ///< [in] bank
2632     ADDR_TILEINFO*  pTileInfo   ///< [in] tile info
2633     ) const
2634 {
2635     if (((pTileInfo->pipeConfig == ADDR_PIPECFG_P4_32x32) ||
2636         (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32)) && (pTileInfo->bankWidth == 1))
2637     {
2638         UINT_32 bankBit0 = _BIT(bank, 0);
2639         UINT_32 x4 = _BIT(tileX, 1);
2640         UINT_32 x5 = _BIT(tileX, 2);
2641 
2642         bankBit0 = bankBit0 ^ x4 ^ x5;
2643         bank |= bankBit0;
2644 
2645         ADDR_ASSERT(pTileInfo->macroAspectRatio > 1);
2646     }
2647 
2648     return bank;
2649 }
2650 
2651 /**
2652 ****************************************************************************************************
2653 *   SiLib::HwlComputeSurfaceInfo
2654 *
2655 *   @brief
2656 *       Entry of si's ComputeSurfaceInfo
2657 *   @return
2658 *       ADDR_E_RETURNCODE
2659 ****************************************************************************************************
2660 */
HwlComputeSurfaceInfo(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2661 ADDR_E_RETURNCODE SiLib::HwlComputeSurfaceInfo(
2662     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,    ///< [in] input structure
2663     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [out] output structure
2664     ) const
2665 {
2666     pOut->tileIndex = pIn->tileIndex;
2667 
2668     ADDR_E_RETURNCODE retCode = EgBasedLib::HwlComputeSurfaceInfo(pIn, pOut);
2669 
2670     UINT_32 tileIndex = static_cast<UINT_32>(pOut->tileIndex);
2671 
2672     if (((pIn->flags.needEquation   == TRUE) ||
2673          (pIn->flags.preferEquation == TRUE)) &&
2674         (pIn->numSamples <= 1) &&
2675         (tileIndex < TileTableSize))
2676     {
2677         static const UINT_32 SiUncompressDepthTileIndex = 3;
2678 
2679         if ((pIn->numSlices > 1) &&
2680             (IsMacroTiled(pOut->tileMode) == TRUE) &&
2681             ((m_chipFamily == ADDR_CHIP_FAMILY_SI) ||
2682              (IsPrtTileMode(pOut->tileMode) == FALSE)))
2683         {
2684             pOut->equationIndex = ADDR_INVALID_EQUATION_INDEX;
2685         }
2686         else if ((pIn->flags.prt == FALSE) &&
2687                  (m_uncompressDepthEqIndex != 0) &&
2688                  (tileIndex == SiUncompressDepthTileIndex))
2689         {
2690             pOut->equationIndex = m_uncompressDepthEqIndex + Log2(pIn->bpp >> 3);
2691         }
2692         else
2693         {
2694 
2695             pOut->equationIndex = m_equationLookupTable[Log2(pIn->bpp >> 3)][tileIndex];
2696         }
2697 
2698         if (pOut->equationIndex != ADDR_INVALID_EQUATION_INDEX)
2699         {
2700             pOut->blockWidth = m_blockWidth[pOut->equationIndex];
2701 
2702             pOut->blockHeight = m_blockHeight[pOut->equationIndex];
2703 
2704             pOut->blockSlices = m_blockSlices[pOut->equationIndex];
2705         }
2706     }
2707     else
2708     {
2709         pOut->equationIndex = ADDR_INVALID_EQUATION_INDEX;
2710     }
2711 
2712     return retCode;
2713 }
2714 
2715 /**
2716 ****************************************************************************************************
2717 *   SiLib::HwlComputeMipLevel
2718 *   @brief
2719 *       Compute MipLevel info (including level 0)
2720 *   @return
2721 *       TRUE if HWL's handled
2722 ****************************************************************************************************
2723 */
HwlComputeMipLevel(ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn) const2724 BOOL_32 SiLib::HwlComputeMipLevel(
2725     ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in,out] Input structure
2726     ) const
2727 {
2728     // basePitch is calculated from level 0 so we only check this for mipLevel > 0
2729     if (pIn->mipLevel > 0)
2730     {
2731         // Note: Don't check expand 3x formats(96 bit) as the basePitch is not pow2 even if
2732         // we explicity set pow2Pad flag. The 3x base pitch is padded to pow2 but after being
2733         // divided by expandX factor (3) - to program texture pitch, the basePitch is never pow2.
2734         if (ElemLib::IsExpand3x(pIn->format) == FALSE)
2735         {
2736             // Sublevel pitches are generated from base level pitch instead of width on SI
2737             // If pow2Pad is 0, we don't assert - as this is not really used for a mip chain
2738             ADDR_ASSERT((pIn->flags.pow2Pad == FALSE) ||
2739                         ((pIn->basePitch != 0) && IsPow2(pIn->basePitch)));
2740         }
2741 
2742         if (pIn->basePitch != 0)
2743         {
2744             pIn->width = Max(1u, pIn->basePitch >> pIn->mipLevel);
2745         }
2746     }
2747 
2748     // pow2Pad is done in PostComputeMipLevel
2749 
2750     return TRUE;
2751 }
2752 
2753 /**
2754 ****************************************************************************************************
2755 *   SiLib::HwlCheckLastMacroTiledLvl
2756 *
2757 *   @brief
2758 *       Sets pOut->last2DLevel to TRUE if it is
2759 *   @note
2760 *
2761 ****************************************************************************************************
2762 */
HwlCheckLastMacroTiledLvl(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2763 VOID SiLib::HwlCheckLastMacroTiledLvl(
2764     const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure
2765     ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut      ///< [in,out] Output structure (used as input, too)
2766     ) const
2767 {
2768     // pow2Pad covers all mipmap cases
2769     if (pIn->flags.pow2Pad)
2770     {
2771         ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
2772 
2773         UINT_32 nextPitch;
2774         UINT_32 nextHeight;
2775         UINT_32 nextSlices;
2776 
2777         AddrTileMode nextTileMode;
2778 
2779         if (pIn->mipLevel == 0 || pIn->basePitch == 0)
2780         {
2781             // Base level or fail-safe case (basePitch == 0)
2782             nextPitch = pOut->pitch >> 1;
2783         }
2784         else
2785         {
2786             // Sub levels
2787             nextPitch = pIn->basePitch >> (pIn->mipLevel + 1);
2788         }
2789 
2790         // nextHeight must be shifted from this level's original height rather than a pow2 padded
2791         // one but this requires original height stored somewhere (pOut->height)
2792         ADDR_ASSERT(pOut->height != 0);
2793 
2794         // next level's height is just current level's >> 1 in pixels
2795         nextHeight = pOut->height >> 1;
2796         // Special format such as FMT_1 and FMT_32_32_32 can be linear only so we consider block
2797         // compressed foramts
2798         if (ElemLib::IsBlockCompressed(pIn->format))
2799         {
2800             nextHeight = (nextHeight + 3) / 4;
2801         }
2802         nextHeight = NextPow2(nextHeight);
2803 
2804         // nextSlices may be 0 if this level's is 1
2805         if (pIn->flags.volume)
2806         {
2807             nextSlices = Max(1u, pIn->numSlices >> 1);
2808         }
2809         else
2810         {
2811             nextSlices = pIn->numSlices;
2812         }
2813 
2814         nextTileMode = ComputeSurfaceMipLevelTileMode(pIn->tileMode,
2815                                                       pIn->bpp,
2816                                                       nextPitch,
2817                                                       nextHeight,
2818                                                       nextSlices,
2819                                                       pIn->numSamples,
2820                                                       pOut->blockWidth,
2821                                                       pOut->blockHeight,
2822                                                       pOut->pTileInfo);
2823 
2824         pOut->last2DLevel = IsMicroTiled(nextTileMode);
2825     }
2826 }
2827 
2828 /**
2829 ****************************************************************************************************
2830 *   SiLib::HwlDegradeThickTileMode
2831 *
2832 *   @brief
2833 *       Degrades valid tile mode for thick modes if needed
2834 *
2835 *   @return
2836 *       Suitable tile mode
2837 ****************************************************************************************************
2838 */
HwlDegradeThickTileMode(AddrTileMode baseTileMode,UINT_32 numSlices,UINT_32 * pBytesPerTile) const2839 AddrTileMode SiLib::HwlDegradeThickTileMode(
2840     AddrTileMode        baseTileMode,   ///< base tile mode
2841     UINT_32             numSlices,      ///< current number of slices
2842     UINT_32*            pBytesPerTile   ///< [in,out] pointer to bytes per slice
2843     ) const
2844 {
2845     return EgBasedLib::HwlDegradeThickTileMode(baseTileMode, numSlices, pBytesPerTile);
2846 }
2847 
2848 /**
2849 ****************************************************************************************************
2850 *   SiLib::HwlTileInfoEqual
2851 *
2852 *   @brief
2853 *       Return TRUE if all field are equal
2854 *   @note
2855 *       Only takes care of current HWL's data
2856 ****************************************************************************************************
2857 */
HwlTileInfoEqual(const ADDR_TILEINFO * pLeft,const ADDR_TILEINFO * pRight) const2858 BOOL_32 SiLib::HwlTileInfoEqual(
2859     const ADDR_TILEINFO* pLeft, ///<[in] Left compare operand
2860     const ADDR_TILEINFO* pRight ///<[in] Right compare operand
2861     ) const
2862 {
2863     BOOL_32 equal = FALSE;
2864 
2865     if (pLeft->pipeConfig == pRight->pipeConfig)
2866     {
2867         equal =  EgBasedLib::HwlTileInfoEqual(pLeft, pRight);
2868     }
2869 
2870     return equal;
2871 }
2872 
2873 /**
2874 ****************************************************************************************************
2875 *   SiLib::GetTileSettings
2876 *
2877 *   @brief
2878 *       Get tile setting infos by index.
2879 *   @return
2880 *       Tile setting info.
2881 ****************************************************************************************************
2882 */
GetTileSetting(UINT_32 index) const2883 const TileConfig* SiLib::GetTileSetting(
2884     UINT_32 index          ///< [in] Tile index
2885     ) const
2886 {
2887     ADDR_ASSERT(index < m_noOfEntries);
2888     return &m_tileTable[index];
2889 }
2890 
2891 /**
2892 ****************************************************************************************************
2893 *   SiLib::HwlPostCheckTileIndex
2894 *
2895 *   @brief
2896 *       Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches
2897 *       tile mode/type/info and change the index if needed
2898 *   @return
2899 *       Tile index.
2900 ****************************************************************************************************
2901 */
HwlPostCheckTileIndex(const ADDR_TILEINFO * pInfo,AddrTileMode mode,AddrTileType type,INT curIndex) const2902 INT_32 SiLib::HwlPostCheckTileIndex(
2903     const ADDR_TILEINFO* pInfo,     ///< [in] Tile Info
2904     AddrTileMode         mode,      ///< [in] Tile mode
2905     AddrTileType         type,      ///< [in] Tile type
2906     INT                  curIndex   ///< [in] Current index assigned in HwlSetupTileInfo
2907     ) const
2908 {
2909     INT_32 index = curIndex;
2910 
2911     if (mode == ADDR_TM_LINEAR_GENERAL)
2912     {
2913         index = TileIndexLinearGeneral;
2914     }
2915     else
2916     {
2917         BOOL_32 macroTiled = IsMacroTiled(mode);
2918 
2919         // We need to find a new index if either of them is true
2920         // 1. curIndex is invalid
2921         // 2. tile mode is changed
2922         // 3. tile info does not match for macro tiled
2923         if ((index == TileIndexInvalid         ||
2924             (mode != m_tileTable[index].mode)  ||
2925             (macroTiled && (HwlTileInfoEqual(pInfo, &m_tileTable[index].info) == FALSE))))
2926         {
2927             for (index = 0; index < static_cast<INT_32>(m_noOfEntries); index++)
2928             {
2929                 if (macroTiled)
2930                 {
2931                     // macro tile modes need all to match
2932                     if (HwlTileInfoEqual(pInfo, &m_tileTable[index].info) &&
2933                         (mode == m_tileTable[index].mode)                 &&
2934                         (type == m_tileTable[index].type))
2935                     {
2936                         break;
2937                     }
2938                 }
2939                 else if (mode == ADDR_TM_LINEAR_ALIGNED)
2940                 {
2941                     // linear mode only needs tile mode to match
2942                     if (mode == m_tileTable[index].mode)
2943                     {
2944                         break;
2945                     }
2946                 }
2947                 else
2948                 {
2949                     // micro tile modes only need tile mode and tile type to match
2950                     if (mode == m_tileTable[index].mode &&
2951                         type == m_tileTable[index].type)
2952                     {
2953                         break;
2954                     }
2955                 }
2956             }
2957         }
2958     }
2959 
2960     ADDR_ASSERT(index < static_cast<INT_32>(m_noOfEntries));
2961 
2962     if (index >= static_cast<INT_32>(m_noOfEntries))
2963     {
2964         index = TileIndexInvalid;
2965     }
2966 
2967     return index;
2968 }
2969 
2970 /**
2971 ****************************************************************************************************
2972 *   SiLib::HwlSetupTileCfg
2973 *
2974 *   @brief
2975 *       Map tile index to tile setting.
2976 *   @return
2977 *       ADDR_E_RETURNCODE
2978 ****************************************************************************************************
2979 */
HwlSetupTileCfg(UINT_32 bpp,INT_32 index,INT_32 macroModeIndex,ADDR_TILEINFO * pInfo,AddrTileMode * pMode,AddrTileType * pType) const2980 ADDR_E_RETURNCODE SiLib::HwlSetupTileCfg(
2981     UINT_32         bpp,            ///< Bits per pixel
2982     INT_32          index,          ///< Tile index
2983     INT_32          macroModeIndex, ///< Index in macro tile mode table(CI)
2984     ADDR_TILEINFO*  pInfo,          ///< [out] Tile Info
2985     AddrTileMode*   pMode,          ///< [out] Tile mode
2986     AddrTileType*   pType           ///< [out] Tile type
2987     ) const
2988 {
2989     ADDR_E_RETURNCODE returnCode = ADDR_OK;
2990 
2991     // Global flag to control usage of tileIndex
2992     if (UseTileIndex(index))
2993     {
2994         if (index == TileIndexLinearGeneral)
2995         {
2996             if (pMode)
2997             {
2998                 *pMode = ADDR_TM_LINEAR_GENERAL;
2999             }
3000 
3001             if (pType)
3002             {
3003                 *pType = ADDR_DISPLAYABLE;
3004             }
3005 
3006             if (pInfo)
3007             {
3008                 pInfo->banks = 2;
3009                 pInfo->bankWidth = 1;
3010                 pInfo->bankHeight = 1;
3011                 pInfo->macroAspectRatio = 1;
3012                 pInfo->tileSplitBytes = 64;
3013                 pInfo->pipeConfig = ADDR_PIPECFG_P2;
3014             }
3015         }
3016         else if (static_cast<UINT_32>(index) >= m_noOfEntries)
3017         {
3018             returnCode = ADDR_INVALIDPARAMS;
3019         }
3020         else
3021         {
3022             const TileConfig* pCfgTable = GetTileSetting(index);
3023 
3024             if (pInfo)
3025             {
3026                 *pInfo = pCfgTable->info;
3027             }
3028             else
3029             {
3030                 if (IsMacroTiled(pCfgTable->mode))
3031                 {
3032                     returnCode = ADDR_INVALIDPARAMS;
3033                 }
3034             }
3035 
3036             if (pMode)
3037             {
3038                 *pMode = pCfgTable->mode;
3039             }
3040 
3041             if (pType)
3042             {
3043                 *pType = pCfgTable->type;
3044             }
3045         }
3046     }
3047 
3048     return returnCode;
3049 }
3050 
3051 /**
3052 ****************************************************************************************************
3053 *   SiLib::ReadGbTileMode
3054 *
3055 *   @brief
3056 *       Convert GB_TILE_MODE HW value to TileConfig.
3057 *   @return
3058 *       NA.
3059 ****************************************************************************************************
3060 */
ReadGbTileMode(UINT_32 regValue,TileConfig * pCfg) const3061 VOID SiLib::ReadGbTileMode(
3062     UINT_32     regValue,   ///< [in] GB_TILE_MODE register
3063     TileConfig* pCfg        ///< [out] output structure
3064     ) const
3065 {
3066     GB_TILE_MODE gbTileMode;
3067     gbTileMode.val = regValue;
3068 
3069     pCfg->type = static_cast<AddrTileType>(gbTileMode.f.micro_tile_mode);
3070     pCfg->info.bankHeight = 1 << gbTileMode.f.bank_height;
3071     pCfg->info.bankWidth = 1 << gbTileMode.f.bank_width;
3072     pCfg->info.banks = 1 << (gbTileMode.f.num_banks + 1);
3073     pCfg->info.macroAspectRatio = 1 << gbTileMode.f.macro_tile_aspect;
3074     pCfg->info.tileSplitBytes = 64 << gbTileMode.f.tile_split;
3075     pCfg->info.pipeConfig = static_cast<AddrPipeCfg>(gbTileMode.f.pipe_config + 1);
3076 
3077     UINT_32 regArrayMode = gbTileMode.f.array_mode;
3078 
3079     pCfg->mode = static_cast<AddrTileMode>(regArrayMode);
3080 
3081     if (regArrayMode == 8) //ARRAY_2D_TILED_XTHICK
3082     {
3083         pCfg->mode = ADDR_TM_2D_TILED_XTHICK;
3084     }
3085     else if (regArrayMode >= 14) //ARRAY_3D_TILED_XTHICK
3086     {
3087         pCfg->mode = static_cast<AddrTileMode>(pCfg->mode + 3);
3088     }
3089 }
3090 
3091 /**
3092 ****************************************************************************************************
3093 *   SiLib::InitTileSettingTable
3094 *
3095 *   @brief
3096 *       Initialize the ADDR_TILE_CONFIG table.
3097 *   @return
3098 *       TRUE if tile table is correctly initialized
3099 ****************************************************************************************************
3100 */
InitTileSettingTable(const UINT_32 * pCfg,UINT_32 noOfEntries)3101 BOOL_32 SiLib::InitTileSettingTable(
3102     const UINT_32*  pCfg,           ///< [in] Pointer to table of tile configs
3103     UINT_32         noOfEntries     ///< [in] Numbe of entries in the table above
3104     )
3105 {
3106     BOOL_32 initOk = TRUE;
3107 
3108     ADDR_ASSERT(noOfEntries <= TileTableSize);
3109 
3110     memset(m_tileTable, 0, sizeof(m_tileTable));
3111 
3112     if (noOfEntries != 0)
3113     {
3114         m_noOfEntries = noOfEntries;
3115     }
3116     else
3117     {
3118         m_noOfEntries = TileTableSize;
3119     }
3120 
3121     if (pCfg) // From Client
3122     {
3123         for (UINT_32 i = 0; i < m_noOfEntries; i++)
3124         {
3125             ReadGbTileMode(*(pCfg + i), &m_tileTable[i]);
3126         }
3127     }
3128     else
3129     {
3130         ADDR_ASSERT_ALWAYS();
3131         initOk = FALSE;
3132     }
3133 
3134     if (initOk)
3135     {
3136         ADDR_ASSERT(m_tileTable[TILEINDEX_LINEAR_ALIGNED].mode == ADDR_TM_LINEAR_ALIGNED);
3137     }
3138 
3139     return initOk;
3140 }
3141 
3142 /**
3143 ****************************************************************************************************
3144 *   SiLib::HwlGetTileIndex
3145 *
3146 *   @brief
3147 *       Return the virtual/real index for given mode/type/info
3148 *   @return
3149 *       ADDR_OK if successful.
3150 ****************************************************************************************************
3151 */
HwlGetTileIndex(const ADDR_GET_TILEINDEX_INPUT * pIn,ADDR_GET_TILEINDEX_OUTPUT * pOut) const3152 ADDR_E_RETURNCODE SiLib::HwlGetTileIndex(
3153     const ADDR_GET_TILEINDEX_INPUT* pIn,
3154     ADDR_GET_TILEINDEX_OUTPUT*      pOut) const
3155 {
3156     ADDR_E_RETURNCODE returnCode = ADDR_OK;
3157 
3158     pOut->index = HwlPostCheckTileIndex(pIn->pTileInfo, pIn->tileMode, pIn->tileType);
3159 
3160     return returnCode;
3161 }
3162 
3163 /**
3164 ****************************************************************************************************
3165 *   SiLib::HwlFmaskPreThunkSurfInfo
3166 *
3167 *   @brief
3168 *       Some preparation before thunking a ComputeSurfaceInfo call for Fmask
3169 *   @return
3170 *       ADDR_E_RETURNCODE
3171 ****************************************************************************************************
3172 */
HwlFmaskPreThunkSurfInfo(const ADDR_COMPUTE_FMASK_INFO_INPUT * pFmaskIn,const ADDR_COMPUTE_FMASK_INFO_OUTPUT * pFmaskOut,ADDR_COMPUTE_SURFACE_INFO_INPUT * pSurfIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pSurfOut) const3173 VOID SiLib::HwlFmaskPreThunkSurfInfo(
3174     const ADDR_COMPUTE_FMASK_INFO_INPUT*    pFmaskIn,   ///< [in] Input of fmask info
3175     const ADDR_COMPUTE_FMASK_INFO_OUTPUT*   pFmaskOut,  ///< [in] Output of fmask info
3176     ADDR_COMPUTE_SURFACE_INFO_INPUT*        pSurfIn,    ///< [out] Input of thunked surface info
3177     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pSurfOut    ///< [out] Output of thunked surface info
3178     ) const
3179 {
3180     pSurfIn->tileIndex = pFmaskIn->tileIndex;
3181 }
3182 
3183 /**
3184 ****************************************************************************************************
3185 *   SiLib::HwlFmaskPostThunkSurfInfo
3186 *
3187 *   @brief
3188 *       Copy hwl extra field after calling thunked ComputeSurfaceInfo
3189 *   @return
3190 *       ADDR_E_RETURNCODE
3191 ****************************************************************************************************
3192 */
HwlFmaskPostThunkSurfInfo(const ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pSurfOut,ADDR_COMPUTE_FMASK_INFO_OUTPUT * pFmaskOut) const3193 VOID SiLib::HwlFmaskPostThunkSurfInfo(
3194     const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut,   ///< [in] Output of surface info
3195     ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut           ///< [out] Output of fmask info
3196     ) const
3197 {
3198     pFmaskOut->macroModeIndex = TileIndexInvalid;
3199     pFmaskOut->tileIndex = pSurfOut->tileIndex;
3200 }
3201 
3202 /**
3203 ****************************************************************************************************
3204 *   SiLib::HwlComputeFmaskBits
3205 *   @brief
3206 *       Computes fmask bits
3207 *   @return
3208 *       Fmask bits
3209 ****************************************************************************************************
3210 */
HwlComputeFmaskBits(const ADDR_COMPUTE_FMASK_INFO_INPUT * pIn,UINT_32 * pNumSamples) const3211 UINT_32 SiLib::HwlComputeFmaskBits(
3212     const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn,
3213     UINT_32* pNumSamples
3214     ) const
3215 {
3216     UINT_32 numSamples = pIn->numSamples;
3217     UINT_32 numFrags = GetNumFragments(numSamples, pIn->numFrags);
3218     UINT_32 bpp;
3219 
3220     if (numFrags != numSamples) // EQAA
3221     {
3222         ADDR_ASSERT(numFrags <= 8);
3223 
3224         if (pIn->resolved == FALSE)
3225         {
3226             if (numFrags == 1)
3227             {
3228                 bpp          = 1;
3229                 numSamples   = numSamples == 16 ? 16 : 8;
3230             }
3231             else if (numFrags == 2)
3232             {
3233                 ADDR_ASSERT(numSamples >= 4);
3234 
3235                 bpp          = 2;
3236                 numSamples   = numSamples;
3237             }
3238             else if (numFrags == 4)
3239             {
3240                 ADDR_ASSERT(numSamples >= 4);
3241 
3242                 bpp          = 4;
3243                 numSamples   = numSamples;
3244             }
3245             else // numFrags == 8
3246             {
3247                 ADDR_ASSERT(numSamples == 16);
3248 
3249                 bpp          = 4;
3250                 numSamples   = numSamples;
3251             }
3252         }
3253         else
3254         {
3255             if (numFrags == 1)
3256             {
3257                 bpp          = (numSamples == 16) ? 16 : 8;
3258                 numSamples   = 1;
3259             }
3260             else if (numFrags == 2)
3261             {
3262                 ADDR_ASSERT(numSamples >= 4);
3263 
3264                 bpp          = numSamples*2;
3265                 numSamples   = 1;
3266             }
3267             else if (numFrags == 4)
3268             {
3269                 ADDR_ASSERT(numSamples >= 4);
3270 
3271                 bpp          = numSamples*4;
3272                 numSamples   = 1;
3273             }
3274             else // numFrags == 8
3275             {
3276                 ADDR_ASSERT(numSamples >= 16);
3277 
3278                 bpp          = 16*4;
3279                 numSamples   = 1;
3280             }
3281         }
3282     }
3283     else // Normal AA
3284     {
3285         if (pIn->resolved == FALSE)
3286         {
3287             bpp          = ComputeFmaskNumPlanesFromNumSamples(numSamples);
3288             numSamples   = numSamples == 2 ? 8 : numSamples;
3289         }
3290         else
3291         {
3292             // The same as 8XX
3293             bpp          = ComputeFmaskResolvedBppFromNumSamples(numSamples);
3294             numSamples   = 1; // 1x sample
3295         }
3296     }
3297 
3298     SafeAssign(pNumSamples, numSamples);
3299 
3300     return bpp;
3301 }
3302 
3303 /**
3304 ****************************************************************************************************
3305 *   SiLib::HwlOptimizeTileMode
3306 *
3307 *   @brief
3308 *       Optimize tile mode on SI
3309 *
3310 *   @return
3311 *       N/A
3312 *
3313 ****************************************************************************************************
3314 */
HwlOptimizeTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT * pInOut) const3315 VOID SiLib::HwlOptimizeTileMode(
3316     ADDR_COMPUTE_SURFACE_INFO_INPUT*    pInOut      ///< [in,out] input output structure
3317     ) const
3318 {
3319     AddrTileMode tileMode = pInOut->tileMode;
3320 
3321     if ((pInOut->flags.needEquation == TRUE) &&
3322         (IsMacroTiled(tileMode) == TRUE) &&
3323         (pInOut->numSamples <= 1))
3324     {
3325         UINT_32 thickness = Thickness(tileMode);
3326 
3327         if (thickness > 1)
3328         {
3329             tileMode = ADDR_TM_1D_TILED_THICK;
3330         }
3331         else if (pInOut->numSlices > 1)
3332         {
3333             tileMode = ADDR_TM_1D_TILED_THIN1;
3334         }
3335         else
3336         {
3337             tileMode = ADDR_TM_2D_TILED_THIN1;
3338         }
3339     }
3340 
3341     if (tileMode != pInOut->tileMode)
3342     {
3343         pInOut->tileMode = tileMode;
3344     }
3345 }
3346 
3347 /**
3348 ****************************************************************************************************
3349 *   SiLib::HwlOverrideTileMode
3350 *
3351 *   @brief
3352 *       Override tile modes (for PRT only, avoid client passes in an invalid PRT mode for SI.
3353 *
3354 *   @return
3355 *       N/A
3356 *
3357 ****************************************************************************************************
3358 */
HwlOverrideTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT * pInOut) const3359 VOID SiLib::HwlOverrideTileMode(
3360     ADDR_COMPUTE_SURFACE_INFO_INPUT*    pInOut          ///< [in,out] input output structure
3361     ) const
3362 {
3363     AddrTileMode tileMode = pInOut->tileMode;
3364 
3365     switch (tileMode)
3366     {
3367         case ADDR_TM_PRT_TILED_THIN1:
3368             tileMode = ADDR_TM_2D_TILED_THIN1;
3369             break;
3370 
3371         case ADDR_TM_PRT_TILED_THICK:
3372             tileMode = ADDR_TM_2D_TILED_THICK;
3373             break;
3374 
3375         case ADDR_TM_PRT_2D_TILED_THICK:
3376             tileMode = ADDR_TM_2D_TILED_THICK;
3377             break;
3378 
3379         case ADDR_TM_PRT_3D_TILED_THICK:
3380             tileMode = ADDR_TM_3D_TILED_THICK;
3381             break;
3382 
3383         default:
3384             break;
3385     }
3386 
3387     if (tileMode != pInOut->tileMode)
3388     {
3389         pInOut->tileMode  = tileMode;
3390         // Only PRT tile modes are overridden for now. Revisit this once new modes are added above.
3391         pInOut->flags.prt = TRUE;
3392     }
3393 }
3394 
3395 /**
3396 ****************************************************************************************************
3397 *   SiLib::HwlSetPrtTileMode
3398 *
3399 *   @brief
3400 *       Set prt tile modes.
3401 *
3402 *   @return
3403 *       N/A
3404 *
3405 ****************************************************************************************************
3406 */
HwlSetPrtTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT * pInOut) const3407 VOID SiLib::HwlSetPrtTileMode(
3408     ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut     ///< [in,out] input output structure
3409     ) const
3410 {
3411     pInOut->tileMode = ADDR_TM_2D_TILED_THIN1;
3412     pInOut->tileType = (pInOut->tileType == ADDR_DEPTH_SAMPLE_ORDER) ?
3413                        ADDR_DEPTH_SAMPLE_ORDER : ADDR_NON_DISPLAYABLE;
3414     pInOut->flags.prt = TRUE;
3415 }
3416 
3417 /**
3418 ****************************************************************************************************
3419 *   SiLib::HwlSelectTileMode
3420 *
3421 *   @brief
3422 *       Select tile modes.
3423 *
3424 *   @return
3425 *       N/A
3426 *
3427 ****************************************************************************************************
3428 */
HwlSelectTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT * pInOut) const3429 VOID SiLib::HwlSelectTileMode(
3430     ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut     ///< [in,out] input output structure
3431     ) const
3432 {
3433     AddrTileMode tileMode;
3434     AddrTileType tileType;
3435 
3436     if (pInOut->flags.volume)
3437     {
3438         if (pInOut->numSlices >= 8)
3439         {
3440             tileMode = ADDR_TM_2D_TILED_XTHICK;
3441         }
3442         else if (pInOut->numSlices >= 4)
3443         {
3444             tileMode = ADDR_TM_2D_TILED_THICK;
3445         }
3446         else
3447         {
3448             tileMode = ADDR_TM_2D_TILED_THIN1;
3449         }
3450         tileType = ADDR_NON_DISPLAYABLE;
3451     }
3452     else
3453     {
3454         tileMode = ADDR_TM_2D_TILED_THIN1;
3455 
3456         if (pInOut->flags.depth || pInOut->flags.stencil)
3457         {
3458             tileType = ADDR_DEPTH_SAMPLE_ORDER;
3459         }
3460         else if ((pInOut->bpp <= 32) ||
3461                  (pInOut->flags.display == TRUE) ||
3462                  (pInOut->flags.overlay == TRUE))
3463         {
3464             tileType = ADDR_DISPLAYABLE;
3465         }
3466         else
3467         {
3468             tileType = ADDR_NON_DISPLAYABLE;
3469         }
3470     }
3471 
3472     if (pInOut->flags.prt)
3473     {
3474         tileMode = ADDR_TM_2D_TILED_THIN1;
3475         tileType = (tileType == ADDR_DISPLAYABLE) ? ADDR_NON_DISPLAYABLE : tileType;
3476     }
3477 
3478     pInOut->tileMode = tileMode;
3479     pInOut->tileType = tileType;
3480 
3481     // Optimize tile mode if possible
3482     pInOut->flags.opt4Space = TRUE;
3483 
3484     // Optimize tile mode if possible
3485     OptimizeTileMode(pInOut);
3486 
3487     HwlOverrideTileMode(pInOut);
3488 }
3489 
3490 /**
3491 ****************************************************************************************************
3492 *   SiLib::HwlComputeMaxBaseAlignments
3493 *
3494 *   @brief
3495 *       Gets maximum alignments
3496 *   @return
3497 *       maximum alignments
3498 ****************************************************************************************************
3499 */
HwlComputeMaxBaseAlignments() const3500 UINT_32 SiLib::HwlComputeMaxBaseAlignments() const
3501 {
3502     const UINT_32 pipes = HwlGetPipes(&m_tileTable[0].info);
3503 
3504     // Initial size is 64 KiB for PRT.
3505     UINT_32 maxBaseAlign = 64 * 1024;
3506 
3507     for (UINT_32 i = 0; i < m_noOfEntries; i++)
3508     {
3509         if ((IsMacroTiled(m_tileTable[i].mode) == TRUE) &&
3510             (IsPrtTileMode(m_tileTable[i].mode) == FALSE))
3511         {
3512             // The maximum tile size is 16 byte-per-pixel and either 8-sample or 8-slice.
3513             UINT_32 tileSize = Min(m_tileTable[i].info.tileSplitBytes,
3514                                    MicroTilePixels * 8 * 16);
3515 
3516             UINT_32 baseAlign = tileSize * pipes * m_tileTable[i].info.banks *
3517                                 m_tileTable[i].info.bankWidth * m_tileTable[i].info.bankHeight;
3518 
3519             if (baseAlign > maxBaseAlign)
3520             {
3521                 maxBaseAlign = baseAlign;
3522             }
3523         }
3524     }
3525 
3526     return maxBaseAlign;
3527 }
3528 
3529 /**
3530 ****************************************************************************************************
3531 *   SiLib::HwlComputeMaxMetaBaseAlignments
3532 *
3533 *   @brief
3534 *       Gets maximum alignments for metadata
3535 *   @return
3536 *       maximum alignments for metadata
3537 ****************************************************************************************************
3538 */
HwlComputeMaxMetaBaseAlignments() const3539 UINT_32 SiLib::HwlComputeMaxMetaBaseAlignments() const
3540 {
3541     UINT_32 maxPipe = 1;
3542 
3543     for (UINT_32 i = 0; i < m_noOfEntries; i++)
3544     {
3545         maxPipe = Max(maxPipe, HwlGetPipes(&m_tileTable[i].info));
3546     }
3547 
3548     return m_pipeInterleaveBytes * maxPipe;
3549 }
3550 
3551 /**
3552 ****************************************************************************************************
3553 *   SiLib::HwlComputeSurfaceAlignmentsMacroTiled
3554 *
3555 *   @brief
3556 *       Hardware layer function to compute alignment request for macro tile mode
3557 *
3558 *   @return
3559 *       N/A
3560 *
3561 ****************************************************************************************************
3562 */
HwlComputeSurfaceAlignmentsMacroTiled(AddrTileMode tileMode,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 mipLevel,UINT_32 numSamples,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const3563 VOID SiLib::HwlComputeSurfaceAlignmentsMacroTiled(
3564     AddrTileMode                      tileMode,           ///< [in] tile mode
3565     UINT_32                           bpp,                ///< [in] bits per pixel
3566     ADDR_SURFACE_FLAGS                flags,              ///< [in] surface flags
3567     UINT_32                           mipLevel,           ///< [in] mip level
3568     UINT_32                           numSamples,         ///< [in] number of samples
3569     ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut                ///< [in,out] Surface output
3570     ) const
3571 {
3572     if ((mipLevel == 0) && (flags.prt))
3573     {
3574         UINT_32 macroTileSize = pOut->blockWidth * pOut->blockHeight * numSamples * bpp / 8;
3575 
3576         if (macroTileSize < PrtTileSize)
3577         {
3578             UINT_32 numMacroTiles = PrtTileSize / macroTileSize;
3579 
3580             ADDR_ASSERT((PrtTileSize % macroTileSize) == 0);
3581 
3582             pOut->pitchAlign *= numMacroTiles;
3583             pOut->baseAlign  *= numMacroTiles;
3584         }
3585     }
3586 }
3587 
3588 /**
3589 ****************************************************************************************************
3590 *   SiLib::InitEquationTable
3591 *
3592 *   @brief
3593 *       Initialize Equation table.
3594 *
3595 *   @return
3596 *       N/A
3597 ****************************************************************************************************
3598 */
InitEquationTable()3599 VOID SiLib::InitEquationTable()
3600 {
3601     ADDR_EQUATION_KEY equationKeyTable[EquationTableSize];
3602     memset(equationKeyTable, 0, sizeof(equationKeyTable));
3603 
3604     memset(m_equationTable, 0, sizeof(m_equationTable));
3605 
3606     memset(m_blockWidth, 0, sizeof(m_blockWidth));
3607 
3608     memset(m_blockHeight, 0, sizeof(m_blockHeight));
3609 
3610     memset(m_blockSlices, 0, sizeof(m_blockSlices));
3611 
3612     // Loop all possible bpp
3613     for (UINT_32 log2ElementBytes = 0; log2ElementBytes < MaxNumElementBytes; log2ElementBytes++)
3614     {
3615         // Get bits per pixel
3616         UINT_32 bpp = 1 << (log2ElementBytes + 3);
3617 
3618         // Loop all possible tile index
3619         for (INT_32 tileIndex = 0; tileIndex < static_cast<INT_32>(m_noOfEntries); tileIndex++)
3620         {
3621             UINT_32 equationIndex = ADDR_INVALID_EQUATION_INDEX;
3622 
3623             TileConfig tileConfig = m_tileTable[tileIndex];
3624 
3625             ADDR_SURFACE_FLAGS flags = {{0}};
3626 
3627             // Compute tile info, hardcode numSamples to 1 because MSAA is not supported
3628             // in swizzle pattern equation
3629             HwlComputeMacroModeIndex(tileIndex, flags, bpp, 1, &tileConfig.info, NULL, NULL);
3630 
3631             // Check if the input is supported
3632             if (IsEquationSupported(bpp, tileConfig, tileIndex, log2ElementBytes) == TRUE)
3633             {
3634                 ADDR_EQUATION_KEY  key   = {{0}};
3635 
3636                 // Generate swizzle equation key from bpp and tile config
3637                 key.fields.log2ElementBytes = log2ElementBytes;
3638                 key.fields.tileMode         = tileConfig.mode;
3639                 // Treat depth micro tile type and non-display micro tile type as the same key
3640                 // because they have the same equation actually
3641                 key.fields.microTileType    = (tileConfig.type == ADDR_DEPTH_SAMPLE_ORDER) ?
3642                                               ADDR_NON_DISPLAYABLE : tileConfig.type;
3643                 key.fields.pipeConfig       = tileConfig.info.pipeConfig;
3644                 key.fields.numBanksLog2     = Log2(tileConfig.info.banks);
3645                 key.fields.bankWidth        = tileConfig.info.bankWidth;
3646                 key.fields.bankHeight       = tileConfig.info.bankHeight;
3647                 key.fields.macroAspectRatio = tileConfig.info.macroAspectRatio;
3648                 key.fields.prt              = ((m_chipFamily == ADDR_CHIP_FAMILY_SI) &&
3649                                                ((1 << tileIndex) & SiPrtTileIndexMask)) ? 1 : 0;
3650 
3651                 // Find in the table if the equation has been built based on the key
3652                 for (UINT_32 i = 0; i < m_numEquations; i++)
3653                 {
3654                     if (key.value == equationKeyTable[i].value)
3655                     {
3656                         equationIndex = i;
3657                         break;
3658                     }
3659                 }
3660 
3661                 // If found, just fill the index into the lookup table and no need
3662                 // to generate the equation again. Otherwise, generate the equation.
3663                 if (equationIndex == ADDR_INVALID_EQUATION_INDEX)
3664                 {
3665                     ADDR_EQUATION equation;
3666                     ADDR_E_RETURNCODE retCode;
3667 
3668                     memset(&equation, 0, sizeof(ADDR_EQUATION));
3669 
3670                     // Generate the equation
3671                     if (IsMicroTiled(tileConfig.mode))
3672                     {
3673                         retCode = ComputeMicroTileEquation(log2ElementBytes,
3674                                                            tileConfig.mode,
3675                                                            tileConfig.type,
3676                                                            &equation);
3677                     }
3678                     else
3679                     {
3680                         retCode = ComputeMacroTileEquation(log2ElementBytes,
3681                                                            tileConfig.mode,
3682                                                            tileConfig.type,
3683                                                            &tileConfig.info,
3684                                                            &equation);
3685                     }
3686                     // Only fill the equation into the table if the return code is ADDR_OK,
3687                     // otherwise if the return code is not ADDR_OK, it indicates this is not
3688                     // a valid input, we do nothing but just fill invalid equation index
3689                     // into the lookup table.
3690                     if (retCode == ADDR_OK)
3691                     {
3692                         equationIndex = m_numEquations;
3693                         ADDR_ASSERT(equationIndex < EquationTableSize);
3694 
3695                         m_blockSlices[equationIndex] = Thickness(tileConfig.mode);
3696 
3697                         if (IsMicroTiled(tileConfig.mode))
3698                         {
3699                             m_blockWidth[equationIndex]  = MicroTileWidth;
3700                             m_blockHeight[equationIndex] = MicroTileHeight;
3701                         }
3702                         else
3703                         {
3704                             const ADDR_TILEINFO* pTileInfo = &tileConfig.info;
3705 
3706                             m_blockWidth[equationIndex]  =
3707                                 HwlGetPipes(pTileInfo) * MicroTileWidth * pTileInfo->bankWidth *
3708                                 pTileInfo->macroAspectRatio;
3709                             m_blockHeight[equationIndex] =
3710                                 MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks /
3711                                 pTileInfo->macroAspectRatio;
3712 
3713                             if (key.fields.prt)
3714                             {
3715                                 UINT_32 macroTileSize =
3716                                     m_blockWidth[equationIndex] * m_blockHeight[equationIndex] *
3717                                     bpp / 8;
3718 
3719                                 if (macroTileSize < PrtTileSize)
3720                                 {
3721                                     UINT_32 numMacroTiles = PrtTileSize / macroTileSize;
3722 
3723                                     ADDR_ASSERT(macroTileSize == (1u << equation.numBits));
3724                                     ADDR_ASSERT((PrtTileSize % macroTileSize) == 0);
3725 
3726                                     UINT_32 numBits = Log2(numMacroTiles);
3727 
3728                                     UINT_32 xStart = Log2(m_blockWidth[equationIndex]) +
3729                                                      log2ElementBytes;
3730 
3731                                     m_blockWidth[equationIndex] *= numMacroTiles;
3732 
3733                                     for (UINT_32 i = 0; i < numBits; i++)
3734                                     {
3735                                         equation.addr[equation.numBits + i].valid = 1;
3736                                         equation.addr[equation.numBits + i].index = xStart + i;
3737                                     }
3738 
3739                                     equation.numBits += numBits;
3740                                 }
3741                             }
3742                         }
3743 
3744                         equationKeyTable[equationIndex] = key;
3745                         m_equationTable[equationIndex]  = equation;
3746 
3747                         m_numEquations++;
3748                     }
3749                 }
3750             }
3751 
3752             // Fill the index into the lookup table, if the combination is not supported
3753             // fill the invalid equation index
3754             m_equationLookupTable[log2ElementBytes][tileIndex] = equationIndex;
3755         }
3756 
3757         if (m_chipFamily == ADDR_CHIP_FAMILY_SI)
3758         {
3759             // For tile index 3 which is shared between PRT depth and uncompressed depth
3760             m_uncompressDepthEqIndex = m_numEquations;
3761 
3762             for (UINT_32 log2ElemBytes = 0; log2ElemBytes < MaxNumElementBytes; log2ElemBytes++)
3763             {
3764                 TileConfig        tileConfig = m_tileTable[3];
3765                 ADDR_EQUATION     equation;
3766                 ADDR_E_RETURNCODE retCode;
3767 
3768                 memset(&equation, 0, sizeof(ADDR_EQUATION));
3769 
3770                 retCode = ComputeMacroTileEquation(log2ElemBytes,
3771                                                    tileConfig.mode,
3772                                                    tileConfig.type,
3773                                                    &tileConfig.info,
3774                                                    &equation);
3775 
3776                 if (retCode == ADDR_OK)
3777                 {
3778                     UINT_32 equationIndex = m_numEquations;
3779                     ADDR_ASSERT(equationIndex < EquationTableSize);
3780 
3781                     m_blockSlices[equationIndex] = 1;
3782 
3783                     const ADDR_TILEINFO* pTileInfo = &tileConfig.info;
3784 
3785                     m_blockWidth[equationIndex]  =
3786                         HwlGetPipes(pTileInfo) * MicroTileWidth * pTileInfo->bankWidth *
3787                         pTileInfo->macroAspectRatio;
3788                     m_blockHeight[equationIndex] =
3789                         MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks /
3790                         pTileInfo->macroAspectRatio;
3791 
3792                     m_equationTable[equationIndex] = equation;
3793 
3794                     m_numEquations++;
3795                 }
3796             }
3797         }
3798     }
3799 }
3800 
3801 /**
3802 ****************************************************************************************************
3803 *   SiLib::IsEquationSupported
3804 *
3805 *   @brief
3806 *       Check if it is supported for given bpp and tile config to generate a equation.
3807 *
3808 *   @return
3809 *       TRUE if supported
3810 ****************************************************************************************************
3811 */
IsEquationSupported(UINT_32 bpp,TileConfig tileConfig,INT_32 tileIndex,UINT_32 elementBytesLog2) const3812 BOOL_32 SiLib::IsEquationSupported(
3813     UINT_32    bpp,             ///< Bits per pixel
3814     TileConfig tileConfig,      ///< Tile config
3815     INT_32     tileIndex,       ///< Tile index
3816     UINT_32    elementBytesLog2 ///< Log2 of element bytes
3817     ) const
3818 {
3819     BOOL_32 supported = TRUE;
3820 
3821     // Linear tile mode is not supported in swizzle pattern equation
3822     if (IsLinear(tileConfig.mode))
3823     {
3824         supported = FALSE;
3825     }
3826     // These tile modes are for Tex2DArray and Tex3D which has depth (num_slice > 1) use,
3827     // which is not supported in swizzle pattern equation due to slice rotation
3828     else if ((tileConfig.mode == ADDR_TM_2D_TILED_THICK)  ||
3829              (tileConfig.mode == ADDR_TM_2D_TILED_XTHICK) ||
3830              (tileConfig.mode == ADDR_TM_3D_TILED_THIN1)  ||
3831              (tileConfig.mode == ADDR_TM_3D_TILED_THICK)  ||
3832              (tileConfig.mode == ADDR_TM_3D_TILED_XTHICK))
3833     {
3834         supported = FALSE;
3835     }
3836     // Only 8bpp(stencil), 16bpp and 32bpp is supported for depth
3837     else if ((tileConfig.type == ADDR_DEPTH_SAMPLE_ORDER) && (bpp > 32))
3838     {
3839         supported = FALSE;
3840     }
3841     // Tile split is not supported in swizzle pattern equation
3842     else if (IsMacroTiled(tileConfig.mode))
3843     {
3844         UINT_32 thickness = Thickness(tileConfig.mode);
3845         if (((bpp >> 3) * MicroTilePixels * thickness) > tileConfig.info.tileSplitBytes)
3846         {
3847             supported = FALSE;
3848         }
3849 
3850         if ((supported == TRUE) && (m_chipFamily == ADDR_CHIP_FAMILY_SI))
3851         {
3852             supported = m_EquationSupport[tileIndex][elementBytesLog2];
3853         }
3854     }
3855 
3856     return supported;
3857 }
3858 
3859 } // V1
3860 } // Addr
3861