2018-12-03 03:38:47 +01:00
|
|
|
using Ryujinx.Graphics.Memory;
|
|
|
|
|
|
|
|
namespace Ryujinx.Graphics.Vic
|
|
|
|
{
|
|
|
|
class VideoImageComposer
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
private NvGpu _gpu;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
private long _configStructAddress;
|
|
|
|
private long _outputSurfaceLumaAddress;
|
|
|
|
private long _outputSurfaceChromaUAddress;
|
|
|
|
private long _outputSurfaceChromaVAddress;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
public VideoImageComposer(NvGpu gpu)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
_gpu = gpu;
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
public void Process(NvGpuVmm vmm, int methodOffset, int[] arguments)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
VideoImageComposerMeth method = (VideoImageComposerMeth)methodOffset;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
switch (method)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
|
|
|
case VideoImageComposerMeth.Execute:
|
2019-03-04 02:45:25 +01:00
|
|
|
Execute(vmm, arguments);
|
2018-12-03 03:38:47 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case VideoImageComposerMeth.SetConfigStructOffset:
|
2019-03-04 02:45:25 +01:00
|
|
|
SetConfigStructOffset(vmm, arguments);
|
2018-12-03 03:38:47 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case VideoImageComposerMeth.SetOutputSurfaceLumaOffset:
|
2019-03-04 02:45:25 +01:00
|
|
|
SetOutputSurfaceLumaOffset(vmm, arguments);
|
2018-12-03 03:38:47 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case VideoImageComposerMeth.SetOutputSurfaceChromaUOffset:
|
2019-03-04 02:45:25 +01:00
|
|
|
SetOutputSurfaceChromaUOffset(vmm, arguments);
|
2018-12-03 03:38:47 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case VideoImageComposerMeth.SetOutputSurfaceChromaVOffset:
|
2019-03-04 02:45:25 +01:00
|
|
|
SetOutputSurfaceChromaVOffset(vmm, arguments);
|
2018-12-03 03:38:47 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
private void Execute(NvGpuVmm vmm, int[] arguments)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
StructUnpacker unpacker = new StructUnpacker(vmm, _configStructAddress + 0x20);
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
SurfacePixelFormat pixelFormat = (SurfacePixelFormat)unpacker.Read(7);
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
int chromaLocHoriz = unpacker.Read(2);
|
|
|
|
int chromaLocVert = unpacker.Read(2);
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
int blockLinearKind = unpacker.Read(4);
|
|
|
|
int blockLinearHeightLog2 = unpacker.Read(4);
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
int reserved0 = unpacker.Read(3);
|
|
|
|
int reserved1 = unpacker.Read(10);
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
int surfaceWidthMinus1 = unpacker.Read(14);
|
|
|
|
int surfaceHeightMinus1 = unpacker.Read(14);
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
int gobBlockHeight = 1 << blockLinearHeightLog2;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
int surfaceWidth = surfaceWidthMinus1 + 1;
|
|
|
|
int surfaceHeight = surfaceHeightMinus1 + 1;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
SurfaceOutputConfig outputConfig = new SurfaceOutputConfig(
|
|
|
|
pixelFormat,
|
|
|
|
surfaceWidth,
|
|
|
|
surfaceHeight,
|
|
|
|
gobBlockHeight,
|
|
|
|
_outputSurfaceLumaAddress,
|
|
|
|
_outputSurfaceChromaUAddress,
|
|
|
|
_outputSurfaceChromaVAddress);
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
_gpu.VideoDecoder.CopyPlanes(vmm, outputConfig);
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
private void SetConfigStructOffset(NvGpuVmm vmm, int[] arguments)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
_configStructAddress = GetAddress(arguments);
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
private void SetOutputSurfaceLumaOffset(NvGpuVmm vmm, int[] arguments)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
_outputSurfaceLumaAddress = GetAddress(arguments);
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
private void SetOutputSurfaceChromaUOffset(NvGpuVmm vmm, int[] arguments)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
_outputSurfaceChromaUAddress = GetAddress(arguments);
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
private void SetOutputSurfaceChromaVOffset(NvGpuVmm vmm, int[] arguments)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
_outputSurfaceChromaVAddress = GetAddress(arguments);
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
private static long GetAddress(int[] arguments)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
return (long)(uint)arguments[0] << 8;
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|