Supper 2D array ASTC compressed texture formats decoding (#1593)

This commit is contained in:
gdkchan 2020-10-01 22:22:23 -03:00 committed by GitHub
parent f8c41a9a51
commit 86412ed30a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 22 deletions

View file

@ -657,6 +657,7 @@ namespace Ryujinx.Graphics.Gpu.Image
Info.Height, Info.Height,
_depth, _depth,
Info.Levels, Info.Levels,
_layers,
out Span<byte> decoded)) out Span<byte> decoded))
{ {
string texInfo = $"{Info.Target} {Info.FormatInfo.Format} {Info.Width}x{Info.Height}x{Info.DepthOrLayers} levels {Info.Levels}"; string texInfo = $"{Info.Target} {Info.FormatInfo.Format} {Info.Width}x{Info.Height}x{Info.DepthOrLayers} levels {Info.Levels}";

View file

@ -30,7 +30,8 @@ namespace Ryujinx.Graphics.Texture.Astc
int width, int width,
int height, int height,
int depth, int depth,
int levels) int levels,
int layers)
{ {
if ((uint)blockWidth > 12) if ((uint)blockWidth > 12)
{ {
@ -48,7 +49,7 @@ namespace Ryujinx.Graphics.Texture.Astc
BlockSizeX = blockWidth; BlockSizeX = blockWidth;
BlockSizeY = blockHeight; BlockSizeY = blockHeight;
Levels = new AstcLevel[levels]; Levels = new AstcLevel[levels * layers];
Success = true; Success = true;
@ -59,20 +60,23 @@ namespace Ryujinx.Graphics.Texture.Astc
for (int i = 0; i < levels; i++) for (int i = 0; i < levels; i++)
{ {
ref AstcLevel level = ref Levels[i]; for (int j = 0; j < layers; j++)
{
ref AstcLevel level = ref Levels[i * layers + j];
level.ImageSizeX = Math.Max(1, width >> i); level.ImageSizeX = Math.Max(1, width >> i);
level.ImageSizeY = Math.Max(1, height >> i); level.ImageSizeY = Math.Max(1, height >> i);
level.ImageSizeZ = Math.Max(1, depth >> i); level.ImageSizeZ = Math.Max(1, depth >> i);
level.BlockCountX = (level.ImageSizeX + blockWidth - 1) / blockWidth; level.BlockCountX = (level.ImageSizeX + blockWidth - 1) / blockWidth;
level.BlockCountY = (level.ImageSizeY + blockHeight - 1) / blockHeight; level.BlockCountY = (level.ImageSizeY + blockHeight - 1) / blockHeight;
level.StartBlock = currentInputBlock; level.StartBlock = currentInputBlock;
level.OutputByteOffset = currentOutputOffset; level.OutputByteOffset = currentOutputOffset;
currentInputBlock += level.TotalBlockCount; currentInputBlock += level.TotalBlockCount;
currentOutputOffset += level.PixelCount * 4; currentOutputOffset += level.PixelCount * 4;
}
} }
TotalBlockCount = currentInputBlock; TotalBlockCount = currentInputBlock;
@ -94,7 +98,7 @@ namespace Ryujinx.Graphics.Texture.Astc
public int PixelCount => ImageSizeX * ImageSizeY * ImageSizeZ; public int PixelCount => ImageSizeX * ImageSizeY * ImageSizeZ;
} }
public static int QueryDecompressedSize(int sizeX, int sizeY, int sizeZ, int levelCount) public static int QueryDecompressedSize(int sizeX, int sizeY, int sizeZ, int levelCount, int layerCount)
{ {
int size = 0; int size = 0;
@ -104,7 +108,7 @@ namespace Ryujinx.Graphics.Texture.Astc
int levelSizeY = Math.Max(1, sizeY >> i); int levelSizeY = Math.Max(1, sizeY >> i);
int levelSizeZ = Math.Max(1, sizeZ >> i); int levelSizeZ = Math.Max(1, sizeZ >> i);
size += levelSizeX * levelSizeY * levelSizeZ; size += levelSizeX * levelSizeY * levelSizeZ * layerCount;
} }
return size * 4; return size * 4;
@ -221,11 +225,12 @@ namespace Ryujinx.Graphics.Texture.Astc
int height, int height,
int depth, int depth,
int levels, int levels,
int layers,
out Span<byte> decoded) out Span<byte> decoded)
{ {
byte[] output = new byte[QueryDecompressedSize(width, height, depth, levels)]; byte[] output = new byte[QueryDecompressedSize(width, height, depth, levels, layers)];
AstcDecoder decoder = new AstcDecoder(data, output, blockWidth, blockHeight, width, height, depth, levels); AstcDecoder decoder = new AstcDecoder(data, output, blockWidth, blockHeight, width, height, depth, levels, layers);
for (int i = 0; i < decoder.TotalBlockCount; i++) for (int i = 0; i < decoder.TotalBlockCount; i++)
{ {
@ -245,9 +250,10 @@ namespace Ryujinx.Graphics.Texture.Astc
int width, int width,
int height, int height,
int depth, int depth,
int levels) int levels,
int layers)
{ {
AstcDecoder decoder = new AstcDecoder(data, outputBuffer, blockWidth, blockHeight, width, height, depth, levels); AstcDecoder decoder = new AstcDecoder(data, outputBuffer, blockWidth, blockHeight, width, height, depth, levels, layers);
for (int i = 0; i < decoder.TotalBlockCount; i++) for (int i = 0; i < decoder.TotalBlockCount; i++)
{ {
@ -265,9 +271,10 @@ namespace Ryujinx.Graphics.Texture.Astc
int width, int width,
int height, int height,
int depth, int depth,
int levels) int levels,
int layers)
{ {
AstcDecoder decoder = new AstcDecoder(data, outputBuffer, blockWidth, blockHeight, width, height, depth, levels); AstcDecoder decoder = new AstcDecoder(data, outputBuffer, blockWidth, blockHeight, width, height, depth, levels, layers);
// Lazy parallelism // Lazy parallelism
Enumerable.Range(0, decoder.TotalBlockCount).AsParallel().ForAll(x => decoder.ProcessBlock(x)); Enumerable.Range(0, decoder.TotalBlockCount).AsParallel().ForAll(x => decoder.ProcessBlock(x));
@ -283,11 +290,12 @@ namespace Ryujinx.Graphics.Texture.Astc
int height, int height,
int depth, int depth,
int levels, int levels,
int layers,
out Span<byte> decoded) out Span<byte> decoded)
{ {
byte[] output = new byte[QueryDecompressedSize(width, height, depth, levels)]; byte[] output = new byte[QueryDecompressedSize(width, height, depth, levels, layers)];
AstcDecoder decoder = new AstcDecoder(data, output, blockWidth, blockHeight, width, height, depth, levels); AstcDecoder decoder = new AstcDecoder(data, output, blockWidth, blockHeight, width, height, depth, levels, layers);
Enumerable.Range(0, decoder.TotalBlockCount).AsParallel().ForAll(x => decoder.ProcessBlock(x)); Enumerable.Range(0, decoder.TotalBlockCount).AsParallel().ForAll(x => decoder.ProcessBlock(x));