#pragma once #include "freelist.hpp" #include "vk-command-buffer.hpp" using VmaAllocator = struct VmaAllocator_T*; struct command_buffer; class window; class vkdevice { struct queue { VkQueue vk_queue = VK_NULL_HANDLE; uint32_t index = UINT32_MAX; VkQueueFlags usages; VkCommandPool command_pool = VK_NULL_HANDLE; }; public: void init(); void deinit(); static inline vkdevice& get() { return render_device; } handle create_texture(const texture_desc& desc); handle create_sampler(const sampler_desc& desc); handle create_buffer(const buffer_desc& desc); handle create_graphics_pipeline(const graphics_pipeline_desc& desc); handle create_compute_pipeline(const compute_pipeline_desc& desc); handle create_surface(const surface_desc& desc); void destroy_texture(handle handle); void destroy_sampler(handle handle); void destroy_buffer(handle handle); void destroy_pipeline(handle handle); void destroy_surface(handle handle); template void allocate_command_buffers(buffer_type* buffers, size_t count, QueueType queue_type, const char* name) { allocate_command_buffers(static_cast(buffers), count, queue_type, name); } [[nodiscard]] inline device_texture* get_texture(handle handle) { return &textures[handle]; } [[nodiscard]] inline device_sampler* get_sampler(handle handle) { return &samplers[handle]; } [[nodiscard]] inline device_buffer* get_buffer(handle handle) { return &buffers[handle]; } [[nodiscard]] inline const device_pipeline* get_pipeline(handle handle) const { return &pipelines[handle]; } [[nodiscard]] inline device_surface* get_surface(handle handle) { return &surfaces[handle]; } // uint64_t submit(std::span buffers, handle wait_handle, handle signal_handle, handle fence_handle); uint32_t acquire_image_index(handle surface_handle); uint64_t submit_before_present(handle surface_handle, command_buffer* buffers, uint32_t count); uint64_t submit(command_buffer* buffers, uint32_t count); void present(handle surface_handle); void wait(); void wait_for_fence(u64 value); private: vkdevice() = default; ~vkdevice() = default; void allocate_command_buffers(command_buffer* buffers, size_t count, QueueType type, const char* name); void create_swapchain(const surface_desc& desc, device_surface& surface); // TODO: Wrap in a struct called adapter ? void create_instance(); void create_device(); bool device_support_features(VkPhysicalDevice physical_dev); queue queues[static_cast(QueueType::MAX)]; static constexpr size_t max_allocable_command_buffers = 16; static constexpr size_t max_submitable_command_buffers = 16; freelist textures; freelist samplers; freelist buffers; freelist pipelines; freelist surfaces; device_semaphore fence; static vkdevice render_device; #ifdef _DEBUG VkDebugUtilsMessengerEXT debug_messenger; #endif // _DEBUG };