mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-10 00:41:26 +12:00
vk: Enable deferred descriptor updates via descriptor-indexing
This commit is contained in:
parent
381c7544fa
commit
ba2a8ebf2e
10 changed files with 164 additions and 66 deletions
|
@ -1,9 +1,12 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "VKCommandStream.h"
|
#include "VKCommandStream.h"
|
||||||
|
#include "vkutils/descriptors.h"
|
||||||
#include "vkutils/sync.h"
|
#include "vkutils/sync.h"
|
||||||
|
|
||||||
#include "Emu/IdManager.h"
|
#include "Emu/IdManager.h"
|
||||||
#include "Emu/system_config.h"
|
|
||||||
#include "Emu/RSX/RSXOffload.h"
|
#include "Emu/RSX/RSXOffload.h"
|
||||||
|
#include "Emu/RSX/RSXThread.h"
|
||||||
|
#include "Emu/system_config.h"
|
||||||
|
|
||||||
namespace vk
|
namespace vk
|
||||||
{
|
{
|
||||||
|
@ -22,6 +25,11 @@ namespace vk
|
||||||
|
|
||||||
void queue_submit(VkQueue queue, const VkSubmitInfo* info, fence* pfence, VkBool32 flush)
|
void queue_submit(VkQueue queue, const VkSubmitInfo* info, fence* pfence, VkBool32 flush)
|
||||||
{
|
{
|
||||||
|
if (rsx::get_current_renderer()->is_current_thread())
|
||||||
|
{
|
||||||
|
vk::descriptors::flush();
|
||||||
|
}
|
||||||
|
|
||||||
if (!flush && g_cfg.video.multithreaded_rsx)
|
if (!flush && g_cfg.video.multithreaded_rsx)
|
||||||
{
|
{
|
||||||
auto packet = new submit_packet(queue, pfence, info);
|
auto packet = new submit_packet(queue, pfence, info);
|
||||||
|
|
|
@ -39,13 +39,7 @@ namespace vk
|
||||||
|
|
||||||
// Reserve descriptor pools
|
// Reserve descriptor pools
|
||||||
m_descriptor_pool.create(*g_render_device, descriptor_pool_sizes.data(), ::size32(descriptor_pool_sizes), VK_MAX_COMPUTE_TASKS, 3);
|
m_descriptor_pool.create(*g_render_device, descriptor_pool_sizes.data(), ::size32(descriptor_pool_sizes), VK_MAX_COMPUTE_TASKS, 3);
|
||||||
|
m_descriptor_layout = vk::descriptors::create_layout(bindings);
|
||||||
VkDescriptorSetLayoutCreateInfo infos = {};
|
|
||||||
infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
|
||||||
infos.pBindings = bindings.data();
|
|
||||||
infos.bindingCount = ::size32(bindings);
|
|
||||||
|
|
||||||
CHECK_RESULT(vkCreateDescriptorSetLayout(*g_render_device, &infos, nullptr, &m_descriptor_layout));
|
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo layout_info = {};
|
VkPipelineLayoutCreateInfo layout_info = {};
|
||||||
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
|
|
|
@ -301,13 +301,7 @@ namespace
|
||||||
push_constants[0].size = 20;
|
push_constants[0].size = 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorSetLayoutCreateInfo infos = {};
|
const auto set_layout = vk::descriptors::create_layout(bindings);
|
||||||
infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
|
||||||
infos.pBindings = bindings.data();
|
|
||||||
infos.bindingCount = static_cast<u32>(bindings.size());
|
|
||||||
|
|
||||||
VkDescriptorSetLayout set_layout;
|
|
||||||
CHECK_RESULT(vkCreateDescriptorSetLayout(dev, &infos, nullptr, &set_layout));
|
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo layout_info = {};
|
VkPipelineLayoutCreateInfo layout_info = {};
|
||||||
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
|
|
|
@ -167,6 +167,8 @@ namespace vk
|
||||||
vkDestroyBuffer(*g_render_device, tmp, nullptr);
|
vkDestroyBuffer(*g_render_device, tmp, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
descriptors::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
VkFlags get_heap_compatible_buffer_types()
|
VkFlags get_heap_compatible_buffer_types()
|
||||||
|
|
|
@ -95,13 +95,7 @@ namespace vk
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure(descriptor_index == num_bindings);
|
ensure(descriptor_index == num_bindings);
|
||||||
|
m_descriptor_layout = vk::descriptors::create_layout(bindings);
|
||||||
VkDescriptorSetLayoutCreateInfo infos = {};
|
|
||||||
infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
|
||||||
infos.pBindings = bindings.data();
|
|
||||||
infos.bindingCount = ::size32(bindings);
|
|
||||||
|
|
||||||
CHECK_RESULT(vkCreateDescriptorSetLayout(*m_device, &infos, nullptr, &m_descriptor_layout));
|
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo layout_info = {};
|
VkPipelineLayoutCreateInfo layout_info = {};
|
||||||
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
|
|
|
@ -357,13 +357,7 @@ namespace vk
|
||||||
push_constants[0].size = 20;
|
push_constants[0].size = 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorSetLayoutCreateInfo infos = {};
|
const auto set_layout = vk::descriptors::create_layout(bindings);
|
||||||
infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
|
||||||
infos.pBindings = bindings.data();
|
|
||||||
infos.bindingCount = static_cast<u32>(bindings.size());
|
|
||||||
|
|
||||||
VkDescriptorSetLayout set_layout;
|
|
||||||
CHECK_RESULT(vkCreateDescriptorSetLayout(dev, &infos, nullptr, &set_layout));
|
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo layout_info = {};
|
VkPipelineLayoutCreateInfo layout_info = {};
|
||||||
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
|
|
|
@ -45,23 +45,21 @@ namespace vk
|
||||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 120 },
|
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 120 },
|
||||||
};
|
};
|
||||||
|
|
||||||
//Reserve descriptor pools
|
// Reserve descriptor pools
|
||||||
m_descriptor_pool.create(dev, descriptor_pools, 1, 120, 2);
|
m_descriptor_pool.create(dev, descriptor_pools, 1, 120, 2);
|
||||||
|
|
||||||
VkDescriptorSetLayoutBinding bindings[1] = {};
|
// Scale and offset data plus output color
|
||||||
|
std::vector<VkDescriptorSetLayoutBinding> bindings =
|
||||||
//Scale and offset data plus output color
|
{
|
||||||
bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
{
|
||||||
bindings[0].descriptorCount = 1;
|
.binding = 0,
|
||||||
bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||||
bindings[0].binding = 0;
|
.descriptorCount = 1,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
||||||
VkDescriptorSetLayoutCreateInfo infos = {};
|
.pImmutableSamplers = nullptr
|
||||||
infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
}
|
||||||
infos.pBindings = bindings;
|
};
|
||||||
infos.bindingCount = 1;
|
m_descriptor_layout = vk::descriptors::create_layout(bindings);
|
||||||
|
|
||||||
CHECK_RESULT(vkCreateDescriptorSetLayout(dev, &infos, nullptr, &m_descriptor_layout));
|
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo layout_info = {};
|
VkPipelineLayoutCreateInfo layout_info = {};
|
||||||
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
|
|
|
@ -1,13 +1,81 @@
|
||||||
|
#include "Emu/IdManager.h"
|
||||||
#include "descriptors.h"
|
#include "descriptors.h"
|
||||||
|
|
||||||
namespace vk
|
namespace vk
|
||||||
{
|
{
|
||||||
|
namespace descriptors
|
||||||
|
{
|
||||||
|
class dispatch_manager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void flush_all()
|
||||||
|
{
|
||||||
|
for (auto& set : m_notification_list)
|
||||||
|
{
|
||||||
|
set->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void notify(descriptor_set* set)
|
||||||
|
{
|
||||||
|
m_notification_list.push_back(set);
|
||||||
|
rsx_log.error("Now monitoring %u descriptor sets", m_notification_list.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch_manager() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
rsx::simple_array<descriptor_set*> m_notification_list;
|
||||||
|
|
||||||
|
dispatch_manager(const dispatch_manager&) = delete;
|
||||||
|
dispatch_manager& operator = (const dispatch_manager&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
void init()
|
||||||
|
{
|
||||||
|
g_fxo->init<dispatch_manager>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush()
|
||||||
|
{
|
||||||
|
g_fxo->get<dispatch_manager>().flush_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
VkDescriptorSetLayout create_layout(const std::vector<VkDescriptorSetLayoutBinding>& bindings)
|
||||||
|
{
|
||||||
|
VkDescriptorSetLayoutCreateInfo infos = {};
|
||||||
|
infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||||
|
infos.pBindings = bindings.data();
|
||||||
|
infos.bindingCount = ::size32(bindings);
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutBindingFlagsCreateInfo binding_infos = {};
|
||||||
|
std::vector<VkDescriptorBindingFlags> binding_flags;
|
||||||
|
|
||||||
|
if (g_render_device->get_descriptor_indexing_support())
|
||||||
|
{
|
||||||
|
binding_flags.resize(bindings.size(), 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;
|
||||||
|
binding_infos.bindingCount = ::size32(binding_flags);
|
||||||
|
binding_infos.pBindingFlags = binding_flags.data();
|
||||||
|
|
||||||
|
infos.pNext = &binding_infos;
|
||||||
|
infos.flags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkDescriptorSetLayout result;
|
||||||
|
CHECK_RESULT(vkCreateDescriptorSetLayout(*g_render_device, &infos, nullptr, &result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void descriptor_pool::create(const vk::render_device& dev, VkDescriptorPoolSize* sizes, u32 size_descriptors_count, u32 max_sets, u8 subpool_count)
|
void descriptor_pool::create(const vk::render_device& dev, VkDescriptorPoolSize* sizes, u32 size_descriptors_count, u32 max_sets, u8 subpool_count)
|
||||||
{
|
{
|
||||||
ensure(subpool_count);
|
ensure(subpool_count);
|
||||||
|
|
||||||
VkDescriptorPoolCreateInfo infos = {};
|
VkDescriptorPoolCreateInfo infos = {};
|
||||||
infos.flags = 0;
|
infos.flags = dev.get_descriptor_indexing_support() ? VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT : 0;
|
||||||
infos.maxSets = max_sets;
|
infos.maxSets = max_sets;
|
||||||
infos.poolSizeCount = size_descriptors_count;
|
infos.poolSizeCount = size_descriptors_count;
|
||||||
infos.pPoolSizes = sizes;
|
infos.pPoolSizes = sizes;
|
||||||
|
@ -57,44 +125,49 @@ namespace vk
|
||||||
descriptor_set::descriptor_set(VkDescriptorSet set)
|
descriptor_set::descriptor_set(VkDescriptorSet set)
|
||||||
{
|
{
|
||||||
flush();
|
flush();
|
||||||
init();
|
|
||||||
m_handle = set;
|
m_handle = set;
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptor_set::descriptor_set()
|
void descriptor_set::init(VkDescriptorSet new_set)
|
||||||
{
|
{
|
||||||
init();
|
if (!m_in_use) [[unlikely]]
|
||||||
}
|
|
||||||
|
|
||||||
void descriptor_set::init()
|
|
||||||
{
|
|
||||||
if (m_image_info_pool.capacity() == 0)
|
|
||||||
{
|
{
|
||||||
m_image_info_pool.reserve(max_cache_size + 16);
|
m_image_info_pool.reserve(max_cache_size + 16);
|
||||||
m_buffer_view_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_buffer_info_pool.reserve(max_cache_size + 16);
|
||||||
|
|
||||||
|
m_in_use = true;
|
||||||
|
m_update_after_bind = g_render_device->get_descriptor_indexing_support();
|
||||||
|
|
||||||
|
if (m_update_after_bind)
|
||||||
|
{
|
||||||
|
g_fxo->get<descriptors::dispatch_manager>().notify(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (!m_update_after_bind)
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_handle = new_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
void descriptor_set::swap(descriptor_set& other)
|
void descriptor_set::swap(descriptor_set& other)
|
||||||
{
|
{
|
||||||
|
const auto other_handle = other.m_handle;
|
||||||
other.flush();
|
other.flush();
|
||||||
flush();
|
other.m_handle = m_handle;
|
||||||
|
init(other_handle);
|
||||||
std::swap(m_handle, other.m_handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptor_set& descriptor_set::operator = (VkDescriptorSet set)
|
descriptor_set& descriptor_set::operator = (VkDescriptorSet set)
|
||||||
{
|
{
|
||||||
flush();
|
init(set);
|
||||||
m_handle = set;
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorSet* descriptor_set::ptr()
|
VkDescriptorSet* descriptor_set::ptr()
|
||||||
{
|
{
|
||||||
// TODO: You shouldn't need this
|
|
||||||
// ensure(m_handle == VK_NULL_HANDLE);
|
|
||||||
return &m_handle;
|
return &m_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +178,11 @@ 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)
|
||||||
|
{
|
||||||
|
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(
|
||||||
{
|
{
|
||||||
|
@ -123,6 +201,11 @@ 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)
|
||||||
|
{
|
||||||
|
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(
|
||||||
{
|
{
|
||||||
|
@ -141,6 +224,11 @@ 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)
|
||||||
|
{
|
||||||
|
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(
|
||||||
{
|
{
|
||||||
|
@ -192,7 +280,11 @@ namespace vk
|
||||||
|
|
||||||
void descriptor_set::bind(VkCommandBuffer cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout)
|
void descriptor_set::bind(VkCommandBuffer cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout)
|
||||||
{
|
{
|
||||||
flush();
|
if (!m_update_after_bind)
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
|
||||||
vkCmdBindDescriptorSets(cmd, bind_point, layout, 0, 1, &m_handle, 0, nullptr);
|
vkCmdBindDescriptorSets(cmd, bind_point, layout, 0, 1, &m_handle, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../VulkanAPI.h"
|
#include "../VulkanAPI.h"
|
||||||
|
#include "Utilities/mutex.h"
|
||||||
|
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
|
||||||
|
@ -32,13 +34,11 @@ namespace vk
|
||||||
class descriptor_set
|
class descriptor_set
|
||||||
{
|
{
|
||||||
const size_t max_cache_size = 16384;
|
const size_t max_cache_size = 16384;
|
||||||
|
void init(VkDescriptorSet new_set);
|
||||||
void flush();
|
|
||||||
void init();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
descriptor_set(VkDescriptorSet set);
|
descriptor_set(VkDescriptorSet set);
|
||||||
descriptor_set();
|
descriptor_set() = default;
|
||||||
~descriptor_set() = default;
|
~descriptor_set() = default;
|
||||||
|
|
||||||
descriptor_set(const descriptor_set&) = delete;
|
descriptor_set(const descriptor_set&) = delete;
|
||||||
|
@ -57,8 +57,12 @@ namespace vk
|
||||||
void bind(VkCommandBuffer cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout);
|
void bind(VkCommandBuffer cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout);
|
||||||
void bind(const command_buffer& cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout);
|
void bind(const command_buffer& cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout);
|
||||||
|
|
||||||
|
void flush();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VkDescriptorSet m_handle = VK_NULL_HANDLE;
|
VkDescriptorSet m_handle = VK_NULL_HANDLE;
|
||||||
|
bool m_update_after_bind = false;
|
||||||
|
bool m_in_use = false;
|
||||||
|
|
||||||
rsx::simple_array<VkBufferView> m_buffer_view_pool;
|
rsx::simple_array<VkBufferView> m_buffer_view_pool;
|
||||||
rsx::simple_array<VkDescriptorBufferInfo> m_buffer_info_pool;
|
rsx::simple_array<VkDescriptorBufferInfo> m_buffer_info_pool;
|
||||||
|
@ -68,5 +72,11 @@ namespace vk
|
||||||
rsx::simple_array<VkCopyDescriptorSet> m_pending_copies;
|
rsx::simple_array<VkCopyDescriptorSet> m_pending_copies;
|
||||||
};
|
};
|
||||||
|
|
||||||
void flush_descriptor_updates();
|
namespace descriptors
|
||||||
|
{
|
||||||
|
void init();
|
||||||
|
void flush();
|
||||||
|
|
||||||
|
VkDescriptorSetLayout create_layout(const std::vector<VkDescriptorSetLayoutBinding>& bindings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -326,6 +326,7 @@ namespace vk
|
||||||
|
|
||||||
if (pgpu->descriptor_indexing_support)
|
if (pgpu->descriptor_indexing_support)
|
||||||
{
|
{
|
||||||
|
requested_extensions.push_back(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
|
||||||
requested_extensions.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
|
requested_extensions.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,6 +461,17 @@ namespace vk
|
||||||
rsx_log.notice("GPU/driver lacks support for float16 data types. All float16_t arithmetic will be emulated with float32_t.");
|
rsx_log.notice("GPU/driver lacks support for float16 data types. All float16_t arithmetic will be emulated with float32_t.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkPhysicalDeviceDescriptorIndexingFeatures indexing_features{};
|
||||||
|
if (pgpu->descriptor_indexing_support)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
CHECK_RESULT_EX(vkCreateDevice(*pgpu, &device, nullptr, &dev), message_on_error);
|
CHECK_RESULT_EX(vkCreateDevice(*pgpu, &device, nullptr, &dev), message_on_error);
|
||||||
|
|
||||||
// Initialize queues
|
// Initialize queues
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue