From 18e760346aab10affd6e9ff129f800d90fa28456 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 27 Feb 2017 22:25:44 +0100 Subject: [PATCH] amd/addrlib: second update for Vega10 + bug fixes MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Highlights: - Display needs tiled pitch alignment to be at least 32 pixels - Implement Addr2ComputeDccAddrFromCoord(). - Macro-pixel packed formats don't support Z swizzle modes - Pad pitch and base alignment of PRT + TEX1D to 64KB. - Fix support for multimedia formats - Fix a case "PRT" entries are not selected on SI. - Fix wrong upper bits in equations for 3D resource. - We can't support 2d array slice rotation in gfx8 swizzle pattern - Set base alignment for PRT + non-xor swizzle mode resource to 64KB. - Bug workaround for Z16 4x/8x and Z32 2x/4x/8x MSAA depth texture - Add stereo support - Optimize swizzle mode selection - Report pitch and height in pixels for each mip - Adjust bpp/expandX for format ADDR_FMT_GB_GR/ADDR_FMT_BG_RG - Correct tcCompatible flag output for mipmap surface - Other fixes and cleanups Acked-by: Alex Deucher Acked-by: Nicolai Hähnle --- src/amd/addrlib/addrinterface.cpp | 90 + src/amd/addrlib/addrinterface.h | 215 ++- src/amd/addrlib/core/addrcommon.h | 52 +- src/amd/addrlib/core/addrelemlib.cpp | 60 +- src/amd/addrlib/core/addrelemlib.h | 3 +- src/amd/addrlib/core/addrlib.h | 6 +- src/amd/addrlib/core/addrlib1.cpp | 47 +- src/amd/addrlib/core/addrlib1.h | 2 +- src/amd/addrlib/core/addrlib2.cpp | 1942 ++++----------------- src/amd/addrlib/core/addrlib2.h | 329 ++-- src/amd/addrlib/gfx9/gfx9addrlib.cpp | 2416 +++++++++++++++++++++++--- src/amd/addrlib/gfx9/gfx9addrlib.h | 188 +- src/amd/addrlib/r800/ciaddrlib.cpp | 110 +- src/amd/addrlib/r800/ciaddrlib.h | 4 + src/amd/addrlib/r800/egbaddrlib.cpp | 2 +- src/amd/addrlib/r800/egbaddrlib.h | 2 +- src/amd/addrlib/r800/siaddrlib.cpp | 26 +- 17 files changed, 3330 insertions(+), 2164 deletions(-) diff --git a/src/amd/addrlib/addrinterface.cpp b/src/amd/addrlib/addrinterface.cpp index 12985fc37b6..ea2506e440f 100644 --- a/src/amd/addrlib/addrinterface.cpp +++ b/src/amd/addrlib/addrinterface.cpp @@ -1527,6 +1527,38 @@ ADDR_E_RETURNCODE ADDR_API Addr2ComputeDccInfo( return returnCode; } +/** +**************************************************************************************************** +* Addr2ComputeDccAddrFromCoord +* +* @brief +* Compute DCC key address according to coordinates +* +* @return +* ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE +**************************************************************************************************** +*/ +ADDR_E_RETURNCODE ADDR_API Addr2ComputeDccAddrFromCoord( + ADDR_HANDLE hLib, ///< address lib handle + const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn, ///< [in] Dcc info and coordinates + ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] Dcc address +{ + V2::Lib* pLib = V2::Lib::GetLib(hLib); + + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (pLib != NULL) + { + returnCode = pLib->ComputeDccAddrFromCoord(pIn, pOut); + } + else + { + returnCode = ADDR_ERROR; + } + + return returnCode; +} + /** **************************************************************************************************** * Addr2ComputePipeBankXor @@ -1556,6 +1588,64 @@ ADDR_E_RETURNCODE ADDR_API Addr2ComputePipeBankXor( return returnCode; } +/** +**************************************************************************************************** +* Addr2ComputeSlicePipeBankXor +* +* @brief +* Calculate slice pipe bank xor value based on base pipe bank xor and slice id. +**************************************************************************************************** +*/ +ADDR_E_RETURNCODE ADDR_API Addr2ComputeSlicePipeBankXor( + ADDR_HANDLE hLib, ///< handle of addrlib + const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn, ///< [in] input + ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut) ///< [out] output +{ + ADDR_E_RETURNCODE returnCode; + + V2::Lib* pLib = V2::Lib::GetLib(hLib); + + if (pLib != NULL) + { + returnCode = pLib->ComputeSlicePipeBankXor(pIn, pOut); + } + else + { + returnCode = ADDR_ERROR; + } + + return returnCode; +} + +/** +**************************************************************************************************** +* Addr2ComputeSubResourceOffsetForSwizzlePattern +* +* @brief +* Calculate sub resource offset for swizzle pattern. +**************************************************************************************************** +*/ +ADDR_E_RETURNCODE ADDR_API Addr2ComputeSubResourceOffsetForSwizzlePattern( + ADDR_HANDLE hLib, ///< handle of addrlib + const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn, ///< [in] input + ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut) ///< [out] output +{ + ADDR_E_RETURNCODE returnCode; + + V2::Lib* pLib = V2::Lib::GetLib(hLib); + + if (pLib != NULL) + { + returnCode = pLib->ComputeSubResourceOffsetForSwizzlePattern(pIn, pOut); + } + else + { + returnCode = ADDR_ERROR; + } + + return returnCode; +} + /** **************************************************************************************************** * Addr2GetPreferredSurfaceSetting diff --git a/src/amd/addrlib/addrinterface.h b/src/amd/addrlib/addrinterface.h index 15115d6e332..c36d4659501 100644 --- a/src/amd/addrlib/addrinterface.h +++ b/src/amd/addrlib/addrinterface.h @@ -2427,14 +2427,17 @@ typedef struct _ADDR2_MIP_INFO UINT_32 pitch; ///< Pitch in elements UINT_32 height; ///< Padded height in elements UINT_32 depth; ///< Padded depth - UINT_32 offset; ///< Offset in bytes from mip base - + UINT_32 pixelPitch; ///< Pitch in pixels + UINT_32 pixelHeight; ///< Padded height in pixels UINT_32 equationIndex; ///< Equation index in the equation table - UINT_32 mipOffsetXBytes; ///< Mip start position offset in byte in X direction - UINT_32 mipOffsetYPixel; ///< Mip start position offset in pixel in Y direction - UINT_32 mipOffsetZPixel; ///< Mip start position offset in pixel in Z direction - UINT_32 postSwizzleOffset; ///< Offset which is used to be added directly onto - /// the address calculated by equation + UINT_64 offset; ///< Offset in bytes from mip base, should only be used + ///< to setup vam surface descriptor, can't be used + ///< to setup swizzle pattern + UINT_64 macroBlockOffset; ///< macro block offset in bytes from mip base + UINT_32 mipTailOffset; ///< mip tail offset in bytes + UINT_32 mipTailCoordX; ///< mip tail coord x + UINT_32 mipTailCoordY; ///< mip tail coord y + UINT_32 mipTailCoordZ; ///< mip tail coord z } ADDR2_MIP_INFO; /** @@ -2459,7 +2462,7 @@ typedef struct _ADDR2_COMPUTE_SURFACE_INFO_OUTPUT UINT_32 mipChainPitch; ///< Pitch (of total mip chain) in elements UINT_32 mipChainHeight; ///< Padded height (of total mip chain) in elements UINT_32 mipChainSlice; ///< Padded depth (of total mip chain) - UINT_32 sliceSize; ///< Slice (total mip chain) size in bytes + UINT_64 sliceSize; ///< Slice (total mip chain) size in bytes UINT_64 surfSize; ///< Surface (total mip chain) size in bytes UINT_32 baseAlign; ///< Base address alignment UINT_32 bpp; ///< Bits per elements @@ -2485,7 +2488,9 @@ typedef struct _ADDR2_COMPUTE_SURFACE_INFO_OUTPUT /// contain numMipLevels entries UINT_32 equationIndex; ///< Equation index in the equation table of mip0 - BOOL_32 firstMipInTail; ///< If whole mipchain falls into mip tail block + BOOL_32 mipChainInTail; ///< If whole mipchain falls into mip tail block + UINT_32 firstMipIdInTail; ///< The id of first mip in tail, if there is no mip + /// in tail, it will be set to number of mip levels } ADDR2_COMPUTE_SURFACE_INFO_OUTPUT; /** @@ -2674,12 +2679,26 @@ typedef union _ADDR2_META_FLAGS typedef struct _ADDR2_META_MIP_INFO { BOOL_32 inMiptail; - UINT_32 startX; - UINT_32 startY; - UINT_32 startZ; - UINT_32 width; - UINT_32 height; - UINT_32 depth; + union + { + struct + { + UINT_32 startX; + UINT_32 startY; + UINT_32 startZ; + UINT_32 width; + UINT_32 height; + UINT_32 depth; + }; + + struct + { + UINT_32 offset; ///< metadata offset within one slice, + /// the thickness of a slice is meta block depth. + UINT_32 sliceSize; ///< metadata size within one slice, + /// the thickness of a slice is meta block depth. + }; + }; } ADDR2_META_MIP_INFO; /** @@ -2701,6 +2720,9 @@ typedef struct _ADDR2_COMPUTE_HTILE_INFO_INPUT UINT_32 unalignedHeight; ///< Depth surface original height (of mip0) UINT_32 numSlices; ///< Number of slices of depth surface (of mip0) UINT_32 numMipLevels; ///< Total mipmap levels of color surface + UINT_32 firstMipIdInTail; ///< id of the first mip in tail, + /// if no mip is in tail, it should be set to + /// number of mip levels } ADDR2_COMPUTE_HTILE_INFO_INPUT; /** @@ -3160,8 +3182,8 @@ typedef struct _ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT UINT_32 unalignedHeight; ///< Color surface original height UINT_32 numSamples; ///< Number of samples UINT_32 numFrags; ///< Number of fragments, leave it zero or the same as - /// number of samples for normal AA; Set it to the - /// number of fragments for EQAA + /// number of samples for normal AA; Set it to the + /// number of fragments for EQAA UINT_32 tileSwizzle; ///< Combined swizzle used to do bank/pipe rotation ADDR2_FMASK_FLAGS fMaskFlags; ///< FMASK flags @@ -3286,6 +3308,8 @@ typedef struct _ADDR2_COMPUTE_DCCINFO_INPUT UINT_32 numMipLevels; ///< Total mipmap levels of color surface UINT_32 dataSurfaceSize; ///< The padded size of all slices and mip levels ///< useful in meta linear case + 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_DCCINFO_INPUT; /** @@ -3336,6 +3360,66 @@ ADDR_E_RETURNCODE ADDR_API Addr2ComputeDccInfo( ADDR2_COMPUTE_DCCINFO_OUTPUT* pOut); +/** +**************************************************************************************************** +* ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT +* +* @brief +* Input structure for Addr2ComputeDccAddrFromCoord +* +**************************************************************************************************** +*/ +typedef struct _ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT +{ + UINT_32 size; ///< Size of this structure in bytes + + UINT_32 x; ///< X coordinate + UINT_32 y; ///< Y coordinate + UINT_32 slice; ///< Index of slices + UINT_32 sample; ///< Index of samples, means fragment index for EQAA + UINT_32 mipId; ///< mipmap level id + + ADDR2_META_FLAGS dccKeyFlags; ///< DCC flags + ADDR2_SURFACE_FLAGS colorFlags; ///< Color surface flags + AddrResourceType resourceType; ///< Color surface type + AddrSwizzleMode swizzleMode; ///< Color surface swizzle mode + UINT_32 bpp; ///< Color surface bits per pixel + UINT_32 unalignedWidth; ///< Color surface original width (of mip0) + UINT_32 unalignedHeight; ///< Color surface original height (of mip0) + UINT_32 numSlices; ///< Color surface original slices (of mip0) + UINT_32 numMipLevels; ///< Color surface mipmap levels + UINT_32 numFrags; ///< Color surface fragment number + + UINT_32 pipeXor; ///< pipe Xor setting +} ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT; + +/** +**************************************************************************************************** +* ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT +* +* @brief +* Output structure for Addr2ComputeDccAddrFromCoord +**************************************************************************************************** +*/ +typedef struct _ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT +{ + UINT_32 size; ///< Size of this structure in bytes + + UINT_64 addr; ///< DCC address in bytes +} ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT; + +/** +**************************************************************************************************** +* Addr2ComputeDccAddrFromCoord +* +* @brief +* Compute DCC address according to coordinates (of MSAA color buffer) +**************************************************************************************************** +*/ +ADDR_E_RETURNCODE ADDR_API Addr2ComputeDccAddrFromCoord( + ADDR_HANDLE hLib, + const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn, + ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut); //////////////////////////////////////////////////////////////////////////////////////////////////// // Misc functions for Gfx9 @@ -3356,6 +3440,11 @@ typedef struct _ADDR2_COMPUTE_PIPEBANKXOR_INPUT ADDR2_SURFACE_FLAGS flags; ///< Surface flag AddrSwizzleMode swizzleMode; ///< Surface swizzle mode AddrResourceType resourceType; ///< Surface resource type + AddrFormat format; ///< Surface format + UINT_32 numSamples; ///< Number of samples + UINT_32 numFrags; ///< Number of fragments, leave it zero or the same as + /// number of samples for normal AA; Set it to the + /// number of fragments for EQAA } ADDR2_COMPUTE_PIPEBANKXOR_INPUT; /** @@ -3385,7 +3474,97 @@ ADDR_E_RETURNCODE ADDR_API Addr2ComputePipeBankXor( const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn, ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut); +/** +**************************************************************************************************** +* ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT +* +* @brief +* Input structure of Addr2ComputeSlicePipeBankXor +**************************************************************************************************** +*/ +typedef struct _ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT +{ + UINT_32 size; ///< Size of this structure in bytes + AddrSwizzleMode swizzleMode; ///< Surface swizzle mode + AddrResourceType resourceType; ///< Surface resource type + UINT_32 basePipeBankXor; ///< Base pipe bank xor + UINT_32 slice; ///< Slice id + UINT_32 numSamples; ///< Number of samples +} ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT; + +/** +**************************************************************************************************** +* ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT +* +* @brief +* Output structure of Addr2ComputeSlicePipeBankXor +**************************************************************************************************** +*/ +typedef struct _ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT +{ + UINT_32 size; ///< Size of this structure in bytes + UINT_32 pipeBankXor; ///< Pipe bank xor +} ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT; + +/** +**************************************************************************************************** +* Addr2ComputeSlicePipeBankXor +* +* @brief +* Calculate slice pipe bank xor value based on base pipe bank xor and slice id. +**************************************************************************************************** +*/ +ADDR_E_RETURNCODE ADDR_API Addr2ComputeSlicePipeBankXor( + ADDR_HANDLE hLib, + const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn, + ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut); + +/** +**************************************************************************************************** +* ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT +* +* @brief +* Input structure of Addr2ComputeSubResourceOffsetForSwizzlePattern +**************************************************************************************************** +*/ +typedef struct _ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT +{ + UINT_32 size; ///< Size of this structure in bytes + AddrSwizzleMode swizzleMode; ///< Surface swizzle mode + AddrResourceType resourceType; ///< Surface resource type + UINT_32 pipeBankXor; ///< Per resource xor + UINT_32 slice; ///< Slice id + UINT_64 sliceSize; ///< Slice size of a mip chain + UINT_64 macroBlockOffset; ///< Macro block offset, returned in ADDR2_MIP_INFO + UINT_32 mipTailOffset; ///< Mip tail offset, returned in ADDR2_MIP_INFO +} ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT; +/** +**************************************************************************************************** +* ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT +* +* @brief +* Output structure of Addr2ComputeSubResourceOffsetForSwizzlePattern +**************************************************************************************************** +*/ +typedef struct _ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT +{ + UINT_32 size; ///< Size of this structure in bytes + UINT_64 offset; ///< offset +} ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT; + +/** +**************************************************************************************************** +* Addr2ComputeSubResourceOffsetForSwizzlePattern +* +* @brief +* Calculate sub resource offset to support swizzle pattern. +**************************************************************************************************** +*/ +ADDR_E_RETURNCODE ADDR_API Addr2ComputeSubResourceOffsetForSwizzlePattern( + ADDR_HANDLE hLib, + const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn, + ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut); /** **************************************************************************************************** @@ -3439,6 +3618,8 @@ typedef struct _ADDR2_GET_PREFERRED_SURF_SETTING_INPUT /// number of samples for normal AA; Set it to the /// number of fragments for EQAA UINT_32 maxAlign; ///< maximum base/size alignment requested by client + UINT_32 minSizeAlign; ///< memory allocated for surface in client driver will + /// be padded to multiple of this value (in bytes) } ADDR2_GET_PREFERRED_SURF_SETTING_INPUT; /** diff --git a/src/amd/addrlib/core/addrcommon.h b/src/amd/addrlib/core/addrcommon.h index 907b9f4eaeb..66424a84ba9 100644 --- a/src/amd/addrlib/core/addrcommon.h +++ b/src/amd/addrlib/core/addrcommon.h @@ -188,6 +188,15 @@ static const INT_32 TileIndexNoMacroIndex = -3; } // V1 +namespace V2 +{ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Common constants +//////////////////////////////////////////////////////////////////////////////////////////////////// +static const UINT_32 MaxSurfaceHeight = 16384; + +} // V2 + //////////////////////////////////////////////////////////////////////////////////////////////////// // Common macros //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -431,9 +440,7 @@ static inline INT_32 Max( static inline UINT_32 NextPow2( UINT_32 dim) ///< [in] dimension of miplevel { - UINT_32 newDim; - - newDim = 1; + UINT_32 newDim = 1; if (dim > 0x7fffffff) { @@ -732,7 +739,7 @@ static inline UINT_32 MortonGen3d( * ReverseBitVector * * @brief -* Return reversed lowest num bits of v +* Return reversed lowest num bits of v: v[0]v[1]...v[num-2]v[num-1] **************************************************************************************************** */ static inline UINT_32 ReverseBitVector( @@ -860,7 +867,7 @@ static inline VOID InitChannel( { pChanDst->valid = pChanSrc->valid; pChanDst->channel = pChanSrc->channel; - pChanDst->index = pChanSrc->channel; + pChanDst->index = pChanSrc->index; } /** @@ -872,9 +879,9 @@ static inline VOID InitChannel( **************************************************************************************************** */ static inline UINT_32 GetMaxValidChannelIndex( - ADDR_CHANNEL_SETTING *pChanSet, ///< [in] channel setting to be initialized - UINT_32 searchCount, ///< [in] number of channel setting to be searched - UINT_32 channel) ///< [in] channel to be searched + const ADDR_CHANNEL_SETTING *pChanSet, ///< [in] channel setting to be initialized + UINT_32 searchCount,///< [in] number of channel setting to be searched + UINT_32 channel) ///< [in] channel to be searched { UINT_32 index = 0; @@ -889,6 +896,35 @@ static inline UINT_32 GetMaxValidChannelIndex( return index; } +/** +**************************************************************************************************** +* GetCoordActiveMask +* +* @brief +* Get bit mask which indicates which positions in the equation match the target coord +**************************************************************************************************** +*/ +static inline UINT_32 GetCoordActiveMask( + const ADDR_CHANNEL_SETTING *pChanSet, ///< [in] channel setting to be initialized + UINT_32 searchCount,///< [in] number of channel setting to be searched + UINT_32 channel, ///< [in] channel to be searched + UINT_32 index) ///< [in] index to be searched +{ + UINT_32 mask = 0; + + for (UINT_32 i = 0; i < searchCount; i++) + { + if ((pChanSet[i].valid == TRUE) && + (pChanSet[i].channel == channel) && + (pChanSet[i].index == index)) + { + mask |= (1 << i); + } + } + + return mask; +} + } // Addr #endif // __ADDR_COMMON_H__ diff --git a/src/amd/addrlib/core/addrelemlib.cpp b/src/amd/addrlib/core/addrelemlib.cpp index e61648087a7..4bc46e0f585 100644 --- a/src/amd/addrlib/core/addrelemlib.cpp +++ b/src/amd/addrlib/core/addrelemlib.cpp @@ -1289,7 +1289,14 @@ VOID ElemLib::RestoreSurfaceInfo( break; case ADDR_PACKED_GBGR: case ADDR_PACKED_BGRG: - originalBits = bpp; // 32-bit packed ==> 2 32-bit result + if (m_pAddrLib->GetChipFamily() >= ADDR_CHIP_FAMILY_AI) + { + originalBits = bpp / expandX; + } + else + { + originalBits = bpp; // 32-bit packed ==> 2 32-bit result + } break; case ADDR_PACKED_BC1: // Fall through case ADDR_PACKED_BC4: @@ -1387,11 +1394,27 @@ UINT_32 ElemLib::GetBitsPerPixel( break; case ADDR_FMT_GB_GR: // treat as FMT_8_8 elemMode = ADDR_PACKED_GBGR; - bpp = 16; + if (m_pAddrLib->GetChipFamily() >= ADDR_CHIP_FAMILY_AI) + { + bpp = 32; + expandX = 2; + } + else + { + bpp = 16; + } break; case ADDR_FMT_BG_RG: // treat as FMT_8_8 elemMode = ADDR_PACKED_BGRG; - bpp = 16; + if (m_pAddrLib->GetChipFamily() >= ADDR_CHIP_FAMILY_AI) + { + bpp = 32; + expandX = 2; + } + else + { + bpp = 16; + } break; case ADDR_FMT_8_8_8_8: case ADDR_FMT_2_10_10_10: @@ -1804,4 +1827,35 @@ BOOL_32 ElemLib::IsExpand3x( return is3x; } +/** +**************************************************************************************************** +* ElemLib::IsMacroPixelPacked +* +* @brief +* TRUE if this is a macro-pixel-packed format. +* +* @note +* +* @return +* BOOL_32 +**************************************************************************************************** +*/ +BOOL_32 ElemLib::IsMacroPixelPacked( + AddrFormat format) ///< [in] Format +{ + BOOL_32 isMacroPixelPacked = FALSE; + + switch (format) + { + case ADDR_FMT_BG_RG: + case ADDR_FMT_GB_GR: + isMacroPixelPacked = TRUE; + break; + default: + break; + } + + return isMacroPixelPacked; +} + } diff --git a/src/amd/addrlib/core/addrelemlib.h b/src/amd/addrlib/core/addrelemlib.h index f1e323639c3..88755dbf368 100644 --- a/src/amd/addrlib/core/addrelemlib.h +++ b/src/amd/addrlib/core/addrelemlib.h @@ -216,7 +216,7 @@ public: AddrDepthFormat format, PixelFormatInfo* pInfo) const; UINT_32 GetBitsPerPixel( - AddrFormat format, ElemMode* pElemMode, + AddrFormat format, ElemMode* pElemMode = NULL, UINT_32* pExpandX = NULL, UINT_32* pExpandY = NULL, UINT_32* pBitsUnused = NULL); static VOID SetClearComps( @@ -245,6 +245,7 @@ public: static BOOL_32 IsCompressed(AddrFormat format); static BOOL_32 IsBlockCompressed(AddrFormat format); static BOOL_32 IsExpand3x(AddrFormat format); + static BOOL_32 IsMacroPixelPacked(AddrFormat format); protected: diff --git a/src/amd/addrlib/core/addrlib.h b/src/amd/addrlib/core/addrlib.h index 03d85003e85..736604e7cc5 100644 --- a/src/amd/addrlib/core/addrlib.h +++ b/src/amd/addrlib/core/addrlib.h @@ -261,9 +261,9 @@ private: ElemLib* m_pElemLib; ///< Element Lib pointer }; -Lib* SiHwlInit (const Client* pClient); -Lib* CiHwlInit (const Client* pClient); -Lib* Gfx9HwlInit(const Client* pClient); +Lib* SiHwlInit (const Client* pClient); +Lib* CiHwlInit (const Client* pClient); +Lib* Gfx9HwlInit (const Client* pClient); } // Addr diff --git a/src/amd/addrlib/core/addrlib1.cpp b/src/amd/addrlib/core/addrlib1.cpp index 2d640cf65f3..548b24b7b69 100644 --- a/src/amd/addrlib/core/addrlib1.cpp +++ b/src/amd/addrlib/core/addrlib1.cpp @@ -259,10 +259,9 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo( // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround // but we use this flag to skip RestoreSurfaceInfo below - if ((elemMode == ADDR_EXPANDED) && - (expandX > 1)) + if ((elemMode == ADDR_EXPANDED) && (expandX > 1)) { - ADDR_ASSERT(localIn.tileMode == ADDR_TM_LINEAR_ALIGNED || localIn.height == 1); + ADDR_ASSERT(IsLinear(localIn.tileMode)); } GetElemLib()->AdjustSurfaceInfo(elemMode, @@ -3621,7 +3620,7 @@ VOID Lib::OptimizeTileMode( { tileMode = ADDR_TM_LINEAR_ALIGNED; } - else if (IsMacroTiled(tileMode)) + else if (IsMacroTiled(tileMode) && (pInOut->flags.tcCompatible == FALSE)) { if (DegradeTo1D(width, height, macroWidthAlign, macroHeightAlign)) { @@ -3878,41 +3877,33 @@ UINT_32 Lib::HwlGetPipes( * @brief * Get quad buffer stereo information * @return -* TRUE if no error +* N/A **************************************************************************************************** */ -BOOL_32 Lib::ComputeQbStereoInfo( +VOID Lib::ComputeQbStereoInfo( ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in,out] updated pOut+pStereoInfo ) const { - BOOL_32 success = FALSE; - - if (pOut->pStereoInfo) - { - ADDR_ASSERT(pOut->bpp >= 8); - ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0); + ADDR_ASSERT(pOut->bpp >= 8); + ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0); - // Save original height - pOut->pStereoInfo->eyeHeight = pOut->height; + // Save original height + pOut->pStereoInfo->eyeHeight = pOut->height; - // Right offset - pOut->pStereoInfo->rightOffset = static_cast(pOut->surfSize); + // Right offset + pOut->pStereoInfo->rightOffset = static_cast(pOut->surfSize); - pOut->pStereoInfo->rightSwizzle = HwlComputeQbStereoRightSwizzle(pOut); - // Double height - pOut->height <<= 1; - pOut->pixelHeight <<= 1; + pOut->pStereoInfo->rightSwizzle = HwlComputeQbStereoRightSwizzle(pOut); + // Double height + pOut->height <<= 1; + pOut->pixelHeight <<= 1; - // Double size - pOut->surfSize <<= 1; + // Double size + pOut->surfSize <<= 1; - // Right start address meets the base align since it is guaranteed by AddrLib1 - - // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo. - success = TRUE; - } + // Right start address meets the base align since it is guaranteed by AddrLib1 - return success; + // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo. } diff --git a/src/amd/addrlib/core/addrlib1.h b/src/amd/addrlib/core/addrlib1.h index 0475e7bd40b..d6642aaaf74 100644 --- a/src/amd/addrlib/core/addrlib1.h +++ b/src/amd/addrlib/core/addrlib1.h @@ -496,7 +496,7 @@ protected: ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const; /// Quad buffer stereo support, has its implementation in ind. layer - virtual BOOL_32 ComputeQbStereoInfo( + VOID ComputeQbStereoInfo( ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const; /// Pure virutual function to compute stereo bank swizzle for right eye diff --git a/src/amd/addrlib/core/addrlib2.cpp b/src/amd/addrlib/core/addrlib2.cpp index 4497b6ff6e6..57505d35af5 100644 --- a/src/amd/addrlib/core/addrlib2.cpp +++ b/src/amd/addrlib/core/addrlib2.cpp @@ -25,10 +25,10 @@ */ /** -**************************************************************************************************** +************************************************************************************************************************ * @file addrlib2.cpp * @brief Contains the implementation for the AddrLib2 base class. -**************************************************************************************************** +************************************************************************************************************************ */ #include "addrinterface.h" @@ -44,77 +44,22 @@ namespace V2 // Static Const Member //////////////////////////////////////////////////////////////////////////////////////////////////// -const SwizzleModeFlags Lib::SwizzleModeTable[ADDR_SW_MAX_TYPE] = -{//Linear 256B 4KB 64KB Var Z Std Disp Rot XOR T - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},//ADDR_SW_LINEAR - {0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0},//ADDR_SW_256B_S - {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0},//ADDR_SW_256B_D - {0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0},//ADDR_SW_256B_R +const Dim2d Lib::Block256_2d[] = {{16, 16}, {16, 8}, {8, 8}, {8, 4}, {4, 4}}; - {0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0},//ADDR_SW_4KB_Z - {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0},//ADDR_SW_4KB_S - {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0},//ADDR_SW_4KB_D - {0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0},//ADDR_SW_4KB_R - - {0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0},//ADDR_SW_64KB_Z - {0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0},//ADDR_SW_64KB_S - {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0},//ADDR_SW_64KB_D - {0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0},//ADDR_SW_64KB_R - - {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},//ADDR_SW_VAR_Z - {0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0},//ADDR_SW_VAR_S - {0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0},//ADDR_SW_VAR_D - {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0},//ADDR_SW_VAR_R - - {0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1},//ADDR_SW_64KB_Z_T - {0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1},//ADDR_SW_64KB_S_T - {0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1},//ADDR_SW_64KB_D_T - {0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1},//ADDR_SW_64KB_R_T - - {0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0},//ADDR_SW_4KB_Z_x - {0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0},//ADDR_SW_4KB_S_x - {0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0},//ADDR_SW_4KB_D_x - {0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0},//ADDR_SW_4KB_R_x - - {0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0},//ADDR_SW_64KB_Z_X - {0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0},//ADDR_SW_64KB_S_X - {0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0},//ADDR_SW_64KB_D_X - {0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0},//ADDR_SW_64KB_R_X - - {0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0},//ADDR_SW_VAR_Z_X - {0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0},//ADDR_SW_VAR_S_X - {0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0},//ADDR_SW_VAR_D_X - {0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0},//ADDR_SW_VAR_R_X - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},//ADDR_SW_LINEAR_GENERAL -}; - -const Dim2d Lib::Block256b[] = {{16, 16}, {16, 8}, {8, 8}, {8, 4}, {4, 4}}; - -const Dim3d Lib::Block1kb[] = {{16, 8, 8}, {8, 8, 8}, {8, 8, 4}, {8, 4, 4}, {4, 4, 4}}; - -const Dim2d Lib::CompressBlock2d[] = {{16, 16}, {16, 8}, {8, 8}, {8, 4}, {4, 4}}; - -const Dim3d Lib::CompressBlock3dS[] = {{16, 4, 4}, {8, 4, 4}, {4, 4, 4}, {2, 4, 4}, {1, 4, 4}}; - -const Dim3d Lib::CompressBlock3dZ[] = {{8, 4, 8}, {4, 4, 8}, {4, 4, 4}, {4, 2, 4}, {2, 2, 4}}; - -const UINT_32 Lib::MaxMacroBits = 20; - -const UINT_32 Lib::MipTailOffset[] = {2048, 1024, 512, 256, 128, 64, 32, 16, - 8, 6, 5, 4, 3, 2, 1, 0}; +const Dim3d Lib::Block1K_3d[] = {{16, 8, 8}, {8, 8, 8}, {8, 8, 4}, {8, 4, 4}, {4, 4, 4}}; //////////////////////////////////////////////////////////////////////////////////////////////////// // Constructor/Destructor //////////////////////////////////////////////////////////////////////////////////////////////////// /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::Lib * * @brief * Constructor for the Addr::V2::Lib class * -**************************************************************************************************** +************************************************************************************************************************ */ Lib::Lib() : @@ -123,13 +68,13 @@ Lib::Lib() } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::Lib * * @brief * Constructor for the AddrLib2 class with hClient as parameter * -**************************************************************************************************** +************************************************************************************************************************ */ Lib::Lib(const Client* pClient) : @@ -138,20 +83,20 @@ Lib::Lib(const Client* pClient) } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::~Lib * * @brief * Destructor for the AddrLib2 class * -**************************************************************************************************** +************************************************************************************************************************ */ Lib::~Lib() { } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::GetLib * * @brief @@ -159,7 +104,7 @@ Lib::~Lib() * * @return * An Addr::V2::Lib class pointer -**************************************************************************************************** +************************************************************************************************************************ */ Lib* Lib::GetLib( ADDR_HANDLE hLib) ///< [in] handle of ADDR_HANDLE @@ -182,7 +127,7 @@ Lib* Lib::GetLib( /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeSurfaceInfo * * @brief @@ -190,7 +135,7 @@ Lib* Lib::GetLib( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo( const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure @@ -210,12 +155,12 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo( // Adjust coming parameters. ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn; - localIn.width = Max(pIn->width, 1u); - localIn.height = Max(pIn->height, 1u); + localIn.width = Max(pIn->width, 1u); + localIn.height = Max(pIn->height, 1u); localIn.numMipLevels = Max(pIn->numMipLevels, 1u); - localIn.numSlices = Max(pIn->numSlices, 1u); - localIn.numSamples = Max(pIn->numSamples, 1u); - localIn.numFrags = (localIn.numFrags == 0) ? localIn.numSamples : pIn->numFrags; + localIn.numSlices = Max(pIn->numSlices, 1u); + localIn.numSamples = Max(pIn->numSamples, 1u); + localIn.numFrags = (localIn.numFrags == 0) ? localIn.numSamples : pIn->numFrags; UINT_32 expandX = 1; UINT_32 expandY = 1; @@ -241,7 +186,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo( if ((elemMode == ADDR_EXPANDED) && (expandX > 1)) { - ADDR_ASSERT((localIn.swizzleMode == ADDR_SW_LINEAR) || (localIn.height == 1)); + ADDR_ASSERT(IsLinear(localIn.swizzleMode)); } UINT_32 basePitch = 0; @@ -315,20 +260,46 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo( &pixelBits, &pOut->pixelMipChainPitch, &pOut->pixelMipChainHeight); + + if ((localIn.numMipLevels > 1) && (pOut->pMipInfo != NULL)) + { + for (UINT_32 i = 0; i < localIn.numMipLevels; i++) + { + pOut->pMipInfo[i].pixelPitch = pOut->pMipInfo[i].pitch; + pOut->pMipInfo[i].pixelHeight = pOut->pMipInfo[i].height; + + GetElemLib()->RestoreSurfaceInfo(elemMode, + expandX, + expandY, + &pixelBits, + &pOut->pMipInfo[i].pixelPitch, + &pOut->pMipInfo[i].pixelHeight); + } + } } if (localIn.flags.needEquation && (Log2(localIn.numFrags) == 0)) { pOut->equationIndex = GetEquationIndex(&localIn, pOut); } + + if (localIn.flags.qbStereo) + { + if (pOut->pStereoInfo != NULL) + { + ComputeQbStereoInfo(pOut); + } + } } } + ADDR_ASSERT(pOut->surfSize != 0); + return returnCode; } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeSurfaceInfo * * @brief @@ -336,7 +307,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord( const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure @@ -355,12 +326,12 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord( } ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT localIn = *pIn; - localIn.unalignedWidth = Max(pIn->unalignedWidth, 1u); + localIn.unalignedWidth = Max(pIn->unalignedWidth, 1u); localIn.unalignedHeight = Max(pIn->unalignedHeight, 1u); - localIn.numMipLevels = Max(pIn->numMipLevels, 1u); - localIn.numSlices = Max(pIn->numSlices, 1u); - localIn.numSamples = Max(pIn->numSamples, 1u); - localIn.numFrags = Max(pIn->numFrags, 1u); + localIn.numMipLevels = Max(pIn->numMipLevels, 1u); + localIn.numSlices = Max(pIn->numSlices, 1u); + localIn.numSamples = Max(pIn->numSamples, 1u); + localIn.numFrags = Max(pIn->numFrags, 1u); if ((localIn.bpp < 8) || (localIn.bpp > 128) || @@ -390,7 +361,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeSurfaceCoordFromAddr * * @brief @@ -398,7 +369,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddr( const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure @@ -445,7 +416,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddr( //////////////////////////////////////////////////////////////////////////////////////////////////// /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeHtileInfo * * @brief @@ -453,7 +424,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddr( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeHtileInfo( const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn, ///< [in] input structure @@ -477,7 +448,7 @@ ADDR_E_RETURNCODE Lib::ComputeHtileInfo( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeHtileAddrFromCoord * * @brief @@ -485,7 +456,7 @@ ADDR_E_RETURNCODE Lib::ComputeHtileInfo( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeHtileAddrFromCoord( const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure @@ -509,7 +480,7 @@ ADDR_E_RETURNCODE Lib::ComputeHtileAddrFromCoord( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeHtileCoordFromAddr * * @brief @@ -517,7 +488,7 @@ ADDR_E_RETURNCODE Lib::ComputeHtileAddrFromCoord( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeHtileCoordFromAddr( const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure @@ -541,7 +512,7 @@ ADDR_E_RETURNCODE Lib::ComputeHtileCoordFromAddr( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeCmaskInfo * * @brief @@ -549,7 +520,7 @@ ADDR_E_RETURNCODE Lib::ComputeHtileCoordFromAddr( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeCmaskInfo( const ADDR2_COMPUTE_CMASK_INFO_INPUT* pIn, ///< [in] input structure @@ -577,7 +548,7 @@ ADDR_E_RETURNCODE Lib::ComputeCmaskInfo( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeCmaskAddrFromCoord * * @brief @@ -585,7 +556,7 @@ ADDR_E_RETURNCODE Lib::ComputeCmaskInfo( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeCmaskAddrFromCoord( const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure @@ -609,7 +580,7 @@ ADDR_E_RETURNCODE Lib::ComputeCmaskAddrFromCoord( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeCmaskCoordFromAddr * * @brief @@ -617,7 +588,7 @@ ADDR_E_RETURNCODE Lib::ComputeCmaskAddrFromCoord( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeCmaskCoordFromAddr( const ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure @@ -632,7 +603,7 @@ ADDR_E_RETURNCODE Lib::ComputeCmaskCoordFromAddr( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeFmaskInfo * * @brief @@ -640,7 +611,7 @@ ADDR_E_RETURNCODE Lib::ComputeCmaskCoordFromAddr( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeFmaskInfo( const ADDR2_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure @@ -709,7 +680,7 @@ ADDR_E_RETURNCODE Lib::ComputeFmaskInfo( pOut->baseAlign = localOut.baseAlign; pOut->numSlices = localOut.numSlices; pOut->fmaskBytes = static_cast(localOut.surfSize); - pOut->sliceSize = localOut.sliceSize; + pOut->sliceSize = static_cast(localOut.sliceSize); pOut->bpp = localIn.bpp; pOut->numSamples = 1; } @@ -719,7 +690,7 @@ ADDR_E_RETURNCODE Lib::ComputeFmaskInfo( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeFmaskAddrFromCoord * * @brief @@ -727,7 +698,7 @@ ADDR_E_RETURNCODE Lib::ComputeFmaskInfo( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeFmaskAddrFromCoord( const ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure @@ -742,7 +713,7 @@ ADDR_E_RETURNCODE Lib::ComputeFmaskAddrFromCoord( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeFmaskCoordFromAddr * * @brief @@ -750,7 +721,7 @@ ADDR_E_RETURNCODE Lib::ComputeFmaskAddrFromCoord( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeFmaskCoordFromAddr( const ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure @@ -765,203 +736,71 @@ ADDR_E_RETURNCODE Lib::ComputeFmaskCoordFromAddr( } /** -**************************************************************************************************** -* Lib::GetMetaMiptailInfo +************************************************************************************************************************ +* Lib::ComputeDccInfo * * @brief -* Get mip tail coordinate information. +* Interface function to compute DCC key info * * @return -* N/A -**************************************************************************************************** +* return code of HwlComputeDccInfo +************************************************************************************************************************ */ -VOID Lib::GetMetaMiptailInfo( - ADDR2_META_MIP_INFO* pInfo, ///< [out] output structure to store per mip coord - Dim3d mipCoord, ///< [in] mip tail base coord - UINT_32 numMipInTail, ///< [in] number of mips in tail - Dim3d* pMetaBlkDim ///< [in] meta block width/height/depth +ADDR_E_RETURNCODE Lib::ComputeDccInfo( + const ADDR2_COMPUTE_DCCINFO_INPUT* pIn, ///< [in] input structure + ADDR2_COMPUTE_DCCINFO_OUTPUT* pOut ///< [out] output structure ) const { - BOOL_32 isThick = (pMetaBlkDim->d > 1); - UINT_32 mipWidth = pMetaBlkDim->w; - UINT_32 mipHeight = pMetaBlkDim->h >> 1; - UINT_32 mipDepth = pMetaBlkDim->d; - UINT_32 minInc; + ADDR_E_RETURNCODE returnCode; - if (isThick) - { - minInc = (pMetaBlkDim->h >= 512) ? 128 : ((pMetaBlkDim->h == 256) ? 64 : 32); - } - else if (pMetaBlkDim->h >= 1024) - { - minInc = 256; - } - else if (pMetaBlkDim->h == 512) + if ((GetFillSizeFieldsFlags() == TRUE) && + ((pIn->size != sizeof(ADDR2_COMPUTE_DCCINFO_INPUT)) || + (pOut->size != sizeof(ADDR2_COMPUTE_DCCINFO_OUTPUT)))) { - minInc = 128; + returnCode = ADDR_INVALIDPARAMS; } else { - minInc = 64; + returnCode = HwlComputeDccInfo(pIn, pOut); } - UINT_32 blk32MipId = 0xFFFFFFFF; - - for (UINT_32 mip = 0; mip < numMipInTail; mip++) - { - pInfo[mip].inMiptail = TRUE; - pInfo[mip].startX = mipCoord.w; - pInfo[mip].startY = mipCoord.h; - pInfo[mip].startZ = mipCoord.d; - pInfo[mip].width = mipWidth; - pInfo[mip].height = mipHeight; - pInfo[mip].depth = mipDepth; - - if (mipWidth <= 32) - { - if (blk32MipId == 0xFFFFFFFF) - { - blk32MipId = mip; - } - - mipCoord.w = pInfo[blk32MipId].startX; - mipCoord.h = pInfo[blk32MipId].startY; - mipCoord.d = pInfo[blk32MipId].startZ; - - switch (mip - blk32MipId) - { - case 0: - mipCoord.w += 32; // 16x16 - break; - case 1: - mipCoord.h += 32; // 8x8 - break; - case 2: - mipCoord.h += 32; // 4x4 - mipCoord.w += 16; - break; - case 3: - mipCoord.h += 32; // 2x2 - mipCoord.w += 32; - break; - case 4: - mipCoord.h += 32; // 1x1 - mipCoord.w += 48; - break; - // The following are for BC/ASTC formats - case 5: - mipCoord.h += 48; // 1/2 x 1/2 - break; - case 6: - mipCoord.h += 48; // 1/4 x 1/4 - mipCoord.w += 16; - break; - case 7: - mipCoord.h += 48; // 1/8 x 1/8 - mipCoord.w += 32; - break; - case 8: - mipCoord.h += 48; // 1/16 x 1/16 - mipCoord.w += 48; - break; - default: - ADDR_ASSERT_ALWAYS(); - break; - } - - mipWidth = ((mip - blk32MipId) == 0) ? 16 : 8; - mipHeight = mipWidth; - - if (isThick) - { - mipDepth = mipWidth; - } - } - else - { - if (mipWidth <= minInc) - { - // if we're below the minimal increment... - if (isThick) - { - // For 3d, just go in z direction - mipCoord.d += mipDepth; - } - else - { - // For 2d, first go across, then down - if ((mipWidth * 2) == minInc) - { - // if we're 2 mips below, that's when we go back in x, and down in y - mipCoord.w -= minInc; - mipCoord.h += minInc; - } - else - { - // otherwise, just go across in x - mipCoord.w += minInc; - } - } - } - else - { - // On even mip, go down, otherwise, go across - if (mip & 1) - { - mipCoord.w += mipWidth; - } - else - { - mipCoord.h += mipHeight; - } - } - // Divide the width by 2 - mipWidth >>= 1; - // After the first mip in tail, the mip is always a square - mipHeight = mipWidth; - // ...or for 3d, a cube - if (isThick) - { - mipDepth = mipWidth; - } - } - } + return returnCode; } /** -**************************************************************************************************** -* Lib::ComputeDccInfo +************************************************************************************************************************ +* Lib::ComputeDccAddrFromCoord * * @brief -* Interface function to compute DCC key info +* Interface function stub of ComputeDccAddrFromCoord * * @return -* return code of HwlComputeDccInfo -**************************************************************************************************** +* ADDR_E_RETURNCODE +************************************************************************************************************************ */ -ADDR_E_RETURNCODE Lib::ComputeDccInfo( - const ADDR2_COMPUTE_DCCINFO_INPUT* pIn, ///< [in] input structure - ADDR2_COMPUTE_DCCINFO_OUTPUT* pOut ///< [out] output structure +ADDR_E_RETURNCODE Lib::ComputeDccAddrFromCoord( + const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure + ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure ) const { ADDR_E_RETURNCODE returnCode; if ((GetFillSizeFieldsFlags() == TRUE) && - ((pIn->size != sizeof(ADDR2_COMPUTE_DCCINFO_INPUT)) || - (pOut->size != sizeof(ADDR2_COMPUTE_DCCINFO_OUTPUT)))) + ((pIn->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT)) || + (pOut->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT)))) { returnCode = ADDR_INVALIDPARAMS; } else { - returnCode = HwlComputeDccInfo(pIn, pOut); + returnCode = HwlComputeDccAddrFromCoord(pIn, pOut); } return returnCode; } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputePipeBankXor * * @brief @@ -969,11 +808,11 @@ ADDR_E_RETURNCODE Lib::ComputeDccInfo( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputePipeBankXor( const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn, - ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut) + ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut) { ADDR_E_RETURNCODE returnCode; @@ -983,41 +822,88 @@ ADDR_E_RETURNCODE Lib::ComputePipeBankXor( { returnCode = ADDR_INVALIDPARAMS; } + else if (IsXor(pIn->swizzleMode) == FALSE) + { + returnCode = ADDR_NOTSUPPORTED; + } else { - UINT_32 macroBlockBits = GetBlockSizeLog2(pIn->swizzleMode); - UINT_32 pipeBits = GetPipeXorBits(macroBlockBits); - UINT_32 bankBits = GetBankXorBits(macroBlockBits); - UINT_32 pipeXor = 0; - UINT_32 bankXor = 0; + returnCode = HwlComputePipeBankXor(pIn, pOut); + } - if (bankBits > 0) - { - UINT_32 bankMask = (1 << bankBits) - 1; - UINT_32 bankIncrease = (1 << (bankBits - 1)) - 1; - bankIncrease = (bankIncrease == 0) ? 1 : bankIncrease; - bankXor = ((pIn->surfIndex & bankMask) * bankIncrease) & bankMask; - } + return returnCode; +} - if (pipeBits > 0) - { - UINT_32 pipeMask = (1 << pipeBits) - 1; - UINT_32 pipeIncrease = ((1 << (pipeBits - 1)) + 1) & pipeMask; - pipeIncrease = (pipeIncrease == 0) ? 1 : pipeIncrease; - pipeXor = ((pIn->surfIndex & pipeMask) * pipeIncrease) & pipeMask; - } +/** +************************************************************************************************************************ +* Lib::ComputeSlicePipeBankXor +* +* @brief +* Interface function stub of Addr2ComputeSlicePipeBankXor. +* +* @return +* ADDR_E_RETURNCODE +************************************************************************************************************************ +*/ +ADDR_E_RETURNCODE Lib::ComputeSlicePipeBankXor( + const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn, + ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut) +{ + ADDR_E_RETURNCODE returnCode; + + if ((GetFillSizeFieldsFlags() == TRUE) && + ((pIn->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT)) || + (pOut->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT)))) + { + returnCode = ADDR_INVALIDPARAMS; + } + else if ((IsThin(pIn->resourceType, pIn->swizzleMode) == FALSE) || + (IsNonPrtXor(pIn->swizzleMode) == FALSE) || + (pIn->numSamples > 1)) + { + returnCode = ADDR_NOTSUPPORTED; + } + else + { + returnCode = HwlComputeSlicePipeBankXor(pIn, pOut); + } - // Todo - pOut->pipeBankXor = pOut->pipeBankXor << (PipeInterleaveLog2 - 8) - pOut->pipeBankXor = (bankXor << pipeBits) | pipeXor; + return returnCode; +} - returnCode = ADDR_OK; +/** +************************************************************************************************************************ +* Lib::ComputeSubResourceOffsetForSwizzlePattern +* +* @brief +* Interface function stub of Addr2ComputeSubResourceOffsetForSwizzlePattern. +* +* @return +* ADDR_E_RETURNCODE +************************************************************************************************************************ +*/ +ADDR_E_RETURNCODE Lib::ComputeSubResourceOffsetForSwizzlePattern( + const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn, + ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut) +{ + ADDR_E_RETURNCODE returnCode; + + if ((GetFillSizeFieldsFlags() == TRUE) && + ((pIn->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT)) || + (pOut->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT)))) + { + returnCode = ADDR_INVALIDPARAMS; + } + else + { + returnCode = HwlComputeSubResourceOffsetForSwizzlePattern(pIn, pOut); } return returnCode; } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ExtractPipeBankXor * * @brief @@ -1025,7 +911,7 @@ ADDR_E_RETURNCODE Lib::ComputePipeBankXor( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ExtractPipeBankXor( UINT_32 pipeBankXor, @@ -1052,7 +938,7 @@ ADDR_E_RETURNCODE Lib::ExtractPipeBankXor( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeSurfaceInfoSanityCheck * * @brief @@ -1060,135 +946,29 @@ ADDR_E_RETURNCODE Lib::ExtractPipeBankXor( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoSanityCheck( const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in] input structure ) const { - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - BOOL_32 invalid = FALSE; - - if ((pIn->bpp > 128) || (pIn->width == 0) || (pIn->numFrags > 8) || (pIn->numSamples > 16)) - { - invalid = TRUE; - } - else if ((pIn->swizzleMode >= ADDR_SW_MAX_TYPE) || - (pIn->resourceType >= ADDR_RSRC_MAX_TYPE)) - { - invalid = TRUE; - } - - 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); - - 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 = pIn->flags.prt; - - if (invalid == FALSE) - { - if ((pIn->numFrags > 1) && - (GetBlockSize(swizzle) < (m_pipeInterleaveBytes * pIn->numFrags))) - { - // MSAA surface must have blk_bytes/pipe_interleave >= num_samples - invalid = TRUE; - } - } - - if (invalid == FALSE) - { - switch (rsrcType) - { - case ADDR_RSRC_TEX_1D: - invalid = msaa || zbuffer || display || (linear == FALSE); - break; - case ADDR_RSRC_TEX_2D: - invalid = msaa && mipmap; - break; - case ADDR_RSRC_TEX_3D: - invalid = msaa || zbuffer || display; - break; - default: - invalid = TRUE; - break; - } - } - - if (invalid == FALSE) - { - if (display) - { - invalid = (IsValidDisplaySwizzleMode(pIn) == FALSE); - } - } + ADDR_E_RETURNCODE returnCode; - if (invalid == FALSE) + if ((GetFillSizeFieldsFlags() == TRUE) && + (pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT))) { - if (linear) - { - invalid = prt || zbuffer || msaa || (pIn->bpp == 0) || ((pIn->bpp % 8) != 0); - } - else - { - if (blk256B || blkVar || isNonPrtXor) - { - invalid = prt; - if (blk256B) - { - invalid = invalid || zbuffer || tex3d || mipmap || msaa; - } - } - - if (invalid == FALSE) - { - if (IsZOrderSwizzle(swizzle)) - { - invalid = color && msaa; - } - else if (IsStandardSwizzle(rsrcType, swizzle)) - { - invalid = zbuffer; - } - else if (IsDisplaySwizzle(rsrcType, swizzle)) - { - invalid = zbuffer; - } - else if (IsRotateSwizzle(swizzle)) - { - invalid = zbuffer || (pIn->bpp > 64); - } - else - { - ADDR_ASSERT(!"invalid swizzle mode"); - invalid = TRUE; - } - } - } + returnCode = ADDR_INVALIDPARAMS; } - - if (invalid) + else { - returnCode = ADDR_INVALIDPARAMS; + returnCode = HwlComputeSurfaceInfoSanityCheck(pIn); } return returnCode; } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ApplyCustomizedPitchHeight * * @brief @@ -1196,12 +976,12 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoSanityCheck( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ApplyCustomizedPitchHeight( const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure UINT_32 elementBytes, ///< [in] element bytes per element - UINT_32 widthAlignInElement, ///< [in] pitch alignment in element + UINT_32 pitchAlignInElement, ///< [in] pitch alignment in element UINT_32* pPitch, ///< [in/out] pitch UINT_32* pHeight ///< [in/out] height ) const @@ -1212,7 +992,7 @@ ADDR_E_RETURNCODE Lib::ApplyCustomizedPitchHeight( { if (pIn->pitchInElement > 0) { - if ((pIn->pitchInElement % widthAlignInElement) != 0) + if ((pIn->pitchInElement % pitchAlignInElement) != 0) { returnCode = ADDR_INVALIDPARAMS; } @@ -1252,7 +1032,7 @@ ADDR_E_RETURNCODE Lib::ApplyCustomizedPitchHeight( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeSurfaceInfoLinear * * @brief @@ -1260,7 +1040,7 @@ ADDR_E_RETURNCODE Lib::ApplyCustomizedPitchHeight( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoLinear( const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure @@ -1272,6 +1052,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoLinear( UINT_32 pitch = 0; UINT_32 actualHeight = 0; UINT_32 elementBytes = pIn->bpp >> 3; + const UINT_32 alignment = pIn->flags.prt ? PrtAlignment : 256; if (IsTex1d(pIn->resourceType)) { @@ -1281,11 +1062,15 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoLinear( } else { - const UINT_32 widthAlignInElement = 256 / elementBytes; - pitch = PowTwoAlign(pIn->width, widthAlignInElement); + const UINT_32 pitchAlignInElement = alignment / elementBytes; + pitch = PowTwoAlign(pIn->width, pitchAlignInElement); actualHeight = pIn->numMipLevels; - returnCode = ApplyCustomizedPitchHeight(pIn, elementBytes, widthAlignInElement, - &pitch, &actualHeight); + + if (pIn->flags.prt == FALSE) + { + returnCode = ApplyCustomizedPitchHeight(pIn, elementBytes, pitchAlignInElement, + &pitch, &actualHeight); + } if (returnCode == ADDR_OK) { @@ -1321,22 +1106,22 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoLinear( pOut->mipChainHeight = actualHeight; pOut->mipChainSlice = pOut->numSlices; pOut->epitchIsHeight = (pIn->numMipLevels > 1) ? TRUE : FALSE; - pOut->sliceSize = pOut->pitch * actualHeight * elementBytes; + pOut->sliceSize = static_cast(pOut->pitch) * actualHeight * elementBytes; pOut->surfSize = pOut->sliceSize * pOut->numSlices; - pOut->baseAlign = (pIn->swizzleMode == ADDR_SW_LINEAR_GENERAL) ? (pIn->bpp / 8) : 256; + pOut->baseAlign = (pIn->swizzleMode == ADDR_SW_LINEAR_GENERAL) ? (pIn->bpp / 8) : alignment; pOut->blockWidth = (pIn->swizzleMode == ADDR_SW_LINEAR_GENERAL) ? 1 : (256 * 8 / pIn->bpp); pOut->blockHeight = 1; pOut->blockSlices = 1; } // Post calculation validate - ADDR_ASSERT((pOut->sliceSize > 0)); + ADDR_ASSERT(pOut->sliceSize > 0); return returnCode; } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeSurfaceInfoTiled * * @brief @@ -1344,195 +1129,64 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoLinear( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoTiled( const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure ) const { - ADDR_E_RETURNCODE returnCode = ComputeBlockDimensionForSurf(&pOut->blockWidth, - &pOut->blockHeight, - &pOut->blockSlices, - pIn->bpp, - pIn->numFrags, - pIn->resourceType, - pIn->swizzleMode); + return HwlComputeSurfaceInfoTiled(pIn, pOut); +} - if (returnCode == ADDR_OK) - { - const UINT_32 widthAlignInElement = pOut->blockWidth; +/** +************************************************************************************************************************ +* Lib::ComputeSurfaceAddrFromCoordLinear +* +* @brief +* Internal function to calculate address from coord for linear swizzle surface +* +* @return +* ADDR_E_RETURNCODE +************************************************************************************************************************ +*/ +ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordLinear( + const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure + ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1) && (pIn->pipeBankXor == 0); - pOut->pitch = PowTwoAlign(pIn->width, widthAlignInElement); + if (valid) + { + if (IsTex1d(pIn->resourceType)) + { + valid = (pIn->y == 0); + } + } - if ((pIn->numMipLevels <= 1) && (pIn->pitchInElement > 0)) + if (valid) + { + ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0}; + ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0}; + localIn.bpp = pIn->bpp; + localIn.flags = pIn->flags; + localIn.width = Max(pIn->unalignedWidth, 1u); + localIn.height = Max(pIn->unalignedHeight, 1u); + localIn.numSlices = Max(pIn->numSlices, 1u); + localIn.numMipLevels = Max(pIn->numMipLevels, 1u); + localIn.resourceType = pIn->resourceType; + if (localIn.numMipLevels <= 1) { - if ((pIn->pitchInElement % widthAlignInElement) != 0) - { - returnCode = ADDR_INVALIDPARAMS; - } - else if (pIn->pitchInElement < pOut->pitch) - { - returnCode = ADDR_INVALIDPARAMS; - } - else - { - pOut->pitch = pIn->pitchInElement; - } + localIn.pitchInElement = pIn->pitchInElement; } - - if (returnCode == ADDR_OK) - { - pOut->height = PowTwoAlign(pIn->height, pOut->blockHeight); - pOut->numSlices = PowTwoAlign(pIn->numSlices, pOut->blockSlices); - - pOut->epitchIsHeight = FALSE; - pOut->firstMipInTail = FALSE; - - pOut->mipChainPitch = pOut->pitch; - pOut->mipChainHeight = pOut->height; - pOut->mipChainSlice = pOut->numSlices; - - if (pIn->numMipLevels > 1) - { - UINT_32 numMipLevel; - ADDR2_MIP_INFO *pMipInfo; - ADDR2_MIP_INFO mipInfo[4]; - - if (pOut->pMipInfo != NULL) - { - pMipInfo = pOut->pMipInfo; - numMipLevel = pIn->numMipLevels; - } - else - { - pMipInfo = mipInfo; - numMipLevel = Min(pIn->numMipLevels, 4u); - } - - UINT_32 endingMip = GetMipChainInfo(pIn->resourceType, - pIn->swizzleMode, - pIn->bpp, - pIn->width, - pIn->height, - pIn->numSlices, - pOut->blockWidth, - pOut->blockHeight, - pOut->blockSlices, - numMipLevel, - pMipInfo); - - if (endingMip == 0) - { - pOut->epitchIsHeight = TRUE; - pOut->pitch = pMipInfo[0].pitch; - pOut->height = pMipInfo[0].height; - pOut->numSlices = pMipInfo[0].depth; - pOut->firstMipInTail = TRUE; - } - else - { - UINT_32 mip0WidthInBlk = pOut->pitch / pOut->blockWidth; - UINT_32 mip0HeightInBlk = pOut->height / pOut->blockHeight; - - AddrMajorMode majorMode = GetMajorMode(pIn->resourceType, - pIn->swizzleMode, - mip0WidthInBlk, - mip0HeightInBlk, - pOut->numSlices / pOut->blockSlices); - if (majorMode == ADDR_MAJOR_Y) - { - UINT_32 mip1WidthInBlk = RoundHalf(mip0WidthInBlk); - - if ((mip1WidthInBlk == 1) && (endingMip > 2)) - { - mip1WidthInBlk++; - } - - pOut->mipChainPitch += (mip1WidthInBlk * pOut->blockWidth); - - pOut->epitchIsHeight = FALSE; - } - else - { - UINT_32 mip1HeightInBlk = RoundHalf(mip0HeightInBlk); - - if ((mip1HeightInBlk == 1) && (endingMip > 2)) - { - mip1HeightInBlk++; - } - - pOut->mipChainHeight += (mip1HeightInBlk * pOut->blockHeight); - - pOut->epitchIsHeight = TRUE; - } - } - } - else if (pOut->pMipInfo != NULL) - { - pOut->pMipInfo[0].pitch = pOut->pitch; - pOut->pMipInfo[0].height = pOut->height; - pOut->pMipInfo[0].depth = IsTex3d(pIn->resourceType)? pOut->numSlices : 1; - pOut->pMipInfo[0].offset = 0; - } - - pOut->sliceSize = pOut->mipChainPitch *pOut->mipChainHeight * - (pIn->bpp >> 3) * pIn->numFrags; - pOut->surfSize = pOut->sliceSize * pOut->mipChainSlice; - pOut->baseAlign = ComputeSurfaceBaseAlign(pIn->swizzleMode); - } - } - - return returnCode; -} - -/** -**************************************************************************************************** -* Lib::ComputeSurfaceAddrFromCoordLinear -* -* @brief -* Internal function to calculate address from coord for linear swizzle surface -* -* @return -* ADDR_E_RETURNCODE -**************************************************************************************************** -*/ -ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordLinear( - const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure - ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1) && (pIn->pipeBankXor == 0); - - if (valid) - { - if (IsTex1d(pIn->resourceType)) - { - valid = (pIn->y == 0); - } - } - - if (valid) - { - ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0}; - ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0}; - localIn.bpp = pIn->bpp; - localIn.width = Max(pIn->unalignedWidth, 1u); - localIn.height = Max(pIn->unalignedHeight, 1u); - localIn.numSlices = Max(pIn->numSlices, 1u); - localIn.numMipLevels = Max(pIn->numMipLevels, 1u); - localIn.resourceType = pIn->resourceType; - if (localIn.numMipLevels <= 1) - { - localIn.pitchInElement = pIn->pitchInElement; - } - returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut); + returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut); if (returnCode == ADDR_OK) { UINT_32 elementBytes = pIn->bpp >> 3; - UINT_64 sliceOffsetInSurf = static_cast(pIn->slice) * localOut.sliceSize; + UINT_64 sliceOffsetInSurf = localOut.sliceSize * pIn->slice; UINT_64 mipOffsetInSlice = 0; UINT_64 offsetInMip = 0; @@ -1566,7 +1220,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordLinear( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeSurfaceAddrFromCoordTiled * * @brief @@ -1574,269 +1228,18 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordLinear( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordTiled( const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure ) const { - ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0}; - localIn.swizzleMode = pIn->swizzleMode; - localIn.flags = pIn->flags; - localIn.resourceType = pIn->resourceType; - localIn.bpp = pIn->bpp; - localIn.width = Max(pIn->unalignedWidth, 1u); - localIn.height = Max(pIn->unalignedHeight, 1u); - localIn.numSlices = Max(pIn->numSlices, 1u); - localIn.numMipLevels = Max(pIn->numMipLevels, 1u); - if (localIn.numMipLevels <= 1) - { - localIn.pitchInElement = pIn->pitchInElement; - } - - ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0}; - ADDR_E_RETURNCODE returnCode = ComputeSurfaceInfoTiled(&localIn, &localOut); - - BOOL_32 valid = (returnCode == ADDR_OK) && - (IsThin(pIn->resourceType, pIn->swizzleMode) || - IsThick(pIn->resourceType, pIn->swizzleMode)) && - ((pIn->pipeBankXor == 0) || (IsXor(pIn->swizzleMode))); - - if (valid) - { - Dim3d mipStartPos = {0}; - UINT_32 mipTailOffset = 0; - - if (pIn->numMipLevels > 1) - { - // Mip-map chain cannot be MSAA surface - ADDR_ASSERT((pIn->numSamples <= 1) && (pIn->numFrags<= 1)); - - mipStartPos = GetMipStartPos(pIn->resourceType, - pIn->swizzleMode, - localOut.pitch, - localOut.height, - localOut.numSlices, - localOut.blockWidth, - localOut.blockHeight, - localOut.blockSlices, - pIn->mipId, - &mipTailOffset); - } - - UINT_32 interleaveOffset = 0; - UINT_32 pipeBits = 0; - UINT_32 pipeXor = 0; - UINT_32 bankBits = 0; - UINT_32 bankXor = 0; - - if (IsThin(pIn->resourceType, pIn->swizzleMode)) - { - UINT_32 blockOffset = 0; - UINT_32 log2blkSize = GetBlockSizeLog2(pIn->swizzleMode); - UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3); - - if (IsZOrderSwizzle(pIn->swizzleMode)) - { - // Morton generation - if ((log2ElementBytes == 0) || (log2ElementBytes == 2)) - { - UINT_32 totalLowBits = 6 - log2ElementBytes; - UINT_32 mortBits = totalLowBits / 2; - UINT_32 lowBitsValue = MortonGen2d(pIn->y, pIn->x, mortBits); - // Are 9 bits enough? - UINT_32 highBitsValue = - MortonGen2d(pIn->x >> mortBits, pIn->y >> mortBits, 9) << totalLowBits; - blockOffset = lowBitsValue | highBitsValue; - ADDR_ASSERT(blockOffset == lowBitsValue + highBitsValue); - } - else - { - blockOffset = MortonGen2d(pIn->y, pIn->x, 13); - } - - // Fill LSBs with sample bits - if (pIn->numSamples > 1) - { - blockOffset *= pIn->numSamples; - blockOffset |= pIn->sample; - } - - // Shift according to BytesPP - blockOffset <<= log2ElementBytes; - } - else - { - // Micro block offset - UINT_32 microBlockOffset = ComputeSurface2DMicroBlockOffset(pIn); - blockOffset = microBlockOffset; - - // Micro block dimension - ADDR_ASSERT(log2ElementBytes < sizeof(Block256b) / sizeof(Block256b[0])); - Dim2d microBlockDim = Block256b[log2ElementBytes]; - // Morton generation, does 12 bit enough? - blockOffset |= - MortonGen2d((pIn->x / microBlockDim.w), (pIn->y / microBlockDim.h), 12) << 8; - - // Sample bits start location - UINT_32 sampleStart = log2blkSize - Log2(pIn->numSamples); - // Join sample bits information to the highest Macro block bits - if (IsNonPrtXor(pIn->swizzleMode)) - { - // Non-prt-Xor : xor highest Macro block bits with sample bits - blockOffset = blockOffset ^ (pIn->sample << sampleStart); - } - else - { - // Non-Xor or prt-Xor: replace highest Macro block bits with sample bits - // after this op, the blockOffset only contains log2 Macro block size bits - blockOffset %= (1 << sampleStart); - blockOffset |= (pIn->sample << sampleStart); - ADDR_ASSERT((blockOffset >> log2blkSize) == 0); - } - } - - if (IsXor(pIn->swizzleMode)) - { - // Mask off bits above Macro block bits to keep page synonyms working for prt - if (IsPrt(pIn->swizzleMode)) - { - blockOffset &= ((1 << log2blkSize) - 1); - } - - // Preserve offset inside pipe interleave - interleaveOffset = blockOffset & ((1 << m_pipeInterleaveLog2) - 1); - blockOffset >>= m_pipeInterleaveLog2; - - // Pipe/Se xor bits - pipeBits = GetPipeXorBits(log2blkSize); - // Pipe xor - pipeXor = FoldXor2d(blockOffset, pipeBits); - blockOffset >>= pipeBits; - - // Bank xor bits - bankBits = GetBankXorBits(log2blkSize); - // Bank Xor - bankXor = FoldXor2d(blockOffset, bankBits); - blockOffset >>= bankBits; - - // Put all the part back together - blockOffset <<= bankBits; - blockOffset |= bankXor; - blockOffset <<= pipeBits; - blockOffset |= pipeXor; - blockOffset <<= m_pipeInterleaveLog2; - blockOffset |= interleaveOffset; - } - - ADDR_ASSERT((blockOffset | mipTailOffset) == (blockOffset + mipTailOffset)); - blockOffset |= mipTailOffset; - - if (IsNonPrtXor(pIn->swizzleMode) && (pIn->numSamples <= 1)) - { - // Apply slice xor if not MSAA/PRT - blockOffset ^= (ReverseBitVector(pIn->slice, pipeBits) << m_pipeInterleaveLog2); - blockOffset ^= (ReverseBitVector(pIn->slice >> pipeBits, bankBits) << - (m_pipeInterleaveLog2 + pipeBits)); - } - - returnCode = ApplyCustomerPipeBankXor(pIn->swizzleMode, pIn->pipeBankXor, - bankBits, pipeBits, &blockOffset); - - blockOffset %= (1 << log2blkSize); - - UINT_32 pitchInMacroBlock = localOut.mipChainPitch / localOut.blockWidth; - UINT_32 paddedHeightInMacroBlock = localOut.mipChainHeight / localOut.blockHeight; - UINT_32 sliceSizeInMacroBlock = pitchInMacroBlock * paddedHeightInMacroBlock; - UINT_32 macroBlockIndex = - (pIn->slice + mipStartPos.d) * sliceSizeInMacroBlock + - ((pIn->y / localOut.blockHeight) + mipStartPos.h) * pitchInMacroBlock + - ((pIn->x / localOut.blockWidth) + mipStartPos.w); - - UINT_64 macroBlockOffset = (static_cast(macroBlockIndex) << - GetBlockSizeLog2(pIn->swizzleMode)); - - pOut->addr = blockOffset | macroBlockOffset; - } - else - { - UINT_32 log2blkSize = GetBlockSizeLog2(pIn->swizzleMode); - UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3); - - Dim3d microBlockDim = Block1kb[log2ElementBytes]; - - UINT_32 blockOffset = MortonGen3d((pIn->x / microBlockDim.w), - (pIn->y / microBlockDim.h), - (pIn->slice / microBlockDim.d), - 8); - - blockOffset <<= 10; - blockOffset |= ComputeSurface3DMicroBlockOffset(pIn); - - if (IsXor(pIn->swizzleMode)) - { - // Mask off bits above Macro block bits to keep page synonyms working for prt - if (IsPrt(pIn->swizzleMode)) - { - blockOffset &= ((1 << log2blkSize) - 1); - } - - // Preserve offset inside pipe interleave - interleaveOffset = blockOffset & ((1 << m_pipeInterleaveLog2) - 1); - blockOffset >>= m_pipeInterleaveLog2; - - // Pipe/Se xor bits - pipeBits = GetPipeXorBits(log2blkSize); - // Pipe xor - pipeXor = FoldXor3d(blockOffset, pipeBits); - blockOffset >>= pipeBits; - - // Bank xor bits - bankBits = GetBankXorBits(log2blkSize); - // Bank Xor - bankXor = FoldXor3d(blockOffset, bankBits); - blockOffset >>= bankBits; - - // Put all the part back together - blockOffset <<= bankBits; - blockOffset |= bankXor; - blockOffset <<= pipeBits; - blockOffset |= pipeXor; - blockOffset <<= m_pipeInterleaveLog2; - blockOffset |= interleaveOffset; - } - - ADDR_ASSERT((blockOffset | mipTailOffset) == (blockOffset + mipTailOffset)); - blockOffset |= mipTailOffset; - - returnCode = ApplyCustomerPipeBankXor(pIn->swizzleMode, pIn->pipeBankXor, - bankBits, pipeBits, &blockOffset); - - blockOffset %= (1 << log2blkSize); - - UINT_32 xb = (pIn->x + mipStartPos.w) / localOut.blockWidth; - UINT_32 yb = (pIn->y + mipStartPos.h) / localOut.blockHeight; - UINT_32 zb = (pIn->slice + mipStartPos.d) / localOut.blockSlices; - - UINT_32 pitchInBlock = localOut.mipChainPitch / localOut.blockWidth; - UINT_32 sliceSizeInBlock = - (localOut.mipChainHeight / localOut.blockHeight) * pitchInBlock; - UINT_32 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb; - - pOut->addr = blockOffset | (blockIndex << log2blkSize); - } - } - else - { - returnCode = ADDR_INVALIDPARAMS; - } - - return returnCode; + return HwlComputeSurfaceAddrFromCoordTiled(pIn, pOut); } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeSurfaceCoordFromAddrLinear * * @brief @@ -1844,7 +1247,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordTiled( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrLinear( const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure @@ -1865,12 +1268,13 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrLinear( if (valid) { - ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0}; + ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0}; ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0}; - localIn.bpp = pIn->bpp; - localIn.width = Max(pIn->unalignedWidth, 1u); - localIn.height = Max(pIn->unalignedHeight, 1u); - localIn.numSlices = Max(pIn->numSlices, 1u); + localIn.bpp = pIn->bpp; + localIn.flags = pIn->flags; + localIn.width = Max(pIn->unalignedWidth, 1u); + localIn.height = Max(pIn->unalignedHeight, 1u); + localIn.numSlices = Max(pIn->numSlices, 1u); localIn.numMipLevels = Max(pIn->numMipLevels, 1u); localIn.resourceType = pIn->resourceType; if (localIn.numMipLevels <= 1) @@ -1972,7 +1376,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrLinear( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeSurfaceCoordFromAddrTiled * * @brief @@ -1980,7 +1384,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrLinear( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrTiled( const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure @@ -1995,7 +1399,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrTiled( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeSurfaceInfoLinear * * @brief @@ -2003,7 +1407,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrTiled( * * @return * N/A -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceLinearPadding( const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input srtucture @@ -2015,23 +1419,23 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceLinearPadding( ADDR_E_RETURNCODE returnCode = ADDR_OK; UINT_32 elementBytes = pIn->bpp >> 3; - UINT_32 widthAlignInElement = 0; + UINT_32 pitchAlignInElement = 0; if (pIn->swizzleMode == ADDR_SW_LINEAR_GENERAL) { ADDR_ASSERT(pIn->numMipLevels <= 1); ADDR_ASSERT(pIn->numSlices <= 1); - widthAlignInElement = 1; + pitchAlignInElement = 1; } else { - widthAlignInElement = (256 / elementBytes); + pitchAlignInElement = (256 / elementBytes); } - UINT_32 mipChainWidth = PowTwoAlign(pIn->width, widthAlignInElement); + UINT_32 mipChainWidth = PowTwoAlign(pIn->width, pitchAlignInElement); UINT_32 slice0PaddedHeight = pIn->height; - returnCode = ApplyCustomizedPitchHeight(pIn, elementBytes, widthAlignInElement, + returnCode = ApplyCustomizedPitchHeight(pIn, elementBytes, pitchAlignInElement, &mipChainWidth, &slice0PaddedHeight); if (returnCode == ADDR_OK) @@ -2062,7 +1466,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceLinearPadding( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeBlockDimensionForSurf * * @brief @@ -2070,29 +1474,7 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceLinearPadding( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** -*/ -ADDR_E_RETURNCODE Lib::ComputeBlockDimensionForSurf( - Dim3d* pDim, - UINT_32 bpp, - UINT_32 numSamples, - AddrResourceType resourceType, - AddrSwizzleMode swizzleMode) const -{ - return ComputeBlockDimensionForSurf(&pDim->w, &pDim->h, &pDim->d, bpp, - numSamples, resourceType, swizzleMode); -} - -/** -**************************************************************************************************** -* Lib::ComputeBlockDimensionForSurf -* -* @brief -* Internal function to get block width/height/depth in element from surface input params. -* -* @return -* ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeBlockDimensionForSurf( UINT_32* pWidth, @@ -2112,20 +1494,20 @@ ADDR_E_RETURNCODE Lib::ComputeBlockDimensionForSurf( if ((returnCode == ADDR_OK) && (numSamples > 1) && IsThin(resourceType, swizzleMode)) { - UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode); - UINT_32 sample = numSamples; - UINT_32 log2sample = Log2(sample); + const UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode); + const UINT_32 log2sample = Log2(numSamples); + const UINT_32 q = log2sample >> 1; + const UINT_32 r = log2sample & 1; - *pWidth >>= (log2sample / 2); - *pHeight >>= (log2sample / 2); - - if ((log2blkSize % 2) == 0) + if (log2blkSize & 1) { - *pWidth >>= (sample % 2); + *pWidth >>= q; + *pHeight >>= (q + r); } else { - *pHeight >>= (sample % 2); + *pWidth >>= (q + r); + *pHeight >>= q; } } @@ -2133,7 +1515,7 @@ ADDR_E_RETURNCODE Lib::ComputeBlockDimensionForSurf( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeBlockDimension * * @brief @@ -2141,7 +1523,7 @@ ADDR_E_RETURNCODE Lib::ComputeBlockDimensionForSurf( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeBlockDimension( UINT_32* pWidth, @@ -2153,37 +1535,33 @@ ADDR_E_RETURNCODE Lib::ComputeBlockDimension( { ADDR_E_RETURNCODE returnCode = ADDR_OK; - UINT_32 eleBytes = bpp >> 3; + UINT_32 eleBytes = bpp >> 3; UINT_32 microBlockSizeTableIndex = Log2(eleBytes); - UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode); + UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode); if (IsThin(resourceType, swizzleMode)) { - if (pDepth != NULL) - { - *pDepth = 1; - } - UINT_32 log2blkSizeIn256B = log2blkSize - 8; - UINT_32 widthAmp = log2blkSizeIn256B / 2; - UINT_32 heightAmp = log2blkSizeIn256B - widthAmp; + UINT_32 widthAmp = log2blkSizeIn256B / 2; + UINT_32 heightAmp = log2blkSizeIn256B - widthAmp; - ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block256b) / sizeof(Block256b[0])); + ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block256_2d) / sizeof(Block256_2d[0])); - *pWidth = (Block256b[microBlockSizeTableIndex].w << widthAmp); - *pHeight = (Block256b[microBlockSizeTableIndex].h << heightAmp); + *pWidth = (Block256_2d[microBlockSizeTableIndex].w << widthAmp); + *pHeight = (Block256_2d[microBlockSizeTableIndex].h << heightAmp); + *pDepth = 1; } else if (IsThick(resourceType, swizzleMode)) { UINT_32 log2blkSizeIn1KB = log2blkSize - 10; - UINT_32 averageAmp = log2blkSizeIn1KB / 3; - UINT_32 restAmp = log2blkSizeIn1KB % 3; + UINT_32 averageAmp = log2blkSizeIn1KB / 3; + UINT_32 restAmp = log2blkSizeIn1KB % 3; - ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block1kb) / sizeof(Block1kb[0])); + ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block1K_3d) / sizeof(Block1K_3d[0])); - *pWidth = Block1kb[microBlockSizeTableIndex].w << averageAmp; - *pHeight = Block1kb[microBlockSizeTableIndex].h << (averageAmp + (restAmp / 2)); - *pDepth = Block1kb[microBlockSizeTableIndex].d << (averageAmp + ((restAmp != 0) ? 1 : 0)); + *pWidth = Block1K_3d[microBlockSizeTableIndex].w << averageAmp; + *pHeight = Block1K_3d[microBlockSizeTableIndex].h << (averageAmp + (restAmp / 2)); + *pDepth = Block1K_3d[microBlockSizeTableIndex].d << (averageAmp + ((restAmp != 0) ? 1 : 0)); } else { @@ -2195,278 +1573,7 @@ ADDR_E_RETURNCODE Lib::ComputeBlockDimension( } /** -**************************************************************************************************** -* Lib::GetMipChainInfo -* -* @brief -* Internal function to get out information about mip chain -* -* @return -* Smaller value between Id of first mip fitted in mip tail and max Id of mip being created -**************************************************************************************************** -*/ -UINT_32 Lib::GetMipChainInfo( - AddrResourceType resourceType, - AddrSwizzleMode swizzleMode, - UINT_32 bpp, - UINT_32 mip0Width, - UINT_32 mip0Height, - UINT_32 mip0Depth, - UINT_32 blockWidth, - UINT_32 blockHeight, - UINT_32 blockDepth, - UINT_32 numMipLevel, - ADDR2_MIP_INFO* pMipInfo) const -{ - const Dim3d tailMaxDim = - GetMipTailDim(resourceType, swizzleMode, blockWidth, blockHeight, blockDepth); - - UINT_32 mipPitch = mip0Width; - UINT_32 mipHeight = mip0Height; - UINT_32 mipDepth = IsTex3d(resourceType) ? mip0Depth : 1; - UINT_32 offset = 0; - UINT_32 endingMip = numMipLevel - 1; - BOOL_32 inTail = FALSE; - BOOL_32 finalDim = FALSE; - - BOOL_32 is3dThick = IsThick(resourceType, swizzleMode); - BOOL_32 is3dThin = IsTex3d(resourceType) && SwizzleModeTable[swizzleMode].isDisp; - - for (UINT_32 mipId = 0; mipId < numMipLevel; mipId++) - { - if (inTail) - { - if (finalDim == FALSE) - { - UINT_32 mipSize; - - if (is3dThick) - { - mipSize = mipPitch * mipHeight * mipDepth * (bpp >> 3); - } - else - { - mipSize = mipPitch * mipHeight * (bpp >> 3); - } - - if (mipSize <= 256) - { - UINT_32 index = Log2(bpp >> 3); - - if (is3dThick) - { - mipPitch = CompressBlock3dZ[index].w; - mipHeight = CompressBlock3dZ[index].h; - mipDepth = CompressBlock3dZ[index].d; - } - else - { - mipPitch = CompressBlock2d[index].w; - mipHeight = CompressBlock2d[index].h; - } - - finalDim = TRUE; - } - } - } - else - { - inTail = IsInMipTail(resourceType, swizzleMode, tailMaxDim, - mipPitch, mipHeight, mipDepth); - - if (inTail) - { - endingMip = mipId; - - mipPitch = tailMaxDim.w; - mipHeight = tailMaxDim.h; - - if (is3dThick) - { - mipDepth = tailMaxDim.d; - } - } - else - { - mipPitch = PowTwoAlign(mipPitch, blockWidth); - mipHeight = PowTwoAlign(mipHeight, blockHeight); - - if (is3dThick) - { - mipDepth = PowTwoAlign(mipDepth, blockDepth); - } - } - } - - pMipInfo[mipId].pitch = mipPitch; - pMipInfo[mipId].height = mipHeight; - pMipInfo[mipId].depth = mipDepth; - pMipInfo[mipId].offset = offset; - offset += (mipPitch * mipHeight * mipDepth * (bpp >> 3)); - - if (finalDim) - { - if (is3dThin) - { - mipDepth = Max(mipDepth >> 1, 1u); - } - } - else - { - mipPitch = Max(mipPitch >> 1, 1u); - mipHeight = Max(mipHeight >> 1, 1u); - - if (is3dThick || is3dThin) - { - mipDepth = Max(mipDepth >> 1, 1u); - } - } - } - - return endingMip; -} - -/** -**************************************************************************************************** -* Lib::GetMipStartPos -* -* @brief -* Internal function to get out information about mip logical start position -* -* @return -* logical start position in macro block width/heith/depth of one mip level within one slice -**************************************************************************************************** -*/ -Dim3d Lib::GetMipStartPos( - AddrResourceType resourceType, - AddrSwizzleMode swizzleMode, - UINT_32 width, - UINT_32 height, - UINT_32 depth, - UINT_32 blockWidth, - UINT_32 blockHeight, - UINT_32 blockDepth, - UINT_32 mipId, - UINT_32* pMipTailOffset) const -{ - Dim3d mipStartPos = {0}; - - const Dim3d tailMaxDim = - GetMipTailDim(resourceType, swizzleMode, blockWidth, blockHeight, blockDepth); - - // Report mip in tail if Mip0 is already in mip tail - BOOL_32 inMipTail = IsInMipTail(resourceType, swizzleMode, tailMaxDim, width, height, depth); - - UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode); - - if (inMipTail == FALSE) - { - // Mip 0 dimension, unit in block - UINT_32 mipWidthInBlk = width / blockWidth; - UINT_32 mipHeightInBlk = height / blockHeight; - UINT_32 mipDepthInBlk = depth / blockDepth; - AddrMajorMode majorMode = GetMajorMode(resourceType, - swizzleMode, - mipWidthInBlk, - mipHeightInBlk, - mipDepthInBlk); - - UINT_32 endingMip = mipId + 1; - - for (UINT_32 i = 1; i <= mipId; i++) - { - if ((i == 1) || (i == 3)) - { - if (majorMode == ADDR_MAJOR_Y) - { - mipStartPos.w += mipWidthInBlk; - } - else - { - mipStartPos.h += mipHeightInBlk; - } - } - else - { - if (majorMode == ADDR_MAJOR_X) - { - mipStartPos.w += mipWidthInBlk; - } - else if (majorMode == ADDR_MAJOR_Y) - { - mipStartPos.h += mipHeightInBlk; - } - else - { - mipStartPos.d += mipDepthInBlk; - } - } - - BOOL_32 inTail = FALSE; - - if (IsThick(resourceType, swizzleMode)) - { - UINT_32 dim = log2blkSize % 3; - - if (dim == 0) - { - inTail = - (mipWidthInBlk <= 2) && (mipHeightInBlk == 1) && (mipDepthInBlk <= 2); - } - else if (dim == 1) - { - inTail = - (mipWidthInBlk == 1) && (mipHeightInBlk <= 2) && (mipDepthInBlk <= 2); - } - else - { - inTail = - (mipWidthInBlk <= 2) && (mipHeightInBlk <= 2) && (mipDepthInBlk == 1); - } - } - else - { - if (log2blkSize & 1) - { - inTail = (mipWidthInBlk <= 2) && (mipHeightInBlk == 1); - } - else - { - inTail = (mipWidthInBlk == 1) && (mipHeightInBlk <= 2); - } - } - - if (inTail) - { - endingMip = i; - break; - } - - mipWidthInBlk = RoundHalf(mipWidthInBlk); - mipHeightInBlk = RoundHalf(mipHeightInBlk); - mipDepthInBlk = RoundHalf(mipDepthInBlk); - } - - if (mipId >= endingMip) - { - inMipTail = TRUE; - UINT_32 index = mipId - endingMip + MaxMacroBits - log2blkSize; - ADDR_ASSERT(index < sizeof(MipTailOffset) / sizeof(UINT_32)); - *pMipTailOffset = MipTailOffset[index] << 8; - } - } - else - { - UINT_32 index = mipId + MaxMacroBits - log2blkSize; - ADDR_ASSERT(index < sizeof(MipTailOffset) / sizeof(UINT_32)); - *pMipTailOffset = MipTailOffset[index] << 8; - } - - return mipStartPos; -} - -/** -**************************************************************************************************** +************************************************************************************************************************ * Lib::GetMipTailDim * * @brief @@ -2474,7 +1581,7 @@ Dim3d Lib::GetMipStartPos( * * @return * Max Width/Height/Depth value of the first mip fitted in mip tail -**************************************************************************************************** +************************************************************************************************************************ */ Dim3d Lib::GetMipTailDim( AddrResourceType resourceType, @@ -2483,7 +1590,7 @@ Dim3d Lib::GetMipTailDim( UINT_32 blockHeight, UINT_32 blockDepth) const { - Dim3d out = {blockWidth, blockHeight, blockDepth}; + Dim3d out = {blockWidth, blockHeight, blockDepth}; UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode); if (IsThick(resourceType, swizzleMode)) @@ -2519,7 +1626,7 @@ Dim3d Lib::GetMipTailDim( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeSurface2DMicroBlockOffset * * @brief @@ -2527,7 +1634,7 @@ Dim3d Lib::GetMipTailDim( * * @return * micro block (256B) offset for 2D resource -**************************************************************************************************** +************************************************************************************************************************ */ UINT_32 Lib::ComputeSurface2DMicroBlockOffset( const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const @@ -2597,7 +1704,7 @@ UINT_32 Lib::ComputeSurface2DMicroBlockOffset( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeSurface3DMicroBlockOffset * * @brief @@ -2605,7 +1712,7 @@ UINT_32 Lib::ComputeSurface2DMicroBlockOffset( * * @return * micro block (1KB) offset for 3D resource -**************************************************************************************************** +************************************************************************************************************************ */ UINT_32 Lib::ComputeSurface3DMicroBlockOffset( const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const @@ -2703,7 +1810,7 @@ UINT_32 Lib::ComputeSurface3DMicroBlockOffset( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::GetPipeXorBits * * @brief @@ -2711,7 +1818,7 @@ UINT_32 Lib::ComputeSurface3DMicroBlockOffset( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ UINT_32 Lib::GetPipeXorBits( UINT_32 macroBlockBits) const @@ -2728,7 +1835,7 @@ UINT_32 Lib::GetPipeXorBits( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::GetBankXorBits * * @brief @@ -2736,7 +1843,7 @@ UINT_32 Lib::GetPipeXorBits( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ UINT_32 Lib::GetBankXorBits( UINT_32 macroBlockBits) const @@ -2750,7 +1857,7 @@ UINT_32 Lib::GetBankXorBits( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::Addr2GetPreferredSurfaceSetting * * @brief @@ -2758,412 +1865,30 @@ UINT_32 Lib::GetBankXorBits( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::Addr2GetPreferredSurfaceSetting( const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn, ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT* pOut) const { - // Macro define resource block type - enum AddrBlockType - { - AddrBlockMicro = 0, // Resource uses 256B block - AddrBlock4KB = 1, // Resource uses 4KB block - AddrBlock64KB = 2, // Resource uses 64KB block - AddrBlockVar = 3, // Resource uses var blcok - AddrBlockLinear = 4, // Resource uses linear swizzle mode - - AddrBlockMaxTiledType = AddrBlock64KB + 1, - }; - - enum AddrBlockSet - { - AddrBlockSetMicro = 1 << AddrBlockMicro, - AddrBlockSetMacro4KB = 1 << AddrBlock4KB, - AddrBlockSetMacro64KB = 1 << AddrBlock64KB, - AddrBlockSetVar = 1 << AddrBlockVar, - AddrBlockSetLinear = 1 << AddrBlockLinear, - - AddrBlockSetMacro = AddrBlockSetMacro4KB | AddrBlockSetMacro64KB, - }; - - ADDR_E_RETURNCODE returnCode = ADDR_OK; - ElemLib* pElemLib = GetElemLib(); - - // Set format to INVALID will skip this conversion - UINT_32 expandX = 1; - UINT_32 expandY = 1; - UINT_32 bpp = pIn->bpp; - if (pIn->format != ADDR_FMT_INVALID) - { - // Don't care for this case - ElemMode elemMode = ADDR_UNCOMPRESSED; - - // Get compression/expansion factors and element mode which indicates compression/expansion - bpp = pElemLib->GetBitsPerPixel(pIn->format, - &elemMode, - &expandX, - &expandY); - } - - UINT_32 numSamples = Max(pIn->numSamples, 1u); - UINT_32 numFrags = (pIn->numFrags == 0) ? numSamples : pIn->numFrags; - UINT_32 width = Max(pIn->width / expandX, 1u); - UINT_32 height = Max(pIn->height / expandY, 1u); - UINT_32 slice = Max(pIn->numSlices, 1u); - UINT_32 numMipLevels = Max(pIn->numMipLevels, 1u); + ADDR_E_RETURNCODE returnCode; - if (pIn->flags.fmask) + if ((GetFillSizeFieldsFlags() == TRUE) && + ((pIn->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_INPUT)) || + (pOut->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT)))) { - bpp = GetFmaskBpp(numSamples, numFrags); - numFrags = 1; - numSamples = 1; - pOut->resourceType = ADDR_RSRC_TEX_2D; + returnCode = ADDR_INVALIDPARAMS; } else { - // The output may get changed for volume(3D) texture resource in future - pOut->resourceType = pIn->resourceType; - } - - if (IsTex1d(pOut->resourceType)) - { - pOut->swizzleMode = ADDR_SW_LINEAR; - pOut->validBlockSet.value = AddrBlockSetLinear; - pOut->canXor = FALSE; - } - else - { - ADDR2_BLOCK_SET blockSet; - AddrSwType swType; - - blockSet.value = 0; - - BOOL_32 tryPrtXor = pIn->flags.prt; - - // Filter out improper swType and blockSet by HW restriction - if (pIn->flags.fmask || pIn->flags.depth || pIn->flags.stencil) - { - ADDR_ASSERT(IsTex2d(pOut->resourceType)); - blockSet.value = AddrBlockSetMacro; - swType = ADDR_SW_Z; - } - else if (pElemLib->IsBlockCompressed(pIn->format)) - { - // block compressed formats (BCx, ASTC, ETC2) must be either S or D modes. Not sure - // under what circumstances "_D" would be appropriate as these formats are not - // displayable. - blockSet.value = AddrBlockSetMacro; - swType = ADDR_SW_S; - } - else if (IsTex3d(pOut->resourceType)) - { - blockSet.value = AddrBlockSetLinear | AddrBlockSetMacro; - swType = (slice >= 8) ? ADDR_SW_Z : ADDR_SW_S; - } - else if (numMipLevels > 1) - { - ADDR_ASSERT(numFrags == 1); - blockSet.value = AddrBlockSetLinear | AddrBlockSetMacro; - swType = pIn->flags.display ? ADDR_SW_D : ADDR_SW_S; - } - else if ((numFrags > 1) || (numSamples > 1)) - { - ADDR_ASSERT(IsTex2d(pOut->resourceType)); - blockSet.value = AddrBlockSetMacro; - swType = pIn->flags.display ? ADDR_SW_D : ADDR_SW_S; - } - else - { - ADDR_ASSERT(IsTex2d(pOut->resourceType)); - blockSet.value = AddrBlockSetLinear | AddrBlockSetMicro | AddrBlockSetMacro; - if (pIn->flags.rotated || pIn->flags.display) - { - swType = pIn->flags.rotated ? ADDR_SW_R : ADDR_SW_D; - - if (IsDce12()) - { - if (pIn->bpp != 32) - { - blockSet.micro = FALSE; - } - - // DCE12 does not support display surface to be _T swizzle mode - tryPrtXor = FALSE; - } - else - { - ADDR_NOT_IMPLEMENTED(); - } - } - else if (pIn->flags.overlay) - { - swType = ADDR_SW_D; - } - else - { - swType = ADDR_SW_S; - } - } - - if ((numFrags > 1) && - (GetBlockSize(ADDR_SW_4KB) < (m_pipeInterleaveBytes * numFrags))) - { - // MSAA surface must have blk_bytes/pipe_interleave >= num_samples - blockSet.macro4KB = FALSE; - } - - if (pIn->flags.prt) - { - blockSet.value &= AddrBlock64KB; - } - - // Apply customized forbidden setting - blockSet.value &= ~pIn->forbiddenBlock.value; - - if (pIn->maxAlign > 0) - { - if (pIn->maxAlign < GetBlockSize(ADDR_SW_64KB)) - { - blockSet.macro64KB = FALSE; - } - - if (pIn->maxAlign < GetBlockSize(ADDR_SW_4KB)) - { - blockSet.macro4KB = FALSE; - } - - if (pIn->maxAlign < GetBlockSize(ADDR_SW_256B)) - { - blockSet.micro = FALSE; - } - } - - Dim3d blkDim[AddrBlockMaxTiledType] = {{0}, {0}, {0}}; - Dim3d padDim[AddrBlockMaxTiledType] = {{0}, {0}, {0}}; - UINT_64 padSize[AddrBlockMaxTiledType] = {0}; - - if (blockSet.micro) - { - returnCode = ComputeBlockDimensionForSurf(&blkDim[AddrBlockMicro], - bpp, - numFrags, - pOut->resourceType, - ADDR_SW_256B); - - if (returnCode == ADDR_OK) - { - if ((blkDim[AddrBlockMicro].w >= width) && (blkDim[AddrBlockMicro].h >= height)) - { - // If one 256B block can contain the surface, don't bother bigger block type - blockSet.macro4KB = FALSE; - blockSet.macro64KB = FALSE; - blockSet.var = FALSE; - } - - padSize[AddrBlockMicro] = ComputePadSize(&blkDim[AddrBlockMicro], width, height, - slice, &padDim[AddrBlockMicro]); - } - } - - if ((returnCode == ADDR_OK) && (blockSet.macro4KB)) - { - returnCode = ComputeBlockDimensionForSurf(&blkDim[AddrBlock4KB], - bpp, - numFrags, - pOut->resourceType, - ADDR_SW_4KB); - - if (returnCode == ADDR_OK) - { - padSize[AddrBlock4KB] = ComputePadSize(&blkDim[AddrBlock4KB], width, height, - slice, &padDim[AddrBlock4KB]); - - ADDR_ASSERT(padSize[AddrBlock4KB] >= padSize[AddrBlockMicro]); - } - } - - if ((returnCode == ADDR_OK) && (blockSet.macro64KB)) - { - returnCode = ComputeBlockDimensionForSurf(&blkDim[AddrBlock64KB], - bpp, - numFrags, - pOut->resourceType, - ADDR_SW_64KB); - - if (returnCode == ADDR_OK) - { - padSize[AddrBlock64KB] = ComputePadSize(&blkDim[AddrBlock64KB], width, height, - slice, &padDim[AddrBlock64KB]); - - ADDR_ASSERT(padSize[AddrBlock64KB] >= padSize[AddrBlock4KB]); - ADDR_ASSERT(padSize[AddrBlock64KB] >= padSize[AddrBlockMicro]); - - if ((padSize[AddrBlock64KB] >= static_cast(width) * height * slice * 2) && - ((blockSet.value & ~AddrBlockSetMacro64KB) != 0)) - { - // If 64KB block waste more than half memory on padding, filter it out from - // candidate list when it is not the only choice left - blockSet.macro64KB = FALSE; - } - } - } - - if (returnCode == ADDR_OK) - { - // Use minimum block type which meets all conditions above if flag minimizeAlign was set - if (pIn->flags.minimizeAlign) - { - // If padded size of 64KB block is larger than padded size of 256B block or 4KB - // block, filter out 64KB block from candidate list - if (blockSet.macro64KB && - ((blockSet.micro && (padSize[AddrBlockMicro] < padSize[AddrBlock64KB])) || - (blockSet.macro4KB && (padSize[AddrBlock4KB] < padSize[AddrBlock64KB])))) - { - blockSet.macro64KB = FALSE; - } - - // If padded size of 4KB block is larger than padded size of 256B block, - // filter out 4KB block from candidate list - if (blockSet.macro4KB && - blockSet.micro && - (padSize[AddrBlockMicro] < padSize[AddrBlock4KB])) - { - blockSet.macro4KB = FALSE; - } - } - // Filter out 64KB/4KB block if a smaller block type has 2/3 or less memory footprint - else if (pIn->flags.opt4space) - { - UINT_64 threshold = - blockSet.micro ? - padSize[AddrBlockMicro] : - (blockSet.macro4KB ? padSize[AddrBlock4KB] : padSize[AddrBlock64KB]); - - threshold += threshold >> 1; - - if (blockSet.macro64KB && (padSize[AddrBlock64KB] > threshold)) - { - blockSet.macro64KB = FALSE; - } - - if (blockSet.macro4KB && (padSize[AddrBlock4KB] > threshold)) - { - blockSet.macro4KB = FALSE; - } - } - - if (blockSet.value == 0) - { - // Bad things happen, client will not get any useful information from AddrLib. - // Maybe we should fill in some output earlier instead of outputing nothing? - ADDR_ASSERT_ALWAYS(); - returnCode = ADDR_INVALIDPARAMS; - } - else - { - pOut->validBlockSet = blockSet; - pOut->canXor = (pIn->flags.prt == FALSE) && - (blockSet.macro4KB || blockSet.macro64KB || blockSet.var); - - if (blockSet.macro64KB || blockSet.macro4KB) - { - if (swType == ADDR_SW_Z) - { - pOut->swizzleMode = blockSet.macro64KB ? ADDR_SW_64KB_Z : ADDR_SW_4KB_Z; - } - else if (swType == ADDR_SW_S) - { - pOut->swizzleMode = blockSet.macro64KB ? ADDR_SW_64KB_S : ADDR_SW_4KB_S; - } - else if (swType == ADDR_SW_D) - { - pOut->swizzleMode = blockSet.macro64KB ? ADDR_SW_64KB_D : ADDR_SW_4KB_D; - } - else - { - ADDR_ASSERT(swType == ADDR_SW_R); - pOut->swizzleMode = blockSet.macro64KB ? ADDR_SW_64KB_R : ADDR_SW_4KB_R; - } - - if (pIn->noXor == FALSE) - { - if (tryPrtXor && blockSet.macro64KB) - { - // Client wants PRTXOR, give back _T swizzle mode if 64KB is available - static const UINT_32 PrtGap = ADDR_SW_64KB_Z_T - ADDR_SW_64KB_Z; - pOut->swizzleMode = - static_cast(pOut->swizzleMode + PrtGap); - } - else if (pOut->canXor) - { - // Client wants XOR and this is allowed, return XOR version swizzle mode - static const UINT_32 XorGap = ADDR_SW_4KB_Z_X - ADDR_SW_4KB_Z; - pOut->swizzleMode = - static_cast(pOut->swizzleMode + XorGap); - } - } - } - else if (blockSet.var) - { - // Designer consider this swizzle is usless for most cases - ADDR_UNHANDLED_CASE(); - } - else if (blockSet.micro) - { - if (swType == ADDR_SW_S) - { - pOut->swizzleMode = ADDR_SW_256B_S; - } - else if (swType == ADDR_SW_D) - { - pOut->swizzleMode = ADDR_SW_256B_D; - } - else - { - ADDR_ASSERT(swType == ADDR_SW_R); - pOut->swizzleMode = ADDR_SW_256B_R; - } - } - else - { - ADDR_ASSERT(blockSet.linear); - // Fall into this branch doesn't mean linear is suitable, only no other choices! - pOut->swizzleMode = ADDR_SW_LINEAR; - } - -#if DEBUG - // Post sanity check, at least AddrLib should accept the output generated by its own - if (pOut->swizzleMode != ADDR_SW_LINEAR) - { - ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0}; - localIn.flags = pIn->flags; - localIn.swizzleMode = pOut->swizzleMode; - localIn.resourceType = pOut->resourceType; - localIn.format = pIn->format; - localIn.bpp = bpp; - localIn.width = width; - localIn.height = height; - localIn.numSlices = slice; - localIn.numMipLevels = numMipLevels; - localIn.numSamples = numSamples; - localIn.numFrags = numFrags; - - ADDR_E_RETURNCODE coherentCheck = ComputeSurfaceInfoSanityCheck(&localIn); - ADDR_ASSERT(coherentCheck == ADDR_OK); - - // TODO : check all valid block type available in validBlockSet? - } -#endif - } - } + returnCode = HwlGetPreferredSurfaceSetting(pIn, pOut); } return returnCode; } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeBlock256Equation * * @brief @@ -3172,7 +1897,7 @@ ADDR_E_RETURNCODE Lib::Addr2GetPreferredSurfaceSetting( * @return * If equation computed successfully * -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeBlock256Equation( AddrResourceType rsrcType, @@ -3196,7 +1921,7 @@ ADDR_E_RETURNCODE Lib::ComputeBlock256Equation( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeThinEquation * * @brief @@ -3205,7 +1930,7 @@ ADDR_E_RETURNCODE Lib::ComputeBlock256Equation( * @return * If equation computed successfully * -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeThinEquation( AddrResourceType rsrcType, @@ -3229,7 +1954,7 @@ ADDR_E_RETURNCODE Lib::ComputeThinEquation( } /** -**************************************************************************************************** +************************************************************************************************************************ * Lib::ComputeThickEquation * * @brief @@ -3238,7 +1963,7 @@ ADDR_E_RETURNCODE Lib::ComputeThinEquation( * @return * If equation computed successfully * -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeThickEquation( AddrResourceType rsrcType, @@ -3261,6 +1986,41 @@ ADDR_E_RETURNCODE Lib::ComputeThickEquation( return ret; } +/** +************************************************************************************************************************ +* Lib::ComputeQbStereoInfo +* +* @brief +* Get quad buffer stereo information +* @return +* N/A +************************************************************************************************************************ +*/ +VOID Lib::ComputeQbStereoInfo( + ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in,out] updated pOut+pStereoInfo + ) const +{ + ADDR_ASSERT(pOut->bpp >= 8); + ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0); + + // Save original height + pOut->pStereoInfo->eyeHeight = pOut->height; + + // Right offset + pOut->pStereoInfo->rightOffset = static_cast(pOut->surfSize); + + // Double height + pOut->height <<= 1; + + ADDR_ASSERT(pOut->height <= MaxSurfaceHeight); + + pOut->pixelHeight <<= 1; + + // Double size + pOut->surfSize <<= 1; +} + + } // V2 } // Addr diff --git a/src/amd/addrlib/core/addrlib2.h b/src/amd/addrlib/core/addrlib2.h index 2815a69e5cf..c9d7df0303e 100644 --- a/src/amd/addrlib/core/addrlib2.h +++ b/src/amd/addrlib/core/addrlib2.h @@ -25,10 +25,10 @@ */ /** -**************************************************************************************************** +************************************************************************************************************************ * @file addrlib2.h * @brief Contains the Addr::V2::Lib class definition. -**************************************************************************************************** +************************************************************************************************************************ */ #ifndef __ADDR2_LIB2_H__ @@ -42,9 +42,9 @@ namespace V2 { /** -**************************************************************************************************** +************************************************************************************************************************ * @brief Flags for SwizzleModeTable -**************************************************************************************************** +************************************************************************************************************************ */ struct SwizzleModeFlags { @@ -66,6 +66,8 @@ struct SwizzleModeFlags UINT_32 isXor : 1; // XOR after swizzle if set UINT_32 isT : 1; // T mode + + UINT_32 isRtOpt : 1; // mode opt for render target }; struct Dim2d @@ -82,9 +84,9 @@ struct Dim3d }; /** -**************************************************************************************************** +************************************************************************************************************************ * @brief This class contains asic independent address lib functionalities -**************************************************************************************************** +************************************************************************************************************************ */ class Lib : public Addr::Lib { @@ -155,10 +157,22 @@ public: const ADDR2_COMPUTE_DCCINFO_INPUT* pIn, ADDR2_COMPUTE_DCCINFO_OUTPUT* pOut) const; + ADDR_E_RETURNCODE ComputeDccAddrFromCoord( + const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn, + ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut) const; + // Misc ADDR_E_RETURNCODE ComputePipeBankXor( const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn, - ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut); + ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut); + + ADDR_E_RETURNCODE ComputeSlicePipeBankXor( + const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn, + ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut); + + ADDR_E_RETURNCODE ComputeSubResourceOffsetForSwizzlePattern( + const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn, + ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut); ADDR_E_RETURNCODE Addr2GetPreferredSurfaceSetting( const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn, @@ -168,77 +182,77 @@ protected: Lib(); // Constructor is protected Lib(const Client* pClient); - static const SwizzleModeFlags SwizzleModeTable[ADDR_SW_MAX_TYPE]; - - static const Dim2d Block256b[]; - static const Dim3d Block1kb[]; + static const UINT_32 MaxNumOfBpp = 5; - static const Dim2d CompressBlock2d[]; - static const Dim3d CompressBlock3dS[]; - static const Dim3d CompressBlock3dZ[]; + static const Dim2d Block256_2d[MaxNumOfBpp]; + static const Dim3d Block1K_3d[MaxNumOfBpp]; - static const UINT_32 MaxMacroBits; - static const UINT_32 MipTailOffset[]; + static const UINT_32 PrtAlignment = 64 * 1024; + static const UINT_32 MaxMacroBits = 20; // Checking block size - static BOOL_32 IsBlock256b(AddrSwizzleMode swizzleMode) + BOOL_32 IsBlock256b(AddrSwizzleMode swizzleMode) const { - return SwizzleModeTable[swizzleMode].is256b; + return m_swizzleModeTable[swizzleMode].is256b; } - static BOOL_32 IsBlock4kb(AddrSwizzleMode swizzleMode) + BOOL_32 IsBlock4kb(AddrSwizzleMode swizzleMode) const { - return SwizzleModeTable[swizzleMode].is4kb; + return m_swizzleModeTable[swizzleMode].is4kb; } - static BOOL_32 IsBlock64kb(AddrSwizzleMode swizzleMode) + BOOL_32 IsBlock64kb(AddrSwizzleMode swizzleMode) const { - return SwizzleModeTable[swizzleMode].is64kb; + return m_swizzleModeTable[swizzleMode].is64kb; } - static BOOL_32 IsBlockVariable(AddrSwizzleMode swizzleMode) + BOOL_32 IsBlockVariable(AddrSwizzleMode swizzleMode) const { - return SwizzleModeTable[swizzleMode].isVar; + return m_swizzleModeTable[swizzleMode].isVar; } // Checking swizzle mode - static BOOL_32 IsLinear(AddrSwizzleMode swizzleMode) + BOOL_32 IsLinear(AddrSwizzleMode swizzleMode) const { - return SwizzleModeTable[swizzleMode].isLinear; + return m_swizzleModeTable[swizzleMode].isLinear; } - static BOOL_32 IsZOrderSwizzle(AddrSwizzleMode swizzleMode) + BOOL_32 IsRtOptSwizzle(AddrSwizzleMode swizzleMode) const { - return SwizzleModeTable[swizzleMode].isZ; + return m_swizzleModeTable[swizzleMode].isRtOpt; } - static BOOL_32 IsStandardSwizzle(AddrResourceType resourceType, AddrSwizzleMode swizzleMode) + BOOL_32 IsZOrderSwizzle(AddrSwizzleMode swizzleMode) const { - return SwizzleModeTable[swizzleMode].isStd || - (IsTex3d(resourceType) && SwizzleModeTable[swizzleMode].isDisp); + return m_swizzleModeTable[swizzleMode].isZ; } - static BOOL_32 IsDisplaySwizzle(AddrResourceType resourceType, AddrSwizzleMode swizzleMode) + BOOL_32 IsStandardSwizzle(AddrResourceType resourceType, AddrSwizzleMode swizzleMode) const { - return IsTex2d(resourceType) && SwizzleModeTable[swizzleMode].isDisp; + return HwlIsStandardSwizzle(resourceType, swizzleMode); } - static BOOL_32 IsRotateSwizzle(AddrSwizzleMode swizzleMode) + BOOL_32 IsDisplaySwizzle(AddrResourceType resourceType, AddrSwizzleMode swizzleMode) const { - return SwizzleModeTable[swizzleMode].isRot; + return HwlIsDisplaySwizzle(resourceType, swizzleMode); } - static BOOL_32 IsXor(AddrSwizzleMode swizzleMode) + BOOL_32 IsRotateSwizzle(AddrSwizzleMode swizzleMode) const { - return SwizzleModeTable[swizzleMode].isXor; + return m_swizzleModeTable[swizzleMode].isRot; } - static BOOL_32 IsPrt(AddrSwizzleMode swizzleMode) + BOOL_32 IsXor(AddrSwizzleMode swizzleMode) const { - return SwizzleModeTable[swizzleMode].isT; + return m_swizzleModeTable[swizzleMode].isXor; } - static BOOL_32 IsNonPrtXor(AddrSwizzleMode swizzleMode) + BOOL_32 IsPrt(AddrSwizzleMode swizzleMode) const + { + return m_swizzleModeTable[swizzleMode].isT; + } + + BOOL_32 IsNonPrtXor(AddrSwizzleMode swizzleMode) const { return (IsXor(swizzleMode) && (IsPrt(swizzleMode) == FALSE)); } @@ -259,23 +273,21 @@ protected: return (resourceType == ADDR_RSRC_TEX_3D); } - static BOOL_32 IsThick(AddrResourceType resourceType, AddrSwizzleMode swizzleMode) + BOOL_32 IsThick(AddrResourceType resourceType, AddrSwizzleMode swizzleMode) const { - return (IsTex3d(resourceType) && - (SwizzleModeTable[swizzleMode].isZ || SwizzleModeTable[swizzleMode].isStd)); + return HwlIsThick(resourceType, swizzleMode); } - static BOOL_32 IsThin(AddrResourceType resourceType, AddrSwizzleMode swizzleMode) + BOOL_32 IsThin(AddrResourceType resourceType, AddrSwizzleMode swizzleMode) const { - return (IsTex2d(resourceType) || - (IsTex3d(resourceType) && SwizzleModeTable[swizzleMode].isDisp)); + return HwlIsThin(resourceType, swizzleMode); } UINT_32 GetBlockSizeLog2(AddrSwizzleMode swizzleMode) const { UINT_32 blockSizeLog2 = 0; - if (IsBlock256b(swizzleMode)) + if (IsBlock256b(swizzleMode) || IsLinear(swizzleMode)) { blockSizeLog2 = 8; } @@ -307,7 +319,7 @@ protected: static UINT_32 GetFmaskBpp(UINT_32 sample, UINT_32 frag) { sample = (sample == 0) ? 1 : sample; - frag = (frag == 0) ? sample : frag; + frag = (frag == 0) ? sample : frag; UINT_32 fmaskBpp = QLog2(frag); @@ -326,6 +338,38 @@ protected: return fmaskBpp; } + virtual BOOL_32 HwlIsStandardSwizzle( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode) const + { + ADDR_NOT_IMPLEMENTED(); + return FALSE; + } + + virtual BOOL_32 HwlIsDisplaySwizzle( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode) const + { + ADDR_NOT_IMPLEMENTED(); + return FALSE; + } + + virtual BOOL_32 HwlIsThin( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode) const + { + ADDR_NOT_IMPLEMENTED(); + return FALSE; + } + + virtual BOOL_32 HwlIsThick( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode) const + { + ADDR_NOT_IMPLEMENTED(); + return FALSE; + } + virtual ADDR_E_RETURNCODE HwlComputeHtileInfo( const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn, ADDR2_COMPUTE_HTILE_INFO_OUTPUT* pOut) const @@ -350,6 +394,14 @@ protected: return ADDR_NOTSUPPORTED; } + virtual ADDR_E_RETURNCODE HwlComputeDccAddrFromCoord( + const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn, + ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut) const + { + ADDR_NOT_IMPLEMENTED(); + return ADDR_NOTSUPPORTED; + } + virtual ADDR_E_RETURNCODE HwlComputeCmaskAddrFromCoord( const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut) const @@ -425,9 +477,60 @@ protected: return 0; } - UINT_32 ComputeSurfaceBaseAlign(AddrSwizzleMode swizzleMode) const + virtual ADDR_E_RETURNCODE HwlComputePipeBankXor( + const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn, + ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut) const + { + ADDR_NOT_IMPLEMENTED(); + return ADDR_NOTSUPPORTED; + } + + virtual ADDR_E_RETURNCODE HwlComputeSlicePipeBankXor( + const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn, + ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut) const + { + ADDR_NOT_IMPLEMENTED(); + return ADDR_NOTSUPPORTED; + } + + + virtual ADDR_E_RETURNCODE HwlComputeSubResourceOffsetForSwizzlePattern( + const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn, + ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut) const + { + ADDR_NOT_IMPLEMENTED(); + return ADDR_NOTSUPPORTED; + } + + virtual ADDR_E_RETURNCODE HwlGetPreferredSurfaceSetting( + const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn, + ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT* pOut) const + { + ADDR_NOT_IMPLEMENTED(); + return ADDR_NOTSUPPORTED; + } + + virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoSanityCheck( + const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const + { + ADDR_NOT_IMPLEMENTED(); + return ADDR_NOTSUPPORTED; + } + + virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoTiled( + const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, + ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const + { + ADDR_NOT_IMPLEMENTED(); + return ADDR_NOTIMPLEMENTED; + } + + virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoordTiled( + const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, + ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const { - return HwlComputeSurfaceBaseAlign(swizzleMode); + ADDR_NOT_IMPLEMENTED(); + return ADDR_NOTIMPLEMENTED; } ADDR_E_RETURNCODE ComputeBlock256Equation( @@ -488,13 +591,6 @@ protected: const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const; // Misc - ADDR_E_RETURNCODE ComputeBlockDimensionForSurf( - Dim3d* pDim, - UINT_32 bpp, - UINT_32 numSamples, - AddrResourceType resourceType, - AddrSwizzleMode swizzleMode) const; - ADDR_E_RETURNCODE ComputeBlockDimensionForSurf( UINT_32* pWidth, UINT_32* pHeight, @@ -525,26 +621,6 @@ protected: return static_cast(pPadDim->w) * pPadDim->h * pPadDim->d; } - UINT_32 GetMipChainInfo( - AddrResourceType resourceType, - AddrSwizzleMode swizzleMode, - UINT_32 bpp, - UINT_32 mip0Width, - UINT_32 mip0Height, - UINT_32 mip0Depth, - UINT_32 blockWidth, - UINT_32 blockHeight, - UINT_32 blockDepth, - UINT_32 numMipLevel, - ADDR2_MIP_INFO* pMipInfo) const; - - VOID GetMetaMiptailInfo( - ADDR2_META_MIP_INFO* pInfo, - Dim3d mipCoord, - UINT_32 numMipInTail, - Dim3d* pMetaBlkDim - ) const; - static ADDR_E_RETURNCODE ExtractPipeBankXor( UINT_32 pipeBankXor, UINT_32 bankBits, @@ -560,76 +636,6 @@ protected: return (Max((numSlices >> mipId), 1u) > slice); } - static AddrMajorMode GetMajorMode( - AddrResourceType resourceType, - AddrSwizzleMode swizzleMode, - UINT_32 mip0WidthInBlk, - UINT_32 mip0HeightInBlk, - UINT_32 mip0DepthInBlk) - { - BOOL_32 yMajor = (mip0WidthInBlk < mip0HeightInBlk); - BOOL_32 xMajor = (yMajor == FALSE); - - if (IsThick(resourceType, swizzleMode)) - { - yMajor = yMajor && (mip0HeightInBlk >= mip0DepthInBlk); - xMajor = xMajor && (mip0WidthInBlk >= mip0DepthInBlk); - } - - AddrMajorMode majorMode; - if (xMajor) - { - majorMode = ADDR_MAJOR_X; - } - else if (yMajor) - { - majorMode = ADDR_MAJOR_Y; - } - else - { - majorMode = ADDR_MAJOR_Z; - } - - return majorMode; - } - - static Dim3d GetDccCompressBlk( - AddrResourceType resourceType, - AddrSwizzleMode swizzleMode, - UINT_32 bpp) - { - UINT_32 index = Log2(bpp >> 3); - Dim3d compressBlkDim; - if (IsThin(resourceType, swizzleMode)) - { - compressBlkDim.w = CompressBlock2d[index].w; - compressBlkDim.h = CompressBlock2d[index].h; - compressBlkDim.d = 1; - } - else if (IsStandardSwizzle(resourceType, swizzleMode)) - { - compressBlkDim = CompressBlock3dS[index]; - } - else - { - compressBlkDim = CompressBlock3dZ[index]; - } - - return compressBlkDim; - } - - Dim3d GetMipStartPos( - AddrResourceType resourceType, - AddrSwizzleMode swizzleMode, - UINT_32 width, - UINT_32 height, - UINT_32 depth, - UINT_32 blockWidth, - UINT_32 blockHeight, - UINT_32 blockDepth, - UINT_32 mipId, - UINT_32* pMipTailOffset) const; - Dim3d GetMipTailDim( AddrResourceType resourceType, AddrSwizzleMode swizzleMode, @@ -637,13 +643,13 @@ protected: UINT_32 blockHeight, UINT_32 blockDepth) const; - static BOOL_32 IsInMipTail( + BOOL_32 IsInMipTail( AddrResourceType resourceType, AddrSwizzleMode swizzleMode, Dim3d mipTailDim, UINT_32 width, UINT_32 height, - UINT_32 depth) + UINT_32 depth) const { BOOL_32 inTail = ((width <= mipTailDim.w) && (height <= mipTailDim.h) && @@ -742,32 +748,15 @@ protected: UINT_32 GetPipeXorBits(UINT_32 macroBlockBits) const; UINT_32 GetBankXorBits(UINT_32 macroBlockBits) const; - virtual BOOL_32 HwlIsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const - { - ADDR_NOT_IMPLEMENTED(); - return FALSE; - } - - BOOL_32 IsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const - { - return HwlIsValidDisplaySwizzleMode(pIn); - } - - virtual BOOL_32 HwlIsDce12() const - { - ADDR_NOT_IMPLEMENTED(); - return FALSE; - } - - BOOL_32 IsDce12() const { return HwlIsDce12(); } - ADDR_E_RETURNCODE ApplyCustomizedPitchHeight( const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, UINT_32 elementBytes, - UINT_32 widthAlignInElement, + UINT_32 pitchAlignInElement, UINT_32* pPitch, UINT_32* pHeight) const; + VOID ComputeQbStereoInfo(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const; + UINT_32 m_se; ///< Number of shader engine UINT_32 m_rbPerSe; ///< Number of render backend per shader engine UINT_32 m_maxCompFrag; ///< Number of max compressed fragment @@ -782,6 +771,8 @@ protected: UINT_32 m_blockVarSizeLog2; ///< Log2 of block var size + SwizzleModeFlags m_swizzleModeTable[ADDR_SW_MAX_TYPE]; ///< Swizzle mode table + private: // Disallow the copy constructor Lib(const Lib& a); diff --git a/src/amd/addrlib/gfx9/gfx9addrlib.cpp b/src/amd/addrlib/gfx9/gfx9addrlib.cpp index 380b785e595..96b05de3dfe 100644 --- a/src/amd/addrlib/gfx9/gfx9addrlib.cpp +++ b/src/amd/addrlib/gfx9/gfx9addrlib.cpp @@ -25,10 +25,10 @@ */ /** -**************************************************************************************************** +************************************************************************************************************************ * @file gfx9addrlib.cpp * @brief Contgfx9ns the implementation for the Gfx9Lib class. -**************************************************************************************************** +************************************************************************************************************************ */ #include "gfx9addrlib.h" @@ -50,7 +50,7 @@ namespace Addr { /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9HwlInit * * @brief @@ -58,7 +58,7 @@ namespace Addr * * @return * Returns an Gfx9Lib object pointer. -**************************************************************************************************** +************************************************************************************************************************ */ Addr::Lib* Gfx9HwlInit(const Client* pClient) { @@ -68,14 +68,69 @@ Addr::Lib* Gfx9HwlInit(const Client* pClient) namespace V2 { +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Static Const Member +//////////////////////////////////////////////////////////////////////////////////////////////////// + +const SwizzleModeFlags Gfx9Lib::SwizzleModeTable[ADDR_SW_MAX_TYPE] = +{//Linear 256B 4KB 64KB Var Z Std Disp Rot XOR T RtOpt + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // ADDR_SW_LINEAR + {0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, // ADDR_SW_256B_S + {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, // ADDR_SW_256B_D + {0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, // ADDR_SW_256B_R + + {0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0}, // ADDR_SW_4KB_Z + {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0}, // ADDR_SW_4KB_S + {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}, // ADDR_SW_4KB_D + {0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0}, // ADDR_SW_4KB_R + + {0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0}, // ADDR_SW_64KB_Z + {0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0}, // ADDR_SW_64KB_S + {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0}, // ADDR_SW_64KB_D + {0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0}, // ADDR_SW_64KB_R + + {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_SW_VAR_Z + {0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0}, // ADDR_SW_VAR_S + {0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_SW_VAR_D + {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, // ADDR_SW_VAR_R + + {0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0}, // ADDR_SW_64KB_Z_T + {0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0}, // ADDR_SW_64KB_S_T + {0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0}, // ADDR_SW_64KB_D_T + {0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0}, // ADDR_SW_64KB_R_T + + {0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0}, // ADDR_SW_4KB_Z_x + {0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0}, // ADDR_SW_4KB_S_x + {0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0}, // ADDR_SW_4KB_D_x + {0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0}, // ADDR_SW_4KB_R_x + + {0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0}, // ADDR_SW_64KB_Z_X + {0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, // ADDR_SW_64KB_S_X + {0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0}, // ADDR_SW_64KB_D_X + {0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0}, // ADDR_SW_64KB_R_X + + {0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0}, // ADDR_SW_VAR_Z_X + {0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0}, // ADDR_SW_VAR_S_X + {0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0}, // ADDR_SW_VAR_D_X + {0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0}, // ADDR_SW_VAR_R_X + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // ADDR_SW_LINEAR_GENERAL +}; + +const UINT_32 Gfx9Lib::MipTailOffset256B[] = {2048, 1024, 512, 256, 128, 64, 32, 16, + 8, 6, 5, 4, 3, 2, 1, 0}; + +const Dim3d Gfx9Lib::Block256_3dS[] = {{16, 4, 4}, {8, 4, 4}, {4, 4, 4}, {2, 4, 4}, {1, 4, 4}}; + +const Dim3d Gfx9Lib::Block256_3dZ[] = {{8, 4, 8}, {4, 4, 8}, {4, 4, 4}, {4, 2, 4}, {2, 2, 4}}; + /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::Gfx9Lib * * @brief * Constructor * -**************************************************************************************************** +************************************************************************************************************************ */ Gfx9Lib::Gfx9Lib(const Client* pClient) : @@ -84,22 +139,23 @@ Gfx9Lib::Gfx9Lib(const Client* pClient) { m_class = AI_ADDRLIB; memset(&m_settings, 0, sizeof(m_settings)); + memcpy(m_swizzleModeTable, SwizzleModeTable, sizeof(SwizzleModeTable)); } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::~Gfx9Lib * * @brief * Destructor -**************************************************************************************************** +************************************************************************************************************************ */ Gfx9Lib::~Gfx9Lib() { } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeHtileInfo * * @brief @@ -107,7 +163,7 @@ Gfx9Lib::~Gfx9Lib() * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileInfo( const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn, ///< [in] input structure @@ -174,6 +230,13 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileInfo( pOut->metaBlkHeight = metaBlkDim.h; pOut->metaBlkNumPerSlice = numMetaBlkX * numMetaBlkY; + pOut->baseAlign = Max(numCompressBlkPerMetaBlk * 4, sizeAlign); + + if (m_settings.metaBaseAlignFix) + { + pOut->baseAlign = Max(pOut->baseAlign, GetBlockSize(pIn->swizzleMode)); + } + if ((IsXor(pIn->swizzleMode) == FALSE) && (numPipeTotal > 2)) { UINT_32 additionalAlign = numPipeTotal * numCompressBlkPerMetaBlk * 2; @@ -185,18 +248,12 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileInfo( } pOut->htileBytes = PowTwoAlign(pOut->sliceSize * numMetaBlkZ, sizeAlign); - pOut->baseAlign = Max(numCompressBlkPerMetaBlk * 4, sizeAlign); - - if (m_settings.metaBaseAlignFix) - { - pOut->baseAlign = Max(pOut->baseAlign, HwlComputeSurfaceBaseAlign(pIn->swizzleMode)); - } return ADDR_OK; } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeCmaskInfo * * @brief @@ -204,7 +261,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileInfo( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskInfo( const ADDR2_COMPUTE_CMASK_INFO_INPUT* pIn, ///< [in] input structure @@ -270,7 +327,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskInfo( if (m_settings.metaBaseAlignFix) { - pOut->baseAlign = Max(pOut->baseAlign, HwlComputeSurfaceBaseAlign(pIn->swizzleMode)); + pOut->baseAlign = Max(pOut->baseAlign, GetBlockSize(pIn->swizzleMode)); } pOut->metaBlkWidth = metaBlkDim.w; @@ -282,7 +339,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskInfo( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::GetMetaMipInfo * * @brief @@ -290,7 +347,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskInfo( * * @return * N/A -**************************************************************************************************** +************************************************************************************************************************ */ VOID Gfx9Lib::GetMetaMipInfo( UINT_32 numMipLevels, ///< [in] number of mip levels @@ -456,7 +513,7 @@ VOID Gfx9Lib::GetMetaMipInfo( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeDccInfo * * @brief @@ -464,7 +521,7 @@ VOID Gfx9Lib::GetMetaMipInfo( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeDccInfo( const ADDR2_COMPUTE_DCCINFO_INPUT* pIn, ///< [in] input structure @@ -500,8 +557,8 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeDccInfo( UINT_32 minMetaBlkSize = dataThick ? 65536 : 4096; - UINT_32 numFrags = (pIn->numFrags == 0) ? 1 : pIn->numFrags; - UINT_32 numSlices = (pIn->numSlices == 0) ? 1 : pIn->numSlices; + UINT_32 numFrags = Max(pIn->numFrags, 1u); + UINT_32 numSlices = Max(pIn->numSlices, 1u); minMetaBlkSize /= numFrags; @@ -572,7 +629,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeDccInfo( if (m_settings.metaBaseAlignFix) { - pOut->dccRamBaseAlign = Max(pOut->dccRamBaseAlign, HwlComputeSurfaceBaseAlign(pIn->swizzleMode)); + pOut->dccRamBaseAlign = Max(pOut->dccRamBaseAlign, GetBlockSize(pIn->swizzleMode)); } pOut->pitch = numMetaBlkX * metaBlkDim.w; @@ -596,14 +653,14 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeDccInfo( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlGetMaxAlignments * * @brief * Gets maximum alignments * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlGetMaxAlignments( ADDR_GET_MAX_ALINGMENTS_OUTPUT* pOut ///< [out] output structure @@ -615,7 +672,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlGetMaxAlignments( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeCmaskAddrFromCoord * * @brief @@ -623,39 +680,34 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlGetMaxAlignments( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskAddrFromCoord( const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure ) const { - ADDR2_COMPUTE_CMASK_INFO_INPUT input; - ADDR2_COMPUTE_CMASK_INFO_OUTPUT output; - - memset(&input, 0, sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT)); - input.size = sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT); - input.cMaskFlags = pIn->cMaskFlags; - input.colorFlags = pIn->colorFlags; - input.unalignedWidth = Max(pIn->unalignedWidth, 1u); + ADDR2_COMPUTE_CMASK_INFO_INPUT input = {0}; + input.size = sizeof(input); + input.cMaskFlags = pIn->cMaskFlags; + input.colorFlags = pIn->colorFlags; + input.unalignedWidth = Max(pIn->unalignedWidth, 1u); input.unalignedHeight = Max(pIn->unalignedHeight, 1u); - input.numSlices = Max(pIn->numSlices, 1u); - input.swizzleMode = pIn->swizzleMode; - input.resourceType = pIn->resourceType; + input.numSlices = Max(pIn->numSlices, 1u); + input.swizzleMode = pIn->swizzleMode; + input.resourceType = pIn->resourceType; - memset(&output, 0, sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT)); - output.size = sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT); + ADDR2_COMPUTE_CMASK_INFO_OUTPUT output = {0}; + output.size = sizeof(output); ADDR_E_RETURNCODE returnCode = ComputeCmaskInfo(&input, &output); if (returnCode == ADDR_OK) { - UINT_32 fmaskBpp = GetFmaskBpp(pIn->numSamples, pIn->numFrags); - + UINT_32 fmaskBpp = GetFmaskBpp(pIn->numSamples, pIn->numFrags); UINT_32 fmaskElementBytesLog2 = Log2(fmaskBpp >> 3); - - UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth); - UINT_32 metaBlkHeightLog2 = Log2(output.metaBlkHeight); + UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth); + UINT_32 metaBlkHeightLog2 = Log2(output.metaBlkHeight); CoordEq metaEq; @@ -667,9 +719,9 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskAddrFromCoord( UINT_32 yb = pIn->y / output.metaBlkHeight; UINT_32 zb = pIn->slice; - UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth; + UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth; UINT_32 sliceSizeInBlock = (output.height / output.metaBlkHeight) * pitchInBlock; - UINT_32 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb; + UINT_32 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb; UINT_64 address = metaEq.solve(pIn->x, pIn->y, pIn->slice, 0, blockIndex); @@ -689,7 +741,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskAddrFromCoord( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeHtileAddrFromCoord * * @brief @@ -697,7 +749,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskAddrFromCoord( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileAddrFromCoord( const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure @@ -712,32 +764,27 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileAddrFromCoord( } else { - ADDR2_COMPUTE_HTILE_INFO_INPUT input; - ADDR2_COMPUTE_HTILE_INFO_OUTPUT output; - - memset(&input, 0, sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT)); - input.size = sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT); - input.hTileFlags = pIn->hTileFlags; - input.depthFlags = pIn->depthflags; - input.swizzleMode = pIn->swizzleMode; - input.unalignedWidth = Max(pIn->unalignedWidth, 1u); + ADDR2_COMPUTE_HTILE_INFO_INPUT input = {0}; + input.size = sizeof(input); + input.hTileFlags = pIn->hTileFlags; + input.depthFlags = pIn->depthflags; + input.swizzleMode = pIn->swizzleMode; + input.unalignedWidth = Max(pIn->unalignedWidth, 1u); input.unalignedHeight = Max(pIn->unalignedHeight, 1u); - input.numSlices = Max(pIn->numSlices, 1u); - input.numMipLevels = Max(pIn->numMipLevels, 1u); + input.numSlices = Max(pIn->numSlices, 1u); + input.numMipLevels = Max(pIn->numMipLevels, 1u); - memset(&output, 0, sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT)); - output.size = sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT); + ADDR2_COMPUTE_HTILE_INFO_OUTPUT output = {0}; + output.size = sizeof(output); returnCode = ComputeHtileInfo(&input, &output); if (returnCode == ADDR_OK) { - UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3); - - UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth); + UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3); + UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth); UINT_32 metaBlkHeightLog2 = Log2(output.metaBlkHeight); - - UINT_32 numSamplesLog2 = Log2(pIn->numSamples); + UINT_32 numSamplesLog2 = Log2(pIn->numSamples); CoordEq metaEq; @@ -749,9 +796,9 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileAddrFromCoord( UINT_32 yb = pIn->y / output.metaBlkHeight; UINT_32 zb = pIn->slice; - UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth; + UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth; UINT_32 sliceSizeInBlock = (output.height / output.metaBlkHeight) * pitchInBlock; - UINT_32 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb; + UINT_32 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb; UINT_64 address = metaEq.solve(pIn->x, pIn->y, pIn->slice, 0, blockIndex); @@ -770,7 +817,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileAddrFromCoord( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeHtileCoordFromAddr * * @brief @@ -778,7 +825,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileAddrFromCoord( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileCoordFromAddr( const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure @@ -793,31 +840,26 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileCoordFromAddr( } else { - ADDR2_COMPUTE_HTILE_INFO_INPUT input; - ADDR2_COMPUTE_HTILE_INFO_OUTPUT output; - - memset(&input, 0, sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT)); - input.size = sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT); - input.hTileFlags = pIn->hTileFlags; - input.swizzleMode = pIn->swizzleMode; - input.unalignedWidth = Max(pIn->unalignedWidth, 1u); + ADDR2_COMPUTE_HTILE_INFO_INPUT input = {0}; + input.size = sizeof(input); + input.hTileFlags = pIn->hTileFlags; + input.swizzleMode = pIn->swizzleMode; + input.unalignedWidth = Max(pIn->unalignedWidth, 1u); input.unalignedHeight = Max(pIn->unalignedHeight, 1u); - input.numSlices = Max(pIn->numSlices, 1u); - input.numMipLevels = Max(pIn->numMipLevels, 1u); + input.numSlices = Max(pIn->numSlices, 1u); + input.numMipLevels = Max(pIn->numMipLevels, 1u); - memset(&output, 0, sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT)); - output.size = sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT); + ADDR2_COMPUTE_HTILE_INFO_OUTPUT output = {0}; + output.size = sizeof(output); returnCode = ComputeHtileInfo(&input, &output); if (returnCode == ADDR_OK) { - UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3); - - UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth); + UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3); + UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth); UINT_32 metaBlkHeightLog2 = Log2(output.metaBlkHeight); - - UINT_32 numSamplesLog2 = Log2(pIn->numSamples); + UINT_32 numSamplesLog2 = Log2(pIn->numSamples); CoordEq metaEq; @@ -832,16 +874,98 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileCoordFromAddr( UINT_64 nibbleAddress = (pIn->addr ^ (pipeXor << m_pipeInterleaveLog2)) << 1; - UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth; + UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth; UINT_32 sliceSizeInBlock = (output.height / output.metaBlkHeight) * pitchInBlock; UINT_32 x, y, z, s, m; - metaEq.solveAddr(nibbleAddress, sliceSizeInBlock, x, y, z, s, m); pOut->slice = m / sliceSizeInBlock; - pOut->y = ((m % sliceSizeInBlock) / pitchInBlock) * output.metaBlkHeight + y; - pOut->x = (m % pitchInBlock) * output.metaBlkWidth + x; + pOut->y = ((m % sliceSizeInBlock) / pitchInBlock) * output.metaBlkHeight + y; + pOut->x = (m % pitchInBlock) * output.metaBlkWidth + x; + } + } + + return returnCode; +} + +/** +************************************************************************************************************************ +* Gfx9Lib::HwlComputeDccAddrFromCoord +* +* @brief +* Interface function stub of AddrComputeDccAddrFromCoord +* +* @return +* ADDR_E_RETURNCODE +************************************************************************************************************************ +*/ +ADDR_E_RETURNCODE Gfx9Lib::HwlComputeDccAddrFromCoord( + const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn, + ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if ((pIn->numMipLevels > 1) || (pIn->mipId > 1) || pIn->dccKeyFlags.linear) + { + returnCode = ADDR_NOTIMPLEMENTED; + } + else + { + ADDR2_COMPUTE_DCCINFO_INPUT input = {0}; + input.size = sizeof(input); + input.dccKeyFlags = pIn->dccKeyFlags; + input.colorFlags = pIn->colorFlags; + input.swizzleMode = pIn->swizzleMode; + input.resourceType = pIn->resourceType; + input.bpp = pIn->bpp; + input.unalignedWidth = Max(pIn->unalignedWidth, 1u); + input.unalignedHeight = Max(pIn->unalignedHeight, 1u); + input.numSlices = Max(pIn->numSlices, 1u); + input.numFrags = Max(pIn->numFrags, 1u); + input.numMipLevels = Max(pIn->numMipLevels, 1u); + + ADDR2_COMPUTE_DCCINFO_OUTPUT output = {0}; + output.size = sizeof(output); + + returnCode = ComputeDccInfo(&input, &output); + + if (returnCode == ADDR_OK) + { + UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3); + UINT_32 numSamplesLog2 = Log2(pIn->numFrags); + UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth); + UINT_32 metaBlkHeightLog2 = Log2(output.metaBlkHeight); + UINT_32 metaBlkDepthLog2 = Log2(output.metaBlkDepth); + UINT_32 compBlkWidthLog2 = Log2(output.compressBlkWidth); + UINT_32 compBlkHeightLog2 = Log2(output.compressBlkHeight); + UINT_32 compBlkDepthLog2 = Log2(output.compressBlkDepth); + + CoordEq metaEq; + + GetMetaEquation(&metaEq, pIn->mipId, elementBytesLog2, numSamplesLog2, pIn->dccKeyFlags, + Gfx9DataColor, pIn->swizzleMode, pIn->resourceType, + metaBlkWidthLog2, metaBlkHeightLog2, metaBlkDepthLog2, + compBlkWidthLog2, compBlkHeightLog2, compBlkDepthLog2); + + UINT_32 xb = pIn->x / output.metaBlkWidth; + UINT_32 yb = pIn->y / output.metaBlkHeight; + UINT_32 zb = pIn->slice / output.metaBlkDepth; + + UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth; + UINT_32 sliceSizeInBlock = (output.height / output.metaBlkHeight) * pitchInBlock; + UINT_32 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb; + + UINT_64 address = metaEq.solve(pIn->x, pIn->y, pIn->slice, pIn->sample, blockIndex); + + pOut->addr = address >> 1; + + UINT_32 numPipeBits = GetPipeLog2ForMetaAddressing(pIn->dccKeyFlags.pipeAligned, + pIn->swizzleMode); + + UINT_64 pipeXor = static_cast(pIn->pipeXor & ((1 << numPipeBits) - 1)); + + pOut->addr ^= (pipeXor << m_pipeInterleaveLog2); } } @@ -849,7 +973,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileCoordFromAddr( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlInitGlobalParams * * @brief @@ -858,7 +982,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileCoordFromAddr( * @return * TRUE if all settings are valid * -**************************************************************************************************** +************************************************************************************************************************ */ BOOL_32 Gfx9Lib::HwlInitGlobalParams( const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input @@ -899,6 +1023,7 @@ BOOL_32 Gfx9Lib::HwlInitGlobalParams( m_pipesLog2 = 5; break; default: + ADDR_ASSERT_ALWAYS(); break; } @@ -921,6 +1046,7 @@ BOOL_32 Gfx9Lib::HwlInitGlobalParams( m_pipeInterleaveLog2 = 11; break; default: + ADDR_ASSERT_ALWAYS(); break; } @@ -947,6 +1073,7 @@ BOOL_32 Gfx9Lib::HwlInitGlobalParams( m_banksLog2 = 4; break; default: + ADDR_ASSERT_ALWAYS(); break; } @@ -969,6 +1096,7 @@ BOOL_32 Gfx9Lib::HwlInitGlobalParams( m_seLog2 = 3; break; default: + ADDR_ASSERT_ALWAYS(); break; } @@ -987,6 +1115,7 @@ BOOL_32 Gfx9Lib::HwlInitGlobalParams( m_rbPerSeLog2 = 2; break; default: + ADDR_ASSERT_ALWAYS(); break; } @@ -1009,6 +1138,7 @@ BOOL_32 Gfx9Lib::HwlInitGlobalParams( m_maxCompFragLog2 = 3; break; default: + ADDR_ASSERT_ALWAYS(); break; } @@ -1032,14 +1162,14 @@ BOOL_32 Gfx9Lib::HwlInitGlobalParams( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlConvertChipFamily * * @brief * Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision * @return * ChipFamily -**************************************************************************************************** +************************************************************************************************************************ */ ChipFamily Gfx9Lib::HwlConvertChipFamily( UINT_32 uChipFamily, ///< [in] chip family defined in atiih.h @@ -1058,8 +1188,9 @@ ChipFamily Gfx9Lib::HwlConvertChipFamily( m_settings.isDce12 = 1; } - // Bug ID DEGGIGX90-1056 m_settings.metaBaseAlignFix = 1; + + m_settings.depthPipeXorDisable = 1; break; default: @@ -1071,14 +1202,14 @@ ChipFamily Gfx9Lib::HwlConvertChipFamily( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::InitRbEquation * * @brief * Init RB equation * @return * N/A -**************************************************************************************************** +************************************************************************************************************************ */ VOID Gfx9Lib::GetRbEquation( CoordEq* pRbEq, ///< [out] rb equation @@ -1129,14 +1260,14 @@ VOID Gfx9Lib::GetRbEquation( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::GetDataEquation * * @brief * Get data equation for fmask and Z * @return * N/A -**************************************************************************************************** +************************************************************************************************************************ */ VOID Gfx9Lib::GetDataEquation( CoordEq* pDataEq, ///< [out] data surface equation @@ -1325,14 +1456,14 @@ VOID Gfx9Lib::GetDataEquation( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::GetPipeEquation * * @brief * Get pipe equation * @return * N/A -**************************************************************************************************** +************************************************************************************************************************ */ VOID Gfx9Lib::GetPipeEquation( CoordEq* pPipeEq, ///< [out] pipe equation @@ -1439,14 +1570,14 @@ VOID Gfx9Lib::GetPipeEquation( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::GetMetaEquation * * @brief * Get meta equation for cmask/htile/DCC * @return * N/A -**************************************************************************************************** +************************************************************************************************************************ */ VOID Gfx9Lib::GetMetaEquation( CoordEq* pMetaEq, ///< [out] meta equation @@ -1779,7 +1910,7 @@ VOID Gfx9Lib::GetMetaEquation( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::IsEquationSupported * * @brief @@ -1787,7 +1918,7 @@ VOID Gfx9Lib::GetMetaEquation( * * @return * TRUE if supported -**************************************************************************************************** +************************************************************************************************************************ */ BOOL_32 Gfx9Lib::IsEquationSupported( AddrResourceType rsrcType, @@ -1796,7 +1927,10 @@ BOOL_32 Gfx9Lib::IsEquationSupported( { BOOL_32 supported = (elementBytesLog2 < MaxElementBytesLog2) && (IsLinear(swMode) == FALSE) && - ((IsTex2d(rsrcType) == TRUE) || + (((IsTex2d(rsrcType) == TRUE) && + ((elementBytesLog2 < 4) || + ((IsRotateSwizzle(swMode) == FALSE) && + (IsZOrderSwizzle(swMode) == FALSE)))) || ((IsTex3d(rsrcType) == TRUE) && (IsRotateSwizzle(swMode) == FALSE) && (IsBlock256b(swMode) == FALSE))); @@ -1805,7 +1939,7 @@ BOOL_32 Gfx9Lib::IsEquationSupported( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::InitEquationTable * * @brief @@ -1813,7 +1947,7 @@ BOOL_32 Gfx9Lib::IsEquationSupported( * * @return * N/A -**************************************************************************************************** +************************************************************************************************************************ */ VOID Gfx9Lib::InitEquationTable() { @@ -1869,6 +2003,10 @@ VOID Gfx9Lib::InitEquationTable() m_numEquations++; } + else + { + ADDR_ASSERT_ALWAYS(); + } } // Fill the index into the lookup table, if the combination is not supported @@ -1880,7 +2018,7 @@ VOID Gfx9Lib::InitEquationTable() } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlGetEquationIndex * * @brief @@ -1888,78 +2026,31 @@ VOID Gfx9Lib::InitEquationTable() * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ UINT_32 Gfx9Lib::HwlGetEquationIndex( const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ) const { - AddrResourceType rsrcType = pIn->resourceType; - AddrSwizzleMode swMode = pIn->swizzleMode; - UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3); - UINT_32 numMipLevels = pIn->numMipLevels; - ADDR2_MIP_INFO* pMipInfo = pOut->pMipInfo; - - UINT_32 index = ADDR_INVALID_EQUATION_INDEX; - - BOOL_32 eqSupported = (pOut->firstMipInTail == FALSE) && - IsEquationSupported(rsrcType, swMode, elementBytesLog2); + AddrResourceType rsrcType = pIn->resourceType; + AddrSwizzleMode swMode = pIn->swizzleMode; + UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3); + UINT_32 index = ADDR_INVALID_EQUATION_INDEX; - UINT_32 rsrcTypeIdx = static_cast(rsrcType) - 1; - UINT_32 swModeIdx = static_cast(swMode); - - if (eqSupported) + if (IsEquationSupported(rsrcType, swMode, elementBytesLog2)) { - index = m_equationLookupTable[rsrcTypeIdx][swModeIdx][elementBytesLog2]; - - if (pMipInfo != NULL) - { - pMipInfo->equationIndex = index; - pMipInfo->mipOffsetXBytes = 0; - pMipInfo->mipOffsetYPixel = 0; - pMipInfo->mipOffsetZPixel = 0; - pMipInfo->postSwizzleOffset = 0; - - /*static const UINT_32 Prt_Xor_Gap = - static_cast(ADDR_SW_64KB_Z_T) - static_cast(ADDR_SW_64KB_Z);*/ - - for (UINT_32 i = 1; i < numMipLevels; i++) - { - Dim3d mipStartPos = {0}; - UINT_32 mipTailOffset = 0; - - mipStartPos = GetMipStartPos(rsrcType, - swMode, - pOut->pitch, - pOut->height, - pOut->numSlices, - pOut->blockWidth, - pOut->blockHeight, - pOut->blockSlices, - i, - &mipTailOffset); + UINT_32 rsrcTypeIdx = static_cast(rsrcType) - 1; + UINT_32 swModeIdx = static_cast(swMode); - UINT_32 mipSwModeIdx = swModeIdx; - - pMipInfo[i].equationIndex = - m_equationLookupTable[rsrcTypeIdx][mipSwModeIdx][elementBytesLog2]; - pMipInfo[i].mipOffsetXBytes = mipStartPos.w * pOut->blockWidth * (pOut->bpp >> 3); - pMipInfo[i].mipOffsetYPixel = mipStartPos.h * pOut->blockHeight; - pMipInfo[i].mipOffsetZPixel = mipStartPos.d * pOut->blockSlices; - pMipInfo[i].postSwizzleOffset = mipTailOffset; - } - } + index = m_equationLookupTable[rsrcTypeIdx][swModeIdx][elementBytesLog2]; } - else if (pMipInfo != NULL) + + if (pOut->pMipInfo != NULL) { - for (UINT_32 i = 0; i < numMipLevels; i++) + for (UINT_32 i = 0; i < pIn->numMipLevels; i++) { - pMipInfo[i].equationIndex = ADDR_INVALID_EQUATION_INDEX; - pMipInfo[i].mipOffsetXBytes = 0; - pMipInfo[i].mipOffsetYPixel = 0; - pMipInfo[i].mipOffsetZPixel = 0; - pMipInfo[i].postSwizzleOffset = 0; + pOut->pMipInfo[i].equationIndex = index; } } @@ -1967,7 +2058,7 @@ UINT_32 Gfx9Lib::HwlGetEquationIndex( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeBlock256Equation * * @brief @@ -1975,13 +2066,13 @@ UINT_32 Gfx9Lib::HwlGetEquationIndex( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeBlock256Equation( AddrResourceType rsrcType, - AddrSwizzleMode swMode, - UINT_32 elementBytesLog2, - ADDR_EQUATION* pEquation) const + AddrSwizzleMode swMode, + UINT_32 elementBytesLog2, + ADDR_EQUATION* pEquation) const { ADDR_E_RETURNCODE ret = ADDR_OK; @@ -1995,11 +2086,11 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeBlock256Equation( ADDR_CHANNEL_SETTING* pixelBit = &pEquation->addr[elementBytesLog2]; - const UINT_32 MaxBitsUsed = 4; - ADDR_CHANNEL_SETTING x[MaxBitsUsed] = {}; - ADDR_CHANNEL_SETTING y[MaxBitsUsed] = {}; + const UINT_32 maxBitsUsed = 4; + ADDR_CHANNEL_SETTING x[maxBitsUsed] = {}; + ADDR_CHANNEL_SETTING y[maxBitsUsed] = {}; - for (i = 0; i < MaxBitsUsed; i++) + for (i = 0; i < maxBitsUsed; i++) { InitChannel(1, 0, elementBytesLog2 + i, &x[i]); InitChannel(1, 1, i, &y[i]); @@ -2159,7 +2250,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeBlock256Equation( // Post validation if (ret == ADDR_OK) { - Dim2d microBlockDim = Block256b[elementBytesLog2]; + Dim2d microBlockDim = Block256_2d[elementBytesLog2]; ADDR_ASSERT((2u << GetMaxValidChannelIndex(pEquation->addr, 8, 0)) == (microBlockDim.w * (1 << elementBytesLog2))); ADDR_ASSERT((2u << GetMaxValidChannelIndex(pEquation->addr, 8, 1)) == microBlockDim.h); @@ -2169,7 +2260,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeBlock256Equation( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeThinEquation * * @brief @@ -2177,13 +2268,13 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeBlock256Equation( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThinEquation( AddrResourceType rsrcType, - AddrSwizzleMode swMode, - UINT_32 elementBytesLog2, - ADDR_EQUATION* pEquation) const + AddrSwizzleMode swMode, + UINT_32 elementBytesLog2, + ADDR_EQUATION* pEquation) const { ADDR_E_RETURNCODE ret = ADDR_OK; @@ -2204,16 +2295,16 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThinEquation( 2 * GetBankXorBits(blockSizeLog2)); } - const UINT_32 MaxBitsUsed = 14; - ADDR_ASSERT((2 * MaxBitsUsed) >= maxXorBits); - ADDR_CHANNEL_SETTING x[MaxBitsUsed] = {}; - ADDR_CHANNEL_SETTING y[MaxBitsUsed] = {}; + const UINT_32 maxBitsUsed = 14; + ADDR_ASSERT((2 * maxBitsUsed) >= maxXorBits); + ADDR_CHANNEL_SETTING x[maxBitsUsed] = {}; + ADDR_CHANNEL_SETTING y[maxBitsUsed] = {}; - const UINT_32 ExtraXorBits = 16; - ADDR_ASSERT(ExtraXorBits >= maxXorBits - blockSizeLog2); - ADDR_CHANNEL_SETTING xorExtra[ExtraXorBits] = {}; + const UINT_32 extraXorBits = 16; + ADDR_ASSERT(extraXorBits >= maxXorBits - blockSizeLog2); + ADDR_CHANNEL_SETTING xorExtra[extraXorBits] = {}; - for (UINT_32 i = 0; i < MaxBitsUsed; i++) + for (UINT_32 i = 0; i < maxBitsUsed; i++) { InitChannel(1, 0, elementBytesLog2 + i, &x[i]); InitChannel(1, 1, i, &y[i]); @@ -2249,9 +2340,10 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThinEquation( else { ret = HwlComputeBlock256Equation(rsrcType, swMode, elementBytesLog2, pEquation); + if (ret == ADDR_OK) { - Dim2d microBlockDim = Block256b[elementBytesLog2]; + Dim2d microBlockDim = Block256_2d[elementBytesLog2]; xIdx = Log2(microBlockDim.w); yIdx = Log2(microBlockDim.h); lowBits = 8; @@ -2269,48 +2361,56 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThinEquation( { xorExtra[i - blockSizeLog2] = ((i & 1) == 0) ? y[yIdx++] : x[xIdx++]; } - } - if ((ret == ADDR_OK) && IsXor(swMode)) - { - // Fill XOR bits - UINT_32 pipeStart = m_pipeInterleaveLog2; - UINT_32 pipeXorBits = GetPipeXorBits(blockSizeLog2); - for (UINT_32 i = 0; i < pipeXorBits; i++) + if (IsXor(swMode)) { - UINT_32 xor1BitPos = pipeStart + 2 * pipeXorBits - 1 - i; - ADDR_CHANNEL_SETTING* pXor1Src = - (xor1BitPos < blockSizeLog2) ? - &pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2]; + // Fill XOR bits + UINT_32 pipeStart = m_pipeInterleaveLog2; + UINT_32 pipeXorBits = GetPipeXorBits(blockSizeLog2); - InitChannel(&pEquation->xor1[pipeStart + i], pXor1Src); - } + UINT_32 bankStart = pipeStart + pipeXorBits; + UINT_32 bankXorBits = GetBankXorBits(blockSizeLog2); - UINT_32 bankStart = pipeStart + pipeXorBits; - UINT_32 bankXorBits = GetBankXorBits(blockSizeLog2); - for (UINT_32 i = 0; i < bankXorBits; i++) - { - UINT_32 xor1BitPos = bankStart + 2 * bankXorBits - 1 - i; - ADDR_CHANNEL_SETTING* pXor1Src = - (xor1BitPos < blockSizeLog2) ? - &pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2]; + for (UINT_32 i = 0; i < pipeXorBits; i++) + { + UINT_32 xor1BitPos = pipeStart + 2 * pipeXorBits - 1 - i; + ADDR_CHANNEL_SETTING* pXor1Src = (xor1BitPos < blockSizeLog2) ? + &pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2]; + + InitChannel(&pEquation->xor1[pipeStart + i], pXor1Src); + } + + for (UINT_32 i = 0; i < bankXorBits; i++) + { + UINT_32 xor1BitPos = bankStart + 2 * bankXorBits - 1 - i; + ADDR_CHANNEL_SETTING* pXor1Src = (xor1BitPos < blockSizeLog2) ? + &pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2]; + + InitChannel(&pEquation->xor1[bankStart + i], pXor1Src); + } + + if (IsPrt(swMode) == FALSE) + { + for (UINT_32 i = 0; i < pipeXorBits; i++) + { + InitChannel(1, 2, pipeXorBits - i - 1, &pEquation->xor2[pipeStart + i]); + } - InitChannel(&pEquation->xor1[pipeStart + i], pXor1Src); + for (UINT_32 i = 0; i < bankXorBits; i++) + { + InitChannel(1, 2, bankXorBits - i - 1 + pipeXorBits, &pEquation->xor2[bankStart + i]); + } + } } pEquation->numBits = blockSizeLog2; } - if ((ret == ADDR_OK) && IsTex3d(rsrcType)) - { - pEquation->stackedDepthSlices = TRUE; - } - return ret; } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeThickEquation * * @brief @@ -2318,13 +2418,13 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThinEquation( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThickEquation( AddrResourceType rsrcType, - AddrSwizzleMode swMode, - UINT_32 elementBytesLog2, - ADDR_EQUATION* pEquation) const + AddrSwizzleMode swMode, + UINT_32 elementBytesLog2, + ADDR_EQUATION* pEquation) const { ADDR_E_RETURNCODE ret = ADDR_OK; @@ -2354,17 +2454,17 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThickEquation( ADDR_CHANNEL_SETTING* pixelBit = &pEquation->addr[elementBytesLog2]; - const UINT_32 MaxBitsUsed = 12; - ADDR_ASSERT((3 * MaxBitsUsed) >= maxXorBits); - ADDR_CHANNEL_SETTING x[MaxBitsUsed] = {}; - ADDR_CHANNEL_SETTING y[MaxBitsUsed] = {}; - ADDR_CHANNEL_SETTING z[MaxBitsUsed] = {}; + const UINT_32 maxBitsUsed = 12; + ADDR_ASSERT((3 * maxBitsUsed) >= maxXorBits); + ADDR_CHANNEL_SETTING x[maxBitsUsed] = {}; + ADDR_CHANNEL_SETTING y[maxBitsUsed] = {}; + ADDR_CHANNEL_SETTING z[maxBitsUsed] = {}; - const UINT_32 ExtraXorBits = 24; - ADDR_ASSERT(ExtraXorBits >= maxXorBits - blockSizeLog2); - ADDR_CHANNEL_SETTING xorExtra[ExtraXorBits] = {}; + const UINT_32 extraXorBits = 24; + ADDR_ASSERT(extraXorBits >= maxXorBits - blockSizeLog2); + ADDR_CHANNEL_SETTING xorExtra[extraXorBits] = {}; - for (UINT_32 i = 0; i < MaxBitsUsed; i++) + for (UINT_32 i = 0; i < maxBitsUsed; i++) { InitChannel(1, 0, elementBytesLog2 + i, &x[i]); InitChannel(1, 1, i, &y[i]); @@ -2499,24 +2599,24 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThickEquation( if (ret == ADDR_OK) { - Dim3d microBlockDim = Block1kb[elementBytesLog2]; + Dim3d microBlockDim = Block1K_3d[elementBytesLog2]; UINT_32 xIdx = Log2(microBlockDim.w); UINT_32 yIdx = Log2(microBlockDim.h); UINT_32 zIdx = Log2(microBlockDim.d); pixelBit = pEquation->addr; - static const UINT_32 lowBits = 10; + const UINT_32 lowBits = 10; ADDR_ASSERT(pEquation->addr[lowBits - 1].valid == 1); ADDR_ASSERT(pEquation->addr[lowBits].valid == 0); for (UINT_32 i = lowBits; i < blockSizeLog2; i++) { - if (((i - lowBits) % 3) == 0) + if ((i % 3) == 0) { pixelBit[i] = x[xIdx++]; } - else if (((i - lowBits) % 3) == 1) + else if ((i % 3) == 1) { pixelBit[i] = z[zIdx++]; } @@ -2528,11 +2628,11 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThickEquation( for (UINT_32 i = blockSizeLog2; i < maxXorBits; i++) { - if (((i - lowBits) % 3) == 0) + if ((i % 3) == 0) { xorExtra[i - blockSizeLog2] = x[xIdx++]; } - else if (((i - lowBits) % 3) == 1) + else if ((i % 3) == 1) { xorExtra[i - blockSizeLog2] = z[zIdx++]; } @@ -2541,47 +2641,43 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThickEquation( xorExtra[i - blockSizeLog2] = y[yIdx++]; } } - } - if ((ret == ADDR_OK) && IsXor(swMode)) - { - // Fill XOR bits - UINT_32 pipeStart = m_pipeInterleaveLog2; - UINT_32 pipeXorBits = GetPipeXorBits(blockSizeLog2); - for (UINT_32 i = 0; i < pipeXorBits; i++) + if (IsXor(swMode)) { - UINT_32 xor1BitPos = pipeStart + (3 * pipeXorBits) - 1 - (2 * i); - ADDR_CHANNEL_SETTING* pXor1Src = - (xor1BitPos < blockSizeLog2) ? - &pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2]; + // Fill XOR bits + UINT_32 pipeStart = m_pipeInterleaveLog2; + UINT_32 pipeXorBits = GetPipeXorBits(blockSizeLog2); + for (UINT_32 i = 0; i < pipeXorBits; i++) + { + UINT_32 xor1BitPos = pipeStart + (3 * pipeXorBits) - 1 - (2 * i); + ADDR_CHANNEL_SETTING* pXor1Src = (xor1BitPos < blockSizeLog2) ? + &pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2]; - InitChannel(&pEquation->xor1[pipeStart + i], pXor1Src); + InitChannel(&pEquation->xor1[pipeStart + i], pXor1Src); - UINT_32 xor2BitPos = pipeStart + (3 * pipeXorBits) - 2 - (2 * i); - ADDR_CHANNEL_SETTING* pXor2Src = - (xor2BitPos < blockSizeLog2) ? - &pEquation->addr[xor2BitPos] : &xorExtra[xor2BitPos - blockSizeLog2]; + UINT_32 xor2BitPos = pipeStart + (3 * pipeXorBits) - 2 - (2 * i); + ADDR_CHANNEL_SETTING* pXor2Src = (xor2BitPos < blockSizeLog2) ? + &pEquation->addr[xor2BitPos] : &xorExtra[xor2BitPos - blockSizeLog2]; - InitChannel(&pEquation->xor2[pipeStart + i], pXor2Src); - } + InitChannel(&pEquation->xor2[pipeStart + i], pXor2Src); + } - UINT_32 bankStart = pipeStart + pipeXorBits; - UINT_32 bankXorBits = GetBankXorBits(blockSizeLog2); - for (UINT_32 i = 0; i < bankXorBits; i++) - { - UINT_32 xor1BitPos = bankStart + (3 * bankXorBits) - 1 - (2 * i); - ADDR_CHANNEL_SETTING* pXor1Src = - (xor1BitPos < blockSizeLog2) ? - &pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2]; + UINT_32 bankStart = pipeStart + pipeXorBits; + UINT_32 bankXorBits = GetBankXorBits(blockSizeLog2); + for (UINT_32 i = 0; i < bankXorBits; i++) + { + UINT_32 xor1BitPos = bankStart + (3 * bankXorBits) - 1 - (2 * i); + ADDR_CHANNEL_SETTING* pXor1Src = (xor1BitPos < blockSizeLog2) ? + &pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2]; - InitChannel(&pEquation->xor1[bankStart + i], pXor1Src); + InitChannel(&pEquation->xor1[bankStart + i], pXor1Src); - UINT_32 xor2BitPos = bankStart + (3 * bankXorBits) - 2 - (2 * i); - ADDR_CHANNEL_SETTING* pXor2Src = - (xor2BitPos < blockSizeLog2) ? - &pEquation->addr[xor2BitPos] : &xorExtra[xor2BitPos - blockSizeLog2]; + UINT_32 xor2BitPos = bankStart + (3 * bankXorBits) - 2 - (2 * i); + ADDR_CHANNEL_SETTING* pXor2Src = (xor2BitPos < blockSizeLog2) ? + &pEquation->addr[xor2BitPos] : &xorExtra[xor2BitPos - blockSizeLog2]; - InitChannel(&pEquation->xor2[bankStart + i], pXor2Src); + InitChannel(&pEquation->xor2[bankStart + i], pXor2Src); + } } pEquation->numBits = blockSizeLog2; @@ -2591,17 +2687,18 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThickEquation( } /** -**************************************************************************************************** -* Gfx9Lib::HwlIsValidDisplaySwizzleMode +************************************************************************************************************************ +* Gfx9Lib::IsValidDisplaySwizzleMode * * @brief * Check if a swizzle mode is supported by display engine * * @return * TRUE is swizzle mode is supported by display engine -**************************************************************************************************** +************************************************************************************************************************ */ -BOOL_32 Gfx9Lib::HwlIsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const +BOOL_32 Gfx9Lib::IsValidDisplaySwizzleMode( + const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const { BOOL_32 support = FALSE; @@ -2645,5 +2742,1762 @@ BOOL_32 Gfx9Lib::HwlIsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_I return support; } +/** +************************************************************************************************************************ +* Gfx9Lib::HwlComputePipeBankXor +* +* @brief +* Generate a PipeBankXor value to be ORed into bits above pipeInterleaveBits of address +* +* @return +* PipeBankXor value +************************************************************************************************************************ +*/ +ADDR_E_RETURNCODE Gfx9Lib::HwlComputePipeBankXor( + const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn, + ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut) const +{ + UINT_32 macroBlockBits = GetBlockSizeLog2(pIn->swizzleMode); + UINT_32 pipeBits = GetPipeXorBits(macroBlockBits); + UINT_32 bankBits = GetBankXorBits(macroBlockBits); + + UINT_32 pipeXor = 0; + UINT_32 bankXor = 0; + + const UINT_32 bankMask = (1 << bankBits) - 1; + const UINT_32 index = pIn->surfIndex & bankMask; + + const UINT_32 bpp = pIn->flags.fmask ? + GetFmaskBpp(pIn->numSamples, pIn->numFrags) : GetElemLib()->GetBitsPerPixel(pIn->format); + if (bankBits == 4) + { + static const UINT_32 BankXorSmallBpp[] = {0, 7, 4, 3, 8, 15, 12, 11, 1, 6, 5, 2, 9, 14, 13, 10}; + static const UINT_32 BankXorLargeBpp[] = {0, 7, 8, 15, 4, 3, 12, 11, 1, 6, 9, 14, 5, 2, 13, 10}; + + bankXor = (bpp <= 32) ? BankXorSmallBpp[index] : BankXorLargeBpp[index]; + } + else if (bankBits > 0) + { + UINT_32 bankIncrease = (1 << (bankBits - 1)) - 1; + bankIncrease = (bankIncrease == 0) ? 1 : bankIncrease; + bankXor = (index * bankIncrease) & bankMask; + } + + pOut->pipeBankXor = (bankXor << pipeBits) | pipeXor; + + return ADDR_OK; +} + +/** +************************************************************************************************************************ +* Gfx9Lib::HwlComputeSlicePipeBankXor +* +* @brief +* Generate slice PipeBankXor value based on base PipeBankXor value and slice id +* +* @return +* PipeBankXor value +************************************************************************************************************************ +*/ +ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSlicePipeBankXor( + const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn, + ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut) const +{ + UINT_32 macroBlockBits = GetBlockSizeLog2(pIn->swizzleMode); + UINT_32 pipeBits = GetPipeXorBits(macroBlockBits); + UINT_32 bankBits = GetBankXorBits(macroBlockBits); + + UINT_32 pipeXor = ReverseBitVector(pIn->slice, pipeBits); + UINT_32 bankXor = ReverseBitVector(pIn->slice >> pipeBits, bankBits); + + pOut->pipeBankXor = pIn->basePipeBankXor ^ (pipeXor | (bankXor << pipeBits)); + + return ADDR_OK; +} + +/** +************************************************************************************************************************ +* Gfx9Lib::HwlComputeSubResourceOffsetForSwizzlePattern +* +* @brief +* Compute sub resource offset to support swizzle pattern +* +* @return +* Offset +************************************************************************************************************************ +*/ +ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSubResourceOffsetForSwizzlePattern( + const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn, + ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut) const +{ + ADDR_ASSERT(IsThin(pIn->resourceType, pIn->swizzleMode)); + + UINT_32 macroBlockBits = GetBlockSizeLog2(pIn->swizzleMode); + UINT_32 pipeBits = GetPipeXorBits(macroBlockBits); + UINT_32 bankBits = GetBankXorBits(macroBlockBits); + UINT_32 pipeXor = ReverseBitVector(pIn->slice, pipeBits); + UINT_32 bankXor = ReverseBitVector(pIn->slice >> pipeBits, bankBits); + UINT_32 pipeBankXor = ((pipeXor | (bankXor << pipeBits)) ^ (pIn->pipeBankXor)) << m_pipeInterleaveLog2; + + pOut->offset = pIn->slice * pIn->sliceSize + + pIn->macroBlockOffset + + (pIn->mipTailOffset ^ pipeBankXor) - + static_cast(pipeBankXor); + return ADDR_OK; +} + +/** +************************************************************************************************************************ +* Gfx9Lib::HwlComputeSurfaceInfoSanityCheck +* +* @brief +* Compute surface info sanity check +* +* @return +* Offset +************************************************************************************************************************ +*/ +ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceInfoSanityCheck( + const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const +{ + BOOL_32 invalid = FALSE; + + if ((pIn->bpp > 128) || (pIn->width == 0) || (pIn->numFrags > 8) || (pIn->numSamples > 16)) + { + invalid = TRUE; + } + else if ((pIn->swizzleMode >= ADDR_SW_MAX_TYPE) || + (pIn->resourceType >= ADDR_RSRC_MAX_TYPE)) + { + invalid = TRUE; + } + + 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); + 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) + { + if ((pIn->numFrags > 1) && + (GetBlockSize(swizzle) < (m_pipeInterleaveBytes * pIn->numFrags))) + { + // MSAA surface must have blk_bytes/pipe_interleave >= num_samples + invalid = TRUE; + } + } + + if (invalid == FALSE) + { + switch (rsrcType) + { + 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; + } + } + + if (invalid == FALSE) + { + if (display) + { + invalid = (IsValidDisplaySwizzleMode(pIn) == FALSE); + } + } + + if (invalid == FALSE) + { + if (linear) + { + invalid = ((ADDR_RSRC_TEX_1D != rsrcType) && prt) || + zbuffer || msaa || (pIn->bpp == 0) || ((pIn->bpp % 8) != 0); + } + else + { + if (blk256B || blkVar || isNonPrtXor) + { + invalid = prt; + if (blk256B) + { + invalid = invalid || zbuffer || tex3d || mipmap || msaa; + } + } + + if (invalid == FALSE) + { + if (IsZOrderSwizzle(swizzle)) + { + invalid = color && msaa; + } + else if (IsStandardSwizzle(rsrcType, swizzle)) + { + invalid = zbuffer; + } + else if (IsDisplaySwizzle(rsrcType, swizzle)) + { + invalid = zbuffer; + } + else if (IsRotateSwizzle(swizzle)) + { + invalid = zbuffer || (pIn->bpp > 64) || tex3d; + } + else + { + ADDR_ASSERT(!"invalid swizzle mode"); + invalid = TRUE; + } + } + } + } + + ADDR_ASSERT(invalid == FALSE); + + return invalid ? ADDR_INVALIDPARAMS : ADDR_OK; +} + +/** +************************************************************************************************************************ +* Gfx9Lib::HwlGetPreferredSurfaceSetting +* +* @brief +* Internal function to get suggested surface information for cliet to use +* +* @return +* ADDR_E_RETURNCODE +************************************************************************************************************************ +*/ +ADDR_E_RETURNCODE Gfx9Lib::HwlGetPreferredSurfaceSetting( + const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn, + ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT* pOut) const +{ + // Macro define resource block type + enum AddrBlockType + { + AddrBlockMicro = 0, // Resource uses 256B block + AddrBlock4KB = 1, // Resource uses 4KB block + AddrBlock64KB = 2, // Resource uses 64KB block + AddrBlockVar = 3, // Resource uses var blcok + AddrBlockLinear = 4, // Resource uses linear swizzle mode + + AddrBlockMaxTiledType = AddrBlock64KB + 1, + }; + + enum AddrBlockSet + { + AddrBlockSetMicro = 1 << AddrBlockMicro, + AddrBlockSetMacro4KB = 1 << AddrBlock4KB, + AddrBlockSetMacro64KB = 1 << AddrBlock64KB, + AddrBlockSetVar = 1 << AddrBlockVar, + AddrBlockSetLinear = 1 << AddrBlockLinear, + + AddrBlockSetMacro = AddrBlockSetMacro4KB | AddrBlockSetMacro64KB, + }; + + ADDR_E_RETURNCODE returnCode = ADDR_OK; + ElemLib* pElemLib = GetElemLib(); + + // Set format to INVALID will skip this conversion + UINT_32 expandX = 1; + UINT_32 expandY = 1; + UINT_32 bpp = pIn->bpp; + UINT_32 width = pIn->width; + UINT_32 height = pIn->height; + + if (pIn->format != ADDR_FMT_INVALID) + { + // Don't care for this case + ElemMode elemMode = ADDR_UNCOMPRESSED; + + // Get compression/expansion factors and element mode which indicates compression/expansion + bpp = pElemLib->GetBitsPerPixel(pIn->format, + &elemMode, + &expandX, + &expandY); + + UINT_32 basePitch = 0; + GetElemLib()->AdjustSurfaceInfo(elemMode, + expandX, + expandY, + &bpp, + &basePitch, + &width, + &height); + } + + UINT_32 numSamples = Max(pIn->numSamples, 1u); + UINT_32 numFrags = (pIn->numFrags == 0) ? numSamples : pIn->numFrags; + UINT_32 slice = Max(pIn->numSlices, 1u); + UINT_32 numMipLevels = Max(pIn->numMipLevels, 1u); + UINT_32 minSizeAlign = NextPow2(pIn->minSizeAlign); + + if (pIn->flags.fmask) + { + bpp = GetFmaskBpp(numSamples, numFrags); + numFrags = 1; + numSamples = 1; + pOut->resourceType = ADDR_RSRC_TEX_2D; + } + else + { + // The output may get changed for volume(3D) texture resource in future + pOut->resourceType = pIn->resourceType; + } + + ADDR_ASSERT(bpp >= 8u); + UINT_64 minSizeAlignInElement = Max(minSizeAlign / (bpp >> 3), 1u); + + if (IsTex1d(pOut->resourceType)) + { + pOut->swizzleMode = ADDR_SW_LINEAR; + pOut->validBlockSet.value = AddrBlockSetLinear; + pOut->canXor = FALSE; + } + else + { + ADDR2_BLOCK_SET blockSet; + blockSet.value = 0; + + AddrSwType swType = ADDR_SW_S; + + // prt Xor and non-xor will have less height align requirement for stereo surface + BOOL_32 prtXor = (pIn->flags.prt || pIn->flags.qbStereo) && (pIn->noXor == FALSE); + BOOL_32 displayResource = FALSE; + + pOut->canXor = (pIn->flags.prt == FALSE) && (pIn->noXor == FALSE); + + // Filter out improper swType and blockSet by HW restriction + if (pIn->flags.fmask || pIn->flags.depth || pIn->flags.stencil) + { + ADDR_ASSERT(IsTex2d(pOut->resourceType)); + blockSet.value = AddrBlockSetMacro; + swType = ADDR_SW_Z; + + if (pIn->flags.depth && pIn->flags.texture) + { + if (((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. + pOut->canXor = FALSE; + prtXor = FALSE; + } + } + } + else if (ElemLib::IsBlockCompressed(pIn->format)) + { + // block compressed formats (BCx, ASTC, ETC2) must be either S or D modes. Not sure + // under what circumstances "_D" would be appropriate as these formats are not + // displayable. + blockSet.value = AddrBlockSetMacro; + + // This isn't to be used as texture and caller doesn't allow macro tiled. + if ((pIn->flags.texture == FALSE) && + (pIn->forbiddenBlock.macro4KB && pIn->forbiddenBlock.macro64KB)) + { + blockSet.value |= AddrBlockSetLinear; + } + swType = ADDR_SW_D; + } + else if (ElemLib::IsMacroPixelPacked(pIn->format)) + { + // macro pixel packed formats (BG_RG, GB_GR) does not support the Z modes. Its not + // clear under what circumstances the D or R modes would be appropriate since + // these formats are not displayable. + blockSet.value = AddrBlockSetLinear | AddrBlockSetMacro; + swType = ADDR_SW_S; + } + else if (IsTex3d(pOut->resourceType)) + { + blockSet.value = AddrBlockSetLinear | AddrBlockSetMacro; + + if (pIn->flags.prt) + { + // PRT cannot use SW_D which gives an unexpected block dimension + swType = ADDR_SW_Z; + } + else if ((numMipLevels > 1) && (slice >= width) && (slice >= height)) + { + // 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 + swType = ADDR_SW_Z; + } + else if (pIn->flags.color) + { + swType = ADDR_SW_D; + } + else + { + swType = ADDR_SW_Z; + } + } + else + { + swType = ((pIn->flags.display == TRUE) || + (pIn->flags.overlay == TRUE) || + (pIn->bpp == 128)) ? ADDR_SW_D : ADDR_SW_S; + + if (numMipLevels > 1) + { + ADDR_ASSERT(numFrags == 1); + blockSet.value = AddrBlockSetLinear | AddrBlockSetMacro; + } + else if ((numFrags > 1) || (numSamples > 1)) + { + ADDR_ASSERT(IsTex2d(pOut->resourceType)); + blockSet.value = AddrBlockSetMacro; + } + else + { + ADDR_ASSERT(IsTex2d(pOut->resourceType)); + blockSet.value = AddrBlockSetLinear | AddrBlockSetMicro | AddrBlockSetMacro; + + displayResource = pIn->flags.rotated || pIn->flags.display; + + if (displayResource) + { + swType = pIn->flags.rotated ? ADDR_SW_R : ADDR_SW_D; + + if (pIn->bpp > 64) + { + blockSet.value = 0; + } + else if (m_settings.isDce12) + { + if (pIn->bpp != 32) + { + blockSet.micro = FALSE; + } + + // DCE12 does not support display surface to be _T swizzle mode + prtXor = FALSE; + } + else + { + ADDR_NOT_IMPLEMENTED(); + returnCode = ADDR_NOTSUPPORTED; + } + } + } + } + + if ((numFrags > 1) && + (GetBlockSize(ADDR_SW_4KB) < (m_pipeInterleaveBytes * numFrags))) + { + // MSAA surface must have blk_bytes/pipe_interleave >= num_samples + blockSet.macro4KB = FALSE; + } + + if (pIn->flags.prt) + { + blockSet.value &= AddrBlockSetMacro64KB; + } + + // Apply customized forbidden setting + blockSet.value &= ~pIn->forbiddenBlock.value; + + if (pIn->maxAlign > 0) + { + if (pIn->maxAlign < GetBlockSize(ADDR_SW_64KB)) + { + blockSet.macro64KB = FALSE; + } + + if (pIn->maxAlign < GetBlockSize(ADDR_SW_4KB)) + { + blockSet.macro4KB = FALSE; + } + + if (pIn->maxAlign < GetBlockSize(ADDR_SW_256B)) + { + blockSet.micro = FALSE; + } + } + + Dim3d blkAlign[AddrBlockMaxTiledType] = {{0}, {0}, {0}}; + Dim3d paddedDim[AddrBlockMaxTiledType] = {{0}, {0}, {0}}; + UINT_64 padSize[AddrBlockMaxTiledType] = {0}; + + if (blockSet.micro) + { + returnCode = ComputeBlockDimensionForSurf(&blkAlign[AddrBlockMicro].w, + &blkAlign[AddrBlockMicro].h, + &blkAlign[AddrBlockMicro].d, + bpp, + numFrags, + pOut->resourceType, + ADDR_SW_256B); + + if (returnCode == ADDR_OK) + { + if (displayResource) + { + blkAlign[AddrBlockMicro].w = PowTwoAlign(blkAlign[AddrBlockMicro].w, 32); + } + else if ((blkAlign[AddrBlockMicro].w >= width) && (blkAlign[AddrBlockMicro].h >= height) && + (minSizeAlign <= GetBlockSize(ADDR_SW_256B))) + { + // If one 256B block can contain the surface, don't bother bigger block type + blockSet.macro4KB = FALSE; + blockSet.macro64KB = FALSE; + blockSet.var = FALSE; + } + + padSize[AddrBlockMicro] = ComputePadSize(&blkAlign[AddrBlockMicro], width, height, + slice, &paddedDim[AddrBlockMicro]); + } + } + + if ((returnCode == ADDR_OK) && blockSet.macro4KB) + { + returnCode = ComputeBlockDimensionForSurf(&blkAlign[AddrBlock4KB].w, + &blkAlign[AddrBlock4KB].h, + &blkAlign[AddrBlock4KB].d, + bpp, + numFrags, + pOut->resourceType, + ADDR_SW_4KB); + + if (returnCode == ADDR_OK) + { + if (displayResource) + { + blkAlign[AddrBlock4KB].w = PowTwoAlign(blkAlign[AddrBlock4KB].w, 32); + } + + padSize[AddrBlock4KB] = ComputePadSize(&blkAlign[AddrBlock4KB], width, height, + slice, &paddedDim[AddrBlock4KB]); + + ADDR_ASSERT(padSize[AddrBlock4KB] >= padSize[AddrBlockMicro]); + } + } + + if ((returnCode == ADDR_OK) && blockSet.macro64KB) + { + returnCode = ComputeBlockDimensionForSurf(&blkAlign[AddrBlock64KB].w, + &blkAlign[AddrBlock64KB].h, + &blkAlign[AddrBlock64KB].d, + bpp, + numFrags, + pOut->resourceType, + ADDR_SW_64KB); + + if (returnCode == ADDR_OK) + { + if (displayResource) + { + blkAlign[AddrBlock64KB].w = PowTwoAlign(blkAlign[AddrBlock64KB].w, 32); + } + + padSize[AddrBlock64KB] = ComputePadSize(&blkAlign[AddrBlock64KB], width, height, + slice, &paddedDim[AddrBlock64KB]); + + ADDR_ASSERT(padSize[AddrBlock64KB] >= padSize[AddrBlock4KB]); + ADDR_ASSERT(padSize[AddrBlock64KB] >= padSize[AddrBlockMicro]); + } + } + + if (returnCode == ADDR_OK) + { + for (UINT_32 i = AddrBlockMicro; i < AddrBlockMaxTiledType; i++) + { + padSize[i] = PowTwoAlign(padSize[i], minSizeAlignInElement); + } + + // Use minimum block type which meets all conditions above if flag minimizeAlign was set + if (pIn->flags.minimizeAlign) + { + // If padded size of 64KB block is larger than padded size of 256B block or 4KB + // block, filter out 64KB block from candidate list + if (blockSet.macro64KB && + ((blockSet.micro && (padSize[AddrBlockMicro] < padSize[AddrBlock64KB])) || + (blockSet.macro4KB && (padSize[AddrBlock4KB] < padSize[AddrBlock64KB])))) + { + blockSet.macro64KB = FALSE; + } + + // If padded size of 4KB block is larger than padded size of 256B block, + // filter out 4KB block from candidate list + if (blockSet.macro4KB && + blockSet.micro && + (padSize[AddrBlockMicro] < padSize[AddrBlock4KB])) + { + blockSet.macro4KB = FALSE; + } + } + // Filter out 64KB/4KB block if a smaller block type has 2/3 or less memory footprint + else if (pIn->flags.opt4space) + { + UINT_64 threshold = blockSet.micro ? padSize[AddrBlockMicro] : + (blockSet.macro4KB ? padSize[AddrBlock4KB] : padSize[AddrBlock64KB]); + + threshold += threshold >> 1; + + if (blockSet.macro64KB && (padSize[AddrBlock64KB] > threshold)) + { + blockSet.macro64KB = FALSE; + } + + if (blockSet.macro4KB && (padSize[AddrBlock4KB] > threshold)) + { + blockSet.macro4KB = FALSE; + } + } + else + { + if (blockSet.macro64KB && + (padSize[AddrBlock64KB] >= static_cast(width) * height * slice * 2) && + ((blockSet.value & ~AddrBlockSetMacro64KB) != 0)) + { + // If 64KB block waste more than half memory on padding, filter it out from + // candidate list when it is not the only choice left + blockSet.macro64KB = FALSE; + } + } + + if (blockSet.value == 0) + { + // Bad things happen, client will not get any useful information from AddrLib. + // Maybe we should fill in some output earlier instead of outputing nothing? + ADDR_ASSERT_ALWAYS(); + returnCode = ADDR_INVALIDPARAMS; + } + else + { + pOut->validBlockSet = blockSet; + pOut->canXor = pOut->canXor && + (blockSet.macro4KB || blockSet.macro64KB || blockSet.var); + + if (blockSet.macro64KB || blockSet.macro4KB) + { + if (swType == ADDR_SW_Z) + { + pOut->swizzleMode = blockSet.macro64KB ? ADDR_SW_64KB_Z : ADDR_SW_4KB_Z; + } + else if (swType == ADDR_SW_S) + { + pOut->swizzleMode = blockSet.macro64KB ? ADDR_SW_64KB_S : ADDR_SW_4KB_S; + } + else if (swType == ADDR_SW_D) + { + pOut->swizzleMode = blockSet.macro64KB ? ADDR_SW_64KB_D : ADDR_SW_4KB_D; + } + else + { + ADDR_ASSERT(swType == ADDR_SW_R); + pOut->swizzleMode = blockSet.macro64KB ? ADDR_SW_64KB_R : ADDR_SW_4KB_R; + } + + if (prtXor && blockSet.macro64KB) + { + // Client wants PRTXOR, give back _T swizzle mode if 64KB is available + const UINT_32 prtGap = ADDR_SW_64KB_Z_T - ADDR_SW_64KB_Z; + pOut->swizzleMode = static_cast(pOut->swizzleMode + prtGap); + } + else if (pOut->canXor) + { + // Client wants XOR and this is allowed, return XOR version swizzle mode + const UINT_32 xorGap = ADDR_SW_4KB_Z_X - ADDR_SW_4KB_Z; + pOut->swizzleMode = static_cast(pOut->swizzleMode + xorGap); + } + } + else if (blockSet.micro) + { + if (swType == ADDR_SW_S) + { + pOut->swizzleMode = ADDR_SW_256B_S; + } + else if (swType == ADDR_SW_D) + { + pOut->swizzleMode = ADDR_SW_256B_D; + } + else + { + ADDR_ASSERT(swType == ADDR_SW_R); + pOut->swizzleMode = ADDR_SW_256B_R; + } + } + else if (blockSet.linear) + { + // Fall into this branch doesn't mean linear is suitable, only no other choices! + pOut->swizzleMode = ADDR_SW_LINEAR; + } + else + { + ADDR_ASSERT(blockSet.var); + + // Designer consider VAR swizzle mode is usless for most cases + ADDR_UNHANDLED_CASE(); + + returnCode = ADDR_NOTSUPPORTED; + } + +#if DEBUG + // Post sanity check, at least AddrLib should accept the output generated by its own + if (pOut->swizzleMode != ADDR_SW_LINEAR) + { + ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0}; + localIn.flags = pIn->flags; + localIn.swizzleMode = pOut->swizzleMode; + localIn.resourceType = pOut->resourceType; + localIn.format = pIn->format; + localIn.bpp = bpp; + localIn.width = width; + localIn.height = height; + localIn.numSlices = slice; + localIn.numMipLevels = numMipLevels; + localIn.numSamples = numSamples; + localIn.numFrags = numFrags; + + HwlComputeSurfaceInfoSanityCheck(&localIn); + + // TODO : check all valid block type available in validBlockSet? + } +#endif + } + } + } + + return returnCode; +} + +/** +************************************************************************************************************************ +* Gfx9Lib::ComputeStereoInfo +* +* @brief +* Compute height alignment and right eye pipeBankXor for stereo surface +* +* @return +* Error code +* +************************************************************************************************************************ +*/ +ADDR_E_RETURNCODE Gfx9Lib::ComputeStereoInfo( + const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, + ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut, + UINT_32* pHeightAlign + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + UINT_32 eqIndex = HwlGetEquationIndex(pIn, pOut); + + if (eqIndex < m_numEquations) + { + if (IsXor(pIn->swizzleMode)) + { + const UINT_32 blkSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode); + const UINT_32 numPipeBits = GetPipeXorBits(blkSizeLog2); + const UINT_32 numBankBits = GetBankXorBits(blkSizeLog2); + const UINT_32 bppLog2 = Log2(pIn->bpp >> 3); + const UINT_32 maxYCoordBlock256 = Log2(Block256_2d[bppLog2].h) - 1; + const ADDR_EQUATION *pEqToCheck = &m_equationTable[eqIndex]; + + ADDR_ASSERT(maxYCoordBlock256 == + GetMaxValidChannelIndex(&pEqToCheck->addr[0], GetBlockSizeLog2(ADDR_SW_256B), 1)); + + const UINT_32 maxYCoordInBaseEquation = + (blkSizeLog2 - GetBlockSizeLog2(ADDR_SW_256B)) / 2 + maxYCoordBlock256; + + ADDR_ASSERT(maxYCoordInBaseEquation == + GetMaxValidChannelIndex(&pEqToCheck->addr[0], blkSizeLog2, 1)); + + const UINT_32 maxYCoordInPipeXor = (numPipeBits == 0) ? 0 : maxYCoordBlock256 + numPipeBits; + + ADDR_ASSERT(maxYCoordInPipeXor == + GetMaxValidChannelIndex(&pEqToCheck->xor1[m_pipeInterleaveLog2], numPipeBits, 1)); + + const UINT_32 maxYCoordInBankXor = (numBankBits == 0) ? + 0 : maxYCoordBlock256 + (numPipeBits + 1) / 2 + numBankBits; + + ADDR_ASSERT(maxYCoordInBankXor == + GetMaxValidChannelIndex(&pEqToCheck->xor1[m_pipeInterleaveLog2 + numPipeBits], numBankBits, 1)); + + const UINT_32 maxYCoordInPipeBankXor = Max(maxYCoordInPipeXor, maxYCoordInBankXor); + + if (maxYCoordInPipeBankXor > maxYCoordInBaseEquation) + { + *pHeightAlign = 1u << maxYCoordInPipeBankXor; + + if (pOut->pStereoInfo != NULL) + { + pOut->pStereoInfo->rightSwizzle = 0; + + if ((PowTwoAlign(pIn->height, *pHeightAlign) % (*pHeightAlign * 2)) != 0) + { + if (maxYCoordInPipeXor == maxYCoordInPipeBankXor) + { + pOut->pStereoInfo->rightSwizzle |= (1u << 1); + } + + if (maxYCoordInBankXor == maxYCoordInPipeBankXor) + { + pOut->pStereoInfo->rightSwizzle |= + 1u << ((numPipeBits % 2) ? numPipeBits : numPipeBits + 1); + } + + ADDR_ASSERT(pOut->pStereoInfo->rightSwizzle == + GetCoordActiveMask(&pEqToCheck->xor1[m_pipeInterleaveLog2], + numPipeBits + numBankBits, 1, maxYCoordInPipeBankXor)); + } + } + } + } + } + else + { + ADDR_ASSERT_ALWAYS(); + returnCode = ADDR_ERROR; + } + + return returnCode; +} + +/** +************************************************************************************************************************ +* Gfx9Lib::HwlComputeSurfaceInfoTiled +* +* @brief +* Internal function to calculate alignment for tiled surface +* +* @return +* ADDR_E_RETURNCODE +************************************************************************************************************************ +*/ +ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceInfoTiled( + const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure + ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ComputeBlockDimensionForSurf(&pOut->blockWidth, + &pOut->blockHeight, + &pOut->blockSlices, + pIn->bpp, + pIn->numFrags, + pIn->resourceType, + pIn->swizzleMode); + + if (returnCode == ADDR_OK) + { + UINT_32 pitchAlignInElement = pOut->blockWidth; + + if ((IsTex2d(pIn->resourceType) == TRUE) && + (pIn->flags.display || pIn->flags.rotated) && + (pIn->numMipLevels <= 1) && + (pIn->numSamples <= 1) && + (pIn->numFrags <= 1)) + { + // Display engine needs pitch align to be at least 32 pixels. + pitchAlignInElement = PowTwoAlign(pitchAlignInElement, 32); + } + + pOut->pitch = PowTwoAlign(pIn->width, pitchAlignInElement); + + if ((pIn->numMipLevels <= 1) && (pIn->pitchInElement > 0)) + { + if ((pIn->pitchInElement % pitchAlignInElement) != 0) + { + returnCode = ADDR_INVALIDPARAMS; + } + else if (pIn->pitchInElement < pOut->pitch) + { + returnCode = ADDR_INVALIDPARAMS; + } + else + { + pOut->pitch = pIn->pitchInElement; + } + } + + UINT_32 heightAlign = 0; + + if (pIn->flags.qbStereo) + { + returnCode = ComputeStereoInfo(pIn, pOut, &heightAlign); + } + + if (returnCode == ADDR_OK) + { + pOut->height = PowTwoAlign(pIn->height, pOut->blockHeight); + + if (heightAlign > 1) + { + pOut->height = PowTwoAlign(pOut->height, heightAlign); + } + + pOut->numSlices = PowTwoAlign(pIn->numSlices, pOut->blockSlices); + + pOut->epitchIsHeight = FALSE; + pOut->mipChainInTail = FALSE; + + pOut->mipChainPitch = pOut->pitch; + pOut->mipChainHeight = pOut->height; + pOut->mipChainSlice = pOut->numSlices; + + if (pIn->numMipLevels > 1) + { + UINT_32 numMipLevel; + ADDR2_MIP_INFO *pMipInfo; + ADDR2_MIP_INFO mipInfo[4]; + + if (pOut->pMipInfo != NULL) + { + pMipInfo = pOut->pMipInfo; + numMipLevel = pIn->numMipLevels; + } + else + { + pMipInfo = mipInfo; + numMipLevel = Min(pIn->numMipLevels, 4u); + } + + UINT_32 endingMip = GetMipChainInfo(pIn->resourceType, + pIn->swizzleMode, + pIn->bpp, + pIn->width, + pIn->height, + pIn->numSlices, + pOut->blockWidth, + pOut->blockHeight, + pOut->blockSlices, + numMipLevel, + pMipInfo); + + if (endingMip == 0) + { + pOut->epitchIsHeight = TRUE; + pOut->pitch = pMipInfo[0].pitch; + pOut->height = pMipInfo[0].height; + pOut->numSlices = pMipInfo[0].depth; + pOut->mipChainInTail = TRUE; + } + else + { + UINT_32 mip0WidthInBlk = pOut->pitch / pOut->blockWidth; + UINT_32 mip0HeightInBlk = pOut->height / pOut->blockHeight; + + AddrMajorMode majorMode = GetMajorMode(pIn->resourceType, + pIn->swizzleMode, + mip0WidthInBlk, + mip0HeightInBlk, + pOut->numSlices / pOut->blockSlices); + if (majorMode == ADDR_MAJOR_Y) + { + UINT_32 mip1WidthInBlk = RoundHalf(mip0WidthInBlk); + + if ((mip1WidthInBlk == 1) && (endingMip > 2)) + { + mip1WidthInBlk++; + } + + pOut->mipChainPitch += (mip1WidthInBlk * pOut->blockWidth); + + pOut->epitchIsHeight = FALSE; + } + else + { + UINT_32 mip1HeightInBlk = RoundHalf(mip0HeightInBlk); + + if ((mip1HeightInBlk == 1) && (endingMip > 2)) + { + mip1HeightInBlk++; + } + + pOut->mipChainHeight += (mip1HeightInBlk * pOut->blockHeight); + + pOut->epitchIsHeight = TRUE; + } + } + + if (pOut->pMipInfo != NULL) + { + UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3); + + for (UINT_32 i = 0; i < pIn->numMipLevels; i++) + { + Dim3d mipStartPos = {0}; + UINT_32 mipTailOffsetInBytes = 0; + + mipStartPos = GetMipStartPos(pIn->resourceType, + pIn->swizzleMode, + pOut->pitch, + pOut->height, + pOut->numSlices, + pOut->blockWidth, + pOut->blockHeight, + pOut->blockSlices, + i, + elementBytesLog2, + &mipTailOffsetInBytes); + + UINT_32 pitchInBlock = + pOut->mipChainPitch / pOut->blockWidth; + UINT_32 sliceInBlock = + (pOut->mipChainHeight / pOut->blockHeight) * pitchInBlock; + UINT_64 blockIndex = + mipStartPos.d * sliceInBlock + mipStartPos.h * pitchInBlock + mipStartPos.w; + UINT_64 macroBlockOffset = + blockIndex << GetBlockSizeLog2(pIn->swizzleMode); + + pMipInfo[i].macroBlockOffset = macroBlockOffset; + pMipInfo[i].mipTailOffset = mipTailOffsetInBytes; + } + } + } + else if (pOut->pMipInfo != NULL) + { + pOut->pMipInfo[0].pitch = pOut->pitch; + pOut->pMipInfo[0].height = pOut->height; + pOut->pMipInfo[0].depth = IsTex3d(pIn->resourceType)? pOut->numSlices : 1; + pOut->pMipInfo[0].offset = 0; + } + + pOut->sliceSize = static_cast(pOut->mipChainPitch) * pOut->mipChainHeight * + (pIn->bpp >> 3) * pIn->numFrags; + pOut->surfSize = pOut->sliceSize * pOut->mipChainSlice; + pOut->baseAlign = HwlComputeSurfaceBaseAlign(pIn->swizzleMode); + + if (pIn->flags.prt) + { + pOut->baseAlign = Max(pOut->baseAlign, PrtAlignment); + } + } + } + + return returnCode; +} + +/** +************************************************************************************************************************ +* Gfx9Lib::GetMipChainInfo +* +* @brief +* Internal function to get out information about mip chain +* +* @return +* Smaller value between Id of first mip fitted in mip tail and max Id of mip being created +************************************************************************************************************************ +*/ +UINT_32 Gfx9Lib::GetMipChainInfo( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode, + UINT_32 bpp, + UINT_32 mip0Width, + UINT_32 mip0Height, + UINT_32 mip0Depth, + UINT_32 blockWidth, + UINT_32 blockHeight, + UINT_32 blockDepth, + UINT_32 numMipLevel, + ADDR2_MIP_INFO* pMipInfo) const +{ + const Dim3d tailMaxDim = + GetMipTailDim(resourceType, swizzleMode, blockWidth, blockHeight, blockDepth); + + UINT_32 mipPitch = mip0Width; + UINT_32 mipHeight = mip0Height; + UINT_32 mipDepth = IsTex3d(resourceType) ? mip0Depth : 1; + UINT_32 offset = 0; + UINT_32 endingMip = numMipLevel - 1; + BOOL_32 inTail = FALSE; + BOOL_32 finalDim = FALSE; + + BOOL_32 is3dThick = IsThick(resourceType, swizzleMode); + BOOL_32 is3dThin = IsTex3d(resourceType) && (is3dThick == FALSE); + + for (UINT_32 mipId = 0; mipId < numMipLevel; mipId++) + { + if (inTail) + { + if (finalDim == FALSE) + { + UINT_32 mipSize; + + if (is3dThick) + { + mipSize = mipPitch * mipHeight * mipDepth * (bpp >> 3); + } + else + { + mipSize = mipPitch * mipHeight * (bpp >> 3); + } + + if (mipSize <= 256) + { + UINT_32 index = Log2(bpp >> 3); + + if (is3dThick) + { + mipPitch = Block256_3dZ[index].w; + mipHeight = Block256_3dZ[index].h; + mipDepth = Block256_3dZ[index].d; + } + else + { + mipPitch = Block256_2d[index].w; + mipHeight = Block256_2d[index].h; + } + + finalDim = TRUE; + } + } + } + else + { + inTail = IsInMipTail(resourceType, swizzleMode, tailMaxDim, + mipPitch, mipHeight, mipDepth); + + if (inTail) + { + endingMip = mipId; + + mipPitch = tailMaxDim.w; + mipHeight = tailMaxDim.h; + + if (is3dThick) + { + mipDepth = tailMaxDim.d; + } + } + else + { + mipPitch = PowTwoAlign(mipPitch, blockWidth); + mipHeight = PowTwoAlign(mipHeight, blockHeight); + + if (is3dThick) + { + mipDepth = PowTwoAlign(mipDepth, blockDepth); + } + } + } + + pMipInfo[mipId].pitch = mipPitch; + pMipInfo[mipId].height = mipHeight; + pMipInfo[mipId].depth = mipDepth; + pMipInfo[mipId].offset = offset; + offset += (mipPitch * mipHeight * mipDepth * (bpp >> 3)); + + if (finalDim) + { + if (is3dThin) + { + mipDepth = Max(mipDepth >> 1, 1u); + } + } + else + { + mipPitch = Max(mipPitch >> 1, 1u); + mipHeight = Max(mipHeight >> 1, 1u); + + if (is3dThick || is3dThin) + { + mipDepth = Max(mipDepth >> 1, 1u); + } + } + } + + return endingMip; +} + +/** +************************************************************************************************************************ +* Gfx9Lib::GetMetaMiptailInfo +* +* @brief +* Get mip tail coordinate information. +* +* @return +* N/A +************************************************************************************************************************ +*/ +VOID Gfx9Lib::GetMetaMiptailInfo( + ADDR2_META_MIP_INFO* pInfo, ///< [out] output structure to store per mip coord + Dim3d mipCoord, ///< [in] mip tail base coord + UINT_32 numMipInTail, ///< [in] number of mips in tail + Dim3d* pMetaBlkDim ///< [in] meta block width/height/depth + ) const +{ + BOOL_32 isThick = (pMetaBlkDim->d > 1); + UINT_32 mipWidth = pMetaBlkDim->w; + UINT_32 mipHeight = pMetaBlkDim->h >> 1; + UINT_32 mipDepth = pMetaBlkDim->d; + UINT_32 minInc; + + if (isThick) + { + minInc = (pMetaBlkDim->h >= 512) ? 128 : ((pMetaBlkDim->h == 256) ? 64 : 32); + } + else if (pMetaBlkDim->h >= 1024) + { + minInc = 256; + } + else if (pMetaBlkDim->h == 512) + { + minInc = 128; + } + else + { + minInc = 64; + } + + UINT_32 blk32MipId = 0xFFFFFFFF; + + for (UINT_32 mip = 0; mip < numMipInTail; mip++) + { + pInfo[mip].inMiptail = TRUE; + pInfo[mip].startX = mipCoord.w; + pInfo[mip].startY = mipCoord.h; + pInfo[mip].startZ = mipCoord.d; + pInfo[mip].width = mipWidth; + pInfo[mip].height = mipHeight; + pInfo[mip].depth = mipDepth; + + if (mipWidth <= 32) + { + if (blk32MipId == 0xFFFFFFFF) + { + blk32MipId = mip; + } + + mipCoord.w = pInfo[blk32MipId].startX; + mipCoord.h = pInfo[blk32MipId].startY; + mipCoord.d = pInfo[blk32MipId].startZ; + + switch (mip - blk32MipId) + { + case 0: + mipCoord.w += 32; // 16x16 + break; + case 1: + mipCoord.h += 32; // 8x8 + break; + case 2: + mipCoord.h += 32; // 4x4 + mipCoord.w += 16; + break; + case 3: + mipCoord.h += 32; // 2x2 + mipCoord.w += 32; + break; + case 4: + mipCoord.h += 32; // 1x1 + mipCoord.w += 48; + break; + // The following are for BC/ASTC formats + case 5: + mipCoord.h += 48; // 1/2 x 1/2 + break; + case 6: + mipCoord.h += 48; // 1/4 x 1/4 + mipCoord.w += 16; + break; + case 7: + mipCoord.h += 48; // 1/8 x 1/8 + mipCoord.w += 32; + break; + case 8: + mipCoord.h += 48; // 1/16 x 1/16 + mipCoord.w += 48; + break; + default: + ADDR_ASSERT_ALWAYS(); + break; + } + + mipWidth = ((mip - blk32MipId) == 0) ? 16 : 8; + mipHeight = mipWidth; + + if (isThick) + { + mipDepth = mipWidth; + } + } + else + { + if (mipWidth <= minInc) + { + // if we're below the minimal increment... + if (isThick) + { + // For 3d, just go in z direction + mipCoord.d += mipDepth; + } + else + { + // For 2d, first go across, then down + if ((mipWidth * 2) == minInc) + { + // if we're 2 mips below, that's when we go back in x, and down in y + mipCoord.w -= minInc; + mipCoord.h += minInc; + } + else + { + // otherwise, just go across in x + mipCoord.w += minInc; + } + } + } + else + { + // On even mip, go down, otherwise, go across + if (mip & 1) + { + mipCoord.w += mipWidth; + } + else + { + mipCoord.h += mipHeight; + } + } + // Divide the width by 2 + mipWidth >>= 1; + // After the first mip in tail, the mip is always a square + mipHeight = mipWidth; + // ...or for 3d, a cube + if (isThick) + { + mipDepth = mipWidth; + } + } + } +} + +/** +************************************************************************************************************************ +* Gfx9Lib::GetMipStartPos +* +* @brief +* Internal function to get out information about mip logical start position +* +* @return +* logical start position in macro block width/heith/depth of one mip level within one slice +************************************************************************************************************************ +*/ +Dim3d Gfx9Lib::GetMipStartPos( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode, + UINT_32 width, + UINT_32 height, + UINT_32 depth, + UINT_32 blockWidth, + UINT_32 blockHeight, + UINT_32 blockDepth, + UINT_32 mipId, + UINT_32 log2ElementBytes, + UINT_32* pMipTailBytesOffset) const +{ + Dim3d mipStartPos = {0}; + const Dim3d tailMaxDim = GetMipTailDim(resourceType, swizzleMode, blockWidth, blockHeight, blockDepth); + + // Report mip in tail if Mip0 is already in mip tail + BOOL_32 inMipTail = IsInMipTail(resourceType, swizzleMode, tailMaxDim, width, height, depth); + UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode); + UINT_32 mipIndexInTail = mipId; + + if (inMipTail == FALSE) + { + // Mip 0 dimension, unit in block + UINT_32 mipWidthInBlk = width / blockWidth; + UINT_32 mipHeightInBlk = height / blockHeight; + UINT_32 mipDepthInBlk = depth / blockDepth; + AddrMajorMode majorMode = GetMajorMode(resourceType, + swizzleMode, + mipWidthInBlk, + mipHeightInBlk, + mipDepthInBlk); + + UINT_32 endingMip = mipId + 1; + + for (UINT_32 i = 1; i <= mipId; i++) + { + if ((i == 1) || (i == 3)) + { + if (majorMode == ADDR_MAJOR_Y) + { + mipStartPos.w += mipWidthInBlk; + } + else + { + mipStartPos.h += mipHeightInBlk; + } + } + else + { + if (majorMode == ADDR_MAJOR_X) + { + mipStartPos.w += mipWidthInBlk; + } + else if (majorMode == ADDR_MAJOR_Y) + { + mipStartPos.h += mipHeightInBlk; + } + else + { + mipStartPos.d += mipDepthInBlk; + } + } + + BOOL_32 inTail = FALSE; + + if (IsThick(resourceType, swizzleMode)) + { + UINT_32 dim = log2blkSize % 3; + + if (dim == 0) + { + inTail = + (mipWidthInBlk <= 2) && (mipHeightInBlk == 1) && (mipDepthInBlk <= 2); + } + else if (dim == 1) + { + inTail = + (mipWidthInBlk == 1) && (mipHeightInBlk <= 2) && (mipDepthInBlk <= 2); + } + else + { + inTail = + (mipWidthInBlk <= 2) && (mipHeightInBlk <= 2) && (mipDepthInBlk == 1); + } + } + else + { + if (log2blkSize & 1) + { + inTail = (mipWidthInBlk <= 2) && (mipHeightInBlk == 1); + } + else + { + inTail = (mipWidthInBlk == 1) && (mipHeightInBlk <= 2); + } + } + + if (inTail) + { + endingMip = i; + break; + } + + mipWidthInBlk = RoundHalf(mipWidthInBlk); + mipHeightInBlk = RoundHalf(mipHeightInBlk); + mipDepthInBlk = RoundHalf(mipDepthInBlk); + } + + if (mipId >= endingMip) + { + inMipTail = TRUE; + mipIndexInTail = mipId - endingMip; + } + } + + if (inMipTail) + { + UINT_32 index = mipIndexInTail + MaxMacroBits - log2blkSize; + ADDR_ASSERT(index < sizeof(MipTailOffset256B) / sizeof(UINT_32)); + *pMipTailBytesOffset = MipTailOffset256B[index] << 8; + } + + return mipStartPos; +} + +/** +************************************************************************************************************************ +* Gfx9Lib::HwlComputeSurfaceAddrFromCoordTiled +* +* @brief +* Internal function to calculate address from coord for tiled swizzle surface +* +* @return +* ADDR_E_RETURNCODE +************************************************************************************************************************ +*/ +ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceAddrFromCoordTiled( + const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure + ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0}; + localIn.swizzleMode = pIn->swizzleMode; + localIn.flags = pIn->flags; + localIn.resourceType = pIn->resourceType; + localIn.bpp = pIn->bpp; + localIn.width = Max(pIn->unalignedWidth, 1u); + localIn.height = Max(pIn->unalignedHeight, 1u); + localIn.numSlices = Max(pIn->numSlices, 1u); + localIn.numMipLevels = Max(pIn->numMipLevels, 1u); + localIn.numSamples = Max(pIn->numSamples, 1u); + localIn.numFrags = Max(pIn->numFrags, 1u); + if (localIn.numMipLevels <= 1) + { + localIn.pitchInElement = pIn->pitchInElement; + } + + ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0}; + ADDR_E_RETURNCODE returnCode = ComputeSurfaceInfoTiled(&localIn, &localOut); + + BOOL_32 valid = (returnCode == ADDR_OK) && + (IsThin(pIn->resourceType, pIn->swizzleMode) || + IsThick(pIn->resourceType, pIn->swizzleMode)) && + ((pIn->pipeBankXor == 0) || (IsXor(pIn->swizzleMode))); + + if (valid) + { + UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3); + Dim3d mipStartPos = {0}; + UINT_32 mipTailBytesOffset = 0; + + if (pIn->numMipLevels > 1) + { + // Mip-map chain cannot be MSAA surface + ADDR_ASSERT((pIn->numSamples <= 1) && (pIn->numFrags<= 1)); + + mipStartPos = GetMipStartPos(pIn->resourceType, + pIn->swizzleMode, + localOut.pitch, + localOut.height, + localOut.numSlices, + localOut.blockWidth, + localOut.blockHeight, + localOut.blockSlices, + pIn->mipId, + log2ElementBytes, + &mipTailBytesOffset); + } + + UINT_32 interleaveOffset = 0; + UINT_32 pipeBits = 0; + UINT_32 pipeXor = 0; + UINT_32 bankBits = 0; + UINT_32 bankXor = 0; + + if (IsThin(pIn->resourceType, pIn->swizzleMode)) + { + UINT_32 blockOffset = 0; + UINT_32 log2blkSize = GetBlockSizeLog2(pIn->swizzleMode); + + if (IsZOrderSwizzle(pIn->swizzleMode)) + { + // Morton generation + if ((log2ElementBytes == 0) || (log2ElementBytes == 2)) + { + UINT_32 totalLowBits = 6 - log2ElementBytes; + UINT_32 mortBits = totalLowBits / 2; + UINT_32 lowBitsValue = MortonGen2d(pIn->y, pIn->x, mortBits); + // Are 9 bits enough? + UINT_32 highBitsValue = + MortonGen2d(pIn->x >> mortBits, pIn->y >> mortBits, 9) << totalLowBits; + blockOffset = lowBitsValue | highBitsValue; + ADDR_ASSERT(blockOffset == lowBitsValue + highBitsValue); + } + else + { + blockOffset = MortonGen2d(pIn->y, pIn->x, 13); + } + + // Fill LSBs with sample bits + if (pIn->numSamples > 1) + { + blockOffset *= pIn->numSamples; + blockOffset |= pIn->sample; + } + + // Shift according to BytesPP + blockOffset <<= log2ElementBytes; + } + else + { + // Micro block offset + UINT_32 microBlockOffset = ComputeSurface2DMicroBlockOffset(pIn); + blockOffset = microBlockOffset; + + // Micro block dimension + ADDR_ASSERT(log2ElementBytes < MaxNumOfBpp); + Dim2d microBlockDim = Block256_2d[log2ElementBytes]; + // Morton generation, does 12 bit enough? + blockOffset |= + MortonGen2d((pIn->x / microBlockDim.w), (pIn->y / microBlockDim.h), 12) << 8; + + // Sample bits start location + UINT_32 sampleStart = log2blkSize - Log2(pIn->numSamples); + // Join sample bits information to the highest Macro block bits + if (IsNonPrtXor(pIn->swizzleMode)) + { + // Non-prt-Xor : xor highest Macro block bits with sample bits + blockOffset = blockOffset ^ (pIn->sample << sampleStart); + } + else + { + // Non-Xor or prt-Xor: replace highest Macro block bits with sample bits + // after this op, the blockOffset only contains log2 Macro block size bits + blockOffset %= (1 << sampleStart); + blockOffset |= (pIn->sample << sampleStart); + ADDR_ASSERT((blockOffset >> log2blkSize) == 0); + } + } + + if (IsXor(pIn->swizzleMode)) + { + // Mask off bits above Macro block bits to keep page synonyms working for prt + if (IsPrt(pIn->swizzleMode)) + { + blockOffset &= ((1 << log2blkSize) - 1); + } + + // Preserve offset inside pipe interleave + interleaveOffset = blockOffset & ((1 << m_pipeInterleaveLog2) - 1); + blockOffset >>= m_pipeInterleaveLog2; + + // Pipe/Se xor bits + pipeBits = GetPipeXorBits(log2blkSize); + // Pipe xor + pipeXor = FoldXor2d(blockOffset, pipeBits); + blockOffset >>= pipeBits; + + // Bank xor bits + bankBits = GetBankXorBits(log2blkSize); + // Bank Xor + bankXor = FoldXor2d(blockOffset, bankBits); + blockOffset >>= bankBits; + + // Put all the part back together + blockOffset <<= bankBits; + blockOffset |= bankXor; + blockOffset <<= pipeBits; + blockOffset |= pipeXor; + blockOffset <<= m_pipeInterleaveLog2; + blockOffset |= interleaveOffset; + } + + ADDR_ASSERT((blockOffset | mipTailBytesOffset) == (blockOffset + mipTailBytesOffset)); + ADDR_ASSERT((mipTailBytesOffset == 0u) || (blockOffset < (1u << log2blkSize))); + + blockOffset |= mipTailBytesOffset; + + if (IsNonPrtXor(pIn->swizzleMode) && (pIn->numSamples <= 1)) + { + // Apply slice xor if not MSAA/PRT + blockOffset ^= (ReverseBitVector(pIn->slice, pipeBits) << m_pipeInterleaveLog2); + blockOffset ^= (ReverseBitVector(pIn->slice >> pipeBits, bankBits) << + (m_pipeInterleaveLog2 + pipeBits)); + } + + returnCode = ApplyCustomerPipeBankXor(pIn->swizzleMode, pIn->pipeBankXor, + bankBits, pipeBits, &blockOffset); + + blockOffset %= (1 << log2blkSize); + + UINT_32 pitchInMacroBlock = localOut.mipChainPitch / localOut.blockWidth; + UINT_32 paddedHeightInMacroBlock = localOut.mipChainHeight / localOut.blockHeight; + UINT_32 sliceSizeInMacroBlock = pitchInMacroBlock * paddedHeightInMacroBlock; + UINT_32 macroBlockIndex = + (pIn->slice + mipStartPos.d) * sliceSizeInMacroBlock + + ((pIn->y / localOut.blockHeight) + mipStartPos.h) * pitchInMacroBlock + + ((pIn->x / localOut.blockWidth) + mipStartPos.w); + + UINT_64 macroBlockOffset = (static_cast(macroBlockIndex) << + GetBlockSizeLog2(pIn->swizzleMode)); + + pOut->addr = blockOffset | macroBlockOffset; + } + else + { + UINT_32 log2blkSize = GetBlockSizeLog2(pIn->swizzleMode); + + Dim3d microBlockDim = Block1K_3d[log2ElementBytes]; + + UINT_32 blockOffset = MortonGen3d((pIn->x / microBlockDim.w), + (pIn->y / microBlockDim.h), + (pIn->slice / microBlockDim.d), + 8); + + blockOffset <<= 10; + blockOffset |= ComputeSurface3DMicroBlockOffset(pIn); + + if (IsXor(pIn->swizzleMode)) + { + // Mask off bits above Macro block bits to keep page synonyms working for prt + if (IsPrt(pIn->swizzleMode)) + { + blockOffset &= ((1 << log2blkSize) - 1); + } + + // Preserve offset inside pipe interleave + interleaveOffset = blockOffset & ((1 << m_pipeInterleaveLog2) - 1); + blockOffset >>= m_pipeInterleaveLog2; + + // Pipe/Se xor bits + pipeBits = GetPipeXorBits(log2blkSize); + // Pipe xor + pipeXor = FoldXor3d(blockOffset, pipeBits); + blockOffset >>= pipeBits; + + // Bank xor bits + bankBits = GetBankXorBits(log2blkSize); + // Bank Xor + bankXor = FoldXor3d(blockOffset, bankBits); + blockOffset >>= bankBits; + + // Put all the part back together + blockOffset <<= bankBits; + blockOffset |= bankXor; + blockOffset <<= pipeBits; + blockOffset |= pipeXor; + blockOffset <<= m_pipeInterleaveLog2; + blockOffset |= interleaveOffset; + } + + ADDR_ASSERT((blockOffset | mipTailBytesOffset) == (blockOffset + mipTailBytesOffset)); + ADDR_ASSERT((mipTailBytesOffset == 0u) || (blockOffset < (1u << log2blkSize))); + blockOffset |= mipTailBytesOffset; + + returnCode = ApplyCustomerPipeBankXor(pIn->swizzleMode, pIn->pipeBankXor, + bankBits, pipeBits, &blockOffset); + + blockOffset %= (1 << log2blkSize); + + UINT_32 xb = pIn->x / localOut.blockWidth + mipStartPos.w; + UINT_32 yb = pIn->y / localOut.blockHeight + mipStartPos.h; + UINT_32 zb = pIn->slice / localOut.blockSlices + + mipStartPos.d; + + UINT_32 pitchInBlock = localOut.mipChainPitch / localOut.blockWidth; + UINT_32 sliceSizeInBlock = + (localOut.mipChainHeight / localOut.blockHeight) * pitchInBlock; + UINT_32 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb; + + pOut->addr = blockOffset | (blockIndex << log2blkSize); + } + } + else + { + returnCode = ADDR_INVALIDPARAMS; + } + + return returnCode; +} + } // V2 } // Addr diff --git a/src/amd/addrlib/gfx9/gfx9addrlib.h b/src/amd/addrlib/gfx9/gfx9addrlib.h index 4a0ccd91d72..73d51f1ef7a 100644 --- a/src/amd/addrlib/gfx9/gfx9addrlib.h +++ b/src/amd/addrlib/gfx9/gfx9addrlib.h @@ -25,10 +25,10 @@ */ /** -**************************************************************************************************** +************************************************************************************************************************ * @file gfx9addrlib.h * @brief Contgfx9ns the Gfx9Lib class definition. -**************************************************************************************************** +************************************************************************************************************************ */ #ifndef __GFX9_ADDR_LIB_H__ @@ -43,9 +43,9 @@ namespace V2 { /** -**************************************************************************************************** +************************************************************************************************************************ * @brief GFX9 specific settings structure. -**************************************************************************************************** +************************************************************************************************************************ */ struct Gfx9ChipSettings { @@ -62,14 +62,15 @@ struct Gfx9ChipSettings // Misc configuration bits UINT_32 metaBaseAlignFix : 1; - UINT_32 reserved2 : 31; + UINT_32 depthPipeXorDisable : 1; + UINT_32 reserved2 : 30; }; }; /** -**************************************************************************************************** +************************************************************************************************************************ * @brief GFX9 data surface type. -**************************************************************************************************** +************************************************************************************************************************ */ enum Gfx9DataType { @@ -79,10 +80,10 @@ enum Gfx9DataType }; /** -**************************************************************************************************** +************************************************************************************************************************ * @brief This class is the GFX9 specific address library * function set. -**************************************************************************************************** +************************************************************************************************************************ */ class Gfx9Lib : public Lib { @@ -98,6 +99,39 @@ protected: Gfx9Lib(const Client* pClient); virtual ~Gfx9Lib(); + virtual BOOL_32 HwlIsStandardSwizzle( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode) const + { + return m_swizzleModeTable[swizzleMode].isStd || + (IsTex3d(resourceType) && m_swizzleModeTable[swizzleMode].isDisp); + } + + virtual BOOL_32 HwlIsDisplaySwizzle( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode) const + { + return IsTex2d(resourceType) && m_swizzleModeTable[swizzleMode].isDisp; + } + + virtual BOOL_32 HwlIsThin( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode) const + { + return ((IsTex2d(resourceType) == TRUE) || + ((IsTex3d(resourceType) == TRUE) && + (m_swizzleModeTable[swizzleMode].isZ == FALSE) && + (m_swizzleModeTable[swizzleMode].isStd == FALSE))); + } + + virtual BOOL_32 HwlIsThick( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode) const + { + return (IsTex3d(resourceType) && + (m_swizzleModeTable[swizzleMode].isZ || m_swizzleModeTable[swizzleMode].isStd)); + } + virtual ADDR_E_RETURNCODE HwlComputeHtileInfo( const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn, ADDR2_COMPUTE_HTILE_INFO_OUTPUT* pOut) const; @@ -122,6 +156,10 @@ protected: const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT* pOut) const; + virtual ADDR_E_RETURNCODE HwlComputeDccAddrFromCoord( + const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn, + ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut) const; + virtual UINT_32 HwlGetEquationIndex( const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const; @@ -183,13 +221,139 @@ protected: return baseAlign; } - virtual BOOL_32 HwlIsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const; + virtual ADDR_E_RETURNCODE HwlComputePipeBankXor( + const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn, + ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut) const; - virtual BOOL_32 HwlIsDce12() const { return m_settings.isDce12; } + virtual ADDR_E_RETURNCODE HwlComputeSlicePipeBankXor( + const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn, + ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut) const; + + virtual ADDR_E_RETURNCODE HwlComputeSubResourceOffsetForSwizzlePattern( + const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn, + ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut) const; + + virtual ADDR_E_RETURNCODE HwlGetPreferredSurfaceSetting( + const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn, + ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT* pOut) const; + + virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoSanityCheck( + const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const; + + virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoTiled( + const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, + ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const; + + virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoordTiled( + const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, + ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const; // Initialize equation table VOID InitEquationTable(); + ADDR_E_RETURNCODE ComputeStereoInfo( + const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, + ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut, + UINT_32* pHeightAlign) const; + + UINT_32 GetMipChainInfo( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode, + UINT_32 bpp, + UINT_32 mip0Width, + UINT_32 mip0Height, + UINT_32 mip0Depth, + UINT_32 blockWidth, + UINT_32 blockHeight, + UINT_32 blockDepth, + UINT_32 numMipLevel, + ADDR2_MIP_INFO* pMipInfo) const; + + VOID GetMetaMiptailInfo( + ADDR2_META_MIP_INFO* pInfo, + Dim3d mipCoord, + UINT_32 numMipInTail, + Dim3d* pMetaBlkDim) const; + + Dim3d GetMipStartPos( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode, + UINT_32 width, + UINT_32 height, + UINT_32 depth, + UINT_32 blockWidth, + UINT_32 blockHeight, + UINT_32 blockDepth, + UINT_32 mipId, + UINT_32 log2ElementBytes, + UINT_32* pMipTailBytesOffset) const; + + AddrMajorMode GetMajorMode( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode, + UINT_32 mip0WidthInBlk, + UINT_32 mip0HeightInBlk, + UINT_32 mip0DepthInBlk) const + { + BOOL_32 yMajor = (mip0WidthInBlk < mip0HeightInBlk); + BOOL_32 xMajor = (yMajor == FALSE); + + if (IsThick(resourceType, swizzleMode)) + { + yMajor = yMajor && (mip0HeightInBlk >= mip0DepthInBlk); + xMajor = xMajor && (mip0WidthInBlk >= mip0DepthInBlk); + } + + AddrMajorMode majorMode; + if (xMajor) + { + majorMode = ADDR_MAJOR_X; + } + else if (yMajor) + { + majorMode = ADDR_MAJOR_Y; + } + else + { + majorMode = ADDR_MAJOR_Z; + } + + return majorMode; + } + + Dim3d GetDccCompressBlk( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode, + UINT_32 bpp) const + { + UINT_32 index = Log2(bpp >> 3); + Dim3d compressBlkDim; + + if (IsThin(resourceType, swizzleMode)) + { + compressBlkDim.w = Block256_2d[index].w; + compressBlkDim.h = Block256_2d[index].h; + compressBlkDim.d = 1; + } + else if (IsStandardSwizzle(resourceType, swizzleMode)) + { + compressBlkDim = Block256_3dS[index]; + } + else + { + compressBlkDim = Block256_3dZ[index]; + } + + return compressBlkDim; + } + + static const Dim3d Block256_3dS[MaxNumOfBpp]; + static const Dim3d Block256_3dZ[MaxNumOfBpp]; + + static const UINT_32 MipTailOffset256B[]; + + static const SwizzleModeFlags SwizzleModeTable[ADDR_SW_MAX_TYPE]; + // Max number of swizzle mode supported for equation static const UINT_32 MaxSwMode = 32; // Max number of resource type (2D/3D) supported for equation @@ -239,6 +403,8 @@ private: UINT_32 mip0Width, UINT_32 mip0Height, UINT_32 mip0Depth, UINT_32* pNumMetaBlkX, UINT_32* pNumMetaBlkY, UINT_32* pNumMetaBlkZ) const; + BOOL_32 IsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const; + Gfx9ChipSettings m_settings; }; diff --git a/src/amd/addrlib/r800/ciaddrlib.cpp b/src/amd/addrlib/r800/ciaddrlib.cpp index 1f7bb189fe4..fe965b8eebd 100644 --- a/src/amd/addrlib/r800/ciaddrlib.cpp +++ b/src/amd/addrlib/r800/ciaddrlib.cpp @@ -711,6 +711,15 @@ ADDR_E_RETURNCODE CiLib::HwlComputeSurfaceInfo( ADDR_E_RETURNCODE retCode = SiLib::HwlComputeSurfaceInfo(pIn, pOut); + + if ((pIn->mipLevel > 0) && + (pOut->tcCompatible == TRUE) && + (pOut->tileMode != pIn->tileMode) && + (m_settings.isVolcanicIslands == TRUE)) + { + CheckTcCompatibility(pOut->pTileInfo, pIn->bpp, pOut->tileMode, pOut->tileType, pOut); + } + if (pOut->macroModeIndex == TileIndexNoMacroIndex) { pOut->macroModeIndex = TileIndexInvalid; @@ -1057,29 +1066,29 @@ VOID CiLib::HwlOverrideTileMode( switch (tileMode) { case ADDR_TM_1D_TILED_THICK: - tileMode = ADDR_TM_1D_TILED_THIN1; + tileMode = ADDR_TM_1D_TILED_THIN1; break; case ADDR_TM_2D_TILED_XTHICK: case ADDR_TM_2D_TILED_THICK: - tileMode = ADDR_TM_2D_TILED_THIN1; + tileMode = ADDR_TM_2D_TILED_THIN1; break; case ADDR_TM_3D_TILED_XTHICK: case ADDR_TM_3D_TILED_THICK: - tileMode = ADDR_TM_3D_TILED_THIN1; + tileMode = ADDR_TM_3D_TILED_THIN1; break; case ADDR_TM_PRT_TILED_THICK: - tileMode = ADDR_TM_PRT_TILED_THIN1; + tileMode = ADDR_TM_PRT_TILED_THIN1; break; case ADDR_TM_PRT_2D_TILED_THICK: - tileMode = ADDR_TM_PRT_2D_TILED_THIN1; + tileMode = ADDR_TM_PRT_2D_TILED_THIN1; break; case ADDR_TM_PRT_3D_TILED_THICK: - tileMode = ADDR_TM_PRT_3D_TILED_THIN1; + tileMode = ADDR_TM_PRT_3D_TILED_THIN1; break; default: @@ -1563,39 +1572,7 @@ VOID CiLib::HwlSetupTileInfo( if (flags.tcCompatible) { - if (IsMacroTiled(tileMode)) - { - if (inTileType != ADDR_DEPTH_SAMPLE_ORDER) - { - // Turn off tcCompatible for color surface if tileSplit happens. Depth/stencil - // tileSplit case was handled at tileIndex selecting time. - INT_32 tileIndex = pOut->tileIndex; - - if ((tileIndex == TileIndexInvalid) && (IsTileInfoAllZero(pTileInfo) == FALSE)) - { - tileIndex = HwlPostCheckTileIndex(pTileInfo, tileMode, inTileType, tileIndex); - } - - if (tileIndex != TileIndexInvalid) - { - ADDR_ASSERT(static_cast(tileIndex) < TileTableSize); - // Non-depth entries store a split factor - UINT_32 sampleSplit = m_tileTable[tileIndex].info.tileSplitBytes; - UINT_32 tileBytes1x = BITS_TO_BYTES(bpp * MicroTilePixels * thickness); - UINT_32 colorTileSplit = Max(256u, sampleSplit * tileBytes1x); - - if (m_rowSize < colorTileSplit) - { - flags.tcCompatible = FALSE; - } - } - } - } - else - { - // Client should not enable tc compatible for linear and 1D tile modes. - flags.tcCompatible = FALSE; - } + CheckTcCompatibility(pTileInfo, bpp, tileMode, inTileType, pOut); } pOut->tcCompatible = flags.tcCompatible; @@ -2289,5 +2266,60 @@ BOOL_32 CiLib::DepthStencilTileCfgMatch( return depthStencil2DTileConfigMatch; } +/** +**************************************************************************************************** +* CiLib::DepthStencilTileCfgMatch +* +* @brief +* Turn off TcCompatible if requirement is not met +* @return +* N/A +**************************************************************************************************** +*/ +VOID CiLib::CheckTcCompatibility( + const ADDR_TILEINFO* pTileInfo, ///< [in] input tile info + UINT_32 bpp, ///< [in] Bits per pixel + AddrTileMode tileMode, ///< [in] input tile mode + AddrTileType tileType, ///< [in] input tile type + ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] out structure + ) const +{ + if (IsMacroTiled(tileMode)) + { + if (tileType != ADDR_DEPTH_SAMPLE_ORDER) + { + // Turn off tcCompatible for color surface if tileSplit happens. Depth/stencil + // tileSplit case was handled at tileIndex selecting time. + INT_32 tileIndex = pOut->tileIndex; + + if ((tileIndex == TileIndexInvalid) && (IsTileInfoAllZero(pTileInfo) == FALSE)) + { + tileIndex = HwlPostCheckTileIndex(pTileInfo, tileMode, tileType, tileIndex); + } + + if (tileIndex != TileIndexInvalid) + { + UINT_32 thickness = Thickness(tileMode); + + ADDR_ASSERT(static_cast(tileIndex) < TileTableSize); + // Non-depth entries store a split factor + UINT_32 sampleSplit = m_tileTable[tileIndex].info.tileSplitBytes; + UINT_32 tileBytes1x = BITS_TO_BYTES(bpp * MicroTilePixels * thickness); + UINT_32 colorTileSplit = Max(256u, sampleSplit * tileBytes1x); + + if (m_rowSize < colorTileSplit) + { + pOut->tcCompatible = FALSE; + } + } + } + } + else + { + // Client should not enable tc compatible for linear and 1D tile modes. + pOut->tcCompatible = FALSE; + } +} + } // V1 } // Addr diff --git a/src/amd/addrlib/r800/ciaddrlib.h b/src/amd/addrlib/r800/ciaddrlib.h index 48835b32822..7e331dd56cf 100644 --- a/src/amd/addrlib/r800/ciaddrlib.h +++ b/src/amd/addrlib/r800/ciaddrlib.h @@ -208,6 +208,10 @@ private: const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const; + VOID CheckTcCompatibility( + const ADDR_TILEINFO* pTileInfo, UINT_32 bpp, AddrTileMode tileMode, + AddrTileType tileType, ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const; + 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/r800/egbaddrlib.cpp b/src/amd/addrlib/r800/egbaddrlib.cpp index 0cd27ada070..7affdecbf02 100644 --- a/src/amd/addrlib/r800/egbaddrlib.cpp +++ b/src/amd/addrlib/r800/egbaddrlib.cpp @@ -4125,7 +4125,7 @@ UINT_32 EgBasedLib::ComputeFmaskResolvedBppFromNumSamples( **************************************************************************************************** */ BOOL_32 EgBasedLib::IsTileInfoAllZero( - ADDR_TILEINFO* pTileInfo) + const ADDR_TILEINFO* pTileInfo) { BOOL_32 allZero = TRUE; diff --git a/src/amd/addrlib/r800/egbaddrlib.h b/src/amd/addrlib/r800/egbaddrlib.h index dbe712a6714..ee2c689df62 100644 --- a/src/amd/addrlib/r800/egbaddrlib.h +++ b/src/amd/addrlib/r800/egbaddrlib.h @@ -297,7 +297,7 @@ protected: ADDR_TILEINFO* pTileInfo, ADDR_EQUATION* pEquation) const; // Static functions - static BOOL_32 IsTileInfoAllZero(ADDR_TILEINFO* pTileInfo); + static BOOL_32 IsTileInfoAllZero(const ADDR_TILEINFO* pTileInfo); static UINT_32 ComputeFmaskNumPlanesFromNumSamples(UINT_32 numSamples); static UINT_32 ComputeFmaskResolvedBppFromNumSamples(UINT_32 numSamples); diff --git a/src/amd/addrlib/r800/siaddrlib.cpp b/src/amd/addrlib/r800/siaddrlib.cpp index d358f0d10b2..ffa5488662b 100644 --- a/src/amd/addrlib/r800/siaddrlib.cpp +++ b/src/amd/addrlib/r800/siaddrlib.cpp @@ -2662,9 +2662,15 @@ ADDR_E_RETURNCODE SiLib::HwlComputeSurfaceInfo( { static const UINT_32 SiUncompressDepthTileIndex = 3; - if ((pIn->flags.prt == FALSE) && - (m_uncompressDepthEqIndex != 0) && - (tileIndex == SiUncompressDepthTileIndex)) + if ((pIn->numSlices > 1) && + (IsMacroTiled(pOut->tileMode) == TRUE) && + (m_chipFamily == ADDR_CHIP_FAMILY_SI)) + { + pOut->equationIndex = ADDR_INVALID_EQUATION_INDEX; + } + else if ((pIn->flags.prt == FALSE) && + (m_uncompressDepthEqIndex != 0) && + (tileIndex == SiUncompressDepthTileIndex)) { pOut->equationIndex = m_uncompressDepthEqIndex + Log2(pIn->bpp >> 3); } @@ -3344,19 +3350,19 @@ VOID SiLib::HwlOverrideTileMode( switch (tileMode) { case ADDR_TM_PRT_TILED_THIN1: - tileMode = ADDR_TM_2D_TILED_THIN1; + tileMode = ADDR_TM_2D_TILED_THIN1; break; case ADDR_TM_PRT_TILED_THICK: - tileMode = ADDR_TM_2D_TILED_THICK; + tileMode = ADDR_TM_2D_TILED_THICK; break; case ADDR_TM_PRT_2D_TILED_THICK: - tileMode = ADDR_TM_2D_TILED_THICK; + tileMode = ADDR_TM_2D_TILED_THICK; break; case ADDR_TM_PRT_3D_TILED_THICK: - tileMode = ADDR_TM_3D_TILED_THICK; + tileMode = ADDR_TM_3D_TILED_THICK; break; default: @@ -3365,9 +3371,9 @@ VOID SiLib::HwlOverrideTileMode( if (tileMode != pInOut->tileMode) { - pInOut->tileMode = tileMode; - - ADDR_ASSERT(pInOut->flags.prt == TRUE); + pInOut->tileMode = tileMode; + // Only PRT tile modes are overridden for now. Revisit this once new modes are added above. + pInOut->flags.prt = TRUE; } } -- 2.30.2