diff options
Diffstat (limited to 'include/api-test')
| -rw-r--r-- | include/api-test/buffer.hpp | 7 | ||||
| -rw-r--r-- | include/api-test/command-buffer.hpp | 37 | ||||
| -rw-r--r-- | include/api-test/freelist.hpp | 43 | ||||
| -rw-r--r-- | include/api-test/texture.hpp | 12 | ||||
| -rw-r--r-- | include/api-test/vk-bindless.hpp | 61 | ||||
| -rw-r--r-- | include/api-test/vk-device-types.hpp | 70 | ||||
| -rw-r--r-- | include/api-test/vk-device.hpp | 138 | ||||
| -rw-r--r-- | include/api-test/vk-utils.hpp | 11 |
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 |
