amd/addrlib: update to latest version
[mesa.git] / src / amd / addrlib / core / addrlib1.cpp
index 34e286e4dd3ff5c588e5bed9678fbe660f763abd..c796a63436c71969ddcdb58e6086ffe288b1d466 100644 (file)
@@ -259,10 +259,9 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(
             // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
             // but we use this flag to skip RestoreSurfaceInfo below
 
-            if ((elemMode == ADDR_EXPANDED) &&
-                (expandX > 1))
+            if ((elemMode == ADDR_EXPANDED) && (expandX > 1))
             {
-                ADDR_ASSERT(localIn.tileMode == ADDR_TM_LINEAR_ALIGNED || localIn.height == 1);
+                ADDR_ASSERT(IsLinear(localIn.tileMode));
             }
 
             GetElemLib()->AdjustSurfaceInfo(elemMode,
@@ -336,6 +335,8 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(
 
         if (returnCode == ADDR_OK)
         {
+            localIn.flags.dccPipeWorkaround = localIn.flags.dccCompatible;
+
             if (localIn.tileMode == ADDR_TM_UNKNOWN)
             {
                 // HWL layer may override tile mode if necessary
@@ -346,13 +347,8 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(
                 // 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);
             }
         }
 
@@ -381,21 +377,17 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(
             if (localIn.format != ADDR_FMT_INVALID)
             {
                 //
-                // 96 bits surface of level 1+ requires element pitch of 32 bits instead
-                // In hwl function we skip multiplication of 3 then we should skip division of 3
-                // We keep pitch that represents 32 bit element instead of 96 bits since we
-                // will get an odd number if divided by 3.
+                // Note: For 96 bit surface, the pixelPitch returned might be an odd number, but it
+                // is okay to program texture pitch as HW's mip calculator would multiply 3 first,
+                // then do the appropriate paddings (linear alignment requirement and possible the
+                // nearest power-of-two for mipmaps), which results in the original pitch.
                 //
-                if (!((expandX == 3) && (localIn.mipLevel > 0)))
-                {
-
-                    GetElemLib()->RestoreSurfaceInfo(elemMode,
-                                                     expandX,
-                                                     expandY,
-                                                     &localIn.bpp,
-                                                     &pOut->pixelPitch,
-                                                     &pOut->pixelHeight);
-                }
+                GetElemLib()->RestoreSurfaceInfo(elemMode,
+                                                 expandX,
+                                                 expandY,
+                                                 &localIn.bpp,
+                                                 &pOut->pixelPitch,
+                                                 &pOut->pixelHeight);
             }
 
             if (localIn.flags.qbStereo)
@@ -1289,21 +1281,55 @@ ADDR_E_RETURNCODE Lib::ComputeHtileInfo(
 
         if (returnCode == ADDR_OK)
         {
-            pOut->bpp = ComputeHtileInfo(pIn->flags,
-                                         pIn->pitch,
-                                         pIn->height,
-                                         pIn->numSlices,
-                                         pIn->isLinear,
-                                         isWidth8,
-                                         isHeight8,
-                                         pIn->pTileInfo,
-                                         &pOut->pitch,
-                                         &pOut->height,
-                                         &pOut->htileBytes,
-                                         &pOut->macroWidth,
-                                         &pOut->macroHeight,
-                                         &pOut->sliceSize,
-                                         &pOut->baseAlign);
+            if (pIn->flags.tcCompatible)
+            {
+                const UINT_32 sliceSize = pIn->pitch * pIn->height * 4 / (8 * 8);
+                const UINT_32 align     = HwlGetPipes(pIn->pTileInfo) * pIn->pTileInfo->banks * m_pipeInterleaveBytes;
+
+                if (pIn->numSlices > 1)
+                {
+                    const UINT_32 surfBytes = (sliceSize * pIn->numSlices);
+
+                    pOut->sliceSize        = sliceSize;
+                    pOut->htileBytes       = pIn->flags.skipTcCompatSizeAlign ?
+                                             surfBytes : PowTwoAlign(surfBytes, align);
+                    pOut->sliceInterleaved = ((sliceSize % align) != 0) ? TRUE : FALSE;
+                }
+                else
+                {
+                    pOut->sliceSize        = pIn->flags.skipTcCompatSizeAlign ?
+                                             sliceSize : PowTwoAlign(sliceSize, align);
+                    pOut->htileBytes       = pOut->sliceSize;
+                    pOut->sliceInterleaved = FALSE;
+                }
+
+                pOut->nextMipLevelCompressible = ((sliceSize % align) == 0) ? TRUE : FALSE;
+
+                pOut->pitch       = pIn->pitch;
+                pOut->height      = pIn->height;
+                pOut->baseAlign   = align;
+                pOut->macroWidth  = 0;
+                pOut->macroHeight = 0;
+                pOut->bpp         = 32;
+            }
+            else
+            {
+                pOut->bpp = ComputeHtileInfo(pIn->flags,
+                                             pIn->pitch,
+                                             pIn->height,
+                                             pIn->numSlices,
+                                             pIn->isLinear,
+                                             isWidth8,
+                                             isHeight8,
+                                             pIn->pTileInfo,
+                                             &pOut->pitch,
+                                             &pOut->height,
+                                             &pOut->htileBytes,
+                                             &pOut->macroWidth,
+                                             &pOut->macroHeight,
+                                             &pOut->sliceSize,
+                                             &pOut->baseAlign);
+            }
         }
     }
 
@@ -2154,6 +2180,8 @@ VOID Lib::HwlComputeXmaskCoordFromAddr(
 {
     UINT_32 pipe;
     UINT_32 numPipes;
+    UINT_32 numGroupBits;
+    (void)numGroupBits;
     UINT_32 numPipeBits;
     UINT_32 macroTilePitch;
     UINT_32 macroTileHeight;
@@ -2196,6 +2224,7 @@ VOID Lib::HwlComputeXmaskCoordFromAddr(
     //
     // Compute the number of group and pipe bits.
     //
+    numGroupBits = Log2(m_pipeInterleaveBytes);
     numPipeBits  = Log2(numPipes);
 
     UINT_32 groupBits = 8 * m_pipeInterleaveBytes;
@@ -3496,6 +3525,10 @@ VOID Lib::ComputeMipLevel(
     ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in,out] Input structure
     ) const
 {
+    // Check if HWL has handled
+    BOOL_32 hwlHandled = FALSE;
+    (void)hwlHandled;
+
     if (ElemLib::IsBlockCompressed(pIn->format))
     {
         if (pIn->mipLevel == 0)
@@ -3509,7 +3542,46 @@ VOID Lib::ComputeMipLevel(
         }
     }
 
-    HwlComputeMipLevel(pIn);
+    hwlHandled = 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;
 }
 
 /**
@@ -3519,67 +3591,158 @@ VOID Lib::ComputeMipLevel(
 *   @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);
+
+    BOOL_32 convertToPrt = FALSE;
 
     // 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)             &&
         (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 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.display == FALSE) &&
+                (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) && (pInOut->flags.tcCompatible == FALSE))
+                {
+                    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))
                 {
-                    ADDR_COMPUTE_SURFACE_INFO_INPUT input = *pIn;
-                    input.tileMode = tileMode;
-                    if (HwlDegradeBaseLevel(&input))
+                    UINT_32 macroSize = PowTwoAlign(width, macroWidthAlign) *
+                                        PowTwoAlign(height, macroHeightAlign);
+                    UINT_32 microSize = PowTwoAlign(width, MicroTileWidth) *
+                                        PowTwoAlign(height, MicroTileHeight);
+
+                    if (macroSize > microSize)
                     {
-                        tileMode = ADDR_TM_1D_TILED_THICK;
+                        tileMode = (thickness == 1) ?
+                                   ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
+                    }
+                }
+
+                if ((pInOut->maxBaseAlign != 0) &&
+                    (IsMacroTiled(tileMode) == TRUE))
+                {
+                    if (macroSizeAlign > pInOut->maxBaseAlign)
+                    {
+                        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)
+    if (convertToPrt)
     {
-        *pTileMode = tileMode;
+        if ((pInOut->flags.matchStencilTileCfg == TRUE) && (pInOut->numSamples <= 1))
+        {
+            pInOut->tileMode = ADDR_TM_1D_TILED_THIN1;
+        }
+        else
+        {
+            HwlSetPrtTileMode(pInOut);
+        }
     }
-    return optimized;
+    else if (tileMode != pInOut->tileMode)
+    {
+        pInOut->tileMode = tileMode;
+    }
+
+    HwlOptimizeTileMode(pInOut);
 }
 
 /**
@@ -3739,41 +3902,33 @@ UINT_32 Lib::HwlGetPipes(
 *   @brief
 *       Get quad buffer stereo information
 *   @return
-*       TRUE if no error
+*       N/A
 ****************************************************************************************************
 */
-BOOL_32 Lib::ComputeQbStereoInfo(
+VOID Lib::ComputeQbStereoInfo(
     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [in,out] updated pOut+pStereoInfo
     ) const
 {
-    BOOL_32 success = FALSE;
-
-    if (pOut->pStereoInfo)
-    {
-        ADDR_ASSERT(pOut->bpp >= 8);
-        ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0);
+    ADDR_ASSERT(pOut->bpp >= 8);
+    ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0);
 
-        // Save original height
-        pOut->pStereoInfo->eyeHeight = pOut->height;
+    // Save original height
+    pOut->pStereoInfo->eyeHeight = pOut->height;
 
-        // Right offset
-        pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize);
+    // Right offset
+    pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize);
 
-        pOut->pStereoInfo->rightSwizzle = HwlComputeQbStereoRightSwizzle(pOut);
-        // Double height
-        pOut->height <<= 1;
-        pOut->pixelHeight <<= 1;
+    pOut->pStereoInfo->rightSwizzle = HwlComputeQbStereoRightSwizzle(pOut);
+    // Double height
+    pOut->height <<= 1;
+    pOut->pixelHeight <<= 1;
 
-        // Double size
-        pOut->surfSize <<= 1;
+    // Double size
+    pOut->surfSize <<= 1;
 
-        // Right start address meets the base align since it is guaranteed by AddrLib1
-
-        // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo.
-        success = TRUE;
-    }
+    // Right start address meets the base align since it is guaranteed by AddrLib1
 
-    return success;
+    // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo.
 }