rpcsx/rpcs3/Emu/RSX/VK/vkutils/commands.cpp

133 lines
3.3 KiB
C++
Raw Normal View History

#include "commands.h"
#include "device.h"
#include "shared.h"
#include "sync.h"
namespace vk
{
// This queue flushing method to be implemented by the backend as behavior depends on config
2022-01-30 12:56:22 +01:00
void queue_submit(const queue_submit_t& submit_info, VkBool32 flush);
2021-02-28 14:59:12 +01:00
void command_pool::create(vk::render_device& dev, u32 queue_family_id)
{
owner = &dev;
2021-02-28 14:59:12 +01:00
queue_family = queue_family_id;
VkCommandPoolCreateInfo infos = {};
infos.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
infos.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
infos.queueFamilyIndex = queue_family;
CHECK_RESULT(vkCreateCommandPool(dev, &infos, nullptr, &pool));
}
void command_pool::destroy()
{
if (!pool)
return;
vkDestroyCommandPool((*owner), pool, nullptr);
pool = nullptr;
}
vk::render_device& command_pool::get_owner() const
{
return (*owner);
}
u32 command_pool::get_queue_family() const
{
return queue_family;
}
command_pool::operator VkCommandPool() const
{
return pool;
}
2022-02-19 22:05:36 +01:00
void command_buffer::create(command_pool& cmd_pool)
{
VkCommandBufferAllocateInfo infos = {};
infos.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
infos.commandBufferCount = 1;
infos.commandPool = +cmd_pool;
infos.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
CHECK_RESULT(vkAllocateCommandBuffers(cmd_pool.get_owner(), &infos, &commands));
2022-02-19 22:05:36 +01:00
m_submit_fence = new fence(cmd_pool.get_owner());
pool = &cmd_pool;
}
void command_buffer::destroy()
{
vkFreeCommandBuffers(pool->get_owner(), (*pool), 1, &commands);
if (m_submit_fence)
{
//vkDestroyFence(pool->get_owner(), m_submit_fence, nullptr);
delete m_submit_fence;
m_submit_fence = nullptr;
}
}
void command_buffer::begin()
{
if (m_submit_fence && is_pending)
{
wait_for_fence(m_submit_fence);
is_pending = false;
//CHECK_RESULT(vkResetFences(pool->get_owner(), 1, &m_submit_fence));
m_submit_fence->reset();
CHECK_RESULT(vkResetCommandBuffer(commands, 0));
}
if (is_open)
return;
VkCommandBufferInheritanceInfo inheritance_info = {};
inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
VkCommandBufferBeginInfo begin_infos = {};
begin_infos.pInheritanceInfo = &inheritance_info;
begin_infos.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
begin_infos.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
CHECK_RESULT(vkBeginCommandBuffer(commands, &begin_infos));
is_open = true;
}
void command_buffer::end()
{
if (!is_open)
{
rsx_log.error("commandbuffer->end was called but commandbuffer is not in a recording state");
return;
}
CHECK_RESULT(vkEndCommandBuffer(commands));
is_open = false;
}
2022-01-30 12:56:22 +01:00
void command_buffer::submit(queue_submit_t& submit_info, VkBool32 flush)
{
if (is_open)
{
rsx_log.error("commandbuffer->submit was called whilst the command buffer is in a recording state");
return;
}
// Check for hanging queries to avoid driver hang
ensure((flags & cb_has_open_query) == 0); // "close and submit of commandbuffer with a hanging query!"
2022-02-11 18:57:19 +01:00
if (!submit_info.pfence)
{
2022-02-11 18:57:19 +01:00
submit_info.pfence = m_submit_fence;
is_pending = bool(submit_info.pfence);
}
2022-01-30 12:56:22 +01:00
submit_info.commands = this->commands;
queue_submit(submit_info, flush);
clear_flags();
}
}