Commit 53337f27 authored by Jason Ekstrand's avatar Jason Ekstrand
Browse files

vulkan: Improve GetPhysicalDeviceExternalSemaphoreProperties()

The previous implementation made a lot more assumptions about the
symmetry of import and export and details of how sync types were listed
by the driver.  This makes a few improvements:

 1. The SYNC_FD handle type requires that all imports are temporary.
    Even if it isn't supported for export by any sync types, it may
    still be supported input-only.  Properly advertise this.

 2. There was generally too much coupling going on between import and
    export where we assume everything that can do import can do export
    as well.  Sort that out by only considering export when searching
    for the sync_type to compre against.

 3. Add more restrictions around compatible handle types such that we
    now guarantee that arbitrary subsets of the reported handle types
    won't end us up in awkward corners.  The newly added rules may seem
    a bit harsh but they're trivially satisfiable by all drivers
    shipping today.
parent e1be0ef2
Pipeline #657066 waiting for manual action with stages
......@@ -229,6 +229,12 @@ vk_common_DestroySemaphore(VkDevice _device,
vk_object_free(device, pAllocator, semaphore);
}
static bool
handle_type_always_temporary(VkExternalSemaphoreHandleTypeFlagBits handle_type)
{
return handle_type == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
}
VKAPI_ATTR void VKAPI_CALL
vk_common_GetPhysicalDeviceExternalSemaphoreProperties(
VkPhysicalDevice physicalDevice,
......@@ -245,14 +251,38 @@ vk_common_GetPhysicalDeviceExternalSemaphoreProperties(
const VkSemaphoreType semaphore_type =
get_semaphore_type(pExternalSemaphoreInfo->pNext, NULL);
/* For most of these checks, we only care about the export sync type
* because that is what gets specified at semaphore creation.
*/
const struct vk_sync_type *sync_type =
get_semaphore_sync_type(pdevice, semaphore_type, handle_type,
SYNC_IMPORT_BIT | SYNC_EXPORT_BIT);
get_semaphore_sync_type(pdevice, semaphore_type,
handle_type, SYNC_EXPORT_BIT);
if (sync_type == NULL) {
pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
pExternalSemaphoreProperties->compatibleHandleTypes = 0;
pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
return;
if (handle_type_always_temporary(handle_type)) {
/* If we will only ever have temporary imports, we can ignore the
* fact that there is no valid export sync type and maybe advertise a
* few features anyway.
*/
const struct vk_sync_type *import_sync_type =
get_semaphore_sync_type(pdevice, semaphore_type,
handle_type, SYNC_IMPORT_BIT);
pExternalSemaphoreProperties->exportFromImportedHandleTypes =
vk_sync_semaphore_export_types(import_sync_type, semaphore_type);
/* This flag can't be set on create so nothing can be set with it */
pExternalSemaphoreProperties->compatibleHandleTypes = 0;
/* This handle type is only importable because we already checked
* and export_sync_type == NULL
*/
pExternalSemaphoreProperties->externalSemaphoreFeatures =
VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
} else {
pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
pExternalSemaphoreProperties->compatibleHandleTypes = 0;
pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
}
}
VkExternalSemaphoreHandleTypeFlagBits import =
......@@ -266,25 +296,78 @@ vk_common_GetPhysicalDeviceExternalSemaphoreProperties(
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
SYNC_IMPORT_BIT | SYNC_EXPORT_BIT);
/* If we're a different vk_sync_type than the one selected when only
* OPAQUE_FD is set, then we can't import/export OPAQUE_FD. Put
* differently, there can only be one OPAQUE_FD sync type.
/* From the Vulkan 1.3.223 spec:
*
* "compatibleHandleTypes is a bitmask of
* VkExternalSemaphoreHandleTypeFlagBits specifying handle types
* which can be specified at the same time as handleType when
* creating a semaphore."
*
* The value we're expected to provide here needs to be such that any
* subset of compatible handle types can be successfully used to create
* a semaphore. If we allow arbitrary combinations, this may not always
* be satisfyable. In order to ensure that any subset of compatible
* handle types can be used, we have the following rules:
*
* 1. The first handle type we find for the given semaphore type
* supporting OPQAUE_FD may support any number of other handle
* types.
*
* 2. All other handle types can only be imported/exported as
* themselves.
*
* This prevents any weird edges in the compatability graph which may
* result in some combination of the bits we claim resulting in a
* failure to create a semaphore.
*/
if (sync_type != opaque_sync_type) {
import &= ~VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
export &= ~VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
import &= handle_type;
export &= handle_type;
}
}
VkExternalSemaphoreHandleTypeFlags compatible = import & export;
VkExternalSemaphoreFeatureFlags features = 0;
if (handle_type & export)
features |= VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT;
/* From the Vulkan 1.3.223 spec:
*
* "exportFromImportedHandleTypes is a bitmask of
* VkExternalSemaphoreHandleTypeFlagBits specifying which types of
* imported handle handleType can be exported from."
*
* Since export types have to be specified up-front, we know the
* vk_sync_type which will be used by the export. This check is a bit
* backwards from what you would expect because we're really asking what
* handle types can be imported into a sync prepared for exporting the
* given handle type. This may not be 100% correct in cases where we have
* some vk_sync_types which support different combinations of handle types.
* Howsever, today everything is either driver custom and supports only
* OPAQUE_FD if it supports import/export at all or is syncobj and supports
* everything we'll ever care about.
*/
pExternalSemaphoreProperties->exportFromImportedHandleTypes = import;
/* From the Vulkan 1.3.223 spec:
*
* "compatibleHandleTypes is a bitmask of
* VkExternalSemaphoreHandleTypeFlagBits specifying handle types which
* can be specified at the same time as handleType when creating a
* semaphore."
*
* Since the flags set on creation are export flags, this is just the set
* of other export types.
*/
pExternalSemaphoreProperties->compatibleHandleTypes = export;
/* From the Vulkan 1.3.223 spec:
*
* "externalSemaphoreFeatures is a bitmask of
* VkExternalSemaphoreFeatureFlagBits describing the features of
* handleType."
*/
assert(handle_type & export);
VkExternalSemaphoreFeatureFlags features =
VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT;
if (handle_type & import)
features |= VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
pExternalSemaphoreProperties->exportFromImportedHandleTypes = export;
pExternalSemaphoreProperties->compatibleHandleTypes = compatible;
pExternalSemaphoreProperties->externalSemaphoreFeatures = features;
}
......@@ -438,6 +521,7 @@ vk_common_ImportSemaphoreFdKHR(VkDevice _device,
sync = temporary;
} else {
assert(!handle_type_always_temporary(handle_type));
sync = &semaphore->permanent;
}
assert(handle_type &
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment