]> git.tdb.fi Git - libs/gl.git/blob - scripts/builtin_funcs.py
Add declarations for most of the builtin functions in GLSL
[libs/gl.git] / scripts / builtin_funcs.py
1 #!/usr/bin/python3
2
3 import sys
4
5 traits = {
6         "sampler1D": { "CDim": 1, "IDim": 1 },
7         "sampler2D": { "CDim": 2, "IDim": 2 },
8         "sampler3D": { "CDim": 3, "IDim": 3 },
9         "sampler1DArray": { "CDim": 2, "IDim": 2 },
10         "sampler2DArray": { "CDim": 3, "IDim": 3 },
11         "samplerCube": { "CDim": 3, "IDim": 2 },
12         "samplerCubeArray": { "CDim": 4, "IDim": 3 },
13         "sampler1DShadow": { "CDim": 3, "IDim": 1 },
14         "sampler2DShadow": { "CDim": 3, "IDim": 2 },
15         "samplerCubeShadow": { "CDim": 4, "IDim": 2 },
16         "sampler1DArrayShadow": { "CDim": 3, "IDim": 2 },
17         "sampler2DArrayShadow": { "CDim": 4, "IDim": 3 },
18         "samplerCubeArrayShadow": { "IDim": 3 },
19         "float": { "Base": "float" },
20         "vec2": { "Base": "float" },
21         "vec3": { "Base": "float" },
22         "vec4": { "Base": "float" },
23         "int": { "Base": "int" },
24         "ivec2": { "Base": "int" },
25         "ivec3": { "Base": "int" },
26         "ivec4": { "Base": "int" }
27 }
28
29 float32types = ("float", "vec2", "vec3", "vec4")
30 floattypes = float32types
31 int32types = ("int", "ivec2", "ivec3", "ivec4")
32 signedtypes = floattypes+int32types
33 arithmetictypes = signedtypes
34 squarematrixtypes = ("mat2", "mat3", "mat4")
35 matrixtypes = squarematrixtypes+("mat2x3", "mat3x2", "mat2x4", "mat4x2", "mat3x4", "mat4x3")
36 flatsamplertypes = ("sampler1D", "sampler2D", "sampler3D", "sampler1DArray", "sampler2DArray")
37 colorsamplertypes = flatsamplertypes+("samplerCube", "samplerCubeArray")
38 shadowsamplertypes = ("sampler1DShadow", "sampler2DShadow", "samplerCubeShadow", "sampler1DArrayShadow", "sampler2DArrayShadow", "samplerCubeArrayShadow")
39 samplertypes = colorsamplertypes+shadowsamplertypes
40 funcs = [
41         # Trigonometric
42         ("T sin(T angle)", float32types),
43         ("T cos(T angle)", float32types),
44         ("T tan(T angle)", float32types),
45         ("T asin(T x)", float32types),
46         ("T acos(T x)", float32types),
47         ("T atan(T y, T x)", float32types),
48         ("T sinh(T angle)", float32types),
49         ("T cosh(T angle)", float32types),
50         ("T tanh(T angle)", float32types),
51         ("T asinh(T x)", float32types),
52         ("T acosh(T x)", float32types),
53         ("T atanh(T x)", float32types),
54
55         # Exponential
56         ("T pow(T x, T y)", float32types),
57         ("T exp(T x)", float32types),
58         ("T log(T x)", float32types),
59         ("T exp2(T x)", float32types),
60         ("T log2(T x)", float32types),
61         ("T sqrt(T x)", floattypes),
62         ("T inversesqrt(T x)", floattypes),
63
64         # Common
65         ("T abs(T x)", signedtypes),
66         ("T sign(T x)", signedtypes),
67         ("T floor(T x)", floattypes),
68         ("T trunc(T x)", floattypes),
69         ("T round(T x)", floattypes),
70         ("T roundEven(T x)", floattypes),
71         ("T ceil(T x)", floattypes),
72         ("T fract(T x)", floattypes),
73         ("T mod(T x, T y)", floattypes),
74         ("T mod(T x, T::Base y)", floattypes),
75         ("T modf(T x, out T y)", floattypes),
76         ("T min(T x, T y)", arithmetictypes),
77         ("T min(T x, T::Base y)", arithmetictypes),
78         ("T max(T x, T y)", arithmetictypes),
79         ("T max(T x, T::Base y)", arithmetictypes),
80         ("T clamp(T x, T minVal, T maxVal)", arithmetictypes),
81         ("T clamp(T x, T::Base minVal, T::Base maxVal)", arithmetictypes),
82         ("T mix(T x, T y, T a)", floattypes),
83         ("T mix(T x, T y, T::Base a)", floattypes),
84         ("T step(T edge, T x)", floattypes),
85         ("T step(T::Base edge, T x)", floattypes),
86         ("T smoothstep(T edge0, T edge1, T x)", floattypes),
87         ("T smoothstep(T::Base edge0, T::Base edge1, T x)", floattypes),
88         ("T fma(T a, T b, T c)", floattypes),
89
90         # Geometric
91         ("T::Base length(T x)", floattypes),
92         ("T::Base distance(T p0, T p1)", floattypes),
93         ("T::Base dot(T x, T y)", floattypes),
94         "vec3 cross(vec3 x)",
95         ("T normalize(T x)", floattypes),
96         ("T faceforward(T N, T I, T Nref)", floattypes),
97         ("T reflect(T N, T I)", floattypes),
98         ("T refract(T N, T I, float eta)", floattypes),
99
100         # Matrix
101         ("T matrixCompMult(T x, T y)", matrixtypes),
102         ("T transpose(T m)", squarematrixtypes),
103         ("T determinant(T m)", squarematrixtypes),
104         ("T inverse(T m)", squarematrixtypes),
105
106         # Texture
107         ("int[T::IDim] textureSize(T sampler, int lod)", samplertypes),
108         ("vec4 texture(T sampler, float[T::CDim] P)", colorsamplertypes),
109         ("float texture(T sampler, float[T::CDim] P)", tuple(s for s in shadowsamplertypes if "CubeArray" not in s)),
110         "float texture(samplerCubeArrayShadow sampler, vec4 P, float compare)",
111         ("vec4 textureLod(T sampler, float[T::CDim] P)", colorsamplertypes),
112         ("vec4 texelFetch(T sampler, int[T::CDim] P, int lod)", flatsamplertypes)
113 ]
114
115 def tokenize(code):
116         out_tokens = []
117         token = ""
118         for i, c in enumerate(code):
119                 if c.isspace():
120                         continue
121
122                 token += c
123                 n = code[i+1] if i+1<len(code) else " "
124
125                 end = False
126                 if token[0].isalpha():
127                         if not n.isalnum():
128                                 end = True
129                 else:
130                         if n.isalnum() or n.isspace():
131                                 end = True
132
133                 if end:
134                         out_tokens.append(token)
135                         token = ""
136
137         return out_tokens
138
139 def expand_tokens(tokens, i, gentype):
140         t = tokens[i]
141         if t=="T":
142                 t = gentype
143         if i+1<len(tokens):
144                 if tokens[i+1]=="::":
145                         return (traits[t][tokens[i+2]], 3)
146                 elif tokens[i+1]=="[":
147                         sub, advance = expand_tokens(tokens, i+2, gentype)
148                         if sub>1:
149                                 t = "ivec" if t=="int" else "vec"
150                                 t += str(sub)
151                         return (t, 3+advance)
152         return (t, 1)
153
154 def expand_template(template, gentype):
155         result = ""
156         special = True
157         tokens = tokenize(template)
158         i = 0
159         while i<len(tokens):
160                 t, advance = expand_tokens(tokens, i, gentype)
161
162                 if not special and t[0].isalpha():
163                         result += " "
164                 special = not t[0].isalpha()
165
166                 if t==",":
167                         result += ", "
168                 else:
169                         result += t
170
171                 i += advance
172
173         return result
174
175 def generate_functions():
176         out_lines = []
177         generated = set()
178         for f in funcs:
179                 if type(f)==tuple:
180                         for t in f[1]:
181                                 decl = expand_template(f[0], t)
182                                 if not decl in generated:
183                                         out_lines.append(decl+";\n")
184                                         generated.add(decl)
185                 else:
186                         out_lines.append(f+";\n")
187
188         return out_lines
189
190 def generate_file(fn):
191         out_lines = []
192         skip = False
193         for line in open(fn):
194                 if not skip:
195                         out_lines.append(line)
196                 if "BEGIN BUILTIN FUNCTIONS" in line:
197                         skip = True
198                         out_lines += generate_functions()
199                 elif "END BUILTIN FUNCTIONS" in line:
200                         out_lines.append(line)
201                         skip = False
202
203         open(fn, "w").writelines(out_lines)
204
205 if __name__=="__main__":
206         generate_file(sys.argv[1])