1 2 /// Loader module for vkdgen. 3 /// Loading bindings is done in 3 steps as follow: 4 /// --- 5 /// import gfx.bindings.vulkan.loader; 6 /// 7 /// // load global commands 8 /// auto globVk = loadVulkanGlobalCmds(); 9 /// 10 /// // load instance commands 11 /// VkInstance inst; 12 /// VkInstanceCreateInfo instCreateInfo = // ... 13 /// globVk.CreateInstance(&instCreateInfo, null, &inst); 14 /// auto instVk = new VkInstanceCmds(inst, globVk); 15 /// 16 /// // load device commands 17 /// VkPhysicalDevice phDev = // ... 18 /// VkDevice dev; 19 /// VkDeviceCreateInfo devCreateInfo = // ... 20 /// instVk.CreateDevice(phDev, &devCreateInfo, null, &dev); 21 /// auto vk = new VkDeviceCmds(dev, instVk); 22 /// 23 /// // vk.CreateBuffer(dev, ...); 24 /// --- 25 module gfx.bindings.vulkan.loader; 26 27 import gfx.bindings.vulkan.vk : VkGlobalCmds; 28 29 import std.exception; 30 31 /// A handle to a shared library 32 alias SharedLib = void*; 33 /// A handle to a shared library symbol 34 alias SharedSym = void*; 35 36 /// Opens a shared library. 37 /// Return null in case of failure. 38 SharedLib openSharedLib(string name); 39 40 /// Load a symbol from a shared library. 41 /// Return null in case of failure. 42 SharedSym loadSharedSym(SharedLib lib, string name); 43 44 /// Close a shared library 45 void closeSharedLib(SharedLib lib); 46 47 48 /// Generic Dynamic lib symbol loader. 49 /// Symbols loaded with such loader must be cast to the appropriate function type. 50 alias SymbolLoader = SharedSym delegate (in string name); 51 52 53 version(Posix) 54 { 55 import std..string : toStringz; 56 import core.sys.posix.dlfcn; 57 58 SharedLib openSharedLib(string name) 59 { 60 return dlopen(toStringz(name), RTLD_LAZY); 61 } 62 63 SharedSym loadSharedSym(SharedLib lib, string name) 64 { 65 return dlsym(lib, toStringz(name)); 66 } 67 68 void closeSharedLib(SharedLib lib) 69 { 70 dlclose(lib); 71 } 72 } 73 version(Windows) 74 { 75 import std..string : toStringz; 76 import core.sys.windows.winbase; 77 78 SharedLib openSharedLib(string name) 79 { 80 return LoadLibraryA(toStringz(name)); 81 } 82 83 SharedSym loadSharedSym(SharedLib lib, string name) 84 { 85 return GetProcAddress(lib, toStringz(name)); 86 } 87 88 void closeSharedLib(SharedLib lib) 89 { 90 FreeLibrary(lib); 91 } 92 } 93 94 /// Load global commands from Vulkan DLL/Shared object. 95 /// Returns: a VkGlobalCmds object 96 VkGlobalCmds loadVulkanGlobalCmds() 97 { 98 import gfx.bindings.vulkan.vk : PFN_vkGetInstanceProcAddr; 99 100 version( Windows ) 101 enum libName = "vulkan-1.dll"; 102 else version ( OSX ) 103 enum libName = "libMoltenVK.dylib"; 104 else version( Posix ) 105 enum libName = "libvulkan.so.1"; 106 else 107 static assert (false, "Vulkan bindings not supported on this OS"); 108 109 auto lib = enforce(openSharedLib(libName), "Cannot open "~libName); 110 111 auto getInstanceProcAddr = enforce( 112 cast(PFN_vkGetInstanceProcAddr)loadSharedSym(lib, "vkGetInstanceProcAddr"), 113 "Could not load vkGetInstanceProcAddr from "~libName 114 ); 115 116 return new VkGlobalCmds(getInstanceProcAddr); 117 }