Layer libraries can be written to intercept or hook VK entry points for various debug and validation purposes. One or more VK entry points can be defined in your Layer library. Undefined entrypoints in the Layer library will be passed to the next Layer which may be the driver. Multiple layer libraries can be chained (actually a hierarchy) together. vkEnumerateInstanceLayerProperties and vkEnumerateDeviceLayerProperties can be called to list the available layers and their properties. Layers can intercept Vulkan instance level entry points in which case they are called an Instance Layer. Layers can intercept device entry points in which case they are called a Device Layer. Instance level entry points are those with VkInstance or VkPhysicalDevice as first parameter. Device level entry points are those with VkDevice, VkCmdBuffer, or VkQueue as the first parameter. Layers that want to intercept both instance and device level entrypoints are called Global Layers. vkXXXXGetProcAddr is used internally by the Layers and Loader to initialize dispatch tables. Device Layers are activated at vkCreateDevice time. Instance Layers are activated at vkCreateInstance. Layers can also be activated via environment variables (VK_INSTANCE_LAYERS or VK_DEVICE_LAYERS).
All validation layers work with the DEBUG_REPORT extension to provide the application or user with validation feedback. When a validation layer is enabled, it will look at the vk_layer_settings.txt file to determine it's behavior. Such as outputing to a file, stdout or debug output (Windows). An application can also register callback functions via the DEBUG_REPORT extension to receive callbacks when the requested validation events happen. Application callbacks happen regardless of the settings in vk_layer_settings.txt
##Layer library example code
Note that some layers are code-generated and will therefore exist in the directory (build_dir)/layers
-include/vkLayer.h - header file for layer code.
layer/Basic.cpp (name=Basic) simple example wrapping a few entrypoints. Shows layer features:
layer/Multi.cpp (name=multi1:multi2) simple example showing multiple layers per library
(build dir)/layer/generic_layer.cpp (name=Generic) - auto generated example wrapping all VK entrypoints.
(build dir)/layer/api_dump.cpp (name=APIDump) - print out API calls along with parameter values
(build dir)/layer/object_track.cpp (name=ObjectTracker) - Track object CREATE/USE/DESTROY stats. Individually track objects by category. VkObjectType enum defined in vulkan.h.
layer/draw_state.cpp (name=DrawState) - DrawState reports the Descriptor Set, Pipeline State, and dynamic state at each Draw call. DrawState layer performs a number of validation checks on this state. Of primary interest is making sure that the resources bound to Descriptor Sets correctly align with the layout specified for the Set.
layer/mem_tracker.cpp (name=MemTracker) - MemTracker functions mostly as a validation layer, attempting to ensure that memory objects are managed correctly by the application. These memory objects are bound to pipelines, objects, and command buffers, and then submitted to the GPU for work. As an example, the layer validates that the correct memory objects have been bound, and that they are specified correctly when the command buffers are submitted. Also, that only existing memory objects are referenced, and that any destroyed memory objects are not referenced. Another type of validation done is that before any memory objects are reused or destroyed, the layer ensures that the application has confirmed that they are no longer in use, and that they have been properly unbound before destruction.
/layer/device_limits.cpp (name=DeviceLimits) - Check that parameters used do not exceed device limits.
/layer/param_checker.cpp (name=ParamChecker) - Check the input parameters to API calls for validity. Currently this only checks ENUM params directly passed to API calls and ENUMs embedded in struct params.
/layer/image.cpp (name=Image) - Verify parameters on Vulkan calls that use VkImage.
/layer/threading.cpp (name=Threading) - Check multithreading of API calls for validity. Currently this checks that only one thread at a time uses an object in free-threaded API calls.
/layer/swapchain.cpp (name=Swapchain) - Check that WSI extensions are being used correctly.
/layer/shader_checker.cpp (name=ShaderChecker) - Verify SPIR-V shader layout matches descriptor set.
Build VK loader and i965 icd driver using normal steps (cmake and make)
Place libVKLayer.so in the same directory as your VK test or app:
cp build/layer/libVKLayerBasic.so build/layer/libVKLayerGeneric.so build/tests
This is required for the Loader to be able to scan and enumerate your library. Alternatively, use the VK_LAYER_PATH environment variable to specify where the layer libraries reside.
Specify which Layers to activate by using vkCreateDevice and/or vkCreateInstance or environment variables.
export VK_INSTANCE_LAYERS=Basic:Generic export VK_DEVICE_LAYERS=Basic:Generic cd build/tests; ./vkinfo