[Mesa-dev] [PATCH 043/140] amdgpu/addrlib: Add new flags minimizePadding and maxBaseAlign
Marek Olšák
maraeo at gmail.com
Mon Mar 20 22:42:53 UTC 2017
From: Frans Gu <frans.gu at amd.com>
1) minimizePadding - Use 1D tile mode if padded size of 2D is bigger
than 1D
2) maxBaseAlign - Force PRT tile mode if macro block size is bigger than
requested alignment.
Also, related changes to tile mode optimization for needEquation.
---
src/amd/addrlib/addrinterface.h | 6 +-
src/amd/addrlib/core/addrlib1.cpp | 205 ++++++++++++++++++++++++++++--------
src/amd/addrlib/core/addrlib1.h | 25 ++++-
src/amd/addrlib/r800/ciaddrlib.cpp | 152 ++++++++++++++++++--------
src/amd/addrlib/r800/ciaddrlib.h | 5 +
src/amd/addrlib/r800/egbaddrlib.cpp | 58 +++++-----
src/amd/addrlib/r800/egbaddrlib.h | 5 +-
src/amd/addrlib/r800/siaddrlib.cpp | 97 ++++++++++++-----
src/amd/addrlib/r800/siaddrlib.h | 5 +
9 files changed, 401 insertions(+), 157 deletions(-)
diff --git a/src/amd/addrlib/addrinterface.h b/src/amd/addrlib/addrinterface.h
index a2a36cd..065545e 100644
--- a/src/amd/addrlib/addrinterface.h
+++ b/src/amd/addrlib/addrinterface.h
@@ -508,21 +508,22 @@ typedef union _ADDR_SURFACE_FLAGS
/// 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 rotateDisplay : 1; ///< Rotate micro tile type
- UINT_32 reserved : 6; ///< Reserved bits
+ UINT_32 minimizeAlignment : 1; ///< Minimize alignment
+ UINT_32 reserved : 5; ///< Reserved bits
};
UINT_32 value;
} ADDR_SURFACE_FLAGS;
/**
****************************************************************************************************
* ADDR_COMPUTE_SURFACE_INFO_INPUT
*
* @brief
@@ -550,20 +551,23 @@ typedef struct _ADDR_COMPUTE_SURFACE_INFO_INPUT
/// number of fragments for EQAA
/// r800 and later HWL parameters
// Needed by 2D tiling, for linear and 1D tiling, just keep them 0's
ADDR_TILEINFO* pTileInfo; ///< 2D tile parameters. Set to 0 to default/calculate
AddrTileType tileType; ///< Micro tiling type, not needed when tileIndex != -1
INT_32 tileIndex; ///< Tile index, MUST be -1 if you don't want to use it
/// while the global useTileIndex is set to 1
UINT_32 basePitch; ///< Base level pitch in pixels, 0 means ignored, is a
/// must for mip levels from SI+.
/// Don't use pitch in blocks for compressed formats!
+ UINT_32 maxBaseAlign; ///< Max base alignment request from client
+ UINT_32 pitchAlign; ///< Pitch alignment request from client
+ UINT_32 heightAlign; ///< Height alignment request from client
} ADDR_COMPUTE_SURFACE_INFO_INPUT;
/**
****************************************************************************************************
* ADDR_COMPUTE_SURFACE_INFO_OUTPUT
*
* @brief
* Output structure for AddrComputeSurfInfo
* @note
Element: AddrLib unit for computing. e.g. BCn: 4x4 blocks; R32B32B32: 32bit with 3x pitch
diff --git a/src/amd/addrlib/core/addrlib1.cpp b/src/amd/addrlib/core/addrlib1.cpp
index d65fd02..516229a 100644
--- a/src/amd/addrlib/core/addrlib1.cpp
+++ b/src/amd/addrlib/core/addrlib1.cpp
@@ -339,27 +339,22 @@ ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(
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;
-
// Optimize tile mode if possible
- if (OptimizeTileMode(&localIn, &tileMode))
- {
- localIn.tileMode = tileMode;
- }
+ OptimizeTileMode(&localIn);
}
}
// Call main function to compute surface info
if (returnCode == ADDR_OK)
{
returnCode = HwlComputeSurfaceInfo(&localIn, pOut);
}
if (returnCode == ADDR_OK)
@@ -3503,86 +3498,206 @@ VOID Lib::ComputeMipLevel(
pIn->width = PowTwoAlign(pIn->width, 4);
pIn->height = PowTwoAlign(pIn->height, 4);
}
}
HwlComputeMipLevel(pIn);
}
/**
****************************************************************************************************
+* Lib::DegradeTo1D
+*
+* @brief
+* Check if surface can be degraded to 1D
+* @return
+* TRUE if degraded
+****************************************************************************************************
+*/
+BOOL_32 Lib::DegradeTo1D(
+ UINT_32 width, ///< surface width
+ UINT_32 height, ///< surface height
+ UINT_32 macroTilePitchAlign, ///< macro tile pitch align
+ UINT_32 macroTileHeightAlign ///< macro tile height align
+ )
+{
+ BOOL_32 degrade = ((width < macroTilePitchAlign) || (height < macroTileHeightAlign));
+
+ // Check whether 2D tiling still has too much footprint
+ if (degrade == FALSE)
+ {
+ // Only check width and height as slices are aligned to thickness
+ UINT_64 unalignedSize = width * height;
+
+ UINT_32 alignedPitch = PowTwoAlign(width, macroTilePitchAlign);
+ UINT_32 alignedHeight = PowTwoAlign(height, macroTileHeightAlign);
+ UINT_64 alignedSize = alignedPitch * alignedHeight;
+
+ // alignedSize > 1.5 * unalignedSize
+ if (2 * alignedSize > 3 * unalignedSize)
+ {
+ degrade = TRUE;
+ }
+ }
+
+ return degrade;
+}
+
+/**
+****************************************************************************************************
* Lib::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)
+* N/A
****************************************************************************************************
*/
-BOOL_32 Lib::OptimizeTileMode(
- const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure for surface info
- AddrTileMode* pTileMode ///< [out] Degraded tile mode
+VOID Lib::OptimizeTileMode(
+ ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in, out] structure for surface info
) const
{
- AddrTileMode tileMode = pIn->tileMode;
- UINT_32 thickness = Thickness(tileMode);
+ AddrTileMode tileMode = pInOut->tileMode;
+ BOOL_32 doOpt = (pInOut->flags.opt4Space == TRUE) ||
+ (pInOut->flags.minimizeAlignment == TRUE) ||
+ (pInOut->maxBaseAlign != 0);
// 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) &&
+ if ((doOpt == TRUE) &&
+ (pInOut->mipLevel == 0) &&
+ (pInOut->flags.display == FALSE) &&
(IsPrtTileMode(tileMode) == FALSE) &&
- (pIn->flags.prt == FALSE))
+ (pInOut->flags.prt == FALSE))
{
- // Check if linear mode is optimal
- if ((pIn->height == 1) &&
- (IsLinear(tileMode) == FALSE) &&
- (ElemLib::IsBlockCompressed(pIn->format) == FALSE) &&
- (pIn->flags.depth == FALSE) &&
- (pIn->flags.stencil == FALSE) &&
- (m_configFlags.disableLinearOpt == FALSE) &&
- (pIn->flags.disableLinearOpt == FALSE))
+ UINT_32 width = pInOut->width;
+ UINT_32 height = pInOut->height;
+ UINT_32 thickness = Thickness(tileMode);
+ BOOL_32 convertToPrt = FALSE;
+ BOOL_32 macroTiledOK = TRUE;
+ UINT_32 macroWidthAlign = 0;
+ UINT_32 macroHeightAlign = 0;
+ UINT_32 macroSizeAlign = 0;
+
+ if (IsMacroTiled(tileMode))
{
- tileMode = ADDR_TM_LINEAR_ALIGNED;
+ macroTiledOK = HwlGetAlignmentInfoMacroTiled(pInOut,
+ ¯oWidthAlign,
+ ¯oHeightAlign,
+ ¯oSizeAlign);
}
- else if (IsMacroTiled(tileMode))
+
+ if (macroTiledOK)
{
- if (HwlDegradeBaseLevel(pIn))
+ if ((pInOut->flags.opt4Space == TRUE) && (pInOut->numSamples <= 1))
{
- tileMode = (thickness == 1) ? ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
+ // Check if linear mode is optimal
+ if ((pInOut->height == 1) &&
+ (IsLinear(tileMode) == FALSE) &&
+ (ElemLib::IsBlockCompressed(pInOut->format) == FALSE) &&
+ (pInOut->flags.depth == FALSE) &&
+ (pInOut->flags.stencil == FALSE) &&
+ (m_configFlags.disableLinearOpt == FALSE) &&
+ (pInOut->flags.disableLinearOpt == FALSE))
+ {
+ tileMode = ADDR_TM_LINEAR_ALIGNED;
+ }
+ else if (IsMacroTiled(tileMode))
+ {
+ if (DegradeTo1D(width, height, macroWidthAlign, macroHeightAlign))
+ {
+ 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 should be degraded. If so, we choose 1D thick mode instead.
+ tileMode = DegradeLargeThickTile(pInOut->tileMode, pInOut->bpp);
+
+ if (tileMode != pInOut->tileMode)
+ {
+ // Get thickness again after large thick degrade
+ thickness = Thickness(tileMode);
+
+ ADDR_COMPUTE_SURFACE_INFO_INPUT input = *pInOut;
+ input.tileMode = tileMode;
+
+ macroTiledOK = HwlGetAlignmentInfoMacroTiled(&input,
+ ¯oWidthAlign,
+ ¯oHeightAlign,
+ ¯oSizeAlign);
+
+ if (macroTiledOK &&
+ DegradeTo1D(width, height, macroWidthAlign, macroHeightAlign))
+ {
+ tileMode = ADDR_TM_1D_TILED_THICK;
+ }
+ }
+ }
+ }
}
- else if (thickness > 1)
+
+ if (macroTiledOK)
{
- // 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)
+ if ((pInOut->flags.minimizeAlignment == TRUE) &&
+ (pInOut->numSamples <= 1) &&
+ (IsMacroTiled(tileMode) == TRUE))
+ {
+ UINT_32 macroSize = PowTwoAlign(width, macroWidthAlign) *
+ PowTwoAlign(height, macroHeightAlign);
+ UINT_32 microSize = PowTwoAlign(width, MicroTileWidth) *
+ PowTwoAlign(height, MicroTileHeight);
+
+ if (macroSize > microSize)
+ {
+ tileMode = (thickness == 1) ?
+ ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
+ }
+ }
+
+ if ((pInOut->maxBaseAlign != 0) &&
+ (IsMacroTiled(tileMode) == TRUE))
{
- ADDR_COMPUTE_SURFACE_INFO_INPUT input = *pIn;
- input.tileMode = tileMode;
- if (HwlDegradeBaseLevel(&input))
+ if (macroSizeAlign > pInOut->maxBaseAlign)
{
- tileMode = ADDR_TM_1D_TILED_THICK;
+ if (pInOut->numSamples > 1)
+ {
+ ADDR_ASSERT(pInOut->maxBaseAlign >= Block64K);
+
+ convertToPrt = TRUE;
+ }
+ else if (pInOut->maxBaseAlign < Block64K)
+ {
+ tileMode = (thickness == 1) ?
+ ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
+ }
+ else
+ {
+ convertToPrt = TRUE;
+ }
}
}
}
}
- }
- BOOL_32 optimized = (tileMode != pIn->tileMode);
- if (optimized)
- {
- *pTileMode = tileMode;
+ if (convertToPrt)
+ {
+ HwlSetPrtTileMode(pInOut);
+ }
+ else if (tileMode != pInOut->tileMode)
+ {
+ pInOut->tileMode = tileMode;
+ }
}
- return optimized;
+
+ HwlOptimizeTileMode(pInOut);
}
/**
****************************************************************************************************
* Lib::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)
diff --git a/src/amd/addrlib/core/addrlib1.h b/src/amd/addrlib/core/addrlib1.h
index c1fc693..0475e7b 100644
--- a/src/amd/addrlib/core/addrlib1.h
+++ b/src/amd/addrlib/core/addrlib1.h
@@ -342,29 +342,36 @@ protected:
virtual VOID HwlComputeXmaskCoordFromAddr(
UINT_64 addr, UINT_32 bitPosition, UINT_32 pitch, UINT_32 height, UINT_32 numSlices,
UINT_32 factor, BOOL_32 isLinear, BOOL_32 isWidth8, BOOL_32 isHeight8,
ADDR_TILEINFO* pTileInfo, UINT_32* pX, UINT_32* pY, UINT_32* pSlice) const;
// Surface mipmap
VOID ComputeMipLevel(
ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const;
- /// Pure Virtual function for Hwl checking degrade for base level
- virtual BOOL_32 HwlDegradeBaseLevel(
- const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const = 0;
+ /// Pure Virtual function for Hwl to get macro tiled alignment info
+ virtual BOOL_32 HwlGetAlignmentInfoMacroTiled(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,
+ UINT_32* pPitchAlign, UINT_32* pHeightAlign, UINT_32* pSizeAlign) const = 0;
+
virtual VOID HwlOverrideTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const
{
// not supported in hwl layer
}
+ virtual VOID HwlOptimizeTileMode(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,
@@ -489,22 +496,30 @@ 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;
+ VOID OptimizeTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
+
+ /// Overwrite tile setting to PRT
+ virtual VOID HwlSetPrtTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const
+ {
+ }
+
+ static BOOL_32 DegradeTo1D(
+ UINT_32 width, UINT_32 height,
+ UINT_32 macroTilePitchAlign, UINT_32 macroTileHeightAlign);
private:
// Disallow the copy constructor
Lib(const Lib& a);
// Disallow the assignment operator
Lib& operator=(const Lib& a);
UINT_32 ComputeCmaskBaseAlign(
ADDR_CMASK_FLAGS flags, ADDR_TILEINFO* pTileInfo) const;
diff --git a/src/amd/addrlib/r800/ciaddrlib.cpp b/src/amd/addrlib/r800/ciaddrlib.cpp
index ed7958d..7272c49 100644
--- a/src/amd/addrlib/r800/ciaddrlib.cpp
+++ b/src/amd/addrlib/r800/ciaddrlib.cpp
@@ -864,20 +864,90 @@ AddrTileMode CiLib::HwlDegradeThickTileMode(
AddrTileMode baseTileMode, ///< [in] base tile mode
UINT_32 numSlices, ///< [in] current number of slices
UINT_32* pBytesPerTile ///< [in,out] pointer to bytes per slice
) const
{
return baseTileMode;
}
/**
****************************************************************************************************
+* CiLib::HwlOptimizeTileMode
+*
+* @brief
+* Optimize tile mode on CI
+*
+* @return
+* N/A
+*
+****************************************************************************************************
+*/
+VOID CiLib::HwlOptimizeTileMode(
+ ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in,out] input output structure
+ ) const
+{
+ AddrTileMode tileMode = pInOut->tileMode;
+
+ // Override 2D/3D macro tile mode to PRT_* tile mode if
+ // client driver requests this surface is equation compatible
+ if ((pInOut->flags.needEquation == TRUE) &&
+ (pInOut->numSamples <= 1) &&
+ (IsMacroTiled(tileMode) == TRUE) &&
+ (IsPrtTileMode(tileMode) == FALSE))
+ {
+ UINT_32 thickness = Thickness(tileMode);
+
+ if (pInOut->maxBaseAlign < Block64K)
+ {
+ tileMode = (thickness == 1) ? ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
+ }
+ else if (thickness == 1)
+ {
+ tileMode = ADDR_TM_PRT_TILED_THIN1;
+ }
+ else
+ {
+ static const UINT_32 PrtTileBytes = 0x10000;
+ // First prt thick tile index in the tile mode table
+ static const UINT_32 PrtThickTileIndex = 22;
+ ADDR_TILEINFO tileInfo = {0};
+
+ HwlComputeMacroModeIndex(PrtThickTileIndex,
+ pInOut->flags,
+ pInOut->bpp,
+ pInOut->numSamples,
+ &tileInfo);
+
+ UINT_32 macroTileBytes = ((pInOut->bpp) >> 3) * 64 * pInOut->numSamples *
+ thickness * HwlGetPipes(&tileInfo) *
+ tileInfo.banks * tileInfo.bankWidth *
+ tileInfo.bankHeight;
+
+ if (macroTileBytes <= PrtTileBytes)
+ {
+ tileMode = ADDR_TM_PRT_TILED_THICK;
+ }
+ else
+ {
+ tileMode = ADDR_TM_PRT_TILED_THIN1;
+ }
+ }
+ }
+
+ if (tileMode != pInOut->tileMode)
+ {
+ pInOut->tileMode = tileMode;
+ }
+}
+
+/**
+****************************************************************************************************
* CiLib::HwlOverrideTileMode
*
* @brief
* Override THICK to THIN, for specific formats on CI
*
* @return
* N/A
*
****************************************************************************************************
*/
@@ -974,62 +1044,20 @@ VOID CiLib::HwlOverrideTileMode(
tileType = ADDR_NON_DISPLAYABLE;
}
break;
default:
break;
}
}
}
- // Override 2D/3D macro tile mode to PRT_* tile mode if
- // client driver requests this surface is equation compatible
- if ((pInOut->flags.needEquation == TRUE) &&
- (pInOut->numSamples <= 1) &&
- (IsMacroTiled(tileMode) == TRUE) &&
- (IsPrtTileMode(tileMode) == FALSE))
- {
- UINT_32 thickness = Thickness(tileMode);
-
- if (thickness == 1)
- {
- tileMode = ADDR_TM_PRT_TILED_THIN1;
- }
- else
- {
- static const UINT_32 PrtTileBytes = 0x10000;
- // First prt thick tile index in the tile mode table
- static const UINT_32 PrtThickTileIndex = 22;
- ADDR_TILEINFO tileInfo = {0};
-
- HwlComputeMacroModeIndex(PrtThickTileIndex,
- pInOut->flags,
- pInOut->bpp,
- pInOut->numSamples,
- &tileInfo);
-
- UINT_32 macroTileBytes = ((pInOut->bpp) >> 3) * 64 * pInOut->numSamples *
- thickness * HwlGetPipes(&tileInfo) *
- tileInfo.banks * tileInfo.bankWidth *
- tileInfo.bankHeight;
-
- if (macroTileBytes <= PrtTileBytes)
- {
- tileMode = ADDR_TM_PRT_TILED_THICK;
- }
- else
- {
- tileMode = ADDR_TM_PRT_TILED_THIN1;
- }
- }
- }
-
if (tileMode != pInOut->tileMode)
{
pInOut->tileMode = tileMode;
pInOut->tileType = tileType;
}
}
/**
****************************************************************************************************
* CiLib::HwlSelectTileMode
@@ -1108,33 +1136,65 @@ VOID CiLib::HwlSelectTileMode(
}
}
pInOut->tileMode = tileMode;
pInOut->tileType = tileType;
if ((pInOut->flags.dccCompatible == FALSE) &&
(pInOut->flags.tcCompatible == FALSE))
{
pInOut->flags.opt4Space = TRUE;
+ pInOut->maxBaseAlign = Block64K;
// Optimize tile mode if possible
- if (OptimizeTileMode(pInOut, &tileMode))
- {
- pInOut->tileMode = tileMode;
- }
+ OptimizeTileMode(pInOut);
}
HwlOverrideTileMode(pInOut);
}
/**
****************************************************************************************************
+* CiLib::HwlSetPrtTileMode
+*
+* @brief
+* Set PRT tile mode.
+*
+* @return
+* N/A
+*
+****************************************************************************************************
+*/
+VOID CiLib::HwlSetPrtTileMode(
+ ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in,out] input output structure
+ ) const
+{
+ AddrTileMode tileMode = pInOut->tileMode;
+ AddrTileType tileType = pInOut->tileType;
+
+ 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;
+ tileType = (tileType == ADDR_THICK) ? ADDR_NON_DISPLAYABLE : tileType;
+ }
+
+ pInOut->tileMode = tileMode;
+ pInOut->tileType = tileType;
+}
+
+/**
+****************************************************************************************************
* CiLib::HwlSetupTileInfo
*
* @brief
* Setup default value of tile info for SI
****************************************************************************************************
*/
VOID CiLib::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 f6c8655..7fa6b75 100644
--- a/src/amd/addrlib/r800/ciaddrlib.h
+++ b/src/amd/addrlib/r800/ciaddrlib.h
@@ -142,22 +142,27 @@ 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 HwlOptimizeTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
+
virtual VOID HwlSelectTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
+ /// Overwrite tile setting to PRT
+ virtual VOID HwlSetPrtTileMode(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/egbaddrlib.cpp b/src/amd/addrlib/r800/egbaddrlib.cpp
index f413cff..2d1123a 100644
--- a/src/amd/addrlib/r800/egbaddrlib.cpp
+++ b/src/amd/addrlib/r800/egbaddrlib.cpp
@@ -233,20 +233,32 @@ BOOL_32 EgBasedLib::ComputeSurfaceInfoLinear(
//
// Compute the surface alignments.
//
ComputeSurfaceAlignmentsLinear(pIn->tileMode,
pIn->bpp,
pIn->flags,
&pOut->baseAlign,
&pOut->pitchAlign,
&pOut->heightAlign);
+ if (pIn->pitchAlign != 0)
+ {
+ ADDR_ASSERT((pIn->pitchAlign % pOut->pitchAlign) == 0);
+ pOut->pitchAlign = pIn->pitchAlign;
+ }
+
+ if (pIn->heightAlign != 0)
+ {
+ ADDR_ASSERT((pIn->heightAlign % pOut->heightAlign) == 0);
+ pOut->heightAlign = pIn->heightAlign;
+ }
+
if ((pIn->tileMode == ADDR_TM_LINEAR_GENERAL) && pIn->flags.color && (pIn->height > 1))
{
#if !ALT_TEST
// When linear_general surface is accessed in multiple lines, it requires 8 pixels in pitch
// alignment since PITCH_TILE_MAX is in unit of 8 pixels.
// It is OK if it is accessed per line.
ADDR_ASSERT((pIn->width % 8) == 0);
#endif
}
@@ -1132,100 +1144,86 @@ AddrTileMode EgBasedLib::ComputeSurfaceMipLevelTileMode(
break;
default:
break;
}
return expTileMode;
}
/**
****************************************************************************************************
-* EgBasedLib::HwlDegradeBaseLevel
+* EgBasedLib::HwlGetAlignmentInfoMacroTiled
* @brief
-* Check if degrade is needed for base level
+* Get alignment info for giving tile mode
* @return
-* TRUE if degrade is suggested
+* TRUE if getting alignment is OK
****************************************************************************************************
*/
-BOOL_32 EgBasedLib::HwlDegradeBaseLevel(
- const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const
+BOOL_32 EgBasedLib::HwlGetAlignmentInfoMacroTiled(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] create surface info
+ UINT_32* pPitchAlign, ///< [out] pitch alignment
+ UINT_32* pHeightAlign, ///< [out] height alignment
+ UINT_32* pSizeAlign ///< [out] size alignment
+ ) const
{
- BOOL_32 degrade = FALSE;
BOOL_32 valid = TRUE;
ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
UINT_32 baseAlign;
UINT_32 pitchAlign;
UINT_32 heightAlign;
UINT_32 macroTileWidth;
UINT_32 macroTileHeight;
+ UINT_32 numSamples = (pIn->numFrags == 0) ? pIn->numSamples : pIn->numFrags;
ADDR_ASSERT(pIn->pTileInfo);
ADDR_TILEINFO tileInfo = *pIn->pTileInfo;
ADDR_COMPUTE_SURFACE_INFO_OUTPUT out = {0};
if (UseTileIndex(pIn->tileIndex))
{
out.tileIndex = pIn->tileIndex;
out.macroModeIndex = TileIndexInvalid;
}
HwlSetupTileInfo(pIn->tileMode,
pIn->flags,
pIn->bpp,
pIn->width,
pIn->height,
- pIn->numSamples,
+ numSamples,
&tileInfo,
&tileInfo,
pIn->tileType,
&out);
valid = ComputeSurfaceAlignmentsMacroTiled(pIn->tileMode,
pIn->bpp,
pIn->flags,
pIn->mipLevel,
- pIn->numSamples,
+ numSamples,
&tileInfo,
&baseAlign,
&pitchAlign,
&heightAlign,
¯oTileWidth,
¯oTileHeight);
if (valid)
{
- degrade = ((pIn->width < macroTileWidth) || (pIn->height < macroTileHeight));
- // Check whether 2D tiling still has too much footprint
- if (degrade == FALSE)
- {
- // Only check width and height as slices are aligned to thickness
- UINT_64 unalignedSize = pIn->width * pIn->height;
-
- UINT_32 alignedPitch = PowTwoAlign(pIn->width, pitchAlign);
- UINT_32 alignedHeight = PowTwoAlign(pIn->height, heightAlign);
- UINT_64 alignedSize = alignedPitch * alignedHeight;
-
- // alignedSize > 1.5 * unalignedSize
- if (2 * alignedSize > 3 * unalignedSize)
- {
- degrade = TRUE;
- }
- }
- }
- else
- {
- degrade = TRUE;
+ *pPitchAlign = pitchAlign;
+ *pHeightAlign = heightAlign;
+ *pSizeAlign = baseAlign;
}
- return degrade;
+ return valid;
}
/**
****************************************************************************************************
* EgBasedLib::HwlDegradeThickTileMode
*
* @brief
* Degrades valid tile mode for thick modes if needed
*
* @return
diff --git a/src/amd/addrlib/r800/egbaddrlib.h b/src/amd/addrlib/r800/egbaddrlib.h
index 1a56003..50fd3d9 100644
--- a/src/amd/addrlib/r800/egbaddrlib.h
+++ b/src/amd/addrlib/r800/egbaddrlib.h
@@ -130,22 +130,23 @@ protected:
ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut);
virtual ADDR_E_RETURNCODE HwlComputeFmaskAddrFromCoord(
const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn,
ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut) const;
virtual ADDR_E_RETURNCODE HwlComputeFmaskCoordFromAddr(
const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn,
ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut) const;
- virtual BOOL_32 HwlDegradeBaseLevel(
- const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const;
+ virtual BOOL_32 HwlGetAlignmentInfoMacroTiled(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,
+ UINT_32* pPitchAlign, UINT_32* pHeightAlign, UINT_32* pSizeAlign) const;
virtual UINT_32 HwlComputeQbStereoRightSwizzle(
ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pInfo) const;
virtual VOID HwlComputePixelCoordFromOffset(
UINT_32 offset, UINT_32 bpp, UINT_32 numSamples,
AddrTileMode tileMode, UINT_32 tileBase, UINT_32 compBits,
UINT_32* pX, UINT_32* pY, UINT_32* pSlice, UINT_32* pSample,
AddrTileType microTileType, BOOL_32 isDepthSampleOrder) const;
diff --git a/src/amd/addrlib/r800/siaddrlib.cpp b/src/amd/addrlib/r800/siaddrlib.cpp
index f8f9379..299951e 100644
--- a/src/amd/addrlib/r800/siaddrlib.cpp
+++ b/src/amd/addrlib/r800/siaddrlib.cpp
@@ -3128,20 +3128,66 @@ UINT_32 SiLib::HwlComputeFmaskBits(
}
}
SafeAssign(pNumSamples, numSamples);
return bpp;
}
/**
****************************************************************************************************
+* SiLib::HwlOptimizeTileMode
+*
+* @brief
+* Optimize tile mode on SI
+*
+* @return
+* N/A
+*
+****************************************************************************************************
+*/
+VOID SiLib::HwlOptimizeTileMode(
+ ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in,out] input output structure
+ ) const
+{
+ AddrTileMode tileMode = pInOut->tileMode;
+
+ if ((pInOut->flags.needEquation == TRUE) &&
+ (IsMacroTiled(tileMode) == TRUE) &&
+ (pInOut->numSamples <= 1))
+ {
+ UINT_32 thickness = Thickness(tileMode);
+
+ pInOut->flags.prt = TRUE;
+
+ if (thickness > 1)
+ {
+ tileMode = ADDR_TM_1D_TILED_THICK;
+ }
+ else if (pInOut->numSlices > 1)
+ {
+ tileMode = ADDR_TM_1D_TILED_THIN1;
+ }
+ else
+ {
+ tileMode = ADDR_TM_2D_TILED_THIN1;
+ }
+ }
+
+ if (tileMode != pInOut->tileMode)
+ {
+ pInOut->tileMode = tileMode;
+ }
+}
+
+/**
+****************************************************************************************************
* SiLib::HwlOverrideTileMode
*
* @brief
* Override tile modes (for PRT only, avoid client passes in an invalid PRT mode for SI.
*
* @return
* N/A
*
****************************************************************************************************
*/
@@ -3166,52 +3212,52 @@ VOID SiLib::HwlOverrideTileMode(
break;
case ADDR_TM_PRT_3D_TILED_THICK:
tileMode = ADDR_TM_3D_TILED_THICK;
break;
default:
break;
}
- if ((pInOut->flags.needEquation == TRUE) &&
- (IsMacroTiled(tileMode) == TRUE) &&
- (pInOut->numSamples <= 1))
- {
- UINT_32 thickness = Thickness(tileMode);
-
- pInOut->flags.prt = TRUE;
-
- if (thickness > 1)
- {
- tileMode = ADDR_TM_1D_TILED_THICK;
- }
- else if (pInOut->numSlices > 1)
- {
- tileMode = ADDR_TM_1D_TILED_THIN1;
- }
- else
- {
- tileMode = ADDR_TM_2D_TILED_THIN1;
- }
- }
-
if (tileMode != pInOut->tileMode)
{
pInOut->tileMode = tileMode;
ADDR_ASSERT(pInOut->flags.prt == TRUE);
}
}
/**
****************************************************************************************************
+* SiLib::HwlSetPrtTileMode
+*
+* @brief
+* Set prt tile modes.
+*
+* @return
+* N/A
+*
+****************************************************************************************************
+*/
+VOID SiLib::HwlSetPrtTileMode(
+ ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in,out] input output structure
+ ) const
+{
+ pInOut->tileMode = ADDR_TM_2D_TILED_THIN1;
+ pInOut->tileType = (pInOut->tileType == ADDR_DEPTH_SAMPLE_ORDER) ?
+ ADDR_DEPTH_SAMPLE_ORDER : ADDR_NON_DISPLAYABLE;
+ pInOut->flags.prt = TRUE;
+}
+
+/**
+****************************************************************************************************
* SiLib::HwlSelectTileMode
*
* @brief
* Select tile modes.
*
* @return
* N/A
*
****************************************************************************************************
*/
@@ -3264,24 +3310,21 @@ VOID SiLib::HwlSelectTileMode(
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;
- }
+ OptimizeTileMode(pInOut);
HwlOverrideTileMode(pInOut);
}
/**
****************************************************************************************************
* SiLib::HwlGetMaxAlignments
*
* @brief
* Gets maximum alignments
@@ -3485,22 +3528,20 @@ VOID SiLib::InitEquationTable()
m_blockWidth[equationIndex] =
HwlGetPipes(pTileInfo) * MicroTileWidth * pTileInfo->bankWidth *
pTileInfo->macroAspectRatio;
m_blockHeight[equationIndex] =
MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks /
pTileInfo->macroAspectRatio;
if (m_chipFamily == ADDR_CHIP_FAMILY_SI)
{
- static const UINT_32 PrtTileSize = 0x10000;
-
UINT_32 macroTileSize =
m_blockWidth[equationIndex] * m_blockHeight[equationIndex] *
bpp / 8;
if (macroTileSize < PrtTileSize)
{
UINT_32 numMacroTiles = PrtTileSize / macroTileSize;
ADDR_ASSERT(macroTileSize == (1u << equation.numBits));
ADDR_ASSERT((PrtTileSize % macroTileSize) == 0);
diff --git a/src/amd/addrlib/r800/siaddrlib.h b/src/amd/addrlib/r800/siaddrlib.h
index 86d2116..53ec68b 100644
--- a/src/amd/addrlib/r800/siaddrlib.h
+++ b/src/amd/addrlib/r800/siaddrlib.h
@@ -182,22 +182,27 @@ 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 HwlOptimizeTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
+
virtual VOID HwlSelectTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;
+ /// Overwrite tile setting to PRT
+ virtual VOID HwlSetPrtTileMode(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