Halide 22.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
26namespace Halide {
27namespace Runtime {
28namespace Internal {
29namespace 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.
40WEAK void *lib_vulkan = nullptr;
41
42extern "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 *env_libname = getenv("HL_VK_LOADER_LIB");
51 if (env_libname) {
52 lib_vulkan = halide_load_library(env_libname);
53 if (lib_vulkan) {
54 debug(user_context) << " Loaded Vulkan loader library: " << env_libname << "\n";
55 } else {
56 debug(user_context) << " Missing Vulkan loader library: " << env_libname << "\n";
57 }
58 }
59
60 // First, attempt to find the versioned library (per the Vulkan API docs), otherwise
61 // fallback to unversioned libs, and known common paths
62 if (!lib_vulkan) {
63 const char *lib_names[] = {
64#ifdef WINDOWS
65 "vulkan-1.dll",
66#else
67 "libvulkan.so.1",
68 "libvulkan.so",
69 "libvulkan.1.dylib",
70 "libvulkan.dylib",
71 "/usr/local/lib/libvulkan.dylib", // MacOS ldopen doesn't search here by default
72 "libMoltenVK.dylib",
73 "vulkan.framework/vulkan", // Search for local frameworks (eg for IOS apps)
74 "MoltenVK.framework/MoltenVK"
75#endif
76 };
77 for (auto &lib_name : lib_names) {
79 if (lib_vulkan) {
80 debug(user_context) << " Loaded Vulkan loader library: " << lib_name << "\n";
81 break;
82 } else {
83 debug(user_context) << " Missing Vulkan loader library: " << lib_name << "\n";
84 }
85 }
86 }
87
88 if (!lib_vulkan) {
89 print(user_context) << "WARNING: Could not find a Vulkan loader library!\n"
90 << "(Try setting the env var HL_VK_LOADER_LIB to an explicit path to fix this.)\n";
91 return nullptr;
92 }
93
95}
96
97// Declare all the function pointers for the Vulkan API methods that will be resolved dynamically
98
99#define VULKAN_FN(fn) WEAK PFN_##fn fn = nullptr;
100#define HL_USE_VULKAN_LOADER_FNS
101#define HL_USE_VULKAN_INSTANCE_FNS
102#define HL_USE_VULKAN_DEVICE_FNS
103#include "vulkan_functions.h"
104#undef HL_USE_VULKAN_DEVICE_FNS
105#undef HL_USE_VULKAN_INSTANCE_FNS
106#undef HL_USE_VULKAN_LOADER_FNS
107#undef VULKAN_FN
108
109// Get the function pointers to the Vulkan loader (to find all available instances)
111 debug(user_context) << " vk_load_vulkan_loader_functions (user_context: " << user_context << ")\n";
112#define VULKAN_FN(fn) fn = (PFN_##fn)halide_vulkan_get_symbol(user_context, #fn);
113#define HL_USE_VULKAN_LOADER_FNS
114#include "vulkan_functions.h"
115#undef HL_USE_VULKAN_LOADER_FNS
116#undef VULKAN_FN
117}
118
119// Get the function pointers from the Vulkan loader for the resolved instance API methods.
120void WEAK vk_load_vulkan_instance_functions(void *user_context, VkInstance instance) {
121 debug(user_context) << " vk_load_vulkan_instance_functions (user_context: " << user_context << ")\n";
122#define VULKAN_FN(fn) fn = (PFN_##fn)vkGetInstanceProcAddr(instance, #fn);
123#define HL_USE_VULKAN_INSTANCE_FNS
124#include "vulkan_functions.h"
125#undef HL_USE_VULKAN_INSTANCE_FNS
126#undef VULKAN_FN
127}
128
129// Reset the instance function pointers
131#define VULKAN_FN(fn) fn = (PFN_##fn)(nullptr);
132#define HL_USE_VULKAN_INSTANCE_FNS
133#include "vulkan_functions.h"
134#undef HL_USE_VULKAN_INSTANCE_FNS
135#undef VULKAN_FN
136}
137
138// Get the function pointers from the Vulkan instance for the resolved driver API methods.
140 debug(user_context) << " vk_load_vulkan_device_functions (user_context: " << user_context << ")\n";
141#define VULKAN_FN(fn) fn = (PFN_##fn)vkGetDeviceProcAddr(device, #fn);
142#define HL_USE_VULKAN_DEVICE_FNS
143#include "vulkan_functions.h"
144#undef HL_USE_VULKAN_DEVICE_FNS
145#undef VULKAN_FN
146}
147
148// Reset the device function pointers
150#define VULKAN_FN(fn) fn = (PFN_##fn)(nullptr);
151#define HL_USE_VULKAN_DEVICE_FNS
152#include "vulkan_functions.h"
153#undef HL_USE_VULKAN_DEVICE_FNS
154#undef VULKAN_FN
155}
156
157// --------------------------------------------------------------------------
158
159} // namespace Vulkan
160} // namespace Internal
161} // namespace Runtime
162} // namespace Halide
163
164#endif // HALIDE_RUNTIME_VULKAN_INTERFACE_H
#define debug(n)
For optional debugging during codegen, use the debug macro as follows:
Definition: Debug.h:52
void * halide_get_library_symbol(void *lib, const char *name)
void * halide_load_library(const char *name)
WEAK void * halide_vulkan_get_symbol(void *user_context, 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)
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,...
Expr print(const std::vector< Expr > &values)
Create an Expr that prints out its value whenever it is evaluated.
#define WEAK
char * getenv(const char *)
Each GPU API provides a halide_device_interface_t struct pointing to the code that manages device all...
void * user_context