Halide  20.0.0
Halide compiler and libraries
vulkan_extensions.h
Go to the documentation of this file.
1 #ifndef HALIDE_RUNTIME_VULKAN_EXTENSIONS_H
2 #define HALIDE_RUNTIME_VULKAN_EXTENSIONS_H
3 
4 #include "vulkan_internal.h"
5 
6 // --------------------------------------------------------------------------
7 
8 namespace Halide {
9 namespace Runtime {
10 namespace Internal {
11 namespace Vulkan {
12 
13 // --------------------------------------------------------------------------
14 
15 WEAK char layer_names[1024];
18 
19 WEAK char extension_names[1024];
22 
23 WEAK char device_type[256];
26 
27 WEAK char build_options[1024];
30 
31 WEAK char alloc_config[1024];
34 
35 // --------------------------------------------------------------------------
36 namespace {
37 
38 void vk_set_layer_names_internal(const char *n) {
39  if (n) {
40  size_t buffer_size = sizeof(layer_names) / sizeof(layer_names[0]);
41  StringUtils::copy_up_to(layer_names, n, buffer_size);
42  } else {
43  layer_names[0] = 0;
44  }
46 }
47 
48 const char *vk_get_layer_names_internal(void *user_context) {
50  const char *value = getenv("HL_VK_LAYERS");
51  if (value == nullptr) {
52  value = getenv("VK_INSTANCE_LAYERS");
53  }
54  vk_set_layer_names_internal(value);
55  }
56  return layer_names;
57 }
58 
59 void vk_set_extension_names_internal(const char *n) {
60  if (n) {
61  size_t buffer_size = sizeof(extension_names) / sizeof(extension_names[0]);
63  } else {
64  extension_names[0] = 0;
65  }
67 }
68 
69 const char *vk_get_extension_names_internal(void *user_context) {
71  const char *name = getenv("HL_VK_EXTENSIONS");
72  vk_set_extension_names_internal(name);
73  }
74  return extension_names;
75 }
76 
77 void vk_set_device_type_internal(const char *n) {
78  if (n) {
79  size_t buffer_size = sizeof(device_type) / sizeof(device_type[0]);
80  StringUtils::copy_up_to(device_type, n, buffer_size);
81  } else {
82  device_type[0] = 0;
83  }
85 }
86 
87 const char *vk_get_device_type_internal(void *user_context) {
89  const char *name = getenv("HL_VK_DEVICE_TYPE");
90  vk_set_device_type_internal(name);
91  }
92  return device_type;
93 }
94 
95 void vk_set_build_options_internal(const char *n) {
96  if (n) {
97  size_t buffer_size = sizeof(build_options) / sizeof(build_options[0]);
98  StringUtils::copy_up_to(build_options, n, buffer_size);
99  } else {
100  build_options[0] = 0;
101  }
103 }
104 
105 const char *vk_get_build_options_internal(void *user_context) {
107  const char *name = getenv("HL_VK_BUILD_OPTIONS");
108  vk_set_build_options_internal(name);
109  }
110  return build_options;
111 }
112 
113 void vk_set_alloc_config_internal(const char *n) {
114  if (n) {
115  size_t buffer_size = sizeof(alloc_config) / sizeof(alloc_config[0]);
116  StringUtils::copy_up_to(alloc_config, n, buffer_size);
117  } else {
118  alloc_config[0] = 0;
119  }
121 }
122 
123 const char *vk_get_alloc_config_internal(void *user_context) {
125  const char *name = getenv("HL_VK_ALLOC_CONFIG");
126  vk_set_alloc_config_internal(name);
127  }
128  return alloc_config;
129 }
130 
131 // --------------------------------------------------------------------------
132 
133 uint32_t vk_get_requested_layers(void *user_context, StringTable &layer_table) {
135  const char *layer_names = vk_get_layer_names_internal(user_context);
136  return layer_table.parse(user_context, layer_names, HL_VK_ENV_DELIM);
137 }
138 
139 uint32_t vk_get_required_instance_extensions(void *user_context, StringTable &ext_table) {
140  const char *required_ext_table[] = {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME};
141  const uint32_t required_ext_count = sizeof(required_ext_table) / sizeof(required_ext_table[0]);
142  ext_table.fill(user_context, (const char **)required_ext_table, required_ext_count);
143  return required_ext_count;
144 }
145 
146 uint32_t vk_get_optional_instance_extensions(void *user_context, StringTable &ext_table) {
147  const char *optional_ext_table[] = {VK_EXT_DEBUG_UTILS_EXTENSION_NAME};
148  const uint32_t optional_ext_count = sizeof(optional_ext_table) / sizeof(optional_ext_table[0]);
149  ext_table.fill(user_context, (const char **)optional_ext_table, optional_ext_count);
150  return optional_ext_count;
151 }
152 
153 uint32_t vk_get_supported_instance_extensions(void *user_context, StringTable &ext_table) {
154 
155  PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
156  vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceExtensionProperties");
157 
158  if (vkEnumerateInstanceExtensionProperties == nullptr) {
159  debug(user_context) << "Vulkan: Missing vkEnumerateInstanceExtensionProperties proc address! Invalid loader?!\n";
160  return 0;
161  }
162 
163  debug(user_context) << "Vulkan: Checking vkEnumerateInstanceExtensionProperties for extensions ...\n";
164 
165  uint32_t avail_ext_count = 0;
166  vkEnumerateInstanceExtensionProperties(nullptr, &avail_ext_count, nullptr);
167 
168  if (avail_ext_count) {
169  BlockStorage::Config config;
170  config.entry_size = sizeof(VkExtensionProperties);
171  config.minimum_capacity = avail_ext_count;
172 
173  BlockStorage extension_properties(user_context, config);
174  extension_properties.resize(user_context, avail_ext_count);
175 
176  vkEnumerateInstanceExtensionProperties(nullptr,
177  &avail_ext_count, static_cast<VkExtensionProperties *>(extension_properties.data()));
178 
179  for (uint32_t n = 0; n < avail_ext_count; ++n) {
180  const VkExtensionProperties *properties = static_cast<const VkExtensionProperties *>(extension_properties[n]);
181  debug(user_context) << " [" << n << "]: " << properties->extensionName << "\n";
182  }
183 
184  ext_table.resize(user_context, avail_ext_count);
185  for (uint32_t n = 0; n < avail_ext_count; ++n) {
186  const VkExtensionProperties *properties = static_cast<const VkExtensionProperties *>(extension_properties[n]);
187  ext_table.assign(user_context, n, properties->extensionName);
188  }
189  }
190  debug(user_context) << "Vulkan: vkEnumerateInstanceExtensionProperties found " << avail_ext_count << " extensions ...\n";
191  return avail_ext_count;
192 }
193 
194 uint32_t vk_get_required_device_extensions(void *user_context, StringTable &ext_table) {
195  const char *required_ext_table[] = {
196  VK_KHR_8BIT_STORAGE_EXTENSION_NAME,
197  VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME};
198  const uint32_t required_ext_count = sizeof(required_ext_table) / sizeof(required_ext_table[0]);
199  ext_table.fill(user_context, (const char **)required_ext_table, required_ext_count);
200  return required_ext_count;
201 }
202 
203 uint32_t vk_get_optional_device_extensions(void *user_context, StringTable &ext_table) {
204  const char *optional_ext_table[] = {
205  "VK_KHR_portability_subset", //< necessary for running under Molten (aka Vulkan on Mac)
206  VK_KHR_MAINTENANCE_5_EXTENSION_NAME,
207  VK_KHR_16BIT_STORAGE_EXTENSION_NAME,
208  VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME,
209  VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME};
210  const uint32_t optional_ext_count = sizeof(optional_ext_table) / sizeof(optional_ext_table[0]);
211  ext_table.fill(user_context, (const char **)optional_ext_table, optional_ext_count);
212  return optional_ext_count;
213 }
214 
215 uint32_t vk_get_supported_device_extensions(void *user_context, VkPhysicalDevice physical_device, StringTable &ext_table) {
216  debug(user_context) << "vk_get_supported_device_extensions\n";
217  if (vkEnumerateDeviceExtensionProperties == nullptr) {
218  debug(user_context) << "Vulkan: Missing vkEnumerateDeviceExtensionProperties proc address! Invalid loader?!\n";
219  return 0;
220  }
221 
222  debug(user_context) << "Vulkan: Checking vkEnumerateDeviceExtensionProperties for extensions ...\n";
223 
224  uint32_t avail_ext_count = 0;
225  vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &avail_ext_count, nullptr);
226  if (avail_ext_count > 0) {
227  BlockStorage::Config config;
228  config.entry_size = sizeof(VkExtensionProperties);
229  config.minimum_capacity = avail_ext_count;
230 
231  BlockStorage extension_properties(user_context, config);
232  extension_properties.resize(user_context, avail_ext_count);
233 
234  vkEnumerateDeviceExtensionProperties(physical_device, nullptr,
235  &avail_ext_count, static_cast<VkExtensionProperties *>(extension_properties.data()));
236 
237  for (uint32_t n = 0; n < avail_ext_count; ++n) {
238  const VkExtensionProperties *properties = static_cast<const VkExtensionProperties *>(extension_properties[n]);
239  debug(user_context) << " [" << n << "]: " << properties->extensionName << "\n";
240  }
241 
242  ext_table.resize(user_context, avail_ext_count);
243  for (uint32_t n = 0; n < avail_ext_count; ++n) {
244  const VkExtensionProperties *properties = static_cast<const VkExtensionProperties *>(extension_properties[n]);
245  ext_table.assign(user_context, n, properties->extensionName);
246  }
247  }
248 
249  debug(user_context) << "Vulkan: vkEnumerateDeviceExtensionProperties found " << avail_ext_count << " extensions ...\n";
250  return avail_ext_count;
251 }
252 
253 bool vk_validate_required_extension_support(void *user_context,
254  const StringTable &required_extensions,
255  const StringTable &supported_extensions) {
256  debug(user_context) << "Vulkan: Validating " << uint32_t(required_extensions.size()) << " extensions ...\n";
257  bool validated = true;
258  for (uint32_t n = 0; n < required_extensions.size(); ++n) {
259  const char *extension = required_extensions[n];
260  if (!supported_extensions.contains(extension)) {
261  debug(user_context) << "Vulkan: Missing required extension: '" << extension << "'!\n";
262  validated = false;
263  }
264  }
265  return validated;
266 }
267 
268 // --------------------------------------------------------------------------
269 
270 } // namespace
271 } // namespace Vulkan
272 } // namespace Internal
273 } // namespace Runtime
274 } // namespace Halide
275 
276 // --------------------------------------------------------------------------
277 
278 using namespace Halide::Runtime::Internal::Vulkan;
279 
280 // --------------------------------------------------------------------------
281 
282 extern "C" {
283 
284 // --------------------------------------------------------------------------
285 
286 WEAK void halide_vulkan_set_layer_names(const char *n) {
288  vk_set_layer_names_internal(n);
289 }
290 
293  return vk_get_layer_names_internal(user_context);
294 }
295 
298  vk_set_extension_names_internal(n);
299 }
300 
303  return vk_get_extension_names_internal(user_context);
304 }
305 
306 WEAK void halide_vulkan_set_device_type(const char *n) {
308  vk_set_device_type_internal(n);
309 }
310 
313  return vk_get_device_type_internal(user_context);
314 }
315 
318  vk_set_build_options_internal(n);
319 }
320 
323  return vk_get_build_options_internal(user_context);
324 }
325 
328  vk_set_alloc_config_internal(n);
329 }
330 
333  return vk_get_alloc_config_internal(user_context);
334 }
335 
336 // --------------------------------------------------------------------------
337 
338 } // extern "C"
339 
340 #endif // HALIDE_RUNTIME_VULKAN_EXTENSIONS_H
void resize(void *user_context, size_t entry_count, bool realloc=true)
size_t parse(void *user_context, const char *str, const char *delim)
Definition: string_table.h:159
void assign(void *user_context, size_t index, const char *str, size_t length=0)
Definition: string_table.h:134
void resize(void *user_context, size_t capacity)
Definition: string_table.h:89
void fill(void *user_context, const char **array, size_t count)
Definition: string_table.h:125
bool contains(const char *str) const
Definition: string_table.h:191
WEAK ScopedSpinLock::AtomicFlag alloc_config_lock
WEAK ScopedSpinLock::AtomicFlag extension_names_lock
WEAK ScopedSpinLock::AtomicFlag layer_names_lock
WEAK ScopedSpinLock::AtomicFlag build_options_lock
WEAK ScopedSpinLock::AtomicFlag device_type_lock
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
@ Internal
Not visible externally, similar to 'static' linkage in C.
char * getenv(const char *)
unsigned __INT32_TYPE__ uint32_t
#define WEAK
static size_t copy_up_to(char *dst, const char *src, size_t max_chars)
WEAK void halide_vulkan_set_layer_names(const char *n)
WEAK const char * halide_vulkan_get_layer_names(void *user_context)
WEAK void halide_vulkan_set_build_options(const char *n)
WEAK void halide_vulkan_set_extension_names(const char *n)
WEAK const char * halide_vulkan_get_alloc_config(void *user_context)
WEAK const char * halide_vulkan_get_device_type(void *user_context)
WEAK void halide_vulkan_set_device_type(const char *n)
WEAK const char * halide_vulkan_get_extension_names(void *user_context)
WEAK void halide_vulkan_set_alloc_config(const char *n)
WEAK const char * halide_vulkan_get_build_options(void *user_context)
#define HL_VK_ENV_DELIM
void * user_context