From: Joe Jenner-Bailey Date: Tue, 4 Aug 2020 11:25:34 +0000 (+0100) Subject: util: add class for storing extensions strings X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f0dcf4fb3679f5e7d7b385799128e92ec95f4d54;p=platform%2Fcore%2Fuifw%2Fvulkan-wsi-tizen.git util: add class for storing extensions strings This utility will be used in future commits. Also add -Wno-undefined to the linker flags to prevent leaving undefined symbols in the layer .so file. Fix issues highlighted while using this flag. Change-Id: I682e266f7b3f313742cb2da83e5ad2569fc72da3 Signed-off-by: Joe Jenner-Bailey Signed-off-by: Matteo Franchin Signed-off-by: Rosen Zhelev --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 637f353..0db933e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2020 Arm Limited. +# Copyright (c) 2019-2021 Arm Limited. # # SPDX-License-Identifier: MIT # @@ -26,11 +26,13 @@ project(VkLayer_window_system_integration CXX) find_package(PkgConfig REQUIRED) pkg_check_modules(VULKAN_PKG_CONFIG vulkan) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pthread") if (DEFINED DEBUG) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0") endif() +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") + if(NOT DEFINED VULKAN_CXX_INCLUDE) set(VULKAN_CXX_INCLUDE ${VULKAN_PKG_CONFIG_INCLUDEDIR}) endif() @@ -49,6 +51,7 @@ add_library(${PROJECT_NAME} SHARED layer/swapchain_api.cpp util/timed_semaphore.cpp util/custom_allocator.cpp + util/extension_list.cpp wsi/swapchain_base.cpp wsi/wsi_factory.cpp wsi/headless/surface_properties.cpp diff --git a/util/custom_allocator.cpp b/util/custom_allocator.cpp index 27d7f09..21b7e6a 100644 --- a/util/custom_allocator.cpp +++ b/util/custom_allocator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Arm Limited. + * Copyright (c) 2020-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -45,6 +45,18 @@ static void default_free(void *, void *pMemory) namespace util { +const allocator& allocator::get_generic() +{ + static allocator generic{nullptr, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND}; + return generic; +} + + +allocator::allocator(const allocator& other, VkSystemAllocationScope new_scope) + : allocator{other.get_original_callbacks(), new_scope} +{ +} + /* If callbacks is already populated by vulkan then use those specified as default. */ allocator::allocator(const VkAllocationCallbacks *callbacks, VkSystemAllocationScope scope) { diff --git a/util/custom_allocator.hpp b/util/custom_allocator.hpp index 8f355e8..870e91c 100644 --- a/util/custom_allocator.hpp +++ b/util/custom_allocator.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Arm Limited. + * Copyright (c) 2020-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -41,6 +41,11 @@ class allocator { public: /** + * @brief Get an allocator that can be used if VkAllocationCallbacks are not provided. + */ + static const allocator& get_generic(); + + /** * @brief Construct a new wrapper for the given VK callbacks and scope. * @param callbacks Pointer to allocation callbacks. If this is @c nullptr, then default * allocation callbacks are used. These can be accessed through #m_callbacks. @@ -49,6 +54,11 @@ public: allocator(const VkAllocationCallbacks *callbacks, VkSystemAllocationScope scope); /** + * @brief Copy the given allocator, but change the allocation scope. + */ + allocator(const allocator& other, VkSystemAllocationScope new_scope); + + /** * @brief Get a pointer to the allocation callbacks provided while constructing this object. * @return a copy of the #VkAllocationCallback argument provided in the allocator constructor * or @c nullptr if this argument was provided as @c nullptr. diff --git a/util/extension_list.cpp b/util/extension_list.cpp new file mode 100644 index 0000000..f6a793d --- /dev/null +++ b/util/extension_list.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2019, 2021 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "extension_list.hpp" +#include +#include +#include + +namespace util +{ + +extension_list::extension_list(const util::allocator& allocator) + : m_alloc{allocator} + , m_ext_props(allocator) +{ +} + +VkResult extension_list::add(const struct VkEnumerateInstanceExtensionPropertiesChain *chain) +{ + uint32_t count; + VkResult m_error = chain->CallDown(nullptr, &count, nullptr); + if (m_error == VK_SUCCESS) + { + if (!m_ext_props.try_resize(count)) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + m_error = chain->CallDown(nullptr, &count, m_ext_props.data()); + } + return m_error; +} + +VkResult extension_list::add(VkPhysicalDevice dev) +{ + layer::instance_private_data &inst_data = layer::instance_private_data::get(layer::get_key(dev)); + uint32_t count; + VkResult m_error = inst_data.disp.EnumerateDeviceExtensionProperties(dev, nullptr, &count, nullptr); + + if (m_error == VK_SUCCESS) + { + if (!m_ext_props.try_resize(count)) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + m_error = inst_data.disp.EnumerateDeviceExtensionProperties(dev, nullptr, &count, m_ext_props.data()); + } + return m_error; +} + +VkResult extension_list::add(PFN_vkEnumerateInstanceExtensionProperties fpEnumerateInstanceExtensionProperties) +{ + uint32_t count = 0; + VkResult m_error = fpEnumerateInstanceExtensionProperties(nullptr, &count, nullptr); + + if (m_error == VK_SUCCESS) + { + if (!m_ext_props.try_resize(count)) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + m_error = fpEnumerateInstanceExtensionProperties(nullptr, &count, m_ext_props.data()); + } + return m_error; +} + +VkResult extension_list::add(const char *const *extensions, uint32_t count) +{ + for (uint32_t i = 0; i < count; i++) + { + VkExtensionProperties props = {}; + strncpy(props.extensionName, extensions[i], sizeof(props.extensionName)); + if (!m_ext_props.try_push_back(props)) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + } + return VK_SUCCESS; +} + +VkResult extension_list::add(const VkExtensionProperties *props, uint32_t count) +{ + if (!m_ext_props.try_push_back_many(props, props + count)) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + return VK_SUCCESS; +} + +VkResult extension_list::add(const char *ext) +{ + if (!contains(ext)) + { + VkExtensionProperties props = {}; + strncpy(props.extensionName, ext, sizeof(props.extensionName)); + if (!m_ext_props.try_push_back(props)) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + } + return VK_SUCCESS; +} + +VkResult extension_list::add(VkExtensionProperties ext_prop) +{ + if (!contains(ext_prop.extensionName)) + { + if (!m_ext_props.try_push_back(ext_prop)) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + } + return VK_SUCCESS; +} + +VkResult extension_list::add(const char **ext_list, uint32_t count) +{ + for (uint32_t i = 0; i < count; i++) + { + if (add(ext_list[i]) != VK_SUCCESS) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + } + return VK_SUCCESS; +} + +VkResult extension_list::add(const extension_list &ext_list) +{ + util::vector ext_vect = ext_list.get_extension_props(); + for (auto &ext : ext_vect) + { + if (add(ext) != VK_SUCCESS) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + } + return VK_SUCCESS; +} + +bool extension_list::get_extension_strings(util::vector &out) const +{ + size_t old_size = out.size(); + size_t new_size = old_size + m_ext_props.size(); + if (!out.try_resize(new_size)) + { + return false; + } + + for (size_t i = old_size; i < new_size; i++) + { + out[i] = m_ext_props[i - old_size].extensionName; + } + return true; +} + +bool extension_list::contains(const extension_list &req) const +{ + for (const auto &req_ext : req.m_ext_props) + { + if (!contains(req_ext.extensionName)) + { + return false; + } + } + return true; +} + +bool extension_list::contains(const char *extension_name) const +{ + for (const auto &p : m_ext_props) + { + if (strcmp(p.extensionName, extension_name) == 0) + { + return true; + } + } + return false; +} + +void extension_list::remove(const char *ext) +{ + m_ext_props.erase(std::remove_if(m_ext_props.begin(), m_ext_props.end(), [&ext](VkExtensionProperties ext_prop) { + return (strcmp(ext_prop.extensionName, ext) == 0); + })); +} +} // namespace util diff --git a/util/extension_list.hpp b/util/extension_list.hpp new file mode 100644 index 0000000..1c844eb --- /dev/null +++ b/util/extension_list.hpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2019, 2021 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#pragma once + +#include "util/custom_allocator.hpp" + +#include +#include + +#include +#include + +namespace util +{ + +class extension_list +{ +public: + extension_list(const util::allocator& allocator); + + extension_list(const extension_list &rhs) = delete; + const extension_list &operator=(const extension_list &rhs) = delete; + + /** + * @brief Obtain a vector of #VkExtensionProperties equivalent to this extension_list object. + */ + const util::vector &get_extension_props() const + { + return m_ext_props; + } + + /** + * @brief Get the allocator used to manage the memory of this object. + */ + const util::allocator get_allocator() const + { + return m_alloc; + } + + /** + * @brief Append pointers to extension strings to the given vector. + * + * @warning Pointers in the vector are referring to string allocated in this extension_list and will become invalid + * if the extension_list is modified (e.g. by adding/removing elements.) + * + * @param[out] out A vector of C strings to which all extension are appended. + * + * @return A boolean indicating whether the operation was successful. If this is @c false, then @p out is + * unmodified. + */ + bool get_extension_strings(util::vector &out) const; + + bool contains(const extension_list &req) const; + bool contains(const char *ext) const; + void remove(const char *ext); + VkResult add(const char *ext); + VkResult add(VkExtensionProperties ext_prop); + VkResult add(const char **ext_list, uint32_t count); + VkResult add(const extension_list &ext_list); + VkResult add(const struct VkEnumerateInstanceExtensionPropertiesChain *chain); + VkResult add(PFN_vkEnumerateInstanceExtensionProperties fpEnumerateInstanceExtensionProperties); + VkResult add(VkPhysicalDevice dev); + VkResult add(const char *const *extensions, uint32_t count); + VkResult add(const VkExtensionProperties *props, uint32_t count); + +private: + util::allocator m_alloc; + util::vector m_ext_props; +}; +} // namespace util diff --git a/wsi/swapchain_base.cpp b/wsi/swapchain_base.cpp index 098f51e..a94d6ba 100644 --- a/wsi/swapchain_base.cpp +++ b/wsi/swapchain_base.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 Arm Limited. + * Copyright (c) 2017-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -320,14 +320,10 @@ void swapchain_base::teardown() if (m_queue != VK_NULL_HANDLE) { /* Make sure the vkFences are done signaling. */ - vkQueueWaitIdle(m_queue); + m_device_data.disp.QueueWaitIdle(m_queue); } - /* Make sure the vkFences are done signaling. */ - m_device_data.disp.QueueWaitIdle(m_queue); - /* We are safe to destroy everything. */ - if (m_thread_sem_defined) { /* Tell flip thread to end. */