Re-add NVDEC project (not integrated)

This commit is contained in:
gdkchan 2019-12-31 21:08:02 -03:00 committed by Thog
parent 6e092c0558
commit 0dbfe3c23e
31 changed files with 2547 additions and 18 deletions

View file

@ -0,0 +1,69 @@
using Ryujinx.Graphics.Gpu.Memory;
using System;
namespace Ryujinx.Graphics.Vic
{
class StructUnpacker
{
private MemoryAccessor _vmm;
private ulong _position;
private ulong _buffer;
private int _buffPos;
public StructUnpacker(MemoryAccessor vmm, ulong position)
{
_vmm = vmm;
_position = position;
_buffPos = 64;
}
public int Read(int bits)
{
if ((uint)bits > 32)
{
throw new ArgumentOutOfRangeException(nameof(bits));
}
int value = 0;
while (bits > 0)
{
RefillBufferIfNeeded();
int readBits = bits;
int maxReadBits = 64 - _buffPos;
if (readBits > maxReadBits)
{
readBits = maxReadBits;
}
value <<= readBits;
value |= (int)(_buffer >> _buffPos) & (int)(0xffffffff >> (32 - readBits));
_buffPos += readBits;
bits -= readBits;
}
return value;
}
private void RefillBufferIfNeeded()
{
if (_buffPos >= 64)
{
_buffer = _vmm.ReadUInt64(_position);
_position += 8;
_buffPos = 0;
}
}
}
}

View file

@ -0,0 +1,33 @@
namespace Ryujinx.Graphics.Vic
{
struct SurfaceOutputConfig
{
public SurfacePixelFormat PixelFormat;
public int SurfaceWidth;
public int SurfaceHeight;
public int GobBlockHeight;
public ulong SurfaceLumaAddress;
public ulong SurfaceChromaUAddress;
public ulong SurfaceChromaVAddress;
public SurfaceOutputConfig(
SurfacePixelFormat pixelFormat,
int surfaceWidth,
int surfaceHeight,
int gobBlockHeight,
ulong outputSurfaceLumaAddress,
ulong outputSurfaceChromaUAddress,
ulong outputSurfaceChromaVAddress)
{
PixelFormat = pixelFormat;
SurfaceWidth = surfaceWidth;
SurfaceHeight = surfaceHeight;
GobBlockHeight = gobBlockHeight;
SurfaceLumaAddress = outputSurfaceLumaAddress;
SurfaceChromaUAddress = outputSurfaceChromaUAddress;
SurfaceChromaVAddress = outputSurfaceChromaVAddress;
}
}
}

View file

@ -0,0 +1,8 @@
namespace Ryujinx.Graphics.Vic
{
enum SurfacePixelFormat
{
Rgba8 = 0x1f,
Yuv420P = 0x44
}
}

View file

@ -0,0 +1,94 @@
using Ryujinx.Graphics.Gpu;
using Ryujinx.Graphics.VDec;
namespace Ryujinx.Graphics.Vic
{
class VideoImageComposer
{
private ulong _configStructAddress;
private ulong _outputSurfaceLumaAddress;
private ulong _outputSurfaceChromaUAddress;
private ulong _outputSurfaceChromaVAddress;
private VideoDecoder _vdec;
public VideoImageComposer(VideoDecoder vdec)
{
_vdec = vdec;
}
public void Process(GpuContext gpu, int methodOffset, int[] arguments)
{
VideoImageComposerMeth method = (VideoImageComposerMeth)methodOffset;
switch (method)
{
case VideoImageComposerMeth.Execute: Execute(gpu); break;
case VideoImageComposerMeth.SetConfigStructOffset: SetConfigStructOffset(arguments); break;
case VideoImageComposerMeth.SetOutputSurfaceLumaOffset: SetOutputSurfaceLumaOffset(arguments); break;
case VideoImageComposerMeth.SetOutputSurfaceChromaUOffset: SetOutputSurfaceChromaUOffset(arguments); break;
case VideoImageComposerMeth.SetOutputSurfaceChromaVOffset: SetOutputSurfaceChromaVOffset(arguments); break;
}
}
private void Execute(GpuContext gpu)
{
StructUnpacker unpacker = new StructUnpacker(gpu.MemoryAccessor, _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);
_vdec.CopyPlanes(gpu, outputConfig);
}
private void SetConfigStructOffset(int[] arguments)
{
_configStructAddress = GetAddress(arguments);
}
private void SetOutputSurfaceLumaOffset(int[] arguments)
{
_outputSurfaceLumaAddress = GetAddress(arguments);
}
private void SetOutputSurfaceChromaUOffset(int[] arguments)
{
_outputSurfaceChromaUAddress = GetAddress(arguments);
}
private void SetOutputSurfaceChromaVOffset(int[] arguments)
{
_outputSurfaceChromaVAddress = GetAddress(arguments);
}
private static ulong GetAddress(int[] arguments)
{
return (ulong)(uint)arguments[0] << 8;
}
}
}

View file

@ -0,0 +1,12 @@
namespace Ryujinx.Graphics.Vic
{
enum VideoImageComposerMeth
{
Execute = 0xc0,
SetControlParams = 0x1c1,
SetConfigStructOffset = 0x1c2,
SetOutputSurfaceLumaOffset = 0x1c8,
SetOutputSurfaceChromaUOffset = 0x1c9,
SetOutputSurfaceChromaVOffset = 0x1ca
}
}