Halide  17.0.2
Halide compiler and libraries
vulkan_context.h
Go to the documentation of this file.
1 #ifndef HALIDE_RUNTIME_VULKAN_CONTEXT_H
2 #define HALIDE_RUNTIME_VULKAN_CONTEXT_H
3 
4 #include "printer.h"
5 #include "runtime_internal.h"
6 #include "scoped_spin_lock.h"
7 
8 #include "vulkan_extensions.h"
9 #include "vulkan_internal.h"
10 #include "vulkan_memory.h"
11 
12 // --------------------------------------------------------------------------
13 
14 namespace Halide {
15 namespace Runtime {
16 namespace Internal {
17 namespace Vulkan {
18 
19 // --------------------------------------------------------------------------
20 
21 // Vulkan Memory allocator for host-device allocations
22 halide_vulkan_memory_allocator *WEAK cached_allocator = nullptr;
23 
24 // Cached instance related handles for device resources
25 VkInstance WEAK cached_instance = nullptr;
26 VkDevice WEAK cached_device = nullptr;
27 VkCommandPool WEAK cached_command_pool = 0;
28 VkQueue WEAK cached_queue = nullptr;
29 VkPhysicalDevice WEAK cached_physical_device = nullptr;
31 
32 // A Vulkan context/queue/synchronization lock defined in this module with weak linkage
34 
35 // --------------------------------------------------------------------------
36 
37 // Helper object to acquire and release the Vulkan context.
39  void *user_context;
40 
41 public:
43  VkInstance instance = nullptr;
44  VkDevice device = nullptr;
45  VkCommandPool command_pool = 0;
46  VkPhysicalDevice physical_device = nullptr;
47  VkQueue queue = nullptr;
48  uint32_t queue_family_index = 0; // used for operations requiring queue family
50 
51  HALIDE_ALWAYS_INLINE explicit VulkanContext(void *user_context)
52  : user_context(user_context) {
53 
54  int result = halide_vulkan_acquire_context(user_context,
55  reinterpret_cast<halide_vulkan_memory_allocator **>(&allocator),
57  if (result != halide_error_code_success) {
60  }
61  halide_debug_assert(user_context, allocator != nullptr);
62  halide_debug_assert(user_context, instance != nullptr);
63  halide_debug_assert(user_context, device != nullptr);
64  halide_debug_assert(user_context, command_pool != 0);
65  halide_debug_assert(user_context, queue != nullptr);
66  halide_debug_assert(user_context, physical_device != nullptr);
67  }
68 
71  }
72 
73  // For now, this is always nullptr
75  return nullptr;
76  }
77 };
78 
79 // --------------------------------------------------------------------------
80 
81 namespace {
82 
83 int vk_find_compute_capability(void *user_context, int *major, int *minor) {
84  debug(user_context) << " vk_find_compute_capability (user_context: " << user_context << ")\n";
85 
86  VkInstance instance = nullptr;
87  VkDevice device = nullptr;
88  VkPhysicalDevice physical_device = nullptr;
89  uint32_t queue_family_index = 0;
90 
91  StringTable requested_layers;
92  vk_get_requested_layers(user_context, requested_layers);
93 
94  const VkAllocationCallbacks *alloc_callbacks = halide_vulkan_get_allocation_callbacks(user_context);
95  int status = vk_create_instance(user_context, requested_layers, &instance, alloc_callbacks);
96  if (status != halide_error_code_success) {
97  debug(user_context) << " no valid vulkan runtime was found ...\n";
98  *major = 0;
99  *minor = 0;
100  return 0;
101  }
102 
103  if (vkCreateDevice == nullptr) {
104  vk_load_vulkan_functions(instance);
105  }
106 
107  status = vk_select_device_for_context(user_context, &instance, &device, &physical_device, &queue_family_index);
108  if (status != halide_error_code_success) {
109  debug(user_context) << " no valid vulkan device was found ...\n";
110  *major = 0;
111  *minor = 0;
112  return 0;
113  }
114 
115  VkPhysicalDeviceProperties device_properties = {0};
116  debug(user_context) << " querying for device properties ...\n";
117  vkGetPhysicalDeviceProperties(physical_device, &device_properties);
118  *major = VK_API_VERSION_MAJOR(device_properties.apiVersion);
119  *minor = VK_API_VERSION_MINOR(device_properties.apiVersion);
120  debug(user_context) << " found device compute capability v" << *major << "." << *minor << " ...\n";
121 
122  vk_destroy_instance(user_context, instance, alloc_callbacks);
123  return 0;
124 }
125 
126 // Initializes the instance (used by the default vk_create_context)
127 int vk_create_instance(void *user_context, const StringTable &requested_layers, VkInstance *instance, const VkAllocationCallbacks *alloc_callbacks) {
128  debug(user_context) << " vk_create_instance (user_context: " << user_context << ")\n";
129 
130  StringTable required_instance_extensions;
131  vk_get_required_instance_extensions(user_context, required_instance_extensions);
132 
133  StringTable supported_instance_extensions;
134  vk_get_supported_instance_extensions(user_context, supported_instance_extensions);
135 
136  bool valid_instance = vk_validate_required_extension_support(user_context, required_instance_extensions, supported_instance_extensions);
137  halide_abort_if_false(user_context, valid_instance);
138 
139  debug(user_context) << " found " << (uint32_t)required_instance_extensions.size() << " required extensions for instance!\n";
140  for (int n = 0; n < (int)required_instance_extensions.size(); ++n) {
141  debug(user_context) << " extension: " << required_instance_extensions[n] << "\n";
142  }
143 
144  // If we're running under Molten VK, we must enable the portability extension and create flags
145  // to allow non-physical devices that are emulated to appear in the device list.
146  uint32_t create_flags = 0;
147  if (supported_instance_extensions.contains("VK_KHR_portability_enumeration") &&
148  supported_instance_extensions.contains("VK_MVK_macos_surface")) {
150  required_instance_extensions.append(user_context, "VK_KHR_portability_enumeration");
151  }
152 
153  VkApplicationInfo app_info = {
154  VK_STRUCTURE_TYPE_APPLICATION_INFO, // struct type
155  nullptr, // Next
156  "Runtime", // application name
157  VK_MAKE_API_VERSION(0, 1, 0, 0), // app version
158  "Halide", // engine name
160  VK_API_VERSION_1_3}; // FIXME: only use the minimum capability necessary
161 
162  VkInstanceCreateInfo create_info = {
164  nullptr, // Next
165  create_flags, // Flags
166  &app_info, // ApplicationInfo
167  (uint32_t)requested_layers.size(), requested_layers.data(), // Layers
168  (uint32_t)required_instance_extensions.size(), required_instance_extensions.data() // Extensions
169  };
170 
171  VkResult result = vkCreateInstance(&create_info, alloc_callbacks, instance);
172  if (result != VK_SUCCESS) {
173  debug(user_context) << "Vulkan: vkCreateInstance failed with return code: " << vk_get_error_name(result) << "\n";
175  }
176 
178 }
179 
180 int vk_destroy_instance(void *user_context, VkInstance instance, const VkAllocationCallbacks *alloc_callbacks) {
181  debug(user_context) << " vk_destroy_instance (user_context: " << user_context << ")\n";
182  vkDestroyInstance(instance, alloc_callbacks);
184 }
185 
186 int vk_select_device_for_context(void *user_context,
187  VkInstance *instance, VkDevice *device,
188  VkPhysicalDevice *physical_device,
189  uint32_t *queue_family_index) {
190  // query for the number of physical devices available in this instance
191  uint32_t device_count = 0;
192  VkResult result = vkEnumeratePhysicalDevices(*instance, &device_count, nullptr);
193  if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) {
194  debug(user_context) << "Vulkan: vkEnumeratePhysicalDevices failed with return code: " << vk_get_error_name(result) << "\n";
196  }
197  if (device_count == 0) {
198  debug(user_context) << "Vulkan: No devices found.\n";
200  }
201 
202  // allocate enough storage for the physical device query results
203  BlockStorage::Config device_query_storage_config;
204  device_query_storage_config.entry_size = sizeof(VkPhysicalDevice);
205  BlockStorage device_query_storage(user_context, device_query_storage_config);
206  device_query_storage.resize(user_context, device_count);
207 
208  VkPhysicalDevice chosen_device = nullptr;
209  VkPhysicalDevice *avail_devices = (VkPhysicalDevice *)(device_query_storage.data());
210  if (avail_devices == nullptr) {
211  debug(user_context) << "Vulkan: Out of system memory!\n";
213  }
214  result = vkEnumeratePhysicalDevices(*instance, &device_count, avail_devices);
215  if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) {
216  debug(user_context) << "Vulkan: vkEnumeratePhysicalDevices failed with return code: " << vk_get_error_name(result) << "\n";
218  }
219 
220  // get the configurable device type to search for (e.g. 'cpu', 'gpu', 'integrated-gpu', 'discrete-gpu', ...)
221  const char *dev_type = halide_vulkan_get_device_type(user_context);
222 
223  // try to find a matching device that supports compute.
224  uint32_t queue_family = 0;
225  for (uint32_t i = 0; (chosen_device == nullptr) && (i < device_count); i++) {
226  VkPhysicalDeviceProperties properties;
227  vkGetPhysicalDeviceProperties(avail_devices[i], &properties);
228  debug(user_context) << "Vulkan: Checking device #" << i << "='" << properties.deviceName << "'\n";
229 
230  int matching_device = 0;
231  if ((dev_type != nullptr) && (*dev_type != '\0')) {
232  if (strstr(dev_type, "cpu") && (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU)) {
233  matching_device = 1;
234  } else if (strstr(dev_type, "integrated-gpu") && ((properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU))) {
235  matching_device = 1;
236  } else if (strstr(dev_type, "discrete-gpu") && ((properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU))) {
237  matching_device = 1;
238  } else if (strstr(dev_type, "virtual-gpu") && (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU)) {
239  matching_device = 1;
240  } else if (strstr(dev_type, "gpu") && ((properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) || (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU))) {
241  matching_device = 1;
242  }
243  } else {
244  // use a non-virtual gpu device by default
247  matching_device = 1;
248  }
249  }
250 
251  if (matching_device) {
252  // get the number of supported queues for this physical device
253  uint32_t queue_properties_count = 0;
254  vkGetPhysicalDeviceQueueFamilyProperties(avail_devices[i], &queue_properties_count, nullptr);
255  if (queue_properties_count < 1) {
256  continue;
257  }
258 
259  // allocate enough storage for the queue properties query results
260  BlockStorage::Config queue_properties_storage_config;
261  queue_properties_storage_config.entry_size = sizeof(VkPhysicalDevice);
262  BlockStorage queue_properties_storage(user_context, queue_properties_storage_config);
263  queue_properties_storage.resize(user_context, queue_properties_count);
264 
265  VkQueueFamilyProperties *queue_properties = (VkQueueFamilyProperties *)(queue_properties_storage.data());
266  vkGetPhysicalDeviceQueueFamilyProperties(avail_devices[i], &queue_properties_count, queue_properties);
267  for (uint32_t j = 0; (chosen_device == nullptr) && (j < queue_properties_count); j++) {
268  if (queue_properties[j].queueCount > 0 &&
269  queue_properties[j].queueFlags & VK_QUEUE_COMPUTE_BIT) {
270  chosen_device = avail_devices[i];
271  queue_family = j;
272 
273  debug(user_context) << "Vulkan: Found matching compute device '" << properties.deviceName << "'\n";
274  }
275  }
276  }
277  }
278  // If nothing, just try the first one for now.
279  if (chosen_device == nullptr) {
280  queue_family = 0;
281  chosen_device = avail_devices[0];
282  VkPhysicalDeviceProperties properties;
283  vkGetPhysicalDeviceProperties(chosen_device, &properties);
284  debug(user_context) << "Vulkan: Defaulting to first compute device '" << properties.deviceName << "'\n";
285  }
286 
287  *queue_family_index = queue_family;
288  *physical_device = chosen_device;
290 }
291 
292 int vk_create_device(void *user_context, const StringTable &requested_layers, VkInstance *instance, VkDevice *device, VkQueue *queue,
293  VkPhysicalDevice *physical_device, uint32_t *queue_family_index, const VkAllocationCallbacks *alloc_callbacks) {
294  debug(user_context) << " vk_create_device (user_context=" << user_context << ")\n";
295 
296  debug(user_context) << " checking for required device extensions ...\n";
297  StringTable required_device_extensions;
298  vk_get_required_device_extensions(user_context, required_device_extensions);
299 
300  debug(user_context) << " checking for optional device extensions ...\n";
301  StringTable optional_device_extensions;
302  vk_get_optional_device_extensions(user_context, optional_device_extensions);
303 
304  debug(user_context) << " validating supported device extensions ...\n";
305  StringTable supported_device_extensions;
306  vk_get_supported_device_extensions(user_context, *physical_device, supported_device_extensions);
307 
308  bool valid_device = vk_validate_required_extension_support(user_context, required_device_extensions, supported_device_extensions);
309  if (!valid_device) {
310  debug(user_context) << "Vulkan: Unable to validate required extension support!\n";
312  }
313 
314  debug(user_context) << " found " << (uint32_t)required_device_extensions.size() << " required extensions for device!\n";
315  for (uint32_t n = 0; n < required_device_extensions.size(); ++n) {
316  debug(user_context) << " required extension: " << required_device_extensions[n] << "\n";
317  }
318 
319  // enable all available optional extensions
320  debug(user_context) << " checking for " << (uint32_t)optional_device_extensions.size() << " optional extensions for device ...\n";
321  for (uint32_t n = 0; n < optional_device_extensions.size(); ++n) {
322  if (supported_device_extensions.contains(optional_device_extensions[n])) {
323  debug(user_context) << " optional extension: " << optional_device_extensions[n] << "\n";
324  required_device_extensions.append(user_context, optional_device_extensions[n]);
325  }
326  }
327 
328  float queue_priority = 1.0f;
329  VkDeviceQueueCreateInfo device_queue_create_info = {
331  nullptr, // Next
332  0, // Flags
333  *queue_family_index,
334  1,
335  &queue_priority,
336  };
337 
338  // Get the API version to determine what device features are valid to search for
339  VkPhysicalDeviceProperties device_properties = {0};
340  debug(user_context) << " querying for device properties ...\n";
341  vkGetPhysicalDeviceProperties(*physical_device, &device_properties);
342  uint32_t major_version = VK_API_VERSION_MAJOR(device_properties.apiVersion);
343  uint32_t minor_version = VK_API_VERSION_MINOR(device_properties.apiVersion);
344  bool has_capability_v11 = (major_version >= 1) && (minor_version >= 1); // supports >= v1.1
345  bool has_capability_v12 = (major_version >= 1) && (minor_version >= 2); // supports >= v1.2
346  debug(user_context) << " found device compute capability v" << major_version << "." << minor_version << " ...\n";
347 
348  // Get the device features so that all supported features are enabled when device is created
349  VkPhysicalDeviceFeatures device_features = {};
350  void *extended_features_ptr = nullptr;
351  void *standard_features_ptr = nullptr;
352 
353  debug(user_context) << " querying for device features...\n";
354  vkGetPhysicalDeviceFeatures(*physical_device, &device_features);
355  debug(user_context) << " shader float64 support: " << (device_features.shaderFloat64 ? "true" : "false") << "...\n";
356  debug(user_context) << " shader int64 support: " << (device_features.shaderInt64 ? "true" : "false") << "...\n";
357  debug(user_context) << " shader int16 support: " << (device_features.shaderInt16 ? "true" : "false") << "...\n";
358 
359  // assemble the chain of features to query, but only add the ones that exist in the API version
360 
361  // note: requires v1.2+
363  nullptr, VK_FALSE, VK_FALSE};
364 
365  // note: requires v1.2+
367  &shader_f16_i8_ext, VK_FALSE, VK_FALSE, VK_FALSE};
368 
369  // note: requires v1.1+
371  (has_capability_v12 ? &storage_8bit_ext : nullptr),
373 
374  VkPhysicalDeviceFeatures2KHR device_features_ext = {
376  &storage_16bit_ext, device_features};
377 
378  // Look for extended device feature query method (KHR was removed when it was adopted into v1.1+)
382  }
383 
384  // If the instance runtime supports querying extended device features, request them
385  if (vkGetPhysicalDeviceFeatures2KHR && has_capability_v11) {
386 
387  debug(user_context) << " querying for extended device features...\n";
388  vkGetPhysicalDeviceFeatures2KHR(*physical_device, &device_features_ext);
389  debug(user_context) << " shader int8 support: " << (shader_f16_i8_ext.shaderInt8 ? "true" : "false") << "...\n";
390  debug(user_context) << " shader float16 support: " << (shader_f16_i8_ext.shaderFloat16 ? "true" : "false") << "...\n";
391  if (has_capability_v12) {
392  debug(user_context) << " storage buffer 8bit access support: " << (storage_8bit_ext.storageBuffer8BitAccess ? "true" : "false") << "...\n";
393  debug(user_context) << " storage buffer 16bit access support: " << (storage_16bit_ext.storageBuffer16BitAccess ? "true" : "false") << "...\n";
394  }
395  extended_features_ptr = (void *)(&device_features_ext); // pass extended features (which also contains the standard features)
396  } else {
397  standard_features_ptr = &device_features; // pass v1.0 standard features
398  }
399 
400  VkDeviceCreateInfo device_create_info = {
402  extended_features_ptr, // Extended struct ptr (used here for requesting chain of extended features)
403  0, // Flags
404  1, // Count of queues to create
405  &device_queue_create_info,
406  (uint32_t)requested_layers.size(), requested_layers.data(), // Layers
407  (uint32_t)required_device_extensions.size(), required_device_extensions.data(), // Enabled extensions
408  (VkPhysicalDeviceFeatures *)standard_features_ptr, // Requested device features
409  };
410 
411  VkResult result = vkCreateDevice(*physical_device, &device_create_info, alloc_callbacks, device);
412  if (result != VK_SUCCESS) {
413  debug(user_context) << "Vulkan: vkCreateDevice failed with return code: " << vk_get_error_name(result) << "\n";
415  }
416 
417  vkGetDeviceQueue(cached_device, *queue_family_index, 0, queue);
419 }
420 
421 // Initializes the context (used by the default implementation of halide_acquire_context)
422 int vk_create_context(void *user_context, VulkanMemoryAllocator **allocator,
423  VkInstance *instance, VkDevice *device, VkPhysicalDevice *physical_device,
424  VkCommandPool *command_pool, VkQueue *queue, uint32_t *queue_family_index) {
425 
426  debug(user_context) << " vk_create_context (user_context: " << user_context << ")\n";
427 
428  StringTable requested_layers;
429  uint32_t requested_layer_count = vk_get_requested_layers(user_context, requested_layers);
430  debug(user_context) << " requested " << requested_layer_count << " layers for instance!\n";
431  for (int n = 0; n < (int)requested_layer_count; ++n) {
432  debug(user_context) << " layer: " << requested_layers[n] << "\n";
433  }
434 
435  const VkAllocationCallbacks *alloc_callbacks = halide_vulkan_get_allocation_callbacks(user_context);
436  int error_code = vk_create_instance(user_context, requested_layers, instance, alloc_callbacks);
437  if (error_code != halide_error_code_success) {
438  error(user_context) << "Vulkan: Failed to create instance for context!\n";
439  return error_code;
440  }
441 
442  if (vkCreateDevice == nullptr) {
443  vk_load_vulkan_functions(*instance);
444  }
445 
446  error_code = vk_select_device_for_context(user_context, instance, device, physical_device, queue_family_index);
447  if (error_code != halide_error_code_success) {
448  error(user_context) << "Vulkan: Failed to select device for context!\n";
449  return error_code;
450  }
451 
452  error_code = vk_create_device(user_context, requested_layers, instance, device, queue, physical_device, queue_family_index, alloc_callbacks);
453  if (error_code != halide_error_code_success) {
454  error(user_context) << "Vulkan: Failed to create device for context!\n";
455  return error_code;
456  }
457 
458  *allocator = vk_create_memory_allocator(user_context, *device, *physical_device, alloc_callbacks);
459  if (*allocator == nullptr) {
460  error(user_context) << "Vulkan: Failed to create memory allocator for device!\n";
462  }
463 
464  error_code = vk_create_command_pool(user_context, *allocator, *queue_family_index, command_pool);
465  if (error_code != halide_error_code_success) {
466  error(user_context) << "Vulkan: Failed to create command pool for context!\n";
467  return error_code;
468  }
469 
471 }
472 
473 // --------------------------------------------------------------------------
474 
475 } // namespace
476 } // namespace Vulkan
477 } // namespace Internal
478 } // namespace Runtime
479 } // namespace Halide
480 
481 #endif /// HALIDE_RUNTIME_VULKAN_CONTEXT_H
int halide_vulkan_release_context(void *user_context, struct VkInstance_T *instance, struct VkDevice_T *device, struct VkQueue_T *queue)
#define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR
Definition: mini_vulkan.h:6069
VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator)
#define WEAK
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties *pQueueFamilyProperties)
volatile ScopedSpinLock::AtomicFlag WEAK thread_lock
An uncategorized error occurred.
VkPhysicalDeviceType deviceType
Definition: mini_vulkan.h:1658
int halide_vulkan_acquire_context(void *user_context, struct halide_vulkan_memory_allocator **allocator, struct VkInstance_T **instance, struct VkDevice_T **device, struct VkPhysicalDevice_T **physical_device, uint64_t *command_pool, struct VkQueue_T **queue, uint32_t *queue_family_index, bool create=true)
VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance)
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures)
#define halide_debug_assert(user_context, cond)
halide_debug_assert() is like halide_assert(), but only expands into a check when DEBUG_RUNTIME is de...
VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue)
This file defines the class FunctionDAG, which is our representation of a Halide pipeline, and contains methods to using Halide&#39;s bounds tools to query properties of it.
#define VK_API_VERSION_1_3
Definition: mini_vulkan.h:83
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *pName)
const char * strstr(const char *, const char *)
const char * halide_vulkan_get_device_type(void *user_context)
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties)
const struct VkAllocationCallbacks * halide_vulkan_get_allocation_callbacks(void *user_context)
#define halide_abort_if_false(user_context, cond)
halide_vulkan_memory_allocator *WEAK cached_allocator
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2KHR *pFeatures)
#define HALIDE_VERSION_PATCH
Definition: HalideRuntime.h:28
halide_error_code_t
The error codes that may be returned by a Halide pipeline.
VkPhysicalDevice WEAK cached_physical_device
unsigned __INT32_TYPE__ uint32_t
Not visible externally, similar to &#39;static&#39; linkage in C.
Buffer has a non-null device_interface but device is 0, which violates a Halide invariant.
#define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR
Definition: mini_vulkan.h:6059
A call to halide_malloc returned NULL.
#define VK_API_VERSION_MAJOR(version)
Definition: mini_vulkan.h:75
#define HALIDE_ALWAYS_INLINE
Definition: HalideRuntime.h:49
#define VK_MAKE_API_VERSION(variant, major, minor, patch)
Definition: mini_vulkan.h:78
char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]
Definition: mini_vulkan.h:1659
VkResult
Definition: mini_vulkan.h:138
#define VK_API_VERSION_MINOR(version)
Definition: mini_vulkan.h:76
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice)
VkCommandPool WEAK cached_command_pool
bool contains(const char *str) const
Definition: string_table.h:191
int halide_error_no_device_interface(void *user_context)
Various other error conditions.
#define VK_FALSE
Definition: mini_vulkan.h:120
void append(void *user_context, const char *str, size_t length=0)
Definition: string_table.h:145
#define HALIDE_VERSION_MINOR
Definition: HalideRuntime.h:27
void(VKAPI_PTR * PFN_vkGetPhysicalDeviceFeatures2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2KHR *pFeatures)
Definition: mini_vulkan.h:3862
#define HALIDE_VERSION_MAJOR
Definition: HalideRuntime.h:26
HALIDE_ALWAYS_INLINE VulkanContext(void *user_context)
Vulkan Memory Allocator class interface for managing large memory requests stored as contiguous block...
Definition: vulkan_memory.h:42
There was no error.
HALIDE_ALWAYS_INLINE const VkAllocationCallbacks * allocation_callbacks()
VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices)