diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2021-01-10 19:51:03 +0100 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2021-01-10 19:51:03 +0100 |
| commit | 94c1b2d414055f9a4ea203fb210666aa769d0096 (patch) | |
| tree | 5bc7e359ba63c1137f5aa276fee1219924e7a0f9 | |
| parent | 78302e1982c1b7b727c95603611b19913f5c13d0 (diff) | |
Create xcb surface and swapchain
| -rw-r--r-- | include/vk-renderer.hpp | 14 | ||||
| -rw-r--r-- | include/vulkan-loader.hpp | 52 | ||||
| -rw-r--r-- | include/window.hpp | 6 | ||||
| -rw-r--r-- | src/main.cpp | 14 | ||||
| -rw-r--r-- | src/vk-renderer.cpp | 63 | ||||
| -rw-r--r-- | src/vulkan-loader.cpp | 11 | ||||
| -rw-r--r-- | src/window.cpp | 7 |
7 files changed, 120 insertions, 47 deletions
diff --git a/include/vk-renderer.hpp b/include/vk-renderer.hpp index 37a3494..a1dda6c 100644 --- a/include/vk-renderer.hpp +++ b/include/vk-renderer.hpp @@ -1,12 +1,15 @@ #ifndef __VK_RENDERER_HPP_ #define __VK_RENDERER_HPP_ +#include <vector> + #include "vulkan-loader.hpp" #include "thirdparty/vk_mem_alloc.h" #include "vec3.hpp" #include "camera.hpp" #include "sphere.hpp" +#include "window.hpp" struct input_data { color sky_color; @@ -35,7 +38,7 @@ struct path_tracer_data { class vkrenderer { public: - vkrenderer(); + vkrenderer(window& wnd); void compute(const input_data& inputs, size_t width, size_t height); @@ -46,8 +49,12 @@ class vkrenderer { void create_debugger(); + void create_surface(window& wnd); + void create_device(); + void create_swapchain(window& wnd); + void create_pipeline(); void create_memory_allocator(); @@ -82,6 +89,11 @@ class vkrenderer { VkPipelineLayout compute_pipeline_layout; VkPipeline compute_pipeline; + VkSurfaceKHR platform_surface; + VkSwapchainKHR swapchain; + size_t swapchain_images_count = 3; + std::vector<VkImage> swapchain_images; + struct path_tracer_data* mapped_data; }; diff --git a/include/vulkan-loader.hpp b/include/vulkan-loader.hpp index 1691c6c..66542cf 100644 --- a/include/vulkan-loader.hpp +++ b/include/vulkan-loader.hpp @@ -1,11 +1,13 @@ #ifndef __VULKAN_LOADER_HPP_ #define __VULKAN_LOADER_HPP_ -#if defined(WINDOWS) +#if defined(_WIN32) || defined(_WIN64) #include <Windows.h> #include <windowsx.h> #define VK_USE_PLATFORM_WIN32_KHR +#elif defined(__linux__) +#define VK_USE_PLATFORM_XCB_KHR #endif #define VK_NO_PROTOTYPES @@ -15,13 +17,32 @@ X(vkGetInstanceProcAddr) \ X(vkGetDeviceProcAddr) + #define VULKAN_APPLICATION_FUNCTIONS \ X(vkCreateInstance) \ X(vkEnumerateInstanceVersion) \ X(vkEnumerateInstanceExtensionProperties) \ X(vkEnumerateInstanceLayerProperties) + +#if defined(VK_USE_PLATFORM_WIN32_KHR) +#define PLATFORM_VULKAN_INSTANCE_FUNCTIONS X(vkCreateWin32SurfaceKHR) +#elif defined(VK_USE_PLATFORM_XCB_KHR) +#define PLATFORM_VULKAN_INSTANCE_FUNCTIONS X(vkCreateXcbSurfaceKHR) +#else +#define PLATFORM_VULKAN_INSTANCE_FUNCTIONS +#endif + +#define VULKAN_SURFACE_FUNCTIONS \ + PLATFORM_VULKAN_INSTANCE_FUNCTIONS \ + X(vkDestroySurfaceKHR) \ + X(vkGetPhysicalDeviceSurfaceSupportKHR) \ + X(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \ + X(vkGetPhysicalDeviceSurfaceFormatsKHR) \ + X(vkGetPhysicalDeviceSurfacePresentModesKHR) + #define VULKAN_INSTANCE_FUNCTIONS \ + VULKAN_SURFACE_FUNCTIONS \ X(vkDestroyInstance) \ X(vkEnumeratePhysicalDevices) \ X(vkGetPhysicalDeviceProperties) \ @@ -33,22 +54,16 @@ X(vkCreateDebugUtilsMessengerEXT) \ X(vkDestroyDebugUtilsMessengerEXT) -#if defined(VK_USE_PLATFORM_WIN32_KHR) -#define VULKAN_SURFACE_FUNCTIONS \ - X(vkDestroySurfaceKHR) \ - X(vkGetPhysicalDeviceSurfaceSupportKHR) \ - X(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \ - X(vkGetPhysicalDeviceSurfaceFormatsKHR) \ - X(vkGetPhysicalDeviceSurfacePresentModesKHR) -#endif -#if defined(WINDOWS) -#define PLATFORM_VULKAN_INSTANCE_FUNCTIONS X(vkCreateWin32SurfaceKHR) -#else -#define PLATFORM_VULKAN_INSTANCE_FUNCTIONS -#endif +#define VULKAN_SWAPCHAIN_FUNCTIONS \ + X(vkCreateSwapchainKHR) \ + X(vkGetSwapchainImagesKHR) \ + X(vkAcquireNextImageKHR) \ + X(vkDestroySwapchainKHR) \ + X(vkQueuePresentKHR) \ #define VULKAN_DEVICE_FUNCTIONS \ + VULKAN_SWAPCHAIN_FUNCTIONS \ X(vkGetDeviceQueue) \ X(vkDestroyDevice) \ X(vkDeviceWaitIdle) \ @@ -116,18 +131,10 @@ X(vkDestroyBuffer) \ X(vkDestroyRenderPass) -// Depends on the swapchain extension -// X(vkCreateSwapchainKHR) \ -// X(vkGetSwapchainImagesKHR) \ -// X(vkAcquireNextImageKHR) \ -// X(vkDestroySwapchainKHR) \ -// X(vkQueuePresentKHR) \ - #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 @@ -139,7 +146,6 @@ #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); diff --git a/include/window.hpp b/include/window.hpp index 593c6f8..8ddb58d 100644 --- a/include/window.hpp +++ b/include/window.hpp @@ -5,11 +5,13 @@ class window { public: - window(); + window(uint32_t width, uint32_t height); - private: xcb_connection_t* connection; xcb_window_t win; + + uint32_t width; + uint32_t height; }; #endif // !__WINDOW_HPP_ diff --git a/src/main.cpp b/src/main.cpp index 7a91c4e..31e3002 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -79,13 +79,13 @@ int main() { assert(ret == 1); } - window wnd {}; - vkrenderer renderer {}; - // Image dimensions const float aspect_ratio = 16.0 / 9.0; - const size_t width = 1920; - const size_t height = width / aspect_ratio; + const uint32_t width = 1920; + const uint32_t height = width / aspect_ratio; + + window wnd { width , height }; + vkrenderer renderer { wnd }; const uint32_t samples_per_pixel = 20; const uint32_t max_depth = 20; @@ -105,8 +105,8 @@ int main() { .max_bounce = max_depth, .samples_per_pixel = samples_per_pixel, - .width = (uint32_t)width, - .height = (uint32_t)height + .width = width, + .height = height }; // Random numbers pools diff --git a/src/vk-renderer.cpp b/src/vk-renderer.cpp index d26fe86..7bfad90 100644 --- a/src/vk-renderer.cpp +++ b/src/vk-renderer.cpp @@ -19,12 +19,13 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(VkDebugUtilsMessageSeverityFlagBits return VK_FALSE; } - -vkrenderer::vkrenderer() { +vkrenderer::vkrenderer(window& wnd) { load_vulkan(); create_instance(); + create_surface(wnd); create_device(); + create_swapchain(wnd); create_pipeline(); create_memory_allocator(); create_command_buffer(); @@ -84,7 +85,9 @@ void vkrenderer::create_instance() { "VK_LAYER_KHRONOS_validation", }; std::vector<const char*> extensions = { - VK_EXT_DEBUG_UTILS_EXTENSION_NAME + VK_EXT_DEBUG_UTILS_EXTENSION_NAME, + "VK_KHR_surface", + "VK_KHR_xcb_surface" }; VkInstanceCreateInfo instance_create_info = {}; @@ -125,6 +128,17 @@ void vkrenderer::create_debugger() { )) } +void vkrenderer::create_surface(window& wnd) { + VkXcbSurfaceCreateInfoKHR create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; + create_info.pNext = nullptr; + create_info.flags = 0; + create_info.connection = wnd.connection; + create_info.window = wnd.win; + + VKRESULT(vkCreateXcbSurfaceKHR(instance, &create_info, nullptr, &platform_surface)) +} + void vkrenderer::create_device() { select_physical_device(); select_compute_queue(); @@ -139,12 +153,17 @@ void vkrenderer::create_device() { VkPhysicalDeviceFeatures device_features = {}; + std::vector<const char*> 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.enabledExtensionCount = 0; // None yet + 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)) @@ -156,6 +175,42 @@ void vkrenderer::create_device() { std::cerr << "Device ready" << std::endl; } +void vkrenderer::create_swapchain(window& wnd) { + VkBool32 queue_support_presentation = VK_FALSE; + VKRESULT(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, compute_queue_index, platform_surface, &queue_support_presentation)); + + VkSurfaceCapabilitiesKHR caps; + VKRESULT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, platform_surface, &caps)) + + uint32_t supported_formats_count = 0; + VKRESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, platform_surface, &supported_formats_count, VK_NULL_HANDLE)) + + std::vector<VkSurfaceFormatKHR> supported_formats { supported_formats_count }; + VKRESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, platform_surface, &supported_formats_count, supported_formats.data())) + + VkSwapchainCreateInfoKHR create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + create_info.pNext = nullptr; + create_info.flags = 0; + create_info.surface = platform_surface; + create_info.minImageCount = swapchain_images_count; + create_info.imageFormat = supported_formats[0].format; + create_info.imageColorSpace = supported_formats[0].colorSpace; + create_info.imageExtent = caps.currentExtent; + create_info.imageArrayLayers = 1; + create_info.imageUsage = VK_IMAGE_USAGE_STORAGE_BIT; + create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + create_info.preTransform = caps.currentTransform; + create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + create_info.presentMode = VK_PRESENT_MODE_FIFO_KHR; + create_info.clipped = VK_TRUE; + create_info.oldSwapchain = VK_NULL_HANDLE; + + VKRESULT(vkCreateSwapchainKHR(device, &create_info, nullptr, &swapchain)) + + VKRESULT(vkGetSwapchainImagesKHR(device, swapchain, (uint32_t*)&swapchain_images_count, swapchain_images.data())) +} + void vkrenderer::create_pipeline() { std::vector<uint8_t> shader_code = get_shader_code("./shaders/compute.comp.spv"); if (shader_code.size() == 0) { diff --git a/src/vulkan-loader.cpp b/src/vulkan-loader.cpp index f4d9547..17ddb31 100644 --- a/src/vulkan-loader.cpp +++ b/src/vulkan-loader.cpp @@ -19,7 +19,6 @@ void *vulkanLibrary = dlopen( "libvulkan.so.1", RTLD_NOW ); VULKAN_EXPORTED_FUNCTIONS VULKAN_APPLICATION_FUNCTIONS VULKAN_INSTANCE_FUNCTIONS - PLATFORM_VULKAN_INSTANCE_FUNCTIONS VULKAN_DEVICE_FUNCTIONS #undef X @@ -28,7 +27,7 @@ void Load_##name() { \ name = reinterpret_cast<PFN_##name>(LoadProcAddress(vulkanLibrary, #name)); \ if (!name) { \ - std::cout << "Cannot load vulkan function " << #name << std::endl; \ + std::cerr << "Cannot load vulkan function " << #name << std::endl; \ } \ } VULKAN_EXPORTED_FUNCTIONS @@ -39,7 +38,7 @@ void Load_##name() { \ name = reinterpret_cast<PFN_##name>(vkGetInstanceProcAddr(nullptr, #name)); \ if (!name) { \ - std::cout << "Cannot load vulkan function " << #name << std::endl; \ + std::cerr << "Cannot load vulkan function " << #name << std::endl; \ } \ } VULKAN_APPLICATION_FUNCTIONS @@ -50,11 +49,10 @@ void Load_##name(VkInstance instance) { \ name = reinterpret_cast<PFN_##name>(vkGetInstanceProcAddr(instance, #name)); \ if (!name) { \ - std::cout << "Cannot load vulkan function " << #name << std::endl; \ + std::cerr << "Cannot load vulkan function " << #name << std::endl; \ } \ } VULKAN_INSTANCE_FUNCTIONS -PLATFORM_VULKAN_INSTANCE_FUNCTIONS #undef X #define X(name) \ @@ -62,7 +60,7 @@ void Load_##name(VkDevice device) \ { \ name = reinterpret_cast<PFN_##name>(vkGetDeviceProcAddr(device, #name)); \ if (!name) { \ - std::cout << "Cannot load vulkan function " << #name << std::endl; \ + std::cerr << "Cannot load vulkan function " << #name << std::endl; \ } \ } VULKAN_DEVICE_FUNCTIONS @@ -79,7 +77,6 @@ void load_vulkan() void load_instance_functions(VkInstance instance) { #define X(name) Load_##name(instance); VULKAN_INSTANCE_FUNCTIONS - PLATFORM_VULKAN_INSTANCE_FUNCTIONS #undef X } diff --git a/src/window.cpp b/src/window.cpp index 93c7517..1bfc903 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1,6 +1,7 @@ #include "window.hpp" -window::window() { +window::window(uint32_t width, uint32_t height) + :width(width), height(height) { connection = xcb_connect(NULL, NULL); win = xcb_generate_id(connection); @@ -14,8 +15,8 @@ window::window() { screen_info->root, 10, 10, - 400, - 400, + width, + height, 10, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen_info->root_visual, |
