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