diff options
author | Charles Giessen <charles@lunarg.com> | 2022-05-25 02:34:38 +0300 |
---|---|---|
committer | Charles Giessen <46324611+charles-lunarg@users.noreply.github.com> | 2022-05-31 23:51:38 +0300 |
commit | 5437a0854fb6b664e2c48c0b8e7b157ac23fe741 (patch) | |
tree | 8c8d91c4e61eefe5107f4fde390d48c76a77d058 | |
parent | 8289053993972e23019eeef59574ed2bc373b62e (diff) |
Update layer and driver vkGetPhysDevProcAddr docs
Better describe the function's purpose and behavior, moving the
reason for introducing vk_layer|icdGetPhysicalDeviceProcAddr to
a following section for clarity.
-rw-r--r-- | docs/LoaderDriverInterface.md | 77 | ||||
-rw-r--r-- | docs/LoaderLayerInterface.md | 86 |
2 files changed, 97 insertions, 66 deletions
diff --git a/docs/LoaderDriverInterface.md b/docs/LoaderDriverInterface.md index b99e9b2d7..12c964a58 100644 --- a/docs/LoaderDriverInterface.md +++ b/docs/LoaderDriverInterface.md @@ -18,6 +18,7 @@ - [Overview](#overview) - [Driver Discovery](#driver-discovery) - [Overriding the Default Driver Discovery](#overriding-the-default-driver-discovery) + - [Additional Driver Discovery](#additional-driver-discovery) - [Exception for Elevated Privileges](#exception-for-elevated-privileges) - [Examples](#examples) - [On Windows](#on-windows) @@ -43,6 +44,7 @@ - [Filtering Out Instance Extension Names](#filtering-out-instance-extension-names) - [Loader Instance Extension Emulation Support](#loader-instance-extension-emulation-support) - [Driver Unknown Physical Device Extensions](#driver-unknown-physical-device-extensions) + - [Reason for adding `vk_icdGetPhysicalDeviceProcAddr`](#reason-for-adding-vk_icdgetphysicaldeviceprocaddr) - [Physical Device Sorting](#physical-device-sorting) - [Driver Dispatchable Object Creation](#driver-dispatchable-object-creation) - [Handling KHR Surface Objects in WSI Extensions](#handling-khr-surface-objects-in-wsi-extensions) @@ -59,11 +61,12 @@ - [Loader Version 0 Interface Requirements](#loader-version-0-interface-requirements) - [Additional Interface Notes:](#additional-interface-notes) - [Android Driver Negotiation](#android-driver-negotiation) -- [Loader implementation of VK_KHR_portability_enumeration](#loader-implementation-of-vkkhrportabilityenumeration) +- [Loader implementation of VK_KHR_portability_enumeration](#loader-implementation-of-vk_khr_portability_enumeration) - [Loader and Driver Policy](#loader-and-driver-policy) - [Number Format](#number-format) - [Android Differences](#android-differences) - [Requirements of Well-Behaved Drivers](#requirements-of-well-behaved-drivers) + - [Removed Driver Policies](#removed-driver-policies) - [Requirements of a Well-Behaved Loader](#requirements-of-a-well-behaved-loader) @@ -720,32 +723,12 @@ missing support for this extension. ## Driver Unknown Physical Device Extensions -Originally, when the loader's `vkGetInstanceProcAddr` was called, it would -result in the following behavior: - 1. The loader would check if it was a core function: - - If so, it would return the function pointer - 2. The loader would check if it was a known extension function: - - If so, it would return the function pointer - 3. If the loader knew nothing about it, it would call down using -`GetInstanceProcAddr` - - If it returned `non-NULL`, treat it as an unknown logical device command. - - This meant setting up a generic trampoline function that takes in a -VkDevice as the first parameter and adjusting the dispatch table to call the -driver/layer's function after getting the dispatch table from the -`VkDevice`. - 4. If all the above failed, the loader would return `NULL` to the application. - -This caused problems when a driver attempted to expose new physical device -extensions the loader knew nothing about, but an application was aware of. -Because the loader knew nothing about it, the loader would get to step 3 in the -above process and would treat the function as an unknown logical device command. -The problem is, this would create a generic `VkDevice` trampoline function -which, on the first call, would attempt to dereference the VkPhysicalDevice as a -`VkDevice`. -This would lead to a crash or corruption. - -In order to identify the extension entry points specific to physical device -extensions, the following function can be added to a driver: +Drivers that implement entrypoints which take a `VkPhysicalDevice` as the first +parameter *should* support `vk_icdGetPhysicalDeviceProcAddr`. This function +is added to the Driver Interface Version 4 and allows the loader to distinguish +between entrypoints which take `VkDevice` and `VkPhysicalDevice` as the first +parameter. This allows the loader to properly support entrypoints that are +unknown to it gracefully. ```cpp PFN_vkVoidFunction @@ -760,7 +743,7 @@ extension entry points. In this way, it compares "pName" to every physical device function supported in the driver. -The following rules apply: +Implementations of the function should have the following behavior: * If `pName` is the name of a Vulkan API entrypoint that takes a `VkPhysicalDevice` as its primary dispatch handle, and the driver supports the entrypoint, then the driver **must** return the valid function pointer to the driver's @@ -771,14 +754,19 @@ The following rules apply: * If the driver is unaware of any entrypoint with the name `pName`, it **must** return `NULL`. -This support is optional and should not be considered a requirement. -This is only required if a driver intends to support some functionality not -directly supported by a significant population of loaders in the public. +If a driver intends to support functions that take VkPhysicalDevice as the +dispatchable parameter, then the driver should support +`vk_icdGetPhysicalDeviceProcAddr`. This is because if these functions aren't +known to the loader, such as those from unreleased extensions or because +the loader is an older build thus doesn't know about them _yet_, the loader +won't be able to distinguish whether this is a device or physical device +function. + If a driver does implement this support, it must export the function from the driver library using the name `vk_icdGetPhysicalDeviceProcAddr` so that the symbol can be located through the platform's dynamic linking utilities. -The new behavior of the loader's vkGetInstanceProcAddr with support for the +The behavior of the loader's `vkGetInstanceProcAddr` with support for the `vk_icdGetPhysicalDeviceProcAddr` function is as follows: 1. Check if core function: - If it is, return the function pointer @@ -805,6 +793,31 @@ However, the driver should continue to support the command query via `vk_icdGetPhysicalDeviceProcAddr`, until at least a Vulkan version bump, because an older loader may still be attempting to use the commands. +### Reason for adding `vk_icdGetPhysicalDeviceProcAddr` + +Originally, when the loader's `vkGetInstanceProcAddr` was called, it would +result in the following behavior: + 1. The loader would check if it was a core function: + - If so, it would return the function pointer + 2. The loader would check if it was a known extension function: + - If so, it would return the function pointer + 3. If the loader knew nothing about it, it would call down using +`GetInstanceProcAddr` + - If it returned `non-NULL`, treat it as an unknown logical device command. + - This meant setting up a generic trampoline function that takes in a +VkDevice as the first parameter and adjusting the dispatch table to call the +driver/layer's function after getting the dispatch table from the +`VkDevice`. + 4. If all the above failed, the loader would return `NULL` to the application. + +This caused problems when a driver attempted to expose new physical device +extensions the loader knew nothing about, but an application was aware of. +Because the loader knew nothing about it, the loader would get to step 3 in the +above process and would treat the function as an unknown logical device command. +The problem is, this would create a generic `VkDevice` trampoline function +which, on the first call, would attempt to dereference the VkPhysicalDevice as a +`VkDevice`. +This would lead to a crash or corruption. ## Physical Device Sorting diff --git a/docs/LoaderLayerInterface.md b/docs/LoaderLayerInterface.md index 2a3633656..ba9d6afde 100644 --- a/docs/LoaderLayerInterface.md +++ b/docs/LoaderLayerInterface.md @@ -29,6 +29,7 @@ - [Layer Version Negotiation](#layer-version-negotiation) - [Layer Call Chains and Distributed Dispatch](#layer-call-chains-and-distributed-dispatch) - [Layer Unknown Physical Device Extensions](#layer-unknown-physical-device-extensions) + - [Reason for adding `vk_layerGetPhysicalDeviceProcAddr`](#reason-for-adding-vk_layergetphysicaldeviceprocaddr) - [Layer Intercept Requirements](#layer-intercept-requirements) - [Distributed Dispatching Requirements](#distributed-dispatching-requirements) - [Layer Conventions and Rules](#layer-conventions-and-rules) @@ -586,32 +587,12 @@ functions to the first entity in the call chain. ## Layer Unknown Physical Device Extensions -Originally, if `vkGetInstanceProcAddr` was called in the loader, it would -result in the following behavior: - 1. The loader would check if core function: - - If it was, it would return the function pointer - 2. The loader would check if known extension function: - - If it was, it would return the function pointer - 3. If the loader knew nothing about it, it would call down using -`GetInstanceProcAddr` - - If it returned non-NULL, treat it as an unknown logical device command. - - This meant setting up a generic trampoline function that takes in a -VkDevice as the first parameter and adjusting the dispatch table to call the -Driver/Layer's function after getting the dispatch table from the `VkDevice`. - 4. If all the above failed, the loader would return NULL to the application. - -This caused problems when a layer attempted to expose new physical device -extensions the loader knew nothing about, but an application did. -Because the loader knew nothing about it, the loader would get to step 3 in the -above process and would treat the function as an unknown logical device -command. -The problem is, this would create a generic VkDevice trampoline function which, -on the first call, would attempt to dereference the VkPhysicalDevice as a -VkDevice. -This would lead to a crash or corruption. - -In order to identify the extension entry-points specific to physical device -extensions, the following function can be added to a layer: +Layers that intercept entrypoints which take a `VkPhysicalDevice` as the first +parameter *should* support `vk_layerGetPhysicalDeviceProcAddr`. This function +is added to the Layer Interface Version 2 and allows the loader to distinguish +between entrypoints which take `VkDevice` and `VkPhysicalDevice` as the first +parameter. This allows the loader to properly support entrypoints that are +unknown to it gracefully. ```cpp PFN_vkVoidFunction @@ -626,7 +607,7 @@ extension entry-points. In this way, it compares "pName" to every physical device function supported in the layer. -The following rules apply: +Implementations of the function should have the following behavior: * If it is the name of a physical device function supported by the layer, the pointer to the layer's corresponding function should be returned. * If it is the name of a valid function which is **not** a physical device @@ -648,17 +629,24 @@ chain_info->u.pLayerInfo->pfnNextGetPhysicalDeviceProcAddr * Using the next layer’s `GetInstanceProcAddr` function to query for `vk_layerGetPhysicalDeviceProcAddr`. -This support is optional and should not be considered a requirement. -This is only required if a layer intends to support some functionality not -directly supported by loaders released in the public. -If a layer does implement this support, it should return the address of its -`vk_layerGetPhysicalDeviceProcAddr` function in the +If a layer intends to support functions that take VkPhysicalDevice as the +dispatchable parameter, then layer should support `vk_layerGetPhysicalDeviceProcAddr`. +This is because if these functions aren't known to the loader, such as those +from unreleased extensions or because the loader is an older build thus doesn't +know about them _yet_, the loader won't be able to distinguish whether this is +a device or physical device function. + +If a layer does implement `vk_layerGetPhysicalDeviceProcAddr`, it should return +the address of its `vk_layerGetPhysicalDeviceProcAddr` function in the "pfnGetPhysicalDeviceProcAddr" member of the `VkNegotiateLayerInterface` structure during [Layer Version Negotiation](#layer-version-negotiation). Additionally, the layer should also make sure `vkGetInstanceProcAddr` returns a valid function pointer to a query of `vk_layerGetPhysicalDeviceProcAddr`. -The new behavior of the loader's `vkGetInstanceProcAddr` with support for the +Note: If a layer wraps the VkInstance handle, support for +`vk_layerGetPhysicalDeviceProcAddr` is *NOT* optional and must be implemented. + +The behavior of the loader's `vkGetInstanceProcAddr` with support for the `vk_layerGetPhysicalDeviceProcAddr` function is as follows: 1. Check if core function: - If it is, return the function pointer @@ -684,6 +672,32 @@ However, the layer should continue to support the command query via `vk_layerGetPhysicalDeviceProcAddr`, until at least a Vulkan version bump, because an older loader may still be attempting to use the commands. +### Reason for adding `vk_layerGetPhysicalDeviceProcAddr` + +Originally, if `vkGetInstanceProcAddr` was called in the loader, it would +result in the following behavior: + 1. The loader would check if core function: + - If it was, it would return the function pointer + 2. The loader would check if known extension function: + - If it was, it would return the function pointer + 3. If the loader knew nothing about it, it would call down using +`GetInstanceProcAddr` + - If it returned non-NULL, treat it as an unknown logical device command. + - This meant setting up a generic trampoline function that takes in a +VkDevice as the first parameter and adjusting the dispatch table to call the +Driver/Layer's function after getting the dispatch table from the `VkDevice`. + 4. If all the above failed, the loader would return NULL to the application. + +This caused problems when a layer attempted to expose new physical device +extensions the loader knew nothing about, but an application did. +Because the loader knew nothing about it, the loader would get to step 3 in the +above process and would treat the function as an unknown logical device +command. +The problem is, this would create a generic VkDevice trampoline function which, +on the first call, would attempt to dereference the VkPhysicalDevice as a +VkDevice. +This would lead to a crash or corruption. + ## Layer Intercept Requirements @@ -1219,7 +1233,8 @@ along the saved handle to the layer below it. This means that the layer **must intercept every Vulkan function which uses** **the object in question**, and wrap or unwrap the object, as appropriate. This includes adding support for all extensions with functions using any -object the layer wraps. +object the layer wraps as well as any loader-layer interface functions such as +`vk_layerGetPhysicalDeviceProcAddr`. Layers above the object wrapping layer will see the wrapped object. Layers which wrap dispatchable objects must ensure that the first field in the @@ -1845,6 +1860,9 @@ Additionally, it introduced the concept of and the associated `vk_layerGetPhysicalDeviceProcAddr` function. Finally, it changed the manifest file definition to 1.1.0. +Note: If a layer wraps the VkInstance handle, support for +`vk_layerGetPhysicalDeviceProcAddr` is *NOT* optional and must be implemented. + ### Layer Interface Version 1 A layer supporting interface version 1 had the following behavior: |