Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 1 | This is a specification for how the Vulkan loader should identify Vulkan
|
Jon Ashburn | 6121daf | 2015-07-24 09:20:11 -0600 | [diff] [blame] | 2 | installable client drivers (ICDs) on MS Windows. This is designed for
|
| 3 | production installation of Vulkan ICDs and layers. The design is shown first
|
| 4 | for ICDs, and then the variation for layers will be discussed.
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 5 |
|
| 6 |
|
| 7 | 1. Installable Client Drivers:
|
| 8 |
|
| 9 |
|
| 10 | 1.1. Properly-Installed ICDs
|
| 11 |
|
| 12 | In order to find properly-installed ICDs, the Vulkan loader will scan the
|
| 13 | values in the following Windows registry key:
|
| 14 |
|
| 15 | HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\Drivers
|
| 16 |
|
| 17 | For each value in this key which has DWORD data set to 0, the loader opens the
|
David Pinedo | 8a15419 | 2015-12-07 17:49:43 -0700 | [diff] [blame] | 18 | JSON format text information file (a.k.a. "manifest file") specified by the
|
| 19 | name of the value. Each name must be a full pathname to the text info file.
|
| 20 | The Vulkan loader will open each info file to obtain the name or pathname of
|
| 21 | an ICD shared library (".dll") file. For example:
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 22 |
|
| 23 | {
|
Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 24 | "file_format_version": "1.0.0",
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 25 | "ICD": {
|
| 26 | "library_path": "path to ICD library",
|
Tony Barbour | fd2f788 | 2016-01-14 10:40:40 -0700 | [diff] [blame] | 27 | "api_version": "1.0.1"
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 28 | }
|
| 29 | }
|
| 30 |
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 31 | The "library_path" specifies either a filename, a relative pathname, or a full
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 32 | pathname to an ICD shared library file, which the loader will attempt to load
|
Jon Ashburn | 6121daf | 2015-07-24 09:20:11 -0600 | [diff] [blame] | 33 | using LoadLibrary(). If the ICD is specified via a filename, the shared
|
Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 34 | library lives in the system's DLL search path (e.g. in the
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 35 | "C:\\Windows\\System32" folder). If the ICD is specified via a relative
|
Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 36 | pathname, it is relative to the path of the info file. Relative pathnames are
|
| 37 | those that do not start with a drive specifier (e.g. "C:"), nor with a
|
| 38 | directory separator (i.e. the '\' character), but do contain at least one
|
| 39 | directory separator.
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 40 |
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 41 | The "file_format_version" specifies a major.minor.patch version number in case
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 42 | the format of the text information file changes in the future. If the same ICD
|
| 43 | shared library supports multiple, incompatible versions of text info file
|
| 44 | format versions, it must have multiple text info files (all of which may point
|
| 45 | to the same shared library).
|
| 46 |
|
Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 47 | The “api_version” specifies the major.minor.patch version number of the Vulkan
|
| 48 | API that the shared library (referenced by "library_path") was built with.
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 49 |
|
| 50 | There are no rules about the name of the text information files (except the
|
| 51 | .json suffix). There are no rules about the name of the ICD shared library
|
| 52 | files. For example, if the registry contains the following values:
|
| 53 |
|
| 54 | [HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\Drivers]
|
| 55 | "c:\\vendor a\\vk_vendora.json"=dword:00000000
|
| 56 | "c:\\windows\\system32\\vendorb_vk.json"=dword:00000000
|
| 57 | "c:\\windows\\system32\\vendorc_icd.json"=dword:00000000
|
| 58 |
|
| 59 | then the loader will open the following text information files, with the
|
| 60 | specified contents:
|
| 61 |
|
| 62 | Text File Name Text File Contents
|
| 63 | --------------------------------------------------------------------------
|
| 64 | vk_vendora.json { "ICD": { "library_path": "C:\\VENDORA\\vk_vendora.dll" }}
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 65 | vendorb_vk.json { "ICD": { "library_path": "vendorb_vk.dll" }}
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 66 | vendorc_icd.json { "ICD": { "library_path": "vedorc_icd.dll" }}
|
| 67 |
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 68 | then the loader will open the three files mentioned in the "Text File Contents"
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 69 | column, and then try to load and use the three shared libraries mentioned
|
| 70 | indicated by the ICD.library_path value.
|
| 71 |
|
| 72 |
|
| 73 | 1.2. Using Pre-Production ICDs
|
| 74 |
|
| 75 | IHV developers (and sometimes other developers) need to use special,
|
| 76 | pre-production ICDs. In some cases, a pre-production ICD may be in an
|
| 77 | installable package. In other cases, a pre-production ICD may simply be a
|
Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 78 | shared library in the developer's build tree. In this latter case, we want to
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 79 | allow developers to point to such an ICD without modifying the
|
| 80 | properly-installed ICD(s) on their system.
|
| 81 |
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 82 | This need is met with the use of the "VK_ICD_FILENAMES" environment variable,
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 83 | which will override the mechanism used for finding properly-installed ICDs. In
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 84 | other words, only the ICDs listed in "VK_ICD_FILENAMES" will be used.
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 85 |
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 86 | The "VK_ICD_FILENAMES" environment variable is a semi-colon-separated list of
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 87 | ICD text information files, containing the following:
|
| 88 |
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 89 | - A full pathname (e.g. "C:\\my_build\\my_icd.json")
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 90 |
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 91 | Typically, "VK_ICD_FILENAMES" will only contain a full pathname to one info
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 92 | file for a developer-built ICD. A semi-colon is only used if more than one ICD
|
| 93 | is listed.
|
| 94 |
|
| 95 | For example, if a developer wants to refer to one ICD that they built, they
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 96 | could set the "VK_ICD_FILENAMES" environment variable to:
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 97 |
|
| 98 | C:\\my_build\\my_icd.json
|
| 99 |
|
| 100 | If a developer wants to refer to two ICDs, one of which is a properly-installed
|
| 101 | ICD, they can use the full pathname of the text file:
|
| 102 |
|
| 103 | C:\\Windows\\System32\\vendorc_icd.json;C:\\my_build\\my_icd.json
|
| 104 |
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 105 | Notice the semi-colon between "C:\\Windows\\System32\\vendorc_icd.json" and
|
| 106 | "C:\\my_build\\my_icd.json".
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 107 |
|
| 108 |
|
| 109 | 2. Layers:
|
| 110 |
|
| 111 |
|
| 112 | 2.1. Properly-Installed Layers
|
| 113 |
|
| 114 | In order to find properly-installed layers, the Vulkan loader will use a
|
| 115 | similar mechanism as used for ICDs. Text information files, that use a JSON
|
| 116 | format, are read in order to identify the names and attributes of layers and
|
| 117 | their extensions. The use of text info files allows the loader to avoid
|
| 118 | loading any shared library files when the application does not query nor
|
| 119 | request any extensions. Layers and extensions have additional complexity, and
|
| 120 | so their info files contain more information than ICD info files. For example,
|
| 121 | a layer shared library file may contain multiple layers/extensions (perhaps
|
| 122 | even an ICD).
|
| 123 |
|
David Pinedo | 8a15419 | 2015-12-07 17:49:43 -0700 | [diff] [blame] | 124 | In order to find properly-installed layers, the Vulkan loader will scan the
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 125 | values in the following Windows registry keys:
|
| 126 |
|
| 127 | HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\ExplicitLayers
|
| 128 | HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\ImplicitLayers
|
| 129 |
|
| 130 | Explicit layers are those which are enabled by an application (e.g. with the
|
| 131 | vkCreateInstance function), or by an environment variable (see below).
|
| 132 | Implicit layers are those which are enabled by their existence. For example,
|
| 133 | certain application environments (e.g. Steam or an automotive infotainment
|
| 134 | system) may have layers which they always want enabled for all applications
|
| 135 | that they start. Other implicit layers may be for all applications started
|
| 136 | on a given system (e.g. layers that overlay frames-per-second). Implicit
|
| 137 | layers are enabled automatically, whereas explicit
|
| 138 | layers must be enabled explicitly. What distinguishes a layer as implicit or
|
| 139 | explicit is by which registry key its layer information file is referenced by.
|
| 140 |
|
Ian Elliott | b901a05 | 2015-12-17 10:22:33 -0700 | [diff] [blame] | 141 | For each value in these keys which has DWORD data set to 0, the loader opens
|
| 142 | the JSON format text information file (a.k.a. "manifest file") specified by the
|
| 143 | name of the value. Each name must be a full pathname to the text info file.
|
| 144 | The Vulkan loader will open each info file to obtain information about the
|
| 145 | layer, including the name or pathname of a shared library (".dll") file.
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 146 | The information file is in the JSON format and contains the following
|
| 147 | information:
|
| 148 |
|
Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 149 | - (required) "file_format_version" - same as for ICDs, except that the format
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 150 | version can vary independently for ICDs and layers.
|
| 151 | - (required) "name" - layer name
|
| 152 | - (required) "type" - which layer chains should the layer be activated on.
|
| 153 | Allowable values are "INSTANCE", "DEVICE", "GLOBAL". Global means activate
|
| 154 | on both device and instance chains.
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 155 | - (required) "library_path" - filename / full path / relative path to the text
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 156 | file
|
Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 157 | - (required) "api_version" - same as for ICDs.
|
| 158 | - (required) "implementation_version" - layer version, a single number increasing with backward compatible changes.
|
| 159 | - (required) "description" - informative decription of the layer.
|
| 160 | - (optional) "device_extensions" or "instance_extensions" - array of extension information as follows
|
| 161 | - (optional) extension "name" - Vulkan registered name
|
| 162 | - (optional) extension "spec_version" - extension specification version, a single number, increasing with backward compatible changes.
|
| 163 | - (optional) extension "entrypoints" - array of device extension entrypoints; not used for instance extensions
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 164 | - (sometimes required) "functions" - mapping list of function entry points. If
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 165 | multiple layers exist within the same shared library (or if a layer is in the
|
| 166 | same shared library as an ICD), this must be specified to allow each layer to
|
| 167 | have its own vkGet*ProcAddr entrypoints that can be found by the loader. At
|
| 168 | this time, only the following two functions are required:
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 169 | - "vkGetInstanceProcAddr" name
|
| 170 | - "vkGetDeviceProcAddr" name
|
| 171 | - (optional for implicit layers) "enable_environment" requirement(s) -
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 172 | environment variable and value required to enable an implicit layer. This
|
| 173 | environment variable (which should vary with each "version" of the layer, as
|
Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 174 | in "ENABLE_LAYER_FOO_1") must be set to the given value or else the
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 175 | implicit layer is not loaded. This is for application environments
|
| 176 | (e.g. Steam) which want to enable a layer(s) only for applications that they
|
| 177 | launch, and allows for applications run outside of an application environment
|
| 178 | to not get that implicit layer(s).
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 179 | - (required for implicit layers) "disable_environment" requirement(s) -
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 180 | environment variable and value required to disable an implicit layer. Note:
|
| 181 | in rare cases of an application not working with an implicit layer, the
|
| 182 | application can set this environment variable (before calling Vulkan
|
| 183 | functions) in order to "blacklist" the layer. This environment variable
|
| 184 | (which should vary with each "version" of the layer, as in
|
Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 185 | "DISABLE_LAYER_FOO_1") must be set (not particularly to any value). If
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 186 | both the "enable_environment" and "disable_environment" variables are set,
|
| 187 | the implicit layer is disabled.
|
| 188 |
|
Jon Ashburn | 6121daf | 2015-07-24 09:20:11 -0600 | [diff] [blame] | 189 | For example:
|
| 190 |
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 191 | {
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 192 | "file_format_version" : "1.0.0",
|
| 193 | "layer": {
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 194 | "name": "OverlayLayer",
|
| 195 | "type": "DEVICE",
|
| 196 | "library_path": "vkOverlayLayer.dll",
|
Tony Barbour | fd2f788 | 2016-01-14 10:40:40 -0700 | [diff] [blame] | 197 | "api_version" : "1.0.1",
|
Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 198 | "implementation_version" : "2",
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 199 | "description" : "LunarG HUD layer",
|
| 200 | "functions": {
|
| 201 | "vkGetInstanceProcAddr": "OverlayLayer_GetInstanceProcAddr",
|
| 202 | "vkGetDeviceProcAddr": "OverlayLayer_GetDeviceProcAddr"
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 203 | },
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 204 | instance_extensions": [
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 205 | {
|
David Pinedo | abd0772 | 2015-11-24 09:00:24 -0700 | [diff] [blame] | 206 | "name": "VK_LUNARG_DEBUG_REPORT",
|
Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 207 | "spec_version": "1"
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 208 | },
|
| 209 | {
|
David Pinedo | abd0772 | 2015-11-24 09:00:24 -0700 | [diff] [blame] | 210 | "name": "VK_VENDOR_DEBUG_X",
|
Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 211 | "spec_version": "3"
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 212 | }
|
| 213 | ],
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 214 | device_extensions": [
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 215 | {
|
David Pinedo | abd0772 | 2015-11-24 09:00:24 -0700 | [diff] [blame] | 216 | "name": "VK_LUNARG_DEBUG_MARKER",
|
Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 217 | "spec_version": "1",
|
| 218 | "entrypoints": ["vkCmdDbgMarkerBegin", "vkCmdDbgMarkerEnd"]
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 219 | }
|
| 220 | ],
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 221 | "disable_environment": {
|
Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 222 | "DISABLE_LAYER_OVERLAY_1": ""
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 223 | }
|
| 224 | }
|
| 225 | }
|
| 226 |
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 227 | The "library_path" specifies either a filename, a relative pathname, or a full
|
| 228 | pathname to a layer shared library (".dll") file, which the loader will attempt
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 229 | to load using LoadLibrary(). If the layer is specified via a relative
|
| 230 | pathname, it is relative to the path of the info file (e.g. for cases when an
|
| 231 | application provides a layer that is in the same folder hierarchy as the rest
|
| 232 | of the application files). If the layer is specified via a filename, the
|
Jon Ashburn | f2a944f | 2015-11-18 16:46:48 -0700 | [diff] [blame] | 233 | shared library lives in the system's DLL search path (e.g. in the
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 234 | "C:\\Windows\\System32" folder).
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 235 |
|
| 236 | There are no rules about the name of the text files (except the .json suffix).
|
| 237 | There are no rules about the name of the layer shared library files.
|
| 238 |
|
| 239 |
|
| 240 | 2.2. Using Pre-Production Layers
|
| 241 |
|
| 242 | As with ICDs, developers may need to use special, pre-production layers,
|
| 243 | without modifying the properly-installed layers.
|
| 244 |
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 245 | This need is met with the use of the "VK_LAYER_PATH" environment variable,
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 246 | which will override the mechanism using for finding properly-installed layers.
|
| 247 | Because many layers may exist on a system, this environment variable is a
|
| 248 | semi-colon-separated list of folders that contain layer info files. Only the
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 249 | folder listed in "VK_LAYER_PATH" will be scanned for info files. Each
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 250 | semi-colon-separated entry is:
|
| 251 |
|
| 252 | - The full pathname of a folder containing layer info files
|
| 253 |
|
| 254 | In addition to overriding the mechanism for finding layers, the following
|
| 255 | environment variables are used to select one or more layers/extensions
|
| 256 | (respectively) to explicitly enable:
|
| 257 |
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 258 | - "VK_INSTANCE_LAYERS" for instance/global layers/extensions, enabled at
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 259 | vkCreateInstance time
|
| 260 |
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 261 | - "VK_DEVICE_LAYERS" for device layers/extensions, enabled at vkCreateDevice
|
Jon Ashburn | 4a511f1 | 2015-07-16 10:54:55 -0600 | [diff] [blame] | 262 | time
|
| 263 |
|
| 264 | These are semi-colon-separated lists of extension names, as listed in the
|
jon | 5b1e34d | 2015-10-29 15:51:28 -0600 | [diff] [blame] | 265 | "name" field of the info file. The loader will load all layers/extensions that
|
| 266 | match the given extension name(s), ignoring the "version" fields.
|