xref: /aosp_15_r20/external/mesa3d/src/amd/addrlib/src/r800/egbaddrlib.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 * @file  egbaddrlib.cpp
11 * @brief Contains the EgBasedLib class implementation.
12 ****************************************************************************************************
13 */
14 
15 #include "egbaddrlib.h"
16 
17 namespace Addr
18 {
19 namespace V1
20 {
21 
22 /**
23 ****************************************************************************************************
24 *   EgBasedLib::EgBasedLib
25 *
26 *   @brief
27 *       Constructor
28 *
29 *   @note
30 *
31 ****************************************************************************************************
32 */
EgBasedLib(const Client * pClient)33 EgBasedLib::EgBasedLib(const Client* pClient)
34     :
35     Lib(pClient),
36     m_ranks(0),
37     m_logicalBanks(0),
38     m_bankInterleave(1)
39 {
40 }
41 
42 /**
43 ****************************************************************************************************
44 *   EgBasedLib::~EgBasedLib
45 *
46 *   @brief
47 *       Destructor
48 ****************************************************************************************************
49 */
~EgBasedLib()50 EgBasedLib::~EgBasedLib()
51 {
52 }
53 
54 /**
55 ****************************************************************************************************
56 *   EgBasedLib::DispatchComputeSurfaceInfo
57 *
58 *   @brief
59 *       Compute surface sizes include padded pitch,height,slices,total size in bytes,
60 *       meanwhile output suitable tile mode and base alignment might be changed in this
61 *       call as well. Results are returned through output parameters.
62 *
63 *   @return
64 *       TRUE if no error occurs
65 ****************************************************************************************************
66 */
DispatchComputeSurfaceInfo(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const67 BOOL_32 EgBasedLib::DispatchComputeSurfaceInfo(
68     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,    ///< [in] input structure
69     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [out] output structure
70     ) const
71 {
72     AddrTileMode        tileMode      = pIn->tileMode;
73     UINT_32             bpp           = pIn->bpp;
74     UINT_32             numSamples    = pIn->numSamples;
75     UINT_32             numFrags      = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
76     UINT_32             pitch         = pIn->width;
77     UINT_32             height        = pIn->height;
78     UINT_32             numSlices     = pIn->numSlices;
79     UINT_32             mipLevel      = pIn->mipLevel;
80     ADDR_SURFACE_FLAGS  flags         = pIn->flags;
81 
82     ADDR_TILEINFO       tileInfoDef   = {0};
83     ADDR_TILEINFO*      pTileInfo     = &tileInfoDef;
84     UINT_32             padDims       = 0;
85     BOOL_32             valid;
86 
87     if (pIn->flags.disallowLargeThickDegrade == 0)
88     {
89         tileMode = DegradeLargeThickTile(tileMode, bpp);
90     }
91 
92     // Only override numSamples for NI above
93     if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
94     {
95         if (numFrags != numSamples) // This means EQAA
96         {
97             // The real surface size needed is determined by number of fragments
98             numSamples = numFrags;
99         }
100 
101         // Save altered numSamples in pOut
102         pOut->numSamples = numSamples;
103     }
104 
105     // Caller makes sure pOut->pTileInfo is not NULL, see HwlComputeSurfaceInfo
106     ADDR_ASSERT(pOut->pTileInfo);
107 
108     if (pOut->pTileInfo != NULL)
109     {
110         pTileInfo = pOut->pTileInfo;
111     }
112 
113     // Set default values
114     if (pIn->pTileInfo != NULL)
115     {
116         if (pTileInfo != pIn->pTileInfo)
117         {
118             *pTileInfo = *pIn->pTileInfo;
119         }
120     }
121     else
122     {
123         memset(pTileInfo, 0, sizeof(ADDR_TILEINFO));
124     }
125 
126     // For macro tile mode, we should calculate default tiling parameters
127     HwlSetupTileInfo(tileMode,
128                      flags,
129                      bpp,
130                      pitch,
131                      height,
132                      numSamples,
133                      pIn->pTileInfo,
134                      pTileInfo,
135                      pIn->tileType,
136                      pOut);
137 
138     if (flags.cube)
139     {
140         if (mipLevel == 0)
141         {
142             padDims = 2;
143         }
144 
145         if (numSlices == 1)
146         {
147             // This is calculating one face, remove cube flag
148             flags.cube = 0;
149         }
150     }
151 
152     switch (tileMode)
153     {
154         case ADDR_TM_LINEAR_GENERAL://fall through
155         case ADDR_TM_LINEAR_ALIGNED:
156             valid = ComputeSurfaceInfoLinear(pIn, pOut, padDims);
157             break;
158 
159         case ADDR_TM_1D_TILED_THIN1://fall through
160         case ADDR_TM_1D_TILED_THICK:
161             valid = ComputeSurfaceInfoMicroTiled(pIn, pOut, padDims, tileMode);
162             break;
163 
164         case ADDR_TM_2D_TILED_THIN1:    //fall through
165         case ADDR_TM_2D_TILED_THICK:    //fall through
166         case ADDR_TM_3D_TILED_THIN1:    //fall through
167         case ADDR_TM_3D_TILED_THICK:    //fall through
168         case ADDR_TM_2D_TILED_XTHICK:   //fall through
169         case ADDR_TM_3D_TILED_XTHICK:   //fall through
170         case ADDR_TM_PRT_TILED_THIN1:   //fall through
171         case ADDR_TM_PRT_2D_TILED_THIN1://fall through
172         case ADDR_TM_PRT_3D_TILED_THIN1://fall through
173         case ADDR_TM_PRT_TILED_THICK:   //fall through
174         case ADDR_TM_PRT_2D_TILED_THICK://fall through
175         case ADDR_TM_PRT_3D_TILED_THICK:
176             valid = ComputeSurfaceInfoMacroTiled(pIn, pOut, padDims, tileMode);
177             break;
178 
179         default:
180             valid = FALSE;
181             ADDR_ASSERT_ALWAYS();
182             break;
183     }
184 
185     return valid;
186 }
187 
188 /**
189 ****************************************************************************************************
190 *   EgBasedLib::ComputeSurfaceInfoLinear
191 *
192 *   @brief
193 *       Compute linear surface sizes include padded pitch, height, slices, total size in
194 *       bytes, meanwhile alignments as well. Since it is linear mode, so output tile mode
195 *       will not be changed here. Results are returned through output parameters.
196 *
197 *   @return
198 *       TRUE if no error occurs
199 ****************************************************************************************************
200 */
ComputeSurfaceInfoLinear(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut,UINT_32 padDims) const201 BOOL_32 EgBasedLib::ComputeSurfaceInfoLinear(
202     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,    ///< [in] Input structure
203     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut,   ///< [out] Output structure
204     UINT_32                                 padDims ///< [in] Dimensions to padd
205     ) const
206 {
207     UINT_32 expPitch = pIn->width;
208     UINT_32 expHeight = pIn->height;
209     UINT_32 expNumSlices = pIn->numSlices;
210 
211     // No linear MSAA on real H/W, keep this for TGL
212     UINT_32 numSamples = pOut->numSamples;
213 
214     const UINT_32 microTileThickness = 1;
215 
216     //
217     // Compute the surface alignments.
218     //
219     ComputeSurfaceAlignmentsLinear(pIn->tileMode,
220                                    pIn->bpp,
221                                    pIn->flags,
222                                    &pOut->baseAlign,
223                                    &pOut->pitchAlign,
224                                    &pOut->heightAlign);
225 
226     if ((pIn->tileMode == ADDR_TM_LINEAR_GENERAL) && pIn->flags.color && (pIn->height > 1))
227     {
228 #if !ALT_TEST
229         // When linear_general surface is accessed in multiple lines, it requires 8 pixels in pitch
230         // alignment since PITCH_TILE_MAX is in unit of 8 pixels.
231         // It is OK if it is accessed per line.
232         ADDR_ASSERT((pIn->width % 8) == 0);
233 #endif
234     }
235 
236     pOut->depthAlign = microTileThickness;
237 
238     expPitch = HwlPreHandleBaseLvl3xPitch(pIn, expPitch);
239 
240     //
241     // Pad pitch and height to the required granularities.
242     //
243     PadDimensions(pIn->tileMode,
244                   pIn->bpp,
245                   pIn->flags,
246                   numSamples,
247                   pOut->pTileInfo,
248                   padDims,
249                   pIn->mipLevel,
250                   &expPitch, &pOut->pitchAlign,
251                   &expHeight, pOut->heightAlign,
252                   &expNumSlices, microTileThickness);
253 
254     expPitch = HwlPostHandleBaseLvl3xPitch(pIn, expPitch);
255 
256     //
257     // Adjust per HWL
258     //
259 
260     UINT_64 logicalSliceSize;
261 
262     logicalSliceSize = HwlGetSizeAdjustmentLinear(pIn->tileMode,
263                                                   pIn->bpp,
264                                                   numSamples,
265                                                   pOut->baseAlign,
266                                                   pOut->pitchAlign,
267                                                   &expPitch,
268                                                   &expHeight,
269                                                   &pOut->heightAlign);
270 
271     if ((pIn->pitchAlign != 0) || (pIn->heightAlign != 0))
272     {
273         if (pIn->pitchAlign != 0)
274         {
275            ADDR_ASSERT((pIn->pitchAlign % pOut->pitchAlign) == 0);
276            pOut->pitchAlign = pIn->pitchAlign;
277 
278             if (IsPow2(pOut->pitchAlign))
279             {
280                 expPitch = PowTwoAlign(expPitch, pOut->pitchAlign);
281             }
282             else
283             {
284                 expPitch += pOut->pitchAlign - 1;
285                 expPitch /= pOut->pitchAlign;
286                 expPitch *= pOut->pitchAlign;
287             }
288         }
289 
290         if (pIn->heightAlign != 0)
291         {
292            ADDR_ASSERT((pIn->heightAlign % pOut->heightAlign) == 0);
293            pOut->heightAlign = pIn->heightAlign;
294 
295             if (IsPow2(pOut->heightAlign))
296             {
297                 expHeight = PowTwoAlign(expHeight, pOut->heightAlign);
298             }
299             else
300             {
301                 expHeight += pOut->heightAlign - 1;
302                 expHeight /= pOut->heightAlign;
303                 expHeight *= pOut->heightAlign;
304             }
305         }
306 
307         logicalSliceSize = BITS_TO_BYTES(expPitch * expHeight * pIn->bpp);
308     }
309 
310     pOut->pitch = expPitch;
311     pOut->height = expHeight;
312     pOut->depth = expNumSlices;
313 
314     pOut->surfSize = logicalSliceSize * expNumSlices;
315 
316     pOut->tileMode = pIn->tileMode;
317 
318     return TRUE;
319 }
320 
321 /**
322 ****************************************************************************************************
323 *   EgBasedLib::ComputeSurfaceInfoMicroTiled
324 *
325 *   @brief
326 *       Compute 1D/Micro Tiled surface sizes include padded pitch, height, slices, total
327 *       size in bytes, meanwhile alignments as well. Results are returned through output
328 *       parameters.
329 *
330 *   @return
331 *       TRUE if no error occurs
332 ****************************************************************************************************
333 */
ComputeSurfaceInfoMicroTiled(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut,UINT_32 padDims,AddrTileMode expTileMode) const334 BOOL_32 EgBasedLib::ComputeSurfaceInfoMicroTiled(
335     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] Input structure
336     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut,       ///< [out] Output structure
337     UINT_32                                 padDims,    ///< [in] Dimensions to padd
338     AddrTileMode                            expTileMode ///< [in] Expected tile mode
339     ) const
340 {
341     BOOL_32 valid = TRUE;
342 
343     UINT_32 microTileThickness;
344     UINT_32 expPitch = pIn->width;
345     UINT_32 expHeight = pIn->height;
346     UINT_32 expNumSlices = pIn->numSlices;
347 
348     // No 1D MSAA on real H/W, keep this for TGL
349     UINT_32 numSamples = pOut->numSamples;
350 
351     //
352     // Compute the micro tile thickness.
353     //
354     microTileThickness = Thickness(expTileMode);
355 
356     //
357     // Extra override for mip levels
358     //
359     if (pIn->mipLevel > 0)
360     {
361         //
362         // Reduce tiling mode from thick to thin if the number of slices is less than the
363         // micro tile thickness.
364         //
365         if ((expTileMode == ADDR_TM_1D_TILED_THICK) &&
366             (expNumSlices < ThickTileThickness))
367         {
368             expTileMode = HwlDegradeThickTileMode(ADDR_TM_1D_TILED_THICK, expNumSlices, NULL);
369             if (expTileMode != ADDR_TM_1D_TILED_THICK)
370             {
371                 microTileThickness = 1;
372             }
373         }
374     }
375 
376     //
377     // Compute the surface restrictions.
378     //
379     ComputeSurfaceAlignmentsMicroTiled(expTileMode,
380                                        pIn->bpp,
381                                        pIn->flags,
382                                        pIn->mipLevel,
383                                        numSamples,
384                                        &pOut->baseAlign,
385                                        &pOut->pitchAlign,
386                                        &pOut->heightAlign);
387 
388     pOut->depthAlign = microTileThickness;
389 
390     //
391     // Pad pitch and height to the required granularities.
392     // Compute surface size.
393     // Return parameters.
394     //
395     PadDimensions(expTileMode,
396                   pIn->bpp,
397                   pIn->flags,
398                   numSamples,
399                   pOut->pTileInfo,
400                   padDims,
401                   pIn->mipLevel,
402                   &expPitch, &pOut->pitchAlign,
403                   &expHeight, pOut->heightAlign,
404                   &expNumSlices, microTileThickness);
405 
406     //
407     // Get HWL specific pitch adjustment
408     //
409     UINT_64 logicalSliceSize = HwlGetSizeAdjustmentMicroTiled(microTileThickness,
410                                                               pIn->bpp,
411                                                               pIn->flags,
412                                                               numSamples,
413                                                               pOut->baseAlign,
414                                                               pOut->pitchAlign,
415                                                               &expPitch,
416                                                               &expHeight);
417 
418 
419     pOut->pitch = expPitch;
420     pOut->height = expHeight;
421     pOut->depth = expNumSlices;
422 
423     pOut->surfSize = logicalSliceSize * expNumSlices;
424 
425     pOut->tileMode = expTileMode;
426 
427     return valid;
428 }
429 
430 
431 /**
432 ****************************************************************************************************
433 *   EgBasedLib::ComputeSurfaceInfoMacroTiled
434 *
435 *   @brief
436 *       Compute 2D/macro tiled surface sizes include padded pitch, height, slices, total
437 *       size in bytes, meanwhile output suitable tile mode and alignments might be changed
438 *       in this call as well. Results are returned through output parameters.
439 *
440 *   @return
441 *       TRUE if no error occurs
442 ****************************************************************************************************
443 */
ComputeSurfaceInfoMacroTiled(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut,UINT_32 padDims,AddrTileMode expTileMode) const444 BOOL_32 EgBasedLib::ComputeSurfaceInfoMacroTiled(
445     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] Input structure
446     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut,       ///< [out] Output structure
447     UINT_32                                 padDims,    ///< [in] Dimensions to padd
448     AddrTileMode                            expTileMode ///< [in] Expected tile mode
449     ) const
450 {
451     BOOL_32 valid = TRUE;
452 
453     AddrTileMode origTileMode = expTileMode;
454     UINT_32 microTileThickness;
455 
456     UINT_32 paddedPitch;
457     UINT_32 paddedHeight;
458     UINT_64 bytesPerSlice;
459 
460     UINT_32 expPitch     = pIn->width;
461     UINT_32 expHeight    = pIn->height;
462     UINT_32 expNumSlices = pIn->numSlices;
463 
464     UINT_32 numSamples = pOut->numSamples;
465 
466     //
467     // Compute the surface restrictions as base
468     // SanityCheckMacroTiled is called in ComputeSurfaceAlignmentsMacroTiled
469     //
470     valid = ComputeSurfaceAlignmentsMacroTiled(expTileMode,
471                                                pIn->bpp,
472                                                pIn->flags,
473                                                pIn->mipLevel,
474                                                numSamples,
475                                                pOut);
476 
477     if (valid)
478     {
479         //
480         // Compute the micro tile thickness.
481         //
482         microTileThickness = Thickness(expTileMode);
483 
484         //
485         // Find the correct tiling mode for mip levels
486         //
487         if (pIn->mipLevel > 0)
488         {
489             //
490             // Try valid tile mode
491             //
492             expTileMode = ComputeSurfaceMipLevelTileMode(expTileMode,
493                                                          pIn->bpp,
494                                                          expPitch,
495                                                          expHeight,
496                                                          expNumSlices,
497                                                          numSamples,
498                                                          pOut->blockWidth,
499                                                          pOut->blockHeight,
500                                                          pOut->pTileInfo);
501 
502             if (!IsMacroTiled(expTileMode)) // Downgraded to micro-tiled
503             {
504                 return ComputeSurfaceInfoMicroTiled(pIn, pOut, padDims, expTileMode);
505             }
506             else if (microTileThickness != Thickness(expTileMode))
507             {
508                 //
509                 // Re-compute if thickness changed since bank-height may be changed!
510                 //
511                 return ComputeSurfaceInfoMacroTiled(pIn, pOut, padDims, expTileMode);
512             }
513         }
514 
515         paddedPitch     = expPitch;
516         paddedHeight    = expHeight;
517 
518         //
519         // Re-cal alignment
520         //
521         if (expTileMode != origTileMode) // Tile mode is changed but still macro-tiled
522         {
523             valid = ComputeSurfaceAlignmentsMacroTiled(expTileMode,
524                                                        pIn->bpp,
525                                                        pIn->flags,
526                                                        pIn->mipLevel,
527                                                        numSamples,
528                                                        pOut);
529         }
530 
531         //
532         // Do padding
533         //
534         PadDimensions(expTileMode,
535                       pIn->bpp,
536                       pIn->flags,
537                       numSamples,
538                       pOut->pTileInfo,
539                       padDims,
540                       pIn->mipLevel,
541                       &paddedPitch, &pOut->pitchAlign,
542                       &paddedHeight, pOut->heightAlign,
543                       &expNumSlices, microTileThickness);
544 
545         if (pIn->flags.qbStereo &&
546             (pOut->pStereoInfo != NULL))
547         {
548             UINT_32 stereoHeightAlign = HwlStereoCheckRightOffsetPadding(pOut->pTileInfo);
549 
550             if (stereoHeightAlign != 0)
551             {
552                 paddedHeight = PowTwoAlign(paddedHeight, stereoHeightAlign);
553             }
554         }
555 
556         if ((pIn->flags.needEquation == TRUE) &&
557             (m_chipFamily == ADDR_CHIP_FAMILY_SI) &&
558             (pIn->numMipLevels > 1) &&
559             (pIn->mipLevel == 0))
560         {
561             BOOL_32 convertTo1D = FALSE;
562 
563             ADDR_ASSERT(Thickness(expTileMode) == 1);
564 
565             for (UINT_32 i = 1; i < pIn->numMipLevels; i++)
566             {
567                 UINT_32 mipPitch = Max(1u, paddedPitch >> i);
568                 UINT_32 mipHeight = Max(1u, pIn->height >> i);
569                 UINT_32 mipSlices = pIn->flags.volume ?
570                                     Max(1u, pIn->numSlices >> i) : pIn->numSlices;
571                 expTileMode = ComputeSurfaceMipLevelTileMode(expTileMode,
572                                                              pIn->bpp,
573                                                              mipPitch,
574                                                              mipHeight,
575                                                              mipSlices,
576                                                              numSamples,
577                                                              pOut->blockWidth,
578                                                              pOut->blockHeight,
579                                                              pOut->pTileInfo);
580 
581                 if (IsMacroTiled(expTileMode))
582                 {
583                     if (PowTwoAlign(mipPitch, pOut->blockWidth) !=
584                         PowTwoAlign(mipPitch, pOut->pitchAlign))
585                     {
586                         convertTo1D = TRUE;
587                         break;
588                     }
589                 }
590                 else
591                 {
592                     break;
593                 }
594             }
595 
596             if (convertTo1D)
597             {
598                 return ComputeSurfaceInfoMicroTiled(pIn, pOut, padDims, ADDR_TM_1D_TILED_THIN1);
599             }
600         }
601 
602         pOut->pitch = paddedPitch;
603         // Put this check right here to workaround special mipmap cases which the original height
604         // is needed.
605         // The original height is pre-stored in pOut->height in PostComputeMipLevel and
606         // pOut->pitch is needed in HwlCheckLastMacroTiledLvl, too.
607         if (m_configFlags.checkLast2DLevel && (numSamples == 1)) // Don't check MSAA
608         {
609             // Set a TRUE in pOut if next Level is the first 1D sub level
610             HwlCheckLastMacroTiledLvl(pIn, pOut);
611         }
612         pOut->height = paddedHeight;
613 
614         pOut->depth = expNumSlices;
615 
616         //
617         // Compute the size of a slice.
618         //
619         bytesPerSlice = BITS_TO_BYTES(static_cast<UINT_64>(paddedPitch) *
620                                       paddedHeight * NextPow2(pIn->bpp) * numSamples);
621 
622         pOut->surfSize = bytesPerSlice * expNumSlices;
623 
624         pOut->tileMode = expTileMode;
625 
626         pOut->depthAlign = microTileThickness;
627 
628     } // if (valid)
629 
630     return valid;
631 }
632 
633 /**
634 ****************************************************************************************************
635 *   EgBasedLib::ComputeSurfaceAlignmentsLinear
636 *
637 *   @brief
638 *       Compute linear surface alignment, calculation results are returned through
639 *       output parameters.
640 *
641 *   @return
642 *       TRUE if no error occurs
643 ****************************************************************************************************
644 */
ComputeSurfaceAlignmentsLinear(AddrTileMode tileMode,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 * pBaseAlign,UINT_32 * pPitchAlign,UINT_32 * pHeightAlign) const645 BOOL_32 EgBasedLib::ComputeSurfaceAlignmentsLinear(
646     AddrTileMode        tileMode,          ///< [in] tile mode
647     UINT_32             bpp,               ///< [in] bits per pixel
648     ADDR_SURFACE_FLAGS  flags,             ///< [in] surface flags
649     UINT_32*            pBaseAlign,        ///< [out] base address alignment in bytes
650     UINT_32*            pPitchAlign,       ///< [out] pitch alignment in pixels
651     UINT_32*            pHeightAlign       ///< [out] height alignment in pixels
652     ) const
653 {
654     BOOL_32 valid = TRUE;
655 
656     switch (tileMode)
657     {
658         case ADDR_TM_LINEAR_GENERAL:
659             //
660             // The required base alignment and pitch and height granularities is to 1 element.
661             //
662             *pBaseAlign   = (bpp > 8) ? bpp / 8 : 1;
663             *pPitchAlign  = 1;
664             *pHeightAlign = 1;
665             break;
666         case ADDR_TM_LINEAR_ALIGNED:
667             //
668             // The required alignment for base is the pipe interleave size.
669             // The required granularity for pitch is hwl dependent.
670             // The required granularity for height is one row.
671             //
672             *pBaseAlign     = m_pipeInterleaveBytes;
673             *pPitchAlign    = HwlGetPitchAlignmentLinear(bpp, flags);
674             *pHeightAlign   = 1;
675             break;
676         default:
677             *pBaseAlign     = 1;
678             *pPitchAlign    = 1;
679             *pHeightAlign   = 1;
680             ADDR_UNHANDLED_CASE();
681             break;
682     }
683 
684     AdjustPitchAlignment(flags, pPitchAlign);
685 
686     return valid;
687 }
688 
689 /**
690 ****************************************************************************************************
691 *   EgBasedLib::ComputeSurfaceAlignmentsMicroTiled
692 *
693 *   @brief
694 *       Compute 1D tiled surface alignment, calculation results are returned through
695 *       output parameters.
696 *
697 *   @return
698 *       TRUE if no error occurs
699 ****************************************************************************************************
700 */
ComputeSurfaceAlignmentsMicroTiled(AddrTileMode tileMode,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 mipLevel,UINT_32 numSamples,UINT_32 * pBaseAlign,UINT_32 * pPitchAlign,UINT_32 * pHeightAlign) const701 BOOL_32 EgBasedLib::ComputeSurfaceAlignmentsMicroTiled(
702     AddrTileMode        tileMode,          ///< [in] tile mode
703     UINT_32             bpp,               ///< [in] bits per pixel
704     ADDR_SURFACE_FLAGS  flags,             ///< [in] surface flags
705     UINT_32             mipLevel,          ///< [in] mip level
706     UINT_32             numSamples,        ///< [in] number of samples
707     UINT_32*            pBaseAlign,        ///< [out] base address alignment in bytes
708     UINT_32*            pPitchAlign,       ///< [out] pitch alignment in pixels
709     UINT_32*            pHeightAlign       ///< [out] height alignment in pixels
710     ) const
711 {
712     BOOL_32 valid = TRUE;
713 
714     //
715     // The required alignment for base is the pipe interleave size.
716     //
717     *pBaseAlign   = m_pipeInterleaveBytes;
718 
719     *pPitchAlign  = HwlGetPitchAlignmentMicroTiled(tileMode, bpp, flags, numSamples);
720 
721     *pHeightAlign = MicroTileHeight;
722 
723     AdjustPitchAlignment(flags, pPitchAlign);
724 
725     if (flags.czDispCompatible && (mipLevel == 0))
726     {
727         *pBaseAlign  = PowTwoAlign(*pBaseAlign, 4096);                         //Base address MOD 4096 = 0
728         *pPitchAlign = PowTwoAlign(*pPitchAlign, 512 / (BITS_TO_BYTES(bpp)));  //(8 lines * pitch * bytes per pixel) MOD 4096 = 0
729     }
730     // end Carrizo workaround for 1D tilling
731 
732     return valid;
733 }
734 
735 
736 /**
737 ****************************************************************************************************
738 *   EgBasedLib::HwlReduceBankWidthHeight
739 *
740 *   @brief
741 *       Additional checks, reduce bankHeight/bankWidth if needed and possible
742 *       tileSize*BANK_WIDTH*BANK_HEIGHT <= ROW_SIZE
743 *
744 *   @return
745 *       TRUE if no error occurs
746 ****************************************************************************************************
747 */
HwlReduceBankWidthHeight(UINT_32 tileSize,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 numSamples,UINT_32 bankHeightAlign,UINT_32 pipes,ADDR_TILEINFO * pTileInfo) const748 BOOL_32 EgBasedLib::HwlReduceBankWidthHeight(
749     UINT_32             tileSize,           ///< [in] tile size
750     UINT_32             bpp,                ///< [in] bits per pixel
751     ADDR_SURFACE_FLAGS  flags,              ///< [in] surface flags
752     UINT_32             numSamples,         ///< [in] number of samples
753     UINT_32             bankHeightAlign,    ///< [in] bank height alignment
754     UINT_32             pipes,              ///< [in] pipes
755     ADDR_TILEINFO*      pTileInfo           ///< [in,out] bank structure.
756     ) const
757 {
758     UINT_32 macroAspectAlign;
759     BOOL_32 valid = TRUE;
760 
761     if (tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize)
762     {
763         BOOL_32 stillGreater = TRUE;
764 
765         // Try reducing bankWidth first
766         if (stillGreater && pTileInfo->bankWidth > 1)
767         {
768             while (stillGreater && pTileInfo->bankWidth > 0)
769             {
770                 pTileInfo->bankWidth >>= 1;
771 
772                 if (pTileInfo->bankWidth == 0)
773                 {
774                     pTileInfo->bankWidth = 1;
775                     break;
776                 }
777 
778                 stillGreater =
779                     tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize;
780             }
781 
782             // bankWidth is reduced above, so we need to recalculate bankHeight and ratio
783             bankHeightAlign = Max(1u,
784                                   m_pipeInterleaveBytes * m_bankInterleave /
785                                   (tileSize * pTileInfo->bankWidth)
786                                   );
787 
788             // We cannot increase bankHeight so just assert this case.
789             ADDR_ASSERT((pTileInfo->bankHeight % bankHeightAlign) == 0);
790 
791             if (numSamples == 1)
792             {
793                 macroAspectAlign = Max(1u,
794                                    m_pipeInterleaveBytes * m_bankInterleave /
795                                    (tileSize * pipes * pTileInfo->bankWidth)
796                                    );
797                 pTileInfo->macroAspectRatio = PowTwoAlign(pTileInfo->macroAspectRatio,
798                                                           macroAspectAlign);
799             }
800         }
801 
802         // Early quit bank_height degradation for "64" bit z buffer
803         if (flags.depth && bpp >= 64)
804         {
805             stillGreater = FALSE;
806         }
807 
808         // Then try reducing bankHeight
809         if (stillGreater && pTileInfo->bankHeight > bankHeightAlign)
810         {
811             while (stillGreater && pTileInfo->bankHeight > bankHeightAlign)
812             {
813                 pTileInfo->bankHeight >>= 1;
814 
815                 if (pTileInfo->bankHeight < bankHeightAlign)
816                 {
817                     pTileInfo->bankHeight = bankHeightAlign;
818                     break;
819                 }
820 
821                 stillGreater =
822                     tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize;
823             }
824         }
825 
826         valid = !stillGreater;
827 
828         // Generate a warning if we still fail to meet this constraint
829         if (valid == FALSE)
830         {
831             ADDR_WARN(
832                 0, "TILE_SIZE(%d)*BANK_WIDTH(%d)*BANK_HEIGHT(%d) <= ROW_SIZE(%d)",
833                 tileSize, pTileInfo->bankWidth, pTileInfo->bankHeight, m_rowSize);
834         }
835     }
836 
837     return valid;
838 }
839 
840 /**
841 ****************************************************************************************************
842 *   EgBasedLib::ComputeSurfaceAlignmentsMacroTiled
843 *
844 *   @brief
845 *       Compute 2D tiled surface alignment, calculation results are returned through
846 *       output parameters.
847 *
848 *   @return
849 *       TRUE if no error occurs
850 ****************************************************************************************************
851 */
ComputeSurfaceAlignmentsMacroTiled(AddrTileMode tileMode,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 mipLevel,UINT_32 numSamples,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const852 BOOL_32 EgBasedLib::ComputeSurfaceAlignmentsMacroTiled(
853     AddrTileMode                      tileMode,           ///< [in] tile mode
854     UINT_32                           bpp,                ///< [in] bits per pixel
855     ADDR_SURFACE_FLAGS                flags,              ///< [in] surface flags
856     UINT_32                           mipLevel,           ///< [in] mip level
857     UINT_32                           numSamples,         ///< [in] number of samples
858     ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut                ///< [in,out] Surface output
859     ) const
860 {
861     ADDR_TILEINFO* pTileInfo = pOut->pTileInfo;
862 
863     BOOL_32 valid = SanityCheckMacroTiled(pTileInfo);
864 
865     if (valid)
866     {
867         UINT_32 macroTileWidth;
868         UINT_32 macroTileHeight;
869 
870         UINT_32 tileSize;
871         UINT_32 bankHeightAlign;
872         UINT_32 macroAspectAlign;
873 
874         UINT_32 thickness = Thickness(tileMode);
875         UINT_32 pipes = HwlGetPipes(pTileInfo);
876 
877         //
878         // Align bank height first according to latest h/w spec
879         //
880 
881         // tile_size = MIN(tile_split, 64 * tile_thickness * element_bytes * num_samples)
882         tileSize = Min(pTileInfo->tileSplitBytes,
883                        BITS_TO_BYTES(64 * thickness * bpp * numSamples));
884 
885         // bank_height_align =
886         // MAX(1, (pipe_interleave_bytes * bank_interleave)/(tile_size*bank_width))
887         bankHeightAlign = Max(1u,
888                               m_pipeInterleaveBytes * m_bankInterleave /
889                               (tileSize * pTileInfo->bankWidth)
890                               );
891 
892         pTileInfo->bankHeight = PowTwoAlign(pTileInfo->bankHeight, bankHeightAlign);
893 
894         // num_pipes * bank_width * macro_tile_aspect >=
895         // (pipe_interleave_size * bank_interleave) / tile_size
896         if (numSamples == 1)
897         {
898             // this restriction is only for mipmap (mipmap's numSamples must be 1)
899             macroAspectAlign = Max(1u,
900                                    m_pipeInterleaveBytes * m_bankInterleave /
901                                    (tileSize * pipes * pTileInfo->bankWidth)
902                                    );
903             pTileInfo->macroAspectRatio = PowTwoAlign(pTileInfo->macroAspectRatio, macroAspectAlign);
904         }
905 
906         valid = HwlReduceBankWidthHeight(tileSize,
907                                          bpp,
908                                          flags,
909                                          numSamples,
910                                          bankHeightAlign,
911                                          pipes,
912                                          pTileInfo);
913 
914         //
915         // The required granularity for pitch is the macro tile width.
916         //
917         macroTileWidth = MicroTileWidth * pTileInfo->bankWidth * pipes *
918             pTileInfo->macroAspectRatio;
919 
920         pOut->pitchAlign = macroTileWidth;
921         pOut->blockWidth = macroTileWidth;
922 
923         AdjustPitchAlignment(flags, &pOut->pitchAlign);
924 
925         //
926         // The required granularity for height is the macro tile height.
927         //
928         macroTileHeight = MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks /
929             pTileInfo->macroAspectRatio;
930 
931         pOut->heightAlign = macroTileHeight;
932         pOut->blockHeight = macroTileHeight;
933 
934         //
935         // Compute base alignment
936         //
937         pOut->baseAlign =
938             pipes * pTileInfo->bankWidth * pTileInfo->banks * pTileInfo->bankHeight * tileSize;
939 
940         HwlComputeSurfaceAlignmentsMacroTiled(tileMode, bpp, flags, mipLevel, numSamples, pOut);
941     }
942 
943     return valid;
944 }
945 
946 /**
947 ****************************************************************************************************
948 *   EgBasedLib::SanityCheckMacroTiled
949 *
950 *   @brief
951 *       Check if macro-tiled parameters are valid
952 *   @return
953 *       TRUE if valid
954 ****************************************************************************************************
955 */
SanityCheckMacroTiled(ADDR_TILEINFO * pTileInfo) const956 BOOL_32 EgBasedLib::SanityCheckMacroTiled(
957     ADDR_TILEINFO* pTileInfo   ///< [in] macro-tiled parameters
958     ) const
959 {
960     BOOL_32 valid       = TRUE;
961     UINT_32 numPipes    = HwlGetPipes(pTileInfo);
962 
963     switch (pTileInfo->banks)
964     {
965         case 2: //fall through
966         case 4: //fall through
967         case 8: //fall through
968         case 16:
969             break;
970         default:
971             valid = FALSE;
972             break;
973 
974     }
975 
976     if (valid)
977     {
978         switch (pTileInfo->bankWidth)
979         {
980             case 1: //fall through
981             case 2: //fall through
982             case 4: //fall through
983             case 8:
984                 break;
985             default:
986                 valid = FALSE;
987                 break;
988         }
989     }
990 
991     if (valid)
992     {
993         switch (pTileInfo->bankHeight)
994         {
995             case 1: //fall through
996             case 2: //fall through
997             case 4: //fall through
998             case 8:
999                 break;
1000             default:
1001                 valid = FALSE;
1002                 break;
1003         }
1004     }
1005 
1006     if (valid)
1007     {
1008         switch (pTileInfo->macroAspectRatio)
1009         {
1010             case 1: //fall through
1011             case 2: //fall through
1012             case 4: //fall through
1013             case 8:
1014                 break;
1015             default:
1016                 valid = FALSE;
1017                 break;
1018         }
1019     }
1020 
1021     if (valid)
1022     {
1023         if (pTileInfo->banks < pTileInfo->macroAspectRatio)
1024         {
1025             // This will generate macro tile height <= 1
1026             valid = FALSE;
1027         }
1028     }
1029 
1030     if (valid)
1031     {
1032         if (pTileInfo->tileSplitBytes > m_rowSize)
1033         {
1034             ADDR_WARN(0, "tileSplitBytes is bigger than row size");
1035         }
1036     }
1037 
1038     if (valid)
1039     {
1040         valid = HwlSanityCheckMacroTiled(pTileInfo);
1041     }
1042 
1043     ADDR_ASSERT(valid == TRUE);
1044 
1045     // Add this assert for guidance
1046     ADDR_ASSERT(numPipes * pTileInfo->banks >= 4);
1047 
1048     return valid;
1049 }
1050 
1051 /**
1052 ****************************************************************************************************
1053 *   EgBasedLib::ComputeSurfaceMipLevelTileMode
1054 *
1055 *   @brief
1056 *       Compute valid tile mode for surface mipmap sub-levels
1057 *
1058 *   @return
1059 *       Suitable tile mode
1060 ****************************************************************************************************
1061 */
ComputeSurfaceMipLevelTileMode(AddrTileMode baseTileMode,UINT_32 bpp,UINT_32 pitch,UINT_32 height,UINT_32 numSlices,UINT_32 numSamples,UINT_32 pitchAlign,UINT_32 heightAlign,ADDR_TILEINFO * pTileInfo) const1062 AddrTileMode EgBasedLib::ComputeSurfaceMipLevelTileMode(
1063     AddrTileMode        baseTileMode,   ///< [in] base tile mode
1064     UINT_32             bpp,            ///< [in] bits per pixels
1065     UINT_32             pitch,          ///< [in] current level pitch
1066     UINT_32             height,         ///< [in] current level height
1067     UINT_32             numSlices,      ///< [in] current number of slices
1068     UINT_32             numSamples,     ///< [in] number of samples
1069     UINT_32             pitchAlign,     ///< [in] pitch alignment
1070     UINT_32             heightAlign,    ///< [in] height alignment
1071     ADDR_TILEINFO*      pTileInfo       ///< [in] ptr to bank structure
1072     ) const
1073 {
1074     UINT_64 bytesPerSlice;
1075     UINT_32 bytesPerTile;
1076 
1077     AddrTileMode expTileMode = baseTileMode;
1078     UINT_32 microTileThickness = Thickness(expTileMode);
1079     UINT_32 interleaveSize = m_pipeInterleaveBytes * m_bankInterleave;
1080 
1081     //
1082     // Compute the size of a slice.
1083     //
1084     bytesPerSlice = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
1085     bytesPerTile = BITS_TO_BYTES(MicroTilePixels * microTileThickness * NextPow2(bpp) * numSamples);
1086 
1087     //
1088     // Reduce tiling mode from thick to thin if the number of slices is less than the
1089     // micro tile thickness.
1090     //
1091     if (numSlices < microTileThickness)
1092     {
1093         expTileMode = HwlDegradeThickTileMode(expTileMode, numSlices, &bytesPerTile);
1094     }
1095 
1096     if (bytesPerTile > pTileInfo->tileSplitBytes)
1097     {
1098         bytesPerTile = pTileInfo->tileSplitBytes;
1099     }
1100 
1101     UINT_32 threshold1 =
1102         bytesPerTile * HwlGetPipes(pTileInfo) * pTileInfo->bankWidth * pTileInfo->macroAspectRatio;
1103 
1104     UINT_32 threshold2 =
1105         bytesPerTile * pTileInfo->bankWidth * pTileInfo->bankHeight;
1106 
1107     //
1108     // Reduce the tile mode from 2D/3D to 1D in following conditions
1109     //
1110     switch (expTileMode)
1111     {
1112         case ADDR_TM_2D_TILED_THIN1: //fall through
1113         case ADDR_TM_3D_TILED_THIN1:
1114         case ADDR_TM_PRT_TILED_THIN1:
1115         case ADDR_TM_PRT_2D_TILED_THIN1:
1116         case ADDR_TM_PRT_3D_TILED_THIN1:
1117             if ((pitch < pitchAlign) ||
1118                 (height < heightAlign) ||
1119                 (interleaveSize > threshold1) ||
1120                 (interleaveSize > threshold2))
1121             {
1122                 expTileMode = ADDR_TM_1D_TILED_THIN1;
1123             }
1124             break;
1125         case ADDR_TM_2D_TILED_THICK: //fall through
1126         case ADDR_TM_3D_TILED_THICK:
1127         case ADDR_TM_2D_TILED_XTHICK:
1128         case ADDR_TM_3D_TILED_XTHICK:
1129         case ADDR_TM_PRT_TILED_THICK:
1130         case ADDR_TM_PRT_2D_TILED_THICK:
1131         case ADDR_TM_PRT_3D_TILED_THICK:
1132             if ((pitch < pitchAlign) ||
1133                 (height < heightAlign))
1134             {
1135                 expTileMode = ADDR_TM_1D_TILED_THICK;
1136             }
1137             break;
1138         default:
1139             break;
1140     }
1141 
1142     return expTileMode;
1143 }
1144 
1145 /**
1146 ****************************************************************************************************
1147 *   EgBasedLib::HwlGetAlignmentInfoMacroTiled
1148 *   @brief
1149 *       Get alignment info for giving tile mode
1150 *   @return
1151 *       TRUE if getting alignment is OK
1152 ****************************************************************************************************
1153 */
HwlGetAlignmentInfoMacroTiled(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,UINT_32 * pPitchAlign,UINT_32 * pHeightAlign,UINT_32 * pSizeAlign) const1154 BOOL_32 EgBasedLib::HwlGetAlignmentInfoMacroTiled(
1155     const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,             ///< [in] create surface info
1156     UINT_32*                               pPitchAlign,     ///< [out] pitch alignment
1157     UINT_32*                               pHeightAlign,    ///< [out] height alignment
1158     UINT_32*                               pSizeAlign       ///< [out] size alignment
1159     ) const
1160 {
1161     BOOL_32 valid = TRUE;
1162 
1163     ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
1164 
1165     UINT_32 numSamples = (pIn->numFrags == 0) ? pIn->numSamples : pIn->numFrags;
1166 
1167     ADDR_ASSERT(pIn->pTileInfo);
1168     ADDR_TILEINFO tileInfo = *pIn->pTileInfo;
1169     ADDR_COMPUTE_SURFACE_INFO_OUTPUT out = {0};
1170     out.pTileInfo = &tileInfo;
1171 
1172     if (UseTileIndex(pIn->tileIndex))
1173     {
1174         out.tileIndex = pIn->tileIndex;
1175         out.macroModeIndex = TileIndexInvalid;
1176     }
1177 
1178     HwlSetupTileInfo(pIn->tileMode,
1179                      pIn->flags,
1180                      pIn->bpp,
1181                      pIn->width,
1182                      pIn->height,
1183                      numSamples,
1184                      &tileInfo,
1185                      &tileInfo,
1186                      pIn->tileType,
1187                      &out);
1188 
1189     valid = ComputeSurfaceAlignmentsMacroTiled(pIn->tileMode,
1190                                                pIn->bpp,
1191                                                pIn->flags,
1192                                                pIn->mipLevel,
1193                                                numSamples,
1194                                                &out);
1195 
1196     if (valid)
1197     {
1198         *pPitchAlign  = out.pitchAlign;
1199         *pHeightAlign = out.heightAlign;
1200         *pSizeAlign   = out.baseAlign;
1201     }
1202 
1203     return valid;
1204 }
1205 
1206 /**
1207 ****************************************************************************************************
1208 *   EgBasedLib::HwlDegradeThickTileMode
1209 *
1210 *   @brief
1211 *       Degrades valid tile mode for thick modes if needed
1212 *
1213 *   @return
1214 *       Suitable tile mode
1215 ****************************************************************************************************
1216 */
HwlDegradeThickTileMode(AddrTileMode baseTileMode,UINT_32 numSlices,UINT_32 * pBytesPerTile) const1217 AddrTileMode EgBasedLib::HwlDegradeThickTileMode(
1218     AddrTileMode        baseTileMode,   ///< [in] base tile mode
1219     UINT_32             numSlices,      ///< [in] current number of slices
1220     UINT_32*            pBytesPerTile   ///< [in,out] pointer to bytes per slice
1221     ) const
1222 {
1223     ADDR_ASSERT(numSlices < Thickness(baseTileMode));
1224     // if pBytesPerTile is NULL, this is a don't-care....
1225     UINT_32 bytesPerTile = pBytesPerTile != NULL ? *pBytesPerTile : 64;
1226 
1227     AddrTileMode expTileMode = baseTileMode;
1228     switch (baseTileMode)
1229     {
1230         case ADDR_TM_1D_TILED_THICK:
1231             expTileMode = ADDR_TM_1D_TILED_THIN1;
1232             bytesPerTile >>= 2;
1233             break;
1234         case ADDR_TM_2D_TILED_THICK:
1235             expTileMode = ADDR_TM_2D_TILED_THIN1;
1236             bytesPerTile >>= 2;
1237             break;
1238         case ADDR_TM_3D_TILED_THICK:
1239             expTileMode = ADDR_TM_3D_TILED_THIN1;
1240             bytesPerTile >>= 2;
1241             break;
1242         case ADDR_TM_2D_TILED_XTHICK:
1243             if (numSlices < ThickTileThickness)
1244             {
1245                 expTileMode = ADDR_TM_2D_TILED_THIN1;
1246                 bytesPerTile >>= 3;
1247             }
1248             else
1249             {
1250                 expTileMode = ADDR_TM_2D_TILED_THICK;
1251                 bytesPerTile >>= 1;
1252             }
1253             break;
1254         case ADDR_TM_3D_TILED_XTHICK:
1255             if (numSlices < ThickTileThickness)
1256             {
1257                 expTileMode = ADDR_TM_3D_TILED_THIN1;
1258                 bytesPerTile >>= 3;
1259             }
1260             else
1261             {
1262                 expTileMode = ADDR_TM_3D_TILED_THICK;
1263                 bytesPerTile >>= 1;
1264             }
1265             break;
1266         default:
1267             ADDR_ASSERT_ALWAYS();
1268             break;
1269     }
1270 
1271     if (pBytesPerTile != NULL)
1272     {
1273         *pBytesPerTile = bytesPerTile;
1274     }
1275 
1276     return expTileMode;
1277 }
1278 
1279 /**
1280 ****************************************************************************************************
1281 *   EgBasedLib::DispatchComputeSurfaceAddrFromCoord
1282 *
1283 *   @brief
1284 *       Compute surface address from given coord (x, y, slice,sample)
1285 *
1286 *   @return
1287 *       Address in bytes
1288 ****************************************************************************************************
1289 */
DispatchComputeSurfaceAddrFromCoord(const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const1290 UINT_64 EgBasedLib::DispatchComputeSurfaceAddrFromCoord(
1291     const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
1292     ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
1293     ) const
1294 {
1295     UINT_32             x                  = pIn->x;
1296     UINT_32             y                  = pIn->y;
1297     UINT_32             slice              = pIn->slice;
1298     UINT_32             sample             = pIn->sample;
1299     UINT_32             bpp                = pIn->bpp;
1300     UINT_32             pitch              = pIn->pitch;
1301     UINT_32             height             = pIn->height;
1302     UINT_32             numSlices          = pIn->numSlices;
1303     UINT_32             numSamples         = ((pIn->numSamples == 0) ? 1 : pIn->numSamples);
1304     UINT_32             numFrags           = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
1305     AddrTileMode        tileMode           = pIn->tileMode;
1306     AddrTileType        microTileType      = pIn->tileType;
1307     BOOL_32             ignoreSE           = pIn->ignoreSE;
1308     BOOL_32             isDepthSampleOrder = pIn->isDepth;
1309     ADDR_TILEINFO*      pTileInfo          = pIn->pTileInfo;
1310 
1311     UINT_32*            pBitPosition       = &pOut->bitPosition;
1312     UINT_64             addr;
1313 
1314     // ADDR_DEPTH_SAMPLE_ORDER = non-disp + depth-sample-order
1315     if (microTileType == ADDR_DEPTH_SAMPLE_ORDER)
1316     {
1317         isDepthSampleOrder = TRUE;
1318     }
1319 
1320     if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
1321     {
1322         if (numFrags != numSamples)
1323         {
1324             numSamples = numFrags;
1325             ADDR_ASSERT(sample < numSamples);
1326         }
1327 
1328         /// @note
1329         /// 128 bit/thick tiled surface doesn't support display tiling and
1330         /// mipmap chain must have the same tileType, so please fill tileType correctly
1331         if (IsLinear(pIn->tileMode) == FALSE)
1332         {
1333             if (bpp >= 128 || Thickness(tileMode) > 1)
1334             {
1335                 ADDR_ASSERT(microTileType != ADDR_DISPLAYABLE);
1336             }
1337         }
1338     }
1339 
1340     switch (tileMode)
1341     {
1342         case ADDR_TM_LINEAR_GENERAL://fall through
1343         case ADDR_TM_LINEAR_ALIGNED:
1344             addr = ComputeSurfaceAddrFromCoordLinear(x,
1345                                                      y,
1346                                                      slice,
1347                                                      sample,
1348                                                      bpp,
1349                                                      pitch,
1350                                                      height,
1351                                                      numSlices,
1352                                                      pBitPosition);
1353             break;
1354         case ADDR_TM_1D_TILED_THIN1://fall through
1355         case ADDR_TM_1D_TILED_THICK:
1356             addr = ComputeSurfaceAddrFromCoordMicroTiled(x,
1357                                                          y,
1358                                                          slice,
1359                                                          sample,
1360                                                          bpp,
1361                                                          pitch,
1362                                                          height,
1363                                                          numSamples,
1364                                                          tileMode,
1365                                                          microTileType,
1366                                                          isDepthSampleOrder,
1367                                                          pBitPosition);
1368             break;
1369         case ADDR_TM_2D_TILED_THIN1:    //fall through
1370         case ADDR_TM_2D_TILED_THICK:    //fall through
1371         case ADDR_TM_3D_TILED_THIN1:    //fall through
1372         case ADDR_TM_3D_TILED_THICK:    //fall through
1373         case ADDR_TM_2D_TILED_XTHICK:   //fall through
1374         case ADDR_TM_3D_TILED_XTHICK:   //fall through
1375         case ADDR_TM_PRT_TILED_THIN1:   //fall through
1376         case ADDR_TM_PRT_2D_TILED_THIN1://fall through
1377         case ADDR_TM_PRT_3D_TILED_THIN1://fall through
1378         case ADDR_TM_PRT_TILED_THICK:   //fall through
1379         case ADDR_TM_PRT_2D_TILED_THICK://fall through
1380         case ADDR_TM_PRT_3D_TILED_THICK:
1381             UINT_32 pipeSwizzle;
1382             UINT_32 bankSwizzle;
1383 
1384             if (m_configFlags.useCombinedSwizzle)
1385             {
1386                 ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo,
1387                                        &bankSwizzle, &pipeSwizzle);
1388             }
1389             else
1390             {
1391                 pipeSwizzle = pIn->pipeSwizzle;
1392                 bankSwizzle = pIn->bankSwizzle;
1393             }
1394 
1395             addr = ComputeSurfaceAddrFromCoordMacroTiled(x,
1396                                                          y,
1397                                                          slice,
1398                                                          sample,
1399                                                          bpp,
1400                                                          pitch,
1401                                                          height,
1402                                                          numSamples,
1403                                                          tileMode,
1404                                                          microTileType,
1405                                                          ignoreSE,
1406                                                          isDepthSampleOrder,
1407                                                          pipeSwizzle,
1408                                                          bankSwizzle,
1409                                                          pTileInfo,
1410                                                          pBitPosition);
1411             break;
1412         default:
1413             addr = 0;
1414             ADDR_ASSERT_ALWAYS();
1415             break;
1416     }
1417 
1418     return addr;
1419 }
1420 
1421 /**
1422 ****************************************************************************************************
1423 *   EgBasedLib::ComputeMacroTileEquation
1424 *
1425 *   @brief
1426 *       Computes the address equation in macro tile
1427 *   @return
1428 *       If equation can be computed
1429 ****************************************************************************************************
1430 */
ComputeMacroTileEquation(UINT_32 log2BytesPP,AddrTileMode tileMode,AddrTileType microTileType,ADDR_TILEINFO * pTileInfo,ADDR_EQUATION * pEquation) const1431 ADDR_E_RETURNCODE EgBasedLib::ComputeMacroTileEquation(
1432     UINT_32             log2BytesPP,            ///< [in] log2 of bytes per pixel
1433     AddrTileMode        tileMode,               ///< [in] tile mode
1434     AddrTileType        microTileType,          ///< [in] micro tiling type
1435     ADDR_TILEINFO*      pTileInfo,              ///< [in] bank structure
1436     ADDR_EQUATION*      pEquation               ///< [out] Equation for addressing in macro tile
1437     ) const
1438 {
1439     ADDR_E_RETURNCODE retCode;
1440 
1441     // Element equation within a tile
1442     retCode = ComputeMicroTileEquation(log2BytesPP, tileMode, microTileType, pEquation);
1443 
1444     if (retCode == ADDR_OK)
1445     {
1446         // Tile equesiton with signle pipe bank
1447         UINT_32 numPipes              = HwlGetPipes(pTileInfo);
1448         UINT_32 numPipeBits           = Log2(numPipes);
1449 
1450         for (UINT_32 i = 0; i < Log2(pTileInfo->bankWidth); i++)
1451         {
1452             pEquation->addr[pEquation->numBits].valid = 1;
1453             pEquation->addr[pEquation->numBits].channel = 0;
1454             pEquation->addr[pEquation->numBits].index = i + log2BytesPP + 3 + numPipeBits;
1455             pEquation->numBits++;
1456         }
1457 
1458         for (UINT_32 i = 0; i < Log2(pTileInfo->bankHeight); i++)
1459         {
1460             pEquation->addr[pEquation->numBits].valid = 1;
1461             pEquation->addr[pEquation->numBits].channel = 1;
1462             pEquation->addr[pEquation->numBits].index = i + 3;
1463             pEquation->numBits++;
1464         }
1465 
1466         ADDR_EQUATION equation;
1467         memset(&equation, 0, sizeof(ADDR_EQUATION));
1468 
1469         UINT_32 thresholdX = 32;
1470         UINT_32 thresholdY = 32;
1471 
1472         if (IsPrtNoRotationTileMode(tileMode))
1473         {
1474             UINT_32 macroTilePitch  =
1475                 (MicroTileWidth  * pTileInfo->bankWidth  * numPipes) * pTileInfo->macroAspectRatio;
1476             UINT_32 macroTileHeight =
1477                 (MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks) /
1478                 pTileInfo->macroAspectRatio;
1479             thresholdX = Log2(macroTilePitch);
1480             thresholdY = Log2(macroTileHeight);
1481         }
1482 
1483         // Pipe equation
1484         retCode = ComputePipeEquation(log2BytesPP, thresholdX, thresholdY, pTileInfo, &equation);
1485 
1486         if (retCode == ADDR_OK)
1487         {
1488             UINT_32 pipeBitStart = Log2(m_pipeInterleaveBytes);
1489 
1490             if (pEquation->numBits > pipeBitStart)
1491             {
1492                 UINT_32 numLeftShift = pEquation->numBits - pipeBitStart;
1493 
1494                 for (UINT_32 i = 0; i < numLeftShift; i++)
1495                 {
1496                     pEquation->addr[pEquation->numBits + equation.numBits - i - 1] =
1497                         pEquation->addr[pEquation->numBits - i - 1];
1498                     pEquation->xor1[pEquation->numBits + equation.numBits - i - 1] =
1499                         pEquation->xor1[pEquation->numBits - i - 1];
1500                     pEquation->xor2[pEquation->numBits + equation.numBits - i - 1] =
1501                         pEquation->xor2[pEquation->numBits - i - 1];
1502                 }
1503             }
1504 
1505             for (UINT_32 i = 0; i < equation.numBits; i++)
1506             {
1507                 pEquation->addr[pipeBitStart + i] = equation.addr[i];
1508                 pEquation->xor1[pipeBitStart + i] = equation.xor1[i];
1509                 pEquation->xor2[pipeBitStart + i] = equation.xor2[i];
1510                 pEquation->numBits++;
1511             }
1512 
1513             // Bank equation
1514             memset(&equation, 0, sizeof(ADDR_EQUATION));
1515 
1516             retCode = ComputeBankEquation(log2BytesPP, thresholdX, thresholdY,
1517                                           pTileInfo, &equation);
1518 
1519             if (retCode == ADDR_OK)
1520             {
1521                 UINT_32 bankBitStart = pipeBitStart + numPipeBits + Log2(m_bankInterleave);
1522 
1523                 if (pEquation->numBits > bankBitStart)
1524                 {
1525                     UINT_32 numLeftShift = pEquation->numBits - bankBitStart;
1526 
1527                     for (UINT_32 i = 0; i < numLeftShift; i++)
1528                     {
1529                         pEquation->addr[pEquation->numBits + equation.numBits - i - 1] =
1530                             pEquation->addr[pEquation->numBits - i - 1];
1531                         pEquation->xor1[pEquation->numBits + equation.numBits - i - 1] =
1532                             pEquation->xor1[pEquation->numBits - i - 1];
1533                         pEquation->xor2[pEquation->numBits + equation.numBits - i - 1] =
1534                             pEquation->xor2[pEquation->numBits - i - 1];
1535                     }
1536                 }
1537 
1538                 for (UINT_32 i = 0; i < equation.numBits; i++)
1539                 {
1540                     pEquation->addr[bankBitStart + i] = equation.addr[i];
1541                     pEquation->xor1[bankBitStart + i] = equation.xor1[i];
1542                     pEquation->xor2[bankBitStart + i] = equation.xor2[i];
1543                     pEquation->numBits++;
1544                 }
1545 
1546                 FillEqBitComponents(pEquation);
1547             }
1548         }
1549     }
1550 
1551     return retCode;
1552 }
1553 
1554 /**
1555 ****************************************************************************************************
1556 *   EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1557 *
1558 *   @brief
1559 *       Computes the surface address and bit position from a
1560 *       coordinate for 2D tilied (macro tiled)
1561 *   @return
1562 *       The byte address
1563 ****************************************************************************************************
1564 */
ComputeSurfaceAddrFromCoordMacroTiled(UINT_32 x,UINT_32 y,UINT_32 slice,UINT_32 sample,UINT_32 bpp,UINT_32 pitch,UINT_32 height,UINT_32 numSamples,AddrTileMode tileMode,AddrTileType microTileType,BOOL_32 ignoreSE,BOOL_32 isDepthSampleOrder,UINT_32 pipeSwizzle,UINT_32 bankSwizzle,ADDR_TILEINFO * pTileInfo,UINT_32 * pBitPosition) const1565 UINT_64 EgBasedLib::ComputeSurfaceAddrFromCoordMacroTiled(
1566     UINT_32             x,                      ///< [in] x coordinate
1567     UINT_32             y,                      ///< [in] y coordinate
1568     UINT_32             slice,                  ///< [in] slice index
1569     UINT_32             sample,                 ///< [in] sample index
1570     UINT_32             bpp,                    ///< [in] bits per pixel
1571     UINT_32             pitch,                  ///< [in] surface pitch, in pixels
1572     UINT_32             height,                 ///< [in] surface height, in pixels
1573     UINT_32             numSamples,             ///< [in] number of samples
1574     AddrTileMode        tileMode,               ///< [in] tile mode
1575     AddrTileType        microTileType,          ///< [in] micro tiling type
1576     BOOL_32             ignoreSE,               ///< [in] TRUE if shader enginers can be ignored
1577     BOOL_32             isDepthSampleOrder,     ///< [in] TRUE if it depth sample ordering is used
1578     UINT_32             pipeSwizzle,            ///< [in] pipe swizzle
1579     UINT_32             bankSwizzle,            ///< [in] bank swizzle
1580     ADDR_TILEINFO*      pTileInfo,              ///< [in] bank structure
1581                                                 ///  **All fields to be valid on entry**
1582     UINT_32*            pBitPosition            ///< [out] bit position, e.g. FMT_1 will use this
1583     ) const
1584 {
1585     UINT_64 addr;
1586 
1587     UINT_32 microTileBytes;
1588     UINT_32 microTileBits;
1589     UINT_32 sampleOffset;
1590     UINT_32 pixelIndex;
1591     UINT_32 pixelOffset;
1592     UINT_32 elementOffset;
1593     UINT_32 tileSplitSlice;
1594     UINT_32 pipe;
1595     UINT_32 bank;
1596     UINT_64 sliceBytes;
1597     UINT_64 sliceOffset;
1598     UINT_32 macroTilePitch;
1599     UINT_32 macroTileHeight;
1600     UINT_32 macroTilesPerRow;
1601     UINT_32 macroTilesPerSlice;
1602     UINT_64 macroTileBytes;
1603     UINT_32 macroTileIndexX;
1604     UINT_32 macroTileIndexY;
1605     UINT_64 macroTileOffset;
1606     UINT_64 totalOffset;
1607     UINT_64 pipeInterleaveMask;
1608     UINT_64 bankInterleaveMask;
1609     UINT_64 pipeInterleaveOffset;
1610     UINT_32 bankInterleaveOffset;
1611     UINT_64 offset;
1612     UINT_32 tileRowIndex;
1613     UINT_32 tileColumnIndex;
1614     UINT_32 tileIndex;
1615     UINT_32 tileOffset;
1616 
1617     UINT_32 microTileThickness = Thickness(tileMode);
1618 
1619     //
1620     // Compute the number of group, pipe, and bank bits.
1621     //
1622     UINT_32 numPipes              = HwlGetPipes(pTileInfo);
1623     UINT_32 numPipeInterleaveBits = Log2(m_pipeInterleaveBytes);
1624     UINT_32 numPipeBits           = Log2(numPipes);
1625     UINT_32 numBankInterleaveBits = Log2(m_bankInterleave);
1626     UINT_32 numBankBits           = Log2(pTileInfo->banks);
1627 
1628     //
1629     // Compute the micro tile size.
1630     //
1631     microTileBits = MicroTilePixels * microTileThickness * bpp * numSamples;
1632 
1633     microTileBytes = microTileBits / 8;
1634     //
1635     // Compute the pixel index within the micro tile.
1636     //
1637     pixelIndex = ComputePixelIndexWithinMicroTile(x,
1638                                                   y,
1639                                                   slice,
1640                                                   bpp,
1641                                                   tileMode,
1642                                                   microTileType);
1643 
1644     //
1645     // Compute the sample offset and pixel offset.
1646     //
1647     if (isDepthSampleOrder)
1648     {
1649         //
1650         // For depth surfaces, samples are stored contiguously for each element, so the sample
1651         // offset is the sample number times the element size.
1652         //
1653         sampleOffset = sample * bpp;
1654         pixelOffset  = pixelIndex * bpp * numSamples;
1655     }
1656     else
1657     {
1658         //
1659         // For color surfaces, all elements for a particular sample are stored contiguously, so
1660         // the sample offset is the sample number times the micro tile size divided yBit the number
1661         // of samples.
1662         //
1663         sampleOffset = sample * (microTileBits / numSamples);
1664         pixelOffset  = pixelIndex * bpp;
1665     }
1666 
1667     //
1668     // Compute the element offset.
1669     //
1670     elementOffset = pixelOffset + sampleOffset;
1671 
1672     *pBitPosition = static_cast<UINT_32>(elementOffset % 8);
1673 
1674     elementOffset /= 8; //bit-to-byte
1675 
1676     //
1677     // Determine if tiles need to be split across slices.
1678     //
1679     // If the size of the micro tile is larger than the tile split size, then the tile will be
1680     // split across multiple slices.
1681     //
1682     UINT_32 slicesPerTile = 1;
1683 
1684     if ((microTileBytes > pTileInfo->tileSplitBytes) && (microTileThickness == 1))
1685     {   //don't support for thick mode
1686 
1687         //
1688         // Compute the number of slices per tile.
1689         //
1690         slicesPerTile = microTileBytes / pTileInfo->tileSplitBytes;
1691 
1692         //
1693         // Compute the tile split slice number for use in rotating the bank.
1694         //
1695         tileSplitSlice = elementOffset / pTileInfo->tileSplitBytes;
1696 
1697         //
1698         // Adjust the element offset to account for the portion of the tile that is being moved to
1699         // a new slice..
1700         //
1701         elementOffset %= pTileInfo->tileSplitBytes;
1702 
1703         //
1704         // Adjust the microTileBytes size to tileSplitBytes size since
1705         // a new slice..
1706         //
1707         microTileBytes = pTileInfo->tileSplitBytes;
1708     }
1709     else
1710     {
1711         tileSplitSlice = 0;
1712     }
1713 
1714     //
1715     // Compute macro tile pitch and height.
1716     //
1717     macroTilePitch  =
1718         (MicroTileWidth  * pTileInfo->bankWidth  * numPipes) * pTileInfo->macroAspectRatio;
1719     macroTileHeight =
1720         (MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks) / pTileInfo->macroAspectRatio;
1721 
1722     //
1723     // Compute the number of bytes per macro tile. Note: bytes of the same bank/pipe actually
1724     //
1725     macroTileBytes =
1726         static_cast<UINT_64>(microTileBytes) *
1727         (macroTilePitch / MicroTileWidth) * (macroTileHeight / MicroTileHeight) /
1728         (numPipes * pTileInfo->banks);
1729 
1730     //
1731     // Compute the number of macro tiles per row.
1732     //
1733     macroTilesPerRow = pitch / macroTilePitch;
1734 
1735     //
1736     // Compute the offset to the macro tile containing the specified coordinate.
1737     //
1738     macroTileIndexX = x / macroTilePitch;
1739     macroTileIndexY = y / macroTileHeight;
1740     macroTileOffset = ((macroTileIndexY * macroTilesPerRow) + macroTileIndexX) * macroTileBytes;
1741 
1742     //
1743     // Compute the number of macro tiles per slice.
1744     //
1745     macroTilesPerSlice = macroTilesPerRow  * (height / macroTileHeight);
1746 
1747     //
1748     // Compute the slice size.
1749     //
1750     sliceBytes = macroTilesPerSlice * macroTileBytes;
1751 
1752     //
1753     // Compute the slice offset.
1754     //
1755     sliceOffset = sliceBytes * (tileSplitSlice + slicesPerTile * (slice / microTileThickness));
1756 
1757     //
1758     // Compute tile offest
1759     //
1760     tileRowIndex    = (y / MicroTileHeight) % pTileInfo->bankHeight;
1761     tileColumnIndex = ((x / MicroTileWidth) / numPipes) % pTileInfo->bankWidth;
1762     tileIndex        = (tileRowIndex * pTileInfo->bankWidth) + tileColumnIndex;
1763     tileOffset       = tileIndex * microTileBytes;
1764 
1765     //
1766     // Combine the slice offset and macro tile offset with the pixel and sample offsets, accounting
1767     // for the pipe and bank bits in the middle of the address.
1768     //
1769     totalOffset = sliceOffset + macroTileOffset + elementOffset + tileOffset;
1770 
1771     //
1772     // Get the pipe and bank.
1773     //
1774 
1775     // when the tileMode is PRT type, then adjust x and y coordinates
1776     if (IsPrtNoRotationTileMode(tileMode))
1777     {
1778         x = x % macroTilePitch;
1779         y = y % macroTileHeight;
1780     }
1781 
1782     pipe = ComputePipeFromCoord(x,
1783                                 y,
1784                                 slice,
1785                                 tileMode,
1786                                 pipeSwizzle,
1787                                 ignoreSE,
1788                                 pTileInfo);
1789 
1790     bank = ComputeBankFromCoord(x,
1791                                 y,
1792                                 slice,
1793                                 tileMode,
1794                                 bankSwizzle,
1795                                 tileSplitSlice,
1796                                 pTileInfo);
1797 
1798 
1799     //
1800     // Split the offset to put some bits below the pipe+bank bits and some above.
1801     //
1802     pipeInterleaveMask = (1 << numPipeInterleaveBits) - 1;
1803     bankInterleaveMask = (1 << numBankInterleaveBits) - 1;
1804     pipeInterleaveOffset = totalOffset & pipeInterleaveMask;
1805     bankInterleaveOffset = static_cast<UINT_32>((totalOffset >> numPipeInterleaveBits) &
1806                                                 bankInterleaveMask);
1807     offset               =  totalOffset >> (numPipeInterleaveBits + numBankInterleaveBits);
1808 
1809     //
1810     // Assemble the address from its components.
1811     //
1812     addr  = pipeInterleaveOffset;
1813     // This is to remove /analyze warnings
1814     UINT_32 pipeBits            = pipe                 <<  numPipeInterleaveBits;
1815     UINT_32 bankInterleaveBits  = bankInterleaveOffset << (numPipeInterleaveBits + numPipeBits);
1816     UINT_32 bankBits            = bank                 << (numPipeInterleaveBits + numPipeBits +
1817                                                            numBankInterleaveBits);
1818     UINT_64 offsetBits          = offset               << (numPipeInterleaveBits + numPipeBits +
1819                                                            numBankInterleaveBits + numBankBits);
1820 
1821     addr |= pipeBits;
1822     addr |= bankInterleaveBits;
1823     addr |= bankBits;
1824     addr |= offsetBits;
1825 
1826     return addr;
1827 }
1828 
1829 /**
1830 ****************************************************************************************************
1831 *   EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1832 *
1833 *   @brief
1834 *       Computes the surface address and bit position from a coordinate for 1D tilied
1835 *       (micro tiled)
1836 *   @return
1837 *       The byte address
1838 ****************************************************************************************************
1839 */
ComputeSurfaceAddrFromCoordMicroTiled(UINT_32 x,UINT_32 y,UINT_32 slice,UINT_32 sample,UINT_32 bpp,UINT_32 pitch,UINT_32 height,UINT_32 numSamples,AddrTileMode tileMode,AddrTileType microTileType,BOOL_32 isDepthSampleOrder,UINT_32 * pBitPosition) const1840 UINT_64 EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled(
1841     UINT_32             x,                      ///< [in] x coordinate
1842     UINT_32             y,                      ///< [in] y coordinate
1843     UINT_32             slice,                  ///< [in] slice index
1844     UINT_32             sample,                 ///< [in] sample index
1845     UINT_32             bpp,                    ///< [in] bits per pixel
1846     UINT_32             pitch,                  ///< [in] pitch, in pixels
1847     UINT_32             height,                 ///< [in] height, in pixels
1848     UINT_32             numSamples,             ///< [in] number of samples
1849     AddrTileMode        tileMode,               ///< [in] tile mode
1850     AddrTileType        microTileType,          ///< [in] micro tiling type
1851     BOOL_32             isDepthSampleOrder,     ///< [in] TRUE if depth sample ordering is used
1852     UINT_32*            pBitPosition            ///< [out] bit position, e.g. FMT_1 will use this
1853     ) const
1854 {
1855     UINT_64 addr = 0;
1856 
1857     UINT_32 microTileBytes;
1858     UINT_64 sliceBytes;
1859     UINT_32 microTilesPerRow;
1860     UINT_32 microTileIndexX;
1861     UINT_32 microTileIndexY;
1862     UINT_32 microTileIndexZ;
1863     UINT_64 sliceOffset;
1864     UINT_64 microTileOffset;
1865     UINT_32 sampleOffset;
1866     UINT_32 pixelIndex;
1867     UINT_32 pixelOffset;
1868 
1869     UINT_32 microTileThickness = Thickness(tileMode);
1870 
1871     //
1872     // Compute the micro tile size.
1873     //
1874     microTileBytes = BITS_TO_BYTES(MicroTilePixels * microTileThickness * bpp * numSamples);
1875 
1876     //
1877     // Compute the slice size.
1878     //
1879     sliceBytes =
1880         BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * microTileThickness * bpp * numSamples);
1881 
1882     //
1883     // Compute the number of micro tiles per row.
1884     //
1885     microTilesPerRow = pitch / MicroTileWidth;
1886 
1887     //
1888     // Compute the micro tile index.
1889     //
1890     microTileIndexX = x     / MicroTileWidth;
1891     microTileIndexY = y     / MicroTileHeight;
1892     microTileIndexZ = slice / microTileThickness;
1893 
1894     //
1895     // Compute the slice offset.
1896     //
1897     sliceOffset = static_cast<UINT_64>(microTileIndexZ) * sliceBytes;
1898 
1899     //
1900     // Compute the offset to the micro tile containing the specified coordinate.
1901     //
1902     microTileOffset = (static_cast<UINT_64>(microTileIndexY) * microTilesPerRow + microTileIndexX) *
1903         microTileBytes;
1904 
1905     //
1906     // Compute the pixel index within the micro tile.
1907     //
1908     pixelIndex = ComputePixelIndexWithinMicroTile(x,
1909                                                   y,
1910                                                   slice,
1911                                                   bpp,
1912                                                   tileMode,
1913                                                   microTileType);
1914 
1915     // Compute the sample offset.
1916     //
1917     if (isDepthSampleOrder)
1918     {
1919         //
1920         // For depth surfaces, samples are stored contiguously for each element, so the sample
1921         // offset is the sample number times the element size.
1922         //
1923         sampleOffset = sample * bpp;
1924         pixelOffset = pixelIndex * bpp * numSamples;
1925     }
1926     else
1927     {
1928         //
1929         // For color surfaces, all elements for a particular sample are stored contiguously, so
1930         // the sample offset is the sample number times the micro tile size divided yBit the number
1931         // of samples.
1932         //
1933         sampleOffset = sample * (microTileBytes*8 / numSamples);
1934         pixelOffset = pixelIndex * bpp;
1935     }
1936 
1937     //
1938     // Compute the bit position of the pixel.  Each element is stored with one bit per sample.
1939     //
1940 
1941     UINT_32 elemOffset = sampleOffset + pixelOffset;
1942 
1943     *pBitPosition = elemOffset % 8;
1944     elemOffset /= 8;
1945 
1946     //
1947     // Combine the slice offset, micro tile offset, sample offset, and pixel offsets.
1948     //
1949     addr = sliceOffset + microTileOffset + elemOffset;
1950 
1951     return addr;
1952 }
1953 
1954 /**
1955 ****************************************************************************************************
1956 *   EgBasedLib::HwlComputePixelCoordFromOffset
1957 *
1958 *   @brief
1959 *       Compute pixel coordinate from offset inside a micro tile
1960 *   @return
1961 *       N/A
1962 ****************************************************************************************************
1963 */
HwlComputePixelCoordFromOffset(UINT_32 offset,UINT_32 bpp,UINT_32 numSamples,AddrTileMode tileMode,UINT_32 tileBase,UINT_32 compBits,UINT_32 * pX,UINT_32 * pY,UINT_32 * pSlice,UINT_32 * pSample,AddrTileType microTileType,BOOL_32 isDepthSampleOrder) const1964 VOID EgBasedLib::HwlComputePixelCoordFromOffset(
1965     UINT_32         offset,             ///< [in] offset inside micro tile in bits
1966     UINT_32         bpp,                ///< [in] bits per pixel
1967     UINT_32         numSamples,         ///< [in] number of samples
1968     AddrTileMode    tileMode,           ///< [in] tile mode
1969     UINT_32         tileBase,           ///< [in] base offset within a tile
1970     UINT_32         compBits,           ///< [in] component bits actually needed(for planar surface)
1971     UINT_32*        pX,                 ///< [out] x coordinate
1972     UINT_32*        pY,                 ///< [out] y coordinate
1973     UINT_32*        pSlice,             ///< [out] slice index
1974     UINT_32*        pSample,            ///< [out] sample index
1975     AddrTileType    microTileType,      ///< [in] micro tiling type
1976     BOOL_32         isDepthSampleOrder  ///< [in] TRUE if depth sample order in microtile is used
1977     ) const
1978 {
1979     UINT_32 x = 0;
1980     UINT_32 y = 0;
1981     UINT_32 z = 0;
1982     UINT_32 thickness = Thickness(tileMode);
1983 
1984     // For planar surface, we adjust offset acoording to tile base
1985     if ((bpp != compBits) && (compBits != 0) && isDepthSampleOrder)
1986     {
1987         offset -= tileBase;
1988 
1989         ADDR_ASSERT(microTileType == ADDR_NON_DISPLAYABLE ||
1990                     microTileType == ADDR_DEPTH_SAMPLE_ORDER);
1991 
1992         bpp = compBits;
1993     }
1994 
1995     UINT_32 sampleTileBits;
1996     UINT_32 samplePixelBits;
1997     UINT_32 pixelIndex;
1998 
1999     if (isDepthSampleOrder)
2000     {
2001         samplePixelBits = bpp * numSamples;
2002         pixelIndex = offset / samplePixelBits;
2003         *pSample = (offset % samplePixelBits) / bpp;
2004     }
2005     else
2006     {
2007         sampleTileBits = MicroTilePixels * bpp * thickness;
2008         *pSample = offset / sampleTileBits;
2009         pixelIndex = (offset % sampleTileBits) / bpp;
2010     }
2011 
2012     if (microTileType != ADDR_THICK)
2013     {
2014         if (microTileType == ADDR_DISPLAYABLE) // displayable
2015         {
2016             switch (bpp)
2017             {
2018                 case 8:
2019                     x = pixelIndex & 0x7;
2020                     y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,4));
2021                     break;
2022                 case 16:
2023                     x = pixelIndex & 0x7;
2024                     y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,3));
2025                     break;
2026                 case 32:
2027                     x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,1),_BIT(pixelIndex,0));
2028                     y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,2));
2029                     break;
2030                 case 64:
2031                     x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
2032                     y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
2033                     break;
2034                 case 128:
2035                     x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,2),_BIT(pixelIndex,1));
2036                     y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,0));
2037                     break;
2038                 default:
2039                     break;
2040             }
2041         }
2042         else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER)
2043         {
2044             x = Bits2Number(3, _BIT(pixelIndex,4),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
2045             y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
2046         }
2047         else if (microTileType == ADDR_ROTATED)
2048         {
2049             /*
2050                 8-Bit Elements
2051                 element_index[5:0] = { x[2], x[0], x[1], y[2], y[1], y[0] }
2052 
2053                 16-Bit Elements
2054                 element_index[5:0] = { x[2], x[1], x[0], y[2], y[1], y[0] }
2055 
2056                 32-Bit Elements
2057                 element_index[5:0] = { x[2], x[1], y[2], x[0], y[1], y[0] }
2058 
2059                 64-Bit Elements
2060                 element_index[5:0] = { y[2], x[2], x[1], y[1], x[0], y[0] }
2061             */
2062             switch(bpp)
2063             {
2064                 case 8:
2065                     x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,4));
2066                     y = pixelIndex & 0x7;
2067                     break;
2068                 case 16:
2069                     x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,3));
2070                     y = pixelIndex & 0x7;
2071                     break;
2072                 case 32:
2073                     x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,2));
2074                     y = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,1),_BIT(pixelIndex,0));
2075                     break;
2076                 case 64:
2077                     x = Bits2Number(3, _BIT(pixelIndex,4),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
2078                     y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
2079                     break;
2080                 default:
2081                     ADDR_ASSERT_ALWAYS();
2082                     break;
2083             }
2084         }
2085 
2086         if (thickness > 1) // thick
2087         {
2088             z = Bits2Number(3, _BIT(pixelIndex,8),_BIT(pixelIndex,7),_BIT(pixelIndex,6));
2089         }
2090     }
2091     else
2092     {
2093         ADDR_ASSERT((m_chipFamily >= ADDR_CHIP_FAMILY_CI) && (thickness > 1));
2094         /*
2095             8-Bit Elements and 16-Bit Elements
2096             element_index[7:0] = { y[2], x[2], z[1], z[0], y[1], x[1], y[0], x[0] }
2097 
2098             32-Bit Elements
2099             element_index[7:0] = { y[2], x[2], z[1], y[1], z[0], x[1], y[0], x[0] }
2100 
2101             64-Bit Elements and 128-Bit Elements
2102             element_index[7:0] = { y[2], x[2], z[1], y[1], x[1], z[0], y[0], x[0] }
2103 
2104             The equation to compute the element index for the extra thick tile:
2105             element_index[8] = z[2]
2106         */
2107         switch (bpp)
2108         {
2109             case 8:
2110             case 16: // fall-through
2111                 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
2112                 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
2113                 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,4));
2114                 break;
2115             case 32:
2116                 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
2117                 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
2118                 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,3));
2119                 break;
2120             case 64:
2121             case 128: // fall-through
2122                 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,3),_BIT(pixelIndex,0));
2123                 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
2124                 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,2));
2125                 break;
2126             default:
2127                 ADDR_ASSERT_ALWAYS();
2128                 break;
2129         }
2130 
2131         if (thickness == 8)
2132         {
2133             z += Bits2Number(3,_BIT(pixelIndex,8),0,0);
2134         }
2135     }
2136 
2137     *pX = x;
2138     *pY = y;
2139     *pSlice += z;
2140 }
2141 
2142 
2143 /**
2144 ****************************************************************************************************
2145 *   EgBasedLib::DispatchComputeSurfaceCoordFromAddrDispatch
2146 *
2147 *   @brief
2148 *       Compute (x,y,slice,sample) coordinates from surface address
2149 *   @return
2150 *       N/A
2151 ****************************************************************************************************
2152 */
DispatchComputeSurfaceCoordFromAddr(const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT * pIn,ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT * pOut) const2153 VOID EgBasedLib::DispatchComputeSurfaceCoordFromAddr(
2154     const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure
2155     ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure
2156     ) const
2157 {
2158     UINT_64             addr               = pIn->addr;
2159     UINT_32             bitPosition        = pIn->bitPosition;
2160     UINT_32             bpp                = pIn->bpp;
2161     UINT_32             pitch              = pIn->pitch;
2162     UINT_32             height             = pIn->height;
2163     UINT_32             numSlices          = pIn->numSlices;
2164     UINT_32             numSamples         = ((pIn->numSamples == 0) ? 1 : pIn->numSamples);
2165     UINT_32             numFrags           = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
2166     AddrTileMode        tileMode           = pIn->tileMode;
2167     UINT_32             tileBase           = pIn->tileBase;
2168     UINT_32             compBits           = pIn->compBits;
2169     AddrTileType        microTileType      = pIn->tileType;
2170     BOOL_32             ignoreSE           = pIn->ignoreSE;
2171     BOOL_32             isDepthSampleOrder = pIn->isDepth;
2172     ADDR_TILEINFO*      pTileInfo          = pIn->pTileInfo;
2173 
2174     UINT_32*            pX                 = &pOut->x;
2175     UINT_32*            pY                 = &pOut->y;
2176     UINT_32*            pSlice             = &pOut->slice;
2177     UINT_32*            pSample            = &pOut->sample;
2178 
2179     if (microTileType == ADDR_DEPTH_SAMPLE_ORDER)
2180     {
2181         isDepthSampleOrder = TRUE;
2182     }
2183 
2184     if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
2185     {
2186         if (numFrags != numSamples)
2187         {
2188             numSamples = numFrags;
2189         }
2190 
2191         /// @note
2192         /// 128 bit/thick tiled surface doesn't support display tiling and
2193         /// mipmap chain must have the same tileType, so please fill tileType correctly
2194         if (IsLinear(pIn->tileMode) == FALSE)
2195         {
2196             if (bpp >= 128 || Thickness(tileMode) > 1)
2197             {
2198                 ADDR_ASSERT(microTileType != ADDR_DISPLAYABLE);
2199             }
2200         }
2201     }
2202 
2203     switch (tileMode)
2204     {
2205         case ADDR_TM_LINEAR_GENERAL://fall through
2206         case ADDR_TM_LINEAR_ALIGNED:
2207             ComputeSurfaceCoordFromAddrLinear(addr,
2208                                               bitPosition,
2209                                               bpp,
2210                                               pitch,
2211                                               height,
2212                                               numSlices,
2213                                               pX,
2214                                               pY,
2215                                               pSlice,
2216                                               pSample);
2217             break;
2218         case ADDR_TM_1D_TILED_THIN1://fall through
2219         case ADDR_TM_1D_TILED_THICK:
2220             ComputeSurfaceCoordFromAddrMicroTiled(addr,
2221                                                   bitPosition,
2222                                                   bpp,
2223                                                   pitch,
2224                                                   height,
2225                                                   numSamples,
2226                                                   tileMode,
2227                                                   tileBase,
2228                                                   compBits,
2229                                                   pX,
2230                                                   pY,
2231                                                   pSlice,
2232                                                   pSample,
2233                                                   microTileType,
2234                                                   isDepthSampleOrder);
2235             break;
2236         case ADDR_TM_2D_TILED_THIN1:    //fall through
2237         case ADDR_TM_2D_TILED_THICK:    //fall through
2238         case ADDR_TM_3D_TILED_THIN1:    //fall through
2239         case ADDR_TM_3D_TILED_THICK:    //fall through
2240         case ADDR_TM_2D_TILED_XTHICK:   //fall through
2241         case ADDR_TM_3D_TILED_XTHICK:   //fall through
2242         case ADDR_TM_PRT_TILED_THIN1:   //fall through
2243         case ADDR_TM_PRT_2D_TILED_THIN1://fall through
2244         case ADDR_TM_PRT_3D_TILED_THIN1://fall through
2245         case ADDR_TM_PRT_TILED_THICK:   //fall through
2246         case ADDR_TM_PRT_2D_TILED_THICK://fall through
2247         case ADDR_TM_PRT_3D_TILED_THICK:
2248             UINT_32 pipeSwizzle;
2249             UINT_32 bankSwizzle;
2250 
2251             if (m_configFlags.useCombinedSwizzle)
2252             {
2253                 ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo,
2254                                        &bankSwizzle, &pipeSwizzle);
2255             }
2256             else
2257             {
2258                 pipeSwizzle = pIn->pipeSwizzle;
2259                 bankSwizzle = pIn->bankSwizzle;
2260             }
2261 
2262             ComputeSurfaceCoordFromAddrMacroTiled(addr,
2263                                                   bitPosition,
2264                                                   bpp,
2265                                                   pitch,
2266                                                   height,
2267                                                   numSamples,
2268                                                   tileMode,
2269                                                   tileBase,
2270                                                   compBits,
2271                                                   microTileType,
2272                                                   ignoreSE,
2273                                                   isDepthSampleOrder,
2274                                                   pipeSwizzle,
2275                                                   bankSwizzle,
2276                                                   pTileInfo,
2277                                                   pX,
2278                                                   pY,
2279                                                   pSlice,
2280                                                   pSample);
2281             break;
2282         default:
2283             ADDR_ASSERT_ALWAYS();
2284     }
2285 }
2286 
2287 
2288 /**
2289 ****************************************************************************************************
2290 *   EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled
2291 *
2292 *   @brief
2293 *       Compute surface coordinates from address for macro tiled surface
2294 *   @return
2295 *       N/A
2296 ****************************************************************************************************
2297 */
ComputeSurfaceCoordFromAddrMacroTiled(UINT_64 addr,UINT_32 bitPosition,UINT_32 bpp,UINT_32 pitch,UINT_32 height,UINT_32 numSamples,AddrTileMode tileMode,UINT_32 tileBase,UINT_32 compBits,AddrTileType microTileType,BOOL_32 ignoreSE,BOOL_32 isDepthSampleOrder,UINT_32 pipeSwizzle,UINT_32 bankSwizzle,ADDR_TILEINFO * pTileInfo,UINT_32 * pX,UINT_32 * pY,UINT_32 * pSlice,UINT_32 * pSample) const2298 VOID EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled(
2299     UINT_64             addr,               ///< [in] byte address
2300     UINT_32             bitPosition,        ///< [in] bit position
2301     UINT_32             bpp,                ///< [in] bits per pixel
2302     UINT_32             pitch,              ///< [in] pitch in pixels
2303     UINT_32             height,             ///< [in] height in pixels
2304     UINT_32             numSamples,         ///< [in] number of samples
2305     AddrTileMode        tileMode,           ///< [in] tile mode
2306     UINT_32             tileBase,           ///< [in] tile base offset
2307     UINT_32             compBits,           ///< [in] component bits (for planar surface)
2308     AddrTileType        microTileType,      ///< [in] micro tiling type
2309     BOOL_32             ignoreSE,           ///< [in] TRUE if shader engines can be ignored
2310     BOOL_32             isDepthSampleOrder, ///< [in] TRUE if depth sample order is used
2311     UINT_32             pipeSwizzle,        ///< [in] pipe swizzle
2312     UINT_32             bankSwizzle,        ///< [in] bank swizzle
2313     ADDR_TILEINFO*      pTileInfo,          ///< [in] bank structure.
2314                                             ///  **All fields to be valid on entry**
2315     UINT_32*            pX,                 ///< [out] X coord
2316     UINT_32*            pY,                 ///< [out] Y coord
2317     UINT_32*            pSlice,             ///< [out] slice index
2318     UINT_32*            pSample             ///< [out] sample index
2319     ) const
2320 {
2321     UINT_32 mx;
2322     UINT_32 my;
2323     UINT_64 tileBits;
2324     UINT_64 macroTileBits;
2325     UINT_32 slices;
2326     UINT_32 tileSlices;
2327     UINT_64 elementOffset;
2328     UINT_64 macroTileIndex;
2329     UINT_32 tileIndex;
2330     UINT_64 totalOffset;
2331 
2332 
2333     UINT_32 bank;
2334     UINT_32 pipe;
2335     UINT_32 groupBits = m_pipeInterleaveBytes << 3;
2336     UINT_32 pipes = HwlGetPipes(pTileInfo);
2337     UINT_32 banks = pTileInfo->banks;
2338 
2339     UINT_32 bankInterleave = m_bankInterleave;
2340 
2341     UINT_64 addrBits = BYTES_TO_BITS(addr) + bitPosition;
2342 
2343     //
2344     // remove bits for bank and pipe
2345     //
2346     totalOffset = (addrBits % groupBits) +
2347         (((addrBits / groupBits / pipes) % bankInterleave) * groupBits) +
2348         (((addrBits / groupBits / pipes) / bankInterleave) / banks) * groupBits * bankInterleave;
2349 
2350     UINT_32 microTileThickness = Thickness(tileMode);
2351 
2352     UINT_32 microTileBits = bpp * microTileThickness * MicroTilePixels * numSamples;
2353 
2354     UINT_32 microTileBytes = BITS_TO_BYTES(microTileBits);
2355     //
2356     // Determine if tiles need to be split across slices.
2357     //
2358     // If the size of the micro tile is larger than the tile split size, then the tile will be
2359     // split across multiple slices.
2360     //
2361     UINT_32 slicesPerTile = 1; //_State->TileSlices
2362 
2363     if ((microTileBytes > pTileInfo->tileSplitBytes) && (microTileThickness == 1))
2364     {   //don't support for thick mode
2365 
2366         //
2367         // Compute the number of slices per tile.
2368         //
2369         slicesPerTile = microTileBytes / pTileInfo->tileSplitBytes;
2370     }
2371 
2372     tileBits = microTileBits / slicesPerTile; // micro tile bits
2373 
2374     // in micro tiles because not MicroTileWidth timed.
2375     UINT_32 macroWidth  = pTileInfo->bankWidth * pipes * pTileInfo->macroAspectRatio;
2376     // in micro tiles as well
2377     UINT_32 macroHeight = pTileInfo->bankHeight * banks / pTileInfo->macroAspectRatio;
2378 
2379     UINT_32 pitchInMacroTiles = pitch / MicroTileWidth / macroWidth;
2380 
2381     macroTileBits = (macroWidth * macroHeight) * tileBits / (banks * pipes);
2382 
2383     macroTileIndex = totalOffset / macroTileBits;
2384 
2385     // pitchMacros * height / heightMacros;  macroTilesPerSlice == _State->SliceMacros
2386     UINT_32 macroTilesPerSlice = (pitch / (macroWidth * MicroTileWidth)) * height /
2387         (macroHeight * MicroTileWidth);
2388 
2389     slices = static_cast<UINT_32>(macroTileIndex / macroTilesPerSlice);
2390 
2391     *pSlice = static_cast<UINT_32>(slices / slicesPerTile * microTileThickness);
2392 
2393     //
2394     // calculate element offset and x[2:0], y[2:0], z[1:0] for thick
2395     //
2396     tileSlices = slices % slicesPerTile;
2397 
2398     elementOffset  = tileSlices * tileBits;
2399     elementOffset += totalOffset % tileBits;
2400 
2401     UINT_32 coordZ = 0;
2402 
2403     HwlComputePixelCoordFromOffset(static_cast<UINT_32>(elementOffset),
2404                                    bpp,
2405                                    numSamples,
2406                                    tileMode,
2407                                    tileBase,
2408                                    compBits,
2409                                    pX,
2410                                    pY,
2411                                    &coordZ,
2412                                    pSample,
2413                                    microTileType,
2414                                    isDepthSampleOrder);
2415 
2416     macroTileIndex = macroTileIndex % macroTilesPerSlice;
2417     *pY += static_cast<UINT_32>(macroTileIndex / pitchInMacroTiles * macroHeight * MicroTileHeight);
2418     *pX += static_cast<UINT_32>(macroTileIndex % pitchInMacroTiles * macroWidth * MicroTileWidth);
2419 
2420     *pSlice += coordZ;
2421 
2422     tileIndex = static_cast<UINT_32>((totalOffset % macroTileBits) / tileBits);
2423 
2424     my = (tileIndex / pTileInfo->bankWidth) % pTileInfo->bankHeight * MicroTileHeight;
2425     mx = (tileIndex % pTileInfo->bankWidth) * pipes * MicroTileWidth;
2426 
2427     *pY += my;
2428     *pX += mx;
2429 
2430     bank = ComputeBankFromAddr(addr, banks, pipes);
2431     pipe = ComputePipeFromAddr(addr, pipes);
2432 
2433     HwlComputeSurfaceCoord2DFromBankPipe(tileMode,
2434                                          pX,
2435                                          pY,
2436                                          *pSlice,
2437                                          bank,
2438                                          pipe,
2439                                          bankSwizzle,
2440                                          pipeSwizzle,
2441                                          tileSlices,
2442                                          ignoreSE,
2443                                          pTileInfo);
2444 }
2445 
2446 /**
2447 ****************************************************************************************************
2448 *   EgBasedLib::ComputeSurfaceCoord2DFromBankPipe
2449 *
2450 *   @brief
2451 *       Compute surface x,y coordinates from bank/pipe info
2452 *   @return
2453 *       N/A
2454 ****************************************************************************************************
2455 */
ComputeSurfaceCoord2DFromBankPipe(AddrTileMode tileMode,UINT_32 x,UINT_32 y,UINT_32 slice,UINT_32 bank,UINT_32 pipe,UINT_32 bankSwizzle,UINT_32 pipeSwizzle,UINT_32 tileSlices,ADDR_TILEINFO * pTileInfo,CoordFromBankPipe * pOutput) const2456 VOID EgBasedLib::ComputeSurfaceCoord2DFromBankPipe(
2457     AddrTileMode        tileMode,   ///< [in] tile mode
2458     UINT_32             x,          ///< [in] x coordinate
2459     UINT_32             y,          ///< [in] y coordinate
2460     UINT_32             slice,      ///< [in] slice index
2461     UINT_32             bank,       ///< [in] bank number
2462     UINT_32             pipe,       ///< [in] pipe number
2463     UINT_32             bankSwizzle,///< [in] bank swizzle
2464     UINT_32             pipeSwizzle,///< [in] pipe swizzle
2465     UINT_32             tileSlices, ///< [in] slices in a micro tile
2466     ADDR_TILEINFO*      pTileInfo,  ///< [in] bank structure. **All fields to be valid on entry**
2467     CoordFromBankPipe*  pOutput     ///< [out] pointer to extracted x/y bits
2468     ) const
2469 {
2470     UINT_32 yBit3 = 0;
2471     UINT_32 yBit4 = 0;
2472     UINT_32 yBit5 = 0;
2473     UINT_32 yBit6 = 0;
2474 
2475     UINT_32 xBit3 = 0;
2476     UINT_32 xBit4 = 0;
2477     UINT_32 xBit5 = 0;
2478 
2479     UINT_32 tileSplitRotation;
2480 
2481     UINT_32 numPipes = HwlGetPipes(pTileInfo);
2482 
2483     UINT_32 bankRotation = ComputeBankRotation(tileMode,
2484                                                pTileInfo->banks, numPipes);
2485 
2486     UINT_32 pipeRotation = ComputePipeRotation(tileMode, numPipes);
2487 
2488     UINT_32 xBit = x / (MicroTileWidth * pTileInfo->bankWidth * numPipes);
2489     UINT_32 yBit = y / (MicroTileHeight * pTileInfo->bankHeight);
2490 
2491     //calculate the bank and pipe before rotation and swizzle
2492 
2493     switch (tileMode)
2494     {
2495         case ADDR_TM_2D_TILED_THIN1:  //fall through
2496         case ADDR_TM_2D_TILED_THICK:  //fall through
2497         case ADDR_TM_2D_TILED_XTHICK: //fall through
2498         case ADDR_TM_3D_TILED_THIN1:  //fall through
2499         case ADDR_TM_3D_TILED_THICK:  //fall through
2500         case ADDR_TM_3D_TILED_XTHICK:
2501             tileSplitRotation = ((pTileInfo->banks / 2) + 1);
2502             break;
2503         default:
2504             tileSplitRotation =  0;
2505             break;
2506     }
2507 
2508     UINT_32 microTileThickness = Thickness(tileMode);
2509 
2510     bank ^= tileSplitRotation * tileSlices;
2511     if (pipeRotation == 0)
2512     {
2513         bank ^= bankRotation * (slice / microTileThickness) + bankSwizzle;
2514         bank %= pTileInfo->banks;
2515         pipe ^= pipeSwizzle;
2516     }
2517     else
2518     {
2519         bank ^= bankRotation * (slice / microTileThickness) / numPipes + bankSwizzle;
2520         bank %= pTileInfo->banks;
2521         pipe ^= pipeRotation * (slice / microTileThickness) + pipeSwizzle;
2522     }
2523 
2524     if (pTileInfo->macroAspectRatio == 1)
2525     {
2526         switch (pTileInfo->banks)
2527         {
2528             case 2:
2529                 yBit3 = _BIT(bank, 0) ^ _BIT(xBit,0);
2530                 break;
2531             case 4:
2532                 yBit4 = _BIT(bank, 0) ^ _BIT(xBit,0);
2533                 yBit3 = _BIT(bank, 1) ^ _BIT(xBit,1);
2534                 break;
2535             case 8:
2536                 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
2537                 yBit5 = _BIT(bank, 0) ^ _BIT(xBit,0);
2538                 yBit4 = _BIT(bank, 1) ^ _BIT(xBit,1) ^ yBit5;
2539                 break;
2540             case 16:
2541                 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3);
2542                 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2);
2543                 yBit6 = _BIT(bank, 0) ^ _BIT(xBit, 0);
2544                 yBit5 = _BIT(bank, 1) ^ _BIT(xBit, 1) ^ yBit6;
2545                 break;
2546             default:
2547                 break;
2548         }
2549 
2550     }
2551     else if (pTileInfo->macroAspectRatio == 2)
2552     {
2553         switch (pTileInfo->banks)
2554         {
2555             case 2: //xBit3 = yBit3^b0
2556                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,0);
2557                 break;
2558             case 4: //xBit3=yBit4^b0; yBit3=xBit4^b1
2559                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,1);
2560                 yBit3 = _BIT(bank, 1) ^ _BIT(xBit,1);
2561                 break;
2562             case 8: //xBit4, xBit5, yBit5 are known
2563                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2);
2564                 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
2565                 yBit4 = _BIT(bank, 1) ^ _BIT(xBit,1) ^ _BIT(yBit, 2);
2566                 break;
2567             case 16://x4,x5,x6,y6 are known
2568                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3); //x3 = y6 ^ b0
2569                 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = x6 ^ b3
2570                 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2); //y4 = x5 ^ b2
2571                 yBit5 = _BIT(bank, 1) ^ _BIT(xBit, 1) ^ _BIT(yBit, 3); //y5=x4^y6^b1
2572                 break;
2573             default:
2574                 break;
2575         }
2576     }
2577     else if (pTileInfo->macroAspectRatio == 4)
2578     {
2579         switch (pTileInfo->banks)
2580         {
2581             case 4: //yBit3, yBit4
2582                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,1);
2583                 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,0);
2584                 break;
2585             case 8: //xBit5, yBit4, yBit5
2586                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2);
2587                 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
2588                 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,1) ^  _BIT(yBit,2);
2589                 break;
2590             case 16: //xBit5, xBit6, yBit5, yBit6
2591                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3);//x3 = b0 ^ y6
2592                 xBit4 = _BIT(bank, 1) ^ _BIT(yBit, 2) ^ _BIT(yBit, 3);//x4 = b1 ^ y5 ^ y6;
2593                 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = b3 ^ x6;
2594                 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2); //y4 = b2 ^ x5;
2595                 break;
2596             default:
2597                 break;
2598         }
2599     }
2600     else if (pTileInfo->macroAspectRatio == 8)
2601     {
2602         switch (pTileInfo->banks)
2603         {
2604             case 8: //yBit3, yBit4, yBit5
2605                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2); //x3 = b0 ^ y5;
2606                 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,1) ^ _BIT(yBit, 2);//x4 = b1 ^ y4 ^ y5;
2607                 xBit5 = _BIT(bank, 2) ^ _BIT(yBit,0);
2608                 break;
2609             case 16: //xBit6, yBit4, yBit5, yBit6
2610                 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3);//x3 = y6 ^ b0
2611                 xBit4 = _BIT(bank, 1) ^ _BIT(yBit, 2) ^ _BIT(yBit, 3);//x4 = y5 ^ y6 ^ b1
2612                 xBit5 = _BIT(bank, 2) ^ _BIT(yBit, 1);//x5 = y4 ^ b2
2613                 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = x6 ^ b3
2614                 break;
2615             default:
2616                 break;
2617         }
2618     }
2619 
2620     pOutput->xBits = xBit;
2621     pOutput->yBits = yBit;
2622 
2623     pOutput->xBit3 = xBit3;
2624     pOutput->xBit4 = xBit4;
2625     pOutput->xBit5 = xBit5;
2626     pOutput->yBit3 = yBit3;
2627     pOutput->yBit4 = yBit4;
2628     pOutput->yBit5 = yBit5;
2629     pOutput->yBit6 = yBit6;
2630 }
2631 
2632 /**
2633 ****************************************************************************************************
2634 *   EgBasedLib::HwlExtractBankPipeSwizzle
2635 *   @brief
2636 *       Entry of EgBasedLib ExtractBankPipeSwizzle
2637 *   @return
2638 *       ADDR_E_RETURNCODE
2639 ****************************************************************************************************
2640 */
HwlExtractBankPipeSwizzle(const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT * pIn,ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT * pOut) const2641 ADDR_E_RETURNCODE EgBasedLib::HwlExtractBankPipeSwizzle(
2642     const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT*  pIn,   ///< [in] input structure
2643     ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT*       pOut   ///< [out] output structure
2644     ) const
2645 {
2646     ExtractBankPipeSwizzle(pIn->base256b,
2647                            pIn->pTileInfo,
2648                            &pOut->bankSwizzle,
2649                            &pOut->pipeSwizzle);
2650 
2651     return ADDR_OK;
2652 }
2653 
2654 
2655 /**
2656 ****************************************************************************************************
2657 *   EgBasedLib::HwlCombineBankPipeSwizzle
2658 *   @brief
2659 *       Combine bank/pipe swizzle
2660 *   @return
2661 *       ADDR_E_RETURNCODE
2662 ****************************************************************************************************
2663 */
HwlCombineBankPipeSwizzle(UINT_32 bankSwizzle,UINT_32 pipeSwizzle,ADDR_TILEINFO * pTileInfo,UINT_64 baseAddr,UINT_32 * pTileSwizzle) const2664 ADDR_E_RETURNCODE EgBasedLib::HwlCombineBankPipeSwizzle(
2665     UINT_32         bankSwizzle,    ///< [in] bank swizzle
2666     UINT_32         pipeSwizzle,    ///< [in] pipe swizzle
2667     ADDR_TILEINFO*  pTileInfo,      ///< [in] tile info
2668     UINT_64         baseAddr,       ///< [in] base address
2669     UINT_32*        pTileSwizzle    ///< [out] combined swizzle
2670     ) const
2671 {
2672     ADDR_E_RETURNCODE retCode = ADDR_OK;
2673 
2674     if (pTileSwizzle)
2675     {
2676         *pTileSwizzle = GetBankPipeSwizzle(bankSwizzle, pipeSwizzle, baseAddr, pTileInfo);
2677     }
2678     else
2679     {
2680         retCode = ADDR_INVALIDPARAMS;
2681     }
2682 
2683     return retCode;
2684 }
2685 
2686 /**
2687 ****************************************************************************************************
2688 *   EgBasedLib::HwlComputeBaseSwizzle
2689 *   @brief
2690 *       Compute base swizzle
2691 *   @return
2692 *       ADDR_E_RETURNCODE
2693 ****************************************************************************************************
2694 */
HwlComputeBaseSwizzle(const ADDR_COMPUTE_BASE_SWIZZLE_INPUT * pIn,ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT * pOut) const2695 ADDR_E_RETURNCODE EgBasedLib::HwlComputeBaseSwizzle(
2696     const ADDR_COMPUTE_BASE_SWIZZLE_INPUT* pIn,
2697     ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut
2698     ) const
2699 {
2700     UINT_32 bankSwizzle = 0;
2701     UINT_32 pipeSwizzle = 0;
2702     ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
2703 
2704     ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
2705     ADDR_ASSERT(pIn->pTileInfo);
2706 
2707     /// This is a legacy misreading of h/w doc, use it as it doesn't hurt.
2708     static const UINT_8 bankRotationArray[4][16] = {
2709         { 0, 0,  0, 0,  0, 0,  0, 0, 0,  0, 0,  0, 0,  0, 0, 0 }, // ADDR_SURF_2_BANK
2710         { 0, 1,  2, 3,  0, 0,  0, 0, 0,  0, 0,  0, 0,  0, 0, 0 }, // ADDR_SURF_4_BANK
2711         { 0, 3,  6, 1,  4, 7,  2, 5, 0,  0, 0,  0, 0,  0, 0, 0 }, // ADDR_SURF_8_BANK
2712         { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }, // ADDR_SURF_16_BANK
2713     };
2714 
2715     UINT_32 pipes = HwlGetPipes(pTileInfo);
2716     UINT_32 banks = pTileInfo ? pTileInfo->banks : 2;
2717     UINT_32 hwNumBanks;
2718 
2719     // Uses less bank swizzle bits
2720     if (pIn->option.reduceBankBit && banks > 2)
2721     {
2722         banks >>= 1;
2723     }
2724 
2725     switch (banks)
2726     {
2727         case 2:
2728             hwNumBanks = 0;
2729             break;
2730         case 4:
2731             hwNumBanks = 1;
2732             break;
2733         case 8:
2734             hwNumBanks = 2;
2735             break;
2736         case 16:
2737             hwNumBanks = 3;
2738             break;
2739         default:
2740             ADDR_ASSERT_ALWAYS();
2741             hwNumBanks = 0;
2742             break;
2743     }
2744 
2745     if (pIn->option.genOption == ADDR_SWIZZLE_GEN_LINEAR)
2746     {
2747         bankSwizzle = pIn->surfIndex & (banks - 1);
2748     }
2749     else // (pIn->option.genOption == ADDR_SWIZZLE_GEN_DEFAULT)
2750     {
2751         bankSwizzle = bankRotationArray[hwNumBanks][pIn->surfIndex & (banks - 1)];
2752     }
2753 
2754     if (IsMacro3dTiled(pIn->tileMode))
2755     {
2756         pipeSwizzle = pIn->surfIndex & (HwlGetPipes(pTileInfo) - 1);
2757     }
2758 
2759     return HwlCombineBankPipeSwizzle(bankSwizzle, pipeSwizzle, pTileInfo, 0, &pOut->tileSwizzle);
2760 }
2761 
2762 /**
2763 ****************************************************************************************************
2764 *   EgBasedLib::ExtractBankPipeSwizzle
2765 *   @brief
2766 *       Extract bank/pipe swizzle from base256b
2767 *   @return
2768 *       N/A
2769 ****************************************************************************************************
2770 */
ExtractBankPipeSwizzle(UINT_32 base256b,ADDR_TILEINFO * pTileInfo,UINT_32 * pBankSwizzle,UINT_32 * pPipeSwizzle) const2771 VOID EgBasedLib::ExtractBankPipeSwizzle(
2772     UINT_32         base256b,       ///< [in] input base256b register value
2773     ADDR_TILEINFO*  pTileInfo,      ///< [in] 2D tile parameters. Client must provide all data
2774     UINT_32*        pBankSwizzle,   ///< [out] bank swizzle
2775     UINT_32*        pPipeSwizzle    ///< [out] pipe swizzle
2776     ) const
2777 {
2778     UINT_32 bankSwizzle = 0;
2779     UINT_32 pipeSwizzle = 0;
2780 
2781     if (base256b != 0)
2782     {
2783         UINT_32 numPipes        = HwlGetPipes(pTileInfo);
2784         UINT_32 bankBits        = QLog2(pTileInfo->banks);
2785         UINT_32 pipeBits        = QLog2(numPipes);
2786         UINT_32 groupBytes      = m_pipeInterleaveBytes;
2787         UINT_32 bankInterleave  = m_bankInterleave;
2788 
2789         pipeSwizzle =
2790             (base256b / (groupBytes >> 8)) & ((1<<pipeBits)-1);
2791 
2792         bankSwizzle =
2793             (base256b / (groupBytes >> 8) / numPipes / bankInterleave) & ((1 << bankBits) - 1);
2794     }
2795 
2796     *pPipeSwizzle = pipeSwizzle;
2797     *pBankSwizzle = bankSwizzle;
2798 }
2799 
2800 /**
2801 ****************************************************************************************************
2802 *   EgBasedLib::GetBankPipeSwizzle
2803 *   @brief
2804 *       Combine bank/pipe swizzle
2805 *   @return
2806 *       Base256b bits (only filled bank/pipe bits)
2807 ****************************************************************************************************
2808 */
GetBankPipeSwizzle(UINT_32 bankSwizzle,UINT_32 pipeSwizzle,UINT_64 baseAddr,ADDR_TILEINFO * pTileInfo) const2809 UINT_32 EgBasedLib::GetBankPipeSwizzle(
2810     UINT_32         bankSwizzle,    ///< [in] bank swizzle
2811     UINT_32         pipeSwizzle,    ///< [in] pipe swizzle
2812     UINT_64         baseAddr,       ///< [in] base address
2813     ADDR_TILEINFO*  pTileInfo       ///< [in] tile info
2814     ) const
2815 {
2816     UINT_32 pipeBits = QLog2(HwlGetPipes(pTileInfo));
2817     UINT_32 bankInterleaveBits = QLog2(m_bankInterleave);
2818     UINT_32 tileSwizzle = pipeSwizzle + ((bankSwizzle << bankInterleaveBits) << pipeBits);
2819 
2820     baseAddr ^= tileSwizzle * m_pipeInterleaveBytes;
2821     baseAddr >>= 8;
2822 
2823     return static_cast<UINT_32>(baseAddr);
2824 }
2825 
2826 /**
2827 ****************************************************************************************************
2828 *   EgBasedLib::ComputeSliceTileSwizzle
2829 *   @brief
2830 *       Compute cubemap/3d texture faces/slices tile swizzle
2831 *   @return
2832 *       Tile swizzle
2833 ****************************************************************************************************
2834 */
ComputeSliceTileSwizzle(AddrTileMode tileMode,UINT_32 baseSwizzle,UINT_32 slice,UINT_64 baseAddr,ADDR_TILEINFO * pTileInfo) const2835 UINT_32 EgBasedLib::ComputeSliceTileSwizzle(
2836     AddrTileMode        tileMode,       ///< [in] Tile mode
2837     UINT_32             baseSwizzle,    ///< [in] Base swizzle
2838     UINT_32             slice,          ///< [in] Slice index, Cubemap face index, 0 means +X
2839     UINT_64             baseAddr,       ///< [in] Base address
2840     ADDR_TILEINFO* pTileInfo       ///< [in] Bank structure
2841     ) const
2842 {
2843     UINT_32 tileSwizzle = 0;
2844 
2845     if (IsMacroTiled(tileMode)) // Swizzle only for macro tile mode
2846     {
2847         UINT_32 firstSlice = slice / Thickness(tileMode);
2848 
2849         UINT_32 numPipes = HwlGetPipes(pTileInfo);
2850         UINT_32 numBanks = pTileInfo->banks;
2851 
2852         UINT_32 pipeRotation;
2853         UINT_32 bankRotation;
2854 
2855         UINT_32 bankSwizzle = 0;
2856         UINT_32 pipeSwizzle = 0;
2857 
2858         pipeRotation = ComputePipeRotation(tileMode, numPipes);
2859         bankRotation = ComputeBankRotation(tileMode, numBanks, numPipes);
2860 
2861         if (baseSwizzle != 0)
2862         {
2863             ExtractBankPipeSwizzle(baseSwizzle,
2864                                    pTileInfo,
2865                                    &bankSwizzle,
2866                                    &pipeSwizzle);
2867         }
2868 
2869         if (pipeRotation == 0) //2D mode
2870         {
2871             bankSwizzle += firstSlice * bankRotation;
2872             bankSwizzle %= numBanks;
2873         }
2874         else //3D mode
2875         {
2876             pipeSwizzle += firstSlice * pipeRotation;
2877             pipeSwizzle %= numPipes;
2878             bankSwizzle += firstSlice * bankRotation / numPipes;
2879             bankSwizzle %= numBanks;
2880         }
2881 
2882         tileSwizzle = GetBankPipeSwizzle(bankSwizzle,
2883                                          pipeSwizzle,
2884                                          baseAddr,
2885                                          pTileInfo);
2886     }
2887 
2888     return tileSwizzle;
2889 }
2890 
2891 /**
2892 ****************************************************************************************************
2893 *   EgBasedLib::HwlComputeQbStereoRightSwizzle
2894 *
2895 *   @brief
2896 *       Compute right eye swizzle
2897 *   @return
2898 *       swizzle
2899 ****************************************************************************************************
2900 */
HwlComputeQbStereoRightSwizzle(ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pInfo) const2901 UINT_32 EgBasedLib::HwlComputeQbStereoRightSwizzle(
2902     ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pInfo  ///< [in] Surface info, must be valid
2903     ) const
2904 {
2905     UINT_32 bankBits    = 0;
2906     UINT_32 swizzle     = 0;
2907 
2908     // The assumption is default swizzle for left eye is 0
2909     if (IsMacroTiled(pInfo->tileMode) && pInfo->pStereoInfo && pInfo->pTileInfo)
2910     {
2911         bankBits = ComputeBankFromCoord(0, pInfo->height, 0,
2912                                         pInfo->tileMode, 0, 0, pInfo->pTileInfo);
2913 
2914         if (bankBits)
2915         {
2916             HwlCombineBankPipeSwizzle(bankBits, 0, pInfo->pTileInfo, 0, &swizzle);
2917         }
2918     }
2919 
2920     return swizzle;
2921 }
2922 
2923 /**
2924 ****************************************************************************************************
2925 *   EgBasedLib::ComputeBankFromCoord
2926 *
2927 *   @brief
2928 *       Compute bank number from coordinates
2929 *   @return
2930 *       Bank number
2931 ****************************************************************************************************
2932 */
ComputeBankFromCoord(UINT_32 x,UINT_32 y,UINT_32 slice,AddrTileMode tileMode,UINT_32 bankSwizzle,UINT_32 tileSplitSlice,ADDR_TILEINFO * pTileInfo) const2933 UINT_32 EgBasedLib::ComputeBankFromCoord(
2934     UINT_32         x,              ///< [in] x coordinate
2935     UINT_32         y,              ///< [in] y coordinate
2936     UINT_32         slice,          ///< [in] slice index
2937     AddrTileMode    tileMode,       ///< [in] tile mode
2938     UINT_32         bankSwizzle,    ///< [in] bank swizzle
2939     UINT_32         tileSplitSlice, ///< [in] If the size of the pixel offset is larger than the
2940                                     ///  tile split size, then the pixel will be moved to a separate
2941                                     ///  slice. This value equals pixelOffset / tileSplitBytes
2942                                     ///  in this case. Otherwise this is 0.
2943     ADDR_TILEINFO*  pTileInfo       ///< [in] tile info
2944     ) const
2945 {
2946     UINT_32 pipes = HwlGetPipes(pTileInfo);
2947     UINT_32 bankBit0 = 0;
2948     UINT_32 bankBit1 = 0;
2949     UINT_32 bankBit2 = 0;
2950     UINT_32 bankBit3 = 0;
2951     UINT_32 sliceRotation;
2952     UINT_32 tileSplitRotation;
2953     UINT_32 bank;
2954     UINT_32 numBanks    = pTileInfo->banks;
2955     UINT_32 bankWidth   = pTileInfo->bankWidth;
2956     UINT_32 bankHeight  = pTileInfo->bankHeight;
2957 
2958     UINT_32 tx = x / MicroTileWidth / (bankWidth * pipes);
2959     UINT_32 ty = y / MicroTileHeight / bankHeight;
2960 
2961     UINT_32 x3 = _BIT(tx,0);
2962     UINT_32 x4 = _BIT(tx,1);
2963     UINT_32 x5 = _BIT(tx,2);
2964     UINT_32 x6 = _BIT(tx,3);
2965     UINT_32 y3 = _BIT(ty,0);
2966     UINT_32 y4 = _BIT(ty,1);
2967     UINT_32 y5 = _BIT(ty,2);
2968     UINT_32 y6 = _BIT(ty,3);
2969 
2970     switch (numBanks)
2971     {
2972         case 16:
2973             bankBit0 = x3 ^ y6;
2974             bankBit1 = x4 ^ y5 ^ y6;
2975             bankBit2 = x5 ^ y4;
2976             bankBit3 = x6 ^ y3;
2977             break;
2978         case 8:
2979             bankBit0 = x3 ^ y5;
2980             bankBit1 = x4 ^ y4 ^ y5;
2981             bankBit2 = x5 ^ y3;
2982             break;
2983         case 4:
2984             bankBit0 = x3 ^ y4;
2985             bankBit1 = x4 ^ y3;
2986             break;
2987         case 2:
2988             bankBit0 = x3 ^ y3;
2989             break;
2990         default:
2991             ADDR_ASSERT_ALWAYS();
2992             break;
2993     }
2994 
2995     bank = bankBit0 | (bankBit1 << 1) | (bankBit2 << 2) | (bankBit3 << 3);
2996 
2997     //Bits2Number(4, bankBit3, bankBit2, bankBit1, bankBit0);
2998 
2999     bank = HwlPreAdjustBank((x / MicroTileWidth), bank, pTileInfo);
3000     //
3001     // Compute bank rotation for the slice.
3002     //
3003     UINT_32 microTileThickness = Thickness(tileMode);
3004 
3005     switch (tileMode)
3006     {
3007         case ADDR_TM_2D_TILED_THIN1:  // fall through
3008         case ADDR_TM_2D_TILED_THICK:  // fall through
3009         case ADDR_TM_2D_TILED_XTHICK:
3010             sliceRotation = ((numBanks / 2) - 1) * (slice / microTileThickness);
3011             break;
3012         case ADDR_TM_3D_TILED_THIN1:  // fall through
3013         case ADDR_TM_3D_TILED_THICK:  // fall through
3014         case ADDR_TM_3D_TILED_XTHICK:
3015             sliceRotation =
3016                 Max(1u, (pipes / 2) - 1) * (slice / microTileThickness) / pipes;
3017             break;
3018         default:
3019             sliceRotation =  0;
3020             break;
3021     }
3022 
3023 
3024     //
3025     // Compute bank rotation for the tile split slice.
3026     //
3027     // The sample slice will be non-zero if samples must be split across multiple slices.
3028     // This situation arises when the micro tile size multiplied yBit the number of samples exceeds
3029     // the split size (set in GB_ADDR_CONFIG).
3030     //
3031     switch (tileMode)
3032     {
3033         case ADDR_TM_2D_TILED_THIN1: //fall through
3034         case ADDR_TM_3D_TILED_THIN1: //fall through
3035         case ADDR_TM_PRT_2D_TILED_THIN1: //fall through
3036         case ADDR_TM_PRT_3D_TILED_THIN1: //fall through
3037             tileSplitRotation = ((numBanks / 2) + 1) * tileSplitSlice;
3038             break;
3039         default:
3040             tileSplitRotation =  0;
3041             break;
3042     }
3043 
3044     //
3045     // Apply bank rotation for the slice and tile split slice.
3046     //
3047     bank ^= bankSwizzle + sliceRotation;
3048     bank ^= tileSplitRotation;
3049 
3050     bank &= (numBanks - 1);
3051 
3052     return bank;
3053 }
3054 
3055 /**
3056 ****************************************************************************************************
3057 *   EgBasedLib::ComputeBankFromAddr
3058 *
3059 *   @brief
3060 *       Compute the bank number from an address
3061 *   @return
3062 *       Bank number
3063 ****************************************************************************************************
3064 */
ComputeBankFromAddr(UINT_64 addr,UINT_32 numBanks,UINT_32 numPipes) const3065 UINT_32 EgBasedLib::ComputeBankFromAddr(
3066     UINT_64 addr,       ///< [in] address
3067     UINT_32 numBanks,   ///< [in] number of banks
3068     UINT_32 numPipes    ///< [in] number of pipes
3069     ) const
3070 {
3071     UINT_32 bank;
3072 
3073     //
3074     // The LSBs of the address are arranged as follows:
3075     //   bank | bankInterleave | pipe | pipeInterleave
3076     //
3077     // To get the bank number, shift off the pipe interleave, pipe, and bank interlave bits and
3078     // mask the bank bits.
3079     //
3080     bank = static_cast<UINT_32>(
3081         (addr >> Log2(m_pipeInterleaveBytes * numPipes * m_bankInterleave)) &
3082         (numBanks - 1)
3083         );
3084 
3085     return bank;
3086 }
3087 
3088 /**
3089 ****************************************************************************************************
3090 *   EgBasedLib::ComputePipeRotation
3091 *
3092 *   @brief
3093 *       Compute pipe rotation value
3094 *   @return
3095 *       Pipe rotation
3096 ****************************************************************************************************
3097 */
ComputePipeRotation(AddrTileMode tileMode,UINT_32 numPipes) const3098 UINT_32 EgBasedLib::ComputePipeRotation(
3099     AddrTileMode tileMode,  ///< [in] tile mode
3100     UINT_32      numPipes   ///< [in] number of pipes
3101     ) const
3102 {
3103    UINT_32 rotation;
3104 
3105     switch (tileMode)
3106     {
3107         case ADDR_TM_3D_TILED_THIN1:        //fall through
3108         case ADDR_TM_3D_TILED_THICK:        //fall through
3109         case ADDR_TM_3D_TILED_XTHICK:       //fall through
3110         case ADDR_TM_PRT_3D_TILED_THIN1:    //fall through
3111         case ADDR_TM_PRT_3D_TILED_THICK:
3112             rotation = (numPipes < 4) ? 1 : (numPipes / 2 - 1);
3113             break;
3114         default:
3115             rotation = 0;
3116     }
3117 
3118     return rotation;
3119 }
3120 
3121 
3122 
3123 /**
3124 ****************************************************************************************************
3125 *   EgBasedLib::ComputeBankRotation
3126 *
3127 *   @brief
3128 *       Compute bank rotation value
3129 *   @return
3130 *       Bank rotation
3131 ****************************************************************************************************
3132 */
ComputeBankRotation(AddrTileMode tileMode,UINT_32 numBanks,UINT_32 numPipes) const3133 UINT_32 EgBasedLib::ComputeBankRotation(
3134     AddrTileMode tileMode,  ///< [in] tile mode
3135     UINT_32      numBanks,  ///< [in] number of banks
3136     UINT_32      numPipes   ///< [in] number of pipes
3137     ) const
3138 {
3139     UINT_32 rotation;
3140 
3141     switch (tileMode)
3142     {
3143         case ADDR_TM_2D_TILED_THIN1: // fall through
3144         case ADDR_TM_2D_TILED_THICK: // fall through
3145         case ADDR_TM_2D_TILED_XTHICK:
3146         case ADDR_TM_PRT_2D_TILED_THIN1:
3147         case ADDR_TM_PRT_2D_TILED_THICK:
3148             // Rotate banks per Z-slice yBit 1 for 4-bank or 3 for 8-bank
3149             rotation =  numBanks / 2 - 1;
3150             break;
3151         case ADDR_TM_3D_TILED_THIN1: // fall through
3152         case ADDR_TM_3D_TILED_THICK: // fall through
3153         case ADDR_TM_3D_TILED_XTHICK:
3154         case ADDR_TM_PRT_3D_TILED_THIN1:
3155         case ADDR_TM_PRT_3D_TILED_THICK:
3156             rotation = (numPipes < 4) ? 1 : (numPipes / 2 - 1);    // rotate pipes & banks
3157             break;
3158         default:
3159             rotation = 0;
3160     }
3161 
3162     return rotation;
3163 }
3164 
3165 
3166 /**
3167 ****************************************************************************************************
3168 *   EgBasedLib::ComputeHtileBytes
3169 *
3170 *   @brief
3171 *       Compute htile size in bytes
3172 *
3173 *   @return
3174 *       Htile size in bytes
3175 ****************************************************************************************************
3176 */
ComputeHtileBytes(UINT_32 pitch,UINT_32 height,UINT_32 bpp,BOOL_32 isLinear,UINT_32 numSlices,UINT_64 * sliceBytes,UINT_32 baseAlign) const3177 UINT_64 EgBasedLib::ComputeHtileBytes(
3178     UINT_32 pitch,        ///< [in] pitch
3179     UINT_32 height,       ///< [in] height
3180     UINT_32 bpp,          ///< [in] bits per pixel
3181     BOOL_32 isLinear,     ///< [in] if it is linear mode
3182     UINT_32 numSlices,    ///< [in] number of slices
3183     UINT_64* sliceBytes,  ///< [out] bytes per slice
3184     UINT_32 baseAlign     ///< [in] base alignments
3185     ) const
3186 {
3187     UINT_64 surfBytes;
3188 
3189     const UINT_64 HtileCacheLineSize = BITS_TO_BYTES(HtileCacheBits);
3190 
3191     *sliceBytes = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp / 64);
3192 
3193     if (m_configFlags.useHtileSliceAlign)
3194     {
3195         // Align the sliceSize to htilecachelinesize * pipes at first
3196         *sliceBytes = PowTwoAlign(*sliceBytes, HtileCacheLineSize * m_pipes);
3197         surfBytes  = *sliceBytes * numSlices;
3198     }
3199     else
3200     {
3201         // Align the surfSize to htilecachelinesize * pipes at last
3202         surfBytes  = *sliceBytes * numSlices;
3203         surfBytes  = PowTwoAlign(surfBytes, HtileCacheLineSize * m_pipes);
3204     }
3205 
3206     return surfBytes;
3207 }
3208 
3209 /**
3210 ****************************************************************************************************
3211 *   EgBasedLib::DispatchComputeFmaskInfo
3212 *
3213 *   @brief
3214 *       Compute fmask sizes include padded pitch, height, slices, total size in bytes,
3215 *       meanwhile output suitable tile mode and alignments as well. Results are returned
3216 *       through output parameters.
3217 *
3218 *   @return
3219 *       ADDR_E_RETURNCODE
3220 ****************************************************************************************************
3221 */
DispatchComputeFmaskInfo(const ADDR_COMPUTE_FMASK_INFO_INPUT * pIn,ADDR_COMPUTE_FMASK_INFO_OUTPUT * pOut)3222 ADDR_E_RETURNCODE EgBasedLib::DispatchComputeFmaskInfo(
3223     const ADDR_COMPUTE_FMASK_INFO_INPUT*    pIn,   ///< [in] input structure
3224     ADDR_COMPUTE_FMASK_INFO_OUTPUT*         pOut)  ///< [out] output structure
3225 {
3226     ADDR_E_RETURNCODE retCode = ADDR_OK;
3227 
3228     ADDR_COMPUTE_SURFACE_INFO_INPUT  surfIn     = {0};
3229     ADDR_COMPUTE_SURFACE_INFO_OUTPUT surfOut    = {0};
3230 
3231     // Setup input structure
3232     surfIn.tileMode          = pIn->tileMode;
3233     surfIn.width             = pIn->pitch;
3234     surfIn.height            = pIn->height;
3235     surfIn.numSlices         = pIn->numSlices;
3236     surfIn.pTileInfo         = pIn->pTileInfo;
3237     surfIn.tileType          = ADDR_NON_DISPLAYABLE;
3238     surfIn.flags.fmask       = 1;
3239 
3240     // Setup output structure
3241     surfOut.pTileInfo       = pOut->pTileInfo;
3242 
3243     // Setup hwl specific fields
3244     HwlFmaskPreThunkSurfInfo(pIn, pOut, &surfIn, &surfOut);
3245 
3246     surfIn.bpp = HwlComputeFmaskBits(pIn, &surfIn.numSamples);
3247 
3248     // ComputeSurfaceInfo needs numSamples in surfOut as surface routines need adjusted numSamples
3249     surfOut.numSamples = surfIn.numSamples;
3250 
3251     retCode = HwlComputeSurfaceInfo(&surfIn, &surfOut);
3252 
3253     // Save bpp field for surface dump support
3254     surfOut.bpp = surfIn.bpp;
3255 
3256     if (retCode == ADDR_OK)
3257     {
3258         pOut->bpp               = surfOut.bpp;
3259         pOut->pitch             = surfOut.pitch;
3260         pOut->height            = surfOut.height;
3261         pOut->numSlices         = surfOut.depth;
3262         pOut->fmaskBytes        = surfOut.surfSize;
3263         pOut->baseAlign         = surfOut.baseAlign;
3264         pOut->pitchAlign        = surfOut.pitchAlign;
3265         pOut->heightAlign       = surfOut.heightAlign;
3266 
3267         if (surfOut.depth > 1)
3268         {
3269             // For fmask, expNumSlices is stored in depth.
3270             pOut->sliceSize = surfOut.surfSize / surfOut.depth;
3271         }
3272         else
3273         {
3274             pOut->sliceSize = surfOut.surfSize;
3275         }
3276 
3277         // Save numSamples field for surface dump support
3278         pOut->numSamples        = surfOut.numSamples;
3279 
3280         HwlFmaskPostThunkSurfInfo(&surfOut, pOut);
3281     }
3282 
3283     return retCode;
3284 }
3285 
3286 /**
3287 ****************************************************************************************************
3288 *   EgBasedLib::HwlFmaskSurfaceInfo
3289 *   @brief
3290 *       Entry of EgBasedLib ComputeFmaskInfo
3291 *   @return
3292 *       ADDR_E_RETURNCODE
3293 ****************************************************************************************************
3294 */
HwlComputeFmaskInfo(const ADDR_COMPUTE_FMASK_INFO_INPUT * pIn,ADDR_COMPUTE_FMASK_INFO_OUTPUT * pOut)3295 ADDR_E_RETURNCODE EgBasedLib::HwlComputeFmaskInfo(
3296     const ADDR_COMPUTE_FMASK_INFO_INPUT*    pIn,   ///< [in] input structure
3297     ADDR_COMPUTE_FMASK_INFO_OUTPUT*         pOut   ///< [out] output structure
3298     )
3299 {
3300     ADDR_E_RETURNCODE retCode = ADDR_OK;
3301 
3302     ADDR_TILEINFO tileInfo = {0};
3303 
3304     // Use internal tile info if pOut does not have a valid pTileInfo
3305     if (pOut->pTileInfo == NULL)
3306     {
3307         pOut->pTileInfo = &tileInfo;
3308     }
3309 
3310     retCode = DispatchComputeFmaskInfo(pIn, pOut);
3311 
3312     if (retCode == ADDR_OK)
3313     {
3314         pOut->tileIndex =
3315             HwlPostCheckTileIndex(pOut->pTileInfo, pIn->tileMode, ADDR_NON_DISPLAYABLE,
3316                                   pOut->tileIndex);
3317     }
3318 
3319     // Resets pTileInfo to NULL if the internal tile info is used
3320     if (pOut->pTileInfo == &tileInfo)
3321     {
3322         pOut->pTileInfo = NULL;
3323     }
3324 
3325     return retCode;
3326 }
3327 
3328 /**
3329 ****************************************************************************************************
3330 *   EgBasedLib::HwlComputeFmaskAddrFromCoord
3331 *   @brief
3332 *       Entry of EgBasedLib ComputeFmaskAddrFromCoord
3333 *   @return
3334 *       ADDR_E_RETURNCODE
3335 ****************************************************************************************************
3336 */
HwlComputeFmaskAddrFromCoord(const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT * pIn,ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT * pOut) const3337 ADDR_E_RETURNCODE EgBasedLib::HwlComputeFmaskAddrFromCoord(
3338     const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
3339     ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure
3340     ) const
3341 {
3342     ADDR_E_RETURNCODE retCode = ADDR_OK;
3343 
3344     return retCode;
3345 }
3346 
3347 /**
3348 ****************************************************************************************************
3349 *   EgBasedLib::HwlComputeFmaskCoordFromAddr
3350 *   @brief
3351 *       Entry of EgBasedLib ComputeFmaskCoordFromAddr
3352 *   @return
3353 *       ADDR_E_RETURNCODE
3354 ****************************************************************************************************
3355 */
HwlComputeFmaskCoordFromAddr(const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT * pIn,ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT * pOut) const3356 ADDR_E_RETURNCODE EgBasedLib::HwlComputeFmaskCoordFromAddr(
3357     const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure
3358     ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT*        pOut    ///< [out] output structure
3359     ) const
3360 {
3361     ADDR_E_RETURNCODE retCode = ADDR_OK;
3362 
3363     return retCode;
3364 }
3365 
3366 /**
3367 ****************************************************************************************************
3368 *   EgBasedLib::ComputeFmaskNumPlanesFromNumSamples
3369 *
3370 *   @brief
3371 *       Compute fmask number of planes from number of samples
3372 *
3373 *   @return
3374 *       Number of planes
3375 ****************************************************************************************************
3376 */
ComputeFmaskNumPlanesFromNumSamples(UINT_32 numSamples)3377 UINT_32 EgBasedLib::ComputeFmaskNumPlanesFromNumSamples(
3378     UINT_32 numSamples)     ///< [in] number of samples
3379 {
3380     UINT_32 numPlanes;
3381 
3382     //
3383     // FMASK is stored such that each micro tile is composed of elements containing N bits, where
3384     // N is the number of samples.  There is a micro tile for each bit in the FMASK address, and
3385     // micro tiles for each address bit, sometimes referred to as a plane, are stored sequentially.
3386     // The FMASK for a 2-sample surface looks like a general surface with 2 bits per element.
3387     // The FMASK for a 4-sample surface looks like a general surface with 4 bits per element and
3388     // 2 samples.  The FMASK for an 8-sample surface looks like a general surface with 8 bits per
3389     // element and 4 samples.  R6xx and R7xx only stored 3 planes for 8-sample FMASK surfaces.
3390     // This was changed for R8xx to simplify the logic in the CB.
3391     //
3392     switch (numSamples)
3393     {
3394         case 2:
3395             numPlanes = 1;
3396             break;
3397         case 4:
3398             numPlanes = 2;
3399             break;
3400         case 8:
3401             numPlanes = 4;
3402             break;
3403         default:
3404             ADDR_UNHANDLED_CASE();
3405             numPlanes = 0;
3406             break;
3407     }
3408     return numPlanes;
3409 }
3410 
3411 /**
3412 ****************************************************************************************************
3413 *   EgBasedLib::ComputeFmaskResolvedBppFromNumSamples
3414 *
3415 *   @brief
3416 *       Compute resolved fmask effective bpp based on number of samples
3417 *
3418 *   @return
3419 *       bpp
3420 ****************************************************************************************************
3421 */
ComputeFmaskResolvedBppFromNumSamples(UINT_32 numSamples)3422 UINT_32 EgBasedLib::ComputeFmaskResolvedBppFromNumSamples(
3423     UINT_32 numSamples)     ///< number of samples
3424 {
3425     UINT_32 bpp;
3426 
3427     //
3428     // Resolved FMASK surfaces are generated yBit the CB and read yBit the texture unit
3429     // so that the texture unit can read compressed multi-sample color data.
3430     // These surfaces store each index value packed per element.
3431     // Each element contains at least num_samples * log2(num_samples) bits.
3432     // Resolved FMASK surfaces are addressed as follows:
3433     // 2-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3434     // 4-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3435     // 8-sample Addressed similarly to a color surface with 32 bits per element and 1 sample.
3436 
3437     switch (numSamples)
3438     {
3439         case 2:
3440             bpp = 8;
3441             break;
3442         case 4:
3443             bpp = 8;
3444             break;
3445         case 8:
3446             bpp = 32;
3447             break;
3448         default:
3449             ADDR_UNHANDLED_CASE();
3450             bpp = 0;
3451             break;
3452     }
3453     return bpp;
3454 }
3455 
3456 /**
3457 ****************************************************************************************************
3458 *   EgBasedLib::IsTileInfoAllZero
3459 *
3460 *   @brief
3461 *       Return TRUE if all field are zero
3462 *   @note
3463 *       Since NULL input is consider to be all zero
3464 ****************************************************************************************************
3465 */
IsTileInfoAllZero(const ADDR_TILEINFO * pTileInfo)3466 BOOL_32 EgBasedLib::IsTileInfoAllZero(
3467     const ADDR_TILEINFO* pTileInfo)
3468 {
3469     BOOL_32 allZero = TRUE;
3470 
3471     if (pTileInfo)
3472     {
3473         if ((pTileInfo->banks            != 0)  ||
3474             (pTileInfo->bankWidth        != 0)  ||
3475             (pTileInfo->bankHeight       != 0)  ||
3476             (pTileInfo->macroAspectRatio != 0)  ||
3477             (pTileInfo->tileSplitBytes   != 0)  ||
3478             (pTileInfo->pipeConfig       != 0)
3479             )
3480         {
3481             allZero = FALSE;
3482         }
3483     }
3484 
3485     return allZero;
3486 }
3487 
3488 /**
3489 ****************************************************************************************************
3490 *   EgBasedLib::HwlTileInfoEqual
3491 *
3492 *   @brief
3493 *       Return TRUE if all field are equal
3494 *   @note
3495 *       Only takes care of current HWL's data
3496 ****************************************************************************************************
3497 */
HwlTileInfoEqual(const ADDR_TILEINFO * pLeft,const ADDR_TILEINFO * pRight) const3498 BOOL_32 EgBasedLib::HwlTileInfoEqual(
3499     const ADDR_TILEINFO* pLeft, ///<[in] Left compare operand
3500     const ADDR_TILEINFO* pRight ///<[in] Right compare operand
3501     ) const
3502 {
3503     BOOL_32 equal = FALSE;
3504 
3505     if (pLeft->banks == pRight->banks           &&
3506         pLeft->bankWidth == pRight->bankWidth   &&
3507         pLeft->bankHeight == pRight->bankHeight &&
3508         pLeft->macroAspectRatio == pRight->macroAspectRatio &&
3509         pLeft->tileSplitBytes == pRight->tileSplitBytes)
3510     {
3511         equal = TRUE;
3512     }
3513 
3514     return equal;
3515 }
3516 
3517 /**
3518 ****************************************************************************************************
3519 *   EgBasedLib::HwlConvertTileInfoToHW
3520 *   @brief
3521 *       Entry of EgBasedLib ConvertTileInfoToHW
3522 *   @return
3523 *       ADDR_E_RETURNCODE
3524 ****************************************************************************************************
3525 */
HwlConvertTileInfoToHW(const ADDR_CONVERT_TILEINFOTOHW_INPUT * pIn,ADDR_CONVERT_TILEINFOTOHW_OUTPUT * pOut) const3526 ADDR_E_RETURNCODE EgBasedLib::HwlConvertTileInfoToHW(
3527     const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure
3528     ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut      ///< [out] output structure
3529     ) const
3530 {
3531     ADDR_E_RETURNCODE retCode   = ADDR_OK;
3532 
3533     ADDR_TILEINFO *pTileInfoIn  = pIn->pTileInfo;
3534     ADDR_TILEINFO *pTileInfoOut = pOut->pTileInfo;
3535 
3536     if ((pTileInfoIn != NULL) && (pTileInfoOut != NULL))
3537     {
3538         if (pIn->reverse == FALSE)
3539         {
3540             switch (pTileInfoIn->banks)
3541             {
3542                 case 2:
3543                     pTileInfoOut->banks = 0;
3544                     break;
3545                 case 4:
3546                     pTileInfoOut->banks = 1;
3547                     break;
3548                 case 8:
3549                     pTileInfoOut->banks = 2;
3550                     break;
3551                 case 16:
3552                     pTileInfoOut->banks = 3;
3553                     break;
3554                 default:
3555                     ADDR_ASSERT_ALWAYS();
3556                     retCode = ADDR_INVALIDPARAMS;
3557                     pTileInfoOut->banks = 0;
3558                     break;
3559             }
3560 
3561             switch (pTileInfoIn->bankWidth)
3562             {
3563                 case 1:
3564                     pTileInfoOut->bankWidth = 0;
3565                     break;
3566                 case 2:
3567                     pTileInfoOut->bankWidth = 1;
3568                     break;
3569                 case 4:
3570                     pTileInfoOut->bankWidth = 2;
3571                     break;
3572                 case 8:
3573                     pTileInfoOut->bankWidth = 3;
3574                     break;
3575                 default:
3576                     ADDR_ASSERT_ALWAYS();
3577                     retCode = ADDR_INVALIDPARAMS;
3578                     pTileInfoOut->bankWidth = 0;
3579                     break;
3580             }
3581 
3582             switch (pTileInfoIn->bankHeight)
3583             {
3584                 case 1:
3585                     pTileInfoOut->bankHeight = 0;
3586                     break;
3587                 case 2:
3588                     pTileInfoOut->bankHeight = 1;
3589                     break;
3590                 case 4:
3591                     pTileInfoOut->bankHeight = 2;
3592                     break;
3593                 case 8:
3594                     pTileInfoOut->bankHeight = 3;
3595                     break;
3596                 default:
3597                     ADDR_ASSERT_ALWAYS();
3598                     retCode = ADDR_INVALIDPARAMS;
3599                     pTileInfoOut->bankHeight = 0;
3600                     break;
3601             }
3602 
3603             switch (pTileInfoIn->macroAspectRatio)
3604             {
3605                 case 1:
3606                     pTileInfoOut->macroAspectRatio = 0;
3607                     break;
3608                 case 2:
3609                     pTileInfoOut->macroAspectRatio = 1;
3610                     break;
3611                 case 4:
3612                     pTileInfoOut->macroAspectRatio = 2;
3613                     break;
3614                 case 8:
3615                     pTileInfoOut->macroAspectRatio = 3;
3616                     break;
3617                 default:
3618                     ADDR_ASSERT_ALWAYS();
3619                     retCode = ADDR_INVALIDPARAMS;
3620                     pTileInfoOut->macroAspectRatio = 0;
3621                     break;
3622             }
3623 
3624             switch (pTileInfoIn->tileSplitBytes)
3625             {
3626                 case 64:
3627                     pTileInfoOut->tileSplitBytes = 0;
3628                     break;
3629                 case 128:
3630                     pTileInfoOut->tileSplitBytes = 1;
3631                     break;
3632                 case 256:
3633                     pTileInfoOut->tileSplitBytes = 2;
3634                     break;
3635                 case 512:
3636                     pTileInfoOut->tileSplitBytes = 3;
3637                     break;
3638                 case 1024:
3639                     pTileInfoOut->tileSplitBytes = 4;
3640                     break;
3641                 case 2048:
3642                     pTileInfoOut->tileSplitBytes = 5;
3643                     break;
3644                 case 4096:
3645                     pTileInfoOut->tileSplitBytes = 6;
3646                     break;
3647                 default:
3648                     ADDR_ASSERT_ALWAYS();
3649                     retCode = ADDR_INVALIDPARAMS;
3650                     pTileInfoOut->tileSplitBytes = 0;
3651                     break;
3652             }
3653         }
3654         else
3655         {
3656             switch (pTileInfoIn->banks)
3657             {
3658                 case 0:
3659                     pTileInfoOut->banks = 2;
3660                     break;
3661                 case 1:
3662                     pTileInfoOut->banks = 4;
3663                     break;
3664                 case 2:
3665                     pTileInfoOut->banks = 8;
3666                     break;
3667                 case 3:
3668                     pTileInfoOut->banks = 16;
3669                     break;
3670                 default:
3671                     ADDR_ASSERT_ALWAYS();
3672                     retCode = ADDR_INVALIDPARAMS;
3673                     pTileInfoOut->banks = 2;
3674                     break;
3675             }
3676 
3677             switch (pTileInfoIn->bankWidth)
3678             {
3679                 case 0:
3680                     pTileInfoOut->bankWidth = 1;
3681                     break;
3682                 case 1:
3683                     pTileInfoOut->bankWidth = 2;
3684                     break;
3685                 case 2:
3686                     pTileInfoOut->bankWidth = 4;
3687                     break;
3688                 case 3:
3689                     pTileInfoOut->bankWidth = 8;
3690                     break;
3691                 default:
3692                     ADDR_ASSERT_ALWAYS();
3693                     retCode = ADDR_INVALIDPARAMS;
3694                     pTileInfoOut->bankWidth = 1;
3695                     break;
3696             }
3697 
3698             switch (pTileInfoIn->bankHeight)
3699             {
3700                 case 0:
3701                     pTileInfoOut->bankHeight = 1;
3702                     break;
3703                 case 1:
3704                     pTileInfoOut->bankHeight = 2;
3705                     break;
3706                 case 2:
3707                     pTileInfoOut->bankHeight = 4;
3708                     break;
3709                 case 3:
3710                     pTileInfoOut->bankHeight = 8;
3711                     break;
3712                 default:
3713                     ADDR_ASSERT_ALWAYS();
3714                     retCode = ADDR_INVALIDPARAMS;
3715                     pTileInfoOut->bankHeight = 1;
3716                     break;
3717             }
3718 
3719             switch (pTileInfoIn->macroAspectRatio)
3720             {
3721                 case 0:
3722                     pTileInfoOut->macroAspectRatio = 1;
3723                     break;
3724                 case 1:
3725                     pTileInfoOut->macroAspectRatio = 2;
3726                     break;
3727                 case 2:
3728                     pTileInfoOut->macroAspectRatio = 4;
3729                     break;
3730                 case 3:
3731                     pTileInfoOut->macroAspectRatio = 8;
3732                     break;
3733                 default:
3734                     ADDR_ASSERT_ALWAYS();
3735                     retCode = ADDR_INVALIDPARAMS;
3736                     pTileInfoOut->macroAspectRatio = 1;
3737                     break;
3738             }
3739 
3740             switch (pTileInfoIn->tileSplitBytes)
3741             {
3742                 case 0:
3743                     pTileInfoOut->tileSplitBytes = 64;
3744                     break;
3745                 case 1:
3746                     pTileInfoOut->tileSplitBytes = 128;
3747                     break;
3748                 case 2:
3749                     pTileInfoOut->tileSplitBytes = 256;
3750                     break;
3751                 case 3:
3752                     pTileInfoOut->tileSplitBytes = 512;
3753                     break;
3754                 case 4:
3755                     pTileInfoOut->tileSplitBytes = 1024;
3756                     break;
3757                 case 5:
3758                     pTileInfoOut->tileSplitBytes = 2048;
3759                     break;
3760                 case 6:
3761                     pTileInfoOut->tileSplitBytes = 4096;
3762                     break;
3763                 default:
3764                     ADDR_ASSERT_ALWAYS();
3765                     retCode = ADDR_INVALIDPARAMS;
3766                     pTileInfoOut->tileSplitBytes = 64;
3767                     break;
3768             }
3769         }
3770 
3771         if (pTileInfoIn != pTileInfoOut)
3772         {
3773             pTileInfoOut->pipeConfig = pTileInfoIn->pipeConfig;
3774         }
3775     }
3776     else
3777     {
3778         ADDR_ASSERT_ALWAYS();
3779         retCode = ADDR_INVALIDPARAMS;
3780     }
3781 
3782     return retCode;
3783 }
3784 
3785 /**
3786 ****************************************************************************************************
3787 *   EgBasedLib::HwlComputeSurfaceInfo
3788 *   @brief
3789 *       Entry of EgBasedLib ComputeSurfaceInfo
3790 *   @return
3791 *       ADDR_E_RETURNCODE
3792 ****************************************************************************************************
3793 */
HwlComputeSurfaceInfo(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const3794 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSurfaceInfo(
3795     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,    ///< [in] input structure
3796     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [out] output structure
3797     ) const
3798 {
3799     ADDR_E_RETURNCODE retCode = ADDR_OK;
3800 
3801     if (pIn->numSamples < pIn->numFrags)
3802     {
3803         retCode = ADDR_INVALIDPARAMS;
3804     }
3805 
3806     ADDR_TILEINFO tileInfo = {0};
3807 
3808     if (retCode == ADDR_OK)
3809     {
3810         // Uses internal tile info if pOut does not have a valid pTileInfo
3811         if (pOut->pTileInfo == NULL)
3812         {
3813             pOut->pTileInfo = &tileInfo;
3814         }
3815 
3816         if (DispatchComputeSurfaceInfo(pIn, pOut) == FALSE)
3817         {
3818             retCode = ADDR_INVALIDPARAMS;
3819         }
3820 
3821         // In case client uses tile info as input and would like to calculate a correct size and
3822         // alignment together with tile info as output when the tile info is not suppose to have any
3823         // matching indices in tile mode tables.
3824         if (pIn->flags.skipIndicesOutput == FALSE)
3825         {
3826             // Returns an index
3827             pOut->tileIndex = HwlPostCheckTileIndex(pOut->pTileInfo,
3828                                                     pOut->tileMode,
3829                                                     pOut->tileType,
3830                                                     pOut->tileIndex);
3831 
3832             if (IsMacroTiled(pOut->tileMode) && (pOut->macroModeIndex == TileIndexInvalid))
3833             {
3834                 pOut->macroModeIndex = HwlComputeMacroModeIndex(pOut->tileIndex,
3835                                                                 pIn->flags,
3836                                                                 pIn->bpp,
3837                                                                 pIn->numSamples,
3838                                                                 pOut->pTileInfo);
3839             }
3840         }
3841 
3842         // Resets pTileInfo to NULL if the internal tile info is used
3843         if (pOut->pTileInfo == &tileInfo)
3844         {
3845 #if DEBUG
3846             // Client does not pass in a valid pTileInfo
3847             if (IsMacroTiled(pOut->tileMode))
3848             {
3849                 // If a valid index is returned, then no pTileInfo is okay
3850                 ADDR_ASSERT((m_configFlags.useTileIndex == FALSE) ||
3851                             (pOut->tileIndex != TileIndexInvalid));
3852 
3853                 if (IsTileInfoAllZero(pIn->pTileInfo) == FALSE)
3854                 {
3855                     // The initial value of pIn->pTileInfo is copied to tileInfo
3856                     // We do not expect any of these value to be changed nor any 0 of inputs
3857                     ADDR_ASSERT(tileInfo.banks == pIn->pTileInfo->banks);
3858                     ADDR_ASSERT(tileInfo.bankWidth == pIn->pTileInfo->bankWidth);
3859                     ADDR_ASSERT(tileInfo.bankHeight == pIn->pTileInfo->bankHeight);
3860                     ADDR_ASSERT(tileInfo.macroAspectRatio == pIn->pTileInfo->macroAspectRatio);
3861                     ADDR_ASSERT(tileInfo.tileSplitBytes == pIn->pTileInfo->tileSplitBytes);
3862                 }
3863             }
3864 #endif
3865             pOut->pTileInfo = NULL;
3866         }
3867     }
3868 
3869     return retCode;
3870 }
3871 
3872 /**
3873 ****************************************************************************************************
3874 *   EgBasedLib::HwlComputeSurfaceAddrFromCoord
3875 *   @brief
3876 *       Entry of EgBasedLib ComputeSurfaceAddrFromCoord
3877 *   @return
3878 *       ADDR_E_RETURNCODE
3879 ****************************************************************************************************
3880 */
HwlComputeSurfaceAddrFromCoord(const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const3881 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSurfaceAddrFromCoord(
3882     const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
3883     ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
3884     ) const
3885 {
3886     ADDR_E_RETURNCODE retCode = ADDR_OK;
3887 
3888     if (
3889 #if !ALT_TEST // Overflow test needs this out-of-boundary coord
3890         (pIn->x > pIn->pitch)   ||
3891         (pIn->y > pIn->height)  ||
3892 #endif
3893         (pIn->numSamples > m_maxSamples))
3894     {
3895         retCode = ADDR_INVALIDPARAMS;
3896     }
3897     else
3898     {
3899         pOut->addr = DispatchComputeSurfaceAddrFromCoord(pIn, pOut);
3900     }
3901 
3902     return retCode;
3903 }
3904 
3905 /**
3906 ****************************************************************************************************
3907 *   EgBasedLib::HwlComputeSurfaceCoordFromAddr
3908 *   @brief
3909 *       Entry of EgBasedLib ComputeSurfaceCoordFromAddr
3910 *   @return
3911 *       ADDR_E_RETURNCODE
3912 ****************************************************************************************************
3913 */
HwlComputeSurfaceCoordFromAddr(const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT * pIn,ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT * pOut) const3914 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSurfaceCoordFromAddr(
3915     const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure
3916     ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure
3917     ) const
3918 {
3919     ADDR_E_RETURNCODE retCode = ADDR_OK;
3920 
3921     if ((pIn->bitPosition >= 8) ||
3922         (pIn->numSamples > m_maxSamples))
3923     {
3924         retCode = ADDR_INVALIDPARAMS;
3925     }
3926     else
3927     {
3928         DispatchComputeSurfaceCoordFromAddr(pIn, pOut);
3929     }
3930     return retCode;
3931 }
3932 
3933 /**
3934 ****************************************************************************************************
3935 *   EgBasedLib::HwlComputeSliceTileSwizzle
3936 *   @brief
3937 *       Entry of EgBasedLib ComputeSurfaceCoordFromAddr
3938 *   @return
3939 *       ADDR_E_RETURNCODE
3940 ****************************************************************************************************
3941 */
HwlComputeSliceTileSwizzle(const ADDR_COMPUTE_SLICESWIZZLE_INPUT * pIn,ADDR_COMPUTE_SLICESWIZZLE_OUTPUT * pOut) const3942 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSliceTileSwizzle(
3943     const ADDR_COMPUTE_SLICESWIZZLE_INPUT*  pIn,    ///< [in] input structure
3944     ADDR_COMPUTE_SLICESWIZZLE_OUTPUT*       pOut    ///< [out] output structure
3945     ) const
3946 {
3947     ADDR_E_RETURNCODE retCode = ADDR_OK;
3948 
3949     if (pIn->pTileInfo && (pIn->pTileInfo->banks > 0))
3950     {
3951 
3952         pOut->tileSwizzle = ComputeSliceTileSwizzle(pIn->tileMode,
3953                                                     pIn->baseSwizzle,
3954                                                     pIn->slice,
3955                                                     pIn->baseAddr,
3956                                                     pIn->pTileInfo);
3957     }
3958     else
3959     {
3960         retCode = ADDR_INVALIDPARAMS;
3961     }
3962 
3963     return retCode;
3964 }
3965 
3966 /**
3967 ****************************************************************************************************
3968 *   EgBasedLib::HwlComputeHtileBpp
3969 *
3970 *   @brief
3971 *       Compute htile bpp
3972 *
3973 *   @return
3974 *       Htile bpp
3975 ****************************************************************************************************
3976 */
HwlComputeHtileBpp(BOOL_32 isWidth8,BOOL_32 isHeight8) const3977 UINT_32 EgBasedLib::HwlComputeHtileBpp(
3978     BOOL_32 isWidth8,   ///< [in] TRUE if block width is 8
3979     BOOL_32 isHeight8   ///< [in] TRUE if block height is 8
3980     ) const
3981 {
3982     // only support 8x8 mode
3983     ADDR_ASSERT(isWidth8 && isHeight8);
3984     return 32;
3985 }
3986 
3987 /**
3988 ****************************************************************************************************
3989 *   EgBasedLib::HwlComputeHtileBaseAlign
3990 *
3991 *   @brief
3992 *       Compute htile base alignment
3993 *
3994 *   @return
3995 *       Htile base alignment
3996 ****************************************************************************************************
3997 */
HwlComputeHtileBaseAlign(BOOL_32 isTcCompatible,BOOL_32 isLinear,ADDR_TILEINFO * pTileInfo) const3998 UINT_32 EgBasedLib::HwlComputeHtileBaseAlign(
3999     BOOL_32         isTcCompatible, ///< [in] if TC compatible
4000     BOOL_32         isLinear,       ///< [in] if it is linear mode
4001     ADDR_TILEINFO*  pTileInfo       ///< [in] Tile info
4002     ) const
4003 {
4004     UINT_32 baseAlign = m_pipeInterleaveBytes * HwlGetPipes(pTileInfo);
4005 
4006     if (isTcCompatible)
4007     {
4008         ADDR_ASSERT(pTileInfo != NULL);
4009         if (pTileInfo)
4010         {
4011             baseAlign *= pTileInfo->banks;
4012         }
4013     }
4014 
4015     return baseAlign;
4016 }
4017 
4018 /**
4019 ****************************************************************************************************
4020 *   EgBasedLib::HwlGetPitchAlignmentMicroTiled
4021 *
4022 *   @brief
4023 *       Compute 1D tiled surface pitch alignment, calculation results are returned through
4024 *       output parameters.
4025 *
4026 *   @return
4027 *       pitch alignment
4028 ****************************************************************************************************
4029 */
HwlGetPitchAlignmentMicroTiled(AddrTileMode tileMode,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 numSamples) const4030 UINT_32 EgBasedLib::HwlGetPitchAlignmentMicroTiled(
4031     AddrTileMode        tileMode,          ///< [in] tile mode
4032     UINT_32             bpp,               ///< [in] bits per pixel
4033     ADDR_SURFACE_FLAGS  flags,             ///< [in] surface flags
4034     UINT_32             numSamples         ///< [in] number of samples
4035     ) const
4036 {
4037     UINT_32 pitchAlign;
4038 
4039     UINT_32 microTileThickness = Thickness(tileMode);
4040 
4041     UINT_32 pixelsPerMicroTile;
4042     UINT_32 pixelsPerPipeInterleave;
4043     UINT_32 microTilesPerPipeInterleave;
4044 
4045     //
4046     // Special workaround for depth/stencil buffer, use 8 bpp to meet larger requirement for
4047     // stencil buffer since pitch alignment is related to bpp.
4048     // For a depth only buffer do not set this.
4049     //
4050     // Note: this actually does not work for mipmap but mipmap depth texture is not really
4051     // sampled with mipmap.
4052     //
4053     if (flags.depth && (flags.noStencil == FALSE))
4054     {
4055         bpp = 8;
4056     }
4057 
4058     pixelsPerMicroTile = MicroTilePixels * microTileThickness;
4059     pixelsPerPipeInterleave = BYTES_TO_BITS(m_pipeInterleaveBytes) / (bpp * numSamples);
4060     microTilesPerPipeInterleave = pixelsPerPipeInterleave / pixelsPerMicroTile;
4061 
4062     pitchAlign = Max(MicroTileWidth, microTilesPerPipeInterleave * MicroTileWidth);
4063 
4064     return pitchAlign;
4065 }
4066 
4067 /**
4068 ****************************************************************************************************
4069 *   EgBasedLib::HwlGetSizeAdjustmentMicroTiled
4070 *
4071 *   @brief
4072 *       Adjust 1D tiled surface pitch and slice size
4073 *
4074 *   @return
4075 *       Logical slice size in bytes
4076 ****************************************************************************************************
4077 */
HwlGetSizeAdjustmentMicroTiled(UINT_32 thickness,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 numSamples,UINT_32 baseAlign,UINT_32 pitchAlign,UINT_32 * pPitch,UINT_32 * pHeight) const4078 UINT_64 EgBasedLib::HwlGetSizeAdjustmentMicroTiled(
4079     UINT_32             thickness,      ///< [in] thickness
4080     UINT_32             bpp,            ///< [in] bits per pixel
4081     ADDR_SURFACE_FLAGS  flags,          ///< [in] surface flags
4082     UINT_32             numSamples,     ///< [in] number of samples
4083     UINT_32             baseAlign,      ///< [in] base alignment
4084     UINT_32             pitchAlign,     ///< [in] pitch alignment
4085     UINT_32*            pPitch,         ///< [in,out] pointer to pitch
4086     UINT_32*            pHeight         ///< [in,out] pointer to height
4087     ) const
4088 {
4089     UINT_64 logicalSliceSize;
4090     UINT_64 physicalSliceSize;
4091 
4092     UINT_32 pitch   = *pPitch;
4093     UINT_32 height  = *pHeight;
4094 
4095     // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
4096     logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
4097 
4098     // Physical slice: multiplied by thickness
4099     physicalSliceSize =  logicalSliceSize * thickness;
4100 
4101     //
4102     // R800 will always pad physical slice size to baseAlign which is pipe_interleave_bytes
4103     //
4104     ADDR_ASSERT((physicalSliceSize % baseAlign) == 0);
4105 
4106     return logicalSliceSize;
4107 }
4108 
4109 /**
4110 ****************************************************************************************************
4111 *   EgBasedLib::HwlStereoCheckRightOffsetPadding
4112 *
4113 *   @brief
4114 *       check if the height needs extra padding for stereo right eye offset, to avoid swizzling
4115 *
4116 *   @return
4117 *       TRUE is the extra padding is needed
4118 *
4119 ****************************************************************************************************
4120 */
HwlStereoCheckRightOffsetPadding(ADDR_TILEINFO * pTileInfo) const4121 UINT_32 EgBasedLib::HwlStereoCheckRightOffsetPadding(
4122     ADDR_TILEINFO* pTileInfo    ///< Tiling info
4123     ) const
4124 {
4125     UINT_32 stereoHeightAlign = 0;
4126 
4127     if (pTileInfo->macroAspectRatio > 2)
4128     {
4129         // Since 3D rendering treats right eye surface starting from y == "eye height" while
4130         // display engine treats it to be 0, so the bank bits may be different.
4131         // Additional padding in height is required to make sure it's possible
4132         // to achieve synonym by adjusting bank swizzle of right eye surface.
4133 
4134         static const UINT_32 StereoAspectRatio = 2;
4135         stereoHeightAlign = pTileInfo->banks *
4136             pTileInfo->bankHeight *
4137             MicroTileHeight /
4138             StereoAspectRatio;
4139     }
4140 
4141     return stereoHeightAlign;
4142 }
4143 
4144 } // V1
4145 } // Addr
4146