#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
return static_cast<AddrLib *>(hLib);
}
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Surface Methods
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-
/**
***************************************************************************************************
-* AddrLib::ComputeSurfaceInfo
+* AddrLib::GetMaxAlignments
*
* @brief
-* Interface function stub of AddrComputeSurfaceInfo.
+* Gets maximum alignments
*
* @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 AddrLib::GetMaxAlignments(
+ ADDR_GET_MAX_ALINGMENTS_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)))
+ if (pOut->size != sizeof(ADDR_GET_MAX_ALINGMENTS_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;
- }
+ returnCode = HwlGetMaxAlignments(pOut);
}
return returnCode;
/**
***************************************************************************************************
-* AddrLib::ComputeSurfaceInfo
+* AddrLib::Bits2Number
*
* @brief
-* Interface function stub of AddrComputeSurfaceInfo.
+* Cat a array of binary bit to a number
*
* @return
-* ADDR_E_RETURNCODE
+* The number combined with the array of bits
***************************************************************************************************
*/
-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
+UINT_32 AddrLib::Bits2Number(
+ UINT_32 bitNum, ///< [in] how many bits
+ ...) ///< [in] varaible bits value starting from MSB
{
- ADDR_E_RETURNCODE returnCode = ADDR_OK;
+ UINT_32 number = 0;
+ UINT_32 i;
+ va_list bits_ptr;
- if (GetFillSizeFieldsFlags() == TRUE)
+ va_start(bits_ptr, bitNum);
+
+ for(i = 0; i < bitNum; i++)
{
- if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) ||
- (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT)))
- {
- returnCode = ADDR_PARAMSIZEMISMATCH;
- }
+ number |= va_arg(bits_ptr, UINT_32);
+ number <<= 1;
}
- if (returnCode == ADDR_OK)
- {
- ADDR_TILEINFO tileInfoNull;
- ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT input;
+ number>>=1;
- 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;
- }
+ va_end(bits_ptr);
- if (returnCode == ADDR_OK)
- {
- returnCode = HwlComputeSurfaceAddrFromCoord(pIn, pOut);
+ return number;
+}
- if (returnCode == ADDR_OK)
- {
- pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024));
- }
- }
- }
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Element lib
+///////////////////////////////////////////////////////////////////////////////////////////////////
- return returnCode;
-}
/**
***************************************************************************************************
-* AddrLib::ComputeSurfaceCoordFromAddr
+* AddrLib::Flt32ToColorPixel
*
* @brief
-* Interface function stub of ComputeSurfaceCoordFromAddr.
-*
+* Convert a FLT_32 value to a depth/stencil pixel value
* @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 AddrLib::Flt32ToDepthPixel(
+ const ELEM_FLT32TODEPTHPIXEL_INPUT* pIn,
+ ELEM_FLT32TODEPTHPIXEL_OUTPUT* pOut) 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)))
+ if ((pIn->size != sizeof(ELEM_FLT32TODEPTHPIXEL_INPUT)) ||
+ (pOut->size != sizeof(ELEM_FLT32TODEPTHPIXEL_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;
- }
+ GetElemLib()->Flt32ToDepthPixel(pIn->format,
+ pIn->comps,
+ pOut->pPixel);
+ UINT_32 depthBase = 0;
+ UINT_32 stencilBase = 0;
+ UINT_32 depthBits = 0;
+ UINT_32 stencilBits = 0;
- if (returnCode == ADDR_OK)
+ switch (pIn->format)
{
- returnCode = HwlComputeSurfaceCoordFromAddr(pIn, pOut);
+ case ADDR_DEPTH_16:
+ depthBits = 16;
+ break;
+ case ADDR_DEPTH_X8_24:
+ case ADDR_DEPTH_8_24:
+ case ADDR_DEPTH_X8_24_FLOAT:
+ case ADDR_DEPTH_8_24_FLOAT:
+ depthBase = 8;
+ depthBits = 24;
+ stencilBits = 8;
+ break;
+ case ADDR_DEPTH_32_FLOAT:
+ depthBits = 32;
+ break;
+ case ADDR_DEPTH_X24_8_32_FLOAT:
+ depthBase = 8;
+ depthBits = 32;
+ stencilBits = 8;
+ break;
+ default:
+ break;
}
- }
-
- 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)))
+ // Overwrite base since R800 has no "tileBase"
+ if (GetElemLib()->IsDepthStencilTilePlanar() == FALSE)
{
- returnCode = ADDR_PARAMSIZEMISMATCH;
+ depthBase = 0;
+ stencilBase = 0;
}
- }
-
- 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;
- }
+ depthBase *= 64;
+ stencilBase *= 64;
- if (returnCode == ADDR_OK)
- {
- returnCode = HwlComputeSliceTileSwizzle(pIn, pOut);
- }
+ pOut->stencilBase = stencilBase;
+ pOut->depthBase = depthBase;
+ pOut->depthBits = depthBits;
+ pOut->stencilBits = stencilBits;
}
return returnCode;
/**
***************************************************************************************************
-* AddrLib::ExtractBankPipeSwizzle
+* AddrLib::Flt32ToColorPixel
*
* @brief
-* Interface function stub of AddrExtractBankPipeSwizzle.
-*
+* Convert a FLT_32 value to a red/green/blue/alpha pixel value
* @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 AddrLib::Flt32ToColorPixel(
+ const ELEM_FLT32TOCOLORPIXEL_INPUT* pIn,
+ ELEM_FLT32TOCOLORPIXEL_OUTPUT* pOut) 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)))
+ if ((pIn->size != sizeof(ELEM_FLT32TOCOLORPIXEL_INPUT)) ||
+ (pOut->size != sizeof(ELEM_FLT32TOCOLORPIXEL_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);
- }
+ GetElemLib()->Flt32ToColorPixel(pIn->format,
+ pIn->surfNum,
+ pIn->surfSwap,
+ pIn->comps,
+ pOut->pPixel);
}
return returnCode;
}
+
/**
***************************************************************************************************
-* AddrLib::CombineBankPipeSwizzle
+* AddrLib::GetExportNorm
*
* @brief
-* Interface function stub of AddrCombineBankPipeSwizzle.
-*
+* Check one format can be EXPORT_NUM
* @return
-* ADDR_E_RETURNCODE
+* TRUE if EXPORT_NORM can be used
***************************************************************************************************
*/
-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
+BOOL_32 AddrLib::GetExportNorm(
+ const ELEM_GETEXPORTNORM_INPUT* pIn) const
{
ADDR_E_RETURNCODE returnCode = ADDR_OK;
+ BOOL_32 enabled = FALSE;
+
if (GetFillSizeFieldsFlags() == TRUE)
{
- if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) ||
- (pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT)))
+ if (pIn->size != sizeof(ELEM_GETEXPORTNORM_INPUT))
{
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);
- }
+ enabled = GetElemLib()->PixGetExportNorm(pIn->format,
+ pIn->num,
+ pIn->swap);
}
- return returnCode;
+ return enabled;
}
-/**
-***************************************************************************************************
-* 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
-*
-* @brief
-* Gets maximum alignments
-*
-* @return
-* ADDR_E_RETURNCODE
-***************************************************************************************************
-*/
-ADDR_E_RETURNCODE AddrLib::GetMaxAlignments(
- ADDR_GET_MAX_ALINGMENTS_OUTPUT* pOut ///< [out] output structure
- ) const
-{
- ADDR_E_RETURNCODE returnCode = ADDR_OK;
-
- if (GetFillSizeFieldsFlags() == TRUE)
- {
- if (pOut->size != sizeof(ADDR_GET_MAX_ALINGMENTS_OUTPUT))
- {
- returnCode = ADDR_PARAMSIZEMISMATCH;
- }
- }
-
- if (returnCode == ADDR_OK)
- {
- returnCode = HwlGetMaxAlignments(pOut);
- }
-
- 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::Bits2Number
-*
-* @brief
-* Cat a array of binary bit to a number
-*
-* @return
-* The number combined with the array of bits
-***************************************************************************************************
-*/
-UINT_32 AddrLib::Bits2Number(
- UINT_32 bitNum, ///< [in] how many bits
- ...) ///< [in] varaible bits value starting from MSB
-{
- UINT_32 number = 0;
- UINT_32 i;
- va_list bits_ptr;
-
- va_start(bits_ptr, bitNum);
-
- for(i = 0; i < bitNum; i++)
- {
- number |= va_arg(bits_ptr, UINT_32);
- number <<= 1;
- }
-
- number>>=1;
-
- va_end(bits_ptr);
-
- 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
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-
-/**
-***************************************************************************************************
-* AddrLib::Flt32ToColorPixel
-*
-* @brief
-* Convert a FLT_32 value to a depth/stencil pixel value
-* @return
-* ADDR_E_RETURNCODE
-***************************************************************************************************
-*/
-ADDR_E_RETURNCODE AddrLib::Flt32ToDepthPixel(
- const ELEM_FLT32TODEPTHPIXEL_INPUT* pIn,
- ELEM_FLT32TODEPTHPIXEL_OUTPUT* pOut) const
-{
- ADDR_E_RETURNCODE returnCode = ADDR_OK;
-
- if (GetFillSizeFieldsFlags() == TRUE)
- {
- if ((pIn->size != sizeof(ELEM_FLT32TODEPTHPIXEL_INPUT)) ||
- (pOut->size != sizeof(ELEM_FLT32TODEPTHPIXEL_OUTPUT)))
- {
- returnCode = ADDR_PARAMSIZEMISMATCH;
- }
- }
-
- if (returnCode == ADDR_OK)
- {
- GetElemLib()->Flt32ToDepthPixel(pIn->format,
- pIn->comps,
- pOut->pPixel);
- UINT_32 depthBase = 0;
- UINT_32 stencilBase = 0;
- UINT_32 depthBits = 0;
- UINT_32 stencilBits = 0;
-
- switch (pIn->format)
- {
- case ADDR_DEPTH_16:
- depthBits = 16;
- break;
- case ADDR_DEPTH_X8_24:
- case ADDR_DEPTH_8_24:
- case ADDR_DEPTH_X8_24_FLOAT:
- case ADDR_DEPTH_8_24_FLOAT:
- depthBase = 8;
- depthBits = 24;
- stencilBits = 8;
- break;
- case ADDR_DEPTH_32_FLOAT:
- depthBits = 32;
- break;
- case ADDR_DEPTH_X24_8_32_FLOAT:
- depthBase = 8;
- depthBits = 32;
- stencilBits = 8;
- break;
- default:
- break;
- }
-
- // Overwrite base since R800 has no "tileBase"
- if (GetElemLib()->IsDepthStencilTilePlanar() == FALSE)
- {
- depthBase = 0;
- stencilBase = 0;
- }
-
- depthBase *= 64;
- stencilBase *= 64;
-
- pOut->stencilBase = stencilBase;
- pOut->depthBase = depthBase;
- pOut->depthBits = depthBits;
- pOut->stencilBits = stencilBits;
- }
-
- return returnCode;
-}
-
-/**
-***************************************************************************************************
-* AddrLib::Flt32ToColorPixel
-*
-* @brief
-* Convert a FLT_32 value to a red/green/blue/alpha pixel value
-* @return
-* ADDR_E_RETURNCODE
-***************************************************************************************************
-*/
-ADDR_E_RETURNCODE AddrLib::Flt32ToColorPixel(
- const ELEM_FLT32TOCOLORPIXEL_INPUT* pIn,
- ELEM_FLT32TOCOLORPIXEL_OUTPUT* pOut) const
-{
- ADDR_E_RETURNCODE returnCode = ADDR_OK;
-
- if (GetFillSizeFieldsFlags() == TRUE)
- {
- if ((pIn->size != sizeof(ELEM_FLT32TOCOLORPIXEL_INPUT)) ||
- (pOut->size != sizeof(ELEM_FLT32TOCOLORPIXEL_OUTPUT)))
- {
- returnCode = ADDR_PARAMSIZEMISMATCH;
- }
- }
-
- if (returnCode == ADDR_OK)
- {
- GetElemLib()->Flt32ToColorPixel(pIn->format,
- pIn->surfNum,
- pIn->surfSwap,
- pIn->comps,
- pOut->pPixel);
- }
-
- return returnCode;
-}
-
-
-/**
-***************************************************************************************************
-* AddrLib::GetExportNorm
-*
-* @brief
-* Check one format can be EXPORT_NUM
-* @return
-* TRUE if EXPORT_NORM can be used
-***************************************************************************************************
-*/
-BOOL_32 AddrLib::GetExportNorm(
- const ELEM_GETEXPORTNORM_INPUT* pIn) const
-{
- ADDR_E_RETURNCODE returnCode = ADDR_OK;
-
- BOOL_32 enabled = FALSE;
-
- if (GetFillSizeFieldsFlags() == TRUE)
- {
- if (pIn->size != sizeof(ELEM_GETEXPORTNORM_INPUT))
- {
- returnCode = ADDR_PARAMSIZEMISMATCH;
- }
- }
-
- if (returnCode == ADDR_OK)
- {
- enabled = GetElemLib()->PixGetExportNorm(pIn->format,
- pIn->num,
- pIn->swap);
- }
-
- 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;
-}
--- /dev/null
+/*
+ * 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;
+}