[Mesa-dev] [PATCH 043/140] amdgpu/addrlib: Add new flags minimizePadding and maxBaseAlign

Marek Olšák maraeo at gmail.com
Mon Mar 20 22:42:53 UTC 2017


From: Frans Gu <frans.gu at amd.com>

1) minimizePadding - Use 1D tile mode if padded size of 2D is bigger
than 1D
2) maxBaseAlign - Force PRT tile mode if macro block size is bigger than
requested alignment.

Also, related changes to tile mode optimization for needEquation.
---
 src/amd/addrlib/addrinterface.h     |   6 +-
 src/amd/addrlib/core/addrlib1.cpp   | 205 ++++++++++++++++++++++++++++--------
 src/amd/addrlib/core/addrlib1.h     |  25 ++++-
 src/amd/addrlib/r800/ciaddrlib.cpp  | 152 ++++++++++++++++++--------
 src/amd/addrlib/r800/ciaddrlib.h    |   5 +
 src/amd/addrlib/r800/egbaddrlib.cpp |  58 +++++-----
 src/amd/addrlib/r800/egbaddrlib.h   |   5 +-
 src/amd/addrlib/r800/siaddrlib.cpp  |  97 ++++++++++++-----
 src/amd/addrlib/r800/siaddrlib.h    |   5 +
 9 files changed, 401 insertions(+), 157 deletions(-)

diff --git a/src/amd/addrlib/addrinterface.h b/src/amd/addrlib/addrinterface.h
index a2a36cd..065545e 100644
--- a/src/amd/addrlib/addrinterface.h
+++ b/src/amd/addrlib/addrinterface.h
@@ -508,21 +508,22 @@ typedef union _ADDR_SURFACE_FLAGS
                                           ///  alignment with CZ families or other ASICs under
                                           ///  PX configuration + CZ.
         UINT_32 nonSplit             : 1; ///< CI: depth texture should not be split
         UINT_32 disableLinearOpt     : 1; ///< Disable tile mode optimization to linear
         UINT_32 needEquation         : 1; ///< Make the surface tile setting equation compatible.
                                           ///  This flag indicates we need to override tile
                                           ///  mode to PRT_* tile mode to disable slice rotation,
                                           ///  which is needed by swizzle pattern equation.
         UINT_32 skipIndicesOutput    : 1; ///< Skipping indices in output.
         UINT_32 rotateDisplay        : 1; ///< Rotate micro tile type
-        UINT_32 reserved             : 6; ///< Reserved bits
+        UINT_32 minimizeAlignment    : 1; ///< Minimize alignment
+        UINT_32 reserved             : 5; ///< Reserved bits
     };
 
     UINT_32 value;
 } ADDR_SURFACE_FLAGS;
 
 /**
 ****************************************************************************************************
 *   ADDR_COMPUTE_SURFACE_INFO_INPUT
 *
 *   @brief
@@ -550,20 +551,23 @@ typedef struct _ADDR_COMPUTE_SURFACE_INFO_INPUT
                                             ///  number of fragments for EQAA
     /// r800 and later HWL parameters
     // Needed by 2D tiling, for linear and 1D tiling, just keep them 0's
     ADDR_TILEINFO*      pTileInfo;          ///< 2D tile parameters. Set to 0 to default/calculate
     AddrTileType        tileType;           ///< Micro tiling type, not needed when tileIndex != -1
     INT_32              tileIndex;          ///< Tile index, MUST be -1 if you don't want to use it
                                             ///  while the global useTileIndex is set to 1
     UINT_32             basePitch;          ///< Base level pitch in pixels, 0 means ignored, is a
                                             ///  must for mip levels from SI+.
                                             ///  Don't use pitch in blocks for compressed formats!
+    UINT_32             maxBaseAlign;       ///< Max base alignment request from client
+    UINT_32             pitchAlign;         ///< Pitch alignment request from client
+    UINT_32             heightAlign;        ///< Height alignment request from client
 } ADDR_COMPUTE_SURFACE_INFO_INPUT;
 
 /**
 ****************************************************************************************************
 *   ADDR_COMPUTE_SURFACE_INFO_OUTPUT
 *
 *   @brief
 *       Output structure for AddrComputeSurfInfo
 *   @note
         Element: AddrLib unit for computing. e.g. BCn: 4x4 blocks; R32B32B32: 32bit with 3x pitch
diff --git a/src/amd/addrlib/core/addrlib1.cpp b/src/amd/addrlib/core/addrlib1.cpp
index d65fd02..516229a 100644
--- a/src/amd/addrlib/core/addrlib1.cpp
+++ b/src/amd/addrlib/core/addrlib1.cpp
@@ -339,27 +339,22 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(
             if (localIn.tileMode == ADDR_TM_UNKNOWN)
             {
                 // HWL layer may override tile mode if necessary
                 HwlSelectTileMode(&localIn);
             }
             else
             {
                 // HWL layer may override tile mode if necessary
                 HwlOverrideTileMode(&localIn);
 
-                AddrTileMode tileMode = localIn.tileMode;
-
                 // Optimize tile mode if possible
-                if (OptimizeTileMode(&localIn, &tileMode))
-                {
-                    localIn.tileMode = tileMode;
-                }
+                OptimizeTileMode(&localIn);
             }
         }
 
         // Call main function to compute surface info
         if (returnCode == ADDR_OK)
         {
             returnCode = HwlComputeSurfaceInfo(&localIn, pOut);
         }
 
         if (returnCode == ADDR_OK)
@@ -3503,86 +3498,206 @@ VOID Lib::ComputeMipLevel(
             pIn->width = PowTwoAlign(pIn->width, 4);
             pIn->height = PowTwoAlign(pIn->height, 4);
         }
     }
 
     HwlComputeMipLevel(pIn);
 }
 
 /**
 ****************************************************************************************************
+*   Lib::DegradeTo1D
+*
+*   @brief
+*       Check if surface can be degraded to 1D
+*   @return
+*       TRUE if degraded
+****************************************************************************************************
+*/
+BOOL_32 Lib::DegradeTo1D(
+    UINT_32 width,                  ///< surface width
+    UINT_32 height,                 ///< surface height
+    UINT_32 macroTilePitchAlign,    ///< macro tile pitch align
+    UINT_32 macroTileHeightAlign    ///< macro tile height align
+    )
+{
+    BOOL_32 degrade = ((width < macroTilePitchAlign) || (height < macroTileHeightAlign));
+
+    // Check whether 2D tiling still has too much footprint
+    if (degrade == FALSE)
+    {
+        // Only check width and height as slices are aligned to thickness
+        UINT_64 unalignedSize = width * height;
+
+        UINT_32 alignedPitch = PowTwoAlign(width, macroTilePitchAlign);
+        UINT_32 alignedHeight = PowTwoAlign(height, macroTileHeightAlign);
+        UINT_64 alignedSize = alignedPitch * alignedHeight;
+
+        // alignedSize > 1.5 * unalignedSize
+        if (2 * alignedSize > 3 * unalignedSize)
+        {
+            degrade = TRUE;
+        }
+    }
+
+    return degrade;
+}
+
+/**
+****************************************************************************************************
 *   Lib::OptimizeTileMode
 *
 *   @brief
 *       Check if base level's tile mode can be optimized (degraded)
 *   @return
-*       TRUE if degraded, also returns degraded tile mode (unchanged if not degraded)
+*       N/A
 ****************************************************************************************************
 */
-BOOL_32 Lib::OptimizeTileMode(
-    const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] Input structure for surface info
-    AddrTileMode*                           pTileMode   ///< [out] Degraded tile mode
+VOID Lib::OptimizeTileMode(
+    ADDR_COMPUTE_SURFACE_INFO_INPUT*  pInOut     ///< [in, out] structure for surface info
     ) const
 {
-    AddrTileMode tileMode = pIn->tileMode;
-    UINT_32 thickness = Thickness(tileMode);
+    AddrTileMode tileMode = pInOut->tileMode;
+    BOOL_32 doOpt = (pInOut->flags.opt4Space == TRUE) ||
+                    (pInOut->flags.minimizeAlignment == TRUE) ||
+                    (pInOut->maxBaseAlign != 0);
 
     // Optimization can only be done on level 0 and samples <= 1
-    if ((pIn->flags.opt4Space == TRUE)      &&
-        (pIn->mipLevel == 0)                &&
-        (pIn->numSamples <= 1)              &&
-        (pIn->flags.display == FALSE)       &&
+    if ((doOpt == TRUE)                     &&
+        (pInOut->mipLevel == 0)             &&
+        (pInOut->flags.display == FALSE)    &&
         (IsPrtTileMode(tileMode) == FALSE)  &&
-        (pIn->flags.prt == FALSE))
+        (pInOut->flags.prt == FALSE))
     {
-        // Check if linear mode is optimal
-        if ((pIn->height == 1) &&
-            (IsLinear(tileMode) == FALSE) &&
-            (ElemLib::IsBlockCompressed(pIn->format) == FALSE) &&
-            (pIn->flags.depth == FALSE) &&
-            (pIn->flags.stencil == FALSE) &&
-            (m_configFlags.disableLinearOpt == FALSE) &&
-            (pIn->flags.disableLinearOpt == FALSE))
+        UINT_32 width = pInOut->width;
+        UINT_32 height = pInOut->height;
+        UINT_32 thickness = Thickness(tileMode);
+        BOOL_32 convertToPrt = FALSE;
+        BOOL_32 macroTiledOK = TRUE;
+        UINT_32 macroWidthAlign = 0;
+        UINT_32 macroHeightAlign = 0;
+        UINT_32 macroSizeAlign = 0;
+
+        if (IsMacroTiled(tileMode))
         {
-            tileMode = ADDR_TM_LINEAR_ALIGNED;
+            macroTiledOK = HwlGetAlignmentInfoMacroTiled(pInOut,
+                                                         &macroWidthAlign,
+                                                         &macroHeightAlign,
+                                                         &macroSizeAlign);
         }
-        else if (IsMacroTiled(tileMode))
+
+        if (macroTiledOK)
         {
-            if (HwlDegradeBaseLevel(pIn))
+            if ((pInOut->flags.opt4Space == TRUE) && (pInOut->numSamples <= 1))
             {
-                tileMode = (thickness == 1) ? ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
+                // Check if linear mode is optimal
+                if ((pInOut->height == 1) &&
+                    (IsLinear(tileMode) == FALSE) &&
+                    (ElemLib::IsBlockCompressed(pInOut->format) == FALSE) &&
+                    (pInOut->flags.depth == FALSE) &&
+                    (pInOut->flags.stencil == FALSE) &&
+                    (m_configFlags.disableLinearOpt == FALSE) &&
+                    (pInOut->flags.disableLinearOpt == FALSE))
+                {
+                    tileMode = ADDR_TM_LINEAR_ALIGNED;
+                }
+                else if (IsMacroTiled(tileMode))
+                {
+                    if (DegradeTo1D(width, height, macroWidthAlign, macroHeightAlign))
+                    {
+                        tileMode = (thickness == 1) ?
+                                   ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
+                    }
+                    else if (thickness > 1)
+                    {
+                        // As in the following HwlComputeSurfaceInfo, thick modes may be degraded to
+                        // thinner modes, we should re-evaluate whether the corresponding
+                        // thinner modes should be degraded. If so, we choose 1D thick mode instead.
+                        tileMode = DegradeLargeThickTile(pInOut->tileMode, pInOut->bpp);
+
+                        if (tileMode != pInOut->tileMode)
+                        {
+                            // Get thickness again after large thick degrade
+                            thickness = Thickness(tileMode);
+
+                            ADDR_COMPUTE_SURFACE_INFO_INPUT input = *pInOut;
+                            input.tileMode = tileMode;
+
+                            macroTiledOK = HwlGetAlignmentInfoMacroTiled(&input,
+                                                                         &macroWidthAlign,
+                                                                         &macroHeightAlign,
+                                                                         &macroSizeAlign);
+
+                            if (macroTiledOK &&
+                                DegradeTo1D(width, height, macroWidthAlign, macroHeightAlign))
+                            {
+                                tileMode = ADDR_TM_1D_TILED_THICK;
+                            }
+                        }
+                    }
+                }
             }
-            else if (thickness > 1)
+
+            if (macroTiledOK)
             {
-                // As in the following HwlComputeSurfaceInfo, thick modes may be degraded to
-                // thinner modes, we should re-evaluate whether the corresponding thinner modes
-                // need to be degraded. If so, we choose 1D thick mode instead.
-                tileMode = DegradeLargeThickTile(pIn->tileMode, pIn->bpp);
-                if (tileMode != pIn->tileMode)
+                if ((pInOut->flags.minimizeAlignment == TRUE) &&
+                    (pInOut->numSamples <= 1) &&
+                    (IsMacroTiled(tileMode) == TRUE))
+                {
+                    UINT_32 macroSize = PowTwoAlign(width, macroWidthAlign) *
+                                        PowTwoAlign(height, macroHeightAlign);
+                    UINT_32 microSize = PowTwoAlign(width, MicroTileWidth) *
+                                        PowTwoAlign(height, MicroTileHeight);
+
+                    if (macroSize > microSize)
+                    {
+                        tileMode = (thickness == 1) ?
+                                   ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
+                    }
+                }
+
+                if ((pInOut->maxBaseAlign != 0) &&
+                    (IsMacroTiled(tileMode) == TRUE))
                 {
-                    ADDR_COMPUTE_SURFACE_INFO_INPUT input = *pIn;
-                    input.tileMode = tileMode;
-                    if (HwlDegradeBaseLevel(&input))
+                    if (macroSizeAlign > pInOut->maxBaseAlign)
                     {
-                        tileMode = ADDR_TM_1D_TILED_THICK;
+                        if (pInOut->numSamples > 1)
+                        {
+                            ADDR_ASSERT(pInOut->maxBaseAlign >= Block64K);
+
+                            convertToPrt = TRUE;
+                        }
+                        else if (pInOut->maxBaseAlign < Block64K)
+                        {
+                            tileMode = (thickness == 1) ?
+                                       ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
+                        }
+                        else
+                        {
+                            convertToPrt = TRUE;
+                        }
                     }
                 }
             }
         }
-    }
 
-    BOOL_32 optimized = (tileMode != pIn->tileMode);
-    if (optimized)
-    {
-        *pTileMode = tileMode;
+        if (convertToPrt)
+        {
+            HwlSetPrtTileMode(pInOut);
+        }
+        else if (tileMode != pInOut->tileMode)
+        {
+            pInOut->tileMode = tileMode;
+        }
     }
-    return optimized;
+
+    HwlOptimizeTileMode(pInOut);
 }
 
 /**
 ****************************************************************************************************
 *   Lib::DegradeLargeThickTile
 *
 *   @brief
 *       Check if the thickness needs to be reduced if a tile is too large
 *   @return
 *       The degraded tile mode (unchanged if not degraded)
diff --git a/src/amd/addrlib/core/addrlib1.h b/src/amd/addrlib/core/addrlib1.h
index c1fc693..0475e7b 100644
--- a/src/amd/addrlib/core/addrlib1.h
+++ b/src/amd/addrlib/core/addrlib1.h
@@ -342,29 +342,36 @@ protected:
 
     virtual VOID HwlComputeXmaskCoordFromAddr(
         UINT_64 addr, UINT_32 bitPosition, UINT_32 pitch, UINT_32 height, UINT_32 numSlices,
         UINT_32 factor, BOOL_32 isLinear, BOOL_32 isWidth8, BOOL_32 isHeight8,
         ADDR_TILEINFO* pTileInfo, UINT_32* pX, UINT_32* pY, UINT_32* pSlice) const;
 
     // Surface mipmap
     VOID    ComputeMipLevel(
         ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const;
 
-    /// Pure Virtual function for Hwl checking degrade for base level
-    virtual BOOL_32 HwlDegradeBaseLevel(
-        const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const = 0;
+    /// Pure Virtual function for Hwl to get macro tiled alignment info
+    virtual BOOL_32 HwlGetAlignmentInfoMacroTiled(
+        const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,
+        UINT_32* pPitchAlign, UINT_32* pHeightAlign, UINT_32* pSizeAlign) const = 0;
+
 
     virtual VOID HwlOverrideTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const
     {
         // not supported in hwl layer
     }
 
+    virtual VOID HwlOptimizeTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const
+    {
+        // not supported in hwl layer
+    }
+
     virtual VOID HwlSelectTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const
     {
         // not supported in hwl layer
     }
 
     AddrTileMode DegradeLargeThickTile(AddrTileMode tileMode, UINT_32 bpp) const;
 
     VOID PadDimensions(
         AddrTileMode tileMode, UINT_32 bpp, ADDR_SURFACE_FLAGS flags,
         UINT_32 numSamples, ADDR_TILEINFO* pTileInfo, UINT_32 padDims, UINT_32 mipLevel,
@@ -489,22 +496,30 @@ protected:
         ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;
 
     /// Quad buffer stereo support, has its implementation in ind. layer
     virtual BOOL_32 ComputeQbStereoInfo(
         ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;
 
     /// Pure virutual function to compute stereo bank swizzle for right eye
     virtual UINT_32 HwlComputeQbStereoRightSwizzle(
         ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const = 0;
 
-    BOOL_32 OptimizeTileMode(
-        const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, AddrTileMode* pTileMode) const;
+    VOID OptimizeTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
+
+    /// Overwrite tile setting to PRT
+    virtual VOID HwlSetPrtTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const
+    {
+    }
+
+    static BOOL_32 DegradeTo1D(
+        UINT_32 width, UINT_32 height,
+        UINT_32 macroTilePitchAlign, UINT_32 macroTileHeightAlign);
 
 private:
     // Disallow the copy constructor
     Lib(const Lib& a);
 
     // Disallow the assignment operator
     Lib& operator=(const Lib& a);
 
     UINT_32 ComputeCmaskBaseAlign(
         ADDR_CMASK_FLAGS flags, ADDR_TILEINFO*  pTileInfo) const;
diff --git a/src/amd/addrlib/r800/ciaddrlib.cpp b/src/amd/addrlib/r800/ciaddrlib.cpp
index ed7958d..7272c49 100644
--- a/src/amd/addrlib/r800/ciaddrlib.cpp
+++ b/src/amd/addrlib/r800/ciaddrlib.cpp
@@ -864,20 +864,90 @@ AddrTileMode CiLib::HwlDegradeThickTileMode(
     AddrTileMode        baseTileMode,   ///< [in] base tile mode
     UINT_32             numSlices,      ///< [in] current number of slices
     UINT_32*            pBytesPerTile   ///< [in,out] pointer to bytes per slice
     ) const
 {
     return baseTileMode;
 }
 
 /**
 ****************************************************************************************************
+*   CiLib::HwlOptimizeTileMode
+*
+*   @brief
+*       Optimize tile mode on CI
+*
+*   @return
+*       N/A
+*
+****************************************************************************************************
+*/
+VOID CiLib::HwlOptimizeTileMode(
+    ADDR_COMPUTE_SURFACE_INFO_INPUT*    pInOut      ///< [in,out] input output structure
+    ) const
+{
+    AddrTileMode tileMode = pInOut->tileMode;
+
+    // Override 2D/3D macro tile mode to PRT_* tile mode if
+    // client driver requests this surface is equation compatible
+    if ((pInOut->flags.needEquation == TRUE) &&
+        (pInOut->numSamples <= 1) &&
+        (IsMacroTiled(tileMode) == TRUE) &&
+        (IsPrtTileMode(tileMode) == FALSE))
+    {
+        UINT_32 thickness = Thickness(tileMode);
+
+        if (pInOut->maxBaseAlign < Block64K)
+        {
+            tileMode = (thickness == 1) ? ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
+        }
+        else if (thickness == 1)
+        {
+            tileMode = ADDR_TM_PRT_TILED_THIN1;
+        }
+        else
+        {
+            static const UINT_32 PrtTileBytes = 0x10000;
+            // First prt thick tile index in the tile mode table
+            static const UINT_32 PrtThickTileIndex = 22;
+            ADDR_TILEINFO tileInfo = {0};
+
+            HwlComputeMacroModeIndex(PrtThickTileIndex,
+                                     pInOut->flags,
+                                     pInOut->bpp,
+                                     pInOut->numSamples,
+                                     &tileInfo);
+
+            UINT_32 macroTileBytes = ((pInOut->bpp) >> 3) * 64 * pInOut->numSamples *
+                                     thickness * HwlGetPipes(&tileInfo) *
+                                     tileInfo.banks * tileInfo.bankWidth *
+                                     tileInfo.bankHeight;
+
+            if (macroTileBytes <= PrtTileBytes)
+            {
+                tileMode = ADDR_TM_PRT_TILED_THICK;
+            }
+            else
+            {
+                tileMode = ADDR_TM_PRT_TILED_THIN1;
+            }
+        }
+    }
+
+    if (tileMode != pInOut->tileMode)
+    {
+        pInOut->tileMode = tileMode;
+    }
+}
+
+/**
+****************************************************************************************************
 *   CiLib::HwlOverrideTileMode
 *
 *   @brief
 *       Override THICK to THIN, for specific formats on CI
 *
 *   @return
 *       N/A
 *
 ****************************************************************************************************
 */
@@ -974,62 +1044,20 @@ VOID CiLib::HwlOverrideTileMode(
                         tileType = ADDR_NON_DISPLAYABLE;
                     }
 
                     break;
                 default:
                     break;
             }
         }
     }
 
-    // Override 2D/3D macro tile mode to PRT_* tile mode if
-    // client driver requests this surface is equation compatible
-    if ((pInOut->flags.needEquation == TRUE) &&
-        (pInOut->numSamples <= 1) &&
-        (IsMacroTiled(tileMode) == TRUE) &&
-        (IsPrtTileMode(tileMode) == FALSE))
-    {
-        UINT_32 thickness = Thickness(tileMode);
-
-        if (thickness == 1)
-        {
-            tileMode = ADDR_TM_PRT_TILED_THIN1;
-        }
-        else
-        {
-            static const UINT_32 PrtTileBytes = 0x10000;
-            // First prt thick tile index in the tile mode table
-            static const UINT_32 PrtThickTileIndex = 22;
-            ADDR_TILEINFO tileInfo = {0};
-
-            HwlComputeMacroModeIndex(PrtThickTileIndex,
-                                     pInOut->flags,
-                                     pInOut->bpp,
-                                     pInOut->numSamples,
-                                     &tileInfo);
-
-            UINT_32 macroTileBytes = ((pInOut->bpp) >> 3) * 64 * pInOut->numSamples *
-                                     thickness * HwlGetPipes(&tileInfo) *
-                                     tileInfo.banks * tileInfo.bankWidth *
-                                     tileInfo.bankHeight;
-
-            if (macroTileBytes <= PrtTileBytes)
-            {
-                tileMode = ADDR_TM_PRT_TILED_THICK;
-            }
-            else
-            {
-                tileMode = ADDR_TM_PRT_TILED_THIN1;
-            }
-        }
-    }
-
     if (tileMode != pInOut->tileMode)
     {
         pInOut->tileMode = tileMode;
         pInOut->tileType = tileType;
     }
 }
 
 /**
 ****************************************************************************************************
 *   CiLib::HwlSelectTileMode
@@ -1108,33 +1136,65 @@ VOID CiLib::HwlSelectTileMode(
         }
     }
 
     pInOut->tileMode = tileMode;
     pInOut->tileType = tileType;
 
     if ((pInOut->flags.dccCompatible == FALSE) &&
         (pInOut->flags.tcCompatible == FALSE))
     {
         pInOut->flags.opt4Space = TRUE;
+        pInOut->maxBaseAlign = Block64K;
 
         // Optimize tile mode if possible
-        if (OptimizeTileMode(pInOut, &tileMode))
-        {
-            pInOut->tileMode = tileMode;
-        }
+        OptimizeTileMode(pInOut);
     }
 
     HwlOverrideTileMode(pInOut);
 }
 
 /**
 ****************************************************************************************************
+*   CiLib::HwlSetPrtTileMode
+*
+*   @brief
+*       Set PRT tile mode.
+*
+*   @return
+*       N/A
+*
+****************************************************************************************************
+*/
+VOID CiLib::HwlSetPrtTileMode(
+    ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut     ///< [in,out] input output structure
+    ) const
+{
+    AddrTileMode tileMode = pInOut->tileMode;
+    AddrTileType tileType = pInOut->tileType;
+
+    if (Thickness(tileMode) > 1)
+    {
+        tileMode = ADDR_TM_PRT_TILED_THICK;
+        tileType = (m_settings.isBonaire == TRUE) ? ADDR_NON_DISPLAYABLE : ADDR_THICK;
+    }
+    else
+    {
+        tileMode = ADDR_TM_PRT_TILED_THIN1;
+        tileType = (tileType == ADDR_THICK) ? ADDR_NON_DISPLAYABLE : tileType;
+    }
+
+    pInOut->tileMode = tileMode;
+    pInOut->tileType = tileType;
+}
+
+/**
+****************************************************************************************************
 *   CiLib::HwlSetupTileInfo
 *
 *   @brief
 *       Setup default value of tile info for SI
 ****************************************************************************************************
 */
 VOID CiLib::HwlSetupTileInfo(
     AddrTileMode                        tileMode,       ///< [in] Tile mode
     ADDR_SURFACE_FLAGS                  flags,          ///< [in] Surface type flags
     UINT_32                             bpp,            ///< [in] Bits per pixel
diff --git a/src/amd/addrlib/r800/ciaddrlib.h b/src/amd/addrlib/r800/ciaddrlib.h
index f6c8655..7fa6b75 100644
--- a/src/amd/addrlib/r800/ciaddrlib.h
+++ b/src/amd/addrlib/r800/ciaddrlib.h
@@ -142,22 +142,27 @@ protected:
 
     virtual VOID HwlFmaskPostThunkSurfInfo(
         const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut,
         ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut) const;
 
     virtual AddrTileMode HwlDegradeThickTileMode(
         AddrTileMode baseTileMode, UINT_32 numSlices, UINT_32* pBytesPerTile) const;
 
     virtual VOID HwlOverrideTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
 
+    virtual VOID HwlOptimizeTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
+
     virtual VOID HwlSelectTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
 
+    /// Overwrite tile setting to PRT
+    virtual VOID HwlSetPrtTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
+
     virtual ADDR_E_RETURNCODE HwlComputeDccInfo(
         const ADDR_COMPUTE_DCCINFO_INPUT* pIn,
         ADDR_COMPUTE_DCCINFO_OUTPUT* pOut) const;
 
     virtual ADDR_E_RETURNCODE HwlComputeCmaskAddrFromCoord(
         const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn,
         ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut) const;
 
     virtual ADDR_E_RETURNCODE HwlComputeHtileAddrFromCoord(
         const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT*  pIn,
diff --git a/src/amd/addrlib/r800/egbaddrlib.cpp b/src/amd/addrlib/r800/egbaddrlib.cpp
index f413cff..2d1123a 100644
--- a/src/amd/addrlib/r800/egbaddrlib.cpp
+++ b/src/amd/addrlib/r800/egbaddrlib.cpp
@@ -233,20 +233,32 @@ BOOL_32 EgBasedLib::ComputeSurfaceInfoLinear(
     //
     // Compute the surface alignments.
     //
     ComputeSurfaceAlignmentsLinear(pIn->tileMode,
                                    pIn->bpp,
                                    pIn->flags,
                                    &pOut->baseAlign,
                                    &pOut->pitchAlign,
                                    &pOut->heightAlign);
 
+    if (pIn->pitchAlign != 0)
+    {
+       ADDR_ASSERT((pIn->pitchAlign % pOut->pitchAlign) == 0);
+       pOut->pitchAlign = pIn->pitchAlign;
+    }
+
+    if (pIn->heightAlign != 0)
+    {
+       ADDR_ASSERT((pIn->heightAlign % pOut->heightAlign) == 0);
+       pOut->heightAlign = pIn->heightAlign;
+    }
+
     if ((pIn->tileMode == ADDR_TM_LINEAR_GENERAL) && pIn->flags.color && (pIn->height > 1))
     {
 #if !ALT_TEST
         // When linear_general surface is accessed in multiple lines, it requires 8 pixels in pitch
         // alignment since PITCH_TILE_MAX is in unit of 8 pixels.
         // It is OK if it is accessed per line.
         ADDR_ASSERT((pIn->width % 8) == 0);
 #endif
     }
 
@@ -1132,100 +1144,86 @@ AddrTileMode EgBasedLib::ComputeSurfaceMipLevelTileMode(
             break;
         default:
             break;
     }
 
     return expTileMode;
 }
 
 /**
 ****************************************************************************************************
-*   EgBasedLib::HwlDegradeBaseLevel
+*   EgBasedLib::HwlGetAlignmentInfoMacroTiled
 *   @brief
-*       Check if degrade is needed for base level
+*       Get alignment info for giving tile mode
 *   @return
-*       TRUE if degrade is suggested
+*       TRUE if getting alignment is OK
 ****************************************************************************************************
 */
-BOOL_32 EgBasedLib::HwlDegradeBaseLevel(
-    const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const
+BOOL_32 EgBasedLib::HwlGetAlignmentInfoMacroTiled(
+    const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,             ///< [in] create surface info
+    UINT_32*                               pPitchAlign,     ///< [out] pitch alignment
+    UINT_32*                               pHeightAlign,    ///< [out] height alignment
+    UINT_32*                               pSizeAlign       ///< [out] size alignment
+    ) const
 {
-    BOOL_32 degrade = FALSE;
     BOOL_32 valid = TRUE;
 
     ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
 
     UINT_32 baseAlign;
     UINT_32 pitchAlign;
     UINT_32 heightAlign;
     UINT_32 macroTileWidth;
     UINT_32 macroTileHeight;
+    UINT_32 numSamples = (pIn->numFrags == 0) ? pIn->numSamples : pIn->numFrags;
 
     ADDR_ASSERT(pIn->pTileInfo);
     ADDR_TILEINFO tileInfo = *pIn->pTileInfo;
     ADDR_COMPUTE_SURFACE_INFO_OUTPUT out = {0};
 
     if (UseTileIndex(pIn->tileIndex))
     {
         out.tileIndex = pIn->tileIndex;
         out.macroModeIndex = TileIndexInvalid;
     }
 
     HwlSetupTileInfo(pIn->tileMode,
                      pIn->flags,
                      pIn->bpp,
                      pIn->width,
                      pIn->height,
-                     pIn->numSamples,
+                     numSamples,
                      &tileInfo,
                      &tileInfo,
                      pIn->tileType,
                      &out);
 
     valid = ComputeSurfaceAlignmentsMacroTiled(pIn->tileMode,
                                                pIn->bpp,
                                                pIn->flags,
                                                pIn->mipLevel,
-                                               pIn->numSamples,
+                                               numSamples,
                                                &tileInfo,
                                                &baseAlign,
                                                &pitchAlign,
                                                &heightAlign,
                                                &macroTileWidth,
                                                &macroTileHeight);
 
     if (valid)
     {
-        degrade = ((pIn->width < macroTileWidth) || (pIn->height < macroTileHeight));
-        // Check whether 2D tiling still has too much footprint
-        if (degrade == FALSE)
-        {
-            // Only check width and height as slices are aligned to thickness
-            UINT_64 unalignedSize = pIn->width * pIn->height;
-
-            UINT_32 alignedPitch = PowTwoAlign(pIn->width, pitchAlign);
-            UINT_32 alignedHeight = PowTwoAlign(pIn->height, heightAlign);
-            UINT_64 alignedSize = alignedPitch * alignedHeight;
-
-            // alignedSize > 1.5 * unalignedSize
-            if (2 * alignedSize > 3 * unalignedSize)
-            {
-                degrade = TRUE;
-            }
-        }
-    }
-    else
-    {
-        degrade = TRUE;
+        *pPitchAlign = pitchAlign;
+        *pHeightAlign = heightAlign;
+        *pSizeAlign = baseAlign;
     }
 
-    return degrade;
+    return valid;
 }
 
 /**
 ****************************************************************************************************
 *   EgBasedLib::HwlDegradeThickTileMode
 *
 *   @brief
 *       Degrades valid tile mode for thick modes if needed
 *
 *   @return
diff --git a/src/amd/addrlib/r800/egbaddrlib.h b/src/amd/addrlib/r800/egbaddrlib.h
index 1a56003..50fd3d9 100644
--- a/src/amd/addrlib/r800/egbaddrlib.h
+++ b/src/amd/addrlib/r800/egbaddrlib.h
@@ -130,22 +130,23 @@ protected:
         ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut);
 
     virtual ADDR_E_RETURNCODE HwlComputeFmaskAddrFromCoord(
         const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn,
         ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut) const;
 
     virtual ADDR_E_RETURNCODE HwlComputeFmaskCoordFromAddr(
         const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn,
         ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut) const;
 
-    virtual BOOL_32 HwlDegradeBaseLevel(
-        const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const;
+    virtual BOOL_32 HwlGetAlignmentInfoMacroTiled(
+        const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,
+        UINT_32* pPitchAlign, UINT_32* pHeightAlign, UINT_32* pSizeAlign) const;
 
     virtual UINT_32 HwlComputeQbStereoRightSwizzle(
         ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pInfo) const;
 
     virtual VOID 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) const;
 
diff --git a/src/amd/addrlib/r800/siaddrlib.cpp b/src/amd/addrlib/r800/siaddrlib.cpp
index f8f9379..299951e 100644
--- a/src/amd/addrlib/r800/siaddrlib.cpp
+++ b/src/amd/addrlib/r800/siaddrlib.cpp
@@ -3128,20 +3128,66 @@ UINT_32 SiLib::HwlComputeFmaskBits(
         }
     }
 
     SafeAssign(pNumSamples, numSamples);
 
     return bpp;
 }
 
 /**
 ****************************************************************************************************
+*   SiLib::HwlOptimizeTileMode
+*
+*   @brief
+*       Optimize tile mode on SI
+*
+*   @return
+*       N/A
+*
+****************************************************************************************************
+*/
+VOID SiLib::HwlOptimizeTileMode(
+    ADDR_COMPUTE_SURFACE_INFO_INPUT*    pInOut      ///< [in,out] input output structure
+    ) const
+{
+    AddrTileMode tileMode = pInOut->tileMode;
+
+    if ((pInOut->flags.needEquation == TRUE) &&
+        (IsMacroTiled(tileMode) == TRUE) &&
+        (pInOut->numSamples <= 1))
+    {
+        UINT_32 thickness = Thickness(tileMode);
+
+        pInOut->flags.prt = TRUE;
+
+        if (thickness > 1)
+        {
+            tileMode = ADDR_TM_1D_TILED_THICK;
+        }
+        else if (pInOut->numSlices > 1)
+        {
+            tileMode = ADDR_TM_1D_TILED_THIN1;
+        }
+        else
+        {
+            tileMode = ADDR_TM_2D_TILED_THIN1;
+        }
+    }
+
+    if (tileMode != pInOut->tileMode)
+    {
+        pInOut->tileMode = tileMode;
+    }
+}
+
+/**
+****************************************************************************************************
 *   SiLib::HwlOverrideTileMode
 *
 *   @brief
 *       Override tile modes (for PRT only, avoid client passes in an invalid PRT mode for SI.
 *
 *   @return
 *       N/A
 *
 ****************************************************************************************************
 */
@@ -3166,52 +3212,52 @@ VOID SiLib::HwlOverrideTileMode(
             break;
 
         case ADDR_TM_PRT_3D_TILED_THICK:
             tileMode    = ADDR_TM_3D_TILED_THICK;
             break;
 
         default:
             break;
     }
 
-    if ((pInOut->flags.needEquation == TRUE) &&
-        (IsMacroTiled(tileMode) == TRUE) &&
-        (pInOut->numSamples <= 1))
-    {
-        UINT_32 thickness = Thickness(tileMode);
-
-        pInOut->flags.prt = TRUE;
-
-        if (thickness > 1)
-        {
-            tileMode = ADDR_TM_1D_TILED_THICK;
-        }
-        else if (pInOut->numSlices > 1)
-        {
-            tileMode = ADDR_TM_1D_TILED_THIN1;
-        }
-        else
-        {
-            tileMode = ADDR_TM_2D_TILED_THIN1;
-        }
-    }
-
     if (tileMode != pInOut->tileMode)
     {
         pInOut->tileMode = tileMode;
 
         ADDR_ASSERT(pInOut->flags.prt == TRUE);
     }
 }
 
 /**
 ****************************************************************************************************
+*   SiLib::HwlSetPrtTileMode
+*
+*   @brief
+*       Set prt tile modes.
+*
+*   @return
+*       N/A
+*
+****************************************************************************************************
+*/
+VOID SiLib::HwlSetPrtTileMode(
+    ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut     ///< [in,out] input output structure
+    ) const
+{
+    pInOut->tileMode = ADDR_TM_2D_TILED_THIN1;
+    pInOut->tileType = (pInOut->tileType == ADDR_DEPTH_SAMPLE_ORDER) ?
+                       ADDR_DEPTH_SAMPLE_ORDER : ADDR_NON_DISPLAYABLE;
+    pInOut->flags.prt = TRUE;
+}
+
+/**
+****************************************************************************************************
 *   SiLib::HwlSelectTileMode
 *
 *   @brief
 *       Select tile modes.
 *
 *   @return
 *       N/A
 *
 ****************************************************************************************************
 */
@@ -3264,24 +3310,21 @@ VOID SiLib::HwlSelectTileMode(
         tileType = (tileType == ADDR_DISPLAYABLE) ? ADDR_NON_DISPLAYABLE : tileType;
     }
 
     pInOut->tileMode = tileMode;
     pInOut->tileType = tileType;
 
     // Optimize tile mode if possible
     pInOut->flags.opt4Space = TRUE;
 
     // Optimize tile mode if possible
-    if (OptimizeTileMode(pInOut, &tileMode))
-    {
-        pInOut->tileMode = tileMode;
-    }
+    OptimizeTileMode(pInOut);
 
     HwlOverrideTileMode(pInOut);
 }
 
 /**
 ****************************************************************************************************
 *   SiLib::HwlGetMaxAlignments
 *
 *   @brief
 *       Gets maximum alignments
@@ -3485,22 +3528,20 @@ VOID SiLib::InitEquationTable()
 
                             m_blockWidth[equationIndex]  =
                                 HwlGetPipes(pTileInfo) * MicroTileWidth * pTileInfo->bankWidth *
                                 pTileInfo->macroAspectRatio;
                             m_blockHeight[equationIndex] =
                                 MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks /
                                 pTileInfo->macroAspectRatio;
 
                             if (m_chipFamily == ADDR_CHIP_FAMILY_SI)
                             {
-                                static const UINT_32 PrtTileSize = 0x10000;
-
                                 UINT_32 macroTileSize =
                                     m_blockWidth[equationIndex] * m_blockHeight[equationIndex] *
                                     bpp / 8;
 
                                 if (macroTileSize < PrtTileSize)
                                 {
                                     UINT_32 numMacroTiles = PrtTileSize / macroTileSize;
 
                                     ADDR_ASSERT(macroTileSize == (1u << equation.numBits));
                                     ADDR_ASSERT((PrtTileSize % macroTileSize) == 0);
diff --git a/src/amd/addrlib/r800/siaddrlib.h b/src/amd/addrlib/r800/siaddrlib.h
index 86d2116..53ec68b 100644
--- a/src/amd/addrlib/r800/siaddrlib.h
+++ b/src/amd/addrlib/r800/siaddrlib.h
@@ -182,22 +182,27 @@ protected:
         const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;
 
     virtual BOOL_32 HwlTileInfoEqual(
         const ADDR_TILEINFO* pLeft, const ADDR_TILEINFO* pRight) const;
 
     virtual AddrTileMode HwlDegradeThickTileMode(
         AddrTileMode baseTileMode, UINT_32 numSlices, UINT_32* pBytesPerTile) const;
 
     virtual VOID HwlOverrideTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
 
+    virtual VOID HwlOptimizeTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
+
     virtual VOID HwlSelectTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
 
+    /// Overwrite tile setting to PRT
+    virtual VOID HwlSetPrtTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
+
     virtual BOOL_32 HwlSanityCheckMacroTiled(
         ADDR_TILEINFO* pTileInfo) const
     {
         return TRUE;
     }
 
     virtual UINT_32 HwlGetPitchAlignmentLinear(UINT_32 bpp, ADDR_SURFACE_FLAGS flags) const;
 
     virtual UINT_64 HwlGetSizeAdjustmentLinear(
         AddrTileMode tileMode,
-- 
2.7.4



More information about the mesa-dev mailing list