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