aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2021-01-29 23:56:55 +0100
committerladevieq <ladevie.quentin@gmail.com>2021-01-29 23:56:55 +0100
commitc5ac7ee3f91efc60d87a59706c9ce2970116b865 (patch)
treed6dc3c5c23f81a5ac05fc711a6353338d9291037
parent34c2b9b450c0f5c695a699ba4ae3f93470057ccb (diff)
Finished moving api resources creation functions
-rw-r--r--CMakeLists.txt4
-rw-r--r--include/vk-api.hpp47
-rw-r--r--include/vk-renderer.hpp23
-rw-r--r--src/vk-api.cpp289
-rw-r--r--src/vk-renderer.cpp254
5 files changed, 354 insertions, 263 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a39d1af..898e2db 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,9 @@
cmake_minimum_required(VERSION 3.10)
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
project(path-tracer VERSION 1.0 LANGUAGES CXX)
diff --git a/include/vk-api.hpp b/include/vk-api.hpp
index 52ebef6..53a33ba 100644
--- a/include/vk-api.hpp
+++ b/include/vk-api.hpp
@@ -2,12 +2,13 @@
#define __VK_API_HPP_
#include <vector>
+#include <optional>
#include "vk-context.hpp"
struct Buffer {
VmaAllocation alloc;
- VkBuffer vkbuffer;
+ VkBuffer handle;
void* mapped_ptr;
};
@@ -15,9 +16,24 @@ struct ComputePipeline {
VkShaderModule shader_module;
VkDescriptorSetLayout descriptor_set_layout;
VkPipelineLayout layout;
- VkPipeline vkpipeline;
+ VkPipeline handle;
};
+struct Image {
+ VkImage handle;
+ VkImageView view;
+ VkImageSubresourceRange subresource_range;
+ VkFormat format;
+};
+
+struct Swapchain {
+ size_t image_count;
+ std::vector<Image> images;
+ VkSwapchainKHR handle;
+};
+
+class window;
+
class vkapi {
public:
vkapi();
@@ -26,26 +42,47 @@ class vkapi {
Buffer create_buffer(size_t data_size, VkBufferUsageFlags buffer_usage, VmaMemoryUsage mem_usage);
void destroy_buffer(Buffer& buffer);
+
+ Image create_image(VkExtent3D size, VkFormat format, VkImageUsageFlags usages);
+ void destroy_image(Image &image);
+ std::vector<Image> create_images(VkExtent3D size, VkFormat format, VkImageUsageFlags usages, size_t image_count);
+ void destroy_images(std::vector<Image> &images);
+
+
VkFence create_fence();
void destroy_fence(VkFence fence);
std::vector<VkFence> create_fences(size_t fences_count);
- void destroy_fences(std::vector<VkFence> fences);
+ void destroy_fences(std::vector<VkFence> &fences);
+
VkSemaphore create_semaphore();
void destroy_semaphore(VkSemaphore semaphore);
std::vector<VkSemaphore> create_semaphores(size_t semaphores_count);
void destroy_semaphores(std::vector<VkSemaphore> &semaphores);
+
std::vector<VkCommandBuffer> create_command_buffers(size_t command_buffers_count);
- void destroy_command_buffers(std::vector<VkCommandBuffer> command_buffers);
+ void destroy_command_buffers(std::vector<VkCommandBuffer> &command_buffers);
+
ComputePipeline create_compute_pipeline(const char* shader_path, std::vector<VkDescriptorSetLayoutBinding> bindings);
void destroy_compute_pipeline(ComputePipeline &pipeline);
+
std::vector<VkDescriptorSet> create_descriptor_sets(VkDescriptorSetLayout descriptor_sets_layout, size_t descriptor_sets_count);
- void destroy_descriptor_sets(std::vector<VkDescriptorSet> descriptor_sets);
+ void destroy_descriptor_sets(std::vector<VkDescriptorSet> &descriptor_sets);
+
+
+ // TODO: Maybe includes surface in the swapchain structure
+ VkSurfaceKHR create_surface(window& wnd);
+ void destroy_surface(VkSurfaceKHR surface);
+
+ Swapchain create_swapchain(VkSurfaceKHR surface, size_t min_image_count, VkImageUsageFlags usages, std::optional<Swapchain> old_swapchain);
+ void destroy_swapchain(Swapchain swapchain);
+ void update_descriptor_set_buffer(VkDescriptorSet set, VkDescriptorSetLayoutBinding binding, Buffer& buffer);
+ void update_descriptor_set_image(VkDescriptorSet set, VkDescriptorSetLayoutBinding binding, VkImageView view);
// private:
vkcontext context;
diff --git a/include/vk-renderer.hpp b/include/vk-renderer.hpp
index c28049c..301aad2 100644
--- a/include/vk-renderer.hpp
+++ b/include/vk-renderer.hpp
@@ -22,21 +22,6 @@ class vkrenderer {
Buffer compute_shader_buffer;
private:
- void create_surface(window& wnd);
-
- void create_swapchain();
-
- void destroy_surface();
-
- void destroy_swapchain();
-
- void destroy_swapchain_images();
-
- void destroy_descriptor_sets();
-
- void update_descriptors_buffer();
-
- void update_descriptors_image();
void handle_swapchain_result(VkResult function_result);
@@ -57,10 +42,10 @@ class vkrenderer {
VkSurfaceFormatKHR surface_format;
VkSurfaceKHR platform_surface = VK_NULL_HANDLE;
- VkSwapchainKHR swapchain = VK_NULL_HANDLE;
- size_t swapchain_images_count = 3;
- std::vector<VkImage> swapchain_images;
- std::vector<VkImageView> swapchain_images_views;
+
+ Swapchain swapchain;
+
+ const uint32_t min_swapchain_image_count = 3;
uint32_t current_image_index;
};
diff --git a/src/vk-api.cpp b/src/vk-api.cpp
index 03532e0..84ac583 100644
--- a/src/vk-api.cpp
+++ b/src/vk-api.cpp
@@ -2,6 +2,7 @@
#include <memory>
#include "vk-api.hpp"
+#include "window.hpp"
#include "utils.hpp"
#define VKRESULT(result) assert(result == VK_SUCCESS);
@@ -31,7 +32,7 @@ vkapi::vkapi() {
VkDescriptorPoolCreateInfo descriptor_pool_create_info = {};
descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptor_pool_create_info.pNext = nullptr;
- descriptor_pool_create_info.flags = 0;
+ descriptor_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
descriptor_pool_create_info.maxSets = 0xff;
descriptor_pool_create_info.poolSizeCount = descriptor_pools_sizes.size();
descriptor_pool_create_info.pPoolSizes = descriptor_pools_sizes.data();
@@ -56,7 +57,7 @@ Buffer vkapi::create_buffer(size_t data_size, VkBufferUsageFlags buffer_usage, V
VmaAllocationCreateInfo alloc_create_info = {};
alloc_create_info.usage = mem_usage;
- vmaCreateBuffer(context.allocator, &buffer_info, &alloc_create_info, &buffer.vkbuffer, &buffer.alloc, nullptr);
+ vmaCreateBuffer(context.allocator, &buffer_info, &alloc_create_info, &buffer.handle, &buffer.alloc, nullptr);
vmaMapMemory(context.allocator, buffer.alloc, (void**) &buffer.mapped_ptr);
@@ -65,7 +66,76 @@ Buffer vkapi::create_buffer(size_t data_size, VkBufferUsageFlags buffer_usage, V
void vkapi::destroy_buffer(Buffer& buffer) {
vmaUnmapMemory(context.allocator, buffer.alloc);
- vmaDestroyBuffer(context.allocator, buffer.vkbuffer, buffer.alloc);
+ vmaDestroyBuffer(context.allocator, buffer.handle, buffer.alloc);
+}
+
+
+Image vkapi::create_image(VkExtent3D size, VkFormat format, VkImageUsageFlags usages) {
+ Image image;
+
+ image.subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ image.subresource_range.baseMipLevel = 0;
+ image.subresource_range.levelCount = 1;
+ image.subresource_range.baseArrayLayer = 0;
+ image.subresource_range.layerCount = 1;
+
+ VkImageCreateInfo img_create_info = {};
+ img_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+ img_create_info.pNext = VK_NULL_HANDLE;
+ img_create_info.flags = 0;
+ img_create_info.imageType = VK_IMAGE_TYPE_2D;
+ img_create_info.format = format;
+ img_create_info.extent = size;
+ img_create_info.mipLevels = 1;
+ img_create_info.arrayLayers = 1;
+ img_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
+ img_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
+ img_create_info.usage = usages;
+ img_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ img_create_info.queueFamilyIndexCount = 0;
+ img_create_info.pQueueFamilyIndices = nullptr;
+ img_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+
+ vkCreateImage(context.device, &img_create_info, VK_NULL_HANDLE, &image.handle);
+
+ VkImageViewCreateInfo image_view_create_info = {};
+ image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ image_view_create_info.pNext = nullptr;
+ image_view_create_info.flags = 0;
+ image_view_create_info.image = image.handle;
+ image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
+ image_view_create_info.format = format;
+ image_view_create_info.components = {
+ VK_COMPONENT_SWIZZLE_IDENTITY,
+ VK_COMPONENT_SWIZZLE_IDENTITY,
+ VK_COMPONENT_SWIZZLE_IDENTITY,
+ VK_COMPONENT_SWIZZLE_IDENTITY
+ };
+ image_view_create_info.subresourceRange = image.subresource_range;
+
+ vkCreateImage(context.device, &img_create_info, VK_NULL_HANDLE, &image.handle);
+
+ return std::move(image);
+}
+void vkapi::destroy_image(Image &image) {
+ vkDestroyImage(context.device, image.handle, nullptr);
+ vkDestroyImageView(context.device, image.view, nullptr);
+}
+
+std::vector<Image> vkapi::create_images(VkExtent3D size, VkFormat format, VkImageUsageFlags usages, size_t image_count) {
+ std::vector<Image> images { image_count };
+
+ for (size_t image_index = 0; image_index < image_count; image_index++) {
+ images[image_index] = create_image(size, format, usages);
+ }
+
+ return std::move(images);
+}
+
+void vkapi::destroy_images(std::vector<Image> &images) {
+ for (auto &image: images) {
+ destroy_image(image);
+ }
}
@@ -88,19 +158,14 @@ void vkapi::destroy_fence(VkFence fence) {
std::vector<VkFence> vkapi::create_fences(size_t fences_count) {
std::vector<VkFence> fences { fences_count };
- for(auto &fence: fences) {
- VkFenceCreateInfo create_info = {};
- create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
- create_info.pNext = nullptr;
- create_info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
-
- VKRESULT(vkCreateFence(context.device, &create_info, nullptr, &fence))
+ for(size_t fence_index = 0; fence_index < fences_count; fence_index++) {
+ fences[fence_index] = create_fence();
}
return std::move(fences);
}
-void vkapi::destroy_fences(std::vector<VkFence> fences) {
+void vkapi::destroy_fences(std::vector<VkFence> &fences) {
for(auto &fence: fences) {
vkDestroyFence(context.device, fence, nullptr);
}
@@ -126,13 +191,8 @@ void vkapi::destroy_semaphore(VkSemaphore semaphore) {
std::vector<VkSemaphore> vkapi::create_semaphores(size_t semaphores_count) {
std::vector<VkSemaphore> semaphores { semaphores_count };
- for (auto &semaphore: semaphores) {
- VkSemaphoreCreateInfo create_info = {};
- create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
- create_info.pNext = nullptr;
- create_info.flags = 0;
-
- VKRESULT(vkCreateSemaphore(context.device, &create_info, nullptr, &semaphore))
+ for (size_t semaphore_index = 0; semaphore_index < semaphores_count; semaphore_index++) {
+ semaphores[semaphore_index] = create_semaphore();
}
return std::move(semaphores);
@@ -159,7 +219,7 @@ std::vector<VkCommandBuffer> vkapi::create_command_buffers(size_t command_buffer
return std::move(command_buffers);
}
-void vkapi::destroy_command_buffers(std::vector<VkCommandBuffer> command_buffers) {
+void vkapi::destroy_command_buffers(std::vector<VkCommandBuffer> &command_buffers) {
vkFreeCommandBuffers(context.device, command_pool, command_buffers.size(), command_buffers.data());
}
@@ -224,7 +284,7 @@ ComputePipeline vkapi::create_compute_pipeline(const char* shader_path, std::vec
1,
&create_info,
nullptr,
- &pipeline.vkpipeline
+ &pipeline.handle
))
return std::move(pipeline);
@@ -234,7 +294,7 @@ void vkapi::destroy_compute_pipeline(ComputePipeline &pipeline) {
vkDestroyShaderModule(context.device, pipeline.shader_module, nullptr);
vkDestroyDescriptorSetLayout(context.device, pipeline.descriptor_set_layout, nullptr);
vkDestroyPipelineLayout(context.device, pipeline.layout, nullptr);
- vkDestroyPipeline(context.device, pipeline.vkpipeline, nullptr);
+ vkDestroyPipeline(context.device, pipeline.handle, nullptr);
}
@@ -254,6 +314,191 @@ std::vector<VkDescriptorSet> vkapi::create_descriptor_sets(VkDescriptorSetLayout
return std::move(descriptor_sets);
}
-void vkapi::destroy_descriptor_sets(std::vector<VkDescriptorSet> descriptor_sets) {
+void vkapi::destroy_descriptor_sets(std::vector<VkDescriptorSet> &descriptor_sets) {
vkFreeDescriptorSets(context.device, descriptor_pool, descriptor_sets.size(), descriptor_sets.data());
}
+
+
+VkSurfaceKHR vkapi::create_surface(window& wnd) {
+ VkSurfaceKHR surface;
+
+#if defined(LINUX)
+ 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(context.instance, &create_info, nullptr, &surface))
+#elif defined(WINDOWS)
+ VkWin32SurfaceCreateInfoKHR create_info = {};
+ create_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
+ create_info.pNext = nullptr;
+ create_info.flags = 0;
+ create_info.hinstance = GetModuleHandle(NULL);
+ create_info.hwnd = wnd.win_handle;
+
+ VKRESULT(vkCreateWin32SurfaceKHR(instance, &create_info, nullptr, &platform_surface))
+#endif
+
+ return surface;
+}
+
+void vkapi::destroy_surface(VkSurfaceKHR surface) {
+ vkDestroySurfaceKHR(context.instance, surface, nullptr);
+}
+
+
+Swapchain vkapi::create_swapchain(VkSurfaceKHR surface, size_t min_image_count, VkImageUsageFlags usages, std::optional<Swapchain> old_swapchain) {
+ Swapchain swapchain;
+ VkBool32 queue_support_presentation = VK_FALSE;
+ VKRESULT(vkGetPhysicalDeviceSurfaceSupportKHR(context.physical_device, context.queue_index, surface, &queue_support_presentation))
+
+ assert(queue_support_presentation == true);
+
+ VkSurfaceCapabilitiesKHR caps;
+ VKRESULT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(context.physical_device, surface, &caps))
+
+ VkExtent2D wantedExtent = caps.currentExtent;
+
+ if (wantedExtent.width < caps.minImageExtent.width) {
+ wantedExtent.width = caps.minImageExtent.width;
+ } else if (wantedExtent.width > caps.maxImageExtent.width) {
+ wantedExtent.width = caps.maxImageExtent.width;
+ }
+
+ if (wantedExtent.height < caps.minImageExtent.height) {
+ wantedExtent.height = caps.minImageExtent.height;
+ } else if (wantedExtent.height > caps.maxImageExtent.height) {
+ wantedExtent.height = caps.maxImageExtent.height;
+ }
+
+ uint32_t supported_formats_count = 0;
+ VKRESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(context.physical_device, surface, &supported_formats_count, VK_NULL_HANDLE))
+
+ std::vector<VkSurfaceFormatKHR> supported_formats { supported_formats_count };
+ VKRESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(context.physical_device, surface, &supported_formats_count, supported_formats.data()))
+
+ uint32_t supported_present_modes_count = 0;
+ VKRESULT(vkGetPhysicalDeviceSurfacePresentModesKHR(context.physical_device, surface, &supported_present_modes_count, VK_NULL_HANDLE))
+
+ std::vector<VkPresentModeKHR> supported_present_modes { supported_present_modes_count };
+ VKRESULT(vkGetPhysicalDeviceSurfacePresentModesKHR(context.physical_device, surface, &supported_present_modes_count, supported_present_modes.data()))
+
+ VkSurfaceFormatKHR surface_format = supported_formats[0];
+ VkSwapchainKHR old_swapchain_handle = (old_swapchain != std::nullopt) ? old_swapchain.value().handle : VK_NULL_HANDLE;
+
+ VkSwapchainCreateInfoKHR create_info = {};
+ create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+ create_info.pNext = nullptr;
+ create_info.flags = 0;
+ create_info.surface = surface;
+ create_info.minImageCount = min_image_count;
+ create_info.imageFormat = surface_format.format;
+ create_info.imageColorSpace = surface_format.colorSpace;
+ create_info.imageExtent = wantedExtent;
+ create_info.imageArrayLayers = 1;
+ create_info.imageUsage = usages;
+ 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 = old_swapchain_handle;
+
+ VKRESULT(vkCreateSwapchainKHR(context.device, &create_info, nullptr, &swapchain.handle))
+
+ if (old_swapchain != std::nullopt) {
+ destroy_swapchain(old_swapchain.value());
+ }
+
+ VKRESULT(vkGetSwapchainImagesKHR(context.device, swapchain.handle, (uint32_t*)&swapchain.image_count, VK_NULL_HANDLE))
+
+ swapchain.images = std::vector<Image>{ swapchain.image_count };
+ auto images = std::vector<VkImage>{ swapchain.image_count };
+ auto views = std::vector<VkImageView>{ swapchain.image_count };
+
+ VKRESULT(vkGetSwapchainImagesKHR(context.device, swapchain.handle, (uint32_t*)&swapchain.image_count, images.data()))
+
+ VkImageSubresourceRange image_subresource_range = {};
+ image_subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ image_subresource_range.baseMipLevel = 0;
+ image_subresource_range.levelCount = 1;
+ image_subresource_range.baseArrayLayer = 0;
+ image_subresource_range.layerCount = 1;
+
+ for (size_t image_index = 0; image_index < swapchain.image_count; image_index++) {
+ swapchain.images[image_index].handle = images[image_index];
+ swapchain.images[image_index].subresource_range = image_subresource_range;
+
+ VkImageViewCreateInfo image_view_create_info = {};
+ image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ image_view_create_info.pNext = nullptr;
+ image_view_create_info.flags = 0;
+ image_view_create_info.image = swapchain.images[image_index].handle;
+ image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
+ image_view_create_info.format = surface_format.format;
+ image_view_create_info.components = {
+ VK_COMPONENT_SWIZZLE_IDENTITY,
+ VK_COMPONENT_SWIZZLE_IDENTITY,
+ VK_COMPONENT_SWIZZLE_IDENTITY,
+ VK_COMPONENT_SWIZZLE_IDENTITY
+ };
+ image_view_create_info.subresourceRange = image_subresource_range;
+
+ VKRESULT(vkCreateImageView(context.device, &image_view_create_info, nullptr, &swapchain.images[image_index].view))
+ }
+
+ return std::move(swapchain);
+}
+
+void vkapi::destroy_swapchain(Swapchain swapchain) {
+ for(auto &image: swapchain.images) {
+ vkDestroyImageView(context.device, image.view, nullptr);
+ }
+ vkDestroySwapchainKHR(context.device, swapchain.handle, nullptr);
+}
+
+
+void vkapi::update_descriptor_set_buffer(VkDescriptorSet set, VkDescriptorSetLayoutBinding binding,Buffer& buffer) {
+ VkDescriptorBufferInfo descriptor_buffer_info = {};
+ descriptor_buffer_info.buffer = buffer.handle;
+ descriptor_buffer_info.offset = 0;
+ descriptor_buffer_info.range = VK_WHOLE_SIZE;
+
+ VkWriteDescriptorSet write_descriptor = {};
+ write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ write_descriptor.pNext = nullptr;
+ write_descriptor.dstSet = set;
+ write_descriptor.dstBinding = 0;
+ write_descriptor.dstArrayElement = 0;
+ write_descriptor.descriptorCount = 1;
+ write_descriptor.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ write_descriptor.pImageInfo = VK_NULL_HANDLE;
+ write_descriptor.pBufferInfo = &descriptor_buffer_info;
+ write_descriptor.pTexelBufferView = VK_NULL_HANDLE;
+
+ vkUpdateDescriptorSets(context.device, 1, &write_descriptor, 0, nullptr);
+}
+
+void vkapi::update_descriptor_set_image(VkDescriptorSet set, VkDescriptorSetLayoutBinding binding, VkImageView view) {
+ VkDescriptorImageInfo descriptor_image_info = {};
+ descriptor_image_info.sampler = VK_NULL_HANDLE;
+ descriptor_image_info.imageView = view;
+ descriptor_image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
+
+ VkWriteDescriptorSet write_descriptor = {};
+ write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ write_descriptor.pNext = nullptr;
+ write_descriptor.dstSet = set;
+ write_descriptor.dstBinding = 1;
+ write_descriptor.dstArrayElement = 0;
+ write_descriptor.descriptorCount = binding.descriptorCount;
+ write_descriptor.descriptorType = binding.descriptorType;
+ write_descriptor.pImageInfo = &descriptor_image_info;
+ write_descriptor.pBufferInfo = VK_NULL_HANDLE;
+ write_descriptor.pTexelBufferView = VK_NULL_HANDLE;
+
+ vkUpdateDescriptorSets(context.device, 1, &write_descriptor, 0, nullptr);
+}
diff --git a/src/vk-renderer.cpp b/src/vk-renderer.cpp
index 0fe2a8d..a8baa38 100644
--- a/src/vk-renderer.cpp
+++ b/src/vk-renderer.cpp
@@ -12,8 +12,13 @@
#define VKRESULT(result) assert(result == VK_SUCCESS);
vkrenderer::vkrenderer(window& wnd, const input_data& inputs) {
-
- create_surface(wnd);
+ platform_surface = api.create_surface(wnd);
+ swapchain = api.create_swapchain(
+ platform_surface,
+ min_swapchain_image_count,
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
+ std::nullopt
+ );
std::vector<VkDescriptorSetLayoutBinding> bindings {
{
@@ -34,21 +39,22 @@ vkrenderer::vkrenderer(window& wnd, const input_data& inputs) {
compute_pipeline = api.create_compute_pipeline("./shaders/compute.comp.spv", bindings);
- create_swapchain();
+ command_buffers = api.create_command_buffers(swapchain.image_count);
- command_buffers = api.create_command_buffers(swapchain_images_count);
+ compute_shader_sets = api.create_descriptor_sets(compute_pipeline.descriptor_set_layout, swapchain.image_count);
- compute_shader_sets = api.create_descriptor_sets(compute_pipeline.descriptor_set_layout, swapchain_images_count);
-
- submission_fences = api.create_fences(swapchain_images_count);
- execution_semaphores = api.create_semaphores(swapchain_images_count);
- acquire_semaphores = api.create_semaphores(swapchain_images_count);
+ submission_fences = api.create_fences(swapchain.image_count);
+ execution_semaphores = api.create_semaphores(swapchain.image_count);
+ acquire_semaphores = api.create_semaphores(swapchain.image_count);
compute_shader_buffer = api.create_buffer(sizeof(inputs), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
std::memcpy(compute_shader_buffer.mapped_ptr, &inputs, sizeof(inputs));
- update_descriptors_buffer();
- update_descriptors_image();
+ size_t image_index = 0;
+ for (auto& set: compute_shader_sets) {
+ api.update_descriptor_set_buffer(set, bindings[0], compute_shader_buffer);
+ api.update_descriptor_set_image(set, bindings[1], swapchain.images[image_index].view);
+ }
}
vkrenderer::~vkrenderer() {
@@ -59,19 +65,20 @@ vkrenderer::~vkrenderer() {
api.destroy_semaphores(execution_semaphores);
api.destroy_semaphores(acquire_semaphores);
- destroy_descriptor_sets();
+ api.destroy_descriptor_sets(compute_shader_sets);
api.destroy_command_buffers(command_buffers);
+ api.destroy_compute_pipeline(compute_pipeline);
- destroy_swapchain();
- destroy_surface();
+ api.destroy_swapchain(swapchain);
+ api.destroy_surface(platform_surface);
}
void vkrenderer::compute(uint32_t width, uint32_t height) {
VKRESULT(vkWaitForFences(api.context.device, 1, &submission_fences[frame_index], VK_TRUE, UINT64_MAX))
VKRESULT(vkResetFences(api.context.device, 1, &submission_fences[frame_index]))
- auto acquire_result = vkAcquireNextImageKHR(api.context.device, swapchain, UINT64_MAX, acquire_semaphores[frame_index], VK_NULL_HANDLE, &current_image_index);
+ auto acquire_result = vkAcquireNextImageKHR(api.context.device, swapchain.handle, UINT64_MAX, acquire_semaphores[frame_index], VK_NULL_HANDLE, &current_image_index);
handle_swapchain_result(acquire_result);
VkCommandBufferBeginInfo cmd_buf_begin_info = {};
@@ -98,7 +105,7 @@ void vkrenderer::compute(uint32_t width, uint32_t height) {
undefined_to_general_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
undefined_to_general_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
undefined_to_general_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- undefined_to_general_barrier.image = swapchain_images[current_image_index];
+ undefined_to_general_barrier.image = swapchain.images[current_image_index].handle;
undefined_to_general_barrier.subresourceRange = image_subresource_range;
vkCmdPipelineBarrier(
@@ -116,7 +123,7 @@ void vkrenderer::compute(uint32_t width, uint32_t height) {
vkCmdBindDescriptorSets(command_buffers[frame_index], VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipeline.layout, 0, 1, &compute_shader_sets[current_image_index], 0, nullptr);
- vkCmdBindPipeline(command_buffers[frame_index], VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipeline.vkpipeline);
+ vkCmdBindPipeline(command_buffers[frame_index], VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipeline.handle);
vkCmdDispatch(command_buffers[frame_index], width / 8, height / 8, 1);
@@ -129,7 +136,7 @@ void vkrenderer::compute(uint32_t width, uint32_t height) {
general_to_present_barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
general_to_present_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
general_to_present_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- general_to_present_barrier.image = swapchain_images[current_image_index];
+ general_to_present_barrier.image = swapchain.images[current_image_index].handle;
general_to_present_barrier.subresourceRange = image_subresource_range;
vkCmdPipelineBarrier(
@@ -168,7 +175,7 @@ void vkrenderer::compute(uint32_t width, uint32_t height) {
present_info.waitSemaphoreCount = 1;
present_info.pWaitSemaphores = &execution_semaphores[frame_index];
present_info.swapchainCount = 1;
- present_info.pSwapchains = &swapchain;
+ present_info.pSwapchains = &swapchain.handle;
present_info.pImageIndices = &current_image_index;
present_info.pResults = nullptr;
@@ -177,210 +184,25 @@ void vkrenderer::compute(uint32_t width, uint32_t height) {
VKRESULT(vkWaitForFences(api.context.device, 1, &submission_fences[frame_index], VK_TRUE, UINT64_MAX))
- frame_index = ++frame_index % swapchain_images_count;
+ frame_index = ++frame_index % swapchain.image_count;
}
void vkrenderer::recreate_swapchain() {
VKRESULT(vkWaitForFences(api.context.device, 1, &submission_fences[frame_index], VK_TRUE, UINT64_MAX))
- destroy_swapchain_images();
-
- create_swapchain();
-
- update_descriptors_image();
-}
-
-
-void vkrenderer::create_surface(window& wnd) {
-#if defined(LINUX)
- 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(api.context.instance, &create_info, nullptr, &platform_surface))
-#elif defined(WINDOWS)
- VkWin32SurfaceCreateInfoKHR create_info = {};
- create_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
- create_info.pNext = nullptr;
- create_info.flags = 0;
- create_info.hinstance = GetModuleHandle(NULL);
- create_info.hwnd = wnd.win_handle;
-
- VKRESULT(vkCreateWin32SurfaceKHR(instance, &create_info, nullptr, &platform_surface))
-#endif
-}
-
-void vkrenderer::create_swapchain() {
- VkBool32 queue_support_presentation = VK_FALSE;
- VKRESULT(vkGetPhysicalDeviceSurfaceSupportKHR(api.context.physical_device, api.context.queue_index, platform_surface, &queue_support_presentation))
-
- VkSurfaceCapabilitiesKHR caps;
- VKRESULT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(api.context.physical_device, platform_surface, &caps))
-
- VkExtent2D wantedExtent = caps.currentExtent;
-
- if (wantedExtent.width < caps.minImageExtent.width) {
- wantedExtent.width = caps.minImageExtent.width;
- } else if (wantedExtent.width > caps.maxImageExtent.width) {
- wantedExtent.width = caps.maxImageExtent.width;
- }
-
- if (wantedExtent.height < caps.minImageExtent.height) {
- wantedExtent.height = caps.minImageExtent.height;
- } else if (wantedExtent.height > caps.maxImageExtent.height) {
- wantedExtent.height = caps.maxImageExtent.height;
- }
-
- uint32_t supported_formats_count = 0;
- VKRESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(api.context.physical_device, platform_surface, &supported_formats_count, VK_NULL_HANDLE))
-
- std::vector<VkSurfaceFormatKHR> supported_formats { supported_formats_count };
- VKRESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(api.context.physical_device, platform_surface, &supported_formats_count, supported_formats.data()))
-
- uint32_t supported_present_modes_count = 0;
- VKRESULT(vkGetPhysicalDeviceSurfacePresentModesKHR(api.context.physical_device, platform_surface, &supported_present_modes_count, VK_NULL_HANDLE))
-
- std::vector<VkPresentModeKHR> supported_present_modes { supported_present_modes_count };
- VKRESULT(vkGetPhysicalDeviceSurfacePresentModesKHR(api.context.physical_device, platform_surface, &supported_present_modes_count, supported_present_modes.data()))
-
- surface_format = supported_formats[0];
-
- VkSwapchainKHR old_swapchain = swapchain;
-
- 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 = surface_format.format;
- create_info.imageColorSpace = surface_format.colorSpace;
- create_info.imageExtent = wantedExtent;
- 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 = old_swapchain;
-
- VKRESULT(vkCreateSwapchainKHR(api.context.device, &create_info, nullptr, &swapchain))
-
- if (old_swapchain != VK_NULL_HANDLE) {
- vkDestroySwapchainKHR(api.context.device, old_swapchain, nullptr);
- }
-
- swapchain_images_count = 0;
- VKRESULT(vkGetSwapchainImagesKHR(api.context.device, swapchain, (uint32_t*)&swapchain_images_count, VK_NULL_HANDLE))
-
- swapchain_images = std::vector<VkImage>{ swapchain_images_count };
- swapchain_images_views = std::vector<VkImageView>{ swapchain_images_count };
- VKRESULT(vkGetSwapchainImagesKHR(api.context.device, swapchain, (uint32_t*)&swapchain_images_count, swapchain_images.data()))
-
- for (size_t index = 0; index < swapchain_images_count; index++) {
- VkImageSubresourceRange image_subresource_range = {};
- image_subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- image_subresource_range.baseMipLevel = 0;
- image_subresource_range.levelCount = 1;
- image_subresource_range.baseArrayLayer = 0;
- image_subresource_range.layerCount = 1;
-
- VkImageViewCreateInfo image_view_create_info = {};
- image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
- image_view_create_info.pNext = nullptr;
- image_view_create_info.flags = 0;
- image_view_create_info.image = swapchain_images[index];
- image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
- image_view_create_info.format = surface_format.format;
- image_view_create_info.components = {
- VK_COMPONENT_SWIZZLE_IDENTITY,
- VK_COMPONENT_SWIZZLE_IDENTITY,
- VK_COMPONENT_SWIZZLE_IDENTITY,
- VK_COMPONENT_SWIZZLE_IDENTITY
- };
- image_view_create_info.subresourceRange = image_subresource_range;
+ swapchain = api.create_swapchain(platform_surface, 3, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, std::optional<Swapchain> { swapchain });
- VKRESULT(vkCreateImageView(api.context.device, &image_view_create_info, nullptr, &swapchain_images_views[index]))
- }
-}
-
-void vkrenderer::destroy_surface() {
- vkDestroySurfaceKHR(api.context.instance, platform_surface, nullptr);
-}
-
-void vkrenderer::destroy_swapchain() {
- vkDestroySwapchainKHR(api.context.device, swapchain, nullptr);
-
- destroy_swapchain_images();
-}
-
-void vkrenderer::destroy_swapchain_images() {
- for (auto view: swapchain_images_views) {
- vkDestroyImageView(api.context.device, view, nullptr);
- }
-
- swapchain_images_views.clear();
- swapchain_images.clear();
-}
-
-void vkrenderer::destroy_descriptor_sets() {
- // vkFreeDescriptorSets(device, descriptor_pool, swapchain_images_count, compute_shader_sets.data());
-
- vkDestroyDescriptorPool(api.context.device, descriptor_pool, nullptr);
-}
-
-void vkrenderer::update_descriptors_buffer() {
- std::vector<VkDescriptorBufferInfo> descriptors_buf_info { swapchain_images_count };
- std::vector<VkWriteDescriptorSet> write_descriptors { swapchain_images_count };
-
- for (size_t set_index = 0; set_index < swapchain_images_count; set_index++) {
- // Update uniform buffer descriptor
- descriptors_buf_info[set_index].buffer = compute_shader_buffer.vkbuffer;
- descriptors_buf_info[set_index].offset = 0;
- descriptors_buf_info[set_index].range = VK_WHOLE_SIZE;
-
- write_descriptors[set_index].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- write_descriptors[set_index].pNext = nullptr;
- write_descriptors[set_index].dstSet = compute_shader_sets[set_index];
- write_descriptors[set_index].dstBinding = 0;
- write_descriptors[set_index].dstArrayElement = 0;
- write_descriptors[set_index].descriptorCount = 1;
- write_descriptors[set_index].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
- write_descriptors[set_index].pImageInfo = VK_NULL_HANDLE;
- write_descriptors[set_index].pBufferInfo = &descriptors_buf_info[set_index];
- write_descriptors[set_index].pTexelBufferView = VK_NULL_HANDLE;
- }
-
- vkUpdateDescriptorSets(api.context.device, write_descriptors.size(), write_descriptors.data(), 0, nullptr);
-}
-
-void vkrenderer::update_descriptors_image() {
- std::vector<VkDescriptorImageInfo> descriptors_image_info { swapchain_images_count };
- std::vector<VkWriteDescriptorSet> write_descriptors { swapchain_images_count };
-
- for (size_t set_index = 0; set_index < swapchain_images_count; set_index++) {
- // Update storage image descriptor
- descriptors_image_info[set_index].sampler = VK_NULL_HANDLE;
- descriptors_image_info[set_index].imageView = swapchain_images_views[set_index];
- descriptors_image_info[set_index].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
-
- write_descriptors[set_index].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- write_descriptors[set_index].pNext = nullptr;
- write_descriptors[set_index].dstSet = compute_shader_sets[set_index];
- write_descriptors[set_index].dstBinding = 1;
- write_descriptors[set_index].dstArrayElement = 0;
- write_descriptors[set_index].descriptorCount = 1;
- write_descriptors[set_index].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
- write_descriptors[set_index].pImageInfo = &descriptors_image_info[set_index];
- write_descriptors[set_index].pBufferInfo = VK_NULL_HANDLE;
- write_descriptors[set_index].pTexelBufferView = VK_NULL_HANDLE;
+ VkDescriptorSetLayoutBinding binding {
+ .binding = 1,
+ .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
+ .descriptorCount = 1,
+ .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
+ .pImmutableSamplers = VK_NULL_HANDLE,
+ };
+ size_t image_index = 0;
+ for (auto& set: compute_shader_sets) {
+ api.update_descriptor_set_image(set, binding, swapchain.images[image_index].view);
}
-
- vkUpdateDescriptorSets(api.context.device, write_descriptors.size(), write_descriptors.data(), 0, nullptr);
}
void vkrenderer::handle_swapchain_result(VkResult function_result) {