3 # Copyright © 2011 Intel Corporation
5 # Permission is hereby granted, free of charge, to any person obtaining a
6 # copy of this software and associated documentation files (the "Software"),
7 # to deal in the Software without restriction, including without limitation
8 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 # and/or sell copies of the Software, and to permit persons to whom the
10 # Software is furnished to do so, subject to the following conditions:
12 # The above copyright notice and this permission notice (including the next
13 # paragraph) shall be included in all copies or substantial portions of the
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 # DEALINGS IN THE SOFTWARE.
24 # Generate a set of shader_runner tests for every overloaded version
25 # of every built-in function, based on the test vectors computed by
26 # builtin_function.py.
28 # In each set of generated tests, one test exercises the built-in
29 # function in each type of shader (vertex, geometry, and fragment).
30 # In all cases, the inputs to the built-in function come from
31 # uniforms, so that the effectiveness of the test won't be
32 # circumvented by constant folding in the GLSL compiler.
34 # The tests operate by invoking the built-in function in the
35 # appropriate shader, applying a scale and offset so that the expected
36 # values are in the range [0.25, 0.75], and then outputting the result
37 # as a solid rgba color, which is then checked using shader_runner's
38 # "probe rgba" command.
40 # For built-in functions whose result type is a matrix, the test
41 # checks one column at a time.
43 # This program outputs, to stdout, the name of each file it generates.
44 # With the optional argument --names-only, it only outputs the names
45 # of the files; it doesn't generate them.
47 from builtin_function
import *
54 from modules
import utils
57 def compute_offset_and_scale(test_vectors
):
58 """Compute scale and offset values such that for each result in
59 test_vectors, (result - offset) * scale is in the range [0.25,
60 0.75], and scale is less than or equal to 1.0. These values are
61 used to transform the test vectors so that their outputs can be
62 stored in gl_FragColor without overflow.
64 low
= min(numpy
.min(tv
.result
) for tv
in test_vectors
)
65 hi
= max(numpy
.max(tv
.result
) for tv
in test_vectors
)
67 center
= (hi
+ low
)/2.0
71 offset
= center
- span
/2.0
76 def shader_runner_format(values
):
77 """Format the given values for use in a shader_runner "uniform" or
78 "probe rgba" command. Bools are converted to 0's and 1's, and
79 values are separated by spaces.
81 transformed_values
= []
83 if isinstance(value
, (bool, np
.bool_
)):
84 transformed_values
.append(int(value
))
86 transformed_values
.append(value
)
87 return ' '.join(repr(x
) for x
in transformed_values
)
90 def shader_runner_type(glsl_type
):
91 """Return the appropriate type name necessary for binding a
92 uniform of the given type using shader_runner's "uniform" command.
93 Boolean values and vectors are converted to ints, and square
94 matrices are written in "matNxN" form.
96 if glsl_type
.base_type
== glsl_bool
:
97 if glsl_type
.is_scalar
:
100 return 'ivec{0}'.format(glsl_type
.num_rows
)
101 elif glsl_type
.is_matrix
:
102 return 'mat{0}x{1}'.format(glsl_type
.num_cols
, glsl_type
.num_rows
)
104 return str(glsl_type
)
107 class Comparator(object):
108 """Base class which abstracts how we compare expected and actual
111 __metaclass__
= abc
.ABCMeta
113 def make_additional_declarations(self
):
114 """Return additional declarations, if any, that are needed in
120 def make_result_handler(self
, invocation
, output_var
):
121 """Return the shader code that is needed to produce the result
122 and store it in output_var.
124 invocation is the GLSL code to compute the output of the
129 def draw_test(self
, test_vector
, draw_command
):
130 """Return the shader_runner test code that is needed to run a
135 def result_vector(self
, test_vector
):
136 """Return the expected result color as a list of floats."""
138 def testname_suffix(self
):
139 """Return a string to be used as a suffix on the test name to
140 distinguish it from tests using other comparators."""
144 class BoolComparator(Comparator
):
145 """Comparator that tests functions returning bools and bvecs by
146 converting them to floats.
148 This comparator causes code to be generated in the following form:
150 rettype result = func(args);
151 output_var = vec4(result, 0.0, ...);
153 def __init__(self
, signature
):
154 assert not signature
.rettype
.is_matrix
155 self
.__signature
= signature
156 self
.__padding
= 4 - signature
.rettype
.num_rows
158 def make_result_handler(self
, invocation
, output_var
):
159 statements
= ' {0} result = {1};\n'.format(
160 self
.__signature
.rettype
, invocation
)
161 statements
+= ' {0} = vec4(result{1});\n'.format(
162 output_var
, ', 0.0' * self
.__padding
)
165 def convert_to_float(self
, value
):
166 """Convert the given vector or scalar value to a list of
167 floats representing the expected color produced by the test.
169 value
= value
*1.0 # convert bools to floats
170 value
= column_major_values(value
)
171 value
+= [0.0] * self
.__padding
174 def draw_test(self
, test_vector
, draw_command
):
177 def result_vector(self
, test_vector
):
178 return self
.convert_to_float(test_vector
.result
)
181 class BoolIfComparator(Comparator
):
182 """Comparator that tests functions returning bools by evaluating
183 them inside an if statement.
185 This comparator causes code to be generated in the following form:
188 output_var = vec4(1.0, 1.0, 0.0, 1.0);
190 output_var = vecp(0.0, 0.0, 1.0, 1.0);
192 def __init__(self
, signature
):
193 assert signature
.rettype
== glsl_bool
194 self
.__padding
= 4 - signature
.rettype
.num_rows
196 def make_result_handler(self
, invocation
, output_var
):
197 statements
= ' if({0})\n'.format(invocation
)
198 statements
+= ' {0} = vec4(1.0, 1.0, 0.0, 1.0);\n'.format(
200 statements
+= ' else\n'
201 statements
+= ' {0} = vec4(0.0, 0.0, 1.0, 1.0);\n'.format(
205 def convert_to_float(self
, value
):
206 """Convert the given vector or scalar value to a list of
207 floats representing the expected color produced by the test.
210 return [1.0, 1.0, 0.0, 1.0]
212 return [0.0, 0.0, 1.0, 1.0]
214 def draw_test(self
, test_vector
, draw_command
):
217 def result_vector(self
, test_vector
):
218 return self
.convert_to_float(test_vector
.result
)
220 def testname_suffix(self
):
224 class IntComparator(Comparator
):
225 """Comparator that tests functions returning ints or ivecs using a
226 strict equality test.
228 This comparator causes code to be generated in the following form:
230 rettype result = func(args);
231 output_var = result == expected ? vec4(0.0, 1.0, 0.0, 1.0)
232 : vec4(1.0, 0.0, 0.0, 1.0);
234 def __init__(self
, signature
):
235 self
.__signature
= signature
237 def make_additional_declarations(self
):
238 return 'uniform {0} expected;\n'.format(self
.__signature
.rettype
)
240 def make_result_handler(self
, invocation
, output_var
):
241 statements
= ' {0} result = {1};\n'.format(
242 self
.__signature
.rettype
, invocation
)
243 statements
+= ' {v} = {cond} ? {green} : {red};\n'.format(
244 v
=output_var
, cond
='result == expected',
245 green
='vec4(0.0, 1.0, 0.0, 1.0)',
246 red
='vec4(1.0, 0.0, 0.0, 1.0)')
249 def draw_test(self
, test_vector
, draw_command
):
250 test
= 'uniform {0} expected {1}\n'.format(
251 shader_runner_type(self
.__signature
.rettype
),
252 shader_runner_format(column_major_values(test_vector
.result
)))
256 def result_vector(self
, test_vector
):
257 return [0.0, 1.0, 0.0, 1.0]
260 class FloatComparator(Comparator
):
261 """Comparator that tests functions returning floats or vecs using a
262 strict equality test.
264 This comparator causes code to be generated in the following form:
266 rettype result = func(args);
267 output_var = distance(result, expected) <= tolerance
268 ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);
270 def __init__(self
, signature
):
271 self
.__signature
= signature
273 def make_additional_declarations(self
):
274 decls
= 'uniform float tolerance;\n'
275 decls
+= 'uniform {0} expected;\n'.format(self
.__signature
.rettype
)
278 def make_indexers(self
):
279 """Build a list of strings which index into every possible
280 value of the result. For example, if the result is a vec2,
281 then build the indexers ['[0]', '[1]'].
283 if self
.__signature
.rettype
.num_cols
== 1:
286 col_indexers
= ['[{0}]'.format(i
)
287 for i
in range(self
.__signature
.rettype
.num_cols
)]
288 if self
.__signature
.rettype
.num_rows
== 1:
291 row_indexers
= ['[{0}]'.format(i
)
292 for i
in range(self
.__signature
.rettype
.num_rows
)]
293 return [col_indexer
+ row_indexer
294 for col_indexer
in col_indexers
295 for row_indexer
in row_indexers
]
297 def make_result_handler(self
, invocation
, output_var
):
298 statements
= ' {0} result = {1};\n'.format(
299 self
.__signature
.rettype
, invocation
)
300 # Can't use distance when testing itself, or when the rettype
302 if self
.__signature
.name
== 'distance' or \
303 self
.__signature
.rettype
.is_matrix
:
304 statements
+= ' {0} residual = result - expected;\n'.format(
305 self
.__signature
.rettype
)
306 statements
+= ' float error_sq = {0};\n'.format(
308 'residual{0} * residual{0}'.format(indexer
)
309 for indexer
in self
.make_indexers()))
310 condition
= 'error_sq <= tolerance * tolerance'
312 condition
= 'distance(result, expected) <= tolerance'
313 statements
+= ' {v} = {cond} ? {green} : {red};\n'.format(
314 v
=output_var
, cond
=condition
, green
='vec4(0.0, 1.0, 0.0, 1.0)',
315 red
='vec4(1.0, 0.0, 0.0, 1.0)')
318 def draw_test(self
, test_vector
, draw_command
):
319 test
= 'uniform {0} expected {1}\n'.format(
320 shader_runner_type(self
.__signature
.rettype
),
321 shader_runner_format(column_major_values(test_vector
.result
)))
322 test
+= 'uniform float tolerance {0}\n'.format(
323 shader_runner_format([test_vector
.tolerance
]))
327 def result_vector(self
, test_vector
):
328 return [0.0, 1.0, 0.0, 1.0]
331 class ShaderTest(object):
332 """Class used to build a test of a single built-in. This is an
333 abstract base class--derived types should override test_prefix(),
334 make_vertex_shader(), make_fragment_shader(), and other functions
337 __metaclass__
= abc
.ABCMeta
339 def __init__(self
, signature
, test_vectors
, use_if
):
340 """Prepare to build a test for a single built-in. signature
341 is the signature of the built-in (a key from the
342 builtin_function.test_suite dict), and test_vectors is the
343 list of test vectors for testing the given builtin (the
344 corresponding value from the builtin_function.test_suite
347 If use_if is True, then the generated test checks the result
348 by using it in an if statement--this only works for builtins
351 self
._signature
= signature
352 self
._test
_vectors
= test_vectors
354 # Size of the rectangles drawn by the test.
357 # shader_runner currently defaults to a 250x250 window. We
358 # could reduce window size to cut test time, but there are
359 # platform-dependent limits we haven't really characterized
360 # (smaller on Linux than Windows, but still present in some
363 self
.win_height
= 250
364 self
.tests_per_row
= (self
.win_width
// self
.rect_width
)
365 self
.test_rows
= (self
.win_height
// self
.rect_height
)
368 self
._comparator
= BoolIfComparator(signature
)
369 elif signature
.rettype
.base_type
== glsl_bool
:
370 self
._comparator
= BoolComparator(signature
)
371 elif signature
.rettype
.base_type
== glsl_float
:
372 self
._comparator
= FloatComparator(signature
)
373 elif signature
.rettype
.base_type
in (glsl_int
, glsl_uint
):
374 self
._comparator
= IntComparator(signature
)
375 elif signature
.rettype
.base_type
in (glsl_int64_t
, glsl_uint64_t
):
376 self
._comparator
= IntComparator(signature
)
378 raise Exception('Unexpected rettype {0}'.format(signature
.rettype
))
380 def glsl_version(self
):
381 return self
._signature
.version_introduced
383 def draw_command(self
, test_num
):
384 x
= (test_num
% self
.tests_per_row
) * self
.rect_width
385 y
= (test_num
// self
.tests_per_row
) * self
.rect_height
386 assert(y
+ self
.rect_height
<= self
.win_height
)
387 return 'draw rect ortho {0} {1} {2} {3}\n'.format(x
, y
,
391 def probe_command(self
, test_num
, probe_vector
):
392 return 'probe rect rgba ({0}, {1}, {2}, {3}) ({4}, {5}, {6}, {7})\n'.format(
393 (test_num
% self
.tests_per_row
) * self
.rect_width
,
394 (test_num
// self
.tests_per_row
) * self
.rect_height
,
397 probe_vector
[0], probe_vector
[1], probe_vector
[2], probe_vector
[3])
399 def extensions(self
):
401 if self
._signature
.extension
:
402 ext
.append(self
._signature
.extension
)
405 def make_additional_requirements(self
):
406 """Return a string that should be included in the test's
412 def test_prefix(self
):
413 """Return the prefix that should be used in the test file name
414 to identify the type of test, e.g. "vs" for a vertex shader
418 def make_vertex_shader(self
):
419 """Return the vertex shader for this test (or None if this
420 test doesn't require a vertex shader). No need to
421 reimplement this function in classes that don't use vertex
426 def make_tess_ctrl_shader(self
):
427 """Return the tessellation control shader for this test
428 (or None if this test doesn't require a geometry shader).
429 No need to reimplement this function in classes that don't
430 use geometry shaders.
434 def make_tess_eval_shader(self
):
435 """Return the tessellation evaluation shader for this test
436 (or None if this test doesn't require a geometry shader).
437 No need to reimplement this function in classes that don't
438 use geometry shaders.
442 def make_geometry_shader(self
):
443 """Return the geometry shader for this test (or None if this
444 test doesn't require a geometry shader). No need to
445 reimplement this function in classes that don't use geometry
450 def make_geometry_layout(self
):
451 """Return the geometry layout for this test (or None if this
452 test doesn't require a geometry layout section). No need to
453 reimplement this function in classes that don't use geometry
458 def make_fragment_shader(self
):
459 """Return the fragment shader for this test (or None if this
460 test doesn't require a fragment shader). No need to
461 reimplement this function in classes that don't use fragment
466 def make_compute_shader(self
):
467 """Return the compute shader for this test (or None if this test
468 doesn't require a compute shader). No need to reimplement
469 this function in classes that don't use compute shaders.
473 def needs_probe_per_draw(self
):
474 """Returns whether the test needs the probe to be immediately after each
480 def make_test_shader(self
, additional_declarations
, prefix_statements
,
481 output_var
, suffix_statements
):
482 """Generate the shader code necessary to test the built-in.
483 additional_declarations is a string containing any
484 declarations that need to be before the main() function of the
485 shader. prefix_statements is a string containing any
486 additional statements than need to be inside the main()
487 function of the shader, before the built-in function is
488 called. output_var is the variable that the result of the
489 built-in function should be assigned to, after conversion to a
490 vec4. suffix_statements is a string containing any additional
491 statements that need to be inside the main() function of the
492 shader, after the built-in function is called.
495 for ext
in self
.extensions():
496 shader
+= '#extension GL_{0} : require\n'.format(ext
)
497 shader
+= additional_declarations
498 for i
in range(len(self
._signature
.argtypes
)):
499 shader
+= 'uniform {0} arg{1};\n'.format(
500 self
._signature
.argtypes
[i
], i
)
501 shader
+= self
._comparator
.make_additional_declarations()
503 shader
+= 'void main()\n'
505 shader
+= prefix_statements
506 invocation
= self
._signature
.template
.format(
508 for i
in range(len(self
._signature
.argtypes
))])
509 shader
+= self
._comparator
.make_result_handler(invocation
, output_var
)
510 shader
+= suffix_statements
514 def make_test_init(self
):
515 """Generate initialization for the test.
520 """Make the complete shader_runner test file, and return it as
523 test
= self
.make_test_init()
524 for test_num
, test_vector
in enumerate(self
._test
_vectors
):
525 for i
in range(len(test_vector
.arguments
)):
526 test
+= 'uniform {0} arg{1} {2}\n'.format(
527 shader_runner_type(self
._signature
.argtypes
[i
]),
528 i
, shader_runner_format(
529 column_major_values(test_vector
.arguments
[i
])))
530 test
+= self
._comparator
.draw_test(test_vector
,
531 self
.draw_command(test_num
))
532 if self
.needs_probe_per_draw():
533 result_color
= self
._comparator
.result_vector(test_vector
)
534 test
+= self
.probe_command(test_num
, result_color
)
536 if not self
.needs_probe_per_draw():
537 for test_num
, test_vector
in enumerate(self
._test
_vectors
):
538 result_color
= self
._comparator
.result_vector(test_vector
)
539 test
+= self
.probe_command(test_num
, result_color
)
543 argtype_names
= '-'.join(
544 str(argtype
) for argtype
in self
._signature
.argtypes
)
545 if self
.extensions():
546 subdir
= self
.extensions()[0].lower()
548 subdir
= 'glsl-{0:1.2f}'.format(float(self
.glsl_version()) / 100)
550 'spec', subdir
, 'execution', 'built-in-functions',
551 '{0}-{1}-{2}{3}.shader_test'.format(
552 self
.test_prefix(), self
._signature
.name
, argtype_names
,
553 self
._comparator
.testname_suffix()))
555 def generate_shader_test(self
):
556 """Generate the test and write it to the output file."""
557 shader_test
= '[require]\n'
558 shader_test
+= 'GLSL >= {0:1.2f}\n'.format(
559 float(self
.glsl_version()) / 100)
560 for extension
in self
.extensions():
561 shader_test
+= 'GL_{}\n'.format(extension
)
562 shader_test
+= self
.make_additional_requirements()
564 vs
= self
.make_vertex_shader()
566 shader_test
+= '[vertex shader]\n'
569 tcs
= self
.make_tess_ctrl_shader()
571 shader_test
+= '[tessellation control shader]\n'
574 tes
= self
.make_tess_eval_shader()
576 shader_test
+= '[tessellation evaluation shader]\n'
579 gs
= self
.make_geometry_shader()
581 shader_test
+= '[geometry shader]\n'
584 gl
= self
.make_geometry_layout()
586 shader_test
+= '[geometry layout]\n'
589 fs
= self
.make_fragment_shader()
591 shader_test
+= '[fragment shader]\n'
594 cs
= self
.make_compute_shader()
596 shader_test
+= '[compute shader]\n'
599 shader_test
+= '[test]\n'
600 shader_test
+= 'clear color 0.0 0.0 1.0 0.0\n'
601 shader_test
+= 'clear\n'
602 shader_test
+= self
.make_test()
603 filename
= self
.filename()
604 dirname
= os
.path
.dirname(filename
)
605 utils
.safe_makedirs(dirname
)
606 with
open(filename
, 'w') as f
:
610 class VertexShaderTest(ShaderTest
):
611 """Derived class for tests that exercise the built-in in a vertex
614 def test_prefix(self
):
617 def make_vertex_shader(self
):
618 if self
.glsl_version() >= 140:
619 return self
.make_test_shader(
620 'in vec4 piglit_vertex;\n' +
622 ' gl_Position = piglit_vertex;\n',
625 return self
.make_test_shader(
626 'varying vec4 color;\n',
627 ' gl_Position = gl_Vertex;\n',
630 def make_fragment_shader(self
):
631 shader
= '''varying vec4 color;
635 gl_FragColor = color;
641 class TessellationShaderTest(ShaderTest
):
642 """Abstract class for tests that exercise the built-in in
643 tessellation shaders.
646 def glsl_version(self
):
647 return max(150, ShaderTest
.glsl_version(self
))
649 def make_additional_requirements(self
):
650 return 'GL_ARB_tessellation_shader'
652 def extensions(self
):
654 if self
._signature
.extension
:
655 ext
.append(self
._signature
.extension
)
656 ext
.append("ARB_tessellation_shader")
659 def draw_command(self
, test_num
):
660 x
= (test_num
% self
.tests_per_row
) * self
.rect_width
661 y
= (test_num
// self
.tests_per_row
) * self
.rect_height
662 assert(y
+ self
.rect_height
<= self
.win_height
)
663 return 'draw rect ortho patch {0} {1} {2} {3}\n'.format(x
, y
,
667 def make_vertex_shader(self
):
669 """in vec4 piglit_vertex;
670 out vec4 vertex_to_tcs;
674 vertex_to_tcs = piglit_vertex;
679 def make_fragment_shader(self
):
681 """in vec4 color_to_fs;
685 gl_FragColor = color_to_fs;
691 class TessCtrlShaderTest(TessellationShaderTest
):
692 """Derived class for tests that exercise the built-in in a
693 tessellation control shader.
696 def test_prefix(self
):
699 def make_tess_ctrl_shader(self
):
700 additional_declarations
= \
701 """layout(vertices = 4) out;
702 in vec4 vertex_to_tcs[];
703 out vec4 vertex_to_tes[];
704 patch out vec4 color_to_tes;
707 """ vertex_to_tes[gl_InvocationID] = vertex_to_tcs[gl_InvocationID];
708 color_to_tes = tmp_color;
709 gl_TessLevelOuter = float[4](1.0, 1.0, 1.0, 1.0);
710 gl_TessLevelInner = float[2](1.0, 1.0);
712 shader
= self
.make_test_shader(
713 additional_declarations
,
714 ' vec4 tmp_color;\n',
719 def make_tess_eval_shader(self
):
721 """#extension GL_ARB_tessellation_shader : require
724 in vec4 vertex_to_tes[];
725 patch in vec4 color_to_tes;
726 out vec4 color_to_fs;
728 gl_Position = mix(mix(vertex_to_tes[0], vertex_to_tes[1], gl_TessCoord.x),
729 mix(vertex_to_tes[2], vertex_to_tes[3], gl_TessCoord.x),
731 color_to_fs = color_to_tes;
737 class GeometryShaderTest(ShaderTest
):
738 """Derived class for tests that exercise the built-in in a
741 def test_prefix(self
):
744 def glsl_version(self
):
745 return max(150, ShaderTest
.glsl_version(self
))
747 def make_vertex_shader(self
):
749 shader
+= "in vec4 piglit_vertex;\n"
750 shader
+= "out vec4 vertex_to_gs;\n"
752 shader
+= "void main()\n"
754 shader
+= " vertex_to_gs = piglit_vertex;\n"
759 def make_geometry_shader(self
):
760 additional_declarations
= ''
761 additional_declarations
+= 'layout(triangles) in;\n'
762 additional_declarations \
763 += 'layout(triangle_strip, max_vertices = 3) out;\n'
764 additional_declarations
+= 'in vec4 vertex_to_gs[3];\n'
765 additional_declarations
+= 'out vec4 color;\n'
766 return self
.make_test_shader(
767 additional_declarations
,
768 ' vec4 tmp_color;\n',
770 ' for (int i = 0; i < 3; i++) {\n'
771 ' gl_Position = vertex_to_gs[i];\n'
772 ' color = tmp_color;\n'
776 def make_fragment_shader(self
):
777 shader
= '''varying vec4 color;
781 gl_FragColor = color;
787 class FragmentShaderTest(ShaderTest
):
788 """Derived class for tests that exercise the built-in in a
791 def test_prefix(self
):
794 def make_vertex_shader(self
):
796 if self
.glsl_version() >= 140:
797 shader
+= "in vec4 piglit_vertex;\n"
799 shader
+= "void main()\n"
801 if self
.glsl_version() >= 140:
802 shader
+= " gl_Position = piglit_vertex;\n"
804 shader
+= " gl_Position = gl_Vertex;\n"
809 def make_fragment_shader(self
):
810 return self
.make_test_shader('', '', 'gl_FragColor', '')
813 class ComputeShaderTest(ShaderTest
):
814 """Derived class for tests that exercise the built-in in a
817 def test_prefix(self
):
820 def glsl_version(self
):
821 return max(430, ShaderTest
.glsl_version(self
))
823 def make_compute_shader(self
):
824 additional_declarations
= 'writeonly uniform image2D tex;\n'
825 num_tests
= len(self
._test
_vectors
)
826 layout_tmpl
= 'layout(local_size_x = {0}) in;\n'
827 additional_declarations
+= layout_tmpl
.format(num_tests
)
828 return self
.make_test_shader(
829 additional_declarations
,
830 ' vec4 tmp_color;\n',
832 ' ivec2 coord = ivec2(gl_GlobalInvocationID.xy);\n'
833 ' imageStore(tex, coord, tmp_color);\n')
835 def make_test_init(self
):
836 return '''uniform int tex 0
837 texture rgbw 0 ({0}, 1) GL_RGBA8
838 image texture 0 GL_RGBA8
840 '''.format(len(self
._test
_vectors
))
843 def draw_command(self
, test_num
):
844 return 'compute 1 1 1\n'
846 def probe_command(self
, test_num
, probe_vector
):
847 # Note: shader_runner uses a 250x250 window so we must
848 # ensure that test_num <= 250.
849 return 'probe rgb {0} 0 {1} {2} {3} {4}\n'.format(test_num
% 250,
854 def needs_probe_per_draw(self
):
858 for use_if
in [False, True]:
859 for signature
, test_vectors
in sorted(test_suite
.items()):
860 if use_if
and signature
.rettype
!= glsl_bool
:
862 yield VertexShaderTest(signature
, test_vectors
, use_if
)
863 yield TessCtrlShaderTest(signature
, test_vectors
, use_if
)
864 yield GeometryShaderTest(signature
, test_vectors
, use_if
)
865 yield FragmentShaderTest(signature
, test_vectors
, use_if
)
866 yield ComputeShaderTest(signature
, test_vectors
, use_if
)
870 desc
= 'Generate shader tests that test built-in functions using uniforms'
871 usage
= 'usage: %prog [-h] [--names-only]'
872 parser
= optparse
.OptionParser(description
=desc
, usage
=usage
)
877 help="Don't output files, just generate a list of filenames to stdout")
878 options
, args
= parser
.parse_args()
879 for test
in all_tests():
880 if not options
.names_only
:
881 test
.generate_shader_test()
882 print(test
.filename())
885 if __name__
== '__main__':