diff --git a/src/amd/addrlib/inc/addrinterface.h b/src/amd/addrlib/inc/addrinterface.h index c620f7b37b3..77654d044f9 100644 --- a/src/amd/addrlib/inc/addrinterface.h +++ b/src/amd/addrlib/inc/addrinterface.h @@ -24,8 +24,9 @@ extern "C" #endif #define ADDRLIB_VERSION_MAJOR 9 -#define ADDRLIB_VERSION_MINOR 4 -#define ADDRLIB_VERSION ((ADDRLIB_VERSION_MAJOR << 16) | ADDRLIB_VERSION_MINOR) +#define ADDRLIB_VERSION_MINOR 11 +#define ADDRLIB_MAKE_VERSION(major, minor) ((major << 16) | minor) +#define ADDRLIB_VERSION ADDRLIB_MAKE_VERSION(ADDRLIB_VERSION_MAJOR, ADDRLIB_VERSION_MINOR) /// Virtually all interface functions need ADDR_HANDLE as first parameter typedef VOID* ADDR_HANDLE; @@ -2424,13 +2425,13 @@ typedef union _ADDR2_SURFACE_FLAGS UINT_32 stencil : 1; ///< Thie resource is a stencil buffer, can be used with DSV UINT_32 fmask : 1; ///< This is an fmask surface UINT_32 overlay : 1; ///< This is an overlay surface - UINT_32 display : 1; ///< This resource is displable, can be used with DRV + UINT_32 display : 1; ///< This resource is displayable, can be used with DRV UINT_32 prt : 1; ///< This is a partially resident texture UINT_32 qbStereo : 1; ///< This is a quad buffer stereo surface UINT_32 interleaved : 1; ///< Special flag for interleaved YUV surface padding UINT_32 texture : 1; ///< This resource can be used with SRV UINT_32 unordered : 1; ///< This resource can be used with UAV - UINT_32 rotated : 1; ///< This resource is rotated and displable + UINT_32 rotated : 1; ///< This resource is rotated and displayable UINT_32 needEquation : 1; ///< This resource needs equation to be generated if possible UINT_32 opt4space : 1; ///< This resource should be optimized for space UINT_32 minimizeAlign : 1; ///< This resource should use minimum alignment @@ -2439,7 +2440,8 @@ typedef union _ADDR2_SURFACE_FLAGS UINT_32 metaPipeUnaligned : 1; ///< This resource has pipe unaligned metadata UINT_32 view3dAs2dArray : 1; ///< This resource is a 3D resource viewed as 2D array UINT_32 allowExtEquation : 1; ///< If unset, only legacy DX eqs are allowed (2 XORs) - UINT_32 reserved : 12; ///< Reserved bits + UINT_32 requireMetadata : 1; ///< This resource must support metadata + UINT_32 reserved : 11; ///< Reserved bits }; UINT_32 value; @@ -4065,8 +4067,12 @@ typedef union _ADDR3_SURFACE_FLAGS UINT_32 p010 : 1; UINT_32 view3dAs2dArray : 1; UINT_32 isVrsImage : 1; ///< This resource is a VRS source image - UINT_32 reserved1 : 1; - UINT_32 reserved : 20; ///< Reserved bits + UINT_32 reserved1 : 2; + UINT_32 denseSliceExact : 1; ///< Pad dimensions such that + /// Pow2Align(pitch*height, surfAlign)==pitch*height + UINT_32 qbStereo : 1; ///< Quad buffer stereo surface + UINT_32 display : 1; ///< This resource is displayable, can be used with DRV + UINT_32 reserved : 16; ///< Reserved bits }; UINT_32 value; @@ -4109,10 +4115,11 @@ typedef struct _ADDR3_COMPUTE_SURFACE_INFO_INPUT */ typedef struct _ADDR3_MIP_INFO { - UINT_32 pitch; ///< Pitch in elements + UINT_32 pitch; ///< Pitch in elements of image data + UINT_32 pitchForSlice; ///< Pitch in elements used to compute slice size UINT_32 height; ///< Padded height in elements UINT_32 depth; ///< Padded depth - UINT_32 pixelPitch; ///< Pitch in pixels + UINT_32 pixelPitch; ///< Pitch in pixels for image data UINT_32 pixelHeight; ///< Padded height in pixels UINT_32 equationIndex; ///< Equation index in the equation table UINT_64 offset; ///< Offset in bytes from mip base, should only be used @@ -4139,7 +4146,8 @@ typedef struct _ADDR3_MIP_INFO typedef struct _ADDR3_COMPUTE_SURFACE_INFO_OUTPUT { UINT_32 size; ///< Size of this structure in bytes - UINT_32 pitch; ///< Pitch in elements (blocks for compressed formats) + UINT_32 pitch; ///< Pitch in elements for image data + UINT_32 pitchForSlice; ///< Pitch in elements used to compute slice size UINT_32 pixelPitch; ///< Pitch in original pixels UINT_32 pixelHeight; ///< Height in original pixels UINT_32 pixelBits; ///< Original bits per pixel, passed from input @@ -4149,6 +4157,7 @@ typedef struct _ADDR3_COMPUTE_SURFACE_INFO_OUTPUT /// or padded number of slices for 2d array resource UINT_32 height; ///< Padded height (of mip0) in elements UINT_64 sliceSize; ///< Slice (total mip chain) size in bytes + UINT_64 sliceSizeDensePacked; ///< Slice (total mip chain) size of image data in bytes UINT_64 surfSize; ///< Surface (total mip chain) size in bytes UINT_32 baseAlign; ///< Base address alignment ADDR_EXTENT3D blockExtent; ///< Dimensions in element inside one block @@ -4158,6 +4167,8 @@ typedef struct _ADDR3_COMPUTE_SURFACE_INFO_OUTPUT 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 + /// Stereo info + ADDR_QBSTEREOINFO* pStereoInfo; ///< Stereo info, needed if qbStereo flag is TRUE } ADDR3_COMPUTE_SURFACE_INFO_OUTPUT; /** @@ -4449,7 +4460,7 @@ typedef struct _ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT * Calculate sub resource offset to support swizzle pattern. **************************************************************************************************** */ -VOID ADDR_API Addr3ComputeSubResourceOffsetForSwizzlePattern( +ADDR_E_RETURNCODE ADDR_API Addr3ComputeSubResourceOffsetForSwizzlePattern( ADDR_HANDLE hLib, const ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn, ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut); diff --git a/src/amd/addrlib/src/addrinterface.cpp b/src/amd/addrlib/src/addrinterface.cpp index dc1e90aa97b..0ab0917e415 100644 --- a/src/amd/addrlib/src/addrinterface.cpp +++ b/src/amd/addrlib/src/addrinterface.cpp @@ -2173,18 +2173,21 @@ ADDR_E_RETURNCODE ADDR_API Addr3ComputeNonBlockCompressedView( * Calculate sub resource offset for swizzle pattern. **************************************************************************************************** */ -VOID ADDR_API Addr3ComputeSubResourceOffsetForSwizzlePattern( +ADDR_E_RETURNCODE ADDR_API Addr3ComputeSubResourceOffsetForSwizzlePattern( ADDR_HANDLE hLib, ///< handle of addrlib const ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn, ///< [in] input ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut) ///< [out] output { - V3::Lib* pLib = V3::Lib::GetLib(hLib); + ADDR_E_RETURNCODE returnCode = ADDR_ERROR; + V3::Lib* pLib = V3::Lib::GetLib(hLib); if (pLib != NULL) { - pLib->ComputeSubResourceOffsetForSwizzlePattern(pIn, pOut); + returnCode = pLib->ComputeSubResourceOffsetForSwizzlePattern(pIn, pOut); } ADDR_RESET_DEBUG_PRINTERS(); + + return returnCode; } /** diff --git a/src/amd/addrlib/src/core/addrcommon.h b/src/amd/addrlib/src/core/addrcommon.h index 37fd6983a9d..38e16b05741 100644 --- a/src/amd/addrlib/src/core/addrcommon.h +++ b/src/amd/addrlib/src/core/addrcommon.h @@ -234,9 +234,16 @@ namespace V2 // Common constants //////////////////////////////////////////////////////////////////////////////////////////////////// static const UINT_32 MaxSurfaceHeight = 16384; - } // V2 +namespace V3 +{ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Common constants +//////////////////////////////////////////////////////////////////////////////////////////////////// +static const UINT_32 MaxSurfaceHeight = 65536; +} // V3 + //////////////////////////////////////////////////////////////////////////////////////////////////// // Common macros //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/amd/addrlib/src/core/addrlib.h b/src/amd/addrlib/src/core/addrlib.h index 7a1f59dc1c5..63c35f8a96a 100644 --- a/src/amd/addrlib/src/core/addrlib.h +++ b/src/amd/addrlib/src/core/addrlib.h @@ -23,14 +23,6 @@ #include "amdgpu_asic_addr.h" -#ifndef CIASICIDGFXENGINE_R600 -#define CIASICIDGFXENGINE_R600 0x00000006 -#endif - -#ifndef CIASICIDGFXENGINE_R800 -#define CIASICIDGFXENGINE_R800 0x00000008 -#endif - #ifndef CIASICIDGFXENGINE_SOUTHERNISLAND #define CIASICIDGFXENGINE_SOUTHERNISLAND 0x0000000A #endif diff --git a/src/amd/addrlib/src/core/addrlib3.cpp b/src/amd/addrlib/src/core/addrlib3.cpp index 56b5e3c0806..3446b9681e8 100644 --- a/src/amd/addrlib/src/core/addrlib3.cpp +++ b/src/amd/addrlib/src/core/addrlib3.cpp @@ -319,6 +319,11 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo( &pOut->pMipInfo[i].pixelHeight); } } + + if (localIn.flags.qbStereo && (pOut->pStereoInfo != NULL)) + { + ComputeQbStereoInfo(pOut); + } } SetEquationIndex(&localIn, pOut); @@ -355,6 +360,11 @@ ADDR_E_RETURNCODE Lib::GetPossibleSwizzleModes( } } + if ((returnCode == ADDR_OK) && (HwlValidateNonSwModeParams(pIn) == FALSE)) + { + returnCode = ADDR_INVALIDPARAMS; + } + if (returnCode == ADDR_OK) { returnCode = HwlGetPossibleSwizzleModes(pIn, pOut); @@ -530,44 +540,26 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordLinear( if (valid) { - ADDR3_COMPUTE_SURFACE_INFO_INPUT localIn = {0}; - ADDR3_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0}; - ADDR3_MIP_INFO mipInfo[MaxMipLevels]; - ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels); + ADDR3_COMPUTE_SURFACE_INFO_INPUT surfInfoIn = {0}; - localIn.size = sizeof(localIn); - localIn.flags = pIn->flags; - localIn.swizzleMode = ADDR3_LINEAR; - localIn.resourceType = pIn->resourceType; - localIn.format = ADDR_FMT_INVALID; - localIn.bpp = pIn->bpp; - localIn.width = Max(pIn->unAlignedDims.width, 1u); - localIn.height = Max(pIn->unAlignedDims.height, 1u); - localIn.numSlices = Max(pIn->unAlignedDims.depth, 1u); - localIn.numMipLevels = Max(pIn->numMipLevels, 1u); - localIn.numSamples = Max(pIn->numSamples, 1u); + surfInfoIn.size = sizeof(surfInfoIn); + surfInfoIn.flags = pIn->flags; + surfInfoIn.swizzleMode = ADDR3_LINEAR; + surfInfoIn.resourceType = pIn->resourceType; + surfInfoIn.format = ADDR_FMT_INVALID; + surfInfoIn.bpp = pIn->bpp; + surfInfoIn.width = Max(pIn->unAlignedDims.width, 1u); + surfInfoIn.height = Max(pIn->unAlignedDims.height, 1u); + surfInfoIn.numSlices = Max(pIn->unAlignedDims.depth, 1u); + surfInfoIn.numMipLevels = Max(pIn->numMipLevels, 1u); + surfInfoIn.numSamples = Max(pIn->numSamples, 1u); - if (localIn.numMipLevels <= 1) + if (surfInfoIn.numMipLevels <= 1) { - localIn.pitchInElement = pIn->pitchInElement; + surfInfoIn.pitchInElement = pIn->pitchInElement; } - localOut.size = sizeof(localOut); - localOut.pMipInfo = mipInfo; - - returnCode = ComputeSurfaceInfo(&localIn, &localOut); - - if (returnCode == ADDR_OK) - { - pOut->addr = (localOut.sliceSize * pIn->slice) + - mipInfo[pIn->mipId].offset + - (pIn->y * mipInfo[pIn->mipId].pitch + pIn->x) * (pIn->bpp >> 3); - pOut->bitPosition = 0; - } - else - { - valid = FALSE; - } + returnCode = HwlComputeSurfaceAddrFromCoordLinear(pIn, &surfInfoIn, pOut); } if (valid == FALSE) @@ -784,25 +776,36 @@ ADDR_E_RETURNCODE Lib::ApplyCustomizedPitchHeight( const UINT_32 elementBytes = pIn->bpp >> 3; - // We may use 128B pitch alignment for linear addressing mip0 image under some restriction. - if ((pIn->numMipLevels == 1) && CanTrimLinearPadding(pIn)) + // Normal pitch of image data + const UINT_32 pitchAlignmentBytes = 1 << GetBlockSizeLog2(pIn->swizzleMode, TRUE); + const UINT_32 pitchAlignmentElements = pitchAlignmentBytes / elementBytes; + pOut->pitch = PowTwoAlign(pIn->width, pitchAlignmentElements); + + // Pitch of image data used for slice sizing (same except for linear images) + const UINT_32 pitchSliceAlignmentBytes = 1 << GetBlockSizeLog2(pIn->swizzleMode, CanTrimLinearPadding(pIn)); + const UINT_32 pitchSliceAlignmentElements = pitchSliceAlignmentBytes / elementBytes; + pOut->pitchForSlice = PowTwoAlign(pIn->width, pitchSliceAlignmentElements); + + UINT_32 heightAlign = pOut->blockExtent.height; + + if (pIn->flags.qbStereo) { - pOut->pitch = PowTwoAlign(pIn->width, 128u / elementBytes); + UINT_32 rightXor = 0; + + returnCode = HwlComputeStereoInfo(pIn, &heightAlign, &rightXor); + + if (returnCode == ADDR_OK) + { + pOut->pStereoInfo->rightSwizzle = rightXor; + } } - else - { - // Calculate the default pitch/height without any user inputs - pOut->pitch = PowTwoAlign(pIn->width, pOut->blockExtent.width); - } - pOut->height = PowTwoAlign(pIn->height, pOut->blockExtent.height); + + pOut->height = PowTwoAlign(pIn->height, heightAlign); // Custom pitches / alignments are only possible with single mip level / linear images; otherwise, // ignore those parameters. - if (UseCustomPitch(pIn)) + if ((returnCode == ADDR_OK) && UseCustomPitch(pIn)) { - const UINT_32 pitchAlignmentBytes = 1 << GetBlockSizeLog2(pIn->swizzleMode, TRUE); - const UINT_32 pitchAlignmentElements = pitchAlignmentBytes / elementBytes; - // Their requested pitch has to meet the pitch alignment constraints applied by the HW. if ((pIn->pitchInElement % pitchAlignmentElements) != 0) { @@ -816,14 +819,17 @@ ADDR_E_RETURNCODE Lib::ApplyCustomizedPitchHeight( else { pOut->pitch = pIn->pitchInElement; + pOut->pitchForSlice = PowTwoAlign(pIn->pitchInElement, pitchSliceAlignmentElements); } } if ((returnCode == ADDR_OK) && UseCustomHeight(pIn)) { - UINT_32 customizedHeight = pIn->sliceAlign / elementBytes / pOut->pitch; + // Note: if a custom slice align is present, it must be an even multiple + // of pitchForSlice, not just pitch. + UINT_32 customizedHeight = pIn->sliceAlign / elementBytes / pOut->pitchForSlice; - if (customizedHeight * elementBytes * pOut->pitch != pIn->sliceAlign) + if ((pIn->numSlices > 1) && (customizedHeight * elementBytes * pOut->pitchForSlice != pIn->sliceAlign)) { returnCode = ADDR_INVALIDPARAMS; } @@ -831,14 +837,57 @@ ADDR_E_RETURNCODE Lib::ApplyCustomizedPitchHeight( { returnCode = ADDR_INVALIDPARAMS; } + else if ((pIn->height * elementBytes * pOut->pitch) > pIn->sliceAlign) + { + // If we only have one slice/depth, then we don't need an even multiple, but the slice size must still + // fit all the pixel data. The one provided is too small! + returnCode = ADDR_INVALIDPARAMS; + } else { - pOut->height = customizedHeight; + // For the single-slice case, the customized height could have been rounded down below the height since + // we allow non-multiples of pitch here, so take the max. + pOut->height = Max(pOut->height, customizedHeight); } } return returnCode; } +/** +************************************************************************************************************************ +* Lib::ComputeQbStereoInfo +* +* @brief +* Get quad buffer stereo information +* @return +* N/A +************************************************************************************************************************ +*/ +VOID Lib::ComputeQbStereoInfo( + ADDR3_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; + pOut->sliceSize <<= 1; +} + } // V3 } // Addr diff --git a/src/amd/addrlib/src/core/addrlib3.h b/src/amd/addrlib/src/core/addrlib3.h index b5cb6db9aac..476218825bd 100644 --- a/src/amd/addrlib/src/core/addrlib3.h +++ b/src/amd/addrlib/src/core/addrlib3.h @@ -206,8 +206,6 @@ protected: Lib(); // Constructor is protected Lib(const Client* pClient); - static const UINT_32 MaxImageDim = 65536; // Max image size is 64k - static const UINT_32 MaxMipLevels = 17; UINT_32 m_pipesLog2; ///< Number of pipe per shader engine Log2 UINT_32 m_pipeInterleaveLog2; ///< Log2 of pipe interleave bytes @@ -227,6 +225,11 @@ protected: // Block dimension lookup table according to swizzle mode, MSAA sample rate and bpp. This includes linear. ADDR_EXTENT3D m_blockDimensionTable[ADDR3_MAX_TYPE][MaxMsaaRateLog2][MaxElementBytesLog2]; + virtual ADDR_E_RETURNCODE HwlComputeStereoInfo( + const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn, + UINT_32* pAlignY, + UINT_32* pRightXor) const = 0; + void SetEquationTableEntry( Addr3SwizzleMode swMode, UINT_32 msaaLog2, @@ -374,6 +377,11 @@ protected: const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const; + virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoordLinear( + const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, + const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pSurfInfoIn, + ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const = 0; + ADDR_E_RETURNCODE ComputeSurfaceAddrFromCoordTiled( const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const; @@ -447,6 +455,8 @@ protected: const ADDR3_COMPUTE_SURFACE_INFO_PARAMS_INPUT* pIn, const ADDR_EXTENT3D& blockDims) const = 0; + virtual BOOL_32 HwlValidateNonSwModeParams(const ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT* pIn) const = 0; + private: // Disallow the copy constructor Lib(const Lib& a); @@ -455,6 +465,8 @@ private: Lib& operator=(const Lib& a); void Init(); + + VOID ComputeQbStereoInfo(ADDR3_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const; }; } // V3 diff --git a/src/amd/addrlib/src/gfx11/gfx11addrlib.cpp b/src/amd/addrlib/src/gfx11/gfx11addrlib.cpp index 81ddd71b939..05406b96e5e 100644 --- a/src/amd/addrlib/src/gfx11/gfx11addrlib.cpp +++ b/src/amd/addrlib/src/gfx11/gfx11addrlib.cpp @@ -266,7 +266,13 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlComputeDccInfo( { ADDR_E_RETURNCODE ret = ADDR_OK; - if (IsLinear(pIn->swizzleMode) || IsBlock256b(pIn->swizzleMode)) + if (IsLinear(pIn->swizzleMode)) + { + ret = ADDR_INVALIDPARAMS; + } + else if (pIn->dccKeyFlags.pipeAligned && + (IsStandardSwizzle(pIn->swizzleMode) || + IsDisplaySwizzle(pIn->swizzleMode))) { ret = ADDR_INVALIDPARAMS; } @@ -861,6 +867,7 @@ INT_32 Gfx11Lib::GetMetaOverlapLog2( GetCompressedBlockSizeLog2(dataType, resourceType, swizzleMode, elemLog2, numSamplesLog2, &compBlock); GetBlk256SizeLog2(resourceType, swizzleMode, elemLog2, numSamplesLog2, µBlock); + const INT_32 blkSizeLog2 = GetBlockSizeLog2(swizzleMode); const INT_32 compSizeLog2 = compBlock.w + compBlock.h + compBlock.d; const INT_32 blk256SizeLog2 = microBlock.w + microBlock.h + microBlock.d; const INT_32 maxSizeLog2 = Max(compSizeLog2, blk256SizeLog2); @@ -873,10 +880,11 @@ INT_32 Gfx11Lib::GetMetaOverlapLog2( } // In 16Bpp 8xaa, we lose 1 overlap bit because the block size reduction eats into a pipe anchor bit (y4) - if ((elemLog2 == 4) && (numSamplesLog2 == 3)) + if ((elemLog2 == 4) && (numSamplesLog2 == 3) && (blkSizeLog2 == 16)) { overlap--; } + overlap += 16 - blkSizeLog2; overlap = Max(overlap, 0); return overlap; } @@ -2551,6 +2559,19 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlGetPreferredSurfaceSetting( allowedSwModeSet.value &= Gfx11ZSwModeMask; } + if (pIn->flags.requireMetadata) + { + // Linear images can never be compressed + allowedSwModeSet.value &= ~Gfx11LinearSwModeMask; + if (pIn->flags.color) + { + // 256B formats must not be pipe-aligned (can't use in CB) + allowedSwModeSet.value &= ~(Gfx11Blk256BSwModeMask); + // D/S formats must not be pipe-aligned + allowedSwModeSet.value &= ~(Gfx11DisplaySwModeMask | Gfx11StandardSwModeMask); + } + } + if (pIn->flags.display) { allowedSwModeSet.value &= GetValidDisplaySwizzleModes(bpp); @@ -3037,6 +3058,19 @@ ADDR_E_RETURNCODE Gfx11Lib::HwlGetPossibleSwizzleModes( allowedSwModeSet.value &= Gfx11ZSwModeMask; } + if (pIn->flags.requireMetadata) + { + // Linear images can never be compressed + allowedSwModeSet.value &= ~Gfx11LinearSwModeMask; + if (pIn->flags.color) + { + // 256B formats must not be pipe-aligned (can't use in CB) + allowedSwModeSet.value &= ~(Gfx11Blk256BSwModeMask); + // D/S formats must not be pipe-aligned + allowedSwModeSet.value &= ~(Gfx11DisplaySwModeMask | Gfx11StandardSwModeMask); + } + } + if (pIn->flags.display) { allowedSwModeSet.value &= GetValidDisplaySwizzleModes(bpp); diff --git a/src/amd/addrlib/src/gfx11/gfx11addrlib.h b/src/amd/addrlib/src/gfx11/gfx11addrlib.h index da8da6c3b1e..0a871ab85b0 100644 --- a/src/amd/addrlib/src/gfx11/gfx11addrlib.h +++ b/src/amd/addrlib/src/gfx11/gfx11addrlib.h @@ -121,12 +121,11 @@ const UINT_32 Gfx11Rsrc2dSwModeMask = Gfx11LinearSwModeMask | Gfx11ZSwModeMask | Gfx11RenderSwModeMask; -const UINT_32 Gfx11Rsrc3dSwModeMask = Gfx11LinearSwModeMask | - Gfx11StandardSwModeMask | - Gfx11ZSwModeMask | - Gfx11RenderSwModeMask | - (1u << ADDR_SW_64KB_D_X) | - (1u << ADDR_SW_256KB_D_X); +const UINT_32 Gfx11Rsrc3dSwModeMask = Gfx11LinearSwModeMask | + Gfx11StandardSwModeMask | + Gfx11ZSwModeMask | + Gfx11RenderSwModeMask | + (1u << ADDR_SW_64KB_D_X); const UINT_32 Gfx11Rsrc2dPrtSwModeMask = (Gfx11Blk4KBSwModeMask | Gfx11Blk64KBSwModeMask) & ~Gfx11XSwModeMask & Gfx11Rsrc2dSwModeMask; diff --git a/src/amd/addrlib/src/gfx12/gfx12addrlib.cpp b/src/amd/addrlib/src/gfx12/gfx12addrlib.cpp index 98de0d6b4c2..c9c1afb9a04 100644 --- a/src/amd/addrlib/src/gfx12/gfx12addrlib.cpp +++ b/src/amd/addrlib/src/gfx12/gfx12addrlib.cpp @@ -300,28 +300,22 @@ VOID Gfx12Lib::GetMipOrigin( ) const { const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pSurfInfo = pIn->pSurfInfo; - const BOOL_32 is3d = Is3dSwizzle(pSurfInfo->swizzleMode); + const BOOL_32 is3d = (pSurfInfo->resourceType == ADDR_RSRC_TEX_3D); const UINT_32 bytesPerPixel = pSurfInfo->bpp >> 3; const UINT_32 elementBytesLog2 = Log2(bytesPerPixel); const UINT_32 samplesLog2 = Log2(pSurfInfo->numSamples); - // Calculate the width/height/depth for ADDR3_4KB_3D swizzle mode. - // Note that only 2D swizzle mode supports MSAA, 1D and 3D all assume no MSAA, i.e., samplesLog2 == 0, so we must - // pass a 0 instead of samplesLog2 for the following ADDR3_4KB_3D. - // See implementation of Addrlib3::ComputeBlockDimensionForSurf(). - ADDR_EXTENT3D pixelDimOfAddr4kb3d = GetBlockDimensionTableEntry(ADDR3_4KB_3D, 0, elementBytesLog2); - const ADDR_EXTENT3D tailMaxDim = GetMipTailDim(pIn, pOut->blockExtent); - const UINT_32 blockSizeLog2 = GetBlockSizeLog2(pSurfInfo->swizzleMode); + // Calculate the width/height/depth for the given microblock, because the mip offset calculation + // is in units of microblocks but we want it in elements. + ADDR_EXTENT3D microBlockExtent = HwlGetMicroBlockSize(pIn); + const ADDR_EXTENT3D tailMaxDim = GetMipTailDim(pIn, pOut->blockExtent); + const UINT_32 blockSizeLog2 = GetBlockSizeLog2(pSurfInfo->swizzleMode); UINT_32 pitch = tailMaxDim.width; UINT_32 height = tailMaxDim.height; + UINT_32 depth = (is3d ? PowTwoAlign(mipExtentFirstInTail.depth, microBlockExtent.depth) : 1); - UINT_32 depth = (is3d ? PowTwoAlign(mipExtentFirstInTail.depth, pixelDimOfAddr4kb3d.depth) : 1); - - const UINT_32 tailMaxDepth = (is3d ? (depth / pixelDimOfAddr4kb3d.depth) : 1); - - // Calculate the width/height/depth for ADDR3_256B_2D swizzle mode. - ADDR_EXTENT3D blockDimOfAddr256b2d = GetBlockDimensionTableEntry(ADDR3_256B_2D, samplesLog2, elementBytesLog2); + const UINT_32 tailMaxDepth = (is3d ? (depth / microBlockExtent.depth) : 1); for (UINT_32 i = pOut->firstMipIdInTail; i < pSurfInfo->numMipLevels; i++) { @@ -356,34 +350,22 @@ VOID Gfx12Lib::GetMipOrigin( ((mipOffset >> 12) & 16) | ((mipOffset >> 13) & 32); - if (is3d == FALSE) - { - pOut->pMipInfo[i].mipTailCoordX = mipX * blockDimOfAddr256b2d.width; - pOut->pMipInfo[i].mipTailCoordY = mipY * blockDimOfAddr256b2d.height; - pOut->pMipInfo[i].mipTailCoordZ = 0; - } - else - { - pOut->pMipInfo[i].mipTailCoordX = mipX * pixelDimOfAddr4kb3d.width; - pOut->pMipInfo[i].mipTailCoordY = mipY * pixelDimOfAddr4kb3d.height; - pOut->pMipInfo[i].mipTailCoordZ = 0; - } + pOut->pMipInfo[i].mipTailCoordX = mipX * microBlockExtent.width; + pOut->pMipInfo[i].mipTailCoordY = mipY * microBlockExtent.height; + pOut->pMipInfo[i].mipTailCoordZ = 0; } if (IsLinear(pSurfInfo->swizzleMode)) { pitch = Max(pitch >> 1, 1u); } - else if (is3d) - { - pitch = Max(pitch >> 1, blockDimOfAddr256b2d.width); - height = Max(height >> 1, blockDimOfAddr256b2d.height); - depth = 1; - } else { - pitch = Max(pitch >> 1, pixelDimOfAddr4kb3d.width); - height = Max(height >> 1, pixelDimOfAddr4kb3d.height); - depth = PowTwoAlign(Max(depth >> 1, 1u), pixelDimOfAddr4kb3d.depth); + pOut->pMipInfo[i].pitch = PowTwoAlign(pitch, microBlockExtent.width); + pOut->pMipInfo[i].height = PowTwoAlign(height, microBlockExtent.height); + pOut->pMipInfo[i].depth = PowTwoAlign(depth, microBlockExtent.depth); + pitch = Max(pitch >> 1, 1u); + height = Max(height >> 1, 1u); + depth = Max(depth >> 1, 1u); } } } @@ -412,95 +394,113 @@ VOID Gfx12Lib::GetMipOffset( const ADDR_EXTENT3D tailMaxDim = GetMipTailDim(pIn, pOut->blockExtent);; const ADDR_EXTENT3D mip0Dims = GetBaseMipExtents(pSurfInfo); const UINT_32 maxMipsInTail = GetMaxNumMipsInTail(pIn); + const bool isLinear = IsLinear(pSurfInfo->swizzleMode); - UINT_32 firstMipInTail = pSurfInfo->numMipLevels; - UINT_64 mipChainSliceSize = 0; - UINT_64 mipSize[MaxMipLevels]; - UINT_64 mipSliceSize[MaxMipLevels]; + UINT_32 firstMipInTail = pSurfInfo->numMipLevels; + UINT_64 mipChainSliceSize = 0; + UINT_64 mipChainSliceSizeDense = 0; + UINT_64 mipSize[MaxMipLevels]; + UINT_64 mipSliceSize[MaxMipLevels]; const BOOL_32 useCustomPitch = UseCustomPitch(pSurfInfo); - const BOOL_32 trimLinearPadding = CanTrimLinearPadding(pSurfInfo); for (UINT_32 mipIdx = 0; mipIdx < pSurfInfo->numMipLevels; mipIdx++) { const ADDR_EXTENT3D mipExtents = GetMipExtent(mip0Dims, mipIdx); if (Lib::SupportsMipTail(pSurfInfo->swizzleMode) && + (pSurfInfo->numMipLevels > 1) && IsInMipTail(tailMaxDim, mipExtents, maxMipsInTail, pSurfInfo->numMipLevels - mipIdx)) { - firstMipInTail = mipIdx; - mipChainSliceSize += blockSize / pOut->blockExtent.depth; + firstMipInTail = mipIdx; + mipChainSliceSize += blockSize / pOut->blockExtent.depth; + mipChainSliceSizeDense += blockSize / pOut->blockExtent.depth; break; } else { - const BOOL_32 trimLinearPaddingForMip0 = ((mipIdx == 0) && trimLinearPadding); - UINT_32 pitch = 0u; - if (useCustomPitch) + UINT_32 pitchImgData = 0u; + UINT_32 pitchSliceSize = 0u; + if (isLinear) { - pitch = pOut->pitch; - } - // We may use 128B pitch alignment for linear addressing mip0 image under some restriction, which is - // followed by a post-processing to conform to base alignment requirement. - else if (trimLinearPaddingForMip0) - { - pitch = PowTwoAlign(mipExtents.width, 128u / bytesPerPixel); + // The slice size of a linear image is calculated as if the "pitch" is 256 byte aligned. + // However, the rendering pitch is aligned to 128 bytes, and that is what needs to be reported + // to our clients in the normal 'pitch' field. + // Note this is NOT the same as the total size of the image being aligned to 256 bytes! + pitchImgData = (useCustomPitch ? pOut->pitch : PowTwoAlign(mipExtents.width, 128u / bytesPerPixel)); + pitchSliceSize = PowTwoAlign(pitchImgData, blockSize / bytesPerPixel); } else { - pitch = PowTwoAlign(mipExtents.width, pOut->blockExtent.width); + pitchImgData = PowTwoAlign(mipExtents.width, pOut->blockExtent.width); + pitchSliceSize = pitchImgData; } - const UINT_32 height = UseCustomHeight(pSurfInfo) + UINT_32 height = UseCustomHeight(pSurfInfo) ? pOut->height : PowTwoAlign(mipExtents.height, pOut->blockExtent.height); const UINT_32 depth = PowTwoAlign(mipExtents.depth, pOut->blockExtent.depth); + if (isLinear && pSurfInfo->flags.denseSliceExact && ((pitchImgData % blockSize) != 0)) + { + // If we want size to exactly equal (data)pitch * height, make sure that value is 256B aligned. + // Essentially, if the pitch is less aligned, ensure the height is padded so total alignment is 256B. + ADDR_ASSERT((blockSize % 128) == 0); + height = PowTwoAlign(height, blockSize / 128u); + } + // The original "blockExtent" calculation does subtraction of logs (i.e., division) to get the // sizes. We aligned our pitch and height to those sizes, which means we need to multiply the various // factors back together to get back to the slice size. - UINT_64 sliceSize = static_cast(pitch) * height * pSurfInfo->numSamples * (pSurfInfo->bpp >> 3); + UINT_64 sizeExceptPitch = static_cast(height) * pSurfInfo->numSamples * (pSurfInfo->bpp >> 3); + UINT_64 sliceSize = static_cast(pitchSliceSize) * sizeExceptPitch; + UINT_64 sliceDataSize = PowTwoAlign(static_cast(pitchImgData) * sizeExceptPitch, + static_cast(blockSize)); - // When using 128B for linear mip0, sometimes the calculated sliceSize above might be not 256B aligned, - // e.g., sliceSize is odd times of 128B, it might cause next plane to be base misaligned. - // We must check if sliceSize is 256B aligned, otherwise the pitch has to be adjusted to be 256B aligned - // instead of 128B. - if ((useCustomPitch == FALSE) && trimLinearPaddingForMip0 && (sliceSize % 256 != 0)) + UINT_64 hwSliceSize = sliceSize * pOut->blockExtent.depth; + ADDR_ASSERT(PowTwoAlign(hwSliceSize, static_cast(blockSize)) == hwSliceSize); + + if ((mipIdx == 0) && CanTrimLinearPadding(pSurfInfo)) { - pitch = PowTwoAlign(mipExtents.width, pOut->blockExtent.width); - sliceSize = PowTwoAlign(sliceSize, 256ul); + // When this is the last linear subresource of the whole image (as laid out in memory), then we don't + // need to worry about the real slice size and can reduce it to the end of the image data (or some + // inflated value to meet a custom depth pitch) + pitchSliceSize = pitchImgData; + if (UseCustomHeight(pSurfInfo)) + { + sliceSize = pSurfInfo->sliceAlign; + } + else + { + sliceSize = sliceDataSize; + } + // CanTrimLinearPadding is always false for 3D swizzles, so block depth is always 1. + hwSliceSize = sliceSize; } - mipSize[mipIdx] = sliceSize * depth; - mipSliceSize[mipIdx] = sliceSize * pOut->blockExtent.depth; - mipChainSliceSize += sliceSize; + mipSize[mipIdx] = sliceSize * depth; + mipSliceSize[mipIdx] = hwSliceSize; + mipChainSliceSize += sliceSize; + mipChainSliceSizeDense += (mipIdx == 0) ? sliceDataSize : sliceSize; if (pOut->pMipInfo != NULL) { - pOut->pMipInfo[mipIdx].pitch = pitch; - pOut->pMipInfo[mipIdx].height = height; - pOut->pMipInfo[mipIdx].depth = depth; - - // The slice size of a linear image was calculated above as if the "pitch" is 256 byte aligned. - // However, the rendering pitch is aligned to 128 bytes, and that is what needs to be reported - // to our clients. - if (IsLinear(pSurfInfo->swizzleMode) && - // If UseCustomPitch is true, the pitch should be from pOut->pitch instead of 128B - (useCustomPitch == FALSE)) - { - pOut->pMipInfo[mipIdx].pitch = PowTwoAlign(mipExtents.width, 128u / bytesPerPixel); - } + pOut->pMipInfo[mipIdx].pitch = pitchImgData; + pOut->pMipInfo[mipIdx].pitchForSlice = pitchSliceSize; + pOut->pMipInfo[mipIdx].height = height; + pOut->pMipInfo[mipIdx].depth = depth; } } } - pOut->sliceSize = mipChainSliceSize; - pOut->surfSize = mipChainSliceSize * pOut->numSlices; - pOut->mipChainInTail = (firstMipInTail == 0) ? TRUE : FALSE; - pOut->firstMipIdInTail = firstMipInTail; + pOut->sliceSize = mipChainSliceSize; + pOut->sliceSizeDensePacked = mipChainSliceSizeDense; + pOut->surfSize = mipChainSliceSize * pOut->numSlices; + pOut->mipChainInTail = (firstMipInTail == 0) ? TRUE : FALSE; + pOut->firstMipIdInTail = firstMipInTail; if (pOut->pMipInfo != NULL) { - if (IsLinear(pSurfInfo->swizzleMode)) + if (isLinear) { // 1. Linear swizzle mode doesn't have miptails. // 2. The organization of linear 3D mipmap resource is same as GFX11, we should use mip slice size to @@ -737,6 +737,44 @@ UINT_32 Gfx12Lib::CalcMipOffset( return mipOffset; } +/** +************************************************************************************************************************ +* Gfx12Lib::HwlComputeSurfaceAddrFromCoordLinear +* +* @brief +* Internal function to calculate address from coord for linear swizzle surface +* +* @return +* ADDR_E_RETURNCODE +************************************************************************************************************************ +*/ +ADDR_E_RETURNCODE Gfx12Lib::HwlComputeSurfaceAddrFromCoordLinear( + const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure + const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pSurfInfoIn, ///< [in] input structure + ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR3_MIP_INFO mipInfo[MaxMipLevels]; + ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels); + + ADDR3_COMPUTE_SURFACE_INFO_OUTPUT surfInfoOut = {0}; + surfInfoOut.size = sizeof(surfInfoOut); + surfInfoOut.pMipInfo = mipInfo; + + ADDR_E_RETURNCODE returnCode = ComputeSurfaceInfo(pSurfInfoIn, &surfInfoOut); + + if (returnCode == ADDR_OK) + { + pOut->addr = (surfInfoOut.sliceSize * pIn->slice) + + mipInfo[pIn->mipId].offset + + (pIn->y * mipInfo[pIn->mipId].pitch + pIn->x) * (pIn->bpp >> 3); + + pOut->bitPosition = 0; + } + + return returnCode; +} + /** ************************************************************************************************************************ * Gfx12Lib::HwlComputeSurfaceAddrFromCoordTiled @@ -1502,6 +1540,49 @@ void Gfx12Lib::SanityCheckSurfSize( #endif } +/** +************************************************************************************************************************ +* Gfx12Lib::HwlGetMicroBlockSize +* +* @brief +* Determines the dimensions of a 256B microblock +* +* @return +************************************************************************************************************************ +*/ +ADDR_EXTENT3D Gfx12Lib::HwlGetMicroBlockSize( + const ADDR3_COMPUTE_SURFACE_INFO_PARAMS_INPUT* pIn + ) const +{ + ADDR_EXTENT3D out = {}; + INT_32 widthLog2 = 0; + INT_32 heightLog2 = 0; + INT_32 depthLog2 = 0; + Addr3SwizzleMode swMode = pIn->pSurfInfo->swizzleMode; + UINT_32 bppLog2 = Log2(pIn->pSurfInfo->bpp >> 3); + UINT_32 blockBits = 8 - bppLog2; + if (IsLinear(swMode)) + { + widthLog2 = blockBits; + } + else if (Is2dSwizzle(swMode)) + { + widthLog2 = (blockBits >> 1) + (blockBits & 1); + heightLog2 = (blockBits >> 1); + } + else + { + ADDR_ASSERT(Is3dSwizzle(swMode)); + depthLog2 = (blockBits / 3) + (((blockBits % 3) > 0) ? 1 : 0); + widthLog2 = (blockBits / 3) + (((blockBits % 3) > 1) ? 1 : 0); + heightLog2 = (blockBits / 3); + } + out.width = 1 << widthLog2; + out.height = 1 << heightLog2; + out.depth = 1 << depthLog2; + return out; +} + /** ************************************************************************************************************************ * Gfx12Lib::HwlCalcBlockSize @@ -1658,9 +1739,6 @@ ADDR_E_RETURNCODE Gfx12Lib::HwlGetPossibleSwizzleModes( const ADDR3_SURFACE_FLAGS flags = pIn->flags; - // VRS images can only be 2D from the client API rules. - ADDR_ASSERT((flags.isVrsImage == 0) || IsTex2d(pIn->resourceType)); - if (pIn->bpp == 96) { pOut->validModes.swLinear = 1; @@ -1719,12 +1797,8 @@ ADDR_E_RETURNCODE Gfx12Lib::HwlGetPossibleSwizzleModes( // There could be more multimedia formats that require more hw specific tiling modes... // The exception is VRS images. - // Linear is not allowed and the VRS surface needs to be 8BPP format. - if (flags.isVrsImage) - { - ADDR_ASSERT(pIn->bpp == 8); - } - else + // Linear is not allowed for VRS images. + if (flags.isVrsImage == 0) { pOut->validModes.swLinear = 1; } @@ -1777,5 +1851,150 @@ ADDR_E_RETURNCODE Gfx12Lib::HwlGetPossibleSwizzleModes( return returnCode; } +/** +************************************************************************************************************************ +* Gfx12Lib::HwlComputeStereoInfo +* +* @brief +* Compute height alignment and right eye pipeBankXor for stereo surface +* +* @return +* Error code +* +************************************************************************************************************************ +*/ +ADDR_E_RETURNCODE Gfx12Lib::HwlComputeStereoInfo( + const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< Compute surface info + UINT_32* pAlignY, ///< Stereo requested additional alignment in Y + UINT_32* pRightXor ///< Right eye xor + ) const +{ + ADDR_E_RETURNCODE ret = ADDR_OK; + + *pRightXor = 0; + + const UINT_32 elemLog2 = Log2(pIn->bpp >> 3); + const UINT_32 samplesLog2 = Log2(pIn->numSamples); + const UINT_32 eqIndex = GetEquationTableEntry(pIn->swizzleMode, samplesLog2, elemLog2); + + if (eqIndex != ADDR_INVALID_EQUATION_INDEX) + { + const UINT_32 blkSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode); + + UINT_32 yMax = 0; + UINT_32 yPosMask = 0; + + // First get "max y bit" + for (UINT_32 i = m_pipeInterleaveLog2; i < blkSizeLog2; i++) + { + ADDR_ASSERT(m_equationTable[eqIndex].addr[i].valid == 1); + + if ((m_equationTable[eqIndex].addr[i].channel == 1) && + (m_equationTable[eqIndex].addr[i].index > yMax)) + { + yMax = m_equationTable[eqIndex].addr[i].index; + } + } + + // Then loop again for populating a position mask of "max Y bit" + for (UINT_32 i = m_pipeInterleaveLog2; i < blkSizeLog2; i++) + { + if ((m_equationTable[eqIndex].addr[i].channel == 1) && + (m_equationTable[eqIndex].addr[i].index == yMax)) + { + yPosMask |= 1u << i; + } + } + + const UINT_32 additionalAlign = 1 << yMax; + + if (additionalAlign >= *pAlignY) + { + *pAlignY = additionalAlign; + + const UINT_32 alignedHeight = PowTwoAlign(pIn->height, additionalAlign); + + if ((alignedHeight >> yMax) & 1) + { + *pRightXor = yPosMask >> m_pipeInterleaveLog2; + } + } + } + else + { + ret = ADDR_INVALIDPARAMS; + } + + return ret; +} + +/** +************************************************************************************************************************ +* Gfx12Lib::HwlValidateNonSwModeParams +* +* @brief +* Validate compute surface info params except swizzle mode +* +* @return +* TRUE if parameters are valid, FALSE otherwise +************************************************************************************************************************ +*/ +BOOL_32 Gfx12Lib::HwlValidateNonSwModeParams( + const ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT* pIn + ) const +{ + const ADDR3_SURFACE_FLAGS flags = pIn->flags; + const AddrResourceType rsrcType = pIn->resourceType; + const BOOL_32 isVrs = flags.isVrsImage; + const BOOL_32 isStereo = flags.qbStereo; + const BOOL_32 isDisplay = flags.display; + const BOOL_32 isMipmap = (pIn->numMipLevels > 1); + const BOOL_32 isMsaa = (pIn->numSamples > 1); + const UINT_32 bpp = pIn->bpp; + + BOOL_32 valid = TRUE; + if ((bpp == 0) || (bpp > 128) || (pIn->width == 0) || (pIn->numSamples > 8)) + { + ADDR_ASSERT_ALWAYS(); + valid = FALSE; + } + + // Resource type check + if (IsTex1d(rsrcType)) + { + if (isMsaa || isStereo || isVrs || isDisplay) + { + ADDR_ASSERT_ALWAYS(); + valid = FALSE; + } + } + else if (IsTex2d(rsrcType)) + { + if ((isMsaa && isMipmap) || (isStereo && isMsaa) || (isStereo && isMipmap) || + // VRS surface needs to be 8BPP format + (isVrs && (bpp != 8))) + { + ADDR_ASSERT_ALWAYS(); + valid = FALSE; + } + } + else if (IsTex3d(rsrcType)) + { + if (isMsaa || isStereo || isVrs || isDisplay) + { + ADDR_ASSERT_ALWAYS(); + valid = FALSE; + } + } + else + { + // An invalid resource type that is not 1D, 2D or 3D. + ADDR_ASSERT_ALWAYS(); + valid = FALSE; + } + + return valid; +} + } // V3 } // Addr diff --git a/src/amd/addrlib/src/gfx12/gfx12addrlib.h b/src/amd/addrlib/src/gfx12/gfx12addrlib.h index b1060287351..75e030a883e 100644 --- a/src/amd/addrlib/src/gfx12/gfx12addrlib.h +++ b/src/amd/addrlib/src/gfx12/gfx12addrlib.h @@ -71,6 +71,11 @@ protected: return inTail; } + virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoordLinear( + const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, + const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pSurfInfoIn, + ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const override; + virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoordTiled( const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const override; @@ -97,6 +102,8 @@ protected: return m_numEquations; } + BOOL_32 HwlValidateNonSwModeParams(const ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT* pIn) const override; + virtual ADDR_E_RETURNCODE HwlGetPossibleSwizzleModes( const ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT* pIn, ADDR3_GET_POSSIBLE_SWIZZLE_MODE_OUTPUT* pOut) const override; @@ -108,6 +115,9 @@ protected: const ADDR3_COMPUTE_SURFACE_INFO_PARAMS_INPUT* pIn, ADDR_EXTENT3D* pExtent) const override final; + ADDR_EXTENT3D HwlGetMicroBlockSize( + const ADDR3_COMPUTE_SURFACE_INFO_PARAMS_INPUT* pIn) const; + virtual ADDR_EXTENT3D HwlGetMipInTailMaxSize( const ADDR3_COMPUTE_SURFACE_INFO_PARAMS_INPUT* pIn, const ADDR_EXTENT3D& blockDims) const override final; @@ -134,12 +144,20 @@ private: (1u << ADDR3_4KB_3D); static const UINT_32 Blk256BSwModeMask = (1u << ADDR3_256B_2D); + static const UINT_32 MaxImageDim = 32768; // Max image size is 32k + static const UINT_32 MaxMipLevels = 16; + virtual ADDR_E_RETURNCODE HwlComputePipeBankXor( const ADDR3_COMPUTE_PIPEBANKXOR_INPUT* pIn, ADDR3_COMPUTE_PIPEBANKXOR_OUTPUT* pOut) const override; virtual BOOL_32 HwlInitGlobalParams(const ADDR_CREATE_INPUT* pCreateIn) override; + virtual ADDR_E_RETURNCODE HwlComputeStereoInfo( + const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn, + UINT_32* pAlignY, + UINT_32* pRightXor) const override; + void SanityCheckSurfSize( const ADDR3_COMPUTE_SURFACE_INFO_PARAMS_INPUT* pIn, const ADDR3_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const; diff --git a/src/amd/addrlib/src/r800/ciaddrlib.cpp b/src/amd/addrlib/src/r800/ciaddrlib.cpp index aedfb0acb62..1eedf94d1fc 100644 --- a/src/amd/addrlib/src/r800/ciaddrlib.cpp +++ b/src/amd/addrlib/src/r800/ciaddrlib.cpp @@ -754,7 +754,7 @@ ADDR_E_RETURNCODE CiLib::HwlComputeSurfaceInfo( **************************************************************************************************** * CiLib::HwlFmaskSurfaceInfo * @brief -* Entry of r800's ComputeFmaskInfo +* Entry of CI's ComputeFmaskInfo * @return * ADDR_E_RETURNCODE **************************************************************************************************** diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c index 01e75842b64..492cba3c401 100644 --- a/src/amd/common/ac_surface.c +++ b/src/amd/common/ac_surface.c @@ -2754,7 +2754,7 @@ static unsigned gfx12_select_swizzle_mode(struct ac_addrlib *addrlib, get_in.flags = in->flags; get_in.resourceType = in->resourceType; - get_in.bpp = in->bpp; + get_in.bpp = in->bpp ? in->bpp : (surf->bpe * 8); get_in.width = in->width; get_in.height = in->height; get_in.numSlices = in->numSlices; @@ -3066,6 +3066,23 @@ static bool gfx12_compute_miptree(struct ac_addrlib *addrlib, const struct radeo if (ret != ADDR_OK) return false; + /* TODO: remove this block once addrlib stops giving us 64K pitch for small images, breaking + * modifiers and X.Org. + */ + if (in->swizzleMode >= ADDR3_256B_2D && in->swizzleMode <= ADDR3_256KB_2D && + in->numMipLevels == 1) { + static unsigned block_bits[ADDR3_MAX_TYPE] = { + [ADDR3_256B_2D] = 8, + [ADDR3_4KB_2D] = 12, + [ADDR3_64KB_2D] = 16, + [ADDR3_256KB_2D] = 18, + }; + unsigned align_bits = block_bits[in->swizzleMode] - util_logbase2(surf->bpe); + unsigned w_align = 1 << (align_bits / 2 + align_bits % 2); + + out.pitch = align(in->width, w_align); + } + if (in->flags.stencil) { surf->u.gfx9.zs.stencil_swizzle_mode = in->swizzleMode; surf->u.gfx9.zs.stencil_offset = align(surf->surf_size, out.baseAlign);