Ryujinx/Ryujinx.Graphics/Vic/VideoImageComposer.cs

107 lines
3.4 KiB
C#
Raw Normal View History

using Ryujinx.Graphics.Memory;
namespace Ryujinx.Graphics.Vic
{
class VideoImageComposer
{
private NvGpu Gpu;
private long ConfigStructAddress;
private long OutputSurfaceLumaAddress;
private long OutputSurfaceChromaUAddress;
private long OutputSurfaceChromaVAddress;
public VideoImageComposer(NvGpu Gpu)
{
this.Gpu = Gpu;
}
public void Process(NvGpuVmm Vmm, int MethodOffset, int[] Arguments)
{
VideoImageComposerMeth Method = (VideoImageComposerMeth)MethodOffset;
switch (Method)
{
case VideoImageComposerMeth.Execute:
Execute(Vmm, Arguments);
break;
case VideoImageComposerMeth.SetConfigStructOffset:
SetConfigStructOffset(Vmm, Arguments);
break;
case VideoImageComposerMeth.SetOutputSurfaceLumaOffset:
SetOutputSurfaceLumaOffset(Vmm, Arguments);
break;
case VideoImageComposerMeth.SetOutputSurfaceChromaUOffset:
SetOutputSurfaceChromaUOffset(Vmm, Arguments);
break;
case VideoImageComposerMeth.SetOutputSurfaceChromaVOffset:
SetOutputSurfaceChromaVOffset(Vmm, Arguments);
break;
}
}
private void Execute(NvGpuVmm Vmm, int[] Arguments)
{
StructUnpacker Unpacker = new StructUnpacker(Vmm, 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);
Gpu.VideoDecoder.CopyPlanes(Vmm, OutputConfig);
}
private void SetConfigStructOffset(NvGpuVmm Vmm, int[] Arguments)
{
ConfigStructAddress = GetAddress(Arguments);
}
private void SetOutputSurfaceLumaOffset(NvGpuVmm Vmm, int[] Arguments)
{
OutputSurfaceLumaAddress = GetAddress(Arguments);
}
private void SetOutputSurfaceChromaUOffset(NvGpuVmm Vmm, int[] Arguments)
{
OutputSurfaceChromaUAddress = GetAddress(Arguments);
}
private void SetOutputSurfaceChromaVOffset(NvGpuVmm Vmm, int[] Arguments)
{
OutputSurfaceChromaVAddress = GetAddress(Arguments);
}
private static long GetAddress(int[] Arguments)
{
return (long)(uint)Arguments[0] << 8;
}
}
}