From 6a3cad22aaa73bfc293323e30e2646e64bcf153a Mon Sep 17 00:00:00 2001 From: Amer Koleci Date: Thu, 1 Jun 2023 16:04:27 +0200 Subject: [PATCH] Dxc: Correct native dll loading. --- Directory.Build.props | 2 +- .../Apis.cs | 85 +++++++++++++++++++ .../01-ClearScreen/01-ClearScreen.csproj | 16 ++++ 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 6d11494..7a95603 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -14,7 +14,7 @@ true $(MSBuildThisFileDirectory)NuGet.config - 1.9.30 + 1.9.31 true diff --git a/src/Vortice.Win32.Graphics.Direct3D.Dxc/Apis.cs b/src/Vortice.Win32.Graphics.Direct3D.Dxc/Apis.cs index fcd4b84..5948a4a 100644 --- a/src/Vortice.Win32.Graphics.Direct3D.Dxc/Apis.cs +++ b/src/Vortice.Win32.Graphics.Direct3D.Dxc/Apis.cs @@ -1,12 +1,97 @@ // Copyright © Amer Koleci and Contributors. // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. +using System.Reflection; + namespace Win32.Graphics.Direct3D.Dxc; public static unsafe partial class Apis { public static ref readonly Guid CLSID_DxcUtils => ref CLSID_DxcLibrary; +#if NET6_0_OR_GREATER + static Apis() + { + NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), OnDllImport); + } + + private static IntPtr OnDllImport(string libraryName, Assembly assembly, DllImportSearchPath? searchPath) + { + if (TryResolveLibrary(libraryName, assembly, searchPath, out IntPtr nativeLibrary)) + { + return nativeLibrary; + } + + return NativeLibrary.Load(libraryName, assembly, searchPath); + } + + private static bool TryResolveLibrary(string libraryName, Assembly assembly, DllImportSearchPath? searchPath, out IntPtr nativeLibrary) + { + nativeLibrary = IntPtr.Zero; + if (libraryName is not "dxcompiler.dll") + return false; + + string rid = RuntimeInformation.RuntimeIdentifier; + + string nugetNativeLibsPath = Path.Combine(AppContext.BaseDirectory, "runtimes", rid, "native"); + bool isNuGetRuntimeLibrariesDirectoryPresent = Directory.Exists(nugetNativeLibsPath); + + string dxilLibName = "dxil"; + string dxcompilerName = "dxcompiler"; + + if (OperatingSystem.IsWindows()) + { + dxilLibName = "dxil.dll"; + dxcompilerName = "dxcompiler.dll"; + + if (!isNuGetRuntimeLibrariesDirectoryPresent) + { + rid = RuntimeInformation.ProcessArchitecture switch + { + Architecture.X64 => "win-x64", + Architecture.Arm64 => "win-arm64", + _ => "win-x64" + }; + + nugetNativeLibsPath = Path.Combine(AppContext.BaseDirectory, "runtimes", rid, "native"); + isNuGetRuntimeLibrariesDirectoryPresent = Directory.Exists(nugetNativeLibsPath); + } + } + else if (OperatingSystem.IsLinux()) + { + dxilLibName = "libdxil.so"; + dxcompilerName = "libdxcompiler.so"; + } + else if (OperatingSystem.IsMacOS() || OperatingSystem.IsMacCatalyst()) + { + dxilLibName = "libdxil.dylib"; + dxcompilerName = "libdxcompiler.dylib"; + } + + if (isNuGetRuntimeLibrariesDirectoryPresent) + { + string dxilLibPath = Path.Combine(AppContext.BaseDirectory, "runtimes", rid, "native", dxilLibName); + string dxcompilerPath = Path.Combine(AppContext.BaseDirectory, "runtimes", rid, "native", dxcompilerName); + + if (NativeLibrary.TryLoad(dxilLibPath, assembly, searchPath, out _) && + NativeLibrary.TryLoad(dxcompilerPath, assembly, searchPath, out nativeLibrary)) + { + return true; + } + } + + // Search root path + if (NativeLibrary.TryLoad(dxilLibName, assembly, searchPath, out _) && + NativeLibrary.TryLoad(dxcompilerName, assembly, searchPath, out nativeLibrary)) + { + return true; + } + + nativeLibrary = IntPtr.Zero; + return false; + } +#endif + public static HResult DxcCreateInstance(in Guid rclsid, Guid* riid, void** ppv) { return DxcCreateInstance( diff --git a/src/samples/01-ClearScreen/01-ClearScreen.csproj b/src/samples/01-ClearScreen/01-ClearScreen.csproj index cca32b9..fa77103 100644 --- a/src/samples/01-ClearScreen/01-ClearScreen.csproj +++ b/src/samples/01-ClearScreen/01-ClearScreen.csproj @@ -18,6 +18,22 @@ + + + + + + + + + + + + + + + +