blob: e25eee08d7aab27aa004e36e442f13e7a4578e49 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
// Copyright (c) 2017 Eric Mellino
// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
//
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
namespace Vulkan
{
public static partial class Vk
{
internal static NativeLibrary s_nativeLib;
static Vk()
{
s_nativeLib = LoadNativeLibrary();
Vk.LoadFunctionPointers();
}
private static NativeLibrary LoadNativeLibrary()
{
return NativeLibrary.Load(GetVulkanName());
}
private static string GetVulkanName()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return "vulkan-1.dll";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
if (RuntimeInformation.OSDescription.Contains("Unix"))
{
// Android
return "libvulkan.so";
}
else
{
// Desktop Linux
return "libvulkan.so.1";
}
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
return "libvulkan.dylib";
}
else
{
throw new PlatformNotSupportedException();
}
}
private static Exception CreateMissingFunctionException()
{
return new InvalidOperationException("The function does not exist or could not be loaded.");
}
}
public abstract class NativeLibrary : IDisposable
{
private readonly string _libraryName;
private readonly IntPtr _libraryHandle;
public IntPtr NativeHandle => _libraryHandle;
public NativeLibrary(string libraryName)
{
_libraryName = libraryName;
_libraryHandle = LoadLibrary(_libraryName);
if (_libraryHandle == IntPtr.Zero)
{
throw new InvalidOperationException("Could not load " + libraryName);
}
}
protected abstract IntPtr LoadLibrary(string libraryName);
protected abstract void FreeLibrary(IntPtr libraryHandle);
protected abstract IntPtr LoadFunction(string functionName);
public IntPtr LoadFunctionPointer(string functionName)
{
if (functionName == null)
{
throw new ArgumentNullException(nameof(functionName));
}
return LoadFunction(functionName);
}
public void Dispose()
{
FreeLibrary(_libraryHandle);
}
public static NativeLibrary Load(string libraryName)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return new WindowsNativeLibrary(libraryName);
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
|| RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
return new UnixNativeLibrary(libraryName);
}
else
{
throw new PlatformNotSupportedException("Cannot load native libraries on this platform: " + RuntimeInformation.OSDescription);
}
}
private class WindowsNativeLibrary : NativeLibrary
{
public WindowsNativeLibrary(string libraryName) : base(libraryName)
{
}
protected override IntPtr LoadLibrary(string libraryName)
{
return Kernel32.LoadLibrary(libraryName);
}
protected override void FreeLibrary(IntPtr libraryHandle)
{
Kernel32.FreeLibrary(libraryHandle);
}
protected override IntPtr LoadFunction(string functionName)
{
Debug.WriteLine("Loading " + functionName);
return Kernel32.GetProcAddress(NativeHandle, functionName);
}
}
private class UnixNativeLibrary : NativeLibrary
{
public UnixNativeLibrary(string libraryName) : base(libraryName)
{
}
protected override IntPtr LoadLibrary(string libraryName)
{
Libdl.dlerror();
IntPtr handle = Libdl.dlopen(libraryName, Libdl.RTLD_NOW);
if (handle == IntPtr.Zero && !Path.IsPathRooted(libraryName))
{
string localPath = Path.Combine(AppContext.BaseDirectory, libraryName);
handle = Libdl.dlopen(localPath, Libdl.RTLD_NOW);
}
return handle;
}
protected override void FreeLibrary(IntPtr libraryHandle)
{
Libdl.dlclose(libraryHandle);
}
protected override IntPtr LoadFunction(string functionName)
{
return Libdl.dlsym(NativeHandle, functionName);
}
}
}
}
|