diff --git a/build/props/common.props b/build/props/common.props index 97d706d945..b4f5f6b052 100644 --- a/build/props/common.props +++ b/build/props/common.props @@ -12,14 +12,54 @@ 10 .NET Foundation and Contributors - Fix a minor regression with some OpenGL Span overloads. Read more about the 2.17 update here: https://dotnet.github.io/Silk.NET/blog/apr-2023/silk2170.html + Silk.NET October 2023 Update + + - Added SPIR-V Reflect bindings + - Added SPIR-V Cross bindings + - Added Shaderc bindings + - Added WIC/WindowsCodecs bindings (thanks @hez2010) + - Added multi-channel formats support for OpenAL (thanks @aleksrutins) + - Added EffectTarget support for OpenAL Soft (thanks @okaniku, @doobah) + - Added MoltenVK support for iOS (massive thank you to @zvasya for contributing and testing) + - Added macOS support for the CreateWebGPUSurface helper function (thanks @AsgardXIV) + - Added the ability to load MoltenVK directly as a fallback should the Vulkan Loader be unavailable on macOS + - Added trimming support with an option to enable/disable static-linking support at link time + - Added WinRT interoperability support for Direct3D 11. + - Added the ability to query extensions from specific Vulkan layers using the Silk.NET helpers + - Added extension methods on IGamepad to return Thumbstick state instead of requiring use of the indexers (thanks @jvyden) + - Added ref properties for Vulkan chain constituents (thanks @khitiara) + - Added Apple Silicon binaries for Assimp (thanks @jschieck) + - Added compatibility with Linux distributions using as early as glibc 2.16 + - Added equality operators and IEquatable to Bool32 (thanks @Syncaidius) + - Added ToSystem/ToGeneric as extension methods (rather than plain static functions) to convert to/from Silk.NET.Maths types (thanks @Wafer-EX) + - Added discriminant values to PinObjectMarshaller to tie pinned handles to state to which the pin pertains + - Updated to Vulkan 1.3.266 + - Updated to OpenXR 1.0.30 + - Updated to SDL 2.28.1 + - Updated to MoltenVK 1.2.5 + - Updated to latest WebGPU headers + - Updated to latest OpenCL specifications + - Updated to latest OpenGL specifications + - Improved allocations in the Silk.NET Loader (thanks @Youssef1313) + - Improved robustness of HLU on AOT compilations + - Fixed WGPU not loading with the correct filename on Windows + - Fixed COM V-Table indices not matching the Clang-reported V-Table index in some cases (DirectWrite/D2D1/DComp) + - Fixed OpenAL throwing when loading an extension prefixed with ALC_ instead AL_ + - Fixed WGL.GetApi throwing a NotImplementedException + - Fixed library loading failing on platforms that do not have a libdl.so symlink (we are now using libdl.so.2, thanks @CasualPokePlayer) + - Fixed a StackOverflowException when using SetWindowIcon in some cases with Silk.NET.Windowing + - Fixed GLFW crashing in some cases where multiple windows are used + - Fixed WebGPU using the incorrect size for booleans + - Fixed a memory leak with some string marshalling functions + + If you are using Silk.NET with an iOS or Android application, please enable trimming and set TrimMode to full. OpenCL;OpenGL;OpenAL;OpenGLES;GLES;Vulkan;Assimp;DirectX;GLFW;SDL;Windowing;Input;Gamepad;Joystick;Keyboard;Mouse;SilkTouch;Source;Generator;C#;F#;.NET;DotNet;Mono;Vector;Math;Maths;Numerics;Game;Graphics;Compute;Audio;Sound;Engine;Silk;Silk.NET;Slim.NET;ElgarTK;GPU;Sharp;Science;Scientific;Visualization;Visual;Audiovisual;Windows;macOS;Linux;Android;Bindings;OSX;Wrapper;Native true $(MSBuildThisFileDirectory)/../output_packages https://github.com/dotnet/Silk.NET Git - 2.17.1 + 2.18.0 Silk.NET is a high-speed, advanced library, providing bindings to popular low-level APIs such as OpenGL, OpenCL, OpenAL, OpenXR, GLFW, SDL, Vulkan, Assimp, and DirectX. diff --git a/src/Input/Silk.NET.Input.Common/InputWindowExtensions.cs b/src/Input/Silk.NET.Input.Common/InputWindowExtensions.cs index dd4d971146..4b5935b92b 100644 --- a/src/Input/Silk.NET.Input.Common/InputWindowExtensions.cs +++ b/src/Input/Silk.NET.Input.Common/InputWindowExtensions.cs @@ -13,7 +13,7 @@ namespace Silk.NET.Input /// public static class InputWindowExtensions { - private static List _platforms = new List(); + internal static List _platforms = new List(); /// /// Gets the input platforms currently registered with the input system. diff --git a/src/Input/Silk.NET.Input.Glfw/GlfwInput.cs b/src/Input/Silk.NET.Input.Glfw/GlfwInput.cs index 25f34e5ab6..8d72a78e37 100644 --- a/src/Input/Silk.NET.Input.Glfw/GlfwInput.cs +++ b/src/Input/Silk.NET.Input.Glfw/GlfwInput.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Silk.NET.Windowing; +using System.Linq; using Silk.NET.Windowing.Glfw; namespace Silk.NET.Input.Glfw @@ -10,8 +10,11 @@ public static class GlfwInput { public static void RegisterPlatform() { - Window.Add(new GlfwPlatform()); - InputWindowExtensions.Add(new GlfwInputPlatform()); + GlfwWindowing.RegisterPlatform(); // just in case it's not already + if (!InputWindowExtensions._platforms.OfType().Any()) + { + InputWindowExtensions.Add(new GlfwInputPlatform()); + } } } } diff --git a/src/Input/Silk.NET.Input.Sdl/PublicAPI/net5.0/PublicAPI.Unshipped.txt b/src/Input/Silk.NET.Input.Sdl/PublicAPI/net5.0/PublicAPI.Unshipped.txt index 7dc5c58110..8b4147ce69 100644 --- a/src/Input/Silk.NET.Input.Sdl/PublicAPI/net5.0/PublicAPI.Unshipped.txt +++ b/src/Input/Silk.NET.Input.Sdl/PublicAPI/net5.0/PublicAPI.Unshipped.txt @@ -1 +1,2 @@ #nullable enable +static Silk.NET.Input.Sdl.SdlInput.Use() -> void diff --git a/src/Input/Silk.NET.Input.Sdl/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt b/src/Input/Silk.NET.Input.Sdl/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt index 7dc5c58110..8b4147ce69 100644 --- a/src/Input/Silk.NET.Input.Sdl/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt +++ b/src/Input/Silk.NET.Input.Sdl/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt @@ -1 +1,2 @@ #nullable enable +static Silk.NET.Input.Sdl.SdlInput.Use() -> void diff --git a/src/Input/Silk.NET.Input.Sdl/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/Input/Silk.NET.Input.Sdl/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt index 7dc5c58110..8b4147ce69 100644 --- a/src/Input/Silk.NET.Input.Sdl/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/Input/Silk.NET.Input.Sdl/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -1 +1,2 @@ #nullable enable +static Silk.NET.Input.Sdl.SdlInput.Use() -> void diff --git a/src/Input/Silk.NET.Input.Sdl/PublicAPI/netstandard2.1/PublicAPI.Unshipped.txt b/src/Input/Silk.NET.Input.Sdl/PublicAPI/netstandard2.1/PublicAPI.Unshipped.txt index 7dc5c58110..8b4147ce69 100644 --- a/src/Input/Silk.NET.Input.Sdl/PublicAPI/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/Input/Silk.NET.Input.Sdl/PublicAPI/netstandard2.1/PublicAPI.Unshipped.txt @@ -1 +1,2 @@ #nullable enable +static Silk.NET.Input.Sdl.SdlInput.Use() -> void diff --git a/src/Input/Silk.NET.Input.Sdl/SdlInput.cs b/src/Input/Silk.NET.Input.Sdl/SdlInput.cs index e79b098902..77a5fd79d4 100644 --- a/src/Input/Silk.NET.Input.Sdl/SdlInput.cs +++ b/src/Input/Silk.NET.Input.Sdl/SdlInput.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Silk.NET.Windowing; +using System.Linq; using Silk.NET.Windowing.Sdl; namespace Silk.NET.Input.Sdl @@ -10,8 +10,17 @@ public static class SdlInput { public static void RegisterPlatform() { - Window.Add(new SdlPlatform()); - InputWindowExtensions.Add(new SdlInputPlatform()); + SdlWindowing.RegisterPlatform(); // just in case it's not already + if (!InputWindowExtensions._platforms.OfType().Any()) + { + InputWindowExtensions.Add(new SdlInputPlatform()); + } + } + + public static void Use() // for consistency with windowing + { + InputWindowExtensions.ShouldLoadFirstPartyPlatforms(false); + RegisterPlatform(); } } } diff --git a/src/Lab/Experiments/BlankWindow/BlankWindow.csproj b/src/Lab/Experiments/BlankWindow/BlankWindow.csproj index e88c23b6b0..7fe54daa69 100644 --- a/src/Lab/Experiments/BlankWindow/BlankWindow.csproj +++ b/src/Lab/Experiments/BlankWindow/BlankWindow.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + net7.0 true diff --git a/src/OpenAL/Silk.NET.OpenAL/AL/AL.cs b/src/OpenAL/Silk.NET.OpenAL/AL/AL.cs index a50ad58a95..2f9049d8ea 100644 --- a/src/OpenAL/Silk.NET.OpenAL/AL/AL.cs +++ b/src/OpenAL/Silk.NET.OpenAL/AL/AL.cs @@ -26,7 +26,26 @@ public AL(INativeContext ctx) } /// - public override partial bool IsExtensionPresent(string name); + public override unsafe bool IsExtensionPresent(string name) + { + if (name.StartsWith("ALC_")) + { + // extreme hack for ALC_EXT_EFX which does not have a standard AL variant + var maxName = SilkMarshal.GetMaxSizeOf(name, NativeStringEncoding.UTF8); + var nameNative = name.Length > 256 ? new byte[maxName] : stackalloc byte[maxName]; + SilkMarshal.StringIntoSpan(name, nameNative, NativeStringEncoding.UTF8); + fixed (byte* namePtr = nameNative) + { + return ((delegate* unmanaged[Cdecl]) Context.GetProcAddress("alcIsExtensionPresent")) + (namePtr) == 1; + } + } + + return CoreIsExtensionPresent(name); + } + + [NativeApi(EntryPoint = nameof(IsExtensionPresent))] + private partial bool CoreIsExtensionPresent(string name); /// public SearchPathContainer SearchPaths => _searchPaths ??= new OpenALLibraryNameContainer(_soft); diff --git a/src/Windowing/Silk.NET.Windowing.Common/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/Windowing/Silk.NET.Windowing.Common/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt index 36e2b72022..ebf3117fc5 100644 --- a/src/Windowing/Silk.NET.Windowing.Common/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/Windowing/Silk.NET.Windowing.Common/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -6,3 +6,4 @@ Silk.NET.Windowing.VideoMode.AspectRatioEstimate.get -> Silk.NET.Maths.Vector2D< Silk.NET.Windowing.WindowOptions.TopMost.get -> bool Silk.NET.Windowing.WindowOptions.TopMost.set -> void Silk.NET.Windowing.WindowOptions.WindowOptions(bool isVisible, Silk.NET.Maths.Vector2D position, Silk.NET.Maths.Vector2D size, double framesPerSecond, double updatesPerSecond, Silk.NET.Windowing.GraphicsAPI api, string! title, Silk.NET.Windowing.WindowState windowState, Silk.NET.Windowing.WindowBorder windowBorder, bool isVSync, bool shouldSwapAutomatically, Silk.NET.Windowing.VideoMode videoMode, int? preferredDepthBufferBits = null, int? preferredStencilBufferBits = null, Silk.NET.Maths.Vector4D? preferredBitDepth = null, bool transparentFramebuffer = false, bool topMost = false, bool isEventDriven = false, Silk.NET.Core.Contexts.IGLContext? sharedContext = null, int? samples = null, string? windowClass = null, bool isContextControlDisabled = false) -> void +static Silk.NET.Windowing.Window.PrioritizeOrAdd(System.Func! factory, bool isFirstParty = false) -> T diff --git a/src/Windowing/Silk.NET.Windowing.Common/PublicAPI/netstandard2.1/PublicAPI.Unshipped.txt b/src/Windowing/Silk.NET.Windowing.Common/PublicAPI/netstandard2.1/PublicAPI.Unshipped.txt index 1375c83df3..4f6a83f143 100644 --- a/src/Windowing/Silk.NET.Windowing.Common/PublicAPI/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/Windowing/Silk.NET.Windowing.Common/PublicAPI/netstandard2.1/PublicAPI.Unshipped.txt @@ -7,3 +7,4 @@ Silk.NET.Windowing.VideoMode.AspectRatioEstimate.get -> Silk.NET.Maths.Vector2D< Silk.NET.Windowing.WindowOptions.TopMost.get -> bool Silk.NET.Windowing.WindowOptions.TopMost.set -> void Silk.NET.Windowing.WindowOptions.WindowOptions(bool isVisible, Silk.NET.Maths.Vector2D position, Silk.NET.Maths.Vector2D size, double framesPerSecond, double updatesPerSecond, Silk.NET.Windowing.GraphicsAPI api, string! title, Silk.NET.Windowing.WindowState windowState, Silk.NET.Windowing.WindowBorder windowBorder, bool isVSync, bool shouldSwapAutomatically, Silk.NET.Windowing.VideoMode videoMode, int? preferredDepthBufferBits = null, int? preferredStencilBufferBits = null, Silk.NET.Maths.Vector4D? preferredBitDepth = null, bool transparentFramebuffer = false, bool topMost = false, bool isEventDriven = false, Silk.NET.Core.Contexts.IGLContext? sharedContext = null, int? samples = null, string? windowClass = null, bool isContextControlDisabled = false) -> void +static Silk.NET.Windowing.Window.PrioritizeOrAdd(System.Func! factory, bool isFirstParty = false) -> T diff --git a/src/Windowing/Silk.NET.Windowing.Common/Window.cs b/src/Windowing/Silk.NET.Windowing.Common/Window.cs index 66c2995c8b..6e86e69255 100644 --- a/src/Windowing/Silk.NET.Windowing.Common/Window.cs +++ b/src/Windowing/Silk.NET.Windowing.Common/Window.cs @@ -264,6 +264,34 @@ public static void PrioritizeSdl() Prioritize(platform); } + /// + /// s the platform of type if it's already been added, + /// otherwise it uses to create an instance to the platform. The + /// instance used is returned. + /// + /// The factory to use if the platform has not been registered. + /// If true, first-party reflection-based loading will be disabled. + /// The platform type. + /// The platform instance. + public static T PrioritizeOrAdd(Func factory, bool isFirstParty = false) where T: IWindowPlatform + { + if (isFirstParty) + { + _initializedFirstPartyPlatforms = true; + } + + var platform = (T?)_platformsValues.FirstOrDefault(x => x is T); + if (platform is null) + { + var inst = factory(); + Add(inst); + return inst; + } + + Prioritize(platform); + return platform; + } + /// /// Adds this window platform to the platform list. Shouldn't be used unless writing your own windowing backend. /// diff --git a/src/Windowing/Silk.NET.Windowing.Glfw/GlfwWindow.cs b/src/Windowing/Silk.NET.Windowing.Glfw/GlfwWindow.cs index 6b74f7b770..2e364abcfa 100644 --- a/src/Windowing/Silk.NET.Windowing.Glfw/GlfwWindow.cs +++ b/src/Windowing/Silk.NET.Windowing.Glfw/GlfwWindow.cs @@ -424,6 +424,7 @@ public override void SetWindowIcon(ReadOnlySpan icons) throw new InvalidOperationException("Window should be initialized."); } + var budget = 1024; if (icons == null) { _glfw.SetWindowIcon(_glfwWindow, 0, null); @@ -431,11 +432,37 @@ public override void SetWindowIcon(ReadOnlySpan icons) else { var images = stackalloc Image[icons.Length]; + nint harr = 0; + var harrLen = 0; + var harrOff = 0; for (var i = 0; i < icons.Length; i++) { var icon = icons[i]; // ReSharper disable once StackAllocInsideLoop - Span iconMemory = stackalloc byte[icon.Pixels.Length]; + var iconMemory = budget >= icon.Pixels.Length + ? stackalloc byte[icon.Pixels.Length] + : harr == 0 + ? null + : new Span((void*)(harr + harrOff), icon.Pixels.Length); + if (iconMemory == null) + { + for (var j = i; j < icons.Length; j++) + { + harrLen += icons[j].Pixels.Length; + } + + harr = SilkMarshal.Allocate(harrLen); + iconMemory = new Span((void*) harr, icon.Pixels.Length); + harrOff = icon.Pixels.Length; + } + else if (budget >= icon.Pixels.Length) + { + budget -= icon.Pixels.Length; + } + else + { + harrOff += icon.Pixels.Length; + } images[i] = new() { Width = icon.Width, Height = icon.Height, @@ -446,6 +473,10 @@ public override void SetWindowIcon(ReadOnlySpan icons) } _glfw.SetWindowIcon(_glfwWindow, icons.Length, images); + if (harr != 0) + { + SilkMarshal.Free(harr); + } GLFW.Glfw.ThrowExceptions(); } } diff --git a/src/Windowing/Silk.NET.Windowing.Glfw/GlfwWindowing.cs b/src/Windowing/Silk.NET.Windowing.Glfw/GlfwWindowing.cs index d3132b4838..e814363e24 100644 --- a/src/Windowing/Silk.NET.Windowing.Glfw/GlfwWindowing.cs +++ b/src/Windowing/Silk.NET.Windowing.Glfw/GlfwWindowing.cs @@ -9,13 +9,16 @@ public static class GlfwWindowing { public static void RegisterPlatform() { - Window.Add(new GlfwPlatform()); + if (Window.GetOrDefault() is null) + { + Window.Add(new GlfwPlatform()); + } } /// /// Prioritizes the GLFW windowing platform over others. /// - public static void Use() => Window.PrioritizeGlfw(); + public static void Use() => Window.PrioritizeOrAdd(() => new GlfwPlatform(), true); /// /// Gets a value indicating whether the given view is a GLFW view. diff --git a/src/Windowing/Silk.NET.Windowing.Sdl/SdlWindowing.cs b/src/Windowing/Silk.NET.Windowing.Sdl/SdlWindowing.cs index ec4c39c71c..488b1805aa 100644 --- a/src/Windowing/Silk.NET.Windowing.Sdl/SdlWindowing.cs +++ b/src/Windowing/Silk.NET.Windowing.Sdl/SdlWindowing.cs @@ -43,7 +43,7 @@ public static unsafe IView CreateFrom(void* handle, IGLContext? ctx = null) /// /// Prioritizes the SDL windowing platform over others. /// - public static void Use() => Window.PrioritizeSdl(); + public static void Use() => Window.PrioritizeOrAdd(() => new SdlPlatform(), true); /// /// Gets a value indicating whether the given view is an SDL view.