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