mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 13:40:16 +01:00
4024 lines
124 KiB
C++
4024 lines
124 KiB
C++
|
|
/*
|
||
|
|
* 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 addrlib.cpp
|
||
|
|
* @brief Contains the implementation for the AddrLib base class..
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include "addrinterface.h"
|
||
|
|
#include "addrlib.h"
|
||
|
|
#include "addrcommon.h"
|
||
|
|
|
||
|
|
#if defined(__APPLE__)
|
||
|
|
|
||
|
|
UINT_32 div64_32(UINT_64 n, UINT_32 base)
|
||
|
|
{
|
||
|
|
UINT_64 rem = n;
|
||
|
|
UINT_64 b = base;
|
||
|
|
UINT_64 res, d = 1;
|
||
|
|
UINT_32 high = rem >> 32;
|
||
|
|
|
||
|
|
res = 0;
|
||
|
|
if (high >= base)
|
||
|
|
{
|
||
|
|
high /= base;
|
||
|
|
res = (UINT_64) high << 32;
|
||
|
|
rem -= (UINT_64) (high*base) << 32;
|
||
|
|
}
|
||
|
|
|
||
|
|
while ((INT_64)b > 0 && b < rem)
|
||
|
|
{
|
||
|
|
b = b+b;
|
||
|
|
d = d+d;
|
||
|
|
}
|
||
|
|
|
||
|
|
do
|
||
|
|
{
|
||
|
|
if (rem >= b)
|
||
|
|
{
|
||
|
|
rem -= b;
|
||
|
|
res += d;
|
||
|
|
}
|
||
|
|
b >>= 1;
|
||
|
|
d >>= 1;
|
||
|
|
} while (d);
|
||
|
|
|
||
|
|
n = res;
|
||
|
|
return rem;
|
||
|
|
}
|
||
|
|
|
||
|
|
extern "C"
|
||
|
|
UINT_32 __umoddi3(UINT_64 n, UINT_32 base)
|
||
|
|
{
|
||
|
|
return div64_32(n, base);
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif // __APPLE__
|
||
|
|
|
||
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
// Static Const Member
|
||
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
const AddrTileModeFlags AddrLib::m_modeFlags[ADDR_TM_COUNT] =
|
||
|
|
{// T L 1 2 3 P Pr B
|
||
|
|
{1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_GENERAL
|
||
|
|
{1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_ALIGNED
|
||
|
|
{1, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THIN1
|
||
|
|
{4, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THICK
|
||
|
|
{1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN1
|
||
|
|
{1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN2
|
||
|
|
{1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN4
|
||
|
|
{4, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THICK
|
||
|
|
{1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN1
|
||
|
|
{1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN2
|
||
|
|
{1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN4
|
||
|
|
{4, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THICK
|
||
|
|
{1, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THIN1
|
||
|
|
{4, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THICK
|
||
|
|
{1, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THIN1
|
||
|
|
{4, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THICK
|
||
|
|
{8, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_XTHICK
|
||
|
|
{8, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_XTHICK
|
||
|
|
{1, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_POWER_SAVE
|
||
|
|
{1, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THIN1
|
||
|
|
{1, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THIN1
|
||
|
|
{1, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THIN1
|
||
|
|
{4, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THICK
|
||
|
|
{4, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THICK
|
||
|
|
{4, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THICK
|
||
|
|
};
|
||
|
|
|
||
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
// Constructor/Destructor
|
||
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::AddrLib
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Constructor for the AddrLib class
|
||
|
|
*
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
AddrLib::AddrLib() :
|
||
|
|
m_class(BASE_ADDRLIB),
|
||
|
|
m_chipFamily(ADDR_CHIP_FAMILY_IVLD),
|
||
|
|
m_chipRevision(0),
|
||
|
|
m_version(ADDRLIB_VERSION),
|
||
|
|
m_pipes(0),
|
||
|
|
m_banks(0),
|
||
|
|
m_pipeInterleaveBytes(0),
|
||
|
|
m_rowSize(0),
|
||
|
|
m_minPitchAlignPixels(1),
|
||
|
|
m_maxSamples(8),
|
||
|
|
m_pElemLib(NULL)
|
||
|
|
{
|
||
|
|
m_configFlags.value = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::AddrLib
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Constructor for the AddrLib class with hClient as parameter
|
||
|
|
*
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
AddrLib::AddrLib(const AddrClient* pClient) :
|
||
|
|
AddrObject(pClient),
|
||
|
|
m_class(BASE_ADDRLIB),
|
||
|
|
m_chipFamily(ADDR_CHIP_FAMILY_IVLD),
|
||
|
|
m_chipRevision(0),
|
||
|
|
m_version(ADDRLIB_VERSION),
|
||
|
|
m_pipes(0),
|
||
|
|
m_banks(0),
|
||
|
|
m_pipeInterleaveBytes(0),
|
||
|
|
m_rowSize(0),
|
||
|
|
m_minPitchAlignPixels(1),
|
||
|
|
m_maxSamples(8),
|
||
|
|
m_pElemLib(NULL)
|
||
|
|
{
|
||
|
|
m_configFlags.value = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::~AddrLib
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Destructor for the AddrLib class
|
||
|
|
*
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
AddrLib::~AddrLib()
|
||
|
|
{
|
||
|
|
if (m_pElemLib)
|
||
|
|
{
|
||
|
|
delete m_pElemLib;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
// Initialization/Helper
|
||
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::Create
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Creates and initializes AddrLib object.
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::Create(
|
||
|
|
const ADDR_CREATE_INPUT* pCreateIn, ///< [in] pointer to ADDR_CREATE_INPUT
|
||
|
|
ADDR_CREATE_OUTPUT* pCreateOut) ///< [out] pointer to ADDR_CREATE_OUTPUT
|
||
|
|
{
|
||
|
|
AddrLib* pLib = NULL;
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (pCreateIn->createFlags.fillSizeFields == TRUE)
|
||
|
|
{
|
||
|
|
if ((pCreateIn->size != sizeof(ADDR_CREATE_INPUT)) ||
|
||
|
|
(pCreateOut->size != sizeof(ADDR_CREATE_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((returnCode == ADDR_OK) &&
|
||
|
|
(pCreateIn->callbacks.allocSysMem != NULL) &&
|
||
|
|
(pCreateIn->callbacks.freeSysMem != NULL))
|
||
|
|
{
|
||
|
|
AddrClient client = {
|
||
|
|
pCreateIn->hClient,
|
||
|
|
pCreateIn->callbacks
|
||
|
|
};
|
||
|
|
|
||
|
|
switch (pCreateIn->chipEngine)
|
||
|
|
{
|
||
|
|
case CIASICIDGFXENGINE_SOUTHERNISLAND:
|
||
|
|
switch (pCreateIn->chipFamily)
|
||
|
|
{
|
||
|
|
case FAMILY_SI:
|
||
|
|
pLib = AddrSIHwlInit(&client);
|
||
|
|
break;
|
||
|
|
case FAMILY_VI:
|
||
|
|
case FAMILY_CZ: // VI based fusion(carrizo)
|
||
|
|
case FAMILY_CI:
|
||
|
|
case FAMILY_KV: // CI based fusion
|
||
|
|
pLib = AddrCIHwlInit(&client);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
ADDR_ASSERT_ALWAYS();
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
ADDR_ASSERT_ALWAYS();
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((pLib != NULL))
|
||
|
|
{
|
||
|
|
BOOL_32 initValid;
|
||
|
|
|
||
|
|
// Pass createFlags to configFlags first since these flags may be overwritten
|
||
|
|
pLib->m_configFlags.noCubeMipSlicesPad = pCreateIn->createFlags.noCubeMipSlicesPad;
|
||
|
|
pLib->m_configFlags.fillSizeFields = pCreateIn->createFlags.fillSizeFields;
|
||
|
|
pLib->m_configFlags.useTileIndex = pCreateIn->createFlags.useTileIndex;
|
||
|
|
pLib->m_configFlags.useCombinedSwizzle = pCreateIn->createFlags.useCombinedSwizzle;
|
||
|
|
pLib->m_configFlags.checkLast2DLevel = pCreateIn->createFlags.checkLast2DLevel;
|
||
|
|
pLib->m_configFlags.useHtileSliceAlign = pCreateIn->createFlags.useHtileSliceAlign;
|
||
|
|
pLib->m_configFlags.degradeBaseLevel = pCreateIn->createFlags.degradeBaseLevel;
|
||
|
|
pLib->m_configFlags.allowLargeThickTile = pCreateIn->createFlags.allowLargeThickTile;
|
||
|
|
|
||
|
|
pLib->SetAddrChipFamily(pCreateIn->chipFamily, pCreateIn->chipRevision);
|
||
|
|
|
||
|
|
pLib->SetMinPitchAlignPixels(pCreateIn->minPitchAlignPixels);
|
||
|
|
|
||
|
|
// Global parameters initialized and remaining configFlags bits are set as well
|
||
|
|
initValid = pLib->HwlInitGlobalParams(pCreateIn);
|
||
|
|
|
||
|
|
if (initValid)
|
||
|
|
{
|
||
|
|
pLib->m_pElemLib = AddrElemLib::Create(pLib);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
pLib->m_pElemLib = NULL; // Don't go on allocating element lib
|
||
|
|
returnCode = ADDR_INVALIDGBREGVALUES;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pLib->m_pElemLib == NULL)
|
||
|
|
{
|
||
|
|
delete pLib;
|
||
|
|
pLib = NULL;
|
||
|
|
ADDR_ASSERT_ALWAYS();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
pLib->m_pElemLib->SetConfigFlags(pLib->m_configFlags);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
pCreateOut->hLib = pLib;
|
||
|
|
|
||
|
|
if ((pLib == NULL) &&
|
||
|
|
(returnCode == ADDR_OK))
|
||
|
|
{
|
||
|
|
// Unknown failures, we return the general error code
|
||
|
|
returnCode = ADDR_ERROR;
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::SetAddrChipFamily
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Convert familyID defined in atiid.h to AddrChipFamily and set m_chipFamily/m_chipRevision
|
||
|
|
* @return
|
||
|
|
* N/A
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
VOID AddrLib::SetAddrChipFamily(
|
||
|
|
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_IVLD;
|
||
|
|
|
||
|
|
family = HwlConvertChipFamily(uChipFamily, uChipRevision);
|
||
|
|
|
||
|
|
ADDR_ASSERT(family != ADDR_CHIP_FAMILY_IVLD);
|
||
|
|
|
||
|
|
m_chipFamily = family;
|
||
|
|
m_chipRevision = uChipRevision;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::SetMinPitchAlignPixels
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Set m_minPitchAlignPixels with input param
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* N/A
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
VOID AddrLib::SetMinPitchAlignPixels(
|
||
|
|
UINT_32 minPitchAlignPixels) ///< [in] minmum pitch alignment in pixels
|
||
|
|
{
|
||
|
|
m_minPitchAlignPixels = (minPitchAlignPixels == 0)? 1 : minPitchAlignPixels;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::GetAddrLib
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Get AddrLib pointer
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* An AddrLib class pointer
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
AddrLib * AddrLib::GetAddrLib(
|
||
|
|
ADDR_HANDLE hLib) ///< [in] handle of ADDR_HANDLE
|
||
|
|
{
|
||
|
|
return static_cast<AddrLib *>(hLib);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
// Surface Methods
|
||
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeSurfaceInfo
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of AddrComputeSurfaceInfo.
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeSurfaceInfo(
|
||
|
|
const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// We suggest client do sanity check but a check here is also good
|
||
|
|
if (pIn->bpp > 128)
|
||
|
|
{
|
||
|
|
returnCode = ADDR_INVALIDPARAMS;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Thick modes don't support multisample
|
||
|
|
if (ComputeSurfaceThickness(pIn->tileMode) > 1 && pIn->numSamples > 1)
|
||
|
|
{
|
||
|
|
returnCode = ADDR_INVALIDPARAMS;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
// Get a local copy of input structure and only reference pIn for unadjusted values
|
||
|
|
ADDR_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;
|
||
|
|
ADDR_TILEINFO tileInfoNull = {0};
|
||
|
|
|
||
|
|
if (UseTileInfo())
|
||
|
|
{
|
||
|
|
// If the original input has a valid ADDR_TILEINFO pointer then copy its contents.
|
||
|
|
// Otherwise the default 0's in tileInfoNull are used.
|
||
|
|
if (pIn->pTileInfo)
|
||
|
|
{
|
||
|
|
tileInfoNull = *pIn->pTileInfo;
|
||
|
|
}
|
||
|
|
localIn.pTileInfo = &tileInfoNull;
|
||
|
|
}
|
||
|
|
|
||
|
|
localIn.numSamples = pIn->numSamples == 0 ? 1 : pIn->numSamples;
|
||
|
|
|
||
|
|
// Do mipmap check first
|
||
|
|
// If format is BCn, pre-pad dimension to power-of-two according to HWL
|
||
|
|
ComputeMipLevel(&localIn);
|
||
|
|
|
||
|
|
if (m_configFlags.checkLast2DLevel)
|
||
|
|
{
|
||
|
|
// Save this level's original height in pixels
|
||
|
|
pOut->height = pIn->height;
|
||
|
|
}
|
||
|
|
|
||
|
|
UINT_32 expandX = 1;
|
||
|
|
UINT_32 expandY = 1;
|
||
|
|
AddrElemMode elemMode;
|
||
|
|
|
||
|
|
// Save outputs that may not go through HWL
|
||
|
|
pOut->pixelBits = localIn.bpp;
|
||
|
|
pOut->numSamples = localIn.numSamples;
|
||
|
|
pOut->last2DLevel = FALSE;
|
||
|
|
|
||
|
|
#if !ALT_TEST
|
||
|
|
if (localIn.numSamples > 1)
|
||
|
|
{
|
||
|
|
ADDR_ASSERT(localIn.mipLevel == 0);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
if (localIn.format != ADDR_FMT_INVALID) // Set format to INVALID will skip this conversion
|
||
|
|
{
|
||
|
|
// Get compression/expansion factors and element mode
|
||
|
|
// (which indicates compression/expansion
|
||
|
|
localIn.bpp = GetElemLib()->GetBitsPerPixel(localIn.format,
|
||
|
|
&elemMode,
|
||
|
|
&expandX,
|
||
|
|
&expandY);
|
||
|
|
|
||
|
|
// Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
|
||
|
|
// pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
|
||
|
|
// aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
|
||
|
|
// restrictions are different.
|
||
|
|
// Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
|
||
|
|
// but we use this flag to skip RestoreSurfaceInfo below
|
||
|
|
|
||
|
|
if ((elemMode == ADDR_EXPANDED) &&
|
||
|
|
(expandX > 1))
|
||
|
|
{
|
||
|
|
ADDR_ASSERT(localIn.tileMode == ADDR_TM_LINEAR_ALIGNED || localIn.height == 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
GetElemLib()->AdjustSurfaceInfo(elemMode,
|
||
|
|
expandX,
|
||
|
|
expandY,
|
||
|
|
&localIn.bpp,
|
||
|
|
&localIn.basePitch,
|
||
|
|
&localIn.width,
|
||
|
|
&localIn.height);
|
||
|
|
|
||
|
|
// Overwrite these parameters if we have a valid format
|
||
|
|
}
|
||
|
|
else if (localIn.bpp != 0)
|
||
|
|
{
|
||
|
|
localIn.width = (localIn.width != 0) ? localIn.width : 1;
|
||
|
|
localIn.height = (localIn.height != 0) ? localIn.height : 1;
|
||
|
|
}
|
||
|
|
else // Rule out some invalid parameters
|
||
|
|
{
|
||
|
|
ADDR_ASSERT_ALWAYS();
|
||
|
|
|
||
|
|
returnCode = ADDR_INVALIDPARAMS;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check mipmap after surface expansion
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
returnCode = PostComputeMipLevel(&localIn, pOut);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
if (UseTileIndex(localIn.tileIndex))
|
||
|
|
{
|
||
|
|
// Make sure pTileInfo is not NULL
|
||
|
|
ADDR_ASSERT(localIn.pTileInfo);
|
||
|
|
|
||
|
|
UINT_32 numSamples = GetNumFragments(localIn.numSamples, localIn.numFrags);
|
||
|
|
|
||
|
|
INT_32 macroModeIndex = TileIndexNoMacroIndex;
|
||
|
|
|
||
|
|
if (localIn.tileIndex != TileIndexLinearGeneral)
|
||
|
|
{
|
||
|
|
// Try finding a macroModeIndex
|
||
|
|
macroModeIndex = HwlComputeMacroModeIndex(localIn.tileIndex,
|
||
|
|
localIn.flags,
|
||
|
|
localIn.bpp,
|
||
|
|
numSamples,
|
||
|
|
localIn.pTileInfo,
|
||
|
|
&localIn.tileMode,
|
||
|
|
&localIn.tileType);
|
||
|
|
}
|
||
|
|
|
||
|
|
// If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
|
||
|
|
if (macroModeIndex == TileIndexNoMacroIndex)
|
||
|
|
{
|
||
|
|
returnCode = HwlSetupTileCfg(localIn.tileIndex, macroModeIndex,
|
||
|
|
localIn.pTileInfo,
|
||
|
|
&localIn.tileMode, &localIn.tileType);
|
||
|
|
}
|
||
|
|
// If macroModeIndex is invalid, then assert this is not macro tiled
|
||
|
|
else if (macroModeIndex == TileIndexInvalid)
|
||
|
|
{
|
||
|
|
ADDR_ASSERT(!IsMacroTiled(localIn.tileMode));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
AddrTileMode tileMode = localIn.tileMode;
|
||
|
|
AddrTileType tileType = localIn.tileType;
|
||
|
|
|
||
|
|
// HWL layer may override tile mode if necessary
|
||
|
|
if (HwlOverrideTileMode(&localIn, &tileMode, &tileType))
|
||
|
|
{
|
||
|
|
localIn.tileMode = tileMode;
|
||
|
|
localIn.tileType = tileType;
|
||
|
|
}
|
||
|
|
// Degrade base level if applicable
|
||
|
|
if (DegradeBaseLevel(&localIn, &tileMode))
|
||
|
|
{
|
||
|
|
localIn.tileMode = tileMode;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Call main function to compute surface info
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
returnCode = HwlComputeSurfaceInfo(&localIn, pOut);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
// Since bpp might be changed we just pass it through
|
||
|
|
pOut->bpp = localIn.bpp;
|
||
|
|
|
||
|
|
// Also original width/height/bpp
|
||
|
|
pOut->pixelPitch = pOut->pitch;
|
||
|
|
pOut->pixelHeight = pOut->height;
|
||
|
|
|
||
|
|
#if DEBUG
|
||
|
|
if (localIn.flags.display)
|
||
|
|
{
|
||
|
|
ADDR_ASSERT((pOut->pitchAlign % 32) == 0);
|
||
|
|
}
|
||
|
|
#endif //DEBUG
|
||
|
|
|
||
|
|
if (localIn.format != ADDR_FMT_INVALID)
|
||
|
|
{
|
||
|
|
//
|
||
|
|
// 96 bits surface of level 1+ requires element pitch of 32 bits instead
|
||
|
|
// In hwl function we skip multiplication of 3 then we should skip division of 3
|
||
|
|
// We keep pitch that represents 32 bit element instead of 96 bits since we
|
||
|
|
// will get an odd number if divided by 3.
|
||
|
|
//
|
||
|
|
if (!((expandX == 3) && (localIn.mipLevel > 0)))
|
||
|
|
{
|
||
|
|
|
||
|
|
GetElemLib()->RestoreSurfaceInfo(elemMode,
|
||
|
|
expandX,
|
||
|
|
expandY,
|
||
|
|
&localIn.bpp,
|
||
|
|
&pOut->pixelPitch,
|
||
|
|
&pOut->pixelHeight);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (localIn.flags.qbStereo)
|
||
|
|
{
|
||
|
|
if (pOut->pStereoInfo)
|
||
|
|
{
|
||
|
|
ComputeQbStereoInfo(pOut);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (localIn.flags.volume) // For volume sliceSize equals to all z-slices
|
||
|
|
{
|
||
|
|
pOut->sliceSize = pOut->surfSize;
|
||
|
|
}
|
||
|
|
else // For array: sliceSize is likely to have slice-padding (the last one)
|
||
|
|
{
|
||
|
|
pOut->sliceSize = pOut->surfSize / pOut->depth;
|
||
|
|
|
||
|
|
// array or cubemap
|
||
|
|
if (pIn->numSlices > 1)
|
||
|
|
{
|
||
|
|
// If this is the last slice then add the padding size to this slice
|
||
|
|
if (pIn->slice == (pIn->numSlices - 1))
|
||
|
|
{
|
||
|
|
pOut->sliceSize += pOut->sliceSize * (pOut->depth - pIn->numSlices);
|
||
|
|
}
|
||
|
|
else if (m_configFlags.checkLast2DLevel)
|
||
|
|
{
|
||
|
|
// Reset last2DLevel flag if this is not the last array slice
|
||
|
|
pOut->last2DLevel = FALSE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
pOut->pitchTileMax = pOut->pitch / 8 - 1;
|
||
|
|
pOut->heightTileMax = pOut->height / 8 - 1;
|
||
|
|
pOut->sliceTileMax = pOut->pitch * pOut->height / 64 - 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeSurfaceInfo
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of AddrComputeSurfaceInfo.
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeSurfaceAddrFromCoord(
|
||
|
|
const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_TILEINFO tileInfoNull;
|
||
|
|
ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT input;
|
||
|
|
|
||
|
|
if (UseTileIndex(pIn->tileIndex))
|
||
|
|
{
|
||
|
|
input = *pIn;
|
||
|
|
// Use temp tile info for calcalation
|
||
|
|
input.pTileInfo = &tileInfoNull;
|
||
|
|
|
||
|
|
const ADDR_SURFACE_FLAGS flags = {{0}};
|
||
|
|
UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags);
|
||
|
|
|
||
|
|
// Try finding a macroModeIndex
|
||
|
|
INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex,
|
||
|
|
flags,
|
||
|
|
input.bpp,
|
||
|
|
numSamples,
|
||
|
|
input.pTileInfo,
|
||
|
|
&input.tileMode,
|
||
|
|
&input.tileType);
|
||
|
|
|
||
|
|
// If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
|
||
|
|
if (macroModeIndex == TileIndexNoMacroIndex)
|
||
|
|
{
|
||
|
|
returnCode = HwlSetupTileCfg(input.tileIndex, macroModeIndex,
|
||
|
|
input.pTileInfo, &input.tileMode, &input.tileType);
|
||
|
|
}
|
||
|
|
// If macroModeIndex is invalid, then assert this is not macro tiled
|
||
|
|
else if (macroModeIndex == TileIndexInvalid)
|
||
|
|
{
|
||
|
|
ADDR_ASSERT(!IsMacroTiled(input.tileMode));
|
||
|
|
}
|
||
|
|
|
||
|
|
// Change the input structure
|
||
|
|
pIn = &input;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
returnCode = HwlComputeSurfaceAddrFromCoord(pIn, pOut);
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeSurfaceCoordFromAddr
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of ComputeSurfaceCoordFromAddr.
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeSurfaceCoordFromAddr(
|
||
|
|
const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_TILEINFO tileInfoNull;
|
||
|
|
ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT input;
|
||
|
|
|
||
|
|
if (UseTileIndex(pIn->tileIndex))
|
||
|
|
{
|
||
|
|
input = *pIn;
|
||
|
|
// Use temp tile info for calcalation
|
||
|
|
input.pTileInfo = &tileInfoNull;
|
||
|
|
|
||
|
|
const ADDR_SURFACE_FLAGS flags = {{0}};
|
||
|
|
UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags);
|
||
|
|
|
||
|
|
// Try finding a macroModeIndex
|
||
|
|
INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex,
|
||
|
|
flags,
|
||
|
|
input.bpp,
|
||
|
|
numSamples,
|
||
|
|
input.pTileInfo,
|
||
|
|
&input.tileMode,
|
||
|
|
&input.tileType);
|
||
|
|
|
||
|
|
// If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
|
||
|
|
if (macroModeIndex == TileIndexNoMacroIndex)
|
||
|
|
{
|
||
|
|
returnCode = HwlSetupTileCfg(input.tileIndex, macroModeIndex,
|
||
|
|
input.pTileInfo, &input.tileMode, &input.tileType);
|
||
|
|
}
|
||
|
|
// If macroModeIndex is invalid, then assert this is not macro tiled
|
||
|
|
else if (macroModeIndex == TileIndexInvalid)
|
||
|
|
{
|
||
|
|
ADDR_ASSERT(!IsMacroTiled(input.tileMode));
|
||
|
|
}
|
||
|
|
|
||
|
|
// Change the input structure
|
||
|
|
pIn = &input;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
returnCode = HwlComputeSurfaceCoordFromAddr(pIn, pOut);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeSliceTileSwizzle
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of ComputeSliceTileSwizzle.
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeSliceTileSwizzle(
|
||
|
|
const ADDR_COMPUTE_SLICESWIZZLE_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_COMPUTE_SLICESWIZZLE_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_TILEINFO tileInfoNull;
|
||
|
|
ADDR_COMPUTE_SLICESWIZZLE_INPUT input;
|
||
|
|
|
||
|
|
if (UseTileIndex(pIn->tileIndex))
|
||
|
|
{
|
||
|
|
input = *pIn;
|
||
|
|
// Use temp tile info for calcalation
|
||
|
|
input.pTileInfo = &tileInfoNull;
|
||
|
|
|
||
|
|
returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex,
|
||
|
|
input.pTileInfo, &input.tileMode);
|
||
|
|
// Change the input structure
|
||
|
|
pIn = &input;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
returnCode = HwlComputeSliceTileSwizzle(pIn, pOut);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ExtractBankPipeSwizzle
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of AddrExtractBankPipeSwizzle.
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ExtractBankPipeSwizzle(
|
||
|
|
const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_TILEINFO tileInfoNull;
|
||
|
|
ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT input;
|
||
|
|
|
||
|
|
if (UseTileIndex(pIn->tileIndex))
|
||
|
|
{
|
||
|
|
input = *pIn;
|
||
|
|
// Use temp tile info for calcalation
|
||
|
|
input.pTileInfo = &tileInfoNull;
|
||
|
|
|
||
|
|
returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
|
||
|
|
// Change the input structure
|
||
|
|
pIn = &input;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
returnCode = HwlExtractBankPipeSwizzle(pIn, pOut);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::CombineBankPipeSwizzle
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of AddrCombineBankPipeSwizzle.
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::CombineBankPipeSwizzle(
|
||
|
|
const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_TILEINFO tileInfoNull;
|
||
|
|
ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT input;
|
||
|
|
|
||
|
|
if (UseTileIndex(pIn->tileIndex))
|
||
|
|
{
|
||
|
|
input = *pIn;
|
||
|
|
// Use temp tile info for calcalation
|
||
|
|
input.pTileInfo = &tileInfoNull;
|
||
|
|
|
||
|
|
returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
|
||
|
|
// Change the input structure
|
||
|
|
pIn = &input;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
returnCode = HwlCombineBankPipeSwizzle(pIn->bankSwizzle,
|
||
|
|
pIn->pipeSwizzle,
|
||
|
|
pIn->pTileInfo,
|
||
|
|
pIn->baseAddr,
|
||
|
|
&pOut->tileSwizzle);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeBaseSwizzle
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of AddrCompueBaseSwizzle.
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeBaseSwizzle(
|
||
|
|
const ADDR_COMPUTE_BASE_SWIZZLE_INPUT* pIn,
|
||
|
|
ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_TILEINFO tileInfoNull;
|
||
|
|
ADDR_COMPUTE_BASE_SWIZZLE_INPUT input;
|
||
|
|
|
||
|
|
if (UseTileIndex(pIn->tileIndex))
|
||
|
|
{
|
||
|
|
input = *pIn;
|
||
|
|
// Use temp tile info for calcalation
|
||
|
|
input.pTileInfo = &tileInfoNull;
|
||
|
|
|
||
|
|
returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
|
||
|
|
// Change the input structure
|
||
|
|
pIn = &input;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
if (IsMacroTiled(pIn->tileMode))
|
||
|
|
{
|
||
|
|
returnCode = HwlComputeBaseSwizzle(pIn, pOut);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
pOut->tileSwizzle = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeFmaskInfo
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of ComputeFmaskInfo.
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeFmaskInfo(
|
||
|
|
const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure
|
||
|
|
)
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// No thick MSAA
|
||
|
|
if (ComputeSurfaceThickness(pIn->tileMode) > 1)
|
||
|
|
{
|
||
|
|
returnCode = ADDR_INVALIDPARAMS;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_TILEINFO tileInfoNull;
|
||
|
|
ADDR_COMPUTE_FMASK_INFO_INPUT input;
|
||
|
|
|
||
|
|
if (UseTileIndex(pIn->tileIndex))
|
||
|
|
{
|
||
|
|
input = *pIn;
|
||
|
|
|
||
|
|
if (pOut->pTileInfo)
|
||
|
|
{
|
||
|
|
// Use temp tile info for calcalation
|
||
|
|
input.pTileInfo = pOut->pTileInfo;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
input.pTileInfo = &tileInfoNull;
|
||
|
|
}
|
||
|
|
|
||
|
|
ADDR_SURFACE_FLAGS flags = {{0}};
|
||
|
|
flags.fmask = 1;
|
||
|
|
|
||
|
|
// Try finding a macroModeIndex
|
||
|
|
INT_32 macroModeIndex = HwlComputeMacroModeIndex(pIn->tileIndex,
|
||
|
|
flags,
|
||
|
|
HwlComputeFmaskBits(pIn, NULL),
|
||
|
|
pIn->numSamples,
|
||
|
|
input.pTileInfo,
|
||
|
|
&input.tileMode);
|
||
|
|
|
||
|
|
// If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
|
||
|
|
if (macroModeIndex == TileIndexNoMacroIndex)
|
||
|
|
{
|
||
|
|
returnCode = HwlSetupTileCfg(input.tileIndex, macroModeIndex,
|
||
|
|
input.pTileInfo, &input.tileMode);
|
||
|
|
}
|
||
|
|
|
||
|
|
ADDR_ASSERT(macroModeIndex != TileIndexInvalid);
|
||
|
|
|
||
|
|
// Change the input structure
|
||
|
|
pIn = &input;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
if (pIn->numSamples > 1)
|
||
|
|
{
|
||
|
|
returnCode = HwlComputeFmaskInfo(pIn, pOut);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
memset(pOut, 0, sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT));
|
||
|
|
|
||
|
|
returnCode = ADDR_INVALIDPARAMS;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeFmaskAddrFromCoord
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of ComputeFmaskAddrFromCoord.
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeFmaskAddrFromCoord(
|
||
|
|
const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_ASSERT(pIn->numSamples > 1);
|
||
|
|
|
||
|
|
if (pIn->numSamples > 1)
|
||
|
|
{
|
||
|
|
returnCode = HwlComputeFmaskAddrFromCoord(pIn, pOut);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
returnCode = ADDR_INVALIDPARAMS;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeFmaskCoordFromAddr
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of ComputeFmaskAddrFromCoord.
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeFmaskCoordFromAddr(
|
||
|
|
const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_ASSERT(pIn->numSamples > 1);
|
||
|
|
|
||
|
|
if (pIn->numSamples > 1)
|
||
|
|
{
|
||
|
|
returnCode = HwlComputeFmaskCoordFromAddr(pIn, pOut);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
returnCode = ADDR_INVALIDPARAMS;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ConvertTileInfoToHW
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Convert tile info from real value to HW register value in HW layer
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ConvertTileInfoToHW(
|
||
|
|
const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_TILEINFO tileInfoNull;
|
||
|
|
ADDR_CONVERT_TILEINFOTOHW_INPUT input;
|
||
|
|
// if pIn->reverse is TRUE, indices are ignored
|
||
|
|
if (pIn->reverse == FALSE && UseTileIndex(pIn->tileIndex))
|
||
|
|
{
|
||
|
|
input = *pIn;
|
||
|
|
input.pTileInfo = &tileInfoNull;
|
||
|
|
|
||
|
|
returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
|
||
|
|
|
||
|
|
pIn = &input;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
returnCode = HwlConvertTileInfoToHW(pIn, pOut);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ConvertTileIndex
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Convert tile index to tile mode/type/info
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ConvertTileIndex(
|
||
|
|
const ADDR_CONVERT_TILEINDEX_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_CONVERT_TILEINDEX_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
|
||
|
|
returnCode = HwlSetupTileCfg(pIn->tileIndex, pIn->macroModeIndex,
|
||
|
|
pOut->pTileInfo, &pOut->tileMode, &pOut->tileType);
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK && pIn->tileInfoHw)
|
||
|
|
{
|
||
|
|
ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0};
|
||
|
|
ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0};
|
||
|
|
|
||
|
|
hwInput.pTileInfo = pOut->pTileInfo;
|
||
|
|
hwInput.tileIndex = -1;
|
||
|
|
hwOutput.pTileInfo = pOut->pTileInfo;
|
||
|
|
|
||
|
|
returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ConvertTileIndex1
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Convert tile index to tile mode/type/info
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ConvertTileIndex1(
|
||
|
|
const ADDR_CONVERT_TILEINDEX1_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_CONVERT_TILEINDEX_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX1_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_SURFACE_FLAGS flags = {{0}};
|
||
|
|
|
||
|
|
HwlComputeMacroModeIndex(pIn->tileIndex, flags, pIn->bpp, pIn->numSamples,
|
||
|
|
pOut->pTileInfo, &pOut->tileMode, &pOut->tileType);
|
||
|
|
|
||
|
|
if (pIn->tileInfoHw)
|
||
|
|
{
|
||
|
|
ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0};
|
||
|
|
ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0};
|
||
|
|
|
||
|
|
hwInput.pTileInfo = pOut->pTileInfo;
|
||
|
|
hwInput.tileIndex = -1;
|
||
|
|
hwOutput.pTileInfo = pOut->pTileInfo;
|
||
|
|
|
||
|
|
returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::GetTileIndex
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Get tile index from tile mode/type/info
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::GetTileIndex(
|
||
|
|
const ADDR_GET_TILEINDEX_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_GET_TILEINDEX_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_GET_TILEINDEX_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_GET_TILEINDEX_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
returnCode = HwlGetTileIndex(pIn, pOut);
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeSurfaceThickness
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Compute surface thickness
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* Surface thickness
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
UINT_32 AddrLib::ComputeSurfaceThickness(
|
||
|
|
AddrTileMode tileMode) ///< [in] tile mode
|
||
|
|
{
|
||
|
|
return m_modeFlags[tileMode].thickness;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
// CMASK/HTILE
|
||
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeHtileInfo
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of AddrComputeHtilenfo
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeHtileInfo(
|
||
|
|
const ADDR_COMPUTE_HTILE_INFO_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_COMPUTE_HTILE_INFO_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
BOOL_32 isWidth8 = (pIn->blockWidth == 8) ? TRUE : FALSE;
|
||
|
|
BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_TILEINFO tileInfoNull;
|
||
|
|
ADDR_COMPUTE_HTILE_INFO_INPUT input;
|
||
|
|
|
||
|
|
if (UseTileIndex(pIn->tileIndex))
|
||
|
|
{
|
||
|
|
input = *pIn;
|
||
|
|
// Use temp tile info for calcalation
|
||
|
|
input.pTileInfo = &tileInfoNull;
|
||
|
|
|
||
|
|
returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
|
||
|
|
|
||
|
|
// Change the input structure
|
||
|
|
pIn = &input;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
pOut->bpp = ComputeHtileInfo(pIn->flags,
|
||
|
|
pIn->pitch,
|
||
|
|
pIn->height,
|
||
|
|
pIn->numSlices,
|
||
|
|
pIn->isLinear,
|
||
|
|
isWidth8,
|
||
|
|
isHeight8,
|
||
|
|
pIn->pTileInfo,
|
||
|
|
&pOut->pitch,
|
||
|
|
&pOut->height,
|
||
|
|
&pOut->htileBytes,
|
||
|
|
&pOut->macroWidth,
|
||
|
|
&pOut->macroHeight,
|
||
|
|
&pOut->sliceSize,
|
||
|
|
&pOut->baseAlign);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeCmaskInfo
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of AddrComputeCmaskInfo
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeCmaskInfo(
|
||
|
|
const ADDR_COMPUTE_CMASK_INFO_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_COMPUTE_CMASK_INFO_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_INFO_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_CMASK_INFO_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_TILEINFO tileInfoNull;
|
||
|
|
ADDR_COMPUTE_CMASK_INFO_INPUT input;
|
||
|
|
|
||
|
|
if (UseTileIndex(pIn->tileIndex))
|
||
|
|
{
|
||
|
|
input = *pIn;
|
||
|
|
// Use temp tile info for calcalation
|
||
|
|
input.pTileInfo = &tileInfoNull;
|
||
|
|
|
||
|
|
returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
|
||
|
|
|
||
|
|
// Change the input structure
|
||
|
|
pIn = &input;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
returnCode = ComputeCmaskInfo(pIn->flags,
|
||
|
|
pIn->pitch,
|
||
|
|
pIn->height,
|
||
|
|
pIn->numSlices,
|
||
|
|
pIn->isLinear,
|
||
|
|
pIn->pTileInfo,
|
||
|
|
&pOut->pitch,
|
||
|
|
&pOut->height,
|
||
|
|
&pOut->cmaskBytes,
|
||
|
|
&pOut->macroWidth,
|
||
|
|
&pOut->macroHeight,
|
||
|
|
&pOut->sliceSize,
|
||
|
|
&pOut->baseAlign,
|
||
|
|
&pOut->blockMax);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeDccInfo
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function to compute DCC key info
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* return code of HwlComputeDccInfo
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeDccInfo(
|
||
|
|
const ADDR_COMPUTE_DCCINFO_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_COMPUTE_DCCINFO_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE ret = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_DCCINFO_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT)))
|
||
|
|
{
|
||
|
|
ret = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (ret == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_COMPUTE_DCCINFO_INPUT input;
|
||
|
|
|
||
|
|
if (UseTileIndex(pIn->tileIndex))
|
||
|
|
{
|
||
|
|
input = *pIn;
|
||
|
|
|
||
|
|
ret = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex,
|
||
|
|
&input.tileInfo, &input.tileMode);
|
||
|
|
|
||
|
|
pIn = &input;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (ADDR_OK == ret)
|
||
|
|
{
|
||
|
|
ret = HwlComputeDccInfo(pIn, pOut);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeHtileAddrFromCoord
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of AddrComputeHtileAddrFromCoord
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeHtileAddrFromCoord(
|
||
|
|
const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
BOOL_32 isWidth8 = (pIn->blockWidth == 8) ? TRUE : FALSE;
|
||
|
|
BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_TILEINFO tileInfoNull;
|
||
|
|
ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT input;
|
||
|
|
|
||
|
|
if (UseTileIndex(pIn->tileIndex))
|
||
|
|
{
|
||
|
|
input = *pIn;
|
||
|
|
// Use temp tile info for calcalation
|
||
|
|
input.pTileInfo = &tileInfoNull;
|
||
|
|
|
||
|
|
returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
|
||
|
|
|
||
|
|
// Change the input structure
|
||
|
|
pIn = &input;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch,
|
||
|
|
pIn->height,
|
||
|
|
pIn->x,
|
||
|
|
pIn->y,
|
||
|
|
pIn->slice,
|
||
|
|
pIn->numSlices,
|
||
|
|
1,
|
||
|
|
pIn->isLinear,
|
||
|
|
isWidth8,
|
||
|
|
isHeight8,
|
||
|
|
pIn->pTileInfo,
|
||
|
|
&pOut->bitPosition);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeHtileCoordFromAddr
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of AddrComputeHtileCoordFromAddr
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeHtileCoordFromAddr(
|
||
|
|
const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
BOOL_32 isWidth8 = (pIn->blockWidth == 8) ? TRUE : FALSE;
|
||
|
|
BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_TILEINFO tileInfoNull;
|
||
|
|
ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT input;
|
||
|
|
|
||
|
|
if (UseTileIndex(pIn->tileIndex))
|
||
|
|
{
|
||
|
|
input = *pIn;
|
||
|
|
// Use temp tile info for calcalation
|
||
|
|
input.pTileInfo = &tileInfoNull;
|
||
|
|
|
||
|
|
returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
|
||
|
|
|
||
|
|
// Change the input structure
|
||
|
|
pIn = &input;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
HwlComputeXmaskCoordFromAddr(pIn->addr,
|
||
|
|
pIn->bitPosition,
|
||
|
|
pIn->pitch,
|
||
|
|
pIn->height,
|
||
|
|
pIn->numSlices,
|
||
|
|
1,
|
||
|
|
pIn->isLinear,
|
||
|
|
isWidth8,
|
||
|
|
isHeight8,
|
||
|
|
pIn->pTileInfo,
|
||
|
|
&pOut->x,
|
||
|
|
&pOut->y,
|
||
|
|
&pOut->slice);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeCmaskAddrFromCoord
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of AddrComputeCmaskAddrFromCoord
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeCmaskAddrFromCoord(
|
||
|
|
const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_TILEINFO tileInfoNull;
|
||
|
|
ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT input;
|
||
|
|
|
||
|
|
if (UseTileIndex(pIn->tileIndex))
|
||
|
|
{
|
||
|
|
input = *pIn;
|
||
|
|
// Use temp tile info for calcalation
|
||
|
|
input.pTileInfo = &tileInfoNull;
|
||
|
|
|
||
|
|
returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
|
||
|
|
|
||
|
|
// Change the input structure
|
||
|
|
pIn = &input;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
if (pIn->flags.tcCompatible == TRUE)
|
||
|
|
{
|
||
|
|
returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch,
|
||
|
|
pIn->height,
|
||
|
|
pIn->x,
|
||
|
|
pIn->y,
|
||
|
|
pIn->slice,
|
||
|
|
pIn->numSlices,
|
||
|
|
2,
|
||
|
|
pIn->isLinear,
|
||
|
|
FALSE, //this is cmask, isWidth8 is not needed
|
||
|
|
FALSE, //this is cmask, isHeight8 is not needed
|
||
|
|
pIn->pTileInfo,
|
||
|
|
&pOut->bitPosition);
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeCmaskCoordFromAddr
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Interface function stub of AddrComputeCmaskCoordFromAddr
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeCmaskCoordFromAddr(
|
||
|
|
const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
|
||
|
|
ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
ADDR_TILEINFO tileInfoNull;
|
||
|
|
ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT input;
|
||
|
|
|
||
|
|
if (UseTileIndex(pIn->tileIndex))
|
||
|
|
{
|
||
|
|
input = *pIn;
|
||
|
|
// Use temp tile info for calcalation
|
||
|
|
input.pTileInfo = &tileInfoNull;
|
||
|
|
|
||
|
|
returnCode = HwlSetupTileCfg(input.tileIndex, input.macroModeIndex, input.pTileInfo);
|
||
|
|
|
||
|
|
// Change the input structure
|
||
|
|
pIn = &input;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
HwlComputeXmaskCoordFromAddr(pIn->addr,
|
||
|
|
pIn->bitPosition,
|
||
|
|
pIn->pitch,
|
||
|
|
pIn->height,
|
||
|
|
pIn->numSlices,
|
||
|
|
2,
|
||
|
|
pIn->isLinear,
|
||
|
|
FALSE,
|
||
|
|
FALSE,
|
||
|
|
pIn->pTileInfo,
|
||
|
|
&pOut->x,
|
||
|
|
&pOut->y,
|
||
|
|
&pOut->slice);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeTileDataWidthAndHeight
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Compute the squared cache shape for per-tile data (CMASK and HTILE)
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* N/A
|
||
|
|
*
|
||
|
|
* @note
|
||
|
|
* MacroWidth and macroHeight are measured in pixels
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
VOID AddrLib::ComputeTileDataWidthAndHeight(
|
||
|
|
UINT_32 bpp, ///< [in] bits per pixel
|
||
|
|
UINT_32 cacheBits, ///< [in] bits of cache
|
||
|
|
ADDR_TILEINFO* pTileInfo, ///< [in] Tile info
|
||
|
|
UINT_32* pMacroWidth, ///< [out] macro tile width
|
||
|
|
UINT_32* pMacroHeight ///< [out] macro tile height
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
UINT_32 height = 1;
|
||
|
|
UINT_32 width = cacheBits / bpp;
|
||
|
|
UINT_32 pipes = HwlGetPipes(pTileInfo);
|
||
|
|
|
||
|
|
// Double height until the macro-tile is close to square
|
||
|
|
// Height can only be doubled if width is even
|
||
|
|
|
||
|
|
while ((width > height * 2 * pipes) && !(width & 1))
|
||
|
|
{
|
||
|
|
width /= 2;
|
||
|
|
height *= 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
*pMacroWidth = 8 * width;
|
||
|
|
*pMacroHeight = 8 * height * pipes;
|
||
|
|
|
||
|
|
// Note: The above iterative comptuation is equivalent to the following
|
||
|
|
//
|
||
|
|
//int log2_height = ((log2(cacheBits)-log2(bpp)-log2(pipes))/2);
|
||
|
|
//int macroHeight = pow2( 3+log2(pipes)+log2_height );
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::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 AddrLib::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(bpp != 4); // Cmask does not support linear layout prior to SI
|
||
|
|
*pMacroWidth = 8 * 512 / bpp; // Align width to 512-bit memory accesses
|
||
|
|
*pMacroHeight = 8 * m_pipes; // Align height to number of pipes
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeHtileInfo
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Compute htile pitch,width, bytes per 2D slice
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* Htile bpp i.e. How many bits for an 8x8 tile
|
||
|
|
* Also returns by output parameters:
|
||
|
|
* *Htile pitch, height, total size in bytes, macro-tile dimensions and slice size*
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
UINT_32 AddrLib::ComputeHtileInfo(
|
||
|
|
ADDR_HTILE_FLAGS flags, ///< [in] htile flags
|
||
|
|
UINT_32 pitchIn, ///< [in] pitch input
|
||
|
|
UINT_32 heightIn, ///< [in] height input
|
||
|
|
UINT_32 numSlices, ///< [in] number of slices
|
||
|
|
BOOL_32 isLinear, ///< [in] if it is linear mode
|
||
|
|
BOOL_32 isWidth8, ///< [in] if htile block width is 8
|
||
|
|
BOOL_32 isHeight8, ///< [in] if htile block height is 8
|
||
|
|
ADDR_TILEINFO* pTileInfo, ///< [in] Tile info
|
||
|
|
UINT_32* pPitchOut, ///< [out] pitch output
|
||
|
|
UINT_32* pHeightOut, ///< [out] height output
|
||
|
|
UINT_64* pHtileBytes, ///< [out] bytes per 2D slice
|
||
|
|
UINT_32* pMacroWidth, ///< [out] macro-tile width in pixels
|
||
|
|
UINT_32* pMacroHeight, ///< [out] macro-tile width in pixels
|
||
|
|
UINT_64* pSliceSize, ///< [out] slice size in bytes
|
||
|
|
UINT_32* pBaseAlign ///< [out] base alignment
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
|
||
|
|
UINT_32 macroWidth;
|
||
|
|
UINT_32 macroHeight;
|
||
|
|
UINT_32 baseAlign;
|
||
|
|
UINT_64 surfBytes;
|
||
|
|
UINT_64 sliceBytes;
|
||
|
|
|
||
|
|
numSlices = Max(1u, numSlices);
|
||
|
|
|
||
|
|
const UINT_32 bpp = HwlComputeHtileBpp(isWidth8, isHeight8);
|
||
|
|
const UINT_32 cacheBits = HtileCacheBits;
|
||
|
|
|
||
|
|
if (isLinear)
|
||
|
|
{
|
||
|
|
HwlComputeTileDataWidthAndHeightLinear(¯oWidth,
|
||
|
|
¯oHeight,
|
||
|
|
bpp,
|
||
|
|
pTileInfo);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
ComputeTileDataWidthAndHeight(bpp,
|
||
|
|
cacheBits,
|
||
|
|
pTileInfo,
|
||
|
|
¯oWidth,
|
||
|
|
¯oHeight);
|
||
|
|
}
|
||
|
|
|
||
|
|
*pPitchOut = PowTwoAlign(pitchIn, macroWidth);
|
||
|
|
*pHeightOut = PowTwoAlign(heightIn, macroHeight);
|
||
|
|
|
||
|
|
baseAlign = HwlComputeHtileBaseAlign(flags.tcCompatible, isLinear, pTileInfo);
|
||
|
|
|
||
|
|
surfBytes = HwlComputeHtileBytes(*pPitchOut,
|
||
|
|
*pHeightOut,
|
||
|
|
bpp,
|
||
|
|
isLinear,
|
||
|
|
numSlices,
|
||
|
|
&sliceBytes,
|
||
|
|
baseAlign);
|
||
|
|
|
||
|
|
*pHtileBytes = surfBytes;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Use SafeAssign since they are optional
|
||
|
|
//
|
||
|
|
SafeAssign(pMacroWidth, macroWidth);
|
||
|
|
|
||
|
|
SafeAssign(pMacroHeight, macroHeight);
|
||
|
|
|
||
|
|
SafeAssign(pSliceSize, sliceBytes);
|
||
|
|
|
||
|
|
SafeAssign(pBaseAlign, baseAlign);
|
||
|
|
|
||
|
|
return bpp;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeCmaskBaseAlign
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Compute cmask base alignment
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* Cmask base alignment
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
UINT_32 AddrLib::ComputeCmaskBaseAlign(
|
||
|
|
ADDR_CMASK_FLAGS flags, ///< [in] Cmask flags
|
||
|
|
ADDR_TILEINFO* pTileInfo ///< [in] Tile info
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
UINT_32 baseAlign = m_pipeInterleaveBytes * HwlGetPipes(pTileInfo);
|
||
|
|
|
||
|
|
if (flags.tcCompatible)
|
||
|
|
{
|
||
|
|
ADDR_ASSERT(pTileInfo != NULL);
|
||
|
|
if (pTileInfo)
|
||
|
|
{
|
||
|
|
baseAlign *= pTileInfo->banks;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return baseAlign;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeCmaskBytes
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Compute cmask size in bytes
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* Cmask size in bytes
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
UINT_64 AddrLib::ComputeCmaskBytes(
|
||
|
|
UINT_32 pitch, ///< [in] pitch
|
||
|
|
UINT_32 height, ///< [in] height
|
||
|
|
UINT_32 numSlices ///< [in] number of slices
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
return BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * numSlices * CmaskElemBits) /
|
||
|
|
MicroTilePixels;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeCmaskInfo
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Compute cmask pitch,width, bytes per 2D slice
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* BlockMax. Also by output parameters: Cmask pitch,height, total size in bytes,
|
||
|
|
* macro-tile dimensions
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputeCmaskInfo(
|
||
|
|
ADDR_CMASK_FLAGS flags, ///< [in] cmask flags
|
||
|
|
UINT_32 pitchIn, ///< [in] pitch input
|
||
|
|
UINT_32 heightIn, ///< [in] height input
|
||
|
|
UINT_32 numSlices, ///< [in] number of slices
|
||
|
|
BOOL_32 isLinear, ///< [in] is linear mode
|
||
|
|
ADDR_TILEINFO* pTileInfo, ///< [in] Tile info
|
||
|
|
UINT_32* pPitchOut, ///< [out] pitch output
|
||
|
|
UINT_32* pHeightOut, ///< [out] height output
|
||
|
|
UINT_64* pCmaskBytes, ///< [out] bytes per 2D slice
|
||
|
|
UINT_32* pMacroWidth, ///< [out] macro-tile width in pixels
|
||
|
|
UINT_32* pMacroHeight, ///< [out] macro-tile width in pixels
|
||
|
|
UINT_64* pSliceSize, ///< [out] slice size in bytes
|
||
|
|
UINT_32* pBaseAlign, ///< [out] base alignment
|
||
|
|
UINT_32* pBlockMax ///< [out] block max == slice / 128 / 128 - 1
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
UINT_32 macroWidth;
|
||
|
|
UINT_32 macroHeight;
|
||
|
|
UINT_32 baseAlign;
|
||
|
|
UINT_64 surfBytes;
|
||
|
|
UINT_64 sliceBytes;
|
||
|
|
|
||
|
|
numSlices = Max(1u, numSlices);
|
||
|
|
|
||
|
|
const UINT_32 bpp = CmaskElemBits;
|
||
|
|
const UINT_32 cacheBits = CmaskCacheBits;
|
||
|
|
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (isLinear)
|
||
|
|
{
|
||
|
|
HwlComputeTileDataWidthAndHeightLinear(¯oWidth,
|
||
|
|
¯oHeight,
|
||
|
|
bpp,
|
||
|
|
pTileInfo);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
ComputeTileDataWidthAndHeight(bpp,
|
||
|
|
cacheBits,
|
||
|
|
pTileInfo,
|
||
|
|
¯oWidth,
|
||
|
|
¯oHeight);
|
||
|
|
}
|
||
|
|
|
||
|
|
*pPitchOut = (pitchIn + macroWidth - 1) & ~(macroWidth - 1);
|
||
|
|
*pHeightOut = (heightIn + macroHeight - 1) & ~(macroHeight - 1);
|
||
|
|
|
||
|
|
|
||
|
|
sliceBytes = ComputeCmaskBytes(*pPitchOut,
|
||
|
|
*pHeightOut,
|
||
|
|
1);
|
||
|
|
|
||
|
|
baseAlign = ComputeCmaskBaseAlign(flags, pTileInfo);
|
||
|
|
|
||
|
|
while (sliceBytes % baseAlign)
|
||
|
|
{
|
||
|
|
*pHeightOut += macroHeight;
|
||
|
|
|
||
|
|
sliceBytes = ComputeCmaskBytes(*pPitchOut,
|
||
|
|
*pHeightOut,
|
||
|
|
1);
|
||
|
|
}
|
||
|
|
|
||
|
|
surfBytes = sliceBytes * numSlices;
|
||
|
|
|
||
|
|
*pCmaskBytes = surfBytes;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Use SafeAssign since they are optional
|
||
|
|
//
|
||
|
|
SafeAssign(pMacroWidth, macroWidth);
|
||
|
|
|
||
|
|
SafeAssign(pMacroHeight, macroHeight);
|
||
|
|
|
||
|
|
SafeAssign(pBaseAlign, baseAlign);
|
||
|
|
|
||
|
|
SafeAssign(pSliceSize, sliceBytes);
|
||
|
|
|
||
|
|
UINT_32 slice = (*pPitchOut) * (*pHeightOut);
|
||
|
|
UINT_32 blockMax = slice / 128 / 128 - 1;
|
||
|
|
|
||
|
|
#if DEBUG
|
||
|
|
if (slice % (64*256) != 0)
|
||
|
|
{
|
||
|
|
ADDR_ASSERT_ALWAYS();
|
||
|
|
}
|
||
|
|
#endif //DEBUG
|
||
|
|
|
||
|
|
UINT_32 maxBlockMax = HwlGetMaxCmaskBlockMax();
|
||
|
|
|
||
|
|
if (blockMax > maxBlockMax)
|
||
|
|
{
|
||
|
|
blockMax = maxBlockMax;
|
||
|
|
returnCode = ADDR_INVALIDPARAMS;
|
||
|
|
}
|
||
|
|
|
||
|
|
SafeAssign(pBlockMax, blockMax);
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeXmaskCoordYFromPipe
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Compute the Y coord from pipe number for cmask/htile
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* Y coordinate
|
||
|
|
*
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
UINT_32 AddrLib::ComputeXmaskCoordYFromPipe(
|
||
|
|
UINT_32 pipe, ///< [in] pipe number
|
||
|
|
UINT_32 x ///< [in] x coordinate
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
UINT_32 pipeBit0;
|
||
|
|
UINT_32 pipeBit1;
|
||
|
|
UINT_32 xBit0;
|
||
|
|
UINT_32 xBit1;
|
||
|
|
UINT_32 yBit0;
|
||
|
|
UINT_32 yBit1;
|
||
|
|
|
||
|
|
UINT_32 y = 0;
|
||
|
|
|
||
|
|
UINT_32 numPipes = m_pipes; // SI has its implementation
|
||
|
|
//
|
||
|
|
// Convert pipe + x to y coordinate.
|
||
|
|
//
|
||
|
|
switch (numPipes)
|
||
|
|
{
|
||
|
|
case 1:
|
||
|
|
//
|
||
|
|
// 1 pipe
|
||
|
|
//
|
||
|
|
// p0 = 0
|
||
|
|
//
|
||
|
|
y = 0;
|
||
|
|
break;
|
||
|
|
case 2:
|
||
|
|
//
|
||
|
|
// 2 pipes
|
||
|
|
//
|
||
|
|
// p0 = x0 ^ y0
|
||
|
|
//
|
||
|
|
// y0 = p0 ^ x0
|
||
|
|
//
|
||
|
|
pipeBit0 = pipe & 0x1;
|
||
|
|
|
||
|
|
xBit0 = x & 0x1;
|
||
|
|
|
||
|
|
yBit0 = pipeBit0 ^ xBit0;
|
||
|
|
|
||
|
|
y = yBit0;
|
||
|
|
break;
|
||
|
|
case 4:
|
||
|
|
//
|
||
|
|
// 4 pipes
|
||
|
|
//
|
||
|
|
// p0 = x1 ^ y0
|
||
|
|
// p1 = x0 ^ y1
|
||
|
|
//
|
||
|
|
// y0 = p0 ^ x1
|
||
|
|
// y1 = p1 ^ x0
|
||
|
|
//
|
||
|
|
pipeBit0 = pipe & 0x1;
|
||
|
|
pipeBit1 = (pipe & 0x2) >> 1;
|
||
|
|
|
||
|
|
xBit0 = x & 0x1;
|
||
|
|
xBit1 = (x & 0x2) >> 1;
|
||
|
|
|
||
|
|
yBit0 = pipeBit0 ^ xBit1;
|
||
|
|
yBit1 = pipeBit1 ^ xBit0;
|
||
|
|
|
||
|
|
y = (yBit0 |
|
||
|
|
(yBit1 << 1));
|
||
|
|
break;
|
||
|
|
case 8:
|
||
|
|
//
|
||
|
|
// 8 pipes
|
||
|
|
//
|
||
|
|
// r600 and r800 have different method
|
||
|
|
//
|
||
|
|
y = HwlComputeXmaskCoordYFrom8Pipe(pipe, x);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
return y;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::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 AddrLib::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] 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* pX, ///< [out] x coord
|
||
|
|
UINT_32* pY, ///< [out] y coord
|
||
|
|
UINT_32* pSlice ///< [out] slice index
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
UINT_32 pipe;
|
||
|
|
UINT_32 numPipes;
|
||
|
|
UINT_32 numPipeBits;
|
||
|
|
UINT_32 macroTilePitch;
|
||
|
|
UINT_32 macroTileHeight;
|
||
|
|
|
||
|
|
UINT_64 bitAddr;
|
||
|
|
|
||
|
|
UINT_32 microTileCoordY;
|
||
|
|
|
||
|
|
UINT_32 elemBits;
|
||
|
|
|
||
|
|
UINT_32 pitchAligned = pitch;
|
||
|
|
UINT_32 heightAligned = height;
|
||
|
|
UINT_64 totalBytes;
|
||
|
|
|
||
|
|
UINT_64 elemOffset;
|
||
|
|
|
||
|
|
UINT_64 macroIndex;
|
||
|
|
UINT_32 microIndex;
|
||
|
|
|
||
|
|
UINT_64 macroNumber;
|
||
|
|
UINT_32 microNumber;
|
||
|
|
|
||
|
|
UINT_32 macroX;
|
||
|
|
UINT_32 macroY;
|
||
|
|
UINT_32 macroZ;
|
||
|
|
|
||
|
|
UINT_32 microX;
|
||
|
|
UINT_32 microY;
|
||
|
|
|
||
|
|
UINT_32 tilesPerMacro;
|
||
|
|
UINT_32 macrosPerPitch;
|
||
|
|
UINT_32 macrosPerSlice;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Extract pipe.
|
||
|
|
//
|
||
|
|
numPipes = HwlGetPipes(pTileInfo);
|
||
|
|
pipe = ComputePipeFromAddr(addr, numPipes);
|
||
|
|
|
||
|
|
//
|
||
|
|
// Compute the number of group and pipe bits.
|
||
|
|
//
|
||
|
|
numPipeBits = Log2(numPipes);
|
||
|
|
|
||
|
|
UINT_32 groupBits = 8 * m_pipeInterleaveBytes;
|
||
|
|
UINT_32 pipes = numPipes;
|
||
|
|
|
||
|
|
|
||
|
|
//
|
||
|
|
// Compute the micro tile size, in bits. And macro tile pitch and height.
|
||
|
|
//
|
||
|
|
if (factor == 2) //CMASK
|
||
|
|
{
|
||
|
|
ADDR_CMASK_FLAGS flags = {{0}};
|
||
|
|
|
||
|
|
elemBits = CmaskElemBits;
|
||
|
|
|
||
|
|
ComputeCmaskInfo(flags,
|
||
|
|
pitch,
|
||
|
|
height,
|
||
|
|
numSlices,
|
||
|
|
isLinear,
|
||
|
|
pTileInfo,
|
||
|
|
&pitchAligned,
|
||
|
|
&heightAligned,
|
||
|
|
&totalBytes,
|
||
|
|
¯oTilePitch,
|
||
|
|
¯oTileHeight);
|
||
|
|
}
|
||
|
|
else //HTILE
|
||
|
|
{
|
||
|
|
ADDR_HTILE_FLAGS flags = {{0}};
|
||
|
|
|
||
|
|
if (factor != 1)
|
||
|
|
{
|
||
|
|
factor = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
elemBits = HwlComputeHtileBpp(isWidth8, isHeight8);
|
||
|
|
|
||
|
|
ComputeHtileInfo(flags,
|
||
|
|
pitch,
|
||
|
|
height,
|
||
|
|
numSlices,
|
||
|
|
isLinear,
|
||
|
|
isWidth8,
|
||
|
|
isHeight8,
|
||
|
|
pTileInfo,
|
||
|
|
&pitchAligned,
|
||
|
|
&heightAligned,
|
||
|
|
&totalBytes,
|
||
|
|
¯oTilePitch,
|
||
|
|
¯oTileHeight);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Should use aligned dims
|
||
|
|
//
|
||
|
|
pitch = pitchAligned;
|
||
|
|
height = heightAligned;
|
||
|
|
|
||
|
|
|
||
|
|
//
|
||
|
|
// Convert byte address to bit address.
|
||
|
|
//
|
||
|
|
bitAddr = BYTES_TO_BITS(addr) + bitPosition;
|
||
|
|
|
||
|
|
|
||
|
|
//
|
||
|
|
// Remove pipe bits from address.
|
||
|
|
//
|
||
|
|
|
||
|
|
bitAddr = (bitAddr % groupBits) + ((bitAddr/groupBits/pipes)*groupBits);
|
||
|
|
|
||
|
|
|
||
|
|
elemOffset = bitAddr / elemBits;
|
||
|
|
|
||
|
|
tilesPerMacro = (macroTilePitch/factor) * macroTileHeight / MicroTilePixels >> numPipeBits;
|
||
|
|
|
||
|
|
macrosPerPitch = pitch / (macroTilePitch/factor);
|
||
|
|
macrosPerSlice = macrosPerPitch * height / macroTileHeight;
|
||
|
|
|
||
|
|
macroIndex = elemOffset / factor / tilesPerMacro;
|
||
|
|
microIndex = static_cast<UINT_32>(elemOffset % (tilesPerMacro * factor));
|
||
|
|
|
||
|
|
macroNumber = macroIndex * factor + microIndex % factor;
|
||
|
|
microNumber = microIndex / factor;
|
||
|
|
|
||
|
|
macroX = static_cast<UINT_32>((macroNumber % macrosPerPitch));
|
||
|
|
macroY = static_cast<UINT_32>((macroNumber % macrosPerSlice) / macrosPerPitch);
|
||
|
|
macroZ = static_cast<UINT_32>((macroNumber / macrosPerSlice));
|
||
|
|
|
||
|
|
|
||
|
|
microX = microNumber % (macroTilePitch / factor / MicroTileWidth);
|
||
|
|
microY = (microNumber / (macroTilePitch / factor / MicroTileHeight));
|
||
|
|
|
||
|
|
*pX = macroX * (macroTilePitch/factor) + microX * MicroTileWidth;
|
||
|
|
*pY = macroY * macroTileHeight + (microY * MicroTileHeight << numPipeBits);
|
||
|
|
*pSlice = macroZ;
|
||
|
|
|
||
|
|
microTileCoordY = ComputeXmaskCoordYFromPipe(pipe,
|
||
|
|
*pX/MicroTileWidth);
|
||
|
|
|
||
|
|
|
||
|
|
//
|
||
|
|
// Assemble final coordinates.
|
||
|
|
//
|
||
|
|
*pY += microTileCoordY * MicroTileHeight;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::HwlComputeXmaskAddrFromCoord
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Compute the address from an address of cmask (prior to si)
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* Address in bytes
|
||
|
|
*
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
UINT_64 AddrLib::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_64 addr;
|
||
|
|
UINT_32 numGroupBits;
|
||
|
|
UINT_32 numPipeBits;
|
||
|
|
UINT_32 newPitch = 0;
|
||
|
|
UINT_32 newHeight = 0;
|
||
|
|
UINT_64 sliceBytes = 0;
|
||
|
|
UINT_64 totalBytes = 0;
|
||
|
|
UINT_64 sliceOffset;
|
||
|
|
UINT_32 pipe;
|
||
|
|
UINT_32 macroTileWidth;
|
||
|
|
UINT_32 macroTileHeight;
|
||
|
|
UINT_32 macroTilesPerRow;
|
||
|
|
UINT_32 macroTileBytes;
|
||
|
|
UINT_32 macroTileIndexX;
|
||
|
|
UINT_32 macroTileIndexY;
|
||
|
|
UINT_64 macroTileOffset;
|
||
|
|
UINT_32 pixelBytesPerRow;
|
||
|
|
UINT_32 pixelOffsetX;
|
||
|
|
UINT_32 pixelOffsetY;
|
||
|
|
UINT_32 pixelOffset;
|
||
|
|
UINT_64 totalOffset;
|
||
|
|
UINT_64 offsetLo;
|
||
|
|
UINT_64 offsetHi;
|
||
|
|
UINT_64 groupMask;
|
||
|
|
|
||
|
|
|
||
|
|
UINT_32 elemBits = 0;
|
||
|
|
|
||
|
|
UINT_32 numPipes = m_pipes; // This function is accessed prior to si only
|
||
|
|
|
||
|
|
if (factor == 2) //CMASK
|
||
|
|
{
|
||
|
|
elemBits = CmaskElemBits;
|
||
|
|
|
||
|
|
// For asics before SI, cmask is always tiled
|
||
|
|
isLinear = FALSE;
|
||
|
|
}
|
||
|
|
else //HTILE
|
||
|
|
{
|
||
|
|
if (factor != 1) // Fix compile warning
|
||
|
|
{
|
||
|
|
factor = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
elemBits = HwlComputeHtileBpp(isWidth8, isHeight8);
|
||
|
|
}
|
||
|
|
|
||
|
|
//
|
||
|
|
// Compute the number of group bits and pipe bits.
|
||
|
|
//
|
||
|
|
numGroupBits = Log2(m_pipeInterleaveBytes);
|
||
|
|
numPipeBits = Log2(numPipes);
|
||
|
|
|
||
|
|
//
|
||
|
|
// Compute macro tile dimensions.
|
||
|
|
//
|
||
|
|
if (factor == 2) // CMASK
|
||
|
|
{
|
||
|
|
ADDR_CMASK_FLAGS flags = {{0}};
|
||
|
|
|
||
|
|
ComputeCmaskInfo(flags,
|
||
|
|
pitch,
|
||
|
|
height,
|
||
|
|
numSlices,
|
||
|
|
isLinear,
|
||
|
|
pTileInfo,
|
||
|
|
&newPitch,
|
||
|
|
&newHeight,
|
||
|
|
&totalBytes,
|
||
|
|
¯oTileWidth,
|
||
|
|
¯oTileHeight);
|
||
|
|
|
||
|
|
sliceBytes = totalBytes / numSlices;
|
||
|
|
}
|
||
|
|
else // HTILE
|
||
|
|
{
|
||
|
|
ADDR_HTILE_FLAGS flags = {{0}};
|
||
|
|
|
||
|
|
ComputeHtileInfo(flags,
|
||
|
|
pitch,
|
||
|
|
height,
|
||
|
|
numSlices,
|
||
|
|
isLinear,
|
||
|
|
isWidth8,
|
||
|
|
isHeight8,
|
||
|
|
pTileInfo,
|
||
|
|
&newPitch,
|
||
|
|
&newHeight,
|
||
|
|
&totalBytes,
|
||
|
|
¯oTileWidth,
|
||
|
|
¯oTileHeight,
|
||
|
|
&sliceBytes);
|
||
|
|
}
|
||
|
|
|
||
|
|
sliceOffset = slice * sliceBytes;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Get the pipe. Note that neither slice rotation nor pipe swizzling apply for CMASK.
|
||
|
|
//
|
||
|
|
pipe = ComputePipeFromCoord(x,
|
||
|
|
y,
|
||
|
|
0,
|
||
|
|
ADDR_TM_2D_TILED_THIN1,
|
||
|
|
0,
|
||
|
|
FALSE,
|
||
|
|
pTileInfo);
|
||
|
|
|
||
|
|
//
|
||
|
|
// Compute the number of macro tiles per row.
|
||
|
|
//
|
||
|
|
macroTilesPerRow = newPitch / macroTileWidth;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Compute the number of bytes per macro tile.
|
||
|
|
//
|
||
|
|
macroTileBytes = BITS_TO_BYTES((macroTileWidth * macroTileHeight * elemBits) / MicroTilePixels);
|
||
|
|
|
||
|
|
//
|
||
|
|
// Compute the offset to the macro tile containing the specified coordinate.
|
||
|
|
//
|
||
|
|
macroTileIndexX = x / macroTileWidth;
|
||
|
|
macroTileIndexY = y / macroTileHeight;
|
||
|
|
macroTileOffset = ((macroTileIndexY * macroTilesPerRow) + macroTileIndexX) * macroTileBytes;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Compute the pixel offset within the macro tile.
|
||
|
|
//
|
||
|
|
pixelBytesPerRow = BITS_TO_BYTES(macroTileWidth * elemBits) / MicroTileWidth;
|
||
|
|
|
||
|
|
//
|
||
|
|
// The nibbles are interleaved (see below), so the part of the offset relative to the x
|
||
|
|
// coordinate repeats halfway across the row. (Not for HTILE)
|
||
|
|
//
|
||
|
|
if (factor == 2)
|
||
|
|
{
|
||
|
|
pixelOffsetX = (x % (macroTileWidth / 2)) / MicroTileWidth;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
pixelOffsetX = (x % (macroTileWidth)) / MicroTileWidth * BITS_TO_BYTES(elemBits);
|
||
|
|
}
|
||
|
|
|
||
|
|
//
|
||
|
|
// Compute the y offset within the macro tile.
|
||
|
|
//
|
||
|
|
pixelOffsetY = (((y % macroTileHeight) / MicroTileHeight) / numPipes) * pixelBytesPerRow;
|
||
|
|
|
||
|
|
pixelOffset = pixelOffsetX + pixelOffsetY;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Combine the slice offset and macro tile offset with the pixel offset, accounting for the
|
||
|
|
// pipe bits in the middle of the address.
|
||
|
|
//
|
||
|
|
totalOffset = ((sliceOffset + macroTileOffset) >> numPipeBits) + pixelOffset;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Split the offset to put some bits below the pipe bits and some above.
|
||
|
|
//
|
||
|
|
groupMask = (1 << numGroupBits) - 1;
|
||
|
|
offsetLo = totalOffset & groupMask;
|
||
|
|
offsetHi = (totalOffset & ~groupMask) << numPipeBits;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Assemble the address from its components.
|
||
|
|
//
|
||
|
|
addr = offsetLo;
|
||
|
|
addr |= offsetHi;
|
||
|
|
// This is to remove warning with /analyze option
|
||
|
|
UINT_32 pipeBits = pipe << numGroupBits;
|
||
|
|
addr |= pipeBits;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Compute the bit position. The lower nibble is used when the x coordinate within the macro
|
||
|
|
// tile is less than half of the macro tile width, and the upper nibble is used when the x
|
||
|
|
// coordinate within the macro tile is greater than or equal to half the macro tile width.
|
||
|
|
//
|
||
|
|
*pBitPosition = ((x % macroTileWidth) < (macroTileWidth / factor)) ? 0 : 4;
|
||
|
|
|
||
|
|
return addr;
|
||
|
|
}
|
||
|
|
|
||
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
// Surface Addressing Shared
|
||
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeSurfaceAddrFromCoordLinear
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Compute address from coord for linear surface
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* Address in bytes
|
||
|
|
*
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
UINT_64 AddrLib::ComputeSurfaceAddrFromCoordLinear(
|
||
|
|
UINT_32 x, ///< [in] x coord
|
||
|
|
UINT_32 y, ///< [in] y coord
|
||
|
|
UINT_32 slice, ///< [in] slice/depth index
|
||
|
|
UINT_32 sample, ///< [in] sample index
|
||
|
|
UINT_32 bpp, ///< [in] bits per pixel
|
||
|
|
UINT_32 pitch, ///< [in] pitch
|
||
|
|
UINT_32 height, ///< [in] height
|
||
|
|
UINT_32 numSlices, ///< [in] number of slices
|
||
|
|
UINT_32* pBitPosition ///< [out] bit position inside a byte
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height;
|
||
|
|
|
||
|
|
UINT_64 sliceOffset = (slice + sample * numSlices)* sliceSize;
|
||
|
|
UINT_64 rowOffset = static_cast<UINT_64>(y) * pitch;
|
||
|
|
UINT_64 pixOffset = x;
|
||
|
|
|
||
|
|
UINT_64 addr = (sliceOffset + rowOffset + pixOffset) * bpp;
|
||
|
|
|
||
|
|
*pBitPosition = static_cast<UINT_32>(addr % 8);
|
||
|
|
addr /= 8;
|
||
|
|
|
||
|
|
return addr;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeSurfaceCoordFromAddrLinear
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Compute the coord from an address of a linear surface
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* N/A
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
VOID AddrLib::ComputeSurfaceCoordFromAddrLinear(
|
||
|
|
UINT_64 addr, ///< [in] address
|
||
|
|
UINT_32 bitPosition, ///< [in] bitPosition in a byte
|
||
|
|
UINT_32 bpp, ///< [in] bits per pixel
|
||
|
|
UINT_32 pitch, ///< [in] pitch
|
||
|
|
UINT_32 height, ///< [in] height
|
||
|
|
UINT_32 numSlices, ///< [in] number of slices
|
||
|
|
UINT_32* pX, ///< [out] x coord
|
||
|
|
UINT_32* pY, ///< [out] y coord
|
||
|
|
UINT_32* pSlice, ///< [out] slice/depth index
|
||
|
|
UINT_32* pSample ///< [out] sample index
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height;
|
||
|
|
const UINT_64 linearOffset = (BYTES_TO_BITS(addr) + bitPosition) / bpp;
|
||
|
|
|
||
|
|
*pX = static_cast<UINT_32>((linearOffset % sliceSize) % pitch);
|
||
|
|
*pY = static_cast<UINT_32>((linearOffset % sliceSize) / pitch % height);
|
||
|
|
*pSlice = static_cast<UINT_32>((linearOffset / sliceSize) % numSlices);
|
||
|
|
*pSample = static_cast<UINT_32>((linearOffset / sliceSize) / numSlices);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeSurfaceCoordFromAddrMicroTiled
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Compute the coord from an address of a micro tiled surface
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* N/A
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
VOID AddrLib::ComputeSurfaceCoordFromAddrMicroTiled(
|
||
|
|
UINT_64 addr, ///< [in] address
|
||
|
|
UINT_32 bitPosition, ///< [in] bitPosition in a byte
|
||
|
|
UINT_32 bpp, ///< [in] bits per pixel
|
||
|
|
UINT_32 pitch, ///< [in] pitch
|
||
|
|
UINT_32 height, ///< [in] height
|
||
|
|
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 coord
|
||
|
|
UINT_32* pY, ///< [out] y coord
|
||
|
|
UINT_32* pSlice, ///< [out] slice/depth index
|
||
|
|
UINT_32* pSample, ///< [out] sample index,
|
||
|
|
AddrTileType microTileType, ///< [in] micro tiling order
|
||
|
|
BOOL_32 isDepthSampleOrder ///< [in] TRUE if in depth sample order
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
UINT_64 bitAddr;
|
||
|
|
UINT_32 microTileThickness;
|
||
|
|
UINT_32 microTileBits;
|
||
|
|
UINT_64 sliceBits;
|
||
|
|
UINT_64 rowBits;
|
||
|
|
UINT_32 sliceIndex;
|
||
|
|
UINT_32 microTileCoordX;
|
||
|
|
UINT_32 microTileCoordY;
|
||
|
|
UINT_32 pixelOffset;
|
||
|
|
UINT_32 pixelCoordX = 0;
|
||
|
|
UINT_32 pixelCoordY = 0;
|
||
|
|
UINT_32 pixelCoordZ = 0;
|
||
|
|
UINT_32 pixelCoordS = 0;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Convert byte address to bit address.
|
||
|
|
//
|
||
|
|
bitAddr = BYTES_TO_BITS(addr) + bitPosition;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Compute the micro tile size, in bits.
|
||
|
|
//
|
||
|
|
switch (tileMode)
|
||
|
|
{
|
||
|
|
case ADDR_TM_1D_TILED_THICK:
|
||
|
|
microTileThickness = ThickTileThickness;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
microTileThickness = 1;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
microTileBits = MicroTilePixels * microTileThickness * bpp * numSamples;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Compute number of bits per slice and number of bits per row of micro tiles.
|
||
|
|
//
|
||
|
|
sliceBits = static_cast<UINT_64>(pitch) * height * microTileThickness * bpp * numSamples;
|
||
|
|
|
||
|
|
rowBits = (pitch / MicroTileWidth) * microTileBits;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Extract the slice index.
|
||
|
|
//
|
||
|
|
sliceIndex = static_cast<UINT_32>(bitAddr / sliceBits);
|
||
|
|
bitAddr -= sliceIndex * sliceBits;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Extract the y coordinate of the micro tile.
|
||
|
|
//
|
||
|
|
microTileCoordY = static_cast<UINT_32>(bitAddr / rowBits) * MicroTileHeight;
|
||
|
|
bitAddr -= (microTileCoordY / MicroTileHeight) * rowBits;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Extract the x coordinate of the micro tile.
|
||
|
|
//
|
||
|
|
microTileCoordX = static_cast<UINT_32>(bitAddr / microTileBits) * MicroTileWidth;
|
||
|
|
|
||
|
|
//
|
||
|
|
// Compute the pixel offset within the micro tile.
|
||
|
|
//
|
||
|
|
pixelOffset = static_cast<UINT_32>(bitAddr % microTileBits);
|
||
|
|
|
||
|
|
//
|
||
|
|
// Extract pixel coordinates from the offset.
|
||
|
|
//
|
||
|
|
HwlComputePixelCoordFromOffset(pixelOffset,
|
||
|
|
bpp,
|
||
|
|
numSamples,
|
||
|
|
tileMode,
|
||
|
|
tileBase,
|
||
|
|
compBits,
|
||
|
|
&pixelCoordX,
|
||
|
|
&pixelCoordY,
|
||
|
|
&pixelCoordZ,
|
||
|
|
&pixelCoordS,
|
||
|
|
microTileType,
|
||
|
|
isDepthSampleOrder);
|
||
|
|
|
||
|
|
//
|
||
|
|
// Assemble final coordinates.
|
||
|
|
//
|
||
|
|
*pX = microTileCoordX + pixelCoordX;
|
||
|
|
*pY = microTileCoordY + pixelCoordY;
|
||
|
|
*pSlice = (sliceIndex * microTileThickness) + pixelCoordZ;
|
||
|
|
*pSample = pixelCoordS;
|
||
|
|
|
||
|
|
if (microTileThickness > 1)
|
||
|
|
{
|
||
|
|
*pSample = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputePipeFromAddr
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Compute the pipe number from an address
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* Pipe number
|
||
|
|
*
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
UINT_32 AddrLib::ComputePipeFromAddr(
|
||
|
|
UINT_64 addr, ///< [in] address
|
||
|
|
UINT_32 numPipes ///< [in] number of banks
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
UINT_32 pipe;
|
||
|
|
|
||
|
|
UINT_32 groupBytes = m_pipeInterleaveBytes; //just different terms
|
||
|
|
|
||
|
|
// R600
|
||
|
|
// The LSBs of the address are arranged as follows:
|
||
|
|
// bank | pipe | group
|
||
|
|
//
|
||
|
|
// To get the pipe number, shift off the group bits and mask the pipe bits.
|
||
|
|
//
|
||
|
|
|
||
|
|
// R800
|
||
|
|
// The LSBs of the address are arranged as follows:
|
||
|
|
// bank | bankInterleave | pipe | pipeInterleave
|
||
|
|
//
|
||
|
|
// To get the pipe number, shift off the pipe interleave bits and mask the pipe bits.
|
||
|
|
//
|
||
|
|
|
||
|
|
pipe = static_cast<UINT_32>(addr >> Log2(groupBytes)) & (numPipes - 1);
|
||
|
|
|
||
|
|
return pipe;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputePixelIndexWithinMicroTile
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Compute the pixel index inside a micro tile of surface
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* Pixel index
|
||
|
|
*
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
UINT_32 AddrLib::ComputePixelIndexWithinMicroTile(
|
||
|
|
UINT_32 x, ///< [in] x coord
|
||
|
|
UINT_32 y, ///< [in] y coord
|
||
|
|
UINT_32 z, ///< [in] slice/depth index
|
||
|
|
UINT_32 bpp, ///< [in] bits per pixel
|
||
|
|
AddrTileMode tileMode, ///< [in] tile mode
|
||
|
|
AddrTileType microTileType ///< [in] pixel order in display/non-display mode
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
UINT_32 pixelBit0 = 0;
|
||
|
|
UINT_32 pixelBit1 = 0;
|
||
|
|
UINT_32 pixelBit2 = 0;
|
||
|
|
UINT_32 pixelBit3 = 0;
|
||
|
|
UINT_32 pixelBit4 = 0;
|
||
|
|
UINT_32 pixelBit5 = 0;
|
||
|
|
UINT_32 pixelBit6 = 0;
|
||
|
|
UINT_32 pixelBit7 = 0;
|
||
|
|
UINT_32 pixelBit8 = 0;
|
||
|
|
UINT_32 pixelNumber;
|
||
|
|
|
||
|
|
UINT_32 x0 = _BIT(x, 0);
|
||
|
|
UINT_32 x1 = _BIT(x, 1);
|
||
|
|
UINT_32 x2 = _BIT(x, 2);
|
||
|
|
UINT_32 y0 = _BIT(y, 0);
|
||
|
|
UINT_32 y1 = _BIT(y, 1);
|
||
|
|
UINT_32 y2 = _BIT(y, 2);
|
||
|
|
UINT_32 z0 = _BIT(z, 0);
|
||
|
|
UINT_32 z1 = _BIT(z, 1);
|
||
|
|
UINT_32 z2 = _BIT(z, 2);
|
||
|
|
|
||
|
|
UINT_32 thickness = ComputeSurfaceThickness(tileMode);
|
||
|
|
|
||
|
|
// Compute the pixel number within the micro tile.
|
||
|
|
|
||
|
|
if (microTileType != ADDR_THICK)
|
||
|
|
{
|
||
|
|
if (microTileType == ADDR_DISPLAYABLE)
|
||
|
|
{
|
||
|
|
switch (bpp)
|
||
|
|
{
|
||
|
|
case 8:
|
||
|
|
pixelBit0 = x0;
|
||
|
|
pixelBit1 = x1;
|
||
|
|
pixelBit2 = x2;
|
||
|
|
pixelBit3 = y1;
|
||
|
|
pixelBit4 = y0;
|
||
|
|
pixelBit5 = y2;
|
||
|
|
break;
|
||
|
|
case 16:
|
||
|
|
pixelBit0 = x0;
|
||
|
|
pixelBit1 = x1;
|
||
|
|
pixelBit2 = x2;
|
||
|
|
pixelBit3 = y0;
|
||
|
|
pixelBit4 = y1;
|
||
|
|
pixelBit5 = y2;
|
||
|
|
break;
|
||
|
|
case 32:
|
||
|
|
pixelBit0 = x0;
|
||
|
|
pixelBit1 = x1;
|
||
|
|
pixelBit2 = y0;
|
||
|
|
pixelBit3 = x2;
|
||
|
|
pixelBit4 = y1;
|
||
|
|
pixelBit5 = y2;
|
||
|
|
break;
|
||
|
|
case 64:
|
||
|
|
pixelBit0 = x0;
|
||
|
|
pixelBit1 = y0;
|
||
|
|
pixelBit2 = x1;
|
||
|
|
pixelBit3 = x2;
|
||
|
|
pixelBit4 = y1;
|
||
|
|
pixelBit5 = y2;
|
||
|
|
break;
|
||
|
|
case 128:
|
||
|
|
pixelBit0 = y0;
|
||
|
|
pixelBit1 = x0;
|
||
|
|
pixelBit2 = x1;
|
||
|
|
pixelBit3 = x2;
|
||
|
|
pixelBit4 = y1;
|
||
|
|
pixelBit5 = y2;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
ADDR_ASSERT_ALWAYS();
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER)
|
||
|
|
{
|
||
|
|
pixelBit0 = x0;
|
||
|
|
pixelBit1 = y0;
|
||
|
|
pixelBit2 = x1;
|
||
|
|
pixelBit3 = y1;
|
||
|
|
pixelBit4 = x2;
|
||
|
|
pixelBit5 = y2;
|
||
|
|
}
|
||
|
|
else if (microTileType == ADDR_ROTATED)
|
||
|
|
{
|
||
|
|
ADDR_ASSERT(thickness == 1);
|
||
|
|
|
||
|
|
switch (bpp)
|
||
|
|
{
|
||
|
|
case 8:
|
||
|
|
pixelBit0 = y0;
|
||
|
|
pixelBit1 = y1;
|
||
|
|
pixelBit2 = y2;
|
||
|
|
pixelBit3 = x1;
|
||
|
|
pixelBit4 = x0;
|
||
|
|
pixelBit5 = x2;
|
||
|
|
break;
|
||
|
|
case 16:
|
||
|
|
pixelBit0 = y0;
|
||
|
|
pixelBit1 = y1;
|
||
|
|
pixelBit2 = y2;
|
||
|
|
pixelBit3 = x0;
|
||
|
|
pixelBit4 = x1;
|
||
|
|
pixelBit5 = x2;
|
||
|
|
break;
|
||
|
|
case 32:
|
||
|
|
pixelBit0 = y0;
|
||
|
|
pixelBit1 = y1;
|
||
|
|
pixelBit2 = x0;
|
||
|
|
pixelBit3 = y2;
|
||
|
|
pixelBit4 = x1;
|
||
|
|
pixelBit5 = x2;
|
||
|
|
break;
|
||
|
|
case 64:
|
||
|
|
pixelBit0 = y0;
|
||
|
|
pixelBit1 = x0;
|
||
|
|
pixelBit2 = y1;
|
||
|
|
pixelBit3 = x1;
|
||
|
|
pixelBit4 = x2;
|
||
|
|
pixelBit5 = y2;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
ADDR_ASSERT_ALWAYS();
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (thickness > 1)
|
||
|
|
{
|
||
|
|
pixelBit6 = z0;
|
||
|
|
pixelBit7 = z1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else // ADDR_THICK
|
||
|
|
{
|
||
|
|
ADDR_ASSERT(thickness > 1);
|
||
|
|
|
||
|
|
switch (bpp)
|
||
|
|
{
|
||
|
|
case 8:
|
||
|
|
case 16:
|
||
|
|
pixelBit0 = x0;
|
||
|
|
pixelBit1 = y0;
|
||
|
|
pixelBit2 = x1;
|
||
|
|
pixelBit3 = y1;
|
||
|
|
pixelBit4 = z0;
|
||
|
|
pixelBit5 = z1;
|
||
|
|
break;
|
||
|
|
case 32:
|
||
|
|
pixelBit0 = x0;
|
||
|
|
pixelBit1 = y0;
|
||
|
|
pixelBit2 = x1;
|
||
|
|
pixelBit3 = z0;
|
||
|
|
pixelBit4 = y1;
|
||
|
|
pixelBit5 = z1;
|
||
|
|
break;
|
||
|
|
case 64:
|
||
|
|
case 128:
|
||
|
|
pixelBit0 = y0;
|
||
|
|
pixelBit1 = x0;
|
||
|
|
pixelBit2 = z0;
|
||
|
|
pixelBit3 = x1;
|
||
|
|
pixelBit4 = y1;
|
||
|
|
pixelBit5 = z1;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
ADDR_ASSERT_ALWAYS();
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
pixelBit6 = x2;
|
||
|
|
pixelBit7 = y2;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (thickness == 8)
|
||
|
|
{
|
||
|
|
pixelBit8 = z2;
|
||
|
|
}
|
||
|
|
|
||
|
|
pixelNumber = ((pixelBit0 ) |
|
||
|
|
(pixelBit1 << 1) |
|
||
|
|
(pixelBit2 << 2) |
|
||
|
|
(pixelBit3 << 3) |
|
||
|
|
(pixelBit4 << 4) |
|
||
|
|
(pixelBit5 << 5) |
|
||
|
|
(pixelBit6 << 6) |
|
||
|
|
(pixelBit7 << 7) |
|
||
|
|
(pixelBit8 << 8));
|
||
|
|
|
||
|
|
return pixelNumber;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::AdjustPitchAlignment
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Adjusts pitch alignment for flipping surface
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* N/A
|
||
|
|
*
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
VOID AddrLib::AdjustPitchAlignment(
|
||
|
|
ADDR_SURFACE_FLAGS flags, ///< [in] Surface flags
|
||
|
|
UINT_32* pPitchAlign ///< [out] Pointer to pitch alignment
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
// Display engine hardwires lower 5 bit of GRPH_PITCH to ZERO which means 32 pixel alignment
|
||
|
|
// Maybe it will be fixed in future but let's make it general for now.
|
||
|
|
if (flags.display || flags.overlay)
|
||
|
|
{
|
||
|
|
*pPitchAlign = PowTwoAlign(*pPitchAlign, 32);
|
||
|
|
|
||
|
|
if(flags.display)
|
||
|
|
{
|
||
|
|
*pPitchAlign = Max(m_minPitchAlignPixels, *pPitchAlign);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::PadDimensions
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Helper function to pad dimensions
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* N/A
|
||
|
|
*
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
VOID AddrLib::PadDimensions(
|
||
|
|
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
|
||
|
|
{
|
||
|
|
UINT_32 thickness = ComputeSurfaceThickness(tileMode);
|
||
|
|
|
||
|
|
ADDR_ASSERT(padDims <= 3);
|
||
|
|
|
||
|
|
//
|
||
|
|
// Override padding for mip levels
|
||
|
|
//
|
||
|
|
if (mipLevel > 0)
|
||
|
|
{
|
||
|
|
if (flags.cube)
|
||
|
|
{
|
||
|
|
// for cubemap, we only pad when client call with 6 faces as an identity
|
||
|
|
if (*pSlices > 1)
|
||
|
|
{
|
||
|
|
padDims = 3; // we should pad cubemap sub levels when we treat it as 3d texture
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
padDims = 2;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Any possibilities that padDims is 0?
|
||
|
|
if (padDims == 0)
|
||
|
|
{
|
||
|
|
padDims = 3;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (IsPow2(pitchAlign))
|
||
|
|
{
|
||
|
|
*pPitch = PowTwoAlign((*pPitch), pitchAlign);
|
||
|
|
}
|
||
|
|
else // add this code to pass unit test, r600 linear mode is not align bpp to pow2 for linear
|
||
|
|
{
|
||
|
|
*pPitch += pitchAlign - 1;
|
||
|
|
*pPitch /= pitchAlign;
|
||
|
|
*pPitch *= pitchAlign;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (padDims > 1)
|
||
|
|
{
|
||
|
|
*pHeight = PowTwoAlign((*pHeight), heightAlign);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (padDims > 2 || thickness > 1)
|
||
|
|
{
|
||
|
|
// for cubemap single face, we do not pad slices.
|
||
|
|
// if we pad it, the slice number should be set to 6 and current mip level > 1
|
||
|
|
if (flags.cube && (!m_configFlags.noCubeMipSlicesPad || flags.cubeAsArray))
|
||
|
|
{
|
||
|
|
*pSlices = NextPow2(*pSlices);
|
||
|
|
}
|
||
|
|
|
||
|
|
// normal 3D texture or arrays or cubemap has a thick mode? (Just pass unit test)
|
||
|
|
if (thickness > 1)
|
||
|
|
{
|
||
|
|
*pSlices = PowTwoAlign((*pSlices), sliceAlign);
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
HwlPadDimensions(tileMode,
|
||
|
|
bpp,
|
||
|
|
flags,
|
||
|
|
numSamples,
|
||
|
|
pTileInfo,
|
||
|
|
padDims,
|
||
|
|
mipLevel,
|
||
|
|
pPitch,
|
||
|
|
pitchAlign,
|
||
|
|
pHeight,
|
||
|
|
heightAlign,
|
||
|
|
pSlices,
|
||
|
|
sliceAlign);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::HwlPreHandleBaseLvl3xPitch
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Pre-handler of 3x pitch (96 bit) adjustment
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* Expected pitch
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
UINT_32 AddrLib::HwlPreHandleBaseLvl3xPitch(
|
||
|
|
const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input
|
||
|
|
UINT_32 expPitch ///< [in] pitch
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
ADDR_ASSERT(pIn->width == expPitch);
|
||
|
|
//
|
||
|
|
// If pitch is pre-multiplied by 3, we retrieve original one here to get correct miplevel size
|
||
|
|
//
|
||
|
|
if (AddrElemLib::IsExpand3x(pIn->format) &&
|
||
|
|
pIn->mipLevel == 0 &&
|
||
|
|
pIn->tileMode == ADDR_TM_LINEAR_ALIGNED)
|
||
|
|
{
|
||
|
|
expPitch /= 3;
|
||
|
|
expPitch = NextPow2(expPitch);
|
||
|
|
}
|
||
|
|
|
||
|
|
return expPitch;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::HwlPostHandleBaseLvl3xPitch
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Post-handler of 3x pitch adjustment
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* Expected pitch
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
UINT_32 AddrLib::HwlPostHandleBaseLvl3xPitch(
|
||
|
|
const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input
|
||
|
|
UINT_32 expPitch ///< [in] pitch
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
//
|
||
|
|
// 96 bits surface of sub levels require element pitch of 32 bits instead
|
||
|
|
// So we just return pitch in 32 bit pixels without timing 3
|
||
|
|
//
|
||
|
|
if (AddrElemLib::IsExpand3x(pIn->format) &&
|
||
|
|
pIn->mipLevel == 0 &&
|
||
|
|
pIn->tileMode == ADDR_TM_LINEAR_ALIGNED)
|
||
|
|
{
|
||
|
|
expPitch *= 3;
|
||
|
|
}
|
||
|
|
|
||
|
|
return expPitch;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::IsMacroTiled
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Check if the tile mode is macro tiled
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* TRUE if it is macro tiled (2D/2B/3D/3B)
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
BOOL_32 AddrLib::IsMacroTiled(
|
||
|
|
AddrTileMode tileMode) ///< [in] tile mode
|
||
|
|
{
|
||
|
|
return m_modeFlags[tileMode].isMacro;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::IsMacro3dTiled
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Check if the tile mode is 3D macro tiled
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* TRUE if it is 3D macro tiled
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
BOOL_32 AddrLib::IsMacro3dTiled(
|
||
|
|
AddrTileMode tileMode) ///< [in] tile mode
|
||
|
|
{
|
||
|
|
return m_modeFlags[tileMode].isMacro3d;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::IsMicroTiled
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Check if the tile mode is micro tiled
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* TRUE if micro tiled
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
BOOL_32 AddrLib::IsMicroTiled(
|
||
|
|
AddrTileMode tileMode) ///< [in] tile mode
|
||
|
|
{
|
||
|
|
return m_modeFlags[tileMode].isMicro;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::IsLinear
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Check if the tile mode is linear
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* TRUE if linear
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
BOOL_32 AddrLib::IsLinear(
|
||
|
|
AddrTileMode tileMode) ///< [in] tile mode
|
||
|
|
{
|
||
|
|
return m_modeFlags[tileMode].isLinear;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::IsPrtNoRotationTileMode
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Return TRUE if it is prt tile without rotation
|
||
|
|
* @note
|
||
|
|
* This function just used by CI
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
BOOL_32 AddrLib::IsPrtNoRotationTileMode(
|
||
|
|
AddrTileMode tileMode)
|
||
|
|
{
|
||
|
|
return m_modeFlags[tileMode].isPrtNoRotation;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::IsPrtTileMode
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Return TRUE if it is prt tile
|
||
|
|
* @note
|
||
|
|
* This function just used by CI
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
BOOL_32 AddrLib::IsPrtTileMode(
|
||
|
|
AddrTileMode tileMode)
|
||
|
|
{
|
||
|
|
return m_modeFlags[tileMode].isPrt;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::Bits2Number
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Cat a array of binary bit to a number
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* The number combined with the array of bits
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
UINT_32 AddrLib::Bits2Number(
|
||
|
|
UINT_32 bitNum, ///< [in] how many bits
|
||
|
|
...) ///< [in] varaible bits value starting from MSB
|
||
|
|
{
|
||
|
|
UINT_32 number = 0;
|
||
|
|
UINT_32 i;
|
||
|
|
va_list bits_ptr;
|
||
|
|
|
||
|
|
va_start(bits_ptr, bitNum);
|
||
|
|
|
||
|
|
for(i = 0; i < bitNum; i++)
|
||
|
|
{
|
||
|
|
number |= va_arg(bits_ptr, UINT_32);
|
||
|
|
number <<= 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
number>>=1;
|
||
|
|
|
||
|
|
va_end(bits_ptr);
|
||
|
|
|
||
|
|
return number;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeMipLevel
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Compute mipmap level width/height/slices
|
||
|
|
* @return
|
||
|
|
* N/A
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
VOID AddrLib::ComputeMipLevel(
|
||
|
|
ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in/out] Input structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
if (AddrElemLib::IsBlockCompressed(pIn->format))
|
||
|
|
{
|
||
|
|
if (pIn->mipLevel == 0)
|
||
|
|
{
|
||
|
|
// DXTn's level 0 must be multiple of 4
|
||
|
|
// But there are exceptions:
|
||
|
|
// 1. Internal surface creation in hostblt/vsblt/etc...
|
||
|
|
// 2. Runtime doesn't reject ATI1/ATI2 whose width/height are not multiple of 4
|
||
|
|
pIn->width = PowTwoAlign(pIn->width, 4);
|
||
|
|
pIn->height = PowTwoAlign(pIn->height, 4);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
HwlComputeMipLevel(pIn);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::DegradeBaseLevel
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Check if base level's tile mode can be degraded
|
||
|
|
* @return
|
||
|
|
* TRUE if degraded, also returns degraded tile mode (unchanged if not degraded)
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
BOOL_32 AddrLib::DegradeBaseLevel(
|
||
|
|
const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure for surface info
|
||
|
|
AddrTileMode* pTileMode ///< [out] Degraded tile mode
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
BOOL_32 degraded = FALSE;
|
||
|
|
AddrTileMode tileMode = pIn->tileMode;
|
||
|
|
UINT_32 thickness = ComputeSurfaceThickness(tileMode);
|
||
|
|
|
||
|
|
if (m_configFlags.degradeBaseLevel) // This is a global setting
|
||
|
|
{
|
||
|
|
if (pIn->flags.degrade4Space && // Degradation per surface
|
||
|
|
pIn->mipLevel == 0 &&
|
||
|
|
pIn->numSamples == 1 &&
|
||
|
|
IsMacroTiled(tileMode))
|
||
|
|
{
|
||
|
|
if (HwlDegradeBaseLevel(pIn))
|
||
|
|
{
|
||
|
|
*pTileMode = thickness == 1 ? ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
|
||
|
|
degraded = TRUE;
|
||
|
|
}
|
||
|
|
else if (thickness > 1)
|
||
|
|
{
|
||
|
|
// As in the following HwlComputeSurfaceInfo, thick modes may be degraded to
|
||
|
|
// thinner modes, we should re-evaluate whether the corresponding thinner modes
|
||
|
|
// need to be degraded. If so, we choose 1D thick mode instead.
|
||
|
|
tileMode = DegradeLargeThickTile(pIn->tileMode, pIn->bpp);
|
||
|
|
if (tileMode != pIn->tileMode)
|
||
|
|
{
|
||
|
|
ADDR_COMPUTE_SURFACE_INFO_INPUT input = *pIn;
|
||
|
|
input.tileMode = tileMode;
|
||
|
|
if (HwlDegradeBaseLevel(&input))
|
||
|
|
{
|
||
|
|
*pTileMode = ADDR_TM_1D_TILED_THICK;
|
||
|
|
degraded = TRUE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return degraded;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::DegradeLargeThickTile
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Check if the thickness needs to be reduced if a tile is too large
|
||
|
|
* @return
|
||
|
|
* The degraded tile mode (unchanged if not degraded)
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
AddrTileMode AddrLib::DegradeLargeThickTile(
|
||
|
|
AddrTileMode tileMode,
|
||
|
|
UINT_32 bpp) const
|
||
|
|
{
|
||
|
|
// Override tilemode
|
||
|
|
// When tile_width (8) * tile_height (8) * thickness * element_bytes is > row_size,
|
||
|
|
// it is better to just use THIN mode in this case
|
||
|
|
UINT_32 thickness = ComputeSurfaceThickness(tileMode);
|
||
|
|
|
||
|
|
if (thickness > 1 && m_configFlags.allowLargeThickTile == 0)
|
||
|
|
{
|
||
|
|
UINT_32 tileSize = MicroTilePixels * thickness * (bpp >> 3);
|
||
|
|
|
||
|
|
if (tileSize > m_rowSize)
|
||
|
|
{
|
||
|
|
switch (tileMode)
|
||
|
|
{
|
||
|
|
case ADDR_TM_2D_TILED_XTHICK:
|
||
|
|
if ((tileSize >> 1) <= m_rowSize)
|
||
|
|
{
|
||
|
|
tileMode = ADDR_TM_2D_TILED_THICK;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
// else fall through
|
||
|
|
case ADDR_TM_2D_TILED_THICK:
|
||
|
|
tileMode = ADDR_TM_2D_TILED_THIN1;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case ADDR_TM_3D_TILED_XTHICK:
|
||
|
|
if ((tileSize >> 1) <= m_rowSize)
|
||
|
|
{
|
||
|
|
tileMode = ADDR_TM_3D_TILED_THICK;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
// else fall through
|
||
|
|
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;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return tileMode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::PostComputeMipLevel
|
||
|
|
* @brief
|
||
|
|
* Compute MipLevel info (including level 0) after surface adjustment
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::PostComputeMipLevel(
|
||
|
|
ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in/out] Input structure
|
||
|
|
ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] Output structure
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
// Mipmap including level 0 must be pow2 padded since either SI hw expects so or it is
|
||
|
|
// required by CFX for Hw Compatibility between NI and SI. Otherwise it is only needed for
|
||
|
|
// mipLevel > 0. Any h/w has different requirement should implement its own virtual function
|
||
|
|
|
||
|
|
if (pIn->flags.pow2Pad)
|
||
|
|
{
|
||
|
|
pIn->width = NextPow2(pIn->width);
|
||
|
|
pIn->height = NextPow2(pIn->height);
|
||
|
|
pIn->numSlices = NextPow2(pIn->numSlices);
|
||
|
|
}
|
||
|
|
else if (pIn->mipLevel > 0)
|
||
|
|
{
|
||
|
|
pIn->width = NextPow2(pIn->width);
|
||
|
|
pIn->height = NextPow2(pIn->height);
|
||
|
|
|
||
|
|
if (!pIn->flags.cube)
|
||
|
|
{
|
||
|
|
pIn->numSlices = NextPow2(pIn->numSlices);
|
||
|
|
}
|
||
|
|
|
||
|
|
// for cubemap, we keep its value at first
|
||
|
|
}
|
||
|
|
|
||
|
|
return ADDR_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::HwlSetupTileCfg
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Map tile index to tile setting.
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::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
|
||
|
|
{
|
||
|
|
return ADDR_NOTSUPPORTED;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::HwlGetPipes
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Get number pipes
|
||
|
|
* @return
|
||
|
|
* num pipes
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
UINT_32 AddrLib::HwlGetPipes(
|
||
|
|
const ADDR_TILEINFO* pTileInfo ///< [in] Tile info
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
//pTileInfo can be NULL when asic is 6xx and 8xx.
|
||
|
|
return m_pipes;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputeQbStereoInfo
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Get quad buffer stereo information
|
||
|
|
* @return
|
||
|
|
* TRUE if no error
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
BOOL_32 AddrLib::ComputeQbStereoInfo(
|
||
|
|
ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in/out] updated pOut+pStereoInfo
|
||
|
|
) const
|
||
|
|
{
|
||
|
|
BOOL_32 success = FALSE;
|
||
|
|
|
||
|
|
if (pOut->pStereoInfo)
|
||
|
|
{
|
||
|
|
ADDR_ASSERT(pOut->bpp >= 8);
|
||
|
|
ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0);
|
||
|
|
|
||
|
|
// Save original height
|
||
|
|
pOut->pStereoInfo->eyeHeight = pOut->height;
|
||
|
|
|
||
|
|
// Right offset
|
||
|
|
pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize);
|
||
|
|
|
||
|
|
pOut->pStereoInfo->rightSwizzle = HwlComputeQbStereoRightSwizzle(pOut);
|
||
|
|
// Double height
|
||
|
|
pOut->height <<= 1;
|
||
|
|
pOut->pixelHeight <<= 1;
|
||
|
|
|
||
|
|
// Double size
|
||
|
|
pOut->surfSize <<= 1;
|
||
|
|
|
||
|
|
// Right start address meets the base align since it is guaranteed by AddrLib
|
||
|
|
|
||
|
|
// 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo.
|
||
|
|
success = TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return success;
|
||
|
|
}
|
||
|
|
|
||
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
// Element lib
|
||
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::Flt32ToColorPixel
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Convert a FLT_32 value to a depth/stencil pixel value
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::Flt32ToDepthPixel(
|
||
|
|
const ELEM_FLT32TODEPTHPIXEL_INPUT* pIn,
|
||
|
|
ELEM_FLT32TODEPTHPIXEL_OUTPUT* pOut) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ELEM_FLT32TODEPTHPIXEL_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ELEM_FLT32TODEPTHPIXEL_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
GetElemLib()->Flt32ToDepthPixel(pIn->format,
|
||
|
|
pIn->comps,
|
||
|
|
pOut->pPixel);
|
||
|
|
UINT_32 depthBase = 0;
|
||
|
|
UINT_32 stencilBase = 0;
|
||
|
|
UINT_32 depthBits = 0;
|
||
|
|
UINT_32 stencilBits = 0;
|
||
|
|
|
||
|
|
switch (pIn->format)
|
||
|
|
{
|
||
|
|
case ADDR_DEPTH_16:
|
||
|
|
depthBits = 16;
|
||
|
|
break;
|
||
|
|
case ADDR_DEPTH_X8_24:
|
||
|
|
case ADDR_DEPTH_8_24:
|
||
|
|
case ADDR_DEPTH_X8_24_FLOAT:
|
||
|
|
case ADDR_DEPTH_8_24_FLOAT:
|
||
|
|
depthBase = 8;
|
||
|
|
depthBits = 24;
|
||
|
|
stencilBits = 8;
|
||
|
|
break;
|
||
|
|
case ADDR_DEPTH_32_FLOAT:
|
||
|
|
depthBits = 32;
|
||
|
|
break;
|
||
|
|
case ADDR_DEPTH_X24_8_32_FLOAT:
|
||
|
|
depthBase = 8;
|
||
|
|
depthBits = 32;
|
||
|
|
stencilBits = 8;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Overwrite base since R800 has no "tileBase"
|
||
|
|
if (GetElemLib()->IsDepthStencilTilePlanar() == FALSE)
|
||
|
|
{
|
||
|
|
depthBase = 0;
|
||
|
|
stencilBase = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
depthBase *= 64;
|
||
|
|
stencilBase *= 64;
|
||
|
|
|
||
|
|
pOut->stencilBase = stencilBase;
|
||
|
|
pOut->depthBase = depthBase;
|
||
|
|
pOut->depthBits = depthBits;
|
||
|
|
pOut->stencilBits = stencilBits;
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::Flt32ToColorPixel
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Convert a FLT_32 value to a red/green/blue/alpha pixel value
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::Flt32ToColorPixel(
|
||
|
|
const ELEM_FLT32TOCOLORPIXEL_INPUT* pIn,
|
||
|
|
ELEM_FLT32TOCOLORPIXEL_OUTPUT* pOut) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if ((pIn->size != sizeof(ELEM_FLT32TOCOLORPIXEL_INPUT)) ||
|
||
|
|
(pOut->size != sizeof(ELEM_FLT32TOCOLORPIXEL_OUTPUT)))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
GetElemLib()->Flt32ToColorPixel(pIn->format,
|
||
|
|
pIn->surfNum,
|
||
|
|
pIn->surfSwap,
|
||
|
|
pIn->comps,
|
||
|
|
pOut->pPixel);
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::GetExportNorm
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Check one format can be EXPORT_NUM
|
||
|
|
* @return
|
||
|
|
* TRUE if EXPORT_NORM can be used
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
BOOL_32 AddrLib::GetExportNorm(
|
||
|
|
const ELEM_GETEXPORTNORM_INPUT* pIn) const
|
||
|
|
{
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
BOOL_32 enabled = FALSE;
|
||
|
|
|
||
|
|
if (GetFillSizeFieldsFlags() == TRUE)
|
||
|
|
{
|
||
|
|
if (pIn->size != sizeof(ELEM_GETEXPORTNORM_INPUT))
|
||
|
|
{
|
||
|
|
returnCode = ADDR_PARAMSIZEMISMATCH;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
enabled = GetElemLib()->PixGetExportNorm(pIn->format,
|
||
|
|
pIn->num,
|
||
|
|
pIn->swap);
|
||
|
|
}
|
||
|
|
|
||
|
|
return enabled;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
***************************************************************************************************
|
||
|
|
* AddrLib::ComputePrtInfo
|
||
|
|
*
|
||
|
|
* @brief
|
||
|
|
* Compute prt surface related info
|
||
|
|
*
|
||
|
|
* @return
|
||
|
|
* ADDR_E_RETURNCODE
|
||
|
|
***************************************************************************************************
|
||
|
|
*/
|
||
|
|
ADDR_E_RETURNCODE AddrLib::ComputePrtInfo(
|
||
|
|
const ADDR_PRT_INFO_INPUT* pIn,
|
||
|
|
ADDR_PRT_INFO_OUTPUT* pOut) const
|
||
|
|
{
|
||
|
|
ADDR_ASSERT(pOut != NULL);
|
||
|
|
|
||
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
||
|
|
|
||
|
|
UINT_32 expandX = 1;
|
||
|
|
UINT_32 expandY = 1;
|
||
|
|
AddrElemMode elemMode;
|
||
|
|
|
||
|
|
UINT_32 bpp = GetElemLib()->GetBitsPerPixel(pIn->format,
|
||
|
|
&elemMode,
|
||
|
|
&expandX,
|
||
|
|
&expandY);
|
||
|
|
|
||
|
|
if (bpp <8 || bpp == 24 || bpp == 48 || bpp == 96 )
|
||
|
|
{
|
||
|
|
returnCode = ADDR_INVALIDPARAMS;
|
||
|
|
}
|
||
|
|
|
||
|
|
UINT_32 numFrags = pIn->numFrags;
|
||
|
|
ADDR_ASSERT(numFrags <= 8);
|
||
|
|
|
||
|
|
UINT_32 tileWidth = 0;
|
||
|
|
UINT_32 tileHeight = 0;
|
||
|
|
if (returnCode == ADDR_OK)
|
||
|
|
{
|
||
|
|
// 3D texture without depth or 2d texture
|
||
|
|
if (pIn->baseMipDepth > 1 || pIn->baseMipHeight > 1)
|
||
|
|
{
|
||
|
|
if (bpp == 8)
|
||
|
|
{
|
||
|
|
tileWidth = 256;
|
||
|
|
tileHeight = 256;
|
||
|
|
}
|
||
|
|
else if (bpp == 16)
|
||
|
|
{
|
||
|
|
tileWidth = 256;
|
||
|
|
tileHeight = 128;
|
||
|
|
}
|
||
|
|
else if (bpp == 32)
|
||
|
|
{
|
||
|
|
tileWidth = 128;
|
||
|
|
tileHeight = 128;
|
||
|
|
}
|
||
|
|
else if (bpp == 64)
|
||
|
|
{
|
||
|
|
// assume it is BC1/4
|
||
|
|
tileWidth = 512;
|
||
|
|
tileHeight = 256;
|
||
|
|
|
||
|
|
if (elemMode == ADDR_UNCOMPRESSED)
|
||
|
|
{
|
||
|
|
tileWidth = 128;
|
||
|
|
tileHeight = 64;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (bpp == 128)
|
||
|
|
{
|
||
|
|
// assume it is BC2/3/5/6H/7
|
||
|
|
tileWidth = 256;
|
||
|
|
tileHeight = 256;
|
||
|
|
|
||
|
|
if (elemMode == ADDR_UNCOMPRESSED)
|
||
|
|
{
|
||
|
|
tileWidth = 64;
|
||
|
|
tileHeight = 64;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (numFrags == 2)
|
||
|
|
{
|
||
|
|
tileWidth = tileWidth / 2;
|
||
|
|
}
|
||
|
|
else if (numFrags == 4)
|
||
|
|
{
|
||
|
|
tileWidth = tileWidth / 2;
|
||
|
|
tileHeight = tileHeight / 2;
|
||
|
|
}
|
||
|
|
else if (numFrags == 8)
|
||
|
|
{
|
||
|
|
tileWidth = tileWidth / 4;
|
||
|
|
tileHeight = tileHeight / 2;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else // 1d
|
||
|
|
{
|
||
|
|
tileHeight = 1;
|
||
|
|
if (bpp == 8)
|
||
|
|
{
|
||
|
|
tileWidth = 65536;
|
||
|
|
}
|
||
|
|
else if (bpp == 16)
|
||
|
|
{
|
||
|
|
tileWidth = 32768;
|
||
|
|
}
|
||
|
|
else if (bpp == 32)
|
||
|
|
{
|
||
|
|
tileWidth = 16384;
|
||
|
|
}
|
||
|
|
else if (bpp == 64)
|
||
|
|
{
|
||
|
|
tileWidth = 8192;
|
||
|
|
}
|
||
|
|
else if (bpp == 128)
|
||
|
|
{
|
||
|
|
tileWidth = 4096;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
pOut->prtTileWidth = tileWidth;
|
||
|
|
pOut->prtTileHeight = tileHeight;
|
||
|
|
|
||
|
|
return returnCode;
|
||
|
|
}
|