AboodXD

Wii U swizzling code (C)

Jan 10th, 2018
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 56.67 KB | None | 0 0
  1. // Copyright © 2016-2017 MasterVermilli0n/AboodXD
  2.  
  3. // Credits:
  4. //  -Exzap: original code
  5. //  -MasterVermilli0n/AboodXD: porting, code improvements and cleaning up
  6.  
  7. typedef unsigned char u8;
  8. typedef unsigned int u32;
  9. typedef long long s64;
  10. typedef unsigned long long u64;
  11.  
  12. #define max(a,b) \
  13.    ({ __typeof__ (a) _a = (a); \
  14.        __typeof__ (b) _b = (b); \
  15.      _a > _b ? _a : _b; })
  16. #define min(a,b) \
  17.    ({ __typeof__ (a) _a = (a); \
  18.        __typeof__ (b) _b = (b); \
  19.      _a < _b ? _a : _b; })
  20.  
  21.  
  22. static u32 m_banks = 4;
  23. static u32 m_banksBitcount = 2;
  24. static u32 m_pipes = 2;
  25. static u32 m_pipesBitcount = 1;
  26. static u32 m_pipeInterleaveBytes = 256;
  27. static u32 m_pipeInterleaveBytesBitcount = 8;
  28. static u32 m_rowSize = 2048;
  29. static u32 m_swapSize = 256;
  30. static u32 m_splitSize = 2048;
  31.  
  32. static u32 m_chipFamily = 2;
  33.  
  34. static u32 MicroTilePixels = 64;
  35.  
  36. u8 formatHwInfo[0x40*4] =
  37. {
  38.     0x00,0x00,0x00,0x01,0x08,0x03,0x00,0x01,0x08,0x01,0x00,0x01,0x00,0x00,0x00,0x01,
  39.     0x00,0x00,0x00,0x01,0x10,0x07,0x00,0x00,0x10,0x03,0x00,0x01,0x10,0x03,0x00,0x01,
  40.     0x10,0x0B,0x00,0x01,0x10,0x01,0x00,0x01,0x10,0x03,0x00,0x01,0x10,0x03,0x00,0x01,
  41.     0x10,0x03,0x00,0x01,0x20,0x03,0x00,0x00,0x20,0x07,0x00,0x00,0x20,0x03,0x00,0x00,
  42.     0x20,0x03,0x00,0x01,0x20,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x03,0x00,0x00,
  43.     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x03,0x00,0x01,0x00,0x00,0x00,0x01,
  44.     0x00,0x00,0x00,0x01,0x20,0x0B,0x00,0x01,0x20,0x0B,0x00,0x01,0x20,0x0B,0x00,0x01,
  45.     0x40,0x05,0x00,0x00,0x40,0x03,0x00,0x00,0x40,0x03,0x00,0x00,0x40,0x03,0x00,0x00,
  46.     0x40,0x03,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x80,0x03,0x00,0x00,
  47.     0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x10,0x01,0x00,0x00,
  48.     0x10,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,0x20,0x01,0x00,0x00,
  49.     0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x60,0x01,0x00,0x00,
  50.     0x60,0x01,0x00,0x00,0x40,0x01,0x00,0x01,0x80,0x01,0x00,0x01,0x80,0x01,0x00,0x01,
  51.     0x40,0x01,0x00,0x01,0x80,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  52.     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  53.     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
  54. };
  55.  
  56.  
  57. u32 surfaceGetBitsPerPixel(u32 surfaceFormat)
  58. {
  59.     u32 hwFormat = surfaceFormat & 0x3F;
  60.     u32 bpp = formatHwInfo[hwFormat * 4];
  61.  
  62.     return bpp;
  63. }
  64.  
  65.  
  66. u32 computeSurfaceThickness(u32 tileMode)
  67. {
  68.     u32 thickness;
  69.  
  70.     switch (tileMode)
  71.     {
  72.         case 3:
  73.         case 7:
  74.         case 11:
  75.         case 13:
  76.         case 15:
  77.             thickness = 4;
  78.             break;
  79.  
  80.         case 16:
  81.         case 17:
  82.             thickness = 8;
  83.             break;
  84.  
  85.         default:
  86.             thickness = 1;
  87.             break;
  88.     }
  89.  
  90.     return thickness;
  91. }
  92.  
  93.  
  94. u32 computePixelIndexWithinMicroTile(u32 x, u32 y, u32 bpp, u32 tileMode)
  95. {
  96.     u32 z = 0;
  97.  
  98.     u32 thickness, pixelBit8, pixelBit7, pixelBit6, pixelBit5;
  99.     u32 pixelBit4, pixelBit3, pixelBit2, pixelBit1, pixelBit0;
  100.  
  101.     pixelBit6 = 0;
  102.     pixelBit7 = 0;
  103.     pixelBit8 = 0;
  104.     thickness = computeSurfaceThickness(tileMode);
  105.  
  106.     switch (bpp)
  107.     {
  108.         case 0x08:
  109.             pixelBit0 = x & 1;
  110.             pixelBit1 = (x & 2) >> 1;
  111.             pixelBit2 = (x & 4) >> 2;
  112.             pixelBit3 = (y & 2) >> 1;
  113.             pixelBit4 = y & 1;
  114.             pixelBit5 = (y & 4) >> 2;
  115.             break;
  116.  
  117.         case 0x10:
  118.             pixelBit0 = x & 1;
  119.             pixelBit1 = (x & 2) >> 1;
  120.             pixelBit2 = (x & 4) >> 2;
  121.             pixelBit3 = y & 1;
  122.             pixelBit4 = (y & 2) >> 1;
  123.             pixelBit5 = (y & 4) >> 2;
  124.             break;
  125.  
  126.         case 0x20:
  127.         case 0x60:
  128.             pixelBit0 = x & 1;
  129.             pixelBit1 = (x & 2) >> 1;
  130.             pixelBit2 = y & 1;
  131.             pixelBit3 = (x & 4) >> 2;
  132.             pixelBit4 = (y & 2) >> 1;
  133.             pixelBit5 = (y & 4) >> 2;
  134.             break;
  135.  
  136.         case 0x40:
  137.             pixelBit0 = x & 1;
  138.             pixelBit1 = y & 1;
  139.             pixelBit2 = (x & 2) >> 1;
  140.             pixelBit3 = (x & 4) >> 2;
  141.             pixelBit4 = (y & 2) >> 1;
  142.             pixelBit5 = (y & 4) >> 2;
  143.             break;
  144.  
  145.         case 0x80:
  146.             pixelBit0 = y & 1;
  147.             pixelBit1 = x & 1;
  148.             pixelBit2 = (x & 2) >> 1;
  149.             pixelBit3 = (x & 4) >> 2;
  150.             pixelBit4 = (y & 2) >> 1;
  151.             pixelBit5 = (y & 4) >> 2;
  152.             break;
  153.  
  154.         default:
  155.             pixelBit0 = x & 1;
  156.             pixelBit1 = (x & 2) >> 1;
  157.             pixelBit2 = y & 1;
  158.             pixelBit3 = (x & 4) >> 2;
  159.             pixelBit4 = (y & 2) >> 1;
  160.             pixelBit5 = (y & 4) >> 2;
  161.             break;
  162.     }
  163.  
  164.     if (thickness > 1)
  165.     {
  166.         pixelBit6 = z & 1;
  167.         pixelBit7 = (z & 2) >> 1;
  168.     }
  169.  
  170.     if (thickness == 8)
  171.         pixelBit8 = (z & 4) >> 2;
  172.  
  173.     return ((pixelBit8 << 8) | (pixelBit7 << 7) | (pixelBit6 << 6) |
  174.             32 * pixelBit5 | 16 * pixelBit4 | 8 * pixelBit3 |
  175.             4 * pixelBit2 | pixelBit0 | 2 * pixelBit1);
  176. }
  177.  
  178.  
  179. u32 computePipeFromCoordWoRotation(u32 x, u32 y)
  180. {
  181.     // hardcoded to assume 2 pipes
  182.     return ((y >> 3) ^ (x >> 3)) & 1;
  183. }
  184.  
  185.  
  186. u32 computeBankFromCoordWoRotation(u32 x, u32 y)
  187. {
  188.     u32 numPipes = m_pipes;
  189.     u32 numBanks = m_banks;
  190.  
  191.     u32 bankBit0, bankBit0a;
  192.  
  193.     u32 bank = 0;
  194.  
  195.     if (numBanks == 4)
  196.     {
  197.         bankBit0 = ((y / (16 * numPipes)) ^ (x >> 3)) & 1;
  198.         bank = bankBit0 | 2 * (((y / (8 * numPipes)) ^ (x >> 4)) & 1);
  199.     }
  200.  
  201.     else if (numBanks == 8)
  202.     {
  203.         bankBit0a = ((y / (32 * numPipes)) ^ (x >> 3)) & 1;
  204.         bank = (bankBit0a | 2 * (((y / (32 * numPipes)) ^ (y / (16 * numPipes) ^ (x >> 4))) & 1) |
  205.                 4 * (((y / (8 * numPipes)) ^ (x >> 5)) & 1));
  206.     }
  207.  
  208.     return bank;
  209. }
  210.  
  211.  
  212. u32 isThickMacroTiled(u32 tileMode)
  213. {
  214.     u32 thickMacroTiled;
  215.  
  216.     switch (tileMode)
  217.     {
  218.         case 7:
  219.         case 11:
  220.         case 13:
  221.         case 15:
  222.             thickMacroTiled = 1;
  223.             break;
  224.  
  225.         default:
  226.             thickMacroTiled = 0;
  227.             break;
  228.     }
  229.  
  230.     return thickMacroTiled;
  231. }
  232.  
  233.  
  234. u32 isBankSwappedTileMode(u32 tileMode)
  235. {
  236.     u32 bankSwapped;
  237.  
  238.     switch (tileMode)
  239.     {
  240.         case 8:
  241.         case 9:
  242.         case 10:
  243.         case 11:
  244.         case 14:
  245.         case 15:
  246.             bankSwapped = 1;
  247.             break;
  248.  
  249.         default:
  250.             bankSwapped = 0;
  251.             break;
  252.     }
  253.  
  254.     return bankSwapped;
  255. }
  256.  
  257.  
  258. u32 computeMacroTileAspectRatio(u32 tileMode)
  259. {
  260.     u32 ratio;
  261.  
  262.     switch (tileMode)
  263.     {
  264.         case 8:
  265.         case 12:
  266.         case 14:
  267.             ratio = 1;
  268.             break;
  269.  
  270.         case 5:
  271.         case 9:
  272.             ratio = 2;
  273.             break;
  274.  
  275.         case 6:
  276.         case 10:
  277.             ratio = 4;
  278.             break;
  279.  
  280.         default:
  281.             ratio = 1;
  282.             break;
  283.     }
  284.  
  285.     return ratio;
  286. }
  287.  
  288.  
  289. u32 computeSurfaceBankSwappedWidth(u32 tileMode, u32 bpp, u32 pitch, u32 numSamples)
  290. {
  291.     if (isBankSwappedTileMode(tileMode) == 0)
  292.         return 0;
  293.  
  294.     u32 numBanks = m_banks;
  295.     u32 numPipes = m_pipes;
  296.     u32 swapSize = m_swapSize;
  297.     u32 rowSize = m_rowSize;
  298.     u32 splitSize = m_splitSize;
  299.     u32 groupSize = m_pipeInterleaveBytesBitcount;
  300.     u32 bytesPerSample = 8 * bpp;
  301.  
  302.     u32 samplesPerTile, slicesPerTile;
  303.  
  304.     if (bytesPerSample != 0)
  305.     {
  306.         samplesPerTile = splitSize / bytesPerSample;
  307.         slicesPerTile = max(1, numSamples / samplesPerTile);
  308.     }
  309.  
  310.     else
  311.         slicesPerTile = 1;
  312.  
  313.     if (isThickMacroTiled(tileMode) != 0)
  314.         numSamples = 4;
  315.  
  316.     u32 bytesPerTileSlice = numSamples * bytesPerSample / slicesPerTile;
  317.  
  318.     u32 factor = computeMacroTileAspectRatio(tileMode);
  319.     u32 swapTiles = max(1, (swapSize >> 1) / bpp);
  320.  
  321.     u32 swapWidth = swapTiles * 8 * numBanks;
  322.     u32 heightBytes = numSamples * factor * numPipes * bpp / slicesPerTile;
  323.     u32 swapMax = numPipes * numBanks * rowSize / heightBytes;
  324.     u32 swapMin = groupSize * 8 * numBanks / bytesPerTileSlice;
  325.  
  326.     u32 bankSwapWidth = min(swapMax, max(swapMin, swapWidth));
  327.  
  328.     while (bankSwapWidth >= 2 * pitch)
  329.         bankSwapWidth >>= 1;
  330.  
  331.     return bankSwapWidth;
  332. }
  333.  
  334.  
  335. u64 computeSurfaceAddrFromCoordLinear(u32 x, u32 y, u32 bpp, u32 pitch)
  336. {
  337.     u64 rowOffset = y * pitch;
  338.     u64 pixOffset = x;
  339.  
  340.     u64 addr = (rowOffset + pixOffset) * bpp;
  341.     addr /= 8;
  342.  
  343.     return addr;
  344. }
  345.  
  346.  
  347. u64 computeSurfaceAddrFromCoordMicroTiled(u32 x, u32 y, u32 bpp, u32 pitch,
  348.                                           u32 tileMode)
  349. {
  350.     int microTileThickness = 1;
  351.  
  352.     if (tileMode == 3)
  353.         microTileThickness = 4;
  354.  
  355.     u32 microTileBytes = (MicroTilePixels * microTileThickness * bpp + 7) / 8;
  356.     u32 microTilesPerRow = pitch >> 3;
  357.     u32 microTileIndexX = x >> 3;
  358.     u32 microTileIndexY = y >> 3;
  359.  
  360.     u64 microTileOffset = microTileBytes * (microTileIndexX + microTileIndexY * microTilesPerRow);
  361.  
  362.     u32 pixelIndex = computePixelIndexWithinMicroTile(x, y, bpp, tileMode);
  363.  
  364.     u64 pixelOffset = bpp * pixelIndex;
  365.     pixelOffset >>= 3;
  366.  
  367.     return pixelOffset + microTileOffset;
  368. }
  369.  
  370.  
  371. u64 computeSurfaceAddrFromCoordMacroTiled(u32 x, u32 y, u32 bpp, u32 pitch, u32 height,
  372.                                                u32 tileMode, u32 pipeSwizzle,
  373.                                                u32 bankSwizzle)
  374. {
  375.     u32 sampleSlice, numSamples, samplesPerSlice;
  376.     u32 numSampleSplits, bankSwapWidth, swapIndex;
  377.     u8 bankSwapOrder[10] = {0, 1, 3, 2, 6, 7, 5, 4, 0, 0};
  378.  
  379.     u32 numPipes = m_pipes;
  380.     u32 numBanks = m_banks;
  381.     u32 numGroupBits = m_pipeInterleaveBytesBitcount;
  382.     u32 numPipeBits = m_pipesBitcount;
  383.     u32 numBankBits = m_banksBitcount;
  384.  
  385.     u32 microTileThickness = computeSurfaceThickness(tileMode);
  386.  
  387.     u32 microTileBits = bpp * (microTileThickness * MicroTilePixels);
  388.     u32 microTileBytes = (microTileBits + 7) / 8;
  389.  
  390.     u32 pixelIndex = computePixelIndexWithinMicroTile(x, y, bpp, tileMode);
  391.  
  392.     u64 pixelOffset = bpp * pixelIndex;
  393.  
  394.     u64 elemOffset = pixelOffset;
  395.  
  396.     u32 bytesPerSample = microTileBytes;
  397.  
  398.     if (microTileBytes <= m_splitSize)
  399.     {
  400.         numSamples = 1;
  401.         sampleSlice = 0;
  402.     }
  403.  
  404.     else
  405.     {
  406.         samplesPerSlice = m_splitSize / bytesPerSample;
  407.         numSampleSplits = max(1, 1 / samplesPerSlice);
  408.         numSamples = samplesPerSlice;
  409.         sampleSlice = elemOffset / (microTileBits / numSampleSplits);
  410.         elemOffset %= microTileBits / numSampleSplits;
  411.     }
  412.  
  413.     elemOffset += 7;
  414.     elemOffset /= 8;
  415.  
  416.     u32 pipe = computePipeFromCoordWoRotation(x, y);
  417.     u32 bank = computeBankFromCoordWoRotation(x, y);
  418.  
  419.     u32 bankPipe = pipe + numPipes * bank;
  420.  
  421.     u32 swizzle_ = pipeSwizzle + numPipes * bankSwizzle;
  422.  
  423.     bankPipe ^= numPipes * sampleSlice * ((numBanks >> 1) + 1) ^ swizzle_;
  424.     bankPipe %= numPipes * numBanks;
  425.     pipe = bankPipe % numPipes;
  426.     bank = bankPipe / numPipes;
  427.  
  428.     u32 sliceBytes = (height * pitch * microTileThickness * bpp * numSamples + 7) / 8;
  429.     u32 sliceOffset = sliceBytes * (sampleSlice / microTileThickness);
  430.  
  431.     u32 macroTilePitch = 8 * m_banks;
  432.     u32 macroTileHeight = 8 * m_pipes;
  433.  
  434.     switch (tileMode)
  435.     {
  436.         case 5: // GX2_TILE_MODE_2D_TILED_THIN2
  437.         case 9: // GX2_TILE_MODE_2B_TILED_THIN2
  438.             macroTilePitch >>= 1;
  439.             macroTileHeight *= 2;
  440.             break;
  441.  
  442.         case 6: // GX2_TILE_MODE_2D_TILED_THIN4
  443.         case 10:  // GX2_TILE_MODE_2B_TILED_THIN4
  444.             macroTilePitch >>= 2;
  445.             macroTileHeight *= 4;
  446.             break;
  447.     }
  448.  
  449.     u32 macroTilesPerRow = pitch / macroTilePitch;
  450.     u32 macroTileBytes = (numSamples * microTileThickness * bpp * macroTileHeight * macroTilePitch + 7) / 8;
  451.     u32 macroTileIndexX = x / macroTilePitch;
  452.     u32 macroTileIndexY = y / macroTileHeight;
  453.     u64 macroTileOffset = (macroTileIndexX + macroTilesPerRow * macroTileIndexY) * macroTileBytes;
  454.  
  455.     if (tileMode == 8 || tileMode == 9 || tileMode == 10 || tileMode == 11 || tileMode == 14 || tileMode == 15)
  456.     {
  457.         bankSwapWidth = computeSurfaceBankSwappedWidth(tileMode, bpp, pitch, 1);
  458.         swapIndex = macroTilePitch * macroTileIndexX / bankSwapWidth;
  459.         bank ^= bankSwapOrder[swapIndex & (m_banks - 1)];
  460.     }
  461.  
  462.     u32 groupMask = ((1 << numGroupBits) - 1);
  463.  
  464.     u32 numSwizzleBits = (numBankBits + numPipeBits);
  465.  
  466.     u64 totalOffset = (elemOffset + ((macroTileOffset + sliceOffset) >> numSwizzleBits));
  467.  
  468.     u64 offsetHigh = (totalOffset & ~groupMask) << numSwizzleBits;
  469.     u64 offsetLow = groupMask & totalOffset;
  470.  
  471.     u64 pipeBits = pipe << numGroupBits;
  472.     u64 bankBits = bank << (numPipeBits + numGroupBits);
  473.  
  474.     return bankBits | pipeBits | offsetLow | offsetHigh;
  475. }
  476.  
  477.  
  478. static u32 ADDR_OK = 0;
  479.  
  480. static u32 m_configFlags = 4;
  481.  
  482.  
  483. typedef struct
  484. {
  485.     u32 value;
  486. } Flags;
  487.  
  488.  
  489. typedef struct
  490. {
  491.     u32 banks;
  492.     u32 bankWidth;
  493.     u32 bankHeight;
  494.     u32 macroAspectRatio;
  495.     u32 tileSplitBytes;
  496.     u32 pipeConfig;
  497. } tileInfo;
  498.  
  499.  
  500. typedef struct
  501. {
  502.     u32 size;
  503.     u32 tileMode;
  504.     u32 format;
  505.     u32 bpp;
  506.     u32 numSamples;
  507.     u32 width;
  508.     u32 height;
  509.     u32 numSlices;
  510.     u32 slice;
  511.     u32 mipLevel;
  512.     Flags flags;
  513.     u32 numFrags;
  514.     tileInfo *pTileInfo;
  515.     int tileIndex;
  516. } surfaceIn;
  517.  
  518.  
  519. typedef struct
  520. {
  521.     u32 size;
  522.     u32 pitch;
  523.     u32 height;
  524.     u32 depth;
  525.     s64 surfSize;
  526.     u32 tileMode;
  527.     u32 baseAlign;
  528.     u32 pitchAlign;
  529.     u32 heightAlign;
  530.     u32 depthAlign;
  531.     u32 bpp;
  532.     u32 pixelPitch;
  533.     u32 pixelHeight;
  534.     u32 pixelBits;
  535.     u32 sliceSize;
  536.     u32 pitchTileMax;
  537.     u32 heightTileMax;
  538.     u32 sliceTileMax;
  539.     tileInfo *pTileInfo;
  540.     u32 tileType;
  541.     int tileIndex;
  542. } surfaceOut;
  543.  
  544.  
  545. surfaceIn pIn;
  546. surfaceOut pOut;
  547.  
  548.  
  549. u32 getFillSizeFieldsFlags()
  550. {
  551.     return (m_configFlags >> 6) & 1;
  552. }
  553.  
  554.  
  555. u32 getSliceComputingFlags()
  556. {
  557.     return (m_configFlags >> 4) & 3;
  558. }
  559.  
  560.  
  561. u32 powTwoAlign(u32 x, u32 align)
  562. {
  563.     return ~(align - 1) & (x + align - 1);
  564. }
  565.  
  566.  
  567. u32 nextPow2(u32 dim)
  568. {
  569.     u32 newDim = 1;
  570.     if (dim <= 0x7FFFFFFF)
  571.     {
  572.         while (newDim < dim)
  573.             newDim *= 2;
  574.     }
  575.  
  576.     else
  577.         newDim = 2147483648;
  578.  
  579.     return newDim;
  580. }
  581.  
  582.  
  583. u32 useTileIndex(u32 index)
  584. {
  585.     if ((m_configFlags >> 7) & 1 != 0 && index != -1)
  586.         return 1;
  587.  
  588.     else
  589.         return 0;
  590. }
  591.  
  592.  
  593. u32 getBitsPerPixel(u32 format_, u32 *expandX, u32 *expandY, u32 *elemMode)
  594. {
  595.     *expandY = 1;
  596.     u32 bitUnused = 0;
  597.     *elemMode = 3;
  598.  
  599.     u32 bpp;
  600.  
  601.     switch (format_)
  602.     {
  603.         case 1:
  604.             bpp = 8;
  605.             *expandX = 1;
  606.             break;
  607.  
  608.         case 5:
  609.         case 6:
  610.         case 7:
  611.         case 8:
  612.         case 9:
  613.         case 10:
  614.         case 11:
  615.             bpp = 16;
  616.             *expandX = 1;
  617.             break;
  618.  
  619.         case 39:
  620.             *elemMode = 7;
  621.             bpp = 16;
  622.             *expandX = 1;
  623.             break;
  624.  
  625.         case 40:
  626.             *elemMode = 8;
  627.             bpp = 16;
  628.             *expandX = 1;
  629.             break;
  630.  
  631.         case 13:
  632.         case 14:
  633.         case 15:
  634.         case 16:
  635.         case 19:
  636.         case 20:
  637.         case 21:
  638.         case 23:
  639.         case 25:
  640.         case 26:
  641.             bpp = 32;
  642.             *expandX = 1;
  643.             break;
  644.  
  645.         case 29:
  646.         case 30:
  647.         case 31:
  648.         case 32:
  649.         case 62:
  650.             bpp = 64;
  651.             *expandX = 1;
  652.             break;
  653.  
  654.         case 34:
  655.         case 35:
  656.             bpp = 128;
  657.             *expandX = 1;
  658.             break;
  659.  
  660.         case 0:
  661.             bpp = 0;
  662.             *expandX = 1;
  663.             break;
  664.  
  665.         case 38:
  666.             *elemMode = 6;
  667.             bpp = 1;
  668.             *expandX = 8;
  669.             break;
  670.  
  671.         case 37:
  672.             *elemMode = 5;
  673.             bpp = 1;
  674.             *expandX = 8;
  675.             break;
  676.  
  677.         case 2:
  678.         case 3:
  679.             bpp = 8;
  680.             *expandX = 1;
  681.             break;
  682.  
  683.         case 12:
  684.             bpp = 16;
  685.             *expandX = 1;
  686.             break;
  687.  
  688.         case 17:
  689.         case 18:
  690.         case 22:
  691.         case 24:
  692.         case 27:
  693.         case 41:
  694.         case 42:
  695.         case 43:
  696.             bpp = 32;
  697.             *expandX = 1;
  698.             break;
  699.  
  700.         case 28:
  701.             bpp = 64;
  702.             bitUnused = 24;
  703.             *expandX = 1;
  704.             break;
  705.  
  706.         case 44:
  707.             *elemMode = 4;
  708.             bpp = 24;
  709.             *expandX = 3;
  710.             break;
  711.  
  712.         case 45:
  713.         case 46:
  714.             *elemMode = 4;
  715.             bpp = 48;
  716.             *expandX = 3;
  717.             break;
  718.  
  719.         case 47:
  720.         case 48:
  721.             *elemMode = 4;
  722.             bpp = 96;
  723.             *expandX = 3;
  724.             break;
  725.  
  726.         case 49:
  727.             *elemMode = 9;
  728.             *expandY = 4;
  729.             bpp = 64;
  730.             *expandX = 4;
  731.             break;
  732.  
  733.         case 52:
  734.             *elemMode = 12;
  735.             *expandY = 4;
  736.             bpp = 64;
  737.             *expandX = 4;
  738.             break;
  739.  
  740.         case 50:
  741.             *elemMode = 10;
  742.             *expandY = 4;
  743.             bpp = 128;
  744.             *expandX = 4;
  745.             break;
  746.  
  747.         case 51:
  748.             *elemMode = 11;
  749.             *expandY = 4;
  750.             bpp = 128;
  751.             *expandX = 4;
  752.             break;
  753.  
  754.         case 53:
  755.         case 54:
  756.         case 55:
  757.             *elemMode = 13;
  758.             *expandY = 4;
  759.             bpp = 128;
  760.             *expandX = 4;
  761.             break;
  762.  
  763.         default:
  764.             bpp = 0;
  765.             *expandX = 1;
  766.  
  767.     return bpp;
  768. }
  769.  
  770.  
  771. u32 adjustSurfaceInfo(u32 elemMode, u32 expandX, u32 expandY, u32 pBpp, u32 pWidth, u32 pHeight)
  772. {
  773.     u32 bBCnFormat = 0;
  774.  
  775.     u32 bpp, packedBits, width, height;
  776.     u32 widtha, heighta;
  777.  
  778.     if (pBpp != 0)
  779.     {
  780.         bpp = pBpp;
  781.  
  782.         switch (elemMode)
  783.         {
  784.             case 4:
  785.                 packedBits = bpp / expandX / expandY;
  786.                 break;
  787.  
  788.             case 5:
  789.             case 6:
  790.                 packedBits = expandY * expandX * bpp;
  791.                 break;
  792.  
  793.             case 7:
  794.             case 8:
  795.                 packedBits = pBpp;
  796.                 break;
  797.  
  798.             case 9:
  799.             case 12:
  800.                 packedBits = 64;
  801.                 bBCnFormat = 1;
  802.                 break;
  803.  
  804.             case 10:
  805.             case 11:
  806.             case 13:
  807.                 bBCnFormat = 1;
  808.                 packedBits = 128;
  809.                 break;
  810.  
  811.             case 0:
  812.             case 1:
  813.             case 2:
  814.             case 3:
  815.                 packedBits = pBpp;
  816.                 break;
  817.  
  818.             default:
  819.                 packedBits = pBpp;
  820.                 break;
  821.         }
  822.  
  823.         pIn.bpp = packedBits;
  824.     }
  825.  
  826.     if (pWidth != 0)
  827.     {
  828.         if (pHeight != 0)
  829.         {
  830.             width = pWidth;
  831.             height = pHeight;
  832.  
  833.             if (expandX > 1 || expandY > 1)
  834.             {
  835.                 if (elemMode == 4)
  836.                 {
  837.                     widtha = expandX * width;
  838.                     heighta = expandY * height;
  839.                 }
  840.  
  841.                 else if (bBCnFormat != 0)
  842.                 {
  843.                     widtha = width / expandX;
  844.                     heighta = height / expandY;
  845.                 }
  846.  
  847.                 else
  848.                 {
  849.                     widtha = (width + expandX - 1) / expandX;
  850.                     heighta = (height + expandY - 1) / expandY;
  851.                 }
  852.  
  853.                 pIn.width = max(1, widtha);
  854.                 pIn.height = max(1, heighta);
  855.             }
  856.         }
  857.     }
  858.  
  859.     return packedBits;
  860. }
  861.  
  862.  
  863. u32 hwlComputeMipLevel()
  864. {
  865.     u32 width, widtha;
  866.     u32 height, heighta;
  867.     u32 slices;
  868.  
  869.     u32 handled = 0;
  870.  
  871.     if (49 <= pIn.format <= 55)
  872.     {
  873.         if (pIn.mipLevel != 0)
  874.         {
  875.             width = pIn.width;
  876.             height = pIn.height;
  877.             slices = pIn.numSlices;
  878.  
  879.             if ((pIn.flags.value >> 12) & 1 != 0)
  880.             {
  881.                 widtha = width >> pIn.mipLevel;
  882.                 heighta = height >> pIn.mipLevel;
  883.  
  884.                 if ((pIn.flags.value >> 4) & 1 == 0)
  885.                     slices >>= pIn.mipLevel;
  886.  
  887.                 width = max(1, widtha);
  888.                 height = max(1, heighta);
  889.                 slices = max(1, slices);
  890.             }
  891.  
  892.             pIn.width = nextPow2(width);
  893.             pIn.height = nextPow2(height);
  894.             pIn.numSlices = slices;
  895.         }
  896.  
  897.         handled = 1;
  898.     }
  899.  
  900.     return handled;
  901. }
  902.  
  903.  
  904. void computeMipLevel()
  905. {
  906.     u32 slices = 0;
  907.     u32 height = 0;
  908.     u32 width = 0;
  909.     u32 hwlHandled = 0;
  910.  
  911.     if (49 <= pIn.format <= 55 && (pIn.mipLevel == 0 || (pIn.flags.value >> 12) & 1 != 0))
  912.     {
  913.         pIn.width = powTwoAlign(pIn.width, 4);
  914.         pIn.height = powTwoAlign(pIn.height, 4);
  915.     }
  916.  
  917.     hwlHandled = hwlComputeMipLevel();
  918.     if (hwlHandled == 0 && pIn.mipLevel != 0 && (pIn.flags.value >> 12) & 1 != 0)
  919.     {
  920.         width = pIn.width;
  921.         height = pIn.height;
  922.         slices = pIn.numSlices;
  923.         width >>= pIn.mipLevel;
  924.         height >>= pIn.mipLevel;
  925.  
  926.         if ((pIn.flags.value >> 4) & 1 == 0)
  927.             slices >>= pIn.mipLevel;
  928.  
  929.         width = max(1, width);
  930.         height = max(1, height);
  931.         slices = max(1, slices);
  932.  
  933.         if (pIn.format != 47 && pIn.format != 48)
  934.         {
  935.             width = nextPow2(width);
  936.             height = nextPow2(height);
  937.             slices = nextPow2(slices);
  938.         }
  939.  
  940.         pIn.width = width;
  941.         pIn.height = height;
  942.         pIn.numSlices = slices;
  943.     }
  944. }
  945.  
  946.  
  947. u32 convertToNonBankSwappedMode(u32 tileMode)
  948. {
  949.     u32 expTileMode;
  950.  
  951.     switch (tileMode)
  952.     {
  953.         case 8:
  954.             expTileMode = 4;
  955.             break;
  956.  
  957.         case 9:
  958.             expTileMode = 5;
  959.             break;
  960.  
  961.         case 10:
  962.             expTileMode = 6;
  963.             break;
  964.  
  965.         case 11:
  966.             expTileMode = 7;
  967.             break;
  968.  
  969.         case 14:
  970.             expTileMode = 12;
  971.             break;
  972.  
  973.         case 15:
  974.             expTileMode = 13;
  975.             break;
  976.  
  977.         default:
  978.             expTileMode = tileMode;
  979.     }
  980.  
  981.     return expTileMode;
  982. }
  983.  
  984.  
  985. u32 computeSurfaceTileSlices(u32 tileMode, u32 bpp, u32 numSamples)
  986. {
  987.     u32 bytePerSample = ((bpp << 6) + 7) >> 3;
  988.     u32 tileSlices = 1;
  989.  
  990.     u32 samplePerTile;
  991.  
  992.     if (computeSurfaceThickness(tileMode) > 1)
  993.         numSamples = 4;
  994.  
  995.     if (bytePerSample != 0)
  996.     {
  997.         samplePerTile = m_splitSize / bytePerSample;
  998.         if (samplePerTile)
  999.             tileSlices = max(1, numSamples / samplePerTile);
  1000.     }
  1001.  
  1002.     return tileSlices;
  1003. }
  1004.  
  1005.  
  1006. u32 computeSurfaceRotationFromTileMode(u32 tileMode)
  1007. {
  1008.     u32 pipes = m_pipes;
  1009.     u32 result;
  1010.  
  1011.     switch (tileMode)
  1012.     {
  1013.         case 4:
  1014.         case 5:
  1015.         case 6:
  1016.         case 7:
  1017.         case 8:
  1018.         case 9:
  1019.         case 10:
  1020.         case 11:
  1021.             result = pipes * ((m_banks >> 1) - 1);
  1022.             break;
  1023.  
  1024.         case 12:
  1025.         case 13:
  1026.         case 14:
  1027.         case 15:
  1028.             result = 1;
  1029.             break;
  1030.  
  1031.         default:
  1032.             result = 0;
  1033.             break;
  1034.     }
  1035.  
  1036.     return result;
  1037. }
  1038.  
  1039.  
  1040. u32 computeSurfaceMipLevelTileMode(u32 baseTileMode, u32 bpp, u32 level, u32 width, u32 height, u32 numSlices, u32 numSamples, u32 isDepth, u32 noRecursive)
  1041. {
  1042.     u32 expTileMode = baseTileMode;
  1043.     u32 numPipes = m_pipes;
  1044.     u32 numBanks = m_banks;
  1045.     u32 groupBytes = m_pipeInterleaveBytes;
  1046.     u32 tileSlices = computeSurfaceTileSlices(baseTileMode, bpp, numSamples);
  1047.  
  1048.     u32 widtha, heighta, numSlicesa, thickness, microTileBytes, v13;
  1049.     u32 widthAlignFactor, macroTileWidth, macroTileHeight, v11;
  1050.  
  1051.     switch (baseTileMode)
  1052.     {
  1053.         case 5:
  1054.             if (2 * m_pipeInterleaveBytes > m_splitSize)
  1055.                 expTileMode = 4;
  1056.             break;
  1057.  
  1058.         case 6:
  1059.             if (4 * m_pipeInterleaveBytes > m_splitSize)
  1060.                 expTileMode = 5;
  1061.             break;
  1062.  
  1063.         case 7:
  1064.             if (numSamples > 1 || tileSlices > 1 || isDepth != 0)
  1065.                 expTileMode = 4;
  1066.             break;
  1067.  
  1068.         case 13:
  1069.             if (numSamples > 1 || tileSlices > 1 || isDepth != 0)
  1070.                 expTileMode = 12;
  1071.             break;
  1072.  
  1073.         case 9:
  1074.             if (2 * m_pipeInterleaveBytes > m_splitSize)
  1075.                 expTileMode = 8;
  1076.             break;
  1077.  
  1078.         case 10:
  1079.             if (4 * m_pipeInterleaveBytes > m_splitSize)
  1080.                 expTileMode = 9;
  1081.             break;
  1082.  
  1083.         case 11:
  1084.             if (numSamples > 1 || tileSlices > 1 || isDepth != 0)
  1085.                 expTileMode = 8;
  1086.             break;
  1087.  
  1088.         case 15:
  1089.             if (numSamples > 1 || tileSlices > 1 || isDepth != 0)
  1090.                 expTileMode = 14;
  1091.             break;
  1092.  
  1093.         case 2:
  1094.             if (numSamples > 1 && (m_configFlags >> 2) & 1 != 0)
  1095.                 expTileMode = 4;
  1096.             break;
  1097.  
  1098.         case 3:
  1099.             if (numSamples > 1 || isDepth != 0)
  1100.                 expTileMode = 2;
  1101.             if (numSamples == 2 || numSamples == 4)
  1102.                 expTileMode = 7;
  1103.             break;
  1104.  
  1105.         default:
  1106.             expTileMode = baseTileMode;
  1107.     }
  1108.  
  1109.     u32 rotation = computeSurfaceRotationFromTileMode(expTileMode);
  1110.     if (rotation % m_pipes == 0)
  1111.     {
  1112.         if (expTileMode == 12)
  1113.             expTileMode = 4;
  1114.  
  1115.         if (expTileMode == 14)
  1116.             expTileMode = 8;
  1117.  
  1118.         if (expTileMode == 13)
  1119.             expTileMode = 7;
  1120.  
  1121.         if (expTileMode == 15)
  1122.             expTileMode = 11;
  1123.     }
  1124.  
  1125.     u32 result;
  1126.     if (noRecursive != 0)
  1127.         result = expTileMode;
  1128.  
  1129.     else
  1130.     {
  1131.         if (bpp == 24 || bpp == 48 || bpp == 96)
  1132.             bpp /= 3;
  1133.  
  1134.         widtha = nextPow2(width);
  1135.         heighta = nextPow2(height);
  1136.         numSlicesa = nextPow2(numSlices);
  1137.  
  1138.         if (level != 0)
  1139.         {
  1140.             expTileMode = convertToNonBankSwappedMode(expTileMode);
  1141.             thickness = computeSurfaceThickness(expTileMode);
  1142.             microTileBytes = (numSamples * bpp * (thickness << 6) + 7) >> 3;
  1143.  
  1144.             if (microTileBytes >= groupBytes)
  1145.                 v13 = 1;
  1146.  
  1147.             else
  1148.                 v13 = groupBytes / microTileBytes;
  1149.  
  1150.             widthAlignFactor = v13;
  1151.             macroTileWidth = 8 * numBanks;
  1152.             macroTileHeight = 8 * numPipes;
  1153.  
  1154.             switch (expTileMode)
  1155.             {
  1156.                 case 4:
  1157.                 case 12:
  1158.                     if ((widtha < widthAlignFactor * macroTileWidth) || heighta < macroTileHeight)
  1159.                         expTileMode = 2;
  1160.                     break;
  1161.  
  1162.                 case 5:
  1163.                     macroTileWidth >>= 1;
  1164.                     macroTileHeight *= 2;
  1165.                     if ((widtha < widthAlignFactor * macroTileWidth) || heighta < macroTileHeight)
  1166.                         expTileMode = 2;
  1167.                     break;
  1168.  
  1169.                 case 6:
  1170.                     macroTileWidth >>= 2;
  1171.                     macroTileHeight *= 4;
  1172.                     if ((widtha < widthAlignFactor * macroTileWidth) || heighta < macroTileHeight)
  1173.                         expTileMode = 2;
  1174.                     break;
  1175.             }
  1176.  
  1177.             if (expTileMode == 7 || expTileMode == 13)
  1178.                 if ((widtha < widthAlignFactor * macroTileWidth) || heighta < macroTileHeight)
  1179.                     expTileMode = 3;
  1180.  
  1181.             v11 = expTileMode;
  1182.             if (expTileMode == 3)
  1183.                 if (numSlicesa < 4)
  1184.                     expTileMode = 2;
  1185.  
  1186.             else if (v11 == 7)
  1187.                 if (numSlicesa < 4)
  1188.                     expTileMode = 4;
  1189.  
  1190.             else if (v11 == 13 && numSlicesa < 4)
  1191.                 expTileMode = 12;
  1192.  
  1193.             result = computeSurfaceMipLevelTileMode(
  1194.                 expTileMode,
  1195.                 bpp,
  1196.                 level,
  1197.                 widtha,
  1198.                 heighta,
  1199.                 numSlicesa,
  1200.                 numSamples,
  1201.                 isDepth,
  1202.                 1);
  1203.         }
  1204.  
  1205.         else
  1206.             result = expTileMode;
  1207.     }
  1208.  
  1209.     return result;
  1210. }
  1211.  
  1212.  
  1213. u32 isDualPitchAlignNeeded(u32 tileMode, u32 isDepth, u32 mipLevel)
  1214. {
  1215.     u32 needed;
  1216.     if (isDepth != 0 || mipLevel != 0 || m_chipFamily != 1)
  1217.         needed = 0;
  1218.  
  1219.     else if (tileMode == 0 || tileMode == 1 || tileMode == 2 || tileMode == 3 || tileMode == 7 || tileMode == 11 || tileMode == 13 || tileMode == 15)
  1220.         needed = 0;
  1221.  
  1222.     else
  1223.         needed = 1;
  1224.  
  1225.     return needed;
  1226. }
  1227.  
  1228.  
  1229. u32 isPow2(u32 dim)
  1230. {
  1231.     if (dim & (dim - 1) == 0)
  1232.         return 1;
  1233.  
  1234.     else
  1235.         return 0;
  1236. }
  1237.  
  1238.  
  1239. void padDimensions(u32 tileMode, u32 padDims, u32 isCube, u32 cubeAsArray, u32 pitchAlign, u32 heightAlign, u32 sliceAlign, u32 *expPitch, u32 *expHeight, u32 *expNumSlices)
  1240. {
  1241.     u32 thickness = computeSurfaceThickness(tileMode);
  1242.  
  1243.     if (padDims == 0)
  1244.         padDims = 3;
  1245.  
  1246.     if (isPow2(pitchAlign) != 0)
  1247.         *expPitch = powTwoAlign(*expPitch, pitchAlign);
  1248.  
  1249.     else
  1250.     {
  1251.         *expPitch = pitchAlign + *expPitch - 1;
  1252.         *expPitch /= pitchAlign;
  1253.         *expPitch *= pitchAlign;
  1254.     }
  1255.  
  1256.     if (padDims > 1)
  1257.         *expHeight = powTwoAlign(*expHeight, heightAlign);
  1258.  
  1259.     if (padDims > 2 || thickness > 1)
  1260.     {
  1261.         if (isCube != 0 && ((m_configFlags >> 3) & 1 == 0 || cubeAsArray != 0))
  1262.             *expNumSlices = nextPow2(*expNumSlices);
  1263.  
  1264.         if (thickness > 1)
  1265.             *expNumSlices = powTwoAlign(*expNumSlices, sliceAlign);
  1266.     }
  1267. }
  1268.  
  1269.  
  1270. u32 adjustPitchAlignment(Flags flags, u32 pitchAlign)
  1271. {
  1272.     if ((flags.value >> 13) & 1 != 0)
  1273.         pitchAlign = powTwoAlign(pitchAlign, 0x20);
  1274.  
  1275.     return pitchAlign;
  1276. }
  1277.  
  1278.  
  1279. void computeSurfaceAlignmentsLinear(u32 tileMode, u32 bpp, Flags flags, u32 *baseAlign, u32 *pitchAlign, u32 *heightAlign)
  1280. {
  1281.     u32 pixelsPerPipeInterleave;
  1282.  
  1283.     if (tileMode != 0)
  1284.     {
  1285.         if (tileMode == 1)
  1286.         {
  1287.             pixelsPerPipeInterleave = 8 * m_pipeInterleaveBytes / bpp;
  1288.             *baseAlign = m_pipeInterleaveBytes;
  1289.             *pitchAlign = max(0x40, pixelsPerPipeInterleave);
  1290.             *heightAlign = 1;
  1291.         }
  1292.  
  1293.         else
  1294.         {
  1295.             *baseAlign = 1;
  1296.             *pitchAlign = 1;
  1297.             *heightAlign = 1;
  1298.         }
  1299.     }
  1300.  
  1301.     else
  1302.     {
  1303.         *baseAlign = 1;
  1304.         *pitchAlign = bpp != 1 ? 1: 8;
  1305.         *heightAlign = 1;
  1306.     }
  1307.  
  1308.     *pitchAlign = adjustPitchAlignment(flags, *pitchAlign);
  1309. }
  1310.  
  1311.  
  1312. 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)
  1313. {
  1314.     u32 valid = 1;
  1315.     u32 expPitch = pitch;
  1316.     u32 expHeight = height;
  1317.     u32 expNumSlices = numSlices;
  1318.     u32 microTileThickness = computeSurfaceThickness(tileMode);
  1319.  
  1320.     u32 baseAlign, pitchAlign, heightAlign;
  1321.     u32 tileSlices, slices;
  1322.  
  1323.     computeSurfaceAlignmentsLinear(tileMode, bpp, flags, &baseAlign, &pitchAlign, &heightAlign);
  1324.  
  1325.     if ((flags.value >> 9) & 1 != 0 && mipLevel == 0)
  1326.     {
  1327.         expPitch /= 3;
  1328.         expPitch = nextPow2(expPitch);
  1329.     }
  1330.  
  1331.     if (mipLevel != 0)
  1332.     {
  1333.         expPitch = nextPow2(expPitch);
  1334.         expHeight = nextPow2(expHeight);
  1335.  
  1336.         if ((flags.value >> 4) & 1 != 0)
  1337.         {
  1338.             expNumSlices = numSlices;
  1339.  
  1340.             if (numSlices <= 1)
  1341.                 padDims = 2;
  1342.  
  1343.             else
  1344.                 padDims = 0;
  1345.         }
  1346.  
  1347.         else
  1348.             expNumSlices = nextPow2(numSlices);
  1349.     }
  1350.  
  1351.     padDimensions(
  1352.         tileMode,
  1353.         padDims,
  1354.         (flags.value >> 4) & 1,
  1355.         (flags.value >> 7) & 1,
  1356.         pitchAlign,
  1357.         heightAlign,
  1358.         microTileThickness,
  1359.         &expPitch,
  1360.         &expHeight,
  1361.         &expNumSlices);
  1362.  
  1363.     if ((flags.value >> 9) & 1 != 0 && mipLevel == 0)
  1364.         expPitch *= 3;
  1365.  
  1366.     tileSlices = numSamples;
  1367.     slices = expNumSlices * numSamples / microTileThickness;
  1368.     *pPitchOut = expPitch;
  1369.     *pHeightOut = expHeight;
  1370.     *pNumSlicesOut = expNumSlices;
  1371.     *pSurfSize = (expHeight * expPitch * slices * bpp * numSamples + 7) / 8;
  1372.     *pBaseAlign = baseAlign;
  1373.     *pPitchAlign = pitchAlign;
  1374.     *pHeightAlign = heightAlign;
  1375.     *pDepthAlign = microTileThickness;
  1376.  
  1377.     return valid;
  1378. }
  1379.  
  1380.  
  1381. void computeSurfaceAlignmentsMicroTiled(u32 tileMode, u32 bpp, Flags flags, u32 numSamples, u32 *baseAlign, u32 *pitchAlign, u32 *heightAlign)
  1382. {
  1383.     if (bpp == 24 || bpp == 48 || bpp == 96)
  1384.         bpp /= 3;
  1385.  
  1386.     u32 v8 = computeSurfaceThickness(tileMode);
  1387.     *baseAlign = m_pipeInterleaveBytes;
  1388.     *pitchAlign = max(8, m_pipeInterleaveBytes / bpp / numSamples / v8);
  1389.     *heightAlign = 8;
  1390.  
  1391.     *pitchAlign = adjustPitchAlignment(flags, *pitchAlign);
  1392. }
  1393.  
  1394.  
  1395. 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)
  1396. {
  1397.     u32 valid = 1;
  1398.     u32 expTileMode = tileMode;
  1399.     u32 expPitch = pitch;
  1400.     u32 expHeight = height;
  1401.     u32 expNumSlices = numSlices;
  1402.     u32 microTileThickness = computeSurfaceThickness(tileMode);
  1403.  
  1404.     u32 baseAlign, pitchAlign, heightAlign;
  1405.  
  1406.     if (mipLevel != 0)
  1407.     {
  1408.         expPitch = nextPow2(pitch);
  1409.         expHeight = nextPow2(height);
  1410.  
  1411.         if ((flags.value >> 4) & 1 != 0)
  1412.         {
  1413.             expNumSlices = numSlices;
  1414.  
  1415.             if (numSlices <= 1)
  1416.                 padDims = 2;
  1417.  
  1418.             else
  1419.                 padDims = 0;
  1420.         }
  1421.  
  1422.         else
  1423.             expNumSlices = nextPow2(numSlices);
  1424.  
  1425.         if (expTileMode == 3 && expNumSlices < 4)
  1426.         {
  1427.             expTileMode = 2;
  1428.             microTileThickness = 1;
  1429.         }
  1430.     }
  1431.  
  1432.     computeSurfaceAlignmentsMicroTiled(
  1433.         expTileMode,
  1434.         bpp,
  1435.         flags,
  1436.         numSamples,
  1437.         &baseAlign,
  1438.         &pitchAlign,
  1439.         &heightAlign);
  1440.  
  1441.     padDimensions(
  1442.         expTileMode,
  1443.         padDims,
  1444.         (flags.value >> 4) & 1,
  1445.         (flags.value >> 7) & 1,
  1446.         pitchAlign,
  1447.         heightAlign,
  1448.         microTileThickness,
  1449.         &expPitch,
  1450.         &expHeight,
  1451.         &expNumSlices);
  1452.  
  1453.     *pPitchOut = expPitch;
  1454.     *pHeightOut = expHeight;
  1455.     *pNumSlicesOut = expNumSlices;
  1456.     *pSurfSize = (expHeight * expPitch * expNumSlices * bpp * numSamples + 7) / 8;
  1457.     *pTileModeOut = expTileMode;
  1458.     *pBaseAlign = baseAlign;
  1459.     *pPitchAlign = pitchAlign;
  1460.     *pHeightAlign = heightAlign;
  1461.     *pDepthAlign = microTileThickness;
  1462.  
  1463.     return valid;
  1464. }
  1465.  
  1466.  
  1467. u32 isDualBaseAlignNeeded(u32 tileMode)
  1468. {
  1469.     u32 needed = 1;
  1470.  
  1471.     if (m_chipFamily == 1)
  1472.         if (0 <= tileMode <= 3)
  1473.             needed = 0;
  1474.  
  1475.     else
  1476.         needed = 0;
  1477.  
  1478.     return needed;
  1479. }
  1480.  
  1481.  
  1482. void computeSurfaceAlignmentsMacroTiled(u32 tileMode, u32 bpp, Flags flags, u32 numSamples, u32 *baseAlign, u32 *pitchAlign, u32 *heightAlign, u32 *macroTileWidth, u32 *macroTileHeight)
  1483. {
  1484.     u32 groupBytes = m_pipeInterleaveBytes;
  1485.     u32 numBanks = m_banks;
  1486.     u32 numPipes = m_pipes;
  1487.     u32 splitBytes = m_splitSize;
  1488.     u32 aspectRatio = computeMacroTileAspectRatio(tileMode);
  1489.     u32 thickness = computeSurfaceThickness(tileMode);
  1490.  
  1491.     if (bpp == 24 || bpp == 48 || bpp == 96)
  1492.         bpp /= 3;
  1493.  
  1494.     if (bpp == 3)
  1495.         bpp = 1;
  1496.  
  1497.     *macroTileWidth = 8 * numBanks / aspectRatio;
  1498.     *macroTileHeight = aspectRatio * 8 * numPipes;
  1499.  
  1500.     *pitchAlign = max(*macroTileWidth, *macroTileWidth * (groupBytes / bpp / (8 * thickness) / numSamples));
  1501.     *pitchAlign = adjustPitchAlignment(flags, *pitchAlign);
  1502.  
  1503.     *heightAlign = *macroTileHeight;
  1504.     u32 macroTileBytes = numSamples * ((bpp * *macroTileHeight * *macroTileWidth + 7) >> 3);
  1505.  
  1506.     if (m_chipFamily == 1 && numSamples == 1)
  1507.         macroTileBytes *= 2;
  1508.  
  1509.     if (thickness == 1)
  1510.         *baseAlign = max(macroTileBytes, (numSamples * *heightAlign * bpp * *pitchAlign + 7) >> 3);
  1511.  
  1512.     else
  1513.         *baseAlign = max(groupBytes, (4 * *heightAlign * bpp * *pitchAlign + 7) >> 3);
  1514.  
  1515.     u32 microTileBytes = (thickness * numSamples * (bpp << 6) + 7) >> 3;
  1516.  
  1517.     u32 v11;
  1518.  
  1519.     if (microTileBytes < splitBytes)
  1520.         v11 = 1;
  1521.  
  1522.     else
  1523.         v11 = microTileBytes / splitBytes;
  1524.  
  1525.     u32 numSlicesPerMicroTile = v11;
  1526.  
  1527.     *baseAlign /= v11;
  1528.  
  1529.     u32 macroBytes;
  1530.  
  1531.     if (isDualBaseAlignNeeded(tileMode) != 0)
  1532.     {
  1533.         macroBytes = (bpp * *macroTileHeight * *macroTileWidth + 7) >> 3;
  1534.  
  1535.         if (*baseAlign / macroBytes % 2 != 0)
  1536.             *baseAlign += macroBytes;
  1537.     }
  1538. }
  1539.  
  1540.  
  1541. 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)
  1542. {
  1543.     u32 valid = 1;
  1544.  
  1545.     u32 expPitch = pitch;
  1546.     u32 expHeight = height;
  1547.     u32 expNumSlices = numSlices;
  1548.  
  1549.     u32 expTileMode = tileMode;
  1550.     u32 microTileThickness = computeSurfaceThickness(tileMode);
  1551.  
  1552.     u32 bankSwappedWidth, v21, tilePerGroup;
  1553.     u32 evenHeight, evenWidth, pitchAlignFactor;
  1554.  
  1555.     u32 baseAlign, pitchAlign, heightAlign;
  1556.     u32 macroWidth, macroHeight;
  1557.  
  1558.     u32 result;
  1559.  
  1560.     if (mipLevel != 0)
  1561.     {
  1562.         expPitch = nextPow2(pitch);
  1563.         expHeight = nextPow2(height);
  1564.  
  1565.         if ((flags.value >> 4) & 1 != 0)
  1566.         {
  1567.             expNumSlices = numSlices;
  1568.             padDims = numSlices <= 1 ? 2: 0;
  1569.         }
  1570.  
  1571.         else
  1572.             expNumSlices = nextPow2(numSlices);
  1573.  
  1574.         if (expTileMode == 7 && expNumSlices < 4)
  1575.         {
  1576.             expTileMode = 4;
  1577.             microTileThickness = 1;
  1578.         }
  1579.     }
  1580.  
  1581.     if (tileMode == baseTileMode
  1582.         || mipLevel == 0
  1583.         || isThickMacroTiled(baseTileMode) == 0
  1584.         || isThickMacroTiled(tileMode) != 0)
  1585.     {
  1586.         computeSurfaceAlignmentsMacroTiled(
  1587.             tileMode,
  1588.             bpp,
  1589.             flags,
  1590.             numSamples,
  1591.             &baseAlign,
  1592.             &pitchAlign,
  1593.             &heightAlign,
  1594.             &macroWidth,
  1595.             &macroHeight);
  1596.  
  1597.         bankSwappedWidth = computeSurfaceBankSwappedWidth(tileMode, bpp, pitch, numSamples);
  1598.  
  1599.         if (bankSwappedWidth > pitchAlign)
  1600.             pitchAlign = bankSwappedWidth;
  1601.  
  1602.         if (isDualPitchAlignNeeded(tileMode, (flags.value >> 1) & 1, mipLevel) != 0)
  1603.         {
  1604.             v21 = (m_pipeInterleaveBytes >> 3) / bpp / numSamples;
  1605.             tilePerGroup = v21 / computeSurfaceThickness(tileMode);
  1606.  
  1607.             if (tilePerGroup == 0)
  1608.                 tilePerGroup = 1;
  1609.  
  1610.             evenHeight = (expHeight - 1) / macroHeight & 1;
  1611.             evenWidth = (expPitch - 1) / macroWidth & 1;
  1612.  
  1613.             if (numSamples == 1
  1614.                 && tilePerGroup == 1
  1615.                 && evenWidth == 0
  1616.                 && (expPitch > macroWidth || evenHeight == 0 && expHeight > macroHeight))
  1617.                 expPitch += macroWidth;
  1618.  
  1619.         padDimensions(
  1620.             tileMode,
  1621.             padDims,
  1622.             (flags.value >> 4) & 1,
  1623.             (flags.value >> 7) & 1,
  1624.             pitchAlign,
  1625.             heightAlign,
  1626.             microTileThickness,
  1627.             &expPitch,
  1628.             &expHeight,
  1629.             &expNumSlices);
  1630.  
  1631.         *pPitchOut = expPitch;
  1632.         *pHeightOut = expHeight;
  1633.         *pNumSlicesOut = expNumSlices;
  1634.         *pSurfSize = (expHeight * expPitch * expNumSlices * bpp * numSamples + 7) / 8;
  1635.         *pTileModeOut = expTileMode;
  1636.         *pBaseAlign = baseAlign;
  1637.         *pPitchAlign = pitchAlign;
  1638.         *pHeightAlign = heightAlign;
  1639.         *pDepthAlign = microTileThickness;
  1640.         result = valid;
  1641.         }
  1642.     }
  1643.  
  1644.     else
  1645.     {
  1646.         computeSurfaceAlignmentsMacroTiled(
  1647.             baseTileMode,
  1648.             bpp,
  1649.             flags,
  1650.             numSamples,
  1651.             &baseAlign,
  1652.             &pitchAlign,
  1653.             &heightAlign,
  1654.             &macroWidth,
  1655.             &macroHeight);
  1656.  
  1657.         pitchAlignFactor = (m_pipeInterleaveBytes >> 3) / bpp;
  1658.         if (pitchAlignFactor == 0)
  1659.             pitchAlignFactor = 1;
  1660.  
  1661.         if (expPitch < pitchAlign * pitchAlignFactor || expHeight < heightAlign)
  1662.         {
  1663.             expTileMode = 2;
  1664.  
  1665.             result = computeSurfaceInfoMicroTiled(
  1666.                 2,
  1667.                 bpp,
  1668.                 numSamples,
  1669.                 pitch,
  1670.                 height,
  1671.                 numSlices,
  1672.                 mipLevel,
  1673.                 padDims,
  1674.                 flags,
  1675.                 pPitchOut,
  1676.                 pHeightOut,
  1677.                 pNumSlicesOut,
  1678.                 pSurfSize,
  1679.                 pTileModeOut,
  1680.                 pBaseAlign,
  1681.                 pPitchAlign,
  1682.                 pHeightAlign,
  1683.                 pDepthAlign);
  1684.         }
  1685.  
  1686.         else
  1687.         {
  1688.             computeSurfaceAlignmentsMacroTiled(
  1689.                 tileMode,
  1690.                 bpp,
  1691.                 flags,
  1692.                 numSamples,
  1693.                 &baseAlign,
  1694.                 &pitchAlign,
  1695.                 &heightAlign,
  1696.                 &macroWidth,
  1697.                 &macroHeight);
  1698.  
  1699.             bankSwappedWidth = computeSurfaceBankSwappedWidth(tileMode, bpp, pitch, numSamples);
  1700.  
  1701.             if (bankSwappedWidth > pitchAlign)
  1702.                 pitchAlign = bankSwappedWidth;
  1703.  
  1704.             if (isDualPitchAlignNeeded(tileMode, (flags.value >> 1) & 1, mipLevel) != 0)
  1705.             {
  1706.                 v21 = (m_pipeInterleaveBytes >> 3) / bpp / numSamples;
  1707.                 tilePerGroup = v21 / computeSurfaceThickness(tileMode);
  1708.  
  1709.                 if (tilePerGroup == 0)
  1710.                     tilePerGroup = 1;
  1711.  
  1712.                 evenHeight = (expHeight - 1) / macroHeight & 1;
  1713.                 evenWidth = (expPitch - 1) / macroWidth & 1;
  1714.  
  1715.                 if (numSamples == 1
  1716.                     && tilePerGroup == 1
  1717.                     && evenWidth == 0
  1718.                     && (expPitch > macroWidth || evenHeight == 0 && expHeight > macroHeight))
  1719.                     expPitch += macroWidth;
  1720.  
  1721.             padDimensions(
  1722.                 tileMode,
  1723.                 padDims,
  1724.                 (flags.value >> 4) & 1,
  1725.                 (flags.value >> 7) & 1,
  1726.                 pitchAlign,
  1727.                 heightAlign,
  1728.                 microTileThickness,
  1729.                 &expPitch,
  1730.                 &expHeight,
  1731.                 &expNumSlices);
  1732.  
  1733.             *pPitchOut = expPitch;
  1734.             *pHeightOut = expHeight;
  1735.             *pNumSlicesOut = expNumSlices;
  1736.             *pSurfSize = (expHeight * expPitch * expNumSlices * bpp * numSamples + 7) / 8;
  1737.             *pTileModeOut = expTileMode;
  1738.             *pBaseAlign = baseAlign;
  1739.             *pPitchAlign = pitchAlign;
  1740.             *pHeightAlign = heightAlign;
  1741.             *pDepthAlign = microTileThickness;
  1742.             result = valid;
  1743.             }
  1744.         }
  1745.  
  1746.     return result;
  1747. }
  1748.  
  1749.  
  1750. u32 ComputeSurfaceInfoEx()
  1751. {
  1752.     u32 tileMode = pIn.tileMode;
  1753.     u32 bpp = pIn.bpp;
  1754.     u32 numSamples = max(1, pIn.numSamples);
  1755.     u32 pitch = pIn.width;
  1756.     u32 height = pIn.height;
  1757.     u32 numSlices = pIn.numSlices;
  1758.     u32 mipLevel = pIn.mipLevel;
  1759.     Flags flags = pIn.flags;
  1760.     u32 pPitchOut = pOut.pitch;
  1761.     u32 pHeightOut = pOut.height;
  1762.     u32 pNumSlicesOut = pOut.depth;
  1763.     u32 pTileModeOut = pOut.tileMode;
  1764.     u32 pSurfSize = pOut.surfSize;
  1765.     u32 pBaseAlign = pOut.baseAlign;
  1766.     u32 pPitchAlign = pOut.pitchAlign;
  1767.     u32 pHeightAlign = pOut.heightAlign;
  1768.     u32 pDepthAlign = pOut.depthAlign;
  1769.     u32 padDims = 0;
  1770.     u32 valid = 0;
  1771.     u32 baseTileMode = tileMode;
  1772.  
  1773.     u32 result;
  1774.  
  1775.     if ((flags.value >> 4) & 1 != 0 && mipLevel == 0)
  1776.         padDims = 2;
  1777.  
  1778.     if ((flags.value >> 6) & 1 != 0)
  1779.         tileMode = convertToNonBankSwappedMode(tileMode);
  1780.  
  1781.     else
  1782.         tileMode = computeSurfaceMipLevelTileMode(
  1783.             tileMode,
  1784.             bpp,
  1785.             mipLevel,
  1786.             pitch,
  1787.             height,
  1788.             numSlices,
  1789.             numSamples,
  1790.             (flags.value >> 1) & 1,
  1791.             0);
  1792.  
  1793.     switch (tileMode)
  1794.     {
  1795.         case 0:
  1796.         case 1:
  1797.             valid = computeSurfaceInfoLinear(
  1798.                 tileMode,
  1799.                 bpp,
  1800.                 numSamples,
  1801.                 pitch,
  1802.                 height,
  1803.                 numSlices,
  1804.                 mipLevel,
  1805.                 padDims,
  1806.                 flags,
  1807.                 &pPitchOut,
  1808.                 &pHeightOut,
  1809.                 &pNumSlicesOut,
  1810.                 &pSurfSize,
  1811.                 &pBaseAlign,
  1812.                 &pPitchAlign,
  1813.                 &pHeightAlign,
  1814.                 &pDepthAlign);
  1815.             pTileModeOut = tileMode;
  1816.             break;
  1817.  
  1818.         case 2:
  1819.         case 3:
  1820.             valid = computeSurfaceInfoMicroTiled(
  1821.                 tileMode,
  1822.                 bpp,
  1823.                 numSamples,
  1824.                 pitch,
  1825.                 height,
  1826.                 numSlices,
  1827.                 mipLevel,
  1828.                 padDims,
  1829.                 flags,
  1830.                 &pPitchOut,
  1831.                 &pHeightOut,
  1832.                 &pNumSlicesOut,
  1833.                 &pSurfSize,
  1834.                 &pTileModeOut,
  1835.                 &pBaseAlign,
  1836.                 &pPitchAlign,
  1837.                 &pHeightAlign,
  1838.                 &pDepthAlign);
  1839.             break;
  1840.  
  1841.         case 4:
  1842.         case 5:
  1843.         case 6:
  1844.         case 7:
  1845.         case 8:
  1846.         case 9:
  1847.         case 10:
  1848.         case 11:
  1849.         case 12:
  1850.         case 13:
  1851.         case 14:
  1852.         case 15:
  1853.             valid = computeSurfaceInfoMacroTiled(
  1854.                 tileMode,
  1855.                 baseTileMode,
  1856.                 bpp,
  1857.                 numSamples,
  1858.                 pitch,
  1859.                 height,
  1860.                 numSlices,
  1861.                 mipLevel,
  1862.                 padDims,
  1863.                 flags,
  1864.                 &pPitchOut,
  1865.                 &pHeightOut,
  1866.                 &pNumSlicesOut,
  1867.                 &pSurfSize,
  1868.                 &pTileModeOut,
  1869.                 &pBaseAlign,
  1870.                 &pPitchAlign,
  1871.                 &pHeightAlign,
  1872.                 &pDepthAlign);
  1873.             break;
  1874.     }
  1875.  
  1876.     result = 0;
  1877.     if (valid == 0)
  1878.         result = 3;
  1879.  
  1880.     pOut.pitch = pPitchOut;
  1881.     pOut.height = pHeightOut;
  1882.     pOut.depth = pNumSlicesOut;
  1883.     pOut.tileMode = pTileModeOut;
  1884.     pOut.surfSize = pSurfSize;
  1885.     pOut.baseAlign = pBaseAlign;
  1886.     pOut.pitchAlign = pPitchAlign;
  1887.     pOut.heightAlign = pHeightAlign;
  1888.     pOut.depthAlign = pDepthAlign;
  1889.  
  1890.     return result;
  1891. }
  1892.  
  1893.  
  1894. u32 restoreSurfaceInfo(u32 elemMode, u32 expandX, u32 expandY, u32 bpp)
  1895. {
  1896.     u32 originalBits, width, height;
  1897.  
  1898.     if (bpp != 0)
  1899.     {
  1900.         switch (elemMode)
  1901.         {
  1902.             case 4:
  1903.                 originalBits = expandY * expandX * bpp;
  1904.                 break;
  1905.  
  1906.             case 5:
  1907.             case 6:
  1908.                 originalBits = bpp / expandX / expandY;
  1909.                 break;
  1910.  
  1911.             case 7:
  1912.             case 8:
  1913.                 originalBits = bpp;
  1914.                 break;
  1915.  
  1916.             case 9:
  1917.             case 12:
  1918.                 originalBits = 64;
  1919.                 break;
  1920.  
  1921.             case 10:
  1922.             case 11:
  1923.             case 13:
  1924.                 originalBits = 128;
  1925.                 break;
  1926.  
  1927.             case 0:
  1928.             case 1:
  1929.             case 2:
  1930.             case 3:
  1931.                 originalBits = bpp;
  1932.                 break;
  1933.  
  1934.             default:
  1935.                 originalBits = bpp;
  1936.                 break;
  1937.         }
  1938.  
  1939.         bpp = originalBits;
  1940.     }
  1941.  
  1942.     if (pOut.pixelPitch != 0 && pOut.pixelHeight != 0)
  1943.     {
  1944.         width = pOut.pixelPitch;
  1945.         height = pOut.pixelHeight;
  1946.  
  1947.         if (expandX > 1 || expandY > 1)
  1948.         {
  1949.             if (elemMode == 4)
  1950.             {
  1951.                 width /= expandX;
  1952.                 height /= expandY;
  1953.             }
  1954.  
  1955.             else
  1956.             {
  1957.                 width *= expandX;
  1958.                 height *= expandY;
  1959.             }
  1960.         }
  1961.  
  1962.         pOut.pixelPitch = max(1, width);
  1963.         pOut.pixelHeight = max(1, height);
  1964.     }
  1965.  
  1966.     return bpp;
  1967. }
  1968.  
  1969.  
  1970. void computeSurfaceInfo(surfaceIn aSurfIn, surfaceOut pSurfOut)
  1971. {
  1972.     pIn = aSurfIn;
  1973.     pOut = pSurfOut;
  1974.  
  1975.     u32 v4 = 0;
  1976.     u32 v6 = 0;
  1977.     u32 v7 = 0;
  1978.     u32 v8 = 0;
  1979.     u32 v10 = 0;
  1980.     u32 v11 = 0;
  1981.     u32 v12 = 0;
  1982.     u32 v14 = 0;
  1983.     u32 v18 = 0;
  1984.     tileInfo tileInfoNull;
  1985.     u32 sliceFlags = 0;
  1986.  
  1987.     u32 returnCode;
  1988.  
  1989.     u32 width, height, bpp, elemMode;
  1990.     u32 expandY, expandX, sliceTileMax;
  1991.  
  1992.     returnCode = 0;
  1993.     if (getFillSizeFieldsFlags() == 1 && (pIn.size != 60 || pOut.size != 96)) // --> m_configFlags.value = 4
  1994.         returnCode = 6;
  1995.  
  1996.     // v3 = pIn
  1997.  
  1998.     if (pIn.bpp > 0x80)
  1999.         returnCode = 3;
  2000.  
  2001.     if (returnCode == ADDR_OK)
  2002.         v18 = 0;
  2003.  
  2004.         computeMipLevel();
  2005.  
  2006.         width = pIn.width;
  2007.         height = pIn.height;
  2008.         bpp = pIn.bpp;
  2009.         expandX = 1;
  2010.         expandY = 1;
  2011.  
  2012.         sliceFlags = getSliceComputingFlags();
  2013.  
  2014.         if (useTileIndex(pIn.tileIndex) && !pIn.pTileInfo)
  2015.         {
  2016.             if (pOut.pTileInfo)
  2017.                 pIn.pTileInfo = pOut.pTileInfo;
  2018.  
  2019.             else
  2020.             {
  2021.                 pOut.pTileInfo = &tileInfoNull;
  2022.                 pIn.pTileInfo = &tileInfoNull;
  2023.             }
  2024.         }
  2025.  
  2026.         returnCode = 0;  // does nothing
  2027.         if (returnCode == ADDR_OK)
  2028.         {
  2029.             pOut.pixelBits = pIn.bpp;
  2030.  
  2031.             // v3 = pIn
  2032.  
  2033.             if (pIn.format != 0)
  2034.             {
  2035.                 v18 = 1;
  2036.                 v4 = pIn.format;
  2037.                 bpp = getBitsPerPixel(v4, &expandX, &expandY, &elemMode);
  2038.  
  2039.                 if (elemMode == 4 && expandX == 3 && pIn.tileMode == 1)
  2040.                     pIn.flags.value |= 0x200;
  2041.  
  2042.                 v6 = expandY;
  2043.                 v7 = expandX;
  2044.                 v8 = elemMode;
  2045.                 bpp = adjustSurfaceInfo(v8, v7, v6, bpp, width, height);
  2046.             }
  2047.  
  2048.             else if (pIn.bpp != 0)
  2049.             {
  2050.                 pIn.width = max(1, pIn.width);
  2051.                 pIn.height = max(1, pIn.height);
  2052.             }
  2053.  
  2054.             else
  2055.                 returnCode = 3;
  2056.         }
  2057.  
  2058.         if (returnCode == ADDR_OK)
  2059.             returnCode = ComputeSurfaceInfoEx();
  2060.  
  2061.         if (returnCode == ADDR_OK)
  2062.         {
  2063.             pOut.bpp = pIn.bpp;
  2064.             pOut.pixelPitch = pOut.pitch;
  2065.             pOut.pixelHeight = pOut.height;
  2066.  
  2067.             if (pIn.format && (!((pIn.flags.value >> 9) & 1) || !pIn.mipLevel))
  2068.             {
  2069.                 if (!v18)
  2070.                     return;
  2071.  
  2072.                 v10 = expandY;
  2073.                 v11 = expandX;
  2074.                 v12 = elemMode;
  2075.                 bpp = restoreSurfaceInfo(v12, v11, v10, bpp);
  2076.             }
  2077.  
  2078.             if (sliceFlags)
  2079.                 if (sliceFlags == 1)
  2080.                     pOut.sliceSize = (pOut.height * pOut.pitch * pOut.bpp * pIn.numSamples + 7) / 8;
  2081.  
  2082.             else if ((pIn.flags.value >> 5) & 1)
  2083.                 pOut.sliceSize = pOut.surfSize;
  2084.  
  2085.             else
  2086.             {
  2087.                 v14 = pOut.surfSize >> 32;
  2088.                 pOut.sliceSize = pOut.surfSize / pOut.depth;
  2089.  
  2090.                 if (pIn.slice == (pIn.numSlices - 1) && pIn.numSlices > 1)
  2091.                     pOut.sliceSize += pOut.sliceSize * (pOut.depth - pIn.numSlices);
  2092.             }
  2093.  
  2094.             pOut.pitchTileMax = (pOut.pitch >> 3) - 1;
  2095.             pOut.heightTileMax = (pOut.height >> 3) - 1;
  2096.             sliceTileMax = (pOut.height * pOut.pitch >> 6) - 1;
  2097.             pOut.sliceTileMax = sliceTileMax;
  2098.         }
  2099. }
  2100.  
  2101.  
  2102. surfaceOut getSurfaceInfo(u32 surfaceFormat, u32 surfaceWidth, u32 surfaceHeight, u32 surfaceDepth, u32 surfaceDim, u32 surfaceTileMode, u32 surfaceAA, u32 level)
  2103. {
  2104.     u32 dim = 0;
  2105.     u32 width = 0;
  2106.     u32 blockSize = 0;
  2107.     u32 numSamples = 0;
  2108.     u32 hwFormat = 0;
  2109.  
  2110.     surfaceIn aSurfIn;
  2111.     surfaceOut pSurfOut;
  2112.  
  2113.     hwFormat = surfaceFormat & 0x3F;
  2114.     if (surfaceTileMode == 16)
  2115.     {
  2116.         numSamples = 1 << surfaceAA;
  2117.  
  2118.         if (hwFormat < 0x31 || hwFormat > 0x35)
  2119.             blockSize = 1;
  2120.  
  2121.         else
  2122.             blockSize = 4;
  2123.  
  2124.         width = ~(blockSize - 1) & ((surfaceWidth >> level) + blockSize - 1);
  2125.  
  2126.         if (hwFormat == 0x35)
  2127.             return pSurfOut;
  2128.  
  2129.         pSurfOut.bpp = formatHwInfo[hwFormat * 4];
  2130.         pSurfOut.size = 96;
  2131.         pSurfOut.pitch = width / blockSize;
  2132.         pSurfOut.pixelBits = formatHwInfo[hwFormat * 4];
  2133.         pSurfOut.baseAlign = 1;
  2134.         pSurfOut.pitchAlign = 1;
  2135.         pSurfOut.heightAlign = 1;
  2136.         pSurfOut.depthAlign = 1;
  2137.         dim = surfaceDim;
  2138.  
  2139.         switch (dim)
  2140.         {
  2141.             case 0:
  2142.                 pSurfOut.height = 1;
  2143.                 pSurfOut.depth = 1;
  2144.                 break;
  2145.  
  2146.             case 1:
  2147.                 pSurfOut.height = max(1, surfaceHeight >> level);
  2148.                 pSurfOut.depth = 1;
  2149.                 break;
  2150.  
  2151.             case 2:
  2152.                 pSurfOut.height = max(1, surfaceHeight >> level);
  2153.                 pSurfOut.depth = max(1, surfaceDepth >> level);
  2154.                 break;
  2155.  
  2156.             case 3:
  2157.                 pSurfOut.height = max(1, surfaceHeight >> level);
  2158.                 pSurfOut.depth = max(6, surfaceDepth);
  2159.  
  2160.             case 4:
  2161.                 pSurfOut.height = 1;
  2162.                 pSurfOut.depth = surfaceDepth;
  2163.                 break;
  2164.  
  2165.             case 5:
  2166.                 pSurfOut.height = max(1, surfaceHeight >> level);
  2167.                 pSurfOut.depth = surfaceDepth;
  2168.                 break;
  2169.         }
  2170.  
  2171.         pSurfOut.height = (~(blockSize - 1) & (pSurfOut.height + blockSize - 1)) / blockSize;
  2172.         pSurfOut.pixelPitch = ~(blockSize - 1) & ((surfaceWidth >> level) + blockSize - 1);
  2173.         pSurfOut.pixelPitch = max(blockSize, pSurfOut.pixelPitch);
  2174.         pSurfOut.pixelHeight = ~(blockSize - 1) & ((surfaceHeight >> level) + blockSize - 1);
  2175.         pSurfOut.pixelHeight = max(blockSize, pSurfOut.pixelHeight);
  2176.         pSurfOut.pitch = max(1, pSurfOut.pitch);
  2177.         pSurfOut.height = max(1, pSurfOut.height);
  2178.         pSurfOut.surfSize = pSurfOut.bpp * numSamples * pSurfOut.depth * pSurfOut.height * pSurfOut.pitch >> 3;
  2179.  
  2180.         if (surfaceDim == 2)
  2181.             pSurfOut.sliceSize = pSurfOut.surfSize;
  2182.  
  2183.         else
  2184.             pSurfOut.sliceSize = pSurfOut.surfSize / pSurfOut.depth;
  2185.  
  2186.         pSurfOut.pitchTileMax = (pSurfOut.pitch >> 3) - 1;
  2187.         pSurfOut.heightTileMax = (pSurfOut.height >> 3) - 1;
  2188.         pSurfOut.sliceTileMax = (pSurfOut.height * pSurfOut.pitch >> 6) - 1;
  2189.     }
  2190.  
  2191.     else
  2192.     {
  2193.         aSurfIn.size = 60;
  2194.         aSurfIn.tileMode = surfaceTileMode & 0xF;
  2195.         aSurfIn.format = hwFormat;
  2196.         aSurfIn.bpp = formatHwInfo[hwFormat * 4];
  2197.         aSurfIn.numSamples = 1 << surfaceAA;
  2198.         aSurfIn.numFrags = aSurfIn.numSamples;
  2199.         aSurfIn.width = max(1, surfaceWidth >> level);
  2200.         dim = surfaceDim;
  2201.  
  2202.         switch (dim)
  2203.         {
  2204.             case 0:
  2205.                 aSurfIn.height = 1;
  2206.                 aSurfIn.numSlices = 1;
  2207.                 break;
  2208.  
  2209.             case 1:
  2210.                 aSurfIn.height = max(1, surfaceHeight >> level);
  2211.                 aSurfIn.numSlices = 1;
  2212.                 break;
  2213.  
  2214.             case 2:
  2215.                 aSurfIn.height = max(1, surfaceHeight >> level);
  2216.                 aSurfIn.numSlices = max(1, surfaceDepth >> level);
  2217.                 break;
  2218.  
  2219.             case 3:
  2220.                 aSurfIn.height = max(1, surfaceHeight >> level);
  2221.                 aSurfIn.numSlices = max(6, surfaceDepth);
  2222.                 aSurfIn.flags.value |= 0x10;
  2223.                 break;
  2224.  
  2225.             case 4:
  2226.                 aSurfIn.height = 1;
  2227.                 aSurfIn.numSlices = surfaceDepth;
  2228.                 break;
  2229.  
  2230.             case 5:
  2231.                 aSurfIn.height = max(1, surfaceHeight >> level);
  2232.                 aSurfIn.numSlices = surfaceDepth;
  2233.                 break;
  2234.  
  2235.             case 6:
  2236.                 aSurfIn.height = max(1, surfaceHeight >> level);
  2237.                 aSurfIn.numSlices = 1;
  2238.                 break;
  2239.  
  2240.             case 7:
  2241.                 aSurfIn.height = max(1, surfaceHeight >> level);
  2242.                 aSurfIn.numSlices = surfaceDepth;
  2243.                 break;
  2244.         }
  2245.  
  2246.         aSurfIn.slice = 0;
  2247.         aSurfIn.mipLevel = level;
  2248.  
  2249.         if (surfaceDim == 2)
  2250.             aSurfIn.flags.value |= 0x20;
  2251.  
  2252.         if (level == 0)
  2253.             aSurfIn.flags.value = (1 << 12) | aSurfIn.flags.value & 0xFFFFEFFF;
  2254.  
  2255.         else
  2256.             aSurfIn.flags.value = aSurfIn.flags.value & 0xFFFFEFFF;
  2257.  
  2258.         pSurfOut.size = 96;
  2259.         computeSurfaceInfo(aSurfIn, pSurfOut);
  2260.         pSurfOut = pOut;
  2261.     }
  2262.  
  2263.     return pSurfOut;
  2264. }
Advertisement
Add Comment
Please, Sign In to add comment