[Mesa-dev] [PATCH 006/140] amdgpu/addrlib: Add a flag "tcCompatible" to surface info output structure.

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


From: Carlos Xiong <clever.xiong at amd.com>

Even if surface info input flag "tcComaptible" is enabled, tc
compatible may be not supported if tile split happens for depth
surfaces. Add a new flag in output structure to notify client to
disable tc compatible in this case.
---
 src/amd/addrlib/addrinterface.h    | 13 +++++++---
 src/amd/addrlib/core/addrlib.cpp   |  1 +
 src/amd/addrlib/r800/ciaddrlib.cpp | 51 +++++++++++++++++++++++++++++---------
 3 files changed, 50 insertions(+), 15 deletions(-)

diff --git a/src/amd/addrlib/addrinterface.h b/src/amd/addrlib/addrinterface.h
index d9a2b82..d05c6ef 100644
--- a/src/amd/addrlib/addrinterface.h
+++ b/src/amd/addrlib/addrinterface.h
@@ -527,23 +527,30 @@ typedef struct _ADDR_COMPUTE_SURFACE_INFO_OUTPUT
     UINT_32         sliceTileMax;   ///< SLICE_TILE_MAX value for h/w register
 
     UINT_32         numSamples;     ///< Pass the effective numSamples processed in this call
 
     /// r800 and later HWL parameters
     ADDR_TILEINFO*  pTileInfo;      ///< Tile parameters used. Filled in if 0 on input
     AddrTileType    tileType;       ///< Micro tiling type, only valid when tileIndex != -1
     INT_32          tileIndex;      ///< Tile index, MAY be "downgraded"
 
     INT_32          macroModeIndex; ///< Index in macro tile mode table if there is one (CI)
-    /// Special information to work around SI mipmap swizzle bug UBTS #317508
-    BOOL_32         last2DLevel;    ///< TRUE if this is the last 2D(3D) tiled
-                                    ///< Only meaningful when create flag checkLast2DLevel is set
+    /// Output flags
+    struct
+    {
+        /// Special information to work around SI mipmap swizzle bug UBTS #317508
+        UINT_32     last2DLevel  : 1;  ///< TRUE if this is the last 2D(3D) tiled
+                                       ///< Only meaningful when create flag checkLast2DLevel is set
+        UINT_32     tcCompatible : 1;  ///< If the surface can be shader compatible
+        UINT_32     reserved     :30; ///< Reserved bits
+    };
+
     /// Stereo info
     ADDR_QBSTEREOINFO*  pStereoInfo;///< Stereo information, needed when .qbStereo flag is TRUE
 } ADDR_COMPUTE_SURFACE_INFO_OUTPUT;
 
 /**
 ***************************************************************************************************
 *   AddrComputeSurfaceInfo
 *
 *   @brief
 *       Compute surface width/height/depth/alignments and suitable tiling mode
diff --git a/src/amd/addrlib/core/addrlib.cpp b/src/amd/addrlib/core/addrlib.cpp
index b829eec..8cf4a24 100644
--- a/src/amd/addrlib/core/addrlib.cpp
+++ b/src/amd/addrlib/core/addrlib.cpp
@@ -442,20 +442,21 @@ ADDR_E_RETURNCODE AddrLib::ComputeSurfaceInfo(
         }
 
         UINT_32 expandX = 1;
         UINT_32 expandY = 1;
         AddrElemMode elemMode;
 
         // Save outputs that may not go through HWL
         pOut->pixelBits = localIn.bpp;
         pOut->numSamples = localIn.numSamples;
         pOut->last2DLevel = FALSE;
+        pOut->tcCompatible = FALSE;
 
 #if !ALT_TEST
         if (localIn.numSamples > 1)
         {
             ADDR_ASSERT(localIn.mipLevel == 0);
         }
 #endif
 
         if (localIn.format != ADDR_FMT_INVALID) // Set format to INVALID will skip this conversion
         {
diff --git a/src/amd/addrlib/r800/ciaddrlib.cpp b/src/amd/addrlib/r800/ciaddrlib.cpp
index 5f8a1fe..1024ff2 100644
--- a/src/amd/addrlib/r800/ciaddrlib.cpp
+++ b/src/amd/addrlib/r800/ciaddrlib.cpp
@@ -476,21 +476,22 @@ INT_32 CiAddrLib::HwlPostCheckTileIndex(
                 if (macroTiled)
                 {
                     // macro tile modes need all to match
                     if ((pInfo->pipeConfig == m_tileTable[index].info.pipeConfig) &&
                         (mode == m_tileTable[index].mode) &&
                         (type == m_tileTable[index].type))
                     {
                         // tileSplitBytes stored in m_tileTable is only valid for depth entries
                         if (type == ADDR_DEPTH_SAMPLE_ORDER)
                         {
-                            if (pInfo->tileSplitBytes == m_tileTable[index].info.tileSplitBytes)
+                            if (Min(m_tileTable[index].info.tileSplitBytes,
+                                    m_rowSize) == pInfo->tileSplitBytes)
                             {
                                 break;
                             }
                         }
                         else // other entries are determined by other 3 fields
                         {
                             break;
                         }
                     }
                 }
@@ -614,20 +615,23 @@ ADDR_E_RETURNCODE CiAddrLib::HwlComputeSurfaceInfo(
     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,    ///< [in] input structure
     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [out] output structure
     ) const
 {
     // If tileIndex is invalid, force macroModeIndex to be invalid, too
     if (pIn->tileIndex == TileIndexInvalid)
     {
         pOut->macroModeIndex = TileIndexInvalid;
     }
 
+    // Pass tcCompatible flag from input to output; and turn off it if tile split occurs
+    pOut->tcCompatible = pIn->flags.tcCompatible;
+
     ADDR_E_RETURNCODE retCode = SiAddrLib::HwlComputeSurfaceInfo(pIn,pOut);
 
     if (pOut->macroModeIndex == TileIndexNoMacroIndex)
     {
         pOut->macroModeIndex = TileIndexInvalid;
     }
 
     return retCode;
 }
 
@@ -1003,25 +1007,32 @@ VOID CiAddrLib::HwlSetupTileInfo(
         {
             inTileType = ADDR_DEPTH_SAMPLE_ORDER;
         }
     }
 
     if (IsTileInfoAllZero(pTileInfo))
     {
         // See table entries 0-4
         if (flags.depth || flags.stencil)
         {
-            if (flags.depth && (flags.nonSplit || flags.tcCompatible))
+            // tileSize = thickness * bpp * numSamples * 8 * 8 / 8
+            UINT_32 tileSize = thickness * bpp * numSamples * 8;
+
+            // Turn off tc compatible if row_size is smaller than tile size (tile split occurs).
+            if (m_rowSize < tileSize)
             {
-                // tileSize = bpp * numSamples * 8 * 8 / 8
-                UINT_32 tileSize = bpp * numSamples * 8;
+                flags.tcCompatible = FALSE;
+                pOut->tcCompatible = FALSE;
+            }
 
+            if (flags.depth && (flags.nonSplit || flags.tcCompatible))
+            {
                 // Texure readable depth surface should not be split
                 switch (tileSize)
                 {
                     case 128:
                         index = 1;
                         break;
                     case 256:
                         index = 2;
                         break;
                     case 512:
@@ -1208,20 +1219,43 @@ VOID CiAddrLib::HwlSetupTileInfo(
         pOut->tileIndex = TileIndexLinearGeneral;
 
         // Copy linear-aligned entry??
         *pTileInfo = m_tileTable[8].info;
     }
     else if (tileMode == ADDR_TM_LINEAR_ALIGNED)
     {
         pOut->tileIndex = 8;
         *pTileInfo = m_tileTable[8].info;
     }
+
+    // Turn off tcCompatible for color surface if tileSplit happens. Depth/stencil is
+    // handled at tileIndex selecting time.
+    if (pOut->tcCompatible && (inTileType != ADDR_DEPTH_SAMPLE_ORDER))
+    {
+        if (IsMacroTiled(tileMode))
+        {
+            // Non-depth entries store a split factor
+            UINT_32 sampleSplit = m_tileTable[pOut->tileIndex].info.tileSplitBytes;
+            UINT_32 tileBytes1x = BITS_TO_BYTES(bpp * MicroTilePixels * thickness);
+            UINT_32 colorTileSplit = Max(256u, sampleSplit * tileBytes1x);
+
+            if (m_rowSize < colorTileSplit)
+            {
+                pOut->tcCompatible = FALSE;
+            }
+        }
+        else
+        {
+            // Client should not enable tc compatible for linear and 1D tile modes.
+            pOut->tcCompatible = FALSE;
+        }
+    }
 }
 
 /**
 ***************************************************************************************************
 *   CiAddrLib::ReadGbTileMode
 *
 *   @brief
 *       Convert GB_TILE_MODE HW value to ADDR_TILE_CONFIG.
 *   @return
 *       NA.
@@ -1510,28 +1544,21 @@ INT_32 CiAddrLib::HwlComputeMacroModeIndex(
             macroModeIndex += PrtMacroModeOffset;
             *pTileInfo = m_macroTileTable[macroModeIndex];
         }
         else
         {
             *pTileInfo = m_macroTileTable[macroModeIndex];
         }
 
         pTileInfo->pipeConfig = m_tileTable[tileIndex].info.pipeConfig;
 
-        if (m_tileTable[tileIndex].type != ADDR_DEPTH_SAMPLE_ORDER)
-        {
-            pTileInfo->tileSplitBytes = tileSplitC;
-        }
-        else
-        {
-            pTileInfo->tileSplitBytes = m_tileTable[tileIndex].info.tileSplitBytes;
-        }
+        pTileInfo->tileSplitBytes = tileSplitC;
     }
 
     if (NULL != pTileMode)
     {
         *pTileMode = tileMode;
     }
 
     if (NULL != pTileType)
     {
         *pTileType = tileType;
-- 
2.7.4



More information about the mesa-dev mailing list