nvdec: Adding Vp8 codec support (#2707)
* first try * second try * working update * Final impl * Fixes nits * Fix everything * remove leftover * Update FFmpegContext.cs * Update Surface.cs * Addresses gdkchan feedback * bool not byte * Addresses gdkchan feedback
This commit is contained in:
parent
a7109c767b
commit
d1604aa762
16 changed files with 220 additions and 35 deletions
|
@ -5,27 +5,26 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.H264
|
||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
||||
{
|
||||
unsafe class FFmpegContext : IDisposable
|
||||
{
|
||||
private readonly AVCodec_decode _h264Decode;
|
||||
private readonly AVCodec_decode _decodeFrame;
|
||||
private static readonly av_log_set_callback_callback _logFunc;
|
||||
private readonly AVCodec* _codec;
|
||||
private AVPacket* _packet;
|
||||
private AVCodecContext* _context;
|
||||
|
||||
public FFmpegContext()
|
||||
public FFmpegContext(AVCodecID codecId)
|
||||
{
|
||||
_codec = ffmpeg.avcodec_find_decoder(AVCodecID.AV_CODEC_ID_H264);
|
||||
_codec = ffmpeg.avcodec_find_decoder(codecId);
|
||||
_context = ffmpeg.avcodec_alloc_context3(_codec);
|
||||
_context->debug |= ffmpeg.FF_DEBUG_MMCO;
|
||||
|
||||
ffmpeg.avcodec_open2(_context, _codec, null);
|
||||
|
||||
_packet = ffmpeg.av_packet_alloc();
|
||||
|
||||
_h264Decode = Marshal.GetDelegateForFunctionPointer<AVCodec_decode>(_codec->decode.Pointer);
|
||||
_decodeFrame = Marshal.GetDelegateForFunctionPointer<AVCodec_decode>(_codec->decode.Pointer);
|
||||
}
|
||||
|
||||
static FFmpegContext()
|
||||
|
@ -115,7 +114,7 @@ namespace Ryujinx.Graphics.Nvdec.H264
|
|||
{
|
||||
_packet->data = ptr;
|
||||
_packet->size = bitstream.Length;
|
||||
result = _h264Decode(_context, output.Frame, &gotFrame, _packet);
|
||||
result = _decodeFrame(_context, output.Frame, &gotFrame, _packet);
|
||||
}
|
||||
|
||||
if (gotFrame == 0)
|
||||
|
@ -126,7 +125,7 @@ namespace Ryujinx.Graphics.Nvdec.H264
|
|||
// Get the next delayed frame by passing a 0 length packet.
|
||||
_packet->data = null;
|
||||
_packet->size = 0;
|
||||
result = _h264Decode(_context, output.Frame, &gotFrame, _packet);
|
||||
result = _decodeFrame(_context, output.Frame, &gotFrame, _packet);
|
||||
|
||||
// We need to set B frames to 0 as we already consumed all delayed frames.
|
||||
// This prevents the decoder from trying to return a delayed frame next time.
|
||||
|
@ -138,6 +137,7 @@ namespace Ryujinx.Graphics.Nvdec.H264
|
|||
if (gotFrame == 0)
|
||||
{
|
||||
ffmpeg.av_frame_unref(output.Frame);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
using Ryujinx.Graphics.Video;
|
||||
using FFmpeg.AutoGen;
|
||||
using Ryujinx.Graphics.Video;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.H264
|
||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.H264
|
||||
{
|
||||
public sealed class Decoder : IH264Decoder
|
||||
{
|
||||
|
@ -11,7 +12,7 @@ namespace Ryujinx.Graphics.Nvdec.H264
|
|||
|
||||
private readonly byte[] _workBuffer = new byte[WorkBufferSize];
|
||||
|
||||
private FFmpegContext _context = new FFmpegContext();
|
||||
private FFmpegContext _context = new FFmpegContext(AVCodecID.AV_CODEC_ID_H264);
|
||||
|
||||
private int _oldOutputWidth;
|
||||
private int _oldOutputHeight;
|
||||
|
@ -29,7 +30,7 @@ namespace Ryujinx.Graphics.Nvdec.H264
|
|||
outSurf.RequestedHeight != _oldOutputHeight)
|
||||
{
|
||||
_context.Dispose();
|
||||
_context = new FFmpegContext();
|
||||
_context = new FFmpegContext(AVCodecID.AV_CODEC_ID_H264);
|
||||
|
||||
_oldOutputWidth = outSurf.RequestedWidth;
|
||||
_oldOutputHeight = outSurf.RequestedHeight;
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.H264
|
||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.H264
|
||||
{
|
||||
struct H264BitStreamWriter
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
using Ryujinx.Graphics.Video;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.H264
|
||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.H264
|
||||
{
|
||||
static class SpsAndPpsReconstruction
|
||||
{
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
|
@ -6,10 +6,11 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FFmpeg.AutoGen" Version="4.4.0" />
|
||||
<PackageReference Include="FFmpeg.AutoGen" Version="4.4.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
|
||||
<ProjectReference Include="..\Ryujinx.Graphics.Video\Ryujinx.Graphics.Video.csproj" />
|
||||
</ItemGroup>
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
using Ryujinx.Graphics.Video;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.H264
|
||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
||||
{
|
||||
unsafe class Surface : ISurface
|
||||
{
|
53
Ryujinx.Graphics.Nvdec.FFmpeg/Vp8/Decoder.cs
Normal file
53
Ryujinx.Graphics.Nvdec.FFmpeg/Vp8/Decoder.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
using FFmpeg.AutoGen;
|
||||
using Ryujinx.Graphics.Video;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Vp8
|
||||
{
|
||||
public sealed class Decoder : IDecoder
|
||||
{
|
||||
public bool IsHardwareAccelerated => false;
|
||||
|
||||
private readonly FFmpegContext _context = new FFmpegContext(AVCodecID.AV_CODEC_ID_VP8);
|
||||
|
||||
public ISurface CreateSurface(int width, int height)
|
||||
{
|
||||
return new Surface(width, height);
|
||||
}
|
||||
|
||||
public bool Decode(ref Vp8PictureInfo pictureInfo, ISurface output, ReadOnlySpan<byte> bitstream)
|
||||
{
|
||||
Surface outSurf = (Surface)output;
|
||||
|
||||
int uncompHeaderSize = pictureInfo.KeyFrame ? 10 : 3;
|
||||
|
||||
byte[] frame = new byte[bitstream.Length + uncompHeaderSize];
|
||||
|
||||
uint firstPartSizeShifted = pictureInfo.FirstPartSize << 5;
|
||||
|
||||
frame[0] = (byte)(pictureInfo.KeyFrame ? 0 : 1);
|
||||
frame[0] |= (byte)((pictureInfo.Version & 7) << 1);
|
||||
frame[0] |= 1 << 4;
|
||||
frame[0] |= (byte)firstPartSizeShifted;
|
||||
frame[1] |= (byte)(firstPartSizeShifted >> 8);
|
||||
frame[2] |= (byte)(firstPartSizeShifted >> 16);
|
||||
|
||||
if (pictureInfo.KeyFrame)
|
||||
{
|
||||
frame[3] = 0x9d;
|
||||
frame[4] = 0x01;
|
||||
frame[5] = 0x2a;
|
||||
frame[6] = (byte)pictureInfo.FrameWidth;
|
||||
frame[7] = (byte)((pictureInfo.FrameWidth >> 8) & 0x3F);
|
||||
frame[8] = (byte)pictureInfo.FrameHeight;
|
||||
frame[9] = (byte)((pictureInfo.FrameHeight >> 8) & 0x3F);
|
||||
}
|
||||
|
||||
bitstream.CopyTo(new Span<byte>(frame).Slice(uncompHeaderSize));
|
||||
|
||||
return _context.DecodeFrame(outSurf, frame) == 0;
|
||||
}
|
||||
|
||||
public void Dispose() => _context.Dispose();
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
using Ryujinx.Graphics.Nvdec.H264;
|
||||
using Ryujinx.Graphics.Nvdec.FFmpeg.H264;
|
||||
using Ryujinx.Graphics.Nvdec.Image;
|
||||
using Ryujinx.Graphics.Nvdec.Types.H264;
|
||||
using Ryujinx.Graphics.Video;
|
||||
|
@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Nvdec
|
|||
{
|
||||
private const int MbSizeInPixels = 16;
|
||||
|
||||
public unsafe static void Decode(NvdecDecoderContext context, ResourceManager rm, ref NvdecRegisters state)
|
||||
public static void Decode(NvdecDecoderContext context, ResourceManager rm, ref NvdecRegisters state)
|
||||
{
|
||||
PictureInfo pictureInfo = rm.Gmm.DeviceRead<PictureInfo>(state.SetPictureInfoOffset);
|
||||
H264PictureInfo info = pictureInfo.Convert();
|
||||
|
@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Nvdec
|
|||
uint lumaOffset = state.SetSurfaceLumaOffset[surfaceIndex];
|
||||
uint chromaOffset = state.SetSurfaceChromaOffset[surfaceIndex];
|
||||
|
||||
Decoder decoder = context.GetDecoder();
|
||||
Decoder decoder = context.GetH264Decoder();
|
||||
|
||||
ISurface outputSurface = rm.Cache.Get(decoder, 0, 0, width, height);
|
||||
|
||||
|
|
|
@ -1,21 +1,29 @@
|
|||
using Ryujinx.Graphics.Nvdec.H264;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec
|
||||
{
|
||||
class NvdecDecoderContext : IDisposable
|
||||
{
|
||||
private Decoder _decoder;
|
||||
private FFmpeg.H264.Decoder _h264Decoder;
|
||||
private FFmpeg.Vp8.Decoder _vp8Decoder;
|
||||
|
||||
public Decoder GetDecoder()
|
||||
public FFmpeg.H264.Decoder GetH264Decoder()
|
||||
{
|
||||
return _decoder ??= new Decoder();
|
||||
return _h264Decoder ??= new FFmpeg.H264.Decoder();
|
||||
}
|
||||
|
||||
public FFmpeg.Vp8.Decoder GetVp8Decoder()
|
||||
{
|
||||
return _vp8Decoder ??= new FFmpeg.Vp8.Decoder();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_decoder?.Dispose();
|
||||
_decoder = null;
|
||||
_h264Decoder?.Dispose();
|
||||
_h264Decoder = null;
|
||||
|
||||
_vp8Decoder?.Dispose();
|
||||
_vp8Decoder = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,6 +68,9 @@ namespace Ryujinx.Graphics.Nvdec
|
|||
case CodecId.H264:
|
||||
H264Decoder.Decode(_currentContext, _rm, ref _state.State);
|
||||
break;
|
||||
case CodecId.Vp8:
|
||||
Vp8Decoder.Decode(_currentContext, _rm, ref _state.State);
|
||||
break;
|
||||
case CodecId.Vp9:
|
||||
Vp9Decoder.Decode(_rm, ref _state.State);
|
||||
break;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
|
||||
<ProjectReference Include="..\Ryujinx.Graphics.Device\Ryujinx.Graphics.Device.csproj" />
|
||||
<ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
|
||||
<ProjectReference Include="..\Ryujinx.Graphics.Nvdec.H264\Ryujinx.Graphics.Nvdec.H264.csproj" />
|
||||
<ProjectReference Include="..\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj" />
|
||||
<ProjectReference Include="..\Ryujinx.Graphics.Nvdec.Vp9\Ryujinx.Graphics.Nvdec.Vp9.csproj" />
|
||||
<ProjectReference Include="..\Ryujinx.Graphics.Texture\Ryujinx.Graphics.Texture.csproj" />
|
||||
<ProjectReference Include="..\Ryujinx.Graphics.Video\Ryujinx.Graphics.Video.csproj" />
|
||||
|
|
75
Ryujinx.Graphics.Nvdec/Types/Vp8/PictureInfo.cs
Normal file
75
Ryujinx.Graphics.Nvdec/Types/Vp8/PictureInfo.cs
Normal file
|
@ -0,0 +1,75 @@
|
|||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Video;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Types.Vp8
|
||||
{
|
||||
struct PictureInfo
|
||||
{
|
||||
#pragma warning disable CS0649
|
||||
public Array13<uint> Unknown0;
|
||||
public uint GpTimerTimeoutValue;
|
||||
public ushort FrameWidth;
|
||||
public ushort FrameHeight;
|
||||
public byte KeyFrame; // 1: key frame - 0: not
|
||||
public byte Version;
|
||||
public byte Flags0;
|
||||
// TileFormat : 2 // 0: TBL; 1: KBL;
|
||||
// GobHeight : 3 // Set GOB height, 0: GOB_2, 1: GOB_4, 2: GOB_8, 3: GOB_16, 4: GOB_32 (NVDEC3 onwards)
|
||||
// ReserverdSurfaceFormat : 3
|
||||
public byte ErrorConcealOn; // 1: error conceal on - 0: off
|
||||
public uint FirstPartSize; // the size of first partition (frame header and mb header partition)
|
||||
public uint HistBufferSize; // in units of 256
|
||||
public uint VLDBufferSize; // in units of 1
|
||||
public Array2<uint> FrameStride; // [y_c]
|
||||
public uint LumaTopOffset; // offset of luma top field in units of 256
|
||||
public uint LumaBotOffset; // offset of luma bottom field in units of 256
|
||||
public uint LumaFrameOffset; // offset of luma frame in units of 256
|
||||
public uint ChromaTopOffset; // offset of chroma top field in units of 256
|
||||
public uint ChromaBotOffset; // offset of chroma bottom field in units of 256
|
||||
public uint ChromaFrameOffset; // offset of chroma frame in units of 256
|
||||
public uint Flags1;
|
||||
// EnableTFOutput : 1; // =1, enable dbfdma to output the display surface; if disable, then the following configure on tf is useless.
|
||||
// Remap for VC1
|
||||
// VC1MapYFlag : 1
|
||||
// MapYValue : 3
|
||||
// VC1MapUVFlag : 1
|
||||
// MapUVValue : 3
|
||||
// TF
|
||||
// OutStride : 8
|
||||
// TilingFormat : 3;
|
||||
// OutputStructure : 1 // 0:frame, 1:field
|
||||
// Reserved0 : 11
|
||||
public Array2<int> OutputTop; // in units of 256
|
||||
public Array2<int> OutputBottom; // in units of 256
|
||||
// Histogram
|
||||
public uint Flags2;
|
||||
// EnableHistogram : 1 // enable histogram info collection
|
||||
// HistogramStartX : 12 // start X of Histogram window
|
||||
// HistogramStartY : 12 // start Y of Histogram window
|
||||
// Reserved1 : 7
|
||||
// HistogramEndX : 12 // end X of Histogram window
|
||||
// HistogramEndY : 12 // end y of Histogram window
|
||||
// Reserved2 : 8
|
||||
// Decode picture buffer related
|
||||
public sbyte CurrentOutputMemoryLayout;
|
||||
public Array3<sbyte> OutputMemoryLayout; // output NV12/NV24 setting. item 0:golden - 1: altref - 2: last
|
||||
public byte SegmentationFeatureDataUpdate;
|
||||
public Array3<byte> Reserved3;
|
||||
public uint ResultValue; // ucode return result
|
||||
public Array8<uint> PartitionOffset;
|
||||
public Array3<uint> Reserved4;
|
||||
#pragma warning restore CS0649
|
||||
|
||||
public Vp8PictureInfo Convert()
|
||||
{
|
||||
return new Vp8PictureInfo()
|
||||
{
|
||||
KeyFrame = KeyFrame != 0,
|
||||
FirstPartSize = FirstPartSize,
|
||||
Version = Version,
|
||||
FrameWidth = FrameWidth,
|
||||
FrameHeight = FrameHeight
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
33
Ryujinx.Graphics.Nvdec/Vp8Decoder.cs
Normal file
33
Ryujinx.Graphics.Nvdec/Vp8Decoder.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using Ryujinx.Graphics.Nvdec.FFmpeg.Vp8;
|
||||
using Ryujinx.Graphics.Nvdec.Image;
|
||||
using Ryujinx.Graphics.Nvdec.Types.Vp8;
|
||||
using Ryujinx.Graphics.Video;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec
|
||||
{
|
||||
static class Vp8Decoder
|
||||
{
|
||||
public static void Decode(NvdecDecoderContext context, ResourceManager rm, ref NvdecRegisters state)
|
||||
{
|
||||
PictureInfo pictureInfo = rm.Gmm.DeviceRead<PictureInfo>(state.SetPictureInfoOffset);
|
||||
ReadOnlySpan<byte> bitstream = rm.Gmm.DeviceGetSpan(state.SetBitstreamOffset, (int)pictureInfo.VLDBufferSize);
|
||||
|
||||
Decoder decoder = context.GetVp8Decoder();
|
||||
|
||||
ISurface outputSurface = rm.Cache.Get(decoder, 0, 0, pictureInfo.FrameWidth, pictureInfo.FrameHeight);
|
||||
|
||||
Vp8PictureInfo info = pictureInfo.Convert();
|
||||
|
||||
uint lumaOffset = state.SetSurfaceLumaOffset[3];
|
||||
uint chromaOffset = state.SetSurfaceChromaOffset[3];
|
||||
|
||||
if (decoder.Decode(ref info, outputSurface, bitstream))
|
||||
{
|
||||
SurfaceWriter.Write(rm.Gmm, outputSurface, lumaOffset, chromaOffset);
|
||||
}
|
||||
|
||||
rm.Cache.Put(outputSurface);
|
||||
}
|
||||
}
|
||||
}
|
11
Ryujinx.Graphics.Video/Vp8PictureInfo.cs
Normal file
11
Ryujinx.Graphics.Video/Vp8PictureInfo.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace Ryujinx.Graphics.Video
|
||||
{
|
||||
public ref struct Vp8PictureInfo
|
||||
{
|
||||
public bool KeyFrame;
|
||||
public uint FirstPartSize;
|
||||
public uint Version;
|
||||
public ushort FrameWidth;
|
||||
public ushort FrameHeight;
|
||||
}
|
||||
}
|
14
Ryujinx.sln
14
Ryujinx.sln
|
@ -51,8 +51,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.Vp9"
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vic", "Ryujinx.Graphics.Vic\Ryujinx.Graphics.Vic.csproj", "{81BB2C11-9408-4EA3-822E-42987AF54429}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.H264", "Ryujinx.Graphics.Nvdec.H264\Ryujinx.Graphics.Nvdec.H264.csproj", "{990F9601-343E-46CB-8529-B498FA761A92}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Video", "Ryujinx.Graphics.Video\Ryujinx.Graphics.Video.csproj", "{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.OpenAL", "Ryujinx.Audio.Backends.OpenAL\Ryujinx.Audio.Backends.OpenAL.csproj", "{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}"
|
||||
|
@ -67,7 +65,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.SDL2.Common", "Ryuj
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL2", "Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj", "{D99A395A-8569-4DB0-B336-900647890052}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Headless.SDL2", "Ryujinx.Headless.SDL2\Ryujinx.Headless.SDL2.csproj", "{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Headless.SDL2", "Ryujinx.Headless.SDL2\Ryujinx.Headless.SDL2.csproj", "{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -159,10 +159,6 @@ Global
|
|||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{81BB2C11-9408-4EA3-822E-42987AF54429}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{990F9601-343E-46CB-8529-B498FA761A92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{990F9601-343E-46CB-8529-B498FA761A92}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{990F9601-343E-46CB-8529-B498FA761A92}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{990F9601-343E-46CB-8529-B498FA761A92}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -195,6 +191,10 @@ Global
|
|||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<PackageReference Include="DiscordRichPresence" Version="1.0.175" />
|
||||
<PackageReference Include="GtkSharp" Version="3.22.25.128" />
|
||||
<PackageReference Include="GtkSharp.Dependencies" Version="1.1.0" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" />
|
||||
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="4.4.0-build7" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" />
|
||||
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="4.4.0-build9" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" />
|
||||
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" />
|
||||
<PackageReference Include="OpenTK.Graphics" Version="4.5.0" />
|
||||
<PackageReference Include="SPB" Version="0.0.3-build15" />
|
||||
|
|
Reference in a new issue