#pragma once #include "../VulkanAPI.h" #include "device.h" #include "sync.h" namespace vk { class command_pool { vk::render_device* owner = nullptr; VkCommandPool pool = nullptr; u32 queue_family = 0; public: command_pool() = default; ~command_pool() = default; void create(vk::render_device& dev, u32 queue_family); void destroy(); vk::render_device& get_owner() const; u32 get_queue_family() const; operator VkCommandPool() const; }; struct queue_submit_t { VkQueue queue = VK_NULL_HANDLE; fence* pfence = nullptr; VkCommandBuffer commands = VK_NULL_HANDLE; std::array wait_semaphores; std::array signal_semaphores; std::array wait_stages; u32 wait_semaphores_count = 0; u32 signal_semaphores_count = 0; queue_submit_t() = default; queue_submit_t(VkQueue queue_, vk::fence* fence_) : queue(queue_), pfence(fence_) {} queue_submit_t(const queue_submit_t& other) { std::memcpy(this, &other, sizeof(queue_submit_t)); } inline queue_submit_t& wait_on(VkSemaphore semaphore, VkPipelineStageFlags stage) { ensure(wait_semaphores_count < 4); wait_semaphores[wait_semaphores_count] = semaphore; wait_stages[wait_semaphores_count++] = stage; return *this; } inline queue_submit_t& queue_signal(VkSemaphore semaphore) { ensure(signal_semaphores_count < 4); signal_semaphores[signal_semaphores_count++] = semaphore; return *this; } }; class command_buffer { protected: bool is_open = false; bool is_pending = false; fence* m_submit_fence = nullptr; command_pool* pool = nullptr; VkCommandBuffer commands = nullptr; public: enum access_type_hint { flush_only, // Only to be submitted/opened/closed via command flush all // Auxiliary, can be submitted/opened/closed at any time } access_hint = flush_only; enum command_buffer_data_flag : u32 { cb_has_occlusion_task = 1, cb_has_blit_transfer = 2, cb_has_dma_transfer = 4, cb_has_open_query = 8, cb_load_occluson_task = 16, cb_has_conditional_render = 32 }; u32 flags = 0; public: command_buffer() = default; ~command_buffer() = default; void create(command_pool& cmd_pool); void destroy(); void begin(); void end(); void submit(queue_submit_t& submit_info, VkBool32 flush = VK_FALSE); // Properties command_pool& get_command_pool() const { return *pool; } u32 get_queue_family() const { return pool->get_queue_family(); } void clear_flags() { flags = 0; } void set_flag(command_buffer_data_flag flag) { flags |= flag; } operator VkCommandBuffer() const { return commands; } bool is_recording() const { return is_open; } }; }