• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2014 Advanced Micro Devices, Inc.
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16  * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17  * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20  * USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * The above copyright notice and this permission notice (including the
23  * next paragraph) shall be included in all copies or substantial portions
24  * of the Software.
25  */
26 
27 /**
28 ***************************************************************************************************
29 * @file  siaddrlib.cpp
30 * @brief Contains the implementation for the SIAddrLib class.
31 ***************************************************************************************************
32 */
33 
34 #include "siaddrlib.h"
35 
36 #include "si_gb_reg.h"
37 
38 #include "si_ci_vi_merged_enum.h"
39 
40 #if BRAHMA_BUILD
41 #include "amdgpu_id.h"
42 #else
43 #include "si_id.h"
44 #endif
45 
46 ///////////////////////////////////////////////////////////////////////////////////////////////////
47 ///////////////////////////////////////////////////////////////////////////////////////////////////
48 
49 /**
50 ***************************************************************************************************
51 *   AddrSIHwlInit
52 *
53 *   @brief
54 *       Creates an SIAddrLib object.
55 *
56 *   @return
57 *       Returns an SIAddrLib object pointer.
58 ***************************************************************************************************
59 */
AddrSIHwlInit(const AddrClient * pClient)60 AddrLib* AddrSIHwlInit(const AddrClient* pClient)
61 {
62     return SIAddrLib::CreateObj(pClient);
63 }
64 
65 /**
66 ***************************************************************************************************
67 *   SIAddrLib::SIAddrLib
68 *
69 *   @brief
70 *       Constructor
71 *
72 ***************************************************************************************************
73 */
SIAddrLib(const AddrClient * pClient)74 SIAddrLib::SIAddrLib(const AddrClient* pClient) :
75     EgBasedAddrLib(pClient),
76     m_noOfEntries(0)
77 {
78     m_class = SI_ADDRLIB;
79     memset(&m_settings, 0, sizeof(m_settings));
80 }
81 
82 /**
83 ***************************************************************************************************
84 *   SIAddrLib::~SIAddrLib
85 *
86 *   @brief
87 *       Destructor
88 ***************************************************************************************************
89 */
~SIAddrLib()90 SIAddrLib::~SIAddrLib()
91 {
92 }
93 
94 /**
95 ***************************************************************************************************
96 *   SIAddrLib::HwlGetPipes
97 *
98 *   @brief
99 *       Get number pipes
100 *   @return
101 *       num pipes
102 ***************************************************************************************************
103 */
HwlGetPipes(const ADDR_TILEINFO * pTileInfo) const104 UINT_32 SIAddrLib::HwlGetPipes(
105     const ADDR_TILEINFO* pTileInfo    ///< [in] Tile info
106     ) const
107 {
108     UINT_32 numPipes;
109 
110     if (pTileInfo)
111     {
112         numPipes = GetPipePerSurf(pTileInfo->pipeConfig);
113     }
114     else
115     {
116         ADDR_ASSERT_ALWAYS();
117         numPipes = m_pipes; // Suppose we should still have a global pipes
118     }
119 
120     return numPipes;
121 }
122 
123 /**
124 ***************************************************************************************************
125 *   SIAddrLib::GetPipePerSurf
126 *   @brief
127 *       get pipe num base on inputing tileinfo->pipeconfig
128 *   @return
129 *       pipe number
130 ***************************************************************************************************
131 */
GetPipePerSurf(AddrPipeCfg pipeConfig) const132 UINT_32 SIAddrLib::GetPipePerSurf(
133     AddrPipeCfg pipeConfig   ///< [in] pipe config
134     ) const
135 {
136     UINT_32 numPipes = 0;
137 
138     switch (pipeConfig)
139     {
140         case ADDR_PIPECFG_P2:
141             numPipes = 2;
142             break;
143         case ADDR_PIPECFG_P4_8x16:
144         case ADDR_PIPECFG_P4_16x16:
145         case ADDR_PIPECFG_P4_16x32:
146         case ADDR_PIPECFG_P4_32x32:
147             numPipes = 4;
148             break;
149         case ADDR_PIPECFG_P8_16x16_8x16:
150         case ADDR_PIPECFG_P8_16x32_8x16:
151         case ADDR_PIPECFG_P8_32x32_8x16:
152         case ADDR_PIPECFG_P8_16x32_16x16:
153         case ADDR_PIPECFG_P8_32x32_16x16:
154         case ADDR_PIPECFG_P8_32x32_16x32:
155         case ADDR_PIPECFG_P8_32x64_32x32:
156             numPipes = 8;
157             break;
158         case ADDR_PIPECFG_P16_32x32_8x16:
159         case ADDR_PIPECFG_P16_32x32_16x16:
160             numPipes = 16;
161             break;
162         default:
163             ADDR_ASSERT(!"Invalid pipe config");
164             numPipes = m_pipes;
165     }
166     return numPipes;
167 }
168 
169 /**
170 ***************************************************************************************************
171 *   SIAddrLib::ComputePipeFromCoord
172 *
173 *   @brief
174 *       Compute pipe number from coordinates
175 *   @return
176 *       Pipe number
177 ***************************************************************************************************
178 */
ComputePipeFromCoord(UINT_32 x,UINT_32 y,UINT_32 slice,AddrTileMode tileMode,UINT_32 pipeSwizzle,BOOL_32 ignoreSE,ADDR_TILEINFO * pTileInfo) const179 UINT_32 SIAddrLib::ComputePipeFromCoord(
180     UINT_32         x,              ///< [in] x coordinate
181     UINT_32         y,              ///< [in] y coordinate
182     UINT_32         slice,          ///< [in] slice index
183     AddrTileMode    tileMode,       ///< [in] tile mode
184     UINT_32         pipeSwizzle,    ///< [in] pipe swizzle
185     BOOL_32         ignoreSE,       ///< [in] TRUE if shader engines are ignored
186     ADDR_TILEINFO*  pTileInfo       ///< [in] Tile info
187     ) const
188 {
189     UINT_32 pipe;
190     UINT_32 pipeBit0 = 0;
191     UINT_32 pipeBit1 = 0;
192     UINT_32 pipeBit2 = 0;
193     UINT_32 pipeBit3 = 0;
194     UINT_32 sliceRotation;
195     UINT_32 numPipes = 0;
196 
197     UINT_32 tx = x / MicroTileWidth;
198     UINT_32 ty = y / MicroTileHeight;
199     UINT_32 x3 = _BIT(tx,0);
200     UINT_32 x4 = _BIT(tx,1);
201     UINT_32 x5 = _BIT(tx,2);
202     UINT_32 x6 = _BIT(tx,3);
203     UINT_32 y3 = _BIT(ty,0);
204     UINT_32 y4 = _BIT(ty,1);
205     UINT_32 y5 = _BIT(ty,2);
206     UINT_32 y6 = _BIT(ty,3);
207 
208     switch (pTileInfo->pipeConfig)
209     {
210         case ADDR_PIPECFG_P2:
211             pipeBit0 = x3 ^ y3;
212             numPipes = 2;
213             break;
214         case ADDR_PIPECFG_P4_8x16:
215             pipeBit0 = x4 ^ y3;
216             pipeBit1 = x3 ^ y4;
217             numPipes = 4;
218             break;
219         case ADDR_PIPECFG_P4_16x16:
220             pipeBit0 = x3 ^ y3 ^ x4;
221             pipeBit1 = x4 ^ y4;
222             numPipes = 4;
223             break;
224         case ADDR_PIPECFG_P4_16x32:
225             pipeBit0 = x3 ^ y3 ^ x4;
226             pipeBit1 = x4 ^ y5;
227             numPipes = 4;
228             break;
229         case ADDR_PIPECFG_P4_32x32:
230             pipeBit0 = x3 ^ y3 ^ x5;
231             pipeBit1 = x5 ^ y5;
232             numPipes = 4;
233             break;
234         case ADDR_PIPECFG_P8_16x16_8x16:
235             pipeBit0 = x4 ^ y3 ^ x5;
236             pipeBit1 = x3 ^ y5;
237             numPipes = 8;
238             break;
239         case ADDR_PIPECFG_P8_16x32_8x16:
240             pipeBit0 = x4 ^ y3 ^ x5;
241             pipeBit1 = x3 ^ y4;
242             pipeBit2 = x4 ^ y5;
243             numPipes = 8;
244             break;
245         case ADDR_PIPECFG_P8_16x32_16x16:
246             pipeBit0 = x3 ^ y3 ^ x4;
247             pipeBit1 = x5 ^ y4;
248             pipeBit2 = x4 ^ y5;
249             numPipes = 8;
250             break;
251         case ADDR_PIPECFG_P8_32x32_8x16:
252             pipeBit0 = x4 ^ y3 ^ x5;
253             pipeBit1 = x3 ^ y4;
254             pipeBit2 = x5 ^ y5;
255             numPipes = 8;
256             break;
257         case ADDR_PIPECFG_P8_32x32_16x16:
258             pipeBit0 = x3 ^ y3 ^ x4;
259             pipeBit1 = x4 ^ y4;
260             pipeBit2 = x5 ^ y5;
261             numPipes = 8;
262             break;
263         case ADDR_PIPECFG_P8_32x32_16x32:
264             pipeBit0 = x3 ^ y3 ^ x4;
265             pipeBit1 = x4 ^ y6;
266             pipeBit2 = x5 ^ y5;
267             numPipes = 8;
268             break;
269         case ADDR_PIPECFG_P8_32x64_32x32:
270             pipeBit0 = x3 ^ y3 ^ x5;
271             pipeBit1 = x6 ^ y5;
272             pipeBit2 = x5 ^ y6;
273             numPipes = 8;
274             break;
275         case ADDR_PIPECFG_P16_32x32_8x16:
276             pipeBit0 = x4 ^ y3;
277             pipeBit1 = x3 ^ y4;
278             pipeBit2 = x5 ^ y6;
279             pipeBit3 = x6 ^ y5;
280             numPipes = 16;
281             break;
282         case ADDR_PIPECFG_P16_32x32_16x16:
283             pipeBit0 = x3 ^ y3 ^ x4;
284             pipeBit1 = x4 ^ y4;
285             pipeBit2 = x5 ^ y6;
286             pipeBit3 = x6 ^ y5;
287             numPipes = 16;
288             break;
289         default:
290             ADDR_UNHANDLED_CASE();
291             break;
292     }
293     pipe = pipeBit0 | (pipeBit1 << 1) | (pipeBit2 << 2) | (pipeBit3 << 3);
294 
295     UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode);
296 
297     //
298     // Apply pipe rotation for the slice.
299     //
300     switch (tileMode)
301     {
302         case ADDR_TM_3D_TILED_THIN1:    //fall through thin
303         case ADDR_TM_3D_TILED_THICK:    //fall through thick
304         case ADDR_TM_3D_TILED_XTHICK:
305             sliceRotation =
306                 Max(1, static_cast<INT_32>(numPipes / 2) - 1) * (slice / microTileThickness);
307             break;
308         default:
309             sliceRotation = 0;
310             break;
311     }
312     pipeSwizzle += sliceRotation;
313     pipeSwizzle &= (numPipes - 1);
314 
315     pipe = pipe ^ pipeSwizzle;
316 
317     return pipe;
318 }
319 
320 /**
321 ***************************************************************************************************
322 *   SIAddrLib::ComputeTileCoordFromPipeAndElemIdx
323 *
324 *   @brief
325 *       Compute (x,y) of a tile within a macro tile from address
326 *   @return
327 *       Pipe number
328 ***************************************************************************************************
329 */
ComputeTileCoordFromPipeAndElemIdx(UINT_32 elemIdx,UINT_32 pipe,AddrPipeCfg pipeCfg,UINT_32 pitchInMacroTile,UINT_32 x,UINT_32 y,UINT_32 * pX,UINT_32 * pY) const330 VOID SIAddrLib::ComputeTileCoordFromPipeAndElemIdx(
331     UINT_32         elemIdx,          ///< [in] per pipe element index within a macro tile
332     UINT_32         pipe,             ///< [in] pipe index
333     AddrPipeCfg     pipeCfg,          ///< [in] pipe config
334     UINT_32         pitchInMacroTile, ///< [in] surface pitch in macro tile
335     UINT_32         x,                ///< [in] x coordinate of the (0,0) tile in a macro tile
336     UINT_32         y,                ///< [in] y coordinate of the (0,0) tile in a macro tile
337     UINT_32*        pX,               ///< [out] x coordinate
338     UINT_32*        pY                ///< [out] y coordinate
339     ) const
340 {
341     UINT_32 pipebit0 = _BIT(pipe,0);
342     UINT_32 pipebit1 = _BIT(pipe,1);
343     UINT_32 pipebit2 = _BIT(pipe,2);
344     UINT_32 pipebit3 = _BIT(pipe,3);
345     UINT_32 elemIdx0 = _BIT(elemIdx,0);
346     UINT_32 elemIdx1 = _BIT(elemIdx,1);
347     UINT_32 elemIdx2 = _BIT(elemIdx,2);
348     UINT_32 x3 = 0;
349     UINT_32 x4 = 0;
350     UINT_32 x5 = 0;
351     UINT_32 x6 = 0;
352     UINT_32 y3 = 0;
353     UINT_32 y4 = 0;
354     UINT_32 y5 = 0;
355     UINT_32 y6 = 0;
356 
357     switch(pipeCfg)
358     {
359         case ADDR_PIPECFG_P2:
360             x4 = elemIdx2;
361             y4 = elemIdx1 ^ x4;
362             y3 = elemIdx0 ^ x4;
363             x3 = pipebit0 ^ y3;
364             *pY = Bits2Number(2, y4, y3);
365             *pX = Bits2Number(2, x4, x3);
366             break;
367         case ADDR_PIPECFG_P4_8x16:
368             x4 = elemIdx1;
369             y4 = elemIdx0 ^ x4;
370             x3 = pipebit1 ^ y4;
371             y3 = pipebit0 ^ x4;
372             *pY = Bits2Number(2, y4, y3);
373             *pX = Bits2Number(2, x4, x3);
374             break;
375         case ADDR_PIPECFG_P4_16x16:
376             x4 = elemIdx1;
377             y3 = elemIdx0 ^ x4;
378             y4 = pipebit1 ^ x4;
379             x3 = pipebit0 ^ y3 ^ x4;
380             *pY = Bits2Number(2, y4, y3);
381             *pX = Bits2Number(2, x4, x3);
382             break;
383         case ADDR_PIPECFG_P4_16x32:
384             x3 = elemIdx0 ^ pipebit0;
385             y5 = _BIT(y,5);
386             x4 = pipebit1 ^ y5;
387             y3 = pipebit0 ^ x3 ^ x4;
388             y4 = elemIdx1 ^ x4;
389             *pY = Bits2Number(2, y4, y3);
390             *pX = Bits2Number(2, x4, x3);
391             break;
392         case ADDR_PIPECFG_P4_32x32:
393             x4 = elemIdx2;
394             y3 = elemIdx0 ^ x4;
395             y4 = elemIdx1 ^ x4;
396             if((pitchInMacroTile % 2) == 0)
397             {   //even
398                 y5 = _BIT(y,5);
399                 x5 = pipebit1 ^ y5;
400                 x3 = pipebit0 ^ y3 ^ x5;
401                 *pY = Bits2Number(2, y4, y3);
402                 *pX = Bits2Number(3, x5, x4, x3);
403             }
404             else
405             {   //odd
406                 x5 = _BIT(x,5);
407                 x3 = pipebit0 ^ y3 ^ x5;
408                 *pY = Bits2Number(2, y4, y3);
409                 *pX = Bits2Number(2, x4, x3);
410             }
411             break;
412         case ADDR_PIPECFG_P8_16x16_8x16:
413             x4 = elemIdx0;
414             y5 = _BIT(y,5);
415             x5 = _BIT(x,5);
416             x3 = pipebit1 ^ y5;
417             y4 = pipebit2 ^ x4;
418             y3 = pipebit0 ^ x5 ^ x4;
419             *pY = Bits2Number(2, y4, y3);
420             *pX = Bits2Number(2, x4, x3);
421             break;
422         case ADDR_PIPECFG_P8_16x32_8x16:
423             x3 = elemIdx0;
424             y4 = pipebit1 ^ x3;
425             y5 = _BIT(y,5);
426             x5 = _BIT(x,5);
427             x4 = pipebit2 ^ y5;
428             y3 = pipebit0 ^ x4 ^ x5;
429             *pY = Bits2Number(2, y4, y3);
430             *pX = Bits2Number(2, x4, x3);
431             break;
432         case ADDR_PIPECFG_P8_32x32_8x16:
433             x4 = elemIdx1;
434             y4 = elemIdx0 ^ x4;
435             x3 = pipebit1 ^ y4;
436             if((pitchInMacroTile % 2) == 0)
437             {  //even
438                 y5 = _BIT(y,5);
439                 x5 = _BIT(x,5);
440                 x5 = pipebit2 ^ y5;
441                 y3 = pipebit0 ^ x4 ^ x5;
442                 *pY = Bits2Number(2, y4, y3);
443                 *pX = Bits2Number(3, x5, x4, x3);
444             }
445             else
446             {  //odd
447                 x5 = _BIT(x,5);
448                 y3 = pipebit0 ^ x4 ^ x5;
449                 *pY = Bits2Number(2, y4, y3);
450                 *pX = Bits2Number(2, x4, x3);
451             }
452             break;
453         case ADDR_PIPECFG_P8_16x32_16x16:
454             x3 = elemIdx0;
455             x5 = _BIT(x,5);
456             y5 = _BIT(y,5);
457             x4 = pipebit2 ^ y5;
458             y4 = pipebit1 ^ x5;
459             y3 = pipebit0 ^ x3 ^ x4;
460             *pY = Bits2Number(2, y4, y3);
461             *pX = Bits2Number(2, x4, x3);
462             break;
463         case ADDR_PIPECFG_P8_32x32_16x16:
464             x4 = elemIdx1;
465             y3 = elemIdx0 ^ x4;
466             x3 = y3^x4^pipebit0;
467             y4 = pipebit1 ^ x4;
468             if((pitchInMacroTile % 2) == 0)
469             {   //even
470                 y5 = _BIT(y,5);
471                 x5 = pipebit2 ^ y5;
472                 *pY = Bits2Number(2, y4, y3);
473                 *pX = Bits2Number(3, x5, x4, x3);
474             }
475             else
476             {   //odd
477                 *pY = Bits2Number(2, y4, y3);
478                 *pX = Bits2Number(2, x4, x3);
479             }
480             break;
481         case ADDR_PIPECFG_P8_32x32_16x32:
482             if((pitchInMacroTile % 2) == 0)
483             {   //even
484                 y5 = _BIT(y,5);
485                 y6 = _BIT(y,6);
486                 x4 = pipebit1 ^ y6;
487                 y3 = elemIdx0 ^ x4;
488                 y4 = elemIdx1 ^ x4;
489                 x3 = pipebit0 ^ y3 ^ x4;
490                 x5 = pipebit2 ^ y5;
491                 *pY = Bits2Number(2, y4, y3);
492                 *pX = Bits2Number(3, x5, x4, x3);
493             }
494             else
495             {   //odd
496                 y6 = _BIT(y,6);
497                 x4 = pipebit1 ^ y6;
498                 y3 = elemIdx0 ^ x4;
499                 y4 = elemIdx1 ^ x4;
500                 x3 = pipebit0 ^ y3 ^ x4;
501                 *pY = Bits2Number(2, y4, y3);
502                 *pX = Bits2Number(2, x4, x3);
503             }
504             break;
505         case ADDR_PIPECFG_P8_32x64_32x32:
506             x4 = elemIdx2;
507             y3 = elemIdx0 ^ x4;
508             y4 = elemIdx1 ^ x4;
509             if((pitchInMacroTile % 4) == 0)
510             {   //multiple of 4
511                 y5 = _BIT(y,5);
512                 y6 = _BIT(y,6);
513                 x5 = pipebit2 ^ y6;
514                 x6 = pipebit1 ^ y5;
515                 x3 = pipebit0 ^ y3 ^ x5;
516                 *pY = Bits2Number(2, y4, y3);
517                 *pX = Bits2Number(4, x6, x5, x4, x3);
518             }
519             else
520             {
521                 y6 = _BIT(y,6);
522                 x5 = pipebit2 ^ y6;
523                 x3 = pipebit0 ^ y3 ^ x5;
524                 *pY = Bits2Number(2, y4, y3);
525                 *pX = Bits2Number(3, x5, x4, x3);
526             }
527             break;
528         case ADDR_PIPECFG_P16_32x32_8x16:
529             x4 = elemIdx1;
530             y4 = elemIdx0 ^ x4;
531             y3 = pipebit0 ^ x4;
532             x3 = pipebit1 ^ y4;
533             if((pitchInMacroTile % 4) == 0)
534             {   //multiple of 4
535                 y5 = _BIT(y,5);
536                 y6 = _BIT(y,6);
537                 x5 = pipebit2 ^ y6;
538                 x6 = pipebit3 ^ y5;
539                 *pY = Bits2Number(2, y4, y3);
540                 *pX = Bits2Number(4, x6, x5,x4, x3);
541             }
542             else
543             {
544                 y6 = _BIT(y,6);
545                 x5 = pipebit2 ^ y6;
546                 *pY = Bits2Number(2, y4, y3);
547                 *pX = Bits2Number(3, x5, x4, x3);
548             }
549             break;
550         case ADDR_PIPECFG_P16_32x32_16x16:
551             x4 = elemIdx1;
552             y3 = elemIdx0 ^ x4;
553             y4 = pipebit1 ^ x4;
554             x3 = pipebit0 ^ y3 ^ x4;
555             if((pitchInMacroTile % 4) == 0)
556             {   //multiple of 4
557                 y5 = _BIT(y,5);
558                 y6 = _BIT(y,6);
559                 x5 = pipebit2 ^ y6;
560                 x6 = pipebit3 ^ y5;
561                 *pY = Bits2Number(2, y4, y3);
562                 *pX = Bits2Number(4, x6, x5, x4, x3);
563             }
564             else
565             {
566                 y6 = _BIT(y,6);
567                 x5 = pipebit2 ^ y6;
568                 *pY = Bits2Number(2, y4, y3);
569                 *pX = Bits2Number(3, x5, x4, x3);
570             }
571             break;
572         default:
573             ADDR_UNHANDLED_CASE();
574     }
575 }
576 
577 /**
578 ***************************************************************************************************
579 *   SIAddrLib::TileCoordToMaskElementIndex
580 *
581 *   @brief
582 *       Compute element index from coordinates in tiles
583 *   @return
584 *       Element index
585 ***************************************************************************************************
586 */
TileCoordToMaskElementIndex(UINT_32 tx,UINT_32 ty,AddrPipeCfg pipeConfig,UINT_32 * macroShift,UINT_32 * elemIdxBits) const587 UINT_32 SIAddrLib::TileCoordToMaskElementIndex(
588     UINT_32         tx,                 ///< [in] x coord, in Tiles
589     UINT_32         ty,                 ///< [in] y coord, in Tiles
590     AddrPipeCfg     pipeConfig,         ///< [in] pipe config
591     UINT_32*        macroShift,         ///< [out] macro shift
592     UINT_32*        elemIdxBits         ///< [out] tile offset bits
593     ) const
594 {
595     UINT_32 elemIdx = 0;
596     UINT_32 elemIdx0, elemIdx1, elemIdx2;
597     UINT_32 tx0, tx1;
598     UINT_32 ty0, ty1;
599 
600     tx0 = _BIT(tx,0);
601     tx1 = _BIT(tx,1);
602     ty0 = _BIT(ty,0);
603     ty1 = _BIT(ty,1);
604 
605     switch(pipeConfig)
606     {
607         case ADDR_PIPECFG_P2:
608             *macroShift = 3;
609             *elemIdxBits =3;
610             elemIdx2 = tx1;
611             elemIdx1 = tx1 ^ ty1;
612             elemIdx0 = tx1 ^ ty0;
613             elemIdx = Bits2Number(3,elemIdx2,elemIdx1,elemIdx0);
614             break;
615         case ADDR_PIPECFG_P4_8x16:
616             *macroShift = 2;
617             *elemIdxBits =2;
618             elemIdx1 = tx1;
619             elemIdx0 = tx1 ^ ty1;
620             elemIdx = Bits2Number(2,elemIdx1,elemIdx0);
621             break;
622         case ADDR_PIPECFG_P4_16x16:
623             *macroShift = 2;
624             *elemIdxBits =2;
625             elemIdx0 = tx1^ty0;
626             elemIdx1 = tx1;
627             elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
628             break;
629         case ADDR_PIPECFG_P4_16x32:
630             *macroShift = 2;
631             *elemIdxBits =2;
632             elemIdx0 = tx1^ty0;
633             elemIdx1 = tx1^ty1;
634             elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
635             break;
636         case ADDR_PIPECFG_P4_32x32:
637             *macroShift = 2;
638             *elemIdxBits =3;
639             elemIdx0 = tx1^ty0;
640             elemIdx1 = tx1^ty1;
641             elemIdx2 = tx1;
642             elemIdx = Bits2Number(3, elemIdx2, elemIdx1, elemIdx0);
643             break;
644         case ADDR_PIPECFG_P8_16x16_8x16:
645             *macroShift = 1;
646             *elemIdxBits =1;
647             elemIdx0 = tx1;
648             elemIdx = elemIdx0;
649             break;
650         case ADDR_PIPECFG_P8_16x32_8x16:
651             *macroShift = 1;
652             *elemIdxBits =1;
653             elemIdx0 = tx0;
654             elemIdx = elemIdx0;
655             break;
656         case ADDR_PIPECFG_P8_32x32_8x16:
657             *macroShift = 1;
658             *elemIdxBits =2;
659             elemIdx1 = tx1;
660             elemIdx0 = tx1^ty1;
661             elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
662             break;
663         case ADDR_PIPECFG_P8_16x32_16x16:
664             *macroShift = 1;
665             *elemIdxBits =1;
666             elemIdx0 = tx0;
667             elemIdx = elemIdx0;
668             break;
669         case ADDR_PIPECFG_P8_32x32_16x16:
670             *macroShift = 1;
671             *elemIdxBits =2;
672             elemIdx0 = tx1^ty0;
673             elemIdx1 = tx1;
674             elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
675             break;
676         case ADDR_PIPECFG_P8_32x32_16x32:
677             *macroShift = 1;
678             *elemIdxBits =2;
679             elemIdx0 =  tx1^ty0;
680             elemIdx1 = tx1^ty1;
681             elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
682             break;
683         case ADDR_PIPECFG_P8_32x64_32x32:
684             *macroShift = 1;
685             *elemIdxBits =3;
686             elemIdx0 = tx1^ty0;
687             elemIdx1 = tx1^ty1;
688             elemIdx2 = tx1;
689             elemIdx = Bits2Number(3, elemIdx2, elemIdx1, elemIdx0);
690             break;
691         case ADDR_PIPECFG_P16_32x32_8x16:
692             *macroShift = 0;
693             *elemIdxBits =2;
694             elemIdx0 = tx1^ty1;
695             elemIdx1 = tx1;
696             elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
697             break;
698         case ADDR_PIPECFG_P16_32x32_16x16:
699             *macroShift = 0;
700             *elemIdxBits =2;
701             elemIdx0 = tx1^ty0;
702             elemIdx1 = tx1;
703             elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
704             break;
705         default:
706             ADDR_UNHANDLED_CASE();
707             break;
708     }
709 
710     return elemIdx;
711 }
712 
713 /**
714 ***************************************************************************************************
715 *   SIAddrLib::HwlComputeTileDataWidthAndHeightLinear
716 *
717 *   @brief
718 *       Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
719 *
720 *   @return
721 *       N/A
722 *
723 *   @note
724 *       MacroWidth and macroHeight are measured in pixels
725 ***************************************************************************************************
726 */
HwlComputeTileDataWidthAndHeightLinear(UINT_32 * pMacroWidth,UINT_32 * pMacroHeight,UINT_32 bpp,ADDR_TILEINFO * pTileInfo) const727 VOID SIAddrLib::HwlComputeTileDataWidthAndHeightLinear(
728     UINT_32*        pMacroWidth,     ///< [out] macro tile width
729     UINT_32*        pMacroHeight,    ///< [out] macro tile height
730     UINT_32         bpp,             ///< [in] bits per pixel
731     ADDR_TILEINFO*  pTileInfo        ///< [in] tile info
732     ) const
733 {
734     ADDR_ASSERT(pTileInfo != NULL);
735     UINT_32 macroWidth;
736     UINT_32 macroHeight;
737 
738     /// In linear mode, the htile or cmask buffer must be padded out to 4 tiles
739     /// but for P8_32x64_32x32, it must be padded out to 8 tiles
740     /// Actually there are more pipe configs which need 8-tile padding but SI family
741     /// has a bug which is fixed in CI family
742     if ((pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32) ||
743         (pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_8x16) ||
744         (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x32_16x16))
745     {
746         macroWidth  = 8*MicroTileWidth;
747         macroHeight = 8*MicroTileHeight;
748     }
749     else
750     {
751         macroWidth  = 4*MicroTileWidth;
752         macroHeight = 4*MicroTileHeight;
753     }
754 
755     *pMacroWidth    = macroWidth;
756     *pMacroHeight   = macroHeight;
757 }
758 
759 /**
760 ***************************************************************************************************
761 *   SIAddrLib::HwlComputeHtileBytes
762 *
763 *   @brief
764 *       Compute htile size in bytes
765 *
766 *   @return
767 *       Htile size in bytes
768 ***************************************************************************************************
769 */
HwlComputeHtileBytes(UINT_32 pitch,UINT_32 height,UINT_32 bpp,BOOL_32 isLinear,UINT_32 numSlices,UINT_64 * pSliceBytes,UINT_32 baseAlign) const770 UINT_64 SIAddrLib::HwlComputeHtileBytes(
771     UINT_32     pitch,          ///< [in] pitch
772     UINT_32     height,         ///< [in] height
773     UINT_32     bpp,            ///< [in] bits per pixel
774     BOOL_32     isLinear,       ///< [in] if it is linear mode
775     UINT_32     numSlices,      ///< [in] number of slices
776     UINT_64*    pSliceBytes,    ///< [out] bytes per slice
777     UINT_32     baseAlign       ///< [in] base alignments
778     ) const
779 {
780     return ComputeHtileBytes(pitch, height, bpp, isLinear, numSlices, pSliceBytes, baseAlign);
781 }
782 
783 /**
784 ***************************************************************************************************
785 *   SIAddrLib::HwlComputeXmaskAddrFromCoord
786 *
787 *   @brief
788 *       Compute address from coordinates for htile/cmask
789 *   @return
790 *       Byte address
791 ***************************************************************************************************
792 */
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) const793 UINT_64 SIAddrLib::HwlComputeXmaskAddrFromCoord(
794     UINT_32        pitch,          ///< [in] pitch
795     UINT_32        height,         ///< [in] height
796     UINT_32        x,              ///< [in] x coord
797     UINT_32        y,              ///< [in] y coord
798     UINT_32        slice,          ///< [in] slice/depth index
799     UINT_32        numSlices,      ///< [in] number of slices
800     UINT_32        factor,         ///< [in] factor that indicates cmask(2) or htile(1)
801     BOOL_32        isLinear,       ///< [in] linear or tiled HTILE layout
802     BOOL_32        isWidth8,       ///< [in] TRUE if width is 8, FALSE means 4. It's register value
803     BOOL_32        isHeight8,      ///< [in] TRUE if width is 8, FALSE means 4. It's register value
804     ADDR_TILEINFO* pTileInfo,      ///< [in] Tile info
805     UINT_32*       pBitPosition    ///< [out] bit position inside a byte
806     ) const
807 {
808     UINT_32 tx = x / MicroTileWidth;
809     UINT_32 ty = y / MicroTileHeight;
810     UINT_32 newPitch;
811     UINT_32 newHeight;
812     UINT_64 totalBytes;
813     UINT_32 macroWidth;
814     UINT_32 macroHeight;
815     UINT_64 pSliceBytes;
816     UINT_32 pBaseAlign;
817     UINT_32 tileNumPerPipe;
818     UINT_32 elemBits;
819 
820     if (factor == 2) //CMASK
821     {
822         ADDR_CMASK_FLAGS flags = {{0}};
823 
824         tileNumPerPipe = 256;
825 
826         ComputeCmaskInfo(flags,
827                          pitch,
828                          height,
829                          numSlices,
830                          isLinear,
831                          pTileInfo,
832                          &newPitch,
833                          &newHeight,
834                          &totalBytes,
835                          &macroWidth,
836                          &macroHeight);
837         elemBits = CmaskElemBits;
838     }
839     else //HTile
840     {
841         ADDR_HTILE_FLAGS flags = {{0}};
842 
843         tileNumPerPipe = 512;
844 
845         ComputeHtileInfo(flags,
846                          pitch,
847                          height,
848                          numSlices,
849                          isLinear,
850                          TRUE,
851                          TRUE,
852                          pTileInfo,
853                          &newPitch,
854                          &newHeight,
855                          &totalBytes,
856                          &macroWidth,
857                          &macroHeight,
858                          &pSliceBytes,
859                          &pBaseAlign);
860         elemBits = 32;
861     }
862 
863     const UINT_32 pitchInTile = newPitch / MicroTileWidth;
864     const UINT_32 heightInTile = newHeight / MicroTileWidth;
865     UINT_64 macroOffset; // Per pipe starting offset of the macro tile in which this tile lies.
866     UINT_64 microNumber; // Per pipe starting offset of the macro tile in which this tile lies.
867     UINT_32 microX;
868     UINT_32 microY;
869     UINT_64 microOffset;
870     UINT_32 microShift;
871     UINT_64 totalOffset;
872     UINT_32 elemIdxBits;
873     UINT_32 elemIdx =
874         TileCoordToMaskElementIndex(tx, ty, pTileInfo->pipeConfig, &microShift, &elemIdxBits);
875 
876     UINT_32 numPipes = HwlGetPipes(pTileInfo);
877 
878     if (isLinear)
879     {   //linear addressing
880         // Linear addressing is extremelly wasting memory if slice > 1, since each pipe has the full
881         // slice memory foot print instead of divided by numPipes.
882         microX = tx / 4; // Macro Tile is 4x4
883         microY = ty / 4 ;
884         microNumber = static_cast<UINT_64>(microX + microY * (pitchInTile / 4)) << microShift;
885 
886         UINT_32 sliceBits = pitchInTile * heightInTile;
887 
888         // do htile single slice alignment if the flag is true
889         if (m_configFlags.useHtileSliceAlign && (factor == 1))  //Htile
890         {
891             sliceBits = PowTwoAlign(sliceBits, BITS_TO_BYTES(HtileCacheBits) * numPipes / elemBits);
892         }
893         macroOffset = slice * (sliceBits / numPipes) * elemBits ;
894     }
895     else
896     {   //tiled addressing
897         const UINT_32 macroWidthInTile = macroWidth / MicroTileWidth; // Now in unit of Tiles
898         const UINT_32 macroHeightInTile = macroHeight / MicroTileHeight;
899         const UINT_32 pitchInCL = pitchInTile / macroWidthInTile;
900         const UINT_32 heightInCL = heightInTile / macroHeightInTile;
901 
902         const UINT_32 macroX = x / macroWidth;
903         const UINT_32 macroY = y / macroHeight;
904         const UINT_32 macroNumber = macroX + macroY * pitchInCL + slice * pitchInCL * heightInCL;
905 
906         // Per pipe starting offset of the cache line in which this tile lies.
907         microX = (x % macroWidth) / MicroTileWidth / 4; // Macro Tile is 4x4
908         microY = (y % macroHeight) / MicroTileHeight / 4 ;
909         microNumber = static_cast<UINT_64>(microX + microY * (macroWidth / MicroTileWidth / 4)) << microShift;
910 
911         macroOffset = macroNumber * tileNumPerPipe * elemBits;
912     }
913 
914     if(elemIdxBits == microShift)
915     {
916         microNumber += elemIdx;
917     }
918     else
919     {
920         microNumber >>= elemIdxBits;
921         microNumber <<= elemIdxBits;
922         microNumber += elemIdx;
923     }
924 
925     microOffset = elemBits * microNumber;
926     totalOffset = microOffset + macroOffset;
927 
928     UINT_32 pipe = ComputePipeFromCoord(x, y, 0, ADDR_TM_2D_TILED_THIN1, 0, FALSE, pTileInfo);
929     UINT_64 addrInBits = totalOffset % (m_pipeInterleaveBytes * 8) +
930                    pipe * (m_pipeInterleaveBytes * 8) +
931                    totalOffset / (m_pipeInterleaveBytes * 8) * (m_pipeInterleaveBytes * 8) * numPipes;
932     *pBitPosition = static_cast<UINT_32>(addrInBits) % 8;
933     UINT_64 addr = addrInBits / 8;
934 
935     return addr;
936 }
937 
938 /**
939 ***************************************************************************************************
940 *   SIAddrLib::HwlComputeXmaskCoordFromAddr
941 *
942 *   @brief
943 *       Compute the coord from an address of a cmask/htile
944 *
945 *   @return
946 *       N/A
947 *
948 *   @note
949 *       This method is reused by htile, so rename to Xmask
950 ***************************************************************************************************
951 */
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) const952 VOID SIAddrLib::HwlComputeXmaskCoordFromAddr(
953     UINT_64         addr,           ///< [in] address
954     UINT_32         bitPosition,    ///< [in] bitPosition in a byte
955     UINT_32         pitch,          ///< [in] pitch
956     UINT_32         height,         ///< [in] height
957     UINT_32         numSlices,      ///< [in] number of slices
958     UINT_32         factor,         ///< [in] factor that indicates cmask or htile
959     BOOL_32         isLinear,       ///< [in] linear or tiled HTILE layout
960     BOOL_32         isWidth8,       ///< [in] Not used by SI
961     BOOL_32         isHeight8,      ///< [in] Not used by SI
962     ADDR_TILEINFO*  pTileInfo,      ///< [in] Tile info
963     UINT_32*        pX,             ///< [out] x coord
964     UINT_32*        pY,             ///< [out] y coord
965     UINT_32*        pSlice          ///< [out] slice index
966     ) const
967 {
968     UINT_32 newPitch;
969     UINT_32 newHeight;
970     UINT_64 totalBytes;
971     UINT_32 clWidth;
972     UINT_32 clHeight;
973     UINT_32 tileNumPerPipe;
974     UINT_64 sliceBytes;
975 
976     *pX = 0;
977     *pY = 0;
978     *pSlice = 0;
979 
980     if (factor == 2) //CMASK
981     {
982         ADDR_CMASK_FLAGS flags = {{0}};
983 
984         tileNumPerPipe = 256;
985 
986         ComputeCmaskInfo(flags,
987                          pitch,
988                          height,
989                          numSlices,
990                          isLinear,
991                          pTileInfo,
992                          &newPitch,
993                          &newHeight,
994                          &totalBytes,
995                          &clWidth,
996                          &clHeight);
997     }
998     else //HTile
999     {
1000         ADDR_HTILE_FLAGS flags = {{0}};
1001 
1002         tileNumPerPipe = 512;
1003 
1004         ComputeHtileInfo(flags,
1005                          pitch,
1006                          height,
1007                          numSlices,
1008                          isLinear,
1009                          TRUE,
1010                          TRUE,
1011                          pTileInfo,
1012                          &newPitch,
1013                          &newHeight,
1014                          &totalBytes,
1015                          &clWidth,
1016                          &clHeight,
1017                          &sliceBytes);
1018     }
1019 
1020     const UINT_32 pitchInTile = newPitch / MicroTileWidth;
1021     const UINT_32 heightInTile = newHeight / MicroTileWidth;
1022     const UINT_32 pitchInMacroTile = pitchInTile / 4;
1023     UINT_32 macroShift;
1024     UINT_32 elemIdxBits;
1025     // get macroShift and elemIdxBits
1026     TileCoordToMaskElementIndex(0, 0, pTileInfo->pipeConfig, &macroShift, &elemIdxBits);
1027 
1028     const UINT_32 numPipes = HwlGetPipes(pTileInfo);
1029     const UINT_32 pipe = (UINT_32)((addr / m_pipeInterleaveBytes) % numPipes);
1030     // per pipe
1031     UINT_64 localOffset = (addr % m_pipeInterleaveBytes) +
1032         (addr / m_pipeInterleaveBytes / numPipes)* m_pipeInterleaveBytes;
1033 
1034     UINT_32 tileIndex;
1035     if (factor == 2) //CMASK
1036     {
1037         tileIndex = (UINT_32)(localOffset * 2 + (bitPosition != 0));
1038     }
1039     else
1040     {
1041         tileIndex = (UINT_32)(localOffset / 4);
1042     }
1043 
1044     UINT_32 macroOffset;
1045     if (isLinear)
1046     {
1047         UINT_32 sliceSizeInTile = pitchInTile * heightInTile;
1048 
1049         // do htile single slice alignment if the flag is true
1050         if (m_configFlags.useHtileSliceAlign && (factor == 1))  //Htile
1051         {
1052             sliceSizeInTile = PowTwoAlign(sliceSizeInTile, static_cast<UINT_32>(sliceBytes) / 64);
1053         }
1054         *pSlice = tileIndex / (sliceSizeInTile / numPipes);
1055         macroOffset = tileIndex % (sliceSizeInTile / numPipes);
1056     }
1057     else
1058     {
1059         const UINT_32 clWidthInTile = clWidth / MicroTileWidth; // Now in unit of Tiles
1060         const UINT_32 clHeightInTile = clHeight / MicroTileHeight;
1061         const UINT_32 pitchInCL = pitchInTile / clWidthInTile;
1062         const UINT_32 heightInCL = heightInTile / clHeightInTile;
1063         const UINT_32 clIndex = tileIndex / tileNumPerPipe;
1064 
1065         UINT_32 clX = clIndex % pitchInCL;
1066         UINT_32 clY = (clIndex % (heightInCL * pitchInCL)) / pitchInCL;
1067 
1068         *pX = clX * clWidthInTile * MicroTileWidth;
1069         *pY = clY * clHeightInTile * MicroTileHeight;
1070         *pSlice = clIndex / (heightInCL * pitchInCL);
1071 
1072         macroOffset = tileIndex % tileNumPerPipe;
1073     }
1074 
1075     UINT_32 elemIdx = macroOffset & 7;
1076     macroOffset >>= elemIdxBits;
1077 
1078     if (elemIdxBits != macroShift)
1079     {
1080         macroOffset <<= (elemIdxBits - macroShift);
1081 
1082         UINT_32 pipebit1 = _BIT(pipe,1);
1083         UINT_32 pipebit2 = _BIT(pipe,2);
1084         UINT_32 pipebit3 = _BIT(pipe,3);
1085         if (pitchInMacroTile % 2)
1086         {   //odd
1087             switch (pTileInfo->pipeConfig)
1088             {
1089                 case ADDR_PIPECFG_P4_32x32:
1090                     macroOffset |= pipebit1;
1091                     break;
1092                 case ADDR_PIPECFG_P8_32x32_8x16:
1093                 case ADDR_PIPECFG_P8_32x32_16x16:
1094                 case ADDR_PIPECFG_P8_32x32_16x32:
1095                     macroOffset |= pipebit2;
1096                     break;
1097                 default:
1098                     break;
1099             }
1100 
1101         }
1102 
1103         if (pitchInMacroTile % 4)
1104         {
1105             if (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32)
1106             {
1107                 macroOffset |= (pipebit1<<1);
1108             }
1109             if((pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_8x16) ||
1110                (pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_16x16))
1111             {
1112                 macroOffset |= (pipebit3<<1);
1113             }
1114         }
1115     }
1116 
1117     UINT_32 macroX;
1118     UINT_32 macroY;
1119 
1120     if (isLinear)
1121     {
1122         macroX = macroOffset % pitchInMacroTile;
1123         macroY = macroOffset / pitchInMacroTile;
1124     }
1125     else
1126     {
1127         const UINT_32 clWidthInMacroTile = clWidth / (MicroTileWidth * 4);
1128         macroX = macroOffset % clWidthInMacroTile;
1129         macroY = macroOffset / clWidthInMacroTile;
1130     }
1131 
1132     *pX += macroX * 4 * MicroTileWidth;
1133     *pY += macroY * 4 * MicroTileHeight;
1134 
1135     UINT_32 microX;
1136     UINT_32 microY;
1137     ComputeTileCoordFromPipeAndElemIdx(elemIdx, pipe, pTileInfo->pipeConfig, pitchInMacroTile,
1138                                        *pX, *pY, &microX, &microY);
1139 
1140     *pX += microX * MicroTileWidth;
1141     *pY += microY * MicroTileWidth;
1142 }
1143 
1144 /**
1145 ***************************************************************************************************
1146 *   SIAddrLib::HwlGetPitchAlignmentLinear
1147 *   @brief
1148 *       Get pitch alignment
1149 *   @return
1150 *       pitch alignment
1151 ***************************************************************************************************
1152 */
HwlGetPitchAlignmentLinear(UINT_32 bpp,ADDR_SURFACE_FLAGS flags) const1153 UINT_32 SIAddrLib::HwlGetPitchAlignmentLinear(
1154     UINT_32             bpp,    ///< [in] bits per pixel
1155     ADDR_SURFACE_FLAGS  flags   ///< [in] surface flags
1156     ) const
1157 {
1158     UINT_32 pitchAlign;
1159 
1160     // Interleaved access requires a 256B aligned pitch, so fall back to pre-SI alignment
1161     if (flags.interleaved)
1162     {
1163         pitchAlign = Max(64u, m_pipeInterleaveBytes / BITS_TO_BYTES(bpp));
1164 
1165     }
1166     else
1167     {
1168         pitchAlign = Max(8u, 64 / BITS_TO_BYTES(bpp));
1169     }
1170 
1171     return pitchAlign;
1172 }
1173 
1174 /**
1175 ***************************************************************************************************
1176 *   SIAddrLib::HwlGetSizeAdjustmentLinear
1177 *
1178 *   @brief
1179 *       Adjust linear surface pitch and slice size
1180 *
1181 *   @return
1182 *       Logical slice size in bytes
1183 ***************************************************************************************************
1184 */
HwlGetSizeAdjustmentLinear(AddrTileMode tileMode,UINT_32 bpp,UINT_32 numSamples,UINT_32 baseAlign,UINT_32 pitchAlign,UINT_32 * pPitch,UINT_32 * pHeight,UINT_32 * pHeightAlign) const1185 UINT_64 SIAddrLib::HwlGetSizeAdjustmentLinear(
1186     AddrTileMode        tileMode,       ///< [in] tile mode
1187     UINT_32             bpp,            ///< [in] bits per pixel
1188     UINT_32             numSamples,     ///< [in] number of samples
1189     UINT_32             baseAlign,      ///< [in] base alignment
1190     UINT_32             pitchAlign,     ///< [in] pitch alignment
1191     UINT_32*            pPitch,         ///< [in/out] pointer to pitch
1192     UINT_32*            pHeight,        ///< [in/out] pointer to height
1193     UINT_32*            pHeightAlign    ///< [in/out] pointer to height align
1194     ) const
1195 {
1196     UINT_64 sliceSize;
1197     if (tileMode == ADDR_TM_LINEAR_GENERAL)
1198     {
1199         sliceSize = BITS_TO_BYTES(static_cast<UINT_64>(*pPitch) * (*pHeight) * bpp * numSamples);
1200     }
1201     else
1202     {
1203         UINT_32 pitch   = *pPitch;
1204         UINT_32 height  = *pHeight;
1205 
1206         UINT_32 pixelsPerPipeInterleave = m_pipeInterleaveBytes / BITS_TO_BYTES(bpp);
1207         UINT_32 sliceAlignInPixel = pixelsPerPipeInterleave < 64 ? 64 : pixelsPerPipeInterleave;
1208 
1209         // numSamples should be 1 in real cases (no MSAA for linear but TGL may pass non 1 value)
1210         UINT_64 pixelPerSlice = static_cast<UINT_64>(pitch) * height * numSamples;
1211 
1212         while (pixelPerSlice % sliceAlignInPixel)
1213         {
1214             pitch += pitchAlign;
1215             pixelPerSlice = static_cast<UINT_64>(pitch) * height * numSamples;
1216         }
1217 
1218         *pPitch = pitch;
1219 
1220         UINT_32 heightAlign = 1;
1221 
1222         while ((pitch * heightAlign) % sliceAlignInPixel)
1223         {
1224             heightAlign++;
1225         }
1226 
1227         *pHeightAlign = heightAlign;
1228 
1229         sliceSize = BITS_TO_BYTES(pixelPerSlice * bpp);
1230     }
1231 
1232     return sliceSize;
1233 }
1234 
1235 /**
1236 ***************************************************************************************************
1237 *   SIAddrLib::HwlPreHandleBaseLvl3xPitch
1238 *
1239 *   @brief
1240 *       Pre-handler of 3x pitch (96 bit) adjustment
1241 *
1242 *   @return
1243 *       Expected pitch
1244 ***************************************************************************************************
1245 */
HwlPreHandleBaseLvl3xPitch(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,UINT_32 expPitch) const1246 UINT_32 SIAddrLib::HwlPreHandleBaseLvl3xPitch(
1247     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] input
1248     UINT_32                                 expPitch    ///< [in] pitch
1249     ) const
1250 {
1251     ADDR_ASSERT(pIn->width == expPitch);
1252 
1253     // From SI, if pow2Pad is 1 the pitch is expanded 3x first, then padded to pow2, so nothing to
1254     // do here
1255     if (!pIn->flags.pow2Pad)
1256     {
1257         AddrLib::HwlPreHandleBaseLvl3xPitch(pIn, expPitch);
1258     }
1259     else
1260     {
1261         ADDR_ASSERT(IsPow2(expPitch));
1262     }
1263 
1264     return expPitch;
1265 }
1266 
1267 /**
1268 ***************************************************************************************************
1269 *   SIAddrLib::HwlPostHandleBaseLvl3xPitch
1270 *
1271 *   @brief
1272 *       Post-handler of 3x pitch adjustment
1273 *
1274 *   @return
1275 *       Expected pitch
1276 ***************************************************************************************************
1277 */
HwlPostHandleBaseLvl3xPitch(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,UINT_32 expPitch) const1278 UINT_32 SIAddrLib::HwlPostHandleBaseLvl3xPitch(
1279     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] input
1280     UINT_32                                 expPitch    ///< [in] pitch
1281     ) const
1282 {
1283     /**
1284      * @note The pitch will be divided by 3 in the end so the value will look odd but h/w should
1285      *  be able to compute a correct pitch from it as h/w address library is doing the job.
1286      */
1287     // From SI, the pitch is expanded 3x first, then padded to pow2, so no special handler here
1288     if (!pIn->flags.pow2Pad)
1289     {
1290         AddrLib::HwlPostHandleBaseLvl3xPitch(pIn, expPitch);
1291     }
1292 
1293     return expPitch;
1294 }
1295 
1296 /**
1297 ***************************************************************************************************
1298 *   SIAddrLib::HwlGetPitchAlignmentMicroTiled
1299 *
1300 *   @brief
1301 *       Compute 1D tiled surface pitch alignment
1302 *
1303 *   @return
1304 *       pitch alignment
1305 ***************************************************************************************************
1306 */
HwlGetPitchAlignmentMicroTiled(AddrTileMode tileMode,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 numSamples) const1307 UINT_32 SIAddrLib::HwlGetPitchAlignmentMicroTiled(
1308     AddrTileMode        tileMode,          ///< [in] tile mode
1309     UINT_32             bpp,               ///< [in] bits per pixel
1310     ADDR_SURFACE_FLAGS  flags,             ///< [in] surface flags
1311     UINT_32             numSamples         ///< [in] number of samples
1312     ) const
1313 {
1314     UINT_32 pitchAlign;
1315 
1316     if (flags.qbStereo)
1317     {
1318         pitchAlign = EgBasedAddrLib::HwlGetPitchAlignmentMicroTiled(tileMode,bpp,flags,numSamples);
1319     }
1320     else
1321     {
1322         pitchAlign = 8;
1323     }
1324 
1325     return pitchAlign;
1326 }
1327 
1328 /**
1329 ***************************************************************************************************
1330 *   SIAddrLib::HwlGetSizeAdjustmentMicroTiled
1331 *
1332 *   @brief
1333 *       Adjust 1D tiled surface pitch and slice size
1334 *
1335 *   @return
1336 *       Logical slice size in bytes
1337 ***************************************************************************************************
1338 */
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) const1339 UINT_64 SIAddrLib::HwlGetSizeAdjustmentMicroTiled(
1340     UINT_32             thickness,      ///< [in] thickness
1341     UINT_32             bpp,            ///< [in] bits per pixel
1342     ADDR_SURFACE_FLAGS  flags,          ///< [in] surface flags
1343     UINT_32             numSamples,     ///< [in] number of samples
1344     UINT_32             baseAlign,      ///< [in] base alignment
1345     UINT_32             pitchAlign,     ///< [in] pitch alignment
1346     UINT_32*            pPitch,         ///< [in/out] pointer to pitch
1347     UINT_32*            pHeight         ///< [in/out] pointer to height
1348     ) const
1349 {
1350     UINT_64 logicalSliceSize;
1351     UINT_64 physicalSliceSize;
1352 
1353     UINT_32 pitch   = *pPitch;
1354     UINT_32 height  = *pHeight;
1355 
1356     // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
1357     logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
1358 
1359     // Physical slice: multiplied by thickness
1360     physicalSliceSize =  logicalSliceSize * thickness;
1361 
1362     // Pitch alignment is always 8, so if slice size is not padded to base alignment
1363     // (pipe_interleave_size), we need to increase pitch
1364     while ((physicalSliceSize % baseAlign) != 0)
1365     {
1366         pitch += pitchAlign;
1367 
1368         logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
1369 
1370         physicalSliceSize =  logicalSliceSize * thickness;
1371     }
1372 
1373 #if !ALT_TEST
1374     //
1375     // Special workaround for depth/stencil buffer, use 8 bpp to align depth buffer again since
1376     // the stencil plane may have larger pitch if the slice size is smaller than base alignment.
1377     //
1378     // Note: this actually does not work for mipmap but mipmap depth texture is not really
1379     // sampled with mipmap.
1380     //
1381     if (flags.depth && !flags.noStencil)
1382     {
1383         ADDR_ASSERT(numSamples == 1);
1384 
1385         UINT_64 logicalSiceSizeStencil = static_cast<UINT_64>(pitch) * height; // 1 byte stencil
1386 
1387         while ((logicalSiceSizeStencil % baseAlign) != 0)
1388         {
1389             pitch += pitchAlign; // Stencil plane's pitch alignment is the same as depth plane's
1390 
1391             logicalSiceSizeStencil = static_cast<UINT_64>(pitch) * height;
1392         }
1393 
1394         if (pitch != *pPitch)
1395         {
1396             // If this is a mipmap, this padded one cannot be sampled as a whole mipmap!
1397             logicalSliceSize = logicalSiceSizeStencil * BITS_TO_BYTES(bpp);
1398         }
1399     }
1400 #endif
1401     *pPitch = pitch;
1402 
1403     // No adjust for pHeight
1404 
1405     return logicalSliceSize;
1406 }
1407 
1408 /**
1409 ***************************************************************************************************
1410 *   SIAddrLib::HwlConvertChipFamily
1411 *
1412 *   @brief
1413 *       Convert familyID defined in atiid.h to AddrChipFamily and set m_chipFamily/m_chipRevision
1414 *   @return
1415 *       AddrChipFamily
1416 ***************************************************************************************************
1417 */
HwlConvertChipFamily(UINT_32 uChipFamily,UINT_32 uChipRevision)1418 AddrChipFamily SIAddrLib::HwlConvertChipFamily(
1419     UINT_32 uChipFamily,        ///< [in] chip family defined in atiih.h
1420     UINT_32 uChipRevision)      ///< [in] chip revision defined in "asic_family"_id.h
1421 {
1422     AddrChipFamily family = ADDR_CHIP_FAMILY_SI;
1423 
1424     switch (uChipFamily)
1425     {
1426         case FAMILY_SI:
1427             m_settings.isSouthernIsland = 1;
1428             m_settings.isTahiti     = ASICREV_IS_TAHITI_P(uChipRevision);
1429             m_settings.isPitCairn   = ASICREV_IS_PITCAIRN_PM(uChipRevision);
1430             m_settings.isCapeVerde  = ASICREV_IS_CAPEVERDE_M(uChipRevision);
1431             m_settings.isOland      = ASICREV_IS_OLAND_M(uChipRevision);
1432             m_settings.isHainan     = ASICREV_IS_HAINAN_V(uChipRevision);
1433             break;
1434         default:
1435             ADDR_ASSERT(!"This should be a Fusion");
1436             break;
1437     }
1438 
1439     return family;
1440 }
1441 
1442 /**
1443 ***************************************************************************************************
1444 *   SIAddrLib::HwlSetupTileInfo
1445 *
1446 *   @brief
1447 *       Setup default value of tile info for SI
1448 ***************************************************************************************************
1449 */
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) const1450 VOID SIAddrLib::HwlSetupTileInfo(
1451     AddrTileMode                        tileMode,       ///< [in] Tile mode
1452     ADDR_SURFACE_FLAGS                  flags,          ///< [in] Surface type flags
1453     UINT_32                             bpp,            ///< [in] Bits per pixel
1454     UINT_32                             pitch,          ///< [in] Pitch in pixels
1455     UINT_32                             height,         ///< [in] Height in pixels
1456     UINT_32                             numSamples,     ///< [in] Number of samples
1457     ADDR_TILEINFO*                      pTileInfoIn,    ///< [in] Tile info input: NULL for default
1458     ADDR_TILEINFO*                      pTileInfoOut,   ///< [out] Tile info output
1459     AddrTileType                        inTileType,     ///< [in] Tile type
1460     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*   pOut            ///< [out] Output
1461     ) const
1462 {
1463     UINT_32 thickness = ComputeSurfaceThickness(tileMode);
1464     ADDR_TILEINFO* pTileInfo = pTileInfoOut;
1465     INT index = TileIndexInvalid;
1466 
1467     // Fail-safe code
1468     if (!IsLinear(tileMode))
1469     {
1470         // 128 bpp/thick tiling must be non-displayable.
1471         // Fmask reuse color buffer's entry but bank-height field can be from another entry
1472         // To simplify the logic, fmask entry should be picked from non-displayable ones
1473         if (bpp == 128 || thickness > 1 || flags.fmask || flags.prt)
1474         {
1475             inTileType = ADDR_NON_DISPLAYABLE;
1476         }
1477 
1478         if (flags.depth || flags.stencil)
1479         {
1480             inTileType = ADDR_DEPTH_SAMPLE_ORDER;
1481         }
1482     }
1483 
1484     // Partial valid fields are not allowed for SI.
1485     if (IsTileInfoAllZero(pTileInfo))
1486     {
1487         if (IsMacroTiled(tileMode))
1488         {
1489             if (flags.prt)
1490             {
1491                 if (numSamples == 1)
1492                 {
1493                     if (flags.depth)
1494                     {
1495                         switch (bpp)
1496                         {
1497                             case 16:
1498                                 index = 3;
1499                                 break;
1500                             case 32:
1501                                 index = 6;
1502                                 break;
1503                             default:
1504                                 ADDR_ASSERT_ALWAYS();
1505                                 break;
1506                         }
1507                     }
1508                     else
1509                     {
1510                         switch (bpp)
1511                         {
1512                             case 8:
1513                                 index = 21;
1514                                 break;
1515                             case 16:
1516                                 index = 22;
1517                                 break;
1518                             case 32:
1519                                 index = 23;
1520                                 break;
1521                             case 64:
1522                                 index = 24;
1523                                 break;
1524                             case 128:
1525                                 index = 25;
1526                                 break;
1527                             default:
1528                                 break;
1529                         }
1530 
1531                         if (thickness > 1)
1532                         {
1533                             ADDR_ASSERT(bpp != 128);
1534                             index += 5;
1535                         }
1536                     }
1537                 }
1538                 else
1539                 {
1540                     ADDR_ASSERT(numSamples == 4);
1541 
1542                     if (flags.depth)
1543                     {
1544                         switch (bpp)
1545                         {
1546                             case 16:
1547                                 index = 5;
1548                                 break;
1549                             case 32:
1550                                 index = 7;
1551                                 break;
1552                             default:
1553                                 ADDR_ASSERT_ALWAYS();
1554                                 break;
1555                         }
1556                     }
1557                     else
1558                     {
1559                         switch (bpp)
1560                         {
1561                             case 8:
1562                                 index = 23;
1563                                 break;
1564                             case 16:
1565                                 index = 24;
1566                                 break;
1567                             case 32:
1568                                 index = 25;
1569                                 break;
1570                             case 64:
1571                                 index = 30;
1572                                 break;
1573                             default:
1574                                 ADDR_ASSERT_ALWAYS();
1575                                 break;
1576                         }
1577                     }
1578                 }
1579             }//end of PRT part
1580             // See table entries 0-7
1581             else if (flags.depth || flags.stencil)
1582             {
1583                 if (flags.compressZ)
1584                 {
1585                     if (flags.stencil)
1586                     {
1587                         index = 0;
1588                     }
1589                     else
1590                     {
1591                         // optimal tile index for compressed depth/stencil.
1592                         switch (numSamples)
1593                         {
1594                             case 1:
1595                                 index = 0;
1596                                 break;
1597                             case 2:
1598                             case 4:
1599                                 index = 1;
1600                                 break;
1601                             case 8:
1602                                 index = 2;
1603                                 break;
1604                             default:
1605                                 break;
1606                         }
1607                     }
1608                 }
1609                 else // unCompressZ
1610                 {
1611                     index = 3;
1612                 }
1613             }
1614             else //non PRT & non Depth & non Stencil
1615             {
1616                 // See table entries 9-12
1617                 if (inTileType == ADDR_DISPLAYABLE)
1618                 {
1619                     switch (bpp)
1620                     {
1621                         case 8:
1622                             index = 10;
1623                             break;
1624                         case 16:
1625                             index = 11;
1626                             break;
1627                         case 32:
1628                             index = 12;
1629                             break;
1630                         case 64:
1631                             index = 12;
1632                             break;
1633                         default:
1634                             break;
1635                     }
1636                 }
1637                 else
1638                 {
1639                     // See table entries 13-17
1640                     if (thickness == 1)
1641                     {
1642                         if (flags.fmask)
1643                         {
1644                             UINT_32 fmaskPixelSize = bpp * numSamples;
1645 
1646                             switch (fmaskPixelSize)
1647                             {
1648                                 case 8:
1649                                     index = 14;
1650                                     break;
1651                                 case 16:
1652                                     index = 15;
1653                                     break;
1654                                 case 32:
1655                                     index = 16;
1656                                     break;
1657                                 case 64:
1658                                     index = 17;
1659                                     break;
1660                                 default:
1661                                     ADDR_ASSERT_ALWAYS();
1662                             }
1663                         }
1664                         else
1665                         {
1666                             switch (bpp)
1667                             {
1668                                 case 8:
1669                                     index = 14;
1670                                     break;
1671                                 case 16:
1672                                     index = 15;
1673                                     break;
1674                                 case 32:
1675                                     index = 16;
1676                                     break;
1677                                 case 64:
1678                                     index = 17;
1679                                     break;
1680                                 case 128:
1681                                     index = 17;
1682                                     break;
1683                                 default:
1684                                     break;
1685                             }
1686                         }
1687                     }
1688                     else // thick tiling - entries 18-20
1689                     {
1690                         switch (thickness)
1691                         {
1692                             case 4:
1693                                 index = 20;
1694                                 break;
1695                             case 8:
1696                                 index = 19;
1697                                 break;
1698                             default:
1699                                 break;
1700                         }
1701                     }
1702                 }
1703             }
1704         }
1705         else
1706         {
1707             if (tileMode == ADDR_TM_LINEAR_ALIGNED)
1708             {
1709                 index = 8;
1710             }
1711             else if (tileMode == ADDR_TM_LINEAR_GENERAL)
1712             {
1713                 index = TileIndexLinearGeneral;
1714             }
1715             else
1716             {
1717                 if (flags.depth || flags.stencil)
1718                 {
1719                     index = 4;
1720                 }
1721                 else if (inTileType == ADDR_DISPLAYABLE)
1722                 {
1723                     index = 9;
1724                 }
1725                 else if (thickness == 1)
1726                 {
1727                     index = 13;
1728                 }
1729                 else
1730                 {
1731                     index = 18;
1732                 }
1733             }
1734         }
1735 
1736         if (index >= 0 && index <= 31)
1737         {
1738             *pTileInfo      = m_tileTable[index].info;
1739             pOut->tileType  = m_tileTable[index].type;
1740         }
1741 
1742         if (index == TileIndexLinearGeneral)
1743         {
1744             *pTileInfo      = m_tileTable[8].info;
1745             pOut->tileType  = m_tileTable[8].type;
1746         }
1747     }
1748     else
1749     {
1750         if (pTileInfoIn)
1751         {
1752             if (flags.stencil && pTileInfoIn->tileSplitBytes == 0)
1753             {
1754                 // Stencil always uses index 0
1755                 *pTileInfo = m_tileTable[0].info;
1756             }
1757         }
1758         // Pass through tile type
1759         pOut->tileType = inTileType;
1760     }
1761 
1762     pOut->tileIndex = index;
1763 }
1764 
1765 /**
1766 ***************************************************************************************************
1767 *   SIAddrLib::DecodeGbRegs
1768 *
1769 *   @brief
1770 *       Decodes GB_ADDR_CONFIG and noOfBanks/noOfRanks
1771 *
1772 *   @return
1773 *       TRUE if all settings are valid
1774 *
1775 ***************************************************************************************************
1776 */
DecodeGbRegs(const ADDR_REGISTER_VALUE * pRegValue)1777 BOOL_32 SIAddrLib::DecodeGbRegs(
1778     const ADDR_REGISTER_VALUE* pRegValue) ///< [in] create input
1779 {
1780     GB_ADDR_CONFIG  reg;
1781     BOOL_32         valid = TRUE;
1782 
1783     reg.val = pRegValue->gbAddrConfig;
1784 
1785     switch (reg.f.pipe_interleave_size)
1786     {
1787         case ADDR_CONFIG_PIPE_INTERLEAVE_256B:
1788             m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_256B;
1789             break;
1790         case ADDR_CONFIG_PIPE_INTERLEAVE_512B:
1791             m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_512B;
1792             break;
1793         default:
1794             valid = FALSE;
1795             ADDR_UNHANDLED_CASE();
1796             break;
1797     }
1798 
1799     switch (reg.f.row_size)
1800     {
1801         case ADDR_CONFIG_1KB_ROW:
1802             m_rowSize = ADDR_ROWSIZE_1KB;
1803             break;
1804         case ADDR_CONFIG_2KB_ROW:
1805             m_rowSize = ADDR_ROWSIZE_2KB;
1806             break;
1807         case ADDR_CONFIG_4KB_ROW:
1808             m_rowSize = ADDR_ROWSIZE_4KB;
1809             break;
1810         default:
1811             valid = FALSE;
1812             ADDR_UNHANDLED_CASE();
1813             break;
1814     }
1815 
1816     switch (pRegValue->noOfBanks)
1817     {
1818         case 0:
1819             m_banks = 4;
1820             break;
1821         case 1:
1822             m_banks = 8;
1823             break;
1824         case 2:
1825             m_banks = 16;
1826             break;
1827         default:
1828             valid = FALSE;
1829             ADDR_UNHANDLED_CASE();
1830             break;
1831     }
1832 
1833     switch (pRegValue->noOfRanks)
1834     {
1835         case 0:
1836             m_ranks = 1;
1837             break;
1838         case 1:
1839             m_ranks = 2;
1840             break;
1841         default:
1842             valid = FALSE;
1843             ADDR_UNHANDLED_CASE();
1844             break;
1845     }
1846 
1847     m_logicalBanks = m_banks * m_ranks;
1848 
1849     ADDR_ASSERT(m_logicalBanks <= 16);
1850 
1851     return valid;
1852 }
1853 
1854 /**
1855 ***************************************************************************************************
1856 *   SIAddrLib::HwlInitGlobalParams
1857 *
1858 *   @brief
1859 *       Initializes global parameters
1860 *
1861 *   @return
1862 *       TRUE if all settings are valid
1863 *
1864 ***************************************************************************************************
1865 */
HwlInitGlobalParams(const ADDR_CREATE_INPUT * pCreateIn)1866 BOOL_32 SIAddrLib::HwlInitGlobalParams(
1867     const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input
1868 {
1869     BOOL_32 valid = TRUE;
1870     const ADDR_REGISTER_VALUE* pRegValue = &pCreateIn->regValue;
1871 
1872     valid = DecodeGbRegs(pRegValue);
1873 
1874     if (valid)
1875     {
1876         if (m_settings.isTahiti || m_settings.isPitCairn)
1877         {
1878             m_pipes = 8;
1879         }
1880         else if (m_settings.isCapeVerde || m_settings.isOland)
1881         {
1882             m_pipes = 4;
1883         }
1884         else
1885         {
1886             // Hainan is 2-pipe (m_settings.isHainan == 1)
1887             m_pipes = 2;
1888         }
1889 
1890         valid = InitTileSettingTable(pRegValue->pTileConfig, pRegValue->noOfEntries);
1891 
1892         m_maxSamples = 16;
1893     }
1894 
1895     return valid;
1896 }
1897 
1898 /**
1899 ***************************************************************************************************
1900 *   SIAddrLib::HwlConvertTileInfoToHW
1901 *   @brief
1902 *       Entry of si's ConvertTileInfoToHW
1903 *   @return
1904 *       ADDR_E_RETURNCODE
1905 ***************************************************************************************************
1906 */
HwlConvertTileInfoToHW(const ADDR_CONVERT_TILEINFOTOHW_INPUT * pIn,ADDR_CONVERT_TILEINFOTOHW_OUTPUT * pOut) const1907 ADDR_E_RETURNCODE SIAddrLib::HwlConvertTileInfoToHW(
1908     const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure
1909     ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut      ///< [out] output structure
1910     ) const
1911 {
1912     ADDR_E_RETURNCODE retCode   = ADDR_OK;
1913 
1914     retCode = EgBasedAddrLib::HwlConvertTileInfoToHW(pIn, pOut);
1915 
1916     if (retCode == ADDR_OK)
1917     {
1918         if (pIn->reverse == FALSE)
1919         {
1920             if (pIn->pTileInfo->pipeConfig == ADDR_PIPECFG_INVALID)
1921             {
1922                 retCode = ADDR_INVALIDPARAMS;
1923             }
1924             else
1925             {
1926                 pOut->pTileInfo->pipeConfig =
1927                     static_cast<AddrPipeCfg>(pIn->pTileInfo->pipeConfig - 1);
1928             }
1929         }
1930         else
1931         {
1932             pOut->pTileInfo->pipeConfig =
1933                 static_cast<AddrPipeCfg>(pIn->pTileInfo->pipeConfig + 1);
1934         }
1935     }
1936 
1937     return retCode;
1938 }
1939 
1940 /**
1941 ***************************************************************************************************
1942 *   SIAddrLib::HwlComputeXmaskCoordYFrom8Pipe
1943 *
1944 *   @brief
1945 *       Compute the Y coord which will be added to Xmask Y
1946 *       coord.
1947 *   @return
1948 *       Y coord
1949 ***************************************************************************************************
1950 */
HwlComputeXmaskCoordYFrom8Pipe(UINT_32 pipe,UINT_32 x) const1951 UINT_32 SIAddrLib::HwlComputeXmaskCoordYFrom8Pipe(
1952     UINT_32         pipe,       ///< [in] pipe id
1953     UINT_32         x           ///< [in] tile coord x, which is original x coord / 8
1954     ) const
1955 {
1956     // This function should never be called since it is 6xx/8xx specfic.
1957     // Keep this empty implementation to avoid any mis-use.
1958     ADDR_ASSERT_ALWAYS();
1959 
1960     return 0;
1961 }
1962 
1963 /**
1964 ***************************************************************************************************
1965 *   SIAddrLib::HwlComputeSurfaceCoord2DFromBankPipe
1966 *
1967 *   @brief
1968 *       Compute surface x,y coordinates from bank/pipe info
1969 *   @return
1970 *       N/A
1971 ***************************************************************************************************
1972 */
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) const1973 VOID SIAddrLib::HwlComputeSurfaceCoord2DFromBankPipe(
1974     AddrTileMode        tileMode,   ///< [in] tile mode
1975     UINT_32*            pX,         ///< [in/out] x coordinate
1976     UINT_32*            pY,         ///< [in/out] y coordinate
1977     UINT_32             slice,      ///< [in] slice index
1978     UINT_32             bank,       ///< [in] bank number
1979     UINT_32             pipe,       ///< [in] pipe number
1980     UINT_32             bankSwizzle,///< [in] bank swizzle
1981     UINT_32             pipeSwizzle,///< [in] pipe swizzle
1982     UINT_32             tileSlices, ///< [in] slices in a micro tile
1983     BOOL_32             ignoreSE,   ///< [in] TRUE if shader engines are ignored
1984     ADDR_TILEINFO*      pTileInfo   ///< [in] bank structure. **All fields to be valid on entry**
1985     ) const
1986 {
1987     UINT_32 xBit;
1988     UINT_32 yBit;
1989     UINT_32 yBit3 = 0;
1990     UINT_32 yBit4 = 0;
1991     UINT_32 yBit5 = 0;
1992     UINT_32 yBit6 = 0;
1993 
1994     UINT_32 xBit3 = 0;
1995     UINT_32 xBit4 = 0;
1996     UINT_32 xBit5 = 0;
1997 
1998     UINT_32 numPipes = GetPipePerSurf(pTileInfo->pipeConfig);
1999 
2000     CoordFromBankPipe xyBits = {0};
2001     ComputeSurfaceCoord2DFromBankPipe(tileMode, *pX, *pY, slice, bank, pipe,
2002                                       bankSwizzle, pipeSwizzle, tileSlices, pTileInfo,
2003                                       &xyBits);
2004     yBit3 = xyBits.yBit3;
2005     yBit4 = xyBits.yBit4;
2006     yBit5 = xyBits.yBit5;
2007     yBit6 = xyBits.yBit6;
2008 
2009     xBit3 = xyBits.xBit3;
2010     xBit4 = xyBits.xBit4;
2011     xBit5 = xyBits.xBit5;
2012 
2013     yBit = xyBits.yBits;
2014 
2015     UINT_32 yBitTemp = 0;
2016 
2017     if ((pTileInfo->pipeConfig == ADDR_PIPECFG_P4_32x32) ||
2018         (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32))
2019     {
2020         ADDR_ASSERT(pTileInfo->bankWidth == 1 && pTileInfo->macroAspectRatio > 1);
2021         UINT_32 yBitToCheck = QLog2(pTileInfo->banks) - 1;
2022 
2023         ADDR_ASSERT(yBitToCheck <= 3);
2024 
2025         yBitTemp = _BIT(yBit, yBitToCheck);
2026 
2027         xBit3 = 0;
2028     }
2029 
2030     yBit = Bits2Number(4, yBit6, yBit5, yBit4, yBit3);
2031     xBit = Bits2Number(3, xBit5, xBit4, xBit3);
2032 
2033     *pY += yBit * pTileInfo->bankHeight * MicroTileHeight;
2034     *pX += xBit * numPipes * pTileInfo->bankWidth * MicroTileWidth;
2035 
2036     //calculate the bank and pipe bits in x, y
2037     UINT_32 xTile; //x in micro tile
2038     UINT_32 x3 = 0;
2039     UINT_32 x4 = 0;
2040     UINT_32 x5 = 0;
2041     UINT_32 x6 = 0;
2042     UINT_32 y = *pY;
2043 
2044     UINT_32 pipeBit0 = _BIT(pipe,0);
2045     UINT_32 pipeBit1 = _BIT(pipe,1);
2046     UINT_32 pipeBit2 = _BIT(pipe,2);
2047 
2048     UINT_32 y3 = _BIT(y, 3);
2049     UINT_32 y4 = _BIT(y, 4);
2050     UINT_32 y5 = _BIT(y, 5);
2051     UINT_32 y6 = _BIT(y, 6);
2052 
2053     // bankbit0 after ^x4^x5
2054     UINT_32 bankBit00 = _BIT(bank,0);
2055     UINT_32 bankBit0 = 0;
2056 
2057     switch (pTileInfo->pipeConfig)
2058     {
2059         case ADDR_PIPECFG_P2:
2060             x3 = pipeBit0 ^ y3;
2061             break;
2062         case ADDR_PIPECFG_P4_8x16:
2063             x4 = pipeBit0 ^ y3;
2064             x3 = pipeBit0 ^ y4;
2065             break;
2066         case ADDR_PIPECFG_P4_16x16:
2067             x4 = pipeBit1 ^ y4;
2068             x3 = pipeBit0 ^ y3 ^ x4;
2069             break;
2070         case ADDR_PIPECFG_P4_16x32:
2071             x4 = pipeBit1 ^ y4;
2072             x3 = pipeBit0 ^ y3 ^ x4;
2073             break;
2074         case ADDR_PIPECFG_P4_32x32:
2075             x5 = pipeBit1 ^ y5;
2076             x3 = pipeBit0 ^ y3 ^ x5;
2077             bankBit0 = yBitTemp ^ x5;
2078             x4 = bankBit00 ^ x5 ^ bankBit0;
2079             *pX += x5 * 4 * 1 * 8; // x5 * num_pipes * bank_width * 8;
2080             break;
2081         case ADDR_PIPECFG_P8_16x16_8x16:
2082             x3 = pipeBit1 ^ y5;
2083             x4 = pipeBit2 ^ y4;
2084             x5 = pipeBit0 ^ y3 ^ x4;
2085             break;
2086         case ADDR_PIPECFG_P8_16x32_8x16:
2087             x3 = pipeBit1 ^ y4;
2088             x4 = pipeBit2 ^ y5;
2089             x5 = pipeBit0 ^ y3 ^ x4;
2090             break;
2091         case ADDR_PIPECFG_P8_32x32_8x16:
2092             x3 = pipeBit1 ^ y4;
2093             x5 = pipeBit2 ^ y5;
2094             x4 = pipeBit0 ^ y3 ^ x5;
2095             break;
2096         case ADDR_PIPECFG_P8_16x32_16x16:
2097             x4 = pipeBit2 ^ y5;
2098             x5 = pipeBit1 ^ y4;
2099             x3 = pipeBit0 ^ y3 ^ x4;
2100             break;
2101         case ADDR_PIPECFG_P8_32x32_16x16:
2102             x5 = pipeBit2 ^ y5;
2103             x4 = pipeBit1 ^ y4;
2104             x3 = pipeBit0 ^ y3 ^ x4;
2105             break;
2106         case ADDR_PIPECFG_P8_32x32_16x32:
2107             x5 = pipeBit2 ^ y5;
2108             x4 = pipeBit1 ^ y6;
2109             x3 = pipeBit0 ^ y3 ^ x4;
2110             break;
2111         case ADDR_PIPECFG_P8_32x64_32x32:
2112             x6 = pipeBit1 ^ y5;
2113             x5 = pipeBit2 ^ y6;
2114             x3 = pipeBit0 ^ y3 ^ x5;
2115             bankBit0 = yBitTemp ^ x6;
2116             x4 = bankBit00 ^ x5 ^ bankBit0;
2117             *pX += x6 * 8 * 1 * 8; // x6 * num_pipes * bank_width * 8;
2118             break;
2119         default:
2120             ADDR_ASSERT_ALWAYS();
2121     }
2122 
2123     xTile = Bits2Number(3, x5, x4, x3);
2124 
2125     *pX += xTile << 3;
2126 }
2127 
2128 /**
2129 ***************************************************************************************************
2130 *   SIAddrLib::HwlPreAdjustBank
2131 *
2132 *   @brief
2133 *       Adjust bank before calculating address acoording to bank/pipe
2134 *   @return
2135 *       Adjusted bank
2136 ***************************************************************************************************
2137 */
HwlPreAdjustBank(UINT_32 tileX,UINT_32 bank,ADDR_TILEINFO * pTileInfo) const2138 UINT_32 SIAddrLib::HwlPreAdjustBank(
2139     UINT_32         tileX,      ///< [in] x coordinate in unit of tile
2140     UINT_32         bank,       ///< [in] bank
2141     ADDR_TILEINFO*  pTileInfo   ///< [in] tile info
2142     ) const
2143 {
2144     if (((pTileInfo->pipeConfig == ADDR_PIPECFG_P4_32x32) ||
2145         (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32)) && (pTileInfo->bankWidth == 1))
2146     {
2147         UINT_32 bankBit0 = _BIT(bank, 0);
2148         UINT_32 x4 = _BIT(tileX, 1);
2149         UINT_32 x5 = _BIT(tileX, 2);
2150 
2151         bankBit0 = bankBit0 ^ x4 ^ x5;
2152         bank |= bankBit0;
2153 
2154         ADDR_ASSERT(pTileInfo->macroAspectRatio > 1)
2155     }
2156 
2157     return bank;
2158 }
2159 
2160 /**
2161 ***************************************************************************************************
2162 *   SIAddrLib::HwlComputeSurfaceInfo
2163 *
2164 *   @brief
2165 *       Entry of si's ComputeSurfaceInfo
2166 *   @return
2167 *       ADDR_E_RETURNCODE
2168 ***************************************************************************************************
2169 */
HwlComputeSurfaceInfo(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2170 ADDR_E_RETURNCODE SIAddrLib::HwlComputeSurfaceInfo(
2171     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,    ///< [in] input structure
2172     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [out] output structure
2173     ) const
2174 {
2175     pOut->tileIndex = pIn->tileIndex;
2176 
2177     return EgBasedAddrLib::HwlComputeSurfaceInfo(pIn,pOut);
2178 }
2179 
2180 /**
2181 ***************************************************************************************************
2182 *   SIAddrLib::HwlComputeMipLevel
2183 *   @brief
2184 *       Compute MipLevel info (including level 0)
2185 *   @return
2186 *       TRUE if HWL's handled
2187 ***************************************************************************************************
2188 */
HwlComputeMipLevel(ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn) const2189 BOOL_32 SIAddrLib::HwlComputeMipLevel(
2190     ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in/out] Input structure
2191     ) const
2192 {
2193     // basePitch is calculated from level 0 so we only check this for mipLevel > 0
2194     if (pIn->mipLevel > 0)
2195     {
2196         // Note: Don't check expand 3x formats(96 bit) as the basePitch is not pow2 even if
2197         // we explicity set pow2Pad flag. The 3x base pitch is padded to pow2 but after being
2198         // divided by expandX factor (3) - to program texture pitch, the basePitch is never pow2.
2199         if (!AddrElemLib::IsExpand3x(pIn->format))
2200         {
2201             // Sublevel pitches are generated from base level pitch instead of width on SI
2202             // If pow2Pad is 0, we don't assert - as this is not really used for a mip chain
2203             ADDR_ASSERT(!pIn->flags.pow2Pad || ((pIn->basePitch != 0) && IsPow2(pIn->basePitch)));
2204         }
2205 
2206         if (pIn->basePitch != 0)
2207         {
2208             pIn->width = Max(1u, pIn->basePitch >> pIn->mipLevel);
2209         }
2210     }
2211 
2212     // pow2Pad is done in PostComputeMipLevel
2213 
2214     return TRUE;
2215 }
2216 
2217 /**
2218 ***************************************************************************************************
2219 *   SIAddrLib::HwlCheckLastMacroTiledLvl
2220 *
2221 *   @brief
2222 *       Sets pOut->last2DLevel to TRUE if it is
2223 *   @note
2224 *
2225 ***************************************************************************************************
2226 */
HwlCheckLastMacroTiledLvl(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2227 VOID SIAddrLib::HwlCheckLastMacroTiledLvl(
2228     const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure
2229     ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut      ///< [in/out] Output structure (used as input, too)
2230     ) const
2231 {
2232     // pow2Pad covers all mipmap cases
2233     if (pIn->flags.pow2Pad)
2234     {
2235         ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
2236 
2237         UINT_32 nextPitch;
2238         UINT_32 nextHeight;
2239         UINT_32 nextSlices;
2240 
2241         AddrTileMode nextTileMode;
2242 
2243         if (pIn->mipLevel == 0 || pIn->basePitch == 0)
2244         {
2245             // Base level or fail-safe case (basePitch == 0)
2246             nextPitch = pOut->pitch >> 1;
2247         }
2248         else
2249         {
2250             // Sub levels
2251             nextPitch = pIn->basePitch >> (pIn->mipLevel + 1);
2252         }
2253 
2254         // nextHeight must be shifted from this level's original height rather than a pow2 padded
2255         // one but this requires original height stored somewhere (pOut->height)
2256         ADDR_ASSERT(pOut->height != 0);
2257 
2258         // next level's height is just current level's >> 1 in pixels
2259         nextHeight = pOut->height >> 1;
2260         // Special format such as FMT_1 and FMT_32_32_32 can be linear only so we consider block
2261         // compressed foramts
2262         if (AddrElemLib::IsBlockCompressed(pIn->format))
2263         {
2264             nextHeight = (nextHeight + 3) / 4;
2265         }
2266         nextHeight = NextPow2(nextHeight);
2267 
2268         // nextSlices may be 0 if this level's is 1
2269         if (pIn->flags.volume)
2270         {
2271             nextSlices = Max(1u, pIn->numSlices >> 1);
2272         }
2273         else
2274         {
2275             nextSlices = pIn->numSlices;
2276         }
2277 
2278         nextTileMode = ComputeSurfaceMipLevelTileMode(pIn->tileMode,
2279                                                       pIn->bpp,
2280                                                       nextPitch,
2281                                                       nextHeight,
2282                                                       nextSlices,
2283                                                       pIn->numSamples,
2284                                                       pOut->pitchAlign,
2285                                                       pOut->heightAlign,
2286                                                       pOut->pTileInfo);
2287 
2288         pOut->last2DLevel = IsMicroTiled(nextTileMode);
2289     }
2290 }
2291 
2292 /**
2293 ***************************************************************************************************
2294 *   SIAddrLib::HwlDegradeThickTileMode
2295 *
2296 *   @brief
2297 *       Degrades valid tile mode for thick modes if needed
2298 *
2299 *   @return
2300 *       Suitable tile mode
2301 ***************************************************************************************************
2302 */
HwlDegradeThickTileMode(AddrTileMode baseTileMode,UINT_32 numSlices,UINT_32 * pBytesPerTile) const2303 AddrTileMode SIAddrLib::HwlDegradeThickTileMode(
2304     AddrTileMode        baseTileMode,   ///< [in] base tile mode
2305     UINT_32             numSlices,      ///< [in] current number of slices
2306     UINT_32*            pBytesPerTile   ///< [in/out] pointer to bytes per slice
2307     ) const
2308 {
2309     return EgBasedAddrLib::HwlDegradeThickTileMode(baseTileMode, numSlices, pBytesPerTile);
2310 }
2311 
2312 /**
2313 ***************************************************************************************************
2314 *   SIAddrLib::HwlTileInfoEqual
2315 *
2316 *   @brief
2317 *       Return TRUE if all field are equal
2318 *   @note
2319 *       Only takes care of current HWL's data
2320 ***************************************************************************************************
2321 */
HwlTileInfoEqual(const ADDR_TILEINFO * pLeft,const ADDR_TILEINFO * pRight) const2322 BOOL_32 SIAddrLib::HwlTileInfoEqual(
2323     const ADDR_TILEINFO* pLeft, ///<[in] Left compare operand
2324     const ADDR_TILEINFO* pRight ///<[in] Right compare operand
2325     ) const
2326 {
2327     BOOL_32 equal = FALSE;
2328 
2329     if (pLeft->pipeConfig == pRight->pipeConfig)
2330     {
2331         equal =  EgBasedAddrLib::HwlTileInfoEqual(pLeft, pRight);
2332     }
2333 
2334     return equal;
2335 }
2336 
2337 /**
2338 ***************************************************************************************************
2339 *   SIAddrLib::GetTileSettings
2340 *
2341 *   @brief
2342 *       Get tile setting infos by index.
2343 *   @return
2344 *       Tile setting info.
2345 ***************************************************************************************************
2346 */
GetTileSetting(UINT_32 index) const2347 const ADDR_TILECONFIG* SIAddrLib::GetTileSetting(
2348     UINT_32 index          ///< [in] Tile index
2349     ) const
2350 {
2351     ADDR_ASSERT(index < m_noOfEntries);
2352     return &m_tileTable[index];
2353 }
2354 
2355 /**
2356 ***************************************************************************************************
2357 *   SIAddrLib::HwlPostCheckTileIndex
2358 *
2359 *   @brief
2360 *       Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches
2361 *       tile mode/type/info and change the index if needed
2362 *   @return
2363 *       Tile index.
2364 ***************************************************************************************************
2365 */
HwlPostCheckTileIndex(const ADDR_TILEINFO * pInfo,AddrTileMode mode,AddrTileType type,INT curIndex) const2366 INT_32 SIAddrLib::HwlPostCheckTileIndex(
2367     const ADDR_TILEINFO* pInfo,     ///< [in] Tile Info
2368     AddrTileMode         mode,      ///< [in] Tile mode
2369     AddrTileType         type,      ///< [in] Tile type
2370     INT                  curIndex   ///< [in] Current index assigned in HwlSetupTileInfo
2371     ) const
2372 {
2373     INT_32 index = curIndex;
2374 
2375     if (mode == ADDR_TM_LINEAR_GENERAL)
2376     {
2377         index = TileIndexLinearGeneral;
2378     }
2379     else
2380     {
2381         BOOL_32 macroTiled = IsMacroTiled(mode);
2382 
2383         // We need to find a new index if either of them is true
2384         // 1. curIndex is invalid
2385         // 2. tile mode is changed
2386         // 3. tile info does not match for macro tiled
2387         if ((index == TileIndexInvalid         ||
2388             (mode != m_tileTable[index].mode)  ||
2389             (macroTiled && !HwlTileInfoEqual(pInfo, &m_tileTable[index].info))))
2390         {
2391             for (index = 0; index < static_cast<INT_32>(m_noOfEntries); index++)
2392             {
2393                 if (macroTiled)
2394                 {
2395                     // macro tile modes need all to match
2396                     if (HwlTileInfoEqual(pInfo, &m_tileTable[index].info) &&
2397                         (mode == m_tileTable[index].mode)                 &&
2398                         (type == m_tileTable[index].type))
2399                     {
2400                         break;
2401                     }
2402                 }
2403                 else if (mode == ADDR_TM_LINEAR_ALIGNED)
2404                 {
2405                     // linear mode only needs tile mode to match
2406                     if (mode == m_tileTable[index].mode)
2407                     {
2408                         break;
2409                     }
2410                 }
2411                 else
2412                 {
2413                     // micro tile modes only need tile mode and tile type to match
2414                     if (mode == m_tileTable[index].mode &&
2415                         type == m_tileTable[index].type)
2416                     {
2417                         break;
2418                     }
2419                 }
2420             }
2421         }
2422     }
2423 
2424     ADDR_ASSERT(index < static_cast<INT_32>(m_noOfEntries));
2425 
2426     if (index >= static_cast<INT_32>(m_noOfEntries))
2427     {
2428         index = TileIndexInvalid;
2429     }
2430 
2431     return index;
2432 }
2433 
2434 /**
2435 ***************************************************************************************************
2436 *   SIAddrLib::HwlSetupTileCfg
2437 *
2438 *   @brief
2439 *       Map tile index to tile setting.
2440 *   @return
2441 *       ADDR_E_RETURNCODE
2442 ***************************************************************************************************
2443 */
HwlSetupTileCfg(INT_32 index,INT_32 macroModeIndex,ADDR_TILEINFO * pInfo,AddrTileMode * pMode,AddrTileType * pType) const2444 ADDR_E_RETURNCODE SIAddrLib::HwlSetupTileCfg(
2445     INT_32          index,          ///< [in] Tile index
2446     INT_32          macroModeIndex, ///< [in] Index in macro tile mode table(CI)
2447     ADDR_TILEINFO*  pInfo,          ///< [out] Tile Info
2448     AddrTileMode*   pMode,          ///< [out] Tile mode
2449     AddrTileType*   pType          ///< [out] Tile type
2450     ) const
2451 {
2452     ADDR_E_RETURNCODE returnCode = ADDR_OK;
2453 
2454     // Global flag to control usage of tileIndex
2455     if (UseTileIndex(index))
2456     {
2457         if (index == TileIndexLinearGeneral)
2458         {
2459             if (pMode)
2460             {
2461                 *pMode = ADDR_TM_LINEAR_GENERAL;
2462             }
2463 
2464             if (pType)
2465             {
2466                 *pType = ADDR_DISPLAYABLE;
2467             }
2468 
2469             if (pInfo)
2470             {
2471                 pInfo->banks = 2;
2472                 pInfo->bankWidth = 1;
2473                 pInfo->bankHeight = 1;
2474                 pInfo->macroAspectRatio = 1;
2475                 pInfo->tileSplitBytes = 64;
2476                 pInfo->pipeConfig = ADDR_PIPECFG_P2;
2477             }
2478         }
2479         else if (static_cast<UINT_32>(index) >= m_noOfEntries)
2480         {
2481             returnCode = ADDR_INVALIDPARAMS;
2482         }
2483         else
2484         {
2485             const ADDR_TILECONFIG* pCfgTable = GetTileSetting(index);
2486 
2487             if (pInfo)
2488             {
2489                 *pInfo = pCfgTable->info;
2490             }
2491             else
2492             {
2493                 if (IsMacroTiled(pCfgTable->mode))
2494                 {
2495                     returnCode = ADDR_INVALIDPARAMS;
2496                 }
2497             }
2498 
2499             if (pMode)
2500             {
2501                 *pMode = pCfgTable->mode;
2502             }
2503 
2504             if (pType)
2505             {
2506                 *pType = pCfgTable->type;
2507             }
2508         }
2509     }
2510 
2511     return returnCode;
2512 }
2513 
2514 /**
2515 ***************************************************************************************************
2516 *   SIAddrLib::ReadGbTileMode
2517 *
2518 *   @brief
2519 *       Convert GB_TILE_MODE HW value to ADDR_TILE_CONFIG.
2520 *   @return
2521 *       NA.
2522 ***************************************************************************************************
2523 */
ReadGbTileMode(UINT_32 regValue,ADDR_TILECONFIG * pCfg) const2524 VOID SIAddrLib::ReadGbTileMode(
2525     UINT_32             regValue,   ///< [in] GB_TILE_MODE register
2526     ADDR_TILECONFIG*    pCfg        ///< [out] output structure
2527     ) const
2528 {
2529     GB_TILE_MODE gbTileMode;
2530     gbTileMode.val = regValue;
2531 
2532     pCfg->type = static_cast<AddrTileType>(gbTileMode.f.micro_tile_mode);
2533     pCfg->info.bankHeight = 1 << gbTileMode.f.bank_height;
2534     pCfg->info.bankWidth = 1 << gbTileMode.f.bank_width;
2535     pCfg->info.banks = 1 << (gbTileMode.f.num_banks + 1);
2536     pCfg->info.macroAspectRatio = 1 << gbTileMode.f.macro_tile_aspect;
2537     pCfg->info.tileSplitBytes = 64 << gbTileMode.f.tile_split;
2538     pCfg->info.pipeConfig = static_cast<AddrPipeCfg>(gbTileMode.f.pipe_config + 1);
2539 
2540     UINT_32 regArrayMode = gbTileMode.f.array_mode;
2541 
2542     pCfg->mode = static_cast<AddrTileMode>(regArrayMode);
2543 
2544     if (regArrayMode == 8) //ARRAY_2D_TILED_XTHICK
2545     {
2546         pCfg->mode = ADDR_TM_2D_TILED_XTHICK;
2547     }
2548     else if (regArrayMode >= 14) //ARRAY_3D_TILED_XTHICK
2549     {
2550         pCfg->mode = static_cast<AddrTileMode>(pCfg->mode + 3);
2551     }
2552 }
2553 
2554 /**
2555 ***************************************************************************************************
2556 *   SIAddrLib::InitTileSettingTable
2557 *
2558 *   @brief
2559 *       Initialize the ADDR_TILE_CONFIG table.
2560 *   @return
2561 *       TRUE if tile table is correctly initialized
2562 ***************************************************************************************************
2563 */
InitTileSettingTable(const UINT_32 * pCfg,UINT_32 noOfEntries)2564 BOOL_32 SIAddrLib::InitTileSettingTable(
2565     const UINT_32*  pCfg,           ///< [in] Pointer to table of tile configs
2566     UINT_32         noOfEntries     ///< [in] Numbe of entries in the table above
2567     )
2568 {
2569     BOOL_32 initOk = TRUE;
2570 
2571     ADDR_ASSERT(noOfEntries <= TileTableSize);
2572 
2573     memset(m_tileTable, 0, sizeof(m_tileTable));
2574 
2575     if (noOfEntries != 0)
2576     {
2577         m_noOfEntries = noOfEntries;
2578     }
2579     else
2580     {
2581         m_noOfEntries = TileTableSize;
2582     }
2583 
2584     if (pCfg) // From Client
2585     {
2586         for (UINT_32 i = 0; i < m_noOfEntries; i++)
2587         {
2588             ReadGbTileMode(*(pCfg + i), &m_tileTable[i]);
2589         }
2590     }
2591     else
2592     {
2593         ADDR_ASSERT_ALWAYS();
2594         initOk = FALSE;
2595     }
2596 
2597     if (initOk)
2598     {
2599         ADDR_ASSERT(m_tileTable[TILEINDEX_LINEAR_ALIGNED].mode == ADDR_TM_LINEAR_ALIGNED);
2600     }
2601 
2602     return initOk;
2603 }
2604 
2605 /**
2606 ***************************************************************************************************
2607 *   SIAddrLib::HwlGetTileIndex
2608 *
2609 *   @brief
2610 *       Return the virtual/real index for given mode/type/info
2611 *   @return
2612 *       ADDR_OK if successful.
2613 ***************************************************************************************************
2614 */
HwlGetTileIndex(const ADDR_GET_TILEINDEX_INPUT * pIn,ADDR_GET_TILEINDEX_OUTPUT * pOut) const2615 ADDR_E_RETURNCODE SIAddrLib::HwlGetTileIndex(
2616     const ADDR_GET_TILEINDEX_INPUT* pIn,
2617     ADDR_GET_TILEINDEX_OUTPUT*      pOut) const
2618 {
2619     ADDR_E_RETURNCODE returnCode = ADDR_OK;
2620 
2621     pOut->index = HwlPostCheckTileIndex(pIn->pTileInfo, pIn->tileMode, pIn->tileType);
2622 
2623     return returnCode;
2624 }
2625 
2626 /**
2627 ***************************************************************************************************
2628 *   SIAddrLib::HwlFmaskPreThunkSurfInfo
2629 *
2630 *   @brief
2631 *       Some preparation before thunking a ComputeSurfaceInfo call for Fmask
2632 *   @return
2633 *       ADDR_E_RETURNCODE
2634 ***************************************************************************************************
2635 */
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) const2636 VOID SIAddrLib::HwlFmaskPreThunkSurfInfo(
2637     const ADDR_COMPUTE_FMASK_INFO_INPUT*    pFmaskIn,   ///< [in] Input of fmask info
2638     const ADDR_COMPUTE_FMASK_INFO_OUTPUT*   pFmaskOut,  ///< [in] Output of fmask info
2639     ADDR_COMPUTE_SURFACE_INFO_INPUT*        pSurfIn,    ///< [out] Input of thunked surface info
2640     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pSurfOut    ///< [out] Output of thunked surface info
2641     ) const
2642 {
2643     pSurfIn->tileIndex = pFmaskIn->tileIndex;
2644 }
2645 
2646 /**
2647 ***************************************************************************************************
2648 *   SIAddrLib::HwlFmaskPostThunkSurfInfo
2649 *
2650 *   @brief
2651 *       Copy hwl extra field after calling thunked ComputeSurfaceInfo
2652 *   @return
2653 *       ADDR_E_RETURNCODE
2654 ***************************************************************************************************
2655 */
HwlFmaskPostThunkSurfInfo(const ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pSurfOut,ADDR_COMPUTE_FMASK_INFO_OUTPUT * pFmaskOut) const2656 VOID SIAddrLib::HwlFmaskPostThunkSurfInfo(
2657     const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut,   ///< [in] Output of surface info
2658     ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut           ///< [out] Output of fmask info
2659     ) const
2660 {
2661     pFmaskOut->macroModeIndex = TileIndexInvalid;
2662     pFmaskOut->tileIndex = pSurfOut->tileIndex;
2663 }
2664 
2665 /**
2666 ***************************************************************************************************
2667 *   SIAddrLib::HwlComputeFmaskBits
2668 *   @brief
2669 *       Computes fmask bits
2670 *   @return
2671 *       Fmask bits
2672 ***************************************************************************************************
2673 */
HwlComputeFmaskBits(const ADDR_COMPUTE_FMASK_INFO_INPUT * pIn,UINT_32 * pNumSamples) const2674 UINT_32 SIAddrLib::HwlComputeFmaskBits(
2675     const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn,
2676     UINT_32* pNumSamples
2677     ) const
2678 {
2679     UINT_32 numSamples = pIn->numSamples;
2680     UINT_32 numFrags = GetNumFragments(numSamples, pIn->numFrags);
2681     UINT_32 bpp;
2682 
2683     if (numFrags != numSamples) // EQAA
2684     {
2685         ADDR_ASSERT(numFrags <= 8);
2686 
2687         if (!pIn->resolved)
2688         {
2689             if (numFrags == 1)
2690             {
2691                 bpp          = 1;
2692                 numSamples   = numSamples == 16 ? 16 : 8;
2693             }
2694             else if (numFrags == 2)
2695             {
2696                 ADDR_ASSERT(numSamples >= 4);
2697 
2698                 bpp          = 2;
2699                 numSamples   = numSamples;
2700             }
2701             else if (numFrags == 4)
2702             {
2703                 ADDR_ASSERT(numSamples >= 4);
2704 
2705                 bpp          = 4;
2706                 numSamples   = numSamples;
2707             }
2708             else // numFrags == 8
2709             {
2710                 ADDR_ASSERT(numSamples == 16);
2711 
2712                 bpp          = 4;
2713                 numSamples   = numSamples;
2714             }
2715         }
2716         else
2717         {
2718             if (numFrags == 1)
2719             {
2720                 bpp          = (numSamples == 16) ? 16 : 8;
2721                 numSamples   = 1;
2722             }
2723             else if (numFrags == 2)
2724             {
2725                 ADDR_ASSERT(numSamples >= 4);
2726 
2727                 bpp          = numSamples*2;
2728                 numSamples   = 1;
2729             }
2730             else if (numFrags == 4)
2731             {
2732                 ADDR_ASSERT(numSamples >= 4);
2733 
2734                 bpp          = numSamples*4;
2735                 numSamples   = 1;
2736             }
2737             else // numFrags == 8
2738             {
2739                 ADDR_ASSERT(numSamples >= 16);
2740 
2741                 bpp          = 16*4;
2742                 numSamples   = 1;
2743             }
2744         }
2745     }
2746     else // Normal AA
2747     {
2748         if (!pIn->resolved)
2749         {
2750             bpp          = ComputeFmaskNumPlanesFromNumSamples(numSamples);
2751             numSamples   = numSamples == 2 ? 8 : numSamples;
2752         }
2753         else
2754         {
2755             // The same as 8XX
2756             bpp          = ComputeFmaskResolvedBppFromNumSamples(numSamples);
2757             numSamples   = 1; // 1x sample
2758         }
2759     }
2760 
2761     SafeAssign(pNumSamples, numSamples);
2762 
2763     return bpp;
2764 }
2765 
2766 /**
2767 ***************************************************************************************************
2768 *   SIAddrLib::HwlOverrideTileMode
2769 *
2770 *   @brief
2771 *       Override tile modes (for PRT only, avoid client passes in an invalid PRT mode for SI.
2772 *
2773 *   @return
2774 *       Suitable tile mode
2775 *
2776 ***************************************************************************************************
2777 */
HwlOverrideTileMode(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,AddrTileMode * pTileMode,AddrTileType * pTileType) const2778 BOOL_32 SIAddrLib::HwlOverrideTileMode(
2779     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,       ///< [in] input structure
2780     AddrTileMode*                           pTileMode, ///< [in/out] pointer to the tile mode
2781     AddrTileType*                           pTileType  ///< [in/out] pointer to the tile type
2782     ) const
2783 {
2784     BOOL_32 bOverrided = FALSE;
2785     AddrTileMode tileMode = *pTileMode;
2786 
2787     switch (tileMode)
2788     {
2789         case ADDR_TM_PRT_TILED_THIN1:
2790             tileMode    = ADDR_TM_2D_TILED_THIN1;
2791             break;
2792 
2793         case ADDR_TM_PRT_TILED_THICK:
2794             tileMode    = ADDR_TM_2D_TILED_THICK;
2795             break;
2796 
2797         case ADDR_TM_PRT_2D_TILED_THICK:
2798             tileMode    = ADDR_TM_2D_TILED_THICK;
2799             break;
2800 
2801         case ADDR_TM_PRT_3D_TILED_THICK:
2802             tileMode    = ADDR_TM_3D_TILED_THICK;
2803             break;
2804 
2805         default:
2806             break;
2807     }
2808 
2809     if (tileMode != *pTileMode)
2810     {
2811         *pTileMode = tileMode;
2812         bOverrided = TRUE;
2813         ADDR_ASSERT(pIn->flags.prt == TRUE);
2814     }
2815 
2816     return bOverrided;
2817 }
2818 
2819