mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-03-01 02:57:01 +01:00
vk: Implement state tracking for command buffers
- Only tracks the heavy items for now. Binding the same pipeline or descriptor set causes some drivers to perform expensive operations (RADV, AMDVLK)
This commit is contained in:
parent
3452aaf5d5
commit
b1365a051d
|
|
@ -74,7 +74,7 @@ namespace vk
|
|||
}
|
||||
|
||||
++reset_id;
|
||||
CHECK_RESULT(vkResetCommandBuffer(commands, 0));
|
||||
vk::command_buffer::reset();
|
||||
}
|
||||
|
||||
bool poke()
|
||||
|
|
|
|||
|
|
@ -414,8 +414,8 @@ namespace vk
|
|||
bind_sets[count++] = set.commit(); // Commit variable changes and return handle to the new set
|
||||
}
|
||||
|
||||
vkCmdBindPipeline(cmd, bind_point, m_pipeline);
|
||||
vkCmdBindDescriptorSets(cmd, bind_point, m_pipeline_layout, 0, count, bind_sets, 0, nullptr);
|
||||
cmd.bind_pipeline(m_pipeline, bind_point);
|
||||
cmd.bind_descriptor_sets({ bind_sets, count }, bind_point, m_pipeline_layout);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1339,7 +1339,7 @@ namespace vk
|
|||
cmd.submit(submit_info, VK_TRUE);
|
||||
vk::wait_for_fence(&submit_fence, GENERAL_WAIT_TIMEOUT);
|
||||
|
||||
CHECK_RESULT(vkResetCommandBuffer(cmd, 0));
|
||||
cmd.reset();
|
||||
cmd.begin();
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -70,6 +70,16 @@ namespace vk
|
|||
}
|
||||
}
|
||||
|
||||
void command_buffer::reset()
|
||||
{
|
||||
// Nuke the state cache
|
||||
m_bound_pipeline = VK_NULL_HANDLE;
|
||||
m_bound_descriptor_sets[0] = VK_NULL_HANDLE;
|
||||
|
||||
// Do the driver reset
|
||||
CHECK_RESULT(vkResetCommandBuffer(commands, 0));
|
||||
}
|
||||
|
||||
void command_buffer::begin()
|
||||
{
|
||||
if (m_submit_fence && is_pending)
|
||||
|
|
@ -79,7 +89,7 @@ namespace vk
|
|||
|
||||
//CHECK_RESULT(vkResetFences(pool->get_owner(), 1, &m_submit_fence));
|
||||
m_submit_fence->reset();
|
||||
CHECK_RESULT(vkResetCommandBuffer(commands, 0));
|
||||
reset();
|
||||
}
|
||||
|
||||
if (is_open)
|
||||
|
|
@ -129,4 +139,51 @@ namespace vk
|
|||
queue_submit(submit_info, flush);
|
||||
clear_flags();
|
||||
}
|
||||
|
||||
void command_buffer::bind_pipeline(VkPipeline pipeline, VkPipelineBindPoint bind_point) const
|
||||
{
|
||||
if (m_bound_pipeline == pipeline)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_bound_pipeline = pipeline;
|
||||
vkCmdBindPipeline(commands, bind_point, pipeline);
|
||||
}
|
||||
|
||||
void command_buffer::bind_descriptor_sets(
|
||||
const std::span<VkDescriptorSet>& sets,
|
||||
const std::span<u32>& dynamic_offsets,
|
||||
VkPipelineBindPoint bind_point,
|
||||
VkPipelineLayout pipe_layout) const
|
||||
{
|
||||
const u32 num_sets = ::size32(sets);
|
||||
ensure(num_sets <= 2);
|
||||
|
||||
if (dynamic_offsets.empty() &&
|
||||
!memcmp(sets.data(), m_bound_descriptor_sets.data(), sets.size_bytes()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::memcpy(m_bound_descriptor_sets.data(), sets.data(), sets.size_bytes());
|
||||
vkCmdBindDescriptorSets(commands, bind_point, pipe_layout, 0, num_sets, sets.data(), ::size32(dynamic_offsets), dynamic_offsets.data());
|
||||
}
|
||||
|
||||
void command_buffer::bind_descriptor_sets(
|
||||
const std::span<VkDescriptorSet>& sets,
|
||||
VkPipelineBindPoint bind_point,
|
||||
VkPipelineLayout pipe_layout) const
|
||||
{
|
||||
const u32 num_sets = ::size32(sets);
|
||||
ensure(num_sets <= 2);
|
||||
|
||||
if (!memcmp(sets.data(), m_bound_descriptor_sets.data(), sets.size_bytes()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::memcpy(m_bound_descriptor_sets.data(), sets.data(), sets.size_bytes());
|
||||
vkCmdBindDescriptorSets(commands, bind_point, pipe_layout, 0, num_sets, sets.data(), 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,10 @@ namespace vk
|
|||
command_pool* pool = nullptr;
|
||||
VkCommandBuffer commands = nullptr;
|
||||
|
||||
// State cache
|
||||
mutable std::array<VkDescriptorSet, 2> m_bound_descriptor_sets {{ VK_NULL_HANDLE }};
|
||||
mutable VkPipeline m_bound_pipeline = VK_NULL_HANDLE;
|
||||
|
||||
public:
|
||||
enum access_type_hint
|
||||
{
|
||||
|
|
@ -97,40 +101,28 @@ namespace vk
|
|||
|
||||
void create(command_pool& cmd_pool);
|
||||
void destroy();
|
||||
void reset();
|
||||
|
||||
void begin();
|
||||
void end();
|
||||
void submit(queue_submit_t& submit_info, VkBool32 flush = VK_FALSE);
|
||||
|
||||
// Abstractions with caching
|
||||
void bind_pipeline(VkPipeline pipeline, VkPipelineBindPoint bind_point) const;
|
||||
void bind_descriptor_sets(const std::span<VkDescriptorSet>& sets, VkPipelineBindPoint bind_point, VkPipelineLayout pipe_layout) const;
|
||||
void bind_descriptor_sets(const std::span<VkDescriptorSet>& sets, const std::span<u32>& dynamic_offsets, VkPipelineBindPoint bind_point, VkPipelineLayout pipe_layout) const;
|
||||
|
||||
// Properties
|
||||
command_pool& get_command_pool() const
|
||||
{
|
||||
return *pool;
|
||||
}
|
||||
command_pool& get_command_pool() const { return *pool; }
|
||||
u32 get_queue_family() const { return pool->get_queue_family(); }
|
||||
bool is_recording() const { return is_open; }
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -453,7 +453,8 @@ namespace vk
|
|||
// Notify
|
||||
on_bind();
|
||||
|
||||
vkCmdBindDescriptorSets(cmd, bind_point, layout, 0, 1, &m_handle, ::size32(m_dynamic_offsets), m_dynamic_offsets.data());
|
||||
VkDescriptorSet sets[1] = { m_handle };
|
||||
cmd.bind_descriptor_sets(sets, m_dynamic_offsets, bind_point, layout);
|
||||
}
|
||||
|
||||
void descriptor_set::flush()
|
||||
|
|
|
|||
Loading…
Reference in a new issue