From af7d4c586c86d67db2ef0e2991d7ee42d24d929c Mon Sep 17 00:00:00 2001 From: V380-Ori Date: Wed, 26 Nov 2025 15:54:06 +0200 Subject: [PATCH 1/2] Shader: skip initialization of all clip distances on macOS. --- src/Ryujinx.Graphics.GAL/Capabilities.cs | 3 +++ src/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs | 2 ++ src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs | 1 + src/Ryujinx.Graphics.Shader/IGpuAccessor.cs | 9 +++++++++ src/Ryujinx.Graphics.Shader/Translation/Translator.cs | 9 ++++++--- src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs | 1 + 6 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Ryujinx.Graphics.GAL/Capabilities.cs b/src/Ryujinx.Graphics.GAL/Capabilities.cs index 1eec80e51..91cd520ba 100644 --- a/src/Ryujinx.Graphics.GAL/Capabilities.cs +++ b/src/Ryujinx.Graphics.GAL/Capabilities.cs @@ -10,6 +10,7 @@ namespace Ryujinx.Graphics.GAL public readonly bool HasFrontFacingBug; public readonly bool HasVectorIndexingBug; + public readonly bool HasClipDistanceInitBug; public readonly bool NeedsFragmentOutputSpecialization; public readonly bool ReduceShaderPrecision; @@ -79,6 +80,7 @@ namespace Ryujinx.Graphics.GAL SystemMemoryType memoryType, bool hasFrontFacingBug, bool hasVectorIndexingBug, + bool hasClipDistanceInitBug, bool needsFragmentOutputSpecialization, bool reduceShaderPrecision, bool supportsAstcCompression, @@ -141,6 +143,7 @@ namespace Ryujinx.Graphics.GAL MemoryType = memoryType; HasFrontFacingBug = hasFrontFacingBug; HasVectorIndexingBug = hasVectorIndexingBug; + HasClipDistanceInitBug = hasClipDistanceInitBug; NeedsFragmentOutputSpecialization = needsFragmentOutputSpecialization; ReduceShaderPrecision = reduceShaderPrecision; SupportsAstcCompression = supportsAstcCompression; diff --git a/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs b/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs index d89eebabf..50386195b 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs @@ -201,6 +201,8 @@ namespace Ryujinx.Graphics.Gpu.Shader public bool QueryHostHasVectorIndexingBug() => _context.Capabilities.HasVectorIndexingBug; + public bool QueryHostHasClipDistanceInitBug() => _context.Capabilities.HasClipDistanceInitBug; + public int QueryHostStorageBufferOffsetAlignment() => _context.Capabilities.StorageBufferOffsetAlignment; public int QueryHostSubgroupSize() => _context.Capabilities.ShaderSubgroupSize; diff --git a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs index af1494bbe..db9f9580e 100644 --- a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs +++ b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs @@ -153,6 +153,7 @@ namespace Ryujinx.Graphics.OpenGL memoryType: SystemMemoryType.BackendManaged, hasFrontFacingBug: intelWindows, hasVectorIndexingBug: amdWindows, + hasClipDistanceInitBug: false, needsFragmentOutputSpecialization: false, reduceShaderPrecision: false, supportsAstcCompression: HwCapabilities.SupportsAstcCompression, diff --git a/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs b/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs index 4e6d6edf9..8262e93e6 100644 --- a/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs +++ b/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs @@ -202,6 +202,15 @@ namespace Ryujinx.Graphics.Shader return false; } + /// + /// Queries host about the presence of the clip distance initialization bug. + /// + /// True if the bug is present on the host device used, false otherwise + bool QueryHostHasClipDistanceInitBug() + { + return false; + } + /// /// Queries host storage buffer alignment required. /// diff --git a/src/Ryujinx.Graphics.Shader/Translation/Translator.cs b/src/Ryujinx.Graphics.Shader/Translation/Translator.cs index 2a1110632..5c9629f48 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/Translator.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/Translator.cs @@ -259,11 +259,14 @@ namespace Ryujinx.Graphics.Shader.Translation context.Store(StorageKind.Output, IoVariable.Position, null, Const(c), ConstF(c == 3 ? 1f : 0f)); } - if (context.Program.ClipDistancesWritten != 0) + if (!context.TranslatorContext.GpuAccessor.QueryHostHasClipDistanceInitBug()) { - for (int i = 0; i < 8; i++) + if (context.Program.ClipDistancesWritten != 0) { - context.Store(StorageKind.Output, IoVariable.ClipDistance, null, Const(i), ConstF(0f)); + for (int i = 0; i < 8; i++) + { + context.Store(StorageKind.Output, IoVariable.ClipDistance, null, Const(i), ConstF(0f)); + } } } } diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs index 5f1c50b00..2193a5731 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs @@ -744,6 +744,7 @@ namespace Ryujinx.Graphics.Vulkan memoryType: memoryType, hasFrontFacingBug: IsIntelWindows, hasVectorIndexingBug: IsQualcommProprietary, + hasClipDistanceInitBug: IsMoltenVk, needsFragmentOutputSpecialization: IsMoltenVk, reduceShaderPrecision: IsMoltenVk, supportsAstcCompression: features2.Features.TextureCompressionAstcLdr && supportsAstcFormats, From 3a593b60845d894ece9e86b967a07e1390949fff Mon Sep 17 00:00:00 2001 From: LotP <22-lotp@users.noreply.git.ryujinx.app> Date: Sat, 6 Dec 2025 20:16:43 -0600 Subject: [PATCH 2/2] Fix kaddressarbiter crash (ryubing/ryujinx!235) See merge request ryubing/ryujinx!235 --- .gitignore | 1 + src/Ryujinx.HLE/HOS/Kernel/Threading/KAddressArbiter.cs | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0c46c50c0..6f887e638 100644 --- a/.gitignore +++ b/.gitignore @@ -100,6 +100,7 @@ DocProject/Help/html # Click-Once directory publish/ +RyubingMaintainerTools/ # Publish Web Output *.Publish.xml diff --git a/src/Ryujinx.HLE/HOS/Kernel/Threading/KAddressArbiter.cs b/src/Ryujinx.HLE/HOS/Kernel/Threading/KAddressArbiter.cs index 3e13b917a..c9ac86fc9 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Threading/KAddressArbiter.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Threading/KAddressArbiter.cs @@ -529,7 +529,13 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading // The value is decremented if the number of threads waiting is less // or equal to the Count of threads to be signaled, or Count is zero // or negative. It is incremented if there are no threads waiting. - int waitingCount = _arbiterThreads[address].Count; + int waitingCount = 0; + + if (_arbiterThreads.TryGetValue(address, out List threads)) + { + waitingCount = threads.Count; + } + if (waitingCount > 0) {