/* * Copyright © 2017 Advanced Micro Devices, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. */ /** ************************************************************************************************************************ * @file addrlib2.cpp * @brief Contains the implementation for the AddrLib2 base class. ************************************************************************************************************************ */ #include "addrinterface.h" #include "addrlib2.h" #include "addrcommon.h" namespace Addr { namespace V2 { //////////////////////////////////////////////////////////////////////////////////////////////////// // Static Const Member //////////////////////////////////////////////////////////////////////////////////////////////////// const Dim2d Lib::Block256_2d[] = {{16, 16}, {16, 8}, {8, 8}, {8, 4}, {4, 4}}; 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() : Addr::Lib() { } /** ************************************************************************************************************************ * Lib::Lib * * @brief * Constructor for the AddrLib2 class with hClient as parameter * ************************************************************************************************************************ */ Lib::Lib(const Client* pClient) : Addr::Lib(pClient) { } /** ************************************************************************************************************************ * Lib::~Lib * * @brief * Destructor for the AddrLib2 class * ************************************************************************************************************************ */ Lib::~Lib() { } /** ************************************************************************************************************************ * Lib::GetLib * * @brief * Get Addr::V2::Lib pointer * * @return * An Addr::V2::Lib class pointer ************************************************************************************************************************ */ Lib* Lib::GetLib( ADDR_HANDLE hLib) ///< [in] handle of ADDR_HANDLE { Addr::Lib* pAddrLib = Addr::Lib::GetLib(hLib); if ((pAddrLib != NULL) && (pAddrLib->GetChipFamily() <= ADDR_CHIP_FAMILY_VI)) { // only valid and GFX9+ AISC can use AddrLib2 function. ADDR_ASSERT_ALWAYS(); hLib = NULL; } return static_cast(hLib); } //////////////////////////////////////////////////////////////////////////////////////////////////// // Surface Methods //////////////////////////////////////////////////////////////////////////////////////////////////// /** ************************************************************************************************************************ * Lib::ComputeSurfaceInfo * * @brief * Interface function stub of AddrComputeSurfaceInfo. * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo( const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure ) const { ADDR_E_RETURNCODE returnCode = ADDR_OK; if (GetFillSizeFieldsFlags() == TRUE) { if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT)) || (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT))) { returnCode = ADDR_PARAMSIZEMISMATCH; } } // Adjust coming parameters. ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn; 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; UINT_32 expandX = 1; UINT_32 expandY = 1; ElemMode elemMode = ADDR_UNCOMPRESSED; if (returnCode == ADDR_OK) { // Set format to INVALID will skip this conversion if (localIn.format != ADDR_FMT_INVALID) { // Get compression/expansion factors and element mode which indicates compression/expansion localIn.bpp = GetElemLib()->GetBitsPerPixel(localIn.format, &elemMode, &expandX, &expandY); // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear- // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw // restrictions are different. // 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)) { ADDR_ASSERT(IsLinear(localIn.swizzleMode)); } UINT_32 basePitch = 0; GetElemLib()->AdjustSurfaceInfo(elemMode, expandX, expandY, &localIn.bpp, &basePitch, &localIn.width, &localIn.height); // Overwrite these parameters if we have a valid format } if (localIn.bpp != 0) { localIn.width = Max(localIn.width, 1u); localIn.height = Max(localIn.height, 1u); } else // Rule out some invalid parameters { ADDR_ASSERT_ALWAYS(); returnCode = ADDR_INVALIDPARAMS; } } if (returnCode == ADDR_OK) { returnCode = ComputeSurfaceInfoSanityCheck(&localIn); } if (returnCode == ADDR_OK) { VerifyMipLevelInfo(pIn); if (IsLinear(pIn->swizzleMode)) { // linear mode returnCode = ComputeSurfaceInfoLinear(&localIn, pOut); } else { // tiled mode returnCode = ComputeSurfaceInfoTiled(&localIn, pOut); } if (returnCode == ADDR_OK) { pOut->bpp = localIn.bpp; pOut->pixelPitch = pOut->pitch; pOut->pixelHeight = pOut->height; pOut->pixelMipChainPitch = pOut->mipChainPitch; pOut->pixelMipChainHeight = pOut->mipChainHeight; pOut->pixelBits = localIn.bpp; if (localIn.format != ADDR_FMT_INVALID) { UINT_32 pixelBits = pOut->pixelBits; GetElemLib()->RestoreSurfaceInfo(elemMode, expandX, expandY, &pOut->pixelBits, &pOut->pixelPitch, &pOut->pixelHeight); GetElemLib()->RestoreSurfaceInfo(elemMode, expandX, expandY, &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); ValidBaseAlignments(pOut->baseAlign); return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeSurfaceInfo * * @brief * Interface function stub of AddrComputeSurfaceInfo. * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord( 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; if (GetFillSizeFieldsFlags() == TRUE) { if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) || (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT))) { returnCode = ADDR_PARAMSIZEMISMATCH; } } ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT localIn = *pIn; 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); if ((localIn.bpp < 8) || (localIn.bpp > 128) || ((localIn.bpp % 8) != 0) || (localIn.sample >= localIn.numSamples) || (localIn.slice >= localIn.numSlices) || (localIn.mipId >= localIn.numMipLevels) || (IsTex3d(localIn.resourceType) && (Valid3DMipSliceIdConstraint(localIn.numSlices, localIn.mipId, localIn.slice) == FALSE))) { returnCode = ADDR_INVALIDPARAMS; } if (returnCode == ADDR_OK) { if (IsLinear(localIn.swizzleMode)) { returnCode = ComputeSurfaceAddrFromCoordLinear(&localIn, pOut); } else { returnCode = ComputeSurfaceAddrFromCoordTiled(&localIn, pOut); } if (returnCode == ADDR_OK) { pOut->prtBlockIndex = static_cast(pOut->addr / (64 * 1024)); } } return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeSurfaceCoordFromAddr * * @brief * Interface function stub of ComputeSurfaceCoordFromAddr. * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddr( const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure ) const { ADDR_E_RETURNCODE returnCode = ADDR_OK; if (GetFillSizeFieldsFlags() == TRUE) { if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) || (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT))) { returnCode = ADDR_PARAMSIZEMISMATCH; } } if ((pIn->bpp < 8) || (pIn->bpp > 128) || ((pIn->bpp % 8) != 0) || (pIn->bitPosition >= 8)) { returnCode = ADDR_INVALIDPARAMS; } if (returnCode == ADDR_OK) { if (IsLinear(pIn->swizzleMode)) { returnCode = ComputeSurfaceCoordFromAddrLinear(pIn, pOut); } else { returnCode = ComputeSurfaceCoordFromAddrTiled(pIn, pOut); } } return returnCode; } //////////////////////////////////////////////////////////////////////////////////////////////////// // CMASK/HTILE //////////////////////////////////////////////////////////////////////////////////////////////////// /** ************************************************************************************************************************ * Lib::ComputeHtileInfo * * @brief * Interface function stub of AddrComputeHtilenfo * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeHtileInfo( const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_HTILE_INFO_OUTPUT* pOut ///< [out] output structure ) const { ADDR_E_RETURNCODE returnCode; if ((GetFillSizeFieldsFlags() == TRUE) && ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT)) || (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT)))) { returnCode = ADDR_INVALIDPARAMS; } else { returnCode = HwlComputeHtileInfo(pIn, pOut); ValidMetaBaseAlignments(pOut->baseAlign); } return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeHtileAddrFromCoord * * @brief * Interface function stub of AddrComputeHtileAddrFromCoord * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeHtileAddrFromCoord( const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure { ADDR_E_RETURNCODE returnCode; if ((GetFillSizeFieldsFlags() == TRUE) && ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) || (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT)))) { returnCode = ADDR_INVALIDPARAMS; } else { returnCode = HwlComputeHtileAddrFromCoord(pIn, pOut); } return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeHtileCoordFromAddr * * @brief * Interface function stub of AddrComputeHtileCoordFromAddr * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeHtileCoordFromAddr( const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT* pOut) ///< [out] output structure { ADDR_E_RETURNCODE returnCode; if ((GetFillSizeFieldsFlags() == TRUE) && ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT)) || (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT)))) { returnCode = ADDR_INVALIDPARAMS; } else { returnCode = HwlComputeHtileCoordFromAddr(pIn, pOut); } return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeCmaskInfo * * @brief * Interface function stub of AddrComputeCmaskInfo * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeCmaskInfo( const ADDR2_COMPUTE_CMASK_INFO_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_CMASK_INFO_OUTPUT* pOut ///< [out] output structure ) const { ADDR_E_RETURNCODE returnCode; if ((GetFillSizeFieldsFlags() == TRUE) && ((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT)) || (pOut->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT)))) { returnCode = ADDR_INVALIDPARAMS; } else if (pIn->cMaskFlags.linear) { returnCode = ADDR_INVALIDPARAMS; } else { returnCode = HwlComputeCmaskInfo(pIn, pOut); ValidMetaBaseAlignments(pOut->baseAlign); } return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeCmaskAddrFromCoord * * @brief * Interface function stub of AddrComputeCmaskAddrFromCoord * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeCmaskAddrFromCoord( const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure { ADDR_E_RETURNCODE returnCode; if ((GetFillSizeFieldsFlags() == TRUE) && ((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) || (pOut->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT)))) { returnCode = ADDR_INVALIDPARAMS; } else { returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut); } return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeCmaskCoordFromAddr * * @brief * Interface function stub of AddrComputeCmaskCoordFromAddr * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeCmaskCoordFromAddr( const ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure ) const { ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED; ADDR_NOT_IMPLEMENTED(); return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeFmaskInfo * * @brief * Interface function stub of ComputeFmaskInfo. * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeFmaskInfo( const ADDR2_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure ) { ADDR_E_RETURNCODE returnCode; BOOL_32 valid = (IsZOrderSwizzle(pIn->swizzleMode) == TRUE) && ((pIn->numSamples > 0) || (pIn->numFrags > 0)); if (GetFillSizeFieldsFlags()) { if ((pIn->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT)) || (pOut->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT))) { valid = FALSE; } } if (valid == FALSE) { returnCode = ADDR_INVALIDPARAMS; } else { ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0}; ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0}; localIn.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT); localOut.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT); localIn.swizzleMode = pIn->swizzleMode; localIn.numSlices = Max(pIn->numSlices, 1u); localIn.width = Max(pIn->unalignedWidth, 1u); localIn.height = Max(pIn->unalignedHeight, 1u); localIn.bpp = GetFmaskBpp(pIn->numSamples, pIn->numFrags); localIn.flags.fmask = 1; localIn.numFrags = 1; localIn.numSamples = 1; localIn.resourceType = ADDR_RSRC_TEX_2D; if (localIn.bpp == 8) { localIn.format = ADDR_FMT_8; } else if (localIn.bpp == 16) { localIn.format = ADDR_FMT_16; } else if (localIn.bpp == 32) { localIn.format = ADDR_FMT_32; } else { localIn.format = ADDR_FMT_32_32; } returnCode = ComputeSurfaceInfo(&localIn, &localOut); if (returnCode == ADDR_OK) { pOut->pitch = localOut.pitch; pOut->height = localOut.height; pOut->baseAlign = localOut.baseAlign; pOut->numSlices = localOut.numSlices; pOut->fmaskBytes = static_cast(localOut.surfSize); pOut->sliceSize = static_cast(localOut.sliceSize); pOut->bpp = localIn.bpp; pOut->numSamples = 1; } } ValidBaseAlignments(pOut->baseAlign); return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeFmaskAddrFromCoord * * @brief * Interface function stub of ComputeFmaskAddrFromCoord. * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeFmaskAddrFromCoord( const ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure ) const { ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED; ADDR_NOT_IMPLEMENTED(); return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeFmaskCoordFromAddr * * @brief * Interface function stub of ComputeFmaskAddrFromCoord. * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeFmaskCoordFromAddr( const ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure ) const { ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED; ADDR_NOT_IMPLEMENTED(); return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeDccInfo * * @brief * Interface function to compute DCC key info * * @return * return code of HwlComputeDccInfo ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeDccInfo( const ADDR2_COMPUTE_DCCINFO_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_DCCINFO_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)))) { returnCode = ADDR_INVALIDPARAMS; } else { returnCode = HwlComputeDccInfo(pIn, pOut); ValidMetaBaseAlignments(pOut->dccRamBaseAlign); } return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeDccAddrFromCoord * * @brief * Interface function stub of ComputeDccAddrFromCoord * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeDccAddrFromCoord( const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure { ADDR_E_RETURNCODE returnCode; if ((GetFillSizeFieldsFlags() == TRUE) && ((pIn->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT)) || (pOut->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT)))) { returnCode = ADDR_INVALIDPARAMS; } else { returnCode = HwlComputeDccAddrFromCoord(pIn, pOut); } return returnCode; } /** ************************************************************************************************************************ * Lib::ComputePipeBankXor * * @brief * Interface function stub of Addr2ComputePipeBankXor. * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputePipeBankXor( const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn, ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut) { ADDR_E_RETURNCODE returnCode; if ((GetFillSizeFieldsFlags() == TRUE) && ((pIn->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT)) || (pOut->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT)))) { returnCode = ADDR_INVALIDPARAMS; } else if (IsXor(pIn->swizzleMode) == FALSE) { returnCode = ADDR_NOTSUPPORTED; } else { returnCode = HwlComputePipeBankXor(pIn, pOut); } return returnCode; } /** ************************************************************************************************************************ * 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); } return returnCode; } /** ************************************************************************************************************************ * 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 * Internal function to extract bank and pipe xor bits from combined xor bits. * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ExtractPipeBankXor( UINT_32 pipeBankXor, UINT_32 bankBits, UINT_32 pipeBits, UINT_32* pBankX, UINT_32* pPipeX) { ADDR_E_RETURNCODE returnCode; if (pipeBankXor < (1u << (pipeBits + bankBits))) { *pPipeX = pipeBankXor % (1 << pipeBits); *pBankX = pipeBankXor >> pipeBits; returnCode = ADDR_OK; } else { ADDR_ASSERT_ALWAYS(); returnCode = ADDR_INVALIDPARAMS; } return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeSurfaceInfoSanityCheck * * @brief * Internal function to do basic sanity check before compute surface info * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoSanityCheck( const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in] input structure ) const { ADDR_E_RETURNCODE returnCode; if ((GetFillSizeFieldsFlags() == TRUE) && (pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT))) { returnCode = ADDR_INVALIDPARAMS; } else { returnCode = HwlComputeSurfaceInfoSanityCheck(pIn); } return returnCode; } /** ************************************************************************************************************************ * Lib::ApplyCustomizedPitchHeight * * @brief * Helper function to override hw required row pitch/slice pitch by customrized one * * @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 pitchAlignInElement, ///< [in] pitch alignment in element UINT_32* pPitch, ///< [in/out] pitch UINT_32* pHeight ///< [in/out] height ) const { ADDR_E_RETURNCODE returnCode = ADDR_OK; if (pIn->numMipLevels <= 1) { if (pIn->pitchInElement > 0) { if ((pIn->pitchInElement % pitchAlignInElement) != 0) { returnCode = ADDR_INVALIDPARAMS; } else if (pIn->pitchInElement < (*pPitch)) { returnCode = ADDR_INVALIDPARAMS; } else { *pPitch = pIn->pitchInElement; } } if (returnCode == ADDR_OK) { if (pIn->sliceAlign > 0) { UINT_32 customizedHeight = pIn->sliceAlign / elementBytes / (*pPitch); if (customizedHeight * elementBytes * (*pPitch) != pIn->sliceAlign) { returnCode = ADDR_INVALIDPARAMS; } else if ((pIn->numSlices > 1) && ((*pHeight) != customizedHeight)) { returnCode = ADDR_INVALIDPARAMS; } else { *pHeight = customizedHeight; } } } } return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeSurfaceInfoLinear * * @brief * Internal function to calculate alignment for linear swizzle surface * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoLinear( const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure ) const { return HwlComputeSurfaceInfoLinear(pIn, pOut); } /** ************************************************************************************************************************ * Lib::ComputeSurfaceInfoTiled * * @brief * Internal function to calculate alignment for tiled swizzle surface * * @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 { return HwlComputeSurfaceInfoTiled(pIn, pOut); } /** ************************************************************************************************************************ * 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}; ADDR2_MIP_INFO mipInfo[MaxMipLevels]; 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) { localIn.pitchInElement = pIn->pitchInElement; } localOut.pMipInfo = mipInfo; returnCode = ComputeSurfaceInfoLinear(&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; } } if (valid == FALSE) { returnCode = ADDR_INVALIDPARAMS; } return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeSurfaceAddrFromCoordTiled * * @brief * Internal function to calculate address from coord for tiled swizzle surface * * @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 { return HwlComputeSurfaceAddrFromCoordTiled(pIn, pOut); } /** ************************************************************************************************************************ * Lib::ComputeSurfaceCoordFromAddrLinear * * @brief * Internal function to calculate coord from address for linear swizzle surface * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrLinear( const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure ) const { ADDR_E_RETURNCODE returnCode = ADDR_OK; BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1); if (valid) { if (IsTex1d(pIn->resourceType)) { valid = (pIn->unalignedHeight == 1); } } 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) { localIn.pitchInElement = pIn->pitchInElement; } returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut); if (returnCode == ADDR_OK) { pOut->slice = static_cast(pIn->addr / localOut.sliceSize); pOut->sample = 0; UINT_32 offsetInSlice = static_cast(pIn->addr % localOut.sliceSize); UINT_32 elementBytes = pIn->bpp >> 3; UINT_32 mipOffsetInSlice = 0; UINT_32 mipSize = 0; UINT_32 mipId = 0; for (; mipId < pIn->numMipLevels ; mipId++) { if (IsTex1d(pIn->resourceType)) { mipSize = localOut.pitch * elementBytes; } else { UINT_32 currentMipHeight = (PowTwoAlign(localIn.height, (1 << mipId))) >> mipId; mipSize = currentMipHeight * localOut.pitch * elementBytes; } if (mipSize == 0) { valid = FALSE; break; } else if ((mipSize + mipOffsetInSlice) > offsetInSlice) { break; } else { mipOffsetInSlice += mipSize; if ((mipId == (pIn->numMipLevels - 1)) || (mipOffsetInSlice >= localOut.sliceSize)) { valid = FALSE; } } } if (valid) { pOut->mipId = mipId; UINT_32 elemOffsetInMip = (offsetInSlice - mipOffsetInSlice) / elementBytes; if (IsTex1d(pIn->resourceType)) { if (elemOffsetInMip < localOut.pitch) { pOut->x = elemOffsetInMip; pOut->y = 0; } else { valid = FALSE; } } else { pOut->y = elemOffsetInMip / localOut.pitch; pOut->x = elemOffsetInMip % localOut.pitch; } if ((pOut->slice >= pIn->numSlices) || (pOut->mipId >= pIn->numMipLevels) || (pOut->x >= Max((pIn->unalignedWidth >> pOut->mipId), 1u)) || (pOut->y >= Max((pIn->unalignedHeight >> pOut->mipId), 1u)) || (IsTex3d(pIn->resourceType) && (FALSE == Valid3DMipSliceIdConstraint(pIn->numSlices, pOut->mipId, pOut->slice)))) { valid = FALSE; } } } else { valid = FALSE; } } if (valid == FALSE) { returnCode = ADDR_INVALIDPARAMS; } return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeSurfaceCoordFromAddrTiled * * @brief * Internal function to calculate coord from address for tiled swizzle surface * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrTiled( const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure ) const { ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED; ADDR_NOT_IMPLEMENTED(); return returnCode; } /** ************************************************************************************************************************ * 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, UINT_32* pHeight, UINT_32* pDepth, UINT_32 bpp, UINT_32 numSamples, AddrResourceType resourceType, AddrSwizzleMode swizzleMode) const { ADDR_E_RETURNCODE returnCode = ComputeBlockDimension(pWidth, pHeight, pDepth, bpp, resourceType, swizzleMode); if ((returnCode == ADDR_OK) && (numSamples > 1) && IsThin(resourceType, swizzleMode)) { const UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode); const UINT_32 log2sample = Log2(numSamples); const UINT_32 q = log2sample >> 1; const UINT_32 r = log2sample & 1; if (log2blkSize & 1) { *pWidth >>= q; *pHeight >>= (q + r); } else { *pWidth >>= (q + r); *pHeight >>= q; } } return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeBlockDimension * * @brief * Internal function to get block width/height/depth in element without considering MSAA case * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeBlockDimension( UINT_32* pWidth, UINT_32* pHeight, UINT_32* pDepth, UINT_32 bpp, AddrResourceType resourceType, AddrSwizzleMode swizzleMode) const { ADDR_E_RETURNCODE returnCode = ADDR_OK; UINT_32 eleBytes = bpp >> 3; UINT_32 microBlockSizeTableIndex = Log2(eleBytes); UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode); if (IsThin(resourceType, swizzleMode)) { UINT_32 log2blkSizeIn256B = log2blkSize - 8; UINT_32 widthAmp = log2blkSizeIn256B / 2; UINT_32 heightAmp = log2blkSizeIn256B - widthAmp; ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block256_2d) / sizeof(Block256_2d[0])); *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; ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block1K_3d) / sizeof(Block1K_3d[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 { ADDR_ASSERT_ALWAYS(); returnCode = ADDR_INVALIDPARAMS; } return returnCode; } /** ************************************************************************************************************************ * Lib::GetMipTailDim * * @brief * Internal function to get out max dimension of first level in mip tail * * @return * Max Width/Height/Depth value of the first mip fitted in mip tail ************************************************************************************************************************ */ Dim3d Lib::GetMipTailDim( AddrResourceType resourceType, AddrSwizzleMode swizzleMode, UINT_32 blockWidth, UINT_32 blockHeight, UINT_32 blockDepth) const { Dim3d out = {blockWidth, blockHeight, blockDepth}; UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode); if (IsThick(resourceType, swizzleMode)) { UINT_32 dim = log2blkSize % 3; if (dim == 0) { out.h >>= 1; } else if (dim == 1) { out.w >>= 1; } else { out.d >>= 1; } } else { if (log2blkSize & 1) { out.h >>= 1; } else { out.w >>= 1; } } return out; } /** ************************************************************************************************************************ * Lib::ComputeSurface2DMicroBlockOffset * * @brief * Internal function to calculate micro block (256B) offset from coord for 2D resource * * @return * micro block (256B) offset for 2D resource ************************************************************************************************************************ */ UINT_32 Lib::ComputeSurface2DMicroBlockOffset( const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const { ADDR_ASSERT(IsThin(pIn->resourceType, pIn->swizzleMode)); UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3); UINT_32 microBlockOffset = 0; if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode)) { UINT_32 xBits = pIn->x << log2ElementBytes; microBlockOffset = (xBits & 0xf) | ((pIn->y & 0x3) << 4); if (log2ElementBytes < 3) { microBlockOffset |= (pIn->y & 0x4) << 4; if (log2ElementBytes == 0) { microBlockOffset |= (pIn->y & 0x8) << 4; } else { microBlockOffset |= (xBits & 0x10) << 3; } } else { microBlockOffset |= (xBits & 0x30) << 2; } } else if (IsDisplaySwizzle(pIn->resourceType, pIn->swizzleMode)) { if (log2ElementBytes == 4) { microBlockOffset = (GetBit(pIn->x, 0) << 4) | (GetBit(pIn->y, 0) << 5) | (GetBit(pIn->x, 1) << 6) | (GetBit(pIn->y, 1) << 7); } else { microBlockOffset = GetBits(pIn->x, 0, 3, log2ElementBytes) | GetBits(pIn->y, 1, 2, 3 + log2ElementBytes) | GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) | GetBits(pIn->y, 3, 1, 6 + log2ElementBytes); microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) | (GetBit(pIn->y, 0) << 4) | GetBits(microBlockOffset, 4, 3, 5); } } else if (IsRotateSwizzle(pIn->swizzleMode)) { microBlockOffset = GetBits(pIn->y, 0, 3, log2ElementBytes) | GetBits(pIn->x, 1, 2, 3 + log2ElementBytes) | GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) | GetBits(pIn->y, 3, 1, 6 + log2ElementBytes); microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) | (GetBit(pIn->x, 0) << 4) | GetBits(microBlockOffset, 4, 3, 5); if (log2ElementBytes == 3) { microBlockOffset = GetBits(microBlockOffset, 0, 6, 0) | GetBits(pIn->x, 1, 2, 6); } } return microBlockOffset; } /** ************************************************************************************************************************ * Lib::ComputeSurface3DMicroBlockOffset * * @brief * Internal function to calculate micro block (1KB) offset from coord for 3D resource * * @return * micro block (1KB) offset for 3D resource ************************************************************************************************************************ */ UINT_32 Lib::ComputeSurface3DMicroBlockOffset( const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const { ADDR_ASSERT(IsThick(pIn->resourceType, pIn->swizzleMode)); UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3); UINT_32 microBlockOffset = 0; if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode)) { if (log2ElementBytes == 0) { microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1); } else if (log2ElementBytes == 1) { microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1); } else if (log2ElementBytes == 2) { microBlockOffset = ((pIn->y & 4) >> 2) | ((pIn->x & 4) >> 1); } else if (log2ElementBytes == 3) { microBlockOffset = (pIn->x & 6) >> 1; } else { microBlockOffset = pIn->x & 3; } microBlockOffset <<= 8; UINT_32 xBits = pIn->x << log2ElementBytes; microBlockOffset |= (xBits & 0xf) | ((pIn->y & 0x3) << 4) | ((pIn->slice & 0x3) << 6); } else if (IsZOrderSwizzle(pIn->swizzleMode)) { UINT_32 xh, yh, zh; if (log2ElementBytes == 0) { microBlockOffset = (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2); microBlockOffset = microBlockOffset | ((pIn->slice & 3) << 4) | ((pIn->x & 4) << 4); xh = pIn->x >> 3; yh = pIn->y >> 2; zh = pIn->slice >> 2; } else if (log2ElementBytes == 1) { microBlockOffset = (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2); microBlockOffset = (microBlockOffset << 1) | ((pIn->slice & 3) << 5); xh = pIn->x >> 2; yh = pIn->y >> 2; zh = pIn->slice >> 2; } else if (log2ElementBytes == 2) { microBlockOffset = (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->slice & 1) << 3); microBlockOffset = (microBlockOffset << 2) | ((pIn->y & 2) << 5); xh = pIn->x >> 2; yh = pIn->y >> 2; zh = pIn->slice >> 1; } else if (log2ElementBytes == 3) { microBlockOffset = (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2) | ((pIn->x & 2) << 2); microBlockOffset <<= 3; xh = pIn->x >> 2; yh = pIn->y >> 1; zh = pIn->slice >> 1; } else { microBlockOffset = (((pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2)) << 4); xh = pIn->x >> 1; yh = pIn->y >> 1; zh = pIn->slice >> 1; } microBlockOffset |= ((MortonGen3d(xh, yh, zh, 1) << 7) & 0x380); } return microBlockOffset; } /** ************************************************************************************************************************ * Lib::GetPipeXorBits * * @brief * Internal function to get bits number for pipe/se xor operation * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ UINT_32 Lib::GetPipeXorBits( UINT_32 macroBlockBits) const { ADDR_ASSERT(macroBlockBits >= m_pipeInterleaveLog2); // Total available xor bits UINT_32 xorBits = macroBlockBits - m_pipeInterleaveLog2; // Pipe/Se xor bits UINT_32 pipeBits = Min(xorBits, m_pipesLog2 + m_seLog2); return pipeBits; } /** ************************************************************************************************************************ * Lib::GetBankXorBits * * @brief * Internal function to get bits number for pipe/se xor operation * * @return * ADDR_E_RETURNCODE ************************************************************************************************************************ */ UINT_32 Lib::GetBankXorBits( UINT_32 macroBlockBits) const { UINT_32 pipeBits = GetPipeXorBits(macroBlockBits); // Bank xor bits UINT_32 bankBits = Min(macroBlockBits - pipeBits - m_pipeInterleaveLog2, m_banksLog2); return bankBits; } /** ************************************************************************************************************************ * Lib::Addr2GetPreferredSurfaceSetting * * @brief * Internal function to get suggested surface information for cliet to use * * @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 { ADDR_E_RETURNCODE returnCode; if ((GetFillSizeFieldsFlags() == TRUE) && ((pIn->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_INPUT)) || (pOut->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT)))) { returnCode = ADDR_INVALIDPARAMS; } else { returnCode = HwlGetPreferredSurfaceSetting(pIn, pOut); } return returnCode; } /** ************************************************************************************************************************ * Lib::ComputeBlock256Equation * * @brief * Compute equation for block 256B * * @return * If equation computed successfully * ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeBlock256Equation( AddrResourceType rsrcType, AddrSwizzleMode swMode, UINT_32 elementBytesLog2, ADDR_EQUATION* pEquation) const { ADDR_E_RETURNCODE ret; if (IsBlock256b(swMode)) { ret = HwlComputeBlock256Equation(rsrcType, swMode, elementBytesLog2, pEquation); } else { ADDR_ASSERT_ALWAYS(); ret = ADDR_INVALIDPARAMS; } return ret; } /** ************************************************************************************************************************ * Lib::ComputeThinEquation * * @brief * Compute equation for 2D/3D resource which use THIN mode * * @return * If equation computed successfully * ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeThinEquation( AddrResourceType rsrcType, AddrSwizzleMode swMode, UINT_32 elementBytesLog2, ADDR_EQUATION* pEquation) const { ADDR_E_RETURNCODE ret; if (IsThin(rsrcType, swMode)) { ret = HwlComputeThinEquation(rsrcType, swMode, elementBytesLog2, pEquation); } else { ADDR_ASSERT_ALWAYS(); ret = ADDR_INVALIDPARAMS; } return ret; } /** ************************************************************************************************************************ * Lib::ComputeThickEquation * * @brief * Compute equation for 3D resource which use THICK mode * * @return * If equation computed successfully * ************************************************************************************************************************ */ ADDR_E_RETURNCODE Lib::ComputeThickEquation( AddrResourceType rsrcType, AddrSwizzleMode swMode, UINT_32 elementBytesLog2, ADDR_EQUATION* pEquation) const { ADDR_E_RETURNCODE ret; if (IsThick(rsrcType, swMode)) { ret = HwlComputeThickEquation(rsrcType, swMode, elementBytesLog2, pEquation); } else { ADDR_ASSERT_ALWAYS(); ret = ADDR_INVALIDPARAMS; } 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