blob: 046b44944e7eb181a0df8c919d95d329a83e9d4d [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 // TODO(geofflang): Find out why this doesn't compile on Apple OpenGL drivers
466 // (http://anglebug.com/1292)
Geoff Lang5103f4c2016-01-26 11:40:18 -0500467 // TODO(geofflang): Find out why this doesn't compile on AMD OpenGL drivers
Geoff Lange0cc2a42016-01-20 10:58:17 -0500468 // (http://anglebug.com/1291)
Jamie Madill7208f692016-02-29 10:47:35 -0500469 if (isOpenGL() && (IsOSX() || !IsNVIDIA()))
Geoff Lange0cc2a42016-01-20 10:58:17 -0500470 {
Jamie Madill7208f692016-02-29 10:47:35 -0500471 std::cout << "Test disabled on this OpenGL configuration." << std::endl;
Geoff Lange0cc2a42016-01-20 10:58:17 -0500472 return;
473 }
Geoff Lange0cc2a42016-01-20 10:58:17 -0500474
Jamie Madillbfa91f42014-06-05 15:45:18 -0400475 const std::string fragmentShaderSource = SHADER_SOURCE
476 (
477 precision mediump float;
478
479 struct T
480 {
481 float f;
482 };
483
484 void main()
485 {
486 T a;
487
488 struct T
489 {
490 float q;
491 };
492
493 T b;
494
495 gl_FragColor = vec4(1, 0, 0, 1);
496 gl_FragColor.a += a.f;
497 gl_FragColor.a += b.q;
498 }
499 );
500
Jamie Madill5599c8f2014-08-26 13:16:39 -0400501 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madillbfa91f42014-06-05 15:45:18 -0400502 EXPECT_NE(0u, program);
503}
504
Jamie Madillfa05f602015-05-07 13:47:11 -0400505TEST_P(GLSLTest, ScopedStructsBug)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400506{
Jamie Madill96509e42014-05-29 14:33:27 -0400507 const std::string fragmentShaderSource = SHADER_SOURCE
508 (
509 precision mediump float;
510
511 struct T_0
512 {
513 float f;
514 };
515
516 void main()
517 {
518 gl_FragColor = vec4(1, 0, 0, 1);
519
520 struct T
521 {
522 vec2 v;
523 };
524
525 T_0 a;
526 T b;
527
528 gl_FragColor.a += a.f;
529 gl_FragColor.a += b.v.x;
530 }
531 );
532
Jamie Madill5599c8f2014-08-26 13:16:39 -0400533 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madill2bf8b372014-06-16 17:18:51 -0400534 EXPECT_NE(0u, program);
535}
536
Jamie Madillfa05f602015-05-07 13:47:11 -0400537TEST_P(GLSLTest, DxPositionBug)
Jamie Madill2bf8b372014-06-16 17:18:51 -0400538{
539 const std::string &vertexShaderSource = SHADER_SOURCE
540 (
541 attribute vec4 inputAttribute;
542 varying float dx_Position;
543 void main()
544 {
545 gl_Position = vec4(inputAttribute);
546 dx_Position = 0.0;
547 }
548 );
549
550 const std::string &fragmentShaderSource = SHADER_SOURCE
551 (
552 precision mediump float;
553
554 varying float dx_Position;
555
556 void main()
557 {
558 gl_FragColor = vec4(dx_Position, 0, 0, 1);
559 }
560 );
561
Jamie Madill5599c8f2014-08-26 13:16:39 -0400562 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill96509e42014-05-29 14:33:27 -0400563 EXPECT_NE(0u, program);
564}
Jamie Madill4836d222014-07-24 06:55:51 -0400565
Jamie Madillfa05f602015-05-07 13:47:11 -0400566TEST_P(GLSLTest, ElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400567{
568 const std::string &vertexShaderSource =
569 "attribute vec4 a_position;\n"
570 "varying float v;\n"
571 "void main() {\n"
572 " gl_Position = a_position;\n"
573 " v = 1.0;\n"
574 " if (a_position.x <= 0.5) {\n"
575 " v = 0.0;\n"
576 " } else if (a_position.x >= 0.5) {\n"
577 " v = 2.0;\n"
578 " }\n"
579 "}\n";
580
581 const std::string &fragmentShaderSource =
582 "precision highp float;\n"
583 "varying float v;\n"
584 "void main() {\n"
585 " vec4 color = vec4(1.0, 0.0, 0.0, 1.0);\n"
586 " if (v >= 1.0) color = vec4(0.0, 1.0, 0.0, 1.0);\n"
587 " if (v >= 2.0) color = vec4(0.0, 0.0, 1.0, 1.0);\n"
588 " gl_FragColor = color;\n"
589 "}\n";
590
Jamie Madill5599c8f2014-08-26 13:16:39 -0400591 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400592 ASSERT_NE(0u, program);
593
594 drawQuad(program, "a_position", 0.5f);
Jamie Madill4836d222014-07-24 06:55:51 -0400595
596 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
597 EXPECT_PIXEL_EQ(getWindowWidth()-1, 0, 0, 255, 0, 255);
598}
599
Jamie Madillfa05f602015-05-07 13:47:11 -0400600TEST_P(GLSLTest, TwoElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400601{
602 const std::string &vertexShaderSource =
603 "attribute vec4 a_position;\n"
604 "varying float v;\n"
605 "void main() {\n"
606 " gl_Position = a_position;\n"
Jamie Madill778d5272014-08-04 13:13:25 -0400607 " if (a_position.x == 0.0) {\n"
Jamie Madill4836d222014-07-24 06:55:51 -0400608 " v = 1.0;\n"
609 " } else if (a_position.x > 0.5) {\n"
610 " v = 0.0;\n"
611 " } else if (a_position.x > 0.75) {\n"
612 " v = 0.5;\n"
613 " }\n"
614 "}\n";
615
616 const std::string &fragmentShaderSource =
617 "precision highp float;\n"
618 "varying float v;\n"
619 "void main() {\n"
620 " gl_FragColor = vec4(v, 0.0, 0.0, 1.0);\n"
621 "}\n";
622
Jamie Madill5599c8f2014-08-26 13:16:39 -0400623 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400624 EXPECT_NE(0u, program);
625}
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400626
Jamie Madillfa05f602015-05-07 13:47:11 -0400627TEST_P(GLSLTest, InvariantVaryingOut)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400628{
Geoff Lange0cc2a42016-01-20 10:58:17 -0500629 // TODO(geofflang): Some OpenGL drivers have compile errors when varyings do not have matching
630 // invariant attributes (http://anglebug.com/1293)
631 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
632 {
633 std::cout << "Test disabled on OpenGL." << std::endl;
634 return;
635 }
636
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400637 const std::string fragmentShaderSource = SHADER_SOURCE
638 (
639 precision mediump float;
640 varying float v_varying;
641 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
642 );
643
644 const std::string vertexShaderSource = SHADER_SOURCE
645 (
646 attribute vec4 a_position;
647 invariant varying float v_varying;
648 void main() { v_varying = a_position.x; gl_Position = a_position; }
649 );
650
Jamie Madill5599c8f2014-08-26 13:16:39 -0400651 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400652 EXPECT_NE(0u, program);
653}
654
Jamie Madillfa05f602015-05-07 13:47:11 -0400655TEST_P(GLSLTest, FrontFacingAndVarying)
Jamie Madille6256f82014-09-17 10:31:15 -0400656{
Geoff Langdd323e92015-06-09 15:16:31 -0400657 EGLPlatformParameters platform = GetParam().eglParameters;
Austin Kinross8b695ee2015-03-12 13:12:20 -0700658
Jamie Madille6256f82014-09-17 10:31:15 -0400659 const std::string vertexShaderSource = SHADER_SOURCE
660 (
661 attribute vec4 a_position;
662 varying float v_varying;
663 void main()
664 {
665 v_varying = a_position.x;
666 gl_Position = a_position;
667 }
668 );
669
670 const std::string fragmentShaderSource = SHADER_SOURCE
671 (
672 precision mediump float;
673 varying float v_varying;
674 void main()
675 {
676 vec4 c;
677
678 if (gl_FrontFacing)
679 {
680 c = vec4(v_varying, 0, 0, 1.0);
681 }
682 else
683 {
684 c = vec4(0, v_varying, 0, 1.0);
685 }
686 gl_FragColor = c;
687 }
688 );
689
690 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Austin Kinross02df7962015-07-01 10:03:42 -0700691
692 // Compilation should fail on D3D11 feature level 9_3, since gl_FrontFacing isn't supported.
693 if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
694 {
695 if (platform.majorVersion == 9 && platform.minorVersion == 3)
696 {
697 EXPECT_EQ(0u, program);
698 return;
699 }
700 }
701
702 // Otherwise, compilation should succeed
Jamie Madille6256f82014-09-17 10:31:15 -0400703 EXPECT_NE(0u, program);
704}
705
Jamie Madillfa05f602015-05-07 13:47:11 -0400706TEST_P(GLSLTest, InvariantVaryingIn)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400707{
Geoff Lange0cc2a42016-01-20 10:58:17 -0500708 // TODO(geofflang): Some OpenGL drivers have compile errors when varyings do not have matching
709 // invariant attributes (http://anglebug.com/1293)
710 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
711 {
712 std::cout << "Test disabled on OpenGL." << std::endl;
713 return;
714 }
715
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400716 const std::string fragmentShaderSource = SHADER_SOURCE
717 (
718 precision mediump float;
719 invariant varying float v_varying;
720 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
721 );
722
723 const std::string vertexShaderSource = SHADER_SOURCE
724 (
725 attribute vec4 a_position;
726 varying float v_varying;
727 void main() { v_varying = a_position.x; gl_Position = a_position; }
728 );
729
Jamie Madill5599c8f2014-08-26 13:16:39 -0400730 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400731 EXPECT_NE(0u, program);
732}
733
Jamie Madillfa05f602015-05-07 13:47:11 -0400734TEST_P(GLSLTest, InvariantVaryingBoth)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400735{
736 const std::string fragmentShaderSource = SHADER_SOURCE
737 (
738 precision mediump float;
739 invariant varying float v_varying;
740 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
741 );
742
743 const std::string vertexShaderSource = SHADER_SOURCE
744 (
745 attribute vec4 a_position;
746 invariant varying float v_varying;
747 void main() { v_varying = a_position.x; gl_Position = a_position; }
748 );
749
Jamie Madill5599c8f2014-08-26 13:16:39 -0400750 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400751 EXPECT_NE(0u, program);
752}
753
Jamie Madillfa05f602015-05-07 13:47:11 -0400754TEST_P(GLSLTest, InvariantGLPosition)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400755{
756 const std::string fragmentShaderSource = SHADER_SOURCE
757 (
758 precision mediump float;
759 varying float v_varying;
760 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
761 );
762
763 const std::string vertexShaderSource = SHADER_SOURCE
764 (
765 attribute vec4 a_position;
766 invariant gl_Position;
767 varying float v_varying;
768 void main() { v_varying = a_position.x; gl_Position = a_position; }
769 );
770
Jamie Madill5599c8f2014-08-26 13:16:39 -0400771 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400772 EXPECT_NE(0u, program);
773}
774
Jamie Madillfa05f602015-05-07 13:47:11 -0400775TEST_P(GLSLTest, InvariantAll)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400776{
Geoff Lange0cc2a42016-01-20 10:58:17 -0500777 // TODO(geofflang): Some OpenGL drivers have compile errors when varyings do not have matching
778 // invariant attributes (http://anglebug.com/1293)
779 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
780 {
781 std::cout << "Test disabled on OpenGL." << std::endl;
782 return;
783 }
784
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400785 const std::string fragmentShaderSource = SHADER_SOURCE
786 (
787 precision mediump float;
788 varying float v_varying;
789 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
790 );
791
792 const std::string vertexShaderSource =
793 "#pragma STDGL invariant(all)\n"
794 "attribute vec4 a_position;\n"
795 "varying float v_varying;\n"
796 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
797
Jamie Madill5599c8f2014-08-26 13:16:39 -0400798 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400799 EXPECT_NE(0u, program);
800}
Austin Kinrossaf875522014-08-25 21:06:07 -0700801
Jamie Madillfa05f602015-05-07 13:47:11 -0400802TEST_P(GLSLTest, MaxVaryingVec4)
Austin Kinross8b695ee2015-03-12 13:12:20 -0700803{
Geoff Lang69accbd2016-01-25 16:22:32 -0500804#if defined(__APPLE__)
805 // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
806 // (http://anglebug.com/1291)
Jamie Madill7208f692016-02-29 10:47:35 -0500807 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lang69accbd2016-01-25 16:22:32 -0500808 {
809 std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
810 return;
811 }
812#endif
813
Austin Kinross8b695ee2015-03-12 13:12:20 -0700814 GLint maxVaryings = 0;
815 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
816
817 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, false, false, true);
818}
819
Jamie Madillfa05f602015-05-07 13:47:11 -0400820TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusTwoSpecialVariables)
Austin Kinross8b695ee2015-03-12 13:12:20 -0700821{
822 GLint maxVaryings = 0;
823 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
824
825 // Generate shader code that uses gl_FragCoord and gl_PointCoord, two special fragment shader variables.
826 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, false, true);
827}
828
Jamie Madillfa05f602015-05-07 13:47:11 -0400829TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusThreeSpecialVariables)
Austin Kinross8b695ee2015-03-12 13:12:20 -0700830{
Geoff Lange0cc2a42016-01-20 10:58:17 -0500831 // TODO(geofflang): Figure out why this fails on OpenGL AMD (http://anglebug.com/1291)
Jamie Madill7208f692016-02-29 10:47:35 -0500832 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lange0cc2a42016-01-20 10:58:17 -0500833 {
834 std::cout << "Test disabled on OpenGL." << std::endl;
835 return;
836 }
837
Austin Kinross8b695ee2015-03-12 13:12:20 -0700838 GLint maxVaryings = 0;
839 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
840
841 // Generate shader code that uses gl_FragCoord, gl_PointCoord and gl_PointSize.
842 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, true, true);
843}
844
Geoff Lange0cc2a42016-01-20 10:58:17 -0500845// Disabled because drivers are allowed to successfully compile shaders that have more than the
846// maximum number of varyings. (http://anglebug.com/1296)
847TEST_P(GLSLTest, DISABLED_MaxVaryingVec4PlusFragCoord)
Austin Kinross8b695ee2015-03-12 13:12:20 -0700848{
849 GLint maxVaryings = 0;
850 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
851
852 // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
853 // This test should fail, since we are really using (maxVaryings + 1) varyings.
854 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, true, false, false, false);
855}
856
Geoff Lange0cc2a42016-01-20 10:58:17 -0500857// Disabled because drivers are allowed to successfully compile shaders that have more than the
858// maximum number of varyings. (http://anglebug.com/1296)
859TEST_P(GLSLTest, DISABLED_MaxVaryingVec4PlusPointCoord)
Austin Kinross8b695ee2015-03-12 13:12:20 -0700860{
861 GLint maxVaryings = 0;
862 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
863
864 // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
865 // This test should fail, since we are really using (maxVaryings + 1) varyings.
866 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, true, false, false);
867}
868
Jamie Madillfa05f602015-05-07 13:47:11 -0400869TEST_P(GLSLTest, MaxVaryingVec3)
Austin Kinrossaf875522014-08-25 21:06:07 -0700870{
871 GLint maxVaryings = 0;
872 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
873
Austin Kinross8b695ee2015-03-12 13:12:20 -0700874 VaryingTestBase(0, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700875}
876
Jamie Madillfa05f602015-05-07 13:47:11 -0400877TEST_P(GLSLTest, MaxVaryingVec3Array)
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, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700883}
884
Jamie Madillbee59e02014-10-02 10:44:18 -0400885// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -0500886TEST_P(GLSLTest, MaxVaryingVec3AndOneFloat)
Austin Kinrossaf875522014-08-25 21:06:07 -0700887{
Jamie Madill7208f692016-02-29 10:47:35 -0500888 if (IsD3D9())
Jamie Madill9fc36822015-11-18 13:08:07 -0500889 {
890 std::cout << "Test disabled on D3D9." << std::endl;
891 return;
892 }
893
Austin Kinrossaf875522014-08-25 21:06:07 -0700894 GLint maxVaryings = 0;
895 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
896
Austin Kinross8b695ee2015-03-12 13:12:20 -0700897 VaryingTestBase(1, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700898}
899
Jamie Madillbee59e02014-10-02 10:44:18 -0400900// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -0500901TEST_P(GLSLTest, MaxVaryingVec3ArrayAndOneFloatArray)
Austin Kinrossaf875522014-08-25 21:06:07 -0700902{
Jamie Madill7208f692016-02-29 10:47:35 -0500903 if (IsD3D9())
Jamie Madill9fc36822015-11-18 13:08:07 -0500904 {
905 std::cout << "Test disabled on D3D9." << std::endl;
906 return;
907 }
908
Austin Kinrossaf875522014-08-25 21:06:07 -0700909 GLint maxVaryings = 0;
910 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
911
Austin Kinross8b695ee2015-03-12 13:12:20 -0700912 VaryingTestBase(0, 1, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700913}
914
Jamie Madillbee59e02014-10-02 10:44:18 -0400915// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -0500916TEST_P(GLSLTest, TwiceMaxVaryingVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -0700917{
Jamie Madill7208f692016-02-29 10:47:35 -0500918 if (IsD3D9())
Jamie Madill9fc36822015-11-18 13:08:07 -0500919 {
920 std::cout << "Test disabled on D3D9." << std::endl;
921 return;
922 }
923
Geoff Lange0cc2a42016-01-20 10:58:17 -0500924 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
925 {
926 // TODO(geofflang): Figure out why this fails on NVIDIA's GLES driver
927 std::cout << "Test disabled on OpenGL ES." << std::endl;
928 return;
929 }
930
Geoff Lang69accbd2016-01-25 16:22:32 -0500931#if defined(__APPLE__)
932 // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
933 // (http://anglebug.com/1291)
Jamie Madill7208f692016-02-29 10:47:35 -0500934 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lang69accbd2016-01-25 16:22:32 -0500935 {
936 std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
937 return;
938 }
939#endif
940
Austin Kinrossaf875522014-08-25 21:06:07 -0700941 GLint maxVaryings = 0;
942 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
943
Austin Kinross8b695ee2015-03-12 13:12:20 -0700944 VaryingTestBase(0, 0, 2 * maxVaryings, 0, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700945}
946
Jamie Madillbee59e02014-10-02 10:44:18 -0400947// Disabled because of a failure in D3D9
Jamie Madill9fc36822015-11-18 13:08:07 -0500948TEST_P(GLSLTest, MaxVaryingVec2Arrays)
Austin Kinrossaf875522014-08-25 21:06:07 -0700949{
Jamie Madill7208f692016-02-29 10:47:35 -0500950 if (IsD3DSM3())
Jamie Madill9fc36822015-11-18 13:08:07 -0500951 {
952 std::cout << "Test disabled on SM3." << std::endl;
953 return;
954 }
955
Geoff Lange0cc2a42016-01-20 10:58:17 -0500956 if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
957 {
958 // TODO(geofflang): Figure out why this fails on NVIDIA's GLES driver
959 std::cout << "Test disabled on OpenGL ES." << std::endl;
960 return;
961 }
962
Geoff Lang69accbd2016-01-25 16:22:32 -0500963#if defined(__APPLE__)
964 // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers
965 // (http://anglebug.com/1291)
Jamie Madill7208f692016-02-29 10:47:35 -0500966 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lang69accbd2016-01-25 16:22:32 -0500967 {
968 std::cout << "Test disabled on Apple AMD OpenGL." << std::endl;
969 return;
970 }
971#endif
972
Austin Kinrossaf875522014-08-25 21:06:07 -0700973 GLint maxVaryings = 0;
974 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
975
Austin Kinross8b695ee2015-03-12 13:12:20 -0700976 VaryingTestBase(0, 0, 0, maxVaryings, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700977}
978
Geoff Lange0cc2a42016-01-20 10:58:17 -0500979// Disabled because drivers are allowed to successfully compile shaders that have more than the
980// maximum number of varyings. (http://anglebug.com/1296)
981TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec3)
Austin Kinrossaf875522014-08-25 21:06:07 -0700982{
983 GLint maxVaryings = 0;
984 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
985
Austin Kinross8b695ee2015-03-12 13:12:20 -0700986 VaryingTestBase(0, 0, 0, 0, maxVaryings + 1, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700987}
988
Geoff Lange0cc2a42016-01-20 10:58:17 -0500989// Disabled because drivers are allowed to successfully compile shaders that have more than the
990// maximum number of varyings. (http://anglebug.com/1296)
991TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec3Array)
Austin Kinrossaf875522014-08-25 21:06:07 -0700992{
993 GLint maxVaryings = 0;
994 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
995
Austin Kinross8b695ee2015-03-12 13:12:20 -0700996 VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2 + 1, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700997}
998
Geoff Lange0cc2a42016-01-20 10:58:17 -0500999// Disabled because drivers are allowed to successfully compile shaders that have more than the
1000// maximum number of varyings. (http://anglebug.com/1296)
1001TEST_P(GLSLTest, DISABLED_MaxVaryingVec3AndOneVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -07001002{
1003 GLint maxVaryings = 0;
1004 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1005
Austin Kinross8b695ee2015-03-12 13:12:20 -07001006 VaryingTestBase(0, 0, 1, 0, maxVaryings, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001007}
1008
Geoff Lange0cc2a42016-01-20 10:58:17 -05001009// Disabled because drivers are allowed to successfully compile shaders that have more than the
1010// maximum number of varyings. (http://anglebug.com/1296)
1011TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -07001012{
1013 GLint maxVaryings = 0;
1014 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1015
Austin Kinross8b695ee2015-03-12 13:12:20 -07001016 VaryingTestBase(0, 0, 2 * maxVaryings + 1, 0, 0, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001017}
1018
Geoff Lange0cc2a42016-01-20 10:58:17 -05001019// Disabled because drivers are allowed to successfully compile shaders that have more than the
1020// maximum number of varyings. (http://anglebug.com/1296)
1021TEST_P(GLSLTest, DISABLED_MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
Austin Kinrossaf875522014-08-25 21:06:07 -07001022{
1023 GLint maxVaryings = 0;
1024 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
1025
Austin Kinross8b695ee2015-03-12 13:12:20 -07001026 VaryingTestBase(0, maxVaryings / 2 + 1, 0, 0, 0, 0, 0, maxVaryings / 2, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -07001027}
Geoff Langf60fab62014-11-24 11:21:20 -05001028
1029// Verify shader source with a fixed length that is less than the null-terminated length will compile.
Jamie Madillfa05f602015-05-07 13:47:11 -04001030TEST_P(GLSLTest, FixedShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -05001031{
1032 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1033
1034 const std::string appendGarbage = "abcasdfasdfasdfasdfasdf";
1035 const std::string source = "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" + appendGarbage;
1036 const char *sourceArray[1] = { source.c_str() };
Corentin Wallez973402f2015-05-11 13:42:22 -04001037 GLint lengths[1] = { static_cast<GLint>(source.length() - appendGarbage.length()) };
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001038 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001039 glCompileShader(shader);
1040
1041 GLint compileResult;
1042 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1043 EXPECT_NE(compileResult, 0);
1044}
1045
1046// Verify that a negative shader source length is treated as a null-terminated length.
Jamie Madillfa05f602015-05-07 13:47:11 -04001047TEST_P(GLSLTest, NegativeShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -05001048{
1049 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1050
1051 const char *sourceArray[1] = { "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" };
1052 GLint lengths[1] = { -10 };
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001053 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001054 glCompileShader(shader);
1055
1056 GLint compileResult;
1057 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1058 EXPECT_NE(compileResult, 0);
1059}
1060
1061// Verify that a length array with mixed positive and negative values compiles.
Jamie Madillfa05f602015-05-07 13:47:11 -04001062TEST_P(GLSLTest, MixedShaderLengths)
Geoff Langf60fab62014-11-24 11:21:20 -05001063{
1064 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1065
1066 const char *sourceArray[] =
1067 {
1068 "void main()",
1069 "{",
1070 " gl_FragColor = vec4(0, 0, 0, 0);",
1071 "}",
1072 };
1073 GLint lengths[] =
1074 {
1075 -10,
1076 1,
Corentin Wallez973402f2015-05-11 13:42:22 -04001077 static_cast<GLint>(strlen(sourceArray[2])),
Geoff Langf60fab62014-11-24 11:21:20 -05001078 -1,
1079 };
1080 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
1081
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001082 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001083 glCompileShader(shader);
1084
1085 GLint compileResult;
1086 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1087 EXPECT_NE(compileResult, 0);
1088}
1089
1090// Verify that zero-length shader source does not affect shader compilation.
Jamie Madillfa05f602015-05-07 13:47:11 -04001091TEST_P(GLSLTest, ZeroShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -05001092{
1093 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1094
1095 const char *sourceArray[] =
1096 {
1097 "adfasdf",
1098 "34534",
1099 "void main() { gl_FragColor = vec4(0, 0, 0, 0); }",
1100 "",
1101 "asdfasdfsdsdf",
1102 };
1103 GLint lengths[] =
1104 {
1105 0,
1106 0,
1107 -1,
1108 0,
1109 0,
1110 };
1111 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
1112
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001113 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -05001114 glCompileShader(shader);
1115
1116 GLint compileResult;
1117 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1118 EXPECT_NE(compileResult, 0);
1119}
Jamie Madill21c1e452014-12-29 11:33:41 -05001120
1121// Tests that bad index expressions don't crash ANGLE's translator.
1122// https://code.google.com/p/angleproject/issues/detail?id=857
Jamie Madillfa05f602015-05-07 13:47:11 -04001123TEST_P(GLSLTest, BadIndexBug)
Jamie Madill21c1e452014-12-29 11:33:41 -05001124{
1125 const std::string &fragmentShaderSourceVec =
1126 "precision mediump float;\n"
1127 "uniform vec4 uniformVec;\n"
1128 "void main()\n"
1129 "{\n"
1130 " gl_FragColor = vec4(uniformVec[int()]);\n"
1131 "}";
1132
1133 GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceVec);
1134 EXPECT_EQ(0u, shader);
1135
1136 if (shader != 0)
1137 {
1138 glDeleteShader(shader);
1139 }
1140
1141 const std::string &fragmentShaderSourceMat =
1142 "precision mediump float;\n"
1143 "uniform mat4 uniformMat;\n"
1144 "void main()\n"
1145 "{\n"
1146 " gl_FragColor = vec4(uniformMat[int()]);\n"
1147 "}";
1148
1149 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceMat);
1150 EXPECT_EQ(0u, shader);
1151
1152 if (shader != 0)
1153 {
1154 glDeleteShader(shader);
1155 }
1156
1157 const std::string &fragmentShaderSourceArray =
1158 "precision mediump float;\n"
1159 "uniform vec4 uniformArray;\n"
1160 "void main()\n"
1161 "{\n"
1162 " gl_FragColor = vec4(uniformArray[int()]);\n"
1163 "}";
1164
1165 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceArray);
1166 EXPECT_EQ(0u, shader);
1167
1168 if (shader != 0)
1169 {
1170 glDeleteShader(shader);
1171 }
Jamie Madill37997142015-01-28 10:06:34 -05001172}
1173
Jamie Madill2e295e22015-04-29 10:41:33 -04001174// Test that structs defined in uniforms are translated correctly.
Jamie Madillfa05f602015-05-07 13:47:11 -04001175TEST_P(GLSLTest, StructSpecifiersUniforms)
Jamie Madill2e295e22015-04-29 10:41:33 -04001176{
1177 const std::string fragmentShaderSource = SHADER_SOURCE
1178 (
1179 precision mediump float;
1180
1181 uniform struct S { float field;} s;
1182
1183 void main()
1184 {
1185 gl_FragColor = vec4(1, 0, 0, 1);
1186 gl_FragColor.a += s.field;
1187 }
1188 );
1189
1190 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1191 EXPECT_NE(0u, program);
1192}
Jamie Madill55def582015-05-04 11:24:57 -04001193
1194// Test that gl_DepthRange is not stored as a uniform location. Since uniforms
1195// beginning with "gl_" are filtered out by our validation logic, we must
1196// bypass the validation to test the behaviour of the implementation.
1197// (note this test is still Impl-independent)
Jamie Madillfa05f602015-05-07 13:47:11 -04001198TEST_P(GLSLTest, DepthRangeUniforms)
Jamie Madill55def582015-05-04 11:24:57 -04001199{
1200 const std::string fragmentShaderSource = SHADER_SOURCE
1201 (
1202 precision mediump float;
1203
1204 void main()
1205 {
1206 gl_FragColor = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff, 1);
1207 }
1208 );
1209
1210 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1211 EXPECT_NE(0u, program);
1212
1213 // dive into the ANGLE internals, so we can bypass validation.
1214 gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
1215 gl::Program *glProgram = context->getProgram(program);
1216 GLint nearIndex = glProgram->getUniformLocation("gl_DepthRange.near");
1217 EXPECT_EQ(-1, nearIndex);
1218
1219 // Test drawing does not throw an exception.
1220 drawQuad(program, "inputAttribute", 0.5f);
1221
1222 EXPECT_GL_NO_ERROR();
1223
1224 glDeleteProgram(program);
1225}
Jamie Madill4052dfc2015-05-06 15:18:49 -04001226
1227// Covers the WebGL test 'glsl/bugs/pow-of-small-constant-in-user-defined-function'
1228// See https://code.google.com/p/angleproject/issues/detail?id=851
1229// TODO(jmadill): ANGLE constant folding can fix this
Jamie Madillfa05f602015-05-07 13:47:11 -04001230TEST_P(GLSLTest, DISABLED_PowOfSmallConstant)
Jamie Madill4052dfc2015-05-06 15:18:49 -04001231{
1232 const std::string &fragmentShaderSource = SHADER_SOURCE
1233 (
1234 precision highp float;
1235
1236 float fun(float arg)
1237 {
1238 // These values are still easily within the highp range.
1239 // The minimum range in terms of 10's exponent is around -19 to 19, and IEEE-754 single precision range is higher than that.
1240 return pow(arg, 2.0);
1241 }
1242
1243 void main()
1244 {
1245 // Note that the bug did not reproduce if an uniform was passed to the function instead of a constant,
1246 // or if the expression was moved outside the user-defined function.
1247 const float a = 1.0e-6;
1248 float b = 1.0e12 * fun(a);
1249 if (abs(b - 1.0) < 0.01)
1250 {
1251 gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); // green
1252 }
1253 else
1254 {
1255 gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // red
1256 }
1257 }
1258 );
1259
1260 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1261 EXPECT_NE(0u, program);
1262
1263 drawQuad(program, "inputAttribute", 0.5f);
1264 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1265 EXPECT_GL_NO_ERROR();
1266}
Jamie Madillfa05f602015-05-07 13:47:11 -04001267
Cooper Partina5ef8d82015-08-19 14:52:21 -07001268// Test that fragment shaders which contain non-constant loop indexers and compiled for FL9_3 and
1269// below
1270// fail with a specific error message.
1271// Additionally test that the same fragment shader compiles successfully with feature levels greater
1272// than FL9_3.
1273TEST_P(GLSLTest, LoopIndexingValidation)
1274{
1275 const std::string fragmentShaderSource = SHADER_SOURCE
1276 (
1277 precision mediump float;
1278
1279 uniform float loopMax;
1280
1281 void main()
1282 {
1283 gl_FragColor = vec4(1, 0, 0, 1);
1284 for (float l = 0.0; l < loopMax; l++)
1285 {
1286 if (loopMax > 3.0)
1287 {
1288 gl_FragColor.a += 0.1;
1289 }
1290 }
1291 }
1292 );
1293
1294 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1295
1296 const char *sourceArray[1] = {fragmentShaderSource.c_str()};
1297 glShaderSource(shader, 1, sourceArray, nullptr);
1298 glCompileShader(shader);
1299
1300 GLint compileResult;
1301 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1302
1303 // If the test is configured to run limited to Feature Level 9_3, then it is
1304 // assumed that shader compilation will fail with an expected error message containing
1305 // "Loop index cannot be compared with non-constant expression"
Olli Etuaho814a54d2015-08-27 16:23:09 +03001306 if ((GetParam() == ES2_D3D11_FL9_3() || GetParam() == ES2_D3D9()))
Cooper Partina5ef8d82015-08-19 14:52:21 -07001307 {
1308 if (compileResult != 0)
1309 {
1310 FAIL() << "Shader compilation succeeded, expected failure";
1311 }
1312 else
1313 {
1314 GLint infoLogLength;
1315 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
1316
1317 std::string infoLog;
1318 infoLog.resize(infoLogLength);
1319 glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
1320
1321 if (infoLog.find("Loop index cannot be compared with non-constant expression") ==
1322 std::string::npos)
1323 {
1324 FAIL() << "Shader compilation failed with unexpected error message";
1325 }
1326 }
1327 }
1328 else
1329 {
1330 EXPECT_NE(0, compileResult);
1331 }
1332
1333 if (shader != 0)
1334 {
1335 glDeleteShader(shader);
1336 }
1337}
1338
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001339// Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1340// can actually be used.
1341TEST_P(GLSLTest, VerifyMaxVertexUniformVectors)
1342{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001343 int maxUniforms = 10000;
1344 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1345 EXPECT_GL_NO_ERROR();
1346 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl;
1347
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001348 CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, 0, 0, true);
1349}
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001350
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001351// Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1352// can actually be used along with the maximum number of texture samplers.
1353TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsWithSamplers)
1354{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001355 if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1356 GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1357 {
1358 std::cout << "Test disabled on OpenGL." << std::endl;
1359 return;
1360 }
1361
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001362 int maxUniforms = 10000;
1363 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1364 EXPECT_GL_NO_ERROR();
1365 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001366
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001367 int maxTextureImageUnits = 0;
1368 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001369
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001370 CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, maxTextureImageUnits, 0, true);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001371}
1372
1373// Tests that the maximum uniforms count + 1 from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1374// fails shader compilation.
1375TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsExceeded)
1376{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001377 int maxUniforms = 10000;
1378 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1379 EXPECT_GL_NO_ERROR();
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001380 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS + 1 = " << maxUniforms + 1 << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001381
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001382 CompileGLSLWithUniformsAndSamplers(maxUniforms + 1, 0, 0, 0, false);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001383}
1384
1385// Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1386// can actually be used.
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001387TEST_P(GLSLTest, VerifyMaxFragmentUniformVectors)
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001388{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001389 int maxUniforms = 10000;
1390 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1391 EXPECT_GL_NO_ERROR();
1392 std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS = " << maxUniforms << std::endl;
1393
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001394 CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, 0, true);
1395}
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001396
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001397// Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1398// can actually be used along with the maximum number of texture samplers.
1399TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsWithSamplers)
1400{
Geoff Lange0cc2a42016-01-20 10:58:17 -05001401 if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE ||
1402 GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
1403 {
1404 std::cout << "Test disabled on OpenGL." << std::endl;
1405 return;
1406 }
1407
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001408 int maxUniforms = 10000;
1409 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1410 EXPECT_GL_NO_ERROR();
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001411
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001412 int maxTextureImageUnits = 0;
1413 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001414
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001415 CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, maxTextureImageUnits, true);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001416}
1417
1418// Tests that the maximum uniforms count + 1 from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1419// fails shader compilation.
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001420TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsExceeded)
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001421{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001422 int maxUniforms = 10000;
1423 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1424 EXPECT_GL_NO_ERROR();
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001425 std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS + 1 = " << maxUniforms + 1
1426 << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001427
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001428 CompileGLSLWithUniformsAndSamplers(0, maxUniforms + 1, 0, 0, false);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001429}
1430
Jamie Madillfa05f602015-05-07 13:47:11 -04001431// 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 -05001432ANGLE_INSTANTIATE_TEST(GLSLTest,
1433 ES2_D3D9(),
1434 ES2_D3D11(),
1435 ES2_D3D11_FL9_3(),
1436 ES2_OPENGL(),
1437 ES3_OPENGL(),
1438 ES2_OPENGLES(),
1439 ES3_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -04001440
1441// 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 -05001442ANGLE_INSTANTIATE_TEST(GLSLTest_ES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());