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