diff options
Diffstat (limited to 'Ryujinx.Graphics.Nvdec/Vic/VideoImageComposer.cs')
| -rw-r--r-- | Ryujinx.Graphics.Nvdec/Vic/VideoImageComposer.cs | 94 |
1 files changed, 94 insertions, 0 deletions
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 |
