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