gl-1.1: Test that unused normal array in ff shader doesn't affect other arrays
[piglit.git] / generated_tests / gen_shader_image_load_store_tests.py
blob34cef3b568ba3fbf525b7c95d1b4852e7c7ccd58
1 # coding=utf-8
3 # Copyright (C) 2014 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
14 # Software.
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 DEALINGS
22 # IN THE SOFTWARE.
24 import os.path
25 from mako.template import Template
26 from textwrap import dedent
28 from modules import utils
31 def gen_header(status):
32 """
33 Generate a GLSL program header.
35 Generate header code for ARB_shader_image_load_store GLSL parser
36 tests that are expected to give status as result.
37 """
38 return dedent("""\
40 * [config]
41 * expect_result: {0}
42 * glsl_version: 1.50
43 * require_extensions: GL_ARB_shader_image_load_store
44 * [end config]
46 #version 150
47 #extension GL_ARB_shader_image_load_store: require
48 """.format(status))
51 def gen_vector_type(scalar, dim):
52 """
53 Generate a GLSL vector type name.
55 Generate a GLSL vector type based on the given scalar type with the
56 specified number of dimensions.
57 """
58 vector_types = {
59 'int': 'ivec',
60 'uint': 'uvec',
61 'float': 'vec',
64 return ('{0}{1}'.format(vector_types[scalar], dim) if dim > 1
65 else scalar)
68 def gen_scalar_args(arity):
69 """
70 Generate image builtin scalar arguments.
72 Returns a generator of well-formed scalar arguments for an image
73 built-in of the given arity having t as argument type.
74 """
75 return lambda t: ', {0}(0)'.format(t) * arity
78 def gen_vector_args(arity):
79 """
80 Generate image builtin vector arguments.
82 Returns a generator of well-formed arguments for an image built-in
83 of the given arity having a 4-component vector of t as argument
84 type.
85 """
86 return lambda t: ', {0}(0)'.format(gen_vector_type(t, 4)) * arity
89 def gen_address_args(dim):
90 """
91 Generate image address arguments.
93 Returns a generator for the coordinate argument of an image
94 built-in expecting an address of the given dimensionality. If
95 fail is True the generated argument will have an arbitrary
96 incorrect dimensionality.
97 """
98 return (lambda fail = False: ', {0}(0)'.format(
99 gen_vector_type('int', dim if not fail else dim % 3 + 1)))
102 def gen_address_args_ms(dim):
103 """Generate multisample image address arguments."""
104 return (lambda fail = False:
105 gen_address_args(dim)() + (', 0' if not fail else ''))
108 def product(ps, *qss):
110 Generate the cartesian product of a number of lists of dictionaries.
112 Each generated element will be the union of some combination of
113 elements from the iterable arguments. The resulting value of each
114 'name' item will be the concatenation of names of the respective
115 element combination separated with dashes.
117 for q in (product(*qss) if qss else [{}]):
118 for p in ps:
119 r = dict(p, **q)
120 r['name'] = '-'.join(s['name'] for s in (p, q) if s.get('name'))
121 yield r
124 def gen(name, src, tests):
126 Expand a source template for the provided list of test definitions.
128 Generate a GLSL parser test for each of the elements of the
129 'tests' iterable, each of them should be a dictionary of
130 definitions that will be used as environment to render the source
131 template.
133 The file name of each test will be the concatenation of the 'name'
134 argument with the 'name' item from the respective test dictionary.
136 template = Template(dedent(src))
138 for t in product([{'name': name}], tests):
139 filename = os.path.join('spec',
140 'ARB_shader_image_load_store',
141 'compiler',
142 '{0}.{1}'.format(t['name'],
143 t['shader_stage']))
144 print(filename)
146 dirname = os.path.dirname(filename)
147 utils.safe_makedirs(dirname)
149 with open(filename, 'w') as f:
150 f.write(template.render(header = gen_header, **t))
153 shader_stages = [
154 {'shader_stage': 'frag'},
155 {'shader_stage': 'vert'}
159 image_atomic_builtins = [
161 'name': 'atomic-add',
162 'image_builtin': 'imageAtomicAdd',
163 'image_args': gen_scalar_args(1)
166 'name': 'atomic-min',
167 'image_builtin': 'imageAtomicMin',
168 'image_args': gen_scalar_args(1)
171 'name': 'atomic-max',
172 'image_builtin': 'imageAtomicMax',
173 'image_args': gen_scalar_args(1)
176 'name': 'atomic-and',
177 'image_builtin': 'imageAtomicAnd',
178 'image_args': gen_scalar_args(1)
181 'name': 'atomic-or',
182 'image_builtin': 'imageAtomicOr',
183 'image_args': gen_scalar_args(1)
186 'name': 'atomic-xor',
187 'image_builtin': 'imageAtomicXor',
188 'image_args': gen_scalar_args(1)
191 'name': 'atomic-exchange',
192 'image_builtin': 'imageAtomicExchange',
193 'image_args': gen_scalar_args(1)
196 'name': 'atomic-comp-swap',
197 'image_builtin': 'imageAtomicCompSwap',
198 'image_args': gen_scalar_args(2)
203 image_load_builtin = [
205 'name': 'load',
206 'image_builtin': 'imageLoad',
207 'image_args': gen_vector_args(0)
212 image_store_builtin = [
214 'name': 'store',
215 'image_builtin': 'imageStore',
216 'image_args': gen_vector_args(1)
221 image_types = [
223 'name': '1d',
224 'image_type': 'image1D',
225 'image_addr': gen_address_args(1)
228 'name': '2d',
229 'image_type': 'image2D',
230 'image_addr': gen_address_args(2)
233 'name': '3d',
234 'image_type': 'image3D',
235 'image_addr': gen_address_args(3)
238 'name': '2d-rect',
239 'image_type': 'image2DRect',
240 'image_addr': gen_address_args(2)
243 'name': 'cube',
244 'image_type': 'imageCube',
245 'image_addr': gen_address_args(3)
248 'name': 'buffer',
249 'image_type': 'imageBuffer',
250 'image_addr': gen_address_args(1)
253 'name': '1d-array',
254 'image_type': 'image1DArray',
255 'image_addr': gen_address_args(2)
258 'name': '2d-array',
259 'image_type': 'image2DArray',
260 'image_addr': gen_address_args(3)
263 'name': 'cube-array',
264 'image_type': 'imageCubeArray',
265 'image_addr': gen_address_args(3)
268 'name': '2d-ms',
269 'image_type': 'image2DMS',
270 'image_addr': gen_address_args_ms(2)
273 'name': '2d-ms-array',
274 'image_type': 'image2DMSArray',
275 'image_addr': gen_address_args_ms(3)
280 def main():
281 """Main function."""
283 # Test the early_fragment_tests layout qualifier.
285 gen('early-fragment-tests', """\
286 ${header('pass' if shader_stage == 'frag' and hunk == 'in' else 'fail')}
288 * From the ARB_shader_image_load_store spec:
290 * "Fragment shaders also allow the following layout qualifier on 'in'
291 * only (not with variable declarations):
293 * layout-qualifier-id
294 * early_fragment_tests"
296 layout(early_fragment_tests) ${hunk};
298 void main()
301 """, product(shader_stages, [
302 {'name': 'in', 'hunk': 'in'},
303 {'name': 'out', 'hunk': 'out'},
304 {'name': 'uniform', 'hunk': 'uniform uint u'},
305 {'name': 'in-var', 'hunk': 'in float f'},
306 {'name': 'uniform-buffer', 'hunk': 'uniform b { image2D img; }'}
310 # Test image declarations.
312 gen('declaration-allowed', """\
313 ${header('pass')}
315 * From the ARB_shader_image_load_store spec:
317 * "[Images] can only be declared as function parameters or uniform
318 * variables."
320 layout(rgba32f) uniform ${image_type} img;
321 layout(rgba32ui) uniform u${image_type} uimg;
322 layout(rgba32i) uniform i${image_type} iimg;
324 void f(${image_type} arg,
325 u${image_type} uarg,
326 i${image_type} iarg)
330 void main()
333 """, product(image_types, shader_stages))
335 gen('declaration-global', """\
336 ${header('fail')}
338 * From the ARB_shader_image_load_store spec:
340 * "[Images] can only be declared as function parameters or uniform
341 * variables."
343 layout(rgba32f) ${qualifier} image2D img;
345 void main()
348 """, product(shader_stages, [
349 {'name': 'const', 'qualifier': 'const'},
350 {'name': 'in', 'qualifier': 'in'},
351 {'name': 'out', 'qualifier': 'out'}
354 gen('declaration-local', """\
355 ${header('fail')}
357 * From the ARB_shader_image_load_store spec:
359 * "[Images] can only be declared as function parameters or uniform
360 * variables."
362 void main()
364 layout(rgba32f) image2D img;
366 """, shader_stages)
368 gen('declaration-uniform-block', """\
369 ${header('fail')}
371 * From the ARB_shader_image_load_store spec:
373 * "Sets of uniforms, except for samplers and images, can be grouped
374 * into uniform blocks."
376 uniform b {
377 layout(rgba32f) image2D img;
380 void main()
383 """, shader_stages)
385 gen('declaration-argument', """\
386 ${header('fail')}
388 * From the ARB_shader_image_load_store spec:
390 * "Images cannot be treated as l-values; hence, they cannot be used
391 * as out or inout function parameters, nor can they be assigned
392 * into."
394 void f(${qualifier} image2D y)
398 void main()
401 """, product(shader_stages, [
402 {'name': 'inout', 'qualifier': 'inout'},
403 {'name': 'out', 'qualifier': 'out'}
406 gen('declaration-initializer', """\
407 ${header('fail')}
409 * From the ARB_shader_image_load_store spec:
411 * "[Images] cannot be declared with an initializer in a shader."
413 layout(rgba32f) uniform image2D img = 0;
415 void main()
418 """, shader_stages)
420 gen('declaration-format-qualifier', """\
421 ${header('fail')}
423 * From the ARB_shader_image_load_store spec:
425 * "It is an error to declare an image variable where the format
426 * qualifier does not match the image variable type."
428 layout(${format}) uniform ${prefix}${image_type} img;
430 void main()
433 """, product(image_types, shader_stages, [
434 {'name': 'float',
435 'format': 'rgba32f',
436 'prefix': 'i'},
437 {'name': 'int',
438 'format': 'rgba32i',
439 'prefix': 'u'},
440 {'name': 'uint',
441 'format': 'rgba32ui',
442 'prefix': ''}
445 gen('declaration-format-qualifier-duplicate', """\
446 ${header('fail')}
448 * From the ARB_shader_image_load_store spec:
450 * "Only one format qualifier may be specified for any image variable
451 * declaration."
453 layout(rgba32f) layout(rgba32f) uniform image2D img;
455 void main()
458 """, shader_stages)
460 gen('declaration-format-qualifier-missing', """\
461 ${header(status)}
463 * From the ARB_shader_image_load_store spec:
465 * "Uniforms not qualified with "writeonly" must have a format
466 * layout qualifier."
468 ${qualifier} uniform image2D img;
470 void main()
473 """, product(shader_stages, [
474 {'name': 'writeonly',
475 'qualifier': 'writeonly',
476 'status': 'pass'},
477 {'name': 'readonly',
478 'qualifier': 'readonly',
479 'status': 'fail'},
480 {'name': 'readwrite',
481 'qualifier': '',
482 'status': 'fail'}
485 gen('declaration-memory-qualifier-sampler', """\
486 ${header('fail')}
488 * From the ARB_shader_image_load_store spec:
490 * "Only variables declared as image types [...] can be qualified
491 * with a memory qualifier. "
493 ${qualifier} uniform sampler2D s;
495 void main()
498 """, product(shader_stages, [
499 {'name': 'readonly', 'qualifier': 'readonly'},
500 {'name': 'writeonly', 'qualifier': 'writeonly'},
501 {'name': 'coherent', 'qualifier': 'coherent'},
502 {'name': 'volatile', 'qualifier': 'volatile'},
503 {'name': 'restrict', 'qualifier': 'restrict'}
507 # Test expressions involving images.
509 gen('expression-allowed', """\
510 ${header('pass')}
512 * From the ARB_shader_image_load_store spec:
514 * "Except for array indexing, structure field selection, and
515 * parentheses, images are not allowed to be operands in
516 * expressions."
518 layout(rgba32f) uniform ${image_type} imgs[2];
519 uniform vec4 y;
521 out vec4 color;
523 void main()
525 color = y + imageLoad((imgs[1]) ${image_addr()});
527 """, product(image_types[:1], shader_stages))
529 gen('expression', """\
530 ${header('fail')}
532 * From the ARB_shader_image_load_store spec:
534 * "Except for array indexing, structure field selection, and
535 * parentheses, images are not allowed to be operands in
536 * expressions."
538 layout(rgba32f) uniform image2D img;
540 void main()
542 ${expression};
544 """, product(shader_stages, [
545 {'name': 'arithmetic-1', 'expression': '-img'},
546 {'name': 'arithmetic-2', 'expression': 'img + img'},
547 {'name': 'arithmetic-3', 'expression': 'img - img'},
548 {'name': 'arithmetic-4', 'expression': 'img * img'},
549 {'name': 'arithmetic-5', 'expression': 'img / img'},
550 {'name': 'arithmetic-6', 'expression': '++img'},
551 {'name': 'arithmetic-7', 'expression': '--img'},
552 {'name': 'arithmetic-8', 'expression': 'img++'},
553 {'name': 'arithmetic-9', 'expression': 'img--'},
554 {'name': 'assignment-1', 'expression': 'img ^= img'},
555 {'name': 'assignment-2', 'expression': 'img |= img'},
556 {'name': 'assignment-3', 'expression': 'img = img'},
557 {'name': 'assignment-4', 'expression': 'img += img'},
558 {'name': 'assignment-5', 'expression': 'img -= img'},
559 {'name': 'assignment-6', 'expression': 'img *= img'},
560 {'name': 'assignment-7', 'expression': 'img /= img'},
561 {'name': 'assignment-8', 'expression': 'img %= img'},
562 {'name': 'assignment-9', 'expression': 'img <<= img'},
563 {'name': 'assignment-10', 'expression': 'img >>= img'},
564 {'name': 'assignment-11', 'expression': 'img &= img'},
565 {'name': 'binary-1', 'expression': '~img'},
566 {'name': 'binary-2', 'expression': 'img << img'},
567 {'name': 'binary-3', 'expression': 'img >> img'},
568 {'name': 'binary-4', 'expression': 'img & img'},
569 {'name': 'binary-5', 'expression': 'img | img'},
570 {'name': 'binary-6', 'expression': 'img ^ img'},
571 {'name': 'conversion-1', 'expression': 'float(img)'},
572 {'name': 'conversion-2', 'expression': 'uint(img)'},
573 {'name': 'conversion-3', 'expression': 'bool(img)'},
574 {'name': 'conversion-4', 'expression': 'image1D(img)'},
575 {'name': 'field-selection', 'expression': 'img.x'},
576 {'name': 'function-call', 'expression': 'img()'},
577 {'name': 'logical-1', 'expression': '!img'},
578 {'name': 'logical-2', 'expression': 'img && img'},
579 {'name': 'logical-3', 'expression': 'img || img'},
580 {'name': 'logical-4', 'expression': 'img ^^ img'},
581 {'name': 'relational-1', 'expression': 'img == img'},
582 {'name': 'relational-2', 'expression': 'img != img'},
583 {'name': 'relational-3', 'expression': 'img < img'},
584 {'name': 'relational-4', 'expression': 'img > img'},
585 {'name': 'relational-5', 'expression': 'img <= img'},
586 {'name': 'relational-6', 'expression': 'img >= img'},
587 {'name': 'selection', 'expression': 'true ? img : img'},
588 {'name': 'subscript', 'expression': 'img[0]'}
592 # Test passing of image variables in function calls.
594 gen('call-argument-qualifiers', """\
595 ${header(status)}
597 * From the ARB_shader_image_load_store spec:
599 * "The values of image variables qualified with 'coherent',
600 * 'volatile', 'restrict', 'readonly', or 'writeonly' may not be
601 * passed to functions whose formal parameters lack such
602 * qualifiers. [...] It is legal to have additional qualifiers on a
603 * formal parameter, but not to have fewer."
605 layout(rgba32f) ${actual_qualifier} uniform image2D x;
607 void f(${formal_qualifier} image2D y)
611 void main()
613 f(x);
615 """, product(shader_stages, [
616 {'name': 'allowed-volatile',
617 'actual_qualifier': 'volatile',
618 'formal_qualifier': 'volatile coherent',
619 'status': 'pass'},
620 {'name': 'allowed-coherent',
621 'actual_qualifier': 'coherent',
622 'formal_qualifier': 'volatile coherent',
623 'status': 'pass'},
624 {'name': 'allowed-restrict',
625 'actual_qualifier': 'restrict',
626 'formal_qualifier': 'volatile restrict',
627 'status': 'pass'},
628 {'name': 'allowed-readonly',
629 'actual_qualifier': 'readonly',
630 'formal_qualifier': 'restrict readonly',
631 'status': 'pass'},
632 {'name': 'allowed-writeonly',
633 'actual_qualifier': 'writeonly',
634 'formal_qualifier': 'volatile writeonly',
635 'status': 'pass'},
636 {'name': 'disallowed-volatile',
637 'actual_qualifier': 'volatile',
638 'formal_qualifier': '',
639 'status': 'fail'},
640 {'name': 'disallowed-coherent',
641 'actual_qualifier': 'coherent',
642 'formal_qualifier': 'restrict',
643 'status': 'fail'},
644 {'name': 'disallowed-restrict',
645 'actual_qualifier': 'restrict',
646 'formal_qualifier': '',
647 'status': 'fail'},
648 {'name': 'disallowed-readonly',
649 'actual_qualifier': 'readonly',
650 'formal_qualifier': 'restrict writeonly',
651 'status': 'fail'},
652 {'name': 'disallowed-writeonly',
653 'actual_qualifier': 'writeonly',
654 'formal_qualifier': 'volatile readonly',
655 'status': 'fail'}
658 gen('call-argument-type', """\
659 ${header('pass' if image_type == 'image2D' else 'fail')}
661 * From the ARB_shader_image_load_store spec:
663 * "As function parameters, images may only be passed to [arguments]
664 * of matching type."
666 layout(rgba32f) uniform image2D x;
668 void f(${image_type} y)
672 void main()
674 f(x);
676 """, product(image_types, shader_stages))
679 # Test the language built-in constants and functions.
681 gen('builtin-constants', """\
682 ${header('pass')}
684 * Check that the builtin constants defined by the extension
685 * are present.
687 out ivec4 color;
689 void main()
691 color.x = gl_MaxImageUnits +
692 gl_MaxCombinedImageUnitsAndFragmentOutputs +
693 gl_MaxImageSamples +
694 gl_MaxVertexImageUniforms +
695 gl_MaxGeometryImageUniforms +
696 gl_MaxFragmentImageUniforms +
697 gl_MaxCombinedImageUniforms;
699 """, shader_stages)
701 gen('builtin-image-argument-mismatch', """\
702 ${header('fail')}
704 * From the ARB_shader_image_load_store spec:
706 * "Atomic memory operations are supported on only [...]: an image
707 * variable with signed integer components (iimage*) format qualifier
708 * of 'r32i', or an image variable with unsigned integer components
709 * (uimage*) and format qualifier of 'r32ui'."
711 * Call an atomic built-in with a floating point image data type.
713 layout(r32f) uniform ${image_type} img;
715 void main()
717 ${image_builtin}(img ${image_addr()} ${image_args('float')});
719 """, product(image_atomic_builtins, image_types[:1], shader_stages))
721 gen('builtin-data-argument-mismatch', """\
722 ${header('fail')}
724 * Call a signed integer atomic built-in with a mismatching
725 * argument data type.
727 layout(r32i) uniform i${image_type} img;
729 void main()
731 ${image_builtin}(img ${image_addr()} ${image_args('uint')});
733 """, product(image_store_builtin + image_atomic_builtins,
734 image_types[:1], shader_stages))
736 gen('builtin-address-argument-mismatch', """\
737 ${header('fail')}
739 * From the ARB_shader_image_load_store spec:
741 * "The 'IMAGE_INFO' placeholder is replaced by one of the following
742 * parameter lists:
743 * gimage1D image, int coord
744 * gimage2D image, ivec2 coord
745 * gimage3D image, ivec3 coord
746 * gimage2DRect image, ivec2 coord
747 * gimageCube image, ivec3 coord
748 * gimageBuffer image, int coord
749 * gimage1DArray image, ivec2 coord
750 * gimage2DArray image, ivec3 coord
751 * gimageCubeArray image, ivec3 coord
752 * gimage2DMS image, ivec2 coord, int sample
753 * gimage2DMSArray image, ivec3 coord, int sample"
755 * Pass an argument as address coordinate that doesn't match the
756 * dimensionality of the specified image.
758 layout(r32i) uniform i${image_type} img;
760 void main()
762 ${image_builtin}(img ${image_addr(fail = True)} ${image_args('int')});
764 """, product(image_load_builtin + image_store_builtin + image_atomic_builtins,
765 image_types, shader_stages))
767 gen('builtin-qualifier-mismatch-readonly', """\
768 ${header('fail')}
770 * From the ARB_shader_image_load_store spec:
772 * "It is an error to pass an image variable qualified with 'readonly'
773 * to imageStore() or other built-in functions that modify image
774 * memory."
776 * Call a built-in function on a readonly qualified image.
778 layout(r32i) readonly uniform i${image_type} img;
780 void main()
782 ${image_builtin}(img ${image_addr()} ${image_args('int')});
784 """, product(image_store_builtin + image_atomic_builtins,
785 image_types[:1], shader_stages))
787 gen('builtin-qualifier-mismatch-writeonly', """\
788 ${header('fail')}
790 * From the ARB_shader_image_load_store spec:
792 * "It is an error to pass an image variable qualified with 'writeonly'
793 * to imageLoad() or other built-in functions that read image
794 * memory."
796 * Call a built-in function on a writeonly qualified image.
798 layout(r32i) writeonly uniform i${image_type} img;
800 void main()
802 ${image_builtin}(img ${image_addr()} ${image_args('int')});
804 """, product(image_load_builtin + image_atomic_builtins,
805 image_types[:1], shader_stages))
807 gen('builtin-memory-barrier', """\
808 ${header('pass')}
809 void main()
811 memoryBarrier();
813 """, shader_stages)
816 if __name__ == '__main__':
817 main()