blob: c19b87304c44eaee5a114ceb3757d3a11c2bd42c [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{
465 const std::string fragmentShaderSource = SHADER_SOURCE
466 (
467 precision mediump float;
468
469 struct T
470 {
471 float f;
472 };
473
474 void main()
475 {
476 T a;
477
478 struct T
479 {
480 float q;
481 };
482
483 T b;
484
485 gl_FragColor = vec4(1, 0, 0, 1);
486 gl_FragColor.a += a.f;
487 gl_FragColor.a += b.q;
488 }
489 );
490
Jamie Madill5599c8f2014-08-26 13:16:39 -0400491 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madillbfa91f42014-06-05 15:45:18 -0400492 EXPECT_NE(0u, program);
493}
494
Jamie Madillfa05f602015-05-07 13:47:11 -0400495TEST_P(GLSLTest, ScopedStructsBug)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400496{
Jamie Madill96509e42014-05-29 14:33:27 -0400497 const std::string fragmentShaderSource = SHADER_SOURCE
498 (
499 precision mediump float;
500
501 struct T_0
502 {
503 float f;
504 };
505
506 void main()
507 {
508 gl_FragColor = vec4(1, 0, 0, 1);
509
510 struct T
511 {
512 vec2 v;
513 };
514
515 T_0 a;
516 T b;
517
518 gl_FragColor.a += a.f;
519 gl_FragColor.a += b.v.x;
520 }
521 );
522
Jamie Madill5599c8f2014-08-26 13:16:39 -0400523 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madill2bf8b372014-06-16 17:18:51 -0400524 EXPECT_NE(0u, program);
525}
526
Jamie Madillfa05f602015-05-07 13:47:11 -0400527TEST_P(GLSLTest, DxPositionBug)
Jamie Madill2bf8b372014-06-16 17:18:51 -0400528{
529 const std::string &vertexShaderSource = SHADER_SOURCE
530 (
531 attribute vec4 inputAttribute;
532 varying float dx_Position;
533 void main()
534 {
535 gl_Position = vec4(inputAttribute);
536 dx_Position = 0.0;
537 }
538 );
539
540 const std::string &fragmentShaderSource = SHADER_SOURCE
541 (
542 precision mediump float;
543
544 varying float dx_Position;
545
546 void main()
547 {
548 gl_FragColor = vec4(dx_Position, 0, 0, 1);
549 }
550 );
551
Jamie Madill5599c8f2014-08-26 13:16:39 -0400552 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill96509e42014-05-29 14:33:27 -0400553 EXPECT_NE(0u, program);
554}
Jamie Madill4836d222014-07-24 06:55:51 -0400555
Jamie Madillfa05f602015-05-07 13:47:11 -0400556TEST_P(GLSLTest, ElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400557{
558 const std::string &vertexShaderSource =
559 "attribute vec4 a_position;\n"
560 "varying float v;\n"
561 "void main() {\n"
562 " gl_Position = a_position;\n"
563 " v = 1.0;\n"
564 " if (a_position.x <= 0.5) {\n"
565 " v = 0.0;\n"
566 " } else if (a_position.x >= 0.5) {\n"
567 " v = 2.0;\n"
568 " }\n"
569 "}\n";
570
571 const std::string &fragmentShaderSource =
572 "precision highp float;\n"
573 "varying float v;\n"
574 "void main() {\n"
575 " vec4 color = vec4(1.0, 0.0, 0.0, 1.0);\n"
576 " if (v >= 1.0) color = vec4(0.0, 1.0, 0.0, 1.0);\n"
577 " if (v >= 2.0) color = vec4(0.0, 0.0, 1.0, 1.0);\n"
578 " gl_FragColor = color;\n"
579 "}\n";
580
Jamie Madill5599c8f2014-08-26 13:16:39 -0400581 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400582 ASSERT_NE(0u, program);
583
584 drawQuad(program, "a_position", 0.5f);
Jamie Madill4836d222014-07-24 06:55:51 -0400585
586 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
587 EXPECT_PIXEL_EQ(getWindowWidth()-1, 0, 0, 255, 0, 255);
588}
589
Jamie Madillfa05f602015-05-07 13:47:11 -0400590TEST_P(GLSLTest, TwoElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400591{
592 const std::string &vertexShaderSource =
593 "attribute vec4 a_position;\n"
594 "varying float v;\n"
595 "void main() {\n"
596 " gl_Position = a_position;\n"
Jamie Madill778d5272014-08-04 13:13:25 -0400597 " if (a_position.x == 0.0) {\n"
Jamie Madill4836d222014-07-24 06:55:51 -0400598 " v = 1.0;\n"
599 " } else if (a_position.x > 0.5) {\n"
600 " v = 0.0;\n"
601 " } else if (a_position.x > 0.75) {\n"
602 " v = 0.5;\n"
603 " }\n"
604 "}\n";
605
606 const std::string &fragmentShaderSource =
607 "precision highp float;\n"
608 "varying float v;\n"
609 "void main() {\n"
610 " gl_FragColor = vec4(v, 0.0, 0.0, 1.0);\n"
611 "}\n";
612
Jamie Madill5599c8f2014-08-26 13:16:39 -0400613 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400614 EXPECT_NE(0u, program);
615}
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400616
Jamie Madillfa05f602015-05-07 13:47:11 -0400617TEST_P(GLSLTest, InvariantVaryingOut)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400618{
619 const std::string fragmentShaderSource = SHADER_SOURCE
620 (
621 precision mediump float;
622 varying float v_varying;
623 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
624 );
625
626 const std::string vertexShaderSource = SHADER_SOURCE
627 (
628 attribute vec4 a_position;
629 invariant varying float v_varying;
630 void main() { v_varying = a_position.x; gl_Position = a_position; }
631 );
632
Jamie Madill5599c8f2014-08-26 13:16:39 -0400633 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400634 EXPECT_NE(0u, program);
635}
636
Jamie Madillfa05f602015-05-07 13:47:11 -0400637TEST_P(GLSLTest, FrontFacingAndVarying)
Jamie Madille6256f82014-09-17 10:31:15 -0400638{
Geoff Langdd323e92015-06-09 15:16:31 -0400639 EGLPlatformParameters platform = GetParam().eglParameters;
Austin Kinross8b695ee2015-03-12 13:12:20 -0700640
Jamie Madille6256f82014-09-17 10:31:15 -0400641 const std::string vertexShaderSource = SHADER_SOURCE
642 (
643 attribute vec4 a_position;
644 varying float v_varying;
645 void main()
646 {
647 v_varying = a_position.x;
648 gl_Position = a_position;
649 }
650 );
651
652 const std::string fragmentShaderSource = SHADER_SOURCE
653 (
654 precision mediump float;
655 varying float v_varying;
656 void main()
657 {
658 vec4 c;
659
660 if (gl_FrontFacing)
661 {
662 c = vec4(v_varying, 0, 0, 1.0);
663 }
664 else
665 {
666 c = vec4(0, v_varying, 0, 1.0);
667 }
668 gl_FragColor = c;
669 }
670 );
671
672 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Austin Kinross02df7962015-07-01 10:03:42 -0700673
674 // Compilation should fail on D3D11 feature level 9_3, since gl_FrontFacing isn't supported.
675 if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
676 {
677 if (platform.majorVersion == 9 && platform.minorVersion == 3)
678 {
679 EXPECT_EQ(0u, program);
680 return;
681 }
682 }
683
684 // Otherwise, compilation should succeed
Jamie Madille6256f82014-09-17 10:31:15 -0400685 EXPECT_NE(0u, program);
686}
687
Jamie Madillfa05f602015-05-07 13:47:11 -0400688TEST_P(GLSLTest, InvariantVaryingIn)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400689{
690 const std::string fragmentShaderSource = SHADER_SOURCE
691 (
692 precision mediump float;
693 invariant varying float v_varying;
694 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
695 );
696
697 const std::string vertexShaderSource = SHADER_SOURCE
698 (
699 attribute vec4 a_position;
700 varying float v_varying;
701 void main() { v_varying = a_position.x; gl_Position = a_position; }
702 );
703
Jamie Madill5599c8f2014-08-26 13:16:39 -0400704 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400705 EXPECT_NE(0u, program);
706}
707
Jamie Madillfa05f602015-05-07 13:47:11 -0400708TEST_P(GLSLTest, InvariantVaryingBoth)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400709{
710 const std::string fragmentShaderSource = SHADER_SOURCE
711 (
712 precision mediump float;
713 invariant varying float v_varying;
714 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
715 );
716
717 const std::string vertexShaderSource = SHADER_SOURCE
718 (
719 attribute vec4 a_position;
720 invariant varying float v_varying;
721 void main() { v_varying = a_position.x; gl_Position = a_position; }
722 );
723
Jamie Madill5599c8f2014-08-26 13:16:39 -0400724 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400725 EXPECT_NE(0u, program);
726}
727
Jamie Madillfa05f602015-05-07 13:47:11 -0400728TEST_P(GLSLTest, InvariantGLPosition)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400729{
730 const std::string fragmentShaderSource = SHADER_SOURCE
731 (
732 precision mediump float;
733 varying float v_varying;
734 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
735 );
736
737 const std::string vertexShaderSource = SHADER_SOURCE
738 (
739 attribute vec4 a_position;
740 invariant gl_Position;
741 varying float v_varying;
742 void main() { v_varying = a_position.x; gl_Position = a_position; }
743 );
744
Jamie Madill5599c8f2014-08-26 13:16:39 -0400745 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400746 EXPECT_NE(0u, program);
747}
748
Jamie Madillfa05f602015-05-07 13:47:11 -0400749TEST_P(GLSLTest, InvariantAll)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400750{
751 const std::string fragmentShaderSource = SHADER_SOURCE
752 (
753 precision mediump float;
754 varying float v_varying;
755 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
756 );
757
758 const std::string vertexShaderSource =
759 "#pragma STDGL invariant(all)\n"
760 "attribute vec4 a_position;\n"
761 "varying float v_varying;\n"
762 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
763
Jamie Madill5599c8f2014-08-26 13:16:39 -0400764 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400765 EXPECT_NE(0u, program);
766}
Austin Kinrossaf875522014-08-25 21:06:07 -0700767
Jamie Madillfa05f602015-05-07 13:47:11 -0400768TEST_P(GLSLTest, MaxVaryingVec4)
Austin Kinross8b695ee2015-03-12 13:12:20 -0700769{
770 GLint maxVaryings = 0;
771 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
772
773 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, false, false, true);
774}
775
Jamie Madillfa05f602015-05-07 13:47:11 -0400776TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusTwoSpecialVariables)
Austin Kinross8b695ee2015-03-12 13:12:20 -0700777{
778 GLint maxVaryings = 0;
779 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
780
781 // Generate shader code that uses gl_FragCoord and gl_PointCoord, two special fragment shader variables.
782 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, false, true);
783}
784
Jamie Madillfa05f602015-05-07 13:47:11 -0400785TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusThreeSpecialVariables)
Austin Kinross8b695ee2015-03-12 13:12:20 -0700786{
787 GLint maxVaryings = 0;
788 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
789
790 // Generate shader code that uses gl_FragCoord, gl_PointCoord and gl_PointSize.
791 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, true, true);
792}
793
Jamie Madillfa05f602015-05-07 13:47:11 -0400794TEST_P(GLSLTest, MaxVaryingVec4PlusFragCoord)
Austin Kinross8b695ee2015-03-12 13:12:20 -0700795{
796 GLint maxVaryings = 0;
797 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
798
799 // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
800 // This test should fail, since we are really using (maxVaryings + 1) varyings.
801 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, true, false, false, false);
802}
803
Jamie Madillfa05f602015-05-07 13:47:11 -0400804TEST_P(GLSLTest, MaxVaryingVec4PlusPointCoord)
Austin Kinross8b695ee2015-03-12 13:12:20 -0700805{
806 GLint maxVaryings = 0;
807 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
808
809 // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
810 // This test should fail, since we are really using (maxVaryings + 1) varyings.
811 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, true, false, false);
812}
813
Jamie Madillfa05f602015-05-07 13:47:11 -0400814TEST_P(GLSLTest, MaxVaryingVec3)
Austin Kinrossaf875522014-08-25 21:06:07 -0700815{
816 GLint maxVaryings = 0;
817 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
818
Austin Kinross8b695ee2015-03-12 13:12:20 -0700819 VaryingTestBase(0, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700820}
821
Jamie Madillfa05f602015-05-07 13:47:11 -0400822TEST_P(GLSLTest, MaxVaryingVec3Array)
Austin Kinrossaf875522014-08-25 21:06:07 -0700823{
824 GLint maxVaryings = 0;
825 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
826
Austin Kinross8b695ee2015-03-12 13:12:20 -0700827 VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700828}
829
Jamie Madillbee59e02014-10-02 10:44:18 -0400830// Disabled because of a failure in D3D9
Jamie Madillfa05f602015-05-07 13:47:11 -0400831TEST_P(GLSLTest, DISABLED_MaxVaryingVec3AndOneFloat)
Austin Kinrossaf875522014-08-25 21:06:07 -0700832{
833 GLint maxVaryings = 0;
834 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
835
Austin Kinross8b695ee2015-03-12 13:12:20 -0700836 VaryingTestBase(1, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700837}
838
Jamie Madillbee59e02014-10-02 10:44:18 -0400839// Disabled because of a failure in D3D9
Jamie Madillfa05f602015-05-07 13:47:11 -0400840TEST_P(GLSLTest, DISABLED_MaxVaryingVec3ArrayAndOneFloatArray)
Austin Kinrossaf875522014-08-25 21:06:07 -0700841{
842 GLint maxVaryings = 0;
843 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
844
Austin Kinross8b695ee2015-03-12 13:12:20 -0700845 VaryingTestBase(0, 1, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700846}
847
Jamie Madillbee59e02014-10-02 10:44:18 -0400848// Disabled because of a failure in D3D9
Jamie Madillfa05f602015-05-07 13:47:11 -0400849TEST_P(GLSLTest, DISABLED_TwiceMaxVaryingVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -0700850{
851 GLint maxVaryings = 0;
852 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
853
Austin Kinross8b695ee2015-03-12 13:12:20 -0700854 VaryingTestBase(0, 0, 2 * maxVaryings, 0, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700855}
856
Jamie Madillbee59e02014-10-02 10:44:18 -0400857// Disabled because of a failure in D3D9
Jamie Madillfa05f602015-05-07 13:47:11 -0400858TEST_P(GLSLTest, DISABLED_MaxVaryingVec2Arrays)
Austin Kinrossaf875522014-08-25 21:06:07 -0700859{
860 GLint maxVaryings = 0;
861 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
862
Austin Kinross8b695ee2015-03-12 13:12:20 -0700863 VaryingTestBase(0, 0, 0, maxVaryings, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700864}
865
Jamie Madillfa05f602015-05-07 13:47:11 -0400866TEST_P(GLSLTest, MaxPlusOneVaryingVec3)
Austin Kinrossaf875522014-08-25 21:06:07 -0700867{
868 GLint maxVaryings = 0;
869 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
870
Austin Kinross8b695ee2015-03-12 13:12:20 -0700871 VaryingTestBase(0, 0, 0, 0, maxVaryings + 1, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700872}
873
Jamie Madillfa05f602015-05-07 13:47:11 -0400874TEST_P(GLSLTest, MaxPlusOneVaryingVec3Array)
Austin Kinrossaf875522014-08-25 21:06:07 -0700875{
876 GLint maxVaryings = 0;
877 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
878
Austin Kinross8b695ee2015-03-12 13:12:20 -0700879 VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2 + 1, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700880}
881
Jamie Madillfa05f602015-05-07 13:47:11 -0400882TEST_P(GLSLTest, MaxVaryingVec3AndOneVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -0700883{
884 GLint maxVaryings = 0;
885 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
886
Austin Kinross8b695ee2015-03-12 13:12:20 -0700887 VaryingTestBase(0, 0, 1, 0, maxVaryings, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700888}
889
Jamie Madillfa05f602015-05-07 13:47:11 -0400890TEST_P(GLSLTest, MaxPlusOneVaryingVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -0700891{
892 GLint maxVaryings = 0;
893 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
894
Austin Kinross8b695ee2015-03-12 13:12:20 -0700895 VaryingTestBase(0, 0, 2 * maxVaryings + 1, 0, 0, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700896}
897
Jamie Madillfa05f602015-05-07 13:47:11 -0400898TEST_P(GLSLTest, MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
Austin Kinrossaf875522014-08-25 21:06:07 -0700899{
900 GLint maxVaryings = 0;
901 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
902
Austin Kinross8b695ee2015-03-12 13:12:20 -0700903 VaryingTestBase(0, maxVaryings / 2 + 1, 0, 0, 0, 0, 0, maxVaryings / 2, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700904}
Geoff Langf60fab62014-11-24 11:21:20 -0500905
906// Verify shader source with a fixed length that is less than the null-terminated length will compile.
Jamie Madillfa05f602015-05-07 13:47:11 -0400907TEST_P(GLSLTest, FixedShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -0500908{
909 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
910
911 const std::string appendGarbage = "abcasdfasdfasdfasdfasdf";
912 const std::string source = "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" + appendGarbage;
913 const char *sourceArray[1] = { source.c_str() };
Corentin Wallez973402f2015-05-11 13:42:22 -0400914 GLint lengths[1] = { static_cast<GLint>(source.length() - appendGarbage.length()) };
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700915 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -0500916 glCompileShader(shader);
917
918 GLint compileResult;
919 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
920 EXPECT_NE(compileResult, 0);
921}
922
923// Verify that a negative shader source length is treated as a null-terminated length.
Jamie Madillfa05f602015-05-07 13:47:11 -0400924TEST_P(GLSLTest, NegativeShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -0500925{
926 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
927
928 const char *sourceArray[1] = { "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" };
929 GLint lengths[1] = { -10 };
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700930 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -0500931 glCompileShader(shader);
932
933 GLint compileResult;
934 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
935 EXPECT_NE(compileResult, 0);
936}
937
938// Verify that a length array with mixed positive and negative values compiles.
Jamie Madillfa05f602015-05-07 13:47:11 -0400939TEST_P(GLSLTest, MixedShaderLengths)
Geoff Langf60fab62014-11-24 11:21:20 -0500940{
941 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
942
943 const char *sourceArray[] =
944 {
945 "void main()",
946 "{",
947 " gl_FragColor = vec4(0, 0, 0, 0);",
948 "}",
949 };
950 GLint lengths[] =
951 {
952 -10,
953 1,
Corentin Wallez973402f2015-05-11 13:42:22 -0400954 static_cast<GLint>(strlen(sourceArray[2])),
Geoff Langf60fab62014-11-24 11:21:20 -0500955 -1,
956 };
957 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
958
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700959 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -0500960 glCompileShader(shader);
961
962 GLint compileResult;
963 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
964 EXPECT_NE(compileResult, 0);
965}
966
967// Verify that zero-length shader source does not affect shader compilation.
Jamie Madillfa05f602015-05-07 13:47:11 -0400968TEST_P(GLSLTest, ZeroShaderLength)
Geoff Langf60fab62014-11-24 11:21:20 -0500969{
970 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
971
972 const char *sourceArray[] =
973 {
974 "adfasdf",
975 "34534",
976 "void main() { gl_FragColor = vec4(0, 0, 0, 0); }",
977 "",
978 "asdfasdfsdsdf",
979 };
980 GLint lengths[] =
981 {
982 0,
983 0,
984 -1,
985 0,
986 0,
987 };
988 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
989
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700990 glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths);
Geoff Langf60fab62014-11-24 11:21:20 -0500991 glCompileShader(shader);
992
993 GLint compileResult;
994 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
995 EXPECT_NE(compileResult, 0);
996}
Jamie Madill21c1e452014-12-29 11:33:41 -0500997
998// Tests that bad index expressions don't crash ANGLE's translator.
999// https://code.google.com/p/angleproject/issues/detail?id=857
Jamie Madillfa05f602015-05-07 13:47:11 -04001000TEST_P(GLSLTest, BadIndexBug)
Jamie Madill21c1e452014-12-29 11:33:41 -05001001{
1002 const std::string &fragmentShaderSourceVec =
1003 "precision mediump float;\n"
1004 "uniform vec4 uniformVec;\n"
1005 "void main()\n"
1006 "{\n"
1007 " gl_FragColor = vec4(uniformVec[int()]);\n"
1008 "}";
1009
1010 GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceVec);
1011 EXPECT_EQ(0u, shader);
1012
1013 if (shader != 0)
1014 {
1015 glDeleteShader(shader);
1016 }
1017
1018 const std::string &fragmentShaderSourceMat =
1019 "precision mediump float;\n"
1020 "uniform mat4 uniformMat;\n"
1021 "void main()\n"
1022 "{\n"
1023 " gl_FragColor = vec4(uniformMat[int()]);\n"
1024 "}";
1025
1026 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceMat);
1027 EXPECT_EQ(0u, shader);
1028
1029 if (shader != 0)
1030 {
1031 glDeleteShader(shader);
1032 }
1033
1034 const std::string &fragmentShaderSourceArray =
1035 "precision mediump float;\n"
1036 "uniform vec4 uniformArray;\n"
1037 "void main()\n"
1038 "{\n"
1039 " gl_FragColor = vec4(uniformArray[int()]);\n"
1040 "}";
1041
1042 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceArray);
1043 EXPECT_EQ(0u, shader);
1044
1045 if (shader != 0)
1046 {
1047 glDeleteShader(shader);
1048 }
Jamie Madill37997142015-01-28 10:06:34 -05001049}
1050
Jamie Madill2e295e22015-04-29 10:41:33 -04001051// Test that structs defined in uniforms are translated correctly.
Jamie Madillfa05f602015-05-07 13:47:11 -04001052TEST_P(GLSLTest, StructSpecifiersUniforms)
Jamie Madill2e295e22015-04-29 10:41:33 -04001053{
1054 const std::string fragmentShaderSource = SHADER_SOURCE
1055 (
1056 precision mediump float;
1057
1058 uniform struct S { float field;} s;
1059
1060 void main()
1061 {
1062 gl_FragColor = vec4(1, 0, 0, 1);
1063 gl_FragColor.a += s.field;
1064 }
1065 );
1066
1067 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1068 EXPECT_NE(0u, program);
1069}
Jamie Madill55def582015-05-04 11:24:57 -04001070
1071// Test that gl_DepthRange is not stored as a uniform location. Since uniforms
1072// beginning with "gl_" are filtered out by our validation logic, we must
1073// bypass the validation to test the behaviour of the implementation.
1074// (note this test is still Impl-independent)
Jamie Madillfa05f602015-05-07 13:47:11 -04001075TEST_P(GLSLTest, DepthRangeUniforms)
Jamie Madill55def582015-05-04 11:24:57 -04001076{
1077 const std::string fragmentShaderSource = SHADER_SOURCE
1078 (
1079 precision mediump float;
1080
1081 void main()
1082 {
1083 gl_FragColor = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff, 1);
1084 }
1085 );
1086
1087 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1088 EXPECT_NE(0u, program);
1089
1090 // dive into the ANGLE internals, so we can bypass validation.
1091 gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
1092 gl::Program *glProgram = context->getProgram(program);
1093 GLint nearIndex = glProgram->getUniformLocation("gl_DepthRange.near");
1094 EXPECT_EQ(-1, nearIndex);
1095
1096 // Test drawing does not throw an exception.
1097 drawQuad(program, "inputAttribute", 0.5f);
1098
1099 EXPECT_GL_NO_ERROR();
1100
1101 glDeleteProgram(program);
1102}
Jamie Madill4052dfc2015-05-06 15:18:49 -04001103
1104// Covers the WebGL test 'glsl/bugs/pow-of-small-constant-in-user-defined-function'
1105// See https://code.google.com/p/angleproject/issues/detail?id=851
1106// TODO(jmadill): ANGLE constant folding can fix this
Jamie Madillfa05f602015-05-07 13:47:11 -04001107TEST_P(GLSLTest, DISABLED_PowOfSmallConstant)
Jamie Madill4052dfc2015-05-06 15:18:49 -04001108{
1109 const std::string &fragmentShaderSource = SHADER_SOURCE
1110 (
1111 precision highp float;
1112
1113 float fun(float arg)
1114 {
1115 // These values are still easily within the highp range.
1116 // The minimum range in terms of 10's exponent is around -19 to 19, and IEEE-754 single precision range is higher than that.
1117 return pow(arg, 2.0);
1118 }
1119
1120 void main()
1121 {
1122 // Note that the bug did not reproduce if an uniform was passed to the function instead of a constant,
1123 // or if the expression was moved outside the user-defined function.
1124 const float a = 1.0e-6;
1125 float b = 1.0e12 * fun(a);
1126 if (abs(b - 1.0) < 0.01)
1127 {
1128 gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); // green
1129 }
1130 else
1131 {
1132 gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // red
1133 }
1134 }
1135 );
1136
1137 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1138 EXPECT_NE(0u, program);
1139
1140 drawQuad(program, "inputAttribute", 0.5f);
1141 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
1142 EXPECT_GL_NO_ERROR();
1143}
Jamie Madillfa05f602015-05-07 13:47:11 -04001144
Cooper Partina5ef8d82015-08-19 14:52:21 -07001145// Test that fragment shaders which contain non-constant loop indexers and compiled for FL9_3 and
1146// below
1147// fail with a specific error message.
1148// Additionally test that the same fragment shader compiles successfully with feature levels greater
1149// than FL9_3.
1150TEST_P(GLSLTest, LoopIndexingValidation)
1151{
1152 const std::string fragmentShaderSource = SHADER_SOURCE
1153 (
1154 precision mediump float;
1155
1156 uniform float loopMax;
1157
1158 void main()
1159 {
1160 gl_FragColor = vec4(1, 0, 0, 1);
1161 for (float l = 0.0; l < loopMax; l++)
1162 {
1163 if (loopMax > 3.0)
1164 {
1165 gl_FragColor.a += 0.1;
1166 }
1167 }
1168 }
1169 );
1170
1171 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
1172
1173 const char *sourceArray[1] = {fragmentShaderSource.c_str()};
1174 glShaderSource(shader, 1, sourceArray, nullptr);
1175 glCompileShader(shader);
1176
1177 GLint compileResult;
1178 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
1179
1180 // If the test is configured to run limited to Feature Level 9_3, then it is
1181 // assumed that shader compilation will fail with an expected error message containing
1182 // "Loop index cannot be compared with non-constant expression"
Olli Etuaho814a54d2015-08-27 16:23:09 +03001183 if ((GetParam() == ES2_D3D11_FL9_3() || GetParam() == ES2_D3D9()))
Cooper Partina5ef8d82015-08-19 14:52:21 -07001184 {
1185 if (compileResult != 0)
1186 {
1187 FAIL() << "Shader compilation succeeded, expected failure";
1188 }
1189 else
1190 {
1191 GLint infoLogLength;
1192 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
1193
1194 std::string infoLog;
1195 infoLog.resize(infoLogLength);
1196 glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
1197
1198 if (infoLog.find("Loop index cannot be compared with non-constant expression") ==
1199 std::string::npos)
1200 {
1201 FAIL() << "Shader compilation failed with unexpected error message";
1202 }
1203 }
1204 }
1205 else
1206 {
1207 EXPECT_NE(0, compileResult);
1208 }
1209
1210 if (shader != 0)
1211 {
1212 glDeleteShader(shader);
1213 }
1214}
1215
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001216// Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1217// can actually be used.
1218TEST_P(GLSLTest, VerifyMaxVertexUniformVectors)
1219{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001220 int maxUniforms = 10000;
1221 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1222 EXPECT_GL_NO_ERROR();
1223 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl;
1224
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001225 CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, 0, 0, true);
1226}
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001227
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001228// Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1229// can actually be used along with the maximum number of texture samplers.
1230TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsWithSamplers)
1231{
1232 int maxUniforms = 10000;
1233 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1234 EXPECT_GL_NO_ERROR();
1235 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001236
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001237 int maxTextureImageUnits = 0;
1238 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001239
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001240 CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, maxTextureImageUnits, 0, true);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001241}
1242
1243// Tests that the maximum uniforms count + 1 from querying GL_MAX_VERTEX_UNIFORM_VECTORS
1244// fails shader compilation.
1245TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsExceeded)
1246{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001247 int maxUniforms = 10000;
1248 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
1249 EXPECT_GL_NO_ERROR();
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001250 std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS + 1 = " << maxUniforms + 1 << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001251
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001252 CompileGLSLWithUniformsAndSamplers(maxUniforms + 1, 0, 0, 0, false);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001253}
1254
1255// Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1256// can actually be used.
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001257TEST_P(GLSLTest, VerifyMaxFragmentUniformVectors)
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001258{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001259 int maxUniforms = 10000;
1260 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1261 EXPECT_GL_NO_ERROR();
1262 std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS = " << maxUniforms << std::endl;
1263
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001264 CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, 0, true);
1265}
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001266
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001267// Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1268// can actually be used along with the maximum number of texture samplers.
1269TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsWithSamplers)
1270{
1271 int maxUniforms = 10000;
1272 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1273 EXPECT_GL_NO_ERROR();
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001274
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001275 int maxTextureImageUnits = 0;
1276 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001277
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001278 CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, maxTextureImageUnits, true);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001279}
1280
1281// Tests that the maximum uniforms count + 1 from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
1282// fails shader compilation.
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001283TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsExceeded)
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001284{
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001285 int maxUniforms = 10000;
1286 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
1287 EXPECT_GL_NO_ERROR();
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001288 std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS + 1 = " << maxUniforms + 1
1289 << std::endl;
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001290
Austin Kinross7a3e8e22015-10-08 15:50:06 -07001291 CompileGLSLWithUniformsAndSamplers(0, maxUniforms + 1, 0, 0, false);
Cooper Partin69f9b2c2015-08-20 13:25:41 -07001292}
1293
Jamie Madillfa05f602015-05-07 13:47:11 -04001294// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Cooper Partina5ef8d82015-08-19 14:52:21 -07001295ANGLE_INSTANTIATE_TEST(GLSLTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
Jamie Madillfa05f602015-05-07 13:47:11 -04001296
1297// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
1298ANGLE_INSTANTIATE_TEST(GLSLTest_ES3, ES3_D3D11());