cmake: move first batch of option() at the beggining of the file
[piglit.git] / generated_tests / gen_tcs_input_tests.py
blob118a9652e840fb0c1baceb1d46801c99f64a5dc9
1 #!/usr/bin/env python
2 # coding=utf-8
4 # Copyright © 2014 The Piglit Project
6 # Permission is hereby granted, free of charge, to any person obtaining a
7 # copy of this software and associated documentation files (the "Software"),
8 # to deal in the Software without restriction, including without limitation
9 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 # and/or sell copies of the Software, and to permit persons to whom the
11 # Software is furnished to do so, subject to the following conditions:
13 # The above copyright notice and this permission notice (including the next
14 # paragraph) shall be included in all copies or substantial portions of the
15 # Software.
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 # DEALINGS IN THE SOFTWARE.
25 """Test passing variables from the vertex shader to the tessellation control
26 shader.
28 For every varying type create one tests that passes a scalar of that type
29 and one test that passes a two element array.
30 Copy a uniform value to the varying in the vertex shader and compare the
31 varying to the same uniform in the tessellation control shader.
32 If the values are equal draw the screen green, red otherwise.
34 Draw for tessellated quads. Each should cover one quarter of the screen.
36 This script outputs, to stdout, the name of each file it generates.
38 """
40 import os
41 import sys
42 import random
43 import textwrap
46 class Test(object):
47 def __init__(self, type_name, array, name):
48 """Creates a test.
50 type_name -- varying type to test (e.g.: vec4, mat3x2, int, ...)
51 array -- number of array elements to test, None for no array
52 name -- name of the variable to test
54 """
55 self.var_name = name or 'var'
57 if self.var_name == 'gl_Position':
58 self.var_type = 'vec4'
59 self.var_array = None
60 elif self.var_name == 'gl_PointSize':
61 self.var_type = 'float'
62 self.var_array = None
63 elif self.var_name == 'gl_ClipDistance':
64 self.var_type = 'float'
65 self.var_array = 8
66 else:
67 self.var_type = type_name
68 self.var_array = array
70 if self.built_in:
71 self.interface_name = 'gl_PerVertex'
72 self.interface_vs_instance = ''
73 self.interface_tcs_instance = 'gl_in'
74 else:
75 self.interface_name = 'v2tc_interface'
76 self.interface_vs_instance = ''
77 self.interface_tcs_instance = 'v2tc'
79 if self.var_array:
80 self.var_type_full = self.var_type + '[{0}]'.format(self.var_array)
81 else:
82 self.var_type_full = self.var_type
84 @property
85 def built_in(self):
86 return self.var_name.startswith('gl_')
88 @property
89 def vs_var_ref(self):
90 return '.' + self.var_name if self.interface_vs_instance else self.var_name
92 @property
93 def tcs_var_ref(self):
94 return '.' + self.var_name if self.interface_tcs_instance else self.var_name
96 @property
97 def uniform_string(self):
98 """Returns string for loading uniform data by the shader_runner."""
99 data = self.test_data()
100 uniforms = ''
101 if self.var_array:
102 for i in range(12):
103 for j in range(self.var_array):
104 uniforms += 'uniform {0} reference[{1}].v[{2}] {3}\n'.format(
105 self.var_type, i, j, data[i*j])
106 else:
107 for i in range(12):
108 uniforms += 'uniform {0} reference[{1}].v {2}\n'.format(
109 self.var_type,
111 data[i])
113 #strip last newline
114 return uniforms[:-1]
116 def components(self):
117 """Returns the number of scalar components of the used data type."""
118 n = 1
120 if self.var_type.startswith('mat'):
121 if 'x' in self.var_type:
122 n *= int(self.var_type[-1])
123 n *= int(self.var_type[-3])
124 else:
125 n *= int(self.var_type[-1])
126 n *= int(self.var_type[-1])
127 elif 'vec' in self.var_type:
128 n *= int(self.var_type[-1])
130 return n
132 def test_data(self):
133 """Returns random but deterministic data as a list of strings.
135 n strings are returned containing c random values, each.
136 Where n is the number of vertices times the array length and
137 c is the number of components in the tested scalar data type.
139 random.seed(17)
141 if self.var_array:
142 n = self.var_array * 12
143 else:
144 n = 12
146 if self.var_type.startswith('i'):
147 rand = lambda: random.randint(-0x80000000, 0x7fffffff)
148 elif self.var_type.startswith('u'):
149 rand = lambda: random.randint(0, 0xffffffff)
150 else:
151 rand = lambda: ((-1 + 2 * random.randint(0, 1)) *
152 random.randint(0, 2**23-1) *
153 2.0**(random.randint(-126, 127)))
155 c = self.components()
157 ret = []
158 for _ in range(n):
159 ret.append(" ".join(str(rand()) for _ in range(c)))
161 return ret
163 def filename(self):
164 """Returns the file name (including path) for the test."""
165 if self.built_in:
166 name = self.var_name
167 elif self.var_array:
168 name = self.var_type + '_{0}'.format(self.var_array)
169 else:
170 name = self.var_type
171 return os.path.join('spec',
172 'arb_tessellation_shader',
173 'execution',
174 'tcs-input',
175 'tcs-input-{0}.shader_test'.format(name))
177 def generate(self):
178 """Generates and writes the test to disc."""
179 test = textwrap.dedent("""\
180 # Test generated by:
181 # {generator_command}
182 # Test tessellation control shader inputs
183 [require]
184 GLSL >= 1.50
185 GL_ARB_tessellation_shader
187 [vertex shader]
188 uniform struct S0 {{
189 {self.var_type_full} v;
190 }} reference[12];
192 out {self.interface_name} {{
193 {self.var_type_full} {self.var_name};
194 }} {self.interface_vs_instance};
196 void main()
198 {self.interface_vs_instance}{self.vs_var_ref} = reference[gl_VertexID].v;
201 [tessellation control shader]
202 #extension GL_ARB_tessellation_shader : require
203 layout(vertices = 3) out;
205 uniform struct S0 {{
206 {self.var_type_full} v;
207 }} reference[12];
209 in {self.interface_name} {{
210 {self.var_type_full} {self.var_name};
211 }} {self.interface_tcs_instance}[];
213 out int pass[];
215 void main()
217 const int vertices_in = 3;
218 int local_pass = 1;
219 for (int i = 0; i < vertices_in; ++i) {{
220 int vertex_ID = gl_PrimitiveID * vertices_in + i;
221 if ({self.interface_tcs_instance}[i]{self.tcs_var_ref} != reference[vertex_ID].v)
222 local_pass = 0;
224 pass[gl_InvocationID] = local_pass;
225 gl_TessLevelOuter = float[4](1.0, 1.0, 1.0, 1.0);
226 gl_TessLevelInner = float[2](1.0, 1.0);
229 [tessellation evaluation shader]
230 #extension GL_ARB_tessellation_shader : require
231 layout(quads) in;
233 in int pass[];
235 out vec4 vert_color;
237 void main()
239 const vec4 red = vec4(1, 0, 0, 1);
240 const vec4 green = vec4(0, 1, 0, 1);
241 vec2[3] position = vec2[3](
242 vec2(float(gl_PrimitiveID / 2) - 1.0, float(gl_PrimitiveID % 2) - 1.0),
243 vec2(float(gl_PrimitiveID / 2) - 0.0, float(gl_PrimitiveID % 2) - 1.0),
244 vec2(float(gl_PrimitiveID / 2) - 1.0, float(gl_PrimitiveID % 2) - 0.0)
246 gl_Position = vec4(position[0]
247 + (position[1] - position[0]) * gl_TessCoord[0]
248 + (position[2] - position[0]) * gl_TessCoord[1], 0.0, 1.0);
249 vert_color = green;
250 if (pass[0] == 0 || pass[1] == 0 || pass[2] == 0) {{
251 vert_color = red;
255 [fragment shader]
257 in vec4 vert_color;
259 out vec4 frag_color;
261 void main()
263 frag_color = vert_color;
266 [test]
267 {self.uniform_string}
268 draw arrays GL_PATCHES 0 12
269 relative probe rgb (0.25, 0.25) (0.0, 1.0, 0.0)
270 relative probe rgb (0.75, 0.25) (0.0, 1.0, 0.0)
271 relative probe rgb (0.25, 0.75) (0.0, 1.0, 0.0)
272 relative probe rgb (0.75, 0.75) (0.0, 1.0, 0.0)
273 """)
275 test = test.format(self=self, generator_command="generated_tests/gen_tcs_input_tests.py")
277 filename = self.filename()
278 dirname = os.path.dirname(filename)
279 if not os.path.exists(dirname):
280 os.makedirs(dirname)
281 with open(filename, 'w') as f:
282 f.write(test)
285 def all_tests():
286 for type_name in ['float', 'vec2', 'vec3', 'vec4',
287 'mat2', 'mat3', 'mat4',
288 'mat2x3', 'mat2x4', 'mat3x2',
289 'mat3x4', 'mat4x2', 'mat4x3',
290 'int', 'ivec2', 'ivec3', 'ivec4',
291 'uint', 'uvec2', 'uvec3', 'uvec4']:
292 for array in [None, 2]:
293 yield Test(type_name=type_name, array=array, name=None)
294 for var in ['gl_Position', 'gl_PointSize', 'gl_ClipDistance']:
295 yield Test(type_name=None, array=None, name=var)
298 def main():
299 for test in all_tests():
300 test.generate()
301 print(test.filename())
304 if __name__ == '__main__':
305 main()