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