diff options
author | Marek Olšák <[email protected]> | 2017-02-27 22:25:44 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2017-04-04 11:14:43 +0200 |
commit | 18e760346aab10affd6e9ff129f800d90fa28456 (patch) | |
tree | 675c8774069880cd1d0f5ba1523e255071d9069b /src/amd/addrlib/gfx9 | |
parent | 3e7d62a774c2598f308e612507672136886ebe60 (diff) |
amd/addrlib: second update for Vega10 + bug fixes
Highlights:
- Display needs tiled pitch alignment to be at least 32 pixels
- Implement Addr2ComputeDccAddrFromCoord().
- Macro-pixel packed formats don't support Z swizzle modes
- Pad pitch and base alignment of PRT + TEX1D to 64KB.
- Fix support for multimedia formats
- Fix a case "PRT" entries are not selected on SI.
- Fix wrong upper bits in equations for 3D resource.
- We can't support 2d array slice rotation in gfx8 swizzle pattern
- Set base alignment for PRT + non-xor swizzle mode resource to 64KB.
- Bug workaround for Z16 4x/8x and Z32 2x/4x/8x MSAA depth texture
- Add stereo support
- Optimize swizzle mode selection
- Report pitch and height in pixels for each mip
- Adjust bpp/expandX for format ADDR_FMT_GB_GR/ADDR_FMT_BG_RG
- Correct tcCompatible flag output for mipmap surface
- Other fixes and cleanups
Acked-by: Alex Deucher <[email protected]>
Acked-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src/amd/addrlib/gfx9')
-rw-r--r-- | src/amd/addrlib/gfx9/gfx9addrlib.cpp | 2416 | ||||
-rw-r--r-- | src/amd/addrlib/gfx9/gfx9addrlib.h | 188 |
2 files changed, 2312 insertions, 292 deletions
diff --git a/src/amd/addrlib/gfx9/gfx9addrlib.cpp b/src/amd/addrlib/gfx9/gfx9addrlib.cpp index 380b785e595..96b05de3dfe 100644 --- a/src/amd/addrlib/gfx9/gfx9addrlib.cpp +++ b/src/amd/addrlib/gfx9/gfx9addrlib.cpp @@ -25,10 +25,10 @@ */ /** -**************************************************************************************************** +************************************************************************************************************************ * @file gfx9addrlib.cpp * @brief Contgfx9ns the implementation for the Gfx9Lib class. -**************************************************************************************************** +************************************************************************************************************************ */ #include "gfx9addrlib.h" @@ -50,7 +50,7 @@ namespace Addr { /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9HwlInit * * @brief @@ -58,7 +58,7 @@ namespace Addr * * @return * Returns an Gfx9Lib object pointer. -**************************************************************************************************** +************************************************************************************************************************ */ Addr::Lib* Gfx9HwlInit(const Client* pClient) { @@ -68,14 +68,69 @@ Addr::Lib* Gfx9HwlInit(const Client* pClient) namespace V2 { +//////////////////////////////////////////////////////////////////////////////////////////////////// +// 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}}; + /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::Gfx9Lib * * @brief * Constructor * -**************************************************************************************************** +************************************************************************************************************************ */ Gfx9Lib::Gfx9Lib(const Client* pClient) : @@ -84,22 +139,23 @@ Gfx9Lib::Gfx9Lib(const Client* pClient) { m_class = AI_ADDRLIB; memset(&m_settings, 0, sizeof(m_settings)); + memcpy(m_swizzleModeTable, SwizzleModeTable, sizeof(SwizzleModeTable)); } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::~Gfx9Lib * * @brief * Destructor -**************************************************************************************************** +************************************************************************************************************************ */ Gfx9Lib::~Gfx9Lib() { } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeHtileInfo * * @brief @@ -107,7 +163,7 @@ Gfx9Lib::~Gfx9Lib() * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileInfo( const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn, ///< [in] input structure @@ -174,6 +230,13 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileInfo( pOut->metaBlkHeight = metaBlkDim.h; pOut->metaBlkNumPerSlice = numMetaBlkX * numMetaBlkY; + pOut->baseAlign = Max(numCompressBlkPerMetaBlk * 4, sizeAlign); + + if (m_settings.metaBaseAlignFix) + { + pOut->baseAlign = Max(pOut->baseAlign, GetBlockSize(pIn->swizzleMode)); + } + if ((IsXor(pIn->swizzleMode) == FALSE) && (numPipeTotal > 2)) { UINT_32 additionalAlign = numPipeTotal * numCompressBlkPerMetaBlk * 2; @@ -185,18 +248,12 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileInfo( } pOut->htileBytes = PowTwoAlign(pOut->sliceSize * numMetaBlkZ, sizeAlign); - pOut->baseAlign = Max(numCompressBlkPerMetaBlk * 4, sizeAlign); - - if (m_settings.metaBaseAlignFix) - { - pOut->baseAlign = Max(pOut->baseAlign, HwlComputeSurfaceBaseAlign(pIn->swizzleMode)); - } return ADDR_OK; } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeCmaskInfo * * @brief @@ -204,7 +261,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileInfo( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskInfo( const ADDR2_COMPUTE_CMASK_INFO_INPUT* pIn, ///< [in] input structure @@ -270,7 +327,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskInfo( if (m_settings.metaBaseAlignFix) { - pOut->baseAlign = Max(pOut->baseAlign, HwlComputeSurfaceBaseAlign(pIn->swizzleMode)); + pOut->baseAlign = Max(pOut->baseAlign, GetBlockSize(pIn->swizzleMode)); } pOut->metaBlkWidth = metaBlkDim.w; @@ -282,7 +339,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskInfo( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::GetMetaMipInfo * * @brief @@ -290,7 +347,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskInfo( * * @return * N/A -**************************************************************************************************** +************************************************************************************************************************ */ VOID Gfx9Lib::GetMetaMipInfo( UINT_32 numMipLevels, ///< [in] number of mip levels @@ -456,7 +513,7 @@ VOID Gfx9Lib::GetMetaMipInfo( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeDccInfo * * @brief @@ -464,7 +521,7 @@ VOID Gfx9Lib::GetMetaMipInfo( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeDccInfo( const ADDR2_COMPUTE_DCCINFO_INPUT* pIn, ///< [in] input structure @@ -500,8 +557,8 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeDccInfo( UINT_32 minMetaBlkSize = dataThick ? 65536 : 4096; - UINT_32 numFrags = (pIn->numFrags == 0) ? 1 : pIn->numFrags; - UINT_32 numSlices = (pIn->numSlices == 0) ? 1 : pIn->numSlices; + UINT_32 numFrags = Max(pIn->numFrags, 1u); + UINT_32 numSlices = Max(pIn->numSlices, 1u); minMetaBlkSize /= numFrags; @@ -572,7 +629,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeDccInfo( if (m_settings.metaBaseAlignFix) { - pOut->dccRamBaseAlign = Max(pOut->dccRamBaseAlign, HwlComputeSurfaceBaseAlign(pIn->swizzleMode)); + pOut->dccRamBaseAlign = Max(pOut->dccRamBaseAlign, GetBlockSize(pIn->swizzleMode)); } pOut->pitch = numMetaBlkX * metaBlkDim.w; @@ -596,14 +653,14 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeDccInfo( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlGetMaxAlignments * * @brief * Gets maximum alignments * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlGetMaxAlignments( ADDR_GET_MAX_ALINGMENTS_OUTPUT* pOut ///< [out] output structure @@ -615,7 +672,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlGetMaxAlignments( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeCmaskAddrFromCoord * * @brief @@ -623,39 +680,34 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlGetMaxAlignments( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ 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 { - ADDR2_COMPUTE_CMASK_INFO_INPUT input; - ADDR2_COMPUTE_CMASK_INFO_OUTPUT output; - - memset(&input, 0, sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT)); - input.size = sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT); - input.cMaskFlags = pIn->cMaskFlags; - input.colorFlags = pIn->colorFlags; - input.unalignedWidth = Max(pIn->unalignedWidth, 1u); + 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); input.unalignedHeight = Max(pIn->unalignedHeight, 1u); - input.numSlices = Max(pIn->numSlices, 1u); - input.swizzleMode = pIn->swizzleMode; - input.resourceType = pIn->resourceType; + input.numSlices = Max(pIn->numSlices, 1u); + input.swizzleMode = pIn->swizzleMode; + input.resourceType = pIn->resourceType; - memset(&output, 0, sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT)); - output.size = sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT); + ADDR2_COMPUTE_CMASK_INFO_OUTPUT output = {0}; + output.size = sizeof(output); ADDR_E_RETURNCODE returnCode = ComputeCmaskInfo(&input, &output); if (returnCode == ADDR_OK) { - UINT_32 fmaskBpp = GetFmaskBpp(pIn->numSamples, pIn->numFrags); - + UINT_32 fmaskBpp = GetFmaskBpp(pIn->numSamples, pIn->numFrags); UINT_32 fmaskElementBytesLog2 = Log2(fmaskBpp >> 3); - - UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth); - UINT_32 metaBlkHeightLog2 = Log2(output.metaBlkHeight); + UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth); + UINT_32 metaBlkHeightLog2 = Log2(output.metaBlkHeight); CoordEq metaEq; @@ -667,9 +719,9 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskAddrFromCoord( UINT_32 yb = pIn->y / output.metaBlkHeight; UINT_32 zb = pIn->slice; - UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth; + UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth; UINT_32 sliceSizeInBlock = (output.height / output.metaBlkHeight) * pitchInBlock; - UINT_32 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb; + UINT_32 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb; UINT_64 address = metaEq.solve(pIn->x, pIn->y, pIn->slice, 0, blockIndex); @@ -689,7 +741,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskAddrFromCoord( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeHtileAddrFromCoord * * @brief @@ -697,7 +749,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskAddrFromCoord( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileAddrFromCoord( const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure @@ -712,32 +764,27 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileAddrFromCoord( } else { - ADDR2_COMPUTE_HTILE_INFO_INPUT input; - ADDR2_COMPUTE_HTILE_INFO_OUTPUT output; - - memset(&input, 0, sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT)); - input.size = sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT); - input.hTileFlags = pIn->hTileFlags; - input.depthFlags = pIn->depthflags; - input.swizzleMode = pIn->swizzleMode; - input.unalignedWidth = Max(pIn->unalignedWidth, 1u); + 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); input.unalignedHeight = Max(pIn->unalignedHeight, 1u); - input.numSlices = Max(pIn->numSlices, 1u); - input.numMipLevels = Max(pIn->numMipLevels, 1u); + input.numSlices = Max(pIn->numSlices, 1u); + input.numMipLevels = Max(pIn->numMipLevels, 1u); - memset(&output, 0, sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT)); - output.size = sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT); + ADDR2_COMPUTE_HTILE_INFO_OUTPUT output = {0}; + output.size = sizeof(output); returnCode = ComputeHtileInfo(&input, &output); if (returnCode == ADDR_OK) { - UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3); - - UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth); + UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3); + UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth); UINT_32 metaBlkHeightLog2 = Log2(output.metaBlkHeight); - - UINT_32 numSamplesLog2 = Log2(pIn->numSamples); + UINT_32 numSamplesLog2 = Log2(pIn->numSamples); CoordEq metaEq; @@ -749,9 +796,9 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileAddrFromCoord( UINT_32 yb = pIn->y / output.metaBlkHeight; UINT_32 zb = pIn->slice; - UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth; + UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth; UINT_32 sliceSizeInBlock = (output.height / output.metaBlkHeight) * pitchInBlock; - UINT_32 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb; + UINT_32 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb; UINT_64 address = metaEq.solve(pIn->x, pIn->y, pIn->slice, 0, blockIndex); @@ -770,7 +817,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileAddrFromCoord( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeHtileCoordFromAddr * * @brief @@ -778,7 +825,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileAddrFromCoord( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileCoordFromAddr( const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure @@ -793,31 +840,26 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileCoordFromAddr( } else { - ADDR2_COMPUTE_HTILE_INFO_INPUT input; - ADDR2_COMPUTE_HTILE_INFO_OUTPUT output; - - memset(&input, 0, sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT)); - input.size = sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT); - input.hTileFlags = pIn->hTileFlags; - input.swizzleMode = pIn->swizzleMode; - input.unalignedWidth = Max(pIn->unalignedWidth, 1u); + 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); input.unalignedHeight = Max(pIn->unalignedHeight, 1u); - input.numSlices = Max(pIn->numSlices, 1u); - input.numMipLevels = Max(pIn->numMipLevels, 1u); + input.numSlices = Max(pIn->numSlices, 1u); + input.numMipLevels = Max(pIn->numMipLevels, 1u); - memset(&output, 0, sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT)); - output.size = sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT); + ADDR2_COMPUTE_HTILE_INFO_OUTPUT output = {0}; + output.size = sizeof(output); returnCode = ComputeHtileInfo(&input, &output); if (returnCode == ADDR_OK) { - UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3); - - UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth); + UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3); + UINT_32 metaBlkWidthLog2 = Log2(output.metaBlkWidth); UINT_32 metaBlkHeightLog2 = Log2(output.metaBlkHeight); - - UINT_32 numSamplesLog2 = Log2(pIn->numSamples); + UINT_32 numSamplesLog2 = Log2(pIn->numSamples); CoordEq metaEq; @@ -832,16 +874,15 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileCoordFromAddr( UINT_64 nibbleAddress = (pIn->addr ^ (pipeXor << m_pipeInterleaveLog2)) << 1; - UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth; + UINT_32 pitchInBlock = output.pitch / output.metaBlkWidth; 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; - pOut->y = ((m % sliceSizeInBlock) / pitchInBlock) * output.metaBlkHeight + y; - pOut->x = (m % pitchInBlock) * output.metaBlkWidth + x; + pOut->y = ((m % sliceSizeInBlock) / pitchInBlock) * output.metaBlkHeight + y; + pOut->x = (m % pitchInBlock) * output.metaBlkWidth + x; } } @@ -849,7 +890,90 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileCoordFromAddr( } /** -**************************************************************************************************** +************************************************************************************************************************ +* 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); + } + } + + return returnCode; +} + +/** +************************************************************************************************************************ * Gfx9Lib::HwlInitGlobalParams * * @brief @@ -858,7 +982,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileCoordFromAddr( * @return * TRUE if all settings are valid * -**************************************************************************************************** +************************************************************************************************************************ */ BOOL_32 Gfx9Lib::HwlInitGlobalParams( const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input @@ -899,6 +1023,7 @@ BOOL_32 Gfx9Lib::HwlInitGlobalParams( m_pipesLog2 = 5; break; default: + ADDR_ASSERT_ALWAYS(); break; } @@ -921,6 +1046,7 @@ BOOL_32 Gfx9Lib::HwlInitGlobalParams( m_pipeInterleaveLog2 = 11; break; default: + ADDR_ASSERT_ALWAYS(); break; } @@ -947,6 +1073,7 @@ BOOL_32 Gfx9Lib::HwlInitGlobalParams( m_banksLog2 = 4; break; default: + ADDR_ASSERT_ALWAYS(); break; } @@ -969,6 +1096,7 @@ BOOL_32 Gfx9Lib::HwlInitGlobalParams( m_seLog2 = 3; break; default: + ADDR_ASSERT_ALWAYS(); break; } @@ -987,6 +1115,7 @@ BOOL_32 Gfx9Lib::HwlInitGlobalParams( m_rbPerSeLog2 = 2; break; default: + ADDR_ASSERT_ALWAYS(); break; } @@ -1009,6 +1138,7 @@ BOOL_32 Gfx9Lib::HwlInitGlobalParams( m_maxCompFragLog2 = 3; break; default: + ADDR_ASSERT_ALWAYS(); break; } @@ -1032,14 +1162,14 @@ BOOL_32 Gfx9Lib::HwlInitGlobalParams( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlConvertChipFamily * * @brief * Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision * @return * ChipFamily -**************************************************************************************************** +************************************************************************************************************************ */ ChipFamily Gfx9Lib::HwlConvertChipFamily( UINT_32 uChipFamily, ///< [in] chip family defined in atiih.h @@ -1058,8 +1188,9 @@ ChipFamily Gfx9Lib::HwlConvertChipFamily( m_settings.isDce12 = 1; } - // Bug ID DEGGIGX90-1056 m_settings.metaBaseAlignFix = 1; + + m_settings.depthPipeXorDisable = 1; break; default: @@ -1071,14 +1202,14 @@ ChipFamily Gfx9Lib::HwlConvertChipFamily( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::InitRbEquation * * @brief * Init RB equation * @return * N/A -**************************************************************************************************** +************************************************************************************************************************ */ VOID Gfx9Lib::GetRbEquation( CoordEq* pRbEq, ///< [out] rb equation @@ -1129,14 +1260,14 @@ VOID Gfx9Lib::GetRbEquation( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::GetDataEquation * * @brief * Get data equation for fmask and Z * @return * N/A -**************************************************************************************************** +************************************************************************************************************************ */ VOID Gfx9Lib::GetDataEquation( CoordEq* pDataEq, ///< [out] data surface equation @@ -1325,14 +1456,14 @@ VOID Gfx9Lib::GetDataEquation( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::GetPipeEquation * * @brief * Get pipe equation * @return * N/A -**************************************************************************************************** +************************************************************************************************************************ */ VOID Gfx9Lib::GetPipeEquation( CoordEq* pPipeEq, ///< [out] pipe equation @@ -1439,14 +1570,14 @@ VOID Gfx9Lib::GetPipeEquation( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::GetMetaEquation * * @brief * Get meta equation for cmask/htile/DCC * @return * N/A -**************************************************************************************************** +************************************************************************************************************************ */ VOID Gfx9Lib::GetMetaEquation( CoordEq* pMetaEq, ///< [out] meta equation @@ -1779,7 +1910,7 @@ VOID Gfx9Lib::GetMetaEquation( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::IsEquationSupported * * @brief @@ -1787,7 +1918,7 @@ VOID Gfx9Lib::GetMetaEquation( * * @return * TRUE if supported -**************************************************************************************************** +************************************************************************************************************************ */ BOOL_32 Gfx9Lib::IsEquationSupported( AddrResourceType rsrcType, @@ -1796,7 +1927,10 @@ BOOL_32 Gfx9Lib::IsEquationSupported( { BOOL_32 supported = (elementBytesLog2 < MaxElementBytesLog2) && (IsLinear(swMode) == FALSE) && - ((IsTex2d(rsrcType) == TRUE) || + (((IsTex2d(rsrcType) == TRUE) && + ((elementBytesLog2 < 4) || + ((IsRotateSwizzle(swMode) == FALSE) && + (IsZOrderSwizzle(swMode) == FALSE)))) || ((IsTex3d(rsrcType) == TRUE) && (IsRotateSwizzle(swMode) == FALSE) && (IsBlock256b(swMode) == FALSE))); @@ -1805,7 +1939,7 @@ BOOL_32 Gfx9Lib::IsEquationSupported( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::InitEquationTable * * @brief @@ -1813,7 +1947,7 @@ BOOL_32 Gfx9Lib::IsEquationSupported( * * @return * N/A -**************************************************************************************************** +************************************************************************************************************************ */ VOID Gfx9Lib::InitEquationTable() { @@ -1869,6 +2003,10 @@ VOID Gfx9Lib::InitEquationTable() m_numEquations++; } + else + { + ADDR_ASSERT_ALWAYS(); + } } // Fill the index into the lookup table, if the combination is not supported @@ -1880,7 +2018,7 @@ VOID Gfx9Lib::InitEquationTable() } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlGetEquationIndex * * @brief @@ -1888,78 +2026,31 @@ VOID Gfx9Lib::InitEquationTable() * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ UINT_32 Gfx9Lib::HwlGetEquationIndex( const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ) const { - AddrResourceType rsrcType = pIn->resourceType; - AddrSwizzleMode swMode = pIn->swizzleMode; - UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3); - UINT_32 numMipLevels = pIn->numMipLevels; - ADDR2_MIP_INFO* pMipInfo = pOut->pMipInfo; - - UINT_32 index = ADDR_INVALID_EQUATION_INDEX; - - BOOL_32 eqSupported = (pOut->firstMipInTail == FALSE) && - IsEquationSupported(rsrcType, swMode, elementBytesLog2); - - UINT_32 rsrcTypeIdx = static_cast<UINT_32>(rsrcType) - 1; - UINT_32 swModeIdx = static_cast<UINT_32>(swMode); + AddrResourceType rsrcType = pIn->resourceType; + AddrSwizzleMode swMode = pIn->swizzleMode; + UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3); + UINT_32 index = ADDR_INVALID_EQUATION_INDEX; - if (eqSupported) + if (IsEquationSupported(rsrcType, swMode, elementBytesLog2)) { - index = m_equationLookupTable[rsrcTypeIdx][swModeIdx][elementBytesLog2]; - - if (pMipInfo != NULL) - { - pMipInfo->equationIndex = index; - pMipInfo->mipOffsetXBytes = 0; - pMipInfo->mipOffsetYPixel = 0; - pMipInfo->mipOffsetZPixel = 0; - pMipInfo->postSwizzleOffset = 0; - - /*static const UINT_32 Prt_Xor_Gap = - static_cast<UINT_32>(ADDR_SW_64KB_Z_T) - static_cast<UINT_32>(ADDR_SW_64KB_Z);*/ - - for (UINT_32 i = 1; i < numMipLevels; i++) - { - Dim3d mipStartPos = {0}; - UINT_32 mipTailOffset = 0; - - mipStartPos = GetMipStartPos(rsrcType, - swMode, - pOut->pitch, - pOut->height, - pOut->numSlices, - pOut->blockWidth, - pOut->blockHeight, - pOut->blockSlices, - i, - &mipTailOffset); + UINT_32 rsrcTypeIdx = static_cast<UINT_32>(rsrcType) - 1; + UINT_32 swModeIdx = static_cast<UINT_32>(swMode); - UINT_32 mipSwModeIdx = swModeIdx; - - pMipInfo[i].equationIndex = - m_equationLookupTable[rsrcTypeIdx][mipSwModeIdx][elementBytesLog2]; - pMipInfo[i].mipOffsetXBytes = mipStartPos.w * pOut->blockWidth * (pOut->bpp >> 3); - pMipInfo[i].mipOffsetYPixel = mipStartPos.h * pOut->blockHeight; - pMipInfo[i].mipOffsetZPixel = mipStartPos.d * pOut->blockSlices; - pMipInfo[i].postSwizzleOffset = mipTailOffset; - } - } + index = m_equationLookupTable[rsrcTypeIdx][swModeIdx][elementBytesLog2]; } - else if (pMipInfo != NULL) + + if (pOut->pMipInfo != NULL) { - for (UINT_32 i = 0; i < numMipLevels; i++) + for (UINT_32 i = 0; i < pIn->numMipLevels; i++) { - pMipInfo[i].equationIndex = ADDR_INVALID_EQUATION_INDEX; - pMipInfo[i].mipOffsetXBytes = 0; - pMipInfo[i].mipOffsetYPixel = 0; - pMipInfo[i].mipOffsetZPixel = 0; - pMipInfo[i].postSwizzleOffset = 0; + pOut->pMipInfo[i].equationIndex = index; } } @@ -1967,7 +2058,7 @@ UINT_32 Gfx9Lib::HwlGetEquationIndex( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeBlock256Equation * * @brief @@ -1975,13 +2066,13 @@ UINT_32 Gfx9Lib::HwlGetEquationIndex( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeBlock256Equation( AddrResourceType rsrcType, - AddrSwizzleMode swMode, - UINT_32 elementBytesLog2, - ADDR_EQUATION* pEquation) const + AddrSwizzleMode swMode, + UINT_32 elementBytesLog2, + ADDR_EQUATION* pEquation) const { ADDR_E_RETURNCODE ret = ADDR_OK; @@ -1995,11 +2086,11 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeBlock256Equation( ADDR_CHANNEL_SETTING* pixelBit = &pEquation->addr[elementBytesLog2]; - const UINT_32 MaxBitsUsed = 4; - ADDR_CHANNEL_SETTING x[MaxBitsUsed] = {}; - ADDR_CHANNEL_SETTING y[MaxBitsUsed] = {}; + const UINT_32 maxBitsUsed = 4; + ADDR_CHANNEL_SETTING x[maxBitsUsed] = {}; + ADDR_CHANNEL_SETTING y[maxBitsUsed] = {}; - for (i = 0; i < MaxBitsUsed; i++) + for (i = 0; i < maxBitsUsed; i++) { InitChannel(1, 0, elementBytesLog2 + i, &x[i]); InitChannel(1, 1, i, &y[i]); @@ -2159,7 +2250,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeBlock256Equation( // Post validation if (ret == ADDR_OK) { - Dim2d microBlockDim = Block256b[elementBytesLog2]; + Dim2d microBlockDim = Block256_2d[elementBytesLog2]; ADDR_ASSERT((2u << GetMaxValidChannelIndex(pEquation->addr, 8, 0)) == (microBlockDim.w * (1 << elementBytesLog2))); ADDR_ASSERT((2u << GetMaxValidChannelIndex(pEquation->addr, 8, 1)) == microBlockDim.h); @@ -2169,7 +2260,7 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeBlock256Equation( } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeThinEquation * * @brief @@ -2177,13 +2268,13 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeBlock256Equation( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThinEquation( AddrResourceType rsrcType, - AddrSwizzleMode swMode, - UINT_32 elementBytesLog2, - ADDR_EQUATION* pEquation) const + AddrSwizzleMode swMode, + UINT_32 elementBytesLog2, + ADDR_EQUATION* pEquation) const { ADDR_E_RETURNCODE ret = ADDR_OK; @@ -2204,16 +2295,16 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThinEquation( 2 * GetBankXorBits(blockSizeLog2)); } - const UINT_32 MaxBitsUsed = 14; - ADDR_ASSERT((2 * MaxBitsUsed) >= maxXorBits); - ADDR_CHANNEL_SETTING x[MaxBitsUsed] = {}; - ADDR_CHANNEL_SETTING y[MaxBitsUsed] = {}; + const UINT_32 maxBitsUsed = 14; + ADDR_ASSERT((2 * maxBitsUsed) >= maxXorBits); + ADDR_CHANNEL_SETTING x[maxBitsUsed] = {}; + ADDR_CHANNEL_SETTING y[maxBitsUsed] = {}; - const UINT_32 ExtraXorBits = 16; - ADDR_ASSERT(ExtraXorBits >= maxXorBits - blockSizeLog2); - ADDR_CHANNEL_SETTING xorExtra[ExtraXorBits] = {}; + const UINT_32 extraXorBits = 16; + ADDR_ASSERT(extraXorBits >= maxXorBits - blockSizeLog2); + ADDR_CHANNEL_SETTING xorExtra[extraXorBits] = {}; - for (UINT_32 i = 0; i < MaxBitsUsed; i++) + for (UINT_32 i = 0; i < maxBitsUsed; i++) { InitChannel(1, 0, elementBytesLog2 + i, &x[i]); InitChannel(1, 1, i, &y[i]); @@ -2249,9 +2340,10 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThinEquation( else { ret = HwlComputeBlock256Equation(rsrcType, swMode, elementBytesLog2, pEquation); + if (ret == ADDR_OK) { - Dim2d microBlockDim = Block256b[elementBytesLog2]; + Dim2d microBlockDim = Block256_2d[elementBytesLog2]; xIdx = Log2(microBlockDim.w); yIdx = Log2(microBlockDim.h); lowBits = 8; @@ -2269,48 +2361,56 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThinEquation( { xorExtra[i - blockSizeLog2] = ((i & 1) == 0) ? y[yIdx++] : x[xIdx++]; } - } - if ((ret == ADDR_OK) && IsXor(swMode)) - { - // Fill XOR bits - UINT_32 pipeStart = m_pipeInterleaveLog2; - UINT_32 pipeXorBits = GetPipeXorBits(blockSizeLog2); - for (UINT_32 i = 0; i < pipeXorBits; i++) + if (IsXor(swMode)) { - UINT_32 xor1BitPos = pipeStart + 2 * pipeXorBits - 1 - i; - ADDR_CHANNEL_SETTING* pXor1Src = - (xor1BitPos < blockSizeLog2) ? - &pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2]; + // Fill XOR bits + UINT_32 pipeStart = m_pipeInterleaveLog2; + UINT_32 pipeXorBits = GetPipeXorBits(blockSizeLog2); - InitChannel(&pEquation->xor1[pipeStart + i], pXor1Src); - } + UINT_32 bankStart = pipeStart + pipeXorBits; + UINT_32 bankXorBits = GetBankXorBits(blockSizeLog2); - UINT_32 bankStart = pipeStart + pipeXorBits; - UINT_32 bankXorBits = GetBankXorBits(blockSizeLog2); - 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]; + 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); + } - InitChannel(&pEquation->xor1[pipeStart + i], pXor1Src); + if (IsPrt(swMode) == FALSE) + { + for (UINT_32 i = 0; i < pipeXorBits; i++) + { + InitChannel(1, 2, pipeXorBits - i - 1, &pEquation->xor2[pipeStart + i]); + } + + for (UINT_32 i = 0; i < bankXorBits; i++) + { + InitChannel(1, 2, bankXorBits - i - 1 + pipeXorBits, &pEquation->xor2[bankStart + i]); + } + } } pEquation->numBits = blockSizeLog2; } - if ((ret == ADDR_OK) && IsTex3d(rsrcType)) - { - pEquation->stackedDepthSlices = TRUE; - } - return ret; } /** -**************************************************************************************************** +************************************************************************************************************************ * Gfx9Lib::HwlComputeThickEquation * * @brief @@ -2318,13 +2418,13 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThinEquation( * * @return * ADDR_E_RETURNCODE -**************************************************************************************************** +************************************************************************************************************************ */ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThickEquation( AddrResourceType rsrcType, - AddrSwizzleMode swMode, - UINT_32 elementBytesLog2, - ADDR_EQUATION* pEquation) const + AddrSwizzleMode swMode, + UINT_32 elementBytesLog2, + ADDR_EQUATION* pEquation) const { ADDR_E_RETURNCODE ret = ADDR_OK; @@ -2354,17 +2454,17 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThickEquation( ADDR_CHANNEL_SETTING* pixelBit = &pEquation->addr[elementBytesLog2]; - 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] = {}; + 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] = {}; - const UINT_32 ExtraXorBits = 24; - ADDR_ASSERT(ExtraXorBits >= maxXorBits - blockSizeLog2); - ADDR_CHANNEL_SETTING xorExtra[ExtraXorBits] = {}; + const UINT_32 extraXorBits = 24; + ADDR_ASSERT(extraXorBits >= maxXorBits - blockSizeLog2); + ADDR_CHANNEL_SETTING xorExtra[extraXorBits] = {}; - for (UINT_32 i = 0; i < MaxBitsUsed; i++) + for (UINT_32 i = 0; i < maxBitsUsed; i++) { InitChannel(1, 0, elementBytesLog2 + i, &x[i]); InitChannel(1, 1, i, &y[i]); @@ -2499,24 +2599,24 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThickEquation( if (ret == ADDR_OK) { - Dim3d microBlockDim = Block1kb[elementBytesLog2]; + Dim3d microBlockDim = Block1K_3d[elementBytesLog2]; UINT_32 xIdx = Log2(microBlockDim.w); UINT_32 yIdx = Log2(microBlockDim.h); UINT_32 zIdx = Log2(microBlockDim.d); pixelBit = pEquation->addr; - static const UINT_32 lowBits = 10; + const UINT_32 lowBits = 10; ADDR_ASSERT(pEquation->addr[lowBits - 1].valid == 1); ADDR_ASSERT(pEquation->addr[lowBits].valid == 0); for (UINT_32 i = lowBits; i < blockSizeLog2; i++) { - if (((i - lowBits) % 3) == 0) + if ((i % 3) == 0) { pixelBit[i] = x[xIdx++]; } - else if (((i - lowBits) % 3) == 1) + else if ((i % 3) == 1) { pixelBit[i] = z[zIdx++]; } @@ -2528,11 +2628,11 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThickEquation( for (UINT_32 i = blockSizeLog2; i < maxXorBits; i++) { - if (((i - lowBits) % 3) == 0) + if ((i % 3) == 0) { xorExtra[i - blockSizeLog2] = x[xIdx++]; } - else if (((i - lowBits) % 3) == 1) + else if ((i % 3) == 1) { xorExtra[i - blockSizeLog2] = z[zIdx++]; } @@ -2541,47 +2641,43 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThickEquation( xorExtra[i - blockSizeLog2] = y[yIdx++]; } } - } - if ((ret == ADDR_OK) && IsXor(swMode)) - { - // Fill XOR bits - UINT_32 pipeStart = m_pipeInterleaveLog2; - UINT_32 pipeXorBits = GetPipeXorBits(blockSizeLog2); - for (UINT_32 i = 0; i < pipeXorBits; i++) + if (IsXor(swMode)) { - UINT_32 xor1BitPos = pipeStart + (3 * pipeXorBits) - 1 - (2 * i); - ADDR_CHANNEL_SETTING* pXor1Src = - (xor1BitPos < blockSizeLog2) ? - &pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2]; + // 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]; - InitChannel(&pEquation->xor1[pipeStart + i], pXor1Src); + InitChannel(&pEquation->xor1[pipeStart + i], pXor1Src); - UINT_32 xor2BitPos = pipeStart + (3 * pipeXorBits) - 2 - (2 * i); - ADDR_CHANNEL_SETTING* pXor2Src = - (xor2BitPos < blockSizeLog2) ? - &pEquation->addr[xor2BitPos] : &xorExtra[xor2BitPos - blockSizeLog2]; + UINT_32 xor2BitPos = pipeStart + (3 * pipeXorBits) - 2 - (2 * i); + ADDR_CHANNEL_SETTING* pXor2Src = (xor2BitPos < blockSizeLog2) ? + &pEquation->addr[xor2BitPos] : &xorExtra[xor2BitPos - blockSizeLog2]; - InitChannel(&pEquation->xor2[pipeStart + i], pXor2Src); - } + InitChannel(&pEquation->xor2[pipeStart + i], pXor2Src); + } - 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]; + 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]; - InitChannel(&pEquation->xor1[bankStart + i], pXor1Src); + InitChannel(&pEquation->xor1[bankStart + i], pXor1Src); - UINT_32 xor2BitPos = bankStart + (3 * bankXorBits) - 2 - (2 * i); - ADDR_CHANNEL_SETTING* pXor2Src = - (xor2BitPos < blockSizeLog2) ? - &pEquation->addr[xor2BitPos] : &xorExtra[xor2BitPos - blockSizeLog2]; + UINT_32 xor2BitPos = bankStart + (3 * bankXorBits) - 2 - (2 * i); + ADDR_CHANNEL_SETTING* pXor2Src = (xor2BitPos < blockSizeLog2) ? + &pEquation->addr[xor2BitPos] : &xorExtra[xor2BitPos - blockSizeLog2]; - InitChannel(&pEquation->xor2[bankStart + i], pXor2Src); + InitChannel(&pEquation->xor2[bankStart + i], pXor2Src); + } } pEquation->numBits = blockSizeLog2; @@ -2591,17 +2687,18 @@ ADDR_E_RETURNCODE Gfx9Lib::HwlComputeThickEquation( } /** -**************************************************************************************************** -* Gfx9Lib::HwlIsValidDisplaySwizzleMode +************************************************************************************************************************ +* Gfx9Lib::IsValidDisplaySwizzleMode * * @brief * Check if a swizzle mode is supported by display engine * * @return * TRUE is swizzle mode is supported by display engine -**************************************************************************************************** +************************************************************************************************************************ */ -BOOL_32 Gfx9Lib::HwlIsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const +BOOL_32 Gfx9Lib::IsValidDisplaySwizzleMode( + const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const { BOOL_32 support = FALSE; @@ -2645,5 +2742,1762 @@ BOOL_32 Gfx9Lib::HwlIsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_I return support; } +/** +************************************************************************************************************************ +* 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; + } + 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; +} + } // V2 } // Addr diff --git a/src/amd/addrlib/gfx9/gfx9addrlib.h b/src/amd/addrlib/gfx9/gfx9addrlib.h index 4a0ccd91d72..73d51f1ef7a 100644 --- a/src/amd/addrlib/gfx9/gfx9addrlib.h +++ b/src/amd/addrlib/gfx9/gfx9addrlib.h @@ -25,10 +25,10 @@ */ /** -**************************************************************************************************** +************************************************************************************************************************ * @file gfx9addrlib.h * @brief Contgfx9ns the Gfx9Lib class definition. -**************************************************************************************************** +************************************************************************************************************************ */ #ifndef __GFX9_ADDR_LIB_H__ @@ -43,9 +43,9 @@ namespace V2 { /** -**************************************************************************************************** +************************************************************************************************************************ * @brief GFX9 specific settings structure. -**************************************************************************************************** +************************************************************************************************************************ */ struct Gfx9ChipSettings { @@ -62,14 +62,15 @@ struct Gfx9ChipSettings // Misc configuration bits UINT_32 metaBaseAlignFix : 1; - UINT_32 reserved2 : 31; + UINT_32 depthPipeXorDisable : 1; + UINT_32 reserved2 : 30; }; }; /** -**************************************************************************************************** +************************************************************************************************************************ * @brief GFX9 data surface type. -**************************************************************************************************** +************************************************************************************************************************ */ enum Gfx9DataType { @@ -79,10 +80,10 @@ enum Gfx9DataType }; /** -**************************************************************************************************** +************************************************************************************************************************ * @brief This class is the GFX9 specific address library * function set. -**************************************************************************************************** +************************************************************************************************************************ */ class Gfx9Lib : public Lib { @@ -98,6 +99,39 @@ protected: Gfx9Lib(const Client* pClient); virtual ~Gfx9Lib(); + virtual BOOL_32 HwlIsStandardSwizzle( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode) const + { + return m_swizzleModeTable[swizzleMode].isStd || + (IsTex3d(resourceType) && m_swizzleModeTable[swizzleMode].isDisp); + } + + virtual BOOL_32 HwlIsDisplaySwizzle( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode) const + { + return IsTex2d(resourceType) && m_swizzleModeTable[swizzleMode].isDisp; + } + + virtual BOOL_32 HwlIsThin( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode) const + { + return ((IsTex2d(resourceType) == TRUE) || + ((IsTex3d(resourceType) == TRUE) && + (m_swizzleModeTable[swizzleMode].isZ == FALSE) && + (m_swizzleModeTable[swizzleMode].isStd == FALSE))); + } + + virtual BOOL_32 HwlIsThick( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode) const + { + return (IsTex3d(resourceType) && + (m_swizzleModeTable[swizzleMode].isZ || m_swizzleModeTable[swizzleMode].isStd)); + } + virtual ADDR_E_RETURNCODE HwlComputeHtileInfo( const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn, ADDR2_COMPUTE_HTILE_INFO_OUTPUT* pOut) const; @@ -122,6 +156,10 @@ protected: const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT* pOut) const; + virtual ADDR_E_RETURNCODE HwlComputeDccAddrFromCoord( + const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn, + ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut) const; + virtual UINT_32 HwlGetEquationIndex( const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const; @@ -183,13 +221,139 @@ protected: return baseAlign; } - virtual BOOL_32 HwlIsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const; + virtual ADDR_E_RETURNCODE HwlComputePipeBankXor( + const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn, + ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut) const; - virtual BOOL_32 HwlIsDce12() const { return m_settings.isDce12; } + virtual ADDR_E_RETURNCODE HwlComputeSlicePipeBankXor( + const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn, + ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut) const; + + virtual ADDR_E_RETURNCODE HwlComputeSubResourceOffsetForSwizzlePattern( + const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn, + ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut) const; + + virtual ADDR_E_RETURNCODE HwlGetPreferredSurfaceSetting( + const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn, + ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT* pOut) const; + + virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoSanityCheck( + const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const; + + virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoTiled( + const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, + ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const; + + virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoordTiled( + const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, + ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const; // Initialize equation table VOID InitEquationTable(); + ADDR_E_RETURNCODE ComputeStereoInfo( + const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, + ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut, + UINT_32* pHeightAlign) const; + + UINT_32 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; + + VOID GetMetaMiptailInfo( + ADDR2_META_MIP_INFO* pInfo, + Dim3d mipCoord, + UINT_32 numMipInTail, + Dim3d* pMetaBlkDim) const; + + Dim3d 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; + + AddrMajorMode GetMajorMode( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode, + UINT_32 mip0WidthInBlk, + UINT_32 mip0HeightInBlk, + UINT_32 mip0DepthInBlk) const + { + BOOL_32 yMajor = (mip0WidthInBlk < mip0HeightInBlk); + BOOL_32 xMajor = (yMajor == FALSE); + + if (IsThick(resourceType, swizzleMode)) + { + yMajor = yMajor && (mip0HeightInBlk >= mip0DepthInBlk); + xMajor = xMajor && (mip0WidthInBlk >= mip0DepthInBlk); + } + + AddrMajorMode majorMode; + if (xMajor) + { + majorMode = ADDR_MAJOR_X; + } + else if (yMajor) + { + majorMode = ADDR_MAJOR_Y; + } + else + { + majorMode = ADDR_MAJOR_Z; + } + + return majorMode; + } + + Dim3d GetDccCompressBlk( + AddrResourceType resourceType, + AddrSwizzleMode swizzleMode, + UINT_32 bpp) const + { + UINT_32 index = Log2(bpp >> 3); + Dim3d compressBlkDim; + + if (IsThin(resourceType, swizzleMode)) + { + compressBlkDim.w = Block256_2d[index].w; + compressBlkDim.h = Block256_2d[index].h; + compressBlkDim.d = 1; + } + else if (IsStandardSwizzle(resourceType, swizzleMode)) + { + compressBlkDim = Block256_3dS[index]; + } + else + { + compressBlkDim = Block256_3dZ[index]; + } + + return compressBlkDim; + } + + static const Dim3d Block256_3dS[MaxNumOfBpp]; + static const Dim3d Block256_3dZ[MaxNumOfBpp]; + + static const UINT_32 MipTailOffset256B[]; + + static const SwizzleModeFlags SwizzleModeTable[ADDR_SW_MAX_TYPE]; + // Max number of swizzle mode supported for equation static const UINT_32 MaxSwMode = 32; // Max number of resource type (2D/3D) supported for equation @@ -239,6 +403,8 @@ private: UINT_32 mip0Width, UINT_32 mip0Height, UINT_32 mip0Depth, UINT_32* pNumMetaBlkX, UINT_32* pNumMetaBlkY, UINT_32* pNumMetaBlkZ) const; + BOOL_32 IsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const; + Gfx9ChipSettings m_settings; }; |