[Mesa-dev] [PATCH 031/140] amdgpu/addrlib: Add a new tile mode ADDR_TM_UNKNOWN
Marek Olšák
maraeo at gmail.com
Mon Mar 20 22:42:41 UTC 2017
From: Frans Gu <frans.gu at amd.com>
This can be used by address lib client to ask address lib to select
tile mode.
---
src/amd/addrlib/addrinterface.h | 3 +-
src/amd/addrlib/addrtypes.h | 3 +-
src/amd/addrlib/core/addrlib1.cpp | 32 +++++++++----
src/amd/addrlib/core/addrlib1.h | 11 +++--
src/amd/addrlib/r800/ciaddrlib.cpp | 96 ++++++++++++++++++++++++++++++++++++++
src/amd/addrlib/r800/ciaddrlib.h | 2 +
src/amd/addrlib/r800/siaddrlib.cpp | 76 ++++++++++++++++++++++++++++++
src/amd/addrlib/r800/siaddrlib.h | 2 +
8 files changed, 211 insertions(+), 14 deletions(-)
diff --git a/src/amd/addrlib/addrinterface.h b/src/amd/addrlib/addrinterface.h
index 3604fb1..fef8d49 100644
--- a/src/amd/addrlib/addrinterface.h
+++ b/src/amd/addrlib/addrinterface.h
@@ -507,21 +507,22 @@ typedef union _ADDR_SURFACE_FLAGS
/// This flag indicates we need to follow the
/// alignment with CZ families or other ASICs under
/// PX configuration + CZ.
UINT_32 nonSplit : 1; ///< CI: depth texture should not be split
UINT_32 disableLinearOpt : 1; ///< Disable tile mode optimization to linear
UINT_32 needEquation : 1; ///< Make the surface tile setting equation compatible.
/// This flag indicates we need to override tile
/// mode to PRT_* tile mode to disable slice rotation,
/// which is needed by swizzle pattern equation.
UINT_32 skipIndicesOutput : 1; ///< Skipping indices in output.
- UINT_32 reserved : 7; ///< Reserved bits
+ UINT_32 rotateDisplay : 1; ///< Rotate micro tile type
+ UINT_32 reserved : 6; ///< Reserved bits
};
UINT_32 value;
} ADDR_SURFACE_FLAGS;
/**
***************************************************************************************************
* ADDR_COMPUTE_SURFACE_INFO_INPUT
*
* @brief
diff --git a/src/amd/addrlib/addrtypes.h b/src/amd/addrlib/addrtypes.h
index fb8e706..681bb24 100644
--- a/src/amd/addrlib/addrtypes.h
+++ b/src/amd/addrlib/addrtypes.h
@@ -188,21 +188,22 @@ typedef enum _AddrTileMode
ADDR_TM_3B_TILED_THICK = 15, ///< 600 HWL only, with bank swap, thick
ADDR_TM_2D_TILED_XTHICK = 16, ///< Tile is 8x8x8, valid from NI
ADDR_TM_3D_TILED_XTHICK = 17, ///< Tile is 8x8x8, valid from NI
ADDR_TM_POWER_SAVE = 18, ///< Power save mode, only used by KMD on NI
ADDR_TM_PRT_TILED_THIN1 = 19, ///< No bank/pipe rotation or hashing beyond macrotile size
ADDR_TM_PRT_2D_TILED_THIN1 = 20, ///< Same as 2D_TILED_THIN1, PRT only
ADDR_TM_PRT_3D_TILED_THIN1 = 21, ///< Same as 3D_TILED_THIN1, PRT only
ADDR_TM_PRT_TILED_THICK = 22, ///< No bank/pipe rotation or hashing beyond macrotile size
ADDR_TM_PRT_2D_TILED_THICK = 23, ///< Same as 2D_TILED_THICK, PRT only
ADDR_TM_PRT_3D_TILED_THICK = 24, ///< Same as 3D_TILED_THICK, PRT only
- ADDR_TM_COUNT = 25, ///< Must be the value of the last tile mode
+ ADDR_TM_UNKNOWN = 25, ///< Unkown tile mode, should be decided by address lib
+ ADDR_TM_COUNT = 26, ///< Must be the value of the last tile mode
} AddrTileMode;
/**
***************************************************************************************************
* AddrFormat
*
* @brief
* Neutral enum for SurfaceFormat
*
***************************************************************************************************
diff --git a/src/amd/addrlib/core/addrlib1.cpp b/src/amd/addrlib/core/addrlib1.cpp
index 5e68f27..e4570cc 100644
--- a/src/amd/addrlib/core/addrlib1.cpp
+++ b/src/amd/addrlib/core/addrlib1.cpp
@@ -60,20 +60,21 @@ const AddrTileModeFlags AddrLib1::ModeFlags[ADDR_TM_COUNT] =
{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
+ {0, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_UNKNOWN
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// Constructor/Destructor
///////////////////////////////////////////////////////////////////////////////////////////////////
/**
***************************************************************************************************
* AddrLib1::AddrLib1
*
@@ -172,22 +173,27 @@ ADDR_E_RETURNCODE AddrLib1::ComputeSurfaceInfo(
returnCode = ADDR_PARAMSIZEMISMATCH;
}
}
// We suggest client do sanity check but a check here is also good
if (pIn->bpp > 128)
{
returnCode = ADDR_INVALIDPARAMS;
}
+ if ((pIn->tileMode == ADDR_TM_UNKNOWN) && (pIn->mipLevel > 0))
+ {
+ returnCode = ADDR_INVALIDPARAMS;
+ }
+
// Thick modes don't support multisample
- if (Thickness(pIn->tileMode) > 1 && pIn->numSamples > 1)
+ if ((Thickness(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};
@@ -195,21 +201,21 @@ ADDR_E_RETURNCODE AddrLib1::ComputeSurfaceInfo(
{
// 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;
+ 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;
}
@@ -317,29 +323,37 @@ ADDR_E_RETURNCODE AddrLib1::ComputeSurfaceInfo(
{
ADDR_ASSERT(!IsMacroTiled(localIn.tileMode));
}
pOut->macroModeIndex = macroModeIndex;
}
}
if (returnCode == ADDR_OK)
{
- // HWL layer may override tile mode if necessary
- HwlOverrideTileMode(&localIn);
+ if (localIn.tileMode == ADDR_TM_UNKNOWN)
+ {
+ // HWL layer may override tile mode if necessary
+ HwlSelectTileMode(&localIn);
+ }
+ else
+ {
+ // HWL layer may override tile mode if necessary
+ HwlOverrideTileMode(&localIn);
- AddrTileMode tileMode = localIn.tileMode;
+ AddrTileMode tileMode = localIn.tileMode;
- // Optimize tile mode if possible
- if (OptimizeTileMode(&localIn, &tileMode))
- {
- localIn.tileMode = tileMode;
+ // 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)
diff --git a/src/amd/addrlib/core/addrlib1.h b/src/amd/addrlib/core/addrlib1.h
index 6ca5826..99e8a9a 100644
--- a/src/amd/addrlib/core/addrlib1.h
+++ b/src/amd/addrlib/core/addrlib1.h
@@ -344,20 +344,25 @@ protected:
/// Pure Virtual function for Hwl checking degrade for base level
virtual BOOL_32 HwlDegradeBaseLevel(
const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const = 0;
virtual VOID HwlOverrideTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const
{
// not supported in hwl layer
}
+ virtual VOID HwlSelectTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const
+ {
+ // not supported in hwl layer
+ }
+
AddrTileMode DegradeLargeThickTile(AddrTileMode tileMode, UINT_32 bpp) const;
VOID PadDimensions(
AddrTileMode tileMode, UINT_32 bpp, ADDR_SURFACE_FLAGS flags,
UINT_32 numSamples, ADDR_TILEINFO* pTileInfo, UINT_32 padDims, UINT_32 mipLevel,
UINT_32* pPitch, UINT_32 pitchAlign, UINT_32* pHeight, UINT_32 heightAlign,
UINT_32* pSlices, UINT_32 sliceAlign) const;
virtual VOID HwlPadDimensions(
AddrTileMode tileMode, UINT_32 bpp, ADDR_SURFACE_FLAGS flags,
@@ -478,20 +483,23 @@ protected:
ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;
/// Quad buffer stereo support, has its implementation in ind. layer
virtual BOOL_32 ComputeQbStereoInfo(
ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;
/// Pure virutual function to compute stereo bank swizzle for right eye
virtual UINT_32 HwlComputeQbStereoRightSwizzle(
ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const = 0;
+ BOOL_32 OptimizeTileMode(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, AddrTileMode* pTileMode) const;
+
private:
// Disallow the copy constructor
AddrLib1(const AddrLib1& a);
// Disallow the assignment operator
AddrLib1& operator=(const AddrLib1& a);
UINT_32 ComputeCmaskBaseAlign(
ADDR_CMASK_FLAGS flags, ADDR_TILEINFO* pTileInfo) const;
@@ -500,17 +508,14 @@ private:
//
// CMASK/HTILE shared methods
//
VOID ComputeTileDataWidthAndHeight(
UINT_32 bpp, UINT_32 cacheBits, ADDR_TILEINFO* pTileInfo,
UINT_32* pMacroWidth, UINT_32* pMacroHeight) const;
UINT_32 ComputeXmaskCoordYFromPipe(
UINT_32 pipe, UINT_32 x) const;
-
- BOOL_32 OptimizeTileMode(
- const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, AddrTileMode* pTileMode) const;
};
#endif
diff --git a/src/amd/addrlib/r800/ciaddrlib.cpp b/src/amd/addrlib/r800/ciaddrlib.cpp
index f88741e..15aff16 100644
--- a/src/amd/addrlib/r800/ciaddrlib.cpp
+++ b/src/amd/addrlib/r800/ciaddrlib.cpp
@@ -1017,20 +1017,116 @@ VOID CiAddrLib::HwlOverrideTileMode(
if (tileMode != pInOut->tileMode)
{
pInOut->tileMode = tileMode;
pInOut->tileType = tileType;
}
}
/**
***************************************************************************************************
+* CiAddrLib::HwlSelectTileMode
+*
+* @brief
+* Select tile modes.
+*
+* @return
+* N/A
+*
+***************************************************************************************************
+*/
+VOID CiAddrLib::HwlSelectTileMode(
+ ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in/out] input output structure
+ ) const
+{
+ AddrTileMode tileMode;
+ AddrTileType tileType;
+
+ if (pInOut->flags.rotateDisplay)
+ {
+ tileMode = ADDR_TM_2D_TILED_THIN1;
+ tileType = ADDR_ROTATED;
+ }
+ else if (pInOut->flags.volume)
+ {
+ BOOL_32 bThin = (m_settings.isBonaire == TRUE) ||
+ ((m_allowNonDispThickModes == TRUE) && (pInOut->flags.color == TRUE));
+
+ if (pInOut->numSlices >= 8)
+ {
+ tileMode = ADDR_TM_2D_TILED_XTHICK;
+ tileType = (bThin == TRUE) ? ADDR_NON_DISPLAYABLE : ADDR_THICK;
+ }
+ else if (pInOut->numSlices >= 4)
+ {
+ tileMode = ADDR_TM_2D_TILED_THICK;
+ tileType = (bThin == TRUE) ? ADDR_NON_DISPLAYABLE : ADDR_THICK;
+ }
+ else
+ {
+ tileMode = ADDR_TM_2D_TILED_THIN1;
+ tileType = ADDR_NON_DISPLAYABLE;
+ }
+ }
+ else
+ {
+ tileMode = ADDR_TM_2D_TILED_THIN1;
+
+ if (pInOut->flags.depth || pInOut->flags.stencil)
+ {
+ tileType = ADDR_DEPTH_SAMPLE_ORDER;
+ }
+ else if ((pInOut->bpp <= 32) ||
+ (pInOut->flags.display == TRUE) ||
+ (pInOut->flags.overlay == TRUE))
+ {
+ tileType = ADDR_DISPLAYABLE;
+ }
+ else
+ {
+ tileType = ADDR_NON_DISPLAYABLE;
+ }
+ }
+
+ if (pInOut->flags.prt)
+ {
+ if (Thickness(tileMode) > 1)
+ {
+ tileMode = ADDR_TM_PRT_TILED_THICK;
+ tileType = (m_settings.isBonaire == TRUE) ? ADDR_NON_DISPLAYABLE : ADDR_THICK;
+ }
+ else
+ {
+ tileMode = ADDR_TM_PRT_TILED_THIN1;
+ }
+ }
+
+ pInOut->tileMode = tileMode;
+ pInOut->tileType = tileType;
+
+ if ((pInOut->flags.dccCompatible == FALSE) &&
+ (pInOut->flags.tcCompatible == FALSE))
+ {
+ pInOut->flags.opt4Space = TRUE;
+
+ // Optimize tile mode if possible
+ if (OptimizeTileMode(pInOut, &tileMode))
+ {
+ pInOut->tileMode = tileMode;
+ }
+ }
+
+ HwlOverrideTileMode(pInOut);
+}
+
+/**
+***************************************************************************************************
* CiAddrLib::HwlSetupTileInfo
*
* @brief
* Setup default value of tile info for SI
***************************************************************************************************
*/
VOID CiAddrLib::HwlSetupTileInfo(
AddrTileMode tileMode, ///< [in] Tile mode
ADDR_SURFACE_FLAGS flags, ///< [in] Surface type flags
UINT_32 bpp, ///< [in] Bits per pixel
diff --git a/src/amd/addrlib/r800/ciaddrlib.h b/src/amd/addrlib/r800/ciaddrlib.h
index e959df3..12587cd 100644
--- a/src/amd/addrlib/r800/ciaddrlib.h
+++ b/src/amd/addrlib/r800/ciaddrlib.h
@@ -136,20 +136,22 @@ protected:
virtual VOID HwlFmaskPostThunkSurfInfo(
const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut,
ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut) const;
virtual AddrTileMode HwlDegradeThickTileMode(
AddrTileMode baseTileMode, UINT_32 numSlices, UINT_32* pBytesPerTile) const;
virtual VOID HwlOverrideTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
+ virtual VOID HwlSelectTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
+
virtual ADDR_E_RETURNCODE HwlComputeDccInfo(
const ADDR_COMPUTE_DCCINFO_INPUT* pIn,
ADDR_COMPUTE_DCCINFO_OUTPUT* pOut) const;
virtual ADDR_E_RETURNCODE HwlComputeCmaskAddrFromCoord(
const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn,
ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut) const;
virtual ADDR_E_RETURNCODE HwlComputeHtileAddrFromCoord(
const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn,
diff --git a/src/amd/addrlib/r800/siaddrlib.cpp b/src/amd/addrlib/r800/siaddrlib.cpp
index 4822d77..30f9934 100644
--- a/src/amd/addrlib/r800/siaddrlib.cpp
+++ b/src/amd/addrlib/r800/siaddrlib.cpp
@@ -3192,20 +3192,96 @@ void SiAddrLib::HwlOverrideTileMode(
if (tileMode != pInOut->tileMode)
{
pInOut->tileMode = tileMode;
ADDR_ASSERT(pInOut->flags.prt == TRUE);
}
}
/**
***************************************************************************************************
+* SiAddrLib::HwlSelectTileMode
+*
+* @brief
+* Select tile modes.
+*
+* @return
+* N/A
+*
+***************************************************************************************************
+*/
+VOID SiAddrLib::HwlSelectTileMode(
+ ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in/out] input output structure
+ ) const
+{
+ AddrTileMode tileMode;
+ AddrTileType tileType;
+
+ if (pInOut->flags.volume)
+ {
+ if (pInOut->numSlices >= 8)
+ {
+ tileMode = ADDR_TM_2D_TILED_XTHICK;
+ }
+ else if (pInOut->numSlices >= 4)
+ {
+ tileMode = ADDR_TM_2D_TILED_THICK;
+ }
+ else
+ {
+ tileMode = ADDR_TM_2D_TILED_THIN1;
+ }
+ tileType = ADDR_NON_DISPLAYABLE;
+ }
+ else
+ {
+ tileMode = ADDR_TM_2D_TILED_THIN1;
+
+ if (pInOut->flags.depth || pInOut->flags.stencil)
+ {
+ tileType = ADDR_DEPTH_SAMPLE_ORDER;
+ }
+ else if ((pInOut->bpp <= 32) ||
+ (pInOut->flags.display == TRUE) ||
+ (pInOut->flags.overlay == TRUE))
+ {
+ tileType = ADDR_DISPLAYABLE;
+ }
+ else
+ {
+ tileType = ADDR_NON_DISPLAYABLE;
+ }
+ }
+
+ if (pInOut->flags.prt)
+ {
+ tileMode = ADDR_TM_2D_TILED_THIN1;
+ tileType = (tileType == ADDR_DISPLAYABLE) ? ADDR_NON_DISPLAYABLE : tileType;
+ }
+
+ pInOut->tileMode = tileMode;
+ pInOut->tileType = tileType;
+
+ // Optimize tile mode if possible
+ pInOut->flags.opt4Space = TRUE;
+
+ // Optimize tile mode if possible
+ if (OptimizeTileMode(pInOut, &tileMode))
+ {
+ pInOut->tileMode = tileMode;
+ }
+
+ HwlOverrideTileMode(pInOut);
+}
+
+/**
+***************************************************************************************************
* SiAddrLib::HwlGetMaxAlignments
*
* @brief
* Gets maximum alignments
* @return
* ADDR_E_RETURNCODE
***************************************************************************************************
*/
ADDR_E_RETURNCODE SiAddrLib::HwlGetMaxAlignments(
ADDR_GET_MAX_ALINGMENTS_OUTPUT* pOut ///< [out] output structure
diff --git a/src/amd/addrlib/r800/siaddrlib.h b/src/amd/addrlib/r800/siaddrlib.h
index 814cd00..7619cfe 100644
--- a/src/amd/addrlib/r800/siaddrlib.h
+++ b/src/amd/addrlib/r800/siaddrlib.h
@@ -176,20 +176,22 @@ protected:
const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;
virtual BOOL_32 HwlTileInfoEqual(
const ADDR_TILEINFO* pLeft, const ADDR_TILEINFO* pRight) const;
virtual AddrTileMode HwlDegradeThickTileMode(
AddrTileMode baseTileMode, UINT_32 numSlices, UINT_32* pBytesPerTile) const;
virtual VOID HwlOverrideTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
+ virtual VOID HwlSelectTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
+
virtual BOOL_32 HwlSanityCheckMacroTiled(
ADDR_TILEINFO* pTileInfo) const
{
return TRUE;
}
virtual UINT_32 HwlGetPitchAlignmentLinear(UINT_32 bpp, ADDR_SURFACE_FLAGS flags) const;
virtual UINT_64 HwlGetSizeAdjustmentLinear(
AddrTileMode tileMode,
--
2.7.4
More information about the mesa-dev
mailing list