From 1314f696a7861f3b1509c7f5c27d6b06bc22d5f1 Mon Sep 17 00:00:00 2001 From: ladevieq Date: Tue, 26 Jan 2021 23:12:49 +0100 Subject: Split vkinstance/vkdevice of renderer into context class --- src/vk-context.cpp | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 src/vk-context.cpp (limited to 'src/vk-context.cpp') diff --git a/src/vk-context.cpp b/src/vk-context.cpp new file mode 100644 index 0000000..cbf2777 --- /dev/null +++ b/src/vk-context.cpp @@ -0,0 +1,178 @@ +#include +#include +#include + +#include "vk-context.hpp" + +#define VMA_IMPLEMENTATION +#include "thirdparty/vk_mem_alloc.h" + +#define VKRESULT(result) assert(result == VK_SUCCESS); + +VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, + VkDebugUtilsMessageTypeFlagsEXT type, + const VkDebugUtilsMessengerCallbackDataEXT *data, + void *userData) +{ + std::cerr << data->pMessage << std::endl; + return VK_FALSE; +} + + +vkcontext::vkcontext() { + load_vulkan(); + + create_instance(); + create_device(); +} + +vkcontext::~vkcontext() { + vmaDestroyAllocator(allocator); + vkDestroyDevice(device, nullptr); + vkDestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr); + vkDestroyInstance(instance, nullptr); +} + + +void vkcontext::create_instance() { + VkApplicationInfo app_info = {}; + app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + app_info.pApplicationName = "path-tracer"; + app_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0); + app_info.pEngineName = "gpu-path-tracer"; + app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0); + app_info.apiVersion = VK_API_VERSION_1_2; + + + std::vector layers = { + "VK_LAYER_KHRONOS_validation", + }; + std::vector extensions = { + VK_EXT_DEBUG_UTILS_EXTENSION_NAME, + "VK_KHR_surface", +#if defined(LINUX) + "VK_KHR_xcb_surface" +#elif defined(WINDOWS) + "VK_KHR_win32_surface" +#endif + }; + + VkInstanceCreateInfo instance_create_info = {}; + instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + instance_create_info.pApplicationInfo = &app_info; + instance_create_info.enabledLayerCount = layers.size(); + instance_create_info.ppEnabledLayerNames = layers.data(); + instance_create_info.enabledExtensionCount = extensions.size(); + instance_create_info.ppEnabledExtensionNames = extensions.data(); + + VKRESULT(vkCreateInstance(&instance_create_info, nullptr, &instance)) + + load_instance_functions(instance); + + create_debugger(); + + std::cerr << "Instance ready" << std::endl; +} + +void vkcontext::create_debugger() { + VkDebugUtilsMessengerCreateInfoEXT debugUtilsMessengeCreateInfo { + VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, + nullptr, + 0, + VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, + VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, + DebugCallback, + nullptr, + }; + + VKRESULT(vkCreateDebugUtilsMessengerEXT( + instance, + &debugUtilsMessengeCreateInfo, + nullptr, + &debugMessenger + )) +} + +void vkcontext::create_device() { + select_physical_device(); + select_queue(); + + VkDeviceQueueCreateInfo queue_create_info = {}; + queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_create_info.queueFamilyIndex = queue_index; + queue_create_info.queueCount = 1; + + float queue_priority = 1.f; + queue_create_info.pQueuePriorities = &queue_priority; + + VkPhysicalDeviceFeatures device_features = {}; + + std::vector device_ext = { + "VK_KHR_swapchain" + }; + + VkDeviceCreateInfo device_create_info = {}; + device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + device_create_info.pQueueCreateInfos = &queue_create_info; + device_create_info.queueCreateInfoCount = 1; + device_create_info.pEnabledFeatures = &device_features; + device_create_info.ppEnabledExtensionNames = device_ext.data(); + device_create_info.enabledExtensionCount = device_ext.size(); + device_create_info.enabledLayerCount = 0; // Deprecated https://www.khronos.org/registry/vulkan/specs/1.2/html/chap31.html#extendingvulkan-layers-devicelayerdeprecation + + VKRESULT(vkCreateDevice(physical_device, &device_create_info, nullptr, &device)) + + load_device_functions(device); + + vkGetDeviceQueue(device, queue_index, 0, &queue); + + create_memory_allocator(); + + std::cerr << "Device ready" << std::endl; +} + +void vkcontext::create_memory_allocator() { + VmaAllocatorCreateInfo allocator_info = {}; + allocator_info.vulkanApiVersion = VK_API_VERSION_1_2; + allocator_info.physicalDevice = physical_device; + allocator_info.device = device; + allocator_info.instance = instance; + + vmaCreateAllocator(&allocator_info, &allocator); +} + + +void vkcontext::select_physical_device() { + uint32_t physical_devices_count = 0; + vkEnumeratePhysicalDevices(instance, &physical_devices_count, nullptr); + + if (physical_devices_count < 1) { + std::cerr << "No physical device found !" << std::endl; + exit(1); + } + + std::vector physical_devices { physical_devices_count }; + vkEnumeratePhysicalDevices(instance, &physical_devices_count, physical_devices.data()); + + physical_device = physical_devices[0]; +} + +void vkcontext::select_queue() { + uint32_t queue_properties_count = 0; + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_properties_count, nullptr); + + std::vector queue_properties { queue_properties_count }; + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_properties_count, queue_properties.data()); + + for (uint32_t properties_index = 0; properties_index < queue_properties_count; properties_index++) { + if (queue_properties[properties_index].queueFlags & VK_QUEUE_COMPUTE_BIT) { + queue_index = properties_index; + return; + } + } + + std::cerr << "No compute queue found !" << std::endl; + exit(1); +} + -- cgit v1.3