From 8a7ccd3019fa2ed27b0c2fa1e5dad33462e0202a Mon Sep 17 00:00:00 2001 From: Eric Mellino Date: Mon, 19 Mar 2018 19:55:07 -0700 Subject: [PATCH] [Metal] Add a real support check for Metal. --- src/Veldrid.MetalBindings/MTLDevice.cs | 3 +++ src/Veldrid.MetalBindings/NSArray.cs | 14 ++++++++++ src/Veldrid/GraphicsDevice.cs | 2 +- src/Veldrid/MTL/MTLGraphicsDevice.cs | 36 ++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 src/Veldrid.MetalBindings/NSArray.cs diff --git a/src/Veldrid.MetalBindings/MTLDevice.cs b/src/Veldrid.MetalBindings/MTLDevice.cs index 39590cccc..716a6672c 100644 --- a/src/Veldrid.MetalBindings/MTLDevice.cs +++ b/src/Veldrid.MetalBindings/MTLDevice.cs @@ -126,6 +126,9 @@ public Bool8 isDepth24Stencil8PixelFormatSupported [DllImport(MetalFramework)] public static extern MTLDevice MTLCreateSystemDefaultDevice(); + [DllImport(MetalFramework)] + public static extern NSArray MTLCopyAllDevices(); + private static readonly Selector sel_name = "name"; private static readonly Selector sel_maxThreadsPerThreadgroup = "maxThreadsPerThreadgroup"; private static readonly Selector sel_newLibraryWithSource = "newLibraryWithSource:options:error:"; diff --git a/src/Veldrid.MetalBindings/NSArray.cs b/src/Veldrid.MetalBindings/NSArray.cs new file mode 100644 index 000000000..8395a6991 --- /dev/null +++ b/src/Veldrid.MetalBindings/NSArray.cs @@ -0,0 +1,14 @@ +using System; +using static Veldrid.MetalBindings.ObjectiveCRuntime; + +namespace Veldrid.MetalBindings +{ + public struct NSArray + { + public readonly IntPtr NativePtr; + public NSArray(IntPtr ptr) => NativePtr = ptr; + + public UIntPtr count => UIntPtr_objc_msgSend(NativePtr, sel_count); + private static readonly Selector sel_count = "count"; + } +} \ No newline at end of file diff --git a/src/Veldrid/GraphicsDevice.cs b/src/Veldrid/GraphicsDevice.cs index 934f251a8..56d4e0053 100644 --- a/src/Veldrid/GraphicsDevice.cs +++ b/src/Veldrid/GraphicsDevice.cs @@ -595,7 +595,7 @@ public static bool IsBackendSupported(GraphicsBackend backend) #endif case GraphicsBackend.Metal: #if !EXCLUDE_METAL_BACKEND - return RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + return MTL.MTLGraphicsDevice.IsSupported(); #else return false; #endif diff --git a/src/Veldrid/MTL/MTLGraphicsDevice.cs b/src/Veldrid/MTL/MTLGraphicsDevice.cs index dce6e5062..34fb3a1f0 100644 --- a/src/Veldrid/MTL/MTLGraphicsDevice.cs +++ b/src/Veldrid/MTL/MTLGraphicsDevice.cs @@ -11,6 +11,8 @@ namespace Veldrid.MTL { internal unsafe class MTLGraphicsDevice : GraphicsDevice { + private static readonly Lazy s_isSupported = new Lazy(GetIsSupported); + private readonly MTLDevice _device; private readonly MTLCommandQueue _commandQueue; private readonly MTLSwapchain _mainSwapchain; @@ -307,6 +309,40 @@ public override void ResetFence(Fence fence) Util.AssertSubtype(fence).Reset(); } + internal static bool IsSupported() => s_isSupported.Value; + + private static bool GetIsSupported() + { + bool result = false; + try + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + if (RuntimeInformation.OSDescription.Contains("Darwin")) + { + NSArray allDevices = MTLDevice.MTLCopyAllDevices(); + result |= (ulong)allDevices.count > 0; + ObjectiveCRuntime.release(allDevices.NativePtr); + } + else + { + MTLDevice defaultDevice = MTLDevice.MTLCreateSystemDefaultDevice(); + if (defaultDevice.NativePtr != IntPtr.Zero) + { + result = true; + ObjectiveCRuntime.release(defaultDevice.NativePtr); + } + } + } + } + catch + { + result = false; + } + + return result; + } + internal MTLComputePipelineState GetUnalignedBufferCopyPipeline() { lock (_unalignedBufferCopyPipelineLock)