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