Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Copyright © 2016-2017 MasterVermilli0n/AboodXD
- // Credits:
- // -Exzap: original code
- // -MasterVermilli0n/AboodXD: porting, code improvements and cleaning up
- typedef unsigned char u8;
- typedef unsigned int u32;
- typedef long long s64;
- typedef unsigned long long u64;
- #define max(a,b) \
- ({ __typeof__ (a) _a = (a); \
- __typeof__ (b) _b = (b); \
- _a > _b ? _a : _b; })
- #define min(a,b) \
- ({ __typeof__ (a) _a = (a); \
- __typeof__ (b) _b = (b); \
- _a < _b ? _a : _b; })
- static u32 m_banks = 4;
- static u32 m_banksBitcount = 2;
- static u32 m_pipes = 2;
- static u32 m_pipesBitcount = 1;
- static u32 m_pipeInterleaveBytes = 256;
- static u32 m_pipeInterleaveBytesBitcount = 8;
- static u32 m_rowSize = 2048;
- static u32 m_swapSize = 256;
- static u32 m_splitSize = 2048;
- static u32 m_chipFamily = 2;
- static u32 MicroTilePixels = 64;
- u8 formatHwInfo[0x40*4] =
- {
- 0x00,0x00,0x00,0x01,0x08,0x03,0x00,0x01,0x08,0x01,0x00,0x01,0x00,0x00,0x00,0x01,
- 0x00,0x00,0x00,0x01,0x10,0x07,0x00,0x00,0x10,0x03,0x00,0x01,0x10,0x03,0x00,0x01,
- 0x10,0x0B,0x00,0x01,0x10,0x01,0x00,0x01,0x10,0x03,0x00,0x01,0x10,0x03,0x00,0x01,
- 0x10,0x03,0x00,0x01,0x20,0x03,0x00,0x00,0x20,0x07,0x00,0x00,0x20,0x03,0x00,0x00,
- 0x20,0x03,0x00,0x01,0x20,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x03,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x03,0x00,0x01,0x00,0x00,0x00,0x01,
- 0x00,0x00,0x00,0x01,0x20,0x0B,0x00,0x01,0x20,0x0B,0x00,0x01,0x20,0x0B,0x00,0x01,
- 0x40,0x05,0x00,0x00,0x40,0x03,0x00,0x00,0x40,0x03,0x00,0x00,0x40,0x03,0x00,0x00,
- 0x40,0x03,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x80,0x03,0x00,0x00,
- 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x10,0x01,0x00,0x00,
- 0x10,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,
- 0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x60,0x01,0x00,0x00,
- 0x60,0x01,0x00,0x00,0x40,0x01,0x00,0x01,0x80,0x01,0x00,0x01,0x80,0x01,0x00,0x01,
- 0x40,0x01,0x00,0x01,0x80,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
- };
- u32 surfaceGetBitsPerPixel(u32 surfaceFormat)
- {
- u32 hwFormat = surfaceFormat & 0x3F;
- u32 bpp = formatHwInfo[hwFormat * 4];
- return bpp;
- }
- u32 computeSurfaceThickness(u32 tileMode)
- {
- u32 thickness;
- switch (tileMode)
- {
- case 3:
- case 7:
- case 11:
- case 13:
- case 15:
- thickness = 4;
- break;
- case 16:
- case 17:
- thickness = 8;
- break;
- default:
- thickness = 1;
- break;
- }
- return thickness;
- }
- u32 computePixelIndexWithinMicroTile(u32 x, u32 y, u32 bpp, u32 tileMode)
- {
- u32 z = 0;
- u32 thickness, pixelBit8, pixelBit7, pixelBit6, pixelBit5;
- u32 pixelBit4, pixelBit3, pixelBit2, pixelBit1, pixelBit0;
- pixelBit6 = 0;
- pixelBit7 = 0;
- pixelBit8 = 0;
- thickness = computeSurfaceThickness(tileMode);
- switch (bpp)
- {
- case 0x08:
- pixelBit0 = x & 1;
- pixelBit1 = (x & 2) >> 1;
- pixelBit2 = (x & 4) >> 2;
- pixelBit3 = (y & 2) >> 1;
- pixelBit4 = y & 1;
- pixelBit5 = (y & 4) >> 2;
- break;
- case 0x10:
- pixelBit0 = x & 1;
- pixelBit1 = (x & 2) >> 1;
- pixelBit2 = (x & 4) >> 2;
- pixelBit3 = y & 1;
- pixelBit4 = (y & 2) >> 1;
- pixelBit5 = (y & 4) >> 2;
- break;
- case 0x20:
- case 0x60:
- pixelBit0 = x & 1;
- pixelBit1 = (x & 2) >> 1;
- pixelBit2 = y & 1;
- pixelBit3 = (x & 4) >> 2;
- pixelBit4 = (y & 2) >> 1;
- pixelBit5 = (y & 4) >> 2;
- break;
- case 0x40:
- pixelBit0 = x & 1;
- pixelBit1 = y & 1;
- pixelBit2 = (x & 2) >> 1;
- pixelBit3 = (x & 4) >> 2;
- pixelBit4 = (y & 2) >> 1;
- pixelBit5 = (y & 4) >> 2;
- break;
- case 0x80:
- pixelBit0 = y & 1;
- pixelBit1 = x & 1;
- pixelBit2 = (x & 2) >> 1;
- pixelBit3 = (x & 4) >> 2;
- pixelBit4 = (y & 2) >> 1;
- pixelBit5 = (y & 4) >> 2;
- break;
- default:
- pixelBit0 = x & 1;
- pixelBit1 = (x & 2) >> 1;
- pixelBit2 = y & 1;
- pixelBit3 = (x & 4) >> 2;
- pixelBit4 = (y & 2) >> 1;
- pixelBit5 = (y & 4) >> 2;
- break;
- }
- if (thickness > 1)
- {
- pixelBit6 = z & 1;
- pixelBit7 = (z & 2) >> 1;
- }
- if (thickness == 8)
- pixelBit8 = (z & 4) >> 2;
- return ((pixelBit8 << 8) | (pixelBit7 << 7) | (pixelBit6 << 6) |
- 32 * pixelBit5 | 16 * pixelBit4 | 8 * pixelBit3 |
- 4 * pixelBit2 | pixelBit0 | 2 * pixelBit1);
- }
- u32 computePipeFromCoordWoRotation(u32 x, u32 y)
- {
- // hardcoded to assume 2 pipes
- return ((y >> 3) ^ (x >> 3)) & 1;
- }
- u32 computeBankFromCoordWoRotation(u32 x, u32 y)
- {
- u32 numPipes = m_pipes;
- u32 numBanks = m_banks;
- u32 bankBit0, bankBit0a;
- u32 bank = 0;
- if (numBanks == 4)
- {
- bankBit0 = ((y / (16 * numPipes)) ^ (x >> 3)) & 1;
- bank = bankBit0 | 2 * (((y / (8 * numPipes)) ^ (x >> 4)) & 1);
- }
- else if (numBanks == 8)
- {
- bankBit0a = ((y / (32 * numPipes)) ^ (x >> 3)) & 1;
- bank = (bankBit0a | 2 * (((y / (32 * numPipes)) ^ (y / (16 * numPipes) ^ (x >> 4))) & 1) |
- 4 * (((y / (8 * numPipes)) ^ (x >> 5)) & 1));
- }
- return bank;
- }
- u32 isThickMacroTiled(u32 tileMode)
- {
- u32 thickMacroTiled;
- switch (tileMode)
- {
- case 7:
- case 11:
- case 13:
- case 15:
- thickMacroTiled = 1;
- break;
- default:
- thickMacroTiled = 0;
- break;
- }
- return thickMacroTiled;
- }
- u32 isBankSwappedTileMode(u32 tileMode)
- {
- u32 bankSwapped;
- switch (tileMode)
- {
- case 8:
- case 9:
- case 10:
- case 11:
- case 14:
- case 15:
- bankSwapped = 1;
- break;
- default:
- bankSwapped = 0;
- break;
- }
- return bankSwapped;
- }
- u32 computeMacroTileAspectRatio(u32 tileMode)
- {
- u32 ratio;
- switch (tileMode)
- {
- case 8:
- case 12:
- case 14:
- ratio = 1;
- break;
- case 5:
- case 9:
- ratio = 2;
- break;
- case 6:
- case 10:
- ratio = 4;
- break;
- default:
- ratio = 1;
- break;
- }
- return ratio;
- }
- u32 computeSurfaceBankSwappedWidth(u32 tileMode, u32 bpp, u32 pitch, u32 numSamples)
- {
- if (isBankSwappedTileMode(tileMode) == 0)
- return 0;
- u32 numBanks = m_banks;
- u32 numPipes = m_pipes;
- u32 swapSize = m_swapSize;
- u32 rowSize = m_rowSize;
- u32 splitSize = m_splitSize;
- u32 groupSize = m_pipeInterleaveBytesBitcount;
- u32 bytesPerSample = 8 * bpp;
- u32 samplesPerTile, slicesPerTile;
- if (bytesPerSample != 0)
- {
- samplesPerTile = splitSize / bytesPerSample;
- slicesPerTile = max(1, numSamples / samplesPerTile);
- }
- else
- slicesPerTile = 1;
- if (isThickMacroTiled(tileMode) != 0)
- numSamples = 4;
- u32 bytesPerTileSlice = numSamples * bytesPerSample / slicesPerTile;
- u32 factor = computeMacroTileAspectRatio(tileMode);
- u32 swapTiles = max(1, (swapSize >> 1) / bpp);
- u32 swapWidth = swapTiles * 8 * numBanks;
- u32 heightBytes = numSamples * factor * numPipes * bpp / slicesPerTile;
- u32 swapMax = numPipes * numBanks * rowSize / heightBytes;
- u32 swapMin = groupSize * 8 * numBanks / bytesPerTileSlice;
- u32 bankSwapWidth = min(swapMax, max(swapMin, swapWidth));
- while (bankSwapWidth >= 2 * pitch)
- bankSwapWidth >>= 1;
- return bankSwapWidth;
- }
- u64 computeSurfaceAddrFromCoordLinear(u32 x, u32 y, u32 bpp, u32 pitch)
- {
- u64 rowOffset = y * pitch;
- u64 pixOffset = x;
- u64 addr = (rowOffset + pixOffset) * bpp;
- addr /= 8;
- return addr;
- }
- u64 computeSurfaceAddrFromCoordMicroTiled(u32 x, u32 y, u32 bpp, u32 pitch,
- u32 tileMode)
- {
- int microTileThickness = 1;
- if (tileMode == 3)
- microTileThickness = 4;
- u32 microTileBytes = (MicroTilePixels * microTileThickness * bpp + 7) / 8;
- u32 microTilesPerRow = pitch >> 3;
- u32 microTileIndexX = x >> 3;
- u32 microTileIndexY = y >> 3;
- u64 microTileOffset = microTileBytes * (microTileIndexX + microTileIndexY * microTilesPerRow);
- u32 pixelIndex = computePixelIndexWithinMicroTile(x, y, bpp, tileMode);
- u64 pixelOffset = bpp * pixelIndex;
- pixelOffset >>= 3;
- return pixelOffset + microTileOffset;
- }
- u64 computeSurfaceAddrFromCoordMacroTiled(u32 x, u32 y, u32 bpp, u32 pitch, u32 height,
- u32 tileMode, u32 pipeSwizzle,
- u32 bankSwizzle)
- {
- u32 sampleSlice, numSamples, samplesPerSlice;
- u32 numSampleSplits, bankSwapWidth, swapIndex;
- u8 bankSwapOrder[10] = {0, 1, 3, 2, 6, 7, 5, 4, 0, 0};
- u32 numPipes = m_pipes;
- u32 numBanks = m_banks;
- u32 numGroupBits = m_pipeInterleaveBytesBitcount;
- u32 numPipeBits = m_pipesBitcount;
- u32 numBankBits = m_banksBitcount;
- u32 microTileThickness = computeSurfaceThickness(tileMode);
- u32 microTileBits = bpp * (microTileThickness * MicroTilePixels);
- u32 microTileBytes = (microTileBits + 7) / 8;
- u32 pixelIndex = computePixelIndexWithinMicroTile(x, y, bpp, tileMode);
- u64 pixelOffset = bpp * pixelIndex;
- u64 elemOffset = pixelOffset;
- u32 bytesPerSample = microTileBytes;
- if (microTileBytes <= m_splitSize)
- {
- numSamples = 1;
- sampleSlice = 0;
- }
- else
- {
- samplesPerSlice = m_splitSize / bytesPerSample;
- numSampleSplits = max(1, 1 / samplesPerSlice);
- numSamples = samplesPerSlice;
- sampleSlice = elemOffset / (microTileBits / numSampleSplits);
- elemOffset %= microTileBits / numSampleSplits;
- }
- elemOffset += 7;
- elemOffset /= 8;
- u32 pipe = computePipeFromCoordWoRotation(x, y);
- u32 bank = computeBankFromCoordWoRotation(x, y);
- u32 bankPipe = pipe + numPipes * bank;
- u32 swizzle_ = pipeSwizzle + numPipes * bankSwizzle;
- bankPipe ^= numPipes * sampleSlice * ((numBanks >> 1) + 1) ^ swizzle_;
- bankPipe %= numPipes * numBanks;
- pipe = bankPipe % numPipes;
- bank = bankPipe / numPipes;
- u32 sliceBytes = (height * pitch * microTileThickness * bpp * numSamples + 7) / 8;
- u32 sliceOffset = sliceBytes * (sampleSlice / microTileThickness);
- u32 macroTilePitch = 8 * m_banks;
- u32 macroTileHeight = 8 * m_pipes;
- switch (tileMode)
- {
- case 5: // GX2_TILE_MODE_2D_TILED_THIN2
- case 9: // GX2_TILE_MODE_2B_TILED_THIN2
- macroTilePitch >>= 1;
- macroTileHeight *= 2;
- break;
- case 6: // GX2_TILE_MODE_2D_TILED_THIN4
- case 10: // GX2_TILE_MODE_2B_TILED_THIN4
- macroTilePitch >>= 2;
- macroTileHeight *= 4;
- break;
- }
- u32 macroTilesPerRow = pitch / macroTilePitch;
- u32 macroTileBytes = (numSamples * microTileThickness * bpp * macroTileHeight * macroTilePitch + 7) / 8;
- u32 macroTileIndexX = x / macroTilePitch;
- u32 macroTileIndexY = y / macroTileHeight;
- u64 macroTileOffset = (macroTileIndexX + macroTilesPerRow * macroTileIndexY) * macroTileBytes;
- if (tileMode == 8 || tileMode == 9 || tileMode == 10 || tileMode == 11 || tileMode == 14 || tileMode == 15)
- {
- bankSwapWidth = computeSurfaceBankSwappedWidth(tileMode, bpp, pitch, 1);
- swapIndex = macroTilePitch * macroTileIndexX / bankSwapWidth;
- bank ^= bankSwapOrder[swapIndex & (m_banks - 1)];
- }
- u32 groupMask = ((1 << numGroupBits) - 1);
- u32 numSwizzleBits = (numBankBits + numPipeBits);
- u64 totalOffset = (elemOffset + ((macroTileOffset + sliceOffset) >> numSwizzleBits));
- u64 offsetHigh = (totalOffset & ~groupMask) << numSwizzleBits;
- u64 offsetLow = groupMask & totalOffset;
- u64 pipeBits = pipe << numGroupBits;
- u64 bankBits = bank << (numPipeBits + numGroupBits);
- return bankBits | pipeBits | offsetLow | offsetHigh;
- }
- static u32 ADDR_OK = 0;
- static u32 m_configFlags = 4;
- typedef struct
- {
- u32 value;
- } Flags;
- typedef struct
- {
- u32 banks;
- u32 bankWidth;
- u32 bankHeight;
- u32 macroAspectRatio;
- u32 tileSplitBytes;
- u32 pipeConfig;
- } tileInfo;
- typedef struct
- {
- u32 size;
- u32 tileMode;
- u32 format;
- u32 bpp;
- u32 numSamples;
- u32 width;
- u32 height;
- u32 numSlices;
- u32 slice;
- u32 mipLevel;
- Flags flags;
- u32 numFrags;
- tileInfo *pTileInfo;
- int tileIndex;
- } surfaceIn;
- typedef struct
- {
- u32 size;
- u32 pitch;
- u32 height;
- u32 depth;
- s64 surfSize;
- u32 tileMode;
- u32 baseAlign;
- u32 pitchAlign;
- u32 heightAlign;
- u32 depthAlign;
- u32 bpp;
- u32 pixelPitch;
- u32 pixelHeight;
- u32 pixelBits;
- u32 sliceSize;
- u32 pitchTileMax;
- u32 heightTileMax;
- u32 sliceTileMax;
- tileInfo *pTileInfo;
- u32 tileType;
- int tileIndex;
- } surfaceOut;
- surfaceIn pIn;
- surfaceOut pOut;
- u32 getFillSizeFieldsFlags()
- {
- return (m_configFlags >> 6) & 1;
- }
- u32 getSliceComputingFlags()
- {
- return (m_configFlags >> 4) & 3;
- }
- u32 powTwoAlign(u32 x, u32 align)
- {
- return ~(align - 1) & (x + align - 1);
- }
- u32 nextPow2(u32 dim)
- {
- u32 newDim = 1;
- if (dim <= 0x7FFFFFFF)
- {
- while (newDim < dim)
- newDim *= 2;
- }
- else
- newDim = 2147483648;
- return newDim;
- }
- u32 useTileIndex(u32 index)
- {
- if ((m_configFlags >> 7) & 1 != 0 && index != -1)
- return 1;
- else
- return 0;
- }
- u32 getBitsPerPixel(u32 format_, u32 *expandX, u32 *expandY, u32 *elemMode)
- {
- *expandY = 1;
- u32 bitUnused = 0;
- *elemMode = 3;
- u32 bpp;
- switch (format_)
- {
- case 1:
- bpp = 8;
- *expandX = 1;
- break;
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- case 11:
- bpp = 16;
- *expandX = 1;
- break;
- case 39:
- *elemMode = 7;
- bpp = 16;
- *expandX = 1;
- break;
- case 40:
- *elemMode = 8;
- bpp = 16;
- *expandX = 1;
- break;
- case 13:
- case 14:
- case 15:
- case 16:
- case 19:
- case 20:
- case 21:
- case 23:
- case 25:
- case 26:
- bpp = 32;
- *expandX = 1;
- break;
- case 29:
- case 30:
- case 31:
- case 32:
- case 62:
- bpp = 64;
- *expandX = 1;
- break;
- case 34:
- case 35:
- bpp = 128;
- *expandX = 1;
- break;
- case 0:
- bpp = 0;
- *expandX = 1;
- break;
- case 38:
- *elemMode = 6;
- bpp = 1;
- *expandX = 8;
- break;
- case 37:
- *elemMode = 5;
- bpp = 1;
- *expandX = 8;
- break;
- case 2:
- case 3:
- bpp = 8;
- *expandX = 1;
- break;
- case 12:
- bpp = 16;
- *expandX = 1;
- break;
- case 17:
- case 18:
- case 22:
- case 24:
- case 27:
- case 41:
- case 42:
- case 43:
- bpp = 32;
- *expandX = 1;
- break;
- case 28:
- bpp = 64;
- bitUnused = 24;
- *expandX = 1;
- break;
- case 44:
- *elemMode = 4;
- bpp = 24;
- *expandX = 3;
- break;
- case 45:
- case 46:
- *elemMode = 4;
- bpp = 48;
- *expandX = 3;
- break;
- case 47:
- case 48:
- *elemMode = 4;
- bpp = 96;
- *expandX = 3;
- break;
- case 49:
- *elemMode = 9;
- *expandY = 4;
- bpp = 64;
- *expandX = 4;
- break;
- case 52:
- *elemMode = 12;
- *expandY = 4;
- bpp = 64;
- *expandX = 4;
- break;
- case 50:
- *elemMode = 10;
- *expandY = 4;
- bpp = 128;
- *expandX = 4;
- break;
- case 51:
- *elemMode = 11;
- *expandY = 4;
- bpp = 128;
- *expandX = 4;
- break;
- case 53:
- case 54:
- case 55:
- *elemMode = 13;
- *expandY = 4;
- bpp = 128;
- *expandX = 4;
- break;
- default:
- bpp = 0;
- *expandX = 1;
- return bpp;
- }
- u32 adjustSurfaceInfo(u32 elemMode, u32 expandX, u32 expandY, u32 pBpp, u32 pWidth, u32 pHeight)
- {
- u32 bBCnFormat = 0;
- u32 bpp, packedBits, width, height;
- u32 widtha, heighta;
- if (pBpp != 0)
- {
- bpp = pBpp;
- switch (elemMode)
- {
- case 4:
- packedBits = bpp / expandX / expandY;
- break;
- case 5:
- case 6:
- packedBits = expandY * expandX * bpp;
- break;
- case 7:
- case 8:
- packedBits = pBpp;
- break;
- case 9:
- case 12:
- packedBits = 64;
- bBCnFormat = 1;
- break;
- case 10:
- case 11:
- case 13:
- bBCnFormat = 1;
- packedBits = 128;
- break;
- case 0:
- case 1:
- case 2:
- case 3:
- packedBits = pBpp;
- break;
- default:
- packedBits = pBpp;
- break;
- }
- pIn.bpp = packedBits;
- }
- if (pWidth != 0)
- {
- if (pHeight != 0)
- {
- width = pWidth;
- height = pHeight;
- if (expandX > 1 || expandY > 1)
- {
- if (elemMode == 4)
- {
- widtha = expandX * width;
- heighta = expandY * height;
- }
- else if (bBCnFormat != 0)
- {
- widtha = width / expandX;
- heighta = height / expandY;
- }
- else
- {
- widtha = (width + expandX - 1) / expandX;
- heighta = (height + expandY - 1) / expandY;
- }
- pIn.width = max(1, widtha);
- pIn.height = max(1, heighta);
- }
- }
- }
- return packedBits;
- }
- u32 hwlComputeMipLevel()
- {
- u32 width, widtha;
- u32 height, heighta;
- u32 slices;
- u32 handled = 0;
- if (49 <= pIn.format <= 55)
- {
- if (pIn.mipLevel != 0)
- {
- width = pIn.width;
- height = pIn.height;
- slices = pIn.numSlices;
- if ((pIn.flags.value >> 12) & 1 != 0)
- {
- widtha = width >> pIn.mipLevel;
- heighta = height >> pIn.mipLevel;
- if ((pIn.flags.value >> 4) & 1 == 0)
- slices >>= pIn.mipLevel;
- width = max(1, widtha);
- height = max(1, heighta);
- slices = max(1, slices);
- }
- pIn.width = nextPow2(width);
- pIn.height = nextPow2(height);
- pIn.numSlices = slices;
- }
- handled = 1;
- }
- return handled;
- }
- void computeMipLevel()
- {
- u32 slices = 0;
- u32 height = 0;
- u32 width = 0;
- u32 hwlHandled = 0;
- if (49 <= pIn.format <= 55 && (pIn.mipLevel == 0 || (pIn.flags.value >> 12) & 1 != 0))
- {
- pIn.width = powTwoAlign(pIn.width, 4);
- pIn.height = powTwoAlign(pIn.height, 4);
- }
- hwlHandled = hwlComputeMipLevel();
- if (hwlHandled == 0 && pIn.mipLevel != 0 && (pIn.flags.value >> 12) & 1 != 0)
- {
- width = pIn.width;
- height = pIn.height;
- slices = pIn.numSlices;
- width >>= pIn.mipLevel;
- height >>= pIn.mipLevel;
- if ((pIn.flags.value >> 4) & 1 == 0)
- slices >>= pIn.mipLevel;
- width = max(1, width);
- height = max(1, height);
- slices = max(1, slices);
- if (pIn.format != 47 && pIn.format != 48)
- {
- width = nextPow2(width);
- height = nextPow2(height);
- slices = nextPow2(slices);
- }
- pIn.width = width;
- pIn.height = height;
- pIn.numSlices = slices;
- }
- }
- u32 convertToNonBankSwappedMode(u32 tileMode)
- {
- u32 expTileMode;
- switch (tileMode)
- {
- case 8:
- expTileMode = 4;
- break;
- case 9:
- expTileMode = 5;
- break;
- case 10:
- expTileMode = 6;
- break;
- case 11:
- expTileMode = 7;
- break;
- case 14:
- expTileMode = 12;
- break;
- case 15:
- expTileMode = 13;
- break;
- default:
- expTileMode = tileMode;
- }
- return expTileMode;
- }
- u32 computeSurfaceTileSlices(u32 tileMode, u32 bpp, u32 numSamples)
- {
- u32 bytePerSample = ((bpp << 6) + 7) >> 3;
- u32 tileSlices = 1;
- u32 samplePerTile;
- if (computeSurfaceThickness(tileMode) > 1)
- numSamples = 4;
- if (bytePerSample != 0)
- {
- samplePerTile = m_splitSize / bytePerSample;
- if (samplePerTile)
- tileSlices = max(1, numSamples / samplePerTile);
- }
- return tileSlices;
- }
- u32 computeSurfaceRotationFromTileMode(u32 tileMode)
- {
- u32 pipes = m_pipes;
- u32 result;
- switch (tileMode)
- {
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- case 11:
- result = pipes * ((m_banks >> 1) - 1);
- break;
- case 12:
- case 13:
- case 14:
- case 15:
- result = 1;
- break;
- default:
- result = 0;
- break;
- }
- return result;
- }
- u32 computeSurfaceMipLevelTileMode(u32 baseTileMode, u32 bpp, u32 level, u32 width, u32 height, u32 numSlices, u32 numSamples, u32 isDepth, u32 noRecursive)
- {
- u32 expTileMode = baseTileMode;
- u32 numPipes = m_pipes;
- u32 numBanks = m_banks;
- u32 groupBytes = m_pipeInterleaveBytes;
- u32 tileSlices = computeSurfaceTileSlices(baseTileMode, bpp, numSamples);
- u32 widtha, heighta, numSlicesa, thickness, microTileBytes, v13;
- u32 widthAlignFactor, macroTileWidth, macroTileHeight, v11;
- switch (baseTileMode)
- {
- case 5:
- if (2 * m_pipeInterleaveBytes > m_splitSize)
- expTileMode = 4;
- break;
- case 6:
- if (4 * m_pipeInterleaveBytes > m_splitSize)
- expTileMode = 5;
- break;
- case 7:
- if (numSamples > 1 || tileSlices > 1 || isDepth != 0)
- expTileMode = 4;
- break;
- case 13:
- if (numSamples > 1 || tileSlices > 1 || isDepth != 0)
- expTileMode = 12;
- break;
- case 9:
- if (2 * m_pipeInterleaveBytes > m_splitSize)
- expTileMode = 8;
- break;
- case 10:
- if (4 * m_pipeInterleaveBytes > m_splitSize)
- expTileMode = 9;
- break;
- case 11:
- if (numSamples > 1 || tileSlices > 1 || isDepth != 0)
- expTileMode = 8;
- break;
- case 15:
- if (numSamples > 1 || tileSlices > 1 || isDepth != 0)
- expTileMode = 14;
- break;
- case 2:
- if (numSamples > 1 && (m_configFlags >> 2) & 1 != 0)
- expTileMode = 4;
- break;
- case 3:
- if (numSamples > 1 || isDepth != 0)
- expTileMode = 2;
- if (numSamples == 2 || numSamples == 4)
- expTileMode = 7;
- break;
- default:
- expTileMode = baseTileMode;
- }
- u32 rotation = computeSurfaceRotationFromTileMode(expTileMode);
- if (rotation % m_pipes == 0)
- {
- if (expTileMode == 12)
- expTileMode = 4;
- if (expTileMode == 14)
- expTileMode = 8;
- if (expTileMode == 13)
- expTileMode = 7;
- if (expTileMode == 15)
- expTileMode = 11;
- }
- u32 result;
- if (noRecursive != 0)
- result = expTileMode;
- else
- {
- if (bpp == 24 || bpp == 48 || bpp == 96)
- bpp /= 3;
- widtha = nextPow2(width);
- heighta = nextPow2(height);
- numSlicesa = nextPow2(numSlices);
- if (level != 0)
- {
- expTileMode = convertToNonBankSwappedMode(expTileMode);
- thickness = computeSurfaceThickness(expTileMode);
- microTileBytes = (numSamples * bpp * (thickness << 6) + 7) >> 3;
- if (microTileBytes >= groupBytes)
- v13 = 1;
- else
- v13 = groupBytes / microTileBytes;
- widthAlignFactor = v13;
- macroTileWidth = 8 * numBanks;
- macroTileHeight = 8 * numPipes;
- switch (expTileMode)
- {
- case 4:
- case 12:
- if ((widtha < widthAlignFactor * macroTileWidth) || heighta < macroTileHeight)
- expTileMode = 2;
- break;
- case 5:
- macroTileWidth >>= 1;
- macroTileHeight *= 2;
- if ((widtha < widthAlignFactor * macroTileWidth) || heighta < macroTileHeight)
- expTileMode = 2;
- break;
- case 6:
- macroTileWidth >>= 2;
- macroTileHeight *= 4;
- if ((widtha < widthAlignFactor * macroTileWidth) || heighta < macroTileHeight)
- expTileMode = 2;
- break;
- }
- if (expTileMode == 7 || expTileMode == 13)
- if ((widtha < widthAlignFactor * macroTileWidth) || heighta < macroTileHeight)
- expTileMode = 3;
- v11 = expTileMode;
- if (expTileMode == 3)
- if (numSlicesa < 4)
- expTileMode = 2;
- else if (v11 == 7)
- if (numSlicesa < 4)
- expTileMode = 4;
- else if (v11 == 13 && numSlicesa < 4)
- expTileMode = 12;
- result = computeSurfaceMipLevelTileMode(
- expTileMode,
- bpp,
- level,
- widtha,
- heighta,
- numSlicesa,
- numSamples,
- isDepth,
- 1);
- }
- else
- result = expTileMode;
- }
- return result;
- }
- u32 isDualPitchAlignNeeded(u32 tileMode, u32 isDepth, u32 mipLevel)
- {
- u32 needed;
- if (isDepth != 0 || mipLevel != 0 || m_chipFamily != 1)
- needed = 0;
- else if (tileMode == 0 || tileMode == 1 || tileMode == 2 || tileMode == 3 || tileMode == 7 || tileMode == 11 || tileMode == 13 || tileMode == 15)
- needed = 0;
- else
- needed = 1;
- return needed;
- }
- u32 isPow2(u32 dim)
- {
- if (dim & (dim - 1) == 0)
- return 1;
- else
- return 0;
- }
- void padDimensions(u32 tileMode, u32 padDims, u32 isCube, u32 cubeAsArray, u32 pitchAlign, u32 heightAlign, u32 sliceAlign, u32 *expPitch, u32 *expHeight, u32 *expNumSlices)
- {
- u32 thickness = computeSurfaceThickness(tileMode);
- if (padDims == 0)
- padDims = 3;
- if (isPow2(pitchAlign) != 0)
- *expPitch = powTwoAlign(*expPitch, pitchAlign);
- else
- {
- *expPitch = pitchAlign + *expPitch - 1;
- *expPitch /= pitchAlign;
- *expPitch *= pitchAlign;
- }
- if (padDims > 1)
- *expHeight = powTwoAlign(*expHeight, heightAlign);
- if (padDims > 2 || thickness > 1)
- {
- if (isCube != 0 && ((m_configFlags >> 3) & 1 == 0 || cubeAsArray != 0))
- *expNumSlices = nextPow2(*expNumSlices);
- if (thickness > 1)
- *expNumSlices = powTwoAlign(*expNumSlices, sliceAlign);
- }
- }
- u32 adjustPitchAlignment(Flags flags, u32 pitchAlign)
- {
- if ((flags.value >> 13) & 1 != 0)
- pitchAlign = powTwoAlign(pitchAlign, 0x20);
- return pitchAlign;
- }
- void computeSurfaceAlignmentsLinear(u32 tileMode, u32 bpp, Flags flags, u32 *baseAlign, u32 *pitchAlign, u32 *heightAlign)
- {
- u32 pixelsPerPipeInterleave;
- if (tileMode != 0)
- {
- if (tileMode == 1)
- {
- pixelsPerPipeInterleave = 8 * m_pipeInterleaveBytes / bpp;
- *baseAlign = m_pipeInterleaveBytes;
- *pitchAlign = max(0x40, pixelsPerPipeInterleave);
- *heightAlign = 1;
- }
- else
- {
- *baseAlign = 1;
- *pitchAlign = 1;
- *heightAlign = 1;
- }
- }
- else
- {
- *baseAlign = 1;
- *pitchAlign = bpp != 1 ? 1: 8;
- *heightAlign = 1;
- }
- *pitchAlign = adjustPitchAlignment(flags, *pitchAlign);
- }
- u32 computeSurfaceInfoLinear(u32 tileMode, u32 bpp, u32 numSamples, u32 pitch, u32 height, u32 numSlices, u32 mipLevel, u32 padDims, Flags flags, u32 *pPitchOut, u32 *pHeightOut, u32 *pNumSlicesOut, u32 *pSurfSize, u32 *pBaseAlign, u32 *pPitchAlign, u32 *pHeightAlign, u32 *pDepthAlign)
- {
- u32 valid = 1;
- u32 expPitch = pitch;
- u32 expHeight = height;
- u32 expNumSlices = numSlices;
- u32 microTileThickness = computeSurfaceThickness(tileMode);
- u32 baseAlign, pitchAlign, heightAlign;
- u32 tileSlices, slices;
- computeSurfaceAlignmentsLinear(tileMode, bpp, flags, &baseAlign, &pitchAlign, &heightAlign);
- if ((flags.value >> 9) & 1 != 0 && mipLevel == 0)
- {
- expPitch /= 3;
- expPitch = nextPow2(expPitch);
- }
- if (mipLevel != 0)
- {
- expPitch = nextPow2(expPitch);
- expHeight = nextPow2(expHeight);
- if ((flags.value >> 4) & 1 != 0)
- {
- expNumSlices = numSlices;
- if (numSlices <= 1)
- padDims = 2;
- else
- padDims = 0;
- }
- else
- expNumSlices = nextPow2(numSlices);
- }
- padDimensions(
- tileMode,
- padDims,
- (flags.value >> 4) & 1,
- (flags.value >> 7) & 1,
- pitchAlign,
- heightAlign,
- microTileThickness,
- &expPitch,
- &expHeight,
- &expNumSlices);
- if ((flags.value >> 9) & 1 != 0 && mipLevel == 0)
- expPitch *= 3;
- tileSlices = numSamples;
- slices = expNumSlices * numSamples / microTileThickness;
- *pPitchOut = expPitch;
- *pHeightOut = expHeight;
- *pNumSlicesOut = expNumSlices;
- *pSurfSize = (expHeight * expPitch * slices * bpp * numSamples + 7) / 8;
- *pBaseAlign = baseAlign;
- *pPitchAlign = pitchAlign;
- *pHeightAlign = heightAlign;
- *pDepthAlign = microTileThickness;
- return valid;
- }
- void computeSurfaceAlignmentsMicroTiled(u32 tileMode, u32 bpp, Flags flags, u32 numSamples, u32 *baseAlign, u32 *pitchAlign, u32 *heightAlign)
- {
- if (bpp == 24 || bpp == 48 || bpp == 96)
- bpp /= 3;
- u32 v8 = computeSurfaceThickness(tileMode);
- *baseAlign = m_pipeInterleaveBytes;
- *pitchAlign = max(8, m_pipeInterleaveBytes / bpp / numSamples / v8);
- *heightAlign = 8;
- *pitchAlign = adjustPitchAlignment(flags, *pitchAlign);
- }
- u32 computeSurfaceInfoMicroTiled(u32 tileMode, u32 bpp, u32 numSamples, u32 pitch, u32 height, u32 numSlices, u32 mipLevel, u32 padDims, Flags flags, u32 *pPitchOut, u32 *pHeightOut, u32 *pNumSlicesOut, u32 *pSurfSize, u32 *pTileModeOut, u32 *pBaseAlign, u32 *pPitchAlign, u32 *pHeightAlign, u32 *pDepthAlign)
- {
- u32 valid = 1;
- u32 expTileMode = tileMode;
- u32 expPitch = pitch;
- u32 expHeight = height;
- u32 expNumSlices = numSlices;
- u32 microTileThickness = computeSurfaceThickness(tileMode);
- u32 baseAlign, pitchAlign, heightAlign;
- if (mipLevel != 0)
- {
- expPitch = nextPow2(pitch);
- expHeight = nextPow2(height);
- if ((flags.value >> 4) & 1 != 0)
- {
- expNumSlices = numSlices;
- if (numSlices <= 1)
- padDims = 2;
- else
- padDims = 0;
- }
- else
- expNumSlices = nextPow2(numSlices);
- if (expTileMode == 3 && expNumSlices < 4)
- {
- expTileMode = 2;
- microTileThickness = 1;
- }
- }
- computeSurfaceAlignmentsMicroTiled(
- expTileMode,
- bpp,
- flags,
- numSamples,
- &baseAlign,
- &pitchAlign,
- &heightAlign);
- padDimensions(
- expTileMode,
- padDims,
- (flags.value >> 4) & 1,
- (flags.value >> 7) & 1,
- pitchAlign,
- heightAlign,
- microTileThickness,
- &expPitch,
- &expHeight,
- &expNumSlices);
- *pPitchOut = expPitch;
- *pHeightOut = expHeight;
- *pNumSlicesOut = expNumSlices;
- *pSurfSize = (expHeight * expPitch * expNumSlices * bpp * numSamples + 7) / 8;
- *pTileModeOut = expTileMode;
- *pBaseAlign = baseAlign;
- *pPitchAlign = pitchAlign;
- *pHeightAlign = heightAlign;
- *pDepthAlign = microTileThickness;
- return valid;
- }
- u32 isDualBaseAlignNeeded(u32 tileMode)
- {
- u32 needed = 1;
- if (m_chipFamily == 1)
- if (0 <= tileMode <= 3)
- needed = 0;
- else
- needed = 0;
- return needed;
- }
- void computeSurfaceAlignmentsMacroTiled(u32 tileMode, u32 bpp, Flags flags, u32 numSamples, u32 *baseAlign, u32 *pitchAlign, u32 *heightAlign, u32 *macroTileWidth, u32 *macroTileHeight)
- {
- u32 groupBytes = m_pipeInterleaveBytes;
- u32 numBanks = m_banks;
- u32 numPipes = m_pipes;
- u32 splitBytes = m_splitSize;
- u32 aspectRatio = computeMacroTileAspectRatio(tileMode);
- u32 thickness = computeSurfaceThickness(tileMode);
- if (bpp == 24 || bpp == 48 || bpp == 96)
- bpp /= 3;
- if (bpp == 3)
- bpp = 1;
- *macroTileWidth = 8 * numBanks / aspectRatio;
- *macroTileHeight = aspectRatio * 8 * numPipes;
- *pitchAlign = max(*macroTileWidth, *macroTileWidth * (groupBytes / bpp / (8 * thickness) / numSamples));
- *pitchAlign = adjustPitchAlignment(flags, *pitchAlign);
- *heightAlign = *macroTileHeight;
- u32 macroTileBytes = numSamples * ((bpp * *macroTileHeight * *macroTileWidth + 7) >> 3);
- if (m_chipFamily == 1 && numSamples == 1)
- macroTileBytes *= 2;
- if (thickness == 1)
- *baseAlign = max(macroTileBytes, (numSamples * *heightAlign * bpp * *pitchAlign + 7) >> 3);
- else
- *baseAlign = max(groupBytes, (4 * *heightAlign * bpp * *pitchAlign + 7) >> 3);
- u32 microTileBytes = (thickness * numSamples * (bpp << 6) + 7) >> 3;
- u32 v11;
- if (microTileBytes < splitBytes)
- v11 = 1;
- else
- v11 = microTileBytes / splitBytes;
- u32 numSlicesPerMicroTile = v11;
- *baseAlign /= v11;
- u32 macroBytes;
- if (isDualBaseAlignNeeded(tileMode) != 0)
- {
- macroBytes = (bpp * *macroTileHeight * *macroTileWidth + 7) >> 3;
- if (*baseAlign / macroBytes % 2 != 0)
- *baseAlign += macroBytes;
- }
- }
- u32 computeSurfaceInfoMacroTiled(u32 tileMode, u32 baseTileMode, u32 bpp, u32 numSamples, u32 pitch, u32 height, u32 numSlices, u32 mipLevel, u32 padDims, Flags flags, u32 *pPitchOut, u32 *pHeightOut, u32 *pNumSlicesOut, u32 *pSurfSize, u32 *pTileModeOut, u32 *pBaseAlign, u32 *pPitchAlign, u32 *pHeightAlign, u32 *pDepthAlign)
- {
- u32 valid = 1;
- u32 expPitch = pitch;
- u32 expHeight = height;
- u32 expNumSlices = numSlices;
- u32 expTileMode = tileMode;
- u32 microTileThickness = computeSurfaceThickness(tileMode);
- u32 bankSwappedWidth, v21, tilePerGroup;
- u32 evenHeight, evenWidth, pitchAlignFactor;
- u32 baseAlign, pitchAlign, heightAlign;
- u32 macroWidth, macroHeight;
- u32 result;
- if (mipLevel != 0)
- {
- expPitch = nextPow2(pitch);
- expHeight = nextPow2(height);
- if ((flags.value >> 4) & 1 != 0)
- {
- expNumSlices = numSlices;
- padDims = numSlices <= 1 ? 2: 0;
- }
- else
- expNumSlices = nextPow2(numSlices);
- if (expTileMode == 7 && expNumSlices < 4)
- {
- expTileMode = 4;
- microTileThickness = 1;
- }
- }
- if (tileMode == baseTileMode
- || mipLevel == 0
- || isThickMacroTiled(baseTileMode) == 0
- || isThickMacroTiled(tileMode) != 0)
- {
- computeSurfaceAlignmentsMacroTiled(
- tileMode,
- bpp,
- flags,
- numSamples,
- &baseAlign,
- &pitchAlign,
- &heightAlign,
- ¯oWidth,
- ¯oHeight);
- bankSwappedWidth = computeSurfaceBankSwappedWidth(tileMode, bpp, pitch, numSamples);
- if (bankSwappedWidth > pitchAlign)
- pitchAlign = bankSwappedWidth;
- if (isDualPitchAlignNeeded(tileMode, (flags.value >> 1) & 1, mipLevel) != 0)
- {
- v21 = (m_pipeInterleaveBytes >> 3) / bpp / numSamples;
- tilePerGroup = v21 / computeSurfaceThickness(tileMode);
- if (tilePerGroup == 0)
- tilePerGroup = 1;
- evenHeight = (expHeight - 1) / macroHeight & 1;
- evenWidth = (expPitch - 1) / macroWidth & 1;
- if (numSamples == 1
- && tilePerGroup == 1
- && evenWidth == 0
- && (expPitch > macroWidth || evenHeight == 0 && expHeight > macroHeight))
- expPitch += macroWidth;
- padDimensions(
- tileMode,
- padDims,
- (flags.value >> 4) & 1,
- (flags.value >> 7) & 1,
- pitchAlign,
- heightAlign,
- microTileThickness,
- &expPitch,
- &expHeight,
- &expNumSlices);
- *pPitchOut = expPitch;
- *pHeightOut = expHeight;
- *pNumSlicesOut = expNumSlices;
- *pSurfSize = (expHeight * expPitch * expNumSlices * bpp * numSamples + 7) / 8;
- *pTileModeOut = expTileMode;
- *pBaseAlign = baseAlign;
- *pPitchAlign = pitchAlign;
- *pHeightAlign = heightAlign;
- *pDepthAlign = microTileThickness;
- result = valid;
- }
- }
- else
- {
- computeSurfaceAlignmentsMacroTiled(
- baseTileMode,
- bpp,
- flags,
- numSamples,
- &baseAlign,
- &pitchAlign,
- &heightAlign,
- ¯oWidth,
- ¯oHeight);
- pitchAlignFactor = (m_pipeInterleaveBytes >> 3) / bpp;
- if (pitchAlignFactor == 0)
- pitchAlignFactor = 1;
- if (expPitch < pitchAlign * pitchAlignFactor || expHeight < heightAlign)
- {
- expTileMode = 2;
- result = computeSurfaceInfoMicroTiled(
- 2,
- bpp,
- numSamples,
- pitch,
- height,
- numSlices,
- mipLevel,
- padDims,
- flags,
- pPitchOut,
- pHeightOut,
- pNumSlicesOut,
- pSurfSize,
- pTileModeOut,
- pBaseAlign,
- pPitchAlign,
- pHeightAlign,
- pDepthAlign);
- }
- else
- {
- computeSurfaceAlignmentsMacroTiled(
- tileMode,
- bpp,
- flags,
- numSamples,
- &baseAlign,
- &pitchAlign,
- &heightAlign,
- ¯oWidth,
- ¯oHeight);
- bankSwappedWidth = computeSurfaceBankSwappedWidth(tileMode, bpp, pitch, numSamples);
- if (bankSwappedWidth > pitchAlign)
- pitchAlign = bankSwappedWidth;
- if (isDualPitchAlignNeeded(tileMode, (flags.value >> 1) & 1, mipLevel) != 0)
- {
- v21 = (m_pipeInterleaveBytes >> 3) / bpp / numSamples;
- tilePerGroup = v21 / computeSurfaceThickness(tileMode);
- if (tilePerGroup == 0)
- tilePerGroup = 1;
- evenHeight = (expHeight - 1) / macroHeight & 1;
- evenWidth = (expPitch - 1) / macroWidth & 1;
- if (numSamples == 1
- && tilePerGroup == 1
- && evenWidth == 0
- && (expPitch > macroWidth || evenHeight == 0 && expHeight > macroHeight))
- expPitch += macroWidth;
- padDimensions(
- tileMode,
- padDims,
- (flags.value >> 4) & 1,
- (flags.value >> 7) & 1,
- pitchAlign,
- heightAlign,
- microTileThickness,
- &expPitch,
- &expHeight,
- &expNumSlices);
- *pPitchOut = expPitch;
- *pHeightOut = expHeight;
- *pNumSlicesOut = expNumSlices;
- *pSurfSize = (expHeight * expPitch * expNumSlices * bpp * numSamples + 7) / 8;
- *pTileModeOut = expTileMode;
- *pBaseAlign = baseAlign;
- *pPitchAlign = pitchAlign;
- *pHeightAlign = heightAlign;
- *pDepthAlign = microTileThickness;
- result = valid;
- }
- }
- return result;
- }
- u32 ComputeSurfaceInfoEx()
- {
- u32 tileMode = pIn.tileMode;
- u32 bpp = pIn.bpp;
- u32 numSamples = max(1, pIn.numSamples);
- u32 pitch = pIn.width;
- u32 height = pIn.height;
- u32 numSlices = pIn.numSlices;
- u32 mipLevel = pIn.mipLevel;
- Flags flags = pIn.flags;
- u32 pPitchOut = pOut.pitch;
- u32 pHeightOut = pOut.height;
- u32 pNumSlicesOut = pOut.depth;
- u32 pTileModeOut = pOut.tileMode;
- u32 pSurfSize = pOut.surfSize;
- u32 pBaseAlign = pOut.baseAlign;
- u32 pPitchAlign = pOut.pitchAlign;
- u32 pHeightAlign = pOut.heightAlign;
- u32 pDepthAlign = pOut.depthAlign;
- u32 padDims = 0;
- u32 valid = 0;
- u32 baseTileMode = tileMode;
- u32 result;
- if ((flags.value >> 4) & 1 != 0 && mipLevel == 0)
- padDims = 2;
- if ((flags.value >> 6) & 1 != 0)
- tileMode = convertToNonBankSwappedMode(tileMode);
- else
- tileMode = computeSurfaceMipLevelTileMode(
- tileMode,
- bpp,
- mipLevel,
- pitch,
- height,
- numSlices,
- numSamples,
- (flags.value >> 1) & 1,
- 0);
- switch (tileMode)
- {
- case 0:
- case 1:
- valid = computeSurfaceInfoLinear(
- tileMode,
- bpp,
- numSamples,
- pitch,
- height,
- numSlices,
- mipLevel,
- padDims,
- flags,
- &pPitchOut,
- &pHeightOut,
- &pNumSlicesOut,
- &pSurfSize,
- &pBaseAlign,
- &pPitchAlign,
- &pHeightAlign,
- &pDepthAlign);
- pTileModeOut = tileMode;
- break;
- case 2:
- case 3:
- valid = computeSurfaceInfoMicroTiled(
- tileMode,
- bpp,
- numSamples,
- pitch,
- height,
- numSlices,
- mipLevel,
- padDims,
- flags,
- &pPitchOut,
- &pHeightOut,
- &pNumSlicesOut,
- &pSurfSize,
- &pTileModeOut,
- &pBaseAlign,
- &pPitchAlign,
- &pHeightAlign,
- &pDepthAlign);
- break;
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- valid = computeSurfaceInfoMacroTiled(
- tileMode,
- baseTileMode,
- bpp,
- numSamples,
- pitch,
- height,
- numSlices,
- mipLevel,
- padDims,
- flags,
- &pPitchOut,
- &pHeightOut,
- &pNumSlicesOut,
- &pSurfSize,
- &pTileModeOut,
- &pBaseAlign,
- &pPitchAlign,
- &pHeightAlign,
- &pDepthAlign);
- break;
- }
- result = 0;
- if (valid == 0)
- result = 3;
- pOut.pitch = pPitchOut;
- pOut.height = pHeightOut;
- pOut.depth = pNumSlicesOut;
- pOut.tileMode = pTileModeOut;
- pOut.surfSize = pSurfSize;
- pOut.baseAlign = pBaseAlign;
- pOut.pitchAlign = pPitchAlign;
- pOut.heightAlign = pHeightAlign;
- pOut.depthAlign = pDepthAlign;
- return result;
- }
- u32 restoreSurfaceInfo(u32 elemMode, u32 expandX, u32 expandY, u32 bpp)
- {
- u32 originalBits, width, height;
- if (bpp != 0)
- {
- switch (elemMode)
- {
- case 4:
- originalBits = expandY * expandX * bpp;
- break;
- case 5:
- case 6:
- originalBits = bpp / expandX / expandY;
- break;
- case 7:
- case 8:
- originalBits = bpp;
- break;
- case 9:
- case 12:
- originalBits = 64;
- break;
- case 10:
- case 11:
- case 13:
- originalBits = 128;
- break;
- case 0:
- case 1:
- case 2:
- case 3:
- originalBits = bpp;
- break;
- default:
- originalBits = bpp;
- break;
- }
- bpp = originalBits;
- }
- if (pOut.pixelPitch != 0 && pOut.pixelHeight != 0)
- {
- width = pOut.pixelPitch;
- height = pOut.pixelHeight;
- if (expandX > 1 || expandY > 1)
- {
- if (elemMode == 4)
- {
- width /= expandX;
- height /= expandY;
- }
- else
- {
- width *= expandX;
- height *= expandY;
- }
- }
- pOut.pixelPitch = max(1, width);
- pOut.pixelHeight = max(1, height);
- }
- return bpp;
- }
- void computeSurfaceInfo(surfaceIn aSurfIn, surfaceOut pSurfOut)
- {
- pIn = aSurfIn;
- pOut = pSurfOut;
- u32 v4 = 0;
- u32 v6 = 0;
- u32 v7 = 0;
- u32 v8 = 0;
- u32 v10 = 0;
- u32 v11 = 0;
- u32 v12 = 0;
- u32 v14 = 0;
- u32 v18 = 0;
- tileInfo tileInfoNull;
- u32 sliceFlags = 0;
- u32 returnCode;
- u32 width, height, bpp, elemMode;
- u32 expandY, expandX, sliceTileMax;
- returnCode = 0;
- if (getFillSizeFieldsFlags() == 1 && (pIn.size != 60 || pOut.size != 96)) // --> m_configFlags.value = 4
- returnCode = 6;
- // v3 = pIn
- if (pIn.bpp > 0x80)
- returnCode = 3;
- if (returnCode == ADDR_OK)
- v18 = 0;
- computeMipLevel();
- width = pIn.width;
- height = pIn.height;
- bpp = pIn.bpp;
- expandX = 1;
- expandY = 1;
- sliceFlags = getSliceComputingFlags();
- if (useTileIndex(pIn.tileIndex) && !pIn.pTileInfo)
- {
- if (pOut.pTileInfo)
- pIn.pTileInfo = pOut.pTileInfo;
- else
- {
- pOut.pTileInfo = &tileInfoNull;
- pIn.pTileInfo = &tileInfoNull;
- }
- }
- returnCode = 0; // does nothing
- if (returnCode == ADDR_OK)
- {
- pOut.pixelBits = pIn.bpp;
- // v3 = pIn
- if (pIn.format != 0)
- {
- v18 = 1;
- v4 = pIn.format;
- bpp = getBitsPerPixel(v4, &expandX, &expandY, &elemMode);
- if (elemMode == 4 && expandX == 3 && pIn.tileMode == 1)
- pIn.flags.value |= 0x200;
- v6 = expandY;
- v7 = expandX;
- v8 = elemMode;
- bpp = adjustSurfaceInfo(v8, v7, v6, bpp, width, height);
- }
- else if (pIn.bpp != 0)
- {
- pIn.width = max(1, pIn.width);
- pIn.height = max(1, pIn.height);
- }
- else
- returnCode = 3;
- }
- if (returnCode == ADDR_OK)
- returnCode = ComputeSurfaceInfoEx();
- if (returnCode == ADDR_OK)
- {
- pOut.bpp = pIn.bpp;
- pOut.pixelPitch = pOut.pitch;
- pOut.pixelHeight = pOut.height;
- if (pIn.format && (!((pIn.flags.value >> 9) & 1) || !pIn.mipLevel))
- {
- if (!v18)
- return;
- v10 = expandY;
- v11 = expandX;
- v12 = elemMode;
- bpp = restoreSurfaceInfo(v12, v11, v10, bpp);
- }
- if (sliceFlags)
- if (sliceFlags == 1)
- pOut.sliceSize = (pOut.height * pOut.pitch * pOut.bpp * pIn.numSamples + 7) / 8;
- else if ((pIn.flags.value >> 5) & 1)
- pOut.sliceSize = pOut.surfSize;
- else
- {
- v14 = pOut.surfSize >> 32;
- pOut.sliceSize = pOut.surfSize / pOut.depth;
- if (pIn.slice == (pIn.numSlices - 1) && pIn.numSlices > 1)
- pOut.sliceSize += pOut.sliceSize * (pOut.depth - pIn.numSlices);
- }
- pOut.pitchTileMax = (pOut.pitch >> 3) - 1;
- pOut.heightTileMax = (pOut.height >> 3) - 1;
- sliceTileMax = (pOut.height * pOut.pitch >> 6) - 1;
- pOut.sliceTileMax = sliceTileMax;
- }
- }
- surfaceOut getSurfaceInfo(u32 surfaceFormat, u32 surfaceWidth, u32 surfaceHeight, u32 surfaceDepth, u32 surfaceDim, u32 surfaceTileMode, u32 surfaceAA, u32 level)
- {
- u32 dim = 0;
- u32 width = 0;
- u32 blockSize = 0;
- u32 numSamples = 0;
- u32 hwFormat = 0;
- surfaceIn aSurfIn;
- surfaceOut pSurfOut;
- hwFormat = surfaceFormat & 0x3F;
- if (surfaceTileMode == 16)
- {
- numSamples = 1 << surfaceAA;
- if (hwFormat < 0x31 || hwFormat > 0x35)
- blockSize = 1;
- else
- blockSize = 4;
- width = ~(blockSize - 1) & ((surfaceWidth >> level) + blockSize - 1);
- if (hwFormat == 0x35)
- return pSurfOut;
- pSurfOut.bpp = formatHwInfo[hwFormat * 4];
- pSurfOut.size = 96;
- pSurfOut.pitch = width / blockSize;
- pSurfOut.pixelBits = formatHwInfo[hwFormat * 4];
- pSurfOut.baseAlign = 1;
- pSurfOut.pitchAlign = 1;
- pSurfOut.heightAlign = 1;
- pSurfOut.depthAlign = 1;
- dim = surfaceDim;
- switch (dim)
- {
- case 0:
- pSurfOut.height = 1;
- pSurfOut.depth = 1;
- break;
- case 1:
- pSurfOut.height = max(1, surfaceHeight >> level);
- pSurfOut.depth = 1;
- break;
- case 2:
- pSurfOut.height = max(1, surfaceHeight >> level);
- pSurfOut.depth = max(1, surfaceDepth >> level);
- break;
- case 3:
- pSurfOut.height = max(1, surfaceHeight >> level);
- pSurfOut.depth = max(6, surfaceDepth);
- case 4:
- pSurfOut.height = 1;
- pSurfOut.depth = surfaceDepth;
- break;
- case 5:
- pSurfOut.height = max(1, surfaceHeight >> level);
- pSurfOut.depth = surfaceDepth;
- break;
- }
- pSurfOut.height = (~(blockSize - 1) & (pSurfOut.height + blockSize - 1)) / blockSize;
- pSurfOut.pixelPitch = ~(blockSize - 1) & ((surfaceWidth >> level) + blockSize - 1);
- pSurfOut.pixelPitch = max(blockSize, pSurfOut.pixelPitch);
- pSurfOut.pixelHeight = ~(blockSize - 1) & ((surfaceHeight >> level) + blockSize - 1);
- pSurfOut.pixelHeight = max(blockSize, pSurfOut.pixelHeight);
- pSurfOut.pitch = max(1, pSurfOut.pitch);
- pSurfOut.height = max(1, pSurfOut.height);
- pSurfOut.surfSize = pSurfOut.bpp * numSamples * pSurfOut.depth * pSurfOut.height * pSurfOut.pitch >> 3;
- if (surfaceDim == 2)
- pSurfOut.sliceSize = pSurfOut.surfSize;
- else
- pSurfOut.sliceSize = pSurfOut.surfSize / pSurfOut.depth;
- pSurfOut.pitchTileMax = (pSurfOut.pitch >> 3) - 1;
- pSurfOut.heightTileMax = (pSurfOut.height >> 3) - 1;
- pSurfOut.sliceTileMax = (pSurfOut.height * pSurfOut.pitch >> 6) - 1;
- }
- else
- {
- aSurfIn.size = 60;
- aSurfIn.tileMode = surfaceTileMode & 0xF;
- aSurfIn.format = hwFormat;
- aSurfIn.bpp = formatHwInfo[hwFormat * 4];
- aSurfIn.numSamples = 1 << surfaceAA;
- aSurfIn.numFrags = aSurfIn.numSamples;
- aSurfIn.width = max(1, surfaceWidth >> level);
- dim = surfaceDim;
- switch (dim)
- {
- case 0:
- aSurfIn.height = 1;
- aSurfIn.numSlices = 1;
- break;
- case 1:
- aSurfIn.height = max(1, surfaceHeight >> level);
- aSurfIn.numSlices = 1;
- break;
- case 2:
- aSurfIn.height = max(1, surfaceHeight >> level);
- aSurfIn.numSlices = max(1, surfaceDepth >> level);
- break;
- case 3:
- aSurfIn.height = max(1, surfaceHeight >> level);
- aSurfIn.numSlices = max(6, surfaceDepth);
- aSurfIn.flags.value |= 0x10;
- break;
- case 4:
- aSurfIn.height = 1;
- aSurfIn.numSlices = surfaceDepth;
- break;
- case 5:
- aSurfIn.height = max(1, surfaceHeight >> level);
- aSurfIn.numSlices = surfaceDepth;
- break;
- case 6:
- aSurfIn.height = max(1, surfaceHeight >> level);
- aSurfIn.numSlices = 1;
- break;
- case 7:
- aSurfIn.height = max(1, surfaceHeight >> level);
- aSurfIn.numSlices = surfaceDepth;
- break;
- }
- aSurfIn.slice = 0;
- aSurfIn.mipLevel = level;
- if (surfaceDim == 2)
- aSurfIn.flags.value |= 0x20;
- if (level == 0)
- aSurfIn.flags.value = (1 << 12) | aSurfIn.flags.value & 0xFFFFEFFF;
- else
- aSurfIn.flags.value = aSurfIn.flags.value & 0xFFFFEFFF;
- pSurfOut.size = 96;
- computeSurfaceInfo(aSurfIn, pSurfOut);
- pSurfOut = pOut;
- }
- return pSurfOut;
- }
Advertisement
Add Comment
Please, Sign In to add comment