• 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  addrlib.cpp
30 * @brief Contains the implementation for the AddrLib base class..
31 ***************************************************************************************************
32 */
33 
34 #include "addrinterface.h"
35 #include "addrlib.h"
36 #include "addrcommon.h"
37 
38 #if defined(__APPLE__)
39 
div64_32(UINT_64 n,UINT_32 base)40 UINT_32 div64_32(UINT_64 n, UINT_32 base)
41 {
42     UINT_64 rem = n;
43     UINT_64 b = base;
44     UINT_64 res, d = 1;
45     UINT_32 high = rem >> 32;
46 
47     res = 0;
48     if (high >= base)
49     {
50         high /= base;
51         res = (UINT_64) high << 32;
52         rem -= (UINT_64) (high*base) << 32;
53     }
54 
55     while ((INT_64)b > 0 && b < rem)
56     {
57         b = b+b;
58         d = d+d;
59     }
60 
61     do
62     {
63         if (rem >= b)
64         {
65             rem -= b;
66             res += d;
67         }
68         b >>= 1;
69         d >>= 1;
70     } while (d);
71 
72     n = res;
73     return rem;
74 }
75 
76 extern "C"
__umoddi3(UINT_64 n,UINT_32 base)77 UINT_32 __umoddi3(UINT_64 n, UINT_32 base)
78 {
79     return div64_32(n, base);
80 }
81 
82 #endif // __APPLE__
83 
84 ///////////////////////////////////////////////////////////////////////////////////////////////////
85 //                               Static Const Member
86 ///////////////////////////////////////////////////////////////////////////////////////////////////
87 
88 const AddrTileModeFlags AddrLib::m_modeFlags[ADDR_TM_COUNT] =
89 {// T   L  1  2  3  P  Pr B
90     {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_GENERAL
91     {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_ALIGNED
92     {1, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THIN1
93     {4, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THICK
94     {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN1
95     {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN2
96     {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN4
97     {4, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THICK
98     {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN1
99     {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN2
100     {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN4
101     {4, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THICK
102     {1, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THIN1
103     {4, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THICK
104     {1, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THIN1
105     {4, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THICK
106     {8, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_XTHICK
107     {8, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_XTHICK
108     {1, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_POWER_SAVE
109     {1, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THIN1
110     {1, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THIN1
111     {1, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THIN1
112     {4, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THICK
113     {4, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THICK
114     {4, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THICK
115 };
116 
117 ///////////////////////////////////////////////////////////////////////////////////////////////////
118 //                               Constructor/Destructor
119 ///////////////////////////////////////////////////////////////////////////////////////////////////
120 
121 /**
122 ***************************************************************************************************
123 *   AddrLib::AddrLib
124 *
125 *   @brief
126 *       Constructor for the AddrLib class
127 *
128 ***************************************************************************************************
129 */
AddrLib()130 AddrLib::AddrLib() :
131     m_class(BASE_ADDRLIB),
132     m_chipFamily(ADDR_CHIP_FAMILY_IVLD),
133     m_chipRevision(0),
134     m_version(ADDRLIB_VERSION),
135     m_pipes(0),
136     m_banks(0),
137     m_pipeInterleaveBytes(0),
138     m_rowSize(0),
139     m_minPitchAlignPixels(1),
140     m_maxSamples(8),
141     m_pElemLib(NULL)
142 {
143     m_configFlags.value = 0;
144 }
145 
146 /**
147 ***************************************************************************************************
148 *   AddrLib::AddrLib
149 *
150 *   @brief
151 *       Constructor for the AddrLib class with hClient as parameter
152 *
153 ***************************************************************************************************
154 */
AddrLib(const AddrClient * pClient)155 AddrLib::AddrLib(const AddrClient* pClient) :
156     AddrObject(pClient),
157     m_class(BASE_ADDRLIB),
158     m_chipFamily(ADDR_CHIP_FAMILY_IVLD),
159     m_chipRevision(0),
160     m_version(ADDRLIB_VERSION),
161     m_pipes(0),
162     m_banks(0),
163     m_pipeInterleaveBytes(0),
164     m_rowSize(0),
165     m_minPitchAlignPixels(1),
166     m_maxSamples(8),
167     m_pElemLib(NULL)
168 {
169     m_configFlags.value = 0;
170 }
171 
172 /**
173 ***************************************************************************************************
174 *   AddrLib::~AddrLib
175 *
176 *   @brief
177 *       Destructor for the AddrLib class
178 *
179 ***************************************************************************************************
180 */
~AddrLib()181 AddrLib::~AddrLib()
182 {
183     if (m_pElemLib)
184     {
185         delete m_pElemLib;
186     }
187 }
188 
189 
190 
191 ///////////////////////////////////////////////////////////////////////////////////////////////////
192 //                               Initialization/Helper
193 ///////////////////////////////////////////////////////////////////////////////////////////////////
194 
195 /**
196 ***************************************************************************************************
197 *   AddrLib::Create
198 *
199 *   @brief
200 *       Creates and initializes AddrLib object.
201 *
202 *   @return
203 *       ADDR_E_RETURNCODE
204 ***************************************************************************************************
205 */
Create(const ADDR_CREATE_INPUT * pCreateIn,ADDR_CREATE_OUTPUT * pCreateOut)206 ADDR_E_RETURNCODE AddrLib::Create(
207     const ADDR_CREATE_INPUT* pCreateIn,     ///< [in] pointer to ADDR_CREATE_INPUT
208     ADDR_CREATE_OUTPUT*      pCreateOut)    ///< [out] pointer to ADDR_CREATE_OUTPUT
209 {
210     AddrLib* pLib = NULL;
211     ADDR_E_RETURNCODE returnCode = ADDR_OK;
212 
213     if (pCreateIn->createFlags.fillSizeFields == TRUE)
214     {
215         if ((pCreateIn->size != sizeof(ADDR_CREATE_INPUT)) ||
216             (pCreateOut->size != sizeof(ADDR_CREATE_OUTPUT)))
217         {
218             returnCode = ADDR_PARAMSIZEMISMATCH;
219         }
220     }
221 
222     if ((returnCode == ADDR_OK)                    &&
223         (pCreateIn->callbacks.allocSysMem != NULL) &&
224         (pCreateIn->callbacks.freeSysMem != NULL))
225     {
226         AddrClient client = {
227             pCreateIn->hClient,
228             pCreateIn->callbacks
229         };
230 
231         switch (pCreateIn->chipEngine)
232         {
233             case CIASICIDGFXENGINE_SOUTHERNISLAND:
234                 switch (pCreateIn->chipFamily)
235                 {
236                     case FAMILY_SI:
237                         pLib = AddrSIHwlInit(&client);
238                         break;
239                     case FAMILY_VI:
240                     case FAMILY_CZ: // VI based fusion(carrizo)
241                     case FAMILY_CI:
242                     case FAMILY_KV: // CI based fusion
243                         pLib = AddrCIHwlInit(&client);
244                         break;
245                     default:
246                         ADDR_ASSERT_ALWAYS();
247                         break;
248                 }
249                 break;
250             default:
251                 ADDR_ASSERT_ALWAYS();
252                 break;
253         }
254     }
255 
256     if ((pLib != NULL))
257     {
258         BOOL_32 initValid;
259 
260         // Pass createFlags to configFlags first since these flags may be overwritten
261         pLib->m_configFlags.noCubeMipSlicesPad  = pCreateIn->createFlags.noCubeMipSlicesPad;
262         pLib->m_configFlags.fillSizeFields      = pCreateIn->createFlags.fillSizeFields;
263         pLib->m_configFlags.useTileIndex        = pCreateIn->createFlags.useTileIndex;
264         pLib->m_configFlags.useCombinedSwizzle  = pCreateIn->createFlags.useCombinedSwizzle;
265         pLib->m_configFlags.checkLast2DLevel    = pCreateIn->createFlags.checkLast2DLevel;
266         pLib->m_configFlags.useHtileSliceAlign  = pCreateIn->createFlags.useHtileSliceAlign;
267         pLib->m_configFlags.degradeBaseLevel    = pCreateIn->createFlags.degradeBaseLevel;
268         pLib->m_configFlags.allowLargeThickTile = pCreateIn->createFlags.allowLargeThickTile;
269 
270         pLib->SetAddrChipFamily(pCreateIn->chipFamily, pCreateIn->chipRevision);
271 
272         pLib->SetMinPitchAlignPixels(pCreateIn->minPitchAlignPixels);
273 
274         // Global parameters initialized and remaining configFlags bits are set as well
275         initValid = pLib->HwlInitGlobalParams(pCreateIn);
276 
277         if (initValid)
278         {
279             pLib->m_pElemLib = AddrElemLib::Create(pLib);
280         }
281         else
282         {
283             pLib->m_pElemLib = NULL; // Don't go on allocating element lib
284             returnCode = ADDR_INVALIDGBREGVALUES;
285         }
286 
287         if (pLib->m_pElemLib == NULL)
288         {
289             delete pLib;
290             pLib = NULL;
291             ADDR_ASSERT_ALWAYS();
292         }
293         else
294         {
295             pLib->m_pElemLib->SetConfigFlags(pLib->m_configFlags);
296         }
297     }
298 
299     pCreateOut->hLib = pLib;
300 
301     if ((pLib == NULL) &&
302         (returnCode == ADDR_OK))
303     {
304         // Unknown failures, we return the general error code
305         returnCode = ADDR_ERROR;
306     }
307 
308     return returnCode;
309 }
310 
311 /**
312 ***************************************************************************************************
313 *   AddrLib::SetAddrChipFamily
314 *
315 *   @brief
316 *       Convert familyID defined in atiid.h to AddrChipFamily and set m_chipFamily/m_chipRevision
317 *   @return
318 *      N/A
319 ***************************************************************************************************
320 */
SetAddrChipFamily(UINT_32 uChipFamily,UINT_32 uChipRevision)321 VOID AddrLib::SetAddrChipFamily(
322     UINT_32 uChipFamily,        ///< [in] chip family defined in atiih.h
323     UINT_32 uChipRevision)      ///< [in] chip revision defined in "asic_family"_id.h
324 {
325     AddrChipFamily family = ADDR_CHIP_FAMILY_IVLD;
326 
327     family = HwlConvertChipFamily(uChipFamily, uChipRevision);
328 
329     ADDR_ASSERT(family != ADDR_CHIP_FAMILY_IVLD);
330 
331     m_chipFamily    = family;
332     m_chipRevision  = uChipRevision;
333 }
334 
335 /**
336 ***************************************************************************************************
337 *   AddrLib::SetMinPitchAlignPixels
338 *
339 *   @brief
340 *       Set m_minPitchAlignPixels with input param
341 *
342 *   @return
343 *      N/A
344 ***************************************************************************************************
345 */
SetMinPitchAlignPixels(UINT_32 minPitchAlignPixels)346 VOID AddrLib::SetMinPitchAlignPixels(
347     UINT_32 minPitchAlignPixels)    ///< [in] minmum pitch alignment in pixels
348 {
349     m_minPitchAlignPixels = (minPitchAlignPixels == 0)? 1 : minPitchAlignPixels;
350 }
351 
352 /**
353 ***************************************************************************************************
354 *   AddrLib::GetAddrLib
355 *
356 *   @brief
357 *       Get AddrLib pointer
358 *
359 *   @return
360 *      An AddrLib class pointer
361 ***************************************************************************************************
362 */
GetAddrLib(ADDR_HANDLE hLib)363 AddrLib * AddrLib::GetAddrLib(
364     ADDR_HANDLE hLib)   ///< [in] handle of ADDR_HANDLE
365 {
366     return static_cast<AddrLib *>(hLib);
367 }
368 
369 
370 
371 ///////////////////////////////////////////////////////////////////////////////////////////////////
372 //                               Surface Methods
373 ///////////////////////////////////////////////////////////////////////////////////////////////////
374 
375 
376 /**
377 ***************************************************************************************************
378 *   AddrLib::ComputeSurfaceInfo
379 *
380 *   @brief
381 *       Interface function stub of AddrComputeSurfaceInfo.
382 *
383 *   @return
384 *       ADDR_E_RETURNCODE
385 ***************************************************************************************************
386 */
ComputeSurfaceInfo(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const387 ADDR_E_RETURNCODE AddrLib::ComputeSurfaceInfo(
388      const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
389      ADDR_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure
390      ) const
391 {
392     ADDR_E_RETURNCODE returnCode = ADDR_OK;
393 
394     if (GetFillSizeFieldsFlags() == TRUE)
395     {
396         if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT)) ||
397             (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT)))
398         {
399             returnCode = ADDR_PARAMSIZEMISMATCH;
400         }
401     }
402 
403     // We suggest client do sanity check but a check here is also good
404     if (pIn->bpp > 128)
405     {
406         returnCode = ADDR_INVALIDPARAMS;
407     }
408 
409     // Thick modes don't support multisample
410     if (ComputeSurfaceThickness(pIn->tileMode) > 1 && pIn->numSamples > 1)
411     {
412         returnCode = ADDR_INVALIDPARAMS;
413     }
414 
415     if (returnCode == ADDR_OK)
416     {
417         // Get a local copy of input structure and only reference pIn for unadjusted values
418         ADDR_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;
419         ADDR_TILEINFO tileInfoNull = {0};
420 
421         if (UseTileInfo())
422         {
423             // If the original input has a valid ADDR_TILEINFO pointer then copy its contents.
424             // Otherwise the default 0's in tileInfoNull are used.
425             if (pIn->pTileInfo)
426             {
427                 tileInfoNull = *pIn->pTileInfo;
428             }
429             localIn.pTileInfo  = &tileInfoNull;
430         }
431 
432         localIn.numSamples = pIn->numSamples == 0 ? 1 : pIn->numSamples;
433 
434         // Do mipmap check first
435         // If format is BCn, pre-pad dimension to power-of-two according to HWL
436         ComputeMipLevel(&localIn);
437 
438         if (m_configFlags.checkLast2DLevel)
439         {
440             // Save this level's original height in pixels
441             pOut->height = pIn->height;
442         }
443 
444         UINT_32 expandX = 1;
445         UINT_32 expandY = 1;
446         AddrElemMode elemMode;
447 
448         // Save outputs that may not go through HWL
449         pOut->pixelBits = localIn.bpp;
450         pOut->numSamples = localIn.numSamples;
451         pOut->last2DLevel = FALSE;
452 
453 #if !ALT_TEST
454         if (localIn.numSamples > 1)
455         {
456             ADDR_ASSERT(localIn.mipLevel == 0);
457         }
458 #endif
459 
460         if (localIn.format != ADDR_FMT_INVALID) // Set format to INVALID will skip this conversion
461         {
462             // Get compression/expansion factors and element mode
463             // (which indicates compression/expansion
464             localIn.bpp = GetElemLib()->GetBitsPerPixel(localIn.format,
465                                                         &elemMode,
466                                                         &expandX,
467                                                         &expandY);
468 
469             // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
470             // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
471             // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
472             // restrictions are different.
473             // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
474             // but we use this flag to skip RestoreSurfaceInfo below
475 
476             if ((elemMode == ADDR_EXPANDED) &&
477                 (expandX > 1))
478             {
479                 ADDR_ASSERT(localIn.tileMode == ADDR_TM_LINEAR_ALIGNED || localIn.height == 1);
480             }
481 
482             GetElemLib()->AdjustSurfaceInfo(elemMode,
483                                             expandX,
484                                             expandY,
485                                             &localIn.bpp,
486                                             &localIn.basePitch,
487                                             &localIn.width,
488                                             &localIn.height);
489 
490             // Overwrite these parameters if we have a valid format
491         }
492         else if (localIn.bpp != 0)
493         {
494             localIn.width  = (localIn.width != 0) ? localIn.width : 1;
495             localIn.height = (localIn.height != 0) ? localIn.height : 1;
496         }
497         else // Rule out some invalid parameters
498         {
499             ADDR_ASSERT_ALWAYS();
500 
501             returnCode = ADDR_INVALIDPARAMS;
502         }
503 
504         // Check mipmap after surface expansion
505         if (returnCode == ADDR_OK)
506         {
507             returnCode = PostComputeMipLevel(&localIn, pOut);
508         }
509 
510         if (returnCode == ADDR_OK)
511         {
512             if (UseTileIndex(localIn.tileIndex))
513             {
514                 // Make sure pTileInfo is not NULL
515                 ADDR_ASSERT(localIn.pTileInfo);
516 
517                 UINT_32 numSamples = GetNumFragments(localIn.numSamples, localIn.numFrags);
518 
519                 INT_32 macroModeIndex = TileIndexNoMacroIndex;
520 
521                 if (localIn.tileIndex != TileIndexLinearGeneral)
522                 {
523                     // Try finding a macroModeIndex
524                     macroModeIndex = HwlComputeMacroModeIndex(localIn.tileIndex,
525                                                               localIn.flags,
526                                                               localIn.bpp,
527                                                               numSamples,
528                                                               localIn.pTileInfo,
529                                                               &localIn.tileMode,
530                                                               &localIn.tileType);
531                 }
532 
533                 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
534                 if (macroModeIndex == TileIndexNoMacroIndex)
535                 {
536                     returnCode = HwlSetupTileCfg(localIn.tileIndex, macroModeIndex,
537                                                  localIn.pTileInfo,
538                                                  &localIn.tileMode, &localIn.tileType);
539                 }
540                 // If macroModeIndex is invalid, then assert this is not macro tiled
541                 else if (macroModeIndex == TileIndexInvalid)
542                 {
543                     ADDR_ASSERT(!IsMacroTiled(localIn.tileMode));
544                 }
545             }
546         }
547 
548         if (returnCode == ADDR_OK)
549         {
550             AddrTileMode tileMode = localIn.tileMode;
551             AddrTileType tileType = localIn.tileType;
552 
553             // HWL layer may override tile mode if necessary
554             if (HwlOverrideTileMode(&localIn, &tileMode, &tileType))
555             {
556                 localIn.tileMode = tileMode;
557                 localIn.tileType = tileType;
558             }
559             // Degrade base level if applicable
560             if (DegradeBaseLevel(&localIn, &tileMode))
561             {
562                 localIn.tileMode = tileMode;
563             }
564         }
565 
566         // Call main function to compute surface info
567         if (returnCode == ADDR_OK)
568         {
569             returnCode = HwlComputeSurfaceInfo(&localIn, pOut);
570         }
571 
572         if (returnCode == ADDR_OK)
573         {
574             // Since bpp might be changed we just pass it through
575             pOut->bpp  = localIn.bpp;
576 
577             // Also original width/height/bpp
578             pOut->pixelPitch    = pOut->pitch;
579             pOut->pixelHeight   = pOut->height;
580 
581 #if DEBUG
582             if (localIn.flags.display)
583             {
584                 ADDR_ASSERT((pOut->pitchAlign % 32) == 0);
585             }
586 #endif //DEBUG
587 
588             if (localIn.format != ADDR_FMT_INVALID)
589             {
590                 //
591                 // 96 bits surface of level 1+ requires element pitch of 32 bits instead
592                 // In hwl function we skip multiplication of 3 then we should skip division of 3
593                 // We keep pitch that represents 32 bit element instead of 96 bits since we
594                 // will get an odd number if divided by 3.
595                 //
596                 if (!((expandX == 3) && (localIn.mipLevel > 0)))
597                 {
598 
599                     GetElemLib()->RestoreSurfaceInfo(elemMode,
600                                                      expandX,
601                                                      expandY,
602                                                      &localIn.bpp,
603                                                      &pOut->pixelPitch,
604                                                      &pOut->pixelHeight);
605                 }
606             }
607 
608             if (localIn.flags.qbStereo)
609             {
610                 if (pOut->pStereoInfo)
611                 {
612                     ComputeQbStereoInfo(pOut);
613                 }
614             }
615 
616             if (localIn.flags.volume) // For volume sliceSize equals to all z-slices
617             {
618                 pOut->sliceSize = pOut->surfSize;
619             }
620             else // For array: sliceSize is likely to have slice-padding (the last one)
621             {
622                 pOut->sliceSize = pOut->surfSize / pOut->depth;
623 
624                 // array or cubemap
625                 if (pIn->numSlices > 1)
626                 {
627                     // If this is the last slice then add the padding size to this slice
628                     if (pIn->slice == (pIn->numSlices - 1))
629                     {
630                         pOut->sliceSize += pOut->sliceSize * (pOut->depth - pIn->numSlices);
631                     }
632                     else if (m_configFlags.checkLast2DLevel)
633                     {
634                         // Reset last2DLevel flag if this is not the last array slice
635                         pOut->last2DLevel = FALSE;
636                     }
637                 }
638             }
639 
640             pOut->pitchTileMax = pOut->pitch / 8 - 1;
641             pOut->heightTileMax = pOut->height / 8 - 1;
642             pOut->sliceTileMax = pOut->pitch * pOut->height / 64 - 1;
643         }
644     }
645 
646     return returnCode;
647 }
648 
649 /**
650 ***************************************************************************************************
651 *   AddrLib::ComputeSurfaceInfo
652 *
653 *   @brief
654 *       Interface function stub of AddrComputeSurfaceInfo.
655 *
656 *   @return
657 *       ADDR_E_RETURNCODE
658 ***************************************************************************************************
659 */
ComputeSurfaceAddrFromCoord(const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const660 ADDR_E_RETURNCODE AddrLib::ComputeSurfaceAddrFromCoord(
661     const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
662     ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
663     ) const
664 {
665     ADDR_E_RETURNCODE returnCode = ADDR_OK;
666 
667     if (GetFillSizeFieldsFlags() == TRUE)
668     {
669         if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) ||
670             (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT)))
671         {
672             returnCode = ADDR_PARAMSIZEMISMATCH;
673         }
674     }
675 
676     if (returnCode == ADDR_OK)
677     {
678         ADDR_TILEINFO tileInfoNull;
679         ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT input;
680 
681         if (UseTileIndex(pIn->tileIndex))
682         {
683             input = *pIn;
684             // Use temp tile info for calcalation
685             input.pTileInfo = &tileInfoNull;
686 
687             const ADDR_SURFACE_FLAGS flags = {{0}};
688             UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags);
689 
690             // Try finding a macroModeIndex
691             INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex,
692                                                              flags,
693                                                              input.bpp,
694                                                              numSamples,
695                                                              input.pTileInfo,
696                                                              &input.tileMode,
697                                                              &input.tileType);
698 
699             // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
700             if (macroModeIndex == TileIndexNoMacroIndex)
701             {
702                 returnCode = HwlSetupTileCfg(input.tileIndex, macroModeIndex,
703                                              input.pTileInfo, &input.tileMode, &input.tileType);
704             }
705             // If macroModeIndex is invalid, then assert this is not macro tiled
706             else if (macroModeIndex == TileIndexInvalid)
707             {
708                 ADDR_ASSERT(!IsMacroTiled(input.tileMode));
709             }
710 
711             // Change the input structure
712             pIn = &input;
713         }
714 
715         if (returnCode == ADDR_OK)
716         {
717             returnCode = HwlComputeSurfaceAddrFromCoord(pIn, pOut);
718 
719             if (returnCode == ADDR_OK)
720             {
721                 pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024));
722             }
723         }
724     }
725 
726     return returnCode;
727 }
728 
729 /**
730 ***************************************************************************************************
731 *   AddrLib::ComputeSurfaceCoordFromAddr
732 *
733 *   @brief
734 *       Interface function stub of ComputeSurfaceCoordFromAddr.
735 *
736 *   @return
737 *       ADDR_E_RETURNCODE
738 ***************************************************************************************************
739 */
ComputeSurfaceCoordFromAddr(const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT * pIn,ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT * pOut) const740 ADDR_E_RETURNCODE AddrLib::ComputeSurfaceCoordFromAddr(
741     const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure
742     ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure
743     ) const
744 {
745     ADDR_E_RETURNCODE returnCode = ADDR_OK;
746 
747     if (GetFillSizeFieldsFlags() == TRUE)
748     {
749         if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) ||
750             (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT)))
751         {
752             returnCode = ADDR_PARAMSIZEMISMATCH;
753         }
754     }
755 
756     if (returnCode == ADDR_OK)
757     {
758         ADDR_TILEINFO tileInfoNull;
759         ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT input;
760 
761         if (UseTileIndex(pIn->tileIndex))
762         {
763             input = *pIn;
764             // Use temp tile info for calcalation
765             input.pTileInfo = &tileInfoNull;
766 
767             const ADDR_SURFACE_FLAGS flags = {{0}};
768             UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags);
769 
770             // Try finding a macroModeIndex
771             INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex,
772                                                              flags,
773                                                              input.bpp,
774                                                              numSamples,
775                                                              input.pTileInfo,
776                                                              &input.tileMode,
777                                                              &input.tileType);
778 
779             // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
780             if (macroModeIndex == TileIndexNoMacroIndex)
781             {
782                 returnCode = HwlSetupTileCfg(input.tileIndex, macroModeIndex,
783                                              input.pTileInfo, &input.tileMode, &input.tileType);
784             }
785             // If macroModeIndex is invalid, then assert this is not macro tiled
786             else if (macroModeIndex == TileIndexInvalid)
787             {
788                 ADDR_ASSERT(!IsMacroTiled(input.tileMode));
789             }
790 
791             // Change the input structure
792             pIn = &input;
793         }
794 
795         if (returnCode == ADDR_OK)
796         {
797             returnCode = HwlComputeSurfaceCoordFromAddr(pIn, pOut);
798         }
799     }
800 
801     return returnCode;
802 }
803 
804 /**
805 ***************************************************************************************************
806 *   AddrLib::ComputeSliceTileSwizzle
807 *
808 *   @brief
809 *       Interface function stub of ComputeSliceTileSwizzle.
810 *
811 *   @return
812 *       ADDR_E_RETURNCODE
813 ***************************************************************************************************
814 */
ComputeSliceTileSwizzle(const ADDR_COMPUTE_SLICESWIZZLE_INPUT * pIn,ADDR_COMPUTE_SLICESWIZZLE_OUTPUT * pOut) const815 ADDR_E_RETURNCODE AddrLib::ComputeSliceTileSwizzle(
816     const ADDR_COMPUTE_SLICESWIZZLE_INPUT*  pIn,    ///< [in] input structure
817     ADDR_COMPUTE_SLICESWIZZLE_OUTPUT*       pOut    ///< [out] output structure
818     ) const
819 {
820     ADDR_E_RETURNCODE returnCode = ADDR_OK;
821 
822     if (GetFillSizeFieldsFlags() == TRUE)
823     {
824         if ((pIn->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_INPUT)) ||
825             (pOut->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_OUTPUT)))
826         {
827             returnCode = ADDR_PARAMSIZEMISMATCH;
828         }
829     }
830 
831     if (returnCode == ADDR_OK)
832     {
833         ADDR_TILEINFO tileInfoNull;
834         ADDR_COMPUTE_SLICESWIZZLE_INPUT input;
835 
836         if (UseTileIndex(pIn->tileIndex))
837         {
838             input = *pIn;
839             // Use temp tile info for calcalation
840             input.pTileInfo = &tileInfoNull;
841 
842             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex,
843                                          input.pTileInfo, &input.tileMode);
844             // Change the input structure
845             pIn = &input;
846         }
847 
848         if (returnCode == ADDR_OK)
849         {
850             returnCode = HwlComputeSliceTileSwizzle(pIn, pOut);
851         }
852     }
853 
854     return returnCode;
855 }
856 
857 /**
858 ***************************************************************************************************
859 *   AddrLib::ExtractBankPipeSwizzle
860 *
861 *   @brief
862 *       Interface function stub of AddrExtractBankPipeSwizzle.
863 *
864 *   @return
865 *       ADDR_E_RETURNCODE
866 ***************************************************************************************************
867 */
ExtractBankPipeSwizzle(const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT * pIn,ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT * pOut) const868 ADDR_E_RETURNCODE AddrLib::ExtractBankPipeSwizzle(
869     const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT*  pIn,    ///< [in] input structure
870     ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT*       pOut    ///< [out] output structure
871     ) const
872 {
873     ADDR_E_RETURNCODE returnCode = ADDR_OK;
874 
875     if (GetFillSizeFieldsFlags() == TRUE)
876     {
877         if ((pIn->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT)) ||
878             (pOut->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT)))
879         {
880             returnCode = ADDR_PARAMSIZEMISMATCH;
881         }
882     }
883 
884     if (returnCode == ADDR_OK)
885     {
886         ADDR_TILEINFO tileInfoNull;
887         ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT input;
888 
889         if (UseTileIndex(pIn->tileIndex))
890         {
891             input = *pIn;
892             // Use temp tile info for calcalation
893             input.pTileInfo = &tileInfoNull;
894 
895             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
896             // Change the input structure
897             pIn = &input;
898         }
899 
900         if (returnCode == ADDR_OK)
901         {
902             returnCode = HwlExtractBankPipeSwizzle(pIn, pOut);
903         }
904     }
905 
906     return returnCode;
907 }
908 
909 /**
910 ***************************************************************************************************
911 *   AddrLib::CombineBankPipeSwizzle
912 *
913 *   @brief
914 *       Interface function stub of AddrCombineBankPipeSwizzle.
915 *
916 *   @return
917 *       ADDR_E_RETURNCODE
918 ***************************************************************************************************
919 */
CombineBankPipeSwizzle(const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT * pIn,ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT * pOut) const920 ADDR_E_RETURNCODE AddrLib::CombineBankPipeSwizzle(
921     const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT*  pIn,    ///< [in] input structure
922     ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT*       pOut    ///< [out] output structure
923     ) const
924 {
925     ADDR_E_RETURNCODE returnCode = ADDR_OK;
926 
927     if (GetFillSizeFieldsFlags() == TRUE)
928     {
929         if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) ||
930             (pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT)))
931         {
932             returnCode = ADDR_PARAMSIZEMISMATCH;
933         }
934     }
935 
936     if (returnCode == ADDR_OK)
937     {
938         ADDR_TILEINFO tileInfoNull;
939         ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT input;
940 
941         if (UseTileIndex(pIn->tileIndex))
942         {
943             input = *pIn;
944             // Use temp tile info for calcalation
945             input.pTileInfo = &tileInfoNull;
946 
947             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
948             // Change the input structure
949             pIn = &input;
950         }
951 
952         if (returnCode == ADDR_OK)
953         {
954             returnCode = HwlCombineBankPipeSwizzle(pIn->bankSwizzle,
955                                                    pIn->pipeSwizzle,
956                                                    pIn->pTileInfo,
957                                                    pIn->baseAddr,
958                                                    &pOut->tileSwizzle);
959         }
960     }
961 
962     return returnCode;
963 }
964 
965 /**
966 ***************************************************************************************************
967 *   AddrLib::ComputeBaseSwizzle
968 *
969 *   @brief
970 *       Interface function stub of AddrCompueBaseSwizzle.
971 *   @return
972 *       ADDR_E_RETURNCODE
973 ***************************************************************************************************
974 */
ComputeBaseSwizzle(const ADDR_COMPUTE_BASE_SWIZZLE_INPUT * pIn,ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT * pOut) const975 ADDR_E_RETURNCODE AddrLib::ComputeBaseSwizzle(
976     const ADDR_COMPUTE_BASE_SWIZZLE_INPUT*  pIn,
977     ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut) const
978 {
979     ADDR_E_RETURNCODE returnCode = ADDR_OK;
980 
981     if (GetFillSizeFieldsFlags() == TRUE)
982     {
983         if ((pIn->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT)) ||
984             (pOut->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT)))
985         {
986             returnCode = ADDR_PARAMSIZEMISMATCH;
987         }
988     }
989 
990     if (returnCode == ADDR_OK)
991     {
992         ADDR_TILEINFO tileInfoNull;
993         ADDR_COMPUTE_BASE_SWIZZLE_INPUT input;
994 
995         if (UseTileIndex(pIn->tileIndex))
996         {
997             input = *pIn;
998             // Use temp tile info for calcalation
999             input.pTileInfo = &tileInfoNull;
1000 
1001             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
1002             // Change the input structure
1003             pIn = &input;
1004         }
1005 
1006         if (returnCode == ADDR_OK)
1007         {
1008             if (IsMacroTiled(pIn->tileMode))
1009             {
1010                 returnCode = HwlComputeBaseSwizzle(pIn, pOut);
1011             }
1012             else
1013             {
1014                 pOut->tileSwizzle = 0;
1015             }
1016         }
1017     }
1018 
1019     return returnCode;
1020 }
1021 
1022 /**
1023 ***************************************************************************************************
1024 *   AddrLib::ComputeFmaskInfo
1025 *
1026 *   @brief
1027 *       Interface function stub of ComputeFmaskInfo.
1028 *
1029 *   @return
1030 *       ADDR_E_RETURNCODE
1031 ***************************************************************************************************
1032 */
ComputeFmaskInfo(const ADDR_COMPUTE_FMASK_INFO_INPUT * pIn,ADDR_COMPUTE_FMASK_INFO_OUTPUT * pOut)1033 ADDR_E_RETURNCODE AddrLib::ComputeFmaskInfo(
1034     const ADDR_COMPUTE_FMASK_INFO_INPUT*    pIn,    ///< [in] input structure
1035     ADDR_COMPUTE_FMASK_INFO_OUTPUT*         pOut    ///< [out] output structure
1036     )
1037 {
1038     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1039 
1040     if (GetFillSizeFieldsFlags() == TRUE)
1041     {
1042         if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) ||
1043             (pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT)))
1044         {
1045             returnCode = ADDR_PARAMSIZEMISMATCH;
1046         }
1047     }
1048 
1049     // No thick MSAA
1050     if (ComputeSurfaceThickness(pIn->tileMode) > 1)
1051     {
1052         returnCode = ADDR_INVALIDPARAMS;
1053     }
1054 
1055     if (returnCode == ADDR_OK)
1056     {
1057         ADDR_TILEINFO tileInfoNull;
1058         ADDR_COMPUTE_FMASK_INFO_INPUT input;
1059 
1060         if (UseTileIndex(pIn->tileIndex))
1061         {
1062             input = *pIn;
1063 
1064             if (pOut->pTileInfo)
1065             {
1066                 // Use temp tile info for calcalation
1067                 input.pTileInfo = pOut->pTileInfo;
1068             }
1069             else
1070             {
1071                 input.pTileInfo = &tileInfoNull;
1072             }
1073 
1074             ADDR_SURFACE_FLAGS flags = {{0}};
1075             flags.fmask = 1;
1076 
1077             // Try finding a macroModeIndex
1078             INT_32 macroModeIndex = HwlComputeMacroModeIndex(pIn->tileIndex,
1079                                                              flags,
1080                                                              HwlComputeFmaskBits(pIn, NULL),
1081                                                              pIn->numSamples,
1082                                                              input.pTileInfo,
1083                                                              &input.tileMode);
1084 
1085             // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
1086             if (macroModeIndex == TileIndexNoMacroIndex)
1087             {
1088                 returnCode = HwlSetupTileCfg(input.tileIndex, macroModeIndex,
1089                                              input.pTileInfo, &input.tileMode);
1090             }
1091 
1092             ADDR_ASSERT(macroModeIndex != TileIndexInvalid);
1093 
1094             // Change the input structure
1095             pIn = &input;
1096         }
1097 
1098         if (returnCode == ADDR_OK)
1099         {
1100             if (pIn->numSamples > 1)
1101             {
1102                 returnCode = HwlComputeFmaskInfo(pIn, pOut);
1103             }
1104             else
1105             {
1106                 memset(pOut, 0, sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT));
1107 
1108                 returnCode = ADDR_INVALIDPARAMS;
1109             }
1110         }
1111     }
1112 
1113     return returnCode;
1114 }
1115 
1116 /**
1117 ***************************************************************************************************
1118 *   AddrLib::ComputeFmaskAddrFromCoord
1119 *
1120 *   @brief
1121 *       Interface function stub of ComputeFmaskAddrFromCoord.
1122 *
1123 *   @return
1124 *       ADDR_E_RETURNCODE
1125 ***************************************************************************************************
1126 */
ComputeFmaskAddrFromCoord(const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT * pIn,ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT * pOut) const1127 ADDR_E_RETURNCODE AddrLib::ComputeFmaskAddrFromCoord(
1128     const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
1129     ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure
1130     ) const
1131 {
1132     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1133 
1134     if (GetFillSizeFieldsFlags() == TRUE)
1135     {
1136         if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT)) ||
1137             (pOut->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT)))
1138         {
1139             returnCode = ADDR_PARAMSIZEMISMATCH;
1140         }
1141     }
1142 
1143     if (returnCode == ADDR_OK)
1144     {
1145         ADDR_ASSERT(pIn->numSamples > 1);
1146 
1147         if (pIn->numSamples > 1)
1148         {
1149             returnCode = HwlComputeFmaskAddrFromCoord(pIn, pOut);
1150         }
1151         else
1152         {
1153             returnCode = ADDR_INVALIDPARAMS;
1154         }
1155     }
1156 
1157     return returnCode;
1158 }
1159 
1160 /**
1161 ***************************************************************************************************
1162 *   AddrLib::ComputeFmaskCoordFromAddr
1163 *
1164 *   @brief
1165 *       Interface function stub of ComputeFmaskAddrFromCoord.
1166 *
1167 *   @return
1168 *       ADDR_E_RETURNCODE
1169 ***************************************************************************************************
1170 */
ComputeFmaskCoordFromAddr(const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT * pIn,ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT * pOut) const1171 ADDR_E_RETURNCODE AddrLib::ComputeFmaskCoordFromAddr(
1172     const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT*  pIn,     ///< [in] input structure
1173     ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut           ///< [out] output structure
1174     ) const
1175 {
1176     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1177 
1178     if (GetFillSizeFieldsFlags() == TRUE)
1179     {
1180         if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT)) ||
1181             (pOut->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT)))
1182         {
1183             returnCode = ADDR_PARAMSIZEMISMATCH;
1184         }
1185     }
1186 
1187     if (returnCode == ADDR_OK)
1188     {
1189         ADDR_ASSERT(pIn->numSamples > 1);
1190 
1191         if (pIn->numSamples > 1)
1192         {
1193             returnCode = HwlComputeFmaskCoordFromAddr(pIn, pOut);
1194         }
1195         else
1196         {
1197             returnCode = ADDR_INVALIDPARAMS;
1198         }
1199     }
1200 
1201     return returnCode;
1202 }
1203 
1204 /**
1205 ***************************************************************************************************
1206 *   AddrLib::ConvertTileInfoToHW
1207 *
1208 *   @brief
1209 *       Convert tile info from real value to HW register value in HW layer
1210 *
1211 *   @return
1212 *       ADDR_E_RETURNCODE
1213 ***************************************************************************************************
1214 */
ConvertTileInfoToHW(const ADDR_CONVERT_TILEINFOTOHW_INPUT * pIn,ADDR_CONVERT_TILEINFOTOHW_OUTPUT * pOut) const1215 ADDR_E_RETURNCODE AddrLib::ConvertTileInfoToHW(
1216     const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure
1217     ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut      ///< [out] output structure
1218     ) const
1219 {
1220     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1221 
1222     if (GetFillSizeFieldsFlags() == TRUE)
1223     {
1224         if ((pIn->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT)) ||
1225             (pOut->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT)))
1226         {
1227             returnCode = ADDR_PARAMSIZEMISMATCH;
1228         }
1229     }
1230 
1231     if (returnCode == ADDR_OK)
1232     {
1233         ADDR_TILEINFO tileInfoNull;
1234         ADDR_CONVERT_TILEINFOTOHW_INPUT input;
1235         // if pIn->reverse is TRUE, indices are ignored
1236         if (pIn->reverse == FALSE && UseTileIndex(pIn->tileIndex))
1237         {
1238             input = *pIn;
1239             input.pTileInfo = &tileInfoNull;
1240 
1241             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
1242 
1243             pIn = &input;
1244         }
1245 
1246         if (returnCode == ADDR_OK)
1247         {
1248             returnCode = HwlConvertTileInfoToHW(pIn, pOut);
1249         }
1250     }
1251 
1252     return returnCode;
1253 }
1254 
1255 /**
1256 ***************************************************************************************************
1257 *   AddrLib::ConvertTileIndex
1258 *
1259 *   @brief
1260 *       Convert tile index to tile mode/type/info
1261 *
1262 *   @return
1263 *       ADDR_E_RETURNCODE
1264 ***************************************************************************************************
1265 */
ConvertTileIndex(const ADDR_CONVERT_TILEINDEX_INPUT * pIn,ADDR_CONVERT_TILEINDEX_OUTPUT * pOut) const1266 ADDR_E_RETURNCODE AddrLib::ConvertTileIndex(
1267     const ADDR_CONVERT_TILEINDEX_INPUT* pIn, ///< [in] input structure
1268     ADDR_CONVERT_TILEINDEX_OUTPUT* pOut      ///< [out] output structure
1269     ) const
1270 {
1271     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1272 
1273     if (GetFillSizeFieldsFlags() == TRUE)
1274     {
1275         if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX_INPUT)) ||
1276             (pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT)))
1277         {
1278             returnCode = ADDR_PARAMSIZEMISMATCH;
1279         }
1280     }
1281 
1282     if (returnCode == ADDR_OK)
1283     {
1284 
1285         returnCode = HwlSetupTileCfg(pIn->tileIndex, pIn->macroModeIndex,
1286                                      pOut->pTileInfo, &pOut->tileMode, &pOut->tileType);
1287 
1288         if (returnCode == ADDR_OK && pIn->tileInfoHw)
1289         {
1290             ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0};
1291             ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0};
1292 
1293             hwInput.pTileInfo = pOut->pTileInfo;
1294             hwInput.tileIndex = -1;
1295             hwOutput.pTileInfo = pOut->pTileInfo;
1296 
1297             returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput);
1298         }
1299     }
1300 
1301     return returnCode;
1302 }
1303 
1304 /**
1305 ***************************************************************************************************
1306 *   AddrLib::ConvertTileIndex1
1307 *
1308 *   @brief
1309 *       Convert tile index to tile mode/type/info
1310 *
1311 *   @return
1312 *       ADDR_E_RETURNCODE
1313 ***************************************************************************************************
1314 */
ConvertTileIndex1(const ADDR_CONVERT_TILEINDEX1_INPUT * pIn,ADDR_CONVERT_TILEINDEX_OUTPUT * pOut) const1315 ADDR_E_RETURNCODE AddrLib::ConvertTileIndex1(
1316     const ADDR_CONVERT_TILEINDEX1_INPUT* pIn,   ///< [in] input structure
1317     ADDR_CONVERT_TILEINDEX_OUTPUT* pOut         ///< [out] output structure
1318     ) const
1319 {
1320     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1321 
1322     if (GetFillSizeFieldsFlags() == TRUE)
1323     {
1324         if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX1_INPUT)) ||
1325             (pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT)))
1326         {
1327             returnCode = ADDR_PARAMSIZEMISMATCH;
1328         }
1329     }
1330 
1331     if (returnCode == ADDR_OK)
1332     {
1333         ADDR_SURFACE_FLAGS flags = {{0}};
1334 
1335         HwlComputeMacroModeIndex(pIn->tileIndex, flags, pIn->bpp, pIn->numSamples,
1336                                  pOut->pTileInfo, &pOut->tileMode, &pOut->tileType);
1337 
1338         if (pIn->tileInfoHw)
1339         {
1340             ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0};
1341             ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0};
1342 
1343             hwInput.pTileInfo = pOut->pTileInfo;
1344             hwInput.tileIndex = -1;
1345             hwOutput.pTileInfo = pOut->pTileInfo;
1346 
1347             returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput);
1348         }
1349     }
1350 
1351     return returnCode;
1352 }
1353 
1354 /**
1355 ***************************************************************************************************
1356 *   AddrLib::GetTileIndex
1357 *
1358 *   @brief
1359 *       Get tile index from tile mode/type/info
1360 *
1361 *   @return
1362 *       ADDR_E_RETURNCODE
1363 ***************************************************************************************************
1364 */
GetTileIndex(const ADDR_GET_TILEINDEX_INPUT * pIn,ADDR_GET_TILEINDEX_OUTPUT * pOut) const1365 ADDR_E_RETURNCODE AddrLib::GetTileIndex(
1366     const ADDR_GET_TILEINDEX_INPUT* pIn, ///< [in] input structure
1367     ADDR_GET_TILEINDEX_OUTPUT* pOut      ///< [out] output structure
1368     ) const
1369 {
1370     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1371 
1372     if (GetFillSizeFieldsFlags() == TRUE)
1373     {
1374         if ((pIn->size != sizeof(ADDR_GET_TILEINDEX_INPUT)) ||
1375             (pOut->size != sizeof(ADDR_GET_TILEINDEX_OUTPUT)))
1376         {
1377             returnCode = ADDR_PARAMSIZEMISMATCH;
1378         }
1379     }
1380 
1381     if (returnCode == ADDR_OK)
1382     {
1383         returnCode = HwlGetTileIndex(pIn, pOut);
1384     }
1385 
1386     return returnCode;
1387 }
1388 
1389 /**
1390 ***************************************************************************************************
1391 *   AddrLib::ComputeSurfaceThickness
1392 *
1393 *   @brief
1394 *       Compute surface thickness
1395 *
1396 *   @return
1397 *       Surface thickness
1398 ***************************************************************************************************
1399 */
ComputeSurfaceThickness(AddrTileMode tileMode)1400 UINT_32 AddrLib::ComputeSurfaceThickness(
1401     AddrTileMode tileMode)    ///< [in] tile mode
1402 {
1403     return m_modeFlags[tileMode].thickness;
1404 }
1405 
1406 
1407 
1408 ///////////////////////////////////////////////////////////////////////////////////////////////////
1409 //                               CMASK/HTILE
1410 ///////////////////////////////////////////////////////////////////////////////////////////////////
1411 
1412 /**
1413 ***************************************************************************************************
1414 *   AddrLib::ComputeHtileInfo
1415 *
1416 *   @brief
1417 *       Interface function stub of AddrComputeHtilenfo
1418 *
1419 *   @return
1420 *       ADDR_E_RETURNCODE
1421 ***************************************************************************************************
1422 */
ComputeHtileInfo(const ADDR_COMPUTE_HTILE_INFO_INPUT * pIn,ADDR_COMPUTE_HTILE_INFO_OUTPUT * pOut) const1423 ADDR_E_RETURNCODE AddrLib::ComputeHtileInfo(
1424     const ADDR_COMPUTE_HTILE_INFO_INPUT*    pIn,    ///< [in] input structure
1425     ADDR_COMPUTE_HTILE_INFO_OUTPUT*         pOut    ///< [out] output structure
1426     ) const
1427 {
1428     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1429 
1430     BOOL_32 isWidth8  = (pIn->blockWidth == 8) ? TRUE : FALSE;
1431     BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;
1432 
1433     if (GetFillSizeFieldsFlags() == TRUE)
1434     {
1435         if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT)) ||
1436             (pOut->size != sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT)))
1437         {
1438             returnCode = ADDR_PARAMSIZEMISMATCH;
1439         }
1440     }
1441 
1442     if (returnCode == ADDR_OK)
1443     {
1444         ADDR_TILEINFO tileInfoNull;
1445         ADDR_COMPUTE_HTILE_INFO_INPUT input;
1446 
1447         if (UseTileIndex(pIn->tileIndex))
1448         {
1449             input = *pIn;
1450             // Use temp tile info for calcalation
1451             input.pTileInfo = &tileInfoNull;
1452 
1453             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
1454 
1455             // Change the input structure
1456             pIn = &input;
1457         }
1458 
1459         if (returnCode == ADDR_OK)
1460         {
1461             pOut->bpp = ComputeHtileInfo(pIn->flags,
1462                                          pIn->pitch,
1463                                          pIn->height,
1464                                          pIn->numSlices,
1465                                          pIn->isLinear,
1466                                          isWidth8,
1467                                          isHeight8,
1468                                          pIn->pTileInfo,
1469                                          &pOut->pitch,
1470                                          &pOut->height,
1471                                          &pOut->htileBytes,
1472                                          &pOut->macroWidth,
1473                                          &pOut->macroHeight,
1474                                          &pOut->sliceSize,
1475                                          &pOut->baseAlign);
1476         }
1477     }
1478 
1479     return returnCode;
1480 }
1481 
1482 /**
1483 ***************************************************************************************************
1484 *   AddrLib::ComputeCmaskInfo
1485 *
1486 *   @brief
1487 *       Interface function stub of AddrComputeCmaskInfo
1488 *
1489 *   @return
1490 *       ADDR_E_RETURNCODE
1491 ***************************************************************************************************
1492 */
ComputeCmaskInfo(const ADDR_COMPUTE_CMASK_INFO_INPUT * pIn,ADDR_COMPUTE_CMASK_INFO_OUTPUT * pOut) const1493 ADDR_E_RETURNCODE AddrLib::ComputeCmaskInfo(
1494     const ADDR_COMPUTE_CMASK_INFO_INPUT*    pIn,    ///< [in] input structure
1495     ADDR_COMPUTE_CMASK_INFO_OUTPUT*         pOut    ///< [out] output structure
1496     ) const
1497 {
1498     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1499 
1500     if (GetFillSizeFieldsFlags() == TRUE)
1501     {
1502         if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_INFO_INPUT)) ||
1503             (pOut->size != sizeof(ADDR_COMPUTE_CMASK_INFO_OUTPUT)))
1504         {
1505             returnCode = ADDR_PARAMSIZEMISMATCH;
1506         }
1507     }
1508 
1509     if (returnCode == ADDR_OK)
1510     {
1511         ADDR_TILEINFO tileInfoNull;
1512         ADDR_COMPUTE_CMASK_INFO_INPUT input;
1513 
1514         if (UseTileIndex(pIn->tileIndex))
1515         {
1516             input = *pIn;
1517             // Use temp tile info for calcalation
1518             input.pTileInfo = &tileInfoNull;
1519 
1520             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
1521 
1522             // Change the input structure
1523             pIn = &input;
1524         }
1525 
1526         if (returnCode == ADDR_OK)
1527         {
1528             returnCode = ComputeCmaskInfo(pIn->flags,
1529                                           pIn->pitch,
1530                                           pIn->height,
1531                                           pIn->numSlices,
1532                                           pIn->isLinear,
1533                                           pIn->pTileInfo,
1534                                           &pOut->pitch,
1535                                           &pOut->height,
1536                                           &pOut->cmaskBytes,
1537                                           &pOut->macroWidth,
1538                                           &pOut->macroHeight,
1539                                           &pOut->sliceSize,
1540                                           &pOut->baseAlign,
1541                                           &pOut->blockMax);
1542         }
1543     }
1544 
1545     return returnCode;
1546 }
1547 
1548 /**
1549 ***************************************************************************************************
1550 *   AddrLib::ComputeDccInfo
1551 *
1552 *   @brief
1553 *       Interface function to compute DCC key info
1554 *
1555 *   @return
1556 *       return code of HwlComputeDccInfo
1557 ***************************************************************************************************
1558 */
ComputeDccInfo(const ADDR_COMPUTE_DCCINFO_INPUT * pIn,ADDR_COMPUTE_DCCINFO_OUTPUT * pOut) const1559 ADDR_E_RETURNCODE AddrLib::ComputeDccInfo(
1560     const ADDR_COMPUTE_DCCINFO_INPUT*    pIn,    ///< [in] input structure
1561     ADDR_COMPUTE_DCCINFO_OUTPUT*         pOut    ///< [out] output structure
1562     ) const
1563 {
1564     ADDR_E_RETURNCODE ret = ADDR_OK;
1565 
1566     if (GetFillSizeFieldsFlags() == TRUE)
1567     {
1568         if ((pIn->size != sizeof(ADDR_COMPUTE_DCCINFO_INPUT)) ||
1569             (pOut->size != sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT)))
1570         {
1571             ret = ADDR_PARAMSIZEMISMATCH;
1572         }
1573     }
1574 
1575     if (ret == ADDR_OK)
1576     {
1577         ADDR_COMPUTE_DCCINFO_INPUT input;
1578 
1579         if (UseTileIndex(pIn->tileIndex))
1580         {
1581             input = *pIn;
1582 
1583             ret = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex,
1584                                   &input.tileInfo, &input.tileMode);
1585 
1586             pIn = &input;
1587         }
1588 
1589         if (ADDR_OK == ret)
1590         {
1591             ret = HwlComputeDccInfo(pIn, pOut);
1592         }
1593     }
1594 
1595     return ret;
1596 }
1597 
1598 /**
1599 ***************************************************************************************************
1600 *   AddrLib::ComputeHtileAddrFromCoord
1601 *
1602 *   @brief
1603 *       Interface function stub of AddrComputeHtileAddrFromCoord
1604 *
1605 *   @return
1606 *       ADDR_E_RETURNCODE
1607 ***************************************************************************************************
1608 */
ComputeHtileAddrFromCoord(const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT * pIn,ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT * pOut) const1609 ADDR_E_RETURNCODE AddrLib::ComputeHtileAddrFromCoord(
1610     const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
1611     ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure
1612     ) const
1613 {
1614     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1615 
1616     BOOL_32 isWidth8  = (pIn->blockWidth == 8) ? TRUE : FALSE;
1617     BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;
1618 
1619     if (GetFillSizeFieldsFlags() == TRUE)
1620     {
1621         if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) ||
1622             (pOut->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT)))
1623         {
1624             returnCode = ADDR_PARAMSIZEMISMATCH;
1625         }
1626     }
1627 
1628     if (returnCode == ADDR_OK)
1629     {
1630         ADDR_TILEINFO tileInfoNull;
1631         ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT input;
1632 
1633         if (UseTileIndex(pIn->tileIndex))
1634         {
1635             input = *pIn;
1636             // Use temp tile info for calcalation
1637             input.pTileInfo = &tileInfoNull;
1638 
1639             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
1640 
1641             // Change the input structure
1642             pIn = &input;
1643         }
1644 
1645         if (returnCode == ADDR_OK)
1646         {
1647             pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch,
1648                                                       pIn->height,
1649                                                       pIn->x,
1650                                                       pIn->y,
1651                                                       pIn->slice,
1652                                                       pIn->numSlices,
1653                                                       1,
1654                                                       pIn->isLinear,
1655                                                       isWidth8,
1656                                                       isHeight8,
1657                                                       pIn->pTileInfo,
1658                                                       &pOut->bitPosition);
1659         }
1660     }
1661 
1662     return returnCode;
1663 
1664 }
1665 
1666 /**
1667 ***************************************************************************************************
1668 *   AddrLib::ComputeHtileCoordFromAddr
1669 *
1670 *   @brief
1671 *       Interface function stub of AddrComputeHtileCoordFromAddr
1672 *
1673 *   @return
1674 *       ADDR_E_RETURNCODE
1675 ***************************************************************************************************
1676 */
ComputeHtileCoordFromAddr(const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT * pIn,ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT * pOut) const1677 ADDR_E_RETURNCODE AddrLib::ComputeHtileCoordFromAddr(
1678     const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure
1679     ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*        pOut    ///< [out] output structure
1680     ) const
1681 {
1682     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1683 
1684     BOOL_32 isWidth8  = (pIn->blockWidth == 8) ? TRUE : FALSE;
1685     BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;
1686 
1687     if (GetFillSizeFieldsFlags() == TRUE)
1688     {
1689         if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT)) ||
1690             (pOut->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT)))
1691         {
1692             returnCode = ADDR_PARAMSIZEMISMATCH;
1693         }
1694     }
1695 
1696     if (returnCode == ADDR_OK)
1697     {
1698         ADDR_TILEINFO tileInfoNull;
1699         ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT input;
1700 
1701         if (UseTileIndex(pIn->tileIndex))
1702         {
1703             input = *pIn;
1704             // Use temp tile info for calcalation
1705             input.pTileInfo = &tileInfoNull;
1706 
1707             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
1708 
1709             // Change the input structure
1710             pIn = &input;
1711         }
1712 
1713         if (returnCode == ADDR_OK)
1714         {
1715             HwlComputeXmaskCoordFromAddr(pIn->addr,
1716                                          pIn->bitPosition,
1717                                          pIn->pitch,
1718                                          pIn->height,
1719                                          pIn->numSlices,
1720                                          1,
1721                                          pIn->isLinear,
1722                                          isWidth8,
1723                                          isHeight8,
1724                                          pIn->pTileInfo,
1725                                          &pOut->x,
1726                                          &pOut->y,
1727                                          &pOut->slice);
1728         }
1729     }
1730 
1731     return returnCode;
1732 }
1733 
1734 /**
1735 ***************************************************************************************************
1736 *   AddrLib::ComputeCmaskAddrFromCoord
1737 *
1738 *   @brief
1739 *       Interface function stub of AddrComputeCmaskAddrFromCoord
1740 *
1741 *   @return
1742 *       ADDR_E_RETURNCODE
1743 ***************************************************************************************************
1744 */
ComputeCmaskAddrFromCoord(const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT * pIn,ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT * pOut) const1745 ADDR_E_RETURNCODE AddrLib::ComputeCmaskAddrFromCoord(
1746     const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
1747     ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure
1748     ) const
1749 {
1750     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1751 
1752     if (GetFillSizeFieldsFlags() == TRUE)
1753     {
1754         if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) ||
1755             (pOut->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT)))
1756         {
1757             returnCode = ADDR_PARAMSIZEMISMATCH;
1758         }
1759     }
1760 
1761     if (returnCode == ADDR_OK)
1762     {
1763         ADDR_TILEINFO tileInfoNull;
1764         ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT input;
1765 
1766         if (UseTileIndex(pIn->tileIndex))
1767         {
1768             input = *pIn;
1769             // Use temp tile info for calcalation
1770             input.pTileInfo = &tileInfoNull;
1771 
1772             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
1773 
1774             // Change the input structure
1775             pIn = &input;
1776         }
1777 
1778         if (returnCode == ADDR_OK)
1779         {
1780             if (pIn->flags.tcCompatible == TRUE)
1781             {
1782                 returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut);
1783             }
1784             else
1785             {
1786                 pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch,
1787                                                           pIn->height,
1788                                                           pIn->x,
1789                                                           pIn->y,
1790                                                           pIn->slice,
1791                                                           pIn->numSlices,
1792                                                           2,
1793                                                           pIn->isLinear,
1794                                                           FALSE, //this is cmask, isWidth8 is not needed
1795                                                           FALSE, //this is cmask, isHeight8 is not needed
1796                                                           pIn->pTileInfo,
1797                                                           &pOut->bitPosition);
1798             }
1799 
1800         }
1801     }
1802 
1803     return returnCode;
1804 }
1805 
1806 /**
1807 ***************************************************************************************************
1808 *   AddrLib::ComputeCmaskCoordFromAddr
1809 *
1810 *   @brief
1811 *       Interface function stub of AddrComputeCmaskCoordFromAddr
1812 *
1813 *   @return
1814 *       ADDR_E_RETURNCODE
1815 ***************************************************************************************************
1816 */
ComputeCmaskCoordFromAddr(const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT * pIn,ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT * pOut) const1817 ADDR_E_RETURNCODE AddrLib::ComputeCmaskCoordFromAddr(
1818     const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure
1819     ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT*        pOut    ///< [out] output structure
1820     ) const
1821 {
1822     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1823 
1824     if (GetFillSizeFieldsFlags() == TRUE)
1825     {
1826         if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT)) ||
1827             (pOut->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT)))
1828         {
1829             returnCode = ADDR_PARAMSIZEMISMATCH;
1830         }
1831     }
1832 
1833     if (returnCode == ADDR_OK)
1834     {
1835         ADDR_TILEINFO tileInfoNull;
1836         ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT input;
1837 
1838         if (UseTileIndex(pIn->tileIndex))
1839         {
1840             input = *pIn;
1841             // Use temp tile info for calcalation
1842             input.pTileInfo = &tileInfoNull;
1843 
1844             returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
1845 
1846             // Change the input structure
1847             pIn = &input;
1848         }
1849 
1850         if (returnCode == ADDR_OK)
1851         {
1852             HwlComputeXmaskCoordFromAddr(pIn->addr,
1853                                          pIn->bitPosition,
1854                                          pIn->pitch,
1855                                          pIn->height,
1856                                          pIn->numSlices,
1857                                          2,
1858                                          pIn->isLinear,
1859                                          FALSE,
1860                                          FALSE,
1861                                          pIn->pTileInfo,
1862                                          &pOut->x,
1863                                          &pOut->y,
1864                                          &pOut->slice);
1865         }
1866     }
1867 
1868     return returnCode;
1869 }
1870 
1871 /**
1872 ***************************************************************************************************
1873 *   AddrLib::ComputeTileDataWidthAndHeight
1874 *
1875 *   @brief
1876 *       Compute the squared cache shape for per-tile data (CMASK and HTILE)
1877 *
1878 *   @return
1879 *       N/A
1880 *
1881 *   @note
1882 *       MacroWidth and macroHeight are measured in pixels
1883 ***************************************************************************************************
1884 */
ComputeTileDataWidthAndHeight(UINT_32 bpp,UINT_32 cacheBits,ADDR_TILEINFO * pTileInfo,UINT_32 * pMacroWidth,UINT_32 * pMacroHeight) const1885 VOID AddrLib::ComputeTileDataWidthAndHeight(
1886     UINT_32         bpp,             ///< [in] bits per pixel
1887     UINT_32         cacheBits,       ///< [in] bits of cache
1888     ADDR_TILEINFO*  pTileInfo,       ///< [in] Tile info
1889     UINT_32*        pMacroWidth,     ///< [out] macro tile width
1890     UINT_32*        pMacroHeight     ///< [out] macro tile height
1891     ) const
1892 {
1893     UINT_32 height = 1;
1894     UINT_32 width  = cacheBits / bpp;
1895     UINT_32 pipes  = HwlGetPipes(pTileInfo);
1896 
1897     // Double height until the macro-tile is close to square
1898     // Height can only be doubled if width is even
1899 
1900     while ((width > height * 2 * pipes) && !(width & 1))
1901     {
1902         width  /= 2;
1903         height *= 2;
1904     }
1905 
1906     *pMacroWidth  = 8 * width;
1907     *pMacroHeight = 8 * height * pipes;
1908 
1909     // Note: The above iterative comptuation is equivalent to the following
1910     //
1911     //int log2_height = ((log2(cacheBits)-log2(bpp)-log2(pipes))/2);
1912     //int macroHeight = pow2( 3+log2(pipes)+log2_height );
1913 }
1914 
1915 /**
1916 ***************************************************************************************************
1917 *   AddrLib::HwlComputeTileDataWidthAndHeightLinear
1918 *
1919 *   @brief
1920 *       Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1921 *
1922 *   @return
1923 *       N/A
1924 *
1925 *   @note
1926 *       MacroWidth and macroHeight are measured in pixels
1927 ***************************************************************************************************
1928 */
HwlComputeTileDataWidthAndHeightLinear(UINT_32 * pMacroWidth,UINT_32 * pMacroHeight,UINT_32 bpp,ADDR_TILEINFO * pTileInfo) const1929 VOID AddrLib::HwlComputeTileDataWidthAndHeightLinear(
1930     UINT_32*        pMacroWidth,     ///< [out] macro tile width
1931     UINT_32*        pMacroHeight,    ///< [out] macro tile height
1932     UINT_32         bpp,             ///< [in] bits per pixel
1933     ADDR_TILEINFO*  pTileInfo        ///< [in] tile info
1934     ) const
1935 {
1936     ADDR_ASSERT(bpp != 4);              // Cmask does not support linear layout prior to SI
1937     *pMacroWidth  = 8 * 512 / bpp;      // Align width to 512-bit memory accesses
1938     *pMacroHeight = 8 * m_pipes;        // Align height to number of pipes
1939 }
1940 
1941 /**
1942 ***************************************************************************************************
1943 *   AddrLib::ComputeHtileInfo
1944 *
1945 *   @brief
1946 *       Compute htile pitch,width, bytes per 2D slice
1947 *
1948 *   @return
1949 *       Htile bpp i.e. How many bits for an 8x8 tile
1950 *       Also returns by output parameters:
1951 *       *Htile pitch, height, total size in bytes, macro-tile dimensions and slice size*
1952 ***************************************************************************************************
1953 */
ComputeHtileInfo(ADDR_HTILE_FLAGS flags,UINT_32 pitchIn,UINT_32 heightIn,UINT_32 numSlices,BOOL_32 isLinear,BOOL_32 isWidth8,BOOL_32 isHeight8,ADDR_TILEINFO * pTileInfo,UINT_32 * pPitchOut,UINT_32 * pHeightOut,UINT_64 * pHtileBytes,UINT_32 * pMacroWidth,UINT_32 * pMacroHeight,UINT_64 * pSliceSize,UINT_32 * pBaseAlign) const1954 UINT_32 AddrLib::ComputeHtileInfo(
1955     ADDR_HTILE_FLAGS flags,             ///< [in] htile flags
1956     UINT_32          pitchIn,           ///< [in] pitch input
1957     UINT_32          heightIn,          ///< [in] height input
1958     UINT_32          numSlices,         ///< [in] number of slices
1959     BOOL_32          isLinear,          ///< [in] if it is linear mode
1960     BOOL_32          isWidth8,          ///< [in] if htile block width is 8
1961     BOOL_32          isHeight8,         ///< [in] if htile block height is 8
1962     ADDR_TILEINFO*   pTileInfo,         ///< [in] Tile info
1963     UINT_32*         pPitchOut,         ///< [out] pitch output
1964     UINT_32*         pHeightOut,        ///< [out] height output
1965     UINT_64*         pHtileBytes,       ///< [out] bytes per 2D slice
1966     UINT_32*         pMacroWidth,       ///< [out] macro-tile width in pixels
1967     UINT_32*         pMacroHeight,      ///< [out] macro-tile width in pixels
1968     UINT_64*         pSliceSize,        ///< [out] slice size in bytes
1969     UINT_32*         pBaseAlign         ///< [out] base alignment
1970     ) const
1971 {
1972 
1973     UINT_32 macroWidth;
1974     UINT_32 macroHeight;
1975     UINT_32 baseAlign;
1976     UINT_64 surfBytes;
1977     UINT_64 sliceBytes;
1978 
1979     numSlices = Max(1u, numSlices);
1980 
1981     const UINT_32 bpp = HwlComputeHtileBpp(isWidth8, isHeight8);
1982     const UINT_32 cacheBits = HtileCacheBits;
1983 
1984     if (isLinear)
1985     {
1986         HwlComputeTileDataWidthAndHeightLinear(&macroWidth,
1987                                                &macroHeight,
1988                                                bpp,
1989                                                pTileInfo);
1990     }
1991     else
1992     {
1993         ComputeTileDataWidthAndHeight(bpp,
1994                                       cacheBits,
1995                                       pTileInfo,
1996                                       &macroWidth,
1997                                       &macroHeight);
1998     }
1999 
2000     *pPitchOut = PowTwoAlign(pitchIn,  macroWidth);
2001     *pHeightOut = PowTwoAlign(heightIn,  macroHeight);
2002 
2003     baseAlign = HwlComputeHtileBaseAlign(flags.tcCompatible, isLinear, pTileInfo);
2004 
2005     surfBytes = HwlComputeHtileBytes(*pPitchOut,
2006                                      *pHeightOut,
2007                                      bpp,
2008                                      isLinear,
2009                                      numSlices,
2010                                      &sliceBytes,
2011                                      baseAlign);
2012 
2013     *pHtileBytes = surfBytes;
2014 
2015     //
2016     // Use SafeAssign since they are optional
2017     //
2018     SafeAssign(pMacroWidth, macroWidth);
2019 
2020     SafeAssign(pMacroHeight, macroHeight);
2021 
2022     SafeAssign(pSliceSize,  sliceBytes);
2023 
2024     SafeAssign(pBaseAlign, baseAlign);
2025 
2026     return bpp;
2027 }
2028 
2029 /**
2030 ***************************************************************************************************
2031 *   AddrLib::ComputeCmaskBaseAlign
2032 *
2033 *   @brief
2034 *       Compute cmask base alignment
2035 *
2036 *   @return
2037 *       Cmask base alignment
2038 ***************************************************************************************************
2039 */
ComputeCmaskBaseAlign(ADDR_CMASK_FLAGS flags,ADDR_TILEINFO * pTileInfo) const2040 UINT_32 AddrLib::ComputeCmaskBaseAlign(
2041     ADDR_CMASK_FLAGS flags,           ///< [in] Cmask flags
2042     ADDR_TILEINFO*   pTileInfo        ///< [in] Tile info
2043     ) const
2044 {
2045     UINT_32 baseAlign = m_pipeInterleaveBytes * HwlGetPipes(pTileInfo);
2046 
2047     if (flags.tcCompatible)
2048     {
2049         ADDR_ASSERT(pTileInfo != NULL);
2050         if (pTileInfo)
2051         {
2052             baseAlign *= pTileInfo->banks;
2053         }
2054     }
2055 
2056     return baseAlign;
2057 }
2058 
2059 /**
2060 ***************************************************************************************************
2061 *   AddrLib::ComputeCmaskBytes
2062 *
2063 *   @brief
2064 *       Compute cmask size in bytes
2065 *
2066 *   @return
2067 *       Cmask size in bytes
2068 ***************************************************************************************************
2069 */
ComputeCmaskBytes(UINT_32 pitch,UINT_32 height,UINT_32 numSlices) const2070 UINT_64 AddrLib::ComputeCmaskBytes(
2071     UINT_32 pitch,        ///< [in] pitch
2072     UINT_32 height,       ///< [in] height
2073     UINT_32 numSlices     ///< [in] number of slices
2074     ) const
2075 {
2076     return BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * numSlices * CmaskElemBits) /
2077         MicroTilePixels;
2078 }
2079 
2080 /**
2081 ***************************************************************************************************
2082 *   AddrLib::ComputeCmaskInfo
2083 *
2084 *   @brief
2085 *       Compute cmask pitch,width, bytes per 2D slice
2086 *
2087 *   @return
2088 *       BlockMax. Also by output parameters: Cmask pitch,height, total size in bytes,
2089 *       macro-tile dimensions
2090 ***************************************************************************************************
2091 */
ComputeCmaskInfo(ADDR_CMASK_FLAGS flags,UINT_32 pitchIn,UINT_32 heightIn,UINT_32 numSlices,BOOL_32 isLinear,ADDR_TILEINFO * pTileInfo,UINT_32 * pPitchOut,UINT_32 * pHeightOut,UINT_64 * pCmaskBytes,UINT_32 * pMacroWidth,UINT_32 * pMacroHeight,UINT_64 * pSliceSize,UINT_32 * pBaseAlign,UINT_32 * pBlockMax) const2092 ADDR_E_RETURNCODE AddrLib::ComputeCmaskInfo(
2093     ADDR_CMASK_FLAGS flags,            ///< [in] cmask flags
2094     UINT_32          pitchIn,           ///< [in] pitch input
2095     UINT_32          heightIn,          ///< [in] height input
2096     UINT_32          numSlices,         ///< [in] number of slices
2097     BOOL_32          isLinear,          ///< [in] is linear mode
2098     ADDR_TILEINFO*   pTileInfo,         ///< [in] Tile info
2099     UINT_32*         pPitchOut,         ///< [out] pitch output
2100     UINT_32*         pHeightOut,        ///< [out] height output
2101     UINT_64*         pCmaskBytes,       ///< [out] bytes per 2D slice
2102     UINT_32*         pMacroWidth,       ///< [out] macro-tile width in pixels
2103     UINT_32*         pMacroHeight,      ///< [out] macro-tile width in pixels
2104     UINT_64*         pSliceSize,        ///< [out] slice size in bytes
2105     UINT_32*         pBaseAlign,        ///< [out] base alignment
2106     UINT_32*         pBlockMax          ///< [out] block max == slice / 128 / 128 - 1
2107     ) const
2108 {
2109     UINT_32 macroWidth;
2110     UINT_32 macroHeight;
2111     UINT_32 baseAlign;
2112     UINT_64 surfBytes;
2113     UINT_64 sliceBytes;
2114 
2115     numSlices = Max(1u, numSlices);
2116 
2117     const UINT_32 bpp = CmaskElemBits;
2118     const UINT_32 cacheBits = CmaskCacheBits;
2119 
2120     ADDR_E_RETURNCODE returnCode = ADDR_OK;
2121 
2122     if (isLinear)
2123     {
2124         HwlComputeTileDataWidthAndHeightLinear(&macroWidth,
2125                                                &macroHeight,
2126                                                bpp,
2127                                                pTileInfo);
2128     }
2129     else
2130     {
2131         ComputeTileDataWidthAndHeight(bpp,
2132                                       cacheBits,
2133                                       pTileInfo,
2134                                       &macroWidth,
2135                                       &macroHeight);
2136     }
2137 
2138     *pPitchOut = (pitchIn + macroWidth - 1) & ~(macroWidth - 1);
2139     *pHeightOut = (heightIn + macroHeight - 1) & ~(macroHeight - 1);
2140 
2141 
2142     sliceBytes = ComputeCmaskBytes(*pPitchOut,
2143                                    *pHeightOut,
2144                                    1);
2145 
2146     baseAlign = ComputeCmaskBaseAlign(flags, pTileInfo);
2147 
2148     while (sliceBytes % baseAlign)
2149     {
2150         *pHeightOut += macroHeight;
2151 
2152         sliceBytes = ComputeCmaskBytes(*pPitchOut,
2153                                        *pHeightOut,
2154                                        1);
2155     }
2156 
2157     surfBytes = sliceBytes * numSlices;
2158 
2159     *pCmaskBytes = surfBytes;
2160 
2161     //
2162     // Use SafeAssign since they are optional
2163     //
2164     SafeAssign(pMacroWidth, macroWidth);
2165 
2166     SafeAssign(pMacroHeight, macroHeight);
2167 
2168     SafeAssign(pBaseAlign, baseAlign);
2169 
2170     SafeAssign(pSliceSize, sliceBytes);
2171 
2172     UINT_32 slice = (*pPitchOut) * (*pHeightOut);
2173     UINT_32 blockMax = slice / 128 / 128 - 1;
2174 
2175 #if DEBUG
2176     if (slice % (64*256) != 0)
2177     {
2178         ADDR_ASSERT_ALWAYS();
2179     }
2180 #endif //DEBUG
2181 
2182     UINT_32 maxBlockMax = HwlGetMaxCmaskBlockMax();
2183 
2184     if (blockMax > maxBlockMax)
2185     {
2186         blockMax = maxBlockMax;
2187         returnCode = ADDR_INVALIDPARAMS;
2188     }
2189 
2190     SafeAssign(pBlockMax, blockMax);
2191 
2192     return returnCode;
2193 }
2194 
2195 /**
2196 ***************************************************************************************************
2197 *   AddrLib::ComputeXmaskCoordYFromPipe
2198 *
2199 *   @brief
2200 *       Compute the Y coord from pipe number for cmask/htile
2201 *
2202 *   @return
2203 *       Y coordinate
2204 *
2205 ***************************************************************************************************
2206 */
ComputeXmaskCoordYFromPipe(UINT_32 pipe,UINT_32 x) const2207 UINT_32 AddrLib::ComputeXmaskCoordYFromPipe(
2208     UINT_32         pipe,       ///< [in] pipe number
2209     UINT_32         x           ///< [in] x coordinate
2210     ) const
2211 {
2212     UINT_32 pipeBit0;
2213     UINT_32 pipeBit1;
2214     UINT_32 xBit0;
2215     UINT_32 xBit1;
2216     UINT_32 yBit0;
2217     UINT_32 yBit1;
2218 
2219     UINT_32 y = 0;
2220 
2221     UINT_32 numPipes = m_pipes; // SI has its implementation
2222     //
2223     // Convert pipe + x to y coordinate.
2224     //
2225     switch (numPipes)
2226     {
2227         case 1:
2228             //
2229             // 1 pipe
2230             //
2231             // p0 = 0
2232             //
2233             y = 0;
2234             break;
2235         case 2:
2236             //
2237             // 2 pipes
2238             //
2239             // p0 = x0 ^ y0
2240             //
2241             // y0 = p0 ^ x0
2242             //
2243             pipeBit0 = pipe & 0x1;
2244 
2245             xBit0 = x & 0x1;
2246 
2247             yBit0 = pipeBit0 ^ xBit0;
2248 
2249             y = yBit0;
2250             break;
2251         case 4:
2252             //
2253             // 4 pipes
2254             //
2255             // p0 = x1 ^ y0
2256             // p1 = x0 ^ y1
2257             //
2258             // y0 = p0 ^ x1
2259             // y1 = p1 ^ x0
2260             //
2261             pipeBit0 =  pipe & 0x1;
2262             pipeBit1 = (pipe & 0x2) >> 1;
2263 
2264             xBit0 =  x & 0x1;
2265             xBit1 = (x & 0x2) >> 1;
2266 
2267             yBit0 = pipeBit0 ^ xBit1;
2268             yBit1 = pipeBit1 ^ xBit0;
2269 
2270             y = (yBit0 |
2271                  (yBit1 << 1));
2272             break;
2273         case 8:
2274             //
2275             // 8 pipes
2276             //
2277             // r600 and r800 have different method
2278             //
2279             y = HwlComputeXmaskCoordYFrom8Pipe(pipe, x);
2280             break;
2281         default:
2282             break;
2283     }
2284     return y;
2285 }
2286 
2287 /**
2288 ***************************************************************************************************
2289 *   AddrLib::HwlComputeXmaskCoordFromAddr
2290 *
2291 *   @brief
2292 *       Compute the coord from an address of a cmask/htile
2293 *
2294 *   @return
2295 *       N/A
2296 *
2297 *   @note
2298 *       This method is reused by htile, so rename to Xmask
2299 ***************************************************************************************************
2300 */
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) const2301 VOID AddrLib::HwlComputeXmaskCoordFromAddr(
2302     UINT_64         addr,           ///< [in] address
2303     UINT_32         bitPosition,    ///< [in] bitPosition in a byte
2304     UINT_32         pitch,          ///< [in] pitch
2305     UINT_32         height,         ///< [in] height
2306     UINT_32         numSlices,      ///< [in] number of slices
2307     UINT_32         factor,         ///< [in] factor that indicates cmask or htile
2308     BOOL_32         isLinear,       ///< [in] linear or tiled HTILE layout
2309     BOOL_32         isWidth8,       ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2310     BOOL_32         isHeight8,      ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2311     ADDR_TILEINFO*  pTileInfo,      ///< [in] Tile info
2312     UINT_32*        pX,             ///< [out] x coord
2313     UINT_32*        pY,             ///< [out] y coord
2314     UINT_32*        pSlice          ///< [out] slice index
2315     ) const
2316 {
2317     UINT_32 pipe;
2318     UINT_32 numPipes;
2319     UINT_32 numPipeBits;
2320     UINT_32 macroTilePitch;
2321     UINT_32 macroTileHeight;
2322 
2323     UINT_64 bitAddr;
2324 
2325     UINT_32 microTileCoordY;
2326 
2327     UINT_32 elemBits;
2328 
2329     UINT_32 pitchAligned = pitch;
2330     UINT_32 heightAligned = height;
2331     UINT_64 totalBytes;
2332 
2333     UINT_64 elemOffset;
2334 
2335     UINT_64 macroIndex;
2336     UINT_32 microIndex;
2337 
2338     UINT_64 macroNumber;
2339     UINT_32 microNumber;
2340 
2341     UINT_32 macroX;
2342     UINT_32 macroY;
2343     UINT_32 macroZ;
2344 
2345     UINT_32 microX;
2346     UINT_32 microY;
2347 
2348     UINT_32 tilesPerMacro;
2349     UINT_32 macrosPerPitch;
2350     UINT_32 macrosPerSlice;
2351 
2352     //
2353     // Extract pipe.
2354     //
2355     numPipes = HwlGetPipes(pTileInfo);
2356     pipe = ComputePipeFromAddr(addr, numPipes);
2357 
2358     //
2359     // Compute the number of group and pipe bits.
2360     //
2361     numPipeBits  = Log2(numPipes);
2362 
2363     UINT_32 groupBits = 8 * m_pipeInterleaveBytes;
2364     UINT_32 pipes = numPipes;
2365 
2366 
2367     //
2368     // Compute the micro tile size, in bits. And macro tile pitch and height.
2369     //
2370     if (factor == 2) //CMASK
2371     {
2372         ADDR_CMASK_FLAGS flags = {{0}};
2373 
2374         elemBits = CmaskElemBits;
2375 
2376         ComputeCmaskInfo(flags,
2377                          pitch,
2378                          height,
2379                          numSlices,
2380                          isLinear,
2381                          pTileInfo,
2382                          &pitchAligned,
2383                          &heightAligned,
2384                          &totalBytes,
2385                          &macroTilePitch,
2386                          &macroTileHeight);
2387     }
2388     else  //HTILE
2389     {
2390         ADDR_HTILE_FLAGS flags = {{0}};
2391 
2392         if (factor != 1)
2393         {
2394             factor = 1;
2395         }
2396 
2397         elemBits = HwlComputeHtileBpp(isWidth8, isHeight8);
2398 
2399         ComputeHtileInfo(flags,
2400                          pitch,
2401                          height,
2402                          numSlices,
2403                          isLinear,
2404                          isWidth8,
2405                          isHeight8,
2406                          pTileInfo,
2407                          &pitchAligned,
2408                          &heightAligned,
2409                          &totalBytes,
2410                          &macroTilePitch,
2411                          &macroTileHeight);
2412     }
2413 
2414     // Should use aligned dims
2415     //
2416     pitch = pitchAligned;
2417     height = heightAligned;
2418 
2419 
2420     //
2421     // Convert byte address to bit address.
2422     //
2423     bitAddr = BYTES_TO_BITS(addr) + bitPosition;
2424 
2425 
2426     //
2427     // Remove pipe bits from address.
2428     //
2429 
2430     bitAddr = (bitAddr % groupBits) + ((bitAddr/groupBits/pipes)*groupBits);
2431 
2432 
2433     elemOffset = bitAddr / elemBits;
2434 
2435     tilesPerMacro = (macroTilePitch/factor) * macroTileHeight / MicroTilePixels >> numPipeBits;
2436 
2437     macrosPerPitch = pitch / (macroTilePitch/factor);
2438     macrosPerSlice = macrosPerPitch * height / macroTileHeight;
2439 
2440     macroIndex = elemOffset / factor / tilesPerMacro;
2441     microIndex = static_cast<UINT_32>(elemOffset % (tilesPerMacro * factor));
2442 
2443     macroNumber = macroIndex * factor + microIndex % factor;
2444     microNumber = microIndex / factor;
2445 
2446     macroX = static_cast<UINT_32>((macroNumber % macrosPerPitch));
2447     macroY = static_cast<UINT_32>((macroNumber % macrosPerSlice) / macrosPerPitch);
2448     macroZ = static_cast<UINT_32>((macroNumber / macrosPerSlice));
2449 
2450 
2451     microX = microNumber % (macroTilePitch / factor / MicroTileWidth);
2452     microY = (microNumber / (macroTilePitch / factor / MicroTileHeight));
2453 
2454     *pX = macroX * (macroTilePitch/factor) + microX * MicroTileWidth;
2455     *pY = macroY * macroTileHeight + (microY * MicroTileHeight << numPipeBits);
2456     *pSlice = macroZ;
2457 
2458     microTileCoordY = ComputeXmaskCoordYFromPipe(pipe,
2459                                                  *pX/MicroTileWidth);
2460 
2461 
2462     //
2463     // Assemble final coordinates.
2464     //
2465     *pY += microTileCoordY * MicroTileHeight;
2466 
2467 }
2468 
2469 /**
2470 ***************************************************************************************************
2471 *   AddrLib::HwlComputeXmaskAddrFromCoord
2472 *
2473 *   @brief
2474 *       Compute the address from an address of cmask (prior to si)
2475 *
2476 *   @return
2477 *       Address in bytes
2478 *
2479 ***************************************************************************************************
2480 */
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) const2481 UINT_64 AddrLib::HwlComputeXmaskAddrFromCoord(
2482     UINT_32        pitch,          ///< [in] pitch
2483     UINT_32        height,         ///< [in] height
2484     UINT_32        x,              ///< [in] x coord
2485     UINT_32        y,              ///< [in] y coord
2486     UINT_32        slice,          ///< [in] slice/depth index
2487     UINT_32        numSlices,      ///< [in] number of slices
2488     UINT_32        factor,         ///< [in] factor that indicates cmask(2) or htile(1)
2489     BOOL_32        isLinear,       ///< [in] linear or tiled HTILE layout
2490     BOOL_32        isWidth8,       ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2491     BOOL_32        isHeight8,      ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2492     ADDR_TILEINFO* pTileInfo,      ///< [in] Tile info
2493     UINT_32*       pBitPosition    ///< [out] bit position inside a byte
2494     ) const
2495 {
2496     UINT_64 addr;
2497     UINT_32 numGroupBits;
2498     UINT_32 numPipeBits;
2499     UINT_32 newPitch = 0;
2500     UINT_32 newHeight = 0;
2501     UINT_64 sliceBytes = 0;
2502     UINT_64 totalBytes = 0;
2503     UINT_64 sliceOffset;
2504     UINT_32 pipe;
2505     UINT_32 macroTileWidth;
2506     UINT_32 macroTileHeight;
2507     UINT_32 macroTilesPerRow;
2508     UINT_32 macroTileBytes;
2509     UINT_32 macroTileIndexX;
2510     UINT_32 macroTileIndexY;
2511     UINT_64 macroTileOffset;
2512     UINT_32 pixelBytesPerRow;
2513     UINT_32 pixelOffsetX;
2514     UINT_32 pixelOffsetY;
2515     UINT_32 pixelOffset;
2516     UINT_64 totalOffset;
2517     UINT_64 offsetLo;
2518     UINT_64 offsetHi;
2519     UINT_64 groupMask;
2520 
2521 
2522     UINT_32 elemBits = 0;
2523 
2524     UINT_32 numPipes = m_pipes; // This function is accessed prior to si only
2525 
2526     if (factor == 2) //CMASK
2527     {
2528         elemBits = CmaskElemBits;
2529 
2530         // For asics before SI, cmask is always tiled
2531         isLinear = FALSE;
2532     }
2533     else //HTILE
2534     {
2535         if (factor != 1) // Fix compile warning
2536         {
2537             factor = 1;
2538         }
2539 
2540         elemBits = HwlComputeHtileBpp(isWidth8, isHeight8);
2541     }
2542 
2543     //
2544     // Compute the number of group bits and pipe bits.
2545     //
2546     numGroupBits = Log2(m_pipeInterleaveBytes);
2547     numPipeBits  = Log2(numPipes);
2548 
2549     //
2550     // Compute macro tile dimensions.
2551     //
2552     if (factor == 2) // CMASK
2553     {
2554         ADDR_CMASK_FLAGS flags = {{0}};
2555 
2556         ComputeCmaskInfo(flags,
2557                          pitch,
2558                          height,
2559                          numSlices,
2560                          isLinear,
2561                          pTileInfo,
2562                          &newPitch,
2563                          &newHeight,
2564                          &totalBytes,
2565                          &macroTileWidth,
2566                          &macroTileHeight);
2567 
2568         sliceBytes = totalBytes / numSlices;
2569     }
2570     else // HTILE
2571     {
2572         ADDR_HTILE_FLAGS flags = {{0}};
2573 
2574         ComputeHtileInfo(flags,
2575                          pitch,
2576                          height,
2577                          numSlices,
2578                          isLinear,
2579                          isWidth8,
2580                          isHeight8,
2581                          pTileInfo,
2582                          &newPitch,
2583                          &newHeight,
2584                          &totalBytes,
2585                          &macroTileWidth,
2586                          &macroTileHeight,
2587                          &sliceBytes);
2588     }
2589 
2590     sliceOffset = slice * sliceBytes;
2591 
2592     //
2593     // Get the pipe.  Note that neither slice rotation nor pipe swizzling apply for CMASK.
2594     //
2595     pipe = ComputePipeFromCoord(x,
2596                                 y,
2597                                 0,
2598                                 ADDR_TM_2D_TILED_THIN1,
2599                                 0,
2600                                 FALSE,
2601                                 pTileInfo);
2602 
2603     //
2604     // Compute the number of macro tiles per row.
2605     //
2606     macroTilesPerRow = newPitch / macroTileWidth;
2607 
2608     //
2609     // Compute the number of bytes per macro tile.
2610     //
2611     macroTileBytes = BITS_TO_BYTES((macroTileWidth * macroTileHeight * elemBits) / MicroTilePixels);
2612 
2613     //
2614     // Compute the offset to the macro tile containing the specified coordinate.
2615     //
2616     macroTileIndexX = x / macroTileWidth;
2617     macroTileIndexY = y / macroTileHeight;
2618     macroTileOffset = ((macroTileIndexY * macroTilesPerRow) + macroTileIndexX) * macroTileBytes;
2619 
2620     //
2621     // Compute the pixel offset within the macro tile.
2622     //
2623     pixelBytesPerRow = BITS_TO_BYTES(macroTileWidth * elemBits) / MicroTileWidth;
2624 
2625     //
2626     // The nibbles are interleaved (see below), so the part of the offset relative to the x
2627     // coordinate repeats halfway across the row. (Not for HTILE)
2628     //
2629     if (factor == 2)
2630     {
2631         pixelOffsetX = (x % (macroTileWidth / 2)) / MicroTileWidth;
2632     }
2633     else
2634     {
2635         pixelOffsetX = (x % (macroTileWidth)) / MicroTileWidth * BITS_TO_BYTES(elemBits);
2636     }
2637 
2638     //
2639     // Compute the y offset within the macro tile.
2640     //
2641     pixelOffsetY = (((y % macroTileHeight) / MicroTileHeight) / numPipes) * pixelBytesPerRow;
2642 
2643     pixelOffset = pixelOffsetX + pixelOffsetY;
2644 
2645     //
2646     // Combine the slice offset and macro tile offset with the pixel offset, accounting for the
2647     // pipe bits in the middle of the address.
2648     //
2649     totalOffset = ((sliceOffset + macroTileOffset) >> numPipeBits) + pixelOffset;
2650 
2651     //
2652     // Split the offset to put some bits below the pipe bits and some above.
2653     //
2654     groupMask = (1 << numGroupBits) - 1;
2655     offsetLo  = totalOffset &  groupMask;
2656     offsetHi  = (totalOffset & ~groupMask) << numPipeBits;
2657 
2658     //
2659     // Assemble the address from its components.
2660     //
2661     addr  = offsetLo;
2662     addr |= offsetHi;
2663     // This is to remove warning with /analyze option
2664     UINT_32 pipeBits = pipe << numGroupBits;
2665     addr |= pipeBits;
2666 
2667     //
2668     // Compute the bit position.  The lower nibble is used when the x coordinate within the macro
2669     // tile is less than half of the macro tile width, and the upper nibble is used when the x
2670     // coordinate within the macro tile is greater than or equal to half the macro tile width.
2671     //
2672     *pBitPosition = ((x % macroTileWidth) < (macroTileWidth / factor)) ? 0 : 4;
2673 
2674     return addr;
2675 }
2676 
2677 ///////////////////////////////////////////////////////////////////////////////////////////////////
2678 //                               Surface Addressing Shared
2679 ///////////////////////////////////////////////////////////////////////////////////////////////////
2680 
2681 /**
2682 ***************************************************************************************************
2683 *   AddrLib::ComputeSurfaceAddrFromCoordLinear
2684 *
2685 *   @brief
2686 *       Compute address from coord for linear surface
2687 *
2688 *   @return
2689 *       Address in bytes
2690 *
2691 ***************************************************************************************************
2692 */
ComputeSurfaceAddrFromCoordLinear(UINT_32 x,UINT_32 y,UINT_32 slice,UINT_32 sample,UINT_32 bpp,UINT_32 pitch,UINT_32 height,UINT_32 numSlices,UINT_32 * pBitPosition) const2693 UINT_64 AddrLib::ComputeSurfaceAddrFromCoordLinear(
2694     UINT_32  x,              ///< [in] x coord
2695     UINT_32  y,              ///< [in] y coord
2696     UINT_32  slice,          ///< [in] slice/depth index
2697     UINT_32  sample,         ///< [in] sample index
2698     UINT_32  bpp,            ///< [in] bits per pixel
2699     UINT_32  pitch,          ///< [in] pitch
2700     UINT_32  height,         ///< [in] height
2701     UINT_32  numSlices,      ///< [in] number of slices
2702     UINT_32* pBitPosition    ///< [out] bit position inside a byte
2703     ) const
2704 {
2705     const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height;
2706 
2707     UINT_64 sliceOffset = (slice + sample * numSlices)* sliceSize;
2708     UINT_64 rowOffset   = static_cast<UINT_64>(y) * pitch;
2709     UINT_64 pixOffset   = x;
2710 
2711     UINT_64 addr = (sliceOffset + rowOffset + pixOffset) * bpp;
2712 
2713     *pBitPosition = static_cast<UINT_32>(addr % 8);
2714     addr /= 8;
2715 
2716     return addr;
2717 }
2718 
2719 /**
2720 ***************************************************************************************************
2721 *   AddrLib::ComputeSurfaceCoordFromAddrLinear
2722 *
2723 *   @brief
2724 *       Compute the coord from an address of a linear surface
2725 *
2726 *   @return
2727 *       N/A
2728 ***************************************************************************************************
2729 */
ComputeSurfaceCoordFromAddrLinear(UINT_64 addr,UINT_32 bitPosition,UINT_32 bpp,UINT_32 pitch,UINT_32 height,UINT_32 numSlices,UINT_32 * pX,UINT_32 * pY,UINT_32 * pSlice,UINT_32 * pSample) const2730 VOID AddrLib::ComputeSurfaceCoordFromAddrLinear(
2731     UINT_64  addr,           ///< [in] address
2732     UINT_32  bitPosition,    ///< [in] bitPosition in a byte
2733     UINT_32  bpp,            ///< [in] bits per pixel
2734     UINT_32  pitch,          ///< [in] pitch
2735     UINT_32  height,         ///< [in] height
2736     UINT_32  numSlices,      ///< [in] number of slices
2737     UINT_32* pX,             ///< [out] x coord
2738     UINT_32* pY,             ///< [out] y coord
2739     UINT_32* pSlice,         ///< [out] slice/depth index
2740     UINT_32* pSample         ///< [out] sample index
2741     ) const
2742 {
2743     const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height;
2744     const UINT_64 linearOffset = (BYTES_TO_BITS(addr) + bitPosition) / bpp;
2745 
2746     *pX = static_cast<UINT_32>((linearOffset % sliceSize) % pitch);
2747     *pY = static_cast<UINT_32>((linearOffset % sliceSize) / pitch % height);
2748     *pSlice  = static_cast<UINT_32>((linearOffset / sliceSize) % numSlices);
2749     *pSample = static_cast<UINT_32>((linearOffset / sliceSize) / numSlices);
2750 }
2751 
2752 /**
2753 ***************************************************************************************************
2754 *   AddrLib::ComputeSurfaceCoordFromAddrMicroTiled
2755 *
2756 *   @brief
2757 *       Compute the coord from an address of a micro tiled surface
2758 *
2759 *   @return
2760 *       N/A
2761 ***************************************************************************************************
2762 */
ComputeSurfaceCoordFromAddrMicroTiled(UINT_64 addr,UINT_32 bitPosition,UINT_32 bpp,UINT_32 pitch,UINT_32 height,UINT_32 numSamples,AddrTileMode tileMode,UINT_32 tileBase,UINT_32 compBits,UINT_32 * pX,UINT_32 * pY,UINT_32 * pSlice,UINT_32 * pSample,AddrTileType microTileType,BOOL_32 isDepthSampleOrder) const2763 VOID AddrLib::ComputeSurfaceCoordFromAddrMicroTiled(
2764     UINT_64         addr,               ///< [in] address
2765     UINT_32         bitPosition,        ///< [in] bitPosition in a byte
2766     UINT_32         bpp,                ///< [in] bits per pixel
2767     UINT_32         pitch,              ///< [in] pitch
2768     UINT_32         height,             ///< [in] height
2769     UINT_32         numSamples,         ///< [in] number of samples
2770     AddrTileMode    tileMode,           ///< [in] tile mode
2771     UINT_32         tileBase,           ///< [in] base offset within a tile
2772     UINT_32         compBits,           ///< [in] component bits actually needed(for planar surface)
2773     UINT_32*        pX,                 ///< [out] x coord
2774     UINT_32*        pY,                 ///< [out] y coord
2775     UINT_32*        pSlice,             ///< [out] slice/depth index
2776     UINT_32*        pSample,            ///< [out] sample index,
2777     AddrTileType    microTileType,      ///< [in] micro tiling order
2778     BOOL_32         isDepthSampleOrder  ///< [in] TRUE if in depth sample order
2779     ) const
2780 {
2781     UINT_64 bitAddr;
2782     UINT_32 microTileThickness;
2783     UINT_32 microTileBits;
2784     UINT_64 sliceBits;
2785     UINT_64 rowBits;
2786     UINT_32 sliceIndex;
2787     UINT_32 microTileCoordX;
2788     UINT_32 microTileCoordY;
2789     UINT_32 pixelOffset;
2790     UINT_32 pixelCoordX = 0;
2791     UINT_32 pixelCoordY = 0;
2792     UINT_32 pixelCoordZ = 0;
2793     UINT_32 pixelCoordS = 0;
2794 
2795     //
2796     // Convert byte address to bit address.
2797     //
2798     bitAddr = BYTES_TO_BITS(addr) + bitPosition;
2799 
2800     //
2801     // Compute the micro tile size, in bits.
2802     //
2803     switch (tileMode)
2804     {
2805         case ADDR_TM_1D_TILED_THICK:
2806             microTileThickness = ThickTileThickness;
2807             break;
2808         default:
2809             microTileThickness = 1;
2810             break;
2811     }
2812 
2813     microTileBits = MicroTilePixels * microTileThickness * bpp * numSamples;
2814 
2815     //
2816     // Compute number of bits per slice and number of bits per row of micro tiles.
2817     //
2818     sliceBits = static_cast<UINT_64>(pitch) * height * microTileThickness * bpp * numSamples;
2819 
2820     rowBits   = (pitch / MicroTileWidth) * microTileBits;
2821 
2822     //
2823     // Extract the slice index.
2824     //
2825     sliceIndex = static_cast<UINT_32>(bitAddr / sliceBits);
2826     bitAddr -= sliceIndex * sliceBits;
2827 
2828     //
2829     // Extract the y coordinate of the micro tile.
2830     //
2831     microTileCoordY = static_cast<UINT_32>(bitAddr / rowBits) * MicroTileHeight;
2832     bitAddr -= (microTileCoordY / MicroTileHeight) * rowBits;
2833 
2834     //
2835     // Extract the x coordinate of the micro tile.
2836     //
2837     microTileCoordX = static_cast<UINT_32>(bitAddr / microTileBits) * MicroTileWidth;
2838 
2839     //
2840     // Compute the pixel offset within the micro tile.
2841     //
2842     pixelOffset = static_cast<UINT_32>(bitAddr % microTileBits);
2843 
2844     //
2845     // Extract pixel coordinates from the offset.
2846     //
2847     HwlComputePixelCoordFromOffset(pixelOffset,
2848                                    bpp,
2849                                    numSamples,
2850                                    tileMode,
2851                                    tileBase,
2852                                    compBits,
2853                                    &pixelCoordX,
2854                                    &pixelCoordY,
2855                                    &pixelCoordZ,
2856                                    &pixelCoordS,
2857                                    microTileType,
2858                                    isDepthSampleOrder);
2859 
2860     //
2861     // Assemble final coordinates.
2862     //
2863     *pX     = microTileCoordX + pixelCoordX;
2864     *pY     = microTileCoordY + pixelCoordY;
2865     *pSlice = (sliceIndex * microTileThickness) + pixelCoordZ;
2866     *pSample = pixelCoordS;
2867 
2868     if (microTileThickness > 1)
2869     {
2870         *pSample = 0;
2871     }
2872 }
2873 
2874 /**
2875 ***************************************************************************************************
2876 *   AddrLib::ComputePipeFromAddr
2877 *
2878 *   @brief
2879 *       Compute the pipe number from an address
2880 *
2881 *   @return
2882 *       Pipe number
2883 *
2884 ***************************************************************************************************
2885 */
ComputePipeFromAddr(UINT_64 addr,UINT_32 numPipes) const2886 UINT_32 AddrLib::ComputePipeFromAddr(
2887     UINT_64 addr,        ///< [in] address
2888     UINT_32 numPipes     ///< [in] number of banks
2889     ) const
2890 {
2891     UINT_32 pipe;
2892 
2893     UINT_32 groupBytes = m_pipeInterleaveBytes; //just different terms
2894 
2895     // R600
2896     // The LSBs of the address are arranged as follows:
2897     //   bank | pipe | group
2898     //
2899     // To get the pipe number, shift off the group bits and mask the pipe bits.
2900     //
2901 
2902     // R800
2903     // The LSBs of the address are arranged as follows:
2904     //   bank | bankInterleave | pipe | pipeInterleave
2905     //
2906     // To get the pipe number, shift off the pipe interleave bits and mask the pipe bits.
2907     //
2908 
2909     pipe = static_cast<UINT_32>(addr >> Log2(groupBytes)) & (numPipes - 1);
2910 
2911     return pipe;
2912 }
2913 
2914 /**
2915 ***************************************************************************************************
2916 *   AddrLib::ComputePixelIndexWithinMicroTile
2917 *
2918 *   @brief
2919 *       Compute the pixel index inside a micro tile of surface
2920 *
2921 *   @return
2922 *       Pixel index
2923 *
2924 ***************************************************************************************************
2925 */
ComputePixelIndexWithinMicroTile(UINT_32 x,UINT_32 y,UINT_32 z,UINT_32 bpp,AddrTileMode tileMode,AddrTileType microTileType) const2926 UINT_32 AddrLib::ComputePixelIndexWithinMicroTile(
2927     UINT_32         x,              ///< [in] x coord
2928     UINT_32         y,              ///< [in] y coord
2929     UINT_32         z,              ///< [in] slice/depth index
2930     UINT_32         bpp,            ///< [in] bits per pixel
2931     AddrTileMode    tileMode,       ///< [in] tile mode
2932     AddrTileType    microTileType   ///< [in] pixel order in display/non-display mode
2933     ) const
2934 {
2935     UINT_32 pixelBit0 = 0;
2936     UINT_32 pixelBit1 = 0;
2937     UINT_32 pixelBit2 = 0;
2938     UINT_32 pixelBit3 = 0;
2939     UINT_32 pixelBit4 = 0;
2940     UINT_32 pixelBit5 = 0;
2941     UINT_32 pixelBit6 = 0;
2942     UINT_32 pixelBit7 = 0;
2943     UINT_32 pixelBit8 = 0;
2944     UINT_32 pixelNumber;
2945 
2946     UINT_32 x0 = _BIT(x, 0);
2947     UINT_32 x1 = _BIT(x, 1);
2948     UINT_32 x2 = _BIT(x, 2);
2949     UINT_32 y0 = _BIT(y, 0);
2950     UINT_32 y1 = _BIT(y, 1);
2951     UINT_32 y2 = _BIT(y, 2);
2952     UINT_32 z0 = _BIT(z, 0);
2953     UINT_32 z1 = _BIT(z, 1);
2954     UINT_32 z2 = _BIT(z, 2);
2955 
2956     UINT_32 thickness = ComputeSurfaceThickness(tileMode);
2957 
2958     // Compute the pixel number within the micro tile.
2959 
2960     if (microTileType != ADDR_THICK)
2961     {
2962         if (microTileType == ADDR_DISPLAYABLE)
2963         {
2964             switch (bpp)
2965             {
2966                 case 8:
2967                     pixelBit0 = x0;
2968                     pixelBit1 = x1;
2969                     pixelBit2 = x2;
2970                     pixelBit3 = y1;
2971                     pixelBit4 = y0;
2972                     pixelBit5 = y2;
2973                     break;
2974                 case 16:
2975                     pixelBit0 = x0;
2976                     pixelBit1 = x1;
2977                     pixelBit2 = x2;
2978                     pixelBit3 = y0;
2979                     pixelBit4 = y1;
2980                     pixelBit5 = y2;
2981                     break;
2982                 case 32:
2983                     pixelBit0 = x0;
2984                     pixelBit1 = x1;
2985                     pixelBit2 = y0;
2986                     pixelBit3 = x2;
2987                     pixelBit4 = y1;
2988                     pixelBit5 = y2;
2989                     break;
2990                 case 64:
2991                     pixelBit0 = x0;
2992                     pixelBit1 = y0;
2993                     pixelBit2 = x1;
2994                     pixelBit3 = x2;
2995                     pixelBit4 = y1;
2996                     pixelBit5 = y2;
2997                     break;
2998                 case 128:
2999                     pixelBit0 = y0;
3000                     pixelBit1 = x0;
3001                     pixelBit2 = x1;
3002                     pixelBit3 = x2;
3003                     pixelBit4 = y1;
3004                     pixelBit5 = y2;
3005                     break;
3006                 default:
3007                     ADDR_ASSERT_ALWAYS();
3008                     break;
3009             }
3010         }
3011         else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER)
3012         {
3013             pixelBit0 = x0;
3014             pixelBit1 = y0;
3015             pixelBit2 = x1;
3016             pixelBit3 = y1;
3017             pixelBit4 = x2;
3018             pixelBit5 = y2;
3019         }
3020         else if (microTileType == ADDR_ROTATED)
3021         {
3022             ADDR_ASSERT(thickness == 1);
3023 
3024             switch (bpp)
3025             {
3026                 case 8:
3027                     pixelBit0 = y0;
3028                     pixelBit1 = y1;
3029                     pixelBit2 = y2;
3030                     pixelBit3 = x1;
3031                     pixelBit4 = x0;
3032                     pixelBit5 = x2;
3033                     break;
3034                 case 16:
3035                     pixelBit0 = y0;
3036                     pixelBit1 = y1;
3037                     pixelBit2 = y2;
3038                     pixelBit3 = x0;
3039                     pixelBit4 = x1;
3040                     pixelBit5 = x2;
3041                     break;
3042                 case 32:
3043                     pixelBit0 = y0;
3044                     pixelBit1 = y1;
3045                     pixelBit2 = x0;
3046                     pixelBit3 = y2;
3047                     pixelBit4 = x1;
3048                     pixelBit5 = x2;
3049                     break;
3050                 case 64:
3051                     pixelBit0 = y0;
3052                     pixelBit1 = x0;
3053                     pixelBit2 = y1;
3054                     pixelBit3 = x1;
3055                     pixelBit4 = x2;
3056                     pixelBit5 = y2;
3057                     break;
3058                 default:
3059                     ADDR_ASSERT_ALWAYS();
3060                     break;
3061             }
3062         }
3063 
3064         if (thickness > 1)
3065         {
3066             pixelBit6 = z0;
3067             pixelBit7 = z1;
3068         }
3069     }
3070     else // ADDR_THICK
3071     {
3072         ADDR_ASSERT(thickness > 1);
3073 
3074         switch (bpp)
3075         {
3076             case 8:
3077             case 16:
3078                 pixelBit0 = x0;
3079                 pixelBit1 = y0;
3080                 pixelBit2 = x1;
3081                 pixelBit3 = y1;
3082                 pixelBit4 = z0;
3083                 pixelBit5 = z1;
3084                 break;
3085             case 32:
3086                 pixelBit0 = x0;
3087                 pixelBit1 = y0;
3088                 pixelBit2 = x1;
3089                 pixelBit3 = z0;
3090                 pixelBit4 = y1;
3091                 pixelBit5 = z1;
3092                 break;
3093             case 64:
3094             case 128:
3095                 pixelBit0 = y0;
3096                 pixelBit1 = x0;
3097                 pixelBit2 = z0;
3098                 pixelBit3 = x1;
3099                 pixelBit4 = y1;
3100                 pixelBit5 = z1;
3101                 break;
3102             default:
3103                 ADDR_ASSERT_ALWAYS();
3104                 break;
3105         }
3106 
3107         pixelBit6 = x2;
3108         pixelBit7 = y2;
3109     }
3110 
3111     if (thickness == 8)
3112     {
3113         pixelBit8 = z2;
3114     }
3115 
3116     pixelNumber = ((pixelBit0     ) |
3117                    (pixelBit1 << 1) |
3118                    (pixelBit2 << 2) |
3119                    (pixelBit3 << 3) |
3120                    (pixelBit4 << 4) |
3121                    (pixelBit5 << 5) |
3122                    (pixelBit6 << 6) |
3123                    (pixelBit7 << 7) |
3124                    (pixelBit8 << 8));
3125 
3126     return pixelNumber;
3127 }
3128 
3129 /**
3130 ***************************************************************************************************
3131 *   AddrLib::AdjustPitchAlignment
3132 *
3133 *   @brief
3134 *       Adjusts pitch alignment for flipping surface
3135 *
3136 *   @return
3137 *       N/A
3138 *
3139 ***************************************************************************************************
3140 */
AdjustPitchAlignment(ADDR_SURFACE_FLAGS flags,UINT_32 * pPitchAlign) const3141 VOID AddrLib::AdjustPitchAlignment(
3142     ADDR_SURFACE_FLAGS  flags,      ///< [in] Surface flags
3143     UINT_32*            pPitchAlign ///< [out] Pointer to pitch alignment
3144     ) const
3145 {
3146     // Display engine hardwires lower 5 bit of GRPH_PITCH to ZERO which means 32 pixel alignment
3147     // Maybe it will be fixed in future but let's make it general for now.
3148     if (flags.display || flags.overlay)
3149     {
3150         *pPitchAlign = PowTwoAlign(*pPitchAlign, 32);
3151 
3152         if(flags.display)
3153         {
3154             *pPitchAlign = Max(m_minPitchAlignPixels, *pPitchAlign);
3155         }
3156     }
3157 }
3158 
3159 /**
3160 ***************************************************************************************************
3161 *   AddrLib::PadDimensions
3162 *
3163 *   @brief
3164 *       Helper function to pad dimensions
3165 *
3166 *   @return
3167 *       N/A
3168 *
3169 ***************************************************************************************************
3170 */
PadDimensions(AddrTileMode tileMode,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 numSamples,ADDR_TILEINFO * pTileInfo,UINT_32 padDims,UINT_32 mipLevel,UINT_32 * pPitch,UINT_32 pitchAlign,UINT_32 * pHeight,UINT_32 heightAlign,UINT_32 * pSlices,UINT_32 sliceAlign) const3171 VOID AddrLib::PadDimensions(
3172     AddrTileMode        tileMode,    ///< [in] tile mode
3173     UINT_32             bpp,         ///< [in] bits per pixel
3174     ADDR_SURFACE_FLAGS  flags,       ///< [in] surface flags
3175     UINT_32             numSamples,  ///< [in] number of samples
3176     ADDR_TILEINFO*      pTileInfo,   ///< [in/out] bank structure.
3177     UINT_32             padDims,     ///< [in] Dimensions to pad valid value 1,2,3
3178     UINT_32             mipLevel,    ///< [in] MipLevel
3179     UINT_32*            pPitch,      ///< [in/out] pitch in pixels
3180     UINT_32             pitchAlign,  ///< [in] pitch alignment
3181     UINT_32*            pHeight,     ///< [in/out] height in pixels
3182     UINT_32             heightAlign, ///< [in] height alignment
3183     UINT_32*            pSlices,     ///< [in/out] number of slices
3184     UINT_32             sliceAlign   ///< [in] number of slice alignment
3185     ) const
3186 {
3187     UINT_32 thickness = ComputeSurfaceThickness(tileMode);
3188 
3189     ADDR_ASSERT(padDims <= 3);
3190 
3191     //
3192     // Override padding for mip levels
3193     //
3194     if (mipLevel > 0)
3195     {
3196         if (flags.cube)
3197         {
3198             // for cubemap, we only pad when client call with 6 faces as an identity
3199             if (*pSlices > 1)
3200             {
3201                 padDims = 3; // we should pad cubemap sub levels when we treat it as 3d texture
3202             }
3203             else
3204             {
3205                 padDims = 2;
3206             }
3207         }
3208     }
3209 
3210     // Any possibilities that padDims is 0?
3211     if (padDims == 0)
3212     {
3213         padDims = 3;
3214     }
3215 
3216     if (IsPow2(pitchAlign))
3217     {
3218         *pPitch = PowTwoAlign((*pPitch), pitchAlign);
3219     }
3220     else // add this code to pass unit test, r600 linear mode is not align bpp to pow2 for linear
3221     {
3222         *pPitch += pitchAlign - 1;
3223         *pPitch /= pitchAlign;
3224         *pPitch *= pitchAlign;
3225     }
3226 
3227     if (padDims > 1)
3228     {
3229         *pHeight = PowTwoAlign((*pHeight), heightAlign);
3230     }
3231 
3232     if (padDims > 2 || thickness > 1)
3233     {
3234         // for cubemap single face, we do not pad slices.
3235         // if we pad it, the slice number should be set to 6 and current mip level > 1
3236         if (flags.cube && (!m_configFlags.noCubeMipSlicesPad || flags.cubeAsArray))
3237         {
3238             *pSlices = NextPow2(*pSlices);
3239         }
3240 
3241         // normal 3D texture or arrays or cubemap has a thick mode? (Just pass unit test)
3242         if (thickness > 1)
3243         {
3244             *pSlices = PowTwoAlign((*pSlices), sliceAlign);
3245         }
3246 
3247     }
3248 
3249     HwlPadDimensions(tileMode,
3250                      bpp,
3251                      flags,
3252                      numSamples,
3253                      pTileInfo,
3254                      padDims,
3255                      mipLevel,
3256                      pPitch,
3257                      pitchAlign,
3258                      pHeight,
3259                      heightAlign,
3260                      pSlices,
3261                      sliceAlign);
3262 }
3263 
3264 
3265 /**
3266 ***************************************************************************************************
3267 *   AddrLib::HwlPreHandleBaseLvl3xPitch
3268 *
3269 *   @brief
3270 *       Pre-handler of 3x pitch (96 bit) adjustment
3271 *
3272 *   @return
3273 *       Expected pitch
3274 ***************************************************************************************************
3275 */
HwlPreHandleBaseLvl3xPitch(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,UINT_32 expPitch) const3276 UINT_32 AddrLib::HwlPreHandleBaseLvl3xPitch(
3277     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] input
3278     UINT_32                                 expPitch    ///< [in] pitch
3279     ) const
3280 {
3281     ADDR_ASSERT(pIn->width == expPitch);
3282     //
3283     // If pitch is pre-multiplied by 3, we retrieve original one here to get correct miplevel size
3284     //
3285     if (AddrElemLib::IsExpand3x(pIn->format) &&
3286         pIn->mipLevel == 0 &&
3287         pIn->tileMode == ADDR_TM_LINEAR_ALIGNED)
3288     {
3289         expPitch /= 3;
3290         expPitch = NextPow2(expPitch);
3291     }
3292 
3293     return expPitch;
3294 }
3295 
3296 /**
3297 ***************************************************************************************************
3298 *   AddrLib::HwlPostHandleBaseLvl3xPitch
3299 *
3300 *   @brief
3301 *       Post-handler of 3x pitch adjustment
3302 *
3303 *   @return
3304 *       Expected pitch
3305 ***************************************************************************************************
3306 */
HwlPostHandleBaseLvl3xPitch(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,UINT_32 expPitch) const3307 UINT_32 AddrLib::HwlPostHandleBaseLvl3xPitch(
3308     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] input
3309     UINT_32                                 expPitch    ///< [in] pitch
3310     ) const
3311 {
3312     //
3313     // 96 bits surface of sub levels require element pitch of 32 bits instead
3314     // So we just return pitch in 32 bit pixels without timing 3
3315     //
3316     if (AddrElemLib::IsExpand3x(pIn->format) &&
3317         pIn->mipLevel == 0 &&
3318         pIn->tileMode == ADDR_TM_LINEAR_ALIGNED)
3319     {
3320         expPitch *= 3;
3321     }
3322 
3323     return expPitch;
3324 }
3325 
3326 
3327 /**
3328 ***************************************************************************************************
3329 *   AddrLib::IsMacroTiled
3330 *
3331 *   @brief
3332 *       Check if the tile mode is macro tiled
3333 *
3334 *   @return
3335 *       TRUE if it is macro tiled (2D/2B/3D/3B)
3336 ***************************************************************************************************
3337 */
IsMacroTiled(AddrTileMode tileMode)3338 BOOL_32 AddrLib::IsMacroTiled(
3339     AddrTileMode tileMode)  ///< [in] tile mode
3340 {
3341    return m_modeFlags[tileMode].isMacro;
3342 }
3343 
3344 /**
3345 ***************************************************************************************************
3346 *   AddrLib::IsMacro3dTiled
3347 *
3348 *   @brief
3349 *       Check if the tile mode is 3D macro tiled
3350 *
3351 *   @return
3352 *       TRUE if it is 3D macro tiled
3353 ***************************************************************************************************
3354 */
IsMacro3dTiled(AddrTileMode tileMode)3355 BOOL_32 AddrLib::IsMacro3dTiled(
3356     AddrTileMode tileMode)  ///< [in] tile mode
3357 {
3358     return m_modeFlags[tileMode].isMacro3d;
3359 }
3360 
3361 /**
3362 ***************************************************************************************************
3363 *   AddrLib::IsMicroTiled
3364 *
3365 *   @brief
3366 *       Check if the tile mode is micro tiled
3367 *
3368 *   @return
3369 *       TRUE if micro tiled
3370 ***************************************************************************************************
3371 */
IsMicroTiled(AddrTileMode tileMode)3372 BOOL_32 AddrLib::IsMicroTiled(
3373     AddrTileMode tileMode)  ///< [in] tile mode
3374 {
3375     return m_modeFlags[tileMode].isMicro;
3376 }
3377 
3378 /**
3379 ***************************************************************************************************
3380 *   AddrLib::IsLinear
3381 *
3382 *   @brief
3383 *       Check if the tile mode is linear
3384 *
3385 *   @return
3386 *       TRUE if linear
3387 ***************************************************************************************************
3388 */
IsLinear(AddrTileMode tileMode)3389 BOOL_32 AddrLib::IsLinear(
3390     AddrTileMode tileMode)  ///< [in] tile mode
3391 {
3392     return m_modeFlags[tileMode].isLinear;
3393 }
3394 
3395 /**
3396 ***************************************************************************************************
3397 *   AddrLib::IsPrtNoRotationTileMode
3398 *
3399 *   @brief
3400 *       Return TRUE if it is prt tile without rotation
3401 *   @note
3402 *       This function just used by CI
3403 ***************************************************************************************************
3404 */
IsPrtNoRotationTileMode(AddrTileMode tileMode)3405 BOOL_32 AddrLib::IsPrtNoRotationTileMode(
3406     AddrTileMode tileMode)
3407 {
3408     return m_modeFlags[tileMode].isPrtNoRotation;
3409 }
3410 
3411 /**
3412 ***************************************************************************************************
3413 *   AddrLib::IsPrtTileMode
3414 *
3415 *   @brief
3416 *       Return TRUE if it is prt tile
3417 *   @note
3418 *       This function just used by CI
3419 ***************************************************************************************************
3420 */
IsPrtTileMode(AddrTileMode tileMode)3421 BOOL_32 AddrLib::IsPrtTileMode(
3422     AddrTileMode tileMode)
3423 {
3424     return m_modeFlags[tileMode].isPrt;
3425 }
3426 
3427 /**
3428 ***************************************************************************************************
3429 *   AddrLib::Bits2Number
3430 *
3431 *   @brief
3432 *       Cat a array of binary bit to a number
3433 *
3434 *   @return
3435 *       The number combined with the array of bits
3436 ***************************************************************************************************
3437 */
Bits2Number(UINT_32 bitNum,...)3438 UINT_32 AddrLib::Bits2Number(
3439     UINT_32 bitNum,     ///< [in] how many bits
3440     ...)                ///< [in] varaible bits value starting from MSB
3441 {
3442     UINT_32 number = 0;
3443     UINT_32 i;
3444     va_list bits_ptr;
3445 
3446     va_start(bits_ptr, bitNum);
3447 
3448     for(i = 0; i < bitNum; i++)
3449     {
3450         number |= va_arg(bits_ptr, UINT_32);
3451         number <<= 1;
3452     }
3453 
3454     number>>=1;
3455 
3456     va_end(bits_ptr);
3457 
3458     return number;
3459 }
3460 
3461 /**
3462 ***************************************************************************************************
3463 *   AddrLib::ComputeMipLevel
3464 *
3465 *   @brief
3466 *       Compute mipmap level width/height/slices
3467 *   @return
3468 *      N/A
3469 ***************************************************************************************************
3470 */
ComputeMipLevel(ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn) const3471 VOID AddrLib::ComputeMipLevel(
3472     ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in/out] Input structure
3473     ) const
3474 {
3475     if (AddrElemLib::IsBlockCompressed(pIn->format))
3476     {
3477         if (pIn->mipLevel == 0)
3478         {
3479             // DXTn's level 0 must be multiple of 4
3480             // But there are exceptions:
3481             // 1. Internal surface creation in hostblt/vsblt/etc...
3482             // 2. Runtime doesn't reject ATI1/ATI2 whose width/height are not multiple of 4
3483             pIn->width = PowTwoAlign(pIn->width, 4);
3484             pIn->height = PowTwoAlign(pIn->height, 4);
3485         }
3486     }
3487 
3488     HwlComputeMipLevel(pIn);
3489 }
3490 
3491 /**
3492 ***************************************************************************************************
3493 *   AddrLib::DegradeBaseLevel
3494 *
3495 *   @brief
3496 *       Check if base level's tile mode can be degraded
3497 *   @return
3498 *       TRUE if degraded, also returns degraded tile mode (unchanged if not degraded)
3499 ***************************************************************************************************
3500 */
DegradeBaseLevel(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,AddrTileMode * pTileMode) const3501 BOOL_32 AddrLib::DegradeBaseLevel(
3502     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] Input structure for surface info
3503     AddrTileMode*                           pTileMode   ///< [out] Degraded tile mode
3504     ) const
3505 {
3506     BOOL_32 degraded = FALSE;
3507     AddrTileMode tileMode = pIn->tileMode;
3508     UINT_32 thickness = ComputeSurfaceThickness(tileMode);
3509 
3510     if (m_configFlags.degradeBaseLevel) // This is a global setting
3511     {
3512         if (pIn->flags.degrade4Space        && // Degradation per surface
3513             pIn->mipLevel == 0              &&
3514             pIn->numSamples == 1            &&
3515             IsMacroTiled(tileMode))
3516         {
3517             if (HwlDegradeBaseLevel(pIn))
3518             {
3519                 *pTileMode = thickness == 1 ? ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
3520                 degraded = TRUE;
3521             }
3522             else if (thickness > 1)
3523             {
3524                 // As in the following HwlComputeSurfaceInfo, thick modes may be degraded to
3525                 // thinner modes, we should re-evaluate whether the corresponding thinner modes
3526                 // need to be degraded. If so, we choose 1D thick mode instead.
3527                 tileMode = DegradeLargeThickTile(pIn->tileMode, pIn->bpp);
3528                 if (tileMode != pIn->tileMode)
3529                 {
3530                     ADDR_COMPUTE_SURFACE_INFO_INPUT input = *pIn;
3531                     input.tileMode = tileMode;
3532                     if (HwlDegradeBaseLevel(&input))
3533                     {
3534                         *pTileMode = ADDR_TM_1D_TILED_THICK;
3535                         degraded = TRUE;
3536                     }
3537                 }
3538             }
3539         }
3540     }
3541 
3542     return degraded;
3543 }
3544 
3545 /**
3546 ***************************************************************************************************
3547 *   AddrLib::DegradeLargeThickTile
3548 *
3549 *   @brief
3550 *       Check if the thickness needs to be reduced if a tile is too large
3551 *   @return
3552 *       The degraded tile mode (unchanged if not degraded)
3553 ***************************************************************************************************
3554 */
DegradeLargeThickTile(AddrTileMode tileMode,UINT_32 bpp) const3555 AddrTileMode AddrLib::DegradeLargeThickTile(
3556     AddrTileMode tileMode,
3557     UINT_32 bpp) const
3558 {
3559     // Override tilemode
3560     // When tile_width (8) * tile_height (8) * thickness * element_bytes is > row_size,
3561     // it is better to just use THIN mode in this case
3562     UINT_32 thickness = ComputeSurfaceThickness(tileMode);
3563 
3564     if (thickness > 1 && m_configFlags.allowLargeThickTile == 0)
3565     {
3566         UINT_32 tileSize = MicroTilePixels * thickness * (bpp >> 3);
3567 
3568         if (tileSize > m_rowSize)
3569         {
3570             switch (tileMode)
3571             {
3572                 case ADDR_TM_2D_TILED_XTHICK:
3573                     if ((tileSize >> 1) <= m_rowSize)
3574                     {
3575                         tileMode = ADDR_TM_2D_TILED_THICK;
3576                         break;
3577                     }
3578                     // else fall through
3579                 case ADDR_TM_2D_TILED_THICK:
3580                     tileMode    = ADDR_TM_2D_TILED_THIN1;
3581                     break;
3582 
3583                 case ADDR_TM_3D_TILED_XTHICK:
3584                     if ((tileSize >> 1) <= m_rowSize)
3585                     {
3586                         tileMode = ADDR_TM_3D_TILED_THICK;
3587                         break;
3588                     }
3589                     // else fall through
3590                 case ADDR_TM_3D_TILED_THICK:
3591                     tileMode    = ADDR_TM_3D_TILED_THIN1;
3592                     break;
3593 
3594                 case ADDR_TM_PRT_TILED_THICK:
3595                     tileMode    = ADDR_TM_PRT_TILED_THIN1;
3596                     break;
3597 
3598                 case ADDR_TM_PRT_2D_TILED_THICK:
3599                     tileMode    = ADDR_TM_PRT_2D_TILED_THIN1;
3600                     break;
3601 
3602                 case ADDR_TM_PRT_3D_TILED_THICK:
3603                     tileMode    = ADDR_TM_PRT_3D_TILED_THIN1;
3604                     break;
3605 
3606                 default:
3607                     break;
3608             }
3609         }
3610     }
3611 
3612     return tileMode;
3613 }
3614 
3615 /**
3616 ***************************************************************************************************
3617 *   AddrLib::PostComputeMipLevel
3618 *   @brief
3619 *       Compute MipLevel info (including level 0) after surface adjustment
3620 *   @return
3621 *       ADDR_E_RETURNCODE
3622 ***************************************************************************************************
3623 */
PostComputeMipLevel(ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const3624 ADDR_E_RETURNCODE AddrLib::PostComputeMipLevel(
3625     ADDR_COMPUTE_SURFACE_INFO_INPUT*    pIn,   ///< [in/out] Input structure
3626     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*   pOut   ///< [out] Output structure
3627     ) const
3628 {
3629     // Mipmap including level 0 must be pow2 padded since either SI hw expects so or it is
3630     // required by CFX  for Hw Compatibility between NI and SI. Otherwise it is only needed for
3631     // mipLevel > 0. Any h/w has different requirement should implement its own virtual function
3632 
3633     if (pIn->flags.pow2Pad)
3634     {
3635         pIn->width      = NextPow2(pIn->width);
3636         pIn->height     = NextPow2(pIn->height);
3637         pIn->numSlices  = NextPow2(pIn->numSlices);
3638     }
3639     else if (pIn->mipLevel > 0)
3640     {
3641         pIn->width      = NextPow2(pIn->width);
3642         pIn->height     = NextPow2(pIn->height);
3643 
3644         if (!pIn->flags.cube)
3645         {
3646             pIn->numSlices = NextPow2(pIn->numSlices);
3647         }
3648 
3649         // for cubemap, we keep its value at first
3650     }
3651 
3652     return ADDR_OK;
3653 }
3654 
3655 /**
3656 ***************************************************************************************************
3657 *   AddrLib::HwlSetupTileCfg
3658 *
3659 *   @brief
3660 *       Map tile index to tile setting.
3661 *   @return
3662 *       ADDR_E_RETURNCODE
3663 ***************************************************************************************************
3664 */
HwlSetupTileCfg(INT_32 index,INT_32 macroModeIndex,ADDR_TILEINFO * pInfo,AddrTileMode * pMode,AddrTileType * pType) const3665 ADDR_E_RETURNCODE AddrLib::HwlSetupTileCfg(
3666     INT_32          index,            ///< [in] Tile index
3667     INT_32          macroModeIndex,   ///< [in] Index in macro tile mode table(CI)
3668     ADDR_TILEINFO*  pInfo,            ///< [out] Tile Info
3669     AddrTileMode*   pMode,            ///< [out] Tile mode
3670     AddrTileType*   pType             ///< [out] Tile type
3671     ) const
3672 {
3673     return ADDR_NOTSUPPORTED;
3674 }
3675 
3676 /**
3677 ***************************************************************************************************
3678 *   AddrLib::HwlGetPipes
3679 *
3680 *   @brief
3681 *       Get number pipes
3682 *   @return
3683 *       num pipes
3684 ***************************************************************************************************
3685 */
HwlGetPipes(const ADDR_TILEINFO * pTileInfo) const3686 UINT_32 AddrLib::HwlGetPipes(
3687     const ADDR_TILEINFO* pTileInfo    ///< [in] Tile info
3688     ) const
3689 {
3690     //pTileInfo can be NULL when asic is 6xx and 8xx.
3691     return m_pipes;
3692 }
3693 
3694 /**
3695 ***************************************************************************************************
3696 *   AddrLib::ComputeQbStereoInfo
3697 *
3698 *   @brief
3699 *       Get quad buffer stereo information
3700 *   @return
3701 *       TRUE if no error
3702 ***************************************************************************************************
3703 */
ComputeQbStereoInfo(ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const3704 BOOL_32 AddrLib::ComputeQbStereoInfo(
3705     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [in/out] updated pOut+pStereoInfo
3706     ) const
3707 {
3708     BOOL_32 success = FALSE;
3709 
3710     if (pOut->pStereoInfo)
3711     {
3712         ADDR_ASSERT(pOut->bpp >= 8);
3713         ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0);
3714 
3715         // Save original height
3716         pOut->pStereoInfo->eyeHeight = pOut->height;
3717 
3718         // Right offset
3719         pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize);
3720 
3721         pOut->pStereoInfo->rightSwizzle = HwlComputeQbStereoRightSwizzle(pOut);
3722         // Double height
3723         pOut->height <<= 1;
3724         pOut->pixelHeight <<= 1;
3725 
3726         // Double size
3727         pOut->surfSize <<= 1;
3728 
3729         // Right start address meets the base align since it is guaranteed by AddrLib
3730 
3731         // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo.
3732         success = TRUE;
3733     }
3734 
3735     return success;
3736 }
3737 
3738 ///////////////////////////////////////////////////////////////////////////////////////////////////
3739 //                               Element lib
3740 ///////////////////////////////////////////////////////////////////////////////////////////////////
3741 
3742 
3743 /**
3744 ***************************************************************************************************
3745 *   AddrLib::Flt32ToColorPixel
3746 *
3747 *   @brief
3748 *       Convert a FLT_32 value to a depth/stencil pixel value
3749 *   @return
3750 *       ADDR_E_RETURNCODE
3751 ***************************************************************************************************
3752 */
Flt32ToDepthPixel(const ELEM_FLT32TODEPTHPIXEL_INPUT * pIn,ELEM_FLT32TODEPTHPIXEL_OUTPUT * pOut) const3753 ADDR_E_RETURNCODE AddrLib::Flt32ToDepthPixel(
3754     const ELEM_FLT32TODEPTHPIXEL_INPUT* pIn,
3755     ELEM_FLT32TODEPTHPIXEL_OUTPUT* pOut) const
3756 {
3757     ADDR_E_RETURNCODE returnCode = ADDR_OK;
3758 
3759     if (GetFillSizeFieldsFlags() == TRUE)
3760     {
3761         if ((pIn->size != sizeof(ELEM_FLT32TODEPTHPIXEL_INPUT)) ||
3762             (pOut->size != sizeof(ELEM_FLT32TODEPTHPIXEL_OUTPUT)))
3763         {
3764             returnCode = ADDR_PARAMSIZEMISMATCH;
3765         }
3766     }
3767 
3768     if (returnCode == ADDR_OK)
3769     {
3770         GetElemLib()->Flt32ToDepthPixel(pIn->format,
3771                                         pIn->comps,
3772                                         pOut->pPixel);
3773         UINT_32 depthBase = 0;
3774         UINT_32 stencilBase = 0;
3775         UINT_32 depthBits = 0;
3776         UINT_32 stencilBits = 0;
3777 
3778         switch (pIn->format)
3779         {
3780             case ADDR_DEPTH_16:
3781                 depthBits = 16;
3782                 break;
3783             case ADDR_DEPTH_X8_24:
3784             case ADDR_DEPTH_8_24:
3785             case ADDR_DEPTH_X8_24_FLOAT:
3786             case ADDR_DEPTH_8_24_FLOAT:
3787                 depthBase = 8;
3788                 depthBits = 24;
3789                 stencilBits = 8;
3790                 break;
3791             case ADDR_DEPTH_32_FLOAT:
3792                 depthBits = 32;
3793                 break;
3794             case ADDR_DEPTH_X24_8_32_FLOAT:
3795                 depthBase = 8;
3796                 depthBits = 32;
3797                 stencilBits = 8;
3798                 break;
3799             default:
3800                 break;
3801         }
3802 
3803         // Overwrite base since R800 has no "tileBase"
3804         if (GetElemLib()->IsDepthStencilTilePlanar() == FALSE)
3805         {
3806             depthBase = 0;
3807             stencilBase = 0;
3808         }
3809 
3810         depthBase *= 64;
3811         stencilBase *= 64;
3812 
3813         pOut->stencilBase = stencilBase;
3814         pOut->depthBase = depthBase;
3815         pOut->depthBits = depthBits;
3816         pOut->stencilBits = stencilBits;
3817     }
3818 
3819     return returnCode;
3820 }
3821 
3822 /**
3823 ***************************************************************************************************
3824 *   AddrLib::Flt32ToColorPixel
3825 *
3826 *   @brief
3827 *       Convert a FLT_32 value to a red/green/blue/alpha pixel value
3828 *   @return
3829 *       ADDR_E_RETURNCODE
3830 ***************************************************************************************************
3831 */
Flt32ToColorPixel(const ELEM_FLT32TOCOLORPIXEL_INPUT * pIn,ELEM_FLT32TOCOLORPIXEL_OUTPUT * pOut) const3832 ADDR_E_RETURNCODE AddrLib::Flt32ToColorPixel(
3833     const ELEM_FLT32TOCOLORPIXEL_INPUT* pIn,
3834     ELEM_FLT32TOCOLORPIXEL_OUTPUT* pOut) const
3835 {
3836     ADDR_E_RETURNCODE returnCode = ADDR_OK;
3837 
3838     if (GetFillSizeFieldsFlags() == TRUE)
3839     {
3840         if ((pIn->size != sizeof(ELEM_FLT32TOCOLORPIXEL_INPUT)) ||
3841             (pOut->size != sizeof(ELEM_FLT32TOCOLORPIXEL_OUTPUT)))
3842         {
3843             returnCode = ADDR_PARAMSIZEMISMATCH;
3844         }
3845     }
3846 
3847     if (returnCode == ADDR_OK)
3848     {
3849         GetElemLib()->Flt32ToColorPixel(pIn->format,
3850                                         pIn->surfNum,
3851                                         pIn->surfSwap,
3852                                         pIn->comps,
3853                                         pOut->pPixel);
3854     }
3855 
3856     return returnCode;
3857 }
3858 
3859 
3860 /**
3861 ***************************************************************************************************
3862 *   AddrLib::GetExportNorm
3863 *
3864 *   @brief
3865 *       Check one format can be EXPORT_NUM
3866 *   @return
3867 *       TRUE if EXPORT_NORM can be used
3868 ***************************************************************************************************
3869 */
GetExportNorm(const ELEM_GETEXPORTNORM_INPUT * pIn) const3870 BOOL_32 AddrLib::GetExportNorm(
3871     const ELEM_GETEXPORTNORM_INPUT* pIn) const
3872 {
3873     ADDR_E_RETURNCODE returnCode = ADDR_OK;
3874 
3875     BOOL_32 enabled = FALSE;
3876 
3877     if (GetFillSizeFieldsFlags() == TRUE)
3878     {
3879         if (pIn->size != sizeof(ELEM_GETEXPORTNORM_INPUT))
3880         {
3881             returnCode = ADDR_PARAMSIZEMISMATCH;
3882         }
3883     }
3884 
3885     if (returnCode == ADDR_OK)
3886     {
3887         enabled = GetElemLib()->PixGetExportNorm(pIn->format,
3888                                                  pIn->num,
3889                                                  pIn->swap);
3890     }
3891 
3892     return enabled;
3893 }
3894 
3895 /**
3896 ***************************************************************************************************
3897 *   AddrLib::ComputePrtInfo
3898 *
3899 *   @brief
3900 *       Compute prt surface related info
3901 *
3902 *   @return
3903 *       ADDR_E_RETURNCODE
3904 ***************************************************************************************************
3905 */
ComputePrtInfo(const ADDR_PRT_INFO_INPUT * pIn,ADDR_PRT_INFO_OUTPUT * pOut) const3906 ADDR_E_RETURNCODE AddrLib::ComputePrtInfo(
3907     const ADDR_PRT_INFO_INPUT*  pIn,
3908     ADDR_PRT_INFO_OUTPUT*       pOut) const
3909 {
3910     ADDR_ASSERT(pOut != NULL);
3911 
3912     ADDR_E_RETURNCODE returnCode = ADDR_OK;
3913 
3914     UINT_32     expandX = 1;
3915     UINT_32     expandY = 1;
3916     AddrElemMode elemMode;
3917 
3918     UINT_32     bpp = GetElemLib()->GetBitsPerPixel(pIn->format,
3919                                                 &elemMode,
3920                                                 &expandX,
3921                                                 &expandY);
3922 
3923     if (bpp <8 || bpp == 24 || bpp == 48 || bpp == 96 )
3924     {
3925         returnCode = ADDR_INVALIDPARAMS;
3926     }
3927 
3928     UINT_32     numFrags = pIn->numFrags;
3929     ADDR_ASSERT(numFrags <= 8);
3930 
3931     UINT_32     tileWidth = 0;
3932     UINT_32     tileHeight = 0;
3933     if (returnCode == ADDR_OK)
3934     {
3935         // 3D texture without depth or 2d texture
3936         if (pIn->baseMipDepth > 1 || pIn->baseMipHeight > 1)
3937         {
3938             if (bpp == 8)
3939             {
3940                 tileWidth = 256;
3941                 tileHeight = 256;
3942             }
3943             else if (bpp == 16)
3944             {
3945                 tileWidth = 256;
3946                 tileHeight = 128;
3947             }
3948             else if (bpp == 32)
3949             {
3950                 tileWidth = 128;
3951                 tileHeight = 128;
3952             }
3953             else if (bpp == 64)
3954             {
3955                 // assume it is BC1/4
3956                 tileWidth = 512;
3957                 tileHeight = 256;
3958 
3959                 if (elemMode == ADDR_UNCOMPRESSED)
3960                 {
3961                     tileWidth = 128;
3962                     tileHeight = 64;
3963                 }
3964             }
3965             else if (bpp == 128)
3966             {
3967                 // assume it is BC2/3/5/6H/7
3968                 tileWidth = 256;
3969                 tileHeight = 256;
3970 
3971                 if (elemMode == ADDR_UNCOMPRESSED)
3972                 {
3973                     tileWidth = 64;
3974                     tileHeight = 64;
3975                 }
3976             }
3977 
3978             if (numFrags == 2)
3979             {
3980                 tileWidth = tileWidth / 2;
3981             }
3982             else if (numFrags == 4)
3983             {
3984                 tileWidth = tileWidth / 2;
3985                 tileHeight = tileHeight / 2;
3986             }
3987             else if (numFrags == 8)
3988             {
3989                 tileWidth = tileWidth / 4;
3990                 tileHeight = tileHeight / 2;
3991             }
3992         }
3993         else    // 1d
3994         {
3995             tileHeight = 1;
3996             if (bpp == 8)
3997             {
3998                 tileWidth = 65536;
3999             }
4000             else if (bpp == 16)
4001             {
4002                 tileWidth = 32768;
4003             }
4004             else if (bpp == 32)
4005             {
4006                 tileWidth = 16384;
4007             }
4008             else if (bpp == 64)
4009             {
4010                 tileWidth = 8192;
4011             }
4012             else if (bpp == 128)
4013             {
4014                 tileWidth = 4096;
4015             }
4016         }
4017     }
4018 
4019     pOut->prtTileWidth = tileWidth;
4020     pOut->prtTileHeight = tileHeight;
4021 
4022     return returnCode;
4023 }
4024