From df8a6072af3545111edf4fa1462a4ed993544c36 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 20 Apr 2016 06:23:24 +0800 Subject: [PATCH] doc: formalize the current loader-layer interface Expand the section "Discovery of layer entry points" into "Layer Library Interface". In general, the new section defines an interface that allows a loader to discover and insert layers while staying compliant. Other sections have additional guidelines for layers to follow. --- layers/README.md | 7 ++ loader/LoaderAndLayerInterface.md | 170 ++++++++++++++++++++++++++++++-------- 2 files changed, 143 insertions(+), 34 deletions(-) diff --git a/layers/README.md b/layers/README.md index dcc81d7..ac85efe 100644 --- a/layers/README.md +++ b/layers/README.md @@ -1,5 +1,12 @@ # Layer Description and Status +## Layer Library Interface + +All layer libraries must support the layer library interface defined in +[`LoaderAndLayerInterface.md`][]. + +[`LoaderAndLayerInterface.md`]: ../loader/LoaderAndLayerInterface.md#layer-library-interface + ## Overview Layer libraries can be written to intercept or hook VK entry points for various diff --git a/loader/LoaderAndLayerInterface.md b/loader/LoaderAndLayerInterface.md index bfc09ec..8a35cba 100644 --- a/loader/LoaderAndLayerInterface.md +++ b/loader/LoaderAndLayerInterface.md @@ -1030,45 +1030,147 @@ VkCommandBuffer as the first parameter and also include vkCreateDevice. Future extensions may introduce new instance or device level dispatchable objects, so the above lists may be extended in the future. -#### Discovery of layer entry points - -For the layer libraries that have been discovered by the loader, their -intercepting entry points that will participate in a device or instance call -chain need to be available to the loader or whatever layer is before them in -the chain. Layers have the following requirements in this area. -- A layer intercepting instance level Vulkan commands (aka an instance level -layer) must implement a vkGetInstanceProcAddr type of function. -- This vkGetInstanceProcAddr type function must be exported by the layer -library. The name of this function is specified in various ways: 1) the layer -manifest JSON file in the "functions", "vkGetInstanceProcAddr" node -(Linux/Windows); 2) it is named "vkGetInstanceProcAddr"; 3) it is -"GetInstanceProcAddr" (Android). -- A layer intercepting device level Vulkan commands (aka a device level layer) -must implement a vkGetDeviceProcAddr type of function. -- This vkGetDeviceProcAddr type function must be exported by the layer library. -The name of this function is specified in various ways: 1) the layer manifest -JSON file in the "functions", "vkGetDeviceProcAddr" node (Linux/Windows); 2) it -is named "vkGetDeviceProcAddr"; 3) it is "GetDeviceProcAddr" -(Android). -- A layer's vkGetInstanceProcAddr function (regardless of its name) must return -the local entry points for all instance level Vulkan commands it intercepts. At -a minimum, this includes vkGetInstanceProcAddr and vkCreateInstance. -- A layer's vkGetDeviceProcAddr function (regardless of its name) must return -the entry points for all device level Vulkan commands it intercepts. At a -minimum, this includes vkGetDeviceProcAddr and vkCreateDevice. -- There are no requirements on the names of the intercepting functions a layer -implements except those listed above for vkGetInstanceProcAddr and -vkGetDeviceProcAddr. -- Currently a layer's VkGetInstanceProcAddr must be able to handle a VkInstance -parameter equal to NULL for -instance level commands it intercepts including vkCreateDevice. -- Currently a layer's VkGetDeviceProcAddr must be able to handle a VkDevice -parameter equal to NULL for device level commands it intercepts. +#### Layer Library Interface + +A layer library is a container of layers. This section defines an extensible +programming interface to discover layers contained in layer libraries. It +also specifies the minimal conventions and rules a layer must follow. + +Other sections might have other guidelines that layers, at least validation +layers, should follow. + +##### Layer Conventions and Rules + +A layer, when inserted into an otherwise compliant Vulkan implementation, must +still result in a compliant Vulkan implementation[\*]. It must additionally +follow some conventions and rules. + +A layer is always chained with other layers. It must not make invalid calls +to or rely on undefined behaviors of its lower layers. When it changes the +behavior of a command, it must make sure its upper layers do not make invalid +calls to or rely on undefined behaviors of its lower layers because of the +changed behavior. For example, when a layer intercepts an object creation +command to wrap the objects created by its lower layers, it must make sure its +lower layers never see the wrapping objects, directly from itself or +indirectly from its upper layers. + +When a layer requires host memory, it is free to scope the allocations to +itself, bypassing the provided allocators entirely. + +`vkEnumerateInstanceLayerProperties` must always fail with +`VK_ERROR_LAYER_NOT_PRESENT`. + +`vkEnumerateInstanceExtensionProperties` must always fail with +`VK_ERROR_LAYER_NOT_PRESENT`, including when `pLayerName` is `NULL`. + +`vkEnumerateDeviceLayerProperties` must always fail with +`VK_ERROR_LAYER_NOT_PRESENT`. + +`vkEnumerateDeviceExtensionProperties` must always fail with +`VK_ERROR_LAYER_NOT_PRESENT`, except when `pLayerName` is `NULL`. It must +handle the case where `pLayerName` is `NULL`, usually by chaining to other +layers. + +`vkGetInstanceProcAddr` can intercept a command by returning a function +pointer different from what would be returned through chaining. + +`vkGetDeviceProcAddr` can intercept a command by returning a function pointer +different from what would be returned through chaining. + +`vkCreateInstance` must not generate an error for unrecognized layer names, +extension names, and `pNext` structs. It may assume the layer names and +extension names have been validated. + +`vkCreateDevice` must not generate an error for unrecognized layer names, +extension names, and `pNext` structs. It may assume the layer names and +extension names have been validated. + +[\*]: The intention is for layers to have a well-defined baseline behavior. +Some of the conventions or rules, for example, may be considered abuses of the +specification. + +###### Layer Library Interface Version 0 + +A layer library supporting interface version 0 must define and export these +functions, unrelated to any Vulkan command despite the names, signatures, and +other similarities: + + - `vkEnumerateInstanceLayerProperties` enumerates all instance layers in a + layer library. This function never fails. + + - `vkEnumerateInstanceExtensionProperties` enumerates instance extensions of + instance layers in a layer library. `pLayerName` is always a valid + instance layer name. This function never fails. + + - `vkEnumerateDeviceLayerProperties` enumerates all device layers in a layer + library. `physicalDevice` is always `VK_NULL_HANDLE`. This function never + fails. + + - `vkEnumerateDeviceExtensionProperties` enumerates device extensions of + device layers in a layer library. `physicalDevice` is always + `VK_NULL_HANDLE`. `pLayerName` is always a valid device layer name. This + function never fails. + + - `GetInstanceProcAddr` behaves as if ``'s + `vkGetInstanceProcAddr` is called, except + + - when `pName` is `vkEnumerateInstanceLayerProperties`, + `vkEnumerateInstanceExtensionProperties`, or + `vkEnumerateDeviceLayerProperties` (but _not_ + `vkEnumerateDeviceExtensionProperties`), it returns a function pointer to + the function of the same name defined by this interface. + - when `pName` is `vkGetInstanceProcAddr`, it returns a function pointer + to itself. + - when `pName` is `vkCreateDevice`, it ignores `instance`. + - when `pName` is a device command defined by Vulkan 1.0 or + `VK_KHR_swapchain` (but _not_ other device commands), it may chain to + other layers without intercepting. A loader should avoid querying such + device commands. + + When a layer library contains only one layer, this function may + alternatively be named `vkGetInstanceProcAddr`. + + - `GetDeviceProcAddr` behaves as if ``'s + `vkGetDeviceProcAddr` is called. + + When a layer library contains only one layer, this function may + alternatively be named `vkGetDeviceProcAddr`. + +All contained layers must support [`vk_layer.h`][]. They do not need to +implement commands that are not queryable. They are recommended not to export +any command. + +[`vk_layer.h`]: ../include/vulkan/vk_layer.h + +#### Layer Libraries and Manifest Files + +The layer libraries and the manifest files must be kept in sync. On Windows +and Linux, the loader uses manifest files to discover layer libraries and +layers. On Android, the loader inspects the layer libraries directly. + +The manifest file specifies in its "functions", "vkGetInstanceProcAddr" node +the function name the loader will use to discover +GetInstanceProcAddr. When the layer library exports +GetInstanceProcAddr, the JSON node must explicitly specify that +function name. When the layer library exports vkGetInstanceProcAddr, the JSON +node may be omitted. The layer library may additionally export another alias +and specify that in the JSON node. + +Similarly, the manifest file specifies in its "functions", +"vkGetDeviceProcAddr" node the function name the loader will use to discover +GetDeviceProcAddr. When the layer library exports +GetDeviceProcAddr, the JSON node must explicitly specify that +function name. When the layer library exports vkGetDeviceProcAddr, the JSON +node may be omitted. The layer library may additionally export another alias +and specify that in the JSON node. #### Layer intercept requirements - Layers intercept a Vulkan command by defining a C/C++ function with signature identical to the Vulkan API for that command. +- An instance layer must intercept at least vkGetInstanceProcAddr and +vkCreateInstance. A device layer must intercept at least vkGetDeviceProcAddr +and vkCreateDevice. - Other than the two vkGet*ProcAddr, all other functions intercepted by a layer need NOT be exported by the layer. - For any Vulkan command a layer intercepts which has a non-void return value, -- 2.7.4