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)
{
_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;
}
}
}