aboutsummaryrefslogtreecommitdiffstats
path: root/include/api-test
diff options
context:
space:
mode:
Diffstat (limited to 'include/api-test')
-rw-r--r--include/api-test/buffer.hpp7
-rw-r--r--include/api-test/command-buffer.hpp37
-rw-r--r--include/api-test/freelist.hpp43
-rw-r--r--include/api-test/texture.hpp12
-rw-r--r--include/api-test/vk-bindless.hpp61
-rw-r--r--include/api-test/vk-device-types.hpp70
-rw-r--r--include/api-test/vk-device.hpp138
-rw-r--r--include/api-test/vk-utils.hpp11
8 files changed, 278 insertions, 101 deletions
diff --git a/include/api-test/buffer.hpp b/include/api-test/buffer.hpp
index 500e15b..64c4881 100644
--- a/include/api-test/buffer.hpp
+++ b/include/api-test/buffer.hpp
@@ -6,13 +6,6 @@
#include "handle.hpp"
-struct buffer_desc {
- size_t size;
- VkBufferUsageFlags usages;
- VkMemoryPropertyFlags memory_properties;
- uint32_t memory_usage;
-};
-
struct device_buffer;
class buffer {
diff --git a/include/api-test/command-buffer.hpp b/include/api-test/command-buffer.hpp
index 140a291..1a0e553 100644
--- a/include/api-test/command-buffer.hpp
+++ b/include/api-test/command-buffer.hpp
@@ -6,6 +6,8 @@
#include "handle.hpp"
+#include "vec3.hpp"
+
enum class QueueType : uint32_t {
GRAPHICS,
ASYNC_COMPUTE,
@@ -14,31 +16,36 @@ enum class QueueType : uint32_t {
};
-struct device_buffer;
struct device_texture;
+struct device_buffer;
+struct device_pipeline;
+
+struct dispatch_params {
+ handle<device_pipeline> pipeline;
+ vec3u group_size;
+ vec3u local_group_size;
+};
struct command_buffer {
- void start() const;
- void stop() const;
+ void start() const;
+ void stop() const;
+
+ void barrier(handle<device_texture> texture_handle, VkPipelineStageFlags2 stage, VkAccessFlags2 access, VkImageLayout layout) const;
- void barrier();
+ void copy(handle<device_buffer> buffer_handle, handle<device_texture> texture_handle, VkDeviceSize offset = 0) const;
- VkCommandBuffer handle;
+ VkCommandBuffer vk_command_buffer;
QueueType queue_type;
};
-struct graphics_command_buffer : public command_buffer {
- void set_pipeline();
-
- void dispatch();
+// General purpose queue
+struct graphics_command_buffer: public command_buffer {
+ void dispatch(const dispatch_params& params);
};
-struct compute_command_buffer : public command_buffer {
- void set_pipeline();
-
- void dispatch();
+struct compute_command_buffer: public command_buffer {
+ void dispatch(const dispatch_params& params);
};
-struct transfer_command_buffer : public command_buffer {
- void copy(::handle<device_buffer> buffer_handle, ::handle<device_texture> texture_handle);
+struct transfer_command_buffer: public command_buffer {
};
diff --git a/include/api-test/freelist.hpp b/include/api-test/freelist.hpp
index e5af6f5..9553a15 100644
--- a/include/api-test/freelist.hpp
+++ b/include/api-test/freelist.hpp
@@ -1,32 +1,57 @@
#include <numeric>
#include <vector>
-template<typename T, const size_t initial_size = 1024U>
+
+static constexpr uint32_t default_element_count = 1024U;
+
+template<typename T, const size_t initial_size = default_element_count>
class freelist {
public:
freelist()
- : holes(initial_size),
+ : free(initial_size),
items(initial_size) {
- std::iota(holes.begin(), holes.end(), 0);
+ std::iota(free.rbegin(), free.rend(), 0);
}
uint32_t add(const T& item) {
- const auto id = holes.back();
- holes.pop_back();
+ const auto id = free.back();
+ free.pop_back();
- items[id] = std::move(item);
+ items[id] = item;
return id;
}
void remove(uint32_t item_id) {
- holes.push_back(item_id);
+ free.push_back(item_id);
}
- const T& operator[](uint32_t index) {
+ T& operator[](uint32_t index) {
return items[index];
}
+ uint32_t find(const T& seeked_item) {
+ for (auto index { 0U }; index < items.size(); index++) {
+ const auto& item = items[index];
+ if (memcmp(&item, &seeked_item, sizeof(T)) == 0) {
+ return index;
+ }
+ }
+
+ return invalid_handle;
+ }
+
+ auto begin() {
+ return items.begin();
+ }
+
+ auto end() {
+ return items.end();
+ }
+
+ static constexpr uint32_t invalid_handle = -1;
+
+private:
std::vector<T> items;
- std::vector<uint32_t> holes;
+ std::vector<uint32_t> free;
};
diff --git a/include/api-test/texture.hpp b/include/api-test/texture.hpp
index 9632c5e..59bfec1 100644
--- a/include/api-test/texture.hpp
+++ b/include/api-test/texture.hpp
@@ -6,18 +6,6 @@
#include "handle.hpp"
-struct texture_desc {
- uint32_t width = 1U;
- uint32_t height = 1U;
- uint32_t depth = 1U;
- uint32_t mips = 1U;
- VkImageUsageFlags usages;
- VkFormat format;
- VkImageType type;
-
- static constexpr auto max_mips = 16U;
-};
-
struct device_texture;
class texture {
diff --git a/include/api-test/vk-bindless.hpp b/include/api-test/vk-bindless.hpp
new file mode 100644
index 0000000..d8fac3c
--- /dev/null
+++ b/include/api-test/vk-bindless.hpp
@@ -0,0 +1,61 @@
+#pragma once
+
+#include <cstdint>
+
+#include <vulkan/vulkan_core.h>
+
+enum BindlessSetType : uint32_t {
+ GLOBAL,
+ MAX,
+};
+
+enum SamplerType : uint32_t {
+ NEAREST,
+ LINEAR,
+ MAX_SAMPLER,
+};
+
+struct bindless_model {
+#ifndef USE_VK_DESCRIPTOR_BUFFERS
+ VkPipelineLayout layout;
+ VkDescriptorSetLayout sets_layout[BindlessSetType::MAX];
+ VkDescriptorSet sets[BindlessSetType::MAX];
+ VkDescriptorPool descriptor_pool;
+
+ static constexpr size_t descriptor_pool_allocable_sets_count = 64U;
+ static constexpr uint32_t set_descriptors_count[BindlessSetType::MAX]{ 1024U };
+
+ static bindless_model create_bindless_model(VkDevice device);
+
+ static void destroy_bindless_model(VkDevice device, bindless_model& bindless);
+
+ private:
+ void create_layout(VkDevice device);
+ void create_descriptor_pool(VkDevice device);
+ void allocate_sets(VkDevice device);
+
+ void destroy_descriptor_pool(VkDevice device);
+
+ void create_immutable_samplers(VkDevice device);
+
+ void destroy_immutable_samplers(VkDevice device);
+
+ VkSampler samplers[SamplerType::MAX_SAMPLER];
+#else
+ VkPipelineLayout layout;
+ VkDescriptorSetLayout sets_layout[BindlessSetType::MAX];
+
+ static constexpr size_t descriptor_pool_allocable_sets_count = 64U;
+ static constexpr uint32_t set_descriptors_count[BindlessSetType::MAX]{ 1024U };
+
+ static bindless_model create_bindless_model(VkDevice device);
+
+ static void destroy_bindless_model(VkDevice device, bindless_model& bindless);
+
+ private:
+ void create_layout(VkDevice device);
+
+ handle<device_buffer> storage_image_descriptors;
+ handle<device_buffer> sampled_image_descriptors;
+#endif
+};
diff --git a/include/api-test/vk-device-types.hpp b/include/api-test/vk-device-types.hpp
new file mode 100644
index 0000000..33a7738
--- /dev/null
+++ b/include/api-test/vk-device-types.hpp
@@ -0,0 +1,70 @@
+#pragma once
+
+#include <vulkan/vulkan_core.h>
+
+#include <span>
+
+#include "vk-bindless.hpp"
+
+using VmaAllocation = struct VmaAllocation_T*;
+
+struct texture_desc {
+ uint32_t width = 1U;
+ uint32_t height = 1U;
+ uint32_t depth = 1U;
+ uint32_t mips = 1U;
+ VkImageUsageFlags usages;
+ VkFormat format;
+ VkImageType type;
+
+ static constexpr auto max_mips = 16U;
+};
+
+struct device_texture {
+ VkImage vk_image;
+ VkImageView whole_view;
+ VkImageView mips_views[texture_desc::max_mips] = { VK_NULL_HANDLE };
+ VkImageLayout layout;
+ VkPipelineStageFlags2 stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ VkAccessFlags2 access = VK_ACCESS_2_NONE;
+
+ uint32_t storage_index = -1;
+ uint32_t sampled_index = -1;
+ uint32_t sampler_index = -1;
+
+ VmaAllocation alloc;
+
+ texture_desc desc;
+};
+
+
+struct buffer_desc {
+ size_t size;
+ VkBufferUsageFlags usages;
+ VkMemoryPropertyFlags memory_properties;
+ uint32_t memory_usage;
+};
+
+struct device_buffer {
+ VkBuffer vk_buffer;
+ VmaAllocation alloc;
+ VkDeviceAddress device_address;
+ void* mapped_ptr;
+
+ buffer_desc desc;
+};
+
+
+struct pipeline_desc {
+ std::span<uint8_t> vs_code;
+ std::span<uint8_t> fs_code;
+ std::span<uint8_t> cs_code;
+};
+
+struct device_pipeline {
+ VkPipeline vk_pipeline;
+ VkPipelineBindPoint bind_point;
+ pipeline_desc desc;
+
+ bindless_model* bindless = nullptr;
+};
diff --git a/include/api-test/vk-device.hpp b/include/api-test/vk-device.hpp
index f010cc5..b09ed9e 100644
--- a/include/api-test/vk-device.hpp
+++ b/include/api-test/vk-device.hpp
@@ -1,115 +1,137 @@
#pragma once
#include <cstdint>
+#include <span>
#include <vulkan/vulkan_core.h>
-#include "handle.hpp"
-#include "freelist.hpp"
-#include "texture.hpp"
-#include "buffer.hpp"
#include "command-buffer.hpp"
+#include "freelist.hpp"
+#include "handle.hpp"
+#include "vk-bindless.hpp"
+#include "vk-device-types.hpp"
using VmaAllocator = struct VmaAllocator_T*;
-using VmaAllocation = struct VmaAllocation_T*;
-
-struct device_texture {
- VkImage handle;
- VkImageView whole_view;
- VkImageView mips_views[texture_desc::max_mips] = { VK_NULL_HANDLE };
- VmaAllocation alloc;
-
- texture_desc desc;
-};
-
-struct device_buffer {
- VkBuffer handle;
- VmaAllocation alloc;
- VkDeviceAddress device_address;
- void* mapped_ptr;
-
- buffer_desc desc;
-};
class window;
class vkdevice {
struct queue {
- VkQueue handle;
- uint32_t index;
- VkQueueFlags usages;
- VkCommandPool command_pool;
+ VkQueue vk_queue;
+ uint32_t index;
+ VkQueueFlags usages;
+ VkCommandPool command_pool;
};
-public:
+ public:
+ static vkdevice* init_device(const window& window);
- vkdevice(const window& window);
+ static void free_device();
+
+ static inline vkdevice* get_device() {
+ return render_device;
+ }
+
+ handle<device_texture> create_texture(const texture_desc& desc);
+
+ handle<device_buffer> create_buffer(const buffer_desc& desc);
- handle<device_texture> create_texture(const texture_desc& desc);
+ handle<device_pipeline> create_pipeline(const pipeline_desc& desc);
- handle<device_buffer> create_buffer(const buffer_desc& desc);
+ void destroy_texture(const device_texture& texture);
+ void destroy_texture(handle<device_texture> handle);
+
+ void destroy_buffer(const device_buffer& buffer);
+ void destroy_buffer(handle<device_buffer> handle);
+
+ void destroy_pipeline(const device_pipeline& pipeline);
+ void destroy_pipeline(handle<device_pipeline> handle);
template<typename cmd_buf_type>
void allocate_command_buffers(cmd_buf_type* buffers, size_t count, QueueType queue_type) {
- allocate_command_buffers(buffers, count, queue_type);
+ allocate_command_buffers(static_cast<command_buffer*>(buffers), count, queue_type);
}
- const device_texture& get_texture(handle<device_texture> handle) {
+ inline device_texture& get_texture(handle<device_texture> handle) {
return textures[handle.id];
}
- const device_buffer& get_buffer(handle<device_buffer> handle) {
+ inline const device_buffer& get_buffer(handle<device_buffer> handle) {
return buffers[handle.id];
}
+ inline const device_pipeline& get_pipeline(handle<device_pipeline> handle) {
+ return pipelines[handle.id];
+ }
+
+ inline const bindless_model& get_bindingmodel() {
+ return bindless;
+ }
+
void submit(command_buffer* buffers, size_t count);
-private:
+ void present();
+
+ private:
+ vkdevice(const window& window);
+ ~vkdevice();
void allocate_command_buffers(command_buffer* buffers, size_t count, QueueType type);
void create_views(device_texture& texture);
- void create_surface(const window& window);
+ // Presentation stuff
+ void create_surface(const window& window);
- void create_swapchain();
+ void create_swapchain();
- VkSurfaceKHR surface;
- VkSwapchainKHR swapchain;
+ void create_virtual_frames();
- // TODO: Wrap in a struct called adapter ?
- void create_instance();
+ VkSurfaceKHR surface = nullptr;
+ VkSwapchainKHR swapchain = nullptr;
- void create_device();
+ // TODO: Wrap in a struct called adapter ?
+ void create_instance();
- void create_memory_allocator();
+ void create_device();
- void create_command_pools();
+ void create_memory_allocator();
- void pick_physical_device();
+ void create_command_pools();
- [[nodiscard]] uint32_t pick_queue(VkQueueFlags usages) const;
+ void pick_physical_device();
static bool device_support_features(VkPhysicalDevice physical_dev);
- void create_debug_layer_callback();
+ void create_debug_layer_callback();
+
+ // Virtual frames resources
+ static constexpr uint32_t virtual_frames_count = 3U;
+ VkSemaphore semaphores[virtual_frames_count];
+
+ queue queues[static_cast<uint32_t>(QueueType::MAX)];
+ VkInstance instance;
+ VkPhysicalDevice physical_device;
+ VkDevice device;
- queue queues[static_cast<uint32_t>(QueueType::MAX)];
+ VmaAllocator gpu_allocator;
- VkInstance instance;
- VkPhysicalDevice physical_device;
- VkDevice device;
+ bindless_model bindless;
- VmaAllocator gpu_allocator;
+ static constexpr size_t max_allocable_command_buffers = 16;
+ static constexpr size_t max_submitable_command_buffers = 16;
- static constexpr size_t max_allocable_command_buffers = 16;
- static constexpr size_t max_submitable_command_buffers = 16;
+ freelist<device_texture*> storage_indices;
+ freelist<device_texture*> sampled_indices;
+
+ freelist<device_texture> textures;
+ freelist<device_buffer> buffers;
+ freelist<device_pipeline> pipelines;
+
+ static vkdevice* render_device;
#ifdef _DEBUG
- VkDebugUtilsMessengerEXT debug_messenger;
+ VkDebugUtilsMessengerEXT debug_messenger;
#endif // _DEBUG
-
- freelist<device_texture> textures;
- freelist<device_buffer> buffers;
};
diff --git a/include/api-test/vk-utils.hpp b/include/api-test/vk-utils.hpp
new file mode 100644
index 0000000..fb02737
--- /dev/null
+++ b/include/api-test/vk-utils.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <cassert>
+
+#include <vulkan/vulkan_core.h>
+
+#ifdef _DEBUG
+#define VKCHECK(result) assert((result) == VK_SUCCESS)
+#else
+#define VKCHECK(result) (result)
+#endif