rpcsx/rpcs3/Emu/RSX/VK/vkutils/commands.h
2022-02-21 23:58:01 +03:00

136 lines
2.7 KiB
C++

#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<VkSemaphore, 4> wait_semaphores;
std::array<VkSemaphore, 4> signal_semaphores;
std::array<VkPipelineStageFlags, 4> 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;
}
};
}