diff --git a/layer/private_data.cpp b/layer/private_data.cpp index ae4a23e..c4e9a3d 100644 --- a/layer/private_data.cpp +++ b/layer/private_data.cpp @@ -98,8 +98,8 @@ VkResult instance_private_data::associate(VkInstance instance, instance_dispatch PFN_vkSetInstanceLoaderData set_loader_data, util::wsi_platform_set enabled_layer_platforms, const util::allocator &allocator) { - auto *instance_data = - allocator.create(1, table, set_loader_data, enabled_layer_platforms, allocator); + auto instance_data = + allocator.make_unique(table, set_loader_data, enabled_layer_platforms, allocator); if (instance_data == nullptr) { @@ -120,9 +120,10 @@ VkResult instance_private_data::associate(VkInstance instance, instance_dispatch g_instance_data.erase(it); } - auto result = g_instance_data.try_insert(std::make_pair(key, instance_data)); + auto result = g_instance_data.try_insert(std::make_pair(key, instance_data.get())); if (result.has_value()) { + instance_data.release(); return VK_SUCCESS; } else @@ -130,7 +131,6 @@ VkResult instance_private_data::associate(VkInstance instance, instance_dispatch WSI_LOG_WARNING("Failed to insert instance_private_data for instance (%p) as host is out of memory", reinterpret_cast(instance)); - destroy(instance_data); return VK_ERROR_OUT_OF_HOST_MEMORY; } } @@ -231,8 +231,8 @@ VkResult device_private_data::associate(VkDevice dev, instance_private_data &ins const device_dispatch_table &table, PFN_vkSetDeviceLoaderData set_loader_data, const util::allocator &allocator) { - auto *device_data = - allocator.create(1, inst_data, phys_dev, dev, table, set_loader_data, allocator); + auto device_data = + allocator.make_unique(inst_data, phys_dev, dev, table, set_loader_data, allocator); if (device_data == nullptr) { @@ -252,9 +252,10 @@ VkResult device_private_data::associate(VkDevice dev, instance_private_data &ins g_device_data.erase(it); } - auto result = g_device_data.try_insert(std::make_pair(key, device_data)); + auto result = g_device_data.try_insert(std::make_pair(key, device_data.get())); if (result.has_value()) { + device_data.release(); return VK_SUCCESS; } else @@ -262,7 +263,6 @@ VkResult device_private_data::associate(VkDevice dev, instance_private_data &ins WSI_LOG_WARNING("Failed to insert device_private_data for device (%p) as host is out of memory", reinterpret_cast(dev)); - destroy(device_data); return VK_ERROR_OUT_OF_HOST_MEMORY; } } diff --git a/util/custom_allocator.hpp b/util/custom_allocator.hpp index 90dd34c..9eacd91 100644 --- a/util/custom_allocator.hpp +++ b/util/custom_allocator.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -34,6 +35,12 @@ namespace util { +template +class deleter; + +template +using unique_ptr = std::unique_ptr>; + /** * @brief Minimalistic wrapper of VkAllocationCallbacks. */ @@ -89,6 +96,9 @@ public: template void destroy(size_t num_objects, T *obj) const noexcept; + template + util::unique_ptr make_unique(Args &&...args) const noexcept; + VkAllocationCallbacks m_callbacks; VkSystemAllocationScope m_scope; }; @@ -223,9 +233,27 @@ void allocator::destroy(size_t num_objects, T *objects) const noexcept } template -void destroy_custom(T *obj) +class deleter { - T::destroy(obj); +public: + deleter(allocator allocator) + : m_allocator(std::move(allocator)) + {} + + void operator()(T *object) + { + m_allocator.destroy(1, object); + } + +private: + allocator m_allocator; +}; + +template +util::unique_ptr allocator::make_unique(Args &&...args) const noexcept +{ + T *object = create(1, std::forward(args)...); + return util::unique_ptr(object, *this); } /** diff --git a/wsi/surface_properties.hpp b/wsi/surface_properties.hpp index b496134..477fb18 100644 --- a/wsi/surface_properties.hpp +++ b/wsi/surface_properties.hpp @@ -63,10 +63,10 @@ public: /** * @brief Return the device extensions that this surface_properties implementation needs. */ - virtual const util::extension_list &get_required_device_extensions() + virtual VkResult get_required_device_extensions(util::extension_list &extension_list) { - static const util::extension_list empty{util::allocator::get_generic()}; - return empty; + /* Requires no additional extensions */ + return VK_SUCCESS; } /** diff --git a/wsi/wayland/surface_properties.cpp b/wsi/wayland/surface_properties.cpp index 1160bcb..45ea124 100644 --- a/wsi/wayland/surface_properties.cpp +++ b/wsi/wayland/surface_properties.cpp @@ -269,18 +269,9 @@ static const char *required_device_extensions[] = { VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, }; -static std::unique_ptr populate_device_extensions() +VkResult surface_properties::get_required_device_extensions(util::extension_list &extension_list) { - std::unique_ptr ret(new util::extension_list(util::allocator::get_generic())); - ret->add(required_device_extensions, NELEMS(required_device_extensions)); - - return ret; -} - -const util::extension_list &surface_properties::get_required_device_extensions() -{ - static std::unique_ptr device_extensions = populate_device_extensions(); - return *device_extensions; + return extension_list.add(required_device_extensions, NELEMS(required_device_extensions)); } /* TODO: Check for zwp_linux_dmabuf_v1 protocol in display */ diff --git a/wsi/wayland/surface_properties.hpp b/wsi/wayland/surface_properties.hpp index 86a6101..755c9c4 100644 --- a/wsi/wayland/surface_properties.hpp +++ b/wsi/wayland/surface_properties.hpp @@ -43,7 +43,7 @@ public: VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface, uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) override; - const util::extension_list &get_required_device_extensions() override; + VkResult get_required_device_extensions(util::extension_list &extension_list) override; PFN_vkVoidFunction get_proc_addr(const char *name) override; }; diff --git a/wsi/wsi_factory.cpp b/wsi/wsi_factory.cpp index 37ad3be..a34f1fb 100644 --- a/wsi/wsi_factory.cpp +++ b/wsi/wsi_factory.cpp @@ -162,8 +162,14 @@ VkResult add_extensions_required_by_layer(VkPhysicalDevice phys_dev, const util: continue; } + util::extension_list extensions_required_by_layer{allocator}; surface_properties *props = get_surface_properties(wsi_ext.platform); - const auto &extensions_required_by_layer = props->get_required_device_extensions(); + res = props->get_required_device_extensions(extensions_required_by_layer); + if (res != VK_SUCCESS) + { + return res; + } + bool supported = device_extensions.contains(extensions_required_by_layer); if (!supported) {