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 | |
| parent | e35c849f1bd0ed3c3123fb253897a6e427f789ab (diff) | |
Setup vulkan and vulkan loader
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | compile_commands.json | 41 | ||||
| -rw-r--r-- | include/vulkan-loader.hpp | 147 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | src/main.cpp | 136 | ||||
| -rw-r--r-- | src/vulkan-loader.cpp | 90 |
6 files changed, 419 insertions, 3 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index abb196a..4cf5438 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,4 +5,6 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) project(path-tracer VERSION 1.0 LANGUAGES CXX) +find_package(Vulkan REQUIRED) + add_subdirectory(src) diff --git a/compile_commands.json b/compile_commands.json index 820d63c..b7b2709 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -1,17 +1,52 @@ [ { "directory": "/home/quentin/Projects/path-tracer/build/src", - "command": "/usr/bin/c++ -I/home/quentin/Projects/path-tracer/include -o CMakeFiles/path-tracer.dir/main.cpp.o -c /home/quentin/Projects/path-tracer/src/main.cpp", + "command": "/usr/bin/c++ -I/home/quentin/Projects/path-tracer/include -I/home/quentin/vulkan-sdk/1.2.162.0/x86_64/include -o CMakeFiles/path-tracer.dir/main.cpp.o -c /home/quentin/Projects/path-tracer/src/main.cpp", "file": "/home/quentin/Projects/path-tracer/src/main.cpp" }, { "directory": "/home/quentin/Projects/path-tracer/build/src", - "command": "/usr/bin/c++ -I/home/quentin/Projects/path-tracer/include -o CMakeFiles/path-tracer.dir/vec3.cpp.o -c /home/quentin/Projects/path-tracer/src/vec3.cpp", + "command": "/usr/bin/c++ -I/home/quentin/Projects/path-tracer/include -I/home/quentin/vulkan-sdk/1.2.162.0/x86_64/include -o CMakeFiles/path-tracer.dir/vec3.cpp.o -c /home/quentin/Projects/path-tracer/src/vec3.cpp", "file": "/home/quentin/Projects/path-tracer/src/vec3.cpp" }, { "directory": "/home/quentin/Projects/path-tracer/build/src", - "command": "/usr/bin/c++ -I/home/quentin/Projects/path-tracer/include -o CMakeFiles/path-tracer.dir/color.cpp.o -c /home/quentin/Projects/path-tracer/src/color.cpp", + "command": "/usr/bin/c++ -I/home/quentin/Projects/path-tracer/include -I/home/quentin/vulkan-sdk/1.2.162.0/x86_64/include -o CMakeFiles/path-tracer.dir/color.cpp.o -c /home/quentin/Projects/path-tracer/src/color.cpp", "file": "/home/quentin/Projects/path-tracer/src/color.cpp" +}, +{ + "directory": "/home/quentin/Projects/path-tracer/build/src", + "command": "/usr/bin/c++ -I/home/quentin/Projects/path-tracer/include -I/home/quentin/vulkan-sdk/1.2.162.0/x86_64/include -o CMakeFiles/path-tracer.dir/ray.cpp.o -c /home/quentin/Projects/path-tracer/src/ray.cpp", + "file": "/home/quentin/Projects/path-tracer/src/ray.cpp" +}, +{ + "directory": "/home/quentin/Projects/path-tracer/build/src", + "command": "/usr/bin/c++ -I/home/quentin/Projects/path-tracer/include -I/home/quentin/vulkan-sdk/1.2.162.0/x86_64/include -o CMakeFiles/path-tracer.dir/sphere.cpp.o -c /home/quentin/Projects/path-tracer/src/sphere.cpp", + "file": "/home/quentin/Projects/path-tracer/src/sphere.cpp" +}, +{ + "directory": "/home/quentin/Projects/path-tracer/build/src", + "command": "/usr/bin/c++ -I/home/quentin/Projects/path-tracer/include -I/home/quentin/vulkan-sdk/1.2.162.0/x86_64/include -o CMakeFiles/path-tracer.dir/hittable_list.cpp.o -c /home/quentin/Projects/path-tracer/src/hittable_list.cpp", + "file": "/home/quentin/Projects/path-tracer/src/hittable_list.cpp" +}, +{ + "directory": "/home/quentin/Projects/path-tracer/build/src", + "command": "/usr/bin/c++ -I/home/quentin/Projects/path-tracer/include -I/home/quentin/vulkan-sdk/1.2.162.0/x86_64/include -o CMakeFiles/path-tracer.dir/camera.cpp.o -c /home/quentin/Projects/path-tracer/src/camera.cpp", + "file": "/home/quentin/Projects/path-tracer/src/camera.cpp" +}, +{ + "directory": "/home/quentin/Projects/path-tracer/build/src", + "command": "/usr/bin/c++ -I/home/quentin/Projects/path-tracer/include -I/home/quentin/vulkan-sdk/1.2.162.0/x86_64/include -o CMakeFiles/path-tracer.dir/lambertian.cpp.o -c /home/quentin/Projects/path-tracer/src/lambertian.cpp", + "file": "/home/quentin/Projects/path-tracer/src/lambertian.cpp" +}, +{ + "directory": "/home/quentin/Projects/path-tracer/build/src", + "command": "/usr/bin/c++ -I/home/quentin/Projects/path-tracer/include -I/home/quentin/vulkan-sdk/1.2.162.0/x86_64/include -o CMakeFiles/path-tracer.dir/metal.cpp.o -c /home/quentin/Projects/path-tracer/src/metal.cpp", + "file": "/home/quentin/Projects/path-tracer/src/metal.cpp" +}, +{ + "directory": "/home/quentin/Projects/path-tracer/build/src", + "command": "/usr/bin/c++ -I/home/quentin/Projects/path-tracer/include -I/home/quentin/vulkan-sdk/1.2.162.0/x86_64/include -o CMakeFiles/path-tracer.dir/dielectric.cpp.o -c /home/quentin/Projects/path-tracer/src/dielectric.cpp", + "file": "/home/quentin/Projects/path-tracer/src/dielectric.cpp" } ]
\ No newline at end of file diff --git a/include/vulkan-loader.hpp b/include/vulkan-loader.hpp new file mode 100644 index 0000000..53bb1a2 --- /dev/null +++ b/include/vulkan-loader.hpp @@ -0,0 +1,147 @@ +#ifndef __VULKAN_LOADER_HPP_ +#define __VULKAN_LOADER_HPP_ + +#if defined(WINDOWS) +#include <Windows.h> +#include <windowsx.h> + +#define VK_USE_PLATFORM_WIN32_KHR +#endif + +#define VK_NO_PROTOTYPES +#include <vulkan/vulkan.h> + +#define VULKAN_EXPORTED_FUNCTIONS \ + X(vkGetInstanceProcAddr) \ + X(vkGetDeviceProcAddr) + +#define VULKAN_APPLICATION_FUNCTIONS \ + X(vkCreateInstance) \ + X(vkEnumerateInstanceVersion) \ + X(vkEnumerateInstanceExtensionProperties) \ + X(vkEnumerateInstanceLayerProperties) + +#define VULKAN_INSTANCE_FUNCTIONS \ + X(vkDestroyInstance) \ + X(vkEnumeratePhysicalDevices) \ + X(vkGetPhysicalDeviceProperties) \ + X(vkGetPhysicalDeviceFeatures) \ + X(vkGetPhysicalDeviceQueueFamilyProperties) \ + X(vkGetPhysicalDeviceMemoryProperties) \ + X(vkCreateDevice) \ + X(vkEnumerateDeviceExtensionProperties) \ + X(vkDestroySurfaceKHR) \ + X(vkGetPhysicalDeviceSurfaceSupportKHR) \ + X(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \ + X(vkGetPhysicalDeviceSurfaceFormatsKHR) \ + X(vkGetPhysicalDeviceSurfacePresentModesKHR) \ + X(vkCreateDebugUtilsMessengerEXT) \ + X(vkDestroyDebugUtilsMessengerEXT) + +#if defined(WINDOWS) +#define PLATFORM_VULKAN_INSTANCE_FUNCTIONS X(vkCreateWin32SurfaceKHR) +#else +#define PLATFORM_VULKAN_INSTANCE_FUNCTIONS +#endif + +#define VULKAN_DEVICE_FUNCTIONS \ + X(vkGetDeviceQueue) \ + X(vkDestroyDevice) \ + X(vkDeviceWaitIdle) \ + X(vkCreateSwapchainKHR) \ + X(vkGetSwapchainImagesKHR) \ + X(vkAcquireNextImageKHR) \ + X(vkDestroySwapchainKHR) \ + X(vkQueueSubmit) \ + X(vkQueuePresentKHR) \ + X(vkCreateSemaphore) \ + X(vkDestroySemaphore) \ + X(vkCreateCommandPool) \ + X(vkAllocateCommandBuffers) \ + X(vkFreeCommandBuffers) \ + X(vkDestroyCommandPool) \ + X(vkBeginCommandBuffer) \ + X(vkCmdPipelineBarrier) \ + X(vkCmdClearColorImage) \ + X(vkCmdBeginRenderPass) \ + X(vkCmdBindPipeline) \ + X(vkCmdBindVertexBuffers) \ + X(vkCmdBindIndexBuffer) \ + X(vkCmdBindDescriptorSets) \ + X(vkCmdCopyBuffer) \ + X(vkCmdCopyImage) \ + X(vkCmdCopyBufferToImage) \ + X(vkCmdDraw) \ + X(vkCmdDrawIndexed) \ + X(vkCmdEndRenderPass) \ + X(vkEndCommandBuffer) \ + X(vkCreateRenderPass) \ + X(vkCreateBuffer) \ + X(vkCreateImage) \ + X(vkCreateImageView) \ + X(vkCreateSampler) \ + X(vkCreateFramebuffer) \ + X(vkCreateShaderModule) \ + X(vkCreatePipelineLayout) \ + X(vkCreateGraphicsPipelines) \ + X(vkCreateFence) \ + X(vkCreateDescriptorSetLayout) \ + X(vkCreateDescriptorPool) \ + X(vkAllocateDescriptorSets) \ + X(vkUpdateDescriptorSets) \ + X(vkGetBufferMemoryRequirements) \ + X(vkGetImageMemoryRequirements) \ + X(vkAllocateMemory) \ + X(vkMapMemory) \ + X(vkInvalidateMappedMemoryRanges) \ + X(vkFlushMappedMemoryRanges) \ + X(vkUnmapMemory) \ + X(vkFreeMemory) \ + X(vkBindBufferMemory) \ + X(vkBindImageMemory) \ + X(vkWaitForFences) \ + X(vkResetFences) \ + X(vkDestroyFence) \ + X(vkFreeDescriptorSets) \ + X(vkDestroyDescriptorPool) \ + X(vkDestroyDescriptorSetLayout) \ + X(vkDestroyPipeline) \ + X(vkDestroyPipelineLayout) \ + X(vkDestroyShaderModule) \ + X(vkDestroyFramebuffer) \ + X(vkDestroySampler) \ + X(vkDestroyImageView) \ + X(vkDestroyImage) \ + X(vkDestroyBuffer) \ + X(vkDestroyRenderPass) + +#define X(name) extern 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(); + VULKAN_EXPORTED_FUNCTIONS + VULKAN_APPLICATION_FUNCTIONS +#undef X + +#define X(name) void Load_##name(VkInstance _instance); + VULKAN_INSTANCE_FUNCTIONS + PLATFORM_VULKAN_INSTANCE_FUNCTIONS +#undef X + +#define X(name) void Load_##name(VkDevice _device); + VULKAN_DEVICE_FUNCTIONS +#undef X + + void load_vulkan(); + + void load_instance_functions(VkInstance instance); + + void load_device_functions(VkDevice device); + +#endif // !__VULKAN_LOADER_HPP_ 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 +} |
