mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-26 12:42:41 +01: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
@ -33,7 +33,7 @@ namespace vk
|
||||
};
|
||||
|
||||
// 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);
|
||||
|
||||
@ -112,7 +112,7 @@ namespace vk
|
||||
if (m_used_descriptors == 0)
|
||||
return;
|
||||
|
||||
vkResetDescriptorPool(*get_current_renderer(), m_descriptor_pool, 0);
|
||||
m_descriptor_pool.reset(0);
|
||||
m_used_descriptors = 0;
|
||||
}
|
||||
|
||||
|
@ -666,7 +666,7 @@ VKGSRender::VKGSRender() : GSRender()
|
||||
for (auto &ctx : frame_context_storage)
|
||||
{
|
||||
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();
|
||||
@ -1069,7 +1069,7 @@ void VKGSRender::check_descriptors()
|
||||
// Should hard sync before resetting descriptors for spec compliance
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -1225,12 +1225,16 @@ void VKGSRender::begin()
|
||||
verify(HERE), !m_current_frame->swap_command_buffer;
|
||||
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->flags &= ~frame_context_state::dirty;
|
||||
}
|
||||
else
|
||||
{
|
||||
check_present_status();
|
||||
}
|
||||
}
|
||||
|
||||
void VKGSRender::update_draw_state()
|
||||
@ -2536,8 +2540,6 @@ void VKGSRender::process_swap_request(frame_context_t *ctx, bool 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)
|
||||
{
|
||||
m_text_writer->reset_descriptors();
|
||||
@ -2629,11 +2631,11 @@ void VKGSRender::do_local_task(rsx::FIFO_state state)
|
||||
case rsx::FIFO_state::lock_wait:
|
||||
// Critical check finished
|
||||
return;
|
||||
case rsx::FIFO_state::spinning:
|
||||
case rsx::FIFO_state::empty:
|
||||
//case rsx::FIFO_state::spinning:
|
||||
//case rsx::FIFO_state::empty:
|
||||
// We have some time, check the present queue
|
||||
check_present_status();
|
||||
break;
|
||||
//check_present_status();
|
||||
//break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2602,43 +2602,66 @@ public:
|
||||
|
||||
class descriptor_pool
|
||||
{
|
||||
VkDescriptorPool pool = nullptr;
|
||||
const vk::render_device *owner = nullptr;
|
||||
const vk::render_device *m_owner = nullptr;
|
||||
|
||||
std::vector<VkDescriptorPool> m_device_pools;
|
||||
VkDescriptorPool m_current_pool_handle = VK_NULL_HANDLE;
|
||||
u32 m_current_pool_index = 0;
|
||||
|
||||
public:
|
||||
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 = {};
|
||||
infos.flags = 0;
|
||||
infos.maxSets = DESCRIPTOR_MAX_DRAW_CALLS;
|
||||
infos.maxSets = max_sets;
|
||||
infos.poolSizeCount = size_descriptors_count;
|
||||
infos.pPoolSizes = sizes;
|
||||
infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||
|
||||
owner = &dev;
|
||||
CHECK_RESULT(vkCreateDescriptorPool(dev, &infos, nullptr, &pool));
|
||||
m_owner = &dev;
|
||||
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()
|
||||
{
|
||||
if (!pool) return;
|
||||
if (m_device_pools.empty()) return;
|
||||
|
||||
vkDestroyDescriptorPool((*owner), pool, nullptr);
|
||||
owner = nullptr;
|
||||
pool = nullptr;
|
||||
for (auto &pool : m_device_pools)
|
||||
{
|
||||
vkDestroyDescriptorPool((*m_owner), pool, nullptr);
|
||||
pool = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
m_owner = nullptr;
|
||||
}
|
||||
|
||||
bool valid()
|
||||
{
|
||||
return (pool != nullptr);
|
||||
return (!m_device_pools.empty());
|
||||
}
|
||||
|
||||
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
|
||||
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);
|
||||
|
||||
@ -297,7 +297,7 @@ namespace vk
|
||||
if (m_used_descriptors == 0)
|
||||
return;
|
||||
|
||||
vkResetDescriptorPool(*m_device, m_descriptor_pool, 0);
|
||||
m_descriptor_pool.reset(0);
|
||||
m_used_descriptors = 0;
|
||||
|
||||
m_vao.reset_allocation_stats();
|
||||
|
@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
#include "VKHelpers.h"
|
||||
#include "VKVertexProgram.h"
|
||||
#include "VKFragmentProgram.h"
|
||||
@ -39,7 +39,7 @@ namespace vk
|
||||
};
|
||||
|
||||
//Reserve descriptor pools
|
||||
m_descriptor_pool.create(dev, descriptor_pools, 1);
|
||||
m_descriptor_pool.create(dev, descriptor_pools, 1, 120, 2);
|
||||
|
||||
VkDescriptorSetLayoutBinding bindings[1] = {};
|
||||
|
||||
@ -370,7 +370,7 @@ namespace vk
|
||||
if (m_used_descriptors == 0)
|
||||
return;
|
||||
|
||||
vkResetDescriptorPool(device, m_descriptor_pool, 0);
|
||||
m_descriptor_pool.reset(0);
|
||||
m_used_descriptors = 0;
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user