public void LoadTexture(int target = 1) { mipmaps.Clear(); uint blk_dim = blk_dims(Format); uint blkWidth = blk_dim >> 4; uint blkHeight = blk_dim & 0xF; uint blockHeight = TegraX1Swizzle.GetBlockHeight(TegraX1Swizzle.DIV_ROUND_UP(Height, blkHeight)); uint BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length - 1; uint tileMode = 0; int linesPerBlockHeight = (1 << (int)BlockHeightLog2) * 8; uint bpp = bpps(Format); for (int arrayLevel = 0; arrayLevel < blocksCompressed.Count; arrayLevel++) { int blockHeightShift = 0; List <byte[]> mips = new List <byte[]>(); for (int mipLevel = 0; mipLevel < blocksCompressed[arrayLevel].Count; mipLevel++) { uint width = (uint)Math.Max(1, Width >> mipLevel); uint height = (uint)Math.Max(1, Height >> mipLevel); uint size = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp; if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight) { blockHeightShift += 1; } Console.WriteLine($"{blk_dim.ToString("x")} {bpp} {width} {height} {linesPerBlockHeight} {blkWidth} {blkHeight} {size} { blocksCompressed[arrayLevel][mipLevel].Length}"); try { byte[] result = TegraX1Swizzle.deswizzle(width, height, blkWidth, blkHeight, target, bpp, tileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), blocksCompressed[arrayLevel][mipLevel]); //Create a copy and use that to remove uneeded data byte[] result_ = new byte[size]; Array.Copy(result, 0, result_, 0, size); mips.Add(result_); } catch (Exception e) { System.Windows.Forms.MessageBox.Show("Failed to swizzle texture!"); Console.WriteLine(e); BadSwizzle = true; break; } } mipmaps.Add(mips); } }
public void LoadTexture() { mipmaps.Clear(); Console.WriteLine(Format); uint blk_dim = XTXFormats.blk_dims((uint)((int)Format >> 8)); uint blkWidth = blk_dim >> 4; uint blkHeight = blk_dim & 0xF; uint blockHeight = TegraX1Swizzle.GetBlockHeight(TegraX1Swizzle.DIV_ROUND_UP(Height, blkHeight)); uint BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length - 1; int linesPerBlockHeight = (1 << (int)BlockHeightLog2) * 8; int TileMode = 0; uint bpp = XTXFormats.bpps((uint)Format); int blockHeightShift = 0; for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) { uint width = (uint)Math.Max(1, Width >> mipLevel); uint height = (uint)Math.Max(1, Height >> mipLevel); // uint size = width * height * bpp; uint size = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp; byte[] mipData = GetMipBlock(MipOffsets[mipLevel], size); if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight) { blockHeightShift += 1; } byte[] result = TegraX1Swizzle.deswizzle(width, height, blkWidth, blkHeight, (int)Target, bpp, (uint)TileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), mipData); //Create a copy and use that to remove uneeded data byte[] result_ = new byte[size]; Array.Copy(result, 0, result_, 0, size); mipmaps.Add(result_); Console.WriteLine("bpp " + bpp); Console.WriteLine("result_ " + size); Console.WriteLine("width " + width); Console.WriteLine("height " + height); } }
public static List <byte[]> SwizzleSurfaceMipMaps(Texture tex, byte[] data, TileMode TileMode) { int blockHeightShift = 0; int target = 1; uint Pitch = 0; uint SurfaceSize = 0; uint blockHeight = 0; uint blk_dim = Formats.blk_dims((uint)((int)tex.Format >> 8)); uint blkWidth = blk_dim >> 4; uint blkHeight = blk_dim & 0xF; uint linesPerBlockHeight = 0; uint bpp = Formats.bpps((uint)((int)tex.Format >> 8)); if ((int)TileMode == 1) { blockHeight = 1; tex.BlockHeightLog2 = 0; tex.Alignment = 1; linesPerBlockHeight = 1; tex.ReadTextureLayout = 0; } else { blockHeight = TegraX1Swizzle.GetBlockHeight(DIV_ROUND_UP(tex.Height, blkHeight)); tex.BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length - 1; Console.WriteLine("BlockHeightLog2 " + tex.BlockHeightLog2); Console.WriteLine("blockHeight " + blockHeight); tex.Alignment = 512; tex.ReadTextureLayout = 1; linesPerBlockHeight = blockHeight * 8; } List <byte[]> mipmaps = new List <byte[]>(); for (int mipLevel = 0; mipLevel < tex.MipCount; mipLevel++) { var result = GetCurrentMipSize(tex.Width, tex.Height, blkWidth, blkHeight, bpp, mipLevel); uint offset = result.Item1; uint size = result.Item2; byte[] data_ = SubArray(data, offset, size); uint width_ = Math.Max(1, tex.Width >> mipLevel); uint height_ = Math.Max(1, tex.Height >> mipLevel); uint width__ = DIV_ROUND_UP(width_, blkWidth); uint height__ = DIV_ROUND_UP(height_, blkHeight); byte[] AlignedData = new byte[(TegraX1Swizzle.round_up(SurfaceSize, (uint)tex.Alignment) - SurfaceSize)]; SurfaceSize += (uint)AlignedData.Length; Console.WriteLine("SurfaceSize Aligned " + AlignedData); Console.WriteLine("MipOffsets " + SurfaceSize); tex.MipOffsets[mipLevel] = SurfaceSize; if (tex.TileMode == TileMode.LinearAligned) { Pitch = width__ * bpp; Console.WriteLine("Pitch 1 " + Pitch); if (target == 1) { Pitch = TegraX1Swizzle.round_up(width__ * bpp, 32); Console.WriteLine("Pitch 2 " + Pitch); } SurfaceSize += Pitch * height__; } else { if (TegraX1Swizzle.pow2_round_up(height__) < linesPerBlockHeight) { blockHeightShift += 1; } Pitch = TegraX1Swizzle.round_up(width__ * bpp, 64); Console.WriteLine("Pitch 1 " + Pitch); Console.WriteLine("blockHeightShift " + blockHeightShift); SurfaceSize += Pitch * TegraX1Swizzle.round_up(height__, Math.Max(1, blockHeight >> blockHeightShift) * 8); Console.WriteLine("SurfaceSize " + SurfaceSize); byte[] SwizzledData = TegraX1Swizzle.swizzle(width_, height_, blkWidth, blkHeight, target, bpp, (uint)tex.TileMode, (int)Math.Max(0, tex.BlockHeightLog2 - blockHeightShift), data_); mipmaps.Add(AlignedData.Concat(SwizzledData).ToArray()); } } tex.ImageSize = SurfaceSize; return(mipmaps); }
public void LoadTexture(int target = 1) { Surfaces.Clear(); uint blk_dim = blk_dims((byte)Format); uint blkWidth = blk_dim >> 4; uint blkHeight = blk_dim & 0xF; uint blockHeight = TegraX1Swizzle.GetBlockHeight(TegraX1Swizzle.DIV_ROUND_UP(Height, blkHeight)); uint BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length - 1; uint tileMode = 0; int linesPerBlockHeight = (1 << (int)BlockHeightLog2) * 8; uint bpp = bpps((byte)Format); for (int arrayLevel = 0; arrayLevel < mipSizes.Count; arrayLevel++) { int blockHeightShift = 0; uint mipOffset = 0; List <byte[]> mips = new List <byte[]>(); for (int mipLevel = 0; mipLevel < mipSizes[arrayLevel].Length; mipLevel++) { //Get the size from the size array int MipSize = (int)mipSizes[arrayLevel][mipLevel]; //Align the size if (mipLevel == 0) { if (MipSize % Alignment != 0) { MipSize = MipSize + (Alignment - (MipSize % Alignment)); } } uint width = (uint)Math.Max(1, Width >> mipLevel); uint height = (uint)Math.Max(1, Height >> mipLevel); uint size = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp; if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight) { blockHeightShift += 1; } Console.WriteLine($"{blk_dim.ToString("x")} {bpp} {width} {height} {linesPerBlockHeight} {blkWidth} {blkHeight} {size} { ImageData.Length}"); try { byte[] result = TegraX1Swizzle.deswizzle(width, height, blkWidth, blkHeight, target, bpp, tileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), ImageData); //Create a copy and use that to remove uneeded data byte[] result_ = new byte[size]; Array.Copy(result, mipOffset, result_, 0, size); mips.Add(result_); } catch (Exception e) { System.Windows.Forms.MessageBox.Show($"Failed to swizzle texture {Text}!"); Console.WriteLine(e); BadSwizzle = true; break; } mipOffset += (uint)MipSize; break; } Surfaces.Add(new Surface() { mipmaps = mips }); } }
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0) { if (!IsSwizzled) { return(ImageData); } int target = 1; uint bpp = GetBytesPerPixel(Format); uint blkWidth = GetBlockWidth(Format); uint blkHeight = GetBlockHeight(Format); uint blkDepth = GetBlockDepth(Format); uint blockHeight = TegraX1Swizzle.GetBlockHeight(TegraX1Swizzle.DIV_ROUND_UP(Height, blkHeight)); uint BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length - 1; uint Pitch = 0; uint DataAlignment = 512; uint TileMode = 0; int linesPerBlockHeight = (1 << (int)BlockHeightLog2) * 8; uint ArrayCount = (uint)mipSizes.Count; uint ArrayOffset = 0; for (int arrayLevel = 0; arrayLevel < ArrayCount; arrayLevel++) { uint SurfaceSize = 0; int blockHeightShift = 0; List <uint> MipOffsets = new List <uint>(); for (int mipLevel = 0; mipLevel < mipSizes[arrayLevel].Length; mipLevel++) { uint width = (uint)Math.Max(1, Width >> mipLevel); uint height = (uint)Math.Max(1, Height >> mipLevel); uint depth = (uint)Math.Max(1, Depth >> mipLevel); uint size = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp; if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight) { blockHeightShift += 1; } uint width__ = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth); uint height__ = TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight); //Calculate the mip size instead byte[] AlignedData = new byte[(TegraX1Swizzle.round_up(SurfaceSize, DataAlignment) - SurfaceSize)]; SurfaceSize += (uint)AlignedData.Length; MipOffsets.Add(SurfaceSize); //Get the first mip offset and current one and the total image size int msize = (int)((MipOffsets[0] + ImageData.Length - MipOffsets[mipLevel]) / ArrayCount); byte[] data_ = Utils.SubArray(ImageData, ArrayOffset + MipOffsets[mipLevel], (uint)msize); try { Pitch = TegraX1Swizzle.round_up(width__ * bpp, 64); SurfaceSize += Pitch * TegraX1Swizzle.round_up(height__, Math.Max(1, blockHeight >> blockHeightShift) * 8); Console.WriteLine($"{width} {height} {blkWidth} {blkHeight} {target} {bpp} {TileMode} {(int)Math.Max(0, BlockHeightLog2 - blockHeightShift)} {data_.Length}"); byte[] result = TegraX1Swizzle.deswizzle(width, height, depth, blkWidth, blkHeight, blkDepth, target, bpp, TileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), data_); //Create a copy and use that to remove uneeded data byte[] result_ = new byte[size]; Array.Copy(result, 0, result_, 0, size); result = null; if (ArrayLevel == arrayLevel && MipLevel == mipLevel) { return(result_); } } catch (Exception e) { System.Windows.Forms.MessageBox.Show($"Failed to swizzle texture {Text}!"); Console.WriteLine(e); return(new byte[0]); } } ArrayOffset += (uint)(ImageData.Length / ArrayCount); } return(new byte[0]); }
private List <uint[]> GenerateMipSizes(uint SurfaceCount = 1) { List <uint[]> MipMapSizes = new List <uint[]>(); uint bpp = GetBytesPerPixel(Format); uint blkWidth = GetBlockWidth(Format); uint blkHeight = GetBlockHeight(Format); uint blkDepth = GetBlockDepth(Format); uint blockHeight = TegraX1Swizzle.GetBlockHeight(TegraX1Swizzle.DIV_ROUND_UP(Height, blkHeight)); uint BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length - 1; uint Pitch = 0; uint DataAlignment = 512; int linesPerBlockHeight = (1 << (int)BlockHeightLog2) * 8; uint ArrayCount = (uint)mipSizes.Count; uint ArrayOffset = 0; for (int arrayLevel = 0; arrayLevel < ArrayCount; arrayLevel++) { uint SurfaceSize = 0; int blockHeightShift = 0; uint[] MipOffsets = new uint[MipCount]; for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) { uint width = (uint)Math.Max(1, Width >> mipLevel); uint height = (uint)Math.Max(1, Height >> mipLevel); uint depth = (uint)Math.Max(1, Depth >> mipLevel); uint size = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp; if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight) { blockHeightShift += 1; } uint width__ = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth); uint height__ = TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight); //Calculate the mip size instead byte[] AlignedData = new byte[(TegraX1Swizzle.round_up(SurfaceSize, DataAlignment) - SurfaceSize)]; SurfaceSize += (uint)AlignedData.Length; MipOffsets[mipLevel] = (SurfaceSize); //Get the first mip offset and current one and the total image size int msize = (int)((MipOffsets[0] + ImageData.Length - MipOffsets[mipLevel]) / ArrayCount); Pitch = TegraX1Swizzle.round_up(width__ * bpp, 64); SurfaceSize += Pitch * TegraX1Swizzle.round_up(height__, Math.Max(1, blockHeight >> blockHeightShift) * 8); } ArrayOffset += (uint)(ImageData.Length / ArrayCount); MipMapSizes.Add(MipOffsets); } return(MipMapSizes); }
public void LoadTexture() { Surfaces.Clear(); Console.WriteLine(Format); uint blk_dim = XTXFormats.blk_dims((uint)((int)Format >> 8)); uint blkWidth = blk_dim >> 4; uint blkHeight = blk_dim & 0xF; uint blockHeight = TegraX1Swizzle.GetBlockHeight(TegraX1Swizzle.DIV_ROUND_UP(Height, blkHeight)); uint BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length - 1; int linesPerBlockHeight = (1 << (int)BlockHeightLog2) * 8; int TileMode = 0; uint bpp = XTXFormats.bpps((uint)Format); List <byte[]> mips = new List <byte[]>(); int blockHeightShift = 0; for (int mipLevel = 0; mipLevel < MipOffsets.Length; mipLevel++) { uint width = (uint)Math.Max(1, Width >> mipLevel); uint height = (uint)Math.Max(1, Height >> mipLevel); // uint size = width * height * bpp; uint size = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp; byte[] Output = new byte[size]; uint mipOffset; if (mipLevel != 0) { mipOffset = (MipOffsets[mipLevel - 1]); if (mipLevel == 1) { mipOffset -= (uint)size; } Array.Copy(ImageData, mipOffset, Output, 0, size); } else { Output = ImageData; } byte[] output = new byte[size]; Console.WriteLine(mipLevel + " " + size); if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight) { blockHeightShift += 1; } byte[] result = TegraX1Swizzle.deswizzle(width, height, blkWidth, blkHeight, (int)Target, bpp, (uint)TileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), Output); //Create a copy and use that to remove uneeded data byte[] result_ = new byte[size]; Array.Copy(result, 0, result_, 0, size); mips.Add(result_); } Surfaces.Add(new Surface() { mipmaps = mips }); }
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0) { uint bpp = GetBytesPerPixel(Format); uint blkWidth = GetBlockHeight(Format); uint blkHeight = GetBlockWidth(Format); uint blkDepth = GetBlockDepth(Format); uint blockHeight = TegraX1Swizzle.GetBlockHeight(TegraX1Swizzle.DIV_ROUND_UP(Height, blkHeight)); uint BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length - 1; int linesPerBlockHeight = (1 << (int)BlockHeightLog2) * 8; int TileMode = 0; List <byte[]> mips = new List <byte[]>(); int blockHeightShift = 0; for (int mipLevel = 0; mipLevel < MipOffsets.Length; mipLevel++) { uint width = (uint)Math.Max(1, Width >> mipLevel); uint height = (uint)Math.Max(1, Height >> mipLevel); uint depth = (uint)Math.Max(1, Depth >> mipLevel); // uint size = width * height * bpp; uint size = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp; byte[] Output = new byte[size]; uint mipOffset; if (mipLevel != 0) { mipOffset = (MipOffsets[mipLevel - 1]); if (mipLevel == 1) { mipOffset -= (uint)size; } Array.Copy(ImageData, mipOffset, Output, 0, size); } else { Output = ImageData; } byte[] output = new byte[size]; Console.WriteLine(mipLevel + " " + size); if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight) { blockHeightShift += 1; } byte[] result = TegraX1Swizzle.deswizzle(width, height, depth, blkWidth, blkHeight, blkDepth, (int)Target, bpp, (uint)TileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), Output); //Create a copy and use that to remove uneeded data byte[] result_ = new byte[size]; Array.Copy(result, 0, result_, 0, size); result = null; if (MipLevel == mipLevel) { return(result_); } Console.WriteLine("bpp " + bpp); Console.WriteLine("result_ " + size); Console.WriteLine("width " + width); Console.WriteLine("height " + height); break; } return(new byte[0]); }