52 : user_context(user_context) {
55 reinterpret_cast<halide_vulkan_memory_allocator **
>(&
allocator),
83int vk_find_compute_capability(
void *user_context,
int *major,
int *minor) {
84 debug(user_context) <<
" vk_find_compute_capability (user_context: " << user_context <<
")\n";
86 VkInstance instance =
nullptr;
87 VkDevice device =
nullptr;
88 VkPhysicalDevice physical_device =
nullptr;
104 vk_load_vulkan_loader_functions(user_context);
106 debug(user_context) <<
" no valid vulkan loader library was found ...\n";
113 vk_get_requested_layers(user_context, requested_layers);
117 int status = vk_create_instance(user_context, requested_layers, &instance, alloc_callbacks);
119 debug(user_context) <<
" no valid vulkan runtime was found ...\n";
127 debug(user_context) <<
" no valid vulkan runtime was found ...\n";
133 status = vk_select_device_for_context(user_context, &instance, &device, &physical_device, &queue_family_index);
135 debug(user_context) <<
" no valid vulkan device was found ...\n";
141 debug(user_context) <<
" querying for device properties ...\n";
145 debug(user_context) <<
" found device compute capability v" << *major <<
"." << *minor <<
" ...\n";
147 vk_destroy_instance(user_context, instance, alloc_callbacks);
153 debug(user_context) <<
" vk_create_instance (user_context: " << user_context <<
")\n";
156 vk_get_required_instance_extensions(user_context, required_instance_extensions);
159 vk_get_supported_instance_extensions(user_context, supported_instance_extensions);
161 bool valid_instance = vk_validate_required_extension_support(user_context, required_instance_extensions, supported_instance_extensions);
164 debug(user_context) <<
" found " << (
uint32_t)required_instance_extensions.
size() <<
" required extensions for instance!\n";
165 for (
int n = 0; n < (int)required_instance_extensions.
size(); ++n) {
166 debug(user_context) <<
" extension: " << required_instance_extensions[n] <<
"\n";
172 if (supported_instance_extensions.
contains(
"VK_KHR_portability_enumeration") &&
173 supported_instance_extensions.
contains(
"VK_MVK_macos_surface")) {
175 required_instance_extensions.
append(user_context,
"VK_KHR_portability_enumeration");
193 (
uint32_t)required_instance_extensions.
size(), required_instance_extensions.
data()
198 debug(user_context) <<
"Vulkan: vkCreateInstance failed with return code: " << vk_get_error_name(result) <<
"\n";
205int vk_destroy_instance(
void *user_context, VkInstance instance,
const VkAllocationCallbacks *alloc_callbacks) {
206 debug(user_context) <<
" vk_destroy_instance (user_context: " << user_context <<
")\n";
211int vk_select_device_for_context(
void *user_context,
212 VkInstance *instance, VkDevice *device,
213 VkPhysicalDevice *physical_device,
219 debug(user_context) <<
"Vulkan: vkEnumeratePhysicalDevices failed with return code: " << vk_get_error_name(result) <<
"\n";
222 if (device_count == 0) {
223 debug(user_context) <<
"Vulkan: No devices found.\n";
229 device_query_storage_config.
entry_size =
sizeof(VkPhysicalDevice);
230 BlockStorage device_query_storage(user_context, device_query_storage_config);
231 device_query_storage.resize(user_context, device_count);
233 VkPhysicalDevice chosen_device =
nullptr;
234 VkPhysicalDevice *avail_devices = (VkPhysicalDevice *)(device_query_storage.data());
235 if (avail_devices ==
nullptr) {
236 debug(user_context) <<
"Vulkan: Out of system memory!\n";
241 debug(user_context) <<
"Vulkan: vkEnumeratePhysicalDevices failed with return code: " << vk_get_error_name(result) <<
"\n";
250 for (
uint32_t i = 0; (chosen_device ==
nullptr) && (i < device_count); i++) {
253 debug(user_context) <<
"Vulkan: Checking device #" << i <<
"='" << properties.
deviceName <<
"'\n";
255 int matching_device = 0;
256 if ((dev_type !=
nullptr) && (*dev_type !=
'\0')) {
276 if (matching_device) {
278 uint32_t queue_properties_count = 0;
280 if (queue_properties_count < 1) {
286 queue_properties_storage_config.
entry_size =
sizeof(VkPhysicalDevice);
287 BlockStorage queue_properties_storage(user_context, queue_properties_storage_config);
288 queue_properties_storage.resize(user_context, queue_properties_count);
292 for (
uint32_t j = 0; (chosen_device ==
nullptr) && (j < queue_properties_count); j++) {
293 if (queue_properties[j].queueCount > 0 &&
295 chosen_device = avail_devices[i];
298 debug(user_context) <<
"Vulkan: Found matching compute device '" << properties.
deviceName <<
"'\n";
304 if (chosen_device ==
nullptr) {
306 chosen_device = avail_devices[0];
309 debug(user_context) <<
"Vulkan: Defaulting to first compute device '" << properties.
deviceName <<
"'\n";
312 *queue_family_index = queue_family;
313 *physical_device = chosen_device;
317int vk_create_device(
void *user_context,
const StringTable &requested_layers, VkInstance *instance, VkDevice *device, VkQueue *queue,
319 debug(user_context) <<
" vk_create_device (user_context=" << user_context <<
")\n";
321 debug(user_context) <<
" checking for required device extensions ...\n";
323 vk_get_required_device_extensions(user_context, required_device_extensions);
325 debug(user_context) <<
" checking for optional device extensions ...\n";
327 vk_get_optional_device_extensions(user_context, optional_device_extensions);
329 debug(user_context) <<
" validating supported device extensions ...\n";
331 vk_get_supported_device_extensions(user_context, *physical_device, supported_device_extensions);
333 bool valid_device = vk_validate_required_extension_support(user_context, required_device_extensions, supported_device_extensions);
335 debug(user_context) <<
"Vulkan: Unable to validate required extension support!\n";
339 debug(user_context) <<
" found " << (
uint32_t)required_device_extensions.
size() <<
" required extensions for device!\n";
340 for (
uint32_t n = 0; n < required_device_extensions.
size(); ++n) {
341 debug(user_context) <<
" required extension: " << required_device_extensions[n] <<
"\n";
345 debug(user_context) <<
" checking for " << (
uint32_t)optional_device_extensions.
size() <<
" optional extensions for device ...\n";
346 for (
uint32_t n = 0; n < optional_device_extensions.
size(); ++n) {
347 if (supported_device_extensions.
contains(optional_device_extensions[n])) {
348 debug(user_context) <<
" optional extension: " << optional_device_extensions[n] <<
"\n";
349 required_device_extensions.
append(user_context, optional_device_extensions[n]);
353 float queue_priority = 1.0f;
365 debug(user_context) <<
" querying for device properties ...\n";
369 bool has_capability_v11 = (major_version >= 1) && (minor_version >= 1);
370 bool has_capability_v12 = (major_version >= 1) && (minor_version >= 2);
371 debug(user_context) <<
" found device compute capability v" << major_version <<
"." << minor_version <<
" ...\n";
375 void *extended_features_ptr =
nullptr;
376 void *standard_features_ptr =
nullptr;
378 debug(user_context) <<
" querying for device features...\n";
380 debug(user_context) <<
" shader float64 support: " << (device_features.
shaderFloat64 ?
"true" :
"false") <<
"...\n";
381 debug(user_context) <<
" shader int64 support: " << (device_features.
shaderInt64 ?
"true" :
"false") <<
"...\n";
382 debug(user_context) <<
" shader int16 support: " << (device_features.
shaderInt16 ?
"true" :
"false") <<
"...\n";
396 (has_capability_v12 ? &storage_8bit_ext :
nullptr),
401 &storage_16bit_ext, device_features};
412 debug(user_context) <<
" querying for extended device features...\n";
414 debug(user_context) <<
" shader int8 support: " << (shader_f16_i8_ext.
shaderInt8 ?
"true" :
"false") <<
"...\n";
415 debug(user_context) <<
" shader float16 support: " << (shader_f16_i8_ext.
shaderFloat16 ?
"true" :
"false") <<
"...\n";
416 if (has_capability_v12) {
417 debug(user_context) <<
" storage buffer 8bit access support: " << (storage_8bit_ext.
storageBuffer8BitAccess ?
"true" :
"false") <<
"...\n";
418 debug(user_context) <<
" storage buffer 16bit access support: " << (storage_16bit_ext.
storageBuffer16BitAccess ?
"true" :
"false") <<
"...\n";
420 extended_features_ptr = (
void *)(&device_features_ext);
422 standard_features_ptr = &device_features;
427 extended_features_ptr,
430 &device_queue_create_info,
432 (
uint32_t)required_device_extensions.
size(), required_device_extensions.
data(),
438 debug(user_context) <<
"Vulkan: vkCreateDevice failed with return code: " << vk_get_error_name(result) <<
"\n";
448 VkInstance *instance, VkDevice *device, VkPhysicalDevice *physical_device,
449 VkCommandPool *command_pool, VkQueue *queue,
uint32_t *queue_family_index) {
451 debug(user_context) <<
" vk_create_context (user_context: " << user_context <<
")\n";
454 vk_load_vulkan_loader_functions(user_context);
456 error(user_context) <<
"Vulkan: Failed to resolve loader library methods to create instance!\n";
462 uint32_t requested_layer_count = vk_get_requested_layers(user_context, requested_layers);
463 debug(user_context) <<
" requested " << requested_layer_count <<
" layers for instance!\n";
464 for (
int n = 0; n < (int)requested_layer_count; ++n) {
465 debug(user_context) <<
" layer: " << requested_layers[n] <<
"\n";
469 int error_code = vk_create_instance(user_context, requested_layers, instance, alloc_callbacks);
471 error(user_context) <<
"Vulkan: Failed to create instance for context!\n";
478 error(user_context) <<
"Vulkan: Failed to resolve API library methods to create device!\n";
483 error_code = vk_select_device_for_context(user_context, instance, device, physical_device, queue_family_index);
485 error(user_context) <<
"Vulkan: Failed to select device for context!\n";
489 error_code = vk_create_device(user_context, requested_layers, instance, device, queue, physical_device, queue_family_index, alloc_callbacks);
491 error(user_context) <<
"Vulkan: Failed to create device for context!\n";
495 *allocator = vk_create_memory_allocator(user_context, *device, *physical_device, alloc_callbacks);
496 if (*allocator ==
nullptr) {
497 error(user_context) <<
"Vulkan: Failed to create memory allocator for device!\n";
501 error_code = vk_create_command_pool(user_context, *allocator, *queue_family_index, command_pool);
503 error(user_context) <<
"Vulkan: Failed to create command pool for context!\n";
513 VkInstance instance, VkDevice device, VkPhysicalDevice physical_device,
514 VkCommandPool command_pool, VkQueue queue) {
517 <<
"vk_destroy_context (user_context: " << user_context <<
")\n";
519 if (device !=
nullptr) {
522 if ((command_pool != VkInvalidCommandPool) && (allocator !=
nullptr)) {
523 vk_destroy_command_pool(user_context, allocator, command_pool);
524 vk_destroy_shader_modules(user_context, allocator);
525 vk_destroy_memory_allocator(user_context, allocator);
527 if (device !=
nullptr) {
530 if (instance !=
nullptr) {