diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2019-12-05 17:34:47 -0300 |
|---|---|---|
| committer | Thog <thog@protonmail.com> | 2020-01-09 02:13:00 +0100 |
| commit | e25b7c9848b6ec486eb513297b5c536857665c7f (patch) | |
| tree | c1ccb6c58bed0f7ece835359516330104feb8f4d /Ryujinx.Graphics.Texture | |
| parent | 6a98c643cabeea25dc42e19fe475a687a034a532 (diff) | |
Initial support for the guest OpenGL driver (NVIDIA and Nouveau)
Diffstat (limited to 'Ryujinx.Graphics.Texture')
| -rw-r--r-- | Ryujinx.Graphics.Texture/LayoutConverter.cs | 129 |
1 files changed, 121 insertions, 8 deletions
diff --git a/Ryujinx.Graphics.Texture/LayoutConverter.cs b/Ryujinx.Graphics.Texture/LayoutConverter.cs index ef80144e..c270b494 100644 --- a/Ryujinx.Graphics.Texture/LayoutConverter.cs +++ b/Ryujinx.Graphics.Texture/LayoutConverter.cs @@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Texture { public static class LayoutConverter { - private const int AlignmentSize = 4; + private const int HostStrideAlignment = 4; public static Span<byte> ConvertBlockLinearToLinear( int width, @@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Texture int gobBlocksInZ, int gobBlocksInTileX, SizeInfo sizeInfo, - Span<byte> data) + ReadOnlySpan<byte> data) { int outSize = GetTextureSize( width, @@ -62,7 +62,7 @@ namespace Ryujinx.Graphics.Texture mipGobBlocksInZ >>= 1; } - int stride = BitUtils.AlignUp(w * bytesPerPixel, AlignmentSize); + int stride = BitUtils.AlignUp(w * bytesPerPixel, HostStrideAlignment); int wAligned = BitUtils.AlignUp(w, wAlignment); BlockLinearLayout layoutConverter = new BlockLinearLayout( @@ -104,17 +104,17 @@ namespace Ryujinx.Graphics.Texture int blockHeight, int stride, int bytesPerPixel, - Span<byte> data) + ReadOnlySpan<byte> data) { - int outOffs = 0; - int w = BitUtils.DivRoundUp(width, blockWidth); int h = BitUtils.DivRoundUp(height, blockHeight); - int outStride = BitUtils.AlignUp(w * bytesPerPixel, AlignmentSize); + int outStride = BitUtils.AlignUp(w * bytesPerPixel, HostStrideAlignment); Span<byte> output = new byte[h * outStride]; + int outOffs = 0; + for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) @@ -132,6 +132,119 @@ namespace Ryujinx.Graphics.Texture return output; } + public static Span<byte> ConvertLinearToBlockLinear( + int width, + int height, + int depth, + int levels, + int layers, + int blockWidth, + int blockHeight, + int bytesPerPixel, + int gobBlocksInY, + int gobBlocksInZ, + int gobBlocksInTileX, + SizeInfo sizeInfo, + ReadOnlySpan<byte> data) + { + Span<byte> output = new byte[sizeInfo.TotalSize]; + + int inOffs = 0; + + int wAlignment = gobBlocksInTileX * (GobStride / bytesPerPixel); + + int mipGobBlocksInY = gobBlocksInY; + int mipGobBlocksInZ = gobBlocksInZ; + + for (int level = 0; level < levels; level++) + { + int w = Math.Max(1, width >> level); + int h = Math.Max(1, height >> level); + int d = Math.Max(1, depth >> level); + + w = BitUtils.DivRoundUp(w, blockWidth); + h = BitUtils.DivRoundUp(h, blockHeight); + + while (h <= (mipGobBlocksInY >> 1) * GobHeight && mipGobBlocksInY != 1) + { + mipGobBlocksInY >>= 1; + } + + while (d <= (mipGobBlocksInZ >> 1) && mipGobBlocksInZ != 1) + { + mipGobBlocksInZ >>= 1; + } + + int stride = BitUtils.AlignUp(w * bytesPerPixel, HostStrideAlignment); + int wAligned = BitUtils.AlignUp(w, wAlignment); + + BlockLinearLayout layoutConverter = new BlockLinearLayout( + wAligned, + h, + d, + mipGobBlocksInY, + mipGobBlocksInZ, + bytesPerPixel); + + for (int layer = 0; layer < layers; layer++) + { + int outBaseOffset = layer * sizeInfo.LayerSize + sizeInfo.GetMipOffset(level); + + for (int z = 0; z < d; z++) + for (int y = 0; y < h; y++) + { + for (int x = 0; x < w; x++) + { + int offset = outBaseOffset + layoutConverter.GetOffset(x, y, z); + + Span<byte> dest = output.Slice(offset, bytesPerPixel); + + data.Slice(inOffs + x * bytesPerPixel, bytesPerPixel).CopyTo(dest); + } + + inOffs += stride; + } + } + } + + return output; + } + + public static Span<byte> ConvertLinearToLinearStrided( + int width, + int height, + int blockWidth, + int blockHeight, + int stride, + int bytesPerPixel, + ReadOnlySpan<byte> data) + { + int w = BitUtils.DivRoundUp(width, blockWidth); + int h = BitUtils.DivRoundUp(height, blockHeight); + + int inStride = BitUtils.AlignUp(w * bytesPerPixel, HostStrideAlignment); + + Span<byte> output = new byte[h * stride]; + + int inOffs = 0; + + for (int y = 0; y < h; y++) + { + for (int x = 0; x < w; x++) + { + int offset = y * stride + x * bytesPerPixel; + + Span<byte> dest = output.Slice(offset, bytesPerPixel); + + data.Slice(inOffs + x * bytesPerPixel, bytesPerPixel).CopyTo(dest); + } + + inOffs += inStride; + } + + return output; + } + private static int GetTextureSize( int width, int height, @@ -153,7 +266,7 @@ namespace Ryujinx.Graphics.Texture w = BitUtils.DivRoundUp(w, blockWidth); h = BitUtils.DivRoundUp(h, blockHeight); - int stride = BitUtils.AlignUp(w * bytesPerPixel, AlignmentSize); + int stride = BitUtils.AlignUp(w * bytesPerPixel, HostStrideAlignment); layerSize += stride * h * d; } |
