blob: 3fc0bf1de6c73d2e1ccca0d3eac0c8b0bec7a689 [file] [log] [blame]
Jamie Madill55def582015-05-04 11:24:57 -04001//
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
Corentin Wallezd3970de2015-05-14 11:07:48 -04007#include "test_utils/ANGLETest.h"
Jamie Madill96509e42014-05-29 14:33:27 -04008
Jamie Madill55def582015-05-04 11:24:57 -04009#include "libANGLE/Context.h"
10#include "libANGLE/Program.h"
11
Jamie Madillfa05f602015-05-07 13:47:11 -040012using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070013
Jamie Madill2bf8b372014-06-16 17:18:51 -040014class GLSLTest : public ANGLETest
Jamie Madill96509e42014-05-29 14:33:27 -040015{
Jamie Madillfa05f602015-05-07 13:47:11 -040016 protected:
17 GLSLTest()
Jamie Madill96509e42014-05-29 14:33:27 -040018 {
19 setWindowWidth(128);
20 setWindowHeight(128);
21 setConfigRedBits(8);
22 setConfigGreenBits(8);
23 setConfigBlueBits(8);
24 setConfigAlphaBits(8);
25 }
Jamie Madillbfa91f42014-06-05 15:45:18 -040026
27 virtual void SetUp()
28 {
29 ANGLETest::SetUp();
30
Jamie Madill2bf8b372014-06-16 17:18:51 -040031 mSimpleVSSource = SHADER_SOURCE
Jamie Madillbfa91f42014-06-05 15:45:18 -040032 (
33 attribute vec4 inputAttribute;
34 void main()
35 {
36 gl_Position = inputAttribute;
37 }
38 );
39 }
40
Austin Kinrossaf875522014-08-25 21:06:07 -070041 std::string GenerateVaryingType(GLint vectorSize)
42 {
43 char varyingType[10];
44
45 if (vectorSize == 1)
46 {
47 sprintf(varyingType, "float");
48 }
49 else
50 {
51 sprintf(varyingType, "vec%d", vectorSize);
52 }
53
54 return std::string(varyingType);
55 }
56
57 std::string GenerateVectorVaryingDeclaration(GLint vectorSize, GLint arraySize, GLint id)
58 {
59 char buff[100];
60
61 if (arraySize == 1)
62 {
63 sprintf(buff, "varying %s v%d;\n", GenerateVaryingType(vectorSize).c_str(), id);
64 }
65 else
66 {
67 sprintf(buff, "varying %s v%d[%d];\n", GenerateVaryingType(vectorSize).c_str(), id, arraySize);
68 }
69
70 return std::string(buff);
71 }
72
73 std::string GenerateVectorVaryingSettingCode(GLint vectorSize, GLint arraySize, GLint id)
74 {
75 std::string returnString;
76 char buff[100];
77
78 if (arraySize == 1)
79 {
80 sprintf(buff, "\t v%d = %s(1.0);\n", id, GenerateVaryingType(vectorSize).c_str());
81 returnString += buff;
82 }
83 else
84 {
85 for (int i = 0; i < arraySize; i++)
86 {
87 sprintf(buff, "\t v%d[%d] = %s(1.0);\n", id, i, GenerateVaryingType(vectorSize).c_str());
88 returnString += buff;
89 }
90 }
91
92 return returnString;
93 }
94
95 std::string GenerateVectorVaryingUseCode(GLint arraySize, GLint id)
96 {
97 if (arraySize == 1)
98 {
99 char buff[100];
100 sprintf(buff, "v%d + ", id);
101 return std::string(buff);
102 }
103 else
104 {
105 std::string returnString;
106 for (int i = 0; i < arraySize; i++)
107 {
108 char buff[100];
109 sprintf(buff, "v%d[%d] + ", id, i);
110 returnString += buff;
111 }
112 return returnString;
113 }
114 }
115
Austin Kinross8b695ee2015-03-12 13:12:20 -0700116 void GenerateGLSLWithVaryings(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
117 GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize,
118 std::string* fragmentShader, std::string* vertexShader)
Austin Kinrossaf875522014-08-25 21:06:07 -0700119 {
120 // Generate a string declaring the varyings, to share between the fragment shader and the vertex shader.
121 std::string varyingDeclaration;
122
123 unsigned int varyingCount = 0;
124
125 for (GLint i = 0; i < floatCount; i++)
126 {
127 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 1, varyingCount);
128 varyingCount += 1;
129 }
130
131 for (GLint i = 0; i < floatArrayCount; i++)
132 {
133 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 2, varyingCount);
134 varyingCount += 1;
135 }
136
137 for (GLint i = 0; i < vec2Count; i++)
138 {
139 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 1, varyingCount);
140 varyingCount += 1;
141 }
142
143 for (GLint i = 0; i < vec2ArrayCount; i++)
144 {
145 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 2, varyingCount);
146 varyingCount += 1;
147 }
148
149 for (GLint i = 0; i < vec3Count; i++)
150 {
151 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 1, varyingCount);
152 varyingCount += 1;
153 }
154
155 for (GLint i = 0; i < vec3ArrayCount; i++)
156 {
157 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 2, varyingCount);
158 varyingCount += 1;
159 }
160
Austin Kinross8b695ee2015-03-12 13:12:20 -0700161 for (GLint i = 0; i < vec4Count; i++)
162 {
163 varyingDeclaration += GenerateVectorVaryingDeclaration(4, 1, varyingCount);
164 varyingCount += 1;
165 }
166
167 for (GLint i = 0; i < vec4ArrayCount; i++)
168 {
169 varyingDeclaration += GenerateVectorVaryingDeclaration(4, 2, varyingCount);
170 varyingCount += 1;
171 }
172
Austin Kinrossaf875522014-08-25 21:06:07 -0700173 // Generate the vertex shader
174 vertexShader->clear();
175 vertexShader->append(varyingDeclaration);
176 vertexShader->append("\nvoid main()\n{\n");
177
178 unsigned int currentVSVarying = 0;
179
180 for (GLint i = 0; i < floatCount; i++)
181 {
182 vertexShader->append(GenerateVectorVaryingSettingCode(1, 1, currentVSVarying));
183 currentVSVarying += 1;
184 }
185
186 for (GLint i = 0; i < floatArrayCount; i++)
187 {
188 vertexShader->append(GenerateVectorVaryingSettingCode(1, 2, currentVSVarying));
189 currentVSVarying += 1;
190 }
191
192 for (GLint i = 0; i < vec2Count; i++)
193 {
194 vertexShader->append(GenerateVectorVaryingSettingCode(2, 1, currentVSVarying));
195 currentVSVarying += 1;
196 }
197
198 for (GLint i = 0; i < vec2ArrayCount; i++)
199 {
200 vertexShader->append(GenerateVectorVaryingSettingCode(2, 2, currentVSVarying));
201 currentVSVarying += 1;
202 }
203
204 for (GLint i = 0; i < vec3Count; i++)
205 {
206 vertexShader->append(GenerateVectorVaryingSettingCode(3, 1, currentVSVarying));
207 currentVSVarying += 1;
208 }
209
210 for (GLint i = 0; i < vec3ArrayCount; i++)
211 {
212 vertexShader->append(GenerateVectorVaryingSettingCode(3, 2, currentVSVarying));
213 currentVSVarying += 1;
214 }
215
Austin Kinross8b695ee2015-03-12 13:12:20 -0700216 for (GLint i = 0; i < vec4Count; i++)
217 {
218 vertexShader->append(GenerateVectorVaryingSettingCode(4, 1, currentVSVarying));
219 currentVSVarying += 1;
220 }
221
222 for (GLint i = 0; i < vec4ArrayCount; i++)
223 {
224 vertexShader->append(GenerateVectorVaryingSettingCode(4, 2, currentVSVarying));
225 currentVSVarying += 1;
226 }
227
228 if (usePointSize)
229 {
230 vertexShader->append("gl_PointSize = 1.0;\n");
231 }
232
Austin Kinrossaf875522014-08-25 21:06:07 -0700233 vertexShader->append("}\n");
234
235 // Generate the fragment shader
236 fragmentShader->clear();
237 fragmentShader->append("precision highp float;\n");
238 fragmentShader->append(varyingDeclaration);
239 fragmentShader->append("\nvoid main() \n{ \n\tvec4 retColor = vec4(0,0,0,0);\n");
240
241 unsigned int currentFSVarying = 0;
242
243 // Make use of the float varyings
244 fragmentShader->append("\tretColor += vec4(");
245
246 for (GLint i = 0; i < floatCount; i++)
247 {
248 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
249 currentFSVarying += 1;
250 }
251
252 for (GLint i = 0; i < floatArrayCount; i++)
253 {
254 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
255 currentFSVarying += 1;
256 }
257
258 fragmentShader->append("0.0, 0.0, 0.0, 0.0);\n");
259
260 // Make use of the vec2 varyings
261 fragmentShader->append("\tretColor += vec4(");
262
263 for (GLint i = 0; i < vec2Count; i++)
264 {
265 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
266 currentFSVarying += 1;
267 }
268
269 for (GLint i = 0; i < vec2ArrayCount; i++)
270 {
271 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
272 currentFSVarying += 1;
273 }
274
275 fragmentShader->append("vec2(0.0, 0.0), 0.0, 0.0);\n");
276
277 // Make use of the vec3 varyings
278 fragmentShader->append("\tretColor += vec4(");
279
280 for (GLint i = 0; i < vec3Count; i++)
281 {
282 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
283 currentFSVarying += 1;
284 }
285
286 for (GLint i = 0; i < vec3ArrayCount; i++)
287 {
288 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
289 currentFSVarying += 1;
290 }
291
292 fragmentShader->append("vec3(0.0, 0.0, 0.0), 0.0);\n");
Austin Kinross8b695ee2015-03-12 13:12:20 -0700293
294 // Make use of the vec4 varyings
295 fragmentShader->append("\tretColor += ");
296
297 for (GLint i = 0; i < vec4Count; i++)
298 {
299 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
300 currentFSVarying += 1;
301 }
302
303 for (GLint i = 0; i < vec4ArrayCount; i++)
304 {
305 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
306 currentFSVarying += 1;
307 }
308
309 fragmentShader->append("vec4(0.0, 0.0, 0.0, 0.0);\n");
310
311 // Set gl_FragColor, and use special variables if requested
312 fragmentShader->append("\tgl_FragColor = retColor");
313
314 if (useFragCoord)
315 {
316 fragmentShader->append(" + gl_FragCoord");
317 }
318
319 if (usePointCoord)
320 {
321 fragmentShader->append(" + vec4(gl_PointCoord, 0.0, 0.0)");
322 }
323
324 fragmentShader->append(";\n}");
325 }
326
327 void VaryingTestBase(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
328 GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize, bool expectSuccess)
329 {
330 std::string fragmentShaderSource;
331 std::string vertexShaderSource;
332
333 GenerateGLSLWithVaryings(floatCount, floatArrayCount, vec2Count, vec2ArrayCount, vec3Count, vec3ArrayCount,
334 vec4Count, vec4ArrayCount, useFragCoord, usePointCoord, usePointSize,
335 &fragmentShaderSource, &vertexShaderSource);
336
337 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
338
339 if (expectSuccess)
340 {
341 EXPECT_NE(0u, program);
342 }
343 else
344 {
345 EXPECT_EQ(0u, program);
346 }
Austin Kinrossaf875522014-08-25 21:06:07 -0700347 }
348
Austin Kinross7a3e8e22015-10-08 15:50:06 -0700349 void CompileGLSLWithUniformsAndSamplers(GLint vertexUniformCount,
350 GLint fragmentUniformCount,
351 GLint vertexSamplersCount,
352 GLint fragmentSamplersCount,
353 bool expectSuccess)
354 {
355 std::stringstream vertexShader;
356 std::stringstream fragmentShader;
357
358 // Generate the vertex shader
359 vertexShader << "precision mediump float;\n";
360
361 for (int i = 0; i < vertexUniformCount; i++)
362 {
363 vertexShader << "uniform vec4 v" << i << ";\n";
364 }
365
366 for (int i = 0; i < vertexSamplersCount; i++)
367 {
368 vertexShader << "uniform sampler2D s" << i << ";\n";
369 }
370
371 vertexShader << "void main()\n{\n";
372
373 for (int i = 0; i < vertexUniformCount; i++)
374 {
375 vertexShader << " gl_Position += v" << i << ";\n";
376 }
377
378 for (int i = 0; i < vertexSamplersCount; i++)
379 {
380 vertexShader << " gl_Position += texture2D(s" << i << ", vec2(0.0, 0.0));\n";
381 }
382
383 if (vertexUniformCount == 0 && vertexSamplersCount == 0)
384 {
385 vertexShader << " gl_Position = vec4(0.0);\n";
386 }
387
388 vertexShader << "}\n";
389
390 // Generate the fragment shader
391 fragmentShader << "precision mediump float;\n";
392
393 for (int i = 0; i < fragmentUniformCount; i++)
394 {
395 fragmentShader << "uniform vec4 v" << i << ";\n";
396 }
397
398 for (int i = 0; i < fragmentSamplersCount; i++)
399 {
400 fragmentShader << "uniform sampler2D s" << i << ";\n";
401 }
402
403 fragmentShader << "void main()\n{\n";
404
405 for (int i = 0; i < fragmentUniformCount; i++)
406 {
407 fragmentShader << " gl_FragColor += v" << i << ";\n";
408 }
409
410 for (int i = 0; i < fragmentSamplersCount; i++)
411 {
412 fragmentShader << " gl_FragColor += texture2D(s" << i << ", vec2(0.0, 0.0));\n";
413 }
414
415 if (fragmentUniformCount == 0 && fragmentSamplersCount == 0)
416 {
417 fragmentShader << " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n";
418 }
419
420 fragmentShader << "}\n";
421
422 GLuint program = CompileProgram(vertexShader.str(), fragmentShader.str());
423
424 if (expectSuccess)
425 {
426 EXPECT_NE(0u, program);
427 }
428 else
429 {
430 EXPECT_EQ(0u, program);
431 }
432 }
433
Jamie Madill2bf8b372014-06-16 17:18:51 -0400434 std::string mSimpleVSSource;
Jamie Madill96509e42014-05-29 14:33:27 -0400435};
436
Jamie Madillfa05f602015-05-07 13:47:11 -0400437class GLSLTest_ES3 : public GLSLTest
Gregoire Payen de La Garanderieb3dced22015-01-12 14:54:55 +0000438{
Olli Etuahoe1d199b2016-07-19 17:14:27 +0300439 void SetUp() override
440 {
441 ANGLETest::SetUp();
442
443 mSimpleVSSource =
444 "#version 300 es\n"
445 "in vec4 inputAttribute;"
446 "void main()"
447 "{"
448 " gl_Position = inputAttribute;"
449 "}";
450 }
Gregoire Payen de La Garanderieb3dced22015-01-12 14:54:55 +0000451};
452
Jamie Madillfa05f602015-05-07 13:47:11 -0400453TEST_P(GLSLTest, NamelessScopedStructs)
Jamie Madill96509e42014-05-29 14:33:27 -0400454{
Jamie Madillbfa91f42014-06-05 15:45:18 -0400455 const std::string fragmentShaderSource = SHADER_SOURCE
Jamie Madill96509e42014-05-29 14:33:27 -0400456 (
Jamie Madillbfa91f42014-06-05 15:45:18 -0400457 precision mediump float;
458
Jamie Madill96509e42014-05-29 14:33:27 -0400459 void main()
460 {
Jamie Madillbfa91f42014-06-05 15:45:18 -0400461 struct
462 {
463 float q;
464 } b;
465
466 gl_FragColor = vec4(1, 0, 0, 1);
467 gl_FragColor.a += b.q;
Jamie Madill96509e42014-05-29 14:33:27 -0400468 }
469 );
470
Jamie Madill5599c8f2014-08-26 13:16:39 -0400471 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madillbfa91f42014-06-05 15:45:18 -0400472 EXPECT_NE(0u, program);
473}
Austin Kinross18b931d2014-09-29 12:58:31 -0700474
Jamie Madillfa05f602015-05-07 13:47:11 -0400475TEST_P(GLSLTest, ScopedStructsOrderBug)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400476{
Geoff Lange0cc2a42016-01-20 10:58:17 -0500477 // TODO(geofflang): Find out why this doesn't compile on Apple OpenGL drivers
478 // (http://anglebug.com/1292)
Geoff Lang5103f4c2016-01-26 11:40:18 -0500479 // TODO(geofflang): Find out why this doesn't compile on AMD OpenGL drivers
Geoff Lange0cc2a42016-01-20 10:58:17 -0500480 // (http://anglebug.com/1291)
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400481 if (IsDesktopOpenGL() && (IsOSX() || !IsNVIDIA()))
Geoff Lange0cc2a42016-01-20 10:58:17 -0500482 {
Jamie Madill518b9fa2016-03-02 11:26:02 -0500483 std::cout << "Test disabled on this OpenGL configuration." << std::endl;
Geoff Lange0cc2a42016-01-20 10:58:17 -0500484 return;
485 }
Geoff Lange0cc2a42016-01-20 10:58:17 -0500486
Jamie Madillbfa91f42014-06-05 15:45:18 -0400487 const std::string fragmentShaderSource = SHADER_SOURCE
488 (
489 precision mediump float;
490
491 struct T
492 {
493 float f;
494 };
495
496 void main()
497 {
498 T a;
499
500 struct T
501 {
502 float q;
503 };
504
505 T b;
506
507 gl_FragColor = vec4(1, 0, 0, 1);
508 gl_FragColor.a += a.f;
509 gl_FragColor.a += b.q;
510 }
511 );
512
Jamie Madill5599c8f2014-08-26 13:16:39 -0400513 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madillbfa91f42014-06-05 15:45:18 -0400514 EXPECT_NE(0u, program);
515}
516
Jamie Madillfa05f602015-05-07 13:47:11 -0400517TEST_P(GLSLTest, ScopedStructsBug)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400518{
Jamie Madill96509e42014-05-29 14:33:27 -0400519 const std::string fragmentShaderSource = SHADER_SOURCE
520 (
521 precision mediump float;
522
523 struct T_0
524 {
525 float f;
526 };
527
528 void main()
529 {
530 gl_FragColor = vec4(1, 0, 0, 1);
531
532 struct T
533 {
534 vec2 v;
535 };
536
537 T_0 a;
538 T b;
539
540 gl_FragColor.a += a.f;
541 gl_FragColor.a += b.v.x;
542 }
543 );
544
Jamie Madill5599c8f2014-08-26 13:16:39 -0400545 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madill2bf8b372014-06-16 17:18:51 -0400546 EXPECT_NE(0u, program);
547}
548
Jamie Madillfa05f602015-05-07 13:47:11 -0400549TEST_P(GLSLTest, DxPositionBug)
Jamie Madill2bf8b372014-06-16 17:18:51 -0400550{
551 const std::string &vertexShaderSource = SHADER_SOURCE
552 (
553 attribute vec4 inputAttribute;
554 varying float dx_Position;
555 void main()
556 {
557 gl_Position = vec4(inputAttribute);
558 dx_Position = 0.0;
559 }
560 );
561
562 const std::string &fragmentShaderSource = SHADER_SOURCE
563 (
564 precision mediump float;
565
566 varying float dx_Position;
567
568 void main()
569 {
570 gl_FragColor = vec4(dx_Position, 0, 0, 1);
571 }
572 );
573
Jamie Madill5599c8f2014-08-26 13:16:39 -0400574 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill96509e42014-05-29 14:33:27 -0400575 EXPECT_NE(0u, program);
576}
Jamie Madill4836d222014-07-24 06:55:51 -0400577
Jamie Madillfa05f602015-05-07 13:47:11 -0400578TEST_P(GLSLTest, ElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400579{
580 const std::string &vertexShaderSource =
581 "attribute vec4 a_position;\n"
582 "varying float v;\n"
583 "void main() {\n"
584 " gl_Position = a_position;\n"
585 " v = 1.0;\n"
586 " if (a_position.x <= 0.5) {\n"
587 " v = 0.0;\n"
588 " } else if (a_position.x >= 0.5) {\n"
589 " v = 2.0;\n"
590 " }\n"
591 "}\n";
592
593 const std::string &fragmentShaderSource =
594 "precision highp float;\n"
595 "varying float v;\n"
596 "void main() {\n"
597 " vec4 color = vec4(1.0, 0.0, 0.0, 1.0);\n"
598 " if (v >= 1.0) color = vec4(0.0, 1.0, 0.0, 1.0);\n"
599 " if (v >= 2.0) color = vec4(0.0, 0.0, 1.0, 1.0);\n"
600 " gl_FragColor = color;\n"
601 "}\n";
602
Jamie Madill5599c8f2014-08-26 13:16:39 -0400603 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400604 ASSERT_NE(0u, program);
605
606 drawQuad(program, "a_position", 0.5f);
Jamie Madill4836d222014-07-24 06:55:51 -0400607
608 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
609 EXPECT_PIXEL_EQ(getWindowWidth()-1, 0, 0, 255, 0, 255);
610}
611
Jamie Madillfa05f602015-05-07 13:47:11 -0400612TEST_P(GLSLTest, TwoElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400613{
614 const std::string &vertexShaderSource =
615 "attribute vec4 a_position;\n"
616 "varying float v;\n"
617 "void main() {\n"
618 " gl_Position = a_position;\n"
Jamie Madill778d5272014-08-04 13:13:25 -0400619 " if (a_position.x == 0.0) {\n"
Jamie Madill4836d222014-07-24 06:55:51 -0400620 " v = 1.0;\n"
621 " } else if (a_position.x > 0.5) {\n"
622 " v = 0.0;\n"
623 " } else if (a_position.x > 0.75) {\n"
624 " v = 0.5;\n"
625 " }\n"
626 "}\n";
627
628 const std::string &fragmentShaderSource =
629 "precision highp float;\n"
630 "varying float v;\n"
631 "void main() {\n"
632 " gl_FragColor = vec4(v, 0.0, 0.0, 1.0);\n"
633 "}\n";
634
Jamie Madill5599c8f2014-08-26 13:16:39 -0400635 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400636 EXPECT_NE(0u, program);
637}
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400638
Jamie Madillfa05f602015-05-07 13:47:11 -0400639TEST_P(GLSLTest, FrontFacingAndVarying)
Jamie Madille6256f82014-09-17 10:31:15 -0400640{
Geoff Langdd323e92015-06-09 15:16:31 -0400641 EGLPlatformParameters platform = GetParam().eglParameters;
Austin Kinross8b695ee2015-03-12 13:12:20 -0700642
Jamie Madille6256f82014-09-17 10:31:15 -0400643 const std::string vertexShaderSource = SHADER_SOURCE
644 (
645 attribute vec4 a_position;
646 varying float v_varying;
647 void main()
648 {
649 v_varying = a_position.x;
650 gl_Position = a_position;
651 }
652 );
653
654 const std::string fragmentShaderSource = SHADER_SOURCE
655 (
656 precision mediump float;
657 varying float v_varying;
658 void main()
659 {
660 vec4 c;
661
662 if (gl_FrontFacing)
663 {
664 c = vec4(v_varying, 0, 0, 1.0);
665 }
666 else
667 {
668 c = vec4(0, v_varying, 0, 1.0);
669 }
670 gl_FragColor = c;
671 }
672 );
673
674 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Austin Kinross02df7962015-07-01 10:03:42 -0700675
676 // Compilation should fail on D3D11 feature level 9_3, since gl_FrontFacing isn't supported.
677 if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
678 {
679 if (platform.majorVersion == 9 && platform.minorVersion == 3)
680 {
681 EXPECT_EQ(0u, program);
682 return;
683 }
684 }
685
686 // Otherwise, compilation should succeed
Jamie Madille6256f82014-09-17 10:31:15 -0400687 EXPECT_NE(0u, program);
688}
689
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400690// Verify that linking shaders declaring different shading language versions fails.
691TEST_P(GLSLTest_ES3, VersionMismatch)
692{
693 const std::string fragmentShaderSource100 =
694 "precision mediump float;\n"
695 "varying float v_varying;\n"
696 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
697
698 const std::string vertexShaderSource100 =
699 "attribute vec4 a_position;\n"
700 "varying float v_varying;\n"
701 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
702
703 const std::string fragmentShaderSource300 =
704 "#version 300 es\n"
705 "precision mediump float;\n"
706 "in float v_varying;\n"
707 "out vec4 my_FragColor;\n"
708 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
709
710 const std::string vertexShaderSource300 =
711 "#version 300 es\n"
712 "in vec4 a_position;\n"
713 "out float v_varying;\n"
714 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
715
716 GLuint program = CompileProgram(vertexShaderSource300, fragmentShaderSource100);
717 EXPECT_EQ(0u, program);
718
719 program = CompileProgram(vertexShaderSource100, fragmentShaderSource300);
720 EXPECT_EQ(0u, program);
721}
722
723// Verify that declaring varying as invariant only in vertex shader fails in ESSL 1.00.
724TEST_P(GLSLTest, InvariantVaryingOut)
725{
726 const std::string fragmentShaderSource =
727 "precision mediump float;\n"
728 "varying float v_varying;\n"
729 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
730
731 const std::string vertexShaderSource =
732 "attribute vec4 a_position;\n"
733 "invariant varying float v_varying;\n"
734 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
735
736 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
737 EXPECT_EQ(0u, program);
738}
739
740// Verify that declaring varying as invariant only in vertex shader succeeds in ESSL 3.00.
741TEST_P(GLSLTest_ES3, InvariantVaryingOut)
742{
743 // TODO: ESSL 3.00 -> GLSL 1.20 translation should add "invariant" in fragment shader
744 // for varyings which are invariant in vertex shader (http://anglebug.com/1293)
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400745 if (IsDesktopOpenGL())
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400746 {
747 std::cout << "Test disabled on OpenGL." << std::endl;
748 return;
749 }
750
751 const std::string fragmentShaderSource =
752 "#version 300 es\n"
753 "precision mediump float;\n"
754 "in float v_varying;\n"
755 "out vec4 my_FragColor;\n"
756 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
757
758 const std::string vertexShaderSource =
759 "#version 300 es\n"
760 "in vec4 a_position;\n"
761 "invariant out float v_varying;\n"
762 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
763
764 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
765 EXPECT_NE(0u, program);
766}
767
768// Verify that declaring varying as invariant only in fragment shader fails in ESSL 1.00.
Jamie Madillfa05f602015-05-07 13:47:11 -0400769TEST_P(GLSLTest, InvariantVaryingIn)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400770{
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400771 const std::string fragmentShaderSource =
772 "precision mediump float;\n"
773 "invariant varying float v_varying;\n"
774 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
Geoff Lange0cc2a42016-01-20 10:58:17 -0500775
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400776 const std::string vertexShaderSource =
777 "attribute vec4 a_position;\n"
778 "varying float v_varying;\n"
779 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400780
Jamie Madill5599c8f2014-08-26 13:16:39 -0400781 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400782 EXPECT_EQ(0u, program);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400783}
784
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400785// Verify that declaring varying as invariant only in fragment shader fails in ESSL 3.00.
786TEST_P(GLSLTest_ES3, InvariantVaryingIn)
787{
788 const std::string fragmentShaderSource =
789 "#version 300 es\n"
790 "precision mediump float;\n"
791 "invariant in float v_varying;\n"
792 "out vec4 my_FragColor;\n"
793 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
794
795 const std::string vertexShaderSource =
796 "#version 300 es\n"
797 "in vec4 a_position;\n"
798 "out float v_varying;\n"
799 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
800
801 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
802 EXPECT_EQ(0u, program);
803}
804
805// Verify that declaring varying as invariant in both shaders succeeds in ESSL 1.00.
Jamie Madillfa05f602015-05-07 13:47:11 -0400806TEST_P(GLSLTest, InvariantVaryingBoth)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400807{
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400808 const std::string fragmentShaderSource =
809 "precision mediump float;\n"
810 "invariant varying float v_varying;\n"
811 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400812
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400813 const std::string vertexShaderSource =
814 "attribute vec4 a_position;\n"
815 "invariant varying float v_varying;\n"
816 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400817
Jamie Madill5599c8f2014-08-26 13:16:39 -0400818 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400819 EXPECT_NE(0u, program);
820}
821
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400822// Verify that declaring varying as invariant in both shaders fails in ESSL 3.00.
823TEST_P(GLSLTest_ES3, InvariantVaryingBoth)
824{
825 const std::string fragmentShaderSource =
826 "#version 300 es\n"
827 "precision mediump float;\n"
828 "invariant in float v_varying;\n"
829 "out vec4 my_FragColor;\n"
830 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
831
832 const std::string vertexShaderSource =
833 "#version 300 es\n"
834 "in vec4 a_position;\n"
835 "invariant out float v_varying;\n"
836 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
837
838 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
839 EXPECT_EQ(0u, program);
840}
841
842// Verify that declaring gl_Position as invariant succeeds in ESSL 1.00.
Jamie Madillfa05f602015-05-07 13:47:11 -0400843TEST_P(GLSLTest, InvariantGLPosition)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400844{
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400845 const std::string fragmentShaderSource =
846 "precision mediump float;\n"
847 "varying float v_varying;\n"
848 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400849
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400850 const std::string vertexShaderSource =
851 "attribute vec4 a_position;\n"
852 "invariant gl_Position;\n"
853 "varying float v_varying;\n"
854 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400855
Jamie Madill5599c8f2014-08-26 13:16:39 -0400856 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400857 EXPECT_NE(0u, program);
858}
859
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400860// Verify that declaring gl_Position as invariant succeeds in ESSL 3.00.
861TEST_P(GLSLTest_ES3, InvariantGLPosition)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400862{
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400863 const std::string fragmentShaderSource =
864 "#version 300 es\n"
865 "precision mediump float;\n"
866 "in float v_varying;\n"
867 "out vec4 my_FragColor;\n"
868 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
869
870 const std::string vertexShaderSource =
871 "#version 300 es\n"
872 "in vec4 a_position;\n"
873 "invariant gl_Position;\n"
874 "out float v_varying;\n"
875 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
876
877 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
878 EXPECT_NE(0u, program);
879}
880
881// Verify that using invariant(all) in both shaders succeeds in ESSL 1.00.
882TEST_P(GLSLTest, InvariantAllBoth)
883{
884 // TODO: ESSL 1.00 -> GLSL 1.20 translation should add "invariant" in fragment shader
885 // for varyings which are invariant in vertex shader individually,
886 // and remove invariant(all) from fragment shader (http://anglebug.com/1293)
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400887 if (IsDesktopOpenGL())
Geoff Lange0cc2a42016-01-20 10:58:17 -0500888 {
889 std::cout << "Test disabled on OpenGL." << std::endl;
890 return;
891 }
892
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400893 const std::string fragmentShaderSource =
894 "#pragma STDGL invariant(all)\n"
895 "precision mediump float;\n"
896 "varying float v_varying;\n"
897 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400898
899 const std::string vertexShaderSource =
900 "#pragma STDGL invariant(all)\n"
901 "attribute vec4 a_position;\n"
902 "varying float v_varying;\n"
903 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
904
Jamie Madill5599c8f2014-08-26 13:16:39 -0400905 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400906 EXPECT_NE(0u, program);
907}
Austin Kinrossaf875522014-08-25 21:06:07 -0700908
Geoff Lang156d7192016-07-21 16:11:00 -0400909// Verify that functions without return statements still compile
910TEST_P(GLSLTest, MissingReturnFloat)
911{
912 const std::string vertexShaderSource =
913 "varying float v_varying;\n"
914 "float f() { if (v_varying > 0.0) return 1.0; }\n"
915 "void main() { gl_Position = vec4(f(), 0, 0, 1); }\n";
916
917 const std::string fragmentShaderSource =
918 "precision mediump float;\n"
919 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
920
921 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
922 EXPECT_NE(0u, program);
923}
924
925// Verify that functions without return statements still compile
926TEST_P(GLSLTest, MissingReturnVec2)
927{
928 const std::string vertexShaderSource =
929 "varying float v_varying;\n"
930 "vec2 f() { if (v_varying > 0.0) return vec2(1.0, 1.0); }\n"
931 "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
932
933 const std::string fragmentShaderSource =
934 "precision mediump float;\n"
935 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
936
937 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
938 EXPECT_NE(0u, program);
939}
940
941// Verify that functions without return statements still compile
942TEST_P(GLSLTest, MissingReturnVec3)
943{
944 const std::string vertexShaderSource =
945 "varying float v_varying;\n"
946 "vec3 f() { if (v_varying > 0.0) return vec3(1.0, 1.0, 1.0); }\n"
947 "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
948
949 const std::string fragmentShaderSource =
950 "precision mediump float;\n"
951 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
952
953 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
954 EXPECT_NE(0u, program);
955}
956
957// Verify that functions without return statements still compile
958TEST_P(GLSLTest, MissingReturnVec4)
959{
960 const std::string vertexShaderSource =
961 "varying float v_varying;\n"
962 "vec4 f() { if (v_varying > 0.0) return vec4(1.0, 1.0, 1.0, 1.0); }\n"
963 "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
964
965 const std::string fragmentShaderSource =
966 "precision mediump float;\n"
967 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
968
969 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
970 EXPECT_NE(0u, program);
971}
972
973// Verify that functions without return statements still compile
974TEST_P(GLSLTest, MissingReturnIVec4)
975{
976 const std::string vertexShaderSource =
977 "varying float v_varying;\n"
978 "ivec4 f() { if (v_varying > 0.0) return ivec4(1, 1, 1, 1); }\n"
979 "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
980
981 const std::string fragmentShaderSource =
982 "precision mediump float;\n"
983 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
984
985 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
986 EXPECT_NE(0u, program);
987}
988
989// Verify that functions without return statements still compile
990TEST_P(GLSLTest, MissingReturnMat4)
991{
992 const std::string vertexShaderSource =
993 "varying float v_varying;\n"
994 "mat4 f() { if (v_varying > 0.0) return mat4(1.0); }\n"
995 "void main() { gl_Position = vec4(f()[0][0], 0, 0, 1); }\n";
996
997 const std::string fragmentShaderSource =
998 "precision mediump float;\n"
999 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
1000
1001 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1002 EXPECT_NE(0u, program);
1003}
1004
1005// Verify that functions without return statements still compile
1006TEST_P(GLSLTest, MissingReturnStruct)
1007{
1008 const std::string vertexShaderSource =
1009 "varying float v_varying;\n"
1010 "struct s { float a; int b; vec2 c; };\n"
1011 "s f() { if (v_varying > 0.0) return s(1.0, 1, vec2(1.0, 1.0)); }\n"
1012 "void main() { gl_Position = vec4(f().a, 0, 0, 1); }\n";
1013
1014 const std::string fragmentShaderSource =
1015 "precision mediump float;\n"
1016 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
1017
1018 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1019 EXPECT_NE(0u, program);
1020}
1021
1022// Verify that functions without return statements still compile
1023TEST_P(GLSLTest_ES3, MissingReturnArray)
1024{
1025 const std::string vertexShaderSource =
1026 "#version 300 es\n"
1027 "in float v_varying;\n"
1028 "vec2[2] f() { if (v_varying > 0.0) { return vec2[2](vec2(1.0, 1.0), vec2(1.0, 1.0)); } }\n"
1029 "void main() { gl_Position = vec4(f()[0].x, 0, 0, 1); }\n";
1030
1031 const std::string fragmentShaderSource =
1032 "#version 300 es\n"
1033 "precision mediump float;\n"
1034 "out vec4 my_FragColor;\n"
1035 "void main() { my_FragColor = vec4(0, 0, 0, 1); }\n";
1036
1037 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1038 EXPECT_NE(0u, program);
1039}
1040
1041// Verify that functions without return statements still compile
1042TEST_P(GLSLTest_ES3, MissingReturnArrayOfStructs)
1043{
1044 const std::string vertexShaderSource =
1045 "#version 300 es\n"
1046 "in float v_varying;\n"
1047 "struct s { float a; int b; vec2 c; };\n"
1048 "s[2] f() { if (v_varying > 0.0) { return s[2](s(1.0, 1, vec2(1.0, 1.0)), s(1.0, 1, "
1049 "vec2(1.0, 1.0))); } }\n"
1050 "void main() { gl_Position = vec4(f()[0].a, 0, 0, 1); }\n";
1051
1052 const std::string fragmentShaderSource =
1053 "#version 300 es\n"
1054 "precision mediump float;\n"
1055 "out vec4 my_FragColor;\n"
1056 "void main() { my_FragColor = vec4(0, 0, 0, 1); }\n";
1057
1058 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1059 EXPECT_NE(0u, program);
1060}
1061
Yuly Novikova1f6dc92016-06-15 23:27:04 -04001062// Verify that using invariant(all) in both shaders fails in ESSL 3.00.
1063TEST_P(GLSLTest_ES3, InvariantAllBoth)
1064{
1065 const std::string fragmentShaderSource =
1066 "#version 300 es\n"
1067 "#pragma STDGL invariant(all)\n"
1068 "precision mediump float;\n"
1069 "in float v_varying;\n"
1070 "out vec4 my_FragColor;\n"
1071 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1072
1073 const std::string vertexShaderSource =
1074 "#version 300 es\n"
1075 "#pragma STDGL invariant(all)\n"
1076 "in vec4 a_position;\n"
1077 "out float v_varying;\n"
1078 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1079
1080 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1081 EXPECT_EQ(0u, program);
1082}
1083
1084// Verify that using invariant(all) only in fragment shader fails in ESSL 1.00.
1085TEST_P(GLSLTest, InvariantAllIn)
1086{
1087 const std::string fragmentShaderSource =
1088 "#pragma STDGL invariant(all)\n"
1089 "precision mediump float;\n"
1090 "varying float v_varying;\n"
1091 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1092
1093 const std::string vertexShaderSource =
1094 "attribute vec4 a_position;\n"
1095 "varying float v_varying;\n"
1096 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1097
1098 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1099 EXPECT_EQ(0u, program);
1100}
1101
1102// Verify that using invariant(all) only in fragment shader fails in ESSL 3.00.
1103TEST_P(GLSLTest_ES3, InvariantAllIn)
1104{
1105 const std::string fragmentShaderSource =
1106 "#version 300 es\n"
1107 "#pragma STDGL invariant(all)\n"
1108 "precision mediump float;\n"
1109 "in float v_varying;\n"
1110 "out vec4 my_FragColor;\n"
1111 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1112
1113 const std::string vertexShaderSource =
1114 "#version 300 es\n"
1115 "in vec4 a_position;\n"
1116 "out float v_varying;\n"
1117 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1118
1119 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1120 EXPECT_EQ(0u, program);
1121}
1122
1123// Verify that using invariant(all) only in vertex shader fails in ESSL 1.00.
1124TEST_P(GLSLTest, InvariantAllOut)
1125{
1126 const std::string fragmentShaderSource =
1127 "precision mediump float;\n"
1128 "varying float v_varying;\n"
1129 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1130
1131 const std::string vertexShaderSource =
1132 "#pragma STDGL invariant(all)\n"
1133 "attribute vec4 a_position;\n"
1134 "varying float v_varying;\n"
1135 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1136
1137 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1138 EXPECT_EQ(0u, program);
1139}
1140
1141// Verify that using invariant(all) only in vertex shader succeeds in ESSL 3.00.
1142TEST_P(GLSLTest_ES3, InvariantAllOut)
1143{
1144 // TODO: ESSL 3.00 -> GLSL 1.20 translation should add "invariant" in fragment shader
1145 // for varyings which are invariant in vertex shader,
1146 // because of invariant(all) being used in vertex shader (http://anglebug.com/1293)
Corentin Wallezc7f59d02016-06-20 10:12:08 -04001147 if (IsDesktopOpenGL())
Yuly Novikova1f6dc92016-06-15 23:27:04 -04001148 {
1149 std::cout << "Test disabled on OpenGL." << std::endl;
1150 return;
1151 }
1152
1153 const std::string fragmentShaderSource =
1154 "#version 300 es\n"
1155 "precision mediump float;\n"
1156 "in float v_varying;\n"
1157 "out vec4 my_FragColor;\n"
1158 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1159
1160 const std::string vertexShaderSource =
1161 "#version 300 es\n"
1162 "#pragma STDGL invariant(all)\n"
1163 "in vec4 a_position;\n"
1164 "out float v_varying;\n"
1165 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1166
1167 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1168 EXPECT_NE(0u, program);
1169}
1170
Jamie Madillfa05f602015-05-07 13:47:11 -04001171TEST_P(GLSLTest, MaxVaryingVec4)
Austin Kinross8b695ee2015-03-12 13:12:20 -07001172{
Geoff Lang69accbd2016-01-25 16:22:32 -05001173#if defined(__APPLE__)
1174 // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
1175 // (http://anglebug.com/1291)
Jamie Madill518b9fa2016-03-02 11:26:02 -05001176 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lang69accbd2016-01-25 16:22:32 -05001177 {
1178 std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
1179 return;
1180 }
1181#endif
1182
Austin Kinross8b695ee2015-03-12 13:12:20 -07001183 GLint maxVaryings = 0;
1184 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1185
1186 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, false, false, true);
1187}
1188
Jamie Madillfa05f602015-05-07 13:47:11 -04001189TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusTwoSpecialVariables)
Austin Kinross8b695ee2015-03-12 13:12:20 -07001190{
1191 GLint maxVaryings = 0;
1192 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1193
1194 // Generate shader code that uses gl_FragCoord and gl_PointCoord, two special fragment shader variables.
1195 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, false, true);
1196}
1197
Jamie Madillfa05f602015-05-07 13:47:11 -04001198TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusThreeSpecialVariables)
Austin Kinross8b695ee2015-03-12 13:12:20 -07001199{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001200 // TODO(geofflang): Figure out why this fails on OpenGL AMD (http://anglebug.com/1291)
Jamie Madill518b9fa2016-03-02 11:26:02 -05001201 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lange0cc2a42016-01-20 10:58:17 -05001202 {
1203 std::cout << "Test disabled on OpenGL." << std::endl;
1204 return;
1205 }
1206
Austin Kinross8b695ee2015-03-12 13:12:20 -07001207 GLint maxVaryings = 0;
1208 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1209
1210 // Generate shader code that uses gl_FragCoord, gl_PointCoord and gl_PointSize.
1211 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, true, true);
1212}
1213
Geoff Lange0cc2a42016-01-20 10:58:17 -05001214// Disabled because drivers are allowed to successfully compile shaders that have more than the
1215// maximum number of varyings. (http://anglebug.com/1296)
1216TEST_P(GLSLTest, DISABLED_MaxVaryingVec4PlusFragCoord)
Austin Kinross8b695ee2015-03-12 13:12:20 -07001217{
1218 GLint maxVaryings = 0;
1219 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1220
1221 // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
1222 // This test should fail, since we are really using (maxVaryings + 1) varyings.
1223 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, true, false, false, false);
1224}
1225
Geoff Lange0cc2a42016-01-20 10:58:17 -05001226// Disabled because drivers are allowed to successfully compile shaders that have more than the
1227// maximum number of varyings. (http://anglebug.com/1296)
1228TEST_P(GLSLTest, DISABLED_MaxVaryingVec4PlusPointCoord)
Austin Kinross8b695ee2015-03-12 13:12:20 -07001229{
1230 GLint maxVaryings = 0;
1231 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1232
1233 // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
1234 // This test should fail, since we are really using (maxVaryings + 1) varyings.
1235 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, true, false, false);
1236}
1237
Jamie Madillfa05f602015-05-07 13:47:11 -04001238TEST_P(GLSLTest, MaxVaryingVec3)
Austin Kinrossaf875522014-08-25 21:06:07 -07001239{
1240 GLint maxVaryings = 0;
1241 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1242
Austin Kinross8b695ee2015-03-12 13:12:20 -07001243 VaryingTestBase(0, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001244}
1245
Jamie Madillfa05f602015-05-07 13:47:11 -04001246TEST_P(GLSLTest, MaxVaryingVec3Array)
Austin Kinrossaf875522014-08-25 21:06:07 -07001247{
1248 GLint maxVaryings = 0;
1249 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1250
Austin Kinross8b695ee2015-03-12 13:12:20 -07001251 VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001252}
1253
Jamie Madillbee59e02014-10-02 10:44:18 -04001254// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -05001255TEST_P(GLSLTest, MaxVaryingVec3AndOneFloat)
Austin Kinrossaf875522014-08-25 21:06:07 -07001256{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001257 if (IsD3D9())
Jamie Madill9fc36822015-11-18 13:08:07 -05001258 {
1259 std::cout << "Test disabled on D3D9." << std::endl;
1260 return;
1261 }
1262
Austin Kinrossaf875522014-08-25 21:06:07 -07001263 GLint maxVaryings = 0;
1264 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1265
Austin Kinross8b695ee2015-03-12 13:12:20 -07001266 VaryingTestBase(1, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001267}
1268
Jamie Madillbee59e02014-10-02 10:44:18 -04001269// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -05001270TEST_P(GLSLTest, MaxVaryingVec3ArrayAndOneFloatArray)
Austin Kinrossaf875522014-08-25 21:06:07 -07001271{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001272 if (IsD3D9())
Jamie Madill9fc36822015-11-18 13:08:07 -05001273 {
1274 std::cout << "Test disabled on D3D9." << std::endl;
1275 return;
1276 }
1277
Austin Kinrossaf875522014-08-25 21:06:07 -07001278 GLint maxVaryings = 0;
1279 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1280
Austin Kinross8b695ee2015-03-12 13:12:20 -07001281 VaryingTestBase(0, 1, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001282}
1283
Jamie Madillbee59e02014-10-02 10:44:18 -04001284// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -05001285TEST_P(GLSLTest, TwiceMaxVaryingVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -07001286{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001287 if (IsD3D9())
Jamie Madill9fc36822015-11-18 13:08:07 -05001288 {
1289 std::cout << "Test disabled on D3D9." << std::endl;
1290 return;
1291 }
1292
Geoff Lange0cc2a42016-01-20 10:58:17 -05001293 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1294 {
1295 // TODO(geofflang): Figure out why this fails on NVIDIA's GLES driver
1296 std::cout << "Test disabled on OpenGL ES." << std::endl;
1297 return;
1298 }
1299
Geoff Lang69accbd2016-01-25 16:22:32 -05001300#if defined(__APPLE__)
1301 // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
1302 // (http://anglebug.com/1291)
Jamie Madill518b9fa2016-03-02 11:26:02 -05001303 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lang69accbd2016-01-25 16:22:32 -05001304 {
1305 std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
1306 return;
1307 }
1308#endif
1309
Austin Kinrossaf875522014-08-25 21:06:07 -07001310 GLint maxVaryings = 0;
1311 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1312
Austin Kinross8b695ee2015-03-12 13:12:20 -07001313 VaryingTestBase(0, 0, 2 * maxVaryings, 0, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001314}
1315
Jamie Madillbee59e02014-10-02 10:44:18 -04001316// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -05001317TEST_P(GLSLTest, MaxVaryingVec2Arrays)
Austin Kinrossaf875522014-08-25 21:06:07 -07001318{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001319 if (IsD3DSM3())
Jamie Madill9fc36822015-11-18 13:08:07 -05001320 {
1321 std::cout << "Test disabled on SM3." << std::endl;
1322 return;
1323 }
1324
Geoff Lange0cc2a42016-01-20 10:58:17 -05001325 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1326 {
1327 // TODO(geofflang): Figure out why this fails on NVIDIA's GLES driver
1328 std::cout << "Test disabled on OpenGL ES." << std::endl;
1329 return;
1330 }
1331
Geoff Lang69accbd2016-01-25 16:22:32 -05001332#if defined(__APPLE__)
1333 // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
1334 // (http://anglebug.com/1291)
Jamie Madill518b9fa2016-03-02 11:26:02 -05001335 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lang69accbd2016-01-25 16:22:32 -05001336 {
1337 std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
1338 return;
1339 }
1340#endif
1341
Austin Kinrossaf875522014-08-25 21:06:07 -07001342 GLint maxVaryings = 0;
1343 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1344
Austin Kinross8b695ee2015-03-12 13:12:20 -07001345 VaryingTestBase(0, 0, 0, maxVaryings, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001346}
1347
Geoff Lange0cc2a42016-01-20 10:58:17 -05001348// Disabled because drivers are allowed to successfully compile shaders that have more than the
1349// maximum number of varyings. (http://anglebug.com/1296)
1350TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec3)
Austin Kinrossaf875522014-08-25 21:06:07 -07001351{
1352 GLint maxVaryings = 0;
1353 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1354
Austin Kinross8b695ee2015-03-12 13:12:20 -07001355 VaryingTestBase(0, 0, 0, 0, maxVaryings + 1, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001356}
1357
Geoff Lange0cc2a42016-01-20 10:58:17 -05001358// Disabled because drivers are allowed to successfully compile shaders that have more than the
1359// maximum number of varyings. (http://anglebug.com/1296)
1360TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec3Array)
Austin Kinrossaf875522014-08-25 21:06:07 -07001361{
1362 GLint maxVaryings = 0;
1363 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1364
Austin Kinross8b695ee2015-03-12 13:12:20 -07001365 VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2 + 1, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001366}
1367
Geoff Lange0cc2a42016-01-20 10:58:17 -05001368// Disabled because drivers are allowed to successfully compile shaders that have more than the
1369// maximum number of varyings. (http://anglebug.com/1296)
1370TEST_P(GLSLTest, DISABLED_MaxVaryingVec3AndOneVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -07001371{
1372 GLint maxVaryings = 0;
1373 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1374
Austin Kinross8b695ee2015-03-12 13:12:20 -07001375 VaryingTestBase(0, 0, 1, 0, maxVaryings, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001376}
1377
Geoff Lange0cc2a42016-01-20 10:58:17 -05001378// Disabled because drivers are allowed to successfully compile shaders that have more than the
1379// maximum number of varyings. (http://anglebug.com/1296)
1380TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -07001381{
1382 GLint maxVaryings = 0;
1383 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1384
Austin Kinross8b695ee2015-03-12 13:12:20 -07001385 VaryingTestBase(0, 0, 2 * maxVaryings + 1, 0, 0, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001386}
1387
Geoff Lange0cc2a42016-01-20 10:58:17 -05001388// Disabled because drivers are allowed to successfully compile shaders that have more than the
1389// maximum number of varyings. (http://anglebug.com/1296)
1390TEST_P(GLSLTest, DISABLED_MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
Austin Kinrossaf875522014-08-25 21:06:07 -07001391{
1392 GLint maxVaryings = 0;
1393 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1394
Austin Kinross8b695ee2015-03-12 13:12:20 -07001395 VaryingTestBase(0, maxVaryings / 2 + 1, 0, 0, 0, 0, 0, maxVaryings / 2, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001396}
Geoff Langf60fab62014-11-24 11:21:20 -05001397
1398// Verify shader source with a fixed length that is less than the null-terminated length will compile.
Jamie Madillfa05f602015-05-07 13:47:11 -04001399TEST_P(GLSLTest, FixedShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -05001400{
1401 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1402
1403 const std::string appendGarbage = "abcasdfasdfasdfasdfasdf";
1404 const std::string source = "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" + appendGarbage;
1405 const char *sourceArray[1] = { source.c_str() };
Corentin Wallez973402f2015-05-11 13:42:22 -04001406 GLint lengths[1] = { static_cast<GLint>(source.length() - appendGarbage.length()) };
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001407 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001408 glCompileShader(shader);
1409
1410 GLint compileResult;
1411 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1412 EXPECT_NE(compileResult, 0);
1413}
1414
1415// Verify that a negative shader source length is treated as a null-terminated length.
Jamie Madillfa05f602015-05-07 13:47:11 -04001416TEST_P(GLSLTest, NegativeShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -05001417{
1418 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1419
1420 const char *sourceArray[1] = { "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" };
1421 GLint lengths[1] = { -10 };
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001422 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001423 glCompileShader(shader);
1424
1425 GLint compileResult;
1426 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1427 EXPECT_NE(compileResult, 0);
1428}
1429
Corentin Wallez9a9c0482016-04-12 10:36:25 -04001430// Check that having an invalid char after the "." doesn't cause an assert.
1431TEST_P(GLSLTest, InvalidFieldFirstChar)
1432{
1433 GLuint shader = glCreateShader(GL_VERTEX_SHADER);
1434 const char *source = "void main() {vec4 x; x.}";
1435 glShaderSource(shader, 1, &source, 0);
1436 glCompileShader(shader);
1437
1438 GLint compileResult;
1439 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1440 EXPECT_EQ(0, compileResult);
1441}
1442
Geoff Langf60fab62014-11-24 11:21:20 -05001443// Verify that a length array with mixed positive and negative values compiles.
Jamie Madillfa05f602015-05-07 13:47:11 -04001444TEST_P(GLSLTest, MixedShaderLengths)
Geoff Langf60fab62014-11-24 11:21:20 -05001445{
1446 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1447
1448 const char *sourceArray[] =
1449 {
1450 "void main()",
1451 "{",
1452 " gl_FragColor = vec4(0, 0, 0, 0);",
1453 "}",
1454 };
1455 GLint lengths[] =
1456 {
1457 -10,
1458 1,
Corentin Wallez973402f2015-05-11 13:42:22 -04001459 static_cast<GLint>(strlen(sourceArray[2])),
Geoff Langf60fab62014-11-24 11:21:20 -05001460 -1,
1461 };
1462 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
1463
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001464 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001465 glCompileShader(shader);
1466
1467 GLint compileResult;
1468 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1469 EXPECT_NE(compileResult, 0);
1470}
1471
1472// Verify that zero-length shader source does not affect shader compilation.
Jamie Madillfa05f602015-05-07 13:47:11 -04001473TEST_P(GLSLTest, ZeroShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -05001474{
1475 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1476
1477 const char *sourceArray[] =
1478 {
1479 "adfasdf",
1480 "34534",
1481 "void main() { gl_FragColor = vec4(0, 0, 0, 0); }",
1482 "",
1483 "asdfasdfsdsdf",
1484 };
1485 GLint lengths[] =
1486 {
1487 0,
1488 0,
1489 -1,
1490 0,
1491 0,
1492 };
1493 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
1494
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001495 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001496 glCompileShader(shader);
1497
1498 GLint compileResult;
1499 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1500 EXPECT_NE(compileResult, 0);
1501}
Jamie Madill21c1e452014-12-29 11:33:41 -05001502
1503// Tests that bad index expressions don't crash ANGLE's translator.
1504// https://code.google.com/p/angleproject/issues/detail?id=857
Jamie Madillfa05f602015-05-07 13:47:11 -04001505TEST_P(GLSLTest, BadIndexBug)
Jamie Madill21c1e452014-12-29 11:33:41 -05001506{
1507 const std::string &fragmentShaderSourceVec =
1508 "precision mediump float;\n"
1509 "uniform vec4 uniformVec;\n"
1510 "void main()\n"
1511 "{\n"
1512 " gl_FragColor = vec4(uniformVec[int()]);\n"
1513 "}";
1514
1515 GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceVec);
1516 EXPECT_EQ(0u, shader);
1517
1518 if (shader != 0)
1519 {
1520 glDeleteShader(shader);
1521 }
1522
1523 const std::string &fragmentShaderSourceMat =
1524 "precision mediump float;\n"
1525 "uniform mat4 uniformMat;\n"
1526 "void main()\n"
1527 "{\n"
1528 " gl_FragColor = vec4(uniformMat[int()]);\n"
1529 "}";
1530
1531 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceMat);
1532 EXPECT_EQ(0u, shader);
1533
1534 if (shader != 0)
1535 {
1536 glDeleteShader(shader);
1537 }
1538
1539 const std::string &fragmentShaderSourceArray =
1540 "precision mediump float;\n"
1541 "uniform vec4 uniformArray;\n"
1542 "void main()\n"
1543 "{\n"
1544 " gl_FragColor = vec4(uniformArray[int()]);\n"
1545 "}";
1546
1547 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceArray);
1548 EXPECT_EQ(0u, shader);
1549
1550 if (shader != 0)
1551 {
1552 glDeleteShader(shader);
1553 }
Jamie Madill37997142015-01-28 10:06:34 -05001554}
1555
Jamie Madill2e295e22015-04-29 10:41:33 -04001556// Test that structs defined in uniforms are translated correctly.
Jamie Madillfa05f602015-05-07 13:47:11 -04001557TEST_P(GLSLTest, StructSpecifiersUniforms)
Jamie Madill2e295e22015-04-29 10:41:33 -04001558{
1559 const std::string fragmentShaderSource = SHADER_SOURCE
1560 (
1561 precision mediump float;
1562
1563 uniform struct S { float field;} s;
1564
1565 void main()
1566 {
1567 gl_FragColor = vec4(1, 0, 0, 1);
1568 gl_FragColor.a += s.field;
1569 }
1570 );
1571
1572 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1573 EXPECT_NE(0u, program);
1574}
Jamie Madill55def582015-05-04 11:24:57 -04001575
1576// Test that gl_DepthRange is not stored as a uniform location. Since uniforms
1577// beginning with "gl_" are filtered out by our validation logic, we must
1578// bypass the validation to test the behaviour of the implementation.
1579// (note this test is still Impl-independent)
Jamie Madillfa05f602015-05-07 13:47:11 -04001580TEST_P(GLSLTest, DepthRangeUniforms)
Jamie Madill55def582015-05-04 11:24:57 -04001581{
1582 const std::string fragmentShaderSource = SHADER_SOURCE
1583 (
1584 precision mediump float;
1585
1586 void main()
1587 {
1588 gl_FragColor = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff, 1);
1589 }
1590 );
1591
1592 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1593 EXPECT_NE(0u, program);
1594
1595 // dive into the ANGLE internals, so we can bypass validation.
1596 gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
1597 gl::Program *glProgram = context->getProgram(program);
1598 GLint nearIndex = glProgram->getUniformLocation("gl_DepthRange.near");
1599 EXPECT_EQ(-1, nearIndex);
1600
1601 // Test drawing does not throw an exception.
1602 drawQuad(program, "inputAttribute", 0.5f);
1603
1604 EXPECT_GL_NO_ERROR();
1605
1606 glDeleteProgram(program);
1607}
Jamie Madill4052dfc2015-05-06 15:18:49 -04001608
1609// Covers the WebGL test 'glsl/bugs/pow-of-small-constant-in-user-defined-function'
1610// See https://code.google.com/p/angleproject/issues/detail?id=851
1611// TODO(jmadill): ANGLE constant folding can fix this
Jamie Madillfa05f602015-05-07 13:47:11 -04001612TEST_P(GLSLTest, DISABLED_PowOfSmallConstant)
Jamie Madill4052dfc2015-05-06 15:18:49 -04001613{
1614 const std::string &fragmentShaderSource = SHADER_SOURCE
1615 (
1616 precision highp float;
1617
1618 float fun(float arg)
1619 {
1620 // These values are still easily within the highp range.
1621 // The minimum range in terms of 10's exponent is around -19 to 19, and IEEE-754 single precision range is higher than that.
1622 return pow(arg, 2.0);
1623 }
1624
1625 void main()
1626 {
1627 // Note that the bug did not reproduce if an uniform was passed to the function instead of a constant,
1628 // or if the expression was moved outside the user-defined function.
1629 const float a = 1.0e-6;
1630 float b = 1.0e12 * fun(a);
1631 if (abs(b - 1.0) < 0.01)
1632 {
1633 gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); // green
1634 }
1635 else
1636 {
1637 gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // red
1638 }
1639 }
1640 );
1641
1642 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1643 EXPECT_NE(0u, program);
1644
1645 drawQuad(program, "inputAttribute", 0.5f);
1646 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1647 EXPECT_GL_NO_ERROR();
1648}
Jamie Madillfa05f602015-05-07 13:47:11 -04001649
Cooper Partina5ef8d82015-08-19 14:52:21 -07001650// Test that fragment shaders which contain non-constant loop indexers and compiled for FL9_3 and
1651// below
1652// fail with a specific error message.
1653// Additionally test that the same fragment shader compiles successfully with feature levels greater
1654// than FL9_3.
1655TEST_P(GLSLTest, LoopIndexingValidation)
1656{
1657 const std::string fragmentShaderSource = SHADER_SOURCE
1658 (
1659 precision mediump float;
1660
1661 uniform float loopMax;
1662
1663 void main()
1664 {
1665 gl_FragColor = vec4(1, 0, 0, 1);
1666 for (float l = 0.0; l < loopMax; l++)
1667 {
1668 if (loopMax > 3.0)
1669 {
1670 gl_FragColor.a += 0.1;
1671 }
1672 }
1673 }
1674 );
1675
1676 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1677
1678 const char *sourceArray[1] = {fragmentShaderSource.c_str()};
1679 glShaderSource(shader, 1, sourceArray, nullptr);
1680 glCompileShader(shader);
1681
1682 GLint compileResult;
1683 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1684
1685 // If the test is configured to run limited to Feature Level 9_3, then it is
1686 // assumed that shader compilation will fail with an expected error message containing
1687 // "Loop index cannot be compared with non-constant expression"
Olli Etuaho814a54d2015-08-27 16:23:09 +03001688 if ((GetParam() == ES2_D3D11_FL9_3() || GetParam() == ES2_D3D9()))
Cooper Partina5ef8d82015-08-19 14:52:21 -07001689 {
1690 if (compileResult != 0)
1691 {
1692 FAIL() << "Shader compilation succeeded, expected failure";
1693 }
1694 else
1695 {
1696 GLint infoLogLength;
1697 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
1698
1699 std::string infoLog;
1700 infoLog.resize(infoLogLength);
1701 glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
1702
1703 if (infoLog.find("Loop index cannot be compared with non-constant expression") ==
1704 std::string::npos)
1705 {
1706 FAIL() << "Shader compilation failed with unexpected error message";
1707 }
1708 }
1709 }
1710 else
1711 {
1712 EXPECT_NE(0, compileResult);
1713 }
1714
1715 if (shader != 0)
1716 {
1717 glDeleteShader(shader);
1718 }
1719}
1720
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001721// Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1722// can actually be used.
1723TEST_P(GLSLTest, VerifyMaxVertexUniformVectors)
1724{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001725 int maxUniforms = 10000;
1726 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1727 EXPECT_GL_NO_ERROR();
1728 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl;
1729
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001730 CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, 0, 0, true);
1731}
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001732
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001733// Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1734// can actually be used along with the maximum number of texture samplers.
1735TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsWithSamplers)
1736{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001737 if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1738 GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1739 {
1740 std::cout << "Test disabled on OpenGL." << std::endl;
1741 return;
1742 }
1743
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001744 int maxUniforms = 10000;
1745 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1746 EXPECT_GL_NO_ERROR();
1747 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001748
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001749 int maxTextureImageUnits = 0;
1750 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001751
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001752 CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, maxTextureImageUnits, 0, true);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001753}
1754
1755// Tests that the maximum uniforms count + 1 from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1756// fails shader compilation.
1757TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsExceeded)
1758{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001759 int maxUniforms = 10000;
1760 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1761 EXPECT_GL_NO_ERROR();
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001762 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS + 1 = " << maxUniforms + 1 << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001763
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001764 CompileGLSLWithUniformsAndSamplers(maxUniforms + 1, 0, 0, 0, false);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001765}
1766
1767// Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1768// can actually be used.
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001769TEST_P(GLSLTest, VerifyMaxFragmentUniformVectors)
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001770{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001771 int maxUniforms = 10000;
1772 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1773 EXPECT_GL_NO_ERROR();
1774 std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS = " << maxUniforms << std::endl;
1775
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001776 CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, 0, true);
1777}
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001778
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001779// Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1780// can actually be used along with the maximum number of texture samplers.
1781TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsWithSamplers)
1782{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001783 if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1784 GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1785 {
1786 std::cout << "Test disabled on OpenGL." << std::endl;
1787 return;
1788 }
1789
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001790 int maxUniforms = 10000;
1791 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1792 EXPECT_GL_NO_ERROR();
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001793
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001794 int maxTextureImageUnits = 0;
1795 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001796
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001797 CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, maxTextureImageUnits, true);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001798}
1799
1800// Tests that the maximum uniforms count + 1 from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1801// fails shader compilation.
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001802TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsExceeded)
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001803{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001804 int maxUniforms = 10000;
1805 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1806 EXPECT_GL_NO_ERROR();
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001807 std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS + 1 = " << maxUniforms + 1
1808 << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001809
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001810 CompileGLSLWithUniformsAndSamplers(0, maxUniforms + 1, 0, 0, false);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001811}
1812
Olli Etuahobe59c2f2016-03-07 11:32:34 +02001813// Test that two constructors which have vec4 and mat2 parameters get disambiguated (issue in
1814// HLSL).
1815TEST_P(GLSLTest_ES3, AmbiguousConstructorCall2x2)
1816{
1817 const std::string fragmentShaderSource =
1818 "#version 300 es\n"
1819 "precision highp float;\n"
1820 "out vec4 my_FragColor;\n"
1821 "void main()\n"
1822 "{\n"
1823 " my_FragColor = vec4(0.0);\n"
1824 "}";
1825
1826 const std::string vertexShaderSource =
1827 "#version 300 es\n"
1828 "precision highp float;\n"
1829 "in vec4 a_vec;\n"
1830 "in mat2 a_mat;\n"
1831 "void main()\n"
1832 "{\n"
1833 " gl_Position = vec4(a_vec) + vec4(a_mat);\n"
1834 "}";
1835
1836 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1837 EXPECT_NE(0u, program);
1838}
1839
1840// Test that two constructors which have mat2x3 and mat3x2 parameters get disambiguated.
1841// This was suspected to be an issue in HLSL, but HLSL seems to be able to natively choose between
1842// the function signatures in this case.
1843TEST_P(GLSLTest_ES3, AmbiguousConstructorCall2x3)
1844{
1845 const std::string fragmentShaderSource =
1846 "#version 300 es\n"
1847 "precision highp float;\n"
1848 "out vec4 my_FragColor;\n"
1849 "void main()\n"
1850 "{\n"
1851 " my_FragColor = vec4(0.0);\n"
1852 "}";
1853
1854 const std::string vertexShaderSource =
1855 "#version 300 es\n"
1856 "precision highp float;\n"
1857 "in mat3x2 a_matA;\n"
1858 "in mat2x3 a_matB;\n"
1859 "void main()\n"
1860 "{\n"
1861 " gl_Position = vec4(a_matA) + vec4(a_matB);\n"
1862 "}";
1863
1864 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1865 EXPECT_NE(0u, program);
1866}
1867
1868// Test that two functions which have vec4 and mat2 parameters get disambiguated (issue in HLSL).
1869TEST_P(GLSLTest_ES3, AmbiguousFunctionCall2x2)
1870{
1871 const std::string fragmentShaderSource =
1872 "#version 300 es\n"
1873 "precision highp float;\n"
1874 "out vec4 my_FragColor;\n"
1875 "void main()\n"
1876 "{\n"
1877 " my_FragColor = vec4(0.0);\n"
1878 "}";
1879
1880 const std::string vertexShaderSource =
1881 "#version 300 es\n"
1882 "precision highp float;\n"
1883 "in vec4 a_vec;\n"
1884 "in mat2 a_mat;\n"
1885 "vec4 foo(vec4 a)\n"
1886 "{\n"
1887 " return a;\n"
1888 "}\n"
1889 "vec4 foo(mat2 a)\n"
1890 "{\n"
1891 " return vec4(a[0][0]);\n"
1892 "}\n"
1893 "void main()\n"
1894 "{\n"
1895 " gl_Position = foo(a_vec) + foo(a_mat);\n"
1896 "}";
1897
1898 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1899 EXPECT_NE(0u, program);
1900}
1901
1902// Test that an user-defined function with a large number of float4 parameters doesn't fail due to
1903// the function name being too long.
1904TEST_P(GLSLTest_ES3, LargeNumberOfFloat4Parameters)
1905{
1906 const std::string fragmentShaderSource =
1907 "#version 300 es\n"
1908 "precision highp float;\n"
1909 "out vec4 my_FragColor;\n"
1910 "void main()\n"
1911 "{\n"
1912 " my_FragColor = vec4(0.0);\n"
1913 "}";
1914
1915 std::stringstream vertexShaderStream;
1916 const unsigned int paramCount = 1024u;
1917
1918 vertexShaderStream << "#version 300 es\n"
1919 "precision highp float;\n"
1920 "in vec4 a_vec;\n"
1921 "vec4 lotsOfVec4Parameters(";
1922 for (unsigned int i = 0; i < paramCount; ++i)
1923 {
1924 vertexShaderStream << "vec4 a" << i << ", ";
1925 }
1926 vertexShaderStream << "vec4 aLast)\n"
1927 "{\n"
1928 " return ";
1929 for (unsigned int i = 0; i < paramCount; ++i)
1930 {
1931 vertexShaderStream << "a" << i << " + ";
1932 }
1933 vertexShaderStream << "aLast;\n"
1934 "}\n"
1935 "void main()\n"
1936 "{\n"
1937 " gl_Position = lotsOfVec4Parameters(";
1938 for (unsigned int i = 0; i < paramCount; ++i)
1939 {
1940 vertexShaderStream << "a_vec, ";
1941 }
1942 vertexShaderStream << "a_vec);\n"
1943 "}";
1944
1945 GLuint program = CompileProgram(vertexShaderStream.str(), fragmentShaderSource);
1946 EXPECT_NE(0u, program);
1947}
1948
Olli Etuahod4f4c112016-04-15 15:11:24 +03001949// This test was written specifically to stress DeferGlobalInitializers AST transformation.
1950// Test a shader where a global constant array is initialized with an expression containing array
1951// indexing. This initializer is tricky to constant fold, so if it's not constant folded it needs to
1952// be handled in a way that doesn't generate statements in the global scope in HLSL output.
1953// Also includes multiple array initializers in one declaration, where only the second one has
1954// array indexing. This makes sure that the qualifier for the declaration is set correctly if
1955// transformations are applied to the declaration also in the case of ESSL output.
1956TEST_P(GLSLTest_ES3, InitGlobalArrayWithArrayIndexing)
1957{
Yuly Novikov41db2242016-06-25 00:14:28 -04001958 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1428 is fixed
1959 if (IsAndroid() && IsAdreno() && IsOpenGLES())
1960 {
1961 std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
1962 return;
1963 }
1964
Olli Etuahod4f4c112016-04-15 15:11:24 +03001965 const std::string vertexShaderSource =
1966 "#version 300 es\n"
1967 "precision highp float;\n"
1968 "in vec4 a_vec;\n"
1969 "void main()\n"
1970 "{\n"
1971 " gl_Position = vec4(a_vec);\n"
1972 "}";
1973
1974 const std::string fragmentShaderSource =
1975 "#version 300 es\n"
1976 "precision highp float;\n"
1977 "out vec4 my_FragColor;\n"
1978 "const highp float f[2] = float[2](0.1, 0.2);\n"
1979 "const highp float[2] g = float[2](0.3, 0.4), h = float[2](0.5, f[1]);\n"
1980 "void main()\n"
1981 "{\n"
1982 " my_FragColor = vec4(h[1]);\n"
1983 "}";
1984
1985 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1986 EXPECT_NE(0u, program);
1987}
1988
Corentin Wallez419bfc92016-06-28 10:54:45 -07001989// Test that index-constant sampler array indexing is supported.
1990TEST_P(GLSLTest, IndexConstantSamplerArrayIndexing)
1991{
1992 if (IsD3D11_FL93()) {
1993 std::cout << "Test skipped on D3D11 FL 9.3." << std::endl;
1994 return;
1995 }
1996
1997 const std::string vertexShaderSource =
1998 "attribute vec4 vPosition;\n"
1999 "void main()\n"
2000 "{\n"
2001 " gl_Position = vPosition;\n"
2002 "}";
2003
2004 const std::string fragmentShaderSource =
2005 "precision mediump float;\n"
2006 "uniform sampler2D uni[2];\n"
2007 "\n"
2008 "float zero(int x)\n"
2009 "{\n"
2010 " return float(x) - float(x);\n"
2011 "}\n"
2012 "\n"
2013 "void main()\n"
2014 "{\n"
2015 " vec4 c = vec4(0,0,0,0);\n"
2016 " for (int ii = 1; ii < 3; ++ii) {\n"
2017 " if (c.x > 255.0) {\n"
2018 " c.x = 255.0 + zero(ii);\n"
2019 " break;\n"
2020 " }\n"
2021 // Index the sampler array with a predictable loop index (index-constant) as opposed to
2022 // a true constant. This is valid in OpenGL ES but isn't in many Desktop OpenGL versions,
2023 // without an extension.
2024 " c += texture2D(uni[ii - 1], vec2(0.5, 0.5));\n"
2025 " }\n"
2026 " gl_FragColor = c;\n"
2027 "}";
2028
2029 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
2030 EXPECT_NE(0u, program);
2031}
2032
Corentin Wallezb00dcee2016-07-11 17:42:58 -04002033// Test that the #pragma directive is supported and doesn't trigger a compilation failure on the
2034// native driver. The only pragma that gets passed to the OpenGL driver is "invariant" but we don't
2035// want to test its behavior, so don't use any varyings.
2036TEST_P(GLSLTest, PragmaDirective)
2037{
2038 const std::string vertexShaderSource =
2039 "#pragma STDGL invariant(all)\n"
2040 "void main()\n"
2041 "{\n"
2042 " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
2043 "}\n";
2044
2045 const std::string fragmentShaderSource =
2046 "precision mediump float;\n"
2047 "void main()\n"
2048 "{\n"
2049 " gl_FragColor = vec4(1.0);\n"
2050 "}\n";
2051
2052 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
2053 EXPECT_NE(0u, program);
2054}
2055
Olli Etuahoe1d199b2016-07-19 17:14:27 +03002056// Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9).
2057// The function call that returns the array needs to be evaluated after ++j for the expression to
2058// return the correct value (true).
2059TEST_P(GLSLTest_ES3, SequenceOperatorEvaluationOrderArray)
2060{
2061 const std::string &fragmentShaderSource =
2062 "#version 300 es\n"
2063 "precision mediump float;\n"
2064 "out vec4 my_FragColor; \n"
2065 "int[2] func(int param) {\n"
2066 " return int[2](param, param);\n"
2067 "}\n"
2068 "void main() {\n"
2069 " int a[2]; \n"
2070 " for (int i = 0; i < 2; ++i) {\n"
2071 " a[i] = 1;\n"
2072 " }\n"
2073 " int j = 0; \n"
2074 " bool result = ((++j), (a == func(j)));\n"
2075 " my_FragColor = vec4(0.0, (result ? 1.0 : 0.0), 0.0, 1.0);\n"
2076 "}\n";
2077
2078 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
2079 ASSERT_NE(0u, program);
2080
2081 drawQuad(program, "inputAttribute", 0.5f);
2082
2083 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2084}
2085
2086// Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9).
2087// The short-circuiting expression needs to be evaluated after ++j for the expression to return the
2088// correct value (true).
2089TEST_P(GLSLTest_ES3, SequenceOperatorEvaluationOrderShortCircuit)
2090{
2091 const std::string &fragmentShaderSource =
2092 "#version 300 es\n"
2093 "precision mediump float;\n"
2094 "out vec4 my_FragColor; \n"
2095 "void main() {\n"
2096 " int j = 0; \n"
2097 " bool result = ((++j), (j == 1 ? true : (++j == 3)));\n"
2098 " my_FragColor = vec4(0.0, ((result && j == 1) ? 1.0 : 0.0), 0.0, 1.0);\n"
2099 "}\n";
2100
2101 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
2102 ASSERT_NE(0u, program);
2103
2104 drawQuad(program, "inputAttribute", 0.5f);
2105
2106 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2107}
2108
Olli Etuaho7da98502016-07-20 18:45:09 +03002109// Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9).
2110// Indexing the vector needs to be evaluated after func() for the right result.
2111TEST_P(GLSLTest_ES3, SequenceOperatorEvaluationOrderDynamicVectorIndexingInLValue)
2112{
2113 const std::string &fragmentShaderSource =
2114 "#version 300 es\n"
2115 "precision mediump float;\n"
2116 "out vec4 my_FragColor;\n"
2117 "uniform int u_zero;\n"
2118 "int sideEffectCount = 0;\n"
2119 "float func() {\n"
2120 " ++sideEffectCount;\n"
2121 " return -1.0;\n"
2122 "}\n"
2123 "void main() {\n"
2124 " vec4 v = vec4(0.0, 2.0, 4.0, 6.0); \n"
2125 " float f = (func(), (++v[u_zero + sideEffectCount]));\n"
2126 " bool green = abs(f - 3.0) < 0.01 && abs(v[1] - 3.0) < 0.01 && sideEffectCount == 1;\n"
2127 " my_FragColor = vec4(0.0, (green ? 1.0 : 0.0), 0.0, 1.0);\n"
2128 "}\n";
2129
2130 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
2131 ASSERT_NE(0u, program);
2132
2133 drawQuad(program, "inputAttribute", 0.5f);
2134
2135 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2136}
2137
Jamie Madillfa05f602015-05-07 13:47:11 -04002138// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Lange0cc2a42016-01-20 10:58:17 -05002139ANGLE_INSTANTIATE_TEST(GLSLTest,
2140 ES2_D3D9(),
2141 ES2_D3D11(),
2142 ES2_D3D11_FL9_3(),
2143 ES2_OPENGL(),
2144 ES3_OPENGL(),
2145 ES2_OPENGLES(),
2146 ES3_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04002147
2148// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Lange0cc2a42016-01-20 10:58:17 -05002149ANGLE_INSTANTIATE_TEST(GLSLTest_ES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());