Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New NVDEC and VIC implementation #1384

Merged
merged 25 commits into from Jul 12, 2020
Merged
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
870ee49
Initial NVDEC and VIC implementation
gdkchan Jun 28, 2020
95d3b9c
Update FFmpeg.AutoGen to 4.3.0
Thog Jun 28, 2020
1b95924
Add nvdec dependencies for Windows
Thog Jun 28, 2020
962dda9
Unify some VP9 structures
gdkchan Jun 28, 2020
66158d1
Rename VP9 structure fields
gdkchan Jun 28, 2020
4d91216
Improvements to Video API
gdkchan Jun 29, 2020
b3be0f0
XML docs for Common.Memory
gdkchan Jun 29, 2020
c689823
Remove now unused or redundant overloads from MemoryAccessor
gdkchan Jun 29, 2020
a1c596c
NVDEC UV surface read/write scalar paths
gdkchan Jun 29, 2020
691beb5
Add FIXME comments about hacky things/stuff that will need to be fixe…
gdkchan Jun 29, 2020
e292762
Cleaned up VP9 memory allocation
gdkchan Jun 30, 2020
c82d012
Remove some debug logs
gdkchan Jun 30, 2020
cdaa07e
Rename some VP9 structs
gdkchan Jun 30, 2020
7f42c6e
Remove unused struct
gdkchan Jun 30, 2020
54b0eaf
No need to compile Ryujinx.Graphics.Host1x with unsafe anymore
gdkchan Jul 3, 2020
b34d575
Name AsyncWorkQueue threads to make debugging easier
gdkchan Jul 4, 2020
ff9c8ae
Make Vp9PictureInfo a ref struct
gdkchan Jul 4, 2020
50d8b6c
LayoutConverter no longer needs the depth argument (broken by rebase)
gdkchan Jul 4, 2020
978745f
Pooling of VP9 buffers, plus fix a memory leak on VP9
gdkchan Jul 6, 2020
6d3fc85
Really wish VS could rename projects properly...
gdkchan Jul 6, 2020
32b373f
Address feedback
gdkchan Jul 10, 2020
924504d
Remove using
gdkchan Jul 10, 2020
cecffcb
Catch OperationCanceledException
gdkchan Jul 11, 2020
82ebd3a
Add licensing informations
Thog Jul 12, 2020
5ad2af0
Add THIRDPARTY.md to release too
Thog Jul 12, 2020
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -112,3 +112,9 @@ If you need help with setting up Ryujinx, you can ask questions in the #support
If you have contributions, need support, have suggestions, or just want to get in touch with the team, join our [Discord server](https://discord.gg/N2FmfVc)!

If you'd like to donate, please take a look at our [Patreon](https://www.patreon.com/ryujinx).

## License

This software is licensed under the terms of the MIT license.
This project makes use of code authored by the libvpx project, licensed under BSD and the ffmpeg project, licensed under LGPLv3.
See [LICENSE.txt](LICENSE.txt) and [THIRDPARTY.md](Ryujinx/THIRDPARTY.md) for more details.
@@ -0,0 +1,100 @@
using System;
using System.Collections.Concurrent;
using System.Threading;

namespace Ryujinx.Common
{
public sealed class AsyncWorkQueue<T> : IDisposable
{
private readonly Thread _workerThread;
private readonly CancellationTokenSource _cts;
private readonly Action<T> _workerAction;
private readonly BlockingCollection<T> _queue;

public bool IsCancellationRequested => _cts.IsCancellationRequested;

public AsyncWorkQueue(Action<T> callback, string name = null) : this(callback, name, new BlockingCollection<T>())
{
}

public AsyncWorkQueue(Action<T> callback, string name, BlockingCollection<T> collection)
{
_cts = new CancellationTokenSource();
_queue = collection;
_workerAction = callback;
_workerThread = new Thread(DoWork) { Name = name };

_workerThread.IsBackground = true;
_workerThread.Start();
}

private void DoWork()
{
try
{
foreach (var item in _queue.GetConsumingEnumerable(_cts.Token))
{
_workerAction(item);
}
}
catch (OperationCanceledException)
{
}
}

public void Cancel()
{
_cts.Cancel();
}

public void CancelAfter(int millisecondsDelay)
{
_cts.CancelAfter(millisecondsDelay);
}

public void CancelAfter(TimeSpan delay)
{
_cts.CancelAfter(delay);
}

public void Add(T workItem)
{
_queue.Add(workItem);
}

public void Add(T workItem, CancellationToken cancellationToken)
{
_queue.Add(workItem, cancellationToken);
}

public bool TryAdd(T workItem)
{
return _queue.TryAdd(workItem);
}

public bool TryAdd(T workItem, int millisecondsDelay)
{
return _queue.TryAdd(workItem, millisecondsDelay);
}

public bool TryAdd(T workItem, int millisecondsDelay, CancellationToken cancellationToken)
{
return _queue.TryAdd(workItem, millisecondsDelay, cancellationToken);
}

public bool TryAdd(T workItem, TimeSpan timeout)
{
return _queue.TryAdd(workItem, timeout);
}

public void Dispose()
{
_queue.CompleteAdding();
_cts.Cancel();
_workerThread.Join();

_queue.Dispose();
_cts.Dispose();
}
}
}
@@ -9,12 +9,14 @@ public enum LogClass
Emulation,
Gpu,
Hid,
Host1x,
Kernel,
KernelIpc,
KernelScheduler,
KernelSvc,
Loader,
ModLoader,
Nvdec,
Ptc,
Service,
ServiceAcc,
@@ -50,6 +52,7 @@ public enum LogClass
ServiceSss,
ServiceTime,
ServiceVi,
SurfaceFlinger
SurfaceFlinger,
Vic
}
}
@@ -0,0 +1,123 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace Ryujinx.Common.Memory
{
/// <summary>
/// Represents an array of unmanaged resources.
/// </summary>
/// <typeparam name="T">Array element type</typeparam>
public unsafe struct ArrayPtr<T> : IEquatable<ArrayPtr<T>>, IArray<T> where T : unmanaged
{
private IntPtr _ptr;

/// <summary>
/// Null pointer.
/// </summary>
public static ArrayPtr<T> Null => new ArrayPtr<T>() { _ptr = IntPtr.Zero };

/// <summary>
/// True if the pointer is null, false otherwise.
/// </summary>
public bool IsNull => _ptr == IntPtr.Zero;

/// <summary>
/// Number of elements on the array.
/// </summary>
public int Length { get; }

/// <summary>
/// Gets a reference to the item at the given index.
/// </summary>
/// <remarks>
/// No bounds checks are performed, this allows negative indexing,
/// but care must be taken if the index may be out of bounds.
/// </remarks>
/// <param name="index">Index of the element</param>
/// <returns>Reference to the element at the given index</returns>
public ref T this[int index] => ref Unsafe.AsRef<T>((T*)_ptr + index);

/// <summary>
/// Creates a new array from a given reference.
/// </summary>
/// <remarks>
/// For data on the heap, proper pinning is necessary during
/// use. Failure to do so will result in memory corruption and crashes.
/// </remarks>
/// <param name="value">Reference of the first array element</param>
/// <param name="length">Number of elements on the array</param>
public ArrayPtr(ref T value, int length)
{
_ptr = (IntPtr)Unsafe.AsPointer(ref value);
Length = length;
}

/// <summary>
/// Creates a new array from a given pointer.
/// </summary>
/// <param name="ptr">Array base pointer</param>
/// <param name="length">Number of elements on the array</param>
public ArrayPtr(T* ptr, int length)
{
_ptr = (IntPtr)ptr;
Length = length;
}

/// <summary>
/// Creates a new array from a given pointer.
/// </summary>
/// <param name="ptr">Array base pointer</param>
/// <param name="length">Number of elements on the array</param>
public ArrayPtr(IntPtr ptr, int length)
{
_ptr = ptr;
Length = length;
}

/// <summary>
/// Splits the array starting at the specified position.
/// </summary>
/// <param name="start">Index where the new array should start</param>
/// <returns>New array starting at the specified position</returns>
public ArrayPtr<T> Slice(int start) => new ArrayPtr<T>(ref this[start], Length - start);

/// <summary>
/// Gets a span from the array.
/// </summary>
/// <returns>Span of the array</returns>
public Span<T> ToSpan() => Length == 0 ? Span<T>.Empty : MemoryMarshal.CreateSpan(ref this[0], Length);

/// <summary>
/// Gets the array base pointer.
/// </summary>
/// <returns>Base pointer</returns>
public T* ToPointer() => (T*)_ptr;

public override bool Equals(object obj)
{
return obj is ArrayPtr<T> other && Equals(other);
}

public bool Equals([AllowNull] ArrayPtr<T> other)
{
return _ptr == other._ptr && Length == other.Length;
}

public override int GetHashCode()
{
return HashCode.Combine(_ptr, Length);
}

public static bool operator ==(ArrayPtr<T> left, ArrayPtr<T> right)
{
return left.Equals(right);
}

public static bool operator !=(ArrayPtr<T> left, ArrayPtr<T> right)
{
return !(left == right);
}
}
}
@@ -0,0 +1,21 @@
namespace Ryujinx.Common.Memory
{
/// <summary>
/// Array interface.
/// </summary>
/// <typeparam name="T">Element type</typeparam>
public interface IArray<T> where T : unmanaged
{
/// <summary>
/// Used to index the array.
/// </summary>
/// <param name="index">Element index</param>
/// <returns>Element at the specified index</returns>
ref T this[int index] { get; }

/// <summary>
/// Number of elements on the array.
/// </summary>
int Length { get; }
}
}
@@ -0,0 +1,68 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;

namespace Ryujinx.Common.Memory
{
/// <summary>
/// Represents a pointer to an unmanaged resource.
/// </summary>
/// <typeparam name="T">Type of the unmanaged resource</typeparam>
public unsafe struct Ptr<T> : IEquatable<Ptr<T>> where T : unmanaged
{
private IntPtr _ptr;

/// <summary>
/// Null pointer.
/// </summary>
public static Ptr<T> Null => new Ptr<T>() { _ptr = IntPtr.Zero };

/// <summary>
/// True if the pointer is null, false otherwise.
/// </summary>
public bool IsNull => _ptr == IntPtr.Zero;

/// <summary>
/// Gets a reference to the value.
/// </summary>
public ref T Value => ref Unsafe.AsRef<T>((void*)_ptr);

/// <summary>
/// Creates a new pointer to an unmanaged resource.
/// </summary>
/// <remarks>
/// For data on the heap, proper pinning is necessary during
/// use. Failure to do so will result in memory corruption and crashes.
/// </remarks>
/// <param name="value">Reference to the unmanaged resource</param>
public Ptr(ref T value)
{
_ptr = (IntPtr)Unsafe.AsPointer(ref value);
}

public override bool Equals(object obj)
{
return obj is Ptr<T> other && Equals(other);
}

public bool Equals([AllowNull] Ptr<T> other)
{
return _ptr == other._ptr;
}

public override int GetHashCode()
{
return _ptr.GetHashCode();
}

public static bool operator ==(Ptr<T> left, Ptr<T> right)
{
return left.Equals(right);
}

public static bool operator !=(Ptr<T> left, Ptr<T> right)
{
return !(left == right);
}
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.