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