summaryrefslogtreecommitdiffstats
path: root/src/amd/addrlib/r800
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2016-09-05 09:54:07 +1000
committerDave Airlie <[email protected]>2016-09-06 10:06:33 +1000
commit69fca64259495d7a31135876e818e1ac2a36d190 (patch)
tree3462cfa208d32e2939a07681c0ab2ed56ff648da /src/amd/addrlib/r800
parent1add3562e33f0234da50e54dda8cfa6dac613125 (diff)
amd/addrlib: move addrlib from amdgpu winsys to common code
Acked-by: Marek Olšák <[email protected]> Reviewed-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src/amd/addrlib/r800')
-rw-r--r--src/amd/addrlib/r800/chip/si_ci_vi_merged_enum.h40
-rw-r--r--src/amd/addrlib/r800/ciaddrlib.cpp1831
-rw-r--r--src/amd/addrlib/r800/ciaddrlib.h202
-rw-r--r--src/amd/addrlib/r800/egbaddrlib.cpp4577
-rw-r--r--src/amd/addrlib/r800/egbaddrlib.h412
-rw-r--r--src/amd/addrlib/r800/siaddrlib.cpp2818
-rw-r--r--src/amd/addrlib/r800/siaddrlib.h262
7 files changed, 10142 insertions, 0 deletions
diff --git a/src/amd/addrlib/r800/chip/si_ci_vi_merged_enum.h b/src/amd/addrlib/r800/chip/si_ci_vi_merged_enum.h
new file mode 100644
index 00000000000..5ed81add264
--- /dev/null
+++ b/src/amd/addrlib/r800/chip/si_ci_vi_merged_enum.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright © 2014 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+#if !defined (SI_CI_VI_MERGED_ENUM_HEADER)
+#define SI_CI_VI_MERGED_ENUM_HEADER
+
+typedef enum PipeInterleaveSize {
+ADDR_CONFIG_PIPE_INTERLEAVE_256B = 0x00000000,
+ADDR_CONFIG_PIPE_INTERLEAVE_512B = 0x00000001,
+} PipeInterleaveSize;
+
+typedef enum RowSize {
+ADDR_CONFIG_1KB_ROW = 0x00000000,
+ADDR_CONFIG_2KB_ROW = 0x00000001,
+ADDR_CONFIG_4KB_ROW = 0x00000002,
+} RowSize;
+
+#endif
diff --git a/src/amd/addrlib/r800/ciaddrlib.cpp b/src/amd/addrlib/r800/ciaddrlib.cpp
new file mode 100644
index 00000000000..7c5d29a2166
--- /dev/null
+++ b/src/amd/addrlib/r800/ciaddrlib.cpp
@@ -0,0 +1,1831 @@
+/*
+ * Copyright © 2014 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+
+/**
+***************************************************************************************************
+* @file ciaddrlib.cpp
+* @brief Contains the implementation for the CIAddrLib class.
+***************************************************************************************************
+*/
+
+#include "ciaddrlib.h"
+
+#include "si_gb_reg.h"
+
+#include "si_ci_vi_merged_enum.h"
+
+#if BRAHMA_BUILD
+#include "amdgpu_id.h"
+#else
+#include "ci_id.h"
+#include "kv_id.h"
+#include "vi_id.h"
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+***************************************************************************************************
+* AddrMask
+*
+* @brief
+* Gets a mask of "width"
+* @return
+* Bit mask
+***************************************************************************************************
+*/
+static UINT_64 AddrMask(
+ UINT_32 width) ///< Width of bits
+{
+ UINT_64 ret;
+
+ if (width >= sizeof(UINT_64)*8)
+ {
+ ret = ~((UINT_64) 0);
+ }
+ else
+ {
+ return (((UINT_64) 1) << width) - 1;
+ }
+ return ret;
+}
+
+/**
+***************************************************************************************************
+* AddrGetBits
+*
+* @brief
+* Gets bits within a range of [msb, lsb]
+* @return
+* Bits of this range
+***************************************************************************************************
+*/
+static UINT_64 AddrGetBits(
+ UINT_64 bits, ///< Source bits
+ UINT_32 msb, ///< Most signicant bit
+ UINT_32 lsb) ///< Least signicant bit
+{
+ UINT_64 ret = 0;
+
+ if (msb >= lsb)
+ {
+ ret = (bits >> lsb) & (AddrMask(1 + msb - lsb));
+ }
+ return ret;
+}
+
+/**
+***************************************************************************************************
+* AddrRemoveBits
+*
+* @brief
+* Removes bits within the range of [msb, lsb]
+* @return
+* Modified bits
+***************************************************************************************************
+*/
+static UINT_64 AddrRemoveBits(
+ UINT_64 bits, ///< Source bits
+ UINT_32 msb, ///< Most signicant bit
+ UINT_32 lsb) ///< Least signicant bit
+{
+ UINT_64 ret = bits;
+
+ if (msb >= lsb)
+ {
+ ret = AddrGetBits(bits, lsb - 1, 0) // low bits
+ | (AddrGetBits(bits, 8 * sizeof(bits) - 1, msb + 1) << lsb); //high bits
+ }
+ return ret;
+}
+
+/**
+***************************************************************************************************
+* AddrInsertBits
+*
+* @brief
+* Inserts new bits into the range of [msb, lsb]
+* @return
+* Modified bits
+***************************************************************************************************
+*/
+static UINT_64 AddrInsertBits(
+ UINT_64 bits, ///< Source bits
+ UINT_64 newBits, ///< New bits to be inserted
+ UINT_32 msb, ///< Most signicant bit
+ UINT_32 lsb) ///< Least signicant bit
+{
+ UINT_64 ret = bits;
+
+ if (msb >= lsb)
+ {
+ ret = AddrGetBits(bits, lsb - 1, 0) // old low bitss
+ | (AddrGetBits(newBits, msb - lsb, 0) << lsb) //new bits
+ | (AddrGetBits(bits, 8 * sizeof(bits) - 1, lsb) << (msb + 1)); //old high bits
+ }
+ return ret;
+}
+
+
+/**
+***************************************************************************************************
+* AddrCIHwlInit
+*
+* @brief
+* Creates an CIAddrLib object.
+*
+* @return
+* Returns an CIAddrLib object pointer.
+***************************************************************************************************
+*/
+AddrLib* AddrCIHwlInit(const AddrClient* pClient)
+{
+ return CIAddrLib::CreateObj(pClient);
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::CIAddrLib
+*
+* @brief
+* Constructor
+*
+***************************************************************************************************
+*/
+CIAddrLib::CIAddrLib(const AddrClient* pClient) :
+ SIAddrLib(pClient),
+ m_noOfMacroEntries(0),
+ m_allowNonDispThickModes(FALSE)
+{
+ m_class = CI_ADDRLIB;
+ memset(&m_settings, 0, sizeof(m_settings));
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::~CIAddrLib
+*
+* @brief
+* Destructor
+***************************************************************************************************
+*/
+CIAddrLib::~CIAddrLib()
+{
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlComputeDccInfo
+*
+* @brief
+* Compute DCC key size, base alignment
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE CIAddrLib::HwlComputeDccInfo(
+ const ADDR_COMPUTE_DCCINFO_INPUT* pIn,
+ ADDR_COMPUTE_DCCINFO_OUTPUT* pOut) const
+{
+ ADDR_E_RETURNCODE returnCode = ADDR_OK;
+
+ if (m_settings.isVolcanicIslands && IsMacroTiled(pIn->tileMode))
+ {
+ UINT_64 dccFastClearSize = pIn->colorSurfSize >> 8;
+
+ ADDR_ASSERT(0 == (pIn->colorSurfSize & 0xff));
+
+ if (pIn->numSamples > 1)
+ {
+ UINT_32 tileSizePerSample = BITS_TO_BYTES(pIn->bpp * MicroTileWidth * MicroTileHeight);
+ UINT_32 samplesPerSplit = pIn->tileInfo.tileSplitBytes / tileSizePerSample;
+
+ if (samplesPerSplit < pIn->numSamples)
+ {
+ UINT_32 numSplits = pIn->numSamples / samplesPerSplit;
+ UINT_32 fastClearBaseAlign = HwlGetPipes(&pIn->tileInfo) * m_pipeInterleaveBytes;
+
+ ADDR_ASSERT(IsPow2(fastClearBaseAlign));
+
+ dccFastClearSize /= numSplits;
+
+ if (0 != (dccFastClearSize & (fastClearBaseAlign - 1)))
+ {
+ // Disable dcc fast clear
+ // if key size of fisrt sample split is not pipe*interleave aligned
+ dccFastClearSize = 0;
+ }
+ }
+ }
+
+ pOut->dccRamSize = pIn->colorSurfSize >> 8;
+ pOut->dccRamBaseAlign = pIn->tileInfo.banks *
+ HwlGetPipes(&pIn->tileInfo) *
+ m_pipeInterleaveBytes;
+ pOut->dccFastClearSize = dccFastClearSize;
+
+ ADDR_ASSERT(IsPow2(pOut->dccRamBaseAlign));
+
+ if (0 == (pOut->dccRamSize & (pOut->dccRamBaseAlign - 1)))
+ {
+ pOut->subLvlCompressible = TRUE;
+ }
+ else
+ {
+ UINT_64 dccRamSizeAlign = HwlGetPipes(&pIn->tileInfo) * m_pipeInterleaveBytes;
+
+ if (pOut->dccRamSize == pOut->dccFastClearSize)
+ {
+ pOut->dccFastClearSize = PowTwoAlign(pOut->dccRamSize, dccRamSizeAlign);
+ }
+ pOut->dccRamSize = PowTwoAlign(pOut->dccRamSize, dccRamSizeAlign);
+ pOut->subLvlCompressible = FALSE;
+ }
+ }
+ else
+ {
+ returnCode = ADDR_NOTSUPPORTED;
+ }
+
+ return returnCode;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlComputeCmaskAddrFromCoord
+*
+* @brief
+* Compute tc compatible Cmask address from fmask ram address
+*
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE CIAddrLib::HwlComputeCmaskAddrFromCoord(
+ const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] fmask addr/bpp/tile input
+ ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] cmask address
+ ) const
+{
+ ADDR_E_RETURNCODE returnCode = ADDR_NOTSUPPORTED;
+
+ if ((m_settings.isVolcanicIslands == TRUE) &&
+ (pIn->flags.tcCompatible == TRUE))
+ {
+ UINT_32 numOfPipes = HwlGetPipes(pIn->pTileInfo);
+ UINT_32 numOfBanks = pIn->pTileInfo->banks;
+ UINT_64 fmaskAddress = pIn->fmaskAddr;
+ UINT_32 elemBits = pIn->bpp;
+ UINT_32 blockByte = 64 * elemBits / 8;
+ UINT_64 metaNibbleAddress = HwlComputeMetadataNibbleAddress(fmaskAddress,
+ 0,
+ 0,
+ 4,
+ elemBits,
+ blockByte,
+ m_pipeInterleaveBytes,
+ numOfPipes,
+ numOfBanks,
+ 1);
+ pOut->addr = (metaNibbleAddress >> 1);
+ pOut->bitPosition = (metaNibbleAddress % 2) ? 4 : 0;
+ returnCode = ADDR_OK;
+ }
+
+ return returnCode;
+}
+/**
+***************************************************************************************************
+* CIAddrLib::HwlConvertChipFamily
+*
+* @brief
+* Convert familyID defined in atiid.h to AddrChipFamily and set m_chipFamily/m_chipRevision
+* @return
+* AddrChipFamily
+***************************************************************************************************
+*/
+AddrChipFamily CIAddrLib::HwlConvertChipFamily(
+ UINT_32 uChipFamily, ///< [in] chip family defined in atiih.h
+ UINT_32 uChipRevision) ///< [in] chip revision defined in "asic_family"_id.h
+{
+ AddrChipFamily family = ADDR_CHIP_FAMILY_CI;
+
+ switch (uChipFamily)
+ {
+ case FAMILY_CI:
+ m_settings.isSeaIsland = 1;
+ m_settings.isBonaire = ASICREV_IS_BONAIRE_M(uChipRevision);
+ m_settings.isHawaii = ASICREV_IS_HAWAII_P(uChipRevision);
+ break;
+ case FAMILY_KV:
+ m_settings.isKaveri = 1;
+ m_settings.isSpectre = ASICREV_IS_SPECTRE(uChipRevision);
+ m_settings.isSpooky = ASICREV_IS_SPOOKY(uChipRevision);
+ m_settings.isKalindi = ASICREV_IS_KALINDI(uChipRevision);
+ break;
+ case FAMILY_VI:
+ m_settings.isVolcanicIslands = 1;
+ m_settings.isIceland = ASICREV_IS_ICELAND_M(uChipRevision);
+ m_settings.isTonga = ASICREV_IS_TONGA_P(uChipRevision);
+ m_settings.isFiji = ASICREV_IS_FIJI_P(uChipRevision);
+ m_settings.isPolaris10 = ASICREV_IS_POLARIS10_P(uChipRevision);
+ m_settings.isPolaris11 = ASICREV_IS_POLARIS11_M(uChipRevision);
+ break;
+ case FAMILY_CZ:
+ m_settings.isCarrizo = 1;
+ m_settings.isVolcanicIslands = 1;
+ break;
+ default:
+ ADDR_ASSERT(!"This should be a unexpected Fusion");
+ break;
+ }
+
+ return family;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlInitGlobalParams
+*
+* @brief
+* Initializes global parameters
+*
+* @return
+* TRUE if all settings are valid
+*
+***************************************************************************************************
+*/
+BOOL_32 CIAddrLib::HwlInitGlobalParams(
+ const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input
+{
+ BOOL_32 valid = TRUE;
+
+ const ADDR_REGISTER_VALUE* pRegValue = &pCreateIn->regValue;
+
+ valid = DecodeGbRegs(pRegValue);
+
+ // The following assignments for m_pipes is only for fail-safe, InitTileSettingTable should
+ // read the correct pipes from tile mode table
+ if (m_settings.isHawaii)
+ {
+ // Hawaii has 16-pipe, see GFXIP_Config_Summary.xls
+ m_pipes = 16;
+ }
+ else if (m_settings.isBonaire || m_settings.isSpectre)
+ {
+ m_pipes = 4;
+ }
+ else // Treat other KV asics to be 2-pipe
+ {
+ m_pipes = 2;
+ }
+
+ // @todo: VI
+ // Move this to VI code path once created
+ if (m_settings.isTonga || m_settings.isPolaris10)
+ {
+ m_pipes = 8;
+ }
+ else if (m_settings.isIceland)
+ {
+ m_pipes = 2;
+ }
+ else if (m_settings.isFiji)
+ {
+ m_pipes = 16;
+ }
+ else if (m_settings.isPolaris11)
+ {
+ m_pipes = 4;
+ }
+
+ if (valid)
+ {
+ valid = InitTileSettingTable(pRegValue->pTileConfig, pRegValue->noOfEntries);
+ }
+ if (valid)
+ {
+ valid = InitMacroTileCfgTable(pRegValue->pMacroTileConfig, pRegValue->noOfMacroEntries);
+ }
+
+ return valid;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlPostCheckTileIndex
+*
+* @brief
+* Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches
+* tile mode/type/info and change the index if needed
+* @return
+* Tile index.
+***************************************************************************************************
+*/
+INT_32 CIAddrLib::HwlPostCheckTileIndex(
+ const ADDR_TILEINFO* pInfo, ///< [in] Tile Info
+ AddrTileMode mode, ///< [in] Tile mode
+ AddrTileType type, ///< [in] Tile type
+ INT curIndex ///< [in] Current index assigned in HwlSetupTileInfo
+ ) const
+{
+ INT_32 index = curIndex;
+
+ if (mode == ADDR_TM_LINEAR_GENERAL)
+ {
+ index = TileIndexLinearGeneral;
+ }
+ else
+ {
+ BOOL_32 macroTiled = IsMacroTiled(mode);
+
+ // We need to find a new index if either of them is true
+ // 1. curIndex is invalid
+ // 2. tile mode is changed
+ // 3. tile info does not match for macro tiled
+ if ((index == TileIndexInvalid) ||
+ (mode != m_tileTable[index].mode) ||
+ (macroTiled && pInfo->pipeConfig != m_tileTable[index].info.pipeConfig))
+ {
+ for (index = 0; index < static_cast<INT_32>(m_noOfEntries); index++)
+ {
+ if (macroTiled)
+ {
+ // macro tile modes need all to match
+ if ((pInfo->pipeConfig == m_tileTable[index].info.pipeConfig) &&
+ (mode == m_tileTable[index].mode) &&
+ (type == m_tileTable[index].type))
+ {
+ // tileSplitBytes stored in m_tileTable is only valid for depth entries
+ if (type == ADDR_DEPTH_SAMPLE_ORDER)
+ {
+ if (pInfo->tileSplitBytes == m_tileTable[index].info.tileSplitBytes)
+ {
+ break;
+ }
+ }
+ else // other entries are determined by other 3 fields
+ {
+ break;
+ }
+ }
+ }
+ else if (mode == ADDR_TM_LINEAR_ALIGNED)
+ {
+ // linear mode only needs tile mode to match
+ if (mode == m_tileTable[index].mode)
+ {
+ break;
+ }
+ }
+ else
+ {
+ // micro tile modes only need tile mode and tile type to match
+ if (mode == m_tileTable[index].mode &&
+ type == m_tileTable[index].type)
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ ADDR_ASSERT(index < static_cast<INT_32>(m_noOfEntries));
+
+ if (index >= static_cast<INT_32>(m_noOfEntries))
+ {
+ index = TileIndexInvalid;
+ }
+
+ return index;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlSetupTileCfg
+*
+* @brief
+* Map tile index to tile setting.
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE CIAddrLib::HwlSetupTileCfg(
+ INT_32 index, ///< [in] Tile index
+ INT_32 macroModeIndex, ///< [in] Index in macro tile mode table(CI)
+ ADDR_TILEINFO* pInfo, ///< [out] Tile Info
+ AddrTileMode* pMode, ///< [out] Tile mode
+ AddrTileType* pType ///< [out] Tile type
+ ) const
+{
+ ADDR_E_RETURNCODE returnCode = ADDR_OK;
+
+ // Global flag to control usage of tileIndex
+ if (UseTileIndex(index))
+ {
+ if (static_cast<UINT_32>(index) >= m_noOfEntries)
+ {
+ returnCode = ADDR_INVALIDPARAMS;
+ }
+ else
+ {
+ const ADDR_TILECONFIG* pCfgTable = GetTileSetting(index);
+
+ if (pInfo != NULL)
+ {
+ if (IsMacroTiled(pCfgTable->mode))
+ {
+ ADDR_ASSERT(((macroModeIndex != TileIndexInvalid)
+ && (macroModeIndex != TileIndexNoMacroIndex)));
+ // Here we used tile_bytes to replace of tile_split
+ // According info as below:
+ // "tile_split_c = MIN(ROW_SIZE, tile_split)
+ // "tile_bytes = MIN(tile_split_c, num_samples * tile_bytes_1x)
+ // when using tile_bytes replacing of tile_split, the result of
+ // alignment and others(such as slicesPerTile) are unaffected -
+ // since if tile_split_c is larger, split won't happen, otherwise
+ // (num_samples * tile_bytes_1x is larger), a correct tile_split is
+ // returned.
+ *pInfo = m_macroTileTable[macroModeIndex];
+
+ if (pCfgTable->type == ADDR_DEPTH_SAMPLE_ORDER)
+ {
+ pInfo->tileSplitBytes = pCfgTable->info.tileSplitBytes;
+ }
+ pInfo->pipeConfig = pCfgTable->info.pipeConfig;
+ }
+ else // 1D and linear modes, we return default value stored in table
+ {
+ *pInfo = pCfgTable->info;
+ }
+ }
+
+ if (pMode != NULL)
+ {
+ *pMode = pCfgTable->mode;
+ }
+
+ if (pType != NULL)
+ {
+ *pType = pCfgTable->type;
+ }
+ }
+ }
+
+ return returnCode;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlComputeSurfaceInfo
+*
+* @brief
+* Entry of ci's ComputeSurfaceInfo
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE CIAddrLib::HwlComputeSurfaceInfo(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ // If tileIndex is invalid, force macroModeIndex to be invalid, too
+ if (pIn->tileIndex == TileIndexInvalid)
+ {
+ pOut->macroModeIndex = TileIndexInvalid;
+ }
+
+ ADDR_E_RETURNCODE retCode = SIAddrLib::HwlComputeSurfaceInfo(pIn,pOut);
+
+ if (pOut->macroModeIndex == TileIndexNoMacroIndex)
+ {
+ pOut->macroModeIndex = TileIndexInvalid;
+ }
+
+ return retCode;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlFmaskSurfaceInfo
+* @brief
+* Entry of r800's ComputeFmaskInfo
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE CIAddrLib::HwlComputeFmaskInfo(
+ const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure
+ )
+{
+ ADDR_E_RETURNCODE retCode = ADDR_OK;
+
+ ADDR_TILEINFO tileInfo = {0};
+ ADDR_COMPUTE_FMASK_INFO_INPUT fmaskIn;
+ fmaskIn = *pIn;
+
+ AddrTileMode tileMode = pIn->tileMode;
+
+ // Use internal tile info if pOut does not have a valid pTileInfo
+ if (pOut->pTileInfo == NULL)
+ {
+ pOut->pTileInfo = &tileInfo;
+ }
+
+ ADDR_ASSERT(tileMode == ADDR_TM_2D_TILED_THIN1 ||
+ tileMode == ADDR_TM_3D_TILED_THIN1 ||
+ tileMode == ADDR_TM_PRT_TILED_THIN1 ||
+ tileMode == ADDR_TM_PRT_2D_TILED_THIN1 ||
+ tileMode == ADDR_TM_PRT_3D_TILED_THIN1);
+
+ ADDR_ASSERT(m_tileTable[14].mode == ADDR_TM_2D_TILED_THIN1);
+ ADDR_ASSERT(m_tileTable[15].mode == ADDR_TM_3D_TILED_THIN1);
+
+ // The only valid tile modes for fmask are 2D_THIN1 and 3D_THIN1 plus non-displayable
+ INT_32 tileIndex = tileMode == ADDR_TM_2D_TILED_THIN1 ? 14 : 15;
+ ADDR_SURFACE_FLAGS flags = {{0}};
+ flags.fmask = 1;
+
+ INT_32 macroModeIndex = TileIndexInvalid;
+
+ UINT_32 numSamples = pIn->numSamples;
+ UINT_32 numFrags = pIn->numFrags == 0 ? numSamples : pIn->numFrags;
+
+ UINT_32 bpp = QLog2(numFrags);
+
+ // EQAA needs one more bit
+ if (numSamples > numFrags)
+ {
+ bpp++;
+ }
+
+ if (bpp == 3)
+ {
+ bpp = 4;
+ }
+
+ bpp = Max(8u, bpp * numSamples);
+
+ macroModeIndex = HwlComputeMacroModeIndex(tileIndex, flags, bpp, numSamples, pOut->pTileInfo);
+
+ fmaskIn.tileIndex = tileIndex;
+ fmaskIn.pTileInfo = pOut->pTileInfo;
+ pOut->macroModeIndex = macroModeIndex;
+ pOut->tileIndex = tileIndex;
+
+ retCode = DispatchComputeFmaskInfo(&fmaskIn, pOut);
+
+ if (retCode == ADDR_OK)
+ {
+ pOut->tileIndex =
+ HwlPostCheckTileIndex(pOut->pTileInfo, pIn->tileMode, ADDR_NON_DISPLAYABLE,
+ pOut->tileIndex);
+ }
+
+ // Resets pTileInfo to NULL if the internal tile info is used
+ if (pOut->pTileInfo == &tileInfo)
+ {
+ pOut->pTileInfo = NULL;
+ }
+
+ return retCode;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlFmaskPreThunkSurfInfo
+*
+* @brief
+* Some preparation before thunking a ComputeSurfaceInfo call for Fmask
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+VOID CIAddrLib::HwlFmaskPreThunkSurfInfo(
+ const ADDR_COMPUTE_FMASK_INFO_INPUT* pFmaskIn, ///< [in] Input of fmask info
+ const ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut, ///< [in] Output of fmask info
+ ADDR_COMPUTE_SURFACE_INFO_INPUT* pSurfIn, ///< [out] Input of thunked surface info
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut ///< [out] Output of thunked surface info
+ ) const
+{
+ pSurfIn->tileIndex = pFmaskIn->tileIndex;
+ pSurfOut->macroModeIndex = pFmaskOut->macroModeIndex;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlFmaskPostThunkSurfInfo
+*
+* @brief
+* Copy hwl extra field after calling thunked ComputeSurfaceInfo
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+VOID CIAddrLib::HwlFmaskPostThunkSurfInfo(
+ const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut, ///< [in] Output of surface info
+ ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut ///< [out] Output of fmask info
+ ) const
+{
+ pFmaskOut->tileIndex = pSurfOut->tileIndex;
+ pFmaskOut->macroModeIndex = pSurfOut->macroModeIndex;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlDegradeThickTileMode
+*
+* @brief
+* Degrades valid tile mode for thick modes if needed
+*
+* @return
+* Suitable tile mode
+***************************************************************************************************
+*/
+AddrTileMode CIAddrLib::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;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlOverrideTileMode
+*
+* @brief
+* Override THICK to THIN, for specific formats on CI
+*
+* @return
+* Suitable tile mode
+*
+***************************************************************************************************
+*/
+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
+ ) const
+{
+ BOOL_32 bOverrided = FALSE;
+ AddrTileMode tileMode = *pTileMode;
+
+ // currently, all CI/VI family do not
+ // support ADDR_TM_PRT_2D_TILED_THICK,ADDR_TM_PRT_3D_TILED_THICK and
+ // ADDR_TM_PRT_2D_TILED_THIN1, ADDR_TM_PRT_3D_TILED_THIN1
+ switch (tileMode)
+ {
+ case ADDR_TM_PRT_2D_TILED_THICK:
+ case ADDR_TM_PRT_3D_TILED_THICK:
+ tileMode = ADDR_TM_PRT_TILED_THICK;
+ break;
+ case ADDR_TM_PRT_2D_TILED_THIN1:
+ case ADDR_TM_PRT_3D_TILED_THIN1:
+ tileMode = ADDR_TM_PRT_TILED_THIN1;
+ break;
+ default:
+ break;
+ }
+
+ // UBTS#404321, we do not need such overriding, as THICK+THICK entries removed from the tile-mode table
+ if (!m_settings.isBonaire)
+ {
+ UINT_32 thickness = ComputeSurfaceThickness(tileMode);
+
+ // tile_thickness = (array_mode == XTHICK) ? 8 : ((array_mode == THICK) ? 4 : 1)
+ if (thickness > 1)
+ {
+ switch (pIn->format)
+ {
+ // see //gfxip/gcB/devel/cds/src/verif/tc/models/csim/tcp.cpp
+ // tcpError("Thick micro tiling is not supported for format...
+ case ADDR_FMT_X24_8_32_FLOAT:
+ case ADDR_FMT_32_AS_8:
+ case ADDR_FMT_32_AS_8_8:
+ case ADDR_FMT_32_AS_32_32_32_32:
+
+ // packed formats
+ case ADDR_FMT_GB_GR:
+ case ADDR_FMT_BG_RG:
+ case ADDR_FMT_1_REVERSED:
+ case ADDR_FMT_1:
+ case ADDR_FMT_BC1:
+ case ADDR_FMT_BC2:
+ case ADDR_FMT_BC3:
+ case ADDR_FMT_BC4:
+ case ADDR_FMT_BC5:
+ case ADDR_FMT_BC6:
+ case ADDR_FMT_BC7:
+ switch (tileMode)
+ {
+ case ADDR_TM_1D_TILED_THICK:
+ tileMode = ADDR_TM_1D_TILED_THIN1;
+ break;
+
+ case ADDR_TM_2D_TILED_XTHICK:
+ case ADDR_TM_2D_TILED_THICK:
+ tileMode = ADDR_TM_2D_TILED_THIN1;
+ break;
+
+ case ADDR_TM_3D_TILED_XTHICK:
+ case ADDR_TM_3D_TILED_THICK:
+ tileMode = ADDR_TM_3D_TILED_THIN1;
+ break;
+
+ case ADDR_TM_PRT_TILED_THICK:
+ tileMode = ADDR_TM_PRT_TILED_THIN1;
+ break;
+
+ case ADDR_TM_PRT_2D_TILED_THICK:
+ tileMode = ADDR_TM_PRT_2D_TILED_THIN1;
+ break;
+
+ case ADDR_TM_PRT_3D_TILED_THICK:
+ tileMode = ADDR_TM_PRT_3D_TILED_THIN1;
+ break;
+
+ default:
+ break;
+
+ }
+
+ // Switch tile type from thick to thin
+ if (tileMode != *pTileMode)
+ {
+ // see tileIndex: 13-18
+ *pTileType = ADDR_NON_DISPLAYABLE;
+ }
+
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (tileMode != *pTileMode)
+ {
+ *pTileMode = tileMode;
+ bOverrided = TRUE;
+ }
+
+ return bOverrided;
+}
+
+/**
+***************************************************************************************************
+* CiAddrLib::GetPrtSwitchP4Threshold
+*
+* @brief
+* Return the threshold of switching to P4_* instead of P16_* for PRT resources
+***************************************************************************************************
+*/
+UINT_32 CIAddrLib::GetPrtSwitchP4Threshold() const
+{
+ UINT_32 threshold;
+
+ switch (m_pipes)
+ {
+ case 8:
+ threshold = 32;
+ break;
+ case 16:
+ if (m_settings.isFiji)
+ {
+ threshold = 16;
+ }
+ else if (m_settings.isHawaii)
+ {
+ threshold = 8;
+ }
+ else
+ {
+ ///@todo add for possible new ASICs.
+ ADDR_ASSERT_ALWAYS();
+ threshold = 16;
+ }
+ break;
+ default:
+ ///@todo add for possible new ASICs.
+ ADDR_ASSERT_ALWAYS();
+ threshold = 32;
+ break;
+ }
+
+ return threshold;
+}
+
+/**
+***************************************************************************************************
+* 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
+ UINT_32 pitch, ///< [in] Pitch in pixels
+ UINT_32 height, ///< [in] Height in pixels
+ UINT_32 numSamples, ///< [in] Number of samples
+ ADDR_TILEINFO* pTileInfoIn, ///< [in] Tile info input: NULL for default
+ ADDR_TILEINFO* pTileInfoOut, ///< [out] Tile info output
+ AddrTileType inTileType, ///< [in] Tile type
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] Output
+ ) const
+{
+ UINT_32 thickness = ComputeSurfaceThickness(tileMode);
+ ADDR_TILEINFO* pTileInfo = pTileInfoOut;
+ INT index = TileIndexInvalid;
+ INT macroModeIndex = TileIndexInvalid;
+
+ // Fail-safe code
+ if (!IsLinear(tileMode))
+ {
+ // Thick tile modes must use thick micro tile mode but Bonaire does not support due to
+ // old derived netlists (UBTS 404321)
+ if (thickness > 1)
+ {
+ if (m_settings.isBonaire)
+ {
+ inTileType = ADDR_NON_DISPLAYABLE;
+ }
+ else if ((m_allowNonDispThickModes == FALSE) || (inTileType != ADDR_NON_DISPLAYABLE))
+ {
+ inTileType = ADDR_THICK;
+ }
+ }
+ // 128 bpp tiling must be non-displayable.
+ // Fmask reuse color buffer's entry but bank-height field can be from another entry
+ // To simplify the logic, fmask entry should be picked from non-displayable ones
+ else if (bpp == 128 || flags.fmask)
+ {
+ inTileType = ADDR_NON_DISPLAYABLE;
+ }
+ // These two modes only have non-disp entries though they can be other micro tile modes
+ else if (tileMode == ADDR_TM_3D_TILED_THIN1 || tileMode == ADDR_TM_PRT_3D_TILED_THIN1)
+ {
+ inTileType = ADDR_NON_DISPLAYABLE;
+ }
+
+ if (flags.depth || flags.stencil)
+ {
+ inTileType = ADDR_DEPTH_SAMPLE_ORDER;
+ }
+ }
+
+ if (IsTileInfoAllZero(pTileInfo))
+ {
+ // See table entries 0-4
+ if (flags.depth || flags.stencil)
+ {
+ if (flags.depth && flags.tcCompatible)
+ {
+ // tileSize = bpp * numSamples * 8 * 8 / 8
+ UINT_32 tileSize = bpp * numSamples * 8;
+
+ // Texure readable depth surface should not be split
+ switch (tileSize)
+ {
+ case 128:
+ index = 1;
+ break;
+ case 256:
+ index = 2;
+ break;
+ case 512:
+ index = 3;
+ break;
+ default:
+ index = 4;
+ break;
+ }
+ }
+ else
+ {
+ // Depth and stencil need to use the same index, thus the pre-defined tile_split
+ // can meet the requirement to choose the same macro mode index
+ // uncompressed depth/stencil are not supported for now
+ switch (numSamples)
+ {
+ case 1:
+ index = 0;
+ break;
+ case 2:
+ case 4:
+ index = 1;
+ break;
+ case 8:
+ index = 2;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ // See table entries 5-6
+ if (inTileType == ADDR_DEPTH_SAMPLE_ORDER)
+ {
+ switch (tileMode)
+ {
+ case ADDR_TM_1D_TILED_THIN1:
+ index = 5;
+ break;
+ case ADDR_TM_PRT_TILED_THIN1:
+ index = 6;
+ break;
+ default:
+ break;
+ }
+ }
+
+ // See table entries 8-12
+ if (inTileType == ADDR_DISPLAYABLE)
+ {
+ switch (tileMode)
+ {
+ case ADDR_TM_1D_TILED_THIN1:
+ index = 9;
+ break;
+ case ADDR_TM_2D_TILED_THIN1:
+ index = 10;
+ break;
+ case ADDR_TM_PRT_TILED_THIN1:
+ index = 11;
+ break;
+ default:
+ break;
+ }
+ }
+
+ // See table entries 13-18
+ if (inTileType == ADDR_NON_DISPLAYABLE)
+ {
+ switch (tileMode)
+ {
+ case ADDR_TM_1D_TILED_THIN1:
+ index = 13;
+ break;
+ case ADDR_TM_2D_TILED_THIN1:
+ index = 14;
+ break;
+ case ADDR_TM_3D_TILED_THIN1:
+ index = 15;
+ break;
+ case ADDR_TM_PRT_TILED_THIN1:
+ index = 16;
+ break;
+ default:
+ break;
+ }
+ }
+
+ // See table entries 19-26
+ if (thickness > 1)
+ {
+ switch (tileMode)
+ {
+ case ADDR_TM_1D_TILED_THICK:
+ //special check for bonaire, for the compatablity between old KMD and new UMD for bonaire
+ index = ((inTileType == ADDR_THICK) || m_settings.isBonaire) ? 19 : 18;
+ break;
+ case ADDR_TM_2D_TILED_THICK:
+ // special check for bonaire, for the compatablity between old KMD and new UMD for bonaire
+ index = ((inTileType == ADDR_THICK) || m_settings.isBonaire) ? 20 : 24;
+ break;
+ case ADDR_TM_3D_TILED_THICK:
+ index = 21;
+ break;
+ case ADDR_TM_PRT_TILED_THICK:
+ index = 22;
+ break;
+ case ADDR_TM_2D_TILED_XTHICK:
+ index = 25;
+ break;
+ case ADDR_TM_3D_TILED_XTHICK:
+ index = 26;
+ break;
+ default:
+ break;
+ }
+ }
+
+ // See table entries 27-30
+ if (inTileType == ADDR_ROTATED)
+ {
+ switch (tileMode)
+ {
+ case ADDR_TM_1D_TILED_THIN1:
+ index = 27;
+ break;
+ case ADDR_TM_2D_TILED_THIN1:
+ index = 28;
+ break;
+ case ADDR_TM_PRT_TILED_THIN1:
+ index = 29;
+ break;
+ case ADDR_TM_PRT_2D_TILED_THIN1:
+ index = 30;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (m_pipes >= 8)
+ {
+ ADDR_ASSERT((index + 1) < static_cast<INT_32>(m_noOfEntries));
+ // Only do this when tile mode table is updated.
+ if (((tileMode == ADDR_TM_PRT_TILED_THIN1) || (tileMode == ADDR_TM_PRT_TILED_THICK)) &&
+ (m_tileTable[index+1].mode == tileMode))
+ {
+ UINT_32 bytesXSamples = bpp * numSamples / 8;
+ UINT_32 bytesXThickness = bpp * thickness / 8;
+ UINT_32 switchP4Threshold = GetPrtSwitchP4Threshold();
+
+ if ((bytesXSamples > switchP4Threshold) || (bytesXThickness > switchP4Threshold))
+ {
+ // Pick next 4 pipe entry
+ index += 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ // A pre-filled tile info is ready
+ index = pOut->tileIndex;
+ macroModeIndex = pOut->macroModeIndex;
+
+ // pass tile type back for post tile index compute
+ pOut->tileType = inTileType;
+ }
+
+ // We only need to set up tile info if there is a valid index but macroModeIndex is invalid
+ if (index != TileIndexInvalid && macroModeIndex == TileIndexInvalid)
+ {
+ macroModeIndex = HwlComputeMacroModeIndex(index, flags, bpp, numSamples, pTileInfo);
+
+ /// Copy to pOut->tileType/tileIndex/macroModeIndex
+ pOut->tileIndex = index;
+ pOut->tileType = m_tileTable[index].type; // Or inTileType, the samea
+ pOut->macroModeIndex = macroModeIndex;
+ }
+ else if (tileMode == ADDR_TM_LINEAR_GENERAL)
+ {
+ pOut->tileIndex = TileIndexLinearGeneral;
+
+ // Copy linear-aligned entry??
+ *pTileInfo = m_tileTable[8].info;
+ }
+ else if (tileMode == ADDR_TM_LINEAR_ALIGNED)
+ {
+ pOut->tileIndex = 8;
+ *pTileInfo = m_tileTable[8].info;
+ }
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::ReadGbTileMode
+*
+* @brief
+* Convert GB_TILE_MODE HW value to ADDR_TILE_CONFIG.
+* @return
+* NA.
+***************************************************************************************************
+*/
+VOID CIAddrLib::ReadGbTileMode(
+ UINT_32 regValue, ///< [in] GB_TILE_MODE register
+ ADDR_TILECONFIG* pCfg ///< [out] output structure
+ ) const
+{
+ GB_TILE_MODE gbTileMode;
+ gbTileMode.val = regValue;
+
+ pCfg->type = static_cast<AddrTileType>(gbTileMode.f.micro_tile_mode_new);
+ pCfg->info.pipeConfig = static_cast<AddrPipeCfg>(gbTileMode.f.pipe_config + 1);
+
+ if (pCfg->type == ADDR_DEPTH_SAMPLE_ORDER)
+ {
+ pCfg->info.tileSplitBytes = 64 << gbTileMode.f.tile_split;
+ }
+ else
+ {
+ pCfg->info.tileSplitBytes = 1 << gbTileMode.f.sample_split;
+ }
+
+ UINT_32 regArrayMode = gbTileMode.f.array_mode;
+
+ pCfg->mode = static_cast<AddrTileMode>(regArrayMode);
+
+ switch (regArrayMode)
+ {
+ case 5:
+ pCfg->mode = ADDR_TM_PRT_TILED_THIN1;
+ break;
+ case 6:
+ pCfg->mode = ADDR_TM_PRT_2D_TILED_THIN1;
+ break;
+ case 8:
+ pCfg->mode = ADDR_TM_2D_TILED_XTHICK;
+ break;
+ case 9:
+ pCfg->mode = ADDR_TM_PRT_TILED_THICK;
+ break;
+ case 0xa:
+ pCfg->mode = ADDR_TM_PRT_2D_TILED_THICK;
+ break;
+ case 0xb:
+ pCfg->mode = ADDR_TM_PRT_3D_TILED_THIN1;
+ break;
+ case 0xe:
+ pCfg->mode = ADDR_TM_3D_TILED_XTHICK;
+ break;
+ case 0xf:
+ pCfg->mode = ADDR_TM_PRT_3D_TILED_THICK;
+ break;
+ default:
+ break;
+ }
+
+ // Fail-safe code for these always convert tile info, as the non-macro modes
+ // return the entry of tile mode table directly without looking up macro mode table
+ if (!IsMacroTiled(pCfg->mode))
+ {
+ pCfg->info.banks = 2;
+ pCfg->info.bankWidth = 1;
+ pCfg->info.bankHeight = 1;
+ pCfg->info.macroAspectRatio = 1;
+ pCfg->info.tileSplitBytes = 64;
+ }
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::InitTileSettingTable
+*
+* @brief
+* Initialize the ADDR_TILE_CONFIG table.
+* @return
+* TRUE if tile table is correctly initialized
+***************************************************************************************************
+*/
+BOOL_32 CIAddrLib::InitTileSettingTable(
+ const UINT_32* pCfg, ///< [in] Pointer to table of tile configs
+ UINT_32 noOfEntries ///< [in] Numbe of entries in the table above
+ )
+{
+ BOOL_32 initOk = TRUE;
+
+ ADDR_ASSERT(noOfEntries <= TileTableSize);
+
+ memset(m_tileTable, 0, sizeof(m_tileTable));
+
+ if (noOfEntries != 0)
+ {
+ m_noOfEntries = noOfEntries;
+ }
+ else
+ {
+ m_noOfEntries = TileTableSize;
+ }
+
+ if (pCfg) // From Client
+ {
+ for (UINT_32 i = 0; i < m_noOfEntries; i++)
+ {
+ ReadGbTileMode(*(pCfg + i), &m_tileTable[i]);
+ }
+ }
+ else
+ {
+ ADDR_ASSERT_ALWAYS();
+ initOk = FALSE;
+ }
+
+ if (initOk)
+ {
+ ADDR_ASSERT(m_tileTable[TILEINDEX_LINEAR_ALIGNED].mode == ADDR_TM_LINEAR_ALIGNED);
+
+ if (m_settings.isBonaire == FALSE)
+ {
+ // Check if entry 18 is "thick+thin" combination
+ if ((m_tileTable[18].mode == ADDR_TM_1D_TILED_THICK) &&
+ (m_tileTable[18].type == ADDR_NON_DISPLAYABLE))
+ {
+ m_allowNonDispThickModes = TRUE;
+ ADDR_ASSERT(m_tileTable[24].mode == ADDR_TM_2D_TILED_THICK);
+ }
+ }
+ else
+ {
+ m_allowNonDispThickModes = TRUE;
+ }
+
+ // Assume the first entry is always programmed with full pipes
+ m_pipes = HwlGetPipes(&m_tileTable[0].info);
+ }
+
+ return initOk;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::ReadGbMacroTileCfg
+*
+* @brief
+* Convert GB_MACRO_TILE_CFG HW value to ADDR_TILE_CONFIG.
+* @return
+* NA.
+***************************************************************************************************
+*/
+VOID CIAddrLib::ReadGbMacroTileCfg(
+ UINT_32 regValue, ///< [in] GB_MACRO_TILE_MODE register
+ ADDR_TILEINFO* pCfg ///< [out] output structure
+ ) const
+{
+ GB_MACROTILE_MODE gbTileMode;
+ gbTileMode.val = regValue;
+
+ pCfg->bankHeight = 1 << gbTileMode.f.bank_height;
+ pCfg->bankWidth = 1 << gbTileMode.f.bank_width;
+ pCfg->banks = 1 << (gbTileMode.f.num_banks + 1);
+ pCfg->macroAspectRatio = 1 << gbTileMode.f.macro_tile_aspect;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::InitMacroTileCfgTable
+*
+* @brief
+* Initialize the ADDR_MACRO_TILE_CONFIG table.
+* @return
+* TRUE if macro tile table is correctly initialized
+***************************************************************************************************
+*/
+BOOL_32 CIAddrLib::InitMacroTileCfgTable(
+ const UINT_32* pCfg, ///< [in] Pointer to table of tile configs
+ UINT_32 noOfMacroEntries ///< [in] Numbe of entries in the table above
+ )
+{
+ BOOL_32 initOk = TRUE;
+
+ ADDR_ASSERT(noOfMacroEntries <= MacroTileTableSize);
+
+ memset(m_macroTileTable, 0, sizeof(m_macroTileTable));
+
+ if (noOfMacroEntries != 0)
+ {
+ m_noOfMacroEntries = noOfMacroEntries;
+ }
+ else
+ {
+ m_noOfMacroEntries = MacroTileTableSize;
+ }
+
+ if (pCfg) // From Client
+ {
+ for (UINT_32 i = 0; i < m_noOfMacroEntries; i++)
+ {
+ ReadGbMacroTileCfg(*(pCfg + i), &m_macroTileTable[i]);
+
+ m_macroTileTable[i].tileSplitBytes = 64 << (i % 8);
+ }
+ }
+ else
+ {
+ ADDR_ASSERT_ALWAYS();
+ initOk = FALSE;
+ }
+ return initOk;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlComputeMacroModeIndex
+*
+* @brief
+* Computes macro tile mode index
+* @return
+* TRUE if macro tile table is correctly initialized
+***************************************************************************************************
+*/
+INT_32 CIAddrLib::HwlComputeMacroModeIndex(
+ INT_32 tileIndex, ///< [in] Tile mode index
+ ADDR_SURFACE_FLAGS flags, ///< [in] Surface flags
+ UINT_32 bpp, ///< [in] Bit per pixel
+ UINT_32 numSamples, ///< [in] Number of samples
+ ADDR_TILEINFO* pTileInfo, ///< [out] Pointer to ADDR_TILEINFO
+ AddrTileMode* pTileMode, ///< [out] Pointer to AddrTileMode
+ AddrTileType* pTileType ///< [out] Pointer to AddrTileType
+ ) const
+{
+ INT_32 macroModeIndex = TileIndexInvalid;
+
+ if (flags.tcCompatible && flags.stencil)
+ {
+ // Don't compute macroModeIndex for tc compatible stencil surface
+ macroModeIndex = TileIndexNoMacroIndex;
+ }
+ else
+ {
+ AddrTileMode tileMode = m_tileTable[tileIndex].mode;
+ AddrTileType tileType = m_tileTable[tileIndex].type;
+ UINT_32 thickness = ComputeSurfaceThickness(tileMode);
+
+ if (!IsMacroTiled(tileMode))
+ {
+ *pTileInfo = m_tileTable[tileIndex].info;
+ macroModeIndex = TileIndexNoMacroIndex;
+ }
+ else
+ {
+ UINT_32 tileBytes1x = BITS_TO_BYTES(bpp * MicroTilePixels * thickness);
+ UINT_32 tileSplit;
+
+ if (m_tileTable[tileIndex].type == ADDR_DEPTH_SAMPLE_ORDER)
+ {
+ // Depth entries store real tileSplitBytes
+ tileSplit = m_tileTable[tileIndex].info.tileSplitBytes;
+ }
+ else
+ {
+ // Non-depth entries store a split factor
+ UINT_32 sampleSplit = m_tileTable[tileIndex].info.tileSplitBytes;
+ UINT_32 colorTileSplit = Max(256u, sampleSplit * tileBytes1x);
+
+ tileSplit = colorTileSplit;
+ }
+
+ UINT_32 tileSplitC = Min(m_rowSize, tileSplit);
+ UINT_32 tileBytes;
+
+ if (flags.fmask)
+ {
+ tileBytes = Min(tileSplitC, tileBytes1x);
+ }
+ else
+ {
+ tileBytes = Min(tileSplitC, numSamples * tileBytes1x);
+ }
+
+ if (tileBytes < 64)
+ {
+ tileBytes = 64;
+ }
+
+ macroModeIndex = Log2(tileBytes / 64);
+
+ if (flags.prt || IsPrtTileMode(tileMode))
+ {
+ // Unknown - assume it is 1/2 of table size
+ const UINT_32 PrtMacroModeOffset = MacroTileTableSize / 2;
+
+ macroModeIndex += PrtMacroModeOffset;
+ *pTileInfo = m_macroTileTable[macroModeIndex];
+ }
+ else
+ {
+ *pTileInfo = m_macroTileTable[macroModeIndex];
+ }
+
+ pTileInfo->pipeConfig = m_tileTable[tileIndex].info.pipeConfig;
+
+ if (m_tileTable[tileIndex].type != ADDR_DEPTH_SAMPLE_ORDER)
+ {
+ pTileInfo->tileSplitBytes = tileSplitC;
+ }
+ else
+ {
+ pTileInfo->tileSplitBytes = m_tileTable[tileIndex].info.tileSplitBytes;
+ }
+ }
+
+ if (NULL != pTileMode)
+ {
+ *pTileMode = tileMode;
+ }
+
+ if (NULL != pTileType)
+ {
+ *pTileType = tileType;
+ }
+ }
+
+ return macroModeIndex;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlComputeTileDataWidthAndHeightLinear
+*
+* @brief
+* Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
+*
+* @return
+* N/A
+*
+* @note
+* MacroWidth and macroHeight are measured in pixels
+***************************************************************************************************
+*/
+VOID CIAddrLib::HwlComputeTileDataWidthAndHeightLinear(
+ UINT_32* pMacroWidth, ///< [out] macro tile width
+ UINT_32* pMacroHeight, ///< [out] macro tile height
+ UINT_32 bpp, ///< [in] bits per pixel
+ ADDR_TILEINFO* pTileInfo ///< [in] tile info
+ ) const
+{
+ ADDR_ASSERT(pTileInfo != NULL);
+
+ UINT_32 numTiles;
+
+ switch (pTileInfo->pipeConfig)
+ {
+ case ADDR_PIPECFG_P16_32x32_8x16:
+ case ADDR_PIPECFG_P16_32x32_16x16:
+ case ADDR_PIPECFG_P8_32x64_32x32:
+ case ADDR_PIPECFG_P8_32x32_16x32:
+ case ADDR_PIPECFG_P8_32x32_16x16:
+ case ADDR_PIPECFG_P8_32x32_8x16:
+ case ADDR_PIPECFG_P4_32x32:
+ numTiles = 8;
+ break;
+ default:
+ numTiles = 4;
+ break;
+ }
+
+ *pMacroWidth = numTiles * MicroTileWidth;
+ *pMacroHeight = numTiles * MicroTileHeight;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlStereoCheckRightOffsetPadding
+*
+* @brief
+* check if the height needs extra padding for stereo right eye offset, to avoid swizzling
+*
+* @return
+* TRUE is the extra padding is needed
+*
+* @note
+* Kalindi (Kabini) is the only one that needs this padding as there is a uncertain
+* possible HW issue where the right eye displays incorrectly with some type of swizzles, if
+* the right eye offset is not 64KB aligned - EPR#366461
+* Other Kaveri APUs also need the padding according to DXX team's report otherwise
+* corruption observed. - EPR#374788
+***************************************************************************************************
+*/
+BOOL_32 CIAddrLib::HwlStereoCheckRightOffsetPadding() const
+{
+ BOOL_32 bNeedPadding = FALSE;
+
+ if (m_settings.isKaveri)
+ {
+ bNeedPadding = TRUE;
+ }
+
+ return bNeedPadding;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlComputeMetadataNibbleAddress
+*
+* @brief
+* calculate meta data address based on input information
+*
+* &parameter
+* uncompressedDataByteAddress - address of a pixel in color surface
+* dataBaseByteAddress - base address of color surface
+* metadataBaseByteAddress - base address of meta ram
+* metadataBitSize - meta key size, 8 for DCC, 4 for cmask
+* elementBitSize - element size of color surface
+* blockByteSize - compression block size, 256 for DCC
+* pipeInterleaveBytes - pipe interleave size
+* numOfPipes - number of pipes
+* numOfBanks - number of banks
+* numOfSamplesPerSplit - number of samples per tile split
+* @return
+* meta data nibble address (nibble address is used to support DCC compatible cmask)
+*
+***************************************************************************************************
+*/
+UINT_64 CIAddrLib::HwlComputeMetadataNibbleAddress(
+ UINT_64 uncompressedDataByteAddress,
+ UINT_64 dataBaseByteAddress,
+ UINT_64 metadataBaseByteAddress,
+ UINT_32 metadataBitSize,
+ UINT_32 elementBitSize,
+ UINT_32 blockByteSize,
+ UINT_32 pipeInterleaveBytes,
+ UINT_32 numOfPipes,
+ UINT_32 numOfBanks,
+ UINT_32 numOfSamplesPerSplit) const
+{
+ ///--------------------------------------------------------------------------------------------
+ /// Get pipe interleave, bank and pipe bits
+ ///--------------------------------------------------------------------------------------------
+ UINT_32 pipeInterleaveBits = Log2(pipeInterleaveBytes);
+ UINT_32 pipeBits = Log2(numOfPipes);
+ UINT_32 bankBits = Log2(numOfBanks);
+
+ ///--------------------------------------------------------------------------------------------
+ /// Clear pipe and bank swizzles
+ ///--------------------------------------------------------------------------------------------
+ UINT_32 dataMacrotileBits = pipeInterleaveBits + pipeBits + bankBits;
+ UINT_32 metadataMacrotileBits = pipeInterleaveBits + pipeBits + bankBits;
+
+ UINT_64 dataMacrotileClearMask = ~((1L << dataMacrotileBits) - 1);
+ UINT_64 metadataMacrotileClearMask = ~((1L << metadataMacrotileBits) - 1);
+
+ UINT_64 dataBaseByteAddressNoSwizzle = dataBaseByteAddress & dataMacrotileClearMask;
+ UINT_64 metadataBaseByteAddressNoSwizzle = metadataBaseByteAddress & metadataMacrotileClearMask;
+
+ ///--------------------------------------------------------------------------------------------
+ /// Modify metadata base before adding in so that when final address is divided by data ratio,
+ /// the base address returns to where it should be
+ ///--------------------------------------------------------------------------------------------
+ ADDR_ASSERT((0 != metadataBitSize));
+ UINT_64 metadataBaseShifted = metadataBaseByteAddressNoSwizzle * blockByteSize * 8 /
+ metadataBitSize;
+ UINT_64 offset = uncompressedDataByteAddress -
+ dataBaseByteAddressNoSwizzle +
+ metadataBaseShifted;
+
+ ///--------------------------------------------------------------------------------------------
+ /// Save bank data bits
+ ///--------------------------------------------------------------------------------------------
+ UINT_32 lsb = pipeBits + pipeInterleaveBits;
+ UINT_32 msb = bankBits - 1 + lsb;
+
+ UINT_64 bankDataBits = AddrGetBits(offset, msb, lsb);
+
+ ///--------------------------------------------------------------------------------------------
+ /// Save pipe data bits
+ ///--------------------------------------------------------------------------------------------
+ lsb = pipeInterleaveBits;
+ msb = pipeBits - 1 + lsb;
+
+ UINT_64 pipeDataBits = AddrGetBits(offset, msb, lsb);
+
+ ///--------------------------------------------------------------------------------------------
+ /// Remove pipe and bank bits
+ ///--------------------------------------------------------------------------------------------
+ lsb = pipeInterleaveBits;
+ msb = dataMacrotileBits - 1;
+
+ UINT_64 offsetWithoutPipeBankBits = AddrRemoveBits(offset, msb, lsb);
+
+ ADDR_ASSERT((0 != blockByteSize));
+ UINT_64 blockInBankpipe = offsetWithoutPipeBankBits / blockByteSize;
+
+ UINT_32 tileSize = 8 * 8 * elementBitSize/8 * numOfSamplesPerSplit;
+ UINT_32 blocksInTile = tileSize / blockByteSize;
+
+ if (0 == blocksInTile)
+ {
+ lsb = 0;
+ }
+ else
+ {
+ lsb = Log2(blocksInTile);
+ }
+ msb = bankBits - 1 + lsb;
+
+ UINT_64 blockInBankpipeWithBankBits = AddrInsertBits(blockInBankpipe, bankDataBits, msb, lsb);
+
+ /// NOTE *2 because we are converting to Nibble address in this step
+ UINT_64 metaAddressInPipe = blockInBankpipeWithBankBits * 2 * metadataBitSize / 8;
+
+
+ ///--------------------------------------------------------------------------------------------
+ /// Reinsert pipe bits back into the final address
+ ///--------------------------------------------------------------------------------------------
+ lsb = pipeInterleaveBits + 1; ///<+1 due to Nibble address now gives interleave bits extra lsb.
+ msb = pipeBits - 1 + lsb;
+ UINT_64 metadataAddress = AddrInsertBits(metaAddressInPipe, pipeDataBits, msb, lsb);
+
+ return metadataAddress;
+}
+
+/**
+***************************************************************************************************
+* CIAddrLib::HwlPadDimensions
+*
+* @brief
+* Helper function to pad dimensions
+*
+* @return
+* N/A
+*
+***************************************************************************************************
+*/
+VOID CIAddrLib::HwlPadDimensions(
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 bpp, ///< [in] bits per pixel
+ ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
+ UINT_32 numSamples, ///< [in] number of samples
+ ADDR_TILEINFO* pTileInfo, ///< [in/out] bank structure.
+ UINT_32 padDims, ///< [in] Dimensions to pad valid value 1,2,3
+ UINT_32 mipLevel, ///< [in] MipLevel
+ UINT_32* pPitch, ///< [in/out] pitch in pixels
+ UINT_32 pitchAlign, ///< [in] pitch alignment
+ UINT_32* pHeight, ///< [in/out] height in pixels
+ UINT_32 heightAlign, ///< [in] height alignment
+ UINT_32* pSlices, ///< [in/out] number of slices
+ UINT_32 sliceAlign ///< [in] number of slice alignment
+ ) const
+{
+ if (m_settings.isVolcanicIslands &&
+ flags.dccCompatible &&
+ (numSamples > 1) &&
+ (mipLevel == 0) &&
+ IsMacroTiled(tileMode))
+ {
+ UINT_32 tileSizePerSample = BITS_TO_BYTES(bpp * MicroTileWidth * MicroTileHeight);
+ UINT_32 samplesPerSplit = pTileInfo->tileSplitBytes / tileSizePerSample;
+
+ if (samplesPerSplit < numSamples)
+ {
+ UINT_32 dccFastClearByteAlign = HwlGetPipes(pTileInfo) * m_pipeInterleaveBytes * 256;
+ UINT_32 bytesPerSplit = BITS_TO_BYTES((*pPitch) * (*pHeight) * bpp * samplesPerSplit);
+
+ ADDR_ASSERT(IsPow2(dccFastClearByteAlign));
+
+ if (0 != (bytesPerSplit & (dccFastClearByteAlign - 1)))
+ {
+ UINT_32 dccFastClearPixelAlign = dccFastClearByteAlign /
+ BITS_TO_BYTES(bpp) /
+ samplesPerSplit;
+ UINT_32 macroTilePixelAlign = pitchAlign * heightAlign;
+
+ if ((dccFastClearPixelAlign >= macroTilePixelAlign) &&
+ ((dccFastClearPixelAlign % macroTilePixelAlign) == 0))
+ {
+ UINT_32 dccFastClearPitchAlignInMacroTile =
+ dccFastClearPixelAlign / macroTilePixelAlign;
+ UINT_32 heightInMacroTile = *pHeight / heightAlign;
+ UINT_32 dccFastClearPitchAlignInPixels;
+
+ while ((heightInMacroTile > 1) &&
+ ((heightInMacroTile % 2) == 0) &&
+ (dccFastClearPitchAlignInMacroTile > 1) &&
+ ((dccFastClearPitchAlignInMacroTile % 2) == 0))
+ {
+ heightInMacroTile >>= 1;
+ dccFastClearPitchAlignInMacroTile >>= 1;
+ }
+
+ dccFastClearPitchAlignInPixels = pitchAlign * dccFastClearPitchAlignInMacroTile;
+
+ if (IsPow2(dccFastClearPitchAlignInPixels))
+ {
+ *pPitch = PowTwoAlign((*pPitch), dccFastClearPitchAlignInPixels);
+ }
+ else
+ {
+ *pPitch += (dccFastClearPitchAlignInPixels - 1);
+ *pPitch /= dccFastClearPitchAlignInPixels;
+ *pPitch *= dccFastClearPitchAlignInPixels;
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/amd/addrlib/r800/ciaddrlib.h b/src/amd/addrlib/r800/ciaddrlib.h
new file mode 100644
index 00000000000..de995fa4058
--- /dev/null
+++ b/src/amd/addrlib/r800/ciaddrlib.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright © 2014 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+
+/**
+***************************************************************************************************
+* @file ciaddrlib.h
+* @brief Contains the CIAddrLib class definition.
+***************************************************************************************************
+*/
+
+#ifndef __CI_ADDR_LIB_H__
+#define __CI_ADDR_LIB_H__
+
+#include "addrlib.h"
+#include "siaddrlib.h"
+
+/**
+***************************************************************************************************
+* @brief CI specific settings structure.
+***************************************************************************************************
+*/
+struct CIChipSettings
+{
+ struct
+ {
+ UINT_32 isSeaIsland : 1;
+ UINT_32 isBonaire : 1;
+ UINT_32 isKaveri : 1;
+ UINT_32 isSpectre : 1;
+ UINT_32 isSpooky : 1;
+ UINT_32 isKalindi : 1;
+ // Hawaii is GFXIP 7.2, similar with CI (Bonaire)
+ UINT_32 isHawaii : 1;
+
+ // VI
+ UINT_32 isVolcanicIslands : 1;
+ UINT_32 isIceland : 1;
+ UINT_32 isTonga : 1;
+ UINT_32 isFiji : 1;
+ UINT_32 isPolaris10 : 1;
+ UINT_32 isPolaris11 : 1;
+ // VI fusion (Carrizo)
+ UINT_32 isCarrizo : 1;
+ };
+};
+
+/**
+***************************************************************************************************
+* @brief This class is the CI specific address library
+* function set.
+***************************************************************************************************
+*/
+class CIAddrLib : public SIAddrLib
+{
+public:
+ /// Creates CIAddrLib object
+ static AddrLib* CreateObj(const AddrClient* pClient)
+ {
+ return new(pClient) CIAddrLib(pClient);
+ }
+
+private:
+ CIAddrLib(const AddrClient* pClient);
+ virtual ~CIAddrLib();
+
+protected:
+
+ // Hwl interface - defined in AddrLib
+ virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfo(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;
+
+ virtual ADDR_E_RETURNCODE HwlComputeFmaskInfo(
+ const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn,
+ ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut);
+
+ virtual AddrChipFamily HwlConvertChipFamily(
+ UINT_32 uChipFamily, UINT_32 uChipRevision);
+
+ virtual BOOL_32 HwlInitGlobalParams(
+ const ADDR_CREATE_INPUT* pCreateIn);
+
+ virtual ADDR_E_RETURNCODE HwlSetupTileCfg(
+ INT_32 index, INT_32 macroModeIndex, ADDR_TILEINFO* pInfo,
+ AddrTileMode* pMode = 0, AddrTileType* pType = 0) const;
+
+ virtual VOID HwlComputeTileDataWidthAndHeightLinear(
+ UINT_32* pMacroWidth, UINT_32* pMacroHeight,
+ UINT_32 bpp, ADDR_TILEINFO* pTileInfo) const;
+
+ virtual INT_32 HwlComputeMacroModeIndex(
+ INT_32 tileIndex, ADDR_SURFACE_FLAGS flags, UINT_32 bpp, UINT_32 numSamples,
+ ADDR_TILEINFO* pTileInfo, AddrTileMode* pTileMode = NULL, AddrTileType* pTileType = NULL
+ ) const;
+
+ // Sub-hwl interface - defined in EgBasedAddrLib
+ virtual VOID HwlSetupTileInfo(
+ AddrTileMode tileMode, ADDR_SURFACE_FLAGS flags,
+ UINT_32 bpp, UINT_32 pitch, UINT_32 height, UINT_32 numSamples,
+ ADDR_TILEINFO* inputTileInfo, ADDR_TILEINFO* outputTileInfo,
+ AddrTileType inTileType, ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;
+
+ virtual INT_32 HwlPostCheckTileIndex(
+ const ADDR_TILEINFO* pInfo, AddrTileMode mode, AddrTileType type,
+ INT curIndex = TileIndexInvalid) const;
+
+ virtual VOID HwlFmaskPreThunkSurfInfo(
+ const ADDR_COMPUTE_FMASK_INFO_INPUT* pFmaskIn,
+ const ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut,
+ ADDR_COMPUTE_SURFACE_INFO_INPUT* pSurfIn,
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut) const;
+
+ 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 BOOL_32 HwlOverrideTileMode(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,
+ AddrTileMode* pTileMode,
+ AddrTileType* pTileType) const;
+
+ virtual BOOL_32 HwlStereoCheckRightOffsetPadding() 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;
+
+protected:
+ virtual VOID HwlPadDimensions(
+ 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;
+
+private:
+ VOID ReadGbTileMode(
+ UINT_32 regValue, ADDR_TILECONFIG* pCfg) const;
+
+ VOID ReadGbMacroTileCfg(
+ UINT_32 regValue, ADDR_TILEINFO* pCfg) const;
+
+ UINT_32 GetPrtSwitchP4Threshold() const;
+
+ BOOL_32 InitTileSettingTable(
+ const UINT_32 *pSetting, UINT_32 noOfEntries);
+
+ BOOL_32 InitMacroTileCfgTable(
+ const UINT_32 *pSetting, UINT_32 noOfEntries);
+
+ UINT_64 HwlComputeMetadataNibbleAddress(
+ UINT_64 uncompressedDataByteAddress,
+ UINT_64 dataBaseByteAddress,
+ UINT_64 metadataBaseByteAddress,
+ UINT_32 metadataBitSize,
+ UINT_32 elementBitSize,
+ UINT_32 blockByteSize,
+ UINT_32 pipeInterleaveBytes,
+ UINT_32 numOfPipes,
+ UINT_32 numOfBanks,
+ UINT_32 numOfSamplesPerSplit) const;
+
+ static const UINT_32 MacroTileTableSize = 16;
+ ADDR_TILEINFO m_macroTileTable[MacroTileTableSize];
+ UINT_32 m_noOfMacroEntries;
+ BOOL_32 m_allowNonDispThickModes;
+
+ CIChipSettings m_settings;
+};
+
+#endif
+
+
diff --git a/src/amd/addrlib/r800/egbaddrlib.cpp b/src/amd/addrlib/r800/egbaddrlib.cpp
new file mode 100644
index 00000000000..e53479839e1
--- /dev/null
+++ b/src/amd/addrlib/r800/egbaddrlib.cpp
@@ -0,0 +1,4577 @@
+/*
+ * Copyright © 2014 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+
+/**
+***************************************************************************************************
+* @file egbaddrlib.cpp
+* @brief Contains the EgBasedAddrLib class implementation
+***************************************************************************************************
+*/
+
+#include "egbaddrlib.h"
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::EgBasedAddrLib
+*
+* @brief
+* Constructor
+*
+* @note
+*
+***************************************************************************************************
+*/
+EgBasedAddrLib::EgBasedAddrLib(const AddrClient* pClient) :
+ AddrLib(pClient),
+ m_ranks(0),
+ m_logicalBanks(0),
+ m_bankInterleave(1)
+{
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::~EgBasedAddrLib
+*
+* @brief
+* Destructor
+***************************************************************************************************
+*/
+EgBasedAddrLib::~EgBasedAddrLib()
+{
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::DispatchComputeSurfaceInfo
+*
+* @brief
+* Compute surface sizes include padded pitch,height,slices,total size in bytes,
+* meanwhile output suitable tile mode and base alignment might be changed in this
+* call as well. Results are returned through output parameters.
+*
+* @return
+* TRUE if no error occurs
+***************************************************************************************************
+*/
+BOOL_32 EgBasedAddrLib::DispatchComputeSurfaceInfo(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ AddrTileMode tileMode = pIn->tileMode;
+ UINT_32 bpp = pIn->bpp;
+ UINT_32 numSamples = pIn->numSamples;
+ UINT_32 numFrags = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
+ UINT_32 pitch = pIn->width;
+ UINT_32 height = pIn->height;
+ UINT_32 numSlices = pIn->numSlices;
+ UINT_32 mipLevel = pIn->mipLevel;
+ ADDR_SURFACE_FLAGS flags = pIn->flags;
+
+ ADDR_TILEINFO tileInfoDef = {0};
+ ADDR_TILEINFO* pTileInfo = &tileInfoDef;
+
+ UINT_32 padDims = 0;
+ BOOL_32 valid;
+
+ tileMode = DegradeLargeThickTile(tileMode, bpp);
+
+ // Only override numSamples for NI above
+ if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
+ {
+ if (numFrags != numSamples) // This means EQAA
+ {
+ // The real surface size needed is determined by number of fragments
+ numSamples = numFrags;
+ }
+
+ // Save altered numSamples in pOut
+ pOut->numSamples = numSamples;
+ }
+
+ // Caller makes sure pOut->pTileInfo is not NULL, see HwlComputeSurfaceInfo
+ ADDR_ASSERT(pOut->pTileInfo);
+
+ if (pOut->pTileInfo != NULL)
+ {
+ pTileInfo = pOut->pTileInfo;
+ }
+
+ // Set default values
+ if (pIn->pTileInfo != NULL)
+ {
+ if (pTileInfo != pIn->pTileInfo)
+ {
+ *pTileInfo = *pIn->pTileInfo;
+ }
+ }
+ else
+ {
+ memset(pTileInfo, 0, sizeof(ADDR_TILEINFO));
+ }
+
+ // For macro tile mode, we should calculate default tiling parameters
+ HwlSetupTileInfo(tileMode,
+ flags,
+ bpp,
+ pitch,
+ height,
+ numSamples,
+ pIn->pTileInfo,
+ pTileInfo,
+ pIn->tileType,
+ pOut);
+
+ if (flags.cube)
+ {
+ if (mipLevel == 0)
+ {
+ padDims = 2;
+ }
+
+ if (numSlices == 1)
+ {
+ // This is calculating one face, remove cube flag
+ flags.cube = 0;
+ }
+ }
+
+ switch (tileMode)
+ {
+ case ADDR_TM_LINEAR_GENERAL://fall through
+ case ADDR_TM_LINEAR_ALIGNED:
+ valid = ComputeSurfaceInfoLinear(pIn, pOut, padDims);
+ break;
+
+ case ADDR_TM_1D_TILED_THIN1://fall through
+ case ADDR_TM_1D_TILED_THICK:
+ valid = ComputeSurfaceInfoMicroTiled(pIn, pOut, padDims, tileMode);
+ break;
+
+ case ADDR_TM_2D_TILED_THIN1: //fall through
+ case ADDR_TM_2D_TILED_THICK: //fall through
+ case ADDR_TM_3D_TILED_THIN1: //fall through
+ case ADDR_TM_3D_TILED_THICK: //fall through
+ case ADDR_TM_2D_TILED_XTHICK: //fall through
+ case ADDR_TM_3D_TILED_XTHICK: //fall through
+ case ADDR_TM_PRT_TILED_THIN1: //fall through
+ case ADDR_TM_PRT_2D_TILED_THIN1://fall through
+ case ADDR_TM_PRT_3D_TILED_THIN1://fall through
+ case ADDR_TM_PRT_TILED_THICK: //fall through
+ case ADDR_TM_PRT_2D_TILED_THICK://fall through
+ case ADDR_TM_PRT_3D_TILED_THICK:
+ valid = ComputeSurfaceInfoMacroTiled(pIn, pOut, padDims, tileMode);
+ break;
+
+ default:
+ valid = FALSE;
+ ADDR_ASSERT_ALWAYS();
+ break;
+ }
+
+ return valid;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeSurfaceInfoLinear
+*
+* @brief
+* Compute linear surface sizes include padded pitch, height, slices, total size in
+* bytes, meanwhile alignments as well. Since it is linear mode, so output tile mode
+* will not be changed here. Results are returned through output parameters.
+*
+* @return
+* TRUE if no error occurs
+***************************************************************************************************
+*/
+BOOL_32 EgBasedAddrLib::ComputeSurfaceInfoLinear(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut, ///< [out] Output structure
+ UINT_32 padDims ///< [in] Dimensions to padd
+ ) const
+{
+ UINT_32 expPitch = pIn->width;
+ UINT_32 expHeight = pIn->height;
+ UINT_32 expNumSlices = pIn->numSlices;
+
+ // No linear MSAA on real H/W, keep this for TGL
+ UINT_32 numSamples = pOut->numSamples;
+
+ const UINT_32 microTileThickness = 1;
+
+ //
+ // Compute the surface alignments.
+ //
+ ComputeSurfaceAlignmentsLinear(pIn->tileMode,
+ pIn->bpp,
+ pIn->flags,
+ &pOut->baseAlign,
+ &pOut->pitchAlign,
+ &pOut->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
+ }
+
+ pOut->depthAlign = microTileThickness;
+
+ expPitch = HwlPreHandleBaseLvl3xPitch(pIn, expPitch);
+
+ //
+ // Pad pitch and height to the required granularities.
+ //
+ PadDimensions(pIn->tileMode,
+ pIn->bpp,
+ pIn->flags,
+ numSamples,
+ pOut->pTileInfo,
+ padDims,
+ pIn->mipLevel,
+ &expPitch, pOut->pitchAlign,
+ &expHeight, pOut->heightAlign,
+ &expNumSlices, microTileThickness);
+
+ expPitch = HwlPostHandleBaseLvl3xPitch(pIn, expPitch);
+
+ //
+ // Adjust per HWL
+ //
+
+ UINT_64 logicalSliceSize;
+
+ logicalSliceSize = HwlGetSizeAdjustmentLinear(pIn->tileMode,
+ pIn->bpp,
+ numSamples,
+ pOut->baseAlign,
+ pOut->pitchAlign,
+ &expPitch,
+ &expHeight,
+ &pOut->heightAlign);
+
+
+ pOut->pitch = expPitch;
+ pOut->height = expHeight;
+ pOut->depth = expNumSlices;
+
+ pOut->surfSize = logicalSliceSize * expNumSlices;
+
+ pOut->tileMode = pIn->tileMode;
+
+ return TRUE;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeSurfaceInfoMicroTiled
+*
+* @brief
+* Compute 1D/Micro Tiled surface sizes include padded pitch, height, slices, total
+* size in bytes, meanwhile alignments as well. Results are returned through output
+* parameters.
+*
+* @return
+* TRUE if no error occurs
+***************************************************************************************************
+*/
+BOOL_32 EgBasedAddrLib::ComputeSurfaceInfoMicroTiled(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut, ///< [out] Output structure
+ UINT_32 padDims, ///< [in] Dimensions to padd
+ AddrTileMode expTileMode ///< [in] Expected tile mode
+ ) const
+{
+ BOOL_32 valid = TRUE;
+
+ UINT_32 microTileThickness;
+ UINT_32 expPitch = pIn->width;
+ UINT_32 expHeight = pIn->height;
+ UINT_32 expNumSlices = pIn->numSlices;
+
+ // No 1D MSAA on real H/W, keep this for TGL
+ UINT_32 numSamples = pOut->numSamples;
+
+ //
+ // Compute the micro tile thickness.
+ //
+ microTileThickness = ComputeSurfaceThickness(expTileMode);
+
+ //
+ // Extra override for mip levels
+ //
+ if (pIn->mipLevel > 0)
+ {
+ //
+ // Reduce tiling mode from thick to thin if the number of slices is less than the
+ // micro tile thickness.
+ //
+ if ((expTileMode == ADDR_TM_1D_TILED_THICK) &&
+ (expNumSlices < ThickTileThickness))
+ {
+ expTileMode = HwlDegradeThickTileMode(ADDR_TM_1D_TILED_THICK, expNumSlices, NULL);
+ if (expTileMode != ADDR_TM_1D_TILED_THICK)
+ {
+ microTileThickness = 1;
+ }
+ }
+ }
+
+ //
+ // Compute the surface restrictions.
+ //
+ ComputeSurfaceAlignmentsMicroTiled(expTileMode,
+ pIn->bpp,
+ pIn->flags,
+ pIn->mipLevel,
+ numSamples,
+ &pOut->baseAlign,
+ &pOut->pitchAlign,
+ &pOut->heightAlign);
+
+ pOut->depthAlign = microTileThickness;
+
+ //
+ // Pad pitch and height to the required granularities.
+ // Compute surface size.
+ // Return parameters.
+ //
+ PadDimensions(expTileMode,
+ pIn->bpp,
+ pIn->flags,
+ numSamples,
+ pOut->pTileInfo,
+ padDims,
+ pIn->mipLevel,
+ &expPitch, pOut->pitchAlign,
+ &expHeight, pOut->heightAlign,
+ &expNumSlices, microTileThickness);
+
+ //
+ // Get HWL specific pitch adjustment
+ //
+ UINT_64 logicalSliceSize = HwlGetSizeAdjustmentMicroTiled(microTileThickness,
+ pIn->bpp,
+ pIn->flags,
+ numSamples,
+ pOut->baseAlign,
+ pOut->pitchAlign,
+ &expPitch,
+ &expHeight);
+
+
+ pOut->pitch = expPitch;
+ pOut->height = expHeight;
+ pOut->depth = expNumSlices;
+
+ pOut->surfSize = logicalSliceSize * expNumSlices;
+
+ pOut->tileMode = expTileMode;
+
+ return valid;
+}
+
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeSurfaceInfoMacroTiled
+*
+* @brief
+* Compute 2D/macro tiled surface sizes include padded pitch, height, slices, total
+* size in bytes, meanwhile output suitable tile mode and alignments might be changed
+* in this call as well. Results are returned through output parameters.
+*
+* @return
+* TRUE if no error occurs
+***************************************************************************************************
+*/
+BOOL_32 EgBasedAddrLib::ComputeSurfaceInfoMacroTiled(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut, ///< [out] Output structure
+ UINT_32 padDims, ///< [in] Dimensions to padd
+ AddrTileMode expTileMode ///< [in] Expected tile mode
+ ) const
+{
+ BOOL_32 valid = TRUE;
+
+ AddrTileMode origTileMode = expTileMode;
+ UINT_32 microTileThickness;
+
+ UINT_32 paddedPitch;
+ UINT_32 paddedHeight;
+ UINT_64 bytesPerSlice;
+
+ UINT_32 expPitch = pIn->width;
+ UINT_32 expHeight = pIn->height;
+ UINT_32 expNumSlices = pIn->numSlices;
+
+ UINT_32 numSamples = pOut->numSamples;
+
+ //
+ // Compute the surface restrictions as base
+ // SanityCheckMacroTiled is called in ComputeSurfaceAlignmentsMacroTiled
+ //
+ valid = ComputeSurfaceAlignmentsMacroTiled(expTileMode,
+ pIn->bpp,
+ pIn->flags,
+ pIn->mipLevel,
+ numSamples,
+ pOut->pTileInfo,
+ &pOut->baseAlign,
+ &pOut->pitchAlign,
+ &pOut->heightAlign);
+
+ if (valid)
+ {
+ //
+ // Compute the micro tile thickness.
+ //
+ microTileThickness = ComputeSurfaceThickness(expTileMode);
+
+ //
+ // Find the correct tiling mode for mip levels
+ //
+ if (pIn->mipLevel > 0)
+ {
+ //
+ // Try valid tile mode
+ //
+ expTileMode = ComputeSurfaceMipLevelTileMode(expTileMode,
+ pIn->bpp,
+ expPitch,
+ expHeight,
+ expNumSlices,
+ numSamples,
+ pOut->pitchAlign,
+ pOut->heightAlign,
+ pOut->pTileInfo);
+
+ if (!IsMacroTiled(expTileMode)) // Downgraded to micro-tiled
+ {
+ return ComputeSurfaceInfoMicroTiled(pIn, pOut, padDims, expTileMode);
+ }
+ else
+ {
+ if (microTileThickness != ComputeSurfaceThickness(expTileMode))
+ {
+ //
+ // Re-compute if thickness changed since bank-height may be changed!
+ //
+ return ComputeSurfaceInfoMacroTiled(pIn, pOut, padDims, expTileMode);
+ }
+ }
+ }
+
+ paddedPitch = expPitch;
+ paddedHeight = expHeight;
+
+ //
+ // Re-cal alignment
+ //
+ if (expTileMode != origTileMode) // Tile mode is changed but still macro-tiled
+ {
+ valid = ComputeSurfaceAlignmentsMacroTiled(expTileMode,
+ pIn->bpp,
+ pIn->flags,
+ pIn->mipLevel,
+ numSamples,
+ pOut->pTileInfo,
+ &pOut->baseAlign,
+ &pOut->pitchAlign,
+ &pOut->heightAlign);
+ }
+
+ //
+ // Do padding
+ //
+ PadDimensions(expTileMode,
+ pIn->bpp,
+ pIn->flags,
+ numSamples,
+ pOut->pTileInfo,
+ padDims,
+ pIn->mipLevel,
+ &paddedPitch, pOut->pitchAlign,
+ &paddedHeight, pOut->heightAlign,
+ &expNumSlices, microTileThickness);
+
+ if (pIn->flags.qbStereo &&
+ (pOut->pStereoInfo != NULL) &&
+ HwlStereoCheckRightOffsetPadding())
+ {
+ // Eye height's bank bits are different from y == 0?
+ // Since 3D rendering treats right eye buffer starting from y == "eye height" while
+ // display engine treats it to be 0, so the bank bits may be different, we pad
+ // more in height to make sure y == "eye height" has the same bank bits as y == 0.
+ UINT_32 checkMask = pOut->pTileInfo->banks - 1;
+ UINT_32 bankBits = 0;
+ do
+ {
+ bankBits = (paddedHeight / 8 / pOut->pTileInfo->bankHeight) & checkMask;
+
+ if (bankBits)
+ {
+ paddedHeight += pOut->heightAlign;
+ }
+ } while (bankBits);
+ }
+
+ //
+ // Compute the size of a slice.
+ //
+ bytesPerSlice = BITS_TO_BYTES(static_cast<UINT_64>(paddedPitch) *
+ paddedHeight * NextPow2(pIn->bpp) * numSamples);
+
+ pOut->pitch = paddedPitch;
+ // Put this check right here to workaround special mipmap cases which the original height
+ // is needed.
+ // The original height is pre-stored in pOut->height in PostComputeMipLevel and
+ // pOut->pitch is needed in HwlCheckLastMacroTiledLvl, too.
+ if (m_configFlags.checkLast2DLevel && numSamples == 1) // Don't check MSAA
+ {
+ // Set a TRUE in pOut if next Level is the first 1D sub level
+ HwlCheckLastMacroTiledLvl(pIn, pOut);
+ }
+ pOut->height = paddedHeight;
+
+ pOut->depth = expNumSlices;
+
+ pOut->surfSize = bytesPerSlice * expNumSlices;
+
+ pOut->tileMode = expTileMode;
+
+ pOut->depthAlign = microTileThickness;
+
+ } // if (valid)
+
+ return valid;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeSurfaceAlignmentsLinear
+*
+* @brief
+* Compute linear surface alignment, calculation results are returned through
+* output parameters.
+*
+* @return
+* TRUE if no error occurs
+***************************************************************************************************
+*/
+BOOL_32 EgBasedAddrLib::ComputeSurfaceAlignmentsLinear(
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 bpp, ///< [in] bits per pixel
+ ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
+ 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
+ ) const
+{
+ BOOL_32 valid = TRUE;
+
+ switch (tileMode)
+ {
+ case ADDR_TM_LINEAR_GENERAL:
+ //
+ // The required base alignment and pitch and height granularities is to 1 element.
+ //
+ *pBaseAlign = (bpp > 8) ? bpp / 8 : 1;
+ *pPitchAlign = 1;
+ *pHeightAlign = 1;
+ break;
+ case ADDR_TM_LINEAR_ALIGNED:
+ //
+ // The required alignment for base is the pipe interleave size.
+ // The required granularity for pitch is hwl dependent.
+ // The required granularity for height is one row.
+ //
+ *pBaseAlign = m_pipeInterleaveBytes;
+ *pPitchAlign = HwlGetPitchAlignmentLinear(bpp, flags);
+ *pHeightAlign = 1;
+ break;
+ default:
+ *pBaseAlign = 1;
+ *pPitchAlign = 1;
+ *pHeightAlign = 1;
+ ADDR_UNHANDLED_CASE();
+ break;
+ }
+
+ AdjustPitchAlignment(flags, pPitchAlign);
+
+ return valid;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeSurfaceAlignmentsMicroTiled
+*
+* @brief
+* Compute 1D tiled surface alignment, calculation results are returned through
+* output parameters.
+*
+* @return
+* TRUE if no error occurs
+***************************************************************************************************
+*/
+BOOL_32 EgBasedAddrLib::ComputeSurfaceAlignmentsMicroTiled(
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 bpp, ///< [in] bits per pixel
+ ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
+ UINT_32 mipLevel, ///< [in] mip level
+ UINT_32 numSamples, ///< [in] number of samples
+ 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
+ ) const
+{
+ BOOL_32 valid = TRUE;
+
+ //
+ // The required alignment for base is the pipe interleave size.
+ //
+ *pBaseAlign = m_pipeInterleaveBytes;
+
+ *pPitchAlign = HwlGetPitchAlignmentMicroTiled(tileMode, bpp, flags, numSamples);
+
+ *pHeightAlign = MicroTileHeight;
+
+ AdjustPitchAlignment(flags, pPitchAlign);
+
+ // ECR#393489
+ // Workaround 2 for 1D tiling - There is HW bug for Carrizo
+ // where it requires the following alignments for 1D tiling.
+ if (flags.czDispCompatible && (mipLevel == 0))
+ {
+ *pBaseAlign = PowTwoAlign(*pBaseAlign, 4096); //Base address MOD 4096 = 0
+ *pPitchAlign = PowTwoAlign(*pPitchAlign, 512 / (BITS_TO_BYTES(bpp))); //(8 lines * pitch * bytes per pixel) MOD 4096 = 0
+ }
+ // end Carrizo workaround for 1D tilling
+
+ return valid;
+}
+
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlReduceBankWidthHeight
+*
+* @brief
+* Additional checks, reduce bankHeight/bankWidth if needed and possible
+* tileSize*BANK_WIDTH*BANK_HEIGHT <= ROW_SIZE
+*
+* @return
+* TRUE if no error occurs
+***************************************************************************************************
+*/
+BOOL_32 EgBasedAddrLib::HwlReduceBankWidthHeight(
+ UINT_32 tileSize, ///< [in] tile size
+ UINT_32 bpp, ///< [in] bits per pixel
+ ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
+ UINT_32 numSamples, ///< [in] number of samples
+ UINT_32 bankHeightAlign, ///< [in] bank height alignment
+ UINT_32 pipes, ///< [in] pipes
+ ADDR_TILEINFO* pTileInfo ///< [in/out] bank structure.
+ ) const
+{
+ UINT_32 macroAspectAlign;
+ BOOL_32 valid = TRUE;
+
+ if (tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize)
+ {
+ BOOL_32 stillGreater = TRUE;
+
+ // Try reducing bankWidth first
+ if (stillGreater && pTileInfo->bankWidth > 1)
+ {
+ while (stillGreater && pTileInfo->bankWidth > 0)
+ {
+ pTileInfo->bankWidth >>= 1;
+
+ if (pTileInfo->bankWidth == 0)
+ {
+ pTileInfo->bankWidth = 1;
+ break;
+ }
+
+ stillGreater =
+ tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize;
+ }
+
+ // bankWidth is reduced above, so we need to recalculate bankHeight and ratio
+ bankHeightAlign = Max(1u,
+ m_pipeInterleaveBytes * m_bankInterleave /
+ (tileSize * pTileInfo->bankWidth)
+ );
+
+ // We cannot increase bankHeight so just assert this case.
+ ADDR_ASSERT((pTileInfo->bankHeight % bankHeightAlign) == 0);
+
+ if (numSamples == 1)
+ {
+ macroAspectAlign = Max(1u,
+ m_pipeInterleaveBytes * m_bankInterleave /
+ (tileSize * pipes * pTileInfo->bankWidth)
+ );
+ pTileInfo->macroAspectRatio = PowTwoAlign(pTileInfo->macroAspectRatio,
+ macroAspectAlign);
+ }
+ }
+
+ // Early quit bank_height degradation for "64" bit z buffer
+ if (flags.depth && bpp >= 64)
+ {
+ stillGreater = FALSE;
+ }
+
+ // Then try reducing bankHeight
+ if (stillGreater && pTileInfo->bankHeight > bankHeightAlign)
+ {
+ while (stillGreater && pTileInfo->bankHeight > bankHeightAlign)
+ {
+ pTileInfo->bankHeight >>= 1;
+
+ if (pTileInfo->bankHeight < bankHeightAlign)
+ {
+ pTileInfo->bankHeight = bankHeightAlign;
+ break;
+ }
+
+ stillGreater =
+ tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize;
+ }
+ }
+
+ valid = !stillGreater;
+
+ // Generate a warning if we still fail to meet this constraint
+ if (!valid)
+ {
+ ADDR_WARN(
+ 0, ("TILE_SIZE(%d)*BANK_WIDTH(%d)*BANK_HEIGHT(%d) <= ROW_SIZE(%d)",
+ tileSize, pTileInfo->bankWidth, pTileInfo->bankHeight, m_rowSize));
+ }
+ }
+
+ return valid;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeSurfaceAlignmentsMacroTiled
+*
+* @brief
+* Compute 2D tiled surface alignment, calculation results are returned through
+* output parameters.
+*
+* @return
+* TRUE if no error occurs
+***************************************************************************************************
+*/
+BOOL_32 EgBasedAddrLib::ComputeSurfaceAlignmentsMacroTiled(
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 bpp, ///< [in] bits per pixel
+ ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
+ UINT_32 mipLevel, ///< [in] mip level
+ UINT_32 numSamples, ///< [in] number of samples
+ 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
+ ) const
+{
+ BOOL_32 valid = SanityCheckMacroTiled(pTileInfo);
+
+ if (valid)
+ {
+ UINT_32 macroTileWidth;
+ UINT_32 macroTileHeight;
+
+ UINT_32 tileSize;
+ UINT_32 bankHeightAlign;
+ UINT_32 macroAspectAlign;
+
+ UINT_32 thickness = ComputeSurfaceThickness(tileMode);
+ UINT_32 pipes = HwlGetPipes(pTileInfo);
+
+ //
+ // Align bank height first according to latest h/w spec
+ //
+
+ // tile_size = MIN(tile_split, 64 * tile_thickness * element_bytes * num_samples)
+ tileSize = Min(pTileInfo->tileSplitBytes,
+ BITS_TO_BYTES(64 * thickness * bpp * numSamples));
+
+ // bank_height_align =
+ // MAX(1, (pipe_interleave_bytes * bank_interleave)/(tile_size*bank_width))
+ bankHeightAlign = Max(1u,
+ m_pipeInterleaveBytes * m_bankInterleave /
+ (tileSize * pTileInfo->bankWidth)
+ );
+
+ pTileInfo->bankHeight = PowTwoAlign(pTileInfo->bankHeight, bankHeightAlign);
+
+ // num_pipes * bank_width * macro_tile_aspect >=
+ // (pipe_interleave_size * bank_interleave) / tile_size
+ if (numSamples == 1)
+ {
+ // this restriction is only for mipmap (mipmap's numSamples must be 1)
+ macroAspectAlign = Max(1u,
+ m_pipeInterleaveBytes * m_bankInterleave /
+ (tileSize * pipes * pTileInfo->bankWidth)
+ );
+ pTileInfo->macroAspectRatio = PowTwoAlign(pTileInfo->macroAspectRatio, macroAspectAlign);
+ }
+
+ valid = HwlReduceBankWidthHeight(tileSize,
+ bpp,
+ flags,
+ numSamples,
+ bankHeightAlign,
+ pipes,
+ pTileInfo);
+
+ //
+ // The required granularity for pitch is the macro tile width.
+ //
+ macroTileWidth = MicroTileWidth * pTileInfo->bankWidth * pipes *
+ pTileInfo->macroAspectRatio;
+
+ *pPitchAlign = macroTileWidth;
+
+ AdjustPitchAlignment(flags, pPitchAlign);
+
+ //
+ // The required granularity for height is the macro tile height.
+ //
+ macroTileHeight = MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks /
+ pTileInfo->macroAspectRatio;
+
+ *pHeightAlign = macroTileHeight;
+
+ //
+ // Compute base alignment
+ //
+ *pBaseAlign = pipes *
+ pTileInfo->bankWidth * pTileInfo->banks * pTileInfo->bankHeight * tileSize;
+
+ if ((mipLevel == 0) && (flags.prt) && (m_chipFamily == ADDR_CHIP_FAMILY_SI))
+ {
+ static const UINT_32 PrtTileSize = 0x10000;
+
+ UINT_32 macroTileSize = macroTileWidth * macroTileHeight * numSamples * bpp / 8;
+
+ if (macroTileSize < PrtTileSize)
+ {
+ UINT_32 numMacroTiles = PrtTileSize / macroTileSize;
+
+ ADDR_ASSERT((PrtTileSize % macroTileSize) == 0);
+
+ *pPitchAlign *= numMacroTiles;
+ *pBaseAlign *= numMacroTiles;
+ }
+ }
+ }
+
+ return valid;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::SanityCheckMacroTiled
+*
+* @brief
+* Check if macro-tiled parameters are valid
+* @return
+* TRUE if valid
+***************************************************************************************************
+*/
+BOOL_32 EgBasedAddrLib::SanityCheckMacroTiled(
+ ADDR_TILEINFO* pTileInfo ///< [in] macro-tiled parameters
+ ) const
+{
+ BOOL_32 valid = TRUE;
+ UINT_32 numPipes = HwlGetPipes(pTileInfo);
+
+ switch (pTileInfo->banks)
+ {
+ case 2: //fall through
+ case 4: //fall through
+ case 8: //fall through
+ case 16:
+ break;
+ default:
+ valid = FALSE;
+ break;
+
+ }
+
+ if (valid)
+ {
+ switch (pTileInfo->bankWidth)
+ {
+ case 1: //fall through
+ case 2: //fall through
+ case 4: //fall through
+ case 8:
+ break;
+ default:
+ valid = FALSE;
+ break;
+ }
+ }
+
+ if (valid)
+ {
+ switch (pTileInfo->bankHeight)
+ {
+ case 1: //fall through
+ case 2: //fall through
+ case 4: //fall through
+ case 8:
+ break;
+ default:
+ valid = FALSE;
+ break;
+ }
+ }
+
+ if (valid)
+ {
+ switch (pTileInfo->macroAspectRatio)
+ {
+ case 1: //fall through
+ case 2: //fall through
+ case 4: //fall through
+ case 8:
+ break;
+ default:
+ valid = FALSE;
+ break;
+ }
+ }
+
+ if (valid)
+ {
+ if (pTileInfo->banks < pTileInfo->macroAspectRatio)
+ {
+ // This will generate macro tile height <= 1
+ valid = FALSE;
+ }
+ }
+
+ if (valid)
+ {
+ if (pTileInfo->tileSplitBytes > m_rowSize)
+ {
+ valid = FALSE;
+ }
+ }
+
+ if (valid)
+ {
+ valid = HwlSanityCheckMacroTiled(pTileInfo);
+ }
+
+ ADDR_ASSERT(valid == TRUE);
+
+ // Add this assert for guidance
+ ADDR_ASSERT(numPipes * pTileInfo->banks >= 4);
+
+ return valid;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeSurfaceMipLevelTileMode
+*
+* @brief
+* Compute valid tile mode for surface mipmap sub-levels
+*
+* @return
+* Suitable tile mode
+***************************************************************************************************
+*/
+AddrTileMode EgBasedAddrLib::ComputeSurfaceMipLevelTileMode(
+ AddrTileMode baseTileMode, ///< [in] base tile mode
+ UINT_32 bpp, ///< [in] bits per pixels
+ UINT_32 pitch, ///< [in] current level pitch
+ UINT_32 height, ///< [in] current level height
+ UINT_32 numSlices, ///< [in] current number of slices
+ UINT_32 numSamples, ///< [in] number of samples
+ UINT_32 pitchAlign, ///< [in] pitch alignment
+ UINT_32 heightAlign, ///< [in] height alignment
+ ADDR_TILEINFO* pTileInfo ///< [in] ptr to bank structure
+ ) const
+{
+ UINT_32 bytesPerTile;
+
+ AddrTileMode expTileMode = baseTileMode;
+ UINT_32 microTileThickness = ComputeSurfaceThickness(expTileMode);
+ UINT_32 interleaveSize = m_pipeInterleaveBytes * m_bankInterleave;
+
+ //
+ // Compute the size of a slice.
+ //
+ bytesPerTile = BITS_TO_BYTES(MicroTilePixels * microTileThickness * NextPow2(bpp) * numSamples);
+
+ //
+ // Reduce tiling mode from thick to thin if the number of slices is less than the
+ // micro tile thickness.
+ //
+ if (numSlices < microTileThickness)
+ {
+ expTileMode = HwlDegradeThickTileMode(expTileMode, numSlices, &bytesPerTile);
+ }
+
+ if (bytesPerTile > pTileInfo->tileSplitBytes)
+ {
+ bytesPerTile = pTileInfo->tileSplitBytes;
+ }
+
+ UINT_32 threshold1 =
+ bytesPerTile * HwlGetPipes(pTileInfo) * pTileInfo->bankWidth * pTileInfo->macroAspectRatio;
+
+ UINT_32 threshold2 =
+ bytesPerTile * pTileInfo->bankWidth * pTileInfo->bankHeight;
+
+ //
+ // Reduce the tile mode from 2D/3D to 1D in following conditions
+ //
+ switch (expTileMode)
+ {
+ case ADDR_TM_2D_TILED_THIN1: //fall through
+ case ADDR_TM_3D_TILED_THIN1:
+ case ADDR_TM_PRT_TILED_THIN1:
+ case ADDR_TM_PRT_2D_TILED_THIN1:
+ case ADDR_TM_PRT_3D_TILED_THIN1:
+ if ((pitch < pitchAlign) ||
+ (height < heightAlign) ||
+ (interleaveSize > threshold1) ||
+ (interleaveSize > threshold2))
+ {
+ expTileMode = ADDR_TM_1D_TILED_THIN1;
+ }
+ break;
+ case ADDR_TM_2D_TILED_THICK: //fall through
+ case ADDR_TM_3D_TILED_THICK:
+ case ADDR_TM_2D_TILED_XTHICK:
+ case ADDR_TM_3D_TILED_XTHICK:
+ case ADDR_TM_PRT_TILED_THICK:
+ case ADDR_TM_PRT_2D_TILED_THICK:
+ case ADDR_TM_PRT_3D_TILED_THICK:
+ if ((pitch < pitchAlign) ||
+ (height < heightAlign))
+ {
+ expTileMode = ADDR_TM_1D_TILED_THICK;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return expTileMode;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlDegradeBaseLevel
+* @brief
+* Check if degrade is needed for base level
+* @return
+* TRUE if degrade is suggested
+***************************************************************************************************
+*/
+BOOL_32 EgBasedAddrLib::HwlDegradeBaseLevel(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const
+{
+ BOOL_32 degrade = FALSE;
+ BOOL_32 valid = TRUE;
+
+ ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
+
+ UINT_32 baseAlign;
+ UINT_32 pitchAlign;
+ UINT_32 heightAlign;
+
+ 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,
+ &tileInfo,
+ &tileInfo,
+ pIn->tileType,
+ &out);
+
+ valid = ComputeSurfaceAlignmentsMacroTiled(pIn->tileMode,
+ pIn->bpp,
+ pIn->flags,
+ pIn->mipLevel,
+ pIn->numSamples,
+ &tileInfo,
+ &baseAlign,
+ &pitchAlign,
+ &heightAlign);
+
+ if (valid)
+ {
+ degrade = (pIn->width < pitchAlign || pIn->height < heightAlign);
+ }
+ else
+ {
+ degrade = TRUE;
+ }
+
+ return degrade;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlDegradeThickTileMode
+*
+* @brief
+* Degrades valid tile mode for thick modes if needed
+*
+* @return
+* Suitable tile mode
+***************************************************************************************************
+*/
+AddrTileMode EgBasedAddrLib::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
+{
+ ADDR_ASSERT(numSlices < ComputeSurfaceThickness(baseTileMode));
+ // if pBytesPerTile is NULL, this is a don't-care....
+ UINT_32 bytesPerTile = pBytesPerTile != NULL ? *pBytesPerTile : 64;
+
+ AddrTileMode expTileMode = baseTileMode;
+ switch (baseTileMode)
+ {
+ case ADDR_TM_1D_TILED_THICK:
+ expTileMode = ADDR_TM_1D_TILED_THIN1;
+ bytesPerTile >>= 2;
+ break;
+ case ADDR_TM_2D_TILED_THICK:
+ expTileMode = ADDR_TM_2D_TILED_THIN1;
+ bytesPerTile >>= 2;
+ break;
+ case ADDR_TM_3D_TILED_THICK:
+ expTileMode = ADDR_TM_3D_TILED_THIN1;
+ bytesPerTile >>= 2;
+ break;
+ case ADDR_TM_2D_TILED_XTHICK:
+ if (numSlices < ThickTileThickness)
+ {
+ expTileMode = ADDR_TM_2D_TILED_THIN1;
+ bytesPerTile >>= 3;
+ }
+ else
+ {
+ expTileMode = ADDR_TM_2D_TILED_THICK;
+ bytesPerTile >>= 1;
+ }
+ break;
+ case ADDR_TM_3D_TILED_XTHICK:
+ if (numSlices < ThickTileThickness)
+ {
+ expTileMode = ADDR_TM_3D_TILED_THIN1;
+ bytesPerTile >>= 3;
+ }
+ else
+ {
+ expTileMode = ADDR_TM_3D_TILED_THICK;
+ bytesPerTile >>= 1;
+ }
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ break;
+ }
+
+ if (pBytesPerTile != NULL)
+ {
+ *pBytesPerTile = bytesPerTile;
+ }
+
+ return expTileMode;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::DispatchComputeSurfaceAddrFromCoord
+*
+* @brief
+* Compute surface address from given coord (x, y, slice,sample)
+*
+* @return
+* Address in bytes
+***************************************************************************************************
+*/
+UINT_64 EgBasedAddrLib::DispatchComputeSurfaceAddrFromCoord(
+ const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ UINT_32 x = pIn->x;
+ UINT_32 y = pIn->y;
+ UINT_32 slice = pIn->slice;
+ UINT_32 sample = pIn->sample;
+ UINT_32 bpp = pIn->bpp;
+ UINT_32 pitch = pIn->pitch;
+ UINT_32 height = pIn->height;
+ UINT_32 numSlices = pIn->numSlices;
+ UINT_32 numSamples = ((pIn->numSamples == 0) ? 1 : pIn->numSamples);
+ UINT_32 numFrags = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
+ AddrTileMode tileMode = pIn->tileMode;
+ AddrTileType microTileType = pIn->tileType;
+ BOOL_32 ignoreSE = pIn->ignoreSE;
+ BOOL_32 isDepthSampleOrder = pIn->isDepth;
+ ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
+
+ UINT_32* pBitPosition = &pOut->bitPosition;
+ UINT_64 addr;
+
+#if ADDR_AM_BUILD
+ UINT_32 addr5Bit = 0;
+ UINT_32 addr5Swizzle = pIn->addr5Swizzle;
+ BOOL_32 is32ByteTile = pIn->is32ByteTile;
+#endif
+
+ // ADDR_DEPTH_SAMPLE_ORDER = non-disp + depth-sample-order
+ if (microTileType == ADDR_DEPTH_SAMPLE_ORDER)
+ {
+ isDepthSampleOrder = TRUE;
+ }
+
+ if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
+ {
+ if (numFrags != numSamples)
+ {
+ numSamples = numFrags;
+ ADDR_ASSERT(sample < numSamples);
+ }
+
+ /// @note
+ /// 128 bit/thick tiled surface doesn't support display tiling and
+ /// mipmap chain must have the same tileType, so please fill tileType correctly
+ if (!IsLinear(pIn->tileMode))
+ {
+ if (bpp >= 128 || ComputeSurfaceThickness(tileMode) > 1)
+ {
+ ADDR_ASSERT(microTileType != ADDR_DISPLAYABLE);
+ }
+ }
+ }
+
+ switch (tileMode)
+ {
+ case ADDR_TM_LINEAR_GENERAL://fall through
+ case ADDR_TM_LINEAR_ALIGNED:
+ addr = ComputeSurfaceAddrFromCoordLinear(x,
+ y,
+ slice,
+ sample,
+ bpp,
+ pitch,
+ height,
+ numSlices,
+ pBitPosition);
+ break;
+ case ADDR_TM_1D_TILED_THIN1://fall through
+ case ADDR_TM_1D_TILED_THICK:
+ addr = ComputeSurfaceAddrFromCoordMicroTiled(x,
+ y,
+ slice,
+ sample,
+ bpp,
+ pitch,
+ height,
+ numSamples,
+ tileMode,
+ microTileType,
+ isDepthSampleOrder,
+ pBitPosition);
+ break;
+ case ADDR_TM_2D_TILED_THIN1: //fall through
+ case ADDR_TM_2D_TILED_THICK: //fall through
+ case ADDR_TM_3D_TILED_THIN1: //fall through
+ case ADDR_TM_3D_TILED_THICK: //fall through
+ case ADDR_TM_2D_TILED_XTHICK: //fall through
+ case ADDR_TM_3D_TILED_XTHICK: //fall through
+ case ADDR_TM_PRT_TILED_THIN1: //fall through
+ case ADDR_TM_PRT_2D_TILED_THIN1://fall through
+ case ADDR_TM_PRT_3D_TILED_THIN1://fall through
+ case ADDR_TM_PRT_TILED_THICK: //fall through
+ case ADDR_TM_PRT_2D_TILED_THICK://fall through
+ case ADDR_TM_PRT_3D_TILED_THICK:
+ UINT_32 pipeSwizzle;
+ UINT_32 bankSwizzle;
+
+ if (m_configFlags.useCombinedSwizzle)
+ {
+ ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo,
+ &bankSwizzle, &pipeSwizzle);
+ }
+ else
+ {
+ pipeSwizzle = pIn->pipeSwizzle;
+ bankSwizzle = pIn->bankSwizzle;
+ }
+
+ addr = ComputeSurfaceAddrFromCoordMacroTiled(x,
+ y,
+ slice,
+ sample,
+ bpp,
+ pitch,
+ height,
+ numSamples,
+ tileMode,
+ microTileType,
+ ignoreSE,
+ isDepthSampleOrder,
+ pipeSwizzle,
+ bankSwizzle,
+ pTileInfo,
+ pBitPosition);
+ break;
+ default:
+ addr = 0;
+ ADDR_ASSERT_ALWAYS();
+ break;
+ }
+
+#if ADDR_AM_BUILD
+ if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
+ {
+ if (addr5Swizzle && isDepthSampleOrder && is32ByteTile)
+ {
+ UINT_32 tx = x >> 3;
+ UINT_32 ty = y >> 3;
+ UINT_32 tileBits = ((ty&0x3) << 2) | (tx&0x3);
+
+ tileBits = tileBits & addr5Swizzle;
+ addr5Bit = XorReduce(tileBits, 4);
+
+ addr = addr | static_cast<UINT_64>(addr5Bit << 5);
+ }
+ }
+#endif
+
+ return addr;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled
+*
+* @brief
+* Computes the surface address and bit position from a
+* coordinate for 2D tilied (macro tiled)
+* @return
+* The byte address
+***************************************************************************************************
+*/
+UINT_64 EgBasedAddrLib::ComputeSurfaceAddrFromCoordMacroTiled(
+ UINT_32 x, ///< [in] x coordinate
+ UINT_32 y, ///< [in] y coordinate
+ UINT_32 slice, ///< [in] slice index
+ UINT_32 sample, ///< [in] sample index
+ UINT_32 bpp, ///< [in] bits per pixel
+ UINT_32 pitch, ///< [in] surface pitch, in pixels
+ UINT_32 height, ///< [in] surface height, in pixels
+ UINT_32 numSamples, ///< [in] number of samples
+ AddrTileMode tileMode, ///< [in] tile mode
+ AddrTileType microTileType, ///< [in] micro tiling type
+ BOOL_32 ignoreSE, ///< [in] TRUE if shader enginers can be ignored
+ BOOL_32 isDepthSampleOrder, ///< [in] TRUE if it depth sample ordering is used
+ UINT_32 pipeSwizzle, ///< [in] pipe swizzle
+ UINT_32 bankSwizzle, ///< [in] bank swizzle
+ ADDR_TILEINFO* pTileInfo, ///< [in] bank structure
+ /// **All fields to be valid on entry**
+ UINT_32* pBitPosition ///< [out] bit position, e.g. FMT_1 will use this
+ ) const
+{
+ UINT_64 addr;
+
+ UINT_32 microTileBytes;
+ UINT_32 microTileBits;
+ UINT_32 sampleOffset;
+ UINT_32 pixelIndex;
+ UINT_32 pixelOffset;
+ UINT_32 elementOffset;
+ UINT_32 tileSplitSlice;
+ UINT_32 pipe;
+ UINT_32 bank;
+ UINT_64 sliceBytes;
+ UINT_64 sliceOffset;
+ UINT_32 macroTilePitch;
+ UINT_32 macroTileHeight;
+ UINT_32 macroTilesPerRow;
+ UINT_32 macroTilesPerSlice;
+ UINT_64 macroTileBytes;
+ UINT_32 macroTileIndexX;
+ UINT_32 macroTileIndexY;
+ UINT_64 macroTileOffset;
+ UINT_64 totalOffset;
+ UINT_64 pipeInterleaveMask;
+ UINT_64 bankInterleaveMask;
+ UINT_64 pipeInterleaveOffset;
+ UINT_32 bankInterleaveOffset;
+ UINT_64 offset;
+ UINT_32 tileRowIndex;
+ UINT_32 tileColumnIndex;
+ UINT_32 tileIndex;
+ UINT_32 tileOffset;
+
+ UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode);
+
+ //
+ // Compute the number of group, pipe, and bank bits.
+ //
+ UINT_32 numPipes = HwlGetPipes(pTileInfo);
+ UINT_32 numPipeInterleaveBits = Log2(m_pipeInterleaveBytes);
+ UINT_32 numPipeBits = Log2(numPipes);
+ UINT_32 numBankInterleaveBits = Log2(m_bankInterleave);
+ UINT_32 numBankBits = Log2(pTileInfo->banks);
+
+ //
+ // Compute the micro tile size.
+ //
+ microTileBits = MicroTilePixels * microTileThickness * bpp * numSamples;
+
+ microTileBytes = microTileBits / 8;
+ //
+ // Compute the pixel index within the micro tile.
+ //
+ pixelIndex = ComputePixelIndexWithinMicroTile(x,
+ y,
+ slice,
+ bpp,
+ tileMode,
+ microTileType);
+
+ //
+ // Compute the sample offset and pixel offset.
+ //
+ if (isDepthSampleOrder)
+ {
+ //
+ // For depth surfaces, samples are stored contiguously for each element, so the sample
+ // offset is the sample number times the element size.
+ //
+ sampleOffset = sample * bpp;
+ pixelOffset = pixelIndex * bpp * numSamples;
+ }
+ else
+ {
+ //
+ // For color surfaces, all elements for a particular sample are stored contiguously, so
+ // the sample offset is the sample number times the micro tile size divided yBit the number
+ // of samples.
+ //
+ sampleOffset = sample * (microTileBits / numSamples);
+ pixelOffset = pixelIndex * bpp;
+ }
+
+ //
+ // Compute the element offset.
+ //
+ elementOffset = pixelOffset + sampleOffset;
+
+ *pBitPosition = static_cast<UINT_32>(elementOffset % 8);
+
+ elementOffset /= 8; //bit-to-byte
+
+ //
+ // Determine if tiles need to be split across slices.
+ //
+ // If the size of the micro tile is larger than the tile split size, then the tile will be
+ // split across multiple slices.
+ //
+ UINT_32 slicesPerTile = 1;
+
+ if ((microTileBytes > pTileInfo->tileSplitBytes) && (microTileThickness == 1))
+ { //don't support for thick mode
+
+ //
+ // Compute the number of slices per tile.
+ //
+ slicesPerTile = microTileBytes / pTileInfo->tileSplitBytes;
+
+ //
+ // Compute the tile split slice number for use in rotating the bank.
+ //
+ tileSplitSlice = elementOffset / pTileInfo->tileSplitBytes;
+
+ //
+ // Adjust the element offset to account for the portion of the tile that is being moved to
+ // a new slice..
+ //
+ elementOffset %= pTileInfo->tileSplitBytes;
+
+ //
+ // Adjust the microTileBytes size to tileSplitBytes size since
+ // a new slice..
+ //
+ microTileBytes = pTileInfo->tileSplitBytes;
+ }
+ else
+ {
+ tileSplitSlice = 0;
+ }
+
+ //
+ // Compute macro tile pitch and height.
+ //
+ macroTilePitch =
+ (MicroTileWidth * pTileInfo->bankWidth * numPipes) * pTileInfo->macroAspectRatio;
+ macroTileHeight =
+ (MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks) / pTileInfo->macroAspectRatio;
+
+ //
+ // Compute the number of bytes per macro tile. Note: bytes of the same bank/pipe actually
+ //
+ macroTileBytes =
+ static_cast<UINT_64>(microTileBytes) *
+ (macroTilePitch / MicroTileWidth) * (macroTileHeight / MicroTileHeight) /
+ (numPipes * pTileInfo->banks);
+
+ //
+ // Compute the number of macro tiles per row.
+ //
+ macroTilesPerRow = pitch / macroTilePitch;
+
+ //
+ // Compute the offset to the macro tile containing the specified coordinate.
+ //
+ macroTileIndexX = x / macroTilePitch;
+ macroTileIndexY = y / macroTileHeight;
+ macroTileOffset = ((macroTileIndexY * macroTilesPerRow) + macroTileIndexX) * macroTileBytes;
+
+ //
+ // Compute the number of macro tiles per slice.
+ //
+ macroTilesPerSlice = macroTilesPerRow * (height / macroTileHeight);
+
+ //
+ // Compute the slice size.
+ //
+ sliceBytes = macroTilesPerSlice * macroTileBytes;
+
+ //
+ // Compute the slice offset.
+ //
+ sliceOffset = sliceBytes * (tileSplitSlice + slicesPerTile * (slice / microTileThickness));
+
+ //
+ // Compute tile offest
+ //
+ tileRowIndex = (y / MicroTileHeight) % pTileInfo->bankHeight;
+ tileColumnIndex = ((x / MicroTileWidth) / numPipes) % pTileInfo->bankWidth;
+ tileIndex = (tileRowIndex * pTileInfo->bankWidth) + tileColumnIndex;
+ tileOffset = tileIndex * microTileBytes;
+
+ //
+ // Combine the slice offset and macro tile offset with the pixel and sample offsets, accounting
+ // for the pipe and bank bits in the middle of the address.
+ //
+ totalOffset = sliceOffset + macroTileOffset + elementOffset + tileOffset;
+
+ //
+ // Get the pipe and bank.
+ //
+
+ // when the tileMode is PRT type, then adjust x and y coordinates
+ if (IsPrtNoRotationTileMode(tileMode))
+ {
+ x = x % macroTilePitch;
+ y = y % macroTileHeight;
+ }
+
+ pipe = ComputePipeFromCoord(x,
+ y,
+ slice,
+ tileMode,
+ pipeSwizzle,
+ ignoreSE,
+ pTileInfo);
+
+ bank = ComputeBankFromCoord(x,
+ y,
+ slice,
+ tileMode,
+ bankSwizzle,
+ tileSplitSlice,
+ pTileInfo);
+
+
+ //
+ // Split the offset to put some bits below the pipe+bank bits and some above.
+ //
+ pipeInterleaveMask = (1 << numPipeInterleaveBits) - 1;
+ bankInterleaveMask = (1 << numBankInterleaveBits) - 1;
+ pipeInterleaveOffset = totalOffset & pipeInterleaveMask;
+ bankInterleaveOffset = static_cast<UINT_32>((totalOffset >> numPipeInterleaveBits) &
+ bankInterleaveMask);
+ offset = totalOffset >> (numPipeInterleaveBits + numBankInterleaveBits);
+
+ //
+ // Assemble the address from its components.
+ //
+ addr = pipeInterleaveOffset;
+ // This is to remove /analyze warnings
+ UINT_32 pipeBits = pipe << numPipeInterleaveBits;
+ UINT_32 bankInterleaveBits = bankInterleaveOffset << (numPipeInterleaveBits + numPipeBits);
+ UINT_32 bankBits = bank << (numPipeInterleaveBits + numPipeBits +
+ numBankInterleaveBits);
+ UINT_64 offsetBits = offset << (numPipeInterleaveBits + numPipeBits +
+ numBankInterleaveBits + numBankBits);
+
+ addr |= pipeBits;
+ addr |= bankInterleaveBits;
+ addr |= bankBits;
+ addr |= offsetBits;
+
+ return addr;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled
+*
+* @brief
+* Computes the surface address and bit position from a coordinate for 1D tilied
+* (micro tiled)
+* @return
+* The byte address
+***************************************************************************************************
+*/
+UINT_64 EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled(
+ UINT_32 x, ///< [in] x coordinate
+ UINT_32 y, ///< [in] y coordinate
+ UINT_32 slice, ///< [in] slice index
+ UINT_32 sample, ///< [in] sample index
+ UINT_32 bpp, ///< [in] bits per pixel
+ UINT_32 pitch, ///< [in] pitch, in pixels
+ UINT_32 height, ///< [in] height, in pixels
+ UINT_32 numSamples, ///< [in] number of samples
+ AddrTileMode tileMode, ///< [in] tile mode
+ AddrTileType microTileType, ///< [in] micro tiling type
+ BOOL_32 isDepthSampleOrder, ///< [in] TRUE if depth sample ordering is used
+ UINT_32* pBitPosition ///< [out] bit position, e.g. FMT_1 will use this
+ ) const
+{
+ UINT_64 addr = 0;
+
+ UINT_32 microTileBytes;
+ UINT_64 sliceBytes;
+ UINT_32 microTilesPerRow;
+ UINT_32 microTileIndexX;
+ UINT_32 microTileIndexY;
+ UINT_32 microTileIndexZ;
+ UINT_64 sliceOffset;
+ UINT_64 microTileOffset;
+ UINT_32 sampleOffset;
+ UINT_32 pixelIndex;
+ UINT_32 pixelOffset;
+
+ UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode);
+
+ //
+ // Compute the micro tile size.
+ //
+ microTileBytes = BITS_TO_BYTES(MicroTilePixels * microTileThickness * bpp * numSamples);
+
+ //
+ // Compute the slice size.
+ //
+ sliceBytes =
+ BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * microTileThickness * bpp * numSamples);
+
+ //
+ // Compute the number of micro tiles per row.
+ //
+ microTilesPerRow = pitch / MicroTileWidth;
+
+ //
+ // Compute the micro tile index.
+ //
+ microTileIndexX = x / MicroTileWidth;
+ microTileIndexY = y / MicroTileHeight;
+ microTileIndexZ = slice / microTileThickness;
+
+ //
+ // Compute the slice offset.
+ //
+ sliceOffset = static_cast<UINT_64>(microTileIndexZ) * sliceBytes;
+
+ //
+ // Compute the offset to the micro tile containing the specified coordinate.
+ //
+ microTileOffset = (static_cast<UINT_64>(microTileIndexY) * microTilesPerRow + microTileIndexX) *
+ microTileBytes;
+
+ //
+ // Compute the pixel index within the micro tile.
+ //
+ pixelIndex = ComputePixelIndexWithinMicroTile(x,
+ y,
+ slice,
+ bpp,
+ tileMode,
+ microTileType);
+
+ // Compute the sample offset.
+ //
+ if (isDepthSampleOrder)
+ {
+ //
+ // For depth surfaces, samples are stored contiguously for each element, so the sample
+ // offset is the sample number times the element size.
+ //
+ sampleOffset = sample * bpp;
+ pixelOffset = pixelIndex * bpp * numSamples;
+ }
+ else
+ {
+ //
+ // For color surfaces, all elements for a particular sample are stored contiguously, so
+ // the sample offset is the sample number times the micro tile size divided yBit the number
+ // of samples.
+ //
+ sampleOffset = sample * (microTileBytes*8 / numSamples);
+ pixelOffset = pixelIndex * bpp;
+ }
+
+ //
+ // Compute the bit position of the pixel. Each element is stored with one bit per sample.
+ //
+
+ UINT_32 elemOffset = sampleOffset + pixelOffset;
+
+ *pBitPosition = elemOffset % 8;
+ elemOffset /= 8;
+
+ //
+ // Combine the slice offset, micro tile offset, sample offset, and pixel offsets.
+ //
+ addr = sliceOffset + microTileOffset + elemOffset;
+
+ return addr;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlComputePixelCoordFromOffset
+*
+* @brief
+* Compute pixel coordinate from offset inside a micro tile
+* @return
+* N/A
+***************************************************************************************************
+*/
+VOID EgBasedAddrLib::HwlComputePixelCoordFromOffset(
+ UINT_32 offset, ///< [in] offset inside micro tile in bits
+ UINT_32 bpp, ///< [in] bits per pixel
+ UINT_32 numSamples, ///< [in] number of samples
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 tileBase, ///< [in] base offset within a tile
+ UINT_32 compBits, ///< [in] component bits actually needed(for planar surface)
+ UINT_32* pX, ///< [out] x coordinate
+ UINT_32* pY, ///< [out] y coordinate
+ UINT_32* pSlice, ///< [out] slice index
+ UINT_32* pSample, ///< [out] sample index
+ AddrTileType microTileType, ///< [in] micro tiling type
+ BOOL_32 isDepthSampleOrder ///< [in] TRUE if depth sample order in microtile is used
+ ) const
+{
+ UINT_32 x = 0;
+ UINT_32 y = 0;
+ UINT_32 z = 0;
+ UINT_32 thickness = ComputeSurfaceThickness(tileMode);
+
+ // For planar surface, we adjust offset acoording to tile base
+ if ((bpp != compBits) && (compBits != 0) && isDepthSampleOrder)
+ {
+ offset -= tileBase;
+
+ ADDR_ASSERT(microTileType == ADDR_NON_DISPLAYABLE ||
+ microTileType == ADDR_DEPTH_SAMPLE_ORDER);
+
+ bpp = compBits;
+ }
+
+ UINT_32 sampleTileBits;
+ UINT_32 samplePixelBits;
+ UINT_32 pixelIndex;
+
+ if (isDepthSampleOrder)
+ {
+ samplePixelBits = bpp * numSamples;
+ pixelIndex = offset / samplePixelBits;
+ *pSample = (offset % samplePixelBits) / bpp;
+ }
+ else
+ {
+ sampleTileBits = MicroTilePixels * bpp * thickness;
+ *pSample = offset / sampleTileBits;
+ pixelIndex = (offset % sampleTileBits) / bpp;
+ }
+
+ if (microTileType != ADDR_THICK)
+ {
+ if (microTileType == ADDR_DISPLAYABLE) // displayable
+ {
+ switch (bpp)
+ {
+ case 8:
+ x = pixelIndex & 0x7;
+ y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,4));
+ break;
+ case 16:
+ x = pixelIndex & 0x7;
+ y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,3));
+ break;
+ case 32:
+ x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,1),_BIT(pixelIndex,0));
+ y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,2));
+ break;
+ case 64:
+ x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
+ y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
+ break;
+ case 128:
+ x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,2),_BIT(pixelIndex,1));
+ y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,0));
+ break;
+ default:
+ break;
+ }
+ }
+ else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER)
+ {
+ x = Bits2Number(3, _BIT(pixelIndex,4),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
+ y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
+ }
+ else if (microTileType == ADDR_ROTATED)
+ {
+ /*
+ 8-Bit Elements
+ element_index[5:0] = { x[2], x[0], x[1], y[2], y[1], y[0] }
+
+ 16-Bit Elements
+ element_index[5:0] = { x[2], x[1], x[0], y[2], y[1], y[0] }
+
+ 32-Bit Elements
+ element_index[5:0] = { x[2], x[1], y[2], x[0], y[1], y[0] }
+
+ 64-Bit Elements
+ element_index[5:0] = { y[2], x[2], x[1], y[1], x[0], y[0] }
+ */
+ switch(bpp)
+ {
+ case 8:
+ x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,4));
+ y = pixelIndex & 0x7;
+ break;
+ case 16:
+ x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,3));
+ y = pixelIndex & 0x7;
+ break;
+ case 32:
+ x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,2));
+ y = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,1),_BIT(pixelIndex,0));
+ break;
+ case 64:
+ x = Bits2Number(3, _BIT(pixelIndex,4),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
+ y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ break;
+ }
+ }
+
+ if (thickness > 1) // thick
+ {
+ z = Bits2Number(3, _BIT(pixelIndex,8),_BIT(pixelIndex,7),_BIT(pixelIndex,6));
+ }
+ }
+ else
+ {
+ ADDR_ASSERT((m_chipFamily >= ADDR_CHIP_FAMILY_CI) && (thickness > 1));
+ /*
+ 8-Bit Elements and 16-Bit Elements
+ element_index[7:0] = { y[2], x[2], z[1], z[0], y[1], x[1], y[0], x[0] }
+
+ 32-Bit Elements
+ element_index[7:0] = { y[2], x[2], z[1], y[1], z[0], x[1], y[0], x[0] }
+
+ 64-Bit Elements and 128-Bit Elements
+ element_index[7:0] = { y[2], x[2], z[1], y[1], x[1], z[0], y[0], x[0] }
+
+ The equation to compute the element index for the extra thick tile:
+ element_index[8] = z[2]
+ */
+ switch (bpp)
+ {
+ case 8:
+ case 16: // fall-through
+ x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
+ y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
+ z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,4));
+ break;
+ case 32:
+ x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
+ y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
+ z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,3));
+ break;
+ case 64:
+ case 128: // fall-through
+ x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,3),_BIT(pixelIndex,0));
+ y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
+ z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,2));
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ break;
+ }
+
+ if (thickness == 8)
+ {
+ z += Bits2Number(3,_BIT(pixelIndex,8),0,0);
+ }
+ }
+
+ *pX = x;
+ *pY = y;
+ *pSlice += z;
+}
+
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::DispatchComputeSurfaceCoordFromAddrDispatch
+*
+* @brief
+* Compute (x,y,slice,sample) coordinates from surface address
+* @return
+* N/A
+***************************************************************************************************
+*/
+VOID EgBasedAddrLib::DispatchComputeSurfaceCoordFromAddr(
+ const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ UINT_64 addr = pIn->addr;
+ UINT_32 bitPosition = pIn->bitPosition;
+ UINT_32 bpp = pIn->bpp;
+ UINT_32 pitch = pIn->pitch;
+ UINT_32 height = pIn->height;
+ UINT_32 numSlices = pIn->numSlices;
+ UINT_32 numSamples = ((pIn->numSamples == 0) ? 1 : pIn->numSamples);
+ UINT_32 numFrags = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
+ AddrTileMode tileMode = pIn->tileMode;
+ UINT_32 tileBase = pIn->tileBase;
+ UINT_32 compBits = pIn->compBits;
+ AddrTileType microTileType = pIn->tileType;
+ BOOL_32 ignoreSE = pIn->ignoreSE;
+ BOOL_32 isDepthSampleOrder = pIn->isDepth;
+ ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
+
+ UINT_32* pX = &pOut->x;
+ UINT_32* pY = &pOut->y;
+ UINT_32* pSlice = &pOut->slice;
+ UINT_32* pSample = &pOut->sample;
+
+ if (microTileType == ADDR_DEPTH_SAMPLE_ORDER)
+ {
+ isDepthSampleOrder = TRUE;
+ }
+
+ if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
+ {
+ if (numFrags != numSamples)
+ {
+ numSamples = numFrags;
+ }
+
+ /// @note
+ /// 128 bit/thick tiled surface doesn't support display tiling and
+ /// mipmap chain must have the same tileType, so please fill tileType correctly
+ if (!IsLinear(pIn->tileMode))
+ {
+ if (bpp >= 128 || ComputeSurfaceThickness(tileMode) > 1)
+ {
+ ADDR_ASSERT(microTileType != ADDR_DISPLAYABLE);
+ }
+ }
+ }
+
+ switch (tileMode)
+ {
+ case ADDR_TM_LINEAR_GENERAL://fall through
+ case ADDR_TM_LINEAR_ALIGNED:
+ ComputeSurfaceCoordFromAddrLinear(addr,
+ bitPosition,
+ bpp,
+ pitch,
+ height,
+ numSlices,
+ pX,
+ pY,
+ pSlice,
+ pSample);
+ break;
+ case ADDR_TM_1D_TILED_THIN1://fall through
+ case ADDR_TM_1D_TILED_THICK:
+ ComputeSurfaceCoordFromAddrMicroTiled(addr,
+ bitPosition,
+ bpp,
+ pitch,
+ height,
+ numSamples,
+ tileMode,
+ tileBase,
+ compBits,
+ pX,
+ pY,
+ pSlice,
+ pSample,
+ microTileType,
+ isDepthSampleOrder);
+ break;
+ case ADDR_TM_2D_TILED_THIN1: //fall through
+ case ADDR_TM_2D_TILED_THICK: //fall through
+ case ADDR_TM_3D_TILED_THIN1: //fall through
+ case ADDR_TM_3D_TILED_THICK: //fall through
+ case ADDR_TM_2D_TILED_XTHICK: //fall through
+ case ADDR_TM_3D_TILED_XTHICK: //fall through
+ case ADDR_TM_PRT_TILED_THIN1: //fall through
+ case ADDR_TM_PRT_2D_TILED_THIN1://fall through
+ case ADDR_TM_PRT_3D_TILED_THIN1://fall through
+ case ADDR_TM_PRT_TILED_THICK: //fall through
+ case ADDR_TM_PRT_2D_TILED_THICK://fall through
+ case ADDR_TM_PRT_3D_TILED_THICK:
+ UINT_32 pipeSwizzle;
+ UINT_32 bankSwizzle;
+
+ if (m_configFlags.useCombinedSwizzle)
+ {
+ ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo,
+ &bankSwizzle, &pipeSwizzle);
+ }
+ else
+ {
+ pipeSwizzle = pIn->pipeSwizzle;
+ bankSwizzle = pIn->bankSwizzle;
+ }
+
+ ComputeSurfaceCoordFromAddrMacroTiled(addr,
+ bitPosition,
+ bpp,
+ pitch,
+ height,
+ numSamples,
+ tileMode,
+ tileBase,
+ compBits,
+ microTileType,
+ ignoreSE,
+ isDepthSampleOrder,
+ pipeSwizzle,
+ bankSwizzle,
+ pTileInfo,
+ pX,
+ pY,
+ pSlice,
+ pSample);
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ }
+}
+
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeSurfaceCoordFromAddrMacroTiled
+*
+* @brief
+* Compute surface coordinates from address for macro tiled surface
+* @return
+* N/A
+***************************************************************************************************
+*/
+VOID EgBasedAddrLib::ComputeSurfaceCoordFromAddrMacroTiled(
+ UINT_64 addr, ///< [in] byte address
+ UINT_32 bitPosition, ///< [in] bit position
+ UINT_32 bpp, ///< [in] bits per pixel
+ UINT_32 pitch, ///< [in] pitch in pixels
+ UINT_32 height, ///< [in] height in pixels
+ UINT_32 numSamples, ///< [in] number of samples
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 tileBase, ///< [in] tile base offset
+ UINT_32 compBits, ///< [in] component bits (for planar surface)
+ AddrTileType microTileType, ///< [in] micro tiling type
+ BOOL_32 ignoreSE, ///< [in] TRUE if shader engines can be ignored
+ BOOL_32 isDepthSampleOrder, ///< [in] TRUE if depth sample order is used
+ UINT_32 pipeSwizzle, ///< [in] pipe swizzle
+ UINT_32 bankSwizzle, ///< [in] bank swizzle
+ ADDR_TILEINFO* pTileInfo, ///< [in] bank structure.
+ /// **All fields to be valid on entry**
+ UINT_32* pX, ///< [out] X coord
+ UINT_32* pY, ///< [out] Y coord
+ UINT_32* pSlice, ///< [out] slice index
+ UINT_32* pSample ///< [out] sample index
+ ) const
+{
+ UINT_32 mx;
+ UINT_32 my;
+ UINT_64 tileBits;
+ UINT_64 macroTileBits;
+ UINT_32 slices;
+ UINT_32 tileSlices;
+ UINT_64 elementOffset;
+ UINT_64 macroTileIndex;
+ UINT_32 tileIndex;
+ UINT_64 totalOffset;
+
+
+ UINT_32 bank;
+ UINT_32 pipe;
+ UINT_32 groupBits = m_pipeInterleaveBytes << 3;
+ UINT_32 pipes = HwlGetPipes(pTileInfo);
+ UINT_32 banks = pTileInfo->banks;
+
+ UINT_32 bankInterleave = m_bankInterleave;
+
+ UINT_64 addrBits = BYTES_TO_BITS(addr) + bitPosition;
+
+ //
+ // remove bits for bank and pipe
+ //
+ totalOffset = (addrBits % groupBits) +
+ (((addrBits / groupBits / pipes) % bankInterleave) * groupBits) +
+ (((addrBits / groupBits / pipes) / bankInterleave) / banks) * groupBits * bankInterleave;
+
+ UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode);
+
+ UINT_32 microTileBits = bpp * microTileThickness * MicroTilePixels * numSamples;
+
+ UINT_32 microTileBytes = BITS_TO_BYTES(microTileBits);
+ //
+ // Determine if tiles need to be split across slices.
+ //
+ // If the size of the micro tile is larger than the tile split size, then the tile will be
+ // split across multiple slices.
+ //
+ UINT_32 slicesPerTile = 1; //_State->TileSlices
+
+ if ((microTileBytes > pTileInfo->tileSplitBytes) && (microTileThickness == 1))
+ { //don't support for thick mode
+
+ //
+ // Compute the number of slices per tile.
+ //
+ slicesPerTile = microTileBytes / pTileInfo->tileSplitBytes;
+ }
+
+ tileBits = microTileBits / slicesPerTile; // micro tile bits
+
+ // in micro tiles because not MicroTileWidth timed.
+ UINT_32 macroWidth = pTileInfo->bankWidth * pipes * pTileInfo->macroAspectRatio;
+ // in micro tiles as well
+ UINT_32 macroHeight = pTileInfo->bankHeight * banks / pTileInfo->macroAspectRatio;
+
+ UINT_32 pitchInMacroTiles = pitch / MicroTileWidth / macroWidth;
+
+ macroTileBits = (macroWidth * macroHeight) * tileBits / (banks * pipes);
+
+ macroTileIndex = totalOffset / macroTileBits;
+
+ // pitchMacros * height / heightMacros; macroTilesPerSlice == _State->SliceMacros
+ UINT_32 macroTilesPerSlice = (pitch / (macroWidth * MicroTileWidth)) * height /
+ (macroHeight * MicroTileWidth);
+
+ slices = static_cast<UINT_32>(macroTileIndex / macroTilesPerSlice);
+
+ *pSlice = static_cast<UINT_32>(slices / slicesPerTile * microTileThickness);
+
+ //
+ // calculate element offset and x[2:0], y[2:0], z[1:0] for thick
+ //
+ tileSlices = slices % slicesPerTile;
+
+ elementOffset = tileSlices * tileBits;
+ elementOffset += totalOffset % tileBits;
+
+ UINT_32 coordZ = 0;
+
+ HwlComputePixelCoordFromOffset(static_cast<UINT_32>(elementOffset),
+ bpp,
+ numSamples,
+ tileMode,
+ tileBase,
+ compBits,
+ pX,
+ pY,
+ &coordZ,
+ pSample,
+ microTileType,
+ isDepthSampleOrder);
+
+ macroTileIndex = macroTileIndex % macroTilesPerSlice;
+ *pY += static_cast<UINT_32>(macroTileIndex / pitchInMacroTiles * macroHeight * MicroTileHeight);
+ *pX += static_cast<UINT_32>(macroTileIndex % pitchInMacroTiles * macroWidth * MicroTileWidth);
+
+ *pSlice += coordZ;
+
+ tileIndex = static_cast<UINT_32>((totalOffset % macroTileBits) / tileBits);
+
+ my = (tileIndex / pTileInfo->bankWidth) % pTileInfo->bankHeight * MicroTileHeight;
+ mx = (tileIndex % pTileInfo->bankWidth) * pipes * MicroTileWidth;
+
+ *pY += my;
+ *pX += mx;
+
+ bank = ComputeBankFromAddr(addr, banks, pipes);
+ pipe = ComputePipeFromAddr(addr, pipes);
+
+ HwlComputeSurfaceCoord2DFromBankPipe(tileMode,
+ pX,
+ pY,
+ *pSlice,
+ bank,
+ pipe,
+ bankSwizzle,
+ pipeSwizzle,
+ tileSlices,
+ ignoreSE,
+ pTileInfo);
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeSurfaceCoord2DFromBankPipe
+*
+* @brief
+* Compute surface x,y coordinates from bank/pipe info
+* @return
+* N/A
+***************************************************************************************************
+*/
+VOID EgBasedAddrLib::ComputeSurfaceCoord2DFromBankPipe(
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 x, ///< [in] x coordinate
+ UINT_32 y, ///< [in] y coordinate
+ UINT_32 slice, ///< [in] slice index
+ UINT_32 bank, ///< [in] bank number
+ UINT_32 pipe, ///< [in] pipe number
+ UINT_32 bankSwizzle,///< [in] bank swizzle
+ UINT_32 pipeSwizzle,///< [in] pipe swizzle
+ UINT_32 tileSlices, ///< [in] slices in a micro tile
+ ADDR_TILEINFO* pTileInfo, ///< [in] bank structure. **All fields to be valid on entry**
+ CoordFromBankPipe* pOutput ///< [out] pointer to extracted x/y bits
+ ) const
+{
+ UINT_32 yBit3 = 0;
+ UINT_32 yBit4 = 0;
+ UINT_32 yBit5 = 0;
+ UINT_32 yBit6 = 0;
+
+ UINT_32 xBit3 = 0;
+ UINT_32 xBit4 = 0;
+ UINT_32 xBit5 = 0;
+
+ UINT_32 tileSplitRotation;
+
+ UINT_32 numPipes = HwlGetPipes(pTileInfo);
+
+ UINT_32 bankRotation = ComputeBankRotation(tileMode,
+ pTileInfo->banks, numPipes);
+
+ UINT_32 pipeRotation = ComputePipeRotation(tileMode, numPipes);
+
+ UINT_32 xBit = x / (MicroTileWidth * pTileInfo->bankWidth * numPipes);
+ UINT_32 yBit = y / (MicroTileHeight * pTileInfo->bankHeight);
+
+ //calculate the bank and pipe before rotation and swizzle
+
+ switch (tileMode)
+ {
+ case ADDR_TM_2D_TILED_THIN1: //fall through
+ case ADDR_TM_2D_TILED_THICK: //fall through
+ case ADDR_TM_2D_TILED_XTHICK: //fall through
+ case ADDR_TM_3D_TILED_THIN1: //fall through
+ case ADDR_TM_3D_TILED_THICK: //fall through
+ case ADDR_TM_3D_TILED_XTHICK:
+ tileSplitRotation = ((pTileInfo->banks / 2) + 1);
+ break;
+ default:
+ tileSplitRotation = 0;
+ break;
+ }
+
+ UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode);
+
+ bank ^= tileSplitRotation * tileSlices;
+ if (pipeRotation == 0)
+ {
+ bank ^= bankRotation * (slice / microTileThickness) + bankSwizzle;
+ bank %= pTileInfo->banks;
+ pipe ^= pipeSwizzle;
+ }
+ else
+ {
+ bank ^= bankRotation * (slice / microTileThickness) / numPipes + bankSwizzle;
+ bank %= pTileInfo->banks;
+ pipe ^= pipeRotation * (slice / microTileThickness) + pipeSwizzle;
+ }
+
+ if (pTileInfo->macroAspectRatio == 1)
+ {
+ switch (pTileInfo->banks)
+ {
+ case 2:
+ yBit3 = _BIT(bank, 0) ^ _BIT(xBit,0);
+ break;
+ case 4:
+ yBit4 = _BIT(bank, 0) ^ _BIT(xBit,0);
+ yBit3 = _BIT(bank, 1) ^ _BIT(xBit,1);
+ break;
+ case 8:
+ yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
+ yBit5 = _BIT(bank, 0) ^ _BIT(xBit,0);
+ yBit4 = _BIT(bank, 1) ^ _BIT(xBit,1) ^ yBit5;
+ break;
+ case 16:
+ yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3);
+ yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2);
+ yBit6 = _BIT(bank, 0) ^ _BIT(xBit, 0);
+ yBit5 = _BIT(bank, 1) ^ _BIT(xBit, 1) ^ yBit6;
+ break;
+ default:
+ break;
+ }
+
+ }
+ else if (pTileInfo->macroAspectRatio == 2)
+ {
+ switch (pTileInfo->banks)
+ {
+ case 2: //xBit3 = yBit3^b0
+ xBit3 = _BIT(bank, 0) ^ _BIT(yBit,0);
+ break;
+ case 4: //xBit3=yBit4^b0; yBit3=xBit4^b1
+ xBit3 = _BIT(bank, 0) ^ _BIT(yBit,1);
+ yBit3 = _BIT(bank, 1) ^ _BIT(xBit,1);
+ break;
+ case 8: //xBit4, xBit5, yBit5 are known
+ xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2);
+ yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
+ yBit4 = _BIT(bank, 1) ^ _BIT(xBit,1) ^ _BIT(yBit, 2);
+ break;
+ case 16://x4,x5,x6,y6 are known
+ xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3); //x3 = y6 ^ b0
+ yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = x6 ^ b3
+ yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2); //y4 = x5 ^ b2
+ yBit5 = _BIT(bank, 1) ^ _BIT(xBit, 1) ^ _BIT(yBit, 3); //y5=x4^y6^b1
+ break;
+ default:
+ break;
+ }
+ }
+ else if (pTileInfo->macroAspectRatio == 4)
+ {
+ switch (pTileInfo->banks)
+ {
+ case 4: //yBit3, yBit4
+ xBit3 = _BIT(bank, 0) ^ _BIT(yBit,1);
+ xBit4 = _BIT(bank, 1) ^ _BIT(yBit,0);
+ break;
+ case 8: //xBit5, yBit4, yBit5
+ xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2);
+ yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
+ xBit4 = _BIT(bank, 1) ^ _BIT(yBit,1) ^ _BIT(yBit,2);
+ break;
+ case 16: //xBit5, xBit6, yBit5, yBit6
+ xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3);//x3 = b0 ^ y6
+ xBit4 = _BIT(bank, 1) ^ _BIT(yBit, 2) ^ _BIT(yBit, 3);//x4 = b1 ^ y5 ^ y6;
+ yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = b3 ^ x6;
+ yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2); //y4 = b2 ^ x5;
+ break;
+ default:
+ break;
+ }
+ }
+ else if (pTileInfo->macroAspectRatio == 8)
+ {
+ switch (pTileInfo->banks)
+ {
+ case 8: //yBit3, yBit4, yBit5
+ xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2); //x3 = b0 ^ y5;
+ xBit4 = _BIT(bank, 1) ^ _BIT(yBit,1) ^ _BIT(yBit, 2);//x4 = b1 ^ y4 ^ y5;
+ xBit5 = _BIT(bank, 2) ^ _BIT(yBit,0);
+ break;
+ case 16: //xBit6, yBit4, yBit5, yBit6
+ xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3);//x3 = y6 ^ b0
+ xBit4 = _BIT(bank, 1) ^ _BIT(yBit, 2) ^ _BIT(yBit, 3);//x4 = y5 ^ y6 ^ b1
+ xBit5 = _BIT(bank, 2) ^ _BIT(yBit, 1);//x5 = y4 ^ b2
+ yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = x6 ^ b3
+ break;
+ default:
+ break;
+ }
+ }
+
+ pOutput->xBits = xBit;
+ pOutput->yBits = yBit;
+
+ pOutput->xBit3 = xBit3;
+ pOutput->xBit4 = xBit4;
+ pOutput->xBit5 = xBit5;
+ pOutput->yBit3 = yBit3;
+ pOutput->yBit4 = yBit4;
+ pOutput->yBit5 = yBit5;
+ pOutput->yBit6 = yBit6;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlExtractBankPipeSwizzle
+* @brief
+* Entry of EgBasedAddrLib ExtractBankPipeSwizzle
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE EgBasedAddrLib::HwlExtractBankPipeSwizzle(
+ const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT* pIn, ///< [in] input structure
+ ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ ExtractBankPipeSwizzle(pIn->base256b,
+ pIn->pTileInfo,
+ &pOut->bankSwizzle,
+ &pOut->pipeSwizzle);
+
+ return ADDR_OK;
+}
+
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlCombineBankPipeSwizzle
+* @brief
+* Combine bank/pipe swizzle
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE EgBasedAddrLib::HwlCombineBankPipeSwizzle(
+ UINT_32 bankSwizzle, ///< [in] bank swizzle
+ UINT_32 pipeSwizzle, ///< [in] pipe swizzle
+ ADDR_TILEINFO* pTileInfo, ///< [in] tile info
+ UINT_64 baseAddr, ///< [in] base address
+ UINT_32* pTileSwizzle ///< [out] combined swizzle
+ ) const
+{
+ ADDR_E_RETURNCODE retCode = ADDR_OK;
+
+ if (pTileSwizzle)
+ {
+ *pTileSwizzle = GetBankPipeSwizzle(bankSwizzle, pipeSwizzle, baseAddr, pTileInfo);
+ }
+ else
+ {
+ retCode = ADDR_INVALIDPARAMS;
+ }
+
+ return retCode;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlComputeBaseSwizzle
+* @brief
+* Compute base swizzle
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeBaseSwizzle(
+ const ADDR_COMPUTE_BASE_SWIZZLE_INPUT* pIn,
+ ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut
+ ) const
+{
+ UINT_32 bankSwizzle = 0;
+ UINT_32 pipeSwizzle = 0;
+ ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
+
+ ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
+ ADDR_ASSERT(pIn->pTileInfo);
+
+ /// This is a legacy misreading of h/w doc, use it as it doesn't hurt.
+ static const UINT_8 bankRotationArray[4][16] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_2_BANK
+ { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_4_BANK
+ { 0, 3, 6, 1, 4, 7, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_8_BANK
+ { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }, // ADDR_SURF_16_BANK
+ };
+
+ UINT_32 banks = pTileInfo ? pTileInfo->banks : 2;
+ UINT_32 hwNumBanks;
+
+ // Uses less bank swizzle bits
+ if (pIn->option.reduceBankBit && banks > 2)
+ {
+ banks >>= 1;
+ }
+
+ switch (banks)
+ {
+ case 2:
+ hwNumBanks = 0;
+ break;
+ case 4:
+ hwNumBanks = 1;
+ break;
+ case 8:
+ hwNumBanks = 2;
+ break;
+ case 16:
+ hwNumBanks = 3;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ hwNumBanks = 0;
+ break;
+ }
+
+ if (pIn->option.genOption == ADDR_SWIZZLE_GEN_LINEAR)
+ {
+ bankSwizzle = pIn->surfIndex & (banks - 1);
+ }
+ else // (pIn->option.genOption == ADDR_SWIZZLE_GEN_DEFAULT)
+ {
+ bankSwizzle = bankRotationArray[hwNumBanks][pIn->surfIndex & (banks - 1)];
+ }
+
+ if (IsMacro3dTiled(pIn->tileMode))
+ {
+ pipeSwizzle = pIn->surfIndex & (HwlGetPipes(pTileInfo) - 1);
+ }
+
+ return HwlCombineBankPipeSwizzle(bankSwizzle, pipeSwizzle, pTileInfo, 0, &pOut->tileSwizzle);
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ExtractBankPipeSwizzle
+* @brief
+* Extract bank/pipe swizzle from base256b
+* @return
+* N/A
+***************************************************************************************************
+*/
+VOID EgBasedAddrLib::ExtractBankPipeSwizzle(
+ UINT_32 base256b, ///< [in] input base256b register value
+ ADDR_TILEINFO* pTileInfo, ///< [in] 2D tile parameters. Client must provide all data
+ UINT_32* pBankSwizzle, ///< [out] bank swizzle
+ UINT_32* pPipeSwizzle ///< [out] pipe swizzle
+ ) const
+{
+ UINT_32 bankSwizzle = 0;
+ UINT_32 pipeSwizzle = 0;
+
+ if (base256b != 0)
+ {
+ UINT_32 numPipes = HwlGetPipes(pTileInfo);
+ UINT_32 bankBits = QLog2(pTileInfo->banks);
+ UINT_32 pipeBits = QLog2(numPipes);
+ UINT_32 groupBytes = m_pipeInterleaveBytes;
+ UINT_32 bankInterleave = m_bankInterleave;
+
+ pipeSwizzle =
+ (base256b / (groupBytes >> 8)) & ((1<<pipeBits)-1);
+
+ bankSwizzle =
+ (base256b / (groupBytes >> 8) / numPipes / bankInterleave) & ((1 << bankBits) - 1);
+ }
+
+ *pPipeSwizzle = pipeSwizzle;
+ *pBankSwizzle = bankSwizzle;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::GetBankPipeSwizzle
+* @brief
+* Combine bank/pipe swizzle
+* @return
+* Base256b bits (only filled bank/pipe bits)
+***************************************************************************************************
+*/
+UINT_32 EgBasedAddrLib::GetBankPipeSwizzle(
+ UINT_32 bankSwizzle, ///< [in] bank swizzle
+ UINT_32 pipeSwizzle, ///< [in] pipe swizzle
+ UINT_64 baseAddr, ///< [in] base address
+ ADDR_TILEINFO* pTileInfo ///< [in] tile info
+ ) const
+{
+ UINT_32 pipeBits = QLog2(HwlGetPipes(pTileInfo));
+ UINT_32 bankInterleaveBits = QLog2(m_bankInterleave);
+ UINT_32 tileSwizzle = pipeSwizzle + ((bankSwizzle << bankInterleaveBits) << pipeBits);
+
+ baseAddr ^= tileSwizzle * m_pipeInterleaveBytes;
+ baseAddr >>= 8;
+
+ return static_cast<UINT_32>(baseAddr);
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeSliceTileSwizzle
+* @brief
+* Compute cubemap/3d texture faces/slices tile swizzle
+* @return
+* Tile swizzle
+***************************************************************************************************
+*/
+UINT_32 EgBasedAddrLib::ComputeSliceTileSwizzle(
+ AddrTileMode tileMode, ///< [in] Tile mode
+ UINT_32 baseSwizzle, ///< [in] Base swizzle
+ UINT_32 slice, ///< [in] Slice index, Cubemap face index, 0 means +X
+ UINT_64 baseAddr, ///< [in] Base address
+ ADDR_TILEINFO* pTileInfo ///< [in] Bank structure
+ ) const
+{
+ UINT_32 tileSwizzle = 0;
+
+ if (IsMacroTiled(tileMode)) // Swizzle only for macro tile mode
+ {
+ UINT_32 firstSlice = slice / ComputeSurfaceThickness(tileMode);
+
+ UINT_32 numPipes = HwlGetPipes(pTileInfo);
+ UINT_32 numBanks = pTileInfo->banks;
+
+ UINT_32 pipeRotation;
+ UINT_32 bankRotation;
+
+ UINT_32 bankSwizzle = 0;
+ UINT_32 pipeSwizzle = 0;
+
+ pipeRotation = ComputePipeRotation(tileMode, numPipes);
+ bankRotation = ComputeBankRotation(tileMode, numBanks, numPipes);
+
+ if (baseSwizzle != 0)
+ {
+ ExtractBankPipeSwizzle(baseSwizzle,
+ pTileInfo,
+ &bankSwizzle,
+ &pipeSwizzle);
+ }
+
+ if (pipeRotation == 0) //2D mode
+ {
+ bankSwizzle += firstSlice * bankRotation;
+ bankSwizzle %= numBanks;
+ }
+ else //3D mode
+ {
+ pipeSwizzle += firstSlice * pipeRotation;
+ pipeSwizzle %= numPipes;
+ bankSwizzle += firstSlice * bankRotation / numPipes;
+ bankSwizzle %= numBanks;
+ }
+
+ tileSwizzle = GetBankPipeSwizzle(bankSwizzle,
+ pipeSwizzle,
+ baseAddr,
+ pTileInfo);
+ }
+
+ return tileSwizzle;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlComputeQbStereoRightSwizzle
+*
+* @brief
+* Compute right eye swizzle
+* @return
+* swizzle
+***************************************************************************************************
+*/
+UINT_32 EgBasedAddrLib::HwlComputeQbStereoRightSwizzle(
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pInfo ///< [in] Surface info, must be valid
+ ) const
+{
+ UINT_32 bankBits = 0;
+ UINT_32 swizzle = 0;
+
+ // The assumption is default swizzle for left eye is 0
+ if (IsMacroTiled(pInfo->tileMode) && pInfo->pStereoInfo && pInfo->pTileInfo)
+ {
+ bankBits = ComputeBankFromCoord(0, pInfo->height, 0,
+ pInfo->tileMode, 0, 0, pInfo->pTileInfo);
+
+ if (bankBits)
+ {
+ HwlCombineBankPipeSwizzle(bankBits, 0, pInfo->pTileInfo, 0, &swizzle);
+ }
+ }
+
+ return swizzle;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeBankFromCoord
+*
+* @brief
+* Compute bank number from coordinates
+* @return
+* Bank number
+***************************************************************************************************
+*/
+UINT_32 EgBasedAddrLib::ComputeBankFromCoord(
+ UINT_32 x, ///< [in] x coordinate
+ UINT_32 y, ///< [in] y coordinate
+ UINT_32 slice, ///< [in] slice index
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 bankSwizzle, ///< [in] bank swizzle
+ UINT_32 tileSplitSlice, ///< [in] If the size of the pixel offset is larger than the
+ /// tile split size, then the pixel will be moved to a separate
+ /// slice. This value equals pixelOffset / tileSplitBytes
+ /// in this case. Otherwise this is 0.
+ ADDR_TILEINFO* pTileInfo ///< [in] tile info
+ ) const
+{
+ UINT_32 pipes = HwlGetPipes(pTileInfo);
+ UINT_32 bankBit0 = 0;
+ UINT_32 bankBit1 = 0;
+ UINT_32 bankBit2 = 0;
+ UINT_32 bankBit3 = 0;
+ UINT_32 sliceRotation;
+ UINT_32 tileSplitRotation;
+ UINT_32 bank;
+ UINT_32 numBanks = pTileInfo->banks;
+ UINT_32 bankWidth = pTileInfo->bankWidth;
+ UINT_32 bankHeight = pTileInfo->bankHeight;
+
+ UINT_32 tx = x / MicroTileWidth / (bankWidth * pipes);
+ UINT_32 ty = y / MicroTileHeight / bankHeight;
+
+ UINT_32 x3 = _BIT(tx,0);
+ UINT_32 x4 = _BIT(tx,1);
+ UINT_32 x5 = _BIT(tx,2);
+ UINT_32 x6 = _BIT(tx,3);
+ UINT_32 y3 = _BIT(ty,0);
+ UINT_32 y4 = _BIT(ty,1);
+ UINT_32 y5 = _BIT(ty,2);
+ UINT_32 y6 = _BIT(ty,3);
+
+ switch (numBanks)
+ {
+ case 16:
+ bankBit0 = x3 ^ y6;
+ bankBit1 = x4 ^ y5 ^ y6;
+ bankBit2 = x5 ^ y4;
+ bankBit3 = x6 ^ y3;
+ break;
+ case 8:
+ bankBit0 = x3 ^ y5;
+ bankBit1 = x4 ^ y4 ^ y5;
+ bankBit2 = x5 ^ y3;
+ break;
+ case 4:
+ bankBit0 = x3 ^ y4;
+ bankBit1 = x4 ^ y3;
+ break;
+ case 2:
+ bankBit0 = x3 ^ y3;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ break;
+ }
+
+ bank = bankBit0 | (bankBit1 << 1) | (bankBit2 << 2) | (bankBit3 << 3);
+
+ //Bits2Number(4, bankBit3, bankBit2, bankBit1, bankBit0);
+
+ bank = HwlPreAdjustBank((x / MicroTileWidth), bank, pTileInfo);
+ //
+ // Compute bank rotation for the slice.
+ //
+ UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode);
+
+ switch (tileMode)
+ {
+ case ADDR_TM_2D_TILED_THIN1: // fall through
+ case ADDR_TM_2D_TILED_THICK: // fall through
+ case ADDR_TM_2D_TILED_XTHICK:
+ sliceRotation = ((numBanks / 2) - 1) * (slice / microTileThickness);
+ break;
+ case ADDR_TM_3D_TILED_THIN1: // fall through
+ case ADDR_TM_3D_TILED_THICK: // fall through
+ case ADDR_TM_3D_TILED_XTHICK:
+ sliceRotation =
+ Max(1u, (pipes / 2) - 1) * (slice / microTileThickness) / pipes;
+ break;
+ default:
+ sliceRotation = 0;
+ break;
+ }
+
+
+ //
+ // Compute bank rotation for the tile split slice.
+ //
+ // The sample slice will be non-zero if samples must be split across multiple slices.
+ // This situation arises when the micro tile size multiplied yBit the number of samples exceeds
+ // the split size (set in GB_ADDR_CONFIG).
+ //
+ switch (tileMode)
+ {
+ case ADDR_TM_2D_TILED_THIN1: //fall through
+ case ADDR_TM_3D_TILED_THIN1: //fall through
+ case ADDR_TM_PRT_2D_TILED_THIN1: //fall through
+ case ADDR_TM_PRT_3D_TILED_THIN1: //fall through
+ tileSplitRotation = ((numBanks / 2) + 1) * tileSplitSlice;
+ break;
+ default:
+ tileSplitRotation = 0;
+ break;
+ }
+
+ //
+ // Apply bank rotation for the slice and tile split slice.
+ //
+ bank ^= bankSwizzle + sliceRotation;
+ bank ^= tileSplitRotation;
+
+ bank &= (numBanks - 1);
+
+ return bank;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeBankFromAddr
+*
+* @brief
+* Compute the bank number from an address
+* @return
+* Bank number
+***************************************************************************************************
+*/
+UINT_32 EgBasedAddrLib::ComputeBankFromAddr(
+ UINT_64 addr, ///< [in] address
+ UINT_32 numBanks, ///< [in] number of banks
+ UINT_32 numPipes ///< [in] number of pipes
+ ) const
+{
+ UINT_32 bank;
+
+ //
+ // The LSBs of the address are arranged as follows:
+ // bank | bankInterleave | pipe | pipeInterleave
+ //
+ // To get the bank number, shift off the pipe interleave, pipe, and bank interlave bits and
+ // mask the bank bits.
+ //
+ bank = static_cast<UINT_32>(
+ (addr >> Log2(m_pipeInterleaveBytes * numPipes * m_bankInterleave)) &
+ (numBanks - 1)
+ );
+
+ return bank;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputePipeRotation
+*
+* @brief
+* Compute pipe rotation value
+* @return
+* Pipe rotation
+***************************************************************************************************
+*/
+UINT_32 EgBasedAddrLib::ComputePipeRotation(
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 numPipes ///< [in] number of pipes
+ ) const
+{
+ UINT_32 rotation;
+
+ switch (tileMode)
+ {
+ case ADDR_TM_3D_TILED_THIN1: //fall through
+ case ADDR_TM_3D_TILED_THICK: //fall through
+ case ADDR_TM_3D_TILED_XTHICK: //fall through
+ case ADDR_TM_PRT_3D_TILED_THIN1: //fall through
+ case ADDR_TM_PRT_3D_TILED_THICK:
+ rotation = (numPipes < 4) ? 1 : (numPipes / 2 - 1);
+ break;
+ default:
+ rotation = 0;
+ }
+
+ return rotation;
+}
+
+
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeBankRotation
+*
+* @brief
+* Compute bank rotation value
+* @return
+* Bank rotation
+***************************************************************************************************
+*/
+UINT_32 EgBasedAddrLib::ComputeBankRotation(
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 numBanks, ///< [in] number of banks
+ UINT_32 numPipes ///< [in] number of pipes
+ ) const
+{
+ UINT_32 rotation;
+
+ switch (tileMode)
+ {
+ case ADDR_TM_2D_TILED_THIN1: // fall through
+ case ADDR_TM_2D_TILED_THICK: // fall through
+ case ADDR_TM_2D_TILED_XTHICK:
+ case ADDR_TM_PRT_2D_TILED_THIN1:
+ case ADDR_TM_PRT_2D_TILED_THICK:
+ // Rotate banks per Z-slice yBit 1 for 4-bank or 3 for 8-bank
+ rotation = numBanks / 2 - 1;
+ break;
+ case ADDR_TM_3D_TILED_THIN1: // fall through
+ case ADDR_TM_3D_TILED_THICK: // fall through
+ case ADDR_TM_3D_TILED_XTHICK:
+ case ADDR_TM_PRT_3D_TILED_THIN1:
+ case ADDR_TM_PRT_3D_TILED_THICK:
+ rotation = (numPipes < 4) ? 1 : (numPipes / 2 - 1); // rotate pipes & banks
+ break;
+ default:
+ rotation = 0;
+ }
+
+ return rotation;
+}
+
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeHtileBytes
+*
+* @brief
+* Compute htile size in bytes
+*
+* @return
+* Htile size in bytes
+***************************************************************************************************
+*/
+UINT_64 EgBasedAddrLib::ComputeHtileBytes(
+ UINT_32 pitch, ///< [in] pitch
+ UINT_32 height, ///< [in] height
+ UINT_32 bpp, ///< [in] bits per pixel
+ BOOL_32 isLinear, ///< [in] if it is linear mode
+ UINT_32 numSlices, ///< [in] number of slices
+ UINT_64* sliceBytes, ///< [out] bytes per slice
+ UINT_32 baseAlign ///< [in] base alignments
+ ) const
+{
+ UINT_64 surfBytes;
+
+ const UINT_64 HtileCacheLineSize = BITS_TO_BYTES(HtileCacheBits);
+
+ *sliceBytes = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp / 64);
+
+ if (m_configFlags.useHtileSliceAlign)
+ {
+ // Align the sliceSize to htilecachelinesize * pipes at first
+ *sliceBytes = PowTwoAlign(*sliceBytes, HtileCacheLineSize * m_pipes);
+ surfBytes = *sliceBytes * numSlices;
+ }
+ else
+ {
+ // Align the surfSize to htilecachelinesize * pipes at last
+ surfBytes = *sliceBytes * numSlices;
+ surfBytes = PowTwoAlign(surfBytes, HtileCacheLineSize * m_pipes);
+ }
+
+ return surfBytes;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::DispatchComputeFmaskInfo
+*
+* @brief
+* Compute fmask sizes include padded pitch, height, slices, total size in bytes,
+* meanwhile output suitable tile mode and alignments as well. Results are returned
+* through output parameters.
+*
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE EgBasedAddrLib::DispatchComputeFmaskInfo(
+ const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut) ///< [out] output structure
+{
+ ADDR_E_RETURNCODE retCode = ADDR_OK;
+
+ ADDR_COMPUTE_SURFACE_INFO_INPUT surfIn = {0};
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT surfOut = {0};
+
+ // Setup input structure
+ surfIn.tileMode = pIn->tileMode;
+ surfIn.width = pIn->pitch;
+ surfIn.height = pIn->height;
+ surfIn.numSlices = pIn->numSlices;
+ surfIn.pTileInfo = pIn->pTileInfo;
+ surfIn.tileType = ADDR_NON_DISPLAYABLE;
+ surfIn.flags.fmask = 1;
+
+ // Setup output structure
+ surfOut.pTileInfo = pOut->pTileInfo;
+
+ // Setup hwl specific fields
+ HwlFmaskPreThunkSurfInfo(pIn, pOut, &surfIn, &surfOut);
+
+ surfIn.bpp = HwlComputeFmaskBits(pIn, &surfIn.numSamples);
+
+ // ComputeSurfaceInfo needs numSamples in surfOut as surface routines need adjusted numSamples
+ surfOut.numSamples = surfIn.numSamples;
+
+ retCode = HwlComputeSurfaceInfo(&surfIn, &surfOut);
+
+ // Save bpp field for surface dump support
+ surfOut.bpp = surfIn.bpp;
+
+ if (retCode == ADDR_OK)
+ {
+ pOut->bpp = surfOut.bpp;
+ pOut->pitch = surfOut.pitch;
+ pOut->height = surfOut.height;
+ pOut->numSlices = surfOut.depth;
+ pOut->fmaskBytes = surfOut.surfSize;
+ pOut->baseAlign = surfOut.baseAlign;
+ pOut->pitchAlign = surfOut.pitchAlign;
+ pOut->heightAlign = surfOut.heightAlign;
+
+ if (surfOut.depth > 1)
+ {
+ // For fmask, expNumSlices is stored in depth.
+ pOut->sliceSize = surfOut.surfSize / surfOut.depth;
+ }
+ else
+ {
+ pOut->sliceSize = surfOut.surfSize;
+ }
+
+ // Save numSamples field for surface dump support
+ pOut->numSamples = surfOut.numSamples;
+
+ HwlFmaskPostThunkSurfInfo(&surfOut, pOut);
+ }
+
+ return retCode;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlFmaskSurfaceInfo
+* @brief
+* Entry of EgBasedAddrLib ComputeFmaskInfo
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeFmaskInfo(
+ const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure
+ )
+{
+ ADDR_E_RETURNCODE retCode = ADDR_OK;
+
+ ADDR_TILEINFO tileInfo = {0};
+
+ // Use internal tile info if pOut does not have a valid pTileInfo
+ if (pOut->pTileInfo == NULL)
+ {
+ pOut->pTileInfo = &tileInfo;
+ }
+
+ retCode = DispatchComputeFmaskInfo(pIn, pOut);
+
+ if (retCode == ADDR_OK)
+ {
+ pOut->tileIndex =
+ HwlPostCheckTileIndex(pOut->pTileInfo, pIn->tileMode, ADDR_NON_DISPLAYABLE,
+ pOut->tileIndex);
+ }
+
+ // Resets pTileInfo to NULL if the internal tile info is used
+ if (pOut->pTileInfo == &tileInfo)
+ {
+ pOut->pTileInfo = NULL;
+ }
+
+ return retCode;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlComputeFmaskAddrFromCoord
+* @brief
+* Entry of EgBasedAddrLib ComputeFmaskAddrFromCoord
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeFmaskAddrFromCoord(
+ const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ ADDR_E_RETURNCODE retCode = ADDR_OK;
+
+#if ADDR_AM_BUILD
+ if ((pIn->x > pIn->pitch) ||
+ (pIn->y > pIn->height) ||
+ (pIn->numSamples > m_maxSamples) ||
+ (pIn->sample >= m_maxSamples))
+ {
+ retCode = ADDR_INVALIDPARAMS;
+ }
+ else
+ {
+ pOut->addr = DispatchComputeFmaskAddrFromCoord(pIn, pOut);
+ }
+#endif
+
+ return retCode;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlComputeFmaskCoordFromAddr
+* @brief
+* Entry of EgBasedAddrLib ComputeFmaskCoordFromAddr
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeFmaskCoordFromAddr(
+ const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ ADDR_E_RETURNCODE retCode = ADDR_OK;
+
+#if ADDR_AM_BUILD
+ if ((pIn->bitPosition >= 8) ||
+ (pIn->numSamples > m_maxSamples))
+ {
+ retCode = ADDR_INVALIDPARAMS;
+ }
+ else
+ {
+ DispatchComputeFmaskCoordFromAddr(pIn, pOut);
+ }
+#endif
+
+ return retCode;
+}
+
+#if ADDR_AM_BUILD
+/**
+***************************************************************************************************
+* EgBasedAddrLib::DispatchComputeFmaskAddrFromCoord
+*
+* @brief
+* Computes the FMASK address and bit position from a coordinate.
+* @return
+* The byte address
+***************************************************************************************************
+*/
+UINT_64 EgBasedAddrLib::DispatchComputeFmaskAddrFromCoord(
+ const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ UINT_32 x = pIn->x;
+ UINT_32 y = pIn->y;
+ UINT_32 slice = pIn->slice;
+ UINT_32 sample = pIn->sample;
+ UINT_32 plane = pIn->plane;
+ UINT_32 pitch = pIn->pitch;
+ UINT_32 height = pIn->height;
+ UINT_32 numSamples = pIn->numSamples;
+ AddrTileMode tileMode = pIn->tileMode;
+ BOOL_32 ignoreSE = pIn->ignoreSE;
+ ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
+ BOOL_32 resolved = pIn->resolved;
+
+ UINT_32* pBitPosition = &pOut->bitPosition;
+ UINT_64 addr = 0;
+
+ ADDR_ASSERT(numSamples > 1);
+ ADDR_ASSERT(ComputeSurfaceThickness(tileMode) == 1);
+
+ switch (tileMode)
+ {
+ case ADDR_TM_1D_TILED_THIN1:
+ addr = ComputeFmaskAddrFromCoordMicroTiled(x,
+ y,
+ slice,
+ sample,
+ plane,
+ pitch,
+ height,
+ numSamples,
+ tileMode,
+ resolved,
+ pBitPosition);
+ break;
+ case ADDR_TM_2D_TILED_THIN1: //fall through
+ case ADDR_TM_3D_TILED_THIN1:
+ UINT_32 pipeSwizzle;
+ UINT_32 bankSwizzle;
+
+ if (m_configFlags.useCombinedSwizzle)
+ {
+ ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo,
+ &bankSwizzle, &pipeSwizzle);
+ }
+ else
+ {
+ pipeSwizzle = pIn->pipeSwizzle;
+ bankSwizzle = pIn->bankSwizzle;
+ }
+
+ addr = ComputeFmaskAddrFromCoordMacroTiled(x,
+ y,
+ slice,
+ sample,
+ plane,
+ pitch,
+ height,
+ numSamples,
+ tileMode,
+ pipeSwizzle,
+ bankSwizzle,
+ ignoreSE,
+ pTileInfo,
+ resolved,
+ pBitPosition);
+ break;
+ default:
+ *pBitPosition = 0;
+ break;
+ }
+
+ return addr;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeFmaskAddrFromCoordMicroTiled
+*
+* @brief
+* Computes the FMASK address and bit position from a coordinate for 1D tilied (micro
+* tiled)
+* @return
+* The byte address
+***************************************************************************************************
+*/
+UINT_64 EgBasedAddrLib::ComputeFmaskAddrFromCoordMicroTiled(
+ UINT_32 x, ///< [in] x coordinate
+ UINT_32 y, ///< [in] y coordinate
+ UINT_32 slice, ///< [in] slice index
+ UINT_32 sample, ///< [in] sample number
+ UINT_32 plane, ///< [in] plane number
+ UINT_32 pitch, ///< [in] surface pitch in pixels
+ UINT_32 height, ///< [in] surface height in pixels
+ UINT_32 numSamples, ///< [in] number of samples
+ AddrTileMode tileMode, ///< [in] tile mode
+ BOOL_32 resolved, ///< [in] TRUE if this is for resolved fmask
+ UINT_32* pBitPosition ///< [out] pointer to returned bit position
+ ) const
+{
+ UINT_64 addr = 0;
+ UINT_32 effectiveBpp;
+ UINT_32 effectiveSamples;
+
+ //
+ // 2xAA use the same layout as 4xAA
+ //
+ if (numSamples == 2)
+ {
+ numSamples = 4;
+ }
+
+ //
+ // Compute the number of planes.
+ //
+ if (!resolved)
+ {
+ effectiveSamples = ComputeFmaskNumPlanesFromNumSamples(numSamples);
+ effectiveBpp = numSamples;
+
+ //
+ // Compute the address just like a color surface with numSamples bits per element and
+ // numPlanes samples.
+ //
+ addr = ComputeSurfaceAddrFromCoordMicroTiled(x,
+ y,
+ slice,
+ plane, // sample
+ effectiveBpp,
+ pitch,
+ height,
+ effectiveSamples,
+ tileMode,
+ ADDR_NON_DISPLAYABLE,
+ FALSE,
+ pBitPosition);
+
+ //
+ // Compute the real bit position. Each (sample, plane) is stored with one bit per sample.
+ //
+
+ //
+ // Compute the pixel index with in the micro tile
+ //
+ UINT_32 pixelIndex = ComputePixelIndexWithinMicroTile(x % 8,
+ y % 8,
+ slice,
+ 1,
+ tileMode,
+ ADDR_NON_DISPLAYABLE);
+
+ *pBitPosition = ((pixelIndex * numSamples) + sample) & (BITS_PER_BYTE-1);
+
+ UINT_64 bitAddr = BYTES_TO_BITS(addr) + *pBitPosition;
+
+ addr = bitAddr / 8;
+ }
+ else
+ {
+ effectiveBpp = ComputeFmaskResolvedBppFromNumSamples(numSamples);
+ effectiveSamples = 1;
+
+ //
+ // Compute the address just like a color surface with numSamples bits per element and
+ // numPlanes samples.
+ //
+ addr = ComputeSurfaceAddrFromCoordMicroTiled(x,
+ y,
+ slice,
+ sample,
+ effectiveBpp,
+ pitch,
+ height,
+ effectiveSamples,
+ tileMode,
+ ADDR_NON_DISPLAYABLE,
+ TRUE,
+ pBitPosition);
+ }
+
+ return addr;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeFmaskAddrFromCoordMacroTiled
+*
+* @brief
+* Computes the FMASK address and bit position from a coordinate for 2D tilied (macro
+* tiled)
+* @return
+* The byte address
+***************************************************************************************************
+*/
+UINT_64 EgBasedAddrLib::ComputeFmaskAddrFromCoordMacroTiled(
+ UINT_32 x, ///< [in] x coordinate
+ UINT_32 y, ///< [in] y coordinate
+ UINT_32 slice, ///< [in] slice index
+ UINT_32 sample, ///< [in] sample number
+ UINT_32 plane, ///< [in] plane number
+ UINT_32 pitch, ///< [in] surface pitch in pixels
+ UINT_32 height, ///< [in] surface height in pixels
+ UINT_32 numSamples, ///< [in] number of samples
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 pipeSwizzle, ///< [in] pipe swizzle
+ UINT_32 bankSwizzle, ///< [in] bank swizzle
+ BOOL_32 ignoreSE, ///< [in] TRUE if ignore shader engine
+ ADDR_TILEINFO* pTileInfo, ///< [in] bank structure.**All fields to be valid on entry**
+ BOOL_32 resolved, ///< [in] TRUE if this is for resolved fmask
+ UINT_32* pBitPosition ///< [out] pointer to returned bit position
+ ) const
+{
+ UINT_64 addr = 0;
+ UINT_32 effectiveBpp;
+ UINT_32 effectiveSamples;
+
+ //
+ // 2xAA use the same layout as 4xAA
+ //
+ if (numSamples == 2)
+ {
+ numSamples = 4;
+ }
+
+ //
+ // Compute the number of planes.
+ //
+ if (!resolved)
+ {
+ effectiveSamples = ComputeFmaskNumPlanesFromNumSamples(numSamples);
+ effectiveBpp = numSamples;
+
+ //
+ // Compute the address just like a color surface with numSamples bits per element and
+ // numPlanes samples.
+ //
+ addr = ComputeSurfaceAddrFromCoordMacroTiled(x,
+ y,
+ slice,
+ plane, // sample
+ effectiveBpp,
+ pitch,
+ height,
+ effectiveSamples,
+ tileMode,
+ ADDR_NON_DISPLAYABLE,// isdisp
+ ignoreSE,// ignore_shader
+ FALSE,// depth_sample_order
+ pipeSwizzle,
+ bankSwizzle,
+ pTileInfo,
+ pBitPosition);
+
+ //
+ // Compute the real bit position. Each (sample, plane) is stored with one bit per sample.
+ //
+
+
+ //
+ // Compute the pixel index with in the micro tile
+ //
+ UINT_32 pixelIndex = ComputePixelIndexWithinMicroTile(x ,
+ y ,
+ slice,
+ effectiveBpp,
+ tileMode,
+ ADDR_NON_DISPLAYABLE);
+
+ *pBitPosition = ((pixelIndex * numSamples) + sample) & (BITS_PER_BYTE-1);
+
+ UINT_64 bitAddr = BYTES_TO_BITS(addr) + *pBitPosition;
+
+ addr = bitAddr / 8;
+
+ }
+ else
+ {
+ effectiveBpp = ComputeFmaskResolvedBppFromNumSamples(numSamples);
+ effectiveSamples = 1;
+
+ //
+ // Compute the address just like a color surface with numSamples bits per element and
+ // numPlanes samples.
+ //
+ addr = ComputeSurfaceAddrFromCoordMacroTiled(x,
+ y,
+ slice,
+ sample,
+ effectiveBpp,
+ pitch,
+ height,
+ effectiveSamples,
+ tileMode,
+ ADDR_NON_DISPLAYABLE,
+ ignoreSE,
+ TRUE,
+ pipeSwizzle,
+ bankSwizzle,
+ pTileInfo,
+ pBitPosition);
+ }
+
+ return addr;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeFmaskCoordFromAddrMicroTiled
+*
+* @brief
+* Compute (x,y,slice,sample,plane) coordinates from fmask address
+* @return
+* N/A
+*
+***************************************************************************************************
+*/
+VOID EgBasedAddrLib::ComputeFmaskCoordFromAddrMicroTiled(
+ UINT_64 addr, ///< [in] byte address
+ UINT_32 bitPosition,///< [in] bit position
+ UINT_32 pitch, ///< [in] pitch in pixels
+ UINT_32 height, ///< [in] height in pixels
+ UINT_32 numSamples, ///< [in] number of samples (of color buffer)
+ AddrTileMode tileMode, ///< [in] tile mode
+ BOOL_32 resolved, ///< [in] TRUE if it is resolved fmask
+ UINT_32* pX, ///< [out] X coord
+ UINT_32* pY, ///< [out] Y coord
+ UINT_32* pSlice, ///< [out] slice index
+ UINT_32* pSample, ///< [out] sample index
+ UINT_32* pPlane ///< [out] plane index
+ ) const
+{
+ UINT_32 effectiveBpp;
+ UINT_32 effectiveSamples;
+
+ // 2xAA use the same layout as 4xAA
+ if (numSamples == 2)
+ {
+ numSamples = 4;
+ }
+
+ if (!resolved)
+ {
+ effectiveSamples = ComputeFmaskNumPlanesFromNumSamples(numSamples);
+ effectiveBpp = numSamples;
+
+ ComputeSurfaceCoordFromAddrMicroTiled(addr,
+ bitPosition,
+ effectiveBpp,
+ pitch,
+ height,
+ effectiveSamples,
+ tileMode,
+ 0, // tileBase
+ 0, // compBits
+ pX,
+ pY,
+ pSlice,
+ pPlane,
+ ADDR_NON_DISPLAYABLE, // microTileType
+ FALSE // isDepthSampleOrder
+ );
+
+
+ if ( pSample )
+ {
+ *pSample = bitPosition % numSamples;
+ }
+ }
+ else
+ {
+ effectiveBpp = ComputeFmaskResolvedBppFromNumSamples(numSamples);
+ effectiveSamples = 1;
+
+ ComputeSurfaceCoordFromAddrMicroTiled(addr,
+ bitPosition,
+ effectiveBpp,
+ pitch,
+ height,
+ effectiveSamples,
+ tileMode,
+ 0, // tileBase
+ 0, // compBits
+ pX,
+ pY,
+ pSlice,
+ pSample,
+ ADDR_NON_DISPLAYABLE, // microTileType
+ TRUE // isDepthSampleOrder
+ );
+ }
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeFmaskCoordFromAddrMacroTiled
+*
+* @brief
+* Compute (x,y,slice,sample,plane) coordinates from
+* fmask address
+* @return
+* N/A
+*
+***************************************************************************************************
+*/
+VOID EgBasedAddrLib::ComputeFmaskCoordFromAddrMacroTiled(
+ UINT_64 addr, ///< [in] byte address
+ UINT_32 bitPosition,///< [in] bit position
+ UINT_32 pitch, ///< [in] pitch in pixels
+ UINT_32 height, ///< [in] height in pixels
+ UINT_32 numSamples, ///< [in] number of samples (of color buffer)
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 pipeSwizzle,///< [in] pipe swizzle
+ UINT_32 bankSwizzle,///< [in] bank swizzle
+ BOOL_32 ignoreSE, ///< [in] TRUE if ignore shader engine
+ ADDR_TILEINFO* pTileInfo, ///< [in] bank structure. **All fields to be valid on entry**
+ BOOL_32 resolved, ///< [in] TRUE if it is resolved fmask
+ UINT_32* pX, ///< [out] X coord
+ UINT_32* pY, ///< [out] Y coord
+ UINT_32* pSlice, ///< [out] slice index
+ UINT_32* pSample, ///< [out] sample index
+ UINT_32* pPlane ///< [out] plane index
+ ) const
+{
+ UINT_32 effectiveBpp;
+ UINT_32 effectiveSamples;
+
+ // 2xAA use the same layout as 4xAA
+ if (numSamples == 2)
+ {
+ numSamples = 4;
+ }
+
+ //
+ // Compute the number of planes.
+ //
+ if (!resolved)
+ {
+ effectiveSamples = ComputeFmaskNumPlanesFromNumSamples(numSamples);
+ effectiveBpp = numSamples;
+
+ ComputeSurfaceCoordFromAddrMacroTiled(addr,
+ bitPosition,
+ effectiveBpp,
+ pitch,
+ height,
+ effectiveSamples,
+ tileMode,
+ 0, // No tileBase
+ 0, // No compBits
+ ADDR_NON_DISPLAYABLE,
+ ignoreSE,
+ FALSE,
+ pipeSwizzle,
+ bankSwizzle,
+ pTileInfo,
+ pX,
+ pY,
+ pSlice,
+ pPlane);
+
+ if (pSample)
+ {
+ *pSample = bitPosition % numSamples;
+ }
+ }
+ else
+ {
+ effectiveBpp = ComputeFmaskResolvedBppFromNumSamples(numSamples);
+ effectiveSamples = 1;
+
+ ComputeSurfaceCoordFromAddrMacroTiled(addr,
+ bitPosition,
+ effectiveBpp,
+ pitch,
+ height,
+ effectiveSamples,
+ tileMode,
+ 0, // No tileBase
+ 0, // No compBits
+ ADDR_NON_DISPLAYABLE,
+ ignoreSE,
+ TRUE,
+ pipeSwizzle,
+ bankSwizzle,
+ pTileInfo,
+ pX,
+ pY,
+ pSlice,
+ pSample);
+ }
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::DispatchComputeFmaskCoordFromAddr
+*
+* @brief
+* Compute (x,y,slice,sample,plane) coordinates from
+* fmask address
+* @return
+* N/A
+*
+***************************************************************************************************
+*/
+VOID EgBasedAddrLib::DispatchComputeFmaskCoordFromAddr(
+ const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ UINT_64 addr = pIn->addr;
+ UINT_32 bitPosition = pIn->bitPosition;
+ UINT_32 pitch = pIn->pitch;
+ UINT_32 height = pIn->height;
+ UINT_32 numSamples = pIn->numSamples;
+ AddrTileMode tileMode = pIn->tileMode;
+ BOOL_32 ignoreSE = pIn->ignoreSE;
+ ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
+ BOOL_32 resolved = pIn->resolved;
+
+ UINT_32* pX = &pOut->x;
+ UINT_32* pY = &pOut->y;
+ UINT_32* pSlice = &pOut->slice;
+ UINT_32* pSample = &pOut->sample;
+ UINT_32* pPlane = &pOut->plane;
+
+ switch (tileMode)
+ {
+ case ADDR_TM_1D_TILED_THIN1:
+ ComputeFmaskCoordFromAddrMicroTiled(addr,
+ bitPosition,
+ pitch,
+ height,
+ numSamples,
+ tileMode,
+ resolved,
+ pX,
+ pY,
+ pSlice,
+ pSample,
+ pPlane);
+ break;
+ case ADDR_TM_2D_TILED_THIN1://fall through
+ case ADDR_TM_3D_TILED_THIN1:
+ UINT_32 pipeSwizzle;
+ UINT_32 bankSwizzle;
+
+ if (m_configFlags.useCombinedSwizzle)
+ {
+ ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo,
+ &bankSwizzle, &pipeSwizzle);
+ }
+ else
+ {
+ pipeSwizzle = pIn->pipeSwizzle;
+ bankSwizzle = pIn->bankSwizzle;
+ }
+
+ ComputeFmaskCoordFromAddrMacroTiled(addr,
+ bitPosition,
+ pitch,
+ height,
+ numSamples,
+ tileMode,
+ pipeSwizzle,
+ bankSwizzle,
+ ignoreSE,
+ pTileInfo,
+ resolved,
+ pX,
+ pY,
+ pSlice,
+ pSample,
+ pPlane);
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ break;
+
+ }
+}
+#endif
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeFmaskNumPlanesFromNumSamples
+*
+* @brief
+* Compute fmask number of planes from number of samples
+*
+* @return
+* Number of planes
+***************************************************************************************************
+*/
+UINT_32 EgBasedAddrLib::ComputeFmaskNumPlanesFromNumSamples(
+ UINT_32 numSamples) ///< [in] number of samples
+{
+ UINT_32 numPlanes;
+
+ //
+ // FMASK is stored such that each micro tile is composed of elements containing N bits, where
+ // N is the number of samples. There is a micro tile for each bit in the FMASK address, and
+ // micro tiles for each address bit, sometimes referred to as a plane, are stored sequentially.
+ // The FMASK for a 2-sample surface looks like a general surface with 2 bits per element.
+ // The FMASK for a 4-sample surface looks like a general surface with 4 bits per element and
+ // 2 samples. The FMASK for an 8-sample surface looks like a general surface with 8 bits per
+ // element and 4 samples. R6xx and R7xx only stored 3 planes for 8-sample FMASK surfaces.
+ // This was changed for R8xx to simplify the logic in the CB.
+ //
+ switch (numSamples)
+ {
+ case 2:
+ numPlanes = 1;
+ break;
+ case 4:
+ numPlanes = 2;
+ break;
+ case 8:
+ numPlanes = 4;
+ break;
+ default:
+ ADDR_UNHANDLED_CASE();
+ numPlanes = 0;
+ break;
+ }
+ return numPlanes;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::ComputeFmaskResolvedBppFromNumSamples
+*
+* @brief
+* Compute resolved fmask effective bpp based on number of samples
+*
+* @return
+* bpp
+***************************************************************************************************
+*/
+UINT_32 EgBasedAddrLib::ComputeFmaskResolvedBppFromNumSamples(
+ UINT_32 numSamples) ///< number of samples
+{
+ UINT_32 bpp;
+
+ //
+ // Resolved FMASK surfaces are generated yBit the CB and read yBit the texture unit
+ // so that the texture unit can read compressed multi-sample color data.
+ // These surfaces store each index value packed per element.
+ // Each element contains at least num_samples * log2(num_samples) bits.
+ // Resolved FMASK surfaces are addressed as follows:
+ // 2-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
+ // 4-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
+ // 8-sample Addressed similarly to a color surface with 32 bits per element and 1 sample.
+
+ switch (numSamples)
+ {
+ case 2:
+ bpp = 8;
+ break;
+ case 4:
+ bpp = 8;
+ break;
+ case 8:
+ bpp = 32;
+ break;
+ default:
+ ADDR_UNHANDLED_CASE();
+ bpp = 0;
+ break;
+ }
+ return bpp;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::IsTileInfoAllZero
+*
+* @brief
+* Return TRUE if all field are zero
+* @note
+* Since NULL input is consider to be all zero
+***************************************************************************************************
+*/
+BOOL_32 EgBasedAddrLib::IsTileInfoAllZero(
+ ADDR_TILEINFO* pTileInfo)
+{
+ BOOL_32 allZero = TRUE;
+
+ if (pTileInfo)
+ {
+ if ((pTileInfo->banks != 0) ||
+ (pTileInfo->bankWidth != 0) ||
+ (pTileInfo->bankHeight != 0) ||
+ (pTileInfo->macroAspectRatio != 0) ||
+ (pTileInfo->tileSplitBytes != 0) ||
+ (pTileInfo->pipeConfig != 0)
+ )
+ {
+ allZero = FALSE;
+ }
+ }
+
+ return allZero;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlTileInfoEqual
+*
+* @brief
+* Return TRUE if all field are equal
+* @note
+* Only takes care of current HWL's data
+***************************************************************************************************
+*/
+BOOL_32 EgBasedAddrLib::HwlTileInfoEqual(
+ const ADDR_TILEINFO* pLeft, ///<[in] Left compare operand
+ const ADDR_TILEINFO* pRight ///<[in] Right compare operand
+ ) const
+{
+ BOOL_32 equal = FALSE;
+
+ if (pLeft->banks == pRight->banks &&
+ pLeft->bankWidth == pRight->bankWidth &&
+ pLeft->bankHeight == pRight->bankHeight &&
+ pLeft->macroAspectRatio == pRight->macroAspectRatio &&
+ pLeft->tileSplitBytes == pRight->tileSplitBytes)
+ {
+ equal = TRUE;
+ }
+
+ return equal;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlConvertTileInfoToHW
+* @brief
+* Entry of EgBasedAddrLib ConvertTileInfoToHW
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE EgBasedAddrLib::HwlConvertTileInfoToHW(
+ const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure
+ ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ ADDR_E_RETURNCODE retCode = ADDR_OK;
+
+ ADDR_TILEINFO *pTileInfoIn = pIn->pTileInfo;
+ ADDR_TILEINFO *pTileInfoOut = pOut->pTileInfo;
+
+ if ((pTileInfoIn != NULL) && (pTileInfoOut != NULL))
+ {
+ if (pIn->reverse == FALSE)
+ {
+ switch (pTileInfoIn->banks)
+ {
+ case 2:
+ pTileInfoOut->banks = 0;
+ break;
+ case 4:
+ pTileInfoOut->banks = 1;
+ break;
+ case 8:
+ pTileInfoOut->banks = 2;
+ break;
+ case 16:
+ pTileInfoOut->banks = 3;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ retCode = ADDR_INVALIDPARAMS;
+ pTileInfoOut->banks = 0;
+ break;
+ }
+
+ switch (pTileInfoIn->bankWidth)
+ {
+ case 1:
+ pTileInfoOut->bankWidth = 0;
+ break;
+ case 2:
+ pTileInfoOut->bankWidth = 1;
+ break;
+ case 4:
+ pTileInfoOut->bankWidth = 2;
+ break;
+ case 8:
+ pTileInfoOut->bankWidth = 3;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ retCode = ADDR_INVALIDPARAMS;
+ pTileInfoOut->bankWidth = 0;
+ break;
+ }
+
+ switch (pTileInfoIn->bankHeight)
+ {
+ case 1:
+ pTileInfoOut->bankHeight = 0;
+ break;
+ case 2:
+ pTileInfoOut->bankHeight = 1;
+ break;
+ case 4:
+ pTileInfoOut->bankHeight = 2;
+ break;
+ case 8:
+ pTileInfoOut->bankHeight = 3;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ retCode = ADDR_INVALIDPARAMS;
+ pTileInfoOut->bankHeight = 0;
+ break;
+ }
+
+ switch (pTileInfoIn->macroAspectRatio)
+ {
+ case 1:
+ pTileInfoOut->macroAspectRatio = 0;
+ break;
+ case 2:
+ pTileInfoOut->macroAspectRatio = 1;
+ break;
+ case 4:
+ pTileInfoOut->macroAspectRatio = 2;
+ break;
+ case 8:
+ pTileInfoOut->macroAspectRatio = 3;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ retCode = ADDR_INVALIDPARAMS;
+ pTileInfoOut->macroAspectRatio = 0;
+ break;
+ }
+
+ switch (pTileInfoIn->tileSplitBytes)
+ {
+ case 64:
+ pTileInfoOut->tileSplitBytes = 0;
+ break;
+ case 128:
+ pTileInfoOut->tileSplitBytes = 1;
+ break;
+ case 256:
+ pTileInfoOut->tileSplitBytes = 2;
+ break;
+ case 512:
+ pTileInfoOut->tileSplitBytes = 3;
+ break;
+ case 1024:
+ pTileInfoOut->tileSplitBytes = 4;
+ break;
+ case 2048:
+ pTileInfoOut->tileSplitBytes = 5;
+ break;
+ case 4096:
+ pTileInfoOut->tileSplitBytes = 6;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ retCode = ADDR_INVALIDPARAMS;
+ pTileInfoOut->tileSplitBytes = 0;
+ break;
+ }
+ }
+ else
+ {
+ switch (pTileInfoIn->banks)
+ {
+ case 0:
+ pTileInfoOut->banks = 2;
+ break;
+ case 1:
+ pTileInfoOut->banks = 4;
+ break;
+ case 2:
+ pTileInfoOut->banks = 8;
+ break;
+ case 3:
+ pTileInfoOut->banks = 16;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ retCode = ADDR_INVALIDPARAMS;
+ pTileInfoOut->banks = 2;
+ break;
+ }
+
+ switch (pTileInfoIn->bankWidth)
+ {
+ case 0:
+ pTileInfoOut->bankWidth = 1;
+ break;
+ case 1:
+ pTileInfoOut->bankWidth = 2;
+ break;
+ case 2:
+ pTileInfoOut->bankWidth = 4;
+ break;
+ case 3:
+ pTileInfoOut->bankWidth = 8;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ retCode = ADDR_INVALIDPARAMS;
+ pTileInfoOut->bankWidth = 1;
+ break;
+ }
+
+ switch (pTileInfoIn->bankHeight)
+ {
+ case 0:
+ pTileInfoOut->bankHeight = 1;
+ break;
+ case 1:
+ pTileInfoOut->bankHeight = 2;
+ break;
+ case 2:
+ pTileInfoOut->bankHeight = 4;
+ break;
+ case 3:
+ pTileInfoOut->bankHeight = 8;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ retCode = ADDR_INVALIDPARAMS;
+ pTileInfoOut->bankHeight = 1;
+ break;
+ }
+
+ switch (pTileInfoIn->macroAspectRatio)
+ {
+ case 0:
+ pTileInfoOut->macroAspectRatio = 1;
+ break;
+ case 1:
+ pTileInfoOut->macroAspectRatio = 2;
+ break;
+ case 2:
+ pTileInfoOut->macroAspectRatio = 4;
+ break;
+ case 3:
+ pTileInfoOut->macroAspectRatio = 8;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ retCode = ADDR_INVALIDPARAMS;
+ pTileInfoOut->macroAspectRatio = 1;
+ break;
+ }
+
+ switch (pTileInfoIn->tileSplitBytes)
+ {
+ case 0:
+ pTileInfoOut->tileSplitBytes = 64;
+ break;
+ case 1:
+ pTileInfoOut->tileSplitBytes = 128;
+ break;
+ case 2:
+ pTileInfoOut->tileSplitBytes = 256;
+ break;
+ case 3:
+ pTileInfoOut->tileSplitBytes = 512;
+ break;
+ case 4:
+ pTileInfoOut->tileSplitBytes = 1024;
+ break;
+ case 5:
+ pTileInfoOut->tileSplitBytes = 2048;
+ break;
+ case 6:
+ pTileInfoOut->tileSplitBytes = 4096;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ retCode = ADDR_INVALIDPARAMS;
+ pTileInfoOut->tileSplitBytes = 64;
+ break;
+ }
+ }
+
+ if (pTileInfoIn != pTileInfoOut)
+ {
+ pTileInfoOut->pipeConfig = pTileInfoIn->pipeConfig;
+ }
+ }
+ else
+ {
+ ADDR_ASSERT_ALWAYS();
+ retCode = ADDR_INVALIDPARAMS;
+ }
+
+ return retCode;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlComputeSurfaceInfo
+* @brief
+* Entry of EgBasedAddrLib ComputeSurfaceInfo
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeSurfaceInfo(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ ADDR_E_RETURNCODE retCode = ADDR_OK;
+
+ if (pIn->numSamples < pIn->numFrags)
+ {
+ retCode = ADDR_INVALIDPARAMS;
+ }
+
+ ADDR_TILEINFO tileInfo = {0};
+
+ if (retCode == ADDR_OK)
+ {
+ // Uses internal tile info if pOut does not have a valid pTileInfo
+ if (pOut->pTileInfo == NULL)
+ {
+ pOut->pTileInfo = &tileInfo;
+ }
+
+ if (!DispatchComputeSurfaceInfo(pIn, pOut))
+ {
+ retCode = ADDR_INVALIDPARAMS;
+ }
+
+ // Returns an index
+ pOut->tileIndex = HwlPostCheckTileIndex(pOut->pTileInfo,
+ pOut->tileMode,
+ pOut->tileType,
+ pOut->tileIndex);
+
+ if (IsMacroTiled(pOut->tileMode) && (pOut->macroModeIndex == TileIndexInvalid))
+ {
+ pOut->macroModeIndex = HwlComputeMacroModeIndex(pOut->tileIndex,
+ pIn->flags,
+ pIn->bpp,
+ pIn->numSamples,
+ pOut->pTileInfo);
+ }
+
+ // Resets pTileInfo to NULL if the internal tile info is used
+ if (pOut->pTileInfo == &tileInfo)
+ {
+#if DEBUG
+ // Client does not pass in a valid pTileInfo
+ if (IsMacroTiled(pOut->tileMode))
+ {
+ // If a valid index is returned, then no pTileInfo is okay
+ ADDR_ASSERT(!m_configFlags.useTileIndex || pOut->tileIndex != TileIndexInvalid);
+
+ if (!IsTileInfoAllZero(pIn->pTileInfo))
+ {
+ // The initial value of pIn->pTileInfo is copied to tileInfo
+ // We do not expect any of these value to be changed nor any 0 of inputs
+ ADDR_ASSERT(tileInfo.banks == pIn->pTileInfo->banks);
+ ADDR_ASSERT(tileInfo.bankWidth == pIn->pTileInfo->bankWidth);
+ ADDR_ASSERT(tileInfo.bankHeight == pIn->pTileInfo->bankHeight);
+ ADDR_ASSERT(tileInfo.macroAspectRatio == pIn->pTileInfo->macroAspectRatio);
+ ADDR_ASSERT(tileInfo.tileSplitBytes == pIn->pTileInfo->tileSplitBytes);
+ }
+ }
+#endif
+ pOut->pTileInfo = NULL;
+ }
+ }
+
+ return retCode;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlComputeSurfaceAddrFromCoord
+* @brief
+* Entry of EgBasedAddrLib ComputeSurfaceAddrFromCoord
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeSurfaceAddrFromCoord(
+ const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ ADDR_E_RETURNCODE retCode = ADDR_OK;
+
+ if (
+#if !ALT_TEST // Overflow test needs this out-of-boundary coord
+ (pIn->x > pIn->pitch) ||
+ (pIn->y > pIn->height) ||
+#endif
+ (pIn->numSamples > m_maxSamples))
+ {
+ retCode = ADDR_INVALIDPARAMS;
+ }
+ else
+ {
+ pOut->addr = DispatchComputeSurfaceAddrFromCoord(pIn, pOut);
+ }
+
+ return retCode;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlComputeSurfaceCoordFromAddr
+* @brief
+* Entry of EgBasedAddrLib ComputeSurfaceCoordFromAddr
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeSurfaceCoordFromAddr(
+ const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ ADDR_E_RETURNCODE retCode = ADDR_OK;
+
+ if ((pIn->bitPosition >= 8) ||
+ (pIn->numSamples > m_maxSamples))
+ {
+ retCode = ADDR_INVALIDPARAMS;
+ }
+ else
+ {
+ DispatchComputeSurfaceCoordFromAddr(pIn, pOut);
+ }
+ return retCode;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlComputeSliceTileSwizzle
+* @brief
+* Entry of EgBasedAddrLib ComputeSurfaceCoordFromAddr
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeSliceTileSwizzle(
+ const ADDR_COMPUTE_SLICESWIZZLE_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_SLICESWIZZLE_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ ADDR_E_RETURNCODE retCode = ADDR_OK;
+
+ if (pIn->pTileInfo && (pIn->pTileInfo->banks > 0))
+ {
+
+ pOut->tileSwizzle = ComputeSliceTileSwizzle(pIn->tileMode,
+ pIn->baseSwizzle,
+ pIn->slice,
+ pIn->baseAddr,
+ pIn->pTileInfo);
+ }
+ else
+ {
+ retCode = ADDR_INVALIDPARAMS;
+ }
+
+ return retCode;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlComputeHtileBpp
+*
+* @brief
+* Compute htile bpp
+*
+* @return
+* Htile bpp
+***************************************************************************************************
+*/
+UINT_32 EgBasedAddrLib::HwlComputeHtileBpp(
+ BOOL_32 isWidth8, ///< [in] TRUE if block width is 8
+ BOOL_32 isHeight8 ///< [in] TRUE if block height is 8
+ ) const
+{
+ // only support 8x8 mode
+ ADDR_ASSERT(isWidth8 && isHeight8);
+ return 32;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlComputeHtileBaseAlign
+*
+* @brief
+* Compute htile base alignment
+*
+* @return
+* Htile base alignment
+***************************************************************************************************
+*/
+UINT_32 EgBasedAddrLib::HwlComputeHtileBaseAlign(
+ BOOL_32 isTcCompatible, ///< [in] if TC compatible
+ BOOL_32 isLinear, ///< [in] if it is linear mode
+ ADDR_TILEINFO* pTileInfo ///< [in] Tile info
+ ) const
+{
+ UINT_32 baseAlign = m_pipeInterleaveBytes * HwlGetPipes(pTileInfo);
+
+ if (isTcCompatible)
+ {
+ ADDR_ASSERT(pTileInfo != NULL);
+ if (pTileInfo)
+ {
+ baseAlign *= pTileInfo->banks;
+ }
+ }
+
+ return baseAlign;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlGetPitchAlignmentMicroTiled
+*
+* @brief
+* Compute 1D tiled surface pitch alignment, calculation results are returned through
+* output parameters.
+*
+* @return
+* pitch alignment
+***************************************************************************************************
+*/
+UINT_32 EgBasedAddrLib::HwlGetPitchAlignmentMicroTiled(
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 bpp, ///< [in] bits per pixel
+ ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
+ UINT_32 numSamples ///< [in] number of samples
+ ) const
+{
+ UINT_32 pitchAlign;
+
+ UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode);
+
+ UINT_32 pixelsPerMicroTile;
+ UINT_32 pixelsPerPipeInterleave;
+ UINT_32 microTilesPerPipeInterleave;
+
+ //
+ // Special workaround for depth/stencil buffer, use 8 bpp to meet larger requirement for
+ // stencil buffer since pitch alignment is related to bpp.
+ // For a depth only buffer do not set this.
+ //
+ // Note: this actually does not work for mipmap but mipmap depth texture is not really
+ // sampled with mipmap.
+ //
+ if (flags.depth && !flags.noStencil)
+ {
+ bpp = 8;
+ }
+
+ pixelsPerMicroTile = MicroTilePixels * microTileThickness;
+ pixelsPerPipeInterleave = BYTES_TO_BITS(m_pipeInterleaveBytes) / (bpp * numSamples);
+ microTilesPerPipeInterleave = pixelsPerPipeInterleave / pixelsPerMicroTile;
+
+ pitchAlign = Max(MicroTileWidth, microTilesPerPipeInterleave * MicroTileWidth);
+
+ return pitchAlign;
+}
+
+/**
+***************************************************************************************************
+* EgBasedAddrLib::HwlGetSizeAdjustmentMicroTiled
+*
+* @brief
+* Adjust 1D tiled surface pitch and slice size
+*
+* @return
+* Logical slice size in bytes
+***************************************************************************************************
+*/
+UINT_64 EgBasedAddrLib::HwlGetSizeAdjustmentMicroTiled(
+ UINT_32 thickness, ///< [in] thickness
+ UINT_32 bpp, ///< [in] bits per pixel
+ ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
+ UINT_32 numSamples, ///< [in] number of samples
+ UINT_32 baseAlign, ///< [in] base alignment
+ UINT_32 pitchAlign, ///< [in] pitch alignment
+ UINT_32* pPitch, ///< [in/out] pointer to pitch
+ UINT_32* pHeight ///< [in/out] pointer to height
+ ) const
+{
+ UINT_64 logicalSliceSize;
+ UINT_64 physicalSliceSize;
+
+ UINT_32 pitch = *pPitch;
+ UINT_32 height = *pHeight;
+
+ // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
+ logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
+
+ // Physical slice: multiplied by thickness
+ physicalSliceSize = logicalSliceSize * thickness;
+
+ //
+ // R800 will always pad physical slice size to baseAlign which is pipe_interleave_bytes
+ //
+ ADDR_ASSERT((physicalSliceSize % baseAlign) == 0)
+
+ return logicalSliceSize;
+}
+
diff --git a/src/amd/addrlib/r800/egbaddrlib.h b/src/amd/addrlib/r800/egbaddrlib.h
new file mode 100644
index 00000000000..25e38964be0
--- /dev/null
+++ b/src/amd/addrlib/r800/egbaddrlib.h
@@ -0,0 +1,412 @@
+/*
+ * Copyright © 2014 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+
+/**
+***************************************************************************************************
+* @file egbaddrlib.h
+* @brief Contains the EgBasedAddrLib class definition.
+***************************************************************************************************
+*/
+
+#ifndef __EG_BASED_ADDR_LIB_H__
+#define __EG_BASED_ADDR_LIB_H__
+
+#include "addrlib.h"
+
+
+/// Structures for functions
+struct CoordFromBankPipe
+{
+ UINT_32 xBits : 3;
+ UINT_32 yBits : 4;
+
+ UINT_32 xBit3 : 1;
+ UINT_32 xBit4 : 1;
+ UINT_32 xBit5 : 1;
+ UINT_32 yBit3 : 1;
+ UINT_32 yBit4 : 1;
+ UINT_32 yBit5 : 1;
+ UINT_32 yBit6 : 1;
+};
+
+/**
+***************************************************************************************************
+* @brief This class is the Evergreen based address library
+* @note Abstract class
+***************************************************************************************************
+*/
+class EgBasedAddrLib : public AddrLib
+{
+protected:
+ EgBasedAddrLib(const AddrClient* pClient);
+ virtual ~EgBasedAddrLib();
+
+public:
+
+ /// Surface info functions
+
+ // NOTE: DispatchComputeSurfaceInfo using TileInfo takes both an input and an output.
+ // On input:
+ // One or more fields may be 0 to be calculated/defaulted - pre-SI h/w.
+ // H/W using tile mode index only accepts none or all 0's - SI and newer h/w.
+ // It then returns the actual tiling configuration used.
+ // Other methods' TileInfo must be valid on entry
+ BOOL_32 DispatchComputeSurfaceInfo(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;
+
+ ADDR_E_RETURNCODE DispatchComputeFmaskInfo(
+ const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn,
+ ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut);
+
+protected:
+ // Hwl interface
+ virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfo(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;
+
+ virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoord(
+ const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,
+ ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const;
+
+ virtual ADDR_E_RETURNCODE HwlComputeSurfaceCoordFromAddr(
+ const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,
+ ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut) const;
+
+ virtual ADDR_E_RETURNCODE HwlComputeSliceTileSwizzle(
+ const ADDR_COMPUTE_SLICESWIZZLE_INPUT* pIn,
+ ADDR_COMPUTE_SLICESWIZZLE_OUTPUT* pOut) const;
+
+ virtual ADDR_E_RETURNCODE HwlExtractBankPipeSwizzle(
+ const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT* pIn,
+ ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT* pOut) const;
+
+ virtual ADDR_E_RETURNCODE HwlCombineBankPipeSwizzle(
+ UINT_32 bankSwizzle, UINT_32 pipeSwizzle, ADDR_TILEINFO* pTileInfo,
+ UINT_64 baseAddr, UINT_32* pTileSwizzle) const;
+
+ virtual ADDR_E_RETURNCODE HwlComputeBaseSwizzle(
+ const ADDR_COMPUTE_BASE_SWIZZLE_INPUT* pIn,
+ ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut) const;
+
+ virtual ADDR_E_RETURNCODE HwlConvertTileInfoToHW(
+ const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn,
+ ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut) const;
+
+ virtual UINT_32 HwlComputeHtileBpp(
+ BOOL_32 isWidth8, BOOL_32 isHeight8) const;
+
+ virtual UINT_32 HwlComputeHtileBaseAlign(
+ BOOL_32 isTcCompatible, BOOL_32 isLinear, ADDR_TILEINFO* pTileInfo) const;
+
+ virtual ADDR_E_RETURNCODE HwlComputeFmaskInfo(
+ const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn,
+ 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 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;
+
+ /// Return Cmask block max
+ virtual BOOL_32 HwlGetMaxCmaskBlockMax() const
+ {
+ return 16383; // 14 bits
+ }
+
+ // Sub-hwl interface
+ /// Pure virtual function to setup tile info (indices) if client requests to do so
+ virtual VOID HwlSetupTileInfo(
+ AddrTileMode tileMode, ADDR_SURFACE_FLAGS flags,
+ UINT_32 bpp, UINT_32 pitch, UINT_32 height, UINT_32 numSamples,
+ ADDR_TILEINFO* inputTileInfo, ADDR_TILEINFO* outputTileInfo,
+ AddrTileType inTileType, ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const = 0;
+
+ /// Pure virtual function to get pitch alignment for linear modes
+ virtual UINT_32 HwlGetPitchAlignmentLinear(UINT_32 bpp, ADDR_SURFACE_FLAGS flags) const = 0;
+
+ /// Pure virtual function to get size adjustment for linear modes
+ virtual UINT_64 HwlGetSizeAdjustmentLinear(
+ AddrTileMode tileMode,
+ UINT_32 bpp, UINT_32 numSamples, UINT_32 baseAlign, UINT_32 pitchAlign,
+ UINT_32 *pPitch, UINT_32 *pHeight, UINT_32 *pHeightAlign) const = 0;
+
+ virtual UINT_32 HwlGetPitchAlignmentMicroTiled(
+ AddrTileMode tileMode, UINT_32 bpp, ADDR_SURFACE_FLAGS flags, UINT_32 numSamples) const;
+
+ virtual UINT_64 HwlGetSizeAdjustmentMicroTiled(
+ UINT_32 thickness, UINT_32 bpp, ADDR_SURFACE_FLAGS flags, UINT_32 numSamples,
+ UINT_32 baseAlign, UINT_32 pitchAlign,
+ UINT_32 *pPitch, UINT_32 *pHeight) const;
+
+ /// Pure virtual function to do extra sanity check
+ virtual BOOL_32 HwlSanityCheckMacroTiled(
+ ADDR_TILEINFO* pTileInfo) const = 0;
+
+ /// Pure virtual function to check current level to be the last macro tiled one
+ virtual VOID HwlCheckLastMacroTiledLvl(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const = 0;
+
+ /// Adjusts bank before bank is modified by rotation
+ virtual UINT_32 HwlPreAdjustBank(
+ UINT_32 tileX, UINT_32 bank, ADDR_TILEINFO* pTileInfo) const = 0;
+
+ virtual VOID HwlComputeSurfaceCoord2DFromBankPipe(
+ AddrTileMode tileMode, UINT_32* pX, UINT_32* pY, UINT_32 slice,
+ UINT_32 bank, UINT_32 pipe,
+ UINT_32 bankSwizzle, UINT_32 pipeSwizzle, UINT_32 tileSlices,
+ BOOL_32 ignoreSE,
+ ADDR_TILEINFO* pTileInfo) const = 0;
+
+ 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 INT_32 HwlPostCheckTileIndex(
+ const ADDR_TILEINFO* pInfo, AddrTileMode mode, AddrTileType type,
+ INT curIndex = TileIndexInvalid) const
+ {
+ return TileIndexInvalid;
+ }
+
+ virtual VOID HwlFmaskPreThunkSurfInfo(
+ const ADDR_COMPUTE_FMASK_INFO_INPUT* pFmaskIn,
+ const ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut,
+ ADDR_COMPUTE_SURFACE_INFO_INPUT* pSurfIn,
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut) const
+ {
+ }
+
+ virtual VOID HwlFmaskPostThunkSurfInfo(
+ const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut,
+ ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut) const
+ {
+ }
+
+ /// Virtual function to check if the height needs extra padding
+ /// for stereo right eye offset, to avoid bank pipe swizzle
+ virtual BOOL_32 HwlStereoCheckRightOffsetPadding() const
+ {
+ return FALSE;
+ }
+
+ virtual BOOL_32 HwlReduceBankWidthHeight(
+ UINT_32 tileSize, UINT_32 bpp, ADDR_SURFACE_FLAGS flags, UINT_32 numSamples,
+ UINT_32 bankHeightAlign, UINT_32 pipes,
+ ADDR_TILEINFO* pTileInfo) const;
+
+ // Protected non-virtual functions
+
+ /// Mip level functions
+ AddrTileMode ComputeSurfaceMipLevelTileMode(
+ AddrTileMode baseTileMode, UINT_32 bpp,
+ UINT_32 pitch, UINT_32 height, UINT_32 numSlices, UINT_32 numSamples,
+ UINT_32 pitchAlign, UINT_32 heightAlign,
+ ADDR_TILEINFO* pTileInfo) const;
+
+ /// Swizzle functions
+ VOID ExtractBankPipeSwizzle(
+ UINT_32 base256b, ADDR_TILEINFO* pTileInfo,
+ UINT_32* pBankSwizzle, UINT_32* pPipeSwizzle) const;
+
+ UINT_32 GetBankPipeSwizzle(
+ UINT_32 bankSwizzle, UINT_32 pipeSwizzle,
+ UINT_64 baseAddr, ADDR_TILEINFO* pTileInfo) const;
+
+ UINT_32 ComputeSliceTileSwizzle(
+ AddrTileMode tileMode, UINT_32 baseSwizzle, UINT_32 slice, UINT_64 baseAddr,
+ ADDR_TILEINFO* pTileInfo) const;
+
+ /// Addressing functions
+ UINT_32 ComputeBankFromCoord(
+ UINT_32 x, UINT_32 y, UINT_32 slice,
+ AddrTileMode tileMode, UINT_32 bankSwizzle, UINT_32 tileSpitSlice,
+ ADDR_TILEINFO* pTileInfo) const;
+
+ UINT_32 ComputeBankFromAddr(
+ UINT_64 addr, UINT_32 numBanks, UINT_32 numPipes) const;
+
+ UINT_32 ComputePipeRotation(
+ AddrTileMode tileMode, UINT_32 numPipes) const;
+
+ UINT_32 ComputeBankRotation(
+ AddrTileMode tileMode, UINT_32 numBanks,
+ UINT_32 numPipes) const;
+
+ VOID ComputeSurfaceCoord2DFromBankPipe(
+ AddrTileMode tileMode, UINT_32 x, UINT_32 y, UINT_32 slice,
+ UINT_32 bank, UINT_32 pipe,
+ UINT_32 bankSwizzle, UINT_32 pipeSwizzle, UINT_32 tileSlices,
+ ADDR_TILEINFO* pTileInfo,
+ CoordFromBankPipe *pOutput) const;
+
+ /// Htile/Cmask functions
+ UINT_64 ComputeHtileBytes(
+ UINT_32 pitch, UINT_32 height, UINT_32 bpp,
+ BOOL_32 isLinear, UINT_32 numSlices, UINT_64* sliceBytes, UINT_32 baseAlign) const;
+
+ // Static functions
+ static BOOL_32 IsTileInfoAllZero(ADDR_TILEINFO* pTileInfo);
+ static UINT_32 ComputeFmaskNumPlanesFromNumSamples(UINT_32 numSamples);
+ static UINT_32 ComputeFmaskResolvedBppFromNumSamples(UINT_32 numSamples);
+
+private:
+
+ BOOL_32 ComputeSurfaceInfoLinear(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut,
+ UINT_32 padDims) const;
+
+ BOOL_32 ComputeSurfaceInfoMicroTiled(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut,
+ UINT_32 padDims,
+ AddrTileMode expTileMode) const;
+
+ BOOL_32 ComputeSurfaceInfoMacroTiled(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut,
+ UINT_32 padDims,
+ AddrTileMode expTileMode) const;
+
+ BOOL_32 ComputeSurfaceAlignmentsLinear(
+ AddrTileMode tileMode, UINT_32 bpp, ADDR_SURFACE_FLAGS flags,
+ UINT_32* pBaseAlign, UINT_32* pPitchAlign, UINT_32* pHeightAlign) const;
+
+ BOOL_32 ComputeSurfaceAlignmentsMicroTiled(
+ AddrTileMode tileMode, UINT_32 bpp, ADDR_SURFACE_FLAGS flags,
+ UINT_32 mipLevel, UINT_32 numSamples,
+ UINT_32* pBaseAlign, UINT_32* pPitchAlign, UINT_32* pHeightAlign) const;
+
+ BOOL_32 ComputeSurfaceAlignmentsMacroTiled(
+ 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;
+
+ /// Surface addressing functions
+ UINT_64 DispatchComputeSurfaceAddrFromCoord(
+ const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,
+ ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const;
+
+ VOID DispatchComputeSurfaceCoordFromAddr(
+ const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,
+ ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut) const;
+
+ UINT_64 ComputeSurfaceAddrFromCoordMicroTiled(
+ UINT_32 x, UINT_32 y, UINT_32 slice, UINT_32 sample,
+ UINT_32 bpp, UINT_32 pitch, UINT_32 height, UINT_32 numSamples,
+ AddrTileMode tileMode,
+ AddrTileType microTileType, BOOL_32 isDepthSampleOrder,
+ UINT_32* pBitPosition) const;
+
+ UINT_64 ComputeSurfaceAddrFromCoordMacroTiled(
+ UINT_32 x, UINT_32 y, UINT_32 slice, UINT_32 sample,
+ UINT_32 bpp, UINT_32 pitch, UINT_32 height, UINT_32 numSamples,
+ AddrTileMode tileMode,
+ AddrTileType microTileType, BOOL_32 ignoreSE, BOOL_32 isDepthSampleOrder,
+ UINT_32 pipeSwizzle, UINT_32 bankSwizzle,
+ ADDR_TILEINFO* pTileInfo,
+ UINT_32* pBitPosition) const;
+
+ VOID ComputeSurfaceCoordFromAddrMacroTiled(
+ UINT_64 addr, UINT_32 bitPosition,
+ UINT_32 bpp, UINT_32 pitch, UINT_32 height, UINT_32 numSamples,
+ AddrTileMode tileMode, UINT_32 tileBase, UINT_32 compBits,
+ AddrTileType microTileType, BOOL_32 ignoreSE, BOOL_32 isDepthSampleOrder,
+ UINT_32 pipeSwizzle, UINT_32 bankSwizzle,
+ ADDR_TILEINFO* pTileInfo,
+ UINT_32* pX, UINT_32* pY, UINT_32* pSlice, UINT_32* pSample) const;
+
+ /// Fmask functions
+ UINT_64 DispatchComputeFmaskAddrFromCoord(
+ const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn,
+ ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut) const;
+
+ VOID DispatchComputeFmaskCoordFromAddr(
+ const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn,
+ ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut) const;
+
+ // FMASK related methods - private
+ UINT_64 ComputeFmaskAddrFromCoordMicroTiled(
+ UINT_32 x, UINT_32 y, UINT_32 slice, UINT_32 sample, UINT_32 plane,
+ UINT_32 pitch, UINT_32 height, UINT_32 numSamples, AddrTileMode tileMode,
+ BOOL_32 resolved, UINT_32* pBitPosition) const;
+
+ VOID ComputeFmaskCoordFromAddrMicroTiled(
+ UINT_64 addr, UINT_32 bitPosition,
+ UINT_32 pitch, UINT_32 height, UINT_32 numSamples,
+ AddrTileMode tileMode, BOOL_32 resolved,
+ UINT_32* pX, UINT_32* pY, UINT_32* pSlice, UINT_32* pSample, UINT_32* pPlane) const;
+
+ VOID ComputeFmaskCoordFromAddrMacroTiled(
+ UINT_64 addr, UINT_32 bitPosition,
+ UINT_32 pitch, UINT_32 height, UINT_32 numSamples, AddrTileMode tileMode,
+ UINT_32 pipeSwizzle, UINT_32 bankSwizzle,
+ BOOL_32 ignoreSE,
+ ADDR_TILEINFO* pTileInfo,
+ BOOL_32 resolved,
+ UINT_32* pX, UINT_32* pY, UINT_32* pSlice, UINT_32* pSample, UINT_32* pPlane) const;
+
+ UINT_64 ComputeFmaskAddrFromCoordMacroTiled(
+ UINT_32 x, UINT_32 y, UINT_32 slice, UINT_32 sample, UINT_32 plane,
+ UINT_32 pitch, UINT_32 height, UINT_32 numSamples,
+ AddrTileMode tileMode, UINT_32 pipeSwizzle, UINT_32 bankSwizzle,
+ BOOL_32 ignoreSE,
+ ADDR_TILEINFO* pTileInfo,
+ BOOL_32 resolved,
+ UINT_32* pBitPosition) const;
+
+ /// Sanity check functions
+ BOOL_32 SanityCheckMacroTiled(
+ ADDR_TILEINFO* pTileInfo) const;
+
+protected:
+ UINT_32 m_ranks; ///< Number of ranks - MC_ARB_RAMCFG.NOOFRANK
+ UINT_32 m_logicalBanks; ///< Logical banks = m_banks * m_ranks if m_banks != 16
+ UINT_32 m_bankInterleave; ///< Bank interleave, as a multiple of pipe interleave size
+};
+
+#endif
+
diff --git a/src/amd/addrlib/r800/siaddrlib.cpp b/src/amd/addrlib/r800/siaddrlib.cpp
new file mode 100644
index 00000000000..a858b55b7cf
--- /dev/null
+++ b/src/amd/addrlib/r800/siaddrlib.cpp
@@ -0,0 +1,2818 @@
+/*
+ * Copyright © 2014 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+
+/**
+***************************************************************************************************
+* @file siaddrlib.cpp
+* @brief Contains the implementation for the SIAddrLib class.
+***************************************************************************************************
+*/
+
+#include "siaddrlib.h"
+
+#include "si_gb_reg.h"
+
+#include "si_ci_vi_merged_enum.h"
+
+#if BRAHMA_BUILD
+#include "amdgpu_id.h"
+#else
+#include "si_id.h"
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+***************************************************************************************************
+* AddrSIHwlInit
+*
+* @brief
+* Creates an SIAddrLib object.
+*
+* @return
+* Returns an SIAddrLib object pointer.
+***************************************************************************************************
+*/
+AddrLib* AddrSIHwlInit(const AddrClient* pClient)
+{
+ return SIAddrLib::CreateObj(pClient);
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::SIAddrLib
+*
+* @brief
+* Constructor
+*
+***************************************************************************************************
+*/
+SIAddrLib::SIAddrLib(const AddrClient* pClient) :
+ EgBasedAddrLib(pClient),
+ m_noOfEntries(0)
+{
+ m_class = SI_ADDRLIB;
+ memset(&m_settings, 0, sizeof(m_settings));
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::~SIAddrLib
+*
+* @brief
+* Destructor
+***************************************************************************************************
+*/
+SIAddrLib::~SIAddrLib()
+{
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlGetPipes
+*
+* @brief
+* Get number pipes
+* @return
+* num pipes
+***************************************************************************************************
+*/
+UINT_32 SIAddrLib::HwlGetPipes(
+ const ADDR_TILEINFO* pTileInfo ///< [in] Tile info
+ ) const
+{
+ UINT_32 numPipes;
+
+ if (pTileInfo)
+ {
+ numPipes = GetPipePerSurf(pTileInfo->pipeConfig);
+ }
+ else
+ {
+ ADDR_ASSERT_ALWAYS();
+ numPipes = m_pipes; // Suppose we should still have a global pipes
+ }
+
+ return numPipes;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::GetPipePerSurf
+* @brief
+* get pipe num base on inputing tileinfo->pipeconfig
+* @return
+* pipe number
+***************************************************************************************************
+*/
+UINT_32 SIAddrLib::GetPipePerSurf(
+ AddrPipeCfg pipeConfig ///< [in] pipe config
+ ) const
+{
+ UINT_32 numPipes = 0;
+
+ switch (pipeConfig)
+ {
+ case ADDR_PIPECFG_P2:
+ numPipes = 2;
+ break;
+ case ADDR_PIPECFG_P4_8x16:
+ case ADDR_PIPECFG_P4_16x16:
+ case ADDR_PIPECFG_P4_16x32:
+ case ADDR_PIPECFG_P4_32x32:
+ numPipes = 4;
+ break;
+ case ADDR_PIPECFG_P8_16x16_8x16:
+ case ADDR_PIPECFG_P8_16x32_8x16:
+ case ADDR_PIPECFG_P8_32x32_8x16:
+ case ADDR_PIPECFG_P8_16x32_16x16:
+ case ADDR_PIPECFG_P8_32x32_16x16:
+ case ADDR_PIPECFG_P8_32x32_16x32:
+ case ADDR_PIPECFG_P8_32x64_32x32:
+ numPipes = 8;
+ break;
+ case ADDR_PIPECFG_P16_32x32_8x16:
+ case ADDR_PIPECFG_P16_32x32_16x16:
+ numPipes = 16;
+ break;
+ default:
+ ADDR_ASSERT(!"Invalid pipe config");
+ numPipes = m_pipes;
+ }
+ return numPipes;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::ComputePipeFromCoord
+*
+* @brief
+* Compute pipe number from coordinates
+* @return
+* Pipe number
+***************************************************************************************************
+*/
+UINT_32 SIAddrLib::ComputePipeFromCoord(
+ UINT_32 x, ///< [in] x coordinate
+ UINT_32 y, ///< [in] y coordinate
+ UINT_32 slice, ///< [in] slice index
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 pipeSwizzle, ///< [in] pipe swizzle
+ BOOL_32 ignoreSE, ///< [in] TRUE if shader engines are ignored
+ ADDR_TILEINFO* pTileInfo ///< [in] Tile info
+ ) const
+{
+ UINT_32 pipe;
+ UINT_32 pipeBit0 = 0;
+ UINT_32 pipeBit1 = 0;
+ UINT_32 pipeBit2 = 0;
+ UINT_32 pipeBit3 = 0;
+ UINT_32 sliceRotation;
+ UINT_32 numPipes = 0;
+
+ UINT_32 tx = x / MicroTileWidth;
+ UINT_32 ty = y / MicroTileHeight;
+ UINT_32 x3 = _BIT(tx,0);
+ UINT_32 x4 = _BIT(tx,1);
+ UINT_32 x5 = _BIT(tx,2);
+ UINT_32 x6 = _BIT(tx,3);
+ UINT_32 y3 = _BIT(ty,0);
+ UINT_32 y4 = _BIT(ty,1);
+ UINT_32 y5 = _BIT(ty,2);
+ UINT_32 y6 = _BIT(ty,3);
+
+ switch (pTileInfo->pipeConfig)
+ {
+ case ADDR_PIPECFG_P2:
+ pipeBit0 = x3 ^ y3;
+ numPipes = 2;
+ break;
+ case ADDR_PIPECFG_P4_8x16:
+ pipeBit0 = x4 ^ y3;
+ pipeBit1 = x3 ^ y4;
+ numPipes = 4;
+ break;
+ case ADDR_PIPECFG_P4_16x16:
+ pipeBit0 = x3 ^ y3 ^ x4;
+ pipeBit1 = x4 ^ y4;
+ numPipes = 4;
+ break;
+ case ADDR_PIPECFG_P4_16x32:
+ pipeBit0 = x3 ^ y3 ^ x4;
+ pipeBit1 = x4 ^ y5;
+ numPipes = 4;
+ break;
+ case ADDR_PIPECFG_P4_32x32:
+ pipeBit0 = x3 ^ y3 ^ x5;
+ pipeBit1 = x5 ^ y5;
+ numPipes = 4;
+ break;
+ case ADDR_PIPECFG_P8_16x16_8x16:
+ pipeBit0 = x4 ^ y3 ^ x5;
+ pipeBit1 = x3 ^ y5;
+ numPipes = 8;
+ break;
+ case ADDR_PIPECFG_P8_16x32_8x16:
+ pipeBit0 = x4 ^ y3 ^ x5;
+ pipeBit1 = x3 ^ y4;
+ pipeBit2 = x4 ^ y5;
+ numPipes = 8;
+ break;
+ case ADDR_PIPECFG_P8_16x32_16x16:
+ pipeBit0 = x3 ^ y3 ^ x4;
+ pipeBit1 = x5 ^ y4;
+ pipeBit2 = x4 ^ y5;
+ numPipes = 8;
+ break;
+ case ADDR_PIPECFG_P8_32x32_8x16:
+ pipeBit0 = x4 ^ y3 ^ x5;
+ pipeBit1 = x3 ^ y4;
+ pipeBit2 = x5 ^ y5;
+ numPipes = 8;
+ break;
+ case ADDR_PIPECFG_P8_32x32_16x16:
+ pipeBit0 = x3 ^ y3 ^ x4;
+ pipeBit1 = x4 ^ y4;
+ pipeBit2 = x5 ^ y5;
+ numPipes = 8;
+ break;
+ case ADDR_PIPECFG_P8_32x32_16x32:
+ pipeBit0 = x3 ^ y3 ^ x4;
+ pipeBit1 = x4 ^ y6;
+ pipeBit2 = x5 ^ y5;
+ numPipes = 8;
+ break;
+ case ADDR_PIPECFG_P8_32x64_32x32:
+ pipeBit0 = x3 ^ y3 ^ x5;
+ pipeBit1 = x6 ^ y5;
+ pipeBit2 = x5 ^ y6;
+ numPipes = 8;
+ break;
+ case ADDR_PIPECFG_P16_32x32_8x16:
+ pipeBit0 = x4 ^ y3;
+ pipeBit1 = x3 ^ y4;
+ pipeBit2 = x5 ^ y6;
+ pipeBit3 = x6 ^ y5;
+ numPipes = 16;
+ break;
+ case ADDR_PIPECFG_P16_32x32_16x16:
+ pipeBit0 = x3 ^ y3 ^ x4;
+ pipeBit1 = x4 ^ y4;
+ pipeBit2 = x5 ^ y6;
+ pipeBit3 = x6 ^ y5;
+ numPipes = 16;
+ break;
+ default:
+ ADDR_UNHANDLED_CASE();
+ break;
+ }
+ pipe = pipeBit0 | (pipeBit1 << 1) | (pipeBit2 << 2) | (pipeBit3 << 3);
+
+ UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode);
+
+ //
+ // Apply pipe rotation for the slice.
+ //
+ switch (tileMode)
+ {
+ case ADDR_TM_3D_TILED_THIN1: //fall through thin
+ case ADDR_TM_3D_TILED_THICK: //fall through thick
+ case ADDR_TM_3D_TILED_XTHICK:
+ sliceRotation =
+ Max(1, static_cast<INT_32>(numPipes / 2) - 1) * (slice / microTileThickness);
+ break;
+ default:
+ sliceRotation = 0;
+ break;
+ }
+ pipeSwizzle += sliceRotation;
+ pipeSwizzle &= (numPipes - 1);
+
+ pipe = pipe ^ pipeSwizzle;
+
+ return pipe;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::ComputeTileCoordFromPipeAndElemIdx
+*
+* @brief
+* Compute (x,y) of a tile within a macro tile from address
+* @return
+* Pipe number
+***************************************************************************************************
+*/
+VOID SIAddrLib::ComputeTileCoordFromPipeAndElemIdx(
+ UINT_32 elemIdx, ///< [in] per pipe element index within a macro tile
+ UINT_32 pipe, ///< [in] pipe index
+ AddrPipeCfg pipeCfg, ///< [in] pipe config
+ UINT_32 pitchInMacroTile, ///< [in] surface pitch in macro tile
+ UINT_32 x, ///< [in] x coordinate of the (0,0) tile in a macro tile
+ UINT_32 y, ///< [in] y coordinate of the (0,0) tile in a macro tile
+ UINT_32* pX, ///< [out] x coordinate
+ UINT_32* pY ///< [out] y coordinate
+ ) const
+{
+ UINT_32 pipebit0 = _BIT(pipe,0);
+ UINT_32 pipebit1 = _BIT(pipe,1);
+ UINT_32 pipebit2 = _BIT(pipe,2);
+ UINT_32 pipebit3 = _BIT(pipe,3);
+ UINT_32 elemIdx0 = _BIT(elemIdx,0);
+ UINT_32 elemIdx1 = _BIT(elemIdx,1);
+ UINT_32 elemIdx2 = _BIT(elemIdx,2);
+ UINT_32 x3 = 0;
+ UINT_32 x4 = 0;
+ UINT_32 x5 = 0;
+ UINT_32 x6 = 0;
+ UINT_32 y3 = 0;
+ UINT_32 y4 = 0;
+ UINT_32 y5 = 0;
+ UINT_32 y6 = 0;
+
+ switch(pipeCfg)
+ {
+ case ADDR_PIPECFG_P2:
+ x4 = elemIdx2;
+ y4 = elemIdx1 ^ x4;
+ y3 = elemIdx0 ^ x4;
+ x3 = pipebit0 ^ y3;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(2, x4, x3);
+ break;
+ case ADDR_PIPECFG_P4_8x16:
+ x4 = elemIdx1;
+ y4 = elemIdx0 ^ x4;
+ x3 = pipebit1 ^ y4;
+ y3 = pipebit0 ^ x4;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(2, x4, x3);
+ break;
+ case ADDR_PIPECFG_P4_16x16:
+ x4 = elemIdx1;
+ y3 = elemIdx0 ^ x4;
+ y4 = pipebit1 ^ x4;
+ x3 = pipebit0 ^ y3 ^ x4;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(2, x4, x3);
+ break;
+ case ADDR_PIPECFG_P4_16x32:
+ x3 = elemIdx0 ^ pipebit0;
+ y5 = _BIT(y,5);
+ x4 = pipebit1 ^ y5;
+ y3 = pipebit0 ^ x3 ^ x4;
+ y4 = elemIdx1 ^ x4;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(2, x4, x3);
+ break;
+ case ADDR_PIPECFG_P4_32x32:
+ x4 = elemIdx2;
+ y3 = elemIdx0 ^ x4;
+ y4 = elemIdx1 ^ x4;
+ if((pitchInMacroTile % 2) == 0)
+ { //even
+ y5 = _BIT(y,5);
+ x5 = pipebit1 ^ y5;
+ x3 = pipebit0 ^ y3 ^ x5;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(3, x5, x4, x3);
+ }
+ else
+ { //odd
+ x5 = _BIT(x,5);
+ x3 = pipebit0 ^ y3 ^ x5;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(2, x4, x3);
+ }
+ break;
+ case ADDR_PIPECFG_P8_16x16_8x16:
+ x4 = elemIdx0;
+ y5 = _BIT(y,5);
+ x5 = _BIT(x,5);
+ x3 = pipebit1 ^ y5;
+ y4 = pipebit2 ^ x4;
+ y3 = pipebit0 ^ x5 ^ x4;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(2, x4, x3);
+ break;
+ case ADDR_PIPECFG_P8_16x32_8x16:
+ x3 = elemIdx0;
+ y4 = pipebit1 ^ x3;
+ y5 = _BIT(y,5);
+ x5 = _BIT(x,5);
+ x4 = pipebit2 ^ y5;
+ y3 = pipebit0 ^ x4 ^ x5;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(2, x4, x3);
+ break;
+ case ADDR_PIPECFG_P8_32x32_8x16:
+ x4 = elemIdx1;
+ y4 = elemIdx0 ^ x4;
+ x3 = pipebit1 ^ y4;
+ if((pitchInMacroTile % 2) == 0)
+ { //even
+ y5 = _BIT(y,5);
+ x5 = _BIT(x,5);
+ x5 = pipebit2 ^ y5;
+ y3 = pipebit0 ^ x4 ^ x5;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(3, x5, x4, x3);
+ }
+ else
+ { //odd
+ x5 = _BIT(x,5);
+ y3 = pipebit0 ^ x4 ^ x5;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(2, x4, x3);
+ }
+ break;
+ case ADDR_PIPECFG_P8_16x32_16x16:
+ x3 = elemIdx0;
+ x5 = _BIT(x,5);
+ y5 = _BIT(y,5);
+ x4 = pipebit2 ^ y5;
+ y4 = pipebit1 ^ x5;
+ y3 = pipebit0 ^ x3 ^ x4;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(2, x4, x3);
+ break;
+ case ADDR_PIPECFG_P8_32x32_16x16:
+ x4 = elemIdx1;
+ y3 = elemIdx0 ^ x4;
+ x3 = y3^x4^pipebit0;
+ y4 = pipebit1 ^ x4;
+ if((pitchInMacroTile % 2) == 0)
+ { //even
+ y5 = _BIT(y,5);
+ x5 = pipebit2 ^ y5;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(3, x5, x4, x3);
+ }
+ else
+ { //odd
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(2, x4, x3);
+ }
+ break;
+ case ADDR_PIPECFG_P8_32x32_16x32:
+ if((pitchInMacroTile % 2) == 0)
+ { //even
+ y5 = _BIT(y,5);
+ y6 = _BIT(y,6);
+ x4 = pipebit1 ^ y6;
+ y3 = elemIdx0 ^ x4;
+ y4 = elemIdx1 ^ x4;
+ x3 = pipebit0 ^ y3 ^ x4;
+ x5 = pipebit2 ^ y5;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(3, x5, x4, x3);
+ }
+ else
+ { //odd
+ y6 = _BIT(y,6);
+ x4 = pipebit1 ^ y6;
+ y3 = elemIdx0 ^ x4;
+ y4 = elemIdx1 ^ x4;
+ x3 = pipebit0 ^ y3 ^ x4;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(2, x4, x3);
+ }
+ break;
+ case ADDR_PIPECFG_P8_32x64_32x32:
+ x4 = elemIdx2;
+ y3 = elemIdx0 ^ x4;
+ y4 = elemIdx1 ^ x4;
+ if((pitchInMacroTile % 4) == 0)
+ { //multiple of 4
+ y5 = _BIT(y,5);
+ y6 = _BIT(y,6);
+ x5 = pipebit2 ^ y6;
+ x6 = pipebit1 ^ y5;
+ x3 = pipebit0 ^ y3 ^ x5;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(4, x6, x5, x4, x3);
+ }
+ else
+ {
+ y6 = _BIT(y,6);
+ x5 = pipebit2 ^ y6;
+ x3 = pipebit0 ^ y3 ^ x5;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(3, x5, x4, x3);
+ }
+ break;
+ case ADDR_PIPECFG_P16_32x32_8x16:
+ x4 = elemIdx1;
+ y4 = elemIdx0 ^ x4;
+ y3 = pipebit0 ^ x4;
+ x3 = pipebit1 ^ y4;
+ if((pitchInMacroTile % 4) == 0)
+ { //multiple of 4
+ y5 = _BIT(y,5);
+ y6 = _BIT(y,6);
+ x5 = pipebit2 ^ y6;
+ x6 = pipebit3 ^ y5;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(4, x6, x5,x4, x3);
+ }
+ else
+ {
+ y6 = _BIT(y,6);
+ x5 = pipebit2 ^ y6;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(3, x5, x4, x3);
+ }
+ break;
+ case ADDR_PIPECFG_P16_32x32_16x16:
+ x4 = elemIdx1;
+ y3 = elemIdx0 ^ x4;
+ y4 = pipebit1 ^ x4;
+ x3 = pipebit0 ^ y3 ^ x4;
+ if((pitchInMacroTile % 4) == 0)
+ { //multiple of 4
+ y5 = _BIT(y,5);
+ y6 = _BIT(y,6);
+ x5 = pipebit2 ^ y6;
+ x6 = pipebit3 ^ y5;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(4, x6, x5, x4, x3);
+ }
+ else
+ {
+ y6 = _BIT(y,6);
+ x5 = pipebit2 ^ y6;
+ *pY = Bits2Number(2, y4, y3);
+ *pX = Bits2Number(3, x5, x4, x3);
+ }
+ break;
+ default:
+ ADDR_UNHANDLED_CASE();
+ }
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::TileCoordToMaskElementIndex
+*
+* @brief
+* Compute element index from coordinates in tiles
+* @return
+* Element index
+***************************************************************************************************
+*/
+UINT_32 SIAddrLib::TileCoordToMaskElementIndex(
+ UINT_32 tx, ///< [in] x coord, in Tiles
+ UINT_32 ty, ///< [in] y coord, in Tiles
+ AddrPipeCfg pipeConfig, ///< [in] pipe config
+ UINT_32* macroShift, ///< [out] macro shift
+ UINT_32* elemIdxBits ///< [out] tile offset bits
+ ) const
+{
+ UINT_32 elemIdx = 0;
+ UINT_32 elemIdx0, elemIdx1, elemIdx2;
+ UINT_32 tx0, tx1;
+ UINT_32 ty0, ty1;
+
+ tx0 = _BIT(tx,0);
+ tx1 = _BIT(tx,1);
+ ty0 = _BIT(ty,0);
+ ty1 = _BIT(ty,1);
+
+ switch(pipeConfig)
+ {
+ case ADDR_PIPECFG_P2:
+ *macroShift = 3;
+ *elemIdxBits =3;
+ elemIdx2 = tx1;
+ elemIdx1 = tx1 ^ ty1;
+ elemIdx0 = tx1 ^ ty0;
+ elemIdx = Bits2Number(3,elemIdx2,elemIdx1,elemIdx0);
+ break;
+ case ADDR_PIPECFG_P4_8x16:
+ *macroShift = 2;
+ *elemIdxBits =2;
+ elemIdx1 = tx1;
+ elemIdx0 = tx1 ^ ty1;
+ elemIdx = Bits2Number(2,elemIdx1,elemIdx0);
+ break;
+ case ADDR_PIPECFG_P4_16x16:
+ *macroShift = 2;
+ *elemIdxBits =2;
+ elemIdx0 = tx1^ty0;
+ elemIdx1 = tx1;
+ elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
+ break;
+ case ADDR_PIPECFG_P4_16x32:
+ *macroShift = 2;
+ *elemIdxBits =2;
+ elemIdx0 = tx1^ty0;
+ elemIdx1 = tx1^ty1;
+ elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
+ break;
+ case ADDR_PIPECFG_P4_32x32:
+ *macroShift = 2;
+ *elemIdxBits =3;
+ elemIdx0 = tx1^ty0;
+ elemIdx1 = tx1^ty1;
+ elemIdx2 = tx1;
+ elemIdx = Bits2Number(3, elemIdx2, elemIdx1, elemIdx0);
+ break;
+ case ADDR_PIPECFG_P8_16x16_8x16:
+ *macroShift = 1;
+ *elemIdxBits =1;
+ elemIdx0 = tx1;
+ elemIdx = elemIdx0;
+ break;
+ case ADDR_PIPECFG_P8_16x32_8x16:
+ *macroShift = 1;
+ *elemIdxBits =1;
+ elemIdx0 = tx0;
+ elemIdx = elemIdx0;
+ break;
+ case ADDR_PIPECFG_P8_32x32_8x16:
+ *macroShift = 1;
+ *elemIdxBits =2;
+ elemIdx1 = tx1;
+ elemIdx0 = tx1^ty1;
+ elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
+ break;
+ case ADDR_PIPECFG_P8_16x32_16x16:
+ *macroShift = 1;
+ *elemIdxBits =1;
+ elemIdx0 = tx0;
+ elemIdx = elemIdx0;
+ break;
+ case ADDR_PIPECFG_P8_32x32_16x16:
+ *macroShift = 1;
+ *elemIdxBits =2;
+ elemIdx0 = tx1^ty0;
+ elemIdx1 = tx1;
+ elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
+ break;
+ case ADDR_PIPECFG_P8_32x32_16x32:
+ *macroShift = 1;
+ *elemIdxBits =2;
+ elemIdx0 = tx1^ty0;
+ elemIdx1 = tx1^ty1;
+ elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
+ break;
+ case ADDR_PIPECFG_P8_32x64_32x32:
+ *macroShift = 1;
+ *elemIdxBits =3;
+ elemIdx0 = tx1^ty0;
+ elemIdx1 = tx1^ty1;
+ elemIdx2 = tx1;
+ elemIdx = Bits2Number(3, elemIdx2, elemIdx1, elemIdx0);
+ break;
+ case ADDR_PIPECFG_P16_32x32_8x16:
+ *macroShift = 0;
+ *elemIdxBits =2;
+ elemIdx0 = tx1^ty1;
+ elemIdx1 = tx1;
+ elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
+ break;
+ case ADDR_PIPECFG_P16_32x32_16x16:
+ *macroShift = 0;
+ *elemIdxBits =2;
+ elemIdx0 = tx1^ty0;
+ elemIdx1 = tx1;
+ elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
+ break;
+ default:
+ ADDR_UNHANDLED_CASE();
+ break;
+ }
+
+ return elemIdx;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlComputeTileDataWidthAndHeightLinear
+*
+* @brief
+* Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
+*
+* @return
+* N/A
+*
+* @note
+* MacroWidth and macroHeight are measured in pixels
+***************************************************************************************************
+*/
+VOID SIAddrLib::HwlComputeTileDataWidthAndHeightLinear(
+ UINT_32* pMacroWidth, ///< [out] macro tile width
+ UINT_32* pMacroHeight, ///< [out] macro tile height
+ UINT_32 bpp, ///< [in] bits per pixel
+ ADDR_TILEINFO* pTileInfo ///< [in] tile info
+ ) const
+{
+ ADDR_ASSERT(pTileInfo != NULL);
+ UINT_32 macroWidth;
+ UINT_32 macroHeight;
+
+ /// In linear mode, the htile or cmask buffer must be padded out to 4 tiles
+ /// but for P8_32x64_32x32, it must be padded out to 8 tiles
+ /// Actually there are more pipe configs which need 8-tile padding but SI family
+ /// has a bug which is fixed in CI family
+ if ((pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32) ||
+ (pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_8x16) ||
+ (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x32_16x16))
+ {
+ macroWidth = 8*MicroTileWidth;
+ macroHeight = 8*MicroTileHeight;
+ }
+ else
+ {
+ macroWidth = 4*MicroTileWidth;
+ macroHeight = 4*MicroTileHeight;
+ }
+
+ *pMacroWidth = macroWidth;
+ *pMacroHeight = macroHeight;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlComputeHtileBytes
+*
+* @brief
+* Compute htile size in bytes
+*
+* @return
+* Htile size in bytes
+***************************************************************************************************
+*/
+UINT_64 SIAddrLib::HwlComputeHtileBytes(
+ UINT_32 pitch, ///< [in] pitch
+ UINT_32 height, ///< [in] height
+ UINT_32 bpp, ///< [in] bits per pixel
+ BOOL_32 isLinear, ///< [in] if it is linear mode
+ UINT_32 numSlices, ///< [in] number of slices
+ UINT_64* pSliceBytes, ///< [out] bytes per slice
+ UINT_32 baseAlign ///< [in] base alignments
+ ) const
+{
+ return ComputeHtileBytes(pitch, height, bpp, isLinear, numSlices, pSliceBytes, baseAlign);
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlComputeXmaskAddrFromCoord
+*
+* @brief
+* Compute address from coordinates for htile/cmask
+* @return
+* Byte address
+***************************************************************************************************
+*/
+UINT_64 SIAddrLib::HwlComputeXmaskAddrFromCoord(
+ UINT_32 pitch, ///< [in] pitch
+ UINT_32 height, ///< [in] height
+ UINT_32 x, ///< [in] x coord
+ UINT_32 y, ///< [in] y coord
+ UINT_32 slice, ///< [in] slice/depth index
+ UINT_32 numSlices, ///< [in] number of slices
+ UINT_32 factor, ///< [in] factor that indicates cmask(2) or htile(1)
+ BOOL_32 isLinear, ///< [in] linear or tiled HTILE layout
+ BOOL_32 isWidth8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
+ BOOL_32 isHeight8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
+ ADDR_TILEINFO* pTileInfo, ///< [in] Tile info
+ UINT_32* pBitPosition ///< [out] bit position inside a byte
+ ) const
+{
+ UINT_32 tx = x / MicroTileWidth;
+ UINT_32 ty = y / MicroTileHeight;
+ UINT_32 newPitch;
+ UINT_32 newHeight;
+ UINT_64 totalBytes;
+ UINT_32 macroWidth;
+ UINT_32 macroHeight;
+ UINT_64 pSliceBytes;
+ UINT_32 pBaseAlign;
+ UINT_32 tileNumPerPipe;
+ UINT_32 elemBits;
+
+ if (factor == 2) //CMASK
+ {
+ ADDR_CMASK_FLAGS flags = {{0}};
+
+ tileNumPerPipe = 256;
+
+ ComputeCmaskInfo(flags,
+ pitch,
+ height,
+ numSlices,
+ isLinear,
+ pTileInfo,
+ &newPitch,
+ &newHeight,
+ &totalBytes,
+ &macroWidth,
+ &macroHeight);
+ elemBits = CmaskElemBits;
+ }
+ else //HTile
+ {
+ ADDR_HTILE_FLAGS flags = {{0}};
+
+ tileNumPerPipe = 512;
+
+ ComputeHtileInfo(flags,
+ pitch,
+ height,
+ numSlices,
+ isLinear,
+ TRUE,
+ TRUE,
+ pTileInfo,
+ &newPitch,
+ &newHeight,
+ &totalBytes,
+ &macroWidth,
+ &macroHeight,
+ &pSliceBytes,
+ &pBaseAlign);
+ elemBits = 32;
+ }
+
+ const UINT_32 pitchInTile = newPitch / MicroTileWidth;
+ const UINT_32 heightInTile = newHeight / MicroTileWidth;
+ UINT_64 macroOffset; // Per pipe starting offset of the macro tile in which this tile lies.
+ UINT_64 microNumber; // Per pipe starting offset of the macro tile in which this tile lies.
+ UINT_32 microX;
+ UINT_32 microY;
+ UINT_64 microOffset;
+ UINT_32 microShift;
+ UINT_64 totalOffset;
+ UINT_32 elemIdxBits;
+ UINT_32 elemIdx =
+ TileCoordToMaskElementIndex(tx, ty, pTileInfo->pipeConfig, &microShift, &elemIdxBits);
+
+ UINT_32 numPipes = HwlGetPipes(pTileInfo);
+
+ if (isLinear)
+ { //linear addressing
+ // Linear addressing is extremelly wasting memory if slice > 1, since each pipe has the full
+ // slice memory foot print instead of divided by numPipes.
+ microX = tx / 4; // Macro Tile is 4x4
+ microY = ty / 4 ;
+ microNumber = static_cast<UINT_64>(microX + microY * (pitchInTile / 4)) << microShift;
+
+ UINT_32 sliceBits = pitchInTile * heightInTile;
+
+ // do htile single slice alignment if the flag is true
+ if (m_configFlags.useHtileSliceAlign && (factor == 1)) //Htile
+ {
+ sliceBits = PowTwoAlign(sliceBits, BITS_TO_BYTES(HtileCacheBits) * numPipes / elemBits);
+ }
+ macroOffset = slice * (sliceBits / numPipes) * elemBits ;
+ }
+ else
+ { //tiled addressing
+ const UINT_32 macroWidthInTile = macroWidth / MicroTileWidth; // Now in unit of Tiles
+ const UINT_32 macroHeightInTile = macroHeight / MicroTileHeight;
+ const UINT_32 pitchInCL = pitchInTile / macroWidthInTile;
+ const UINT_32 heightInCL = heightInTile / macroHeightInTile;
+
+ const UINT_32 macroX = x / macroWidth;
+ const UINT_32 macroY = y / macroHeight;
+ const UINT_32 macroNumber = macroX + macroY * pitchInCL + slice * pitchInCL * heightInCL;
+
+ // Per pipe starting offset of the cache line in which this tile lies.
+ microX = (x % macroWidth) / MicroTileWidth / 4; // Macro Tile is 4x4
+ microY = (y % macroHeight) / MicroTileHeight / 4 ;
+ microNumber = static_cast<UINT_64>(microX + microY * (macroWidth / MicroTileWidth / 4)) << microShift;
+
+ macroOffset = macroNumber * tileNumPerPipe * elemBits;
+ }
+
+ if(elemIdxBits == microShift)
+ {
+ microNumber += elemIdx;
+ }
+ else
+ {
+ microNumber >>= elemIdxBits;
+ microNumber <<= elemIdxBits;
+ microNumber += elemIdx;
+ }
+
+ microOffset = elemBits * microNumber;
+ totalOffset = microOffset + macroOffset;
+
+ UINT_32 pipe = ComputePipeFromCoord(x, y, 0, ADDR_TM_2D_TILED_THIN1, 0, FALSE, pTileInfo);
+ UINT_64 addrInBits = totalOffset % (m_pipeInterleaveBytes * 8) +
+ pipe * (m_pipeInterleaveBytes * 8) +
+ totalOffset / (m_pipeInterleaveBytes * 8) * (m_pipeInterleaveBytes * 8) * numPipes;
+ *pBitPosition = static_cast<UINT_32>(addrInBits) % 8;
+ UINT_64 addr = addrInBits / 8;
+
+ return addr;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlComputeXmaskCoordFromAddr
+*
+* @brief
+* Compute the coord from an address of a cmask/htile
+*
+* @return
+* N/A
+*
+* @note
+* This method is reused by htile, so rename to Xmask
+***************************************************************************************************
+*/
+VOID SIAddrLib::HwlComputeXmaskCoordFromAddr(
+ UINT_64 addr, ///< [in] address
+ UINT_32 bitPosition, ///< [in] bitPosition in a byte
+ UINT_32 pitch, ///< [in] pitch
+ UINT_32 height, ///< [in] height
+ UINT_32 numSlices, ///< [in] number of slices
+ UINT_32 factor, ///< [in] factor that indicates cmask or htile
+ BOOL_32 isLinear, ///< [in] linear or tiled HTILE layout
+ BOOL_32 isWidth8, ///< [in] Not used by SI
+ BOOL_32 isHeight8, ///< [in] Not used by SI
+ ADDR_TILEINFO* pTileInfo, ///< [in] Tile info
+ UINT_32* pX, ///< [out] x coord
+ UINT_32* pY, ///< [out] y coord
+ UINT_32* pSlice ///< [out] slice index
+ ) const
+{
+ UINT_32 newPitch;
+ UINT_32 newHeight;
+ UINT_64 totalBytes;
+ UINT_32 clWidth;
+ UINT_32 clHeight;
+ UINT_32 tileNumPerPipe;
+ UINT_64 sliceBytes;
+
+ *pX = 0;
+ *pY = 0;
+ *pSlice = 0;
+
+ if (factor == 2) //CMASK
+ {
+ ADDR_CMASK_FLAGS flags = {{0}};
+
+ tileNumPerPipe = 256;
+
+ ComputeCmaskInfo(flags,
+ pitch,
+ height,
+ numSlices,
+ isLinear,
+ pTileInfo,
+ &newPitch,
+ &newHeight,
+ &totalBytes,
+ &clWidth,
+ &clHeight);
+ }
+ else //HTile
+ {
+ ADDR_HTILE_FLAGS flags = {{0}};
+
+ tileNumPerPipe = 512;
+
+ ComputeHtileInfo(flags,
+ pitch,
+ height,
+ numSlices,
+ isLinear,
+ TRUE,
+ TRUE,
+ pTileInfo,
+ &newPitch,
+ &newHeight,
+ &totalBytes,
+ &clWidth,
+ &clHeight,
+ &sliceBytes);
+ }
+
+ const UINT_32 pitchInTile = newPitch / MicroTileWidth;
+ const UINT_32 heightInTile = newHeight / MicroTileWidth;
+ const UINT_32 pitchInMacroTile = pitchInTile / 4;
+ UINT_32 macroShift;
+ UINT_32 elemIdxBits;
+ // get macroShift and elemIdxBits
+ TileCoordToMaskElementIndex(0, 0, pTileInfo->pipeConfig, &macroShift, &elemIdxBits);
+
+ const UINT_32 numPipes = HwlGetPipes(pTileInfo);
+ const UINT_32 pipe = (UINT_32)((addr / m_pipeInterleaveBytes) % numPipes);
+ // per pipe
+ UINT_64 localOffset = (addr % m_pipeInterleaveBytes) +
+ (addr / m_pipeInterleaveBytes / numPipes)* m_pipeInterleaveBytes;
+
+ UINT_32 tileIndex;
+ if (factor == 2) //CMASK
+ {
+ tileIndex = (UINT_32)(localOffset * 2 + (bitPosition != 0));
+ }
+ else
+ {
+ tileIndex = (UINT_32)(localOffset / 4);
+ }
+
+ UINT_32 macroOffset;
+ if (isLinear)
+ {
+ UINT_32 sliceSizeInTile = pitchInTile * heightInTile;
+
+ // do htile single slice alignment if the flag is true
+ if (m_configFlags.useHtileSliceAlign && (factor == 1)) //Htile
+ {
+ sliceSizeInTile = PowTwoAlign(sliceSizeInTile, static_cast<UINT_32>(sliceBytes) / 64);
+ }
+ *pSlice = tileIndex / (sliceSizeInTile / numPipes);
+ macroOffset = tileIndex % (sliceSizeInTile / numPipes);
+ }
+ else
+ {
+ const UINT_32 clWidthInTile = clWidth / MicroTileWidth; // Now in unit of Tiles
+ const UINT_32 clHeightInTile = clHeight / MicroTileHeight;
+ const UINT_32 pitchInCL = pitchInTile / clWidthInTile;
+ const UINT_32 heightInCL = heightInTile / clHeightInTile;
+ const UINT_32 clIndex = tileIndex / tileNumPerPipe;
+
+ UINT_32 clX = clIndex % pitchInCL;
+ UINT_32 clY = (clIndex % (heightInCL * pitchInCL)) / pitchInCL;
+
+ *pX = clX * clWidthInTile * MicroTileWidth;
+ *pY = clY * clHeightInTile * MicroTileHeight;
+ *pSlice = clIndex / (heightInCL * pitchInCL);
+
+ macroOffset = tileIndex % tileNumPerPipe;
+ }
+
+ UINT_32 elemIdx = macroOffset & 7;
+ macroOffset >>= elemIdxBits;
+
+ if (elemIdxBits != macroShift)
+ {
+ macroOffset <<= (elemIdxBits - macroShift);
+
+ UINT_32 pipebit1 = _BIT(pipe,1);
+ UINT_32 pipebit2 = _BIT(pipe,2);
+ UINT_32 pipebit3 = _BIT(pipe,3);
+ if (pitchInMacroTile % 2)
+ { //odd
+ switch (pTileInfo->pipeConfig)
+ {
+ case ADDR_PIPECFG_P4_32x32:
+ macroOffset |= pipebit1;
+ break;
+ case ADDR_PIPECFG_P8_32x32_8x16:
+ case ADDR_PIPECFG_P8_32x32_16x16:
+ case ADDR_PIPECFG_P8_32x32_16x32:
+ macroOffset |= pipebit2;
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ if (pitchInMacroTile % 4)
+ {
+ if (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32)
+ {
+ macroOffset |= (pipebit1<<1);
+ }
+ if((pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_8x16) ||
+ (pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_16x16))
+ {
+ macroOffset |= (pipebit3<<1);
+ }
+ }
+ }
+
+ UINT_32 macroX;
+ UINT_32 macroY;
+
+ if (isLinear)
+ {
+ macroX = macroOffset % pitchInMacroTile;
+ macroY = macroOffset / pitchInMacroTile;
+ }
+ else
+ {
+ const UINT_32 clWidthInMacroTile = clWidth / (MicroTileWidth * 4);
+ macroX = macroOffset % clWidthInMacroTile;
+ macroY = macroOffset / clWidthInMacroTile;
+ }
+
+ *pX += macroX * 4 * MicroTileWidth;
+ *pY += macroY * 4 * MicroTileHeight;
+
+ UINT_32 microX;
+ UINT_32 microY;
+ ComputeTileCoordFromPipeAndElemIdx(elemIdx, pipe, pTileInfo->pipeConfig, pitchInMacroTile,
+ *pX, *pY, &microX, &microY);
+
+ *pX += microX * MicroTileWidth;
+ *pY += microY * MicroTileWidth;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlGetPitchAlignmentLinear
+* @brief
+* Get pitch alignment
+* @return
+* pitch alignment
+***************************************************************************************************
+*/
+UINT_32 SIAddrLib::HwlGetPitchAlignmentLinear(
+ UINT_32 bpp, ///< [in] bits per pixel
+ ADDR_SURFACE_FLAGS flags ///< [in] surface flags
+ ) const
+{
+ UINT_32 pitchAlign;
+
+ // Interleaved access requires a 256B aligned pitch, so fall back to pre-SI alignment
+ if (flags.interleaved)
+ {
+ pitchAlign = Max(64u, m_pipeInterleaveBytes / BITS_TO_BYTES(bpp));
+
+ }
+ else
+ {
+ pitchAlign = Max(8u, 64 / BITS_TO_BYTES(bpp));
+ }
+
+ return pitchAlign;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlGetSizeAdjustmentLinear
+*
+* @brief
+* Adjust linear surface pitch and slice size
+*
+* @return
+* Logical slice size in bytes
+***************************************************************************************************
+*/
+UINT_64 SIAddrLib::HwlGetSizeAdjustmentLinear(
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 bpp, ///< [in] bits per pixel
+ UINT_32 numSamples, ///< [in] number of samples
+ UINT_32 baseAlign, ///< [in] base alignment
+ UINT_32 pitchAlign, ///< [in] pitch alignment
+ UINT_32* pPitch, ///< [in/out] pointer to pitch
+ UINT_32* pHeight, ///< [in/out] pointer to height
+ UINT_32* pHeightAlign ///< [in/out] pointer to height align
+ ) const
+{
+ UINT_64 sliceSize;
+ if (tileMode == ADDR_TM_LINEAR_GENERAL)
+ {
+ sliceSize = BITS_TO_BYTES(static_cast<UINT_64>(*pPitch) * (*pHeight) * bpp * numSamples);
+ }
+ else
+ {
+ UINT_32 pitch = *pPitch;
+ UINT_32 height = *pHeight;
+
+ UINT_32 pixelsPerPipeInterleave = m_pipeInterleaveBytes / BITS_TO_BYTES(bpp);
+ UINT_32 sliceAlignInPixel = pixelsPerPipeInterleave < 64 ? 64 : pixelsPerPipeInterleave;
+
+ // numSamples should be 1 in real cases (no MSAA for linear but TGL may pass non 1 value)
+ UINT_64 pixelPerSlice = static_cast<UINT_64>(pitch) * height * numSamples;
+
+ while (pixelPerSlice % sliceAlignInPixel)
+ {
+ pitch += pitchAlign;
+ pixelPerSlice = static_cast<UINT_64>(pitch) * height * numSamples;
+ }
+
+ *pPitch = pitch;
+
+ UINT_32 heightAlign = 1;
+
+ while ((pitch * heightAlign) % sliceAlignInPixel)
+ {
+ heightAlign++;
+ }
+
+ *pHeightAlign = heightAlign;
+
+ sliceSize = BITS_TO_BYTES(pixelPerSlice * bpp);
+ }
+
+ return sliceSize;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlPreHandleBaseLvl3xPitch
+*
+* @brief
+* Pre-handler of 3x pitch (96 bit) adjustment
+*
+* @return
+* Expected pitch
+***************************************************************************************************
+*/
+UINT_32 SIAddrLib::HwlPreHandleBaseLvl3xPitch(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input
+ UINT_32 expPitch ///< [in] pitch
+ ) const
+{
+ ADDR_ASSERT(pIn->width == expPitch);
+
+ // From SI, if pow2Pad is 1 the pitch is expanded 3x first, then padded to pow2, so nothing to
+ // do here
+ if (!pIn->flags.pow2Pad)
+ {
+ AddrLib::HwlPreHandleBaseLvl3xPitch(pIn, expPitch);
+ }
+ else
+ {
+ ADDR_ASSERT(IsPow2(expPitch));
+ }
+
+ return expPitch;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlPostHandleBaseLvl3xPitch
+*
+* @brief
+* Post-handler of 3x pitch adjustment
+*
+* @return
+* Expected pitch
+***************************************************************************************************
+*/
+UINT_32 SIAddrLib::HwlPostHandleBaseLvl3xPitch(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input
+ UINT_32 expPitch ///< [in] pitch
+ ) const
+{
+ /**
+ * @note The pitch will be divided by 3 in the end so the value will look odd but h/w should
+ * be able to compute a correct pitch from it as h/w address library is doing the job.
+ */
+ // From SI, the pitch is expanded 3x first, then padded to pow2, so no special handler here
+ if (!pIn->flags.pow2Pad)
+ {
+ AddrLib::HwlPostHandleBaseLvl3xPitch(pIn, expPitch);
+ }
+
+ return expPitch;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlGetPitchAlignmentMicroTiled
+*
+* @brief
+* Compute 1D tiled surface pitch alignment
+*
+* @return
+* pitch alignment
+***************************************************************************************************
+*/
+UINT_32 SIAddrLib::HwlGetPitchAlignmentMicroTiled(
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32 bpp, ///< [in] bits per pixel
+ ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
+ UINT_32 numSamples ///< [in] number of samples
+ ) const
+{
+ UINT_32 pitchAlign;
+
+ if (flags.qbStereo)
+ {
+ pitchAlign = EgBasedAddrLib::HwlGetPitchAlignmentMicroTiled(tileMode,bpp,flags,numSamples);
+ }
+ else
+ {
+ pitchAlign = 8;
+ }
+
+ return pitchAlign;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlGetSizeAdjustmentMicroTiled
+*
+* @brief
+* Adjust 1D tiled surface pitch and slice size
+*
+* @return
+* Logical slice size in bytes
+***************************************************************************************************
+*/
+UINT_64 SIAddrLib::HwlGetSizeAdjustmentMicroTiled(
+ UINT_32 thickness, ///< [in] thickness
+ UINT_32 bpp, ///< [in] bits per pixel
+ ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
+ UINT_32 numSamples, ///< [in] number of samples
+ UINT_32 baseAlign, ///< [in] base alignment
+ UINT_32 pitchAlign, ///< [in] pitch alignment
+ UINT_32* pPitch, ///< [in/out] pointer to pitch
+ UINT_32* pHeight ///< [in/out] pointer to height
+ ) const
+{
+ UINT_64 logicalSliceSize;
+ UINT_64 physicalSliceSize;
+
+ UINT_32 pitch = *pPitch;
+ UINT_32 height = *pHeight;
+
+ // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
+ logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
+
+ // Physical slice: multiplied by thickness
+ physicalSliceSize = logicalSliceSize * thickness;
+
+ // Pitch alignment is always 8, so if slice size is not padded to base alignment
+ // (pipe_interleave_size), we need to increase pitch
+ while ((physicalSliceSize % baseAlign) != 0)
+ {
+ pitch += pitchAlign;
+
+ logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
+
+ physicalSliceSize = logicalSliceSize * thickness;
+ }
+
+#if !ALT_TEST
+ //
+ // Special workaround for depth/stencil buffer, use 8 bpp to align depth buffer again since
+ // the stencil plane may have larger pitch if the slice size is smaller than base alignment.
+ //
+ // Note: this actually does not work for mipmap but mipmap depth texture is not really
+ // sampled with mipmap.
+ //
+ if (flags.depth && !flags.noStencil)
+ {
+ ADDR_ASSERT(numSamples == 1);
+
+ UINT_64 logicalSiceSizeStencil = static_cast<UINT_64>(pitch) * height; // 1 byte stencil
+
+ while ((logicalSiceSizeStencil % baseAlign) != 0)
+ {
+ pitch += pitchAlign; // Stencil plane's pitch alignment is the same as depth plane's
+
+ logicalSiceSizeStencil = static_cast<UINT_64>(pitch) * height;
+ }
+
+ if (pitch != *pPitch)
+ {
+ // If this is a mipmap, this padded one cannot be sampled as a whole mipmap!
+ logicalSliceSize = logicalSiceSizeStencil * BITS_TO_BYTES(bpp);
+ }
+ }
+#endif
+ *pPitch = pitch;
+
+ // No adjust for pHeight
+
+ return logicalSliceSize;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlConvertChipFamily
+*
+* @brief
+* Convert familyID defined in atiid.h to AddrChipFamily and set m_chipFamily/m_chipRevision
+* @return
+* AddrChipFamily
+***************************************************************************************************
+*/
+AddrChipFamily SIAddrLib::HwlConvertChipFamily(
+ UINT_32 uChipFamily, ///< [in] chip family defined in atiih.h
+ UINT_32 uChipRevision) ///< [in] chip revision defined in "asic_family"_id.h
+{
+ AddrChipFamily family = ADDR_CHIP_FAMILY_SI;
+
+ switch (uChipFamily)
+ {
+ case FAMILY_SI:
+ m_settings.isSouthernIsland = 1;
+ m_settings.isTahiti = ASICREV_IS_TAHITI_P(uChipRevision);
+ m_settings.isPitCairn = ASICREV_IS_PITCAIRN_PM(uChipRevision);
+ m_settings.isCapeVerde = ASICREV_IS_CAPEVERDE_M(uChipRevision);
+ m_settings.isOland = ASICREV_IS_OLAND_M(uChipRevision);
+ m_settings.isHainan = ASICREV_IS_HAINAN_V(uChipRevision);
+ break;
+ default:
+ ADDR_ASSERT(!"This should be a Fusion");
+ break;
+ }
+
+ return family;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlSetupTileInfo
+*
+* @brief
+* Setup default value of tile info for SI
+***************************************************************************************************
+*/
+VOID SIAddrLib::HwlSetupTileInfo(
+ AddrTileMode tileMode, ///< [in] Tile mode
+ ADDR_SURFACE_FLAGS flags, ///< [in] Surface type flags
+ UINT_32 bpp, ///< [in] Bits per pixel
+ UINT_32 pitch, ///< [in] Pitch in pixels
+ UINT_32 height, ///< [in] Height in pixels
+ UINT_32 numSamples, ///< [in] Number of samples
+ ADDR_TILEINFO* pTileInfoIn, ///< [in] Tile info input: NULL for default
+ ADDR_TILEINFO* pTileInfoOut, ///< [out] Tile info output
+ AddrTileType inTileType, ///< [in] Tile type
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] Output
+ ) const
+{
+ UINT_32 thickness = ComputeSurfaceThickness(tileMode);
+ ADDR_TILEINFO* pTileInfo = pTileInfoOut;
+ INT index = TileIndexInvalid;
+
+ // Fail-safe code
+ if (!IsLinear(tileMode))
+ {
+ // 128 bpp/thick tiling must be non-displayable.
+ // Fmask reuse color buffer's entry but bank-height field can be from another entry
+ // To simplify the logic, fmask entry should be picked from non-displayable ones
+ if (bpp == 128 || thickness > 1 || flags.fmask || flags.prt)
+ {
+ inTileType = ADDR_NON_DISPLAYABLE;
+ }
+
+ if (flags.depth || flags.stencil)
+ {
+ inTileType = ADDR_DEPTH_SAMPLE_ORDER;
+ }
+ }
+
+ // Partial valid fields are not allowed for SI.
+ if (IsTileInfoAllZero(pTileInfo))
+ {
+ if (IsMacroTiled(tileMode))
+ {
+ if (flags.prt)
+ {
+ if (numSamples == 1)
+ {
+ if (flags.depth)
+ {
+ switch (bpp)
+ {
+ case 16:
+ index = 3;
+ break;
+ case 32:
+ index = 6;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ break;
+ }
+ }
+ else
+ {
+ switch (bpp)
+ {
+ case 8:
+ index = 21;
+ break;
+ case 16:
+ index = 22;
+ break;
+ case 32:
+ index = 23;
+ break;
+ case 64:
+ index = 24;
+ break;
+ case 128:
+ index = 25;
+ break;
+ default:
+ break;
+ }
+
+ if (thickness > 1)
+ {
+ ADDR_ASSERT(bpp != 128);
+ index += 5;
+ }
+ }
+ }
+ else
+ {
+ ADDR_ASSERT(numSamples == 4);
+
+ if (flags.depth)
+ {
+ switch (bpp)
+ {
+ case 16:
+ index = 5;
+ break;
+ case 32:
+ index = 7;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ break;
+ }
+ }
+ else
+ {
+ switch (bpp)
+ {
+ case 8:
+ index = 23;
+ break;
+ case 16:
+ index = 24;
+ break;
+ case 32:
+ index = 25;
+ break;
+ case 64:
+ index = 30;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ break;
+ }
+ }
+ }
+ }//end of PRT part
+ // See table entries 0-7
+ else if (flags.depth || flags.stencil)
+ {
+ if (flags.compressZ)
+ {
+ if (flags.stencil)
+ {
+ index = 0;
+ }
+ else
+ {
+ // optimal tile index for compressed depth/stencil.
+ switch (numSamples)
+ {
+ case 1:
+ index = 0;
+ break;
+ case 2:
+ case 4:
+ index = 1;
+ break;
+ case 8:
+ index = 2;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else // unCompressZ
+ {
+ index = 3;
+ }
+ }
+ else //non PRT & non Depth & non Stencil
+ {
+ // See table entries 9-12
+ if (inTileType == ADDR_DISPLAYABLE)
+ {
+ switch (bpp)
+ {
+ case 8:
+ index = 10;
+ break;
+ case 16:
+ index = 11;
+ break;
+ case 32:
+ index = 12;
+ break;
+ case 64:
+ index = 12;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ // See table entries 13-17
+ if (thickness == 1)
+ {
+ if (flags.fmask)
+ {
+ UINT_32 fmaskPixelSize = bpp * numSamples;
+
+ switch (fmaskPixelSize)
+ {
+ case 8:
+ index = 14;
+ break;
+ case 16:
+ index = 15;
+ break;
+ case 32:
+ index = 16;
+ break;
+ case 64:
+ index = 17;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ }
+ }
+ else
+ {
+ switch (bpp)
+ {
+ case 8:
+ index = 14;
+ break;
+ case 16:
+ index = 15;
+ break;
+ case 32:
+ index = 16;
+ break;
+ case 64:
+ index = 17;
+ break;
+ case 128:
+ index = 17;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else // thick tiling - entries 18-20
+ {
+ switch (thickness)
+ {
+ case 4:
+ index = 20;
+ break;
+ case 8:
+ index = 19;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (tileMode == ADDR_TM_LINEAR_ALIGNED)
+ {
+ index = 8;
+ }
+ else if (tileMode == ADDR_TM_LINEAR_GENERAL)
+ {
+ index = TileIndexLinearGeneral;
+ }
+ else
+ {
+ if (flags.depth || flags.stencil)
+ {
+ index = 4;
+ }
+ else if (inTileType == ADDR_DISPLAYABLE)
+ {
+ index = 9;
+ }
+ else if (thickness == 1)
+ {
+ index = 13;
+ }
+ else
+ {
+ index = 18;
+ }
+ }
+ }
+
+ if (index >= 0 && index <= 31)
+ {
+ *pTileInfo = m_tileTable[index].info;
+ pOut->tileType = m_tileTable[index].type;
+ }
+
+ if (index == TileIndexLinearGeneral)
+ {
+ *pTileInfo = m_tileTable[8].info;
+ pOut->tileType = m_tileTable[8].type;
+ }
+ }
+ else
+ {
+ if (pTileInfoIn)
+ {
+ if (flags.stencil && pTileInfoIn->tileSplitBytes == 0)
+ {
+ // Stencil always uses index 0
+ *pTileInfo = m_tileTable[0].info;
+ }
+ }
+ // Pass through tile type
+ pOut->tileType = inTileType;
+ }
+
+ pOut->tileIndex = index;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::DecodeGbRegs
+*
+* @brief
+* Decodes GB_ADDR_CONFIG and noOfBanks/noOfRanks
+*
+* @return
+* TRUE if all settings are valid
+*
+***************************************************************************************************
+*/
+BOOL_32 SIAddrLib::DecodeGbRegs(
+ const ADDR_REGISTER_VALUE* pRegValue) ///< [in] create input
+{
+ GB_ADDR_CONFIG reg;
+ BOOL_32 valid = TRUE;
+
+ reg.val = pRegValue->gbAddrConfig;
+
+ switch (reg.f.pipe_interleave_size)
+ {
+ case ADDR_CONFIG_PIPE_INTERLEAVE_256B:
+ m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_256B;
+ break;
+ case ADDR_CONFIG_PIPE_INTERLEAVE_512B:
+ m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_512B;
+ break;
+ default:
+ valid = FALSE;
+ ADDR_UNHANDLED_CASE();
+ break;
+ }
+
+ switch (reg.f.row_size)
+ {
+ case ADDR_CONFIG_1KB_ROW:
+ m_rowSize = ADDR_ROWSIZE_1KB;
+ break;
+ case ADDR_CONFIG_2KB_ROW:
+ m_rowSize = ADDR_ROWSIZE_2KB;
+ break;
+ case ADDR_CONFIG_4KB_ROW:
+ m_rowSize = ADDR_ROWSIZE_4KB;
+ break;
+ default:
+ valid = FALSE;
+ ADDR_UNHANDLED_CASE();
+ break;
+ }
+
+ switch (pRegValue->noOfBanks)
+ {
+ case 0:
+ m_banks = 4;
+ break;
+ case 1:
+ m_banks = 8;
+ break;
+ case 2:
+ m_banks = 16;
+ break;
+ default:
+ valid = FALSE;
+ ADDR_UNHANDLED_CASE();
+ break;
+ }
+
+ switch (pRegValue->noOfRanks)
+ {
+ case 0:
+ m_ranks = 1;
+ break;
+ case 1:
+ m_ranks = 2;
+ break;
+ default:
+ valid = FALSE;
+ ADDR_UNHANDLED_CASE();
+ break;
+ }
+
+ m_logicalBanks = m_banks * m_ranks;
+
+ ADDR_ASSERT(m_logicalBanks <= 16);
+
+ return valid;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlInitGlobalParams
+*
+* @brief
+* Initializes global parameters
+*
+* @return
+* TRUE if all settings are valid
+*
+***************************************************************************************************
+*/
+BOOL_32 SIAddrLib::HwlInitGlobalParams(
+ const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input
+{
+ BOOL_32 valid = TRUE;
+ const ADDR_REGISTER_VALUE* pRegValue = &pCreateIn->regValue;
+
+ valid = DecodeGbRegs(pRegValue);
+
+ if (valid)
+ {
+ if (m_settings.isTahiti || m_settings.isPitCairn)
+ {
+ m_pipes = 8;
+ }
+ else if (m_settings.isCapeVerde || m_settings.isOland)
+ {
+ m_pipes = 4;
+ }
+ else
+ {
+ // Hainan is 2-pipe (m_settings.isHainan == 1)
+ m_pipes = 2;
+ }
+
+ valid = InitTileSettingTable(pRegValue->pTileConfig, pRegValue->noOfEntries);
+
+ m_maxSamples = 16;
+ }
+
+ return valid;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlConvertTileInfoToHW
+* @brief
+* Entry of si's ConvertTileInfoToHW
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE SIAddrLib::HwlConvertTileInfoToHW(
+ const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure
+ ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ ADDR_E_RETURNCODE retCode = ADDR_OK;
+
+ retCode = EgBasedAddrLib::HwlConvertTileInfoToHW(pIn, pOut);
+
+ if (retCode == ADDR_OK)
+ {
+ if (pIn->reverse == FALSE)
+ {
+ if (pIn->pTileInfo->pipeConfig == ADDR_PIPECFG_INVALID)
+ {
+ retCode = ADDR_INVALIDPARAMS;
+ }
+ else
+ {
+ pOut->pTileInfo->pipeConfig =
+ static_cast<AddrPipeCfg>(pIn->pTileInfo->pipeConfig - 1);
+ }
+ }
+ else
+ {
+ pOut->pTileInfo->pipeConfig =
+ static_cast<AddrPipeCfg>(pIn->pTileInfo->pipeConfig + 1);
+ }
+ }
+
+ return retCode;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlComputeXmaskCoordYFrom8Pipe
+*
+* @brief
+* Compute the Y coord which will be added to Xmask Y
+* coord.
+* @return
+* Y coord
+***************************************************************************************************
+*/
+UINT_32 SIAddrLib::HwlComputeXmaskCoordYFrom8Pipe(
+ UINT_32 pipe, ///< [in] pipe id
+ UINT_32 x ///< [in] tile coord x, which is original x coord / 8
+ ) const
+{
+ // This function should never be called since it is 6xx/8xx specfic.
+ // Keep this empty implementation to avoid any mis-use.
+ ADDR_ASSERT_ALWAYS();
+
+ return 0;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlComputeSurfaceCoord2DFromBankPipe
+*
+* @brief
+* Compute surface x,y coordinates from bank/pipe info
+* @return
+* N/A
+***************************************************************************************************
+*/
+VOID SIAddrLib::HwlComputeSurfaceCoord2DFromBankPipe(
+ AddrTileMode tileMode, ///< [in] tile mode
+ UINT_32* pX, ///< [in/out] x coordinate
+ UINT_32* pY, ///< [in/out] y coordinate
+ UINT_32 slice, ///< [in] slice index
+ UINT_32 bank, ///< [in] bank number
+ UINT_32 pipe, ///< [in] pipe number
+ UINT_32 bankSwizzle,///< [in] bank swizzle
+ UINT_32 pipeSwizzle,///< [in] pipe swizzle
+ UINT_32 tileSlices, ///< [in] slices in a micro tile
+ BOOL_32 ignoreSE, ///< [in] TRUE if shader engines are ignored
+ ADDR_TILEINFO* pTileInfo ///< [in] bank structure. **All fields to be valid on entry**
+ ) const
+{
+ UINT_32 xBit;
+ UINT_32 yBit;
+ UINT_32 yBit3 = 0;
+ UINT_32 yBit4 = 0;
+ UINT_32 yBit5 = 0;
+ UINT_32 yBit6 = 0;
+
+ UINT_32 xBit3 = 0;
+ UINT_32 xBit4 = 0;
+ UINT_32 xBit5 = 0;
+
+ UINT_32 numPipes = GetPipePerSurf(pTileInfo->pipeConfig);
+
+ CoordFromBankPipe xyBits = {0};
+ ComputeSurfaceCoord2DFromBankPipe(tileMode, *pX, *pY, slice, bank, pipe,
+ bankSwizzle, pipeSwizzle, tileSlices, pTileInfo,
+ &xyBits);
+ yBit3 = xyBits.yBit3;
+ yBit4 = xyBits.yBit4;
+ yBit5 = xyBits.yBit5;
+ yBit6 = xyBits.yBit6;
+
+ xBit3 = xyBits.xBit3;
+ xBit4 = xyBits.xBit4;
+ xBit5 = xyBits.xBit5;
+
+ yBit = xyBits.yBits;
+
+ UINT_32 yBitTemp = 0;
+
+ if ((pTileInfo->pipeConfig == ADDR_PIPECFG_P4_32x32) ||
+ (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32))
+ {
+ ADDR_ASSERT(pTileInfo->bankWidth == 1 && pTileInfo->macroAspectRatio > 1);
+ UINT_32 yBitToCheck = QLog2(pTileInfo->banks) - 1;
+
+ ADDR_ASSERT(yBitToCheck <= 3);
+
+ yBitTemp = _BIT(yBit, yBitToCheck);
+
+ xBit3 = 0;
+ }
+
+ yBit = Bits2Number(4, yBit6, yBit5, yBit4, yBit3);
+ xBit = Bits2Number(3, xBit5, xBit4, xBit3);
+
+ *pY += yBit * pTileInfo->bankHeight * MicroTileHeight;
+ *pX += xBit * numPipes * pTileInfo->bankWidth * MicroTileWidth;
+
+ //calculate the bank and pipe bits in x, y
+ UINT_32 xTile; //x in micro tile
+ UINT_32 x3 = 0;
+ UINT_32 x4 = 0;
+ UINT_32 x5 = 0;
+ UINT_32 x6 = 0;
+ UINT_32 y = *pY;
+
+ UINT_32 pipeBit0 = _BIT(pipe,0);
+ UINT_32 pipeBit1 = _BIT(pipe,1);
+ UINT_32 pipeBit2 = _BIT(pipe,2);
+
+ UINT_32 y3 = _BIT(y, 3);
+ UINT_32 y4 = _BIT(y, 4);
+ UINT_32 y5 = _BIT(y, 5);
+ UINT_32 y6 = _BIT(y, 6);
+
+ // bankbit0 after ^x4^x5
+ UINT_32 bankBit00 = _BIT(bank,0);
+ UINT_32 bankBit0 = 0;
+
+ switch (pTileInfo->pipeConfig)
+ {
+ case ADDR_PIPECFG_P2:
+ x3 = pipeBit0 ^ y3;
+ break;
+ case ADDR_PIPECFG_P4_8x16:
+ x4 = pipeBit0 ^ y3;
+ x3 = pipeBit0 ^ y4;
+ break;
+ case ADDR_PIPECFG_P4_16x16:
+ x4 = pipeBit1 ^ y4;
+ x3 = pipeBit0 ^ y3 ^ x4;
+ break;
+ case ADDR_PIPECFG_P4_16x32:
+ x4 = pipeBit1 ^ y4;
+ x3 = pipeBit0 ^ y3 ^ x4;
+ break;
+ case ADDR_PIPECFG_P4_32x32:
+ x5 = pipeBit1 ^ y5;
+ x3 = pipeBit0 ^ y3 ^ x5;
+ bankBit0 = yBitTemp ^ x5;
+ x4 = bankBit00 ^ x5 ^ bankBit0;
+ *pX += x5 * 4 * 1 * 8; // x5 * num_pipes * bank_width * 8;
+ break;
+ case ADDR_PIPECFG_P8_16x16_8x16:
+ x3 = pipeBit1 ^ y5;
+ x4 = pipeBit2 ^ y4;
+ x5 = pipeBit0 ^ y3 ^ x4;
+ break;
+ case ADDR_PIPECFG_P8_16x32_8x16:
+ x3 = pipeBit1 ^ y4;
+ x4 = pipeBit2 ^ y5;
+ x5 = pipeBit0 ^ y3 ^ x4;
+ break;
+ case ADDR_PIPECFG_P8_32x32_8x16:
+ x3 = pipeBit1 ^ y4;
+ x5 = pipeBit2 ^ y5;
+ x4 = pipeBit0 ^ y3 ^ x5;
+ break;
+ case ADDR_PIPECFG_P8_16x32_16x16:
+ x4 = pipeBit2 ^ y5;
+ x5 = pipeBit1 ^ y4;
+ x3 = pipeBit0 ^ y3 ^ x4;
+ break;
+ case ADDR_PIPECFG_P8_32x32_16x16:
+ x5 = pipeBit2 ^ y5;
+ x4 = pipeBit1 ^ y4;
+ x3 = pipeBit0 ^ y3 ^ x4;
+ break;
+ case ADDR_PIPECFG_P8_32x32_16x32:
+ x5 = pipeBit2 ^ y5;
+ x4 = pipeBit1 ^ y6;
+ x3 = pipeBit0 ^ y3 ^ x4;
+ break;
+ case ADDR_PIPECFG_P8_32x64_32x32:
+ x6 = pipeBit1 ^ y5;
+ x5 = pipeBit2 ^ y6;
+ x3 = pipeBit0 ^ y3 ^ x5;
+ bankBit0 = yBitTemp ^ x6;
+ x4 = bankBit00 ^ x5 ^ bankBit0;
+ *pX += x6 * 8 * 1 * 8; // x6 * num_pipes * bank_width * 8;
+ break;
+ default:
+ ADDR_ASSERT_ALWAYS();
+ }
+
+ xTile = Bits2Number(3, x5, x4, x3);
+
+ *pX += xTile << 3;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlPreAdjustBank
+*
+* @brief
+* Adjust bank before calculating address acoording to bank/pipe
+* @return
+* Adjusted bank
+***************************************************************************************************
+*/
+UINT_32 SIAddrLib::HwlPreAdjustBank(
+ UINT_32 tileX, ///< [in] x coordinate in unit of tile
+ UINT_32 bank, ///< [in] bank
+ ADDR_TILEINFO* pTileInfo ///< [in] tile info
+ ) const
+{
+ if (((pTileInfo->pipeConfig == ADDR_PIPECFG_P4_32x32) ||
+ (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32)) && (pTileInfo->bankWidth == 1))
+ {
+ UINT_32 bankBit0 = _BIT(bank, 0);
+ UINT_32 x4 = _BIT(tileX, 1);
+ UINT_32 x5 = _BIT(tileX, 2);
+
+ bankBit0 = bankBit0 ^ x4 ^ x5;
+ bank |= bankBit0;
+
+ ADDR_ASSERT(pTileInfo->macroAspectRatio > 1)
+ }
+
+ return bank;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlComputeSurfaceInfo
+*
+* @brief
+* Entry of si's ComputeSurfaceInfo
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE SIAddrLib::HwlComputeSurfaceInfo(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
+ ) const
+{
+ pOut->tileIndex = pIn->tileIndex;
+
+ return EgBasedAddrLib::HwlComputeSurfaceInfo(pIn,pOut);
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlComputeMipLevel
+* @brief
+* Compute MipLevel info (including level 0)
+* @return
+* TRUE if HWL's handled
+***************************************************************************************************
+*/
+BOOL_32 SIAddrLib::HwlComputeMipLevel(
+ ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in/out] Input structure
+ ) const
+{
+ // basePitch is calculated from level 0 so we only check this for mipLevel > 0
+ if (pIn->mipLevel > 0)
+ {
+ // Note: Don't check expand 3x formats(96 bit) as the basePitch is not pow2 even if
+ // we explicity set pow2Pad flag. The 3x base pitch is padded to pow2 but after being
+ // divided by expandX factor (3) - to program texture pitch, the basePitch is never pow2.
+ if (!AddrElemLib::IsExpand3x(pIn->format))
+ {
+ // Sublevel pitches are generated from base level pitch instead of width on SI
+ // If pow2Pad is 0, we don't assert - as this is not really used for a mip chain
+ ADDR_ASSERT(!pIn->flags.pow2Pad || ((pIn->basePitch != 0) && IsPow2(pIn->basePitch)));
+ }
+
+ if (pIn->basePitch != 0)
+ {
+ pIn->width = Max(1u, pIn->basePitch >> pIn->mipLevel);
+ }
+ }
+
+ // pow2Pad is done in PostComputeMipLevel
+
+ return TRUE;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlCheckLastMacroTiledLvl
+*
+* @brief
+* Sets pOut->last2DLevel to TRUE if it is
+* @note
+*
+***************************************************************************************************
+*/
+VOID SIAddrLib::HwlCheckLastMacroTiledLvl(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in/out] Output structure (used as input, too)
+ ) const
+{
+ // pow2Pad covers all mipmap cases
+ if (pIn->flags.pow2Pad)
+ {
+ ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
+
+ UINT_32 nextPitch;
+ UINT_32 nextHeight;
+ UINT_32 nextSlices;
+
+ AddrTileMode nextTileMode;
+
+ if (pIn->mipLevel == 0 || pIn->basePitch == 0)
+ {
+ // Base level or fail-safe case (basePitch == 0)
+ nextPitch = pOut->pitch >> 1;
+ }
+ else
+ {
+ // Sub levels
+ nextPitch = pIn->basePitch >> (pIn->mipLevel + 1);
+ }
+
+ // nextHeight must be shifted from this level's original height rather than a pow2 padded
+ // one but this requires original height stored somewhere (pOut->height)
+ ADDR_ASSERT(pOut->height != 0);
+
+ // next level's height is just current level's >> 1 in pixels
+ nextHeight = pOut->height >> 1;
+ // Special format such as FMT_1 and FMT_32_32_32 can be linear only so we consider block
+ // compressed foramts
+ if (AddrElemLib::IsBlockCompressed(pIn->format))
+ {
+ nextHeight = (nextHeight + 3) / 4;
+ }
+ nextHeight = NextPow2(nextHeight);
+
+ // nextSlices may be 0 if this level's is 1
+ if (pIn->flags.volume)
+ {
+ nextSlices = Max(1u, pIn->numSlices >> 1);
+ }
+ else
+ {
+ nextSlices = pIn->numSlices;
+ }
+
+ nextTileMode = ComputeSurfaceMipLevelTileMode(pIn->tileMode,
+ pIn->bpp,
+ nextPitch,
+ nextHeight,
+ nextSlices,
+ pIn->numSamples,
+ pOut->pitchAlign,
+ pOut->heightAlign,
+ pOut->pTileInfo);
+
+ pOut->last2DLevel = IsMicroTiled(nextTileMode);
+ }
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlDegradeThickTileMode
+*
+* @brief
+* Degrades valid tile mode for thick modes if needed
+*
+* @return
+* Suitable tile mode
+***************************************************************************************************
+*/
+AddrTileMode SIAddrLib::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 EgBasedAddrLib::HwlDegradeThickTileMode(baseTileMode, numSlices, pBytesPerTile);
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlTileInfoEqual
+*
+* @brief
+* Return TRUE if all field are equal
+* @note
+* Only takes care of current HWL's data
+***************************************************************************************************
+*/
+BOOL_32 SIAddrLib::HwlTileInfoEqual(
+ const ADDR_TILEINFO* pLeft, ///<[in] Left compare operand
+ const ADDR_TILEINFO* pRight ///<[in] Right compare operand
+ ) const
+{
+ BOOL_32 equal = FALSE;
+
+ if (pLeft->pipeConfig == pRight->pipeConfig)
+ {
+ equal = EgBasedAddrLib::HwlTileInfoEqual(pLeft, pRight);
+ }
+
+ return equal;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::GetTileSettings
+*
+* @brief
+* Get tile setting infos by index.
+* @return
+* Tile setting info.
+***************************************************************************************************
+*/
+const ADDR_TILECONFIG* SIAddrLib::GetTileSetting(
+ UINT_32 index ///< [in] Tile index
+ ) const
+{
+ ADDR_ASSERT(index < m_noOfEntries);
+ return &m_tileTable[index];
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlPostCheckTileIndex
+*
+* @brief
+* Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches
+* tile mode/type/info and change the index if needed
+* @return
+* Tile index.
+***************************************************************************************************
+*/
+INT_32 SIAddrLib::HwlPostCheckTileIndex(
+ const ADDR_TILEINFO* pInfo, ///< [in] Tile Info
+ AddrTileMode mode, ///< [in] Tile mode
+ AddrTileType type, ///< [in] Tile type
+ INT curIndex ///< [in] Current index assigned in HwlSetupTileInfo
+ ) const
+{
+ INT_32 index = curIndex;
+
+ if (mode == ADDR_TM_LINEAR_GENERAL)
+ {
+ index = TileIndexLinearGeneral;
+ }
+ else
+ {
+ BOOL_32 macroTiled = IsMacroTiled(mode);
+
+ // We need to find a new index if either of them is true
+ // 1. curIndex is invalid
+ // 2. tile mode is changed
+ // 3. tile info does not match for macro tiled
+ if ((index == TileIndexInvalid ||
+ (mode != m_tileTable[index].mode) ||
+ (macroTiled && !HwlTileInfoEqual(pInfo, &m_tileTable[index].info))))
+ {
+ for (index = 0; index < static_cast<INT_32>(m_noOfEntries); index++)
+ {
+ if (macroTiled)
+ {
+ // macro tile modes need all to match
+ if (HwlTileInfoEqual(pInfo, &m_tileTable[index].info) &&
+ (mode == m_tileTable[index].mode) &&
+ (type == m_tileTable[index].type))
+ {
+ break;
+ }
+ }
+ else if (mode == ADDR_TM_LINEAR_ALIGNED)
+ {
+ // linear mode only needs tile mode to match
+ if (mode == m_tileTable[index].mode)
+ {
+ break;
+ }
+ }
+ else
+ {
+ // micro tile modes only need tile mode and tile type to match
+ if (mode == m_tileTable[index].mode &&
+ type == m_tileTable[index].type)
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ ADDR_ASSERT(index < static_cast<INT_32>(m_noOfEntries));
+
+ if (index >= static_cast<INT_32>(m_noOfEntries))
+ {
+ index = TileIndexInvalid;
+ }
+
+ return index;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlSetupTileCfg
+*
+* @brief
+* Map tile index to tile setting.
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE SIAddrLib::HwlSetupTileCfg(
+ INT_32 index, ///< [in] Tile index
+ INT_32 macroModeIndex, ///< [in] Index in macro tile mode table(CI)
+ ADDR_TILEINFO* pInfo, ///< [out] Tile Info
+ AddrTileMode* pMode, ///< [out] Tile mode
+ AddrTileType* pType ///< [out] Tile type
+ ) const
+{
+ ADDR_E_RETURNCODE returnCode = ADDR_OK;
+
+ // Global flag to control usage of tileIndex
+ if (UseTileIndex(index))
+ {
+ if (index == TileIndexLinearGeneral)
+ {
+ if (pMode)
+ {
+ *pMode = ADDR_TM_LINEAR_GENERAL;
+ }
+
+ if (pType)
+ {
+ *pType = ADDR_DISPLAYABLE;
+ }
+
+ if (pInfo)
+ {
+ pInfo->banks = 2;
+ pInfo->bankWidth = 1;
+ pInfo->bankHeight = 1;
+ pInfo->macroAspectRatio = 1;
+ pInfo->tileSplitBytes = 64;
+ pInfo->pipeConfig = ADDR_PIPECFG_P2;
+ }
+ }
+ else if (static_cast<UINT_32>(index) >= m_noOfEntries)
+ {
+ returnCode = ADDR_INVALIDPARAMS;
+ }
+ else
+ {
+ const ADDR_TILECONFIG* pCfgTable = GetTileSetting(index);
+
+ if (pInfo)
+ {
+ *pInfo = pCfgTable->info;
+ }
+ else
+ {
+ if (IsMacroTiled(pCfgTable->mode))
+ {
+ returnCode = ADDR_INVALIDPARAMS;
+ }
+ }
+
+ if (pMode)
+ {
+ *pMode = pCfgTable->mode;
+ }
+
+ if (pType)
+ {
+ *pType = pCfgTable->type;
+ }
+ }
+ }
+
+ return returnCode;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::ReadGbTileMode
+*
+* @brief
+* Convert GB_TILE_MODE HW value to ADDR_TILE_CONFIG.
+* @return
+* NA.
+***************************************************************************************************
+*/
+VOID SIAddrLib::ReadGbTileMode(
+ UINT_32 regValue, ///< [in] GB_TILE_MODE register
+ ADDR_TILECONFIG* pCfg ///< [out] output structure
+ ) const
+{
+ GB_TILE_MODE gbTileMode;
+ gbTileMode.val = regValue;
+
+ pCfg->type = static_cast<AddrTileType>(gbTileMode.f.micro_tile_mode);
+ pCfg->info.bankHeight = 1 << gbTileMode.f.bank_height;
+ pCfg->info.bankWidth = 1 << gbTileMode.f.bank_width;
+ pCfg->info.banks = 1 << (gbTileMode.f.num_banks + 1);
+ pCfg->info.macroAspectRatio = 1 << gbTileMode.f.macro_tile_aspect;
+ pCfg->info.tileSplitBytes = 64 << gbTileMode.f.tile_split;
+ pCfg->info.pipeConfig = static_cast<AddrPipeCfg>(gbTileMode.f.pipe_config + 1);
+
+ UINT_32 regArrayMode = gbTileMode.f.array_mode;
+
+ pCfg->mode = static_cast<AddrTileMode>(regArrayMode);
+
+ if (regArrayMode == 8) //ARRAY_2D_TILED_XTHICK
+ {
+ pCfg->mode = ADDR_TM_2D_TILED_XTHICK;
+ }
+ else if (regArrayMode >= 14) //ARRAY_3D_TILED_XTHICK
+ {
+ pCfg->mode = static_cast<AddrTileMode>(pCfg->mode + 3);
+ }
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::InitTileSettingTable
+*
+* @brief
+* Initialize the ADDR_TILE_CONFIG table.
+* @return
+* TRUE if tile table is correctly initialized
+***************************************************************************************************
+*/
+BOOL_32 SIAddrLib::InitTileSettingTable(
+ const UINT_32* pCfg, ///< [in] Pointer to table of tile configs
+ UINT_32 noOfEntries ///< [in] Numbe of entries in the table above
+ )
+{
+ BOOL_32 initOk = TRUE;
+
+ ADDR_ASSERT(noOfEntries <= TileTableSize);
+
+ memset(m_tileTable, 0, sizeof(m_tileTable));
+
+ if (noOfEntries != 0)
+ {
+ m_noOfEntries = noOfEntries;
+ }
+ else
+ {
+ m_noOfEntries = TileTableSize;
+ }
+
+ if (pCfg) // From Client
+ {
+ for (UINT_32 i = 0; i < m_noOfEntries; i++)
+ {
+ ReadGbTileMode(*(pCfg + i), &m_tileTable[i]);
+ }
+ }
+ else
+ {
+ ADDR_ASSERT_ALWAYS();
+ initOk = FALSE;
+ }
+
+ if (initOk)
+ {
+ ADDR_ASSERT(m_tileTable[TILEINDEX_LINEAR_ALIGNED].mode == ADDR_TM_LINEAR_ALIGNED);
+ }
+
+ return initOk;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlGetTileIndex
+*
+* @brief
+* Return the virtual/real index for given mode/type/info
+* @return
+* ADDR_OK if successful.
+***************************************************************************************************
+*/
+ADDR_E_RETURNCODE SIAddrLib::HwlGetTileIndex(
+ const ADDR_GET_TILEINDEX_INPUT* pIn,
+ ADDR_GET_TILEINDEX_OUTPUT* pOut) const
+{
+ ADDR_E_RETURNCODE returnCode = ADDR_OK;
+
+ pOut->index = HwlPostCheckTileIndex(pIn->pTileInfo, pIn->tileMode, pIn->tileType);
+
+ return returnCode;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlFmaskPreThunkSurfInfo
+*
+* @brief
+* Some preparation before thunking a ComputeSurfaceInfo call for Fmask
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+VOID SIAddrLib::HwlFmaskPreThunkSurfInfo(
+ const ADDR_COMPUTE_FMASK_INFO_INPUT* pFmaskIn, ///< [in] Input of fmask info
+ const ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut, ///< [in] Output of fmask info
+ ADDR_COMPUTE_SURFACE_INFO_INPUT* pSurfIn, ///< [out] Input of thunked surface info
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut ///< [out] Output of thunked surface info
+ ) const
+{
+ pSurfIn->tileIndex = pFmaskIn->tileIndex;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlFmaskPostThunkSurfInfo
+*
+* @brief
+* Copy hwl extra field after calling thunked ComputeSurfaceInfo
+* @return
+* ADDR_E_RETURNCODE
+***************************************************************************************************
+*/
+VOID SIAddrLib::HwlFmaskPostThunkSurfInfo(
+ const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut, ///< [in] Output of surface info
+ ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut ///< [out] Output of fmask info
+ ) const
+{
+ pFmaskOut->macroModeIndex = TileIndexInvalid;
+ pFmaskOut->tileIndex = pSurfOut->tileIndex;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlComputeFmaskBits
+* @brief
+* Computes fmask bits
+* @return
+* Fmask bits
+***************************************************************************************************
+*/
+UINT_32 SIAddrLib::HwlComputeFmaskBits(
+ const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn,
+ UINT_32* pNumSamples
+ ) const
+{
+ UINT_32 numSamples = pIn->numSamples;
+ UINT_32 numFrags = GetNumFragments(numSamples, pIn->numFrags);
+ UINT_32 bpp;
+
+ if (numFrags != numSamples) // EQAA
+ {
+ ADDR_ASSERT(numFrags <= 8);
+
+ if (!pIn->resolved)
+ {
+ if (numFrags == 1)
+ {
+ bpp = 1;
+ numSamples = numSamples == 16 ? 16 : 8;
+ }
+ else if (numFrags == 2)
+ {
+ ADDR_ASSERT(numSamples >= 4);
+
+ bpp = 2;
+ numSamples = numSamples;
+ }
+ else if (numFrags == 4)
+ {
+ ADDR_ASSERT(numSamples >= 4);
+
+ bpp = 4;
+ numSamples = numSamples;
+ }
+ else // numFrags == 8
+ {
+ ADDR_ASSERT(numSamples == 16);
+
+ bpp = 4;
+ numSamples = numSamples;
+ }
+ }
+ else
+ {
+ if (numFrags == 1)
+ {
+ bpp = (numSamples == 16) ? 16 : 8;
+ numSamples = 1;
+ }
+ else if (numFrags == 2)
+ {
+ ADDR_ASSERT(numSamples >= 4);
+
+ bpp = numSamples*2;
+ numSamples = 1;
+ }
+ else if (numFrags == 4)
+ {
+ ADDR_ASSERT(numSamples >= 4);
+
+ bpp = numSamples*4;
+ numSamples = 1;
+ }
+ else // numFrags == 8
+ {
+ ADDR_ASSERT(numSamples >= 16);
+
+ bpp = 16*4;
+ numSamples = 1;
+ }
+ }
+ }
+ else // Normal AA
+ {
+ if (!pIn->resolved)
+ {
+ bpp = ComputeFmaskNumPlanesFromNumSamples(numSamples);
+ numSamples = numSamples == 2 ? 8 : numSamples;
+ }
+ else
+ {
+ // The same as 8XX
+ bpp = ComputeFmaskResolvedBppFromNumSamples(numSamples);
+ numSamples = 1; // 1x sample
+ }
+ }
+
+ SafeAssign(pNumSamples, numSamples);
+
+ return bpp;
+}
+
+/**
+***************************************************************************************************
+* SIAddrLib::HwlOverrideTileMode
+*
+* @brief
+* Override tile modes (for PRT only, avoid client passes in an invalid PRT mode for SI.
+*
+* @return
+* Suitable tile mode
+*
+***************************************************************************************************
+*/
+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
+ ) const
+{
+ BOOL_32 bOverrided = FALSE;
+ AddrTileMode tileMode = *pTileMode;
+
+ switch (tileMode)
+ {
+ case ADDR_TM_PRT_TILED_THIN1:
+ tileMode = ADDR_TM_2D_TILED_THIN1;
+ break;
+
+ case ADDR_TM_PRT_TILED_THICK:
+ tileMode = ADDR_TM_2D_TILED_THICK;
+ break;
+
+ case ADDR_TM_PRT_2D_TILED_THICK:
+ tileMode = ADDR_TM_2D_TILED_THICK;
+ break;
+
+ case ADDR_TM_PRT_3D_TILED_THICK:
+ tileMode = ADDR_TM_3D_TILED_THICK;
+ break;
+
+ default:
+ break;
+ }
+
+ if (tileMode != *pTileMode)
+ {
+ *pTileMode = tileMode;
+ bOverrided = TRUE;
+ ADDR_ASSERT(pIn->flags.prt == TRUE);
+ }
+
+ return bOverrided;
+}
+
diff --git a/src/amd/addrlib/r800/siaddrlib.h b/src/amd/addrlib/r800/siaddrlib.h
new file mode 100644
index 00000000000..897beb1bb92
--- /dev/null
+++ b/src/amd/addrlib/r800/siaddrlib.h
@@ -0,0 +1,262 @@
+/*
+ * Copyright © 2014 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+
+/**
+***************************************************************************************************
+* @file siaddrlib.h
+* @brief Contains the R800AddrLib class definition.
+***************************************************************************************************
+*/
+
+#ifndef __SI_ADDR_LIB_H__
+#define __SI_ADDR_LIB_H__
+
+#include "addrlib.h"
+#include "egbaddrlib.h"
+
+/**
+***************************************************************************************************
+* @brief Describes the information in tile mode table
+***************************************************************************************************
+*/
+struct ADDR_TILECONFIG
+{
+ AddrTileMode mode;
+ AddrTileType type;
+ ADDR_TILEINFO info;
+};
+
+/**
+***************************************************************************************************
+* @brief SI specific settings structure.
+***************************************************************************************************
+*/
+struct SIChipSettings
+{
+ struct
+ {
+ UINT_32 isSouthernIsland : 1;
+ UINT_32 isTahiti : 1;
+ UINT_32 isPitCairn : 1;
+ UINT_32 isCapeVerde : 1;
+ /// Oland/Hainan are of GFXIP 6.0, similar with SI
+ UINT_32 isOland : 1;
+ UINT_32 isHainan : 1;
+ };
+};
+
+/**
+***************************************************************************************************
+* @brief This class is the SI specific address library
+* function set.
+***************************************************************************************************
+*/
+class SIAddrLib : public EgBasedAddrLib
+{
+public:
+ /// Creates SIAddrLib object
+ static AddrLib* CreateObj(const AddrClient* pClient)
+ {
+ return new(pClient) SIAddrLib(pClient);
+ }
+
+protected:
+ SIAddrLib(const AddrClient* pClient);
+ virtual ~SIAddrLib();
+
+ // Hwl interface - defined in AddrLib
+ virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfo(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;
+
+ virtual ADDR_E_RETURNCODE HwlConvertTileInfoToHW(
+ const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn,
+ ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut) const;
+
+ virtual UINT_64 HwlComputeXmaskAddrFromCoord(
+ UINT_32 pitch, UINT_32 height, UINT_32 x, UINT_32 y, UINT_32 slice, UINT_32 numSlices,
+ UINT_32 factor, BOOL_32 isLinear, BOOL_32 isWidth8, BOOL_32 isHeight8,
+ ADDR_TILEINFO* pTileInfo, UINT_32* pBitPosition) const;
+
+ 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;
+
+ virtual ADDR_E_RETURNCODE HwlGetTileIndex(
+ const ADDR_GET_TILEINDEX_INPUT* pIn,
+ ADDR_GET_TILEINDEX_OUTPUT* pOut) const;
+
+ virtual BOOL_32 HwlComputeMipLevel(
+ ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const;
+
+ virtual AddrChipFamily HwlConvertChipFamily(
+ UINT_32 uChipFamily, UINT_32 uChipRevision);
+
+ virtual BOOL_32 HwlInitGlobalParams(
+ const ADDR_CREATE_INPUT* pCreateIn);
+
+ virtual ADDR_E_RETURNCODE HwlSetupTileCfg(
+ INT_32 index, INT_32 macroModeIndex,
+ ADDR_TILEINFO* pInfo, AddrTileMode* pMode = 0, AddrTileType* pType = 0) const;
+
+ virtual VOID HwlComputeTileDataWidthAndHeightLinear(
+ UINT_32* pMacroWidth, UINT_32* pMacroHeight,
+ UINT_32 bpp, ADDR_TILEINFO* pTileInfo) const;
+
+ virtual UINT_64 HwlComputeHtileBytes(
+ UINT_32 pitch, UINT_32 height, UINT_32 bpp,
+ BOOL_32 isLinear, UINT_32 numSlices, UINT_64* pSliceBytes, UINT_32 baseAlign) const;
+
+ virtual UINT_32 ComputePipeFromCoord(
+ UINT_32 x, UINT_32 y, UINT_32 slice,
+ AddrTileMode tileMode, UINT_32 pipeSwizzle, BOOL_32 ignoreSE,
+ ADDR_TILEINFO* pTileInfo) const;
+
+ virtual UINT_32 HwlGetPipes(const ADDR_TILEINFO* pTileInfo) const;
+
+ /// Pre-handler of 3x pitch (96 bit) adjustment
+ virtual UINT_32 HwlPreHandleBaseLvl3xPitch(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, UINT_32 expPitch) const;
+ /// Post-handler of 3x pitch adjustment
+ virtual UINT_32 HwlPostHandleBaseLvl3xPitch(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, UINT_32 expPitch) const;
+
+ /// Dummy function to finalize the inheritance
+ virtual UINT_32 HwlComputeXmaskCoordYFrom8Pipe(
+ UINT_32 pipe, UINT_32 x) const;
+
+ // Sub-hwl interface - defined in EgBasedAddrLib
+ virtual VOID HwlSetupTileInfo(
+ AddrTileMode tileMode, ADDR_SURFACE_FLAGS flags,
+ UINT_32 bpp, UINT_32 pitch, UINT_32 height, UINT_32 numSamples,
+ ADDR_TILEINFO* inputTileInfo, ADDR_TILEINFO* outputTileInfo,
+ AddrTileType inTileType, ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;
+
+ virtual UINT_32 HwlGetPitchAlignmentMicroTiled(
+ AddrTileMode tileMode, UINT_32 bpp, ADDR_SURFACE_FLAGS flags, UINT_32 numSamples) const;
+
+ virtual UINT_64 HwlGetSizeAdjustmentMicroTiled(
+ UINT_32 thickness, UINT_32 bpp, ADDR_SURFACE_FLAGS flags, UINT_32 numSamples,
+ UINT_32 baseAlign, UINT_32 pitchAlign,
+ UINT_32 *pPitch, UINT_32 *pHeight) const;
+
+ virtual VOID HwlCheckLastMacroTiledLvl(
+ 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 BOOL_32 HwlOverrideTileMode(
+ const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,
+ AddrTileMode* pTileMode,
+ AddrTileType* pTileType) 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,
+ UINT_32 bpp, UINT_32 numSamples, UINT_32 baseAlign, UINT_32 pitchAlign,
+ UINT_32 *pPitch, UINT_32 *pHeight, UINT_32 *pHeightAlign) const;
+
+ virtual VOID HwlComputeSurfaceCoord2DFromBankPipe(
+ AddrTileMode tileMode, UINT_32* pX, UINT_32* pY, UINT_32 slice,
+ UINT_32 bank, UINT_32 pipe,
+ UINT_32 bankSwizzle, UINT_32 pipeSwizzle, UINT_32 tileSlices,
+ BOOL_32 ignoreSE,
+ ADDR_TILEINFO* pTileInfo) const;
+
+ virtual UINT_32 HwlPreAdjustBank(
+ UINT_32 tileX, UINT_32 bank, ADDR_TILEINFO* pTileInfo) const;
+
+ virtual INT_32 HwlPostCheckTileIndex(
+ const ADDR_TILEINFO* pInfo, AddrTileMode mode, AddrTileType type,
+ INT curIndex = TileIndexInvalid) const;
+
+ virtual VOID HwlFmaskPreThunkSurfInfo(
+ const ADDR_COMPUTE_FMASK_INFO_INPUT* pFmaskIn,
+ const ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut,
+ ADDR_COMPUTE_SURFACE_INFO_INPUT* pSurfIn,
+ ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut) const;
+
+ virtual VOID HwlFmaskPostThunkSurfInfo(
+ const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut,
+ ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut) const;
+
+ virtual UINT_32 HwlComputeFmaskBits(
+ const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn,
+ UINT_32* pNumSamples) const;
+
+ virtual BOOL_32 HwlReduceBankWidthHeight(
+ UINT_32 tileSize, UINT_32 bpp, ADDR_SURFACE_FLAGS flags, UINT_32 numSamples,
+ UINT_32 bankHeightAlign, UINT_32 pipes,
+ ADDR_TILEINFO* pTileInfo) const
+ {
+ return TRUE;
+ }
+
+ // Protected non-virtual functions
+ VOID ComputeTileCoordFromPipeAndElemIdx(
+ UINT_32 elemIdx, UINT_32 pipe, AddrPipeCfg pipeCfg, UINT_32 pitchInMacroTile,
+ UINT_32 x, UINT_32 y, UINT_32* pX, UINT_32* pY) const;
+
+ UINT_32 TileCoordToMaskElementIndex(
+ UINT_32 tx, UINT_32 ty, AddrPipeCfg pipeConfig,
+ UINT_32 *macroShift, UINT_32 *elemIdxBits) const;
+
+ BOOL_32 DecodeGbRegs(
+ const ADDR_REGISTER_VALUE* pRegValue);
+
+ const ADDR_TILECONFIG* GetTileSetting(
+ UINT_32 index) const;
+
+ static const UINT_32 TileTableSize = 32;
+ ADDR_TILECONFIG m_tileTable[TileTableSize];
+ UINT_32 m_noOfEntries;
+
+private:
+
+ UINT_32 GetPipePerSurf(AddrPipeCfg pipeConfig) const;
+
+ VOID ReadGbTileMode(
+ UINT_32 regValue, ADDR_TILECONFIG* pCfg) const;
+ BOOL_32 InitTileSettingTable(
+ const UINT_32 *pSetting, UINT_32 noOfEntries);
+
+ SIChipSettings m_settings;
+};
+
+#endif
+