• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1![Continuous Integration](https://github.com/KhronosGroup/glslang/actions/workflows/continuous_integration.yml/badge.svg)
2![Continuous Deployment](https://github.com/KhronosGroup/glslang/actions/workflows/continuous_deployment.yml/badge.svg)
3[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/KhronosGroup/glslang/badge)](https://securityscorecards.dev/viewer/?uri=github.com/KhronosGroup/glslang)
4
5# News
6
71. `OGLCompiler` and `HLSL` stub libraries have been fully removed from the build.
8
92. `OVERRIDE_MSVCCRT` has been removed in favor of `CMAKE_MSVC_RUNTIME_LIBRARY`
10
11Users are encouraged to utilize the standard approach via [CMAKE_MSVC_RUNTIME_LIBRARY](https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html).
12
13# Glslang Components and Status
14
15There are several components:
16
17### Reference Validator and GLSL/ESSL -> AST Front End
18
19An OpenGL GLSL and OpenGL|ES GLSL (ESSL) front-end for reference validation and translation of GLSL/ESSL into an internal abstract syntax tree (AST).
20
21**Status**: Virtually complete, with results carrying similar weight as the specifications.
22
23### HLSL -> AST Front End
24
25An HLSL front-end for translation of an approximation of HLSL to glslang's AST form.
26
27**Status**: Partially complete. Semantics are not reference quality and input is not validated.
28This is in contrast to the [DXC project](https://github.com/Microsoft/DirectXShaderCompiler), which receives a much larger investment and attempts to have definitive/reference-level semantics.
29
30See [issue 362](https://github.com/KhronosGroup/glslang/issues/362) and [issue 701](https://github.com/KhronosGroup/glslang/issues/701) for current status.
31
32### AST -> SPIR-V Back End
33
34Translates glslang's AST to the Khronos-specified SPIR-V intermediate language.
35
36**Status**: Virtually complete.
37
38### Reflector
39
40An API for getting reflection information from the AST, reflection types/variables/etc. from the HLL source (not the SPIR-V).
41
42**Status**: There is a large amount of functionality present, but no specification/goal to measure completeness against.  It is accurate for the input HLL and AST, but only approximate for what would later be emitted for SPIR-V.
43
44### Standalone Wrapper
45
46`glslang` is command-line tool for accessing the functionality above.
47
48Status: Complete.
49
50Tasks waiting to be done are documented as GitHub issues.
51
52## Other References
53
54Also see the Khronos landing page for glslang as a reference front end:
55
56https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/
57
58The above page, while not kept up to date, includes additional information regarding glslang as a reference validator.
59
60# How to Use Glslang
61
62## Execution of Standalone Wrapper
63
64To use the standalone binary form, execute `glslang`, and it will print
65a usage statement.  Basic operation is to give it a file containing a shader,
66and it will print out warnings/errors and optionally an AST.
67
68The applied stage-specific rules are based on the file extension:
69* `.vert` for a vertex shader
70* `.tesc` for a tessellation control shader
71* `.tese` for a tessellation evaluation shader
72* `.geom` for a geometry shader
73* `.frag` for a fragment shader
74* `.comp` for a compute shader
75
76For ray tracing pipeline shaders:
77* `.rgen` for a ray generation shader
78* `.rint` for a ray intersection shader
79* `.rahit` for a ray any-hit shader
80* `.rchit` for a ray closest-hit shader
81* `.rmiss` for a ray miss shader
82* `.rcall` for a callable shader
83
84There is also a non-shader extension:
85* `.conf` for a configuration file of limits, see usage statement for example
86
87## Building (CMake)
88
89Instead of building manually, you can also download the binaries for your
90platform directly from the [main-tot release][main-tot-release] on GitHub.
91Those binaries are automatically uploaded by the buildbots after successful
92testing and they always reflect the current top of the tree of the main
93branch.
94
95### Dependencies
96
97* A C++17 compiler.
98  (For MSVS: use 2019 or later.)
99* [CMake][cmake]: for generating compilation targets.
100* make: _Linux_, ninja is an alternative, if configured.
101* [Python 3.x][python]: for executing SPIRV-Tools scripts. (Optional if not using SPIRV-Tools and the 'External' subdirectory does not exist.)
102* [bison][bison]: _optional_, but needed when changing the grammar (glslang.y).
103* [googletest][googletest]: _optional_, but should use if making any changes to glslang.
104
105### Build steps
106
107The following steps assume a Bash shell. On Windows, that could be the Git Bash
108shell or some other shell of your choosing.
109
110#### 1) Check-Out this project
111
112```bash
113cd <parent of where you want glslang to be>
114git clone https://github.com/KhronosGroup/glslang.git
115```
116
117#### 2) Check-Out External Projects
118
119```bash
120./update_glslang_sources.py
121```
122
123#### 3) Configure
124
125Assume the source directory is `$SOURCE_DIR` and the build directory is
126`$BUILD_DIR`. First ensure the build directory exists, then navigate to it:
127
128```bash
129mkdir -p $BUILD_DIR
130cd $BUILD_DIR
131```
132
133For building on Linux:
134
135```bash
136cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/install" $SOURCE_DIR
137# "Release" (for CMAKE_BUILD_TYPE) could also be "Debug" or "RelWithDebInfo"
138```
139
140For building on Android:
141```bash
142cmake $SOURCE_DIR -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DANDROID_ABI=arm64-v8a -DCMAKE_BUILD_TYPE=Release -DANDROID_STL=c++_static -DANDROID_PLATFORM=android-24 -DCMAKE_SYSTEM_NAME=Android -DANDROID_TOOLCHAIN=clang -DANDROID_ARM_MODE=arm -DCMAKE_MAKE_PROGRAM=$ANDROID_NDK_HOME/prebuilt/linux-x86_64/bin/make -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake
143# If on Windows will be -DCMAKE_MAKE_PROGRAM=%ANDROID_NDK_HOME%\prebuilt\windows-x86_64\bin\make.exe
144# -G is needed for building on Windows
145# -DANDROID_ABI can also be armeabi-v7a for 32 bit
146```
147
148For building on Windows:
149
150```bash
151cmake $SOURCE_DIR -DCMAKE_INSTALL_PREFIX="$(pwd)/install"
152# The CMAKE_INSTALL_PREFIX part is for testing (explained later).
153```
154
155The CMake GUI also works for Windows (version 3.4.1 tested).
156
157Also, consider using `git config --global core.fileMode false` (or with `--local`) on Windows
158to prevent the addition of execution permission on files.
159
160#### 4) Build and Install
161
162```bash
163# for Linux:
164make -j4 install
165
166# for Windows:
167cmake --build . --config Release --target install
168# "Release" (for --config) could also be "Debug", "MinSizeRel", or "RelWithDebInfo"
169```
170
171If using MSVC, after running CMake to configure, use the
172Configuration Manager to check the `INSTALL` project.
173
174If you want to enable testing via CMake set `GLSLANG_TESTS=ON` when configuring the build.
175
176`GLSLANG_TESTS` is off by default to streamline the packaging / Vulkan SDK process.
177
178### Building (GN)
179
180glslang can also be built with the [GN build system](https://gn.googlesource.com/gn/).
181
182#### 1) Install `depot_tools`
183
184Download [depot_tools.zip](https://storage.googleapis.com/chrome-infra/depot_tools.zip),
185extract to a directory, and add this directory to your `PATH`.
186
187#### 2) Synchronize dependencies and generate build files
188
189This only needs to be done once after updating `glslang`.
190
191With the current directory set to your `glslang` checkout, type:
192
193```bash
194./update_glslang_sources.py
195gclient sync --gclientfile=standalone.gclient
196gn gen out/Default
197```
198
199#### 3) Build
200
201With the current directory set to your `glslang` checkout, type:
202
203```bash
204cd out/Default
205ninja
206```
207
208### If you need to change the GLSL grammar
209
210The grammar in `glslang/MachineIndependent/glslang.y` has to be recompiled with
211bison if it changes, the output files are committed to the repo to avoid every
212developer needing to have bison configured to compile the project when grammar
213changes are quite infrequent. For windows you can get binaries from
214[GnuWin32][bison-gnu-win32].
215
216The command to rebuild is:
217
218```bash
219bison --defines=MachineIndependent/glslang_tab.cpp.h
220      -t MachineIndependent/glslang.y
221      -o MachineIndependent/glslang_tab.cpp
222```
223
224The above command is also available in the bash script in `updateGrammar`,
225when executed from the glslang subdirectory of the glslang repository.
226
227### Building to WASM for the Web and Node
228### Building a standalone JS/WASM library for the Web and Node
229
230Use the steps in [Build Steps](#build-steps), with the following notes/exceptions:
231* `emsdk` needs to be present in your executable search path, *PATH* for
232  Bash-like environments:
233  + [Instructions located here](https://emscripten.org/docs/getting_started/downloads.html#sdk-download-and-install)
234* Wrap cmake call: `emcmake cmake`
235* Set `-DENABLE_OPT=OFF`.
236* Set `-DENABLE_HLSL=OFF` if HLSL is not needed.
237* For a standalone JS/WASM library, turn on `-DENABLE_GLSLANG_JS=ON`.
238* To get a fully minimized build, make sure to use `brotli` to compress the .js
239  and .wasm files
240* Note that by default, Emscripten allocates a very small stack size, which may
241  cause stack overflows when compiling large shaders. Use the
242  [STACK_SIZE](https://emscripten.org/docs/tools_reference/settings_reference.html?highlight=environment#stack-size)
243  compiler setting to increase the stack size.
244
245Example:
246
247```sh
248emcmake cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GLSLANG_JS=ON \
249    -DENABLE_HLSL=OFF -DENABLE_OPT=OFF ..
250```
251
252## Building glslang - Using vcpkg
253
254You can download and install glslang using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
255
256    git clone https://github.com/Microsoft/vcpkg.git
257    cd vcpkg
258    ./bootstrap-vcpkg.sh
259    ./vcpkg integrate install
260    ./vcpkg install glslang
261
262The glslang port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
263
264## Testing
265
266Right now, there are two test harnesses existing in glslang: one is [Google
267Test](gtests/), one is the [`runtests` script](Test/runtests). The former
268runs unit tests and single-shader single-threaded integration tests, while
269the latter runs multiple-shader linking tests and multi-threaded tests.
270
271Tests may erroneously fail or pass if using `ALLOW_EXTERNAL_SPIRV_TOOLS` with
272any commit other than the one specified in `known_good.json`.
273
274### Running tests
275
276The [`runtests` script](Test/runtests) requires compiled binaries to be
277installed into `$BUILD_DIR/install`. Please make sure you have supplied the
278correct configuration to CMake (using `-DCMAKE_INSTALL_PREFIX`) when building;
279otherwise, you may want to modify the path in the `runtests` script.
280
281Running Google Test-backed tests:
282
283```bash
284cd $BUILD_DIR
285
286# for Linux:
287ctest
288
289# for Windows:
290ctest -C {Debug|Release|RelWithDebInfo|MinSizeRel}
291
292# or, run the test binary directly
293# (which gives more fine-grained control like filtering):
294<dir-to-glslangtests-in-build-dir>/glslangtests
295```
296
297Running `runtests` script-backed tests:
298
299```bash
300cd $SOURCE_DIR/Test && ./runtests
301```
302
303If some tests fail with validation errors, there may be a mismatch between the
304version of `spirv-val` on the system and the version of glslang.  In this
305case, it is necessary to run `update_glslang_sources.py`.  See "Check-Out
306External Projects" above for more details.
307
308### Contributing tests
309
310Test results should always be included with a pull request that modifies
311functionality.
312
313If you are writing unit tests, please use the Google Test framework and
314place the tests under the `gtests/` directory.
315
316Integration tests are placed in the `Test/` directory. It contains test input
317and a subdirectory `baseResults/` that contains the expected results of the
318tests.  Both the tests and `baseResults/` are under source-code control.
319
320Google Test runs those integration tests by reading the test input, compiling
321them, and then compare against the expected results in `baseResults/`. The
322integration tests to run via Google Test is registered in various
323`gtests/*.FromFile.cpp` source files. `glslangtests` provides a command-line
324option `--update-mode`, which, if supplied, will overwrite the golden files
325under the `baseResults/` directory with real output from that invocation.
326For more information, please check `gtests/` directory's
327[README](gtests/README.md).
328
329For the `runtests` script, it will generate current results in the
330`localResults/` directory and `diff` them against the `baseResults/`.
331When you want to update the tracked test results, they need to be
332copied from `localResults/` to `baseResults/`.  This can be done by
333the `bump` shell script.
334
335You can add your own private list of tests, not tracked publicly, by using
336`localtestlist` to list non-tracked tests.  This is automatically read
337by `runtests` and included in the `diff` and `bump` process.
338
339## Programmatic Interfaces
340
341Another piece of software can programmatically translate shaders to an AST
342using one of two different interfaces:
343* A new C++ class-oriented interface, or
344* The original C functional interface
345
346The `main()` in `StandAlone/StandAlone.cpp` shows examples using both styles.
347
348### C++ Class Interface (new, preferred)
349
350This interface is in roughly the last 1/3 of `ShaderLang.h`.  It is in the
351glslang namespace and contains the following, here with suggested calls
352for generating SPIR-V:
353
354```cxx
355const char* GetEsslVersionString();
356const char* GetGlslVersionString();
357bool InitializeProcess();
358void FinalizeProcess();
359
360class TShader
361    setStrings(...);
362    setEnvInput(EShSourceHlsl or EShSourceGlsl, stage,  EShClientVulkan or EShClientOpenGL, 100);
363    setEnvClient(EShClientVulkan or EShClientOpenGL, EShTargetVulkan_1_0 or EShTargetVulkan_1_1 or EShTargetOpenGL_450);
364    setEnvTarget(EShTargetSpv, EShTargetSpv_1_0 or EShTargetSpv_1_3);
365    bool parse(...);
366    const char* getInfoLog();
367
368class TProgram
369    void addShader(...);
370    bool link(...);
371    const char* getInfoLog();
372    Reflection queries
373```
374
375For just validating (not generating code), substitute these calls:
376
377```cxx
378    setEnvInput(EShSourceHlsl or EShSourceGlsl, stage,  EShClientNone, 0);
379    setEnvClient(EShClientNone, 0);
380    setEnvTarget(EShTargetNone, 0);
381```
382
383See `ShaderLang.h` and the usage of it in `StandAlone/StandAlone.cpp` for more
384details. There is a block comment giving more detail above the calls for
385`setEnvInput, setEnvClient, and setEnvTarget`.
386
387### C Functional Interface (original)
388
389This interface is in roughly the first 2/3 of `ShaderLang.h`, and referred to
390as the `Sh*()` interface, as all the entry points start `Sh`.
391
392The `Sh*()` interface takes a "compiler" call-back object, which it calls after
393building call back that is passed the AST and can then execute a back end on it.
394
395The following is a simplified resulting run-time call stack:
396
397```c
398ShCompile(shader, compiler) -> compiler(AST) -> <back end>
399```
400
401In practice, `ShCompile()` takes shader strings, default version, and
402warning/error and other options for controlling compilation.
403
404### C Functional Interface (new)
405
406This interface is located `glslang_c_interface.h` and exposes functionality similar to the C++ interface. The following snippet is a complete example showing how to compile GLSL into SPIR-V 1.5 for Vulkan 1.2.
407
408```c
409#include <glslang/Include/glslang_c_interface.h>
410
411// Required for use of glslang_default_resource
412#include <glslang/Public/resource_limits_c.h>
413
414typedef struct SpirVBinary {
415    uint32_t *words; // SPIR-V words
416    int size; // number of words in SPIR-V binary
417} SpirVBinary;
418
419SpirVBinary compileShaderToSPIRV_Vulkan(glslang_stage_t stage, const char* shaderSource, const char* fileName) {
420    const glslang_input_t input = {
421        .language = GLSLANG_SOURCE_GLSL,
422        .stage = stage,
423        .client = GLSLANG_CLIENT_VULKAN,
424        .client_version = GLSLANG_TARGET_VULKAN_1_2,
425        .target_language = GLSLANG_TARGET_SPV,
426        .target_language_version = GLSLANG_TARGET_SPV_1_5,
427        .code = shaderSource,
428        .default_version = 100,
429        .default_profile = GLSLANG_NO_PROFILE,
430        .force_default_version_and_profile = false,
431        .forward_compatible = false,
432        .messages = GLSLANG_MSG_DEFAULT_BIT,
433        .resource = glslang_default_resource(),
434    };
435
436    glslang_shader_t* shader = glslang_shader_create(&input);
437
438    SpirVBinary bin = {
439        .words = NULL,
440        .size = 0,
441    };
442    if (!glslang_shader_preprocess(shader, &input))	{
443        printf("GLSL preprocessing failed %s\n", fileName);
444        printf("%s\n", glslang_shader_get_info_log(shader));
445        printf("%s\n", glslang_shader_get_info_debug_log(shader));
446        printf("%s\n", input.code);
447        glslang_shader_delete(shader);
448        return bin;
449    }
450
451    if (!glslang_shader_parse(shader, &input)) {
452        printf("GLSL parsing failed %s\n", fileName);
453        printf("%s\n", glslang_shader_get_info_log(shader));
454        printf("%s\n", glslang_shader_get_info_debug_log(shader));
455        printf("%s\n", glslang_shader_get_preprocessed_code(shader));
456        glslang_shader_delete(shader);
457        return bin;
458    }
459
460    glslang_program_t* program = glslang_program_create();
461    glslang_program_add_shader(program, shader);
462
463    if (!glslang_program_link(program, GLSLANG_MSG_SPV_RULES_BIT | GLSLANG_MSG_VULKAN_RULES_BIT)) {
464        printf("GLSL linking failed %s\n", fileName);
465        printf("%s\n", glslang_program_get_info_log(program));
466        printf("%s\n", glslang_program_get_info_debug_log(program));
467        glslang_program_delete(program);
468        glslang_shader_delete(shader);
469        return bin;
470    }
471
472    glslang_program_SPIRV_generate(program, stage);
473
474    bin.size = glslang_program_SPIRV_get_size(program);
475    bin.words = malloc(bin.size * sizeof(uint32_t));
476    glslang_program_SPIRV_get(program, bin.words);
477
478    const char* spirv_messages = glslang_program_SPIRV_get_messages(program);
479    if (spirv_messages)
480        printf("(%s) %s\b", fileName, spirv_messages);
481
482    glslang_program_delete(program);
483    glslang_shader_delete(shader);
484
485    return bin;
486}
487```
488
489## Basic Internal Operation
490
491* Initial lexical analysis is done by the preprocessor in
492  `MachineIndependent/Preprocessor`, and then refined by a GLSL scanner
493  in `MachineIndependent/Scan.cpp`.  There is currently no use of flex.
494
495* Code is parsed using bison on `MachineIndependent/glslang.y` with the
496  aid of a symbol table and an AST.  The symbol table is not passed on to
497  the back-end; the intermediate representation stands on its own.
498  The tree is built by the grammar productions, many of which are
499  offloaded into `ParseHelper.cpp`, and by `Intermediate.cpp`.
500
501* The intermediate representation is very high-level, and represented
502  as an in-memory tree.   This serves to lose no information from the
503  original program, and to have efficient transfer of the result from
504  parsing to the back-end.  In the AST, constants are propagated and
505  folded, and a very small amount of dead code is eliminated.
506
507  To aid linking and reflection, the last top-level branch in the AST
508  lists all global symbols.
509
510* The primary algorithm of the back-end compiler is to traverse the
511  tree (high-level intermediate representation), and create an internal
512  object code representation.  There is an example of how to do this
513  in `MachineIndependent/intermOut.cpp`.
514
515* Reduction of the tree to a linear byte-code style low-level intermediate
516  representation is likely a good way to generate fully optimized code.
517
518* There is currently some dead old-style linker-type code still lying around.
519
520* Memory pool: parsing uses types derived from C++ `std` types, using a
521  custom allocator that puts them in a memory pool.  This makes allocation
522  of individual container/contents just few cycles and deallocation free.
523  This pool is popped after the AST is made and processed.
524
525  The use is simple: if you are going to call `new`, there are three cases:
526
527  - the object comes from the pool (its base class has the macro
528    `POOL_ALLOCATOR_NEW_DELETE` in it) and you do not have to call `delete`
529
530  - it is a `TString`, in which case call `NewPoolTString()`, which gets
531    it from the pool, and there is no corresponding `delete`
532
533  - the object does not come from the pool, and you have to do normal
534    C++ memory management of what you `new`
535
536* Features can be protected by version/extension/stage/profile:
537  See the comment in `glslang/MachineIndependent/Versions.cpp`.
538
539[cmake]: https://cmake.org/
540[python]: https://www.python.org/
541[bison]: https://www.gnu.org/software/bison/
542[googletest]: https://github.com/google/googletest
543[bison-gnu-win32]: http://gnuwin32.sourceforge.net/packages/bison.htm
544[main-tot-release]: https://github.com/KhronosGroup/glslang/releases/tag/main-tot
545