tests: add ext_image_dma_buf_import-tex-modifier
[piglit.git] / generated_tests / gen_tes_input_tests.py
blob954840b201d3eaa3288de2ba2cad65ecbbca138c
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 tessellation control shader to the
26 tessellation evaluation shader.
28 For every combination of varying type as scalar and as two element array and
29 per-vertex or per-patch varying create a test that that passes said variable
30 between the tessellation shader stages.
32 Copy a uniform value to the varying in the tessellation control shader and
33 compare the varying to the same uniform in the tessellation evaluation
34 shader.
35 If the values are equal draw the screen green, red otherwise.
37 Draw for tessellated quads. Each should cover one quarter of the screen.
39 This script outputs, to stdout, the name of each file it generates.
41 """
43 import os
44 import sys
45 import random
46 import textwrap
49 class Test(object):
50 def __init__(self, type_name, array, patch_in, name):
51 """Creates a test.
53 type_name -- varying type to test (e.g.: vec4, mat3x2, int, ...)
54 array -- number of array elements to test, None for no array
55 patch_in -- true for per-patch varying, false for per-vertex varying
56 name -- name of the variable to test
58 """
59 self.var_name = name or 'var'
60 self.use_block = 0 if patch_in else 1
62 if self.var_name == 'gl_Position':
63 self.var_type = 'vec4'
64 self.var_array = None
65 self.patch_in = False
66 elif self.var_name == 'gl_PointSize':
67 self.var_type = 'float'
68 self.var_array = None
69 self.patch_in = False
70 elif self.var_name == 'gl_ClipDistance':
71 self.var_type = 'float'
72 self.var_array = 8
73 self.patch_in = False
74 else:
75 self.var_type = type_name
76 self.var_array = array
77 self.patch_in = patch_in
79 if self.built_in:
80 self.interface_name = 'gl_PerVertex'
81 self.interface_tcs_instance = 'gl_out'
82 self.interface_tes_instance = 'gl_in'
83 else:
84 self.interface_name = 'tc2te_interface'
85 self.interface_tcs_instance = '' if self.patch_in else 'tc2te'
86 self.interface_tes_instance = '' if self.patch_in else 'tc2te'
88 if self.var_array:
89 self.var_type_full = self.var_type + '[{0}]'.format(self.var_array)
90 else:
91 self.var_type_full = self.var_type
93 if self.patch_in:
94 self.interface_prefix = 'patch '
95 self.interface_postfix = ''
96 else:
97 self.interface_prefix = ''
98 self.interface_postfix = '[]'
100 @property
101 def built_in(self):
102 return self.var_name.startswith('gl_')
104 @property
105 def tcs_var_ref(self):
106 return '[gl_InvocationID].' + self.var_name if self.interface_tcs_instance else self.var_name
108 @property
109 def tes_var_ref(self):
110 return '[i].' + self.var_name if self.interface_tes_instance else self.var_name
112 @property
113 def tcs_reference_index(self):
114 return 'gl_PrimitiveID' if self.patch_in else 'gl_PrimitiveID * vertices_in + gl_InvocationID'
116 @property
117 def tes_reference_index(self):
118 return 'gl_PrimitiveID' if self.patch_in else 'gl_PrimitiveID * vertices_in + i'
120 @property
121 def reference_size(self):
122 return 4 if self.patch_in else 12
124 @property
125 def uniform_string(self):
126 """Returns string for loading uniform data by the shader_runner."""
127 data = self.test_data()
128 uniforms = ''
129 if self.var_array:
130 for i in range(self.reference_size):
131 for j in range(self.var_array):
132 uniforms += 'uniform {0} reference[{1}].v[{2}] {3}\n'.format(
133 self.var_type, i, j, data[i*j])
134 else:
135 for i in range(self.reference_size):
136 uniforms += 'uniform {0} reference[{1}].v {2}\n'.format(
137 self.var_type,
139 data[i])
141 #strip last newline
142 return uniforms[:-1]
144 def components(self):
145 """Returns the number of scalar components of the used data type."""
146 n = 1
148 if self.var_type.startswith('mat'):
149 if 'x' in self.var_type:
150 n *= int(self.var_type[-1])
151 n *= int(self.var_type[-3])
152 else:
153 n *= int(self.var_type[-1])
154 n *= int(self.var_type[-1])
155 elif 'vec' in self.var_type:
156 n *= int(self.var_type[-1])
158 return n
160 def test_data(self):
161 """Returns random but deterministic data as a list of strings.
163 n strings are returned containing c random values, each.
164 Where n is the number of vertices times the array length and
165 c is the number of components in the tested scalar data type.
167 random.seed(17)
169 if self.var_array:
170 n = self.var_array * self.reference_size
171 else:
172 n = self.reference_size
174 if self.var_type.startswith('i'):
175 rand = lambda: random.randint(-0x80000000, 0x7fffffff)
176 elif self.var_type.startswith('u'):
177 rand = lambda: random.randint(0, 0xffffffff)
178 else:
179 rand = lambda: ((-1 + 2 * random.randint(0, 1)) *
180 random.randint(0, 2**23-1) *
181 2.0**(random.randint(-126, 127)))
183 c = self.components()
185 ret = []
186 for _ in range(n):
187 ret.append(" ".join(str(rand()) for _ in range(c)))
189 return ret
191 def filename(self):
192 """Returns the file name (including path) for the test."""
193 if self.built_in:
194 name = self.var_name
195 elif self.var_array:
196 name = self.var_type + '_{0}'.format(self.var_array)
197 else:
198 name = self.var_type
199 if self.patch_in:
200 name = 'patch-' + name
201 return os.path.join('spec',
202 'arb_tessellation_shader',
203 'execution',
204 'tes-input',
205 'tes-input-{0}.shader_test'.format(name))
207 def generate(self):
208 """Generates and writes the test to disc."""
209 test = textwrap.dedent("""\
210 # Test generated by:
211 # {generator_command}
212 # Test tessellation evaluation shader inputs
213 [require]
214 GLSL >= 1.50
215 GL_ARB_tessellation_shader
217 [vertex shader]
218 void main()
220 gl_Position = vec4(0);
223 [tessellation control shader]
224 #extension GL_ARB_tessellation_shader : require
225 layout(vertices = 3) out;
227 uniform struct S0 {{
228 {self.var_type_full} v;
229 }} reference[12];
231 #if {self.use_block}
232 {self.interface_prefix}out {self.interface_name} {{
233 {self.var_type_full} {self.var_name};
234 }} {self.interface_tcs_instance}{self.interface_postfix};
235 #else
236 {self.interface_prefix}out {self.var_type_full} {self.var_name};
237 #endif
239 void main()
241 const int vertices_in = 3;
242 {self.interface_tcs_instance}{self.tcs_var_ref} = reference[{self.tcs_reference_index}].v;
243 gl_TessLevelOuter = float[4](1.0, 1.0, 1.0, 1.0);
244 gl_TessLevelInner = float[2](1.0, 1.0);
247 [tessellation evaluation shader]
248 #extension GL_ARB_tessellation_shader : require
249 layout(quads) in;
251 uniform struct S0 {{
252 {self.var_type_full} v;
253 }} reference[12];
255 #if {self.use_block}
256 {self.interface_prefix}in {self.interface_name} {{
257 {self.var_type_full} {self.var_name};
258 }} {self.interface_tes_instance}{self.interface_postfix};
259 #else
260 {self.interface_prefix}in {self.var_type_full} {self.var_name};
261 #endif
263 out vec4 vert_color;
265 void main()
267 const int vertices_in = 3;
268 const vec4 red = vec4(1, 0, 0, 1);
269 const vec4 green = vec4(0, 1, 0, 1);
270 vert_color = green;
271 for (int i = 0; i < vertices_in; ++i)
272 if ({self.interface_tes_instance}{self.tes_var_ref} != reference[{self.tes_reference_index}].v)
273 vert_color = red;
274 vec2[3] position = vec2[3](
275 vec2(float(gl_PrimitiveID / 2) - 1.0, float(gl_PrimitiveID % 2) - 1.0),
276 vec2(float(gl_PrimitiveID / 2) - 0.0, float(gl_PrimitiveID % 2) - 1.0),
277 vec2(float(gl_PrimitiveID / 2) - 1.0, float(gl_PrimitiveID % 2) - 0.0)
279 gl_Position = vec4(position[0]
280 + (position[1] - position[0]) * gl_TessCoord[0]
281 + (position[2] - position[0]) * gl_TessCoord[1], 0.0, 1.0);
284 [fragment shader]
286 in vec4 vert_color;
288 out vec4 frag_color;
290 void main()
292 frag_color = vert_color;
295 [test]
296 {self.uniform_string}
297 draw arrays GL_PATCHES 0 12
298 relative probe rgb (0.25, 0.25) (0.0, 1.0, 0.0)
299 relative probe rgb (0.75, 0.25) (0.0, 1.0, 0.0)
300 relative probe rgb (0.25, 0.75) (0.0, 1.0, 0.0)
301 relative probe rgb (0.75, 0.75) (0.0, 1.0, 0.0)
302 """)
304 test = test.format(self=self, generator_command="generated_tests/gen_tes_input_tests.py")
306 filename = self.filename()
307 dirname = os.path.dirname(filename)
308 if not os.path.exists(dirname):
309 os.makedirs(dirname)
310 with open(filename, 'w') as f:
311 f.write(test)
314 def all_tests():
315 for type_name in ['float', 'vec2', 'vec3', 'vec4',
316 'mat2', 'mat3', 'mat4',
317 'mat2x3', 'mat2x4', 'mat3x2',
318 'mat3x4', 'mat4x2', 'mat4x3',
319 'int', 'ivec2', 'ivec3', 'ivec4',
320 'uint', 'uvec2', 'uvec3', 'uvec4']:
321 for array in [None, 2]:
322 for patch_in in [True, False]:
323 yield Test(type_name, array, patch_in, name=None)
324 for var in ['gl_Position', 'gl_PointSize', 'gl_ClipDistance']:
325 yield Test(type_name=None, array=None, patch_in=False, name=var)
328 def main():
329 for test in all_tests():
330 test.generate()
331 print(test.filename())
334 if __name__ == '__main__':
335 main()