1
0
mirror of synced 2025-02-26 22:59:24 +01:00

Update tiling for gx2 swizzling

This commit is contained in:
KillzXGaming 2019-04-06 10:22:02 -04:00
parent 7680baa375
commit 5837fbe5d6
7 changed files with 121 additions and 78 deletions

Binary file not shown.

View File

@ -496,8 +496,13 @@ namespace Switch_Toolbox.Library
int dataOffset = 0; int dataOffset = 0;
int mipDataOffset = 0; int mipDataOffset = 0;
int TotalImageSize = tex.data.Length; int TotalImageSize = tex.data.Length;
int _swizzle = (int)tex.swizzle << 8;
uint CurrentTileMode = tex.tileMode; if (tex.tileMode == 0)
tex.tileMode = getDefaultGX2TileMode(1, tex.width, tex.height, 1, tex.format, 0, 1);
int tiling1dLevel = 0;
bool tiling1dLevelSet = false;
List<List<byte[]>> result = new List<List<byte[]>>(); List<List<byte[]>> result = new List<List<byte[]>>();
for (int arrayLevel = 0; arrayLevel < tex.numArray; arrayLevel++) for (int arrayLevel = 0; arrayLevel < tex.numArray; arrayLevel++)
@ -505,9 +510,6 @@ namespace Switch_Toolbox.Library
List<byte[]> mips = new List<byte[]>(); List<byte[]> mips = new List<byte[]>();
for (int mipLevel = 0; mipLevel < mipCount; mipLevel++) for (int mipLevel = 0; mipLevel < mipCount; mipLevel++)
{ {
//Reset the tilemode if set from higher mip levels
tex.tileMode = CurrentTileMode;
uint width_ = (uint)Math.Max(1, tex.width >> mipLevel); uint width_ = (uint)Math.Max(1, tex.width >> mipLevel);
uint height_ = (uint)Math.Max(1, tex.height >> mipLevel); uint height_ = (uint)Math.Max(1, tex.height >> mipLevel);
@ -516,23 +518,6 @@ namespace Switch_Toolbox.Library
uint mipOffset; uint mipOffset;
if (mipLevel != 0) if (mipLevel != 0)
{ {
if (mipLevel >= 8)
{
switch (tex.tileMode)
{
case (uint)GTX.GX2TileMode.MODE_1D_TILED_THICK:
case (uint)GTX.GX2TileMode.MODE_2B_TILED_THICK:
case (uint)GTX.GX2TileMode.MODE_2D_TILED_THICK:
case (uint)GTX.GX2TileMode.MODE_3B_TILED_THICK:
case (uint)GTX.GX2TileMode.MODE_3D_TILED_THICK:
tex.tileMode = (uint)GTX.GX2TileMode.MODE_1D_TILED_THICK;
break;
default:
tex.tileMode = (uint)GTX.GX2TileMode.MODE_1D_TILED_THIN1;
break;
}
}
mipOffset = (tex.mipOffset[mipLevel - 1]); mipOffset = (tex.mipOffset[mipLevel - 1]);
if (mipLevel == 1) if (mipLevel == 1)
mipOffset -= (uint)surfInfo.surfSize; mipOffset -= (uint)surfInfo.surfSize;
@ -555,11 +540,28 @@ namespace Switch_Toolbox.Library
result.Add(mips); result.Add(mips);
if (surfInfo.tileMode == 1 || surfInfo.tileMode == 2 ||
surfInfo.tileMode == 3 || surfInfo.tileMode == 16)
{
tiling1dLevelSet = true;
}
if (tiling1dLevelSet == false)
{
tiling1dLevel += 1;
}
dataOffset += ArrayImageize; dataOffset += ArrayImageize;
mipDataOffset += ArrayMipImageize; mipDataOffset += ArrayMipImageize;
break; break;
} }
if (tiling1dLevelSet)
_swizzle |= tiling1dLevel << 16;
else
_swizzle |= 13 << 16;
return result; return result;
} }
private static byte[] SubArray(byte[] data, int offset, int length) private static byte[] SubArray(byte[] data, int offset, int length)
@ -571,6 +573,10 @@ namespace Switch_Toolbox.Library
return (n + d - 1) / d; return (n + d - 1) / d;
} }
private static uint powTwoAlign_0(uint x, uint align) {
return (x + align - 1) & ~(align - 1);
}
/*--------------------------------------- /*---------------------------------------
* *
@ -626,6 +632,8 @@ namespace Switch_Toolbox.Library
pipeSwizzle = (swizzle_ >> 8) & 1; pipeSwizzle = (swizzle_ >> 8) & 1;
bankSwizzle = (swizzle_ >> 9) & 3; bankSwizzle = (swizzle_ >> 9) & 3;
tileMode = GX2TileModeToAddrTileMode(tileMode);
for (int y = 0; y < height; y++) for (int y = 0; y < height; y++)
{ {
for (int x = 0; x < width; x++) for (int x = 0; x < width; x++)
@ -719,6 +727,39 @@ namespace Switch_Toolbox.Library
return newDim; return newDim;
} }
private static uint getDefaultGX2TileMode(uint dim, uint width, uint height, uint depth, uint format_, uint aa, uint use)
{
uint tileMode = 1;
bool IsDepthBuffer = (use & 4) != 0;
bool isColorBuffer = (use & 2) != 0;
if (dim != 0 || aa != 0 || IsDepthBuffer)
{
if (dim != 2 || isColorBuffer)
tileMode = 4;
else
tileMode = 7;
var surfOut = getSurfaceInfo((GX2SurfaceFormat)format_, width, height, depth, dim, tileMode, aa, 0);
if (width < surfOut.pitchAlign && height<surfOut.heightAlign)
{
if (tileMode == 7)
tileMode = 3;
else
tileMode = 2;
}
}
return tileMode;
}
private static uint GX2TileModeToAddrTileMode(uint tileMode)
{
if (tileMode == 16)
return 0;
return tileMode;
}
private static uint computeSurfaceThickness(AddrTileMode tileMode) private static uint computeSurfaceThickness(AddrTileMode tileMode)
{ {
switch (tileMode) switch (tileMode)
@ -999,14 +1040,13 @@ namespace Switch_Toolbox.Library
if (DebugSurface) if (DebugSurface)
Console.WriteLine("baseTileMode " + baseTileMode); Console.WriteLine("baseTileMode " + baseTileMode);
if (baseTileMode == 7)
{
if (numSamples > 1 || tileSlices > 1 || isDepth != 0) if (numSamples > 1 || tileSlices > 1 || isDepth != 0)
{
if (baseTileMode == 7)
expTileMode = 4; expTileMode = 4;
} }
else if (baseTileMode == 13) else if (baseTileMode == 13)
{ {
if (numSamples > 1 || tileSlices > 1 || isDepth != 0)
expTileMode = 12; expTileMode = 12;
} }
else if (baseTileMode == 11) else if (baseTileMode == 11)
@ -1019,9 +1059,8 @@ namespace Switch_Toolbox.Library
if (numSamples > 1 || tileSlices > 1 || isDepth != 0) if (numSamples > 1 || tileSlices > 1 || isDepth != 0)
expTileMode = 14; expTileMode = 14;
} }
else if (baseTileMode == 2) if (baseTileMode == 2 && numSamples > 1)
{ {
if (numSamples > 1 && ((4 >> 2) & 1) != 0)
expTileMode = 4; expTileMode = 4;
} }
else if (baseTileMode == 3) else if (baseTileMode == 3)
@ -1104,9 +1143,9 @@ namespace Switch_Toolbox.Library
if ((widtha < widthAlignFactor * macroTileWidth) || heighta < macroTileHeight) if ((widtha < widthAlignFactor * macroTileWidth) || heighta < macroTileHeight)
expTileMode = 3; expTileMode = 3;
} }
else if (expTileMode == 3)
{
if (numSlicesa < 4) if (numSlicesa < 4)
{
if (expTileMode == 3)
expTileMode = 2; expTileMode = 2;
} }
else if (expTileMode == 7) else if (expTileMode == 7)
@ -1114,9 +1153,9 @@ namespace Switch_Toolbox.Library
if (numSlicesa < 4) if (numSlicesa < 4)
expTileMode = 4; expTileMode = 4;
} }
else if (expTileMode == 13 && numSlicesa < 4) else if (expTileMode == 13)
{ {
expTileMode = 13; expTileMode = 12;
} }
return computeSurfaceMipLevelTileMode( return computeSurfaceMipLevelTileMode(
@ -1438,9 +1477,13 @@ namespace Switch_Toolbox.Library
uint pixelsPerPipeInterleave; uint pixelsPerPipeInterleave;
uint baseAlign, pitchAlign, heightAlign; uint baseAlign, pitchAlign, heightAlign;
if (tileMode != 0) if (tileMode == 0)
{ {
if (tileMode == 1) baseAlign = 1;
pitchAlign = (bpp != 1 ? (uint)1 : 8);
heightAlign = 1;
}
else if (tileMode == 1)
{ {
pixelsPerPipeInterleave = 2048 / bpp; pixelsPerPipeInterleave = 2048 / bpp;
baseAlign = 256; baseAlign = 256;
@ -1453,17 +1496,6 @@ namespace Switch_Toolbox.Library
pitchAlign = 1; pitchAlign = 1;
heightAlign = 1; heightAlign = 1;
} }
}
else
{
baseAlign = 1;
if (bpp != 1)
pitchAlign = 1;
else
pitchAlign = 8;
heightAlign = 1;
}
pitchAlign = adjustPitchAlignment(flags, pitchAlign); pitchAlign = adjustPitchAlignment(flags, pitchAlign);
return new Tuple<uint, uint, uint>(baseAlign, pitchAlign, heightAlign); return new Tuple<uint, uint, uint>(baseAlign, pitchAlign, heightAlign);
@ -1614,7 +1646,7 @@ namespace Switch_Toolbox.Library
if (sliceFlags == 1) if (sliceFlags == 1)
pOut.sliceSize = (pOut.height * pOut.pitch * pOut.bpp * pIn.numSamples + 7) / 8; pOut.sliceSize = (pOut.height * pOut.pitch * pOut.bpp * pIn.numSamples + 7) / 8;
else if (((pIn.flags.value >> 5) & 1) != 0) if (((pIn.flags.value >> 5) & 1) != 0)
pOut.sliceSize = (uint)pOut.surfSize; pOut.sliceSize = (uint)pOut.surfSize;
else else
@ -1736,7 +1768,7 @@ namespace Switch_Toolbox.Library
if (padDims > 2 || thickness > 1) if (padDims > 2 || thickness > 1)
{ {
if (isCube != 0) if (isCube != 0 || cubeAsArray != 0)
expNumSlices = nextPow2(expNumSlices); expNumSlices = nextPow2(expNumSlices);
if (thickness > 1) if (thickness > 1)
@ -1989,7 +2021,7 @@ namespace Switch_Toolbox.Library
private static uint adjustPitchAlignment(Flags flags, uint pitchAlign) private static uint adjustPitchAlignment(Flags flags, uint pitchAlign)
{ {
if (((flags.value >> 13) & 1) != 0) if (((flags.value >> 13) & 1) != 0)
pitchAlign = powTwoAlign(pitchAlign, 0x20); pitchAlign = powTwoAlign_0(pitchAlign, 0x20);
return pitchAlign; return pitchAlign;
} }
@ -2223,6 +2255,17 @@ namespace Switch_Toolbox.Library
return ~(align - 1) & (x + align - 1); return ~(align - 1) & (x + align - 1);
} }
/// <summary>
/// Gets the surface info of a GX2 texture
/// </summary>
/// <param name="surfaceFormat">The <see cref="GX2SurfaceFormat"/> of the surface.</param>
/// <param name="surfaceWidth">The width of the surface.</param>
/// <param name="surfaceHeight">The height of the surface.</param>
/// <param name="surfaceDepth">The depth of the surface.</param>
/// <param name="surfaceDim">The <see cref="GX2SurfaceDim"/ of the surface.</param>
/// <param name="surfaceTileMode">The <see cref="GX2TileMode"/ of the surface.</param>
/// <param name="surfaceAA">The <see cref="GX2AAMode"/ of the surface.</param>
/// <param name="level">The mip level of which the info will be calculated for (first mipmap corresponds to value 1</param>
public static surfaceOut getSurfaceInfo(GX2SurfaceFormat surfaceFormat, uint surfaceWidth, uint surfaceHeight, uint surfaceDepth, uint surfaceDim, uint surfaceTileMode, uint surfaceAA, int level) public static surfaceOut getSurfaceInfo(GX2SurfaceFormat surfaceFormat, uint surfaceWidth, uint surfaceHeight, uint surfaceDepth, uint surfaceDim, uint surfaceTileMode, uint surfaceAA, int level)
{ {
GX2Surface surface = new GX2Surface(); GX2Surface surface = new GX2Surface();