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.
40 from __future__
import print_function
, division
, absolute_import
46 from six
.moves
import range
50 def __init__(self
, type_name
, array
, name
):
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 name -- name of the variable to test
58 self
.var_name
= name
or 'var'
60 if self
.var_name
== 'gl_Position':
61 self
.var_type
= 'vec4'
63 elif self
.var_name
== 'gl_PointSize':
64 self
.var_type
= 'float'
66 elif self
.var_name
== 'gl_ClipDistance':
67 self
.var_type
= 'float'
70 self
.var_type
= type_name
71 self
.var_array
= array
74 self
.interface_name
= 'gl_PerVertex'
75 self
.interface_vs_instance
= ''
76 self
.interface_tcs_instance
= 'gl_in'
78 self
.interface_name
= 'v2tc_interface'
79 self
.interface_vs_instance
= ''
80 self
.interface_tcs_instance
= 'v2tc'
83 self
.var_type_full
= self
.var_type
+ '[{0}]'.format(self
.var_array
)
85 self
.var_type_full
= self
.var_type
89 return self
.var_name
.startswith('gl_')
93 return '.' + self
.var_name
if self
.interface_vs_instance
else self
.var_name
96 def tcs_var_ref(self
):
97 return '.' + self
.var_name
if self
.interface_tcs_instance
else self
.var_name
100 def uniform_string(self
):
101 """Returns string for loading uniform data by the shader_runner."""
102 data
= self
.test_data()
106 for j
in range(self
.var_array
):
107 uniforms
+= 'uniform {0} reference[{1}].v[{2}] {3}\n'.format(
108 self
.var_type
, i
, j
, data
[i
*j
])
111 uniforms
+= 'uniform {0} reference[{1}].v {2}\n'.format(
119 def components(self
):
120 """Returns the number of scalar components of the used data type."""
123 if self
.var_type
.startswith('mat'):
124 if 'x' in self
.var_type
:
125 n
*= int(self
.var_type
[-1])
126 n
*= int(self
.var_type
[-3])
128 n
*= int(self
.var_type
[-1])
129 n
*= int(self
.var_type
[-1])
130 elif 'vec' in self
.var_type
:
131 n
*= int(self
.var_type
[-1])
136 """Returns random but deterministic data as a list of strings.
138 n strings are returned containing c random values, each.
139 Where n is the number of vertices times the array length and
140 c is the number of components in the tested scalar data type.
145 n
= self
.var_array
* 12
149 if self
.var_type
.startswith('i'):
150 rand
= lambda: random
.randint(-0x80000000, 0x7fffffff)
151 elif self
.var_type
.startswith('u'):
152 rand
= lambda: random
.randint(0, 0xffffffff)
154 rand
= lambda: ((-1 + 2 * random
.randint(0, 1)) *
155 random
.randint(0, 2**23-1) *
156 2.0**(random
.randint(-126, 127)))
158 c
= self
.components()
162 ret
.append(" ".join(str(rand()) for _
in range(c
)))
167 """Returns the file name (including path) for the test."""
171 name
= self
.var_type
+ '_{0}'.format(self
.var_array
)
174 return os
.path
.join('spec',
175 'arb_tessellation_shader',
178 'tcs-input-{0}.shader_test'.format(name
))
181 """Generates and writes the test to disc."""
182 test
= textwrap
.dedent("""\
184 # {generator_command}
185 # Test tessellation control shader inputs
188 GL_ARB_tessellation_shader
192 {self.var_type_full} v;
195 out {self.interface_name} {{
196 {self.var_type_full} {self.var_name};
197 }} {self.interface_vs_instance};
201 {self.interface_vs_instance}{self.vs_var_ref} = reference[gl_VertexID].v;
204 [tessellation control shader]
205 #extension GL_ARB_tessellation_shader : require
206 layout(vertices = 3) out;
209 {self.var_type_full} v;
212 in {self.interface_name} {{
213 {self.var_type_full} {self.var_name};
214 }} {self.interface_tcs_instance}[];
220 const int vertices_in = 3;
222 for (int i = 0; i < vertices_in; ++i) {{
223 int vertex_ID = gl_PrimitiveID * vertices_in + i;
224 if ({self.interface_tcs_instance}[i]{self.tcs_var_ref} != reference[vertex_ID].v)
227 pass[gl_InvocationID] = local_pass;
228 gl_TessLevelOuter = float[4](1.0, 1.0, 1.0, 1.0);
229 gl_TessLevelInner = float[2](1.0, 1.0);
232 [tessellation evaluation shader]
233 #extension GL_ARB_tessellation_shader : require
242 const vec4 red = vec4(1, 0, 0, 1);
243 const vec4 green = vec4(0, 1, 0, 1);
244 vec2[3] position = vec2[3](
245 vec2(float(gl_PrimitiveID / 2) - 1.0, float(gl_PrimitiveID % 2) - 1.0),
246 vec2(float(gl_PrimitiveID / 2) - 0.0, float(gl_PrimitiveID % 2) - 1.0),
247 vec2(float(gl_PrimitiveID / 2) - 1.0, float(gl_PrimitiveID % 2) - 0.0)
249 gl_Position = vec4(position[0]
250 + (position[1] - position[0]) * gl_TessCoord[0]
251 + (position[2] - position[0]) * gl_TessCoord[1], 0.0, 1.0);
253 if (pass[0] == 0 || pass[1] == 0 || pass[2] == 0) {{
266 frag_color = vert_color;
270 {self.uniform_string}
271 draw arrays GL_PATCHES 0 12
272 relative probe rgb (0.25, 0.25) (0.0, 1.0, 0.0)
273 relative probe rgb (0.75, 0.25) (0.0, 1.0, 0.0)
274 relative probe rgb (0.25, 0.75) (0.0, 1.0, 0.0)
275 relative probe rgb (0.75, 0.75) (0.0, 1.0, 0.0)
278 test
= test
.format(self
=self
, generator_command
=" ".join(sys
.argv
))
280 filename
= self
.filename()
281 dirname
= os
.path
.dirname(filename
)
282 if not os
.path
.exists(dirname
):
284 with
open(filename
, 'w') as f
:
289 for type_name
in ['float', 'vec2', 'vec3', 'vec4',
290 'mat2', 'mat3', 'mat4',
291 'mat2x3', 'mat2x4', 'mat3x2',
292 'mat3x4', 'mat4x2', 'mat4x3',
293 'int', 'ivec2', 'ivec3', 'ivec4',
294 'uint', 'uvec2', 'uvec3', 'uvec4']:
295 for array
in [None, 2]:
296 yield Test(type_name
=type_name
, array
=array
, name
=None)
297 for var
in ['gl_Position', 'gl_PointSize', 'gl_ClipDistance']:
298 yield Test(type_name
=None, array
=None, name
=var
)
302 for test
in all_tests():
304 print(test
.filename())
307 if __name__
== '__main__':