Layer libraries can be written to intercept or hook VK entrypoints for various debug and validation purposes. One or more VK entrypoints 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. vkEnumerateLayer can be called to list the available layer libraries. vkGetProcAddr is used internally by the Layers and ICD Loader to initialize dispatch tables. Layers are activated at vkCreateDevice time. vkCreateDevice createInfo struct is extended to allow a list of layers to be activated. Layer libraries can alternatively be LD_PRELOADed depending upon how they are implemented.
##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.c (name=Generic) - auto generated example wrapping all VK entrypoints. Single global dispatch table. Can be LD_PRELOADed.
(build dir)/layer/api_dump.c (name=APIDump) - print out API calls along with parameter values
(build dir)/layer/api_dump.cpp (name=APIDumpCpp) - same as above but uses c++ strings and i/o streams
(build dir)/layer/api_dump_file.c (name=APIDumpFile) - Write API calls along with parameter values to vk_apidump.txt file.
(build dir)/layer/api_dump_no_addr.c (name=APIDumpNoAddr) - print out API calls along with parameter values but replace any variable addresses with the static string "addr".
(build dir)/layer/api_dump_no_addr.cpp (name=APIDumpNoAddrCpp) - same as above but uses c++ strings and i/o streams
(build dir>/layer/object_track.c (name=ObjectTracker) - Print object CREATE/USE/DESTROY stats. Individually track objects by category. VkObjectType enum defined in vulkan.h. If a Dbg callback function is registered, this layer will use callback function(s) for reporting, otherwise uses stdout. Provides custom interface to query number about the total number of objects or of live objects of given type. To get information on all objects, use "VK_UINT64 objTrackGetObjectsCount()" and the secondary call to return an array of those objects "VK_RESULT objTrackGetObjects(VK_UINT64 objCount, OBJTRACK_NODE* pObjNodeArray)". For objects of a specific type, use "VK_UINT64 objTrackGetObjectsOfTypeCount(VkObjectType type)" and the secondary call to return an array of those objects "VK_RESULT objTrackGetObjectsOfType(VK_OBJECT_TYPE type, VK_UINT64 objCount, OBJTRACK_NODE* pObjNodeArray)".
layer/draw_state.c (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. If a Dbg callback function is registered, this layer will use callback function(s) for reporting, otherwise uses stdout.
layer/mem_tracker.c (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. If a Dbg callback function is registered, this layer will use callback function(s) for reporting, otherwise uses stdout.
/layer/param_checker.c (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. If a Dbg callback function is registered, this layer will use callback function(s) for reporting, otherwise uses stdout.
/layer/threading.c (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. If a Dbg callback function is registered, this layer will use callback function(s) for reporting, otherwise uses stdout.
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 Icd loader to be able to scan and enumerate your library. Alternatively, use the LIBVK_LAYERS_PATH environment variable to specify where the layer libraries reside.
Specify which Layers to activate by using vkCreateDevice VK_LAYER_CREATE_INFO struct or environment variable LIBVK_LAYER_NAMES
export LIBVK_LAYER_NAMES=Basic:Generic cd build/tests; ./vkinfo