]> git.tdb.fi Git - libs/gl.git/blob - scripts/builtin_funcs.py
Rearrange postprocessor creation code in SequenceBuilder
[libs/gl.git] / scripts / builtin_funcs.py
1 #!/usr/bin/python3
2
3 import sys
4
5 traits = {
6         "sampler1D": { "CDim": 1, "IDim": 1, "LDim": 1 },
7         "sampler2D": { "CDim": 2, "IDim": 2, "LDim": 2 },
8         "sampler3D": { "CDim": 3, "IDim": 3, "LDim": 3 },
9         "sampler1DArray": { "CDim": 2, "IDim": 2, "LDim": 1 },
10         "sampler2DArray": { "CDim": 3, "IDim": 3, "LDim": 2 },
11         "samplerCube": { "CDim": 3, "IDim": 2, "LDim": 3 },
12         "samplerCubeArray": { "CDim": 4, "IDim": 3, "LDim": 3 },
13         "sampler1DShadow": { "CDim": 3, "IDim": 1, "LDim": 1 },
14         "sampler2DShadow": { "CDim": 3, "IDim": 2, "LDim": 2 },
15         "samplerCubeShadow": { "CDim": 4, "IDim": 2, "LDim": 3 },
16         "sampler1DArrayShadow": { "CDim": 3, "IDim": 2, "LDim": 1 },
17         "sampler2DArrayShadow": { "CDim": 4, "IDim": 3, "LDim": 2 },
18         "samplerCubeArrayShadow": { "IDim": 3, "LDim": 3 },
19         "float": { "Base": "float", "Dim": 1, "Vec": "vec", "Mat": "mat" },
20         "vec2": { "Base": "float", "Dim": 2 },
21         "vec3": { "Base": "float", "Dim": 3 },
22         "vec4": { "Base": "float", "Dim": 4 },
23         "int": { "Base": "int", "Dim": 1, "Vec": "ivec" },
24         "ivec2": { "Base": "int", "Dim": 2 },
25         "ivec3": { "Base": "int", "Dim": 3 },
26         "ivec4": { "Base": "int", "Dim": 4 },
27         "uint": { "Base": "uint", "Dim": 1, "Vec": "uvec" },
28         "uvec2": { "Base": "uint", "Dim": 2 },
29         "uvec3": { "Base": "uint", "Dim": 3 },
30         "uvec4": { "Base": "uint", "Dim": 4 },
31         "bool": { "Base": "bool", "Dim": 1, "Vec": "bvec" },
32         "bvec2": { "Base": "bool", "Dim": 2 },
33         "bvec3": { "Base": "bool", "Dim": 3 },
34         "bvec4": { "Base": "bool", "Dim": 4 },
35         "mat2": { "Cols": 2, "Rows": 2 },
36         "mat3": { "Cols": 3, "Rows": 3 },
37         "mat4": { "Cols": 4, "Rows": 4 },
38         "mat2x3": { "Cols": 2, "Rows": 3 },
39         "mat3x2": { "Cols": 3, "Rows": 2 },
40         "mat2x4": { "Cols": 2, "Rows": 4 },
41         "mat4x2": { "Cols": 4, "Rows": 2 },
42         "mat3x4": { "Cols": 3, "Rows": 4 },
43         "mat4x3": { "Cols": 4, "Rows": 3 }
44 }
45
46 float32vectypes = ("vec2", "vec3", "vec4")
47 float32types = ("float",)+float32vectypes
48 floatvectypes = float32vectypes
49 floattypes = float32types
50 sint32vectypes = ("ivec2", "ivec3", "ivec4")
51 sint32types = ("int",)+sint32vectypes
52 signedtypes = floattypes+sint32types
53 uint32vectypes = ("uvec2", "uvec3", "uvec4")
54 uint32types = ("uint",)+uint32vectypes
55 int32types = sint32types+uint32types
56 unsignedtypes = uint32types
57 arithmetictypes = signedtypes+unsignedtypes
58 arithmeticvectypes = float32vectypes+sint32vectypes+uint32vectypes
59 boolvectypes = ("bvec2", "bvec3", "bvec4")
60 squarematrixtypes = ("mat2", "mat3", "mat4")
61 matrixtypes = squarematrixtypes+("mat2x3", "mat3x2", "mat2x4", "mat4x2", "mat3x4", "mat4x3")
62 flatsamplertypes = ("sampler1D", "sampler2D", "sampler3D", "sampler1DArray", "sampler2DArray")
63 colorsamplertypes = flatsamplertypes+("samplerCube", "samplerCubeArray")
64 shadowsamplertypes = ("sampler1DShadow", "sampler2DShadow", "samplerCubeShadow", "sampler1DArrayShadow", "sampler2DArrayShadow", "samplerCubeArrayShadow")
65 samplertypes = colorsamplertypes+shadowsamplertypes
66 shared_funcs = [
67         # Trigonometric
68         ("T radians(T degrees)", float32types),
69         ("T degrees(T radians)", float32types),
70         ("T sin(T angle)", float32types),
71         ("T cos(T angle)", float32types),
72         ("T tan(T angle)", float32types),
73         ("T asin(T x)", float32types),
74         ("T acos(T x)", float32types),
75         ("T atan(T y, T x)", float32types),
76         ("T atan(T y_over_x)", float32types),
77         ("T sinh(T angle)", float32types),
78         ("T cosh(T angle)", float32types),
79         ("T tanh(T angle)", float32types),
80         ("T asinh(T x)", float32types),
81         ("T acosh(T x)", float32types),
82         ("T atanh(T x)", float32types),
83
84         # Exponential
85         ("T pow(T x, T y)", float32types),
86         ("T exp(T x)", float32types),
87         ("T log(T x)", float32types),
88         ("T exp2(T x)", float32types),
89         ("T log2(T x)", float32types),
90         ("T sqrt(T x)", floattypes),
91         ("T inversesqrt(T x)", floattypes),
92
93         # Common
94         ("T abs(T x)", signedtypes),
95         ("T sign(T x)", signedtypes),
96         ("T floor(T x)", floattypes),
97         ("T trunc(T x)", floattypes),
98         ("T round(T x)", floattypes),
99         ("T roundEven(T x)", floattypes),
100         ("T ceil(T x)", floattypes),
101         ("T fract(T x)", floattypes),
102         ("T mod(T x, T y)", floattypes),
103         ("T mod(T x, T::Base y)", "mod(x, T(y))", floatvectypes),
104         ("T min(T x, T y)", arithmetictypes),
105         ("T min(T x, T::Base y)", "min(x, T(y))", arithmeticvectypes),
106         ("T max(T x, T y)", arithmetictypes),
107         ("T max(T x, T::Base y)", "max(x, T(y))", arithmeticvectypes),
108         ("T clamp(T x, T minVal, T maxVal)", arithmetictypes),
109         ("T clamp(T x, T::Base minVal, T::Base maxVal)", "clamp(x, T(minVal), T(maxVal))", arithmeticvectypes),
110         ("T mix(T x, T y, T a)", floattypes),
111         ("T mix(T x, T y, T::Base a)", "mix(x, y, T(a))", floattypes),
112         ("T mix(T x, T y, bool[T::Dim] a)", arithmetictypes),
113         ("T step(T edge, T x)", floattypes),
114         ("T step(T::Base edge, T x)", "step(T(edge), x)", floatvectypes),
115         ("T smoothstep(T edge0, T edge1, T x)", floattypes),
116         ("T smoothstep(T::Base edge0, T::Base edge1, T x)", "smoothstep(T(edge0), T(edge1), x)", floatvectypes),
117         ("bool[T::Dim] isnan(T x)", floattypes),
118         ("bool[T::Dim] isinf(T x)", floattypes),
119         ("T fma(T a, T b, T c)", floattypes),
120
121         # Geometric
122         ("T::Base length(T x)", floattypes),
123         ("T::Base distance(T p0, T p1)", floattypes),
124         ("T::Base dot(T x, T y)", floattypes),
125         "vec3 cross(vec3 x, vec3 y)",
126         ("T normalize(T x)", floattypes),
127         ("T faceforward(T N, T I, T Nref)", floattypes),
128         ("T reflect(T I, T N)", floattypes),
129         ("T refract(T I, T N, float eta)", floattypes),
130
131         # Matrix
132         ("T matrixCompMult(T x, T y)", matrixtypes),
133         ("T outerProduct(float[T::Rows] c, float[T::Cols] r)", matrixtypes),
134         ("float[T::Rows, T::Cols] transpose(T m)", matrixtypes),
135         ("T determinant(T m)", squarematrixtypes),
136         ("T inverse(T m)", squarematrixtypes),
137
138         # Vector relational
139         ("bool[T::Dim] lessThan(T x, T y)", arithmeticvectypes),
140         ("bool[T::Dim] lessThanEqual(T x, T y)", arithmeticvectypes),
141         ("bool[T::Dim] greaterThan(T x, T y)", arithmeticvectypes),
142         ("bool[T::Dim] greaterThanEqual(T x, T y)", arithmeticvectypes),
143         ("bool[T::Dim] equal(T x, T y)", arithmeticvectypes),
144         ("bool[T::Dim] notEqual(T x, T y)", arithmeticvectypes),
145         ("bool any(T x)", boolvectypes),
146         ("bool all(T x)", boolvectypes),
147         ("bool not(T x)", boolvectypes),
148
149         # Integer
150         ("T bitfieldExtract(T value, int offset, int bits)", int32types),
151         ("T bitfieldInsert(T value, T insert, int offset, int bits)", int32types),
152         ("T bitfieldReverse(T value)", int32types),
153         ("T bitCount(T value)", int32types),
154         ("int[T::Dim] findLSB(T value)", int32types),
155         ("int[T::Dim] findMSB(T value)", int32types),
156
157         # Texture
158         ("int[T::IDim] textureSize(T sampler, int lod)", samplertypes),
159         ("vec2 textureQueryLod(T sampler, float[T::LDim] P)", samplertypes),
160         ("int textureQueryLevels(T sampler)", samplertypes),
161         ("vec4 texture(T sampler, float[T::CDim] P)", colorsamplertypes),
162         ("float texture(T sampler, float[T::CDim] P)", tuple(s for s in shadowsamplertypes if "CubeArray" not in s)),
163         "float texture(samplerCubeArrayShadow sampler, vec4 P, float compare)",
164         ("vec4 textureLod(T sampler, float[T::CDim] P, float lod)", colorsamplertypes),
165         ("vec4 texelFetch(T sampler, int[T::CDim] P, int lod)", flatsamplertypes)
166 ]
167
168 fragment_funcs = [
169         # Derivative
170         ("T dFdx(T p)", float32types),
171         ("T dFdy(T p)", float32types),
172         ("T dFdxFine(T p)", float32types),
173         ("T dFdyFine(T p)", float32types),
174         ("T dFdxCoarse(T p)", float32types),
175         ("T dFdyCoarse(T p)", float32types),
176         ("T fwidth(T p)", float32types),
177         ("T fwidthFine(T p)", float32types),
178         ("T fwidthCoarse(T p)", float32types),
179
180         # Interpolation
181         ("T interpolateAtCentroid(T interpolant)", float32types),
182         ("T interpolateAtSample(T interpolant, int sample)", float32types),
183         ("T interpolateAtOffset(T interpolant, vec2 offset)", float32types)
184 ]
185
186 def tokenize(code):
187         out_tokens = []
188         token = ""
189         for i, c in enumerate(code):
190                 if c.isspace():
191                         continue
192
193                 token += c
194                 n = code[i+1] if i+1<len(code) else " "
195
196                 end = False
197                 if token[0].isalpha():
198                         if not n.isalnum():
199                                 end = True
200                 else:
201                         if n.isalnum() or n.isspace():
202                                 end = True
203
204                 if end:
205                         out_tokens.append(token)
206                         token = ""
207
208         return out_tokens
209
210 def expand_tokens(tokens, i, gentype):
211         t = tokens[i]
212         if t=="T":
213                 t = gentype
214         if i+1<len(tokens):
215                 if tokens[i+1]=="::":
216                         return (traits[t][tokens[i+2]], 3)
217                 elif tokens[i+1]=="[":
218                         sub, advance = expand_tokens(tokens, i+2, gentype)
219                         if tokens[i+2+advance]==",":
220                                 sub2, adv2 = expand_tokens(tokens, i+3+advance, gentype)
221                                 advance += 1+adv2
222                                 if sub2==sub:
223                                         t = traits[t]["Mat"]+str(sub)
224                                 else:
225                                         t = traits[t]["Mat"]+"{}x{}".format(sub, sub2)
226                         elif sub>1:
227                                 t = traits[t]["Vec"]+str(sub)
228                         return (t, 3+advance)
229         return (t, 1)
230
231 def expand_template(template, gentype):
232         result = ""
233         special = True
234         tokens = tokenize(template)
235         i = 0
236         while i<len(tokens):
237                 t, advance = expand_tokens(tokens, i, gentype)
238
239                 if not special and t[0].isalpha():
240                         result += " "
241                 special = not t[0].isalpha()
242
243                 result += t
244                 if t[-1]==",":
245                         result += " "
246
247                 i += advance
248
249         return result
250
251 def generate_functions(funcs):
252         out_lines = []
253         generated = set()
254         for f in funcs:
255                 if type(f)==tuple:
256                         for t in f[-1]:
257                                 decl = expand_template(f[0], t)
258                                 if len(f)>=3:
259                                         decl += " {{ return {}; }}".format(expand_template(f[1], t))
260                                 else:
261                                         decl += ";"
262                                 if not decl in generated:
263                                         out_lines.append(decl+"\n")
264                                         generated.add(decl)
265                 else:
266                         out_lines.append(f+";\n")
267
268         return out_lines
269
270 def generate_file(fn):
271         out_lines = []
272         skip = False
273         for line in open(fn):
274                 if not skip:
275                         out_lines.append(line)
276                 if "BEGIN BUILTIN FUNCTIONS" in line:
277                         skip = True
278                         out_lines += generate_functions(shared_funcs)
279                 elif "BEGIN BUILTIN FRAGMENT FUNCTIONS" in line:
280                         skip = True
281                         out_lines += generate_functions(fragment_funcs)
282                 elif "END BUILTIN" in line:
283                         out_lines.append(line)
284                         skip = False
285
286         open(fn, "w").writelines(out_lines)
287
288 if __name__=="__main__":
289         generate_file(sys.argv[1])