Halide  20.0.0
Halide compiler and libraries
vulkan_interface.h
Go to the documentation of this file.
1 #ifndef HALIDE_RUNTIME_VULKAN_INTERFACE_H
2 #define HALIDE_RUNTIME_VULKAN_INTERFACE_H
3 
4 #include "runtime_internal.h"
5 
6 // --------------------------------------------------------------------------
7 // Vulkan Specific Definitions
8 // --------------------------------------------------------------------------
9 
10 // Environment variable string delimiter
11 #ifdef WINDOWS
12 #define HL_VK_ENV_DELIM ";"
13 #else
14 #define HL_VK_ENV_DELIM ":"
15 #endif
16 
17 // Prototypes for the subset of the Vulkan API we need
18 #define VK_NO_PROTOTYPES
19 // NOLINTNEXTLINE
20 #include <vulkan/vulkan.h>
21 
22 // --------------------------------------------------------------------------
23 // Vulkan API Definition
24 // --------------------------------------------------------------------------
25 
26 namespace Halide {
27 namespace Runtime {
28 namespace Internal {
29 namespace Vulkan {
30 
31 // --------------------------------------------------------------------------
32 
33 // Halide device interface struct for runtime specific function table
35 
36 // --------------------------------------------------------------------------
37 
38 // The default implementation of halide_vulkan_get_symbol attempts to load
39 // the Vulkan loader shared library/DLL, and then get the symbol from it.
40 WEAK void *lib_vulkan = nullptr;
41 
42 extern "C" WEAK void *halide_vulkan_get_symbol(void *user_context, const char *name) {
43  // Only try to load the library if the library isn't already
44  // loaded, or we can't load the symbol from the process already.
45  void *symbol = halide_get_library_symbol(lib_vulkan, name);
46  if (symbol) {
47  return symbol;
48  }
49 
50  const char *lib_names[] = {
51 #ifdef WINDOWS
52  "vulkan-1.dll",
53 #else
54  "libvulkan.so.1",
55  "libvulkan.1.dylib",
56 #endif
57  };
58  for (auto &lib_name : lib_names) {
59  lib_vulkan = halide_load_library(lib_name);
60  if (lib_vulkan) {
61  debug(user_context) << " Loaded Vulkan loader library: " << lib_name << "\n";
62  break;
63  } else {
64  debug(user_context) << " Missing Vulkan loader library: " << lib_name << "\n";
65  }
66  }
67 
69 }
70 
71 // Declare all the function pointers for the Vulkan API methods that will be resolved dynamically
72 // clang-format off
73 #define VULKAN_FN(fn) WEAK PFN_##fn fn = nullptr;
74 #define HL_USE_VULKAN_LOADER_FNS
75 #define HL_USE_VULKAN_INSTANCE_FNS
76 #define HL_USE_VULKAN_DEVICE_FNS
77 #include "vulkan_functions.h"
78 #undef HL_USE_VULKAN_DEVICE_FNS
79 #undef HL_USE_VULKAN_INSTANCE_FNS
80 #undef HL_USE_VULKAN_LOADER_FNS
81 #undef VULKAN_FN
82 // clang-format on
83 
84 // Get the function pointers to the Vulkan loader (to find all available instances)
86  debug(user_context) << " vk_load_vulkan_loader_functions (user_context: " << user_context << ")\n";
87 #define VULKAN_FN(fn) fn = (PFN_##fn)halide_vulkan_get_symbol(user_context, #fn);
88 #define HL_USE_VULKAN_LOADER_FNS
89 #include "vulkan_functions.h"
90 #undef HL_USE_VULKAN_LOADER_FNS
91 #undef VULKAN_FN
92 }
93 
94 // Get the function pointers from the Vulkan loader for the resolved instance API methods.
95 void WEAK vk_load_vulkan_instance_functions(void *user_context, VkInstance instance) {
96  debug(user_context) << " vk_load_vulkan_instance_functions (user_context: " << user_context << ")\n";
97 #define VULKAN_FN(fn) fn = (PFN_##fn)vkGetInstanceProcAddr(instance, #fn);
98 #define HL_USE_VULKAN_INSTANCE_FNS
99 #include "vulkan_functions.h"
100 #undef HL_USE_VULKAN_INSTANCE_FNS
101 #undef VULKAN_FN
102 }
103 
104 // Reset the instance function pointers
106 #define VULKAN_FN(fn) fn = (PFN_##fn)(nullptr);
107 #define HL_USE_VULKAN_INSTANCE_FNS
108 #include "vulkan_functions.h"
109 #undef HL_USE_VULKAN_INSTANCE_FNS
110 #undef VULKAN_FN
111 }
112 
113 // Get the function pointers from the Vulkan instance for the resolved driver API methods.
114 void WEAK vk_load_vulkan_device_functions(void *user_context, VkDevice device) {
115  debug(user_context) << " vk_load_vulkan_device_functions (user_context: " << user_context << ")\n";
116 #define VULKAN_FN(fn) fn = (PFN_##fn)vkGetDeviceProcAddr(device, #fn);
117 #define HL_USE_VULKAN_DEVICE_FNS
118 #include "vulkan_functions.h"
119 #undef HL_USE_VULKAN_DEVICE_FNS
120 #undef VULKAN_FN
121 }
122 
123 // Reset the device function pointers
125 #define VULKAN_FN(fn) fn = (PFN_##fn)(nullptr);
126 #define HL_USE_VULKAN_DEVICE_FNS
127 #include "vulkan_functions.h"
128 #undef HL_USE_VULKAN_DEVICE_FNS
129 #undef VULKAN_FN
130 }
131 
132 // --------------------------------------------------------------------------
133 
134 } // namespace Vulkan
135 } // namespace Internal
136 } // namespace Runtime
137 } // namespace Halide
138 
139 #endif // HALIDE_RUNTIME_VULKAN_INTERFACE_H
void * halide_get_library_symbol(void *lib, const char *name)
void * halide_load_library(const char *name)
void WEAK vk_unload_vulkan_device_functions(void *user_context)
void WEAK vk_unload_vulkan_instance_functions(void *user_context)
void WEAK vk_load_vulkan_loader_functions(void *user_context)
WEAK void * halide_vulkan_get_symbol(void *user_context, const char *name)
void WEAK vk_load_vulkan_device_functions(void *user_context, VkDevice device)
void WEAK vk_load_vulkan_instance_functions(void *user_context, VkInstance instance)
WEAK halide_device_interface_t vulkan_device_interface
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
#define WEAK
Each GPU API provides a halide_device_interface_t struct pointing to the code that manages device all...
void * user_context