Browse code

Add implementation

Robert Cranston authored on 21/12/2021 09:34:56
Showing 2 changed files

... ...
@@ -2,8 +2,44 @@
2 2
 
3 3
 Run [GLSL][] code on the CPU.
4 4
 
5
+Generates a wrapper file including some [C++][] standard library functionality
6
+and [OpenGL Mathematics (GLM)][], compiles it with the systems C++ compiler (by
7
+default [`gcc`][], can be changed by setting the [environment variable][]
8
+`CXX`) and runs the result.
9
+
10
+This, of course, does not *really* run GLSL code on the CPU. For an actual GLSL
11
+compiler (but not to something that can run on the CPU), see [`glslang`][].
12
+
13
+The wapper does the following:
14
+
15
+-   C++ standard library
16
+    -   Brings the `std` namespace into global scope.
17
+    -   `#include`s [`cassert`][] for testing.
18
+    -   `#include`s [`iostream`][] for printing.
19
+-   GLM
20
+    -   Brings the `glm` namespace into global scope.
21
+    -   `#define`s `GLM_FORCE_SWIZZLE` to enable [swizzling][] support.
22
+    -   `#include`s [`glm/gtx/io.hpp`][] to enable [`iostream`][] support.
23
+-   Other
24
+    -   `#define`s `GLSLRUN`.
25
+    -   Defines [built-in variable][]s (like [`gl_Position`][]).
26
+    -   Defines [built-in function][]s (like [`EmitVertex`][]).
27
+
5 28
 [`glslrun`]: https://git.rcrnstn.net/rcrnstn/glslrun
6 29
 [GLSL]: https://en.wikipedia.org/wiki/OpenGL_Shading_Language
30
+[C++]: https://en.wikipedia.org/wiki/C++
31
+[OpenGL Mathematics (GLM)]: https://glm.g-truc.net
32
+[`gcc`]: https://gcc.gnu.org
33
+[environment variable]: https://en.wikipedia.org/wiki/Environment_variable
34
+[`glslang`]: https://github.com/KhronosGroup/glslang
35
+[`cassert`]: https://en.cppreference.com/w/cpp/header/cassert
36
+[`iostream`]: https://en.cppreference.com/w/cpp/header/iostream
37
+[swizzling]: https://en.wikipedia.org/wiki/Swizzling_(computer_graphics)
38
+[`glm/gtx/io.hpp`]: http://glm.g-truc.net/0.9.9/api/a00332.html
39
+[built-in variable]: https://www.khronos.org/opengl/wiki/Built-in_Variable_(GLSL)
40
+[`gl_Position`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/gl_Position.xhtml
41
+[built-in function]: https://www.khronos.org/opengl/wiki/Built-in_Function_(GLSL)
42
+[`EmitVertex`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/EmitVertex.xhtml
7 43
 
8 44
 ## Usage
9 45
 
... ...
@@ -21,7 +57,8 @@ usage:
21 57
 
22 58
 arguments:
23 59
   <file>
24
-    File containing code to run. Specify - to read from stdin instead.
60
+    File containing code to run. If <file> is omitted or -, to read from
61
+    stdin instead.
25 62
 
26 63
 options:
27 64
   -m, --main
... ...
@@ -33,16 +70,28 @@ options:
33 70
 
34 71
 ## Dependencies
35 72
 
36
-All dependencies are [POSIX][] and are highly likely to be installed by default
73
+For compiling C++:
74
+
75
+-   C++ compiler (e.g. from [`g++`][])
76
+-   C++ standard library (e.g. from [`libstdc++`][])
77
+-   OpenGL Mathematics (GLM) (e.g. from [`libglm-dev`][])
78
+
79
+All other dependencies are [POSIX][] (except `mktemp`, but most Unix-like
80
+systems have some version), and are highly likely to be installed by default
37 81
 (e.g. they all have the [Debian priority][] `required`).
38 82
 
39 83
 -   `sh` (e.g. from [`bash`][] or [`dash`][])
84
+-   `rm`, `cat`, `mktemp` (e.g. from [`coreutils`][])
40 85
 -   `sed` (e.g. from [`sed`][])
41 86
 -   `awk` (e.g. from [`mawk`][])
42 87
 
88
+[`g++`]: https://packages.debian.org/g++
89
+[`libstdc++`]: https://packages.debian.org/libstdc++
90
+[`libglm-dev`]: https://packages.debian.org/libglm-dev
43 91
 [POSIX]: https://en.wikipedia.org/wiki/POSIX
44 92
 [Debian priority]: https://www.debian.org/doc/debian-policy/ch-archive.html#s-priorities
45 93
 [`bash`]: https://packages.debian.org/bash
94
+[`coreutils`]: https://packages.debian.org/coreutils
46 95
 [`dash`]: https://packages.debian.org/dash
47 96
 [`sed`]: https://packages.debian.org/sed
48 97
 [`mawk`]: https://packages.debian.org/mawk
... ...
@@ -12,7 +12,8 @@ set -euC
12 12
 #////
13 13
 ###// arguments:
14 14
 ####/   <file>
15
-#////     File containing code to run. Specify - to read from stdin instead.
15
+#////     File containing code to run. If <file> is omitted or -, to read from
16
+#////     stdin instead.
16 17
 #////
17 18
 ###// options:
18 19
 ####/   -m, --main
... ...
@@ -59,3 +60,190 @@ file="${1-}"; shift $(($#>0));
59 60
 
60 61
 ## Parse unrecognized arguments
61 62
 [ $# -eq 0 ] || parse "unrecognized argument: '$1'"
63
+
64
+## Create temporary directory
65
+dir_tmp="$(mktemp -d)"
66
+trap 'rm -rf "$dir_tmp"' EXIT
67
+
68
+## Variables
69
+file_in="$dir_tmp/$(basename "$0").cpp"
70
+file_out="$file_in-out"
71
+if [ "$main" ]
72
+then
73
+  main_begin="int main() {"
74
+  main_end="}"
75
+fi
76
+if [ "$file" = "-" ]
77
+then
78
+  file=""
79
+fi
80
+
81
+## Generate
82
+cat << EOF > "$file_in"
83
+#include <cassert>
84
+#include <iostream>
85
+
86
+#define GLM_FORCE_SWIZZLE 1
87
+#define GLM_ENABLE_EXPERIMENTAL 1
88
+#include <glm/glm.hpp>
89
+#include <glm/gtx/io.hpp>
90
+
91
+using namespace std;
92
+using namespace glm;
93
+
94
+// Constants
95
+const int gl_MaxVertexAttribs = 16;
96
+const int gl_MaxVertexOutputComponents = 64;
97
+const int gl_MaxVertexUniformComponents = 1024;
98
+const int gl_MaxVertexTextureImageUnits = 16;
99
+const int gl_MaxGeometryInputComponents = 64;
100
+const int gl_MaxGeometryOutputComponents = 128;
101
+const int gl_MaxGeometryUniformComponents = 1024;
102
+const int gl_MaxGeometryTextureImageUnits = 16;
103
+const int gl_MaxGeometryOutputVertices = 256;
104
+const int gl_MaxGeometryTotalOutputComponents = 1024;
105
+const int gl_MaxGeometryVaryingComponents = 64;
106
+const int gl_MaxFragmentInputComponents = 128;
107
+const int gl_MaxDrawBuffers = 8;
108
+const int gl_MaxFragmentUniformComponents = 1024;
109
+const int gl_MaxTextureImageUnits1 = 16;
110
+const int gl_MaxClipDistances = 8;
111
+const int gl_MaxCombinedTextureImageUnits = 48;
112
+// OpenGL 4.0
113
+int gl_MaxTessControlInputComponents = 128;
114
+int gl_MaxTessControlOutputComponents = 128;
115
+int gl_MaxTessControlUniformComponents = 1024;
116
+int gl_MaxTessControlTextureImageUnits = 16;
117
+int gl_MaxTessControlTotalOutputComponents = 4096;
118
+int gl_MaxTessEvaluationInputComponents = 128;
119
+int gl_MaxTessEvaluationOutputComponents = 128;
120
+int gl_MaxTessEvaluationUniformComponents = 1024;
121
+int gl_MaxTessEvaluationTextureImageUnits = 16;
122
+int gl_MaxTessPatchComponents = 120;
123
+int gl_MaxPatchVertices = 32;
124
+int gl_MaxTessGenLevel = 64;
125
+// OpenGL 4.1
126
+int gl_MaxViewports = 16;
127
+int gl_MaxVertexUniformVectors = 256;
128
+int gl_MaxFragmentUniformVectors = 256;
129
+int gl_MaxVaryingVectors = 15;
130
+// OpenGL 4.2
131
+int gl_MaxVertexImageUniforms = 0;
132
+int gl_MaxVertexAtomicCounters = 0;
133
+int gl_MaxVertexAtomicCounterBuffers = 0;
134
+int gl_MaxTessControlImageUniforms = 0;
135
+int gl_MaxTessControlAtomicCounters = 0;
136
+int gl_MaxTessControlAtomicCounterBuffers = 0;
137
+int gl_MaxTessEvaluationImageUniforms = 0;
138
+int gl_MaxTessEvaluationAtomicCounters = 0;
139
+int gl_MaxTessEvaluationAtomicCounterBuffers = 0;
140
+int gl_MaxGeometryImageUniforms = 0;
141
+int gl_MaxGeometryAtomicCounters = 0;
142
+int gl_MaxGeometryAtomicCounterBuffers = 0;
143
+int gl_MaxFragmentImageUniforms = 8;
144
+int gl_MaxFragmentAtomicCounters = 8;
145
+int gl_MaxFragmentAtomicCounterBuffers = 1;
146
+int gl_MaxCombinedImageUniforms = 8;
147
+int gl_MaxCombinedAtomicCounters = 8;
148
+int gl_MaxCombinedAtomicCounterBuffers = 1;
149
+int gl_MaxImageUnits = 8;
150
+int gl_MaxCombinedImageUnitsAndFragmentOutputs = 8;
151
+int gl_MaxImageSamples = 0;
152
+int gl_MaxAtomicCounterBindings = 1;
153
+int gl_MaxAtomicCounterBufferSize = 32;
154
+int gl_MinProgramTexelOffset = -8;
155
+int gl_MaxProgramTexelOffset = 7;
156
+// OpenGL 4.3
157
+ivec3 gl_MaxComputeWorkGroupCount = {65535, 65535, 65535};
158
+ivec3 gl_MaxComputeWorkGroupSize = { 1024, 1024, 64 };
159
+int gl_MaxComputeUniformComponents = 512;
160
+int gl_MaxComputeTextureImageUnits = 16;
161
+int gl_MaxComputeImageUniforms = 8;
162
+int gl_MaxComputeAtomicCounters = 8;
163
+int gl_MaxComputeAtomicCounterBuffers = 1;
164
+// OpenGL 4.4
165
+int gl_MaxTransformFeedbackBuffers = 4;
166
+int gl_MaxTransformFeedbackInterleavedComponents = 64;
167
+
168
+// Vertex shader inputs
169
+int  gl_VertexID;
170
+int  gl_InstanceID;
171
+int  gl_DrawID;
172
+int  gl_BaseVertex;
173
+int  gl_BaseInstance;
174
+// Vertex shader outputs
175
+vec4  gl_Position;
176
+float gl_PointSize;
177
+float gl_ClipDistance[gl_MaxClipDistances];
178
+// Tessellation control shader inputs
179
+int gl_PatchVerticesIn;
180
+// Tessellation control shader outputs
181
+float gl_TessLevelOuter[4];
182
+float gl_TessLevelInner[2];
183
+// Tessellation evaluation shader inputs
184
+vec3 gl_TessCoord;
185
+// Geometry shader inputs
186
+int gl_PrimitiveIDIn;
187
+int gl_InvocationID;
188
+// Geometry shader outputs
189
+int gl_PrimitiveID;
190
+int gl_Layer;
191
+int gl_ViewportIndex;
192
+// Fragment shader inputs
193
+vec4 gl_FragCoord;
194
+bool gl_FrontFacing;
195
+vec2 gl_PointCoord;
196
+int gl_SampleID;
197
+vec2 gl_SamplePosition;
198
+int gl_SampleMaskIn[1];
199
+// Fragment shader outputs
200
+float gl_FragDepth;
201
+int gl_SampleMask;
202
+// Compute shader inputs
203
+uvec3 gl_NumWorkGroups;
204
+uvec3 gl_WorkGroupID;
205
+uvec3 gl_LocalInvocationID;
206
+uvec3 gl_GlobalInvocationID;
207
+uint  gl_LocalInvocationIndex;
208
+// Compute shader other variables
209
+uvec3 gl_WorkGroupSize;
210
+// Shader uniforms
211
+struct gl_DepthRange
212
+{
213
+    float near;
214
+    float far;
215
+    float diff;
216
+};
217
+int gl_NumSamples;
218
+
219
+// Functions
220
+void EmitVertex() {}
221
+void EndPrimitive() {}
222
+
223
+#define GLSLRUN 1
224
+
225
+${main_begin-}
226
+#line 1
227
+$(
228
+    sed ${file:+"$file"} \
229
+        -e 's/^\s*#version\>.*//' \
230
+        -e 's/^\s*#extension\>.*//' \
231
+        -e 's/^\s*layout\>.*//' \
232
+        -e 's/^\s*in\>\s\?//' \
233
+        -e 's/^\s*out\>\s\?//' \
234
+        -e 's/^\s*void\(\s\+main\>\)/int\1/' \
235
+)
236
+${main_end-}
237
+EOF
238
+
239
+## Optionally print
240
+if [ "$print" ]
241
+then
242
+  cat "$file_in"
243
+fi
244
+
245
+## Compile
246
+"${CXX-g++}" -Wall -I. -o "$file_out" "$file_in"
247
+
248
+## Run
249
+"$file_out"