aboutsummaryrefslogtreecommitdiff
path: root/glslc/README.asciidoc
blob: b1551cdc4682c75ea4b7f59805de4fc5effd0a35 (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
= glslc Manual

:numbered:
:source-highlighter: pygments

== Name

`glslc` - A command-line GLSL/HLSL to SPIR-V compiler with
Clang-compatible arguments.

== Synopsis

----
glslc [--help]

glslc [--show-limits]

glslc [-c|-S|-E]
      [-x ...] [-std=standard]
      [-fentry-point=...]
      [-flimit=...]
      [-fshader-stage=...]
      [--target-env=...]
      [-g]
      [-O0|-Os]
      [-Idirectory...]
      [-Dmacroname[=value]...]
      [-w] [-Werror]
      [-o outfile]
      shader...
----

== Description

=== Input file languages

glslc accepts both GLSL/HLSL source and SPIR-V assembly files as inputs.

==== Shader stage specification

glslc provides three ways to specify the shader stage of a GLSL source file:
`-fshader-stage=<stage>`, `#pragma shader_stage(<stage>)`, and file extension.
The `-fshader-stage=` option overrides `#pragma shader_stage()`, which overrides
the file extension.

Shader stages can be specified by naming a file with an appropriate extension
as shown in the following table. `-fshader-stage=` and `#pragma shader_stage()`,
on the other hand, enable you to specify shader stages from the command line
and within the source file. Possible ``stage``s for them are also listed in
the following table. Details about `-fshader-stage=` can be found in
<<option-f-shader-stage,its own section>>.

[[shader-stage-selection]]
.Shader Stage Selection
|===
|Shader Stage |Shader File Extension |`<stage>`

|vertex                 |`.vert` |`vertex`
|fragment               |`.frag` |`fragment`
|tesselation control    |`.tesc` |`tesscontrol`
|tesselation evaluation |`.tese` |`tesseval`
|geometry               |`.geom` |`geometry`
|compute                |`.comp` |`compute`
|===

`#pragma shader_stage()` relies on the `#pragma` preprocessor directive; thus,
the token inside `shader_stage()` is not subject to preprocessor macro
expansion. It must be exactly one of the ``stage``s in the above table.

`#pragma shader_stage()` behaves as follows:

* The first `#pragma shader_stage()` directive in a translation unit must
  precede any non-preprocessor tokens.
* If there is more than one `#pragma shader_stage()` directive in the same
  translation unit, all the ``stage``s specified must be the same. Otherwise,
  glslc will issue an error.

==== SPIR-V assembly files

SPIR-V assembly input files should follow the
https://github.com/KhronosGroup/SPIRV-Tools/blob/master/syntax.md[syntax]
defined in the https://github.com/KhronosGroup/SPIRV-Tools[SPIRV-Tools]
project and have the `.spvasm` extension. Command line options treat SPIR-V
assembly files differently; some may ignore them, e.g., `<<option-cap-e,-E>>`,
`<<option-cap-s,-S>>`, and some may even treat them not as SPIR-V assembly
files, e.g., `<<shader-stage-with-spirv-assembly,-fshader-stage\=>>`.

[[output-file-naming]]
=== Output file naming

If a name is specified via `-o`, the output file will be given that name.
Otherwise,

* If a compilation stage selection option is given (`-S` or `-c`), there will
  be one output file generated per input shader file. The generated output file
  will end with a file extension that matches the compilation stage, which is
  `.spvasm` for `-S` and `.spv` for `-c`. The name will depend on the original
  file's name and extension.
** If the input file has a <<shader-stage-selection,shader stage selection
   extension>>, the output file will be named as by appending the file extension
   for the compilation stage to the input file's name. E.g., `glslc -c foo.vert`
   will generate `foo.vert.spv`, and `glslc -s bar.frag` will generate
   `bar.frag.spvasm`.
** Otherwise, the output file will be named as by replacing the input file's
   file extension, if any, with the file extension for the compilation stage.
   E.g., `glslc -c foo` will generate `foo.spv`, and `glslc -s bar.glsl` will
   generate `bar.spvasm`.
* If no compilation stage is selected, the output file will be named `a.spv`.

== Command Line Options

=== Overall Options

==== `--help`

`--help` tells the glslc compiler to display all available options and exit.

==== `--show-limits`

`--show-limits` shows default resource limits for shader compilation.  The syntax
is the same as accepted by `-flimit=` and for the contents of the file specified
by `-flimit-file`.

==== `-o`

`-o` lets you specify the output file's name. It cannot be used when there are
multiple files generated. A filename of `-` represents standard output.

=== Language and Mode Selection Options

[[option-f-entry-point]]
==== `-fentry-point=`

`-fentry-point=<name>` lets you specify the entry point name.  This is only
significant for HLSL compilation.  The default is "main".

[[option-f-limit]]
==== `-flimit=`

`-flimit=<resource-limits>` lets you specify resource limits.
The argument should be a sequence of limit name, integer value pairs.  Tokens
should be separated by whitespace.  If the same limit is specified several
times, only the last setting takes effect.

Use `--show-limits` to show the default values, and example syntax.

This option affects all compiled shaders.

[[option-f-limit-file]]
==== `-flimit-file`

`-flimit-file <resource-limits-file>` lets you specify resource limits in a file.
The syntax of the file contents is the same as the argument to `-flimit=` and
the output of `--show-limits`.  This option accepts Glslang resource configuration
files, e.g. as emitted by `glslangValidator -c`.

This option affects all compiled shaders.

[[option-f-shader-stage]]
==== `-fshader-stage=`

`-fshader-stage=<stage>` lets you specify the shader stage for one or more
inputs from the command line.

Possible values for ``<stage>`` are listed in the <<shader-stage-selection,
Shader Stage Selection>> table.

`-fshader-stage=` behaves as follows:

* `-fshader-stage=` sets the shader stage for subsequent input files. It does
  not affect the stages of any preceding inputs on the command line.
* When supplying more than one `-fshader-stage=` argument, the most recent
  argument preceding an input file applies.
* A shader file not ending with <<shader-stage-selection,known shader file
  extensions>> must have a `-fshader-stage=` argument ahead of it to specify
  its stage.
* If there is a `-fshader-stage=` before a file in which there is a `#pragma
  shader_stage()` directive, the directive is ignored and the `-fshader-stage=`
  argument is used instead.
* If there is a `-fshader-stage=` before a file with a known shader file
  extension, the file extension is ignored and the `-fshader-stage=` argument
  is used instead.

[[shader-stage-with-spirv-assembly]]
CAUTION: `-fshader-stage=` overrides file extension; that means it should not
be used together with SPIR-V assembly files because glslc will treat the given
SPIR-V assembly files as GLSL source code of the given shader stage. If you
need to supply both SPIR-V assembly files and `-fshader-stage=` on the same
command line, please put SPIR-V assembly files ahead of the first
`-fshader-stage=`, since `-fshader-stage=` only affects the treatment of
subsequent files.

==== `-std=`

`-std=<value>` lets you specify a shader version and profile on the command
line. ``<value>`` can be any valid concatenation of a GLSL version number and
profile, e.g., `310es`, `450core`, etc. The profile can be omitted as allowed by
GLSL, e.g., `450`.

`-std=` behaves as follows:

* `-std=` affects the version of all GLSL inputs passed to `glslc`.
* `-std=` is ignored for HLSL inputs.
* `-std=` overwrites `#version` directives in all input shaders, including those
  preceding the argument.
* If a `-std=` argument specifies a different version from a `#version`
  directive in an input file, `glslc` will issue a warning.
* If multiple `-std=` arguments are specified on the command line, only the last
  one takes effect.

CAUTION: `-std=` does not affect the `#version` directive in the preprocessed
output. That is, when `-std=` specifies a version different from the shader
source code, the `#version` directive in preprocessed output will still be the
one in the source code. But `-std=` does affect the behavior of `#line`
directives in the preprocessed output. Behavior of `#line` directives will
follow the version specified by `-std=`.

==== `--target-env=`

`--target-env=<value>` lets you specify a target environment on the command line.
This affects the generation of warnings and errors. ``<value>`` can be one of
the following:

* `vulkan`: create SPIR-V under Vulkan semantics.
* `opengl`: create SPIR-V under OpenGL semantics.
* `opengl_compat`: create SPIR-V under OpenGL semantics, including compatibility
  profile functions.

By default, the ``<value>`` is set to `vulkan` and the compiler creates SPIR-V
under Vulkan semantics.

==== `-x`

`-x` lets you specify the language of the input shader files. Valid languages
are `glsl` and `hlsl`.  If the file extension is `hlsl` then the default language
is HLSL.  Otherwise the default is 'glsl'.

[[compilation-stage-selection-options]]
=== Compilation Stage Selection Options

==== `-c`

`-c` tells the glslc compiler to run the preprocessing and compiling stage.
Each input shader file results in a SPIR-V binary file; these SPIR-V binary
files are named by the rules in the <<output-file-naming,Output File Naming>>
section.

[[option-cap-e]]
==== `-E`

`-E` tells the glslc compiler to run only the preprocessing stage. It overrides
`-c` and `-S`. Preprocessed output is written to standard output, while
preprocessing errors are written to standard error. If multiple input shader
files are given, their preprocessed output are all written to standard output,
in the order specified on the command line.

glslc will do nothing for SPIR-V assembly files with this option.

[[option-cap-s]]
==== `-S`

`-S` tells the glslc compiler to run the preprocessing, compiling, and then
disassembling stage. It overrides `-c`. Each input shader file results in a
SPIR-V assembly file; these SPIR-V assembly files are named by the rules in the
<<output-file-naming,Output File Naming>> section.

glslc will do nothing for SPIR-V assembly files with this option.

==== No Compilation Stage Selection

If none of the above options is given, the glslc compiler will run
preprocessing, compiling, and linking stages.

WARNING: Linking of multiple input shader files are not supported yet.

=== Preprocessor Options

==== `-D`

`-Dmacroname[=[value]]` lets you define a preprocessor macro before input shader
files are preprocessed. If `value` is omitted, the macro is defined with an
empty value.

==== `-I`

`-Idirectory` or `-I directory` adds the specified directory to the search path
for include files.  The directory may be an absolute path or a relative path to
the current working directory.

=== Code Generation Options

==== `-g`

Requests that the compiler place source-level debug information into the object
code, such as identifier names and line numbers.

This option restrains `-O` from turning on the strip-debug-info optimization
pass.

NOTE: Currently this option has no effect.  Full functionality depends on
glslang support for generating debug info.

==== `-O0`, `-Os`

`-O` specifies which optimization level to use:

* `-O0` means "no optimization". This level generates the most debuggable code.
* `-Os` enables optimizations to reduce code size.

==== `-mfmt=<format>`

`-mfmt=<format>` selects output format for compilation output in SPIR-V binary
code form.  Supported options are listed in the
<<binary-output-format-options,binary output format options>> table. This
option is only valid to be used when the compilation output is SPIR-V binary
code. Specifying any options listed below when the output is not SPIR-V binary
code, like disassembly (with `-S` specified), text (with `-M`, `-MM` or `-E`
specified) will trigger an error.

[[binary-output-format-options]]
.Binary Output Format Options
[cols="20%,80%"]
|===
|Format option  |Description

|bin            |Output SPIR-V binary code as a sequence of binary 32-bitwords
                 in host native endianness. This is the default format for
                 SPIR-V binary compilation output.
|num            |Output SPIR-V binary code as a text file containing a list of
                 comma-separated hex numbers. +
                 Example: `glslc -c -mfmt=num main.vert -o output_file.txt` +
                 Content of the output_file.txt: +
                 0x07230203,0x00010000,0x00080001,0x00000006...
|c              |Output SPIR-V binary code as a text file containing C-style +
                 initializer list. +
                 This is just wrapping the output of `num` option with curly
                 brackets. +
                 Example: `glslc -c -mfmt=c main.vert -o output_file.txt` +
                 Content of output_file.txt: +
                 {0x07230203, 0x00010000, 0x00080001, 0x00000006...}
|===

=== Warning and Error Options

==== `-w`

`-w` suppresses all warning output from `glslc`. Any warning that would have
been generated is silently ignored.

==== `-Werror`

`-Werror` forces any warning to be treated as an error in `glslc`. This means
that all `warning:` messages are shown as `error:` and any warnings will cause
a non-zero exit code from `glslc`. If `-w` is specified the warnings
generated are suppressed before they are converted to errors.

=== Dependency Generation Options

==== `-M` or `-MM`

`-M` generates *make* dependencies. It outputs a rule suitable for *make*
describing the dependencies of the input file. Instead of outputting the result
of preprocessing, the preprocessor outputs one *make* rule containing the
SPIR-V object file name for that source file, a colon, and the names of all the
included files.

Unless specified explicitly (with `-MT`), the SPIR-V object file name in the
generated *make* rules follows the rules of  <<output-file-naming,Output File
Naming>> as in `-c` compilation stage.

Specifying `-M` implies `-E`, and suppresses warnings with an implicit `-w`.
By default the output will be written to stdout, unless `-MF` or `-o` is
specified.

The dependency info file name can be specified by `-o` and `-MF` options. When
both are specified, `-o` option is ignored.

Specifying multiple input files is valid when the *make* rules are written to
stdout, which means neither `-MF` nor `-o` is specified. When `-o` or `-MF` is
specified, only one input file is allowed.

`-MM` is an alias for `-M`.

E.g., `glslc -M main.vert` will dump `main.vert.spv: main.vert <other included
files>` to stdout. More examples are listed in
<<dependency-generation-examples,Dependency Generation Examples>>

==== `-MD`

`-MD` tells the glslc compiler to both compile the source and generate *make*
dependencies. Dependencies are written to a file whose name is determined as
follows: If option `-MF` is specified, use its argument. Otherwise, use the
filename formed by appending *.d* to the name of the file containing
compilation results.

Specifying multiple input files is valid when neither `-MF` nor `-o` is
specified. When `-o` or `-MF` is specified, only one input file is allowed.

E.g., `glslc -c -MD main.vert` will generate `main.vert.spv` as the SPIR-V
object file and `main.vert.spv.d` as the dependency info file. More examples
are listed in <<dependency-generation-examples,Dependency Generation Examples>>

==== `-MF`

`-MF` lets you specify the dependency info file name when used with `-M` or
`-MD`. This option is invalid when used with multiple input files.

E.g., `glslc -c -MD main.vert -MF dep_info` will generate `main.vert.spv` as
the SPIR-V object file and `dep_info` as the dependency info file.

==== `-MT`

`-MT` lets you specify the target of the rule emitted by dependency generation
when used with `-M` or `-MD`.  This option is invalid when used with multiple
input files.

E.g., `glslc -M main.vert -MT target` will dump following dependency info to
stdout: `target: main.vert <other dependent files>`.

[[dependency-generation-examples]]
.Dependency Generation Examples
|===
|Command Line Input|Compilation Output File|Dependency Output File|Dependency Info

|glslc -M main.vert             | <NA> | <Stdout> | main.vert.spv: main.vert
.2+|glslc -M a.vert b.vert         | <NA> | <Stdout> | a.vert.spv: a.vert
                                   | <NA> | <Stdout> | b.vert.spv: b.vert
|glslc -M main.vert -o dep_info | <NA> | dep_info | main.vert.spv: main.vert
|glslc -M main.vert -MF dep_info| <NA> | dep_info | main.vert.spv: main.vert
|glslc -M main.vert -MT target  | <NA> | <Stdout> | target: main.vert
|glslc -MD main.vert    |a.spv  |main.vert.spv.d|main.vert.spv: main.vert
|glslc -c -MD main.vert |main.vert.spv|main.vert.spv.d|main.vert.spv: main.vert
.2+|glslc -c -MD a.vert b.vert | a.vert.spv | a.vert.spv.d | a.vert.spv: a.vert
                               | b.vert.spv | b.vert.spv.d | b.vert.spv: b.vert
|glslc -S -MD main.vert |main.vert.spvasm  |main.vert.spvasm.d  |main.vert.spvasm: main.vert
|glslc -c -MD main.vert -MF dep_info  |main.vert.spv|dep_info|main.vert.spv: main.vert
|glslc -c -MD main.vert -o obj  |obj  |obj.d  |obj: main.vert
|glslc -c -MD main.vert -o obj -MF dep_info -MT target|obj|dep_info|target: main.vert
|===

== Divergence from and extensions to GLSL specifications

=== Source-filename-based `#line` and `\\__FILE__`

This section describes how the glslc compiler extends the syntax for the `#line`
directive and the `\\__FILE__` macro. By default, the glslc compiler enables
the `GL_GOOGLE_cpp_style_line_directive` extension. It will generate this
extended syntax in the preprocessed output (obtained via the `-E` option).

WARNING: This section is still evolving. Expect changes.

GLSL specifications have a notion of source strings.

[quote, Section 3.2 of both version 3.30 and 4.50]
____
The source for a single shader is an array of strings of characters from the
character set. A single shader is made from the concatenation of these strings.
____

With the above notion, the second parameter to the `#line` directive should
be a constant integer expressions representing the source string number. Also
the `\\__FILE__` macro will "substitute a decimal integer constant that says
which source string number is currently being processed."

The glslc compiler implements the standard `#line` and `\\__FILE__` syntax. It
also provides an extension, `GL_GOOGLE_cpp_style_line_directive`, to allow
source filenames to be used instead of integer source string indices.
Specifically, the `#line` directive can have, after macro substitution, one of
the following three forms:

[source,glsl]
----
#line line-number
#line line-number integer-source-string-index
#line line-number "source-filename"
----

where `source-filename` can be any combinations of characters except double
quotation marks. (Note that according to the GLSL specification, "there are
no escape sequences or other uses of the backslash beyond use as the
line-continuation character".)

And if source-filename-based `#line` is used, the `\\__FILE__` macro expands to
a string whose contents are the filename quoted with double quotation marks.
The filename is dertermined as the last of

* The filename given to the glslc compiler,
* The filename argument of the most recent `#line` directive, if any.

[[include-directive]]
=== `#include`

The glslc compiler extends GLSL with the include syntax by turning on the
`GL_GOOGLE_include_directive` extension. It will preprocess and substitute
`#include` directives properly with the following behaviors.

WARNING: This section is still evolving. Expect changes.

If `#include` directives are used in a shader, there will be an `#extension
GL_GOOGLE_include_directive : enable` line generated into the preprocessed
output.

The `GL_GOOGLE_cpp_style_line_directive` extension is implicitly turned on by
the `GL_GOOGLE_include_directive` extension.

The file argument to `#include` must be enclosed in double quotes.  It must be a
relative path, using whatever path separator the OS supports.  However, the last
path element -- the name of the file itself -- must not contain either '/' or
'\', regardless of which path separator is used.  This will not be flagged as an
error but will instead trigger undefined behavior.  For example, let's say there
is a file named `f\ilename.vert` on a Unix OS.  It is not possible to craft a
`#include` that includes that file.

Furthermore, it is not possible to escape any characters in a `#include`
directive, so the file argument cannot contain any special characters that need
escaping in C.

The file argument is a relative path that is matched first against the including
file's own directory and then against all `-I` arguments in order of their
appearance on the command line.  If the file cannot be found, `glslc` aborts
with an error.