[Mesa-dev] [PATCH 031/140] amdgpu/addrlib: Add a new tile mode ADDR_TM_UNKNOWN

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


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

This can be used by address lib client to ask address lib to select
tile mode.
---
 src/amd/addrlib/addrinterface.h    |  3 +-
 src/amd/addrlib/addrtypes.h        |  3 +-
 src/amd/addrlib/core/addrlib1.cpp  | 32 +++++++++----
 src/amd/addrlib/core/addrlib1.h    | 11 +++--
 src/amd/addrlib/r800/ciaddrlib.cpp | 96 ++++++++++++++++++++++++++++++++++++++
 src/amd/addrlib/r800/ciaddrlib.h   |  2 +
 src/amd/addrlib/r800/siaddrlib.cpp | 76 ++++++++++++++++++++++++++++++
 src/amd/addrlib/r800/siaddrlib.h   |  2 +
 8 files changed, 211 insertions(+), 14 deletions(-)

diff --git a/src/amd/addrlib/addrinterface.h b/src/amd/addrlib/addrinterface.h
index 3604fb1..fef8d49 100644
--- a/src/amd/addrlib/addrinterface.h
+++ b/src/amd/addrlib/addrinterface.h
@@ -507,21 +507,22 @@ typedef union _ADDR_SURFACE_FLAGS
                                           ///  This flag indicates we need to follow the
                                           ///  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 reserved             : 7; ///< Reserved bits
+        UINT_32 rotateDisplay        : 1; ///< Rotate micro tile type
+        UINT_32 reserved             : 6; ///< Reserved bits
     };
 
     UINT_32 value;
 } ADDR_SURFACE_FLAGS;
 
 /**
 ***************************************************************************************************
 *   ADDR_COMPUTE_SURFACE_INFO_INPUT
 *
 *   @brief
diff --git a/src/amd/addrlib/addrtypes.h b/src/amd/addrlib/addrtypes.h
index fb8e706..681bb24 100644
--- a/src/amd/addrlib/addrtypes.h
+++ b/src/amd/addrlib/addrtypes.h
@@ -188,21 +188,22 @@ typedef enum _AddrTileMode
     ADDR_TM_3B_TILED_THICK      = 15,   ///< 600 HWL only, with bank swap, thick
     ADDR_TM_2D_TILED_XTHICK     = 16,   ///< Tile is 8x8x8, valid from NI
     ADDR_TM_3D_TILED_XTHICK     = 17,   ///< Tile is 8x8x8, valid from NI
     ADDR_TM_POWER_SAVE          = 18,   ///< Power save mode, only used by KMD on NI
     ADDR_TM_PRT_TILED_THIN1     = 19,   ///< No bank/pipe rotation or hashing beyond macrotile size
     ADDR_TM_PRT_2D_TILED_THIN1  = 20,   ///< Same as 2D_TILED_THIN1, PRT only
     ADDR_TM_PRT_3D_TILED_THIN1  = 21,   ///< Same as 3D_TILED_THIN1, PRT only
     ADDR_TM_PRT_TILED_THICK     = 22,   ///< No bank/pipe rotation or hashing beyond macrotile size
     ADDR_TM_PRT_2D_TILED_THICK  = 23,   ///< Same as 2D_TILED_THICK, PRT only
     ADDR_TM_PRT_3D_TILED_THICK  = 24,   ///< Same as 3D_TILED_THICK, PRT only
-    ADDR_TM_COUNT               = 25,   ///< Must be the value of the last tile mode
+    ADDR_TM_UNKNOWN             = 25,   ///< Unkown tile mode, should be decided by address lib
+    ADDR_TM_COUNT               = 26,   ///< Must be the value of the last tile mode
 } AddrTileMode;
 
 /**
 ***************************************************************************************************
 *   AddrFormat
 *
 *   @brief
 *       Neutral enum for SurfaceFormat
 *
 ***************************************************************************************************
diff --git a/src/amd/addrlib/core/addrlib1.cpp b/src/amd/addrlib/core/addrlib1.cpp
index 5e68f27..e4570cc 100644
--- a/src/amd/addrlib/core/addrlib1.cpp
+++ b/src/amd/addrlib/core/addrlib1.cpp
@@ -60,20 +60,21 @@ const AddrTileModeFlags AddrLib1::ModeFlags[ADDR_TM_COUNT] =
     {4, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THICK
     {8, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_XTHICK
     {8, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_XTHICK
     {1, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_POWER_SAVE
     {1, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THIN1
     {1, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THIN1
     {1, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THIN1
     {4, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THICK
     {4, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THICK
     {4, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THICK
+    {0, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_UNKNOWN
 };
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 //                               Constructor/Destructor
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 /**
 ***************************************************************************************************
 *   AddrLib1::AddrLib1
 *
@@ -172,22 +173,27 @@ ADDR_E_RETURNCODE AddrLib1::ComputeSurfaceInfo(
             returnCode = ADDR_PARAMSIZEMISMATCH;
         }
     }
 
     // We suggest client do sanity check but a check here is also good
     if (pIn->bpp > 128)
     {
         returnCode = ADDR_INVALIDPARAMS;
     }
 
+    if ((pIn->tileMode == ADDR_TM_UNKNOWN) && (pIn->mipLevel > 0))
+    {
+        returnCode = ADDR_INVALIDPARAMS;
+    }
+
     // Thick modes don't support multisample
-    if (Thickness(pIn->tileMode) > 1 && pIn->numSamples > 1)
+    if ((Thickness(pIn->tileMode) > 1) && (pIn->numSamples > 1))
     {
         returnCode = ADDR_INVALIDPARAMS;
     }
 
     if (returnCode == ADDR_OK)
     {
         // Get a local copy of input structure and only reference pIn for unadjusted values
         ADDR_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;
         ADDR_TILEINFO tileInfoNull = {0};
 
@@ -195,21 +201,21 @@ ADDR_E_RETURNCODE AddrLib1::ComputeSurfaceInfo(
         {
             // If the original input has a valid ADDR_TILEINFO pointer then copy its contents.
             // Otherwise the default 0's in tileInfoNull are used.
             if (pIn->pTileInfo)
             {
                 tileInfoNull = *pIn->pTileInfo;
             }
             localIn.pTileInfo  = &tileInfoNull;
         }
 
-        localIn.numSamples = pIn->numSamples == 0 ? 1 : pIn->numSamples;
+        localIn.numSamples = (pIn->numSamples == 0) ? 1 : pIn->numSamples;
 
         // Do mipmap check first
         // If format is BCn, pre-pad dimension to power-of-two according to HWL
         ComputeMipLevel(&localIn);
 
         if (m_configFlags.checkLast2DLevel)
         {
             // Save this level's original height in pixels
             pOut->height = pIn->height;
         }
@@ -317,29 +323,37 @@ ADDR_E_RETURNCODE AddrLib1::ComputeSurfaceInfo(
                 {
                     ADDR_ASSERT(!IsMacroTiled(localIn.tileMode));
                 }
 
                 pOut->macroModeIndex = macroModeIndex;
             }
         }
 
         if (returnCode == ADDR_OK)
         {
-            // HWL layer may override tile mode if necessary
-            HwlOverrideTileMode(&localIn);
+            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;
+                AddrTileMode tileMode = localIn.tileMode;
 
-            // Optimize tile mode if possible
-            if (OptimizeTileMode(&localIn, &tileMode))
-            {
-                localIn.tileMode = tileMode;
+                // Optimize tile mode if possible
+                if (OptimizeTileMode(&localIn, &tileMode))
+                {
+                    localIn.tileMode = tileMode;
+                }
             }
         }
 
         // Call main function to compute surface info
         if (returnCode == ADDR_OK)
         {
             returnCode = HwlComputeSurfaceInfo(&localIn, pOut);
         }
 
         if (returnCode == ADDR_OK)
diff --git a/src/amd/addrlib/core/addrlib1.h b/src/amd/addrlib/core/addrlib1.h
index 6ca5826..99e8a9a 100644
--- a/src/amd/addrlib/core/addrlib1.h
+++ b/src/amd/addrlib/core/addrlib1.h
@@ -344,20 +344,25 @@ protected:
 
     /// Pure Virtual function for Hwl checking degrade for base level
     virtual BOOL_32 HwlDegradeBaseLevel(
         const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const = 0;
 
     virtual VOID HwlOverrideTileMode(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,
         UINT_32* pPitch, UINT_32 pitchAlign, UINT_32* pHeight, UINT_32 heightAlign,
         UINT_32* pSlices, UINT_32 sliceAlign) const;
 
     virtual VOID HwlPadDimensions(
         AddrTileMode tileMode, UINT_32 bpp, ADDR_SURFACE_FLAGS flags,
@@ -478,20 +483,23 @@ 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;
+
 private:
     // Disallow the copy constructor
     AddrLib1(const AddrLib1& a);
 
     // Disallow the assignment operator
     AddrLib1& operator=(const AddrLib1& a);
 
     UINT_32 ComputeCmaskBaseAlign(
         ADDR_CMASK_FLAGS flags, ADDR_TILEINFO*  pTileInfo) const;
 
@@ -500,17 +508,14 @@ private:
 
     //
     // CMASK/HTILE shared methods
     //
     VOID    ComputeTileDataWidthAndHeight(
         UINT_32 bpp, UINT_32 cacheBits, ADDR_TILEINFO* pTileInfo,
         UINT_32* pMacroWidth, UINT_32* pMacroHeight) const;
 
     UINT_32 ComputeXmaskCoordYFromPipe(
         UINT_32 pipe, UINT_32 x) const;
-
-    BOOL_32 OptimizeTileMode(
-        const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, AddrTileMode* pTileMode) const;
 };
 
 #endif
 
diff --git a/src/amd/addrlib/r800/ciaddrlib.cpp b/src/amd/addrlib/r800/ciaddrlib.cpp
index f88741e..15aff16 100644
--- a/src/amd/addrlib/r800/ciaddrlib.cpp
+++ b/src/amd/addrlib/r800/ciaddrlib.cpp
@@ -1017,20 +1017,116 @@ VOID CiAddrLib::HwlOverrideTileMode(
 
     if (tileMode != pInOut->tileMode)
     {
         pInOut->tileMode = tileMode;
         pInOut->tileType = tileType;
     }
 }
 
 /**
 ***************************************************************************************************
+*   CiAddrLib::HwlSelectTileMode
+*
+*   @brief
+*       Select tile modes.
+*
+*   @return
+*       N/A
+*
+***************************************************************************************************
+*/
+VOID CiAddrLib::HwlSelectTileMode(
+    ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut     ///< [in/out] input output structure
+    ) const
+{
+    AddrTileMode tileMode;
+    AddrTileType tileType;
+
+    if (pInOut->flags.rotateDisplay)
+    {
+        tileMode = ADDR_TM_2D_TILED_THIN1;
+        tileType = ADDR_ROTATED;
+    }
+    else if (pInOut->flags.volume)
+    {
+        BOOL_32 bThin = (m_settings.isBonaire == TRUE) ||
+                        ((m_allowNonDispThickModes == TRUE) && (pInOut->flags.color == TRUE));
+
+        if (pInOut->numSlices >= 8)
+        {
+            tileMode = ADDR_TM_2D_TILED_XTHICK;
+            tileType = (bThin == TRUE) ? ADDR_NON_DISPLAYABLE : ADDR_THICK;
+        }
+        else if (pInOut->numSlices >= 4)
+        {
+            tileMode = ADDR_TM_2D_TILED_THICK;
+            tileType = (bThin == TRUE) ? ADDR_NON_DISPLAYABLE : ADDR_THICK;
+        }
+        else
+        {
+            tileMode = ADDR_TM_2D_TILED_THIN1;
+            tileType = ADDR_NON_DISPLAYABLE;
+        }
+    }
+    else
+    {
+        tileMode = ADDR_TM_2D_TILED_THIN1;
+
+        if (pInOut->flags.depth || pInOut->flags.stencil)
+        {
+            tileType = ADDR_DEPTH_SAMPLE_ORDER;
+        }
+        else if ((pInOut->bpp <= 32) ||
+                 (pInOut->flags.display == TRUE) ||
+                 (pInOut->flags.overlay == TRUE))
+        {
+            tileType = ADDR_DISPLAYABLE;
+        }
+        else
+        {
+            tileType = ADDR_NON_DISPLAYABLE;
+        }
+    }
+
+    if (pInOut->flags.prt)
+    {
+        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;
+        }
+    }
+
+    pInOut->tileMode = tileMode;
+    pInOut->tileType = tileType;
+
+    if ((pInOut->flags.dccCompatible == FALSE) &&
+        (pInOut->flags.tcCompatible == FALSE))
+    {
+        pInOut->flags.opt4Space = TRUE;
+
+        // Optimize tile mode if possible
+        if (OptimizeTileMode(pInOut, &tileMode))
+        {
+            pInOut->tileMode = tileMode;
+        }
+    }
+
+    HwlOverrideTileMode(pInOut);
+}
+
+/**
+***************************************************************************************************
 *   CiAddrLib::HwlSetupTileInfo
 *
 *   @brief
 *       Setup default value of tile info for SI
 ***************************************************************************************************
 */
 VOID CiAddrLib::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 e959df3..12587cd 100644
--- a/src/amd/addrlib/r800/ciaddrlib.h
+++ b/src/amd/addrlib/r800/ciaddrlib.h
@@ -136,20 +136,22 @@ 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 HwlSelectTileMode(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/siaddrlib.cpp b/src/amd/addrlib/r800/siaddrlib.cpp
index 4822d77..30f9934 100644
--- a/src/amd/addrlib/r800/siaddrlib.cpp
+++ b/src/amd/addrlib/r800/siaddrlib.cpp
@@ -3192,20 +3192,96 @@ void SiAddrLib::HwlOverrideTileMode(
     if (tileMode != pInOut->tileMode)
     {
         pInOut->tileMode = tileMode;
 
         ADDR_ASSERT(pInOut->flags.prt == TRUE);
     }
 }
 
 /**
 ***************************************************************************************************
+*   SiAddrLib::HwlSelectTileMode
+*
+*   @brief
+*       Select tile modes.
+*
+*   @return
+*       N/A
+*
+***************************************************************************************************
+*/
+VOID SiAddrLib::HwlSelectTileMode(
+    ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut     ///< [in/out] input output structure
+    ) const
+{
+    AddrTileMode tileMode;
+    AddrTileType tileType;
+
+    if (pInOut->flags.volume)
+    {
+        if (pInOut->numSlices >= 8)
+        {
+            tileMode = ADDR_TM_2D_TILED_XTHICK;
+        }
+        else if (pInOut->numSlices >= 4)
+        {
+            tileMode = ADDR_TM_2D_TILED_THICK;
+        }
+        else
+        {
+            tileMode = ADDR_TM_2D_TILED_THIN1;
+        }
+        tileType = ADDR_NON_DISPLAYABLE;
+    }
+    else
+    {
+        tileMode = ADDR_TM_2D_TILED_THIN1;
+
+        if (pInOut->flags.depth || pInOut->flags.stencil)
+        {
+            tileType = ADDR_DEPTH_SAMPLE_ORDER;
+        }
+        else if ((pInOut->bpp <= 32) ||
+                 (pInOut->flags.display == TRUE) ||
+                 (pInOut->flags.overlay == TRUE))
+        {
+            tileType = ADDR_DISPLAYABLE;
+        }
+        else
+        {
+            tileType = ADDR_NON_DISPLAYABLE;
+        }
+    }
+
+    if (pInOut->flags.prt)
+    {
+        tileMode = ADDR_TM_2D_TILED_THIN1;
+        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;
+    }
+
+    HwlOverrideTileMode(pInOut);
+}
+
+/**
+***************************************************************************************************
 *   SiAddrLib::HwlGetMaxAlignments
 *
 *   @brief
 *       Gets maximum alignments
 *   @return
 *       ADDR_E_RETURNCODE
 ***************************************************************************************************
 */
 ADDR_E_RETURNCODE SiAddrLib::HwlGetMaxAlignments(
     ADDR_GET_MAX_ALINGMENTS_OUTPUT* pOut    ///< [out] output structure
diff --git a/src/amd/addrlib/r800/siaddrlib.h b/src/amd/addrlib/r800/siaddrlib.h
index 814cd00..7619cfe 100644
--- a/src/amd/addrlib/r800/siaddrlib.h
+++ b/src/amd/addrlib/r800/siaddrlib.h
@@ -176,20 +176,22 @@ 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 HwlSelectTileMode(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