1*61046927SAndroid Build Coastguard WorkerDispatch 2*61046927SAndroid Build Coastguard Worker============= 3*61046927SAndroid Build Coastguard Worker 4*61046927SAndroid Build Coastguard WorkerThis chapter attempts to document the Vulkan dispatch infrastructure in the 5*61046927SAndroid Build Coastguard WorkerMesa Vulkan runtime. There are a lot of moving pieces here but the end 6*61046927SAndroid Build Coastguard Workerresult has proven quite effective for implementing all the various Vulkan 7*61046927SAndroid Build Coastguard WorkerAPI requirements. 8*61046927SAndroid Build Coastguard Worker 9*61046927SAndroid Build Coastguard Worker 10*61046927SAndroid Build Coastguard WorkerExtension tables 11*61046927SAndroid Build Coastguard Worker---------------- 12*61046927SAndroid Build Coastguard Worker 13*61046927SAndroid Build Coastguard WorkerThe Vulkan runtime defines two extension table structures, one for instance 14*61046927SAndroid Build Coastguard Workerextensions and one for device extensions which contain a Boolean per 15*61046927SAndroid Build Coastguard Workerextension. The device table looks like this: 16*61046927SAndroid Build Coastguard Worker 17*61046927SAndroid Build Coastguard Worker.. code-block:: c 18*61046927SAndroid Build Coastguard Worker 19*61046927SAndroid Build Coastguard Worker #define VK_DEVICE_EXTENSION_COUNT 238 20*61046927SAndroid Build Coastguard Worker 21*61046927SAndroid Build Coastguard Worker struct vk_device_extension_table { 22*61046927SAndroid Build Coastguard Worker union { 23*61046927SAndroid Build Coastguard Worker bool extensions[VK_DEVICE_EXTENSION_COUNT]; 24*61046927SAndroid Build Coastguard Worker struct { 25*61046927SAndroid Build Coastguard Worker bool KHR_8bit_storage; 26*61046927SAndroid Build Coastguard Worker bool KHR_16bit_storage; 27*61046927SAndroid Build Coastguard Worker bool KHR_acceleration_structure; 28*61046927SAndroid Build Coastguard Worker bool KHR_bind_memory2; 29*61046927SAndroid Build Coastguard Worker ... 30*61046927SAndroid Build Coastguard Worker }; 31*61046927SAndroid Build Coastguard Worker }; 32*61046927SAndroid Build Coastguard Worker }; 33*61046927SAndroid Build Coastguard Worker 34*61046927SAndroid Build Coastguard WorkerThe instance extension table is similar except that it includes the 35*61046927SAndroid Build Coastguard Workerinstance level extensions. Both tables are actually unions so that you can 36*61046927SAndroid Build Coastguard Workeraccess the table either by name or as an array. Accessing by name is 37*61046927SAndroid Build Coastguard Workertypically better for human-written code which needs to query for specific 38*61046927SAndroid Build Coastguard Workerenabled extensions or declare a table of which extensions a driver 39*61046927SAndroid Build Coastguard Workersupports. The array form is convenient for more automatic code which wants 40*61046927SAndroid Build Coastguard Workerto iterate over the table. 41*61046927SAndroid Build Coastguard Worker 42*61046927SAndroid Build Coastguard WorkerThese tables are are generated automatically using a bit of python code that 43*61046927SAndroid Build Coastguard Workerparses the vk.xml from the `Vulkan-Docs repo 44*61046927SAndroid Build Coastguard Worker<https://github.com/KhronosGroup/Vulkan-docs/>`__, enumerates the 45*61046927SAndroid Build Coastguard Workerextensions, sorts them by instance vs. device and generates the table. 46*61046927SAndroid Build Coastguard WorkerGenerating it from XML means that we never have to manually maintain any of 47*61046927SAndroid Build Coastguard Workerthese data structures; they get automatically updated when someone imports 48*61046927SAndroid Build Coastguard Workera new version of vk.xml. We also generates a matching pair of tables of 49*61046927SAndroid Build Coastguard Worker``VkExtensionProperties``. This makes it easy to implement 50*61046927SAndroid Build Coastguard Worker``vkEnumerate*ExtensionProperties()`` with a simple loop that walks a table 51*61046927SAndroid Build Coastguard Workerof supported extensions and copies the VkExtensionProperties for each 52*61046927SAndroid Build Coastguard Workerenabled entry. Similarly, we can have a loop in ``vkCreateInstance()`` or 53*61046927SAndroid Build Coastguard Worker``vkCreateDevice()`` which takes the ``ppEnabledExtensionNames`` and fills 54*61046927SAndroid Build Coastguard Workerout the table with all enabled extensions. 55*61046927SAndroid Build Coastguard Worker 56*61046927SAndroid Build Coastguard Worker 57*61046927SAndroid Build Coastguard WorkerEntrypoint and dispatch tables 58*61046927SAndroid Build Coastguard Worker------------------------------ 59*61046927SAndroid Build Coastguard Worker 60*61046927SAndroid Build Coastguard WorkerEntrypoint tables contain a function pointer for every Vulkan entrypoint 61*61046927SAndroid Build Coastguard Workerwithin a particular scope. There are separate tables for instance, 62*61046927SAndroid Build Coastguard Workerphysical device, and device-level functionality. The device entrypoint 63*61046927SAndroid Build Coastguard Workertable looks like this: 64*61046927SAndroid Build Coastguard Worker 65*61046927SAndroid Build Coastguard Worker.. code-block:: c 66*61046927SAndroid Build Coastguard Worker 67*61046927SAndroid Build Coastguard Worker struct vk_device_entrypoint_table { 68*61046927SAndroid Build Coastguard Worker PFN_vkGetDeviceProcAddr GetDeviceProcAddr; 69*61046927SAndroid Build Coastguard Worker PFN_vkDestroyDevice DestroyDevice; 70*61046927SAndroid Build Coastguard Worker PFN_vkGetDeviceQueue GetDeviceQueue; 71*61046927SAndroid Build Coastguard Worker PFN_vkQueueSubmit QueueSubmit; 72*61046927SAndroid Build Coastguard Worker ... 73*61046927SAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_WIN32_KHR 74*61046927SAndroid Build Coastguard Worker PFN_vkGetSemaphoreWin32HandleKHR GetSemaphoreWin32HandleKHR; 75*61046927SAndroid Build Coastguard Worker #else 76*61046927SAndroid Build Coastguard Worker PFN_vkVoidFunction GetSemaphoreWin32HandleKHR; 77*61046927SAndroid Build Coastguard Worker # endif 78*61046927SAndroid Build Coastguard Worker ... 79*61046927SAndroid Build Coastguard Worker }; 80*61046927SAndroid Build Coastguard Worker 81*61046927SAndroid Build Coastguard WorkerEvery entry that requires some sort of platform define is wrapped in an 82*61046927SAndroid Build Coastguard Worker``#ifdef`` and declared as the actual function pointer type if the platform 83*61046927SAndroid Build Coastguard Workerdefine is set and declared as a void function otherwise. This ensures that 84*61046927SAndroid Build Coastguard Workerthe layout of the structure doesn't change based on preprocessor symbols 85*61046927SAndroid Build Coastguard Workerbut anyone who has the platform defines set gets the real prototype and 86*61046927SAndroid Build Coastguard Workeranyone who doesn't can use the table without needing to pull in all the 87*61046927SAndroid Build Coastguard Workerplatform headers. 88*61046927SAndroid Build Coastguard Worker 89*61046927SAndroid Build Coastguard WorkerDispatch tables are similar to entrypoint tables except that they're 90*61046927SAndroid Build Coastguard Workerdeduplicated so that aliased entrypoints have only one entry in the table. 91*61046927SAndroid Build Coastguard WorkerThe device dispatch table looks like this: 92*61046927SAndroid Build Coastguard Worker 93*61046927SAndroid Build Coastguard Worker.. code-block:: c 94*61046927SAndroid Build Coastguard Worker 95*61046927SAndroid Build Coastguard Worker struct vk_device_dispatch_table { 96*61046927SAndroid Build Coastguard Worker PFN_vkGetDeviceProcAddr GetDeviceProcAddr; 97*61046927SAndroid Build Coastguard Worker PFN_vkDestroyDevice DestroyDevice; 98*61046927SAndroid Build Coastguard Worker PFN_vkGetDeviceQueue GetDeviceQueue; 99*61046927SAndroid Build Coastguard Worker PFN_vkQueueSubmit QueueSubmit; 100*61046927SAndroid Build Coastguard Worker ... 101*61046927SAndroid Build Coastguard Worker union { 102*61046927SAndroid Build Coastguard Worker PFN_vkResetQueryPool ResetQueryPool; 103*61046927SAndroid Build Coastguard Worker PFN_vkResetQueryPoolEXT ResetQueryPoolEXT; 104*61046927SAndroid Build Coastguard Worker }; 105*61046927SAndroid Build Coastguard Worker ... 106*61046927SAndroid Build Coastguard Worker }; 107*61046927SAndroid Build Coastguard Worker 108*61046927SAndroid Build Coastguard WorkerIn order to allow code to use any of the aliases for a given entrypoint, 109*61046927SAndroid Build Coastguard Workersuch entrypoints are wrapped in a union. This is important because we need 110*61046927SAndroid Build Coastguard Workerto be able to add new aliases potentially at any Vulkan release and we want 111*61046927SAndroid Build Coastguard Workerto do so without having to update all the driver code which uses one of the 112*61046927SAndroid Build Coastguard Workernewly aliased entrypoints. We could require that everyone use the first 113*61046927SAndroid Build Coastguard Workername an entrypoint ever has but that gets weird if, for instance, it's 114*61046927SAndroid Build Coastguard Workerintroduced in an EXT extension and some driver only ever implements the KHR 115*61046927SAndroid Build Coastguard Workeror core version of the feature. It's easier for everyone if we make all 116*61046927SAndroid Build Coastguard Workerthe entrypoint names work. 117*61046927SAndroid Build Coastguard Worker 118*61046927SAndroid Build Coastguard WorkerAn entrypoint table can be converted to a dispatch table by compacting it 119*61046927SAndroid Build Coastguard Workerwith one of the ``vk_*_dispatch_table_from_entrypoints()`` family of 120*61046927SAndroid Build Coastguard Workerfunctions: 121*61046927SAndroid Build Coastguard Worker 122*61046927SAndroid Build Coastguard Worker.. code-block:: c 123*61046927SAndroid Build Coastguard Worker 124*61046927SAndroid Build Coastguard Worker void vk_instance_dispatch_table_from_entrypoints( 125*61046927SAndroid Build Coastguard Worker struct vk_instance_dispatch_table *dispatch_table, 126*61046927SAndroid Build Coastguard Worker const struct vk_instance_entrypoint_table *entrypoint_table, 127*61046927SAndroid Build Coastguard Worker bool overwrite); 128*61046927SAndroid Build Coastguard Worker 129*61046927SAndroid Build Coastguard Worker void vk_physical_device_dispatch_table_from_entrypoints( 130*61046927SAndroid Build Coastguard Worker struct vk_physical_device_dispatch_table *dispatch_table, 131*61046927SAndroid Build Coastguard Worker const struct vk_physical_device_entrypoint_table *entrypoint_table, 132*61046927SAndroid Build Coastguard Worker bool overwrite); 133*61046927SAndroid Build Coastguard Worker 134*61046927SAndroid Build Coastguard Worker void vk_device_dispatch_table_from_entrypoints( 135*61046927SAndroid Build Coastguard Worker struct vk_device_dispatch_table *dispatch_table, 136*61046927SAndroid Build Coastguard Worker const struct vk_device_entrypoint_table *entrypoint_table, 137*61046927SAndroid Build Coastguard Worker bool overwrite); 138*61046927SAndroid Build Coastguard Worker 139*61046927SAndroid Build Coastguard Worker 140*61046927SAndroid Build Coastguard WorkerGenerating driver dispatch tables 141*61046927SAndroid Build Coastguard Worker--------------------------------- 142*61046927SAndroid Build Coastguard Worker 143*61046927SAndroid Build Coastguard WorkerEntrypoint tables can be easily auto-generated for your driver. Simply put 144*61046927SAndroid Build Coastguard Workerthe following in the driver's ``meson.build``, modified as necessary: 145*61046927SAndroid Build Coastguard Worker 146*61046927SAndroid Build Coastguard Worker.. code-block:: 147*61046927SAndroid Build Coastguard Worker 148*61046927SAndroid Build Coastguard Worker drv_entrypoints = custom_target( 149*61046927SAndroid Build Coastguard Worker 'drv_entrypoints', 150*61046927SAndroid Build Coastguard Worker input : [vk_entrypoints_gen, vk_api_xml], 151*61046927SAndroid Build Coastguard Worker output : ['drv_entrypoints.h', 'drv_entrypoints.c'], 152*61046927SAndroid Build Coastguard Worker command : [ 153*61046927SAndroid Build Coastguard Worker prog_python, '@INPUT0@', '--xml', '@INPUT1@', '--proto', '--weak', 154*61046927SAndroid Build Coastguard Worker '--out-h', '@OUTPUT0@', '--out-c', '@OUTPUT1@', '--prefix', 'drv', 155*61046927SAndroid Build Coastguard Worker '--beta', with_vulkan_beta.to_string(), 156*61046927SAndroid Build Coastguard Worker ], 157*61046927SAndroid Build Coastguard Worker depend_files : vk_entrypoints_gen_depend_files, 158*61046927SAndroid Build Coastguard Worker ) 159*61046927SAndroid Build Coastguard Worker 160*61046927SAndroid Build Coastguard WorkerThe generated ``drv_entrypoints.h`` fill will contain prototypes for every 161*61046927SAndroid Build Coastguard WorkerVulkan entrypoint, prefixed with what you passed to ``--prefix`` above. 162*61046927SAndroid Build Coastguard WorkerFor instance, if you set ``--prefix drv`` and the entrypoint name is 163*61046927SAndroid Build Coastguard Worker``vkCreateDevice()``, the driver entrypoint will be named 164*61046927SAndroid Build Coastguard Worker``drv_CreateDevice()``. The ``--prefix`` flag can be specified multiple 165*61046927SAndroid Build Coastguard Workertimes if you want more than one table. It also generates an entrypoint 166*61046927SAndroid Build Coastguard Workertable for each prefix and each dispatch level (instance, physical device, 167*61046927SAndroid Build Coastguard Workerand device) which is populated using the driver's functions. Thanks to our 168*61046927SAndroid Build Coastguard Workeruse of weak function pointers (or something roughly equivalent for MSVC), 169*61046927SAndroid Build Coastguard Workerany entrypoints which are not implemented will automatically show up as 170*61046927SAndroid Build Coastguard Worker``NULL`` entries in the table rather than resulting in linking errors. 171*61046927SAndroid Build Coastguard Worker 172*61046927SAndroid Build Coastguard WorkerThe above generates entrypoint tables because, thanks to aliasing and the C 173*61046927SAndroid Build Coastguard Workerrules around const struct declarations, it's not practical to generate a 174*61046927SAndroid Build Coastguard Workerdispatch table directly. Before they can be passed into the relevant 175*61046927SAndroid Build Coastguard Worker``vk_*_init()`` function, the entrypoint table will have to be converted to 176*61046927SAndroid Build Coastguard Workera dispatch table. The typical pattern for this inside a driver looks 177*61046927SAndroid Build Coastguard Workersomething like this: 178*61046927SAndroid Build Coastguard Worker 179*61046927SAndroid Build Coastguard Worker.. code-block:: c 180*61046927SAndroid Build Coastguard Worker 181*61046927SAndroid Build Coastguard Worker struct vk_instance_dispatch_table dispatch_table; 182*61046927SAndroid Build Coastguard Worker vk_instance_dispatch_table_from_entrypoints( 183*61046927SAndroid Build Coastguard Worker &dispatch_table, &anv_instance_entrypoints, true); 184*61046927SAndroid Build Coastguard Worker vk_instance_dispatch_table_from_entrypoints( 185*61046927SAndroid Build Coastguard Worker &dispatch_table, &wsi_instance_entrypoints, false); 186*61046927SAndroid Build Coastguard Worker 187*61046927SAndroid Build Coastguard Worker result = vk_instance_init(&instance->vk, &instance_extensions, 188*61046927SAndroid Build Coastguard Worker &dispatch_table, pCreateInfo, pAllocator); 189*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) { 190*61046927SAndroid Build Coastguard Worker vk_free(pAllocator, instance); 191*61046927SAndroid Build Coastguard Worker return result; 192*61046927SAndroid Build Coastguard Worker } 193*61046927SAndroid Build Coastguard Worker 194*61046927SAndroid Build Coastguard WorkerThe ``vk_*_dispatch_table_from_entrypoints()`` functions are designed so 195*61046927SAndroid Build Coastguard Workerthat they can be layered like this. In this case, it starts with the 196*61046927SAndroid Build Coastguard Workerinstance entrypoints from the Intel Vulkan driver and then adds in the WSI 197*61046927SAndroid Build Coastguard Workerentrypoints. If there are any entrypoints duplicated between the two, the 198*61046927SAndroid Build Coastguard Workerfirst one to define the entrypoint wins. 199*61046927SAndroid Build Coastguard Worker 200*61046927SAndroid Build Coastguard Worker 201*61046927SAndroid Build Coastguard WorkerCommon Vulkan entrypoints 202*61046927SAndroid Build Coastguard Worker------------------------- 203*61046927SAndroid Build Coastguard Worker 204*61046927SAndroid Build Coastguard WorkerFor the Vulkan runtime itself, there is a dispatch table with the 205*61046927SAndroid Build Coastguard Worker``vk_common`` prefix used to provide common implementations of various 206*61046927SAndroid Build Coastguard Workerentrypoints. This entrypoint table is added last as part of 207*61046927SAndroid Build Coastguard Worker``vk_*_init()`` so that the driver implementation will always be used, if 208*61046927SAndroid Build Coastguard Workerthere is one. 209*61046927SAndroid Build Coastguard Worker 210*61046927SAndroid Build Coastguard WorkerThis is used to implement a bunch of things on behalf of the driver. The 211*61046927SAndroid Build Coastguard Workermost common case is whenever there are ``vkFoo()`` and ``vkFoo2()`` 212*61046927SAndroid Build Coastguard Workerentrypoints. We provide wrappers for nearly all of these that implement 213*61046927SAndroid Build Coastguard Worker``vkFoo()`` in terms of ``vkFoo2()`` so a driver can switch to the new one 214*61046927SAndroid Build Coastguard Workerand throw the old one away. For instance, ``vk_common_BindBufferMemory()`` 215*61046927SAndroid Build Coastguard Workerlooks like this: 216*61046927SAndroid Build Coastguard Worker 217*61046927SAndroid Build Coastguard Worker.. code-block:: c 218*61046927SAndroid Build Coastguard Worker 219*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL 220*61046927SAndroid Build Coastguard Worker vk_common_BindBufferMemory(VkDevice _device, 221*61046927SAndroid Build Coastguard Worker VkBuffer buffer, 222*61046927SAndroid Build Coastguard Worker VkDeviceMemory memory, 223*61046927SAndroid Build Coastguard Worker VkDeviceSize memoryOffset) 224*61046927SAndroid Build Coastguard Worker { 225*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(vk_device, device, _device); 226*61046927SAndroid Build Coastguard Worker 227*61046927SAndroid Build Coastguard Worker VkBindBufferMemoryInfo bind = { 228*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO, 229*61046927SAndroid Build Coastguard Worker .buffer = buffer, 230*61046927SAndroid Build Coastguard Worker .memory = memory, 231*61046927SAndroid Build Coastguard Worker .memoryOffset = memoryOffset, 232*61046927SAndroid Build Coastguard Worker }; 233*61046927SAndroid Build Coastguard Worker 234*61046927SAndroid Build Coastguard Worker return device->dispatch_table.BindBufferMemory2(_device, 1, &bind); 235*61046927SAndroid Build Coastguard Worker } 236*61046927SAndroid Build Coastguard Worker 237*61046927SAndroid Build Coastguard WorkerThere are, of course, far more complicated cases of implementing 238*61046927SAndroid Build Coastguard Worker``vkFoo()`` in terms of ``vkFoo2()`` such as the 239*61046927SAndroid Build Coastguard Worker``vk_common_QueueSubmit()`` implementation. We also implement far less 240*61046927SAndroid Build Coastguard Workertrivial functionality as ``vk_common_*`` entrypoints. For instance, we 241*61046927SAndroid Build Coastguard Workerhave full implementations of ``VkFence``, ``VkSemaphore``, and 242*61046927SAndroid Build Coastguard Worker``vkQueueSubmit2()``. 243*61046927SAndroid Build Coastguard Worker 244*61046927SAndroid Build Coastguard Worker 245*61046927SAndroid Build Coastguard WorkerEntrypoint lookup 246*61046927SAndroid Build Coastguard Worker----------------- 247*61046927SAndroid Build Coastguard Worker 248*61046927SAndroid Build Coastguard WorkerImplementing ``vkGet*ProcAddr()`` is quite complicated because of the 249*61046927SAndroid Build Coastguard WorkerVulkan 1.2 rules around exactly when they have to return ``NULL``. When a 250*61046927SAndroid Build Coastguard Workerclient calls ``vkGet*ProcAddr()``, we go through a three step process resolve 251*61046927SAndroid Build Coastguard Workerthe function pointer: 252*61046927SAndroid Build Coastguard Worker 253*61046927SAndroid Build Coastguard Worker 1. A static (generated at compile time) hash table is used to map the 254*61046927SAndroid Build Coastguard Worker entrypoint name to an index into the corresponding entry point table. 255*61046927SAndroid Build Coastguard Worker 256*61046927SAndroid Build Coastguard Worker 2. Optionally, the index is passed to an auto-generated function that 257*61046927SAndroid Build Coastguard Worker checks against the enabled core API version and extensions. We use an 258*61046927SAndroid Build Coastguard Worker index into the entrypoint table, not the dispatch table, because the 259*61046927SAndroid Build Coastguard Worker rules for when an entrypoint should be exposed are per-entrypoint. For 260*61046927SAndroid Build Coastguard Worker instance, ``vkBindImageMemory2`` is available on Vulkan 1.1 and later but 261*61046927SAndroid Build Coastguard Worker ``vkBindImageMemory2KHR`` is available if :ext:`VK_KHR_bind_memory2` is 262*61046927SAndroid Build Coastguard Worker enabled. 263*61046927SAndroid Build Coastguard Worker 264*61046927SAndroid Build Coastguard Worker 3. A compaction table is used to map from the entrypoint table index to 265*61046927SAndroid Build Coastguard Worker the dispatch table index and the function is finally fetched from the 266*61046927SAndroid Build Coastguard Worker dispatch table. 267*61046927SAndroid Build Coastguard Worker 268*61046927SAndroid Build Coastguard WorkerAll of this is encapsulated within the ``vk_*_dispatch_table_get()`` and 269*61046927SAndroid Build Coastguard Worker``vk_*_dispatch_table_get_if_supported()`` families of functions. The 270*61046927SAndroid Build Coastguard Worker``_if_supported`` versions take a core version and one or more extension 271*61046927SAndroid Build Coastguard Workertables. The driver has to provide ``vk_icdGet*ProcAddr()`` entrypoints 272*61046927SAndroid Build Coastguard Workerwhich wrap these functions because those have to be exposed as actual 273*61046927SAndroid Build Coastguard Workersymbols from the ``.so`` or ``.dll`` as part of the loader interface. It 274*61046927SAndroid Build Coastguard Workeralso has to provide its own ``drv_GetInstanceProcAddr()`` because it needs 275*61046927SAndroid Build Coastguard Workerto pass the supported instance extension table to 276*61046927SAndroid Build Coastguard Worker:c:func:`vk_instance_get_proc_addr`. The runtime will provide 277*61046927SAndroid Build Coastguard Worker``vk_common_GetDeviceProcAddr()`` implementations. 278*61046927SAndroid Build Coastguard Worker 279*61046927SAndroid Build Coastguard Worker 280*61046927SAndroid Build Coastguard WorkerPopulating layer or client dispatch tables 281*61046927SAndroid Build Coastguard Worker------------------------------------------ 282*61046927SAndroid Build Coastguard Worker 283*61046927SAndroid Build Coastguard WorkerThe entrypoint and dispatch tables actually live in ``src/vulkan/util``, 284*61046927SAndroid Build Coastguard Workernot ``src/vulkan/runtime`` so they can be used by layers and clients (such 285*61046927SAndroid Build Coastguard Workeras Zink) as well as the runtime. Layers and clients may wish to populate 286*61046927SAndroid Build Coastguard Workerdispatch tables from an underlying Vulkan implementation. This can be done 287*61046927SAndroid Build Coastguard Workervia the ``vk_*_dispatch_table_load()`` family of functions: 288*61046927SAndroid Build Coastguard Worker 289*61046927SAndroid Build Coastguard Worker.. code-block:: c 290*61046927SAndroid Build Coastguard Worker 291*61046927SAndroid Build Coastguard Worker void 292*61046927SAndroid Build Coastguard Worker vk_instance_dispatch_table_load(struct vk_instance_dispatch_table *table, 293*61046927SAndroid Build Coastguard Worker PFN_vkGetInstanceProcAddr gpa, 294*61046927SAndroid Build Coastguard Worker VkInstance instance); 295*61046927SAndroid Build Coastguard Worker void 296*61046927SAndroid Build Coastguard Worker vk_physical_device_dispatch_table_load(struct vk_physical_device_dispatch_table *table, 297*61046927SAndroid Build Coastguard Worker PFN_vkGetInstanceProcAddr gpa, 298*61046927SAndroid Build Coastguard Worker VkInstance instance); 299*61046927SAndroid Build Coastguard Worker void 300*61046927SAndroid Build Coastguard Worker vk_device_dispatch_table_load(struct vk_device_dispatch_table *table, 301*61046927SAndroid Build Coastguard Worker PFN_vkGetDeviceProcAddr gpa, 302*61046927SAndroid Build Coastguard Worker VkDevice device); 303*61046927SAndroid Build Coastguard Worker 304*61046927SAndroid Build Coastguard WorkerThese call the given ``vkGet*ProcAddr`` function to populate the dispatch 305*61046927SAndroid Build Coastguard Workertable. For aliased entrypoints, it will try each variant in succession to 306*61046927SAndroid Build Coastguard Workerensure that the dispatch table entry gets populated no matter which version 307*61046927SAndroid Build Coastguard Workerof the feature you have enabled. 308