From 4d02a2d2c0451b4de1f6de3bbce54c457cacebe2 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 12 Jul 2020 00:07:01 -0300 Subject: New NVDEC and VIC implementation (#1384) * Initial NVDEC and VIC implementation * Update FFmpeg.AutoGen to 4.3.0 * Add nvdec dependencies for Windows * Unify some VP9 structures * Rename VP9 structure fields * Improvements to Video API * XML docs for Common.Memory * Remove now unused or redundant overloads from MemoryAccessor * NVDEC UV surface read/write scalar paths * Add FIXME comments about hacky things/stuff that will need to be fixed in the future * Cleaned up VP9 memory allocation * Remove some debug logs * Rename some VP9 structs * Remove unused struct * No need to compile Ryujinx.Graphics.Host1x with unsafe anymore * Name AsyncWorkQueue threads to make debugging easier * Make Vp9PictureInfo a ref struct * LayoutConverter no longer needs the depth argument (broken by rebase) * Pooling of VP9 buffers, plus fix a memory leak on VP9 * Really wish VS could rename projects properly... * Address feedback * Remove using * Catch OperationCanceledException * Add licensing informations * Add THIRDPARTY.md to release too Co-authored-by: Thog --- Ryujinx.Common/Memory/ArrayPtr.cs | 123 +++++++ Ryujinx.Common/Memory/IArray.cs | 21 ++ Ryujinx.Common/Memory/Ptr.cs | 68 ++++ Ryujinx.Common/Memory/StructArrayHelpers.cs | 518 ++++++++++++++++++++++++++++ 4 files changed, 730 insertions(+) create mode 100644 Ryujinx.Common/Memory/ArrayPtr.cs create mode 100644 Ryujinx.Common/Memory/IArray.cs create mode 100644 Ryujinx.Common/Memory/Ptr.cs create mode 100644 Ryujinx.Common/Memory/StructArrayHelpers.cs (limited to 'Ryujinx.Common/Memory') diff --git a/Ryujinx.Common/Memory/ArrayPtr.cs b/Ryujinx.Common/Memory/ArrayPtr.cs new file mode 100644 index 00000000..7a145de2 --- /dev/null +++ b/Ryujinx.Common/Memory/ArrayPtr.cs @@ -0,0 +1,123 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Ryujinx.Common.Memory +{ + /// + /// Represents an array of unmanaged resources. + /// + /// Array element type + public unsafe struct ArrayPtr : IEquatable>, IArray where T : unmanaged + { + private IntPtr _ptr; + + /// + /// Null pointer. + /// + public static ArrayPtr Null => new ArrayPtr() { _ptr = IntPtr.Zero }; + + /// + /// True if the pointer is null, false otherwise. + /// + public bool IsNull => _ptr == IntPtr.Zero; + + /// + /// Number of elements on the array. + /// + public int Length { get; } + + /// + /// Gets a reference to the item at the given index. + /// + /// + /// No bounds checks are performed, this allows negative indexing, + /// but care must be taken if the index may be out of bounds. + /// + /// Index of the element + /// Reference to the element at the given index + public ref T this[int index] => ref Unsafe.AsRef((T*)_ptr + index); + + /// + /// Creates a new array from a given reference. + /// + /// + /// For data on the heap, proper pinning is necessary during + /// use. Failure to do so will result in memory corruption and crashes. + /// + /// Reference of the first array element + /// Number of elements on the array + public ArrayPtr(ref T value, int length) + { + _ptr = (IntPtr)Unsafe.AsPointer(ref value); + Length = length; + } + + /// + /// Creates a new array from a given pointer. + /// + /// Array base pointer + /// Number of elements on the array + public ArrayPtr(T* ptr, int length) + { + _ptr = (IntPtr)ptr; + Length = length; + } + + /// + /// Creates a new array from a given pointer. + /// + /// Array base pointer + /// Number of elements on the array + public ArrayPtr(IntPtr ptr, int length) + { + _ptr = ptr; + Length = length; + } + + /// + /// Splits the array starting at the specified position. + /// + /// Index where the new array should start + /// New array starting at the specified position + public ArrayPtr Slice(int start) => new ArrayPtr(ref this[start], Length - start); + + /// + /// Gets a span from the array. + /// + /// Span of the array + public Span ToSpan() => Length == 0 ? Span.Empty : MemoryMarshal.CreateSpan(ref this[0], Length); + + /// + /// Gets the array base pointer. + /// + /// Base pointer + public T* ToPointer() => (T*)_ptr; + + public override bool Equals(object obj) + { + return obj is ArrayPtr other && Equals(other); + } + + public bool Equals([AllowNull] ArrayPtr other) + { + return _ptr == other._ptr && Length == other.Length; + } + + public override int GetHashCode() + { + return HashCode.Combine(_ptr, Length); + } + + public static bool operator ==(ArrayPtr left, ArrayPtr right) + { + return left.Equals(right); + } + + public static bool operator !=(ArrayPtr left, ArrayPtr right) + { + return !(left == right); + } + } +} diff --git a/Ryujinx.Common/Memory/IArray.cs b/Ryujinx.Common/Memory/IArray.cs new file mode 100644 index 00000000..8f17fade --- /dev/null +++ b/Ryujinx.Common/Memory/IArray.cs @@ -0,0 +1,21 @@ +namespace Ryujinx.Common.Memory +{ + /// + /// Array interface. + /// + /// Element type + public interface IArray where T : unmanaged + { + /// + /// Used to index the array. + /// + /// Element index + /// Element at the specified index + ref T this[int index] { get; } + + /// + /// Number of elements on the array. + /// + int Length { get; } + } +} diff --git a/Ryujinx.Common/Memory/Ptr.cs b/Ryujinx.Common/Memory/Ptr.cs new file mode 100644 index 00000000..66bcf569 --- /dev/null +++ b/Ryujinx.Common/Memory/Ptr.cs @@ -0,0 +1,68 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; + +namespace Ryujinx.Common.Memory +{ + /// + /// Represents a pointer to an unmanaged resource. + /// + /// Type of the unmanaged resource + public unsafe struct Ptr : IEquatable> where T : unmanaged + { + private IntPtr _ptr; + + /// + /// Null pointer. + /// + public static Ptr Null => new Ptr() { _ptr = IntPtr.Zero }; + + /// + /// True if the pointer is null, false otherwise. + /// + public bool IsNull => _ptr == IntPtr.Zero; + + /// + /// Gets a reference to the value. + /// + public ref T Value => ref Unsafe.AsRef((void*)_ptr); + + /// + /// Creates a new pointer to an unmanaged resource. + /// + /// + /// For data on the heap, proper pinning is necessary during + /// use. Failure to do so will result in memory corruption and crashes. + /// + /// Reference to the unmanaged resource + public Ptr(ref T value) + { + _ptr = (IntPtr)Unsafe.AsPointer(ref value); + } + + public override bool Equals(object obj) + { + return obj is Ptr other && Equals(other); + } + + public bool Equals([AllowNull] Ptr other) + { + return _ptr == other._ptr; + } + + public override int GetHashCode() + { + return _ptr.GetHashCode(); + } + + public static bool operator ==(Ptr left, Ptr right) + { + return left.Equals(right); + } + + public static bool operator !=(Ptr left, Ptr right) + { + return !(left == right); + } + } +} diff --git a/Ryujinx.Common/Memory/StructArrayHelpers.cs b/Ryujinx.Common/Memory/StructArrayHelpers.cs new file mode 100644 index 00000000..eb8d3ce1 --- /dev/null +++ b/Ryujinx.Common/Memory/StructArrayHelpers.cs @@ -0,0 +1,518 @@ +using System; +using System.Runtime.InteropServices; + +namespace Ryujinx.Common.Memory +{ + public struct Array1 : IArray where T : unmanaged + { + T _e0; + public int Length => 1; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 1); + } + public struct Array2 : IArray where T : unmanaged + { + T _e0; + Array1 _other; + public int Length => 2; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 2); + } + public struct Array3 : IArray where T : unmanaged + { + T _e0; + Array2 _other; + public int Length => 3; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 3); + } + public struct Array4 : IArray where T : unmanaged + { + T _e0; + Array3 _other; + public int Length => 4; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 4); + } + public struct Array5 : IArray where T : unmanaged + { + T _e0; + Array4 _other; + public int Length => 5; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 5); + } + public struct Array6 : IArray where T : unmanaged + { + T _e0; + Array5 _other; + public int Length => 6; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 6); + } + public struct Array7 : IArray where T : unmanaged + { + T _e0; + Array6 _other; + public int Length => 7; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 7); + } + public struct Array8 : IArray where T : unmanaged + { + T _e0; + Array7 _other; + public int Length => 8; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 8); + } + public struct Array9 : IArray where T : unmanaged + { + T _e0; + Array8 _other; + public int Length => 9; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 9); + } + public struct Array10 : IArray where T : unmanaged + { + T _e0; + Array9 _other; + public int Length => 10; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 10); + } + public struct Array11 : IArray where T : unmanaged + { + T _e0; + Array10 _other; + public int Length => 11; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 11); + } + public struct Array12 : IArray where T : unmanaged + { + T _e0; + Array11 _other; + public int Length => 12; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 12); + } + public struct Array13 : IArray where T : unmanaged + { + T _e0; + Array12 _other; + public int Length => 13; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 13); + } + public struct Array14 : IArray where T : unmanaged + { + T _e0; + Array13 _other; + public int Length => 14; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 14); + } + public struct Array15 : IArray where T : unmanaged + { + T _e0; + Array14 _other; + public int Length => 15; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 15); + } + public struct Array16 : IArray where T : unmanaged + { + T _e0; + Array15 _other; + public int Length => 16; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 16); + } + public struct Array17 : IArray where T : unmanaged + { + T _e0; + Array16 _other; + public int Length => 17; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 17); + } + public struct Array18 : IArray where T : unmanaged + { + T _e0; + Array17 _other; + public int Length => 18; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 18); + } + public struct Array19 : IArray where T : unmanaged + { + T _e0; + Array18 _other; + public int Length => 19; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 19); + } + public struct Array20 : IArray where T : unmanaged + { + T _e0; + Array19 _other; + public int Length => 20; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 20); + } + public struct Array21 : IArray where T : unmanaged + { + T _e0; + Array20 _other; + public int Length => 21; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 21); + } + public struct Array22 : IArray where T : unmanaged + { + T _e0; + Array21 _other; + public int Length => 22; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 22); + } + public struct Array23 : IArray where T : unmanaged + { + T _e0; + Array22 _other; + public int Length => 23; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 23); + } + public struct Array24 : IArray where T : unmanaged + { + T _e0; + Array23 _other; + public int Length => 24; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 24); + } + public struct Array25 : IArray where T : unmanaged + { + T _e0; + Array24 _other; + public int Length => 25; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 25); + } + public struct Array26 : IArray where T : unmanaged + { + T _e0; + Array25 _other; + public int Length => 26; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 26); + } + public struct Array27 : IArray where T : unmanaged + { + T _e0; + Array26 _other; + public int Length => 27; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 27); + } + public struct Array28 : IArray where T : unmanaged + { + T _e0; + Array27 _other; + public int Length => 28; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 28); + } + public struct Array29 : IArray where T : unmanaged + { + T _e0; + Array28 _other; + public int Length => 29; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 29); + } + public struct Array30 : IArray where T : unmanaged + { + T _e0; + Array29 _other; + public int Length => 30; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 30); + } + public struct Array31 : IArray where T : unmanaged + { + T _e0; + Array30 _other; + public int Length => 31; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 31); + } + public struct Array32 : IArray where T : unmanaged + { + T _e0; + Array31 _other; + public int Length => 32; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 32); + } + public struct Array33 : IArray where T : unmanaged + { + T _e0; + Array32 _other; + public int Length => 33; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 33); + } + public struct Array34 : IArray where T : unmanaged + { + T _e0; + Array33 _other; + public int Length => 34; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 34); + } + public struct Array35 : IArray where T : unmanaged + { + T _e0; + Array34 _other; + public int Length => 35; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 35); + } + public struct Array36 : IArray where T : unmanaged + { + T _e0; + Array35 _other; + public int Length => 36; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 36); + } + public struct Array37 : IArray where T : unmanaged + { + T _e0; + Array36 _other; + public int Length => 37; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 37); + } + public struct Array38 : IArray where T : unmanaged + { + T _e0; + Array37 _other; + public int Length => 38; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 38); + } + public struct Array39 : IArray where T : unmanaged + { + T _e0; + Array38 _other; + public int Length => 39; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 39); + } + public struct Array40 : IArray where T : unmanaged + { + T _e0; + Array39 _other; + public int Length => 40; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 40); + } + public struct Array41 : IArray where T : unmanaged + { + T _e0; + Array40 _other; + public int Length => 41; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 41); + } + public struct Array42 : IArray where T : unmanaged + { + T _e0; + Array41 _other; + public int Length => 42; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 42); + } + public struct Array43 : IArray where T : unmanaged + { + T _e0; + Array42 _other; + public int Length => 43; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 43); + } + public struct Array44 : IArray where T : unmanaged + { + T _e0; + Array43 _other; + public int Length => 44; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 44); + } + public struct Array45 : IArray where T : unmanaged + { + T _e0; + Array44 _other; + public int Length => 45; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 45); + } + public struct Array46 : IArray where T : unmanaged + { + T _e0; + Array45 _other; + public int Length => 46; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 46); + } + public struct Array47 : IArray where T : unmanaged + { + T _e0; + Array46 _other; + public int Length => 47; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 47); + } + public struct Array48 : IArray where T : unmanaged + { + T _e0; + Array47 _other; + public int Length => 48; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 48); + } + public struct Array49 : IArray where T : unmanaged + { + T _e0; + Array48 _other; + public int Length => 49; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 49); + } + public struct Array50 : IArray where T : unmanaged + { + T _e0; + Array49 _other; + public int Length => 50; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 50); + } + public struct Array51 : IArray where T : unmanaged + { + T _e0; + Array50 _other; + public int Length => 51; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 51); + } + public struct Array52 : IArray where T : unmanaged + { + T _e0; + Array51 _other; + public int Length => 52; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 52); + } + public struct Array53 : IArray where T : unmanaged + { + T _e0; + Array52 _other; + public int Length => 53; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 53); + } + public struct Array54 : IArray where T : unmanaged + { + T _e0; + Array53 _other; + public int Length => 54; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 54); + } + public struct Array55 : IArray where T : unmanaged + { + T _e0; + Array54 _other; + public int Length => 55; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 55); + } + public struct Array56 : IArray where T : unmanaged + { + T _e0; + Array55 _other; + public int Length => 56; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 56); + } + public struct Array57 : IArray where T : unmanaged + { + T _e0; + Array56 _other; + public int Length => 57; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 57); + } + public struct Array58 : IArray where T : unmanaged + { + T _e0; + Array57 _other; + public int Length => 58; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 58); + } + public struct Array59 : IArray where T : unmanaged + { + T _e0; + Array58 _other; + public int Length => 59; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 59); + } + public struct Array60 : IArray where T : unmanaged + { + T _e0; + Array59 _other; + public int Length => 60; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 60); + } + public struct Array61 : IArray where T : unmanaged + { + T _e0; + Array60 _other; + public int Length => 61; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 61); + } + public struct Array62 : IArray where T : unmanaged + { + T _e0; + Array61 _other; + public int Length => 62; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 62); + } + public struct Array63 : IArray where T : unmanaged + { + T _e0; + Array62 _other; + public int Length => 63; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 63); + } + public struct Array64 : IArray where T : unmanaged + { + T _e0; + Array63 _other; + public int Length => 64; + public ref T this[int index] => ref ToSpan()[index]; + public Span ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 64); + } + +} -- cgit v1.2.3