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