mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-11-08 07:08:37 +00:00
c86aacde76
* Initial nvdec implementation using FFmpeg * Fix swapped channels on the video decoder and the G8R8 texture format * Fix texture samplers not being set properly (regression) * Rebased * Remove unused code introduced on the rebase * Add support for RGBA8 output format on the video image composer * Correct spacing * Some fixes for rebase and other tweaks * Allow size mismatch on frame copy * Get rid of GetHostAddress calls on VDec
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;
|
|
}
|
|
}
|
|
} |