forked from Mirror/Ryujinx
107 lines
3.4 KiB
C#
107 lines
3.4 KiB
C#
|
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;
|
||
|
}
|
||
|
}
|
||
|
}
|