From: Marek Olšák Date: Fri, 14 Jun 2019 21:55:38 +0000 (-0400) Subject: amd: update addrlib X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=eba932ea43a702e097218d2d4b1df56e0d1e3940;p=mesa.git amd: update addrlib Acked-by: Bas Nieuwenhuizen Tested-by: Bas Nieuwenhuizen --- 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 -#include -#include - #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 + #include + #include +#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(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(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(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(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;