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);
VkDescriptorSetLayoutBindingFlagsCreateInfo binding_infos = {};
std::vector<VkDescriptorBindingFlags> binding_flags;
rsx::simple_array<VkDescriptorBindingFlags> binding_flags;
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.pNext = nullptr;
@ -197,19 +210,19 @@ namespace vk
{
if (!m_in_use) [[unlikely]]
{
m_image_info_pool.reserve(max_cache_size + 16);
m_buffer_view_pool.reserve(max_cache_size + 16);
m_buffer_info_pool.reserve(max_cache_size + 16);
m_image_info_pool.reserve(m_pool_size);
m_buffer_view_pool.reserve(m_pool_size);
m_buffer_info_pool.reserve(m_pool_size);
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);
}
}
else if (!m_update_after_bind)
else if (m_push_type_mask & ~m_update_after_bind_mask)
{
flush();
}
@ -233,6 +246,11 @@ namespace vk
VkDescriptorSet* descriptor_set::ptr()
{
if (!m_in_use) [[likely]]
{
init(m_handle);
}
return &m_handle;
}
@ -243,11 +261,7 @@ namespace vk
void descriptor_set::push(const VkBufferView& buffer_view, VkDescriptorType type, u32 binding)
{
if (m_pending_writes.size() > max_cache_size)
{
flush();
}
m_push_type_mask |= (1ull << type);
m_buffer_view_pool.push_back(buffer_view);
m_pending_writes.push_back(
{
@ -266,11 +280,7 @@ namespace vk
void descriptor_set::push(const VkDescriptorBufferInfo& buffer_info, VkDescriptorType type, u32 binding)
{
if (m_pending_writes.size() > max_cache_size)
{
flush();
}
m_push_type_mask |= (1ull << type);
m_buffer_info_pool.push_back(buffer_info);
m_pending_writes.push_back(
{
@ -289,11 +299,7 @@ namespace vk
void descriptor_set::push(const VkDescriptorImageInfo& image_info, VkDescriptorType type, u32 binding)
{
if (m_pending_writes.size() >= max_cache_size)
{
flush();
}
m_push_type_mask |= (1ull << type);
m_image_info_pool.push_back(image_info);
m_pending_writes.push_back(
{
@ -336,8 +342,8 @@ namespace vk
}
else
{
const size_t old_size = m_pending_copies.size();
const size_t new_size = copy_cmd.size() + old_size;
const auto old_size = m_pending_copies.size();
const auto new_size = copy_cmd.size() + old_size;
m_pending_copies.resize(new_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)
{
if (!m_update_after_bind)
if ((m_push_type_mask & ~m_update_after_bind_mask) || (m_pending_writes.size() >= max_cache_size))
{
flush();
}
@ -360,7 +366,7 @@ namespace vk
void descriptor_set::flush()
{
if (m_pending_writes.empty() && m_pending_copies.empty())
if (!m_push_type_mask)
{
return;
}
@ -369,6 +375,7 @@ namespace vk
const auto num_copies = ::size32(m_pending_copies);
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_copies.clear();
m_image_info_pool.clear();

View File

@ -33,7 +33,7 @@ namespace vk
VkDescriptorPool m_current_pool_handle = VK_NULL_HANDLE;
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;
rsx::simple_array<VkDescriptorSet> m_descriptor_set_cache;
rsx::simple_array<VkDescriptorSetLayout> m_allocation_request_cache;
@ -41,7 +41,10 @@ namespace vk
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);
public:
@ -69,7 +72,8 @@ namespace vk
private:
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;
rsx::simple_array<VkBufferView> m_buffer_view_pool;

View File

@ -30,6 +30,7 @@ namespace vk
features2.pNext = nullptr;
VkPhysicalDeviceFloat16Int8FeaturesKHR shader_support_info{};
VkPhysicalDeviceDescriptorIndexingFeatures descriptor_indexing_info{};
if (device_extensions.is_supported(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME))
{
@ -44,6 +45,14 @@ namespace vk
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"));
ensure(_vkGetPhysicalDeviceFeatures2KHR); // "vkGetInstanceProcAddress failed to find entry point!"
_vkGetPhysicalDeviceFeatures2KHR(dev, &features2);
@ -52,11 +61,23 @@ namespace vk
shader_types_support.allow_float16 = !!shader_support_info.shaderFloat16;
shader_types_support.allow_int8 = !!shader_support_info.shaderInt8;
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);
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);
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);
@ -464,11 +485,17 @@ namespace vk
VkPhysicalDeviceDescriptorIndexingFeatures indexing_features{};
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.descriptorBindingUniformTexelBufferUpdateAfterBind = VK_TRUE;
indexing_features.descriptorBindingUniformBufferUpdateAfterBind = VK_TRUE;
indexing_features.descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE;
indexing_features.descriptorBindingSampledImageUpdateAfterBind = VK_TRUE;
device.pNext = &indexing_features;
}
@ -682,6 +709,11 @@ namespace vk
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
{
return m_allocator.get();

View File

@ -61,6 +61,8 @@ namespace vk
bool sampler_mirror_clamped_support = false;
bool descriptor_indexing_support = false;
u64 descriptor_update_after_bind_mask = 0;
friend class render_device;
private:
void get_physical_device_features(bool allow_extensions);
@ -144,6 +146,8 @@ namespace vk
bool get_debug_utils_support() const;
bool get_descriptor_indexing_support() const;
u64 get_descriptor_update_after_bind_support() const;
VkQueue get_present_queue() const;
VkQueue get_graphics_queue() const;
VkQueue get_transfer_queue() const;