Skip to content

Commit

Permalink
Re-add NVDEC project (not integrated)
Browse files Browse the repository at this point in the history
  • Loading branch information
gdkchan authored and marysaka committed Jan 9, 2020
1 parent 6e092c0 commit 0dbfe3c
Show file tree
Hide file tree
Showing 31 changed files with 2,547 additions and 18 deletions.
2 changes: 1 addition & 1 deletion Ryujinx.Graphics.Gpu/GpuContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public sealed class GpuContext : IDisposable
/// <summary>
/// GPU memory accessor.
/// </summary>
internal MemoryAccessor MemoryAccessor { get; }
public MemoryAccessor MemoryAccessor { get; }

/// <summary>
/// GPU engine methods processing.
Expand Down
37 changes: 36 additions & 1 deletion Ryujinx.Graphics.Gpu/Memory/MemoryAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
/// <summary>
/// GPU mapped memory accessor.
/// </summary>
class MemoryAccessor
public class MemoryAccessor
{
private GpuContext _context;

Expand All @@ -19,6 +19,17 @@ public MemoryAccessor(GpuContext context)
_context = context;
}

/// <summary>
/// Reads a byte array from GPU mapped memory.
/// </summary>
/// <param name="gpuVa">GPU virtual address where the data is located</param>
/// <param name="size">Size of the data in bytes</param>
/// <returns>Byte array with the data</returns>
public byte[] ReadBytes(ulong gpuVa, ulong size)
{
return Read(gpuVa, size).ToArray();
}

/// <summary>
/// Reads data from GPU mapped memory.
/// This reads as much data as possible, up to the specified maximum size.
Expand Down Expand Up @@ -62,6 +73,30 @@ public int ReadInt32(ulong gpuVa)
return BitConverter.ToInt32(_context.PhysicalMemory.Read(processVa, 4));
}

/// <summary>
/// Reads a 64-bits unsigned integer from GPU mapped memory.
/// </summary>
/// <param name="gpuVa">GPU virtual address where the value is located</param>
/// <returns>The value at the specified memory location</returns>
public ulong ReadUInt64(ulong gpuVa)
{
ulong processVa = _context.MemoryManager.Translate(gpuVa);

return BitConverter.ToUInt64(_context.PhysicalMemory.Read(processVa, 8));
}

/// <summary>
/// Reads a 8-bits unsigned integer from GPU mapped memory.
/// </summary>
/// <param name="gpuVa">GPU virtual address where the value is located</param>
/// <param name="value">The value to be written</param>
public void WriteByte(ulong gpuVa, byte value)
{
ulong processVa = _context.MemoryManager.Translate(gpuVa);

_context.PhysicalMemory.Write(processVa, MemoryMarshal.CreateSpan(ref value, 1));
}

/// <summary>
/// Writes a 32-bits signed integer to GPU mapped memory.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ internal ulong GetSubSize(ulong gpuVa)
/// </summary>
/// <param name="gpuVa">GPU virtual address to be translated</param>
/// <returns>CPU virtual address</returns>
internal ulong Translate(ulong gpuVa)
public ulong Translate(ulong gpuVa)
{
ulong baseAddress = GetPte(gpuVa);

Expand Down
103 changes: 103 additions & 0 deletions Ryujinx.Graphics.Nvdec/CdmaProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
using Ryujinx.Graphics.Gpu;
using Ryujinx.Graphics.VDec;
using Ryujinx.Graphics.Vic;
using System.Collections.Generic;

namespace Ryujinx.Graphics
{
public class CdmaProcessor
{
private const int MethSetMethod = 0x10;
private const int MethSetData = 0x11;

private readonly VideoDecoder _videoDecoder;
private readonly VideoImageComposer _videoImageComposer;

public CdmaProcessor()
{
_videoDecoder = new VideoDecoder();
_videoImageComposer = new VideoImageComposer(_videoDecoder);
}

public void PushCommands(GpuContext gpu, int[] cmdBuffer)
{
List<ChCommand> commands = new List<ChCommand>();

ChClassId currentClass = 0;

for (int index = 0; index < cmdBuffer.Length; index++)
{
int cmd = cmdBuffer[index];

int value = (cmd >> 0) & 0xffff;
int methodOffset = (cmd >> 16) & 0xfff;

ChSubmissionMode submissionMode = (ChSubmissionMode)((cmd >> 28) & 0xf);

switch (submissionMode)
{
case ChSubmissionMode.SetClass: currentClass = (ChClassId)(value >> 6); break;

case ChSubmissionMode.Incrementing:
{
int count = value;

for (int argIdx = 0; argIdx < count; argIdx++)
{
int argument = cmdBuffer[++index];

commands.Add(new ChCommand(currentClass, methodOffset + argIdx, argument));
}

break;
}

case ChSubmissionMode.NonIncrementing:
{
int count = value;

int[] arguments = new int[count];

for (int argIdx = 0; argIdx < count; argIdx++)
{
arguments[argIdx] = cmdBuffer[++index];
}

commands.Add(new ChCommand(currentClass, methodOffset, arguments));

break;
}
}
}

ProcessCommands(gpu, commands.ToArray());
}

private void ProcessCommands(GpuContext gpu, ChCommand[] commands)
{
int methodOffset = 0;

foreach (ChCommand command in commands)
{
switch (command.MethodOffset)
{
case MethSetMethod: methodOffset = command.Arguments[0]; break;

case MethSetData:
{
if (command.ClassId == ChClassId.NvDec)
{
_videoDecoder.Process(gpu, methodOffset, command.Arguments);
}
else if (command.ClassId == ChClassId.GraphicsVic)
{
_videoImageComposer.Process(gpu, methodOffset, command.Arguments);
}

break;
}
}
}
}
}
}
20 changes: 20 additions & 0 deletions Ryujinx.Graphics.Nvdec/ChClassId.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace Ryujinx.Graphics
{
enum ChClassId
{
Host1X = 0x1,
VideoEncodeMpeg = 0x20,
VideoEncodeNvEnc = 0x21,
VideoStreamingVi = 0x30,
VideoStreamingIsp = 0x32,
VideoStreamingIspB = 0x34,
VideoStreamingViI2c = 0x36,
GraphicsVic = 0x5d,
Graphics3D = 0x60,
GraphicsGpu = 0x61,
Tsec = 0xe0,
TsecB = 0xe1,
NvJpg = 0xc0,
NvDec = 0xf0
}
}
18 changes: 18 additions & 0 deletions Ryujinx.Graphics.Nvdec/ChCommandEntry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Ryujinx.Graphics
{
struct ChCommand
{
public ChClassId ClassId { get; private set; }

public int MethodOffset { get; private set; }

public int[] Arguments { get; private set; }

public ChCommand(ChClassId classId, int methodOffset, params int[] arguments)
{
ClassId = classId;
MethodOffset = methodOffset;
Arguments = arguments;
}
}
}
13 changes: 13 additions & 0 deletions Ryujinx.Graphics.Nvdec/ChSubmissionMode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Ryujinx.Graphics
{
enum ChSubmissionMode
{
SetClass = 0,
Incrementing = 1,
NonIncrementing = 2,
Mask = 3,
Immediate = 4,
Restart = 5,
Gather = 6
}
}
23 changes: 23 additions & 0 deletions Ryujinx.Graphics.Nvdec/Ryujinx.Graphics.Nvdec.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FFmpeg.AutoGen" Version="4.2.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
</ItemGroup>

</Project>
75 changes: 75 additions & 0 deletions Ryujinx.Graphics.Nvdec/VDec/BitStreamWriter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System.IO;

namespace Ryujinx.Graphics.VDec
{
class BitStreamWriter
{
private const int BufferSize = 8;

private Stream _baseStream;

private int _buffer;
private int _bufferPos;

public BitStreamWriter(Stream baseStream)
{
_baseStream = baseStream;
}

public void WriteBit(bool value)
{
WriteBits(value ? 1 : 0, 1);
}

public void WriteBits(int value, int valueSize)
{
int valuePos = 0;

int remaining = valueSize;

while (remaining > 0)
{
int copySize = remaining;

int free = GetFreeBufferBits();

if (copySize > free)
{
copySize = free;
}

int mask = (1 << copySize) - 1;

int srcShift = (valueSize - valuePos) - copySize;
int dstShift = (BufferSize - _bufferPos) - copySize;

_buffer |= ((value >> srcShift) & mask) << dstShift;

valuePos += copySize;
_bufferPos += copySize;
remaining -= copySize;
}
}

private int GetFreeBufferBits()
{
if (_bufferPos == BufferSize)
{
Flush();
}

return BufferSize - _bufferPos;
}

public void Flush()
{
if (_bufferPos != 0)
{
_baseStream.WriteByte((byte)_buffer);

_buffer = 0;
_bufferPos = 0;
}
}
}
}
17 changes: 17 additions & 0 deletions Ryujinx.Graphics.Nvdec/VDec/DecoderHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;

namespace Ryujinx.Graphics.VDec
{
static class DecoderHelper
{
public static byte[] Combine(byte[] arr0, byte[] arr1)
{
byte[] output = new byte[arr0.Length + arr1.Length];

Buffer.BlockCopy(arr0, 0, output, 0, arr0.Length);
Buffer.BlockCopy(arr1, 0, output, arr0.Length, arr1.Length);

return output;
}
}
}
Loading

0 comments on commit 0dbfe3c

Please sign in to comment.