diff options
-rw-r--r-- | layer/private_data.hpp | 6 | ||||
-rw-r--r-- | util/extension_list.hpp | 7 | ||||
-rw-r--r-- | util/helpers.hpp | 37 | ||||
-rw-r--r-- | wsi/swapchain_base.cpp | 58 | ||||
-rw-r--r-- | wsi/wsi_factory.cpp | 76 |
5 files changed, 147 insertions, 37 deletions
diff --git a/layer/private_data.hpp b/layer/private_data.hpp index 11fa5ce..ee43338 100644 --- a/layer/private_data.hpp +++ b/layer/private_data.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021 Arm Limited. + * Copyright (c) 2018-2022 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -136,7 +136,9 @@ struct instance_dispatch_table OPTIONAL(GetDeviceGroupSurfacePresentModesKHR) \ OPTIONAL(GetDeviceGroupPresentCapabilitiesKHR) \ OPTIONAL(AcquireNextImage2KHR) \ - OPTIONAL(GetFenceFdKHR) + OPTIONAL(GetFenceFdKHR) \ + OPTIONAL(ImportFenceFdKHR) \ + OPTIONAL(ImportSemaphoreFdKHR) struct device_dispatch_table { diff --git a/util/extension_list.hpp b/util/extension_list.hpp index 0268efa..8caecb6 100644 --- a/util/extension_list.hpp +++ b/util/extension_list.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Arm Limited. + * Copyright (c) 2019, 2021-2022 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -85,6 +85,11 @@ public: VkResult add(const extension_list &ext_list); VkResult add(const char *const *extensions, uint32_t count); + VkResult add(const char *extension) + { + return add(&extension, 1); + } + /** * @brief Perform intersection between extensions and add them to the list. * diff --git a/util/helpers.hpp b/util/helpers.hpp index 9b5932e..cbdc4e3 100644 --- a/util/helpers.hpp +++ b/util/helpers.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Arm Limited. + * Copyright (c) 2021-2022 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -32,6 +32,41 @@ #include <vulkan/vulkan.h> +/* + * Conditional return statement. This allows functions to return early for + * failing Vulkan commands with a terse syntax. + * + * Example usage: + * + * VkResult foo() + * { + * TRY(vkCommand()); + * return VK_SUCCESS; + * } + * + * The above is equivalent to: + * + * VkResult foo() + * { + * VkResult result = vkCommand(); + * if (result != VK_SUCCESS) + * { + * return result; + * } + * return VK_SUCCESS; + * } + */ +#define TRY(expression) \ + do \ + { \ + VkResult try_result = expression; \ + if (try_result != VK_SUCCESS) \ + { \ + return try_result; \ + } \ + } \ + while (0) + namespace util { template <typename T> diff --git a/wsi/swapchain_base.cpp b/wsi/swapchain_base.cpp index ab24f0b..7fbbe68 100644 --- a/wsi/swapchain_base.cpp +++ b/wsi/swapchain_base.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 Arm Limited. + * Copyright (c) 2017-2022 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -404,6 +404,62 @@ VkResult swapchain_base::acquire_next_image(uint64_t timeout, VkSemaphore semaph image_status_lock.unlock(); + /* Try to signal fences/semaphores with a sync FD for optimal performance. */ + if (m_device_data.disp.ImportFenceFdKHR != nullptr && + m_device_data.disp.ImportSemaphoreFdKHR != nullptr) + { + if (fence != VK_NULL_HANDLE) + { + int already_signalled_sentinel_fd = -1; + auto info = VkImportFenceFdInfoKHR{}; + { + info.sType = VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR; + info.fence = fence; + info.handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT; + info.fd = already_signalled_sentinel_fd; + } + + auto result = m_device_data.disp.ImportFenceFdKHR(m_device, &info); + switch (result) + { + case VK_SUCCESS: + fence = VK_NULL_HANDLE; + break; + case VK_ERROR_INVALID_EXTERNAL_HANDLE: + /* Leave to fallback. */ + break; + default: + return result; + } + } + + if (semaphore != VK_NULL_HANDLE) + { + int already_signalled_sentinel_fd = -1; + auto info = VkImportSemaphoreFdInfoKHR{}; + { + info.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR; + info.semaphore = semaphore; + info.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; + info.fd = already_signalled_sentinel_fd; + } + + auto result = m_device_data.disp.ImportSemaphoreFdKHR(m_device, &info); + switch (result) + { + case VK_SUCCESS: + semaphore = VK_NULL_HANDLE; + break; + case VK_ERROR_INVALID_EXTERNAL_HANDLE: + /* Leave to fallback. */ + break; + default: + return result; + } + } + } + + /* Fallback for when importing fence/semaphore sync FDs is unsupported by the ICD. */ if (VK_NULL_HANDLE != semaphore || VK_NULL_HANDLE != fence) { VkSubmitInfo submit = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; diff --git a/wsi/wsi_factory.cpp b/wsi/wsi_factory.cpp index 6d7013a..d62b1ca 100644 --- a/wsi/wsi_factory.cpp +++ b/wsi/wsi_factory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2021 Arm Limited. + * Copyright (c) 2019-2022 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -119,38 +119,58 @@ util::wsi_platform_set find_enabled_layer_platforms(const VkInstanceCreateInfo * return ret; } +static VkResult get_available_device_extensions(VkPhysicalDevice physical_device, + util::extension_list &available_extensions) +{ + auto &instance_data = layer::instance_private_data::get(physical_device); + util::vector<VkExtensionProperties> properties{available_extensions.get_allocator()}; + uint32_t count; + TRY(instance_data.disp.EnumerateDeviceExtensionProperties(physical_device, nullptr, &count, nullptr)); + + if (!properties.try_resize(count)) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + TRY(instance_data.disp.EnumerateDeviceExtensionProperties(physical_device, nullptr, &count, properties.data())); + TRY(available_extensions.add(properties.data(), count)); + + return VK_SUCCESS; +} + VkResult add_extensions_required_by_layer(VkPhysicalDevice phys_dev, const util::wsi_platform_set enabled_platforms, util::extension_list &extensions_to_enable) { util::allocator allocator{extensions_to_enable.get_allocator(), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND}; - util::extension_list device_extensions{allocator}; - util::vector<VkExtensionProperties> ext_props{allocator}; - layer::instance_private_data &inst_data = layer::instance_private_data::get(phys_dev); - uint32_t count; - VkResult res = inst_data.disp.EnumerateDeviceExtensionProperties(phys_dev, nullptr, &count, nullptr); + util::extension_list available_device_extensions{allocator}; + TRY(get_available_device_extensions(phys_dev, available_device_extensions)); - if (res == VK_SUCCESS) + /* Add optional extensions independent of winsys. */ { - if (!ext_props.try_resize(count)) + const char *optional_extensions[] = { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - res = inst_data.disp.EnumerateDeviceExtensionProperties(phys_dev, nullptr, &count, ext_props.data()); - } + VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, + VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME, + VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME, - if (res != VK_SUCCESS) - { - return res; - } + VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, + VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME, + VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, - res = device_extensions.add(ext_props.data(), count); + VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, + }; - if (res != VK_SUCCESS) - { - return res; + for (auto extension : optional_extensions) + { + if (available_device_extensions.contains(extension)) + { + TRY(extensions_to_enable.add(extension)); + } + } } + layer::instance_private_data &inst_data = layer::instance_private_data::get(phys_dev); for (const auto &wsi_ext : supported_wsi_extensions) { /* Skip iterating over platforms not enabled in the instance. */ @@ -166,13 +186,8 @@ VkResult add_extensions_required_by_layer(VkPhysicalDevice phys_dev, const util: return VK_ERROR_INITIALIZATION_FAILED; } - 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); + TRY(props->get_required_device_extensions(extensions_required_by_layer)); + bool supported = available_device_extensions.contains(extensions_required_by_layer); if (!supported) { /* Can we accept failure? The layer unconditionally advertises support for this platform and the loader uses @@ -183,12 +198,9 @@ VkResult add_extensions_required_by_layer(VkPhysicalDevice phys_dev, const util: return VK_ERROR_INITIALIZATION_FAILED; } - res = extensions_to_enable.add(extensions_required_by_layer); - if (res != VK_SUCCESS) - { - return res; - } + TRY(extensions_to_enable.add(extensions_required_by_layer)); } + return VK_SUCCESS; } |