aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2020-12-25 00:55:10 +0100
committerladevieq <ladevie.quentin@gmail.com>2020-12-25 00:57:56 +0100
commit198004233b111334df7ca82954fe61a2a1ad3bd5 (patch)
treeef677a842374e7c836acf63b685469bde2c10f34
parente35c849f1bd0ed3c3123fb253897a6e427f789ab (diff)
Setup vulkan and vulkan loader
-rw-r--r--CMakeLists.txt2
-rw-r--r--compile_commands.json41
-rw-r--r--include/vulkan-loader.hpp147
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/main.cpp136
-rw-r--r--src/vulkan-loader.cpp90
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
+}