File: api_layer.adoc

package info (click to toggle)
openxr-sdk-source 1.0.14~dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,564 kB
  • sloc: python: 16,103; cpp: 12,052; ansic: 8,813; xml: 3,480; sh: 410; makefile: 338; ruby: 247
file content (1020 lines) | stat: -rw-r--r-- 41,664 bytes parent folder | download
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
// Copyright (c) 2017-2021, The Khronos Group Inc.
//
// SPDX-License-Identifier: CC-BY-4.0

[[api-layer-interaction]]
== API Layer Interaction ==

This section details how the loader interacts with API layers.


[[api-layer-call-chains-and-distributed-dispatch]]
=== API Layer Call Chains and Distributed Dispatch ===

Remember, an API layer does not need to intercept all commands, instead, it
can choose to intercept only a subset.
Normally, when an API layer intercepts a given OpenXR command, it will call
down the <<openxr-call-chains,call chain>> as needed.
The loader and all enabled API layers that participate in a call chain
cooperate to ensure the correct sequencing of calls from one entity to the
next.
This group effort for call chain sequencing is hereinafter referred to as
*distributed dispatch*.

If an API layer does not wish to intercept a command, it must forward the
request made to its `xrGetInstanceProcAddr` implementation (provided through
pname:getInstanceProcAddr) down to the next `xrGetInstanceProcAddr`
implementation in the call chain (provided to the API layer through
pname:nextGetInstanceProcAddr).

In distributed dispatch each API layer is responsible for properly calling
the next entity in the call chain.
This means that a dispatch mechanism is required for all OpenXR commands
that an API layer intercepts.

For example, if the enabled API layers intercepted only certain functions,
the call chain would look as follows:

image::images/optional_layer_function_impl.svg[align="center", title="Optional Function Example"]

[NOTE]
.Note
====
In the above example, notice that "API Layer A" fails to pass along the
information for "xrFunction6".
This may not be an error since some commands expect to only work with one
specific API layer (`xrEnumerateInstanceExtensionProperties` when
"layerName" is set).
However, a badly designed API layer could do something similar for other
commands.
====

The loader is responsible for dispatching all core and instance extension
OpenXR functions to the first entity in the call chain.


[[api-layer-discovery]]
=== API Layer Discovery ===

As mentioned in the <<implicit-vs-explicit-api-layers, Implicit vs Explicit
API Layers>> section, API layers can be categorized into two categories:

* Implicit API layers
* Explicit API layers

The main difference between the two is that implicit API layers are
automatically enabled, unless overridden, and explicit API layers must be
manually enabled.

On any system, the loader looks in specific areas for information on the API
layers that it can load.
The process of finding the available API layers on a system is known as "API
Layer Discovery".
During "API Layer Discovery", the loader determines what API layers are
available and then grabs some basic information about each API layer: the
name, the version, and any extensions it supports.
This information is then provided back to the application through the
`xrEnumerateApiLayerProperties` command.

This section specifies the minimal conventions and rules an API layer must
follow, especially with regards to interacting with the loader and other API
layers.

On Windows and Linux systems, JSON formatted manifest files are used to
store API layer information.
In order to find OpenXR API layers, the OpenXR loader will read the JSON
files to identify the names and attributes of API layers and their
extensions.

[[desktop-api-layer-discovery]]
==== Desktop API Layer Discovery ====

On Desktop systems (such as Windows and Linux) JSON formatted manifest files
are used to store OpenXR component information.
The OpenXR loader will search specific areas of the computer for the
corresponding JSON manifest files that are used to identify the names and
attributes of OpenXR API layers.
The use of manifest files allows the loader to avoid actively loading the
shared library files until the application request causes them to be
activated.

The following sections define the standard locations the OpenXR loader
searches when looking for JSON manifest files.

[[windows-manifest-registry-usage]]
===== Windows Manifest Registry Usage =====

On Windows, the OpenXR loader will scan the Windows registry for details on
JSON manifest files in the following locations:

[NOTE]
.Note
====
The following table uses 2 acronyms:

* <HKLM> is used to indicate the top key of "HKEY_LOCAL_MACHINE"
* <HKCU> is used to indicate the top key of "HKEY_CURRENT_USER"

This is done purely to simplify the reading of the table
====

.Typical Windows Manifest File Registry Keys

[options="header",cols="10,10,30,50%"]
|====
| Windows OS Target | Binary Target | Base Registry Key (see note above) | Common Uses
.2+| 32-bit
    .2+| 32-bit
        l| <HKLM>\SOFTWARE\Khronos\OpenXR
            | Manifest files typically installed by some application for the
            entire system and all users on that system are found under this
            base key.
        l| <HKCU>\SOFTWARE\Khronos\OpenXR
            | Manifest files typically installed by some application for just
            the current user are found under this base key.
.2+| 64-bit
    .2+| 64-bit
        l| <HKLM>\SOFTWARE\Khronos\OpenXR
            | Manifest files for 64-bit OpenXR components are typically
            installed by some application for the entire system and all users
            on that system and recorded under this base key.
        l| <HKCU>\SOFTWARE\Khronos\OpenXR
            | Manifest files for 64-bit OpenXR components are typically
            installed by some application for just the current user
            and recorded under this base key.
.2+| 64-bit
    .2+| 32-bit
        l| <HKLM>\WOW6432Node\SOFTWARE\Khronos\OpenXR
            | Manifest files for 32-bit OpenXR components are typically
            installed by some application for the entire system and all users
            on that system and recorded under this base key.
        l| <HKCU>\WOW6432Node\SOFTWARE\Khronos\OpenXR
            | Manifest files for 32-bit OpenXR components are typically
            installed by some application for just the current user
            and recorded under this base key.
|====

When the OpenXR loader scans each of the appropriate registry keys based on
the Binary Target size, the loader will search under specific sub-keys for
the correct JSON manifest files based on the type of content stored in the
manifest file.

Additionally, the major version of the OpenXR API is used to separate up
each group of elements so that they don't conflict with one another in the
future.

Finally, each API layer type has their own sub-key under which their list of
available layers resides:

.Sub-Key Suffix for Manifest Search

[width="70%",options="header",cols="^.^40%e,^.^60%v"]
|====
| JSON Manifest File Type | Sub-key Suffix Added to Each Valid Key
| Implicit API Layer | ApiLayers\Implicit
| Explicit API Layer | ApiLayers\Explicit
|====

The following example shows possible keys searched for OpenXR 1.x explicit
API layers for a 64-bit loader on a 64-bit system.

[example]
.OpenXR 1.x Explicit Layer Windows' Registry Locations
====
----
HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenXR\1\ApiLayers\Explicit
HKEY_CURRENT_USER\SOFTWARE\Khronos\OpenXR\1\ApiLayers\Explicit
----
====

When searching for implicit API layers, the loader appends
`ApiLayers\Implicit` to each of the keys found.

Similar to the above example, this example shows the possible keys searched
for OpenXR 1.x implicit API layers for the same system as above.

[example]
.OpenXR 1.x Implicit Layer Windows' Registry Locations
====
----
HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenXR\1\ApiLayers\Implicit
HKEY_CURRENT_USER\SOFTWARE\Khronos\OpenXR\1\ApiLayers\Implicit
----
====

Each registry value under the above keys must: be defined in the following
way:

* The name of the value must: be the full path name to a valid manifest JSON
  file (including the ".json" suffix)
* The data for value must: be a DWORD
** In order for the loader to attempt to load the binary associated with
   this, the value must: be 0.
** To disable this manifest file so that the loader does not attempt to use
   it, set the value to a non-zero value.

For each value in these keys which has DWORD data set to 0, the loader opens
the manifest file specified by the name of the value.
The OpenXR loader will then obtain information about the library, including
the name and pathname of the shared library (".dll") file which defines the
actual API layer binary.

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

----
[HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenXR\1\ApiLayers\Explicit\]

"C:\vendor a\layer_a.json"=dword:00000000
"C:\windows\system32\layer_b.json"=dword:00000001
"C:\windows\system32\layer_c.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 API layer
manifest file.
In this case, the loader will open the first and last listings, but not the
middle one.
This is because the value of 1 for layer_b.json disables the layer from
being loaded.


[[linux-manifest-search-paths]]
===== Linux Manifest Search Paths =====

On Linux, the OpenXR loader will scan for JSON manifest files using the
following base folders:

.Typical Linux Manifest File Search Directories

[options="header",cols="20%e,20%v,60%"]
|====
| Environment Variable | Common Locations | Common Uses
| XDG_CONFIG_DIRS
    | /etc/xdg
        | Defines common paths for config files
| SYSCONFDIR
    | /usr/local/etc
        | The directory for installing read-only data files that pertain to
        a single machine.  In this case, it is commonly used to store locally
        built API layers.
| EXTRASYSCONFDIR
    | /etc
        | Location of API layers installed from non-Linux-distribution-provided
        packages.
| XDG_DATA_DIRS
    | /usr/local/share, /usr/share/
        | Location of API layers installed from Linux-distribution-provided
        packages.
| XDG_DATA_HOME
    | $HOME/.local/share
        | Used to define manually enabled API layers per user.  $HOME is the
        current home directory of the application's user id; this
        path will be ignored for suid programs
|====

[NOTE]
.Note
====
The "/usr/local/*" directories can: be configured to be other directories at
build time.
====

When the OpenXR loader scans the directories defined by each of the above
environmental variables, it pulls out each individual path (tokenizing the
value based on the colon (:) separator), and then appends additional
sub-path information on the end of each based on the type of manifest file
being searched for.
The following table shows the sub-path information added onto the end of
each path based on the JSON manifest file type:

.Sub-Folder Suffix for Manifest Search

[width="70%",options="header",cols="^.^40%e,^.^60%v"]
|====
| JSON Manifest File Type | Sub-Folder Suffix Added to Each Path
| Implicit Layer | openxr/<major_version>/api_layers/implicit.d
| Explicit Layer | openxr/<major_version>/api_layers/explicit.d
|====

Where <major_version> is the integer number for the OpenXR API's major
version the API layers are associated with.

The following example shows possible search paths for OpenXR 1.x explicit
API layers (depending on the environmental variables defined on a user's
system).

[example]
.OpenXR 1.x Linux Explicit Layer Search Paths
====
----
/usr/local/etc/openxr/1/api_layers/explicit.d
/usr/local/share/openxr/1/api_layers/explicit.d
/etc/openxr/1/api_layers/explicit.d
/usr/share/openxr/1/api_layers/explicit.d
$HOME/.local/share/openxr/1/api_layers/explicit.d
----
====

When searching for OpenXR 1.x implicit API layers, the loader appends
`openxr/1/api_layers/implicit.d` to each of the paths found.

Similar to the above example, the following shows the search paths for
OpenXR 1.x implicit API layers for the same system as above.

[example]
.OpenXR 1.x Linux Implicit Layer Search Paths
====
----
/usr/local/etc/openxr/1/api_layers/implicit.d
/usr/local/share/openxr/1/api_layers/implicit.d
/etc/openxr/1/api_layers/implicit.d
/usr/share/openxr/1/api_layers/implicit.d
$HOME/.local/share/openxr/1/api_layers/implicit.d
----
====


[[overriding-the-default-api-layer-paths]]
===== Overriding the Default API Layer Paths =====

There may be times that a developer wishes to force the loader to use their
own explicit API layers (or specific explicit API layers).
In order to support this, the desktop loader can be forced to look in
specific paths for explicit API layers with the `XR_API_LAYER_PATH`
environment variable.
Simply set it to a properly delimited list of paths that you want the loader
to search for explicit API layer JSON Manfiest files.
While relative paths may work, it is preferable to use absolute paths when
defining this environment variable to reduce issues.

[NOTE]
.Important
====
If the "XR_API_LAYER_PATH" environmental variable is defined, then the
desktop loader will not look in the standard locations to find explicit API
layers, instead looking only at the paths defined in that environment
variable.
Implicit API layers will always be discovered using the standard paths.
====

[example]
.Setting XR_API_LAYER_PATH Override
====
*Windows*

----
set XR_API_LAYER_PATH=<my_api_layer_path_1>;<my_api_layer_path_2>;<my_api_layer_path_3>
----

*Linux*

----
export XR_API_LAYER_PATH=<my_api_layer_path_1>:<my_api_layer_path_2>:<my_api_layer_path_3>
----
====


[[api-layer-manifest-file-format]]
===== API Layer Manifest File Format =====

On Windows and Linux, the desktop loader uses manifest files to discover API
layers.
The desktop loader doesn't load the API layer libraries (e.g. DLL or .so
files) for each of the enabled API layers except during `xrCreateInstance`
when it sets up the call chain.
This is to reduce the likelihood of loading a malicious API layer into
memory.
Instead, details are read from the manifest file, which are then provided
for applications to determine what API layers should actually be loaded.

The following section discusses the details of the API layer manifest JSON
file format.
The JSON file itself does not have any requirements for naming.
The only requirement is that the filename extension is ".json".

[example]
.API Layer Manifest Examples
====
*Simple Explicit API Layer Manifest File*

[source,json]
----
{
   "file_format_version" : "1.0.0",
   "api_layer": {
       "name": "XR_APILAYER_LUNARG_test",
       "library_path": "xrTestLayer.dll"
       "api_version" : "1.0",
       "implementation_version" : "2",
       "description" : "LunarG test API layer"
   }
}
----

*More Complex Implicit API Layer Manifest File*

[source,json]
----
{
   "file_format_version" : "1.0.0",
   "api_layer": {
       "name": "XR_APILAYER_LUNARG_test",
       "library_path": "xrTestLayer.dll"
       "api_version" : "1.0",
       "implementation_version" : "2",
       "description" : "LunarG test API layer",
       "functions": {
           "xrNegotiateLoaderApiLayerInterface":
               "TestLayer_xrNegotiateLoaderApiLayerInterface"
       },
       "instance_extensions": [
           {
               "name": "XR_EXT_instance_extension_example",
               "extension_version": "1"
           }
       ],
       "enable_environment": "ENABLE_XR_API_LAYER_TEST_1",
       "disable_environment": "DISABLE_XR_API_LAYER_TEST_1"
   }
}
----
====

.API Layer Manifest JSON Fields

[width="70%",options="header",cols="<.^20%,^.^10%,<.^60%,^.^10%"]
|====
| JSON Node | API Layer Type | Description and Notes | Introspection Query
| "file_format_version"
    | *Required* for Implicit / Explicit
        | Manifest format major.minor.patch version number.  Currently only a
        value of 1.0.0 is supported.
            | N/A
| "api_layer"
    | *Required* for Implicit / Explicit
        | The identifier used to group a single API layer's information together.
            | xrEnumerateApiLayerProperties
| "name"
    | *Required* for Implicit / Explicit
        | The string used to uniquely identify this API layer to applications.
            | xrEnumerateApiLayerProperties
| "library_path"
    | *Required* for Implicit / Explicit
        | The "library_path" specifies either a filename, a relative pathname,
        or a full pathname to the API layer's shared library file.  If
        "library_path" specifies a relative pathname, it is relative to the
        path of the JSON manifest file (e.g. for cases when an application
        provides an API layer that is in the same folder hierarchy as the rest of
        the application files).  If "library_path" specifies a filename, the
        library must live in the system's shared object search path. There
        are no rules about the name of the API layer shared library files other
        than it should end with the appropriate suffix (".DLL" on Windows,
        and ".so" on Linux).
        | N/A
| "api_version"
    | *Required* for Implicit / Explicit
        | The major.minor (but not patch) version number of the OpenXR API that the
        shared library file for the library was built against. For example:
        1.0.
            | xrEnumerateApiLayerProperties
| "implementation_version"
    | *Required* for Implicit / Explicit
        | The version of the API layer implemented.  If the API layer itself has any
        major changes, this number should change so the loader and/or
        application can identify it properly.
            | xrEnumerateApiLayerProperties
| "description"
    | *Required* for Implicit / Explicit
        | A high-level description of the API layer and it's intended use.
            | xrEnumerateApiLayerProperties
| "functions"
    | Optional for Implicit / Explicit
        | This section can be used to identify a different function name for
        the loader to use in place of standard API layer interface functions. The
        "functions" node is required if the API layer is using an alternative name
        for `xrNegotiateLoaderApiLayerInterface`.
            | xrGet*ProcAddr (except for `xrNegotiateLoaderApiLayerInterface`
            which must be queried using the OS/platform-specific
            GetProcAddress)s.
| "instance_extensions"
    | Optional for Implicit / Explicit
        | Contains the list of instance extension names supported by this
        API layer. One "instance_extensions" node with an array of one or more
        elements is required if any instance extensions are supported by a
        API layer, otherwise the node is optional. Each element of the array
        must have the nodes "name" and "extension_version" which correspond to
        `XrExtensionProperties` "extensionName" and "extensionVersion" respectively.
            | xrEnumerateInstanceExtensionProperties
| "enable_environment"
    | Optional for Implicit
        | Indicates an environment variable used to enable the implicit API layer.
        If provided in the JSON file, this environment variable (which should vary
		with each "version" of the API layer) must be set in the environment or else
        the implicit API layer is not loaded. This is for application environments
        (e.g. Steam) which want to enable an API layer(s) only for applications that
        they launch, and allows for applications run outside of that
        environment to not get that implicit API layer(s).
            | N/A
| "disable_environment"
    | *Required* for Implicit
        | Indicates an environment variable used to disable the implicit API layer.
        Required to allow users or applications to disable implicit layers that are
		not desired or that cause problems for the application. The user/application
		can set this environment variable (before calling OpenXR functions) to
		"blacklist" the API layer.
        This environment variable should vary with each "version" of the
        API layer.  If both the
        "enable_environment" and "disable_environment" variables are set, the
        implicit API layer is disabled.
            | N/A
|====

[NOTE]
.Note
====
If the same API layer 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).
====


[[api-layer-manifest-file-version-history]]
====== API Layer Manifest File Version History ======

The current highest supported API layer manifest file format supported is
1.0.0.
Information about each version is detailed in the following sub-sections:

_API Layer Manifest File Version 1.0.0_

The initial version of the API layer manifest file specified the basic
format and fields of an API layer JSON file.
The fields of the 1.0.0 file format include:

* "file_format_version"
* "api_layer"
* "name"
* "library_path"
* "api_version"
* "implementation_version"
* "description"
* "functions"
* "instance_extensions"
* "enable_environment"
* "disable_environment"


[[loader-api-layer-interface-negotiation]]
=== Loader/API Layer Interface Negotiation ===

Now that an API layer has been discovered, an application can choose to load
it (or it is loaded by default if it is an implicit API layer).
When the loader attempts to load the API layer, the first thing it does is
attempt to negotiate the version of the loader to API layer interface.
In order to negotiate the loader/API layer interface version, the API layer
must implement the fname:xrNegotiateLoaderApiLayerInterface function (or a
renamed version of this function identified in the manifest file).

[[xrNegotiateLoaderApiLayerInterface,xrNegotiateLoaderApiLayerInterface]]
[source,c++]
----
XrResult xrNegotiateLoaderApiLayerInterface(
            const XrNegotiateLoaderInfo *loaderInfo,
            const char *layerName,
            XrNegotiateApiLayerRequest *apiLayerRequest);
----
  * pname:loaderInfo must: be a valid pointer to a constant
    slink:XrNegotiateLoaderInfo structure.
  * pname:layerName must: be NULL or a valid C-style NULL-terminated string
    listing the name of an API layer which the loader is attempting to
    negotiate with.
  * pname:layerRequest must be a valid pointer to a
    slink:XrNegotiateApiLayerRequest structure.

This function should be directly exported by an API layer so that using
"GetProcAddress" on Windows or "dlsym" on Linux, should return a valid
function pointer to it.
If the function succeeds, the API layer must: return `XR_SUCCESS`.
If the function fails, the API layer must: return
`XR_ERROR_INITIALIZATION_FAILED`.
The entire <<loader-api-layer-negotiation-process, negotiation process>> is
defined in more detail below.

The sname:XrNegotiateLoaderInfo struct is defined in the
`src/common/loader_interfaces.h` header.
It is used to pass information about the loader to an API layer during the
negotiation process.

[[XrNegotiateLoaderInfo,XrNegotiateLoaderInfo]]
[source,c++]
----
struct XrNegotiateLoaderInfo {
    XrLoaderInterfaceStructs structType;
    uint32_t structVersion;
    size_t structSize;
    uint32_t minInterfaceVersion;
    uint32_t maxInterfaceVersion;
    XrVersion minApiVersion;
    XrVersion maxApiVersion;
};
----
  * pname:structType must: be a valid value of
    elink:XrLoaderInterfaceStructs.
    In this case, it must: specifically be
    `XR_LOADER_INTERFACE_STRUCT_LOADER_INFO`.
  * pname:structVersion must: be a valid version of the structure.
    The `loader_interfaces.h` header uses the value
    `XR_LOADER_INFO_STRUCT_VERSION` to describe the current latest version
    of this structure.
  * pname:structSize must: be the size in bytes of the current version of
    the structure (i.e. sizeof(XrNegotiateLoaderInfo)).
  * pname:minInterfaceVersion is the minimum
    <<api-layer-interface-versions,loader/API layer interface version>>
    supported by the loader.
  * pname:maxInterfaceVersion is the maximum valid version of the
    <<api-layer-interface-versions,loader/API layer interface version>>
    supported by the loader, currently defined using
    `XR_CURRENT_LOADER_API_LAYER_VERSION`.
  * pname:minApiVersion is the minimum supported version of the OpenXR API
    by this loader as formatted by `XR_MAKE_VERSION` defined in `openxr.h`.
    Patch is ignored.
  * pname:maxApiVersion is the maximum supported version of the OpenXR API
    by this loader as formatted by `XR_MAKE_VERSION` defined in `openxr.h`.
    Patch is ignored.

You'll notice the structures are similar to other OpenXR structures.
The "structType" field, in this case takes a new enum defined just for
internal loader interfacing use.

The ename:XrLoaderInterfaceStructs enumeration is also defined in the
`src/common/loader_interfaces.h` header and currently looks like:

[[XrLoaderInterfaceStructs,XrLoaderInterfaceStructs]]
[source,c++]
----
enum XrLoaderInterfaceStructs {
    XR_LOADER_INTERFACE_STRUCT_UNINTIALIZED = 0,
    XR_LOADER_INTERFACE_STRUCT_LOADER_INFO,
    XR_LOADER_INTERFACE_STRUCT_API_LAYER_REQUEST,
    XR_LOADER_INTERFACE_STRUCT_RUNTIME_REQUEST,
    XR_LOADER_INTERFACE_STRUCT_API_LAYER_CREATE_INFO,
    XR_LOADER_INTERFACE_STRUCT_API_LAYER_NEXT_INFO,
};
----

Just like standard OpenXR structs, the ename:XrLoaderInterfaceStructs enum
defines the set of valid structures and can grow in the future.

The sname:XrNegotiateApiLayerRequest can also be found in the
`src/common/loader_interfaces.h` header.
It is used to pass information about the API layer back to the loader during
the negotiation process.

[[XrNegotiateApiLayerRequest,XrNegotiateApiLayerRequest]]
[source,c++]
----
struct XrNegotiateApiLayerRequest {
    XrLoaderInterfaceStructs structType;
    uint32_t structVersion;
    size_t structSize;
    uint32_t layerInterfaceVersion;
    XrVersion layerApiVersion;
    PFN_xrGetInstanceProcAddr getInstanceProcAddr;
    PFN_xrCreateApiLayerInstance createApiLayerInstance;
};
----
  * pname:structType must: be a valid value of
    elink:XrLoaderInterfaceStructs.
    In this case, it must: specifically be
    `XR_LOADER_INTERFACE_STRUCT_API_LAYER_REQUEST`.
  * pname:structVersion must: be a valid version of the structure.
    The `loader_interfaces.h` header uses the value
    `XR_API_LAYER_INFO_STRUCT_VERSION` to describe the current latest
    version of this structure.
  * pname:structSize must: be the size in bytes of the current version of
    the structure (i.e. sizeof(XrNegotiateApiLayerRequest)).
  * pname:layerInterfaceVersion is the version of the
    <<api-layer-interface-versions,loader/API layer interface version>>
    being requested by the API layer.
    Should not be outside of the bounds of the
    sname:XrNegotiateLoaderInfo::`minInterfaceVersion` and
    sname:XrNegotiateLoaderInfo::`maxInterfaceVersion` values (inclusive).
  * pname:layerApiVersion is the version of the OpenXR API supported by this
    API layer as formatted by `XR_MAKE_VERSION` defined in `openxr.h`.
    Patch is ignored.
  * pname:getInstanceProcAddr is a pointer to the API layer's
    `xrGetInstanceProcAddr` command that will be used by the loader to
    complete a dispatch table to all valid OpenXR commands supported by the
    API layer.
  * pname:createLayerInstance is a pointer to the API layer's
    `xrCreateApiLayerInstance` command that will be used by the loader when
    a `xrCreateInstance` command is triggered and an API layer exists.
    This is used because API layers need additional information at
    `xrCreateInstance` time.

[[loader-api-layer-negotiation-process]]
==== Loader/API Layer Negotiation Process ====

Once the loader has obtained a valid address to the API layer's
flink:xrNegotiateLoaderApiLayerInterface function, the loader will create a
variable of type slink:XrNegotiateLoaderInfo and initialize it in the
following ways:

1. Set the structure "structType" to
   `XR_LOADER_INTERFACE_STRUCT_LOADER_INFO`
2. Set the structure "structVersion" to the current version,
   `XR_LOADER_INFO_STRUCT_VERSION`
3. Set the structure "structSize" to the current size of the
   `XrNegotiateLoaderInfo` structure
4. Set "minInterfaceVersion" to the minimum
   <<api-layer-interface-versions,loader/API layer interface version>> that
   the loader supports
5. Set "maxInterfaceVersion" to the current version of the
   <<api-layer-interface-versions,loader/API layer interface version>> at
   the time of loader compilation
6. Set "minApiVersion" to the minimum version of OpenXR supported by the
   loader
7. Set "maxApiVersion" to the maximum version of OpenXR supported by the
   loader (the current version at the time of loader compilation).

The loader also creates and initializes a variable of type
slink:XrNegotiateApiLayerRequest to allow the API layer to properly respond
to the request.
The structure will be initialized by the loader in the following way:

1. Set the structure "structType" to
   `XR_LOADER_INTERFACE_STRUCT_API_LAYER_REQUEST`
2. Set the structure "structVersion" to the current version,
   `XR_API_LAYER_INFO_STRUCT_VERSION`
3. Set the structure "structSize" to the current size of the
   `XrNegotiateApiLayerRequest` structure

The loader will leave the remaining fields uninitialized to allow each API
layer to fill in the appropriate information for itself.
The loader will then individually call each API layer's
flink:xrNegotiateLoaderApiLayerInterface function and each API layer then
must: :

* Determine if it can support the loader's request:
** Does the API layer support any <<api-layer-interface-versions, loader/API
  layer interface version>> between
  pname:loaderInfo->pname:minInterfaceVersion and
  pname:loaderInfo->pname:maxInterfaceVersion:
** *AND* does the API layer support any OpenXR API version between
  pname:loaderInfo->pname:minApiVersion and
  pname:loaderInfo->pname:maxApiVersion:
* If it is able to support the request, it must: return `XR_SUCCESS` and:
** Fill in pname:layerRequest->pname:layerInterfaceVersion with the API
   layer interface version it desires to support.
** Fill in pname:layerRequest->pname:layerApiVersion with the API version of
   OpenXR it will execute under.
** Fill in pname:layerRequest->pname:getInstanceProcAddr with a valid
   function pointer so that the loader can query function pointers to the
   remaining OpenXR commands supported by the API layer.
** Fill in pname:layerRequest->pname:createLayerInstance with a valid
   function pointer so that the loader can create the instance through the
   API layer call chain.
* Otherwise, it must: return `XR_ERROR_INITIALIZATION_FAILED`

[NOTE]
.Note
====
The API layer must: not call to another API layer while inside of the
`xrNegotiateLoaderApiLayerInterface` function.
The loader will handle all API layer negotiations with each API layer
individually.
====


[[api-layer-interface-versions]]
==== API Layer Interface Versions ====

The current API layer interface is at version 1.
The following sections detail the differences between the various versions.


[[api-layer-interface-version-1]]
===== API Layer Interface Version 1 =====

* Defined manifest file version 1.0.0.
* Introduced the concept of negotiation.
** Requires API layers to export `xrNegotiateLoaderApiLayerInterface`
   function.


[[api-layer-intercept-requirements]]
=== API Layer Intercept Requirements ===

* API Layers intercept an OpenXR command by defining a C/C++ function with
  signature *identical* to the OpenXR API for that command.
* The following commands are required: to be implemented by any API layer:
** `xrGetInstanceProcAddr`
** `xrCreateApiLayerInstance`
* The following commands must: not be implemented by any API layer:
** `xrCreateInstance`
* For any OpenXR command an API layer intercepts which has a non-void return
  value, an appropriate value must: be returned by the API layer intercept
  command.
* Most commands an API layer intercepts must: call down the chain to the
  corresponding OpenXR command in the next entity.
** The common behavior for an API layer is to intercept a call, perform some
   behavior, then pass it down to the next entity.
*** If a layer does not call down to the next entity for a given command,
    undefined behavior may occur.
    This is because the command will not be received by API layers and
    runtimes further down the call chain.
*** One command that cannot: call down the chain is:
**** `xrNegotiateLoaderApiLayerInterfaceVersion`
*** Some commands that may: choose to not call down the chain are:
**** `xrGetInstanceProcAddr`
* API layer intercept commands may: insert extra calls to OpenXR commands in
  addition to those that are intercepted
** If an API layer inserts new calls, that API layer must: pass along all
   new commands to the next entity.


[[api-layer-conventions-and-rules]]
=== API Layer Conventions and Rules ===

An API layer, when inserted into an otherwise compliant OpenXR
implementation, must still result in a compliant OpenXR implementation.
The intention is for API layers to have a well-defined baseline behavior.
Therefore, it must follow some conventions and rules defined below:

* An API layer may: be in a call chain with any number of API layers before
  or after it.
* It must: not make invalid calls to, or rely on undefined behaviors of, its
  lower API layers.
* If it changes the behavior of a function, it must: ensure the API layers
  called prior to itself do not make invalid calls because of the changed
  behavior.
** For example, if an API layer chooses to intercept an object creation
   function, and then wraps the objects created by lower API layers, it
   must: make sure the lower API layers never see the wrapped objects.
*** This means it must protect the lower API layers directly from itself or
    indirectly from its upper API layers.
* `xrEnumerateApiLayerProperties` must: return only its own API layer
  properties.
* `xrEnumerateInstanceExtensionProperties` must: obey the "layerName"
  parameter:
** If "layerName" is the name of this API layer, it must: return the
   contents of the instance extensions it supports.
** If "layerName" is NULL and:
*** It is an explicit API layer, it must: not fill in any data.
*** It is an implicit API layer, it must: add it's own instance extension
    contents to the list of extensions.
* For any OpenXR command the API layer intercepts, `xrGetInstanceProcAddr`
  must: return a pointer to a local entry-point.
** Otherwise it returns the value obtained by calling down the instance call
   chain.


[[api-layer-create-instance-process]]
=== API Layer Create Instance Process ===

After <<loader-api-layer-interface-negotiation, interface negotiation>> and
any directed `xrEnumerateInstanceExtensionProperties` calls, the next time
an API layer is invoked is during the loader's `xrCreateInstance` call.
The API layer is only involved if it is in the enabled API layer list (this
includes implicit, environment variable enabled, and application enabled API
layers).
An API layer needs additional information during `xrCreateInstance` calls,
so each API layer must implement the fname:xrCreateApiLayerInstance command,
which is a special API layer command.

[[xrCreateApiLayerInstance,xrCreateApiLayerInstance]]
[source,c++]
----
XrResult xrCreateApiLayerInstance(
    const XrInstanceCreateInfo *info,
    const struct XrApiLayerCreateInfo *layerInfo,
    XrInstance *instance);
----
  * pname:info is a pointer to the slink:XrInstanceCreateInfo information
    passed into the standard flink:xrCreateInstance command.
  * pname:layerInfo is a pointer to an slink:XrApiLayerCreateInfo structure
    that contains special information required by a API layer during its
    create instance process.
    This is generated by the loader.
  * pname:instance is a pointer to store the returned instance in, just as
    in the standard fname:xrCreateInstance command.

The sname:XrApiLayerCreateInfo structure is defined in
`src/common/loader_interfaces.h` and looks like:

[[XrApiLayerCreateInfo,XrApiLayerCreateInfo]]
[source,c++]
----
struct XrApiLayerCreateInfo {
    XrLoaderInterfaceStructs structType;
    uint32_t structVersion;
    size_t structSize;
    XrInstance loaderInstance;
    char settings_file_location[XR_API_LAYER_MAX_SETTINGS_PATH_SIZE];
    XrApiLayerNextInfo *nextInfo;
};
----
  * pname:structType is the type of structure, or
    XR_LOADER_INTERFACE_STRUCT_API_LAYER_CREATE_INFO in this case.
  * pname:structVersion is the version of the structure being supplied by
    the loader.
  * pname:structSize is the size of the structure supplied by the loader.
  * pname:loaderInstance is deprecated and must be ignored.
  * pname:settings_file_location is the location of any API layer settings
    file that can be used.
    This is currently unused.
  * pname:nextInfo is a pointer to the slink:XrApiLayerNextInfo structure
    which contains information to work with the next API layer in the chain.

The sname:XrApiLayerNextInfo structure is also defined in
`src/common/loader_interfaces.h` and looks like:

[[XrApiLayerNextInfo,XrApiLayerNextInfo]]
[source,c++]
----
struct XrApiLayerNextInfo {
    XrLoaderInterfaceStructs structType;
    uint32_t structVersion;
    size_t structSize;
    char layerName[XR_MAX_API_LAYER_NAME_SIZE];
    PFN_xrGetInstanceProcAddr nextGetInstanceProcAddr;
    PFN_xrCreateApiLayerInstance nextCreateApiLayerInstance;
    XrApiLayerNextInfo *next;
};
----
  * pname:structType is the type of structure, or
    XR_LOADER_INTERFACE_STRUCT_API_LAYER_NEXT_INFO in this case.
  * pname:structVersion is the version of the structure being supplied by
    the loader.
  * pname:structSize is the size of the structure supplied by the loader.
  * pname:layerName is the name of the API layer which should be receiving
    this information.
    The intent is to make sure the API layer chain information is behaving
    properly.
  * pname:nextGetInstanceProcAddr is a pointer to the next API layer's
    `xrGetInstanceProcAddr`.
    This can be used to generate a dispatch table to the next commands in
    the chain.
  * pname:nextCreateLayerInstance is a pointer to the next API layer's
    `xrCreateApiLayerInstance` command.
    This is to be called after the API layer has done any localized
    creation, but before the API layer records any command addresses from
    the next API layer using `xrGetInstanceProcAddr`.
  * pname:next is a pointer to the sname:XrApiLayerNextInfo for the next API
    layer.
    If no API layer is after this, it will be NULL.
    However, the loader implements a `xrTerminatorCreateLayerInstance`
    command to re-direct the call-chain back to the runtime's
    `xrCreateInstance` command, so this should be the last command to
    receive this information.

During the `xrCreateInstance` call, the following happens:

. The call enters the loader's trampoline function `xrCreateInstance`
. The loader will generate an instance of the slink:XrApiLayerCreateInfo
  structure
. The loader will go through each API layer in reverse order (i.e. starting with
  the layer closest to the runtime and ending with the API layer closest to
  the application):
.. Record the API layer's name, `xrGetInstanceProcAddr` address, and the
   `xrCreateApiLayerInstance` address.
.. Build a `XrApiLayerNextInfo` structure for the API layer recording the name and
   command addresses.
... If this is the first API layer (the one closest to the runtime) we want it
    to enter the loader again when we're done.
    So, the loader sets the following:
.... `XrApiLayerNextInfo.nextGetInstanceProcAddr` =
     `loaderXrTermGetInstanceProcAddr`
.... `XrApiLayerNextInfo.nextCreateLayerInstance` =
     `loaderXrTermCreateLayerInstance`
.... `XrApiLayerNextInfo.next` = NULL
... Otherwise, the loader sets the information to the previous API layer's
    information:
.... `XrApiLayerNextInfo.nextGetInstanceProcAddr` =
     Previous `XrApiLayerNextInfo.loaderXrTermGetInstanceProcAddr`
.... `XrApiLayerNextInfo.nextCreateLayerInstance` =
     Previous `XrApiLayerNextInfo.loaderXrTermCreateLayerInstance`
.... `XrApiLayerNextInfo.next` = address to previous `XrApiLayerNextInfo`
. The loader will then update the `XrApiLayerCreateInfo.nextInfo` to point to the
  last created `XrApiLayerNextInfo` since this is the first API layer in the
  call-chain.
. The loader calls the first API layer's flink:xrCreateApiLayerInstance command
  passing in the pointer to the created slink:XrApiLayerCreateInfo
. The API layer receives the information in its flink:xrCreateApiLayerInstance command.
. The API layer copies the slink:XrApiLayerCreateInfo structure into it's own structure.
. The API layer then updates it's version of the slink:XrApiLayerCreateInfo structure
  setting pname:nextInfo to point to the slink:XrApiLayerNextInfo for the
  next API layer (i.e. `XrApiLayerCreateInfo->nextInfo =
  XrApiLayerCreateInfo->nextInfo->next;`).
. The API layer may validate that it is getting the correct next information by
  checking that the pname:layerName matches.
. The API layer then uses the information out of its sname:XrApiLayerNextInfo to call
  down the call-chain to the next fname:xrCreateApiLayerInstance, using a
  pointer to its slink:XrApiLayerCreateInfo structure instead of the one
  that was passed in during its fname:xrCreateApiLayerInstance command.
.. If the call passes, this API layer may choose to setup its own dispatch table to
   the next API layer's commands using the returned `XrInstance`, the next
   API layer's `xrGetInstanceProcAddr` and the
   fname:GeneratedXrPopulateDispatchTable utility command provided in the
   generated `xr_generated_dispatch_table.h` header.
. Finally, the API layer should return the result passed in from the next API layer.