diff options
author | Nicolai Hähnle <[email protected]> | 2016-07-20 12:21:13 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2017-03-30 14:44:33 +0200 |
commit | 52a1288a15b6f2a5e80e2c129fd049c4fac8cbcd (patch) | |
tree | 0b184b9f6d3d8fbcb8965fbc98d2afc0587c9c62 /src/amd | |
parent | f12d430c5959c38b93131999d07278ca8d35b9ca (diff) |
amdgpu/addrlib: rearrange code in preparation of refactoring
No code changes.
Signed-off-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src/amd')
-rw-r--r-- | src/amd/Makefile.sources | 2 | ||||
-rw-r--r-- | src/amd/addrlib/core/addrlib.cpp | 3515 | ||||
-rw-r--r-- | src/amd/addrlib/core/addrlib.h | 13 | ||||
-rw-r--r-- | src/amd/addrlib/core/addrlib1.cpp | 3546 | ||||
-rw-r--r-- | src/amd/addrlib/core/addrlib1.h | 47 |
5 files changed, 3595 insertions, 3528 deletions
diff --git a/src/amd/Makefile.sources b/src/amd/Makefile.sources index 7aaa90a37a1..1ca443289c0 100644 --- a/src/amd/Makefile.sources +++ b/src/amd/Makefile.sources @@ -14,6 +14,8 @@ ADDRLIB_FILES = \ addrlib/core/addrelemlib.h \ addrlib/core/addrlib.cpp \ addrlib/core/addrlib.h \ + addrlib/core/addrlib1.cpp \ + addrlib/core/addrlib1.h \ addrlib/core/addrobject.cpp \ addrlib/core/addrobject.h \ addrlib/inc/chip/r800/si_gb_reg.h \ diff --git a/src/amd/addrlib/core/addrlib.cpp b/src/amd/addrlib/core/addrlib.cpp index f1a9fcbe30a..fbe7930bb02 100644 --- a/src/amd/addrlib/core/addrlib.cpp +++ b/src/amd/addrlib/core/addrlib.cpp @@ -81,38 +81,6 @@ UINT_32 __umoddi3(UINT_64 n, UINT_32 base) #endif // __APPLE__ -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Static Const Member -/////////////////////////////////////////////////////////////////////////////////////////////////// - -const AddrTileModeFlags AddrLib::m_modeFlags[ADDR_TM_COUNT] = -{// T L 1 2 3 P Pr B - {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_GENERAL - {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_ALIGNED - {1, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THIN1 - {4, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THICK - {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN1 - {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN2 - {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN4 - {4, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THICK - {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN1 - {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN2 - {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN4 - {4, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THICK - {1, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THIN1 - {4, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THICK - {1, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THIN1 - {4, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THICK - {8, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_XTHICK - {8, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_XTHICK - {1, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_POWER_SAVE - {1, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THIN1 - {1, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THIN1 - {1, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THIN1 - {4, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THICK - {4, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THICK - {4, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THICK -}; /////////////////////////////////////////////////////////////////////////////////////////////////// // Constructor/Destructor @@ -366,1511 +334,6 @@ AddrLib * AddrLib::GetAddrLib( return static_cast<AddrLib *>(hLib); } - - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Surface Methods -/////////////////////////////////////////////////////////////////////////////////////////////////// - - -/** -*************************************************************************************************** -* AddrLib::ComputeSurfaceInfo -* -* @brief -* Interface function stub of AddrComputeSurfaceInfo. -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeSurfaceInfo( - const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure - ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - // We suggest client do sanity check but a check here is also good - if (pIn->bpp > 128) - { - returnCode = ADDR_INVALIDPARAMS; - } - - // Thick modes don't support multisample - if (ComputeSurfaceThickness(pIn->tileMode) > 1 && pIn->numSamples > 1) - { - returnCode = ADDR_INVALIDPARAMS; - } - - if (returnCode == ADDR_OK) - { - // Get a local copy of input structure and only reference pIn for unadjusted values - ADDR_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn; - ADDR_TILEINFO tileInfoNull = {0}; - - if (UseTileInfo()) - { - // If the original input has a valid ADDR_TILEINFO pointer then copy its contents. - // Otherwise the default 0's in tileInfoNull are used. - if (pIn->pTileInfo) - { - tileInfoNull = *pIn->pTileInfo; - } - localIn.pTileInfo = &tileInfoNull; - } - - localIn.numSamples = pIn->numSamples == 0 ? 1 : pIn->numSamples; - - // Do mipmap check first - // If format is BCn, pre-pad dimension to power-of-two according to HWL - ComputeMipLevel(&localIn); - - if (m_configFlags.checkLast2DLevel) - { - // Save this level's original height in pixels - pOut->height = pIn->height; - } - - UINT_32 expandX = 1; - UINT_32 expandY = 1; - AddrElemMode elemMode; - - // Save outputs that may not go through HWL - pOut->pixelBits = localIn.bpp; - pOut->numSamples = localIn.numSamples; - pOut->last2DLevel = FALSE; - pOut->tcCompatible = FALSE; - -#if !ALT_TEST - if (localIn.numSamples > 1) - { - ADDR_ASSERT(localIn.mipLevel == 0); - } -#endif - - if (localIn.format != ADDR_FMT_INVALID) // Set format to INVALID will skip this conversion - { - // 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(localIn.tileMode == ADDR_TM_LINEAR_ALIGNED || localIn.height == 1); - } - - GetElemLib()->AdjustSurfaceInfo(elemMode, - expandX, - expandY, - &localIn.bpp, - &localIn.basePitch, - &localIn.width, - &localIn.height); - - // Overwrite these parameters if we have a valid format - } - else if (localIn.bpp != 0) - { - localIn.width = (localIn.width != 0) ? localIn.width : 1; - localIn.height = (localIn.height != 0) ? localIn.height : 1; - } - else // Rule out some invalid parameters - { - ADDR_ASSERT_ALWAYS(); - - returnCode = ADDR_INVALIDPARAMS; - } - - // Check mipmap after surface expansion - if (returnCode == ADDR_OK) - { - returnCode = PostComputeMipLevel(&localIn, pOut); - } - - if (returnCode == ADDR_OK) - { - if (UseTileIndex(localIn.tileIndex)) - { - // Make sure pTileInfo is not NULL - ADDR_ASSERT(localIn.pTileInfo); - - UINT_32 numSamples = GetNumFragments(localIn.numSamples, localIn.numFrags); - - INT_32 macroModeIndex = TileIndexNoMacroIndex; - - if (localIn.tileIndex != TileIndexLinearGeneral) - { - // Try finding a macroModeIndex - macroModeIndex = HwlComputeMacroModeIndex(localIn.tileIndex, - localIn.flags, - localIn.bpp, - numSamples, - localIn.pTileInfo, - &localIn.tileMode, - &localIn.tileType); - } - - // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info - if (macroModeIndex == TileIndexNoMacroIndex) - { - returnCode = HwlSetupTileCfg(localIn.tileIndex, macroModeIndex, - localIn.pTileInfo, - &localIn.tileMode, &localIn.tileType); - } - // If macroModeIndex is invalid, then assert this is not macro tiled - else if (macroModeIndex == TileIndexInvalid) - { - ADDR_ASSERT(!IsMacroTiled(localIn.tileMode)); - } - - pOut->macroModeIndex = macroModeIndex; - } - } - - if (returnCode == ADDR_OK) - { - AddrTileMode tileMode = localIn.tileMode; - AddrTileType tileType = localIn.tileType; - - // HWL layer may override tile mode if necessary - if (HwlOverrideTileMode(&localIn, &tileMode, &tileType)) - { - localIn.tileMode = tileMode; - localIn.tileType = tileType; - } - // Optimize tile mode if possible - if (OptimizeTileMode(&localIn, &tileMode)) - { - localIn.tileMode = tileMode; - } - } - - // Call main function to compute surface info - if (returnCode == ADDR_OK) - { - returnCode = HwlComputeSurfaceInfo(&localIn, pOut); - } - - if (returnCode == ADDR_OK) - { - // Since bpp might be changed we just pass it through - pOut->bpp = localIn.bpp; - - // Also original width/height/bpp - pOut->pixelPitch = pOut->pitch; - pOut->pixelHeight = pOut->height; - -#if DEBUG - if (localIn.flags.display) - { - ADDR_ASSERT((pOut->pitchAlign % 32) == 0); - } -#endif //DEBUG - - if (localIn.format != ADDR_FMT_INVALID) - { - // - // 96 bits surface of level 1+ requires element pitch of 32 bits instead - // In hwl function we skip multiplication of 3 then we should skip division of 3 - // We keep pitch that represents 32 bit element instead of 96 bits since we - // will get an odd number if divided by 3. - // - if (!((expandX == 3) && (localIn.mipLevel > 0))) - { - - GetElemLib()->RestoreSurfaceInfo(elemMode, - expandX, - expandY, - &localIn.bpp, - &pOut->pixelPitch, - &pOut->pixelHeight); - } - } - - if (localIn.flags.qbStereo) - { - if (pOut->pStereoInfo) - { - ComputeQbStereoInfo(pOut); - } - } - - if (localIn.flags.volume) // For volume sliceSize equals to all z-slices - { - pOut->sliceSize = pOut->surfSize; - } - else // For array: sliceSize is likely to have slice-padding (the last one) - { - pOut->sliceSize = pOut->surfSize / pOut->depth; - - // array or cubemap - if (pIn->numSlices > 1) - { - // If this is the last slice then add the padding size to this slice - if (pIn->slice == (pIn->numSlices - 1)) - { - pOut->sliceSize += pOut->sliceSize * (pOut->depth - pIn->numSlices); - } - else if (m_configFlags.checkLast2DLevel) - { - // Reset last2DLevel flag if this is not the last array slice - pOut->last2DLevel = FALSE; - } - } - } - - pOut->pitchTileMax = pOut->pitch / 8 - 1; - pOut->heightTileMax = pOut->height / 8 - 1; - pOut->sliceTileMax = pOut->pitch * pOut->height / 64 - 1; - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeSurfaceInfo -* -* @brief -* Interface function stub of AddrComputeSurfaceInfo. -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeSurfaceAddrFromCoord( - const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure - ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_TILEINFO tileInfoNull; - ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT input; - - if (UseTileIndex(pIn->tileIndex)) - { - input = *pIn; - // Use temp tile info for calcalation - input.pTileInfo = &tileInfoNull; - - const ADDR_SURFACE_FLAGS flags = {{0}}; - UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags); - - // Try finding a macroModeIndex - INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex, - flags, - input.bpp, - numSamples, - input.pTileInfo, - &input.tileMode, - &input.tileType); - - // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info - if (macroModeIndex == TileIndexNoMacroIndex) - { - returnCode = HwlSetupTileCfg(input.tileIndex, macroModeIndex, - input.pTileInfo, &input.tileMode, &input.tileType); - } - // If macroModeIndex is invalid, then assert this is not macro tiled - else if (macroModeIndex == TileIndexInvalid) - { - ADDR_ASSERT(!IsMacroTiled(input.tileMode)); - } - - // Change the input structure - pIn = &input; - } - - if (returnCode == ADDR_OK) - { - returnCode = HwlComputeSurfaceAddrFromCoord(pIn, pOut); - - if (returnCode == ADDR_OK) - { - pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024)); - } - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeSurfaceCoordFromAddr -* -* @brief -* Interface function stub of ComputeSurfaceCoordFromAddr. -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeSurfaceCoordFromAddr( - const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure - ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_TILEINFO tileInfoNull; - ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT input; - - if (UseTileIndex(pIn->tileIndex)) - { - input = *pIn; - // Use temp tile info for calcalation - input.pTileInfo = &tileInfoNull; - - const ADDR_SURFACE_FLAGS flags = {{0}}; - UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags); - - // Try finding a macroModeIndex - INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex, - flags, - input.bpp, - numSamples, - input.pTileInfo, - &input.tileMode, - &input.tileType); - - // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info - if (macroModeIndex == TileIndexNoMacroIndex) - { - returnCode = HwlSetupTileCfg(input.tileIndex, macroModeIndex, - input.pTileInfo, &input.tileMode, &input.tileType); - } - // If macroModeIndex is invalid, then assert this is not macro tiled - else if (macroModeIndex == TileIndexInvalid) - { - ADDR_ASSERT(!IsMacroTiled(input.tileMode)); - } - - // Change the input structure - pIn = &input; - } - - if (returnCode == ADDR_OK) - { - returnCode = HwlComputeSurfaceCoordFromAddr(pIn, pOut); - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeSliceTileSwizzle -* -* @brief -* Interface function stub of ComputeSliceTileSwizzle. -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeSliceTileSwizzle( - const ADDR_COMPUTE_SLICESWIZZLE_INPUT* pIn, ///< [in] input structure - ADDR_COMPUTE_SLICESWIZZLE_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_TILEINFO tileInfoNull; - ADDR_COMPUTE_SLICESWIZZLE_INPUT input; - - if (UseTileIndex(pIn->tileIndex)) - { - input = *pIn; - // Use temp tile info for calcalation - input.pTileInfo = &tileInfoNull; - - returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, - input.pTileInfo, &input.tileMode); - // Change the input structure - pIn = &input; - } - - if (returnCode == ADDR_OK) - { - returnCode = HwlComputeSliceTileSwizzle(pIn, pOut); - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ExtractBankPipeSwizzle -* -* @brief -* Interface function stub of AddrExtractBankPipeSwizzle. -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ExtractBankPipeSwizzle( - const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT* pIn, ///< [in] input structure - ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT)) || - (pOut->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_TILEINFO tileInfoNull; - ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT input; - - if (UseTileIndex(pIn->tileIndex)) - { - input = *pIn; - // Use temp tile info for calcalation - input.pTileInfo = &tileInfoNull; - - returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); - // Change the input structure - pIn = &input; - } - - if (returnCode == ADDR_OK) - { - returnCode = HwlExtractBankPipeSwizzle(pIn, pOut); - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::CombineBankPipeSwizzle -* -* @brief -* Interface function stub of AddrCombineBankPipeSwizzle. -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::CombineBankPipeSwizzle( - const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT* pIn, ///< [in] input structure - ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_TILEINFO tileInfoNull; - ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT input; - - if (UseTileIndex(pIn->tileIndex)) - { - input = *pIn; - // Use temp tile info for calcalation - input.pTileInfo = &tileInfoNull; - - returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); - // Change the input structure - pIn = &input; - } - - if (returnCode == ADDR_OK) - { - returnCode = HwlCombineBankPipeSwizzle(pIn->bankSwizzle, - pIn->pipeSwizzle, - pIn->pTileInfo, - pIn->baseAddr, - &pOut->tileSwizzle); - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeBaseSwizzle -* -* @brief -* Interface function stub of AddrCompueBaseSwizzle. -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeBaseSwizzle( - const ADDR_COMPUTE_BASE_SWIZZLE_INPUT* pIn, - ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_TILEINFO tileInfoNull; - ADDR_COMPUTE_BASE_SWIZZLE_INPUT input; - - if (UseTileIndex(pIn->tileIndex)) - { - input = *pIn; - // Use temp tile info for calcalation - input.pTileInfo = &tileInfoNull; - - returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); - // Change the input structure - pIn = &input; - } - - if (returnCode == ADDR_OK) - { - if (IsMacroTiled(pIn->tileMode)) - { - returnCode = HwlComputeBaseSwizzle(pIn, pOut); - } - else - { - pOut->tileSwizzle = 0; - } - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeFmaskInfo -* -* @brief -* Interface function stub of ComputeFmaskInfo. -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeFmaskInfo( - const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure - ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure - ) -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - // No thick MSAA - if (ComputeSurfaceThickness(pIn->tileMode) > 1) - { - returnCode = ADDR_INVALIDPARAMS; - } - - if (returnCode == ADDR_OK) - { - ADDR_TILEINFO tileInfoNull; - ADDR_COMPUTE_FMASK_INFO_INPUT input; - - if (UseTileIndex(pIn->tileIndex)) - { - input = *pIn; - - if (pOut->pTileInfo) - { - // Use temp tile info for calcalation - input.pTileInfo = pOut->pTileInfo; - } - else - { - input.pTileInfo = &tileInfoNull; - } - - ADDR_SURFACE_FLAGS flags = {{0}}; - flags.fmask = 1; - - // Try finding a macroModeIndex - INT_32 macroModeIndex = HwlComputeMacroModeIndex(pIn->tileIndex, - flags, - HwlComputeFmaskBits(pIn, NULL), - pIn->numSamples, - input.pTileInfo, - &input.tileMode); - - // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info - if (macroModeIndex == TileIndexNoMacroIndex) - { - returnCode = HwlSetupTileCfg(input.tileIndex, macroModeIndex, - input.pTileInfo, &input.tileMode); - } - - ADDR_ASSERT(macroModeIndex != TileIndexInvalid); - - // Change the input structure - pIn = &input; - } - - if (returnCode == ADDR_OK) - { - if (pIn->numSamples > 1) - { - returnCode = HwlComputeFmaskInfo(pIn, pOut); - } - else - { - memset(pOut, 0, sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT)); - - returnCode = ADDR_INVALIDPARAMS; - } - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeFmaskAddrFromCoord -* -* @brief -* Interface function stub of ComputeFmaskAddrFromCoord. -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeFmaskAddrFromCoord( - const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure - ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_ASSERT(pIn->numSamples > 1); - - if (pIn->numSamples > 1) - { - returnCode = HwlComputeFmaskAddrFromCoord(pIn, pOut); - } - else - { - returnCode = ADDR_INVALIDPARAMS; - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeFmaskCoordFromAddr -* -* @brief -* Interface function stub of ComputeFmaskAddrFromCoord. -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeFmaskCoordFromAddr( - const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure - ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_ASSERT(pIn->numSamples > 1); - - if (pIn->numSamples > 1) - { - returnCode = HwlComputeFmaskCoordFromAddr(pIn, pOut); - } - else - { - returnCode = ADDR_INVALIDPARAMS; - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ConvertTileInfoToHW -* -* @brief -* Convert tile info from real value to HW register value in HW layer -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ConvertTileInfoToHW( - const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure - ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT)) || - (pOut->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_TILEINFO tileInfoNull; - ADDR_CONVERT_TILEINFOTOHW_INPUT input; - // if pIn->reverse is TRUE, indices are ignored - if (pIn->reverse == FALSE && UseTileIndex(pIn->tileIndex)) - { - input = *pIn; - input.pTileInfo = &tileInfoNull; - - returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); - - pIn = &input; - } - - if (returnCode == ADDR_OK) - { - returnCode = HwlConvertTileInfoToHW(pIn, pOut); - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ConvertTileIndex -* -* @brief -* Convert tile index to tile mode/type/info -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ConvertTileIndex( - const ADDR_CONVERT_TILEINDEX_INPUT* pIn, ///< [in] input structure - ADDR_CONVERT_TILEINDEX_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX_INPUT)) || - (pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - - returnCode = HwlSetupTileCfg(pIn->tileIndex, pIn->macroModeIndex, - pOut->pTileInfo, &pOut->tileMode, &pOut->tileType); - - if (returnCode == ADDR_OK && pIn->tileInfoHw) - { - ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0}; - ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0}; - - hwInput.pTileInfo = pOut->pTileInfo; - hwInput.tileIndex = -1; - hwOutput.pTileInfo = pOut->pTileInfo; - - returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput); - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ConvertTileIndex1 -* -* @brief -* Convert tile index to tile mode/type/info -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ConvertTileIndex1( - const ADDR_CONVERT_TILEINDEX1_INPUT* pIn, ///< [in] input structure - ADDR_CONVERT_TILEINDEX_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX1_INPUT)) || - (pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_SURFACE_FLAGS flags = {{0}}; - - HwlComputeMacroModeIndex(pIn->tileIndex, flags, pIn->bpp, pIn->numSamples, - pOut->pTileInfo, &pOut->tileMode, &pOut->tileType); - - if (pIn->tileInfoHw) - { - ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0}; - ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0}; - - hwInput.pTileInfo = pOut->pTileInfo; - hwInput.tileIndex = -1; - hwOutput.pTileInfo = pOut->pTileInfo; - - returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput); - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::GetTileIndex -* -* @brief -* Get tile index from tile mode/type/info -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::GetTileIndex( - const ADDR_GET_TILEINDEX_INPUT* pIn, ///< [in] input structure - ADDR_GET_TILEINDEX_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_GET_TILEINDEX_INPUT)) || - (pOut->size != sizeof(ADDR_GET_TILEINDEX_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - returnCode = HwlGetTileIndex(pIn, pOut); - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeSurfaceThickness -* -* @brief -* Compute surface thickness -* -* @return -* Surface thickness -*************************************************************************************************** -*/ -UINT_32 AddrLib::ComputeSurfaceThickness( - AddrTileMode tileMode) ///< [in] tile mode -{ - return m_modeFlags[tileMode].thickness; -} - - - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// CMASK/HTILE -/////////////////////////////////////////////////////////////////////////////////////////////////// - -/** -*************************************************************************************************** -* AddrLib::ComputeHtileInfo -* -* @brief -* Interface function stub of AddrComputeHtilenfo -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeHtileInfo( - const ADDR_COMPUTE_HTILE_INFO_INPUT* pIn, ///< [in] input structure - ADDR_COMPUTE_HTILE_INFO_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - BOOL_32 isWidth8 = (pIn->blockWidth == 8) ? TRUE : FALSE; - BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_TILEINFO tileInfoNull; - ADDR_COMPUTE_HTILE_INFO_INPUT input; - - if (UseTileIndex(pIn->tileIndex)) - { - input = *pIn; - // Use temp tile info for calcalation - input.pTileInfo = &tileInfoNull; - - returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); - - // Change the input structure - pIn = &input; - } - - if (returnCode == ADDR_OK) - { - pOut->bpp = ComputeHtileInfo(pIn->flags, - pIn->pitch, - pIn->height, - pIn->numSlices, - pIn->isLinear, - isWidth8, - isHeight8, - pIn->pTileInfo, - &pOut->pitch, - &pOut->height, - &pOut->htileBytes, - &pOut->macroWidth, - &pOut->macroHeight, - &pOut->sliceSize, - &pOut->baseAlign); - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeCmaskInfo -* -* @brief -* Interface function stub of AddrComputeCmaskInfo -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeCmaskInfo( - const ADDR_COMPUTE_CMASK_INFO_INPUT* pIn, ///< [in] input structure - ADDR_COMPUTE_CMASK_INFO_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_INFO_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_CMASK_INFO_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_TILEINFO tileInfoNull; - ADDR_COMPUTE_CMASK_INFO_INPUT input; - - if (UseTileIndex(pIn->tileIndex)) - { - input = *pIn; - // Use temp tile info for calcalation - input.pTileInfo = &tileInfoNull; - - returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); - - // Change the input structure - pIn = &input; - } - - if (returnCode == ADDR_OK) - { - returnCode = ComputeCmaskInfo(pIn->flags, - pIn->pitch, - pIn->height, - pIn->numSlices, - pIn->isLinear, - pIn->pTileInfo, - &pOut->pitch, - &pOut->height, - &pOut->cmaskBytes, - &pOut->macroWidth, - &pOut->macroHeight, - &pOut->sliceSize, - &pOut->baseAlign, - &pOut->blockMax); - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeDccInfo -* -* @brief -* Interface function to compute DCC key info -* -* @return -* return code of HwlComputeDccInfo -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeDccInfo( - const ADDR_COMPUTE_DCCINFO_INPUT* pIn, ///< [in] input structure - ADDR_COMPUTE_DCCINFO_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE ret = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_DCCINFO_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT))) - { - ret = ADDR_PARAMSIZEMISMATCH; - } - } - - if (ret == ADDR_OK) - { - ADDR_COMPUTE_DCCINFO_INPUT input; - - if (UseTileIndex(pIn->tileIndex)) - { - input = *pIn; - - ret = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, - &input.tileInfo, &input.tileMode); - - pIn = &input; - } - - if (ADDR_OK == ret) - { - ret = HwlComputeDccInfo(pIn, pOut); - } - } - - return ret; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeHtileAddrFromCoord -* -* @brief -* Interface function stub of AddrComputeHtileAddrFromCoord -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeHtileAddrFromCoord( - const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure - ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - BOOL_32 isWidth8 = (pIn->blockWidth == 8) ? TRUE : FALSE; - BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_TILEINFO tileInfoNull; - ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT input; - - if (UseTileIndex(pIn->tileIndex)) - { - input = *pIn; - // Use temp tile info for calcalation - input.pTileInfo = &tileInfoNull; - - returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); - - // Change the input structure - pIn = &input; - } - - if (returnCode == ADDR_OK) - { - pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch, - pIn->height, - pIn->x, - pIn->y, - pIn->slice, - pIn->numSlices, - 1, - pIn->isLinear, - isWidth8, - isHeight8, - pIn->pTileInfo, - &pOut->bitPosition); - } - } - - return returnCode; - -} - -/** -*************************************************************************************************** -* AddrLib::ComputeHtileCoordFromAddr -* -* @brief -* Interface function stub of AddrComputeHtileCoordFromAddr -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeHtileCoordFromAddr( - const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure - ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - BOOL_32 isWidth8 = (pIn->blockWidth == 8) ? TRUE : FALSE; - BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_TILEINFO tileInfoNull; - ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT input; - - if (UseTileIndex(pIn->tileIndex)) - { - input = *pIn; - // Use temp tile info for calcalation - input.pTileInfo = &tileInfoNull; - - returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); - - // Change the input structure - pIn = &input; - } - - if (returnCode == ADDR_OK) - { - HwlComputeXmaskCoordFromAddr(pIn->addr, - pIn->bitPosition, - pIn->pitch, - pIn->height, - pIn->numSlices, - 1, - pIn->isLinear, - isWidth8, - isHeight8, - pIn->pTileInfo, - &pOut->x, - &pOut->y, - &pOut->slice); - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeCmaskAddrFromCoord -* -* @brief -* Interface function stub of AddrComputeCmaskAddrFromCoord -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeCmaskAddrFromCoord( - const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure - ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_TILEINFO tileInfoNull; - ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT input; - - if (UseTileIndex(pIn->tileIndex)) - { - input = *pIn; - // Use temp tile info for calcalation - input.pTileInfo = &tileInfoNull; - - returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); - - // Change the input structure - pIn = &input; - } - - if (returnCode == ADDR_OK) - { - if (pIn->flags.tcCompatible == TRUE) - { - returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut); - } - else - { - pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch, - pIn->height, - pIn->x, - pIn->y, - pIn->slice, - pIn->numSlices, - 2, - pIn->isLinear, - FALSE, //this is cmask, isWidth8 is not needed - FALSE, //this is cmask, isHeight8 is not needed - pIn->pTileInfo, - &pOut->bitPosition); - } - - } - } - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeCmaskCoordFromAddr -* -* @brief -* Interface function stub of AddrComputeCmaskCoordFromAddr -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeCmaskCoordFromAddr( - const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure - ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure - ) const -{ - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (GetFillSizeFieldsFlags() == TRUE) - { - if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT)) || - (pOut->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT))) - { - returnCode = ADDR_PARAMSIZEMISMATCH; - } - } - - if (returnCode == ADDR_OK) - { - ADDR_TILEINFO tileInfoNull; - ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT input; - - if (UseTileIndex(pIn->tileIndex)) - { - input = *pIn; - // Use temp tile info for calcalation - input.pTileInfo = &tileInfoNull; - - returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); - - // Change the input structure - pIn = &input; - } - - if (returnCode == ADDR_OK) - { - HwlComputeXmaskCoordFromAddr(pIn->addr, - pIn->bitPosition, - pIn->pitch, - pIn->height, - pIn->numSlices, - 2, - pIn->isLinear, - FALSE, - FALSE, - pIn->pTileInfo, - &pOut->x, - &pOut->y, - &pOut->slice); - } - } - - return returnCode; -} - /** *************************************************************************************************** * AddrLib::GetMaxAlignments @@ -1906,1562 +369,6 @@ ADDR_E_RETURNCODE AddrLib::GetMaxAlignments( /** *************************************************************************************************** -* AddrLib::ComputeTileDataWidthAndHeight -* -* @brief -* Compute the squared cache shape for per-tile data (CMASK and HTILE) -* -* @return -* N/A -* -* @note -* MacroWidth and macroHeight are measured in pixels -*************************************************************************************************** -*/ -VOID AddrLib::ComputeTileDataWidthAndHeight( - UINT_32 bpp, ///< [in] bits per pixel - UINT_32 cacheBits, ///< [in] bits of cache - ADDR_TILEINFO* pTileInfo, ///< [in] Tile info - UINT_32* pMacroWidth, ///< [out] macro tile width - UINT_32* pMacroHeight ///< [out] macro tile height - ) const -{ - UINT_32 height = 1; - UINT_32 width = cacheBits / bpp; - UINT_32 pipes = HwlGetPipes(pTileInfo); - - // Double height until the macro-tile is close to square - // Height can only be doubled if width is even - - while ((width > height * 2 * pipes) && !(width & 1)) - { - width /= 2; - height *= 2; - } - - *pMacroWidth = 8 * width; - *pMacroHeight = 8 * height * pipes; - - // Note: The above iterative comptuation is equivalent to the following - // - //int log2_height = ((log2(cacheBits)-log2(bpp)-log2(pipes))/2); - //int macroHeight = pow2( 3+log2(pipes)+log2_height ); -} - -/** -*************************************************************************************************** -* AddrLib::HwlComputeTileDataWidthAndHeightLinear -* -* @brief -* Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout -* -* @return -* N/A -* -* @note -* MacroWidth and macroHeight are measured in pixels -*************************************************************************************************** -*/ -VOID AddrLib::HwlComputeTileDataWidthAndHeightLinear( - UINT_32* pMacroWidth, ///< [out] macro tile width - UINT_32* pMacroHeight, ///< [out] macro tile height - UINT_32 bpp, ///< [in] bits per pixel - ADDR_TILEINFO* pTileInfo ///< [in] tile info - ) const -{ - ADDR_ASSERT(bpp != 4); // Cmask does not support linear layout prior to SI - *pMacroWidth = 8 * 512 / bpp; // Align width to 512-bit memory accesses - *pMacroHeight = 8 * m_pipes; // Align height to number of pipes -} - -/** -*************************************************************************************************** -* AddrLib::ComputeHtileInfo -* -* @brief -* Compute htile pitch,width, bytes per 2D slice -* -* @return -* Htile bpp i.e. How many bits for an 8x8 tile -* Also returns by output parameters: -* *Htile pitch, height, total size in bytes, macro-tile dimensions and slice size* -*************************************************************************************************** -*/ -UINT_32 AddrLib::ComputeHtileInfo( - ADDR_HTILE_FLAGS flags, ///< [in] htile flags - UINT_32 pitchIn, ///< [in] pitch input - UINT_32 heightIn, ///< [in] height input - UINT_32 numSlices, ///< [in] number of slices - BOOL_32 isLinear, ///< [in] if it is linear mode - BOOL_32 isWidth8, ///< [in] if htile block width is 8 - BOOL_32 isHeight8, ///< [in] if htile block height is 8 - ADDR_TILEINFO* pTileInfo, ///< [in] Tile info - UINT_32* pPitchOut, ///< [out] pitch output - UINT_32* pHeightOut, ///< [out] height output - UINT_64* pHtileBytes, ///< [out] bytes per 2D slice - UINT_32* pMacroWidth, ///< [out] macro-tile width in pixels - UINT_32* pMacroHeight, ///< [out] macro-tile width in pixels - UINT_64* pSliceSize, ///< [out] slice size in bytes - UINT_32* pBaseAlign ///< [out] base alignment - ) const -{ - - UINT_32 macroWidth; - UINT_32 macroHeight; - UINT_32 baseAlign; - UINT_64 surfBytes; - UINT_64 sliceBytes; - - numSlices = Max(1u, numSlices); - - const UINT_32 bpp = HwlComputeHtileBpp(isWidth8, isHeight8); - const UINT_32 cacheBits = HtileCacheBits; - - if (isLinear) - { - HwlComputeTileDataWidthAndHeightLinear(¯oWidth, - ¯oHeight, - bpp, - pTileInfo); - } - else - { - ComputeTileDataWidthAndHeight(bpp, - cacheBits, - pTileInfo, - ¯oWidth, - ¯oHeight); - } - - *pPitchOut = PowTwoAlign(pitchIn, macroWidth); - *pHeightOut = PowTwoAlign(heightIn, macroHeight); - - baseAlign = HwlComputeHtileBaseAlign(flags.tcCompatible, isLinear, pTileInfo); - - surfBytes = HwlComputeHtileBytes(*pPitchOut, - *pHeightOut, - bpp, - isLinear, - numSlices, - &sliceBytes, - baseAlign); - - *pHtileBytes = surfBytes; - - // - // Use SafeAssign since they are optional - // - SafeAssign(pMacroWidth, macroWidth); - - SafeAssign(pMacroHeight, macroHeight); - - SafeAssign(pSliceSize, sliceBytes); - - SafeAssign(pBaseAlign, baseAlign); - - return bpp; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeCmaskBaseAlign -* -* @brief -* Compute cmask base alignment -* -* @return -* Cmask base alignment -*************************************************************************************************** -*/ -UINT_32 AddrLib::ComputeCmaskBaseAlign( - ADDR_CMASK_FLAGS flags, ///< [in] Cmask flags - ADDR_TILEINFO* pTileInfo ///< [in] Tile info - ) const -{ - UINT_32 baseAlign = m_pipeInterleaveBytes * HwlGetPipes(pTileInfo); - - if (flags.tcCompatible) - { - ADDR_ASSERT(pTileInfo != NULL); - if (pTileInfo) - { - baseAlign *= pTileInfo->banks; - } - } - - return baseAlign; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeCmaskBytes -* -* @brief -* Compute cmask size in bytes -* -* @return -* Cmask size in bytes -*************************************************************************************************** -*/ -UINT_64 AddrLib::ComputeCmaskBytes( - UINT_32 pitch, ///< [in] pitch - UINT_32 height, ///< [in] height - UINT_32 numSlices ///< [in] number of slices - ) const -{ - return BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * numSlices * CmaskElemBits) / - MicroTilePixels; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeCmaskInfo -* -* @brief -* Compute cmask pitch,width, bytes per 2D slice -* -* @return -* BlockMax. Also by output parameters: Cmask pitch,height, total size in bytes, -* macro-tile dimensions -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputeCmaskInfo( - ADDR_CMASK_FLAGS flags, ///< [in] cmask flags - UINT_32 pitchIn, ///< [in] pitch input - UINT_32 heightIn, ///< [in] height input - UINT_32 numSlices, ///< [in] number of slices - BOOL_32 isLinear, ///< [in] is linear mode - ADDR_TILEINFO* pTileInfo, ///< [in] Tile info - UINT_32* pPitchOut, ///< [out] pitch output - UINT_32* pHeightOut, ///< [out] height output - UINT_64* pCmaskBytes, ///< [out] bytes per 2D slice - UINT_32* pMacroWidth, ///< [out] macro-tile width in pixels - UINT_32* pMacroHeight, ///< [out] macro-tile width in pixels - UINT_64* pSliceSize, ///< [out] slice size in bytes - UINT_32* pBaseAlign, ///< [out] base alignment - UINT_32* pBlockMax ///< [out] block max == slice / 128 / 128 - 1 - ) const -{ - UINT_32 macroWidth; - UINT_32 macroHeight; - UINT_32 baseAlign; - UINT_64 surfBytes; - UINT_64 sliceBytes; - - numSlices = Max(1u, numSlices); - - const UINT_32 bpp = CmaskElemBits; - const UINT_32 cacheBits = CmaskCacheBits; - - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - if (isLinear) - { - HwlComputeTileDataWidthAndHeightLinear(¯oWidth, - ¯oHeight, - bpp, - pTileInfo); - } - else - { - ComputeTileDataWidthAndHeight(bpp, - cacheBits, - pTileInfo, - ¯oWidth, - ¯oHeight); - } - - *pPitchOut = (pitchIn + macroWidth - 1) & ~(macroWidth - 1); - *pHeightOut = (heightIn + macroHeight - 1) & ~(macroHeight - 1); - - - sliceBytes = ComputeCmaskBytes(*pPitchOut, - *pHeightOut, - 1); - - baseAlign = ComputeCmaskBaseAlign(flags, pTileInfo); - - while (sliceBytes % baseAlign) - { - *pHeightOut += macroHeight; - - sliceBytes = ComputeCmaskBytes(*pPitchOut, - *pHeightOut, - 1); - } - - surfBytes = sliceBytes * numSlices; - - *pCmaskBytes = surfBytes; - - // - // Use SafeAssign since they are optional - // - SafeAssign(pMacroWidth, macroWidth); - - SafeAssign(pMacroHeight, macroHeight); - - SafeAssign(pBaseAlign, baseAlign); - - SafeAssign(pSliceSize, sliceBytes); - - UINT_32 slice = (*pPitchOut) * (*pHeightOut); - UINT_32 blockMax = slice / 128 / 128 - 1; - -#if DEBUG - if (slice % (64*256) != 0) - { - ADDR_ASSERT_ALWAYS(); - } -#endif //DEBUG - - UINT_32 maxBlockMax = HwlGetMaxCmaskBlockMax(); - - if (blockMax > maxBlockMax) - { - blockMax = maxBlockMax; - returnCode = ADDR_INVALIDPARAMS; - } - - SafeAssign(pBlockMax, blockMax); - - return returnCode; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeXmaskCoordYFromPipe -* -* @brief -* Compute the Y coord from pipe number for cmask/htile -* -* @return -* Y coordinate -* -*************************************************************************************************** -*/ -UINT_32 AddrLib::ComputeXmaskCoordYFromPipe( - UINT_32 pipe, ///< [in] pipe number - UINT_32 x ///< [in] x coordinate - ) const -{ - UINT_32 pipeBit0; - UINT_32 pipeBit1; - UINT_32 xBit0; - UINT_32 xBit1; - UINT_32 yBit0; - UINT_32 yBit1; - - UINT_32 y = 0; - - UINT_32 numPipes = m_pipes; // SI has its implementation - // - // Convert pipe + x to y coordinate. - // - switch (numPipes) - { - case 1: - // - // 1 pipe - // - // p0 = 0 - // - y = 0; - break; - case 2: - // - // 2 pipes - // - // p0 = x0 ^ y0 - // - // y0 = p0 ^ x0 - // - pipeBit0 = pipe & 0x1; - - xBit0 = x & 0x1; - - yBit0 = pipeBit0 ^ xBit0; - - y = yBit0; - break; - case 4: - // - // 4 pipes - // - // p0 = x1 ^ y0 - // p1 = x0 ^ y1 - // - // y0 = p0 ^ x1 - // y1 = p1 ^ x0 - // - pipeBit0 = pipe & 0x1; - pipeBit1 = (pipe & 0x2) >> 1; - - xBit0 = x & 0x1; - xBit1 = (x & 0x2) >> 1; - - yBit0 = pipeBit0 ^ xBit1; - yBit1 = pipeBit1 ^ xBit0; - - y = (yBit0 | - (yBit1 << 1)); - break; - case 8: - // - // 8 pipes - // - // r600 and r800 have different method - // - y = HwlComputeXmaskCoordYFrom8Pipe(pipe, x); - break; - default: - break; - } - return y; -} - -/** -*************************************************************************************************** -* AddrLib::HwlComputeXmaskCoordFromAddr -* -* @brief -* Compute the coord from an address of a cmask/htile -* -* @return -* N/A -* -* @note -* This method is reused by htile, so rename to Xmask -*************************************************************************************************** -*/ -VOID AddrLib::HwlComputeXmaskCoordFromAddr( - UINT_64 addr, ///< [in] address - UINT_32 bitPosition, ///< [in] bitPosition in a byte - UINT_32 pitch, ///< [in] pitch - UINT_32 height, ///< [in] height - UINT_32 numSlices, ///< [in] number of slices - UINT_32 factor, ///< [in] factor that indicates cmask or htile - BOOL_32 isLinear, ///< [in] linear or tiled HTILE layout - BOOL_32 isWidth8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value - BOOL_32 isHeight8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value - ADDR_TILEINFO* pTileInfo, ///< [in] Tile info - UINT_32* pX, ///< [out] x coord - UINT_32* pY, ///< [out] y coord - UINT_32* pSlice ///< [out] slice index - ) const -{ - UINT_32 pipe; - UINT_32 numPipes; - UINT_32 numPipeBits; - UINT_32 macroTilePitch; - UINT_32 macroTileHeight; - - UINT_64 bitAddr; - - UINT_32 microTileCoordY; - - UINT_32 elemBits; - - UINT_32 pitchAligned = pitch; - UINT_32 heightAligned = height; - UINT_64 totalBytes; - - UINT_64 elemOffset; - - UINT_64 macroIndex; - UINT_32 microIndex; - - UINT_64 macroNumber; - UINT_32 microNumber; - - UINT_32 macroX; - UINT_32 macroY; - UINT_32 macroZ; - - UINT_32 microX; - UINT_32 microY; - - UINT_32 tilesPerMacro; - UINT_32 macrosPerPitch; - UINT_32 macrosPerSlice; - - // - // Extract pipe. - // - numPipes = HwlGetPipes(pTileInfo); - pipe = ComputePipeFromAddr(addr, numPipes); - - // - // Compute the number of group and pipe bits. - // - numPipeBits = Log2(numPipes); - - UINT_32 groupBits = 8 * m_pipeInterleaveBytes; - UINT_32 pipes = numPipes; - - - // - // Compute the micro tile size, in bits. And macro tile pitch and height. - // - if (factor == 2) //CMASK - { - ADDR_CMASK_FLAGS flags = {{0}}; - - elemBits = CmaskElemBits; - - ComputeCmaskInfo(flags, - pitch, - height, - numSlices, - isLinear, - pTileInfo, - &pitchAligned, - &heightAligned, - &totalBytes, - ¯oTilePitch, - ¯oTileHeight); - } - else //HTILE - { - ADDR_HTILE_FLAGS flags = {{0}}; - - if (factor != 1) - { - factor = 1; - } - - elemBits = HwlComputeHtileBpp(isWidth8, isHeight8); - - ComputeHtileInfo(flags, - pitch, - height, - numSlices, - isLinear, - isWidth8, - isHeight8, - pTileInfo, - &pitchAligned, - &heightAligned, - &totalBytes, - ¯oTilePitch, - ¯oTileHeight); - } - - // Should use aligned dims - // - pitch = pitchAligned; - height = heightAligned; - - - // - // Convert byte address to bit address. - // - bitAddr = BYTES_TO_BITS(addr) + bitPosition; - - - // - // Remove pipe bits from address. - // - - bitAddr = (bitAddr % groupBits) + ((bitAddr/groupBits/pipes)*groupBits); - - - elemOffset = bitAddr / elemBits; - - tilesPerMacro = (macroTilePitch/factor) * macroTileHeight / MicroTilePixels >> numPipeBits; - - macrosPerPitch = pitch / (macroTilePitch/factor); - macrosPerSlice = macrosPerPitch * height / macroTileHeight; - - macroIndex = elemOffset / factor / tilesPerMacro; - microIndex = static_cast<UINT_32>(elemOffset % (tilesPerMacro * factor)); - - macroNumber = macroIndex * factor + microIndex % factor; - microNumber = microIndex / factor; - - macroX = static_cast<UINT_32>((macroNumber % macrosPerPitch)); - macroY = static_cast<UINT_32>((macroNumber % macrosPerSlice) / macrosPerPitch); - macroZ = static_cast<UINT_32>((macroNumber / macrosPerSlice)); - - - microX = microNumber % (macroTilePitch / factor / MicroTileWidth); - microY = (microNumber / (macroTilePitch / factor / MicroTileHeight)); - - *pX = macroX * (macroTilePitch/factor) + microX * MicroTileWidth; - *pY = macroY * macroTileHeight + (microY * MicroTileHeight << numPipeBits); - *pSlice = macroZ; - - microTileCoordY = ComputeXmaskCoordYFromPipe(pipe, - *pX/MicroTileWidth); - - - // - // Assemble final coordinates. - // - *pY += microTileCoordY * MicroTileHeight; - -} - -/** -*************************************************************************************************** -* AddrLib::HwlComputeXmaskAddrFromCoord -* -* @brief -* Compute the address from an address of cmask (prior to si) -* -* @return -* Address in bytes -* -*************************************************************************************************** -*/ -UINT_64 AddrLib::HwlComputeXmaskAddrFromCoord( - UINT_32 pitch, ///< [in] pitch - UINT_32 height, ///< [in] height - UINT_32 x, ///< [in] x coord - UINT_32 y, ///< [in] y coord - UINT_32 slice, ///< [in] slice/depth index - UINT_32 numSlices, ///< [in] number of slices - UINT_32 factor, ///< [in] factor that indicates cmask(2) or htile(1) - BOOL_32 isLinear, ///< [in] linear or tiled HTILE layout - BOOL_32 isWidth8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value - BOOL_32 isHeight8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value - ADDR_TILEINFO* pTileInfo, ///< [in] Tile info - UINT_32* pBitPosition ///< [out] bit position inside a byte - ) const -{ - UINT_64 addr; - UINT_32 numGroupBits; - UINT_32 numPipeBits; - UINT_32 newPitch = 0; - UINT_32 newHeight = 0; - UINT_64 sliceBytes = 0; - UINT_64 totalBytes = 0; - UINT_64 sliceOffset; - UINT_32 pipe; - UINT_32 macroTileWidth; - UINT_32 macroTileHeight; - UINT_32 macroTilesPerRow; - UINT_32 macroTileBytes; - UINT_32 macroTileIndexX; - UINT_32 macroTileIndexY; - UINT_64 macroTileOffset; - UINT_32 pixelBytesPerRow; - UINT_32 pixelOffsetX; - UINT_32 pixelOffsetY; - UINT_32 pixelOffset; - UINT_64 totalOffset; - UINT_64 offsetLo; - UINT_64 offsetHi; - UINT_64 groupMask; - - - UINT_32 elemBits = 0; - - UINT_32 numPipes = m_pipes; // This function is accessed prior to si only - - if (factor == 2) //CMASK - { - elemBits = CmaskElemBits; - - // For asics before SI, cmask is always tiled - isLinear = FALSE; - } - else //HTILE - { - if (factor != 1) // Fix compile warning - { - factor = 1; - } - - elemBits = HwlComputeHtileBpp(isWidth8, isHeight8); - } - - // - // Compute the number of group bits and pipe bits. - // - numGroupBits = Log2(m_pipeInterleaveBytes); - numPipeBits = Log2(numPipes); - - // - // Compute macro tile dimensions. - // - if (factor == 2) // CMASK - { - ADDR_CMASK_FLAGS flags = {{0}}; - - ComputeCmaskInfo(flags, - pitch, - height, - numSlices, - isLinear, - pTileInfo, - &newPitch, - &newHeight, - &totalBytes, - ¯oTileWidth, - ¯oTileHeight); - - sliceBytes = totalBytes / numSlices; - } - else // HTILE - { - ADDR_HTILE_FLAGS flags = {{0}}; - - ComputeHtileInfo(flags, - pitch, - height, - numSlices, - isLinear, - isWidth8, - isHeight8, - pTileInfo, - &newPitch, - &newHeight, - &totalBytes, - ¯oTileWidth, - ¯oTileHeight, - &sliceBytes); - } - - sliceOffset = slice * sliceBytes; - - // - // Get the pipe. Note that neither slice rotation nor pipe swizzling apply for CMASK. - // - pipe = ComputePipeFromCoord(x, - y, - 0, - ADDR_TM_2D_TILED_THIN1, - 0, - FALSE, - pTileInfo); - - // - // Compute the number of macro tiles per row. - // - macroTilesPerRow = newPitch / macroTileWidth; - - // - // Compute the number of bytes per macro tile. - // - macroTileBytes = BITS_TO_BYTES((macroTileWidth * macroTileHeight * elemBits) / MicroTilePixels); - - // - // Compute the offset to the macro tile containing the specified coordinate. - // - macroTileIndexX = x / macroTileWidth; - macroTileIndexY = y / macroTileHeight; - macroTileOffset = ((macroTileIndexY * macroTilesPerRow) + macroTileIndexX) * macroTileBytes; - - // - // Compute the pixel offset within the macro tile. - // - pixelBytesPerRow = BITS_TO_BYTES(macroTileWidth * elemBits) / MicroTileWidth; - - // - // The nibbles are interleaved (see below), so the part of the offset relative to the x - // coordinate repeats halfway across the row. (Not for HTILE) - // - if (factor == 2) - { - pixelOffsetX = (x % (macroTileWidth / 2)) / MicroTileWidth; - } - else - { - pixelOffsetX = (x % (macroTileWidth)) / MicroTileWidth * BITS_TO_BYTES(elemBits); - } - - // - // Compute the y offset within the macro tile. - // - pixelOffsetY = (((y % macroTileHeight) / MicroTileHeight) / numPipes) * pixelBytesPerRow; - - pixelOffset = pixelOffsetX + pixelOffsetY; - - // - // Combine the slice offset and macro tile offset with the pixel offset, accounting for the - // pipe bits in the middle of the address. - // - totalOffset = ((sliceOffset + macroTileOffset) >> numPipeBits) + pixelOffset; - - // - // Split the offset to put some bits below the pipe bits and some above. - // - groupMask = (1 << numGroupBits) - 1; - offsetLo = totalOffset & groupMask; - offsetHi = (totalOffset & ~groupMask) << numPipeBits; - - // - // Assemble the address from its components. - // - addr = offsetLo; - addr |= offsetHi; - // This is to remove warning with /analyze option - UINT_32 pipeBits = pipe << numGroupBits; - addr |= pipeBits; - - // - // Compute the bit position. The lower nibble is used when the x coordinate within the macro - // tile is less than half of the macro tile width, and the upper nibble is used when the x - // coordinate within the macro tile is greater than or equal to half the macro tile width. - // - *pBitPosition = ((x % macroTileWidth) < (macroTileWidth / factor)) ? 0 : 4; - - return addr; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Surface Addressing Shared -/////////////////////////////////////////////////////////////////////////////////////////////////// - -/** -*************************************************************************************************** -* AddrLib::ComputeSurfaceAddrFromCoordLinear -* -* @brief -* Compute address from coord for linear surface -* -* @return -* Address in bytes -* -*************************************************************************************************** -*/ -UINT_64 AddrLib::ComputeSurfaceAddrFromCoordLinear( - UINT_32 x, ///< [in] x coord - UINT_32 y, ///< [in] y coord - UINT_32 slice, ///< [in] slice/depth index - UINT_32 sample, ///< [in] sample index - UINT_32 bpp, ///< [in] bits per pixel - UINT_32 pitch, ///< [in] pitch - UINT_32 height, ///< [in] height - UINT_32 numSlices, ///< [in] number of slices - UINT_32* pBitPosition ///< [out] bit position inside a byte - ) const -{ - const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height; - - UINT_64 sliceOffset = (slice + sample * numSlices)* sliceSize; - UINT_64 rowOffset = static_cast<UINT_64>(y) * pitch; - UINT_64 pixOffset = x; - - UINT_64 addr = (sliceOffset + rowOffset + pixOffset) * bpp; - - *pBitPosition = static_cast<UINT_32>(addr % 8); - addr /= 8; - - return addr; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeSurfaceCoordFromAddrLinear -* -* @brief -* Compute the coord from an address of a linear surface -* -* @return -* N/A -*************************************************************************************************** -*/ -VOID AddrLib::ComputeSurfaceCoordFromAddrLinear( - UINT_64 addr, ///< [in] address - UINT_32 bitPosition, ///< [in] bitPosition in a byte - UINT_32 bpp, ///< [in] bits per pixel - UINT_32 pitch, ///< [in] pitch - UINT_32 height, ///< [in] height - UINT_32 numSlices, ///< [in] number of slices - UINT_32* pX, ///< [out] x coord - UINT_32* pY, ///< [out] y coord - UINT_32* pSlice, ///< [out] slice/depth index - UINT_32* pSample ///< [out] sample index - ) const -{ - const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height; - const UINT_64 linearOffset = (BYTES_TO_BITS(addr) + bitPosition) / bpp; - - *pX = static_cast<UINT_32>((linearOffset % sliceSize) % pitch); - *pY = static_cast<UINT_32>((linearOffset % sliceSize) / pitch % height); - *pSlice = static_cast<UINT_32>((linearOffset / sliceSize) % numSlices); - *pSample = static_cast<UINT_32>((linearOffset / sliceSize) / numSlices); -} - -/** -*************************************************************************************************** -* AddrLib::ComputeSurfaceCoordFromAddrMicroTiled -* -* @brief -* Compute the coord from an address of a micro tiled surface -* -* @return -* N/A -*************************************************************************************************** -*/ -VOID AddrLib::ComputeSurfaceCoordFromAddrMicroTiled( - UINT_64 addr, ///< [in] address - UINT_32 bitPosition, ///< [in] bitPosition in a byte - UINT_32 bpp, ///< [in] bits per pixel - UINT_32 pitch, ///< [in] pitch - UINT_32 height, ///< [in] height - UINT_32 numSamples, ///< [in] number of samples - AddrTileMode tileMode, ///< [in] tile mode - UINT_32 tileBase, ///< [in] base offset within a tile - UINT_32 compBits, ///< [in] component bits actually needed(for planar surface) - UINT_32* pX, ///< [out] x coord - UINT_32* pY, ///< [out] y coord - UINT_32* pSlice, ///< [out] slice/depth index - UINT_32* pSample, ///< [out] sample index, - AddrTileType microTileType, ///< [in] micro tiling order - BOOL_32 isDepthSampleOrder ///< [in] TRUE if in depth sample order - ) const -{ - UINT_64 bitAddr; - UINT_32 microTileThickness; - UINT_32 microTileBits; - UINT_64 sliceBits; - UINT_64 rowBits; - UINT_32 sliceIndex; - UINT_32 microTileCoordX; - UINT_32 microTileCoordY; - UINT_32 pixelOffset; - UINT_32 pixelCoordX = 0; - UINT_32 pixelCoordY = 0; - UINT_32 pixelCoordZ = 0; - UINT_32 pixelCoordS = 0; - - // - // Convert byte address to bit address. - // - bitAddr = BYTES_TO_BITS(addr) + bitPosition; - - // - // Compute the micro tile size, in bits. - // - switch (tileMode) - { - case ADDR_TM_1D_TILED_THICK: - microTileThickness = ThickTileThickness; - break; - default: - microTileThickness = 1; - break; - } - - microTileBits = MicroTilePixels * microTileThickness * bpp * numSamples; - - // - // Compute number of bits per slice and number of bits per row of micro tiles. - // - sliceBits = static_cast<UINT_64>(pitch) * height * microTileThickness * bpp * numSamples; - - rowBits = (pitch / MicroTileWidth) * microTileBits; - - // - // Extract the slice index. - // - sliceIndex = static_cast<UINT_32>(bitAddr / sliceBits); - bitAddr -= sliceIndex * sliceBits; - - // - // Extract the y coordinate of the micro tile. - // - microTileCoordY = static_cast<UINT_32>(bitAddr / rowBits) * MicroTileHeight; - bitAddr -= (microTileCoordY / MicroTileHeight) * rowBits; - - // - // Extract the x coordinate of the micro tile. - // - microTileCoordX = static_cast<UINT_32>(bitAddr / microTileBits) * MicroTileWidth; - - // - // Compute the pixel offset within the micro tile. - // - pixelOffset = static_cast<UINT_32>(bitAddr % microTileBits); - - // - // Extract pixel coordinates from the offset. - // - HwlComputePixelCoordFromOffset(pixelOffset, - bpp, - numSamples, - tileMode, - tileBase, - compBits, - &pixelCoordX, - &pixelCoordY, - &pixelCoordZ, - &pixelCoordS, - microTileType, - isDepthSampleOrder); - - // - // Assemble final coordinates. - // - *pX = microTileCoordX + pixelCoordX; - *pY = microTileCoordY + pixelCoordY; - *pSlice = (sliceIndex * microTileThickness) + pixelCoordZ; - *pSample = pixelCoordS; - - if (microTileThickness > 1) - { - *pSample = 0; - } -} - -/** -*************************************************************************************************** -* AddrLib::ComputePipeFromAddr -* -* @brief -* Compute the pipe number from an address -* -* @return -* Pipe number -* -*************************************************************************************************** -*/ -UINT_32 AddrLib::ComputePipeFromAddr( - UINT_64 addr, ///< [in] address - UINT_32 numPipes ///< [in] number of banks - ) const -{ - UINT_32 pipe; - - UINT_32 groupBytes = m_pipeInterleaveBytes; //just different terms - - // R600 - // The LSBs of the address are arranged as follows: - // bank | pipe | group - // - // To get the pipe number, shift off the group bits and mask the pipe bits. - // - - // R800 - // The LSBs of the address are arranged as follows: - // bank | bankInterleave | pipe | pipeInterleave - // - // To get the pipe number, shift off the pipe interleave bits and mask the pipe bits. - // - - pipe = static_cast<UINT_32>(addr >> Log2(groupBytes)) & (numPipes - 1); - - return pipe; -} - -/** -*************************************************************************************************** -* AddrLib::ComputePixelIndexWithinMicroTile -* -* @brief -* Compute the pixel index inside a micro tile of surface -* -* @return -* Pixel index -* -*************************************************************************************************** -*/ -UINT_32 AddrLib::ComputePixelIndexWithinMicroTile( - UINT_32 x, ///< [in] x coord - UINT_32 y, ///< [in] y coord - UINT_32 z, ///< [in] slice/depth index - UINT_32 bpp, ///< [in] bits per pixel - AddrTileMode tileMode, ///< [in] tile mode - AddrTileType microTileType ///< [in] pixel order in display/non-display mode - ) const -{ - UINT_32 pixelBit0 = 0; - UINT_32 pixelBit1 = 0; - UINT_32 pixelBit2 = 0; - UINT_32 pixelBit3 = 0; - UINT_32 pixelBit4 = 0; - UINT_32 pixelBit5 = 0; - UINT_32 pixelBit6 = 0; - UINT_32 pixelBit7 = 0; - UINT_32 pixelBit8 = 0; - UINT_32 pixelNumber; - - UINT_32 x0 = _BIT(x, 0); - UINT_32 x1 = _BIT(x, 1); - UINT_32 x2 = _BIT(x, 2); - UINT_32 y0 = _BIT(y, 0); - UINT_32 y1 = _BIT(y, 1); - UINT_32 y2 = _BIT(y, 2); - UINT_32 z0 = _BIT(z, 0); - UINT_32 z1 = _BIT(z, 1); - UINT_32 z2 = _BIT(z, 2); - - UINT_32 thickness = ComputeSurfaceThickness(tileMode); - - // Compute the pixel number within the micro tile. - - if (microTileType != ADDR_THICK) - { - if (microTileType == ADDR_DISPLAYABLE) - { - switch (bpp) - { - case 8: - pixelBit0 = x0; - pixelBit1 = x1; - pixelBit2 = x2; - pixelBit3 = y1; - pixelBit4 = y0; - pixelBit5 = y2; - break; - case 16: - pixelBit0 = x0; - pixelBit1 = x1; - pixelBit2 = x2; - pixelBit3 = y0; - pixelBit4 = y1; - pixelBit5 = y2; - break; - case 32: - pixelBit0 = x0; - pixelBit1 = x1; - pixelBit2 = y0; - pixelBit3 = x2; - pixelBit4 = y1; - pixelBit5 = y2; - break; - case 64: - pixelBit0 = x0; - pixelBit1 = y0; - pixelBit2 = x1; - pixelBit3 = x2; - pixelBit4 = y1; - pixelBit5 = y2; - break; - case 128: - pixelBit0 = y0; - pixelBit1 = x0; - pixelBit2 = x1; - pixelBit3 = x2; - pixelBit4 = y1; - pixelBit5 = y2; - break; - default: - ADDR_ASSERT_ALWAYS(); - break; - } - } - else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER) - { - pixelBit0 = x0; - pixelBit1 = y0; - pixelBit2 = x1; - pixelBit3 = y1; - pixelBit4 = x2; - pixelBit5 = y2; - } - else if (microTileType == ADDR_ROTATED) - { - ADDR_ASSERT(thickness == 1); - - switch (bpp) - { - case 8: - pixelBit0 = y0; - pixelBit1 = y1; - pixelBit2 = y2; - pixelBit3 = x1; - pixelBit4 = x0; - pixelBit5 = x2; - break; - case 16: - pixelBit0 = y0; - pixelBit1 = y1; - pixelBit2 = y2; - pixelBit3 = x0; - pixelBit4 = x1; - pixelBit5 = x2; - break; - case 32: - pixelBit0 = y0; - pixelBit1 = y1; - pixelBit2 = x0; - pixelBit3 = y2; - pixelBit4 = x1; - pixelBit5 = x2; - break; - case 64: - pixelBit0 = y0; - pixelBit1 = x0; - pixelBit2 = y1; - pixelBit3 = x1; - pixelBit4 = x2; - pixelBit5 = y2; - break; - default: - ADDR_ASSERT_ALWAYS(); - break; - } - } - - if (thickness > 1) - { - pixelBit6 = z0; - pixelBit7 = z1; - } - } - else // ADDR_THICK - { - ADDR_ASSERT(thickness > 1); - - switch (bpp) - { - case 8: - case 16: - pixelBit0 = x0; - pixelBit1 = y0; - pixelBit2 = x1; - pixelBit3 = y1; - pixelBit4 = z0; - pixelBit5 = z1; - break; - case 32: - pixelBit0 = x0; - pixelBit1 = y0; - pixelBit2 = x1; - pixelBit3 = z0; - pixelBit4 = y1; - pixelBit5 = z1; - break; - case 64: - case 128: - pixelBit0 = y0; - pixelBit1 = x0; - pixelBit2 = z0; - pixelBit3 = x1; - pixelBit4 = y1; - pixelBit5 = z1; - break; - default: - ADDR_ASSERT_ALWAYS(); - break; - } - - pixelBit6 = x2; - pixelBit7 = y2; - } - - if (thickness == 8) - { - pixelBit8 = z2; - } - - pixelNumber = ((pixelBit0 ) | - (pixelBit1 << 1) | - (pixelBit2 << 2) | - (pixelBit3 << 3) | - (pixelBit4 << 4) | - (pixelBit5 << 5) | - (pixelBit6 << 6) | - (pixelBit7 << 7) | - (pixelBit8 << 8)); - - return pixelNumber; -} - -/** -*************************************************************************************************** -* AddrLib::AdjustPitchAlignment -* -* @brief -* Adjusts pitch alignment for flipping surface -* -* @return -* N/A -* -*************************************************************************************************** -*/ -VOID AddrLib::AdjustPitchAlignment( - ADDR_SURFACE_FLAGS flags, ///< [in] Surface flags - UINT_32* pPitchAlign ///< [out] Pointer to pitch alignment - ) const -{ - // Display engine hardwires lower 5 bit of GRPH_PITCH to ZERO which means 32 pixel alignment - // Maybe it will be fixed in future but let's make it general for now. - if (flags.display || flags.overlay) - { - *pPitchAlign = PowTwoAlign(*pPitchAlign, 32); - - if(flags.display) - { - *pPitchAlign = Max(m_minPitchAlignPixels, *pPitchAlign); - } - } -} - -/** -*************************************************************************************************** -* AddrLib::PadDimensions -* -* @brief -* Helper function to pad dimensions -* -* @return -* N/A -* -*************************************************************************************************** -*/ -VOID AddrLib::PadDimensions( - AddrTileMode tileMode, ///< [in] tile mode - UINT_32 bpp, ///< [in] bits per pixel - ADDR_SURFACE_FLAGS flags, ///< [in] surface flags - UINT_32 numSamples, ///< [in] number of samples - ADDR_TILEINFO* pTileInfo, ///< [in/out] bank structure. - UINT_32 padDims, ///< [in] Dimensions to pad valid value 1,2,3 - UINT_32 mipLevel, ///< [in] MipLevel - UINT_32* pPitch, ///< [in/out] pitch in pixels - UINT_32 pitchAlign, ///< [in] pitch alignment - UINT_32* pHeight, ///< [in/out] height in pixels - UINT_32 heightAlign, ///< [in] height alignment - UINT_32* pSlices, ///< [in/out] number of slices - UINT_32 sliceAlign ///< [in] number of slice alignment - ) const -{ - UINT_32 thickness = ComputeSurfaceThickness(tileMode); - - ADDR_ASSERT(padDims <= 3); - - // - // Override padding for mip levels - // - if (mipLevel > 0) - { - if (flags.cube) - { - // for cubemap, we only pad when client call with 6 faces as an identity - if (*pSlices > 1) - { - padDims = 3; // we should pad cubemap sub levels when we treat it as 3d texture - } - else - { - padDims = 2; - } - } - } - - // Any possibilities that padDims is 0? - if (padDims == 0) - { - padDims = 3; - } - - if (IsPow2(pitchAlign)) - { - *pPitch = PowTwoAlign((*pPitch), pitchAlign); - } - else // add this code to pass unit test, r600 linear mode is not align bpp to pow2 for linear - { - *pPitch += pitchAlign - 1; - *pPitch /= pitchAlign; - *pPitch *= pitchAlign; - } - - if (padDims > 1) - { - *pHeight = PowTwoAlign((*pHeight), heightAlign); - } - - if (padDims > 2 || thickness > 1) - { - // for cubemap single face, we do not pad slices. - // if we pad it, the slice number should be set to 6 and current mip level > 1 - if (flags.cube && (!m_configFlags.noCubeMipSlicesPad || flags.cubeAsArray)) - { - *pSlices = NextPow2(*pSlices); - } - - // normal 3D texture or arrays or cubemap has a thick mode? (Just pass unit test) - if (thickness > 1) - { - *pSlices = PowTwoAlign((*pSlices), sliceAlign); - } - - } - - HwlPadDimensions(tileMode, - bpp, - flags, - numSamples, - pTileInfo, - padDims, - mipLevel, - pPitch, - pitchAlign, - pHeight, - heightAlign, - pSlices, - sliceAlign); -} - - -/** -*************************************************************************************************** -* AddrLib::HwlPreHandleBaseLvl3xPitch -* -* @brief -* Pre-handler of 3x pitch (96 bit) adjustment -* -* @return -* Expected pitch -*************************************************************************************************** -*/ -UINT_32 AddrLib::HwlPreHandleBaseLvl3xPitch( - const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input - UINT_32 expPitch ///< [in] pitch - ) const -{ - ADDR_ASSERT(pIn->width == expPitch); - // - // If pitch is pre-multiplied by 3, we retrieve original one here to get correct miplevel size - // - if (AddrElemLib::IsExpand3x(pIn->format) && - pIn->mipLevel == 0 && - pIn->tileMode == ADDR_TM_LINEAR_ALIGNED) - { - expPitch /= 3; - expPitch = NextPow2(expPitch); - } - - return expPitch; -} - -/** -*************************************************************************************************** -* AddrLib::HwlPostHandleBaseLvl3xPitch -* -* @brief -* Post-handler of 3x pitch adjustment -* -* @return -* Expected pitch -*************************************************************************************************** -*/ -UINT_32 AddrLib::HwlPostHandleBaseLvl3xPitch( - const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input - UINT_32 expPitch ///< [in] pitch - ) const -{ - // - // 96 bits surface of sub levels require element pitch of 32 bits instead - // So we just return pitch in 32 bit pixels without timing 3 - // - if (AddrElemLib::IsExpand3x(pIn->format) && - pIn->mipLevel == 0 && - pIn->tileMode == ADDR_TM_LINEAR_ALIGNED) - { - expPitch *= 3; - } - - return expPitch; -} - - -/** -*************************************************************************************************** -* AddrLib::IsMacroTiled -* -* @brief -* Check if the tile mode is macro tiled -* -* @return -* TRUE if it is macro tiled (2D/2B/3D/3B) -*************************************************************************************************** -*/ -BOOL_32 AddrLib::IsMacroTiled( - AddrTileMode tileMode) ///< [in] tile mode -{ - return m_modeFlags[tileMode].isMacro; -} - -/** -*************************************************************************************************** -* AddrLib::IsMacro3dTiled -* -* @brief -* Check if the tile mode is 3D macro tiled -* -* @return -* TRUE if it is 3D macro tiled -*************************************************************************************************** -*/ -BOOL_32 AddrLib::IsMacro3dTiled( - AddrTileMode tileMode) ///< [in] tile mode -{ - return m_modeFlags[tileMode].isMacro3d; -} - -/** -*************************************************************************************************** -* AddrLib::IsMicroTiled -* -* @brief -* Check if the tile mode is micro tiled -* -* @return -* TRUE if micro tiled -*************************************************************************************************** -*/ -BOOL_32 AddrLib::IsMicroTiled( - AddrTileMode tileMode) ///< [in] tile mode -{ - return m_modeFlags[tileMode].isMicro; -} - -/** -*************************************************************************************************** -* AddrLib::IsLinear -* -* @brief -* Check if the tile mode is linear -* -* @return -* TRUE if linear -*************************************************************************************************** -*/ -BOOL_32 AddrLib::IsLinear( - AddrTileMode tileMode) ///< [in] tile mode -{ - return m_modeFlags[tileMode].isLinear; -} - -/** -*************************************************************************************************** -* AddrLib::IsPrtNoRotationTileMode -* -* @brief -* Return TRUE if it is prt tile without rotation -* @note -* This function just used by CI -*************************************************************************************************** -*/ -BOOL_32 AddrLib::IsPrtNoRotationTileMode( - AddrTileMode tileMode) -{ - return m_modeFlags[tileMode].isPrtNoRotation; -} - -/** -*************************************************************************************************** -* AddrLib::IsPrtTileMode -* -* @brief -* Return TRUE if it is prt tile -* @note -* This function just used by CI -*************************************************************************************************** -*/ -BOOL_32 AddrLib::IsPrtTileMode( - AddrTileMode tileMode) -{ - return m_modeFlags[tileMode].isPrt; -} - -/** -*************************************************************************************************** * AddrLib::Bits2Number * * @brief @@ -3494,299 +401,6 @@ UINT_32 AddrLib::Bits2Number( return number; } -/** -*************************************************************************************************** -* AddrLib::ComputeMipLevel -* -* @brief -* Compute mipmap level width/height/slices -* @return -* N/A -*************************************************************************************************** -*/ -VOID AddrLib::ComputeMipLevel( - ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in/out] Input structure - ) const -{ - if (AddrElemLib::IsBlockCompressed(pIn->format)) - { - if (pIn->mipLevel == 0) - { - // DXTn's level 0 must be multiple of 4 - // But there are exceptions: - // 1. Internal surface creation in hostblt/vsblt/etc... - // 2. Runtime doesn't reject ATI1/ATI2 whose width/height are not multiple of 4 - pIn->width = PowTwoAlign(pIn->width, 4); - pIn->height = PowTwoAlign(pIn->height, 4); - } - } - - HwlComputeMipLevel(pIn); -} - -/** -*************************************************************************************************** -* AddrLib::OptimizeTileMode -* -* @brief -* Check if base level's tile mode can be optimized (degraded) -* @return -* TRUE if degraded, also returns degraded tile mode (unchanged if not degraded) -*************************************************************************************************** -*/ -BOOL_32 AddrLib::OptimizeTileMode( - const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure for surface info - AddrTileMode* pTileMode ///< [out] Degraded tile mode - ) const -{ - AddrTileMode tileMode = pIn->tileMode; - UINT_32 thickness = ComputeSurfaceThickness(tileMode); - - // Optimization can only be done on level 0 and samples <= 1 - if ((pIn->flags.opt4Space == TRUE) && - (pIn->mipLevel == 0) && - (pIn->numSamples <= 1) && - (pIn->flags.display == FALSE) && - (IsPrtTileMode(tileMode) == FALSE) && - (pIn->flags.prt == FALSE)) - { - // Check if linear mode is optimal - if ((pIn->height == 1) && - (IsLinear(tileMode) == FALSE) && - (AddrElemLib::IsBlockCompressed(pIn->format) == FALSE) && - (pIn->flags.depth == FALSE) && - (pIn->flags.stencil == FALSE) && - (m_configFlags.disableLinearOpt == FALSE) && - (pIn->flags.disableLinearOpt == FALSE)) - { - tileMode = ADDR_TM_LINEAR_ALIGNED; - } - else if (IsMacroTiled(tileMode)) - { - if (HwlDegradeBaseLevel(pIn)) - { - tileMode = (thickness == 1) ? ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK; - } - else if (thickness > 1) - { - // As in the following HwlComputeSurfaceInfo, thick modes may be degraded to - // thinner modes, we should re-evaluate whether the corresponding thinner modes - // need to be degraded. If so, we choose 1D thick mode instead. - tileMode = DegradeLargeThickTile(pIn->tileMode, pIn->bpp); - if (tileMode != pIn->tileMode) - { - ADDR_COMPUTE_SURFACE_INFO_INPUT input = *pIn; - input.tileMode = tileMode; - if (HwlDegradeBaseLevel(&input)) - { - tileMode = ADDR_TM_1D_TILED_THICK; - } - } - } - } - } - - BOOL_32 optimized = (tileMode != pIn->tileMode); - if (optimized) - { - *pTileMode = tileMode; - } - return optimized; -} - -/** -*************************************************************************************************** -* AddrLib::DegradeLargeThickTile -* -* @brief -* Check if the thickness needs to be reduced if a tile is too large -* @return -* The degraded tile mode (unchanged if not degraded) -*************************************************************************************************** -*/ -AddrTileMode AddrLib::DegradeLargeThickTile( - AddrTileMode tileMode, - UINT_32 bpp) const -{ - // Override tilemode - // When tile_width (8) * tile_height (8) * thickness * element_bytes is > row_size, - // it is better to just use THIN mode in this case - UINT_32 thickness = ComputeSurfaceThickness(tileMode); - - if (thickness > 1 && m_configFlags.allowLargeThickTile == 0) - { - UINT_32 tileSize = MicroTilePixels * thickness * (bpp >> 3); - - if (tileSize > m_rowSize) - { - switch (tileMode) - { - case ADDR_TM_2D_TILED_XTHICK: - if ((tileSize >> 1) <= m_rowSize) - { - tileMode = ADDR_TM_2D_TILED_THICK; - break; - } - // else fall through - case ADDR_TM_2D_TILED_THICK: - tileMode = ADDR_TM_2D_TILED_THIN1; - break; - - case ADDR_TM_3D_TILED_XTHICK: - if ((tileSize >> 1) <= m_rowSize) - { - tileMode = ADDR_TM_3D_TILED_THICK; - break; - } - // else fall through - case ADDR_TM_3D_TILED_THICK: - tileMode = ADDR_TM_3D_TILED_THIN1; - break; - - case ADDR_TM_PRT_TILED_THICK: - tileMode = ADDR_TM_PRT_TILED_THIN1; - break; - - case ADDR_TM_PRT_2D_TILED_THICK: - tileMode = ADDR_TM_PRT_2D_TILED_THIN1; - break; - - case ADDR_TM_PRT_3D_TILED_THICK: - tileMode = ADDR_TM_PRT_3D_TILED_THIN1; - break; - - default: - break; - } - } - } - - return tileMode; -} - -/** -*************************************************************************************************** -* AddrLib::PostComputeMipLevel -* @brief -* Compute MipLevel info (including level 0) after surface adjustment -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::PostComputeMipLevel( - ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in/out] Input structure - ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] Output structure - ) const -{ - // Mipmap including level 0 must be pow2 padded since either SI hw expects so or it is - // required by CFX for Hw Compatibility between NI and SI. Otherwise it is only needed for - // mipLevel > 0. Any h/w has different requirement should implement its own virtual function - - if (pIn->flags.pow2Pad) - { - pIn->width = NextPow2(pIn->width); - pIn->height = NextPow2(pIn->height); - pIn->numSlices = NextPow2(pIn->numSlices); - } - else if (pIn->mipLevel > 0) - { - pIn->width = NextPow2(pIn->width); - pIn->height = NextPow2(pIn->height); - - if (!pIn->flags.cube) - { - pIn->numSlices = NextPow2(pIn->numSlices); - } - - // for cubemap, we keep its value at first - } - - return ADDR_OK; -} - -/** -*************************************************************************************************** -* AddrLib::HwlSetupTileCfg -* -* @brief -* Map tile index to tile setting. -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::HwlSetupTileCfg( - INT_32 index, ///< [in] Tile index - INT_32 macroModeIndex, ///< [in] Index in macro tile mode table(CI) - ADDR_TILEINFO* pInfo, ///< [out] Tile Info - AddrTileMode* pMode, ///< [out] Tile mode - AddrTileType* pType ///< [out] Tile type - ) const -{ - return ADDR_NOTSUPPORTED; -} - -/** -*************************************************************************************************** -* AddrLib::HwlGetPipes -* -* @brief -* Get number pipes -* @return -* num pipes -*************************************************************************************************** -*/ -UINT_32 AddrLib::HwlGetPipes( - const ADDR_TILEINFO* pTileInfo ///< [in] Tile info - ) const -{ - //pTileInfo can be NULL when asic is 6xx and 8xx. - return m_pipes; -} - -/** -*************************************************************************************************** -* AddrLib::ComputeQbStereoInfo -* -* @brief -* Get quad buffer stereo information -* @return -* TRUE if no error -*************************************************************************************************** -*/ -BOOL_32 AddrLib::ComputeQbStereoInfo( - ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in/out] updated pOut+pStereoInfo - ) const -{ - BOOL_32 success = FALSE; - - if (pOut->pStereoInfo) - { - ADDR_ASSERT(pOut->bpp >= 8); - ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0); - - // Save original height - pOut->pStereoInfo->eyeHeight = pOut->height; - - // Right offset - pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize); - - pOut->pStereoInfo->rightSwizzle = HwlComputeQbStereoRightSwizzle(pOut); - // Double height - pOut->height <<= 1; - pOut->pixelHeight <<= 1; - - // Double size - pOut->surfSize <<= 1; - - // Right start address meets the base align since it is guaranteed by AddrLib - - // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo. - success = TRUE; - } - - return success; -} - /////////////////////////////////////////////////////////////////////////////////////////////////// // Element lib /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -3944,132 +558,3 @@ BOOL_32 AddrLib::GetExportNorm( return enabled; } -/** -*************************************************************************************************** -* AddrLib::ComputePrtInfo -* -* @brief -* Compute prt surface related info -* -* @return -* ADDR_E_RETURNCODE -*************************************************************************************************** -*/ -ADDR_E_RETURNCODE AddrLib::ComputePrtInfo( - const ADDR_PRT_INFO_INPUT* pIn, - ADDR_PRT_INFO_OUTPUT* pOut) const -{ - ADDR_ASSERT(pOut != NULL); - - ADDR_E_RETURNCODE returnCode = ADDR_OK; - - UINT_32 expandX = 1; - UINT_32 expandY = 1; - AddrElemMode elemMode; - - UINT_32 bpp = GetElemLib()->GetBitsPerPixel(pIn->format, - &elemMode, - &expandX, - &expandY); - - if (bpp <8 || bpp == 24 || bpp == 48 || bpp == 96 ) - { - returnCode = ADDR_INVALIDPARAMS; - } - - UINT_32 numFrags = pIn->numFrags; - ADDR_ASSERT(numFrags <= 8); - - UINT_32 tileWidth = 0; - UINT_32 tileHeight = 0; - if (returnCode == ADDR_OK) - { - // 3D texture without depth or 2d texture - if (pIn->baseMipDepth > 1 || pIn->baseMipHeight > 1) - { - if (bpp == 8) - { - tileWidth = 256; - tileHeight = 256; - } - else if (bpp == 16) - { - tileWidth = 256; - tileHeight = 128; - } - else if (bpp == 32) - { - tileWidth = 128; - tileHeight = 128; - } - else if (bpp == 64) - { - // assume it is BC1/4 - tileWidth = 512; - tileHeight = 256; - - if (elemMode == ADDR_UNCOMPRESSED) - { - tileWidth = 128; - tileHeight = 64; - } - } - else if (bpp == 128) - { - // assume it is BC2/3/5/6H/7 - tileWidth = 256; - tileHeight = 256; - - if (elemMode == ADDR_UNCOMPRESSED) - { - tileWidth = 64; - tileHeight = 64; - } - } - - if (numFrags == 2) - { - tileWidth = tileWidth / 2; - } - else if (numFrags == 4) - { - tileWidth = tileWidth / 2; - tileHeight = tileHeight / 2; - } - else if (numFrags == 8) - { - tileWidth = tileWidth / 4; - tileHeight = tileHeight / 2; - } - } - else // 1d - { - tileHeight = 1; - if (bpp == 8) - { - tileWidth = 65536; - } - else if (bpp == 16) - { - tileWidth = 32768; - } - else if (bpp == 32) - { - tileWidth = 16384; - } - else if (bpp == 64) - { - tileWidth = 8192; - } - else if (bpp == 128) - { - tileWidth = 4096; - } - } - } - - pOut->prtTileWidth = tileWidth; - pOut->prtTileHeight = tileHeight; - - return returnCode; -} diff --git a/src/amd/addrlib/core/addrlib.h b/src/amd/addrlib/core/addrlib.h index 3221120f8f7..b369db80483 100644 --- a/src/amd/addrlib/core/addrlib.h +++ b/src/amd/addrlib/core/addrlib.h @@ -136,19 +136,6 @@ enum AddrBankSwapSize /** *************************************************************************************************** -* @brief Neutral enums that define bank swap size -*************************************************************************************************** -*/ -enum AddrSampleSplitSize -{ - ADDR_SAMPLESPLIT_1KB = 1024, - ADDR_SAMPLESPLIT_2KB = 2048, - ADDR_SAMPLESPLIT_4KB = 4096, - ADDR_SAMPLESPLIT_8KB = 8192, -}; - -/** -*************************************************************************************************** * @brief Flags for AddrTileMode *************************************************************************************************** */ diff --git a/src/amd/addrlib/core/addrlib1.cpp b/src/amd/addrlib/core/addrlib1.cpp new file mode 100644 index 00000000000..e44e673d0a9 --- /dev/null +++ b/src/amd/addrlib/core/addrlib1.cpp @@ -0,0 +1,3546 @@ +/* + * Copyright © 2016 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. + */ + +#include "addrinterface.h" +#include "addrlib1.h" +#include "addrcommon.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Static Const Member +/////////////////////////////////////////////////////////////////////////////////////////////////// + +const AddrTileModeFlags AddrLib::m_modeFlags[ADDR_TM_COUNT] = +{// T L 1 2 3 P Pr B + {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_GENERAL + {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_ALIGNED + {1, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THIN1 + {4, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THICK + {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN1 + {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN2 + {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN4 + {4, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THICK + {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN1 + {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN2 + {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN4 + {4, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THICK + {1, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THIN1 + {4, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THICK + {1, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THIN1 + {4, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THICK + {8, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_XTHICK + {8, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_XTHICK + {1, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_POWER_SAVE + {1, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THIN1 + {1, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THIN1 + {1, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THIN1 + {4, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THICK + {4, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THICK + {4, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THICK +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Surface Methods +/////////////////////////////////////////////////////////////////////////////////////////////////// + + +/** +*************************************************************************************************** +* AddrLib::ComputeSurfaceInfo +* +* @brief +* Interface function stub of AddrComputeSurfaceInfo. +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeSurfaceInfo( + const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure + ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + // We suggest client do sanity check but a check here is also good + if (pIn->bpp > 128) + { + returnCode = ADDR_INVALIDPARAMS; + } + + // Thick modes don't support multisample + if (ComputeSurfaceThickness(pIn->tileMode) > 1 && pIn->numSamples > 1) + { + returnCode = ADDR_INVALIDPARAMS; + } + + if (returnCode == ADDR_OK) + { + // Get a local copy of input structure and only reference pIn for unadjusted values + ADDR_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn; + ADDR_TILEINFO tileInfoNull = {0}; + + if (UseTileInfo()) + { + // If the original input has a valid ADDR_TILEINFO pointer then copy its contents. + // Otherwise the default 0's in tileInfoNull are used. + if (pIn->pTileInfo) + { + tileInfoNull = *pIn->pTileInfo; + } + localIn.pTileInfo = &tileInfoNull; + } + + localIn.numSamples = pIn->numSamples == 0 ? 1 : pIn->numSamples; + + // Do mipmap check first + // If format is BCn, pre-pad dimension to power-of-two according to HWL + ComputeMipLevel(&localIn); + + if (m_configFlags.checkLast2DLevel) + { + // Save this level's original height in pixels + pOut->height = pIn->height; + } + + UINT_32 expandX = 1; + UINT_32 expandY = 1; + AddrElemMode elemMode; + + // Save outputs that may not go through HWL + pOut->pixelBits = localIn.bpp; + pOut->numSamples = localIn.numSamples; + pOut->last2DLevel = FALSE; + pOut->tcCompatible = FALSE; + +#if !ALT_TEST + if (localIn.numSamples > 1) + { + ADDR_ASSERT(localIn.mipLevel == 0); + } +#endif + + if (localIn.format != ADDR_FMT_INVALID) // Set format to INVALID will skip this conversion + { + // 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(localIn.tileMode == ADDR_TM_LINEAR_ALIGNED || localIn.height == 1); + } + + GetElemLib()->AdjustSurfaceInfo(elemMode, + expandX, + expandY, + &localIn.bpp, + &localIn.basePitch, + &localIn.width, + &localIn.height); + + // Overwrite these parameters if we have a valid format + } + else if (localIn.bpp != 0) + { + localIn.width = (localIn.width != 0) ? localIn.width : 1; + localIn.height = (localIn.height != 0) ? localIn.height : 1; + } + else // Rule out some invalid parameters + { + ADDR_ASSERT_ALWAYS(); + + returnCode = ADDR_INVALIDPARAMS; + } + + // Check mipmap after surface expansion + if (returnCode == ADDR_OK) + { + returnCode = PostComputeMipLevel(&localIn, pOut); + } + + if (returnCode == ADDR_OK) + { + if (UseTileIndex(localIn.tileIndex)) + { + // Make sure pTileInfo is not NULL + ADDR_ASSERT(localIn.pTileInfo); + + UINT_32 numSamples = GetNumFragments(localIn.numSamples, localIn.numFrags); + + INT_32 macroModeIndex = TileIndexNoMacroIndex; + + if (localIn.tileIndex != TileIndexLinearGeneral) + { + // Try finding a macroModeIndex + macroModeIndex = HwlComputeMacroModeIndex(localIn.tileIndex, + localIn.flags, + localIn.bpp, + numSamples, + localIn.pTileInfo, + &localIn.tileMode, + &localIn.tileType); + } + + // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info + if (macroModeIndex == TileIndexNoMacroIndex) + { + returnCode = HwlSetupTileCfg(localIn.tileIndex, macroModeIndex, + localIn.pTileInfo, + &localIn.tileMode, &localIn.tileType); + } + // If macroModeIndex is invalid, then assert this is not macro tiled + else if (macroModeIndex == TileIndexInvalid) + { + ADDR_ASSERT(!IsMacroTiled(localIn.tileMode)); + } + + pOut->macroModeIndex = macroModeIndex; + } + } + + if (returnCode == ADDR_OK) + { + AddrTileMode tileMode = localIn.tileMode; + AddrTileType tileType = localIn.tileType; + + // HWL layer may override tile mode if necessary + if (HwlOverrideTileMode(&localIn, &tileMode, &tileType)) + { + localIn.tileMode = tileMode; + localIn.tileType = tileType; + } + // Optimize tile mode if possible + if (OptimizeTileMode(&localIn, &tileMode)) + { + localIn.tileMode = tileMode; + } + } + + // Call main function to compute surface info + if (returnCode == ADDR_OK) + { + returnCode = HwlComputeSurfaceInfo(&localIn, pOut); + } + + if (returnCode == ADDR_OK) + { + // Since bpp might be changed we just pass it through + pOut->bpp = localIn.bpp; + + // Also original width/height/bpp + pOut->pixelPitch = pOut->pitch; + pOut->pixelHeight = pOut->height; + +#if DEBUG + if (localIn.flags.display) + { + ADDR_ASSERT((pOut->pitchAlign % 32) == 0); + } +#endif //DEBUG + + if (localIn.format != ADDR_FMT_INVALID) + { + // + // 96 bits surface of level 1+ requires element pitch of 32 bits instead + // In hwl function we skip multiplication of 3 then we should skip division of 3 + // We keep pitch that represents 32 bit element instead of 96 bits since we + // will get an odd number if divided by 3. + // + if (!((expandX == 3) && (localIn.mipLevel > 0))) + { + + GetElemLib()->RestoreSurfaceInfo(elemMode, + expandX, + expandY, + &localIn.bpp, + &pOut->pixelPitch, + &pOut->pixelHeight); + } + } + + if (localIn.flags.qbStereo) + { + if (pOut->pStereoInfo) + { + ComputeQbStereoInfo(pOut); + } + } + + if (localIn.flags.volume) // For volume sliceSize equals to all z-slices + { + pOut->sliceSize = pOut->surfSize; + } + else // For array: sliceSize is likely to have slice-padding (the last one) + { + pOut->sliceSize = pOut->surfSize / pOut->depth; + + // array or cubemap + if (pIn->numSlices > 1) + { + // If this is the last slice then add the padding size to this slice + if (pIn->slice == (pIn->numSlices - 1)) + { + pOut->sliceSize += pOut->sliceSize * (pOut->depth - pIn->numSlices); + } + else if (m_configFlags.checkLast2DLevel) + { + // Reset last2DLevel flag if this is not the last array slice + pOut->last2DLevel = FALSE; + } + } + } + + pOut->pitchTileMax = pOut->pitch / 8 - 1; + pOut->heightTileMax = pOut->height / 8 - 1; + pOut->sliceTileMax = pOut->pitch * pOut->height / 64 - 1; + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeSurfaceInfo +* +* @brief +* Interface function stub of AddrComputeSurfaceInfo. +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeSurfaceAddrFromCoord( + const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure + ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_TILEINFO tileInfoNull; + ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT input; + + if (UseTileIndex(pIn->tileIndex)) + { + input = *pIn; + // Use temp tile info for calcalation + input.pTileInfo = &tileInfoNull; + + const ADDR_SURFACE_FLAGS flags = {{0}}; + UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags); + + // Try finding a macroModeIndex + INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex, + flags, + input.bpp, + numSamples, + input.pTileInfo, + &input.tileMode, + &input.tileType); + + // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info + if (macroModeIndex == TileIndexNoMacroIndex) + { + returnCode = HwlSetupTileCfg(input.tileIndex, macroModeIndex, + input.pTileInfo, &input.tileMode, &input.tileType); + } + // If macroModeIndex is invalid, then assert this is not macro tiled + else if (macroModeIndex == TileIndexInvalid) + { + ADDR_ASSERT(!IsMacroTiled(input.tileMode)); + } + + // Change the input structure + pIn = &input; + } + + if (returnCode == ADDR_OK) + { + returnCode = HwlComputeSurfaceAddrFromCoord(pIn, pOut); + + if (returnCode == ADDR_OK) + { + pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024)); + } + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeSurfaceCoordFromAddr +* +* @brief +* Interface function stub of ComputeSurfaceCoordFromAddr. +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeSurfaceCoordFromAddr( + const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure + ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_TILEINFO tileInfoNull; + ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT input; + + if (UseTileIndex(pIn->tileIndex)) + { + input = *pIn; + // Use temp tile info for calcalation + input.pTileInfo = &tileInfoNull; + + const ADDR_SURFACE_FLAGS flags = {{0}}; + UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags); + + // Try finding a macroModeIndex + INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex, + flags, + input.bpp, + numSamples, + input.pTileInfo, + &input.tileMode, + &input.tileType); + + // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info + if (macroModeIndex == TileIndexNoMacroIndex) + { + returnCode = HwlSetupTileCfg(input.tileIndex, macroModeIndex, + input.pTileInfo, &input.tileMode, &input.tileType); + } + // If macroModeIndex is invalid, then assert this is not macro tiled + else if (macroModeIndex == TileIndexInvalid) + { + ADDR_ASSERT(!IsMacroTiled(input.tileMode)); + } + + // Change the input structure + pIn = &input; + } + + if (returnCode == ADDR_OK) + { + returnCode = HwlComputeSurfaceCoordFromAddr(pIn, pOut); + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeSliceTileSwizzle +* +* @brief +* Interface function stub of ComputeSliceTileSwizzle. +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeSliceTileSwizzle( + const ADDR_COMPUTE_SLICESWIZZLE_INPUT* pIn, ///< [in] input structure + ADDR_COMPUTE_SLICESWIZZLE_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_TILEINFO tileInfoNull; + ADDR_COMPUTE_SLICESWIZZLE_INPUT input; + + if (UseTileIndex(pIn->tileIndex)) + { + input = *pIn; + // Use temp tile info for calcalation + input.pTileInfo = &tileInfoNull; + + returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, + input.pTileInfo, &input.tileMode); + // Change the input structure + pIn = &input; + } + + if (returnCode == ADDR_OK) + { + returnCode = HwlComputeSliceTileSwizzle(pIn, pOut); + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ExtractBankPipeSwizzle +* +* @brief +* Interface function stub of AddrExtractBankPipeSwizzle. +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ExtractBankPipeSwizzle( + const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT* pIn, ///< [in] input structure + ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT)) || + (pOut->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_TILEINFO tileInfoNull; + ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT input; + + if (UseTileIndex(pIn->tileIndex)) + { + input = *pIn; + // Use temp tile info for calcalation + input.pTileInfo = &tileInfoNull; + + returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); + // Change the input structure + pIn = &input; + } + + if (returnCode == ADDR_OK) + { + returnCode = HwlExtractBankPipeSwizzle(pIn, pOut); + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::CombineBankPipeSwizzle +* +* @brief +* Interface function stub of AddrCombineBankPipeSwizzle. +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::CombineBankPipeSwizzle( + const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT* pIn, ///< [in] input structure + ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_TILEINFO tileInfoNull; + ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT input; + + if (UseTileIndex(pIn->tileIndex)) + { + input = *pIn; + // Use temp tile info for calcalation + input.pTileInfo = &tileInfoNull; + + returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); + // Change the input structure + pIn = &input; + } + + if (returnCode == ADDR_OK) + { + returnCode = HwlCombineBankPipeSwizzle(pIn->bankSwizzle, + pIn->pipeSwizzle, + pIn->pTileInfo, + pIn->baseAddr, + &pOut->tileSwizzle); + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeBaseSwizzle +* +* @brief +* Interface function stub of AddrCompueBaseSwizzle. +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeBaseSwizzle( + const ADDR_COMPUTE_BASE_SWIZZLE_INPUT* pIn, + ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_TILEINFO tileInfoNull; + ADDR_COMPUTE_BASE_SWIZZLE_INPUT input; + + if (UseTileIndex(pIn->tileIndex)) + { + input = *pIn; + // Use temp tile info for calcalation + input.pTileInfo = &tileInfoNull; + + returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); + // Change the input structure + pIn = &input; + } + + if (returnCode == ADDR_OK) + { + if (IsMacroTiled(pIn->tileMode)) + { + returnCode = HwlComputeBaseSwizzle(pIn, pOut); + } + else + { + pOut->tileSwizzle = 0; + } + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeFmaskInfo +* +* @brief +* Interface function stub of ComputeFmaskInfo. +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeFmaskInfo( + const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure + ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure + ) +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + // No thick MSAA + if (ComputeSurfaceThickness(pIn->tileMode) > 1) + { + returnCode = ADDR_INVALIDPARAMS; + } + + if (returnCode == ADDR_OK) + { + ADDR_TILEINFO tileInfoNull; + ADDR_COMPUTE_FMASK_INFO_INPUT input; + + if (UseTileIndex(pIn->tileIndex)) + { + input = *pIn; + + if (pOut->pTileInfo) + { + // Use temp tile info for calcalation + input.pTileInfo = pOut->pTileInfo; + } + else + { + input.pTileInfo = &tileInfoNull; + } + + ADDR_SURFACE_FLAGS flags = {{0}}; + flags.fmask = 1; + + // Try finding a macroModeIndex + INT_32 macroModeIndex = HwlComputeMacroModeIndex(pIn->tileIndex, + flags, + HwlComputeFmaskBits(pIn, NULL), + pIn->numSamples, + input.pTileInfo, + &input.tileMode); + + // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info + if (macroModeIndex == TileIndexNoMacroIndex) + { + returnCode = HwlSetupTileCfg(input.tileIndex, macroModeIndex, + input.pTileInfo, &input.tileMode); + } + + ADDR_ASSERT(macroModeIndex != TileIndexInvalid); + + // Change the input structure + pIn = &input; + } + + if (returnCode == ADDR_OK) + { + if (pIn->numSamples > 1) + { + returnCode = HwlComputeFmaskInfo(pIn, pOut); + } + else + { + memset(pOut, 0, sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT)); + + returnCode = ADDR_INVALIDPARAMS; + } + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeFmaskAddrFromCoord +* +* @brief +* Interface function stub of ComputeFmaskAddrFromCoord. +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeFmaskAddrFromCoord( + const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure + ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_ASSERT(pIn->numSamples > 1); + + if (pIn->numSamples > 1) + { + returnCode = HwlComputeFmaskAddrFromCoord(pIn, pOut); + } + else + { + returnCode = ADDR_INVALIDPARAMS; + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeFmaskCoordFromAddr +* +* @brief +* Interface function stub of ComputeFmaskAddrFromCoord. +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeFmaskCoordFromAddr( + const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure + ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_ASSERT(pIn->numSamples > 1); + + if (pIn->numSamples > 1) + { + returnCode = HwlComputeFmaskCoordFromAddr(pIn, pOut); + } + else + { + returnCode = ADDR_INVALIDPARAMS; + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ConvertTileInfoToHW +* +* @brief +* Convert tile info from real value to HW register value in HW layer +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ConvertTileInfoToHW( + const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure + ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT)) || + (pOut->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_TILEINFO tileInfoNull; + ADDR_CONVERT_TILEINFOTOHW_INPUT input; + // if pIn->reverse is TRUE, indices are ignored + if (pIn->reverse == FALSE && UseTileIndex(pIn->tileIndex)) + { + input = *pIn; + input.pTileInfo = &tileInfoNull; + + returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); + + pIn = &input; + } + + if (returnCode == ADDR_OK) + { + returnCode = HwlConvertTileInfoToHW(pIn, pOut); + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ConvertTileIndex +* +* @brief +* Convert tile index to tile mode/type/info +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ConvertTileIndex( + const ADDR_CONVERT_TILEINDEX_INPUT* pIn, ///< [in] input structure + ADDR_CONVERT_TILEINDEX_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX_INPUT)) || + (pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + + returnCode = HwlSetupTileCfg(pIn->tileIndex, pIn->macroModeIndex, + pOut->pTileInfo, &pOut->tileMode, &pOut->tileType); + + if (returnCode == ADDR_OK && pIn->tileInfoHw) + { + ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0}; + ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0}; + + hwInput.pTileInfo = pOut->pTileInfo; + hwInput.tileIndex = -1; + hwOutput.pTileInfo = pOut->pTileInfo; + + returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput); + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ConvertTileIndex1 +* +* @brief +* Convert tile index to tile mode/type/info +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ConvertTileIndex1( + const ADDR_CONVERT_TILEINDEX1_INPUT* pIn, ///< [in] input structure + ADDR_CONVERT_TILEINDEX_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX1_INPUT)) || + (pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_SURFACE_FLAGS flags = {{0}}; + + HwlComputeMacroModeIndex(pIn->tileIndex, flags, pIn->bpp, pIn->numSamples, + pOut->pTileInfo, &pOut->tileMode, &pOut->tileType); + + if (pIn->tileInfoHw) + { + ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0}; + ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0}; + + hwInput.pTileInfo = pOut->pTileInfo; + hwInput.tileIndex = -1; + hwOutput.pTileInfo = pOut->pTileInfo; + + returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput); + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::GetTileIndex +* +* @brief +* Get tile index from tile mode/type/info +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::GetTileIndex( + const ADDR_GET_TILEINDEX_INPUT* pIn, ///< [in] input structure + ADDR_GET_TILEINDEX_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_GET_TILEINDEX_INPUT)) || + (pOut->size != sizeof(ADDR_GET_TILEINDEX_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + returnCode = HwlGetTileIndex(pIn, pOut); + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeSurfaceThickness +* +* @brief +* Compute surface thickness +* +* @return +* Surface thickness +*************************************************************************************************** +*/ +UINT_32 AddrLib::ComputeSurfaceThickness( + AddrTileMode tileMode) ///< [in] tile mode +{ + return m_modeFlags[tileMode].thickness; +} + + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// CMASK/HTILE +/////////////////////////////////////////////////////////////////////////////////////////////////// + +/** +*************************************************************************************************** +* AddrLib::ComputeHtileInfo +* +* @brief +* Interface function stub of AddrComputeHtilenfo +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeHtileInfo( + const ADDR_COMPUTE_HTILE_INFO_INPUT* pIn, ///< [in] input structure + ADDR_COMPUTE_HTILE_INFO_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + BOOL_32 isWidth8 = (pIn->blockWidth == 8) ? TRUE : FALSE; + BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_TILEINFO tileInfoNull; + ADDR_COMPUTE_HTILE_INFO_INPUT input; + + if (UseTileIndex(pIn->tileIndex)) + { + input = *pIn; + // Use temp tile info for calcalation + input.pTileInfo = &tileInfoNull; + + returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); + + // Change the input structure + pIn = &input; + } + + if (returnCode == ADDR_OK) + { + pOut->bpp = ComputeHtileInfo(pIn->flags, + pIn->pitch, + pIn->height, + pIn->numSlices, + pIn->isLinear, + isWidth8, + isHeight8, + pIn->pTileInfo, + &pOut->pitch, + &pOut->height, + &pOut->htileBytes, + &pOut->macroWidth, + &pOut->macroHeight, + &pOut->sliceSize, + &pOut->baseAlign); + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeCmaskInfo +* +* @brief +* Interface function stub of AddrComputeCmaskInfo +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeCmaskInfo( + const ADDR_COMPUTE_CMASK_INFO_INPUT* pIn, ///< [in] input structure + ADDR_COMPUTE_CMASK_INFO_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_INFO_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_CMASK_INFO_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_TILEINFO tileInfoNull; + ADDR_COMPUTE_CMASK_INFO_INPUT input; + + if (UseTileIndex(pIn->tileIndex)) + { + input = *pIn; + // Use temp tile info for calcalation + input.pTileInfo = &tileInfoNull; + + returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); + + // Change the input structure + pIn = &input; + } + + if (returnCode == ADDR_OK) + { + returnCode = ComputeCmaskInfo(pIn->flags, + pIn->pitch, + pIn->height, + pIn->numSlices, + pIn->isLinear, + pIn->pTileInfo, + &pOut->pitch, + &pOut->height, + &pOut->cmaskBytes, + &pOut->macroWidth, + &pOut->macroHeight, + &pOut->sliceSize, + &pOut->baseAlign, + &pOut->blockMax); + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeDccInfo +* +* @brief +* Interface function to compute DCC key info +* +* @return +* return code of HwlComputeDccInfo +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeDccInfo( + const ADDR_COMPUTE_DCCINFO_INPUT* pIn, ///< [in] input structure + ADDR_COMPUTE_DCCINFO_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE ret = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_DCCINFO_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT))) + { + ret = ADDR_PARAMSIZEMISMATCH; + } + } + + if (ret == ADDR_OK) + { + ADDR_COMPUTE_DCCINFO_INPUT input; + + if (UseTileIndex(pIn->tileIndex)) + { + input = *pIn; + + ret = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, + &input.tileInfo, &input.tileMode); + + pIn = &input; + } + + if (ADDR_OK == ret) + { + ret = HwlComputeDccInfo(pIn, pOut); + } + } + + return ret; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeHtileAddrFromCoord +* +* @brief +* Interface function stub of AddrComputeHtileAddrFromCoord +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeHtileAddrFromCoord( + const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure + ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + BOOL_32 isWidth8 = (pIn->blockWidth == 8) ? TRUE : FALSE; + BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_TILEINFO tileInfoNull; + ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT input; + + if (UseTileIndex(pIn->tileIndex)) + { + input = *pIn; + // Use temp tile info for calcalation + input.pTileInfo = &tileInfoNull; + + returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); + + // Change the input structure + pIn = &input; + } + + if (returnCode == ADDR_OK) + { + pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch, + pIn->height, + pIn->x, + pIn->y, + pIn->slice, + pIn->numSlices, + 1, + pIn->isLinear, + isWidth8, + isHeight8, + pIn->pTileInfo, + &pOut->bitPosition); + } + } + + return returnCode; + +} + +/** +*************************************************************************************************** +* AddrLib::ComputeHtileCoordFromAddr +* +* @brief +* Interface function stub of AddrComputeHtileCoordFromAddr +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeHtileCoordFromAddr( + const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure + ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + BOOL_32 isWidth8 = (pIn->blockWidth == 8) ? TRUE : FALSE; + BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_TILEINFO tileInfoNull; + ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT input; + + if (UseTileIndex(pIn->tileIndex)) + { + input = *pIn; + // Use temp tile info for calcalation + input.pTileInfo = &tileInfoNull; + + returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); + + // Change the input structure + pIn = &input; + } + + if (returnCode == ADDR_OK) + { + HwlComputeXmaskCoordFromAddr(pIn->addr, + pIn->bitPosition, + pIn->pitch, + pIn->height, + pIn->numSlices, + 1, + pIn->isLinear, + isWidth8, + isHeight8, + pIn->pTileInfo, + &pOut->x, + &pOut->y, + &pOut->slice); + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeCmaskAddrFromCoord +* +* @brief +* Interface function stub of AddrComputeCmaskAddrFromCoord +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeCmaskAddrFromCoord( + const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure + ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_TILEINFO tileInfoNull; + ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT input; + + if (UseTileIndex(pIn->tileIndex)) + { + input = *pIn; + // Use temp tile info for calcalation + input.pTileInfo = &tileInfoNull; + + returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); + + // Change the input structure + pIn = &input; + } + + if (returnCode == ADDR_OK) + { + if (pIn->flags.tcCompatible == TRUE) + { + returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut); + } + else + { + pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch, + pIn->height, + pIn->x, + pIn->y, + pIn->slice, + pIn->numSlices, + 2, + pIn->isLinear, + FALSE, //this is cmask, isWidth8 is not needed + FALSE, //this is cmask, isHeight8 is not needed + pIn->pTileInfo, + &pOut->bitPosition); + } + + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeCmaskCoordFromAddr +* +* @brief +* Interface function stub of AddrComputeCmaskCoordFromAddr +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeCmaskCoordFromAddr( + const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure + ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure + ) const +{ + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (GetFillSizeFieldsFlags() == TRUE) + { + if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT)) || + (pOut->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT))) + { + returnCode = ADDR_PARAMSIZEMISMATCH; + } + } + + if (returnCode == ADDR_OK) + { + ADDR_TILEINFO tileInfoNull; + ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT input; + + if (UseTileIndex(pIn->tileIndex)) + { + input = *pIn; + // Use temp tile info for calcalation + input.pTileInfo = &tileInfoNull; + + returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo); + + // Change the input structure + pIn = &input; + } + + if (returnCode == ADDR_OK) + { + HwlComputeXmaskCoordFromAddr(pIn->addr, + pIn->bitPosition, + pIn->pitch, + pIn->height, + pIn->numSlices, + 2, + pIn->isLinear, + FALSE, + FALSE, + pIn->pTileInfo, + &pOut->x, + &pOut->y, + &pOut->slice); + } + } + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeTileDataWidthAndHeight +* +* @brief +* Compute the squared cache shape for per-tile data (CMASK and HTILE) +* +* @return +* N/A +* +* @note +* MacroWidth and macroHeight are measured in pixels +*************************************************************************************************** +*/ +VOID AddrLib::ComputeTileDataWidthAndHeight( + UINT_32 bpp, ///< [in] bits per pixel + UINT_32 cacheBits, ///< [in] bits of cache + ADDR_TILEINFO* pTileInfo, ///< [in] Tile info + UINT_32* pMacroWidth, ///< [out] macro tile width + UINT_32* pMacroHeight ///< [out] macro tile height + ) const +{ + UINT_32 height = 1; + UINT_32 width = cacheBits / bpp; + UINT_32 pipes = HwlGetPipes(pTileInfo); + + // Double height until the macro-tile is close to square + // Height can only be doubled if width is even + + while ((width > height * 2 * pipes) && !(width & 1)) + { + width /= 2; + height *= 2; + } + + *pMacroWidth = 8 * width; + *pMacroHeight = 8 * height * pipes; + + // Note: The above iterative comptuation is equivalent to the following + // + //int log2_height = ((log2(cacheBits)-log2(bpp)-log2(pipes))/2); + //int macroHeight = pow2( 3+log2(pipes)+log2_height ); +} + +/** +*************************************************************************************************** +* AddrLib::HwlComputeTileDataWidthAndHeightLinear +* +* @brief +* Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout +* +* @return +* N/A +* +* @note +* MacroWidth and macroHeight are measured in pixels +*************************************************************************************************** +*/ +VOID AddrLib::HwlComputeTileDataWidthAndHeightLinear( + UINT_32* pMacroWidth, ///< [out] macro tile width + UINT_32* pMacroHeight, ///< [out] macro tile height + UINT_32 bpp, ///< [in] bits per pixel + ADDR_TILEINFO* pTileInfo ///< [in] tile info + ) const +{ + ADDR_ASSERT(bpp != 4); // Cmask does not support linear layout prior to SI + *pMacroWidth = 8 * 512 / bpp; // Align width to 512-bit memory accesses + *pMacroHeight = 8 * m_pipes; // Align height to number of pipes +} + +/** +*************************************************************************************************** +* AddrLib::ComputeHtileInfo +* +* @brief +* Compute htile pitch,width, bytes per 2D slice +* +* @return +* Htile bpp i.e. How many bits for an 8x8 tile +* Also returns by output parameters: +* *Htile pitch, height, total size in bytes, macro-tile dimensions and slice size* +*************************************************************************************************** +*/ +UINT_32 AddrLib::ComputeHtileInfo( + ADDR_HTILE_FLAGS flags, ///< [in] htile flags + UINT_32 pitchIn, ///< [in] pitch input + UINT_32 heightIn, ///< [in] height input + UINT_32 numSlices, ///< [in] number of slices + BOOL_32 isLinear, ///< [in] if it is linear mode + BOOL_32 isWidth8, ///< [in] if htile block width is 8 + BOOL_32 isHeight8, ///< [in] if htile block height is 8 + ADDR_TILEINFO* pTileInfo, ///< [in] Tile info + UINT_32* pPitchOut, ///< [out] pitch output + UINT_32* pHeightOut, ///< [out] height output + UINT_64* pHtileBytes, ///< [out] bytes per 2D slice + UINT_32* pMacroWidth, ///< [out] macro-tile width in pixels + UINT_32* pMacroHeight, ///< [out] macro-tile width in pixels + UINT_64* pSliceSize, ///< [out] slice size in bytes + UINT_32* pBaseAlign ///< [out] base alignment + ) const +{ + + UINT_32 macroWidth; + UINT_32 macroHeight; + UINT_32 baseAlign; + UINT_64 surfBytes; + UINT_64 sliceBytes; + + numSlices = Max(1u, numSlices); + + const UINT_32 bpp = HwlComputeHtileBpp(isWidth8, isHeight8); + const UINT_32 cacheBits = HtileCacheBits; + + if (isLinear) + { + HwlComputeTileDataWidthAndHeightLinear(¯oWidth, + ¯oHeight, + bpp, + pTileInfo); + } + else + { + ComputeTileDataWidthAndHeight(bpp, + cacheBits, + pTileInfo, + ¯oWidth, + ¯oHeight); + } + + *pPitchOut = PowTwoAlign(pitchIn, macroWidth); + *pHeightOut = PowTwoAlign(heightIn, macroHeight); + + baseAlign = HwlComputeHtileBaseAlign(flags.tcCompatible, isLinear, pTileInfo); + + surfBytes = HwlComputeHtileBytes(*pPitchOut, + *pHeightOut, + bpp, + isLinear, + numSlices, + &sliceBytes, + baseAlign); + + *pHtileBytes = surfBytes; + + // + // Use SafeAssign since they are optional + // + SafeAssign(pMacroWidth, macroWidth); + + SafeAssign(pMacroHeight, macroHeight); + + SafeAssign(pSliceSize, sliceBytes); + + SafeAssign(pBaseAlign, baseAlign); + + return bpp; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeCmaskBaseAlign +* +* @brief +* Compute cmask base alignment +* +* @return +* Cmask base alignment +*************************************************************************************************** +*/ +UINT_32 AddrLib::ComputeCmaskBaseAlign( + ADDR_CMASK_FLAGS flags, ///< [in] Cmask flags + ADDR_TILEINFO* pTileInfo ///< [in] Tile info + ) const +{ + UINT_32 baseAlign = m_pipeInterleaveBytes * HwlGetPipes(pTileInfo); + + if (flags.tcCompatible) + { + ADDR_ASSERT(pTileInfo != NULL); + if (pTileInfo) + { + baseAlign *= pTileInfo->banks; + } + } + + return baseAlign; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeCmaskBytes +* +* @brief +* Compute cmask size in bytes +* +* @return +* Cmask size in bytes +*************************************************************************************************** +*/ +UINT_64 AddrLib::ComputeCmaskBytes( + UINT_32 pitch, ///< [in] pitch + UINT_32 height, ///< [in] height + UINT_32 numSlices ///< [in] number of slices + ) const +{ + return BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * numSlices * CmaskElemBits) / + MicroTilePixels; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeCmaskInfo +* +* @brief +* Compute cmask pitch,width, bytes per 2D slice +* +* @return +* BlockMax. Also by output parameters: Cmask pitch,height, total size in bytes, +* macro-tile dimensions +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputeCmaskInfo( + ADDR_CMASK_FLAGS flags, ///< [in] cmask flags + UINT_32 pitchIn, ///< [in] pitch input + UINT_32 heightIn, ///< [in] height input + UINT_32 numSlices, ///< [in] number of slices + BOOL_32 isLinear, ///< [in] is linear mode + ADDR_TILEINFO* pTileInfo, ///< [in] Tile info + UINT_32* pPitchOut, ///< [out] pitch output + UINT_32* pHeightOut, ///< [out] height output + UINT_64* pCmaskBytes, ///< [out] bytes per 2D slice + UINT_32* pMacroWidth, ///< [out] macro-tile width in pixels + UINT_32* pMacroHeight, ///< [out] macro-tile width in pixels + UINT_64* pSliceSize, ///< [out] slice size in bytes + UINT_32* pBaseAlign, ///< [out] base alignment + UINT_32* pBlockMax ///< [out] block max == slice / 128 / 128 - 1 + ) const +{ + UINT_32 macroWidth; + UINT_32 macroHeight; + UINT_32 baseAlign; + UINT_64 surfBytes; + UINT_64 sliceBytes; + + numSlices = Max(1u, numSlices); + + const UINT_32 bpp = CmaskElemBits; + const UINT_32 cacheBits = CmaskCacheBits; + + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + if (isLinear) + { + HwlComputeTileDataWidthAndHeightLinear(¯oWidth, + ¯oHeight, + bpp, + pTileInfo); + } + else + { + ComputeTileDataWidthAndHeight(bpp, + cacheBits, + pTileInfo, + ¯oWidth, + ¯oHeight); + } + + *pPitchOut = (pitchIn + macroWidth - 1) & ~(macroWidth - 1); + *pHeightOut = (heightIn + macroHeight - 1) & ~(macroHeight - 1); + + + sliceBytes = ComputeCmaskBytes(*pPitchOut, + *pHeightOut, + 1); + + baseAlign = ComputeCmaskBaseAlign(flags, pTileInfo); + + while (sliceBytes % baseAlign) + { + *pHeightOut += macroHeight; + + sliceBytes = ComputeCmaskBytes(*pPitchOut, + *pHeightOut, + 1); + } + + surfBytes = sliceBytes * numSlices; + + *pCmaskBytes = surfBytes; + + // + // Use SafeAssign since they are optional + // + SafeAssign(pMacroWidth, macroWidth); + + SafeAssign(pMacroHeight, macroHeight); + + SafeAssign(pBaseAlign, baseAlign); + + SafeAssign(pSliceSize, sliceBytes); + + UINT_32 slice = (*pPitchOut) * (*pHeightOut); + UINT_32 blockMax = slice / 128 / 128 - 1; + +#if DEBUG + if (slice % (64*256) != 0) + { + ADDR_ASSERT_ALWAYS(); + } +#endif //DEBUG + + UINT_32 maxBlockMax = HwlGetMaxCmaskBlockMax(); + + if (blockMax > maxBlockMax) + { + blockMax = maxBlockMax; + returnCode = ADDR_INVALIDPARAMS; + } + + SafeAssign(pBlockMax, blockMax); + + return returnCode; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeXmaskCoordYFromPipe +* +* @brief +* Compute the Y coord from pipe number for cmask/htile +* +* @return +* Y coordinate +* +*************************************************************************************************** +*/ +UINT_32 AddrLib::ComputeXmaskCoordYFromPipe( + UINT_32 pipe, ///< [in] pipe number + UINT_32 x ///< [in] x coordinate + ) const +{ + UINT_32 pipeBit0; + UINT_32 pipeBit1; + UINT_32 xBit0; + UINT_32 xBit1; + UINT_32 yBit0; + UINT_32 yBit1; + + UINT_32 y = 0; + + UINT_32 numPipes = m_pipes; // SI has its implementation + // + // Convert pipe + x to y coordinate. + // + switch (numPipes) + { + case 1: + // + // 1 pipe + // + // p0 = 0 + // + y = 0; + break; + case 2: + // + // 2 pipes + // + // p0 = x0 ^ y0 + // + // y0 = p0 ^ x0 + // + pipeBit0 = pipe & 0x1; + + xBit0 = x & 0x1; + + yBit0 = pipeBit0 ^ xBit0; + + y = yBit0; + break; + case 4: + // + // 4 pipes + // + // p0 = x1 ^ y0 + // p1 = x0 ^ y1 + // + // y0 = p0 ^ x1 + // y1 = p1 ^ x0 + // + pipeBit0 = pipe & 0x1; + pipeBit1 = (pipe & 0x2) >> 1; + + xBit0 = x & 0x1; + xBit1 = (x & 0x2) >> 1; + + yBit0 = pipeBit0 ^ xBit1; + yBit1 = pipeBit1 ^ xBit0; + + y = (yBit0 | + (yBit1 << 1)); + break; + case 8: + // + // 8 pipes + // + // r600 and r800 have different method + // + y = HwlComputeXmaskCoordYFrom8Pipe(pipe, x); + break; + default: + break; + } + return y; +} + +/** +*************************************************************************************************** +* AddrLib::HwlComputeXmaskCoordFromAddr +* +* @brief +* Compute the coord from an address of a cmask/htile +* +* @return +* N/A +* +* @note +* This method is reused by htile, so rename to Xmask +*************************************************************************************************** +*/ +VOID AddrLib::HwlComputeXmaskCoordFromAddr( + UINT_64 addr, ///< [in] address + UINT_32 bitPosition, ///< [in] bitPosition in a byte + UINT_32 pitch, ///< [in] pitch + UINT_32 height, ///< [in] height + UINT_32 numSlices, ///< [in] number of slices + UINT_32 factor, ///< [in] factor that indicates cmask or htile + BOOL_32 isLinear, ///< [in] linear or tiled HTILE layout + BOOL_32 isWidth8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value + BOOL_32 isHeight8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value + ADDR_TILEINFO* pTileInfo, ///< [in] Tile info + UINT_32* pX, ///< [out] x coord + UINT_32* pY, ///< [out] y coord + UINT_32* pSlice ///< [out] slice index + ) const +{ + UINT_32 pipe; + UINT_32 numPipes; + UINT_32 numPipeBits; + UINT_32 macroTilePitch; + UINT_32 macroTileHeight; + + UINT_64 bitAddr; + + UINT_32 microTileCoordY; + + UINT_32 elemBits; + + UINT_32 pitchAligned = pitch; + UINT_32 heightAligned = height; + UINT_64 totalBytes; + + UINT_64 elemOffset; + + UINT_64 macroIndex; + UINT_32 microIndex; + + UINT_64 macroNumber; + UINT_32 microNumber; + + UINT_32 macroX; + UINT_32 macroY; + UINT_32 macroZ; + + UINT_32 microX; + UINT_32 microY; + + UINT_32 tilesPerMacro; + UINT_32 macrosPerPitch; + UINT_32 macrosPerSlice; + + // + // Extract pipe. + // + numPipes = HwlGetPipes(pTileInfo); + pipe = ComputePipeFromAddr(addr, numPipes); + + // + // Compute the number of group and pipe bits. + // + numPipeBits = Log2(numPipes); + + UINT_32 groupBits = 8 * m_pipeInterleaveBytes; + UINT_32 pipes = numPipes; + + + // + // Compute the micro tile size, in bits. And macro tile pitch and height. + // + if (factor == 2) //CMASK + { + ADDR_CMASK_FLAGS flags = {{0}}; + + elemBits = CmaskElemBits; + + ComputeCmaskInfo(flags, + pitch, + height, + numSlices, + isLinear, + pTileInfo, + &pitchAligned, + &heightAligned, + &totalBytes, + ¯oTilePitch, + ¯oTileHeight); + } + else //HTILE + { + ADDR_HTILE_FLAGS flags = {{0}}; + + if (factor != 1) + { + factor = 1; + } + + elemBits = HwlComputeHtileBpp(isWidth8, isHeight8); + + ComputeHtileInfo(flags, + pitch, + height, + numSlices, + isLinear, + isWidth8, + isHeight8, + pTileInfo, + &pitchAligned, + &heightAligned, + &totalBytes, + ¯oTilePitch, + ¯oTileHeight); + } + + // Should use aligned dims + // + pitch = pitchAligned; + height = heightAligned; + + + // + // Convert byte address to bit address. + // + bitAddr = BYTES_TO_BITS(addr) + bitPosition; + + + // + // Remove pipe bits from address. + // + + bitAddr = (bitAddr % groupBits) + ((bitAddr/groupBits/pipes)*groupBits); + + + elemOffset = bitAddr / elemBits; + + tilesPerMacro = (macroTilePitch/factor) * macroTileHeight / MicroTilePixels >> numPipeBits; + + macrosPerPitch = pitch / (macroTilePitch/factor); + macrosPerSlice = macrosPerPitch * height / macroTileHeight; + + macroIndex = elemOffset / factor / tilesPerMacro; + microIndex = static_cast<UINT_32>(elemOffset % (tilesPerMacro * factor)); + + macroNumber = macroIndex * factor + microIndex % factor; + microNumber = microIndex / factor; + + macroX = static_cast<UINT_32>((macroNumber % macrosPerPitch)); + macroY = static_cast<UINT_32>((macroNumber % macrosPerSlice) / macrosPerPitch); + macroZ = static_cast<UINT_32>((macroNumber / macrosPerSlice)); + + + microX = microNumber % (macroTilePitch / factor / MicroTileWidth); + microY = (microNumber / (macroTilePitch / factor / MicroTileHeight)); + + *pX = macroX * (macroTilePitch/factor) + microX * MicroTileWidth; + *pY = macroY * macroTileHeight + (microY * MicroTileHeight << numPipeBits); + *pSlice = macroZ; + + microTileCoordY = ComputeXmaskCoordYFromPipe(pipe, + *pX/MicroTileWidth); + + + // + // Assemble final coordinates. + // + *pY += microTileCoordY * MicroTileHeight; + +} + +/** +*************************************************************************************************** +* AddrLib::HwlComputeXmaskAddrFromCoord +* +* @brief +* Compute the address from an address of cmask (prior to si) +* +* @return +* Address in bytes +* +*************************************************************************************************** +*/ +UINT_64 AddrLib::HwlComputeXmaskAddrFromCoord( + UINT_32 pitch, ///< [in] pitch + UINT_32 height, ///< [in] height + UINT_32 x, ///< [in] x coord + UINT_32 y, ///< [in] y coord + UINT_32 slice, ///< [in] slice/depth index + UINT_32 numSlices, ///< [in] number of slices + UINT_32 factor, ///< [in] factor that indicates cmask(2) or htile(1) + BOOL_32 isLinear, ///< [in] linear or tiled HTILE layout + BOOL_32 isWidth8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value + BOOL_32 isHeight8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value + ADDR_TILEINFO* pTileInfo, ///< [in] Tile info + UINT_32* pBitPosition ///< [out] bit position inside a byte + ) const +{ + UINT_64 addr; + UINT_32 numGroupBits; + UINT_32 numPipeBits; + UINT_32 newPitch = 0; + UINT_32 newHeight = 0; + UINT_64 sliceBytes = 0; + UINT_64 totalBytes = 0; + UINT_64 sliceOffset; + UINT_32 pipe; + UINT_32 macroTileWidth; + UINT_32 macroTileHeight; + UINT_32 macroTilesPerRow; + UINT_32 macroTileBytes; + UINT_32 macroTileIndexX; + UINT_32 macroTileIndexY; + UINT_64 macroTileOffset; + UINT_32 pixelBytesPerRow; + UINT_32 pixelOffsetX; + UINT_32 pixelOffsetY; + UINT_32 pixelOffset; + UINT_64 totalOffset; + UINT_64 offsetLo; + UINT_64 offsetHi; + UINT_64 groupMask; + + + UINT_32 elemBits = 0; + + UINT_32 numPipes = m_pipes; // This function is accessed prior to si only + + if (factor == 2) //CMASK + { + elemBits = CmaskElemBits; + + // For asics before SI, cmask is always tiled + isLinear = FALSE; + } + else //HTILE + { + if (factor != 1) // Fix compile warning + { + factor = 1; + } + + elemBits = HwlComputeHtileBpp(isWidth8, isHeight8); + } + + // + // Compute the number of group bits and pipe bits. + // + numGroupBits = Log2(m_pipeInterleaveBytes); + numPipeBits = Log2(numPipes); + + // + // Compute macro tile dimensions. + // + if (factor == 2) // CMASK + { + ADDR_CMASK_FLAGS flags = {{0}}; + + ComputeCmaskInfo(flags, + pitch, + height, + numSlices, + isLinear, + pTileInfo, + &newPitch, + &newHeight, + &totalBytes, + ¯oTileWidth, + ¯oTileHeight); + + sliceBytes = totalBytes / numSlices; + } + else // HTILE + { + ADDR_HTILE_FLAGS flags = {{0}}; + + ComputeHtileInfo(flags, + pitch, + height, + numSlices, + isLinear, + isWidth8, + isHeight8, + pTileInfo, + &newPitch, + &newHeight, + &totalBytes, + ¯oTileWidth, + ¯oTileHeight, + &sliceBytes); + } + + sliceOffset = slice * sliceBytes; + + // + // Get the pipe. Note that neither slice rotation nor pipe swizzling apply for CMASK. + // + pipe = ComputePipeFromCoord(x, + y, + 0, + ADDR_TM_2D_TILED_THIN1, + 0, + FALSE, + pTileInfo); + + // + // Compute the number of macro tiles per row. + // + macroTilesPerRow = newPitch / macroTileWidth; + + // + // Compute the number of bytes per macro tile. + // + macroTileBytes = BITS_TO_BYTES((macroTileWidth * macroTileHeight * elemBits) / MicroTilePixels); + + // + // Compute the offset to the macro tile containing the specified coordinate. + // + macroTileIndexX = x / macroTileWidth; + macroTileIndexY = y / macroTileHeight; + macroTileOffset = ((macroTileIndexY * macroTilesPerRow) + macroTileIndexX) * macroTileBytes; + + // + // Compute the pixel offset within the macro tile. + // + pixelBytesPerRow = BITS_TO_BYTES(macroTileWidth * elemBits) / MicroTileWidth; + + // + // The nibbles are interleaved (see below), so the part of the offset relative to the x + // coordinate repeats halfway across the row. (Not for HTILE) + // + if (factor == 2) + { + pixelOffsetX = (x % (macroTileWidth / 2)) / MicroTileWidth; + } + else + { + pixelOffsetX = (x % (macroTileWidth)) / MicroTileWidth * BITS_TO_BYTES(elemBits); + } + + // + // Compute the y offset within the macro tile. + // + pixelOffsetY = (((y % macroTileHeight) / MicroTileHeight) / numPipes) * pixelBytesPerRow; + + pixelOffset = pixelOffsetX + pixelOffsetY; + + // + // Combine the slice offset and macro tile offset with the pixel offset, accounting for the + // pipe bits in the middle of the address. + // + totalOffset = ((sliceOffset + macroTileOffset) >> numPipeBits) + pixelOffset; + + // + // Split the offset to put some bits below the pipe bits and some above. + // + groupMask = (1 << numGroupBits) - 1; + offsetLo = totalOffset & groupMask; + offsetHi = (totalOffset & ~groupMask) << numPipeBits; + + // + // Assemble the address from its components. + // + addr = offsetLo; + addr |= offsetHi; + // This is to remove warning with /analyze option + UINT_32 pipeBits = pipe << numGroupBits; + addr |= pipeBits; + + // + // Compute the bit position. The lower nibble is used when the x coordinate within the macro + // tile is less than half of the macro tile width, and the upper nibble is used when the x + // coordinate within the macro tile is greater than or equal to half the macro tile width. + // + *pBitPosition = ((x % macroTileWidth) < (macroTileWidth / factor)) ? 0 : 4; + + return addr; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Surface Addressing Shared +/////////////////////////////////////////////////////////////////////////////////////////////////// + +/** +*************************************************************************************************** +* AddrLib::ComputeSurfaceAddrFromCoordLinear +* +* @brief +* Compute address from coord for linear surface +* +* @return +* Address in bytes +* +*************************************************************************************************** +*/ +UINT_64 AddrLib::ComputeSurfaceAddrFromCoordLinear( + UINT_32 x, ///< [in] x coord + UINT_32 y, ///< [in] y coord + UINT_32 slice, ///< [in] slice/depth index + UINT_32 sample, ///< [in] sample index + UINT_32 bpp, ///< [in] bits per pixel + UINT_32 pitch, ///< [in] pitch + UINT_32 height, ///< [in] height + UINT_32 numSlices, ///< [in] number of slices + UINT_32* pBitPosition ///< [out] bit position inside a byte + ) const +{ + const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height; + + UINT_64 sliceOffset = (slice + sample * numSlices)* sliceSize; + UINT_64 rowOffset = static_cast<UINT_64>(y) * pitch; + UINT_64 pixOffset = x; + + UINT_64 addr = (sliceOffset + rowOffset + pixOffset) * bpp; + + *pBitPosition = static_cast<UINT_32>(addr % 8); + addr /= 8; + + return addr; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeSurfaceCoordFromAddrLinear +* +* @brief +* Compute the coord from an address of a linear surface +* +* @return +* N/A +*************************************************************************************************** +*/ +VOID AddrLib::ComputeSurfaceCoordFromAddrLinear( + UINT_64 addr, ///< [in] address + UINT_32 bitPosition, ///< [in] bitPosition in a byte + UINT_32 bpp, ///< [in] bits per pixel + UINT_32 pitch, ///< [in] pitch + UINT_32 height, ///< [in] height + UINT_32 numSlices, ///< [in] number of slices + UINT_32* pX, ///< [out] x coord + UINT_32* pY, ///< [out] y coord + UINT_32* pSlice, ///< [out] slice/depth index + UINT_32* pSample ///< [out] sample index + ) const +{ + const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height; + const UINT_64 linearOffset = (BYTES_TO_BITS(addr) + bitPosition) / bpp; + + *pX = static_cast<UINT_32>((linearOffset % sliceSize) % pitch); + *pY = static_cast<UINT_32>((linearOffset % sliceSize) / pitch % height); + *pSlice = static_cast<UINT_32>((linearOffset / sliceSize) % numSlices); + *pSample = static_cast<UINT_32>((linearOffset / sliceSize) / numSlices); +} + +/** +*************************************************************************************************** +* AddrLib::ComputeSurfaceCoordFromAddrMicroTiled +* +* @brief +* Compute the coord from an address of a micro tiled surface +* +* @return +* N/A +*************************************************************************************************** +*/ +VOID AddrLib::ComputeSurfaceCoordFromAddrMicroTiled( + UINT_64 addr, ///< [in] address + UINT_32 bitPosition, ///< [in] bitPosition in a byte + UINT_32 bpp, ///< [in] bits per pixel + UINT_32 pitch, ///< [in] pitch + UINT_32 height, ///< [in] height + UINT_32 numSamples, ///< [in] number of samples + AddrTileMode tileMode, ///< [in] tile mode + UINT_32 tileBase, ///< [in] base offset within a tile + UINT_32 compBits, ///< [in] component bits actually needed(for planar surface) + UINT_32* pX, ///< [out] x coord + UINT_32* pY, ///< [out] y coord + UINT_32* pSlice, ///< [out] slice/depth index + UINT_32* pSample, ///< [out] sample index, + AddrTileType microTileType, ///< [in] micro tiling order + BOOL_32 isDepthSampleOrder ///< [in] TRUE if in depth sample order + ) const +{ + UINT_64 bitAddr; + UINT_32 microTileThickness; + UINT_32 microTileBits; + UINT_64 sliceBits; + UINT_64 rowBits; + UINT_32 sliceIndex; + UINT_32 microTileCoordX; + UINT_32 microTileCoordY; + UINT_32 pixelOffset; + UINT_32 pixelCoordX = 0; + UINT_32 pixelCoordY = 0; + UINT_32 pixelCoordZ = 0; + UINT_32 pixelCoordS = 0; + + // + // Convert byte address to bit address. + // + bitAddr = BYTES_TO_BITS(addr) + bitPosition; + + // + // Compute the micro tile size, in bits. + // + switch (tileMode) + { + case ADDR_TM_1D_TILED_THICK: + microTileThickness = ThickTileThickness; + break; + default: + microTileThickness = 1; + break; + } + + microTileBits = MicroTilePixels * microTileThickness * bpp * numSamples; + + // + // Compute number of bits per slice and number of bits per row of micro tiles. + // + sliceBits = static_cast<UINT_64>(pitch) * height * microTileThickness * bpp * numSamples; + + rowBits = (pitch / MicroTileWidth) * microTileBits; + + // + // Extract the slice index. + // + sliceIndex = static_cast<UINT_32>(bitAddr / sliceBits); + bitAddr -= sliceIndex * sliceBits; + + // + // Extract the y coordinate of the micro tile. + // + microTileCoordY = static_cast<UINT_32>(bitAddr / rowBits) * MicroTileHeight; + bitAddr -= (microTileCoordY / MicroTileHeight) * rowBits; + + // + // Extract the x coordinate of the micro tile. + // + microTileCoordX = static_cast<UINT_32>(bitAddr / microTileBits) * MicroTileWidth; + + // + // Compute the pixel offset within the micro tile. + // + pixelOffset = static_cast<UINT_32>(bitAddr % microTileBits); + + // + // Extract pixel coordinates from the offset. + // + HwlComputePixelCoordFromOffset(pixelOffset, + bpp, + numSamples, + tileMode, + tileBase, + compBits, + &pixelCoordX, + &pixelCoordY, + &pixelCoordZ, + &pixelCoordS, + microTileType, + isDepthSampleOrder); + + // + // Assemble final coordinates. + // + *pX = microTileCoordX + pixelCoordX; + *pY = microTileCoordY + pixelCoordY; + *pSlice = (sliceIndex * microTileThickness) + pixelCoordZ; + *pSample = pixelCoordS; + + if (microTileThickness > 1) + { + *pSample = 0; + } +} + +/** +*************************************************************************************************** +* AddrLib::ComputePipeFromAddr +* +* @brief +* Compute the pipe number from an address +* +* @return +* Pipe number +* +*************************************************************************************************** +*/ +UINT_32 AddrLib::ComputePipeFromAddr( + UINT_64 addr, ///< [in] address + UINT_32 numPipes ///< [in] number of banks + ) const +{ + UINT_32 pipe; + + UINT_32 groupBytes = m_pipeInterleaveBytes; //just different terms + + // R600 + // The LSBs of the address are arranged as follows: + // bank | pipe | group + // + // To get the pipe number, shift off the group bits and mask the pipe bits. + // + + // R800 + // The LSBs of the address are arranged as follows: + // bank | bankInterleave | pipe | pipeInterleave + // + // To get the pipe number, shift off the pipe interleave bits and mask the pipe bits. + // + + pipe = static_cast<UINT_32>(addr >> Log2(groupBytes)) & (numPipes - 1); + + return pipe; +} + +/** +*************************************************************************************************** +* AddrLib::ComputePixelIndexWithinMicroTile +* +* @brief +* Compute the pixel index inside a micro tile of surface +* +* @return +* Pixel index +* +*************************************************************************************************** +*/ +UINT_32 AddrLib::ComputePixelIndexWithinMicroTile( + UINT_32 x, ///< [in] x coord + UINT_32 y, ///< [in] y coord + UINT_32 z, ///< [in] slice/depth index + UINT_32 bpp, ///< [in] bits per pixel + AddrTileMode tileMode, ///< [in] tile mode + AddrTileType microTileType ///< [in] pixel order in display/non-display mode + ) const +{ + UINT_32 pixelBit0 = 0; + UINT_32 pixelBit1 = 0; + UINT_32 pixelBit2 = 0; + UINT_32 pixelBit3 = 0; + UINT_32 pixelBit4 = 0; + UINT_32 pixelBit5 = 0; + UINT_32 pixelBit6 = 0; + UINT_32 pixelBit7 = 0; + UINT_32 pixelBit8 = 0; + UINT_32 pixelNumber; + + UINT_32 x0 = _BIT(x, 0); + UINT_32 x1 = _BIT(x, 1); + UINT_32 x2 = _BIT(x, 2); + UINT_32 y0 = _BIT(y, 0); + UINT_32 y1 = _BIT(y, 1); + UINT_32 y2 = _BIT(y, 2); + UINT_32 z0 = _BIT(z, 0); + UINT_32 z1 = _BIT(z, 1); + UINT_32 z2 = _BIT(z, 2); + + UINT_32 thickness = ComputeSurfaceThickness(tileMode); + + // Compute the pixel number within the micro tile. + + if (microTileType != ADDR_THICK) + { + if (microTileType == ADDR_DISPLAYABLE) + { + switch (bpp) + { + case 8: + pixelBit0 = x0; + pixelBit1 = x1; + pixelBit2 = x2; + pixelBit3 = y1; + pixelBit4 = y0; + pixelBit5 = y2; + break; + case 16: + pixelBit0 = x0; + pixelBit1 = x1; + pixelBit2 = x2; + pixelBit3 = y0; + pixelBit4 = y1; + pixelBit5 = y2; + break; + case 32: + pixelBit0 = x0; + pixelBit1 = x1; + pixelBit2 = y0; + pixelBit3 = x2; + pixelBit4 = y1; + pixelBit5 = y2; + break; + case 64: + pixelBit0 = x0; + pixelBit1 = y0; + pixelBit2 = x1; + pixelBit3 = x2; + pixelBit4 = y1; + pixelBit5 = y2; + break; + case 128: + pixelBit0 = y0; + pixelBit1 = x0; + pixelBit2 = x1; + pixelBit3 = x2; + pixelBit4 = y1; + pixelBit5 = y2; + break; + default: + ADDR_ASSERT_ALWAYS(); + break; + } + } + else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER) + { + pixelBit0 = x0; + pixelBit1 = y0; + pixelBit2 = x1; + pixelBit3 = y1; + pixelBit4 = x2; + pixelBit5 = y2; + } + else if (microTileType == ADDR_ROTATED) + { + ADDR_ASSERT(thickness == 1); + + switch (bpp) + { + case 8: + pixelBit0 = y0; + pixelBit1 = y1; + pixelBit2 = y2; + pixelBit3 = x1; + pixelBit4 = x0; + pixelBit5 = x2; + break; + case 16: + pixelBit0 = y0; + pixelBit1 = y1; + pixelBit2 = y2; + pixelBit3 = x0; + pixelBit4 = x1; + pixelBit5 = x2; + break; + case 32: + pixelBit0 = y0; + pixelBit1 = y1; + pixelBit2 = x0; + pixelBit3 = y2; + pixelBit4 = x1; + pixelBit5 = x2; + break; + case 64: + pixelBit0 = y0; + pixelBit1 = x0; + pixelBit2 = y1; + pixelBit3 = x1; + pixelBit4 = x2; + pixelBit5 = y2; + break; + default: + ADDR_ASSERT_ALWAYS(); + break; + } + } + + if (thickness > 1) + { + pixelBit6 = z0; + pixelBit7 = z1; + } + } + else // ADDR_THICK + { + ADDR_ASSERT(thickness > 1); + + switch (bpp) + { + case 8: + case 16: + pixelBit0 = x0; + pixelBit1 = y0; + pixelBit2 = x1; + pixelBit3 = y1; + pixelBit4 = z0; + pixelBit5 = z1; + break; + case 32: + pixelBit0 = x0; + pixelBit1 = y0; + pixelBit2 = x1; + pixelBit3 = z0; + pixelBit4 = y1; + pixelBit5 = z1; + break; + case 64: + case 128: + pixelBit0 = y0; + pixelBit1 = x0; + pixelBit2 = z0; + pixelBit3 = x1; + pixelBit4 = y1; + pixelBit5 = z1; + break; + default: + ADDR_ASSERT_ALWAYS(); + break; + } + + pixelBit6 = x2; + pixelBit7 = y2; + } + + if (thickness == 8) + { + pixelBit8 = z2; + } + + pixelNumber = ((pixelBit0 ) | + (pixelBit1 << 1) | + (pixelBit2 << 2) | + (pixelBit3 << 3) | + (pixelBit4 << 4) | + (pixelBit5 << 5) | + (pixelBit6 << 6) | + (pixelBit7 << 7) | + (pixelBit8 << 8)); + + return pixelNumber; +} + +/** +*************************************************************************************************** +* AddrLib::AdjustPitchAlignment +* +* @brief +* Adjusts pitch alignment for flipping surface +* +* @return +* N/A +* +*************************************************************************************************** +*/ +VOID AddrLib::AdjustPitchAlignment( + ADDR_SURFACE_FLAGS flags, ///< [in] Surface flags + UINT_32* pPitchAlign ///< [out] Pointer to pitch alignment + ) const +{ + // Display engine hardwires lower 5 bit of GRPH_PITCH to ZERO which means 32 pixel alignment + // Maybe it will be fixed in future but let's make it general for now. + if (flags.display || flags.overlay) + { + *pPitchAlign = PowTwoAlign(*pPitchAlign, 32); + + if(flags.display) + { + *pPitchAlign = Max(m_minPitchAlignPixels, *pPitchAlign); + } + } +} + +/** +*************************************************************************************************** +* AddrLib::PadDimensions +* +* @brief +* Helper function to pad dimensions +* +* @return +* N/A +* +*************************************************************************************************** +*/ +VOID AddrLib::PadDimensions( + AddrTileMode tileMode, ///< [in] tile mode + UINT_32 bpp, ///< [in] bits per pixel + ADDR_SURFACE_FLAGS flags, ///< [in] surface flags + UINT_32 numSamples, ///< [in] number of samples + ADDR_TILEINFO* pTileInfo, ///< [in/out] bank structure. + UINT_32 padDims, ///< [in] Dimensions to pad valid value 1,2,3 + UINT_32 mipLevel, ///< [in] MipLevel + UINT_32* pPitch, ///< [in/out] pitch in pixels + UINT_32 pitchAlign, ///< [in] pitch alignment + UINT_32* pHeight, ///< [in/out] height in pixels + UINT_32 heightAlign, ///< [in] height alignment + UINT_32* pSlices, ///< [in/out] number of slices + UINT_32 sliceAlign ///< [in] number of slice alignment + ) const +{ + UINT_32 thickness = ComputeSurfaceThickness(tileMode); + + ADDR_ASSERT(padDims <= 3); + + // + // Override padding for mip levels + // + if (mipLevel > 0) + { + if (flags.cube) + { + // for cubemap, we only pad when client call with 6 faces as an identity + if (*pSlices > 1) + { + padDims = 3; // we should pad cubemap sub levels when we treat it as 3d texture + } + else + { + padDims = 2; + } + } + } + + // Any possibilities that padDims is 0? + if (padDims == 0) + { + padDims = 3; + } + + if (IsPow2(pitchAlign)) + { + *pPitch = PowTwoAlign((*pPitch), pitchAlign); + } + else // add this code to pass unit test, r600 linear mode is not align bpp to pow2 for linear + { + *pPitch += pitchAlign - 1; + *pPitch /= pitchAlign; + *pPitch *= pitchAlign; + } + + if (padDims > 1) + { + *pHeight = PowTwoAlign((*pHeight), heightAlign); + } + + if (padDims > 2 || thickness > 1) + { + // for cubemap single face, we do not pad slices. + // if we pad it, the slice number should be set to 6 and current mip level > 1 + if (flags.cube && (!m_configFlags.noCubeMipSlicesPad || flags.cubeAsArray)) + { + *pSlices = NextPow2(*pSlices); + } + + // normal 3D texture or arrays or cubemap has a thick mode? (Just pass unit test) + if (thickness > 1) + { + *pSlices = PowTwoAlign((*pSlices), sliceAlign); + } + + } + + HwlPadDimensions(tileMode, + bpp, + flags, + numSamples, + pTileInfo, + padDims, + mipLevel, + pPitch, + pitchAlign, + pHeight, + heightAlign, + pSlices, + sliceAlign); +} + + +/** +*************************************************************************************************** +* AddrLib::HwlPreHandleBaseLvl3xPitch +* +* @brief +* Pre-handler of 3x pitch (96 bit) adjustment +* +* @return +* Expected pitch +*************************************************************************************************** +*/ +UINT_32 AddrLib::HwlPreHandleBaseLvl3xPitch( + const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input + UINT_32 expPitch ///< [in] pitch + ) const +{ + ADDR_ASSERT(pIn->width == expPitch); + // + // If pitch is pre-multiplied by 3, we retrieve original one here to get correct miplevel size + // + if (AddrElemLib::IsExpand3x(pIn->format) && + pIn->mipLevel == 0 && + pIn->tileMode == ADDR_TM_LINEAR_ALIGNED) + { + expPitch /= 3; + expPitch = NextPow2(expPitch); + } + + return expPitch; +} + +/** +*************************************************************************************************** +* AddrLib::HwlPostHandleBaseLvl3xPitch +* +* @brief +* Post-handler of 3x pitch adjustment +* +* @return +* Expected pitch +*************************************************************************************************** +*/ +UINT_32 AddrLib::HwlPostHandleBaseLvl3xPitch( + const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input + UINT_32 expPitch ///< [in] pitch + ) const +{ + // + // 96 bits surface of sub levels require element pitch of 32 bits instead + // So we just return pitch in 32 bit pixels without timing 3 + // + if (AddrElemLib::IsExpand3x(pIn->format) && + pIn->mipLevel == 0 && + pIn->tileMode == ADDR_TM_LINEAR_ALIGNED) + { + expPitch *= 3; + } + + return expPitch; +} + + +/** +*************************************************************************************************** +* AddrLib::IsMacroTiled +* +* @brief +* Check if the tile mode is macro tiled +* +* @return +* TRUE if it is macro tiled (2D/2B/3D/3B) +*************************************************************************************************** +*/ +BOOL_32 AddrLib::IsMacroTiled( + AddrTileMode tileMode) ///< [in] tile mode +{ + return m_modeFlags[tileMode].isMacro; +} + +/** +*************************************************************************************************** +* AddrLib::IsMacro3dTiled +* +* @brief +* Check if the tile mode is 3D macro tiled +* +* @return +* TRUE if it is 3D macro tiled +*************************************************************************************************** +*/ +BOOL_32 AddrLib::IsMacro3dTiled( + AddrTileMode tileMode) ///< [in] tile mode +{ + return m_modeFlags[tileMode].isMacro3d; +} + +/** +*************************************************************************************************** +* AddrLib::IsMicroTiled +* +* @brief +* Check if the tile mode is micro tiled +* +* @return +* TRUE if micro tiled +*************************************************************************************************** +*/ +BOOL_32 AddrLib::IsMicroTiled( + AddrTileMode tileMode) ///< [in] tile mode +{ + return m_modeFlags[tileMode].isMicro; +} + +/** +*************************************************************************************************** +* AddrLib::IsLinear +* +* @brief +* Check if the tile mode is linear +* +* @return +* TRUE if linear +*************************************************************************************************** +*/ +BOOL_32 AddrLib::IsLinear( + AddrTileMode tileMode) ///< [in] tile mode +{ + return m_modeFlags[tileMode].isLinear; +} + +/** +*************************************************************************************************** +* AddrLib::IsPrtNoRotationTileMode +* +* @brief +* Return TRUE if it is prt tile without rotation +* @note +* This function just used by CI +*************************************************************************************************** +*/ +BOOL_32 AddrLib::IsPrtNoRotationTileMode( + AddrTileMode tileMode) +{ + return m_modeFlags[tileMode].isPrtNoRotation; +} + +/** +*************************************************************************************************** +* AddrLib::IsPrtTileMode +* +* @brief +* Return TRUE if it is prt tile +* @note +* This function just used by CI +*************************************************************************************************** +*/ +BOOL_32 AddrLib::IsPrtTileMode( + AddrTileMode tileMode) +{ + return m_modeFlags[tileMode].isPrt; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeMipLevel +* +* @brief +* Compute mipmap level width/height/slices +* @return +* N/A +*************************************************************************************************** +*/ +VOID AddrLib::ComputeMipLevel( + ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in/out] Input structure + ) const +{ + if (AddrElemLib::IsBlockCompressed(pIn->format)) + { + if (pIn->mipLevel == 0) + { + // DXTn's level 0 must be multiple of 4 + // But there are exceptions: + // 1. Internal surface creation in hostblt/vsblt/etc... + // 2. Runtime doesn't reject ATI1/ATI2 whose width/height are not multiple of 4 + pIn->width = PowTwoAlign(pIn->width, 4); + pIn->height = PowTwoAlign(pIn->height, 4); + } + } + + HwlComputeMipLevel(pIn); +} + +/** +*************************************************************************************************** +* AddrLib::OptimizeTileMode +* +* @brief +* Check if base level's tile mode can be optimized (degraded) +* @return +* TRUE if degraded, also returns degraded tile mode (unchanged if not degraded) +*************************************************************************************************** +*/ +BOOL_32 AddrLib::OptimizeTileMode( + const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure for surface info + AddrTileMode* pTileMode ///< [out] Degraded tile mode + ) const +{ + AddrTileMode tileMode = pIn->tileMode; + UINT_32 thickness = ComputeSurfaceThickness(tileMode); + + // Optimization can only be done on level 0 and samples <= 1 + if ((pIn->flags.opt4Space == TRUE) && + (pIn->mipLevel == 0) && + (pIn->numSamples <= 1) && + (pIn->flags.display == FALSE) && + (IsPrtTileMode(tileMode) == FALSE) && + (pIn->flags.prt == FALSE)) + { + // Check if linear mode is optimal + if ((pIn->height == 1) && + (IsLinear(tileMode) == FALSE) && + (AddrElemLib::IsBlockCompressed(pIn->format) == FALSE) && + (pIn->flags.depth == FALSE) && + (pIn->flags.stencil == FALSE) && + (m_configFlags.disableLinearOpt == FALSE) && + (pIn->flags.disableLinearOpt == FALSE)) + { + tileMode = ADDR_TM_LINEAR_ALIGNED; + } + else if (IsMacroTiled(tileMode)) + { + if (HwlDegradeBaseLevel(pIn)) + { + tileMode = (thickness == 1) ? ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK; + } + else if (thickness > 1) + { + // As in the following HwlComputeSurfaceInfo, thick modes may be degraded to + // thinner modes, we should re-evaluate whether the corresponding thinner modes + // need to be degraded. If so, we choose 1D thick mode instead. + tileMode = DegradeLargeThickTile(pIn->tileMode, pIn->bpp); + if (tileMode != pIn->tileMode) + { + ADDR_COMPUTE_SURFACE_INFO_INPUT input = *pIn; + input.tileMode = tileMode; + if (HwlDegradeBaseLevel(&input)) + { + tileMode = ADDR_TM_1D_TILED_THICK; + } + } + } + } + } + + BOOL_32 optimized = (tileMode != pIn->tileMode); + if (optimized) + { + *pTileMode = tileMode; + } + return optimized; +} + +/** +*************************************************************************************************** +* AddrLib::DegradeLargeThickTile +* +* @brief +* Check if the thickness needs to be reduced if a tile is too large +* @return +* The degraded tile mode (unchanged if not degraded) +*************************************************************************************************** +*/ +AddrTileMode AddrLib::DegradeLargeThickTile( + AddrTileMode tileMode, + UINT_32 bpp) const +{ + // Override tilemode + // When tile_width (8) * tile_height (8) * thickness * element_bytes is > row_size, + // it is better to just use THIN mode in this case + UINT_32 thickness = ComputeSurfaceThickness(tileMode); + + if (thickness > 1 && m_configFlags.allowLargeThickTile == 0) + { + UINT_32 tileSize = MicroTilePixels * thickness * (bpp >> 3); + + if (tileSize > m_rowSize) + { + switch (tileMode) + { + case ADDR_TM_2D_TILED_XTHICK: + if ((tileSize >> 1) <= m_rowSize) + { + tileMode = ADDR_TM_2D_TILED_THICK; + break; + } + // else fall through + case ADDR_TM_2D_TILED_THICK: + tileMode = ADDR_TM_2D_TILED_THIN1; + break; + + case ADDR_TM_3D_TILED_XTHICK: + if ((tileSize >> 1) <= m_rowSize) + { + tileMode = ADDR_TM_3D_TILED_THICK; + break; + } + // else fall through + case ADDR_TM_3D_TILED_THICK: + tileMode = ADDR_TM_3D_TILED_THIN1; + break; + + case ADDR_TM_PRT_TILED_THICK: + tileMode = ADDR_TM_PRT_TILED_THIN1; + break; + + case ADDR_TM_PRT_2D_TILED_THICK: + tileMode = ADDR_TM_PRT_2D_TILED_THIN1; + break; + + case ADDR_TM_PRT_3D_TILED_THICK: + tileMode = ADDR_TM_PRT_3D_TILED_THIN1; + break; + + default: + break; + } + } + } + + return tileMode; +} + +/** +*************************************************************************************************** +* AddrLib::PostComputeMipLevel +* @brief +* Compute MipLevel info (including level 0) after surface adjustment +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::PostComputeMipLevel( + ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in/out] Input structure + ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] Output structure + ) const +{ + // Mipmap including level 0 must be pow2 padded since either SI hw expects so or it is + // required by CFX for Hw Compatibility between NI and SI. Otherwise it is only needed for + // mipLevel > 0. Any h/w has different requirement should implement its own virtual function + + if (pIn->flags.pow2Pad) + { + pIn->width = NextPow2(pIn->width); + pIn->height = NextPow2(pIn->height); + pIn->numSlices = NextPow2(pIn->numSlices); + } + else if (pIn->mipLevel > 0) + { + pIn->width = NextPow2(pIn->width); + pIn->height = NextPow2(pIn->height); + + if (!pIn->flags.cube) + { + pIn->numSlices = NextPow2(pIn->numSlices); + } + + // for cubemap, we keep its value at first + } + + return ADDR_OK; +} + +/** +*************************************************************************************************** +* AddrLib::HwlSetupTileCfg +* +* @brief +* Map tile index to tile setting. +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::HwlSetupTileCfg( + INT_32 index, ///< [in] Tile index + INT_32 macroModeIndex, ///< [in] Index in macro tile mode table(CI) + ADDR_TILEINFO* pInfo, ///< [out] Tile Info + AddrTileMode* pMode, ///< [out] Tile mode + AddrTileType* pType ///< [out] Tile type + ) const +{ + return ADDR_NOTSUPPORTED; +} + +/** +*************************************************************************************************** +* AddrLib::HwlGetPipes +* +* @brief +* Get number pipes +* @return +* num pipes +*************************************************************************************************** +*/ +UINT_32 AddrLib::HwlGetPipes( + const ADDR_TILEINFO* pTileInfo ///< [in] Tile info + ) const +{ + //pTileInfo can be NULL when asic is 6xx and 8xx. + return m_pipes; +} + +/** +*************************************************************************************************** +* AddrLib::ComputeQbStereoInfo +* +* @brief +* Get quad buffer stereo information +* @return +* TRUE if no error +*************************************************************************************************** +*/ +BOOL_32 AddrLib::ComputeQbStereoInfo( + ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in/out] updated pOut+pStereoInfo + ) const +{ + BOOL_32 success = FALSE; + + if (pOut->pStereoInfo) + { + ADDR_ASSERT(pOut->bpp >= 8); + ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0); + + // Save original height + pOut->pStereoInfo->eyeHeight = pOut->height; + + // Right offset + pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize); + + pOut->pStereoInfo->rightSwizzle = HwlComputeQbStereoRightSwizzle(pOut); + // Double height + pOut->height <<= 1; + pOut->pixelHeight <<= 1; + + // Double size + pOut->surfSize <<= 1; + + // Right start address meets the base align since it is guaranteed by AddrLib + + // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo. + success = TRUE; + } + + return success; +} + +/** +*************************************************************************************************** +* AddrLib::ComputePrtInfo +* +* @brief +* Compute prt surface related info +* +* @return +* ADDR_E_RETURNCODE +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE AddrLib::ComputePrtInfo( + const ADDR_PRT_INFO_INPUT* pIn, + ADDR_PRT_INFO_OUTPUT* pOut) const +{ + ADDR_ASSERT(pOut != NULL); + + ADDR_E_RETURNCODE returnCode = ADDR_OK; + + UINT_32 expandX = 1; + UINT_32 expandY = 1; + AddrElemMode elemMode; + + UINT_32 bpp = GetElemLib()->GetBitsPerPixel(pIn->format, + &elemMode, + &expandX, + &expandY); + + if (bpp <8 || bpp == 24 || bpp == 48 || bpp == 96 ) + { + returnCode = ADDR_INVALIDPARAMS; + } + + UINT_32 numFrags = pIn->numFrags; + ADDR_ASSERT(numFrags <= 8); + + UINT_32 tileWidth = 0; + UINT_32 tileHeight = 0; + if (returnCode == ADDR_OK) + { + // 3D texture without depth or 2d texture + if (pIn->baseMipDepth > 1 || pIn->baseMipHeight > 1) + { + if (bpp == 8) + { + tileWidth = 256; + tileHeight = 256; + } + else if (bpp == 16) + { + tileWidth = 256; + tileHeight = 128; + } + else if (bpp == 32) + { + tileWidth = 128; + tileHeight = 128; + } + else if (bpp == 64) + { + // assume it is BC1/4 + tileWidth = 512; + tileHeight = 256; + + if (elemMode == ADDR_UNCOMPRESSED) + { + tileWidth = 128; + tileHeight = 64; + } + } + else if (bpp == 128) + { + // assume it is BC2/3/5/6H/7 + tileWidth = 256; + tileHeight = 256; + + if (elemMode == ADDR_UNCOMPRESSED) + { + tileWidth = 64; + tileHeight = 64; + } + } + + if (numFrags == 2) + { + tileWidth = tileWidth / 2; + } + else if (numFrags == 4) + { + tileWidth = tileWidth / 2; + tileHeight = tileHeight / 2; + } + else if (numFrags == 8) + { + tileWidth = tileWidth / 4; + tileHeight = tileHeight / 2; + } + } + else // 1d + { + tileHeight = 1; + if (bpp == 8) + { + tileWidth = 65536; + } + else if (bpp == 16) + { + tileWidth = 32768; + } + else if (bpp == 32) + { + tileWidth = 16384; + } + else if (bpp == 64) + { + tileWidth = 8192; + } + else if (bpp == 128) + { + tileWidth = 4096; + } + } + } + + pOut->prtTileWidth = tileWidth; + pOut->prtTileHeight = tileHeight; + + return returnCode; +} diff --git a/src/amd/addrlib/core/addrlib1.h b/src/amd/addrlib/core/addrlib1.h new file mode 100644 index 00000000000..f0f8d56842c --- /dev/null +++ b/src/amd/addrlib/core/addrlib1.h @@ -0,0 +1,47 @@ +/* + * Copyright © 2016 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. + */ + +#ifndef __ADDR_LIB1_H__ +#define __ADDR_LIB1_H__ + +#include "addrlib.h" + + +/** +*************************************************************************************************** +* @brief Neutral enums that define bank swap size +*************************************************************************************************** +*/ +enum AddrSampleSplitSize +{ + ADDR_SAMPLESPLIT_1KB = 1024, + ADDR_SAMPLESPLIT_2KB = 2048, + ADDR_SAMPLESPLIT_4KB = 4096, + ADDR_SAMPLESPLIT_8KB = 8192, +}; + + +#endif |