blob: f8b77a9ed80f41fba9d4ad59657477ace25a76f2 [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"
Jamie Madill1048e432016-07-23 18:51:28 -040011#include "test_utils/gl_raii.h"
Jamie Madill55def582015-05-04 11:24:57 -040012
Jamie Madillfa05f602015-05-07 13:47:11 -040013using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070014
Jamie Madill2bf8b372014-06-16 17:18:51 -040015class GLSLTest : public ANGLETest
Jamie Madill96509e42014-05-29 14:33:27 -040016{
Jamie Madillfa05f602015-05-07 13:47:11 -040017 protected:
18 GLSLTest()
Jamie Madill96509e42014-05-29 14:33:27 -040019 {
20 setWindowWidth(128);
21 setWindowHeight(128);
22 setConfigRedBits(8);
23 setConfigGreenBits(8);
24 setConfigBlueBits(8);
25 setConfigAlphaBits(8);
26 }
Jamie Madillbfa91f42014-06-05 15:45:18 -040027
28 virtual void SetUp()
29 {
30 ANGLETest::SetUp();
31
Jamie Madill2bf8b372014-06-16 17:18:51 -040032 mSimpleVSSource = SHADER_SOURCE
Jamie Madillbfa91f42014-06-05 15:45:18 -040033 (
34 attribute vec4 inputAttribute;
35 void main()
36 {
37 gl_Position = inputAttribute;
38 }
39 );
40 }
41
Austin Kinrossaf875522014-08-25 21:06:07 -070042 std::string GenerateVaryingType(GLint vectorSize)
43 {
44 char varyingType[10];
45
46 if (vectorSize == 1)
47 {
48 sprintf(varyingType, "float");
49 }
50 else
51 {
52 sprintf(varyingType, "vec%d", vectorSize);
53 }
54
55 return std::string(varyingType);
56 }
57
58 std::string GenerateVectorVaryingDeclaration(GLint vectorSize, GLint arraySize, GLint id)
59 {
60 char buff[100];
61
62 if (arraySize == 1)
63 {
64 sprintf(buff, "varying %s v%d;\n", GenerateVaryingType(vectorSize).c_str(), id);
65 }
66 else
67 {
68 sprintf(buff, "varying %s v%d[%d];\n", GenerateVaryingType(vectorSize).c_str(), id, arraySize);
69 }
70
71 return std::string(buff);
72 }
73
74 std::string GenerateVectorVaryingSettingCode(GLint vectorSize, GLint arraySize, GLint id)
75 {
76 std::string returnString;
77 char buff[100];
78
79 if (arraySize == 1)
80 {
81 sprintf(buff, "\t v%d = %s(1.0);\n", id, GenerateVaryingType(vectorSize).c_str());
82 returnString += buff;
83 }
84 else
85 {
86 for (int i = 0; i < arraySize; i++)
87 {
88 sprintf(buff, "\t v%d[%d] = %s(1.0);\n", id, i, GenerateVaryingType(vectorSize).c_str());
89 returnString += buff;
90 }
91 }
92
93 return returnString;
94 }
95
96 std::string GenerateVectorVaryingUseCode(GLint arraySize, GLint id)
97 {
98 if (arraySize == 1)
99 {
100 char buff[100];
101 sprintf(buff, "v%d + ", id);
102 return std::string(buff);
103 }
104 else
105 {
106 std::string returnString;
107 for (int i = 0; i < arraySize; i++)
108 {
109 char buff[100];
110 sprintf(buff, "v%d[%d] + ", id, i);
111 returnString += buff;
112 }
113 return returnString;
114 }
115 }
116
Austin Kinross8b695ee2015-03-12 13:12:20 -0700117 void GenerateGLSLWithVaryings(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
118 GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize,
119 std::string* fragmentShader, std::string* vertexShader)
Austin Kinrossaf875522014-08-25 21:06:07 -0700120 {
121 // Generate a string declaring the varyings, to share between the fragment shader and the vertex shader.
122 std::string varyingDeclaration;
123
124 unsigned int varyingCount = 0;
125
126 for (GLint i = 0; i < floatCount; i++)
127 {
128 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 1, varyingCount);
129 varyingCount += 1;
130 }
131
132 for (GLint i = 0; i < floatArrayCount; i++)
133 {
134 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 2, varyingCount);
135 varyingCount += 1;
136 }
137
138 for (GLint i = 0; i < vec2Count; i++)
139 {
140 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 1, varyingCount);
141 varyingCount += 1;
142 }
143
144 for (GLint i = 0; i < vec2ArrayCount; i++)
145 {
146 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 2, varyingCount);
147 varyingCount += 1;
148 }
149
150 for (GLint i = 0; i < vec3Count; i++)
151 {
152 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 1, varyingCount);
153 varyingCount += 1;
154 }
155
156 for (GLint i = 0; i < vec3ArrayCount; i++)
157 {
158 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 2, varyingCount);
159 varyingCount += 1;
160 }
161
Austin Kinross8b695ee2015-03-12 13:12:20 -0700162 for (GLint i = 0; i < vec4Count; i++)
163 {
164 varyingDeclaration += GenerateVectorVaryingDeclaration(4, 1, varyingCount);
165 varyingCount += 1;
166 }
167
168 for (GLint i = 0; i < vec4ArrayCount; i++)
169 {
170 varyingDeclaration += GenerateVectorVaryingDeclaration(4, 2, varyingCount);
171 varyingCount += 1;
172 }
173
Austin Kinrossaf875522014-08-25 21:06:07 -0700174 // Generate the vertex shader
175 vertexShader->clear();
176 vertexShader->append(varyingDeclaration);
177 vertexShader->append("\nvoid main()\n{\n");
178
179 unsigned int currentVSVarying = 0;
180
181 for (GLint i = 0; i < floatCount; i++)
182 {
183 vertexShader->append(GenerateVectorVaryingSettingCode(1, 1, currentVSVarying));
184 currentVSVarying += 1;
185 }
186
187 for (GLint i = 0; i < floatArrayCount; i++)
188 {
189 vertexShader->append(GenerateVectorVaryingSettingCode(1, 2, currentVSVarying));
190 currentVSVarying += 1;
191 }
192
193 for (GLint i = 0; i < vec2Count; i++)
194 {
195 vertexShader->append(GenerateVectorVaryingSettingCode(2, 1, currentVSVarying));
196 currentVSVarying += 1;
197 }
198
199 for (GLint i = 0; i < vec2ArrayCount; i++)
200 {
201 vertexShader->append(GenerateVectorVaryingSettingCode(2, 2, currentVSVarying));
202 currentVSVarying += 1;
203 }
204
205 for (GLint i = 0; i < vec3Count; i++)
206 {
207 vertexShader->append(GenerateVectorVaryingSettingCode(3, 1, currentVSVarying));
208 currentVSVarying += 1;
209 }
210
211 for (GLint i = 0; i < vec3ArrayCount; i++)
212 {
213 vertexShader->append(GenerateVectorVaryingSettingCode(3, 2, currentVSVarying));
214 currentVSVarying += 1;
215 }
216
Austin Kinross8b695ee2015-03-12 13:12:20 -0700217 for (GLint i = 0; i < vec4Count; i++)
218 {
219 vertexShader->append(GenerateVectorVaryingSettingCode(4, 1, currentVSVarying));
220 currentVSVarying += 1;
221 }
222
223 for (GLint i = 0; i < vec4ArrayCount; i++)
224 {
225 vertexShader->append(GenerateVectorVaryingSettingCode(4, 2, currentVSVarying));
226 currentVSVarying += 1;
227 }
228
229 if (usePointSize)
230 {
231 vertexShader->append("gl_PointSize = 1.0;\n");
232 }
233
Austin Kinrossaf875522014-08-25 21:06:07 -0700234 vertexShader->append("}\n");
235
236 // Generate the fragment shader
237 fragmentShader->clear();
238 fragmentShader->append("precision highp float;\n");
239 fragmentShader->append(varyingDeclaration);
240 fragmentShader->append("\nvoid main() \n{ \n\tvec4 retColor = vec4(0,0,0,0);\n");
241
242 unsigned int currentFSVarying = 0;
243
244 // Make use of the float varyings
245 fragmentShader->append("\tretColor += vec4(");
246
247 for (GLint i = 0; i < floatCount; i++)
248 {
249 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
250 currentFSVarying += 1;
251 }
252
253 for (GLint i = 0; i < floatArrayCount; i++)
254 {
255 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
256 currentFSVarying += 1;
257 }
258
259 fragmentShader->append("0.0, 0.0, 0.0, 0.0);\n");
260
261 // Make use of the vec2 varyings
262 fragmentShader->append("\tretColor += vec4(");
263
264 for (GLint i = 0; i < vec2Count; i++)
265 {
266 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
267 currentFSVarying += 1;
268 }
269
270 for (GLint i = 0; i < vec2ArrayCount; i++)
271 {
272 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
273 currentFSVarying += 1;
274 }
275
276 fragmentShader->append("vec2(0.0, 0.0), 0.0, 0.0);\n");
277
278 // Make use of the vec3 varyings
279 fragmentShader->append("\tretColor += vec4(");
280
281 for (GLint i = 0; i < vec3Count; i++)
282 {
283 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
284 currentFSVarying += 1;
285 }
286
287 for (GLint i = 0; i < vec3ArrayCount; i++)
288 {
289 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
290 currentFSVarying += 1;
291 }
292
293 fragmentShader->append("vec3(0.0, 0.0, 0.0), 0.0);\n");
Austin Kinross8b695ee2015-03-12 13:12:20 -0700294
295 // Make use of the vec4 varyings
296 fragmentShader->append("\tretColor += ");
297
298 for (GLint i = 0; i < vec4Count; i++)
299 {
300 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
301 currentFSVarying += 1;
302 }
303
304 for (GLint i = 0; i < vec4ArrayCount; i++)
305 {
306 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
307 currentFSVarying += 1;
308 }
309
310 fragmentShader->append("vec4(0.0, 0.0, 0.0, 0.0);\n");
311
312 // Set gl_FragColor, and use special variables if requested
313 fragmentShader->append("\tgl_FragColor = retColor");
314
315 if (useFragCoord)
316 {
317 fragmentShader->append(" + gl_FragCoord");
318 }
319
320 if (usePointCoord)
321 {
322 fragmentShader->append(" + vec4(gl_PointCoord, 0.0, 0.0)");
323 }
324
325 fragmentShader->append(";\n}");
326 }
327
328 void VaryingTestBase(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
329 GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize, bool expectSuccess)
330 {
331 std::string fragmentShaderSource;
332 std::string vertexShaderSource;
333
334 GenerateGLSLWithVaryings(floatCount, floatArrayCount, vec2Count, vec2ArrayCount, vec3Count, vec3ArrayCount,
335 vec4Count, vec4ArrayCount, useFragCoord, usePointCoord, usePointSize,
336 &fragmentShaderSource, &vertexShaderSource);
337
338 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
339
340 if (expectSuccess)
341 {
342 EXPECT_NE(0u, program);
343 }
344 else
345 {
346 EXPECT_EQ(0u, program);
347 }
Austin Kinrossaf875522014-08-25 21:06:07 -0700348 }
349
Austin Kinross7a3e8e22015-10-08 15:50:06 -0700350 void CompileGLSLWithUniformsAndSamplers(GLint vertexUniformCount,
351 GLint fragmentUniformCount,
352 GLint vertexSamplersCount,
353 GLint fragmentSamplersCount,
354 bool expectSuccess)
355 {
356 std::stringstream vertexShader;
357 std::stringstream fragmentShader;
358
359 // Generate the vertex shader
360 vertexShader << "precision mediump float;\n";
361
362 for (int i = 0; i < vertexUniformCount; i++)
363 {
364 vertexShader << "uniform vec4 v" << i << ";\n";
365 }
366
367 for (int i = 0; i < vertexSamplersCount; i++)
368 {
369 vertexShader << "uniform sampler2D s" << i << ";\n";
370 }
371
372 vertexShader << "void main()\n{\n";
373
374 for (int i = 0; i < vertexUniformCount; i++)
375 {
376 vertexShader << " gl_Position += v" << i << ";\n";
377 }
378
379 for (int i = 0; i < vertexSamplersCount; i++)
380 {
381 vertexShader << " gl_Position += texture2D(s" << i << ", vec2(0.0, 0.0));\n";
382 }
383
384 if (vertexUniformCount == 0 && vertexSamplersCount == 0)
385 {
386 vertexShader << " gl_Position = vec4(0.0);\n";
387 }
388
389 vertexShader << "}\n";
390
391 // Generate the fragment shader
392 fragmentShader << "precision mediump float;\n";
393
394 for (int i = 0; i < fragmentUniformCount; i++)
395 {
396 fragmentShader << "uniform vec4 v" << i << ";\n";
397 }
398
399 for (int i = 0; i < fragmentSamplersCount; i++)
400 {
401 fragmentShader << "uniform sampler2D s" << i << ";\n";
402 }
403
404 fragmentShader << "void main()\n{\n";
405
406 for (int i = 0; i < fragmentUniformCount; i++)
407 {
408 fragmentShader << " gl_FragColor += v" << i << ";\n";
409 }
410
411 for (int i = 0; i < fragmentSamplersCount; i++)
412 {
413 fragmentShader << " gl_FragColor += texture2D(s" << i << ", vec2(0.0, 0.0));\n";
414 }
415
416 if (fragmentUniformCount == 0 && fragmentSamplersCount == 0)
417 {
418 fragmentShader << " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n";
419 }
420
421 fragmentShader << "}\n";
422
423 GLuint program = CompileProgram(vertexShader.str(), fragmentShader.str());
424
425 if (expectSuccess)
426 {
427 EXPECT_NE(0u, program);
428 }
429 else
430 {
431 EXPECT_EQ(0u, program);
432 }
433 }
434
Jamie Madill2bf8b372014-06-16 17:18:51 -0400435 std::string mSimpleVSSource;
Jamie Madill96509e42014-05-29 14:33:27 -0400436};
437
Jamie Madillfa05f602015-05-07 13:47:11 -0400438class GLSLTest_ES3 : public GLSLTest
Gregoire Payen de La Garanderieb3dced22015-01-12 14:54:55 +0000439{
Olli Etuahoe1d199b2016-07-19 17:14:27 +0300440 void SetUp() override
441 {
442 ANGLETest::SetUp();
443
444 mSimpleVSSource =
445 "#version 300 es\n"
446 "in vec4 inputAttribute;"
447 "void main()"
448 "{"
449 " gl_Position = inputAttribute;"
450 "}";
451 }
Gregoire Payen de La Garanderieb3dced22015-01-12 14:54:55 +0000452};
453
Jamie Madillfa05f602015-05-07 13:47:11 -0400454TEST_P(GLSLTest, NamelessScopedStructs)
Jamie Madill96509e42014-05-29 14:33:27 -0400455{
Jamie Madillbfa91f42014-06-05 15:45:18 -0400456 const std::string fragmentShaderSource = SHADER_SOURCE
Jamie Madill96509e42014-05-29 14:33:27 -0400457 (
Jamie Madillbfa91f42014-06-05 15:45:18 -0400458 precision mediump float;
459
Jamie Madill96509e42014-05-29 14:33:27 -0400460 void main()
461 {
Jamie Madillbfa91f42014-06-05 15:45:18 -0400462 struct
463 {
464 float q;
465 } b;
466
467 gl_FragColor = vec4(1, 0, 0, 1);
468 gl_FragColor.a += b.q;
Jamie Madill96509e42014-05-29 14:33:27 -0400469 }
470 );
471
Jamie Madill5599c8f2014-08-26 13:16:39 -0400472 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madillbfa91f42014-06-05 15:45:18 -0400473 EXPECT_NE(0u, program);
474}
Austin Kinross18b931d2014-09-29 12:58:31 -0700475
Jamie Madillfa05f602015-05-07 13:47:11 -0400476TEST_P(GLSLTest, ScopedStructsOrderBug)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400477{
Geoff Lange0cc2a42016-01-20 10:58:17 -0500478 // TODO(geofflang): Find out why this doesn't compile on Apple OpenGL drivers
479 // (http://anglebug.com/1292)
Geoff Lang5103f4c2016-01-26 11:40:18 -0500480 // TODO(geofflang): Find out why this doesn't compile on AMD OpenGL drivers
Geoff Lange0cc2a42016-01-20 10:58:17 -0500481 // (http://anglebug.com/1291)
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400482 if (IsDesktopOpenGL() && (IsOSX() || !IsNVIDIA()))
Geoff Lange0cc2a42016-01-20 10:58:17 -0500483 {
Jamie Madill518b9fa2016-03-02 11:26:02 -0500484 std::cout << "Test disabled on this OpenGL configuration." << std::endl;
Geoff Lange0cc2a42016-01-20 10:58:17 -0500485 return;
486 }
Geoff Lange0cc2a42016-01-20 10:58:17 -0500487
Jamie Madillbfa91f42014-06-05 15:45:18 -0400488 const std::string fragmentShaderSource = SHADER_SOURCE
489 (
490 precision mediump float;
491
492 struct T
493 {
494 float f;
495 };
496
497 void main()
498 {
499 T a;
500
501 struct T
502 {
503 float q;
504 };
505
506 T b;
507
508 gl_FragColor = vec4(1, 0, 0, 1);
509 gl_FragColor.a += a.f;
510 gl_FragColor.a += b.q;
511 }
512 );
513
Jamie Madill5599c8f2014-08-26 13:16:39 -0400514 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madillbfa91f42014-06-05 15:45:18 -0400515 EXPECT_NE(0u, program);
516}
517
Jamie Madillfa05f602015-05-07 13:47:11 -0400518TEST_P(GLSLTest, ScopedStructsBug)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400519{
Jamie Madill96509e42014-05-29 14:33:27 -0400520 const std::string fragmentShaderSource = SHADER_SOURCE
521 (
522 precision mediump float;
523
524 struct T_0
525 {
526 float f;
527 };
528
529 void main()
530 {
531 gl_FragColor = vec4(1, 0, 0, 1);
532
533 struct T
534 {
535 vec2 v;
536 };
537
538 T_0 a;
539 T b;
540
541 gl_FragColor.a += a.f;
542 gl_FragColor.a += b.v.x;
543 }
544 );
545
Jamie Madill5599c8f2014-08-26 13:16:39 -0400546 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madill2bf8b372014-06-16 17:18:51 -0400547 EXPECT_NE(0u, program);
548}
549
Jamie Madillfa05f602015-05-07 13:47:11 -0400550TEST_P(GLSLTest, DxPositionBug)
Jamie Madill2bf8b372014-06-16 17:18:51 -0400551{
552 const std::string &vertexShaderSource = SHADER_SOURCE
553 (
554 attribute vec4 inputAttribute;
555 varying float dx_Position;
556 void main()
557 {
558 gl_Position = vec4(inputAttribute);
559 dx_Position = 0.0;
560 }
561 );
562
563 const std::string &fragmentShaderSource = SHADER_SOURCE
564 (
565 precision mediump float;
566
567 varying float dx_Position;
568
569 void main()
570 {
571 gl_FragColor = vec4(dx_Position, 0, 0, 1);
572 }
573 );
574
Jamie Madill5599c8f2014-08-26 13:16:39 -0400575 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill96509e42014-05-29 14:33:27 -0400576 EXPECT_NE(0u, program);
577}
Jamie Madill4836d222014-07-24 06:55:51 -0400578
Jamie Madillfa05f602015-05-07 13:47:11 -0400579TEST_P(GLSLTest, ElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400580{
581 const std::string &vertexShaderSource =
582 "attribute vec4 a_position;\n"
583 "varying float v;\n"
584 "void main() {\n"
585 " gl_Position = a_position;\n"
586 " v = 1.0;\n"
587 " if (a_position.x <= 0.5) {\n"
588 " v = 0.0;\n"
589 " } else if (a_position.x >= 0.5) {\n"
590 " v = 2.0;\n"
591 " }\n"
592 "}\n";
593
594 const std::string &fragmentShaderSource =
595 "precision highp float;\n"
596 "varying float v;\n"
597 "void main() {\n"
598 " vec4 color = vec4(1.0, 0.0, 0.0, 1.0);\n"
599 " if (v >= 1.0) color = vec4(0.0, 1.0, 0.0, 1.0);\n"
600 " if (v >= 2.0) color = vec4(0.0, 0.0, 1.0, 1.0);\n"
601 " gl_FragColor = color;\n"
602 "}\n";
603
Jamie Madill5599c8f2014-08-26 13:16:39 -0400604 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400605 ASSERT_NE(0u, program);
606
607 drawQuad(program, "a_position", 0.5f);
Jamie Madill4836d222014-07-24 06:55:51 -0400608
609 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
610 EXPECT_PIXEL_EQ(getWindowWidth()-1, 0, 0, 255, 0, 255);
611}
612
Jamie Madillfa05f602015-05-07 13:47:11 -0400613TEST_P(GLSLTest, TwoElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400614{
615 const std::string &vertexShaderSource =
616 "attribute vec4 a_position;\n"
617 "varying float v;\n"
618 "void main() {\n"
619 " gl_Position = a_position;\n"
Jamie Madill778d5272014-08-04 13:13:25 -0400620 " if (a_position.x == 0.0) {\n"
Jamie Madill4836d222014-07-24 06:55:51 -0400621 " v = 1.0;\n"
622 " } else if (a_position.x > 0.5) {\n"
623 " v = 0.0;\n"
624 " } else if (a_position.x > 0.75) {\n"
625 " v = 0.5;\n"
626 " }\n"
627 "}\n";
628
629 const std::string &fragmentShaderSource =
630 "precision highp float;\n"
631 "varying float v;\n"
632 "void main() {\n"
633 " gl_FragColor = vec4(v, 0.0, 0.0, 1.0);\n"
634 "}\n";
635
Jamie Madill5599c8f2014-08-26 13:16:39 -0400636 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400637 EXPECT_NE(0u, program);
638}
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400639
Jamie Madillfa05f602015-05-07 13:47:11 -0400640TEST_P(GLSLTest, FrontFacingAndVarying)
Jamie Madille6256f82014-09-17 10:31:15 -0400641{
Geoff Langdd323e92015-06-09 15:16:31 -0400642 EGLPlatformParameters platform = GetParam().eglParameters;
Austin Kinross8b695ee2015-03-12 13:12:20 -0700643
Jamie Madille6256f82014-09-17 10:31:15 -0400644 const std::string vertexShaderSource = SHADER_SOURCE
645 (
646 attribute vec4 a_position;
647 varying float v_varying;
648 void main()
649 {
650 v_varying = a_position.x;
651 gl_Position = a_position;
652 }
653 );
654
655 const std::string fragmentShaderSource = SHADER_SOURCE
656 (
657 precision mediump float;
658 varying float v_varying;
659 void main()
660 {
661 vec4 c;
662
663 if (gl_FrontFacing)
664 {
665 c = vec4(v_varying, 0, 0, 1.0);
666 }
667 else
668 {
669 c = vec4(0, v_varying, 0, 1.0);
670 }
671 gl_FragColor = c;
672 }
673 );
674
675 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Austin Kinross02df7962015-07-01 10:03:42 -0700676
677 // Compilation should fail on D3D11 feature level 9_3, since gl_FrontFacing isn't supported.
678 if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
679 {
680 if (platform.majorVersion == 9 && platform.minorVersion == 3)
681 {
682 EXPECT_EQ(0u, program);
683 return;
684 }
685 }
686
687 // Otherwise, compilation should succeed
Jamie Madille6256f82014-09-17 10:31:15 -0400688 EXPECT_NE(0u, program);
689}
690
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400691// Verify that linking shaders declaring different shading language versions fails.
692TEST_P(GLSLTest_ES3, VersionMismatch)
693{
694 const std::string fragmentShaderSource100 =
695 "precision mediump float;\n"
696 "varying float v_varying;\n"
697 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
698
699 const std::string vertexShaderSource100 =
700 "attribute vec4 a_position;\n"
701 "varying float v_varying;\n"
702 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
703
704 const std::string fragmentShaderSource300 =
705 "#version 300 es\n"
706 "precision mediump float;\n"
707 "in float v_varying;\n"
708 "out vec4 my_FragColor;\n"
709 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
710
711 const std::string vertexShaderSource300 =
712 "#version 300 es\n"
713 "in vec4 a_position;\n"
714 "out float v_varying;\n"
715 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
716
717 GLuint program = CompileProgram(vertexShaderSource300, fragmentShaderSource100);
718 EXPECT_EQ(0u, program);
719
720 program = CompileProgram(vertexShaderSource100, fragmentShaderSource300);
721 EXPECT_EQ(0u, program);
722}
723
724// Verify that declaring varying as invariant only in vertex shader fails in ESSL 1.00.
725TEST_P(GLSLTest, InvariantVaryingOut)
726{
727 const std::string fragmentShaderSource =
728 "precision mediump float;\n"
729 "varying float v_varying;\n"
730 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
731
732 const std::string vertexShaderSource =
733 "attribute vec4 a_position;\n"
734 "invariant varying float v_varying;\n"
735 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
736
737 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
738 EXPECT_EQ(0u, program);
739}
740
741// Verify that declaring varying as invariant only in vertex shader succeeds in ESSL 3.00.
742TEST_P(GLSLTest_ES3, InvariantVaryingOut)
743{
744 // TODO: ESSL 3.00 -> GLSL 1.20 translation should add "invariant" in fragment shader
745 // for varyings which are invariant in vertex shader (http://anglebug.com/1293)
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400746 if (IsDesktopOpenGL())
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400747 {
748 std::cout << "Test disabled on OpenGL." << std::endl;
749 return;
750 }
751
752 const std::string fragmentShaderSource =
753 "#version 300 es\n"
754 "precision mediump float;\n"
755 "in float v_varying;\n"
756 "out vec4 my_FragColor;\n"
757 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
758
759 const std::string vertexShaderSource =
760 "#version 300 es\n"
761 "in vec4 a_position;\n"
762 "invariant out float v_varying;\n"
763 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
764
765 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
766 EXPECT_NE(0u, program);
767}
768
769// Verify that declaring varying as invariant only in fragment shader fails in ESSL 1.00.
Jamie Madillfa05f602015-05-07 13:47:11 -0400770TEST_P(GLSLTest, InvariantVaryingIn)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400771{
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400772 const std::string fragmentShaderSource =
773 "precision mediump float;\n"
774 "invariant varying float v_varying;\n"
775 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
Geoff Lange0cc2a42016-01-20 10:58:17 -0500776
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400777 const std::string vertexShaderSource =
778 "attribute vec4 a_position;\n"
779 "varying float v_varying;\n"
780 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400781
Jamie Madill5599c8f2014-08-26 13:16:39 -0400782 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400783 EXPECT_EQ(0u, program);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400784}
785
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400786// Verify that declaring varying as invariant only in fragment shader fails in ESSL 3.00.
787TEST_P(GLSLTest_ES3, InvariantVaryingIn)
788{
789 const std::string fragmentShaderSource =
790 "#version 300 es\n"
791 "precision mediump float;\n"
792 "invariant in float v_varying;\n"
793 "out vec4 my_FragColor;\n"
794 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
795
796 const std::string vertexShaderSource =
797 "#version 300 es\n"
798 "in vec4 a_position;\n"
799 "out float v_varying;\n"
800 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
801
802 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
803 EXPECT_EQ(0u, program);
804}
805
806// Verify that declaring varying as invariant in both shaders succeeds in ESSL 1.00.
Jamie Madillfa05f602015-05-07 13:47:11 -0400807TEST_P(GLSLTest, InvariantVaryingBoth)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400808{
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400809 const std::string fragmentShaderSource =
810 "precision mediump float;\n"
811 "invariant varying float v_varying;\n"
812 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400813
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400814 const std::string vertexShaderSource =
815 "attribute vec4 a_position;\n"
816 "invariant varying float v_varying;\n"
817 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400818
Jamie Madill5599c8f2014-08-26 13:16:39 -0400819 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400820 EXPECT_NE(0u, program);
821}
822
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400823// Verify that declaring varying as invariant in both shaders fails in ESSL 3.00.
824TEST_P(GLSLTest_ES3, InvariantVaryingBoth)
825{
826 const std::string fragmentShaderSource =
827 "#version 300 es\n"
828 "precision mediump float;\n"
829 "invariant in float v_varying;\n"
830 "out vec4 my_FragColor;\n"
831 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
832
833 const std::string vertexShaderSource =
834 "#version 300 es\n"
835 "in vec4 a_position;\n"
836 "invariant out float v_varying;\n"
837 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
838
839 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
840 EXPECT_EQ(0u, program);
841}
842
843// Verify that declaring gl_Position as invariant succeeds in ESSL 1.00.
Jamie Madillfa05f602015-05-07 13:47:11 -0400844TEST_P(GLSLTest, InvariantGLPosition)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400845{
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400846 const std::string fragmentShaderSource =
847 "precision mediump float;\n"
848 "varying float v_varying;\n"
849 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400850
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400851 const std::string vertexShaderSource =
852 "attribute vec4 a_position;\n"
853 "invariant gl_Position;\n"
854 "varying float v_varying;\n"
855 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400856
Jamie Madill5599c8f2014-08-26 13:16:39 -0400857 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400858 EXPECT_NE(0u, program);
859}
860
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400861// Verify that declaring gl_Position as invariant succeeds in ESSL 3.00.
862TEST_P(GLSLTest_ES3, InvariantGLPosition)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400863{
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400864 const std::string fragmentShaderSource =
865 "#version 300 es\n"
866 "precision mediump float;\n"
867 "in float v_varying;\n"
868 "out vec4 my_FragColor;\n"
869 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
870
871 const std::string vertexShaderSource =
872 "#version 300 es\n"
873 "in vec4 a_position;\n"
874 "invariant gl_Position;\n"
875 "out float v_varying;\n"
876 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
877
878 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
879 EXPECT_NE(0u, program);
880}
881
882// Verify that using invariant(all) in both shaders succeeds in ESSL 1.00.
883TEST_P(GLSLTest, InvariantAllBoth)
884{
885 // TODO: ESSL 1.00 -> GLSL 1.20 translation should add "invariant" in fragment shader
886 // for varyings which are invariant in vertex shader individually,
887 // and remove invariant(all) from fragment shader (http://anglebug.com/1293)
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400888 if (IsDesktopOpenGL())
Geoff Lange0cc2a42016-01-20 10:58:17 -0500889 {
890 std::cout << "Test disabled on OpenGL." << std::endl;
891 return;
892 }
893
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400894 const std::string fragmentShaderSource =
895 "#pragma STDGL invariant(all)\n"
896 "precision mediump float;\n"
897 "varying float v_varying;\n"
898 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400899
900 const std::string vertexShaderSource =
901 "#pragma STDGL invariant(all)\n"
902 "attribute vec4 a_position;\n"
903 "varying float v_varying;\n"
904 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
905
Jamie Madill5599c8f2014-08-26 13:16:39 -0400906 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400907 EXPECT_NE(0u, program);
908}
Austin Kinrossaf875522014-08-25 21:06:07 -0700909
Geoff Lang156d7192016-07-21 16:11:00 -0400910// Verify that functions without return statements still compile
911TEST_P(GLSLTest, MissingReturnFloat)
912{
913 const std::string vertexShaderSource =
914 "varying float v_varying;\n"
915 "float f() { if (v_varying > 0.0) return 1.0; }\n"
916 "void main() { gl_Position = vec4(f(), 0, 0, 1); }\n";
917
918 const std::string fragmentShaderSource =
919 "precision mediump float;\n"
920 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
921
922 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
923 EXPECT_NE(0u, program);
924}
925
926// Verify that functions without return statements still compile
927TEST_P(GLSLTest, MissingReturnVec2)
928{
929 const std::string vertexShaderSource =
930 "varying float v_varying;\n"
931 "vec2 f() { if (v_varying > 0.0) return vec2(1.0, 1.0); }\n"
932 "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
933
934 const std::string fragmentShaderSource =
935 "precision mediump float;\n"
936 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
937
938 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
939 EXPECT_NE(0u, program);
940}
941
942// Verify that functions without return statements still compile
943TEST_P(GLSLTest, MissingReturnVec3)
944{
945 const std::string vertexShaderSource =
946 "varying float v_varying;\n"
947 "vec3 f() { if (v_varying > 0.0) return vec3(1.0, 1.0, 1.0); }\n"
948 "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
949
950 const std::string fragmentShaderSource =
951 "precision mediump float;\n"
952 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
953
954 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
955 EXPECT_NE(0u, program);
956}
957
958// Verify that functions without return statements still compile
959TEST_P(GLSLTest, MissingReturnVec4)
960{
961 const std::string vertexShaderSource =
962 "varying float v_varying;\n"
963 "vec4 f() { if (v_varying > 0.0) return vec4(1.0, 1.0, 1.0, 1.0); }\n"
964 "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
965
966 const std::string fragmentShaderSource =
967 "precision mediump float;\n"
968 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
969
970 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
971 EXPECT_NE(0u, program);
972}
973
974// Verify that functions without return statements still compile
975TEST_P(GLSLTest, MissingReturnIVec4)
976{
977 const std::string vertexShaderSource =
978 "varying float v_varying;\n"
979 "ivec4 f() { if (v_varying > 0.0) return ivec4(1, 1, 1, 1); }\n"
980 "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
981
982 const std::string fragmentShaderSource =
983 "precision mediump float;\n"
984 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
985
986 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
987 EXPECT_NE(0u, program);
988}
989
990// Verify that functions without return statements still compile
991TEST_P(GLSLTest, MissingReturnMat4)
992{
993 const std::string vertexShaderSource =
994 "varying float v_varying;\n"
995 "mat4 f() { if (v_varying > 0.0) return mat4(1.0); }\n"
996 "void main() { gl_Position = vec4(f()[0][0], 0, 0, 1); }\n";
997
998 const std::string fragmentShaderSource =
999 "precision mediump float;\n"
1000 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
1001
1002 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1003 EXPECT_NE(0u, program);
1004}
1005
1006// Verify that functions without return statements still compile
1007TEST_P(GLSLTest, MissingReturnStruct)
1008{
1009 const std::string vertexShaderSource =
1010 "varying float v_varying;\n"
1011 "struct s { float a; int b; vec2 c; };\n"
1012 "s f() { if (v_varying > 0.0) return s(1.0, 1, vec2(1.0, 1.0)); }\n"
1013 "void main() { gl_Position = vec4(f().a, 0, 0, 1); }\n";
1014
1015 const std::string fragmentShaderSource =
1016 "precision mediump float;\n"
1017 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
1018
1019 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1020 EXPECT_NE(0u, program);
1021}
1022
1023// Verify that functions without return statements still compile
1024TEST_P(GLSLTest_ES3, MissingReturnArray)
1025{
1026 const std::string vertexShaderSource =
1027 "#version 300 es\n"
1028 "in float v_varying;\n"
1029 "vec2[2] f() { if (v_varying > 0.0) { return vec2[2](vec2(1.0, 1.0), vec2(1.0, 1.0)); } }\n"
1030 "void main() { gl_Position = vec4(f()[0].x, 0, 0, 1); }\n";
1031
1032 const std::string fragmentShaderSource =
1033 "#version 300 es\n"
1034 "precision mediump float;\n"
1035 "out vec4 my_FragColor;\n"
1036 "void main() { my_FragColor = vec4(0, 0, 0, 1); }\n";
1037
1038 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1039 EXPECT_NE(0u, program);
1040}
1041
1042// Verify that functions without return statements still compile
1043TEST_P(GLSLTest_ES3, MissingReturnArrayOfStructs)
1044{
1045 const std::string vertexShaderSource =
1046 "#version 300 es\n"
1047 "in float v_varying;\n"
1048 "struct s { float a; int b; vec2 c; };\n"
1049 "s[2] f() { if (v_varying > 0.0) { return s[2](s(1.0, 1, vec2(1.0, 1.0)), s(1.0, 1, "
1050 "vec2(1.0, 1.0))); } }\n"
1051 "void main() { gl_Position = vec4(f()[0].a, 0, 0, 1); }\n";
1052
1053 const std::string fragmentShaderSource =
1054 "#version 300 es\n"
1055 "precision mediump float;\n"
1056 "out vec4 my_FragColor;\n"
1057 "void main() { my_FragColor = vec4(0, 0, 0, 1); }\n";
1058
1059 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1060 EXPECT_NE(0u, program);
1061}
1062
Yuly Novikova1f6dc92016-06-15 23:27:04 -04001063// Verify that using invariant(all) in both shaders fails in ESSL 3.00.
1064TEST_P(GLSLTest_ES3, InvariantAllBoth)
1065{
1066 const std::string fragmentShaderSource =
1067 "#version 300 es\n"
1068 "#pragma STDGL invariant(all)\n"
1069 "precision mediump float;\n"
1070 "in float v_varying;\n"
1071 "out vec4 my_FragColor;\n"
1072 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1073
1074 const std::string vertexShaderSource =
1075 "#version 300 es\n"
1076 "#pragma STDGL invariant(all)\n"
1077 "in vec4 a_position;\n"
1078 "out float v_varying;\n"
1079 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1080
1081 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1082 EXPECT_EQ(0u, program);
1083}
1084
1085// Verify that using invariant(all) only in fragment shader fails in ESSL 1.00.
1086TEST_P(GLSLTest, InvariantAllIn)
1087{
1088 const std::string fragmentShaderSource =
1089 "#pragma STDGL invariant(all)\n"
1090 "precision mediump float;\n"
1091 "varying float v_varying;\n"
1092 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1093
1094 const std::string vertexShaderSource =
1095 "attribute vec4 a_position;\n"
1096 "varying float v_varying;\n"
1097 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1098
1099 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1100 EXPECT_EQ(0u, program);
1101}
1102
1103// Verify that using invariant(all) only in fragment shader fails in ESSL 3.00.
1104TEST_P(GLSLTest_ES3, InvariantAllIn)
1105{
1106 const std::string fragmentShaderSource =
1107 "#version 300 es\n"
1108 "#pragma STDGL invariant(all)\n"
1109 "precision mediump float;\n"
1110 "in float v_varying;\n"
1111 "out vec4 my_FragColor;\n"
1112 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1113
1114 const std::string vertexShaderSource =
1115 "#version 300 es\n"
1116 "in vec4 a_position;\n"
1117 "out float v_varying;\n"
1118 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1119
1120 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1121 EXPECT_EQ(0u, program);
1122}
1123
1124// Verify that using invariant(all) only in vertex shader fails in ESSL 1.00.
1125TEST_P(GLSLTest, InvariantAllOut)
1126{
1127 const std::string fragmentShaderSource =
1128 "precision mediump float;\n"
1129 "varying float v_varying;\n"
1130 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1131
1132 const std::string vertexShaderSource =
1133 "#pragma STDGL invariant(all)\n"
1134 "attribute vec4 a_position;\n"
1135 "varying float v_varying;\n"
1136 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1137
1138 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1139 EXPECT_EQ(0u, program);
1140}
1141
1142// Verify that using invariant(all) only in vertex shader succeeds in ESSL 3.00.
1143TEST_P(GLSLTest_ES3, InvariantAllOut)
1144{
1145 // TODO: ESSL 3.00 -> GLSL 1.20 translation should add "invariant" in fragment shader
1146 // for varyings which are invariant in vertex shader,
1147 // because of invariant(all) being used in vertex shader (http://anglebug.com/1293)
Corentin Wallezc7f59d02016-06-20 10:12:08 -04001148 if (IsDesktopOpenGL())
Yuly Novikova1f6dc92016-06-15 23:27:04 -04001149 {
1150 std::cout << "Test disabled on OpenGL." << std::endl;
1151 return;
1152 }
1153
1154 const std::string fragmentShaderSource =
1155 "#version 300 es\n"
1156 "precision mediump float;\n"
1157 "in float v_varying;\n"
1158 "out vec4 my_FragColor;\n"
1159 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1160
1161 const std::string vertexShaderSource =
1162 "#version 300 es\n"
1163 "#pragma STDGL invariant(all)\n"
1164 "in vec4 a_position;\n"
1165 "out float v_varying;\n"
1166 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1167
1168 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1169 EXPECT_NE(0u, program);
1170}
1171
Jamie Madillfa05f602015-05-07 13:47:11 -04001172TEST_P(GLSLTest, MaxVaryingVec4)
Austin Kinross8b695ee2015-03-12 13:12:20 -07001173{
Geoff Lang69accbd2016-01-25 16:22:32 -05001174#if defined(__APPLE__)
1175 // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
1176 // (http://anglebug.com/1291)
Jamie Madill518b9fa2016-03-02 11:26:02 -05001177 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lang69accbd2016-01-25 16:22:32 -05001178 {
1179 std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
1180 return;
1181 }
1182#endif
1183
Austin Kinross8b695ee2015-03-12 13:12:20 -07001184 GLint maxVaryings = 0;
1185 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1186
1187 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, false, false, true);
1188}
1189
Jamie Madillfa05f602015-05-07 13:47:11 -04001190TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusTwoSpecialVariables)
Austin Kinross8b695ee2015-03-12 13:12:20 -07001191{
1192 GLint maxVaryings = 0;
1193 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1194
1195 // Generate shader code that uses gl_FragCoord and gl_PointCoord, two special fragment shader variables.
1196 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, false, true);
1197}
1198
Jamie Madillfa05f602015-05-07 13:47:11 -04001199TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusThreeSpecialVariables)
Austin Kinross8b695ee2015-03-12 13:12:20 -07001200{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001201 // TODO(geofflang): Figure out why this fails on OpenGL AMD (http://anglebug.com/1291)
Jamie Madill518b9fa2016-03-02 11:26:02 -05001202 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lange0cc2a42016-01-20 10:58:17 -05001203 {
1204 std::cout << "Test disabled on OpenGL." << std::endl;
1205 return;
1206 }
1207
Austin Kinross8b695ee2015-03-12 13:12:20 -07001208 GLint maxVaryings = 0;
1209 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1210
1211 // Generate shader code that uses gl_FragCoord, gl_PointCoord and gl_PointSize.
1212 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, true, true);
1213}
1214
Geoff Lange0cc2a42016-01-20 10:58:17 -05001215// Disabled because drivers are allowed to successfully compile shaders that have more than the
1216// maximum number of varyings. (http://anglebug.com/1296)
1217TEST_P(GLSLTest, DISABLED_MaxVaryingVec4PlusFragCoord)
Austin Kinross8b695ee2015-03-12 13:12:20 -07001218{
1219 GLint maxVaryings = 0;
1220 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1221
1222 // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
1223 // This test should fail, since we are really using (maxVaryings + 1) varyings.
1224 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, true, false, false, false);
1225}
1226
Geoff Lange0cc2a42016-01-20 10:58:17 -05001227// Disabled because drivers are allowed to successfully compile shaders that have more than the
1228// maximum number of varyings. (http://anglebug.com/1296)
1229TEST_P(GLSLTest, DISABLED_MaxVaryingVec4PlusPointCoord)
Austin Kinross8b695ee2015-03-12 13:12:20 -07001230{
1231 GLint maxVaryings = 0;
1232 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1233
1234 // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
1235 // This test should fail, since we are really using (maxVaryings + 1) varyings.
1236 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, true, false, false);
1237}
1238
Jamie Madillfa05f602015-05-07 13:47:11 -04001239TEST_P(GLSLTest, MaxVaryingVec3)
Austin Kinrossaf875522014-08-25 21:06:07 -07001240{
1241 GLint maxVaryings = 0;
1242 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1243
Austin Kinross8b695ee2015-03-12 13:12:20 -07001244 VaryingTestBase(0, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001245}
1246
Jamie Madillfa05f602015-05-07 13:47:11 -04001247TEST_P(GLSLTest, MaxVaryingVec3Array)
Austin Kinrossaf875522014-08-25 21:06:07 -07001248{
1249 GLint maxVaryings = 0;
1250 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1251
Austin Kinross8b695ee2015-03-12 13:12:20 -07001252 VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001253}
1254
Jamie Madillbee59e02014-10-02 10:44:18 -04001255// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -05001256TEST_P(GLSLTest, MaxVaryingVec3AndOneFloat)
Austin Kinrossaf875522014-08-25 21:06:07 -07001257{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001258 if (IsD3D9())
Jamie Madill9fc36822015-11-18 13:08:07 -05001259 {
1260 std::cout << "Test disabled on D3D9." << std::endl;
1261 return;
1262 }
1263
Austin Kinrossaf875522014-08-25 21:06:07 -07001264 GLint maxVaryings = 0;
1265 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1266
Austin Kinross8b695ee2015-03-12 13:12:20 -07001267 VaryingTestBase(1, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001268}
1269
Jamie Madillbee59e02014-10-02 10:44:18 -04001270// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -05001271TEST_P(GLSLTest, MaxVaryingVec3ArrayAndOneFloatArray)
Austin Kinrossaf875522014-08-25 21:06:07 -07001272{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001273 if (IsD3D9())
Jamie Madill9fc36822015-11-18 13:08:07 -05001274 {
1275 std::cout << "Test disabled on D3D9." << std::endl;
1276 return;
1277 }
1278
Austin Kinrossaf875522014-08-25 21:06:07 -07001279 GLint maxVaryings = 0;
1280 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1281
Austin Kinross8b695ee2015-03-12 13:12:20 -07001282 VaryingTestBase(0, 1, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001283}
1284
Jamie Madillbee59e02014-10-02 10:44:18 -04001285// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -05001286TEST_P(GLSLTest, TwiceMaxVaryingVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -07001287{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001288 if (IsD3D9())
Jamie Madill9fc36822015-11-18 13:08:07 -05001289 {
1290 std::cout << "Test disabled on D3D9." << std::endl;
1291 return;
1292 }
1293
Geoff Lange0cc2a42016-01-20 10:58:17 -05001294 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1295 {
1296 // TODO(geofflang): Figure out why this fails on NVIDIA's GLES driver
1297 std::cout << "Test disabled on OpenGL ES." << std::endl;
1298 return;
1299 }
1300
Geoff Lang69accbd2016-01-25 16:22:32 -05001301#if defined(__APPLE__)
1302 // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
1303 // (http://anglebug.com/1291)
Jamie Madill518b9fa2016-03-02 11:26:02 -05001304 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lang69accbd2016-01-25 16:22:32 -05001305 {
1306 std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
1307 return;
1308 }
1309#endif
1310
Austin Kinrossaf875522014-08-25 21:06:07 -07001311 GLint maxVaryings = 0;
1312 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1313
Austin Kinross8b695ee2015-03-12 13:12:20 -07001314 VaryingTestBase(0, 0, 2 * maxVaryings, 0, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001315}
1316
Jamie Madillbee59e02014-10-02 10:44:18 -04001317// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -05001318TEST_P(GLSLTest, MaxVaryingVec2Arrays)
Austin Kinrossaf875522014-08-25 21:06:07 -07001319{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001320 if (IsD3DSM3())
Jamie Madill9fc36822015-11-18 13:08:07 -05001321 {
1322 std::cout << "Test disabled on SM3." << std::endl;
1323 return;
1324 }
1325
Geoff Lange0cc2a42016-01-20 10:58:17 -05001326 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1327 {
1328 // TODO(geofflang): Figure out why this fails on NVIDIA's GLES driver
1329 std::cout << "Test disabled on OpenGL ES." << std::endl;
1330 return;
1331 }
1332
Geoff Lang69accbd2016-01-25 16:22:32 -05001333#if defined(__APPLE__)
1334 // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
1335 // (http://anglebug.com/1291)
Jamie Madill518b9fa2016-03-02 11:26:02 -05001336 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lang69accbd2016-01-25 16:22:32 -05001337 {
1338 std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
1339 return;
1340 }
1341#endif
1342
Austin Kinrossaf875522014-08-25 21:06:07 -07001343 GLint maxVaryings = 0;
1344 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1345
Austin Kinross8b695ee2015-03-12 13:12:20 -07001346 VaryingTestBase(0, 0, 0, maxVaryings, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001347}
1348
Geoff Lange0cc2a42016-01-20 10:58:17 -05001349// Disabled because drivers are allowed to successfully compile shaders that have more than the
1350// maximum number of varyings. (http://anglebug.com/1296)
1351TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec3)
Austin Kinrossaf875522014-08-25 21:06:07 -07001352{
1353 GLint maxVaryings = 0;
1354 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1355
Austin Kinross8b695ee2015-03-12 13:12:20 -07001356 VaryingTestBase(0, 0, 0, 0, maxVaryings + 1, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001357}
1358
Geoff Lange0cc2a42016-01-20 10:58:17 -05001359// Disabled because drivers are allowed to successfully compile shaders that have more than the
1360// maximum number of varyings. (http://anglebug.com/1296)
1361TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec3Array)
Austin Kinrossaf875522014-08-25 21:06:07 -07001362{
1363 GLint maxVaryings = 0;
1364 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1365
Austin Kinross8b695ee2015-03-12 13:12:20 -07001366 VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2 + 1, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001367}
1368
Geoff Lange0cc2a42016-01-20 10:58:17 -05001369// Disabled because drivers are allowed to successfully compile shaders that have more than the
1370// maximum number of varyings. (http://anglebug.com/1296)
1371TEST_P(GLSLTest, DISABLED_MaxVaryingVec3AndOneVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -07001372{
1373 GLint maxVaryings = 0;
1374 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1375
Austin Kinross8b695ee2015-03-12 13:12:20 -07001376 VaryingTestBase(0, 0, 1, 0, maxVaryings, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001377}
1378
Geoff Lange0cc2a42016-01-20 10:58:17 -05001379// Disabled because drivers are allowed to successfully compile shaders that have more than the
1380// maximum number of varyings. (http://anglebug.com/1296)
1381TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -07001382{
1383 GLint maxVaryings = 0;
1384 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1385
Austin Kinross8b695ee2015-03-12 13:12:20 -07001386 VaryingTestBase(0, 0, 2 * maxVaryings + 1, 0, 0, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001387}
1388
Geoff Lange0cc2a42016-01-20 10:58:17 -05001389// Disabled because drivers are allowed to successfully compile shaders that have more than the
1390// maximum number of varyings. (http://anglebug.com/1296)
1391TEST_P(GLSLTest, DISABLED_MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
Austin Kinrossaf875522014-08-25 21:06:07 -07001392{
1393 GLint maxVaryings = 0;
1394 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1395
Austin Kinross8b695ee2015-03-12 13:12:20 -07001396 VaryingTestBase(0, maxVaryings / 2 + 1, 0, 0, 0, 0, 0, maxVaryings / 2, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001397}
Geoff Langf60fab62014-11-24 11:21:20 -05001398
1399// Verify shader source with a fixed length that is less than the null-terminated length will compile.
Jamie Madillfa05f602015-05-07 13:47:11 -04001400TEST_P(GLSLTest, FixedShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -05001401{
1402 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1403
1404 const std::string appendGarbage = "abcasdfasdfasdfasdfasdf";
1405 const std::string source = "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" + appendGarbage;
1406 const char *sourceArray[1] = { source.c_str() };
Corentin Wallez973402f2015-05-11 13:42:22 -04001407 GLint lengths[1] = { static_cast<GLint>(source.length() - appendGarbage.length()) };
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001408 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001409 glCompileShader(shader);
1410
1411 GLint compileResult;
1412 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1413 EXPECT_NE(compileResult, 0);
1414}
1415
1416// Verify that a negative shader source length is treated as a null-terminated length.
Jamie Madillfa05f602015-05-07 13:47:11 -04001417TEST_P(GLSLTest, NegativeShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -05001418{
1419 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1420
1421 const char *sourceArray[1] = { "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" };
1422 GLint lengths[1] = { -10 };
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001423 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001424 glCompileShader(shader);
1425
1426 GLint compileResult;
1427 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1428 EXPECT_NE(compileResult, 0);
1429}
1430
Corentin Wallez9a9c0482016-04-12 10:36:25 -04001431// Check that having an invalid char after the "." doesn't cause an assert.
1432TEST_P(GLSLTest, InvalidFieldFirstChar)
1433{
1434 GLuint shader = glCreateShader(GL_VERTEX_SHADER);
1435 const char *source = "void main() {vec4 x; x.}";
1436 glShaderSource(shader, 1, &source, 0);
1437 glCompileShader(shader);
1438
1439 GLint compileResult;
1440 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1441 EXPECT_EQ(0, compileResult);
1442}
1443
Geoff Langf60fab62014-11-24 11:21:20 -05001444// Verify that a length array with mixed positive and negative values compiles.
Jamie Madillfa05f602015-05-07 13:47:11 -04001445TEST_P(GLSLTest, MixedShaderLengths)
Geoff Langf60fab62014-11-24 11:21:20 -05001446{
1447 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1448
1449 const char *sourceArray[] =
1450 {
1451 "void main()",
1452 "{",
1453 " gl_FragColor = vec4(0, 0, 0, 0);",
1454 "}",
1455 };
1456 GLint lengths[] =
1457 {
1458 -10,
1459 1,
Corentin Wallez973402f2015-05-11 13:42:22 -04001460 static_cast<GLint>(strlen(sourceArray[2])),
Geoff Langf60fab62014-11-24 11:21:20 -05001461 -1,
1462 };
1463 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
1464
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001465 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001466 glCompileShader(shader);
1467
1468 GLint compileResult;
1469 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1470 EXPECT_NE(compileResult, 0);
1471}
1472
1473// Verify that zero-length shader source does not affect shader compilation.
Jamie Madillfa05f602015-05-07 13:47:11 -04001474TEST_P(GLSLTest, ZeroShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -05001475{
1476 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1477
1478 const char *sourceArray[] =
1479 {
1480 "adfasdf",
1481 "34534",
1482 "void main() { gl_FragColor = vec4(0, 0, 0, 0); }",
1483 "",
1484 "asdfasdfsdsdf",
1485 };
1486 GLint lengths[] =
1487 {
1488 0,
1489 0,
1490 -1,
1491 0,
1492 0,
1493 };
1494 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
1495
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001496 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001497 glCompileShader(shader);
1498
1499 GLint compileResult;
1500 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1501 EXPECT_NE(compileResult, 0);
1502}
Jamie Madill21c1e452014-12-29 11:33:41 -05001503
1504// Tests that bad index expressions don't crash ANGLE's translator.
1505// https://code.google.com/p/angleproject/issues/detail?id=857
Jamie Madillfa05f602015-05-07 13:47:11 -04001506TEST_P(GLSLTest, BadIndexBug)
Jamie Madill21c1e452014-12-29 11:33:41 -05001507{
1508 const std::string &fragmentShaderSourceVec =
1509 "precision mediump float;\n"
1510 "uniform vec4 uniformVec;\n"
1511 "void main()\n"
1512 "{\n"
1513 " gl_FragColor = vec4(uniformVec[int()]);\n"
1514 "}";
1515
1516 GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceVec);
1517 EXPECT_EQ(0u, shader);
1518
1519 if (shader != 0)
1520 {
1521 glDeleteShader(shader);
1522 }
1523
1524 const std::string &fragmentShaderSourceMat =
1525 "precision mediump float;\n"
1526 "uniform mat4 uniformMat;\n"
1527 "void main()\n"
1528 "{\n"
1529 " gl_FragColor = vec4(uniformMat[int()]);\n"
1530 "}";
1531
1532 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceMat);
1533 EXPECT_EQ(0u, shader);
1534
1535 if (shader != 0)
1536 {
1537 glDeleteShader(shader);
1538 }
1539
1540 const std::string &fragmentShaderSourceArray =
1541 "precision mediump float;\n"
1542 "uniform vec4 uniformArray;\n"
1543 "void main()\n"
1544 "{\n"
1545 " gl_FragColor = vec4(uniformArray[int()]);\n"
1546 "}";
1547
1548 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceArray);
1549 EXPECT_EQ(0u, shader);
1550
1551 if (shader != 0)
1552 {
1553 glDeleteShader(shader);
1554 }
Jamie Madill37997142015-01-28 10:06:34 -05001555}
1556
Jamie Madill2e295e22015-04-29 10:41:33 -04001557// Test that structs defined in uniforms are translated correctly.
Jamie Madillfa05f602015-05-07 13:47:11 -04001558TEST_P(GLSLTest, StructSpecifiersUniforms)
Jamie Madill2e295e22015-04-29 10:41:33 -04001559{
1560 const std::string fragmentShaderSource = SHADER_SOURCE
1561 (
1562 precision mediump float;
1563
1564 uniform struct S { float field;} s;
1565
1566 void main()
1567 {
1568 gl_FragColor = vec4(1, 0, 0, 1);
1569 gl_FragColor.a += s.field;
1570 }
1571 );
1572
1573 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1574 EXPECT_NE(0u, program);
1575}
Jamie Madill55def582015-05-04 11:24:57 -04001576
1577// Test that gl_DepthRange is not stored as a uniform location. Since uniforms
1578// beginning with "gl_" are filtered out by our validation logic, we must
1579// bypass the validation to test the behaviour of the implementation.
1580// (note this test is still Impl-independent)
Jamie Madillfa05f602015-05-07 13:47:11 -04001581TEST_P(GLSLTest, DepthRangeUniforms)
Jamie Madill55def582015-05-04 11:24:57 -04001582{
1583 const std::string fragmentShaderSource = SHADER_SOURCE
1584 (
1585 precision mediump float;
1586
1587 void main()
1588 {
1589 gl_FragColor = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff, 1);
1590 }
1591 );
1592
1593 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1594 EXPECT_NE(0u, program);
1595
1596 // dive into the ANGLE internals, so we can bypass validation.
1597 gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
1598 gl::Program *glProgram = context->getProgram(program);
1599 GLint nearIndex = glProgram->getUniformLocation("gl_DepthRange.near");
1600 EXPECT_EQ(-1, nearIndex);
1601
1602 // Test drawing does not throw an exception.
1603 drawQuad(program, "inputAttribute", 0.5f);
1604
1605 EXPECT_GL_NO_ERROR();
1606
1607 glDeleteProgram(program);
1608}
Jamie Madill4052dfc2015-05-06 15:18:49 -04001609
1610// Covers the WebGL test 'glsl/bugs/pow-of-small-constant-in-user-defined-function'
Jamie Madill1048e432016-07-23 18:51:28 -04001611// See http://anglebug.com/851
1612TEST_P(GLSLTest, 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
Jamie Madill1048e432016-07-23 18:51:28 -04001642 ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShaderSource);
Jamie Madill4052dfc2015-05-06 15:18:49 -04001643
Jamie Madill1048e432016-07-23 18:51:28 -04001644 drawQuad(program.get(), "inputAttribute", 0.5f);
1645 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madill4052dfc2015-05-06 15:18:49 -04001646 EXPECT_GL_NO_ERROR();
1647}
Jamie Madillfa05f602015-05-07 13:47:11 -04001648
Cooper Partina5ef8d82015-08-19 14:52:21 -07001649// Test that fragment shaders which contain non-constant loop indexers and compiled for FL9_3 and
1650// below
1651// fail with a specific error message.
1652// Additionally test that the same fragment shader compiles successfully with feature levels greater
1653// than FL9_3.
1654TEST_P(GLSLTest, LoopIndexingValidation)
1655{
1656 const std::string fragmentShaderSource = SHADER_SOURCE
1657 (
1658 precision mediump float;
1659
1660 uniform float loopMax;
1661
1662 void main()
1663 {
1664 gl_FragColor = vec4(1, 0, 0, 1);
1665 for (float l = 0.0; l < loopMax; l++)
1666 {
1667 if (loopMax > 3.0)
1668 {
1669 gl_FragColor.a += 0.1;
1670 }
1671 }
1672 }
1673 );
1674
1675 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1676
1677 const char *sourceArray[1] = {fragmentShaderSource.c_str()};
1678 glShaderSource(shader, 1, sourceArray, nullptr);
1679 glCompileShader(shader);
1680
1681 GLint compileResult;
1682 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1683
1684 // If the test is configured to run limited to Feature Level 9_3, then it is
1685 // assumed that shader compilation will fail with an expected error message containing
1686 // "Loop index cannot be compared with non-constant expression"
Olli Etuaho814a54d2015-08-27 16:23:09 +03001687 if ((GetParam() == ES2_D3D11_FL9_3() || GetParam() == ES2_D3D9()))
Cooper Partina5ef8d82015-08-19 14:52:21 -07001688 {
1689 if (compileResult != 0)
1690 {
1691 FAIL() << "Shader compilation succeeded, expected failure";
1692 }
1693 else
1694 {
1695 GLint infoLogLength;
1696 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
1697
1698 std::string infoLog;
1699 infoLog.resize(infoLogLength);
1700 glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
1701
1702 if (infoLog.find("Loop index cannot be compared with non-constant expression") ==
1703 std::string::npos)
1704 {
1705 FAIL() << "Shader compilation failed with unexpected error message";
1706 }
1707 }
1708 }
1709 else
1710 {
1711 EXPECT_NE(0, compileResult);
1712 }
1713
1714 if (shader != 0)
1715 {
1716 glDeleteShader(shader);
1717 }
1718}
1719
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001720// Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1721// can actually be used.
1722TEST_P(GLSLTest, VerifyMaxVertexUniformVectors)
1723{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001724 int maxUniforms = 10000;
1725 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1726 EXPECT_GL_NO_ERROR();
1727 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl;
1728
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001729 CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, 0, 0, true);
1730}
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001731
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001732// Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1733// can actually be used along with the maximum number of texture samplers.
1734TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsWithSamplers)
1735{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001736 if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1737 GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1738 {
1739 std::cout << "Test disabled on OpenGL." << std::endl;
1740 return;
1741 }
1742
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001743 int maxUniforms = 10000;
1744 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1745 EXPECT_GL_NO_ERROR();
1746 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001747
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001748 int maxTextureImageUnits = 0;
1749 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001750
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001751 CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, maxTextureImageUnits, 0, true);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001752}
1753
1754// Tests that the maximum uniforms count + 1 from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1755// fails shader compilation.
1756TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsExceeded)
1757{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001758 int maxUniforms = 10000;
1759 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1760 EXPECT_GL_NO_ERROR();
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001761 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS + 1 = " << maxUniforms + 1 << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001762
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001763 CompileGLSLWithUniformsAndSamplers(maxUniforms + 1, 0, 0, 0, false);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001764}
1765
1766// Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1767// can actually be used.
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001768TEST_P(GLSLTest, VerifyMaxFragmentUniformVectors)
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001769{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001770 int maxUniforms = 10000;
1771 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1772 EXPECT_GL_NO_ERROR();
1773 std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS = " << maxUniforms << std::endl;
1774
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001775 CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, 0, true);
1776}
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001777
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001778// Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1779// can actually be used along with the maximum number of texture samplers.
1780TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsWithSamplers)
1781{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001782 if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1783 GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1784 {
1785 std::cout << "Test disabled on OpenGL." << std::endl;
1786 return;
1787 }
1788
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001789 int maxUniforms = 10000;
1790 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1791 EXPECT_GL_NO_ERROR();
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001792
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001793 int maxTextureImageUnits = 0;
1794 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001795
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001796 CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, maxTextureImageUnits, true);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001797}
1798
1799// Tests that the maximum uniforms count + 1 from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1800// fails shader compilation.
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001801TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsExceeded)
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001802{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001803 int maxUniforms = 10000;
1804 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1805 EXPECT_GL_NO_ERROR();
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001806 std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS + 1 = " << maxUniforms + 1
1807 << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001808
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001809 CompileGLSLWithUniformsAndSamplers(0, maxUniforms + 1, 0, 0, false);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001810}
1811
Olli Etuahobe59c2f2016-03-07 11:32:34 +02001812// Test that two constructors which have vec4 and mat2 parameters get disambiguated (issue in
1813// HLSL).
1814TEST_P(GLSLTest_ES3, AmbiguousConstructorCall2x2)
1815{
1816 const std::string fragmentShaderSource =
1817 "#version 300 es\n"
1818 "precision highp float;\n"
1819 "out vec4 my_FragColor;\n"
1820 "void main()\n"
1821 "{\n"
1822 " my_FragColor = vec4(0.0);\n"
1823 "}";
1824
1825 const std::string vertexShaderSource =
1826 "#version 300 es\n"
1827 "precision highp float;\n"
1828 "in vec4 a_vec;\n"
1829 "in mat2 a_mat;\n"
1830 "void main()\n"
1831 "{\n"
1832 " gl_Position = vec4(a_vec) + vec4(a_mat);\n"
1833 "}";
1834
1835 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1836 EXPECT_NE(0u, program);
1837}
1838
1839// Test that two constructors which have mat2x3 and mat3x2 parameters get disambiguated.
1840// This was suspected to be an issue in HLSL, but HLSL seems to be able to natively choose between
1841// the function signatures in this case.
1842TEST_P(GLSLTest_ES3, AmbiguousConstructorCall2x3)
1843{
1844 const std::string fragmentShaderSource =
1845 "#version 300 es\n"
1846 "precision highp float;\n"
1847 "out vec4 my_FragColor;\n"
1848 "void main()\n"
1849 "{\n"
1850 " my_FragColor = vec4(0.0);\n"
1851 "}";
1852
1853 const std::string vertexShaderSource =
1854 "#version 300 es\n"
1855 "precision highp float;\n"
1856 "in mat3x2 a_matA;\n"
1857 "in mat2x3 a_matB;\n"
1858 "void main()\n"
1859 "{\n"
1860 " gl_Position = vec4(a_matA) + vec4(a_matB);\n"
1861 "}";
1862
1863 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1864 EXPECT_NE(0u, program);
1865}
1866
1867// Test that two functions which have vec4 and mat2 parameters get disambiguated (issue in HLSL).
1868TEST_P(GLSLTest_ES3, AmbiguousFunctionCall2x2)
1869{
1870 const std::string fragmentShaderSource =
1871 "#version 300 es\n"
1872 "precision highp float;\n"
1873 "out vec4 my_FragColor;\n"
1874 "void main()\n"
1875 "{\n"
1876 " my_FragColor = vec4(0.0);\n"
1877 "}";
1878
1879 const std::string vertexShaderSource =
1880 "#version 300 es\n"
1881 "precision highp float;\n"
1882 "in vec4 a_vec;\n"
1883 "in mat2 a_mat;\n"
1884 "vec4 foo(vec4 a)\n"
1885 "{\n"
1886 " return a;\n"
1887 "}\n"
1888 "vec4 foo(mat2 a)\n"
1889 "{\n"
1890 " return vec4(a[0][0]);\n"
1891 "}\n"
1892 "void main()\n"
1893 "{\n"
1894 " gl_Position = foo(a_vec) + foo(a_mat);\n"
1895 "}";
1896
1897 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1898 EXPECT_NE(0u, program);
1899}
1900
1901// Test that an user-defined function with a large number of float4 parameters doesn't fail due to
1902// the function name being too long.
1903TEST_P(GLSLTest_ES3, LargeNumberOfFloat4Parameters)
1904{
1905 const std::string fragmentShaderSource =
1906 "#version 300 es\n"
1907 "precision highp float;\n"
1908 "out vec4 my_FragColor;\n"
1909 "void main()\n"
1910 "{\n"
1911 " my_FragColor = vec4(0.0);\n"
1912 "}";
1913
1914 std::stringstream vertexShaderStream;
1915 const unsigned int paramCount = 1024u;
1916
1917 vertexShaderStream << "#version 300 es\n"
1918 "precision highp float;\n"
1919 "in vec4 a_vec;\n"
1920 "vec4 lotsOfVec4Parameters(";
1921 for (unsigned int i = 0; i < paramCount; ++i)
1922 {
1923 vertexShaderStream << "vec4 a" << i << ", ";
1924 }
1925 vertexShaderStream << "vec4 aLast)\n"
1926 "{\n"
1927 " return ";
1928 for (unsigned int i = 0; i < paramCount; ++i)
1929 {
1930 vertexShaderStream << "a" << i << " + ";
1931 }
1932 vertexShaderStream << "aLast;\n"
1933 "}\n"
1934 "void main()\n"
1935 "{\n"
1936 " gl_Position = lotsOfVec4Parameters(";
1937 for (unsigned int i = 0; i < paramCount; ++i)
1938 {
1939 vertexShaderStream << "a_vec, ";
1940 }
1941 vertexShaderStream << "a_vec);\n"
1942 "}";
1943
1944 GLuint program = CompileProgram(vertexShaderStream.str(), fragmentShaderSource);
1945 EXPECT_NE(0u, program);
1946}
1947
Olli Etuahod4f4c112016-04-15 15:11:24 +03001948// This test was written specifically to stress DeferGlobalInitializers AST transformation.
1949// Test a shader where a global constant array is initialized with an expression containing array
1950// indexing. This initializer is tricky to constant fold, so if it's not constant folded it needs to
1951// be handled in a way that doesn't generate statements in the global scope in HLSL output.
1952// Also includes multiple array initializers in one declaration, where only the second one has
1953// array indexing. This makes sure that the qualifier for the declaration is set correctly if
1954// transformations are applied to the declaration also in the case of ESSL output.
1955TEST_P(GLSLTest_ES3, InitGlobalArrayWithArrayIndexing)
1956{
Yuly Novikov41db2242016-06-25 00:14:28 -04001957 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1428 is fixed
1958 if (IsAndroid() && IsAdreno() && IsOpenGLES())
1959 {
1960 std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
1961 return;
1962 }
1963
Olli Etuahod4f4c112016-04-15 15:11:24 +03001964 const std::string vertexShaderSource =
1965 "#version 300 es\n"
1966 "precision highp float;\n"
1967 "in vec4 a_vec;\n"
1968 "void main()\n"
1969 "{\n"
1970 " gl_Position = vec4(a_vec);\n"
1971 "}";
1972
1973 const std::string fragmentShaderSource =
1974 "#version 300 es\n"
1975 "precision highp float;\n"
1976 "out vec4 my_FragColor;\n"
1977 "const highp float f[2] = float[2](0.1, 0.2);\n"
1978 "const highp float[2] g = float[2](0.3, 0.4), h = float[2](0.5, f[1]);\n"
1979 "void main()\n"
1980 "{\n"
1981 " my_FragColor = vec4(h[1]);\n"
1982 "}";
1983
1984 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1985 EXPECT_NE(0u, program);
1986}
1987
Corentin Wallez419bfc92016-06-28 10:54:45 -07001988// Test that index-constant sampler array indexing is supported.
1989TEST_P(GLSLTest, IndexConstantSamplerArrayIndexing)
1990{
1991 if (IsD3D11_FL93()) {
1992 std::cout << "Test skipped on D3D11 FL 9.3." << std::endl;
1993 return;
1994 }
1995
1996 const std::string vertexShaderSource =
1997 "attribute vec4 vPosition;\n"
1998 "void main()\n"
1999 "{\n"
2000 " gl_Position = vPosition;\n"
2001 "}";
2002
2003 const std::string fragmentShaderSource =
2004 "precision mediump float;\n"
2005 "uniform sampler2D uni[2];\n"
2006 "\n"
2007 "float zero(int x)\n"
2008 "{\n"
2009 " return float(x) - float(x);\n"
2010 "}\n"
2011 "\n"
2012 "void main()\n"
2013 "{\n"
2014 " vec4 c = vec4(0,0,0,0);\n"
2015 " for (int ii = 1; ii < 3; ++ii) {\n"
2016 " if (c.x > 255.0) {\n"
2017 " c.x = 255.0 + zero(ii);\n"
2018 " break;\n"
2019 " }\n"
2020 // Index the sampler array with a predictable loop index (index-constant) as opposed to
2021 // a true constant. This is valid in OpenGL ES but isn't in many Desktop OpenGL versions,
2022 // without an extension.
2023 " c += texture2D(uni[ii - 1], vec2(0.5, 0.5));\n"
2024 " }\n"
2025 " gl_FragColor = c;\n"
2026 "}";
2027
2028 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
2029 EXPECT_NE(0u, program);
2030}
2031
Corentin Wallezb00dcee2016-07-11 17:42:58 -04002032// Test that the #pragma directive is supported and doesn't trigger a compilation failure on the
2033// native driver. The only pragma that gets passed to the OpenGL driver is "invariant" but we don't
2034// want to test its behavior, so don't use any varyings.
2035TEST_P(GLSLTest, PragmaDirective)
2036{
2037 const std::string vertexShaderSource =
2038 "#pragma STDGL invariant(all)\n"
2039 "void main()\n"
2040 "{\n"
2041 " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
2042 "}\n";
2043
2044 const std::string fragmentShaderSource =
2045 "precision mediump float;\n"
2046 "void main()\n"
2047 "{\n"
2048 " gl_FragColor = vec4(1.0);\n"
2049 "}\n";
2050
2051 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
2052 EXPECT_NE(0u, program);
2053}
2054
Olli Etuahoe1d199b2016-07-19 17:14:27 +03002055// Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9).
2056// The function call that returns the array needs to be evaluated after ++j for the expression to
2057// return the correct value (true).
2058TEST_P(GLSLTest_ES3, SequenceOperatorEvaluationOrderArray)
2059{
2060 const std::string &fragmentShaderSource =
2061 "#version 300 es\n"
2062 "precision mediump float;\n"
2063 "out vec4 my_FragColor; \n"
2064 "int[2] func(int param) {\n"
2065 " return int[2](param, param);\n"
2066 "}\n"
2067 "void main() {\n"
2068 " int a[2]; \n"
2069 " for (int i = 0; i < 2; ++i) {\n"
2070 " a[i] = 1;\n"
2071 " }\n"
2072 " int j = 0; \n"
2073 " bool result = ((++j), (a == func(j)));\n"
2074 " my_FragColor = vec4(0.0, (result ? 1.0 : 0.0), 0.0, 1.0);\n"
2075 "}\n";
2076
2077 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
2078 ASSERT_NE(0u, program);
2079
2080 drawQuad(program, "inputAttribute", 0.5f);
2081
2082 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2083}
2084
2085// Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9).
2086// The short-circuiting expression needs to be evaluated after ++j for the expression to return the
2087// correct value (true).
2088TEST_P(GLSLTest_ES3, SequenceOperatorEvaluationOrderShortCircuit)
2089{
2090 const std::string &fragmentShaderSource =
2091 "#version 300 es\n"
2092 "precision mediump float;\n"
2093 "out vec4 my_FragColor; \n"
2094 "void main() {\n"
2095 " int j = 0; \n"
2096 " bool result = ((++j), (j == 1 ? true : (++j == 3)));\n"
2097 " my_FragColor = vec4(0.0, ((result && j == 1) ? 1.0 : 0.0), 0.0, 1.0);\n"
2098 "}\n";
2099
2100 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
2101 ASSERT_NE(0u, program);
2102
2103 drawQuad(program, "inputAttribute", 0.5f);
2104
2105 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2106}
2107
Olli Etuaho7da98502016-07-20 18:45:09 +03002108// Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9).
2109// Indexing the vector needs to be evaluated after func() for the right result.
2110TEST_P(GLSLTest_ES3, SequenceOperatorEvaluationOrderDynamicVectorIndexingInLValue)
2111{
2112 const std::string &fragmentShaderSource =
2113 "#version 300 es\n"
2114 "precision mediump float;\n"
2115 "out vec4 my_FragColor;\n"
2116 "uniform int u_zero;\n"
2117 "int sideEffectCount = 0;\n"
2118 "float func() {\n"
2119 " ++sideEffectCount;\n"
2120 " return -1.0;\n"
2121 "}\n"
2122 "void main() {\n"
2123 " vec4 v = vec4(0.0, 2.0, 4.0, 6.0); \n"
2124 " float f = (func(), (++v[u_zero + sideEffectCount]));\n"
2125 " bool green = abs(f - 3.0) < 0.01 && abs(v[1] - 3.0) < 0.01 && sideEffectCount == 1;\n"
2126 " my_FragColor = vec4(0.0, (green ? 1.0 : 0.0), 0.0, 1.0);\n"
2127 "}\n";
2128
2129 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
2130 ASSERT_NE(0u, program);
2131
2132 drawQuad(program, "inputAttribute", 0.5f);
2133
2134 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2135}
2136
Jamie Madillfa05f602015-05-07 13:47:11 -04002137// 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 -05002138ANGLE_INSTANTIATE_TEST(GLSLTest,
2139 ES2_D3D9(),
2140 ES2_D3D11(),
2141 ES2_D3D11_FL9_3(),
2142 ES2_OPENGL(),
2143 ES3_OPENGL(),
2144 ES2_OPENGLES(),
2145 ES3_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04002146
2147// 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 -05002148ANGLE_INSTANTIATE_TEST(GLSLTest_ES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());