amd: update addrlib

Submitted by Marek Olšák on June 14, 2019, 10:47 p.m.

Details

Message ID 20190614224732.26982-1-maraeo@gmail.com
State New
Headers show
Series "amd: update addrlib" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Marek Olšák June 14, 2019, 10:47 p.m.
From: Marek Olšák <marek.olsak@amd.com>

---

Please test and fix RADV if needed. Compressed textures may be broken.
This change contains the necessary radeonsi fixes for this addrlib.

 src/amd/addrlib/inc/addrinterface.h         |  12 +-
 src/amd/addrlib/inc/addrtypes.h             |  36 +-
 src/amd/addrlib/src/addrinterface.cpp       |   2 +-
 src/amd/addrlib/src/amdgpu_asic_addr.h      |   2 +-
 src/amd/addrlib/src/chip/gfx9/gfx9_gb_reg.h |   2 +-
 src/amd/addrlib/src/chip/r800/si_gb_reg.h   |   2 +-
 src/amd/addrlib/src/core/addrcommon.h       |  21 +-
 src/amd/addrlib/src/core/addrelemlib.cpp    |   2 +-
 src/amd/addrlib/src/core/addrelemlib.h      |   2 +-
 src/amd/addrlib/src/core/addrlib.cpp        |   3 +-
 src/amd/addrlib/src/core/addrlib.h          |   3 +-
 src/amd/addrlib/src/core/addrlib1.cpp       |   2 +-
 src/amd/addrlib/src/core/addrlib1.h         |   2 +-
 src/amd/addrlib/src/core/addrlib2.cpp       |  48 +-
 src/amd/addrlib/src/core/addrlib2.h         |  18 +-
 src/amd/addrlib/src/core/addrobject.cpp     |   2 +-
 src/amd/addrlib/src/core/addrobject.h       |   2 +-
 src/amd/addrlib/src/core/coord.cpp          |   2 +-
 src/amd/addrlib/src/core/coord.h            |   2 +-
 src/amd/addrlib/src/gfx9/gfx9addrlib.cpp    | 898 +++++++++++---------
 src/amd/addrlib/src/gfx9/gfx9addrlib.h      |  30 +-
 src/amd/addrlib/src/r800/ciaddrlib.cpp      |  16 +-
 src/amd/addrlib/src/r800/ciaddrlib.h        |   7 +-
 src/amd/addrlib/src/r800/egbaddrlib.cpp     |   4 +-
 src/amd/addrlib/src/r800/egbaddrlib.h       |   2 +-
 src/amd/addrlib/src/r800/siaddrlib.cpp      |   7 +-
 src/amd/addrlib/src/r800/siaddrlib.h        |   2 +-
 src/gallium/drivers/radeonsi/si_texture.c   |  24 +
 28 files changed, 665 insertions(+), 490 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/amd/addrlib/inc/addrinterface.h b/src/amd/addrlib/inc/addrinterface.h
index 1a2690970be..8e8f36378b3 100644
--- a/src/amd/addrlib/inc/addrinterface.h
+++ b/src/amd/addrlib/inc/addrinterface.h
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
@@ -307,7 +307,8 @@  typedef union _ADDR_CREATE_FLAGS
         UINT_32 checkLast2DLevel       : 1;    ///< Check the last 2D mip sub level
         UINT_32 useHtileSliceAlign     : 1;    ///< Do htile single slice alignment
         UINT_32 allowLargeThickTile    : 1;    ///< Allow 64*thickness*bytesPerPixel > rowSize
-        UINT_32 reserved               : 25;   ///< Reserved bits for future use
+        UINT_32 forceDccAndTcCompat    : 1;    ///< Force enable DCC and TC compatibility
+        UINT_32 reserved               : 24;   ///< Reserved bits for future use
     };
 
     UINT_32 value;
@@ -2879,6 +2880,9 @@  typedef struct _ADDR2_COMPUTE_CMASKINFO_INPUT
     UINT_32             unalignedWidth;     ///< Color surface original width
     UINT_32             unalignedHeight;    ///< Color surface original height
     UINT_32             numSlices;          ///< Number of slices of color buffer
+    UINT_32             numMipLevels;       ///< Number of mip levels
+    UINT_32             firstMipIdInTail;   ///< The id of first mip in tail, if no mip is in tail,
+                                            ///  it should be number of mip levels
 } ADDR2_COMPUTE_CMASK_INFO_INPUT;
 
 /**
@@ -2904,7 +2908,9 @@  typedef struct _ADDR2_COMPUTE_CMASK_INFO_OUTPUT
     UINT_32    metaBlkWidth;  ///< Meta block width
     UINT_32    metaBlkHeight; ///< Meta block height
 
-    UINT_32    metaBlkNumPerSlice; ///< Number of metablock within one slice
+    UINT_32    metaBlkNumPerSlice;  ///< Number of metablock within one slice
+
+    ADDR2_META_MIP_INFO* pMipInfo;  ///< CMASK mip information
 } ADDR2_COMPUTE_CMASK_INFO_OUTPUT;
 
 /**
diff --git a/src/amd/addrlib/inc/addrtypes.h b/src/amd/addrlib/inc/addrtypes.h
index c9393579b7e..36e342f3176 100644
--- a/src/amd/addrlib/inc/addrtypes.h
+++ b/src/amd/addrlib/inc/addrtypes.h
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
@@ -567,23 +567,23 @@  typedef enum _AddrHtileBlockSize
 */
 typedef enum _AddrPipeCfg
 {
-    ADDR_PIPECFG_INVALID         = 0,
-    ADDR_PIPECFG_P2              = 1, /// 2 pipes,
-    ADDR_PIPECFG_P4_8x16         = 5, /// 4 pipes,
-    ADDR_PIPECFG_P4_16x16        = 6,
-    ADDR_PIPECFG_P4_16x32        = 7,
-    ADDR_PIPECFG_P4_32x32        = 8,
-    ADDR_PIPECFG_P8_16x16_8x16   = 9, /// 8 pipes
-    ADDR_PIPECFG_P8_16x32_8x16   = 10,
-    ADDR_PIPECFG_P8_32x32_8x16   = 11,
-    ADDR_PIPECFG_P8_16x32_16x16  = 12,
-    ADDR_PIPECFG_P8_32x32_16x16  = 13,
-    ADDR_PIPECFG_P8_32x32_16x32  = 14,
-    ADDR_PIPECFG_P8_32x64_32x32  = 15,
-    ADDR_PIPECFG_P16_32x32_8x16  = 17, /// 16 pipes
-    ADDR_PIPECFG_P16_32x32_16x16 = 18,
-    ADDR_PIPECFG_RESERVED        = 19, /// reserved for internal use
-    ADDR_PIPECFG_MAX             = 20,
+    ADDR_PIPECFG_INVALID              = 0,
+    ADDR_PIPECFG_P2                   = 1, /// 2 pipes,
+    ADDR_PIPECFG_P4_8x16              = 5, /// 4 pipes,
+    ADDR_PIPECFG_P4_16x16             = 6,
+    ADDR_PIPECFG_P4_16x32             = 7,
+    ADDR_PIPECFG_P4_32x32             = 8,
+    ADDR_PIPECFG_P8_16x16_8x16        = 9, /// 8 pipes
+    ADDR_PIPECFG_P8_16x32_8x16        = 10,
+    ADDR_PIPECFG_P8_32x32_8x16        = 11,
+    ADDR_PIPECFG_P8_16x32_16x16       = 12,
+    ADDR_PIPECFG_P8_32x32_16x16       = 13,
+    ADDR_PIPECFG_P8_32x32_16x32       = 14,
+    ADDR_PIPECFG_P8_32x64_32x32       = 15,
+    ADDR_PIPECFG_P16_32x32_8x16       = 17, /// 16 pipes
+    ADDR_PIPECFG_P16_32x32_16x16      = 18,
+    ADDR_PIPECFG_UNUSED               = 19,
+    ADDR_PIPECFG_MAX                  = 20,
 } AddrPipeCfg;
 
 /**
diff --git a/src/amd/addrlib/src/addrinterface.cpp b/src/amd/addrlib/src/addrinterface.cpp
index b4eabd56062..921eed370f2 100644
--- a/src/amd/addrlib/src/addrinterface.cpp
+++ b/src/amd/addrlib/src/addrinterface.cpp
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/amd/addrlib/src/amdgpu_asic_addr.h b/src/amd/addrlib/src/amdgpu_asic_addr.h
index 41efd70e8ff..11fe4a0ecc5 100644
--- a/src/amd/addrlib/src/amdgpu_asic_addr.h
+++ b/src/amd/addrlib/src/amdgpu_asic_addr.h
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2017-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2017-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/amd/addrlib/src/chip/gfx9/gfx9_gb_reg.h b/src/amd/addrlib/src/chip/gfx9/gfx9_gb_reg.h
index ade70b9f6be..3a097964f0e 100644
--- a/src/amd/addrlib/src/chip/gfx9/gfx9_gb_reg.h
+++ b/src/amd/addrlib/src/chip/gfx9/gfx9_gb_reg.h
@@ -2,7 +2,7 @@ 
 #define __GFX9_GB_REG_H__
 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/amd/addrlib/src/chip/r800/si_gb_reg.h b/src/amd/addrlib/src/chip/r800/si_gb_reg.h
index 15711ee4b52..aa6c3fb8631 100644
--- a/src/amd/addrlib/src/chip/r800/si_gb_reg.h
+++ b/src/amd/addrlib/src/chip/r800/si_gb_reg.h
@@ -2,7 +2,7 @@ 
 #define __SI_GB_REG_H__
 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/amd/addrlib/src/core/addrcommon.h b/src/amd/addrlib/src/core/addrcommon.h
index f54f1657127..ced842a1e58 100644
--- a/src/amd/addrlib/src/core/addrcommon.h
+++ b/src/amd/addrlib/src/core/addrcommon.h
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
@@ -36,10 +36,6 @@ 
 
 #include "addrinterface.h"
 
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
 #if !defined(DEBUG)
 #ifdef NDEBUG
 #define DEBUG 0
@@ -48,6 +44,14 @@ 
 #endif
 #endif
 
+// ADDR_LNX_KERNEL_BUILD is for internal build
+// Moved from addrinterface.h so __KERNEL__ is not needed any more
+#if   !defined(__APPLE__) || defined(HAVE_TSERVER)
+    #include <stdlib.h>
+    #include <string.h>
+    #include <assert.h>
+#endif
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Platform specific debug break defines
 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -152,7 +156,11 @@ 
 #endif // DEBUG
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
+#if defined(static_assert)
+#define ADDR_C_ASSERT(__e) static_assert(__e, "")
+#else
 #define ADDR_C_ASSERT(__e) typedef char __ADDR_C_ASSERT__[(__e) ? 1 : -1]
+#endif
 
 namespace Addr
 {
@@ -260,7 +268,8 @@  union ConfigFlags
         UINT_32 allowLargeThickTile    : 1;    ///< Allow 64*thickness*bytesPerPixel > rowSize
         UINT_32 disableLinearOpt       : 1;    ///< Disallow tile modes to be optimized to linear
         UINT_32 use32bppFor422Fmt      : 1;    ///< View 422 formats as 32 bits per pixel element
-        UINT_32 reserved               : 21;   ///< Reserved bits for future use
+        UINT_32 forceDccAndTcCompat    : 1;    ///< Force enable DCC and TC compatibility
+        UINT_32 reserved               : 20;   ///< Reserved bits for future use
     };
 
     UINT_32 value;
diff --git a/src/amd/addrlib/src/core/addrelemlib.cpp b/src/amd/addrlib/src/core/addrelemlib.cpp
index 71c0ba74df9..27afb593b65 100644
--- a/src/amd/addrlib/src/core/addrelemlib.cpp
+++ b/src/amd/addrlib/src/core/addrelemlib.cpp
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/amd/addrlib/src/core/addrelemlib.h b/src/amd/addrlib/src/core/addrelemlib.h
index 633f94cd207..519e194f3dd 100644
--- a/src/amd/addrlib/src/core/addrelemlib.h
+++ b/src/amd/addrlib/src/core/addrelemlib.h
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/amd/addrlib/src/core/addrlib.cpp b/src/amd/addrlib/src/core/addrlib.cpp
index bdc17ffedcb..ceb5ef826a5 100644
--- a/src/amd/addrlib/src/core/addrlib.cpp
+++ b/src/amd/addrlib/src/core/addrlib.cpp
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
@@ -246,6 +246,7 @@  ADDR_E_RETURNCODE Lib::Create(
         pLib->m_configFlags.checkLast2DLevel    = pCreateIn->createFlags.checkLast2DLevel;
         pLib->m_configFlags.useHtileSliceAlign  = pCreateIn->createFlags.useHtileSliceAlign;
         pLib->m_configFlags.allowLargeThickTile = pCreateIn->createFlags.allowLargeThickTile;
+        pLib->m_configFlags.forceDccAndTcCompat = pCreateIn->createFlags.forceDccAndTcCompat;
         pLib->m_configFlags.disableLinearOpt    = FALSE;
 
         pLib->SetChipFamily(pCreateIn->chipFamily, pCreateIn->chipRevision);
diff --git a/src/amd/addrlib/src/core/addrlib.h b/src/amd/addrlib/src/core/addrlib.h
index 70c74f917d9..d0a135b31fc 100644
--- a/src/amd/addrlib/src/core/addrlib.h
+++ b/src/amd/addrlib/src/core/addrlib.h
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
@@ -409,7 +409,6 @@  private:
 Lib* SiHwlInit   (const Client* pClient);
 Lib* CiHwlInit   (const Client* pClient);
 Lib* Gfx9HwlInit (const Client* pClient);
-
 } // Addr
 
 #endif
diff --git a/src/amd/addrlib/src/core/addrlib1.cpp b/src/amd/addrlib/src/core/addrlib1.cpp
index 65f8fe01492..0704e0f4e1f 100644
--- a/src/amd/addrlib/src/core/addrlib1.cpp
+++ b/src/amd/addrlib/src/core/addrlib1.cpp
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/amd/addrlib/src/core/addrlib1.h b/src/amd/addrlib/src/core/addrlib1.h
index 4933a53f128..5411d1c1a84 100644
--- a/src/amd/addrlib/src/core/addrlib1.h
+++ b/src/amd/addrlib/src/core/addrlib1.h
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/amd/addrlib/src/core/addrlib2.cpp b/src/amd/addrlib/src/core/addrlib2.cpp
index 3b4b8debf43..e6440d6ca5c 100644
--- a/src/amd/addrlib/src/core/addrlib2.cpp
+++ b/src/amd/addrlib/src/core/addrlib2.cpp
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
@@ -63,7 +63,17 @@  const Dim3d Lib::Block1K_3d[]  = {{16, 8, 8}, {8, 8, 8}, {8, 8, 4}, {8, 4, 4}, {
 */
 Lib::Lib()
     :
-    Addr::Lib()
+    Addr::Lib(),
+    m_se(0),
+    m_rbPerSe(0),
+    m_maxCompFrag(0),
+    m_banksLog2(0),
+    m_pipesLog2(0),
+    m_seLog2(0),
+    m_rbPerSeLog2(0),
+    m_maxCompFragLog2(0),
+    m_pipeInterleaveLog2(0),
+    m_blockVarSizeLog2(0)
 {
 }
 
@@ -78,7 +88,17 @@  Lib::Lib()
 */
 Lib::Lib(const Client* pClient)
     :
-    Addr::Lib(pClient)
+    Addr::Lib(pClient),
+    m_se(0),
+    m_rbPerSe(0),
+    m_maxCompFrag(0),
+    m_banksLog2(0),
+    m_pipesLog2(0),
+    m_seLog2(0),
+    m_rbPerSeLog2(0),
+    m_maxCompFragLog2(0),
+    m_pipeInterleaveLog2(0),
+    m_blockVarSizeLog2(0)
 {
 }
 
@@ -1692,28 +1712,6 @@  UINT_32 Lib::GetPipeXorBits(
     return pipeBits;
 }
 
-/**
-************************************************************************************************************************
-*   Lib::GetBankXorBits
-*
-*   @brief
-*       Internal function to get bits number for pipe/se xor operation
-*
-*   @return
-*       ADDR_E_RETURNCODE
-************************************************************************************************************************
-*/
-UINT_32 Lib::GetBankXorBits(
-    UINT_32 macroBlockBits) const
-{
-    UINT_32 pipeBits = GetPipeXorBits(macroBlockBits);
-
-    // Bank xor bits
-    UINT_32 bankBits = Min(macroBlockBits - pipeBits - m_pipeInterleaveLog2, m_banksLog2);
-
-    return bankBits;
-}
-
 /**
 ************************************************************************************************************************
 *   Lib::Addr2GetPreferredSurfaceSetting
diff --git a/src/amd/addrlib/src/core/addrlib2.h b/src/amd/addrlib/src/core/addrlib2.h
index e72dd43678d..258607b8d77 100644
--- a/src/amd/addrlib/src/core/addrlib2.h
+++ b/src/amd/addrlib/src/core/addrlib2.h
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
@@ -691,21 +691,6 @@  protected:
         UINT_32           blockHeight,
         UINT_32           blockDepth) const;
 
-    BOOL_32 IsInMipTail(
-        AddrResourceType  resourceType,
-        AddrSwizzleMode   swizzleMode,
-        Dim3d             mipTailDim,
-        UINT_32           width,
-        UINT_32           height,
-        UINT_32           depth) const
-    {
-        BOOL_32 inTail = ((width <= mipTailDim.w) &&
-                          (height <= mipTailDim.h) &&
-                          (IsThin(resourceType, swizzleMode) || (depth <= mipTailDim.d)));
-
-        return inTail;
-    }
-
     static BOOL_32 IsLocalHeap(AddrResrouceLocation resourceType)
     {
         return ((resourceType == ADDR_RSRC_LOC_LOCAL) ||
@@ -794,7 +779,6 @@  protected:
     }
 
     UINT_32 GetPipeXorBits(UINT_32 macroBlockBits) const;
-    UINT_32 GetBankXorBits(UINT_32 macroBlockBits) const;
 
     ADDR_E_RETURNCODE ApplyCustomizedPitchHeight(
         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,
diff --git a/src/amd/addrlib/src/core/addrobject.cpp b/src/amd/addrlib/src/core/addrobject.cpp
index 5f262c3e9e2..79ef3d8dc90 100644
--- a/src/amd/addrlib/src/core/addrobject.cpp
+++ b/src/amd/addrlib/src/core/addrobject.cpp
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/amd/addrlib/src/core/addrobject.h b/src/amd/addrlib/src/core/addrobject.h
index 069bb78dee0..05559757712 100644
--- a/src/amd/addrlib/src/core/addrobject.h
+++ b/src/amd/addrlib/src/core/addrobject.h
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/amd/addrlib/src/core/coord.cpp b/src/amd/addrlib/src/core/coord.cpp
index 7fd6bc9173b..9ed0f9db50b 100644
--- a/src/amd/addrlib/src/core/coord.cpp
+++ b/src/amd/addrlib/src/core/coord.cpp
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/amd/addrlib/src/core/coord.h b/src/amd/addrlib/src/core/coord.h
index ce40a3ee1f5..72e93e0a187 100644
--- a/src/amd/addrlib/src/core/coord.h
+++ b/src/amd/addrlib/src/core/coord.h
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/amd/addrlib/src/gfx9/gfx9addrlib.cpp b/src/amd/addrlib/src/gfx9/gfx9addrlib.cpp
index 9be775f35f9..f4e3b47cf9d 100644
--- a/src/amd/addrlib/src/gfx9/gfx9addrlib.cpp
+++ b/src/amd/addrlib/src/gfx9/gfx9addrlib.cpp
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
@@ -136,8 +136,8 @@  Gfx9Lib::Gfx9Lib(const Client* pClient)
     m_class = AI_ADDRLIB;
     memset(&m_settings, 0, sizeof(m_settings));
     memcpy(m_swizzleModeTable, SwizzleModeTable, sizeof(SwizzleModeTable));
-    m_metaEqOverrideIndex = 0;
     memset(m_cachedMetaEqKey, 0, sizeof(m_cachedMetaEqKey));
+    m_metaEqOverrideIndex = 0;
 }
 
 /**
@@ -1233,6 +1233,7 @@  BOOL_32 Gfx9Lib::HwlInitGlobalParams(
         {
             ADDR_ASSERT(m_settings.isVega10 == FALSE);
             ADDR_ASSERT(m_settings.isRaven == FALSE);
+
             ADDR_ASSERT(m_settings.isVega20 == FALSE);
 
             if (m_settings.isVega12)
@@ -2934,13 +2935,9 @@  BOOL_32 Gfx9Lib::IsValidDisplaySwizzleMode(
 {
     BOOL_32 support = FALSE;
 
-    const AddrResourceType resourceType = pIn->resourceType;
-    (void)resourceType;
-    const AddrSwizzleMode swizzleMode = pIn->swizzleMode;
-
     if (m_settings.isDce12)
     {
-        switch (swizzleMode)
+        switch (pIn->swizzleMode)
         {
             case ADDR_SW_256B_D:
             case ADDR_SW_256B_R:
@@ -2969,7 +2966,7 @@  BOOL_32 Gfx9Lib::IsValidDisplaySwizzleMode(
     }
     else if (m_settings.isDcn1)
     {
-        switch (swizzleMode)
+        switch (pIn->swizzleMode)
         {
             case ADDR_SW_4KB_D:
             case ADDR_SW_64KB_D:
@@ -3117,134 +3114,248 @@  ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSubResourceOffsetForSwizzlePattern(
 
 /**
 ************************************************************************************************************************
-*   Gfx9Lib::HwlComputeSurfaceInfoSanityCheck
+*   Gfx9Lib::ValidateNonSwModeParams
 *
 *   @brief
-*       Compute surface info sanity check
+*       Validate compute surface info params except swizzle mode
 *
 *   @return
-*       Offset
+*       TRUE if parameters are valid, FALSE otherwise
 ************************************************************************************************************************
 */
-ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceInfoSanityCheck(
+BOOL_32 Gfx9Lib::ValidateNonSwModeParams(
     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const
 {
-    BOOL_32 invalid = FALSE;
+    BOOL_32 valid = TRUE;
 
-    if ((pIn->bpp > 128) || (pIn->width == 0) || (pIn->numFrags > 8) || (pIn->numSamples > 16))
+    if ((pIn->bpp == 0) || (pIn->bpp > 128) || (pIn->width == 0) || (pIn->numFrags > 8) || (pIn->numSamples > 16))
     {
-        invalid = TRUE;
+        ADDR_ASSERT_ALWAYS();
+        valid = FALSE;
     }
-    else if ((pIn->swizzleMode >= ADDR_SW_MAX_TYPE)    ||
-             (pIn->resourceType >= ADDR_RSRC_MAX_TYPE))
+
+    if (pIn->resourceType >= ADDR_RSRC_MAX_TYPE)
     {
-        invalid = TRUE;
+        ADDR_ASSERT_ALWAYS();
+        valid = FALSE;
     }
 
-    BOOL_32 mipmap = (pIn->numMipLevels > 1);
-    BOOL_32 msaa   = (pIn->numFrags > 1);
-
-    ADDR2_SURFACE_FLAGS flags = pIn->flags;
-    BOOL_32 zbuffer = (flags.depth || flags.stencil);
-    BOOL_32 color   = flags.color;
-    BOOL_32 display = flags.display || flags.rotated;
-
-    AddrResourceType rsrcType    = pIn->resourceType;
-    BOOL_32          tex3d       = IsTex3d(rsrcType);
-    BOOL_32          thin3d      = tex3d && flags.view3dAs2dArray;
-    AddrSwizzleMode  swizzle     = pIn->swizzleMode;
-    BOOL_32          linear      = IsLinear(swizzle);
-    BOOL_32          blk256B     = IsBlock256b(swizzle);
-    BOOL_32          blkVar      = IsBlockVariable(swizzle);
-    BOOL_32          isNonPrtXor = IsNonPrtXor(swizzle);
-    BOOL_32          prt         = flags.prt;
-    BOOL_32          stereo      = flags.qbStereo;
-
-    if (invalid == FALSE)
+    const BOOL_32 mipmap = (pIn->numMipLevels > 1);
+    const BOOL_32 msaa   = (pIn->numFrags > 1);
+    const BOOL_32 isBc   = ElemLib::IsBlockCompressed(pIn->format);
+
+    const AddrResourceType rsrcType = pIn->resourceType;
+    const BOOL_32          tex3d    = IsTex3d(rsrcType);
+    const BOOL_32          tex2d    = IsTex2d(rsrcType);
+    const BOOL_32          tex1d    = IsTex1d(rsrcType);
+
+    const ADDR2_SURFACE_FLAGS flags   = pIn->flags;
+    const BOOL_32             zbuffer = flags.depth || flags.stencil;
+    const BOOL_32             display = flags.display || flags.rotated;
+    const BOOL_32             stereo  = flags.qbStereo;
+    const BOOL_32             fmask   = flags.fmask;
+
+    // Resource type check
+    if (tex1d)
     {
-        if ((pIn->numFrags > 1) &&
-            (GetBlockSize(swizzle) < (m_pipeInterleaveBytes * pIn->numFrags)))
+        if (msaa || zbuffer || display || stereo || isBc || fmask)
         {
-            // MSAA surface must have blk_bytes/pipe_interleave >= num_samples
-            invalid = TRUE;
+            ADDR_ASSERT_ALWAYS();
+            valid = FALSE;
         }
     }
-
-    if (invalid == FALSE)
+    else if (tex2d)
     {
-        switch (rsrcType)
+        if ((msaa && mipmap) || (stereo && msaa) || (stereo && mipmap))
         {
-            case ADDR_RSRC_TEX_1D:
-                invalid = msaa || zbuffer || display || (linear == FALSE) || stereo;
-                break;
-            case ADDR_RSRC_TEX_2D:
-                invalid = (msaa && mipmap) || (stereo && msaa) || (stereo && mipmap);
-                break;
-            case ADDR_RSRC_TEX_3D:
-                invalid = msaa || zbuffer || display || stereo;
-                break;
-            default:
-                invalid = TRUE;
-                break;
+            ADDR_ASSERT_ALWAYS();
+            valid = FALSE;
         }
     }
+    else if (tex3d)
+    {
+        if (msaa || zbuffer || display || stereo || fmask)
+        {
+            ADDR_ASSERT_ALWAYS();
+            valid = FALSE;
+        }
+    }
+    else
+    {
+        ADDR_ASSERT_ALWAYS();
+        valid = FALSE;
+    }
 
-    if (invalid == FALSE)
+    return valid;
+}
+
+/**
+************************************************************************************************************************
+*   Gfx9Lib::ValidateSwModeParams
+*
+*   @brief
+*       Validate compute surface info related to swizzle mode
+*
+*   @return
+*       TRUE if parameters are valid, FALSE otherwise
+************************************************************************************************************************
+*/
+BOOL_32 Gfx9Lib::ValidateSwModeParams(
+    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const
+{
+    BOOL_32 valid = TRUE;
+
+    if (pIn->swizzleMode >= ADDR_SW_MAX_TYPE)
+    {
+        ADDR_ASSERT_ALWAYS();
+        valid = FALSE;
+    }
+
+    const BOOL_32 mipmap = (pIn->numMipLevels > 1);
+    const BOOL_32 msaa   = (pIn->numFrags > 1);
+    const BOOL_32 isBc   = ElemLib::IsBlockCompressed(pIn->format);
+    const BOOL_32 is422  = ElemLib::IsMacroPixelPacked(pIn->format);
+
+    const AddrResourceType rsrcType = pIn->resourceType;
+    const BOOL_32          tex3d    = IsTex3d(rsrcType);
+    const BOOL_32          tex2d    = IsTex2d(rsrcType);
+    const BOOL_32          tex1d    = IsTex1d(rsrcType);
+
+    const AddrSwizzleMode  swizzle     = pIn->swizzleMode;
+    const BOOL_32          linear      = IsLinear(swizzle);
+    const BOOL_32          blk256B     = IsBlock256b(swizzle);
+    const BOOL_32          blkVar      = IsBlockVariable(swizzle);
+    const BOOL_32          isNonPrtXor = IsNonPrtXor(swizzle);
+
+    const ADDR2_SURFACE_FLAGS flags   = pIn->flags;
+    const BOOL_32             zbuffer = flags.depth || flags.stencil;
+    const BOOL_32             color   = flags.color;
+    const BOOL_32             texture = flags.texture;
+    const BOOL_32             display = flags.display || flags.rotated;
+    const BOOL_32             prt     = flags.prt;
+    const BOOL_32             fmask   = flags.fmask;
+
+    const BOOL_32             thin3d  = tex3d && flags.view3dAs2dArray;
+    const BOOL_32             zMaxMip = tex3d && mipmap &&
+                                        (pIn->numSlices >= pIn->width) && (pIn->numSlices >= pIn->height);
+
+    // Misc check
+    if (msaa && (GetBlockSize(swizzle) < (m_pipeInterleaveBytes * pIn->numFrags)))
+    {
+        // MSAA surface must have blk_bytes/pipe_interleave >= num_samples
+        ADDR_ASSERT_ALWAYS();
+        valid = FALSE;
+    }
+
+    if (display && (IsValidDisplaySwizzleMode(pIn) == FALSE))
+    {
+        ADDR_ASSERT_ALWAYS();
+        valid = FALSE;
+    }
+
+    if ((pIn->bpp == 96) && (linear == FALSE))
+    {
+        ADDR_ASSERT_ALWAYS();
+        valid = FALSE;
+    }
+
+    if (prt && isNonPrtXor)
     {
-        if (display)
+        ADDR_ASSERT_ALWAYS();
+        valid = FALSE;
+    }
+
+    // Resource type check
+    if (tex1d)
+    {
+        if (linear == FALSE)
         {
-            invalid = (IsValidDisplaySwizzleMode(pIn) == FALSE);
+            ADDR_ASSERT_ALWAYS();
+            valid = FALSE;
         }
     }
 
-    if (invalid == FALSE)
+    // Swizzle type check
+    if (linear)
     {
-        if (linear)
+        if (((tex1d == FALSE) && prt) || zbuffer || msaa || (pIn->bpp == 0) ||
+            ((pIn->bpp % 8) != 0) || (isBc && texture) || fmask)
         {
-            invalid = ((ADDR_RSRC_TEX_1D != rsrcType) && prt) ||
-                      zbuffer || msaa || (pIn->bpp == 0) || ((pIn->bpp % 8) != 0);
+            ADDR_ASSERT_ALWAYS();
+            valid = FALSE;
         }
-        else
+    }
+    else if (IsZOrderSwizzle(swizzle))
+    {
+        if ((color && msaa) || thin3d || isBc || is422 || (tex2d && (pIn->bpp > 64)) || (msaa && (pIn->bpp > 32)))
         {
-            if (blk256B || blkVar || isNonPrtXor)
-            {
-                invalid = prt;
-                if (blk256B)
-                {
-                    invalid = invalid || zbuffer || tex3d || mipmap || msaa;
-                }
-            }
+            ADDR_ASSERT_ALWAYS();
+            valid = FALSE;
+        }
+    }
+    else if (IsStandardSwizzle(swizzle))
+    {
+        if (zbuffer || thin3d || (tex3d && (pIn->bpp == 128) && color) || fmask)
+        {
+            ADDR_ASSERT_ALWAYS();
+            valid = FALSE;
+        }
+    }
+    else if (IsDisplaySwizzle(swizzle))
+    {
+        if (zbuffer || (prt && tex3d) || fmask || zMaxMip)
+        {
+            ADDR_ASSERT_ALWAYS();
+            valid = FALSE;
+        }
+    }
+    else if (IsRotateSwizzle(swizzle))
+    {
+        if (zbuffer || (pIn->bpp > 64) || tex3d || isBc || fmask)
+        {
+            ADDR_ASSERT_ALWAYS();
+            valid = FALSE;
+        }
+    }
+    else
+    {
+        ADDR_ASSERT_ALWAYS();
+        valid = FALSE;
+    }
 
-            if (invalid == FALSE)
-            {
-                if (IsZOrderSwizzle(swizzle))
-                {
-                    invalid = (color && msaa) || thin3d;
-                }
-                else if (IsStandardSwizzle(swizzle))
-                {
-                    invalid = zbuffer || thin3d;
-                }
-                else if (IsDisplaySwizzle(swizzle))
-                {
-                    invalid = zbuffer || (prt && (ADDR_RSRC_TEX_3D == rsrcType));
-                }
-                else if (IsRotateSwizzle(swizzle))
-                {
-                    invalid = zbuffer || (pIn->bpp > 64) || tex3d;
-                }
-                else
-                {
-                    ADDR_ASSERT(!"invalid swizzle mode");
-                    invalid = TRUE;
-                }
-            }
+    // Block type check
+    if (blk256B)
+    {
+        if (prt || zbuffer || tex3d || mipmap || msaa)
+        {
+            ADDR_ASSERT_ALWAYS();
+            valid = FALSE;
         }
     }
+    else if (blkVar)
+    {
+        ADDR_ASSERT_ALWAYS();
+        valid = FALSE;
+    }
 
-    ADDR_ASSERT(invalid == FALSE);
+    return valid;
+}
 
-    return invalid ? ADDR_INVALIDPARAMS : ADDR_OK;
+/**
+************************************************************************************************************************
+*   Gfx9Lib::HwlComputeSurfaceInfoSanityCheck
+*
+*   @brief
+*       Compute surface info sanity check
+*
+*   @return
+*       ADDR_OK if parameters are valid, ADDR_INVALIDPARAMS otherwise
+************************************************************************************************************************
+*/
+ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceInfoSanityCheck(
+    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const
+{
+    return ValidateNonSwModeParams(pIn) && ValidateSwModeParams(pIn) ? ADDR_OK : ADDR_INVALIDPARAMS;
 }
 
 /**
@@ -3262,14 +3373,14 @@  ADDR_E_RETURNCODE Gfx9Lib::HwlGetPreferredSurfaceSetting(
     const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
     ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const
 {
-    ADDR_E_RETURNCODE returnCode = ADDR_OK;
+    ADDR_E_RETURNCODE returnCode = ADDR_INVALIDPARAMS;
     ElemLib*          pElemLib   = GetElemLib();
 
-    UINT_32 bpp          = pIn->bpp;
-    UINT_32 width        = pIn->width;
-    UINT_32 height       = pIn->height;
-    UINT_32 numSamples   = Max(pIn->numSamples, 1u);
-    UINT_32 numFrags     = (pIn->numFrags == 0) ? numSamples : pIn->numFrags;
+    UINT_32 bpp        = pIn->bpp;
+    UINT_32 width      = Max(pIn->width, 1u);
+    UINT_32 height     = Max(pIn->height, 1u);
+    UINT_32 numSamples = Max(pIn->numSamples, 1u);
+    UINT_32 numFrags   = (pIn->numFrags == 0) ? numSamples : pIn->numFrags;
 
     if (pIn->flags.fmask)
     {
@@ -3313,378 +3424,389 @@  ADDR_E_RETURNCODE Gfx9Lib::HwlGetPreferredSurfaceSetting(
     const BOOL_32 msaa         = (numFrags > 1) || (numSamples > 1);
     const BOOL_32 displayRsrc  = pIn->flags.display || pIn->flags.rotated;
 
-    // Forbid swizzle mode(s) by client setting, for simplicity we never allow VAR swizzle mode for GFX9
-    ADDR2_SWMODE_SET allowedSwModeSet = {};
-    allowedSwModeSet.value |= pIn->forbiddenBlock.linear    ? 0 : Gfx9LinearSwModeMask;
-    allowedSwModeSet.value |= pIn->forbiddenBlock.micro     ? 0 : Gfx9Blk256BSwModeMask;
-    allowedSwModeSet.value |= pIn->forbiddenBlock.macro4KB  ? 0 : Gfx9Blk4KBSwModeMask;
-    allowedSwModeSet.value |= pIn->forbiddenBlock.macro64KB ? 0 : Gfx9Blk64KBSwModeMask;
-
-    if (pIn->preferredSwSet.value != 0)
-    {
-        allowedSwModeSet.value &= pIn->preferredSwSet.sw_Z ? ~0 : ~Gfx9ZSwModeMask;
-        allowedSwModeSet.value &= pIn->preferredSwSet.sw_S ? ~0 : ~Gfx9StandardSwModeMask;
-        allowedSwModeSet.value &= pIn->preferredSwSet.sw_D ? ~0 : ~Gfx9DisplaySwModeMask;
-        allowedSwModeSet.value &= pIn->preferredSwSet.sw_R ? ~0 : ~Gfx9RotateSwModeMask;
-    }
-
-    if (pIn->noXor)
-    {
-        allowedSwModeSet.value &= ~Gfx9XorSwModeMask;
-    }
-
-    if (pIn->maxAlign > 0)
+    // Pre sanity check on non swizzle mode parameters
+    ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {};
+    localIn.flags        = pIn->flags;
+    localIn.resourceType = pOut->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     = numFrags;
+
+    if (ValidateNonSwModeParams(&localIn))
     {
-        if (pIn->maxAlign < GetBlockSize(ADDR_SW_64KB))
+        // Forbid swizzle mode(s) by client setting, for simplicity we never allow VAR swizzle mode for GFX9
+        ADDR2_SWMODE_SET allowedSwModeSet = {};
+        allowedSwModeSet.value |= pIn->forbiddenBlock.linear    ? 0 : Gfx9LinearSwModeMask;
+        allowedSwModeSet.value |= pIn->forbiddenBlock.micro     ? 0 : Gfx9Blk256BSwModeMask;
+        allowedSwModeSet.value |= pIn->forbiddenBlock.macro4KB  ? 0 : Gfx9Blk4KBSwModeMask;
+        allowedSwModeSet.value |= pIn->forbiddenBlock.macro64KB ? 0 : Gfx9Blk64KBSwModeMask;
+
+        if (pIn->preferredSwSet.value != 0)
         {
-            allowedSwModeSet.value &= ~Gfx9Blk64KBSwModeMask;
+            allowedSwModeSet.value &= pIn->preferredSwSet.sw_Z ? ~0 : ~Gfx9ZSwModeMask;
+            allowedSwModeSet.value &= pIn->preferredSwSet.sw_S ? ~0 : ~Gfx9StandardSwModeMask;
+            allowedSwModeSet.value &= pIn->preferredSwSet.sw_D ? ~0 : ~Gfx9DisplaySwModeMask;
+            allowedSwModeSet.value &= pIn->preferredSwSet.sw_R ? ~0 : ~Gfx9RotateSwModeMask;
         }
 
-        if (pIn->maxAlign < GetBlockSize(ADDR_SW_4KB))
+        if (pIn->noXor)
         {
-            allowedSwModeSet.value &= ~Gfx9Blk4KBSwModeMask;
+            allowedSwModeSet.value &= ~Gfx9XorSwModeMask;
         }
 
-        if (pIn->maxAlign < GetBlockSize(ADDR_SW_256B))
+        if (pIn->maxAlign > 0)
         {
-            allowedSwModeSet.value &= ~Gfx9Blk256BSwModeMask;
-        }
-    }
-
-    // Filter out invalid swizzle mode(s) by image attributes and HW restrictions
-    switch (pOut->resourceType)
-    {
-        case ADDR_RSRC_TEX_1D:
-            allowedSwModeSet.value &= Gfx9Rsrc1dSwModeMask;
-            break;
-
-        case ADDR_RSRC_TEX_2D:
-            allowedSwModeSet.value &= pIn->flags.prt ? Gfx9Rsrc2dPrtSwModeMask : Gfx9Rsrc2dSwModeMask;
-
-            if (bpp > 64)
+            if (pIn->maxAlign < GetBlockSize(ADDR_SW_64KB))
             {
-                allowedSwModeSet.value &= ~(Gfx9RotateSwModeMask | Gfx9ZSwModeMask);
+                allowedSwModeSet.value &= ~Gfx9Blk64KBSwModeMask;
             }
-            break;
 
-        case ADDR_RSRC_TEX_3D:
-            allowedSwModeSet.value &= pIn->flags.prt ? Gfx9Rsrc3dPrtSwModeMask : Gfx9Rsrc3dSwModeMask;
-
-            if ((numMipLevels > 1) && (numSlices >= width) && (numSlices >= height))
+            if (pIn->maxAlign < GetBlockSize(ADDR_SW_4KB))
             {
-                // SW_*_D for 3D mipmaps (maxmip > 0) is only supported for Xmajor or Ymajor mipmap
-                // When depth (Z) is the maximum dimension then must use one of the SW_*_S
-                // or SW_*_Z modes if mipmapping is desired on a 3D surface
-                allowedSwModeSet.value &= ~Gfx9DisplaySwModeMask;
+                allowedSwModeSet.value &= ~Gfx9Blk4KBSwModeMask;
             }
 
-            if ((bpp == 128) && pIn->flags.color)
+            if (pIn->maxAlign < GetBlockSize(ADDR_SW_256B))
             {
-                allowedSwModeSet.value &= ~Gfx9StandardSwModeMask;
+                allowedSwModeSet.value &= ~Gfx9Blk256BSwModeMask;
             }
+        }
 
-            if (pIn->flags.view3dAs2dArray)
-            {
-                allowedSwModeSet.value &= Gfx9Rsrc3dThinSwModeMask | Gfx9LinearSwModeMask;
-            }
-            break;
+        // Filter out invalid swizzle mode(s) by image attributes and HW restrictions
+        switch (pOut->resourceType)
+        {
+            case ADDR_RSRC_TEX_1D:
+                allowedSwModeSet.value &= Gfx9Rsrc1dSwModeMask;
+                break;
 
-        default:
-            ADDR_ASSERT_ALWAYS();
-            allowedSwModeSet.value = 0;
-            break;
-    }
+            case ADDR_RSRC_TEX_2D:
+                allowedSwModeSet.value &= pIn->flags.prt ? Gfx9Rsrc2dPrtSwModeMask : Gfx9Rsrc2dSwModeMask;
 
-    if (pIn->format == ADDR_FMT_32_32_32)
-    {
-        allowedSwModeSet.value &= Gfx9LinearSwModeMask;
-    }
+                if (bpp > 64)
+                {
+                    allowedSwModeSet.value &= ~(Gfx9RotateSwModeMask | Gfx9ZSwModeMask);
+                }
+                break;
 
-    if (ElemLib::IsBlockCompressed(pIn->format))
-    {
-        if (pIn->flags.texture)
-        {
-            allowedSwModeSet.value &= Gfx9StandardSwModeMask | Gfx9DisplaySwModeMask;
+            case ADDR_RSRC_TEX_3D:
+                allowedSwModeSet.value &= pIn->flags.prt ? Gfx9Rsrc3dPrtSwModeMask : Gfx9Rsrc3dSwModeMask;
+
+                if ((numMipLevels > 1) && (numSlices >= width) && (numSlices >= height))
+                {
+                    // SW_*_D for 3D mipmaps (maxmip > 0) is only supported for Xmajor or Ymajor mipmap
+                    // When depth (Z) is the maximum dimension then must use one of the SW_*_S
+                    // or SW_*_Z modes if mipmapping is desired on a 3D surface
+                    allowedSwModeSet.value &= ~Gfx9DisplaySwModeMask;
+                }
+
+                if ((bpp == 128) && pIn->flags.color)
+                {
+                    allowedSwModeSet.value &= ~Gfx9StandardSwModeMask;
+                }
+
+                if (pIn->flags.view3dAs2dArray)
+                {
+                    allowedSwModeSet.value &= Gfx9Rsrc3dThinSwModeMask | Gfx9LinearSwModeMask;
+                }
+                break;
+
+            default:
+                ADDR_ASSERT_ALWAYS();
+                allowedSwModeSet.value = 0;
+                break;
         }
-        else
+
+        if (pIn->format == ADDR_FMT_32_32_32)
         {
-            allowedSwModeSet.value &= Gfx9StandardSwModeMask | Gfx9DisplaySwModeMask | Gfx9LinearSwModeMask;
+            allowedSwModeSet.value &= Gfx9LinearSwModeMask;
         }
-    }
 
-    if (ElemLib::IsMacroPixelPacked(pIn->format) ||
-        (msaa && ((bpp > 32) || pIn->flags.color || pIn->flags.unordered)))
-    {
-        allowedSwModeSet.value &= ~Gfx9ZSwModeMask;
-    }
-
-    if (pIn->flags.fmask || pIn->flags.depth || pIn->flags.stencil)
-    {
-        allowedSwModeSet.value &= Gfx9ZSwModeMask;
-
-        if (pIn->flags.noMetadata == FALSE)
+        if (ElemLib::IsBlockCompressed(pIn->format))
         {
-            if (pIn->flags.depth &&
-                pIn->flags.texture &&
-                (((bpp == 16) && (numFrags >= 4)) || ((bpp == 32) && (numFrags >= 2))))
+            if (pIn->flags.texture)
             {
-                // When _X/_T swizzle mode was used for MSAA depth texture, TC will get zplane
-                // equation from wrong address within memory range a tile covered and use the
-                // garbage data for compressed Z reading which finally leads to corruption.
-                allowedSwModeSet.value &= ~Gfx9XorSwModeMask;
+                allowedSwModeSet.value &= Gfx9StandardSwModeMask | Gfx9DisplaySwModeMask;
             }
-
-            if (m_settings.htileCacheRbConflict &&
-                (pIn->flags.depth || pIn->flags.stencil) &&
-                (numSlices > 1) &&
-                (pIn->flags.metaRbUnaligned == FALSE) &&
-                (pIn->flags.metaPipeUnaligned == FALSE))
+            else
             {
-                // Z_X 2D array with Rb/Pipe aligned HTile won't have metadata cache coherency
-                allowedSwModeSet.value &= ~Gfx9XSwModeMask;
+                allowedSwModeSet.value &= Gfx9StandardSwModeMask | Gfx9DisplaySwModeMask | Gfx9LinearSwModeMask;
             }
         }
-    }
 
-    if (msaa)
-    {
-        allowedSwModeSet.value &= Gfx9MsaaSwModeMask;
-    }
-
-    if ((numFrags > 1) &&
-        (GetBlockSize(ADDR_SW_4KB) < (m_pipeInterleaveBytes * numFrags)))
-    {
-        // MSAA surface must have blk_bytes/pipe_interleave >= num_samples
-        allowedSwModeSet.value &= Gfx9Blk64KBSwModeMask;
-    }
-
-    if (numMipLevels > 1)
-    {
-        allowedSwModeSet.value &= ~Gfx9Blk256BSwModeMask;
-    }
-
-    if (displayRsrc)
-    {
-        if (m_settings.isDce12)
+        if (ElemLib::IsMacroPixelPacked(pIn->format) ||
+            (msaa && ((bpp > 32) || pIn->flags.color || pIn->flags.unordered)))
         {
-            allowedSwModeSet.value &= (bpp == 32) ? Dce12Bpp32SwModeMask : Dce12NonBpp32SwModeMask;
+            allowedSwModeSet.value &= ~Gfx9ZSwModeMask;
         }
-        else if (m_settings.isDcn1)
-        {
-            allowedSwModeSet.value &= (bpp == 64) ? Dcn1Bpp64SwModeMask : Dcn1NonBpp64SwModeMask;
-        }
-        else
-        {
-            ADDR_NOT_IMPLEMENTED();
-        }
-    }
 
-    if (allowedSwModeSet.value != 0)
-    {
-#if DEBUG
-        // Post sanity check, at least AddrLib should accept the output generated by its own
-        ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {};
-        localIn.flags        = pIn->flags;
-        localIn.resourceType = pOut->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     = numFrags;
-
-        UINT_32 validateSwModeSet = allowedSwModeSet.value;
-        for (UINT_32 i = 0; validateSwModeSet != 0; i++)
+        if (pIn->flags.fmask || pIn->flags.depth || pIn->flags.stencil)
         {
-            if (validateSwModeSet & 1)
+            allowedSwModeSet.value &= Gfx9ZSwModeMask;
+
+            if (pIn->flags.noMetadata == FALSE)
             {
-                localIn.swizzleMode = static_cast<AddrSwizzleMode>(i);
-                HwlComputeSurfaceInfoSanityCheck(&localIn);
-            }
+                if (pIn->flags.depth &&
+                    pIn->flags.texture &&
+                    (((bpp == 16) && (numFrags >= 4)) || ((bpp == 32) && (numFrags >= 2))))
+                {
+                    // When _X/_T swizzle mode was used for MSAA depth texture, TC will get zplane
+                    // equation from wrong address within memory range a tile covered and use the
+                    // garbage data for compressed Z reading which finally leads to corruption.
+                    allowedSwModeSet.value &= ~Gfx9XorSwModeMask;
+                }
 
-            validateSwModeSet >>= 1;
+                if (m_settings.htileCacheRbConflict &&
+                    (pIn->flags.depth || pIn->flags.stencil) &&
+                    (numSlices > 1) &&
+                    (pIn->flags.metaRbUnaligned == FALSE) &&
+                    (pIn->flags.metaPipeUnaligned == FALSE))
+                {
+                    // Z_X 2D array with Rb/Pipe aligned HTile won't have metadata cache coherency
+                    allowedSwModeSet.value &= ~Gfx9XSwModeMask;
+                }
+            }
         }
-#endif
 
-        pOut->validSwModeSet = allowedSwModeSet;
-        pOut->canXor         = (allowedSwModeSet.value & Gfx9XorSwModeMask) ? TRUE : FALSE;
-        pOut->validBlockSet  = GetAllowedBlockSet(allowedSwModeSet);
-        pOut->validSwTypeSet = GetAllowedSwSet(allowedSwModeSet);
-
-        pOut->clientPreferredSwSet = pIn->preferredSwSet;
+        if (msaa)
+        {
+            allowedSwModeSet.value &= Gfx9MsaaSwModeMask;
+        }
 
-        if (pOut->clientPreferredSwSet.value == 0)
+        if ((numFrags > 1) &&
+            (GetBlockSize(ADDR_SW_4KB) < (m_pipeInterleaveBytes * numFrags)))
         {
-            pOut->clientPreferredSwSet.value = AddrSwSetAll;
+            // MSAA surface must have blk_bytes/pipe_interleave >= num_samples
+            allowedSwModeSet.value &= Gfx9Blk64KBSwModeMask;
         }
 
-        if (allowedSwModeSet.value == Gfx9LinearSwModeMask)
+        if (numMipLevels > 1)
         {
-            pOut->swizzleMode = ADDR_SW_LINEAR;
+            allowedSwModeSet.value &= ~Gfx9Blk256BSwModeMask;
         }
-        else
+
+        if (displayRsrc)
         {
-            // Always ignore linear swizzle mode if there is other choice.
-            allowedSwModeSet.swLinear = 0;
+            if (m_settings.isDce12)
+            {
+                allowedSwModeSet.value &= (bpp == 32) ? Dce12Bpp32SwModeMask : Dce12NonBpp32SwModeMask;
+            }
+            else if (m_settings.isDcn1)
+            {
+                allowedSwModeSet.value &= (bpp == 64) ? Dcn1Bpp64SwModeMask : Dcn1NonBpp64SwModeMask;
+            }
+            else
+            {
+                ADDR_NOT_IMPLEMENTED();
+            }
+        }
 
-            ADDR2_BLOCK_SET allowedBlockSet = GetAllowedBlockSet(allowedSwModeSet);
+        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;
 
-            // Determine block size if there is 2 or more block type candidates
-            if (IsPow2(allowedBlockSet.value) == FALSE)
+            for (UINT_32 i = 0; validateSwModeSet != 0; i++)
             {
-                const AddrSwizzleMode swMode[AddrBlockMaxTiledType]  = {ADDR_SW_256B, ADDR_SW_4KB, ADDR_SW_64KB};
-                Dim3d                 blkDim[AddrBlockMaxTiledType]  = {{0}, {0}, {0}};
-                Dim3d                 padDim[AddrBlockMaxTiledType]  = {{0}, {0}, {0}};
-                UINT_64               padSize[AddrBlockMaxTiledType] = {0};
-
-                const UINT_32 ratioLow           = pIn->flags.minimizeAlign ? 1 : (pIn->flags.opt4space ? 3 : 2);
-                const UINT_32 ratioHi            = pIn->flags.minimizeAlign ? 1 : (pIn->flags.opt4space ? 2 : 1);
-                const UINT_64 sizeAlignInElement = Max(NextPow2(pIn->minSizeAlign) / (bpp >> 3), 1u);
-                UINT_32       minSizeBlk         = AddrBlockMicro;
-                UINT_64       minSize            = 0;
-
-                for (UINT_32 i = AddrBlockMicro; i < AddrBlockMaxTiledType; i++)
+                if (validateSwModeSet & 1)
                 {
-                    if (allowedBlockSet.value & (1 << i))
-                    {
-                        ComputeBlockDimensionForSurf(&blkDim[i].w,
-                                                     &blkDim[i].h,
-                                                     &blkDim[i].d,
-                                                     bpp,
-                                                     numFrags,
-                                                     pOut->resourceType,
-                                                     swMode[i]);
-
-                        if (displayRsrc)
-                        {
-                            blkDim[i].w = PowTwoAlign(blkDim[i].w, 32);
-                        }
+                    localIn.swizzleMode = static_cast<AddrSwizzleMode>(i);
+                    ADDR_ASSERT(ValidateSwModeParams(&localIn));
+                }
 
-                        padSize[i] = ComputePadSize(&blkDim[i], width, height, numSlices, &padDim[i]);
-                        padSize[i] = PowTwoAlign(padSize[i], sizeAlignInElement);
+                validateSwModeSet >>= 1;
+            }
+#endif
 
-                        if ((minSize == 0) ||
-                            ((padSize[i] * ratioHi) <= (minSize * ratioLow)))
-                        {
-                            minSize    = padSize[i];
-                            minSizeBlk = i;
-                        }
-                    }
-                }
+            pOut->validSwModeSet = allowedSwModeSet;
+            pOut->canXor         = (allowedSwModeSet.value & Gfx9XorSwModeMask) ? TRUE : FALSE;
+            pOut->validBlockSet  = GetAllowedBlockSet(allowedSwModeSet);
+            pOut->validSwTypeSet = GetAllowedSwSet(allowedSwModeSet);
 
-                if ((allowedBlockSet.micro == TRUE)      &&
-                    (width  <= blkDim[AddrBlockMicro].w) &&
-                    (height <= blkDim[AddrBlockMicro].h) &&
-                    (NextPow2(pIn->minSizeAlign) <= GetBlockSize(ADDR_SW_256B)))
-                {
-                    minSizeBlk = AddrBlockMicro;
-                }
+            pOut->clientPreferredSwSet = pIn->preferredSwSet;
 
-                if (minSizeBlk == AddrBlockMicro)
-                {
-                    allowedSwModeSet.value &= Gfx9Blk256BSwModeMask;
-                }
-                else if (minSizeBlk == AddrBlock4KB)
-                {
-                    allowedSwModeSet.value &= Gfx9Blk4KBSwModeMask;
-                }
-                else
-                {
-                    ADDR_ASSERT(minSizeBlk == AddrBlock64KB);
-                    allowedSwModeSet.value &= Gfx9Blk64KBSwModeMask;
-                }
+            if (pOut->clientPreferredSwSet.value == 0)
+            {
+                pOut->clientPreferredSwSet.value = AddrSwSetAll;
             }
 
-            // Block type should be determined.
-            ADDR_ASSERT(IsPow2(GetAllowedBlockSet(allowedSwModeSet).value));
+            if (allowedSwModeSet.value == Gfx9LinearSwModeMask)
+            {
+                pOut->swizzleMode = ADDR_SW_LINEAR;
+            }
+            else
+            {
+                // Always ignore linear swizzle mode if there is other choice.
+                allowedSwModeSet.swLinear = 0;
 
-            ADDR2_SWTYPE_SET allowedSwSet = GetAllowedSwSet(allowedSwModeSet);
+                ADDR2_BLOCK_SET allowedBlockSet = GetAllowedBlockSet(allowedSwModeSet);
 
-            // Determine swizzle type if there is 2 or more swizzle type candidates
-            if (IsPow2(allowedSwSet.value) == FALSE)
-            {
-                if (ElemLib::IsBlockCompressed(pIn->format))
+                // Determine block size if there is 2 or more block type candidates
+                if (IsPow2(allowedBlockSet.value) == FALSE)
                 {
-                    if (allowedSwSet.sw_D)
+                    const AddrSwizzleMode swMode[AddrBlockMaxTiledType]  = {ADDR_SW_256B, ADDR_SW_4KB, ADDR_SW_64KB};
+                    Dim3d                 blkDim[AddrBlockMaxTiledType]  = {{0}, {0}, {0}};
+                    Dim3d                 padDim[AddrBlockMaxTiledType]  = {{0}, {0}, {0}};
+                    UINT_64               padSize[AddrBlockMaxTiledType] = {0};
+
+                    const UINT_32 ratioLow           = pIn->flags.minimizeAlign ? 1 : (pIn->flags.opt4space ? 3 : 2);
+                    const UINT_32 ratioHi            = pIn->flags.minimizeAlign ? 1 : (pIn->flags.opt4space ? 2 : 1);
+                    const UINT_64 sizeAlignInElement = Max(NextPow2(pIn->minSizeAlign) / (bpp >> 3), 1u);
+                    UINT_32       minSizeBlk         = AddrBlockMicro;
+                    UINT_64       minSize            = 0;
+
+                    for (UINT_32 i = AddrBlockMicro; i < AddrBlockMaxTiledType; i++)
                     {
-                        allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
-                    }
-                    else
-                    {
-                        ADDR_ASSERT(allowedSwSet.sw_S);
-                        allowedSwModeSet.value &= Gfx9StandardSwModeMask;
-                    }
-                }
-                else if (ElemLib::IsMacroPixelPacked(pIn->format))
-                {
-                    if (allowedSwSet.sw_S)
-                    {
-                        allowedSwModeSet.value &= Gfx9StandardSwModeMask;
-                    }
-                    else if (allowedSwSet.sw_D)
-                    {
-                        allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
+                        if (allowedBlockSet.value & (1 << i))
+                        {
+                            ComputeBlockDimensionForSurf(&blkDim[i].w,
+                                                         &blkDim[i].h,
+                                                         &blkDim[i].d,
+                                                         bpp,
+                                                         numFrags,
+                                                         pOut->resourceType,
+                                                         swMode[i]);
+
+                            if (displayRsrc)
+                            {
+                                blkDim[i].w = PowTwoAlign(blkDim[i].w, 32);
+                            }
+
+                            padSize[i] = ComputePadSize(&blkDim[i], width, height, numSlices, &padDim[i]);
+                            padSize[i] = PowTwoAlign(padSize[i], sizeAlignInElement);
+
+                            if ((minSize == 0) ||
+                                ((padSize[i] * ratioHi) <= (minSize * ratioLow)))
+                            {
+                                minSize    = padSize[i];
+                                minSizeBlk = i;
+                            }
+                        }
                     }
-                    else
+
+                    if ((allowedBlockSet.micro == TRUE)      &&
+                        (width  <= blkDim[AddrBlockMicro].w) &&
+                        (height <= blkDim[AddrBlockMicro].h) &&
+                        (NextPow2(pIn->minSizeAlign) <= GetBlockSize(ADDR_SW_256B)))
                     {
-                        ADDR_ASSERT(allowedSwSet.sw_R);
-                        allowedSwModeSet.value &= Gfx9RotateSwModeMask;
+                        minSizeBlk = AddrBlockMicro;
                     }
-                }
-                else if (pOut->resourceType == ADDR_RSRC_TEX_3D)
-                {
-                    if (pIn->flags.color && allowedSwSet.sw_D)
+
+                    if (minSizeBlk == AddrBlockMicro)
                     {
-                        allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
+                        allowedSwModeSet.value &= Gfx9Blk256BSwModeMask;
                     }
-                    else if (allowedSwSet.sw_Z)
+                    else if (minSizeBlk == AddrBlock4KB)
                     {
-                        allowedSwModeSet.value &= Gfx9ZSwModeMask;
+                        allowedSwModeSet.value &= Gfx9Blk4KBSwModeMask;
                     }
                     else
                     {
-                        ADDR_ASSERT(allowedSwSet.sw_S);
-                        allowedSwModeSet.value &= Gfx9StandardSwModeMask;
+                        ADDR_ASSERT(minSizeBlk == AddrBlock64KB);
+                        allowedSwModeSet.value &= Gfx9Blk64KBSwModeMask;
                     }
                 }
-                else
+
+                // Block type should be determined.
+                ADDR_ASSERT(IsPow2(GetAllowedBlockSet(allowedSwModeSet).value));
+
+                ADDR2_SWTYPE_SET allowedSwSet = GetAllowedSwSet(allowedSwModeSet);
+
+                // Determine swizzle type if there is 2 or more swizzle type candidates
+                if (IsPow2(allowedSwSet.value) == FALSE)
                 {
-                    if (pIn->flags.rotated && allowedSwSet.sw_R)
+                    if (ElemLib::IsBlockCompressed(pIn->format))
                     {
-                        allowedSwModeSet.value &= Gfx9RotateSwModeMask;
+                        if (allowedSwSet.sw_D)
+                        {
+                            allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
+                        }
+                        else
+                        {
+                            ADDR_ASSERT(allowedSwSet.sw_S);
+                            allowedSwModeSet.value &= Gfx9StandardSwModeMask;
+                        }
                     }
-                    else if (displayRsrc && allowedSwSet.sw_D)
+                    else if (ElemLib::IsMacroPixelPacked(pIn->format))
                     {
-                        allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
+                        if (allowedSwSet.sw_S)
+                        {
+                            allowedSwModeSet.value &= Gfx9StandardSwModeMask;
+                        }
+                        else if (allowedSwSet.sw_D)
+                        {
+                            allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
+                        }
+                        else
+                        {
+                            ADDR_ASSERT(allowedSwSet.sw_R);
+                            allowedSwModeSet.value &= Gfx9RotateSwModeMask;
+                        }
                     }
-                    else if (allowedSwSet.sw_S)
+                    else if (pOut->resourceType == ADDR_RSRC_TEX_3D)
                     {
-                        allowedSwModeSet.value &= Gfx9StandardSwModeMask;
+                        if (pIn->flags.color && allowedSwSet.sw_D)
+                        {
+                            allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
+                        }
+                        else if (allowedSwSet.sw_Z)
+                        {
+                            allowedSwModeSet.value &= Gfx9ZSwModeMask;
+                        }
+                        else
+                        {
+                            ADDR_ASSERT(allowedSwSet.sw_S);
+                            allowedSwModeSet.value &= Gfx9StandardSwModeMask;
+                        }
                     }
                     else
                     {
-                        ADDR_ASSERT(allowedSwSet.sw_Z);
-                        allowedSwModeSet.value &= Gfx9ZSwModeMask;
+                        if (pIn->flags.rotated && allowedSwSet.sw_R)
+                        {
+                            allowedSwModeSet.value &= Gfx9RotateSwModeMask;
+                        }
+                        else if (displayRsrc && allowedSwSet.sw_D)
+                        {
+                            allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
+                        }
+                        else if (allowedSwSet.sw_S)
+                        {
+                            allowedSwModeSet.value &= Gfx9StandardSwModeMask;
+                        }
+                        else
+                        {
+                            ADDR_ASSERT(allowedSwSet.sw_Z);
+                            allowedSwModeSet.value &= Gfx9ZSwModeMask;
+                        }
                     }
                 }
-            }
 
-            // Swizzle type should be determined.
-            ADDR_ASSERT(IsPow2(GetAllowedSwSet(allowedSwModeSet).value));
+                // Swizzle type should be determined.
+                ADDR_ASSERT(IsPow2(GetAllowedSwSet(allowedSwModeSet).value));
+
+                // Determine swizzle mode now - always select the "largest" swizzle mode for a given block type +
+                // swizzle type combination. For example, for AddrBlock64KB + ADDR_SW_S, select SW_64KB_S_X(25) if it's
+                // available, or otherwise select SW_64KB_S_T(17) if it's available, or otherwise select SW_64KB_S(9).
+                pOut->swizzleMode = static_cast<AddrSwizzleMode>(Log2NonPow2(allowedSwModeSet.value));
+            }
 
-            // Determine swizzle mode now - always select the "largest" swizzle mode for a given block type +
-            // swizzle type combination. For example, for AddrBlock64KB + ADDR_SW_S, select SW_64KB_S_X(25) if it's
-            // available, or otherwise select SW_64KB_S_T(17) if it's available, or otherwise select SW_64KB_S(9).
-            pOut->swizzleMode = static_cast<AddrSwizzleMode>(Log2NonPow2(allowedSwModeSet.value));
+            returnCode = ADDR_OK;
+        }
+        else
+        {
+            // Invalid combination...
+            ADDR_ASSERT_ALWAYS();
         }
     }
     else
     {
         // Invalid combination...
         ADDR_ASSERT_ALWAYS();
-        returnCode = ADDR_INVALIDPARAMS;
     }
 
     return returnCode;
@@ -3992,7 +4114,7 @@  ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceInfoTiled(
                 // Then we need extra padding for base surface. Otherwise, metadata and data surface for same pixel will
                 // be flushed to different pipes, but texture engine only uses pipe id of data surface to fetch both of
                 // them, which may cause invalid metadata to be fetched.
-                pOut->baseAlign = Max(pOut->baseAlign, m_pipeInterleaveBytes * m_pipes);
+                pOut->baseAlign = Max(pOut->baseAlign, m_pipeInterleaveBytes * m_pipes * m_se);
             }
 
             if (pIn->flags.prt)
diff --git a/src/amd/addrlib/src/gfx9/gfx9addrlib.h b/src/amd/addrlib/src/gfx9/gfx9addrlib.h
index 73f035370db..d64d8e879b4 100644
--- a/src/amd/addrlib/src/gfx9/gfx9addrlib.h
+++ b/src/amd/addrlib/src/gfx9/gfx9addrlib.h
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
@@ -615,6 +615,34 @@  private:
         return allowedSwSet;
     }
 
+    BOOL_32 IsInMipTail(
+        AddrResourceType  resourceType,
+        AddrSwizzleMode   swizzleMode,
+        Dim3d             mipTailDim,
+        UINT_32           width,
+        UINT_32           height,
+        UINT_32           depth) const
+    {
+        BOOL_32 inTail = ((width <= mipTailDim.w) &&
+                          (height <= mipTailDim.h) &&
+                          (IsThin(resourceType, swizzleMode) || (depth <= mipTailDim.d)));
+
+        return inTail;
+    }
+
+    BOOL_32 ValidateNonSwModeParams(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;
+    BOOL_32 ValidateSwModeParams(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;
+
+    UINT_32 GetBankXorBits(UINT_32 macroBlockBits) const
+    {
+        UINT_32 pipeBits = GetPipeXorBits(macroBlockBits);
+
+        // Bank xor bits
+        UINT_32 bankBits = Min(macroBlockBits - pipeBits - m_pipeInterleaveLog2, m_banksLog2);
+
+        return bankBits;
+    }
+
     Gfx9ChipSettings m_settings;
 
     CoordEq      m_cachedMetaEq[MaxCachedMetaEq];
diff --git a/src/amd/addrlib/src/r800/ciaddrlib.cpp b/src/amd/addrlib/src/r800/ciaddrlib.cpp
index 5bec0918471..5a83e715301 100644
--- a/src/amd/addrlib/src/r800/ciaddrlib.cpp
+++ b/src/amd/addrlib/src/r800/ciaddrlib.cpp
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
@@ -210,7 +210,7 @@  ADDR_E_RETURNCODE CiLib::HwlComputeDccInfo(
 {
     ADDR_E_RETURNCODE returnCode = ADDR_OK;
 
-    if (m_settings.isVolcanicIslands && IsMacroTiled(pIn->tileMode))
+    if (SupportDccAndTcCompatibility() && IsMacroTiled(pIn->tileMode))
     {
         UINT_64 dccFastClearSize = pIn->colorSurfSize >> 8;
 
@@ -294,7 +294,7 @@  ADDR_E_RETURNCODE CiLib::HwlComputeCmaskAddrFromCoord(
 {
     ADDR_E_RETURNCODE returnCode = ADDR_NOTSUPPORTED;
 
-    if ((m_settings.isVolcanicIslands == TRUE) &&
+    if ((SupportDccAndTcCompatibility() == TRUE) &&
         (pIn->flags.tcCompatible == TRUE))
     {
         UINT_32 numOfPipes   = HwlGetPipes(pIn->pTileInfo);
@@ -338,7 +338,7 @@  ADDR_E_RETURNCODE CiLib::HwlComputeHtileAddrFromCoord(
 {
     ADDR_E_RETURNCODE returnCode = ADDR_NOTSUPPORTED;
 
-    if ((m_settings.isVolcanicIslands == TRUE) &&
+    if ((SupportDccAndTcCompatibility() == TRUE) &&
         (pIn->flags.tcCompatible == TRUE))
     {
         UINT_32 numOfPipes   = HwlGetPipes(pIn->pTileInfo);
@@ -709,7 +709,7 @@  ADDR_E_RETURNCODE CiLib::HwlComputeSurfaceInfo(
     if ((pIn->mipLevel > 0) &&
         (pOut->tcCompatible == TRUE) &&
         (pOut->tileMode != pIn->tileMode) &&
-        (m_settings.isVolcanicIslands == TRUE))
+        (SupportDccAndTcCompatibility() == TRUE))
     {
         pOut->tcCompatible = CheckTcCompatibility(pOut->pTileInfo, pIn->bpp, pOut->tileMode, pOut->tileType, pOut);
     }
@@ -1303,7 +1303,7 @@  VOID CiLib::HwlSetupTileInfo(
     }
 
     // tcCompatible flag is only meaningful for gfx8.
-    if (m_settings.isVolcanicIslands == FALSE)
+    if (SupportDccAndTcCompatibility() == FALSE)
     {
         flags.tcCompatible = FALSE;
     }
@@ -2098,7 +2098,7 @@  VOID CiLib::HwlPadDimensions(
     UINT_32             heightAlign  ///< [in] height alignment
     ) const
 {
-    if ((m_settings.isVolcanicIslands == TRUE) &&
+    if ((SupportDccAndTcCompatibility() == TRUE) &&
         (flags.dccCompatible == TRUE) &&
         (numSamples > 1) &&
         (mipLevel == 0) &&
@@ -2208,7 +2208,7 @@  UINT_32 CiLib::HwlComputeMaxMetaBaseAlignments() const
 
     for (UINT_32 i = 0; i < m_noOfMacroEntries; i++)
     {
-        if ((m_settings.isVolcanicIslands) && IsMacroTiled(m_tileTable[i].mode))
+        if (SupportDccAndTcCompatibility() && IsMacroTiled(m_tileTable[i].mode))
         {
             maxBank = Max(maxBank, m_macroTileTable[i].banks);
         }
diff --git a/src/amd/addrlib/src/r800/ciaddrlib.h b/src/amd/addrlib/src/r800/ciaddrlib.h
index 51853893266..b548254ca82 100644
--- a/src/amd/addrlib/src/r800/ciaddrlib.h
+++ b/src/amd/addrlib/src/r800/ciaddrlib.h
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
@@ -184,6 +184,11 @@  private:
     BOOL_32 CheckTcCompatibility(const ADDR_TILEINFO* pTileInfo, UINT_32 bpp, AddrTileMode tileMode,
                                  AddrTileType tileType, const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;
 
+    BOOL_32 SupportDccAndTcCompatibility() const
+    {
+        return ((m_settings.isVolcanicIslands == TRUE) || (m_configFlags.forceDccAndTcCompat == TRUE));
+    }
+
     static const UINT_32    MacroTileTableSize = 16;
     static const UINT_32    PrtMacroModeOffset = MacroTileTableSize / 2;
     static const INT_32     MinDepth2DThinIndex = 0;
diff --git a/src/amd/addrlib/src/r800/egbaddrlib.cpp b/src/amd/addrlib/src/r800/egbaddrlib.cpp
index 3c684235058..1c2596e4292 100644
--- a/src/amd/addrlib/src/r800/egbaddrlib.cpp
+++ b/src/amd/addrlib/src/r800/egbaddrlib.cpp
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
@@ -741,8 +741,6 @@  BOOL_32 EgBasedLib::ComputeSurfaceAlignmentsMicroTiled(
 
     AdjustPitchAlignment(flags, pPitchAlign);
 
-    // Workaround 2 for 1D tiling -  There is HW bug for Carrizo,
-    // where it requires the following alignments for 1D tiling.
     if (flags.czDispCompatible && (mipLevel == 0))
     {
         *pBaseAlign  = PowTwoAlign(*pBaseAlign, 4096);                         //Base address MOD 4096 = 0
diff --git a/src/amd/addrlib/src/r800/egbaddrlib.h b/src/amd/addrlib/src/r800/egbaddrlib.h
index f5bae10ed68..55e53540e95 100644
--- a/src/amd/addrlib/src/r800/egbaddrlib.h
+++ b/src/amd/addrlib/src/r800/egbaddrlib.h
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/amd/addrlib/src/r800/siaddrlib.cpp b/src/amd/addrlib/src/r800/siaddrlib.cpp
index da37ad8f901..c91f72640a3 100644
--- a/src/amd/addrlib/src/r800/siaddrlib.cpp
+++ b/src/amd/addrlib/src/r800/siaddrlib.cpp
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
@@ -1603,8 +1603,9 @@  VOID SiLib::HwlComputeXmaskCoordFromAddr(
             {
                 macroOffset |= (pipebit1<<1);
             }
-            if((pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_8x16) ||
-               (pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_16x16))
+            if ((pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_8x16) ||
+                (pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_16x16)
+               )
             {
                 macroOffset |= (pipebit3<<1);
             }
diff --git a/src/amd/addrlib/src/r800/siaddrlib.h b/src/amd/addrlib/src/r800/siaddrlib.h
index 705141161db..5a4f00a1680 100644
--- a/src/amd/addrlib/src/r800/siaddrlib.h
+++ b/src/amd/addrlib/src/r800/siaddrlib.h
@@ -1,5 +1,5 @@ 
 /*
- * Copyright © 2007-2018 Advanced Micro Devices, Inc.
+ * Copyright © 2007-2019 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c
index 34db177ffb6..27c977ac7d9 100644
--- a/src/gallium/drivers/radeonsi/si_texture.c
+++ b/src/gallium/drivers/radeonsi/si_texture.c
@@ -173,6 +173,11 @@  static void si_copy_from_staging_texture(struct pipe_context *ctx, struct si_tra
 		return;
 	}
 
+	if (util_format_is_compressed(dst->format)) {
+		sbox.width = util_format_get_nblocksx(dst->format, sbox.width);
+		sbox.height = util_format_get_nblocksx(dst->format, sbox.height);
+	}
+
 	sctx->dma_copy(ctx, dst, transfer->level,
 		       transfer->box.x, transfer->box.y, transfer->box.z,
 		       src, 0, &sbox);
@@ -1794,6 +1799,25 @@  static void si_init_temp_resource_from_box(struct pipe_resource *res,
 	res->usage = flags & SI_RESOURCE_FLAG_TRANSFER ? PIPE_USAGE_STAGING : PIPE_USAGE_DEFAULT;
 	res->flags = flags;
 
+	if (flags & SI_RESOURCE_FLAG_TRANSFER &&
+	    util_format_is_compressed(orig->format)) {
+		/* Transfer resources are allocated with linear tiling, which is
+		 * not supported for compressed formats.
+		 */
+		unsigned blocksize =
+			util_format_get_blocksize(orig->format);
+
+		if (blocksize == 8) {
+			res->format = PIPE_FORMAT_R16G16B16A16_UINT;
+		} else {
+			assert(blocksize == 16);
+			res->format = PIPE_FORMAT_R32G32B32A32_UINT;
+		}
+
+		res->width0 = util_format_get_nblocksx(orig->format, box->width);
+		res->height0 = util_format_get_nblocksy(orig->format, box->height);
+	}
+
 	/* We must set the correct texture target and dimensions for a 3D box. */
 	if (box->depth > 1 && util_max_layer(orig, level) > 0) {
 		res->target = PIPE_TEXTURE_2D_ARRAY;

Comments

I'm not quite sure why the dimension changes are needed for radeonsi,
but for both polarisd and vega the compressed texture CTS tests pass
on RADV.

Acked-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Tested-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>

On Sat, Jun 15, 2019 at 12:47 AM Marek Olšák <maraeo@gmail.com> wrote:
>
> From: Marek Olšák <marek.olsak@amd.com>
>
> ---
>
> Please test and fix RADV if needed. Compressed textures may be broken.
> This change contains the necessary radeonsi fixes for this addrlib.
>
>  src/amd/addrlib/inc/addrinterface.h         |  12 +-
>  src/amd/addrlib/inc/addrtypes.h             |  36 +-
>  src/amd/addrlib/src/addrinterface.cpp       |   2 +-
>  src/amd/addrlib/src/amdgpu_asic_addr.h      |   2 +-
>  src/amd/addrlib/src/chip/gfx9/gfx9_gb_reg.h |   2 +-
>  src/amd/addrlib/src/chip/r800/si_gb_reg.h   |   2 +-
>  src/amd/addrlib/src/core/addrcommon.h       |  21 +-
>  src/amd/addrlib/src/core/addrelemlib.cpp    |   2 +-
>  src/amd/addrlib/src/core/addrelemlib.h      |   2 +-
>  src/amd/addrlib/src/core/addrlib.cpp        |   3 +-
>  src/amd/addrlib/src/core/addrlib.h          |   3 +-
>  src/amd/addrlib/src/core/addrlib1.cpp       |   2 +-
>  src/amd/addrlib/src/core/addrlib1.h         |   2 +-
>  src/amd/addrlib/src/core/addrlib2.cpp       |  48 +-
>  src/amd/addrlib/src/core/addrlib2.h         |  18 +-
>  src/amd/addrlib/src/core/addrobject.cpp     |   2 +-
>  src/amd/addrlib/src/core/addrobject.h       |   2 +-
>  src/amd/addrlib/src/core/coord.cpp          |   2 +-
>  src/amd/addrlib/src/core/coord.h            |   2 +-
>  src/amd/addrlib/src/gfx9/gfx9addrlib.cpp    | 898 +++++++++++---------
>  src/amd/addrlib/src/gfx9/gfx9addrlib.h      |  30 +-
>  src/amd/addrlib/src/r800/ciaddrlib.cpp      |  16 +-
>  src/amd/addrlib/src/r800/ciaddrlib.h        |   7 +-
>  src/amd/addrlib/src/r800/egbaddrlib.cpp     |   4 +-
>  src/amd/addrlib/src/r800/egbaddrlib.h       |   2 +-
>  src/amd/addrlib/src/r800/siaddrlib.cpp      |   7 +-
>  src/amd/addrlib/src/r800/siaddrlib.h        |   2 +-
>  src/gallium/drivers/radeonsi/si_texture.c   |  24 +
>  28 files changed, 665 insertions(+), 490 deletions(-)
>
> diff --git a/src/amd/addrlib/inc/addrinterface.h b/src/amd/addrlib/inc/addrinterface.h
> index 1a2690970be..8e8f36378b3 100644
> --- a/src/amd/addrlib/inc/addrinterface.h
> +++ b/src/amd/addrlib/inc/addrinterface.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> @@ -307,7 +307,8 @@ typedef union _ADDR_CREATE_FLAGS
>          UINT_32 checkLast2DLevel       : 1;    ///< Check the last 2D mip sub level
>          UINT_32 useHtileSliceAlign     : 1;    ///< Do htile single slice alignment
>          UINT_32 allowLargeThickTile    : 1;    ///< Allow 64*thickness*bytesPerPixel > rowSize
> -        UINT_32 reserved               : 25;   ///< Reserved bits for future use
> +        UINT_32 forceDccAndTcCompat    : 1;    ///< Force enable DCC and TC compatibility
> +        UINT_32 reserved               : 24;   ///< Reserved bits for future use
>      };
>
>      UINT_32 value;
> @@ -2879,6 +2880,9 @@ typedef struct _ADDR2_COMPUTE_CMASKINFO_INPUT
>      UINT_32             unalignedWidth;     ///< Color surface original width
>      UINT_32             unalignedHeight;    ///< Color surface original height
>      UINT_32             numSlices;          ///< Number of slices of color buffer
> +    UINT_32             numMipLevels;       ///< Number of mip levels
> +    UINT_32             firstMipIdInTail;   ///< The id of first mip in tail, if no mip is in tail,
> +                                            ///  it should be number of mip levels
>  } ADDR2_COMPUTE_CMASK_INFO_INPUT;
>
>  /**
> @@ -2904,7 +2908,9 @@ typedef struct _ADDR2_COMPUTE_CMASK_INFO_OUTPUT
>      UINT_32    metaBlkWidth;  ///< Meta block width
>      UINT_32    metaBlkHeight; ///< Meta block height
>
> -    UINT_32    metaBlkNumPerSlice; ///< Number of metablock within one slice
> +    UINT_32    metaBlkNumPerSlice;  ///< Number of metablock within one slice
> +
> +    ADDR2_META_MIP_INFO* pMipInfo;  ///< CMASK mip information
>  } ADDR2_COMPUTE_CMASK_INFO_OUTPUT;
>
>  /**
> diff --git a/src/amd/addrlib/inc/addrtypes.h b/src/amd/addrlib/inc/addrtypes.h
> index c9393579b7e..36e342f3176 100644
> --- a/src/amd/addrlib/inc/addrtypes.h
> +++ b/src/amd/addrlib/inc/addrtypes.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> @@ -567,23 +567,23 @@ typedef enum _AddrHtileBlockSize
>  */
>  typedef enum _AddrPipeCfg
>  {
> -    ADDR_PIPECFG_INVALID         = 0,
> -    ADDR_PIPECFG_P2              = 1, /// 2 pipes,
> -    ADDR_PIPECFG_P4_8x16         = 5, /// 4 pipes,
> -    ADDR_PIPECFG_P4_16x16        = 6,
> -    ADDR_PIPECFG_P4_16x32        = 7,
> -    ADDR_PIPECFG_P4_32x32        = 8,
> -    ADDR_PIPECFG_P8_16x16_8x16   = 9, /// 8 pipes
> -    ADDR_PIPECFG_P8_16x32_8x16   = 10,
> -    ADDR_PIPECFG_P8_32x32_8x16   = 11,
> -    ADDR_PIPECFG_P8_16x32_16x16  = 12,
> -    ADDR_PIPECFG_P8_32x32_16x16  = 13,
> -    ADDR_PIPECFG_P8_32x32_16x32  = 14,
> -    ADDR_PIPECFG_P8_32x64_32x32  = 15,
> -    ADDR_PIPECFG_P16_32x32_8x16  = 17, /// 16 pipes
> -    ADDR_PIPECFG_P16_32x32_16x16 = 18,
> -    ADDR_PIPECFG_RESERVED        = 19, /// reserved for internal use
> -    ADDR_PIPECFG_MAX             = 20,
> +    ADDR_PIPECFG_INVALID              = 0,
> +    ADDR_PIPECFG_P2                   = 1, /// 2 pipes,
> +    ADDR_PIPECFG_P4_8x16              = 5, /// 4 pipes,
> +    ADDR_PIPECFG_P4_16x16             = 6,
> +    ADDR_PIPECFG_P4_16x32             = 7,
> +    ADDR_PIPECFG_P4_32x32             = 8,
> +    ADDR_PIPECFG_P8_16x16_8x16        = 9, /// 8 pipes
> +    ADDR_PIPECFG_P8_16x32_8x16        = 10,
> +    ADDR_PIPECFG_P8_32x32_8x16        = 11,
> +    ADDR_PIPECFG_P8_16x32_16x16       = 12,
> +    ADDR_PIPECFG_P8_32x32_16x16       = 13,
> +    ADDR_PIPECFG_P8_32x32_16x32       = 14,
> +    ADDR_PIPECFG_P8_32x64_32x32       = 15,
> +    ADDR_PIPECFG_P16_32x32_8x16       = 17, /// 16 pipes
> +    ADDR_PIPECFG_P16_32x32_16x16      = 18,
> +    ADDR_PIPECFG_UNUSED               = 19,
> +    ADDR_PIPECFG_MAX                  = 20,
>  } AddrPipeCfg;
>
>  /**
> diff --git a/src/amd/addrlib/src/addrinterface.cpp b/src/amd/addrlib/src/addrinterface.cpp
> index b4eabd56062..921eed370f2 100644
> --- a/src/amd/addrlib/src/addrinterface.cpp
> +++ b/src/amd/addrlib/src/addrinterface.cpp
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> diff --git a/src/amd/addrlib/src/amdgpu_asic_addr.h b/src/amd/addrlib/src/amdgpu_asic_addr.h
> index 41efd70e8ff..11fe4a0ecc5 100644
> --- a/src/amd/addrlib/src/amdgpu_asic_addr.h
> +++ b/src/amd/addrlib/src/amdgpu_asic_addr.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2017-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2017-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> diff --git a/src/amd/addrlib/src/chip/gfx9/gfx9_gb_reg.h b/src/amd/addrlib/src/chip/gfx9/gfx9_gb_reg.h
> index ade70b9f6be..3a097964f0e 100644
> --- a/src/amd/addrlib/src/chip/gfx9/gfx9_gb_reg.h
> +++ b/src/amd/addrlib/src/chip/gfx9/gfx9_gb_reg.h
> @@ -2,7 +2,7 @@
>  #define __GFX9_GB_REG_H__
>
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> diff --git a/src/amd/addrlib/src/chip/r800/si_gb_reg.h b/src/amd/addrlib/src/chip/r800/si_gb_reg.h
> index 15711ee4b52..aa6c3fb8631 100644
> --- a/src/amd/addrlib/src/chip/r800/si_gb_reg.h
> +++ b/src/amd/addrlib/src/chip/r800/si_gb_reg.h
> @@ -2,7 +2,7 @@
>  #define __SI_GB_REG_H__
>
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> diff --git a/src/amd/addrlib/src/core/addrcommon.h b/src/amd/addrlib/src/core/addrcommon.h
> index f54f1657127..ced842a1e58 100644
> --- a/src/amd/addrlib/src/core/addrcommon.h
> +++ b/src/amd/addrlib/src/core/addrcommon.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> @@ -36,10 +36,6 @@
>
>  #include "addrinterface.h"
>
> -#include <stdlib.h>
> -#include <string.h>
> -#include <assert.h>
> -
>  #if !defined(DEBUG)
>  #ifdef NDEBUG
>  #define DEBUG 0
> @@ -48,6 +44,14 @@
>  #endif
>  #endif
>
> +// ADDR_LNX_KERNEL_BUILD is for internal build
> +// Moved from addrinterface.h so __KERNEL__ is not needed any more
> +#if   !defined(__APPLE__) || defined(HAVE_TSERVER)
> +    #include <stdlib.h>
> +    #include <string.h>
> +    #include <assert.h>
> +#endif
> +
>  ////////////////////////////////////////////////////////////////////////////////////////////////////
>  // Platform specific debug break defines
>  ////////////////////////////////////////////////////////////////////////////////////////////////////
> @@ -152,7 +156,11 @@
>  #endif // DEBUG
>  ////////////////////////////////////////////////////////////////////////////////////////////////////
>
> +#if defined(static_assert)
> +#define ADDR_C_ASSERT(__e) static_assert(__e, "")
> +#else
>  #define ADDR_C_ASSERT(__e) typedef char __ADDR_C_ASSERT__[(__e) ? 1 : -1]
> +#endif
>
>  namespace Addr
>  {
> @@ -260,7 +268,8 @@ union ConfigFlags
>          UINT_32 allowLargeThickTile    : 1;    ///< Allow 64*thickness*bytesPerPixel > rowSize
>          UINT_32 disableLinearOpt       : 1;    ///< Disallow tile modes to be optimized to linear
>          UINT_32 use32bppFor422Fmt      : 1;    ///< View 422 formats as 32 bits per pixel element
> -        UINT_32 reserved               : 21;   ///< Reserved bits for future use
> +        UINT_32 forceDccAndTcCompat    : 1;    ///< Force enable DCC and TC compatibility
> +        UINT_32 reserved               : 20;   ///< Reserved bits for future use
>      };
>
>      UINT_32 value;
> diff --git a/src/amd/addrlib/src/core/addrelemlib.cpp b/src/amd/addrlib/src/core/addrelemlib.cpp
> index 71c0ba74df9..27afb593b65 100644
> --- a/src/amd/addrlib/src/core/addrelemlib.cpp
> +++ b/src/amd/addrlib/src/core/addrelemlib.cpp
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> diff --git a/src/amd/addrlib/src/core/addrelemlib.h b/src/amd/addrlib/src/core/addrelemlib.h
> index 633f94cd207..519e194f3dd 100644
> --- a/src/amd/addrlib/src/core/addrelemlib.h
> +++ b/src/amd/addrlib/src/core/addrelemlib.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> diff --git a/src/amd/addrlib/src/core/addrlib.cpp b/src/amd/addrlib/src/core/addrlib.cpp
> index bdc17ffedcb..ceb5ef826a5 100644
> --- a/src/amd/addrlib/src/core/addrlib.cpp
> +++ b/src/amd/addrlib/src/core/addrlib.cpp
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> @@ -246,6 +246,7 @@ ADDR_E_RETURNCODE Lib::Create(
>          pLib->m_configFlags.checkLast2DLevel    = pCreateIn->createFlags.checkLast2DLevel;
>          pLib->m_configFlags.useHtileSliceAlign  = pCreateIn->createFlags.useHtileSliceAlign;
>          pLib->m_configFlags.allowLargeThickTile = pCreateIn->createFlags.allowLargeThickTile;
> +        pLib->m_configFlags.forceDccAndTcCompat = pCreateIn->createFlags.forceDccAndTcCompat;
>          pLib->m_configFlags.disableLinearOpt    = FALSE;
>
>          pLib->SetChipFamily(pCreateIn->chipFamily, pCreateIn->chipRevision);
> diff --git a/src/amd/addrlib/src/core/addrlib.h b/src/amd/addrlib/src/core/addrlib.h
> index 70c74f917d9..d0a135b31fc 100644
> --- a/src/amd/addrlib/src/core/addrlib.h
> +++ b/src/amd/addrlib/src/core/addrlib.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> @@ -409,7 +409,6 @@ private:
>  Lib* SiHwlInit   (const Client* pClient);
>  Lib* CiHwlInit   (const Client* pClient);
>  Lib* Gfx9HwlInit (const Client* pClient);
> -
>  } // Addr
>
>  #endif
> diff --git a/src/amd/addrlib/src/core/addrlib1.cpp b/src/amd/addrlib/src/core/addrlib1.cpp
> index 65f8fe01492..0704e0f4e1f 100644
> --- a/src/amd/addrlib/src/core/addrlib1.cpp
> +++ b/src/amd/addrlib/src/core/addrlib1.cpp
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> diff --git a/src/amd/addrlib/src/core/addrlib1.h b/src/amd/addrlib/src/core/addrlib1.h
> index 4933a53f128..5411d1c1a84 100644
> --- a/src/amd/addrlib/src/core/addrlib1.h
> +++ b/src/amd/addrlib/src/core/addrlib1.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> diff --git a/src/amd/addrlib/src/core/addrlib2.cpp b/src/amd/addrlib/src/core/addrlib2.cpp
> index 3b4b8debf43..e6440d6ca5c 100644
> --- a/src/amd/addrlib/src/core/addrlib2.cpp
> +++ b/src/amd/addrlib/src/core/addrlib2.cpp
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> @@ -63,7 +63,17 @@ const Dim3d Lib::Block1K_3d[]  = {{16, 8, 8}, {8, 8, 8}, {8, 8, 4}, {8, 4, 4}, {
>  */
>  Lib::Lib()
>      :
> -    Addr::Lib()
> +    Addr::Lib(),
> +    m_se(0),
> +    m_rbPerSe(0),
> +    m_maxCompFrag(0),
> +    m_banksLog2(0),
> +    m_pipesLog2(0),
> +    m_seLog2(0),
> +    m_rbPerSeLog2(0),
> +    m_maxCompFragLog2(0),
> +    m_pipeInterleaveLog2(0),
> +    m_blockVarSizeLog2(0)
>  {
>  }
>
> @@ -78,7 +88,17 @@ Lib::Lib()
>  */
>  Lib::Lib(const Client* pClient)
>      :
> -    Addr::Lib(pClient)
> +    Addr::Lib(pClient),
> +    m_se(0),
> +    m_rbPerSe(0),
> +    m_maxCompFrag(0),
> +    m_banksLog2(0),
> +    m_pipesLog2(0),
> +    m_seLog2(0),
> +    m_rbPerSeLog2(0),
> +    m_maxCompFragLog2(0),
> +    m_pipeInterleaveLog2(0),
> +    m_blockVarSizeLog2(0)
>  {
>  }
>
> @@ -1692,28 +1712,6 @@ UINT_32 Lib::GetPipeXorBits(
>      return pipeBits;
>  }
>
> -/**
> -************************************************************************************************************************
> -*   Lib::GetBankXorBits
> -*
> -*   @brief
> -*       Internal function to get bits number for pipe/se xor operation
> -*
> -*   @return
> -*       ADDR_E_RETURNCODE
> -************************************************************************************************************************
> -*/
> -UINT_32 Lib::GetBankXorBits(
> -    UINT_32 macroBlockBits) const
> -{
> -    UINT_32 pipeBits = GetPipeXorBits(macroBlockBits);
> -
> -    // Bank xor bits
> -    UINT_32 bankBits = Min(macroBlockBits - pipeBits - m_pipeInterleaveLog2, m_banksLog2);
> -
> -    return bankBits;
> -}
> -
>  /**
>  ************************************************************************************************************************
>  *   Lib::Addr2GetPreferredSurfaceSetting
> diff --git a/src/amd/addrlib/src/core/addrlib2.h b/src/amd/addrlib/src/core/addrlib2.h
> index e72dd43678d..258607b8d77 100644
> --- a/src/amd/addrlib/src/core/addrlib2.h
> +++ b/src/amd/addrlib/src/core/addrlib2.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> @@ -691,21 +691,6 @@ protected:
>          UINT_32           blockHeight,
>          UINT_32           blockDepth) const;
>
> -    BOOL_32 IsInMipTail(
> -        AddrResourceType  resourceType,
> -        AddrSwizzleMode   swizzleMode,
> -        Dim3d             mipTailDim,
> -        UINT_32           width,
> -        UINT_32           height,
> -        UINT_32           depth) const
> -    {
> -        BOOL_32 inTail = ((width <= mipTailDim.w) &&
> -                          (height <= mipTailDim.h) &&
> -                          (IsThin(resourceType, swizzleMode) || (depth <= mipTailDim.d)));
> -
> -        return inTail;
> -    }
> -
>      static BOOL_32 IsLocalHeap(AddrResrouceLocation resourceType)
>      {
>          return ((resourceType == ADDR_RSRC_LOC_LOCAL) ||
> @@ -794,7 +779,6 @@ protected:
>      }
>
>      UINT_32 GetPipeXorBits(UINT_32 macroBlockBits) const;
> -    UINT_32 GetBankXorBits(UINT_32 macroBlockBits) const;
>
>      ADDR_E_RETURNCODE ApplyCustomizedPitchHeight(
>          const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,
> diff --git a/src/amd/addrlib/src/core/addrobject.cpp b/src/amd/addrlib/src/core/addrobject.cpp
> index 5f262c3e9e2..79ef3d8dc90 100644
> --- a/src/amd/addrlib/src/core/addrobject.cpp
> +++ b/src/amd/addrlib/src/core/addrobject.cpp
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> diff --git a/src/amd/addrlib/src/core/addrobject.h b/src/amd/addrlib/src/core/addrobject.h
> index 069bb78dee0..05559757712 100644
> --- a/src/amd/addrlib/src/core/addrobject.h
> +++ b/src/amd/addrlib/src/core/addrobject.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> diff --git a/src/amd/addrlib/src/core/coord.cpp b/src/amd/addrlib/src/core/coord.cpp
> index 7fd6bc9173b..9ed0f9db50b 100644
> --- a/src/amd/addrlib/src/core/coord.cpp
> +++ b/src/amd/addrlib/src/core/coord.cpp
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> diff --git a/src/amd/addrlib/src/core/coord.h b/src/amd/addrlib/src/core/coord.h
> index ce40a3ee1f5..72e93e0a187 100644
> --- a/src/amd/addrlib/src/core/coord.h
> +++ b/src/amd/addrlib/src/core/coord.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> diff --git a/src/amd/addrlib/src/gfx9/gfx9addrlib.cpp b/src/amd/addrlib/src/gfx9/gfx9addrlib.cpp
> index 9be775f35f9..f4e3b47cf9d 100644
> --- a/src/amd/addrlib/src/gfx9/gfx9addrlib.cpp
> +++ b/src/amd/addrlib/src/gfx9/gfx9addrlib.cpp
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> @@ -136,8 +136,8 @@ Gfx9Lib::Gfx9Lib(const Client* pClient)
>      m_class = AI_ADDRLIB;
>      memset(&m_settings, 0, sizeof(m_settings));
>      memcpy(m_swizzleModeTable, SwizzleModeTable, sizeof(SwizzleModeTable));
> -    m_metaEqOverrideIndex = 0;
>      memset(m_cachedMetaEqKey, 0, sizeof(m_cachedMetaEqKey));
> +    m_metaEqOverrideIndex = 0;
>  }
>
>  /**
> @@ -1233,6 +1233,7 @@ BOOL_32 Gfx9Lib::HwlInitGlobalParams(
>          {
>              ADDR_ASSERT(m_settings.isVega10 == FALSE);
>              ADDR_ASSERT(m_settings.isRaven == FALSE);
> +
>              ADDR_ASSERT(m_settings.isVega20 == FALSE);
>
>              if (m_settings.isVega12)
> @@ -2934,13 +2935,9 @@ BOOL_32 Gfx9Lib::IsValidDisplaySwizzleMode(
>  {
>      BOOL_32 support = FALSE;
>
> -    const AddrResourceType resourceType = pIn->resourceType;
> -    (void)resourceType;
> -    const AddrSwizzleMode swizzleMode = pIn->swizzleMode;
> -
>      if (m_settings.isDce12)
>      {
> -        switch (swizzleMode)
> +        switch (pIn->swizzleMode)
>          {
>              case ADDR_SW_256B_D:
>              case ADDR_SW_256B_R:
> @@ -2969,7 +2966,7 @@ BOOL_32 Gfx9Lib::IsValidDisplaySwizzleMode(
>      }
>      else if (m_settings.isDcn1)
>      {
> -        switch (swizzleMode)
> +        switch (pIn->swizzleMode)
>          {
>              case ADDR_SW_4KB_D:
>              case ADDR_SW_64KB_D:
> @@ -3117,134 +3114,248 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSubResourceOffsetForSwizzlePattern(
>
>  /**
>  ************************************************************************************************************************
> -*   Gfx9Lib::HwlComputeSurfaceInfoSanityCheck
> +*   Gfx9Lib::ValidateNonSwModeParams
>  *
>  *   @brief
> -*       Compute surface info sanity check
> +*       Validate compute surface info params except swizzle mode
>  *
>  *   @return
> -*       Offset
> +*       TRUE if parameters are valid, FALSE otherwise
>  ************************************************************************************************************************
>  */
> -ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceInfoSanityCheck(
> +BOOL_32 Gfx9Lib::ValidateNonSwModeParams(
>      const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const
>  {
> -    BOOL_32 invalid = FALSE;
> +    BOOL_32 valid = TRUE;
>
> -    if ((pIn->bpp > 128) || (pIn->width == 0) || (pIn->numFrags > 8) || (pIn->numSamples > 16))
> +    if ((pIn->bpp == 0) || (pIn->bpp > 128) || (pIn->width == 0) || (pIn->numFrags > 8) || (pIn->numSamples > 16))
>      {
> -        invalid = TRUE;
> +        ADDR_ASSERT_ALWAYS();
> +        valid = FALSE;
>      }
> -    else if ((pIn->swizzleMode >= ADDR_SW_MAX_TYPE)    ||
> -             (pIn->resourceType >= ADDR_RSRC_MAX_TYPE))
> +
> +    if (pIn->resourceType >= ADDR_RSRC_MAX_TYPE)
>      {
> -        invalid = TRUE;
> +        ADDR_ASSERT_ALWAYS();
> +        valid = FALSE;
>      }
>
> -    BOOL_32 mipmap = (pIn->numMipLevels > 1);
> -    BOOL_32 msaa   = (pIn->numFrags > 1);
> -
> -    ADDR2_SURFACE_FLAGS flags = pIn->flags;
> -    BOOL_32 zbuffer = (flags.depth || flags.stencil);
> -    BOOL_32 color   = flags.color;
> -    BOOL_32 display = flags.display || flags.rotated;
> -
> -    AddrResourceType rsrcType    = pIn->resourceType;
> -    BOOL_32          tex3d       = IsTex3d(rsrcType);
> -    BOOL_32          thin3d      = tex3d && flags.view3dAs2dArray;
> -    AddrSwizzleMode  swizzle     = pIn->swizzleMode;
> -    BOOL_32          linear      = IsLinear(swizzle);
> -    BOOL_32          blk256B     = IsBlock256b(swizzle);
> -    BOOL_32          blkVar      = IsBlockVariable(swizzle);
> -    BOOL_32          isNonPrtXor = IsNonPrtXor(swizzle);
> -    BOOL_32          prt         = flags.prt;
> -    BOOL_32          stereo      = flags.qbStereo;
> -
> -    if (invalid == FALSE)
> +    const BOOL_32 mipmap = (pIn->numMipLevels > 1);
> +    const BOOL_32 msaa   = (pIn->numFrags > 1);
> +    const BOOL_32 isBc   = ElemLib::IsBlockCompressed(pIn->format);
> +
> +    const AddrResourceType rsrcType = pIn->resourceType;
> +    const BOOL_32          tex3d    = IsTex3d(rsrcType);
> +    const BOOL_32          tex2d    = IsTex2d(rsrcType);
> +    const BOOL_32          tex1d    = IsTex1d(rsrcType);
> +
> +    const ADDR2_SURFACE_FLAGS flags   = pIn->flags;
> +    const BOOL_32             zbuffer = flags.depth || flags.stencil;
> +    const BOOL_32             display = flags.display || flags.rotated;
> +    const BOOL_32             stereo  = flags.qbStereo;
> +    const BOOL_32             fmask   = flags.fmask;
> +
> +    // Resource type check
> +    if (tex1d)
>      {
> -        if ((pIn->numFrags > 1) &&
> -            (GetBlockSize(swizzle) < (m_pipeInterleaveBytes * pIn->numFrags)))
> +        if (msaa || zbuffer || display || stereo || isBc || fmask)
>          {
> -            // MSAA surface must have blk_bytes/pipe_interleave >= num_samples
> -            invalid = TRUE;
> +            ADDR_ASSERT_ALWAYS();
> +            valid = FALSE;
>          }
>      }
> -
> -    if (invalid == FALSE)
> +    else if (tex2d)
>      {
> -        switch (rsrcType)
> +        if ((msaa && mipmap) || (stereo && msaa) || (stereo && mipmap))
>          {
> -            case ADDR_RSRC_TEX_1D:
> -                invalid = msaa || zbuffer || display || (linear == FALSE) || stereo;
> -                break;
> -            case ADDR_RSRC_TEX_2D:
> -                invalid = (msaa && mipmap) || (stereo && msaa) || (stereo && mipmap);
> -                break;
> -            case ADDR_RSRC_TEX_3D:
> -                invalid = msaa || zbuffer || display || stereo;
> -                break;
> -            default:
> -                invalid = TRUE;
> -                break;
> +            ADDR_ASSERT_ALWAYS();
> +            valid = FALSE;
>          }
>      }
> +    else if (tex3d)
> +    {
> +        if (msaa || zbuffer || display || stereo || fmask)
> +        {
> +            ADDR_ASSERT_ALWAYS();
> +            valid = FALSE;
> +        }
> +    }
> +    else
> +    {
> +        ADDR_ASSERT_ALWAYS();
> +        valid = FALSE;
> +    }
>
> -    if (invalid == FALSE)
> +    return valid;
> +}
> +
> +/**
> +************************************************************************************************************************
> +*   Gfx9Lib::ValidateSwModeParams
> +*
> +*   @brief
> +*       Validate compute surface info related to swizzle mode
> +*
> +*   @return
> +*       TRUE if parameters are valid, FALSE otherwise
> +************************************************************************************************************************
> +*/
> +BOOL_32 Gfx9Lib::ValidateSwModeParams(
> +    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const
> +{
> +    BOOL_32 valid = TRUE;
> +
> +    if (pIn->swizzleMode >= ADDR_SW_MAX_TYPE)
> +    {
> +        ADDR_ASSERT_ALWAYS();
> +        valid = FALSE;
> +    }
> +
> +    const BOOL_32 mipmap = (pIn->numMipLevels > 1);
> +    const BOOL_32 msaa   = (pIn->numFrags > 1);
> +    const BOOL_32 isBc   = ElemLib::IsBlockCompressed(pIn->format);
> +    const BOOL_32 is422  = ElemLib::IsMacroPixelPacked(pIn->format);
> +
> +    const AddrResourceType rsrcType = pIn->resourceType;
> +    const BOOL_32          tex3d    = IsTex3d(rsrcType);
> +    const BOOL_32          tex2d    = IsTex2d(rsrcType);
> +    const BOOL_32          tex1d    = IsTex1d(rsrcType);
> +
> +    const AddrSwizzleMode  swizzle     = pIn->swizzleMode;
> +    const BOOL_32          linear      = IsLinear(swizzle);
> +    const BOOL_32          blk256B     = IsBlock256b(swizzle);
> +    const BOOL_32          blkVar      = IsBlockVariable(swizzle);
> +    const BOOL_32          isNonPrtXor = IsNonPrtXor(swizzle);
> +
> +    const ADDR2_SURFACE_FLAGS flags   = pIn->flags;
> +    const BOOL_32             zbuffer = flags.depth || flags.stencil;
> +    const BOOL_32             color   = flags.color;
> +    const BOOL_32             texture = flags.texture;
> +    const BOOL_32             display = flags.display || flags.rotated;
> +    const BOOL_32             prt     = flags.prt;
> +    const BOOL_32             fmask   = flags.fmask;
> +
> +    const BOOL_32             thin3d  = tex3d && flags.view3dAs2dArray;
> +    const BOOL_32             zMaxMip = tex3d && mipmap &&
> +                                        (pIn->numSlices >= pIn->width) && (pIn->numSlices >= pIn->height);
> +
> +    // Misc check
> +    if (msaa && (GetBlockSize(swizzle) < (m_pipeInterleaveBytes * pIn->numFrags)))
> +    {
> +        // MSAA surface must have blk_bytes/pipe_interleave >= num_samples
> +        ADDR_ASSERT_ALWAYS();
> +        valid = FALSE;
> +    }
> +
> +    if (display && (IsValidDisplaySwizzleMode(pIn) == FALSE))
> +    {
> +        ADDR_ASSERT_ALWAYS();
> +        valid = FALSE;
> +    }
> +
> +    if ((pIn->bpp == 96) && (linear == FALSE))
> +    {
> +        ADDR_ASSERT_ALWAYS();
> +        valid = FALSE;
> +    }
> +
> +    if (prt && isNonPrtXor)
>      {
> -        if (display)
> +        ADDR_ASSERT_ALWAYS();
> +        valid = FALSE;
> +    }
> +
> +    // Resource type check
> +    if (tex1d)
> +    {
> +        if (linear == FALSE)
>          {
> -            invalid = (IsValidDisplaySwizzleMode(pIn) == FALSE);
> +            ADDR_ASSERT_ALWAYS();
> +            valid = FALSE;
>          }
>      }
>
> -    if (invalid == FALSE)
> +    // Swizzle type check
> +    if (linear)
>      {
> -        if (linear)
> +        if (((tex1d == FALSE) && prt) || zbuffer || msaa || (pIn->bpp == 0) ||
> +            ((pIn->bpp % 8) != 0) || (isBc && texture) || fmask)
>          {
> -            invalid = ((ADDR_RSRC_TEX_1D != rsrcType) && prt) ||
> -                      zbuffer || msaa || (pIn->bpp == 0) || ((pIn->bpp % 8) != 0);
> +            ADDR_ASSERT_ALWAYS();
> +            valid = FALSE;
>          }
> -        else
> +    }
> +    else if (IsZOrderSwizzle(swizzle))
> +    {
> +        if ((color && msaa) || thin3d || isBc || is422 || (tex2d && (pIn->bpp > 64)) || (msaa && (pIn->bpp > 32)))
>          {
> -            if (blk256B || blkVar || isNonPrtXor)
> -            {
> -                invalid = prt;
> -                if (blk256B)
> -                {
> -                    invalid = invalid || zbuffer || tex3d || mipmap || msaa;
> -                }
> -            }
> +            ADDR_ASSERT_ALWAYS();
> +            valid = FALSE;
> +        }
> +    }
> +    else if (IsStandardSwizzle(swizzle))
> +    {
> +        if (zbuffer || thin3d || (tex3d && (pIn->bpp == 128) && color) || fmask)
> +        {
> +            ADDR_ASSERT_ALWAYS();
> +            valid = FALSE;
> +        }
> +    }
> +    else if (IsDisplaySwizzle(swizzle))
> +    {
> +        if (zbuffer || (prt && tex3d) || fmask || zMaxMip)
> +        {
> +            ADDR_ASSERT_ALWAYS();
> +            valid = FALSE;
> +        }
> +    }
> +    else if (IsRotateSwizzle(swizzle))
> +    {
> +        if (zbuffer || (pIn->bpp > 64) || tex3d || isBc || fmask)
> +        {
> +            ADDR_ASSERT_ALWAYS();
> +            valid = FALSE;
> +        }
> +    }
> +    else
> +    {
> +        ADDR_ASSERT_ALWAYS();
> +        valid = FALSE;
> +    }
>
> -            if (invalid == FALSE)
> -            {
> -                if (IsZOrderSwizzle(swizzle))
> -                {
> -                    invalid = (color && msaa) || thin3d;
> -                }
> -                else if (IsStandardSwizzle(swizzle))
> -                {
> -                    invalid = zbuffer || thin3d;
> -                }
> -                else if (IsDisplaySwizzle(swizzle))
> -                {
> -                    invalid = zbuffer || (prt && (ADDR_RSRC_TEX_3D == rsrcType));
> -                }
> -                else if (IsRotateSwizzle(swizzle))
> -                {
> -                    invalid = zbuffer || (pIn->bpp > 64) || tex3d;
> -                }
> -                else
> -                {
> -                    ADDR_ASSERT(!"invalid swizzle mode");
> -                    invalid = TRUE;
> -                }
> -            }
> +    // Block type check
> +    if (blk256B)
> +    {
> +        if (prt || zbuffer || tex3d || mipmap || msaa)
> +        {
> +            ADDR_ASSERT_ALWAYS();
> +            valid = FALSE;
>          }
>      }
> +    else if (blkVar)
> +    {
> +        ADDR_ASSERT_ALWAYS();
> +        valid = FALSE;
> +    }
>
> -    ADDR_ASSERT(invalid == FALSE);
> +    return valid;
> +}
>
> -    return invalid ? ADDR_INVALIDPARAMS : ADDR_OK;
> +/**
> +************************************************************************************************************************
> +*   Gfx9Lib::HwlComputeSurfaceInfoSanityCheck
> +*
> +*   @brief
> +*       Compute surface info sanity check
> +*
> +*   @return
> +*       ADDR_OK if parameters are valid, ADDR_INVALIDPARAMS otherwise
> +************************************************************************************************************************
> +*/
> +ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceInfoSanityCheck(
> +    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const
> +{
> +    return ValidateNonSwModeParams(pIn) && ValidateSwModeParams(pIn) ? ADDR_OK : ADDR_INVALIDPARAMS;
>  }
>
>  /**
> @@ -3262,14 +3373,14 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlGetPreferredSurfaceSetting(
>      const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
>      ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const
>  {
> -    ADDR_E_RETURNCODE returnCode = ADDR_OK;
> +    ADDR_E_RETURNCODE returnCode = ADDR_INVALIDPARAMS;
>      ElemLib*          pElemLib   = GetElemLib();
>
> -    UINT_32 bpp          = pIn->bpp;
> -    UINT_32 width        = pIn->width;
> -    UINT_32 height       = pIn->height;
> -    UINT_32 numSamples   = Max(pIn->numSamples, 1u);
> -    UINT_32 numFrags     = (pIn->numFrags == 0) ? numSamples : pIn->numFrags;
> +    UINT_32 bpp        = pIn->bpp;
> +    UINT_32 width      = Max(pIn->width, 1u);
> +    UINT_32 height     = Max(pIn->height, 1u);
> +    UINT_32 numSamples = Max(pIn->numSamples, 1u);
> +    UINT_32 numFrags   = (pIn->numFrags == 0) ? numSamples : pIn->numFrags;
>
>      if (pIn->flags.fmask)
>      {
> @@ -3313,378 +3424,389 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlGetPreferredSurfaceSetting(
>      const BOOL_32 msaa         = (numFrags > 1) || (numSamples > 1);
>      const BOOL_32 displayRsrc  = pIn->flags.display || pIn->flags.rotated;
>
> -    // Forbid swizzle mode(s) by client setting, for simplicity we never allow VAR swizzle mode for GFX9
> -    ADDR2_SWMODE_SET allowedSwModeSet = {};
> -    allowedSwModeSet.value |= pIn->forbiddenBlock.linear    ? 0 : Gfx9LinearSwModeMask;
> -    allowedSwModeSet.value |= pIn->forbiddenBlock.micro     ? 0 : Gfx9Blk256BSwModeMask;
> -    allowedSwModeSet.value |= pIn->forbiddenBlock.macro4KB  ? 0 : Gfx9Blk4KBSwModeMask;
> -    allowedSwModeSet.value |= pIn->forbiddenBlock.macro64KB ? 0 : Gfx9Blk64KBSwModeMask;
> -
> -    if (pIn->preferredSwSet.value != 0)
> -    {
> -        allowedSwModeSet.value &= pIn->preferredSwSet.sw_Z ? ~0 : ~Gfx9ZSwModeMask;
> -        allowedSwModeSet.value &= pIn->preferredSwSet.sw_S ? ~0 : ~Gfx9StandardSwModeMask;
> -        allowedSwModeSet.value &= pIn->preferredSwSet.sw_D ? ~0 : ~Gfx9DisplaySwModeMask;
> -        allowedSwModeSet.value &= pIn->preferredSwSet.sw_R ? ~0 : ~Gfx9RotateSwModeMask;
> -    }
> -
> -    if (pIn->noXor)
> -    {
> -        allowedSwModeSet.value &= ~Gfx9XorSwModeMask;
> -    }
> -
> -    if (pIn->maxAlign > 0)
> +    // Pre sanity check on non swizzle mode parameters
> +    ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {};
> +    localIn.flags        = pIn->flags;
> +    localIn.resourceType = pOut->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     = numFrags;
> +
> +    if (ValidateNonSwModeParams(&localIn))
>      {
> -        if (pIn->maxAlign < GetBlockSize(ADDR_SW_64KB))
> +        // Forbid swizzle mode(s) by client setting, for simplicity we never allow VAR swizzle mode for GFX9
> +        ADDR2_SWMODE_SET allowedSwModeSet = {};
> +        allowedSwModeSet.value |= pIn->forbiddenBlock.linear    ? 0 : Gfx9LinearSwModeMask;
> +        allowedSwModeSet.value |= pIn->forbiddenBlock.micro     ? 0 : Gfx9Blk256BSwModeMask;
> +        allowedSwModeSet.value |= pIn->forbiddenBlock.macro4KB  ? 0 : Gfx9Blk4KBSwModeMask;
> +        allowedSwModeSet.value |= pIn->forbiddenBlock.macro64KB ? 0 : Gfx9Blk64KBSwModeMask;
> +
> +        if (pIn->preferredSwSet.value != 0)
>          {
> -            allowedSwModeSet.value &= ~Gfx9Blk64KBSwModeMask;
> +            allowedSwModeSet.value &= pIn->preferredSwSet.sw_Z ? ~0 : ~Gfx9ZSwModeMask;
> +            allowedSwModeSet.value &= pIn->preferredSwSet.sw_S ? ~0 : ~Gfx9StandardSwModeMask;
> +            allowedSwModeSet.value &= pIn->preferredSwSet.sw_D ? ~0 : ~Gfx9DisplaySwModeMask;
> +            allowedSwModeSet.value &= pIn->preferredSwSet.sw_R ? ~0 : ~Gfx9RotateSwModeMask;
>          }
>
> -        if (pIn->maxAlign < GetBlockSize(ADDR_SW_4KB))
> +        if (pIn->noXor)
>          {
> -            allowedSwModeSet.value &= ~Gfx9Blk4KBSwModeMask;
> +            allowedSwModeSet.value &= ~Gfx9XorSwModeMask;
>          }
>
> -        if (pIn->maxAlign < GetBlockSize(ADDR_SW_256B))
> +        if (pIn->maxAlign > 0)
>          {
> -            allowedSwModeSet.value &= ~Gfx9Blk256BSwModeMask;
> -        }
> -    }
> -
> -    // Filter out invalid swizzle mode(s) by image attributes and HW restrictions
> -    switch (pOut->resourceType)
> -    {
> -        case ADDR_RSRC_TEX_1D:
> -            allowedSwModeSet.value &= Gfx9Rsrc1dSwModeMask;
> -            break;
> -
> -        case ADDR_RSRC_TEX_2D:
> -            allowedSwModeSet.value &= pIn->flags.prt ? Gfx9Rsrc2dPrtSwModeMask : Gfx9Rsrc2dSwModeMask;
> -
> -            if (bpp > 64)
> +            if (pIn->maxAlign < GetBlockSize(ADDR_SW_64KB))
>              {
> -                allowedSwModeSet.value &= ~(Gfx9RotateSwModeMask | Gfx9ZSwModeMask);
> +                allowedSwModeSet.value &= ~Gfx9Blk64KBSwModeMask;
>              }
> -            break;
>
> -        case ADDR_RSRC_TEX_3D:
> -            allowedSwModeSet.value &= pIn->flags.prt ? Gfx9Rsrc3dPrtSwModeMask : Gfx9Rsrc3dSwModeMask;
> -
> -            if ((numMipLevels > 1) && (numSlices >= width) && (numSlices >= height))
> +            if (pIn->maxAlign < GetBlockSize(ADDR_SW_4KB))
>              {
> -                // SW_*_D for 3D mipmaps (maxmip > 0) is only supported for Xmajor or Ymajor mipmap
> -                // When depth (Z) is the maximum dimension then must use one of the SW_*_S
> -                // or SW_*_Z modes if mipmapping is desired on a 3D surface
> -                allowedSwModeSet.value &= ~Gfx9DisplaySwModeMask;
> +                allowedSwModeSet.value &= ~Gfx9Blk4KBSwModeMask;
>              }
>
> -            if ((bpp == 128) && pIn->flags.color)
> +            if (pIn->maxAlign < GetBlockSize(ADDR_SW_256B))
>              {
> -                allowedSwModeSet.value &= ~Gfx9StandardSwModeMask;
> +                allowedSwModeSet.value &= ~Gfx9Blk256BSwModeMask;
>              }
> +        }
>
> -            if (pIn->flags.view3dAs2dArray)
> -            {
> -                allowedSwModeSet.value &= Gfx9Rsrc3dThinSwModeMask | Gfx9LinearSwModeMask;
> -            }
> -            break;
> +        // Filter out invalid swizzle mode(s) by image attributes and HW restrictions
> +        switch (pOut->resourceType)
> +        {
> +            case ADDR_RSRC_TEX_1D:
> +                allowedSwModeSet.value &= Gfx9Rsrc1dSwModeMask;
> +                break;
>
> -        default:
> -            ADDR_ASSERT_ALWAYS();
> -            allowedSwModeSet.value = 0;
> -            break;
> -    }
> +            case ADDR_RSRC_TEX_2D:
> +                allowedSwModeSet.value &= pIn->flags.prt ? Gfx9Rsrc2dPrtSwModeMask : Gfx9Rsrc2dSwModeMask;
>
> -    if (pIn->format == ADDR_FMT_32_32_32)
> -    {
> -        allowedSwModeSet.value &= Gfx9LinearSwModeMask;
> -    }
> +                if (bpp > 64)
> +                {
> +                    allowedSwModeSet.value &= ~(Gfx9RotateSwModeMask | Gfx9ZSwModeMask);
> +                }
> +                break;
>
> -    if (ElemLib::IsBlockCompressed(pIn->format))
> -    {
> -        if (pIn->flags.texture)
> -        {
> -            allowedSwModeSet.value &= Gfx9StandardSwModeMask | Gfx9DisplaySwModeMask;
> +            case ADDR_RSRC_TEX_3D:
> +                allowedSwModeSet.value &= pIn->flags.prt ? Gfx9Rsrc3dPrtSwModeMask : Gfx9Rsrc3dSwModeMask;
> +
> +                if ((numMipLevels > 1) && (numSlices >= width) && (numSlices >= height))
> +                {
> +                    // SW_*_D for 3D mipmaps (maxmip > 0) is only supported for Xmajor or Ymajor mipmap
> +                    // When depth (Z) is the maximum dimension then must use one of the SW_*_S
> +                    // or SW_*_Z modes if mipmapping is desired on a 3D surface
> +                    allowedSwModeSet.value &= ~Gfx9DisplaySwModeMask;
> +                }
> +
> +                if ((bpp == 128) && pIn->flags.color)
> +                {
> +                    allowedSwModeSet.value &= ~Gfx9StandardSwModeMask;
> +                }
> +
> +                if (pIn->flags.view3dAs2dArray)
> +                {
> +                    allowedSwModeSet.value &= Gfx9Rsrc3dThinSwModeMask | Gfx9LinearSwModeMask;
> +                }
> +                break;
> +
> +            default:
> +                ADDR_ASSERT_ALWAYS();
> +                allowedSwModeSet.value = 0;
> +                break;
>          }
> -        else
> +
> +        if (pIn->format == ADDR_FMT_32_32_32)
>          {
> -            allowedSwModeSet.value &= Gfx9StandardSwModeMask | Gfx9DisplaySwModeMask | Gfx9LinearSwModeMask;
> +            allowedSwModeSet.value &= Gfx9LinearSwModeMask;
>          }
> -    }
>
> -    if (ElemLib::IsMacroPixelPacked(pIn->format) ||
> -        (msaa && ((bpp > 32) || pIn->flags.color || pIn->flags.unordered)))
> -    {
> -        allowedSwModeSet.value &= ~Gfx9ZSwModeMask;
> -    }
> -
> -    if (pIn->flags.fmask || pIn->flags.depth || pIn->flags.stencil)
> -    {
> -        allowedSwModeSet.value &= Gfx9ZSwModeMask;
> -
> -        if (pIn->flags.noMetadata == FALSE)
> +        if (ElemLib::IsBlockCompressed(pIn->format))
>          {
> -            if (pIn->flags.depth &&
> -                pIn->flags.texture &&
> -                (((bpp == 16) && (numFrags >= 4)) || ((bpp == 32) && (numFrags >= 2))))
> +            if (pIn->flags.texture)
>              {
> -                // When _X/_T swizzle mode was used for MSAA depth texture, TC will get zplane
> -                // equation from wrong address within memory range a tile covered and use the
> -                // garbage data for compressed Z reading which finally leads to corruption.
> -                allowedSwModeSet.value &= ~Gfx9XorSwModeMask;
> +                allowedSwModeSet.value &= Gfx9StandardSwModeMask | Gfx9DisplaySwModeMask;
>              }
> -
> -            if (m_settings.htileCacheRbConflict &&
> -                (pIn->flags.depth || pIn->flags.stencil) &&
> -                (numSlices > 1) &&
> -                (pIn->flags.metaRbUnaligned == FALSE) &&
> -                (pIn->flags.metaPipeUnaligned == FALSE))
> +            else
>              {
> -                // Z_X 2D array with Rb/Pipe aligned HTile won't have metadata cache coherency
> -                allowedSwModeSet.value &= ~Gfx9XSwModeMask;
> +                allowedSwModeSet.value &= Gfx9StandardSwModeMask | Gfx9DisplaySwModeMask | Gfx9LinearSwModeMask;
>              }
>          }
> -    }
>
> -    if (msaa)
> -    {
> -        allowedSwModeSet.value &= Gfx9MsaaSwModeMask;
> -    }
> -
> -    if ((numFrags > 1) &&
> -        (GetBlockSize(ADDR_SW_4KB) < (m_pipeInterleaveBytes * numFrags)))
> -    {
> -        // MSAA surface must have blk_bytes/pipe_interleave >= num_samples
> -        allowedSwModeSet.value &= Gfx9Blk64KBSwModeMask;
> -    }
> -
> -    if (numMipLevels > 1)
> -    {
> -        allowedSwModeSet.value &= ~Gfx9Blk256BSwModeMask;
> -    }
> -
> -    if (displayRsrc)
> -    {
> -        if (m_settings.isDce12)
> +        if (ElemLib::IsMacroPixelPacked(pIn->format) ||
> +            (msaa && ((bpp > 32) || pIn->flags.color || pIn->flags.unordered)))
>          {
> -            allowedSwModeSet.value &= (bpp == 32) ? Dce12Bpp32SwModeMask : Dce12NonBpp32SwModeMask;
> +            allowedSwModeSet.value &= ~Gfx9ZSwModeMask;
>          }
> -        else if (m_settings.isDcn1)
> -        {
> -            allowedSwModeSet.value &= (bpp == 64) ? Dcn1Bpp64SwModeMask : Dcn1NonBpp64SwModeMask;
> -        }
> -        else
> -        {
> -            ADDR_NOT_IMPLEMENTED();
> -        }
> -    }
>
> -    if (allowedSwModeSet.value != 0)
> -    {
> -#if DEBUG
> -        // Post sanity check, at least AddrLib should accept the output generated by its own
> -        ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {};
> -        localIn.flags        = pIn->flags;
> -        localIn.resourceType = pOut->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     = numFrags;
> -
> -        UINT_32 validateSwModeSet = allowedSwModeSet.value;
> -        for (UINT_32 i = 0; validateSwModeSet != 0; i++)
> +        if (pIn->flags.fmask || pIn->flags.depth || pIn->flags.stencil)
>          {
> -            if (validateSwModeSet & 1)
> +            allowedSwModeSet.value &= Gfx9ZSwModeMask;
> +
> +            if (pIn->flags.noMetadata == FALSE)
>              {
> -                localIn.swizzleMode = static_cast<AddrSwizzleMode>(i);
> -                HwlComputeSurfaceInfoSanityCheck(&localIn);
> -            }
> +                if (pIn->flags.depth &&
> +                    pIn->flags.texture &&
> +                    (((bpp == 16) && (numFrags >= 4)) || ((bpp == 32) && (numFrags >= 2))))
> +                {
> +                    // When _X/_T swizzle mode was used for MSAA depth texture, TC will get zplane
> +                    // equation from wrong address within memory range a tile covered and use the
> +                    // garbage data for compressed Z reading which finally leads to corruption.
> +                    allowedSwModeSet.value &= ~Gfx9XorSwModeMask;
> +                }
>
> -            validateSwModeSet >>= 1;
> +                if (m_settings.htileCacheRbConflict &&
> +                    (pIn->flags.depth || pIn->flags.stencil) &&
> +                    (numSlices > 1) &&
> +                    (pIn->flags.metaRbUnaligned == FALSE) &&
> +                    (pIn->flags.metaPipeUnaligned == FALSE))
> +                {
> +                    // Z_X 2D array with Rb/Pipe aligned HTile won't have metadata cache coherency
> +                    allowedSwModeSet.value &= ~Gfx9XSwModeMask;
> +                }
> +            }
>          }
> -#endif
>
> -        pOut->validSwModeSet = allowedSwModeSet;
> -        pOut->canXor         = (allowedSwModeSet.value & Gfx9XorSwModeMask) ? TRUE : FALSE;
> -        pOut->validBlockSet  = GetAllowedBlockSet(allowedSwModeSet);
> -        pOut->validSwTypeSet = GetAllowedSwSet(allowedSwModeSet);
> -
> -        pOut->clientPreferredSwSet = pIn->preferredSwSet;
> +        if (msaa)
> +        {
> +            allowedSwModeSet.value &= Gfx9MsaaSwModeMask;
> +        }
>
> -        if (pOut->clientPreferredSwSet.value == 0)
> +        if ((numFrags > 1) &&
> +            (GetBlockSize(ADDR_SW_4KB) < (m_pipeInterleaveBytes * numFrags)))
>          {
> -            pOut->clientPreferredSwSet.value = AddrSwSetAll;
> +            // MSAA surface must have blk_bytes/pipe_interleave >= num_samples
> +            allowedSwModeSet.value &= Gfx9Blk64KBSwModeMask;
>          }
>
> -        if (allowedSwModeSet.value == Gfx9LinearSwModeMask)
> +        if (numMipLevels > 1)
>          {
> -            pOut->swizzleMode = ADDR_SW_LINEAR;
> +            allowedSwModeSet.value &= ~Gfx9Blk256BSwModeMask;
>          }
> -        else
> +
> +        if (displayRsrc)
>          {
> -            // Always ignore linear swizzle mode if there is other choice.
> -            allowedSwModeSet.swLinear = 0;
> +            if (m_settings.isDce12)
> +            {
> +                allowedSwModeSet.value &= (bpp == 32) ? Dce12Bpp32SwModeMask : Dce12NonBpp32SwModeMask;
> +            }
> +            else if (m_settings.isDcn1)
> +            {
> +                allowedSwModeSet.value &= (bpp == 64) ? Dcn1Bpp64SwModeMask : Dcn1NonBpp64SwModeMask;
> +            }
> +            else
> +            {
> +                ADDR_NOT_IMPLEMENTED();
> +            }
> +        }
>
> -            ADDR2_BLOCK_SET allowedBlockSet = GetAllowedBlockSet(allowedSwModeSet);
> +        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;
>
> -            // Determine block size if there is 2 or more block type candidates
> -            if (IsPow2(allowedBlockSet.value) == FALSE)
> +            for (UINT_32 i = 0; validateSwModeSet != 0; i++)
>              {
> -                const AddrSwizzleMode swMode[AddrBlockMaxTiledType]  = {ADDR_SW_256B, ADDR_SW_4KB, ADDR_SW_64KB};
> -                Dim3d                 blkDim[AddrBlockMaxTiledType]  = {{0}, {0}, {0}};
> -                Dim3d                 padDim[AddrBlockMaxTiledType]  = {{0}, {0}, {0}};
> -                UINT_64               padSize[AddrBlockMaxTiledType] = {0};
> -
> -                const UINT_32 ratioLow           = pIn->flags.minimizeAlign ? 1 : (pIn->flags.opt4space ? 3 : 2);
> -                const UINT_32 ratioHi            = pIn->flags.minimizeAlign ? 1 : (pIn->flags.opt4space ? 2 : 1);
> -                const UINT_64 sizeAlignInElement = Max(NextPow2(pIn->minSizeAlign) / (bpp >> 3), 1u);
> -                UINT_32       minSizeBlk         = AddrBlockMicro;
> -                UINT_64       minSize            = 0;
> -
> -                for (UINT_32 i = AddrBlockMicro; i < AddrBlockMaxTiledType; i++)
> +                if (validateSwModeSet & 1)
>                  {
> -                    if (allowedBlockSet.value & (1 << i))
> -                    {
> -                        ComputeBlockDimensionForSurf(&blkDim[i].w,
> -                                                     &blkDim[i].h,
> -                                                     &blkDim[i].d,
> -                                                     bpp,
> -                                                     numFrags,
> -                                                     pOut->resourceType,
> -                                                     swMode[i]);
> -
> -                        if (displayRsrc)
> -                        {
> -                            blkDim[i].w = PowTwoAlign(blkDim[i].w, 32);
> -                        }
> +                    localIn.swizzleMode = static_cast<AddrSwizzleMode>(i);
> +                    ADDR_ASSERT(ValidateSwModeParams(&localIn));
> +                }
>
> -                        padSize[i] = ComputePadSize(&blkDim[i], width, height, numSlices, &padDim[i]);
> -                        padSize[i] = PowTwoAlign(padSize[i], sizeAlignInElement);
> +                validateSwModeSet >>= 1;
> +            }
> +#endif
>
> -                        if ((minSize == 0) ||
> -                            ((padSize[i] * ratioHi) <= (minSize * ratioLow)))
> -                        {
> -                            minSize    = padSize[i];
> -                            minSizeBlk = i;
> -                        }
> -                    }
> -                }
> +            pOut->validSwModeSet = allowedSwModeSet;
> +            pOut->canXor         = (allowedSwModeSet.value & Gfx9XorSwModeMask) ? TRUE : FALSE;
> +            pOut->validBlockSet  = GetAllowedBlockSet(allowedSwModeSet);
> +            pOut->validSwTypeSet = GetAllowedSwSet(allowedSwModeSet);
>
> -                if ((allowedBlockSet.micro == TRUE)      &&
> -                    (width  <= blkDim[AddrBlockMicro].w) &&
> -                    (height <= blkDim[AddrBlockMicro].h) &&
> -                    (NextPow2(pIn->minSizeAlign) <= GetBlockSize(ADDR_SW_256B)))
> -                {
> -                    minSizeBlk = AddrBlockMicro;
> -                }
> +            pOut->clientPreferredSwSet = pIn->preferredSwSet;
>
> -                if (minSizeBlk == AddrBlockMicro)
> -                {
> -                    allowedSwModeSet.value &= Gfx9Blk256BSwModeMask;
> -                }
> -                else if (minSizeBlk == AddrBlock4KB)
> -                {
> -                    allowedSwModeSet.value &= Gfx9Blk4KBSwModeMask;
> -                }
> -                else
> -                {
> -                    ADDR_ASSERT(minSizeBlk == AddrBlock64KB);
> -                    allowedSwModeSet.value &= Gfx9Blk64KBSwModeMask;
> -                }
> +            if (pOut->clientPreferredSwSet.value == 0)
> +            {
> +                pOut->clientPreferredSwSet.value = AddrSwSetAll;
>              }
>
> -            // Block type should be determined.
> -            ADDR_ASSERT(IsPow2(GetAllowedBlockSet(allowedSwModeSet).value));
> +            if (allowedSwModeSet.value == Gfx9LinearSwModeMask)
> +            {
> +                pOut->swizzleMode = ADDR_SW_LINEAR;
> +            }
> +            else
> +            {
> +                // Always ignore linear swizzle mode if there is other choice.
> +                allowedSwModeSet.swLinear = 0;
>
> -            ADDR2_SWTYPE_SET allowedSwSet = GetAllowedSwSet(allowedSwModeSet);
> +                ADDR2_BLOCK_SET allowedBlockSet = GetAllowedBlockSet(allowedSwModeSet);
>
> -            // Determine swizzle type if there is 2 or more swizzle type candidates
> -            if (IsPow2(allowedSwSet.value) == FALSE)
> -            {
> -                if (ElemLib::IsBlockCompressed(pIn->format))
> +                // Determine block size if there is 2 or more block type candidates
> +                if (IsPow2(allowedBlockSet.value) == FALSE)
>                  {
> -                    if (allowedSwSet.sw_D)
> +                    const AddrSwizzleMode swMode[AddrBlockMaxTiledType]  = {ADDR_SW_256B, ADDR_SW_4KB, ADDR_SW_64KB};
> +                    Dim3d                 blkDim[AddrBlockMaxTiledType]  = {{0}, {0}, {0}};
> +                    Dim3d                 padDim[AddrBlockMaxTiledType]  = {{0}, {0}, {0}};
> +                    UINT_64               padSize[AddrBlockMaxTiledType] = {0};
> +
> +                    const UINT_32 ratioLow           = pIn->flags.minimizeAlign ? 1 : (pIn->flags.opt4space ? 3 : 2);
> +                    const UINT_32 ratioHi            = pIn->flags.minimizeAlign ? 1 : (pIn->flags.opt4space ? 2 : 1);
> +                    const UINT_64 sizeAlignInElement = Max(NextPow2(pIn->minSizeAlign) / (bpp >> 3), 1u);
> +                    UINT_32       minSizeBlk         = AddrBlockMicro;
> +                    UINT_64       minSize            = 0;
> +
> +                    for (UINT_32 i = AddrBlockMicro; i < AddrBlockMaxTiledType; i++)
>                      {
> -                        allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
> -                    }
> -                    else
> -                    {
> -                        ADDR_ASSERT(allowedSwSet.sw_S);
> -                        allowedSwModeSet.value &= Gfx9StandardSwModeMask;
> -                    }
> -                }
> -                else if (ElemLib::IsMacroPixelPacked(pIn->format))
> -                {
> -                    if (allowedSwSet.sw_S)
> -                    {
> -                        allowedSwModeSet.value &= Gfx9StandardSwModeMask;
> -                    }
> -                    else if (allowedSwSet.sw_D)
> -                    {
> -                        allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
> +                        if (allowedBlockSet.value & (1 << i))
> +                        {
> +                            ComputeBlockDimensionForSurf(&blkDim[i].w,
> +                                                         &blkDim[i].h,
> +                                                         &blkDim[i].d,
> +                                                         bpp,
> +                                                         numFrags,
> +                                                         pOut->resourceType,
> +                                                         swMode[i]);
> +
> +                            if (displayRsrc)
> +                            {
> +                                blkDim[i].w = PowTwoAlign(blkDim[i].w, 32);
> +                            }
> +
> +                            padSize[i] = ComputePadSize(&blkDim[i], width, height, numSlices, &padDim[i]);
> +                            padSize[i] = PowTwoAlign(padSize[i], sizeAlignInElement);
> +
> +                            if ((minSize == 0) ||
> +                                ((padSize[i] * ratioHi) <= (minSize * ratioLow)))
> +                            {
> +                                minSize    = padSize[i];
> +                                minSizeBlk = i;
> +                            }
> +                        }
>                      }
> -                    else
> +
> +                    if ((allowedBlockSet.micro == TRUE)      &&
> +                        (width  <= blkDim[AddrBlockMicro].w) &&
> +                        (height <= blkDim[AddrBlockMicro].h) &&
> +                        (NextPow2(pIn->minSizeAlign) <= GetBlockSize(ADDR_SW_256B)))
>                      {
> -                        ADDR_ASSERT(allowedSwSet.sw_R);
> -                        allowedSwModeSet.value &= Gfx9RotateSwModeMask;
> +                        minSizeBlk = AddrBlockMicro;
>                      }
> -                }
> -                else if (pOut->resourceType == ADDR_RSRC_TEX_3D)
> -                {
> -                    if (pIn->flags.color && allowedSwSet.sw_D)
> +
> +                    if (minSizeBlk == AddrBlockMicro)
>                      {
> -                        allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
> +                        allowedSwModeSet.value &= Gfx9Blk256BSwModeMask;
>                      }
> -                    else if (allowedSwSet.sw_Z)
> +                    else if (minSizeBlk == AddrBlock4KB)
>                      {
> -                        allowedSwModeSet.value &= Gfx9ZSwModeMask;
> +                        allowedSwModeSet.value &= Gfx9Blk4KBSwModeMask;
>                      }
>                      else
>                      {
> -                        ADDR_ASSERT(allowedSwSet.sw_S);
> -                        allowedSwModeSet.value &= Gfx9StandardSwModeMask;
> +                        ADDR_ASSERT(minSizeBlk == AddrBlock64KB);
> +                        allowedSwModeSet.value &= Gfx9Blk64KBSwModeMask;
>                      }
>                  }
> -                else
> +
> +                // Block type should be determined.
> +                ADDR_ASSERT(IsPow2(GetAllowedBlockSet(allowedSwModeSet).value));
> +
> +                ADDR2_SWTYPE_SET allowedSwSet = GetAllowedSwSet(allowedSwModeSet);
> +
> +                // Determine swizzle type if there is 2 or more swizzle type candidates
> +                if (IsPow2(allowedSwSet.value) == FALSE)
>                  {
> -                    if (pIn->flags.rotated && allowedSwSet.sw_R)
> +                    if (ElemLib::IsBlockCompressed(pIn->format))
>                      {
> -                        allowedSwModeSet.value &= Gfx9RotateSwModeMask;
> +                        if (allowedSwSet.sw_D)
> +                        {
> +                            allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
> +                        }
> +                        else
> +                        {
> +                            ADDR_ASSERT(allowedSwSet.sw_S);
> +                            allowedSwModeSet.value &= Gfx9StandardSwModeMask;
> +                        }
>                      }
> -                    else if (displayRsrc && allowedSwSet.sw_D)
> +                    else if (ElemLib::IsMacroPixelPacked(pIn->format))
>                      {
> -                        allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
> +                        if (allowedSwSet.sw_S)
> +                        {
> +                            allowedSwModeSet.value &= Gfx9StandardSwModeMask;
> +                        }
> +                        else if (allowedSwSet.sw_D)
> +                        {
> +                            allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
> +                        }
> +                        else
> +                        {
> +                            ADDR_ASSERT(allowedSwSet.sw_R);
> +                            allowedSwModeSet.value &= Gfx9RotateSwModeMask;
> +                        }
>                      }
> -                    else if (allowedSwSet.sw_S)
> +                    else if (pOut->resourceType == ADDR_RSRC_TEX_3D)
>                      {
> -                        allowedSwModeSet.value &= Gfx9StandardSwModeMask;
> +                        if (pIn->flags.color && allowedSwSet.sw_D)
> +                        {
> +                            allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
> +                        }
> +                        else if (allowedSwSet.sw_Z)
> +                        {
> +                            allowedSwModeSet.value &= Gfx9ZSwModeMask;
> +                        }
> +                        else
> +                        {
> +                            ADDR_ASSERT(allowedSwSet.sw_S);
> +                            allowedSwModeSet.value &= Gfx9StandardSwModeMask;
> +                        }
>                      }
>                      else
>                      {
> -                        ADDR_ASSERT(allowedSwSet.sw_Z);
> -                        allowedSwModeSet.value &= Gfx9ZSwModeMask;
> +                        if (pIn->flags.rotated && allowedSwSet.sw_R)
> +                        {
> +                            allowedSwModeSet.value &= Gfx9RotateSwModeMask;
> +                        }
> +                        else if (displayRsrc && allowedSwSet.sw_D)
> +                        {
> +                            allowedSwModeSet.value &= Gfx9DisplaySwModeMask;
> +                        }
> +                        else if (allowedSwSet.sw_S)
> +                        {
> +                            allowedSwModeSet.value &= Gfx9StandardSwModeMask;
> +                        }
> +                        else
> +                        {
> +                            ADDR_ASSERT(allowedSwSet.sw_Z);
> +                            allowedSwModeSet.value &= Gfx9ZSwModeMask;
> +                        }
>                      }
>                  }
> -            }
>
> -            // Swizzle type should be determined.
> -            ADDR_ASSERT(IsPow2(GetAllowedSwSet(allowedSwModeSet).value));
> +                // Swizzle type should be determined.
> +                ADDR_ASSERT(IsPow2(GetAllowedSwSet(allowedSwModeSet).value));
> +
> +                // Determine swizzle mode now - always select the "largest" swizzle mode for a given block type +
> +                // swizzle type combination. For example, for AddrBlock64KB + ADDR_SW_S, select SW_64KB_S_X(25) if it's
> +                // available, or otherwise select SW_64KB_S_T(17) if it's available, or otherwise select SW_64KB_S(9).
> +                pOut->swizzleMode = static_cast<AddrSwizzleMode>(Log2NonPow2(allowedSwModeSet.value));
> +            }
>
> -            // Determine swizzle mode now - always select the "largest" swizzle mode for a given block type +
> -            // swizzle type combination. For example, for AddrBlock64KB + ADDR_SW_S, select SW_64KB_S_X(25) if it's
> -            // available, or otherwise select SW_64KB_S_T(17) if it's available, or otherwise select SW_64KB_S(9).
> -            pOut->swizzleMode = static_cast<AddrSwizzleMode>(Log2NonPow2(allowedSwModeSet.value));
> +            returnCode = ADDR_OK;
> +        }
> +        else
> +        {
> +            // Invalid combination...
> +            ADDR_ASSERT_ALWAYS();
>          }
>      }
>      else
>      {
>          // Invalid combination...
>          ADDR_ASSERT_ALWAYS();
> -        returnCode = ADDR_INVALIDPARAMS;
>      }
>
>      return returnCode;
> @@ -3992,7 +4114,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceInfoTiled(
>                  // Then we need extra padding for base surface. Otherwise, metadata and data surface for same pixel will
>                  // be flushed to different pipes, but texture engine only uses pipe id of data surface to fetch both of
>                  // them, which may cause invalid metadata to be fetched.
> -                pOut->baseAlign = Max(pOut->baseAlign, m_pipeInterleaveBytes * m_pipes);
> +                pOut->baseAlign = Max(pOut->baseAlign, m_pipeInterleaveBytes * m_pipes * m_se);
>              }
>
>              if (pIn->flags.prt)
> diff --git a/src/amd/addrlib/src/gfx9/gfx9addrlib.h b/src/amd/addrlib/src/gfx9/gfx9addrlib.h
> index 73f035370db..d64d8e879b4 100644
> --- a/src/amd/addrlib/src/gfx9/gfx9addrlib.h
> +++ b/src/amd/addrlib/src/gfx9/gfx9addrlib.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> @@ -615,6 +615,34 @@ private:
>          return allowedSwSet;
>      }
>
> +    BOOL_32 IsInMipTail(
> +        AddrResourceType  resourceType,
> +        AddrSwizzleMode   swizzleMode,
> +        Dim3d             mipTailDim,
> +        UINT_32           width,
> +        UINT_32           height,
> +        UINT_32           depth) const
> +    {
> +        BOOL_32 inTail = ((width <= mipTailDim.w) &&
> +                          (height <= mipTailDim.h) &&
> +                          (IsThin(resourceType, swizzleMode) || (depth <= mipTailDim.d)));
> +
> +        return inTail;
> +    }
> +
> +    BOOL_32 ValidateNonSwModeParams(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;
> +    BOOL_32 ValidateSwModeParams(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;
> +
> +    UINT_32 GetBankXorBits(UINT_32 macroBlockBits) const
> +    {
> +        UINT_32 pipeBits = GetPipeXorBits(macroBlockBits);
> +
> +        // Bank xor bits
> +        UINT_32 bankBits = Min(macroBlockBits - pipeBits - m_pipeInterleaveLog2, m_banksLog2);
> +
> +        return bankBits;
> +    }
> +
>      Gfx9ChipSettings m_settings;
>
>      CoordEq      m_cachedMetaEq[MaxCachedMetaEq];
> diff --git a/src/amd/addrlib/src/r800/ciaddrlib.cpp b/src/amd/addrlib/src/r800/ciaddrlib.cpp
> index 5bec0918471..5a83e715301 100644
> --- a/src/amd/addrlib/src/r800/ciaddrlib.cpp
> +++ b/src/amd/addrlib/src/r800/ciaddrlib.cpp
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> @@ -210,7 +210,7 @@ ADDR_E_RETURNCODE CiLib::HwlComputeDccInfo(
>  {
>      ADDR_E_RETURNCODE returnCode = ADDR_OK;
>
> -    if (m_settings.isVolcanicIslands && IsMacroTiled(pIn->tileMode))
> +    if (SupportDccAndTcCompatibility() && IsMacroTiled(pIn->tileMode))
>      {
>          UINT_64 dccFastClearSize = pIn->colorSurfSize >> 8;
>
> @@ -294,7 +294,7 @@ ADDR_E_RETURNCODE CiLib::HwlComputeCmaskAddrFromCoord(
>  {
>      ADDR_E_RETURNCODE returnCode = ADDR_NOTSUPPORTED;
>
> -    if ((m_settings.isVolcanicIslands == TRUE) &&
> +    if ((SupportDccAndTcCompatibility() == TRUE) &&
>          (pIn->flags.tcCompatible == TRUE))
>      {
>          UINT_32 numOfPipes   = HwlGetPipes(pIn->pTileInfo);
> @@ -338,7 +338,7 @@ ADDR_E_RETURNCODE CiLib::HwlComputeHtileAddrFromCoord(
>  {
>      ADDR_E_RETURNCODE returnCode = ADDR_NOTSUPPORTED;
>
> -    if ((m_settings.isVolcanicIslands == TRUE) &&
> +    if ((SupportDccAndTcCompatibility() == TRUE) &&
>          (pIn->flags.tcCompatible == TRUE))
>      {
>          UINT_32 numOfPipes   = HwlGetPipes(pIn->pTileInfo);
> @@ -709,7 +709,7 @@ ADDR_E_RETURNCODE CiLib::HwlComputeSurfaceInfo(
>      if ((pIn->mipLevel > 0) &&
>          (pOut->tcCompatible == TRUE) &&
>          (pOut->tileMode != pIn->tileMode) &&
> -        (m_settings.isVolcanicIslands == TRUE))
> +        (SupportDccAndTcCompatibility() == TRUE))
>      {
>          pOut->tcCompatible = CheckTcCompatibility(pOut->pTileInfo, pIn->bpp, pOut->tileMode, pOut->tileType, pOut);
>      }
> @@ -1303,7 +1303,7 @@ VOID CiLib::HwlSetupTileInfo(
>      }
>
>      // tcCompatible flag is only meaningful for gfx8.
> -    if (m_settings.isVolcanicIslands == FALSE)
> +    if (SupportDccAndTcCompatibility() == FALSE)
>      {
>          flags.tcCompatible = FALSE;
>      }
> @@ -2098,7 +2098,7 @@ VOID CiLib::HwlPadDimensions(
>      UINT_32             heightAlign  ///< [in] height alignment
>      ) const
>  {
> -    if ((m_settings.isVolcanicIslands == TRUE) &&
> +    if ((SupportDccAndTcCompatibility() == TRUE) &&
>          (flags.dccCompatible == TRUE) &&
>          (numSamples > 1) &&
>          (mipLevel == 0) &&
> @@ -2208,7 +2208,7 @@ UINT_32 CiLib::HwlComputeMaxMetaBaseAlignments() const
>
>      for (UINT_32 i = 0; i < m_noOfMacroEntries; i++)
>      {
> -        if ((m_settings.isVolcanicIslands) && IsMacroTiled(m_tileTable[i].mode))
> +        if (SupportDccAndTcCompatibility() && IsMacroTiled(m_tileTable[i].mode))
>          {
>              maxBank = Max(maxBank, m_macroTileTable[i].banks);
>          }
> diff --git a/src/amd/addrlib/src/r800/ciaddrlib.h b/src/amd/addrlib/src/r800/ciaddrlib.h
> index 51853893266..b548254ca82 100644
> --- a/src/amd/addrlib/src/r800/ciaddrlib.h
> +++ b/src/amd/addrlib/src/r800/ciaddrlib.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> @@ -184,6 +184,11 @@ private:
>      BOOL_32 CheckTcCompatibility(const ADDR_TILEINFO* pTileInfo, UINT_32 bpp, AddrTileMode tileMode,
>                                   AddrTileType tileType, const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;
>
> +    BOOL_32 SupportDccAndTcCompatibility() const
> +    {
> +        return ((m_settings.isVolcanicIslands == TRUE) || (m_configFlags.forceDccAndTcCompat == TRUE));
> +    }
> +
>      static const UINT_32    MacroTileTableSize = 16;
>      static const UINT_32    PrtMacroModeOffset = MacroTileTableSize / 2;
>      static const INT_32     MinDepth2DThinIndex = 0;
> diff --git a/src/amd/addrlib/src/r800/egbaddrlib.cpp b/src/amd/addrlib/src/r800/egbaddrlib.cpp
> index 3c684235058..1c2596e4292 100644
> --- a/src/amd/addrlib/src/r800/egbaddrlib.cpp
> +++ b/src/amd/addrlib/src/r800/egbaddrlib.cpp
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> @@ -741,8 +741,6 @@ BOOL_32 EgBasedLib::ComputeSurfaceAlignmentsMicroTiled(
>
>      AdjustPitchAlignment(flags, pPitchAlign);
>
> -    // Workaround 2 for 1D tiling -  There is HW bug for Carrizo,
> -    // where it requires the following alignments for 1D tiling.
>      if (flags.czDispCompatible && (mipLevel == 0))
>      {
>          *pBaseAlign  = PowTwoAlign(*pBaseAlign, 4096);                         //Base address MOD 4096 = 0
> diff --git a/src/amd/addrlib/src/r800/egbaddrlib.h b/src/amd/addrlib/src/r800/egbaddrlib.h
> index f5bae10ed68..55e53540e95 100644
> --- a/src/amd/addrlib/src/r800/egbaddrlib.h
> +++ b/src/amd/addrlib/src/r800/egbaddrlib.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> diff --git a/src/amd/addrlib/src/r800/siaddrlib.cpp b/src/amd/addrlib/src/r800/siaddrlib.cpp
> index da37ad8f901..c91f72640a3 100644
> --- a/src/amd/addrlib/src/r800/siaddrlib.cpp
> +++ b/src/amd/addrlib/src/r800/siaddrlib.cpp
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> @@ -1603,8 +1603,9 @@ VOID SiLib::HwlComputeXmaskCoordFromAddr(
>              {
>                  macroOffset |= (pipebit1<<1);
>              }
> -            if((pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_8x16) ||
> -               (pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_16x16))
> +            if ((pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_8x16) ||
> +                (pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_16x16)
> +               )
>              {
>                  macroOffset |= (pipebit3<<1);
>              }
> diff --git a/src/amd/addrlib/src/r800/siaddrlib.h b/src/amd/addrlib/src/r800/siaddrlib.h
> index 705141161db..5a4f00a1680 100644
> --- a/src/amd/addrlib/src/r800/siaddrlib.h
> +++ b/src/amd/addrlib/src/r800/siaddrlib.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright © 2007-2018 Advanced Micro Devices, Inc.
> + * Copyright © 2007-2019 Advanced Micro Devices, Inc.
>   * All Rights Reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
> diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c
> index 34db177ffb6..27c977ac7d9 100644
> --- a/src/gallium/drivers/radeonsi/si_texture.c
> +++ b/src/gallium/drivers/radeonsi/si_texture.c
> @@ -173,6 +173,11 @@ static void si_copy_from_staging_texture(struct pipe_context *ctx, struct si_tra
>                 return;
>         }
>
> +       if (util_format_is_compressed(dst->format)) {
> +               sbox.width = util_format_get_nblocksx(dst->format, sbox.width);
> +               sbox.height = util_format_get_nblocksx(dst->format, sbox.height);
> +       }
> +
>         sctx->dma_copy(ctx, dst, transfer->level,
>                        transfer->box.x, transfer->box.y, transfer->box.z,
>                        src, 0, &sbox);
> @@ -1794,6 +1799,25 @@ static void si_init_temp_resource_from_box(struct pipe_resource *res,
>         res->usage = flags & SI_RESOURCE_FLAG_TRANSFER ? PIPE_USAGE_STAGING : PIPE_USAGE_DEFAULT;
>         res->flags = flags;
>
> +       if (flags & SI_RESOURCE_FLAG_TRANSFER &&
> +           util_format_is_compressed(orig->format)) {
> +               /* Transfer resources are allocated with linear tiling, which is
> +                * not supported for compressed formats.
> +                */
> +               unsigned blocksize =
> +                       util_format_get_blocksize(orig->format);
> +
> +               if (blocksize == 8) {
> +                       res->format = PIPE_FORMAT_R16G16B16A16_UINT;
> +               } else {
> +                       assert(blocksize == 16);
> +                       res->format = PIPE_FORMAT_R32G32B32A32_UINT;
> +               }
> +
> +               res->width0 = util_format_get_nblocksx(orig->format, box->width);
> +               res->height0 = util_format_get_nblocksy(orig->format, box->height);
> +       }
> +
>         /* We must set the correct texture target and dimensions for a 3D box. */
>         if (box->depth > 1 && util_max_layer(orig, level) > 0) {
>                 res->target = PIPE_TEXTURE_2D_ARRAY;
> --
> 2.17.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev

On Mon, Jun 17, 2019 at 9:19 PM Marek Olšák <maraeo@gmail.com> wrote:
>
> On Sat, Jun 15, 2019 at 5:51 PM Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> wrote:
>>
>> I'm not quite sure why the dimension changes are needed for radeonsi,
>> but for both polarisd and vega the compressed texture CTS tests pass
>> on RADV.
>
>
> Addrlib no longer supports linear compressed formats, so 64-bit or 128-bit integer formats have to be used for CPU mappings.

Thanks for the info.

We already did use integer formats for the upload/download. However,
apps can specify linear tiling, and I have a patch on the list to stop
claiming support for that. However, I'm still trying to figure out why
CTS did not fail without that. Anyway, not considered a blocker, as
CTS did not fail for me and no sane game tries to use linear
compressed textures.

- Bas

>
> Marek