mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-23 03:02:53 +01:00
vk: Use a dynamic number of descriptor allocations
This commit is contained in:
parent
dc8fc9fc79
commit
f90bf2dd40
@ -425,22 +425,23 @@ VKGSRender::VKGSRender() : GSRender()
|
|||||||
m_occlusion_query_manager->set_control_flags(VK_QUERY_CONTROL_PRECISE_BIT, 0);
|
m_occlusion_query_manager->set_control_flags(VK_QUERY_CONTROL_PRECISE_BIT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Generate frame contexts
|
// Generate frame contexts
|
||||||
|
const u32 max_draw_calls = m_device->get_descriptor_max_draw_calls();
|
||||||
const auto& binding_table = m_device->get_pipeline_binding_table();
|
const auto& binding_table = m_device->get_pipeline_binding_table();
|
||||||
const u32 num_fs_samplers = binding_table.vertex_textures_first_bind_slot - binding_table.textures_first_bind_slot;
|
const u32 num_fs_samplers = binding_table.vertex_textures_first_bind_slot - binding_table.textures_first_bind_slot;
|
||||||
|
|
||||||
std::vector<VkDescriptorPoolSize> sizes;
|
std::vector<VkDescriptorPoolSize> sizes;
|
||||||
sizes.push_back({ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER , 6 * DESCRIPTOR_MAX_DRAW_CALLS });
|
sizes.push_back({ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER , 6 * max_draw_calls });
|
||||||
sizes.push_back({ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER , 3 * DESCRIPTOR_MAX_DRAW_CALLS });
|
sizes.push_back({ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER , 3 * max_draw_calls });
|
||||||
sizes.push_back({ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER , (num_fs_samplers + 4) * DESCRIPTOR_MAX_DRAW_CALLS });
|
sizes.push_back({ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER , (num_fs_samplers + 4) * max_draw_calls });
|
||||||
|
|
||||||
// Conditional rendering predicate slot; refactor to allow skipping this when not needed
|
// Conditional rendering predicate slot; refactor to allow skipping this when not needed
|
||||||
sizes.push_back({ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1 * DESCRIPTOR_MAX_DRAW_CALLS });
|
sizes.push_back({ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1 * max_draw_calls });
|
||||||
|
|
||||||
VkSemaphoreCreateInfo semaphore_info = {};
|
VkSemaphoreCreateInfo semaphore_info = {};
|
||||||
semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
|
|
||||||
//VRAM allocation
|
// VRAM allocation
|
||||||
m_attrib_ring_info.create(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VK_ATTRIB_RING_BUFFER_SIZE_M * 0x100000, "attrib buffer", 0x400000, VK_TRUE);
|
m_attrib_ring_info.create(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VK_ATTRIB_RING_BUFFER_SIZE_M * 0x100000, "attrib buffer", 0x400000, VK_TRUE);
|
||||||
m_fragment_env_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "fragment env buffer");
|
m_fragment_env_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "fragment env buffer");
|
||||||
m_vertex_env_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "vertex env buffer");
|
m_vertex_env_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "vertex env buffer");
|
||||||
@ -476,7 +477,7 @@ VKGSRender::VKGSRender() : GSRender()
|
|||||||
{
|
{
|
||||||
vkCreateSemaphore((*m_device), &semaphore_info, nullptr, &ctx.present_wait_semaphore);
|
vkCreateSemaphore((*m_device), &semaphore_info, nullptr, &ctx.present_wait_semaphore);
|
||||||
vkCreateSemaphore((*m_device), &semaphore_info, nullptr, &ctx.acquire_signal_semaphore);
|
vkCreateSemaphore((*m_device), &semaphore_info, nullptr, &ctx.acquire_signal_semaphore);
|
||||||
ctx.descriptor_pool.create(*m_device, sizes.data(), static_cast<u32>(sizes.size()), DESCRIPTOR_MAX_DRAW_CALLS, 1);
|
ctx.descriptor_pool.create(*m_device, sizes.data(), static_cast<u32>(sizes.size()), max_draw_calls, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& memory_map = m_device->get_memory_mapping();
|
const auto& memory_map = m_device->get_memory_mapping();
|
||||||
@ -1063,8 +1064,7 @@ void VKGSRender::check_descriptors()
|
|||||||
{
|
{
|
||||||
// Ease resource pressure if the number of draw calls becomes too high or we are running low on memory resources
|
// Ease resource pressure if the number of draw calls becomes too high or we are running low on memory resources
|
||||||
const auto required_descriptors = rsx::method_registers.current_draw_clause.pass_count();
|
const auto required_descriptors = rsx::method_registers.current_draw_clause.pass_count();
|
||||||
ensure(required_descriptors < DESCRIPTOR_MAX_DRAW_CALLS);
|
if (!m_current_frame->descriptor_pool.can_allocate(required_descriptors, m_current_frame->used_descriptors))
|
||||||
if ((required_descriptors + m_current_frame->used_descriptors) > DESCRIPTOR_MAX_DRAW_CALLS)
|
|
||||||
{
|
{
|
||||||
// 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);
|
||||||
@ -1078,7 +1078,6 @@ VkDescriptorSet VKGSRender::allocate_descriptor_set()
|
|||||||
{
|
{
|
||||||
if (!m_shader_interpreter.is_interpreter(m_program)) [[likely]]
|
if (!m_shader_interpreter.is_interpreter(m_program)) [[likely]]
|
||||||
{
|
{
|
||||||
ensure(m_current_frame->used_descriptors < DESCRIPTOR_MAX_DRAW_CALLS);
|
|
||||||
return m_current_frame->descriptor_pool.allocate(descriptor_layouts, VK_TRUE, m_current_frame->used_descriptors++);
|
return m_current_frame->descriptor_pool.allocate(descriptor_layouts, VK_TRUE, m_current_frame->used_descriptors++);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "Emu/RSX/Common/TextureUtils.h"
|
#include "Emu/RSX/Common/TextureUtils.h"
|
||||||
#include "Emu/RSX/rsx_utils.h"
|
#include "Emu/RSX/rsx_utils.h"
|
||||||
|
|
||||||
#define DESCRIPTOR_MAX_DRAW_CALLS 16384
|
|
||||||
#define OCCLUSION_MAX_POOL_SIZE DESCRIPTOR_MAX_DRAW_CALLS
|
#define OCCLUSION_MAX_POOL_SIZE DESCRIPTOR_MAX_DRAW_CALLS
|
||||||
|
|
||||||
#define FRAME_PRESENT_TIMEOUT 10000000ull // 10 seconds
|
#define FRAME_PRESENT_TIMEOUT 10000000ull // 10 seconds
|
||||||
|
@ -373,13 +373,15 @@ namespace vk
|
|||||||
|
|
||||||
void shader_interpreter::create_descriptor_pools(const vk::render_device& dev)
|
void shader_interpreter::create_descriptor_pools(const vk::render_device& dev)
|
||||||
{
|
{
|
||||||
std::vector<VkDescriptorPoolSize> sizes;
|
const auto max_draw_calls = dev.get_descriptor_max_draw_calls();
|
||||||
sizes.push_back({ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER , 6 * DESCRIPTOR_MAX_DRAW_CALLS });
|
|
||||||
sizes.push_back({ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER , 3 * DESCRIPTOR_MAX_DRAW_CALLS });
|
|
||||||
sizes.push_back({ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER , 68 * DESCRIPTOR_MAX_DRAW_CALLS });
|
|
||||||
sizes.push_back({ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3 * DESCRIPTOR_MAX_DRAW_CALLS });
|
|
||||||
|
|
||||||
m_descriptor_pool.create(dev, sizes.data(), ::size32(sizes), DESCRIPTOR_MAX_DRAW_CALLS, 2);
|
std::vector<VkDescriptorPoolSize> sizes;
|
||||||
|
sizes.push_back({ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER , 6 * max_draw_calls });
|
||||||
|
sizes.push_back({ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER , 3 * max_draw_calls });
|
||||||
|
sizes.push_back({ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER , 68 * max_draw_calls });
|
||||||
|
sizes.push_back({ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3 * max_draw_calls });
|
||||||
|
|
||||||
|
m_descriptor_pool.create(dev, sizes.data(), ::size32(sizes), max_draw_calls, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void shader_interpreter::init(const vk::render_device& dev)
|
void shader_interpreter::init(const vk::render_device& dev)
|
||||||
@ -513,7 +515,7 @@ namespace vk
|
|||||||
|
|
||||||
VkDescriptorSet shader_interpreter::allocate_descriptor_set()
|
VkDescriptorSet shader_interpreter::allocate_descriptor_set()
|
||||||
{
|
{
|
||||||
if (m_used_descriptors == DESCRIPTOR_MAX_DRAW_CALLS)
|
if (!m_descriptor_pool.can_allocate(1u, m_used_descriptors))
|
||||||
{
|
{
|
||||||
m_descriptor_pool.reset(0);
|
m_descriptor_pool.reset(0);
|
||||||
m_used_descriptors = 0;
|
m_used_descriptors = 0;
|
||||||
|
@ -109,7 +109,7 @@ namespace vk
|
|||||||
{
|
{
|
||||||
ensure(subpool_count);
|
ensure(subpool_count);
|
||||||
|
|
||||||
info.flags = dev.get_descriptor_indexing_support() ? VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT : 0;
|
info.flags = dev.get_descriptor_update_after_bind_support() ? VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT : 0;
|
||||||
info.maxSets = max_sets;
|
info.maxSets = max_sets;
|
||||||
info.poolSizeCount = size_descriptors_count;
|
info.poolSizeCount = size_descriptors_count;
|
||||||
info.pPoolSizes = sizes;
|
info.pPoolSizes = sizes;
|
||||||
@ -139,16 +139,6 @@ namespace vk
|
|||||||
m_owner = nullptr;
|
m_owner = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool descriptor_pool::valid() const
|
|
||||||
{
|
|
||||||
return (!m_device_pools.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
descriptor_pool::operator VkDescriptorPool()
|
|
||||||
{
|
|
||||||
return m_current_pool_handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void descriptor_pool::reset(VkDescriptorPoolResetFlags flags)
|
void descriptor_pool::reset(VkDescriptorPoolResetFlags flags)
|
||||||
{
|
{
|
||||||
m_descriptor_set_cache.clear();
|
m_descriptor_set_cache.clear();
|
||||||
@ -194,11 +184,10 @@ namespace vk
|
|||||||
|
|
||||||
if (use_cache)
|
if (use_cache)
|
||||||
{
|
{
|
||||||
|
ensure(used_count < info.maxSets);
|
||||||
const auto alloc_size = std::min<u32>(info.maxSets - used_count, max_cache_size);
|
const auto alloc_size = std::min<u32>(info.maxSets - used_count, max_cache_size);
|
||||||
|
|
||||||
ensure(alloc_size);
|
|
||||||
ensure(m_descriptor_set_cache.empty());
|
ensure(m_descriptor_set_cache.empty());
|
||||||
|
|
||||||
alloc_info.descriptorSetCount = alloc_size;
|
alloc_info.descriptorSetCount = alloc_size;
|
||||||
alloc_info.pSetLayouts = m_allocation_request_cache.data();
|
alloc_info.pSetLayouts = m_allocation_request_cache.data();
|
||||||
|
|
||||||
|
@ -20,11 +20,13 @@ namespace vk
|
|||||||
void destroy();
|
void destroy();
|
||||||
void reset(VkDescriptorPoolResetFlags flags);
|
void reset(VkDescriptorPoolResetFlags flags);
|
||||||
|
|
||||||
bool valid() const;
|
|
||||||
operator VkDescriptorPool();
|
|
||||||
|
|
||||||
VkDescriptorSet allocate(VkDescriptorSetLayout layout, VkBool32 use_cache, u32 used_count);
|
VkDescriptorSet allocate(VkDescriptorSetLayout layout, VkBool32 use_cache, u32 used_count);
|
||||||
|
|
||||||
|
operator VkDescriptorPool() { return m_current_pool_handle; }
|
||||||
|
FORCE_INLINE bool valid() const { return (!m_device_pools.empty()); }
|
||||||
|
FORCE_INLINE u32 max_sets() const { return info.maxSets; }
|
||||||
|
FORCE_INLINE bool can_allocate(u32 required_count, u32 used_count) const { return (used_count + required_count) <= info.maxSets; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const vk::render_device* m_owner = nullptr;
|
const vk::render_device* m_owner = nullptr;
|
||||||
VkDescriptorPoolCreateInfo info = {};
|
VkDescriptorPoolCreateInfo info = {};
|
||||||
|
@ -85,13 +85,65 @@ namespace vk
|
|||||||
surface_capabilities_2_support = instance_extensions.is_supported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
surface_capabilities_2_support = instance_extensions.is_supported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void physical_device::get_physical_device_properties(bool allow_extensions)
|
||||||
|
{
|
||||||
|
vkGetPhysicalDeviceMemoryProperties(dev, &memory_properties);
|
||||||
|
|
||||||
|
if (!allow_extensions)
|
||||||
|
{
|
||||||
|
vkGetPhysicalDeviceProperties(dev, &props);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
supported_extensions instance_extensions(supported_extensions::instance);
|
||||||
|
if (!instance_extensions.is_supported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
|
||||||
|
{
|
||||||
|
vkGetPhysicalDeviceProperties(dev, &props);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VkPhysicalDeviceProperties2KHR properties2;
|
||||||
|
properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
|
||||||
|
properties2.pNext = nullptr;
|
||||||
|
|
||||||
|
VkPhysicalDeviceDescriptorIndexingPropertiesEXT descriptor_indexing_props{};
|
||||||
|
|
||||||
|
if (descriptor_indexing_support)
|
||||||
|
{
|
||||||
|
descriptor_indexing_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT;
|
||||||
|
descriptor_indexing_props.pNext = properties2.pNext;
|
||||||
|
properties2.pNext = &descriptor_indexing_props;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto _vkGetPhysicalDeviceProperties2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2KHR>(vkGetInstanceProcAddr(parent, "vkGetPhysicalDeviceProperties2KHR"));
|
||||||
|
ensure(_vkGetPhysicalDeviceProperties2KHR);
|
||||||
|
|
||||||
|
_vkGetPhysicalDeviceProperties2KHR(dev, &properties2);
|
||||||
|
props = properties2.properties;
|
||||||
|
|
||||||
|
if (descriptor_indexing_support)
|
||||||
|
{
|
||||||
|
if (descriptor_indexing_props.maxUpdateAfterBindDescriptorsInAllPools < 800'000)
|
||||||
|
{
|
||||||
|
rsx_log.error("Physical device does not support enough descriptors for deferred updates to work effectively. Deferred updates are disabled.");
|
||||||
|
descriptor_update_after_bind_mask = 0;
|
||||||
|
}
|
||||||
|
else if (descriptor_indexing_props.maxUpdateAfterBindDescriptorsInAllPools < 2'000'000)
|
||||||
|
{
|
||||||
|
rsx_log.warning("Physical device reports a low amount of allowed deferred descriptor updates. Draw call threshold will be lowered accordingly.");
|
||||||
|
descriptor_max_draw_calls = 8192;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void physical_device::create(VkInstance context, VkPhysicalDevice pdev, bool allow_extensions)
|
void physical_device::create(VkInstance context, VkPhysicalDevice pdev, bool allow_extensions)
|
||||||
{
|
{
|
||||||
dev = pdev;
|
dev = pdev;
|
||||||
parent = context;
|
parent = context;
|
||||||
vkGetPhysicalDeviceProperties(pdev, &props);
|
|
||||||
vkGetPhysicalDeviceMemoryProperties(pdev, &memory_properties);
|
|
||||||
get_physical_device_features(allow_extensions);
|
get_physical_device_features(allow_extensions);
|
||||||
|
get_physical_device_properties(allow_extensions);
|
||||||
|
|
||||||
rsx_log.always()("Found vulkan-compatible GPU: '%s' running on driver %s", get_name(), get_driver_version());
|
rsx_log.always()("Found vulkan-compatible GPU: '%s' running on driver %s", get_name(), get_driver_version());
|
||||||
|
|
||||||
@ -714,6 +766,11 @@ namespace vk
|
|||||||
return pgpu->descriptor_update_after_bind_mask;
|
return pgpu->descriptor_update_after_bind_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 render_device::get_descriptor_max_draw_calls() const
|
||||||
|
{
|
||||||
|
return pgpu->descriptor_max_draw_calls;
|
||||||
|
}
|
||||||
|
|
||||||
mem_allocator_base* render_device::get_allocator() const
|
mem_allocator_base* render_device::get_allocator() const
|
||||||
{
|
{
|
||||||
return m_allocator.get();
|
return m_allocator.get();
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#define DESCRIPTOR_MAX_DRAW_CALLS 16384
|
||||||
|
|
||||||
namespace vk
|
namespace vk
|
||||||
{
|
{
|
||||||
struct gpu_formats_support
|
struct gpu_formats_support
|
||||||
@ -62,10 +64,12 @@ namespace vk
|
|||||||
bool descriptor_indexing_support = false;
|
bool descriptor_indexing_support = false;
|
||||||
|
|
||||||
u64 descriptor_update_after_bind_mask = 0;
|
u64 descriptor_update_after_bind_mask = 0;
|
||||||
|
u32 descriptor_max_draw_calls = DESCRIPTOR_MAX_DRAW_CALLS;
|
||||||
|
|
||||||
friend class render_device;
|
friend class render_device;
|
||||||
private:
|
private:
|
||||||
void get_physical_device_features(bool allow_extensions);
|
void get_physical_device_features(bool allow_extensions);
|
||||||
|
void get_physical_device_properties(bool allow_extensions);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -147,6 +151,7 @@ namespace vk
|
|||||||
bool get_descriptor_indexing_support() const;
|
bool get_descriptor_indexing_support() const;
|
||||||
|
|
||||||
u64 get_descriptor_update_after_bind_support() const;
|
u64 get_descriptor_update_after_bind_support() const;
|
||||||
|
u32 get_descriptor_max_draw_calls() const;
|
||||||
|
|
||||||
VkQueue get_present_queue() const;
|
VkQueue get_present_queue() const;
|
||||||
VkQueue get_graphics_queue() const;
|
VkQueue get_graphics_queue() const;
|
||||||
|
Loading…
Reference in New Issue
Block a user