blob: 7776f404f126c3c47ea8f84887ae734c3732e324 [file] [log] [blame]
Jamie Madill55def582015-05-04 11:24:57 -04001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Corentin Wallezd3970de2015-05-14 11:07:48 -04007#include "test_utils/ANGLETest.h"
Jamie Madill96509e42014-05-29 14:33:27 -04008
Jamie Madill55def582015-05-04 11:24:57 -04009#include "libANGLE/Context.h"
10#include "libANGLE/Program.h"
11
Jamie Madillfa05f602015-05-07 13:47:11 -040012using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070013
Jamie Madill2bf8b372014-06-16 17:18:51 -040014class GLSLTest : public ANGLETest
Jamie Madill96509e42014-05-29 14:33:27 -040015{
Jamie Madillfa05f602015-05-07 13:47:11 -040016 protected:
17 GLSLTest()
Jamie Madill96509e42014-05-29 14:33:27 -040018 {
19 setWindowWidth(128);
20 setWindowHeight(128);
21 setConfigRedBits(8);
22 setConfigGreenBits(8);
23 setConfigBlueBits(8);
24 setConfigAlphaBits(8);
25 }
Jamie Madillbfa91f42014-06-05 15:45:18 -040026
27 virtual void SetUp()
28 {
29 ANGLETest::SetUp();
30
Jamie Madill2bf8b372014-06-16 17:18:51 -040031 mSimpleVSSource = SHADER_SOURCE
Jamie Madillbfa91f42014-06-05 15:45:18 -040032 (
33 attribute vec4 inputAttribute;
34 void main()
35 {
36 gl_Position = inputAttribute;
37 }
38 );
39 }
40
Austin Kinrossaf875522014-08-25 21:06:07 -070041 std::string GenerateVaryingType(GLint vectorSize)
42 {
43 char varyingType[10];
44
45 if (vectorSize == 1)
46 {
47 sprintf(varyingType, "float");
48 }
49 else
50 {
51 sprintf(varyingType, "vec%d", vectorSize);
52 }
53
54 return std::string(varyingType);
55 }
56
57 std::string GenerateVectorVaryingDeclaration(GLint vectorSize, GLint arraySize, GLint id)
58 {
59 char buff[100];
60
61 if (arraySize == 1)
62 {
63 sprintf(buff, "varying %s v%d;\n", GenerateVaryingType(vectorSize).c_str(), id);
64 }
65 else
66 {
67 sprintf(buff, "varying %s v%d[%d];\n", GenerateVaryingType(vectorSize).c_str(), id, arraySize);
68 }
69
70 return std::string(buff);
71 }
72
73 std::string GenerateVectorVaryingSettingCode(GLint vectorSize, GLint arraySize, GLint id)
74 {
75 std::string returnString;
76 char buff[100];
77
78 if (arraySize == 1)
79 {
80 sprintf(buff, "\t v%d = %s(1.0);\n", id, GenerateVaryingType(vectorSize).c_str());
81 returnString += buff;
82 }
83 else
84 {
85 for (int i = 0; i < arraySize; i++)
86 {
87 sprintf(buff, "\t v%d[%d] = %s(1.0);\n", id, i, GenerateVaryingType(vectorSize).c_str());
88 returnString += buff;
89 }
90 }
91
92 return returnString;
93 }
94
95 std::string GenerateVectorVaryingUseCode(GLint arraySize, GLint id)
96 {
97 if (arraySize == 1)
98 {
99 char buff[100];
100 sprintf(buff, "v%d + ", id);
101 return std::string(buff);
102 }
103 else
104 {
105 std::string returnString;
106 for (int i = 0; i < arraySize; i++)
107 {
108 char buff[100];
109 sprintf(buff, "v%d[%d] + ", id, i);
110 returnString += buff;
111 }
112 return returnString;
113 }
114 }
115
Austin Kinross8b695ee2015-03-12 13:12:20 -0700116 void GenerateGLSLWithVaryings(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
117 GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize,
118 std::string* fragmentShader, std::string* vertexShader)
Austin Kinrossaf875522014-08-25 21:06:07 -0700119 {
120 // Generate a string declaring the varyings, to share between the fragment shader and the vertex shader.
121 std::string varyingDeclaration;
122
123 unsigned int varyingCount = 0;
124
125 for (GLint i = 0; i < floatCount; i++)
126 {
127 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 1, varyingCount);
128 varyingCount += 1;
129 }
130
131 for (GLint i = 0; i < floatArrayCount; i++)
132 {
133 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 2, varyingCount);
134 varyingCount += 1;
135 }
136
137 for (GLint i = 0; i < vec2Count; i++)
138 {
139 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 1, varyingCount);
140 varyingCount += 1;
141 }
142
143 for (GLint i = 0; i < vec2ArrayCount; i++)
144 {
145 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 2, varyingCount);
146 varyingCount += 1;
147 }
148
149 for (GLint i = 0; i < vec3Count; i++)
150 {
151 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 1, varyingCount);
152 varyingCount += 1;
153 }
154
155 for (GLint i = 0; i < vec3ArrayCount; i++)
156 {
157 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 2, varyingCount);
158 varyingCount += 1;
159 }
160
Austin Kinross8b695ee2015-03-12 13:12:20 -0700161 for (GLint i = 0; i < vec4Count; i++)
162 {
163 varyingDeclaration += GenerateVectorVaryingDeclaration(4, 1, varyingCount);
164 varyingCount += 1;
165 }
166
167 for (GLint i = 0; i < vec4ArrayCount; i++)
168 {
169 varyingDeclaration += GenerateVectorVaryingDeclaration(4, 2, varyingCount);
170 varyingCount += 1;
171 }
172
Austin Kinrossaf875522014-08-25 21:06:07 -0700173 // Generate the vertex shader
174 vertexShader->clear();
175 vertexShader->append(varyingDeclaration);
176 vertexShader->append("\nvoid main()\n{\n");
177
178 unsigned int currentVSVarying = 0;
179
180 for (GLint i = 0; i < floatCount; i++)
181 {
182 vertexShader->append(GenerateVectorVaryingSettingCode(1, 1, currentVSVarying));
183 currentVSVarying += 1;
184 }
185
186 for (GLint i = 0; i < floatArrayCount; i++)
187 {
188 vertexShader->append(GenerateVectorVaryingSettingCode(1, 2, currentVSVarying));
189 currentVSVarying += 1;
190 }
191
192 for (GLint i = 0; i < vec2Count; i++)
193 {
194 vertexShader->append(GenerateVectorVaryingSettingCode(2, 1, currentVSVarying));
195 currentVSVarying += 1;
196 }
197
198 for (GLint i = 0; i < vec2ArrayCount; i++)
199 {
200 vertexShader->append(GenerateVectorVaryingSettingCode(2, 2, currentVSVarying));
201 currentVSVarying += 1;
202 }
203
204 for (GLint i = 0; i < vec3Count; i++)
205 {
206 vertexShader->append(GenerateVectorVaryingSettingCode(3, 1, currentVSVarying));
207 currentVSVarying += 1;
208 }
209
210 for (GLint i = 0; i < vec3ArrayCount; i++)
211 {
212 vertexShader->append(GenerateVectorVaryingSettingCode(3, 2, currentVSVarying));
213 currentVSVarying += 1;
214 }
215
Austin Kinross8b695ee2015-03-12 13:12:20 -0700216 for (GLint i = 0; i < vec4Count; i++)
217 {
218 vertexShader->append(GenerateVectorVaryingSettingCode(4, 1, currentVSVarying));
219 currentVSVarying += 1;
220 }
221
222 for (GLint i = 0; i < vec4ArrayCount; i++)
223 {
224 vertexShader->append(GenerateVectorVaryingSettingCode(4, 2, currentVSVarying));
225 currentVSVarying += 1;
226 }
227
228 if (usePointSize)
229 {
230 vertexShader->append("gl_PointSize = 1.0;\n");
231 }
232
Austin Kinrossaf875522014-08-25 21:06:07 -0700233 vertexShader->append("}\n");
234
235 // Generate the fragment shader
236 fragmentShader->clear();
237 fragmentShader->append("precision highp float;\n");
238 fragmentShader->append(varyingDeclaration);
239 fragmentShader->append("\nvoid main() \n{ \n\tvec4 retColor = vec4(0,0,0,0);\n");
240
241 unsigned int currentFSVarying = 0;
242
243 // Make use of the float varyings
244 fragmentShader->append("\tretColor += vec4(");
245
246 for (GLint i = 0; i < floatCount; i++)
247 {
248 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
249 currentFSVarying += 1;
250 }
251
252 for (GLint i = 0; i < floatArrayCount; i++)
253 {
254 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
255 currentFSVarying += 1;
256 }
257
258 fragmentShader->append("0.0, 0.0, 0.0, 0.0);\n");
259
260 // Make use of the vec2 varyings
261 fragmentShader->append("\tretColor += vec4(");
262
263 for (GLint i = 0; i < vec2Count; i++)
264 {
265 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
266 currentFSVarying += 1;
267 }
268
269 for (GLint i = 0; i < vec2ArrayCount; i++)
270 {
271 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
272 currentFSVarying += 1;
273 }
274
275 fragmentShader->append("vec2(0.0, 0.0), 0.0, 0.0);\n");
276
277 // Make use of the vec3 varyings
278 fragmentShader->append("\tretColor += vec4(");
279
280 for (GLint i = 0; i < vec3Count; i++)
281 {
282 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
283 currentFSVarying += 1;
284 }
285
286 for (GLint i = 0; i < vec3ArrayCount; i++)
287 {
288 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
289 currentFSVarying += 1;
290 }
291
292 fragmentShader->append("vec3(0.0, 0.0, 0.0), 0.0);\n");
Austin Kinross8b695ee2015-03-12 13:12:20 -0700293
294 // Make use of the vec4 varyings
295 fragmentShader->append("\tretColor += ");
296
297 for (GLint i = 0; i < vec4Count; i++)
298 {
299 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
300 currentFSVarying += 1;
301 }
302
303 for (GLint i = 0; i < vec4ArrayCount; i++)
304 {
305 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
306 currentFSVarying += 1;
307 }
308
309 fragmentShader->append("vec4(0.0, 0.0, 0.0, 0.0);\n");
310
311 // Set gl_FragColor, and use special variables if requested
312 fragmentShader->append("\tgl_FragColor = retColor");
313
314 if (useFragCoord)
315 {
316 fragmentShader->append(" + gl_FragCoord");
317 }
318
319 if (usePointCoord)
320 {
321 fragmentShader->append(" + vec4(gl_PointCoord, 0.0, 0.0)");
322 }
323
324 fragmentShader->append(";\n}");
325 }
326
327 void VaryingTestBase(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
328 GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize, bool expectSuccess)
329 {
330 std::string fragmentShaderSource;
331 std::string vertexShaderSource;
332
333 GenerateGLSLWithVaryings(floatCount, floatArrayCount, vec2Count, vec2ArrayCount, vec3Count, vec3ArrayCount,
334 vec4Count, vec4ArrayCount, useFragCoord, usePointCoord, usePointSize,
335 &fragmentShaderSource, &vertexShaderSource);
336
337 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
338
339 if (expectSuccess)
340 {
341 EXPECT_NE(0u, program);
342 }
343 else
344 {
345 EXPECT_EQ(0u, program);
346 }
Austin Kinrossaf875522014-08-25 21:06:07 -0700347 }
348
Austin Kinross7a3e8e22015-10-08 15:50:06 -0700349 void CompileGLSLWithUniformsAndSamplers(GLint vertexUniformCount,
350 GLint fragmentUniformCount,
351 GLint vertexSamplersCount,
352 GLint fragmentSamplersCount,
353 bool expectSuccess)
354 {
355 std::stringstream vertexShader;
356 std::stringstream fragmentShader;
357
358 // Generate the vertex shader
359 vertexShader << "precision mediump float;\n";
360
361 for (int i = 0; i < vertexUniformCount; i++)
362 {
363 vertexShader << "uniform vec4 v" << i << ";\n";
364 }
365
366 for (int i = 0; i < vertexSamplersCount; i++)
367 {
368 vertexShader << "uniform sampler2D s" << i << ";\n";
369 }
370
371 vertexShader << "void main()\n{\n";
372
373 for (int i = 0; i < vertexUniformCount; i++)
374 {
375 vertexShader << " gl_Position += v" << i << ";\n";
376 }
377
378 for (int i = 0; i < vertexSamplersCount; i++)
379 {
380 vertexShader << " gl_Position += texture2D(s" << i << ", vec2(0.0, 0.0));\n";
381 }
382
383 if (vertexUniformCount == 0 && vertexSamplersCount == 0)
384 {
385 vertexShader << " gl_Position = vec4(0.0);\n";
386 }
387
388 vertexShader << "}\n";
389
390 // Generate the fragment shader
391 fragmentShader << "precision mediump float;\n";
392
393 for (int i = 0; i < fragmentUniformCount; i++)
394 {
395 fragmentShader << "uniform vec4 v" << i << ";\n";
396 }
397
398 for (int i = 0; i < fragmentSamplersCount; i++)
399 {
400 fragmentShader << "uniform sampler2D s" << i << ";\n";
401 }
402
403 fragmentShader << "void main()\n{\n";
404
405 for (int i = 0; i < fragmentUniformCount; i++)
406 {
407 fragmentShader << " gl_FragColor += v" << i << ";\n";
408 }
409
410 for (int i = 0; i < fragmentSamplersCount; i++)
411 {
412 fragmentShader << " gl_FragColor += texture2D(s" << i << ", vec2(0.0, 0.0));\n";
413 }
414
415 if (fragmentUniformCount == 0 && fragmentSamplersCount == 0)
416 {
417 fragmentShader << " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n";
418 }
419
420 fragmentShader << "}\n";
421
422 GLuint program = CompileProgram(vertexShader.str(), fragmentShader.str());
423
424 if (expectSuccess)
425 {
426 EXPECT_NE(0u, program);
427 }
428 else
429 {
430 EXPECT_EQ(0u, program);
431 }
432 }
433
Jamie Madill2bf8b372014-06-16 17:18:51 -0400434 std::string mSimpleVSSource;
Jamie Madill96509e42014-05-29 14:33:27 -0400435};
436
Jamie Madillfa05f602015-05-07 13:47:11 -0400437class GLSLTest_ES3 : public GLSLTest
Gregoire Payen de La Garanderieb3dced22015-01-12 14:54:55 +0000438{
439};
440
Jamie Madillfa05f602015-05-07 13:47:11 -0400441TEST_P(GLSLTest, NamelessScopedStructs)
Jamie Madill96509e42014-05-29 14:33:27 -0400442{
Jamie Madillbfa91f42014-06-05 15:45:18 -0400443 const std::string fragmentShaderSource = SHADER_SOURCE
Jamie Madill96509e42014-05-29 14:33:27 -0400444 (
Jamie Madillbfa91f42014-06-05 15:45:18 -0400445 precision mediump float;
446
Jamie Madill96509e42014-05-29 14:33:27 -0400447 void main()
448 {
Jamie Madillbfa91f42014-06-05 15:45:18 -0400449 struct
450 {
451 float q;
452 } b;
453
454 gl_FragColor = vec4(1, 0, 0, 1);
455 gl_FragColor.a += b.q;
Jamie Madill96509e42014-05-29 14:33:27 -0400456 }
457 );
458
Jamie Madill5599c8f2014-08-26 13:16:39 -0400459 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madillbfa91f42014-06-05 15:45:18 -0400460 EXPECT_NE(0u, program);
461}
Austin Kinross18b931d2014-09-29 12:58:31 -0700462
Jamie Madillfa05f602015-05-07 13:47:11 -0400463TEST_P(GLSLTest, ScopedStructsOrderBug)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400464{
Geoff Lange0cc2a42016-01-20 10:58:17 -0500465#if defined(__APPLE__)
466 // TODO(geofflang): Find out why this doesn't compile on Apple OpenGL drivers
467 // (http://anglebug.com/1292)
468 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
469 {
470 std::cout << "Test disabled on Apple OpenGL." << std::endl;
471 return;
472 }
473#elif defined(_WIN32)
474 // TODO(geofflang): Find out why this doesn't compile on Windows AMD OpenGL drivers
475 // (http://anglebug.com/1291)
476 if (isAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
477 {
478 std::cout << "Test disabled on Windows AMD OpenGL." << std::endl;
479 return;
480 }
481#endif
482
Jamie Madillbfa91f42014-06-05 15:45:18 -0400483 const std::string fragmentShaderSource = SHADER_SOURCE
484 (
485 precision mediump float;
486
487 struct T
488 {
489 float f;
490 };
491
492 void main()
493 {
494 T a;
495
496 struct T
497 {
498 float q;
499 };
500
501 T b;
502
503 gl_FragColor = vec4(1, 0, 0, 1);
504 gl_FragColor.a += a.f;
505 gl_FragColor.a += b.q;
506 }
507 );
508
Jamie Madill5599c8f2014-08-26 13:16:39 -0400509 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madillbfa91f42014-06-05 15:45:18 -0400510 EXPECT_NE(0u, program);
511}
512
Jamie Madillfa05f602015-05-07 13:47:11 -0400513TEST_P(GLSLTest, ScopedStructsBug)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400514{
Jamie Madill96509e42014-05-29 14:33:27 -0400515 const std::string fragmentShaderSource = SHADER_SOURCE
516 (
517 precision mediump float;
518
519 struct T_0
520 {
521 float f;
522 };
523
524 void main()
525 {
526 gl_FragColor = vec4(1, 0, 0, 1);
527
528 struct T
529 {
530 vec2 v;
531 };
532
533 T_0 a;
534 T b;
535
536 gl_FragColor.a += a.f;
537 gl_FragColor.a += b.v.x;
538 }
539 );
540
Jamie Madill5599c8f2014-08-26 13:16:39 -0400541 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madill2bf8b372014-06-16 17:18:51 -0400542 EXPECT_NE(0u, program);
543}
544
Jamie Madillfa05f602015-05-07 13:47:11 -0400545TEST_P(GLSLTest, DxPositionBug)
Jamie Madill2bf8b372014-06-16 17:18:51 -0400546{
547 const std::string &vertexShaderSource = SHADER_SOURCE
548 (
549 attribute vec4 inputAttribute;
550 varying float dx_Position;
551 void main()
552 {
553 gl_Position = vec4(inputAttribute);
554 dx_Position = 0.0;
555 }
556 );
557
558 const std::string &fragmentShaderSource = SHADER_SOURCE
559 (
560 precision mediump float;
561
562 varying float dx_Position;
563
564 void main()
565 {
566 gl_FragColor = vec4(dx_Position, 0, 0, 1);
567 }
568 );
569
Jamie Madill5599c8f2014-08-26 13:16:39 -0400570 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill96509e42014-05-29 14:33:27 -0400571 EXPECT_NE(0u, program);
572}
Jamie Madill4836d222014-07-24 06:55:51 -0400573
Jamie Madillfa05f602015-05-07 13:47:11 -0400574TEST_P(GLSLTest, ElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400575{
576 const std::string &vertexShaderSource =
577 "attribute vec4 a_position;\n"
578 "varying float v;\n"
579 "void main() {\n"
580 " gl_Position = a_position;\n"
581 " v = 1.0;\n"
582 " if (a_position.x <= 0.5) {\n"
583 " v = 0.0;\n"
584 " } else if (a_position.x >= 0.5) {\n"
585 " v = 2.0;\n"
586 " }\n"
587 "}\n";
588
589 const std::string &fragmentShaderSource =
590 "precision highp float;\n"
591 "varying float v;\n"
592 "void main() {\n"
593 " vec4 color = vec4(1.0, 0.0, 0.0, 1.0);\n"
594 " if (v >= 1.0) color = vec4(0.0, 1.0, 0.0, 1.0);\n"
595 " if (v >= 2.0) color = vec4(0.0, 0.0, 1.0, 1.0);\n"
596 " gl_FragColor = color;\n"
597 "}\n";
598
Jamie Madill5599c8f2014-08-26 13:16:39 -0400599 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400600 ASSERT_NE(0u, program);
601
602 drawQuad(program, "a_position", 0.5f);
Jamie Madill4836d222014-07-24 06:55:51 -0400603
604 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
605 EXPECT_PIXEL_EQ(getWindowWidth()-1, 0, 0, 255, 0, 255);
606}
607
Jamie Madillfa05f602015-05-07 13:47:11 -0400608TEST_P(GLSLTest, TwoElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400609{
610 const std::string &vertexShaderSource =
611 "attribute vec4 a_position;\n"
612 "varying float v;\n"
613 "void main() {\n"
614 " gl_Position = a_position;\n"
Jamie Madill778d5272014-08-04 13:13:25 -0400615 " if (a_position.x == 0.0) {\n"
Jamie Madill4836d222014-07-24 06:55:51 -0400616 " v = 1.0;\n"
617 " } else if (a_position.x > 0.5) {\n"
618 " v = 0.0;\n"
619 " } else if (a_position.x > 0.75) {\n"
620 " v = 0.5;\n"
621 " }\n"
622 "}\n";
623
624 const std::string &fragmentShaderSource =
625 "precision highp float;\n"
626 "varying float v;\n"
627 "void main() {\n"
628 " gl_FragColor = vec4(v, 0.0, 0.0, 1.0);\n"
629 "}\n";
630
Jamie Madill5599c8f2014-08-26 13:16:39 -0400631 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400632 EXPECT_NE(0u, program);
633}
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400634
Jamie Madillfa05f602015-05-07 13:47:11 -0400635TEST_P(GLSLTest, InvariantVaryingOut)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400636{
Geoff Lange0cc2a42016-01-20 10:58:17 -0500637 // TODO(geofflang): Some OpenGL drivers have compile errors when varyings do not have matching
638 // invariant attributes (http://anglebug.com/1293)
639 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
640 {
641 std::cout << "Test disabled on OpenGL." << std::endl;
642 return;
643 }
644
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400645 const std::string fragmentShaderSource = SHADER_SOURCE
646 (
647 precision mediump float;
648 varying float v_varying;
649 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
650 );
651
652 const std::string vertexShaderSource = SHADER_SOURCE
653 (
654 attribute vec4 a_position;
655 invariant varying float v_varying;
656 void main() { v_varying = a_position.x; gl_Position = a_position; }
657 );
658
Jamie Madill5599c8f2014-08-26 13:16:39 -0400659 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400660 EXPECT_NE(0u, program);
661}
662
Jamie Madillfa05f602015-05-07 13:47:11 -0400663TEST_P(GLSLTest, FrontFacingAndVarying)
Jamie Madille6256f82014-09-17 10:31:15 -0400664{
Geoff Langdd323e92015-06-09 15:16:31 -0400665 EGLPlatformParameters platform = GetParam().eglParameters;
Austin Kinross8b695ee2015-03-12 13:12:20 -0700666
Jamie Madille6256f82014-09-17 10:31:15 -0400667 const std::string vertexShaderSource = SHADER_SOURCE
668 (
669 attribute vec4 a_position;
670 varying float v_varying;
671 void main()
672 {
673 v_varying = a_position.x;
674 gl_Position = a_position;
675 }
676 );
677
678 const std::string fragmentShaderSource = SHADER_SOURCE
679 (
680 precision mediump float;
681 varying float v_varying;
682 void main()
683 {
684 vec4 c;
685
686 if (gl_FrontFacing)
687 {
688 c = vec4(v_varying, 0, 0, 1.0);
689 }
690 else
691 {
692 c = vec4(0, v_varying, 0, 1.0);
693 }
694 gl_FragColor = c;
695 }
696 );
697
698 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Austin Kinross02df7962015-07-01 10:03:42 -0700699
700 // Compilation should fail on D3D11 feature level 9_3, since gl_FrontFacing isn't supported.
701 if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
702 {
703 if (platform.majorVersion == 9 && platform.minorVersion == 3)
704 {
705 EXPECT_EQ(0u, program);
706 return;
707 }
708 }
709
710 // Otherwise, compilation should succeed
Jamie Madille6256f82014-09-17 10:31:15 -0400711 EXPECT_NE(0u, program);
712}
713
Jamie Madillfa05f602015-05-07 13:47:11 -0400714TEST_P(GLSLTest, InvariantVaryingIn)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400715{
Geoff Lange0cc2a42016-01-20 10:58:17 -0500716 // TODO(geofflang): Some OpenGL drivers have compile errors when varyings do not have matching
717 // invariant attributes (http://anglebug.com/1293)
718 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
719 {
720 std::cout << "Test disabled on OpenGL." << std::endl;
721 return;
722 }
723
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400724 const std::string fragmentShaderSource = SHADER_SOURCE
725 (
726 precision mediump float;
727 invariant varying float v_varying;
728 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
729 );
730
731 const std::string vertexShaderSource = SHADER_SOURCE
732 (
733 attribute vec4 a_position;
734 varying float v_varying;
735 void main() { v_varying = a_position.x; gl_Position = a_position; }
736 );
737
Jamie Madill5599c8f2014-08-26 13:16:39 -0400738 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400739 EXPECT_NE(0u, program);
740}
741
Jamie Madillfa05f602015-05-07 13:47:11 -0400742TEST_P(GLSLTest, InvariantVaryingBoth)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400743{
744 const std::string fragmentShaderSource = SHADER_SOURCE
745 (
746 precision mediump float;
747 invariant varying float v_varying;
748 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
749 );
750
751 const std::string vertexShaderSource = SHADER_SOURCE
752 (
753 attribute vec4 a_position;
754 invariant varying float v_varying;
755 void main() { v_varying = a_position.x; gl_Position = a_position; }
756 );
757
Jamie Madill5599c8f2014-08-26 13:16:39 -0400758 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400759 EXPECT_NE(0u, program);
760}
761
Jamie Madillfa05f602015-05-07 13:47:11 -0400762TEST_P(GLSLTest, InvariantGLPosition)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400763{
764 const std::string fragmentShaderSource = SHADER_SOURCE
765 (
766 precision mediump float;
767 varying float v_varying;
768 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
769 );
770
771 const std::string vertexShaderSource = SHADER_SOURCE
772 (
773 attribute vec4 a_position;
774 invariant gl_Position;
775 varying float v_varying;
776 void main() { v_varying = a_position.x; gl_Position = a_position; }
777 );
778
Jamie Madill5599c8f2014-08-26 13:16:39 -0400779 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400780 EXPECT_NE(0u, program);
781}
782
Jamie Madillfa05f602015-05-07 13:47:11 -0400783TEST_P(GLSLTest, InvariantAll)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400784{
Geoff Lange0cc2a42016-01-20 10:58:17 -0500785 // TODO(geofflang): Some OpenGL drivers have compile errors when varyings do not have matching
786 // invariant attributes (http://anglebug.com/1293)
787 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
788 {
789 std::cout << "Test disabled on OpenGL." << std::endl;
790 return;
791 }
792
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400793 const std::string fragmentShaderSource = SHADER_SOURCE
794 (
795 precision mediump float;
796 varying float v_varying;
797 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
798 );
799
800 const std::string vertexShaderSource =
801 "#pragma STDGL invariant(all)\n"
802 "attribute vec4 a_position;\n"
803 "varying float v_varying;\n"
804 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
805
Jamie Madill5599c8f2014-08-26 13:16:39 -0400806 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400807 EXPECT_NE(0u, program);
808}
Austin Kinrossaf875522014-08-25 21:06:07 -0700809
Jamie Madillfa05f602015-05-07 13:47:11 -0400810TEST_P(GLSLTest, MaxVaryingVec4)
Austin Kinross8b695ee2015-03-12 13:12:20 -0700811{
Geoff Lang69accbd2016-01-25 16:22:32 -0500812#if defined(__APPLE__)
813 // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
814 // (http://anglebug.com/1291)
815 if (isAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
816 {
817 std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
818 return;
819 }
820#endif
821
Austin Kinross8b695ee2015-03-12 13:12:20 -0700822 GLint maxVaryings = 0;
823 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
824
825 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, false, false, true);
826}
827
Jamie Madillfa05f602015-05-07 13:47:11 -0400828TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusTwoSpecialVariables)
Austin Kinross8b695ee2015-03-12 13:12:20 -0700829{
830 GLint maxVaryings = 0;
831 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
832
833 // Generate shader code that uses gl_FragCoord and gl_PointCoord, two special fragment shader variables.
834 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, false, true);
835}
836
Jamie Madillfa05f602015-05-07 13:47:11 -0400837TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusThreeSpecialVariables)
Austin Kinross8b695ee2015-03-12 13:12:20 -0700838{
Geoff Lange0cc2a42016-01-20 10:58:17 -0500839 // TODO(geofflang): Figure out why this fails on OpenGL AMD (http://anglebug.com/1291)
840 if (isAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
841 {
842 std::cout << "Test disabled on OpenGL." << std::endl;
843 return;
844 }
845
Austin Kinross8b695ee2015-03-12 13:12:20 -0700846 GLint maxVaryings = 0;
847 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
848
849 // Generate shader code that uses gl_FragCoord, gl_PointCoord and gl_PointSize.
850 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, true, true);
851}
852
Geoff Lange0cc2a42016-01-20 10:58:17 -0500853// Disabled because drivers are allowed to successfully compile shaders that have more than the
854// maximum number of varyings. (http://anglebug.com/1296)
855TEST_P(GLSLTest, DISABLED_MaxVaryingVec4PlusFragCoord)
Austin Kinross8b695ee2015-03-12 13:12:20 -0700856{
857 GLint maxVaryings = 0;
858 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
859
860 // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
861 // This test should fail, since we are really using (maxVaryings + 1) varyings.
862 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, true, false, false, false);
863}
864
Geoff Lange0cc2a42016-01-20 10:58:17 -0500865// Disabled because drivers are allowed to successfully compile shaders that have more than the
866// maximum number of varyings. (http://anglebug.com/1296)
867TEST_P(GLSLTest, DISABLED_MaxVaryingVec4PlusPointCoord)
Austin Kinross8b695ee2015-03-12 13:12:20 -0700868{
869 GLint maxVaryings = 0;
870 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
871
872 // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
873 // This test should fail, since we are really using (maxVaryings + 1) varyings.
874 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, true, false, false);
875}
876
Jamie Madillfa05f602015-05-07 13:47:11 -0400877TEST_P(GLSLTest, MaxVaryingVec3)
Austin Kinrossaf875522014-08-25 21:06:07 -0700878{
879 GLint maxVaryings = 0;
880 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
881
Austin Kinross8b695ee2015-03-12 13:12:20 -0700882 VaryingTestBase(0, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700883}
884
Jamie Madillfa05f602015-05-07 13:47:11 -0400885TEST_P(GLSLTest, MaxVaryingVec3Array)
Austin Kinrossaf875522014-08-25 21:06:07 -0700886{
887 GLint maxVaryings = 0;
888 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
889
Austin Kinross8b695ee2015-03-12 13:12:20 -0700890 VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700891}
892
Jamie Madillbee59e02014-10-02 10:44:18 -0400893// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -0500894TEST_P(GLSLTest, MaxVaryingVec3AndOneFloat)
Austin Kinrossaf875522014-08-25 21:06:07 -0700895{
Jamie Madill9fc36822015-11-18 13:08:07 -0500896 if (isD3D9())
897 {
898 std::cout << "Test disabled on D3D9." << std::endl;
899 return;
900 }
901
Austin Kinrossaf875522014-08-25 21:06:07 -0700902 GLint maxVaryings = 0;
903 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
904
Austin Kinross8b695ee2015-03-12 13:12:20 -0700905 VaryingTestBase(1, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700906}
907
Jamie Madillbee59e02014-10-02 10:44:18 -0400908// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -0500909TEST_P(GLSLTest, MaxVaryingVec3ArrayAndOneFloatArray)
Austin Kinrossaf875522014-08-25 21:06:07 -0700910{
Jamie Madill9fc36822015-11-18 13:08:07 -0500911 if (isD3D9())
912 {
913 std::cout << "Test disabled on D3D9." << std::endl;
914 return;
915 }
916
Austin Kinrossaf875522014-08-25 21:06:07 -0700917 GLint maxVaryings = 0;
918 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
919
Austin Kinross8b695ee2015-03-12 13:12:20 -0700920 VaryingTestBase(0, 1, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700921}
922
Jamie Madillbee59e02014-10-02 10:44:18 -0400923// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -0500924TEST_P(GLSLTest, TwiceMaxVaryingVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -0700925{
Jamie Madill9fc36822015-11-18 13:08:07 -0500926 if (isD3D9())
927 {
928 std::cout << "Test disabled on D3D9." << std::endl;
929 return;
930 }
931
Geoff Lange0cc2a42016-01-20 10:58:17 -0500932 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
933 {
934 // TODO(geofflang): Figure out why this fails on NVIDIA's GLES driver
935 std::cout << "Test disabled on OpenGL ES." << std::endl;
936 return;
937 }
938
Geoff Lang69accbd2016-01-25 16:22:32 -0500939#if defined(__APPLE__)
940 // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
941 // (http://anglebug.com/1291)
942 if (isAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
943 {
944 std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
945 return;
946 }
947#endif
948
Austin Kinrossaf875522014-08-25 21:06:07 -0700949 GLint maxVaryings = 0;
950 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
951
Austin Kinross8b695ee2015-03-12 13:12:20 -0700952 VaryingTestBase(0, 0, 2 * maxVaryings, 0, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700953}
954
Jamie Madillbee59e02014-10-02 10:44:18 -0400955// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -0500956TEST_P(GLSLTest, MaxVaryingVec2Arrays)
Austin Kinrossaf875522014-08-25 21:06:07 -0700957{
Jamie Madill9fc36822015-11-18 13:08:07 -0500958 if (isD3DSM3())
959 {
960 std::cout << "Test disabled on SM3." << std::endl;
961 return;
962 }
963
Geoff Lange0cc2a42016-01-20 10:58:17 -0500964 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
965 {
966 // TODO(geofflang): Figure out why this fails on NVIDIA's GLES driver
967 std::cout << "Test disabled on OpenGL ES." << std::endl;
968 return;
969 }
970
Geoff Lang69accbd2016-01-25 16:22:32 -0500971#if defined(__APPLE__)
972 // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
973 // (http://anglebug.com/1291)
974 if (isAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
975 {
976 std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
977 return;
978 }
979#endif
980
Austin Kinrossaf875522014-08-25 21:06:07 -0700981 GLint maxVaryings = 0;
982 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
983
Austin Kinross8b695ee2015-03-12 13:12:20 -0700984 VaryingTestBase(0, 0, 0, maxVaryings, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700985}
986
Geoff Lange0cc2a42016-01-20 10:58:17 -0500987// Disabled because drivers are allowed to successfully compile shaders that have more than the
988// maximum number of varyings. (http://anglebug.com/1296)
989TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec3)
Austin Kinrossaf875522014-08-25 21:06:07 -0700990{
991 GLint maxVaryings = 0;
992 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
993
Austin Kinross8b695ee2015-03-12 13:12:20 -0700994 VaryingTestBase(0, 0, 0, 0, maxVaryings + 1, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700995}
996
Geoff Lange0cc2a42016-01-20 10:58:17 -0500997// Disabled because drivers are allowed to successfully compile shaders that have more than the
998// maximum number of varyings. (http://anglebug.com/1296)
999TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec3Array)
Austin Kinrossaf875522014-08-25 21:06:07 -07001000{
1001 GLint maxVaryings = 0;
1002 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1003
Austin Kinross8b695ee2015-03-12 13:12:20 -07001004 VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2 + 1, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001005}
1006
Geoff Lange0cc2a42016-01-20 10:58:17 -05001007// Disabled because drivers are allowed to successfully compile shaders that have more than the
1008// maximum number of varyings. (http://anglebug.com/1296)
1009TEST_P(GLSLTest, DISABLED_MaxVaryingVec3AndOneVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -07001010{
1011 GLint maxVaryings = 0;
1012 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1013
Austin Kinross8b695ee2015-03-12 13:12:20 -07001014 VaryingTestBase(0, 0, 1, 0, maxVaryings, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001015}
1016
Geoff Lange0cc2a42016-01-20 10:58:17 -05001017// Disabled because drivers are allowed to successfully compile shaders that have more than the
1018// maximum number of varyings. (http://anglebug.com/1296)
1019TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -07001020{
1021 GLint maxVaryings = 0;
1022 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1023
Austin Kinross8b695ee2015-03-12 13:12:20 -07001024 VaryingTestBase(0, 0, 2 * maxVaryings + 1, 0, 0, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001025}
1026
Geoff Lange0cc2a42016-01-20 10:58:17 -05001027// Disabled because drivers are allowed to successfully compile shaders that have more than the
1028// maximum number of varyings. (http://anglebug.com/1296)
1029TEST_P(GLSLTest, DISABLED_MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
Austin Kinrossaf875522014-08-25 21:06:07 -07001030{
1031 GLint maxVaryings = 0;
1032 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1033
Austin Kinross8b695ee2015-03-12 13:12:20 -07001034 VaryingTestBase(0, maxVaryings / 2 + 1, 0, 0, 0, 0, 0, maxVaryings / 2, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001035}
Geoff Langf60fab62014-11-24 11:21:20 -05001036
1037// Verify shader source with a fixed length that is less than the null-terminated length will compile.
Jamie Madillfa05f602015-05-07 13:47:11 -04001038TEST_P(GLSLTest, FixedShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -05001039{
1040 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1041
1042 const std::string appendGarbage = "abcasdfasdfasdfasdfasdf";
1043 const std::string source = "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" + appendGarbage;
1044 const char *sourceArray[1] = { source.c_str() };
Corentin Wallez973402f2015-05-11 13:42:22 -04001045 GLint lengths[1] = { static_cast<GLint>(source.length() - appendGarbage.length()) };
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001046 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001047 glCompileShader(shader);
1048
1049 GLint compileResult;
1050 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1051 EXPECT_NE(compileResult, 0);
1052}
1053
1054// Verify that a negative shader source length is treated as a null-terminated length.
Jamie Madillfa05f602015-05-07 13:47:11 -04001055TEST_P(GLSLTest, NegativeShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -05001056{
1057 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1058
1059 const char *sourceArray[1] = { "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" };
1060 GLint lengths[1] = { -10 };
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001061 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001062 glCompileShader(shader);
1063
1064 GLint compileResult;
1065 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1066 EXPECT_NE(compileResult, 0);
1067}
1068
1069// Verify that a length array with mixed positive and negative values compiles.
Jamie Madillfa05f602015-05-07 13:47:11 -04001070TEST_P(GLSLTest, MixedShaderLengths)
Geoff Langf60fab62014-11-24 11:21:20 -05001071{
1072 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1073
1074 const char *sourceArray[] =
1075 {
1076 "void main()",
1077 "{",
1078 " gl_FragColor = vec4(0, 0, 0, 0);",
1079 "}",
1080 };
1081 GLint lengths[] =
1082 {
1083 -10,
1084 1,
Corentin Wallez973402f2015-05-11 13:42:22 -04001085 static_cast<GLint>(strlen(sourceArray[2])),
Geoff Langf60fab62014-11-24 11:21:20 -05001086 -1,
1087 };
1088 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
1089
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001090 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001091 glCompileShader(shader);
1092
1093 GLint compileResult;
1094 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1095 EXPECT_NE(compileResult, 0);
1096}
1097
1098// Verify that zero-length shader source does not affect shader compilation.
Jamie Madillfa05f602015-05-07 13:47:11 -04001099TEST_P(GLSLTest, ZeroShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -05001100{
1101 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1102
1103 const char *sourceArray[] =
1104 {
1105 "adfasdf",
1106 "34534",
1107 "void main() { gl_FragColor = vec4(0, 0, 0, 0); }",
1108 "",
1109 "asdfasdfsdsdf",
1110 };
1111 GLint lengths[] =
1112 {
1113 0,
1114 0,
1115 -1,
1116 0,
1117 0,
1118 };
1119 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
1120
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001121 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001122 glCompileShader(shader);
1123
1124 GLint compileResult;
1125 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1126 EXPECT_NE(compileResult, 0);
1127}
Jamie Madill21c1e452014-12-29 11:33:41 -05001128
1129// Tests that bad index expressions don't crash ANGLE's translator.
1130// https://code.google.com/p/angleproject/issues/detail?id=857
Jamie Madillfa05f602015-05-07 13:47:11 -04001131TEST_P(GLSLTest, BadIndexBug)
Jamie Madill21c1e452014-12-29 11:33:41 -05001132{
1133 const std::string &fragmentShaderSourceVec =
1134 "precision mediump float;\n"
1135 "uniform vec4 uniformVec;\n"
1136 "void main()\n"
1137 "{\n"
1138 " gl_FragColor = vec4(uniformVec[int()]);\n"
1139 "}";
1140
1141 GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceVec);
1142 EXPECT_EQ(0u, shader);
1143
1144 if (shader != 0)
1145 {
1146 glDeleteShader(shader);
1147 }
1148
1149 const std::string &fragmentShaderSourceMat =
1150 "precision mediump float;\n"
1151 "uniform mat4 uniformMat;\n"
1152 "void main()\n"
1153 "{\n"
1154 " gl_FragColor = vec4(uniformMat[int()]);\n"
1155 "}";
1156
1157 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceMat);
1158 EXPECT_EQ(0u, shader);
1159
1160 if (shader != 0)
1161 {
1162 glDeleteShader(shader);
1163 }
1164
1165 const std::string &fragmentShaderSourceArray =
1166 "precision mediump float;\n"
1167 "uniform vec4 uniformArray;\n"
1168 "void main()\n"
1169 "{\n"
1170 " gl_FragColor = vec4(uniformArray[int()]);\n"
1171 "}";
1172
1173 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceArray);
1174 EXPECT_EQ(0u, shader);
1175
1176 if (shader != 0)
1177 {
1178 glDeleteShader(shader);
1179 }
Jamie Madill37997142015-01-28 10:06:34 -05001180}
1181
Jamie Madill2e295e22015-04-29 10:41:33 -04001182// Test that structs defined in uniforms are translated correctly.
Jamie Madillfa05f602015-05-07 13:47:11 -04001183TEST_P(GLSLTest, StructSpecifiersUniforms)
Jamie Madill2e295e22015-04-29 10:41:33 -04001184{
1185 const std::string fragmentShaderSource = SHADER_SOURCE
1186 (
1187 precision mediump float;
1188
1189 uniform struct S { float field;} s;
1190
1191 void main()
1192 {
1193 gl_FragColor = vec4(1, 0, 0, 1);
1194 gl_FragColor.a += s.field;
1195 }
1196 );
1197
1198 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1199 EXPECT_NE(0u, program);
1200}
Jamie Madill55def582015-05-04 11:24:57 -04001201
1202// Test that gl_DepthRange is not stored as a uniform location. Since uniforms
1203// beginning with "gl_" are filtered out by our validation logic, we must
1204// bypass the validation to test the behaviour of the implementation.
1205// (note this test is still Impl-independent)
Jamie Madillfa05f602015-05-07 13:47:11 -04001206TEST_P(GLSLTest, DepthRangeUniforms)
Jamie Madill55def582015-05-04 11:24:57 -04001207{
1208 const std::string fragmentShaderSource = SHADER_SOURCE
1209 (
1210 precision mediump float;
1211
1212 void main()
1213 {
1214 gl_FragColor = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff, 1);
1215 }
1216 );
1217
1218 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1219 EXPECT_NE(0u, program);
1220
1221 // dive into the ANGLE internals, so we can bypass validation.
1222 gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
1223 gl::Program *glProgram = context->getProgram(program);
1224 GLint nearIndex = glProgram->getUniformLocation("gl_DepthRange.near");
1225 EXPECT_EQ(-1, nearIndex);
1226
1227 // Test drawing does not throw an exception.
1228 drawQuad(program, "inputAttribute", 0.5f);
1229
1230 EXPECT_GL_NO_ERROR();
1231
1232 glDeleteProgram(program);
1233}
Jamie Madill4052dfc2015-05-06 15:18:49 -04001234
1235// Covers the WebGL test 'glsl/bugs/pow-of-small-constant-in-user-defined-function'
1236// See https://code.google.com/p/angleproject/issues/detail?id=851
1237// TODO(jmadill): ANGLE constant folding can fix this
Jamie Madillfa05f602015-05-07 13:47:11 -04001238TEST_P(GLSLTest, DISABLED_PowOfSmallConstant)
Jamie Madill4052dfc2015-05-06 15:18:49 -04001239{
1240 const std::string &fragmentShaderSource = SHADER_SOURCE
1241 (
1242 precision highp float;
1243
1244 float fun(float arg)
1245 {
1246 // These values are still easily within the highp range.
1247 // The minimum range in terms of 10's exponent is around -19 to 19, and IEEE-754 single precision range is higher than that.
1248 return pow(arg, 2.0);
1249 }
1250
1251 void main()
1252 {
1253 // Note that the bug did not reproduce if an uniform was passed to the function instead of a constant,
1254 // or if the expression was moved outside the user-defined function.
1255 const float a = 1.0e-6;
1256 float b = 1.0e12 * fun(a);
1257 if (abs(b - 1.0) < 0.01)
1258 {
1259 gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); // green
1260 }
1261 else
1262 {
1263 gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // red
1264 }
1265 }
1266 );
1267
1268 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1269 EXPECT_NE(0u, program);
1270
1271 drawQuad(program, "inputAttribute", 0.5f);
1272 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1273 EXPECT_GL_NO_ERROR();
1274}
Jamie Madillfa05f602015-05-07 13:47:11 -04001275
Cooper Partina5ef8d82015-08-19 14:52:21 -07001276// Test that fragment shaders which contain non-constant loop indexers and compiled for FL9_3 and
1277// below
1278// fail with a specific error message.
1279// Additionally test that the same fragment shader compiles successfully with feature levels greater
1280// than FL9_3.
1281TEST_P(GLSLTest, LoopIndexingValidation)
1282{
1283 const std::string fragmentShaderSource = SHADER_SOURCE
1284 (
1285 precision mediump float;
1286
1287 uniform float loopMax;
1288
1289 void main()
1290 {
1291 gl_FragColor = vec4(1, 0, 0, 1);
1292 for (float l = 0.0; l < loopMax; l++)
1293 {
1294 if (loopMax > 3.0)
1295 {
1296 gl_FragColor.a += 0.1;
1297 }
1298 }
1299 }
1300 );
1301
1302 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1303
1304 const char *sourceArray[1] = {fragmentShaderSource.c_str()};
1305 glShaderSource(shader, 1, sourceArray, nullptr);
1306 glCompileShader(shader);
1307
1308 GLint compileResult;
1309 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1310
1311 // If the test is configured to run limited to Feature Level 9_3, then it is
1312 // assumed that shader compilation will fail with an expected error message containing
1313 // "Loop index cannot be compared with non-constant expression"
Olli Etuaho814a54d2015-08-27 16:23:09 +03001314 if ((GetParam() == ES2_D3D11_FL9_3() || GetParam() == ES2_D3D9()))
Cooper Partina5ef8d82015-08-19 14:52:21 -07001315 {
1316 if (compileResult != 0)
1317 {
1318 FAIL() << "Shader compilation succeeded, expected failure";
1319 }
1320 else
1321 {
1322 GLint infoLogLength;
1323 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
1324
1325 std::string infoLog;
1326 infoLog.resize(infoLogLength);
1327 glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
1328
1329 if (infoLog.find("Loop index cannot be compared with non-constant expression") ==
1330 std::string::npos)
1331 {
1332 FAIL() << "Shader compilation failed with unexpected error message";
1333 }
1334 }
1335 }
1336 else
1337 {
1338 EXPECT_NE(0, compileResult);
1339 }
1340
1341 if (shader != 0)
1342 {
1343 glDeleteShader(shader);
1344 }
1345}
1346
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001347// Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1348// can actually be used.
1349TEST_P(GLSLTest, VerifyMaxVertexUniformVectors)
1350{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001351 int maxUniforms = 10000;
1352 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1353 EXPECT_GL_NO_ERROR();
1354 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl;
1355
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001356 CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, 0, 0, true);
1357}
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001358
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001359// Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1360// can actually be used along with the maximum number of texture samplers.
1361TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsWithSamplers)
1362{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001363 if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1364 GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1365 {
1366 std::cout << "Test disabled on OpenGL." << std::endl;
1367 return;
1368 }
1369
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001370 int maxUniforms = 10000;
1371 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1372 EXPECT_GL_NO_ERROR();
1373 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001374
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001375 int maxTextureImageUnits = 0;
1376 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001377
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001378 CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, maxTextureImageUnits, 0, true);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001379}
1380
1381// Tests that the maximum uniforms count + 1 from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1382// fails shader compilation.
1383TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsExceeded)
1384{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001385 int maxUniforms = 10000;
1386 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1387 EXPECT_GL_NO_ERROR();
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001388 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS + 1 = " << maxUniforms + 1 << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001389
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001390 CompileGLSLWithUniformsAndSamplers(maxUniforms + 1, 0, 0, 0, false);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001391}
1392
1393// Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1394// can actually be used.
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001395TEST_P(GLSLTest, VerifyMaxFragmentUniformVectors)
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001396{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001397 int maxUniforms = 10000;
1398 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1399 EXPECT_GL_NO_ERROR();
1400 std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS = " << maxUniforms << std::endl;
1401
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001402 CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, 0, true);
1403}
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001404
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001405// Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1406// can actually be used along with the maximum number of texture samplers.
1407TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsWithSamplers)
1408{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001409 if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1410 GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1411 {
1412 std::cout << "Test disabled on OpenGL." << std::endl;
1413 return;
1414 }
1415
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001416 int maxUniforms = 10000;
1417 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1418 EXPECT_GL_NO_ERROR();
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001419
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001420 int maxTextureImageUnits = 0;
1421 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001422
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001423 CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, maxTextureImageUnits, true);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001424}
1425
1426// Tests that the maximum uniforms count + 1 from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1427// fails shader compilation.
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001428TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsExceeded)
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001429{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001430 int maxUniforms = 10000;
1431 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1432 EXPECT_GL_NO_ERROR();
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001433 std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS + 1 = " << maxUniforms + 1
1434 << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001435
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001436 CompileGLSLWithUniformsAndSamplers(0, maxUniforms + 1, 0, 0, false);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001437}
1438
Jamie Madillfa05f602015-05-07 13:47:11 -04001439// 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 -05001440ANGLE_INSTANTIATE_TEST(GLSLTest,
1441 ES2_D3D9(),
1442 ES2_D3D11(),
1443 ES2_D3D11_FL9_3(),
1444 ES2_OPENGL(),
1445 ES3_OPENGL(),
1446 ES2_OPENGLES(),
1447 ES3_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04001448
1449// 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 -05001450ANGLE_INSTANTIATE_TEST(GLSLTest_ES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());