Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
2d252db0a7 | ||
|
7f8a3541eb | ||
|
b34de74f81 | ||
|
5811d121df | ||
|
6eb85e846f | ||
|
c5bddfeab8 | ||
|
70ec5def9c | ||
|
7853faa334 | ||
|
b7fb474bfe | ||
|
2fa6413ed8 |
@@ -118,7 +118,7 @@
|
|||||||
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
|
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
|
||||||
"SettingsTabSystemAudioBackendSDL2": "SDL2",
|
"SettingsTabSystemAudioBackendSDL2": "SDL2",
|
||||||
"SettingsTabSystemHacks": "Hacks",
|
"SettingsTabSystemHacks": "Hacks",
|
||||||
"SettingsTabSystemHacksNote": " - These may cause instabilities",
|
"SettingsTabSystemHacksNote": " (may cause instability)",
|
||||||
"SettingsTabSystemExpandDramSize": "Expand DRAM Size to 6GB",
|
"SettingsTabSystemExpandDramSize": "Expand DRAM Size to 6GB",
|
||||||
"SettingsTabSystemIgnoreMissingServices": "Ignore Missing Services",
|
"SettingsTabSystemIgnoreMissingServices": "Ignore Missing Services",
|
||||||
"SettingsTabGraphics": "Graphics",
|
"SettingsTabGraphics": "Graphics",
|
||||||
|
@@ -54,5 +54,6 @@
|
|||||||
<Color x:Key="TextOnAccentFillColorPrimary">#FFFFFFFF</Color>
|
<Color x:Key="TextOnAccentFillColorPrimary">#FFFFFFFF</Color>
|
||||||
<Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
|
<Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
|
||||||
<Color x:Key="ThemeForegroundColor">#FFFFFFFF</Color>
|
<Color x:Key="ThemeForegroundColor">#FFFFFFFF</Color>
|
||||||
|
<Color x:Key="MenuFlyoutPresenterBorderColor">#3D3D3D</Color>
|
||||||
</Styles.Resources>
|
</Styles.Resources>
|
||||||
</Styles>
|
</Styles>
|
@@ -49,5 +49,6 @@
|
|||||||
<Color x:Key="TextOnAccentFillColorPrimary">#FFFFFFFF</Color>
|
<Color x:Key="TextOnAccentFillColorPrimary">#FFFFFFFF</Color>
|
||||||
<Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
|
<Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
|
||||||
<Color x:Key="ThemeForegroundColor">#FF000000</Color>
|
<Color x:Key="ThemeForegroundColor">#FF000000</Color>
|
||||||
|
<Color x:Key="MenuFlyoutPresenterBorderColor">#C1C1C1</Color>
|
||||||
</Styles.Resources>
|
</Styles.Resources>
|
||||||
</Styles>
|
</Styles>
|
@@ -221,6 +221,7 @@
|
|||||||
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundColor}" />
|
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundColor}" />
|
||||||
</Style>
|
</Style>
|
||||||
<Styles.Resources>
|
<Styles.Resources>
|
||||||
|
<SolidColorBrush x:Key="ThemeAccentColorBrush" Color="{DynamicResource SystemAccentColor}" />
|
||||||
<StaticResource x:Key="ListViewItemBackgroundSelected" ResourceKey="ThemeAccentColorBrush" />
|
<StaticResource x:Key="ListViewItemBackgroundSelected" ResourceKey="ThemeAccentColorBrush" />
|
||||||
<StaticResource x:Key="ListViewItemBackgroundPressed" ResourceKey="SystemAccentColorDark1" />
|
<StaticResource x:Key="ListViewItemBackgroundPressed" ResourceKey="SystemAccentColorDark1" />
|
||||||
<StaticResource x:Key="ListViewItemBackgroundPointerOver" ResourceKey="SystemAccentColorDark2" />
|
<StaticResource x:Key="ListViewItemBackgroundPointerOver" ResourceKey="SystemAccentColorDark2" />
|
||||||
@@ -232,7 +233,7 @@
|
|||||||
Color="{DynamicResource SystemBaseMediumLowColor}" />
|
Color="{DynamicResource SystemBaseMediumLowColor}" />
|
||||||
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush" Color="{DynamicResource DataGridSelectionColor}" />
|
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush" Color="{DynamicResource DataGridSelectionColor}" />
|
||||||
<SolidColorBrush x:Key="MenuFlyoutPresenterBorderBrush" Color="{DynamicResource MenuFlyoutPresenterBorderColor}" />
|
<SolidColorBrush x:Key="MenuFlyoutPresenterBorderBrush" Color="{DynamicResource MenuFlyoutPresenterBorderColor}" />
|
||||||
<SolidColorBrush x:Key="ThemeAccentColorBrush" Color="{DynamicResource SystemAccentColor}" />
|
<SolidColorBrush x:Key="FlyoutBorderThemeBrush" Color="{DynamicResource MenuFlyoutPresenterBorderColor}" />
|
||||||
<SolidColorBrush x:Key="ListBoxBackground" Color="{DynamicResource ThemeContentBackgroundColor}" />
|
<SolidColorBrush x:Key="ListBoxBackground" Color="{DynamicResource ThemeContentBackgroundColor}" />
|
||||||
<SolidColorBrush x:Key="ThemeForegroundBrush" Color="{DynamicResource ThemeForegroundColor}" />
|
<SolidColorBrush x:Key="ThemeForegroundBrush" Color="{DynamicResource ThemeForegroundColor}" />
|
||||||
<SolidColorBrush x:Key="ThemeAccentBrush4" Color="{DynamicResource ThemeAccentColor4}" />
|
<SolidColorBrush x:Key="ThemeAccentBrush4" Color="{DynamicResource ThemeAccentColor4}" />
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
<PackageReference Include="FluentAvaloniaUI" Version="1.4.1" />
|
<PackageReference Include="FluentAvaloniaUI" Version="1.4.1" />
|
||||||
|
|
||||||
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" 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="Ryujinx.Graphics.Nvdec.Dependencies" Version="4.4.0-build9" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" />
|
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build10" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" />
|
||||||
<PackageReference Include="OpenTK.Graphics" Version="4.7.2" />
|
<PackageReference Include="OpenTK.Graphics" Version="4.7.2" />
|
||||||
<PackageReference Include="SPB" Version="0.0.4-build17" />
|
<PackageReference Include="SPB" Version="0.0.4-build17" />
|
||||||
<PackageReference Include="SharpZipLib" Version="1.3.3" />
|
<PackageReference Include="SharpZipLib" Version="1.3.3" />
|
||||||
|
@@ -535,6 +535,11 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool ShowConsoleVisible
|
||||||
|
{
|
||||||
|
get => ConsoleHelper.SetConsoleWindowStateSupported;
|
||||||
|
}
|
||||||
|
|
||||||
public ObservableCollection<ApplicationData> Applications
|
public ObservableCollection<ApplicationData> Applications
|
||||||
{
|
{
|
||||||
get => _applications;
|
get => _applications;
|
||||||
|
@@ -128,7 +128,7 @@
|
|||||||
<CheckBox IsChecked="{Binding StartGamesInFullscreen, Mode=TwoWay}" />
|
<CheckBox IsChecked="{Binding StartGamesInFullscreen, Mode=TwoWay}" />
|
||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="{locale:Locale MenuBarOptionsShowConsole}">
|
<MenuItem Header="{locale:Locale MenuBarOptionsShowConsole}" IsVisible="{Binding ShowConsoleVisible}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<CheckBox IsChecked="{Binding ShowConsole, Mode=TwoWay}" />
|
<CheckBox IsChecked="{Binding ShowConsole, Mode=TwoWay}" />
|
||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
|
@@ -208,7 +208,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReadOnlySpan<byte> srcSpan = memoryManager.GetSpan(srcGpuVa + (ulong)srcBaseOffset, srcSize, true);
|
ReadOnlySpan<byte> srcSpan = memoryManager.GetSpan(srcGpuVa + (ulong)srcBaseOffset, srcSize, true);
|
||||||
Span<byte> dstSpan = memoryManager.GetSpan(dstGpuVa + (ulong)dstBaseOffset, dstSize).ToArray();
|
|
||||||
|
|
||||||
bool completeSource = IsTextureCopyComplete(src, srcLinear, srcBpp, srcStride, xCount, yCount);
|
bool completeSource = IsTextureCopyComplete(src, srcLinear, srcBpp, srcStride, xCount, yCount);
|
||||||
bool completeDest = IsTextureCopyComplete(dst, dstLinear, dstBpp, dstStride, xCount, yCount);
|
bool completeDest = IsTextureCopyComplete(dst, dstLinear, dstBpp, dstStride, xCount, yCount);
|
||||||
@@ -262,20 +261,33 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
target.SynchronizeMemory();
|
target.SynchronizeMemory();
|
||||||
target.SetData(data);
|
target.SetData(data);
|
||||||
target.SignalModified();
|
target.SignalModified();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (srcCalculator.LayoutMatches(dstCalculator))
|
else if (srcCalculator.LayoutMatches(dstCalculator))
|
||||||
{
|
{
|
||||||
srcSpan.CopyTo(dstSpan); // No layout conversion has to be performed, just copy the data entirely.
|
// No layout conversion has to be performed, just copy the data entirely.
|
||||||
|
memoryManager.Write(dstGpuVa + (ulong)dstBaseOffset, srcSpan);
|
||||||
memoryManager.Write(dstGpuVa + (ulong)dstBaseOffset, dstSpan);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe bool Convert<T>(Span<byte> dstSpan, ReadOnlySpan<byte> srcSpan) where T : unmanaged
|
unsafe bool Convert<T>(Span<byte> dstSpan, ReadOnlySpan<byte> srcSpan) where T : unmanaged
|
||||||
|
{
|
||||||
|
if (srcLinear && dstLinear && srcBpp == dstBpp)
|
||||||
|
{
|
||||||
|
// Optimized path for purely linear copies - we don't need to calculate every single byte offset,
|
||||||
|
// and we can make use of Span.CopyTo which is very very fast (even compared to pointers)
|
||||||
|
for (int y = 0; y < yCount; y++)
|
||||||
|
{
|
||||||
|
srcCalculator.SetY(srcRegionY + y);
|
||||||
|
dstCalculator.SetY(dstRegionY + y);
|
||||||
|
int srcOffset = srcCalculator.GetOffset(srcRegionX);
|
||||||
|
int dstOffset = dstCalculator.GetOffset(dstRegionX);
|
||||||
|
srcSpan.Slice(srcOffset - srcBaseOffset, xCount * srcBpp)
|
||||||
|
.CopyTo(dstSpan.Slice(dstOffset - dstBaseOffset, xCount * dstBpp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
fixed (byte* dstPtr = dstSpan, srcPtr = srcSpan)
|
fixed (byte* dstPtr = dstSpan, srcPtr = srcSpan)
|
||||||
{
|
{
|
||||||
@@ -296,9 +308,16 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OPT: This allocates a (potentially) huge temporary array and then copies an existing
|
||||||
|
// region of memory into it, data that might get overwritten entirely anyways. Ideally this should
|
||||||
|
// all be rewritten to use pooled arrays, but that gets complicated with packed data and strides
|
||||||
|
Span<byte> dstSpan = memoryManager.GetSpan(dstGpuVa + (ulong)dstBaseOffset, dstSize).ToArray();
|
||||||
|
|
||||||
bool _ = srcBpp switch
|
bool _ = srcBpp switch
|
||||||
{
|
{
|
||||||
1 => Convert<byte>(dstSpan, srcSpan),
|
1 => Convert<byte>(dstSpan, srcSpan),
|
||||||
|
@@ -174,6 +174,14 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (info.Width == info.Height * info.Height)
|
||||||
|
{
|
||||||
|
// Possibly used for a "3D texture" drawn onto a 2D surface.
|
||||||
|
// Some games do this to generate a tone mapping LUT without rendering into 3D texture slices.
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
private const ushort FileFormatVersionMajor = 1;
|
private const ushort FileFormatVersionMajor = 1;
|
||||||
private const ushort FileFormatVersionMinor = 1;
|
private const ushort FileFormatVersionMinor = 1;
|
||||||
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
||||||
private const uint CodeGenVersion = 3457;
|
private const uint CodeGenVersion = 3472;
|
||||||
|
|
||||||
private const string SharedTocFileName = "shared.toc";
|
private const string SharedTocFileName = "shared.toc";
|
||||||
private const string SharedDataFileName = "shared.data";
|
private const string SharedDataFileName = "shared.data";
|
||||||
|
@@ -1,23 +1,21 @@
|
|||||||
using FFmpeg.AutoGen;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Graphics.Nvdec.FFmpeg.Native;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
||||||
{
|
{
|
||||||
unsafe class FFmpegContext : IDisposable
|
unsafe class FFmpegContext : IDisposable
|
||||||
{
|
{
|
||||||
private readonly AVCodec_decode _decodeFrame;
|
private readonly FFCodec.AVCodec_decode _decodeFrame;
|
||||||
private static readonly av_log_set_callback_callback _logFunc;
|
private static readonly FFmpegApi.av_log_set_callback_callback _logFunc;
|
||||||
private readonly AVCodec* _codec;
|
private readonly AVCodec* _codec;
|
||||||
private AVPacket* _packet;
|
private AVPacket* _packet;
|
||||||
private AVCodecContext* _context;
|
private AVCodecContext* _context;
|
||||||
|
|
||||||
public FFmpegContext(AVCodecID codecId)
|
public FFmpegContext(AVCodecID codecId)
|
||||||
{
|
{
|
||||||
_codec = ffmpeg.avcodec_find_decoder(codecId);
|
_codec = FFmpegApi.avcodec_find_decoder(codecId);
|
||||||
if (_codec == null)
|
if (_codec == null)
|
||||||
{
|
{
|
||||||
Logger.Error?.PrintMsg(LogClass.FFmpeg, $"Codec wasn't found. Make sure you have the {codecId} codec present in your FFmpeg installation.");
|
Logger.Error?.PrintMsg(LogClass.FFmpeg, $"Codec wasn't found. Make sure you have the {codecId} codec present in your FFmpeg installation.");
|
||||||
@@ -25,7 +23,7 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_context = ffmpeg.avcodec_alloc_context3(_codec);
|
_context = FFmpegApi.avcodec_alloc_context3(_codec);
|
||||||
if (_context == null)
|
if (_context == null)
|
||||||
{
|
{
|
||||||
Logger.Error?.PrintMsg(LogClass.FFmpeg, "Codec context couldn't be allocated.");
|
Logger.Error?.PrintMsg(LogClass.FFmpeg, "Codec context couldn't be allocated.");
|
||||||
@@ -33,14 +31,14 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ffmpeg.avcodec_open2(_context, _codec, null) != 0)
|
if (FFmpegApi.avcodec_open2(_context, _codec, null) != 0)
|
||||||
{
|
{
|
||||||
Logger.Error?.PrintMsg(LogClass.FFmpeg, "Codec couldn't be opened.");
|
Logger.Error?.PrintMsg(LogClass.FFmpeg, "Codec couldn't be opened.");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_packet = ffmpeg.av_packet_alloc();
|
_packet = FFmpegApi.av_packet_alloc();
|
||||||
if (_packet == null)
|
if (_packet == null)
|
||||||
{
|
{
|
||||||
Logger.Error?.PrintMsg(LogClass.FFmpeg, "Packet couldn't be allocated.");
|
Logger.Error?.PrintMsg(LogClass.FFmpeg, "Packet couldn't be allocated.");
|
||||||
@@ -48,52 +46,39 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_decodeFrame = Marshal.GetDelegateForFunctionPointer<AVCodec_decode>(_codec->decode.Pointer);
|
int avCodecRawVersion = FFmpegApi.avcodec_version();
|
||||||
|
int avCodecMajorVersion = avCodecRawVersion >> 16;
|
||||||
|
int avCodecMinorVersion = (avCodecRawVersion >> 8) & 0xFF;
|
||||||
|
|
||||||
|
// libavcodec 59.24 changed AvCodec to move its private API and also move the codec function to an union.
|
||||||
|
if (avCodecMajorVersion > 59 || (avCodecMajorVersion == 59 && avCodecMinorVersion > 24))
|
||||||
|
{
|
||||||
|
_decodeFrame = Marshal.GetDelegateForFunctionPointer<FFCodec.AVCodec_decode>(((FFCodec*)_codec)->CodecCallback);
|
||||||
|
}
|
||||||
|
// libavcodec 59.x changed AvCodec private API layout.
|
||||||
|
else if (avCodecMajorVersion == 59)
|
||||||
|
{
|
||||||
|
_decodeFrame = Marshal.GetDelegateForFunctionPointer<FFCodec.AVCodec_decode>(((FFCodecLegacy<AVCodec>*)_codec)->Decode);
|
||||||
|
}
|
||||||
|
// libavcodec 58.x and lower
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_decodeFrame = Marshal.GetDelegateForFunctionPointer<FFCodec.AVCodec_decode>(((FFCodecLegacy<AVCodecLegacy>*)_codec)->Decode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static FFmpegContext()
|
static FFmpegContext()
|
||||||
{
|
{
|
||||||
SetRootPath();
|
|
||||||
|
|
||||||
_logFunc = Log;
|
_logFunc = Log;
|
||||||
|
|
||||||
// Redirect log output.
|
// Redirect log output.
|
||||||
ffmpeg.av_log_set_level(ffmpeg.AV_LOG_MAX_OFFSET);
|
FFmpegApi.av_log_set_level(AVLog.MaxOffset);
|
||||||
ffmpeg.av_log_set_callback(_logFunc);
|
FFmpegApi.av_log_set_callback(_logFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetRootPath()
|
private static void Log(void* ptr, AVLog level, string format, byte* vl)
|
||||||
{
|
{
|
||||||
if (OperatingSystem.IsLinux())
|
if (level > FFmpegApi.av_log_get_level())
|
||||||
{
|
|
||||||
// Configure FFmpeg search path
|
|
||||||
Process lddProcess = Process.Start(new ProcessStartInfo
|
|
||||||
{
|
|
||||||
FileName = "/bin/sh",
|
|
||||||
Arguments = "-c \"ldd $(which ffmpeg 2>/dev/null) | grep libavfilter\" 2>/dev/null",
|
|
||||||
UseShellExecute = false,
|
|
||||||
RedirectStandardOutput = true
|
|
||||||
});
|
|
||||||
|
|
||||||
string lddOutput = lddProcess.StandardOutput.ReadToEnd();
|
|
||||||
|
|
||||||
lddProcess.WaitForExit();
|
|
||||||
lddProcess.Close();
|
|
||||||
|
|
||||||
if (lddOutput.Contains(" => "))
|
|
||||||
{
|
|
||||||
ffmpeg.RootPath = Path.GetDirectoryName(lddOutput.Split(" => ")[1]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger.Error?.PrintMsg(LogClass.FFmpeg, "FFmpeg wasn't found. Make sure that you have it installed and up to date.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Log(void* p0, int level, string format, byte* vl)
|
|
||||||
{
|
|
||||||
if (level > ffmpeg.av_log_get_level())
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -102,65 +87,67 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
|||||||
byte* lineBuffer = stackalloc byte[lineSize];
|
byte* lineBuffer = stackalloc byte[lineSize];
|
||||||
int printPrefix = 1;
|
int printPrefix = 1;
|
||||||
|
|
||||||
ffmpeg.av_log_format_line(p0, level, format, vl, lineBuffer, lineSize, &printPrefix);
|
FFmpegApi.av_log_format_line(ptr, level, format, vl, lineBuffer, lineSize, &printPrefix);
|
||||||
|
|
||||||
string line = Marshal.PtrToStringAnsi((IntPtr)lineBuffer).Trim();
|
string line = Marshal.PtrToStringAnsi((IntPtr)lineBuffer).Trim();
|
||||||
|
|
||||||
switch (level)
|
switch (level)
|
||||||
{
|
{
|
||||||
case ffmpeg.AV_LOG_PANIC:
|
case AVLog.Panic:
|
||||||
case ffmpeg.AV_LOG_FATAL:
|
case AVLog.Fatal:
|
||||||
case ffmpeg.AV_LOG_ERROR:
|
case AVLog.Error:
|
||||||
Logger.Error?.Print(LogClass.FFmpeg, line);
|
Logger.Error?.Print(LogClass.FFmpeg, line);
|
||||||
break;
|
break;
|
||||||
case ffmpeg.AV_LOG_WARNING:
|
case AVLog.Warning:
|
||||||
Logger.Warning?.Print(LogClass.FFmpeg, line);
|
Logger.Warning?.Print(LogClass.FFmpeg, line);
|
||||||
break;
|
break;
|
||||||
case ffmpeg.AV_LOG_INFO:
|
case AVLog.Info:
|
||||||
Logger.Info?.Print(LogClass.FFmpeg, line);
|
Logger.Info?.Print(LogClass.FFmpeg, line);
|
||||||
break;
|
break;
|
||||||
case ffmpeg.AV_LOG_VERBOSE:
|
case AVLog.Verbose:
|
||||||
case ffmpeg.AV_LOG_DEBUG:
|
case AVLog.Debug:
|
||||||
case ffmpeg.AV_LOG_TRACE:
|
|
||||||
Logger.Debug?.Print(LogClass.FFmpeg, line);
|
Logger.Debug?.Print(LogClass.FFmpeg, line);
|
||||||
break;
|
break;
|
||||||
|
case AVLog.Trace:
|
||||||
|
Logger.Trace?.Print(LogClass.FFmpeg, line);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int DecodeFrame(Surface output, ReadOnlySpan<byte> bitstream)
|
public int DecodeFrame(Surface output, ReadOnlySpan<byte> bitstream)
|
||||||
{
|
{
|
||||||
ffmpeg.av_frame_unref(output.Frame);
|
FFmpegApi.av_frame_unref(output.Frame);
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
int gotFrame;
|
int gotFrame;
|
||||||
|
|
||||||
fixed (byte* ptr = bitstream)
|
fixed (byte* ptr = bitstream)
|
||||||
{
|
{
|
||||||
_packet->data = ptr;
|
_packet->Data = ptr;
|
||||||
_packet->size = bitstream.Length;
|
_packet->Size = bitstream.Length;
|
||||||
result = _decodeFrame(_context, output.Frame, &gotFrame, _packet);
|
result = _decodeFrame(_context, output.Frame, &gotFrame, _packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gotFrame == 0)
|
if (gotFrame == 0)
|
||||||
{
|
{
|
||||||
ffmpeg.av_frame_unref(output.Frame);
|
FFmpegApi.av_frame_unref(output.Frame);
|
||||||
|
|
||||||
// If the frame was not delivered, it was probably delayed.
|
// If the frame was not delivered, it was probably delayed.
|
||||||
// Get the next delayed frame by passing a 0 length packet.
|
// Get the next delayed frame by passing a 0 length packet.
|
||||||
_packet->data = null;
|
_packet->Data = null;
|
||||||
_packet->size = 0;
|
_packet->Size = 0;
|
||||||
result = _decodeFrame(_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.
|
// 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.
|
// This prevents the decoder from trying to return a delayed frame next time.
|
||||||
_context->has_b_frames = 0;
|
_context->HasBFrames = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ffmpeg.av_packet_unref(_packet);
|
FFmpegApi.av_packet_unref(_packet);
|
||||||
|
|
||||||
if (gotFrame == 0)
|
if (gotFrame == 0)
|
||||||
{
|
{
|
||||||
ffmpeg.av_frame_unref(output.Frame);
|
FFmpegApi.av_frame_unref(output.Frame);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -172,14 +159,14 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
|||||||
{
|
{
|
||||||
fixed (AVPacket** ppPacket = &_packet)
|
fixed (AVPacket** ppPacket = &_packet)
|
||||||
{
|
{
|
||||||
ffmpeg.av_packet_free(ppPacket);
|
FFmpegApi.av_packet_free(ppPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
ffmpeg.avcodec_close(_context);
|
FFmpegApi.avcodec_close(_context);
|
||||||
|
|
||||||
fixed (AVCodecContext** ppContext = &_context)
|
fixed (AVCodecContext** ppContext = &_context)
|
||||||
{
|
{
|
||||||
ffmpeg.avcodec_free_context(ppContext);
|
FFmpegApi.avcodec_free_context(ppContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
using FFmpeg.AutoGen;
|
using Ryujinx.Graphics.Nvdec.FFmpeg.Native;
|
||||||
using Ryujinx.Graphics.Video;
|
using Ryujinx.Graphics.Video;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
25
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs
Normal file
25
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
|
{
|
||||||
|
struct AVCodec
|
||||||
|
{
|
||||||
|
#pragma warning disable CS0649
|
||||||
|
public unsafe byte* Name;
|
||||||
|
public unsafe byte* LongName;
|
||||||
|
public int Type;
|
||||||
|
public AVCodecID Id;
|
||||||
|
public int Capabilities;
|
||||||
|
public byte MaxLowRes;
|
||||||
|
public unsafe AVRational* SupportedFramerates;
|
||||||
|
public IntPtr PixFmts;
|
||||||
|
public IntPtr SupportedSamplerates;
|
||||||
|
public IntPtr SampleFmts;
|
||||||
|
// Deprecated
|
||||||
|
public unsafe ulong* ChannelLayouts;
|
||||||
|
public unsafe IntPtr PrivClass;
|
||||||
|
public IntPtr Profiles;
|
||||||
|
public unsafe byte* WrapperName;
|
||||||
|
#pragma warning restore CS0649
|
||||||
|
}
|
||||||
|
}
|
171
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs
Normal file
171
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
using Ryujinx.Common.Memory;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
|
{
|
||||||
|
struct AVCodecContext
|
||||||
|
{
|
||||||
|
#pragma warning disable CS0649
|
||||||
|
public unsafe IntPtr AvClass;
|
||||||
|
public int LogLevelOffset;
|
||||||
|
public int CodecType;
|
||||||
|
public unsafe AVCodecLegacy* Codec;
|
||||||
|
public AVCodecID CodecId;
|
||||||
|
public uint CodecTag;
|
||||||
|
public IntPtr PrivData;
|
||||||
|
public IntPtr Internal;
|
||||||
|
public IntPtr Opaque;
|
||||||
|
public long BitRate;
|
||||||
|
public int BitRateTolerance;
|
||||||
|
public int GlobalQuality;
|
||||||
|
public int CompressionLevel;
|
||||||
|
public int Flags;
|
||||||
|
public int Flags2;
|
||||||
|
public IntPtr ExtraData;
|
||||||
|
public int ExtraDataSize;
|
||||||
|
public AVRational TimeBase;
|
||||||
|
public int TicksPerFrame;
|
||||||
|
public int Delay;
|
||||||
|
public int Width;
|
||||||
|
public int Height;
|
||||||
|
public int CodedWidth;
|
||||||
|
public int CodedHeight;
|
||||||
|
public int GopSize;
|
||||||
|
public int PixFmt;
|
||||||
|
public IntPtr DrawHorizBand;
|
||||||
|
public IntPtr GetFormat;
|
||||||
|
public int MaxBFrames;
|
||||||
|
public float BQuantFactor;
|
||||||
|
public float BQuantOffset;
|
||||||
|
public int HasBFrames;
|
||||||
|
public float IQuantFactor;
|
||||||
|
public float IQuantOffset;
|
||||||
|
public float LumiMasking;
|
||||||
|
public float TemporalCplxMasking;
|
||||||
|
public float SpatialCplxMasking;
|
||||||
|
public float PMasking;
|
||||||
|
public float DarkMasking;
|
||||||
|
public int SliceCount;
|
||||||
|
public IntPtr SliceOffset;
|
||||||
|
public AVRational SampleAspectRatio;
|
||||||
|
public int MeCmp;
|
||||||
|
public int MeSubCmp;
|
||||||
|
public int MbCmp;
|
||||||
|
public int IldctCmp;
|
||||||
|
public int DiaSize;
|
||||||
|
public int LastPredictorCount;
|
||||||
|
public int MePreCmp;
|
||||||
|
public int PreDiaSize;
|
||||||
|
public int MeSubpelQuality;
|
||||||
|
public int MeRange;
|
||||||
|
public int SliceFlags;
|
||||||
|
public int MbDecision;
|
||||||
|
public IntPtr IntraMatrix;
|
||||||
|
public IntPtr InterMatrix;
|
||||||
|
public int IntraDcPrecision;
|
||||||
|
public int SkipTop;
|
||||||
|
public int SkipBottom;
|
||||||
|
public int MbLmin;
|
||||||
|
public int MbLmax;
|
||||||
|
public int BidirRefine;
|
||||||
|
public int KeyintMin;
|
||||||
|
public int Refs;
|
||||||
|
public int Mv0Threshold;
|
||||||
|
public int ColorPrimaries;
|
||||||
|
public int ColorPrc;
|
||||||
|
public int Colorspace;
|
||||||
|
public int ColorRange;
|
||||||
|
public int ChromaSampleLocation;
|
||||||
|
public int Slices;
|
||||||
|
public int FieldOrder;
|
||||||
|
public int SampleRate;
|
||||||
|
public int Channels;
|
||||||
|
public int SampleFmt;
|
||||||
|
public int FrameSize;
|
||||||
|
public int FrameNumber;
|
||||||
|
public int BlockAlign;
|
||||||
|
public int CutOff;
|
||||||
|
public ulong ChannelLayout;
|
||||||
|
public ulong RequestChannelLayout;
|
||||||
|
public int AudioServiceType;
|
||||||
|
public int RequestSampleFmt;
|
||||||
|
public IntPtr GetBuffer2;
|
||||||
|
public float QCompress;
|
||||||
|
public float QBlur;
|
||||||
|
public int QMin;
|
||||||
|
public int QMax;
|
||||||
|
public int MaxQdiff;
|
||||||
|
public int RcBufferSize;
|
||||||
|
public int RcOverrideCount;
|
||||||
|
public IntPtr RcOverride;
|
||||||
|
public long RcMaxRate;
|
||||||
|
public long RcMinRate;
|
||||||
|
public float RcMax_available_vbv_use;
|
||||||
|
public float RcMin_vbv_overflow_use;
|
||||||
|
public int RcInitialBufferOccupancy;
|
||||||
|
public int Trellis;
|
||||||
|
public IntPtr StatsOut;
|
||||||
|
public IntPtr StatsIn;
|
||||||
|
public int WorkaroundBugs;
|
||||||
|
public int StrictStdCompliance;
|
||||||
|
public int ErrorConcealment;
|
||||||
|
public int Debug;
|
||||||
|
public int ErrRecognition;
|
||||||
|
public long ReorderedOpaque;
|
||||||
|
public IntPtr HwAccel;
|
||||||
|
public IntPtr HwAccelContext;
|
||||||
|
public Array8<ulong> Error;
|
||||||
|
public int DctAlgo;
|
||||||
|
public int IdctAlgo;
|
||||||
|
public int BitsPerCodedSample;
|
||||||
|
public int BitsPerRawSample;
|
||||||
|
public int LowRes;
|
||||||
|
public int ThreadCount;
|
||||||
|
public int ThreadType;
|
||||||
|
public int ActiveThreadType;
|
||||||
|
public int ThreadSafeCallbacks;
|
||||||
|
public IntPtr Execute;
|
||||||
|
public IntPtr Execute2;
|
||||||
|
public int NsseWeight;
|
||||||
|
public int Profile;
|
||||||
|
public int Level;
|
||||||
|
public int SkipLoopFilter;
|
||||||
|
public int SkipIdct;
|
||||||
|
public int SkipFrame;
|
||||||
|
public IntPtr SubtitleHeader;
|
||||||
|
public int SubtitleHeaderSize;
|
||||||
|
public int InitialPadding;
|
||||||
|
public AVRational Framerate;
|
||||||
|
public int SwPixFmt;
|
||||||
|
public AVRational PktTimebase;
|
||||||
|
public IntPtr CodecDescriptor;
|
||||||
|
public long PtsCorrectionNumFaultyPts;
|
||||||
|
public long PtsCorrectionNumFaultyDts;
|
||||||
|
public long PtsCorrectionLastPts;
|
||||||
|
public long PtsCorrectionLastDts;
|
||||||
|
public IntPtr SubCharenc;
|
||||||
|
public int SubCharencMode;
|
||||||
|
public int SkipAlpha;
|
||||||
|
public int SeekPreroll;
|
||||||
|
public int DebugMv;
|
||||||
|
public IntPtr ChromaIntraMatrix;
|
||||||
|
public IntPtr DumpSeparator;
|
||||||
|
public IntPtr CodecWhitelist;
|
||||||
|
public uint Properties;
|
||||||
|
public IntPtr CodedSideData;
|
||||||
|
public int NbCodedSideData;
|
||||||
|
public IntPtr HwFramesCtx;
|
||||||
|
public int SubTextFormat;
|
||||||
|
public int TrailingPadding;
|
||||||
|
public long MaxPixels;
|
||||||
|
public IntPtr HwDeviceCtx;
|
||||||
|
public int HwAccelFlags;
|
||||||
|
public int applyCropping;
|
||||||
|
public int ExtraHwFrames;
|
||||||
|
public int DiscardDamagedPercentage;
|
||||||
|
public long MaxSamples;
|
||||||
|
public int ExportSideData;
|
||||||
|
public IntPtr GetEncodeBuffer;
|
||||||
|
#pragma warning restore CS0649
|
||||||
|
}
|
||||||
|
}
|
8
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecID.cs
Normal file
8
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecID.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
|
{
|
||||||
|
enum AVCodecID
|
||||||
|
{
|
||||||
|
AV_CODEC_ID_H264 = 27,
|
||||||
|
AV_CODEC_ID_VP8 = 139,
|
||||||
|
}
|
||||||
|
}
|
26
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecLegacy.cs
Normal file
26
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecLegacy.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
|
{
|
||||||
|
struct AVCodecLegacy
|
||||||
|
{
|
||||||
|
#pragma warning disable CS0649
|
||||||
|
public unsafe byte* Name;
|
||||||
|
public unsafe byte* LongName;
|
||||||
|
public int Type;
|
||||||
|
public AVCodecID Id;
|
||||||
|
public int Capabilities;
|
||||||
|
public byte MaxLowRes;
|
||||||
|
public unsafe AVRational* SupportedFramerates;
|
||||||
|
public IntPtr PixFmts;
|
||||||
|
public IntPtr SupportedSamplerates;
|
||||||
|
public IntPtr SampleFmts;
|
||||||
|
// Deprecated
|
||||||
|
public unsafe ulong* ChannelLayouts;
|
||||||
|
public unsafe IntPtr PrivClass;
|
||||||
|
public IntPtr Profiles;
|
||||||
|
public unsafe byte* WrapperName;
|
||||||
|
public IntPtr ChLayouts;
|
||||||
|
#pragma warning restore CS0649
|
||||||
|
}
|
||||||
|
}
|
37
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVFrame.cs
Normal file
37
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVFrame.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using Ryujinx.Common.Memory;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
|
{
|
||||||
|
struct AVFrame
|
||||||
|
{
|
||||||
|
#pragma warning disable CS0649
|
||||||
|
public Array8<IntPtr> Data;
|
||||||
|
public Array8<int> LineSize;
|
||||||
|
public IntPtr ExtendedData;
|
||||||
|
public int Width;
|
||||||
|
public int Height;
|
||||||
|
public int NumSamples;
|
||||||
|
public int Format;
|
||||||
|
public int KeyFrame;
|
||||||
|
public int PictureType;
|
||||||
|
public AVRational SampleAspectRatio;
|
||||||
|
public long Pts;
|
||||||
|
public long PktDts;
|
||||||
|
public AVRational TimeBase;
|
||||||
|
public int CodedPictureNumber;
|
||||||
|
public int DisplayPictureNumber;
|
||||||
|
public int Quality;
|
||||||
|
public IntPtr Opaque;
|
||||||
|
public int RepeatPicture;
|
||||||
|
public int InterlacedFrame;
|
||||||
|
public int TopFieldFirst;
|
||||||
|
public int PaletteHasChanged;
|
||||||
|
public long ReorderedOpaque;
|
||||||
|
public int SampleRate;
|
||||||
|
public ulong ChannelLayout;
|
||||||
|
#pragma warning restore CS0649
|
||||||
|
|
||||||
|
// NOTE: There is more after, but the layout kind of changed a bit and we don't need more than this. This is safe as we only manipulate this behind a reference.
|
||||||
|
}
|
||||||
|
}
|
15
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVLog.cs
Normal file
15
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVLog.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
|
{
|
||||||
|
enum AVLog
|
||||||
|
{
|
||||||
|
Panic = 0,
|
||||||
|
Fatal = 8,
|
||||||
|
Error = 16,
|
||||||
|
Warning = 24,
|
||||||
|
Info = 32,
|
||||||
|
Verbose = 40,
|
||||||
|
Debug = 48,
|
||||||
|
Trace = 56,
|
||||||
|
MaxOffset = 64
|
||||||
|
}
|
||||||
|
}
|
26
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVPacket.cs
Normal file
26
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVPacket.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
using AVBufferRef = System.IntPtr;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
|
{
|
||||||
|
struct AVPacket
|
||||||
|
{
|
||||||
|
#pragma warning disable CS0649
|
||||||
|
public unsafe AVBufferRef *Buf;
|
||||||
|
public long Pts;
|
||||||
|
public long Dts;
|
||||||
|
public unsafe byte* Data;
|
||||||
|
public int Size;
|
||||||
|
public int StreamIndex;
|
||||||
|
public int Flags;
|
||||||
|
public IntPtr SizeData;
|
||||||
|
public int SizeDataElems;
|
||||||
|
public long Duration;
|
||||||
|
public long Position;
|
||||||
|
public IntPtr Opaque;
|
||||||
|
public unsafe AVBufferRef *OpaqueRef;
|
||||||
|
public AVRational TimeBase;
|
||||||
|
#pragma warning restore CS0649
|
||||||
|
}
|
||||||
|
}
|
8
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVRational.cs
Normal file
8
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVRational.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
|
{
|
||||||
|
public struct AVRational
|
||||||
|
{
|
||||||
|
public int Numerator;
|
||||||
|
public int Denominator;
|
||||||
|
}
|
||||||
|
}
|
23
Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs
Normal file
23
Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
|
{
|
||||||
|
struct FFCodec
|
||||||
|
{
|
||||||
|
public unsafe delegate int AVCodec_decode(AVCodecContext* avctx, void* outdata, int* got_frame_ptr, AVPacket* avpkt);
|
||||||
|
|
||||||
|
#pragma warning disable CS0649
|
||||||
|
public AVCodec Base;
|
||||||
|
public int CapsInternalOrCbType;
|
||||||
|
public int PrivDataSize;
|
||||||
|
public IntPtr UpdateThreadContext;
|
||||||
|
public IntPtr UpdateThreadContextForUser;
|
||||||
|
public IntPtr Defaults;
|
||||||
|
public IntPtr InitStaticData;
|
||||||
|
public IntPtr Init;
|
||||||
|
public IntPtr CodecCallback;
|
||||||
|
#pragma warning restore CS0649
|
||||||
|
|
||||||
|
// NOTE: There is more after, but the layout kind of changed a bit and we don't need more than this. This is safe as we only manipulate this behind a reference.
|
||||||
|
}
|
||||||
|
}
|
23
Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodecLegacy.cs
Normal file
23
Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodecLegacy.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
|
{
|
||||||
|
struct FFCodecLegacy<T> where T: struct
|
||||||
|
{
|
||||||
|
#pragma warning disable CS0649
|
||||||
|
public T Base;
|
||||||
|
public uint CapsInternalOrCbType;
|
||||||
|
public int PrivDataSize;
|
||||||
|
public IntPtr UpdateThreadContext;
|
||||||
|
public IntPtr UpdateThreadContextForUser;
|
||||||
|
public IntPtr Defaults;
|
||||||
|
public IntPtr InitStaticData;
|
||||||
|
public IntPtr Init;
|
||||||
|
public IntPtr EncodeSub;
|
||||||
|
public IntPtr Encode2;
|
||||||
|
public IntPtr Decode;
|
||||||
|
#pragma warning restore CS0649
|
||||||
|
|
||||||
|
// NOTE: There is more after, but the layout kind of changed a bit and we don't need more than this. This is safe as we only manipulate this behind a reference.
|
||||||
|
}
|
||||||
|
}
|
129
Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs
Normal file
129
Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
|
{
|
||||||
|
static class FFmpegApi
|
||||||
|
{
|
||||||
|
public const string AvCodecLibraryName = "avcodec";
|
||||||
|
public const string AvUtilLibraryName = "avutil";
|
||||||
|
|
||||||
|
private static readonly Dictionary<string, (int, int)> _librariesWhitelist = new Dictionary<string, (int, int)>
|
||||||
|
{
|
||||||
|
{ AvCodecLibraryName, (58, 59) },
|
||||||
|
{ AvUtilLibraryName, (56, 57) }
|
||||||
|
};
|
||||||
|
|
||||||
|
private static string FormatLibraryNameForCurrentOs(string libraryName, int version)
|
||||||
|
{
|
||||||
|
if (OperatingSystem.IsWindows())
|
||||||
|
{
|
||||||
|
return $"{libraryName}-{version}.dll";
|
||||||
|
}
|
||||||
|
else if (OperatingSystem.IsLinux())
|
||||||
|
{
|
||||||
|
return $"lib{libraryName}.so.{version}";
|
||||||
|
}
|
||||||
|
else if (OperatingSystem.IsMacOS())
|
||||||
|
{
|
||||||
|
return $"lib{libraryName}.{version}.dylib";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotImplementedException($"Unsupported OS for FFmpeg: {RuntimeInformation.RuntimeIdentifier}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static bool TryLoadWhitelistedLibrary(string libraryName, Assembly assembly, DllImportSearchPath? searchPath, out IntPtr handle)
|
||||||
|
{
|
||||||
|
handle = IntPtr.Zero;
|
||||||
|
|
||||||
|
if (_librariesWhitelist.TryGetValue(libraryName, out var value))
|
||||||
|
{
|
||||||
|
(int minVersion, int maxVersion) = value;
|
||||||
|
|
||||||
|
for (int version = minVersion; version <= maxVersion; version++)
|
||||||
|
{
|
||||||
|
if (NativeLibrary.TryLoad(FormatLibraryNameForCurrentOs(libraryName, version), assembly, searchPath, out handle))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FFmpegApi()
|
||||||
|
{
|
||||||
|
NativeLibrary.SetDllImportResolver(typeof(FFmpegApi).Assembly, (name, assembly, path) =>
|
||||||
|
{
|
||||||
|
IntPtr handle;
|
||||||
|
|
||||||
|
if (name == AvUtilLibraryName && TryLoadWhitelistedLibrary(AvUtilLibraryName, assembly, path, out handle))
|
||||||
|
{
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
else if (name == AvCodecLibraryName && TryLoadWhitelistedLibrary(AvCodecLibraryName, assembly, path, out handle))
|
||||||
|
{
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IntPtr.Zero;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe delegate void av_log_set_callback_callback(void* a0, AVLog level, [MarshalAs(UnmanagedType.LPUTF8Str)] string a2, byte* a3);
|
||||||
|
|
||||||
|
[DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern AVFrame* av_frame_alloc();
|
||||||
|
|
||||||
|
[DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern void av_frame_unref(AVFrame* frame);
|
||||||
|
|
||||||
|
[DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern void av_free(AVFrame* frame);
|
||||||
|
|
||||||
|
[DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern void av_log_set_level(AVLog level);
|
||||||
|
|
||||||
|
[DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern void av_log_set_callback(av_log_set_callback_callback callback);
|
||||||
|
|
||||||
|
[DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern AVLog av_log_get_level();
|
||||||
|
|
||||||
|
[DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern void av_log_format_line(void* ptr, AVLog level, [MarshalAs(UnmanagedType.LPUTF8Str)] string fmt, byte* vl, byte* line, int lineSize, int* printPrefix);
|
||||||
|
|
||||||
|
[DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern AVCodec* avcodec_find_decoder(AVCodecID id);
|
||||||
|
|
||||||
|
[DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern AVCodecContext* avcodec_alloc_context3(AVCodec* codec);
|
||||||
|
|
||||||
|
[DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern int avcodec_open2(AVCodecContext* avctx, AVCodec* codec, void **options);
|
||||||
|
|
||||||
|
[DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern int avcodec_close(AVCodecContext* avctx);
|
||||||
|
|
||||||
|
[DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern void avcodec_free_context(AVCodecContext** avctx);
|
||||||
|
|
||||||
|
[DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern AVPacket* av_packet_alloc();
|
||||||
|
|
||||||
|
[DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern void av_packet_unref(AVPacket* pkt);
|
||||||
|
|
||||||
|
[DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern void av_packet_free(AVPacket** pkt);
|
||||||
|
|
||||||
|
[DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static unsafe extern int avcodec_version();
|
||||||
|
}
|
||||||
|
}
|
@@ -1,14 +1,10 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="FFmpeg.AutoGen" Version="4.4.1" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
|
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.Video\Ryujinx.Graphics.Video.csproj" />
|
<ProjectReference Include="..\Ryujinx.Graphics.Video\Ryujinx.Graphics.Video.csproj" />
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
using FFmpeg.AutoGen;
|
using Ryujinx.Graphics.Nvdec.FFmpeg.Native;
|
||||||
using Ryujinx.Graphics.Video;
|
using Ryujinx.Graphics.Video;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
@@ -11,31 +11,31 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
|||||||
public int RequestedWidth { get; }
|
public int RequestedWidth { get; }
|
||||||
public int RequestedHeight { get; }
|
public int RequestedHeight { get; }
|
||||||
|
|
||||||
public Plane YPlane => new Plane((IntPtr)Frame->data[0], Stride * Height);
|
public Plane YPlane => new Plane((IntPtr)Frame->Data[0], Stride * Height);
|
||||||
public Plane UPlane => new Plane((IntPtr)Frame->data[1], UvStride * UvHeight);
|
public Plane UPlane => new Plane((IntPtr)Frame->Data[1], UvStride * UvHeight);
|
||||||
public Plane VPlane => new Plane((IntPtr)Frame->data[2], UvStride * UvHeight);
|
public Plane VPlane => new Plane((IntPtr)Frame->Data[2], UvStride * UvHeight);
|
||||||
|
|
||||||
public FrameField Field => Frame->interlaced_frame != 0 ? FrameField.Interlaced : FrameField.Progressive;
|
public FrameField Field => Frame->InterlacedFrame != 0 ? FrameField.Interlaced : FrameField.Progressive;
|
||||||
|
|
||||||
public int Width => Frame->width;
|
public int Width => Frame->Width;
|
||||||
public int Height => Frame->height;
|
public int Height => Frame->Height;
|
||||||
public int Stride => Frame->linesize[0];
|
public int Stride => Frame->LineSize[0];
|
||||||
public int UvWidth => (Width + 1) >> 1;
|
public int UvWidth => (Width + 1) >> 1;
|
||||||
public int UvHeight => (Height + 1) >> 1;
|
public int UvHeight => (Height + 1) >> 1;
|
||||||
public int UvStride => Frame->linesize[1];
|
public int UvStride => Frame->LineSize[1];
|
||||||
|
|
||||||
public Surface(int width, int height)
|
public Surface(int width, int height)
|
||||||
{
|
{
|
||||||
RequestedWidth = width;
|
RequestedWidth = width;
|
||||||
RequestedHeight = height;
|
RequestedHeight = height;
|
||||||
|
|
||||||
Frame = ffmpeg.av_frame_alloc();
|
Frame = FFmpegApi.av_frame_alloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
ffmpeg.av_frame_unref(Frame);
|
FFmpegApi.av_frame_unref(Frame);
|
||||||
ffmpeg.av_free(Frame);
|
FFmpegApi.av_free(Frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
using FFmpeg.AutoGen;
|
using Ryujinx.Graphics.Nvdec.FFmpeg.Native;
|
||||||
using Ryujinx.Graphics.Video;
|
using Ryujinx.Graphics.Video;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
@@ -92,7 +92,11 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
pushOpInfo.Consumers.Add(rightBlock, local);
|
pushOpInfo.Consumers.Add(rightBlock, local);
|
||||||
}
|
}
|
||||||
|
|
||||||
rightBlock.SyncTargets.Union(SyncTargets);
|
foreach ((ulong key, SyncTarget value) in SyncTargets)
|
||||||
|
{
|
||||||
|
rightBlock.SyncTargets.Add(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
SyncTargets.Clear();
|
SyncTargets.Clear();
|
||||||
|
|
||||||
// Move push ops.
|
// Move push ops.
|
||||||
|
@@ -340,7 +340,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
{
|
{
|
||||||
InstConditional condOp = new InstConditional(op.RawOpCode);
|
InstConditional condOp = new InstConditional(op.RawOpCode);
|
||||||
|
|
||||||
if (op.Name == InstName.Exit && condOp.Ccc != Ccc.T)
|
if ((op.Name == InstName.Bra || op.Name == InstName.Exit) && condOp.Ccc != Ccc.T)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -672,6 +672,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
// Make sure we found the correct address,
|
// Make sure we found the correct address,
|
||||||
// the push and pop instruction types must match, so:
|
// the push and pop instruction types must match, so:
|
||||||
// - BRK can only consume addresses pushed by PBK.
|
// - BRK can only consume addresses pushed by PBK.
|
||||||
|
// - CONT can only consume addresses pushed by PCNT.
|
||||||
// - SYNC can only consume addresses pushed by SSY.
|
// - SYNC can only consume addresses pushed by SSY.
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
|
@@ -45,12 +45,12 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
if (isFP64)
|
if (isFP64)
|
||||||
{
|
{
|
||||||
return context.PackDouble2x32(
|
return context.PackDouble2x32(
|
||||||
context.Config.CreateCbuf(cbufSlot, cbufOffset),
|
Cbuf(cbufSlot, cbufOffset),
|
||||||
context.Config.CreateCbuf(cbufSlot, cbufOffset + 1));
|
Cbuf(cbufSlot, cbufOffset + 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return context.Config.CreateCbuf(cbufSlot, cbufOffset);
|
return Cbuf(cbufSlot, cbufOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -300,6 +300,11 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
|
|
||||||
if (operand.Type != OperandType.LocalVariable)
|
if (operand.Type != OperandType.LocalVariable)
|
||||||
{
|
{
|
||||||
|
if (operand.Type == OperandType.ConstantBuffer)
|
||||||
|
{
|
||||||
|
Config.SetUsedConstantBuffer(operand.GetCbufSlot());
|
||||||
|
}
|
||||||
|
|
||||||
return new AstOperand(operand);
|
return new AstOperand(operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -68,7 +68,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||||||
{
|
{
|
||||||
Operand addrLow = operation.GetSource(0);
|
Operand addrLow = operation.GetSource(0);
|
||||||
|
|
||||||
Operand baseAddrLow = config.CreateCbuf(0, GetStorageCbOffset(config.Stage, storageIndex));
|
Operand baseAddrLow = Cbuf(0, GetStorageCbOffset(config.Stage, storageIndex));
|
||||||
|
|
||||||
Operand baseAddrTrunc = Local();
|
Operand baseAddrTrunc = Local();
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||||||
{
|
{
|
||||||
Operand addrLow = operation.GetSource(0);
|
Operand addrLow = operation.GetSource(0);
|
||||||
|
|
||||||
Operand baseAddrLow = config.CreateCbuf(0, UbeBaseOffset + storageIndex * StorageDescSize);
|
Operand baseAddrLow = Cbuf(0, UbeBaseOffset + storageIndex * StorageDescSize);
|
||||||
|
|
||||||
Operand baseAddrTrunc = Local();
|
Operand baseAddrTrunc = Local();
|
||||||
|
|
||||||
|
@@ -75,9 +75,9 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
int cbOffset = GetStorageCbOffset(config.Stage, slot);
|
int cbOffset = GetStorageCbOffset(config.Stage, slot);
|
||||||
|
|
||||||
Operand baseAddrLow = config.CreateCbuf(0, cbOffset);
|
Operand baseAddrLow = Cbuf(0, cbOffset);
|
||||||
Operand baseAddrHigh = config.CreateCbuf(0, cbOffset + 1);
|
Operand baseAddrHigh = Cbuf(0, cbOffset + 1);
|
||||||
Operand size = config.CreateCbuf(0, cbOffset + 2);
|
Operand size = Cbuf(0, cbOffset + 2);
|
||||||
|
|
||||||
Operand offset = PrependOperation(Instruction.Subtract, addrLow, baseAddrLow);
|
Operand offset = PrependOperation(Instruction.Subtract, addrLow, baseAddrLow);
|
||||||
Operand borrow = PrependOperation(Instruction.CompareLessU32, addrLow, baseAddrLow);
|
Operand borrow = PrependOperation(Instruction.CompareLessU32, addrLow, baseAddrLow);
|
||||||
@@ -164,7 +164,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
|
bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
|
||||||
|
|
||||||
bool isCoordNormalized = !isBindless && config.GpuAccessor.QueryTextureCoordNormalized(texOp.Handle, texOp.CbufSlot);
|
bool isCoordNormalized = isBindless || config.GpuAccessor.QueryTextureCoordNormalized(texOp.Handle, texOp.CbufSlot);
|
||||||
|
|
||||||
if (!hasInvalidOffset && isCoordNormalized)
|
if (!hasInvalidOffset && isCoordNormalized)
|
||||||
{
|
{
|
||||||
|
@@ -360,12 +360,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
UsedFeatures |= flags;
|
UsedFeatures |= flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Operand CreateCbuf(int slot, int offset)
|
|
||||||
{
|
|
||||||
SetUsedConstantBuffer(slot);
|
|
||||||
return OperandHelper.Cbuf(slot, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetUsedConstantBuffer(int slot)
|
public void SetUsedConstantBuffer(int slot)
|
||||||
{
|
{
|
||||||
_usedConstantBuffers |= 1 << slot;
|
_usedConstantBuffers |= 1 << slot;
|
||||||
|
@@ -184,18 +184,35 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
|||||||
|
|
||||||
public LinuxError Receive(out int receiveSize, Span<byte> buffer, BsdSocketFlags flags)
|
public LinuxError Receive(out int receiveSize, Span<byte> buffer, BsdSocketFlags flags)
|
||||||
{
|
{
|
||||||
|
LinuxError result;
|
||||||
|
|
||||||
|
bool shouldBlockAfterOperation = false;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (Blocking && flags.HasFlag(BsdSocketFlags.DontWait))
|
||||||
|
{
|
||||||
|
Blocking = false;
|
||||||
|
shouldBlockAfterOperation = true;
|
||||||
|
}
|
||||||
|
|
||||||
receiveSize = Socket.Receive(buffer, ConvertBsdSocketFlags(flags));
|
receiveSize = Socket.Receive(buffer, ConvertBsdSocketFlags(flags));
|
||||||
|
|
||||||
return LinuxError.SUCCESS;
|
result = LinuxError.SUCCESS;
|
||||||
}
|
}
|
||||||
catch (SocketException exception)
|
catch (SocketException exception)
|
||||||
{
|
{
|
||||||
receiveSize = -1;
|
receiveSize = -1;
|
||||||
|
|
||||||
return WinSockHelper.ConvertError((WsaError)exception.ErrorCode);
|
result = WinSockHelper.ConvertError((WsaError)exception.ErrorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shouldBlockAfterOperation)
|
||||||
|
{
|
||||||
|
Blocking = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LinuxError ReceiveFrom(out int receiveSize, Span<byte> buffer, int size, BsdSocketFlags flags, out IPEndPoint remoteEndPoint)
|
public LinuxError ReceiveFrom(out int receiveSize, Span<byte> buffer, int size, BsdSocketFlags flags, out IPEndPoint remoteEndPoint)
|
||||||
@@ -304,7 +321,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
|||||||
return LinuxError.EOPNOTSUPP;
|
return LinuxError.EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int value = MemoryMarshal.Read<int>(optionValue);
|
int value = optionValue.Length >= 4 ? MemoryMarshal.Read<int>(optionValue) : MemoryMarshal.Read<byte>(optionValue);
|
||||||
|
|
||||||
if (option == BsdSocketOption.SoLinger)
|
if (option == BsdSocketOption.SoLinger)
|
||||||
{
|
{
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<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="5.0.1-build10" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@@ -19,7 +19,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="GtkSharp" Version="3.22.25.128" />
|
<PackageReference Include="GtkSharp" Version="3.22.25.128" />
|
||||||
<PackageReference Include="GtkSharp.Dependencies" Version="1.1.1" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" />
|
<PackageReference Include="GtkSharp.Dependencies" Version="1.1.1" 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.Graphics.Nvdec.Dependencies" Version="5.0.1-build10" 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="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" />
|
||||||
<PackageReference Include="OpenTK.Graphics" Version="4.7.2" />
|
<PackageReference Include="OpenTK.Graphics" Version="4.7.2" />
|
||||||
<PackageReference Include="SPB" Version="0.0.4-build17" />
|
<PackageReference Include="SPB" Version="0.0.4-build17" />
|
||||||
|
@@ -1509,7 +1509,7 @@
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckButton" id="_internetToggle">
|
<object class="GtkCheckButton" id="_internetToggle">
|
||||||
<property name="label" translatable="yes">Enable guest Internet access</property>
|
<property name="label" translatable="yes">Enable Guest Internet Access</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="can-focus">True</property>
|
||||||
<property name="receives-default">False</property>
|
<property name="receives-default">False</property>
|
||||||
@@ -1643,7 +1643,7 @@
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkRadioButton" id="_mmHostUnsafe">
|
<object class="GtkRadioButton" id="_mmHostUnsafe">
|
||||||
<property name="label" translatable="yes">Host unchecked (fastest, unsafe)</property>
|
<property name="label" translatable="yes">Host Unchecked (fastest, unsafe)</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="can-focus">True</property>
|
||||||
<property name="receives-default">False</property>
|
<property name="receives-default">False</property>
|
||||||
@@ -1725,7 +1725,7 @@
|
|||||||
<property name="can-focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="margin-bottom">5</property>
|
<property name="margin-bottom">5</property>
|
||||||
<property name="label" translatable="yes"> - These may cause instability</property>
|
<property name="label" translatable="yes"> (may cause instability)</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -1749,7 +1749,7 @@
|
|||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckButton" id="_expandRamToggle">
|
<object class="GtkCheckButton" id="_expandRamToggle">
|
||||||
<property name="label" translatable="yes">Expand DRAM size to 6GB</property>
|
<property name="label" translatable="yes">Expand DRAM Size to 6GB</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="can-focus">True</property>
|
||||||
<property name="receives-default">False</property>
|
<property name="receives-default">False</property>
|
||||||
|
Reference in New Issue
Block a user