blob: 18622efe20f5ae3d8c48bcd46684792cfe68d720 [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 Madill6c9503e2016-08-16 14:06:32 -040015namespace
16{
17
Jamie Madill2bf8b372014-06-16 17:18:51 -040018class GLSLTest : public ANGLETest
Jamie Madill96509e42014-05-29 14:33:27 -040019{
Jamie Madillfa05f602015-05-07 13:47:11 -040020 protected:
21 GLSLTest()
Jamie Madill96509e42014-05-29 14:33:27 -040022 {
23 setWindowWidth(128);
24 setWindowHeight(128);
25 setConfigRedBits(8);
26 setConfigGreenBits(8);
27 setConfigBlueBits(8);
28 setConfigAlphaBits(8);
29 }
Jamie Madillbfa91f42014-06-05 15:45:18 -040030
31 virtual void SetUp()
32 {
33 ANGLETest::SetUp();
34
Jamie Madill2bf8b372014-06-16 17:18:51 -040035 mSimpleVSSource = SHADER_SOURCE
Jamie Madillbfa91f42014-06-05 15:45:18 -040036 (
37 attribute vec4 inputAttribute;
38 void main()
39 {
40 gl_Position = inputAttribute;
41 }
42 );
43 }
44
Austin Kinrossaf875522014-08-25 21:06:07 -070045 std::string GenerateVaryingType(GLint vectorSize)
46 {
47 char varyingType[10];
48
49 if (vectorSize == 1)
50 {
51 sprintf(varyingType, "float");
52 }
53 else
54 {
55 sprintf(varyingType, "vec%d", vectorSize);
56 }
57
58 return std::string(varyingType);
59 }
60
61 std::string GenerateVectorVaryingDeclaration(GLint vectorSize, GLint arraySize, GLint id)
62 {
63 char buff[100];
64
65 if (arraySize == 1)
66 {
67 sprintf(buff, "varying %s v%d;\n", GenerateVaryingType(vectorSize).c_str(), id);
68 }
69 else
70 {
71 sprintf(buff, "varying %s v%d[%d];\n", GenerateVaryingType(vectorSize).c_str(), id, arraySize);
72 }
73
74 return std::string(buff);
75 }
76
77 std::string GenerateVectorVaryingSettingCode(GLint vectorSize, GLint arraySize, GLint id)
78 {
79 std::string returnString;
80 char buff[100];
81
82 if (arraySize == 1)
83 {
84 sprintf(buff, "\t v%d = %s(1.0);\n", id, GenerateVaryingType(vectorSize).c_str());
85 returnString += buff;
86 }
87 else
88 {
89 for (int i = 0; i < arraySize; i++)
90 {
91 sprintf(buff, "\t v%d[%d] = %s(1.0);\n", id, i, GenerateVaryingType(vectorSize).c_str());
92 returnString += buff;
93 }
94 }
95
96 return returnString;
97 }
98
99 std::string GenerateVectorVaryingUseCode(GLint arraySize, GLint id)
100 {
101 if (arraySize == 1)
102 {
103 char buff[100];
104 sprintf(buff, "v%d + ", id);
105 return std::string(buff);
106 }
107 else
108 {
109 std::string returnString;
110 for (int i = 0; i < arraySize; i++)
111 {
112 char buff[100];
113 sprintf(buff, "v%d[%d] + ", id, i);
114 returnString += buff;
115 }
116 return returnString;
117 }
118 }
119
Austin Kinross8b695ee2015-03-12 13:12:20 -0700120 void GenerateGLSLWithVaryings(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
121 GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize,
122 std::string* fragmentShader, std::string* vertexShader)
Austin Kinrossaf875522014-08-25 21:06:07 -0700123 {
124 // Generate a string declaring the varyings, to share between the fragment shader and the vertex shader.
125 std::string varyingDeclaration;
126
127 unsigned int varyingCount = 0;
128
129 for (GLint i = 0; i < floatCount; i++)
130 {
131 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 1, varyingCount);
132 varyingCount += 1;
133 }
134
135 for (GLint i = 0; i < floatArrayCount; i++)
136 {
137 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 2, varyingCount);
138 varyingCount += 1;
139 }
140
141 for (GLint i = 0; i < vec2Count; i++)
142 {
143 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 1, varyingCount);
144 varyingCount += 1;
145 }
146
147 for (GLint i = 0; i < vec2ArrayCount; i++)
148 {
149 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 2, varyingCount);
150 varyingCount += 1;
151 }
152
153 for (GLint i = 0; i < vec3Count; i++)
154 {
155 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 1, varyingCount);
156 varyingCount += 1;
157 }
158
159 for (GLint i = 0; i < vec3ArrayCount; i++)
160 {
161 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 2, varyingCount);
162 varyingCount += 1;
163 }
164
Austin Kinross8b695ee2015-03-12 13:12:20 -0700165 for (GLint i = 0; i < vec4Count; i++)
166 {
167 varyingDeclaration += GenerateVectorVaryingDeclaration(4, 1, varyingCount);
168 varyingCount += 1;
169 }
170
171 for (GLint i = 0; i < vec4ArrayCount; i++)
172 {
173 varyingDeclaration += GenerateVectorVaryingDeclaration(4, 2, varyingCount);
174 varyingCount += 1;
175 }
176
Austin Kinrossaf875522014-08-25 21:06:07 -0700177 // Generate the vertex shader
178 vertexShader->clear();
179 vertexShader->append(varyingDeclaration);
180 vertexShader->append("\nvoid main()\n{\n");
181
182 unsigned int currentVSVarying = 0;
183
184 for (GLint i = 0; i < floatCount; i++)
185 {
186 vertexShader->append(GenerateVectorVaryingSettingCode(1, 1, currentVSVarying));
187 currentVSVarying += 1;
188 }
189
190 for (GLint i = 0; i < floatArrayCount; i++)
191 {
192 vertexShader->append(GenerateVectorVaryingSettingCode(1, 2, currentVSVarying));
193 currentVSVarying += 1;
194 }
195
196 for (GLint i = 0; i < vec2Count; i++)
197 {
198 vertexShader->append(GenerateVectorVaryingSettingCode(2, 1, currentVSVarying));
199 currentVSVarying += 1;
200 }
201
202 for (GLint i = 0; i < vec2ArrayCount; i++)
203 {
204 vertexShader->append(GenerateVectorVaryingSettingCode(2, 2, currentVSVarying));
205 currentVSVarying += 1;
206 }
207
208 for (GLint i = 0; i < vec3Count; i++)
209 {
210 vertexShader->append(GenerateVectorVaryingSettingCode(3, 1, currentVSVarying));
211 currentVSVarying += 1;
212 }
213
214 for (GLint i = 0; i < vec3ArrayCount; i++)
215 {
216 vertexShader->append(GenerateVectorVaryingSettingCode(3, 2, currentVSVarying));
217 currentVSVarying += 1;
218 }
219
Austin Kinross8b695ee2015-03-12 13:12:20 -0700220 for (GLint i = 0; i < vec4Count; i++)
221 {
222 vertexShader->append(GenerateVectorVaryingSettingCode(4, 1, currentVSVarying));
223 currentVSVarying += 1;
224 }
225
226 for (GLint i = 0; i < vec4ArrayCount; i++)
227 {
228 vertexShader->append(GenerateVectorVaryingSettingCode(4, 2, currentVSVarying));
229 currentVSVarying += 1;
230 }
231
232 if (usePointSize)
233 {
234 vertexShader->append("gl_PointSize = 1.0;\n");
235 }
236
Austin Kinrossaf875522014-08-25 21:06:07 -0700237 vertexShader->append("}\n");
238
239 // Generate the fragment shader
240 fragmentShader->clear();
241 fragmentShader->append("precision highp float;\n");
242 fragmentShader->append(varyingDeclaration);
243 fragmentShader->append("\nvoid main() \n{ \n\tvec4 retColor = vec4(0,0,0,0);\n");
244
245 unsigned int currentFSVarying = 0;
246
247 // Make use of the float varyings
248 fragmentShader->append("\tretColor += vec4(");
249
250 for (GLint i = 0; i < floatCount; i++)
251 {
252 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
253 currentFSVarying += 1;
254 }
255
256 for (GLint i = 0; i < floatArrayCount; i++)
257 {
258 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
259 currentFSVarying += 1;
260 }
261
262 fragmentShader->append("0.0, 0.0, 0.0, 0.0);\n");
263
264 // Make use of the vec2 varyings
265 fragmentShader->append("\tretColor += vec4(");
266
267 for (GLint i = 0; i < vec2Count; i++)
268 {
269 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
270 currentFSVarying += 1;
271 }
272
273 for (GLint i = 0; i < vec2ArrayCount; i++)
274 {
275 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
276 currentFSVarying += 1;
277 }
278
279 fragmentShader->append("vec2(0.0, 0.0), 0.0, 0.0);\n");
280
281 // Make use of the vec3 varyings
282 fragmentShader->append("\tretColor += vec4(");
283
284 for (GLint i = 0; i < vec3Count; i++)
285 {
286 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
287 currentFSVarying += 1;
288 }
289
290 for (GLint i = 0; i < vec3ArrayCount; i++)
291 {
292 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
293 currentFSVarying += 1;
294 }
295
296 fragmentShader->append("vec3(0.0, 0.0, 0.0), 0.0);\n");
Austin Kinross8b695ee2015-03-12 13:12:20 -0700297
298 // Make use of the vec4 varyings
299 fragmentShader->append("\tretColor += ");
300
301 for (GLint i = 0; i < vec4Count; i++)
302 {
303 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
304 currentFSVarying += 1;
305 }
306
307 for (GLint i = 0; i < vec4ArrayCount; i++)
308 {
309 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
310 currentFSVarying += 1;
311 }
312
313 fragmentShader->append("vec4(0.0, 0.0, 0.0, 0.0);\n");
314
315 // Set gl_FragColor, and use special variables if requested
316 fragmentShader->append("\tgl_FragColor = retColor");
317
318 if (useFragCoord)
319 {
320 fragmentShader->append(" + gl_FragCoord");
321 }
322
323 if (usePointCoord)
324 {
325 fragmentShader->append(" + vec4(gl_PointCoord, 0.0, 0.0)");
326 }
327
328 fragmentShader->append(";\n}");
329 }
330
331 void VaryingTestBase(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
332 GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize, bool expectSuccess)
333 {
334 std::string fragmentShaderSource;
335 std::string vertexShaderSource;
336
337 GenerateGLSLWithVaryings(floatCount, floatArrayCount, vec2Count, vec2ArrayCount, vec3Count, vec3ArrayCount,
338 vec4Count, vec4ArrayCount, useFragCoord, usePointCoord, usePointSize,
339 &fragmentShaderSource, &vertexShaderSource);
340
341 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
342
343 if (expectSuccess)
344 {
345 EXPECT_NE(0u, program);
346 }
347 else
348 {
349 EXPECT_EQ(0u, program);
350 }
Austin Kinrossaf875522014-08-25 21:06:07 -0700351 }
352
Austin Kinross7a3e8e22015-10-08 15:50:06 -0700353 void CompileGLSLWithUniformsAndSamplers(GLint vertexUniformCount,
354 GLint fragmentUniformCount,
355 GLint vertexSamplersCount,
356 GLint fragmentSamplersCount,
357 bool expectSuccess)
358 {
359 std::stringstream vertexShader;
360 std::stringstream fragmentShader;
361
362 // Generate the vertex shader
363 vertexShader << "precision mediump float;\n";
364
365 for (int i = 0; i < vertexUniformCount; i++)
366 {
367 vertexShader << "uniform vec4 v" << i << ";\n";
368 }
369
370 for (int i = 0; i < vertexSamplersCount; i++)
371 {
372 vertexShader << "uniform sampler2D s" << i << ";\n";
373 }
374
375 vertexShader << "void main()\n{\n";
376
377 for (int i = 0; i < vertexUniformCount; i++)
378 {
379 vertexShader << " gl_Position += v" << i << ";\n";
380 }
381
382 for (int i = 0; i < vertexSamplersCount; i++)
383 {
384 vertexShader << " gl_Position += texture2D(s" << i << ", vec2(0.0, 0.0));\n";
385 }
386
387 if (vertexUniformCount == 0 && vertexSamplersCount == 0)
388 {
389 vertexShader << " gl_Position = vec4(0.0);\n";
390 }
391
392 vertexShader << "}\n";
393
394 // Generate the fragment shader
395 fragmentShader << "precision mediump float;\n";
396
397 for (int i = 0; i < fragmentUniformCount; i++)
398 {
399 fragmentShader << "uniform vec4 v" << i << ";\n";
400 }
401
402 for (int i = 0; i < fragmentSamplersCount; i++)
403 {
404 fragmentShader << "uniform sampler2D s" << i << ";\n";
405 }
406
407 fragmentShader << "void main()\n{\n";
408
409 for (int i = 0; i < fragmentUniformCount; i++)
410 {
411 fragmentShader << " gl_FragColor += v" << i << ";\n";
412 }
413
414 for (int i = 0; i < fragmentSamplersCount; i++)
415 {
416 fragmentShader << " gl_FragColor += texture2D(s" << i << ", vec2(0.0, 0.0));\n";
417 }
418
419 if (fragmentUniformCount == 0 && fragmentSamplersCount == 0)
420 {
421 fragmentShader << " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n";
422 }
423
424 fragmentShader << "}\n";
425
426 GLuint program = CompileProgram(vertexShader.str(), fragmentShader.str());
427
428 if (expectSuccess)
429 {
430 EXPECT_NE(0u, program);
431 }
432 else
433 {
434 EXPECT_EQ(0u, program);
435 }
436 }
437
Jamie Madill2bf8b372014-06-16 17:18:51 -0400438 std::string mSimpleVSSource;
Jamie Madill96509e42014-05-29 14:33:27 -0400439};
440
Jamie Madillfa05f602015-05-07 13:47:11 -0400441class GLSLTest_ES3 : public GLSLTest
Gregoire Payen de La Garanderieb3dced22015-01-12 14:54:55 +0000442{
Olli Etuahoe1d199b2016-07-19 17:14:27 +0300443 void SetUp() override
444 {
445 ANGLETest::SetUp();
446
447 mSimpleVSSource =
448 "#version 300 es\n"
449 "in vec4 inputAttribute;"
450 "void main()"
451 "{"
452 " gl_Position = inputAttribute;"
453 "}";
454 }
Gregoire Payen de La Garanderieb3dced22015-01-12 14:54:55 +0000455};
456
Jamie Madillfa05f602015-05-07 13:47:11 -0400457TEST_P(GLSLTest, NamelessScopedStructs)
Jamie Madill96509e42014-05-29 14:33:27 -0400458{
Jamie Madillbfa91f42014-06-05 15:45:18 -0400459 const std::string fragmentShaderSource = SHADER_SOURCE
Jamie Madill96509e42014-05-29 14:33:27 -0400460 (
Jamie Madillbfa91f42014-06-05 15:45:18 -0400461 precision mediump float;
462
Jamie Madill96509e42014-05-29 14:33:27 -0400463 void main()
464 {
Jamie Madillbfa91f42014-06-05 15:45:18 -0400465 struct
466 {
467 float q;
468 } b;
469
470 gl_FragColor = vec4(1, 0, 0, 1);
471 gl_FragColor.a += b.q;
Jamie Madill96509e42014-05-29 14:33:27 -0400472 }
473 );
474
Jamie Madill5599c8f2014-08-26 13:16:39 -0400475 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madillbfa91f42014-06-05 15:45:18 -0400476 EXPECT_NE(0u, program);
477}
Austin Kinross18b931d2014-09-29 12:58:31 -0700478
Jamie Madillfa05f602015-05-07 13:47:11 -0400479TEST_P(GLSLTest, ScopedStructsOrderBug)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400480{
Geoff Lange0cc2a42016-01-20 10:58:17 -0500481 // TODO(geofflang): Find out why this doesn't compile on Apple OpenGL drivers
482 // (http://anglebug.com/1292)
Geoff Lang5103f4c2016-01-26 11:40:18 -0500483 // TODO(geofflang): Find out why this doesn't compile on AMD OpenGL drivers
Geoff Lange0cc2a42016-01-20 10:58:17 -0500484 // (http://anglebug.com/1291)
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400485 if (IsDesktopOpenGL() && (IsOSX() || !IsNVIDIA()))
Geoff Lange0cc2a42016-01-20 10:58:17 -0500486 {
Jamie Madill518b9fa2016-03-02 11:26:02 -0500487 std::cout << "Test disabled on this OpenGL configuration." << std::endl;
Geoff Lange0cc2a42016-01-20 10:58:17 -0500488 return;
489 }
Geoff Lange0cc2a42016-01-20 10:58:17 -0500490
Jamie Madillbfa91f42014-06-05 15:45:18 -0400491 const std::string fragmentShaderSource = SHADER_SOURCE
492 (
493 precision mediump float;
494
495 struct T
496 {
497 float f;
498 };
499
500 void main()
501 {
502 T a;
503
504 struct T
505 {
506 float q;
507 };
508
509 T b;
510
511 gl_FragColor = vec4(1, 0, 0, 1);
512 gl_FragColor.a += a.f;
513 gl_FragColor.a += b.q;
514 }
515 );
516
Jamie Madill5599c8f2014-08-26 13:16:39 -0400517 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madillbfa91f42014-06-05 15:45:18 -0400518 EXPECT_NE(0u, program);
519}
520
Jamie Madillfa05f602015-05-07 13:47:11 -0400521TEST_P(GLSLTest, ScopedStructsBug)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400522{
Jamie Madill96509e42014-05-29 14:33:27 -0400523 const std::string fragmentShaderSource = SHADER_SOURCE
524 (
525 precision mediump float;
526
527 struct T_0
528 {
529 float f;
530 };
531
532 void main()
533 {
534 gl_FragColor = vec4(1, 0, 0, 1);
535
536 struct T
537 {
538 vec2 v;
539 };
540
541 T_0 a;
542 T b;
543
544 gl_FragColor.a += a.f;
545 gl_FragColor.a += b.v.x;
546 }
547 );
548
Jamie Madill5599c8f2014-08-26 13:16:39 -0400549 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madill2bf8b372014-06-16 17:18:51 -0400550 EXPECT_NE(0u, program);
551}
552
Jamie Madillfa05f602015-05-07 13:47:11 -0400553TEST_P(GLSLTest, DxPositionBug)
Jamie Madill2bf8b372014-06-16 17:18:51 -0400554{
555 const std::string &vertexShaderSource = SHADER_SOURCE
556 (
557 attribute vec4 inputAttribute;
558 varying float dx_Position;
559 void main()
560 {
561 gl_Position = vec4(inputAttribute);
562 dx_Position = 0.0;
563 }
564 );
565
566 const std::string &fragmentShaderSource = SHADER_SOURCE
567 (
568 precision mediump float;
569
570 varying float dx_Position;
571
572 void main()
573 {
574 gl_FragColor = vec4(dx_Position, 0, 0, 1);
575 }
576 );
577
Jamie Madill5599c8f2014-08-26 13:16:39 -0400578 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill96509e42014-05-29 14:33:27 -0400579 EXPECT_NE(0u, program);
580}
Jamie Madill4836d222014-07-24 06:55:51 -0400581
Jamie Madillfa05f602015-05-07 13:47:11 -0400582TEST_P(GLSLTest, ElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400583{
584 const std::string &vertexShaderSource =
585 "attribute vec4 a_position;\n"
586 "varying float v;\n"
587 "void main() {\n"
588 " gl_Position = a_position;\n"
589 " v = 1.0;\n"
590 " if (a_position.x <= 0.5) {\n"
591 " v = 0.0;\n"
592 " } else if (a_position.x >= 0.5) {\n"
593 " v = 2.0;\n"
594 " }\n"
595 "}\n";
596
597 const std::string &fragmentShaderSource =
598 "precision highp float;\n"
599 "varying float v;\n"
600 "void main() {\n"
601 " vec4 color = vec4(1.0, 0.0, 0.0, 1.0);\n"
602 " if (v >= 1.0) color = vec4(0.0, 1.0, 0.0, 1.0);\n"
603 " if (v >= 2.0) color = vec4(0.0, 0.0, 1.0, 1.0);\n"
604 " gl_FragColor = color;\n"
605 "}\n";
606
Jamie Madill5599c8f2014-08-26 13:16:39 -0400607 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400608 ASSERT_NE(0u, program);
609
610 drawQuad(program, "a_position", 0.5f);
Jamie Madill4836d222014-07-24 06:55:51 -0400611
612 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
613 EXPECT_PIXEL_EQ(getWindowWidth()-1, 0, 0, 255, 0, 255);
614}
615
Jamie Madillfa05f602015-05-07 13:47:11 -0400616TEST_P(GLSLTest, TwoElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400617{
618 const std::string &vertexShaderSource =
619 "attribute vec4 a_position;\n"
620 "varying float v;\n"
621 "void main() {\n"
622 " gl_Position = a_position;\n"
Jamie Madill778d5272014-08-04 13:13:25 -0400623 " if (a_position.x == 0.0) {\n"
Jamie Madill4836d222014-07-24 06:55:51 -0400624 " v = 1.0;\n"
625 " } else if (a_position.x > 0.5) {\n"
626 " v = 0.0;\n"
627 " } else if (a_position.x > 0.75) {\n"
628 " v = 0.5;\n"
629 " }\n"
630 "}\n";
631
632 const std::string &fragmentShaderSource =
633 "precision highp float;\n"
634 "varying float v;\n"
635 "void main() {\n"
636 " gl_FragColor = vec4(v, 0.0, 0.0, 1.0);\n"
637 "}\n";
638
Jamie Madill5599c8f2014-08-26 13:16:39 -0400639 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400640 EXPECT_NE(0u, program);
641}
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400642
Jamie Madillfa05f602015-05-07 13:47:11 -0400643TEST_P(GLSLTest, FrontFacingAndVarying)
Jamie Madille6256f82014-09-17 10:31:15 -0400644{
Geoff Langdd323e92015-06-09 15:16:31 -0400645 EGLPlatformParameters platform = GetParam().eglParameters;
Austin Kinross8b695ee2015-03-12 13:12:20 -0700646
Jamie Madille6256f82014-09-17 10:31:15 -0400647 const std::string vertexShaderSource = SHADER_SOURCE
648 (
649 attribute vec4 a_position;
650 varying float v_varying;
651 void main()
652 {
653 v_varying = a_position.x;
654 gl_Position = a_position;
655 }
656 );
657
658 const std::string fragmentShaderSource = SHADER_SOURCE
659 (
660 precision mediump float;
661 varying float v_varying;
662 void main()
663 {
664 vec4 c;
665
666 if (gl_FrontFacing)
667 {
668 c = vec4(v_varying, 0, 0, 1.0);
669 }
670 else
671 {
672 c = vec4(0, v_varying, 0, 1.0);
673 }
674 gl_FragColor = c;
675 }
676 );
677
678 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Austin Kinross02df7962015-07-01 10:03:42 -0700679
680 // Compilation should fail on D3D11 feature level 9_3, since gl_FrontFacing isn't supported.
681 if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
682 {
683 if (platform.majorVersion == 9 && platform.minorVersion == 3)
684 {
685 EXPECT_EQ(0u, program);
686 return;
687 }
688 }
689
690 // Otherwise, compilation should succeed
Jamie Madille6256f82014-09-17 10:31:15 -0400691 EXPECT_NE(0u, program);
692}
693
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400694// Verify that linking shaders declaring different shading language versions fails.
695TEST_P(GLSLTest_ES3, VersionMismatch)
696{
697 const std::string fragmentShaderSource100 =
698 "precision mediump float;\n"
699 "varying float v_varying;\n"
700 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
701
702 const std::string vertexShaderSource100 =
703 "attribute vec4 a_position;\n"
704 "varying float v_varying;\n"
705 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
706
707 const std::string fragmentShaderSource300 =
708 "#version 300 es\n"
709 "precision mediump float;\n"
710 "in float v_varying;\n"
711 "out vec4 my_FragColor;\n"
712 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
713
714 const std::string vertexShaderSource300 =
715 "#version 300 es\n"
716 "in vec4 a_position;\n"
717 "out float v_varying;\n"
718 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
719
720 GLuint program = CompileProgram(vertexShaderSource300, fragmentShaderSource100);
721 EXPECT_EQ(0u, program);
722
723 program = CompileProgram(vertexShaderSource100, fragmentShaderSource300);
724 EXPECT_EQ(0u, program);
725}
726
727// Verify that declaring varying as invariant only in vertex shader fails in ESSL 1.00.
728TEST_P(GLSLTest, InvariantVaryingOut)
729{
730 const std::string fragmentShaderSource =
731 "precision mediump float;\n"
732 "varying float v_varying;\n"
733 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
734
735 const std::string vertexShaderSource =
736 "attribute vec4 a_position;\n"
737 "invariant varying float v_varying;\n"
738 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
739
740 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
741 EXPECT_EQ(0u, program);
742}
743
744// Verify that declaring varying as invariant only in vertex shader succeeds in ESSL 3.00.
745TEST_P(GLSLTest_ES3, InvariantVaryingOut)
746{
747 // TODO: ESSL 3.00 -> GLSL 1.20 translation should add "invariant" in fragment shader
748 // for varyings which are invariant in vertex shader (http://anglebug.com/1293)
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400749 if (IsDesktopOpenGL())
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400750 {
751 std::cout << "Test disabled on OpenGL." << std::endl;
752 return;
753 }
754
755 const std::string fragmentShaderSource =
756 "#version 300 es\n"
757 "precision mediump float;\n"
758 "in float v_varying;\n"
759 "out vec4 my_FragColor;\n"
760 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
761
762 const std::string vertexShaderSource =
763 "#version 300 es\n"
764 "in vec4 a_position;\n"
765 "invariant out float v_varying;\n"
766 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
767
768 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
769 EXPECT_NE(0u, program);
770}
771
772// Verify that declaring varying as invariant only in fragment shader fails in ESSL 1.00.
Jamie Madillfa05f602015-05-07 13:47:11 -0400773TEST_P(GLSLTest, InvariantVaryingIn)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400774{
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400775 const std::string fragmentShaderSource =
776 "precision mediump float;\n"
777 "invariant varying float v_varying;\n"
778 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
Geoff Lange0cc2a42016-01-20 10:58:17 -0500779
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400780 const std::string vertexShaderSource =
781 "attribute vec4 a_position;\n"
782 "varying float v_varying;\n"
783 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400784
Jamie Madill5599c8f2014-08-26 13:16:39 -0400785 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400786 EXPECT_EQ(0u, program);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400787}
788
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400789// Verify that declaring varying as invariant only in fragment shader fails in ESSL 3.00.
790TEST_P(GLSLTest_ES3, InvariantVaryingIn)
791{
792 const std::string fragmentShaderSource =
793 "#version 300 es\n"
794 "precision mediump float;\n"
795 "invariant in float v_varying;\n"
796 "out vec4 my_FragColor;\n"
797 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
798
799 const std::string vertexShaderSource =
800 "#version 300 es\n"
801 "in vec4 a_position;\n"
802 "out float v_varying;\n"
803 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
804
805 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
806 EXPECT_EQ(0u, program);
807}
808
809// Verify that declaring varying as invariant in both shaders succeeds in ESSL 1.00.
Jamie Madillfa05f602015-05-07 13:47:11 -0400810TEST_P(GLSLTest, InvariantVaryingBoth)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400811{
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400812 const std::string fragmentShaderSource =
813 "precision mediump float;\n"
814 "invariant varying float v_varying;\n"
815 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400816
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400817 const std::string vertexShaderSource =
818 "attribute vec4 a_position;\n"
819 "invariant varying float v_varying;\n"
820 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400821
Jamie Madill5599c8f2014-08-26 13:16:39 -0400822 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400823 EXPECT_NE(0u, program);
824}
825
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400826// Verify that declaring varying as invariant in both shaders fails in ESSL 3.00.
827TEST_P(GLSLTest_ES3, InvariantVaryingBoth)
828{
829 const std::string fragmentShaderSource =
830 "#version 300 es\n"
831 "precision mediump float;\n"
832 "invariant in float v_varying;\n"
833 "out vec4 my_FragColor;\n"
834 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
835
836 const std::string vertexShaderSource =
837 "#version 300 es\n"
838 "in vec4 a_position;\n"
839 "invariant out float v_varying;\n"
840 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
841
842 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
843 EXPECT_EQ(0u, program);
844}
845
846// Verify that declaring gl_Position as invariant succeeds in ESSL 1.00.
Jamie Madillfa05f602015-05-07 13:47:11 -0400847TEST_P(GLSLTest, InvariantGLPosition)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400848{
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400849 const std::string fragmentShaderSource =
850 "precision mediump float;\n"
851 "varying float v_varying;\n"
852 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400853
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400854 const std::string vertexShaderSource =
855 "attribute vec4 a_position;\n"
856 "invariant gl_Position;\n"
857 "varying float v_varying;\n"
858 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400859
Jamie Madill5599c8f2014-08-26 13:16:39 -0400860 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400861 EXPECT_NE(0u, program);
862}
863
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400864// Verify that declaring gl_Position as invariant succeeds in ESSL 3.00.
865TEST_P(GLSLTest_ES3, InvariantGLPosition)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400866{
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400867 const std::string fragmentShaderSource =
868 "#version 300 es\n"
869 "precision mediump float;\n"
870 "in float v_varying;\n"
871 "out vec4 my_FragColor;\n"
872 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
873
874 const std::string vertexShaderSource =
875 "#version 300 es\n"
876 "in vec4 a_position;\n"
877 "invariant gl_Position;\n"
878 "out float v_varying;\n"
879 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
880
881 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
882 EXPECT_NE(0u, program);
883}
884
885// Verify that using invariant(all) in both shaders succeeds in ESSL 1.00.
886TEST_P(GLSLTest, InvariantAllBoth)
887{
888 // TODO: ESSL 1.00 -> GLSL 1.20 translation should add "invariant" in fragment shader
889 // for varyings which are invariant in vertex shader individually,
890 // and remove invariant(all) from fragment shader (http://anglebug.com/1293)
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400891 if (IsDesktopOpenGL())
Geoff Lange0cc2a42016-01-20 10:58:17 -0500892 {
893 std::cout << "Test disabled on OpenGL." << std::endl;
894 return;
895 }
896
Yuly Novikova1f6dc92016-06-15 23:27:04 -0400897 const std::string fragmentShaderSource =
898 "#pragma STDGL invariant(all)\n"
899 "precision mediump float;\n"
900 "varying float v_varying;\n"
901 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400902
903 const std::string vertexShaderSource =
904 "#pragma STDGL invariant(all)\n"
905 "attribute vec4 a_position;\n"
906 "varying float v_varying;\n"
907 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
908
Jamie Madill5599c8f2014-08-26 13:16:39 -0400909 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400910 EXPECT_NE(0u, program);
911}
Austin Kinrossaf875522014-08-25 21:06:07 -0700912
Geoff Lang156d7192016-07-21 16:11:00 -0400913// Verify that functions without return statements still compile
914TEST_P(GLSLTest, MissingReturnFloat)
915{
916 const std::string vertexShaderSource =
917 "varying float v_varying;\n"
918 "float f() { if (v_varying > 0.0) return 1.0; }\n"
919 "void main() { gl_Position = vec4(f(), 0, 0, 1); }\n";
920
921 const std::string fragmentShaderSource =
922 "precision mediump float;\n"
923 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
924
925 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
926 EXPECT_NE(0u, program);
927}
928
929// Verify that functions without return statements still compile
930TEST_P(GLSLTest, MissingReturnVec2)
931{
932 const std::string vertexShaderSource =
933 "varying float v_varying;\n"
934 "vec2 f() { if (v_varying > 0.0) return vec2(1.0, 1.0); }\n"
935 "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
936
937 const std::string fragmentShaderSource =
938 "precision mediump float;\n"
939 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
940
941 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
942 EXPECT_NE(0u, program);
943}
944
945// Verify that functions without return statements still compile
946TEST_P(GLSLTest, MissingReturnVec3)
947{
948 const std::string vertexShaderSource =
949 "varying float v_varying;\n"
950 "vec3 f() { if (v_varying > 0.0) return vec3(1.0, 1.0, 1.0); }\n"
951 "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
952
953 const std::string fragmentShaderSource =
954 "precision mediump float;\n"
955 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
956
957 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
958 EXPECT_NE(0u, program);
959}
960
961// Verify that functions without return statements still compile
962TEST_P(GLSLTest, MissingReturnVec4)
963{
964 const std::string vertexShaderSource =
965 "varying float v_varying;\n"
966 "vec4 f() { if (v_varying > 0.0) return vec4(1.0, 1.0, 1.0, 1.0); }\n"
967 "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
968
969 const std::string fragmentShaderSource =
970 "precision mediump float;\n"
971 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
972
973 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
974 EXPECT_NE(0u, program);
975}
976
977// Verify that functions without return statements still compile
978TEST_P(GLSLTest, MissingReturnIVec4)
979{
980 const std::string vertexShaderSource =
981 "varying float v_varying;\n"
982 "ivec4 f() { if (v_varying > 0.0) return ivec4(1, 1, 1, 1); }\n"
983 "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n";
984
985 const std::string fragmentShaderSource =
986 "precision mediump float;\n"
987 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
988
989 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
990 EXPECT_NE(0u, program);
991}
992
993// Verify that functions without return statements still compile
994TEST_P(GLSLTest, MissingReturnMat4)
995{
996 const std::string vertexShaderSource =
997 "varying float v_varying;\n"
998 "mat4 f() { if (v_varying > 0.0) return mat4(1.0); }\n"
999 "void main() { gl_Position = vec4(f()[0][0], 0, 0, 1); }\n";
1000
1001 const std::string fragmentShaderSource =
1002 "precision mediump float;\n"
1003 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
1004
1005 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1006 EXPECT_NE(0u, program);
1007}
1008
1009// Verify that functions without return statements still compile
1010TEST_P(GLSLTest, MissingReturnStruct)
1011{
1012 const std::string vertexShaderSource =
1013 "varying float v_varying;\n"
1014 "struct s { float a; int b; vec2 c; };\n"
1015 "s f() { if (v_varying > 0.0) return s(1.0, 1, vec2(1.0, 1.0)); }\n"
1016 "void main() { gl_Position = vec4(f().a, 0, 0, 1); }\n";
1017
1018 const std::string fragmentShaderSource =
1019 "precision mediump float;\n"
1020 "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n";
1021
1022 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1023 EXPECT_NE(0u, program);
1024}
1025
1026// Verify that functions without return statements still compile
1027TEST_P(GLSLTest_ES3, MissingReturnArray)
1028{
1029 const std::string vertexShaderSource =
1030 "#version 300 es\n"
1031 "in float v_varying;\n"
1032 "vec2[2] f() { if (v_varying > 0.0) { return vec2[2](vec2(1.0, 1.0), vec2(1.0, 1.0)); } }\n"
1033 "void main() { gl_Position = vec4(f()[0].x, 0, 0, 1); }\n";
1034
1035 const std::string fragmentShaderSource =
1036 "#version 300 es\n"
1037 "precision mediump float;\n"
1038 "out vec4 my_FragColor;\n"
1039 "void main() { my_FragColor = vec4(0, 0, 0, 1); }\n";
1040
1041 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1042 EXPECT_NE(0u, program);
1043}
1044
1045// Verify that functions without return statements still compile
1046TEST_P(GLSLTest_ES3, MissingReturnArrayOfStructs)
1047{
1048 const std::string vertexShaderSource =
1049 "#version 300 es\n"
1050 "in float v_varying;\n"
1051 "struct s { float a; int b; vec2 c; };\n"
1052 "s[2] f() { if (v_varying > 0.0) { return s[2](s(1.0, 1, vec2(1.0, 1.0)), s(1.0, 1, "
1053 "vec2(1.0, 1.0))); } }\n"
1054 "void main() { gl_Position = vec4(f()[0].a, 0, 0, 1); }\n";
1055
1056 const std::string fragmentShaderSource =
1057 "#version 300 es\n"
1058 "precision mediump float;\n"
1059 "out vec4 my_FragColor;\n"
1060 "void main() { my_FragColor = vec4(0, 0, 0, 1); }\n";
1061
1062 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1063 EXPECT_NE(0u, program);
1064}
1065
Corentin Wallez509e4562016-08-25 14:55:44 -04001066// Verify that functions without return statements still compile
1067TEST_P(GLSLTest_ES3, MissingReturnStructOfArrays)
1068{
1069 // TODO(cwallez) remove the suppression once NVIDIA removes the restriction for
1070 // GLSL >= 300. It was defined only in GLSL 2.0, section 6.1.
1071 if (IsNVIDIA() && IsOpenGLES())
1072 {
1073 std::cout << "Test skipped on NVIDIA OpenGL ES because it disallows returning "
1074 "structure of arrays"
1075 << std::endl;
1076 return;
1077 }
1078
1079 const std::string vertexShaderSource =
1080 "#version 300 es\n"
1081 "in float v_varying;\n"
1082 "struct s { float a[2]; int b[2]; vec2 c[2]; };\n"
1083 "s f() { if (v_varying > 0.0) { return s(float[2](1.0, 1.0), int[2](1, 1),"
1084 "vec2[2](vec2(1.0, 1.0), vec2(1.0, 1.0))); } }\n"
1085 "void main() { gl_Position = vec4(f().a[0], 0, 0, 1); }\n";
1086
1087 const std::string fragmentShaderSource =
1088 "#version 300 es\n"
1089 "precision mediump float;\n"
1090 "out vec4 my_FragColor;\n"
1091 "void main() { my_FragColor = vec4(0, 0, 0, 1); }\n";
1092
1093 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1094 EXPECT_NE(0u, program);
1095}
1096
Yuly Novikova1f6dc92016-06-15 23:27:04 -04001097// Verify that using invariant(all) in both shaders fails in ESSL 3.00.
1098TEST_P(GLSLTest_ES3, InvariantAllBoth)
1099{
1100 const std::string fragmentShaderSource =
1101 "#version 300 es\n"
1102 "#pragma STDGL invariant(all)\n"
1103 "precision mediump float;\n"
1104 "in float v_varying;\n"
1105 "out vec4 my_FragColor;\n"
1106 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1107
1108 const std::string vertexShaderSource =
1109 "#version 300 es\n"
1110 "#pragma STDGL invariant(all)\n"
1111 "in vec4 a_position;\n"
1112 "out float v_varying;\n"
1113 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1114
1115 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1116 EXPECT_EQ(0u, program);
1117}
1118
1119// Verify that using invariant(all) only in fragment shader fails in ESSL 1.00.
1120TEST_P(GLSLTest, InvariantAllIn)
1121{
1122 const std::string fragmentShaderSource =
1123 "#pragma STDGL invariant(all)\n"
1124 "precision mediump float;\n"
1125 "varying float v_varying;\n"
1126 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1127
1128 const std::string vertexShaderSource =
1129 "attribute vec4 a_position;\n"
1130 "varying float v_varying;\n"
1131 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1132
1133 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1134 EXPECT_EQ(0u, program);
1135}
1136
1137// Verify that using invariant(all) only in fragment shader fails in ESSL 3.00.
1138TEST_P(GLSLTest_ES3, InvariantAllIn)
1139{
1140 const std::string fragmentShaderSource =
1141 "#version 300 es\n"
1142 "#pragma STDGL invariant(all)\n"
1143 "precision mediump float;\n"
1144 "in float v_varying;\n"
1145 "out vec4 my_FragColor;\n"
1146 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1147
1148 const std::string vertexShaderSource =
1149 "#version 300 es\n"
1150 "in vec4 a_position;\n"
1151 "out float v_varying;\n"
1152 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1153
1154 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1155 EXPECT_EQ(0u, program);
1156}
1157
1158// Verify that using invariant(all) only in vertex shader fails in ESSL 1.00.
1159TEST_P(GLSLTest, InvariantAllOut)
1160{
1161 const std::string fragmentShaderSource =
1162 "precision mediump float;\n"
1163 "varying float v_varying;\n"
1164 "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1165
1166 const std::string vertexShaderSource =
1167 "#pragma STDGL invariant(all)\n"
1168 "attribute vec4 a_position;\n"
1169 "varying float v_varying;\n"
1170 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1171
1172 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1173 EXPECT_EQ(0u, program);
1174}
1175
1176// Verify that using invariant(all) only in vertex shader succeeds in ESSL 3.00.
1177TEST_P(GLSLTest_ES3, InvariantAllOut)
1178{
1179 // TODO: ESSL 3.00 -> GLSL 1.20 translation should add "invariant" in fragment shader
1180 // for varyings which are invariant in vertex shader,
1181 // because of invariant(all) being used in vertex shader (http://anglebug.com/1293)
Corentin Wallezc7f59d02016-06-20 10:12:08 -04001182 if (IsDesktopOpenGL())
Yuly Novikova1f6dc92016-06-15 23:27:04 -04001183 {
1184 std::cout << "Test disabled on OpenGL." << std::endl;
1185 return;
1186 }
1187
1188 const std::string fragmentShaderSource =
1189 "#version 300 es\n"
1190 "precision mediump float;\n"
1191 "in float v_varying;\n"
1192 "out vec4 my_FragColor;\n"
1193 "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n";
1194
1195 const std::string vertexShaderSource =
1196 "#version 300 es\n"
1197 "#pragma STDGL invariant(all)\n"
1198 "in vec4 a_position;\n"
1199 "out float v_varying;\n"
1200 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
1201
1202 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1203 EXPECT_NE(0u, program);
1204}
1205
Jamie Madillfa05f602015-05-07 13:47:11 -04001206TEST_P(GLSLTest, MaxVaryingVec4)
Austin Kinross8b695ee2015-03-12 13:12:20 -07001207{
Geoff Lang69accbd2016-01-25 16:22:32 -05001208#if defined(__APPLE__)
1209 // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
1210 // (http://anglebug.com/1291)
Jamie Madill518b9fa2016-03-02 11:26:02 -05001211 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lang69accbd2016-01-25 16:22:32 -05001212 {
1213 std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
1214 return;
1215 }
1216#endif
1217
Austin Kinross8b695ee2015-03-12 13:12:20 -07001218 GLint maxVaryings = 0;
1219 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1220
1221 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, false, false, true);
1222}
1223
Jamie Madillfa05f602015-05-07 13:47:11 -04001224TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusTwoSpecialVariables)
Austin Kinross8b695ee2015-03-12 13:12:20 -07001225{
1226 GLint maxVaryings = 0;
1227 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1228
1229 // Generate shader code that uses gl_FragCoord and gl_PointCoord, two special fragment shader variables.
1230 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, false, true);
1231}
1232
Jamie Madillfa05f602015-05-07 13:47:11 -04001233TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusThreeSpecialVariables)
Austin Kinross8b695ee2015-03-12 13:12:20 -07001234{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001235 // TODO(geofflang): Figure out why this fails on OpenGL AMD (http://anglebug.com/1291)
Jamie Madill518b9fa2016-03-02 11:26:02 -05001236 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lange0cc2a42016-01-20 10:58:17 -05001237 {
1238 std::cout << "Test disabled on OpenGL." << std::endl;
1239 return;
1240 }
1241
Austin Kinross8b695ee2015-03-12 13:12:20 -07001242 GLint maxVaryings = 0;
1243 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1244
1245 // Generate shader code that uses gl_FragCoord, gl_PointCoord and gl_PointSize.
1246 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, true, true);
1247}
1248
Jamie Madillfa05f602015-05-07 13:47:11 -04001249TEST_P(GLSLTest, MaxVaryingVec3)
Austin Kinrossaf875522014-08-25 21:06:07 -07001250{
1251 GLint maxVaryings = 0;
1252 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1253
Austin Kinross8b695ee2015-03-12 13:12:20 -07001254 VaryingTestBase(0, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001255}
1256
Jamie Madillfa05f602015-05-07 13:47:11 -04001257TEST_P(GLSLTest, MaxVaryingVec3Array)
Austin Kinrossaf875522014-08-25 21:06:07 -07001258{
1259 GLint maxVaryings = 0;
1260 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1261
Austin Kinross8b695ee2015-03-12 13:12:20 -07001262 VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001263}
1264
Jamie Madillbee59e02014-10-02 10:44:18 -04001265// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -05001266TEST_P(GLSLTest, MaxVaryingVec3AndOneFloat)
Austin Kinrossaf875522014-08-25 21:06:07 -07001267{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001268 if (IsD3D9())
Jamie Madill9fc36822015-11-18 13:08:07 -05001269 {
1270 std::cout << "Test disabled on D3D9." << std::endl;
1271 return;
1272 }
1273
Austin Kinrossaf875522014-08-25 21:06:07 -07001274 GLint maxVaryings = 0;
1275 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1276
Austin Kinross8b695ee2015-03-12 13:12:20 -07001277 VaryingTestBase(1, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001278}
1279
Jamie Madillbee59e02014-10-02 10:44:18 -04001280// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -05001281TEST_P(GLSLTest, MaxVaryingVec3ArrayAndOneFloatArray)
Austin Kinrossaf875522014-08-25 21:06:07 -07001282{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001283 if (IsD3D9())
Jamie Madill9fc36822015-11-18 13:08:07 -05001284 {
1285 std::cout << "Test disabled on D3D9." << std::endl;
1286 return;
1287 }
1288
Austin Kinrossaf875522014-08-25 21:06:07 -07001289 GLint maxVaryings = 0;
1290 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1291
Austin Kinross8b695ee2015-03-12 13:12:20 -07001292 VaryingTestBase(0, 1, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001293}
1294
Jamie Madillbee59e02014-10-02 10:44:18 -04001295// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -05001296TEST_P(GLSLTest, TwiceMaxVaryingVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -07001297{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001298 if (IsD3D9())
Jamie Madill9fc36822015-11-18 13:08:07 -05001299 {
1300 std::cout << "Test disabled on D3D9." << std::endl;
1301 return;
1302 }
1303
Geoff Lange0cc2a42016-01-20 10:58:17 -05001304 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1305 {
1306 // TODO(geofflang): Figure out why this fails on NVIDIA's GLES driver
1307 std::cout << "Test disabled on OpenGL ES." << std::endl;
1308 return;
1309 }
1310
Geoff Lang69accbd2016-01-25 16:22:32 -05001311#if defined(__APPLE__)
1312 // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
1313 // (http://anglebug.com/1291)
Jamie Madill518b9fa2016-03-02 11:26:02 -05001314 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lang69accbd2016-01-25 16:22:32 -05001315 {
1316 std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
1317 return;
1318 }
1319#endif
1320
Austin Kinrossaf875522014-08-25 21:06:07 -07001321 GLint maxVaryings = 0;
1322 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1323
Austin Kinross8b695ee2015-03-12 13:12:20 -07001324 VaryingTestBase(0, 0, 2 * maxVaryings, 0, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001325}
1326
Jamie Madillbee59e02014-10-02 10:44:18 -04001327// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -05001328TEST_P(GLSLTest, MaxVaryingVec2Arrays)
Austin Kinrossaf875522014-08-25 21:06:07 -07001329{
Jamie Madill518b9fa2016-03-02 11:26:02 -05001330 if (IsD3DSM3())
Jamie Madill9fc36822015-11-18 13:08:07 -05001331 {
1332 std::cout << "Test disabled on SM3." << std::endl;
1333 return;
1334 }
1335
Geoff Lange0cc2a42016-01-20 10:58:17 -05001336 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1337 {
1338 // TODO(geofflang): Figure out why this fails on NVIDIA's GLES driver
1339 std::cout << "Test disabled on OpenGL ES." << std::endl;
1340 return;
1341 }
1342
Geoff Lang69accbd2016-01-25 16:22:32 -05001343#if defined(__APPLE__)
1344 // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
1345 // (http://anglebug.com/1291)
Jamie Madill518b9fa2016-03-02 11:26:02 -05001346 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lang69accbd2016-01-25 16:22:32 -05001347 {
1348 std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
1349 return;
1350 }
1351#endif
1352
Austin Kinrossaf875522014-08-25 21:06:07 -07001353 GLint maxVaryings = 0;
1354 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1355
Austin Kinross8b695ee2015-03-12 13:12:20 -07001356 VaryingTestBase(0, 0, 0, maxVaryings, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -07001357}
1358
Geoff Langf60fab62014-11-24 11:21:20 -05001359// Verify shader source with a fixed length that is less than the null-terminated length will compile.
Jamie Madillfa05f602015-05-07 13:47:11 -04001360TEST_P(GLSLTest, FixedShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -05001361{
1362 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1363
1364 const std::string appendGarbage = "abcasdfasdfasdfasdfasdf";
1365 const std::string source = "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" + appendGarbage;
1366 const char *sourceArray[1] = { source.c_str() };
Corentin Wallez973402f2015-05-11 13:42:22 -04001367 GLint lengths[1] = { static_cast<GLint>(source.length() - appendGarbage.length()) };
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001368 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001369 glCompileShader(shader);
1370
1371 GLint compileResult;
1372 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1373 EXPECT_NE(compileResult, 0);
1374}
1375
1376// Verify that a negative shader source length is treated as a null-terminated length.
Jamie Madillfa05f602015-05-07 13:47:11 -04001377TEST_P(GLSLTest, NegativeShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -05001378{
1379 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1380
1381 const char *sourceArray[1] = { "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" };
1382 GLint lengths[1] = { -10 };
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001383 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001384 glCompileShader(shader);
1385
1386 GLint compileResult;
1387 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1388 EXPECT_NE(compileResult, 0);
1389}
1390
Corentin Wallez9a9c0482016-04-12 10:36:25 -04001391// Check that having an invalid char after the "." doesn't cause an assert.
1392TEST_P(GLSLTest, InvalidFieldFirstChar)
1393{
1394 GLuint shader = glCreateShader(GL_VERTEX_SHADER);
1395 const char *source = "void main() {vec4 x; x.}";
1396 glShaderSource(shader, 1, &source, 0);
1397 glCompileShader(shader);
1398
1399 GLint compileResult;
1400 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1401 EXPECT_EQ(0, compileResult);
1402}
1403
Geoff Langf60fab62014-11-24 11:21:20 -05001404// Verify that a length array with mixed positive and negative values compiles.
Jamie Madillfa05f602015-05-07 13:47:11 -04001405TEST_P(GLSLTest, MixedShaderLengths)
Geoff Langf60fab62014-11-24 11:21:20 -05001406{
1407 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1408
1409 const char *sourceArray[] =
1410 {
1411 "void main()",
1412 "{",
1413 " gl_FragColor = vec4(0, 0, 0, 0);",
1414 "}",
1415 };
1416 GLint lengths[] =
1417 {
1418 -10,
1419 1,
Corentin Wallez973402f2015-05-11 13:42:22 -04001420 static_cast<GLint>(strlen(sourceArray[2])),
Geoff Langf60fab62014-11-24 11:21:20 -05001421 -1,
1422 };
1423 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
1424
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001425 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001426 glCompileShader(shader);
1427
1428 GLint compileResult;
1429 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1430 EXPECT_NE(compileResult, 0);
1431}
1432
1433// Verify that zero-length shader source does not affect shader compilation.
Jamie Madillfa05f602015-05-07 13:47:11 -04001434TEST_P(GLSLTest, ZeroShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -05001435{
1436 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1437
1438 const char *sourceArray[] =
1439 {
1440 "adfasdf",
1441 "34534",
1442 "void main() { gl_FragColor = vec4(0, 0, 0, 0); }",
1443 "",
1444 "asdfasdfsdsdf",
1445 };
1446 GLint lengths[] =
1447 {
1448 0,
1449 0,
1450 -1,
1451 0,
1452 0,
1453 };
1454 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
1455
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001456 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001457 glCompileShader(shader);
1458
1459 GLint compileResult;
1460 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1461 EXPECT_NE(compileResult, 0);
1462}
Jamie Madill21c1e452014-12-29 11:33:41 -05001463
1464// Tests that bad index expressions don't crash ANGLE's translator.
1465// https://code.google.com/p/angleproject/issues/detail?id=857
Jamie Madillfa05f602015-05-07 13:47:11 -04001466TEST_P(GLSLTest, BadIndexBug)
Jamie Madill21c1e452014-12-29 11:33:41 -05001467{
1468 const std::string &fragmentShaderSourceVec =
1469 "precision mediump float;\n"
1470 "uniform vec4 uniformVec;\n"
1471 "void main()\n"
1472 "{\n"
1473 " gl_FragColor = vec4(uniformVec[int()]);\n"
1474 "}";
1475
1476 GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceVec);
1477 EXPECT_EQ(0u, shader);
1478
1479 if (shader != 0)
1480 {
1481 glDeleteShader(shader);
1482 }
1483
1484 const std::string &fragmentShaderSourceMat =
1485 "precision mediump float;\n"
1486 "uniform mat4 uniformMat;\n"
1487 "void main()\n"
1488 "{\n"
1489 " gl_FragColor = vec4(uniformMat[int()]);\n"
1490 "}";
1491
1492 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceMat);
1493 EXPECT_EQ(0u, shader);
1494
1495 if (shader != 0)
1496 {
1497 glDeleteShader(shader);
1498 }
1499
1500 const std::string &fragmentShaderSourceArray =
1501 "precision mediump float;\n"
1502 "uniform vec4 uniformArray;\n"
1503 "void main()\n"
1504 "{\n"
1505 " gl_FragColor = vec4(uniformArray[int()]);\n"
1506 "}";
1507
1508 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceArray);
1509 EXPECT_EQ(0u, shader);
1510
1511 if (shader != 0)
1512 {
1513 glDeleteShader(shader);
1514 }
Jamie Madill37997142015-01-28 10:06:34 -05001515}
1516
Jamie Madill2e295e22015-04-29 10:41:33 -04001517// Test that structs defined in uniforms are translated correctly.
Jamie Madillfa05f602015-05-07 13:47:11 -04001518TEST_P(GLSLTest, StructSpecifiersUniforms)
Jamie Madill2e295e22015-04-29 10:41:33 -04001519{
1520 const std::string fragmentShaderSource = SHADER_SOURCE
1521 (
1522 precision mediump float;
1523
1524 uniform struct S { float field;} s;
1525
1526 void main()
1527 {
1528 gl_FragColor = vec4(1, 0, 0, 1);
1529 gl_FragColor.a += s.field;
1530 }
1531 );
1532
1533 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1534 EXPECT_NE(0u, program);
1535}
Jamie Madill55def582015-05-04 11:24:57 -04001536
1537// Test that gl_DepthRange is not stored as a uniform location. Since uniforms
1538// beginning with "gl_" are filtered out by our validation logic, we must
1539// bypass the validation to test the behaviour of the implementation.
1540// (note this test is still Impl-independent)
Jamie Madillfa05f602015-05-07 13:47:11 -04001541TEST_P(GLSLTest, DepthRangeUniforms)
Jamie Madill55def582015-05-04 11:24:57 -04001542{
1543 const std::string fragmentShaderSource = SHADER_SOURCE
1544 (
1545 precision mediump float;
1546
1547 void main()
1548 {
1549 gl_FragColor = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff, 1);
1550 }
1551 );
1552
1553 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1554 EXPECT_NE(0u, program);
1555
1556 // dive into the ANGLE internals, so we can bypass validation.
1557 gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
1558 gl::Program *glProgram = context->getProgram(program);
1559 GLint nearIndex = glProgram->getUniformLocation("gl_DepthRange.near");
1560 EXPECT_EQ(-1, nearIndex);
1561
1562 // Test drawing does not throw an exception.
1563 drawQuad(program, "inputAttribute", 0.5f);
1564
1565 EXPECT_GL_NO_ERROR();
1566
1567 glDeleteProgram(program);
1568}
Jamie Madill4052dfc2015-05-06 15:18:49 -04001569
Jamie Madill6c9503e2016-08-16 14:06:32 -04001570std::string GenerateSmallPowShader(double base, double exponent)
1571{
1572 std::stringstream stream;
1573
1574 stream.precision(8);
1575
1576 double result = pow(base, exponent);
1577
1578 stream << "precision highp float;\n"
1579 << "float fun(float arg)\n"
1580 << "{\n"
1581 << " return pow(arg, " << std::fixed << exponent << ");\n"
1582 << "}\n"
1583 << "\n"
1584 << "void main()\n"
1585 << "{\n"
1586 << " const float a = " << std::scientific << base << ";\n"
1587 << " float b = fun(a);\n"
1588 << " if (abs(" << result << " - b) < " << std::abs(result * 0.001) << ")\n"
1589 << " {\n"
1590 << " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
1591 << " }\n"
1592 << " else\n"
1593 << " {\n"
1594 << " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
1595 << " }\n"
1596 << "}\n";
1597
1598 return stream.str();
1599}
1600
Jamie Madill4052dfc2015-05-06 15:18:49 -04001601// Covers the WebGL test 'glsl/bugs/pow-of-small-constant-in-user-defined-function'
Jamie Madill1048e432016-07-23 18:51:28 -04001602// See http://anglebug.com/851
1603TEST_P(GLSLTest, PowOfSmallConstant)
Jamie Madill4052dfc2015-05-06 15:18:49 -04001604{
Jamie Madill6c9503e2016-08-16 14:06:32 -04001605 std::vector<double> bads;
1606 for (int eps = -1; eps <= 1; ++eps)
1607 {
1608 for (int i = -4; i <= 5; ++i)
Jamie Madill4052dfc2015-05-06 15:18:49 -04001609 {
Jamie Madill6c9503e2016-08-16 14:06:32 -04001610 if (i >= -1 && i <= 1)
1611 continue;
1612 const double epsilon = 1.0e-8;
1613 double bad = static_cast<double>(i) + static_cast<double>(eps) * epsilon;
1614 bads.push_back(bad);
Jamie Madill4052dfc2015-05-06 15:18:49 -04001615 }
Jamie Madill6c9503e2016-08-16 14:06:32 -04001616 }
Jamie Madill4052dfc2015-05-06 15:18:49 -04001617
Jamie Madill6c9503e2016-08-16 14:06:32 -04001618 for (double bad : bads)
1619 {
1620 const std::string &fragmentShaderSource = GenerateSmallPowShader(1.0e-6, bad);
Jamie Madill4052dfc2015-05-06 15:18:49 -04001621
Jamie Madill6c9503e2016-08-16 14:06:32 -04001622 ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShaderSource);
Jamie Madill4052dfc2015-05-06 15:18:49 -04001623
Jamie Madill6c9503e2016-08-16 14:06:32 -04001624 drawQuad(program.get(), "inputAttribute", 0.5f);
1625
1626 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1627 EXPECT_GL_NO_ERROR();
1628 }
Jamie Madill4052dfc2015-05-06 15:18:49 -04001629}
Jamie Madillfa05f602015-05-07 13:47:11 -04001630
Cooper Partina5ef8d82015-08-19 14:52:21 -07001631// Test that fragment shaders which contain non-constant loop indexers and compiled for FL9_3 and
1632// below
1633// fail with a specific error message.
1634// Additionally test that the same fragment shader compiles successfully with feature levels greater
1635// than FL9_3.
1636TEST_P(GLSLTest, LoopIndexingValidation)
1637{
1638 const std::string fragmentShaderSource = SHADER_SOURCE
1639 (
1640 precision mediump float;
1641
1642 uniform float loopMax;
1643
1644 void main()
1645 {
1646 gl_FragColor = vec4(1, 0, 0, 1);
1647 for (float l = 0.0; l < loopMax; l++)
1648 {
1649 if (loopMax > 3.0)
1650 {
1651 gl_FragColor.a += 0.1;
1652 }
1653 }
1654 }
1655 );
1656
1657 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1658
1659 const char *sourceArray[1] = {fragmentShaderSource.c_str()};
1660 glShaderSource(shader, 1, sourceArray, nullptr);
1661 glCompileShader(shader);
1662
1663 GLint compileResult;
1664 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1665
1666 // If the test is configured to run limited to Feature Level 9_3, then it is
1667 // assumed that shader compilation will fail with an expected error message containing
1668 // "Loop index cannot be compared with non-constant expression"
Olli Etuaho814a54d2015-08-27 16:23:09 +03001669 if ((GetParam() == ES2_D3D11_FL9_3() || GetParam() == ES2_D3D9()))
Cooper Partina5ef8d82015-08-19 14:52:21 -07001670 {
1671 if (compileResult != 0)
1672 {
1673 FAIL() << "Shader compilation succeeded, expected failure";
1674 }
1675 else
1676 {
1677 GLint infoLogLength;
1678 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
1679
1680 std::string infoLog;
1681 infoLog.resize(infoLogLength);
1682 glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
1683
1684 if (infoLog.find("Loop index cannot be compared with non-constant expression") ==
1685 std::string::npos)
1686 {
1687 FAIL() << "Shader compilation failed with unexpected error message";
1688 }
1689 }
1690 }
1691 else
1692 {
1693 EXPECT_NE(0, compileResult);
1694 }
1695
1696 if (shader != 0)
1697 {
1698 glDeleteShader(shader);
1699 }
1700}
1701
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001702// Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1703// can actually be used.
1704TEST_P(GLSLTest, VerifyMaxVertexUniformVectors)
1705{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001706 int maxUniforms = 10000;
1707 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1708 EXPECT_GL_NO_ERROR();
1709 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl;
1710
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001711 CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, 0, 0, true);
1712}
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001713
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001714// Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1715// can actually be used along with the maximum number of texture samplers.
1716TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsWithSamplers)
1717{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001718 if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1719 GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1720 {
1721 std::cout << "Test disabled on OpenGL." << std::endl;
1722 return;
1723 }
1724
Austin Kinross7a3e8e22015-10-08 15:50:06 -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;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001729
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001730 int maxTextureImageUnits = 0;
1731 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001732
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001733 CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, maxTextureImageUnits, 0, true);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001734}
1735
1736// Tests that the maximum uniforms count + 1 from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1737// fails shader compilation.
1738TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsExceeded)
1739{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001740 int maxUniforms = 10000;
1741 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1742 EXPECT_GL_NO_ERROR();
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001743 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS + 1 = " << maxUniforms + 1 << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001744
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001745 CompileGLSLWithUniformsAndSamplers(maxUniforms + 1, 0, 0, 0, false);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001746}
1747
1748// Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1749// can actually be used.
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001750TEST_P(GLSLTest, VerifyMaxFragmentUniformVectors)
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001751{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001752 int maxUniforms = 10000;
1753 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1754 EXPECT_GL_NO_ERROR();
1755 std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS = " << maxUniforms << std::endl;
1756
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001757 CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, 0, true);
1758}
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001759
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001760// Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1761// can actually be used along with the maximum number of texture samplers.
1762TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsWithSamplers)
1763{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001764 if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1765 GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1766 {
1767 std::cout << "Test disabled on OpenGL." << std::endl;
1768 return;
1769 }
1770
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001771 int maxUniforms = 10000;
1772 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1773 EXPECT_GL_NO_ERROR();
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001774
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001775 int maxTextureImageUnits = 0;
1776 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001777
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001778 CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, maxTextureImageUnits, true);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001779}
1780
1781// Tests that the maximum uniforms count + 1 from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1782// fails shader compilation.
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001783TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsExceeded)
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001784{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001785 int maxUniforms = 10000;
1786 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1787 EXPECT_GL_NO_ERROR();
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001788 std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS + 1 = " << maxUniforms + 1
1789 << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001790
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001791 CompileGLSLWithUniformsAndSamplers(0, maxUniforms + 1, 0, 0, false);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001792}
1793
Olli Etuahobe59c2f2016-03-07 11:32:34 +02001794// Test that two constructors which have vec4 and mat2 parameters get disambiguated (issue in
1795// HLSL).
1796TEST_P(GLSLTest_ES3, AmbiguousConstructorCall2x2)
1797{
1798 const std::string fragmentShaderSource =
1799 "#version 300 es\n"
1800 "precision highp float;\n"
1801 "out vec4 my_FragColor;\n"
1802 "void main()\n"
1803 "{\n"
1804 " my_FragColor = vec4(0.0);\n"
1805 "}";
1806
1807 const std::string vertexShaderSource =
1808 "#version 300 es\n"
1809 "precision highp float;\n"
1810 "in vec4 a_vec;\n"
1811 "in mat2 a_mat;\n"
1812 "void main()\n"
1813 "{\n"
1814 " gl_Position = vec4(a_vec) + vec4(a_mat);\n"
1815 "}";
1816
1817 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1818 EXPECT_NE(0u, program);
1819}
1820
1821// Test that two constructors which have mat2x3 and mat3x2 parameters get disambiguated.
1822// This was suspected to be an issue in HLSL, but HLSL seems to be able to natively choose between
1823// the function signatures in this case.
1824TEST_P(GLSLTest_ES3, AmbiguousConstructorCall2x3)
1825{
1826 const std::string fragmentShaderSource =
1827 "#version 300 es\n"
1828 "precision highp float;\n"
1829 "out vec4 my_FragColor;\n"
1830 "void main()\n"
1831 "{\n"
1832 " my_FragColor = vec4(0.0);\n"
1833 "}";
1834
1835 const std::string vertexShaderSource =
1836 "#version 300 es\n"
1837 "precision highp float;\n"
1838 "in mat3x2 a_matA;\n"
1839 "in mat2x3 a_matB;\n"
1840 "void main()\n"
1841 "{\n"
1842 " gl_Position = vec4(a_matA) + vec4(a_matB);\n"
1843 "}";
1844
1845 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1846 EXPECT_NE(0u, program);
1847}
1848
1849// Test that two functions which have vec4 and mat2 parameters get disambiguated (issue in HLSL).
1850TEST_P(GLSLTest_ES3, AmbiguousFunctionCall2x2)
1851{
1852 const std::string fragmentShaderSource =
1853 "#version 300 es\n"
1854 "precision highp float;\n"
1855 "out vec4 my_FragColor;\n"
1856 "void main()\n"
1857 "{\n"
1858 " my_FragColor = vec4(0.0);\n"
1859 "}";
1860
1861 const std::string vertexShaderSource =
1862 "#version 300 es\n"
1863 "precision highp float;\n"
1864 "in vec4 a_vec;\n"
1865 "in mat2 a_mat;\n"
1866 "vec4 foo(vec4 a)\n"
1867 "{\n"
1868 " return a;\n"
1869 "}\n"
1870 "vec4 foo(mat2 a)\n"
1871 "{\n"
1872 " return vec4(a[0][0]);\n"
1873 "}\n"
1874 "void main()\n"
1875 "{\n"
1876 " gl_Position = foo(a_vec) + foo(a_mat);\n"
1877 "}";
1878
1879 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1880 EXPECT_NE(0u, program);
1881}
1882
1883// Test that an user-defined function with a large number of float4 parameters doesn't fail due to
1884// the function name being too long.
1885TEST_P(GLSLTest_ES3, LargeNumberOfFloat4Parameters)
1886{
1887 const std::string fragmentShaderSource =
1888 "#version 300 es\n"
1889 "precision highp float;\n"
1890 "out vec4 my_FragColor;\n"
1891 "void main()\n"
1892 "{\n"
1893 " my_FragColor = vec4(0.0);\n"
1894 "}";
1895
1896 std::stringstream vertexShaderStream;
1897 const unsigned int paramCount = 1024u;
1898
1899 vertexShaderStream << "#version 300 es\n"
1900 "precision highp float;\n"
1901 "in vec4 a_vec;\n"
1902 "vec4 lotsOfVec4Parameters(";
1903 for (unsigned int i = 0; i < paramCount; ++i)
1904 {
1905 vertexShaderStream << "vec4 a" << i << ", ";
1906 }
1907 vertexShaderStream << "vec4 aLast)\n"
1908 "{\n"
1909 " return ";
1910 for (unsigned int i = 0; i < paramCount; ++i)
1911 {
1912 vertexShaderStream << "a" << i << " + ";
1913 }
1914 vertexShaderStream << "aLast;\n"
1915 "}\n"
1916 "void main()\n"
1917 "{\n"
1918 " gl_Position = lotsOfVec4Parameters(";
1919 for (unsigned int i = 0; i < paramCount; ++i)
1920 {
1921 vertexShaderStream << "a_vec, ";
1922 }
1923 vertexShaderStream << "a_vec);\n"
1924 "}";
1925
1926 GLuint program = CompileProgram(vertexShaderStream.str(), fragmentShaderSource);
1927 EXPECT_NE(0u, program);
1928}
1929
Olli Etuahod4f4c112016-04-15 15:11:24 +03001930// This test was written specifically to stress DeferGlobalInitializers AST transformation.
1931// Test a shader where a global constant array is initialized with an expression containing array
1932// indexing. This initializer is tricky to constant fold, so if it's not constant folded it needs to
1933// be handled in a way that doesn't generate statements in the global scope in HLSL output.
1934// Also includes multiple array initializers in one declaration, where only the second one has
1935// array indexing. This makes sure that the qualifier for the declaration is set correctly if
1936// transformations are applied to the declaration also in the case of ESSL output.
1937TEST_P(GLSLTest_ES3, InitGlobalArrayWithArrayIndexing)
1938{
Yuly Novikov41db2242016-06-25 00:14:28 -04001939 // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1428 is fixed
1940 if (IsAndroid() && IsAdreno() && IsOpenGLES())
1941 {
1942 std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
1943 return;
1944 }
1945
Olli Etuahod4f4c112016-04-15 15:11:24 +03001946 const std::string vertexShaderSource =
1947 "#version 300 es\n"
1948 "precision highp float;\n"
1949 "in vec4 a_vec;\n"
1950 "void main()\n"
1951 "{\n"
1952 " gl_Position = vec4(a_vec);\n"
1953 "}";
1954
1955 const std::string fragmentShaderSource =
1956 "#version 300 es\n"
1957 "precision highp float;\n"
1958 "out vec4 my_FragColor;\n"
1959 "const highp float f[2] = float[2](0.1, 0.2);\n"
1960 "const highp float[2] g = float[2](0.3, 0.4), h = float[2](0.5, f[1]);\n"
1961 "void main()\n"
1962 "{\n"
1963 " my_FragColor = vec4(h[1]);\n"
1964 "}";
1965
1966 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1967 EXPECT_NE(0u, program);
1968}
1969
Corentin Wallez419bfc92016-06-28 10:54:45 -07001970// Test that index-constant sampler array indexing is supported.
1971TEST_P(GLSLTest, IndexConstantSamplerArrayIndexing)
1972{
1973 if (IsD3D11_FL93()) {
1974 std::cout << "Test skipped on D3D11 FL 9.3." << std::endl;
1975 return;
1976 }
1977
1978 const std::string vertexShaderSource =
1979 "attribute vec4 vPosition;\n"
1980 "void main()\n"
1981 "{\n"
1982 " gl_Position = vPosition;\n"
1983 "}";
1984
1985 const std::string fragmentShaderSource =
1986 "precision mediump float;\n"
1987 "uniform sampler2D uni[2];\n"
1988 "\n"
1989 "float zero(int x)\n"
1990 "{\n"
1991 " return float(x) - float(x);\n"
1992 "}\n"
1993 "\n"
1994 "void main()\n"
1995 "{\n"
1996 " vec4 c = vec4(0,0,0,0);\n"
1997 " for (int ii = 1; ii < 3; ++ii) {\n"
1998 " if (c.x > 255.0) {\n"
1999 " c.x = 255.0 + zero(ii);\n"
2000 " break;\n"
2001 " }\n"
2002 // Index the sampler array with a predictable loop index (index-constant) as opposed to
2003 // a true constant. This is valid in OpenGL ES but isn't in many Desktop OpenGL versions,
2004 // without an extension.
2005 " c += texture2D(uni[ii - 1], vec2(0.5, 0.5));\n"
2006 " }\n"
2007 " gl_FragColor = c;\n"
2008 "}";
2009
2010 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
2011 EXPECT_NE(0u, program);
2012}
2013
Corentin Wallezb00dcee2016-07-11 17:42:58 -04002014// Test that the #pragma directive is supported and doesn't trigger a compilation failure on the
2015// native driver. The only pragma that gets passed to the OpenGL driver is "invariant" but we don't
2016// want to test its behavior, so don't use any varyings.
2017TEST_P(GLSLTest, PragmaDirective)
2018{
2019 const std::string vertexShaderSource =
2020 "#pragma STDGL invariant(all)\n"
2021 "void main()\n"
2022 "{\n"
2023 " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
2024 "}\n";
2025
2026 const std::string fragmentShaderSource =
2027 "precision mediump float;\n"
2028 "void main()\n"
2029 "{\n"
2030 " gl_FragColor = vec4(1.0);\n"
2031 "}\n";
2032
2033 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
2034 EXPECT_NE(0u, program);
2035}
2036
Olli Etuahoe1d199b2016-07-19 17:14:27 +03002037// Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9).
2038// The function call that returns the array needs to be evaluated after ++j for the expression to
2039// return the correct value (true).
2040TEST_P(GLSLTest_ES3, SequenceOperatorEvaluationOrderArray)
2041{
2042 const std::string &fragmentShaderSource =
2043 "#version 300 es\n"
2044 "precision mediump float;\n"
2045 "out vec4 my_FragColor; \n"
2046 "int[2] func(int param) {\n"
2047 " return int[2](param, param);\n"
2048 "}\n"
2049 "void main() {\n"
2050 " int a[2]; \n"
2051 " for (int i = 0; i < 2; ++i) {\n"
2052 " a[i] = 1;\n"
2053 " }\n"
2054 " int j = 0; \n"
2055 " bool result = ((++j), (a == func(j)));\n"
2056 " my_FragColor = vec4(0.0, (result ? 1.0 : 0.0), 0.0, 1.0);\n"
2057 "}\n";
2058
2059 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
2060 ASSERT_NE(0u, program);
2061
2062 drawQuad(program, "inputAttribute", 0.5f);
2063
2064 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2065}
2066
2067// Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9).
2068// The short-circuiting expression needs to be evaluated after ++j for the expression to return the
2069// correct value (true).
2070TEST_P(GLSLTest_ES3, SequenceOperatorEvaluationOrderShortCircuit)
2071{
2072 const std::string &fragmentShaderSource =
2073 "#version 300 es\n"
2074 "precision mediump float;\n"
2075 "out vec4 my_FragColor; \n"
2076 "void main() {\n"
2077 " int j = 0; \n"
2078 " bool result = ((++j), (j == 1 ? true : (++j == 3)));\n"
2079 " my_FragColor = vec4(0.0, ((result && j == 1) ? 1.0 : 0.0), 0.0, 1.0);\n"
2080 "}\n";
2081
2082 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
2083 ASSERT_NE(0u, program);
2084
2085 drawQuad(program, "inputAttribute", 0.5f);
2086
2087 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2088}
2089
Jamie Madill666f65a2016-08-26 01:34:37 +00002090// Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9).
2091// Indexing the vector needs to be evaluated after func() for the right result.
2092TEST_P(GLSLTest_ES3, SequenceOperatorEvaluationOrderDynamicVectorIndexingInLValue)
2093{
2094 const std::string &fragmentShaderSource =
2095 "#version 300 es\n"
2096 "precision mediump float;\n"
2097 "out vec4 my_FragColor;\n"
2098 "uniform int u_zero;\n"
2099 "int sideEffectCount = 0;\n"
2100 "float func() {\n"
2101 " ++sideEffectCount;\n"
2102 " return -1.0;\n"
2103 "}\n"
2104 "void main() {\n"
2105 " vec4 v = vec4(0.0, 2.0, 4.0, 6.0); \n"
2106 " float f = (func(), (++v[u_zero + sideEffectCount]));\n"
2107 " bool green = abs(f - 3.0) < 0.01 && abs(v[1] - 3.0) < 0.01 && sideEffectCount == 1;\n"
2108 " my_FragColor = vec4(0.0, (green ? 1.0 : 0.0), 0.0, 1.0);\n"
2109 "}\n";
2110
2111 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
2112 ASSERT_NE(0u, program);
2113
2114 drawQuad(program, "inputAttribute", 0.5f);
2115
2116 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2117}
2118
Jamie Madillc9bde922016-07-24 17:58:50 -04002119// Test that using gl_PointCoord with GL_TRIANGLES doesn't produce a link error.
2120// From WebGL test conformance/rendering/point-specific-shader-variables.html
2121// See http://anglebug.com/1380
2122TEST_P(GLSLTest, RenderTrisWithPointCoord)
2123{
2124 const std::string &vert =
2125 "attribute vec2 aPosition;\n"
2126 "void main()\n"
2127 "{\n"
2128 " gl_Position = vec4(aPosition, 0, 1);\n"
2129 " gl_PointSize = 1.0;\n"
2130 "}";
2131 const std::string &frag =
2132 "void main()\n"
2133 "{\n"
2134 " gl_FragColor = vec4(gl_PointCoord.xy, 0, 1);\n"
2135 " gl_FragColor = vec4(0, 1, 0, 1);\n"
2136 "}";
2137
2138 ANGLE_GL_PROGRAM(prog, vert, frag);
2139 drawQuad(prog.get(), "aPosition", 0.5f);
2140 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2141}
2142
Jamie Madill5655b842016-08-02 11:00:07 -04002143// Convers a bug with the integer pow statement workaround.
2144TEST_P(GLSLTest, NestedPowStatements)
2145{
2146 const std::string &vert =
2147 "attribute vec2 position;\n"
2148 "void main()\n"
2149 "{\n"
2150 " gl_Position = vec4(position, 0, 1);\n"
2151 "}";
2152 const std::string &frag =
2153 "precision mediump float;\n"
2154 "float func(float v)\n"
2155 "{\n"
2156 " float f1 = pow(v, 2.0);\n"
2157 " return pow(f1 + v, 2.0);\n"
2158 "}\n"
2159 "void main()\n"
2160 "{\n"
2161 " float v = func(2.0);\n"
2162 " gl_FragColor = abs(v - 36.0) < 0.001 ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n"
2163 "}";
2164
2165 ANGLE_GL_PROGRAM(prog, vert, frag);
2166 drawQuad(prog.get(), "position", 0.5f);
2167 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2168}
2169
Qiankun Miaof52fe932016-12-07 13:39:15 +08002170// Test that -float calculation is correct.
2171TEST_P(GLSLTest_ES3, UnaryMinusOperatorFloat)
2172{
2173 // TODO(oetuaho@nvidia.com): re-enable once http://crbug.com/672380 is fixed.
2174 if ((IsWindows() || IsLinux()) && IsNVIDIA() && IsOpenGL())
2175 {
2176 std::cout << "Test disabled on this OpenGL configuration." << std::endl;
2177 return;
2178 }
2179
2180 const std::string &vert =
2181 "#version 300 es\n"
2182 "in highp vec4 position;\n"
2183 "void main() {\n"
2184 " gl_Position = position;\n"
2185 "}\n";
2186 const std::string &frag =
2187 "#version 300 es\n"
2188 "out highp vec4 o_color;\n"
2189 "void main() {\n"
2190 " highp float f = -1.0;\n"
2191 " // atan(tan(0.5), -f) should be 0.5.\n"
2192 " highp float v = atan(tan(0.5), -f);\n"
2193 " o_color = abs(v - 0.5) < 0.001 ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n"
2194 "}\n";
2195
2196 ANGLE_GL_PROGRAM(prog, vert, frag);
2197 drawQuad(prog.get(), "position", 0.5f);
2198 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2199}
2200
Jiawei-Shaoe292e902016-09-07 10:49:01 +08002201// Convers a bug with the unary minus operator on signed integer workaround.
2202TEST_P(GLSLTest_ES3, UnaryMinusOperatorSignedInt)
2203{
2204 const std::string &vert =
2205 "#version 300 es\n"
2206 "in highp vec4 position;\n"
2207 "out mediump vec4 v_color;\n"
2208 "uniform int ui_one;\n"
2209 "uniform int ui_two;\n"
2210 "uniform int ui_three;\n"
2211 "void main() {\n"
2212 " int s[3];\n"
2213 " s[0] = ui_one;\n"
2214 " s[1] = -(-(-ui_two + 1) + 1);\n" // s[1] = -ui_two
2215 " s[2] = ui_three;\n"
2216 " int result = 0;\n"
2217 " for (int i = 0; i < ui_three; i++) {\n"
2218 " result += s[i];\n"
2219 " }\n"
2220 " v_color = (result == 2) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n"
2221 " gl_Position = position;\n"
2222 "}\n";
2223 const std::string &frag =
2224 "#version 300 es\n"
2225 "in mediump vec4 v_color;\n"
2226 "layout(location=0) out mediump vec4 o_color;\n"
2227 "void main() {\n"
2228 " o_color = v_color;\n"
2229 "}\n";
2230
2231 ANGLE_GL_PROGRAM(prog, vert, frag);
2232
2233 gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
2234 gl::Program *glProgram = context->getProgram(prog.get());
2235 GLint oneIndex = glProgram->getUniformLocation("ui_one");
2236 ASSERT_NE(-1, oneIndex);
2237 GLint twoIndex = glProgram->getUniformLocation("ui_two");
2238 ASSERT_NE(-1, twoIndex);
2239 GLint threeIndex = glProgram->getUniformLocation("ui_three");
2240 ASSERT_NE(-1, threeIndex);
2241 glUseProgram(prog.get());
2242 glUniform1i(oneIndex, 1);
2243 glUniform1i(twoIndex, 2);
2244 glUniform1i(threeIndex, 3);
2245
2246 drawQuad(prog.get(), "position", 0.5f);
2247 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2248}
2249
2250// Convers a bug with the unary minus operator on unsigned integer workaround.
2251TEST_P(GLSLTest_ES3, UnaryMinusOperatorUnsignedInt)
2252{
2253 const std::string &vert =
2254 "#version 300 es\n"
2255 "in highp vec4 position;\n"
2256 "out mediump vec4 v_color;\n"
2257 "uniform uint ui_one;\n"
2258 "uniform uint ui_two;\n"
2259 "uniform uint ui_three;\n"
2260 "void main() {\n"
2261 " uint s[3];\n"
2262 " s[0] = ui_one;\n"
2263 " s[1] = -(-(-ui_two + 1u) + 1u);\n" // s[1] = -ui_two
2264 " s[2] = ui_three;\n"
2265 " uint result = 0u;\n"
2266 " for (uint i = 0u; i < ui_three; i++) {\n"
2267 " result += s[i];\n"
2268 " }\n"
2269 " v_color = (result == 2u) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n"
2270 " gl_Position = position;\n"
2271 "}\n";
2272 const std::string &frag =
2273 "#version 300 es\n"
2274 "in mediump vec4 v_color;\n"
2275 "layout(location=0) out mediump vec4 o_color;\n"
2276 "void main() {\n"
2277 " o_color = v_color;\n"
2278 "}\n";
2279
2280 ANGLE_GL_PROGRAM(prog, vert, frag);
2281
2282 gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
2283 gl::Program *glProgram = context->getProgram(prog.get());
2284 GLint oneIndex = glProgram->getUniformLocation("ui_one");
2285 ASSERT_NE(-1, oneIndex);
2286 GLint twoIndex = glProgram->getUniformLocation("ui_two");
2287 ASSERT_NE(-1, twoIndex);
2288 GLint threeIndex = glProgram->getUniformLocation("ui_three");
2289 ASSERT_NE(-1, threeIndex);
2290 glUseProgram(prog.get());
2291 glUniform1ui(oneIndex, 1u);
2292 glUniform1ui(twoIndex, 2u);
2293 glUniform1ui(threeIndex, 3u);
2294
2295 drawQuad(prog.get(), "position", 0.5f);
2296 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2297}
2298
Olli Etuahoab481642016-08-26 12:09:10 +03002299// Test a nested sequence operator with a ternary operator inside. The ternary operator is
2300// intended to be such that it gets converted to an if statement on the HLSL backend.
2301TEST_P(GLSLTest, NestedSequenceOperatorWithTernaryInside)
2302{
2303 const std::string &vert =
2304 "attribute vec2 position;\n"
2305 "void main()\n"
2306 "{\n"
2307 " gl_Position = vec4(position, 0, 1);\n"
2308 "}";
2309
2310 // Note that the uniform keep_flop_positive doesn't need to be set - the test expects it to have
2311 // its default value false.
2312 const std::string &frag =
2313 "precision mediump float;\n"
2314 "uniform bool keep_flop_positive;\n"
2315 "float flop;\n"
2316 "void main() {\n"
2317 " flop = -1.0,\n"
2318 " (flop *= -1.0,\n"
2319 " keep_flop_positive ? 0.0 : flop *= -1.0),\n"
2320 " gl_FragColor = vec4(0, -flop, 0, 1);\n"
2321 "}";
2322
2323 ANGLE_GL_PROGRAM(prog, vert, frag);
2324 drawQuad(prog.get(), "position", 0.5f);
2325 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2326}
2327
Geoff Lang28a97ee2016-09-22 13:01:26 -04002328// Test that using a sampler2D and samplerExternalOES in the same shader works (anglebug.com/1534)
2329TEST_P(GLSLTest, ExternalAnd2DSampler)
2330{
2331 if (!extensionEnabled("GL_OES_EGL_image_external"))
2332 {
2333 std::cout << "Test skipped because GL_OES_EGL_image_external is not available."
2334 << std::endl;
2335 return;
2336 }
2337
2338 const std::string fragmentShader =
2339 "precision mediump float;\n"
2340 "uniform samplerExternalOES tex0;\n"
2341 "uniform sampler2D tex1;\n"
2342 "void main(void)\n"
2343 "{\n"
2344 " vec2 uv = vec2(0.0, 0.0);"
2345 " gl_FragColor = texture2D(tex0, uv) + texture2D(tex1, uv);\n"
2346 "}\n";
2347
2348 ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
2349}
2350
Jamie Madill44ebf6b2016-09-22 13:00:02 -04002351// Test that using an invalid constant right-shift produces an error.
2352TEST_P(GLSLTest_ES3, FoldedInvalidRightShift)
2353{
2354 const std::string &fragmentShader =
2355 "#version 300 es\n"
2356 "precision mediump float;\n"
2357 "out vec4 color;\n"
2358 "void main(void)\n"
2359 "{\n"
2360 " int diff = -100 >> -100;\n"
2361 " color = vec4(float(diff));\n"
2362 "}\n";
2363
2364 GLuint program = CompileProgram(mSimpleVSSource, fragmentShader);
2365 EXPECT_EQ(0u, program);
2366 glDeleteProgram(program);
2367}
2368
2369// Test that using an invalid constant left-shift produces an error.
2370TEST_P(GLSLTest_ES3, FoldedInvalidLeftShift)
2371{
2372 const std::string &fragmentShader =
2373 "#version 300 es\n"
2374 "precision mediump float;\n"
2375 "out vec4 color;\n"
2376 "void main(void)\n"
2377 "{\n"
2378 " int diff = -100 << -100;\n"
2379 " color = vec4(float(diff));\n"
2380 "}\n";
2381
2382 GLuint program = CompileProgram(mSimpleVSSource, fragmentShader);
2383 EXPECT_EQ(0u, program);
2384 glDeleteProgram(program);
2385}
2386
Olli Etuaho56a2f952016-12-08 12:16:27 +00002387// Test that literal infinity can be written out from the shader translator.
2388// A similar test can't be made for NaNs, since ESSL 3.00.6 requirements for NaNs are very loose.
2389TEST_P(GLSLTest_ES3, LiteralInfinityOutput)
2390{
2391 const std::string &fragmentShader =
2392 "#version 300 es\n"
2393 "precision highp float;\n"
2394 "out vec4 out_color;\n"
2395 "uniform float u;\n"
2396 "void main()\n"
2397 "{\n"
2398 " float infVar = 1.0e40 - u;\n"
2399 " bool correct = isinf(infVar) && infVar > 0.0;\n"
2400 " out_color = correct ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);\n"
2401 "}\n";
2402
2403 ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
2404 drawQuad(program.get(), "inputAttribute", 0.5f);
2405 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2406}
2407
2408// Test that literal negative infinity can be written out from the shader translator.
2409// A similar test can't be made for NaNs, since ESSL 3.00.6 requirements for NaNs are very loose.
2410TEST_P(GLSLTest_ES3, LiteralNegativeInfinityOutput)
2411{
2412 const std::string &fragmentShader =
2413 "#version 300 es\n"
2414 "precision highp float;\n"
2415 "out vec4 out_color;\n"
2416 "uniform float u;\n"
2417 "void main()\n"
2418 "{\n"
2419 " float infVar = -1.0e40 + u;\n"
2420 " bool correct = isinf(infVar) && infVar < 0.0;\n"
2421 " out_color = correct ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);\n"
2422 "}\n";
2423
2424 ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
2425 drawQuad(program.get(), "inputAttribute", 0.5f);
2426 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2427}
2428
Corentin Wallez36fd1002016-12-08 11:30:44 -05002429// The following MultipleDeclaration* tests are testing TranslatorHLSL specific simplification
2430// passes. Because the interaction of multiple passes must be tested, it is difficult to write
2431// a unittest for them. Instead we add the tests as end2end so will in particular test
2432// TranslatorHLSL when run on Windows.
2433
2434// Test that passes splitting multiple declarations and comma operators are correctly ordered.
2435TEST_P(GLSLTest_ES3, MultipleDeclarationWithCommaOperator)
2436{
2437 const std::string &fragmentShader =
2438 "#version 300 es\n"
2439 "precision mediump float;\n"
2440 "out vec4 color;\n"
2441 "void main(void)\n"
2442 "{\n"
2443 " float a = 0.0, b = ((gl_FragCoord.x < 0.5 ? a : 0.0), 1.0);\n"
2444 " color = vec4(b);\n"
2445 "}\n";
2446
2447 ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
2448}
2449
2450// Test that passes splitting multiple declarations and comma operators and for loops are
2451// correctly ordered.
2452TEST_P(GLSLTest_ES3, MultipleDeclarationWithCommaOperatorInForLoop)
2453{
2454 const std::string &fragmentShader =
2455 "#version 300 es\n"
2456 "precision mediump float;\n"
2457 "out vec4 color;\n"
2458 "void main(void)\n"
2459 "{\n"
2460 " for(float a = 0.0, b = ((gl_FragCoord.x < 0.5 ? a : 0.0), 1.0); a < 10.0; a++)\n"
2461 " {\n"
2462 " b += 1.0;\n"
2463 " color = vec4(b);\n"
2464 " }\n"
2465 "}\n";
2466
2467 ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
2468}
2469
2470// Test that splitting multiple declaration in for loops works with no loop condition
2471TEST_P(GLSLTest_ES3, MultipleDeclarationInForLoopEmptyCondition)
2472{
2473 const std::string &fragmentShader =
2474 "#version 300 es\n"
2475 "precision mediump float;\n"
2476 "out vec4 color;\n"
2477 "void main(void)\n"
2478 "{\n"
2479 " for(float a = 0.0, b = 1.0;; a++)\n"
2480 " {\n"
2481 " b += 1.0;\n"
2482 " if (a > 10.0) {break;}\n"
2483 " color = vec4(b);\n"
2484 " }\n"
2485 "}\n";
2486
2487 ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
2488}
2489
2490// Test that splitting multiple declaration in for loops works with no loop expression
2491TEST_P(GLSLTest_ES3, MultipleDeclarationInForLoopEmptyExpression)
2492{
2493 const std::string &fragmentShader =
2494 "#version 300 es\n"
2495 "precision mediump float;\n"
2496 "out vec4 color;\n"
2497 "void main(void)\n"
2498 "{\n"
2499 " for(float a = 0.0, b = 1.0; a < 10.0;)\n"
2500 " {\n"
2501 " b += 1.0;\n"
2502 " a += 1.0;\n"
2503 " color = vec4(b);\n"
2504 " }\n"
2505 "}\n";
2506
2507 ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
2508}
2509
Jamie Madill6c9503e2016-08-16 14:06:32 -04002510} // anonymous namespace
2511
Jamie Madillfa05f602015-05-07 13:47:11 -04002512// 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 -05002513ANGLE_INSTANTIATE_TEST(GLSLTest,
2514 ES2_D3D9(),
2515 ES2_D3D11(),
2516 ES2_D3D11_FL9_3(),
2517 ES2_OPENGL(),
2518 ES3_OPENGL(),
2519 ES2_OPENGLES(),
2520 ES3_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04002521
2522// 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 -05002523ANGLE_INSTANTIATE_TEST(GLSLTest_ES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());