mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-10 08:51:28 +12:00
vk: Improve descriptor pool management
- Add double-buffered descriptor pools to avoid use-after-free situations - Make descriptor pools more configurable - Also adds in a hack to allow renderdoc to capture properly
This commit is contained in:
parent
46ba53f122
commit
370b9e196d
5 changed files with 53 additions and 28 deletions
|
@ -33,7 +33,7 @@ namespace vk
|
||||||
};
|
};
|
||||||
|
|
||||||
// Reserve descriptor pools
|
// Reserve descriptor pools
|
||||||
m_descriptor_pool.create(*get_current_renderer(), descriptor_pool_sizes, 2);
|
m_descriptor_pool.create(*get_current_renderer(), descriptor_pool_sizes, 2, VK_MAX_COMPUTE_TASKS, 2);
|
||||||
|
|
||||||
std::vector<VkDescriptorSetLayoutBinding> bindings(2);
|
std::vector<VkDescriptorSetLayoutBinding> bindings(2);
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ namespace vk
|
||||||
if (m_used_descriptors == 0)
|
if (m_used_descriptors == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vkResetDescriptorPool(*get_current_renderer(), m_descriptor_pool, 0);
|
m_descriptor_pool.reset(0);
|
||||||
m_used_descriptors = 0;
|
m_used_descriptors = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -666,7 +666,7 @@ VKGSRender::VKGSRender() : GSRender()
|
||||||
for (auto &ctx : frame_context_storage)
|
for (auto &ctx : frame_context_storage)
|
||||||
{
|
{
|
||||||
vkCreateSemaphore((*m_device), &semaphore_info, nullptr, &ctx.present_semaphore);
|
vkCreateSemaphore((*m_device), &semaphore_info, nullptr, &ctx.present_semaphore);
|
||||||
ctx.descriptor_pool.create(*m_device, sizes.data(), static_cast<uint32_t>(sizes.size()));
|
ctx.descriptor_pool.create(*m_device, sizes.data(), static_cast<uint32_t>(sizes.size()), DESCRIPTOR_MAX_DRAW_CALLS, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& memory_map = m_device->get_memory_mapping();
|
const auto& memory_map = m_device->get_memory_mapping();
|
||||||
|
@ -1069,7 +1069,7 @@ void VKGSRender::check_descriptors()
|
||||||
// Should hard sync before resetting descriptors for spec compliance
|
// Should hard sync before resetting descriptors for spec compliance
|
||||||
flush_command_queue(true);
|
flush_command_queue(true);
|
||||||
|
|
||||||
CHECK_RESULT(vkResetDescriptorPool(*m_device, m_current_frame->descriptor_pool, 0));
|
m_current_frame->descriptor_pool.reset(0);
|
||||||
m_current_frame->used_descriptors = 0;
|
m_current_frame->used_descriptors = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1225,12 +1225,16 @@ void VKGSRender::begin()
|
||||||
verify(HERE), !m_current_frame->swap_command_buffer;
|
verify(HERE), !m_current_frame->swap_command_buffer;
|
||||||
if (m_current_frame->used_descriptors)
|
if (m_current_frame->used_descriptors)
|
||||||
{
|
{
|
||||||
CHECK_RESULT(vkResetDescriptorPool(*m_device, m_current_frame->descriptor_pool, 0));
|
m_current_frame->descriptor_pool.reset(0);
|
||||||
m_current_frame->used_descriptors = 0;
|
m_current_frame->used_descriptors = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_current_frame->flags &= ~frame_context_state::dirty;
|
m_current_frame->flags &= ~frame_context_state::dirty;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
check_present_status();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKGSRender::update_draw_state()
|
void VKGSRender::update_draw_state()
|
||||||
|
@ -2536,8 +2540,6 @@ void VKGSRender::process_swap_request(frame_context_t *ctx, bool free_resources)
|
||||||
|
|
||||||
if (free_resources)
|
if (free_resources)
|
||||||
{
|
{
|
||||||
//Cleanup of reference sensitive resources
|
|
||||||
//TODO: These should be double buffered as well to prevent destruction of anything in use
|
|
||||||
if (g_cfg.video.overlay)
|
if (g_cfg.video.overlay)
|
||||||
{
|
{
|
||||||
m_text_writer->reset_descriptors();
|
m_text_writer->reset_descriptors();
|
||||||
|
@ -2629,11 +2631,11 @@ void VKGSRender::do_local_task(rsx::FIFO_state state)
|
||||||
case rsx::FIFO_state::lock_wait:
|
case rsx::FIFO_state::lock_wait:
|
||||||
// Critical check finished
|
// Critical check finished
|
||||||
return;
|
return;
|
||||||
case rsx::FIFO_state::spinning:
|
//case rsx::FIFO_state::spinning:
|
||||||
case rsx::FIFO_state::empty:
|
//case rsx::FIFO_state::empty:
|
||||||
// We have some time, check the present queue
|
// We have some time, check the present queue
|
||||||
check_present_status();
|
//check_present_status();
|
||||||
break;
|
//break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2602,43 +2602,66 @@ public:
|
||||||
|
|
||||||
class descriptor_pool
|
class descriptor_pool
|
||||||
{
|
{
|
||||||
VkDescriptorPool pool = nullptr;
|
const vk::render_device *m_owner = nullptr;
|
||||||
const vk::render_device *owner = nullptr;
|
|
||||||
|
std::vector<VkDescriptorPool> m_device_pools;
|
||||||
|
VkDescriptorPool m_current_pool_handle = VK_NULL_HANDLE;
|
||||||
|
u32 m_current_pool_index = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
descriptor_pool() {}
|
descriptor_pool() {}
|
||||||
~descriptor_pool() {}
|
~descriptor_pool() {}
|
||||||
|
|
||||||
void create(const vk::render_device &dev, VkDescriptorPoolSize *sizes, u32 size_descriptors_count)
|
void create(const vk::render_device &dev, VkDescriptorPoolSize *sizes, u32 size_descriptors_count, u32 max_sets, u8 subpool_count)
|
||||||
{
|
{
|
||||||
|
verify(HERE), subpool_count;
|
||||||
|
|
||||||
VkDescriptorPoolCreateInfo infos = {};
|
VkDescriptorPoolCreateInfo infos = {};
|
||||||
infos.flags = 0;
|
infos.flags = 0;
|
||||||
infos.maxSets = DESCRIPTOR_MAX_DRAW_CALLS;
|
infos.maxSets = max_sets;
|
||||||
infos.poolSizeCount = size_descriptors_count;
|
infos.poolSizeCount = size_descriptors_count;
|
||||||
infos.pPoolSizes = sizes;
|
infos.pPoolSizes = sizes;
|
||||||
infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||||
|
|
||||||
owner = &dev;
|
m_owner = &dev;
|
||||||
CHECK_RESULT(vkCreateDescriptorPool(dev, &infos, nullptr, &pool));
|
m_device_pools.resize(subpool_count);
|
||||||
|
|
||||||
|
for (auto &pool : m_device_pools)
|
||||||
|
{
|
||||||
|
CHECK_RESULT(vkCreateDescriptorPool(dev, &infos, nullptr, &pool));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_current_pool_handle = m_device_pools[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy()
|
void destroy()
|
||||||
{
|
{
|
||||||
if (!pool) return;
|
if (m_device_pools.empty()) return;
|
||||||
|
|
||||||
vkDestroyDescriptorPool((*owner), pool, nullptr);
|
for (auto &pool : m_device_pools)
|
||||||
owner = nullptr;
|
{
|
||||||
pool = nullptr;
|
vkDestroyDescriptorPool((*m_owner), pool, nullptr);
|
||||||
|
pool = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_owner = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool valid()
|
bool valid()
|
||||||
{
|
{
|
||||||
return (pool != nullptr);
|
return (!m_device_pools.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
operator VkDescriptorPool()
|
operator VkDescriptorPool()
|
||||||
{
|
{
|
||||||
return pool;
|
return m_current_pool_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(VkDescriptorPoolResetFlags flags)
|
||||||
|
{
|
||||||
|
m_current_pool_index = (m_current_pool_index + 1) % u32(m_device_pools.size());
|
||||||
|
m_current_pool_handle = m_device_pools[m_current_pool_index];
|
||||||
|
CHECK_RESULT(vkResetDescriptorPool(*m_owner, m_current_pool_handle, flags));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ namespace vk
|
||||||
};
|
};
|
||||||
|
|
||||||
//Reserve descriptor pools
|
//Reserve descriptor pools
|
||||||
m_descriptor_pool.create(*m_device, descriptor_pool_sizes, 2);
|
m_descriptor_pool.create(*m_device, descriptor_pool_sizes, 2, VK_OVERLAY_MAX_DRAW_CALLS, 2);
|
||||||
|
|
||||||
std::vector<VkDescriptorSetLayoutBinding> bindings(1 + m_num_usable_samplers);
|
std::vector<VkDescriptorSetLayoutBinding> bindings(1 + m_num_usable_samplers);
|
||||||
|
|
||||||
|
@ -297,7 +297,7 @@ namespace vk
|
||||||
if (m_used_descriptors == 0)
|
if (m_used_descriptors == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vkResetDescriptorPool(*m_device, m_descriptor_pool, 0);
|
m_descriptor_pool.reset(0);
|
||||||
m_used_descriptors = 0;
|
m_used_descriptors = 0;
|
||||||
|
|
||||||
m_vao.reset_allocation_stats();
|
m_vao.reset_allocation_stats();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "VKHelpers.h"
|
#include "VKHelpers.h"
|
||||||
#include "VKVertexProgram.h"
|
#include "VKVertexProgram.h"
|
||||||
#include "VKFragmentProgram.h"
|
#include "VKFragmentProgram.h"
|
||||||
|
@ -39,7 +39,7 @@ namespace vk
|
||||||
};
|
};
|
||||||
|
|
||||||
//Reserve descriptor pools
|
//Reserve descriptor pools
|
||||||
m_descriptor_pool.create(dev, descriptor_pools, 1);
|
m_descriptor_pool.create(dev, descriptor_pools, 1, 120, 2);
|
||||||
|
|
||||||
VkDescriptorSetLayoutBinding bindings[1] = {};
|
VkDescriptorSetLayoutBinding bindings[1] = {};
|
||||||
|
|
||||||
|
@ -370,7 +370,7 @@ namespace vk
|
||||||
if (m_used_descriptors == 0)
|
if (m_used_descriptors == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vkResetDescriptorPool(device, m_descriptor_pool, 0);
|
m_descriptor_pool.reset(0);
|
||||||
m_used_descriptors = 0;
|
m_used_descriptors = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue