single MR with all patches i did, compared to the 2.0.5 release:

See merge request kenji-nx/ryujinx!18
This commit is contained in:
BeZide
2026-01-20 00:10:38 -06:00
committed by KeatonTheBot
parent dc4a51a462
commit 2c1b7bc667
38 changed files with 7401 additions and 598 deletions
+112 -18
View File
@@ -28,6 +28,9 @@ namespace Ryujinx.Graphics.Vulkan
private bool _initialized;
// JNI/Lifecycle Flag
internal volatile bool PresentAllowed = true;
public uint ProgramCount { get; set; } = 0;
internal FormatCapabilities FormatCapabilities { get; private set; }
@@ -49,6 +52,9 @@ namespace Ryujinx.Graphics.Vulkan
internal Lock BackgroundQueueLock { get; private set; }
internal Lock QueueLock { get; private set; }
// SurfaceLock to serialize Create/Destroy/Queries
internal Lock SurfaceLock { get; private set; }
internal MemoryAllocator MemoryAllocator { get; private set; }
internal HostMemoryAllocator HostMemoryAllocator { get; private set; }
internal CommandBufferPool CommandBufferPool { get; private set; }
@@ -500,6 +506,15 @@ namespace Ryujinx.Graphics.Vulkan
Queue = queue;
QueueLock = new();
// Init Locks
SurfaceLock = new();
if (maxQueueCount >= 2)
{
Api.GetDeviceQueue(_device, queueFamilyIndex, 1, out var backgroundQueue);
BackgroundQueue = backgroundQueue;
BackgroundQueueLock = new();
}
LoadFeatures(maxQueueCount, queueFamilyIndex);
QueueFamilyIndex = queueFamilyIndex;
@@ -551,7 +566,7 @@ namespace Ryujinx.Graphics.Vulkan
public IProgram CreateProgram(ShaderSource[] sources, ShaderInfo info)
{
ProgramCount++;
bool isCompute = sources.Length == 1 && sources[0].Stage == ShaderStage.Compute;
if (info.State.HasValue || isCompute)
@@ -1006,13 +1021,100 @@ namespace Ryujinx.Graphics.Vulkan
return !(IsMoltenVk || IsQualcommProprietary);
}
internal unsafe void RecreateSurface()
// ===== Surface/Present Lifecycle helpers =====
public unsafe bool RecreateSurface()
{
SurfaceApi.DestroySurface(_instance.Instance, _surface, null);
if (!PresentAllowed)
{
return false;
}
_surface = _getSurface(_instance.Instance, Api);
lock (SurfaceLock)
{
try
{
if (_surface.Handle != 0)
{
SurfaceApi.DestroySurface(_instance.Instance, _surface, null);
_surface = new SurfaceKHR(0);
}
(_window as Window)?.SetSurface(_surface);
_surface = _getSurface(_instance.Instance, Api);
if (_surface.Handle == 0)
{
return false;
}
( _window as Window )?.SetSurface(_surface);
( _window as Window )?.SetSurfaceQueryAllowed(true);
return true;
}
catch
{
// retry später
return false;
}
}
}
public unsafe void ReleaseSurface()
{
lock (SurfaceLock)
{
try
{
( _window as Window )?.SetSurfaceQueryAllowed(false);
if (_surface.Handle != 0)
{
SurfaceApi.DestroySurface(_instance.Instance, _surface, null);
_surface = new SurfaceKHR(0);
}
}
catch
{
// still
}
( _window as Window )?.OnSurfaceLost();
}
}
public void SetPresentEnabled(bool enabled)
{
PresentAllowed = enabled;
if (!enabled)
{
( _window as Window )?.SetSurfaceQueryAllowed(false);
ReleaseSurface();
}
else
{
_ = RecreateSurface();
}
}
public void SetPresentAllowed(bool allowed)
{
PresentAllowed = allowed;
Logger.Trace?.Print(LogClass.Gpu, $"PresentAllowed={allowed}");
if (allowed)
{
try
{
( _window as Window )?.SetSurfaceQueryAllowed(true);
_window?.SetSize(0, 0);
_ = RecreateSurface();
}
catch { }
}
else
{
( _window as Window )?.SetSurfaceQueryAllowed(false);
}
}
public unsafe void Dispose()
@@ -1034,23 +1136,15 @@ namespace Ryujinx.Graphics.Vulkan
MemoryAllocator.Dispose();
foreach (var shader in Shaders)
{
shader.Dispose();
}
foreach (var shader in Shaders) shader.Dispose();
foreach (var texture in Textures) texture.Release();
foreach (var sampler in Samplers) sampler.Dispose();
foreach (var texture in Textures)
if (_surface.Handle != 0)
{
texture.Release();
SurfaceApi.DestroySurface(_instance.Instance, _surface, null);
}
foreach (var sampler in Samplers)
{
sampler.Dispose();
}
SurfaceApi.DestroySurface(_instance.Instance, _surface, null);
Api.DestroyDevice(_device, null);
_debugMessenger.Dispose();