#pragma once #include #include #include #include "command-buffer.hpp" #include "freelist.hpp" #include "vk-bindless.hpp" using VmaAllocator = struct VmaAllocator_T*; class window; class vkdevice { struct queue { VkQueue vk_queue; uint32_t index; VkQueueFlags usages; VkCommandPool command_pool; }; public: void init(); static inline vkdevice& get_render_device() { 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); handle create_semaphore(const semaphore_desc& desc); void destroy_texture(handle handle); void destroy_sampler(handle handle); void destroy_buffer(handle handle); void destroy_pipeline(handle handle); void destroy_semaphore(handle handle); void destroy_surface(handle handle); template void allocate_command_buffers(buffer_type* buffers, size_t count, QueueType queue_type) { allocate_command_buffers(static_cast(buffers), count, queue_type); } [[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]; } [[nodiscard]] inline device_semaphore& get_semaphore(handle handle) { return semaphores[handle]; } [[nodiscard]] inline const bindless_model& get_bindingmodel() const { return bindless; } inline VkDevice get_device() { return device; } inline VmaAllocator get_allocator() { return gpu_allocator; } // uint64_t submit(std::span buffers, handle wait_handle, handle signal_handle, handle fence_handle); uint32_t acquire_image_index(handle surface_handle); uint32_t submit_before_present(handle surface_handle, command_buffer* buffers, uint32_t count); uint32_t submit(command_buffer* buffers, uint32_t count); void present(handle surface_handle); void wait(); private: vkdevice() = default; ~vkdevice(); void allocate_command_buffers(command_buffer* buffers, size_t count, QueueType type); VkShaderModule create_shader_module(const std::span& shader_code); void create_swapchain(const surface_desc& desc, device_surface& surface); // TODO: Wrap in a struct called adapter ? void create_instance(); void create_device(); void create_memory_allocator(); void create_command_pools(); void pick_physical_device(); static bool device_support_features(VkPhysicalDevice physical_dev); void create_debug_layer_callback(); queue queues[static_cast(QueueType::MAX)]; VkInstance instance; VkPhysicalDevice physical_device; VkDevice device; VmaAllocator gpu_allocator; bindless_model bindless; 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; freelist semaphores; device_semaphore timeline_semaphore; static vkdevice render_device; #ifdef _DEBUG VkDebugUtilsMessengerEXT debug_messenger; #endif // _DEBUG };