diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/api-test/freelist.hpp | 115 | ||||
| -rw-r--r-- | include/api-test/handle.hpp | 14 | ||||
| -rw-r--r-- | include/api-test/vk-device-types.hpp | 59 | ||||
| -rw-r--r-- | include/api-test/vk-device.hpp | 16 |
4 files changed, 136 insertions, 68 deletions
diff --git a/include/api-test/freelist.hpp b/include/api-test/freelist.hpp index 3cdd55d..e9df734 100644 --- a/include/api-test/freelist.hpp +++ b/include/api-test/freelist.hpp @@ -3,61 +3,118 @@ #include <vector> #include <cassert> +#include "handle.hpp" + static constexpr uint32_t default_element_count = 1024U; template<typename T, const size_t initial_size = default_element_count> class freelist { public: - freelist() - : free(initial_size), - items(initial_size) { - std::iota(free.rbegin(), free.rend(), 0); + + freelist() { + auto next_free = 0U; + elements.reserve(initial_size); + for (auto id { 0U }; id < initial_size; id++) { + elements.push_back( + { + .next_free = static_cast<uint32_t>(++next_free % initial_size), + } + ); + } + + elements.back().next_free = -1U; } - uint32_t add(const T& item) { - const auto id = free.back(); - free.pop_back(); + handle<T> add(const T& item) { + auto id = elements[0U].next_free; + + if (id != -1U) { + auto& element = elements[id]; - items[id] = std::move(item); + elements[0U].next_free = element.next_free; + element.item = std::move(item); - return id; + return { id, ++element.generation }; + } + + // grow } - void remove(uint32_t item_id) { - free.push_back(item_id); + void remove(handle<T> handle) { + assert(handle.generation == elements[handle.id].generation); + elements[handle.id].next_free = elements[0U].next_free; + elements[0U].next_free = handle.id; } - T& operator[](uint32_t index) { - assert(index >= 0); - return items[index]; + T& operator[](handle<T> handle) { + assert(handle.generation == elements[handle.id].generation); + return elements[handle.id].item; } - const T& operator[](uint32_t index) const { - return items[index]; + const T& operator[](handle<T> handle) const { + assert(handle.generation == elements[handle.id].generation); + return elements[handle.id].item; } - 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; - } + static constexpr uint32_t invalid_id = -1; + +private: + struct element { + union { + T item; + uint32_t next_free = -1; + }; + uint32_t generation = 0U; + }; + + std::vector<element> elements; +}; + +template<const size_t initial_size = default_element_count> +class idlist { + public: + + idlist() { + auto next_free = 1U; + elements.reserve(initial_size); + for (auto id { 0U }; id < initial_size; id++) { + elements.push_back( + { + .next_free = static_cast<uint32_t>(++next_free % initial_size), + } + ); } - return invalid_id; + elements.back().next_free = -1U; } - auto begin() const { - return items.begin(); + handle<void> add() { + auto id = elements[0U].next_free; + + if (id != -1U) { + auto& element = elements[id]; + elements[0U].next_free = element.next_free; + element.next_free = -1; + + return { id, ++element.generation }; + } + + // grow } - auto end() const { - return items.end(); + void remove(handle<void> handle) { + assert(handle.generation == elements[handle.id].generation); + elements[handle.id].next_free = elements[0U].next_free; + elements[0U].next_free = handle.id; } static constexpr uint32_t invalid_id = -1; private: - std::vector<T> items; - std::vector<uint32_t> free; + struct element { + uint32_t next_free = -1; + uint32_t generation = 0U; + }; + + std::vector<element> elements; }; diff --git a/include/api-test/handle.hpp b/include/api-test/handle.hpp index a81480a..72c46a2 100644 --- a/include/api-test/handle.hpp +++ b/include/api-test/handle.hpp @@ -2,9 +2,19 @@ #include <cstdint> -template<typename T> +// template<typename T> +// struct handle { +// uint32_t id = handle::invalid_id; +// +// [[nodiscard]] inline bool is_valid() const { return id != handle::invalid_id; } +// +// static constexpr uint32_t invalid_id = -1U; +// }; + +template<typename U> struct handle { - uint32_t id = handle::invalid_id; + uint32_t id = invalid_id; + uint32_t generation = 0U; [[nodiscard]] inline bool is_valid() const { return id != handle::invalid_id; } diff --git a/include/api-test/vk-device-types.hpp b/include/api-test/vk-device-types.hpp index 86eb22b..3085e29 100644 --- a/include/api-test/vk-device-types.hpp +++ b/include/api-test/vk-device-types.hpp @@ -22,33 +22,42 @@ struct texture_desc { }; struct device_texture { - device_texture() = default; - device_texture(const texture_desc& desc); + void init(const texture_desc& desc); - void create_views(); + void release(); - VkImage vk_image; - VkImageView whole_view; + void create_views(); + + [[nodiscard]] uint32_t get_storage_index() const { + return storage_index.id; + } + + [[nodiscard]] uint32_t get_sampled_index() const { + return sampled_index.id; + } + + VkImage vk_image = nullptr; + VkImageView whole_view = nullptr; VkImageView mips_views[texture_desc::max_mips] = { nullptr }; - VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED; - VkPipelineStageFlags2 stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - VkAccessFlags2 access = VK_ACCESS_2_NONE; - VkFormat format; - VkImageAspectFlags aspects; + VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED; + VkPipelineStageFlags2 stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + VkAccessFlags2 access = VK_ACCESS_2_NONE; + VkFormat format = VK_FORMAT_UNDEFINED; + VkImageAspectFlags aspects = VK_IMAGE_ASPECT_NONE_KHR; - uint32_t width = 1U; - uint32_t height = 1U; - uint32_t depth = 1U; - uint32_t mips = 1U; + uint32_t width = 1U; + uint32_t height = 1U; + uint32_t depth = 1U; + uint32_t mips = 1U; - uint32_t storage_index = -1; - uint32_t sampled_index = -1; + private: + handle<void> storage_index; + handle<void> sampled_index; - VmaAllocation alloc; + VmaAllocation alloc = nullptr; -private: - static freelist<device_texture*> storage_indices; - static freelist<device_texture*> sampled_indices; + static idlist<> storage_indices; + static idlist<> sampled_indices; }; struct buffer_desc { @@ -66,7 +75,6 @@ struct device_buffer { size_t size; }; - struct pipeline_desc { std::span<uint8_t> cs_code; std::span<uint8_t> vs_code; @@ -81,15 +89,14 @@ struct device_pipeline { VkPipelineBindPoint bind_point; }; - struct semaphore_desc { VkSemaphoreType type; uint64_t initial_value = 0U; }; struct device_semaphore { - VkSemaphore vk_semaphore = nullptr; - uint64_t value; + VkSemaphore vk_semaphore = nullptr; + uint64_t value; }; @@ -102,7 +109,7 @@ struct surface_desc { VkImageUsageFlags usages; uint32_t image_count = surface_desc::default_image_count; - static constexpr uint32_t max_image_count = 3U; + static constexpr uint32_t max_image_count = 3U; static constexpr uint32_t default_image_count = 3U; }; @@ -115,6 +122,6 @@ struct device_surface { uint32_t image_index; uint32_t image_count; - void acquire_image_index(handle<device_semaphore> signal_handle); + void acquire_image_index(handle<device_semaphore> signal_handle); handle<device_texture> get_backbuffer_image() const; }; diff --git a/include/api-test/vk-device.hpp b/include/api-test/vk-device.hpp index 9e42b38..ca5457a 100644 --- a/include/api-test/vk-device.hpp +++ b/include/api-test/vk-device.hpp @@ -7,7 +7,6 @@ #include "command-buffer.hpp" #include "freelist.hpp" -#include "handle.hpp" #include "vk-bindless.hpp" #include "vk-device-types.hpp" @@ -40,19 +39,14 @@ class vkdevice { handle<device_semaphore> create_semaphore(const semaphore_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); - void destroy_semaphore(const device_semaphore& semaphore); void destroy_semaphore(handle<device_semaphore> handle); - void destroy_surface(const device_surface& surface); void destroy_surface(handle<device_surface> handle); template<typename cmd_buf_type> @@ -61,23 +55,23 @@ class vkdevice { } [[nodiscard]] inline device_texture& get_texture(handle<device_texture> handle) { - return textures[handle.id]; + return textures[handle]; } [[nodiscard]] inline const device_buffer& get_buffer(handle<device_buffer> handle) const { - return buffers[handle.id]; + return buffers[handle]; } [[nodiscard]] inline const device_pipeline& get_pipeline(handle<device_pipeline> handle) const { - return pipelines[handle.id]; + return pipelines[handle]; } [[nodiscard]] inline device_surface& get_surface(handle<device_surface> handle) { - return surfaces[handle.id]; + return surfaces[handle]; } [[nodiscard]] inline device_semaphore& get_semaphore(handle<device_semaphore> handle) { - return semaphores[handle.id]; + return semaphores[handle]; } [[nodiscard]] inline const bindless_model& get_bindingmodel() const { |
