diff --git a/src/Ryujinx.Graphics.Metal/CommandBufferEncoder.cs b/src/Ryujinx.Graphics.Metal/CommandBufferEncoder.cs index 82584629d..26cb4f5c7 100644 --- a/src/Ryujinx.Graphics.Metal/CommandBufferEncoder.cs +++ b/src/Ryujinx.Graphics.Metal/CommandBufferEncoder.cs @@ -149,7 +149,7 @@ class CommandBufferEncoder { EndCurrentPass(); - var descriptor = new MTLBlitPassDescriptor(); + using var descriptor = new MTLBlitPassDescriptor(); var blitCommandEncoder = _commandBuffer.BlitCommandEncoder(descriptor); CurrentEncoder = blitCommandEncoder; diff --git a/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs b/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs index 55c995760..88731a504 100644 --- a/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs +++ b/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs @@ -176,15 +176,12 @@ namespace Ryujinx.Graphics.Metal public readonly MTLComputeCommandEncoder CreateComputeCommandEncoder() { - var descriptor = new MTLComputePassDescriptor(); + using var descriptor = new MTLComputePassDescriptor(); var computeCommandEncoder = _pipeline.CommandBuffer.ComputeCommandEncoder(descriptor); // Mark all state as dirty to ensure it is set on the encoder SignalDirty(DirtyFlags.ComputeAll); - // Cleanup - descriptor.Dispose(); - return computeCommandEncoder; } diff --git a/src/Ryujinx.Graphics.Metal/Program.cs b/src/Ryujinx.Graphics.Metal/Program.cs index 170f178ad..11e9be55b 100644 --- a/src/Ryujinx.Graphics.Metal/Program.cs +++ b/src/Ryujinx.Graphics.Metal/Program.cs @@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Metal { ShaderSource shader = _shaders[i]; - var compileOptions = new MTLCompileOptions + using var compileOptions = new MTLCompileOptions { PreserveInvariance = true, LanguageVersion = MTLLanguageVersion.Version31, diff --git a/src/Ryujinx.Graphics.Metal/Sampler.cs b/src/Ryujinx.Graphics.Metal/Sampler.cs index 7930627d4..1189288f6 100644 --- a/src/Ryujinx.Graphics.Metal/Sampler.cs +++ b/src/Ryujinx.Graphics.Metal/Sampler.cs @@ -16,7 +16,7 @@ namespace Ryujinx.Graphics.Metal MTLSamplerBorderColor borderColor = GetConstrainedBorderColor(info.BorderColor, out _); - var samplerState = device.NewSamplerState(new MTLSamplerDescriptor + using var descriptor = new MTLSamplerDescriptor { BorderColor = borderColor, MinFilter = minFilter, @@ -31,7 +31,9 @@ namespace Ryujinx.Graphics.Metal TAddressMode = info.AddressV.Convert(), RAddressMode = info.AddressP.Convert(), SupportArgumentBuffers = true - }); + }; + + var samplerState = device.NewSamplerState(descriptor); _mtlSamplerState = samplerState; } diff --git a/src/Ryujinx.Graphics.Metal/Texture.cs b/src/Ryujinx.Graphics.Metal/Texture.cs index 5ca92eb1e..4219f3db9 100644 --- a/src/Ryujinx.Graphics.Metal/Texture.cs +++ b/src/Ryujinx.Graphics.Metal/Texture.cs @@ -151,6 +151,11 @@ namespace Ryujinx.Graphics.Metal TextureBase src = this; TextureBase dst = (TextureBase)destination; + if (!Valid || !dst.Valid) + { + return; + } + var srcImage = GetHandle(); var dstImage = dst.GetHandle(); @@ -203,6 +208,11 @@ namespace Ryujinx.Graphics.Metal TextureBase src = this; TextureBase dst = (TextureBase)destination; + if (!Valid || !dst.Valid) + { + return; + } + var srcImage = GetHandle(); var dstImage = dst.GetHandle(); diff --git a/src/Ryujinx.Graphics.Metal/TextureBase.cs b/src/Ryujinx.Graphics.Metal/TextureBase.cs index 964f06e22..fecd64958 100644 --- a/src/Ryujinx.Graphics.Metal/TextureBase.cs +++ b/src/Ryujinx.Graphics.Metal/TextureBase.cs @@ -2,13 +2,16 @@ using Ryujinx.Graphics.GAL; using SharpMetal.Metal; using System; using System.Runtime.Versioning; +using System.Threading; namespace Ryujinx.Graphics.Metal { [SupportedOSPlatform("macos")] abstract class TextureBase : IDisposable { - private bool _disposed; + private int _isValid = 1; + + public bool Valid => Volatile.Read(ref _isValid) != 0; protected readonly Pipeline Pipeline; protected readonly MTLDevice Device; @@ -35,7 +38,7 @@ namespace Ryujinx.Graphics.Metal public MTLTexture GetHandle() { - if (_disposed) + if (_isValid == 0) { return new MTLTexture(IntPtr.Zero); } @@ -50,11 +53,15 @@ namespace Ryujinx.Graphics.Metal public void Dispose() { - if (MtlTexture != IntPtr.Zero) + bool wasValid = Interlocked.Exchange(ref _isValid, 0) != 0; + + if (wasValid) { - MtlTexture.Dispose(); + if (MtlTexture != IntPtr.Zero) + { + MtlTexture.Dispose(); + } } - _disposed = true; } } }