diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2019-12-31 21:08:02 -0300 |
|---|---|---|
| committer | Thog <thog@protonmail.com> | 2020-01-09 02:13:00 +0100 |
| commit | 0dbfe3c23ee072ec9dbc477f955a163107af2be1 (patch) | |
| tree | f7f3501ef32891e80197717ab18b22a8d88fdb9f /Ryujinx.Graphics.Nvdec/Vic | |
| parent | 6e092c05584ccbbd548ac26c056c1a7edfa6c1a0 (diff) | |
Re-add NVDEC project (not integrated)
Diffstat (limited to 'Ryujinx.Graphics.Nvdec/Vic')
| -rw-r--r-- | Ryujinx.Graphics.Nvdec/Vic/StructUnpacker.cs | 69 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Nvdec/Vic/SurfaceOutputConfig.cs | 33 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Nvdec/Vic/SurfacePixelFormat.cs | 8 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Nvdec/Vic/VideoImageComposer.cs | 94 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Nvdec/Vic/VideoImageComposerMeth.cs | 12 |
5 files changed, 216 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Nvdec/Vic/StructUnpacker.cs b/Ryujinx.Graphics.Nvdec/Vic/StructUnpacker.cs new file mode 100644 index 00000000..4957e6b6 --- /dev/null +++ b/Ryujinx.Graphics.Nvdec/Vic/StructUnpacker.cs @@ -0,0 +1,69 @@ +using Ryujinx.Graphics.Gpu.Memory; +using System; + +namespace Ryujinx.Graphics.Vic +{ + class StructUnpacker + { + private MemoryAccessor _vmm; + + private ulong _position; + + private ulong _buffer; + private int _buffPos; + + public StructUnpacker(MemoryAccessor vmm, ulong position) + { + _vmm = vmm; + _position = position; + + _buffPos = 64; + } + + public int Read(int bits) + { + if ((uint)bits > 32) + { + throw new ArgumentOutOfRangeException(nameof(bits)); + } + + int value = 0; + + while (bits > 0) + { + RefillBufferIfNeeded(); + + int readBits = bits; + + int maxReadBits = 64 - _buffPos; + + if (readBits > maxReadBits) + { + readBits = maxReadBits; + } + + value <<= readBits; + + value |= (int)(_buffer >> _buffPos) & (int)(0xffffffff >> (32 - readBits)); + + _buffPos += readBits; + + bits -= readBits; + } + + return value; + } + + private void RefillBufferIfNeeded() + { + if (_buffPos >= 64) + { + _buffer = _vmm.ReadUInt64(_position); + + _position += 8; + + _buffPos = 0; + } + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Nvdec/Vic/SurfaceOutputConfig.cs b/Ryujinx.Graphics.Nvdec/Vic/SurfaceOutputConfig.cs new file mode 100644 index 00000000..bcb01e70 --- /dev/null +++ b/Ryujinx.Graphics.Nvdec/Vic/SurfaceOutputConfig.cs @@ -0,0 +1,33 @@ +namespace Ryujinx.Graphics.Vic +{ + struct SurfaceOutputConfig + { + public SurfacePixelFormat PixelFormat; + + public int SurfaceWidth; + public int SurfaceHeight; + public int GobBlockHeight; + + public ulong SurfaceLumaAddress; + public ulong SurfaceChromaUAddress; + public ulong SurfaceChromaVAddress; + + public SurfaceOutputConfig( + SurfacePixelFormat pixelFormat, + int surfaceWidth, + int surfaceHeight, + int gobBlockHeight, + ulong outputSurfaceLumaAddress, + ulong outputSurfaceChromaUAddress, + ulong outputSurfaceChromaVAddress) + { + PixelFormat = pixelFormat; + SurfaceWidth = surfaceWidth; + SurfaceHeight = surfaceHeight; + GobBlockHeight = gobBlockHeight; + SurfaceLumaAddress = outputSurfaceLumaAddress; + SurfaceChromaUAddress = outputSurfaceChromaUAddress; + SurfaceChromaVAddress = outputSurfaceChromaVAddress; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Nvdec/Vic/SurfacePixelFormat.cs b/Ryujinx.Graphics.Nvdec/Vic/SurfacePixelFormat.cs new file mode 100644 index 00000000..8dabd094 --- /dev/null +++ b/Ryujinx.Graphics.Nvdec/Vic/SurfacePixelFormat.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Graphics.Vic +{ + enum SurfacePixelFormat + { + Rgba8 = 0x1f, + Yuv420P = 0x44 + } +}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Nvdec/Vic/VideoImageComposer.cs b/Ryujinx.Graphics.Nvdec/Vic/VideoImageComposer.cs new file mode 100644 index 00000000..e16a2523 --- /dev/null +++ b/Ryujinx.Graphics.Nvdec/Vic/VideoImageComposer.cs @@ -0,0 +1,94 @@ +using Ryujinx.Graphics.Gpu; +using Ryujinx.Graphics.VDec; + +namespace Ryujinx.Graphics.Vic +{ + class VideoImageComposer + { + private ulong _configStructAddress; + private ulong _outputSurfaceLumaAddress; + private ulong _outputSurfaceChromaUAddress; + private ulong _outputSurfaceChromaVAddress; + + private VideoDecoder _vdec; + + public VideoImageComposer(VideoDecoder vdec) + { + _vdec = vdec; + } + + public void Process(GpuContext gpu, int methodOffset, int[] arguments) + { + VideoImageComposerMeth method = (VideoImageComposerMeth)methodOffset; + + switch (method) + { + case VideoImageComposerMeth.Execute: Execute(gpu); break; + case VideoImageComposerMeth.SetConfigStructOffset: SetConfigStructOffset(arguments); break; + case VideoImageComposerMeth.SetOutputSurfaceLumaOffset: SetOutputSurfaceLumaOffset(arguments); break; + case VideoImageComposerMeth.SetOutputSurfaceChromaUOffset: SetOutputSurfaceChromaUOffset(arguments); break; + case VideoImageComposerMeth.SetOutputSurfaceChromaVOffset: SetOutputSurfaceChromaVOffset(arguments); break; + } + } + + private void Execute(GpuContext gpu) + { + StructUnpacker unpacker = new StructUnpacker(gpu.MemoryAccessor, _configStructAddress + 0x20); + + SurfacePixelFormat pixelFormat = (SurfacePixelFormat)unpacker.Read(7); + + int chromaLocHoriz = unpacker.Read(2); + int chromaLocVert = unpacker.Read(2); + + int blockLinearKind = unpacker.Read(4); + int blockLinearHeightLog2 = unpacker.Read(4); + + int reserved0 = unpacker.Read(3); + int reserved1 = unpacker.Read(10); + + int surfaceWidthMinus1 = unpacker.Read(14); + int surfaceHeightMinus1 = unpacker.Read(14); + + int gobBlockHeight = 1 << blockLinearHeightLog2; + + int surfaceWidth = surfaceWidthMinus1 + 1; + int surfaceHeight = surfaceHeightMinus1 + 1; + + SurfaceOutputConfig outputConfig = new SurfaceOutputConfig( + pixelFormat, + surfaceWidth, + surfaceHeight, + gobBlockHeight, + _outputSurfaceLumaAddress, + _outputSurfaceChromaUAddress, + _outputSurfaceChromaVAddress); + + _vdec.CopyPlanes(gpu, outputConfig); + } + + private void SetConfigStructOffset(int[] arguments) + { + _configStructAddress = GetAddress(arguments); + } + + private void SetOutputSurfaceLumaOffset(int[] arguments) + { + _outputSurfaceLumaAddress = GetAddress(arguments); + } + + private void SetOutputSurfaceChromaUOffset(int[] arguments) + { + _outputSurfaceChromaUAddress = GetAddress(arguments); + } + + private void SetOutputSurfaceChromaVOffset(int[] arguments) + { + _outputSurfaceChromaVAddress = GetAddress(arguments); + } + + private static ulong GetAddress(int[] arguments) + { + return (ulong)(uint)arguments[0] << 8; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Nvdec/Vic/VideoImageComposerMeth.cs b/Ryujinx.Graphics.Nvdec/Vic/VideoImageComposerMeth.cs new file mode 100644 index 00000000..b30cabea --- /dev/null +++ b/Ryujinx.Graphics.Nvdec/Vic/VideoImageComposerMeth.cs @@ -0,0 +1,12 @@ +namespace Ryujinx.Graphics.Vic +{ + enum VideoImageComposerMeth + { + Execute = 0xc0, + SetControlParams = 0x1c1, + SetConfigStructOffset = 0x1c2, + SetOutputSurfaceLumaOffset = 0x1c8, + SetOutputSurfaceChromaUOffset = 0x1c9, + SetOutputSurfaceChromaVOffset = 0x1ca + } +}
\ No newline at end of file |
