From: Frans Gu <frans...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev