gen-uniform-blocks.py revision 0a9d96ece56b7068267e62e57f8fac45eb7b10ec
1from genutil import *
2
3allCases = []
4
5VERTEX = "VERTEX"
6FRAGMENT = "FRAGMENT"
7
8CASE_FRAGMENT_SHADER_TEMPLATE = """
9case ${{NAME}}
10	version 300 es
11	expect ${{EXPECT}}
12
13	vertex ""
14		#version 300 es
15		precision highp float;
16
17		in vec4 a_pos;
18
19		void main()
20		{
21			gl_Position = a_pos;
22		}
23	""
24
25	fragment ""
26		${{SOURCE}}
27	""
28end"""[1:]
29
30CASE_VERTEX_SHADER_TEMPLATE = """
31case ${{NAME}}
32	version 300 es
33	expect ${{EXPECT}}
34
35	vertex ""
36		${{SOURCE}}
37	""
38
39	fragment ""
40		#version 300 es
41		precision highp float;
42
43		layout(location=0) out vec4 o_color;
44
45		void main()
46		{
47			o_color = vec4(1.0);
48		}
49	""
50end"""[1:]
51
52class UniformBlockCase(ShaderCase):
53	def __init__(self, name, shaderType, source, valid):
54		self.name = name
55		self.shaderType = shaderType
56		self.source = source
57		self.valid = valid
58
59	def __str__(self):
60		if self.shaderType == FRAGMENT:
61			sourceParams = {
62				"OUTPUT":				"o_color",
63				"OUTPUT_DECLARATION":	"layout(location=0) out vec4 o_color;"
64			}
65
66			source = fillTemplate(self.source, sourceParams)
67
68			testCaseParams = {
69				"NAME":		self.name,
70				"SOURCE":	source,
71				"EXPECT":	("build_successful" if self.valid else "compile_fail")
72			}
73
74			return fillTemplate(CASE_FRAGMENT_SHADER_TEMPLATE, testCaseParams)
75		elif self.shaderType == VERTEX:
76			sourceParams = {
77				"OUTPUT":				"gl_Position",
78				"OUTPUT_DECLARATION":	""
79			}
80
81			source = fillTemplate(self.source, sourceParams)
82
83			testCaseParams = {
84				"NAME":		self.name,
85				"SOURCE":	source,
86				"EXPECT":	("build_successful" if self.valid else "compile_fail")
87			}
88
89			return fillTemplate(CASE_VERTEX_SHADER_TEMPLATE, testCaseParams)
90
91		assert False
92
93def createCases(name, source, valid):
94	return [UniformBlockCase(name + "_vertex", VERTEX, source, valid),
95			UniformBlockCase(name + "_fragment", FRAGMENT, source, valid)]
96
97repeatShaderTemplate = """
98#version 300 es
99precision highp float;
100
101${{OUTPUT_DECLARATION}}
102
103uniform UniformBlock
104{
105	uniform vec4 uniformMember;
106} uniformBlock;
107
108void main()
109{
110	${{OUTPUT}} = uniformBlock.uniformMember;
111}"""[1:]
112
113layoutQualifierShaderTemplate = """
114#version 300 es
115precision highp float;
116
117${{OUTPUT_DECLARATION}}
118
119layout(%s) uniform UniformBlock
120{
121	vec4 uniformMember;
122} uniformBlock;
123
124void main()
125{
126	${{OUTPUT}} = uniformBlock.uniformMember;
127}"""[1:]
128
129layoutGlobalQualifierShaderTemplate = """
130#version 300 es
131precision highp float;
132
133layout(%s) uniform;
134
135${{OUTPUT_DECLARATION}}
136
137uniform UniformBlock
138{
139	vec4 uniformMember;
140} uniformBlock;
141
142void main()
143{
144	${{OUTPUT}} = uniformBlock.uniformMember;
145}"""[1:]
146
147layoutMemberQualifierShaderTemplate = """
148#version 300 es
149precision highp float;
150
151${{OUTPUT_DECLARATION}}
152
153uniform UniformBlock
154{
155	layout(%s) mat4 uniformMember;
156} uniformBlock;
157
158void main()
159{
160	${{OUTPUT}} = uniformBlock.uniformMember[0];
161}"""[1:]
162
163layoutMemberVec4QualifierShaderTemplate = """
164#version 300 es
165precision highp float;
166
167${{OUTPUT_DECLARATION}}
168
169uniform UniformBlock
170{
171	layout(%s) vec4 uniformMember;
172} uniformBlock;
173
174void main()
175{
176	${{OUTPUT}} = uniformBlock.uniformMember;
177}"""[1:]
178
179noInstanceNameShaderTemplate = """
180#version 300 es
181precision highp float;
182
183${{OUTPUT_DECLARATION}}
184
185uniform UniformBlock
186{
187	vec4 uniformMember;
188};
189
190void main()
191{
192	${{OUTPUT}} = uniformMember;
193}"""[1:]
194
195sameVariableAndInstanceNameShaderTemplate = """
196#version 300 es
197precision highp float;
198
199${{OUTPUT_DECLARATION}}
200
201uniform UniformBlock
202{
203	vec4 uniformMember;
204} uniformBlock;
205
206void main()
207{
208	vec4 uniformBlock = vec4(0.0);
209	${{OUTPUT}} = uniformBlock;
210}"""[1:]
211
212sameVariableAndBlockNameShaderTemplate = """
213#version 300 es
214precision highp float;
215
216${{OUTPUT_DECLARATION}}
217
218uniform UniformBlock
219{
220	vec4 uniformMember;
221} uniformBlock;
222
223void main()
224{
225	vec4 UniformBlock = vec4(0.0);
226	${{OUTPUT}} = UniformBlock + uniformBlock.uniformMember;
227}"""[1:]
228
229repeatedBlockShaderTemplate = """
230#version 300 es
231precision highp float;
232
233${{OUTPUT_DECLARATION}}
234
235uniform UniformBlock
236{
237	vec4 uniformMember;
238} uniformBlockA;
239
240uniform UniformBlock
241{
242	vec4 uniformMember;
243} uniformBlockB;
244
245void main()
246{
247	${{OUTPUT}} = uniformBlockA.uniformMember + uniformBlockB.uniformMember;
248}"""[1:]
249
250repeatedBlockNoInstanceNameShaderTemplate = """
251#version 300 es
252precision highp float;
253
254${{OUTPUT_DECLARATION}}
255
256uniform UniformBlock
257{
258	vec4 uniformMember;
259} uniformBlock;
260
261uniform UniformBlock
262{
263	vec4 uniformMember;
264};
265
266void main()
267{
268	${{OUTPUT}} = uniformBlock.uniformMember + uniformMember;
269}"""[1:]
270
271structMemberShaderTemplate = """
272#version 300 es
273precision highp float;
274
275${{OUTPUT_DECLARATION}}
276
277struct Struct
278{
279	vec4 uniformMember;
280};
281
282uniform UniformBlock
283{
284	Struct st;
285} uniformBlock;
286
287void main()
288{
289	${{OUTPUT}} = uniformBlock.st.uniformMember;
290}"""[1:]
291
292layoutStructMemberQualifierShaderTemplate = """
293#version 300 es
294precision highp float;
295
296${{OUTPUT_DECLARATION}}
297
298struct Struct
299{
300	vec4 uniformMember;
301};
302
303uniform UniformBlock
304{
305	layout(%s) Struct st;
306} uniformBlock;
307
308void main()
309{
310	${{OUTPUT}} = uniformBlock.st.uniformMember;
311}"""[1:]
312
313longIdentifierBlockNameShaderTemplate = ("""
314#version 300 es
315precision highp float;
316
317${{OUTPUT_DECLARATION}}
318
319// Total of 1024 characters
320uniform """ + ("a" * 1024) + """
321{
322	vec4 uniformMember;
323} uniformBlock;
324
325void main()
326{
327	${{OUTPUT}} = uniformBlock.uniformMember;
328}""")[1:]
329
330longIdentifierInstanceNameShaderTemplate = ("""
331#version 300 es
332precision highp float;
333
334${{OUTPUT_DECLARATION}}
335
336uniform UniformBlock
337{
338	vec4 uniformMember;
339} """ + ("a" * 1024) + """;
340// Total of 1024 characters
341
342void main()
343{
344	${{OUTPUT}} = """ + ("a" * 1024) + """.uniformMember;
345}""")[1:]
346
347underscoreIdentifierInstanceNameShaderTemplate = ("""
348#version 300 es
349precision highp float;
350
351${{OUTPUT_DECLARATION}}
352
353uniform UniformBlock
354{
355	vec4 uniformMember;
356} _;
357
358void main()
359{
360	${{OUTPUT}} = _.uniformMember;
361}""")[1:]
362
363underscoreIdentifierBlockNameShaderTemplate = ("""
364#version 300 es
365precision highp float;
366
367${{OUTPUT_DECLARATION}}
368
369uniform _
370{
371	vec4 uniformMember;
372} uniformBlock;
373
374void main()
375{
376	${{OUTPUT}} = uniformBlock.uniformMember;
377}""")[1:]
378
379validCases = (createCases("repeat_interface_qualifier", repeatShaderTemplate, True)
380			+ sum([createCases("layout_%s" % qualifier, layoutQualifierShaderTemplate % qualifier, True)
381						for qualifier in ["shared", "packed", "std140", "row_major", "column_major"]], [])
382			+ createCases("layout_all", layoutQualifierShaderTemplate % "shared, packed, std140, row_major, column_major", True)
383			+ createCases("layout_all_8_times", layoutQualifierShaderTemplate % str.join(", ", ["shared", "packed", "std140", "row_major", "column_major"] * 8), True)
384			+ sum([createCases("global_layout_%s" % qualifier, layoutGlobalQualifierShaderTemplate % qualifier, True)
385						for qualifier in ["shared", "packed", "std140", "row_major", "column_major"]], [])
386			+ createCases("global_layout_all", layoutGlobalQualifierShaderTemplate % "shared, packed, std140, row_major, column_major", True)
387			+ createCases("global_layout_all_8_times", layoutGlobalQualifierShaderTemplate % str.join(", ", ["shared", "packed", "std140", "row_major", "column_major"] * 8), True)
388			+ sum([createCases("member_layout_%s" % qualifier, layoutMemberQualifierShaderTemplate % qualifier, True)
389						for qualifier in ["row_major", "column_major"]], [])
390			+ sum([createCases("member_layout_%s_vec4" % qualifier, layoutMemberVec4QualifierShaderTemplate % qualifier, True)
391						for qualifier in ["row_major", "column_major"]], [])
392			+ createCases("member_layout_all", layoutMemberQualifierShaderTemplate % "row_major, column_major", True)
393			+ createCases("member_layout_all_8_times", layoutMemberQualifierShaderTemplate % str.join(", ", ["row_major", "column_major"] * 8), True)
394			+ createCases("no_instance_name", noInstanceNameShaderTemplate, True)
395			+ createCases("same_variable_and_block_name", sameVariableAndBlockNameShaderTemplate, True)
396			+ createCases("same_variable_and_instance_name", sameVariableAndInstanceNameShaderTemplate, True)
397			+ createCases("repeated_block", repeatedBlockShaderTemplate, True)
398			+ createCases("repeated_block_no_instance_name", repeatedBlockNoInstanceNameShaderTemplate, True)
399			+ createCases("struct_member", structMemberShaderTemplate, True)
400			+ sum([createCases("struct_member_layout_%s" % qualifier, layoutStructMemberQualifierShaderTemplate % qualifier, True)
401						for qualifier in ["row_major", "column_major"]], [])
402			+ createCases("struct_member_layout_all", layoutStructMemberQualifierShaderTemplate % "row_major, column_major", True)
403			+ createCases("struct_member_layout_all_8_times", layoutStructMemberQualifierShaderTemplate % str.join(", ", ["row_major", "column_major"] * 8), True)
404			+ createCases("long_block_name", longIdentifierBlockNameShaderTemplate, True)
405			+ createCases("long_instance_name", longIdentifierInstanceNameShaderTemplate, True)
406			+ createCases("underscore_block_name", underscoreIdentifierBlockNameShaderTemplate, True)
407			+ createCases("underscore_instance_name", underscoreIdentifierInstanceNameShaderTemplate, True))
408
409invalidMemberInterfaceQualifierShaderTemplate = """
410#version 300 es
411precision highp float;
412
413${{OUTPUT_DECLARATION}}
414
415uniform UniformBlock
416{
417	%s vec4 uniformMember;
418} uniformBlock;
419
420void main()
421{
422	${{OUTPUT}} = uniformBlock.uniformMember;
423}"""[1:]
424
425conflictingInstanceNamesShaderTemplate = """
426#version 300 es
427precision highp float;
428
429${{OUTPUT_DECLARATION}}
430
431uniform UniformBlockA
432{
433	vec4 uniformMember;
434} uniformBlock;
435
436uniform UniformBlockB
437{
438	vec4 uniformMember;
439} uniformBlock;
440
441void main()
442{
443	${{OUTPUT}} = uniformBlock.uniformMember;
444}"""[1:]
445
446conflictingFunctionAndInstanceNameShaderTemplate = """
447#version 300 es
448precision highp float;
449
450${{OUTPUT_DECLARATION}}
451
452uniform UniformBlock
453{
454	vec4 uniformMember;
455} uniformBlock;
456
457float uniformBlock (float x)
458{
459	return x;
460}
461
462void main()
463{
464	${{OUTPUT}} = uniformBlock.uniformMember;
465}"""[1:]
466
467conflictingFunctionAndBlockNameShaderTemplate = """
468#version 300 es
469precision highp float;
470
471${{OUTPUT_DECLARATION}}
472
473uniform UniformBlock
474{
475	vec4 uniformMember;
476} uniformBlock;
477
478float UniformBlock (float x)
479{
480	return x;
481}
482
483void main()
484{
485	${{OUTPUT}} = uniformBlock.uniformMember;
486}"""[1:]
487
488conflictingVariableAndInstanceNameShaderTemplate = """
489#version 300 es
490precision highp float;
491
492${{OUTPUT_DECLARATION}}
493
494uniform UniformBlock
495{
496	vec4 uniformMember;
497} uniformBlock;
498
499%s vec4 uniformBlock;
500
501void main()
502{
503	${{OUTPUT}} = uniformBlock.uniformMember;
504}"""[1:]
505
506conflictingVariableAndBlockNameShaderTemplate = """
507#version 300 es
508precision highp float;
509
510${{OUTPUT_DECLARATION}}
511
512uniform UniformBlock
513{
514	vec4 uniformMember;
515} uniformBlock;
516
517%s vec4 UniformBlock;
518
519void main()
520{
521	${{OUTPUT}} = uniformBlock.uniformMember;
522}"""[1:]
523
524
525matchingInstanceAndBlockNameShaderTemplate = """
526#version 300 es
527precision highp float;
528
529${{OUTPUT_DECLARATION}}
530
531uniform UniformBlock
532{
533	vec4 uniformMember;
534} UniformBlock;
535
536void main()
537{
538	${{OUTPUT}} = UniformBlock.uniformMember;
539}"""[1:]
540
541referenceUsingBlockNameShaderTemplate = """
542#version 300 es
543precision highp float;
544
545${{OUTPUT_DECLARATION}}
546
547uniform UniformBlock
548{
549	vec4 uniformMember;
550} uniformBlock;
551
552void main()
553{
554	${{OUTPUT}} = UniformBlock.uniformMember;
555}"""[1:]
556
557emptyBlockShaderTemplate = """
558#version 300 es
559precision highp float;
560
561${{OUTPUT_DECLARATION}}
562
563uniform UniformBlock
564{
565} uniformBlock;
566
567void main()
568{
569	${{OUTPUT}} = vec4(0.0);
570}"""[1:]
571
572emptyLayoutShaderTemplate = """
573#version 300 es
574precision highp float;
575
576${{OUTPUT_DECLARATION}}
577
578layout() uniform UniformBlock
579{
580	vec4 uniformMember;
581} uniformBlock;
582
583void main()
584{
585	${{OUTPUT}} = uniformBlock.uniformMember;
586}"""[1:]
587
588emptyGlobalLayoutShaderTemplate = """
589#version 300 es
590precision highp float;
591
592layout() uniform;
593
594${{OUTPUT_DECLARATION}}
595
596uniform UniformBlock
597{
598	vec4 uniformMember;
599} uniformBlock;
600
601void main()
602{
603	${{OUTPUT}} = uniformBlock.uniformMember;
604}"""[1:]
605
606emptyMemberLayoutShaderTemplate = """
607#version 300 es
608precision highp float;
609
610${{OUTPUT_DECLARATION}}
611
612uniform UniformBlock
613{
614	layout() vec4 uniformMember;
615} uniformBlock;
616
617void main()
618{
619	${{OUTPUT}} = uniformBlock.uniformMember;
620}"""[1:]
621
622invalidMemberLayoutShaderTemplate = """
623#version 300 es
624precision highp float;
625
626${{OUTPUT_DECLARATION}}
627
628uniform UniformBlock
629{
630	layout(%s) vec4 uniformMember;
631} uniformBlock;
632
633void main()
634{
635	${{OUTPUT}} = uniformBlock.uniformMember;
636}"""[1:]
637
638structureDefinitionShaderTemplate = """
639#version 300 es
640precision highp float;
641
642${{OUTPUT_DECLARATION}}
643
644uniform UniformBlock
645{
646	struct A
647	{
648		vec4 uniformMember;
649	} a;
650} uniformBlock;
651
652void main()
653{
654	${{OUTPUT}} = uniformBlock.a.uniformMember;
655}"""[1:]
656
657samplerShaderTemplate = """
658#version 300 es
659precision highp float;
660
661${{OUTPUT_DECLARATION}}
662
663uniform UniformBlock
664{
665	sampler2D sampler;
666	vec4 uniformMember;
667} uniformBlock;
668
669void main()
670{
671	${{OUTPUT}} = uniformBlock.uniformMember;
672}"""[1:]
673
674missingBlockNameShaderTemplate = """
675#version 300 es
676precision highp float;
677
678${{OUTPUT_DECLARATION}}
679
680uniform
681{
682	vec4 uniformMember;
683} uniformBlock;
684
685void main()
686{
687	${{OUTPUT}} = uniformBlock.uniformMember;
688}"""[1:]
689
690invalidCharacterBlockNameShaderTemplate = """
691#version 300 es
692precision highp float;
693
694${{OUTPUT_DECLARATION}}
695
696uniform 0UniformBlock
697{
698	vec4 uniformMember;
699} uniformBlock;
700
701void main()
702{
703	${{OUTPUT}} = uniformBlock.uniformMember;
704}"""[1:]
705
706invalidIdentifierBlockNameShaderTemplate = """
707#version 300 es
708precision highp float;
709
710${{OUTPUT_DECLARATION}}
711
712uniform gl_UniformBlock
713{
714	vec4 uniformMember;
715} uniformBlock;
716
717void main()
718{
719	${{OUTPUT}} = uniformBlock.uniformMember;
720}"""[1:]
721
722tooLongIdentifierBlockNameShaderTemplate = ("""
723#version 300 es
724precision highp float;
725
726${{OUTPUT_DECLARATION}}
727
728// Total of 1025 characters
729uniform """ + ("a" * 1025) + """
730{
731	vec4 uniformMember;
732} uniformBlock;
733
734void main()
735{
736	${{OUTPUT}} = uniformBlock.uniformMember;
737}""")[1:]
738
739invalidCharacterInstanceNameShaderTemplate = """
740#version 300 es
741precision highp float;
742
743${{OUTPUT_DECLARATION}}
744
745uniform UniformInstance
746{
747	vec4 uniformMember;
748} 0uniformBlock;
749
750void main()
751{
752	${{OUTPUT}} = 0uniformBlock.uniformMember;
753}"""[1:]
754
755invalidIdentifierInstanceNameShaderTemplate = """
756#version 300 es
757precision highp float;
758
759${{OUTPUT_DECLARATION}}
760
761uniform UniformBlock
762{
763	vec4 uniformMember;
764} gl_uniformBlock;
765
766void main()
767{
768	${{OUTPUT}} = gl_uniformBlock.uniformMember;
769}"""[1:]
770
771tooLongIdentifierInstanceNameShaderTemplate = ("""
772#version 300 es
773precision highp float;
774
775${{OUTPUT_DECLARATION}}
776
777uniform UniformBlock
778{
779	vec4 uniformMember;
780} """ + ("a" * 1025) + """;
781// Total of 1025 characters
782
783void main()
784{
785	${{OUTPUT}} = """ + ("a" * 1025) + """.uniformMember;
786}""")[1:]
787
788doubleUnderscoreIdentifierInstanceNameShaderTemplate = ("""
789#version 300 es
790precision highp float;
791
792${{OUTPUT_DECLARATION}}
793
794uniform UniformBlock
795{
796	vec4 uniformMember;
797} __;
798
799void main()
800{
801	${{OUTPUT}} = __.uniformMember;
802}""")[1:]
803
804doubleUnderscoreIdentifierBlockNameShaderTemplate = ("""
805#version 300 es
806precision highp float;
807
808${{OUTPUT_DECLARATION}}
809
810uniform __
811{
812	vec4 uniformMember;
813} uniformBlock;
814
815void main()
816{
817	${{OUTPUT}} = uniformBlock.uniformMember;
818}""")[1:]
819
820invalidCases = (
821			sum([createCases("member_%s_interface_qualifier" % qualifier, invalidMemberInterfaceQualifierShaderTemplate % qualifier, False)
822					for qualifier in ["in", "out", "buffer", "attribute", "varying"]], [])
823			+ createCases("conflicting_instance_names", conflictingInstanceNamesShaderTemplate, False)
824			+ createCases("conflicting_function_and_instance_name", conflictingFunctionAndInstanceNameShaderTemplate, False)
825			+ createCases("conflicting_function_and_block_name", conflictingFunctionAndBlockNameShaderTemplate, False)
826			+ sum([createCases("conflicting_%s_and_instance_name" % qualifier, conflictingVariableAndInstanceNameShaderTemplate % qualifier, False)
827					for qualifier in ["uniform", "in", "out"]], [])
828			+ sum([createCases("conflicting_%s_and_block_name" % qualifier, conflictingVariableAndBlockNameShaderTemplate % qualifier, False)
829					for qualifier in ["uniform", "in", "out"]], [])
830			+ createCases("matching_instance_and_block_name", matchingInstanceAndBlockNameShaderTemplate, False)
831			+ createCases("reference_using_block_name", referenceUsingBlockNameShaderTemplate, False)
832			+ createCases("empty_block", emptyBlockShaderTemplate, False)
833			+ createCases("empty_layout", emptyLayoutShaderTemplate, False)
834			+ createCases("empty_member_layout", emptyMemberLayoutShaderTemplate, False)
835			+ createCases("empty_global_layout", emptyGlobalLayoutShaderTemplate, False)
836			+ createCases("structure_definition", structureDefinitionShaderTemplate, False)
837			+ sum([createCases("member_layout_%s" % qualifier, invalidMemberLayoutShaderTemplate % qualifier, False)
838					for qualifier in ["shared", "packed", "std140"]], [])
839			+ createCases("missing_block_name", missingBlockNameShaderTemplate, False)
840			+ createCases("invalid_character_block_name", invalidCharacterBlockNameShaderTemplate, False)
841			+ createCases("invalid_identifier_block_name", invalidIdentifierBlockNameShaderTemplate, False)
842			+ createCases("too_long_block_name", tooLongIdentifierBlockNameShaderTemplate, False)
843			+ createCases("invalid_character_instance_name", invalidCharacterInstanceNameShaderTemplate, False)
844			+ createCases("invalid_identifier_instance_name", invalidIdentifierInstanceNameShaderTemplate, False)
845			+ createCases("double_underscore_block_name", doubleUnderscoreIdentifierBlockNameShaderTemplate, False)
846			+ createCases("double_underscore_instance_name", doubleUnderscoreIdentifierInstanceNameShaderTemplate, False)
847		)
848
849allCases.append(CaseGroup("valid", "Valid uniform interface block syntax tests.", validCases))
850allCases.append(CaseGroup("invalid", "Invalid uniform interface block syntax tests.", invalidCases))
851
852if __name__ == "__main__":
853	print "Generating shader case files."
854	writeAllCases("uniform_block.test", allCases)
855