summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/glslang/src/README.md
blob: 7a14f56afb8ef8aca4e2916238f8f9d48de30287 (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
Also see the Khronos landing page for glslang as a reference front end:

https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/

The above page includes where to get binaries, and is kept up to date
regarding the feature level of glslang.

glslang
=======

[![Build Status](https://travis-ci.org/KhronosGroup/glslang.svg?branch=master)](https://travis-ci.org/KhronosGroup/glslang)
[![Build status](https://ci.appveyor.com/api/projects/status/q6fi9cb0qnhkla68/branch/master?svg=true)](https://ci.appveyor.com/project/Khronoswebmaster/glslang/branch/master)

An OpenGL and OpenGL ES shader front end and validator.

There are two components:

1. A front-end library for programmatic parsing of GLSL/ESSL into an AST.

2. A standalone wrapper, `glslangValidator`, that can be used as a shader
   validation tool.

How to add a feature protected by a version/extension/stage/profile:  See the
comment in `glslang/MachineIndependent/Versions.cpp`.

Things left to do:  See `Todo.txt`

Execution of Standalone Wrapper
-------------------------------

To use the standalone binary form, execute `glslangValidator`, and it will print
a usage statement.  Basic operation is to give it a file containing a shader,
and it will print out warnings/errors and optionally an AST.

The applied stage-specific rules are based on the file extension:
* `.vert` for a vertex shader
* `.tesc` for a tessellation control shader
* `.tese` for a tessellation evaluation shader
* `.geom` for a geometry shader
* `.frag` for a fragment shader
* `.comp` for a compute shader

There is also a non-shader extension
* `.conf` for a configuration file of limits, see usage statement for example

Building
--------

### Dependencies

* [CMake][cmake]: for generating compilation targets.
* [bison][bison]: _optional_, but needed when changing the grammar (glslang.y).
* [googletest][googletest]: _optional_, but should use if making any changes to glslang.

### Build steps

#### 1) Check-Out External Projects

```bash
cd <the directory glslang was cloned to, External will be a subdirectory>
git clone https://github.com/google/googletest.git External/googletest
```

#### 2) Configure

Assume the source directory is `$SOURCE_DIR` and
the build directory is `$BUILD_DIR`:

For building on Linux (assuming using the Ninja generator):

```bash
cd $BUILD_DIR

cmake -GNinja -DCMAKE_BUILD_TYPE={Debug|Release|RelWithDebInfo} \
      -DCMAKE_INSTALL_PREFIX=`pwd`/install $SOURCE_DIR
```

For building on Windows:

```bash
cmake $SOURCE_DIR -DCMAKE_INSTALL_PREFIX=`pwd`/install
# The CMAKE_INSTALL_PREFIX part is for testing (explained later).
```

The CMake GUI also works for Windows (version 3.4.1 tested).

#### 3) Build and Install

```bash
# for Linux:
ninja install

# for Windows:
cmake --build . --config {Release|Debug|MinSizeRel|RelWithDebInfo} \
      --target install
```

If using MSVC, after running CMake to configure, use the
Configuration Manager to check the `INSTALL` project.

### If you need to change the GLSL grammar

The grammar in `glslang/MachineIndependent/glslang.y` has to be recompiled with
bison if it changes, the output files are committed to the repo to avoid every
developer needing to have bison configured to compile the project when grammar
changes are quite infrequent. For windows you can get binaries from
[GnuWin32][bison-gnu-win32].

The command to rebuild is:

```bash
bison --defines=MachineIndependent/glslang_tab.cpp.h
      -t MachineIndependent/glslang.y
      -o MachineIndependent/glslang_tab.cpp
```

The above command is also available in the bash script at
`glslang/updateGrammar`.

Testing
-------

Right now, there are two test harnesses existing in glslang: one is [Google
Test](gtests/), one is the [`runtests` script](Test/runtests). The former
runs unit tests and single-shader single-threaded integration tests, while
the latter runs multiple-shader linking tests and multi-threaded tests.

### Running tests

The [`runtests` script](Test/runtests) requires compiled binaries to be
installed into `$BUILD_DIR/install`. Please make sure you have supplied the
correct configuration to CMake (using `-DCMAKE_INSTALL_PREFIX`) when building;
otherwise, you may want to modify the path in the `runtests` script.

Running Google Test-backed tests:

```bash
cd $BUILD_DIR

# for Linux:
ctest

# for Windows:
ctest -C {Debug|Release|RelWithDebInfo|MinSizeRel}

# or, run the test binary directly
# (which gives more fine-grained control like filtering):
<dir-to-glslangtests-in-build-dir>/glslangtests
```

Running `runtests` script-backed tests:

```bash
cd $SOURCE_DIR/Test && ./runtests
```

### Contributing tests

Test results should always be included with a pull request that modifies
functionality.

If you are writing unit tests, please use the Google Test framework and
place the tests under the `gtests/` directory.

Integration tests are placed in the `Test/` directory. It contains test input
and a subdirectory `baseResults/` that contains the expected results of the
tests.  Both the tests and `baseResults/` are under source-code control.

Google Test runs those integration tests by reading the test input, compiling
them, and then compare against the expected results in `baseResults/`. The
integration tests to run via Google Test is registered in various
`gtests/*.FromFile.cpp` source files. `glslangtests` provides a command-line
option `--update-mode`, which, if supplied, will overwrite the golden files
under the `baseResults/` directory with real output from that invocation.
For more information, please check `gtests/` directory's
[README](gtests/README.md).

For the `runtests` script, it will generate current results in the
`localResults/` directory and `diff` them against the `baseResults/`.
The integration tests to run via the `runtests` script is registered
via various `Test/test-*` text files and `Test/testlist`.
When you want to update the tracked test results, they need to be
copied from `localResults/` to `baseResults/`.  This can be done by
the `bump` shell script.

The list of files tested comes from `testlist`, and lists input shaders
in this directory, which must all be public for this to work.  However,
you can add your own private list of tests, not tracked here, by using
`localtestlist` to list non-tracked tests.  This is automatically read
by `runtests` and included in the `diff` and `bump` process.

Programmatic Interfaces
-----------------------

Another piece of software can programmatically translate shaders to an AST
using one of two different interfaces:
* A new C++ class-oriented interface, or
* The original C functional interface

The `main()` in `StandAlone/StandAlone.cpp` shows examples using both styles.

### C++ Class Interface (new, preferred)

This interface is in roughly the last 1/3 of `ShaderLang.h`.  It is in the
glslang namespace and contains the following.

```cxx
const char* GetEsslVersionString();
const char* GetGlslVersionString();
bool InitializeProcess();
void FinalizeProcess();

class TShader
    bool parse(...);
    void setStrings(...);
    const char* getInfoLog();

class TProgram
    void addShader(...);
    bool link(...);
    const char* getInfoLog();
    Reflection queries
```

See `ShaderLang.h` and the usage of it in `StandAlone/StandAlone.cpp` for more
details.

### C Functional Interface (orignal)

This interface is in roughly the first 2/3 of `ShaderLang.h`, and referred to
as the `Sh*()` interface, as all the entry points start `Sh`.

The `Sh*()` interface takes a "compiler" call-back object, which it calls after
building call back that is passed the AST and can then execute a backend on it.

The following is a simplified resulting run-time call stack:

```c
ShCompile(shader, compiler) -> compiler(AST) -> <back end>
```

In practice, `ShCompile()` takes shader strings, default version, and
warning/error and other options for controlling compilation.

Basic Internal Operation
------------------------

* Initial lexical analysis is done by the preprocessor in
  `MachineIndependent/Preprocessor`, and then refined by a GLSL scanner
  in `MachineIndependent/Scan.cpp`.  There is currently no use of flex.

* Code is parsed using bison on `MachineIndependent/glslang.y` with the
  aid of a symbol table and an AST.  The symbol table is not passed on to
  the back-end; the intermediate representation stands on its own.
  The tree is built by the grammar productions, many of which are
  offloaded into `ParseHelper.cpp`, and by `Intermediate.cpp`.

* The intermediate representation is very high-level, and represented
  as an in-memory tree.   This serves to lose no information from the
  original program, and to have efficient transfer of the result from
  parsing to the back-end.  In the AST, constants are propogated and
  folded, and a very small amount of dead code is eliminated.

  To aid linking and reflection, the last top-level branch in the AST
  lists all global symbols.

* The primary algorithm of the back-end compiler is to traverse the
  tree (high-level intermediate representation), and create an internal
  object code representation.  There is an example of how to do this
  in `MachineIndependent/intermOut.cpp`.

* Reduction of the tree to a linear byte-code style low-level intermediate
  representation is likely a good way to generate fully optimized code.

* There is currently some dead old-style linker-type code still lying around.

* Memory pool: parsing uses types derived from C++ `std` types, using a
  custom allocator that puts them in a memory pool.  This makes allocation
  of individual container/contents just few cycles and deallocation free.
  This pool is popped after the AST is made and processed.

  The use is simple: if you are going to call `new`, there are three cases:

  - the object comes from the pool (its base class has the macro
    `POOL_ALLOCATOR_NEW_DELETE` in it) and you do not have to call `delete`

  - it is a `TString`, in which case call `NewPoolTString()`, which gets
    it from the pool, and there is no corresponding `delete`

  - the object does not come from the pool, and you have to do normal
    C++ memory management of what you `new`


[cmake]: https://cmake.org/
[bison]: https://www.gnu.org/software/bison/
[googletest]: https://github.com/google/googletest
[bison-gnu-win32]: http://gnuwin32.sourceforge.net/packages/bison.htm