1
0
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:
kd-11 2019-05-21 20:17:48 +03:00 committed by kd-11
parent 46ba53f122
commit 370b9e196d
5 changed files with 53 additions and 28 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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));
}
};

View File

@ -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();

View File

@ -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;
}
};