amd: update addrlib
authorMarek Olšák <marek.olsak@amd.com>
Sun, 19 Mar 2023 17:34:44 +0000 (13:34 -0400)
committerMarge Bot <emma+marge@anholt.net>
Wed, 29 Mar 2023 20:36:09 +0000 (20:36 +0000)
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22084>

18 files changed:
src/amd/addrlib/inc/addrinterface.h
src/amd/addrlib/src/addrinterface.cpp
src/amd/addrlib/src/amdgpu_asic_addr.h
src/amd/addrlib/src/core/addrcommon.h
src/amd/addrlib/src/core/addrlib.cpp
src/amd/addrlib/src/core/addrlib.h
src/amd/addrlib/src/core/addrlib1.cpp
src/amd/addrlib/src/core/addrlib2.cpp
src/amd/addrlib/src/core/addrlib2.h
src/amd/addrlib/src/gfx10/gfx10SwizzlePattern.h
src/amd/addrlib/src/gfx10/gfx10addrlib.cpp
src/amd/addrlib/src/gfx10/gfx10addrlib.h
src/amd/addrlib/src/gfx11/gfx11addrlib.cpp
src/amd/addrlib/src/gfx11/gfx11addrlib.h
src/amd/addrlib/src/gfx9/gfx9addrlib.cpp
src/amd/addrlib/src/r800/egbaddrlib.cpp
src/amd/addrlib/src/r800/siaddrlib.cpp
src/amd/common/ac_gpu_info.c

index 11e9e8c..f5abdaf 100644 (file)
@@ -40,8 +40,8 @@ extern "C"
 {
 #endif
 
-#define ADDRLIB_VERSION_MAJOR 6
-#define ADDRLIB_VERSION_MINOR 2
+#define ADDRLIB_VERSION_MAJOR 8
+#define ADDRLIB_VERSION_MINOR 7
 #define ADDRLIB_VERSION ((ADDRLIB_VERSION_MAJOR << 16) | ADDRLIB_VERSION_MINOR)
 
 /// Virtually all interface functions need ADDR_HANDLE as first parameter
@@ -127,7 +127,7 @@ typedef union _ADDR_CHANNEL_SETTING
     struct
     {
         UINT_8 valid   : 1;    ///< Indicate whehter this channel setting is valid
-        UINT_8 channel : 2;    ///< 0 for x channel, 1 for y channel, 2 for z channel
+        UINT_8 channel : 2;    ///< 0 for x channel, 1 for y channel, 2 for z channel, 3 for MSAA sample index
         UINT_8 index   : 5;    ///< Channel index
     };
     UINT_8 value;              ///< Value
@@ -161,18 +161,29 @@ typedef union _ADDR_EQUATION_KEY
 * @brief address equation structure
 ****************************************************************************************************
 */
-#define ADDR_MAX_EQUATION_BIT 20u
+#define ADDR_MAX_LEGACY_EQUATION_COMP 3u
+#define ADDR_MAX_EQUATION_COMP        5u
+#define ADDR_MAX_EQUATION_BIT         20u
 
 // Invalid equation index
 #define ADDR_INVALID_EQUATION_INDEX 0xFFFFFFFF
 
 typedef struct _ADDR_EQUATION
 {
-    ADDR_CHANNEL_SETTING addr[ADDR_MAX_EQUATION_BIT];  ///< addr setting
-                                                       ///< each bit is result of addr ^ xor ^ xor2
-    ADDR_CHANNEL_SETTING xor1[ADDR_MAX_EQUATION_BIT];  ///< xor setting
-    ADDR_CHANNEL_SETTING xor2[ADDR_MAX_EQUATION_BIT];  ///< xor2 setting
+    union
+    {
+        struct {
+            ADDR_CHANNEL_SETTING addr[ADDR_MAX_EQUATION_BIT];  ///< addr setting
+            ADDR_CHANNEL_SETTING xor1[ADDR_MAX_EQUATION_BIT];  ///< xor setting
+            ADDR_CHANNEL_SETTING xor2[ADDR_MAX_EQUATION_BIT];  ///< xor2 setting
+            ADDR_CHANNEL_SETTING xor3[ADDR_MAX_EQUATION_BIT];  ///< xor3 setting
+            ADDR_CHANNEL_SETTING xor4[ADDR_MAX_EQUATION_BIT];  ///< xor4 setting
+        };
+        ///< Components showing the sources of each bit; each bit is result of addr ^ xor ^ xor2...
+        ADDR_CHANNEL_SETTING comps[ADDR_MAX_EQUATION_COMP][ADDR_MAX_EQUATION_BIT];
+    };
     UINT_32              numBits;                      ///< The number of bits in equation
+    UINT_32              numBitComponents;             ///< The max number of channels contributing to a bit
     BOOL_32              stackedDepthSlices;           ///< TRUE if depth slices are treated as being
                                                        ///< stacked vertically prior to swizzling
 } ADDR_EQUATION;
@@ -1728,6 +1739,30 @@ typedef enum _AddrSwizzleGenOption
 
 /**
 ****************************************************************************************************
+*   AddrBlockType
+*
+*   @brief
+*       Macro define resource block type
+****************************************************************************************************
+*/
+typedef enum
+{
+    AddrBlockLinear = 0, // Resource uses linear swizzle mode
+    AddrBlockMicro = 1, // Resource uses 256B block
+    AddrBlockThin4KB = 2, // Resource uses thin 4KB block
+    AddrBlockThick4KB = 3, // Resource uses thick 4KB block
+    AddrBlockThin64KB = 4, // Resource uses thin 64KB block
+    AddrBlockThick64KB = 5, // Resource uses thick 64KB block
+    AddrBlockThinVar = 6, // Resource uses thin var block
+    AddrBlockThickVar = 7, // Resource uses thick var block
+    AddrBlockMaxTiledType,
+
+    AddrBlockThin256KB = AddrBlockThinVar,
+    AddrBlockThick256KB = AddrBlockThickVar,
+} AddrBlockType;
+
+/**
+****************************************************************************************************
 *   AddrSwizzleOption
 *
 *   @brief
@@ -2411,7 +2446,8 @@ typedef union _ADDR2_SURFACE_FLAGS
         UINT_32 metaRbUnaligned   :  1; ///< This resource has rb unaligned metadata
         UINT_32 metaPipeUnaligned :  1; ///< This resource has pipe unaligned metadata
         UINT_32 view3dAs2dArray   :  1; ///< This resource is a 3D resource viewed as 2D array
-        UINT_32 reserved          : 13; ///< Reserved bits
+        UINT_32 allowExtEquation  :  1; ///< If unset, only legacy DX eqs are allowed (2 XORs)
+        UINT_32 reserved          : 12; ///< Reserved bits
     };
 
     UINT_32 value;
@@ -2588,7 +2624,7 @@ typedef struct _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
 {
     UINT_32    size;             ///< Size of this structure in bytes
 
-    UINT_64    addr;             ///< Byte address
+    UINT_64    addr;             ///< Byte offset from the image starting address
     UINT_32    bitPosition;      ///< Bit position within surfaceAddr, 0-7.
                                  ///  For surface bpp < 8, e.g. FMT_1.
     UINT_32    prtBlockIndex;    ///< Index of a PRT tile (64K block)
@@ -3929,6 +3965,20 @@ ADDR_E_RETURNCODE ADDR_API Addr2GetPreferredSurfaceSetting(
 
 /**
 ****************************************************************************************************
+*   Addr2GetPossibleSwizzleModes
+*
+*   @brief
+*       Returns a list of swizzle modes that are valid from the hardware's perspective for the
+*       client to choose from
+****************************************************************************************************
+*/
+ADDR_E_RETURNCODE ADDR_API Addr2GetPossibleSwizzleModes(
+    ADDR_HANDLE                                   hLib,
+    const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
+    ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut);
+
+/**
+****************************************************************************************************
 *   Addr2IsValidDisplaySwizzleMode
 *
 *   @brief
@@ -3941,6 +3991,65 @@ ADDR_E_RETURNCODE ADDR_API Addr2IsValidDisplaySwizzleMode(
     UINT_32         bpp,
     BOOL_32         *pResult);
 
+/**
+****************************************************************************************************
+*   Addr2GetAllowedBlockSet
+*
+*   @brief
+*       Returns the set of allowed block sizes given the allowed swizzle modes and resource type
+****************************************************************************************************
+*/
+ADDR_E_RETURNCODE ADDR_API Addr2GetAllowedBlockSet(
+    ADDR_HANDLE      hLib,
+    ADDR2_SWMODE_SET allowedSwModeSet,
+    AddrResourceType rsrcType,
+    ADDR2_BLOCK_SET* pAllowedBlockSet);
+
+/**
+****************************************************************************************************
+*   Addr2GetAllowedSwSet
+*
+*   @brief
+*       Returns the set of allowed swizzle types given the allowed swizzle modes
+****************************************************************************************************
+*/
+ADDR_E_RETURNCODE ADDR_API Addr2GetAllowedSwSet(
+    ADDR_HANDLE       hLib,
+    ADDR2_SWMODE_SET  allowedSwModeSet,
+    ADDR2_SWTYPE_SET* pAllowedSwSet);
+
+/**
+****************************************************************************************************
+*   Addr2IsBlockTypeAvailable
+*
+*   @brief
+*       Determine whether a block type is allowed in a given blockSet
+****************************************************************************************************
+*/
+BOOL_32 Addr2IsBlockTypeAvailable(ADDR2_BLOCK_SET blockSet, AddrBlockType blockType);
+
+/**
+****************************************************************************************************
+*   Addr2BlockTypeWithinMemoryBudget
+*
+*   @brief
+*       Determine whether a new block type is acceptable based on memory waste ratio. Will favor
+*       larger block types.
+****************************************************************************************************
+*/
+BOOL_32 Addr2BlockTypeWithinMemoryBudget(
+    UINT_64 minSize,
+    UINT_64 newBlockTypeSize,
+    UINT_32 ratioLow,
+    UINT_32 ratioHi,
+#if defined(__cplusplus)
+    DOUBLE  memoryBudget = 0.0f,
+    BOOL_32 newBlockTypeBigger = TRUE);
+#else
+    DOUBLE  memoryBudget,
+    BOOL_32 newBlockTypeBigger);
+#endif
+
 #if defined(__cplusplus)
 }
 #endif
index 7f85a4b..b9d1263 100644 (file)
@@ -1797,3 +1797,174 @@ ADDR_E_RETURNCODE ADDR_API Addr2IsValidDisplaySwizzleMode(
 
     return returnCode;
 }
+
+/**
+****************************************************************************************************
+*   Addr2GetPossibleSwizzleModes
+*
+*   @brief
+*       Returns a list of swizzle modes that are valid from the hardware's perspective for the
+*       client to choose from
+****************************************************************************************************
+*/
+ADDR_E_RETURNCODE ADDR_API Addr2GetPossibleSwizzleModes(
+    ADDR_HANDLE                                   hLib, ///< handle of addrlib
+    const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,  ///< [in] input
+    ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) ///< [out] output
+{
+    ADDR_E_RETURNCODE returnCode;
+
+    V2::Lib* pLib = V2::Lib::GetLib(hLib);
+
+    if (pLib != NULL)
+    {
+        returnCode = pLib->GetPossibleSwizzleModes(pIn, pOut);
+    }
+    else
+    {
+        returnCode = ADDR_ERROR;
+    }
+
+    return returnCode;
+}
+/**
+****************************************************************************************************
+*   Addr2GetAllowedBlockSet
+*
+*   @brief
+*       Returns the set of allowed block sizes given the allowed swizzle modes and resource type
+****************************************************************************************************
+*/
+ADDR_E_RETURNCODE ADDR_API Addr2GetAllowedBlockSet(
+    ADDR_HANDLE      hLib,              ///< handle of addrlib
+    ADDR2_SWMODE_SET allowedSwModeSet,  ///< [in] allowed swizzle modes
+    AddrResourceType rsrcType,          ///< [in] resource type
+    ADDR2_BLOCK_SET* pAllowedBlockSet)  ///< [out] allowed block sizes
+{
+    ADDR_E_RETURNCODE returnCode;
+
+    V2::Lib* pLib = V2::Lib::GetLib(hLib);
+
+    if (pLib != NULL)
+    {
+        returnCode = pLib->GetAllowedBlockSet(allowedSwModeSet, rsrcType, pAllowedBlockSet);
+    }
+    else
+    {
+        returnCode = ADDR_ERROR;
+    }
+
+    return returnCode;
+}
+
+/**
+****************************************************************************************************
+*   Addr2GetAllowedSwSet
+*
+*   @brief
+*       Returns the set of allowed swizzle types given the allowed swizzle modes
+****************************************************************************************************
+*/
+ADDR_E_RETURNCODE ADDR_API Addr2GetAllowedSwSet(
+    ADDR_HANDLE       hLib,              ///< handle of addrlib
+    ADDR2_SWMODE_SET  allowedSwModeSet,  ///< [in] allowed swizzle modes
+    ADDR2_SWTYPE_SET* pAllowedSwSet)     ///< [out] allowed swizzle types
+{
+    ADDR_E_RETURNCODE returnCode;
+
+    V2::Lib* pLib = V2::Lib::GetLib(hLib);
+
+    if (pLib != NULL)
+    {
+        returnCode = pLib->GetAllowedSwSet(allowedSwModeSet, pAllowedSwSet);
+    }
+    else
+    {
+        returnCode = ADDR_ERROR;
+    }
+
+    return returnCode;
+}
+
+/**
+****************************************************************************************************
+*   Addr2IsBlockTypeAvailable
+*
+*   @brief
+*       Determine whether a block type is allowed in a given blockSet
+****************************************************************************************************
+*/
+BOOL_32 Addr2IsBlockTypeAvailable(
+    ADDR2_BLOCK_SET blockSet,
+    AddrBlockType   blockType)
+{
+    BOOL_32 avail;
+
+    if (blockType == AddrBlockLinear)
+    {
+        avail = blockSet.linear ? TRUE : FALSE;
+    }
+    else
+    {
+        avail = blockSet.value & (1 << (static_cast<UINT_32>(blockType) - 1)) ? TRUE : FALSE;
+    }
+
+    return avail;
+}
+
+/**
+****************************************************************************************************
+*   Addr2BlockTypeWithinMemoryBudget
+*
+*   @brief
+*       Determine whether a new block type is acceptable based on memory waste ratio. Will favor
+*       larger block types.
+****************************************************************************************************
+*/
+BOOL_32 Addr2BlockTypeWithinMemoryBudget(
+    UINT_64 minSize,
+    UINT_64 newBlockTypeSize,
+    UINT_32 ratioLow,
+    UINT_32 ratioHi,
+    DOUBLE  memoryBudget,
+    BOOL_32 newBlockTypeBigger)
+{
+    BOOL_32 accept = FALSE;
+
+    if (memoryBudget >= 1.0)
+    {
+        if (newBlockTypeBigger)
+        {
+            if ((static_cast<DOUBLE>(newBlockTypeSize) / minSize) <= memoryBudget)
+            {
+                accept = TRUE;
+            }
+        }
+        else
+        {
+            if ((static_cast<DOUBLE>(minSize) / newBlockTypeSize) > memoryBudget)
+            {
+                accept = TRUE;
+            }
+        }
+    }
+    else
+    {
+        if (newBlockTypeBigger)
+        {
+            if ((newBlockTypeSize * ratioHi) <= (minSize * ratioLow))
+            {
+                accept = TRUE;
+            }
+        }
+        else
+        {
+            if ((newBlockTypeSize * ratioLow) < (minSize * ratioHi))
+            {
+                accept = TRUE;
+            }
+        }
+    }
+
+    return accept;
+}
index 34c16e2..92ef7c2 100644 (file)
@@ -47,8 +47,8 @@
 #define FAMILY_GFX1100 0x91
 #define FAMILY_GFX1103 0x94
 #define FAMILY_RMB     0x92 //# 146 / Rembrandt
-#define FAMILY_GC_10_3_6  0x95
-#define FAMILY_GC_10_3_7  0x97
+#define FAMILY_RPL     0x95 //# 149 / Raphael
+#define FAMILY_MDN     0x97 //# 151 / Mendocino
 
 // AMDGPU_FAMILY_IS(familyId, familyName)
 #define FAMILY_IS(f, fn)     (f == FAMILY_##fn)
 #define AMDGPU_GFX1101_RANGE    0x20, 0xFF //# 32 <= x < 255
 #define AMDGPU_GFX1102_RANGE    0x10, 0x20 //# 16 <= x < 32
 
-#define AMDGPU_GFX1103_R1_RANGE 0x01, 0x10 //# 1 <= x < 16
+#define AMDGPU_GFX1103_R1_RANGE 0x01, 0x80 //# 1 <= x < 128
 #define AMDGPU_GFX1103_R2_RANGE 0x80, 0xFF //# 128 <= x < max
 
 #define AMDGPU_REMBRANDT_RANGE  0x01, 0xFF //# 01 <= x < 255
 
-#define AMDGPU_GFX1036_RANGE    0x01, 0xFF //# 1 <= x < max
+#define AMDGPU_RAPHAEL_RANGE    0x01, 0xFF //# 1 <= x < max
 
-#define AMDGPU_GFX1037_RANGE    0x01, 0xFF //# 1 <= x < max
+#define AMDGPU_MENDOCINO_RANGE  0x01, 0xFF //# 1 <= x < max
 
 #define AMDGPU_EXPAND_FIX(x) x
 #define AMDGPU_RANGE_HELPER(val, min, max) ((val >= min) && (val < max))
 
 #define ASICREV_IS_REMBRANDT(r)        ASICREV_IS(r, REMBRANDT)
 
-#define ASICREV_IS_GFX1036(r)          ASICREV_IS(r, GFX1036)
+#define ASICREV_IS_RAPHAEL(r)          ASICREV_IS(r, RAPHAEL)
 
-#define ASICREV_IS_GFX1037(r)          ASICREV_IS(r, GFX1037)
+#define ASICREV_IS_MENDOCINO(r)        ASICREV_IS(r, MENDOCINO)
 
 #endif // _AMDGPU_ASIC_ADDR_H
index 02e5443..349843f 100644 (file)
 #endif
 
 #if defined(__GNUC__)
+    #include <signal.h>
     #include <assert.h>
 #endif
 
+#if defined(_WIN32)
+#include <intrin.h>
+#endif
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Platform specific debug break defines
     #else
         #define ADDR_ASSERT(__e) if ( !((__e) ? TRUE : FALSE)) { ADDR_DBG_BREAK(); }
     #endif
-    #define ADDR_ASSERT_ALWAYS() ADDR_DBG_BREAK()
+
+    #if ADDR_SILENCE_ASSERT_ALWAYS
+        #define ADDR_ASSERT_ALWAYS()
+    #else
+        #define ADDR_ASSERT_ALWAYS() ADDR_DBG_BREAK()
+    #endif
+
     #define ADDR_UNHANDLED_CASE() ADDR_ASSERT(!"Unhandled case")
     #define ADDR_NOT_IMPLEMENTED() ADDR_ASSERT(!"Not implemented");
 #else //DEBUG
@@ -321,6 +331,49 @@ static inline UINT_32 XorReduce(
 
 /**
 ****************************************************************************************************
+*   Unset least bit
+*
+*   @brief
+*       Returns a copy of the value with the least-significant '1' bit unset
+****************************************************************************************************
+*/
+static inline UINT_32 UnsetLeastBit(
+    UINT_32 val)
+{
+    return val & (val - 1);
+}
+
+/**
+****************************************************************************************************
+*   BitScanForward
+*
+*   @brief
+*       Returns the index-position of the least-significant '1' bit. Must not be 0.
+****************************************************************************************************
+*/
+static inline UINT_32 BitScanForward(
+    UINT_32 mask) ///< [in] Bitmask to scan
+{
+    ADDR_ASSERT(mask > 0);
+    unsigned long out = 0;
+#if (defined(_WIN64) && defined(_M_X64)) || (defined(_WIN32) && defined(_M_IX64))
+    out = ::_tzcnt_u32(mask);
+#elif (defined(_WIN32) || defined(_WIN64))
+    ::_BitScanForward(&out, mask);
+#elif defined(__GNUC__)
+    out = __builtin_ctz(mask);
+#else
+    while ((mask & 1) == 0)
+    {
+        mask >>= 1;
+        out++;
+    }
+#endif
+    return out;
+}
+
+/**
+****************************************************************************************************
 *   IsPow2
 *
 *   @brief
@@ -977,6 +1030,37 @@ static inline UINT_32 GetCoordActiveMask(
 
 /**
 ****************************************************************************************************
+*   FillEqBitComponents
+*
+*   @brief
+*       Fill the 'numBitComponents' field based on the equation.
+****************************************************************************************************
+*/
+static inline void FillEqBitComponents(
+    ADDR_EQUATION *pEquation) // [in/out] Equation to calculate bit components for
+{
+    pEquation->numBitComponents = 1; // We always have at least the address
+    for (UINT_32 xorN = 1; xorN < ADDR_MAX_EQUATION_COMP; xorN++)
+    {
+        for (UINT_32 bit = 0; bit < ADDR_MAX_EQUATION_BIT; bit++)
+        {
+            if (pEquation->comps[xorN][bit].valid)
+            {
+                pEquation->numBitComponents = xorN + 1;
+                break;
+            }
+        }
+
+        if (pEquation->numBitComponents != (xorN + 1))
+        {
+            // Skip following components if this one wasn't valid
+            break;
+        }
+    }
+}
+
+/**
+****************************************************************************************************
 *   ShiftCeil
 *
 *   @brief
index 4594271..9681b42 100644 (file)
@@ -228,8 +228,8 @@ ADDR_E_RETURNCODE Lib::Create(
                     case FAMILY_NV:
                     case FAMILY_VGH:
                     case FAMILY_RMB:
-                    case FAMILY_GC_10_3_6:
-                    case FAMILY_GC_10_3_7:
+                    case FAMILY_RPL:
+                    case FAMILY_MDN:
                         pLib = Gfx10HwlInit(&client);
                         break;
                     case FAMILY_GFX1100:
index 91195a7..a5518cc 100644 (file)
@@ -34,6 +34,7 @@
 #define __ADDR_LIB_H__
 
 #include "addrinterface.h"
+#include "addrtypes.h"
 #include "addrobject.h"
 #include "addrelemlib.h"
 
@@ -266,7 +267,7 @@ public:
     }
 
     /// Returns asic chip family name defined by AddrLib
-    ChipFamily GetChipFamily()
+    ChipFamily GetChipFamily() const
     {
         return m_chipFamily;
     }
@@ -316,6 +317,21 @@ protected:
 #endif
     }
 
+    static BOOL_32 IsTex1d(AddrResourceType resourceType)
+    {
+        return (resourceType == ADDR_RSRC_TEX_1D);
+    }
+
+    static BOOL_32 IsTex2d(AddrResourceType resourceType)
+    {
+        return (resourceType == ADDR_RSRC_TEX_2D);
+    }
+
+    static BOOL_32 IsTex3d(AddrResourceType resourceType)
+    {
+        return (resourceType == ADDR_RSRC_TEX_3D);
+    }
+
     //
     // Initialization
     //
index 00f344d..a0a6139 100644 (file)
@@ -2995,6 +2995,7 @@ ADDR_E_RETURNCODE Lib::ComputeMicroTileEquation(
     // stackedDepthSlices is used for addressing mode that a tile block contains multiple slices,
     // which is not supported by our address lib
     pEquation->stackedDepthSlices = FALSE;
+    pEquation->numBitComponents   = 1;
 
     return retCode;
 }
index e8e77d2..a05a978 100644 (file)
@@ -303,6 +303,12 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(
             if (localIn.flags.needEquation && (Log2(localIn.numFrags) == 0))
             {
                 pOut->equationIndex = GetEquationIndex(&localIn, pOut);
+                if ((localIn.flags.allowExtEquation == 0) &&
+                    (pOut->equationIndex != ADDR_INVALID_EQUATION_INDEX) &&
+                    (m_equationTable[pOut->equationIndex].numBitComponents > ADDR_MAX_LEGACY_EQUATION_COMP))
+                {
+                    pOut->equationIndex = ADDR_INVALID_EQUATION_INDEX;
+                }
             }
 
             if (localIn.flags.qbStereo)
@@ -1178,6 +1184,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordLinear(
         ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn  = {0};
         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
         ADDR2_MIP_INFO                    mipInfo[MaxMipLevels];
+        ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels);
 
         localIn.bpp          = pIn->bpp;
         localIn.flags        = pIn->flags;
@@ -1855,6 +1862,61 @@ ADDR_E_RETURNCODE Lib::Addr2GetPreferredSurfaceSetting(
 
 /**
 ************************************************************************************************************************
+*   Lib::GetPossibleSwizzleModes
+*
+*   @brief
+*       Returns a list of swizzle modes that are valid from the hardware's perspective for the client to choose from
+*
+*   @return
+*       ADDR_E_RETURNCODE
+************************************************************************************************************************
+*/
+ADDR_E_RETURNCODE Lib::GetPossibleSwizzleModes(
+    const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
+    ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const
+{
+    return HwlGetPossibleSwizzleModes(pIn, pOut);
+}
+
+/**
+************************************************************************************************************************
+*   Lib::GetAllowedBlockSet
+*
+*   @brief
+*       Returns the set of allowed block sizes given the allowed swizzle modes and resource type
+*
+*   @return
+*       ADDR_E_RETURNCODE
+************************************************************************************************************************
+*/
+ADDR_E_RETURNCODE Lib::GetAllowedBlockSet(
+    ADDR2_SWMODE_SET allowedSwModeSet,
+    AddrResourceType rsrcType,
+    ADDR2_BLOCK_SET* pAllowedBlockSet) const
+{
+    return HwlGetAllowedBlockSet(allowedSwModeSet, rsrcType, pAllowedBlockSet);
+}
+
+/**
+************************************************************************************************************************
+*   Lib::GetAllowedSwSet
+*
+*   @brief
+*       Returns the set of allowed swizzle types given the allowed swizzle modes
+*
+*   @return
+*       ADDR_E_RETURNCODE
+************************************************************************************************************************
+*/
+ADDR_E_RETURNCODE Lib::GetAllowedSwSet(
+    ADDR2_SWMODE_SET  allowedSwModeSet,
+    ADDR2_SWTYPE_SET* pAllowedSwSet) const
+{
+    return HwlGetAllowedSwSet(allowedSwModeSet, pAllowedSwSet);
+}
+
+/**
+************************************************************************************************************************
 *   Lib::ComputeBlock256Equation
 *
 *   @brief
@@ -2001,7 +2063,8 @@ VOID Lib::ComputeQbStereoInfo(
 VOID Lib::FilterInvalidEqSwizzleMode(
     ADDR2_SWMODE_SET& allowedSwModeSet,
     AddrResourceType  resourceType,
-    UINT_32           elemLog2
+    UINT_32           elemLog2,
+    UINT_32           maxComponents
     ) const
 {
     if (resourceType != ADDR_RSRC_TEX_1D)
@@ -2014,7 +2077,12 @@ VOID Lib::FilterInvalidEqSwizzleMode(
         {
             if (validSwModeSet & 1)
             {
-                if (m_equationLookupTable[rsrcTypeIdx][swModeIdx][elemLog2] == ADDR_INVALID_EQUATION_INDEX)
+                UINT_32 equation = m_equationLookupTable[rsrcTypeIdx][swModeIdx][elemLog2];
+                if (equation == ADDR_INVALID_EQUATION_INDEX)
+                {
+                    allowedSwModeSetVal &= ~(1u << swModeIdx);
+                }
+                else if (m_equationTable[equation].numBitComponents > maxComponents)
                 {
                     allowedSwModeSetVal &= ~(1u << swModeIdx);
                 }
@@ -2031,94 +2099,6 @@ VOID Lib::FilterInvalidEqSwizzleMode(
     }
 }
 
-/**
-************************************************************************************************************************
-*   Lib::IsBlockTypeAvaiable
-*
-*   @brief
-*       Determine whether a block type is allowed in a given blockSet
-*
-*   @return
-*       N/A
-************************************************************************************************************************
-*/
-BOOL_32 Lib::IsBlockTypeAvaiable(
-    ADDR2_BLOCK_SET blockSet,
-    AddrBlockType   blockType)
-{
-    BOOL_32 avail;
-
-    if (blockType == AddrBlockLinear)
-    {
-        avail = blockSet.linear ? TRUE : FALSE;
-    }
-    else
-    {
-        avail = blockSet.value & (1 << (static_cast<UINT_32>(blockType) - 1)) ? TRUE : FALSE;
-    }
-
-    return avail;
-}
-
-/**
-************************************************************************************************************************
-*   Lib::BlockTypeWithinMemoryBudget
-*
-*   @brief
-*       Determine whether a new block type is acceptable based on memory waste ratio. Will favor larger block types.
-*
-*   @return
-*       N/A
-************************************************************************************************************************
-*/
-BOOL_32 Lib::BlockTypeWithinMemoryBudget(
-    UINT_64 minSize,
-    UINT_64 newBlockTypeSize,
-    UINT_32 ratioLow,
-    UINT_32 ratioHi,
-    DOUBLE  memoryBudget,
-    BOOL_32 newBlockTypeBigger)
-{
-    BOOL_32 accept = FALSE;
-
-    if (memoryBudget >= 1.0)
-    {
-        if (newBlockTypeBigger)
-        {
-            if ((static_cast<DOUBLE>(newBlockTypeSize) / minSize) <= memoryBudget)
-            {
-                accept = TRUE;
-            }
-        }
-        else
-        {
-            if ((static_cast<DOUBLE>(minSize) / newBlockTypeSize) > memoryBudget)
-            {
-                accept = TRUE;
-            }
-        }
-    }
-    else
-    {
-        if (newBlockTypeBigger)
-        {
-            if ((newBlockTypeSize * ratioHi) <= (minSize * ratioLow))
-            {
-                accept = TRUE;
-            }
-        }
-        else
-        {
-            if ((newBlockTypeSize * ratioLow) < (minSize * ratioHi))
-            {
-                accept = TRUE;
-            }
-        }
-    }
-
-    return accept;
-}
-
 #if DEBUG
 /**
 ************************************************************************************************************************
index e381054..7014d3c 100644 (file)
@@ -308,6 +308,10 @@ public:
         const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
         ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const;
 
+    ADDR_E_RETURNCODE GetPossibleSwizzleModes(
+        const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
+        ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT* pOut) const;
+
     virtual BOOL_32 IsValidDisplaySwizzleMode(
         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const
     {
@@ -315,11 +319,21 @@ public:
         return ADDR_NOTIMPLEMENTED;
     }
 
+    ADDR_E_RETURNCODE GetAllowedBlockSet(
+        ADDR2_SWMODE_SET allowedSwModeSet,
+        AddrResourceType rsrcType,
+        ADDR2_BLOCK_SET* pAllowedBlockSet) const;
+
+    ADDR_E_RETURNCODE GetAllowedSwSet(
+        ADDR2_SWMODE_SET  allowedSwModeSet,
+        ADDR2_SWTYPE_SET* pAllowedSwSet) const;
+
 protected:
     Lib();  // Constructor is protected
     Lib(const Client* pClient);
 
     static const UINT_32 MaxNumOfBpp = 5;
+    static const UINT_32 MaxNumOfBppCMask = 4;
     static const UINT_32 MaxNumOfAA  = 4;
 
     static const Dim2d Block256_2d[MaxNumOfBpp];
@@ -672,6 +686,31 @@ protected:
         return ADDR_NOTSUPPORTED;
     }
 
+    virtual ADDR_E_RETURNCODE HwlGetPossibleSwizzleModes(
+        const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
+        ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const
+    {
+        ADDR_NOT_IMPLEMENTED();
+        return ADDR_NOTSUPPORTED;
+    }
+
+    virtual ADDR_E_RETURNCODE HwlGetAllowedBlockSet(
+        ADDR2_SWMODE_SET allowedSwModeSet,
+        AddrResourceType rsrcType,
+        ADDR2_BLOCK_SET* pAllowedBlockSet) const
+    {
+        ADDR_NOT_IMPLEMENTED();
+        return ADDR_NOTIMPLEMENTED;
+    }
+
+    virtual ADDR_E_RETURNCODE HwlGetAllowedSwSet(
+        ADDR2_SWMODE_SET  allowedSwModeSet,
+        ADDR2_SWTYPE_SET* pAllowedSwSet) const
+    {
+        ADDR_NOT_IMPLEMENTED();
+        return ADDR_NOTIMPLEMENTED;
+    }
+
     virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoSanityCheck(
         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const
     {
@@ -925,17 +964,8 @@ protected:
     VOID FilterInvalidEqSwizzleMode(
         ADDR2_SWMODE_SET& allowedSwModeSet,
         AddrResourceType  resourceType,
-        UINT_32           elemLog2) const;
-
-    static BOOL_32 IsBlockTypeAvaiable(ADDR2_BLOCK_SET blockSet, AddrBlockType blockType);
-
-    static BOOL_32 BlockTypeWithinMemoryBudget(
-        UINT_64 minSize,
-        UINT_64 newBlockTypeSize,
-        UINT_32 ratioLow,
-        UINT_32 ratioHi,
-        DOUBLE  memoryBudget = 0.0f,
-        BOOL_32 newBlockTypeBigger = TRUE);
+        UINT_32           elemLog2,
+        UINT_32           maxComponents) const;
 
 #if DEBUG
     VOID ValidateStereoInfo(
index 65af381..4ac52fd 100644 (file)
@@ -3738,7 +3738,6 @@ const ADDR_SW_PATINFO GFX10_SW_VAR_Z_X_8xaa_RBPLUS_PATINFO[] =
     {   3,   27,  344,  365,  124, } , // 64 pipes (32 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus
 };
 
-// Nibble 2D arrays contain arrays of sections of the index equation. An index equation depends on the swizzle mode, pipe#, and bpe#
 const UINT_64 GFX10_SW_PATTERN_NIBBLE01[][8] =
 {
     {X0,            X1,            X2,            X3,            Y0,            Y1,            Y2,            Y3,            }, // 0
@@ -4295,8 +4294,6 @@ const UINT_64 GFX10_SW_PATTERN_NIBBLE2[][4] =
     {Y4^X9^Y9,      X4^Y4,         Y2^Y5^X8,      Z2^X5^Y8,      }, // 507
     {Z3^Y4^X9^Y9,   X4^Y4,         Y1^Y5^X8,      Z2^X5^Y8,      }, // 508
     {Z3^Y4^X9^Y9,   Y1^X4^Y4,      X1^Y5^X8,      Z2^X5^Y8,      }, // 509
-    {Y3^X5^Y5,      Z0^X4^Y4,      Y2,            X3,            }, // 510
-    {Y3^X5^Y5,      X2^X4^Y4,      Y2,            X3,            }, // 511
 };
 
 const UINT_64 GFX10_SW_PATTERN_NIBBLE3[][4] =
index d130487..f318f47 100644 (file)
@@ -31,6 +31,7 @@
 */
 
 #include "gfx10addrlib.h"
+#include "addrcommon.h"
 #include "gfx10_gb_reg.h"
 
 #include "amdgpu_asic_addr.h"
@@ -128,6 +129,7 @@ Gfx10Lib::Gfx10Lib(const Client* pClient)
     m_numSaLog2(0),
     m_colorBaseIndex(0),
     m_xmaskBaseIndex(0),
+    m_htileBaseIndex(0),
     m_dccBaseIndex(0)
 {
     memset(&m_settings, 0, sizeof(m_settings));
@@ -675,7 +677,7 @@ ADDR_E_RETURNCODE Gfx10Lib::HwlComputeHtileAddrFromCoord(
         {
             const UINT_32  numSampleLog2 = Log2(pIn->numSamples);
             const UINT_32  pipeMask      = (1 << m_pipesLog2) - 1;
-            const UINT_32  index         = m_xmaskBaseIndex + numSampleLog2;
+            const UINT_32  index         = m_htileBaseIndex + numSampleLog2;
             const UINT_8*  patIdxTable   = m_settings.supportRbPlus ? GFX10_HTILE_RBPLUS_PATIDX : GFX10_HTILE_PATIDX;
 
             const UINT_32  blkSizeLog2   = Log2(output.metaBlkWidth) + Log2(output.metaBlkHeight) - 4;
@@ -948,9 +950,11 @@ BOOL_32 Gfx10Lib::HwlInitGlobalParams(
 
     {
         // Skip unaligned case
-        m_xmaskBaseIndex += MaxNumOfAA;
+        m_xmaskBaseIndex += MaxNumOfBppCMask;
+        m_htileBaseIndex += MaxNumOfAA;
 
-        m_xmaskBaseIndex += m_pipesLog2 * MaxNumOfAA;
+        m_xmaskBaseIndex += m_pipesLog2 * MaxNumOfBppCMask;
+        m_htileBaseIndex += m_pipesLog2 * MaxNumOfAA;
         m_colorBaseIndex += m_pipesLog2 * MaxNumOfBpp;
 
         if (m_settings.supportRbPlus)
@@ -966,7 +970,8 @@ BOOL_32 Gfx10Lib::HwlInitGlobalParams(
             if (m_numPkrLog2 >= 2)
             {
                 m_colorBaseIndex += (2 * m_numPkrLog2 - 2) * MaxNumOfBpp;
-                m_xmaskBaseIndex += (m_numPkrLog2 - 1) * 3 * MaxNumOfAA;
+                m_xmaskBaseIndex += (m_numPkrLog2 - 1) * 3 * MaxNumOfBppCMask;
+                m_htileBaseIndex += (m_numPkrLog2 - 1) * 3 * MaxNumOfAA;
             }
         }
         else
@@ -976,9 +981,8 @@ BOOL_32 Gfx10Lib::HwlInitGlobalParams(
                                         1;
 
             ADDR_C_ASSERT(sizeof(GFX10_HTILE_PATIDX) / sizeof(GFX10_HTILE_PATIDX[0]) == (numPipeType + 1) * MaxNumOfAA);
-
-            ADDR_C_ASSERT(sizeof(GFX10_HTILE_PATIDX) / sizeof(GFX10_HTILE_PATIDX[0]) ==
-                          sizeof(GFX10_CMASK_64K_PATIDX) / sizeof(GFX10_CMASK_64K_PATIDX[0]));
+            ADDR_C_ASSERT(sizeof(GFX10_CMASK_64K_PATIDX) / sizeof(GFX10_CMASK_64K_PATIDX[0]) ==
+                          (numPipeType + 1) * MaxNumOfBppCMask);
         }
     }
 
@@ -1083,15 +1087,15 @@ ChipFamily Gfx10Lib::HwlConvertChipFamily(
                 ADDR_ASSERT(!"Unknown chip revision");
             }
             break;
-        case FAMILY_GC_10_3_6:
-            if (ASICREV_IS_GFX1036(chipRevision))
+        case FAMILY_RPL:
+            if (ASICREV_IS_RAPHAEL(chipRevision))
             {
                 m_settings.supportRbPlus   = 1;
                 m_settings.dccUnsup3DSwDis = 0;
             }
             break;
-        case FAMILY_GC_10_3_7:
-            if (ASICREV_IS_GFX1037(chipRevision))
+        case FAMILY_MDN:
+            if (ASICREV_IS_MENDOCINO(chipRevision))
             {
                 m_settings.supportRbPlus   = 1;
                 m_settings.dccUnsup3DSwDis = 0;
@@ -1461,12 +1465,14 @@ VOID Gfx10Lib::ConvertSwizzlePatternToEquation(
     const
 {
     // Get full swizzle pattern and store it as an ADDR_BIT_SETTING list
-    ADDR_BIT_SETTING fullSwizzlePattern[20];
+    ADDR_BIT_SETTING fullSwizzlePattern[ADDR_MAX_EQUATION_BIT];
     GetSwizzlePatternFromPatternInfo(pPatInfo, fullSwizzlePattern);
 
     const ADDR_BIT_SETTING* pSwizzle      = fullSwizzlePattern;
     const UINT_32           blockSizeLog2 = GetBlockSizeLog2(swMode);
+    memset(pEquation, 0, sizeof(ADDR_EQUATION));
     pEquation->numBits            = blockSizeLog2;
+    pEquation->numBitComponents   = pPatInfo->maxItemCount;
     pEquation->stackedDepthSlices = FALSE;
 
     for (UINT_32 i = 0; i < elemLog2; i++)
@@ -1478,6 +1484,7 @@ VOID Gfx10Lib::ConvertSwizzlePatternToEquation(
 
     if (IsXor(swMode) == FALSE)
     {
+        // Use simplified logic when we only have one bit-component
         for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)
         {
             ADDR_ASSERT(IsPow2(pSwizzle[i].value));
@@ -1507,475 +1514,87 @@ VOID Gfx10Lib::ConvertSwizzlePatternToEquation(
                 pEquation->addr[i].valid   = 1;
                 pEquation->addr[i].index   = Log2(pSwizzle[i].z);
             }
-
-            pEquation->xor1[i].value = 0;
-            pEquation->xor2[i].value = 0;
         }
     }
-    else if (IsThin(rsrcType, swMode))
+    else
     {
         Dim3d dim;
-        ComputeThinBlockDimension(&dim.w, &dim.h, &dim.d, 8u << elemLog2, 0, rsrcType, swMode);
+        ComputeBlockDimension(&dim.w, &dim.h, &dim.d, 8u << elemLog2, rsrcType, swMode);
 
         const UINT_32 blkXLog2 = Log2(dim.w);
         const UINT_32 blkYLog2 = Log2(dim.h);
+        const UINT_32 blkZLog2 = Log2(dim.d);
         const UINT_32 blkXMask = dim.w - 1;
         const UINT_32 blkYMask = dim.h - 1;
+        const UINT_32 blkZMask = dim.d - 1;
 
         ADDR_BIT_SETTING swizzle[ADDR_MAX_EQUATION_BIT] = {};
+        memcpy(&swizzle, pSwizzle, sizeof(swizzle));
         UINT_32          xMask = 0;
         UINT_32          yMask = 0;
-        UINT_32          bMask = (1 << elemLog2) - 1;
+        UINT_32          zMask = 0;
 
         for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)
         {
-            if (IsPow2(pSwizzle[i].value))
-            {
-                if (pSwizzle[i].x != 0)
-                {
-                    ADDR_ASSERT((xMask & pSwizzle[i].x) == 0);
-                    xMask |= pSwizzle[i].x;
-
-                    const UINT_32 xLog2 = Log2(pSwizzle[i].x);
-
-                    ADDR_ASSERT(xLog2 < blkXLog2);
-
-                    pEquation->addr[i].channel = 0;
-                    pEquation->addr[i].valid   = 1;
-                    pEquation->addr[i].index   = xLog2 + elemLog2;
-                }
-                else
-                {
-                    ADDR_ASSERT(pSwizzle[i].y != 0);
-                    ADDR_ASSERT((yMask & pSwizzle[i].y) == 0);
-                    yMask |= pSwizzle[i].y;
-
-                    pEquation->addr[i].channel = 1;
-                    pEquation->addr[i].valid   = 1;
-                    pEquation->addr[i].index   = Log2(pSwizzle[i].y);
-
-                    ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);
-                }
-
-                swizzle[i].value = 0;
-                bMask |= 1 << i;
-            }
-            else
+            for (UINT_32 bitComp = 0; bitComp < ADDR_MAX_EQUATION_COMP; bitComp++)
             {
-                if (pSwizzle[i].z != 0)
-                {
-                    ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].z)));
-
-                    pEquation->xor2[i].channel = 2;
-                    pEquation->xor2[i].valid   = 1;
-                    pEquation->xor2[i].index   = Log2(pSwizzle[i].z);
-                }
-
-                swizzle[i].x = pSwizzle[i].x;
-                swizzle[i].y = pSwizzle[i].y;
-                swizzle[i].z = swizzle[i].s = 0;
-
-                ADDR_ASSERT(IsPow2(swizzle[i].value) == FALSE);
-
-                const UINT_32 xHi = swizzle[i].x & (~blkXMask);
-
-                if (xHi != 0)
-                {
-                    ADDR_ASSERT(IsPow2(xHi));
-                    ADDR_ASSERT(pEquation->xor1[i].value == 0);
-
-                    pEquation->xor1[i].channel = 0;
-                    pEquation->xor1[i].valid   = 1;
-                    pEquation->xor1[i].index   = Log2(xHi) + elemLog2;
-
-                    swizzle[i].x &= blkXMask;
-                }
-
-                const UINT_32 yHi = swizzle[i].y & (~blkYMask);
-
-                if (yHi != 0)
-                {
-                    ADDR_ASSERT(IsPow2(yHi));
-
-                    if (xHi == 0)
-                    {
-                        ADDR_ASSERT(pEquation->xor1[i].value == 0);
-                        pEquation->xor1[i].channel = 1;
-                        pEquation->xor1[i].valid   = 1;
-                        pEquation->xor1[i].index   = Log2(yHi);
-                    }
-                    else
-                    {
-                        ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                        pEquation->xor2[i].channel = 1;
-                        pEquation->xor2[i].valid   = 1;
-                        pEquation->xor2[i].index   = Log2(yHi);
-                    }
-
-                    swizzle[i].y &= blkYMask;
-                }
-
                 if (swizzle[i].value == 0)
                 {
-                    bMask |= 1 << i;
+                    ADDR_ASSERT(bitComp != 0); // Bits above element size must have at least one addr-bit
+                    ADDR_ASSERT(bitComp <= pPatInfo->maxItemCount);
+                    break;
                 }
-            }
-        }
-
-        const UINT_32 pipeIntMask = (1 << m_pipeInterleaveLog2) - 1;
-        const UINT_32 blockMask   = (1 << blockSizeLog2) - 1;
 
-        ADDR_ASSERT((bMask & pipeIntMask) == pipeIntMask);
-
-        while (bMask != blockMask)
-        {
-            for (UINT_32 i = m_pipeInterleaveLog2; i < blockSizeLog2; i++)
-            {
-                if ((bMask & (1 << i)) == 0)
+                if (swizzle[i].x != 0)
                 {
-                    if (IsPow2(swizzle[i].value))
-                    {
-                        if (swizzle[i].x != 0)
-                        {
-                            ADDR_ASSERT((xMask & swizzle[i].x) == 0);
-                            xMask |= swizzle[i].x;
-
-                            const UINT_32 xLog2 = Log2(swizzle[i].x);
-
-                            ADDR_ASSERT(xLog2 < blkXLog2);
-
-                            pEquation->addr[i].channel = 0;
-                            pEquation->addr[i].valid   = 1;
-                            pEquation->addr[i].index   = xLog2 + elemLog2;
-                        }
-                        else
-                        {
-                            ADDR_ASSERT(swizzle[i].y != 0);
-                            ADDR_ASSERT((yMask & swizzle[i].y) == 0);
-                            yMask |= swizzle[i].y;
-
-                            pEquation->addr[i].channel = 1;
-                            pEquation->addr[i].valid   = 1;
-                            pEquation->addr[i].index   = Log2(swizzle[i].y);
-
-                            ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);
-                        }
+                    const UINT_32 xLog2 = BitScanForward(swizzle[i].x);
+                    swizzle[i].x = UnsetLeastBit(swizzle[i].x);
+                    xMask |= (1 << xLog2);
 
-                        swizzle[i].value = 0;
-                        bMask |= 1 << i;
-                    }
-                    else
-                    {
-                        const UINT_32 x = swizzle[i].x & xMask;
-                        const UINT_32 y = swizzle[i].y & yMask;
-
-                        if (x != 0)
-                        {
-                            ADDR_ASSERT(IsPow2(x));
-
-                            if (pEquation->xor1[i].value == 0)
-                            {
-                                pEquation->xor1[i].channel = 0;
-                                pEquation->xor1[i].valid   = 1;
-                                pEquation->xor1[i].index   = Log2(x) + elemLog2;
-                            }
-                            else
-                            {
-                                ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                                pEquation->xor2[i].channel = 0;
-                                pEquation->xor2[i].valid   = 1;
-                                pEquation->xor2[i].index   = Log2(x) + elemLog2;
-                            }
-                        }
-
-                        if (y != 0)
-                        {
-                            ADDR_ASSERT(IsPow2(y));
-
-                            if (pEquation->xor1[i].value == 0)
-                            {
-                                pEquation->xor1[i].channel = 1;
-                                pEquation->xor1[i].valid   = 1;
-                                pEquation->xor1[i].index   = Log2(y);
-                            }
-                            else
-                            {
-                                ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                                pEquation->xor2[i].channel = 1;
-                                pEquation->xor2[i].valid   = 1;
-                                pEquation->xor2[i].index   = Log2(y);
-                            }
-                        }
-
-                        swizzle[i].x &= ~x;
-                        swizzle[i].y &= ~y;
-                    }
+                    pEquation->comps[bitComp][i].channel = 0;
+                    pEquation->comps[bitComp][i].valid   = 1;
+                    pEquation->comps[bitComp][i].index   = xLog2 + elemLog2;
                 }
-            }
-        }
-
-        ADDR_ASSERT((xMask == blkXMask) && (yMask == blkYMask));
-    }
-    else
-    {
-        const UINT_32 blkXLog2 = (blockSizeLog2 == 12) ? Block4K_Log2_3d[elemLog2].w : Block64K_Log2_3d[elemLog2].w;
-        const UINT_32 blkYLog2 = (blockSizeLog2 == 12) ? Block4K_Log2_3d[elemLog2].h : Block64K_Log2_3d[elemLog2].h;
-        const UINT_32 blkZLog2 = (blockSizeLog2 == 12) ? Block4K_Log2_3d[elemLog2].d : Block64K_Log2_3d[elemLog2].d;
-        const UINT_32 blkXMask = (1 << blkXLog2) - 1;
-        const UINT_32 blkYMask = (1 << blkYLog2) - 1;
-        const UINT_32 blkZMask = (1 << blkZLog2) - 1;
-
-        ADDR_BIT_SETTING swizzle[ADDR_MAX_EQUATION_BIT] = {};
-        UINT_32          xMask = 0;
-        UINT_32          yMask = 0;
-        UINT_32          zMask = 0;
-        UINT_32          bMask = (1 << elemLog2) - 1;
-
-        for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)
-        {
-            if (IsPow2(pSwizzle[i].value))
-            {
-                if (pSwizzle[i].x != 0)
+                else if (swizzle[i].y != 0)
                 {
-                    ADDR_ASSERT((xMask & pSwizzle[i].x) == 0);
-                    xMask |= pSwizzle[i].x;
-
-                    const UINT_32 xLog2 = Log2(pSwizzle[i].x);
+                    const UINT_32 yLog2 = BitScanForward(swizzle[i].y);
+                    swizzle[i].y = UnsetLeastBit(swizzle[i].y);
+                    yMask |= (1 << yLog2);
 
-                    ADDR_ASSERT(xLog2 < blkXLog2);
-
-                    pEquation->addr[i].channel = 0;
-                    pEquation->addr[i].valid   = 1;
-                    pEquation->addr[i].index   = xLog2 + elemLog2;
+                    pEquation->comps[bitComp][i].channel = 1;
+                    pEquation->comps[bitComp][i].valid   = 1;
+                    pEquation->comps[bitComp][i].index   = yLog2;
                 }
-                else if (pSwizzle[i].y != 0)
+                else if (swizzle[i].z != 0)
                 {
-                    ADDR_ASSERT((yMask & pSwizzle[i].y) == 0);
-                    yMask |= pSwizzle[i].y;
-
-                    pEquation->addr[i].channel = 1;
-                    pEquation->addr[i].valid   = 1;
-                    pEquation->addr[i].index   = Log2(pSwizzle[i].y);
+                    const UINT_32 zLog2 = BitScanForward(swizzle[i].z);
+                    swizzle[i].z = UnsetLeastBit(swizzle[i].z);
+                    zMask |= (1 << zLog2);
 
-                    ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);
+                    pEquation->comps[bitComp][i].channel = 2;
+                    pEquation->comps[bitComp][i].valid   = 1;
+                    pEquation->comps[bitComp][i].index   = zLog2;
                 }
                 else
                 {
-                    ADDR_ASSERT(pSwizzle[i].z != 0);
-                    ADDR_ASSERT((zMask & pSwizzle[i].z) == 0);
-                    zMask |= pSwizzle[i].z;
-
-                    pEquation->addr[i].channel = 2;
-                    pEquation->addr[i].valid   = 1;
-                    pEquation->addr[i].index   = Log2(pSwizzle[i].z);
-
-                    ADDR_ASSERT(pEquation->addr[i].index < blkZLog2);
-                }
-
-                swizzle[i].value = 0;
-                bMask |= 1 << i;
-            }
-            else
-            {
-                swizzle[i].x = pSwizzle[i].x;
-                swizzle[i].y = pSwizzle[i].y;
-                swizzle[i].z = pSwizzle[i].z;
-                swizzle[i].s = 0;
-
-                ADDR_ASSERT(IsPow2(swizzle[i].value) == FALSE);
-
-                const UINT_32 xHi = swizzle[i].x & (~blkXMask);
-                const UINT_32 yHi = swizzle[i].y & (~blkYMask);
-                const UINT_32 zHi = swizzle[i].z & (~blkZMask);
-
-                ADDR_ASSERT((xHi == 0) || (yHi== 0) || (zHi == 0));
-
-                if (xHi != 0)
-                {
-                    ADDR_ASSERT(IsPow2(xHi));
-                    ADDR_ASSERT(pEquation->xor1[i].value == 0);
-
-                    pEquation->xor1[i].channel = 0;
-                    pEquation->xor1[i].valid   = 1;
-                    pEquation->xor1[i].index   = Log2(xHi) + elemLog2;
-
-                    swizzle[i].x &= blkXMask;
-                }
-
-                if (yHi != 0)
-                {
-                    ADDR_ASSERT(IsPow2(yHi));
-
-                    if (pEquation->xor1[i].value == 0)
-                    {
-                        pEquation->xor1[i].channel = 1;
-                        pEquation->xor1[i].valid   = 1;
-                        pEquation->xor1[i].index   = Log2(yHi);
-                    }
-                    else
-                    {
-                        ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                        pEquation->xor2[i].channel = 1;
-                        pEquation->xor2[i].valid   = 1;
-                        pEquation->xor2[i].index   = Log2(yHi);
-                    }
-
-                    swizzle[i].y &= blkYMask;
-                }
-
-                if (zHi != 0)
-                {
-                    ADDR_ASSERT(IsPow2(zHi));
-
-                    if (pEquation->xor1[i].value == 0)
-                    {
-                        pEquation->xor1[i].channel = 2;
-                        pEquation->xor1[i].valid   = 1;
-                        pEquation->xor1[i].index   = Log2(zHi);
-                    }
-                    else
-                    {
-                        ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                        pEquation->xor2[i].channel = 2;
-                        pEquation->xor2[i].valid   = 1;
-                        pEquation->xor2[i].index   = Log2(zHi);
-                    }
-
-                    swizzle[i].z &= blkZMask;
-                }
-
-                if (swizzle[i].value == 0)
-                {
-                    bMask |= 1 << i;
-                }
-            }
-        }
-
-        const UINT_32 pipeIntMask = (1 << m_pipeInterleaveLog2) - 1;
-        const UINT_32 blockMask   = (1 << blockSizeLog2) - 1;
-
-        ADDR_ASSERT((bMask & pipeIntMask) == pipeIntMask);
-
-        while (bMask != blockMask)
-        {
-            for (UINT_32 i = m_pipeInterleaveLog2; i < blockSizeLog2; i++)
-            {
-                if ((bMask & (1 << i)) == 0)
-                {
-                    if (IsPow2(swizzle[i].value))
-                    {
-                        if (swizzle[i].x != 0)
-                        {
-                            ADDR_ASSERT((xMask & swizzle[i].x) == 0);
-                            xMask |= swizzle[i].x;
-
-                            const UINT_32 xLog2 = Log2(swizzle[i].x);
-
-                            ADDR_ASSERT(xLog2 < blkXLog2);
-
-                            pEquation->addr[i].channel = 0;
-                            pEquation->addr[i].valid   = 1;
-                            pEquation->addr[i].index   = xLog2 + elemLog2;
-                        }
-                        else if (swizzle[i].y != 0)
-                        {
-                            ADDR_ASSERT((yMask & swizzle[i].y) == 0);
-                            yMask |= swizzle[i].y;
-
-                            pEquation->addr[i].channel = 1;
-                            pEquation->addr[i].valid   = 1;
-                            pEquation->addr[i].index   = Log2(swizzle[i].y);
-
-                            ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);
-                        }
-                        else
-                        {
-                            ADDR_ASSERT(swizzle[i].z != 0);
-                            ADDR_ASSERT((zMask & swizzle[i].z) == 0);
-                            zMask |= swizzle[i].z;
-
-                            pEquation->addr[i].channel = 2;
-                            pEquation->addr[i].valid   = 1;
-                            pEquation->addr[i].index   = Log2(swizzle[i].z);
-
-                            ADDR_ASSERT(pEquation->addr[i].index < blkZLog2);
-                        }
-
-                        swizzle[i].value = 0;
-                        bMask |= 1 << i;
-                    }
-                    else
-                    {
-                        const UINT_32 x = swizzle[i].x & xMask;
-                        const UINT_32 y = swizzle[i].y & yMask;
-                        const UINT_32 z = swizzle[i].z & zMask;
-
-                        if (x != 0)
-                        {
-                            ADDR_ASSERT(IsPow2(x));
-
-                            if (pEquation->xor1[i].value == 0)
-                            {
-                                pEquation->xor1[i].channel = 0;
-                                pEquation->xor1[i].valid   = 1;
-                                pEquation->xor1[i].index   = Log2(x) + elemLog2;
-                            }
-                            else
-                            {
-                                ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                                pEquation->xor2[i].channel = 0;
-                                pEquation->xor2[i].valid   = 1;
-                                pEquation->xor2[i].index   = Log2(x) + elemLog2;
-                            }
-                        }
-
-                        if (y != 0)
-                        {
-                            ADDR_ASSERT(IsPow2(y));
-
-                            if (pEquation->xor1[i].value == 0)
-                            {
-                                pEquation->xor1[i].channel = 1;
-                                pEquation->xor1[i].valid   = 1;
-                                pEquation->xor1[i].index   = Log2(y);
-                            }
-                            else
-                            {
-                                ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                                pEquation->xor2[i].channel = 1;
-                                pEquation->xor2[i].valid   = 1;
-                                pEquation->xor2[i].index   = Log2(y);
-                            }
-                        }
-
-                        if (z != 0)
-                        {
-                            ADDR_ASSERT(IsPow2(z));
-
-                            if (pEquation->xor1[i].value == 0)
-                            {
-                                pEquation->xor1[i].channel = 2;
-                                pEquation->xor1[i].valid   = 1;
-                                pEquation->xor1[i].index   = Log2(z);
-                            }
-                            else
-                            {
-                                ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                                pEquation->xor2[i].channel = 2;
-                                pEquation->xor2[i].valid   = 1;
-                                pEquation->xor2[i].index   = Log2(z);
-                            }
-                        }
-
-                        swizzle[i].x &= ~x;
-                        swizzle[i].y &= ~y;
-                        swizzle[i].z &= ~z;
-                    }
+                    // This function doesn't handle MSAA (must update block dims, here, and consumers)
+                    ADDR_ASSERT_ALWAYS();
                 }
             }
+            ADDR_ASSERT(swizzle[i].value == 0); // We missed an xor? Are there too many?
         }
 
-        ADDR_ASSERT((xMask == blkXMask) && (yMask == blkYMask) && (zMask == blkZMask));
+        // We missed an address bit for coords inside the block?
+        // That means two coords will land on the same addr, which is bad.
+        ADDR_ASSERT(((xMask & blkXMask) == blkXMask) &&
+                    ((yMask & blkYMask) == blkYMask) &&
+                    ((zMask & blkZMask) == blkZMask));
+        // We're sourcing from outside our block? That won't fly for PRTs, which need to be movable.
+        // Non-xor modes can also be used for 2D PRTs but they're handled in the simplified logic above.
+        ADDR_ASSERT((IsPrt(swMode) == false) ||
+                    ((xMask == blkXMask) &&
+                     (yMask == blkYMask) &&
+                     (zMask == blkZMask)));
     }
 }
 
@@ -2018,29 +1637,17 @@ VOID Gfx10Lib::InitEquationTable()
                 if (pPatInfo != NULL)
                 {
                     ADDR_ASSERT(IsValidSwMode(swMode));
+                    ADDR_EQUATION equation = {};
 
-                    if (pPatInfo->maxItemCount <= 3) // Get a valid equationIndex
-                    {
-                        ADDR_EQUATION equation = {};
-
-                        // Passing in pPatInfo to get the addr equation
-                        ConvertSwizzlePatternToEquation(elemLog2, rsrcType, swMode, pPatInfo, &equation);
+                    // Passing in pPatInfo to get the addr equation
+                    ConvertSwizzlePatternToEquation(elemLog2, rsrcType, swMode, pPatInfo, &equation);
 
-                        equationIndex = m_numEquations;
-                        ADDR_ASSERT(equationIndex < EquationTableSize);
-                        // Updates m_equationTable[m_numEquations] to be the addr equation for this PatInfo
-                        m_equationTable[equationIndex] = equation;
-                        // Increment m_numEquations
-                        m_numEquations++;
-                    }
-                    else // There is no equationIndex
-                    {
-                        // We only see "ill" equation from 64/128 BPE + 3D resource + SW_64KB_D_X under RB+ case
-                        ADDR_ASSERT((elemLog2 == 3) || (elemLog2 == 4));
-                        ADDR_ASSERT(rsrcTypeIdx == 1);
-                        ADDR_ASSERT(swMode == ADDR_SW_64KB_D_X);
-                        ADDR_ASSERT(m_settings.supportRbPlus == 1);
-                    }
+                    equationIndex = m_numEquations;
+                    ADDR_ASSERT(equationIndex < EquationTableSize);
+                    // Updates m_equationTable[m_numEquations] to be the addr equation for this PatInfo
+                    m_equationTable[equationIndex] = equation;
+                    // Increment m_numEquations
+                    m_numEquations++;
                 }
                 // equationIndex, which is used to look up equations in m_equationTable, will be cached for every
                 // iteration in this nested for-loop
@@ -2328,9 +1935,9 @@ ADDR_E_RETURNCODE Gfx10Lib::HwlComputeNonBlockCompressedView(
 {
     ADDR_E_RETURNCODE returnCode = ADDR_OK;
 
-    if (pIn->resourceType != ADDR_RSRC_TEX_2D)
+    if (IsThin(pIn->resourceType, pIn->swizzleMode) == FALSE)
     {
-        // Only 2D resource can have a NonBC view...
+        // Only thin swizzle mode can have a NonBC view...
         returnCode = ADDR_INVALIDPARAMS;
     }
     else if (((pIn->format < ADDR_FMT_ASTC_4x4) || (pIn->format > ADDR_FMT_ETC2_128BPP)) &&
@@ -2357,6 +1964,7 @@ ADDR_E_RETURNCODE Gfx10Lib::HwlComputeNonBlockCompressedView(
         infoIn.numFrags     = 1;
 
         ADDR2_MIP_INFO mipInfo[MaxMipLevels] = {};
+        ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels);
 
         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT infoOut = {};
         infoOut.pMipInfo = mipInfo;
@@ -2835,7 +2443,7 @@ ADDR_E_RETURNCODE Gfx10Lib::HwlGetPreferredSurfaceSetting(
                     padSize[i] = PowTwoAlign(padSize[i], sizeAlignInElement);
                 }
 
-                if (BlockTypeWithinMemoryBudget(padSize[0],
+                if (Addr2BlockTypeWithinMemoryBudget(padSize[0],
                                                 padSize[1],
                                                 ratioLow,
                                                 ratioHi,
@@ -3018,7 +2626,6 @@ ADDR_E_RETURNCODE Gfx10Lib::HwlGetPreferredSurfaceSetting(
                 allowedSwModeSet.value &= GetValidDisplaySwizzleModes(bpp);
             }
 
-
             if (allowedSwModeSet.value != 0)
             {
 #if DEBUG
@@ -3069,7 +2676,9 @@ ADDR_E_RETURNCODE Gfx10Lib::HwlGetPreferredSurfaceSetting(
 
                 if (pIn->flags.needEquation)
                 {
-                    FilterInvalidEqSwizzleMode(allowedSwModeSet, pIn->resourceType, Log2(bpp >> 3));
+                    UINT_32 components = pIn->flags.allowExtEquation ?  ADDR_MAX_EQUATION_COMP :
+                                                                        ADDR_MAX_LEGACY_EQUATION_COMP;
+                    FilterInvalidEqSwizzleMode(allowedSwModeSet, pIn->resourceType, Log2(bpp >> 3), components);
                 }
 
                 if (allowedSwModeSet.value == Gfx10LinearSwModeMask)
@@ -3131,7 +2740,7 @@ ADDR_E_RETURNCODE Gfx10Lib::HwlGetPreferredSurfaceSetting(
                         // Iterate through all block types
                         for (UINT_32 i = AddrBlockLinear; i < AddrBlockMaxTiledType; i++)
                         {
-                            if (IsBlockTypeAvaiable(allowedBlockSet, static_cast<AddrBlockType>(i)))
+                            if (Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<::AddrBlockType>(i)))
                             {
                                 localIn.swizzleMode = swMode[i];
 
@@ -3156,7 +2765,7 @@ ADDR_E_RETURNCODE Gfx10Lib::HwlGetPreferredSurfaceSetting(
                                     else
                                     {
                                         // Checks if the block type is within the memory budget but favors larger blocks
-                                        if (BlockTypeWithinMemoryBudget(
+                                        if (Addr2BlockTypeWithinMemoryBudget(
                                                 minSize,
                                                 padSize[i],
                                                 ratioLow,
@@ -3205,9 +2814,9 @@ ADDR_E_RETURNCODE Gfx10Lib::HwlGetPreferredSurfaceSetting(
                             for (UINT_32 i = AddrBlockMicro; i < AddrBlockMaxTiledType; i++)
                             {
                                 if ((i != minSizeBlk) &&
-                                    IsBlockTypeAvaiable(allowedBlockSet, static_cast<AddrBlockType>(i)))
+                                    Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<::AddrBlockType>(i)))
                                 {
-                                    if (BlockTypeWithinMemoryBudget(
+                                    if (Addr2BlockTypeWithinMemoryBudget(
                                             minSize,
                                             padSize[i],
                                             0,
@@ -3697,6 +3306,7 @@ ADDR_E_RETURNCODE Gfx10Lib::ComputeSurfaceInfoMacroTiled(
                 UINT_64       mipSize[MaxMipLevels];
                 UINT_64       mipSliceSize[MaxMipLevels];
 
+                ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels);
                 Dim3d fixedTailMaxDim = tailMaxDim;
 
                 if (m_settings.dsMipmapHtileFix && IsZOrderSwizzle(pIn->swizzleMode) && (index <= 1))
@@ -3913,54 +3523,23 @@ UINT_32 Gfx10Lib::ComputeOffsetFromEquation(
     {
         UINT_32 v = 0;
 
-        if (pEq->addr[i].valid)
-        {
-            if (pEq->addr[i].channel == 0)
-            {
-                v ^= (x >> pEq->addr[i].index) & 1;
-            }
-            else if (pEq->addr[i].channel == 1)
-            {
-                v ^= (y >> pEq->addr[i].index) & 1;
-            }
-            else
-            {
-                ADDR_ASSERT(pEq->addr[i].channel == 2);
-                v ^= (z >> pEq->addr[i].index) & 1;
-            }
-        }
-
-        if (pEq->xor1[i].valid)
+        for (UINT_32 c = 0; c < pEq->numBitComponents; c++)
         {
-            if (pEq->xor1[i].channel == 0)
+            if (pEq->comps[c][i].valid)
             {
-                v ^= (x >> pEq->xor1[i].index) & 1;
-            }
-            else if (pEq->xor1[i].channel == 1)
-            {
-                v ^= (y >> pEq->xor1[i].index) & 1;
-            }
-            else
-            {
-                ADDR_ASSERT(pEq->xor1[i].channel == 2);
-                v ^= (z >> pEq->xor1[i].index) & 1;
-            }
-        }
-
-        if (pEq->xor2[i].valid)
-        {
-            if (pEq->xor2[i].channel == 0)
-            {
-                v ^= (x >> pEq->xor2[i].index) & 1;
-            }
-            else if (pEq->xor2[i].channel == 1)
-            {
-                v ^= (y >> pEq->xor2[i].index) & 1;
-            }
-            else
-            {
-                ADDR_ASSERT(pEq->xor2[i].channel == 2);
-                v ^= (z >> pEq->xor2[i].index) & 1;
+                if (pEq->comps[c][i].channel == 0)
+                {
+                    v ^= (x >> pEq->comps[c][i].index) & 1;
+                }
+                else if (pEq->comps[c][i].channel == 1)
+                {
+                    v ^= (y >> pEq->comps[c][i].index) & 1;
+                }
+                else
+                {
+                    ADDR_ASSERT(pEq->comps[c][i].channel == 2);
+                    v ^= (z >> pEq->comps[c][i].index) & 1;
+                }
             }
         }
 
@@ -4382,6 +3961,7 @@ ADDR_E_RETURNCODE Gfx10Lib::ComputeSurfaceAddrFromCoordMicroTiled(
     ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn  = {};
     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};
     ADDR2_MIP_INFO                    mipInfo[MaxMipLevels];
+    ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels);
 
     localIn.swizzleMode  = pIn->swizzleMode;
     localIn.flags        = pIn->flags;
@@ -4448,6 +4028,7 @@ ADDR_E_RETURNCODE Gfx10Lib::ComputeSurfaceAddrFromCoordMacroTiled(
     ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn  = {};
     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};
     ADDR2_MIP_INFO                    mipInfo[MaxMipLevels];
+    ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels);
 
     localIn.swizzleMode  = pIn->swizzleMode;
     localIn.flags        = pIn->flags;
index d9c0d46..ce4da4f 100644 (file)
@@ -58,8 +58,8 @@ struct Gfx10ChipSettings
         UINT_32 supportRbPlus       : 1;
         UINT_32 dsMipmapHtileFix    : 1;
         UINT_32 dccUnsup3DSwDis     : 1;
-        UINT_32                     : 3;
-        UINT_32 reserved2           : 25;
+        UINT_32                     : 4;
+        UINT_32 reserved2           : 24;
     };
 };
 
@@ -159,7 +159,9 @@ const UINT_32 Gfx10Rsrc3dPrtSwModeMask = Gfx10Rsrc2dPrtSwModeMask & ~Gfx10Displa
 const UINT_32 Gfx10Rsrc3dThin64KBSwModeMask = (1u << ADDR_SW_64KB_Z_X) |
                                               (1u << ADDR_SW_64KB_R_X);
 
-const UINT_32 Gfx10Rsrc3dThinSwModeMask = Gfx10Rsrc3dThin64KBSwModeMask | Gfx10BlkVarSwModeMask;
+
+const UINT_32 Gfx10Rsrc3dThinSwModeMask = Gfx10Rsrc3dThin64KBSwModeMask |
+                                          Gfx10BlkVarSwModeMask;
 
 const UINT_32 Gfx10Rsrc3dThickSwModeMask = Gfx10Rsrc3dSwModeMask & ~(Gfx10Rsrc3dThinSwModeMask | Gfx10LinearSwModeMask);
 
@@ -167,8 +169,9 @@ const UINT_32 Gfx10Rsrc3dThick4KBSwModeMask = Gfx10Rsrc3dThickSwModeMask & Gfx10
 
 const UINT_32 Gfx10Rsrc3dThick64KBSwModeMask = Gfx10Rsrc3dThickSwModeMask & Gfx10Blk64KBSwModeMask;
 
-const UINT_32 Gfx10MsaaSwModeMask = Gfx10ZSwModeMask |
-                                    Gfx10RenderSwModeMask;
+const UINT_32 Gfx10MsaaSwModeMask = (Gfx10ZSwModeMask       |
+                                     Gfx10RenderSwModeMask)
+                                    ;
 
 const UINT_32 Dcn20NonBpp64SwModeMask = (1u << ADDR_SW_LINEAR)   |
                                         (1u << ADDR_SW_4KB_S)    |
@@ -577,6 +580,7 @@ private:
 
     UINT_32 m_colorBaseIndex;
     UINT_32 m_xmaskBaseIndex;
+    UINT_32 m_htileBaseIndex;
     UINT_32 m_dccBaseIndex;
 };
 
index af48e77..9445450 100644 (file)
@@ -289,18 +289,23 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlComputeDccInfo(
     }
     else
     {
-        const UINT_32 elemLog2 = Log2(pIn->bpp >> 3);
-
-        const BOOL_32 isThick = IsThick(pIn->resourceType, pIn->swizzleMode);
-
-        pOut->compressBlkWidth  = isThick ? Block256_3d[elemLog2].w : Block256_2d[elemLog2].w;
-        pOut->compressBlkHeight = isThick ? Block256_3d[elemLog2].h : Block256_2d[elemLog2].h;
-        pOut->compressBlkDepth  = isThick ? Block256_3d[elemLog2].d : 1;
+        const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);
+        const UINT_32 numFragLog2 = Log2(Max(pIn->numFrags, 1u));
+        Dim3d         compBlock   = {};
+
+        GetCompressedBlockSizeLog2(Gfx11DataColor,
+                                   pIn->resourceType,
+                                   pIn->swizzleMode,
+                                   elemLog2,
+                                   numFragLog2,
+                                   &compBlock);
+        pOut->compressBlkWidth  = 1 << compBlock.w;
+        pOut->compressBlkHeight = 1 << compBlock.h;
+        pOut->compressBlkDepth  = 1 << compBlock.d;
 
         if (ret == ADDR_OK)
         {
             Dim3d         metaBlk     = {};
-            const UINT_32 numFragLog2 = Log2(Max(pIn->numFrags, 1u));
             const UINT_32 metaBlkSize = GetMetaBlkSize(Gfx11DataColor,
                                                        pIn->resourceType,
                                                        pIn->swizzleMode,
@@ -752,6 +757,7 @@ ChipFamily Gfx11Lib::HwlConvertChipFamily(
             }
             break;
         case FAMILY_GFX1103:
+            m_settings.isGfx1103 = 1;
             break;
         default:
             ADDR_ASSERT(!"Unknown chip family");
@@ -1096,13 +1102,14 @@ VOID Gfx11Lib::ConvertSwizzlePatternToEquation(
     ADDR_EQUATION*         pEquation) ///< [out] equation converted from swizzle pattern
     const
 {
-    ADDR_BIT_SETTING fullSwizzlePattern[20];
+    ADDR_BIT_SETTING fullSwizzlePattern[ADDR_MAX_EQUATION_BIT];
     GetSwizzlePatternFromPatternInfo(pPatInfo, fullSwizzlePattern);
 
     const ADDR_BIT_SETTING* pSwizzle      = fullSwizzlePattern;
     const UINT_32           blockSizeLog2 = GetBlockSizeLog2(swMode);
-
+    memset(pEquation, 0, sizeof(ADDR_EQUATION));
     pEquation->numBits            = blockSizeLog2;
+    pEquation->numBitComponents   = pPatInfo->maxItemCount;
     pEquation->stackedDepthSlices = FALSE;
 
     for (UINT_32 i = 0; i < elemLog2; i++)
@@ -1114,6 +1121,7 @@ VOID Gfx11Lib::ConvertSwizzlePatternToEquation(
 
     if (IsXor(swMode) == FALSE)
     {
+        // Use simplified logic when we only have one bit-component
         for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)
         {
             ADDR_ASSERT(IsPow2(pSwizzle[i].value));
@@ -1143,479 +1151,87 @@ VOID Gfx11Lib::ConvertSwizzlePatternToEquation(
                 pEquation->addr[i].valid   = 1;
                 pEquation->addr[i].index   = Log2(pSwizzle[i].z);
             }
-
-            pEquation->xor1[i].value = 0;
-            pEquation->xor2[i].value = 0;
         }
     }
-    else if (IsThin(rsrcType, swMode))
+    else
     {
         Dim3d dim;
-        ComputeThinBlockDimension(&dim.w, &dim.h, &dim.d, 8u << elemLog2, 0, rsrcType, swMode);
+        ComputeBlockDimension(&dim.w, &dim.h, &dim.d, 8u << elemLog2, rsrcType, swMode);
 
         const UINT_32 blkXLog2 = Log2(dim.w);
         const UINT_32 blkYLog2 = Log2(dim.h);
+        const UINT_32 blkZLog2 = Log2(dim.d);
         const UINT_32 blkXMask = dim.w - 1;
         const UINT_32 blkYMask = dim.h - 1;
-
-        ADDR_BIT_SETTING swizzle[ADDR_MAX_EQUATION_BIT];
-        UINT_32          xMask = 0;
-        UINT_32          yMask = 0;
-        UINT_32          bMask = (1 << elemLog2) - 1;
-
-        for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)
-        {
-            if (IsPow2(pSwizzle[i].value))
-            {
-                if (pSwizzle[i].x != 0)
-                {
-                    ADDR_ASSERT((xMask & pSwizzle[i].x) == 0);
-                    xMask |= pSwizzle[i].x;
-
-                    const UINT_32 xLog2 = Log2(pSwizzle[i].x);
-
-                    ADDR_ASSERT(xLog2 < blkXLog2);
-
-                    pEquation->addr[i].channel = 0;
-                    pEquation->addr[i].valid   = 1;
-                    pEquation->addr[i].index   = xLog2 + elemLog2;
-                }
-                else
-                {
-                    ADDR_ASSERT(pSwizzle[i].y != 0);
-                    ADDR_ASSERT((yMask & pSwizzle[i].y) == 0);
-                    yMask |= pSwizzle[i].y;
-
-                    pEquation->addr[i].channel = 1;
-                    pEquation->addr[i].valid   = 1;
-                    pEquation->addr[i].index   = Log2(pSwizzle[i].y);
-
-                    ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);
-                }
-
-                swizzle[i].value = 0;
-                bMask |= 1 << i;
-            }
-            else
-            {
-                if (pSwizzle[i].z != 0)
-                {
-                    ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].z)));
-
-                    pEquation->xor2[i].channel = 2;
-                    pEquation->xor2[i].valid   = 1;
-                    pEquation->xor2[i].index   = Log2(pSwizzle[i].z);
-                }
-
-                swizzle[i].x = pSwizzle[i].x;
-                swizzle[i].y = pSwizzle[i].y;
-                swizzle[i].z = swizzle[i].s = 0;
-
-                ADDR_ASSERT(IsPow2(swizzle[i].value) == FALSE);
-
-                const UINT_32 xHi = swizzle[i].x & (~blkXMask);
-
-                if (xHi != 0)
-                {
-                    ADDR_ASSERT(IsPow2(xHi));
-                    ADDR_ASSERT(pEquation->xor1[i].value == 0);
-
-                    pEquation->xor1[i].channel = 0;
-                    pEquation->xor1[i].valid   = 1;
-                    pEquation->xor1[i].index   = Log2(xHi) + elemLog2;
-
-                    swizzle[i].x &= blkXMask;
-                }
-
-                const UINT_32 yHi = swizzle[i].y & (~blkYMask);
-
-                if (yHi != 0)
-                {
-                    ADDR_ASSERT(IsPow2(yHi));
-
-                    if (xHi == 0)
-                    {
-                        ADDR_ASSERT(pEquation->xor1[i].value == 0);
-                        pEquation->xor1[i].channel = 1;
-                        pEquation->xor1[i].valid   = 1;
-                        pEquation->xor1[i].index   = Log2(yHi);
-                    }
-                    else
-                    {
-                        ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                        pEquation->xor2[i].channel = 1;
-                        pEquation->xor2[i].valid   = 1;
-                        pEquation->xor2[i].index   = Log2(yHi);
-                    }
-
-                    swizzle[i].y &= blkYMask;
-                }
-
-                if (swizzle[i].value == 0)
-                {
-                    bMask |= 1 << i;
-                }
-            }
-        }
-
-        const UINT_32 pipeIntMask = (1 << m_pipeInterleaveLog2) - 1;
-        const UINT_32 blockMask   = (1 << blockSizeLog2) - 1;
-
-        ADDR_ASSERT((bMask & pipeIntMask) == pipeIntMask);
-
-        while (bMask != blockMask)
-        {
-            for (UINT_32 i = m_pipeInterleaveLog2; i < blockSizeLog2; i++)
-            {
-                if ((bMask & (1 << i)) == 0)
-                {
-                    if (IsPow2(swizzle[i].value))
-                    {
-                        if (swizzle[i].x != 0)
-                        {
-                            ADDR_ASSERT((xMask & swizzle[i].x) == 0);
-                            xMask |= swizzle[i].x;
-
-                            const UINT_32 xLog2 = Log2(swizzle[i].x);
-
-                            ADDR_ASSERT(xLog2 < blkXLog2);
-
-                            pEquation->addr[i].channel = 0;
-                            pEquation->addr[i].valid   = 1;
-                            pEquation->addr[i].index   = xLog2 + elemLog2;
-                        }
-                        else
-                        {
-                            ADDR_ASSERT(swizzle[i].y != 0);
-                            ADDR_ASSERT((yMask & swizzle[i].y) == 0);
-                            yMask |= swizzle[i].y;
-
-                            pEquation->addr[i].channel = 1;
-                            pEquation->addr[i].valid   = 1;
-                            pEquation->addr[i].index   = Log2(swizzle[i].y);
-
-                            ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);
-                        }
-
-                        swizzle[i].value = 0;
-                        bMask |= 1 << i;
-                    }
-                    else
-                    {
-                        const UINT_32 x = swizzle[i].x & xMask;
-                        const UINT_32 y = swizzle[i].y & yMask;
-
-                        if (x != 0)
-                        {
-                            ADDR_ASSERT(IsPow2(x));
-
-                            if (pEquation->xor1[i].value == 0)
-                            {
-                                pEquation->xor1[i].channel = 0;
-                                pEquation->xor1[i].valid   = 1;
-                                pEquation->xor1[i].index   = Log2(x) + elemLog2;
-                            }
-                            else
-                            {
-                                ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                                pEquation->xor2[i].channel = 0;
-                                pEquation->xor2[i].valid   = 1;
-                                pEquation->xor2[i].index   = Log2(x) + elemLog2;
-                            }
-                        }
-
-                        if (y != 0)
-                        {
-                            ADDR_ASSERT(IsPow2(y));
-
-                            if (pEquation->xor1[i].value == 0)
-                            {
-                                pEquation->xor1[i].channel = 1;
-                                pEquation->xor1[i].valid   = 1;
-                                pEquation->xor1[i].index   = Log2(y);
-                            }
-                            else
-                            {
-                                ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                                pEquation->xor2[i].channel = 1;
-                                pEquation->xor2[i].valid   = 1;
-                                pEquation->xor2[i].index   = Log2(y);
-                            }
-                        }
-
-                        swizzle[i].x &= ~x;
-                        swizzle[i].y &= ~y;
-                    }
-                }
-            }
-        }
-
-        ADDR_ASSERT((xMask == blkXMask) && (yMask == blkYMask));
-    }
-    else
-    {
-        const Dim3d& blkDim = (blockSizeLog2 == Log2Size256K) ?
-                              Block256K_Log2_3d[elemLog2] :
-                              ((blockSizeLog2 == Log2Size4K) ? Block4K_Log2_3d[elemLog2] : Block64K_Log2_3d[elemLog2]);
-
-        const UINT_32 blkXLog2 = blkDim.w;
-        const UINT_32 blkYLog2 = blkDim.h;
-        const UINT_32 blkZLog2 = blkDim.d;
-        const UINT_32 blkXMask = (1 << blkXLog2) - 1;
-        const UINT_32 blkYMask = (1 << blkYLog2) - 1;
-        const UINT_32 blkZMask = (1 << blkZLog2) - 1;
+        const UINT_32 blkZMask = dim.d - 1;
 
         ADDR_BIT_SETTING swizzle[ADDR_MAX_EQUATION_BIT] = {};
+        memcpy(&swizzle, pSwizzle, sizeof(swizzle));
         UINT_32          xMask = 0;
         UINT_32          yMask = 0;
         UINT_32          zMask = 0;
-        UINT_32          bMask = (1 << elemLog2) - 1;
 
         for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)
         {
-            if (IsPow2(pSwizzle[i].value))
+            for (UINT_32 bitComp = 0; bitComp < ADDR_MAX_EQUATION_COMP; bitComp++)
             {
-                if (pSwizzle[i].x != 0)
-                {
-                    ADDR_ASSERT((xMask & pSwizzle[i].x) == 0);
-                    xMask |= pSwizzle[i].x;
-
-                    const UINT_32 xLog2 = Log2(pSwizzle[i].x);
-
-                    ADDR_ASSERT(xLog2 < blkXLog2);
-
-                    pEquation->addr[i].channel = 0;
-                    pEquation->addr[i].valid   = 1;
-                    pEquation->addr[i].index   = xLog2 + elemLog2;
-                }
-                else if (pSwizzle[i].y != 0)
-                {
-                    ADDR_ASSERT((yMask & pSwizzle[i].y) == 0);
-                    yMask |= pSwizzle[i].y;
-
-                    pEquation->addr[i].channel = 1;
-                    pEquation->addr[i].valid   = 1;
-                    pEquation->addr[i].index   = Log2(pSwizzle[i].y);
-
-                    ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);
-                }
-                else
+                if (swizzle[i].value == 0)
                 {
-                    ADDR_ASSERT(pSwizzle[i].z != 0);
-                    ADDR_ASSERT((zMask & pSwizzle[i].z) == 0);
-                    zMask |= pSwizzle[i].z;
-
-                    pEquation->addr[i].channel = 2;
-                    pEquation->addr[i].valid   = 1;
-                    pEquation->addr[i].index   = Log2(pSwizzle[i].z);
-
-                    ADDR_ASSERT(pEquation->addr[i].index < blkZLog2);
+                    ADDR_ASSERT(bitComp != 0); // Bits above element size must have at least one addr-bit
+                    ADDR_ASSERT(bitComp <= pPatInfo->maxItemCount);
+                    break;
                 }
 
-                swizzle[i].value = 0;
-                bMask |= 1 << i;
-            }
-            else
-            {
-                swizzle[i].x = pSwizzle[i].x;
-                swizzle[i].y = pSwizzle[i].y;
-                swizzle[i].z = pSwizzle[i].z;
-                swizzle[i].s = 0;
-
-                ADDR_ASSERT(IsPow2(swizzle[i].value) == FALSE);
-
-                const UINT_32 xHi = swizzle[i].x & (~blkXMask);
-                const UINT_32 yHi = swizzle[i].y & (~blkYMask);
-                const UINT_32 zHi = swizzle[i].z & (~blkZMask);
-
-                ADDR_ASSERT((xHi == 0) || (yHi== 0) || (zHi == 0));
-
-                if (xHi != 0)
+                if (swizzle[i].x != 0)
                 {
-                    ADDR_ASSERT(IsPow2(xHi));
-                    ADDR_ASSERT(pEquation->xor1[i].value == 0);
-
-                    pEquation->xor1[i].channel = 0;
-                    pEquation->xor1[i].valid   = 1;
-                    pEquation->xor1[i].index   = Log2(xHi) + elemLog2;
+                    const UINT_32 xLog2 = BitScanForward(swizzle[i].x);
+                    swizzle[i].x = UnsetLeastBit(swizzle[i].x);
+                    xMask |= (1 << xLog2);
 
-                    swizzle[i].x &= blkXMask;
+                    pEquation->comps[bitComp][i].channel = 0;
+                    pEquation->comps[bitComp][i].valid   = 1;
+                    pEquation->comps[bitComp][i].index   = xLog2 + elemLog2;
                 }
-
-                if (yHi != 0)
+                else if (swizzle[i].y != 0)
                 {
-                    ADDR_ASSERT(IsPow2(yHi));
+                    const UINT_32 yLog2 = BitScanForward(swizzle[i].y);
+                    swizzle[i].y = UnsetLeastBit(swizzle[i].y);
+                    yMask |= (1 << yLog2);
 
-                    if (pEquation->xor1[i].value == 0)
-                    {
-                        pEquation->xor1[i].channel = 1;
-                        pEquation->xor1[i].valid   = 1;
-                        pEquation->xor1[i].index   = Log2(yHi);
-                    }
-                    else
-                    {
-                        ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                        pEquation->xor2[i].channel = 1;
-                        pEquation->xor2[i].valid   = 1;
-                        pEquation->xor2[i].index   = Log2(yHi);
-                    }
-
-                    swizzle[i].y &= blkYMask;
+                    pEquation->comps[bitComp][i].channel = 1;
+                    pEquation->comps[bitComp][i].valid   = 1;
+                    pEquation->comps[bitComp][i].index   = yLog2;
                 }
-
-                if (zHi != 0)
+                else if (swizzle[i].z != 0)
                 {
-                    ADDR_ASSERT(IsPow2(zHi));
-
-                    if (pEquation->xor1[i].value == 0)
-                    {
-                        pEquation->xor1[i].channel = 2;
-                        pEquation->xor1[i].valid   = 1;
-                        pEquation->xor1[i].index   = Log2(zHi);
-                    }
-                    else
-                    {
-                        ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                        pEquation->xor2[i].channel = 2;
-                        pEquation->xor2[i].valid   = 1;
-                        pEquation->xor2[i].index   = Log2(zHi);
-                    }
-
-                    swizzle[i].z &= blkZMask;
-                }
+                    const UINT_32 zLog2 = BitScanForward(swizzle[i].z);
+                    swizzle[i].z = UnsetLeastBit(swizzle[i].z);
+                    zMask |= (1 << zLog2);
 
-                if (swizzle[i].value == 0)
-                {
-                    bMask |= 1 << i;
+                    pEquation->comps[bitComp][i].channel = 2;
+                    pEquation->comps[bitComp][i].valid   = 1;
+                    pEquation->comps[bitComp][i].index   = zLog2;
                 }
-            }
-        }
-
-        const UINT_32 pipeIntMask = (1 << m_pipeInterleaveLog2) - 1;
-        const UINT_32 blockMask   = (1 << blockSizeLog2) - 1;
-
-        ADDR_ASSERT((bMask & pipeIntMask) == pipeIntMask);
-
-        while (bMask != blockMask)
-        {
-            for (UINT_32 i = m_pipeInterleaveLog2; i < blockSizeLog2; i++)
-            {
-                if ((bMask & (1 << i)) == 0)
+                else
                 {
-                    if (IsPow2(swizzle[i].value))
-                    {
-                        if (swizzle[i].x != 0)
-                        {
-                            ADDR_ASSERT((xMask & swizzle[i].x) == 0);
-                            xMask |= swizzle[i].x;
-
-                            const UINT_32 xLog2 = Log2(swizzle[i].x);
-
-                            ADDR_ASSERT(xLog2 < blkXLog2);
-
-                            pEquation->addr[i].channel = 0;
-                            pEquation->addr[i].valid   = 1;
-                            pEquation->addr[i].index   = xLog2 + elemLog2;
-                        }
-                        else if (swizzle[i].y != 0)
-                        {
-                            ADDR_ASSERT((yMask & swizzle[i].y) == 0);
-                            yMask |= swizzle[i].y;
-
-                            pEquation->addr[i].channel = 1;
-                            pEquation->addr[i].valid   = 1;
-                            pEquation->addr[i].index   = Log2(swizzle[i].y);
-
-                            ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);
-                        }
-                        else
-                        {
-                            ADDR_ASSERT(swizzle[i].z != 0);
-                            ADDR_ASSERT((zMask & swizzle[i].z) == 0);
-                            zMask |= swizzle[i].z;
-
-                            pEquation->addr[i].channel = 2;
-                            pEquation->addr[i].valid   = 1;
-                            pEquation->addr[i].index   = Log2(swizzle[i].z);
-
-                            ADDR_ASSERT(pEquation->addr[i].index < blkZLog2);
-                        }
-
-                        swizzle[i].value = 0;
-                        bMask |= 1 << i;
-                    }
-                    else
-                    {
-                        const UINT_32 x = swizzle[i].x & xMask;
-                        const UINT_32 y = swizzle[i].y & yMask;
-                        const UINT_32 z = swizzle[i].z & zMask;
-
-                        if (x != 0)
-                        {
-                            ADDR_ASSERT(IsPow2(x));
-
-                            if (pEquation->xor1[i].value == 0)
-                            {
-                                pEquation->xor1[i].channel = 0;
-                                pEquation->xor1[i].valid   = 1;
-                                pEquation->xor1[i].index   = Log2(x) + elemLog2;
-                            }
-                            else
-                            {
-                                ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                                pEquation->xor2[i].channel = 0;
-                                pEquation->xor2[i].valid   = 1;
-                                pEquation->xor2[i].index   = Log2(x) + elemLog2;
-                            }
-                        }
-
-                        if (y != 0)
-                        {
-                            ADDR_ASSERT(IsPow2(y));
-
-                            if (pEquation->xor1[i].value == 0)
-                            {
-                                pEquation->xor1[i].channel = 1;
-                                pEquation->xor1[i].valid   = 1;
-                                pEquation->xor1[i].index   = Log2(y);
-                            }
-                            else
-                            {
-                                ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                                pEquation->xor2[i].channel = 1;
-                                pEquation->xor2[i].valid   = 1;
-                                pEquation->xor2[i].index   = Log2(y);
-                            }
-                        }
-
-                        if (z != 0)
-                        {
-                            ADDR_ASSERT(IsPow2(z));
-
-                            if (pEquation->xor1[i].value == 0)
-                            {
-                                pEquation->xor1[i].channel = 2;
-                                pEquation->xor1[i].valid   = 1;
-                                pEquation->xor1[i].index   = Log2(z);
-                            }
-                            else
-                            {
-                                ADDR_ASSERT(pEquation->xor2[i].value == 0);
-                                pEquation->xor2[i].channel = 2;
-                                pEquation->xor2[i].valid   = 1;
-                                pEquation->xor2[i].index   = Log2(z);
-                            }
-                        }
-
-                        swizzle[i].x &= ~x;
-                        swizzle[i].y &= ~y;
-                        swizzle[i].z &= ~z;
-                    }
+                    // This function doesn't handle MSAA (must update block dims, here, and consumers)
+                    ADDR_ASSERT_ALWAYS();
                 }
             }
+            ADDR_ASSERT(swizzle[i].value == 0); // We missed an xor? Are there too many?
         }
 
-        ADDR_ASSERT((xMask == blkXMask) && (yMask == blkYMask) && (zMask == blkZMask));
+        // We missed an address bit for coords inside the block?
+        // That means two coords will land on the same addr, which is bad.
+        ADDR_ASSERT(((xMask & blkXMask) == blkXMask) &&
+                    ((yMask & blkYMask) == blkYMask) &&
+                    ((zMask & blkZMask) == blkZMask));
+        // We're sourcing from outside our block? That won't fly for PRTs, which need to be movable.
+        // Non-xor modes can also be used for 2D PRTs but they're handled in the simplified logic above.
+        ADDR_ASSERT((IsPrt(swMode) == false) ||
+                    ((xMask == blkXMask) &&
+                     (yMask == blkYMask) &&
+                     (zMask == blkZMask)));
     }
 }
 
@@ -1650,27 +1266,16 @@ VOID Gfx11Lib::InitEquationTable()
                 if (pPatInfo != NULL)
                 {
                     ADDR_ASSERT(IsValidSwMode(swMode));
+                    ADDR_EQUATION equation = {};
 
-                    if (pPatInfo->maxItemCount <= 3)
-                    {
-                        ADDR_EQUATION equation = {};
-
-                        ConvertSwizzlePatternToEquation(elemLog2, rsrcType, swMode, pPatInfo, &equation);
+                    ConvertSwizzlePatternToEquation(elemLog2, rsrcType, swMode, pPatInfo, &equation);
 
-                        equationIndex = m_numEquations;
-                        ADDR_ASSERT(equationIndex < EquationTableSize);
+                    equationIndex = m_numEquations;
+                    ADDR_ASSERT(equationIndex < EquationTableSize);
 
-                        m_equationTable[equationIndex] = equation;
+                    m_equationTable[equationIndex] = equation;
 
-                        m_numEquations++;
-                    }
-                    else
-                    {
-                        // We only see "ill" equation from 64/128 BPE + 3D resource + SW_64KB_D_X
-                        ADDR_ASSERT((elemLog2 == 3) || (elemLog2 == 4));
-                        ADDR_ASSERT(rsrcType == ADDR_RSRC_TEX_3D);
-                        ADDR_ASSERT(swMode == ADDR_SW_64KB_D_X);
-                    }
+                    m_numEquations++;
                 }
 
                 m_equationLookupTable[rsrcTypeIdx][swModeIdx][elemLog2] = equationIndex;
@@ -1737,7 +1342,18 @@ UINT_32 Gfx11Lib::GetValidDisplaySwizzleModes(
 
     if (bpp <= 64)
     {
+        const ChipFamily  family = GetChipFamily();
+
         swModeMask = Dcn32SwModeMask;
+
+        if (false
+            || (m_settings.isGfx1103)
+           )
+        {
+            // Not all GPUs support displaying with 256kB swizzle modes.
+            swModeMask &= ~((1u << ADDR_SW_256KB_D_X) |
+                            (1u << ADDR_SW_256KB_R_X));
+        }
     }
 
     return swModeMask;
@@ -1929,15 +1545,15 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlComputeNonBlockCompressedView(
 {
     ADDR_E_RETURNCODE returnCode = ADDR_OK;
 
-    if (pIn->resourceType != ADDR_RSRC_TEX_2D)
+    if (IsThin(pIn->resourceType, pIn->swizzleMode) == FALSE)
     {
-        // Only 2D resource can have a NonBC view...
+        // Only thin swizzle mode can have a NonBC view...
         returnCode = ADDR_INVALIDPARAMS;
     }
-    else if ((pIn->format != ADDR_FMT_ASTC_8x8) &&
+    else if (((pIn->format < ADDR_FMT_ASTC_4x4) || (pIn->format > ADDR_FMT_ETC2_128BPP)) &&
              ((pIn->format < ADDR_FMT_BC1) || (pIn->format > ADDR_FMT_BC7)))
     {
-        // Only support BC1~BC7 or ASTC_8x8 for now...
+        // Only support BC1~BC7, ASTC, or ETC2 for now...
         returnCode = ADDR_NOTSUPPORTED;
     }
     else
@@ -1950,8 +1566,8 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlComputeNonBlockCompressedView(
         infoIn.swizzleMode  = pIn->swizzleMode;
         infoIn.resourceType = pIn->resourceType;
         infoIn.bpp          = bpp;
-        infoIn.width        = PowTwoAlign(pIn->width, bcWidth) / bcWidth;
-        infoIn.height       = PowTwoAlign(pIn->height, bcHeight) / bcHeight;
+        infoIn.width        = RoundUpQuotient(pIn->width, bcWidth);
+        infoIn.height       = RoundUpQuotient(pIn->height, bcHeight);
         infoIn.numSlices    = pIn->numSlices;
         infoIn.numMipLevels = pIn->numMipLevels;
         infoIn.numSamples   = 1;
@@ -2003,8 +1619,8 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlComputeNonBlockCompressedView(
             pOut->pipeBankXor = slicePbXorOut.pipeBankXor;
 
             const BOOL_32 inTail           = tiled && (pIn->mipId >= infoOut.firstMipIdInTail) ? TRUE : FALSE;
-            const UINT_32 requestMipWidth  = PowTwoAlign(Max(pIn->width >> pIn->mipId, 1u), bcWidth) / bcWidth;
-            const UINT_32 requestMipHeight = PowTwoAlign(Max(pIn->height >> pIn->mipId, 1u), bcHeight) / bcHeight;
+            const UINT_32 requestMipWidth  = RoundUpQuotient(Max(pIn->width >> pIn->mipId, 1u), bcWidth);
+            const UINT_32 requestMipHeight = RoundUpQuotient(Max(pIn->height >> pIn->mipId, 1u), bcHeight);
 
             if (inTail)
             {
@@ -2054,10 +1670,8 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlComputeNonBlockCompressedView(
                 pOut->mipId        = 1;
                 pOut->numMipLevels = 2;
 
-                const UINT_32 upperMipWidth  =
-                    PowTwoAlign(Max(pIn->width >> (pIn->mipId - 1), 1u), bcWidth) / bcWidth;
-                const UINT_32 upperMipHeight =
-                    PowTwoAlign(Max(pIn->height >> (pIn->mipId - 1), 1u), bcHeight) / bcHeight;
+                const UINT_32 upperMipWidth  = RoundUpQuotient(Max(pIn->width >> (pIn->mipId - 1), 1u), bcWidth);
+                const UINT_32 upperMipHeight = RoundUpQuotient(Max(pIn->height >> (pIn->mipId - 1), 1u), bcHeight);
 
                 const BOOL_32 needToAvoidInTail =
                     tiled && (requestMipWidth <= infoOut.blockWidth / 2) && (requestMipHeight <= infoOut.blockHeight) ?
@@ -2565,8 +2179,9 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlGetPreferredSurfaceSetting(
                 pOut->resourceType   = pIn->resourceType;
                 pOut->validSwModeSet = allowedSwModeSet;
                 pOut->canXor         = (allowedSwModeSet.value & Gfx11XorSwModeMask) ? TRUE : FALSE;
-                pOut->validBlockSet  = GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType);
-                pOut->validSwTypeSet = GetAllowedSwSet(allowedSwModeSet);
+
+                GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType, &(pOut->validBlockSet));
+                GetAllowedSwSet(allowedSwModeSet, &(pOut->validSwTypeSet));
 
                 pOut->clientPreferredSwSet = pIn->preferredSwSet;
 
@@ -2578,7 +2193,9 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlGetPreferredSurfaceSetting(
                 // Apply optional restrictions
                 if (pIn->flags.needEquation)
                 {
-                    FilterInvalidEqSwizzleMode(allowedSwModeSet, pIn->resourceType, Log2(bpp >> 3));
+                    UINT_32 components = pIn->flags.allowExtEquation ?  ADDR_MAX_EQUATION_COMP :
+                                                                        ADDR_MAX_LEGACY_EQUATION_COMP;
+                    FilterInvalidEqSwizzleMode(allowedSwModeSet, pIn->resourceType, Log2(bpp >> 3), components);
                 }
 
                 if (allowedSwModeSet.value == Gfx11LinearSwModeMask)
@@ -2597,7 +2214,8 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlGetPreferredSurfaceSetting(
                         allowedSwModeSet.swLinear = 0;
                     }
 
-                    ADDR2_BLOCK_SET allowedBlockSet = GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType);
+                    ADDR2_BLOCK_SET allowedBlockSet = {};
+                    GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType, &allowedBlockSet);
 
                     // Determine block size if there are 2 or more block type candidates
                     if (IsPow2(allowedBlockSet.value) == FALSE)
@@ -2634,7 +2252,7 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlGetPreferredSurfaceSetting(
 
                         for (UINT_32 i = AddrBlockLinear; i < AddrBlockMaxTiledType; i++)
                         {
-                            if (IsBlockTypeAvaiable(allowedBlockSet, static_cast<AddrBlockType>(i)))
+                            if (Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<::AddrBlockType>(i)))
                             {
                                 localIn.swizzleMode = swMode[i];
 
@@ -2652,7 +2270,7 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlGetPreferredSurfaceSetting(
                                     padSize[i] = localOut.surfSize;
 
                                     if ((minSize == 0) ||
-                                        BlockTypeWithinMemoryBudget(minSize, padSize[i], ratioLow, ratioHi))
+                                        Addr2BlockTypeWithinMemoryBudget(minSize, padSize[i], ratioLow, ratioHi))
                                     {
                                         minSize    = padSize[i];
                                         minSizeBlk = i;
@@ -2697,9 +2315,9 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlGetPreferredSurfaceSetting(
                             for (UINT_32 i = AddrBlockMicro; i < AddrBlockMaxTiledType; i++)
                             {
                                 if ((i != minSizeBlk) &&
-                                    IsBlockTypeAvaiable(allowedBlockSet, static_cast<AddrBlockType>(i)))
+                                    Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<::AddrBlockType>(i)))
                                 {
-                                    if (BlockTypeWithinMemoryBudget(minSize, padSize[i], 0, 0, pIn->memoryBudget) == FALSE)
+                                    if (Addr2BlockTypeWithinMemoryBudget(minSize, padSize[i], 0, 0, pIn->memoryBudget) == FALSE)
                                     {
                                         // Clear the block type if the memory waste is unacceptable
                                         allowedBlockSet.value &= ~(1u << (i - 1));
@@ -2771,9 +2389,11 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlGetPreferredSurfaceSetting(
                     }
 
                     // Block type should be determined.
-                    ADDR_ASSERT(IsPow2(GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType).value));
+                    GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType, &allowedBlockSet);
+                    ADDR_ASSERT(IsPow2(allowedBlockSet.value));
 
-                    ADDR2_SWTYPE_SET allowedSwSet = GetAllowedSwSet(allowedSwModeSet);
+                    ADDR2_SWTYPE_SET allowedSwSet = {};
+                    GetAllowedSwSet(allowedSwModeSet, &allowedSwSet);
 
                     // Determine swizzle type if there are 2 or more swizzle type candidates
                     if ((allowedSwSet.value != 0) && (IsPow2(allowedSwSet.value) == FALSE))
@@ -2812,17 +2432,17 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlGetPreferredSurfaceSetting(
                         }
                         else if (pIn->resourceType == ADDR_RSRC_TEX_3D)
                         {
-                            if (allowedSwSet.sw_D)
+                            if (pIn->flags.color && allowedSwSet.sw_R)
                             {
-                                allowedSwModeSet.value &= Gfx11DisplaySwModeMask;
+                                allowedSwModeSet.value &= Gfx11RenderSwModeMask;
                             }
                             else if (allowedSwSet.sw_S)
                             {
                                 allowedSwModeSet.value &= Gfx11StandardSwModeMask;
                             }
-                            else if (allowedSwSet.sw_R)
+                            else if (allowedSwSet.sw_D)
                             {
-                                allowedSwModeSet.value &= Gfx11RenderSwModeMask;
+                                allowedSwModeSet.value &= Gfx11DisplaySwModeMask;
                             }
                             else
                             {
@@ -2851,7 +2471,8 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlGetPreferredSurfaceSetting(
                         }
 
                         // Swizzle type should be determined.
-                        ADDR_ASSERT(IsPow2(GetAllowedSwSet(allowedSwModeSet).value));
+                        GetAllowedSwSet(allowedSwModeSet, &allowedSwSet);
+                        ADDR_ASSERT(IsPow2(allowedSwSet.value));
                     }
 
                     // Determine swizzle mode now. Always select the "largest" swizzle mode for a given block type +
@@ -2880,6 +2501,271 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlGetPreferredSurfaceSetting(
 
 /**
 ************************************************************************************************************************
+*   Gfx11Lib::HwlGetPossibleSwizzleModes
+*
+*   @brief
+*       Returns a list of swizzle modes that are valid from the hardware's perspective for the client to choose from
+*
+*   @return
+*       ADDR_E_RETURNCODE
+************************************************************************************************************************
+*/
+ADDR_E_RETURNCODE Gfx11Lib::HwlGetPossibleSwizzleModes(
+    const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,  ///< [in] input structure
+    ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut  ///< [out] output structure
+    ) const
+{
+    ADDR_E_RETURNCODE returnCode = ADDR_OK;
+
+    if (pIn->flags.fmask)
+    {
+        // There is no FMASK for GFX11 ASICs.
+        ADDR_ASSERT_ALWAYS();
+
+        returnCode = ADDR_INVALIDPARAMS;
+    }
+    else
+    {
+        UINT_32 bpp    = pIn->bpp;
+        UINT_32 width  = Max(pIn->width, 1u);
+        UINT_32 height = Max(pIn->height, 1u);
+
+        // Set format to INVALID will skip this conversion
+        if (pIn->format != ADDR_FMT_INVALID)
+        {
+            ElemMode elemMode = ADDR_UNCOMPRESSED;
+            UINT_32 expandX, expandY;
+
+            // Get compression/expansion factors and element mode which indicates compression/expansion
+            bpp = GetElemLib()->GetBitsPerPixel(pIn->format,
+                &elemMode,
+                &expandX,
+                &expandY);
+
+            UINT_32 basePitch = 0;
+            GetElemLib()->AdjustSurfaceInfo(elemMode,
+                expandX,
+                expandY,
+                &bpp,
+                &basePitch,
+                &width,
+                &height);
+        }
+
+        const UINT_32 numSlices    = Max(pIn->numSlices, 1u);
+        const UINT_32 numMipLevels = Max(pIn->numMipLevels, 1u);
+        const UINT_32 numSamples   = Max(pIn->numSamples, 1u);
+        const BOOL_32 msaa         = numSamples > 1;
+
+        // Pre sanity check on non swizzle mode parameters
+        ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {};
+        localIn.flags = pIn->flags;
+        localIn.resourceType = pIn->resourceType;
+        localIn.format = pIn->format;
+        localIn.bpp = bpp;
+        localIn.width = width;
+        localIn.height = height;
+        localIn.numSlices = numSlices;
+        localIn.numMipLevels = numMipLevels;
+        localIn.numSamples = numSamples;
+        localIn.numFrags = numSamples;
+
+        if (ValidateNonSwModeParams(&localIn))
+        {
+            // Allow appropriate swizzle modes by default
+            ADDR2_SWMODE_SET allowedSwModeSet = {};
+            allowedSwModeSet.value |= Gfx11LinearSwModeMask | Gfx11Blk256BSwModeMask;
+            if (pIn->resourceType == ADDR_RSRC_TEX_3D)
+            {
+                allowedSwModeSet.value |= Gfx11Rsrc3dThick4KBSwModeMask  |
+                                          Gfx11Rsrc3dThin64KBSwModeMask  |
+                                          Gfx11Rsrc3dThick64KBSwModeMask |
+                                          Gfx11Rsrc3dThin256KBSwModeMask |
+                                          Gfx11Rsrc3dThick256KBSwModeMask;
+            }
+            else
+            {
+                allowedSwModeSet.value |= Gfx11Blk4KBSwModeMask | Gfx11Blk64KBSwModeMask | Gfx11Blk256KBSwModeMask;
+            }
+
+            // Filter out invalid swizzle mode(s) by image attributes and HW restrictions
+            switch (pIn->resourceType)
+            {
+            case ADDR_RSRC_TEX_1D:
+                allowedSwModeSet.value &= Gfx11Rsrc1dSwModeMask;
+                break;
+
+            case ADDR_RSRC_TEX_2D:
+                allowedSwModeSet.value &= pIn->flags.prt ? Gfx11Rsrc2dPrtSwModeMask : Gfx11Rsrc2dSwModeMask;
+                break;
+
+            case ADDR_RSRC_TEX_3D:
+                allowedSwModeSet.value &= pIn->flags.prt ? Gfx11Rsrc3dPrtSwModeMask : Gfx11Rsrc3dSwModeMask;
+
+                if (pIn->flags.view3dAs2dArray)
+                {
+                    allowedSwModeSet.value &= Gfx11Rsrc3dThinSwModeMask;
+                }
+                break;
+
+            default:
+                ADDR_ASSERT_ALWAYS();
+                allowedSwModeSet.value = 0;
+                break;
+            }
+
+            // TODO: figure out if following restrictions are correct on GFX11...
+            if (ElemLib::IsBlockCompressed(pIn->format) ||
+                ElemLib::IsMacroPixelPacked(pIn->format) ||
+                (bpp > 64) ||
+                (msaa && ((bpp > 32) || pIn->flags.color || pIn->flags.unordered)))
+            {
+                allowedSwModeSet.value &= ~Gfx11ZSwModeMask;
+            }
+
+            if (pIn->format == ADDR_FMT_32_32_32)
+            {
+                allowedSwModeSet.value &= Gfx11LinearSwModeMask;
+            }
+
+            if (msaa)
+            {
+                allowedSwModeSet.value &= Gfx11MsaaSwModeMask;
+            }
+
+            if (pIn->flags.depth || pIn->flags.stencil)
+            {
+                allowedSwModeSet.value &= Gfx11ZSwModeMask;
+            }
+
+            if (pIn->flags.display)
+            {
+                allowedSwModeSet.value &= GetValidDisplaySwizzleModes(bpp);
+            }
+
+            if (allowedSwModeSet.value != 0)
+            {
+#if DEBUG
+                // Post sanity check, at least AddrLib should accept the output generated by its own
+                UINT_32 validateSwModeSet = allowedSwModeSet.value;
+
+                for (UINT_32 i = 0; validateSwModeSet != 0; i++)
+                {
+                    if (validateSwModeSet & 1)
+                    {
+                        localIn.swizzleMode = static_cast<AddrSwizzleMode>(i);
+                        ADDR_ASSERT(ValidateSwModeParams(&localIn));
+                    }
+
+                    validateSwModeSet >>= 1;
+                }
+#endif
+
+                pOut->resourceType = pIn->resourceType;
+                pOut->clientPreferredSwSet = pIn->preferredSwSet;
+
+                if (pOut->clientPreferredSwSet.value == 0)
+                {
+                    pOut->clientPreferredSwSet.value = AddrSwSetAll;
+                }
+
+                if (pIn->flags.needEquation)
+                {
+                    UINT_32 components = pIn->flags.allowExtEquation ?  ADDR_MAX_EQUATION_COMP :
+                                                                        ADDR_MAX_LEGACY_EQUATION_COMP;
+                    FilterInvalidEqSwizzleMode(allowedSwModeSet, pIn->resourceType, Log2(bpp >> 3), components);
+                }
+
+                pOut->validSwModeSet = allowedSwModeSet;
+                pOut->canXor = (allowedSwModeSet.value & Gfx11XorSwModeMask) ? TRUE : FALSE;
+            }
+            else
+            {
+                // Invalid combination...
+                ADDR_ASSERT_ALWAYS();
+                returnCode = ADDR_INVALIDPARAMS;
+            }
+        }
+        else
+        {
+            // Invalid combination...
+            ADDR_ASSERT_ALWAYS();
+            returnCode = ADDR_INVALIDPARAMS;
+        }
+    }
+
+    return returnCode;
+}
+
+/**
+************************************************************************************************************************
+*   Gfx11Lib::HwlGetAllowedBlockSet
+*
+*   @brief
+*       Returns the set of allowed block sizes given the allowed swizzle modes and resource type
+*
+*   @return
+*       ADDR_E_RETURNCODE
+************************************************************************************************************************
+*/
+ADDR_E_RETURNCODE Gfx11Lib::HwlGetAllowedBlockSet(
+    ADDR2_SWMODE_SET allowedSwModeSet,  ///< [in] allowed swizzle modes
+    AddrResourceType rsrcType,          ///< [in] resource type
+    ADDR2_BLOCK_SET* pAllowedBlockSet   ///< [out] allowed block sizes
+    ) const
+{
+    ADDR2_BLOCK_SET allowedBlockSet = {};
+
+    allowedBlockSet.micro  = (allowedSwModeSet.value & Gfx11Blk256BSwModeMask) ? TRUE : FALSE;
+    allowedBlockSet.linear = (allowedSwModeSet.value & Gfx11LinearSwModeMask)  ? TRUE : FALSE;
+
+    if (rsrcType == ADDR_RSRC_TEX_3D)
+    {
+        allowedBlockSet.macroThick4KB    = (allowedSwModeSet.value & Gfx11Rsrc3dThick4KBSwModeMask)   ? TRUE : FALSE;
+        allowedBlockSet.macroThin64KB    = (allowedSwModeSet.value & Gfx11Rsrc3dThin64KBSwModeMask)   ? TRUE : FALSE;
+        allowedBlockSet.macroThick64KB   = (allowedSwModeSet.value & Gfx11Rsrc3dThick64KBSwModeMask)  ? TRUE : FALSE;
+        allowedBlockSet.gfx11.thin256KB  = (allowedSwModeSet.value & Gfx11Rsrc3dThin256KBSwModeMask)  ? TRUE : FALSE;
+        allowedBlockSet.gfx11.thick256KB = (allowedSwModeSet.value & Gfx11Rsrc3dThick256KBSwModeMask) ? TRUE : FALSE;
+    }
+    else
+    {
+        allowedBlockSet.macroThin4KB    = (allowedSwModeSet.value & Gfx11Blk4KBSwModeMask)   ? TRUE : FALSE;
+        allowedBlockSet.macroThin64KB   = (allowedSwModeSet.value & Gfx11Blk64KBSwModeMask)  ? TRUE : FALSE;
+        allowedBlockSet.gfx11.thin256KB = (allowedSwModeSet.value & Gfx11Blk256KBSwModeMask) ? TRUE : FALSE;
+    }
+
+    *pAllowedBlockSet = allowedBlockSet;
+    return ADDR_OK;
+}
+
+/**
+************************************************************************************************************************
+*   Gfx11Lib::HwlGetAllowedSwSet
+*
+*   @brief
+*       Returns the set of allowed swizzle types given the allowed swizzle modes
+*   @return
+*       ADDR_E_RETURNCODE
+************************************************************************************************************************
+*/
+ADDR_E_RETURNCODE Gfx11Lib::HwlGetAllowedSwSet(
+    ADDR2_SWMODE_SET  allowedSwModeSet, ///< [in] allowed swizzle modes
+    ADDR2_SWTYPE_SET* pAllowedSwSet     ///< [out] allowed swizzle types
+    ) const
+{
+    ADDR2_SWTYPE_SET allowedSwSet = {};
+
+    allowedSwSet.sw_Z = (allowedSwModeSet.value & Gfx11ZSwModeMask)        ? TRUE : FALSE;
+    allowedSwSet.sw_S = (allowedSwModeSet.value & Gfx11StandardSwModeMask) ? TRUE : FALSE;
+    allowedSwSet.sw_D = (allowedSwModeSet.value & Gfx11DisplaySwModeMask)  ? TRUE : FALSE;
+    allowedSwSet.sw_R = (allowedSwModeSet.value & Gfx11RenderSwModeMask)   ? TRUE : FALSE;
+
+    *pAllowedSwSet = allowedSwSet;
+    return ADDR_OK;
+}
+
+/**
+************************************************************************************************************************
 *   Gfx11Lib::ComputeStereoInfo
 *
 *   @brief
@@ -3177,12 +3063,12 @@ ADDR_E_RETURNCODE Gfx11Lib::ComputeSurfaceInfoMacroTiled(
                 UINT_64       mipSize[MaxMipLevels];
                 UINT_64       mipSliceSize[MaxMipLevels];
 
+                // For htile, we need to make z16 and stencil enter the mip tail at the same time as z32 would
                 Dim3d fixedTailMaxDim = tailMaxDim;
-
-                if ((IsZOrderSwizzle(pIn->swizzleMode) || IsRtOptSwizzle(pIn->swizzleMode)) && (index <= 1))
+                if (IsZOrderSwizzle(pIn->swizzleMode) && (index <= 1))
                 {
                     fixedTailMaxDim.w /= Block256_2d[index].w / Block256_2d[2].w;
-                    fixedTailMaxDim.h /= Block256_2d[index].h / Block256_2d[2].h;
+                    fixedTailMaxDim.h /= Block256_2d[index].w / Block256_2d[2].w;
                 }
 
                 for (UINT_32 i = 0; i < pIn->numMipLevels; i++)
@@ -3395,54 +3281,23 @@ UINT_32 Gfx11Lib::ComputeOffsetFromEquation(
     {
         UINT_32 v = 0;
 
-        if (pEq->addr[i].valid)
-        {
-            if (pEq->addr[i].channel == 0)
-            {
-                v ^= (x >> pEq->addr[i].index) & 1;
-            }
-            else if (pEq->addr[i].channel == 1)
-            {
-                v ^= (y >> pEq->addr[i].index) & 1;
-            }
-            else
-            {
-                ADDR_ASSERT(pEq->addr[i].channel == 2);
-                v ^= (z >> pEq->addr[i].index) & 1;
-            }
-        }
-
-        if (pEq->xor1[i].valid)
+        for (UINT_32 c = 0; c < pEq->numBitComponents; c++)
         {
-            if (pEq->xor1[i].channel == 0)
-            {
-                v ^= (x >> pEq->xor1[i].index) & 1;
-            }
-            else if (pEq->xor1[i].channel == 1)
+            if (pEq->comps[c][i].valid)
             {
-                v ^= (y >> pEq->xor1[i].index) & 1;
-            }
-            else
-            {
-                ADDR_ASSERT(pEq->xor1[i].channel == 2);
-                v ^= (z >> pEq->xor1[i].index) & 1;
-            }
-        }
-
-        if (pEq->xor2[i].valid)
-        {
-            if (pEq->xor2[i].channel == 0)
-            {
-                v ^= (x >> pEq->xor2[i].index) & 1;
-            }
-            else if (pEq->xor2[i].channel == 1)
-            {
-                v ^= (y >> pEq->xor2[i].index) & 1;
-            }
-            else
-            {
-                ADDR_ASSERT(pEq->xor2[i].channel == 2);
-                v ^= (z >> pEq->xor2[i].index) & 1;
+                if (pEq->comps[c][i].channel == 0)
+                {
+                    v ^= (x >> pEq->comps[c][i].index) & 1;
+                }
+                else if (pEq->comps[c][i].channel == 1)
+                {
+                    v ^= (y >> pEq->comps[c][i].index) & 1;
+                }
+                else
+                {
+                    ADDR_ASSERT(pEq->comps[c][i].channel == 2);
+                    v ^= (z >> pEq->comps[c][i].index) & 1;
+                }
             }
         }
 
@@ -4028,6 +3883,7 @@ UINT_32 Gfx11Lib::HwlComputeMaxMetaBaseAlignments() const
     }
 
     // Max base alignment for 2D Dcc
+    // swizzle mode support DCC...
     const AddrSwizzleMode ValidSwizzleModeForDcc2D[] =
     {
         ADDR_SW_64KB_R_X,
index ad742bf..ec65dad 100644 (file)
@@ -51,7 +51,9 @@ struct Gfx11ChipSettings
 {
     struct
     {
-        UINT_32 reserved1           : 32;
+        UINT_32 reserved0           :  1;
+        UINT_32 isGfx1103           :  1;
+        UINT_32 reserved1           : 30;
 
         // Misc configuration bits
         UINT_32 reserved2           : 32;
@@ -286,6 +288,19 @@ protected:
         const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
         ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const;
 
+    virtual ADDR_E_RETURNCODE HwlGetPossibleSwizzleModes(
+        const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
+        ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const;
+
+    virtual ADDR_E_RETURNCODE HwlGetAllowedBlockSet(
+        ADDR2_SWMODE_SET allowedSwModeSet,
+        AddrResourceType rsrcType,
+        ADDR2_BLOCK_SET* pAllowedBlockSet) const;
+
+    virtual ADDR_E_RETURNCODE HwlGetAllowedSwSet(
+        ADDR2_SWMODE_SET  allowedSwModeSet,
+        ADDR2_SWTYPE_SET* pAllowedSwSet) const;
+
     virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoSanityCheck(
         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;
 
@@ -468,43 +483,6 @@ private:
 
     UINT_32 GetMaxNumMipsInTail(UINT_32 blockSizeLog2, BOOL_32 isThin) const;
 
-    static ADDR2_BLOCK_SET GetAllowedBlockSet(ADDR2_SWMODE_SET allowedSwModeSet, AddrResourceType rsrcType)
-    {
-        ADDR2_BLOCK_SET allowedBlockSet = {};
-
-        allowedBlockSet.micro  = (allowedSwModeSet.value & Gfx11Blk256BSwModeMask) ? TRUE : FALSE;
-        allowedBlockSet.linear = (allowedSwModeSet.value & Gfx11LinearSwModeMask)  ? TRUE : FALSE;
-
-        if (rsrcType == ADDR_RSRC_TEX_3D)
-        {
-            allowedBlockSet.macroThick4KB    = (allowedSwModeSet.value & Gfx11Rsrc3dThick4KBSwModeMask)   ? TRUE : FALSE;
-            allowedBlockSet.macroThin64KB    = (allowedSwModeSet.value & Gfx11Rsrc3dThin64KBSwModeMask)   ? TRUE : FALSE;
-            allowedBlockSet.macroThick64KB   = (allowedSwModeSet.value & Gfx11Rsrc3dThick64KBSwModeMask)  ? TRUE : FALSE;
-            allowedBlockSet.gfx11.thin256KB  = (allowedSwModeSet.value & Gfx11Rsrc3dThin256KBSwModeMask)  ? TRUE : FALSE;
-            allowedBlockSet.gfx11.thick256KB = (allowedSwModeSet.value & Gfx11Rsrc3dThick256KBSwModeMask) ? TRUE : FALSE;
-        }
-        else
-        {
-            allowedBlockSet.macroThin4KB    = (allowedSwModeSet.value & Gfx11Blk4KBSwModeMask)   ? TRUE : FALSE;
-            allowedBlockSet.macroThin64KB   = (allowedSwModeSet.value & Gfx11Blk64KBSwModeMask)  ? TRUE : FALSE;
-            allowedBlockSet.gfx11.thin256KB = (allowedSwModeSet.value & Gfx11Blk256KBSwModeMask) ? TRUE : FALSE;
-        }
-
-        return allowedBlockSet;
-    }
-
-    static ADDR2_SWTYPE_SET GetAllowedSwSet(ADDR2_SWMODE_SET allowedSwModeSet)
-    {
-        ADDR2_SWTYPE_SET allowedSwSet = {};
-
-        allowedSwSet.sw_Z = (allowedSwModeSet.value & Gfx11ZSwModeMask)        ? TRUE : FALSE;
-        allowedSwSet.sw_S = (allowedSwModeSet.value & Gfx11StandardSwModeMask) ? TRUE : FALSE;
-        allowedSwSet.sw_D = (allowedSwModeSet.value & Gfx11DisplaySwModeMask)  ? TRUE : FALSE;
-        allowedSwSet.sw_R = (allowedSwModeSet.value & Gfx11RenderSwModeMask)   ? TRUE : FALSE;
-
-        return allowedSwSet;
-    }
-
     BOOL_32 IsInMipTail(
         Dim3d   mipTailDim,
         UINT_32 maxNumMipsInTail,
index 4aec276..3709927 100644 (file)
@@ -2411,6 +2411,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeBlock256Equation(
     ADDR_E_RETURNCODE ret = ADDR_OK;
 
     pEquation->numBits = 8;
+    pEquation->numBitComponents = 1;
 
     UINT_32 i = 0;
     for (; i < elementBytesLog2; i++)
@@ -2737,6 +2738,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThinEquation(
             }
         }
 
+        FillEqBitComponents(pEquation);
         pEquation->numBits = blockSizeLog2;
     }
 
@@ -3014,6 +3016,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThickEquation(
             }
         }
 
+        FillEqBitComponents(pEquation);
         pEquation->numBits = blockSizeLog2;
     }
 
@@ -3724,7 +3727,9 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlGetPreferredSurfaceSetting(
             // Apply optional restrictions
             if (pIn->flags.needEquation)
             {
-                FilterInvalidEqSwizzleMode(allowedSwModeSet, pIn->resourceType, Log2(bpp >> 3));
+                UINT_32 components = pIn->flags.allowExtEquation ?  ADDR_MAX_EQUATION_COMP :
+                                                                    ADDR_MAX_LEGACY_EQUATION_COMP;
+                FilterInvalidEqSwizzleMode(allowedSwModeSet, pIn->resourceType, Log2(bpp >> 3), components);
             }
 
             if (allowedSwModeSet.value == Gfx9LinearSwModeMask)
@@ -3773,7 +3778,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlGetPreferredSurfaceSetting(
 
                     for (UINT_32 i = AddrBlockLinear; i < AddrBlockMaxTiledType; i++)
                     {
-                        if (IsBlockTypeAvaiable(allowedBlockSet, static_cast<AddrBlockType>(i)))
+                        if (Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<::AddrBlockType>(i)))
                         {
                             localIn.swizzleMode = swMode[i];
 
@@ -3791,7 +3796,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlGetPreferredSurfaceSetting(
                                 padSize[i] = localOut.surfSize;
 
                                 if ((minSize == 0) ||
-                                    BlockTypeWithinMemoryBudget(minSize, padSize[i], ratioLow, ratioHi))
+                                    Addr2BlockTypeWithinMemoryBudget(minSize, padSize[i], ratioLow, ratioHi))
                                 {
                                     minSize    = padSize[i];
                                     minSizeBlk = i;
@@ -3832,9 +3837,9 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlGetPreferredSurfaceSetting(
                         for (UINT_32 i = AddrBlockMicro; i < AddrBlockMaxTiledType; i++)
                         {
                             if ((i != minSizeBlk) &&
-                                IsBlockTypeAvaiable(allowedBlockSet, static_cast<AddrBlockType>(i)))
+                                Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<::AddrBlockType>(i)))
                             {
-                                if (BlockTypeWithinMemoryBudget(minSize, padSize[i], 0, 0, pIn->memoryBudget) == FALSE)
+                                if (Addr2BlockTypeWithinMemoryBudget(minSize, padSize[i], 0, 0, pIn->memoryBudget) == FALSE)
                                 {
                                     // Clear the block type if the memory waste is unacceptable
                                     allowedBlockSet.value &= ~(1u << (i - 1));
index 256dba0..eab483a 100644 (file)
@@ -1559,6 +1559,8 @@ ADDR_E_RETURNCODE EgBasedLib::ComputeMacroTileEquation(
                     pEquation->xor2[bankBitStart + i] = equation.xor2[i];
                     pEquation->numBits++;
                 }
+
+                FillEqBitComponents(pEquation);
             }
         }
     }
index bb7983c..0650693 100644 (file)
@@ -419,6 +419,7 @@ ADDR_E_RETURNCODE SiLib::ComputeBankEquation(
             }
         }
     }
+    FillEqBitComponents(pEquation);
 
     if ((pTileInfo->bankWidth == 1) &&
         ((pTileInfo->pipeConfig == ADDR_PIPECFG_P4_32x32) ||
index 4087488..0c0cf05 100644 (file)
@@ -689,8 +689,8 @@ bool ac_query_gpu_info(int fd, void *dev_p, struct radeon_info *info)
          else if (device_info.family == FAMILY_NV ||
                   device_info.family == FAMILY_VGH ||
                   device_info.family == FAMILY_RMB ||
-                  device_info.family == FAMILY_GC_10_3_6 ||
-                  device_info.family == FAMILY_GC_10_3_7)
+                  device_info.family == FAMILY_RPL ||
+                  device_info.family == FAMILY_MDN)
             info->ip[AMD_IP_GFX].ver_minor = info->ip[AMD_IP_COMPUTE].ver_minor = 3;
       }
       info->ip[ip_type].num_queues = util_bitcount(ip_info.available_rings);
@@ -845,11 +845,11 @@ bool ac_query_gpu_info(int fd, void *dev_p, struct radeon_info *info)
    case FAMILY_RMB:
       identify_chip(REMBRANDT);
       break;
-   case FAMILY_GC_10_3_6:
-      identify_chip(GFX1036);
+   case FAMILY_RPL:
+      identify_chip2(RAPHAEL, GFX1036);
       break;
-   case FAMILY_GC_10_3_7:
-      identify_chip2(GFX1037, GFX1036);
+   case FAMILY_MDN:
+      identify_chip2(MENDOCINO, GFX1036);
       break;
    case FAMILY_GFX1100:
       identify_chip(GFX1100);