summaryrefslogtreecommitdiff
path: root/drivers/vulkan/vulkan_context.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vulkan/vulkan_context.cpp')
-rw-r--r--drivers/vulkan/vulkan_context.cpp348
1 files changed, 223 insertions, 125 deletions
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index c8ff342713..d293abdee3 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -51,20 +51,20 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(
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") != NULL &&
- strstr(pCallbackData->pMessage, "can result in undefined behavior if this memory is used by the device") != NULL) {
+ 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) {
return VK_FALSE;
}
// This needs to be ignored because Validator is wrong here.
- if (strstr(pCallbackData->pMessage, "SPIR-V module not valid: Pointer operand") != NULL &&
- strstr(pCallbackData->pMessage, "must be a memory object") != NULL) {
+ if (strstr(pCallbackData->pMessage, "SPIR-V module not valid: Pointer operand") != nullptr &&
+ strstr(pCallbackData->pMessage, "must be a memory object") != nullptr) {
return VK_FALSE;
}
// Workaround for Vulkan-Loader usability bug: https://github.com/KhronosGroup/Vulkan-Loader/issues/262.
- if (strstr(pCallbackData->pMessage, "wrong ELF class: ELFCLASS32") != NULL) {
+ if (strstr(pCallbackData->pMessage, "wrong ELF class: ELFCLASS32") != nullptr) {
return VK_FALSE;
}
- if (pCallbackData->pMessageIdName && strstr(pCallbackData->pMessageIdName, "UNASSIGNED-CoreValidation-DrawState-ClearCmdBeforeDraw") != NULL) {
+ if (pCallbackData->pMessageIdName && strstr(pCallbackData->pMessageIdName, "UNASSIGNED-CoreValidation-DrawState-ClearCmdBeforeDraw") != nullptr) {
return VK_FALSE;
}
@@ -92,7 +92,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(
"\n\t\tObject[" + String::num_int64(object) + "]" +
" - " + string_VkObjectType(pCallbackData->pObjects[object].objectType) +
", Handle " + String::num_int64(pCallbackData->pObjects[object].objectHandle);
- if (NULL != pCallbackData->pObjects[object].pObjectName && strlen(pCallbackData->pObjects[object].pObjectName) > 0) {
+ if (nullptr != pCallbackData->pObjects[object].pObjectName && strlen(pCallbackData->pObjects[object].pObjectName) > 0) {
objects_string += ", Name \"" + String(pCallbackData->pObjects[object].pObjectName) + "\"";
}
}
@@ -165,16 +165,17 @@ 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" };
+ const char *instance_validation_layers_alt3[] = { "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation", "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation", "VK_LAYER_GOOGLE_unique_objects" };
+
uint32_t instance_layer_count = 0;
- uint32_t validation_layer_count = 0;
- const char *instance_validation_layers_alt1[] = { "VK_LAYER_LUNARG_standard_validation" };
- const char *instance_validation_layers_alt2[] = { "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation",
- "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation",
- "VK_LAYER_GOOGLE_unique_objects" };
- VkBool32 validation_found = 0;
- err = vkEnumerateInstanceLayerProperties(&instance_layer_count, NULL);
+ err = vkEnumerateInstanceLayerProperties(&instance_layer_count, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
- const char **instance_validation_layers = instance_validation_layers_alt1;
+
+ VkBool32 validation_found = 0;
+ uint32_t validation_layer_count = 0;
+ const char **instance_validation_layers = nullptr;
if (instance_layer_count > 0) {
VkLayerProperties *instance_layers = (VkLayerProperties *)malloc(sizeof(VkLayerProperties) * instance_layer_count);
err = vkEnumerateInstanceLayerProperties(&instance_layer_count, instance_layers);
@@ -183,27 +184,33 @@ Error VulkanContext::_create_validation_layers() {
ERR_FAIL_V(ERR_CANT_CREATE);
}
- validation_found = _check_layers(ARRAY_SIZE(instance_validation_layers_alt1), instance_validation_layers,
- instance_layer_count, instance_layers);
- if (validation_found) {
- enabled_layer_count = ARRAY_SIZE(instance_validation_layers_alt1);
- enabled_layers[0] = "VK_LAYER_LUNARG_standard_validation";
- validation_layer_count = 1;
- } else {
- // use alternative set of validation layers
- instance_validation_layers = instance_validation_layers_alt2;
- enabled_layer_count = ARRAY_SIZE(instance_validation_layers_alt2);
- validation_found = _check_layers(ARRAY_SIZE(instance_validation_layers_alt2), instance_validation_layers,
- instance_layer_count, instance_layers);
+ validation_layer_count = ARRAY_SIZE(instance_validation_layers_alt1);
+ instance_validation_layers = instance_validation_layers_alt1;
+ validation_found = _check_layers(validation_layer_count, instance_validation_layers, instance_layer_count, instance_layers);
+
+ // use alternative (deprecated, removed in SDK 1.1.126.0) set of validation layers
+ if (!validation_found) {
validation_layer_count = ARRAY_SIZE(instance_validation_layers_alt2);
- for (uint32_t i = 0; i < validation_layer_count; i++) {
- enabled_layers[i] = instance_validation_layers[i];
- }
+ instance_validation_layers = instance_validation_layers_alt2;
+ validation_found = _check_layers(validation_layer_count, instance_validation_layers, instance_layer_count, instance_layers);
}
+
+ // use alternative (deprecated, removed in SDK 1.1.121.1) set of validation layers
+ if (!validation_found) {
+ validation_layer_count = ARRAY_SIZE(instance_validation_layers_alt3);
+ instance_validation_layers = instance_validation_layers_alt3;
+ validation_found = _check_layers(validation_layer_count, instance_validation_layers, instance_layer_count, instance_layers);
+ }
+
free(instance_layers);
}
- if (!validation_found) {
+ if (validation_found) {
+ enabled_layer_count = validation_layer_count;
+ for (uint32_t i = 0; i < validation_layer_count; i++) {
+ enabled_layers[i] = instance_validation_layers[i];
+ }
+ } else {
return ERR_CANT_CREATE;
}
@@ -222,12 +229,12 @@ Error VulkanContext::_initialize_extensions() {
VkBool32 platformSurfaceExtFound = 0;
memset(extension_names, 0, sizeof(extension_names));
- err = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL);
+ err = vkEnumerateInstanceExtensionProperties(nullptr, &instance_extension_count, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
if (instance_extension_count > 0) {
VkExtensionProperties *instance_extensions = (VkExtensionProperties *)malloc(sizeof(VkExtensionProperties) * instance_extension_count);
- err = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, instance_extensions);
+ err = vkEnumerateInstanceExtensionProperties(nullptr, &instance_extension_count, instance_extensions);
if (err) {
free(instance_extensions);
ERR_FAIL_V(ERR_CANT_CREATE);
@@ -286,7 +293,7 @@ Error VulkanContext::_create_physical_device() {
CharString namecs = name.utf8();
const VkApplicationInfo app = {
/*sType*/ VK_STRUCTURE_TYPE_APPLICATION_INFO,
- /*pNext*/ NULL,
+ /*pNext*/ nullptr,
/*pApplicationName*/ cs.get_data(),
/*applicationVersion*/ 0,
/*pEngineName*/ namecs.get_data(),
@@ -295,7 +302,7 @@ Error VulkanContext::_create_physical_device() {
};
VkInstanceCreateInfo inst_info = {
/*sType*/ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
- /*pNext*/ NULL,
+ /*pNext*/ nullptr,
/*flags*/ 0,
/*pApplicationInfo*/ &app,
/*enabledLayerCount*/ enabled_layer_count,
@@ -313,7 +320,7 @@ Error VulkanContext::_create_physical_device() {
if (use_validation_layers) {
// VK_EXT_debug_utils style
dbg_messenger_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
- dbg_messenger_create_info.pNext = NULL;
+ dbg_messenger_create_info.pNext = nullptr;
dbg_messenger_create_info.flags = 0;
dbg_messenger_create_info.messageSeverity =
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
@@ -327,7 +334,7 @@ Error VulkanContext::_create_physical_device() {
uint32_t gpu_count;
- VkResult err = vkCreateInstance(&inst_info, NULL, &inst);
+ VkResult err = vkCreateInstance(&inst_info, nullptr, &inst);
ERR_FAIL_COND_V_MSG(err == VK_ERROR_INCOMPATIBLE_DRIVER, ERR_CANT_CREATE,
"Cannot find a compatible Vulkan installable client driver (ICD).\n\n"
"vkCreateInstance Failure");
@@ -342,7 +349,7 @@ Error VulkanContext::_create_physical_device() {
"vkCreateInstance Failure");
/* Make initial call to query gpu_count, then second call for gpu info*/
- err = vkEnumeratePhysicalDevices(inst, &gpu_count, NULL);
+ err = vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
ERR_FAIL_COND_V_MSG(gpu_count == 0, ERR_CANT_CREATE,
@@ -366,12 +373,12 @@ Error VulkanContext::_create_physical_device() {
enabled_extension_count = 0;
memset(extension_names, 0, sizeof(extension_names));
- err = vkEnumerateDeviceExtensionProperties(gpu, NULL, &device_extension_count, NULL);
+ err = vkEnumerateDeviceExtensionProperties(gpu, nullptr, &device_extension_count, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
if (device_extension_count > 0) {
VkExtensionProperties *device_extensions = (VkExtensionProperties *)malloc(sizeof(VkExtensionProperties) * device_extension_count);
- err = vkEnumerateDeviceExtensionProperties(gpu, NULL, &device_extension_count, device_extensions);
+ err = vkEnumerateDeviceExtensionProperties(gpu, nullptr, &device_extension_count, device_extensions);
if (err) {
free(device_extensions);
ERR_FAIL_V(ERR_CANT_CREATE);
@@ -449,16 +456,16 @@ Error VulkanContext::_create_physical_device() {
(PFN_vkCmdInsertDebugUtilsLabelEXT)vkGetInstanceProcAddr(inst, "vkCmdInsertDebugUtilsLabelEXT");
SetDebugUtilsObjectNameEXT =
(PFN_vkSetDebugUtilsObjectNameEXT)vkGetInstanceProcAddr(inst, "vkSetDebugUtilsObjectNameEXT");
- if (NULL == CreateDebugUtilsMessengerEXT || NULL == DestroyDebugUtilsMessengerEXT ||
- NULL == SubmitDebugUtilsMessageEXT || NULL == CmdBeginDebugUtilsLabelEXT ||
- NULL == CmdEndDebugUtilsLabelEXT || NULL == CmdInsertDebugUtilsLabelEXT ||
- NULL == SetDebugUtilsObjectNameEXT) {
+ if (nullptr == CreateDebugUtilsMessengerEXT || nullptr == DestroyDebugUtilsMessengerEXT ||
+ nullptr == SubmitDebugUtilsMessageEXT || nullptr == CmdBeginDebugUtilsLabelEXT ||
+ nullptr == CmdEndDebugUtilsLabelEXT || nullptr == CmdInsertDebugUtilsLabelEXT ||
+ nullptr == SetDebugUtilsObjectNameEXT) {
ERR_FAIL_V_MSG(ERR_CANT_CREATE,
"GetProcAddr: Failed to init VK_EXT_debug_utils\n"
"GetProcAddr: Failure");
}
- err = CreateDebugUtilsMessengerEXT(inst, &dbg_messenger_create_info, NULL, &dbg_messenger);
+ err = CreateDebugUtilsMessengerEXT(inst, &dbg_messenger_create_info, nullptr, &dbg_messenger);
switch (err) {
case VK_SUCCESS:
break;
@@ -478,7 +485,7 @@ Error VulkanContext::_create_physical_device() {
vkGetPhysicalDeviceProperties(gpu, &gpu_props);
/* Call with NULL data to get count */
- vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_family_count, NULL);
+ vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_family_count, nullptr);
ERR_FAIL_COND_V(queue_family_count == 0, ERR_CANT_CREATE);
queue_props = (VkQueueFamilyProperties *)malloc(queue_family_count * sizeof(VkQueueFamilyProperties));
@@ -492,7 +499,7 @@ Error VulkanContext::_create_physical_device() {
#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \
{ \
fp##entrypoint = (PFN_vk##entrypoint)vkGetInstanceProcAddr(inst, "vk" #entrypoint); \
- ERR_FAIL_COND_V_MSG(fp##entrypoint == NULL, ERR_CANT_CREATE, \
+ ERR_FAIL_COND_V_MSG(fp##entrypoint == nullptr, ERR_CANT_CREATE, \
"vkGetInstanceProcAddr failed to find vk" #entrypoint); \
}
@@ -511,7 +518,7 @@ Error VulkanContext::_create_device() {
float queue_priorities[1] = { 0.0 };
VkDeviceQueueCreateInfo queues[2];
queues[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- queues[0].pNext = NULL;
+ queues[0].pNext = nullptr;
queues[0].queueFamilyIndex = graphics_queue_family_index;
queues[0].queueCount = 1;
queues[0].pQueuePriorities = queue_priorities;
@@ -519,12 +526,12 @@ Error VulkanContext::_create_device() {
VkDeviceCreateInfo sdevice = {
/*sType*/ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
- /*pNext*/ NULL,
+ /*pNext*/ nullptr,
/*flags*/ 0,
/*queueCreateInfoCount*/ 1,
/*pQueueCreateInfos*/ queues,
/*enabledLayerCount*/ 0,
- /*ppEnabledLayerNames*/ NULL,
+ /*ppEnabledLayerNames*/ nullptr,
/*enabledExtensionCount*/ enabled_extension_count,
/*ppEnabledExtensionNames*/ (const char *const *)extension_names,
/*pEnabledFeatures*/ &physical_device_features, // If specific features are required, pass them in here
@@ -532,14 +539,14 @@ Error VulkanContext::_create_device() {
};
if (separate_present_queue) {
queues[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- queues[1].pNext = NULL;
+ queues[1].pNext = nullptr;
queues[1].queueFamilyIndex = present_queue_family_index;
queues[1].queueCount = 1;
queues[1].pQueuePriorities = queue_priorities;
queues[1].flags = 0;
sdevice.queueCreateInfoCount = 2;
}
- err = vkCreateDevice(gpu, &sdevice, NULL, &device);
+ err = vkCreateDevice(gpu, &sdevice, nullptr, &device);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
return OK;
}
@@ -593,12 +600,12 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR surface) {
_create_device();
- static PFN_vkGetDeviceProcAddr g_gdpa = NULL;
+ 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 == NULL, ERR_CANT_CREATE, \
+ ERR_FAIL_COND_V_MSG(fp##entrypoint == nullptr, ERR_CANT_CREATE, \
"vkGetDeviceProcAddr failed to find vk" #entrypoint); \
}
@@ -622,7 +629,7 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR surface) {
// Get the list of VkFormat's that are supported:
uint32_t formatCount;
- VkResult err = fpGetPhysicalDeviceSurfaceFormatsKHR(gpu, surface, &formatCount, NULL);
+ VkResult err = fpGetPhysicalDeviceSurfaceFormatsKHR(gpu, surface, &formatCount, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
VkSurfaceFormatKHR *surfFormats = (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
err = fpGetPhysicalDeviceSurfaceFormatsKHR(gpu, surface, &formatCount, surfFormats);
@@ -662,7 +669,7 @@ Error VulkanContext::_create_semaphores() {
// rendering and waiting for drawing to be complete before presenting
VkSemaphoreCreateInfo semaphoreCreateInfo = {
/*sType*/ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
- /*pNext*/ NULL,
+ /*pNext*/ nullptr,
/*flags*/ 0,
};
@@ -670,21 +677,21 @@ Error VulkanContext::_create_semaphores() {
// ahead of the image presents
VkFenceCreateInfo fence_ci = {
/*sType*/ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
- /*pNext*/ NULL,
+ /*pNext*/ nullptr,
/*flags*/ VK_FENCE_CREATE_SIGNALED_BIT
};
for (uint32_t i = 0; i < FRAME_LAG; i++) {
- err = vkCreateFence(device, &fence_ci, NULL, &fences[i]);
+ err = vkCreateFence(device, &fence_ci, nullptr, &fences[i]);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
- err = vkCreateSemaphore(device, &semaphoreCreateInfo, NULL, &image_acquired_semaphores[i]);
+ err = vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &image_acquired_semaphores[i]);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
- err = vkCreateSemaphore(device, &semaphoreCreateInfo, NULL, &draw_complete_semaphores[i]);
+ err = vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &draw_complete_semaphores[i]);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
if (separate_present_queue) {
- err = vkCreateSemaphore(device, &semaphoreCreateInfo, NULL, &image_ownership_semaphores[i]);
+ err = vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &image_ownership_semaphores[i]);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
}
}
@@ -696,7 +703,9 @@ Error VulkanContext::_create_semaphores() {
return OK;
}
-int VulkanContext::_window_create(VkSurfaceKHR p_surface, int p_width, int p_height) {
+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
@@ -710,39 +719,37 @@ int VulkanContext::_window_create(VkSurfaceKHR p_surface, int p_width, int p_hei
window.width = p_width;
window.height = p_height;
Error err = _update_swap_chain(&window);
- ERR_FAIL_COND_V(err != OK, -1);
+ ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
- int id = last_window_id;
- windows[id] = window;
- last_window_id++;
- return id;
+ windows[p_window_id] = window;
+ return OK;
}
-void VulkanContext::window_resize(int p_window, int p_width, int p_height) {
+void VulkanContext::window_resize(DisplayServer::WindowID p_window, int p_width, int p_height) {
ERR_FAIL_COND(!windows.has(p_window));
windows[p_window].width = p_width;
windows[p_window].height = p_height;
_update_swap_chain(&windows[p_window]);
}
-int VulkanContext::window_get_width(int p_window) {
+int VulkanContext::window_get_width(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), -1);
return windows[p_window].width;
}
-int VulkanContext::window_get_height(int p_window) {
+int VulkanContext::window_get_height(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), -1);
return windows[p_window].height;
}
-VkRenderPass VulkanContext::window_get_render_pass(int p_window) {
+VkRenderPass VulkanContext::window_get_render_pass(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE);
Window *w = &windows[p_window];
//vulkan use of currentbuffer
return w->render_pass;
}
-VkFramebuffer VulkanContext::window_get_framebuffer(int p_window) {
+VkFramebuffer VulkanContext::window_get_framebuffer(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE);
ERR_FAIL_COND_V(!buffers_prepared, VK_NULL_HANDLE);
Window *w = &windows[p_window];
@@ -750,10 +757,10 @@ VkFramebuffer VulkanContext::window_get_framebuffer(int p_window) {
return w->swapchain_image_resources[w->current_buffer].framebuffer;
}
-void VulkanContext::window_destroy(int p_window_id) {
+void VulkanContext::window_destroy(DisplayServer::WindowID p_window_id) {
ERR_FAIL_COND(!windows.has(p_window_id));
_clean_up_swap_chain(&windows[p_window_id]);
- vkDestroySurfaceKHR(inst, windows[p_window_id].surface, NULL);
+ vkDestroySurfaceKHR(inst, windows[p_window_id].surface, nullptr);
windows.erase(p_window_id);
}
@@ -765,20 +772,20 @@ Error VulkanContext::_clean_up_swap_chain(Window *window) {
vkDeviceWaitIdle(device);
//this destroys images associated it seems
- fpDestroySwapchainKHR(device, window->swapchain, NULL);
+ fpDestroySwapchainKHR(device, window->swapchain, nullptr);
window->swapchain = VK_NULL_HANDLE;
- vkDestroyRenderPass(device, window->render_pass, NULL);
+ vkDestroyRenderPass(device, window->render_pass, nullptr);
if (window->swapchain_image_resources) {
for (uint32_t i = 0; i < swapchainImageCount; i++) {
- vkDestroyImageView(device, window->swapchain_image_resources[i].view, NULL);
- vkDestroyFramebuffer(device, window->swapchain_image_resources[i].framebuffer, NULL);
+ vkDestroyImageView(device, window->swapchain_image_resources[i].view, nullptr);
+ vkDestroyFramebuffer(device, window->swapchain_image_resources[i].framebuffer, nullptr);
}
free(window->swapchain_image_resources);
- window->swapchain_image_resources = NULL;
+ window->swapchain_image_resources = nullptr;
}
if (separate_present_queue) {
- vkDestroyCommandPool(device, window->present_cmd_pool, NULL);
+ vkDestroyCommandPool(device, window->present_cmd_pool, nullptr);
}
return OK;
}
@@ -796,7 +803,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
uint32_t presentModeCount;
- err = fpGetPhysicalDeviceSurfacePresentModesKHR(gpu, window->surface, &presentModeCount, NULL);
+ err = fpGetPhysicalDeviceSurfacePresentModesKHR(gpu, window->surface, &presentModeCount, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
VkPresentModeKHR *presentModes = (VkPresentModeKHR *)malloc(presentModeCount * sizeof(VkPresentModeKHR));
ERR_FAIL_COND_V(!presentModes, ERR_CANT_CREATE);
@@ -918,7 +925,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
VkSwapchainCreateInfoKHR swapchain_ci = {
/*sType*/ VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
- /*pNext*/ NULL,
+ /*pNext*/ nullptr,
/*flags*/ 0,
/*surface*/ window->surface,
/*minImageCount*/ desiredNumOfSwapchainImages,
@@ -932,19 +939,19 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/*imageUsage*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
/*imageSharingMode*/ VK_SHARING_MODE_EXCLUSIVE,
/*queueFamilyIndexCount*/ 0,
- /*pQueueFamilyIndices*/ NULL,
+ /*pQueueFamilyIndices*/ nullptr,
/*preTransform*/ (VkSurfaceTransformFlagBitsKHR)preTransform,
/*compositeAlpha*/ compositeAlpha,
/*presentMode*/ swapchainPresentMode,
/*clipped*/ true,
- /*oldSwapchain*/ NULL,
+ /*oldSwapchain*/ VK_NULL_HANDLE,
};
- err = fpCreateSwapchainKHR(device, &swapchain_ci, NULL, &window->swapchain);
+ err = fpCreateSwapchainKHR(device, &swapchain_ci, nullptr, &window->swapchain);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
uint32_t sp_image_count;
- err = fpGetSwapchainImagesKHR(device, window->swapchain, &sp_image_count, NULL);
+ err = fpGetSwapchainImagesKHR(device, window->swapchain, &sp_image_count, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
if (swapchainImageCount == 0) {
@@ -972,7 +979,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
for (uint32_t i = 0; i < swapchainImageCount; i++) {
VkImageViewCreateInfo color_image_view = {
/*sType*/ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
- /*pNext*/ NULL,
+ /*pNext*/ nullptr,
/*flags*/ 0,
/*image*/ swapchainImages[i],
/*viewType*/ VK_IMAGE_VIEW_TYPE_2D,
@@ -994,7 +1001,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
color_image_view.image = window->swapchain_image_resources[i].image;
- err = vkCreateImageView(device, &color_image_view, NULL, &window->swapchain_image_resources[i].view);
+ err = vkCreateImageView(device, &color_image_view, nullptr, &window->swapchain_image_resources[i].view);
if (err) {
free(swapchainImages);
ERR_FAIL_V(ERR_CANT_CREATE);
@@ -1028,33 +1035,33 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/*flags*/ 0,
/*pipelineBindPoint*/ VK_PIPELINE_BIND_POINT_GRAPHICS,
/*inputAttachmentCount*/ 0,
- /*pInputAttachments*/ NULL,
+ /*pInputAttachments*/ nullptr,
/*colorAttachmentCount*/ 1,
/*pColorAttachments*/ &color_reference,
- /*pResolveAttachments*/ NULL,
- /*pDepthStencilAttachment*/ NULL,
+ /*pResolveAttachments*/ nullptr,
+ /*pDepthStencilAttachment*/ nullptr,
/*preserveAttachmentCount*/ 0,
- /*pPreserveAttachments*/ NULL,
+ /*pPreserveAttachments*/ nullptr,
};
const VkRenderPassCreateInfo rp_info = {
/*sTyp*/ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
- /*pNext*/ NULL,
+ /*pNext*/ nullptr,
/*flags*/ 0,
/*attachmentCount*/ 1,
/*pAttachments*/ &attachment,
/*subpassCount*/ 1,
/*pSubpasses*/ &subpass,
/*dependencyCount*/ 0,
- /*pDependencies*/ NULL,
+ /*pDependencies*/ nullptr,
};
- err = vkCreateRenderPass(device, &rp_info, NULL, &window->render_pass);
+ err = vkCreateRenderPass(device, &rp_info, nullptr, &window->render_pass);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
for (uint32_t i = 0; i < swapchainImageCount; i++) {
const VkFramebufferCreateInfo fb_info = {
/*sType*/ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
- /*pNext*/ NULL,
+ /*pNext*/ nullptr,
/*flags*/ 0,
/*renderPass*/ window->render_pass,
/*attachmentCount*/ 1,
@@ -1064,7 +1071,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/*layers*/ 1,
};
- err = vkCreateFramebuffer(device, &fb_info, NULL, &window->swapchain_image_resources[i].framebuffer);
+ err = vkCreateFramebuffer(device, &fb_info, nullptr, &window->swapchain_image_resources[i].framebuffer);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
}
}
@@ -1074,15 +1081,15 @@ Error VulkanContext::_update_swap_chain(Window *window) {
if (separate_present_queue) {
const VkCommandPoolCreateInfo present_cmd_pool_info = {
/*sType*/ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
- /*pNext*/ NULL,
+ /*pNext*/ nullptr,
/*flags*/ 0,
/*queueFamilyIndex*/ present_queue_family_index,
};
- err = vkCreateCommandPool(device, &present_cmd_pool_info, NULL, &window->present_cmd_pool);
+ err = vkCreateCommandPool(device, &present_cmd_pool_info, nullptr, &window->present_cmd_pool);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
const VkCommandBufferAllocateInfo present_cmd_info = {
/*sType*/ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
- /*pNext*/ NULL,
+ /*pNext*/ nullptr,
/*commandPool*/ window->present_cmd_pool,
/*level*/ VK_COMMAND_BUFFER_LEVEL_PRIMARY,
/*commandBufferCount*/ 1,
@@ -1094,16 +1101,16 @@ Error VulkanContext::_update_swap_chain(Window *window) {
const VkCommandBufferBeginInfo cmd_buf_info = {
/*sType*/ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
- /*pNext*/ NULL,
+ /*pNext*/ nullptr,
/*flags*/ VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
- /*pInheritanceInfo*/ NULL,
+ /*pInheritanceInfo*/ nullptr,
};
err = vkBeginCommandBuffer(window->swapchain_image_resources[i].graphics_to_present_cmd, &cmd_buf_info);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
VkImageMemoryBarrier image_ownership_barrier = {
/*sType*/ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
- /*pNext*/ NULL,
+ /*pNext*/ nullptr,
/*srcAccessMask*/ 0,
/*dstAccessMask*/ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
/*oldLayout*/ VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
@@ -1115,7 +1122,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
};
vkCmdPipelineBarrier(window->swapchain_image_resources[i].graphics_to_present_cmd, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
- VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, NULL, 0, NULL, 1, &image_ownership_barrier);
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_ownership_barrier);
err = vkEndCommandBuffer(window->swapchain_image_resources[i].graphics_to_present_cmd);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
}
@@ -1163,16 +1170,16 @@ void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) {
//use a fence to wait for everything done
VkSubmitInfo submit_info;
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submit_info.pNext = NULL;
- submit_info.pWaitDstStageMask = NULL;
+ submit_info.pNext = nullptr;
+ submit_info.pWaitDstStageMask = nullptr;
submit_info.waitSemaphoreCount = 0;
- submit_info.pWaitSemaphores = NULL;
+ submit_info.pWaitSemaphores = nullptr;
submit_info.commandBufferCount = 1;
submit_info.pCommandBuffers = command_buffer_queue.ptr();
submit_info.signalSemaphoreCount = 0;
- submit_info.pSignalSemaphores = NULL;
+ submit_info.pSignalSemaphores = nullptr;
VkResult err = vkQueueSubmit(graphics_queue, 1, &submit_info, VK_NULL_HANDLE);
- command_buffer_queue.write[0] = NULL;
+ command_buffer_queue.write[0] = nullptr;
ERR_FAIL_COND(err);
vkDeviceWaitIdle(device);
}
@@ -1183,14 +1190,14 @@ void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) {
VkSubmitInfo submit_info;
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submit_info.pNext = NULL;
- submit_info.pWaitDstStageMask = NULL;
+ submit_info.pNext = nullptr;
+ submit_info.pWaitDstStageMask = nullptr;
submit_info.waitSemaphoreCount = 0;
- submit_info.pWaitSemaphores = NULL;
+ submit_info.pWaitSemaphores = nullptr;
submit_info.commandBufferCount = command_buffer_count - 1;
submit_info.pCommandBuffers = command_buffer_queue.ptr() + 1;
submit_info.signalSemaphoreCount = 0;
- submit_info.pSignalSemaphores = NULL;
+ submit_info.pSignalSemaphores = nullptr;
VkResult err = vkQueueSubmit(graphics_queue, 1, &submit_info, VK_NULL_HANDLE);
ERR_FAIL_COND(err);
vkDeviceWaitIdle(device);
@@ -1274,10 +1281,10 @@ Error VulkanContext::swap_buffers() {
// engine has fully released ownership to the application, and it is
// okay to render to the image.
- const VkCommandBuffer *commands_ptr = NULL;
+ const VkCommandBuffer *commands_ptr = nullptr;
uint32_t commands_to_submit = 0;
- if (command_buffer_queue[0] == NULL) {
+ if (command_buffer_queue[0] == nullptr) {
//no setup command, but commands to submit, submit from the first and skip command
if (command_buffer_count > 1) {
commands_ptr = command_buffer_queue.ptr() + 1;
@@ -1291,7 +1298,7 @@ Error VulkanContext::swap_buffers() {
VkPipelineStageFlags pipe_stage_flags;
VkSubmitInfo submit_info;
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submit_info.pNext = NULL;
+ submit_info.pNext = nullptr;
submit_info.pWaitDstStageMask = &pipe_stage_flags;
pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
submit_info.waitSemaphoreCount = 1;
@@ -1303,7 +1310,7 @@ Error VulkanContext::swap_buffers() {
err = vkQueueSubmit(graphics_queue, 1, &submit_info, fences[frame_index]);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
- command_buffer_queue.write[0] = NULL;
+ command_buffer_queue.write[0] = nullptr;
command_buffer_count = 1;
if (separate_present_queue) {
@@ -1339,13 +1346,13 @@ Error VulkanContext::swap_buffers() {
// otherwise wait for draw complete
VkPresentInfoKHR present = {
/*sType*/ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
- /*pNext*/ NULL,
+ /*pNext*/ nullptr,
/*waitSemaphoreCount*/ 1,
/*pWaitSemaphores*/ (separate_present_queue) ? &image_ownership_semaphores[frame_index] : &draw_complete_semaphores[frame_index],
/*swapchainCount*/ 0,
- /*pSwapchain*/ NULL,
- /*pImageIndices*/ NULL,
- /*pResults*/ NULL,
+ /*pSwapchain*/ nullptr,
+ /*pImageIndices*/ nullptr,
+ /*pResults*/ nullptr,
};
VkSwapchainKHR *pSwapchains = (VkSwapchainKHR *)alloca(sizeof(VkSwapchainKHR *) * windows.size());
@@ -1483,25 +1490,116 @@ VkPhysicalDeviceLimits VulkanContext::get_device_limits() const {
}
VulkanContext::VulkanContext() {
- queue_props = NULL;
+ queue_props = nullptr;
command_buffer_count = 0;
- instance_validation_layers = NULL;
+ 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] = NULL;
+ command_buffer_queue.write[0] = nullptr;
command_buffer_count = 1;
queues_initialized = false;
buffers_prepared = false;
swapchainImageCount = 0;
- last_window_id = 0;
+}
+
+RID VulkanContext::local_device_create() {
+ LocalDevice ld;
+
+ { //create device
+ VkResult err;
+ float queue_priorities[1] = { 0.0 };
+ VkDeviceQueueCreateInfo queues[2];
+ queues[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+ queues[0].pNext = nullptr;
+ queues[0].queueFamilyIndex = graphics_queue_family_index;
+ queues[0].queueCount = 1;
+ queues[0].pQueuePriorities = queue_priorities;
+ queues[0].flags = 0;
+
+ VkDeviceCreateInfo sdevice = {
+ /*sType =*/VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+ /*pNext */ nullptr,
+ /*flags */ 0,
+ /*queueCreateInfoCount */ 1,
+ /*pQueueCreateInfos */ queues,
+ /*enabledLayerCount */ 0,
+ /*ppEnabledLayerNames */ nullptr,
+ /*enabledExtensionCount */ enabled_extension_count,
+ /*ppEnabledExtensionNames */ (const char *const *)extension_names,
+ /*pEnabledFeatures */ &physical_device_features, // If specific features are required, pass them in here
+ };
+ err = vkCreateDevice(gpu, &sdevice, nullptr, &ld.device);
+ ERR_FAIL_COND_V(err, RID());
+ }
+
+ { //create graphics queue
+
+ vkGetDeviceQueue(ld.device, graphics_queue_family_index, 0, &ld.queue);
+ }
+
+ return local_device_owner.make_rid(ld);
+}
+
+VkDevice VulkanContext::local_device_get_vk_device(RID p_local_device) {
+ LocalDevice *ld = local_device_owner.getornull(p_local_device);
+ return ld->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);
+
+ VkSubmitInfo submit_info;
+ submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submit_info.pNext = nullptr;
+ submit_info.pWaitDstStageMask = nullptr;
+ submit_info.waitSemaphoreCount = 0;
+ submit_info.pWaitSemaphores = nullptr;
+ submit_info.commandBufferCount = p_count;
+ submit_info.pCommandBuffers = p_buffers;
+ submit_info.signalSemaphoreCount = 0;
+ submit_info.pSignalSemaphores = nullptr;
+
+ VkResult err = vkQueueSubmit(ld->queue, 1, &submit_info, VK_NULL_HANDLE);
+ 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);
+
+ vkDeviceWaitIdle(ld->device);
+ ld->waiting = false;
+}
+
+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() {
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);
+ }
+ }
+ DestroyDebugUtilsMessengerEXT(inst, dbg_messenger, nullptr);
+ vkDestroyDevice(device, nullptr);
+ vkDestroyInstance(inst, nullptr);
}