diff options
Diffstat (limited to 'drivers/vulkan/vulkan_context.cpp')
-rw-r--r-- | drivers/vulkan/vulkan_context.cpp | 121 |
1 files changed, 57 insertions, 64 deletions
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index d293abdee3..4d2bc406e4 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,9 +30,9 @@ #include "vulkan_context.h" -#include "core/engine.h" -#include "core/project_settings.h" -#include "core/ustring.h" +#include "core/config/engine.h" +#include "core/config/project_settings.h" +#include "core/string/ustring.h" #include "core/version.h" #include "vk_enum_string_helper.h" @@ -49,7 +49,6 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback( VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData) { - // This error needs to be ignored because the AMD allocator will mix up memory types on IGP processors. if (strstr(pCallbackData->pMessage, "Mapping an image with layout") != nullptr && strstr(pCallbackData->pMessage, "can result in undefined behavior if this memory is used by the device") != nullptr) { @@ -155,7 +154,7 @@ VkBool32 VulkanContext::_check_layers(uint32_t check_count, const char **check_n } } if (!found) { - ERR_PRINT("Cant find layer: " + String(check_names[i])); + WARN_PRINT("Can't find layer: " + String(check_names[i])); return 0; } } @@ -163,7 +162,6 @@ VkBool32 VulkanContext::_check_layers(uint32_t check_count, const char **check_n } Error VulkanContext::_create_validation_layers() { - VkResult err; const char *instance_validation_layers_alt1[] = { "VK_LAYER_KHRONOS_validation" }; const char *instance_validation_layers_alt2[] = { "VK_LAYER_LUNARG_standard_validation" }; @@ -218,8 +216,6 @@ Error VulkanContext::_create_validation_layers() { } Error VulkanContext::_initialize_extensions() { - - VkResult err; uint32_t instance_extension_count = 0; enabled_extension_count = 0; @@ -229,13 +225,13 @@ Error VulkanContext::_initialize_extensions() { VkBool32 platformSurfaceExtFound = 0; memset(extension_names, 0, sizeof(extension_names)); - err = vkEnumerateInstanceExtensionProperties(nullptr, &instance_extension_count, nullptr); - ERR_FAIL_COND_V(err, ERR_CANT_CREATE); + VkResult err = vkEnumerateInstanceExtensionProperties(nullptr, &instance_extension_count, nullptr); + ERR_FAIL_COND_V(err != VK_SUCCESS && err != VK_INCOMPLETE, ERR_CANT_CREATE); if (instance_extension_count > 0) { VkExtensionProperties *instance_extensions = (VkExtensionProperties *)malloc(sizeof(VkExtensionProperties) * instance_extension_count); err = vkEnumerateInstanceExtensionProperties(nullptr, &instance_extension_count, instance_extensions); - if (err) { + if (err != VK_SUCCESS && err != VK_INCOMPLETE) { free(instance_extensions); ERR_FAIL_V(ERR_CANT_CREATE); } @@ -275,7 +271,6 @@ Error VulkanContext::_initialize_extensions() { } Error VulkanContext::_create_physical_device() { - /* Look for validation layers */ if (use_validation_layers) { _create_validation_layers(); @@ -306,7 +301,7 @@ Error VulkanContext::_create_physical_device() { /*flags*/ 0, /*pApplicationInfo*/ &app, /*enabledLayerCount*/ enabled_layer_count, - /*ppEnabledLayerNames*/ (const char *const *)instance_validation_layers, + /*ppEnabledLayerNames*/ (const char *const *)enabled_layers, /*enabledExtensionCount*/ enabled_extension_count, /*ppEnabledExtensionNames*/ (const char *const *)extension_names, }; @@ -348,6 +343,8 @@ Error VulkanContext::_create_physical_device() { "Please look at the Getting Started guide for additional information.\n" "vkCreateInstance Failure"); + inst_initialized = true; + /* Make initial call to query gpu_count, then second call for gpu info*/ err = vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr); ERR_FAIL_COND_V(err, ERR_CANT_CREATE); @@ -496,6 +493,8 @@ Error VulkanContext::_create_physical_device() { // features based on this query vkGetPhysicalDeviceFeatures(gpu, &physical_device_features); + physical_device_features.robustBufferAccess = false; //turn off robust buffer access, which can hamper performance on some hardware + #define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \ { \ fp##entrypoint = (PFN_vk##entrypoint)vkGetInstanceProcAddr(inst, "vk" #entrypoint); \ @@ -513,7 +512,6 @@ Error VulkanContext::_create_physical_device() { } Error VulkanContext::_create_device() { - VkResult err; float queue_priorities[1] = { 0.0 }; VkDeviceQueueCreateInfo queues[2]; @@ -552,7 +550,6 @@ Error VulkanContext::_create_device() { } Error VulkanContext::_initialize_queues(VkSurfaceKHR surface) { - // Iterate over each queue to learn whether it supports presenting: VkBool32 *supportsPresent = (VkBool32 *)malloc(queue_family_count * sizeof(VkBool32)); for (uint32_t i = 0; i < queue_family_count; i++) { @@ -601,12 +598,13 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR surface) { _create_device(); static PFN_vkGetDeviceProcAddr g_gdpa = nullptr; -#define GET_DEVICE_PROC_ADDR(dev, entrypoint) \ - { \ - if (!g_gdpa) g_gdpa = (PFN_vkGetDeviceProcAddr)vkGetInstanceProcAddr(inst, "vkGetDeviceProcAddr"); \ - fp##entrypoint = (PFN_vk##entrypoint)g_gdpa(dev, "vk" #entrypoint); \ - ERR_FAIL_COND_V_MSG(fp##entrypoint == nullptr, ERR_CANT_CREATE, \ - "vkGetDeviceProcAddr failed to find vk" #entrypoint); \ +#define GET_DEVICE_PROC_ADDR(dev, entrypoint) \ + { \ + if (!g_gdpa) \ + g_gdpa = (PFN_vkGetDeviceProcAddr)vkGetInstanceProcAddr(inst, "vkGetDeviceProcAddr"); \ + fp##entrypoint = (PFN_vk##entrypoint)g_gdpa(dev, "vk" #entrypoint); \ + ERR_FAIL_COND_V_MSG(fp##entrypoint == nullptr, ERR_CANT_CREATE, \ + "vkGetDeviceProcAddr failed to find vk" #entrypoint); \ } GET_DEVICE_PROC_ADDR(device, CreateSwapchainKHR); @@ -704,14 +702,14 @@ Error VulkanContext::_create_semaphores() { } Error VulkanContext::_window_create(DisplayServer::WindowID p_window_id, VkSurfaceKHR p_surface, int p_width, int p_height) { - ERR_FAIL_COND_V(windows.has(p_window_id), ERR_INVALID_PARAMETER); if (!queues_initialized) { // We use a single GPU, but we need a surface to initialize the // queues, so this process must be deferred until a surface // is created. - _initialize_queues(p_surface); + Error err = _initialize_queues(p_surface); + ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE); } Window window; @@ -765,7 +763,6 @@ void VulkanContext::window_destroy(DisplayServer::WindowID p_window_id) { } Error VulkanContext::_clean_up_swap_chain(Window *window) { - if (!window->swapchain) { return OK; } @@ -1014,7 +1011,6 @@ Error VulkanContext::_update_swap_chain(Window *window) { { const VkAttachmentDescription attachment = { - /*flags*/ 0, /*format*/ format, /*samples*/ VK_SAMPLE_COUNT_1_BIT, @@ -1135,12 +1131,12 @@ Error VulkanContext::_update_swap_chain(Window *window) { } Error VulkanContext::initialize() { - Error err = _create_physical_device(); if (err) { return err; } + device_initialized = true; return OK; } @@ -1149,7 +1145,6 @@ void VulkanContext::set_setup_buffer(const VkCommandBuffer &pCommandBuffer) { } void VulkanContext::append_command_buffer(const VkCommandBuffer &pCommandBuffer) { - if (command_buffer_queue.size() <= command_buffer_count) { command_buffer_queue.resize(command_buffer_count + 1); } @@ -1159,14 +1154,12 @@ void VulkanContext::append_command_buffer(const VkCommandBuffer &pCommandBuffer) } void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) { - // ensure everything else pending is executed vkDeviceWaitIdle(device); //flush the pending setup buffer if (p_flush_setup && command_buffer_queue[0]) { - //use a fence to wait for everything done VkSubmitInfo submit_info; submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; @@ -1185,7 +1178,6 @@ void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) { } if (p_flush_pending && command_buffer_count > 1) { - //use a fence to wait for everything done VkSubmitInfo submit_info; @@ -1207,7 +1199,6 @@ void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) { } Error VulkanContext::prepare_buffers() { - if (!queues_initialized) { return OK; } @@ -1219,7 +1210,6 @@ Error VulkanContext::prepare_buffers() { vkResetFences(device, 1, &fences[frame_index]); for (Map<int, Window>::Element *E = windows.front(); E; E = E->next()) { - Window *w = &E->get(); if (w->swapchain == VK_NULL_HANDLE) { @@ -1255,7 +1245,6 @@ Error VulkanContext::prepare_buffers() { } Error VulkanContext::swap_buffers() { - if (!queues_initialized) { return OK; } @@ -1474,9 +1463,11 @@ VkDevice VulkanContext::get_device() { VkPhysicalDevice VulkanContext::get_physical_device() { return gpu; } + int VulkanContext::get_swapchain_image_count() const { return swapchainImageCount; } + uint32_t VulkanContext::get_graphics_queue() const { return graphics_queue_family_index; } @@ -1489,23 +1480,6 @@ VkPhysicalDeviceLimits VulkanContext::get_device_limits() const { return gpu_props.limits; } -VulkanContext::VulkanContext() { - queue_props = nullptr; - command_buffer_count = 0; - instance_validation_layers = nullptr; - use_validation_layers = true; - VK_KHR_incremental_present_enabled = true; - VK_GOOGLE_display_timing_enabled = true; - - command_buffer_queue.resize(1); //first one is the setup command always - command_buffer_queue.write[0] = nullptr; - command_buffer_count = 1; - queues_initialized = false; - - buffers_prepared = false; - swapchainImageCount = 0; -} - RID VulkanContext::local_device_create() { LocalDevice ld; @@ -1550,7 +1524,6 @@ VkDevice VulkanContext::local_device_get_vk_device(RID p_local_device) { } void VulkanContext::local_device_push_command_buffers(RID p_local_device, const VkCommandBuffer *p_buffers, int p_count) { - LocalDevice *ld = local_device_owner.getornull(p_local_device); ERR_FAIL_COND(ld->waiting); @@ -1566,13 +1539,21 @@ void VulkanContext::local_device_push_command_buffers(RID p_local_device, const submit_info.pSignalSemaphores = nullptr; VkResult err = vkQueueSubmit(ld->queue, 1, &submit_info, VK_NULL_HANDLE); + if (err == VK_ERROR_OUT_OF_HOST_MEMORY) { + print_line("out of host memory"); + } + if (err == VK_ERROR_OUT_OF_DEVICE_MEMORY) { + print_line("out of device memory"); + } + if (err == VK_ERROR_DEVICE_LOST) { + print_line("device lost"); + } ERR_FAIL_COND(err); ld->waiting = true; } void VulkanContext::local_device_sync(RID p_local_device) { - LocalDevice *ld = local_device_owner.getornull(p_local_device); ERR_FAIL_COND(!ld->waiting); @@ -1581,25 +1562,37 @@ void VulkanContext::local_device_sync(RID p_local_device) { } void VulkanContext::local_device_free(RID p_local_device) { - LocalDevice *ld = local_device_owner.getornull(p_local_device); vkDestroyDevice(ld->device, nullptr); local_device_owner.free(p_local_device); } +VulkanContext::VulkanContext() { + use_validation_layers = Engine::get_singleton()->is_validation_layers_enabled(); + + command_buffer_queue.resize(1); // First one is always the setup command. + command_buffer_queue.write[0] = nullptr; +} + VulkanContext::~VulkanContext() { if (queue_props) { free(queue_props); } - for (uint32_t i = 0; i < FRAME_LAG; i++) { - vkDestroyFence(device, fences[i], nullptr); - vkDestroySemaphore(device, image_acquired_semaphores[i], nullptr); - vkDestroySemaphore(device, draw_complete_semaphores[i], nullptr); - if (separate_present_queue) { - vkDestroySemaphore(device, image_ownership_semaphores[i], nullptr); + if (device_initialized) { + for (uint32_t i = 0; i < FRAME_LAG; i++) { + vkDestroyFence(device, fences[i], nullptr); + vkDestroySemaphore(device, image_acquired_semaphores[i], nullptr); + vkDestroySemaphore(device, draw_complete_semaphores[i], nullptr); + if (separate_present_queue) { + vkDestroySemaphore(device, image_ownership_semaphores[i], nullptr); + } } + if (inst_initialized && use_validation_layers) { + DestroyDebugUtilsMessengerEXT(inst, dbg_messenger, nullptr); + } + vkDestroyDevice(device, nullptr); + } + if (inst_initialized) { + vkDestroyInstance(inst, nullptr); } - DestroyDebugUtilsMessengerEXT(inst, dbg_messenger, nullptr); - vkDestroyDevice(device, nullptr); - vkDestroyInstance(inst, nullptr); } |