1617a3babSopenharmony_ci![Continuous Integration](https://github.com/KhronosGroup/glslang/actions/workflows/continuous_integration.yml/badge.svg)
2617a3babSopenharmony_ci![Continuous Deployment](https://github.com/KhronosGroup/glslang/actions/workflows/continuous_deployment.yml/badge.svg)
3617a3babSopenharmony_ci[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/KhronosGroup/glslang/badge)](https://securityscorecards.dev/viewer/?uri=github.com/KhronosGroup/glslang)
4617a3babSopenharmony_ci
5617a3babSopenharmony_ci# News
6617a3babSopenharmony_ci
7617a3babSopenharmony_ci1. `OGLCompiler` and `HLSL` stub libraries have been fully removed from the build.
8617a3babSopenharmony_ci
9617a3babSopenharmony_ci2. `OVERRIDE_MSVCCRT` has been removed in favor of `CMAKE_MSVC_RUNTIME_LIBRARY`
10617a3babSopenharmony_ci
11617a3babSopenharmony_ciUsers are encouraged to utilize the standard approach via [CMAKE_MSVC_RUNTIME_LIBRARY](https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html).
12617a3babSopenharmony_ci
13617a3babSopenharmony_ci# Glslang Components and Status
14617a3babSopenharmony_ci
15617a3babSopenharmony_ciThere are several components:
16617a3babSopenharmony_ci
17617a3babSopenharmony_ci### Reference Validator and GLSL/ESSL -> AST Front End
18617a3babSopenharmony_ci
19617a3babSopenharmony_ciAn OpenGL GLSL and OpenGL|ES GLSL (ESSL) front-end for reference validation and translation of GLSL/ESSL into an internal abstract syntax tree (AST).
20617a3babSopenharmony_ci
21617a3babSopenharmony_ci**Status**: Virtually complete, with results carrying similar weight as the specifications.
22617a3babSopenharmony_ci
23617a3babSopenharmony_ci### HLSL -> AST Front End
24617a3babSopenharmony_ci
25617a3babSopenharmony_ciAn HLSL front-end for translation of an approximation of HLSL to glslang's AST form.
26617a3babSopenharmony_ci
27617a3babSopenharmony_ci**Status**: Partially complete. Semantics are not reference quality and input is not validated.
28617a3babSopenharmony_ciThis 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.
29617a3babSopenharmony_ci
30617a3babSopenharmony_ciSee [issue 362](https://github.com/KhronosGroup/glslang/issues/362) and [issue 701](https://github.com/KhronosGroup/glslang/issues/701) for current status.
31617a3babSopenharmony_ci
32617a3babSopenharmony_ci### AST -> SPIR-V Back End
33617a3babSopenharmony_ci
34617a3babSopenharmony_ciTranslates glslang's AST to the Khronos-specified SPIR-V intermediate language.
35617a3babSopenharmony_ci
36617a3babSopenharmony_ci**Status**: Virtually complete.
37617a3babSopenharmony_ci
38617a3babSopenharmony_ci### Reflector
39617a3babSopenharmony_ci
40617a3babSopenharmony_ciAn API for getting reflection information from the AST, reflection types/variables/etc. from the HLL source (not the SPIR-V).
41617a3babSopenharmony_ci
42617a3babSopenharmony_ci**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.
43617a3babSopenharmony_ci
44617a3babSopenharmony_ci### Standalone Wrapper
45617a3babSopenharmony_ci
46617a3babSopenharmony_ci`glslang` is command-line tool for accessing the functionality above.
47617a3babSopenharmony_ci
48617a3babSopenharmony_ciStatus: Complete.
49617a3babSopenharmony_ci
50617a3babSopenharmony_ciTasks waiting to be done are documented as GitHub issues.
51617a3babSopenharmony_ci
52617a3babSopenharmony_ci## Other References
53617a3babSopenharmony_ci
54617a3babSopenharmony_ciAlso see the Khronos landing page for glslang as a reference front end:
55617a3babSopenharmony_ci
56617a3babSopenharmony_cihttps://www.khronos.org/opengles/sdk/tools/Reference-Compiler/
57617a3babSopenharmony_ci
58617a3babSopenharmony_ciThe above page, while not kept up to date, includes additional information regarding glslang as a reference validator.
59617a3babSopenharmony_ci
60617a3babSopenharmony_ci# How to Use Glslang
61617a3babSopenharmony_ci
62617a3babSopenharmony_ci## Execution of Standalone Wrapper
63617a3babSopenharmony_ci
64617a3babSopenharmony_ciTo use the standalone binary form, execute `glslang`, and it will print
65617a3babSopenharmony_cia usage statement.  Basic operation is to give it a file containing a shader,
66617a3babSopenharmony_ciand it will print out warnings/errors and optionally an AST.
67617a3babSopenharmony_ci
68617a3babSopenharmony_ciThe applied stage-specific rules are based on the file extension:
69617a3babSopenharmony_ci* `.vert` for a vertex shader
70617a3babSopenharmony_ci* `.tesc` for a tessellation control shader
71617a3babSopenharmony_ci* `.tese` for a tessellation evaluation shader
72617a3babSopenharmony_ci* `.geom` for a geometry shader
73617a3babSopenharmony_ci* `.frag` for a fragment shader
74617a3babSopenharmony_ci* `.comp` for a compute shader
75617a3babSopenharmony_ci
76617a3babSopenharmony_ciFor ray tracing pipeline shaders:
77617a3babSopenharmony_ci* `.rgen` for a ray generation shader
78617a3babSopenharmony_ci* `.rint` for a ray intersection shader
79617a3babSopenharmony_ci* `.rahit` for a ray any-hit shader
80617a3babSopenharmony_ci* `.rchit` for a ray closest-hit shader
81617a3babSopenharmony_ci* `.rmiss` for a ray miss shader
82617a3babSopenharmony_ci* `.rcall` for a callable shader
83617a3babSopenharmony_ci
84617a3babSopenharmony_ciThere is also a non-shader extension:
85617a3babSopenharmony_ci* `.conf` for a configuration file of limits, see usage statement for example
86617a3babSopenharmony_ci
87617a3babSopenharmony_ci## Building (CMake)
88617a3babSopenharmony_ci
89617a3babSopenharmony_ciInstead of building manually, you can also download the binaries for your
90617a3babSopenharmony_ciplatform directly from the [main-tot release][main-tot-release] on GitHub.
91617a3babSopenharmony_ciThose binaries are automatically uploaded by the buildbots after successful
92617a3babSopenharmony_citesting and they always reflect the current top of the tree of the main
93617a3babSopenharmony_cibranch.
94617a3babSopenharmony_ci
95617a3babSopenharmony_ci### Dependencies
96617a3babSopenharmony_ci
97617a3babSopenharmony_ci* A C++17 compiler.
98617a3babSopenharmony_ci  (For MSVS: use 2019 or later.)
99617a3babSopenharmony_ci* [CMake][cmake]: for generating compilation targets.
100617a3babSopenharmony_ci* make: _Linux_, ninja is an alternative, if configured.
101617a3babSopenharmony_ci* [Python 3.x][python]: for executing SPIRV-Tools scripts. (Optional if not using SPIRV-Tools and the 'External' subdirectory does not exist.)
102617a3babSopenharmony_ci* [bison][bison]: _optional_, but needed when changing the grammar (glslang.y).
103617a3babSopenharmony_ci* [googletest][googletest]: _optional_, but should use if making any changes to glslang.
104617a3babSopenharmony_ci
105617a3babSopenharmony_ci### Build steps
106617a3babSopenharmony_ci
107617a3babSopenharmony_ciThe following steps assume a Bash shell. On Windows, that could be the Git Bash
108617a3babSopenharmony_cishell or some other shell of your choosing.
109617a3babSopenharmony_ci
110617a3babSopenharmony_ci#### 1) Check-Out this project
111617a3babSopenharmony_ci
112617a3babSopenharmony_ci```bash
113617a3babSopenharmony_cicd <parent of where you want glslang to be>
114617a3babSopenharmony_cigit clone https://github.com/KhronosGroup/glslang.git
115617a3babSopenharmony_ci```
116617a3babSopenharmony_ci
117617a3babSopenharmony_ci#### 2) Check-Out External Projects
118617a3babSopenharmony_ci
119617a3babSopenharmony_ci```bash
120617a3babSopenharmony_ci./update_glslang_sources.py
121617a3babSopenharmony_ci```
122617a3babSopenharmony_ci
123617a3babSopenharmony_ci#### 3) Configure
124617a3babSopenharmony_ci
125617a3babSopenharmony_ciAssume the source directory is `$SOURCE_DIR` and the build directory is
126617a3babSopenharmony_ci`$BUILD_DIR`. First ensure the build directory exists, then navigate to it:
127617a3babSopenharmony_ci
128617a3babSopenharmony_ci```bash
129617a3babSopenharmony_cimkdir -p $BUILD_DIR
130617a3babSopenharmony_cicd $BUILD_DIR
131617a3babSopenharmony_ci```
132617a3babSopenharmony_ci
133617a3babSopenharmony_ciFor building on Linux:
134617a3babSopenharmony_ci
135617a3babSopenharmony_ci```bash
136617a3babSopenharmony_cicmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/install" $SOURCE_DIR
137617a3babSopenharmony_ci# "Release" (for CMAKE_BUILD_TYPE) could also be "Debug" or "RelWithDebInfo"
138617a3babSopenharmony_ci```
139617a3babSopenharmony_ci
140617a3babSopenharmony_ciFor building on Android:
141617a3babSopenharmony_ci```bash
142617a3babSopenharmony_cicmake $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
143617a3babSopenharmony_ci# If on Windows will be -DCMAKE_MAKE_PROGRAM=%ANDROID_NDK_HOME%\prebuilt\windows-x86_64\bin\make.exe
144617a3babSopenharmony_ci# -G is needed for building on Windows
145617a3babSopenharmony_ci# -DANDROID_ABI can also be armeabi-v7a for 32 bit
146617a3babSopenharmony_ci```
147617a3babSopenharmony_ci
148617a3babSopenharmony_ciFor building on Windows:
149617a3babSopenharmony_ci
150617a3babSopenharmony_ci```bash
151617a3babSopenharmony_cicmake $SOURCE_DIR -DCMAKE_INSTALL_PREFIX="$(pwd)/install"
152617a3babSopenharmony_ci# The CMAKE_INSTALL_PREFIX part is for testing (explained later).
153617a3babSopenharmony_ci```
154617a3babSopenharmony_ci
155617a3babSopenharmony_ciThe CMake GUI also works for Windows (version 3.4.1 tested).
156617a3babSopenharmony_ci
157617a3babSopenharmony_ciAlso, consider using `git config --global core.fileMode false` (or with `--local`) on Windows
158617a3babSopenharmony_cito prevent the addition of execution permission on files.
159617a3babSopenharmony_ci
160617a3babSopenharmony_ci#### 4) Build and Install
161617a3babSopenharmony_ci
162617a3babSopenharmony_ci```bash
163617a3babSopenharmony_ci# for Linux:
164617a3babSopenharmony_cimake -j4 install
165617a3babSopenharmony_ci
166617a3babSopenharmony_ci# for Windows:
167617a3babSopenharmony_cicmake --build . --config Release --target install
168617a3babSopenharmony_ci# "Release" (for --config) could also be "Debug", "MinSizeRel", or "RelWithDebInfo"
169617a3babSopenharmony_ci```
170617a3babSopenharmony_ci
171617a3babSopenharmony_ciIf using MSVC, after running CMake to configure, use the
172617a3babSopenharmony_ciConfiguration Manager to check the `INSTALL` project.
173617a3babSopenharmony_ci
174617a3babSopenharmony_ciIf you want to enable testing via CMake set `GLSLANG_TESTS=ON` when configuring the build.
175617a3babSopenharmony_ci
176617a3babSopenharmony_ci`GLSLANG_TESTS` is off by default to streamline the packaging / Vulkan SDK process.
177617a3babSopenharmony_ci
178617a3babSopenharmony_ci### Building (GN)
179617a3babSopenharmony_ci
180617a3babSopenharmony_ciglslang can also be built with the [GN build system](https://gn.googlesource.com/gn/).
181617a3babSopenharmony_ci
182617a3babSopenharmony_ci#### 1) Install `depot_tools`
183617a3babSopenharmony_ci
184617a3babSopenharmony_ciDownload [depot_tools.zip](https://storage.googleapis.com/chrome-infra/depot_tools.zip),
185617a3babSopenharmony_ciextract to a directory, and add this directory to your `PATH`.
186617a3babSopenharmony_ci
187617a3babSopenharmony_ci#### 2) Synchronize dependencies and generate build files
188617a3babSopenharmony_ci
189617a3babSopenharmony_ciThis only needs to be done once after updating `glslang`.
190617a3babSopenharmony_ci
191617a3babSopenharmony_ciWith the current directory set to your `glslang` checkout, type:
192617a3babSopenharmony_ci
193617a3babSopenharmony_ci```bash
194617a3babSopenharmony_ci./update_glslang_sources.py
195617a3babSopenharmony_cigclient sync --gclientfile=standalone.gclient
196617a3babSopenharmony_cign gen out/Default
197617a3babSopenharmony_ci```
198617a3babSopenharmony_ci
199617a3babSopenharmony_ci#### 3) Build
200617a3babSopenharmony_ci
201617a3babSopenharmony_ciWith the current directory set to your `glslang` checkout, type:
202617a3babSopenharmony_ci
203617a3babSopenharmony_ci```bash
204617a3babSopenharmony_cicd out/Default
205617a3babSopenharmony_cininja
206617a3babSopenharmony_ci```
207617a3babSopenharmony_ci
208617a3babSopenharmony_ci### If you need to change the GLSL grammar
209617a3babSopenharmony_ci
210617a3babSopenharmony_ciThe grammar in `glslang/MachineIndependent/glslang.y` has to be recompiled with
211617a3babSopenharmony_cibison if it changes, the output files are committed to the repo to avoid every
212617a3babSopenharmony_cideveloper needing to have bison configured to compile the project when grammar
213617a3babSopenharmony_cichanges are quite infrequent. For windows you can get binaries from
214617a3babSopenharmony_ci[GnuWin32][bison-gnu-win32].
215617a3babSopenharmony_ci
216617a3babSopenharmony_ciThe command to rebuild is:
217617a3babSopenharmony_ci
218617a3babSopenharmony_ci```bash
219617a3babSopenharmony_cibison --defines=MachineIndependent/glslang_tab.cpp.h
220617a3babSopenharmony_ci      -t MachineIndependent/glslang.y
221617a3babSopenharmony_ci      -o MachineIndependent/glslang_tab.cpp
222617a3babSopenharmony_ci```
223617a3babSopenharmony_ci
224617a3babSopenharmony_ciThe above command is also available in the bash script in `updateGrammar`,
225617a3babSopenharmony_ciwhen executed from the glslang subdirectory of the glslang repository.
226617a3babSopenharmony_ci
227617a3babSopenharmony_ci### Building to WASM for the Web and Node
228617a3babSopenharmony_ci### Building a standalone JS/WASM library for the Web and Node
229617a3babSopenharmony_ci
230617a3babSopenharmony_ciUse the steps in [Build Steps](#build-steps), with the following notes/exceptions:
231617a3babSopenharmony_ci* `emsdk` needs to be present in your executable search path, *PATH* for
232617a3babSopenharmony_ci  Bash-like environments:
233617a3babSopenharmony_ci  + [Instructions located here](https://emscripten.org/docs/getting_started/downloads.html#sdk-download-and-install)
234617a3babSopenharmony_ci* Wrap cmake call: `emcmake cmake`
235617a3babSopenharmony_ci* Set `-DENABLE_OPT=OFF`.
236617a3babSopenharmony_ci* Set `-DENABLE_HLSL=OFF` if HLSL is not needed.
237617a3babSopenharmony_ci* For a standalone JS/WASM library, turn on `-DENABLE_GLSLANG_JS=ON`.
238617a3babSopenharmony_ci* To get a fully minimized build, make sure to use `brotli` to compress the .js
239617a3babSopenharmony_ci  and .wasm files
240617a3babSopenharmony_ci
241617a3babSopenharmony_ciExample:
242617a3babSopenharmony_ci
243617a3babSopenharmony_ci```sh
244617a3babSopenharmony_ciemcmake cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GLSLANG_JS=ON \
245617a3babSopenharmony_ci    -DENABLE_HLSL=OFF -DENABLE_OPT=OFF ..
246617a3babSopenharmony_ci```
247617a3babSopenharmony_ci
248617a3babSopenharmony_ci## Building glslang - Using vcpkg
249617a3babSopenharmony_ci
250617a3babSopenharmony_ciYou can download and install glslang using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
251617a3babSopenharmony_ci
252617a3babSopenharmony_ci    git clone https://github.com/Microsoft/vcpkg.git
253617a3babSopenharmony_ci    cd vcpkg
254617a3babSopenharmony_ci    ./bootstrap-vcpkg.sh
255617a3babSopenharmony_ci    ./vcpkg integrate install
256617a3babSopenharmony_ci    ./vcpkg install glslang
257617a3babSopenharmony_ci
258617a3babSopenharmony_ciThe 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.
259617a3babSopenharmony_ci
260617a3babSopenharmony_ci## Testing
261617a3babSopenharmony_ci
262617a3babSopenharmony_ciRight now, there are two test harnesses existing in glslang: one is [Google
263617a3babSopenharmony_ciTest](gtests/), one is the [`runtests` script](Test/runtests). The former
264617a3babSopenharmony_ciruns unit tests and single-shader single-threaded integration tests, while
265617a3babSopenharmony_cithe latter runs multiple-shader linking tests and multi-threaded tests.
266617a3babSopenharmony_ci
267617a3babSopenharmony_ci### Running tests
268617a3babSopenharmony_ci
269617a3babSopenharmony_ciThe [`runtests` script](Test/runtests) requires compiled binaries to be
270617a3babSopenharmony_ciinstalled into `$BUILD_DIR/install`. Please make sure you have supplied the
271617a3babSopenharmony_cicorrect configuration to CMake (using `-DCMAKE_INSTALL_PREFIX`) when building;
272617a3babSopenharmony_ciotherwise, you may want to modify the path in the `runtests` script.
273617a3babSopenharmony_ci
274617a3babSopenharmony_ciRunning Google Test-backed tests:
275617a3babSopenharmony_ci
276617a3babSopenharmony_ci```bash
277617a3babSopenharmony_cicd $BUILD_DIR
278617a3babSopenharmony_ci
279617a3babSopenharmony_ci# for Linux:
280617a3babSopenharmony_cictest
281617a3babSopenharmony_ci
282617a3babSopenharmony_ci# for Windows:
283617a3babSopenharmony_cictest -C {Debug|Release|RelWithDebInfo|MinSizeRel}
284617a3babSopenharmony_ci
285617a3babSopenharmony_ci# or, run the test binary directly
286617a3babSopenharmony_ci# (which gives more fine-grained control like filtering):
287617a3babSopenharmony_ci<dir-to-glslangtests-in-build-dir>/glslangtests
288617a3babSopenharmony_ci```
289617a3babSopenharmony_ci
290617a3babSopenharmony_ciRunning `runtests` script-backed tests:
291617a3babSopenharmony_ci
292617a3babSopenharmony_ci```bash
293617a3babSopenharmony_cicd $SOURCE_DIR/Test && ./runtests
294617a3babSopenharmony_ci```
295617a3babSopenharmony_ci
296617a3babSopenharmony_ciIf some tests fail with validation errors, there may be a mismatch between the
297617a3babSopenharmony_civersion of `spirv-val` on the system and the version of glslang.  In this
298617a3babSopenharmony_cicase, it is necessary to run `update_glslang_sources.py`.  See "Check-Out
299617a3babSopenharmony_ciExternal Projects" above for more details.
300617a3babSopenharmony_ci
301617a3babSopenharmony_ci### Contributing tests
302617a3babSopenharmony_ci
303617a3babSopenharmony_ciTest results should always be included with a pull request that modifies
304617a3babSopenharmony_cifunctionality.
305617a3babSopenharmony_ci
306617a3babSopenharmony_ciIf you are writing unit tests, please use the Google Test framework and
307617a3babSopenharmony_ciplace the tests under the `gtests/` directory.
308617a3babSopenharmony_ci
309617a3babSopenharmony_ciIntegration tests are placed in the `Test/` directory. It contains test input
310617a3babSopenharmony_ciand a subdirectory `baseResults/` that contains the expected results of the
311617a3babSopenharmony_citests.  Both the tests and `baseResults/` are under source-code control.
312617a3babSopenharmony_ci
313617a3babSopenharmony_ciGoogle Test runs those integration tests by reading the test input, compiling
314617a3babSopenharmony_cithem, and then compare against the expected results in `baseResults/`. The
315617a3babSopenharmony_ciintegration tests to run via Google Test is registered in various
316617a3babSopenharmony_ci`gtests/*.FromFile.cpp` source files. `glslangtests` provides a command-line
317617a3babSopenharmony_cioption `--update-mode`, which, if supplied, will overwrite the golden files
318617a3babSopenharmony_ciunder the `baseResults/` directory with real output from that invocation.
319617a3babSopenharmony_ciFor more information, please check `gtests/` directory's
320617a3babSopenharmony_ci[README](gtests/README.md).
321617a3babSopenharmony_ci
322617a3babSopenharmony_ciFor the `runtests` script, it will generate current results in the
323617a3babSopenharmony_ci`localResults/` directory and `diff` them against the `baseResults/`.
324617a3babSopenharmony_ciWhen you want to update the tracked test results, they need to be
325617a3babSopenharmony_cicopied from `localResults/` to `baseResults/`.  This can be done by
326617a3babSopenharmony_cithe `bump` shell script.
327617a3babSopenharmony_ci
328617a3babSopenharmony_ciYou can add your own private list of tests, not tracked publicly, by using
329617a3babSopenharmony_ci`localtestlist` to list non-tracked tests.  This is automatically read
330617a3babSopenharmony_ciby `runtests` and included in the `diff` and `bump` process.
331617a3babSopenharmony_ci
332617a3babSopenharmony_ci## Programmatic Interfaces
333617a3babSopenharmony_ci
334617a3babSopenharmony_ciAnother piece of software can programmatically translate shaders to an AST
335617a3babSopenharmony_ciusing one of two different interfaces:
336617a3babSopenharmony_ci* A new C++ class-oriented interface, or
337617a3babSopenharmony_ci* The original C functional interface
338617a3babSopenharmony_ci
339617a3babSopenharmony_ciThe `main()` in `StandAlone/StandAlone.cpp` shows examples using both styles.
340617a3babSopenharmony_ci
341617a3babSopenharmony_ci### C++ Class Interface (new, preferred)
342617a3babSopenharmony_ci
343617a3babSopenharmony_ciThis interface is in roughly the last 1/3 of `ShaderLang.h`.  It is in the
344617a3babSopenharmony_ciglslang namespace and contains the following, here with suggested calls
345617a3babSopenharmony_cifor generating SPIR-V:
346617a3babSopenharmony_ci
347617a3babSopenharmony_ci```cxx
348617a3babSopenharmony_ciconst char* GetEsslVersionString();
349617a3babSopenharmony_ciconst char* GetGlslVersionString();
350617a3babSopenharmony_cibool InitializeProcess();
351617a3babSopenharmony_civoid FinalizeProcess();
352617a3babSopenharmony_ci
353617a3babSopenharmony_ciclass TShader
354617a3babSopenharmony_ci    setStrings(...);
355617a3babSopenharmony_ci    setEnvInput(EShSourceHlsl or EShSourceGlsl, stage,  EShClientVulkan or EShClientOpenGL, 100);
356617a3babSopenharmony_ci    setEnvClient(EShClientVulkan or EShClientOpenGL, EShTargetVulkan_1_0 or EShTargetVulkan_1_1 or EShTargetOpenGL_450);
357617a3babSopenharmony_ci    setEnvTarget(EShTargetSpv, EShTargetSpv_1_0 or EShTargetSpv_1_3);
358617a3babSopenharmony_ci    bool parse(...);
359617a3babSopenharmony_ci    const char* getInfoLog();
360617a3babSopenharmony_ci
361617a3babSopenharmony_ciclass TProgram
362617a3babSopenharmony_ci    void addShader(...);
363617a3babSopenharmony_ci    bool link(...);
364617a3babSopenharmony_ci    const char* getInfoLog();
365617a3babSopenharmony_ci    Reflection queries
366617a3babSopenharmony_ci```
367617a3babSopenharmony_ci
368617a3babSopenharmony_ciFor just validating (not generating code), substitute these calls:
369617a3babSopenharmony_ci
370617a3babSopenharmony_ci```cxx
371617a3babSopenharmony_ci    setEnvInput(EShSourceHlsl or EShSourceGlsl, stage,  EShClientNone, 0);
372617a3babSopenharmony_ci    setEnvClient(EShClientNone, 0);
373617a3babSopenharmony_ci    setEnvTarget(EShTargetNone, 0);
374617a3babSopenharmony_ci```
375617a3babSopenharmony_ci
376617a3babSopenharmony_ciSee `ShaderLang.h` and the usage of it in `StandAlone/StandAlone.cpp` for more
377617a3babSopenharmony_cidetails. There is a block comment giving more detail above the calls for
378617a3babSopenharmony_ci`setEnvInput, setEnvClient, and setEnvTarget`.
379617a3babSopenharmony_ci
380617a3babSopenharmony_ci### C Functional Interface (original)
381617a3babSopenharmony_ci
382617a3babSopenharmony_ciThis interface is in roughly the first 2/3 of `ShaderLang.h`, and referred to
383617a3babSopenharmony_cias the `Sh*()` interface, as all the entry points start `Sh`.
384617a3babSopenharmony_ci
385617a3babSopenharmony_ciThe `Sh*()` interface takes a "compiler" call-back object, which it calls after
386617a3babSopenharmony_cibuilding call back that is passed the AST and can then execute a back end on it.
387617a3babSopenharmony_ci
388617a3babSopenharmony_ciThe following is a simplified resulting run-time call stack:
389617a3babSopenharmony_ci
390617a3babSopenharmony_ci```c
391617a3babSopenharmony_ciShCompile(shader, compiler) -> compiler(AST) -> <back end>
392617a3babSopenharmony_ci```
393617a3babSopenharmony_ci
394617a3babSopenharmony_ciIn practice, `ShCompile()` takes shader strings, default version, and
395617a3babSopenharmony_ciwarning/error and other options for controlling compilation.
396617a3babSopenharmony_ci
397617a3babSopenharmony_ci### C Functional Interface (new)
398617a3babSopenharmony_ci
399617a3babSopenharmony_ciThis 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.
400617a3babSopenharmony_ci
401617a3babSopenharmony_ci```c
402617a3babSopenharmony_ci#include <glslang/Include/glslang_c_interface.h>
403617a3babSopenharmony_ci
404617a3babSopenharmony_ci// Required for use of glslang_default_resource
405617a3babSopenharmony_ci#include <glslang/Public/resource_limits_c.h>
406617a3babSopenharmony_ci
407617a3babSopenharmony_citypedef struct SpirVBinary {
408617a3babSopenharmony_ci    uint32_t *words; // SPIR-V words
409617a3babSopenharmony_ci    int size; // number of words in SPIR-V binary
410617a3babSopenharmony_ci} SpirVBinary;
411617a3babSopenharmony_ci
412617a3babSopenharmony_ciSpirVBinary compileShaderToSPIRV_Vulkan(glslang_stage_t stage, const char* shaderSource, const char* fileName) {
413617a3babSopenharmony_ci    const glslang_input_t input = {
414617a3babSopenharmony_ci        .language = GLSLANG_SOURCE_GLSL,
415617a3babSopenharmony_ci        .stage = stage,
416617a3babSopenharmony_ci        .client = GLSLANG_CLIENT_VULKAN,
417617a3babSopenharmony_ci        .client_version = GLSLANG_TARGET_VULKAN_1_2,
418617a3babSopenharmony_ci        .target_language = GLSLANG_TARGET_SPV,
419617a3babSopenharmony_ci        .target_language_version = GLSLANG_TARGET_SPV_1_5,
420617a3babSopenharmony_ci        .code = shaderSource,
421617a3babSopenharmony_ci        .default_version = 100,
422617a3babSopenharmony_ci        .default_profile = GLSLANG_NO_PROFILE,
423617a3babSopenharmony_ci        .force_default_version_and_profile = false,
424617a3babSopenharmony_ci        .forward_compatible = false,
425617a3babSopenharmony_ci        .messages = GLSLANG_MSG_DEFAULT_BIT,
426617a3babSopenharmony_ci        .resource = glslang_default_resource(),
427617a3babSopenharmony_ci    };
428617a3babSopenharmony_ci
429617a3babSopenharmony_ci    glslang_shader_t* shader = glslang_shader_create(&input);
430617a3babSopenharmony_ci
431617a3babSopenharmony_ci    SpirVBinary bin = {
432617a3babSopenharmony_ci        .words = NULL,
433617a3babSopenharmony_ci        .size = 0,
434617a3babSopenharmony_ci    };
435617a3babSopenharmony_ci    if (!glslang_shader_preprocess(shader, &input))	{
436617a3babSopenharmony_ci        printf("GLSL preprocessing failed %s\n", fileName);
437617a3babSopenharmony_ci        printf("%s\n", glslang_shader_get_info_log(shader));
438617a3babSopenharmony_ci        printf("%s\n", glslang_shader_get_info_debug_log(shader));
439617a3babSopenharmony_ci        printf("%s\n", input.code);
440617a3babSopenharmony_ci        glslang_shader_delete(shader);
441617a3babSopenharmony_ci        return bin;
442617a3babSopenharmony_ci    }
443617a3babSopenharmony_ci
444617a3babSopenharmony_ci    if (!glslang_shader_parse(shader, &input)) {
445617a3babSopenharmony_ci        printf("GLSL parsing failed %s\n", fileName);
446617a3babSopenharmony_ci        printf("%s\n", glslang_shader_get_info_log(shader));
447617a3babSopenharmony_ci        printf("%s\n", glslang_shader_get_info_debug_log(shader));
448617a3babSopenharmony_ci        printf("%s\n", glslang_shader_get_preprocessed_code(shader));
449617a3babSopenharmony_ci        glslang_shader_delete(shader);
450617a3babSopenharmony_ci        return bin;
451617a3babSopenharmony_ci    }
452617a3babSopenharmony_ci
453617a3babSopenharmony_ci    glslang_program_t* program = glslang_program_create();
454617a3babSopenharmony_ci    glslang_program_add_shader(program, shader);
455617a3babSopenharmony_ci
456617a3babSopenharmony_ci    if (!glslang_program_link(program, GLSLANG_MSG_SPV_RULES_BIT | GLSLANG_MSG_VULKAN_RULES_BIT)) {
457617a3babSopenharmony_ci        printf("GLSL linking failed %s\n", fileName);
458617a3babSopenharmony_ci        printf("%s\n", glslang_program_get_info_log(program));
459617a3babSopenharmony_ci        printf("%s\n", glslang_program_get_info_debug_log(program));
460617a3babSopenharmony_ci        glslang_program_delete(program);
461617a3babSopenharmony_ci        glslang_shader_delete(shader);
462617a3babSopenharmony_ci        return bin;
463617a3babSopenharmony_ci    }
464617a3babSopenharmony_ci
465617a3babSopenharmony_ci    glslang_program_SPIRV_generate(program, stage);
466617a3babSopenharmony_ci
467617a3babSopenharmony_ci    bin.size = glslang_program_SPIRV_get_size(program);
468617a3babSopenharmony_ci    bin.words = malloc(bin.size * sizeof(uint32_t));
469617a3babSopenharmony_ci    glslang_program_SPIRV_get(program, bin.words);
470617a3babSopenharmony_ci
471617a3babSopenharmony_ci    const char* spirv_messages = glslang_program_SPIRV_get_messages(program);
472617a3babSopenharmony_ci    if (spirv_messages)
473617a3babSopenharmony_ci        printf("(%s) %s\b", fileName, spirv_messages);
474617a3babSopenharmony_ci
475617a3babSopenharmony_ci    glslang_program_delete(program);
476617a3babSopenharmony_ci    glslang_shader_delete(shader);
477617a3babSopenharmony_ci
478617a3babSopenharmony_ci    return bin;
479617a3babSopenharmony_ci}
480617a3babSopenharmony_ci```
481617a3babSopenharmony_ci
482617a3babSopenharmony_ci## Basic Internal Operation
483617a3babSopenharmony_ci
484617a3babSopenharmony_ci* Initial lexical analysis is done by the preprocessor in
485617a3babSopenharmony_ci  `MachineIndependent/Preprocessor`, and then refined by a GLSL scanner
486617a3babSopenharmony_ci  in `MachineIndependent/Scan.cpp`.  There is currently no use of flex.
487617a3babSopenharmony_ci
488617a3babSopenharmony_ci* Code is parsed using bison on `MachineIndependent/glslang.y` with the
489617a3babSopenharmony_ci  aid of a symbol table and an AST.  The symbol table is not passed on to
490617a3babSopenharmony_ci  the back-end; the intermediate representation stands on its own.
491617a3babSopenharmony_ci  The tree is built by the grammar productions, many of which are
492617a3babSopenharmony_ci  offloaded into `ParseHelper.cpp`, and by `Intermediate.cpp`.
493617a3babSopenharmony_ci
494617a3babSopenharmony_ci* The intermediate representation is very high-level, and represented
495617a3babSopenharmony_ci  as an in-memory tree.   This serves to lose no information from the
496617a3babSopenharmony_ci  original program, and to have efficient transfer of the result from
497617a3babSopenharmony_ci  parsing to the back-end.  In the AST, constants are propagated and
498617a3babSopenharmony_ci  folded, and a very small amount of dead code is eliminated.
499617a3babSopenharmony_ci
500617a3babSopenharmony_ci  To aid linking and reflection, the last top-level branch in the AST
501617a3babSopenharmony_ci  lists all global symbols.
502617a3babSopenharmony_ci
503617a3babSopenharmony_ci* The primary algorithm of the back-end compiler is to traverse the
504617a3babSopenharmony_ci  tree (high-level intermediate representation), and create an internal
505617a3babSopenharmony_ci  object code representation.  There is an example of how to do this
506617a3babSopenharmony_ci  in `MachineIndependent/intermOut.cpp`.
507617a3babSopenharmony_ci
508617a3babSopenharmony_ci* Reduction of the tree to a linear byte-code style low-level intermediate
509617a3babSopenharmony_ci  representation is likely a good way to generate fully optimized code.
510617a3babSopenharmony_ci
511617a3babSopenharmony_ci* There is currently some dead old-style linker-type code still lying around.
512617a3babSopenharmony_ci
513617a3babSopenharmony_ci* Memory pool: parsing uses types derived from C++ `std` types, using a
514617a3babSopenharmony_ci  custom allocator that puts them in a memory pool.  This makes allocation
515617a3babSopenharmony_ci  of individual container/contents just few cycles and deallocation free.
516617a3babSopenharmony_ci  This pool is popped after the AST is made and processed.
517617a3babSopenharmony_ci
518617a3babSopenharmony_ci  The use is simple: if you are going to call `new`, there are three cases:
519617a3babSopenharmony_ci
520617a3babSopenharmony_ci  - the object comes from the pool (its base class has the macro
521617a3babSopenharmony_ci    `POOL_ALLOCATOR_NEW_DELETE` in it) and you do not have to call `delete`
522617a3babSopenharmony_ci
523617a3babSopenharmony_ci  - it is a `TString`, in which case call `NewPoolTString()`, which gets
524617a3babSopenharmony_ci    it from the pool, and there is no corresponding `delete`
525617a3babSopenharmony_ci
526617a3babSopenharmony_ci  - the object does not come from the pool, and you have to do normal
527617a3babSopenharmony_ci    C++ memory management of what you `new`
528617a3babSopenharmony_ci
529617a3babSopenharmony_ci* Features can be protected by version/extension/stage/profile:
530617a3babSopenharmony_ci  See the comment in `glslang/MachineIndependent/Versions.cpp`.
531617a3babSopenharmony_ci
532617a3babSopenharmony_ci[cmake]: https://cmake.org/
533617a3babSopenharmony_ci[python]: https://www.python.org/
534617a3babSopenharmony_ci[bison]: https://www.gnu.org/software/bison/
535617a3babSopenharmony_ci[googletest]: https://github.com/google/googletest
536617a3babSopenharmony_ci[bison-gnu-win32]: http://gnuwin32.sourceforge.net/packages/bison.htm
537617a3babSopenharmony_ci[main-tot-release]: https://github.com/KhronosGroup/glslang/releases/tag/main-tot
538