2016-10-06 18:55:25 +02:00
|
|
|
/*
|
|
|
|
|
* Copyright © 2017 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.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* @file gfx9addrlib.cpp
|
|
|
|
|
* @brief Contgfx9ns the implementation for the Gfx9Lib class.
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "gfx9addrlib.h"
|
|
|
|
|
|
|
|
|
|
#include "gfx9_gb_reg.h"
|
|
|
|
|
#include "gfx9_enum.h"
|
|
|
|
|
|
|
|
|
|
#if BRAHMA_BUILD
|
|
|
|
|
#include "amdgpu_id.h"
|
|
|
|
|
#else
|
|
|
|
|
#include "ai_id.h"
|
|
|
|
|
#include "rv_id.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
namespace Addr
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9HwlInit
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Creates an Gfx9Lib object.
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* Returns an Gfx9Lib object pointer.
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
Addr::Lib* Gfx9HwlInit(const Client* pClient)
|
|
|
|
|
{
|
|
|
|
|
return V2::Gfx9Lib::CreateObj(pClient);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace V2
|
|
|
|
|
{
|
|
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Static Const Member
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
const SwizzleModeFlags Gfx9Lib::SwizzleModeTable[ADDR_SW_MAX_TYPE] =
|
|
|
|
|
{//Linear 256B 4KB 64KB Var Z Std Disp Rot XOR T RtOpt
|
|
|
|
|
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // ADDR_SW_LINEAR
|
|
|
|
|
{0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, // ADDR_SW_256B_S
|
|
|
|
|
{0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, // ADDR_SW_256B_D
|
|
|
|
|
{0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, // ADDR_SW_256B_R
|
|
|
|
|
|
|
|
|
|
{0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0}, // ADDR_SW_4KB_Z
|
|
|
|
|
{0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0}, // ADDR_SW_4KB_S
|
|
|
|
|
{0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}, // ADDR_SW_4KB_D
|
|
|
|
|
{0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0}, // ADDR_SW_4KB_R
|
|
|
|
|
|
|
|
|
|
{0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0}, // ADDR_SW_64KB_Z
|
|
|
|
|
{0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0}, // ADDR_SW_64KB_S
|
|
|
|
|
{0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0}, // ADDR_SW_64KB_D
|
|
|
|
|
{0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0}, // ADDR_SW_64KB_R
|
|
|
|
|
|
|
|
|
|
{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_SW_VAR_Z
|
|
|
|
|
{0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0}, // ADDR_SW_VAR_S
|
|
|
|
|
{0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_SW_VAR_D
|
|
|
|
|
{0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, // ADDR_SW_VAR_R
|
|
|
|
|
|
|
|
|
|
{0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0}, // ADDR_SW_64KB_Z_T
|
|
|
|
|
{0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0}, // ADDR_SW_64KB_S_T
|
|
|
|
|
{0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0}, // ADDR_SW_64KB_D_T
|
|
|
|
|
{0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0}, // ADDR_SW_64KB_R_T
|
|
|
|
|
|
|
|
|
|
{0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0}, // ADDR_SW_4KB_Z_x
|
|
|
|
|
{0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0}, // ADDR_SW_4KB_S_x
|
|
|
|
|
{0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0}, // ADDR_SW_4KB_D_x
|
|
|
|
|
{0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0}, // ADDR_SW_4KB_R_x
|
|
|
|
|
|
|
|
|
|
{0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0}, // ADDR_SW_64KB_Z_X
|
|
|
|
|
{0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, // ADDR_SW_64KB_S_X
|
|
|
|
|
{0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0}, // ADDR_SW_64KB_D_X
|
|
|
|
|
{0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0}, // ADDR_SW_64KB_R_X
|
|
|
|
|
|
|
|
|
|
{0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0}, // ADDR_SW_VAR_Z_X
|
|
|
|
|
{0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0}, // ADDR_SW_VAR_S_X
|
|
|
|
|
{0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0}, // ADDR_SW_VAR_D_X
|
|
|
|
|
{0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0}, // ADDR_SW_VAR_R_X
|
|
|
|
|
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // ADDR_SW_LINEAR_GENERAL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const UINT_32 Gfx9Lib::MipTailOffset256B[] = {2048, 1024, 512, 256, 128, 64, 32, 16,
|
|
|
|
|
8, 6, 5, 4, 3, 2, 1, 0};
|
|
|
|
|
|
|
|
|
|
const Dim3d Gfx9Lib::Block256_3dS[] = {{16, 4, 4}, {8, 4, 4}, {4, 4, 4}, {2, 4, 4}, {1, 4, 4}};
|
|
|
|
|
|
|
|
|
|
const Dim3d Gfx9Lib::Block256_3dZ[] = {{8, 4, 8}, {4, 4, 8}, {4, 4, 4}, {4, 2, 4}, {2, 2, 4}};
|
|
|
|
|
|
2016-10-06 18:55:25 +02:00
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::Gfx9Lib
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Constructor
|
|
|
|
|
*
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
Gfx9Lib::Gfx9Lib(const Client* pClient)
|
|
|
|
|
:
|
|
|
|
|
Lib(pClient),
|
|
|
|
|
m_numEquations(0)
|
|
|
|
|
{
|
|
|
|
|
m_class = AI_ADDRLIB;
|
|
|
|
|
memset(&m_settings, 0, sizeof(m_settings));
|
2017-02-27 22:25:44 +01:00
|
|
|
memcpy(m_swizzleModeTable, SwizzleModeTable, sizeof(SwizzleModeTable));
|
2016-10-06 18:55:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::~Gfx9Lib
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Destructor
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
Gfx9Lib::~Gfx9Lib()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::HwlComputeHtileInfo
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Interface function stub of AddrComputeHtilenfo
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* ADDR_E_RETURNCODE
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileInfo(
|
|
|
|
|
const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn, ///< [in] input structure
|
|
|
|
|
ADDR2_COMPUTE_HTILE_INFO_OUTPUT* pOut ///< [out] output structure
|
|
|
|
|
) const
|
|
|
|
|
{
|
|
|
|
|
UINT_32 numPipeTotal = GetPipeNumForMetaAddressing(pIn->hTileFlags.pipeAligned,
|
|
|
|
|
pIn->swizzleMode);
|
|
|
|
|
|
|
|
|
|
UINT_32 numRbTotal = pIn->hTileFlags.rbAligned ? m_se * m_rbPerSe : 1;
|
|
|
|
|
|
|
|
|
|
UINT_32 numCompressBlkPerMetaBlk, numCompressBlkPerMetaBlkLog2;
|
|
|
|
|
|
|
|
|
|
if ((numPipeTotal == 1) && (numRbTotal == 1))
|
|
|
|
|
{
|
|
|
|
|
numCompressBlkPerMetaBlkLog2 = 10;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
numCompressBlkPerMetaBlkLog2 = m_seLog2 + m_rbPerSeLog2 + 10;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
numCompressBlkPerMetaBlk = 1 << numCompressBlkPerMetaBlkLog2;
|
|
|
|
|
|
|
|
|
|
Dim3d metaBlkDim = {8, 8, 1};
|
|
|
|
|
UINT_32 totalAmpBits = numCompressBlkPerMetaBlkLog2;
|
|
|
|
|
UINT_32 widthAmp = (pIn->numMipLevels > 1) ? (totalAmpBits >> 1) : RoundHalf(totalAmpBits);
|
|
|
|
|
UINT_32 heightAmp = totalAmpBits - widthAmp;
|
|
|
|
|
metaBlkDim.w <<= widthAmp;
|
|
|
|
|
metaBlkDim.h <<= heightAmp;
|
|
|
|
|
|
|
|
|
|
#if DEBUG
|
|
|
|
|
Dim3d metaBlkDimDbg = {8, 8, 1};
|
|
|
|
|
for (UINT_32 index = 0; index < numCompressBlkPerMetaBlkLog2; index++)
|
|
|
|
|
{
|
|
|
|
|
if ((metaBlkDimDbg.h < metaBlkDimDbg.w) ||
|
|
|
|
|
((pIn->numMipLevels > 1) && (metaBlkDimDbg.h == metaBlkDimDbg.w)))
|
|
|
|
|
{
|
|
|
|
|
metaBlkDimDbg.h <<= 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
metaBlkDimDbg.w <<= 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ADDR_ASSERT((metaBlkDimDbg.w == metaBlkDim.w) && (metaBlkDimDbg.h == metaBlkDim.h));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
UINT_32 numMetaBlkX;
|
|
|
|
|
UINT_32 numMetaBlkY;
|
|
|
|
|
UINT_32 numMetaBlkZ;
|
|
|
|
|
|
|
|
|
|
GetMetaMipInfo(pIn->numMipLevels, &metaBlkDim, FALSE, pOut->pMipInfo,
|
|
|
|
|
pIn->unalignedWidth, pIn->unalignedHeight, pIn->numSlices,
|
|
|
|
|
&numMetaBlkX, &numMetaBlkY, &numMetaBlkZ);
|
|
|
|
|
|
|
|
|
|
UINT_32 sizeAlign = numPipeTotal * numRbTotal * m_pipeInterleaveBytes;
|
|
|
|
|
|
|
|
|
|
pOut->pitch = numMetaBlkX * metaBlkDim.w;
|
|
|
|
|
pOut->height = numMetaBlkY * metaBlkDim.h;
|
|
|
|
|
pOut->sliceSize = numMetaBlkX * numMetaBlkY * numCompressBlkPerMetaBlk * 4;
|
|
|
|
|
|
|
|
|
|
pOut->metaBlkWidth = metaBlkDim.w;
|
|
|
|
|
pOut->metaBlkHeight = metaBlkDim.h;
|
|
|
|
|
pOut->metaBlkNumPerSlice = numMetaBlkX * numMetaBlkY;
|
|
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
pOut->baseAlign = Max(numCompressBlkPerMetaBlk * 4, sizeAlign);
|
|
|
|
|
|
|
|
|
|
if (m_settings.metaBaseAlignFix)
|
|
|
|
|
{
|
|
|
|
|
pOut->baseAlign = Max(pOut->baseAlign, GetBlockSize(pIn->swizzleMode));
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-06 18:55:25 +02:00
|
|
|
if ((IsXor(pIn->swizzleMode) == FALSE) && (numPipeTotal > 2))
|
|
|
|
|
{
|
|
|
|
|
UINT_32 additionalAlign = numPipeTotal * numCompressBlkPerMetaBlk * 2;
|
|
|
|
|
|
|
|
|
|
if (additionalAlign > sizeAlign)
|
|
|
|
|
{
|
|
|
|
|
sizeAlign = additionalAlign;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pOut->htileBytes = PowTwoAlign(pOut->sliceSize * numMetaBlkZ, sizeAlign);
|
|
|
|
|
|
|
|
|
|
return ADDR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::HwlComputeCmaskInfo
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Interface function stub of AddrComputeCmaskInfo
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* ADDR_E_RETURNCODE
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskInfo(
|
|
|
|
|
const ADDR2_COMPUTE_CMASK_INFO_INPUT* pIn, ///< [in] input structure
|
|
|
|
|
ADDR2_COMPUTE_CMASK_INFO_OUTPUT* pOut ///< [out] output structure
|
|
|
|
|
) const
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT(pIn->resourceType == ADDR_RSRC_TEX_2D);
|
|
|
|
|
|
|
|
|
|
UINT_32 numPipeTotal = GetPipeNumForMetaAddressing(pIn->cMaskFlags.pipeAligned,
|
|
|
|
|
pIn->swizzleMode);
|
|
|
|
|
|
|
|
|
|
UINT_32 numRbTotal = pIn->cMaskFlags.rbAligned ? m_se * m_rbPerSe : 1;
|
|
|
|
|
|
|
|
|
|
UINT_32 numCompressBlkPerMetaBlkLog2, numCompressBlkPerMetaBlk;
|
|
|
|
|
|
|
|
|
|
if ((numPipeTotal == 1) && (numRbTotal == 1))
|
|
|
|
|
{
|
|
|
|
|
numCompressBlkPerMetaBlkLog2 = 13;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
numCompressBlkPerMetaBlkLog2 = m_seLog2 + m_rbPerSeLog2 + 10;
|
|
|
|
|
|
|
|
|
|
numCompressBlkPerMetaBlkLog2 = Max(numCompressBlkPerMetaBlkLog2, 13u);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
numCompressBlkPerMetaBlk = 1 << numCompressBlkPerMetaBlkLog2;
|
|
|
|
|
|
|
|
|
|
Dim2d metaBlkDim = {8, 8};
|
|
|
|
|
UINT_32 totalAmpBits = numCompressBlkPerMetaBlkLog2;
|
|
|
|
|
UINT_32 heightAmp = totalAmpBits >> 1;
|
|
|
|
|
UINT_32 widthAmp = totalAmpBits - heightAmp;
|
|
|
|
|
metaBlkDim.w <<= widthAmp;
|
|
|
|
|
metaBlkDim.h <<= heightAmp;
|
|
|
|
|
|
|
|
|
|
#if DEBUG
|
|
|
|
|
Dim2d metaBlkDimDbg = {8, 8};
|
|
|
|
|
for (UINT_32 index = 0; index < numCompressBlkPerMetaBlkLog2; index++)
|
|
|
|
|
{
|
|
|
|
|
if (metaBlkDimDbg.h < metaBlkDimDbg.w)
|
|
|
|
|
{
|
|
|
|
|
metaBlkDimDbg.h <<= 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
metaBlkDimDbg.w <<= 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ADDR_ASSERT((metaBlkDimDbg.w == metaBlkDim.w) && (metaBlkDimDbg.h == metaBlkDim.h));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
UINT_32 numMetaBlkX = (pIn->unalignedWidth + metaBlkDim.w - 1) / metaBlkDim.w;
|
|
|
|
|
UINT_32 numMetaBlkY = (pIn->unalignedHeight + metaBlkDim.h - 1) / metaBlkDim.h;
|
|
|
|
|
UINT_32 numMetaBlkZ = Max(pIn->numSlices, 1u);
|
|
|
|
|
|
|
|
|
|
UINT_32 sizeAlign = numPipeTotal * numRbTotal * m_pipeInterleaveBytes;
|
|
|
|
|
|
|
|
|
|
pOut->pitch = numMetaBlkX * metaBlkDim.w;
|
|
|
|
|
pOut->height = numMetaBlkY * metaBlkDim.h;
|
|
|
|
|
pOut->sliceSize = (numMetaBlkX * numMetaBlkY * numCompressBlkPerMetaBlk) >> 1;
|
|
|
|
|
pOut->cmaskBytes = PowTwoAlign(pOut->sliceSize * numMetaBlkZ, sizeAlign);
|
|
|
|
|
pOut->baseAlign = Max(numCompressBlkPerMetaBlk >> 1, sizeAlign);
|
|
|
|
|
|
|
|
|
|
if (m_settings.metaBaseAlignFix)
|
|
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
pOut->baseAlign = Max(pOut->baseAlign, GetBlockSize(pIn->swizzleMode));
|
2016-10-06 18:55:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pOut->metaBlkWidth = metaBlkDim.w;
|
|
|
|
|
pOut->metaBlkHeight = metaBlkDim.h;
|
|
|
|
|
|
|
|
|
|
pOut->metaBlkNumPerSlice = numMetaBlkX * numMetaBlkY;
|
|
|
|
|
|
|
|
|
|
return ADDR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::GetMetaMipInfo
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Get meta mip info
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* N/A
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
VOID Gfx9Lib::GetMetaMipInfo(
|
|
|
|
|
UINT_32 numMipLevels, ///< [in] number of mip levels
|
|
|
|
|
Dim3d* pMetaBlkDim, ///< [in] meta block dimension
|
|
|
|
|
BOOL_32 dataThick, ///< [in] data surface is thick
|
|
|
|
|
ADDR2_META_MIP_INFO* pInfo, ///< [out] meta mip info
|
|
|
|
|
UINT_32 mip0Width, ///< [in] mip0 width
|
|
|
|
|
UINT_32 mip0Height, ///< [in] mip0 height
|
|
|
|
|
UINT_32 mip0Depth, ///< [in] mip0 depth
|
|
|
|
|
UINT_32* pNumMetaBlkX, ///< [out] number of metablock X in mipchain
|
|
|
|
|
UINT_32* pNumMetaBlkY, ///< [out] number of metablock Y in mipchain
|
|
|
|
|
UINT_32* pNumMetaBlkZ) ///< [out] number of metablock Z in mipchain
|
|
|
|
|
const
|
|
|
|
|
{
|
|
|
|
|
UINT_32 numMetaBlkX = (mip0Width + pMetaBlkDim->w - 1) / pMetaBlkDim->w;
|
|
|
|
|
UINT_32 numMetaBlkY = (mip0Height + pMetaBlkDim->h - 1) / pMetaBlkDim->h;
|
|
|
|
|
UINT_32 numMetaBlkZ = (mip0Depth + pMetaBlkDim->d - 1) / pMetaBlkDim->d;
|
|
|
|
|
UINT_32 tailWidth = pMetaBlkDim->w;
|
|
|
|
|
UINT_32 tailHeight = pMetaBlkDim->h >> 1;
|
|
|
|
|
UINT_32 tailDepth = pMetaBlkDim->d;
|
|
|
|
|
BOOL_32 inTail = FALSE;
|
|
|
|
|
AddrMajorMode major = ADDR_MAJOR_MAX_TYPE;
|
|
|
|
|
|
|
|
|
|
if (numMipLevels > 1)
|
|
|
|
|
{
|
|
|
|
|
if (dataThick && (numMetaBlkZ > numMetaBlkX) && (numMetaBlkZ > numMetaBlkY))
|
|
|
|
|
{
|
|
|
|
|
// Z major
|
|
|
|
|
major = ADDR_MAJOR_Z;
|
|
|
|
|
}
|
|
|
|
|
else if (numMetaBlkX >= numMetaBlkY)
|
|
|
|
|
{
|
|
|
|
|
// X major
|
|
|
|
|
major = ADDR_MAJOR_X;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Y major
|
|
|
|
|
major = ADDR_MAJOR_Y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inTail = ((mip0Width <= tailWidth) &&
|
|
|
|
|
(mip0Height <= tailHeight) &&
|
|
|
|
|
((dataThick == FALSE) || (mip0Depth <= tailDepth)));
|
|
|
|
|
|
|
|
|
|
if (inTail == FALSE)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 orderLimit;
|
|
|
|
|
UINT_32 *pMipDim;
|
|
|
|
|
UINT_32 *pOrderDim;
|
|
|
|
|
|
|
|
|
|
if (major == ADDR_MAJOR_Z)
|
|
|
|
|
{
|
|
|
|
|
// Z major
|
|
|
|
|
pMipDim = &numMetaBlkY;
|
|
|
|
|
pOrderDim = &numMetaBlkZ;
|
|
|
|
|
orderLimit = 4;
|
|
|
|
|
}
|
|
|
|
|
else if (major == ADDR_MAJOR_X)
|
|
|
|
|
{
|
|
|
|
|
// X major
|
|
|
|
|
pMipDim = &numMetaBlkY;
|
|
|
|
|
pOrderDim = &numMetaBlkX;
|
|
|
|
|
orderLimit = 4;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Y major
|
|
|
|
|
pMipDim = &numMetaBlkX;
|
|
|
|
|
pOrderDim = &numMetaBlkY;
|
|
|
|
|
orderLimit = 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((*pMipDim < 3) && (*pOrderDim > orderLimit) && (numMipLevels > 3))
|
|
|
|
|
{
|
|
|
|
|
*pMipDim += 2;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
*pMipDim += ((*pMipDim / 2) + (*pMipDim & 1));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pInfo != NULL)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 mipWidth = mip0Width;
|
|
|
|
|
UINT_32 mipHeight = mip0Height;
|
|
|
|
|
UINT_32 mipDepth = mip0Depth;
|
|
|
|
|
Dim3d mipCoord = {0};
|
|
|
|
|
|
|
|
|
|
for (UINT_32 mip = 0; mip < numMipLevels; mip++)
|
|
|
|
|
{
|
|
|
|
|
if (inTail)
|
|
|
|
|
{
|
|
|
|
|
GetMetaMiptailInfo(&pInfo[mip], mipCoord, numMipLevels - mip,
|
|
|
|
|
pMetaBlkDim);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mipWidth = PowTwoAlign(mipWidth, pMetaBlkDim->w);
|
|
|
|
|
mipHeight = PowTwoAlign(mipHeight, pMetaBlkDim->h);
|
|
|
|
|
mipDepth = PowTwoAlign(mipDepth, pMetaBlkDim->d);
|
|
|
|
|
|
|
|
|
|
pInfo[mip].inMiptail = FALSE;
|
|
|
|
|
pInfo[mip].startX = mipCoord.w;
|
|
|
|
|
pInfo[mip].startY = mipCoord.h;
|
|
|
|
|
pInfo[mip].startZ = mipCoord.d;
|
|
|
|
|
pInfo[mip].width = mipWidth;
|
|
|
|
|
pInfo[mip].height = mipHeight;
|
|
|
|
|
pInfo[mip].depth = dataThick ? mipDepth : 1;
|
|
|
|
|
|
|
|
|
|
if ((mip >= 3) || (mip & 1))
|
|
|
|
|
{
|
|
|
|
|
switch (major)
|
|
|
|
|
{
|
|
|
|
|
case ADDR_MAJOR_X:
|
|
|
|
|
mipCoord.w += mipWidth;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_MAJOR_Y:
|
|
|
|
|
mipCoord.h += mipHeight;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_MAJOR_Z:
|
|
|
|
|
mipCoord.d += mipDepth;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
switch (major)
|
|
|
|
|
{
|
|
|
|
|
case ADDR_MAJOR_X:
|
|
|
|
|
mipCoord.h += mipHeight;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_MAJOR_Y:
|
|
|
|
|
mipCoord.w += mipWidth;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_MAJOR_Z:
|
|
|
|
|
mipCoord.h += mipHeight;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mipWidth = Max(mipWidth >> 1, 1u);
|
|
|
|
|
mipHeight = Max(mipHeight >> 1, 1u);
|
|
|
|
|
mipDepth = Max(mipDepth >> 1, 1u);
|
|
|
|
|
|
|
|
|
|
inTail = ((mipWidth <= tailWidth) &&
|
|
|
|
|
(mipHeight <= tailHeight) &&
|
|
|
|
|
((dataThick == FALSE) || (mipDepth <= tailDepth)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*pNumMetaBlkX = numMetaBlkX;
|
|
|
|
|
*pNumMetaBlkY = numMetaBlkY;
|
|
|
|
|
*pNumMetaBlkZ = numMetaBlkZ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::HwlComputeDccInfo
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Interface function to compute DCC key info
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* ADDR_E_RETURNCODE
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputeDccInfo(
|
|
|
|
|
const ADDR2_COMPUTE_DCCINFO_INPUT* pIn, ///< [in] input structure
|
|
|
|
|
ADDR2_COMPUTE_DCCINFO_OUTPUT* pOut ///< [out] output structure
|
|
|
|
|
) const
|
|
|
|
|
{
|
|
|
|
|
BOOL_32 dataLinear = IsLinear(pIn->swizzleMode);
|
|
|
|
|
BOOL_32 metaLinear = pIn->dccKeyFlags.linear;
|
|
|
|
|
BOOL_32 pipeAligned = pIn->dccKeyFlags.pipeAligned;
|
|
|
|
|
|
|
|
|
|
if (dataLinear)
|
|
|
|
|
{
|
|
|
|
|
metaLinear = TRUE;
|
|
|
|
|
}
|
|
|
|
|
else if (metaLinear == TRUE)
|
|
|
|
|
{
|
|
|
|
|
pipeAligned = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UINT_32 numPipeTotal = GetPipeNumForMetaAddressing(pipeAligned, pIn->swizzleMode);
|
|
|
|
|
|
|
|
|
|
if (metaLinear)
|
|
|
|
|
{
|
|
|
|
|
// Linear metadata supporting was removed for GFX9! No one can use this feature on GFX9.
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
|
|
|
|
|
pOut->dccRamBaseAlign = numPipeTotal * m_pipeInterleaveBytes;
|
|
|
|
|
pOut->dccRamSize = PowTwoAlign((pIn->dataSurfaceSize / 256), pOut->dccRamBaseAlign);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
BOOL_32 dataThick = IsThick(pIn->resourceType, pIn->swizzleMode);
|
|
|
|
|
|
|
|
|
|
UINT_32 minMetaBlkSize = dataThick ? 65536 : 4096;
|
|
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 numFrags = Max(pIn->numFrags, 1u);
|
|
|
|
|
UINT_32 numSlices = Max(pIn->numSlices, 1u);
|
2016-10-06 18:55:25 +02:00
|
|
|
|
|
|
|
|
minMetaBlkSize /= numFrags;
|
|
|
|
|
|
|
|
|
|
UINT_32 numCompressBlkPerMetaBlk = minMetaBlkSize;
|
|
|
|
|
|
|
|
|
|
UINT_32 numRbTotal = pIn->dccKeyFlags.rbAligned ? m_se * m_rbPerSe : 1;
|
|
|
|
|
|
|
|
|
|
if ((numPipeTotal > 1) || (numRbTotal > 1))
|
|
|
|
|
{
|
|
|
|
|
numCompressBlkPerMetaBlk =
|
|
|
|
|
Max(numCompressBlkPerMetaBlk, m_se * m_rbPerSe * (dataThick ? 262144 : 1024));
|
|
|
|
|
|
|
|
|
|
if (numCompressBlkPerMetaBlk > 65536 * pIn->bpp)
|
|
|
|
|
{
|
|
|
|
|
numCompressBlkPerMetaBlk = 65536 * pIn->bpp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Dim3d compressBlkDim = GetDccCompressBlk(pIn->resourceType, pIn->swizzleMode, pIn->bpp);
|
|
|
|
|
Dim3d metaBlkDim = compressBlkDim;
|
|
|
|
|
|
|
|
|
|
for (UINT_32 index = 1; index < numCompressBlkPerMetaBlk; index <<= 1)
|
|
|
|
|
{
|
|
|
|
|
if ((metaBlkDim.h < metaBlkDim.w) ||
|
|
|
|
|
((pIn->numMipLevels > 1) && (metaBlkDim.h == metaBlkDim.w)))
|
|
|
|
|
{
|
|
|
|
|
if ((dataThick == FALSE) || (metaBlkDim.h <= metaBlkDim.d))
|
|
|
|
|
{
|
|
|
|
|
metaBlkDim.h <<= 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
metaBlkDim.d <<= 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ((dataThick == FALSE) || (metaBlkDim.w <= metaBlkDim.d))
|
|
|
|
|
{
|
|
|
|
|
metaBlkDim.w <<= 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
metaBlkDim.d <<= 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UINT_32 numMetaBlkX;
|
|
|
|
|
UINT_32 numMetaBlkY;
|
|
|
|
|
UINT_32 numMetaBlkZ;
|
|
|
|
|
|
|
|
|
|
GetMetaMipInfo(pIn->numMipLevels, &metaBlkDim, dataThick, pOut->pMipInfo,
|
|
|
|
|
pIn->unalignedWidth, pIn->unalignedHeight, numSlices,
|
|
|
|
|
&numMetaBlkX, &numMetaBlkY, &numMetaBlkZ);
|
|
|
|
|
|
|
|
|
|
UINT_32 sizeAlign = numPipeTotal * numRbTotal * m_pipeInterleaveBytes;
|
|
|
|
|
|
|
|
|
|
if (numFrags > m_maxCompFrag)
|
|
|
|
|
{
|
|
|
|
|
sizeAlign *= (numFrags / m_maxCompFrag);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pOut->dccRamSize = numMetaBlkX * numMetaBlkY * numMetaBlkZ *
|
|
|
|
|
numCompressBlkPerMetaBlk * numFrags;
|
|
|
|
|
pOut->dccRamSize = PowTwoAlign(pOut->dccRamSize, sizeAlign);
|
|
|
|
|
pOut->dccRamBaseAlign = Max(numCompressBlkPerMetaBlk, sizeAlign);
|
|
|
|
|
|
|
|
|
|
if (m_settings.metaBaseAlignFix)
|
|
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
pOut->dccRamBaseAlign = Max(pOut->dccRamBaseAlign, GetBlockSize(pIn->swizzleMode));
|
2016-10-06 18:55:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pOut->pitch = numMetaBlkX * metaBlkDim.w;
|
|
|
|
|
pOut->height = numMetaBlkY * metaBlkDim.h;
|
|
|
|
|
pOut->depth = numMetaBlkZ * metaBlkDim.d;
|
|
|
|
|
|
|
|
|
|
pOut->compressBlkWidth = compressBlkDim.w;
|
|
|
|
|
pOut->compressBlkHeight = compressBlkDim.h;
|
|
|
|
|
pOut->compressBlkDepth = compressBlkDim.d;
|
|
|
|
|
|
|
|
|
|
pOut->metaBlkWidth = metaBlkDim.w;
|
|
|
|
|
pOut->metaBlkHeight = metaBlkDim.h;
|
|
|
|
|
pOut->metaBlkDepth = metaBlkDim.d;
|
|
|
|
|
|
|
|
|
|
pOut->metaBlkNumPerSlice = numMetaBlkX * numMetaBlkY;
|
|
|
|
|
pOut->fastClearSizePerSlice =
|
|
|
|
|
pOut->metaBlkNumPerSlice * numCompressBlkPerMetaBlk * Min(numFrags, m_maxCompFrag);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ADDR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::HwlGetMaxAlignments
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Gets maximum alignments
|
|
|
|
|
* @return
|
|
|
|
|
* ADDR_E_RETURNCODE
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlGetMaxAlignments(
|
2017-07-09 20:27:48 +01:00
|
|
|
ADDR_GET_MAX_ALIGNMENTS_OUTPUT* pOut ///< [out] output structure
|
2016-10-06 18:55:25 +02:00
|
|
|
) const
|
|
|
|
|
{
|
|
|
|
|
pOut->baseAlign = HwlComputeSurfaceBaseAlign(ADDR_SW_64KB);
|
|
|
|
|
|
|
|
|
|
return ADDR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::HwlComputeCmaskAddrFromCoord
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Interface function stub of AddrComputeCmaskAddrFromCoord
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* ADDR_E_RETURNCODE
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskAddrFromCoord(
|
|
|
|
|
const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
|
|
|
|
|
ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
|
|
|
|
|
) const
|
|
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
ADDR2_COMPUTE_CMASK_INFO_INPUT input = {0};
|
|
|
|
|
input.size = sizeof(input);
|
|
|
|
|
input.cMaskFlags = pIn->cMaskFlags;
|
|
|
|
|
input.colorFlags = pIn->colorFlags;
|
|
|
|
|
input.unalignedWidth = Max(pIn->unalignedWidth, 1u);
|
2016-10-06 18:55:25 +02:00
|
|
|
input.unalignedHeight = Max(pIn->unalignedHeight, 1u);
|
2017-02-27 22:25:44 +01:00
|
|
|
input.numSlices = Max(pIn->numSlices, 1u);
|
|
|
|
|
input.swizzleMode = pIn->swizzleMode;
|
|
|
|
|
input.resourceType = pIn->resourceType;
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
ADDR2_COMPUTE_CMASK_INFO_OUTPUT output = {0};
|
|
|
|
|
output.size = sizeof(output);
|
2016-10-06 18:55:25 +02:00
|
|
|
|
|
|
|
|
ADDR_E_RETURNCODE returnCode = ComputeCmaskInfo(&input, &output);
|
|
|
|
|
|
|
|
|
|
if (returnCode == ADDR_OK)
|
|
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 fmaskBpp = GetFmaskBpp(pIn->numSamples, pIn->numFrags);
|
2016-10-06 18:55:25 +02:00
|
|
|
UINT_32 fmaskElementBytesLog2 = Log2(fmaskBpp >> 3);
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth);
|
|
|
|
|
UINT_32 metaBlkHeightLog2 = Log2(output.metaBlkHeight);
|
2016-10-06 18:55:25 +02:00
|
|
|
|
|
|
|
|
CoordEq metaEq;
|
|
|
|
|
|
|
|
|
|
GetMetaEquation(&metaEq, 0, fmaskElementBytesLog2, 0, pIn->cMaskFlags,
|
|
|
|
|
Gfx9DataFmask, pIn->swizzleMode, pIn->resourceType,
|
|
|
|
|
metaBlkWidthLog2, metaBlkHeightLog2, 0, 3, 3, 0);
|
|
|
|
|
|
|
|
|
|
UINT_32 xb = pIn->x / output.metaBlkWidth;
|
|
|
|
|
UINT_32 yb = pIn->y / output.metaBlkHeight;
|
|
|
|
|
UINT_32 zb = pIn->slice;
|
|
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth;
|
2016-10-06 18:55:25 +02:00
|
|
|
UINT_32 sliceSizeInBlock = (output.height / output.metaBlkHeight) * pitchInBlock;
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb;
|
2016-10-06 18:55:25 +02:00
|
|
|
|
|
|
|
|
UINT_64 address = metaEq.solve(pIn->x, pIn->y, pIn->slice, 0, blockIndex);
|
|
|
|
|
|
|
|
|
|
pOut->addr = address >> 1;
|
|
|
|
|
pOut->bitPosition = static_cast<UINT_32>((address & 1) << 2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UINT_32 numPipeBits = GetPipeLog2ForMetaAddressing(pIn->cMaskFlags.pipeAligned,
|
|
|
|
|
pIn->swizzleMode);
|
|
|
|
|
|
|
|
|
|
UINT_64 pipeXor = static_cast<UINT_64>(pIn->pipeXor & ((1 << numPipeBits) - 1));
|
|
|
|
|
|
|
|
|
|
pOut->addr ^= (pipeXor << m_pipeInterleaveLog2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return returnCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::HwlComputeHtileAddrFromCoord
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Interface function stub of AddrComputeHtileAddrFromCoord
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* ADDR_E_RETURNCODE
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileAddrFromCoord(
|
|
|
|
|
const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
|
|
|
|
|
ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
|
|
|
|
|
) const
|
|
|
|
|
{
|
|
|
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
|
|
|
|
|
|
|
|
|
if (pIn->numMipLevels > 1)
|
|
|
|
|
{
|
|
|
|
|
returnCode = ADDR_NOTIMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
ADDR2_COMPUTE_HTILE_INFO_INPUT input = {0};
|
|
|
|
|
input.size = sizeof(input);
|
|
|
|
|
input.hTileFlags = pIn->hTileFlags;
|
|
|
|
|
input.depthFlags = pIn->depthflags;
|
|
|
|
|
input.swizzleMode = pIn->swizzleMode;
|
|
|
|
|
input.unalignedWidth = Max(pIn->unalignedWidth, 1u);
|
2016-10-06 18:55:25 +02:00
|
|
|
input.unalignedHeight = Max(pIn->unalignedHeight, 1u);
|
2017-02-27 22:25:44 +01:00
|
|
|
input.numSlices = Max(pIn->numSlices, 1u);
|
|
|
|
|
input.numMipLevels = Max(pIn->numMipLevels, 1u);
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
ADDR2_COMPUTE_HTILE_INFO_OUTPUT output = {0};
|
|
|
|
|
output.size = sizeof(output);
|
2016-10-06 18:55:25 +02:00
|
|
|
|
|
|
|
|
returnCode = ComputeHtileInfo(&input, &output);
|
|
|
|
|
|
|
|
|
|
if (returnCode == ADDR_OK)
|
|
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3);
|
|
|
|
|
UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth);
|
2016-10-06 18:55:25 +02:00
|
|
|
UINT_32 metaBlkHeightLog2 = Log2(output.metaBlkHeight);
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 numSamplesLog2 = Log2(pIn->numSamples);
|
2016-10-06 18:55:25 +02:00
|
|
|
|
|
|
|
|
CoordEq metaEq;
|
|
|
|
|
|
|
|
|
|
GetMetaEquation(&metaEq, 0, elementBytesLog2, numSamplesLog2, pIn->hTileFlags,
|
|
|
|
|
Gfx9DataDepthStencil, pIn->swizzleMode, ADDR_RSRC_TEX_2D,
|
|
|
|
|
metaBlkWidthLog2, metaBlkHeightLog2, 0, 3, 3, 0);
|
|
|
|
|
|
|
|
|
|
UINT_32 xb = pIn->x / output.metaBlkWidth;
|
|
|
|
|
UINT_32 yb = pIn->y / output.metaBlkHeight;
|
|
|
|
|
UINT_32 zb = pIn->slice;
|
|
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth;
|
2016-10-06 18:55:25 +02:00
|
|
|
UINT_32 sliceSizeInBlock = (output.height / output.metaBlkHeight) * pitchInBlock;
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb;
|
2016-10-06 18:55:25 +02:00
|
|
|
|
|
|
|
|
UINT_64 address = metaEq.solve(pIn->x, pIn->y, pIn->slice, 0, blockIndex);
|
|
|
|
|
|
|
|
|
|
pOut->addr = address >> 1;
|
|
|
|
|
|
|
|
|
|
UINT_32 numPipeBits = GetPipeLog2ForMetaAddressing(pIn->hTileFlags.pipeAligned,
|
|
|
|
|
pIn->swizzleMode);
|
|
|
|
|
|
|
|
|
|
UINT_64 pipeXor = static_cast<UINT_64>(pIn->pipeXor & ((1 << numPipeBits) - 1));
|
|
|
|
|
|
|
|
|
|
pOut->addr ^= (pipeXor << m_pipeInterleaveLog2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return returnCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::HwlComputeHtileCoordFromAddr
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Interface function stub of AddrComputeHtileCoordFromAddr
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* ADDR_E_RETURNCODE
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileCoordFromAddr(
|
|
|
|
|
const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
|
|
|
|
|
ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
|
|
|
|
|
) const
|
|
|
|
|
{
|
|
|
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
|
|
|
|
|
|
|
|
|
if (pIn->numMipLevels > 1)
|
|
|
|
|
{
|
|
|
|
|
returnCode = ADDR_NOTIMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
ADDR2_COMPUTE_HTILE_INFO_INPUT input = {0};
|
|
|
|
|
input.size = sizeof(input);
|
|
|
|
|
input.hTileFlags = pIn->hTileFlags;
|
|
|
|
|
input.swizzleMode = pIn->swizzleMode;
|
|
|
|
|
input.unalignedWidth = Max(pIn->unalignedWidth, 1u);
|
2016-10-06 18:55:25 +02:00
|
|
|
input.unalignedHeight = Max(pIn->unalignedHeight, 1u);
|
2017-02-27 22:25:44 +01:00
|
|
|
input.numSlices = Max(pIn->numSlices, 1u);
|
|
|
|
|
input.numMipLevels = Max(pIn->numMipLevels, 1u);
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
ADDR2_COMPUTE_HTILE_INFO_OUTPUT output = {0};
|
|
|
|
|
output.size = sizeof(output);
|
2016-10-06 18:55:25 +02:00
|
|
|
|
|
|
|
|
returnCode = ComputeHtileInfo(&input, &output);
|
|
|
|
|
|
|
|
|
|
if (returnCode == ADDR_OK)
|
|
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3);
|
|
|
|
|
UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth);
|
2016-10-06 18:55:25 +02:00
|
|
|
UINT_32 metaBlkHeightLog2 = Log2(output.metaBlkHeight);
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 numSamplesLog2 = Log2(pIn->numSamples);
|
2016-10-06 18:55:25 +02:00
|
|
|
|
|
|
|
|
CoordEq metaEq;
|
|
|
|
|
|
|
|
|
|
GetMetaEquation(&metaEq, 0, elementBytesLog2, numSamplesLog2, pIn->hTileFlags,
|
|
|
|
|
Gfx9DataDepthStencil, pIn->swizzleMode, ADDR_RSRC_TEX_2D,
|
|
|
|
|
metaBlkWidthLog2, metaBlkHeightLog2, 0, 3, 3, 0);
|
|
|
|
|
|
|
|
|
|
UINT_32 numPipeBits = GetPipeLog2ForMetaAddressing(pIn->hTileFlags.pipeAligned,
|
|
|
|
|
pIn->swizzleMode);
|
|
|
|
|
|
|
|
|
|
UINT_64 pipeXor = static_cast<UINT_64>(pIn->pipeXor & ((1 << numPipeBits) - 1));
|
|
|
|
|
|
|
|
|
|
UINT_64 nibbleAddress = (pIn->addr ^ (pipeXor << m_pipeInterleaveLog2)) << 1;
|
|
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth;
|
2016-10-06 18:55:25 +02:00
|
|
|
UINT_32 sliceSizeInBlock = (output.height / output.metaBlkHeight) * pitchInBlock;
|
|
|
|
|
|
|
|
|
|
UINT_32 x, y, z, s, m;
|
|
|
|
|
metaEq.solveAddr(nibbleAddress, sliceSizeInBlock, x, y, z, s, m);
|
|
|
|
|
|
|
|
|
|
pOut->slice = m / sliceSizeInBlock;
|
2017-02-27 22:25:44 +01:00
|
|
|
pOut->y = ((m % sliceSizeInBlock) / pitchInBlock) * output.metaBlkHeight + y;
|
|
|
|
|
pOut->x = (m % pitchInBlock) * output.metaBlkWidth + x;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return returnCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
* Gfx9Lib::HwlComputeDccAddrFromCoord
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Interface function stub of AddrComputeDccAddrFromCoord
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* ADDR_E_RETURNCODE
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputeDccAddrFromCoord(
|
|
|
|
|
const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn,
|
|
|
|
|
ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut) const
|
|
|
|
|
{
|
|
|
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
|
|
|
|
|
|
|
|
|
if ((pIn->numMipLevels > 1) || (pIn->mipId > 1) || pIn->dccKeyFlags.linear)
|
|
|
|
|
{
|
|
|
|
|
returnCode = ADDR_NOTIMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ADDR2_COMPUTE_DCCINFO_INPUT input = {0};
|
|
|
|
|
input.size = sizeof(input);
|
|
|
|
|
input.dccKeyFlags = pIn->dccKeyFlags;
|
|
|
|
|
input.colorFlags = pIn->colorFlags;
|
|
|
|
|
input.swizzleMode = pIn->swizzleMode;
|
|
|
|
|
input.resourceType = pIn->resourceType;
|
|
|
|
|
input.bpp = pIn->bpp;
|
|
|
|
|
input.unalignedWidth = Max(pIn->unalignedWidth, 1u);
|
|
|
|
|
input.unalignedHeight = Max(pIn->unalignedHeight, 1u);
|
|
|
|
|
input.numSlices = Max(pIn->numSlices, 1u);
|
|
|
|
|
input.numFrags = Max(pIn->numFrags, 1u);
|
|
|
|
|
input.numMipLevels = Max(pIn->numMipLevels, 1u);
|
|
|
|
|
|
|
|
|
|
ADDR2_COMPUTE_DCCINFO_OUTPUT output = {0};
|
|
|
|
|
output.size = sizeof(output);
|
|
|
|
|
|
|
|
|
|
returnCode = ComputeDccInfo(&input, &output);
|
|
|
|
|
|
|
|
|
|
if (returnCode == ADDR_OK)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3);
|
|
|
|
|
UINT_32 numSamplesLog2 = Log2(pIn->numFrags);
|
|
|
|
|
UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth);
|
|
|
|
|
UINT_32 metaBlkHeightLog2 = Log2(output.metaBlkHeight);
|
|
|
|
|
UINT_32 metaBlkDepthLog2 = Log2(output.metaBlkDepth);
|
|
|
|
|
UINT_32 compBlkWidthLog2 = Log2(output.compressBlkWidth);
|
|
|
|
|
UINT_32 compBlkHeightLog2 = Log2(output.compressBlkHeight);
|
|
|
|
|
UINT_32 compBlkDepthLog2 = Log2(output.compressBlkDepth);
|
|
|
|
|
|
|
|
|
|
CoordEq metaEq;
|
|
|
|
|
|
|
|
|
|
GetMetaEquation(&metaEq, pIn->mipId, elementBytesLog2, numSamplesLog2, pIn->dccKeyFlags,
|
|
|
|
|
Gfx9DataColor, pIn->swizzleMode, pIn->resourceType,
|
|
|
|
|
metaBlkWidthLog2, metaBlkHeightLog2, metaBlkDepthLog2,
|
|
|
|
|
compBlkWidthLog2, compBlkHeightLog2, compBlkDepthLog2);
|
|
|
|
|
|
|
|
|
|
UINT_32 xb = pIn->x / output.metaBlkWidth;
|
|
|
|
|
UINT_32 yb = pIn->y / output.metaBlkHeight;
|
|
|
|
|
UINT_32 zb = pIn->slice / output.metaBlkDepth;
|
|
|
|
|
|
|
|
|
|
UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth;
|
|
|
|
|
UINT_32 sliceSizeInBlock = (output.height / output.metaBlkHeight) * pitchInBlock;
|
|
|
|
|
UINT_32 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb;
|
|
|
|
|
|
|
|
|
|
UINT_64 address = metaEq.solve(pIn->x, pIn->y, pIn->slice, pIn->sample, blockIndex);
|
|
|
|
|
|
|
|
|
|
pOut->addr = address >> 1;
|
|
|
|
|
|
|
|
|
|
UINT_32 numPipeBits = GetPipeLog2ForMetaAddressing(pIn->dccKeyFlags.pipeAligned,
|
|
|
|
|
pIn->swizzleMode);
|
|
|
|
|
|
|
|
|
|
UINT_64 pipeXor = static_cast<UINT_64>(pIn->pipeXor & ((1 << numPipeBits) - 1));
|
|
|
|
|
|
|
|
|
|
pOut->addr ^= (pipeXor << m_pipeInterleaveLog2);
|
2016-10-06 18:55:25 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return returnCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::HwlInitGlobalParams
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Initializes global parameters
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* TRUE if all settings are valid
|
|
|
|
|
*
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
BOOL_32 Gfx9Lib::HwlInitGlobalParams(
|
|
|
|
|
const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input
|
|
|
|
|
{
|
|
|
|
|
BOOL_32 valid = TRUE;
|
|
|
|
|
|
|
|
|
|
if (m_settings.isArcticIsland)
|
|
|
|
|
{
|
|
|
|
|
GB_ADDR_CONFIG gbAddrConfig;
|
|
|
|
|
|
|
|
|
|
gbAddrConfig.u32All = pCreateIn->regValue.gbAddrConfig;
|
|
|
|
|
|
|
|
|
|
// These values are copied from CModel code
|
|
|
|
|
switch (gbAddrConfig.bits.NUM_PIPES)
|
|
|
|
|
{
|
|
|
|
|
case ADDR_CONFIG_1_PIPE:
|
|
|
|
|
m_pipes = 1;
|
|
|
|
|
m_pipesLog2 = 0;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_2_PIPE:
|
|
|
|
|
m_pipes = 2;
|
|
|
|
|
m_pipesLog2 = 1;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_4_PIPE:
|
|
|
|
|
m_pipes = 4;
|
|
|
|
|
m_pipesLog2 = 2;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_8_PIPE:
|
|
|
|
|
m_pipes = 8;
|
|
|
|
|
m_pipesLog2 = 3;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_16_PIPE:
|
|
|
|
|
m_pipes = 16;
|
|
|
|
|
m_pipesLog2 = 4;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_32_PIPE:
|
|
|
|
|
m_pipes = 32;
|
|
|
|
|
m_pipesLog2 = 5;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2017-02-27 22:25:44 +01:00
|
|
|
ADDR_ASSERT_ALWAYS();
|
2016-10-06 18:55:25 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (gbAddrConfig.bits.PIPE_INTERLEAVE_SIZE)
|
|
|
|
|
{
|
|
|
|
|
case ADDR_CONFIG_PIPE_INTERLEAVE_256B:
|
|
|
|
|
m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_256B;
|
|
|
|
|
m_pipeInterleaveLog2 = 8;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_PIPE_INTERLEAVE_512B:
|
|
|
|
|
m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_512B;
|
|
|
|
|
m_pipeInterleaveLog2 = 9;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_PIPE_INTERLEAVE_1KB:
|
|
|
|
|
m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_1KB;
|
|
|
|
|
m_pipeInterleaveLog2 = 10;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_PIPE_INTERLEAVE_2KB:
|
|
|
|
|
m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_2KB;
|
|
|
|
|
m_pipeInterleaveLog2 = 11;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2017-02-27 22:25:44 +01:00
|
|
|
ADDR_ASSERT_ALWAYS();
|
2016-10-06 18:55:25 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (gbAddrConfig.bits.NUM_BANKS)
|
|
|
|
|
{
|
|
|
|
|
case ADDR_CONFIG_1_BANK:
|
|
|
|
|
m_banks = 1;
|
|
|
|
|
m_banksLog2 = 0;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_2_BANK:
|
|
|
|
|
m_banks = 2;
|
|
|
|
|
m_banksLog2 = 1;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_4_BANK:
|
|
|
|
|
m_banks = 4;
|
|
|
|
|
m_banksLog2 = 2;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_8_BANK:
|
|
|
|
|
m_banks = 8;
|
|
|
|
|
m_banksLog2 = 3;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_16_BANK:
|
|
|
|
|
m_banks = 16;
|
|
|
|
|
m_banksLog2 = 4;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2017-02-27 22:25:44 +01:00
|
|
|
ADDR_ASSERT_ALWAYS();
|
2016-10-06 18:55:25 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (gbAddrConfig.bits.NUM_SHADER_ENGINES)
|
|
|
|
|
{
|
|
|
|
|
case ADDR_CONFIG_1_SHADER_ENGINE:
|
|
|
|
|
m_se = 1;
|
|
|
|
|
m_seLog2 = 0;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_2_SHADER_ENGINE:
|
|
|
|
|
m_se = 2;
|
|
|
|
|
m_seLog2 = 1;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_4_SHADER_ENGINE:
|
|
|
|
|
m_se = 4;
|
|
|
|
|
m_seLog2 = 2;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_8_SHADER_ENGINE:
|
|
|
|
|
m_se = 8;
|
|
|
|
|
m_seLog2 = 3;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2017-02-27 22:25:44 +01:00
|
|
|
ADDR_ASSERT_ALWAYS();
|
2016-10-06 18:55:25 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (gbAddrConfig.bits.NUM_RB_PER_SE)
|
|
|
|
|
{
|
|
|
|
|
case ADDR_CONFIG_1_RB_PER_SHADER_ENGINE:
|
|
|
|
|
m_rbPerSe = 1;
|
|
|
|
|
m_rbPerSeLog2 = 0;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_2_RB_PER_SHADER_ENGINE:
|
|
|
|
|
m_rbPerSe = 2;
|
|
|
|
|
m_rbPerSeLog2 = 1;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_4_RB_PER_SHADER_ENGINE:
|
|
|
|
|
m_rbPerSe = 4;
|
|
|
|
|
m_rbPerSeLog2 = 2;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2017-02-27 22:25:44 +01:00
|
|
|
ADDR_ASSERT_ALWAYS();
|
2016-10-06 18:55:25 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (gbAddrConfig.bits.MAX_COMPRESSED_FRAGS)
|
|
|
|
|
{
|
|
|
|
|
case ADDR_CONFIG_1_MAX_COMPRESSED_FRAGMENTS:
|
|
|
|
|
m_maxCompFrag = 1;
|
|
|
|
|
m_maxCompFragLog2 = 0;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_2_MAX_COMPRESSED_FRAGMENTS:
|
|
|
|
|
m_maxCompFrag = 2;
|
|
|
|
|
m_maxCompFragLog2 = 1;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_4_MAX_COMPRESSED_FRAGMENTS:
|
|
|
|
|
m_maxCompFrag = 4;
|
|
|
|
|
m_maxCompFragLog2 = 2;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_CONFIG_8_MAX_COMPRESSED_FRAGMENTS:
|
|
|
|
|
m_maxCompFrag = 8;
|
|
|
|
|
m_maxCompFragLog2 = 3;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2017-02-27 22:25:44 +01:00
|
|
|
ADDR_ASSERT_ALWAYS();
|
2016-10-06 18:55:25 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_blockVarSizeLog2 = pCreateIn->regValue.blockVarSizeLog2;
|
|
|
|
|
ADDR_ASSERT((m_blockVarSizeLog2 == 0) ||
|
|
|
|
|
((m_blockVarSizeLog2 >= 17u) && (m_blockVarSizeLog2 <= 20u)));
|
|
|
|
|
m_blockVarSizeLog2 = Min(Max(17u, m_blockVarSizeLog2), 20u);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
valid = FALSE;
|
|
|
|
|
ADDR_NOT_IMPLEMENTED();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (valid)
|
|
|
|
|
{
|
|
|
|
|
InitEquationTable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return valid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::HwlConvertChipFamily
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
|
|
|
|
|
* @return
|
|
|
|
|
* ChipFamily
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
ChipFamily Gfx9Lib::HwlConvertChipFamily(
|
|
|
|
|
UINT_32 uChipFamily, ///< [in] chip family defined in atiih.h
|
|
|
|
|
UINT_32 uChipRevision) ///< [in] chip revision defined in "asic_family"_id.h
|
|
|
|
|
{
|
|
|
|
|
ChipFamily family = ADDR_CHIP_FAMILY_AI;
|
|
|
|
|
|
|
|
|
|
switch (uChipFamily)
|
|
|
|
|
{
|
|
|
|
|
case FAMILY_AI:
|
|
|
|
|
m_settings.isArcticIsland = 1;
|
|
|
|
|
m_settings.isVega10 = ASICREV_IS_VEGA10_P(uChipRevision);
|
|
|
|
|
|
|
|
|
|
if (m_settings.isVega10)
|
|
|
|
|
{
|
|
|
|
|
m_settings.isDce12 = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_settings.metaBaseAlignFix = 1;
|
2017-02-27 22:25:44 +01:00
|
|
|
|
|
|
|
|
m_settings.depthPipeXorDisable = 1;
|
2016-10-06 18:55:25 +02:00
|
|
|
break;
|
|
|
|
|
|
2017-02-27 22:25:43 +01:00
|
|
|
case FAMILY_RV:
|
|
|
|
|
m_settings.isArcticIsland = 1;
|
|
|
|
|
m_settings.isRaven = ASICREV_IS_RAVEN(uChipRevision);
|
|
|
|
|
|
|
|
|
|
if (m_settings.isRaven)
|
|
|
|
|
{
|
|
|
|
|
m_settings.isDcn1 = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_settings.metaBaseAlignFix = 1;
|
|
|
|
|
|
|
|
|
|
m_settings.depthPipeXorDisable = 1;
|
|
|
|
|
break;
|
|
|
|
|
|
2016-10-06 18:55:25 +02:00
|
|
|
default:
|
|
|
|
|
ADDR_ASSERT(!"This should be a Fusion");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return family;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::InitRbEquation
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Init RB equation
|
|
|
|
|
* @return
|
|
|
|
|
* N/A
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
VOID Gfx9Lib::GetRbEquation(
|
|
|
|
|
CoordEq* pRbEq, ///< [out] rb equation
|
|
|
|
|
UINT_32 numRbPerSeLog2, ///< [in] number of rb per shader engine
|
|
|
|
|
UINT_32 numSeLog2) ///< [in] number of shader engine
|
|
|
|
|
{
|
|
|
|
|
// RB's are distributed on 16x16, except when we have 1 rb per se, in which case its 32x32
|
|
|
|
|
UINT_32 rbRegion = (numRbPerSeLog2 == 0) ? 5 : 4;
|
|
|
|
|
Coordinate cx('x', rbRegion);
|
|
|
|
|
Coordinate cy('y', rbRegion);
|
|
|
|
|
|
|
|
|
|
UINT_32 start = 0;
|
|
|
|
|
UINT_32 numRbTotalLog2 = numRbPerSeLog2 + numSeLog2;
|
|
|
|
|
|
|
|
|
|
// Clear the rb equation
|
|
|
|
|
pRbEq->resize(0);
|
|
|
|
|
pRbEq->resize(numRbTotalLog2);
|
|
|
|
|
|
|
|
|
|
if ((numSeLog2 > 0) && (numRbPerSeLog2 == 1))
|
|
|
|
|
{
|
|
|
|
|
// Special case when more than 1 SE, and 2 RB per SE
|
|
|
|
|
(*pRbEq)[0].add(cx);
|
|
|
|
|
(*pRbEq)[0].add(cy);
|
|
|
|
|
cx++;
|
|
|
|
|
cy++;
|
|
|
|
|
(*pRbEq)[0].add(cy);
|
|
|
|
|
start++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UINT_32 numBits = 2 * (numRbTotalLog2 - start);
|
|
|
|
|
|
|
|
|
|
for (UINT_32 i = 0; i < numBits; i++)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 idx =
|
|
|
|
|
start + (((start + i) >= numRbTotalLog2) ? (2 * (numRbTotalLog2 - start) - i - 1) : i);
|
|
|
|
|
|
|
|
|
|
if ((i % 2) == 1)
|
|
|
|
|
{
|
|
|
|
|
(*pRbEq)[idx].add(cx);
|
|
|
|
|
cx++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
(*pRbEq)[idx].add(cy);
|
|
|
|
|
cy++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::GetDataEquation
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Get data equation for fmask and Z
|
|
|
|
|
* @return
|
|
|
|
|
* N/A
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
VOID Gfx9Lib::GetDataEquation(
|
|
|
|
|
CoordEq* pDataEq, ///< [out] data surface equation
|
|
|
|
|
Gfx9DataType dataSurfaceType, ///< [in] data surface type
|
|
|
|
|
AddrSwizzleMode swizzleMode, ///< [in] data surface swizzle mode
|
|
|
|
|
AddrResourceType resourceType, ///< [in] data surface resource type
|
|
|
|
|
UINT_32 elementBytesLog2, ///< [in] data surface element bytes
|
|
|
|
|
UINT_32 numSamplesLog2) ///< [in] data surface sample count
|
|
|
|
|
const
|
|
|
|
|
{
|
|
|
|
|
Coordinate cx('x', 0);
|
|
|
|
|
Coordinate cy('y', 0);
|
|
|
|
|
Coordinate cz('z', 0);
|
|
|
|
|
Coordinate cs('s', 0);
|
|
|
|
|
|
|
|
|
|
// Clear the equation
|
|
|
|
|
pDataEq->resize(0);
|
|
|
|
|
pDataEq->resize(27);
|
|
|
|
|
|
|
|
|
|
if (dataSurfaceType == Gfx9DataColor)
|
|
|
|
|
{
|
|
|
|
|
if (IsLinear(swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
Coordinate cm('m', 0);
|
|
|
|
|
|
|
|
|
|
pDataEq->resize(49);
|
|
|
|
|
|
|
|
|
|
for (UINT_32 i = 0; i < 49; i++)
|
|
|
|
|
{
|
|
|
|
|
(*pDataEq)[i].add(cm);
|
|
|
|
|
cm++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (IsThick(resourceType, swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
// Color 3d_S and 3d_Z modes, 3d_D is same as color 2d
|
|
|
|
|
UINT_32 i;
|
|
|
|
|
if (IsStandardSwizzle(resourceType, swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
// Standard 3d swizzle
|
|
|
|
|
// Fill in bottom x bits
|
|
|
|
|
for (i = elementBytesLog2; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
(*pDataEq)[i].add(cx);
|
|
|
|
|
cx++;
|
|
|
|
|
}
|
|
|
|
|
// Fill in 2 bits of y and then z
|
|
|
|
|
for (i = 4; i < 6; i++)
|
|
|
|
|
{
|
|
|
|
|
(*pDataEq)[i].add(cy);
|
|
|
|
|
cy++;
|
|
|
|
|
}
|
|
|
|
|
for (i = 6; i < 8; i++)
|
|
|
|
|
{
|
|
|
|
|
(*pDataEq)[i].add(cz);
|
|
|
|
|
cz++;
|
|
|
|
|
}
|
|
|
|
|
if (elementBytesLog2 < 2)
|
|
|
|
|
{
|
|
|
|
|
// fill in z & y bit
|
|
|
|
|
(*pDataEq)[8].add(cz);
|
|
|
|
|
(*pDataEq)[9].add(cy);
|
|
|
|
|
cz++;
|
|
|
|
|
cy++;
|
|
|
|
|
}
|
|
|
|
|
else if (elementBytesLog2 == 2)
|
|
|
|
|
{
|
|
|
|
|
// fill in y and x bit
|
|
|
|
|
(*pDataEq)[8].add(cy);
|
|
|
|
|
(*pDataEq)[9].add(cx);
|
|
|
|
|
cy++;
|
|
|
|
|
cx++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// fill in 2 x bits
|
|
|
|
|
(*pDataEq)[8].add(cx);
|
|
|
|
|
cx++;
|
|
|
|
|
(*pDataEq)[9].add(cx);
|
|
|
|
|
cx++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Z 3d swizzle
|
|
|
|
|
UINT_32 m2dEnd = (elementBytesLog2 ==0) ? 3 : ((elementBytesLog2 < 4) ? 4 : 5);
|
|
|
|
|
UINT_32 numZs = (elementBytesLog2 == 0 || elementBytesLog2 == 4) ?
|
|
|
|
|
2 : ((elementBytesLog2 == 1) ? 3 : 1);
|
|
|
|
|
pDataEq->mort2d(cx, cy, elementBytesLog2, m2dEnd);
|
|
|
|
|
for (i = m2dEnd + 1; i <= m2dEnd + numZs; i++)
|
|
|
|
|
{
|
|
|
|
|
(*pDataEq)[i].add(cz);
|
|
|
|
|
cz++;
|
|
|
|
|
}
|
|
|
|
|
if ((elementBytesLog2 == 0) || (elementBytesLog2 == 3))
|
|
|
|
|
{
|
|
|
|
|
// add an x and z
|
|
|
|
|
(*pDataEq)[6].add(cx);
|
|
|
|
|
(*pDataEq)[7].add(cz);
|
|
|
|
|
cx++;
|
|
|
|
|
cz++;
|
|
|
|
|
}
|
|
|
|
|
else if (elementBytesLog2 == 2)
|
|
|
|
|
{
|
|
|
|
|
// add a y and z
|
|
|
|
|
(*pDataEq)[6].add(cy);
|
|
|
|
|
(*pDataEq)[7].add(cz);
|
|
|
|
|
cy++;
|
|
|
|
|
cz++;
|
|
|
|
|
}
|
|
|
|
|
// add y and x
|
|
|
|
|
(*pDataEq)[8].add(cy);
|
|
|
|
|
(*pDataEq)[9].add(cx);
|
|
|
|
|
cy++;
|
|
|
|
|
cx++;
|
|
|
|
|
}
|
|
|
|
|
// Fill in bit 10 and up
|
|
|
|
|
pDataEq->mort3d( cz, cy, cx, 10 );
|
|
|
|
|
}
|
|
|
|
|
else if (IsThin(resourceType, swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
UINT_32 blockSizeLog2 = GetBlockSizeLog2(swizzleMode);
|
|
|
|
|
// Color 2D
|
|
|
|
|
UINT_32 microYBits = (8 - elementBytesLog2) / 2;
|
|
|
|
|
UINT_32 tileSplitStart = blockSizeLog2 - numSamplesLog2;
|
|
|
|
|
UINT_32 i;
|
|
|
|
|
// Fill in bottom x bits
|
|
|
|
|
for (i = elementBytesLog2; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
(*pDataEq)[i].add(cx);
|
|
|
|
|
cx++;
|
|
|
|
|
}
|
|
|
|
|
// Fill in bottom y bits
|
|
|
|
|
for (i = 4; i < 4 + microYBits; i++)
|
|
|
|
|
{
|
|
|
|
|
(*pDataEq)[i].add(cy);
|
|
|
|
|
cy++;
|
|
|
|
|
}
|
|
|
|
|
// Fill in last of the micro_x bits
|
|
|
|
|
for (i = 4 + microYBits; i < 8; i++)
|
|
|
|
|
{
|
|
|
|
|
(*pDataEq)[i].add(cx);
|
|
|
|
|
cx++;
|
|
|
|
|
}
|
|
|
|
|
// Fill in x/y bits below sample split
|
|
|
|
|
pDataEq->mort2d(cy, cx, 8, tileSplitStart - 1);
|
|
|
|
|
// Fill in sample bits
|
|
|
|
|
for (i = 0; i < numSamplesLog2; i++)
|
|
|
|
|
{
|
|
|
|
|
cs.set('s', i);
|
|
|
|
|
(*pDataEq)[tileSplitStart + i].add(cs);
|
|
|
|
|
}
|
|
|
|
|
// Fill in x/y bits above sample split
|
|
|
|
|
if ((numSamplesLog2 & 1) ^ (blockSizeLog2 & 1))
|
|
|
|
|
{
|
|
|
|
|
pDataEq->mort2d(cx, cy, blockSizeLog2);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pDataEq->mort2d(cy, cx, blockSizeLog2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Fmask or depth
|
|
|
|
|
UINT_32 sampleStart = elementBytesLog2;
|
|
|
|
|
UINT_32 pixelStart = elementBytesLog2 + numSamplesLog2;
|
|
|
|
|
UINT_32 ymajStart = 6 + numSamplesLog2;
|
|
|
|
|
|
|
|
|
|
for (UINT_32 s = 0; s < numSamplesLog2; s++)
|
|
|
|
|
{
|
|
|
|
|
cs.set('s', s);
|
|
|
|
|
(*pDataEq)[sampleStart + s].add(cs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Put in the x-major order pixel bits
|
|
|
|
|
pDataEq->mort2d(cx, cy, pixelStart, ymajStart - 1);
|
|
|
|
|
// Put in the y-major order pixel bits
|
|
|
|
|
pDataEq->mort2d(cy, cx, ymajStart);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::GetPipeEquation
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Get pipe equation
|
|
|
|
|
* @return
|
|
|
|
|
* N/A
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
VOID Gfx9Lib::GetPipeEquation(
|
|
|
|
|
CoordEq* pPipeEq, ///< [out] pipe equation
|
|
|
|
|
CoordEq* pDataEq, ///< [in] data equation
|
|
|
|
|
UINT_32 pipeInterleaveLog2, ///< [in] pipe interleave
|
|
|
|
|
UINT_32 numPipeLog2, ///< [in] number of pipes
|
|
|
|
|
UINT_32 numSamplesLog2, ///< [in] data surface sample count
|
|
|
|
|
Gfx9DataType dataSurfaceType, ///< [in] data surface type
|
|
|
|
|
AddrSwizzleMode swizzleMode, ///< [in] data surface swizzle mode
|
|
|
|
|
AddrResourceType resourceType ///< [in] data surface resource type
|
|
|
|
|
) const
|
|
|
|
|
{
|
|
|
|
|
UINT_32 blockSizeLog2 = GetBlockSizeLog2(swizzleMode);
|
|
|
|
|
CoordEq dataEq;
|
|
|
|
|
|
|
|
|
|
pDataEq->copy(dataEq);
|
|
|
|
|
|
|
|
|
|
if (dataSurfaceType == Gfx9DataColor)
|
|
|
|
|
{
|
|
|
|
|
INT_32 shift = static_cast<INT_32>(numSamplesLog2);
|
|
|
|
|
dataEq.shift(-shift, blockSizeLog2 - numSamplesLog2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dataEq.copy(*pPipeEq, pipeInterleaveLog2, numPipeLog2);
|
|
|
|
|
|
|
|
|
|
// This section should only apply to z/stencil, maybe fmask
|
|
|
|
|
// If the pipe bit is below the comp block size,
|
|
|
|
|
// then keep moving up the address until we find a bit that is above
|
|
|
|
|
UINT_32 pipeStart = 0;
|
|
|
|
|
|
|
|
|
|
if (dataSurfaceType != Gfx9DataColor)
|
|
|
|
|
{
|
|
|
|
|
Coordinate tileMin('x', 3);
|
|
|
|
|
|
|
|
|
|
while (dataEq[pipeInterleaveLog2 + pipeStart][0] < tileMin)
|
|
|
|
|
{
|
|
|
|
|
pipeStart++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if pipe is 0, then the first pipe bit is above the comp block size,
|
|
|
|
|
// so we don't need to do anything
|
|
|
|
|
// Note, this if condition is not necessary, since if we execute the loop when pipe==0,
|
|
|
|
|
// we will get the same pipe equation
|
|
|
|
|
if (pipeStart != 0)
|
|
|
|
|
{
|
|
|
|
|
for (UINT_32 i = 0; i < numPipeLog2; i++)
|
|
|
|
|
{
|
|
|
|
|
// Copy the jth bit above pipe interleave to the current pipe equation bit
|
|
|
|
|
dataEq[pipeInterleaveLog2 + pipeStart + i].copyto((*pPipeEq)[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IsPrt(swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
// Clear out bits above the block size if prt's are enabled
|
|
|
|
|
dataEq.resize(blockSizeLog2);
|
|
|
|
|
dataEq.resize(48);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IsXor(swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
CoordEq xorMask;
|
|
|
|
|
|
|
|
|
|
if (IsThick(resourceType, swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
CoordEq xorMask2;
|
|
|
|
|
|
|
|
|
|
dataEq.copy(xorMask2, pipeInterleaveLog2 + numPipeLog2, 2 * numPipeLog2);
|
|
|
|
|
|
|
|
|
|
xorMask.resize(numPipeLog2);
|
|
|
|
|
|
|
|
|
|
for (UINT_32 pipeIdx = 0; pipeIdx < numPipeLog2; pipeIdx++)
|
|
|
|
|
{
|
|
|
|
|
xorMask[pipeIdx].add(xorMask2[2 * pipeIdx]);
|
|
|
|
|
xorMask[pipeIdx].add(xorMask2[2 * pipeIdx + 1]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Xor in the bits above the pipe+gpu bits
|
|
|
|
|
dataEq.copy(xorMask, pipeInterleaveLog2 + pipeStart + numPipeLog2, numPipeLog2);
|
|
|
|
|
|
|
|
|
|
if ((numSamplesLog2 == 0) && (IsPrt(swizzleMode) == FALSE))
|
|
|
|
|
{
|
|
|
|
|
Coordinate co;
|
|
|
|
|
CoordEq xorMask2;
|
|
|
|
|
// if 1xaa and not prt, then xor in the z bits
|
|
|
|
|
xorMask2.resize(0);
|
|
|
|
|
xorMask2.resize(numPipeLog2);
|
|
|
|
|
for (UINT_32 pipeIdx = 0; pipeIdx < numPipeLog2; pipeIdx++)
|
|
|
|
|
{
|
|
|
|
|
co.set('z', numPipeLog2 - 1 - pipeIdx);
|
|
|
|
|
xorMask2[pipeIdx].add(co);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pPipeEq->xorin(xorMask2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xorMask.reverse();
|
|
|
|
|
pPipeEq->xorin(xorMask);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::GetMetaEquation
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Get meta equation for cmask/htile/DCC
|
|
|
|
|
* @return
|
|
|
|
|
* N/A
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
VOID Gfx9Lib::GetMetaEquation(
|
|
|
|
|
CoordEq* pMetaEq, ///< [out] meta equation
|
|
|
|
|
UINT_32 maxMip, ///< [in] max mip Id
|
|
|
|
|
UINT_32 elementBytesLog2, ///< [in] data surface element bytes
|
|
|
|
|
UINT_32 numSamplesLog2, ///< [in] data surface sample count
|
|
|
|
|
ADDR2_META_FLAGS metaFlag, ///< [in] meta falg
|
|
|
|
|
Gfx9DataType dataSurfaceType, ///< [in] data surface type
|
|
|
|
|
AddrSwizzleMode swizzleMode, ///< [in] data surface swizzle mode
|
|
|
|
|
AddrResourceType resourceType, ///< [in] data surface resource type
|
|
|
|
|
UINT_32 metaBlkWidthLog2, ///< [in] meta block width
|
|
|
|
|
UINT_32 metaBlkHeightLog2, ///< [in] meta block height
|
|
|
|
|
UINT_32 metaBlkDepthLog2, ///< [in] meta block depth
|
|
|
|
|
UINT_32 compBlkWidthLog2, ///< [in] compress block width
|
|
|
|
|
UINT_32 compBlkHeightLog2, ///< [in] compress block height
|
|
|
|
|
UINT_32 compBlkDepthLog2) ///< [in] compress block depth
|
|
|
|
|
const
|
|
|
|
|
{
|
|
|
|
|
UINT_32 numPipeTotalLog2 = GetPipeLog2ForMetaAddressing(metaFlag.pipeAligned, swizzleMode);
|
|
|
|
|
UINT_32 pipeInterleaveLog2 = m_pipeInterleaveLog2;
|
2017-03-14 22:32:25 +01:00
|
|
|
//UINT_32 blockSizeLog2 = GetBlockSizeLog2(swizzleMode);
|
2016-10-06 18:55:25 +02:00
|
|
|
|
|
|
|
|
// Get the correct data address and rb equation
|
|
|
|
|
CoordEq dataEq;
|
|
|
|
|
GetDataEquation(&dataEq, dataSurfaceType, swizzleMode, resourceType,
|
|
|
|
|
elementBytesLog2, numSamplesLog2);
|
|
|
|
|
|
|
|
|
|
// Get pipe and rb equations
|
|
|
|
|
CoordEq pipeEquation;
|
|
|
|
|
GetPipeEquation(&pipeEquation, &dataEq, pipeInterleaveLog2, numPipeTotalLog2,
|
|
|
|
|
numSamplesLog2, dataSurfaceType, swizzleMode, resourceType);
|
|
|
|
|
numPipeTotalLog2 = pipeEquation.getsize();
|
|
|
|
|
|
|
|
|
|
if (metaFlag.linear)
|
|
|
|
|
{
|
|
|
|
|
// Linear metadata supporting was removed for GFX9! No one can use this feature.
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
|
|
|
|
|
ADDR_ASSERT(dataSurfaceType == Gfx9DataColor);
|
|
|
|
|
|
|
|
|
|
dataEq.copy(*pMetaEq);
|
|
|
|
|
|
|
|
|
|
if (IsLinear(swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
if (metaFlag.pipeAligned)
|
|
|
|
|
{
|
|
|
|
|
// Remove the pipe bits
|
|
|
|
|
INT_32 shift = static_cast<INT_32>(numPipeTotalLog2);
|
|
|
|
|
pMetaEq->shift(-shift, pipeInterleaveLog2);
|
|
|
|
|
}
|
|
|
|
|
// Divide by comp block size, which for linear (which is always color) is 256 B
|
|
|
|
|
pMetaEq->shift(-8);
|
|
|
|
|
|
|
|
|
|
if (metaFlag.pipeAligned)
|
|
|
|
|
{
|
|
|
|
|
// Put pipe bits back in
|
|
|
|
|
pMetaEq->shift(numPipeTotalLog2, pipeInterleaveLog2);
|
|
|
|
|
|
|
|
|
|
for (UINT_32 i = 0; i < numPipeTotalLog2; i++)
|
|
|
|
|
{
|
|
|
|
|
pipeEquation[i].copyto((*pMetaEq)[pipeInterleaveLog2 + i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pMetaEq->shift(1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UINT_32 maxCompFragLog2 = static_cast<INT_32>(m_maxCompFragLog2);
|
|
|
|
|
UINT_32 compFragLog2 =
|
|
|
|
|
((dataSurfaceType == Gfx9DataColor) && (numSamplesLog2 > maxCompFragLog2)) ?
|
|
|
|
|
maxCompFragLog2 : numSamplesLog2;
|
|
|
|
|
|
|
|
|
|
UINT_32 uncompFragLog2 = numSamplesLog2 - compFragLog2;
|
|
|
|
|
|
|
|
|
|
// Make sure the metaaddr is cleared
|
|
|
|
|
pMetaEq->resize(0);
|
|
|
|
|
pMetaEq->resize(27);
|
|
|
|
|
|
|
|
|
|
if (IsThick(resourceType, swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
Coordinate cx('x', 0);
|
|
|
|
|
Coordinate cy('y', 0);
|
|
|
|
|
Coordinate cz('z', 0);
|
|
|
|
|
|
|
|
|
|
if (maxMip > 0)
|
|
|
|
|
{
|
|
|
|
|
pMetaEq->mort3d(cy, cx, cz);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pMetaEq->mort3d(cx, cy, cz);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Coordinate cx('x', 0);
|
|
|
|
|
Coordinate cy('y', 0);
|
|
|
|
|
Coordinate cs;
|
|
|
|
|
|
|
|
|
|
if (maxMip > 0)
|
|
|
|
|
{
|
|
|
|
|
pMetaEq->mort2d(cy, cx, compFragLog2);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pMetaEq->mort2d(cx, cy, compFragLog2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
// Put the compressible fragments at the lsb
|
|
|
|
|
// the uncompressible frags will be at the msb of the micro address
|
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
for (UINT_32 s = 0; s < compFragLog2; s++)
|
|
|
|
|
{
|
|
|
|
|
cs.set('s', s);
|
|
|
|
|
(*pMetaEq)[s].add(cs);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Keep a copy of the pipe equations
|
|
|
|
|
CoordEq origPipeEquation;
|
|
|
|
|
pipeEquation.copy(origPipeEquation);
|
|
|
|
|
|
|
|
|
|
Coordinate co;
|
|
|
|
|
// filter out everything under the compressed block size
|
|
|
|
|
co.set('x', compBlkWidthLog2);
|
|
|
|
|
pMetaEq->Filter('<', co, 0, 'x');
|
|
|
|
|
co.set('y', compBlkHeightLog2);
|
|
|
|
|
pMetaEq->Filter('<', co, 0, 'y');
|
|
|
|
|
co.set('z', compBlkDepthLog2);
|
|
|
|
|
pMetaEq->Filter('<', co, 0, 'z');
|
|
|
|
|
|
|
|
|
|
// For non-color, filter out sample bits
|
|
|
|
|
if (dataSurfaceType != Gfx9DataColor)
|
|
|
|
|
{
|
|
|
|
|
co.set('x', 0);
|
|
|
|
|
pMetaEq->Filter('<', co, 0, 's');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// filter out everything above the metablock size
|
|
|
|
|
co.set('x', metaBlkWidthLog2 - 1);
|
|
|
|
|
pMetaEq->Filter('>', co, 0, 'x');
|
|
|
|
|
co.set('y', metaBlkHeightLog2 - 1);
|
|
|
|
|
pMetaEq->Filter('>', co, 0, 'y');
|
|
|
|
|
co.set('z', metaBlkDepthLog2 - 1);
|
|
|
|
|
pMetaEq->Filter('>', co, 0, 'z');
|
|
|
|
|
|
|
|
|
|
// filter out everything above the metablock size for the channel bits
|
|
|
|
|
co.set('x', metaBlkWidthLog2 - 1);
|
|
|
|
|
pipeEquation.Filter('>', co, 0, 'x');
|
|
|
|
|
co.set('y', metaBlkHeightLog2 - 1);
|
|
|
|
|
pipeEquation.Filter('>', co, 0, 'y');
|
|
|
|
|
co.set('z', metaBlkDepthLog2 - 1);
|
|
|
|
|
pipeEquation.Filter('>', co, 0, 'z');
|
|
|
|
|
|
|
|
|
|
// Make sure we still have the same number of channel bits
|
|
|
|
|
if (pipeEquation.getsize() != numPipeTotalLog2)
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Loop through all channel and rb bits,
|
|
|
|
|
// and make sure these components exist in the metadata address
|
|
|
|
|
for (UINT_32 i = 0; i < numPipeTotalLog2; i++)
|
|
|
|
|
{
|
|
|
|
|
for (UINT_32 j = pipeEquation[i].getsize(); j > 0; j--)
|
|
|
|
|
{
|
|
|
|
|
if (pMetaEq->Exists(pipeEquation[i][j - 1]) == FALSE)
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UINT_32 numSeLog2 = metaFlag.rbAligned ? m_seLog2 : 0;
|
|
|
|
|
UINT_32 numRbPeSeLog2 = metaFlag.rbAligned ? m_rbPerSeLog2 : 0;
|
|
|
|
|
CoordEq origRbEquation;
|
|
|
|
|
|
|
|
|
|
GetRbEquation(&origRbEquation, numRbPeSeLog2, numSeLog2);
|
|
|
|
|
|
|
|
|
|
CoordEq rbEquation = origRbEquation;
|
|
|
|
|
|
|
|
|
|
UINT_32 numRbTotalLog2 = numRbPeSeLog2 + numSeLog2;
|
|
|
|
|
|
|
|
|
|
for (UINT_32 i = 0; i < numRbTotalLog2; i++)
|
|
|
|
|
{
|
|
|
|
|
for (UINT_32 j = rbEquation[i].getsize(); j > 0; j--)
|
|
|
|
|
{
|
|
|
|
|
if (pMetaEq->Exists(rbEquation[i][j - 1]) == FALSE)
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Loop through each rb id bit; if it is equal to any of the filtered channel bits, clear it
|
|
|
|
|
for (UINT_32 i = 0; i < numRbTotalLog2; i++)
|
|
|
|
|
{
|
|
|
|
|
for (UINT_32 j = 0; j < numPipeTotalLog2; j++)
|
|
|
|
|
{
|
|
|
|
|
if (rbEquation[i] == pipeEquation[j])
|
|
|
|
|
{
|
|
|
|
|
rbEquation[i].Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Loop through each bit of the channel, get the smallest coordinate,
|
|
|
|
|
// and remove it from the metaaddr, and rb_equation
|
|
|
|
|
for (UINT_32 i = 0; i < numPipeTotalLog2; i++)
|
|
|
|
|
{
|
|
|
|
|
pipeEquation[i].getsmallest(co);
|
|
|
|
|
|
|
|
|
|
UINT_32 old_size = pMetaEq->getsize();
|
|
|
|
|
pMetaEq->Filter('=', co);
|
|
|
|
|
UINT_32 new_size = pMetaEq->getsize();
|
|
|
|
|
if (new_size != old_size-1)
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
}
|
|
|
|
|
pipeEquation.remove(co);
|
|
|
|
|
for (UINT_32 j = 0; j < numRbTotalLog2; j++)
|
|
|
|
|
{
|
|
|
|
|
if (rbEquation[j].remove(co))
|
|
|
|
|
{
|
|
|
|
|
// if we actually removed something from this bit, then add the remaining
|
|
|
|
|
// channel bits, as these can be removed for this bit
|
|
|
|
|
for (UINT_32 k = 0; k < pipeEquation[i].getsize(); k++)
|
|
|
|
|
{
|
|
|
|
|
if (pipeEquation[i][k] != co)
|
|
|
|
|
{
|
|
|
|
|
rbEquation[j].add(pipeEquation[i][k]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Loop through the rb bits and see what remain;
|
|
|
|
|
// filter out the smallest coordinate if it remains
|
|
|
|
|
UINT_32 rbBitsLeft = 0;
|
|
|
|
|
for (UINT_32 i = 0; i < numRbTotalLog2; i++)
|
|
|
|
|
{
|
|
|
|
|
if (rbEquation[i].getsize() > 0)
|
|
|
|
|
{
|
|
|
|
|
rbBitsLeft++;
|
|
|
|
|
rbEquation[i].getsmallest(co);
|
|
|
|
|
UINT_32 old_size = pMetaEq->getsize();
|
|
|
|
|
pMetaEq->Filter('=', co);
|
|
|
|
|
UINT_32 new_size = pMetaEq->getsize();
|
|
|
|
|
if (new_size != old_size - 1)
|
|
|
|
|
{
|
|
|
|
|
// assert warning
|
|
|
|
|
}
|
|
|
|
|
for (UINT_32 j = i + 1; j < numRbTotalLog2; j++)
|
|
|
|
|
{
|
|
|
|
|
if (rbEquation[j].remove(co))
|
|
|
|
|
{
|
|
|
|
|
// if we actually removed something from this bit, then add the remaining
|
|
|
|
|
// rb bits, as these can be removed for this bit
|
|
|
|
|
for (UINT_32 k = 0; k < rbEquation[i].getsize(); k++)
|
|
|
|
|
{
|
|
|
|
|
if (rbEquation[i][k] != co)
|
|
|
|
|
{
|
|
|
|
|
rbEquation[j].add(rbEquation[i][k]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// capture the size of the metaaddr
|
|
|
|
|
UINT_32 metaSize = pMetaEq->getsize();
|
|
|
|
|
// resize to 49 bits...make this a nibble address
|
|
|
|
|
pMetaEq->resize(49);
|
|
|
|
|
// Concatenate the macro address above the current address
|
|
|
|
|
for (UINT_32 i = metaSize, j = 0; i < 49; i++, j++)
|
|
|
|
|
{
|
|
|
|
|
co.set('m', j);
|
|
|
|
|
(*pMetaEq)[i].add(co);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Multiply by meta element size (in nibbles)
|
|
|
|
|
if (dataSurfaceType == Gfx9DataColor)
|
|
|
|
|
{
|
|
|
|
|
pMetaEq->shift(1);
|
|
|
|
|
}
|
|
|
|
|
else if (dataSurfaceType == Gfx9DataDepthStencil)
|
|
|
|
|
{
|
|
|
|
|
pMetaEq->shift(3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
|
// Note the pipeInterleaveLog2+1 is because address is a nibble address
|
|
|
|
|
// Shift up from pipe interleave number of channel
|
|
|
|
|
// and rb bits left, and uncompressed fragments
|
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
pMetaEq->shift(numPipeTotalLog2 + rbBitsLeft + uncompFragLog2, pipeInterleaveLog2 + 1);
|
|
|
|
|
|
|
|
|
|
// Put in the channel bits
|
|
|
|
|
for (UINT_32 i = 0; i < numPipeTotalLog2; i++)
|
|
|
|
|
{
|
|
|
|
|
origPipeEquation[i].copyto((*pMetaEq)[pipeInterleaveLog2+1 + i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Put in remaining rb bits
|
|
|
|
|
for (UINT_32 i = 0, j = 0; j < rbBitsLeft; i = (i + 1) % numRbTotalLog2)
|
|
|
|
|
{
|
|
|
|
|
if (rbEquation[i].getsize() > 0)
|
|
|
|
|
{
|
|
|
|
|
origRbEquation[i].copyto((*pMetaEq)[pipeInterleaveLog2 + 1 + numPipeTotalLog2 + j]);
|
|
|
|
|
// Mark any rb bit we add in to the rb mask
|
|
|
|
|
j++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
|
// Put in the uncompressed fragment bits
|
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
|
|
|
for (UINT_32 i = 0; i < uncompFragLog2; i++)
|
|
|
|
|
{
|
|
|
|
|
co.set('s', compFragLog2 + i);
|
|
|
|
|
(*pMetaEq)[pipeInterleaveLog2 + 1 + numPipeTotalLog2 + rbBitsLeft + i].add(co);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::IsEquationSupported
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Check if equation is supported for given swizzle mode and resource type.
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* TRUE if supported
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
BOOL_32 Gfx9Lib::IsEquationSupported(
|
|
|
|
|
AddrResourceType rsrcType,
|
|
|
|
|
AddrSwizzleMode swMode,
|
|
|
|
|
UINT_32 elementBytesLog2) const
|
|
|
|
|
{
|
|
|
|
|
BOOL_32 supported = (elementBytesLog2 < MaxElementBytesLog2) &&
|
|
|
|
|
(IsLinear(swMode) == FALSE) &&
|
2017-02-27 22:25:44 +01:00
|
|
|
(((IsTex2d(rsrcType) == TRUE) &&
|
|
|
|
|
((elementBytesLog2 < 4) ||
|
|
|
|
|
((IsRotateSwizzle(swMode) == FALSE) &&
|
|
|
|
|
(IsZOrderSwizzle(swMode) == FALSE)))) ||
|
2016-10-06 18:55:25 +02:00
|
|
|
((IsTex3d(rsrcType) == TRUE) &&
|
|
|
|
|
(IsRotateSwizzle(swMode) == FALSE) &&
|
|
|
|
|
(IsBlock256b(swMode) == FALSE)));
|
|
|
|
|
|
|
|
|
|
return supported;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::InitEquationTable
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Initialize Equation table.
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* N/A
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
VOID Gfx9Lib::InitEquationTable()
|
|
|
|
|
{
|
|
|
|
|
memset(m_equationTable, 0, sizeof(m_equationTable));
|
|
|
|
|
|
|
|
|
|
// Loop all possible resource type (2D/3D)
|
|
|
|
|
for (UINT_32 rsrcTypeIdx = 0; rsrcTypeIdx < MaxRsrcType; rsrcTypeIdx++)
|
|
|
|
|
{
|
|
|
|
|
AddrResourceType rsrcType = static_cast<AddrResourceType>(rsrcTypeIdx + ADDR_RSRC_TEX_2D);
|
|
|
|
|
|
|
|
|
|
// Loop all possible swizzle mode
|
|
|
|
|
for (UINT_32 swModeIdx = 0; swModeIdx < MaxSwMode; swModeIdx++)
|
|
|
|
|
{
|
|
|
|
|
AddrSwizzleMode swMode = static_cast<AddrSwizzleMode>(swModeIdx);
|
|
|
|
|
|
|
|
|
|
// Loop all possible bpp
|
|
|
|
|
for (UINT_32 bppIdx = 0; bppIdx < MaxElementBytesLog2; bppIdx++)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 equationIndex = ADDR_INVALID_EQUATION_INDEX;
|
|
|
|
|
|
|
|
|
|
// Check if the input is supported
|
|
|
|
|
if (IsEquationSupported(rsrcType, swMode, bppIdx))
|
|
|
|
|
{
|
|
|
|
|
ADDR_EQUATION equation;
|
|
|
|
|
ADDR_E_RETURNCODE retCode;
|
|
|
|
|
|
|
|
|
|
memset(&equation, 0, sizeof(ADDR_EQUATION));
|
|
|
|
|
|
|
|
|
|
// Generate the equation
|
|
|
|
|
if (IsBlock256b(swMode) && IsTex2d(rsrcType))
|
|
|
|
|
{
|
|
|
|
|
retCode = ComputeBlock256Equation(rsrcType, swMode, bppIdx, &equation);
|
|
|
|
|
}
|
|
|
|
|
else if (IsThin(rsrcType, swMode))
|
|
|
|
|
{
|
|
|
|
|
retCode = ComputeThinEquation(rsrcType, swMode, bppIdx, &equation);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
retCode = ComputeThickEquation(rsrcType, swMode, bppIdx, &equation);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Only fill the equation into the table if the return code is ADDR_OK,
|
|
|
|
|
// otherwise if the return code is not ADDR_OK, it indicates this is not
|
|
|
|
|
// a valid input, we do nothing but just fill invalid equation index
|
|
|
|
|
// into the lookup table.
|
|
|
|
|
if (retCode == ADDR_OK)
|
|
|
|
|
{
|
|
|
|
|
equationIndex = m_numEquations;
|
|
|
|
|
ADDR_ASSERT(equationIndex < EquationTableSize);
|
|
|
|
|
|
|
|
|
|
m_equationTable[equationIndex] = equation;
|
|
|
|
|
|
|
|
|
|
m_numEquations++;
|
|
|
|
|
}
|
2017-02-27 22:25:44 +01:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
}
|
2016-10-06 18:55:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fill the index into the lookup table, if the combination is not supported
|
|
|
|
|
// fill the invalid equation index
|
|
|
|
|
m_equationLookupTable[rsrcTypeIdx][swModeIdx][bppIdx] = equationIndex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::HwlGetEquationIndex
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Interface function stub of GetEquationIndex
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* ADDR_E_RETURNCODE
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
UINT_32 Gfx9Lib::HwlGetEquationIndex(
|
|
|
|
|
const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,
|
|
|
|
|
ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut
|
|
|
|
|
) const
|
|
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
AddrResourceType rsrcType = pIn->resourceType;
|
|
|
|
|
AddrSwizzleMode swMode = pIn->swizzleMode;
|
|
|
|
|
UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3);
|
|
|
|
|
UINT_32 index = ADDR_INVALID_EQUATION_INDEX;
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
if (IsEquationSupported(rsrcType, swMode, elementBytesLog2))
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 rsrcTypeIdx = static_cast<UINT_32>(rsrcType) - 1;
|
|
|
|
|
UINT_32 swModeIdx = static_cast<UINT_32>(swMode);
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
index = m_equationLookupTable[rsrcTypeIdx][swModeIdx][elementBytesLog2];
|
2016-10-06 18:55:25 +02:00
|
|
|
}
|
2017-02-27 22:25:44 +01:00
|
|
|
|
|
|
|
|
if (pOut->pMipInfo != NULL)
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
for (UINT_32 i = 0; i < pIn->numMipLevels; i++)
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
pOut->pMipInfo[i].equationIndex = index;
|
2016-10-06 18:55:25 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::HwlComputeBlock256Equation
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Interface function stub of ComputeBlock256Equation
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* ADDR_E_RETURNCODE
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputeBlock256Equation(
|
|
|
|
|
AddrResourceType rsrcType,
|
2017-02-27 22:25:44 +01:00
|
|
|
AddrSwizzleMode swMode,
|
|
|
|
|
UINT_32 elementBytesLog2,
|
|
|
|
|
ADDR_EQUATION* pEquation) const
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
|
|
|
|
ADDR_E_RETURNCODE ret = ADDR_OK;
|
|
|
|
|
|
|
|
|
|
pEquation->numBits = 8;
|
|
|
|
|
|
|
|
|
|
UINT_32 i = 0;
|
|
|
|
|
for (; i < elementBytesLog2; i++)
|
|
|
|
|
{
|
|
|
|
|
InitChannel(1, 0 , i, &pEquation->addr[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ADDR_CHANNEL_SETTING* pixelBit = &pEquation->addr[elementBytesLog2];
|
|
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
const UINT_32 maxBitsUsed = 4;
|
|
|
|
|
ADDR_CHANNEL_SETTING x[maxBitsUsed] = {};
|
|
|
|
|
ADDR_CHANNEL_SETTING y[maxBitsUsed] = {};
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
for (i = 0; i < maxBitsUsed; i++)
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
|
|
|
|
InitChannel(1, 0, elementBytesLog2 + i, &x[i]);
|
|
|
|
|
InitChannel(1, 1, i, &y[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IsStandardSwizzle(rsrcType, swMode))
|
|
|
|
|
{
|
|
|
|
|
switch (elementBytesLog2)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = x[1];
|
|
|
|
|
pixelBit[2] = x[2];
|
|
|
|
|
pixelBit[3] = x[3];
|
|
|
|
|
pixelBit[4] = y[0];
|
|
|
|
|
pixelBit[5] = y[1];
|
|
|
|
|
pixelBit[6] = y[2];
|
|
|
|
|
pixelBit[7] = y[3];
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = x[1];
|
|
|
|
|
pixelBit[2] = x[2];
|
|
|
|
|
pixelBit[3] = y[0];
|
|
|
|
|
pixelBit[4] = y[1];
|
|
|
|
|
pixelBit[5] = y[2];
|
|
|
|
|
pixelBit[6] = x[3];
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = x[1];
|
|
|
|
|
pixelBit[2] = y[0];
|
|
|
|
|
pixelBit[3] = y[1];
|
|
|
|
|
pixelBit[4] = y[2];
|
|
|
|
|
pixelBit[5] = x[2];
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = y[0];
|
|
|
|
|
pixelBit[2] = y[1];
|
|
|
|
|
pixelBit[3] = x[1];
|
|
|
|
|
pixelBit[4] = x[2];
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
pixelBit[0] = y[0];
|
|
|
|
|
pixelBit[1] = y[1];
|
|
|
|
|
pixelBit[2] = x[0];
|
|
|
|
|
pixelBit[3] = x[1];
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
ret = ADDR_INVALIDPARAMS;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (IsDisplaySwizzle(rsrcType, swMode))
|
|
|
|
|
{
|
|
|
|
|
switch (elementBytesLog2)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = x[1];
|
|
|
|
|
pixelBit[2] = x[2];
|
|
|
|
|
pixelBit[3] = y[1];
|
|
|
|
|
pixelBit[4] = y[0];
|
|
|
|
|
pixelBit[5] = y[2];
|
|
|
|
|
pixelBit[6] = x[3];
|
|
|
|
|
pixelBit[7] = y[3];
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = x[1];
|
|
|
|
|
pixelBit[2] = x[2];
|
|
|
|
|
pixelBit[3] = y[0];
|
|
|
|
|
pixelBit[4] = y[1];
|
|
|
|
|
pixelBit[5] = y[2];
|
|
|
|
|
pixelBit[6] = x[3];
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = x[1];
|
|
|
|
|
pixelBit[2] = y[0];
|
|
|
|
|
pixelBit[3] = x[2];
|
|
|
|
|
pixelBit[4] = y[1];
|
|
|
|
|
pixelBit[5] = y[2];
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = y[0];
|
|
|
|
|
pixelBit[2] = x[1];
|
|
|
|
|
pixelBit[3] = x[2];
|
|
|
|
|
pixelBit[4] = y[1];
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = y[0];
|
|
|
|
|
pixelBit[2] = x[1];
|
|
|
|
|
pixelBit[3] = y[1];
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
ret = ADDR_INVALIDPARAMS;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (IsRotateSwizzle(swMode))
|
|
|
|
|
{
|
|
|
|
|
switch (elementBytesLog2)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
pixelBit[0] = y[0];
|
|
|
|
|
pixelBit[1] = y[1];
|
|
|
|
|
pixelBit[2] = y[2];
|
|
|
|
|
pixelBit[3] = x[1];
|
|
|
|
|
pixelBit[4] = x[0];
|
|
|
|
|
pixelBit[5] = x[2];
|
|
|
|
|
pixelBit[6] = x[3];
|
|
|
|
|
pixelBit[7] = y[3];
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
pixelBit[0] = y[0];
|
|
|
|
|
pixelBit[1] = y[1];
|
|
|
|
|
pixelBit[2] = y[2];
|
|
|
|
|
pixelBit[3] = x[0];
|
|
|
|
|
pixelBit[4] = x[1];
|
|
|
|
|
pixelBit[5] = x[2];
|
|
|
|
|
pixelBit[6] = x[3];
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
pixelBit[0] = y[0];
|
|
|
|
|
pixelBit[1] = y[1];
|
|
|
|
|
pixelBit[2] = x[0];
|
|
|
|
|
pixelBit[3] = y[2];
|
|
|
|
|
pixelBit[4] = x[1];
|
|
|
|
|
pixelBit[5] = x[2];
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
pixelBit[0] = y[0];
|
|
|
|
|
pixelBit[1] = x[0];
|
|
|
|
|
pixelBit[2] = y[1];
|
|
|
|
|
pixelBit[3] = x[1];
|
|
|
|
|
pixelBit[4] = x[2];
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
case 4:
|
|
|
|
|
ret = ADDR_INVALIDPARAMS;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
ret = ADDR_INVALIDPARAMS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Post validation
|
|
|
|
|
if (ret == ADDR_OK)
|
|
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
Dim2d microBlockDim = Block256_2d[elementBytesLog2];
|
2016-10-06 18:55:25 +02:00
|
|
|
ADDR_ASSERT((2u << GetMaxValidChannelIndex(pEquation->addr, 8, 0)) ==
|
|
|
|
|
(microBlockDim.w * (1 << elementBytesLog2)));
|
|
|
|
|
ADDR_ASSERT((2u << GetMaxValidChannelIndex(pEquation->addr, 8, 1)) == microBlockDim.h);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::HwlComputeThinEquation
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Interface function stub of ComputeThinEquation
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* ADDR_E_RETURNCODE
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThinEquation(
|
|
|
|
|
AddrResourceType rsrcType,
|
2017-02-27 22:25:44 +01:00
|
|
|
AddrSwizzleMode swMode,
|
|
|
|
|
UINT_32 elementBytesLog2,
|
|
|
|
|
ADDR_EQUATION* pEquation) const
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
|
|
|
|
ADDR_E_RETURNCODE ret = ADDR_OK;
|
|
|
|
|
|
|
|
|
|
UINT_32 blockSizeLog2 = GetBlockSizeLog2(swMode);
|
|
|
|
|
|
|
|
|
|
UINT_32 maxXorBits = blockSizeLog2;
|
|
|
|
|
if (IsNonPrtXor(swMode))
|
|
|
|
|
{
|
|
|
|
|
// For non-prt-xor, maybe need to initialize some more bits for xor
|
|
|
|
|
// The highest xor bit used in equation will be max the following 3 items:
|
|
|
|
|
// 1. m_pipeInterleaveLog2 + 2 * pipeXorBits
|
|
|
|
|
// 2. m_pipeInterleaveLog2 + pipeXorBits + 2 * bankXorBits
|
|
|
|
|
// 3. blockSizeLog2
|
|
|
|
|
|
|
|
|
|
maxXorBits = Max(maxXorBits, m_pipeInterleaveLog2 + 2 * GetPipeXorBits(blockSizeLog2));
|
|
|
|
|
maxXorBits = Max(maxXorBits, m_pipeInterleaveLog2 +
|
|
|
|
|
GetPipeXorBits(blockSizeLog2) +
|
|
|
|
|
2 * GetBankXorBits(blockSizeLog2));
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
const UINT_32 maxBitsUsed = 14;
|
|
|
|
|
ADDR_ASSERT((2 * maxBitsUsed) >= maxXorBits);
|
|
|
|
|
ADDR_CHANNEL_SETTING x[maxBitsUsed] = {};
|
|
|
|
|
ADDR_CHANNEL_SETTING y[maxBitsUsed] = {};
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
const UINT_32 extraXorBits = 16;
|
|
|
|
|
ADDR_ASSERT(extraXorBits >= maxXorBits - blockSizeLog2);
|
|
|
|
|
ADDR_CHANNEL_SETTING xorExtra[extraXorBits] = {};
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
for (UINT_32 i = 0; i < maxBitsUsed; i++)
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
|
|
|
|
InitChannel(1, 0, elementBytesLog2 + i, &x[i]);
|
|
|
|
|
InitChannel(1, 1, i, &y[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ADDR_CHANNEL_SETTING* pixelBit = pEquation->addr;
|
|
|
|
|
|
|
|
|
|
for (UINT_32 i = 0; i < elementBytesLog2; i++)
|
|
|
|
|
{
|
|
|
|
|
InitChannel(1, 0 , i, &pixelBit[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UINT_32 xIdx = 0;
|
|
|
|
|
UINT_32 yIdx = 0;
|
|
|
|
|
UINT_32 lowBits = 0;
|
|
|
|
|
|
|
|
|
|
if (IsZOrderSwizzle(swMode))
|
|
|
|
|
{
|
|
|
|
|
if (elementBytesLog2 <= 3)
|
|
|
|
|
{
|
|
|
|
|
for (UINT_32 i = elementBytesLog2; i < 6; i++)
|
|
|
|
|
{
|
|
|
|
|
pixelBit[i] = (((i - elementBytesLog2) & 1) == 0) ? x[xIdx++] : y[yIdx++];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lowBits = 6;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ret = ADDR_INVALIDPARAMS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ret = HwlComputeBlock256Equation(rsrcType, swMode, elementBytesLog2, pEquation);
|
2017-02-27 22:25:44 +01:00
|
|
|
|
2016-10-06 18:55:25 +02:00
|
|
|
if (ret == ADDR_OK)
|
|
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
Dim2d microBlockDim = Block256_2d[elementBytesLog2];
|
2016-10-06 18:55:25 +02:00
|
|
|
xIdx = Log2(microBlockDim.w);
|
|
|
|
|
yIdx = Log2(microBlockDim.h);
|
|
|
|
|
lowBits = 8;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ret == ADDR_OK)
|
|
|
|
|
{
|
|
|
|
|
for (UINT_32 i = lowBits; i < blockSizeLog2; i++)
|
|
|
|
|
{
|
|
|
|
|
pixelBit[i] = ((i & 1) == 0) ? y[yIdx++] : x[xIdx++];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (UINT_32 i = blockSizeLog2; i < maxXorBits; i++)
|
|
|
|
|
{
|
|
|
|
|
xorExtra[i - blockSizeLog2] = ((i & 1) == 0) ? y[yIdx++] : x[xIdx++];
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
if (IsXor(swMode))
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
// Fill XOR bits
|
|
|
|
|
UINT_32 pipeStart = m_pipeInterleaveLog2;
|
|
|
|
|
UINT_32 pipeXorBits = GetPipeXorBits(blockSizeLog2);
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 bankStart = pipeStart + pipeXorBits;
|
|
|
|
|
UINT_32 bankXorBits = GetBankXorBits(blockSizeLog2);
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
for (UINT_32 i = 0; i < pipeXorBits; i++)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 xor1BitPos = pipeStart + 2 * pipeXorBits - 1 - i;
|
|
|
|
|
ADDR_CHANNEL_SETTING* pXor1Src = (xor1BitPos < blockSizeLog2) ?
|
|
|
|
|
&pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2];
|
|
|
|
|
|
|
|
|
|
InitChannel(&pEquation->xor1[pipeStart + i], pXor1Src);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (UINT_32 i = 0; i < bankXorBits; i++)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 xor1BitPos = bankStart + 2 * bankXorBits - 1 - i;
|
|
|
|
|
ADDR_CHANNEL_SETTING* pXor1Src = (xor1BitPos < blockSizeLog2) ?
|
|
|
|
|
&pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2];
|
|
|
|
|
|
|
|
|
|
InitChannel(&pEquation->xor1[bankStart + i], pXor1Src);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IsPrt(swMode) == FALSE)
|
|
|
|
|
{
|
|
|
|
|
for (UINT_32 i = 0; i < pipeXorBits; i++)
|
|
|
|
|
{
|
|
|
|
|
InitChannel(1, 2, pipeXorBits - i - 1, &pEquation->xor2[pipeStart + i]);
|
|
|
|
|
}
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
for (UINT_32 i = 0; i < bankXorBits; i++)
|
|
|
|
|
{
|
|
|
|
|
InitChannel(1, 2, bankXorBits - i - 1 + pipeXorBits, &pEquation->xor2[bankStart + i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-10-06 18:55:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pEquation->numBits = blockSizeLog2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
* Gfx9Lib::HwlComputeThickEquation
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Interface function stub of ComputeThickEquation
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* ADDR_E_RETURNCODE
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThickEquation(
|
|
|
|
|
AddrResourceType rsrcType,
|
2017-02-27 22:25:44 +01:00
|
|
|
AddrSwizzleMode swMode,
|
|
|
|
|
UINT_32 elementBytesLog2,
|
|
|
|
|
ADDR_EQUATION* pEquation) const
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
|
|
|
|
ADDR_E_RETURNCODE ret = ADDR_OK;
|
|
|
|
|
|
|
|
|
|
ADDR_ASSERT(IsTex3d(rsrcType));
|
|
|
|
|
|
|
|
|
|
UINT_32 blockSizeLog2 = GetBlockSizeLog2(swMode);
|
|
|
|
|
|
|
|
|
|
UINT_32 maxXorBits = blockSizeLog2;
|
|
|
|
|
if (IsNonPrtXor(swMode))
|
|
|
|
|
{
|
|
|
|
|
// For non-prt-xor, maybe need to initialize some more bits for xor
|
|
|
|
|
// The highest xor bit used in equation will be max the following 3:
|
|
|
|
|
// 1. m_pipeInterleaveLog2 + 3 * pipeXorBits
|
|
|
|
|
// 2. m_pipeInterleaveLog2 + pipeXorBits + 3 * bankXorBits
|
|
|
|
|
// 3. blockSizeLog2
|
|
|
|
|
|
|
|
|
|
maxXorBits = Max(maxXorBits, m_pipeInterleaveLog2 + 3 * GetPipeXorBits(blockSizeLog2));
|
|
|
|
|
maxXorBits = Max(maxXorBits, m_pipeInterleaveLog2 +
|
|
|
|
|
GetPipeXorBits(blockSizeLog2) +
|
|
|
|
|
3 * GetBankXorBits(blockSizeLog2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (UINT_32 i = 0; i < elementBytesLog2; i++)
|
|
|
|
|
{
|
|
|
|
|
InitChannel(1, 0 , i, &pEquation->addr[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ADDR_CHANNEL_SETTING* pixelBit = &pEquation->addr[elementBytesLog2];
|
|
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
const UINT_32 maxBitsUsed = 12;
|
|
|
|
|
ADDR_ASSERT((3 * maxBitsUsed) >= maxXorBits);
|
|
|
|
|
ADDR_CHANNEL_SETTING x[maxBitsUsed] = {};
|
|
|
|
|
ADDR_CHANNEL_SETTING y[maxBitsUsed] = {};
|
|
|
|
|
ADDR_CHANNEL_SETTING z[maxBitsUsed] = {};
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
const UINT_32 extraXorBits = 24;
|
|
|
|
|
ADDR_ASSERT(extraXorBits >= maxXorBits - blockSizeLog2);
|
|
|
|
|
ADDR_CHANNEL_SETTING xorExtra[extraXorBits] = {};
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
for (UINT_32 i = 0; i < maxBitsUsed; i++)
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
|
|
|
|
InitChannel(1, 0, elementBytesLog2 + i, &x[i]);
|
|
|
|
|
InitChannel(1, 1, i, &y[i]);
|
|
|
|
|
InitChannel(1, 2, i, &z[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IsZOrderSwizzle(swMode))
|
|
|
|
|
{
|
|
|
|
|
switch (elementBytesLog2)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = y[0];
|
|
|
|
|
pixelBit[2] = x[1];
|
|
|
|
|
pixelBit[3] = y[1];
|
|
|
|
|
pixelBit[4] = z[0];
|
|
|
|
|
pixelBit[5] = z[1];
|
|
|
|
|
pixelBit[6] = x[2];
|
|
|
|
|
pixelBit[7] = z[2];
|
|
|
|
|
pixelBit[8] = y[2];
|
|
|
|
|
pixelBit[9] = x[3];
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = y[0];
|
|
|
|
|
pixelBit[2] = x[1];
|
|
|
|
|
pixelBit[3] = y[1];
|
|
|
|
|
pixelBit[4] = z[0];
|
|
|
|
|
pixelBit[5] = z[1];
|
|
|
|
|
pixelBit[6] = z[2];
|
|
|
|
|
pixelBit[7] = y[2];
|
|
|
|
|
pixelBit[8] = x[2];
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = y[0];
|
|
|
|
|
pixelBit[2] = x[1];
|
|
|
|
|
pixelBit[3] = z[0];
|
|
|
|
|
pixelBit[4] = y[1];
|
|
|
|
|
pixelBit[5] = z[1];
|
|
|
|
|
pixelBit[6] = y[2];
|
|
|
|
|
pixelBit[7] = x[2];
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = y[0];
|
|
|
|
|
pixelBit[2] = z[0];
|
|
|
|
|
pixelBit[3] = x[1];
|
|
|
|
|
pixelBit[4] = z[1];
|
|
|
|
|
pixelBit[5] = y[1];
|
|
|
|
|
pixelBit[6] = x[2];
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = y[0];
|
|
|
|
|
pixelBit[2] = z[0];
|
|
|
|
|
pixelBit[3] = z[1];
|
|
|
|
|
pixelBit[4] = y[1];
|
|
|
|
|
pixelBit[5] = x[1];
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
ret = ADDR_INVALIDPARAMS;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (IsStandardSwizzle(rsrcType, swMode))
|
|
|
|
|
{
|
|
|
|
|
switch (elementBytesLog2)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = x[1];
|
|
|
|
|
pixelBit[2] = x[2];
|
|
|
|
|
pixelBit[3] = x[3];
|
|
|
|
|
pixelBit[4] = y[0];
|
|
|
|
|
pixelBit[5] = y[1];
|
|
|
|
|
pixelBit[6] = z[0];
|
|
|
|
|
pixelBit[7] = z[1];
|
|
|
|
|
pixelBit[8] = z[2];
|
|
|
|
|
pixelBit[9] = y[2];
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = x[1];
|
|
|
|
|
pixelBit[2] = x[2];
|
|
|
|
|
pixelBit[3] = y[0];
|
|
|
|
|
pixelBit[4] = y[1];
|
|
|
|
|
pixelBit[5] = z[0];
|
|
|
|
|
pixelBit[6] = z[1];
|
|
|
|
|
pixelBit[7] = z[2];
|
|
|
|
|
pixelBit[8] = y[2];
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = x[1];
|
|
|
|
|
pixelBit[2] = y[0];
|
|
|
|
|
pixelBit[3] = y[1];
|
|
|
|
|
pixelBit[4] = z[0];
|
|
|
|
|
pixelBit[5] = z[1];
|
|
|
|
|
pixelBit[6] = y[2];
|
|
|
|
|
pixelBit[7] = x[2];
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
pixelBit[0] = x[0];
|
|
|
|
|
pixelBit[1] = y[0];
|
|
|
|
|
pixelBit[2] = y[1];
|
|
|
|
|
pixelBit[3] = z[0];
|
|
|
|
|
pixelBit[4] = z[1];
|
|
|
|
|
pixelBit[5] = x[1];
|
|
|
|
|
pixelBit[6] = x[2];
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
pixelBit[0] = y[0];
|
|
|
|
|
pixelBit[1] = y[1];
|
|
|
|
|
pixelBit[2] = z[0];
|
|
|
|
|
pixelBit[3] = z[1];
|
|
|
|
|
pixelBit[4] = x[0];
|
|
|
|
|
pixelBit[5] = x[1];
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
ret = ADDR_INVALIDPARAMS;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
ret = ADDR_INVALIDPARAMS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ret == ADDR_OK)
|
|
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
Dim3d microBlockDim = Block1K_3d[elementBytesLog2];
|
2016-10-06 18:55:25 +02:00
|
|
|
UINT_32 xIdx = Log2(microBlockDim.w);
|
|
|
|
|
UINT_32 yIdx = Log2(microBlockDim.h);
|
|
|
|
|
UINT_32 zIdx = Log2(microBlockDim.d);
|
|
|
|
|
|
|
|
|
|
pixelBit = pEquation->addr;
|
|
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
const UINT_32 lowBits = 10;
|
2016-10-06 18:55:25 +02:00
|
|
|
ADDR_ASSERT(pEquation->addr[lowBits - 1].valid == 1);
|
|
|
|
|
ADDR_ASSERT(pEquation->addr[lowBits].valid == 0);
|
|
|
|
|
|
|
|
|
|
for (UINT_32 i = lowBits; i < blockSizeLog2; i++)
|
|
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
if ((i % 3) == 0)
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
|
|
|
|
pixelBit[i] = x[xIdx++];
|
|
|
|
|
}
|
2017-02-27 22:25:44 +01:00
|
|
|
else if ((i % 3) == 1)
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
|
|
|
|
pixelBit[i] = z[zIdx++];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pixelBit[i] = y[yIdx++];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (UINT_32 i = blockSizeLog2; i < maxXorBits; i++)
|
|
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
if ((i % 3) == 0)
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
|
|
|
|
xorExtra[i - blockSizeLog2] = x[xIdx++];
|
|
|
|
|
}
|
2017-02-27 22:25:44 +01:00
|
|
|
else if ((i % 3) == 1)
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
|
|
|
|
xorExtra[i - blockSizeLog2] = z[zIdx++];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
xorExtra[i - blockSizeLog2] = y[yIdx++];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
if (IsXor(swMode))
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
2017-02-27 22:25:44 +01:00
|
|
|
// Fill XOR bits
|
|
|
|
|
UINT_32 pipeStart = m_pipeInterleaveLog2;
|
|
|
|
|
UINT_32 pipeXorBits = GetPipeXorBits(blockSizeLog2);
|
|
|
|
|
for (UINT_32 i = 0; i < pipeXorBits; i++)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 xor1BitPos = pipeStart + (3 * pipeXorBits) - 1 - (2 * i);
|
|
|
|
|
ADDR_CHANNEL_SETTING* pXor1Src = (xor1BitPos < blockSizeLog2) ?
|
|
|
|
|
&pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2];
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
InitChannel(&pEquation->xor1[pipeStart + i], pXor1Src);
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 xor2BitPos = pipeStart + (3 * pipeXorBits) - 2 - (2 * i);
|
|
|
|
|
ADDR_CHANNEL_SETTING* pXor2Src = (xor2BitPos < blockSizeLog2) ?
|
|
|
|
|
&pEquation->addr[xor2BitPos] : &xorExtra[xor2BitPos - blockSizeLog2];
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
InitChannel(&pEquation->xor2[pipeStart + i], pXor2Src);
|
|
|
|
|
}
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 bankStart = pipeStart + pipeXorBits;
|
|
|
|
|
UINT_32 bankXorBits = GetBankXorBits(blockSizeLog2);
|
|
|
|
|
for (UINT_32 i = 0; i < bankXorBits; i++)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 xor1BitPos = bankStart + (3 * bankXorBits) - 1 - (2 * i);
|
|
|
|
|
ADDR_CHANNEL_SETTING* pXor1Src = (xor1BitPos < blockSizeLog2) ?
|
|
|
|
|
&pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2];
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
InitChannel(&pEquation->xor1[bankStart + i], pXor1Src);
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
UINT_32 xor2BitPos = bankStart + (3 * bankXorBits) - 2 - (2 * i);
|
|
|
|
|
ADDR_CHANNEL_SETTING* pXor2Src = (xor2BitPos < blockSizeLog2) ?
|
|
|
|
|
&pEquation->addr[xor2BitPos] : &xorExtra[xor2BitPos - blockSizeLog2];
|
2016-10-06 18:55:25 +02:00
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
InitChannel(&pEquation->xor2[bankStart + i], pXor2Src);
|
|
|
|
|
}
|
2016-10-06 18:55:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pEquation->numBits = blockSizeLog2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
|
|
|
|
* Gfx9Lib::IsValidDisplaySwizzleMode
|
2016-10-06 18:55:25 +02:00
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Check if a swizzle mode is supported by display engine
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* TRUE is swizzle mode is supported by display engine
|
2017-02-27 22:25:44 +01:00
|
|
|
************************************************************************************************************************
|
2016-10-06 18:55:25 +02:00
|
|
|
*/
|
2017-02-27 22:25:44 +01:00
|
|
|
BOOL_32 Gfx9Lib::IsValidDisplaySwizzleMode(
|
|
|
|
|
const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const
|
2016-10-06 18:55:25 +02:00
|
|
|
{
|
|
|
|
|
BOOL_32 support = FALSE;
|
|
|
|
|
|
2017-03-14 22:32:25 +01:00
|
|
|
//const AddrResourceType resourceType = pIn->resourceType;
|
2016-10-06 18:55:25 +02:00
|
|
|
const AddrSwizzleMode swizzleMode = pIn->swizzleMode;
|
|
|
|
|
|
|
|
|
|
if (m_settings.isDce12)
|
|
|
|
|
{
|
|
|
|
|
switch (swizzleMode)
|
|
|
|
|
{
|
|
|
|
|
case ADDR_SW_256B_D:
|
|
|
|
|
case ADDR_SW_256B_R:
|
|
|
|
|
support = (pIn->bpp == 32);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ADDR_SW_LINEAR:
|
|
|
|
|
case ADDR_SW_4KB_D:
|
|
|
|
|
case ADDR_SW_4KB_R:
|
|
|
|
|
case ADDR_SW_64KB_D:
|
|
|
|
|
case ADDR_SW_64KB_R:
|
|
|
|
|
case ADDR_SW_VAR_D:
|
|
|
|
|
case ADDR_SW_VAR_R:
|
|
|
|
|
case ADDR_SW_4KB_D_X:
|
|
|
|
|
case ADDR_SW_4KB_R_X:
|
|
|
|
|
case ADDR_SW_64KB_D_X:
|
|
|
|
|
case ADDR_SW_64KB_R_X:
|
|
|
|
|
case ADDR_SW_VAR_D_X:
|
|
|
|
|
case ADDR_SW_VAR_R_X:
|
|
|
|
|
support = (pIn->bpp <= 64);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-02-27 22:25:43 +01:00
|
|
|
else if (m_settings.isDcn1)
|
|
|
|
|
{
|
|
|
|
|
switch (swizzleMode)
|
|
|
|
|
{
|
|
|
|
|
case ADDR_SW_4KB_D:
|
|
|
|
|
case ADDR_SW_64KB_D:
|
|
|
|
|
case ADDR_SW_VAR_D:
|
|
|
|
|
case ADDR_SW_64KB_D_T:
|
|
|
|
|
case ADDR_SW_4KB_D_X:
|
|
|
|
|
case ADDR_SW_64KB_D_X:
|
|
|
|
|
case ADDR_SW_VAR_D_X:
|
|
|
|
|
support = (pIn->bpp == 64);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ADDR_SW_LINEAR:
|
|
|
|
|
case ADDR_SW_4KB_S:
|
|
|
|
|
case ADDR_SW_64KB_S:
|
|
|
|
|
case ADDR_SW_VAR_S:
|
|
|
|
|
case ADDR_SW_64KB_S_T:
|
|
|
|
|
case ADDR_SW_4KB_S_X:
|
|
|
|
|
case ADDR_SW_64KB_S_X:
|
|
|
|
|
case ADDR_SW_VAR_S_X:
|
|
|
|
|
support = (pIn->bpp <= 64);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-10-06 18:55:25 +02:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ADDR_NOT_IMPLEMENTED();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return support;
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-27 22:25:44 +01:00
|
|
|
/**
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
* Gfx9Lib::HwlComputePipeBankXor
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Generate a PipeBankXor value to be ORed into bits above pipeInterleaveBits of address
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* PipeBankXor value
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputePipeBankXor(
|
|
|
|
|
const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,
|
|
|
|
|
ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut) const
|
|
|
|
|
{
|
|
|
|
|
UINT_32 macroBlockBits = GetBlockSizeLog2(pIn->swizzleMode);
|
|
|
|
|
UINT_32 pipeBits = GetPipeXorBits(macroBlockBits);
|
|
|
|
|
UINT_32 bankBits = GetBankXorBits(macroBlockBits);
|
|
|
|
|
|
|
|
|
|
UINT_32 pipeXor = 0;
|
|
|
|
|
UINT_32 bankXor = 0;
|
|
|
|
|
|
|
|
|
|
const UINT_32 bankMask = (1 << bankBits) - 1;
|
|
|
|
|
const UINT_32 index = pIn->surfIndex & bankMask;
|
|
|
|
|
|
|
|
|
|
const UINT_32 bpp = pIn->flags.fmask ?
|
|
|
|
|
GetFmaskBpp(pIn->numSamples, pIn->numFrags) : GetElemLib()->GetBitsPerPixel(pIn->format);
|
|
|
|
|
if (bankBits == 4)
|
|
|
|
|
{
|
|
|
|
|
static const UINT_32 BankXorSmallBpp[] = {0, 7, 4, 3, 8, 15, 12, 11, 1, 6, 5, 2, 9, 14, 13, 10};
|
|
|
|
|
static const UINT_32 BankXorLargeBpp[] = {0, 7, 8, 15, 4, 3, 12, 11, 1, 6, 9, 14, 5, 2, 13, 10};
|
|
|
|
|
|
|
|
|
|
bankXor = (bpp <= 32) ? BankXorSmallBpp[index] : BankXorLargeBpp[index];
|
|
|
|
|
}
|
|
|
|
|
else if (bankBits > 0)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 bankIncrease = (1 << (bankBits - 1)) - 1;
|
|
|
|
|
bankIncrease = (bankIncrease == 0) ? 1 : bankIncrease;
|
|
|
|
|
bankXor = (index * bankIncrease) & bankMask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pOut->pipeBankXor = (bankXor << pipeBits) | pipeXor;
|
|
|
|
|
|
|
|
|
|
return ADDR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
* Gfx9Lib::HwlComputeSlicePipeBankXor
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Generate slice PipeBankXor value based on base PipeBankXor value and slice id
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* PipeBankXor value
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSlicePipeBankXor(
|
|
|
|
|
const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,
|
|
|
|
|
ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut) const
|
|
|
|
|
{
|
|
|
|
|
UINT_32 macroBlockBits = GetBlockSizeLog2(pIn->swizzleMode);
|
|
|
|
|
UINT_32 pipeBits = GetPipeXorBits(macroBlockBits);
|
|
|
|
|
UINT_32 bankBits = GetBankXorBits(macroBlockBits);
|
|
|
|
|
|
|
|
|
|
UINT_32 pipeXor = ReverseBitVector(pIn->slice, pipeBits);
|
|
|
|
|
UINT_32 bankXor = ReverseBitVector(pIn->slice >> pipeBits, bankBits);
|
|
|
|
|
|
|
|
|
|
pOut->pipeBankXor = pIn->basePipeBankXor ^ (pipeXor | (bankXor << pipeBits));
|
|
|
|
|
|
|
|
|
|
return ADDR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
* Gfx9Lib::HwlComputeSubResourceOffsetForSwizzlePattern
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Compute sub resource offset to support swizzle pattern
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* Offset
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSubResourceOffsetForSwizzlePattern(
|
|
|
|
|
const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,
|
|
|
|
|
ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut) const
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT(IsThin(pIn->resourceType, pIn->swizzleMode));
|
|
|
|
|
|
|
|
|
|
UINT_32 macroBlockBits = GetBlockSizeLog2(pIn->swizzleMode);
|
|
|
|
|
UINT_32 pipeBits = GetPipeXorBits(macroBlockBits);
|
|
|
|
|
UINT_32 bankBits = GetBankXorBits(macroBlockBits);
|
|
|
|
|
UINT_32 pipeXor = ReverseBitVector(pIn->slice, pipeBits);
|
|
|
|
|
UINT_32 bankXor = ReverseBitVector(pIn->slice >> pipeBits, bankBits);
|
|
|
|
|
UINT_32 pipeBankXor = ((pipeXor | (bankXor << pipeBits)) ^ (pIn->pipeBankXor)) << m_pipeInterleaveLog2;
|
|
|
|
|
|
|
|
|
|
pOut->offset = pIn->slice * pIn->sliceSize +
|
|
|
|
|
pIn->macroBlockOffset +
|
|
|
|
|
(pIn->mipTailOffset ^ pipeBankXor) -
|
|
|
|
|
static_cast<UINT_64>(pipeBankXor);
|
|
|
|
|
return ADDR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
* Gfx9Lib::HwlComputeSurfaceInfoSanityCheck
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Compute surface info sanity check
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* Offset
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceInfoSanityCheck(
|
|
|
|
|
const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const
|
|
|
|
|
{
|
|
|
|
|
BOOL_32 invalid = FALSE;
|
|
|
|
|
|
|
|
|
|
if ((pIn->bpp > 128) || (pIn->width == 0) || (pIn->numFrags > 8) || (pIn->numSamples > 16))
|
|
|
|
|
{
|
|
|
|
|
invalid = TRUE;
|
|
|
|
|
}
|
|
|
|
|
else if ((pIn->swizzleMode >= ADDR_SW_MAX_TYPE) ||
|
|
|
|
|
(pIn->resourceType >= ADDR_RSRC_MAX_TYPE))
|
|
|
|
|
{
|
|
|
|
|
invalid = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL_32 mipmap = (pIn->numMipLevels > 1);
|
|
|
|
|
BOOL_32 msaa = (pIn->numFrags > 1);
|
|
|
|
|
|
|
|
|
|
ADDR2_SURFACE_FLAGS flags = pIn->flags;
|
|
|
|
|
BOOL_32 zbuffer = (flags.depth || flags.stencil);
|
|
|
|
|
BOOL_32 color = flags.color;
|
|
|
|
|
BOOL_32 display = flags.display || flags.rotated;
|
|
|
|
|
|
|
|
|
|
AddrResourceType rsrcType = pIn->resourceType;
|
|
|
|
|
BOOL_32 tex3d = IsTex3d(rsrcType);
|
|
|
|
|
AddrSwizzleMode swizzle = pIn->swizzleMode;
|
|
|
|
|
BOOL_32 linear = IsLinear(swizzle);
|
|
|
|
|
BOOL_32 blk256B = IsBlock256b(swizzle);
|
|
|
|
|
BOOL_32 blkVar = IsBlockVariable(swizzle);
|
|
|
|
|
BOOL_32 isNonPrtXor = IsNonPrtXor(swizzle);
|
|
|
|
|
BOOL_32 prt = flags.prt;
|
|
|
|
|
BOOL_32 stereo = flags.qbStereo;
|
|
|
|
|
|
|
|
|
|
if (invalid == FALSE)
|
|
|
|
|
{
|
|
|
|
|
if ((pIn->numFrags > 1) &&
|
|
|
|
|
(GetBlockSize(swizzle) < (m_pipeInterleaveBytes * pIn->numFrags)))
|
|
|
|
|
{
|
|
|
|
|
// MSAA surface must have blk_bytes/pipe_interleave >= num_samples
|
|
|
|
|
invalid = TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (invalid == FALSE)
|
|
|
|
|
{
|
|
|
|
|
switch (rsrcType)
|
|
|
|
|
{
|
|
|
|
|
case ADDR_RSRC_TEX_1D:
|
|
|
|
|
invalid = msaa || zbuffer || display || (linear == FALSE) || stereo;
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_RSRC_TEX_2D:
|
|
|
|
|
invalid = (msaa && mipmap) || (stereo && msaa) || (stereo && mipmap);
|
|
|
|
|
break;
|
|
|
|
|
case ADDR_RSRC_TEX_3D:
|
|
|
|
|
invalid = msaa || zbuffer || display || stereo;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
invalid = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (invalid == FALSE)
|
|
|
|
|
{
|
|
|
|
|
if (display)
|
|
|
|
|
{
|
|
|
|
|
invalid = (IsValidDisplaySwizzleMode(pIn) == FALSE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (invalid == FALSE)
|
|
|
|
|
{
|
|
|
|
|
if (linear)
|
|
|
|
|
{
|
|
|
|
|
invalid = ((ADDR_RSRC_TEX_1D != rsrcType) && prt) ||
|
|
|
|
|
zbuffer || msaa || (pIn->bpp == 0) || ((pIn->bpp % 8) != 0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (blk256B || blkVar || isNonPrtXor)
|
|
|
|
|
{
|
|
|
|
|
invalid = prt;
|
|
|
|
|
if (blk256B)
|
|
|
|
|
{
|
|
|
|
|
invalid = invalid || zbuffer || tex3d || mipmap || msaa;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (invalid == FALSE)
|
|
|
|
|
{
|
|
|
|
|
if (IsZOrderSwizzle(swizzle))
|
|
|
|
|
{
|
|
|
|
|
invalid = color && msaa;
|
|
|
|
|
}
|
|
|
|
|
else if (IsStandardSwizzle(rsrcType, swizzle))
|
|
|
|
|
{
|
|
|
|
|
invalid = zbuffer;
|
|
|
|
|
}
|
|
|
|
|
else if (IsDisplaySwizzle(rsrcType, swizzle))
|
|
|
|
|
{
|
|
|
|
|
invalid = zbuffer;
|
|
|
|
|
}
|
|
|
|
|
else if (IsRotateSwizzle(swizzle))
|
|
|
|
|
{
|
|
|
|
|
invalid = zbuffer || (pIn->bpp > 64) || tex3d;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT(!"invalid swizzle mode");
|
|
|
|
|
invalid = TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ADDR_ASSERT(invalid == FALSE);
|
|
|
|
|
|
|
|
|
|
return invalid ? ADDR_INVALIDPARAMS : ADDR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
* Gfx9Lib::HwlGetPreferredSurfaceSetting
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Internal function to get suggested surface information for cliet to use
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* ADDR_E_RETURNCODE
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlGetPreferredSurfaceSetting(
|
|
|
|
|
const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
|
|
|
|
|
ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT* pOut) const
|
|
|
|
|
{
|
|
|
|
|
// Macro define resource block type
|
|
|
|
|
enum AddrBlockType
|
|
|
|
|
{
|
|
|
|
|
AddrBlockMicro = 0, // Resource uses 256B block
|
|
|
|
|
AddrBlock4KB = 1, // Resource uses 4KB block
|
|
|
|
|
AddrBlock64KB = 2, // Resource uses 64KB block
|
|
|
|
|
AddrBlockVar = 3, // Resource uses var blcok
|
|
|
|
|
AddrBlockLinear = 4, // Resource uses linear swizzle mode
|
|
|
|
|
|
|
|
|
|
AddrBlockMaxTiledType = AddrBlock64KB + 1,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum AddrBlockSet
|
|
|
|
|
{
|
|
|
|
|
AddrBlockSetMicro = 1 << AddrBlockMicro,
|
|
|
|
|
AddrBlockSetMacro4KB = 1 << AddrBlock4KB,
|
|
|
|
|
AddrBlockSetMacro64KB = 1 << AddrBlock64KB,
|
|
|
|
|
AddrBlockSetVar = 1 << AddrBlockVar,
|
|
|
|
|
AddrBlockSetLinear = 1 << AddrBlockLinear,
|
|
|
|
|
|
|
|
|
|
AddrBlockSetMacro = AddrBlockSetMacro4KB | AddrBlockSetMacro64KB,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
|
|
|
|
ElemLib* pElemLib = GetElemLib();
|
|
|
|
|
|
|
|
|
|
// Set format to INVALID will skip this conversion
|
|
|
|
|
UINT_32 expandX = 1;
|
|
|
|
|
UINT_32 expandY = 1;
|
|
|
|
|
UINT_32 bpp = pIn->bpp;
|
|
|
|
|
UINT_32 width = pIn->width;
|
|
|
|
|
UINT_32 height = pIn->height;
|
|
|
|
|
|
|
|
|
|
if (pIn->format != ADDR_FMT_INVALID)
|
|
|
|
|
{
|
|
|
|
|
// Don't care for this case
|
|
|
|
|
ElemMode elemMode = ADDR_UNCOMPRESSED;
|
|
|
|
|
|
|
|
|
|
// Get compression/expansion factors and element mode which indicates compression/expansion
|
|
|
|
|
bpp = pElemLib->GetBitsPerPixel(pIn->format,
|
|
|
|
|
&elemMode,
|
|
|
|
|
&expandX,
|
|
|
|
|
&expandY);
|
|
|
|
|
|
|
|
|
|
UINT_32 basePitch = 0;
|
|
|
|
|
GetElemLib()->AdjustSurfaceInfo(elemMode,
|
|
|
|
|
expandX,
|
|
|
|
|
expandY,
|
|
|
|
|
&bpp,
|
|
|
|
|
&basePitch,
|
|
|
|
|
&width,
|
|
|
|
|
&height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UINT_32 numSamples = Max(pIn->numSamples, 1u);
|
|
|
|
|
UINT_32 numFrags = (pIn->numFrags == 0) ? numSamples : pIn->numFrags;
|
|
|
|
|
UINT_32 slice = Max(pIn->numSlices, 1u);
|
|
|
|
|
UINT_32 numMipLevels = Max(pIn->numMipLevels, 1u);
|
|
|
|
|
UINT_32 minSizeAlign = NextPow2(pIn->minSizeAlign);
|
|
|
|
|
|
|
|
|
|
if (pIn->flags.fmask)
|
|
|
|
|
{
|
|
|
|
|
bpp = GetFmaskBpp(numSamples, numFrags);
|
|
|
|
|
numFrags = 1;
|
|
|
|
|
numSamples = 1;
|
|
|
|
|
pOut->resourceType = ADDR_RSRC_TEX_2D;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// The output may get changed for volume(3D) texture resource in future
|
|
|
|
|
pOut->resourceType = pIn->resourceType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ADDR_ASSERT(bpp >= 8u);
|
|
|
|
|
UINT_64 minSizeAlignInElement = Max(minSizeAlign / (bpp >> 3), 1u);
|
|
|
|
|
|
|
|
|
|
if (IsTex1d(pOut->resourceType))
|
|
|
|
|
{
|
|
|
|
|
pOut->swizzleMode = ADDR_SW_LINEAR;
|
|
|
|
|
pOut->validBlockSet.value = AddrBlockSetLinear;
|
|
|
|
|
pOut->canXor = FALSE;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ADDR2_BLOCK_SET blockSet;
|
|
|
|
|
blockSet.value = 0;
|
|
|
|
|
|
|
|
|
|
AddrSwType swType = ADDR_SW_S;
|
|
|
|
|
|
|
|
|
|
// prt Xor and non-xor will have less height align requirement for stereo surface
|
|
|
|
|
BOOL_32 prtXor = (pIn->flags.prt || pIn->flags.qbStereo) && (pIn->noXor == FALSE);
|
|
|
|
|
BOOL_32 displayResource = FALSE;
|
|
|
|
|
|
|
|
|
|
pOut->canXor = (pIn->flags.prt == FALSE) && (pIn->noXor == FALSE);
|
|
|
|
|
|
|
|
|
|
// Filter out improper swType and blockSet by HW restriction
|
|
|
|
|
if (pIn->flags.fmask || pIn->flags.depth || pIn->flags.stencil)
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT(IsTex2d(pOut->resourceType));
|
|
|
|
|
blockSet.value = AddrBlockSetMacro;
|
|
|
|
|
swType = ADDR_SW_Z;
|
|
|
|
|
|
|
|
|
|
if (pIn->flags.depth && pIn->flags.texture)
|
|
|
|
|
{
|
|
|
|
|
if (((bpp == 16) && (numFrags >= 4)) ||
|
|
|
|
|
((bpp == 32) && (numFrags >= 2)))
|
|
|
|
|
{
|
|
|
|
|
// When _X/_T swizzle mode was used for MSAA depth texture, TC will get zplane
|
|
|
|
|
// equation from wrong address within memory range a tile covered and use the
|
|
|
|
|
// garbage data for compressed Z reading which finally leads to corruption.
|
|
|
|
|
pOut->canXor = FALSE;
|
|
|
|
|
prtXor = FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (ElemLib::IsBlockCompressed(pIn->format))
|
|
|
|
|
{
|
|
|
|
|
// block compressed formats (BCx, ASTC, ETC2) must be either S or D modes. Not sure
|
|
|
|
|
// under what circumstances "_D" would be appropriate as these formats are not
|
|
|
|
|
// displayable.
|
|
|
|
|
blockSet.value = AddrBlockSetMacro;
|
|
|
|
|
|
|
|
|
|
// This isn't to be used as texture and caller doesn't allow macro tiled.
|
|
|
|
|
if ((pIn->flags.texture == FALSE) &&
|
|
|
|
|
(pIn->forbiddenBlock.macro4KB && pIn->forbiddenBlock.macro64KB))
|
|
|
|
|
{
|
|
|
|
|
blockSet.value |= AddrBlockSetLinear;
|
|
|
|
|
}
|
|
|
|
|
swType = ADDR_SW_D;
|
|
|
|
|
}
|
|
|
|
|
else if (ElemLib::IsMacroPixelPacked(pIn->format))
|
|
|
|
|
{
|
|
|
|
|
// macro pixel packed formats (BG_RG, GB_GR) does not support the Z modes. Its not
|
|
|
|
|
// clear under what circumstances the D or R modes would be appropriate since
|
|
|
|
|
// these formats are not displayable.
|
|
|
|
|
blockSet.value = AddrBlockSetLinear | AddrBlockSetMacro;
|
|
|
|
|
swType = ADDR_SW_S;
|
|
|
|
|
}
|
|
|
|
|
else if (IsTex3d(pOut->resourceType))
|
|
|
|
|
{
|
|
|
|
|
blockSet.value = AddrBlockSetLinear | AddrBlockSetMacro;
|
|
|
|
|
|
|
|
|
|
if (pIn->flags.prt)
|
|
|
|
|
{
|
|
|
|
|
// PRT cannot use SW_D which gives an unexpected block dimension
|
|
|
|
|
swType = ADDR_SW_Z;
|
|
|
|
|
}
|
|
|
|
|
else if ((numMipLevels > 1) && (slice >= width) && (slice >= height))
|
|
|
|
|
{
|
|
|
|
|
// When depth (Z) is the maximum dimension then must use one of the SW_*_S
|
|
|
|
|
// or SW_*_Z modes if mipmapping is desired on a 3D surface
|
|
|
|
|
swType = ADDR_SW_Z;
|
|
|
|
|
}
|
|
|
|
|
else if (pIn->flags.color)
|
|
|
|
|
{
|
|
|
|
|
swType = ADDR_SW_D;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
swType = ADDR_SW_Z;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
swType = ((pIn->flags.display == TRUE) ||
|
|
|
|
|
(pIn->flags.overlay == TRUE) ||
|
|
|
|
|
(pIn->bpp == 128)) ? ADDR_SW_D : ADDR_SW_S;
|
|
|
|
|
|
|
|
|
|
if (numMipLevels > 1)
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT(numFrags == 1);
|
|
|
|
|
blockSet.value = AddrBlockSetLinear | AddrBlockSetMacro;
|
|
|
|
|
}
|
|
|
|
|
else if ((numFrags > 1) || (numSamples > 1))
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT(IsTex2d(pOut->resourceType));
|
|
|
|
|
blockSet.value = AddrBlockSetMacro;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT(IsTex2d(pOut->resourceType));
|
|
|
|
|
blockSet.value = AddrBlockSetLinear | AddrBlockSetMicro | AddrBlockSetMacro;
|
|
|
|
|
|
|
|
|
|
displayResource = pIn->flags.rotated || pIn->flags.display;
|
|
|
|
|
|
|
|
|
|
if (displayResource)
|
|
|
|
|
{
|
|
|
|
|
swType = pIn->flags.rotated ? ADDR_SW_R : ADDR_SW_D;
|
|
|
|
|
|
|
|
|
|
if (pIn->bpp > 64)
|
|
|
|
|
{
|
|
|
|
|
blockSet.value = 0;
|
|
|
|
|
}
|
|
|
|
|
else if (m_settings.isDce12)
|
|
|
|
|
{
|
|
|
|
|
if (pIn->bpp != 32)
|
|
|
|
|
{
|
|
|
|
|
blockSet.micro = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DCE12 does not support display surface to be _T swizzle mode
|
|
|
|
|
prtXor = FALSE;
|
|
|
|
|
}
|
2017-02-27 22:25:43 +01:00
|
|
|
else if (m_settings.isDcn1)
|
|
|
|
|
{
|
|
|
|
|
// _R is not supported by Dcn1
|
|
|
|
|
if (pIn->bpp == 64)
|
|
|
|
|
{
|
|
|
|
|
swType = ADDR_SW_D;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
swType = ADDR_SW_S;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
blockSet.micro = FALSE;
|
|
|
|
|
}
|
2017-02-27 22:25:44 +01:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ADDR_NOT_IMPLEMENTED();
|
|
|
|
|
returnCode = ADDR_NOTSUPPORTED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((numFrags > 1) &&
|
|
|
|
|
(GetBlockSize(ADDR_SW_4KB) < (m_pipeInterleaveBytes * numFrags)))
|
|
|
|
|
{
|
|
|
|
|
// MSAA surface must have blk_bytes/pipe_interleave >= num_samples
|
|
|
|
|
blockSet.macro4KB = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pIn->flags.prt)
|
|
|
|
|
{
|
|
|
|
|
blockSet.value &= AddrBlockSetMacro64KB;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Apply customized forbidden setting
|
|
|
|
|
blockSet.value &= ~pIn->forbiddenBlock.value;
|
|
|
|
|
|
|
|
|
|
if (pIn->maxAlign > 0)
|
|
|
|
|
{
|
|
|
|
|
if (pIn->maxAlign < GetBlockSize(ADDR_SW_64KB))
|
|
|
|
|
{
|
|
|
|
|
blockSet.macro64KB = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pIn->maxAlign < GetBlockSize(ADDR_SW_4KB))
|
|
|
|
|
{
|
|
|
|
|
blockSet.macro4KB = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pIn->maxAlign < GetBlockSize(ADDR_SW_256B))
|
|
|
|
|
{
|
|
|
|
|
blockSet.micro = FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Dim3d blkAlign[AddrBlockMaxTiledType] = {{0}, {0}, {0}};
|
|
|
|
|
Dim3d paddedDim[AddrBlockMaxTiledType] = {{0}, {0}, {0}};
|
|
|
|
|
UINT_64 padSize[AddrBlockMaxTiledType] = {0};
|
|
|
|
|
|
|
|
|
|
if (blockSet.micro)
|
|
|
|
|
{
|
|
|
|
|
returnCode = ComputeBlockDimensionForSurf(&blkAlign[AddrBlockMicro].w,
|
|
|
|
|
&blkAlign[AddrBlockMicro].h,
|
|
|
|
|
&blkAlign[AddrBlockMicro].d,
|
|
|
|
|
bpp,
|
|
|
|
|
numFrags,
|
|
|
|
|
pOut->resourceType,
|
|
|
|
|
ADDR_SW_256B);
|
|
|
|
|
|
|
|
|
|
if (returnCode == ADDR_OK)
|
|
|
|
|
{
|
|
|
|
|
if (displayResource)
|
|
|
|
|
{
|
|
|
|
|
blkAlign[AddrBlockMicro].w = PowTwoAlign(blkAlign[AddrBlockMicro].w, 32);
|
|
|
|
|
}
|
|
|
|
|
else if ((blkAlign[AddrBlockMicro].w >= width) && (blkAlign[AddrBlockMicro].h >= height) &&
|
|
|
|
|
(minSizeAlign <= GetBlockSize(ADDR_SW_256B)))
|
|
|
|
|
{
|
|
|
|
|
// If one 256B block can contain the surface, don't bother bigger block type
|
|
|
|
|
blockSet.macro4KB = FALSE;
|
|
|
|
|
blockSet.macro64KB = FALSE;
|
|
|
|
|
blockSet.var = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
padSize[AddrBlockMicro] = ComputePadSize(&blkAlign[AddrBlockMicro], width, height,
|
|
|
|
|
slice, &paddedDim[AddrBlockMicro]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((returnCode == ADDR_OK) && blockSet.macro4KB)
|
|
|
|
|
{
|
|
|
|
|
returnCode = ComputeBlockDimensionForSurf(&blkAlign[AddrBlock4KB].w,
|
|
|
|
|
&blkAlign[AddrBlock4KB].h,
|
|
|
|
|
&blkAlign[AddrBlock4KB].d,
|
|
|
|
|
bpp,
|
|
|
|
|
numFrags,
|
|
|
|
|
pOut->resourceType,
|
|
|
|
|
ADDR_SW_4KB);
|
|
|
|
|
|
|
|
|
|
if (returnCode == ADDR_OK)
|
|
|
|
|
{
|
|
|
|
|
if (displayResource)
|
|
|
|
|
{
|
|
|
|
|
blkAlign[AddrBlock4KB].w = PowTwoAlign(blkAlign[AddrBlock4KB].w, 32);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
padSize[AddrBlock4KB] = ComputePadSize(&blkAlign[AddrBlock4KB], width, height,
|
|
|
|
|
slice, &paddedDim[AddrBlock4KB]);
|
|
|
|
|
|
|
|
|
|
ADDR_ASSERT(padSize[AddrBlock4KB] >= padSize[AddrBlockMicro]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((returnCode == ADDR_OK) && blockSet.macro64KB)
|
|
|
|
|
{
|
|
|
|
|
returnCode = ComputeBlockDimensionForSurf(&blkAlign[AddrBlock64KB].w,
|
|
|
|
|
&blkAlign[AddrBlock64KB].h,
|
|
|
|
|
&blkAlign[AddrBlock64KB].d,
|
|
|
|
|
bpp,
|
|
|
|
|
numFrags,
|
|
|
|
|
pOut->resourceType,
|
|
|
|
|
ADDR_SW_64KB);
|
|
|
|
|
|
|
|
|
|
if (returnCode == ADDR_OK)
|
|
|
|
|
{
|
|
|
|
|
if (displayResource)
|
|
|
|
|
{
|
|
|
|
|
blkAlign[AddrBlock64KB].w = PowTwoAlign(blkAlign[AddrBlock64KB].w, 32);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
padSize[AddrBlock64KB] = ComputePadSize(&blkAlign[AddrBlock64KB], width, height,
|
|
|
|
|
slice, &paddedDim[AddrBlock64KB]);
|
|
|
|
|
|
|
|
|
|
ADDR_ASSERT(padSize[AddrBlock64KB] >= padSize[AddrBlock4KB]);
|
|
|
|
|
ADDR_ASSERT(padSize[AddrBlock64KB] >= padSize[AddrBlockMicro]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (returnCode == ADDR_OK)
|
|
|
|
|
{
|
|
|
|
|
for (UINT_32 i = AddrBlockMicro; i < AddrBlockMaxTiledType; i++)
|
|
|
|
|
{
|
|
|
|
|
padSize[i] = PowTwoAlign(padSize[i], minSizeAlignInElement);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Use minimum block type which meets all conditions above if flag minimizeAlign was set
|
|
|
|
|
if (pIn->flags.minimizeAlign)
|
|
|
|
|
{
|
|
|
|
|
// If padded size of 64KB block is larger than padded size of 256B block or 4KB
|
|
|
|
|
// block, filter out 64KB block from candidate list
|
|
|
|
|
if (blockSet.macro64KB &&
|
|
|
|
|
((blockSet.micro && (padSize[AddrBlockMicro] < padSize[AddrBlock64KB])) ||
|
|
|
|
|
(blockSet.macro4KB && (padSize[AddrBlock4KB] < padSize[AddrBlock64KB]))))
|
|
|
|
|
{
|
|
|
|
|
blockSet.macro64KB = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If padded size of 4KB block is larger than padded size of 256B block,
|
|
|
|
|
// filter out 4KB block from candidate list
|
|
|
|
|
if (blockSet.macro4KB &&
|
|
|
|
|
blockSet.micro &&
|
|
|
|
|
(padSize[AddrBlockMicro] < padSize[AddrBlock4KB]))
|
|
|
|
|
{
|
|
|
|
|
blockSet.macro4KB = FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Filter out 64KB/4KB block if a smaller block type has 2/3 or less memory footprint
|
|
|
|
|
else if (pIn->flags.opt4space)
|
|
|
|
|
{
|
|
|
|
|
UINT_64 threshold = blockSet.micro ? padSize[AddrBlockMicro] :
|
|
|
|
|
(blockSet.macro4KB ? padSize[AddrBlock4KB] : padSize[AddrBlock64KB]);
|
|
|
|
|
|
|
|
|
|
threshold += threshold >> 1;
|
|
|
|
|
|
|
|
|
|
if (blockSet.macro64KB && (padSize[AddrBlock64KB] > threshold))
|
|
|
|
|
{
|
|
|
|
|
blockSet.macro64KB = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (blockSet.macro4KB && (padSize[AddrBlock4KB] > threshold))
|
|
|
|
|
{
|
|
|
|
|
blockSet.macro4KB = FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (blockSet.macro64KB &&
|
|
|
|
|
(padSize[AddrBlock64KB] >= static_cast<UINT_64>(width) * height * slice * 2) &&
|
|
|
|
|
((blockSet.value & ~AddrBlockSetMacro64KB) != 0))
|
|
|
|
|
{
|
|
|
|
|
// If 64KB block waste more than half memory on padding, filter it out from
|
|
|
|
|
// candidate list when it is not the only choice left
|
|
|
|
|
blockSet.macro64KB = FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (blockSet.value == 0)
|
|
|
|
|
{
|
|
|
|
|
// Bad things happen, client will not get any useful information from AddrLib.
|
|
|
|
|
// Maybe we should fill in some output earlier instead of outputing nothing?
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
returnCode = ADDR_INVALIDPARAMS;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pOut->validBlockSet = blockSet;
|
|
|
|
|
pOut->canXor = pOut->canXor &&
|
|
|
|
|
(blockSet.macro4KB || blockSet.macro64KB || blockSet.var);
|
|
|
|
|
|
|
|
|
|
if (blockSet.macro64KB || blockSet.macro4KB)
|
|
|
|
|
{
|
|
|
|
|
if (swType == ADDR_SW_Z)
|
|
|
|
|
{
|
|
|
|
|
pOut->swizzleMode = blockSet.macro64KB ? ADDR_SW_64KB_Z : ADDR_SW_4KB_Z;
|
|
|
|
|
}
|
|
|
|
|
else if (swType == ADDR_SW_S)
|
|
|
|
|
{
|
|
|
|
|
pOut->swizzleMode = blockSet.macro64KB ? ADDR_SW_64KB_S : ADDR_SW_4KB_S;
|
|
|
|
|
}
|
|
|
|
|
else if (swType == ADDR_SW_D)
|
|
|
|
|
{
|
|
|
|
|
pOut->swizzleMode = blockSet.macro64KB ? ADDR_SW_64KB_D : ADDR_SW_4KB_D;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT(swType == ADDR_SW_R);
|
|
|
|
|
pOut->swizzleMode = blockSet.macro64KB ? ADDR_SW_64KB_R : ADDR_SW_4KB_R;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (prtXor && blockSet.macro64KB)
|
|
|
|
|
{
|
|
|
|
|
// Client wants PRTXOR, give back _T swizzle mode if 64KB is available
|
|
|
|
|
const UINT_32 prtGap = ADDR_SW_64KB_Z_T - ADDR_SW_64KB_Z;
|
|
|
|
|
pOut->swizzleMode = static_cast<AddrSwizzleMode>(pOut->swizzleMode + prtGap);
|
|
|
|
|
}
|
|
|
|
|
else if (pOut->canXor)
|
|
|
|
|
{
|
|
|
|
|
// Client wants XOR and this is allowed, return XOR version swizzle mode
|
|
|
|
|
const UINT_32 xorGap = ADDR_SW_4KB_Z_X - ADDR_SW_4KB_Z;
|
|
|
|
|
pOut->swizzleMode = static_cast<AddrSwizzleMode>(pOut->swizzleMode + xorGap);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (blockSet.micro)
|
|
|
|
|
{
|
|
|
|
|
if (swType == ADDR_SW_S)
|
|
|
|
|
{
|
|
|
|
|
pOut->swizzleMode = ADDR_SW_256B_S;
|
|
|
|
|
}
|
|
|
|
|
else if (swType == ADDR_SW_D)
|
|
|
|
|
{
|
|
|
|
|
pOut->swizzleMode = ADDR_SW_256B_D;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT(swType == ADDR_SW_R);
|
|
|
|
|
pOut->swizzleMode = ADDR_SW_256B_R;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (blockSet.linear)
|
|
|
|
|
{
|
|
|
|
|
// Fall into this branch doesn't mean linear is suitable, only no other choices!
|
|
|
|
|
pOut->swizzleMode = ADDR_SW_LINEAR;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT(blockSet.var);
|
|
|
|
|
|
|
|
|
|
// Designer consider VAR swizzle mode is usless for most cases
|
|
|
|
|
ADDR_UNHANDLED_CASE();
|
|
|
|
|
|
|
|
|
|
returnCode = ADDR_NOTSUPPORTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if DEBUG
|
|
|
|
|
// Post sanity check, at least AddrLib should accept the output generated by its own
|
|
|
|
|
if (pOut->swizzleMode != ADDR_SW_LINEAR)
|
|
|
|
|
{
|
|
|
|
|
ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0};
|
|
|
|
|
localIn.flags = pIn->flags;
|
|
|
|
|
localIn.swizzleMode = pOut->swizzleMode;
|
|
|
|
|
localIn.resourceType = pOut->resourceType;
|
|
|
|
|
localIn.format = pIn->format;
|
|
|
|
|
localIn.bpp = bpp;
|
|
|
|
|
localIn.width = width;
|
|
|
|
|
localIn.height = height;
|
|
|
|
|
localIn.numSlices = slice;
|
|
|
|
|
localIn.numMipLevels = numMipLevels;
|
|
|
|
|
localIn.numSamples = numSamples;
|
|
|
|
|
localIn.numFrags = numFrags;
|
|
|
|
|
|
|
|
|
|
HwlComputeSurfaceInfoSanityCheck(&localIn);
|
|
|
|
|
|
|
|
|
|
// TODO : check all valid block type available in validBlockSet?
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return returnCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
* Gfx9Lib::ComputeStereoInfo
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Compute height alignment and right eye pipeBankXor for stereo surface
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* Error code
|
|
|
|
|
*
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::ComputeStereoInfo(
|
|
|
|
|
const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,
|
|
|
|
|
ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut,
|
|
|
|
|
UINT_32* pHeightAlign
|
|
|
|
|
) const
|
|
|
|
|
{
|
|
|
|
|
ADDR_E_RETURNCODE returnCode = ADDR_OK;
|
|
|
|
|
|
|
|
|
|
UINT_32 eqIndex = HwlGetEquationIndex(pIn, pOut);
|
|
|
|
|
|
|
|
|
|
if (eqIndex < m_numEquations)
|
|
|
|
|
{
|
|
|
|
|
if (IsXor(pIn->swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
const UINT_32 blkSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);
|
|
|
|
|
const UINT_32 numPipeBits = GetPipeXorBits(blkSizeLog2);
|
|
|
|
|
const UINT_32 numBankBits = GetBankXorBits(blkSizeLog2);
|
|
|
|
|
const UINT_32 bppLog2 = Log2(pIn->bpp >> 3);
|
|
|
|
|
const UINT_32 maxYCoordBlock256 = Log2(Block256_2d[bppLog2].h) - 1;
|
|
|
|
|
const ADDR_EQUATION *pEqToCheck = &m_equationTable[eqIndex];
|
|
|
|
|
|
|
|
|
|
ADDR_ASSERT(maxYCoordBlock256 ==
|
|
|
|
|
GetMaxValidChannelIndex(&pEqToCheck->addr[0], GetBlockSizeLog2(ADDR_SW_256B), 1));
|
|
|
|
|
|
|
|
|
|
const UINT_32 maxYCoordInBaseEquation =
|
|
|
|
|
(blkSizeLog2 - GetBlockSizeLog2(ADDR_SW_256B)) / 2 + maxYCoordBlock256;
|
|
|
|
|
|
|
|
|
|
ADDR_ASSERT(maxYCoordInBaseEquation ==
|
|
|
|
|
GetMaxValidChannelIndex(&pEqToCheck->addr[0], blkSizeLog2, 1));
|
|
|
|
|
|
|
|
|
|
const UINT_32 maxYCoordInPipeXor = (numPipeBits == 0) ? 0 : maxYCoordBlock256 + numPipeBits;
|
|
|
|
|
|
|
|
|
|
ADDR_ASSERT(maxYCoordInPipeXor ==
|
|
|
|
|
GetMaxValidChannelIndex(&pEqToCheck->xor1[m_pipeInterleaveLog2], numPipeBits, 1));
|
|
|
|
|
|
|
|
|
|
const UINT_32 maxYCoordInBankXor = (numBankBits == 0) ?
|
|
|
|
|
0 : maxYCoordBlock256 + (numPipeBits + 1) / 2 + numBankBits;
|
|
|
|
|
|
|
|
|
|
ADDR_ASSERT(maxYCoordInBankXor ==
|
|
|
|
|
GetMaxValidChannelIndex(&pEqToCheck->xor1[m_pipeInterleaveLog2 + numPipeBits], numBankBits, 1));
|
|
|
|
|
|
|
|
|
|
const UINT_32 maxYCoordInPipeBankXor = Max(maxYCoordInPipeXor, maxYCoordInBankXor);
|
|
|
|
|
|
|
|
|
|
if (maxYCoordInPipeBankXor > maxYCoordInBaseEquation)
|
|
|
|
|
{
|
|
|
|
|
*pHeightAlign = 1u << maxYCoordInPipeBankXor;
|
|
|
|
|
|
|
|
|
|
if (pOut->pStereoInfo != NULL)
|
|
|
|
|
{
|
|
|
|
|
pOut->pStereoInfo->rightSwizzle = 0;
|
|
|
|
|
|
|
|
|
|
if ((PowTwoAlign(pIn->height, *pHeightAlign) % (*pHeightAlign * 2)) != 0)
|
|
|
|
|
{
|
|
|
|
|
if (maxYCoordInPipeXor == maxYCoordInPipeBankXor)
|
|
|
|
|
{
|
|
|
|
|
pOut->pStereoInfo->rightSwizzle |= (1u << 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (maxYCoordInBankXor == maxYCoordInPipeBankXor)
|
|
|
|
|
{
|
|
|
|
|
pOut->pStereoInfo->rightSwizzle |=
|
|
|
|
|
1u << ((numPipeBits % 2) ? numPipeBits : numPipeBits + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ADDR_ASSERT(pOut->pStereoInfo->rightSwizzle ==
|
|
|
|
|
GetCoordActiveMask(&pEqToCheck->xor1[m_pipeInterleaveLog2],
|
|
|
|
|
numPipeBits + numBankBits, 1, maxYCoordInPipeBankXor));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
returnCode = ADDR_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return returnCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
* Gfx9Lib::HwlComputeSurfaceInfoTiled
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Internal function to calculate alignment for tiled surface
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* ADDR_E_RETURNCODE
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceInfoTiled(
|
|
|
|
|
const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
|
|
|
|
|
ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
|
|
|
|
|
) const
|
|
|
|
|
{
|
|
|
|
|
ADDR_E_RETURNCODE returnCode = ComputeBlockDimensionForSurf(&pOut->blockWidth,
|
|
|
|
|
&pOut->blockHeight,
|
|
|
|
|
&pOut->blockSlices,
|
|
|
|
|
pIn->bpp,
|
|
|
|
|
pIn->numFrags,
|
|
|
|
|
pIn->resourceType,
|
|
|
|
|
pIn->swizzleMode);
|
|
|
|
|
|
|
|
|
|
if (returnCode == ADDR_OK)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 pitchAlignInElement = pOut->blockWidth;
|
|
|
|
|
|
|
|
|
|
if ((IsTex2d(pIn->resourceType) == TRUE) &&
|
|
|
|
|
(pIn->flags.display || pIn->flags.rotated) &&
|
|
|
|
|
(pIn->numMipLevels <= 1) &&
|
|
|
|
|
(pIn->numSamples <= 1) &&
|
|
|
|
|
(pIn->numFrags <= 1))
|
|
|
|
|
{
|
|
|
|
|
// Display engine needs pitch align to be at least 32 pixels.
|
|
|
|
|
pitchAlignInElement = PowTwoAlign(pitchAlignInElement, 32);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pOut->pitch = PowTwoAlign(pIn->width, pitchAlignInElement);
|
|
|
|
|
|
|
|
|
|
if ((pIn->numMipLevels <= 1) && (pIn->pitchInElement > 0))
|
|
|
|
|
{
|
|
|
|
|
if ((pIn->pitchInElement % pitchAlignInElement) != 0)
|
|
|
|
|
{
|
|
|
|
|
returnCode = ADDR_INVALIDPARAMS;
|
|
|
|
|
}
|
|
|
|
|
else if (pIn->pitchInElement < pOut->pitch)
|
|
|
|
|
{
|
|
|
|
|
returnCode = ADDR_INVALIDPARAMS;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pOut->pitch = pIn->pitchInElement;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UINT_32 heightAlign = 0;
|
|
|
|
|
|
|
|
|
|
if (pIn->flags.qbStereo)
|
|
|
|
|
{
|
|
|
|
|
returnCode = ComputeStereoInfo(pIn, pOut, &heightAlign);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (returnCode == ADDR_OK)
|
|
|
|
|
{
|
|
|
|
|
pOut->height = PowTwoAlign(pIn->height, pOut->blockHeight);
|
|
|
|
|
|
|
|
|
|
if (heightAlign > 1)
|
|
|
|
|
{
|
|
|
|
|
pOut->height = PowTwoAlign(pOut->height, heightAlign);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pOut->numSlices = PowTwoAlign(pIn->numSlices, pOut->blockSlices);
|
|
|
|
|
|
|
|
|
|
pOut->epitchIsHeight = FALSE;
|
|
|
|
|
pOut->mipChainInTail = FALSE;
|
|
|
|
|
|
|
|
|
|
pOut->mipChainPitch = pOut->pitch;
|
|
|
|
|
pOut->mipChainHeight = pOut->height;
|
|
|
|
|
pOut->mipChainSlice = pOut->numSlices;
|
|
|
|
|
|
|
|
|
|
if (pIn->numMipLevels > 1)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 numMipLevel;
|
|
|
|
|
ADDR2_MIP_INFO *pMipInfo;
|
|
|
|
|
ADDR2_MIP_INFO mipInfo[4];
|
|
|
|
|
|
|
|
|
|
if (pOut->pMipInfo != NULL)
|
|
|
|
|
{
|
|
|
|
|
pMipInfo = pOut->pMipInfo;
|
|
|
|
|
numMipLevel = pIn->numMipLevels;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pMipInfo = mipInfo;
|
|
|
|
|
numMipLevel = Min(pIn->numMipLevels, 4u);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UINT_32 endingMip = GetMipChainInfo(pIn->resourceType,
|
|
|
|
|
pIn->swizzleMode,
|
|
|
|
|
pIn->bpp,
|
|
|
|
|
pIn->width,
|
|
|
|
|
pIn->height,
|
|
|
|
|
pIn->numSlices,
|
|
|
|
|
pOut->blockWidth,
|
|
|
|
|
pOut->blockHeight,
|
|
|
|
|
pOut->blockSlices,
|
|
|
|
|
numMipLevel,
|
|
|
|
|
pMipInfo);
|
|
|
|
|
|
|
|
|
|
if (endingMip == 0)
|
|
|
|
|
{
|
|
|
|
|
pOut->epitchIsHeight = TRUE;
|
|
|
|
|
pOut->pitch = pMipInfo[0].pitch;
|
|
|
|
|
pOut->height = pMipInfo[0].height;
|
|
|
|
|
pOut->numSlices = pMipInfo[0].depth;
|
|
|
|
|
pOut->mipChainInTail = TRUE;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UINT_32 mip0WidthInBlk = pOut->pitch / pOut->blockWidth;
|
|
|
|
|
UINT_32 mip0HeightInBlk = pOut->height / pOut->blockHeight;
|
|
|
|
|
|
|
|
|
|
AddrMajorMode majorMode = GetMajorMode(pIn->resourceType,
|
|
|
|
|
pIn->swizzleMode,
|
|
|
|
|
mip0WidthInBlk,
|
|
|
|
|
mip0HeightInBlk,
|
|
|
|
|
pOut->numSlices / pOut->blockSlices);
|
|
|
|
|
if (majorMode == ADDR_MAJOR_Y)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 mip1WidthInBlk = RoundHalf(mip0WidthInBlk);
|
|
|
|
|
|
|
|
|
|
if ((mip1WidthInBlk == 1) && (endingMip > 2))
|
|
|
|
|
{
|
|
|
|
|
mip1WidthInBlk++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pOut->mipChainPitch += (mip1WidthInBlk * pOut->blockWidth);
|
|
|
|
|
|
|
|
|
|
pOut->epitchIsHeight = FALSE;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UINT_32 mip1HeightInBlk = RoundHalf(mip0HeightInBlk);
|
|
|
|
|
|
|
|
|
|
if ((mip1HeightInBlk == 1) && (endingMip > 2))
|
|
|
|
|
{
|
|
|
|
|
mip1HeightInBlk++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pOut->mipChainHeight += (mip1HeightInBlk * pOut->blockHeight);
|
|
|
|
|
|
|
|
|
|
pOut->epitchIsHeight = TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pOut->pMipInfo != NULL)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3);
|
|
|
|
|
|
|
|
|
|
for (UINT_32 i = 0; i < pIn->numMipLevels; i++)
|
|
|
|
|
{
|
|
|
|
|
Dim3d mipStartPos = {0};
|
|
|
|
|
UINT_32 mipTailOffsetInBytes = 0;
|
|
|
|
|
|
|
|
|
|
mipStartPos = GetMipStartPos(pIn->resourceType,
|
|
|
|
|
pIn->swizzleMode,
|
|
|
|
|
pOut->pitch,
|
|
|
|
|
pOut->height,
|
|
|
|
|
pOut->numSlices,
|
|
|
|
|
pOut->blockWidth,
|
|
|
|
|
pOut->blockHeight,
|
|
|
|
|
pOut->blockSlices,
|
|
|
|
|
i,
|
|
|
|
|
elementBytesLog2,
|
|
|
|
|
&mipTailOffsetInBytes);
|
|
|
|
|
|
|
|
|
|
UINT_32 pitchInBlock =
|
|
|
|
|
pOut->mipChainPitch / pOut->blockWidth;
|
|
|
|
|
UINT_32 sliceInBlock =
|
|
|
|
|
(pOut->mipChainHeight / pOut->blockHeight) * pitchInBlock;
|
|
|
|
|
UINT_64 blockIndex =
|
|
|
|
|
mipStartPos.d * sliceInBlock + mipStartPos.h * pitchInBlock + mipStartPos.w;
|
|
|
|
|
UINT_64 macroBlockOffset =
|
|
|
|
|
blockIndex << GetBlockSizeLog2(pIn->swizzleMode);
|
|
|
|
|
|
|
|
|
|
pMipInfo[i].macroBlockOffset = macroBlockOffset;
|
|
|
|
|
pMipInfo[i].mipTailOffset = mipTailOffsetInBytes;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (pOut->pMipInfo != NULL)
|
|
|
|
|
{
|
|
|
|
|
pOut->pMipInfo[0].pitch = pOut->pitch;
|
|
|
|
|
pOut->pMipInfo[0].height = pOut->height;
|
|
|
|
|
pOut->pMipInfo[0].depth = IsTex3d(pIn->resourceType)? pOut->numSlices : 1;
|
|
|
|
|
pOut->pMipInfo[0].offset = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pOut->sliceSize = static_cast<UINT_64>(pOut->mipChainPitch) * pOut->mipChainHeight *
|
|
|
|
|
(pIn->bpp >> 3) * pIn->numFrags;
|
|
|
|
|
pOut->surfSize = pOut->sliceSize * pOut->mipChainSlice;
|
|
|
|
|
pOut->baseAlign = HwlComputeSurfaceBaseAlign(pIn->swizzleMode);
|
|
|
|
|
|
|
|
|
|
if (pIn->flags.prt)
|
|
|
|
|
{
|
|
|
|
|
pOut->baseAlign = Max(pOut->baseAlign, PrtAlignment);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return returnCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
* Gfx9Lib::GetMipChainInfo
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Internal function to get out information about mip chain
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* Smaller value between Id of first mip fitted in mip tail and max Id of mip being created
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
UINT_32 Gfx9Lib::GetMipChainInfo(
|
|
|
|
|
AddrResourceType resourceType,
|
|
|
|
|
AddrSwizzleMode swizzleMode,
|
|
|
|
|
UINT_32 bpp,
|
|
|
|
|
UINT_32 mip0Width,
|
|
|
|
|
UINT_32 mip0Height,
|
|
|
|
|
UINT_32 mip0Depth,
|
|
|
|
|
UINT_32 blockWidth,
|
|
|
|
|
UINT_32 blockHeight,
|
|
|
|
|
UINT_32 blockDepth,
|
|
|
|
|
UINT_32 numMipLevel,
|
|
|
|
|
ADDR2_MIP_INFO* pMipInfo) const
|
|
|
|
|
{
|
|
|
|
|
const Dim3d tailMaxDim =
|
|
|
|
|
GetMipTailDim(resourceType, swizzleMode, blockWidth, blockHeight, blockDepth);
|
|
|
|
|
|
|
|
|
|
UINT_32 mipPitch = mip0Width;
|
|
|
|
|
UINT_32 mipHeight = mip0Height;
|
|
|
|
|
UINT_32 mipDepth = IsTex3d(resourceType) ? mip0Depth : 1;
|
|
|
|
|
UINT_32 offset = 0;
|
|
|
|
|
UINT_32 endingMip = numMipLevel - 1;
|
|
|
|
|
BOOL_32 inTail = FALSE;
|
|
|
|
|
BOOL_32 finalDim = FALSE;
|
|
|
|
|
|
|
|
|
|
BOOL_32 is3dThick = IsThick(resourceType, swizzleMode);
|
|
|
|
|
BOOL_32 is3dThin = IsTex3d(resourceType) && (is3dThick == FALSE);
|
|
|
|
|
|
|
|
|
|
for (UINT_32 mipId = 0; mipId < numMipLevel; mipId++)
|
|
|
|
|
{
|
|
|
|
|
if (inTail)
|
|
|
|
|
{
|
|
|
|
|
if (finalDim == FALSE)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 mipSize;
|
|
|
|
|
|
|
|
|
|
if (is3dThick)
|
|
|
|
|
{
|
|
|
|
|
mipSize = mipPitch * mipHeight * mipDepth * (bpp >> 3);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mipSize = mipPitch * mipHeight * (bpp >> 3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mipSize <= 256)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 index = Log2(bpp >> 3);
|
|
|
|
|
|
|
|
|
|
if (is3dThick)
|
|
|
|
|
{
|
|
|
|
|
mipPitch = Block256_3dZ[index].w;
|
|
|
|
|
mipHeight = Block256_3dZ[index].h;
|
|
|
|
|
mipDepth = Block256_3dZ[index].d;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mipPitch = Block256_2d[index].w;
|
|
|
|
|
mipHeight = Block256_2d[index].h;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
finalDim = TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
inTail = IsInMipTail(resourceType, swizzleMode, tailMaxDim,
|
|
|
|
|
mipPitch, mipHeight, mipDepth);
|
|
|
|
|
|
|
|
|
|
if (inTail)
|
|
|
|
|
{
|
|
|
|
|
endingMip = mipId;
|
|
|
|
|
|
|
|
|
|
mipPitch = tailMaxDim.w;
|
|
|
|
|
mipHeight = tailMaxDim.h;
|
|
|
|
|
|
|
|
|
|
if (is3dThick)
|
|
|
|
|
{
|
|
|
|
|
mipDepth = tailMaxDim.d;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mipPitch = PowTwoAlign(mipPitch, blockWidth);
|
|
|
|
|
mipHeight = PowTwoAlign(mipHeight, blockHeight);
|
|
|
|
|
|
|
|
|
|
if (is3dThick)
|
|
|
|
|
{
|
|
|
|
|
mipDepth = PowTwoAlign(mipDepth, blockDepth);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pMipInfo[mipId].pitch = mipPitch;
|
|
|
|
|
pMipInfo[mipId].height = mipHeight;
|
|
|
|
|
pMipInfo[mipId].depth = mipDepth;
|
|
|
|
|
pMipInfo[mipId].offset = offset;
|
|
|
|
|
offset += (mipPitch * mipHeight * mipDepth * (bpp >> 3));
|
|
|
|
|
|
|
|
|
|
if (finalDim)
|
|
|
|
|
{
|
|
|
|
|
if (is3dThin)
|
|
|
|
|
{
|
|
|
|
|
mipDepth = Max(mipDepth >> 1, 1u);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mipPitch = Max(mipPitch >> 1, 1u);
|
|
|
|
|
mipHeight = Max(mipHeight >> 1, 1u);
|
|
|
|
|
|
|
|
|
|
if (is3dThick || is3dThin)
|
|
|
|
|
{
|
|
|
|
|
mipDepth = Max(mipDepth >> 1, 1u);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return endingMip;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
* Gfx9Lib::GetMetaMiptailInfo
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Get mip tail coordinate information.
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* N/A
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
VOID Gfx9Lib::GetMetaMiptailInfo(
|
|
|
|
|
ADDR2_META_MIP_INFO* pInfo, ///< [out] output structure to store per mip coord
|
|
|
|
|
Dim3d mipCoord, ///< [in] mip tail base coord
|
|
|
|
|
UINT_32 numMipInTail, ///< [in] number of mips in tail
|
|
|
|
|
Dim3d* pMetaBlkDim ///< [in] meta block width/height/depth
|
|
|
|
|
) const
|
|
|
|
|
{
|
|
|
|
|
BOOL_32 isThick = (pMetaBlkDim->d > 1);
|
|
|
|
|
UINT_32 mipWidth = pMetaBlkDim->w;
|
|
|
|
|
UINT_32 mipHeight = pMetaBlkDim->h >> 1;
|
|
|
|
|
UINT_32 mipDepth = pMetaBlkDim->d;
|
|
|
|
|
UINT_32 minInc;
|
|
|
|
|
|
|
|
|
|
if (isThick)
|
|
|
|
|
{
|
|
|
|
|
minInc = (pMetaBlkDim->h >= 512) ? 128 : ((pMetaBlkDim->h == 256) ? 64 : 32);
|
|
|
|
|
}
|
|
|
|
|
else if (pMetaBlkDim->h >= 1024)
|
|
|
|
|
{
|
|
|
|
|
minInc = 256;
|
|
|
|
|
}
|
|
|
|
|
else if (pMetaBlkDim->h == 512)
|
|
|
|
|
{
|
|
|
|
|
minInc = 128;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
minInc = 64;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UINT_32 blk32MipId = 0xFFFFFFFF;
|
|
|
|
|
|
|
|
|
|
for (UINT_32 mip = 0; mip < numMipInTail; mip++)
|
|
|
|
|
{
|
|
|
|
|
pInfo[mip].inMiptail = TRUE;
|
|
|
|
|
pInfo[mip].startX = mipCoord.w;
|
|
|
|
|
pInfo[mip].startY = mipCoord.h;
|
|
|
|
|
pInfo[mip].startZ = mipCoord.d;
|
|
|
|
|
pInfo[mip].width = mipWidth;
|
|
|
|
|
pInfo[mip].height = mipHeight;
|
|
|
|
|
pInfo[mip].depth = mipDepth;
|
|
|
|
|
|
|
|
|
|
if (mipWidth <= 32)
|
|
|
|
|
{
|
|
|
|
|
if (blk32MipId == 0xFFFFFFFF)
|
|
|
|
|
{
|
|
|
|
|
blk32MipId = mip;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mipCoord.w = pInfo[blk32MipId].startX;
|
|
|
|
|
mipCoord.h = pInfo[blk32MipId].startY;
|
|
|
|
|
mipCoord.d = pInfo[blk32MipId].startZ;
|
|
|
|
|
|
|
|
|
|
switch (mip - blk32MipId)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
mipCoord.w += 32; // 16x16
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
mipCoord.h += 32; // 8x8
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
mipCoord.h += 32; // 4x4
|
|
|
|
|
mipCoord.w += 16;
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
mipCoord.h += 32; // 2x2
|
|
|
|
|
mipCoord.w += 32;
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
mipCoord.h += 32; // 1x1
|
|
|
|
|
mipCoord.w += 48;
|
|
|
|
|
break;
|
|
|
|
|
// The following are for BC/ASTC formats
|
|
|
|
|
case 5:
|
|
|
|
|
mipCoord.h += 48; // 1/2 x 1/2
|
|
|
|
|
break;
|
|
|
|
|
case 6:
|
|
|
|
|
mipCoord.h += 48; // 1/4 x 1/4
|
|
|
|
|
mipCoord.w += 16;
|
|
|
|
|
break;
|
|
|
|
|
case 7:
|
|
|
|
|
mipCoord.h += 48; // 1/8 x 1/8
|
|
|
|
|
mipCoord.w += 32;
|
|
|
|
|
break;
|
|
|
|
|
case 8:
|
|
|
|
|
mipCoord.h += 48; // 1/16 x 1/16
|
|
|
|
|
mipCoord.w += 48;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ADDR_ASSERT_ALWAYS();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mipWidth = ((mip - blk32MipId) == 0) ? 16 : 8;
|
|
|
|
|
mipHeight = mipWidth;
|
|
|
|
|
|
|
|
|
|
if (isThick)
|
|
|
|
|
{
|
|
|
|
|
mipDepth = mipWidth;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (mipWidth <= minInc)
|
|
|
|
|
{
|
|
|
|
|
// if we're below the minimal increment...
|
|
|
|
|
if (isThick)
|
|
|
|
|
{
|
|
|
|
|
// For 3d, just go in z direction
|
|
|
|
|
mipCoord.d += mipDepth;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// For 2d, first go across, then down
|
|
|
|
|
if ((mipWidth * 2) == minInc)
|
|
|
|
|
{
|
|
|
|
|
// if we're 2 mips below, that's when we go back in x, and down in y
|
|
|
|
|
mipCoord.w -= minInc;
|
|
|
|
|
mipCoord.h += minInc;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// otherwise, just go across in x
|
|
|
|
|
mipCoord.w += minInc;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// On even mip, go down, otherwise, go across
|
|
|
|
|
if (mip & 1)
|
|
|
|
|
{
|
|
|
|
|
mipCoord.w += mipWidth;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mipCoord.h += mipHeight;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Divide the width by 2
|
|
|
|
|
mipWidth >>= 1;
|
|
|
|
|
// After the first mip in tail, the mip is always a square
|
|
|
|
|
mipHeight = mipWidth;
|
|
|
|
|
// ...or for 3d, a cube
|
|
|
|
|
if (isThick)
|
|
|
|
|
{
|
|
|
|
|
mipDepth = mipWidth;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
* Gfx9Lib::GetMipStartPos
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Internal function to get out information about mip logical start position
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* logical start position in macro block width/heith/depth of one mip level within one slice
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
Dim3d Gfx9Lib::GetMipStartPos(
|
|
|
|
|
AddrResourceType resourceType,
|
|
|
|
|
AddrSwizzleMode swizzleMode,
|
|
|
|
|
UINT_32 width,
|
|
|
|
|
UINT_32 height,
|
|
|
|
|
UINT_32 depth,
|
|
|
|
|
UINT_32 blockWidth,
|
|
|
|
|
UINT_32 blockHeight,
|
|
|
|
|
UINT_32 blockDepth,
|
|
|
|
|
UINT_32 mipId,
|
|
|
|
|
UINT_32 log2ElementBytes,
|
|
|
|
|
UINT_32* pMipTailBytesOffset) const
|
|
|
|
|
{
|
|
|
|
|
Dim3d mipStartPos = {0};
|
|
|
|
|
const Dim3d tailMaxDim = GetMipTailDim(resourceType, swizzleMode, blockWidth, blockHeight, blockDepth);
|
|
|
|
|
|
|
|
|
|
// Report mip in tail if Mip0 is already in mip tail
|
|
|
|
|
BOOL_32 inMipTail = IsInMipTail(resourceType, swizzleMode, tailMaxDim, width, height, depth);
|
|
|
|
|
UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode);
|
|
|
|
|
UINT_32 mipIndexInTail = mipId;
|
|
|
|
|
|
|
|
|
|
if (inMipTail == FALSE)
|
|
|
|
|
{
|
|
|
|
|
// Mip 0 dimension, unit in block
|
|
|
|
|
UINT_32 mipWidthInBlk = width / blockWidth;
|
|
|
|
|
UINT_32 mipHeightInBlk = height / blockHeight;
|
|
|
|
|
UINT_32 mipDepthInBlk = depth / blockDepth;
|
|
|
|
|
AddrMajorMode majorMode = GetMajorMode(resourceType,
|
|
|
|
|
swizzleMode,
|
|
|
|
|
mipWidthInBlk,
|
|
|
|
|
mipHeightInBlk,
|
|
|
|
|
mipDepthInBlk);
|
|
|
|
|
|
|
|
|
|
UINT_32 endingMip = mipId + 1;
|
|
|
|
|
|
|
|
|
|
for (UINT_32 i = 1; i <= mipId; i++)
|
|
|
|
|
{
|
|
|
|
|
if ((i == 1) || (i == 3))
|
|
|
|
|
{
|
|
|
|
|
if (majorMode == ADDR_MAJOR_Y)
|
|
|
|
|
{
|
|
|
|
|
mipStartPos.w += mipWidthInBlk;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mipStartPos.h += mipHeightInBlk;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (majorMode == ADDR_MAJOR_X)
|
|
|
|
|
{
|
|
|
|
|
mipStartPos.w += mipWidthInBlk;
|
|
|
|
|
}
|
|
|
|
|
else if (majorMode == ADDR_MAJOR_Y)
|
|
|
|
|
{
|
|
|
|
|
mipStartPos.h += mipHeightInBlk;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mipStartPos.d += mipDepthInBlk;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL_32 inTail = FALSE;
|
|
|
|
|
|
|
|
|
|
if (IsThick(resourceType, swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
UINT_32 dim = log2blkSize % 3;
|
|
|
|
|
|
|
|
|
|
if (dim == 0)
|
|
|
|
|
{
|
|
|
|
|
inTail =
|
|
|
|
|
(mipWidthInBlk <= 2) && (mipHeightInBlk == 1) && (mipDepthInBlk <= 2);
|
|
|
|
|
}
|
|
|
|
|
else if (dim == 1)
|
|
|
|
|
{
|
|
|
|
|
inTail =
|
|
|
|
|
(mipWidthInBlk == 1) && (mipHeightInBlk <= 2) && (mipDepthInBlk <= 2);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
inTail =
|
|
|
|
|
(mipWidthInBlk <= 2) && (mipHeightInBlk <= 2) && (mipDepthInBlk == 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (log2blkSize & 1)
|
|
|
|
|
{
|
|
|
|
|
inTail = (mipWidthInBlk <= 2) && (mipHeightInBlk == 1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
inTail = (mipWidthInBlk == 1) && (mipHeightInBlk <= 2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (inTail)
|
|
|
|
|
{
|
|
|
|
|
endingMip = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mipWidthInBlk = RoundHalf(mipWidthInBlk);
|
|
|
|
|
mipHeightInBlk = RoundHalf(mipHeightInBlk);
|
|
|
|
|
mipDepthInBlk = RoundHalf(mipDepthInBlk);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mipId >= endingMip)
|
|
|
|
|
{
|
|
|
|
|
inMipTail = TRUE;
|
|
|
|
|
mipIndexInTail = mipId - endingMip;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (inMipTail)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 index = mipIndexInTail + MaxMacroBits - log2blkSize;
|
|
|
|
|
ADDR_ASSERT(index < sizeof(MipTailOffset256B) / sizeof(UINT_32));
|
|
|
|
|
*pMipTailBytesOffset = MipTailOffset256B[index] << 8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mipStartPos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
* Gfx9Lib::HwlComputeSurfaceAddrFromCoordTiled
|
|
|
|
|
*
|
|
|
|
|
* @brief
|
|
|
|
|
* Internal function to calculate address from coord for tiled swizzle surface
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* ADDR_E_RETURNCODE
|
|
|
|
|
************************************************************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
ADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceAddrFromCoordTiled(
|
|
|
|
|
const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
|
|
|
|
|
ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
|
|
|
|
|
) const
|
|
|
|
|
{
|
|
|
|
|
ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0};
|
|
|
|
|
localIn.swizzleMode = pIn->swizzleMode;
|
|
|
|
|
localIn.flags = pIn->flags;
|
|
|
|
|
localIn.resourceType = pIn->resourceType;
|
|
|
|
|
localIn.bpp = pIn->bpp;
|
|
|
|
|
localIn.width = Max(pIn->unalignedWidth, 1u);
|
|
|
|
|
localIn.height = Max(pIn->unalignedHeight, 1u);
|
|
|
|
|
localIn.numSlices = Max(pIn->numSlices, 1u);
|
|
|
|
|
localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
|
|
|
|
|
localIn.numSamples = Max(pIn->numSamples, 1u);
|
|
|
|
|
localIn.numFrags = Max(pIn->numFrags, 1u);
|
|
|
|
|
if (localIn.numMipLevels <= 1)
|
|
|
|
|
{
|
|
|
|
|
localIn.pitchInElement = pIn->pitchInElement;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
|
|
|
|
|
ADDR_E_RETURNCODE returnCode = ComputeSurfaceInfoTiled(&localIn, &localOut);
|
|
|
|
|
|
|
|
|
|
BOOL_32 valid = (returnCode == ADDR_OK) &&
|
|
|
|
|
(IsThin(pIn->resourceType, pIn->swizzleMode) ||
|
|
|
|
|
IsThick(pIn->resourceType, pIn->swizzleMode)) &&
|
|
|
|
|
((pIn->pipeBankXor == 0) || (IsXor(pIn->swizzleMode)));
|
|
|
|
|
|
|
|
|
|
if (valid)
|
|
|
|
|
{
|
|
|
|
|
UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3);
|
|
|
|
|
Dim3d mipStartPos = {0};
|
|
|
|
|
UINT_32 mipTailBytesOffset = 0;
|
|
|
|
|
|
|
|
|
|
if (pIn->numMipLevels > 1)
|
|
|
|
|
{
|
|
|
|
|
// Mip-map chain cannot be MSAA surface
|
|
|
|
|
ADDR_ASSERT((pIn->numSamples <= 1) && (pIn->numFrags<= 1));
|
|
|
|
|
|
|
|
|
|
mipStartPos = GetMipStartPos(pIn->resourceType,
|
|
|
|
|
pIn->swizzleMode,
|
|
|
|
|
localOut.pitch,
|
|
|
|
|
localOut.height,
|
|
|
|
|
localOut.numSlices,
|
|
|
|
|
localOut.blockWidth,
|
|
|
|
|
localOut.blockHeight,
|
|
|
|
|
localOut.blockSlices,
|
|
|
|
|
pIn->mipId,
|
|
|
|
|
log2ElementBytes,
|
|
|
|
|
&mipTailBytesOffset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UINT_32 interleaveOffset = 0;
|
|
|
|
|
UINT_32 pipeBits = 0;
|
|
|
|
|
UINT_32 pipeXor = 0;
|
|
|
|
|
UINT_32 bankBits = 0;
|
|
|
|
|
UINT_32 bankXor = 0;
|
|
|
|
|
|
|
|
|
|
if (IsThin(pIn->resourceType, pIn->swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
UINT_32 blockOffset = 0;
|
|
|
|
|
UINT_32 log2blkSize = GetBlockSizeLog2(pIn->swizzleMode);
|
|
|
|
|
|
|
|
|
|
if (IsZOrderSwizzle(pIn->swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
// Morton generation
|
|
|
|
|
if ((log2ElementBytes == 0) || (log2ElementBytes == 2))
|
|
|
|
|
{
|
|
|
|
|
UINT_32 totalLowBits = 6 - log2ElementBytes;
|
|
|
|
|
UINT_32 mortBits = totalLowBits / 2;
|
|
|
|
|
UINT_32 lowBitsValue = MortonGen2d(pIn->y, pIn->x, mortBits);
|
|
|
|
|
// Are 9 bits enough?
|
|
|
|
|
UINT_32 highBitsValue =
|
|
|
|
|
MortonGen2d(pIn->x >> mortBits, pIn->y >> mortBits, 9) << totalLowBits;
|
|
|
|
|
blockOffset = lowBitsValue | highBitsValue;
|
|
|
|
|
ADDR_ASSERT(blockOffset == lowBitsValue + highBitsValue);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
blockOffset = MortonGen2d(pIn->y, pIn->x, 13);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fill LSBs with sample bits
|
|
|
|
|
if (pIn->numSamples > 1)
|
|
|
|
|
{
|
|
|
|
|
blockOffset *= pIn->numSamples;
|
|
|
|
|
blockOffset |= pIn->sample;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Shift according to BytesPP
|
|
|
|
|
blockOffset <<= log2ElementBytes;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Micro block offset
|
|
|
|
|
UINT_32 microBlockOffset = ComputeSurface2DMicroBlockOffset(pIn);
|
|
|
|
|
blockOffset = microBlockOffset;
|
|
|
|
|
|
|
|
|
|
// Micro block dimension
|
|
|
|
|
ADDR_ASSERT(log2ElementBytes < MaxNumOfBpp);
|
|
|
|
|
Dim2d microBlockDim = Block256_2d[log2ElementBytes];
|
|
|
|
|
// Morton generation, does 12 bit enough?
|
|
|
|
|
blockOffset |=
|
|
|
|
|
MortonGen2d((pIn->x / microBlockDim.w), (pIn->y / microBlockDim.h), 12) << 8;
|
|
|
|
|
|
|
|
|
|
// Sample bits start location
|
|
|
|
|
UINT_32 sampleStart = log2blkSize - Log2(pIn->numSamples);
|
|
|
|
|
// Join sample bits information to the highest Macro block bits
|
|
|
|
|
if (IsNonPrtXor(pIn->swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
// Non-prt-Xor : xor highest Macro block bits with sample bits
|
|
|
|
|
blockOffset = blockOffset ^ (pIn->sample << sampleStart);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Non-Xor or prt-Xor: replace highest Macro block bits with sample bits
|
|
|
|
|
// after this op, the blockOffset only contains log2 Macro block size bits
|
|
|
|
|
blockOffset %= (1 << sampleStart);
|
|
|
|
|
blockOffset |= (pIn->sample << sampleStart);
|
|
|
|
|
ADDR_ASSERT((blockOffset >> log2blkSize) == 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IsXor(pIn->swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
// Mask off bits above Macro block bits to keep page synonyms working for prt
|
|
|
|
|
if (IsPrt(pIn->swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
blockOffset &= ((1 << log2blkSize) - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Preserve offset inside pipe interleave
|
|
|
|
|
interleaveOffset = blockOffset & ((1 << m_pipeInterleaveLog2) - 1);
|
|
|
|
|
blockOffset >>= m_pipeInterleaveLog2;
|
|
|
|
|
|
|
|
|
|
// Pipe/Se xor bits
|
|
|
|
|
pipeBits = GetPipeXorBits(log2blkSize);
|
|
|
|
|
// Pipe xor
|
|
|
|
|
pipeXor = FoldXor2d(blockOffset, pipeBits);
|
|
|
|
|
blockOffset >>= pipeBits;
|
|
|
|
|
|
|
|
|
|
// Bank xor bits
|
|
|
|
|
bankBits = GetBankXorBits(log2blkSize);
|
|
|
|
|
// Bank Xor
|
|
|
|
|
bankXor = FoldXor2d(blockOffset, bankBits);
|
|
|
|
|
blockOffset >>= bankBits;
|
|
|
|
|
|
|
|
|
|
// Put all the part back together
|
|
|
|
|
blockOffset <<= bankBits;
|
|
|
|
|
blockOffset |= bankXor;
|
|
|
|
|
blockOffset <<= pipeBits;
|
|
|
|
|
blockOffset |= pipeXor;
|
|
|
|
|
blockOffset <<= m_pipeInterleaveLog2;
|
|
|
|
|
blockOffset |= interleaveOffset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ADDR_ASSERT((blockOffset | mipTailBytesOffset) == (blockOffset + mipTailBytesOffset));
|
|
|
|
|
ADDR_ASSERT((mipTailBytesOffset == 0u) || (blockOffset < (1u << log2blkSize)));
|
|
|
|
|
|
|
|
|
|
blockOffset |= mipTailBytesOffset;
|
|
|
|
|
|
|
|
|
|
if (IsNonPrtXor(pIn->swizzleMode) && (pIn->numSamples <= 1))
|
|
|
|
|
{
|
|
|
|
|
// Apply slice xor if not MSAA/PRT
|
|
|
|
|
blockOffset ^= (ReverseBitVector(pIn->slice, pipeBits) << m_pipeInterleaveLog2);
|
|
|
|
|
blockOffset ^= (ReverseBitVector(pIn->slice >> pipeBits, bankBits) <<
|
|
|
|
|
(m_pipeInterleaveLog2 + pipeBits));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
returnCode = ApplyCustomerPipeBankXor(pIn->swizzleMode, pIn->pipeBankXor,
|
|
|
|
|
bankBits, pipeBits, &blockOffset);
|
|
|
|
|
|
|
|
|
|
blockOffset %= (1 << log2blkSize);
|
|
|
|
|
|
|
|
|
|
UINT_32 pitchInMacroBlock = localOut.mipChainPitch / localOut.blockWidth;
|
|
|
|
|
UINT_32 paddedHeightInMacroBlock = localOut.mipChainHeight / localOut.blockHeight;
|
|
|
|
|
UINT_32 sliceSizeInMacroBlock = pitchInMacroBlock * paddedHeightInMacroBlock;
|
|
|
|
|
UINT_32 macroBlockIndex =
|
|
|
|
|
(pIn->slice + mipStartPos.d) * sliceSizeInMacroBlock +
|
|
|
|
|
((pIn->y / localOut.blockHeight) + mipStartPos.h) * pitchInMacroBlock +
|
|
|
|
|
((pIn->x / localOut.blockWidth) + mipStartPos.w);
|
|
|
|
|
|
|
|
|
|
UINT_64 macroBlockOffset = (static_cast<UINT_64>(macroBlockIndex) <<
|
|
|
|
|
GetBlockSizeLog2(pIn->swizzleMode));
|
|
|
|
|
|
|
|
|
|
pOut->addr = blockOffset | macroBlockOffset;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UINT_32 log2blkSize = GetBlockSizeLog2(pIn->swizzleMode);
|
|
|
|
|
|
|
|
|
|
Dim3d microBlockDim = Block1K_3d[log2ElementBytes];
|
|
|
|
|
|
|
|
|
|
UINT_32 blockOffset = MortonGen3d((pIn->x / microBlockDim.w),
|
|
|
|
|
(pIn->y / microBlockDim.h),
|
|
|
|
|
(pIn->slice / microBlockDim.d),
|
|
|
|
|
8);
|
|
|
|
|
|
|
|
|
|
blockOffset <<= 10;
|
|
|
|
|
blockOffset |= ComputeSurface3DMicroBlockOffset(pIn);
|
|
|
|
|
|
|
|
|
|
if (IsXor(pIn->swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
// Mask off bits above Macro block bits to keep page synonyms working for prt
|
|
|
|
|
if (IsPrt(pIn->swizzleMode))
|
|
|
|
|
{
|
|
|
|
|
blockOffset &= ((1 << log2blkSize) - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Preserve offset inside pipe interleave
|
|
|
|
|
interleaveOffset = blockOffset & ((1 << m_pipeInterleaveLog2) - 1);
|
|
|
|
|
blockOffset >>= m_pipeInterleaveLog2;
|
|
|
|
|
|
|
|
|
|
// Pipe/Se xor bits
|
|
|
|
|
pipeBits = GetPipeXorBits(log2blkSize);
|
|
|
|
|
// Pipe xor
|
|
|
|
|
pipeXor = FoldXor3d(blockOffset, pipeBits);
|
|
|
|
|
blockOffset >>= pipeBits;
|
|
|
|
|
|
|
|
|
|
// Bank xor bits
|
|
|
|
|
bankBits = GetBankXorBits(log2blkSize);
|
|
|
|
|
// Bank Xor
|
|
|
|
|
bankXor = FoldXor3d(blockOffset, bankBits);
|
|
|
|
|
blockOffset >>= bankBits;
|
|
|
|
|
|
|
|
|
|
// Put all the part back together
|
|
|
|
|
blockOffset <<= bankBits;
|
|
|
|
|
blockOffset |= bankXor;
|
|
|
|
|
blockOffset <<= pipeBits;
|
|
|
|
|
blockOffset |= pipeXor;
|
|
|
|
|
blockOffset <<= m_pipeInterleaveLog2;
|
|
|
|
|
blockOffset |= interleaveOffset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ADDR_ASSERT((blockOffset | mipTailBytesOffset) == (blockOffset + mipTailBytesOffset));
|
|
|
|
|
ADDR_ASSERT((mipTailBytesOffset == 0u) || (blockOffset < (1u << log2blkSize)));
|
|
|
|
|
blockOffset |= mipTailBytesOffset;
|
|
|
|
|
|
|
|
|
|
returnCode = ApplyCustomerPipeBankXor(pIn->swizzleMode, pIn->pipeBankXor,
|
|
|
|
|
bankBits, pipeBits, &blockOffset);
|
|
|
|
|
|
|
|
|
|
blockOffset %= (1 << log2blkSize);
|
|
|
|
|
|
|
|
|
|
UINT_32 xb = pIn->x / localOut.blockWidth + mipStartPos.w;
|
|
|
|
|
UINT_32 yb = pIn->y / localOut.blockHeight + mipStartPos.h;
|
|
|
|
|
UINT_32 zb = pIn->slice / localOut.blockSlices + + mipStartPos.d;
|
|
|
|
|
|
|
|
|
|
UINT_32 pitchInBlock = localOut.mipChainPitch / localOut.blockWidth;
|
|
|
|
|
UINT_32 sliceSizeInBlock =
|
|
|
|
|
(localOut.mipChainHeight / localOut.blockHeight) * pitchInBlock;
|
|
|
|
|
UINT_32 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb;
|
|
|
|
|
|
|
|
|
|
pOut->addr = blockOffset | (blockIndex << log2blkSize);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
returnCode = ADDR_INVALIDPARAMS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return returnCode;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-06 18:55:25 +02:00
|
|
|
} // V2
|
|
|
|
|
} // Addr
|