diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2020-12-25 00:55:10 +0100 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2020-12-25 00:57:56 +0100 |
| commit | 198004233b111334df7ca82954fe61a2a1ad3bd5 (patch) | |
| tree | ef677a842374e7c836acf63b685469bde2c10f34 /src | |
| parent | e35c849f1bd0ed3c3123fb253897a6e427f789ab (diff) | |
Setup vulkan and vulkan loader
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | src/main.cpp | 136 | ||||
| -rw-r--r-- | src/vulkan-loader.cpp | 90 |
3 files changed, 232 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bac7a7a..75c689b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,5 @@ include_directories(${CMAKE_SOURCE_DIR}/include) +include_directories(${Vulkan_INCLUDE_DIRS}) add_executable( path-tracer @@ -12,4 +13,9 @@ add_executable( lambertian.cpp metal.cpp dielectric.cpp + vulkan-loader.cpp ) + +if(UNIX) + target_link_libraries(path-tracer ${CMAKE_DL_LIBS}) +endif() diff --git a/src/main.cpp b/src/main.cpp index 937dc9c..973f86c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,7 @@ #include <iostream> +#include <vector> +#include "vulkan-loader.hpp" #include "rt.hpp" #include "hittable_list.hpp" @@ -73,7 +75,141 @@ color ray_color(ray& r, const hittable& world, uint32_t depth) { return lerp(ground_color, sky_color, t); } +VkInstance instance = nullptr; +VkPhysicalDevice physical_device = nullptr; +int32_t compute_queue_index = -1; +VkDevice device = nullptr; +VkQueue compute_queue = nullptr; + +VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT _severity, + VkDebugUtilsMessageTypeFlagsEXT _type, + const VkDebugUtilsMessengerCallbackDataEXT *_data, + void *_userData) +{ + std::cerr << _data->pMessage << std::endl; + return VK_FALSE; +} + +void create_debugger(VkInstance instance) { + VkDebugUtilsMessengerEXT debugMessenger; + 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, + }; + + vkCreateDebugUtilsMessengerEXT( + instance, + &debugUtilsMessengeCreateInfo, + nullptr, + &debugMessenger + ); +} + +void 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_0; + + + const char* layers[1] = { + "VK_LAYER_KHRONOS_validation", + }; + const char* ext[1] = { + VK_EXT_DEBUG_UTILS_EXTENSION_NAME + }; + VkInstanceCreateInfo instance_create_info = {}; + instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + instance_create_info.pApplicationInfo = &app_info; + instance_create_info.enabledLayerCount = 1; + instance_create_info.ppEnabledLayerNames = layers; + instance_create_info.enabledExtensionCount = 1; + instance_create_info.ppEnabledExtensionNames = ext; + + vkCreateInstance(&instance_create_info, nullptr, &instance); + + load_instance_functions(instance); + create_debugger(instance); +} + +void 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<VkPhysicalDevice> physical_devices { physical_devices_count }; + vkEnumeratePhysicalDevices(instance, &physical_devices_count, physical_devices.data()); + + physical_device = physical_devices[0]; +} + +int32_t get_compute_queue_index() { + uint32_t queue_properties_count = 0; + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_properties_count, nullptr); + + std::vector<VkQueueFamilyProperties> 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) { + return properties_index; + } + } + + return -1; +} + +void create_device() { + select_physical_device(); + + compute_queue_index = get_compute_queue_index(); + VkDeviceQueueCreateInfo queue_create_info = {}; + queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_create_info.queueFamilyIndex = compute_queue_index; + queue_create_info.queueCount = 1; + + float queue_priority = 1.f; + queue_create_info.pQueuePriorities = &queue_priority; + + VkPhysicalDeviceFeatures device_features = {}; + + 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.enabledExtensionCount = 0; // None yet + device_create_info.enabledLayerCount = 0; // https://www.khronos.org/registry/vulkan/specs/1.2/html/chap31.html#extendingvulkan-layers-devicelayerdeprecation + + vkCreateDevice(physical_device, &device_create_info, nullptr, &device); + + load_device_functions(device); + + vkGetDeviceQueue(device, compute_queue_index, 0, &compute_queue); +} + +void init_vk() { + create_instance(); + create_device(); +} + int main() { + load_vulkan(); + init_vk(); + // Image dimensions const double aspect_ratio = 16.0 / 9.0; const size_t width = 1920; diff --git a/src/vulkan-loader.cpp b/src/vulkan-loader.cpp new file mode 100644 index 0000000..32aa49b --- /dev/null +++ b/src/vulkan-loader.cpp @@ -0,0 +1,90 @@ +#include "vulkan-loader.hpp" + +#include <iostream> + +#if defined(WINDOWS) +HMODULE vulkanLibrary = LoadLibrary("vulkan-1.dll"); + +#define LoadProcAddress GetProcAddress + +#elif defined(__linux__) +#include <dlfcn.h> + +void *vulkanLibrary = dlopen( "libvulkan.so.1", RTLD_NOW ); + +#define LoadProcAddress dlsym +#endif + +#define X(name) PFN_##name name; + VULKAN_EXPORTED_FUNCTIONS + VULKAN_APPLICATION_FUNCTIONS + VULKAN_INSTANCE_FUNCTIONS + PLATFORM_VULKAN_INSTANCE_FUNCTIONS + VULKAN_DEVICE_FUNCTIONS +#undef X + +#define X(name) \ +void Load_##name() \ +{ \ + name = reinterpret_cast<PFN_##name>(LoadProcAddress(vulkanLibrary, #name)); \ + if (!name) { \ + std::cout << "Cannot load vulkan function " << #name << std::endl; \ + } \ +} +VULKAN_EXPORTED_FUNCTIONS +#undef X + +#define X(name) \ +void Load_##name() \ +{ \ + name = reinterpret_cast<PFN_##name>(vkGetInstanceProcAddr(nullptr, #name)); \ + if (!name) { \ + std::cout << "Cannot load vulkan function " << #name << std::endl; \ + } \ +} +VULKAN_APPLICATION_FUNCTIONS +#undef X + +#define X(name) \ +void Load_##name(VkInstance _instance) \ +{ \ + name = reinterpret_cast<PFN_##name>(vkGetInstanceProcAddr(_instance, #name)); \ + if (!name) { \ + std::cout << "Cannot load vulkan function " << #name << std::endl; \ + } \ +} +VULKAN_INSTANCE_FUNCTIONS +PLATFORM_VULKAN_INSTANCE_FUNCTIONS +#undef X + +#define X(name) \ +void Load_##name(VkDevice _device) \ +{ \ + name = reinterpret_cast<PFN_##name>(vkGetDeviceProcAddr(_device, #name)); \ + if (!name) { \ + std::cout << "Cannot load vulkan function " << #name << std::endl; \ + } \ +} +VULKAN_DEVICE_FUNCTIONS +#undef X + +void load_vulkan() +{ +#define X(name) Load_##name(); + VULKAN_EXPORTED_FUNCTIONS + VULKAN_APPLICATION_FUNCTIONS +#undef X +}; + +void load_instance_functions(VkInstance instance) { +#define X(name) Load_##name(instance); + VULKAN_INSTANCE_FUNCTIONS + PLATFORM_VULKAN_INSTANCE_FUNCTIONS +#undef X +} + +void load_device_functions(VkDevice device) { +#define X(name) void Load_##name(VkDevice _device); + VULKAN_DEVICE_FUNCTIONS +#undef X +} |
