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