Update comments in vulkan_context.cpp

Co-authored-by: Quinn Leavitt <59779489+QuinnLeavitt@users.noreply.github.com>
This commit is contained in:
Aaron Franke 2022-07-17 01:12:11 -05:00
parent 3ae61590e1
commit 97df94ae90
No known key found for this signature in database
GPG Key ID: 40A1750B977E56BF

View File

@ -227,13 +227,13 @@ VkBool32 VulkanContext::_check_layers(uint32_t check_count, const char *const *c
Error VulkanContext::_get_preferred_validation_layers(uint32_t *count, const char *const **names) { Error VulkanContext::_get_preferred_validation_layers(uint32_t *count, const char *const **names) {
static const LocalVector<LocalVector<const char *>> instance_validation_layers_alt{ static const LocalVector<LocalVector<const char *>> instance_validation_layers_alt{
// Preferred set of validation layers // Preferred set of validation layers.
{ "VK_LAYER_KHRONOS_validation" }, { "VK_LAYER_KHRONOS_validation" },
// Alternative (deprecated, removed in SDK 1.1.126.0) set of validation layers // Alternative (deprecated, removed in SDK 1.1.126.0) set of validation layers.
{ "VK_LAYER_LUNARG_standard_validation" }, { "VK_LAYER_LUNARG_standard_validation" },
// Alternative (deprecated, removed in SDK 1.1.121.1) set of validation layers // Alternative (deprecated, removed in SDK 1.1.121.1) set of validation layers.
{ "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation", "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation", "VK_LAYER_GOOGLE_unique_objects" } { "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation", "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation", "VK_LAYER_GOOGLE_unique_objects" }
}; };
@ -281,7 +281,7 @@ typedef VkResult(VKAPI_PTR *_vkEnumerateInstanceVersion)(uint32_t *);
Error VulkanContext::_obtain_vulkan_version() { Error VulkanContext::_obtain_vulkan_version() {
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkApplicationInfo.html#_description // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkApplicationInfo.html#_description
// for Vulkan 1.0 vkEnumerateInstanceVersion is not available, including not in the loader we compile against on Android. // For Vulkan 1.0 vkEnumerateInstanceVersion is not available, including not in the loader we compile against on Android.
_vkEnumerateInstanceVersion func = (_vkEnumerateInstanceVersion)vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion"); _vkEnumerateInstanceVersion func = (_vkEnumerateInstanceVersion)vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion");
if (func != nullptr) { if (func != nullptr) {
uint32_t api_version; uint32_t api_version;
@ -291,15 +291,15 @@ Error VulkanContext::_obtain_vulkan_version() {
vulkan_minor = VK_API_VERSION_MINOR(api_version); vulkan_minor = VK_API_VERSION_MINOR(api_version);
vulkan_patch = VK_API_VERSION_PATCH(api_version); vulkan_patch = VK_API_VERSION_PATCH(api_version);
} else { } else {
// according to the documentation this shouldn't fail with anything except a memory allocation error // According to the documentation this shouldn't fail with anything except a memory allocation error
// in which case we're in deep trouble anyway // in which case we're in deep trouble anyway.
ERR_FAIL_V(ERR_CANT_CREATE); ERR_FAIL_V(ERR_CANT_CREATE);
} }
} else { } else {
print_line("vkEnumerateInstanceVersion not available, assuming Vulkan 1.0."); print_line("vkEnumerateInstanceVersion not available, assuming Vulkan 1.0.");
} }
// we don't go above 1.2 // We don't go above 1.2.
if ((vulkan_major > 1) || (vulkan_major == 1 && vulkan_minor > 2)) { if ((vulkan_major > 1) || (vulkan_major == 1 && vulkan_minor > 2)) {
vulkan_major = 1; vulkan_major = 1;
vulkan_minor = 2; vulkan_minor = 2;
@ -315,7 +315,7 @@ Error VulkanContext::_initialize_extensions() {
enabled_extension_count = 0; enabled_extension_count = 0;
enabled_debug_utils = false; enabled_debug_utils = false;
enabled_debug_report = false; enabled_debug_report = false;
/* Look for instance extensions */ // Look for instance extensions.
VkBool32 surfaceExtFound = 0; VkBool32 surfaceExtFound = 0;
VkBool32 platformSurfaceExtFound = 0; VkBool32 platformSurfaceExtFound = 0;
memset(extension_names, 0, sizeof(extension_names)); memset(extension_names, 0, sizeof(extension_names));
@ -415,7 +415,7 @@ String VulkanContext::SubgroupCapabilities::supported_stages_desc() const {
res += ", STAGE_COMPUTE"; res += ", STAGE_COMPUTE";
} }
/* these are not defined on Android GRMBL */ // These are not defined on Android GRMBL.
if (supportedStages & 0x00000100 /* VK_SHADER_STAGE_RAYGEN_BIT_KHR */) { if (supportedStages & 0x00000100 /* VK_SHADER_STAGE_RAYGEN_BIT_KHR */) {
res += ", STAGE_RAYGEN_KHR"; res += ", STAGE_RAYGEN_KHR";
} }
@ -441,7 +441,7 @@ String VulkanContext::SubgroupCapabilities::supported_stages_desc() const {
res += ", STAGE_MESH_NV"; res += ", STAGE_MESH_NV";
} }
return res.substr(2); // remove first ", " return res.substr(2); // Remove first ", "
} }
uint32_t VulkanContext::SubgroupCapabilities::supported_operations_flags_rd() const { uint32_t VulkanContext::SubgroupCapabilities::supported_operations_flags_rd() const {
@ -506,19 +506,19 @@ String VulkanContext::SubgroupCapabilities::supported_operations_desc() const {
res += ", FEATURE_PARTITIONED_NV"; res += ", FEATURE_PARTITIONED_NV";
} }
return res.substr(2); // remove first ", " return res.substr(2); // Remove first ", "
} }
Error VulkanContext::_check_capabilities() { Error VulkanContext::_check_capabilities() {
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_KHR_multiview.html // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_KHR_multiview.html
// https://www.khronos.org/blog/vulkan-subgroup-tutorial // https://www.khronos.org/blog/vulkan-subgroup-tutorial
// for Vulkan 1.0 vkGetPhysicalDeviceProperties2 is not available, including not in the loader we compile against on Android. // For Vulkan 1.0 vkGetPhysicalDeviceProperties2 is not available, including not in the loader we compile against on Android.
// so we check if the functions are accessible by getting their function pointers and skipping if not // So we check if the functions are accessible by getting their function pointers and skipping if not
// (note that the desktop loader does a better job here but the android loader doesn't) // (note that the desktop loader does a better job here but the android loader doesn't.)
// assume not supported until proven otherwise // Assume not supported until proven otherwise.
vrs_capabilities.pipeline_vrs_supported = false; vrs_capabilities.pipeline_vrs_supported = false;
vrs_capabilities.primitive_vrs_supported = false; vrs_capabilities.primitive_vrs_supported = false;
vrs_capabilities.attachment_vrs_supported = false; vrs_capabilities.attachment_vrs_supported = false;
@ -538,14 +538,14 @@ Error VulkanContext::_check_capabilities() {
storage_buffer_capabilities.storage_push_constant_16_is_supported = false; storage_buffer_capabilities.storage_push_constant_16_is_supported = false;
storage_buffer_capabilities.storage_input_output_16 = false; storage_buffer_capabilities.storage_input_output_16 = false;
// check for extended features // Check for extended features.
PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2"); PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2");
if (vkGetPhysicalDeviceFeatures2_func == nullptr) { if (vkGetPhysicalDeviceFeatures2_func == nullptr) {
// In Vulkan 1.0 might be accessible under its original extension name // In Vulkan 1.0 might be accessible under its original extension name.
vkGetPhysicalDeviceFeatures2_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2KHR"); vkGetPhysicalDeviceFeatures2_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2KHR");
} }
if (vkGetPhysicalDeviceFeatures2_func != nullptr) { if (vkGetPhysicalDeviceFeatures2_func != nullptr) {
// check our extended features // Check our extended features.
VkPhysicalDeviceFragmentShadingRateFeaturesKHR vrs_features = { VkPhysicalDeviceFragmentShadingRateFeaturesKHR vrs_features = {
/*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR, /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR,
/*pNext*/ nullptr, /*pNext*/ nullptr,
@ -601,10 +601,10 @@ Error VulkanContext::_check_capabilities() {
storage_buffer_capabilities.storage_input_output_16 = storage_feature.storageInputOutput16; storage_buffer_capabilities.storage_input_output_16 = storage_feature.storageInputOutput16;
} }
// check extended properties // Check extended properties.
PFN_vkGetPhysicalDeviceProperties2 device_properties_func = (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceProperties2"); PFN_vkGetPhysicalDeviceProperties2 device_properties_func = (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceProperties2");
if (device_properties_func == nullptr) { if (device_properties_func == nullptr) {
// In Vulkan 1.0 might be accessible under its original extension name // In Vulkan 1.0 might be accessible under its original extension name.
device_properties_func = (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceProperties2KHR"); device_properties_func = (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceProperties2KHR");
} }
if (device_properties_func != nullptr) { if (device_properties_func != nullptr) {
@ -693,10 +693,10 @@ Error VulkanContext::_check_capabilities() {
} }
Error VulkanContext::_create_instance() { Error VulkanContext::_create_instance() {
/* obtain version */ // Obtain Vulkan version.
_obtain_vulkan_version(); _obtain_vulkan_version();
/* initialise extensions */ // Initialize extensions.
{ {
Error err = _initialize_extensions(); Error err = _initialize_extensions();
if (err != OK) { if (err != OK) {
@ -784,8 +784,7 @@ Error VulkanContext::_create_instance() {
#endif #endif
if (enabled_debug_utils) { if (enabled_debug_utils) {
// Setup VK_EXT_debug_utils function pointers always (we use them for // Setup VK_EXT_debug_utils function pointers always (we use them for debug labels and names).
// debug labels and names).
CreateDebugUtilsMessengerEXT = CreateDebugUtilsMessengerEXT =
(PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(inst, "vkCreateDebugUtilsMessengerEXT"); (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(inst, "vkCreateDebugUtilsMessengerEXT");
DestroyDebugUtilsMessengerEXT = DestroyDebugUtilsMessengerEXT =
@ -858,7 +857,7 @@ Error VulkanContext::_create_instance() {
} }
Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) { Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
/* Make initial call to query gpu_count, then second call for gpu info*/ // Make initial call to query gpu_count, then second call for gpu info.
uint32_t gpu_count = 0; uint32_t gpu_count = 0;
VkResult err = vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr); VkResult err = vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE); ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
@ -894,7 +893,7 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
return ERR_CANT_CREATE; return ERR_CANT_CREATE;
} }
// not really needed but nice to print the correct entry // Not really needed but nice to print the correct entry.
for (uint32_t i = 0; i < gpu_count; ++i) { for (uint32_t i = 0; i < gpu_count; ++i) {
if (physical_devices[i] == gpu) { if (physical_devices[i] == gpu) {
device_index = i; device_index = i;
@ -1006,13 +1005,13 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
free(physical_devices); free(physical_devices);
/* Look for device extensions */ // Look for device extensions.
uint32_t device_extension_count = 0; uint32_t device_extension_count = 0;
VkBool32 swapchainExtFound = 0; VkBool32 swapchainExtFound = 0;
enabled_extension_count = 0; enabled_extension_count = 0;
memset(extension_names, 0, sizeof(extension_names)); memset(extension_names, 0, sizeof(extension_names));
/* Get identifier properties */ // Get identifier properties.
vkGetPhysicalDeviceProperties(gpu, &gpu_props); vkGetPhysicalDeviceProperties(gpu, &gpu_props);
device_name = gpu_props.deviceName; device_name = gpu_props.deviceName;
@ -1054,7 +1053,7 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
extension_names[enabled_extension_count++] = VK_KHR_SWAPCHAIN_EXTENSION_NAME; extension_names[enabled_extension_count++] = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
} }
if (!strcmp(VK_KHR_MULTIVIEW_EXTENSION_NAME, device_extensions[i].extensionName)) { if (!strcmp(VK_KHR_MULTIVIEW_EXTENSION_NAME, device_extensions[i].extensionName)) {
// if multiview is supported, enable it // If multiview is supported, enable it.
extension_names[enabled_extension_count++] = VK_KHR_MULTIVIEW_EXTENSION_NAME; extension_names[enabled_extension_count++] = VK_KHR_MULTIVIEW_EXTENSION_NAME;
} }
if (!strcmp(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, device_extensions[i].extensionName)) { if (!strcmp(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, device_extensions[i].extensionName)) {
@ -1114,19 +1113,18 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
" extension.\n\nDo you have a compatible Vulkan installable client driver (ICD) installed?\n" " extension.\n\nDo you have a compatible Vulkan installable client driver (ICD) installed?\n"
"vkCreateInstance Failure"); "vkCreateInstance Failure");
/* Call with nullptr data to get count */ // Call with nullptr data to get count.
vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_family_count, nullptr); vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_family_count, nullptr);
ERR_FAIL_COND_V(queue_family_count == 0, ERR_CANT_CREATE); ERR_FAIL_COND_V(queue_family_count == 0, ERR_CANT_CREATE);
queue_props = (VkQueueFamilyProperties *)malloc(queue_family_count * sizeof(VkQueueFamilyProperties)); queue_props = (VkQueueFamilyProperties *)malloc(queue_family_count * sizeof(VkQueueFamilyProperties));
vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_family_count, queue_props); vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_family_count, queue_props);
// Query fine-grained feature support for this device. // Query fine-grained feature support for this device.
// If app has specific feature requirements it should check supported // If app has specific feature requirements it should check supported
// features based on this query // features based on this query
vkGetPhysicalDeviceFeatures(gpu, &physical_device_features); vkGetPhysicalDeviceFeatures(gpu, &physical_device_features);
physical_device_features.robustBufferAccess = false; //turn off robust buffer access, which can hamper performance on some hardware physical_device_features.robustBufferAccess = false; // Turn off robust buffer access, which can hamper performance on some hardware.
#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \ #define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \
{ \ { \
@ -1141,7 +1139,7 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
GET_INSTANCE_PROC_ADDR(inst, GetPhysicalDeviceSurfacePresentModesKHR); GET_INSTANCE_PROC_ADDR(inst, GetPhysicalDeviceSurfacePresentModesKHR);
GET_INSTANCE_PROC_ADDR(inst, GetSwapchainImagesKHR); GET_INSTANCE_PROC_ADDR(inst, GetSwapchainImagesKHR);
// get info about what our vulkan driver is capable off // Gets capability info for current Vulkan driver.
{ {
Error res = _check_capabilities(); Error res = _check_capabilities();
if (res != OK) { if (res != OK) {
@ -1191,7 +1189,7 @@ Error VulkanContext::_create_device() {
VkPhysicalDevice16BitStorageFeaturesKHR storage_feature; VkPhysicalDevice16BitStorageFeaturesKHR storage_feature;
VkPhysicalDeviceMultiviewFeatures multiview_features; VkPhysicalDeviceMultiviewFeatures multiview_features;
if (vulkan_major > 1 || vulkan_minor >= 2) { if (vulkan_major > 1 || vulkan_minor >= 2) {
// In Vulkan 1.2 and newer we use a newer struct to enable various features // In Vulkan 1.2 and newer we use a newer struct to enable various features.
vulkan11features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; vulkan11features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
vulkan11features.pNext = nextptr; vulkan11features.pNext = nextptr;
@ -1209,7 +1207,7 @@ Error VulkanContext::_create_device() {
vulkan11features.shaderDrawParameters = 0; vulkan11features.shaderDrawParameters = 0;
nextptr = &vulkan11features; nextptr = &vulkan11features;
} else { } else {
// On Vulkan 1.0 and 1.1 we use our older structs to initialise these features // On Vulkan 1.0 and 1.1 we use our older structs to initialise these features.
storage_feature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR; storage_feature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR;
storage_feature.pNext = nextptr; storage_feature.pNext = nextptr;
storage_feature.storageBuffer16BitAccess = storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported; storage_feature.storageBuffer16BitAccess = storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported;
@ -1238,7 +1236,7 @@ Error VulkanContext::_create_device() {
/*ppEnabledLayerNames*/ nullptr, /*ppEnabledLayerNames*/ nullptr,
/*enabledExtensionCount*/ enabled_extension_count, /*enabledExtensionCount*/ enabled_extension_count,
/*ppEnabledExtensionNames*/ (const char *const *)extension_names, /*ppEnabledExtensionNames*/ (const char *const *)extension_names,
/*pEnabledFeatures*/ &physical_device_features, // If specific features are required, pass them in here /*pEnabledFeatures*/ &physical_device_features, // If specific features are required, pass them in here.
}; };
if (separate_present_queue) { if (separate_present_queue) {
queues[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queues[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
@ -1270,7 +1268,7 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
} }
// Search for a graphics and a present queue in the array of queue // Search for a graphics and a present queue in the array of queue
// families, try to find one that supports both // families, try to find one that supports both.
uint32_t graphicsQueueFamilyIndex = UINT32_MAX; uint32_t graphicsQueueFamilyIndex = UINT32_MAX;
uint32_t presentQueueFamilyIndex = UINT32_MAX; uint32_t presentQueueFamilyIndex = UINT32_MAX;
for (uint32_t i = 0; i < queue_family_count; i++) { for (uint32_t i = 0; i < queue_family_count; i++) {
@ -1300,7 +1298,7 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
free(supportsPresent); free(supportsPresent);
// Generate error if could not find both a graphics and a present queue // Generate error if could not find both a graphics and a present queue.
ERR_FAIL_COND_V_MSG(graphicsQueueFamilyIndex == UINT32_MAX || presentQueueFamilyIndex == UINT32_MAX, ERR_CANT_CREATE, ERR_FAIL_COND_V_MSG(graphicsQueueFamilyIndex == UINT32_MAX || presentQueueFamilyIndex == UINT32_MAX, ERR_CANT_CREATE,
"Could not find both graphics and present queues\n"); "Could not find both graphics and present queues\n");
@ -1356,7 +1354,7 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
color_space = surfFormats[0].colorSpace; color_space = surfFormats[0].colorSpace;
} else { } else {
// These should be ordered with the ones we want to use on top and fallback modes further down // These should be ordered with the ones we want to use on top and fallback modes further down
// we want an 32bit RGBA unsigned normalised buffer or similar // we want a 32bit RGBA unsigned normalised buffer or similar.
const VkFormat allowed_formats[] = { const VkFormat allowed_formats[] = {
VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM,
VK_FORMAT_R8G8B8A8_UNORM VK_FORMAT_R8G8B8A8_UNORM
@ -1368,7 +1366,7 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "formatCount less than 1"); ERR_FAIL_V_MSG(ERR_CANT_CREATE, "formatCount less than 1");
} }
// Find the first format that we support // Find the first format that we support.
format = VK_FORMAT_UNDEFINED; format = VK_FORMAT_UNDEFINED;
for (uint32_t af = 0; af < allowed_formats_count && format == VK_FORMAT_UNDEFINED; af++) { for (uint32_t af = 0; af < allowed_formats_count && format == VK_FORMAT_UNDEFINED; af++) {
for (uint32_t sf = 0; sf < formatCount && format == VK_FORMAT_UNDEFINED; sf++) { for (uint32_t sf = 0; sf < formatCount && format == VK_FORMAT_UNDEFINED; sf++) {
@ -1400,7 +1398,7 @@ Error VulkanContext::_create_semaphores() {
VkResult err; VkResult err;
// Create semaphores to synchronize acquiring presentable buffers before // Create semaphores to synchronize acquiring presentable buffers before
// rendering and waiting for drawing to be complete before presenting // rendering and waiting for drawing to be complete before presenting.
VkSemaphoreCreateInfo semaphoreCreateInfo = { VkSemaphoreCreateInfo semaphoreCreateInfo = {
/*sType*/ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, /*sType*/ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
/*pNext*/ nullptr, /*pNext*/ nullptr,
@ -1408,7 +1406,7 @@ Error VulkanContext::_create_semaphores() {
}; };
// Create fences that we can use to throttle if we get too far // Create fences that we can use to throttle if we get too far
// ahead of the image presents // ahead of the image presents.
VkFenceCreateInfo fence_ci = { VkFenceCreateInfo fence_ci = {
/*sType*/ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, /*sType*/ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
/*pNext*/ nullptr, /*pNext*/ nullptr,
@ -1428,7 +1426,7 @@ Error VulkanContext::_create_semaphores() {
} }
frame_index = 0; frame_index = 0;
// Get Memory information and properties // Get Memory information and properties.
vkGetPhysicalDeviceMemoryProperties(gpu, &memory_properties); vkGetPhysicalDeviceMemoryProperties(gpu, &memory_properties);
return OK; return OK;
@ -1503,7 +1501,7 @@ bool VulkanContext::window_is_valid_swapchain(DisplayServer::WindowID p_window)
VkRenderPass VulkanContext::window_get_render_pass(DisplayServer::WindowID p_window) { VkRenderPass VulkanContext::window_get_render_pass(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE); ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE);
Window *w = &windows[p_window]; Window *w = &windows[p_window];
//vulkan use of currentbuffer // Vulkan use of currentbuffer.
return w->render_pass; return w->render_pass;
} }
@ -1511,7 +1509,7 @@ VkFramebuffer VulkanContext::window_get_framebuffer(DisplayServer::WindowID p_wi
ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE); ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE);
ERR_FAIL_COND_V(!buffers_prepared, VK_NULL_HANDLE); ERR_FAIL_COND_V(!buffers_prepared, VK_NULL_HANDLE);
Window *w = &windows[p_window]; Window *w = &windows[p_window];
//vulkan use of currentbuffer // Vulkan use of currentbuffer.
if (w->swapchain_image_resources != VK_NULL_HANDLE) { if (w->swapchain_image_resources != VK_NULL_HANDLE) {
return w->swapchain_image_resources[w->current_buffer].framebuffer; return w->swapchain_image_resources[w->current_buffer].framebuffer;
} else { } else {
@ -1536,7 +1534,7 @@ Error VulkanContext::_clean_up_swap_chain(Window *window) {
} }
vkDeviceWaitIdle(device); vkDeviceWaitIdle(device);
//this destroys images associated it seems // This destroys images associated it seems.
fpDestroySwapchainKHR(device, window->swapchain, nullptr); fpDestroySwapchainKHR(device, window->swapchain, nullptr);
window->swapchain = VK_NULL_HANDLE; window->swapchain = VK_NULL_HANDLE;
vkDestroyRenderPass(device, window->render_pass, nullptr); vkDestroyRenderPass(device, window->render_pass, nullptr);
@ -1562,7 +1560,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
_clean_up_swap_chain(window); _clean_up_swap_chain(window);
} }
// Check the surface capabilities and formats // Check the surface capabilities and formats.
VkSurfaceCapabilitiesKHR surfCapabilities; VkSurfaceCapabilitiesKHR surfCapabilities;
err = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu, window->surface, &surfCapabilities); err = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu, window->surface, &surfCapabilities);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE); ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
@ -1579,7 +1577,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
} }
VkExtent2D swapchainExtent; VkExtent2D swapchainExtent;
// width and height are either both 0xFFFFFFFF, or both not 0xFFFFFFFF. // Width and height are either both 0xFFFFFFFF, or both not 0xFFFFFFFF.
if (surfCapabilities.currentExtent.width == 0xFFFFFFFF) { if (surfCapabilities.currentExtent.width == 0xFFFFFFFF) {
// If the surface size is undefined, the size is set to the size // If the surface size is undefined, the size is set to the size
// of the images requested, which must fit within the minimum and // of the images requested, which must fit within the minimum and
@ -1599,7 +1597,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
swapchainExtent.height = surfCapabilities.maxImageExtent.height; swapchainExtent.height = surfCapabilities.maxImageExtent.height;
} }
} else { } else {
// If the surface size is defined, the swap chain size must match // If the surface size is defined, the swap chain size must match.
swapchainExtent = surfCapabilities.currentExtent; swapchainExtent = surfCapabilities.currentExtent;
window->width = surfCapabilities.currentExtent.width; window->width = surfCapabilities.currentExtent.width;
window->height = surfCapabilities.currentExtent.height; window->height = surfCapabilities.currentExtent.height;
@ -1607,7 +1605,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
if (window->width == 0 || window->height == 0) { if (window->width == 0 || window->height == 0) {
free(presentModes); free(presentModes);
//likely window minimized, no swapchain created // Likely window minimized, no swapchain created.
return OK; return OK;
} }
// The FIFO present mode is guaranteed by the spec to be supported // The FIFO present mode is guaranteed by the spec to be supported
@ -1669,7 +1667,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
window->presentMode = requested_present_mode; window->presentMode = requested_present_mode;
} else { } else {
WARN_PRINT("Requested VSync mode is not available!"); WARN_PRINT("Requested VSync mode is not available!");
window->vsync_mode = DisplayServer::VSYNC_ENABLED; //Set to default window->vsync_mode = DisplayServer::VSYNC_ENABLED; // Set to default.
} }
print_verbose("Using present mode: " + String(string_VkPresentModeKHR(window->presentMode))); print_verbose("Using present mode: " + String(string_VkPresentModeKHR(window->presentMode)));
@ -1678,13 +1676,13 @@ Error VulkanContext::_update_swap_chain(Window *window) {
// Determine the number of VkImages to use in the swap chain. // Determine the number of VkImages to use in the swap chain.
// Application desires to acquire 3 images at a time for triple // Application desires to acquire 3 images at a time for triple
// buffering // buffering.
uint32_t desiredNumOfSwapchainImages = 3; uint32_t desiredNumOfSwapchainImages = 3;
if (desiredNumOfSwapchainImages < surfCapabilities.minImageCount) { if (desiredNumOfSwapchainImages < surfCapabilities.minImageCount) {
desiredNumOfSwapchainImages = surfCapabilities.minImageCount; desiredNumOfSwapchainImages = surfCapabilities.minImageCount;
} }
// If maxImageCount is 0, we can ask for as many images as we want; // If maxImageCount is 0, we can ask for as many images as we want;
// otherwise we're limited to maxImageCount // otherwise we're limited to maxImageCount.
if ((surfCapabilities.maxImageCount > 0) && (desiredNumOfSwapchainImages > surfCapabilities.maxImageCount)) { if ((surfCapabilities.maxImageCount > 0) && (desiredNumOfSwapchainImages > surfCapabilities.maxImageCount)) {
// Application must settle for fewer images than desired: // Application must settle for fewer images than desired:
desiredNumOfSwapchainImages = surfCapabilities.maxImageCount; desiredNumOfSwapchainImages = surfCapabilities.maxImageCount;
@ -1697,7 +1695,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
preTransform = surfCapabilities.currentTransform; preTransform = surfCapabilities.currentTransform;
} }
// Find a supported composite alpha mode - one of these is guaranteed to be set // Find a supported composite alpha mode - one of these is guaranteed to be set.
VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
VkCompositeAlphaFlagBitsKHR compositeAlphaFlags[4] = { VkCompositeAlphaFlagBitsKHR compositeAlphaFlags[4] = {
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
@ -1744,7 +1742,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
ERR_FAIL_COND_V(err, ERR_CANT_CREATE); ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
if (swapchainImageCount == 0) { if (swapchainImageCount == 0) {
//assign here for the first time. // Assign here for the first time.
swapchainImageCount = sp_image_count; swapchainImageCount = sp_image_count;
} else { } else {
ERR_FAIL_COND_V(swapchainImageCount != sp_image_count, ERR_BUG); ERR_FAIL_COND_V(swapchainImageCount != sp_image_count, ERR_BUG);
@ -1928,7 +1926,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
} }
} }
//reset current buffer // Reset current buffer.
window->current_buffer = 0; window->current_buffer = 0;
return OK; return OK;
@ -1963,16 +1961,16 @@ void VulkanContext::append_command_buffer(VkCommandBuffer p_command_buffer) {
} }
void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) { void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) {
// ensure everything else pending is executed // Ensure everything else pending is executed.
vkDeviceWaitIdle(device); vkDeviceWaitIdle(device);
//flush the pending setup buffer // Flush the pending setup buffer.
bool setup_flushable = p_flush_setup && command_buffer_queue[0]; bool setup_flushable = p_flush_setup && command_buffer_queue[0];
bool pending_flushable = p_flush_pending && command_buffer_count > 1; bool pending_flushable = p_flush_pending && command_buffer_count > 1;
if (setup_flushable) { if (setup_flushable) {
//use a fence to wait for everything done // Use a fence to wait for everything done.
VkSubmitInfo submit_info; VkSubmitInfo submit_info;
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submit_info.pNext = nullptr; submit_info.pNext = nullptr;
@ -1989,7 +1987,7 @@ void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) {
} }
if (pending_flushable) { if (pending_flushable) {
//use a fence to wait for everything done // Use a fence to wait for everything to finish.
VkSubmitInfo submit_info; VkSubmitInfo submit_info;
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
@ -2017,7 +2015,7 @@ Error VulkanContext::prepare_buffers() {
VkResult err; VkResult err;
// Ensure no more than FRAME_LAG renderings are outstanding // Ensure no more than FRAME_LAG renderings are outstanding.
vkWaitForFences(device, 1, &fences[frame_index], VK_TRUE, UINT64_MAX); vkWaitForFences(device, 1, &fences[frame_index], VK_TRUE, UINT64_MAX);
vkResetFences(device, 1, &fences[frame_index]); vkResetFences(device, 1, &fences[frame_index]);
@ -2037,13 +2035,13 @@ Error VulkanContext::prepare_buffers() {
w->image_acquired_semaphores[frame_index], VK_NULL_HANDLE, &w->current_buffer); w->image_acquired_semaphores[frame_index], VK_NULL_HANDLE, &w->current_buffer);
if (err == VK_ERROR_OUT_OF_DATE_KHR) { if (err == VK_ERROR_OUT_OF_DATE_KHR) {
// swapchain is out of date (e.g. the window was resized) and // Swapchain is out of date (e.g. the window was resized) and
// must be recreated: // must be recreated:
print_verbose("Vulkan: Early out of date swapchain, recreating."); print_verbose("Vulkan: Early out of date swapchain, recreating.");
//resize_notify(); // resize_notify();
_update_swap_chain(w); _update_swap_chain(w);
} else if (err == VK_SUBOPTIMAL_KHR) { } else if (err == VK_SUBOPTIMAL_KHR) {
// swapchain is not as optimal as it could be, but the platform's // Swapchain is not as optimal as it could be, but the platform's
// presentation engine will still present the image correctly. // presentation engine will still present the image correctly.
print_verbose("Vulkan: Early suboptimal swapchain."); print_verbose("Vulkan: Early suboptimal swapchain.");
break; break;
@ -2090,7 +2088,7 @@ Error VulkanContext::swap_buffers() {
uint32_t commands_to_submit = 0; uint32_t commands_to_submit = 0;
if (command_buffer_queue[0] == nullptr) { if (command_buffer_queue[0] == nullptr) {
//no setup command, but commands to submit, submit from the first and skip command // No setup command, but commands to submit, submit from the first and skip command.
if (command_buffer_count > 1) { if (command_buffer_count > 1) {
commands_ptr = command_buffer_queue.ptr() + 1; commands_ptr = command_buffer_queue.ptr() + 1;
commands_to_submit = command_buffer_count - 1; commands_to_submit = command_buffer_count - 1;
@ -2133,7 +2131,7 @@ Error VulkanContext::swap_buffers() {
if (separate_present_queue) { if (separate_present_queue) {
// If we are using separate queues, change image ownership to the // If we are using separate queues, change image ownership to the
// present queue before presenting, waiting for the draw complete // present queue before presenting, waiting for the draw complete
// semaphore and signalling the ownership released semaphore when finished // semaphore and signalling the ownership released semaphore when finished.
VkFence nullFence = VK_NULL_HANDLE; VkFence nullFence = VK_NULL_HANDLE;
pipe_stage_flags[0] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; pipe_stage_flags[0] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
submit_info.waitSemaphoreCount = 1; submit_info.waitSemaphoreCount = 1;
@ -2160,7 +2158,7 @@ Error VulkanContext::swap_buffers() {
} }
// If we are using separate queues, we have to wait for image ownership, // If we are using separate queues, we have to wait for image ownership,
// otherwise wait for draw complete // otherwise wait for draw complete.
VkPresentInfoKHR present = { VkPresentInfoKHR present = {
/*sType*/ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, /*sType*/ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
/*pNext*/ nullptr, /*pNext*/ nullptr,
@ -2265,12 +2263,12 @@ Error VulkanContext::swap_buffers() {
frame_index %= FRAME_LAG; frame_index %= FRAME_LAG;
if (err == VK_ERROR_OUT_OF_DATE_KHR) { if (err == VK_ERROR_OUT_OF_DATE_KHR) {
// swapchain is out of date (e.g. the window was resized) and // Swapchain is out of date (e.g. the window was resized) and
// must be recreated: // must be recreated:
print_verbose("Vulkan: Swapchain is out of date, recreating."); print_verbose("Vulkan: Swapchain is out of date, recreating.");
resize_notify(); resize_notify();
} else if (err == VK_SUBOPTIMAL_KHR) { } else if (err == VK_SUBOPTIMAL_KHR) {
// swapchain is not as optimal as it could be, but the platform's // Swapchain is not as optimal as it could be, but the platform's
// presentation engine will still present the image correctly. // presentation engine will still present the image correctly.
print_verbose("Vulkan: Swapchain is suboptimal."); print_verbose("Vulkan: Swapchain is suboptimal.");
} else { } else {
@ -2315,7 +2313,7 @@ VkPhysicalDeviceLimits VulkanContext::get_device_limits() const {
RID VulkanContext::local_device_create() { RID VulkanContext::local_device_create() {
LocalDevice ld; LocalDevice ld;
{ //create device { // Create device.
VkResult err; VkResult err;
float queue_priorities[1] = { 0.0 }; float queue_priorities[1] = { 0.0 };
VkDeviceQueueCreateInfo queues[2]; VkDeviceQueueCreateInfo queues[2];
@ -2336,13 +2334,13 @@ RID VulkanContext::local_device_create() {
/*ppEnabledLayerNames */ nullptr, /*ppEnabledLayerNames */ nullptr,
/*enabledExtensionCount */ enabled_extension_count, /*enabledExtensionCount */ enabled_extension_count,
/*ppEnabledExtensionNames */ (const char *const *)extension_names, /*ppEnabledExtensionNames */ (const char *const *)extension_names,
/*pEnabledFeatures */ &physical_device_features, // If specific features are required, pass them in here /*pEnabledFeatures */ &physical_device_features, // If specific features are required, pass them in here.
}; };
err = vkCreateDevice(gpu, &sdevice, nullptr, &ld.device); err = vkCreateDevice(gpu, &sdevice, nullptr, &ld.device);
ERR_FAIL_COND_V(err, RID()); ERR_FAIL_COND_V(err, RID());
} }
{ //create graphics queue { // Create graphics queue.
vkGetDeviceQueue(ld.device, graphics_queue_family_index, 0, &ld.queue); vkGetDeviceQueue(ld.device, graphics_queue_family_index, 0, &ld.queue);
} }