summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--layer/private_data.hpp6
-rw-r--r--util/extension_list.hpp7
-rw-r--r--util/helpers.hpp37
-rw-r--r--wsi/swapchain_base.cpp58
-rw-r--r--wsi/wsi_factory.cpp76
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;
}