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
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
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.
47 def __init__(self
, type_name
, array
, name
):
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
55 self
.var_name
= name
or 'var'
57 if self
.var_name
== 'gl_Position':
58 self
.var_type
= 'vec4'
60 elif self
.var_name
== 'gl_PointSize':
61 self
.var_type
= 'float'
63 elif self
.var_name
== 'gl_ClipDistance':
64 self
.var_type
= 'float'
67 self
.var_type
= type_name
68 self
.var_array
= array
71 self
.interface_name
= 'gl_PerVertex'
72 self
.interface_vs_instance
= ''
73 self
.interface_tcs_instance
= 'gl_in'
75 self
.interface_name
= 'v2tc_interface'
76 self
.interface_vs_instance
= ''
77 self
.interface_tcs_instance
= 'v2tc'
80 self
.var_type_full
= self
.var_type
+ '[{0}]'.format(self
.var_array
)
82 self
.var_type_full
= self
.var_type
86 return self
.var_name
.startswith('gl_')
90 return '.' + self
.var_name
if self
.interface_vs_instance
else self
.var_name
93 def tcs_var_ref(self
):
94 return '.' + self
.var_name
if self
.interface_tcs_instance
else self
.var_name
97 def uniform_string(self
):
98 """Returns string for loading uniform data by the shader_runner."""
99 data
= self
.test_data()
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
])
108 uniforms
+= 'uniform {0} reference[{1}].v {2}\n'.format(
116 def components(self
):
117 """Returns the number of scalar components of the used data type."""
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])
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])
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.
142 n
= self
.var_array
* 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)
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()
159 ret
.append(" ".join(str(rand()) for _
in range(c
)))
164 """Returns the file name (including path) for the test."""
168 name
= self
.var_type
+ '_{0}'.format(self
.var_array
)
171 return os
.path
.join('spec',
172 'arb_tessellation_shader',
175 'tcs-input-{0}.shader_test'.format(name
))
178 """Generates and writes the test to disc."""
179 test
= textwrap
.dedent("""\
181 # {generator_command}
182 # Test tessellation control shader inputs
185 GL_ARB_tessellation_shader
189 {self.var_type_full} v;
192 out {self.interface_name} {{
193 {self.var_type_full} {self.var_name};
194 }} {self.interface_vs_instance};
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;
206 {self.var_type_full} v;
209 in {self.interface_name} {{
210 {self.var_type_full} {self.var_name};
211 }} {self.interface_tcs_instance}[];
217 const int vertices_in = 3;
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)
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
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);
250 if (pass[0] == 0 || pass[1] == 0 || pass[2] == 0) {{
263 frag_color = vert_color;
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)
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
):
281 with
open(filename
, 'w') as f
:
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
)
299 for test
in all_tests():
301 print(test
.filename())
304 if __name__
== '__main__':