1 //
2 // Copyright 2015 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 
7 #include "test_utils/ANGLETest.h"
8 
9 #include "libANGLE/Context.h"
10 #include "libANGLE/Program.h"
11 #include "test_utils/gl_raii.h"
12 
13 using namespace angle;
14 
15 namespace
16 {
17 
18 class GLSLTest : public ANGLETest
19 {
20   protected:
GLSLTest()21     GLSLTest()
22     {
23         setWindowWidth(128);
24         setWindowHeight(128);
25         setConfigRedBits(8);
26         setConfigGreenBits(8);
27         setConfigBlueBits(8);
28         setConfigAlphaBits(8);
29     }
30 
SetUp()31     virtual void SetUp()
32     {
33         ANGLETest::SetUp();
34 
35         mSimpleVSSource = SHADER_SOURCE
36         (
37             attribute vec4 inputAttribute;
38             void main()
39             {
40                 gl_Position = inputAttribute;
41             }
42         );
43     }
44 
GenerateVaryingType(GLint vectorSize)45     std::string GenerateVaryingType(GLint vectorSize)
46     {
47         char varyingType[10];
48 
49         if (vectorSize == 1)
50         {
51             sprintf(varyingType, "float");
52         }
53         else
54         {
55             sprintf(varyingType, "vec%d", vectorSize);
56         }
57 
58         return std::string(varyingType);
59     }
60 
GenerateVectorVaryingDeclaration(GLint vectorSize,GLint arraySize,GLint id)61     std::string GenerateVectorVaryingDeclaration(GLint vectorSize, GLint arraySize, GLint id)
62     {
63         char buff[100];
64 
65         if (arraySize == 1)
66         {
67             sprintf(buff, "varying %s v%d;\n", GenerateVaryingType(vectorSize).c_str(), id);
68         }
69         else
70         {
71             sprintf(buff, "varying %s v%d[%d];\n", GenerateVaryingType(vectorSize).c_str(), id, arraySize);
72         }
73 
74         return std::string(buff);
75     }
76 
GenerateVectorVaryingSettingCode(GLint vectorSize,GLint arraySize,GLint id)77     std::string GenerateVectorVaryingSettingCode(GLint vectorSize, GLint arraySize, GLint id)
78     {
79         std::string returnString;
80         char buff[100];
81 
82         if (arraySize == 1)
83         {
84             sprintf(buff, "\t v%d = %s(1.0);\n", id, GenerateVaryingType(vectorSize).c_str());
85             returnString += buff;
86         }
87         else
88         {
89             for (int i = 0; i < arraySize; i++)
90             {
91                 sprintf(buff, "\t v%d[%d] = %s(1.0);\n", id, i, GenerateVaryingType(vectorSize).c_str());
92                 returnString += buff;
93             }
94         }
95 
96         return returnString;
97     }
98 
GenerateVectorVaryingUseCode(GLint arraySize,GLint id)99     std::string GenerateVectorVaryingUseCode(GLint arraySize, GLint id)
100     {
101         if (arraySize == 1)
102         {
103             char buff[100];
104             sprintf(buff, "v%d + ", id);
105             return std::string(buff);
106         }
107         else
108         {
109             std::string returnString;
110             for (int i = 0; i < arraySize; i++)
111             {
112                 char buff[100];
113                 sprintf(buff, "v%d[%d] + ", id, i);
114                 returnString += buff;
115             }
116             return returnString;
117         }
118     }
119 
GenerateGLSLWithVaryings(GLint floatCount,GLint floatArrayCount,GLint vec2Count,GLint vec2ArrayCount,GLint vec3Count,GLint vec3ArrayCount,GLint vec4Count,GLint vec4ArrayCount,bool useFragCoord,bool usePointCoord,bool usePointSize,std::string * fragmentShader,std::string * vertexShader)120     void GenerateGLSLWithVaryings(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
121                                   GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize,
122                                   std::string* fragmentShader, std::string* vertexShader)
123     {
124         // Generate a string declaring the varyings, to share between the fragment shader and the vertex shader.
125         std::string varyingDeclaration;
126 
127         unsigned int varyingCount = 0;
128 
129         for (GLint i = 0; i < floatCount; i++)
130         {
131             varyingDeclaration += GenerateVectorVaryingDeclaration(1, 1, varyingCount);
132             varyingCount += 1;
133         }
134 
135         for (GLint i = 0; i < floatArrayCount; i++)
136         {
137             varyingDeclaration += GenerateVectorVaryingDeclaration(1, 2, varyingCount);
138             varyingCount += 1;
139         }
140 
141         for (GLint i = 0; i < vec2Count; i++)
142         {
143             varyingDeclaration += GenerateVectorVaryingDeclaration(2, 1, varyingCount);
144             varyingCount += 1;
145         }
146 
147         for (GLint i = 0; i < vec2ArrayCount; i++)
148         {
149             varyingDeclaration += GenerateVectorVaryingDeclaration(2, 2, varyingCount);
150             varyingCount += 1;
151         }
152 
153         for (GLint i = 0; i < vec3Count; i++)
154         {
155             varyingDeclaration += GenerateVectorVaryingDeclaration(3, 1, varyingCount);
156             varyingCount += 1;
157         }
158 
159         for (GLint i = 0; i < vec3ArrayCount; i++)
160         {
161             varyingDeclaration += GenerateVectorVaryingDeclaration(3, 2, varyingCount);
162             varyingCount += 1;
163         }
164 
165         for (GLint i = 0; i < vec4Count; i++)
166         {
167             varyingDeclaration += GenerateVectorVaryingDeclaration(4, 1, varyingCount);
168             varyingCount += 1;
169         }
170 
171         for (GLint i = 0; i < vec4ArrayCount; i++)
172         {
173             varyingDeclaration += GenerateVectorVaryingDeclaration(4, 2, varyingCount);
174             varyingCount += 1;
175         }
176 
177         // Generate the vertex shader
178         vertexShader->clear();
179         vertexShader->append(varyingDeclaration);
180         vertexShader->append("\nvoid main()\n{\n");
181 
182         unsigned int currentVSVarying = 0;
183 
184         for (GLint i = 0; i < floatCount; i++)
185         {
186             vertexShader->append(GenerateVectorVaryingSettingCode(1, 1, currentVSVarying));
187             currentVSVarying += 1;
188         }
189 
190         for (GLint i = 0; i < floatArrayCount; i++)
191         {
192             vertexShader->append(GenerateVectorVaryingSettingCode(1, 2, currentVSVarying));
193             currentVSVarying += 1;
194         }
195 
196         for (GLint i = 0; i < vec2Count; i++)
197         {
198             vertexShader->append(GenerateVectorVaryingSettingCode(2, 1, currentVSVarying));
199             currentVSVarying += 1;
200         }
201 
202         for (GLint i = 0; i < vec2ArrayCount; i++)
203         {
204             vertexShader->append(GenerateVectorVaryingSettingCode(2, 2, currentVSVarying));
205             currentVSVarying += 1;
206         }
207 
208         for (GLint i = 0; i < vec3Count; i++)
209         {
210             vertexShader->append(GenerateVectorVaryingSettingCode(3, 1, currentVSVarying));
211             currentVSVarying += 1;
212         }
213 
214         for (GLint i = 0; i < vec3ArrayCount; i++)
215         {
216             vertexShader->append(GenerateVectorVaryingSettingCode(3, 2, currentVSVarying));
217             currentVSVarying += 1;
218         }
219 
220         for (GLint i = 0; i < vec4Count; i++)
221         {
222             vertexShader->append(GenerateVectorVaryingSettingCode(4, 1, currentVSVarying));
223             currentVSVarying += 1;
224         }
225 
226         for (GLint i = 0; i < vec4ArrayCount; i++)
227         {
228             vertexShader->append(GenerateVectorVaryingSettingCode(4, 2, currentVSVarying));
229             currentVSVarying += 1;
230         }
231 
232         if (usePointSize)
233         {
234             vertexShader->append("gl_PointSize = 1.0;\n");
235         }
236 
237         vertexShader->append("}\n");
238 
239         // Generate the fragment shader
240         fragmentShader->clear();
241         fragmentShader->append("precision highp float;\n");
242         fragmentShader->append(varyingDeclaration);
243         fragmentShader->append("\nvoid main() \n{ \n\tvec4 retColor = vec4(0,0,0,0);\n");
244 
245         unsigned int currentFSVarying = 0;
246 
247         // Make use of the float varyings
248         fragmentShader->append("\tretColor += vec4(");
249 
250         for (GLint i = 0; i < floatCount; i++)
251         {
252             fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
253             currentFSVarying += 1;
254         }
255 
256         for (GLint i = 0; i < floatArrayCount; i++)
257         {
258             fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
259             currentFSVarying += 1;
260         }
261 
262         fragmentShader->append("0.0, 0.0, 0.0, 0.0);\n");
263 
264         // Make use of the vec2 varyings
265         fragmentShader->append("\tretColor += vec4(");
266 
267         for (GLint i = 0; i < vec2Count; i++)
268         {
269             fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
270             currentFSVarying += 1;
271         }
272 
273         for (GLint i = 0; i < vec2ArrayCount; i++)
274         {
275             fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
276             currentFSVarying += 1;
277         }
278 
279         fragmentShader->append("vec2(0.0, 0.0), 0.0, 0.0);\n");
280 
281         // Make use of the vec3 varyings
282         fragmentShader->append("\tretColor += vec4(");
283 
284         for (GLint i = 0; i < vec3Count; i++)
285         {
286             fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
287             currentFSVarying += 1;
288         }
289 
290         for (GLint i = 0; i < vec3ArrayCount; i++)
291         {
292             fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
293             currentFSVarying += 1;
294         }
295 
296         fragmentShader->append("vec3(0.0, 0.0, 0.0), 0.0);\n");
297 
298         // Make use of the vec4 varyings
299         fragmentShader->append("\tretColor += ");
300 
301         for (GLint i = 0; i < vec4Count; i++)
302         {
303             fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
304             currentFSVarying += 1;
305         }
306 
307         for (GLint i = 0; i < vec4ArrayCount; i++)
308         {
309             fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
310             currentFSVarying += 1;
311         }
312 
313         fragmentShader->append("vec4(0.0, 0.0, 0.0, 0.0);\n");
314 
315         // Set gl_FragColor, and use special variables if requested
316         fragmentShader->append("\tgl_FragColor = retColor");
317 
318         if (useFragCoord)
319         {
320             fragmentShader->append(" + gl_FragCoord");
321         }
322 
323         if (usePointCoord)
324         {
325             fragmentShader->append(" + vec4(gl_PointCoord, 0.0, 0.0)");
326         }
327 
328         fragmentShader->append(";\n}");
329     }
330 
VaryingTestBase(GLint floatCount,GLint floatArrayCount,GLint vec2Count,GLint vec2ArrayCount,GLint vec3Count,GLint vec3ArrayCount,GLint vec4Count,GLint vec4ArrayCount,bool useFragCoord,bool usePointCoord,bool usePointSize,bool expectSuccess)331     void VaryingTestBase(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
332                          GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize, bool expectSuccess)
333     {
334         std::string fragmentShaderSource;
335         std::string vertexShaderSource;
336 
337         GenerateGLSLWithVaryings(floatCount, floatArrayCount, vec2Count, vec2ArrayCount, vec3Count, vec3ArrayCount,
338                                  vec4Count, vec4ArrayCount, useFragCoord, usePointCoord, usePointSize,
339                                  &fragmentShaderSource, &vertexShaderSource);
340 
341         GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
342 
343         if (expectSuccess)
344         {
345             EXPECT_NE(0u, program);
346         }
347         else
348         {
349             EXPECT_EQ(0u, program);
350         }
351     }
352 
CompileGLSLWithUniformsAndSamplers(GLint vertexUniformCount,GLint fragmentUniformCount,GLint vertexSamplersCount,GLint fragmentSamplersCount,bool expectSuccess)353     void CompileGLSLWithUniformsAndSamplers(GLint vertexUniformCount,
354                                             GLint fragmentUniformCount,
355                                             GLint vertexSamplersCount,
356                                             GLint fragmentSamplersCount,
357                                             bool expectSuccess)
358     {
359         std::stringstream vertexShader;
360         std::stringstream fragmentShader;
361 
362         // Generate the vertex shader
363         vertexShader << "precision mediump float;\n";
364 
365         for (int i = 0; i < vertexUniformCount; i++)
366         {
367             vertexShader << "uniform vec4 v" << i << ";\n";
368         }
369 
370         for (int i = 0; i < vertexSamplersCount; i++)
371         {
372             vertexShader << "uniform sampler2D s" << i << ";\n";
373         }
374 
375         vertexShader << "void main()\n{\n";
376 
377         for (int i = 0; i < vertexUniformCount; i++)
378         {
379             vertexShader << "    gl_Position +=  v" << i << ";\n";
380         }
381 
382         for (int i = 0; i < vertexSamplersCount; i++)
383         {
384             vertexShader << "    gl_Position +=  texture2D(s" << i << ", vec2(0.0, 0.0));\n";
385         }
386 
387         if (vertexUniformCount == 0 && vertexSamplersCount == 0)
388         {
389             vertexShader << "   gl_Position = vec4(0.0);\n";
390         }
391 
392         vertexShader << "}\n";
393 
394         // Generate the fragment shader
395         fragmentShader << "precision mediump float;\n";
396 
397         for (int i = 0; i < fragmentUniformCount; i++)
398         {
399             fragmentShader << "uniform vec4 v" << i << ";\n";
400         }
401 
402         for (int i = 0; i < fragmentSamplersCount; i++)
403         {
404             fragmentShader << "uniform sampler2D s" << i << ";\n";
405         }
406 
407         fragmentShader << "void main()\n{\n";
408 
409         for (int i = 0; i < fragmentUniformCount; i++)
410         {
411             fragmentShader << "    gl_FragColor +=  v" << i << ";\n";
412         }
413 
414         for (int i = 0; i < fragmentSamplersCount; i++)
415         {
416             fragmentShader << "    gl_FragColor +=  texture2D(s" << i << ", vec2(0.0, 0.0));\n";
417         }
418 
419         if (fragmentUniformCount == 0 && fragmentSamplersCount == 0)
420         {
421             fragmentShader << "    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n";
422         }
423 
424         fragmentShader << "}\n";
425 
426         GLuint program = CompileProgram(vertexShader.str(), fragmentShader.str());
427 
428         if (expectSuccess)
429         {
430             EXPECT_NE(0u, program);
431         }
432         else
433         {
434             EXPECT_EQ(0u, program);
435         }
436     }
437 
438     std::string mSimpleVSSource;
439 };
440 
441 class GLSLTest_ES3 : public GLSLTest
442 {
SetUp()443     void SetUp() override
444     {
445         ANGLETest::SetUp();
446 
447         mSimpleVSSource =
448             "#version 300 es\n"
449             "in vec4 inputAttribute;"
450             "void main()"
451             "{"
452             "    gl_Position = inputAttribute;"
453             "}";
454     }
455 };
456 
TEST_P(GLSLTest,NamelessScopedStructs)457 TEST_P(GLSLTest, NamelessScopedStructs)
458 {
459     const std::string fragmentShaderSource = SHADER_SOURCE
460     (
461         precision mediump float;
462 
463         void main()
464         {
465             struct
466             {
467                 float q;
468             } b;
469 
470             gl_FragColor = vec4(1, 0, 0, 1);
471             gl_FragColor.a += b.q;
472         }
473     );
474 
475     GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
476     EXPECT_NE(0u, program);
477 }
478 
TEST_P(GLSLTest,ScopedStructsOrderBug)479 TEST_P(GLSLTest, ScopedStructsOrderBug)
480 {
481     // TODO(geofflang): Find out why this doesn't compile on Apple OpenGL drivers
482     // (http://anglebug.com/1292)
483     // TODO(geofflang): Find out why this doesn't compile on AMD OpenGL drivers
484     // (http://anglebug.com/1291)
485     if (IsDesktopOpenGL() && (IsOSX() || !IsNVIDIA()))
486     {
487         std::cout << "Test disabled on this OpenGL configuration." << std::endl;
488         return;
489     }
490 
491     const std::string fragmentShaderSource = SHADER_SOURCE
492     (
493         precision mediump float;
494 
495         struct T
496         {
497             float f;
498         };
499 
500         void main()
501         {
502             T a;
503 
504             struct T
505             {
506                 float q;
507             };
508 
509             T b;
510 
511             gl_FragColor = vec4(1, 0, 0, 1);
512             gl_FragColor.a += a.f;
513             gl_FragColor.a += b.q;
514         }
515     );
516 
517     GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
518     EXPECT_NE(0u, program);
519 }
520 
TEST_P(GLSLTest,ScopedStructsBug)521 TEST_P(GLSLTest, ScopedStructsBug)
522 {
523     const std::string fragmentShaderSource = SHADER_SOURCE
524     (
525         precision mediump float;
526 
527         struct T_0
528         {
529             float f;
530         };
531 
532         void main()
533         {
534             gl_FragColor = vec4(1, 0, 0, 1);
535 
536             struct T
537             {
538                 vec2 v;
539             };
540 
541             T_0 a;
542             T b;
543 
544             gl_FragColor.a += a.f;
545             gl_FragColor.a += b.v.x;
546         }
547     );
548 
549     GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
550     EXPECT_NE(0u, program);
551 }
552 
TEST_P(GLSLTest,DxPositionBug)553 TEST_P(GLSLTest, DxPositionBug)
554 {
555     const std::string &vertexShaderSource = SHADER_SOURCE
556     (
557         attribute vec4 inputAttribute;
558         varying float dx_Position;
559         void main()
560         {
561             gl_Position = vec4(inputAttribute);
562             dx_Position = 0.0;
563         }
564     );
565 
566     const std::string &fragmentShaderSource = SHADER_SOURCE
567     (
568         precision mediump float;
569 
570         varying float dx_Position;
571 
572         void main()
573         {
574             gl_FragColor = vec4(dx_Position, 0, 0, 1);
575         }
576     );
577 
578     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
579     EXPECT_NE(0u, program);
580 }
581 
TEST_P(GLSLTest,ElseIfRewriting)582 TEST_P(GLSLTest, ElseIfRewriting)
583 {
584     const std::string &vertexShaderSource =
585         "attribute vec4 a_position;\n"
586         "varying float v;\n"
587         "void main() {\n"
588         "  gl_Position = a_position;\n"
589         "  v = 1.0;\n"
590         "  if (a_position.x <= 0.5) {\n"
591         "    v = 0.0;\n"
592         "  } else if (a_position.x >= 0.5) {\n"
593         "    v = 2.0;\n"
594         "  }\n"
595         "}\n";
596 
597     const std::string &fragmentShaderSource =
598         "precision highp float;\n"
599         "varying float v;\n"
600         "void main() {\n"
601         "  vec4 color = vec4(1.0, 0.0, 0.0, 1.0);\n"
602         "  if (v >= 1.0) color = vec4(0.0, 1.0, 0.0, 1.0);\n"
603         "  if (v >= 2.0) color = vec4(0.0, 0.0, 1.0, 1.0);\n"
604         "  gl_FragColor = color;\n"
605         "}\n";
606 
607     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
608     ASSERT_NE(0u, program);
609 
610     drawQuad(program, "a_position", 0.5f);
611 
612     EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
613     EXPECT_PIXEL_EQ(getWindowWidth()-1, 0, 0, 255, 0, 255);
614 }
615 
TEST_P(GLSLTest,TwoElseIfRewriting)616 TEST_P(GLSLTest, TwoElseIfRewriting)
617 {
618     const std::string &vertexShaderSource =
619         "attribute vec4 a_position;\n"
620         "varying float v;\n"
621         "void main() {\n"
622         "  gl_Position = a_position;\n"
623         "  if (a_position.x == 0.0) {\n"
624         "    v = 1.0;\n"
625         "  } else if (a_position.x > 0.5) {\n"
626         "    v = 0.0;\n"
627         "  } else if (a_position.x > 0.75) {\n"
628         "    v = 0.5;\n"
629         "  }\n"
630         "}\n";
631 
632     const std::string &fragmentShaderSource =
633         "precision highp float;\n"
634         "varying float v;\n"
635         "void main() {\n"
636         "  gl_FragColor = vec4(v, 0.0, 0.0, 1.0);\n"
637         "}\n";
638 
639     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
640     EXPECT_NE(0u, program);
641 }
642 
TEST_P(GLSLTest,FrontFacingAndVarying)643 TEST_P(GLSLTest, FrontFacingAndVarying)
644 {
645     EGLPlatformParameters platform = GetParam().eglParameters;
646 
647     const std::string vertexShaderSource = SHADER_SOURCE
648     (
649         attribute vec4 a_position;
650         varying float v_varying;
651         void main()
652         {
653             v_varying = a_position.x;
654             gl_Position = a_position;
655         }
656     );
657 
658     const std::string fragmentShaderSource = SHADER_SOURCE
659     (
660         precision mediump float;
661         varying float v_varying;
662         void main()
663         {
664             vec4 c;
665 
666             if (gl_FrontFacing)
667             {
668                 c = vec4(v_varying, 0, 0, 1.0);
669             }
670             else
671             {
672                 c = vec4(0, v_varying, 0, 1.0);
673             }
674             gl_FragColor = c;
675         }
676     );
677 
678     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
679 
680     // Compilation should fail on D3D11 feature level 9_3, since gl_FrontFacing isn't supported.
681     if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
682     {
683         if (platform.majorVersion == 9 && platform.minorVersion == 3)
684         {
685             EXPECT_EQ(0u, program);
686             return;
687         }
688     }
689 
690     // Otherwise, compilation should succeed
691     EXPECT_NE(0u, program);
692 }
693 
694 // Verify that linking shaders declaring different shading language versions fails.
TEST_P(GLSLTest_ES3,VersionMismatch)695 TEST_P(GLSLTest_ES3, VersionMismatch)
696 {
697     const std::string fragmentShaderSource100 =
698         "precision mediump float;\n"
699         "varying float v_varying;\n"
700         "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
701 
702     const std::string vertexShaderSource100 =
703         "attribute vec4 a_position;\n"
704         "varying float v_varying;\n"
705         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
706 
707     const std::string fragmentShaderSource300 =
708         "#version 300 es\n"
709         "precision mediump float;\n"
710         "in float v_varying;\n"
711         "out vec4 my_FragColor;\n"
712         "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
713 
714     const std::string vertexShaderSource300 =
715         "#version 300 es\n"
716         "in vec4 a_position;\n"
717         "out float v_varying;\n"
718         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
719 
720     GLuint program = CompileProgram(vertexShaderSource300, fragmentShaderSource100);
721     EXPECT_EQ(0u, program);
722 
723     program = CompileProgram(vertexShaderSource100, fragmentShaderSource300);
724     EXPECT_EQ(0u, program);
725 }
726 
727 // Verify that declaring varying as invariant only in vertex shader fails in ESSL 1.00.
TEST_P(GLSLTest,InvariantVaryingOut)728 TEST_P(GLSLTest, InvariantVaryingOut)
729 {
730     const std::string fragmentShaderSource =
731         "precision mediump float;\n"
732         "varying float v_varying;\n"
733         "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
734 
735     const std::string vertexShaderSource =
736         "attribute vec4 a_position;\n"
737         "invariant varying float v_varying;\n"
738         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
739 
740     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
741     EXPECT_EQ(0u, program);
742 }
743 
744 // Verify that declaring varying as invariant only in vertex shader succeeds in ESSL 3.00.
TEST_P(GLSLTest_ES3,InvariantVaryingOut)745 TEST_P(GLSLTest_ES3, InvariantVaryingOut)
746 {
747     // TODO: ESSL 3.00 -> GLSL 1.20 translation should add "invariant" in fragment shader
748     // for varyings which are invariant in vertex shader (http://anglebug.com/1293)
749     if (IsDesktopOpenGL())
750     {
751         std::cout << "Test disabled on OpenGL." << std::endl;
752         return;
753     }
754 
755     const std::string fragmentShaderSource =
756         "#version 300 es\n"
757         "precision mediump float;\n"
758         "in float v_varying;\n"
759         "out vec4 my_FragColor;\n"
760         "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
761 
762     const std::string vertexShaderSource =
763         "#version 300 es\n"
764         "in vec4 a_position;\n"
765         "invariant out float v_varying;\n"
766         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
767 
768     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
769     EXPECT_NE(0u, program);
770 }
771 
772 // Verify that declaring varying as invariant only in fragment shader fails in ESSL 1.00.
TEST_P(GLSLTest,InvariantVaryingIn)773 TEST_P(GLSLTest, InvariantVaryingIn)
774 {
775     const std::string fragmentShaderSource =
776         "precision mediump float;\n"
777         "invariant varying float v_varying;\n"
778         "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
779 
780     const std::string vertexShaderSource =
781         "attribute vec4 a_position;\n"
782         "varying float v_varying;\n"
783         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
784 
785     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
786     EXPECT_EQ(0u, program);
787 }
788 
789 // Verify that declaring varying as invariant only in fragment shader fails in ESSL 3.00.
TEST_P(GLSLTest_ES3,InvariantVaryingIn)790 TEST_P(GLSLTest_ES3, InvariantVaryingIn)
791 {
792     const std::string fragmentShaderSource =
793         "#version 300 es\n"
794         "precision mediump float;\n"
795         "invariant in float v_varying;\n"
796         "out vec4 my_FragColor;\n"
797         "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
798 
799     const std::string vertexShaderSource =
800         "#version 300 es\n"
801         "in vec4 a_position;\n"
802         "out float v_varying;\n"
803         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
804 
805     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
806     EXPECT_EQ(0u, program);
807 }
808 
809 // Verify that declaring varying as invariant in both shaders succeeds in ESSL 1.00.
TEST_P(GLSLTest,InvariantVaryingBoth)810 TEST_P(GLSLTest, InvariantVaryingBoth)
811 {
812     const std::string fragmentShaderSource =
813         "precision mediump float;\n"
814         "invariant varying float v_varying;\n"
815         "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
816 
817     const std::string vertexShaderSource =
818         "attribute vec4 a_position;\n"
819         "invariant varying float v_varying;\n"
820         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
821 
822     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
823     EXPECT_NE(0u, program);
824 }
825 
826 // Verify that declaring varying as invariant in both shaders fails in ESSL 3.00.
TEST_P(GLSLTest_ES3,InvariantVaryingBoth)827 TEST_P(GLSLTest_ES3, InvariantVaryingBoth)
828 {
829     const std::string fragmentShaderSource =
830         "#version 300 es\n"
831         "precision mediump float;\n"
832         "invariant in float v_varying;\n"
833         "out vec4 my_FragColor;\n"
834         "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
835 
836     const std::string vertexShaderSource =
837         "#version 300 es\n"
838         "in vec4 a_position;\n"
839         "invariant out float v_varying;\n"
840         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
841 
842     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
843     EXPECT_EQ(0u, program);
844 }
845 
846 // Verify that declaring gl_Position as invariant succeeds in ESSL 1.00.
TEST_P(GLSLTest,InvariantGLPosition)847 TEST_P(GLSLTest, InvariantGLPosition)
848 {
849     const std::string fragmentShaderSource =
850         "precision mediump float;\n"
851         "varying float v_varying;\n"
852         "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
853 
854     const std::string vertexShaderSource =
855         "attribute vec4 a_position;\n"
856         "invariant gl_Position;\n"
857         "varying float v_varying;\n"
858         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
859 
860     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
861     EXPECT_NE(0u, program);
862 }
863 
864 // Verify that declaring gl_Position as invariant succeeds in ESSL 3.00.
TEST_P(GLSLTest_ES3,InvariantGLPosition)865 TEST_P(GLSLTest_ES3, InvariantGLPosition)
866 {
867     const std::string fragmentShaderSource =
868         "#version 300 es\n"
869         "precision mediump float;\n"
870         "in float v_varying;\n"
871         "out vec4 my_FragColor;\n"
872         "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
873 
874     const std::string vertexShaderSource =
875         "#version 300 es\n"
876         "in vec4 a_position;\n"
877         "invariant gl_Position;\n"
878         "out float v_varying;\n"
879         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
880 
881     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
882     EXPECT_NE(0u, program);
883 }
884 
885 // Verify that using invariant(all) in both shaders succeeds in ESSL 1.00.
TEST_P(GLSLTest,InvariantAllBoth)886 TEST_P(GLSLTest, InvariantAllBoth)
887 {
888     // TODO: ESSL 1.00 -> GLSL 1.20 translation should add "invariant" in fragment shader
889     // for varyings which are invariant in vertex shader individually,
890     // and remove invariant(all) from fragment shader (http://anglebug.com/1293)
891     if (IsDesktopOpenGL())
892     {
893         std::cout << "Test disabled on OpenGL." << std::endl;
894         return;
895     }
896 
897     const std::string fragmentShaderSource =
898         "#pragma STDGL invariant(all)\n"
899         "precision mediump float;\n"
900         "varying float v_varying;\n"
901         "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
902 
903     const std::string vertexShaderSource =
904         "#pragma STDGL invariant(all)\n"
905         "attribute vec4 a_position;\n"
906         "varying float v_varying;\n"
907         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
908 
909     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
910     EXPECT_NE(0u, program);
911 }
912 
913 // Verify that functions without return statements still compile
TEST_P(GLSLTest,MissingReturnFloat)914 TEST_P(GLSLTest, MissingReturnFloat)
915 {
916     const std::string vertexShaderSource =
917         "varying float v_varying;\n"
918         "float f() { if (v_varying > 0.0) return 1.0; }\n"
919         "void main() { gl_Position = vec4(f(), 0, 0, 1); }\n";
920 
921     const std::string fragmentShaderSource =
922         "precision mediump float;\n"
923         "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
924 
925     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
926     EXPECT_NE(0u, program);
927 }
928 
929 // Verify that functions without return statements still compile
TEST_P(GLSLTest,MissingReturnVec2)930 TEST_P(GLSLTest, MissingReturnVec2)
931 {
932     const std::string vertexShaderSource =
933         "varying float v_varying;\n"
934         "vec2 f() { if (v_varying > 0.0) return vec2(1.0, 1.0); }\n"
935         "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
936 
937     const std::string fragmentShaderSource =
938         "precision mediump float;\n"
939         "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
940 
941     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
942     EXPECT_NE(0u, program);
943 }
944 
945 // Verify that functions without return statements still compile
TEST_P(GLSLTest,MissingReturnVec3)946 TEST_P(GLSLTest, MissingReturnVec3)
947 {
948     const std::string vertexShaderSource =
949         "varying float v_varying;\n"
950         "vec3 f() { if (v_varying > 0.0) return vec3(1.0, 1.0, 1.0); }\n"
951         "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
952 
953     const std::string fragmentShaderSource =
954         "precision mediump float;\n"
955         "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
956 
957     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
958     EXPECT_NE(0u, program);
959 }
960 
961 // Verify that functions without return statements still compile
TEST_P(GLSLTest,MissingReturnVec4)962 TEST_P(GLSLTest, MissingReturnVec4)
963 {
964     const std::string vertexShaderSource =
965         "varying float v_varying;\n"
966         "vec4 f() { if (v_varying > 0.0) return vec4(1.0, 1.0, 1.0, 1.0); }\n"
967         "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
968 
969     const std::string fragmentShaderSource =
970         "precision mediump float;\n"
971         "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
972 
973     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
974     EXPECT_NE(0u, program);
975 }
976 
977 // Verify that functions without return statements still compile
TEST_P(GLSLTest,MissingReturnIVec4)978 TEST_P(GLSLTest, MissingReturnIVec4)
979 {
980     const std::string vertexShaderSource =
981         "varying float v_varying;\n"
982         "ivec4 f() { if (v_varying > 0.0) return ivec4(1, 1, 1, 1); }\n"
983         "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
984 
985     const std::string fragmentShaderSource =
986         "precision mediump float;\n"
987         "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
988 
989     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
990     EXPECT_NE(0u, program);
991 }
992 
993 // Verify that functions without return statements still compile
TEST_P(GLSLTest,MissingReturnMat4)994 TEST_P(GLSLTest, MissingReturnMat4)
995 {
996     const std::string vertexShaderSource =
997         "varying float v_varying;\n"
998         "mat4 f() { if (v_varying > 0.0) return mat4(1.0); }\n"
999         "void main() { gl_Position = vec4(f()[0][0], 0, 0, 1); }\n";
1000 
1001     const std::string fragmentShaderSource =
1002         "precision mediump float;\n"
1003         "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
1004 
1005     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1006     EXPECT_NE(0u, program);
1007 }
1008 
1009 // Verify that functions without return statements still compile
TEST_P(GLSLTest,MissingReturnStruct)1010 TEST_P(GLSLTest, MissingReturnStruct)
1011 {
1012     const std::string vertexShaderSource =
1013         "varying float v_varying;\n"
1014         "struct s { float a; int b; vec2 c; };\n"
1015         "s f() { if (v_varying > 0.0) return s(1.0, 1, vec2(1.0, 1.0)); }\n"
1016         "void main() { gl_Position = vec4(f().a, 0, 0, 1); }\n";
1017 
1018     const std::string fragmentShaderSource =
1019         "precision mediump float;\n"
1020         "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
1021 
1022     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1023     EXPECT_NE(0u, program);
1024 }
1025 
1026 // Verify that functions without return statements still compile
TEST_P(GLSLTest_ES3,MissingReturnArray)1027 TEST_P(GLSLTest_ES3, MissingReturnArray)
1028 {
1029     const std::string vertexShaderSource =
1030         "#version 300 es\n"
1031         "in float v_varying;\n"
1032         "vec2[2] f() { if (v_varying > 0.0) { return vec2[2](vec2(1.0, 1.0), vec2(1.0, 1.0)); } }\n"
1033         "void main() { gl_Position = vec4(f()[0].x, 0, 0, 1); }\n";
1034 
1035     const std::string fragmentShaderSource =
1036         "#version 300 es\n"
1037         "precision mediump float;\n"
1038         "out vec4 my_FragColor;\n"
1039         "void main() { my_FragColor = vec4(0, 0, 0, 1); }\n";
1040 
1041     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1042     EXPECT_NE(0u, program);
1043 }
1044 
1045 // Verify that functions without return statements still compile
TEST_P(GLSLTest_ES3,MissingReturnArrayOfStructs)1046 TEST_P(GLSLTest_ES3, MissingReturnArrayOfStructs)
1047 {
1048     const std::string vertexShaderSource =
1049         "#version 300 es\n"
1050         "in float v_varying;\n"
1051         "struct s { float a; int b; vec2 c; };\n"
1052         "s[2] f() { if (v_varying > 0.0) { return s[2](s(1.0, 1, vec2(1.0, 1.0)), s(1.0, 1, "
1053         "vec2(1.0, 1.0))); } }\n"
1054         "void main() { gl_Position = vec4(f()[0].a, 0, 0, 1); }\n";
1055 
1056     const std::string fragmentShaderSource =
1057         "#version 300 es\n"
1058         "precision mediump float;\n"
1059         "out vec4 my_FragColor;\n"
1060         "void main() { my_FragColor = vec4(0, 0, 0, 1); }\n";
1061 
1062     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1063     EXPECT_NE(0u, program);
1064 }
1065 
1066 // Verify that functions without return statements still compile
TEST_P(GLSLTest_ES3,MissingReturnStructOfArrays)1067 TEST_P(GLSLTest_ES3, MissingReturnStructOfArrays)
1068 {
1069     // TODO(cwallez) remove the suppression once NVIDIA removes the restriction for
1070     // GLSL >= 300. It was defined only in GLSL 2.0, section 6.1.
1071     if (IsNVIDIA() && IsOpenGLES())
1072     {
1073         std::cout << "Test skipped on NVIDIA OpenGL ES because it disallows returning "
1074                      "structure of arrays"
1075                   << std::endl;
1076         return;
1077     }
1078 
1079     const std::string vertexShaderSource =
1080         "#version 300 es\n"
1081         "in float v_varying;\n"
1082         "struct s { float a[2]; int b[2]; vec2 c[2]; };\n"
1083         "s f() { if (v_varying > 0.0) { return s(float[2](1.0, 1.0), int[2](1, 1),"
1084         "vec2[2](vec2(1.0, 1.0), vec2(1.0, 1.0))); } }\n"
1085         "void main() { gl_Position = vec4(f().a[0], 0, 0, 1); }\n";
1086 
1087     const std::string fragmentShaderSource =
1088         "#version 300 es\n"
1089         "precision mediump float;\n"
1090         "out vec4 my_FragColor;\n"
1091         "void main() { my_FragColor = vec4(0, 0, 0, 1); }\n";
1092 
1093     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1094     EXPECT_NE(0u, program);
1095 }
1096 
1097 // Verify that using invariant(all) in both shaders fails in ESSL 3.00.
TEST_P(GLSLTest_ES3,InvariantAllBoth)1098 TEST_P(GLSLTest_ES3, InvariantAllBoth)
1099 {
1100     const std::string fragmentShaderSource =
1101         "#version 300 es\n"
1102         "#pragma STDGL invariant(all)\n"
1103         "precision mediump float;\n"
1104         "in float v_varying;\n"
1105         "out vec4 my_FragColor;\n"
1106         "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1107 
1108     const std::string vertexShaderSource =
1109         "#version 300 es\n"
1110         "#pragma STDGL invariant(all)\n"
1111         "in vec4 a_position;\n"
1112         "out float v_varying;\n"
1113         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1114 
1115     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1116     EXPECT_EQ(0u, program);
1117 }
1118 
1119 // Verify that using invariant(all) only in fragment shader fails in ESSL 1.00.
TEST_P(GLSLTest,InvariantAllIn)1120 TEST_P(GLSLTest, InvariantAllIn)
1121 {
1122     const std::string fragmentShaderSource =
1123         "#pragma STDGL invariant(all)\n"
1124         "precision mediump float;\n"
1125         "varying float v_varying;\n"
1126         "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1127 
1128     const std::string vertexShaderSource =
1129         "attribute vec4 a_position;\n"
1130         "varying float v_varying;\n"
1131         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1132 
1133     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1134     EXPECT_EQ(0u, program);
1135 }
1136 
1137 // Verify that using invariant(all) only in fragment shader fails in ESSL 3.00.
TEST_P(GLSLTest_ES3,InvariantAllIn)1138 TEST_P(GLSLTest_ES3, InvariantAllIn)
1139 {
1140     const std::string fragmentShaderSource =
1141         "#version 300 es\n"
1142         "#pragma STDGL invariant(all)\n"
1143         "precision mediump float;\n"
1144         "in float v_varying;\n"
1145         "out vec4 my_FragColor;\n"
1146         "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1147 
1148     const std::string vertexShaderSource =
1149         "#version 300 es\n"
1150         "in vec4 a_position;\n"
1151         "out float v_varying;\n"
1152         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1153 
1154     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1155     EXPECT_EQ(0u, program);
1156 }
1157 
1158 // Verify that using invariant(all) only in vertex shader fails in ESSL 1.00.
TEST_P(GLSLTest,InvariantAllOut)1159 TEST_P(GLSLTest, InvariantAllOut)
1160 {
1161     const std::string fragmentShaderSource =
1162         "precision mediump float;\n"
1163         "varying float v_varying;\n"
1164         "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1165 
1166     const std::string vertexShaderSource =
1167         "#pragma STDGL invariant(all)\n"
1168         "attribute vec4 a_position;\n"
1169         "varying float v_varying;\n"
1170         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1171 
1172     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1173     EXPECT_EQ(0u, program);
1174 }
1175 
1176 // Verify that using invariant(all) only in vertex shader succeeds in ESSL 3.00.
TEST_P(GLSLTest_ES3,InvariantAllOut)1177 TEST_P(GLSLTest_ES3, InvariantAllOut)
1178 {
1179     // TODO: ESSL 3.00 -> GLSL 1.20 translation should add "invariant" in fragment shader
1180     // for varyings which are invariant in vertex shader,
1181     // because of invariant(all) being used in vertex shader (http://anglebug.com/1293)
1182     if (IsDesktopOpenGL())
1183     {
1184         std::cout << "Test disabled on OpenGL." << std::endl;
1185         return;
1186     }
1187 
1188     const std::string fragmentShaderSource =
1189         "#version 300 es\n"
1190         "precision mediump float;\n"
1191         "in float v_varying;\n"
1192         "out vec4 my_FragColor;\n"
1193         "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1194 
1195     const std::string vertexShaderSource =
1196         "#version 300 es\n"
1197         "#pragma STDGL invariant(all)\n"
1198         "in vec4 a_position;\n"
1199         "out float v_varying;\n"
1200         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1201 
1202     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1203     EXPECT_NE(0u, program);
1204 }
1205 
TEST_P(GLSLTest,MaxVaryingVec4)1206 TEST_P(GLSLTest, MaxVaryingVec4)
1207 {
1208 #if defined(__APPLE__)
1209     // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
1210     // (http://anglebug.com/1291)
1211     if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1212     {
1213         std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
1214         return;
1215     }
1216 #endif
1217 
1218     GLint maxVaryings = 0;
1219     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1220 
1221     VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, false, false, true);
1222 }
1223 
TEST_P(GLSLTest,MaxMinusTwoVaryingVec4PlusTwoSpecialVariables)1224 TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusTwoSpecialVariables)
1225 {
1226     GLint maxVaryings = 0;
1227     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1228 
1229     // Generate shader code that uses gl_FragCoord and gl_PointCoord, two special fragment shader variables.
1230     VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, false, true);
1231 }
1232 
TEST_P(GLSLTest,MaxMinusTwoVaryingVec4PlusThreeSpecialVariables)1233 TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusThreeSpecialVariables)
1234 {
1235     // TODO(geofflang): Figure out why this fails on OpenGL AMD (http://anglebug.com/1291)
1236     if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1237     {
1238         std::cout << "Test disabled on OpenGL." << std::endl;
1239         return;
1240     }
1241 
1242     GLint maxVaryings = 0;
1243     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1244 
1245     // Generate shader code that uses gl_FragCoord, gl_PointCoord and gl_PointSize.
1246     VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, true, true);
1247 }
1248 
1249 // Disabled because drivers are allowed to successfully compile shaders that have more than the
1250 // maximum number of varyings. (http://anglebug.com/1296)
TEST_P(GLSLTest,DISABLED_MaxVaryingVec4PlusFragCoord)1251 TEST_P(GLSLTest, DISABLED_MaxVaryingVec4PlusFragCoord)
1252 {
1253     GLint maxVaryings = 0;
1254     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1255 
1256     // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
1257     // This test should fail, since we are really using (maxVaryings + 1) varyings.
1258     VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, true, false, false, false);
1259 }
1260 
1261 // Disabled because drivers are allowed to successfully compile shaders that have more than the
1262 // maximum number of varyings. (http://anglebug.com/1296)
TEST_P(GLSLTest,DISABLED_MaxVaryingVec4PlusPointCoord)1263 TEST_P(GLSLTest, DISABLED_MaxVaryingVec4PlusPointCoord)
1264 {
1265     GLint maxVaryings = 0;
1266     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1267 
1268     // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
1269     // This test should fail, since we are really using (maxVaryings + 1) varyings.
1270     VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, true, false, false);
1271 }
1272 
TEST_P(GLSLTest,MaxVaryingVec3)1273 TEST_P(GLSLTest, MaxVaryingVec3)
1274 {
1275     GLint maxVaryings = 0;
1276     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1277 
1278     VaryingTestBase(0, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
1279 }
1280 
TEST_P(GLSLTest,MaxVaryingVec3Array)1281 TEST_P(GLSLTest, MaxVaryingVec3Array)
1282 {
1283     GLint maxVaryings = 0;
1284     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1285 
1286     VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
1287 }
1288 
1289 // Disabled because of a failure in D3D9
TEST_P(GLSLTest,MaxVaryingVec3AndOneFloat)1290 TEST_P(GLSLTest, MaxVaryingVec3AndOneFloat)
1291 {
1292     if (IsD3D9())
1293     {
1294         std::cout << "Test disabled on D3D9." << std::endl;
1295         return;
1296     }
1297 
1298     GLint maxVaryings = 0;
1299     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1300 
1301     VaryingTestBase(1, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
1302 }
1303 
1304 // Disabled because of a failure in D3D9
TEST_P(GLSLTest,MaxVaryingVec3ArrayAndOneFloatArray)1305 TEST_P(GLSLTest, MaxVaryingVec3ArrayAndOneFloatArray)
1306 {
1307     if (IsD3D9())
1308     {
1309         std::cout << "Test disabled on D3D9." << std::endl;
1310         return;
1311     }
1312 
1313     GLint maxVaryings = 0;
1314     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1315 
1316     VaryingTestBase(0, 1, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
1317 }
1318 
1319 // Disabled because of a failure in D3D9
TEST_P(GLSLTest,TwiceMaxVaryingVec2)1320 TEST_P(GLSLTest, TwiceMaxVaryingVec2)
1321 {
1322     if (IsD3D9())
1323     {
1324         std::cout << "Test disabled on D3D9." << std::endl;
1325         return;
1326     }
1327 
1328     if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1329     {
1330         // TODO(geofflang): Figure out why this fails on NVIDIA's GLES driver
1331         std::cout << "Test disabled on OpenGL ES." << std::endl;
1332         return;
1333     }
1334 
1335 #if defined(__APPLE__)
1336     // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
1337     // (http://anglebug.com/1291)
1338     if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1339     {
1340         std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
1341         return;
1342     }
1343 #endif
1344 
1345     GLint maxVaryings = 0;
1346     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1347 
1348     VaryingTestBase(0, 0, 2 * maxVaryings, 0, 0, 0, 0, 0, false, false, false, true);
1349 }
1350 
1351 // Disabled because of a failure in D3D9
TEST_P(GLSLTest,MaxVaryingVec2Arrays)1352 TEST_P(GLSLTest, MaxVaryingVec2Arrays)
1353 {
1354     if (IsD3DSM3())
1355     {
1356         std::cout << "Test disabled on SM3." << std::endl;
1357         return;
1358     }
1359 
1360     if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1361     {
1362         // TODO(geofflang): Figure out why this fails on NVIDIA's GLES driver
1363         std::cout << "Test disabled on OpenGL ES." << std::endl;
1364         return;
1365     }
1366 
1367 #if defined(__APPLE__)
1368     // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
1369     // (http://anglebug.com/1291)
1370     if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
1371     {
1372         std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
1373         return;
1374     }
1375 #endif
1376 
1377     GLint maxVaryings = 0;
1378     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1379 
1380     VaryingTestBase(0, 0, 0, maxVaryings, 0, 0, 0, 0, false, false, false, true);
1381 }
1382 
1383 // Disabled because drivers are allowed to successfully compile shaders that have more than the
1384 // maximum number of varyings. (http://anglebug.com/1296)
TEST_P(GLSLTest,DISABLED_MaxPlusOneVaryingVec3)1385 TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec3)
1386 {
1387     GLint maxVaryings = 0;
1388     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1389 
1390     VaryingTestBase(0, 0, 0, 0, maxVaryings + 1, 0, 0, 0, false, false, false, false);
1391 }
1392 
1393 // Disabled because drivers are allowed to successfully compile shaders that have more than the
1394 // maximum number of varyings. (http://anglebug.com/1296)
TEST_P(GLSLTest,DISABLED_MaxPlusOneVaryingVec3Array)1395 TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec3Array)
1396 {
1397     GLint maxVaryings = 0;
1398     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1399 
1400     VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2 + 1, 0, 0, false, false, false, false);
1401 }
1402 
1403 // Disabled because drivers are allowed to successfully compile shaders that have more than the
1404 // maximum number of varyings. (http://anglebug.com/1296)
TEST_P(GLSLTest,DISABLED_MaxVaryingVec3AndOneVec2)1405 TEST_P(GLSLTest, DISABLED_MaxVaryingVec3AndOneVec2)
1406 {
1407     GLint maxVaryings = 0;
1408     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1409 
1410     VaryingTestBase(0, 0, 1, 0, maxVaryings, 0, 0, 0, false, false, false, false);
1411 }
1412 
1413 // Disabled because drivers are allowed to successfully compile shaders that have more than the
1414 // maximum number of varyings. (http://anglebug.com/1296)
TEST_P(GLSLTest,DISABLED_MaxPlusOneVaryingVec2)1415 TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec2)
1416 {
1417     GLint maxVaryings = 0;
1418     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1419 
1420     VaryingTestBase(0, 0, 2 * maxVaryings + 1, 0, 0, 0, 0, 0, false, false, false, false);
1421 }
1422 
1423 // Disabled because drivers are allowed to successfully compile shaders that have more than the
1424 // maximum number of varyings. (http://anglebug.com/1296)
TEST_P(GLSLTest,DISABLED_MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)1425 TEST_P(GLSLTest, DISABLED_MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
1426 {
1427     GLint maxVaryings = 0;
1428     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1429 
1430     VaryingTestBase(0, maxVaryings / 2 + 1, 0, 0, 0, 0, 0, maxVaryings / 2, false, false, false, false);
1431 }
1432 
1433 // Verify shader source with a fixed length that is less than the null-terminated length will compile.
TEST_P(GLSLTest,FixedShaderLength)1434 TEST_P(GLSLTest, FixedShaderLength)
1435 {
1436     GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1437 
1438     const std::string appendGarbage = "abcasdfasdfasdfasdfasdf";
1439     const std::string source = "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" + appendGarbage;
1440     const char *sourceArray[1] = { source.c_str() };
1441     GLint lengths[1] = { static_cast<GLint>(source.length() - appendGarbage.length()) };
1442     glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
1443     glCompileShader(shader);
1444 
1445     GLint compileResult;
1446     glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1447     EXPECT_NE(compileResult, 0);
1448 }
1449 
1450 // Verify that a negative shader source length is treated as a null-terminated length.
TEST_P(GLSLTest,NegativeShaderLength)1451 TEST_P(GLSLTest, NegativeShaderLength)
1452 {
1453     GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1454 
1455     const char *sourceArray[1] = { "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" };
1456     GLint lengths[1] = { -10 };
1457     glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
1458     glCompileShader(shader);
1459 
1460     GLint compileResult;
1461     glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1462     EXPECT_NE(compileResult, 0);
1463 }
1464 
1465 // Check that having an invalid char after the "." doesn't cause an assert.
TEST_P(GLSLTest,InvalidFieldFirstChar)1466 TEST_P(GLSLTest, InvalidFieldFirstChar)
1467 {
1468     GLuint shader      = glCreateShader(GL_VERTEX_SHADER);
1469     const char *source = "void main() {vec4 x; x.}";
1470     glShaderSource(shader, 1, &source, 0);
1471     glCompileShader(shader);
1472 
1473     GLint compileResult;
1474     glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1475     EXPECT_EQ(0, compileResult);
1476 }
1477 
1478 // Verify that a length array with mixed positive and negative values compiles.
TEST_P(GLSLTest,MixedShaderLengths)1479 TEST_P(GLSLTest, MixedShaderLengths)
1480 {
1481     GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1482 
1483     const char *sourceArray[] =
1484     {
1485         "void main()",
1486         "{",
1487         "    gl_FragColor = vec4(0, 0, 0, 0);",
1488         "}",
1489     };
1490     GLint lengths[] =
1491     {
1492         -10,
1493         1,
1494         static_cast<GLint>(strlen(sourceArray[2])),
1495         -1,
1496     };
1497     ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
1498 
1499     glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
1500     glCompileShader(shader);
1501 
1502     GLint compileResult;
1503     glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1504     EXPECT_NE(compileResult, 0);
1505 }
1506 
1507 // Verify that zero-length shader source does not affect shader compilation.
TEST_P(GLSLTest,ZeroShaderLength)1508 TEST_P(GLSLTest, ZeroShaderLength)
1509 {
1510     GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1511 
1512     const char *sourceArray[] =
1513     {
1514         "adfasdf",
1515         "34534",
1516         "void main() { gl_FragColor = vec4(0, 0, 0, 0); }",
1517         "",
1518         "asdfasdfsdsdf",
1519     };
1520     GLint lengths[] =
1521     {
1522         0,
1523         0,
1524         -1,
1525         0,
1526         0,
1527     };
1528     ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
1529 
1530     glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
1531     glCompileShader(shader);
1532 
1533     GLint compileResult;
1534     glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1535     EXPECT_NE(compileResult, 0);
1536 }
1537 
1538 // Tests that bad index expressions don't crash ANGLE's translator.
1539 // https://code.google.com/p/angleproject/issues/detail?id=857
TEST_P(GLSLTest,BadIndexBug)1540 TEST_P(GLSLTest, BadIndexBug)
1541 {
1542     const std::string &fragmentShaderSourceVec =
1543         "precision mediump float;\n"
1544         "uniform vec4 uniformVec;\n"
1545         "void main()\n"
1546         "{\n"
1547         "    gl_FragColor = vec4(uniformVec[int()]);\n"
1548         "}";
1549 
1550     GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceVec);
1551     EXPECT_EQ(0u, shader);
1552 
1553     if (shader != 0)
1554     {
1555         glDeleteShader(shader);
1556     }
1557 
1558     const std::string &fragmentShaderSourceMat =
1559         "precision mediump float;\n"
1560         "uniform mat4 uniformMat;\n"
1561         "void main()\n"
1562         "{\n"
1563         "    gl_FragColor = vec4(uniformMat[int()]);\n"
1564         "}";
1565 
1566     shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceMat);
1567     EXPECT_EQ(0u, shader);
1568 
1569     if (shader != 0)
1570     {
1571         glDeleteShader(shader);
1572     }
1573 
1574     const std::string &fragmentShaderSourceArray =
1575         "precision mediump float;\n"
1576         "uniform vec4 uniformArray;\n"
1577         "void main()\n"
1578         "{\n"
1579         "    gl_FragColor = vec4(uniformArray[int()]);\n"
1580         "}";
1581 
1582     shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceArray);
1583     EXPECT_EQ(0u, shader);
1584 
1585     if (shader != 0)
1586     {
1587         glDeleteShader(shader);
1588     }
1589 }
1590 
1591 // Test that structs defined in uniforms are translated correctly.
TEST_P(GLSLTest,StructSpecifiersUniforms)1592 TEST_P(GLSLTest, StructSpecifiersUniforms)
1593 {
1594     const std::string fragmentShaderSource = SHADER_SOURCE
1595     (
1596         precision mediump float;
1597 
1598         uniform struct S { float field;} s;
1599 
1600         void main()
1601         {
1602             gl_FragColor = vec4(1, 0, 0, 1);
1603             gl_FragColor.a += s.field;
1604         }
1605     );
1606 
1607     GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1608     EXPECT_NE(0u, program);
1609 }
1610 
1611 // Test that gl_DepthRange is not stored as a uniform location. Since uniforms
1612 // beginning with "gl_" are filtered out by our validation logic, we must
1613 // bypass the validation to test the behaviour of the implementation.
1614 // (note this test is still Impl-independent)
TEST_P(GLSLTest,DepthRangeUniforms)1615 TEST_P(GLSLTest, DepthRangeUniforms)
1616 {
1617     const std::string fragmentShaderSource = SHADER_SOURCE
1618     (
1619         precision mediump float;
1620 
1621         void main()
1622         {
1623             gl_FragColor = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff, 1);
1624         }
1625     );
1626 
1627     GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1628     EXPECT_NE(0u, program);
1629 
1630     // dive into the ANGLE internals, so we can bypass validation.
1631     gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
1632     gl::Program *glProgram = context->getProgram(program);
1633     GLint nearIndex = glProgram->getUniformLocation("gl_DepthRange.near");
1634     EXPECT_EQ(-1, nearIndex);
1635 
1636     // Test drawing does not throw an exception.
1637     drawQuad(program, "inputAttribute", 0.5f);
1638 
1639     EXPECT_GL_NO_ERROR();
1640 
1641     glDeleteProgram(program);
1642 }
1643 
GenerateSmallPowShader(double base,double exponent)1644 std::string GenerateSmallPowShader(double base, double exponent)
1645 {
1646     std::stringstream stream;
1647 
1648     stream.precision(8);
1649 
1650     double result = pow(base, exponent);
1651 
1652     stream << "precision highp float;\n"
1653            << "float fun(float arg)\n"
1654            << "{\n"
1655            << "    return pow(arg, " << std::fixed << exponent << ");\n"
1656            << "}\n"
1657            << "\n"
1658            << "void main()\n"
1659            << "{\n"
1660            << "    const float a = " << std::scientific << base << ";\n"
1661            << "    float b = fun(a);\n"
1662            << "    if (abs(" << result << " - b) < " << std::abs(result * 0.001) << ")\n"
1663            << "    {\n"
1664            << "        gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
1665            << "    }\n"
1666            << "    else\n"
1667            << "    {\n"
1668            << "        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
1669            << "    }\n"
1670            << "}\n";
1671 
1672     return stream.str();
1673 }
1674 
1675 // Covers the WebGL test 'glsl/bugs/pow-of-small-constant-in-user-defined-function'
1676 // See http://anglebug.com/851
TEST_P(GLSLTest,PowOfSmallConstant)1677 TEST_P(GLSLTest, PowOfSmallConstant)
1678 {
1679     std::vector<double> bads;
1680     for (int eps = -1; eps <= 1; ++eps)
1681     {
1682         for (int i = -4; i <= 5; ++i)
1683         {
1684             if (i >= -1 && i <= 1)
1685                 continue;
1686             const double epsilon = 1.0e-8;
1687             double bad           = static_cast<double>(i) + static_cast<double>(eps) * epsilon;
1688             bads.push_back(bad);
1689         }
1690     }
1691 
1692     for (double bad : bads)
1693     {
1694         const std::string &fragmentShaderSource = GenerateSmallPowShader(1.0e-6, bad);
1695 
1696         ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShaderSource);
1697 
1698         drawQuad(program.get(), "inputAttribute", 0.5f);
1699 
1700         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1701         EXPECT_GL_NO_ERROR();
1702     }
1703 }
1704 
1705 // Test that fragment shaders which contain non-constant loop indexers and compiled for FL9_3 and
1706 // below
1707 // fail with a specific error message.
1708 // Additionally test that the same fragment shader compiles successfully with feature levels greater
1709 // than FL9_3.
TEST_P(GLSLTest,LoopIndexingValidation)1710 TEST_P(GLSLTest, LoopIndexingValidation)
1711 {
1712     const std::string fragmentShaderSource = SHADER_SOURCE
1713     (
1714         precision mediump float;
1715 
1716         uniform float loopMax;
1717 
1718         void main()
1719         {
1720             gl_FragColor = vec4(1, 0, 0, 1);
1721             for (float l = 0.0; l < loopMax; l++)
1722             {
1723                 if (loopMax > 3.0)
1724                 {
1725                     gl_FragColor.a += 0.1;
1726                 }
1727             }
1728         }
1729     );
1730 
1731     GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1732 
1733     const char *sourceArray[1] = {fragmentShaderSource.c_str()};
1734     glShaderSource(shader, 1, sourceArray, nullptr);
1735     glCompileShader(shader);
1736 
1737     GLint compileResult;
1738     glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1739 
1740     // If the test is configured to run limited to Feature Level 9_3, then it is
1741     // assumed that shader compilation will fail with an expected error message containing
1742     // "Loop index cannot be compared with non-constant expression"
1743     if ((GetParam() == ES2_D3D11_FL9_3() || GetParam() == ES2_D3D9()))
1744     {
1745         if (compileResult != 0)
1746         {
1747             FAIL() << "Shader compilation succeeded, expected failure";
1748         }
1749         else
1750         {
1751             GLint infoLogLength;
1752             glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
1753 
1754             std::string infoLog;
1755             infoLog.resize(infoLogLength);
1756             glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
1757 
1758             if (infoLog.find("Loop index cannot be compared with non-constant expression") ==
1759                 std::string::npos)
1760             {
1761                 FAIL() << "Shader compilation failed with unexpected error message";
1762             }
1763         }
1764     }
1765     else
1766     {
1767         EXPECT_NE(0, compileResult);
1768     }
1769 
1770     if (shader != 0)
1771     {
1772         glDeleteShader(shader);
1773     }
1774 }
1775 
1776 // Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1777 // can actually be used.
TEST_P(GLSLTest,VerifyMaxVertexUniformVectors)1778 TEST_P(GLSLTest, VerifyMaxVertexUniformVectors)
1779 {
1780     int maxUniforms = 10000;
1781     glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1782     EXPECT_GL_NO_ERROR();
1783     std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl;
1784 
1785     CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, 0, 0, true);
1786 }
1787 
1788 // Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1789 // can actually be used along with the maximum number of texture samplers.
TEST_P(GLSLTest,VerifyMaxVertexUniformVectorsWithSamplers)1790 TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsWithSamplers)
1791 {
1792     if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1793         GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1794     {
1795         std::cout << "Test disabled on OpenGL." << std::endl;
1796         return;
1797     }
1798 
1799     int maxUniforms = 10000;
1800     glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1801     EXPECT_GL_NO_ERROR();
1802     std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl;
1803 
1804     int maxTextureImageUnits = 0;
1805     glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
1806 
1807     CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, maxTextureImageUnits, 0, true);
1808 }
1809 
1810 // Tests that the maximum uniforms count + 1 from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1811 // fails shader compilation.
TEST_P(GLSLTest,VerifyMaxVertexUniformVectorsExceeded)1812 TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsExceeded)
1813 {
1814     int maxUniforms = 10000;
1815     glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1816     EXPECT_GL_NO_ERROR();
1817     std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS + 1 = " << maxUniforms + 1 << std::endl;
1818 
1819     CompileGLSLWithUniformsAndSamplers(maxUniforms + 1, 0, 0, 0, false);
1820 }
1821 
1822 // Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1823 // can actually be used.
TEST_P(GLSLTest,VerifyMaxFragmentUniformVectors)1824 TEST_P(GLSLTest, VerifyMaxFragmentUniformVectors)
1825 {
1826     int maxUniforms = 10000;
1827     glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1828     EXPECT_GL_NO_ERROR();
1829     std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS = " << maxUniforms << std::endl;
1830 
1831     CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, 0, true);
1832 }
1833 
1834 // Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1835 // can actually be used along with the maximum number of texture samplers.
TEST_P(GLSLTest,VerifyMaxFragmentUniformVectorsWithSamplers)1836 TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsWithSamplers)
1837 {
1838     if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1839         GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1840     {
1841         std::cout << "Test disabled on OpenGL." << std::endl;
1842         return;
1843     }
1844 
1845     int maxUniforms = 10000;
1846     glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1847     EXPECT_GL_NO_ERROR();
1848 
1849     int maxTextureImageUnits = 0;
1850     glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
1851 
1852     CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, maxTextureImageUnits, true);
1853 }
1854 
1855 // Tests that the maximum uniforms count + 1 from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1856 // fails shader compilation.
TEST_P(GLSLTest,VerifyMaxFragmentUniformVectorsExceeded)1857 TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsExceeded)
1858 {
1859     int maxUniforms = 10000;
1860     glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1861     EXPECT_GL_NO_ERROR();
1862     std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS + 1 = " << maxUniforms + 1
1863               << std::endl;
1864 
1865     CompileGLSLWithUniformsAndSamplers(0, maxUniforms + 1, 0, 0, false);
1866 }
1867 
1868 // Test that two constructors which have vec4 and mat2 parameters get disambiguated (issue in
1869 // HLSL).
TEST_P(GLSLTest_ES3,AmbiguousConstructorCall2x2)1870 TEST_P(GLSLTest_ES3, AmbiguousConstructorCall2x2)
1871 {
1872     const std::string fragmentShaderSource =
1873         "#version 300 es\n"
1874         "precision highp float;\n"
1875         "out vec4 my_FragColor;\n"
1876         "void main()\n"
1877         "{\n"
1878         "    my_FragColor = vec4(0.0);\n"
1879         "}";
1880 
1881     const std::string vertexShaderSource =
1882         "#version 300 es\n"
1883         "precision highp float;\n"
1884         "in vec4 a_vec;\n"
1885         "in mat2 a_mat;\n"
1886         "void main()\n"
1887         "{\n"
1888         "    gl_Position = vec4(a_vec) + vec4(a_mat);\n"
1889         "}";
1890 
1891     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1892     EXPECT_NE(0u, program);
1893 }
1894 
1895 // Test that two constructors which have mat2x3 and mat3x2 parameters get disambiguated.
1896 // This was suspected to be an issue in HLSL, but HLSL seems to be able to natively choose between
1897 // the function signatures in this case.
TEST_P(GLSLTest_ES3,AmbiguousConstructorCall2x3)1898 TEST_P(GLSLTest_ES3, AmbiguousConstructorCall2x3)
1899 {
1900     const std::string fragmentShaderSource =
1901         "#version 300 es\n"
1902         "precision highp float;\n"
1903         "out vec4 my_FragColor;\n"
1904         "void main()\n"
1905         "{\n"
1906         "    my_FragColor = vec4(0.0);\n"
1907         "}";
1908 
1909     const std::string vertexShaderSource =
1910         "#version 300 es\n"
1911         "precision highp float;\n"
1912         "in mat3x2 a_matA;\n"
1913         "in mat2x3 a_matB;\n"
1914         "void main()\n"
1915         "{\n"
1916         "    gl_Position = vec4(a_matA) + vec4(a_matB);\n"
1917         "}";
1918 
1919     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1920     EXPECT_NE(0u, program);
1921 }
1922 
1923 // Test that two functions which have vec4 and mat2 parameters get disambiguated (issue in HLSL).
TEST_P(GLSLTest_ES3,AmbiguousFunctionCall2x2)1924 TEST_P(GLSLTest_ES3, AmbiguousFunctionCall2x2)
1925 {
1926     const std::string fragmentShaderSource =
1927         "#version 300 es\n"
1928         "precision highp float;\n"
1929         "out vec4 my_FragColor;\n"
1930         "void main()\n"
1931         "{\n"
1932         "    my_FragColor = vec4(0.0);\n"
1933         "}";
1934 
1935     const std::string vertexShaderSource =
1936         "#version 300 es\n"
1937         "precision highp float;\n"
1938         "in vec4 a_vec;\n"
1939         "in mat2 a_mat;\n"
1940         "vec4 foo(vec4 a)\n"
1941         "{\n"
1942         "    return a;\n"
1943         "}\n"
1944         "vec4 foo(mat2 a)\n"
1945         "{\n"
1946         "    return vec4(a[0][0]);\n"
1947         "}\n"
1948         "void main()\n"
1949         "{\n"
1950         "    gl_Position = foo(a_vec) + foo(a_mat);\n"
1951         "}";
1952 
1953     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1954     EXPECT_NE(0u, program);
1955 }
1956 
1957 // Test that an user-defined function with a large number of float4 parameters doesn't fail due to
1958 // the function name being too long.
TEST_P(GLSLTest_ES3,LargeNumberOfFloat4Parameters)1959 TEST_P(GLSLTest_ES3, LargeNumberOfFloat4Parameters)
1960 {
1961     const std::string fragmentShaderSource =
1962         "#version 300 es\n"
1963         "precision highp float;\n"
1964         "out vec4 my_FragColor;\n"
1965         "void main()\n"
1966         "{\n"
1967         "    my_FragColor = vec4(0.0);\n"
1968         "}";
1969 
1970     std::stringstream vertexShaderStream;
1971     const unsigned int paramCount = 1024u;
1972 
1973     vertexShaderStream << "#version 300 es\n"
1974                           "precision highp float;\n"
1975                           "in vec4 a_vec;\n"
1976                           "vec4 lotsOfVec4Parameters(";
1977     for (unsigned int i = 0; i < paramCount; ++i)
1978     {
1979         vertexShaderStream << "vec4 a" << i << ", ";
1980     }
1981     vertexShaderStream << "vec4 aLast)\n"
1982                           "{\n"
1983                           "    return ";
1984     for (unsigned int i = 0; i < paramCount; ++i)
1985     {
1986         vertexShaderStream << "a" << i << " + ";
1987     }
1988     vertexShaderStream << "aLast;\n"
1989                           "}\n"
1990                           "void main()\n"
1991                           "{\n"
1992                           "    gl_Position = lotsOfVec4Parameters(";
1993     for (unsigned int i = 0; i < paramCount; ++i)
1994     {
1995         vertexShaderStream << "a_vec, ";
1996     }
1997     vertexShaderStream << "a_vec);\n"
1998                           "}";
1999 
2000     GLuint program = CompileProgram(vertexShaderStream.str(), fragmentShaderSource);
2001     EXPECT_NE(0u, program);
2002 }
2003 
2004 // This test was written specifically to stress DeferGlobalInitializers AST transformation.
2005 // Test a shader where a global constant array is initialized with an expression containing array
2006 // indexing. This initializer is tricky to constant fold, so if it's not constant folded it needs to
2007 // be handled in a way that doesn't generate statements in the global scope in HLSL output.
2008 // Also includes multiple array initializers in one declaration, where only the second one has
2009 // array indexing. This makes sure that the qualifier for the declaration is set correctly if
2010 // transformations are applied to the declaration also in the case of ESSL output.
TEST_P(GLSLTest_ES3,InitGlobalArrayWithArrayIndexing)2011 TEST_P(GLSLTest_ES3, InitGlobalArrayWithArrayIndexing)
2012 {
2013     // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1428 is fixed
2014     if (IsAndroid() && IsAdreno() && IsOpenGLES())
2015     {
2016         std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
2017         return;
2018     }
2019 
2020     const std::string vertexShaderSource =
2021         "#version 300 es\n"
2022         "precision highp float;\n"
2023         "in vec4 a_vec;\n"
2024         "void main()\n"
2025         "{\n"
2026         "    gl_Position = vec4(a_vec);\n"
2027         "}";
2028 
2029     const std::string fragmentShaderSource =
2030         "#version 300 es\n"
2031         "precision highp float;\n"
2032         "out vec4 my_FragColor;\n"
2033         "const highp float f[2] = float[2](0.1, 0.2);\n"
2034         "const highp float[2] g = float[2](0.3, 0.4), h = float[2](0.5, f[1]);\n"
2035         "void main()\n"
2036         "{\n"
2037         "    my_FragColor = vec4(h[1]);\n"
2038         "}";
2039 
2040     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
2041     EXPECT_NE(0u, program);
2042 }
2043 
2044 // Test that index-constant sampler array indexing is supported.
TEST_P(GLSLTest,IndexConstantSamplerArrayIndexing)2045 TEST_P(GLSLTest, IndexConstantSamplerArrayIndexing)
2046 {
2047     if (IsD3D11_FL93()) {
2048         std::cout << "Test skipped on D3D11 FL 9.3." << std::endl;
2049         return;
2050     }
2051 
2052     const std::string vertexShaderSource =
2053         "attribute vec4 vPosition;\n"
2054         "void main()\n"
2055         "{\n"
2056         "      gl_Position = vPosition;\n"
2057         "}";
2058 
2059     const std::string fragmentShaderSource =
2060         "precision mediump float;\n"
2061         "uniform sampler2D uni[2];\n"
2062         "\n"
2063         "float zero(int x)\n"
2064         "{\n"
2065         "    return float(x) - float(x);\n"
2066         "}\n"
2067         "\n"
2068         "void main()\n"
2069         "{\n"
2070         "    vec4 c = vec4(0,0,0,0);\n"
2071         "    for (int ii = 1; ii < 3; ++ii) {\n"
2072         "        if (c.x > 255.0) {\n"
2073         "            c.x = 255.0 + zero(ii);\n"
2074         "            break;\n"
2075         "        }\n"
2076         // Index the sampler array with a predictable loop index (index-constant) as opposed to
2077         // a true constant. This is valid in OpenGL ES but isn't in many Desktop OpenGL versions,
2078         // without an extension.
2079         "        c += texture2D(uni[ii - 1], vec2(0.5, 0.5));\n"
2080         "    }\n"
2081         "    gl_FragColor = c;\n"
2082         "}";
2083 
2084     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
2085     EXPECT_NE(0u, program);
2086 }
2087 
2088 // Test that the #pragma directive is supported and doesn't trigger a compilation failure on the
2089 // native driver. The only pragma that gets passed to the OpenGL driver is "invariant" but we don't
2090 // want to test its behavior, so don't use any varyings.
TEST_P(GLSLTest,PragmaDirective)2091 TEST_P(GLSLTest, PragmaDirective)
2092 {
2093     const std::string vertexShaderSource =
2094         "#pragma STDGL invariant(all)\n"
2095         "void main()\n"
2096         "{\n"
2097         "    gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
2098         "}\n";
2099 
2100     const std::string fragmentShaderSource =
2101         "precision mediump float;\n"
2102         "void main()\n"
2103         "{\n"
2104         "    gl_FragColor = vec4(1.0);\n"
2105         "}\n";
2106 
2107     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
2108     EXPECT_NE(0u, program);
2109 }
2110 
2111 // Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9).
2112 // The function call that returns the array needs to be evaluated after ++j for the expression to
2113 // return the correct value (true).
TEST_P(GLSLTest_ES3,SequenceOperatorEvaluationOrderArray)2114 TEST_P(GLSLTest_ES3, SequenceOperatorEvaluationOrderArray)
2115 {
2116     const std::string &fragmentShaderSource =
2117         "#version 300 es\n"
2118         "precision mediump float;\n"
2119         "out vec4 my_FragColor; \n"
2120         "int[2] func(int param) {\n"
2121         "    return int[2](param, param);\n"
2122         "}\n"
2123         "void main() {\n"
2124         "    int a[2]; \n"
2125         "    for (int i = 0; i < 2; ++i) {\n"
2126         "        a[i] = 1;\n"
2127         "    }\n"
2128         "    int j = 0; \n"
2129         "    bool result = ((++j), (a == func(j)));\n"
2130         "    my_FragColor = vec4(0.0, (result ? 1.0 : 0.0), 0.0, 1.0);\n"
2131         "}\n";
2132 
2133     GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
2134     ASSERT_NE(0u, program);
2135 
2136     drawQuad(program, "inputAttribute", 0.5f);
2137 
2138     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2139 }
2140 
2141 // Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9).
2142 // The short-circuiting expression needs to be evaluated after ++j for the expression to return the
2143 // correct value (true).
TEST_P(GLSLTest_ES3,SequenceOperatorEvaluationOrderShortCircuit)2144 TEST_P(GLSLTest_ES3, SequenceOperatorEvaluationOrderShortCircuit)
2145 {
2146     const std::string &fragmentShaderSource =
2147         "#version 300 es\n"
2148         "precision mediump float;\n"
2149         "out vec4 my_FragColor; \n"
2150         "void main() {\n"
2151         "    int j = 0; \n"
2152         "    bool result = ((++j), (j == 1 ? true : (++j == 3)));\n"
2153         "    my_FragColor = vec4(0.0, ((result && j == 1) ? 1.0 : 0.0), 0.0, 1.0);\n"
2154         "}\n";
2155 
2156     GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
2157     ASSERT_NE(0u, program);
2158 
2159     drawQuad(program, "inputAttribute", 0.5f);
2160 
2161     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2162 }
2163 
2164 // Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9).
2165 // Indexing the vector needs to be evaluated after func() for the right result.
TEST_P(GLSLTest_ES3,SequenceOperatorEvaluationOrderDynamicVectorIndexingInLValue)2166 TEST_P(GLSLTest_ES3, SequenceOperatorEvaluationOrderDynamicVectorIndexingInLValue)
2167 {
2168     const std::string &fragmentShaderSource =
2169         "#version 300 es\n"
2170         "precision mediump float;\n"
2171         "out vec4 my_FragColor;\n"
2172         "uniform int u_zero;\n"
2173         "int sideEffectCount = 0;\n"
2174         "float func() {\n"
2175         "    ++sideEffectCount;\n"
2176         "    return -1.0;\n"
2177         "}\n"
2178         "void main() {\n"
2179         "    vec4 v = vec4(0.0, 2.0, 4.0, 6.0); \n"
2180         "    float f = (func(), (++v[u_zero + sideEffectCount]));\n"
2181         "    bool green = abs(f - 3.0) < 0.01 && abs(v[1] - 3.0) < 0.01 && sideEffectCount == 1;\n"
2182         "    my_FragColor = vec4(0.0, (green ? 1.0 : 0.0), 0.0, 1.0);\n"
2183         "}\n";
2184 
2185     GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
2186     ASSERT_NE(0u, program);
2187 
2188     drawQuad(program, "inputAttribute", 0.5f);
2189 
2190     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2191 }
2192 
2193 // Test that using gl_PointCoord with GL_TRIANGLES doesn't produce a link error.
2194 // From WebGL test conformance/rendering/point-specific-shader-variables.html
2195 // See http://anglebug.com/1380
TEST_P(GLSLTest,RenderTrisWithPointCoord)2196 TEST_P(GLSLTest, RenderTrisWithPointCoord)
2197 {
2198     const std::string &vert =
2199         "attribute vec2 aPosition;\n"
2200         "void main()\n"
2201         "{\n"
2202         "    gl_Position = vec4(aPosition, 0, 1);\n"
2203         "    gl_PointSize = 1.0;\n"
2204         "}";
2205     const std::string &frag =
2206         "void main()\n"
2207         "{\n"
2208         "    gl_FragColor = vec4(gl_PointCoord.xy, 0, 1);\n"
2209         "    gl_FragColor = vec4(0, 1, 0, 1);\n"
2210         "}";
2211 
2212     ANGLE_GL_PROGRAM(prog, vert, frag);
2213     drawQuad(prog.get(), "aPosition", 0.5f);
2214     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2215 }
2216 
2217 // Convers a bug with the integer pow statement workaround.
TEST_P(GLSLTest,NestedPowStatements)2218 TEST_P(GLSLTest, NestedPowStatements)
2219 {
2220     const std::string &vert =
2221         "attribute vec2 position;\n"
2222         "void main()\n"
2223         "{\n"
2224         "    gl_Position = vec4(position, 0, 1);\n"
2225         "}";
2226     const std::string &frag =
2227         "precision mediump float;\n"
2228         "float func(float v)\n"
2229         "{\n"
2230         "   float f1 = pow(v, 2.0);\n"
2231         "   return pow(f1 + v, 2.0);\n"
2232         "}\n"
2233         "void main()\n"
2234         "{\n"
2235         "    float v = func(2.0);\n"
2236         "    gl_FragColor = abs(v - 36.0) < 0.001 ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n"
2237         "}";
2238 
2239     ANGLE_GL_PROGRAM(prog, vert, frag);
2240     drawQuad(prog.get(), "position", 0.5f);
2241     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2242 }
2243 
2244 // Convers a bug with the unary minus operator on signed integer workaround.
TEST_P(GLSLTest_ES3,UnaryMinusOperatorSignedInt)2245 TEST_P(GLSLTest_ES3, UnaryMinusOperatorSignedInt)
2246 {
2247     const std::string &vert =
2248         "#version 300 es\n"
2249         "in highp vec4 position;\n"
2250         "out mediump vec4 v_color;\n"
2251         "uniform int ui_one;\n"
2252         "uniform int ui_two;\n"
2253         "uniform int ui_three;\n"
2254         "void main() {\n"
2255         "    int s[3];\n"
2256         "    s[0] = ui_one;\n"
2257         "    s[1] = -(-(-ui_two + 1) + 1);\n"  // s[1] = -ui_two
2258         "    s[2] = ui_three;\n"
2259         "    int result = 0;\n"
2260         "    for (int i = 0; i < ui_three; i++) {\n"
2261         "        result += s[i];\n"
2262         "    }\n"
2263         "    v_color = (result == 2) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n"
2264         "    gl_Position = position;\n"
2265         "}\n";
2266     const std::string &frag =
2267         "#version 300 es\n"
2268         "in mediump vec4 v_color;\n"
2269         "layout(location=0) out mediump vec4 o_color;\n"
2270         "void main() {\n"
2271         "    o_color = v_color;\n"
2272         "}\n";
2273 
2274     ANGLE_GL_PROGRAM(prog, vert, frag);
2275 
2276     gl::Context *context   = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
2277     gl::Program *glProgram = context->getProgram(prog.get());
2278     GLint oneIndex         = glProgram->getUniformLocation("ui_one");
2279     ASSERT_NE(-1, oneIndex);
2280     GLint twoIndex = glProgram->getUniformLocation("ui_two");
2281     ASSERT_NE(-1, twoIndex);
2282     GLint threeIndex = glProgram->getUniformLocation("ui_three");
2283     ASSERT_NE(-1, threeIndex);
2284     glUseProgram(prog.get());
2285     glUniform1i(oneIndex, 1);
2286     glUniform1i(twoIndex, 2);
2287     glUniform1i(threeIndex, 3);
2288 
2289     drawQuad(prog.get(), "position", 0.5f);
2290     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2291 }
2292 
2293 // Convers a bug with the unary minus operator on unsigned integer workaround.
TEST_P(GLSLTest_ES3,UnaryMinusOperatorUnsignedInt)2294 TEST_P(GLSLTest_ES3, UnaryMinusOperatorUnsignedInt)
2295 {
2296     const std::string &vert =
2297         "#version 300 es\n"
2298         "in highp vec4 position;\n"
2299         "out mediump vec4 v_color;\n"
2300         "uniform uint ui_one;\n"
2301         "uniform uint ui_two;\n"
2302         "uniform uint ui_three;\n"
2303         "void main() {\n"
2304         "    uint s[3];\n"
2305         "    s[0] = ui_one;\n"
2306         "    s[1] = -(-(-ui_two + 1u) + 1u);\n"  // s[1] = -ui_two
2307         "    s[2] = ui_three;\n"
2308         "    uint result = 0u;\n"
2309         "    for (uint i = 0u; i < ui_three; i++) {\n"
2310         "        result += s[i];\n"
2311         "    }\n"
2312         "    v_color = (result == 2u) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n"
2313         "    gl_Position = position;\n"
2314         "}\n";
2315     const std::string &frag =
2316         "#version 300 es\n"
2317         "in mediump vec4 v_color;\n"
2318         "layout(location=0) out mediump vec4 o_color;\n"
2319         "void main() {\n"
2320         "    o_color = v_color;\n"
2321         "}\n";
2322 
2323     ANGLE_GL_PROGRAM(prog, vert, frag);
2324 
2325     gl::Context *context   = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
2326     gl::Program *glProgram = context->getProgram(prog.get());
2327     GLint oneIndex         = glProgram->getUniformLocation("ui_one");
2328     ASSERT_NE(-1, oneIndex);
2329     GLint twoIndex = glProgram->getUniformLocation("ui_two");
2330     ASSERT_NE(-1, twoIndex);
2331     GLint threeIndex = glProgram->getUniformLocation("ui_three");
2332     ASSERT_NE(-1, threeIndex);
2333     glUseProgram(prog.get());
2334     glUniform1ui(oneIndex, 1u);
2335     glUniform1ui(twoIndex, 2u);
2336     glUniform1ui(threeIndex, 3u);
2337 
2338     drawQuad(prog.get(), "position", 0.5f);
2339     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2340 }
2341 
2342 // Test a nested sequence operator with a ternary operator inside. The ternary operator is
2343 // intended to be such that it gets converted to an if statement on the HLSL backend.
TEST_P(GLSLTest,NestedSequenceOperatorWithTernaryInside)2344 TEST_P(GLSLTest, NestedSequenceOperatorWithTernaryInside)
2345 {
2346     const std::string &vert =
2347         "attribute vec2 position;\n"
2348         "void main()\n"
2349         "{\n"
2350         "    gl_Position = vec4(position, 0, 1);\n"
2351         "}";
2352 
2353     // Note that the uniform keep_flop_positive doesn't need to be set - the test expects it to have
2354     // its default value false.
2355     const std::string &frag =
2356         "precision mediump float;\n"
2357         "uniform bool keep_flop_positive;\n"
2358         "float flop;\n"
2359         "void main() {\n"
2360         "    flop = -1.0,\n"
2361         "    (flop *= -1.0,\n"
2362         "    keep_flop_positive ? 0.0 : flop *= -1.0),\n"
2363         "    gl_FragColor = vec4(0, -flop, 0, 1);\n"
2364         "}";
2365 
2366     ANGLE_GL_PROGRAM(prog, vert, frag);
2367     drawQuad(prog.get(), "position", 0.5f);
2368     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2369 }
2370 
2371 // Test that using a sampler2D and samplerExternalOES in the same shader works (anglebug.com/1534)
TEST_P(GLSLTest,ExternalAnd2DSampler)2372 TEST_P(GLSLTest, ExternalAnd2DSampler)
2373 {
2374     if (!extensionEnabled("GL_OES_EGL_image_external"))
2375     {
2376         std::cout << "Test skipped because GL_OES_EGL_image_external is not available."
2377                   << std::endl;
2378         return;
2379     }
2380 
2381     const std::string fragmentShader =
2382         "precision mediump float;\n"
2383         "uniform samplerExternalOES tex0;\n"
2384         "uniform sampler2D tex1;\n"
2385         "void main(void)\n"
2386         "{\n"
2387         " vec2 uv = vec2(0.0, 0.0);"
2388         " gl_FragColor = texture2D(tex0, uv) + texture2D(tex1, uv);\n"
2389         "}\n";
2390 
2391     ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
2392 }
2393 
2394 // Test that using an invalid constant right-shift produces an error.
TEST_P(GLSLTest_ES3,FoldedInvalidRightShift)2395 TEST_P(GLSLTest_ES3, FoldedInvalidRightShift)
2396 {
2397     const std::string &fragmentShader =
2398         "#version 300 es\n"
2399         "precision mediump float;\n"
2400         "out vec4 color;\n"
2401         "void main(void)\n"
2402         "{\n"
2403         " int diff = -100 >> -100;\n"
2404         " color = vec4(float(diff));\n"
2405         "}\n";
2406 
2407     GLuint program = CompileProgram(mSimpleVSSource, fragmentShader);
2408     EXPECT_EQ(0u, program);
2409     glDeleteProgram(program);
2410 }
2411 
2412 // Test that using an invalid constant left-shift produces an error.
TEST_P(GLSLTest_ES3,FoldedInvalidLeftShift)2413 TEST_P(GLSLTest_ES3, FoldedInvalidLeftShift)
2414 {
2415     const std::string &fragmentShader =
2416         "#version 300 es\n"
2417         "precision mediump float;\n"
2418         "out vec4 color;\n"
2419         "void main(void)\n"
2420         "{\n"
2421         " int diff = -100 << -100;\n"
2422         " color = vec4(float(diff));\n"
2423         "}\n";
2424 
2425     GLuint program = CompileProgram(mSimpleVSSource, fragmentShader);
2426     EXPECT_EQ(0u, program);
2427     glDeleteProgram(program);
2428 }
2429 
2430 }  // anonymous namespace
2431 
2432 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
2433 ANGLE_INSTANTIATE_TEST(GLSLTest,
2434                        ES2_D3D9(),
2435                        ES2_D3D11(),
2436                        ES2_D3D11_FL9_3(),
2437                        ES2_OPENGL(),
2438                        ES3_OPENGL(),
2439                        ES2_OPENGLES(),
2440                        ES3_OPENGLES());
2441 
2442 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
2443 ANGLE_INSTANTIATE_TEST(GLSLTest_ES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
2444