Fixed static initialization of VulkanFunctions

This commit is contained in:
Charles Giessen 2020-09-26 12:15:40 -06:00
parent 812ce2cf0a
commit 6657593fa3

View File

@ -194,7 +194,10 @@ class VulkanFunctions {
} }
}; };
VulkanFunctions vk_functions; VulkanFunctions& vulkan_functions () {
static VulkanFunctions v;
return v;
}
// Helper for robustly executing the two-call pattern // Helper for robustly executing the two-call pattern
template <typename T, typename F, typename... Ts> template <typename T, typename F, typename... Ts>
@ -266,7 +269,7 @@ VkResult create_debug_utils_messenger (VkInstance instance,
messengerCreateInfo.pfnUserCallback = debug_callback; messengerCreateInfo.pfnUserCallback = debug_callback;
PFN_vkCreateDebugUtilsMessengerEXT createMessengerFunc; PFN_vkCreateDebugUtilsMessengerEXT createMessengerFunc;
detail::vk_functions.get_inst_proc_addr (createMessengerFunc, "vkCreateDebugUtilsMessengerEXT"); detail::vulkan_functions ().get_inst_proc_addr (createMessengerFunc, "vkCreateDebugUtilsMessengerEXT");
if (createMessengerFunc != nullptr) { if (createMessengerFunc != nullptr) {
return createMessengerFunc (instance, &messengerCreateInfo, allocation_callbacks, pDebugMessenger); return createMessengerFunc (instance, &messengerCreateInfo, allocation_callbacks, pDebugMessenger);
@ -279,7 +282,7 @@ void destroy_debug_utils_messenger (
VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, VkAllocationCallbacks* allocation_callbacks) { VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, VkAllocationCallbacks* allocation_callbacks) {
PFN_vkDestroyDebugUtilsMessengerEXT deleteMessengerFunc; PFN_vkDestroyDebugUtilsMessengerEXT deleteMessengerFunc;
detail::vk_functions.get_inst_proc_addr (deleteMessengerFunc, "vkDestroyDebugUtilsMessengerEXT"); detail::vulkan_functions ().get_inst_proc_addr (deleteMessengerFunc, "vkDestroyDebugUtilsMessengerEXT");
if (deleteMessengerFunc != nullptr) { if (deleteMessengerFunc != nullptr) {
deleteMessengerFunc (instance, debugMessenger, allocation_callbacks); deleteMessengerFunc (instance, debugMessenger, allocation_callbacks);
@ -490,7 +493,7 @@ const char* to_string (SwapchainError err) {
} }
detail::Result<SystemInfo> SystemInfo::get_system_info () { detail::Result<SystemInfo> SystemInfo::get_system_info () {
if (!detail::vk_functions.init_vulkan_funcs (nullptr)) { if (!detail::vulkan_functions ().init_vulkan_funcs (nullptr)) {
return make_error_code (InstanceError::vulkan_unavailable); return make_error_code (InstanceError::vulkan_unavailable);
} }
return SystemInfo (); return SystemInfo ();
@ -498,13 +501,13 @@ detail::Result<SystemInfo> SystemInfo::get_system_info () {
detail::Result<SystemInfo> SystemInfo::get_system_info (PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr) { detail::Result<SystemInfo> SystemInfo::get_system_info (PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr) {
// Using externally provided function pointers, assume the loader is available // Using externally provided function pointers, assume the loader is available
detail::vk_functions.init_vulkan_funcs (fp_vkGetInstanceProcAddr); detail::vulkan_functions ().init_vulkan_funcs (fp_vkGetInstanceProcAddr);
return SystemInfo (); return SystemInfo ();
} }
SystemInfo::SystemInfo () { SystemInfo::SystemInfo () {
auto available_layers_ret = detail::get_vector<VkLayerProperties> ( auto available_layers_ret = detail::get_vector<VkLayerProperties> (
this->available_layers, detail::vk_functions.fp_vkEnumerateInstanceLayerProperties); this->available_layers, detail::vulkan_functions ().fp_vkEnumerateInstanceLayerProperties);
if (available_layers_ret != VK_SUCCESS) { if (available_layers_ret != VK_SUCCESS) {
this->available_layers.clear (); this->available_layers.clear ();
} }
@ -513,8 +516,9 @@ SystemInfo::SystemInfo () {
if (strcmp (layer.layerName, detail::validation_layer_name) == 0) if (strcmp (layer.layerName, detail::validation_layer_name) == 0)
validation_layers_available = true; validation_layers_available = true;
auto available_extensions_ret = detail::get_vector<VkExtensionProperties> ( auto available_extensions_ret = detail::get_vector<VkExtensionProperties> (this->available_extensions,
this->available_extensions, detail::vk_functions.fp_vkEnumerateInstanceExtensionProperties, nullptr); detail::vulkan_functions ().fp_vkEnumerateInstanceExtensionProperties,
nullptr);
if (available_extensions_ret != VK_SUCCESS) { if (available_extensions_ret != VK_SUCCESS) {
this->available_extensions.clear (); this->available_extensions.clear ();
} }
@ -525,8 +529,9 @@ SystemInfo::SystemInfo () {
for (auto& layer : this->available_layers) { for (auto& layer : this->available_layers) {
std::vector<VkExtensionProperties> layer_extensions; std::vector<VkExtensionProperties> layer_extensions;
auto layer_extensions_ret = detail::get_vector<VkExtensionProperties> ( auto layer_extensions_ret = detail::get_vector<VkExtensionProperties> (layer_extensions,
layer_extensions, detail::vk_functions.fp_vkEnumerateInstanceExtensionProperties, layer.layerName); detail::vulkan_functions ().fp_vkEnumerateInstanceExtensionProperties,
layer.layerName);
if (layer_extensions_ret != VK_SUCCESS) { if (layer_extensions_ret != VK_SUCCESS) {
for (auto& ext : layer_extensions) for (auto& ext : layer_extensions)
if (strcmp (ext.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0) if (strcmp (ext.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0)
@ -547,7 +552,7 @@ void destroy_instance (Instance instance) {
if (instance.instance != VK_NULL_HANDLE) { if (instance.instance != VK_NULL_HANDLE) {
if (instance.debug_messenger != nullptr) if (instance.debug_messenger != nullptr)
destroy_debug_utils_messenger (instance.instance, instance.debug_messenger, instance.allocation_callbacks); destroy_debug_utils_messenger (instance.instance, instance.debug_messenger, instance.allocation_callbacks);
detail::vk_functions.fp_vkDestroyInstance (instance.instance, instance.allocation_callbacks); detail::vulkan_functions ().fp_vkDestroyInstance (instance.instance, instance.allocation_callbacks);
} }
} }
@ -567,7 +572,7 @@ detail::Result<Instance> InstanceBuilder::build () const {
if (info.required_api_version > VK_MAKE_VERSION (1, 0, 0) || if (info.required_api_version > VK_MAKE_VERSION (1, 0, 0) ||
info.desired_api_version > VK_MAKE_VERSION (1, 0, 0)) { info.desired_api_version > VK_MAKE_VERSION (1, 0, 0)) {
PFN_vkEnumerateInstanceVersion pfn_vkEnumerateInstanceVersion = PFN_vkEnumerateInstanceVersion pfn_vkEnumerateInstanceVersion =
detail::vk_functions.fp_vkEnumerateInstanceVersion; detail::vulkan_functions ().fp_vkEnumerateInstanceVersion;
uint32_t queried_api_version = VK_MAKE_VERSION (1, 0, 0); uint32_t queried_api_version = VK_MAKE_VERSION (1, 0, 0);
if (pfn_vkEnumerateInstanceVersion != nullptr) { if (pfn_vkEnumerateInstanceVersion != nullptr) {
@ -697,12 +702,12 @@ detail::Result<Instance> InstanceBuilder::build () const {
instance_create_info.ppEnabledLayerNames = layers.data (); instance_create_info.ppEnabledLayerNames = layers.data ();
Instance instance; Instance instance;
VkResult res = detail::vk_functions.fp_vkCreateInstance ( VkResult res = detail::vulkan_functions ().fp_vkCreateInstance (
&instance_create_info, info.allocation_callbacks, &instance.instance); &instance_create_info, info.allocation_callbacks, &instance.instance);
if (res != VK_SUCCESS) if (res != VK_SUCCESS)
return detail::Result<Instance> (InstanceError::failed_create_instance, res); return detail::Result<Instance> (InstanceError::failed_create_instance, res);
detail::vk_functions.init_instance_funcs (instance.instance); detail::vulkan_functions ().init_instance_funcs (instance.instance);
if (info.use_debug_messenger) { if (info.use_debug_messenger) {
res = create_debug_utils_messenger (instance.instance, res = create_debug_utils_messenger (instance.instance,
@ -721,7 +726,7 @@ detail::Result<Instance> InstanceBuilder::build () const {
} }
instance.allocation_callbacks = info.allocation_callbacks; instance.allocation_callbacks = info.allocation_callbacks;
instance.instance_version = api_version; instance.instance_version = api_version;
instance.fp_vkGetInstanceProcAddr = detail::vk_functions.ptr_vkGetInstanceProcAddr; instance.fp_vkGetInstanceProcAddr = detail::vulkan_functions ().ptr_vkGetInstanceProcAddr;
return instance; return instance;
} }
@ -824,7 +829,7 @@ std::vector<const char*> check_device_extension_support (
VkPhysicalDevice device, std::vector<const char*> desired_extensions) { VkPhysicalDevice device, std::vector<const char*> desired_extensions) {
std::vector<VkExtensionProperties> available_extensions; std::vector<VkExtensionProperties> available_extensions;
auto available_extensions_ret = detail::get_vector<VkExtensionProperties> ( auto available_extensions_ret = detail::get_vector<VkExtensionProperties> (
available_extensions, detail::vk_functions.fp_vkEnumerateDeviceExtensionProperties, device, nullptr); available_extensions, detail::vulkan_functions ().fp_vkEnumerateDeviceExtensionProperties, device, nullptr);
if (available_extensions_ret != VK_SUCCESS) return {}; if (available_extensions_ret != VK_SUCCESS) return {};
std::vector<const char*> extensions_to_enable; std::vector<const char*> extensions_to_enable;
@ -966,7 +971,7 @@ int get_present_queue_index (VkPhysicalDevice const phys_device,
for (size_t i = 0; i < families.size (); i++) { for (size_t i = 0; i < families.size (); i++) {
VkBool32 presentSupport = false; VkBool32 presentSupport = false;
if (surface != VK_NULL_HANDLE) { if (surface != VK_NULL_HANDLE) {
VkResult res = detail::vk_functions.fp_vkGetPhysicalDeviceSurfaceSupportKHR ( VkResult res = detail::vulkan_functions ().fp_vkGetPhysicalDeviceSurfaceSupportKHR (
phys_device, static_cast<uint32_t> (i), surface, &presentSupport); phys_device, static_cast<uint32_t> (i), surface, &presentSupport);
if (res != VK_SUCCESS) return -1; // TODO: determine if this should fail another way if (res != VK_SUCCESS) return -1; // TODO: determine if this should fail another way
} }
@ -982,12 +987,12 @@ PhysicalDeviceSelector::PhysicalDeviceDesc PhysicalDeviceSelector::populate_devi
PhysicalDeviceSelector::PhysicalDeviceDesc desc{}; PhysicalDeviceSelector::PhysicalDeviceDesc desc{};
desc.phys_device = phys_device; desc.phys_device = phys_device;
auto queue_families = detail::get_vector_noerror<VkQueueFamilyProperties> ( auto queue_families = detail::get_vector_noerror<VkQueueFamilyProperties> (
detail::vk_functions.fp_vkGetPhysicalDeviceQueueFamilyProperties, phys_device); detail::vulkan_functions ().fp_vkGetPhysicalDeviceQueueFamilyProperties, phys_device);
desc.queue_families = queue_families; desc.queue_families = queue_families;
detail::vk_functions.fp_vkGetPhysicalDeviceProperties (phys_device, &desc.device_properties); detail::vulkan_functions ().fp_vkGetPhysicalDeviceProperties (phys_device, &desc.device_properties);
detail::vk_functions.fp_vkGetPhysicalDeviceFeatures (phys_device, &desc.device_features); detail::vulkan_functions ().fp_vkGetPhysicalDeviceFeatures (phys_device, &desc.device_features);
detail::vk_functions.fp_vkGetPhysicalDeviceMemoryProperties (phys_device, &desc.mem_properties); detail::vulkan_functions ().fp_vkGetPhysicalDeviceMemoryProperties (phys_device, &desc.mem_properties);
return desc; return desc;
} }
@ -1031,11 +1036,11 @@ PhysicalDeviceSelector::Suitable PhysicalDeviceSelector::is_device_suitable (Phy
std::vector<VkPresentModeKHR> present_modes; std::vector<VkPresentModeKHR> present_modes;
auto formats_ret = detail::get_vector<VkSurfaceFormatKHR> (formats, auto formats_ret = detail::get_vector<VkSurfaceFormatKHR> (formats,
detail::vk_functions.fp_vkGetPhysicalDeviceSurfaceFormatsKHR, detail::vulkan_functions ().fp_vkGetPhysicalDeviceSurfaceFormatsKHR,
pd.phys_device, pd.phys_device,
system_info.surface); system_info.surface);
auto present_modes_ret = detail::get_vector<VkPresentModeKHR> (present_modes, auto present_modes_ret = detail::get_vector<VkPresentModeKHR> (present_modes,
detail::vk_functions.fp_vkGetPhysicalDeviceSurfacePresentModesKHR, detail::vulkan_functions ().fp_vkGetPhysicalDeviceSurfacePresentModesKHR,
pd.phys_device, pd.phys_device,
system_info.surface); system_info.surface);
@ -1092,7 +1097,7 @@ detail::Result<PhysicalDevice> PhysicalDeviceSelector::select () const {
std::vector<VkPhysicalDevice> physical_devices; std::vector<VkPhysicalDevice> physical_devices;
auto physical_devices_ret = detail::get_vector<VkPhysicalDevice> ( auto physical_devices_ret = detail::get_vector<VkPhysicalDevice> (
physical_devices, detail::vk_functions.fp_vkEnumeratePhysicalDevices, system_info.instance); physical_devices, detail::vulkan_functions ().fp_vkEnumeratePhysicalDevices, system_info.instance);
if (physical_devices_ret != VK_SUCCESS) { if (physical_devices_ret != VK_SUCCESS) {
return detail::Result<PhysicalDevice>{ PhysicalDeviceError::failed_enumerate_physical_devices, return detail::Result<PhysicalDevice>{ PhysicalDeviceError::failed_enumerate_physical_devices,
physical_devices_ret }; physical_devices_ret };
@ -1286,7 +1291,7 @@ detail::Result<uint32_t> Device::get_dedicated_queue_index (QueueType type) cons
namespace detail { namespace detail {
VkQueue get_queue (VkDevice device, uint32_t family) { VkQueue get_queue (VkDevice device, uint32_t family) {
VkQueue out_queue; VkQueue out_queue;
detail::vk_functions.fp_vkGetDeviceQueue (device, family, 0, &out_queue); detail::vulkan_functions ().fp_vkGetDeviceQueue (device, family, 0, &out_queue);
return out_queue; return out_queue;
} }
} // namespace detail } // namespace detail
@ -1309,7 +1314,7 @@ CustomQueueDescription::CustomQueueDescription (uint32_t index, uint32_t count,
} }
void destroy_device (Device device) { void destroy_device (Device device) {
detail::vk_functions.fp_vkDestroyDevice (device.device, device.allocation_callbacks); detail::vulkan_functions ().fp_vkDestroyDevice (device.device, device.allocation_callbacks);
} }
DeviceBuilder::DeviceBuilder (PhysicalDevice phys_device) { DeviceBuilder::DeviceBuilder (PhysicalDevice phys_device) {
@ -1368,7 +1373,7 @@ detail::Result<Device> DeviceBuilder::build () const {
} }
Device device; Device device;
VkResult res = detail::vk_functions.fp_vkCreateDevice (info.physical_device.physical_device, VkResult res = detail::vulkan_functions ().fp_vkCreateDevice (info.physical_device.physical_device,
&device_create_info, &device_create_info,
info.allocation_callbacks, info.allocation_callbacks,
&device.device); &device.device);
@ -1434,7 +1439,7 @@ Result<SurfaceSupportDetails> query_surface_support_details (VkPhysicalDevice ph
return make_error_code (SurfaceSupportError::surface_handle_null); return make_error_code (SurfaceSupportError::surface_handle_null);
VkSurfaceCapabilitiesKHR capabilities; VkSurfaceCapabilitiesKHR capabilities;
VkResult res = detail::vk_functions.fp_vkGetPhysicalDeviceSurfaceCapabilitiesKHR ( VkResult res = detail::vulkan_functions ().fp_vkGetPhysicalDeviceSurfaceCapabilitiesKHR (
phys_device, surface, &capabilities); phys_device, surface, &capabilities);
if (res != VK_SUCCESS) { if (res != VK_SUCCESS) {
return { make_error_code (SurfaceSupportError::failed_get_surface_capabilities), res }; return { make_error_code (SurfaceSupportError::failed_get_surface_capabilities), res };
@ -1444,11 +1449,11 @@ Result<SurfaceSupportDetails> query_surface_support_details (VkPhysicalDevice ph
std::vector<VkPresentModeKHR> present_modes; std::vector<VkPresentModeKHR> present_modes;
auto formats_ret = detail::get_vector<VkSurfaceFormatKHR> ( auto formats_ret = detail::get_vector<VkSurfaceFormatKHR> (
formats, detail::vk_functions.fp_vkGetPhysicalDeviceSurfaceFormatsKHR, phys_device, surface); formats, detail::vulkan_functions ().fp_vkGetPhysicalDeviceSurfaceFormatsKHR, phys_device, surface);
if (formats_ret != VK_SUCCESS) if (formats_ret != VK_SUCCESS)
return { make_error_code (SurfaceSupportError::failed_enumerate_surface_formats), formats_ret }; return { make_error_code (SurfaceSupportError::failed_enumerate_surface_formats), formats_ret };
auto present_modes_ret = detail::get_vector<VkPresentModeKHR> ( auto present_modes_ret = detail::get_vector<VkPresentModeKHR> (
present_modes, detail::vk_functions.fp_vkGetPhysicalDeviceSurfacePresentModesKHR, phys_device, surface); present_modes, detail::vulkan_functions ().fp_vkGetPhysicalDeviceSurfacePresentModesKHR, phys_device, surface);
if (present_modes_ret != VK_SUCCESS) if (present_modes_ret != VK_SUCCESS)
return { make_error_code (SurfaceSupportError::failed_enumerate_present_modes), present_modes_ret }; return { make_error_code (SurfaceSupportError::failed_enumerate_present_modes), present_modes_ret };
@ -1505,7 +1510,7 @@ VkExtent2D find_extent (
void destroy_swapchain (Swapchain const& swapchain) { void destroy_swapchain (Swapchain const& swapchain) {
if (swapchain.device != VK_NULL_HANDLE && swapchain.swapchain != VK_NULL_HANDLE) { if (swapchain.device != VK_NULL_HANDLE && swapchain.swapchain != VK_NULL_HANDLE) {
detail::vk_functions.fp_vkDestroySwapchainKHR ( detail::vulkan_functions ().fp_vkDestroySwapchainKHR (
swapchain.device, swapchain.swapchain, swapchain.allocation_callbacks); swapchain.device, swapchain.swapchain, swapchain.allocation_callbacks);
} }
} }
@ -1599,7 +1604,7 @@ detail::Result<Swapchain> SwapchainBuilder::build () const {
swapchain_create_info.clipped = info.clipped; swapchain_create_info.clipped = info.clipped;
swapchain_create_info.oldSwapchain = info.old_swapchain; swapchain_create_info.oldSwapchain = info.old_swapchain;
Swapchain swapchain{}; Swapchain swapchain{};
VkResult res = detail::vk_functions.fp_vkCreateSwapchainKHR ( VkResult res = detail::vulkan_functions ().fp_vkCreateSwapchainKHR (
info.device, &swapchain_create_info, info.allocation_callbacks, &swapchain.swapchain); info.device, &swapchain_create_info, info.allocation_callbacks, &swapchain.swapchain);
if (res != VK_SUCCESS) { if (res != VK_SUCCESS) {
return detail::Error{ SwapchainError::failed_create_swapchain, res }; return detail::Error{ SwapchainError::failed_create_swapchain, res };
@ -1619,7 +1624,7 @@ detail::Result<std::vector<VkImage>> Swapchain::get_images () {
std::vector<VkImage> swapchain_images; std::vector<VkImage> swapchain_images;
auto swapchain_images_ret = detail::get_vector<VkImage> ( auto swapchain_images_ret = detail::get_vector<VkImage> (
swapchain_images, detail::vk_functions.fp_vkGetSwapchainImagesKHR, device, swapchain); swapchain_images, detail::vulkan_functions ().fp_vkGetSwapchainImagesKHR, device, swapchain);
if (swapchain_images_ret != VK_SUCCESS) { if (swapchain_images_ret != VK_SUCCESS) {
return detail::Error{ SwapchainError::failed_get_swapchain_images, swapchain_images_ret }; return detail::Error{ SwapchainError::failed_get_swapchain_images, swapchain_images_ret };
} }
@ -1649,7 +1654,7 @@ detail::Result<std::vector<VkImageView>> Swapchain::get_image_views () {
createInfo.subresourceRange.baseArrayLayer = 0; createInfo.subresourceRange.baseArrayLayer = 0;
createInfo.subresourceRange.layerCount = 1; createInfo.subresourceRange.layerCount = 1;
VkResult res = detail::vk_functions.fp_vkCreateImageView ( VkResult res = detail::vulkan_functions ().fp_vkCreateImageView (
device, &createInfo, allocation_callbacks, &views[i]); device, &createInfo, allocation_callbacks, &views[i]);
if (res != VK_SUCCESS) if (res != VK_SUCCESS)
return detail::Error{ SwapchainError::failed_create_swapchain_image_views, res }; return detail::Error{ SwapchainError::failed_create_swapchain_image_views, res };
@ -1658,7 +1663,7 @@ detail::Result<std::vector<VkImageView>> Swapchain::get_image_views () {
} }
void Swapchain::destroy_image_views (std::vector<VkImageView> const& image_views) { void Swapchain::destroy_image_views (std::vector<VkImageView> const& image_views) {
for (auto& image_view : image_views) { for (auto& image_view : image_views) {
detail::vk_functions.fp_vkDestroyImageView (device, image_view, allocation_callbacks); detail::vulkan_functions ().fp_vkDestroyImageView (device, image_view, allocation_callbacks);
} }
} }
SwapchainBuilder& SwapchainBuilder::set_old_swapchain (VkSwapchainKHR old_swapchain) { SwapchainBuilder& SwapchainBuilder::set_old_swapchain (VkSwapchainKHR old_swapchain) {