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