mirror of
https://github.com/KillzXGaming/Switch-Toolbox
synced 2024-11-21 20:13:06 +00:00
update tegra_swizzle to 0.3.1 (#614)
This commit is contained in:
parent
6826fa01cf
commit
ff40338bc0
5 changed files with 175 additions and 109 deletions
|
@ -212,13 +212,13 @@ namespace FirstPlugin
|
|||
Width = tex.Texture.Width;
|
||||
Height = tex.Texture.Height;
|
||||
MipCount = tex.Texture.MipCount;
|
||||
// ArrayCount = tex.Texture.ArrayLength;
|
||||
// Depth = tex.Texture.Depth;
|
||||
ArrayCount = tex.Texture.ArrayLength;
|
||||
Depth = tex.Texture.Depth;
|
||||
|
||||
Format = tex.Format;
|
||||
NutFormat = ConvertGenericToNutFormat(tex.Format);
|
||||
|
||||
mipSizes = TegraX1Swizzle.GenerateMipSizes(tex.Format, tex.Width, tex.Height, tex.Depth, tex.ArrayCount, tex.MipCount, (uint)ImageData.Length);
|
||||
mipSizes = TegraX1Swizzle.GenerateMipSizes(tex.Format, tex.Width, tex.Height, tex.Depth, tex.ArrayCount, tex.MipCount);
|
||||
|
||||
ImageData = SetImageData(output);
|
||||
|
||||
|
@ -422,19 +422,19 @@ namespace FirstPlugin
|
|||
TextureName = Text;
|
||||
Console.WriteLine($"Text {Text}");
|
||||
|
||||
//MipSizes stores mip sizes for multile arrays
|
||||
// MipSizes stores mip sizes for multiple arrays
|
||||
int arrayCount = mipSizes.Count;
|
||||
|
||||
//Mip sizes for the first array
|
||||
// Mip sizes for the first array
|
||||
int mipCount = mipSizes[0].Length;
|
||||
|
||||
writer.Write(ImageData); //Write textue block first
|
||||
writer.Write(ImageData); //Write texture block first
|
||||
|
||||
long headerStart = writer.Position;
|
||||
foreach (var mips in mipSizes)
|
||||
{
|
||||
long MipStart = writer.Position;
|
||||
writer.Write(mips); //Write textue block first
|
||||
writer.Write(mips); //Write texture block first
|
||||
|
||||
writer.Seek(MipStart + 0x40, System.IO.SeekOrigin.Begin);
|
||||
}
|
||||
|
@ -482,7 +482,7 @@ namespace FirstPlugin
|
|||
tex.TextureData = new List<List<byte[]>>();
|
||||
|
||||
STChannelType[] channels = SetChannelsByFormat(Format);
|
||||
tex.sparseBinding = 0; //false
|
||||
tex.sparseBinding = 0; //false
|
||||
tex.sparseResidency = 0; //false
|
||||
tex.Flags = 0;
|
||||
tex.Swizzle = 0;
|
||||
|
@ -513,6 +513,7 @@ namespace FirstPlugin
|
|||
|
||||
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
|
||||
{
|
||||
// TODO: Rename this to Swizzled?
|
||||
if (Alignment == 0)
|
||||
return DDS.GetArrayFaces(this, ImageData, ArrayCount)[ArrayLevel].mipmaps[MipLevel];
|
||||
|
||||
|
@ -536,23 +537,25 @@ namespace FirstPlugin
|
|||
public override ToolStripItem[] GetContextMenuItems()
|
||||
{
|
||||
List<ToolStripItem> Items = new List<ToolStripItem>();
|
||||
Items.Add(new STToolStipMenuItem("Use Size Restrictions", null, UseSizeRestrictionsAction, Keys.Control | Keys.U)
|
||||
Items.Add(new STToolStipMenuItem("Use Size Restrictions", null, UseSizeRestrictionsAction, Keys.Control | Keys.U)
|
||||
{ Checked = Runtime.NUTEXBSettings.LimitFileSize, CheckOnClick = true });
|
||||
|
||||
Items.Add(new STToolStipMenuItem("Save", null, SaveAction, Keys.Control | Keys.T));
|
||||
|
||||
Items.Add(new STToolStipMenuItem("Force padding for smaller file sizes", null, PaddingToggle, Keys.Control | Keys.P)
|
||||
Items.Add(new STToolStipMenuItem("Force padding for smaller file sizes", null, PaddingToggle, Keys.Control | Keys.P)
|
||||
{ Checked = Runtime.NUTEXBSettings.PadFileSize, CheckOnClick = true });
|
||||
|
||||
Items.AddRange(base.GetContextMenuItems());
|
||||
return Items.ToArray();
|
||||
}
|
||||
|
||||
private void PaddingToggle(object sender, EventArgs args) {
|
||||
private void PaddingToggle(object sender, EventArgs args)
|
||||
{
|
||||
Runtime.NUTEXBSettings.PadFileSize = ((STToolStipMenuItem)sender).Checked ? true : false;
|
||||
}
|
||||
|
||||
private void UseSizeRestrictionsAction(object sender, EventArgs args) {
|
||||
private void UseSizeRestrictionsAction(object sender, EventArgs args)
|
||||
{
|
||||
Runtime.NUTEXBSettings.LimitFileSize = ((STToolStipMenuItem)sender).Checked ? true : false;
|
||||
}
|
||||
|
||||
|
|
|
@ -521,7 +521,7 @@ namespace FirstPlugin
|
|||
Format = tex.Format;
|
||||
XTXFormat = ConvertFromGenericFormat(tex.Format);
|
||||
|
||||
uint[] mips = TegraX1Swizzle.GenerateMipSizes(tex.Format, tex.Width, tex.Height, tex.Depth, tex.ArrayCount, tex.MipCount, (uint)ImageData.Length)[0];
|
||||
uint[] mips = TegraX1Swizzle.GenerateMipSizes(tex.Format, tex.Width, tex.Height, tex.Depth, tex.ArrayCount, tex.MipCount)[0];
|
||||
MipOffsets = new uint[17];
|
||||
|
||||
for (int i = 0; i < mips.Length; i++)
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Toolbox.Library
|
||||
{
|
||||
|
@ -12,22 +8,46 @@ namespace Toolbox.Library
|
|||
{
|
||||
// Swizzle code and surface calculations are performed using an efficient Rust implementation.
|
||||
// C# code can call the Rust code using the library's C API.
|
||||
// Documentation, code, and tests for the tegra_swizzle Rust library can be found here:
|
||||
// https://github.com/ScanMountGoat/nutexb_swizzle
|
||||
// Github: https://github.com/ScanMountGoat/tegra_swizzle
|
||||
// FFI Docs: https://docs.rs/tegra_swizzle/0.3.1/tegra_swizzle/ffi/index.html
|
||||
|
||||
// TODO: Find a cleaner way to support both 32 and 64 bit binaries.
|
||||
// 64 Bit.
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct BlockDimX64
|
||||
{
|
||||
public ulong width;
|
||||
public ulong height;
|
||||
public ulong depth;
|
||||
}
|
||||
|
||||
[DllImport("tegra_swizzle_x64", EntryPoint = "deswizzle_surface")]
|
||||
private static unsafe extern void DeswizzleSurfaceX64(ulong width, ulong height, ulong depth,
|
||||
byte* source, ulong sourceLength,
|
||||
byte* destination, ulong destinationLength,
|
||||
BlockDimX64 blockDim, ulong blockHeightMip0, ulong bytesPerPixel,
|
||||
ulong mipmapCount, ulong arrayCount);
|
||||
|
||||
[DllImport("tegra_swizzle_x64", EntryPoint = "swizzle_surface")]
|
||||
private static unsafe extern void SwizzleSurfaceX64(ulong width, ulong height, ulong depth,
|
||||
byte* source, ulong sourceLength,
|
||||
byte* destination, ulong destinationLength,
|
||||
BlockDimX64 blockDim, ulong blockHeightMip0, ulong bytesPerPixel,
|
||||
ulong mipmapCount, ulong arrayCount);
|
||||
|
||||
[DllImport("tegra_swizzle_x64", EntryPoint = "deswizzle_block_linear")]
|
||||
private static unsafe extern void DeswizzleBlockLinearX64(ulong width, ulong height, ulong depth, byte* source, ulong sourceLength,
|
||||
byte[] destination, ulong destinationLength, ulong blockHeight, ulong bytesPerPixel);
|
||||
private static unsafe extern void DeswizzleBlockLinearX64(ulong width, ulong height, ulong depth, byte* source, ulong sourceLength,
|
||||
byte* destination, ulong destinationLength, ulong blockHeight, ulong bytesPerPixel);
|
||||
|
||||
[DllImport("tegra_swizzle_x64", EntryPoint = "swizzle_block_linear")]
|
||||
private static unsafe extern void SwizzleBlockLinearX64(ulong width, ulong height, ulong depth, byte* source, ulong sourceLength,
|
||||
byte[] destination, ulong destinationLength, ulong blockHeight, ulong bytesPerPixel);
|
||||
byte* destination, ulong destinationLength, ulong blockHeight, ulong bytesPerPixel);
|
||||
|
||||
[DllImport("tegra_swizzle_x64", EntryPoint = "swizzled_surface_size")]
|
||||
private static extern ulong GetSurfaceSizeX64(ulong width, ulong height, ulong depth, ulong blockHeight, ulong bytesPerPixel);
|
||||
|
||||
private static extern ulong SwizzledSurfaceSizeX64(ulong width, ulong height, ulong depth, BlockDimX64 blockDim, ulong blockHeightMip0, ulong bytesPerPixel, ulong mipmapCount, ulong arrayCount);
|
||||
|
||||
[DllImport("tegra_swizzle_x64", EntryPoint = "deswizzled_surface_size")]
|
||||
private static extern ulong DeswizzledSurfaceSizeX64(ulong width, ulong height, ulong depth, BlockDimX64 blockDim, ulong bytesPerPixel, ulong mipmapCount, ulong arrayCount);
|
||||
|
||||
[DllImport("tegra_swizzle_x64", EntryPoint = "block_height_mip0")]
|
||||
private static extern ulong BlockHeightMip0X64(ulong height);
|
||||
|
||||
|
@ -35,16 +55,41 @@ namespace Toolbox.Library
|
|||
private static extern ulong MipBlockHeightX64(ulong mipHeight, ulong blockHeightMip0);
|
||||
|
||||
// 32 Bit.
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct BlockDimX86
|
||||
{
|
||||
public uint width;
|
||||
public uint height;
|
||||
public uint depth;
|
||||
}
|
||||
|
||||
[DllImport("tegra_swizzle_x86", EntryPoint = "deswizzle_surface")]
|
||||
private static unsafe extern void DeswizzleSurfaceX86(uint width, uint height, uint depth,
|
||||
byte* source, uint sourceLength,
|
||||
byte* destination, uint destinationLength,
|
||||
BlockDimX86 blockDim, uint blockHeightMip0, uint bytesPerPixel,
|
||||
uint mipmapCount, uint arrayCount);
|
||||
|
||||
[DllImport("tegra_swizzle_x86", EntryPoint = "swizzle_surface")]
|
||||
private static unsafe extern void SwizzleSurfaceX86(uint width, uint height, uint depth,
|
||||
byte* source, uint sourceLength,
|
||||
byte* destination, uint destinationLength,
|
||||
BlockDimX86 blockDim, uint blockHeightMip0, uint bytesPerPixel,
|
||||
uint mipmapCount, uint arrayCount);
|
||||
|
||||
[DllImport("tegra_swizzle_x86", EntryPoint = "deswizzle_block_linear")]
|
||||
private static unsafe extern void DeswizzleBlockLinearX86(uint width, uint height, uint depth, byte* source, uint sourceLength,
|
||||
byte[] destination, uint destinationLength, uint blockHeight, uint bytesPerPixel);
|
||||
byte* destination, uint destinationLength, uint blockHeight, uint bytesPerPixel);
|
||||
|
||||
[DllImport("tegra_swizzle_x86", EntryPoint = "swizzle_block_linear")]
|
||||
private static unsafe extern void SwizzleBlockLinearX86(uint width, uint height, uint depth, byte* source, uint sourceLength,
|
||||
byte[] destination, uint destinationLength, uint blockHeight, uint bytesPerPixel);
|
||||
byte* destination, uint destinationLength, uint blockHeight, uint bytesPerPixel);
|
||||
|
||||
[DllImport("tegra_swizzle_x86", EntryPoint = "swizzled_surface_size")]
|
||||
private static extern uint GetSurfaceSizeX86(uint width, uint height, uint depth, uint blockHeight, uint bytesPerPixel);
|
||||
private static extern uint SwizzledSurfaceSizeX86(uint width, uint height, uint depth, BlockDimX86 blockDim, uint blockHeightMip0, uint bytesPerPixel, uint mipmapCount, uint arrayCount);
|
||||
|
||||
[DllImport("tegra_swizzle_x86", EntryPoint = "deswizzled_surface_size")]
|
||||
private static extern uint DeswizzledSurfaceSizeX86(uint width, uint height, uint depth, BlockDimX86 blockDim, uint bytesPerPixel, uint mipmapCount, uint arrayCount);
|
||||
|
||||
[DllImport("tegra_swizzle_x86", EntryPoint = "block_height_mip0")]
|
||||
private static extern uint BlockHeightMip0X86(uint height);
|
||||
|
@ -52,7 +97,7 @@ namespace Toolbox.Library
|
|||
[DllImport("tegra_swizzle_x86", EntryPoint = "mip_block_height")]
|
||||
private static extern uint MipBlockHeightX86(uint mipHeight, uint blockHeightMip0);
|
||||
|
||||
public static List<uint[]> GenerateMipSizes(TEX_FORMAT Format, uint Width, uint Height, uint Depth, uint SurfaceCount, uint MipCount, uint ImageSize)
|
||||
public static List<uint[]> GenerateMipSizes(TEX_FORMAT Format, uint Width, uint Height, uint Depth, uint SurfaceCount, uint MipCount)
|
||||
{
|
||||
List<uint[]> MipMapSizes = new List<uint[]>();
|
||||
|
||||
|
@ -61,34 +106,19 @@ namespace Toolbox.Library
|
|||
uint blkHeight = STGenericTexture.GetBlockHeight(Format);
|
||||
uint blkDepth = STGenericTexture.GetBlockDepth(Format);
|
||||
|
||||
uint blockHeight = GetBlockHeight(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 = SurfaceCount;
|
||||
|
||||
uint ArrayOffset = 0;
|
||||
for (int arrayLevel = 0; arrayLevel < ArrayCount; arrayLevel++)
|
||||
for (int arrayLevel = 0; arrayLevel < SurfaceCount; 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 width = Math.Max(1, Width >> mipLevel);
|
||||
uint height = Math.Max(1, Height >> mipLevel);
|
||||
uint depth = Math.Max(1, Depth >> mipLevel);
|
||||
|
||||
uint size = DIV_ROUND_UP(width, blkWidth) * DIV_ROUND_UP(height, blkHeight) * bpp;
|
||||
uint size = DIV_ROUND_UP(width, blkWidth) * DIV_ROUND_UP(height, blkHeight) * DIV_ROUND_UP(depth, blkDepth) * bpp;
|
||||
MipOffsets[mipLevel] = size;
|
||||
}
|
||||
ArrayOffset += (uint)(ImageSize / ArrayCount);
|
||||
|
||||
MipMapSizes.Add(MipOffsets);
|
||||
}
|
||||
|
@ -146,15 +176,18 @@ namespace Toolbox.Library
|
|||
uint TileMode = 0;
|
||||
if (LinearTileMode)
|
||||
TileMode = 1;
|
||||
uint numDepth = 1;
|
||||
if (texture.Depth > 1)
|
||||
numDepth = texture.Depth;
|
||||
|
||||
var blockHeightMip0 = GetBlockHeight(DIV_ROUND_UP(texture.Height, blkHeight));
|
||||
uint width = texture.Width;
|
||||
uint height = texture.Height;
|
||||
uint depth = Math.Max(1, texture.Depth);
|
||||
|
||||
var blockHeightMip0 = GetBlockHeight(DIV_ROUND_UP(height, blkHeight));
|
||||
|
||||
var blockDim = new BlockDimX64 { width = blkWidth, height = blkHeight, depth = blkDepth };
|
||||
|
||||
uint arrayOffset = 0;
|
||||
// TODO: Why is depth done like this?
|
||||
for (int depthLevel = 0; depthLevel < numDepth; depthLevel++)
|
||||
for (int depthLevel = 0; depthLevel < depth; depthLevel++)
|
||||
{
|
||||
for (int arrayLevel = 0; arrayLevel < texture.ArrayCount; arrayLevel++)
|
||||
{
|
||||
|
@ -162,24 +195,16 @@ namespace Toolbox.Library
|
|||
|
||||
for (int mipLevel = 0; mipLevel < texture.MipCount; mipLevel++)
|
||||
{
|
||||
uint width = Math.Max(1, texture.Width >> mipLevel);
|
||||
uint height = Math.Max(1, texture.Height >> mipLevel);
|
||||
uint depth = Math.Max(1, texture.Depth >> mipLevel);
|
||||
uint mipWidth = Math.Max(1, width >> mipLevel);
|
||||
uint mipHeight = Math.Max(1, height >> mipLevel);
|
||||
uint mipDepth = Math.Max(1, depth >> mipLevel);
|
||||
|
||||
uint widthInBlocks = DIV_ROUND_UP(width, blkWidth);
|
||||
uint heightInBlocks = DIV_ROUND_UP(height, blkHeight);
|
||||
uint depthInBlocks = DIV_ROUND_UP(depth, blkDepth);
|
||||
uint mipHeightInBlocks = DIV_ROUND_UP(mipHeight, blkHeight);
|
||||
|
||||
// tegra_swizzle only allows block heights supported by the TRM (1,2,4,8,16,32).
|
||||
var mipBlockHeightLog2 = (int)Math.Log(GetMipBlockHeight(heightInBlocks, blockHeightMip0), 2);
|
||||
var mipBlockHeight = 1 << Math.Max(Math.Min(mipBlockHeightLog2, 5), 0);
|
||||
|
||||
uint mipSize;
|
||||
if (Environment.Is64BitProcess)
|
||||
mipSize = (uint)GetSurfaceSizeX64(widthInBlocks, heightInBlocks, depthInBlocks, (ulong)mipBlockHeight, bpp);
|
||||
else
|
||||
mipSize = (uint)GetSurfaceSizeX86(widthInBlocks, heightInBlocks, depthInBlocks, (uint)mipBlockHeight, bpp);
|
||||
var mipBlockHeightLog2 = (int)Math.Log(GetMipBlockHeight(mipHeightInBlocks, blockHeightMip0), 2);
|
||||
|
||||
uint mipSize = (uint)SwizzledSurfaceSizeX64(mipWidth, mipHeight, mipDepth, blockDim, blockHeightMip0, bpp, 1, 1);
|
||||
// TODO: Avoid this copy.
|
||||
byte[] mipData = Utils.SubArray(ImageData, arrayOffset + mipOffset, mipSize);
|
||||
|
||||
|
@ -189,7 +214,7 @@ namespace Toolbox.Library
|
|||
{
|
||||
// The set of swizzled addresses is at least as big as the set of linear addresses.
|
||||
// When defined appropriately, we only require a single memory allocation for the output.
|
||||
byte[] result = deswizzle(width, height, depth, blkWidth, blkHeight, blkDepth, target, bpp, TileMode, mipBlockHeightLog2, mipData);
|
||||
byte[] result = deswizzle(mipWidth, mipHeight, mipDepth, blkWidth, blkHeight, blkDepth, target, bpp, TileMode, mipBlockHeightLog2, mipData);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -213,51 +238,84 @@ namespace Toolbox.Library
|
|||
private static unsafe byte[] SwizzleDeswizzleBlockLinear(uint width, uint height, uint depth, uint blkWidth, uint blkHeight, uint blkDepth,
|
||||
uint bpp, int blockHeightLog2, byte[] data, bool deswizzle, uint size, uint alignment = 512)
|
||||
{
|
||||
// This function expects the surface dimensions in blocks rather than pixels for block compressed formats.
|
||||
// This ensures the bytes per pixel parameter is used correctly.
|
||||
width = DIV_ROUND_UP(width, blkWidth);
|
||||
height = DIV_ROUND_UP(height, blkHeight);
|
||||
depth = DIV_ROUND_UP(depth, blkDepth);
|
||||
|
||||
// tegra_swizzle only allows block heights supported by the TRM (1,2,4,8,16,32).
|
||||
var blockHeight = (ulong)(1 << Math.Max(Math.Min(blockHeightLog2, 5), 0));
|
||||
var blockHeightMip0 = (ulong)(1 << Math.Max(Math.Min(blockHeightLog2, 5), 0));
|
||||
|
||||
if (deswizzle)
|
||||
{
|
||||
var output = new byte[width * height * bpp];
|
||||
// This function expects the surface dimensions in blocks rather than pixels for block compressed formats.
|
||||
// This ensures the bytes per pixel parameter is used correctly.
|
||||
width = DIV_ROUND_UP(width, blkWidth);
|
||||
height = DIV_ROUND_UP(height, blkHeight);
|
||||
depth = DIV_ROUND_UP(depth, blkDepth);
|
||||
|
||||
fixed (byte* dataPtr = data)
|
||||
{
|
||||
if (Environment.Is64BitProcess)
|
||||
DeswizzleBlockLinearX64(width, height, depth, dataPtr, (ulong)data.Length, output, (ulong)output.Length, blockHeight, bpp);
|
||||
else
|
||||
DeswizzleBlockLinearX86(width, height, depth, dataPtr, (uint)data.Length, output, (uint)output.Length, (uint)blockHeight, bpp);
|
||||
}
|
||||
var output = new byte[width * height * depth * bpp];
|
||||
|
||||
DeswizzleBlockLinear(width, height, depth, bpp, data, (uint)blockHeightMip0, output);
|
||||
|
||||
return output;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong surfaceSize;
|
||||
if (Environment.Is64BitProcess)
|
||||
surfaceSize = GetSurfaceSizeX64(width, height, depth, blockHeight, bpp);
|
||||
else
|
||||
surfaceSize = GetSurfaceSizeX86(width, height, depth, (uint)blockHeight, bpp);
|
||||
var blockDim = new BlockDimX86 { width = blkWidth, height = blkHeight, depth = blkDepth };
|
||||
|
||||
ulong surfaceSize = SwizzledSurfaceSize(width, height, depth, blockDim, (uint)blockHeightMip0, bpp, 1, 1);
|
||||
var output = new byte[surfaceSize];
|
||||
|
||||
fixed (byte* dataPtr = data)
|
||||
{
|
||||
if (Environment.Is64BitProcess)
|
||||
SwizzleBlockLinearX64(width, height, depth, dataPtr, (ulong)data.Length, output, (ulong)output.Length, blockHeight, bpp);
|
||||
else
|
||||
SwizzleBlockLinearX86(width, height, depth, dataPtr, (uint)data.Length, output, (uint)output.Length, (uint)blockHeight, bpp);
|
||||
}
|
||||
// This function expects the surface dimensions in blocks rather than pixels for block compressed formats.
|
||||
// This ensures the bytes per pixel parameter is used correctly.
|
||||
width = DIV_ROUND_UP(width, blkWidth);
|
||||
height = DIV_ROUND_UP(height, blkHeight);
|
||||
depth = DIV_ROUND_UP(depth, blkDepth);
|
||||
|
||||
SwizzleBlockLinear(width, height, depth, bpp, data, (uint)blockHeightMip0, output);
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
private static unsafe void SwizzleBlockLinear(uint width, uint height, uint depth, uint bpp, byte[] data, uint blockHeightMip0, byte[] output)
|
||||
{
|
||||
fixed (byte* dataPtr = data)
|
||||
{
|
||||
fixed (byte* outputPtr = output)
|
||||
{
|
||||
if (Environment.Is64BitProcess)
|
||||
SwizzleBlockLinearX64(width, height, depth, dataPtr, (ulong)data.Length, outputPtr, (ulong)output.Length, blockHeightMip0, bpp);
|
||||
else
|
||||
SwizzleBlockLinearX86(width, height, depth, dataPtr, (uint)data.Length, outputPtr, (uint)output.Length, blockHeightMip0, bpp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static unsafe void DeswizzleBlockLinear(uint width, uint height, uint depth, uint bpp, byte[] data, uint blockHeightMip0, byte[] output)
|
||||
{
|
||||
fixed (byte* dataPtr = data)
|
||||
{
|
||||
fixed (byte* outputPtr = output)
|
||||
{
|
||||
if (Environment.Is64BitProcess)
|
||||
DeswizzleBlockLinearX64(width, height, depth, dataPtr, (ulong)data.Length, outputPtr, (ulong)output.Length, blockHeightMip0, bpp);
|
||||
else
|
||||
DeswizzleBlockLinearX86(width, height, depth, dataPtr, (uint)data.Length, outputPtr, (uint)output.Length, blockHeightMip0, bpp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ulong SwizzledSurfaceSize(uint width, uint height, uint depth, BlockDimX86 blockDim, uint blockHeightMip0, uint bytesPerPixel, uint mipmapCount, uint arrayCount)
|
||||
{
|
||||
if (Environment.Is64BitProcess)
|
||||
{
|
||||
var blockDimX64 = new BlockDimX64 { width = blockDim.width, height = blockDim.height, depth = blockDim.depth };
|
||||
return SwizzledSurfaceSizeX64(width, height, depth, blockDimX64, blockHeightMip0, bytesPerPixel, mipmapCount, arrayCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
return SwizzledSurfaceSizeX86(width, height, depth, blockDim, blockHeightMip0, bytesPerPixel, mipmapCount, arrayCount);
|
||||
}
|
||||
}
|
||||
|
||||
public static uint GetBlockHeight(uint heightInBytes)
|
||||
{
|
||||
if (Environment.Is64BitProcess)
|
||||
|
@ -274,6 +332,7 @@ namespace Toolbox.Library
|
|||
return MipBlockHeightX86(mipHeightInBytes, blockHeightMip0);
|
||||
}
|
||||
|
||||
// TODO: These should not be public.
|
||||
public static byte[] deswizzle(uint width, uint height, uint depth, uint blkWidth, uint blkHeight, uint blkDepth, int roundPitch, uint bpp, uint tileMode, int blockHeightLog2, byte[] data)
|
||||
{
|
||||
if (tileMode == 1)
|
||||
|
@ -335,26 +394,30 @@ namespace Toolbox.Library
|
|||
|
||||
byte[] result = new byte[surfSize];
|
||||
|
||||
for (uint y = 0; y < height; y++)
|
||||
for (uint z = 0; z < depth; z++)
|
||||
{
|
||||
for (uint x = 0; x < width; x++)
|
||||
for (uint y = 0; y < height; y++)
|
||||
{
|
||||
uint pos;
|
||||
uint pos_;
|
||||
|
||||
pos = y * pitch + x * bpp;
|
||||
|
||||
pos_ = (y * width + x) * bpp;
|
||||
|
||||
if (pos + bpp <= surfSize)
|
||||
for (uint x = 0; x < width; x++)
|
||||
{
|
||||
if (!deswizzle)
|
||||
Array.Copy(data, pos, result, pos_, bpp);
|
||||
else
|
||||
Array.Copy(data, pos_, result, pos, bpp);
|
||||
uint pos;
|
||||
uint pos_;
|
||||
|
||||
pos = y * pitch + x * bpp;
|
||||
|
||||
pos_ = (y * width + x) * bpp;
|
||||
|
||||
if (pos + bpp <= surfSize)
|
||||
{
|
||||
if (!deswizzle)
|
||||
Array.Copy(data, pos, result, pos_, bpp);
|
||||
else
|
||||
Array.Copy(data, pos_, result, pos, bpp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue