From 0b56da42cb4e238601a6bc06e3e124e3541baf85 Mon Sep 17 00:00:00 2001 From: Jon Ashburn Date: Fri, 22 Apr 2016 14:40:07 -0600 Subject: loader: update spec doc for ICD interface versioning Change-Id: I7c149a4542623e537b44720766006652abe33948 --- loader/LoaderAndLayerInterface.md | 167 ++++++++++++++++++++++++++------------ 1 file changed, 114 insertions(+), 53 deletions(-) (limited to 'loader') diff --git a/loader/LoaderAndLayerInterface.md b/loader/LoaderAndLayerInterface.md index 5d706ca1..b1eaf7c8 100644 --- a/loader/LoaderAndLayerInterface.md +++ b/loader/LoaderAndLayerInterface.md @@ -489,60 +489,101 @@ ICD interface requirements Generally, for all Vulkan commands issued by an application, the loader can be viewed as a pass through. That is, the loader generally doesn’t modified the -commands or their parameters but simply calls the ICDs entry point for that -command. Thus, the loader to ICD interface requirements will be specified by -covering two areas: 1) Obtaining ICD Vulkan entry points; 2) Specifying -requirements for a given Vulkan command(s) over and above the Vulkan -specification requirements. +commands or their parameters, but simply calls the ICDs entry point for that +command. There are specific additional interface requirements an ICD needs to comply with that +are over and above any requirements from the Vulkan specification including WSI extension specification. +These addtional requirements are versioned to allow flexibility in the future. +These interface requirements will be set forth in the following sections: 1) describing +which "loader-ICD" interface version is available, 2) detailing the most recent interface version; +3) the supported, older interface requirements will be described as differences +from the most recent interface version. #### Windows and Linux -##### Obtaining ICD entry points - -Currently, two methods of the loader finding ICD entry points are supported on -Linux and Windows: - -1) Recommended - -- vk\_icdGetInstanceProcAddr is exported by the ICD library and it returns - valid function pointers for all the global level and instance level Vulkan - commands, and also for vkGetDeviceProcAddr. Global level commands are those - which contain no dispatchable object as the first parameter, such as - vkCreateInstance and vkEnumerateInstanceExtensionProperties. The ICD must - support querying global level entry points by calling - vk\_icdGetInstanceProcAddr with a NULL VkInstance parameter. Instance level - commands are those that have either VkInstance, or VkPhysicalDevice as the - first parameter dispatchable object. Both core entry points and any instance - extension entry points the ICD supports should be available via - vk\_icdGetInstanceProcAddr. Future Vulkan instance extensions may define and - use new instance level dispatchable objects other than VkInstance and - VkPhysicalDevice, in which case extension entry points using these newly - defined dispatchable objects must be queryable via - vk\_icdGetInstanceProcAddr. - -- All other Vulkan entry points must either NOT be exported from the ICD - library or else NOT use the official Vulkan function names if they are - exported. This requirement is for ICD libraries that include other - functionality (such as OpenGL library) and thus could be loaded by the - application prior to when the Vulkan loader library is loaded by the - application. In other words, the ICD library exported Vulkan symbols must not - clash with the loader's exported Vulkan symbols. - -- Beware of interposing by dynamic OS library loaders if the official Vulkan - names are used. On Linux, if official names are used, the ICD library must be - linked with -Bsymbolic. - -2) Deprecated - -- vkGetInstanceProcAddr exported in the ICD library and returns valid function - pointers for all the Vulkan API entry points. - -- vkCreateInstance exported in the ICD library; - -- vkEnumerateInstanceExtensionProperties exported in the ICD library; - -##### Loader specific requirements for Vulkan commands - +##### Version Negotiation Between Loader and ICDs + +All ICDs (supporting interface version 2 or higher) must export the following +function that is used for determination of the interface version that will be used. +This entry point is not a part of the Vulkan API itself, only a private interface +between the loader and ICDs. + +VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion); + +This entry point reports the "loader-ICD" interface version supported by both the loader and the ICD. +The loader informs the ICD of it's desired interface version (typically the latest) via the +pSupportedVersion parameter. +This call is the first call made by the loader into the ICD (prior to any calls to +vk\_icdGetInstanceProcAddr). + +If a loader sees that an ICD does not export this symbol it knows that it's dealing +with a legacy ICD supporting either interface version 0 or 1. +Similarly, if an ICD sees a call to vk\_icdGetInstanceProcAddr before a call to +vk_icdGetLoaderICDInterfaceVersion then it knows that it's dealing with a legacy loader +supporting version 0 or 1. +Note if the loader calls vk\_icdGetInstanceProcAddr first it supports version 1, +otherwise the loader only supports version 0. + +The pSupportedVersion parameter is both an input and output parameter. +It is filled in by the loader before the call with the desired latest interface version supported by the loader. + +If the ICD receiving the call no longer supports the interface version provided +by the loader (due to deprecation) then it can report VK_ERROR_INCOMPATIBLE_DRIVER error, +otherwise it sets the value pointed by pSupportedVersion to the latest interface +version supported by both the ICD and the loader and returns VK_SUCCESS. +The ICD should report VK_SUCCESS in case the loader provided interface version +is newer than that supported by the ICD, as it's the loader's responsibility to +determine whether it can support the older interface version supported by the ICD. +The ICD should also report VK_SUCCESS in the case it's interface version is greater +than the loader's, but return the loader's version. Thus, upon return of VK_SUCCESS +the pSupportedVersion will contain the desired interface version to be used by the ICD. + +If the loader receives back an interface version from the ICD that the loader no longer +supports (due to deprecation) or it receives a VK_ERROR_INCOMPATIBLE_DRIVER error +instead of VK_SUCCESS then the loader will treat the ICD as incompatible +and will not load it for use. In this case the application will not see the ICDs vkPhysicalDevice +during enumeration. + +##### Loader Version 2 Interface Requirements + +Version 2 interface has requirements in three areas: 1) ICD Vulkan entry point discovery, +2) KHR_surface related requirements in the WSI extensions, 3) Vulkan dispatchable object +creation requirements. + +###### ICD Vulkan entry point discovery +All ICDs must export the following function that is used for discovery of ICD Vulkan entry points. +This entry point is not a part of the Vulkan API itself, only a private interface between the loader and ICDs for version 1 and higher interfaces. + +VKAPI\_ATTR PFN\_vkVoidFunction VKAPI\_CALL vk\_icdGetInstanceProcAddr(VkInstance instance, const char* pName); + +This function has very similar semantics to the Vulkan command vkGetInstanceProcAddr. +vk\_icdGetInstanceProcAddr returns valid function pointers for all the global level +and instance level Vulkan commands, and also for vkGetDeviceProcAddr. +Global level commands are those +which contain no dispatchable object as the first parameter, such as +vkCreateInstance and vkEnumerateInstanceExtensionProperties. The ICD must +support querying global level entry points by calling +vk\_icdGetInstanceProcAddr with a NULL VkInstance parameter. Instance level +commands are those that have either VkInstance, or VkPhysicalDevice as the +first parameter dispatchable object. Both core entry points and any instance +extension entry points the ICD supports should be available via +vk\_icdGetInstanceProcAddr. Future Vulkan instance extensions may define and +use new instance level dispatchable objects other than VkInstance and +VkPhysicalDevice, in which case extension entry points using these newly +defined dispatchable objects must be queryable via vk\_icdGetInstanceProcAddr. + +All other Vulkan entry points must either NOT be exported from the ICD +library or else NOT use the official Vulkan function names if they are +exported. This requirement is for ICD libraries that include other +functionality (such as OpenGL library) and thus could be loaded by the +application prior to when the Vulkan loader library is loaded by the +application. In other words, the ICD library exported Vulkan symbols must not +clash with the loader's exported Vulkan symbols. + +Beware of interposing by dynamic OS library loaders if the official Vulkan +names are used. On Linux, if official names are used, the ICD library must be +linked with -Bsymbolic. + +###### Handling KHR_surface objects in the WSI extensions Normally, ICDs handle object creation and destruction for various Vulkan objects. The WSI surface extensions for Linux and Windows (VK\_KHR\_win32\_surface, VK\_KHR\_xcb\_surface, VK\_KHR\_xlib\_surface, @@ -564,6 +605,7 @@ destruction is handled by the loader as follows: in the structure is a VkIcdSurfaceBase enumerant that indicates whether the surface object is Win32, Xcb, Xlib, Mir, or Wayland. +###### ICD dispatchable object creation As previously covered, the loader requires dispatch tables to be accessible within Vulkan dispatchable objects, which include VkInstance, VkPhysicalDevice, VkDevice, VkQueue, and VkCommandBuffer. The specific requirements on all @@ -606,6 +648,24 @@ vkObj alloc_icd_obj() } ``` +##### Loader Version 0 and 1 Interface Differences + +Version 0 and 1 interfaces do not support version negotiation via vk\_icdNegotiateLoaderICDInterfaceVersion. +ICDs can distinguish version 0 and version 1 interfaces as follows: +if the loader calls vk\_icdGetInstanceProcAddr first it supports version 1, +otherwise the loader only supports version 0. + +Version 0 interface does not support vk\_icdGetInstanceProcAddr. Version 0 interface requirements for +obtaining ICD Vulkan entry points are as follows: + +- vkGetInstanceProcAddr exported in the ICD library and returns valid function + pointers for all the Vulkan API entry points; + +- vkCreateInstance exported in the ICD library; + +- vkEnumerateInstanceExtensionProperties exported in the ICD library; + + Additional Notes: - The loader will filter out extensions requested in vkCreateInstance and @@ -618,9 +678,10 @@ appropriate layer JSON manifest file refer to the ICD library file. - The loader will not call the ICD for vkEnumerate\*ExtensionProperties(pLayerName != NULL). - ICDs creating new dispatchable objects via device extensions need to initialize -the created disaptchable object. The loader has generic trampoline code for unknown +the created dispatchable object. The loader has generic trampoline code for unknown device extensions. This generic trampoline code doesn't initialize the dispatch table within -the newly created object. See the section [layer link](#creating-new-dispatchable-objects) +the newly created object. See the section for more information on how to initialize created +dispatchable objects for extensions non known by the loader. [layer link](#creating-new-dispatchable-objects) #### Android -- cgit v1.2.3