diff options
author | Nicolai Hähnle <[email protected]> | 2016-07-20 20:25:15 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2017-03-30 14:44:33 +0200 |
commit | 10f7d1cb0321c5c15b9eb318c2c59ea0d9ac14db (patch) | |
tree | bb3d234784c0d7a142cd3adedfaaefaf8d6fad45 /src/amd/addrlib/r800 | |
parent | 3e44337bd6314056b5c0d18e99754993f872c19e (diff) |
amdgpu/addrlib: add equation generation
1. Add new surface flags needEquation for client driver use to force
the surface tile setting equation compatible. Override 2D/3D macro
tile mode to PRT_* tile mode if this flag is TRUE and num slice > 1.
2. Add numEquations and pEquationTable in ADDR_CREATE_OUTPUT structure
to return number of equations and the equation table to client driver
3. Add equationIndex in ADDR_COMPUTE_SURFACE_INFO_OUTPUT structure to
return the equation index to client driver
Please note the use of address equation has following restrictions:
1) The surface can't be splitable
2) The surface can't have non zero tile swizzle value
3) Surface with > 1 slices must have PRT tile mode, which disable
slice rotation
Diffstat (limited to 'src/amd/addrlib/r800')
-rw-r--r-- | src/amd/addrlib/r800/ciaddrlib.cpp | 87 | ||||
-rw-r--r-- | src/amd/addrlib/r800/ciaddrlib.h | 7 | ||||
-rw-r--r-- | src/amd/addrlib/r800/egbaddrlib.cpp | 226 | ||||
-rw-r--r-- | src/amd/addrlib/r800/egbaddrlib.h | 14 | ||||
-rw-r--r-- | src/amd/addrlib/r800/siaddrlib.cpp | 663 | ||||
-rw-r--r-- | src/amd/addrlib/r800/siaddrlib.h | 50 |
6 files changed, 974 insertions, 73 deletions
diff --git a/src/amd/addrlib/r800/ciaddrlib.cpp b/src/amd/addrlib/r800/ciaddrlib.cpp index 7585e2558b0..3322d952165 100644 --- a/src/amd/addrlib/r800/ciaddrlib.cpp +++ b/src/amd/addrlib/r800/ciaddrlib.cpp @@ -482,6 +482,11 @@ BOOL_32 CiAddrLib::HwlInitGlobalParams( valid = InitMacroTileCfgTable(pRegValue->pMacroTileConfig, pRegValue->noOfMacroEntries); } + if (valid) + { + InitEquationTable(); + } + return valid; } @@ -615,7 +620,7 @@ ADDR_E_RETURNCODE CiAddrLib::HwlSetupTileCfg( } else { - const ADDR_TILECONFIG* pCfgTable = GetTileSetting(index); + const AddrTileConfig* pCfgTable = GetTileSetting(index); if (pInfo != NULL) { @@ -864,18 +869,16 @@ AddrTileMode CiAddrLib::HwlDegradeThickTileMode( * Override THICK to THIN, for specific formats on CI * * @return -* Suitable tile mode +* N/A * *************************************************************************************************** */ -BOOL_32 CiAddrLib::HwlOverrideTileMode( - const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure - AddrTileMode* pTileMode, ///< [in/out] pointer to the tile mode - AddrTileType* pTileType ///< [in/out] pointer to the tile type +VOID CiAddrLib::HwlOverrideTileMode( + ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in/out] input output structure ) const { - BOOL_32 bOverrided = FALSE; - AddrTileMode tileMode = *pTileMode; + AddrTileMode tileMode = pInOut->tileMode; + AddrTileType tileType = pInOut->tileType; // currently, all CI/VI family do not // support ADDR_TM_PRT_2D_TILED_THICK,ADDR_TM_PRT_3D_TILED_THICK and @@ -902,7 +905,7 @@ BOOL_32 CiAddrLib::HwlOverrideTileMode( // tile_thickness = (array_mode == XTHICK) ? 8 : ((array_mode == THICK) ? 4 : 1) if (thickness > 1) { - switch (pIn->format) + switch (pInOut->format) { // see //gfxip/gcB/devel/cds/src/verif/tc/models/csim/tcp.cpp // tcpError("Thick micro tiling is not supported for format... @@ -957,10 +960,10 @@ BOOL_32 CiAddrLib::HwlOverrideTileMode( } // Switch tile type from thick to thin - if (tileMode != *pTileMode) + if (tileMode != pInOut->tileMode) { // see tileIndex: 13-18 - *pTileType = ADDR_NON_DISPLAYABLE; + tileType = ADDR_NON_DISPLAYABLE; } break; @@ -970,13 +973,53 @@ BOOL_32 CiAddrLib::HwlOverrideTileMode( } } - if (tileMode != *pTileMode) + // 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)) { - *pTileMode = tileMode; - bOverrided = TRUE; + 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; + } + } } - return bOverrided; + if (tileMode != pInOut->tileMode) + { + pInOut->tileMode = tileMode; + pInOut->tileType = tileType; + } } /** @@ -1016,7 +1059,10 @@ VOID CiAddrLib::HwlSetupTileInfo( { inTileType = ADDR_NON_DISPLAYABLE; } - else if ((m_allowNonDispThickModes == FALSE) || (inTileType != ADDR_NON_DISPLAYABLE)) + else if ((m_allowNonDispThickModes == FALSE) || + (inTileType != ADDR_NON_DISPLAYABLE) || + // There is no PRT_THICK + THIN entry in tile mode table except Bonaire + (IsPrtTileMode(tileMode) == TRUE)) { inTileType = ADDR_THICK; } @@ -1055,7 +1101,7 @@ VOID CiAddrLib::HwlSetupTileInfo( pOut->tcCompatible = FALSE; } - if (flags.depth && (flags.nonSplit || flags.tcCompatible)) + if (flags.depth && (flags.nonSplit || flags.tcCompatible || flags.needEquation)) { // Texure readable depth surface should not be split switch (tileSize) @@ -1277,7 +1323,7 @@ VOID CiAddrLib::HwlSetupTileInfo( { if (IsMacroTiled(tileMode)) { - UINT_32 tileIndex = static_cast<UINT_32>(pOut->tileIndex); + INT_32 tileIndex = pOut->tileIndex; if ((tileIndex == TileIndexInvalid) && (IsTileInfoAllZero(pTileInfo) == FALSE)) { @@ -1286,7 +1332,7 @@ VOID CiAddrLib::HwlSetupTileInfo( if (tileIndex != TileIndexInvalid) { - ADDR_ASSERT(tileIndex < TileTableSize); + ADDR_ASSERT(static_cast<UINT_32>(tileIndex) < TileTableSize); // Non-depth entries store a split factor UINT_32 sampleSplit = m_tileTable[tileIndex].info.tileSplitBytes; UINT_32 tileBytes1x = BITS_TO_BYTES(bpp * MicroTilePixels * thickness); @@ -1318,7 +1364,7 @@ VOID CiAddrLib::HwlSetupTileInfo( */ VOID CiAddrLib::ReadGbTileMode( UINT_32 regValue, ///< [in] GB_TILE_MODE register - ADDR_TILECONFIG* pCfg ///< [out] output structure + AddrTileConfig* pCfg ///< [out] output structure ) const { GB_TILE_MODE gbTileMode; @@ -1915,3 +1961,4 @@ ADDR_E_RETURNCODE CiAddrLib::HwlGetMaxAlignments( return ADDR_OK; } + diff --git a/src/amd/addrlib/r800/ciaddrlib.h b/src/amd/addrlib/r800/ciaddrlib.h index 750b2b382e1..e959df39231 100644 --- a/src/amd/addrlib/r800/ciaddrlib.h +++ b/src/amd/addrlib/r800/ciaddrlib.h @@ -141,10 +141,7 @@ protected: virtual AddrTileMode HwlDegradeThickTileMode( AddrTileMode baseTileMode, UINT_32 numSlices, UINT_32* pBytesPerTile) const; - virtual BOOL_32 HwlOverrideTileMode( - const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, - AddrTileMode* pTileMode, - AddrTileType* pTileType) const; + virtual VOID HwlOverrideTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const; virtual ADDR_E_RETURNCODE HwlComputeDccInfo( const ADDR_COMPUTE_DCCINFO_INPUT* pIn, @@ -168,7 +165,7 @@ protected: private: VOID ReadGbTileMode( - UINT_32 regValue, ADDR_TILECONFIG* pCfg) const; + UINT_32 regValue, AddrTileConfig* pCfg) const; VOID ReadGbMacroTileCfg( UINT_32 regValue, ADDR_TILEINFO* pCfg) const; diff --git a/src/amd/addrlib/r800/egbaddrlib.cpp b/src/amd/addrlib/r800/egbaddrlib.cpp index 52cf59b1b04..854d5725df2 100644 --- a/src/amd/addrlib/r800/egbaddrlib.cpp +++ b/src/amd/addrlib/r800/egbaddrlib.cpp @@ -448,7 +448,9 @@ BOOL_32 EgBasedAddrLib::ComputeSurfaceInfoMacroTiled( pOut->pTileInfo, &pOut->baseAlign, &pOut->pitchAlign, - &pOut->heightAlign); + &pOut->heightAlign, + &pOut->blockWidth, + &pOut->blockHeight); if (valid) { @@ -471,23 +473,20 @@ BOOL_32 EgBasedAddrLib::ComputeSurfaceInfoMacroTiled( expHeight, expNumSlices, numSamples, - pOut->pitchAlign, - pOut->heightAlign, + pOut->blockWidth, + pOut->blockHeight, pOut->pTileInfo); if (!IsMacroTiled(expTileMode)) // Downgraded to micro-tiled { return ComputeSurfaceInfoMicroTiled(pIn, pOut, padDims, expTileMode); } - else + else if (microTileThickness != Thickness(expTileMode)) { - if (microTileThickness != Thickness(expTileMode)) - { - // - // Re-compute if thickness changed since bank-height may be changed! - // - return ComputeSurfaceInfoMacroTiled(pIn, pOut, padDims, expTileMode); - } + // + // Re-compute if thickness changed since bank-height may be changed! + // + return ComputeSurfaceInfoMacroTiled(pIn, pOut, padDims, expTileMode); } } @@ -507,7 +506,9 @@ BOOL_32 EgBasedAddrLib::ComputeSurfaceInfoMacroTiled( pOut->pTileInfo, &pOut->baseAlign, &pOut->pitchAlign, - &pOut->heightAlign); + &pOut->heightAlign, + &pOut->blockWidth, + &pOut->blockHeight); } // @@ -535,11 +536,51 @@ BOOL_32 EgBasedAddrLib::ComputeSurfaceInfoMacroTiled( } } - // - // Compute the size of a slice. - // - bytesPerSlice = BITS_TO_BYTES(static_cast<UINT_64>(paddedPitch) * - paddedHeight * NextPow2(pIn->bpp) * numSamples); + if ((pIn->flags.needEquation == TRUE) && + (m_chipFamily == ADDR_CHIP_FAMILY_SI) && + (pIn->numMipLevels > 1) && + (pIn->mipLevel == 0)) + { + BOOL_32 convertTo1D = FALSE; + + ADDR_ASSERT(Thickness(expTileMode) == 1); + + for (UINT_32 i = 1; i < pIn->numMipLevels; i++) + { + UINT_32 mipPitch = Max(1u, paddedPitch >> i); + UINT_32 mipHeight = Max(1u, pIn->height >> i); + UINT_32 mipSlices = pIn->flags.volume ? + Max(1u, pIn->numSlices >> i) : pIn->numSlices; + expTileMode = ComputeSurfaceMipLevelTileMode(expTileMode, + pIn->bpp, + mipPitch, + mipHeight, + mipSlices, + numSamples, + pOut->blockWidth, + pOut->blockHeight, + pOut->pTileInfo); + + if (IsMacroTiled(expTileMode)) + { + if (PowTwoAlign(mipPitch, pOut->blockWidth) != + PowTwoAlign(mipPitch, pOut->pitchAlign)) + { + convertTo1D = TRUE; + break; + } + } + else + { + break; + } + } + + if (convertTo1D) + { + return ComputeSurfaceInfoMicroTiled(pIn, pOut, padDims, ADDR_TM_1D_TILED_THIN1); + } + } pOut->pitch = paddedPitch; // Put this check right here to workaround special mipmap cases which the original height @@ -555,6 +596,12 @@ BOOL_32 EgBasedAddrLib::ComputeSurfaceInfoMacroTiled( pOut->depth = expNumSlices; + // + // Compute the size of a slice. + // + bytesPerSlice = BITS_TO_BYTES(static_cast<UINT_64>(paddedPitch) * + paddedHeight * NextPow2(pIn->bpp) * numSamples); + pOut->surfSize = bytesPerSlice * expNumSlices; pOut->tileMode = expTileMode; @@ -797,7 +844,9 @@ BOOL_32 EgBasedAddrLib::ComputeSurfaceAlignmentsMacroTiled( ADDR_TILEINFO* pTileInfo, ///< [in/out] bank structure. UINT_32* pBaseAlign, ///< [out] base address alignment in bytes UINT_32* pPitchAlign, ///< [out] pitch alignment in pixels - UINT_32* pHeightAlign ///< [out] height alignment in pixels + UINT_32* pHeightAlign, ///< [out] height alignment in pixels + UINT_32* pMacroTileWidth, ///< [out] macro tile width in pixels + UINT_32* pMacroTileHeight ///< [out] macro tile height in pixels ) const { BOOL_32 valid = SanityCheckMacroTiled(pTileInfo); @@ -858,6 +907,7 @@ BOOL_32 EgBasedAddrLib::ComputeSurfaceAlignmentsMacroTiled( pTileInfo->macroAspectRatio; *pPitchAlign = macroTileWidth; + *pMacroTileWidth = macroTileWidth; AdjustPitchAlignment(flags, pPitchAlign); @@ -868,6 +918,7 @@ BOOL_32 EgBasedAddrLib::ComputeSurfaceAlignmentsMacroTiled( pTileInfo->macroAspectRatio; *pHeightAlign = macroTileHeight; + *pMacroTileHeight = macroTileHeight; // // Compute base alignment @@ -1113,6 +1164,8 @@ BOOL_32 EgBasedAddrLib::HwlDegradeBaseLevel( UINT_32 baseAlign; UINT_32 pitchAlign; UINT_32 heightAlign; + UINT_32 macroTileWidth; + UINT_32 macroTileHeight; ADDR_ASSERT(pIn->pTileInfo); ADDR_TILEINFO tileInfo = *pIn->pTileInfo; @@ -1143,11 +1196,13 @@ BOOL_32 EgBasedAddrLib::HwlDegradeBaseLevel( &tileInfo, &baseAlign, &pitchAlign, - &heightAlign); + &heightAlign, + ¯oTileWidth, + ¯oTileHeight); if (valid) { - degrade = (pIn->width < pitchAlign || pIn->height < heightAlign); + degrade = ((pIn->width < macroTileWidth) || (pIn->height < macroTileHeight)); // Check whether 2D tiling still has too much footprint if (degrade == FALSE) { @@ -1413,6 +1468,137 @@ UINT_64 EgBasedAddrLib::DispatchComputeSurfaceAddrFromCoord( /** *************************************************************************************************** +* EgBasedAddrLib::ComputeMacroTileEquation +* +* @brief +* Computes the address equation in macro tile +* @return +* If equation can be computed +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE EgBasedAddrLib::ComputeMacroTileEquation( + UINT_32 log2BytesPP, ///< [in] log2 of bytes per pixel + AddrTileMode tileMode, ///< [in] tile mode + AddrTileType microTileType, ///< [in] micro tiling type + ADDR_TILEINFO* pTileInfo, ///< [in] bank structure + ADDR_EQUATION* pEquation ///< [out] Equation for addressing in macro tile + ) const +{ + ADDR_E_RETURNCODE retCode; + + // Element equation within a tile + retCode = ComputeMicroTileEquation(log2BytesPP, tileMode, microTileType, pEquation); + + if (retCode == ADDR_OK) + { + // Tile equesiton with signle pipe bank + UINT_32 numPipes = HwlGetPipes(pTileInfo); + UINT_32 numPipeBits = Log2(numPipes); + + for (UINT_32 i = 0; i < Log2(pTileInfo->bankWidth); i++) + { + pEquation->addr[pEquation->numBits].valid = 1; + pEquation->addr[pEquation->numBits].channel = 0; + pEquation->addr[pEquation->numBits].index = i + log2BytesPP + 3 + numPipeBits; + pEquation->numBits++; + } + + for (UINT_32 i = 0; i < Log2(pTileInfo->bankHeight); i++) + { + pEquation->addr[pEquation->numBits].valid = 1; + pEquation->addr[pEquation->numBits].channel = 1; + pEquation->addr[pEquation->numBits].index = i + 3; + pEquation->numBits++; + } + + ADDR_EQUATION equation; + memset(&equation, 0, sizeof(ADDR_EQUATION)); + + UINT_32 thresholdX = 32; + UINT_32 thresholdY = 32; + + if (IsPrtNoRotationTileMode(tileMode)) + { + UINT_32 macroTilePitch = + (MicroTileWidth * pTileInfo->bankWidth * numPipes) * pTileInfo->macroAspectRatio; + UINT_32 macroTileHeight = + (MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks) / + pTileInfo->macroAspectRatio; + thresholdX = Log2(macroTilePitch); + thresholdY = Log2(macroTileHeight); + } + + // Pipe equation + retCode = ComputePipeEquation(log2BytesPP, thresholdX, thresholdY, pTileInfo, &equation); + + if (retCode == ADDR_OK) + { + UINT_32 pipeBitStart = Log2(m_pipeInterleaveBytes); + + if (pEquation->numBits > pipeBitStart) + { + UINT_32 numLeftShift = pEquation->numBits - pipeBitStart; + + for (UINT_32 i = 0; i < numLeftShift; i++) + { + pEquation->addr[pEquation->numBits + equation.numBits - i - 1] = + pEquation->addr[pEquation->numBits - i - 1]; + pEquation->xor1[pEquation->numBits + equation.numBits - i - 1] = + pEquation->xor1[pEquation->numBits - i - 1]; + pEquation->xor2[pEquation->numBits + equation.numBits - i - 1] = + pEquation->xor2[pEquation->numBits - i - 1]; + } + } + + for (UINT_32 i = 0; i < equation.numBits; i++) + { + pEquation->addr[pipeBitStart + i] = equation.addr[i]; + pEquation->xor1[pipeBitStart + i] = equation.xor1[i]; + pEquation->xor2[pipeBitStart + i] = equation.xor2[i]; + pEquation->numBits++; + } + + // Bank equation + memset(&equation, 0, sizeof(ADDR_EQUATION)); + + retCode = ComputeBankEquation(log2BytesPP, thresholdX, thresholdY, + pTileInfo, &equation); + + if (retCode == ADDR_OK) + { + UINT_32 bankBitStart = pipeBitStart + numPipeBits + Log2(m_bankInterleave); + + if (pEquation->numBits > bankBitStart) + { + UINT_32 numLeftShift = pEquation->numBits - bankBitStart; + + for (UINT_32 i = 0; i < numLeftShift; i++) + { + pEquation->addr[pEquation->numBits + equation.numBits - i - 1] = + pEquation->addr[pEquation->numBits - i - 1]; + pEquation->xor1[pEquation->numBits + equation.numBits - i - 1] = + pEquation->xor1[pEquation->numBits - i - 1]; + pEquation->xor2[pEquation->numBits + equation.numBits - i - 1] = + pEquation->xor2[pEquation->numBits - i - 1]; + } + } + + for (UINT_32 i = 0; i < equation.numBits; i++) + { + pEquation->addr[bankBitStart + i] = equation.addr[i]; + pEquation->xor1[bankBitStart + i] = equation.xor1[i]; + pEquation->xor2[bankBitStart + i] = equation.xor2[i]; + pEquation->numBits++; + } + } + } + } + + return retCode; +} + +/** +*************************************************************************************************** * EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled * * @brief diff --git a/src/amd/addrlib/r800/egbaddrlib.h b/src/amd/addrlib/r800/egbaddrlib.h index d43eca81aae..a4240829fa0 100644 --- a/src/amd/addrlib/r800/egbaddrlib.h +++ b/src/amd/addrlib/r800/egbaddrlib.h @@ -254,6 +254,13 @@ protected: ADDR_TILEINFO* pTileInfo) const; /// Addressing functions + virtual ADDR_E_RETURNCODE ComputeBankEquation( + UINT_32 log2BytesPP, UINT_32 threshX, UINT_32 threshY, + ADDR_TILEINFO* pTileInfo, ADDR_EQUATION* pEquation) const + { + return ADDR_NOTSUPPORTED; + } + UINT_32 ComputeBankFromCoord( UINT_32 x, UINT_32 y, UINT_32 slice, AddrTileMode tileMode, UINT_32 bankSwizzle, UINT_32 tileSpitSlice, @@ -281,6 +288,10 @@ protected: UINT_32 pitch, UINT_32 height, UINT_32 bpp, BOOL_32 isLinear, UINT_32 numSlices, UINT_64* sliceBytes, UINT_32 baseAlign) const; + ADDR_E_RETURNCODE ComputeMacroTileEquation( + UINT_32 log2BytesPP, AddrTileMode tileMode, AddrTileType microTileType, + ADDR_TILEINFO* pTileInfo, ADDR_EQUATION* pEquation) const; + // Static functions static BOOL_32 IsTileInfoAllZero(ADDR_TILEINFO* pTileInfo); static UINT_32 ComputeFmaskNumPlanesFromNumSamples(UINT_32 numSamples); @@ -318,7 +329,8 @@ private: AddrTileMode tileMode, UINT_32 bpp, ADDR_SURFACE_FLAGS flags, UINT_32 mipLevel, UINT_32 numSamples, ADDR_TILEINFO* pTileInfo, - UINT_32* pBaseAlign, UINT_32* pPitchAlign, UINT_32* pHeightAlign) const; + UINT_32* pBaseAlign, UINT_32* pPitchAlign, UINT_32* pHeightAlign, + UINT_32* pMacroTileWidth, UINT_32* pMacroTileHeight) const; /// Surface addressing functions UINT_64 DispatchComputeSurfaceAddrFromCoord( diff --git a/src/amd/addrlib/r800/siaddrlib.cpp b/src/amd/addrlib/r800/siaddrlib.cpp index 694c0f3a4bb..686bb7fc343 100644 --- a/src/amd/addrlib/r800/siaddrlib.cpp +++ b/src/amd/addrlib/r800/siaddrlib.cpp @@ -73,7 +73,8 @@ AddrLib* AddrSIHwlInit(const AddrClient* pClient) */ SiAddrLib::SiAddrLib(const AddrClient* pClient) : EgBasedAddrLib(pClient), - m_noOfEntries(0) + m_noOfEntries(0), + m_numEquations(0) { m_class = SI_ADDRLIB; memset(&m_settings, 0, sizeof(m_settings)); @@ -168,6 +169,338 @@ UINT_32 SiAddrLib::GetPipePerSurf( /** *************************************************************************************************** +* SiAddrLib::ComputeBankEquation +* +* @brief +* Compute bank equation +* +* @return +* If equation can be computed +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE SiAddrLib::ComputeBankEquation( + UINT_32 log2BytesPP, ///< [in] log2 of bytes per pixel + UINT_32 threshX, ///< [in] threshold for x channel + UINT_32 threshY, ///< [in] threshold for y channel + ADDR_TILEINFO* pTileInfo, ///< [in] tile info + ADDR_EQUATION* pEquation ///< [out] bank equation + ) const +{ + ADDR_E_RETURNCODE retCode = ADDR_OK; + + UINT_32 pipes = HwlGetPipes(pTileInfo); + UINT_32 bankXStart = 3 + Log2(pipes) + Log2(pTileInfo->bankWidth); + UINT_32 bankYStart = 3 + Log2(pTileInfo->bankHeight); + + ADDR_CHANNEL_SETTING x3 = InitChannel(1, 0, log2BytesPP + bankXStart); + ADDR_CHANNEL_SETTING x4 = InitChannel(1, 0, log2BytesPP + bankXStart + 1); + ADDR_CHANNEL_SETTING x5 = InitChannel(1, 0, log2BytesPP + bankXStart + 2); + ADDR_CHANNEL_SETTING x6 = InitChannel(1, 0, log2BytesPP + bankXStart + 3); + ADDR_CHANNEL_SETTING y3 = InitChannel(1, 1, bankYStart); + ADDR_CHANNEL_SETTING y4 = InitChannel(1, 1, bankYStart + 1); + ADDR_CHANNEL_SETTING y5 = InitChannel(1, 1, bankYStart + 2); + ADDR_CHANNEL_SETTING y6 = InitChannel(1, 1, bankYStart + 3); + + x3.value = (threshX > bankXStart) ? x3.value : 0; + x4.value = (threshX > bankXStart + 1) ? x4.value : 0; + x5.value = (threshX > bankXStart + 2) ? x5.value : 0; + x6.value = (threshX > bankXStart + 3) ? x6.value : 0; + y3.value = (threshY > bankYStart) ? y3.value : 0; + y4.value = (threshY > bankYStart + 1) ? y4.value : 0; + y5.value = (threshY > bankYStart + 2) ? y5.value : 0; + y6.value = (threshY > bankYStart + 3) ? y6.value : 0; + + switch (pTileInfo->banks) + { + case 16: + pEquation->addr[0] = y6; + pEquation->xor1[0] = x3; + pEquation->addr[1] = y5; + pEquation->xor1[1] = y6; + pEquation->xor2[1] = x4; + pEquation->addr[2] = y4; + pEquation->xor1[2] = x5; + pEquation->addr[3] = y3; + pEquation->xor1[3] = x6; + pEquation->numBits = 4; + break; + case 8: + pEquation->addr[0] = y5; + pEquation->xor1[0] = x3; + pEquation->addr[1] = y4; + pEquation->xor1[1] = y5; + pEquation->xor2[1] = x4; + pEquation->addr[2] = y3; + pEquation->xor1[2] = x5; + pEquation->numBits = 3; + break; + case 4: + pEquation->addr[0] = y4; + pEquation->xor1[0] = x3; + pEquation->addr[1] = y3; + pEquation->xor1[1] = x4; + pEquation->numBits = 2; + break; + case 2: + pEquation->addr[0] = y3; + pEquation->xor1[0] = x3; + pEquation->numBits = 1; + break; + default: + pEquation->numBits = 0; + retCode = ADDR_NOTSUPPORTED; + ADDR_ASSERT_ALWAYS(); + break; + } + + for (UINT_32 i = 0; i < pEquation->numBits; i++) + { + if (pEquation->addr[i].value == 0) + { + if (pEquation->xor1[i].value == 0) + { + // 00X -> X00 + pEquation->addr[i].value = pEquation->xor2[i].value; + pEquation->xor2[i].value = 0; + } + else + { + pEquation->addr[i].value = pEquation->xor1[i].value; + + if (pEquation->xor2[i].value != 0) + { + // 0XY -> XY0 + pEquation->xor1[i].value = pEquation->xor2[i].value; + pEquation->xor2[i].value = 0; + } + else + { + // 0X0 -> X00 + pEquation->xor1[i].value = 0; + } + } + } + else if (pEquation->xor1[i].value == 0) + { + if (pEquation->xor2[i].value != 0) + { + // X0Y -> XY0 + pEquation->xor1[i].value = pEquation->xor2[i].value; + pEquation->xor2[i].value = 0; + } + } + } + + if ((pTileInfo->bankWidth == 1) && + ((pTileInfo->pipeConfig == ADDR_PIPECFG_P4_32x32) || + (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32))) + { + retCode = ADDR_NOTSUPPORTED; + } + + return retCode; +} + +/** +*************************************************************************************************** +* SiAddrLib::ComputePipeEquation +* +* @brief +* Compute pipe equation +* +* @return +* If equation can be computed +*************************************************************************************************** +*/ +ADDR_E_RETURNCODE SiAddrLib::ComputePipeEquation( + UINT_32 log2BytesPP, ///< [in] Log2 of bytes per pixel + UINT_32 threshX, ///< [in] Threshold for X channel + UINT_32 threshY, ///< [in] Threshold for Y channel + ADDR_TILEINFO* pTileInfo, ///< [in] Tile info + ADDR_EQUATION* pEquation ///< [out] Pipe configure + ) const +{ + ADDR_E_RETURNCODE retCode = ADDR_OK; + + ADDR_CHANNEL_SETTING* pAddr = pEquation->addr; + ADDR_CHANNEL_SETTING* pXor1 = pEquation->xor1; + ADDR_CHANNEL_SETTING* pXor2 = pEquation->xor2; + + ADDR_CHANNEL_SETTING x3 = InitChannel(1, 0, 3 + log2BytesPP); + ADDR_CHANNEL_SETTING x4 = InitChannel(1, 0, 4 + log2BytesPP); + ADDR_CHANNEL_SETTING x5 = InitChannel(1, 0, 5 + log2BytesPP); + ADDR_CHANNEL_SETTING x6 = InitChannel(1, 0, 6 + log2BytesPP); + ADDR_CHANNEL_SETTING y3 = InitChannel(1, 1, 3); + ADDR_CHANNEL_SETTING y4 = InitChannel(1, 1, 4); + ADDR_CHANNEL_SETTING y5 = InitChannel(1, 1, 5); + ADDR_CHANNEL_SETTING y6 = InitChannel(1, 1, 6); + + x3.value = (threshX > 3) ? x3.value : 0; + x4.value = (threshX > 4) ? x4.value : 0; + x5.value = (threshX > 5) ? x5.value : 0; + x6.value = (threshX > 6) ? x6.value : 0; + y3.value = (threshY > 3) ? y3.value : 0; + y4.value = (threshY > 4) ? y4.value : 0; + y5.value = (threshY > 5) ? y5.value : 0; + y6.value = (threshY > 6) ? y6.value : 0; + + switch (pTileInfo->pipeConfig) + { + case ADDR_PIPECFG_P2: + pAddr[0] = x3; + pXor1[0] = y3; + pEquation->numBits = 1; + break; + case ADDR_PIPECFG_P4_8x16: + pAddr[0] = x4; + pXor1[0] = y3; + pAddr[1] = x3; + pXor1[1] = y4; + pEquation->numBits = 2; + break; + case ADDR_PIPECFG_P4_16x16: + pAddr[0] = x3; + pXor1[0] = y3; + pXor2[0] = x4; + pAddr[1] = x4; + pXor1[1] = y4; + pEquation->numBits = 2; + break; + case ADDR_PIPECFG_P4_16x32: + pAddr[0] = x3; + pXor1[0] = y3; + pXor2[0] = x4; + pAddr[1] = x4; + pXor1[1] = y5; + pEquation->numBits = 2; + break; + case ADDR_PIPECFG_P4_32x32: + pAddr[0] = x3; + pXor1[0] = y3; + pXor2[0] = x5; + pAddr[1] = x5; + pXor1[1] = y5; + pEquation->numBits = 2; + break; + case ADDR_PIPECFG_P8_16x16_8x16: + pAddr[0] = x4; + pXor1[0] = y3; + pXor2[0] = x5; + pAddr[1] = x3; + pXor1[1] = y5; + pEquation->numBits = 3; + break; + case ADDR_PIPECFG_P8_16x32_8x16: + pAddr[0] = x4; + pXor1[0] = y3; + pXor2[0] = x5; + pAddr[1] = x3; + pXor1[1] = y4; + pAddr[2] = x4; + pXor1[2] = y5; + pEquation->numBits = 3; + break; + case ADDR_PIPECFG_P8_16x32_16x16: + pAddr[0] = x3; + pXor1[0] = y3; + pXor2[0] = x4; + pAddr[1] = x5; + pXor1[1] = y4; + pAddr[2] = x4; + pXor1[2] = y5; + pEquation->numBits = 3; + break; + case ADDR_PIPECFG_P8_32x32_8x16: + pAddr[0] = x4; + pXor1[0] = y3; + pXor2[0] = x5; + pAddr[1] = x3; + pXor1[1] = y4; + pAddr[2] = x5; + pXor1[2] = y5; + pEquation->numBits = 3; + break; + case ADDR_PIPECFG_P8_32x32_16x16: + pAddr[0] = x3; + pXor1[0] = y3; + pXor2[0] = x4; + pAddr[1] = x4; + pXor1[1] = y4; + pAddr[2] = x5; + pXor1[2] = y5; + pEquation->numBits = 3; + break; + case ADDR_PIPECFG_P8_32x32_16x32: + pAddr[0] = x3; + pXor1[0] = y3; + pXor2[0] = x4; + pAddr[1] = x4; + pXor1[1] = y6; + pAddr[2] = x5; + pXor1[2] = y5; + pEquation->numBits = 3; + break; + case ADDR_PIPECFG_P8_32x64_32x32: + pAddr[0] = x3; + pXor1[0] = y3; + pXor2[0] = x5; + pAddr[1] = x6; + pXor1[1] = y5; + pAddr[2] = x5; + pXor1[2] = y6; + pEquation->numBits = 3; + break; + case ADDR_PIPECFG_P16_32x32_8x16: + pAddr[0] = x4; + pXor1[0] = y3; + pAddr[1] = x3; + pXor1[1] = y4; + pAddr[2] = x5; + pXor1[2] = y6; + pAddr[3] = x6; + pXor1[3] = y5; + pEquation->numBits = 4; + break; + case ADDR_PIPECFG_P16_32x32_16x16: + pAddr[0] = x3; + pXor1[0] = y3; + pXor2[0] = x4; + pAddr[1] = x4; + pXor1[1] = y4; + pAddr[2] = x5; + pXor1[2] = y6; + pAddr[3] = x6; + pXor1[3] = y5; + pEquation->numBits = 4; + break; + default: + ADDR_UNHANDLED_CASE(); + pEquation->numBits = 0; + retCode = ADDR_NOTSUPPORTED; + break; + } + + for (UINT_32 i = 0; i < pEquation->numBits; i++) + { + if (pAddr[i].value == 0) + { + if (pXor1[i].value == 0) + { + pAddr[i].value = pXor2[i].value; + } + else + { + pAddr[i].value = pXor1[i].value; + pXor1[i].value = 0; + } + } + } + + return retCode; +} + +/** +*************************************************************************************************** * SiAddrLib::ComputePipeFromCoord * * @brief @@ -1889,6 +2222,11 @@ BOOL_32 SiAddrLib::HwlInitGlobalParams( valid = InitTileSettingTable(pRegValue->pTileConfig, pRegValue->noOfEntries); + if (valid) + { + InitEquationTable(); + } + m_maxSamples = 16; } @@ -2174,7 +2512,31 @@ ADDR_E_RETURNCODE SiAddrLib::HwlComputeSurfaceInfo( { pOut->tileIndex = pIn->tileIndex; - return EgBasedAddrLib::HwlComputeSurfaceInfo(pIn,pOut); + ADDR_E_RETURNCODE retCode = EgBasedAddrLib::HwlComputeSurfaceInfo(pIn, pOut); + + UINT_32 tileIndex = static_cast<UINT_32>(pOut->tileIndex); + + if ((pIn->flags.needEquation == TRUE) && + (pIn->numSamples <= 1) && + (tileIndex < TileTableSize)) + { + pOut->equationIndex = m_equationLookupTable[Log2(pIn->bpp >> 3)][tileIndex]; + + if (pOut->equationIndex != ADDR_INVALID_EQUATION_INDEX) + { + pOut->blockWidth = m_blockWidth[pOut->equationIndex]; + + pOut->blockHeight = m_blockHeight[pOut->equationIndex]; + + pOut->blockSlices = m_blockSlices[pOut->equationIndex]; + } + } + else + { + pOut->equationIndex = ADDR_INVALID_EQUATION_INDEX; + } + + return retCode; } /** @@ -2282,8 +2644,8 @@ VOID SiAddrLib::HwlCheckLastMacroTiledLvl( nextHeight, nextSlices, pIn->numSamples, - pOut->pitchAlign, - pOut->heightAlign, + pOut->blockWidth, + pOut->blockHeight, pOut->pTileInfo); pOut->last2DLevel = IsMicroTiled(nextTileMode); @@ -2345,7 +2707,7 @@ BOOL_32 SiAddrLib::HwlTileInfoEqual( * Tile setting info. *************************************************************************************************** */ -const ADDR_TILECONFIG* SiAddrLib::GetTileSetting( +const AddrTileConfig* SiAddrLib::GetTileSetting( UINT_32 index ///< [in] Tile index ) const { @@ -2484,7 +2846,7 @@ ADDR_E_RETURNCODE SiAddrLib::HwlSetupTileCfg( } else { - const ADDR_TILECONFIG* pCfgTable = GetTileSetting(index); + const AddrTileConfig* pCfgTable = GetTileSetting(index); if (pInfo) { @@ -2525,7 +2887,7 @@ ADDR_E_RETURNCODE SiAddrLib::HwlSetupTileCfg( */ VOID SiAddrLib::ReadGbTileMode( UINT_32 regValue, ///< [in] GB_TILE_MODE register - ADDR_TILECONFIG* pCfg ///< [out] output structure + AddrTileConfig* pCfg ///< [out] output structure ) const { GB_TILE_MODE gbTileMode; @@ -2773,18 +3135,15 @@ UINT_32 SiAddrLib::HwlComputeFmaskBits( * Override tile modes (for PRT only, avoid client passes in an invalid PRT mode for SI. * * @return -* Suitable tile mode +* N/A * *************************************************************************************************** */ -BOOL_32 SiAddrLib::HwlOverrideTileMode( - const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure - AddrTileMode* pTileMode, ///< [in/out] pointer to the tile mode - AddrTileType* pTileType ///< [in/out] pointer to the tile type +void SiAddrLib::HwlOverrideTileMode( + ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in/out] input output structure ) const { - BOOL_32 bOverrided = FALSE; - AddrTileMode tileMode = *pTileMode; + AddrTileMode tileMode = pInOut->tileMode; switch (tileMode) { @@ -2808,14 +3167,34 @@ BOOL_32 SiAddrLib::HwlOverrideTileMode( break; } - if (tileMode != *pTileMode) + if ((pInOut->flags.needEquation == TRUE) && + (IsMacroTiled(tileMode) == TRUE) && + (pInOut->numSamples <= 1)) { - *pTileMode = tileMode; - bOverrided = TRUE; - ADDR_ASSERT(pIn->flags.prt == TRUE); + 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; + } } - return bOverrided; + if (tileMode != pInOut->tileMode) + { + pInOut->tileMode = tileMode; + + ADDR_ASSERT(pInOut->flags.prt == TRUE); + } } /** @@ -2864,3 +3243,249 @@ ADDR_E_RETURNCODE SiAddrLib::HwlGetMaxAlignments( return ADDR_OK; } +/** +*************************************************************************************************** +* SiAddrLib::InitEquationTable +* +* @brief +* Initialize Equation table. +* +* @return +* N/A +*************************************************************************************************** +*/ +VOID SiAddrLib::InitEquationTable() +{ + ADDR_EQUATION_KEY equationKeyTable[EquationTableSize]; + memset(equationKeyTable, 0, sizeof(equationKeyTable)); + + memset(m_equationTable, 0, sizeof(m_equationTable)); + + memset(m_blockWidth, 0, sizeof(m_blockWidth)); + + memset(m_blockHeight, 0, sizeof(m_blockHeight)); + + memset(m_blockSlices, 0, sizeof(m_blockSlices)); + + // Loop all possible bpp + for (UINT_32 log2ElementBytes = 0; log2ElementBytes < MaxNumElementBytes; log2ElementBytes++) + { + // Get bits per pixel + UINT_32 bpp = 1 << (log2ElementBytes + 3); + + // Loop all possible tile index + for (INT_32 tileIndex = 0; tileIndex < m_noOfEntries; tileIndex++) + { + UINT_32 equationIndex = ADDR_INVALID_EQUATION_INDEX; + + AddrTileConfig tileConfig = m_tileTable[tileIndex]; + + ADDR_SURFACE_FLAGS flags = {{0}}; + + // Compute tile info, hardcode numSamples to 1 because MSAA is not supported + // in swizzle pattern equation + HwlComputeMacroModeIndex(tileIndex, flags, bpp, 1, &tileConfig.info, NULL, NULL); + + // Check if the input is supported + if (IsEquationSupported(bpp, tileConfig, tileIndex) == TRUE) + { + ADDR_EQUATION_KEY key = {{0}}; + + // Generate swizzle equation key from bpp and tile config + key.fields.log2ElementBytes = log2ElementBytes; + key.fields.tileMode = tileConfig.mode; + // Treat depth micro tile type and non-display micro tile type as the same key + // because they have the same equation actually + key.fields.microTileType = (tileConfig.type == ADDR_DEPTH_SAMPLE_ORDER) ? + ADDR_NON_DISPLAYABLE : tileConfig.type; + key.fields.pipeConfig = tileConfig.info.pipeConfig; + key.fields.numBanks = tileConfig.info.banks; + key.fields.bankWidth = tileConfig.info.bankWidth; + key.fields.bankHeight = tileConfig.info.bankHeight; + key.fields.macroAspectRatio = tileConfig.info.macroAspectRatio; + + // Find in the table if the equation has been built based on the key + for (UINT_32 i = 0; i < m_numEquations; i++) + { + if (key.value == equationKeyTable[i].value) + { + equationIndex = i; + break; + } + } + + // If found, just fill the index into the lookup table and no need + // to generate the equation again. Otherwise, generate the equation. + if (equationIndex == ADDR_INVALID_EQUATION_INDEX) + { + ADDR_EQUATION equation; + ADDR_E_RETURNCODE retCode; + + memset(&equation, 0, sizeof(ADDR_EQUATION)); + + // Generate the equation + if (IsMicroTiled(tileConfig.mode)) + { + retCode = ComputeMicroTileEquation(log2ElementBytes, + tileConfig.mode, + tileConfig.type, + &equation); + } + else + { + retCode = ComputeMacroTileEquation(log2ElementBytes, + tileConfig.mode, + tileConfig.type, + &tileConfig.info, + &equation); + } + // Only fill the equation into the table if the return code is ADDR_OK, + // otherwise if the return code is not ADDR_OK, it indicates this is not + // a valid input, we do nothing but just fill invalid equation index + // into the lookup table. + if (retCode == ADDR_OK) + { + equationIndex = m_numEquations; + ADDR_ASSERT(equationIndex < EquationTableSize); + + m_blockSlices[equationIndex] = Thickness(tileConfig.mode); + + if (IsMicroTiled(tileConfig.mode)) + { + m_blockWidth[equationIndex] = MicroTileWidth; + m_blockHeight[equationIndex] = MicroTileHeight; + } + else + { + const ADDR_TILEINFO* pTileInfo = &tileConfig.info; + + 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); + + UINT_32 numBits = Log2(numMacroTiles); + + UINT_32 xStart = Log2(m_blockWidth[equationIndex]) + + log2ElementBytes; + + m_blockWidth[equationIndex] *= numMacroTiles; + + for (UINT_32 i = 0; i < numBits; i++) + { + equation.addr[equation.numBits + i].valid = 1; + equation.addr[equation.numBits + i].index = xStart + i; + } + + equation.numBits += numBits; + } + } + } + + equationKeyTable[equationIndex] = key; + m_equationTable[equationIndex] = equation; + + m_numEquations++; + } + } + } + + // Fill the index into the lookup table, if the combination is not supported + // fill the invalid equation index + m_equationLookupTable[log2ElementBytes][tileIndex] = equationIndex; + } + } +} + +/** +*************************************************************************************************** +* SiAddrLib::IsEquationSupported +* +* @brief +* Check if it is supported for given bpp and tile config to generate a equation. +* +* @return +* TRUE if supported +*************************************************************************************************** +*/ +BOOL_32 SiAddrLib::IsEquationSupported( + UINT_32 bpp, ///< Bits per pixel + AddrTileConfig tileConfig, ///< Tile config + INT_32 tileIndex ///< Tile index + ) const +{ + BOOL_32 supported = TRUE; + + // Linear tile mode is not supported in swizzle pattern equation + if (IsLinear(tileConfig.mode)) + { + supported = FALSE; + } + // These tile modes are for Tex2DArray and Tex3D which has depth (num_slice > 1) use, + // which is not supported in swizzle pattern equation due to slice rotation + else if ((tileConfig.mode == ADDR_TM_2D_TILED_THICK) || + (tileConfig.mode == ADDR_TM_2D_TILED_XTHICK) || + (tileConfig.mode == ADDR_TM_3D_TILED_THIN1) || + (tileConfig.mode == ADDR_TM_3D_TILED_THICK) || + (tileConfig.mode == ADDR_TM_3D_TILED_XTHICK)) + { + supported = FALSE; + } + // Only 8bpp(stencil), 16bpp and 32bpp is supported for depth + else if ((tileConfig.type == ADDR_DEPTH_SAMPLE_ORDER) && (bpp > 32)) + { + supported = FALSE; + } + // Tile split is not supported in swizzle pattern equation + else if (IsMacroTiled(tileConfig.mode)) + { + UINT_32 thickness = Thickness(tileConfig.mode); + if (((bpp >> 3) * MicroTilePixels * thickness) > tileConfig.info.tileSplitBytes) + { + supported = FALSE; + } + + if ((supported == TRUE) && (m_chipFamily == ADDR_CHIP_FAMILY_SI)) + { + // Please refer to SiAddrLib::HwlSetupTileInfo for PRT tile index selecting + // Tile index 3, 6, 21-25 are for PRT single sample + if (tileIndex == 3) + { + supported = (bpp == 16); + } + else if (tileIndex == 6) + { + supported = (bpp == 32); + } + else if ((tileIndex >= 21) && (tileIndex <= 25)) + { + supported = (bpp == 8u * (1u << (static_cast<UINT_32>(tileIndex) - 21u))); + } + else + { + supported = FALSE; + } + } + } + + return supported; +} + + diff --git a/src/amd/addrlib/r800/siaddrlib.h b/src/amd/addrlib/r800/siaddrlib.h index 9201fb220fd..814cd0095db 100644 --- a/src/amd/addrlib/r800/siaddrlib.h +++ b/src/amd/addrlib/r800/siaddrlib.h @@ -42,7 +42,7 @@ * @brief Describes the information in tile mode table *************************************************************************************************** */ -struct ADDR_TILECONFIG +struct AddrTileConfig { AddrTileMode mode; AddrTileType type; @@ -131,6 +131,14 @@ protected: UINT_32 pitch, UINT_32 height, UINT_32 bpp, BOOL_32 isLinear, UINT_32 numSlices, UINT_64* pSliceBytes, UINT_32 baseAlign) const; + virtual ADDR_E_RETURNCODE ComputeBankEquation( + UINT_32 log2BytesPP, UINT_32 threshX, UINT_32 threshY, + ADDR_TILEINFO* pTileInfo, ADDR_EQUATION* pEquation) const; + + virtual ADDR_E_RETURNCODE ComputePipeEquation( + UINT_32 log2BytesPP, UINT_32 threshX, UINT_32 threshY, + ADDR_TILEINFO* pTileInfo, ADDR_EQUATION* pEquation) const; + virtual UINT_32 ComputePipeFromCoord( UINT_32 x, UINT_32 y, UINT_32 slice, AddrTileMode tileMode, UINT_32 pipeSwizzle, BOOL_32 ignoreSE, @@ -173,10 +181,7 @@ protected: virtual AddrTileMode HwlDegradeThickTileMode( AddrTileMode baseTileMode, UINT_32 numSlices, UINT_32* pBytesPerTile) const; - virtual BOOL_32 HwlOverrideTileMode( - const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, - AddrTileMode* pTileMode, - AddrTileType* pTileType) const; + virtual VOID HwlOverrideTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const; virtual BOOL_32 HwlSanityCheckMacroTiled( ADDR_TILEINFO* pTileInfo) const @@ -229,6 +234,18 @@ protected: virtual ADDR_E_RETURNCODE HwlGetMaxAlignments(ADDR_GET_MAX_ALINGMENTS_OUTPUT* pOut) const; + // Get equation table pointer and number of equations + virtual UINT_32 HwlGetEquationTableInfo(const ADDR_EQUATION** ppEquationTable) const + { + *ppEquationTable = m_equationTable; + + return m_numEquations; + } + + // Check if it is supported for given bpp and tile config to generate an equation + BOOL_32 IsEquationSupported( + UINT_32 bpp, AddrTileConfig tileConfig, INT_32 tileIndex) const; + // Protected non-virtual functions VOID ComputeTileCoordFromPipeAndElemIdx( UINT_32 elemIdx, UINT_32 pipe, AddrPipeCfg pipeCfg, UINT_32 pitchInMacroTile, @@ -241,19 +258,36 @@ protected: BOOL_32 DecodeGbRegs( const ADDR_REGISTER_VALUE* pRegValue); - const ADDR_TILECONFIG* GetTileSetting( + const AddrTileConfig* GetTileSetting( UINT_32 index) const; + // Initialize equation table + VOID InitEquationTable(); + static const UINT_32 TileTableSize = 32; - ADDR_TILECONFIG m_tileTable[TileTableSize]; + AddrTileConfig m_tileTable[TileTableSize]; UINT_32 m_noOfEntries; + // Max number of bpp (8bpp/16bpp/32bpp/64bpp/128bpp) + static const UINT_32 MaxNumElementBytes = 5; + // More than half slots in tile mode table can't support equation + static const UINT_32 EquationTableSize = (MaxNumElementBytes * TileTableSize) / 2; + // Equation table + ADDR_EQUATION m_equationTable[EquationTableSize]; + UINT_32 m_blockWidth[EquationTableSize]; + UINT_32 m_blockHeight[EquationTableSize]; + UINT_32 m_blockSlices[EquationTableSize]; + // Number of equation entries in the table + UINT_32 m_numEquations; + // Equation lookup table according to bpp and tile index + UINT_32 m_equationLookupTable[MaxNumElementBytes][TileTableSize]; + private: UINT_32 GetPipePerSurf(AddrPipeCfg pipeConfig) const; VOID ReadGbTileMode( - UINT_32 regValue, ADDR_TILECONFIG* pCfg) const; + UINT_32 regValue, AddrTileConfig* pCfg) const; BOOL_32 InitTileSettingTable( const UINT_32 *pSetting, UINT_32 noOfEntries); |