xref: /aosp_15_r20/external/angle/src/tests/compiler_tests/QualificationOrder_test.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // QualificationOrder_test.cpp:
7 //   OpenGL ES 3.1 removes the strict order of qualifiers imposed by the grammar.
8 //   This file contains tests for invalid order and usage of qualifiers.
9 
10 #include "tests/test_utils/ShaderCompileTreeTest.h"
11 
12 using namespace sh;
13 
14 class QualificationOrderFragmentShaderTest : public ShaderCompileTreeTest
15 {
16   public:
QualificationOrderFragmentShaderTest()17     QualificationOrderFragmentShaderTest() {}
18 
19   protected:
initResources(ShBuiltInResources * resources)20     void initResources(ShBuiltInResources *resources) override
21     {
22         resources->MaxDrawBuffers = (getShaderSpec() == SH_GLES2_SPEC) ? 1 : 8;
23     }
24 
getShaderType() const25     ::GLenum getShaderType() const override { return GL_FRAGMENT_SHADER; }
26 
getShaderSpec() const27     ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }
28 };
29 
30 class QualificationOrderVertexShaderTest : public QualificationOrderFragmentShaderTest
31 {
32   public:
QualificationOrderVertexShaderTest()33     QualificationOrderVertexShaderTest() {}
34 
35   protected:
getShaderType() const36     ::GLenum getShaderType() const override { return GL_VERTEX_SHADER; }
37 };
38 
39 // Repeating centroid qualifier is invalid.
TEST_F(QualificationOrderFragmentShaderTest,RepeatingCentroid)40 TEST_F(QualificationOrderFragmentShaderTest, RepeatingCentroid)
41 {
42     const std::string &shaderString =
43         "#version 300 es\n"
44         "precision mediump float;\n"
45         "flat centroid centroid in float myValue;\n"
46         "void main() {\n"
47         "}\n";
48 
49     if (compile(shaderString))
50     {
51         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
52     }
53 }
54 
55 // Repeating uniform storage qualifiers is invalid.
TEST_F(QualificationOrderFragmentShaderTest,RepeatingUniforms)56 TEST_F(QualificationOrderFragmentShaderTest, RepeatingUniforms)
57 {
58     const std::string &shaderString =
59         "#version 300 es\n"
60         "precision mediump float;\n"
61         "uniform uniform float myValue;\n"
62         "void main() {\n"
63         "}\n";
64 
65     if (compile(shaderString))
66     {
67         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
68     }
69 }
70 
71 // Repeating varying storage qualifiers is invalid.
TEST_F(QualificationOrderFragmentShaderTest,RepeatingVaryings)72 TEST_F(QualificationOrderFragmentShaderTest, RepeatingVaryings)
73 {
74     const std::string &shaderString =
75         "precision mediump float;\n"
76         "varying varying vec4 myColor;\n"
77         "void main() {\n"
78         "}\n";
79 
80     if (compile(shaderString))
81     {
82         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
83     }
84 }
85 
86 // Layout qualifier should be before the storage qualifiers.
TEST_F(QualificationOrderFragmentShaderTest,WrongOrderQualifiers)87 TEST_F(QualificationOrderFragmentShaderTest, WrongOrderQualifiers)
88 {
89     const std::string &shaderString =
90         "#version 300 es\n"
91         "precision mediump float;\n"
92         "out layout(location=1) vec4 myColor;\n"
93         "void main() {\n"
94         "}\n";
95 
96     if (compile(shaderString))
97     {
98         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
99     }
100 }
101 
102 // Centroid out is the correct order. Out centroid is incorrect.
TEST_F(QualificationOrderVertexShaderTest,WrongOrderCentroidOut)103 TEST_F(QualificationOrderVertexShaderTest, WrongOrderCentroidOut)
104 {
105     const std::string &shaderString =
106         "#version 300 es\n"
107         "precision mediump float;\n"
108         "in vec4 uv;\n"
109         "out centroid vec4 position;\n"
110         "void main() {\n"
111         "position = uv;\n"
112         "gl_Position = uv;\n"
113         "}\n";
114 
115     if (compile(shaderString))
116     {
117         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
118     }
119 }
120 
121 // Centroid in is the correct order. In centroid is incorrect.
TEST_F(QualificationOrderFragmentShaderTest,WrongOrderCentroidIn)122 TEST_F(QualificationOrderFragmentShaderTest, WrongOrderCentroidIn)
123 {
124     const std::string &shaderString =
125         "#version 300 es\n"
126         "precision mediump float;\n"
127         "in centroid vec4 colorIN;\n"
128         "out vec4 colorOUT;\n"
129         "void main() {\n"
130         "colorOUT = colorIN;\n"
131         "}\n";
132 
133     if (compile(shaderString))
134     {
135         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
136     }
137 }
138 
139 // Type cannot be before the storage qualifier.
TEST_F(QualificationOrderFragmentShaderTest,WrongOrderTypeStorage)140 TEST_F(QualificationOrderFragmentShaderTest, WrongOrderTypeStorage)
141 {
142     const std::string &shaderString =
143         "#version 300 es\n"
144         "precision mediump float;\n"
145         "centroid in vec4 colorIN;\n"
146         "vec4 out colorOUT;\n"
147         "void main() {\n"
148         "colorOUT = colorIN;\n"
149         "}\n";
150 
151     if (compile(shaderString))
152     {
153         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
154     }
155 }
156 
157 // A variable cannot have two conflicting storage qualifiers.
TEST_F(QualificationOrderFragmentShaderTest,RepeatingDifferentStorageQualifiers)158 TEST_F(QualificationOrderFragmentShaderTest, RepeatingDifferentStorageQualifiers)
159 {
160     const std::string &shaderString =
161         "#version 300 es\n"
162         "precision mediump float;\n"
163         "centroid in vec4 colorIN;\n"
164         "uniform out vec4 colorOUT;\n"
165         "void main() {\n"
166         "colorOUT = colorIN;\n"
167         "}\n";
168 
169     if (compile(shaderString))
170     {
171         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
172     }
173 }
174 
175 // A variable cannot have two different layout qualifiers.
TEST_F(QualificationOrderFragmentShaderTest,RepeatingLayoutQualifiers)176 TEST_F(QualificationOrderFragmentShaderTest, RepeatingLayoutQualifiers)
177 {
178     const std::string &shaderString =
179         "#version 300 es\n"
180         "precision mediump float;\n"
181         "in vec4 colorIN;\n"
182         "layout(location=0) layout(location=0) out vec4 colorOUT;\n"
183         "void main() {\n"
184         "colorOUT = colorIN;\n"
185         "}\n";
186 
187     if (compile(shaderString))
188     {
189         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
190     }
191 }
192 
193 // A variable cannot have repeating invariant qualifiers.
TEST_F(QualificationOrderFragmentShaderTest,RepeatingInvariantQualifiers)194 TEST_F(QualificationOrderFragmentShaderTest, RepeatingInvariantQualifiers)
195 {
196     const std::string &shaderString =
197         "#version 300 es\n"
198         "precision mediump float;\n"
199         "in vec4 colorIN;\n"
200         "invariant invariant out vec4 colorOUT;\n"
201         "void main() {\n"
202         "colorOUT = colorIN;\n"
203         "}\n";
204 
205     if (compile(shaderString))
206     {
207         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
208     }
209 }
210 
211 // A variable cannot have repeating storage qualifiers.
TEST_F(QualificationOrderVertexShaderTest,RepeatingAttributes)212 TEST_F(QualificationOrderVertexShaderTest, RepeatingAttributes)
213 {
214     const std::string &shaderString =
215         "precision mediump float;\n"
216         "attribute attribute vec4 positionIN;\n"
217         "void main() {\n"
218         "gl_Position = positionIN;\n"
219         "}\n";
220 
221     if (compile(shaderString))
222     {
223         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
224     }
225 }
226 
227 // Wrong order for invariant varying. It should be 'invariant varying', not 'varying invariant'.
TEST_F(QualificationOrderVertexShaderTest,VaryingInvariantWrongOrder)228 TEST_F(QualificationOrderVertexShaderTest, VaryingInvariantWrongOrder)
229 {
230     const std::string &shaderString =
231         "precision mediump float;\n"
232         "attribute vec4 positionIN;\n"
233         "varying invariant vec4 dataOUT;\n"
234         "void main() {\n"
235         "gl_Position = positionIN;\n"
236         "dataOUT = 0.5 * dataOUT + vec4(0.5);\n"
237         "}\n";
238 
239     if (compile(shaderString))
240     {
241         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
242     }
243 }
244 
245 // A variable cannot have repeating storage qualifiers.
TEST_F(QualificationOrderVertexShaderTest,AttributeVaryingMix)246 TEST_F(QualificationOrderVertexShaderTest, AttributeVaryingMix)
247 {
248     const std::string &shaderString =
249         "precision mediump float;\n"
250         "attribute varying vec4 positionIN;\n"
251         "void main() {\n"
252         "gl_Position = positionIN;\n"
253         "}\n";
254 
255     if (compile(shaderString))
256     {
257         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
258     }
259 }
260 
261 // A variable cannot have repeating storage qualifiers.
TEST_F(QualificationOrderVertexShaderTest,VaryingAttributeMix)262 TEST_F(QualificationOrderVertexShaderTest, VaryingAttributeMix)
263 {
264     const std::string &shaderString =
265         "precision mediump float;\n"
266         "varying attribute vec4 positionIN;\n"
267         "void main() {\n"
268         "gl_Position = positionIN;\n"
269         "}\n";
270     if (compile(shaderString))
271     {
272         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
273     }
274 }
275 
276 // A variable cannot have repeating interpolation qualifiers.
TEST_F(QualificationOrderVertexShaderTest,RepeatingInterpolationQualifiers)277 TEST_F(QualificationOrderVertexShaderTest, RepeatingInterpolationQualifiers)
278 {
279     const std::string &shaderString =
280         "#version 300 es\n"
281         "precision mediump float;\n"
282         "in vec4 positionIN;\n"
283         "flat flat out vec4 dataOUT;\n"
284         "void main() {\n"
285         "gl_Position = positionIN;\n"
286         "dataOUT = 0.5 * dataOUT + vec4(0.5);\n"
287         "}\n";
288 
289     if (compile(shaderString))
290     {
291         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
292     }
293 }
294 
295 // Wrong order for the interpolation and storage qualifier. The correct order is interpolation
296 // qualifier and then storage qualifier.
TEST_F(QualificationOrderVertexShaderTest,WrongOrderInterpolationStorageQualifiers)297 TEST_F(QualificationOrderVertexShaderTest, WrongOrderInterpolationStorageQualifiers)
298 {
299     const std::string &shaderString =
300         "#version 300 es\n"
301         "precision mediump float;\n"
302         "in vec4 positionIN;\n"
303         "out flat vec4 dataOUT;\n"
304         "void main() {\n"
305         "gl_Position = positionIN;\n"
306         "dataOUT = 0.5 * dataOUT + vec4(0.5);\n"
307         "}\n";
308 
309     if (compile(shaderString))
310     {
311         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
312     }
313 }
314 
315 // The correct order is invariant, interpolation, storage.
TEST_F(QualificationOrderVertexShaderTest,WrongOrderInvariantInterpolationStorageQualifiers)316 TEST_F(QualificationOrderVertexShaderTest, WrongOrderInvariantInterpolationStorageQualifiers)
317 {
318     const std::string &shaderString =
319         "#version 300 es\n"
320         "precision mediump float;\n"
321         "in vec4 positionIN;\n"
322         "flat invariant out vec4 dataOUT;\n"
323         "void main() {\n"
324         "gl_Position = positionIN;\n"
325         "dataOUT = 0.5 * dataOUT + vec4(0.5);\n"
326         "}\n";
327 
328     if (compile(shaderString))
329     {
330         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
331     }
332 }
333 
334 // The invariant qualifer has to be before the storage qualifiers.
TEST_F(QualificationOrderVertexShaderTest,WrongOrderInvariantNotFirst)335 TEST_F(QualificationOrderVertexShaderTest, WrongOrderInvariantNotFirst)
336 {
337     const std::string &shaderString =
338         "#version 300 es\n"
339         "precision mediump float;\n"
340         "in vec4 positionIN;\n"
341         "centroid out invariant vec4 dataOUT;\n"
342         "void main() {\n"
343         "gl_Position = positionIN;\n"
344         "dataOUT = 0.5 * dataOUT + vec4(0.5);\n"
345         "}\n";
346 
347     if (compile(shaderString))
348     {
349         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
350     }
351 }
352 
353 // The precision qualifier is after the storage qualifiers.
TEST_F(QualificationOrderVertexShaderTest,WrongOrderPrecision)354 TEST_F(QualificationOrderVertexShaderTest, WrongOrderPrecision)
355 {
356     const std::string &shaderString =
357         "#version 300 es\n"
358         "precision mediump float;\n"
359         "in vec4 positionIN;\n"
360         "highp centroid out vec4 dataOUT;\n"
361         "void main() {\n"
362         "gl_Position = positionIN;\n"
363         "dataOUT = 0.5 * dataOUT + vec4(0.5);\n"
364         "}\n";
365 
366     if (compile(shaderString))
367     {
368         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
369     }
370 }
371 
372 // A variable cannot have multiple declarations of the 'in' storage qualifier.
TEST_F(QualificationOrderVertexShaderTest,RepeatingInQualifier)373 TEST_F(QualificationOrderVertexShaderTest, RepeatingInQualifier)
374 {
375     const std::string &shaderString =
376         "#version 300 es\n"
377         "precision mediump float;\n"
378         "in in vec4 positionIN;\n"
379         "void main() {\n"
380         "gl_Position = positionIN;\n"
381         "}\n";
382 
383     if (compile(shaderString))
384     {
385         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
386     }
387 }
388 
389 // A variable cannot have multiple declarations of the 'attribute' storage qualifier.
TEST_F(QualificationOrderVertexShaderTest,RepeatingAttributeQualifier)390 TEST_F(QualificationOrderVertexShaderTest, RepeatingAttributeQualifier)
391 {
392     const std::string &shaderString =
393         "precision mediump float;\n"
394         "attribute attribute vec4 positionIN;\n"
395         "void main() {\n"
396         "gl_Position = positionIN;\n"
397         "}\n";
398 
399     if (compile(shaderString))
400     {
401         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
402     }
403 }
404 
405 // Vertex input cannot be qualified with invariant.
TEST_F(QualificationOrderVertexShaderTest,InvariantVertexInput)406 TEST_F(QualificationOrderVertexShaderTest, InvariantVertexInput)
407 {
408     const std::string &shaderString =
409         "precision mediump float;\n"
410         "invariant attribute vec4 positionIN;\n"
411         "void main() {\n"
412         "gl_Position = positionIN;\n"
413         "}\n";
414 
415     if (compile(shaderString))
416     {
417         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
418     }
419 }
420 
421 // Cannot have a function parameter with the invariant qualifier.
TEST_F(QualificationOrderFragmentShaderTest,InvalidFunctionParametersInvariant)422 TEST_F(QualificationOrderFragmentShaderTest, InvalidFunctionParametersInvariant)
423 {
424     const std::string &shaderString =
425         "precision lowp float;\n"
426         "varying float value;\n"
427         "float foo0 (invariant in float x) {\n"
428         "   return 2.0*x;\n"
429         "}\n"
430         "void main()\n"
431         "{\n"
432         "   gl_FragColor = vec4(foo0(value));\n"
433         "}\n";
434 
435     if (compile(shaderString))
436     {
437         FAIL() << "Shader compilation succeeded, expecting failure" << mInfoLog;
438     }
439 }
440 
441 // Cannot have a function parameter with the attribute qualifier.
TEST_F(QualificationOrderFragmentShaderTest,InvalidFunctionParametersAttribute)442 TEST_F(QualificationOrderFragmentShaderTest, InvalidFunctionParametersAttribute)
443 {
444     const std::string &shaderString =
445         "precision lowp float;\n"
446         "varying float value;\n"
447         "float foo0 (attribute float x) {\n"
448         "   return 2.0*x;\n"
449         "}\n"
450         "void main()\n"
451         "{\n"
452         "   gl_FragColor = vec4(foo0(value));\n"
453         "}\n";
454 
455     if (compile(shaderString))
456     {
457         FAIL() << "Shader compilation succeeded, expecting failure" << mInfoLog;
458     }
459 }
460 
461 // Cannot have a function parameter with the varying qualifier.
TEST_F(QualificationOrderFragmentShaderTest,InvalidFunctionParametersVarying)462 TEST_F(QualificationOrderFragmentShaderTest, InvalidFunctionParametersVarying)
463 {
464     const std::string &shaderString =
465         "precision lowp float;\n"
466         "varying float value;\n"
467         "float foo0 (varying float x) {\n"
468         "   return 2.0*x;\n"
469         "}\n"
470         "void main()\n"
471         "{\n"
472         "   gl_FragColor = vec4(foo0(value));\n"
473         "}\n";
474 
475     if (compile(shaderString))
476     {
477         FAIL() << "Shader compilation succeeded, expecting failure" << mInfoLog;
478     }
479 }
480 
481 // Cannot have a function parameter with the layout qualifier
TEST_F(QualificationOrderFragmentShaderTest,InvalidFunctionParametersLayout)482 TEST_F(QualificationOrderFragmentShaderTest, InvalidFunctionParametersLayout)
483 {
484     const std::string &shaderString =
485         "#version 300 es\n"
486         "precision lowp float;\n"
487         "in float value;\n"
488         "float foo0 (layout(location = 3) in float x) {\n"
489         "   return 2.0*x;\n"
490         "}\n"
491         "out vec4 colorOUT;\n"
492         "void main()\n"
493         "{\n"
494         "   colorOUT = vec4(foo0(value));\n"
495         "}\n";
496 
497     if (compile(shaderString))
498     {
499         FAIL() << "Shader compilation succeeded, expecting failure" << mInfoLog;
500     }
501 }
502 
503 // Cannot have a function parameter with the centroid qualifier
TEST_F(QualificationOrderFragmentShaderTest,InvalidFunctionParametersCentroidIn)504 TEST_F(QualificationOrderFragmentShaderTest, InvalidFunctionParametersCentroidIn)
505 {
506     const std::string &shaderString =
507         "#version 300 es\n"
508         "precision lowp float;\n"
509         "in float value;\n"
510         "float foo0 (centroid in float x) {\n"
511         "   return 2.0*x;\n"
512         "}\n"
513         "out vec4 colorOUT;\n"
514         "void main()\n"
515         "{\n"
516         "   colorOUT = vec4(foo0(value));\n"
517         "}\n";
518 
519     if (compile(shaderString))
520     {
521         FAIL() << "Shader compilation succeeded, expecting failure" << mInfoLog;
522     }
523 }
524 
525 // Cannot have a function parameter with the flat qualifier
TEST_F(QualificationOrderFragmentShaderTest,InvalidFunctionParametersFlatIn)526 TEST_F(QualificationOrderFragmentShaderTest, InvalidFunctionParametersFlatIn)
527 {
528     const std::string &shaderString =
529         "#version 300 es\n"
530         "precision lowp float;\n"
531         "in float value;\n"
532         "float foo0 (flat in float x) {\n"
533         "   return 2.0*x;\n"
534         "}\n"
535         "out vec4 colorOUT;\n"
536         "void main()\n"
537         "{\n"
538         "   colorOUT = vec4(foo0(value));\n"
539         "}\n";
540 
541     if (compile(shaderString))
542     {
543         FAIL() << "Shader compilation succeeded, expecting failure" << mInfoLog;
544     }
545 }
546 
547 // Output layout location qualifier can't appear more than once within a declaration.
548 // GLSL ES 3.00.6 section 4.3.8.2 Output Layout Qualifiers.
TEST_F(QualificationOrderFragmentShaderTest,TwoOutputLocations)549 TEST_F(QualificationOrderFragmentShaderTest, TwoOutputLocations)
550 {
551     const std::string &shaderString =
552         "#version 300 es\n"
553         "precision mediump float;\n"
554         "layout(location=1, location=2) out vec4 myColor;\n"
555         "void main() {\n"
556         "}\n";
557 
558     if (compile(shaderString))
559     {
560         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
561     }
562 }
563