Halide
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_properties2"};
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_supported_instance_extensions(void *user_context, StringTable &ext_table) {
147 
149  vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceExtensionProperties");
150 
152  debug(user_context) << "Vulkan: Missing vkEnumerateInstanceExtensionProperties proc address! Invalid loader?!\n";
153  return 0;
154  }
155 
156  uint32_t avail_ext_count = 0;
157  vkEnumerateInstanceExtensionProperties(nullptr, &avail_ext_count, nullptr);
158  debug(user_context) << "Vulkan: vkEnumerateInstanceExtensionProperties found " << avail_ext_count << " extensions ...\n";
159 
160  if (avail_ext_count) {
161  BlockStorage::Config config;
162  config.entry_size = sizeof(VkExtensionProperties);
163  config.minimum_capacity = avail_ext_count;
164 
165  BlockStorage extension_properties(user_context, config);
166  extension_properties.resize(user_context, avail_ext_count);
167 
169  &avail_ext_count, static_cast<VkExtensionProperties *>(extension_properties.data()));
170 
171  for (uint32_t n = 0; n < avail_ext_count; ++n) {
172  const VkExtensionProperties *properties = static_cast<const VkExtensionProperties *>(extension_properties[n]);
173  debug(user_context) << " extension: " << properties->extensionName << "\n";
174  }
175 
176  ext_table.resize(user_context, avail_ext_count);
177  for (uint32_t n = 0; n < avail_ext_count; ++n) {
178  const VkExtensionProperties *properties = static_cast<const VkExtensionProperties *>(extension_properties[n]);
179  ext_table.assign(user_context, n, properties->extensionName);
180  }
181  }
182 
183  return avail_ext_count;
184 }
185 
186 uint32_t vk_get_required_device_extensions(void *user_context, StringTable &ext_table) {
187  const char *required_ext_table[] = {"VK_KHR_8bit_storage", "VK_KHR_storage_buffer_storage_class"};
188  const uint32_t required_ext_count = sizeof(required_ext_table) / sizeof(required_ext_table[0]);
189  ext_table.fill(user_context, (const char **)required_ext_table, required_ext_count);
190  return required_ext_count;
191 }
192 
193 uint32_t vk_get_optional_device_extensions(void *user_context, StringTable &ext_table) {
194  const char *optional_ext_table[] = {
195  "VK_KHR_portability_subset", //< necessary for running under Molten (aka Vulkan on Mac)
196  "VK_KHR_16bit_storage",
197  "VK_KHR_shader_float16_int8",
198  "VK_KHR_shader_float_controls"};
199  const uint32_t optional_ext_count = sizeof(optional_ext_table) / sizeof(optional_ext_table[0]);
200 
201  ext_table.resize(user_context, optional_ext_count);
202  for (uint32_t n = 0; n < optional_ext_count; ++n) {
203  ext_table.assign(user_context, n, optional_ext_table[n]);
204  }
205  return optional_ext_count;
206 }
207 
208 uint32_t vk_get_supported_device_extensions(void *user_context, VkPhysicalDevice physical_device, StringTable &ext_table) {
209  debug(user_context) << "vk_get_supported_device_extensions\n";
210  if (vkEnumerateDeviceExtensionProperties == nullptr) {
211  debug(user_context) << "Vulkan: Missing vkEnumerateDeviceExtensionProperties proc address! Invalid loader?!\n";
212  return 0;
213  }
214 
215  uint32_t avail_ext_count = 0;
216  vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &avail_ext_count, nullptr);
217  debug(user_context) << "Vulkan: vkEnumerateDeviceExtensionProperties found " << avail_ext_count << " extensions ...\n";
218 
219  if (avail_ext_count > 0) {
220  BlockStorage::Config config;
221  config.entry_size = sizeof(VkExtensionProperties);
222  config.minimum_capacity = avail_ext_count;
223 
224  BlockStorage extension_properties(user_context, config);
225  extension_properties.resize(user_context, avail_ext_count);
226 
227  vkEnumerateDeviceExtensionProperties(physical_device, nullptr,
228  &avail_ext_count, static_cast<VkExtensionProperties *>(extension_properties.data()));
229 
230  for (uint32_t n = 0; n < avail_ext_count; ++n) {
231  const VkExtensionProperties *properties = static_cast<const VkExtensionProperties *>(extension_properties[n]);
232  debug(user_context) << " extension: " << properties->extensionName << "\n";
233  }
234 
235  ext_table.resize(user_context, avail_ext_count);
236  for (uint32_t n = 0; n < avail_ext_count; ++n) {
237  const VkExtensionProperties *properties = static_cast<const VkExtensionProperties *>(extension_properties[n]);
238  ext_table.assign(user_context, n, properties->extensionName);
239  }
240  }
241 
242  return avail_ext_count;
243 }
244 
245 bool vk_validate_required_extension_support(void *user_context,
246  const StringTable &required_extensions,
247  const StringTable &supported_extensions) {
248  bool validated = true;
249  for (uint32_t n = 0; n < required_extensions.size(); ++n) {
250  const char *extension = required_extensions[n];
251  if (!supported_extensions.contains(extension)) {
252  debug(user_context) << "Vulkan: Missing required extension: '" << extension << "'! \n";
253  validated = false;
254  }
255  }
256  return validated;
257 }
258 
259 // --------------------------------------------------------------------------
260 
261 } // namespace
262 } // namespace Vulkan
263 } // namespace Internal
264 } // namespace Runtime
265 } // namespace Halide
266 
267 // --------------------------------------------------------------------------
268 
269 using namespace Halide::Runtime::Internal::Vulkan;
270 
271 // --------------------------------------------------------------------------
272 
273 extern "C" {
274 
275 // --------------------------------------------------------------------------
276 
277 WEAK void halide_vulkan_set_layer_names(const char *n) {
279  vk_set_layer_names_internal(n);
280 }
281 
282 WEAK const char *halide_vulkan_get_layer_names(void *user_context) {
284  return vk_get_layer_names_internal(user_context);
285 }
286 
289  vk_set_extension_names_internal(n);
290 }
291 
292 WEAK const char *halide_vulkan_get_extension_names(void *user_context) {
294  return vk_get_extension_names_internal(user_context);
295 }
296 
297 WEAK void halide_vulkan_set_device_type(const char *n) {
299  vk_set_device_type_internal(n);
300 }
301 
302 WEAK const char *halide_vulkan_get_device_type(void *user_context) {
304  return vk_get_device_type_internal(user_context);
305 }
306 
309  vk_set_build_options_internal(n);
310 }
311 
312 WEAK const char *halide_vulkan_get_build_options(void *user_context) {
314  return vk_get_build_options_internal(user_context);
315 }
316 
319  vk_set_alloc_config_internal(n);
320 }
321 
322 WEAK const char *halide_vulkan_get_alloc_config(void *user_context) {
324  return vk_get_alloc_config_internal(user_context);
325 }
326 
327 // --------------------------------------------------------------------------
328 
329 } // extern "C"
330 
331 #endif // HALIDE_RUNTIME_VULKAN_EXTENSIONS_H
Halide::Runtime::Internal::Vulkan::device_type_lock
WEAK ScopedSpinLock::AtomicFlag device_type_lock
Definition: vulkan_extensions.h:24
Halide::Runtime::Internal::StringTable::fill
void fill(void *user_context, const char **array, size_t coun)
Definition: string_table.h:124
vkEnumerateInstanceExtensionProperties
VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties)
Halide::Runtime::Internal::Vulkan::extension_names_initialized
WEAK bool extension_names_initialized
Definition: vulkan_extensions.h:21
Halide::Runtime::Internal::Vulkan::alloc_config
WEAK char alloc_config[1024]
Definition: vulkan_extensions.h:31
Halide::Runtime::Internal::BlockStorage::data
void * data()
Definition: block_storage.h:354
halide_vulkan_get_device_type
const WEAK char * halide_vulkan_get_device_type(void *user_context)
Definition: vulkan_extensions.h:302
Halide::Runtime::Internal::Vulkan::extension_names_lock
WEAK ScopedSpinLock::AtomicFlag extension_names_lock
Definition: vulkan_extensions.h:20
Halide::Runtime::Internal::StringTable::resize
void resize(void *user_context, size_t capacity)
Definition: string_table.h:89
halide_vulkan_set_build_options
WEAK void halide_vulkan_set_build_options(const char *n)
Definition: vulkan_extensions.h:307
Halide::Runtime::Internal::ScopedSpinLock::AtomicFlag
char AtomicFlag
Definition: scoped_spin_lock.h:11
Halide::Runtime::Internal::Vulkan::device_type
WEAK char device_type[256]
Definition: vulkan_extensions.h:23
Halide::Runtime::Internal::BlockStorage
Definition: block_storage.h:18
Halide::Runtime::Internal::Vulkan::device_type_initialized
WEAK bool device_type_initialized
Definition: vulkan_extensions.h:25
vkEnumerateDeviceExtensionProperties
VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties)
Halide::Runtime::Internal::Vulkan::build_options_initialized
WEAK bool build_options_initialized
Definition: vulkan_extensions.h:29
getenv
char * getenv(const char *)
Halide::Runtime::Internal::StringTable::size
size_t size() const
Definition: string_table.h:54
halide_vulkan_set_device_type
WEAK void halide_vulkan_set_device_type(const char *n)
Definition: vulkan_extensions.h:297
PFN_vkEnumerateInstanceExtensionProperties
VkResult(VKAPI_PTR * PFN_vkEnumerateInstanceExtensionProperties)(const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties)
Definition: mini_vulkan.h:2517
Halide::Runtime::Internal::Vulkan::layer_names_lock
WEAK ScopedSpinLock::AtomicFlag layer_names_lock
Definition: vulkan_extensions.h:16
Halide::Runtime::Internal::Vulkan::build_options_lock
WEAK ScopedSpinLock::AtomicFlag build_options_lock
Definition: vulkan_extensions.h:28
Halide::Runtime::Internal::Vulkan::build_options
WEAK char build_options[1024]
Definition: vulkan_extensions.h:27
halide_vulkan_set_layer_names
WEAK void halide_vulkan_set_layer_names(const char *n)
Definition: vulkan_extensions.h:277
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Definition: AbstractGenerator.h:19
Halide::LinkageType::Internal
@ Internal
Not visible externally, similar to 'static' linkage in C.
Halide::Runtime::Internal::Vulkan::extension_names
WEAK char extension_names[1024]
Definition: vulkan_extensions.h:19
halide_vulkan_get_build_options
const WEAK char * halide_vulkan_get_build_options(void *user_context)
Definition: vulkan_extensions.h:312
VkExtensionProperties
struct VkExtensionProperties VkExtensionProperties
Halide::Runtime::Internal::BlockStorage::resize
void resize(void *user_context, size_t entry_count, bool realloc=true)
Definition: block_storage.h:204
halide_vulkan_get_layer_names
const WEAK char * halide_vulkan_get_layer_names(void *user_context)
Definition: vulkan_extensions.h:282
halide_vulkan_get_extension_names
const WEAK char * halide_vulkan_get_extension_names(void *user_context)
Definition: vulkan_extensions.h:292
Halide::Runtime::Internal::StringTable::parse
size_t parse(void *user_context, const char *str, const char *delim)
Definition: string_table.h:158
Halide::Runtime::Internal::BlockStorage::Config::entry_size
uint32_t entry_size
Definition: block_storage.h:24
halide_vulkan_get_alloc_config
const WEAK char * halide_vulkan_get_alloc_config(void *user_context)
Definition: vulkan_extensions.h:322
vkGetInstanceProcAddr
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *pName)
Halide::Runtime::Internal::StringTable::contains
bool contains(const char *str) const
Definition: string_table.h:190
Halide::Runtime::Internal::ScopedSpinLock
Definition: scoped_spin_lock.h:9
halide_vulkan_set_alloc_config
WEAK void halide_vulkan_set_alloc_config(const char *n)
Definition: vulkan_extensions.h:317
Halide::Runtime::Internal::StringTable::assign
void assign(void *user_context, size_t index, const char *str, size_t length=0)
Definition: string_table.h:133
Halide::Runtime::Internal::Vulkan::layer_names_initialized
WEAK bool layer_names_initialized
Definition: vulkan_extensions.h:17
Halide::Runtime::Internal::StringUtils::copy_up_to
static size_t copy_up_to(char *dst, const char *src, size_t max_chars)
Definition: string_storage.h:72
Halide::Runtime::Internal::Vulkan
Definition: vulkan_context.h:17
Halide::DeviceAPI::Vulkan
@ Vulkan
Halide::Runtime::Internal::BlockStorage::Config::minimum_capacity
uint32_t minimum_capacity
Definition: block_storage.h:26
vulkan_internal.h
HL_VK_ENV_DELIM
#define HL_VK_ENV_DELIM
Definition: vulkan_interface.h:21
halide_vulkan_set_extension_names
WEAK void halide_vulkan_set_extension_names(const char *n)
Definition: vulkan_extensions.h:287
WEAK
#define WEAK
Definition: runtime_internal.h:52
VkExtensionProperties::extensionName
char extensionName[VK_MAX_EXTENSION_NAME_SIZE]
Definition: mini_vulkan.h:1713
uint32_t
unsigned __INT32_TYPE__ uint32_t
Definition: runtime_internal.h:25
VkExtensionProperties
Definition: mini_vulkan.h:1712
Halide::Runtime::Internal::Vulkan::layer_names
WEAK char layer_names[1024]
Definition: vulkan_extensions.h:15
Halide::Runtime::Internal::StringTable
Definition: string_table.h:15
Halide::Runtime::Internal::Vulkan::alloc_config_initialized
WEAK bool alloc_config_initialized
Definition: vulkan_extensions.h:33
Halide::Runtime::Internal::Vulkan::alloc_config_lock
WEAK ScopedSpinLock::AtomicFlag alloc_config_lock
Definition: vulkan_extensions.h:32
Halide::Runtime::Internal::BlockStorage::Config
Definition: block_storage.h:23