vk: Make the new descriptor system spec compliant

This commit is contained in:
kd-11 2021-09-25 23:53:34 +03:00 committed by kd-11
parent 9595297a3a
commit eed38e1bbc
4 changed files with 82 additions and 35 deletions

View file

@ -56,11 +56,24 @@ namespace vk
infos.bindingCount = ::size32(bindings); infos.bindingCount = ::size32(bindings);
VkDescriptorSetLayoutBindingFlagsCreateInfo binding_infos = {}; VkDescriptorSetLayoutBindingFlagsCreateInfo binding_infos = {};
std::vector<VkDescriptorBindingFlags> binding_flags; rsx::simple_array<VkDescriptorBindingFlags> binding_flags;
if (g_render_device->get_descriptor_indexing_support()) if (g_render_device->get_descriptor_indexing_support())
{ {
binding_flags.resize(bindings.size(), VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT); const auto deferred_mask = g_render_device->get_descriptor_update_after_bind_support();
binding_flags.resize(::size32(bindings));
for (u32 i = 0; i < binding_flags.size(); ++i)
{
if ((1ull << bindings[i].descriptorType) & ~deferred_mask)
{
binding_flags[i] = 0u;
}
else
{
binding_flags[i] = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT;
}
}
binding_infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT; binding_infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT;
binding_infos.pNext = nullptr; binding_infos.pNext = nullptr;
@ -197,19 +210,19 @@ namespace vk
{ {
if (!m_in_use) [[unlikely]] if (!m_in_use) [[unlikely]]
{ {
m_image_info_pool.reserve(max_cache_size + 16); m_image_info_pool.reserve(m_pool_size);
m_buffer_view_pool.reserve(max_cache_size + 16); m_buffer_view_pool.reserve(m_pool_size);
m_buffer_info_pool.reserve(max_cache_size + 16); m_buffer_info_pool.reserve(m_pool_size);
m_in_use = true; m_in_use = true;
m_update_after_bind = g_render_device->get_descriptor_indexing_support(); m_update_after_bind_mask = g_render_device->get_descriptor_update_after_bind_support();
if (m_update_after_bind) if (m_update_after_bind_mask)
{ {
g_fxo->get<descriptors::dispatch_manager>().notify(this); g_fxo->get<descriptors::dispatch_manager>().notify(this);
} }
} }
else if (!m_update_after_bind) else if (m_push_type_mask & ~m_update_after_bind_mask)
{ {
flush(); flush();
} }
@ -233,6 +246,11 @@ namespace vk
VkDescriptorSet* descriptor_set::ptr() VkDescriptorSet* descriptor_set::ptr()
{ {
if (!m_in_use) [[likely]]
{
init(m_handle);
}
return &m_handle; return &m_handle;
} }
@ -243,11 +261,7 @@ namespace vk
void descriptor_set::push(const VkBufferView& buffer_view, VkDescriptorType type, u32 binding) void descriptor_set::push(const VkBufferView& buffer_view, VkDescriptorType type, u32 binding)
{ {
if (m_pending_writes.size() > max_cache_size) m_push_type_mask |= (1ull << type);
{
flush();
}
m_buffer_view_pool.push_back(buffer_view); m_buffer_view_pool.push_back(buffer_view);
m_pending_writes.push_back( m_pending_writes.push_back(
{ {
@ -266,11 +280,7 @@ namespace vk
void descriptor_set::push(const VkDescriptorBufferInfo& buffer_info, VkDescriptorType type, u32 binding) void descriptor_set::push(const VkDescriptorBufferInfo& buffer_info, VkDescriptorType type, u32 binding)
{ {
if (m_pending_writes.size() > max_cache_size) m_push_type_mask |= (1ull << type);
{
flush();
}
m_buffer_info_pool.push_back(buffer_info); m_buffer_info_pool.push_back(buffer_info);
m_pending_writes.push_back( m_pending_writes.push_back(
{ {
@ -289,11 +299,7 @@ namespace vk
void descriptor_set::push(const VkDescriptorImageInfo& image_info, VkDescriptorType type, u32 binding) void descriptor_set::push(const VkDescriptorImageInfo& image_info, VkDescriptorType type, u32 binding)
{ {
if (m_pending_writes.size() >= max_cache_size) m_push_type_mask |= (1ull << type);
{
flush();
}
m_image_info_pool.push_back(image_info); m_image_info_pool.push_back(image_info);
m_pending_writes.push_back( m_pending_writes.push_back(
{ {
@ -336,8 +342,8 @@ namespace vk
} }
else else
{ {
const size_t old_size = m_pending_copies.size(); const auto old_size = m_pending_copies.size();
const size_t new_size = copy_cmd.size() + old_size; const auto new_size = copy_cmd.size() + old_size;
m_pending_copies.resize(new_size); m_pending_copies.resize(new_size);
std::copy(copy_cmd.begin(), copy_cmd.end(), m_pending_copies.begin() + old_size); std::copy(copy_cmd.begin(), copy_cmd.end(), m_pending_copies.begin() + old_size);
} }
@ -345,7 +351,7 @@ namespace vk
void descriptor_set::bind(VkCommandBuffer cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout) void descriptor_set::bind(VkCommandBuffer cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout)
{ {
if (!m_update_after_bind) if ((m_push_type_mask & ~m_update_after_bind_mask) || (m_pending_writes.size() >= max_cache_size))
{ {
flush(); flush();
} }
@ -360,7 +366,7 @@ namespace vk
void descriptor_set::flush() void descriptor_set::flush()
{ {
if (m_pending_writes.empty() && m_pending_copies.empty()) if (!m_push_type_mask)
{ {
return; return;
} }
@ -369,6 +375,7 @@ namespace vk
const auto num_copies = ::size32(m_pending_copies); const auto num_copies = ::size32(m_pending_copies);
vkUpdateDescriptorSets(*g_render_device, num_writes, m_pending_writes.data(), num_copies, m_pending_copies.data()); vkUpdateDescriptorSets(*g_render_device, num_writes, m_pending_writes.data(), num_copies, m_pending_copies.data());
m_push_type_mask = 0;
m_pending_writes.clear(); m_pending_writes.clear();
m_pending_copies.clear(); m_pending_copies.clear();
m_image_info_pool.clear(); m_image_info_pool.clear();

View file

@ -33,7 +33,7 @@ namespace vk
VkDescriptorPool m_current_pool_handle = VK_NULL_HANDLE; VkDescriptorPool m_current_pool_handle = VK_NULL_HANDLE;
u32 m_current_pool_index = 0; u32 m_current_pool_index = 0;
static const size_t max_cache_size = 64; static constexpr size_t max_cache_size = 64;
VkDescriptorSetLayout m_cached_layout = VK_NULL_HANDLE; VkDescriptorSetLayout m_cached_layout = VK_NULL_HANDLE;
rsx::simple_array<VkDescriptorSet> m_descriptor_set_cache; rsx::simple_array<VkDescriptorSet> m_descriptor_set_cache;
rsx::simple_array<VkDescriptorSetLayout> m_allocation_request_cache; rsx::simple_array<VkDescriptorSetLayout> m_allocation_request_cache;
@ -41,7 +41,10 @@ namespace vk
class descriptor_set class descriptor_set
{ {
static const size_t max_cache_size = 16384; static constexpr size_t max_cache_size = 16384;
static constexpr size_t max_overflow_size = 64;
static constexpr size_t m_pool_size = max_cache_size + max_overflow_size;
void init(VkDescriptorSet new_set); void init(VkDescriptorSet new_set);
public: public:
@ -69,7 +72,8 @@ namespace vk
private: private:
VkDescriptorSet m_handle = VK_NULL_HANDLE; VkDescriptorSet m_handle = VK_NULL_HANDLE;
bool m_update_after_bind = false; u64 m_update_after_bind_mask = 0;
u64 m_push_type_mask = 0;
bool m_in_use = false; bool m_in_use = false;
rsx::simple_array<VkBufferView> m_buffer_view_pool; rsx::simple_array<VkBufferView> m_buffer_view_pool;

View file

@ -30,6 +30,7 @@ namespace vk
features2.pNext = nullptr; features2.pNext = nullptr;
VkPhysicalDeviceFloat16Int8FeaturesKHR shader_support_info{}; VkPhysicalDeviceFloat16Int8FeaturesKHR shader_support_info{};
VkPhysicalDeviceDescriptorIndexingFeatures descriptor_indexing_info{};
if (device_extensions.is_supported(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME)) if (device_extensions.is_supported(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME))
{ {
@ -44,6 +45,14 @@ namespace vk
features2.pNext = &driver_properties; features2.pNext = &driver_properties;
} }
if (device_extensions.is_supported(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME))
{
descriptor_indexing_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
descriptor_indexing_info.pNext = features2.pNext;
features2.pNext = &descriptor_indexing_info;
descriptor_indexing_support = true;
}
auto _vkGetPhysicalDeviceFeatures2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>(vkGetInstanceProcAddr(parent, "vkGetPhysicalDeviceFeatures2KHR")); auto _vkGetPhysicalDeviceFeatures2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>(vkGetInstanceProcAddr(parent, "vkGetPhysicalDeviceFeatures2KHR"));
ensure(_vkGetPhysicalDeviceFeatures2KHR); // "vkGetInstanceProcAddress failed to find entry point!" ensure(_vkGetPhysicalDeviceFeatures2KHR); // "vkGetInstanceProcAddress failed to find entry point!"
_vkGetPhysicalDeviceFeatures2KHR(dev, &features2); _vkGetPhysicalDeviceFeatures2KHR(dev, &features2);
@ -52,11 +61,23 @@ namespace vk
shader_types_support.allow_float16 = !!shader_support_info.shaderFloat16; shader_types_support.allow_float16 = !!shader_support_info.shaderFloat16;
shader_types_support.allow_int8 = !!shader_support_info.shaderInt8; shader_types_support.allow_int8 = !!shader_support_info.shaderInt8;
features = features2.features; features = features2.features;
if (descriptor_indexing_support)
{
#define SET_DESCRIPTOR_BITFLAG(field, bit) if (descriptor_indexing_info.field) descriptor_update_after_bind_mask |= (1ull << bit)
SET_DESCRIPTOR_BITFLAG(descriptorBindingUniformBufferUpdateAfterBind, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
SET_DESCRIPTOR_BITFLAG(descriptorBindingSampledImageUpdateAfterBind, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
SET_DESCRIPTOR_BITFLAG(descriptorBindingSampledImageUpdateAfterBind, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
SET_DESCRIPTOR_BITFLAG(descriptorBindingStorageImageUpdateAfterBind, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
SET_DESCRIPTOR_BITFLAG(descriptorBindingStorageBufferUpdateAfterBind, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
SET_DESCRIPTOR_BITFLAG(descriptorBindingUniformTexelBufferUpdateAfterBind, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER);
SET_DESCRIPTOR_BITFLAG(descriptorBindingStorageTexelBufferUpdateAfterBind, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
#undef SET_DESCRIPTOR_BITFLAG
}
} }
stencil_export_support = device_extensions.is_supported(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME); stencil_export_support = device_extensions.is_supported(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME);
conditional_render_support = device_extensions.is_supported(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME); conditional_render_support = device_extensions.is_supported(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME);
descriptor_indexing_support = device_extensions.is_supported(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
external_memory_host_support = device_extensions.is_supported(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME); external_memory_host_support = device_extensions.is_supported(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME);
sampler_mirror_clamped_support = device_extensions.is_supported(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME); sampler_mirror_clamped_support = device_extensions.is_supported(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME);
unrestricted_depth_range_support = device_extensions.is_supported(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME); unrestricted_depth_range_support = device_extensions.is_supported(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME);
@ -464,11 +485,17 @@ namespace vk
VkPhysicalDeviceDescriptorIndexingFeatures indexing_features{}; VkPhysicalDeviceDescriptorIndexingFeatures indexing_features{};
if (pgpu->descriptor_indexing_support) if (pgpu->descriptor_indexing_support)
{ {
#define SET_DESCRIPTOR_BITFLAG(field, bit) if (pgpu->descriptor_update_after_bind_mask & (1ull << bit)) indexing_features.field = VK_TRUE
SET_DESCRIPTOR_BITFLAG(descriptorBindingUniformBufferUpdateAfterBind, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
SET_DESCRIPTOR_BITFLAG(descriptorBindingSampledImageUpdateAfterBind, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
SET_DESCRIPTOR_BITFLAG(descriptorBindingSampledImageUpdateAfterBind, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
SET_DESCRIPTOR_BITFLAG(descriptorBindingStorageImageUpdateAfterBind, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
SET_DESCRIPTOR_BITFLAG(descriptorBindingStorageBufferUpdateAfterBind, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
SET_DESCRIPTOR_BITFLAG(descriptorBindingUniformTexelBufferUpdateAfterBind, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER);
SET_DESCRIPTOR_BITFLAG(descriptorBindingStorageTexelBufferUpdateAfterBind, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
#undef SET_DESCRIPTOR_BITFLAG
indexing_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; indexing_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
indexing_features.descriptorBindingUniformTexelBufferUpdateAfterBind = VK_TRUE;
indexing_features.descriptorBindingUniformBufferUpdateAfterBind = VK_TRUE;
indexing_features.descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE;
indexing_features.descriptorBindingSampledImageUpdateAfterBind = VK_TRUE;
device.pNext = &indexing_features; device.pNext = &indexing_features;
} }
@ -682,6 +709,11 @@ namespace vk
return pgpu->descriptor_indexing_support; return pgpu->descriptor_indexing_support;
} }
u64 render_device::get_descriptor_update_after_bind_support() const
{
return pgpu->descriptor_update_after_bind_mask;
}
mem_allocator_base* render_device::get_allocator() const mem_allocator_base* render_device::get_allocator() const
{ {
return m_allocator.get(); return m_allocator.get();

View file

@ -61,6 +61,8 @@ namespace vk
bool sampler_mirror_clamped_support = false; bool sampler_mirror_clamped_support = false;
bool descriptor_indexing_support = false; bool descriptor_indexing_support = false;
u64 descriptor_update_after_bind_mask = 0;
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);
@ -144,6 +146,8 @@ namespace vk
bool get_debug_utils_support() const; bool get_debug_utils_support() const;
bool get_descriptor_indexing_support() const; bool get_descriptor_indexing_support() const;
u64 get_descriptor_update_after_bind_support() const;
VkQueue get_present_queue() const; VkQueue get_present_queue() const;
VkQueue get_graphics_queue() const; VkQueue get_graphics_queue() const;
VkQueue get_transfer_queue() const; VkQueue get_transfer_queue() const;