aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/vk-renderer.hpp14
-rw-r--r--include/vulkan-loader.hpp52
-rw-r--r--include/window.hpp6
-rw-r--r--src/main.cpp14
-rw-r--r--src/vk-renderer.cpp63
-rw-r--r--src/vulkan-loader.cpp11
-rw-r--r--src/window.cpp7
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,