• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ************************************************************************************************************************
3 *
4 *  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.
5 *  SPDX-License-Identifier: MIT
6 *
7 ***********************************************************************************************************************/
8 
9 
10 /**
11 ************************************************************************************************************************
12 * @file  addrlib2.cpp
13 * @brief Contains the implementation for the AddrLib2 base class.
14 ************************************************************************************************************************
15 */
16 
17 #include "addrinterface.h"
18 #include "addrlib2.h"
19 #include "addrcommon.h"
20 
21 namespace Addr
22 {
23 namespace V2
24 {
25 
26 ////////////////////////////////////////////////////////////////////////////////////////////////////
27 //                               Static Const Member
28 ////////////////////////////////////////////////////////////////////////////////////////////////////
29 
30 const Dim2d Lib::Block256_2d[] = {{16, 16}, {16, 8}, {8, 8}, {8, 4}, {4, 4}};
31 
32 const Dim3d Lib::Block1K_3d[]  = {{16, 8, 8}, {8, 8, 8}, {8, 8, 4}, {8, 4, 4}, {4, 4, 4}};
33 
34 ////////////////////////////////////////////////////////////////////////////////////////////////////
35 //                               Constructor/Destructor
36 ////////////////////////////////////////////////////////////////////////////////////////////////////
37 
38 /**
39 ************************************************************************************************************************
40 *   Lib::Lib
41 *
42 *   @brief
43 *       Constructor for the Addr::V2::Lib class
44 *
45 ************************************************************************************************************************
46 */
Lib()47 Lib::Lib()
48     :
49     Addr::Lib(),
50     m_se(0),
51     m_rbPerSe(0),
52     m_maxCompFrag(0),
53     m_banksLog2(0),
54     m_pipesLog2(0),
55     m_seLog2(0),
56     m_rbPerSeLog2(0),
57     m_maxCompFragLog2(0),
58     m_pipeInterleaveLog2(0),
59     m_blockVarSizeLog2(0),
60     m_numEquations(0)
61 {
62 }
63 
64 /**
65 ************************************************************************************************************************
66 *   Lib::Lib
67 *
68 *   @brief
69 *       Constructor for the AddrLib2 class with hClient as parameter
70 *
71 ************************************************************************************************************************
72 */
Lib(const Client * pClient)73 Lib::Lib(const Client* pClient)
74     :
75     Addr::Lib(pClient),
76     m_se(0),
77     m_rbPerSe(0),
78     m_maxCompFrag(0),
79     m_banksLog2(0),
80     m_pipesLog2(0),
81     m_seLog2(0),
82     m_rbPerSeLog2(0),
83     m_maxCompFragLog2(0),
84     m_pipeInterleaveLog2(0),
85     m_blockVarSizeLog2(0),
86     m_numEquations(0)
87 {
88 }
89 
90 /**
91 ************************************************************************************************************************
92 *   Lib::~Lib
93 *
94 *   @brief
95 *       Destructor for the AddrLib2 class
96 *
97 ************************************************************************************************************************
98 */
~Lib()99 Lib::~Lib()
100 {
101 }
102 
103 /**
104 ************************************************************************************************************************
105 *   Lib::GetLib
106 *
107 *   @brief
108 *       Get Addr::V2::Lib pointer
109 *
110 *   @return
111 *      An Addr::V2::Lib class pointer
112 ************************************************************************************************************************
113 */
GetLib(ADDR_HANDLE hLib)114 Lib* Lib::GetLib(
115     ADDR_HANDLE hLib)   ///< [in] handle of ADDR_HANDLE
116 {
117     Addr::Lib* pAddrLib = Addr::Lib::GetLib(hLib);
118     if ((pAddrLib != NULL) &&
119         (pAddrLib->GetChipFamily() <= ADDR_CHIP_FAMILY_VI))
120     {
121         // only valid and GFX9+ ASIC can use AddrLib2 function.
122         ADDR_ASSERT_ALWAYS();
123         hLib = NULL;
124     }
125     return static_cast<Lib*>(hLib);
126 }
127 
128 
129 ////////////////////////////////////////////////////////////////////////////////////////////////////
130 //                               Surface Methods
131 ////////////////////////////////////////////////////////////////////////////////////////////////////
132 
133 
134 /**
135 ************************************************************************************************************************
136 *   Lib::ComputeSurfaceInfo
137 *
138 *   @brief
139 *       Interface function stub of AddrComputeSurfaceInfo.
140 *
141 *   @return
142 *       ADDR_E_RETURNCODE
143 ************************************************************************************************************************
144 */
ComputeSurfaceInfo(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const145 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(
146      const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
147      ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure
148      ) const
149 {
150     ADDR_E_RETURNCODE returnCode = ADDR_OK;
151 
152     if (GetFillSizeFieldsFlags() == TRUE)
153     {
154         if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT)) ||
155             (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT)))
156         {
157             returnCode = ADDR_PARAMSIZEMISMATCH;
158         }
159     }
160 
161     // Adjust coming parameters.
162     ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;
163     localIn.width        = Max(pIn->width, 1u);
164     localIn.height       = Max(pIn->height, 1u);
165     localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
166     localIn.numSlices    = Max(pIn->numSlices, 1u);
167     localIn.numSamples   = Max(pIn->numSamples, 1u);
168     localIn.numFrags     = (localIn.numFrags == 0) ? localIn.numSamples : pIn->numFrags;
169 
170     UINT_32  expandX  = 1;
171     UINT_32  expandY  = 1;
172     ElemMode elemMode = ADDR_UNCOMPRESSED;
173 
174     if (returnCode == ADDR_OK)
175     {
176         // Set format to INVALID will skip this conversion
177         if (localIn.format != ADDR_FMT_INVALID)
178         {
179             // Get compression/expansion factors and element mode which indicates compression/expansion
180             localIn.bpp = GetElemLib()->GetBitsPerPixel(localIn.format,
181                                                         &elemMode,
182                                                         &expandX,
183                                                         &expandY);
184 
185             // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
186             // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
187             // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
188             // restrictions are different.
189             // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
190             // but we use this flag to skip RestoreSurfaceInfo below
191 
192             if ((elemMode == ADDR_EXPANDED) && (expandX > 1))
193             {
194                 ADDR_ASSERT(IsLinear(localIn.swizzleMode));
195             }
196 
197             UINT_32 basePitch = 0;
198             GetElemLib()->AdjustSurfaceInfo(elemMode,
199                                             expandX,
200                                             expandY,
201                                             &localIn.bpp,
202                                             &basePitch,
203                                             &localIn.width,
204                                             &localIn.height);
205 
206             // Overwrite these parameters if we have a valid format
207         }
208 
209         if (localIn.bpp != 0)
210         {
211             localIn.width  = Max(localIn.width, 1u);
212             localIn.height = Max(localIn.height, 1u);
213         }
214         else // Rule out some invalid parameters
215         {
216             ADDR_ASSERT_ALWAYS();
217 
218             returnCode = ADDR_INVALIDPARAMS;
219         }
220     }
221 
222     if (returnCode == ADDR_OK)
223     {
224         returnCode = ComputeSurfaceInfoSanityCheck(&localIn);
225     }
226 
227     if (returnCode == ADDR_OK)
228     {
229         VerifyMipLevelInfo(pIn);
230 
231         if (IsLinear(pIn->swizzleMode))
232         {
233             // linear mode
234             returnCode = ComputeSurfaceInfoLinear(&localIn, pOut);
235         }
236         else
237         {
238             // tiled mode
239             returnCode = ComputeSurfaceInfoTiled(&localIn, pOut);
240         }
241 
242         if (returnCode == ADDR_OK)
243         {
244             pOut->bpp = localIn.bpp;
245             pOut->pixelPitch = pOut->pitch;
246             pOut->pixelHeight = pOut->height;
247             pOut->pixelMipChainPitch = pOut->mipChainPitch;
248             pOut->pixelMipChainHeight = pOut->mipChainHeight;
249             pOut->pixelBits = localIn.bpp;
250 
251             if (localIn.format != ADDR_FMT_INVALID)
252             {
253                 UINT_32 pixelBits = pOut->pixelBits;
254 
255                 GetElemLib()->RestoreSurfaceInfo(elemMode,
256                                                  expandX,
257                                                  expandY,
258                                                  &pOut->pixelBits,
259                                                  &pOut->pixelPitch,
260                                                  &pOut->pixelHeight);
261 
262                 GetElemLib()->RestoreSurfaceInfo(elemMode,
263                                                  expandX,
264                                                  expandY,
265                                                  &pixelBits,
266                                                  &pOut->pixelMipChainPitch,
267                                                  &pOut->pixelMipChainHeight);
268 
269                 if ((localIn.numMipLevels > 1) && (pOut->pMipInfo != NULL))
270                 {
271                     for (UINT_32 i = 0; i < localIn.numMipLevels; i++)
272                     {
273                         pOut->pMipInfo[i].pixelPitch  = pOut->pMipInfo[i].pitch;
274                         pOut->pMipInfo[i].pixelHeight = pOut->pMipInfo[i].height;
275 
276                         GetElemLib()->RestoreSurfaceInfo(elemMode,
277                                                          expandX,
278                                                          expandY,
279                                                          &pixelBits,
280                                                          &pOut->pMipInfo[i].pixelPitch,
281                                                          &pOut->pMipInfo[i].pixelHeight);
282                     }
283                 }
284             }
285 
286             if (localIn.flags.needEquation && (Log2(localIn.numFrags) == 0))
287             {
288                 pOut->equationIndex = GetEquationIndex(&localIn, pOut);
289                 if ((localIn.flags.allowExtEquation == 0) &&
290                     (pOut->equationIndex != ADDR_INVALID_EQUATION_INDEX) &&
291                     (m_equationTable[pOut->equationIndex].numBitComponents > ADDR_MAX_LEGACY_EQUATION_COMP))
292                 {
293                     pOut->equationIndex = ADDR_INVALID_EQUATION_INDEX;
294                 }
295             }
296 
297             if (localIn.flags.qbStereo)
298             {
299                 if (pOut->pStereoInfo != NULL)
300                 {
301                     ComputeQbStereoInfo(pOut);
302 #if DEBUG
303                     ValidateStereoInfo(pIn, pOut);
304 #endif
305                 }
306             }
307         }
308     }
309 
310     ADDR_ASSERT(pOut->surfSize != 0);
311 
312     ValidBaseAlignments(pOut->baseAlign);
313 
314     return returnCode;
315 }
316 
317 /**
318 ************************************************************************************************************************
319 *   Lib::ComputeSurfaceInfo
320 *
321 *   @brief
322 *       Interface function stub of AddrComputeSurfaceInfo.
323 *
324 *   @return
325 *       ADDR_E_RETURNCODE
326 ************************************************************************************************************************
327 */
ComputeSurfaceAddrFromCoord(const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const328 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord(
329     const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
330     ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
331     ) const
332 {
333     ADDR_E_RETURNCODE returnCode = ADDR_OK;
334 
335     if (GetFillSizeFieldsFlags() == TRUE)
336     {
337         if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) ||
338             (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT)))
339         {
340             returnCode = ADDR_PARAMSIZEMISMATCH;
341         }
342     }
343 
344     ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT localIn = *pIn;
345     localIn.unalignedWidth  = Max(pIn->unalignedWidth, 1u);
346     localIn.unalignedHeight = Max(pIn->unalignedHeight, 1u);
347     localIn.numMipLevels    = Max(pIn->numMipLevels, 1u);
348     localIn.numSlices       = Max(pIn->numSlices, 1u);
349     localIn.numSamples      = Max(pIn->numSamples, 1u);
350     localIn.numFrags        = Max(pIn->numFrags, 1u);
351 
352     if ((localIn.bpp < 8)        ||
353         (localIn.bpp > 128)      ||
354         ((localIn.bpp % 8) != 0) ||
355         (localIn.sample >= localIn.numSamples)  ||
356         (localIn.slice >= localIn.numSlices)    ||
357         (localIn.mipId >= localIn.numMipLevels) ||
358         (IsTex3d(localIn.resourceType) &&
359          (Valid3DMipSliceIdConstraint(localIn.numSlices, localIn.mipId, localIn.slice) == FALSE)))
360     {
361         returnCode = ADDR_INVALIDPARAMS;
362     }
363 
364     if (returnCode == ADDR_OK)
365     {
366         if (IsLinear(localIn.swizzleMode))
367         {
368             returnCode = ComputeSurfaceAddrFromCoordLinear(&localIn, pOut);
369         }
370         else
371         {
372             returnCode = ComputeSurfaceAddrFromCoordTiled(&localIn, pOut);
373         }
374 
375         if (returnCode == ADDR_OK)
376         {
377             pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024));
378         }
379     }
380 
381     return returnCode;
382 }
383 
384 /**
385 ************************************************************************************************************************
386 *   Lib::ComputeSurfaceCoordFromAddr
387 *
388 *   @brief
389 *       Interface function stub of ComputeSurfaceCoordFromAddr.
390 *
391 *   @return
392 *       ADDR_E_RETURNCODE
393 ************************************************************************************************************************
394 */
ComputeSurfaceCoordFromAddr(const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT * pIn,ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT * pOut) const395 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddr(
396     const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure
397     ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure
398     ) const
399 {
400     ADDR_E_RETURNCODE returnCode = ADDR_OK;
401 
402     if (GetFillSizeFieldsFlags() == TRUE)
403     {
404         if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) ||
405             (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT)))
406         {
407             returnCode = ADDR_PARAMSIZEMISMATCH;
408         }
409     }
410 
411     if ((pIn->bpp < 8)        ||
412         (pIn->bpp > 128)      ||
413         ((pIn->bpp % 8) != 0) ||
414         (pIn->bitPosition >= 8))
415     {
416         returnCode = ADDR_INVALIDPARAMS;
417     }
418 
419     if (returnCode == ADDR_OK)
420     {
421         if (IsLinear(pIn->swizzleMode))
422         {
423             returnCode = ComputeSurfaceCoordFromAddrLinear(pIn, pOut);
424         }
425         else
426         {
427             returnCode = ComputeSurfaceCoordFromAddrTiled(pIn, pOut);
428         }
429     }
430 
431     return returnCode;
432 }
433 
434 
435 ////////////////////////////////////////////////////////////////////////////////////////////////////
436 //                               CMASK/HTILE
437 ////////////////////////////////////////////////////////////////////////////////////////////////////
438 
439 /**
440 ************************************************************************************************************************
441 *   Lib::ComputeHtileInfo
442 *
443 *   @brief
444 *       Interface function stub of AddrComputeHtilenfo
445 *
446 *   @return
447 *       ADDR_E_RETURNCODE
448 ************************************************************************************************************************
449 */
ComputeHtileInfo(const ADDR2_COMPUTE_HTILE_INFO_INPUT * pIn,ADDR2_COMPUTE_HTILE_INFO_OUTPUT * pOut) const450 ADDR_E_RETURNCODE Lib::ComputeHtileInfo(
451     const ADDR2_COMPUTE_HTILE_INFO_INPUT*    pIn,    ///< [in] input structure
452     ADDR2_COMPUTE_HTILE_INFO_OUTPUT*         pOut    ///< [out] output structure
453     ) const
454 {
455     ADDR_E_RETURNCODE returnCode;
456 
457     if ((GetFillSizeFieldsFlags() == TRUE) &&
458         ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT)) ||
459          (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT))))
460     {
461         returnCode = ADDR_INVALIDPARAMS;
462     }
463     else
464     {
465         returnCode = HwlComputeHtileInfo(pIn, pOut);
466 
467         ValidMetaBaseAlignments(pOut->baseAlign);
468     }
469 
470     return returnCode;
471 }
472 
473 /**
474 ************************************************************************************************************************
475 *   Lib::ComputeHtileAddrFromCoord
476 *
477 *   @brief
478 *       Interface function stub of AddrComputeHtileAddrFromCoord
479 *
480 *   @return
481 *       ADDR_E_RETURNCODE
482 ************************************************************************************************************************
483 */
ComputeHtileAddrFromCoord(const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT * pOut)484 ADDR_E_RETURNCODE Lib::ComputeHtileAddrFromCoord(
485     const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
486     ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*        pOut)   ///< [out] output structure
487 {
488     ADDR_E_RETURNCODE returnCode;
489 
490     if ((GetFillSizeFieldsFlags() == TRUE) &&
491         ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) ||
492          (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT))))
493     {
494         returnCode = ADDR_INVALIDPARAMS;
495     }
496     else
497     {
498         returnCode = HwlComputeHtileAddrFromCoord(pIn, pOut);
499     }
500 
501     return returnCode;
502 }
503 
504 /**
505 ************************************************************************************************************************
506 *   Lib::ComputeHtileCoordFromAddr
507 *
508 *   @brief
509 *       Interface function stub of AddrComputeHtileCoordFromAddr
510 *
511 *   @return
512 *       ADDR_E_RETURNCODE
513 ************************************************************************************************************************
514 */
ComputeHtileCoordFromAddr(const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT * pIn,ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT * pOut)515 ADDR_E_RETURNCODE Lib::ComputeHtileCoordFromAddr(
516     const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure
517     ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*        pOut)   ///< [out] output structure
518 {
519     ADDR_E_RETURNCODE returnCode;
520 
521     if ((GetFillSizeFieldsFlags() == TRUE) &&
522         ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT)) ||
523          (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT))))
524     {
525         returnCode = ADDR_INVALIDPARAMS;
526     }
527     else
528     {
529         returnCode = HwlComputeHtileCoordFromAddr(pIn, pOut);
530     }
531 
532     return returnCode;
533 }
534 
535 /**
536 ************************************************************************************************************************
537 *   Lib::ComputeCmaskInfo
538 *
539 *   @brief
540 *       Interface function stub of AddrComputeCmaskInfo
541 *
542 *   @return
543 *       ADDR_E_RETURNCODE
544 ************************************************************************************************************************
545 */
ComputeCmaskInfo(const ADDR2_COMPUTE_CMASK_INFO_INPUT * pIn,ADDR2_COMPUTE_CMASK_INFO_OUTPUT * pOut) const546 ADDR_E_RETURNCODE Lib::ComputeCmaskInfo(
547     const ADDR2_COMPUTE_CMASK_INFO_INPUT*    pIn,    ///< [in] input structure
548     ADDR2_COMPUTE_CMASK_INFO_OUTPUT*         pOut    ///< [out] output structure
549     ) const
550 {
551     ADDR_E_RETURNCODE returnCode;
552 
553     if ((GetFillSizeFieldsFlags() == TRUE) &&
554         ((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT)) ||
555          (pOut->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT))))
556     {
557         returnCode = ADDR_INVALIDPARAMS;
558     }
559     else if (pIn->cMaskFlags.linear)
560     {
561         returnCode = ADDR_INVALIDPARAMS;
562     }
563     else
564     {
565         returnCode = HwlComputeCmaskInfo(pIn, pOut);
566 
567         ValidMetaBaseAlignments(pOut->baseAlign);
568     }
569 
570     return returnCode;
571 }
572 
573 /**
574 ************************************************************************************************************************
575 *   Lib::ComputeCmaskAddrFromCoord
576 *
577 *   @brief
578 *       Interface function stub of AddrComputeCmaskAddrFromCoord
579 *
580 *   @return
581 *       ADDR_E_RETURNCODE
582 ************************************************************************************************************************
583 */
ComputeCmaskAddrFromCoord(const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT * pOut)584 ADDR_E_RETURNCODE Lib::ComputeCmaskAddrFromCoord(
585     const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
586     ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*        pOut)   ///< [out] output structure
587 {
588     ADDR_E_RETURNCODE returnCode;
589 
590     if ((GetFillSizeFieldsFlags() == TRUE) &&
591         ((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) ||
592          (pOut->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT))))
593     {
594         returnCode = ADDR_INVALIDPARAMS;
595     }
596     else
597     {
598         returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut);
599     }
600 
601     return returnCode;
602 }
603 
604 /**
605 ************************************************************************************************************************
606 *   Lib::ComputeCmaskCoordFromAddr
607 *
608 *   @brief
609 *       Interface function stub of AddrComputeCmaskCoordFromAddr
610 *
611 *   @return
612 *       ADDR_E_RETURNCODE
613 ************************************************************************************************************************
614 */
ComputeCmaskCoordFromAddr(const ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT * pIn,ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT * pOut) const615 ADDR_E_RETURNCODE Lib::ComputeCmaskCoordFromAddr(
616     const ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure
617     ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT*        pOut    ///< [out] output structure
618     ) const
619 {
620     ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
621 
622     ADDR_NOT_IMPLEMENTED();
623 
624     return returnCode;
625 }
626 
627 /**
628 ************************************************************************************************************************
629 *   Lib::ComputeFmaskInfo
630 *
631 *   @brief
632 *       Interface function stub of ComputeFmaskInfo.
633 *
634 *   @return
635 *       ADDR_E_RETURNCODE
636 ************************************************************************************************************************
637 */
ComputeFmaskInfo(const ADDR2_COMPUTE_FMASK_INFO_INPUT * pIn,ADDR2_COMPUTE_FMASK_INFO_OUTPUT * pOut)638 ADDR_E_RETURNCODE Lib::ComputeFmaskInfo(
639     const ADDR2_COMPUTE_FMASK_INFO_INPUT*    pIn,    ///< [in] input structure
640     ADDR2_COMPUTE_FMASK_INFO_OUTPUT*         pOut    ///< [out] output structure
641     )
642 {
643     ADDR_E_RETURNCODE returnCode;
644 
645     BOOL_32 valid = (IsZOrderSwizzle(pIn->swizzleMode) == TRUE) &&
646                     ((pIn->numSamples > 0) || (pIn->numFrags > 0));
647 
648     if (GetFillSizeFieldsFlags())
649     {
650         if ((pIn->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT)) ||
651             (pOut->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT)))
652         {
653             valid = FALSE;
654         }
655     }
656 
657     if (valid == FALSE)
658     {
659         returnCode = ADDR_INVALIDPARAMS;
660     }
661     else
662     {
663         ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn = {0};
664         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
665 
666         localIn.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT);
667         localOut.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT);
668 
669         localIn.swizzleMode  = pIn->swizzleMode;
670         localIn.numSlices    = Max(pIn->numSlices, 1u);
671         localIn.width        = Max(pIn->unalignedWidth, 1u);
672         localIn.height       = Max(pIn->unalignedHeight, 1u);
673         localIn.bpp          = GetFmaskBpp(pIn->numSamples, pIn->numFrags);
674         localIn.flags.fmask  = 1;
675         localIn.numFrags     = 1;
676         localIn.numSamples   = 1;
677         localIn.resourceType = ADDR_RSRC_TEX_2D;
678 
679         if (localIn.bpp == 8)
680         {
681             localIn.format = ADDR_FMT_8;
682         }
683         else if (localIn.bpp == 16)
684         {
685             localIn.format = ADDR_FMT_16;
686         }
687         else if (localIn.bpp == 32)
688         {
689             localIn.format = ADDR_FMT_32;
690         }
691         else
692         {
693             localIn.format = ADDR_FMT_32_32;
694         }
695 
696         returnCode = ComputeSurfaceInfo(&localIn, &localOut);
697 
698         if (returnCode == ADDR_OK)
699         {
700             pOut->pitch      = localOut.pitch;
701             pOut->height     = localOut.height;
702             pOut->baseAlign  = localOut.baseAlign;
703             pOut->numSlices  = localOut.numSlices;
704             pOut->fmaskBytes = static_cast<UINT_32>(localOut.surfSize);
705             pOut->sliceSize  = static_cast<UINT_32>(localOut.sliceSize);
706             pOut->bpp        = localIn.bpp;
707             pOut->numSamples = 1;
708         }
709     }
710 
711     ValidBaseAlignments(pOut->baseAlign);
712 
713     return returnCode;
714 }
715 
716 /**
717 ************************************************************************************************************************
718 *   Lib::ComputeFmaskAddrFromCoord
719 *
720 *   @brief
721 *       Interface function stub of ComputeFmaskAddrFromCoord.
722 *
723 *   @return
724 *       ADDR_E_RETURNCODE
725 ************************************************************************************************************************
726 */
ComputeFmaskAddrFromCoord(const ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT * pOut) const727 ADDR_E_RETURNCODE Lib::ComputeFmaskAddrFromCoord(
728     const ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
729     ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure
730     ) const
731 {
732     ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
733 
734     ADDR_NOT_IMPLEMENTED();
735 
736     return returnCode;
737 }
738 
739 /**
740 ************************************************************************************************************************
741 *   Lib::ComputeFmaskCoordFromAddr
742 *
743 *   @brief
744 *       Interface function stub of ComputeFmaskAddrFromCoord.
745 *
746 *   @return
747 *       ADDR_E_RETURNCODE
748 ************************************************************************************************************************
749 */
ComputeFmaskCoordFromAddr(const ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT * pIn,ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT * pOut) const750 ADDR_E_RETURNCODE Lib::ComputeFmaskCoordFromAddr(
751     const ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT*  pIn,     ///< [in] input structure
752     ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT*       pOut     ///< [out] output structure
753     ) const
754 {
755     ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
756 
757     ADDR_NOT_IMPLEMENTED();
758 
759     return returnCode;
760 }
761 
762 /**
763 ************************************************************************************************************************
764 *   Lib::ComputeDccInfo
765 *
766 *   @brief
767 *       Interface function to compute DCC key info
768 *
769 *   @return
770 *       return code of HwlComputeDccInfo
771 ************************************************************************************************************************
772 */
ComputeDccInfo(const ADDR2_COMPUTE_DCCINFO_INPUT * pIn,ADDR2_COMPUTE_DCCINFO_OUTPUT * pOut) const773 ADDR_E_RETURNCODE Lib::ComputeDccInfo(
774     const ADDR2_COMPUTE_DCCINFO_INPUT*    pIn,    ///< [in] input structure
775     ADDR2_COMPUTE_DCCINFO_OUTPUT*         pOut    ///< [out] output structure
776     ) const
777 {
778     ADDR_E_RETURNCODE returnCode;
779 
780     if ((GetFillSizeFieldsFlags() == TRUE) &&
781         ((pIn->size != sizeof(ADDR2_COMPUTE_DCCINFO_INPUT)) ||
782          (pOut->size != sizeof(ADDR2_COMPUTE_DCCINFO_OUTPUT))))
783     {
784         returnCode = ADDR_INVALIDPARAMS;
785     }
786     else
787     {
788         returnCode = HwlComputeDccInfo(pIn, pOut);
789 
790         ValidMetaBaseAlignments(pOut->dccRamBaseAlign);
791     }
792 
793     return returnCode;
794 }
795 
796 /**
797 ************************************************************************************************************************
798 *   Lib::ComputeDccAddrFromCoord
799 *
800 *   @brief
801 *       Interface function stub of ComputeDccAddrFromCoord
802 *
803 *   @return
804 *       ADDR_E_RETURNCODE
805 ************************************************************************************************************************
806 */
ComputeDccAddrFromCoord(const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT * pOut)807 ADDR_E_RETURNCODE Lib::ComputeDccAddrFromCoord(
808     const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
809     ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT*      pOut)   ///< [out] output structure
810 {
811     ADDR_E_RETURNCODE returnCode;
812 
813     if ((GetFillSizeFieldsFlags() == TRUE) &&
814         ((pIn->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT)) ||
815          (pOut->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT))))
816     {
817         returnCode = ADDR_INVALIDPARAMS;
818     }
819     else
820     {
821         returnCode = HwlSupportComputeDccAddrFromCoord(pIn);
822 
823         if (returnCode == ADDR_OK)
824         {
825             HwlComputeDccAddrFromCoord(pIn, pOut);
826         }
827     }
828 
829     return returnCode;
830 }
831 
832 /**
833 ************************************************************************************************************************
834 *   Lib::ComputePipeBankXor
835 *
836 *   @brief
837 *       Interface function stub of Addr2ComputePipeBankXor.
838 *
839 *   @return
840 *       ADDR_E_RETURNCODE
841 ************************************************************************************************************************
842 */
ComputePipeBankXor(const ADDR2_COMPUTE_PIPEBANKXOR_INPUT * pIn,ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT * pOut)843 ADDR_E_RETURNCODE Lib::ComputePipeBankXor(
844     const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,
845     ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut)
846 {
847     ADDR_E_RETURNCODE returnCode;
848 
849     if ((GetFillSizeFieldsFlags() == TRUE) &&
850         ((pIn->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT)) ||
851          (pOut->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT))))
852     {
853         returnCode = ADDR_INVALIDPARAMS;
854     }
855     else
856     {
857         returnCode = HwlComputePipeBankXor(pIn, pOut);
858     }
859 
860     return returnCode;
861 }
862 
863 /**
864 ************************************************************************************************************************
865 *   Lib::ComputeSlicePipeBankXor
866 *
867 *   @brief
868 *       Interface function stub of Addr2ComputeSlicePipeBankXor.
869 *
870 *   @return
871 *       ADDR_E_RETURNCODE
872 ************************************************************************************************************************
873 */
ComputeSlicePipeBankXor(const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT * pIn,ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT * pOut)874 ADDR_E_RETURNCODE Lib::ComputeSlicePipeBankXor(
875     const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,
876     ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut)
877 {
878     ADDR_E_RETURNCODE returnCode;
879 
880     if ((GetFillSizeFieldsFlags() == TRUE) &&
881         ((pIn->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT)) ||
882          (pOut->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT))))
883     {
884         returnCode = ADDR_INVALIDPARAMS;
885     }
886     else if ((IsThin(pIn->resourceType, pIn->swizzleMode) == FALSE) ||
887              (IsNonPrtXor(pIn->swizzleMode) == FALSE) ||
888              (pIn->numSamples > 1))
889     {
890         returnCode = ADDR_NOTSUPPORTED;
891     }
892     else if ((pIn->bpe != 0) &&
893              (pIn->bpe != 8) &&
894              (pIn->bpe != 16) &&
895              (pIn->bpe != 32) &&
896              (pIn->bpe != 64) &&
897              (pIn->bpe != 128))
898     {
899         returnCode = ADDR_INVALIDPARAMS;
900     }
901     else
902     {
903         returnCode = HwlComputeSlicePipeBankXor(pIn, pOut);
904     }
905 
906     return returnCode;
907 }
908 
909 /**
910 ************************************************************************************************************************
911 *   Lib::ComputeSubResourceOffsetForSwizzlePattern
912 *
913 *   @brief
914 *       Interface function stub of Addr2ComputeSubResourceOffsetForSwizzlePattern.
915 *
916 *   @return
917 *       ADDR_E_RETURNCODE
918 ************************************************************************************************************************
919 */
ComputeSubResourceOffsetForSwizzlePattern(const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT * pIn,ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT * pOut)920 ADDR_E_RETURNCODE Lib::ComputeSubResourceOffsetForSwizzlePattern(
921     const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,
922     ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut)
923 {
924     ADDR_E_RETURNCODE returnCode;
925 
926     if ((GetFillSizeFieldsFlags() == TRUE) &&
927         ((pIn->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT)) ||
928          (pOut->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT))))
929     {
930         returnCode = ADDR_INVALIDPARAMS;
931     }
932     else
933     {
934         returnCode = HwlComputeSubResourceOffsetForSwizzlePattern(pIn, pOut);
935     }
936 
937     return returnCode;
938 }
939 
940 /**
941 ************************************************************************************************************************
942 *   Lib::ComputeNonBlockCompressedView
943 *
944 *   @brief
945 *       Interface function stub of Addr2ComputeNonBlockCompressedView.
946 *
947 *   @return
948 *       ADDR_E_RETURNCODE
949 ************************************************************************************************************************
950 */
ComputeNonBlockCompressedView(const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT * pIn,ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT * pOut)951 ADDR_E_RETURNCODE Lib::ComputeNonBlockCompressedView(
952     const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,
953     ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut)
954 {
955     ADDR_E_RETURNCODE returnCode;
956 
957     if ((GetFillSizeFieldsFlags() == TRUE) &&
958         ((pIn->size != sizeof(ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT)) ||
959          (pOut->size != sizeof(ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT))))
960     {
961         returnCode = ADDR_INVALIDPARAMS;
962     }
963     else
964     {
965         returnCode = HwlComputeNonBlockCompressedView(pIn, pOut);
966     }
967 
968     return returnCode;
969 }
970 
971 /**
972 ************************************************************************************************************************
973 *   Lib::ExtractPipeBankXor
974 *
975 *   @brief
976 *       Internal function to extract bank and pipe xor bits from combined xor bits.
977 *
978 *   @return
979 *       ADDR_E_RETURNCODE
980 ************************************************************************************************************************
981 */
ExtractPipeBankXor(UINT_32 pipeBankXor,UINT_32 bankBits,UINT_32 pipeBits,UINT_32 * pBankX,UINT_32 * pPipeX)982 ADDR_E_RETURNCODE Lib::ExtractPipeBankXor(
983     UINT_32  pipeBankXor,
984     UINT_32  bankBits,
985     UINT_32  pipeBits,
986     UINT_32* pBankX,
987     UINT_32* pPipeX)
988 {
989     ADDR_E_RETURNCODE returnCode;
990 
991     if (pipeBankXor < (1u << (pipeBits + bankBits)))
992     {
993         *pPipeX = pipeBankXor % (1 << pipeBits);
994         *pBankX = pipeBankXor >> pipeBits;
995         returnCode = ADDR_OK;
996     }
997     else
998     {
999         ADDR_ASSERT_ALWAYS();
1000         returnCode = ADDR_INVALIDPARAMS;
1001     }
1002 
1003     return returnCode;
1004 }
1005 
1006 /**
1007 ************************************************************************************************************************
1008 *   Lib::ComputeSurfaceInfoSanityCheck
1009 *
1010 *   @brief
1011 *       Internal function to do basic sanity check before compute surface info
1012 *
1013 *   @return
1014 *       ADDR_E_RETURNCODE
1015 ************************************************************************************************************************
1016 */
ComputeSurfaceInfoSanityCheck(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn) const1017 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoSanityCheck(
1018     const ADDR2_COMPUTE_SURFACE_INFO_INPUT*  pIn   ///< [in] input structure
1019     ) const
1020 {
1021     ADDR_E_RETURNCODE returnCode;
1022 
1023     if ((GetFillSizeFieldsFlags() == TRUE) &&
1024         (pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT)))
1025     {
1026         returnCode = ADDR_INVALIDPARAMS;
1027     }
1028     else
1029     {
1030         returnCode = HwlComputeSurfaceInfoSanityCheck(pIn);
1031     }
1032 
1033     return returnCode;
1034 }
1035 
1036 /**
1037 ************************************************************************************************************************
1038 *   Lib::ApplyCustomizedPitchHeight
1039 *
1040 *   @brief
1041 *       Helper function to override hw required row pitch/slice pitch by customrized one
1042 *
1043 *   @return
1044 *       ADDR_E_RETURNCODE
1045 ************************************************************************************************************************
1046 */
ApplyCustomizedPitchHeight(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,UINT_32 elementBytes,UINT_32 pitchAlignInElement,UINT_32 * pPitch,UINT_32 * pHeight) const1047 ADDR_E_RETURNCODE Lib::ApplyCustomizedPitchHeight(
1048     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
1049     UINT_32  elementBytes,                          ///< [in] element bytes per element
1050     UINT_32  pitchAlignInElement,                   ///< [in] pitch alignment in element
1051     UINT_32* pPitch,                                ///< [in/out] pitch
1052     UINT_32* pHeight                                ///< [in/out] height
1053     ) const
1054 {
1055     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1056 
1057     if (pIn->numMipLevels <= 1)
1058     {
1059         if (pIn->pitchInElement > 0)
1060         {
1061             if ((pIn->pitchInElement % pitchAlignInElement) != 0)
1062             {
1063                 returnCode = ADDR_INVALIDPARAMS;
1064             }
1065             else if (pIn->pitchInElement < (*pPitch))
1066             {
1067                 returnCode = ADDR_INVALIDPARAMS;
1068             }
1069             else
1070             {
1071                 *pPitch = pIn->pitchInElement;
1072             }
1073         }
1074 
1075         if (returnCode == ADDR_OK)
1076         {
1077             if (pIn->sliceAlign > 0)
1078             {
1079                 UINT_32 customizedHeight = pIn->sliceAlign / elementBytes / (*pPitch);
1080 
1081                 if (customizedHeight * elementBytes * (*pPitch) != pIn->sliceAlign)
1082                 {
1083                     returnCode = ADDR_INVALIDPARAMS;
1084                 }
1085                 else if ((pIn->numSlices > 1) && ((*pHeight) != customizedHeight))
1086                 {
1087                     returnCode = ADDR_INVALIDPARAMS;
1088                 }
1089                 else
1090                 {
1091                     *pHeight = customizedHeight;
1092                 }
1093             }
1094         }
1095     }
1096 
1097     return returnCode;
1098 }
1099 
1100 /**
1101 ************************************************************************************************************************
1102 *   Lib::ComputeSurfaceInfoLinear
1103 *
1104 *   @brief
1105 *       Internal function to calculate alignment for linear swizzle surface
1106 *
1107 *   @return
1108 *       ADDR_E_RETURNCODE
1109 ************************************************************************************************************************
1110 */
ComputeSurfaceInfoLinear(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const1111 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoLinear(
1112      const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
1113      ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure
1114      ) const
1115 {
1116     return HwlComputeSurfaceInfoLinear(pIn, pOut);
1117 }
1118 
1119 /**
1120 ************************************************************************************************************************
1121 *   Lib::ComputeSurfaceInfoTiled
1122 *
1123 *   @brief
1124 *       Internal function to calculate alignment for tiled swizzle surface
1125 *
1126 *   @return
1127 *       ADDR_E_RETURNCODE
1128 ************************************************************************************************************************
1129 */
ComputeSurfaceInfoTiled(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const1130 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoTiled(
1131      const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
1132      ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure
1133      ) const
1134 {
1135     return HwlComputeSurfaceInfoTiled(pIn, pOut);
1136 }
1137 
1138 /**
1139 ************************************************************************************************************************
1140 *   Lib::ComputeSurfaceAddrFromCoordLinear
1141 *
1142 *   @brief
1143 *       Internal function to calculate address from coord for linear swizzle surface
1144 *
1145 *   @return
1146 *       ADDR_E_RETURNCODE
1147 ************************************************************************************************************************
1148 */
ComputeSurfaceAddrFromCoordLinear(const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const1149 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordLinear(
1150      const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
1151      ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
1152      ) const
1153 {
1154     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1155     BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1) && (pIn->pipeBankXor == 0);
1156 
1157     if (valid)
1158     {
1159         if (IsTex1d(pIn->resourceType))
1160         {
1161             valid = (pIn->y == 0);
1162         }
1163     }
1164 
1165     if (valid)
1166     {
1167         ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn  = {0};
1168         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
1169         ADDR2_MIP_INFO                    mipInfo[MaxMipLevels];
1170         ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels);
1171 
1172         localIn.bpp          = pIn->bpp;
1173         localIn.flags        = pIn->flags;
1174         localIn.width        = Max(pIn->unalignedWidth, 1u);
1175         localIn.height       = Max(pIn->unalignedHeight, 1u);
1176         localIn.numSlices    = Max(pIn->numSlices, 1u);
1177         localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
1178         localIn.resourceType = pIn->resourceType;
1179 
1180         if (localIn.numMipLevels <= 1)
1181         {
1182             localIn.pitchInElement = pIn->pitchInElement;
1183         }
1184 
1185         localOut.pMipInfo = mipInfo;
1186 
1187         returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut);
1188 
1189         if (returnCode == ADDR_OK)
1190         {
1191             pOut->addr        = (localOut.sliceSize * pIn->slice) +
1192                                 mipInfo[pIn->mipId].offset +
1193                                 (pIn->y * mipInfo[pIn->mipId].pitch + pIn->x) * (pIn->bpp >> 3);
1194             pOut->bitPosition = 0;
1195         }
1196         else
1197         {
1198             valid = FALSE;
1199         }
1200     }
1201 
1202     if (valid == FALSE)
1203     {
1204         returnCode = ADDR_INVALIDPARAMS;
1205     }
1206 
1207     return returnCode;
1208 }
1209 
1210 /**
1211 ************************************************************************************************************************
1212 *   Lib::ComputeSurfaceAddrFromCoordTiled
1213 *
1214 *   @brief
1215 *       Internal function to calculate address from coord for tiled swizzle surface
1216 *
1217 *   @return
1218 *       ADDR_E_RETURNCODE
1219 ************************************************************************************************************************
1220 */
ComputeSurfaceAddrFromCoordTiled(const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const1221 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordTiled(
1222      const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
1223      ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
1224      ) const
1225 {
1226     return HwlComputeSurfaceAddrFromCoordTiled(pIn, pOut);
1227 }
1228 
1229 /**
1230 ************************************************************************************************************************
1231 *   Lib::ComputeSurfaceCoordFromAddrLinear
1232 *
1233 *   @brief
1234 *       Internal function to calculate coord from address for linear swizzle surface
1235 *
1236 *   @return
1237 *       ADDR_E_RETURNCODE
1238 ************************************************************************************************************************
1239 */
ComputeSurfaceCoordFromAddrLinear(const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT * pIn,ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT * pOut) const1240 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrLinear(
1241      const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure
1242      ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure
1243      ) const
1244 {
1245     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1246 
1247     BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1);
1248 
1249     if (valid)
1250     {
1251         if (IsTex1d(pIn->resourceType))
1252         {
1253             valid = (pIn->unalignedHeight == 1);
1254         }
1255     }
1256 
1257     if (valid)
1258     {
1259         ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn  = {0};
1260         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
1261         localIn.bpp          = pIn->bpp;
1262         localIn.flags        = pIn->flags;
1263         localIn.width        = Max(pIn->unalignedWidth, 1u);
1264         localIn.height       = Max(pIn->unalignedHeight, 1u);
1265         localIn.numSlices    = Max(pIn->numSlices, 1u);
1266         localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
1267         localIn.resourceType = pIn->resourceType;
1268         if (localIn.numMipLevels <= 1)
1269         {
1270             localIn.pitchInElement = pIn->pitchInElement;
1271         }
1272         returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut);
1273 
1274         if (returnCode == ADDR_OK)
1275         {
1276             pOut->slice = static_cast<UINT_32>(pIn->addr / localOut.sliceSize);
1277             pOut->sample = 0;
1278 
1279             UINT_32 offsetInSlice = static_cast<UINT_32>(pIn->addr % localOut.sliceSize);
1280             UINT_32 elementBytes = pIn->bpp >> 3;
1281             UINT_32 mipOffsetInSlice = 0;
1282             UINT_32 mipSize = 0;
1283             UINT_32 mipId = 0;
1284             for (; mipId < pIn->numMipLevels ; mipId++)
1285             {
1286                 if (IsTex1d(pIn->resourceType))
1287                 {
1288                     mipSize = localOut.pitch * elementBytes;
1289                 }
1290                 else
1291                 {
1292                     UINT_32 currentMipHeight = (PowTwoAlign(localIn.height, (1 << mipId))) >> mipId;
1293                     mipSize = currentMipHeight * localOut.pitch * elementBytes;
1294                 }
1295 
1296                 if (mipSize == 0)
1297                 {
1298                     valid = FALSE;
1299                     break;
1300                 }
1301                 else if ((mipSize + mipOffsetInSlice) > offsetInSlice)
1302                 {
1303                     break;
1304                 }
1305                 else
1306                 {
1307                     mipOffsetInSlice += mipSize;
1308                     if ((mipId == (pIn->numMipLevels - 1)) ||
1309                         (mipOffsetInSlice >= localOut.sliceSize))
1310                     {
1311                         valid = FALSE;
1312                     }
1313                 }
1314             }
1315 
1316             if (valid)
1317             {
1318                 pOut->mipId = mipId;
1319 
1320                 UINT_32 elemOffsetInMip = (offsetInSlice - mipOffsetInSlice) / elementBytes;
1321                 if (IsTex1d(pIn->resourceType))
1322                 {
1323                     if (elemOffsetInMip < localOut.pitch)
1324                     {
1325                         pOut->x = elemOffsetInMip;
1326                         pOut->y = 0;
1327                     }
1328                     else
1329                     {
1330                         valid = FALSE;
1331                     }
1332                 }
1333                 else
1334                 {
1335                     pOut->y = elemOffsetInMip / localOut.pitch;
1336                     pOut->x = elemOffsetInMip % localOut.pitch;
1337                 }
1338 
1339                 if ((pOut->slice >= pIn->numSlices)    ||
1340                     (pOut->mipId >= pIn->numMipLevels) ||
1341                     (pOut->x >= Max((pIn->unalignedWidth >> pOut->mipId), 1u))  ||
1342                     (pOut->y >= Max((pIn->unalignedHeight >> pOut->mipId), 1u)) ||
1343                     (IsTex3d(pIn->resourceType) &&
1344                      (FALSE == Valid3DMipSliceIdConstraint(pIn->numSlices,
1345                                                            pOut->mipId,
1346                                                            pOut->slice))))
1347                 {
1348                     valid = FALSE;
1349                 }
1350             }
1351         }
1352         else
1353         {
1354             valid = FALSE;
1355         }
1356     }
1357 
1358     if (valid == FALSE)
1359     {
1360         returnCode = ADDR_INVALIDPARAMS;
1361     }
1362 
1363     return returnCode;
1364 }
1365 
1366 /**
1367 ************************************************************************************************************************
1368 *   Lib::ComputeSurfaceCoordFromAddrTiled
1369 *
1370 *   @brief
1371 *       Internal function to calculate coord from address for tiled swizzle surface
1372 *
1373 *   @return
1374 *       ADDR_E_RETURNCODE
1375 ************************************************************************************************************************
1376 */
ComputeSurfaceCoordFromAddrTiled(const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT * pIn,ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT * pOut) const1377 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrTiled(
1378      const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure
1379      ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure
1380      ) const
1381 {
1382     ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
1383 
1384     ADDR_NOT_IMPLEMENTED();
1385 
1386     return returnCode;
1387 }
1388 
1389 /**
1390 ************************************************************************************************************************
1391 *   Lib::ComputeBlockDimensionForSurf
1392 *
1393 *   @brief
1394 *       Internal function to get block width/height/depth in element from surface input params.
1395 *
1396 *   @return
1397 *       ADDR_E_RETURNCODE
1398 ************************************************************************************************************************
1399 */
ComputeBlockDimensionForSurf(UINT_32 * pWidth,UINT_32 * pHeight,UINT_32 * pDepth,UINT_32 bpp,UINT_32 numSamples,AddrResourceType resourceType,AddrSwizzleMode swizzleMode) const1400 ADDR_E_RETURNCODE Lib::ComputeBlockDimensionForSurf(
1401     UINT_32*         pWidth,
1402     UINT_32*         pHeight,
1403     UINT_32*         pDepth,
1404     UINT_32          bpp,
1405     UINT_32          numSamples,
1406     AddrResourceType resourceType,
1407     AddrSwizzleMode  swizzleMode) const
1408 {
1409     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1410 
1411     if (IsThick(resourceType, swizzleMode))
1412     {
1413         ComputeThickBlockDimension(pWidth, pHeight, pDepth, bpp, resourceType, swizzleMode);
1414     }
1415     else if (IsThin(resourceType, swizzleMode))
1416     {
1417         ComputeThinBlockDimension(pWidth, pHeight, pDepth, bpp, numSamples, resourceType, swizzleMode);
1418     }
1419     else
1420     {
1421         ADDR_ASSERT_ALWAYS();
1422         returnCode = ADDR_INVALIDPARAMS;
1423     }
1424 
1425     return returnCode;
1426 }
1427 
1428 /**
1429 ************************************************************************************************************************
1430 *   Lib::ComputeThinBlockDimension
1431 *
1432 *   @brief
1433 *       Internal function to get thin block width/height/depth in element from surface input params.
1434 *
1435 *   @return
1436 *       N/A
1437 ************************************************************************************************************************
1438 */
ComputeThinBlockDimension(UINT_32 * pWidth,UINT_32 * pHeight,UINT_32 * pDepth,UINT_32 bpp,UINT_32 numSamples,AddrResourceType resourceType,AddrSwizzleMode swizzleMode) const1439 VOID Lib::ComputeThinBlockDimension(
1440     UINT_32*         pWidth,
1441     UINT_32*         pHeight,
1442     UINT_32*         pDepth,
1443     UINT_32          bpp,
1444     UINT_32          numSamples,
1445     AddrResourceType resourceType,
1446     AddrSwizzleMode  swizzleMode) const
1447 {
1448     ADDR_ASSERT(IsThin(resourceType, swizzleMode));
1449 
1450     // GFX9/GFX10 use different dimension amplifying logic: say for 128KB block + 1xAA + 1BPE, the dimension of thin
1451     // swizzle mode will be [256W * 512H] on GFX9 ASICs and [512W * 256H] on GFX10 ASICs. Since GFX10 is newer HWL so we
1452     // make its implementation into base class (in order to save future change on new HWLs)
1453     const UINT_32 log2BlkSize  = GetBlockSizeLog2(swizzleMode);
1454     const UINT_32 log2EleBytes = Log2(bpp >> 3);
1455     const UINT_32 log2Samples  = Log2(Max(numSamples, 1u));
1456     const UINT_32 log2NumEle   = log2BlkSize - log2EleBytes - log2Samples;
1457 
1458     // For "1xAA/4xAA cases" or "2xAA/8xAA + odd log2BlkSize cases", width == height or width == 2 * height;
1459     // For other cases, height == width or height == 2 * width
1460     const BOOL_32 widthPrecedent = ((log2Samples & 1) == 0) || ((log2BlkSize & 1) != 0);
1461     const UINT_32 log2Width      = (log2NumEle + (widthPrecedent ? 1 : 0)) / 2;
1462 
1463     *pWidth  = 1u << log2Width;
1464     *pHeight = 1u << (log2NumEle - log2Width);
1465     *pDepth  = 1;
1466 }
1467 
1468 /**
1469 ************************************************************************************************************************
1470 *   Lib::ComputeBlockDimension
1471 *
1472 *   @brief
1473 *       Internal function to get block width/height/depth in element without considering MSAA case
1474 *
1475 *   @return
1476 *       ADDR_E_RETURNCODE
1477 ************************************************************************************************************************
1478 */
ComputeBlockDimension(UINT_32 * pWidth,UINT_32 * pHeight,UINT_32 * pDepth,UINT_32 bpp,AddrResourceType resourceType,AddrSwizzleMode swizzleMode) const1479 ADDR_E_RETURNCODE Lib::ComputeBlockDimension(
1480     UINT_32*         pWidth,
1481     UINT_32*         pHeight,
1482     UINT_32*         pDepth,
1483     UINT_32          bpp,
1484     AddrResourceType resourceType,
1485     AddrSwizzleMode  swizzleMode) const
1486 {
1487     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1488 
1489     if (IsThick(resourceType, swizzleMode))
1490     {
1491         ComputeThickBlockDimension(pWidth, pHeight, pDepth, bpp, resourceType, swizzleMode);
1492     }
1493     else if (IsThin(resourceType, swizzleMode))
1494     {
1495         ComputeThinBlockDimension(pWidth, pHeight, pDepth, bpp, 0, resourceType, swizzleMode);
1496     }
1497     else
1498     {
1499         ADDR_ASSERT_ALWAYS();
1500         returnCode = ADDR_INVALIDPARAMS;
1501     }
1502 
1503     return returnCode;
1504 }
1505 
1506 /**
1507 ************************************************************************************************************************
1508 *   Lib::ComputeThickBlockDimension
1509 *
1510 *   @brief
1511 *       Internal function to get block width/height/depth in element for thick swizzle mode
1512 *
1513 *   @return
1514 *       N/A
1515 ************************************************************************************************************************
1516 */
ComputeThickBlockDimension(UINT_32 * pWidth,UINT_32 * pHeight,UINT_32 * pDepth,UINT_32 bpp,AddrResourceType resourceType,AddrSwizzleMode swizzleMode) const1517 VOID Lib::ComputeThickBlockDimension(
1518     UINT_32*         pWidth,
1519     UINT_32*         pHeight,
1520     UINT_32*         pDepth,
1521     UINT_32          bpp,
1522     AddrResourceType resourceType,
1523     AddrSwizzleMode  swizzleMode) const
1524 {
1525     ADDR_ASSERT(IsThick(resourceType, swizzleMode));
1526 
1527     const UINT_32 log2BlkSize              = GetBlockSizeLog2(swizzleMode);
1528     const UINT_32 eleBytes                 = bpp >> 3;
1529     const UINT_32 microBlockSizeTableIndex = Log2(eleBytes);
1530 
1531     ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block1K_3d) / sizeof(Block1K_3d[0]));
1532 
1533     const UINT_32 log2blkSizeIn1KB = log2BlkSize - 10;
1534     const UINT_32 averageAmp       = log2blkSizeIn1KB / 3;
1535     const UINT_32 restAmp          = log2blkSizeIn1KB % 3;
1536 
1537     *pWidth  = Block1K_3d[microBlockSizeTableIndex].w << averageAmp;
1538     *pHeight = Block1K_3d[microBlockSizeTableIndex].h << (averageAmp + (restAmp / 2));
1539     *pDepth  = Block1K_3d[microBlockSizeTableIndex].d << (averageAmp + ((restAmp != 0) ? 1 : 0));
1540 }
1541 
1542 /**
1543 ************************************************************************************************************************
1544 *   Lib::GetMipTailDim
1545 *
1546 *   @brief
1547 *       Internal function to get out max dimension of first level in mip tail
1548 *
1549 *   @return
1550 *       Max Width/Height/Depth value of the first mip fitted in mip tail
1551 ************************************************************************************************************************
1552 */
GetMipTailDim(AddrResourceType resourceType,AddrSwizzleMode swizzleMode,UINT_32 blockWidth,UINT_32 blockHeight,UINT_32 blockDepth) const1553 Dim3d Lib::GetMipTailDim(
1554     AddrResourceType  resourceType,
1555     AddrSwizzleMode   swizzleMode,
1556     UINT_32           blockWidth,
1557     UINT_32           blockHeight,
1558     UINT_32           blockDepth) const
1559 {
1560     Dim3d   out         = {blockWidth, blockHeight, blockDepth};
1561     UINT_32 log2BlkSize = GetBlockSizeLog2(swizzleMode);
1562 
1563     if (IsThick(resourceType, swizzleMode))
1564     {
1565         UINT_32 dim = log2BlkSize % 3;
1566 
1567         if (dim == 0)
1568         {
1569             out.h >>= 1;
1570         }
1571         else if (dim == 1)
1572         {
1573             out.w >>= 1;
1574         }
1575         else
1576         {
1577             out.d >>= 1;
1578         }
1579     }
1580     else
1581     {
1582         ADDR_ASSERT(IsThin(resourceType, swizzleMode));
1583 
1584 #if DEBUG
1585         // GFX9/GFX10 use different dimension shrinking logic for mipmap tail: say for 128KB block + 2BPE, the maximum
1586         // dimension of mipmap tail level will be [256W * 128H] on GFX9 ASICs and [128W * 256H] on GFX10 ASICs. Since
1587         // GFX10 is newer HWL so we make its implementation into base class, in order to save future change on new HWLs.
1588         // And assert log2BlkSize will always be an even value on GFX9, so we never need the logic wrapped by DEBUG...
1589         if ((log2BlkSize & 1) && (m_chipFamily == ADDR_CHIP_FAMILY_AI))
1590         {
1591             // Should never go here...
1592             ADDR_ASSERT_ALWAYS();
1593 
1594             out.h >>= 1;
1595         }
1596         else
1597 #endif
1598         {
1599             out.w >>= 1;
1600         }
1601     }
1602 
1603     return out;
1604 }
1605 
1606 /**
1607 ************************************************************************************************************************
1608 *   Lib::ComputeSurface2DMicroBlockOffset
1609 *
1610 *   @brief
1611 *       Internal function to calculate micro block (256B) offset from coord for 2D resource
1612 *
1613 *   @return
1614 *       micro block (256B) offset for 2D resource
1615 ************************************************************************************************************************
1616 */
ComputeSurface2DMicroBlockOffset(const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn) const1617 UINT_32 Lib::ComputeSurface2DMicroBlockOffset(
1618     const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const
1619 {
1620     ADDR_ASSERT(IsThin(pIn->resourceType, pIn->swizzleMode));
1621 
1622     UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3);
1623     UINT_32 microBlockOffset = 0;
1624     if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode))
1625     {
1626         UINT_32 xBits = pIn->x << log2ElementBytes;
1627         microBlockOffset = (xBits & 0xf) | ((pIn->y & 0x3) << 4);
1628         if (log2ElementBytes < 3)
1629         {
1630             microBlockOffset |= (pIn->y & 0x4) << 4;
1631             if (log2ElementBytes == 0)
1632             {
1633                 microBlockOffset |= (pIn->y & 0x8) << 4;
1634             }
1635             else
1636             {
1637                 microBlockOffset |= (xBits & 0x10) << 3;
1638             }
1639         }
1640         else
1641         {
1642             microBlockOffset |= (xBits & 0x30) << 2;
1643         }
1644     }
1645     else if (IsDisplaySwizzle(pIn->resourceType, pIn->swizzleMode))
1646     {
1647         if (log2ElementBytes == 4)
1648         {
1649             microBlockOffset = (GetBit(pIn->x, 0) << 4) |
1650                                (GetBit(pIn->y, 0) << 5) |
1651                                (GetBit(pIn->x, 1) << 6) |
1652                                (GetBit(pIn->y, 1) << 7);
1653         }
1654         else
1655         {
1656             microBlockOffset = GetBits(pIn->x, 0, 3, log2ElementBytes)     |
1657                                GetBits(pIn->y, 1, 2, 3 + log2ElementBytes) |
1658                                GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) |
1659                                GetBits(pIn->y, 3, 1, 6 + log2ElementBytes);
1660             microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) |
1661                                (GetBit(pIn->y, 0) << 4) |
1662                                GetBits(microBlockOffset, 4, 3, 5);
1663         }
1664     }
1665     else if (IsRotateSwizzle(pIn->swizzleMode))
1666     {
1667         microBlockOffset = GetBits(pIn->y, 0, 3, log2ElementBytes) |
1668                            GetBits(pIn->x, 1, 2, 3 + log2ElementBytes) |
1669                            GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) |
1670                            GetBits(pIn->y, 3, 1, 6 + log2ElementBytes);
1671         microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) |
1672                            (GetBit(pIn->x, 0) << 4) |
1673                            GetBits(microBlockOffset, 4, 3, 5);
1674         if (log2ElementBytes == 3)
1675         {
1676            microBlockOffset = GetBits(microBlockOffset, 0, 6, 0) |
1677                               GetBits(pIn->x, 1, 2, 6);
1678         }
1679     }
1680 
1681     return microBlockOffset;
1682 }
1683 
1684 /**
1685 ************************************************************************************************************************
1686 *   Lib::ComputeSurface3DMicroBlockOffset
1687 *
1688 *   @brief
1689 *       Internal function to calculate micro block (1KB) offset from coord for 3D resource
1690 *
1691 *   @return
1692 *       micro block (1KB) offset for 3D resource
1693 ************************************************************************************************************************
1694 */
ComputeSurface3DMicroBlockOffset(const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn) const1695 UINT_32 Lib::ComputeSurface3DMicroBlockOffset(
1696     const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const
1697 {
1698     ADDR_ASSERT(IsThick(pIn->resourceType, pIn->swizzleMode));
1699 
1700     UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3);
1701     UINT_32 microBlockOffset = 0;
1702     if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode))
1703     {
1704         if (log2ElementBytes == 0)
1705         {
1706             microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1);
1707         }
1708         else if (log2ElementBytes == 1)
1709         {
1710             microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1);
1711         }
1712         else if (log2ElementBytes == 2)
1713         {
1714             microBlockOffset = ((pIn->y & 4) >> 2) | ((pIn->x & 4) >> 1);
1715         }
1716         else if (log2ElementBytes == 3)
1717         {
1718             microBlockOffset = (pIn->x & 6) >> 1;
1719         }
1720         else
1721         {
1722             microBlockOffset = pIn->x & 3;
1723         }
1724 
1725         microBlockOffset <<= 8;
1726 
1727         UINT_32 xBits = pIn->x << log2ElementBytes;
1728         microBlockOffset |= (xBits & 0xf) | ((pIn->y & 0x3) << 4) | ((pIn->slice & 0x3) << 6);
1729     }
1730     else if (IsZOrderSwizzle(pIn->swizzleMode))
1731     {
1732         UINT_32 xh, yh, zh;
1733 
1734         if (log2ElementBytes == 0)
1735         {
1736             microBlockOffset =
1737                 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2);
1738             microBlockOffset = microBlockOffset | ((pIn->slice & 3) << 4) | ((pIn->x & 4) << 4);
1739 
1740             xh = pIn->x >> 3;
1741             yh = pIn->y >> 2;
1742             zh = pIn->slice >> 2;
1743         }
1744         else if (log2ElementBytes == 1)
1745         {
1746             microBlockOffset =
1747                 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2);
1748             microBlockOffset = (microBlockOffset << 1) | ((pIn->slice & 3) << 5);
1749 
1750             xh = pIn->x >> 2;
1751             yh = pIn->y >> 2;
1752             zh = pIn->slice >> 2;
1753         }
1754         else if (log2ElementBytes == 2)
1755         {
1756             microBlockOffset =
1757                 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->slice & 1) << 3);
1758             microBlockOffset = (microBlockOffset << 2) | ((pIn->y & 2) << 5);
1759 
1760             xh = pIn->x >> 2;
1761             yh = pIn->y >> 2;
1762             zh = pIn->slice >> 1;
1763         }
1764         else if (log2ElementBytes == 3)
1765         {
1766             microBlockOffset =
1767                 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2) | ((pIn->x & 2) << 2);
1768             microBlockOffset <<= 3;
1769 
1770             xh = pIn->x >> 2;
1771             yh = pIn->y >> 1;
1772             zh = pIn->slice >> 1;
1773         }
1774         else
1775         {
1776             microBlockOffset =
1777                 (((pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2)) << 4);
1778 
1779             xh = pIn->x >> 1;
1780             yh = pIn->y >> 1;
1781             zh = pIn->slice >> 1;
1782         }
1783 
1784         microBlockOffset |= ((MortonGen3d(xh, yh, zh, 1) << 7) & 0x380);
1785     }
1786 
1787     return microBlockOffset;
1788 }
1789 
1790 /**
1791 ************************************************************************************************************************
1792 *   Lib::GetPipeXorBits
1793 *
1794 *   @brief
1795 *       Internal function to get bits number for pipe/se xor operation
1796 *
1797 *   @return
1798 *       ADDR_E_RETURNCODE
1799 ************************************************************************************************************************
1800 */
GetPipeXorBits(UINT_32 macroBlockBits) const1801 UINT_32 Lib::GetPipeXorBits(
1802     UINT_32 macroBlockBits) const
1803 {
1804     ADDR_ASSERT(macroBlockBits >= m_pipeInterleaveLog2);
1805 
1806     // Total available xor bits
1807     UINT_32 xorBits = macroBlockBits - m_pipeInterleaveLog2;
1808 
1809     // Pipe/Se xor bits
1810     UINT_32 pipeBits = Min(xorBits, m_pipesLog2 + m_seLog2);
1811 
1812     return pipeBits;
1813 }
1814 
1815 /**
1816 ************************************************************************************************************************
1817 *   Lib::Addr2GetPreferredSurfaceSetting
1818 *
1819 *   @brief
1820 *       Internal function to get suggested surface information for cliet to use
1821 *
1822 *   @return
1823 *       ADDR_E_RETURNCODE
1824 ************************************************************************************************************************
1825 */
Addr2GetPreferredSurfaceSetting(const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT * pIn,ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT * pOut) const1826 ADDR_E_RETURNCODE Lib::Addr2GetPreferredSurfaceSetting(
1827     const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
1828     ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const
1829 {
1830     ADDR_E_RETURNCODE returnCode;
1831 
1832     if ((GetFillSizeFieldsFlags() == TRUE) &&
1833         ((pIn->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_INPUT)) ||
1834          (pOut->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT))))
1835     {
1836         returnCode = ADDR_INVALIDPARAMS;
1837     }
1838     else
1839     {
1840         returnCode = HwlGetPreferredSurfaceSetting(pIn, pOut);
1841     }
1842 
1843     return returnCode;
1844 }
1845 
1846 /**
1847 ************************************************************************************************************************
1848 *   Lib::GetPossibleSwizzleModes
1849 *
1850 *   @brief
1851 *       Returns a list of swizzle modes that are valid from the hardware's perspective for the client to choose from
1852 *
1853 *   @return
1854 *       ADDR_E_RETURNCODE
1855 ************************************************************************************************************************
1856 */
GetPossibleSwizzleModes(const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT * pIn,ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT * pOut) const1857 ADDR_E_RETURNCODE Lib::GetPossibleSwizzleModes(
1858     const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
1859     ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const
1860 {
1861     return HwlGetPossibleSwizzleModes(pIn, pOut);
1862 }
1863 
1864 /**
1865 ************************************************************************************************************************
1866 *   Lib::GetAllowedBlockSet
1867 *
1868 *   @brief
1869 *       Returns the set of allowed block sizes given the allowed swizzle modes and resource type
1870 *
1871 *   @return
1872 *       ADDR_E_RETURNCODE
1873 ************************************************************************************************************************
1874 */
GetAllowedBlockSet(ADDR2_SWMODE_SET allowedSwModeSet,AddrResourceType rsrcType,ADDR2_BLOCK_SET * pAllowedBlockSet) const1875 ADDR_E_RETURNCODE Lib::GetAllowedBlockSet(
1876     ADDR2_SWMODE_SET allowedSwModeSet,
1877     AddrResourceType rsrcType,
1878     ADDR2_BLOCK_SET* pAllowedBlockSet) const
1879 {
1880     return HwlGetAllowedBlockSet(allowedSwModeSet, rsrcType, pAllowedBlockSet);
1881 }
1882 
1883 /**
1884 ************************************************************************************************************************
1885 *   Lib::GetAllowedSwSet
1886 *
1887 *   @brief
1888 *       Returns the set of allowed swizzle types given the allowed swizzle modes
1889 *
1890 *   @return
1891 *       ADDR_E_RETURNCODE
1892 ************************************************************************************************************************
1893 */
GetAllowedSwSet(ADDR2_SWMODE_SET allowedSwModeSet,ADDR2_SWTYPE_SET * pAllowedSwSet) const1894 ADDR_E_RETURNCODE Lib::GetAllowedSwSet(
1895     ADDR2_SWMODE_SET  allowedSwModeSet,
1896     ADDR2_SWTYPE_SET* pAllowedSwSet) const
1897 {
1898     return HwlGetAllowedSwSet(allowedSwModeSet, pAllowedSwSet);
1899 }
1900 
1901 /**
1902 ************************************************************************************************************************
1903 *   Lib::ComputeBlock256Equation
1904 *
1905 *   @brief
1906 *       Compute equation for block 256B
1907 *
1908 *   @return
1909 *       If equation computed successfully
1910 *
1911 ************************************************************************************************************************
1912 */
ComputeBlock256Equation(AddrResourceType rsrcType,AddrSwizzleMode swMode,UINT_32 elementBytesLog2,ADDR_EQUATION * pEquation) const1913 ADDR_E_RETURNCODE Lib::ComputeBlock256Equation(
1914     AddrResourceType rsrcType,
1915     AddrSwizzleMode swMode,
1916     UINT_32 elementBytesLog2,
1917     ADDR_EQUATION* pEquation) const
1918 {
1919     ADDR_E_RETURNCODE ret;
1920 
1921     if (IsBlock256b(swMode))
1922     {
1923         ret = HwlComputeBlock256Equation(rsrcType, swMode, elementBytesLog2, pEquation);
1924     }
1925     else
1926     {
1927         ADDR_ASSERT_ALWAYS();
1928         ret = ADDR_INVALIDPARAMS;
1929     }
1930 
1931     return ret;
1932 }
1933 
1934 /**
1935 ************************************************************************************************************************
1936 *   Lib::ComputeThinEquation
1937 *
1938 *   @brief
1939 *       Compute equation for 2D/3D resource which use THIN mode
1940 *
1941 *   @return
1942 *       If equation computed successfully
1943 *
1944 ************************************************************************************************************************
1945 */
ComputeThinEquation(AddrResourceType rsrcType,AddrSwizzleMode swMode,UINT_32 elementBytesLog2,ADDR_EQUATION * pEquation) const1946 ADDR_E_RETURNCODE Lib::ComputeThinEquation(
1947     AddrResourceType rsrcType,
1948     AddrSwizzleMode swMode,
1949     UINT_32 elementBytesLog2,
1950     ADDR_EQUATION* pEquation) const
1951 {
1952     ADDR_E_RETURNCODE ret;
1953 
1954     if (IsThin(rsrcType, swMode))
1955     {
1956         ret = HwlComputeThinEquation(rsrcType, swMode, elementBytesLog2, pEquation);
1957     }
1958     else
1959     {
1960         ADDR_ASSERT_ALWAYS();
1961         ret = ADDR_INVALIDPARAMS;
1962     }
1963 
1964     return ret;
1965 }
1966 
1967 /**
1968 ************************************************************************************************************************
1969 *   Lib::ComputeThickEquation
1970 *
1971 *   @brief
1972 *       Compute equation for 3D resource which use THICK mode
1973 *
1974 *   @return
1975 *       If equation computed successfully
1976 *
1977 ************************************************************************************************************************
1978 */
ComputeThickEquation(AddrResourceType rsrcType,AddrSwizzleMode swMode,UINT_32 elementBytesLog2,ADDR_EQUATION * pEquation) const1979 ADDR_E_RETURNCODE Lib::ComputeThickEquation(
1980     AddrResourceType rsrcType,
1981     AddrSwizzleMode swMode,
1982     UINT_32 elementBytesLog2,
1983     ADDR_EQUATION* pEquation) const
1984 {
1985     ADDR_E_RETURNCODE ret;
1986 
1987     if (IsThick(rsrcType, swMode))
1988     {
1989         ret = HwlComputeThickEquation(rsrcType, swMode, elementBytesLog2, pEquation);
1990     }
1991     else
1992     {
1993         ADDR_ASSERT_ALWAYS();
1994         ret = ADDR_INVALIDPARAMS;
1995     }
1996 
1997     return ret;
1998 }
1999 
2000 /**
2001 ************************************************************************************************************************
2002 *   Lib::ComputeQbStereoInfo
2003 *
2004 *   @brief
2005 *       Get quad buffer stereo information
2006 *   @return
2007 *       N/A
2008 ************************************************************************************************************************
2009 */
ComputeQbStereoInfo(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2010 VOID Lib::ComputeQbStereoInfo(
2011     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut    ///< [in,out] updated pOut+pStereoInfo
2012     ) const
2013 {
2014     ADDR_ASSERT(pOut->bpp >= 8);
2015     ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0);
2016 
2017     // Save original height
2018     pOut->pStereoInfo->eyeHeight = pOut->height;
2019 
2020     // Right offset
2021     pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize);
2022 
2023     // Double height
2024     pOut->height <<= 1;
2025 
2026     ADDR_ASSERT(pOut->height <= MaxSurfaceHeight);
2027 
2028     pOut->pixelHeight <<= 1;
2029 
2030     // Double size
2031     pOut->surfSize  <<= 1;
2032     pOut->sliceSize <<= 1;
2033 }
2034 
2035 /**
2036 ************************************************************************************************************************
2037 *   Lib::FilterInvalidEqSwizzleMode
2038 *
2039 *   @brief
2040 *       Filter out swizzle mode(s) if it doesn't have valid equation index
2041 *
2042 *   @return
2043 *       N/A
2044 ************************************************************************************************************************
2045 */
FilterInvalidEqSwizzleMode(ADDR2_SWMODE_SET & allowedSwModeSet,AddrResourceType resourceType,UINT_32 elemLog2,UINT_32 maxComponents) const2046 VOID Lib::FilterInvalidEqSwizzleMode(
2047     ADDR2_SWMODE_SET& allowedSwModeSet,
2048     AddrResourceType  resourceType,
2049     UINT_32           elemLog2,
2050     UINT_32           maxComponents
2051     ) const
2052 {
2053     if (resourceType != ADDR_RSRC_TEX_1D)
2054     {
2055         UINT_32       allowedSwModeSetVal = allowedSwModeSet.value;
2056         const UINT_32 rsrcTypeIdx         = static_cast<UINT_32>(resourceType) - 1;
2057         UINT_32       validSwModeSet      = allowedSwModeSetVal;
2058 
2059         for (UINT_32 swModeIdx = 1; validSwModeSet != 0; swModeIdx++)
2060         {
2061             if (validSwModeSet & 1)
2062             {
2063                 UINT_32 equation = m_equationLookupTable[rsrcTypeIdx][swModeIdx][elemLog2];
2064                 if (equation == ADDR_INVALID_EQUATION_INDEX)
2065                 {
2066                     allowedSwModeSetVal &= ~(1u << swModeIdx);
2067                 }
2068                 else if (m_equationTable[equation].numBitComponents > maxComponents)
2069                 {
2070                     allowedSwModeSetVal &= ~(1u << swModeIdx);
2071                 }
2072             }
2073 
2074             validSwModeSet >>= 1;
2075         }
2076 
2077         // Only apply the filtering if at least one valid swizzle mode remains
2078         if (allowedSwModeSetVal != 0)
2079         {
2080             allowedSwModeSet.value = allowedSwModeSetVal;
2081         }
2082     }
2083 }
2084 
2085 #if DEBUG
2086 /**
2087 ************************************************************************************************************************
2088 *   Lib::ValidateStereoInfo
2089 *
2090 *   @brief
2091 *       Validate stereo info by checking a few typical cases
2092 *
2093 *   @return
2094 *       N/A
2095 ************************************************************************************************************************
2096 */
ValidateStereoInfo(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,const ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2097 VOID Lib::ValidateStereoInfo(
2098     const ADDR2_COMPUTE_SURFACE_INFO_INPUT*  pIn,   ///< [in] input structure
2099     const ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut   ///< [in] output structure
2100     ) const
2101 {
2102     ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT addrIn = {};
2103     addrIn.size            = sizeof(addrIn);
2104     addrIn.swizzleMode     = pIn->swizzleMode;
2105     addrIn.flags           = pIn->flags;
2106     addrIn.flags.qbStereo  = 0;
2107     addrIn.resourceType    = pIn->resourceType;
2108     addrIn.bpp             = pIn->bpp;
2109     addrIn.unalignedWidth  = pIn->width;
2110     addrIn.numSlices       = pIn->numSlices;
2111     addrIn.numMipLevels    = pIn->numMipLevels;
2112     addrIn.numSamples      = pIn->numSamples;
2113     addrIn.numFrags        = pIn->numFrags;
2114 
2115     // Call Addr2ComputePipeBankXor() and validate different pbXor value if necessary...
2116     const UINT_32 pbXor = 0;
2117 
2118     ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT addrOut = {};
2119     addrOut.size = sizeof(addrOut);
2120 
2121     // Make the array to be {0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096} for full test
2122     const UINT_32 TestCoord[] = {0};
2123 
2124     for (UINT_32 xIdx = 0; xIdx < sizeof(TestCoord) / sizeof(TestCoord[0]); xIdx++)
2125     {
2126         if (TestCoord[xIdx] < pIn->width)
2127         {
2128             addrIn.x = TestCoord[xIdx];
2129 
2130             for (UINT_32 yIdx = 0; yIdx  < sizeof(TestCoord) / sizeof(TestCoord[0]); yIdx++)
2131             {
2132                 if (TestCoord[yIdx] < pIn->height)
2133                 {
2134                     addrIn.y               = TestCoord[yIdx] + pOut->pStereoInfo->eyeHeight;
2135                     addrIn.pipeBankXor     = pbXor ^ pOut->pStereoInfo->rightSwizzle;
2136                     addrIn.unalignedHeight = pIn->height + pOut->pStereoInfo->eyeHeight;
2137 
2138                     ADDR_E_RETURNCODE ret = ComputeSurfaceAddrFromCoord(&addrIn, &addrOut);
2139                     ADDR_ASSERT(ret == ADDR_OK);
2140 
2141                     const UINT_64 rightEyeOffsetFromBase = addrOut.addr;
2142 
2143                     addrIn.y               = TestCoord[yIdx];
2144                     addrIn.pipeBankXor     = pbXor;
2145                     addrIn.unalignedHeight = pIn->height;
2146 
2147                     ret = ComputeSurfaceAddrFromCoord(&addrIn, &addrOut);
2148                     ADDR_ASSERT(ret == ADDR_OK);
2149 
2150                     const UINT_64 rightEyeOffsetRelative = addrOut.addr;
2151 
2152                     ADDR_ASSERT(rightEyeOffsetFromBase == rightEyeOffsetRelative + pOut->pStereoInfo->rightOffset);
2153                 }
2154             }
2155         }
2156     }
2157 }
2158 #endif
2159 
2160 } // V2
2161 } // Addr
2162 
2163