Welcome to mirror list, hosted at ThFree Co, Russian Federation.

LoaderDriverInterface.md « docs - github.com/KhronosGroup/Vulkan-Loader.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: ab20941ba5700778d89be2fce47e2c4cdc420a4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
<!-- markdownlint-disable MD041 -->
[![Khronos Vulkan][1]][2]

[1]: https://vulkan.lunarg.com/img/Vulkan_100px_Dec16.png "https://www.khronos.org/vulkan/"
[2]: https://www.khronos.org/vulkan/

# Driver interface to the Vulkan Loader
[![Creative Commons][3]][4]

<!-- Copyright &copy; 2015-2021 LunarG, Inc. -->

[3]: https://i.creativecommons.org/l/by-nd/4.0/88x31.png "Creative Commons License"
[4]: https://creativecommons.org/licenses/by-nd/4.0/


## Table of Contents

- [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)
      - [On Linux](#on-linux)
      - [On macOS](#on-macos)
  - [Driver Manifest File Usage](#driver-manifest-file-usage)
  - [Driver Discovery on Windows](#driver-discovery-on-windows)
  - [Driver Discovery on Linux](#driver-discovery-on-linux)
    - [Example Linux Driver Search Path](#example-linux-driver-search-path)
  - [Driver Discovery on Fuchsia](#driver-discovery-on-fuchsia)
  - [Driver Discovery on macOS](#driver-discovery-on-macos)
    - [Example macOS Driver Search Path](#example-macos-driver-search-path)
    - [Additional Settings For Driver Debugging](#additional-settings-for-driver-debugging)
  - [Using Pre-Production ICDs or Software Drivers](#using-pre-production-icds-or-software-drivers)
  - [Driver Discovery on Android](#driver-discovery-on-android)
- [Driver Manifest File Format](#driver-manifest-file-format)
  - [Driver Manifest File Versions](#driver-manifest-file-versions)
    - [Driver Manifest File Version 1.0.0](#driver-manifest-file-version-100)
    - [Driver Manifest File Version 1.0.1](#driver-manifest-file-version-101)
- [Driver Vulkan Entry Point Discovery](#driver-vulkan-entry-point-discovery)
- [Driver API Version](#driver-api-version)
- [Mixed Driver Instance Extension Support](#mixed-driver-instance-extension-support)
  - [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)
- [Loader and Driver Interface Negotiation](#loader-and-driver-interface-negotiation)
  - [Windows, Linux and macOS Driver Negotiation](#windows-linux-and-macos-driver-negotiation)
    - [Version Negotiation Between Loader and Drivers](#version-negotiation-between-loader-and-drivers)
    - [Interfacing With Legacy Drivers or Loaders](#interfacing-with-legacy-drivers-or-loaders)
    - [Loader Version 6 Interface Requirements](#loader-version-6-interface-requirements)
    - [Loader Version 5 Interface Requirements](#loader-version-5-interface-requirements)
    - [Loader Version 4 Interface Requirements](#loader-version-4-interface-requirements)
    - [Loader Version 3 Interface Requirements](#loader-version-3-interface-requirements)
    - [Loader Version 2 Interface Requirements](#loader-version-2-interface-requirements)
    - [Loader Version 1 Interface Requirements](#loader-version-1-interface-requirements)
    - [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-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)


## Overview

This is the Driver-centric view of working with the Vulkan loader.
For the complete overview of all sections of the loader, please refer to the
[LoaderInterfaceArchitecture.md](LoaderInterfaceArchitecture.md) file.

**NOTE:** While many of the interfaces still use the "icd" sub-string to
identify various behavior associated with drivers, this is purely
historical and should not indicate that the implementing code do so through
the traditional ICD interface.
Granted, the majority of drivers to this date are ICD drivers
targeting specific GPU hardware.

## Driver Discovery

Vulkan allows multiple drivers each with one or more devices
(represented by a Vulkan `VkPhysicalDevice` object) to be used collectively.
The loader is responsible for discovering available Vulkan drivers on
the system.
Given a list of available drivers, the loader can enumerate all the
physical devices available for an application and return this information to the
application.
The process in which the loader discovers the available drivers on a
system is platform-dependent.
Windows, Linux, Android, and macOS Driver Discovery details are listed
below.

### Overriding the Default Driver Discovery

There may be times that a developer wishes to force the loader to use a specific
Driver.
This could be for many reasons including using a beta driver, or forcing the
loader to skip a problematic driver.
In order to support this, the loader can be forced to look at specific
drivers with either the `VK_DRIVER_FILES` or the older `VK_ICD_FILENAMES`
environment variable.
Both these environment variables behave the same, but `VK_ICD_FILENAMES`
should be considered deprecated.
If both `VK_DRIVER_FILES` and `VK_ICD_FILENAMES` environment variables are
present, then the newer `VK_DRIVER_FILES` will be used, and the values in
`VK_ICD_FILENAMES` will be ignored.

The `VK_DRIVER_FILES` environment variable is a list of Driver Manifest
files, containing the full path to the driver JSON Manifest file.
This list is colon-separated on Linux and macOS, and semicolon-separated on
Windows.
Typically, `VK_DRIVER_FILES` will only contain a full pathname to one info
file for a single driver.
A separator (colon or semicolon) is only used if more than one driver is needed.

### Additional Driver Discovery

There may be times that a developer wishes to force the loader to use a specific
Driver in addition to the standard drivers (without replacing the standard
search paths.
The `VK_ADD_DRIVER_FILES` environment variable can be used to add a list of
Driver Manifest files, containing the full path to the driver JSON Manifest file.
This list is colon-separated on Linux and macOS, and semicolon-separated on
Windows.
It will be added prior to the standard driver search files.
If `VK_DRIVER_FILES` or `VK_ICD_FILENAMES` is present, then
`VK_ADD_DRIVER_FILES` will not be used by the loader and any values will be
ignored.

#### Exception for Elevated Privileges

For security reasons, `VK_ICD_FILENAMES`, `VK_DRIVER_FILES` and
`VK_ADD_DRIVER_FILES` are all ignored if running the Vulkan application with
elevated privileges.
Because of this, these environment variables can only be used for applications
that do not use elevated privileges.

For more information see
[Elevated Privilege Caveats](LoaderInterfaceArchitecture.md#elevated-privilege-caveats)
in the top-level
[LoaderInterfaceArchitecture.md](LoaderInterfaceArchitecture.md) document.

#### Examples

In order to use the setting, simply set it to a properly delimited list of
Driver Manifest files.
In this case, please provide the global path to these files to reduce issues.

For example:

##### On Windows

```
set VK_DRIVER_FILES=\windows\system32\nv-vk64.json
```

This is an example which is using the `VK_DRIVER_FILES` override on Windows to
point to the Nvidia Vulkan Driver's Manifest file.

```
set VK_ADD_DRIVER_FILES=\windows\system32\nv-vk64.json
```

This is an example which is using the `VK_ADD_DRIVER_FILES` on Windows to
point to the Nvidia Vulkan Driver's Manifest file which will be loaded first
before all other drivers.

##### On Linux

```
export VK_DRIVER_FILES=/home/user/dev/mesa/share/vulkan/icd.d/intel_icd.x86_64.json
```

This is an example which is using the `VK_DRIVER_FILES` override on Linux to
point to the Intel Mesa Driver's Manifest file.

```
export VK_ADD_DRIVER_FILES=/home/user/dev/mesa/share/vulkan/icd.d/intel_icd.x86_64.json
```

This is an example which is using the `VK_ADD_DRIVER_FILES` on Linux to
point to the Intel Mesa Driver's Manifest file which will be loaded first
before all other drivers.

##### On macOS

```
export VK_DRIVER_FILES=/home/user/MoltenVK/Package/Latest/MoltenVK/macOS/MoltenVK_icd.json
```

This is an example which is using the `VK_DRIVER_FILES` override on macOS to
point to an installation and build of the MoltenVK GitHub repository that
contains the MoltenVK driver.

See the
[Table of Debug Environment Variables](LoaderInterfaceArchitecture.md#table-of-debug-environment-variables)
in the [LoaderInterfaceArchitecture.md document](LoaderInterfaceArchitecture.md)
for more details


### Driver Manifest File Usage

As with layers, on Windows, Linux and macOS systems, JSON-formatted manifest
files are used to store driver information.
In order to find system-installed drivers, the Vulkan loader will read the JSON
files to identify the names and attributes of each driver.
Notice that Driver Manifest files are much simpler than the corresponding
layer Manifest files.

See the
[Current Driver Manifest File Format](#driver-manifest-file-format)
section for more details.


### Driver Discovery on Windows

In order to find available drivers (including installed ICDs), the
loader scans through registry keys specific to Display Adapters and all Software
Components associated with these adapters for the locations of JSON manifest
files.
These keys are located in device keys created during driver installation and
contain configuration information for base settings, including OpenGL and
Direct3D locations.

The Device Adapter and Software Component key paths will be obtained by first
enumerating DXGI adapters.
Should that fail it will use the PnP Configuration Manager API.
The `000X` key will be a numbered key, where each device is assigned a different
number.

```
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{Adapter GUID}\000X\VulkanDriverName
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{SoftwareComponent GUID}\000X\VulkanDriverName
```

In addition, on 64-bit systems there may be another set of registry values,
listed below.
These values record the locations of 32-bit layers on 64-bit operating systems,
in the same way as the Windows-on-Windows functionality.

```
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{Adapter GUID}\000X\VulkanDriverNameWow
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{SoftwareComponent GUID}\000X\VulkanDriverNameWow
```

If any of the above values exist and is of type `REG_SZ`, the loader will open
the JSON manifest file specified by the key value.
Each value must be a full absolute path to a JSON manifest file.
The values may also be of type `REG_MULTI_SZ`, in which case the value will be
interpreted as a list of paths to JSON manifest files.

Additionally, the Vulkan loader will scan the values in the following Windows
registry key:

```
HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\Drivers
```

For 32-bit applications on 64-bit Windows, the loader scan's the 32-bit
registry location:

```
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Khronos\Vulkan\Drivers
```

Every driver in these locations should be given as a DWORD, with value 0, where
the name of the value is the full path to a JSON manifest file.
The Vulkan loader will attempt to open each manifest file to obtain the
information about a driver's shared library (".dll") file.

For example, let us assume the registry contains the following data:

```
[HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\Drivers\]

"C:\vendor a\vk_vendor_a.json"=dword:00000000
"C:\windows\system32\vendor_b_vk.json"=dword:00000001
"C:\windows\system32\vendor_c_icd.json"=dword:00000000
```

In this case, the loader will step through each entry, and check the value.
If the value is 0, then the loader will attempt to load the file.
In this case, the loader will open the first and last listings, but not the
middle.
This is because the value of 1 for vendor_b_vk.json disables the driver.

Additionally, the Vulkan loader will scan the system for well-known Windows
AppX/MSIX packages. If a package is found, the loader will scan the root directory
of this installed package for JSON manifest files. At this time, the only package
that is known is Microsoft's
[OpenCL™ and OpenGL® Compatibility Pack](https://apps.microsoft.com/store/detail/9NQPSL29BFFF?hl=en-us&gl=US).

The Vulkan loader will open each enabled manifest file found to obtain the name
or pathname of a driver's shared library (".DLL") file.

Drivers should use the registry locations from the PnP Configuration
Manager wherever practical.
Typically, this is most important for drivers, and the location clearly
ties the driver to a given device.
The `SOFTWARE\Khronos\Vulkan\Drivers` location is the older method for locating
drivers, but is the primary location for software based drivers.

See the
[Driver Manifest File Format](#driver-manifest-file-format)
section for more details.


### Driver Discovery on Linux

On Linux, the Vulkan loader will scan for Driver Manifest files using
environment variables or corresponding fallback values if the corresponding
environment variable is not defined:

<table style="width:100%">
  <tr>
    <th>Search Order</th>
    <th>Directory/Environment Variable</th>
    <th>Fallback</th>
    <th>Additional Notes</th>
  </tr>
  <tr>
    <td>1</td>
    <td>$XDG_CONFIG_HOME</td>
    <td>$HOME/.config</td>
    <td><b>This path is ignored when running with elevated privileges such as
           setuid, setgid, or filesystem capabilities</b>.<br/>
        This is done because under these scenarios it is not safe to trust
        that the environment variables are non-malicious.<br/>
        See <a href="LoaderInterfaceArchitecture.md#elevated-privilege-caveats">
        Elevated Privilege Caveats</a> for more information.
    </td>
  </tr>
  <tr>
    <td>1</td>
    <td>$XDG_CONFIG_DIRS</td>
    <td>/etc/xdg</td>
    <td></td>
  </tr>
  <tr>
    <td>2</td>
    <td>SYSCONFDIR</td>
    <td>/etc</td>
    <td>Compile-time option set to possible location of drivers
        installed from non-Linux-distribution-provided packages.
    </td>
  </tr>
  <tr>
    <td>3</td>
    <td>EXTRASYSCONFDIR</td>
    <td>/etc</td>
    <td>Compile-time option set to possible location of drivers
        installed from non-Linux-distribution-provided packages.
        Typically only set if SYSCONFDIR is set to something other than /etc
    </td>
  </tr>
  <tr>
    <td>4</td>
    <td>$XDG_DATA_HOME</td>
    <td>$HOME/.local/share</td>
    <td><b>This path is ignored when running with elevated privileges such as
           setuid, setgid, or filesystem capabilities</b>.<br/>
        This is done because under these scenarios it is not safe to trust
        that the environment variables are non-malicious.<br/>
        See <a href="LoaderInterfaceArchitecture.md#elevated-privilege-caveats">
        Elevated Privilege Caveats</a> for more information.
    </td>
  </tr>
  <tr>
    <td>5</td>
    <td>$XDG_DATA_DIRS</td>
    <td>/usr/local/share/:/usr/share/</td>
    <td></td>
  </tr>
</table>

The directory lists are concatenated together using the standard platform path
separator (:).
The loader then selects each path, and applies the "/vulkan/icd.d" suffix onto
each and looks in that specific folder for manifest files.

The Vulkan loader will open each manifest file found to obtain the name or
pathname of a driver's shared library (".dylib") file.

**NOTE** While the order of folders searched for manifest files is well
defined, the order contents are read by the loader in each directory is
[random due to the behavior of readdir](https://www.ibm.com/support/pages/order-directory-contents-returned-calls-readdir).

See the
[Driver Manifest File Format](#driver-manifest-file-format)
section for more details.

It is also important to note that while `VK_DRIVER_FILES` will point the loader
to finding the manifest files, it does not guarantee the library files mentioned
by the manifest will immediately be found.
Often, the Driver Manifest file will point to the library file using a
relative or absolute path.
When a relative or absolute path is used, the loader can typically find the
library file without querying the operating system.
However, if a library is listed only by name, the loader may not find it,
unless the driver is installed placing the library in an operating system
searchable default location.
If problems occur finding a library file associated with a driver, try updating
the `LD_LIBRARY_PATH` environment variable to point at the location of the
corresponding `.so` file.


#### Example Linux Driver Search Path

For a fictional user "me" the Driver Manifest search path might look
like the following:

```
  /home/me/.config/vulkan/icd.d
  /etc/xdg/vulkan/icd.d
  /usr/local/etc/vulkan/icd.d
  /etc/vulkan/icd.d
  /home/me/.local/share/vulkan/icd.d
  /usr/local/share/vulkan/icd.d
  /usr/share/vulkan/icd.d
```


### Driver Discovery on Fuchsia

On Fuchsia, the Vulkan loader will scan for manifest files using environment
variables or corresponding fallback values if the corresponding environment
variable is not defined in the same way as
[Linux](#linux-driver-discovery).
The **only** difference is that Fuchsia does not allow fallback values for
*$XDG_DATA_DIRS* or *$XDG_HOME_DIRS*.


### Driver Discovery on macOS

On macOS, the Vulkan loader will scan for Driver Manifest files using
the application resource folder as well as environment variables or
corresponding fallback values if the corresponding environment variable is not
defined.
The order is similar to the search path on Linux with the exception that
the application's bundle resources are searched first:
`(bundle)/Contents/Resources/`.

#### Example macOS Driver Search Path

For a fictional user "Me" the Driver Manifest search path might look
like the following:

```
  <bundle>/Contents/Resources/vulkan/icd.d
  /Users/Me/.config/vulkan/icd.d
  /etc/xdg/vulkan/icd.d
  /usr/local/etc/vulkan/icd.d
  /etc/vulkan/icd.d
  /Users/Me/.local/share/vulkan/icd.d
  /usr/local/share/vulkan/icd.d
  /usr/share/vulkan/icd.d
```


#### Additional Settings For Driver Debugging

Sometimes, the driver may encounter issues when loading.
A useful option may be to enable the `LD_BIND_NOW` environment variable
to debug the issue.
This forces every dynamic library's symbols to be fully resolved on load.
If there is a problem with a driver missing symbols on the current system, this
will expose it and cause the Vulkan loader to fail on loading the driver.
It is recommended that `LD_BIND_NOW` along with `VK_LOADER_DEBUG=error,warn`
to expose any issues.


### Using Pre-Production ICDs or Software Drivers

Both software and pre-production ICDs can use an alternative mechanism to
detect their drivers.
Independent Hardware Vendor (IHV) may not want to fully install a pre-production
ICD and so it can't be found in the standard location.
For example, a pre-production ICD may simply be a shared library in the
developer's build tree.
In this case, there should be a way to allow developers to point to such an
ICD without modifying the system-installed ICD(s) on their system.

This need is met with the use of the `VK_DRIVER_FILES` environment variable,
which will override the mechanism used for finding system-installed
drivers.

In other words, only the drivers listed in `VK_DRIVER_FILES` will be
used.

See
[Overriding the Default Driver Discovery](#overriding-the-default-driver-discovery)
for more information on this.


### Driver Discovery on Android

The Android loader lives in the system library folder.
The location cannot be changed.
The loader will load the driver via `hw_get_module` with the ID of "vulkan".
**Due to security policies in Android, none of this can be modified under**
**normal use.**


## Driver Manifest File Format

The following section discusses the details of the Driver Manifest JSON file format.
The JSON file itself does not have any requirements for naming.
The only requirement is that the extension suffix of the file is ".json".

Here is an example driver JSON Manifest file:

```json
{
   "file_format_version": "1.0.1",
   "ICD": {
      "library_path": "path to driver library",
      "api_version": "1.2.205",
      "library_arch" : "64",
      "is_portability_driver": false
   }
}
```

<table style="width:100%">
  <tr>
    <th>Field Name</th>
    <th>Field Value</th>
  </tr>
  <tr>
    <td>"file_format_version"</td>
    <td>The JSON format major.minor.patch version number of this file.<br/>
        Supported versions are: 1.0.0 and 1.0.1.</td>
  </tr>
  <tr>
    <td>"ICD"</td>
    <td>The identifier used to group all driver information together.
        <br/>
        <b>NOTE:</b> Even though this is labelled <i>ICD</i> it is historical
        and just as accurate to use for other drivers.</td>
  </tr>
  <tr>
    <td>"library_path"</td>
    <td>The "library_path" specifies either a filename, a relative pathname, or
        a full pathname to a driver shared library file. <br />
        If "library_path" specifies a relative pathname, it is relative to the
        path of the JSON manifest file. <br />
        If "library_path" specifies a filename, the library must live in the
        system's shared object search path. <br />
        There are no rules about the name of the driver's shared library file
        other than it should end with the appropriate suffix (".DLL" on
        Windows, ".so" on Linux and ".dylib" on macOS).</td>
  </tr>
  <tr>
    <td>"library_arch"</td>
    <td>Optional field which specifies the architecture of the binary associated
        with "library_path". <br />
        Allows the loader to quickly determine if the architecture of the driver
        matches that of the running application. <br />
        The only valid values are "32" and "64".</td>
  </tr>
  <tr>
    <td>"api_version" </td>
    <td>The major.minor.patch version number of the maximum Vulkan API supported
        by the driver.
        However, just because the driver supports the specific Vulkan API version,
        it does not guarantee that the hardware on a user's system can support
        that version.
        Information on what the underlying physical device can support must be
        queried by the user using the <i>vkGetPhysicalDeviceProperties</i> API call.
        <br/>
        For example: 1.0.33.</td>
  </tr>
  <tr>
    <td>"is_portability_driver" </td>
    <td>Defines whether the driver contains any VkPhysicalDevices which implement
        the VK_KHR_portability_subset extension.<br/>
    </td>
  </tr>
</table>

**NOTE:** If the same driver shared library supports multiple, incompatible
versions of text manifest file format versions, it must have separate JSON files
for each (all of which may point to the same shared library).

### Driver Manifest File Versions

The current highest supported Layer Manifest file format supported is 1.0.1.
Information about each version is detailed in the following sub-sections:

#### Driver Manifest File Version 1.0.0

The initial version of the Driver Manifest file specified the basic
format and fields of a layer JSON file.
The fields supported in version 1.0.0 of the file format include:
 * "file\_format\_version"
 * "ICD"
 * "library\_path"
 * "api\_version"

#### Driver Manifest File Version 1.0.1

Added the `is_portability_driver` boolean field for drivers to self report that
they contain VkPhysicalDevices which support the VK_KHR_portability_subset
extension. This is an optional field. Omitting the field has the same effect as
setting the field to `false`.

Added the "library\_arch" field to the driver manifest to allow the loader to
quickly determine if the driver matches the architecture of the current running
application. This field is optional.

##  Driver Vulkan Entry Point Discovery

The Vulkan symbols exported by a driver must not clash with the loader's
exported Vulkan symbols.
Therefore, `vk_icdGetInstanceProcAddr` was introduced to allow the loader
to perform the the same behavior as `vkGetInstanceProcAddr` but on a driver
basis.
As such, it behaves the same as `vkGetInstanceProcAddr`.
All drivers must export this function which is used for discovery of driver
Vulkan entry-points.
This entry-point is not a part of the Vulkan API itself, only a private
interface between the loader and drivers for version 1 and higher
interfaces.

```cpp
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
   vk_icdGetInstanceProcAddr(
      VkInstance instance,
      const char* pName);
```

The driver must support querying global-level entry points by calling
`vk_icdGetInstanceProcAddr` with a NULL `VkInstance` parameter.
Global-level functions are those which contain no dispatchable object as the
first parameter, such as `vkCreateInstance` and
`vkEnumerateInstanceExtensionProperties`.
Instance-level functions are those that have either `VkInstance`, or
`VkPhysicalDevice` as the first parameter dispatchable object.
Both core entry points and any instance extension entry points the
driver supports should be available via `vk_icdGetInstanceProcAddr`.
Future Vulkan instance extensions may define and use new instance-level
dispatchable objects other than `VkInstance` and `VkPhysicalDevice`, in which
case extension entry points using these newly defined dispatchable objects must
be queryable via `vk_icdGetInstanceProcAddr`.

All other Vulkan entry points must either:
 * NOT be exported directly from the driver library
 * or NOT use the official Vulkan function names if they are exported

This requirement is for driver libraries that include other functionality (such
as OpenGL) and thus could be loaded by the application prior to when the Vulkan
loader library is loaded by the application.

Beware of interposing by dynamic OS library loaders if the official Vulkan
names are used.
On Linux, if official names are used, the driver library must be linked with
`-Bsymbolic`.


## Driver API Version

When an application calls `vkCreateInstance`, it can optionally include a
`VkApplicationInfo` struct, which includes an `apiVersion` field.
A Vulkan 1.0 driver was required to return `VK_ERROR_INCOMPATIBLE_DRIVER` if it
did not support the API version that the user passed.
Beginning with Vulkan 1.1, drivers are not allowed to return this error
for any value of `apiVersion`.
This creates a problem when working with multiple drivers, where one is
a 1.0 driver and another is newer.

A loader that is newer than 1.0 will always give the version it supports when
the application calls `vkEnumerateInstanceVersion`, regardless of the API
version supported by the drivers on the system.
This means that when the application calls `vkCreateInstance`, the loader will
be forced to pass a copy of the `VkApplicationInfo` struct where `apiVersion` is
1.0 to any 1.0 drivers in order to prevent an error.
To determine if this must be done, the loader will perform the following steps:

1. Check the driver's JSON manifest file for the "api_version" field.
2. If the JSON version is greater than or equal to 1.1, Load the driver's
dynamic library
3. Call the driver's `vkGetInstanceProcAddr` command to get a pointer to
`vkEnumerateInstanceVersion`
4. If the pointer to `vkEnumerateInstanceVersion` is not `NULL`, it will be
called to get the driver's supported API version

The driver will be treated as a 1.0 driver if any of the following conditions
are met:

- The JSON manifest's "api_version" field is less that version 1.1
- The function pointer to `vkEnumerateInstanceVersion` is `NULL`
- The version returned by `vkEnumerateInstanceVersion` is less than 1.1
- `vkEnumerateInstanceVersion` returns anything other than `VK_SUCCESS`

If the driver only supports Vulkan 1.0, the loader will ensure that any
`VkApplicationInfo` struct that is passed to the driver will have an
`apiVersion` field set to Vulkan 1.0.
Otherwise, the loader will pass the struct to the driver without any
changes.


## Mixed Driver Instance Extension Support

On a system with more than one driver, a special case can arise.
Some drivers may expose an instance extension that the loader is already
aware of.
Other drivers on that same system may not support the same instance
extension.

In that scenario, the loader has some additional responsibilities:


### Filtering Out Instance Extension Names

During a call to `vkCreateInstance`, the list of requested instance extensions
is passed down to each driver.
Since the driver may not support one or more of these instance extensions, the
loader will filter out any instance extensions that are not supported by the
driver.
This is done per driver since different drivers may support different instance
extensions.


### Loader Instance Extension Emulation Support

In the same scenario, the loader must emulate the instance extension
entry-points, to the best of its ability, for each driver that does not support
an instance extension directly.
This must work correctly when combined with calling into the other
drivers which do support the extension natively.
In this fashion, the application will be unaware of what drivers are
missing support for this extension.


## Driver Unknown Physical Device Extensions

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
   vk_icdGetPhysicalDeviceProcAddr(
      VkInstance instance,
      const char* pName);
```

This function behaves similar to `vkGetInstanceProcAddr` and
`vkGetDeviceProcAddr` except it should only return values for physical device
extension entry points.
In this way, it compares "pName" to every physical device function supported in
the driver.

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
  implementation of that entrypoint.
* If `pName` is the name of a Vulkan API entrypoint that takes something other than
  a `VkPhysicalDevice` as its primary dispatch handle, then the driver **must**
  return `NULL`.
* If the driver is unaware of any entrypoint with the name `pName`, it **must**
  return `NULL`.

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 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
 2. Check if known instance or device extension function:
    - If it is, return the function pointer
 3. Call the layer/driver `GetPhysicalDeviceProcAddr`
    - If it returns `non-NULL`, return a trampoline to a generic physical device
function, and set up a generic terminator which will pass it to the proper
driver.
 4. Call down using `GetInstanceProcAddr`
    - If it returns non-NULL, treat it as an unknown logical device command.
This means 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`.
Then, return the pointer to the corresponding trampoline function.
 5. Return `NULL`

The result is that if the command gets promoted to Vulkan core later, it will no
longer be set up using `vk_icdGetPhysicalDeviceProcAddr`.
Additionally, if the loader adds direct support for the extension, it will no
longer get to step 3, because step 2 will return a valid function pointer.
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

When an application selects a GPU to use, it must enumerate physical devices or
physical device groups.
These API functions do not specify which order the physical devices or physical
device groups will be presented in.
On Windows, the loader will attempt to sort these objects so that the system
preference will be listed first.
This mechanism does not force an application to use any particular GPU &mdash;
it merely changes the order in which they are presented.

This mechanism requires that a driver provide version 6 of the loader/driver
interface.
Version 6 of this interface defines a new exported function that the driver may
provide on Windows:

```c
VKAPI_ATTR VkResult VKAPI_CALL
   vk_icdEnumerateAdapterPhysicalDevices(
      VkInstance instance,
      LUID adapterLUID,
      uint32_t* pPhysicalDeviceCount,
      VkPhysicalDevice* pPhysicalDevices);
```

This function takes an adapter LUID as input, and enumerates all Vulkan physical
devices that are associated with that LUID.
This works in the same way as other Vulkan enumerations &mdash; if
`pPhysicalDevices` is `NULL`, then the count will be provided.
Otherwise, the physical devices associated with the queried adapter will be
provided.
The function must provide multiple physical devices when the LUID refers to a
linked adapter.
This allows the loader to translate the adapter into Vulkan physical device
groups.

While the loader attempts to match the system's preference for GPU ordering,
there are some limitations.
Because this feature requires a new driver interface, only physical devices from
drivers that support this function will be sorted.
All unsorted physical devices will be listed at the end of the list, in an
indeterminate order.
Furthermore, only physical devices that correspond to an adapter may be sorted.
This means that a software driver would likely not be sorted.
Finally, this API only applies to Windows systems and will only work on versions
of Windows 10 that support GPU selection through the OS.
Other platforms may be included in the future, but they will require separate
platform-specific interfaces.


## Driver Dispatchable Object Creation

As previously covered, the loader requires dispatch tables to be accessible
within Vulkan dispatchable objects, such as: `VkInstance`, `VkPhysicalDevice`,
`VkDevice`, `VkQueue`, and `VkCommandBuffer`.
The specific requirements on all dispatchable objects created by drivers
are as follows:

- All dispatchable objects created by a driver can be cast to void \*\*
- The loader will replace the first entry with a pointer to the dispatch table
which is owned by the loader.
This implies three things for drivers:
  1. The driver must return a pointer for the opaque dispatchable object handle
  2. This pointer points to a regular C structure with the first entry being a
   pointer.
   * **NOTE:** For any C\++ drivers that implement VK objects directly
as C\++ classes:
     * The C\++ compiler may put a vtable at offset zero if the class is
non-POD due to the use of a virtual function.
     * In this case use a regular C structure (see below).
  3. The loader checks for a magic value (ICD\_LOADER\_MAGIC) in all the created
   dispatchable objects, as follows (see `include/vulkan/vk_icd.h`):

```cpp
#include "vk_icd.h"

union _VK_LOADER_DATA {
  uintptr loadermagic;
  void *  loaderData;
} VK_LOADER_DATA;

vkObj
   alloc_icd_obj()
{
  vkObj *newObj = alloc_obj();
  ...
  // Initialize pointer to loader's dispatch table with ICD_LOADER_MAGIC

  set_loader_magic_value(newObj);
  ...
  return newObj;
}
```


## Handling KHR Surface Objects in WSI Extensions

Normally, drivers handle object creation and destruction for various Vulkan
objects.
The WSI surface extensions for Linux, Windows, macOS, and QNX
("VK\_KHR\_win32\_surface", "VK\_KHR\_xcb\_surface", "VK\_KHR\_xlib\_surface",
"VK\_KHR\_wayland\_surface", "VK\_MVK\_macos\_surface",
"VK\_QNX\_screen\_surface" and "VK\_KHR\_surface") are handled differently.
For these extensions, the `VkSurfaceKHR` object creation and destruction may be
handled by either the loader or a driver.

If the loader handles the management of the `VkSurfaceKHR` objects:
 1. The loader will handle the calls to `vkCreateXXXSurfaceKHR` and
`vkDestroySurfaceKHR`
    functions without involving the drivers.
    * Where XXX stands for the Windowing System name:
      * Wayland
      * XCB
      * Xlib
      * Windows
      * Android
      * MacOS (`vkCreateMacOSSurfaceMVK`)
      * QNX (`vkCreateScreenSurfaceQNX`)
 2. The loader creates a `VkIcdSurfaceXXX` object for the corresponding
`vkCreateXXXSurfaceKHR` call.
    * The `VkIcdSurfaceXXX` structures are defined in `include/vulkan/vk_icd.h`.
 3. Drivers can cast any `VkSurfaceKHR` object to a pointer to the
appropriate `VkIcdSurfaceXXX` structure.
 4. The first field of all the `VkIcdSurfaceXXX` structures is a
`VkIcdSurfaceBase` enumerant that indicates whether the
    surface object is Win32, XCB, Xlib, Wayland, or Screen.

The driver may choose to handle `VkSurfaceKHR` object creation instead.
If a driver desires to handle creating and destroying it must do the following:
 1. Support version 3 or newer of the loader/driver interface.
 2. Export and handle all functions that take in a `VkSurfaceKHR` object,
including:
     * `vkCreateXXXSurfaceKHR`
     * `vkGetPhysicalDeviceSurfaceSupportKHR`
     * `vkGetPhysicalDeviceSurfaceCapabilitiesKHR`
     * `vkGetPhysicalDeviceSurfaceFormatsKHR`
     * `vkGetPhysicalDeviceSurfacePresentModesKHR`
     * `vkCreateSwapchainKHR`
     * `vkDestroySurfaceKHR`

Because the `VkSurfaceKHR` object is an instance-level object, one object can be
associated with multiple drivers.
Therefore, when the loader receives the `vkCreateXXXSurfaceKHR` call, it still
creates an internal `VkSurfaceIcdXXX` object.
This object acts as a container for each driver's version of the
`VkSurfaceKHR` object.
If a driver does not support the creation of its own `VkSurfaceKHR` object, the
loader's container stores a NULL for that driver.
On the other hand, if the driver does support `VkSurfaceKHR` creation, the
loader will make the appropriate `vkCreateXXXSurfaceKHR` call to the
driver, and store the returned pointer in its container object.
The loader then returns the `VkSurfaceIcdXXX` as a `VkSurfaceKHR` object back up
the call chain.
Finally, when the loader receives the `vkDestroySurfaceKHR` call, it
subsequently calls `vkDestroySurfaceKHR` for each driver whose internal
`VkSurfaceKHR` object is not NULL.
Then the loader destroys the container object before returning.


## Loader and Driver Interface Negotiation

Generally, for functions issued by an application, the loader can be viewed as a
pass through.
That is, the loader generally doesn't modify the functions or their parameters,
but simply calls the driver's entry point for that function.
There are specific additional interface requirements a driver needs to comply
with that are not part of any requirements from the Vulkan specification.
These additional requirements are versioned to allow flexibility in the future.


### Windows, Linux and macOS Driver Negotiation


#### Version Negotiation Between Loader and Drivers

All drivers (supporting interface version 2 or higher) must export the
following function that is used for determination of the interface version that
will be used.
This entry point is not a part of the Vulkan API itself, only a private
interface between the loader and drivers.

```cpp
VKAPI_ATTR VkResult VKAPI_CALL
   vk_icdNegotiateLoaderICDInterfaceVersion(
      uint32_t* pSupportedVersion);
```

This function allows the loader and driver to agree on an interface version to
use.
The "pSupportedVersion" parameter is both an input and output parameter.
"pSupportedVersion" is filled in by the loader with the desired latest interface
version supported by the loader (typically the latest).
The driver receives this and returns back the version it desires in the same
field.
Because it is setting up the interface version between the loader and
driver, this should be the first call made by a loader to the driver (even prior
to any calls to `vk_icdGetInstanceProcAddr`).

If the driver receiving the call no longer supports the interface version
provided by the loader (due to deprecation), then it should report a
`VK_ERROR_INCOMPATIBLE_DRIVER` error.
Otherwise it sets the value pointed by "pSupportedVersion" to the latest
interface version supported by both the driver and the loader and returns
`VK_SUCCESS`.

The driver should report `VK_SUCCESS` in case the loader-provided interface
version is newer than that supported by the driver, as it's the loader's
responsibility to determine whether it can support the older interface version
supported by the driver.
The driver should also report `VK_SUCCESS` in the case its interface version is
greater than the loader's, but return the loader's version.
Thus, upon return of `VK_SUCCESS` the "pSupportedVersion" will contain the
desired interface version to be used by the driver.

If the loader receives an interface version from the driver that the loader no
longer supports (due to deprecation), or it receives a
`VK_ERROR_INCOMPATIBLE_DRIVER` error instead of `VK_SUCCESS`, then the loader
will treat the driver as incompatible and will not load it for use.
In this case, the application will not see the driver's `vkPhysicalDevice`
during enumeration.

#### Interfacing With Legacy Drivers or Loaders

If a loader sees that a driver does not export the
`vk_icdNegotiateLoaderICDInterfaceVersion` function, then the loader assumes the
corresponding driver only supports either interface version 0 or 1.

From the other side of the interface, if a driver sees a call to
`vk_icdGetInstanceProcAddr` before a call to
`vk_icdNegotiateLoaderICDInterfaceVersion`, then it knows that loader making the
calls is a legacy loader supporting version 0 or 1.
If the loader calls `vk_icdGetInstanceProcAddr` first, it supports at least
version 1.
Otherwise, the loader only supports version 0.

#### Loader Version 6 Interface Requirements

Version 6 provides a mechanism to allow the loader to sort physical devices.
The loader will only attempt to sort physical devices on a driver if version 6
of the interface is supported.
This version provides the `vk_icdEnumerateAdapterPhysicalDevices` function
defined earlier in this document.

#### Loader Version 5 Interface Requirements

Version 5 of the loader/driver interface has no changes to the actual interface.
If the loader requests interface version 5 or greater, it is simply
an indication to drivers that the loader is now evaluating whether the API
Version info passed into vkCreateInstance is a valid version for the loader.
If it is not, the loader will catch this during vkCreateInstance and fail with a
`VK_ERROR_INCOMPATIBLE_DRIVER` error.

On the other hand, if version 5 or newer is not requested by the loader, then it
indicates to the driver that the loader is ignorant of the API version being
requested.
Because of this, it falls on the driver to validate that the API Version is not
greater than major = 1 and minor = 0.
If it is, then the driver should automatically fail with a
`VK_ERROR_INCOMPATIBLE_DRIVER` error since the loader is a 1.0 loader, and is
unaware of the version.

Here is a table of the expected behaviors:

<table style="width:100%">
  <tr>
    <th>Loader Supports I/f Version</th>
    <th>Driver Supports I/f Version</th>
    <th>Result</th>
  </tr>
  <tr>
    <td>4 or Earlier</td>
    <td>Any Version</td>
    <td>Driver <b>must fail</b> with <b>VK_ERROR_INCOMPATIBLE_DRIVER</b>
        for all vkCreateInstance calls with apiVersion set to > Vulkan 1.0
        because the loader is still at interface version <= 4.<br/>
        Otherwise, the driver should behave as normal.
    </td>
  </tr>
  <tr>
    <td>5 or Newer</td>
    <td>4 or Earlier</td>
    <td>Loader <b>must fail</b> with <b>VK_ERROR_INCOMPATIBLE_DRIVER</b> if it
        can't handle the apiVersion.
        Driver may pass for all apiVersions, but since its interface is
        <= 4, it is best if it assumes it needs to do the work of rejecting
        anything > Vulkan 1.0 and fail with <b>VK_ERROR_INCOMPATIBLE_DRIVER</b>.
        <br/>
        Otherwise, the driver should behave as normal.
    </td>
  </tr>
  <tr>
    <td>5 or Newer</td>
    <td>5 or Newer</td>
    <td>Loader <b>must fail</b> with <b>VK_ERROR_INCOMPATIBLE_DRIVER</b> if it
        can't handle the apiVersion, and drivers should fail with
        <b>VK_ERROR_INCOMPATIBLE_DRIVER</b> <i>only if</i> they can not support
        the specified apiVersion. <br/>
        Otherwise, the driver should behave as normal.
    </td>
  </tr>
</table>

#### Loader Version 4 Interface Requirements

The major change to version 4 of the loader/driver interface is the
support of
[Unknown Physical Device Extensions](#driver-unknown-physical-device-extensions)
using the `vk_icdGetPhysicalDeviceProcAddr` function.
This function is purely optional.
However, if a driver supports a physical device extension, it must provide a
`vk_icdGetPhysicalDeviceProcAddr` function.
Otherwise, the loader will continue to treat any unknown functions as VkDevice
functions and cause invalid behavior.


#### Loader Version 3 Interface Requirements

The primary change that occurred in version 3 of the loader/driver interface was
to allow a driver to handle creation/destruction of their own KHR_surfaces.
Up until this point, the loader created a surface object that was used by all
drivers.
However, some drivers may want to provide their own surface handles.
If a driver chooses to enable this support, it must export support for version 3
of the loader/driver interface, as well as any Vulkan function that uses a
KHR_surface handle, such as:
- `vkCreateXXXSurfaceKHR` (where XXX is the platform-specific identifier [i.e.
`vkCreateWin32SurfaceKHR` for Windows])
- `vkDestroySurfaceKHR`
- `vkCreateSwapchainKHR`
- `vkGetPhysicalDeviceSurfaceSupportKHR`
- `vkGetPhysicalDeviceSurfaceCapabilitiesKHR`
- `vkGetPhysicalDeviceSurfaceFormatsKHR`
- `vkGetPhysicalDeviceSurfacePresentModesKHR`

A driver can still choose to not take advantage of this functionality
by simply not exposing the above `vkCreateXXXSurfaceKHR` and
`vkDestroySurfaceKHR` functions.


#### Loader Version 2 Interface Requirements

Version 2 interface is the first to implement the new
`vk_icdNegotiateLoaderICDInterfaceVersion` functionality, see
[Version Negotiation Between Loader and Drivers](#version-negotiation-between-loader-and-drivers) for more details
on that function.

Additional, version 2 was the first to define that Vulkan dispatchable objects
created by drivers must now be created in accordance to the
[Driver Dispatchable Object Creation](#driver-dispatchable-object-creation)
section.


#### Loader Version 1 Interface Requirements

Version 1 of the interface added the driver-specific entry-point
`vk_icdGetInstanceProcAddr`.
Since this is before the creation of the
`vk_icdNegotiateLoaderICDInterfaceVersion` entry-point, the loader has no
negotiation process for determine what interface version the driver
supports.
Because of this, the loader detects support for version 1 of the interface
by the absence of the negotiate function, but the presence of the
`vk_icdGetInstanceProcAddr`.
No other entry-points need to be exported by the driver as the loader will query
the appropriate function pointers using that.


#### Loader Version 0 Interface Requirements

Version 0 interface does not support either `vk_icdGetInstanceProcAddr` or
`vk_icdNegotiateLoaderICDInterfaceVersion`.
Because of this, the loader will assume the driver supports only version 0 of
the interface unless one of those functions exists.

Additionally, for version 0, the driver must expose at least the following core
Vulkan entry-points so the loader may build up the interface to the driver:

- The function `vkGetInstanceProcAddr` **must be exported** in the driver
library and returns valid function pointers for all the Vulkan API entry points.
- `vkCreateInstance` **must be exported** by the driver library.
- `vkEnumerateInstanceExtensionProperties` **must be exported** by the driver
library.


#### Additional Interface Notes:

- The loader will filter out extensions requested in `vkCreateInstance` and
`vkCreateDevice` before calling into the driver; filtering will be of extensions
advertised by entities (e.g. layers) different from the driver in question.
- The loader will not call the driver for `vkEnumerate*LayerProperties`
as layer properties are obtained from the layer libraries and layer JSON files.
- If a driver library author wants to implement a layer, it can do so by having
the appropriate layer JSON manifest file refer to the driver library file.
- The loader will not call the driver for `vkEnumerate*ExtensionProperties` if
"pLayerName" is not equal to `NULL`.
- Drivers creating new dispatchable objects via device extensions need
to initialize the created dispatchable object.
The loader has generic *trampoline* code for unknown device extensions.
This generic *trampoline* code doesn't initialize the dispatch table within the
newly created object.
See the
[Driver Dispatchable Object Creation](#driver-dispatchable-object-creation)
section for more information on how to initialize created dispatchable objects
for extensions non known by the loader.


### Android Driver Negotiation

The Android loader uses the same protocol for initializing the dispatch table as
described above.
The only difference is that the Android loader queries layer and extension
information directly from the respective libraries and does not use the JSON
manifest files used by the Windows, Linux and macOS loaders.


## Loader implementation of VK_KHR_portability_enumeration

The loader implements the `VK_KHR_portability_enumeration` instance extension,
which filters out any drivers that report support for the portability subset
device extension. Unless the application explicitly requests enumeration of
portability devices by setting the VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR
bit in the VkInstanceCreateInfo::flags, the loader does not load any drivers
that declare themselves to be portability drivers.

Drivers declare whether they are portability drivers or not in the Driver Manifest
Json file, with the `is_portability_driver` boolean field.
[More information here](#driver-manifest-file-version-101)

The initial support for this extension only reported errors when an application
did not enable the portability enumeration feature. It did not filter out
portability drivers. This was done to give a grace period for applications to
update their instance creation logic without outright breaking the application.

## Loader and Driver Policy

This section is intended to define proper behavior expected between the loader
and drivers.
Much of this section is additive to the Vulkan spec, and necessary for
maintaining consistency across platforms.
In fact, much of the language can be found throughout this document, but is
summarized here for convenience.
Additionally, there should be a way to identify bad or non-conformant behavior
in a driver and remedy it as soon as possible.
Therefore, a policy numbering system is provided to clearly identify each
policy statement in a unique way.

Finally, based on the goal of making the loader efficient and performant,
some of these policy statements defining proper driver behavior may not
be testable (and therefore aren't enforceable by the loader).
However, that should not detract from the requirement in order to provide the
best experience to end-users and developers.


### Number Format

Loader/Driver policy items start with the prefix `LDP_` (short for
Loader/Driver Policy) which is followed by an identifier based on what
component the policy is targeted against.
In this case there are only two possible components:
 - Drivers: which will have the string `DRIVER_` as part of the policy number.
 - The Loader: which will have the string `LOADER_` as part of the policy
   number.


### Android Differences

As stated before, the Android Loader is actually separate from the Khronos
Loader.
Because of this and other platform requirements, not all of these policy
statements apply to Android.
Each table also has a column titled "Applicable to Android?"
which indicates which policy statements apply to drivers that are focused
only on Android support.
Further information on the Android loader can be found in the
<a href="https://source.android.com/devices/graphics/implement-vulkan">
Android Vulkan documentation</a>.


### Requirements of Well-Behaved Drivers

<table style="width:100%">
  <tr>
    <th>Requirement Number</th>
    <th>Requirement Description</th>
    <th>Result of Non-Compliance</th>
    <th>Applicable to Android?</th>
    <th>Enforceable by Loader?</th>
    <th>Reference Section</th>
  </tr>
  <tr>
    <td><small><b>LDP_DRIVER_1</b></small></td>
    <td>A driver <b>must not</b> cause other drivers to fail, crash, or
        otherwise misbehave.
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>Yes</td>
    <td>No</td>
    <td><small>N/A</small></td>
  </tr>
  <tr>
    <td><small><b>LDP_DRIVER_2</b></small></td>
    <td>A driver <b>must not</b> crash if it detects that there are no supported
        Vulkan Physical Devices (<i>VkPhysicalDevice</i>) on the system when a
        call to that driver is made using any Vulkan instance of physical device
        API.<br/>
        This is because some devices can be hot-plugged.
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>Yes</td>
    <td>No<br/>
        The loader has no direct knowledge of what devices (virtual or physical)
        may be supported by a given driver.</td>
    <td><small>N/A</small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_DRIVER_3</b></small></td>
    <td>A driver <b>must</b> be able to negotiate a supported version of the
        loader/driver interface with the loader in accordance with the stated
        negotiation process.
    </td>
    <td>The driver will not be loaded.</td>
    <td>No</td>
    <td>Yes</td>
    <td><small>
        <a href="#loader-and-driver-interface-negotiation">
        Interface Negotiation</a></small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_DRIVER_4</b></small></td>
    <td>A driver <b>must</b> have a valid JSON manifest file for the loader to
        process that ends with the ".json" suffix.
    </td>
    <td>The driver will not be loaded.</td>
    <td>No</td>
    <td>Yes</td>
    <td><small>
        <a href="#driver-manifest-file-format">Manifest File Format</a>
        </small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_DRIVER_5</b></small></td>
    <td>A driver <b>must</b> pass conformance with the results submitted,
        verified, and approved by Khronos before reporting a conformance version
        through any mechanism provided by Vulkan (examples include inside the
        <i>VkPhysicalDeviceVulkan12Properties</i> and the
        <i>VkPhysicalDeviceDriverProperties</i> structs).<br/>
        Otherwise, when such a structure containing a conformance version is
        encountered, the driver <b>must</b> return a conformance version
        of 0.0.0.0 to indicate it hasn't been so verified and approved.
    </td>
    <td>Yes</td>
    <td>No</td>
    <td>The loader and/or the application may make assumptions about the
        capabilities of the driver resulting in undefined behavior
        possibly including crashes or corruption.
    </td>
    <td><small>
        <a href="https://github.com/KhronosGroup/VK-GL-CTS/blob/master/external/openglcts/README.md">
        Vulkan CTS Documentation</a>
        </small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_DRIVER_6</b></small></td>
    <td>Removed - See <a href="#removed-driver-policies">Removed Driver Policies</a>
    </td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
  </tr>
  <tr>
    <td><small><b>LDP_DRIVER_7</b></small></td>
    <td>If a driver desires to support Vulkan API 1.1 or newer, it <b>must</b>
        expose support of Vulkan loader/driver interface 5 or newer.
    </td>
    <td>The driver will be used when it shouldn't be and will cause
        undefined behavior possibly including crashes or corruption.
    </td>
    <td>No</td>
    <td>Yes</td>
    <td><small>
        <a href="#loader-version-5-interface-requirements">
        Version 5 Interface Requirements</a></small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_DRIVER_8</b></small></td>
    <td>If a driver wishes to handle its own <i>VkSurfaceKHR</i> object
        creation, it <b>must</b> implement loader/driver interface version 3 or
        newer and support querying all the relevant surface functions via
        <i>vk_icdGetInstanceProcAddr</i>.
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>No</td>
    <td>Yes</td>
    <td><small>
        <a href="#handling-khr-surface-objects-in-wsi-extensions">
        Handling KHR Surface Objects</a></small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_DRIVER_9</b></small></td>
    <td>If a driver negotiation results in it using loader/driver interface
        version 4 or earlier, the driver <b>must</b> verify that the Vulkan API
        version passed into <i>vkCreateInstance</i> (through
        <i>VkInstanceCreateInfo</i>’s <i>VkApplicationInfo</i>'s
        <i>apiVersion</i>) is supported.
        If the requested Vulkan API version can not be supported by the driver,
        it <b>must</b> return <b>VK_ERROR_INCOMPATIBLE_DRIVER</b>. <br/>
        This is not required if the interface version is 5 or newer because the
        responsibility for this check then falls on the loader.
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>No</td>
    <td>No</td>
    <td><small>
        <a href="#loader-version-5-interface-requirements">
        Version 5 Interface Requirements</a></small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_DRIVER_10</b></small></td>
    <td>If a driver negotiation results in it using loader/driver interface
        version 5 or newer, the driver <b>must</b> ignore the Vulkan API version
        passed into <i>vkCreateInstance</i> (through
        <i>VkInstanceCreateInfo</i>’s <i>VkApplicationInfo</i>'s
        <i>apiVersion</i>).
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>No</td>
    <td>No</td>
    <td><small>
        <a href="#loader-version-5-interface-requirements">
        Version 5 Interface Requirements</a></small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_DRIVER_11</b></small></td>
    <td>A driver <b>must</b> remove all Manifest files and references to those
        files (i.e. Registry entries on Windows) when uninstalling.
        <br/>
        Similarly, on updating the driver files, the old files <b>must</b> be
        all updated or removed.
    </td>
    <td>If an old file is left pointing to an incorrect library, it will
        result in undefined behavior which may include crashes or corruption.
    </td>
    <td>No</td>
    <td>No<br/>
        The loader has no idea what driver files are new, old, or incorrect.
        Any type of driver file verification would quickly become very complex
        since it would require the loader to maintain an internal database
        tracking badly behaving drivers based on the driver vendor, driver
        version, targeted platform(s), and possibly other criteria.
    </td>
    <td><small>N/A</small></td>
  </tr>
  <tr>
    <td><small><b>LDP_DRIVER_12</b></small></td>
    <td>To work properly with the public Khronos Loader, a driver
        <b>must not</b> expose platform interface extensions without first
        publishing them with Khronos.<br/>
        Platforms under development may use modified versions of the Khronos
        Loader until the design because stable and/or public.
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>Yes (specifically for Android extensions)</td>
    <td>No</td>
    <td><small>N/A</small></td>
  </tr>
</table>

#### Removed Driver Policies

These policies were in the loader source at some point but later removed. They are documented here for reference.

<table>
  <tr>
    <th>Requirement Number</th>
    <th>Requirement Description</th>
    <th>Removal Reason</th>
  </tr>
  <tr>
    <td><small><b>LDP_DRIVER_6</b></small></td>
    <td>A driver supporting loader/driver interface version 1 or newer <b>must
        not</b> directly export standard Vulkan entry-points.
        <br/>
        Instead, it <b>must</b> export only the loader interface functions
        required by the interface versions it does support (for example
        <i>vk_icdGetInstanceProcAddr</i>). <br/>
        This is because the dynamic linking on some platforms has been
        problematic in the past and incorrectly links to exported functions from
        the wrong dynamic library at times. <br/>
        <b>NOTE:</b> This is actually true for all exports.
        When in doubt, don't export any items from a driver that could cause
        conflicts in other libraries.<br/>
    </td>
    <td>
        This policy has been removed due to there being valid circumstances for
        drivers to export core entrypoints.
        Additionally, it was not found that dynamic linking would cause many
        issues in practice.
    </td>
  </tr>
</table>

### Requirements of a Well-Behaved Loader

<table style="width:100%">
  <tr>
    <th>Requirement Number</th>
    <th>Requirement Description</th>
    <th>Result of Non-Compliance</th>
    <th>Applicable to Android?</th>
    <th>Reference Section</th>
  </tr>
  <tr>
    <td><small><b>LDP_LOADER_1</b></small></td>
    <td>A loader <b>must</b> return <b>VK_ERROR_INCOMPATIBLE_DRIVER</b> if it
        fails to find and load a valid Vulkan driver on the system.
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>Yes</td>
    <td><small>N/A</small></td>
  </tr>
  <tr>
    <td><small><b>LDP_LOADER_2</b></small></td>
    <td>A loader <b>must</b> attempt to load any driver's Manifest file it
        discovers and determines is formatted in accordance with this document.
        <br/>
        The <b>only</b> exception is on platforms which determines driver
        location and functionality through some other mechanism.
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>Yes</td>
    <td><small>
        <a href="#driver-discovery">Driver Discovery</a></small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_LOADER_3</b></small></td>
    <td>A loader <b>must</b> support a mechanism to load driver in one or more
        non-standard locations.<br/>
        This is to allow support for fully software drivers as well as
        evaluating in-development ICDs. <br/>
        The <b>only</b> exception to this rule is if the OS does not wish to
        support this due to security policies.
    </td>
    <td>It will be more difficult to use a Vulkan loader by certain
        tools and driver developers.</td>
    <td>No</td>
    <td><small>
        <a href="#using-pre-production-icds-or-software-drivers">
        Pre-Production ICDs or SW</a></small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_LOADER_4</b></small></td>
    <td>A loader <b>must not</b> load a Vulkan driver which defines an API
        version that is incompatible with itself.
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>Yes</td>
    <td><small>
        <a href="#driver-discovery">Driver Discovery</a></small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_LOADER_5</b></small></td>
    <td>A loader <b>must</b> ignore any driver for which a compatible
        loader/driver interface version can not be negotiated.
    </td>
    <td>The loader would load a driver improperly resulting in undefined
        behavior possibly including crashes or corruption.
    </td>
    <td>No</td>
    <td><small>
        <a href="#loader-and-driver-interface-negotiation">
        Interface Negotiation</a></small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_LOADER_6</b></small></td>
    <td>If a driver negotiation results in it using loader/driver interface
        version 5 or newer, a loader <b>must</b> verify that the Vulkan API
        version passed into <i>vkCreateInstance</i> (through
        <i>VkInstanceCreateInfo</i>’s <i>VkApplicationInfo</i>'s
        <i>apiVersion</i>) is supported by at least one driver.
        If the requested Vulkan API version can not be supported by any
        driver, the loader <b>must</b> return
        <b>VK_ERROR_INCOMPATIBLE_DRIVER</b>.<br/>
        This is not required if the interface version is 4 or earlier because
        the responsibility for this check then falls on the drivers.
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>No</td>
    <td><small>
        <a href="#loader-version-5-interface-requirements">
        Version 5 Interface Requirements</a></small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_LOADER_7</b></small></td>
    <td>If there exist more than one driver on a system, and some of those
        drivers support <i>only</i> Vulkan API version 1.0 while other drivers
        support a newer Vulkan API version, then a loader <b>must</b> adjust
        the <i>apiVersion</i> field of the <i>VkInstanceCreateInfo</i>’s
        <i>VkApplicationInfo</i> to version 1.0 for all the drivers that are
        only aware of Vulkan API version 1.0.<br/>
        Otherwise, the drivers that support Vulkan API version 1.0 will
        return <b>VK_ERROR_INCOMPATIBLE_DRIVER</b> during
        <i>vkCreateInstance</i> since 1.0 drivers were not aware of future
        versions.
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>No</td>
    <td><small>
        <a href="#driver-api-version">Driver API Version</a>
        </small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_LOADER_8</b></small></td>
    <td>If more than one driver is present, and at least one driver <i>does not
        support</i> instance-level functionality that other drivers support;
        then a loader <b>must</b> support the instance-level functionality in
        some fashion for the non-supporting drivers.
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>No</td>
    <td><small>
        <a href="#loader-instance-extension-emulation-support">
        Loader Instance Extension Emulation Support</a></small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_LOADER_9</b></small></td>
    <td>A loader <b>must</b> filter out instance extensions from the
        <i>VkInstanceCreateInfo</i> structure's <i>ppEnabledExtensionNames</i>
        field that the driver does not support during a call to the driver's
        <i>vkCreateInstance</i>.<br/>
        This is because the application has no way of knowing which
        drivers support which extensions.<br/>
        This ties in directly with <i>LDP_LOADER_8</i> above.
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>No</td>
    <td><small>
        <a href="#filtering-out-instance-extension-names">
        Filtering Out Instance Extension Names</a></small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_LOADER_10</b></small></td>
    <td>A loader <b>must</b> support creating <i>VkSurfaceKHR</i> handles
        that <b>may</b> be shared by all underlying drivers.
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>Yes</td>
    <td><small>
        <a href="#handling-khr-surface-objects-in-wsi-extensions">
        Handling KHR Surface Objects</a></small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_LOADER_11</b></small></td>
    <td>If a driver exposes the appropriate <i>VkSurfaceKHR</i>
        creation/handling entry-points, a loader <b>must</b> support creating
        the driver-specific surface object handle and provide it, and not the
        shared <i>VkSurfaceKHR</i> handle, back to that driver when requested.
        <br/>
        Otherwise, a loader <b>must</b> provide the loader created
        <i>VkSurfaceKHR</i> handle.
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>No</td>
    <td><small>
        <a href="#handling-khr-surface-objects-in-wsi-extensions">
        Handling KHR Surface Objects</a></small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_LOADER_12</b></small></td>
    <td>A loader <b>must not</b> call any <i>vkEnumerate*ExtensionProperties</i>
        entry-points in a driver if <i>pLayerName</i> is not <b>NULL</b>.
    </td>
    <td>The behavior is undefined and may result in crashes or corruption.</td>
    <td>Yes</td>
    <td><small>
        <a href="#additional-interface-notes">
        Additional Interface Notes</a></small>
    </td>
  </tr>
  <tr>
    <td><small><b>LDP_LOADER_13</b></small></td>
    <td>A loader <b>must</b> not load from user-defined paths (including the
        use of any of <i>VK_ICD_FILENAMES</i>, <i>VK_DRIVER_FILES</i>, or
        <i>VK_ADD_DRIVER_FILES</i> environment variables) when running elevated
        (Administrator/Super-user) applications.<br/>
        <b>This is for security reasons.</b>
    </td>
    <td>The behavior is undefined and may result in computer security lapses,
        crashes or corruption.
    </td>
    <td>No</td>
    <td><small>
        <a href="#exception-for-administrator-and-super-user-mode">
          Exception for Administrator and Super-User mode
        </a></small>
    </td>
  </tr>
</table>

<br/>

[Return to the top-level LoaderInterfaceArchitecture.md file.](LoaderInterfaceArchitecture.md)