예제 #1
0
        public static int computeSurfaceRotationFromTileMode(AddrTileMode tileMode)
        {
            switch ((int)tileMode)
            {
            case 4:
            case 5:
            case 6:
            case 7:
            case 8:
            case 9:
            case 10:
            case 11:
            {
                return(2);
            }

            case 12:
            case 13:
            case 14:
            case 15:
            {
                return(1);
            }
            }

            return(0);
        }
예제 #2
0
        public static int computeMacroTileAspectRatio(AddrTileMode tileMode)
        {
            switch (tileMode)
            {
            case AddrTileMode.ADDR_TM_2B_TILED_THIN1:
            case AddrTileMode.ADDR_TM_3D_TILED_THIN1:
            case AddrTileMode.ADDR_TM_3B_TILED_THIN1:
            {
                return(1);
            }

            case AddrTileMode.ADDR_TM_2D_TILED_THIN2:
            case AddrTileMode.ADDR_TM_2B_TILED_THIN2:
            {
                return(2);
            }

            case AddrTileMode.ADDR_TM_2D_TILED_THIN4:
            case AddrTileMode.ADDR_TM_2B_TILED_THIN4:
            {
                return(4);
            }
            }

            return(1);
        }
예제 #3
0
        public static int ComputeMacroTileAspectRatio(AddrTileMode tileMode)
        {
            switch (tileMode)
            {
            case AddrTileMode.AddrTm2BTiledThin1:
            case AddrTileMode.AddrTm3DTiledThin1:
            case AddrTileMode.AddrTm3BTiledThin1:
            {
                return(1);
            }

            case AddrTileMode.AddrTm2DTiledThin2:
            case AddrTileMode.AddrTm2BTiledThin2:
            {
                return(2);
            }

            case AddrTileMode.AddrTm2DTiledThin4:
            case AddrTileMode.AddrTm2BTiledThin4:
            {
                return(4);
            }
            }

            return(1);
        }
예제 #4
0
        public static int isThickMacroTiled(AddrTileMode tileMode)
        {
            switch (tileMode)
            {
            case AddrTileMode.ADDR_TM_2D_TILED_THICK:
            case AddrTileMode.ADDR_TM_2B_TILED_THICK:
            case AddrTileMode.ADDR_TM_3D_TILED_THICK:
            case AddrTileMode.ADDR_TM_3B_TILED_THICK:
            {
                return(1);
            }
            }

            return(0);
        }
예제 #5
0
        public static int IsThickMacroTiled(AddrTileMode tileMode)
        {
            switch (tileMode)
            {
            case AddrTileMode.AddrTm2DTiledThick:
            case AddrTileMode.AddrTm2BTiledThick:
            case AddrTileMode.AddrTm3DTiledThick:
            case AddrTileMode.AddrTm3BTiledThick:
            {
                return(1);
            }
            }

            return(0);
        }
예제 #6
0
 public static int isBankSwappedTileMode(AddrTileMode tileMode)
 {
     switch (tileMode)
     {
     case AddrTileMode.ADDR_TM_2B_TILED_THIN1:
     case AddrTileMode.ADDR_TM_2B_TILED_THIN2:
     case AddrTileMode.ADDR_TM_2B_TILED_THIN4:
     case AddrTileMode.ADDR_TM_2B_TILED_THICK:
     case AddrTileMode.ADDR_TM_3B_TILED_THIN1:
     case AddrTileMode.ADDR_TM_3B_TILED_THICK:
     {
         return(1);
     }
     }
     return(0);
 }
예제 #7
0
 public static int IsBankSwappedTileMode(AddrTileMode tileMode)
 {
     switch (tileMode)
     {
     case AddrTileMode.AddrTm2BTiledThin1:
     case AddrTileMode.AddrTm2BTiledThin2:
     case AddrTileMode.AddrTm2BTiledThin4:
     case AddrTileMode.AddrTm2BTiledThick:
     case AddrTileMode.AddrTm3BTiledThin1:
     case AddrTileMode.AddrTm3BTiledThick:
     {
         return(1);
     }
     }
     return(0);
 }
예제 #8
0
        public static int computeSurfaceThickness(AddrTileMode tileMode)
        {
            switch (tileMode)
            {
            case AddrTileMode.ADDR_TM_1D_TILED_THICK:
            case AddrTileMode.ADDR_TM_2D_TILED_THICK:
            case AddrTileMode.ADDR_TM_2B_TILED_THICK:
            case AddrTileMode.ADDR_TM_3D_TILED_THICK:
            case AddrTileMode.ADDR_TM_3B_TILED_THICK:
            {
                return(4);
            }

            case AddrTileMode.ADDR_TM_2D_TILED_XTHICK:
            case AddrTileMode.ADDR_TM_3D_TILED_XTHICK:
            {
                return(8);
            }
            }

            return(1);
        }
예제 #9
0
        public static int ComputeSurfaceThickness(AddrTileMode tileMode)
        {
            switch (tileMode)
            {
            case AddrTileMode.AddrTm1DTiledThick:
            case AddrTileMode.AddrTm2DTiledThick:
            case AddrTileMode.AddrTm2BTiledThick:
            case AddrTileMode.AddrTm3DTiledThick:
            case AddrTileMode.AddrTm3BTiledThick:
            {
                return(4);
            }

            case AddrTileMode.AddrTm2DTiledXthick:
            case AddrTileMode.AddrTm3DTiledXthick:
            {
                return(8);
            }
            }

            return(1);
        }
예제 #10
0
        public static int surfaceAddrFromCoordMacroTiled(
            int x, int y, int slice, int sample, int bpp,
            int pitch, int height, int numSamples, AddrTileMode tileMode,
            int isDepth, int tileBase, int compBits,
            int pipeSwizzle, int bankSwizzle
            )
        {
            const int numPipes     = 2;
            const int numBanks     = 4;
            const int numGroupBits = 8;
            const int numPipeBits  = 1;
            const int numBankBits  = 2;

            int microTileThickness = computeSurfaceThickness(tileMode);
            int microTileBits      = numSamples * bpp * (microTileThickness * (8 * 8));
            int microTileBytes     = microTileBits >> 3;
            int microTileType      = (isDepth == 1) ? 1 : 0;
            int pixelIndex         = computePixelIndexWithinMicroTile(x, y, slice, bpp, tileMode, microTileType);

            int sampleOffset;
            int pixelOffset;

            if (isDepth == 1)
            {
                if (compBits != 0 && compBits != bpp)
                {
                    sampleOffset = tileBase + compBits * sample;
                    pixelOffset  = numSamples * compBits * pixelIndex;
                }
                else
                {
                    sampleOffset = bpp * sample;
                    pixelOffset  = numSamples * compBits * pixelIndex;
                }
            }
            else
            {
                sampleOffset = sample * (microTileBits / numSamples);
                pixelOffset  = bpp * pixelIndex;
            }

            int elemOffset     = pixelOffset + sampleOffset;
            int bytesPerSample = microTileBytes / numSamples;

            int samplesPerSlice;
            int numSampleSplits;
            int sampleSlice;

            if (numSamples <= 1 || microTileBytes <= 2048)
            {
                samplesPerSlice = numSamples;
                numSampleSplits = 1;
                sampleSlice     = 0;
            }
            else
            {
                samplesPerSlice = 2048 / bytesPerSample;
                numSampleSplits = numSamples / samplesPerSlice;
                numSamples      = samplesPerSlice;
                sampleSlice     = elemOffset / (microTileBits / numSampleSplits);
                elemOffset     %= microTileBits / numSampleSplits;
            }

            elemOffset >>= 3;

            int pipe     = computePipeFromCoordWoRotation(x, y);
            int bank     = computeBankFromCoordWoRotation(x, y);
            int bankPipe = pipe + numPipes * bank;
            int rotation = computeSurfaceRotationFromTileMode(tileMode);
            int swizzle  = pipeSwizzle + numPipes * bankSwizzle;
            int sliceIn  = slice;

            if (isThickMacroTiled(tileMode) == 1)
            {
                sliceIn >>= 2;
            }

            bankPipe ^= numPipes * sampleSlice * ((numBanks >> 1) + 1) ^ (swizzle + sliceIn * rotation);
            bankPipe %= numPipes * numBanks;
            pipe      = bankPipe % numPipes;
            bank      = bankPipe / numPipes;

            int sliceBytes      = (height * pitch * microTileThickness * bpp * numSamples + 7) / 8;
            int sliceOffset     = sliceBytes * ((sampleSlice + numSampleSplits * slice) / microTileThickness);
            int macroTilePitch  = 8 * 4; // m_banks
            int macroTileHeight = 8 * 2; // m_pipes
            int v18             = (int)tileMode - 5;

            if ((int)tileMode == 5 || (int)tileMode == 9)
            {
                macroTilePitch >>= 1;
                macroTileHeight *= 2;
            }
            else if ((int)tileMode == 6 || (int)tileMode == 10)
            {
                macroTilePitch >>= 2;
                macroTileHeight *= 4;
            }

            int macroTilesPerRow = pitch / macroTilePitch;
            int macroTileBytes   = (numSamples * microTileThickness * bpp * macroTileHeight * macroTilePitch + 7) >> 3;
            int macroTileIndexX  = x / macroTilePitch;
            int macroTileIndexY  = y / macroTileHeight;
            int macroTileOffset  = (x / macroTilePitch + pitch / macroTilePitch * (y / macroTileHeight)) * macroTileBytes;

            int bankSwapWidth;
            int swapIndex;
            int bankMask;

            byte[] bankSwapOrder = { 0, 1, 3, 2 };
            switch ((int)tileMode)
            {
            case 8:
            case 9:
            case 10:
            case 11:
            case 14:
            case 15:
            {
                bankSwapWidth = computeSurfaceBankSwappedWidth(tileMode, bpp, numSamples, pitch, 0);
                swapIndex     = macroTilePitch * macroTileIndexX / bankSwapWidth;
                bankMask      = 3; // m_banks-1
                bank         ^= bankSwapOrder[swapIndex & bankMask];
            }
            break;
            }

            int p4             = pipe << numGroupBits;
            int p5             = bank << (numPipeBits + numGroupBits);
            int numSwizzleBits = numBankBits + numPipeBits;
            int unk1           = (macroTileOffset + sliceOffset) >> numSwizzleBits;
            int unk2           = ~((1 << numGroupBits) - 1);
            int unk3           = (elemOffset + unk1) & unk2;
            int groupMask      = (1 << numGroupBits) - 1;
            int offset1        = macroTileOffset + sliceOffset;
            int unk4           = elemOffset + (offset1 >> numSwizzleBits);

            int subOffset1 = unk3 << numSwizzleBits;
            int subOffset2 = groupMask & unk4;

            return(subOffset1 | subOffset2 | p4 | p5);
        }
예제 #11
0
        public static int computePixelIndexWithinMicroTile(int x, int y, int z, int bpp, AddrTileMode tileMode, int microTileType)
        {
            int pixelBit0 = 0;
            int pixelBit1 = 0;
            int pixelBit2 = 0;
            int pixelBit3 = 0;
            int pixelBit4 = 0;
            int pixelBit5 = 0;
            int pixelBit6 = 0;
            int pixelBit7 = 0;
            int pixelBit8 = 0;
            int thickness = computeSurfaceThickness(tileMode);

            if (microTileType == 3)
            {
                pixelBit0 = x & 1;
                pixelBit1 = y & 1;
                pixelBit2 = z & 1;
                pixelBit3 = (x & 2) >> 1;
                pixelBit4 = (y & 2) >> 1;
                pixelBit5 = (z & 2) >> 1;
                pixelBit6 = (x & 4) >> 2;
                pixelBit7 = (y & 4) >> 2;
            }
            else
            {
                if (microTileType != 0)
                {
                    pixelBit0 = x & 1;
                    pixelBit1 = y & 1;
                    pixelBit2 = (x & 2) >> 1;
                    pixelBit3 = (y & 2) >> 1;
                    pixelBit4 = (x & 4) >> 2;
                    pixelBit5 = (y & 4) >> 2;
                }
                else
                {
                    if (bpp == 0x08)
                    {
                        pixelBit0 = x & 1;
                        pixelBit1 = (x & 2) >> 1;
                        pixelBit2 = (x & 4) >> 2;
                        pixelBit3 = (y & 2) >> 1;
                        pixelBit4 = y & 1;
                        pixelBit5 = (y & 4) >> 2;
                    }
                    else if (bpp == 0x10)
                    {
                        pixelBit0 = x & 1;
                        pixelBit1 = (x & 2) >> 1;
                        pixelBit2 = (x & 4) >> 2;
                        pixelBit3 = y & 1;
                        pixelBit4 = (y & 2) >> 1;
                        pixelBit5 = (y & 4) >> 2;
                    }
                    else if (bpp == 0x20 || bpp == 0x60)
                    {
                        pixelBit0 = x & 1;
                        pixelBit1 = (x & 2) >> 1;
                        pixelBit2 = y & 1;
                        pixelBit3 = (x & 4) >> 2;
                        pixelBit4 = (y & 2) >> 1;
                        pixelBit5 = (y & 4) >> 2;
                    }
                    else if (bpp == 0x40)
                    {
                        pixelBit0 = x & 1;
                        pixelBit1 = y & 1;
                        pixelBit2 = (x & 2) >> 1;
                        pixelBit3 = (x & 4) >> 2;
                        pixelBit4 = (y & 2) >> 1;
                        pixelBit5 = (y & 4) >> 2;
                    }
                    else if (bpp == 0x80)
                    {
                        pixelBit0 = y & 1;
                        pixelBit1 = x & 1;
                        pixelBit2 = (x & 2) >> 1;
                        pixelBit3 = (x & 4) >> 2;
                        pixelBit4 = (y & 2) >> 1;
                        pixelBit5 = (y & 4) >> 2;
                    }
                    else
                    {
                        pixelBit0 = x & 1;
                        pixelBit1 = (x & 2) >> 1;
                        pixelBit2 = y & 1;
                        pixelBit3 = (x & 4) >> 2;
                        pixelBit4 = (y & 2) >> 1;
                        pixelBit5 = (y & 4) >> 2;
                    }
                }

                if (thickness > 1)
                {
                    pixelBit6 = z & 1;
                    pixelBit7 = (z & 2) >> 1;
                }
            }

            if (thickness == 8)
            {
                pixelBit8 = (z & 4) >> 2;
            }

            return(pixelBit0 |
                   (pixelBit8 << 8) |
                   (pixelBit7 << 7) |
                   (pixelBit6 << 6) |
                   (pixelBit5 << 5) |
                   (pixelBit4 << 4) |
                   (pixelBit3 << 3) |
                   (pixelBit2 << 2) |
                   (pixelBit1 << 1));
        }
예제 #12
0
        public static int computeSurfaceBankSwappedWidth(AddrTileMode tileMode, int bpp, int numSamples, int pitch, int pSlicesPerTile)
        {
            int bankSwapWidth  = 0;
            int numBanks       = 4;
            int numPipes       = 2;
            int swapSize       = 256;
            int rowSize        = 2048;
            int splitSize      = 2048;
            int groupSize      = 256;
            int slicesPerTile  = 1;
            int bytesPerSample = 8 * bpp & 0x1FFFFFFF;
            int samplesPerTile = splitSize / bytesPerSample;

            if ((splitSize / bytesPerSample) != 0)
            {
                slicesPerTile = numSamples / samplesPerTile;
                if ((numSamples / samplesPerTile) == 0)
                {
                    slicesPerTile = 1;
                }
            }

            if (pSlicesPerTile != 0)
            {
                pSlicesPerTile = slicesPerTile;
            }

            if (isThickMacroTiled(tileMode) == 1)
            {
                numSamples = 4;
            }

            int bytesPerTileSlice = numSamples * bytesPerSample / slicesPerTile;

            if (isBankSwappedTileMode(tileMode) == 1)
            {
                int v7;
                int v8;
                int v9;

                int factor    = computeMacroTileAspectRatio(tileMode);
                int swapTiles = (swapSize >> 1) / bpp;

                if (swapTiles != 0)
                {
                    v9 = swapTiles;
                }
                else
                {
                    v9 = 1;
                }

                int swapWidth   = v9 * 8 * numBanks;
                int heightBytes = numSamples * factor * numPipes * bpp / slicesPerTile;
                int swapMax     = numPipes * numBanks * rowSize / heightBytes;
                int swapMin     = groupSize * 8 * numBanks / bytesPerTileSlice;

                if (swapMax >= swapWidth)
                {
                    if (swapMin <= swapWidth)
                    {
                        v7 = swapWidth;
                    }
                    else
                    {
                        v7 = swapMin;
                    }

                    v8 = v7;
                }
                else
                {
                    v8 = swapMax;
                }

                bankSwapWidth = v8;

                while (bankSwapWidth >= (2 * pitch))
                {
                    bankSwapWidth >>= 1;
                }
            }

            return(bankSwapWidth);
        }