Added allocation callbacks

This commit is contained in:
Charles Giessen 2020-03-07 15:33:17 -07:00
parent d29d8d0daf
commit 8a18c5a7ba
2 changed files with 56 additions and 18 deletions

View File

@ -66,7 +66,8 @@ VkResult create_debug_utils_messenger (VkInstance instance,
PFN_vkDebugUtilsMessengerCallbackEXT debug_callback, PFN_vkDebugUtilsMessengerCallbackEXT debug_callback,
VkDebugUtilsMessageSeverityFlagsEXT severity, VkDebugUtilsMessageSeverityFlagsEXT severity,
VkDebugUtilsMessageTypeFlagsEXT type, VkDebugUtilsMessageTypeFlagsEXT type,
VkDebugUtilsMessengerEXT* pDebugMessenger) { VkDebugUtilsMessengerEXT* pDebugMessenger,
VkAllocationCallbacks* allocation_callbacks) {
if (debug_callback == nullptr) debug_callback = default_debug_callback; if (debug_callback == nullptr) debug_callback = default_debug_callback;
VkDebugUtilsMessengerCreateInfoEXT messengerCreateInfo = {}; VkDebugUtilsMessengerCreateInfoEXT messengerCreateInfo = {};
messengerCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; messengerCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
@ -79,17 +80,19 @@ VkResult create_debug_utils_messenger (VkInstance instance,
auto vkCreateDebugUtilsMessengerEXT_func = reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT> ( auto vkCreateDebugUtilsMessengerEXT_func = reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT> (
vkGetInstanceProcAddr (instance, "vkCreateDebugUtilsMessengerEXT")); vkGetInstanceProcAddr (instance, "vkCreateDebugUtilsMessengerEXT"));
if (vkCreateDebugUtilsMessengerEXT_func != nullptr) { if (vkCreateDebugUtilsMessengerEXT_func != nullptr) {
return vkCreateDebugUtilsMessengerEXT_func (instance, &messengerCreateInfo, nullptr, pDebugMessenger); return vkCreateDebugUtilsMessengerEXT_func (
instance, &messengerCreateInfo, allocation_callbacks, pDebugMessenger);
} else { } else {
return VK_ERROR_EXTENSION_NOT_PRESENT; return VK_ERROR_EXTENSION_NOT_PRESENT;
} }
} }
void destroy_debug_utils_messenger (VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger) { void destroy_debug_utils_messenger (
VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, VkAllocationCallbacks* allocation_callbacks) {
auto vkDestroyDebugUtilsMessengerEXT_func = reinterpret_cast<PFN_vkDestroyDebugUtilsMessengerEXT> ( auto vkDestroyDebugUtilsMessengerEXT_func = reinterpret_cast<PFN_vkDestroyDebugUtilsMessengerEXT> (
vkGetInstanceProcAddr (instance, "vkDestroyDebugUtilsMessengerEXT")); vkGetInstanceProcAddr (instance, "vkDestroyDebugUtilsMessengerEXT"));
if (vkDestroyDebugUtilsMessengerEXT_func != nullptr) { if (vkDestroyDebugUtilsMessengerEXT_func != nullptr) {
vkDestroyDebugUtilsMessengerEXT_func (instance, debugMessenger, nullptr); vkDestroyDebugUtilsMessengerEXT_func (instance, debugMessenger, allocation_callbacks);
} }
} }
@ -201,8 +204,8 @@ const char* to_string (InstanceError err) {
void destroy_instance (Instance instance) { 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); destroy_debug_utils_messenger (instance.instance, instance.debug_messenger, instance.allocation_callbacks);
vkDestroyInstance (instance.instance, nullptr); vkDestroyInstance (instance.instance, instance.allocation_callbacks);
} }
} }
@ -300,7 +303,7 @@ detail::Expected<Instance, detail::Error<InstanceError>> InstanceBuilder::build
instance_create_info.ppEnabledLayerNames = layers.data (); instance_create_info.ppEnabledLayerNames = layers.data ();
Instance instance; Instance instance;
VkResult res = vkCreateInstance (&instance_create_info, nullptr, &instance.instance); VkResult res = vkCreateInstance (&instance_create_info, info.allocation_callbacks, &instance.instance);
if (res != VK_SUCCESS) if (res != VK_SUCCESS)
return detail::Error<InstanceError>{ InstanceError::failed_create_instance, res }; return detail::Error<InstanceError>{ InstanceError::failed_create_instance, res };
@ -309,7 +312,8 @@ detail::Expected<Instance, detail::Error<InstanceError>> InstanceBuilder::build
info.debug_callback, info.debug_callback,
info.debug_message_severity, info.debug_message_severity,
info.debug_message_type, info.debug_message_type,
&instance.debug_messenger); &instance.debug_messenger,
info.allocation_callbacks);
if (res != VK_SUCCESS) { if (res != VK_SUCCESS) {
return detail::Error<InstanceError>{ InstanceError::failed_create_debug_messenger, res }; return detail::Error<InstanceError>{ InstanceError::failed_create_debug_messenger, res };
} }
@ -318,6 +322,7 @@ detail::Expected<Instance, detail::Error<InstanceError>> InstanceBuilder::build
if (info.headless_context) { if (info.headless_context) {
instance.headless = true; instance.headless = true;
} }
instance.allocation_callbacks = info.allocation_callbacks;
return instance; return instance;
} }
@ -405,6 +410,10 @@ InstanceBuilder& InstanceBuilder::add_validation_feature_disable (VkValidationFe
info.disabled_validation_features.push_back (disable); info.disabled_validation_features.push_back (disable);
return *this; return *this;
} }
InstanceBuilder& InstanceBuilder::set_allocation_callbacks (VkAllocationCallbacks* callbacks) {
info.allocation_callbacks = callbacks;
return *this;
}
// ---- Physical Device ---- // // ---- Physical Device ---- //
@ -846,7 +855,9 @@ const char* to_string (DeviceError err) {
} }
} }
void destroy_device (Device device) { vkDestroyDevice (device.device, nullptr); } void destroy_device (Device device) {
vkDestroyDevice (device.device, device.allocation_callbacks);
}
DeviceBuilder::DeviceBuilder (PhysicalDevice phys_device) { DeviceBuilder::DeviceBuilder (PhysicalDevice phys_device) {
info.physical_device = phys_device; info.physical_device = phys_device;
@ -927,14 +938,15 @@ detail::Expected<Device, detail::Error<DeviceError>> DeviceBuilder::build () {
device_create_info.pEnabledFeatures = &info.physical_device.features; device_create_info.pEnabledFeatures = &info.physical_device.features;
Device device; Device device;
VkResult res = VkResult res = vkCreateDevice (
vkCreateDevice (info.physical_device.phys_device, &device_create_info, nullptr, &device.device); info.physical_device.phys_device, &device_create_info, info.allocation_callbacks, &device.device);
if (res != VK_SUCCESS) { if (res != VK_SUCCESS) {
return detail::Error<DeviceError>{ DeviceError::failed_create_device, res }; return detail::Error<DeviceError>{ DeviceError::failed_create_device, res };
} }
device.physical_device = info.physical_device; device.physical_device = info.physical_device;
device.surface = info.physical_device.surface; device.surface = info.physical_device.surface;
device.queue_families = info.queue_families; device.queue_families = info.queue_families;
device.allocation_callbacks = info.allocation_callbacks;
return device; return device;
} }
DeviceBuilder& DeviceBuilder::request_dedicated_compute_queue (bool compute) { DeviceBuilder& DeviceBuilder::request_dedicated_compute_queue (bool compute) {
@ -961,6 +973,10 @@ template <typename T> DeviceBuilder& DeviceBuilder::add_pNext (T* structure) {
info.pNext_chain.push_back (reinterpret_cast<VkBaseOutStructure*> (structure)); info.pNext_chain.push_back (reinterpret_cast<VkBaseOutStructure*> (structure));
return *this; return *this;
} }
DeviceBuilder& DeviceBuilder::set_allocation_callbacks (VkAllocationCallbacks* callbacks) {
info.allocation_callbacks = callbacks;
return *this;
}
// ---- Queues ---- // // ---- Queues ---- //
@ -1203,16 +1219,17 @@ detail::Expected<Swapchain, detail::Error<SwapchainError>> SwapchainBuilder::bui
swapchain_create_info.clipped = VK_TRUE; swapchain_create_info.clipped = VK_TRUE;
swapchain_create_info.oldSwapchain = info.old_swapchain; swapchain_create_info.oldSwapchain = info.old_swapchain;
Swapchain swapchain{}; Swapchain swapchain{};
VkResult res = vkCreateSwapchainKHR (info.device, &swapchain_create_info, nullptr, &swapchain.swapchain); VkResult res = vkCreateSwapchainKHR (
info.device, &swapchain_create_info, info.allocation_callbacks, &swapchain.swapchain);
if (res != VK_SUCCESS) { if (res != VK_SUCCESS) {
return detail::Error<SwapchainError>{ SwapchainError::failed_create_swapchain, res }; return detail::Error<SwapchainError>{ SwapchainError::failed_create_swapchain, res };
} }
swapchain.device = info.device; swapchain.device = info.device;
swapchain.image_format = surface_format.format; swapchain.image_format = surface_format.format;
swapchain.extent = extent; swapchain.extent = extent;
auto images = get_swapchain_images (swapchain); auto images = get_swapchain_images (swapchain);
swapchain.image_count = images.value ().size (); swapchain.image_count = images.value ().size ();
swapchain.allocation_callbacks = info.allocation_callbacks;
return swapchain; return swapchain;
} // namespace vkb } // namespace vkb
detail::Expected<Swapchain, detail::Error<SwapchainError>> SwapchainBuilder::recreate (Swapchain const& swapchain) { detail::Expected<Swapchain, detail::Error<SwapchainError>> SwapchainBuilder::recreate (Swapchain const& swapchain) {
@ -1260,7 +1277,7 @@ get_swapchain_image_views (Swapchain const& swapchain, std::vector<VkImage> cons
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)
vkDestroySwapchainKHR (swapchain.device, swapchain.swapchain, nullptr); vkDestroySwapchainKHR (swapchain.device, swapchain.swapchain, swapchain.allocation_callbacks);
} }
SwapchainBuilder& SwapchainBuilder::set_desired_format (VkSurfaceFormatKHR format) { SwapchainBuilder& SwapchainBuilder::set_desired_format (VkSurfaceFormatKHR format) {
@ -1290,6 +1307,9 @@ SwapchainBuilder& SwapchainBuilder::use_default_present_mode_selection () {
info.desired_present_modes.push_back (VK_PRESENT_MODE_FIFO_KHR); info.desired_present_modes.push_back (VK_PRESENT_MODE_FIFO_KHR);
return *this; return *this;
} }
SwapchainBuilder& SwapchainBuilder::set_allocation_callbacks (VkAllocationCallbacks* callbacks) {
info.allocation_callbacks = callbacks;
return *this;
}
} // namespace vkb } // namespace vkb

View File

@ -123,6 +123,7 @@ class PhysicalDeviceSelector;
struct Instance { struct Instance {
VkInstance instance = VK_NULL_HANDLE; VkInstance instance = VK_NULL_HANDLE;
VkDebugUtilsMessengerEXT debug_messenger = VK_NULL_HANDLE; VkDebugUtilsMessengerEXT debug_messenger = VK_NULL_HANDLE;
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
private: private:
bool headless = false; bool headless = false;
@ -190,6 +191,9 @@ class InstanceBuilder {
// Options: All, shaders, thread safety, api parameters, object lifetimes, core checks, and unique handles. // Options: All, shaders, thread safety, api parameters, object lifetimes, core checks, and unique handles.
InstanceBuilder& add_validation_feature_disable (VkValidationFeatureDisableEXT disable); InstanceBuilder& add_validation_feature_disable (VkValidationFeatureDisableEXT disable);
// Provide custom allocation callbacks.
InstanceBuilder& set_allocation_callbacks (VkAllocationCallbacks* callbacks);
private: private:
struct InstanceInfo { struct InstanceInfo {
// VkApplicationInfo // VkApplicationInfo
@ -218,6 +222,9 @@ class InstanceBuilder {
std::vector<VkValidationFeatureEnableEXT> enabled_validation_features; std::vector<VkValidationFeatureEnableEXT> enabled_validation_features;
std::vector<VkValidationFeatureDisableEXT> disabled_validation_features; std::vector<VkValidationFeatureDisableEXT> disabled_validation_features;
// Custom allocator
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
bool enable_validation_layers = false; bool enable_validation_layers = false;
bool use_debug_messenger = false; bool use_debug_messenger = false;
bool headless_context = false; bool headless_context = false;
@ -233,9 +240,12 @@ VkResult create_debug_utils_messenger (VkInstance instance,
PFN_vkDebugUtilsMessengerCallbackEXT debug_callback, PFN_vkDebugUtilsMessengerCallbackEXT debug_callback,
VkDebugUtilsMessageSeverityFlagsEXT severity, VkDebugUtilsMessageSeverityFlagsEXT severity,
VkDebugUtilsMessageTypeFlagsEXT type, VkDebugUtilsMessageTypeFlagsEXT type,
VkDebugUtilsMessengerEXT* pDebugMessenger); VkDebugUtilsMessengerEXT* pDebugMessenger,
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE);
void destroy_debug_utils_messenger (VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger); void destroy_debug_utils_messenger (VkInstance instance,
VkDebugUtilsMessengerEXT debugMessenger,
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE);
static VKAPI_ATTR VkBool32 VKAPI_CALL default_debug_callback (VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, static VKAPI_ATTR VkBool32 VKAPI_CALL default_debug_callback (VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType, VkDebugUtilsMessageTypeFlagsEXT messageType,
@ -379,6 +389,7 @@ struct Device {
PhysicalDevice physical_device; PhysicalDevice physical_device;
VkSurfaceKHR surface = VK_NULL_HANDLE; VkSurfaceKHR surface = VK_NULL_HANDLE;
std::vector<VkQueueFamilyProperties> queue_families; std::vector<VkQueueFamilyProperties> queue_families;
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
}; };
void destroy_device (Device device); void destroy_device (Device device);
@ -420,6 +431,9 @@ class DeviceBuilder {
// The structure must be valid when DeviceBuilder::build() is called. // The structure must be valid when DeviceBuilder::build() is called.
template <typename T> DeviceBuilder& add_pNext (T* structure); template <typename T> DeviceBuilder& add_pNext (T* structure);
// Provide custom allocation callbacks.
DeviceBuilder& set_allocation_callbacks (VkAllocationCallbacks* callbacks);
private: private:
struct DeviceInfo { struct DeviceInfo {
VkDeviceCreateFlags flags = 0; VkDeviceCreateFlags flags = 0;
@ -432,6 +446,7 @@ class DeviceBuilder {
bool distinct_compute = false; bool distinct_compute = false;
bool dedicated_transfer = false; bool dedicated_transfer = false;
bool distinct_transfer = false; bool distinct_transfer = false;
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
} info; } info;
}; };
@ -472,6 +487,7 @@ struct Swapchain {
uint32_t image_count = 0; uint32_t image_count = 0;
VkFormat image_format = VK_FORMAT_UNDEFINED; VkFormat image_format = VK_FORMAT_UNDEFINED;
VkExtent2D extent = { 0, 0 }; VkExtent2D extent = { 0, 0 };
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
}; };
void destroy_swapchain (Swapchain const& swapchain); void destroy_swapchain (Swapchain const& swapchain);
@ -501,7 +517,8 @@ class SwapchainBuilder {
SwapchainBuilder& add_fallback_present_mode (VkPresentModeKHR present_mode); SwapchainBuilder& add_fallback_present_mode (VkPresentModeKHR present_mode);
SwapchainBuilder& use_default_present_mode_selection (); SwapchainBuilder& use_default_present_mode_selection ();
// Provide custom allocation callbacks.
SwapchainBuilder& set_allocation_callbacks (VkAllocationCallbacks* callbacks);
private: private:
struct SwapchainInfo { struct SwapchainInfo {
@ -516,6 +533,7 @@ class SwapchainBuilder {
std::vector<VkBaseOutStructure*> pNext_elements; std::vector<VkBaseOutStructure*> pNext_elements;
uint32_t graphics_queue_index = 0; uint32_t graphics_queue_index = 0;
uint32_t present_queue_index = 0; uint32_t present_queue_index = 0;
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
} info; } info;
}; };