blob: 71ee6c9b00489cbfab1e6087e03bd58a3234a33e [file] [log] [blame]
Jamie Madill96509e42014-05-29 14:33:27 -04001#include "ANGLETest.h"
2
Austin Kinross18b931d2014-09-29 12:58:31 -07003// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Lang0d3683c2014-10-23 11:08:16 -04004ANGLE_TYPED_TEST_CASE(GLSLTest, ES2_D3D9, ES2_D3D11);
Austin Kinross18b931d2014-09-29 12:58:31 -07005
6template<typename T>
Jamie Madill2bf8b372014-06-16 17:18:51 -04007class GLSLTest : public ANGLETest
Jamie Madill96509e42014-05-29 14:33:27 -04008{
9protected:
Geoff Lang0d3683c2014-10-23 11:08:16 -040010 GLSLTest() : ANGLETest(T::GetGlesMajorVersion(), T::GetPlatform())
Jamie Madill96509e42014-05-29 14:33:27 -040011 {
12 setWindowWidth(128);
13 setWindowHeight(128);
14 setConfigRedBits(8);
15 setConfigGreenBits(8);
16 setConfigBlueBits(8);
17 setConfigAlphaBits(8);
18 }
Jamie Madillbfa91f42014-06-05 15:45:18 -040019
20 virtual void SetUp()
21 {
22 ANGLETest::SetUp();
23
Jamie Madill2bf8b372014-06-16 17:18:51 -040024 mSimpleVSSource = SHADER_SOURCE
Jamie Madillbfa91f42014-06-05 15:45:18 -040025 (
26 attribute vec4 inputAttribute;
27 void main()
28 {
29 gl_Position = inputAttribute;
30 }
31 );
32 }
33
Austin Kinrossaf875522014-08-25 21:06:07 -070034 std::string GenerateVaryingType(GLint vectorSize)
35 {
36 char varyingType[10];
37
38 if (vectorSize == 1)
39 {
40 sprintf(varyingType, "float");
41 }
42 else
43 {
44 sprintf(varyingType, "vec%d", vectorSize);
45 }
46
47 return std::string(varyingType);
48 }
49
50 std::string GenerateVectorVaryingDeclaration(GLint vectorSize, GLint arraySize, GLint id)
51 {
52 char buff[100];
53
54 if (arraySize == 1)
55 {
56 sprintf(buff, "varying %s v%d;\n", GenerateVaryingType(vectorSize).c_str(), id);
57 }
58 else
59 {
60 sprintf(buff, "varying %s v%d[%d];\n", GenerateVaryingType(vectorSize).c_str(), id, arraySize);
61 }
62
63 return std::string(buff);
64 }
65
66 std::string GenerateVectorVaryingSettingCode(GLint vectorSize, GLint arraySize, GLint id)
67 {
68 std::string returnString;
69 char buff[100];
70
71 if (arraySize == 1)
72 {
73 sprintf(buff, "\t v%d = %s(1.0);\n", id, GenerateVaryingType(vectorSize).c_str());
74 returnString += buff;
75 }
76 else
77 {
78 for (int i = 0; i < arraySize; i++)
79 {
80 sprintf(buff, "\t v%d[%d] = %s(1.0);\n", id, i, GenerateVaryingType(vectorSize).c_str());
81 returnString += buff;
82 }
83 }
84
85 return returnString;
86 }
87
88 std::string GenerateVectorVaryingUseCode(GLint arraySize, GLint id)
89 {
90 if (arraySize == 1)
91 {
92 char buff[100];
93 sprintf(buff, "v%d + ", id);
94 return std::string(buff);
95 }
96 else
97 {
98 std::string returnString;
99 for (int i = 0; i < arraySize; i++)
100 {
101 char buff[100];
102 sprintf(buff, "v%d[%d] + ", id, i);
103 returnString += buff;
104 }
105 return returnString;
106 }
107 }
108
Austin Kinross8b695ee2015-03-12 13:12:20 -0700109 void GenerateGLSLWithVaryings(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
110 GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize,
111 std::string* fragmentShader, std::string* vertexShader)
Austin Kinrossaf875522014-08-25 21:06:07 -0700112 {
113 // Generate a string declaring the varyings, to share between the fragment shader and the vertex shader.
114 std::string varyingDeclaration;
115
116 unsigned int varyingCount = 0;
117
118 for (GLint i = 0; i < floatCount; i++)
119 {
120 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 1, varyingCount);
121 varyingCount += 1;
122 }
123
124 for (GLint i = 0; i < floatArrayCount; i++)
125 {
126 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 2, varyingCount);
127 varyingCount += 1;
128 }
129
130 for (GLint i = 0; i < vec2Count; i++)
131 {
132 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 1, varyingCount);
133 varyingCount += 1;
134 }
135
136 for (GLint i = 0; i < vec2ArrayCount; i++)
137 {
138 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 2, varyingCount);
139 varyingCount += 1;
140 }
141
142 for (GLint i = 0; i < vec3Count; i++)
143 {
144 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 1, varyingCount);
145 varyingCount += 1;
146 }
147
148 for (GLint i = 0; i < vec3ArrayCount; i++)
149 {
150 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 2, varyingCount);
151 varyingCount += 1;
152 }
153
Austin Kinross8b695ee2015-03-12 13:12:20 -0700154 for (GLint i = 0; i < vec4Count; i++)
155 {
156 varyingDeclaration += GenerateVectorVaryingDeclaration(4, 1, varyingCount);
157 varyingCount += 1;
158 }
159
160 for (GLint i = 0; i < vec4ArrayCount; i++)
161 {
162 varyingDeclaration += GenerateVectorVaryingDeclaration(4, 2, varyingCount);
163 varyingCount += 1;
164 }
165
Austin Kinrossaf875522014-08-25 21:06:07 -0700166 // Generate the vertex shader
167 vertexShader->clear();
168 vertexShader->append(varyingDeclaration);
169 vertexShader->append("\nvoid main()\n{\n");
170
171 unsigned int currentVSVarying = 0;
172
173 for (GLint i = 0; i < floatCount; i++)
174 {
175 vertexShader->append(GenerateVectorVaryingSettingCode(1, 1, currentVSVarying));
176 currentVSVarying += 1;
177 }
178
179 for (GLint i = 0; i < floatArrayCount; i++)
180 {
181 vertexShader->append(GenerateVectorVaryingSettingCode(1, 2, currentVSVarying));
182 currentVSVarying += 1;
183 }
184
185 for (GLint i = 0; i < vec2Count; i++)
186 {
187 vertexShader->append(GenerateVectorVaryingSettingCode(2, 1, currentVSVarying));
188 currentVSVarying += 1;
189 }
190
191 for (GLint i = 0; i < vec2ArrayCount; i++)
192 {
193 vertexShader->append(GenerateVectorVaryingSettingCode(2, 2, currentVSVarying));
194 currentVSVarying += 1;
195 }
196
197 for (GLint i = 0; i < vec3Count; i++)
198 {
199 vertexShader->append(GenerateVectorVaryingSettingCode(3, 1, currentVSVarying));
200 currentVSVarying += 1;
201 }
202
203 for (GLint i = 0; i < vec3ArrayCount; i++)
204 {
205 vertexShader->append(GenerateVectorVaryingSettingCode(3, 2, currentVSVarying));
206 currentVSVarying += 1;
207 }
208
Austin Kinross8b695ee2015-03-12 13:12:20 -0700209 for (GLint i = 0; i < vec4Count; i++)
210 {
211 vertexShader->append(GenerateVectorVaryingSettingCode(4, 1, currentVSVarying));
212 currentVSVarying += 1;
213 }
214
215 for (GLint i = 0; i < vec4ArrayCount; i++)
216 {
217 vertexShader->append(GenerateVectorVaryingSettingCode(4, 2, currentVSVarying));
218 currentVSVarying += 1;
219 }
220
221 if (usePointSize)
222 {
223 vertexShader->append("gl_PointSize = 1.0;\n");
224 }
225
Austin Kinrossaf875522014-08-25 21:06:07 -0700226 vertexShader->append("}\n");
227
228 // Generate the fragment shader
229 fragmentShader->clear();
230 fragmentShader->append("precision highp float;\n");
231 fragmentShader->append(varyingDeclaration);
232 fragmentShader->append("\nvoid main() \n{ \n\tvec4 retColor = vec4(0,0,0,0);\n");
233
234 unsigned int currentFSVarying = 0;
235
236 // Make use of the float varyings
237 fragmentShader->append("\tretColor += vec4(");
238
239 for (GLint i = 0; i < floatCount; i++)
240 {
241 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
242 currentFSVarying += 1;
243 }
244
245 for (GLint i = 0; i < floatArrayCount; i++)
246 {
247 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
248 currentFSVarying += 1;
249 }
250
251 fragmentShader->append("0.0, 0.0, 0.0, 0.0);\n");
252
253 // Make use of the vec2 varyings
254 fragmentShader->append("\tretColor += vec4(");
255
256 for (GLint i = 0; i < vec2Count; i++)
257 {
258 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
259 currentFSVarying += 1;
260 }
261
262 for (GLint i = 0; i < vec2ArrayCount; i++)
263 {
264 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
265 currentFSVarying += 1;
266 }
267
268 fragmentShader->append("vec2(0.0, 0.0), 0.0, 0.0);\n");
269
270 // Make use of the vec3 varyings
271 fragmentShader->append("\tretColor += vec4(");
272
273 for (GLint i = 0; i < vec3Count; i++)
274 {
275 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
276 currentFSVarying += 1;
277 }
278
279 for (GLint i = 0; i < vec3ArrayCount; i++)
280 {
281 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
282 currentFSVarying += 1;
283 }
284
285 fragmentShader->append("vec3(0.0, 0.0, 0.0), 0.0);\n");
Austin Kinross8b695ee2015-03-12 13:12:20 -0700286
287 // Make use of the vec4 varyings
288 fragmentShader->append("\tretColor += ");
289
290 for (GLint i = 0; i < vec4Count; i++)
291 {
292 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
293 currentFSVarying += 1;
294 }
295
296 for (GLint i = 0; i < vec4ArrayCount; i++)
297 {
298 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
299 currentFSVarying += 1;
300 }
301
302 fragmentShader->append("vec4(0.0, 0.0, 0.0, 0.0);\n");
303
304 // Set gl_FragColor, and use special variables if requested
305 fragmentShader->append("\tgl_FragColor = retColor");
306
307 if (useFragCoord)
308 {
309 fragmentShader->append(" + gl_FragCoord");
310 }
311
312 if (usePointCoord)
313 {
314 fragmentShader->append(" + vec4(gl_PointCoord, 0.0, 0.0)");
315 }
316
317 fragmentShader->append(";\n}");
318 }
319
320 void VaryingTestBase(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
321 GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize, bool expectSuccess)
322 {
323 std::string fragmentShaderSource;
324 std::string vertexShaderSource;
325
326 GenerateGLSLWithVaryings(floatCount, floatArrayCount, vec2Count, vec2ArrayCount, vec3Count, vec3ArrayCount,
327 vec4Count, vec4ArrayCount, useFragCoord, usePointCoord, usePointSize,
328 &fragmentShaderSource, &vertexShaderSource);
329
330 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
331
332 if (expectSuccess)
333 {
334 EXPECT_NE(0u, program);
335 }
336 else
337 {
338 EXPECT_EQ(0u, program);
339 }
Austin Kinrossaf875522014-08-25 21:06:07 -0700340 }
341
Jamie Madill2bf8b372014-06-16 17:18:51 -0400342 std::string mSimpleVSSource;
Austin Kinross8b695ee2015-03-12 13:12:20 -0700343 T fixtureType;
Jamie Madill96509e42014-05-29 14:33:27 -0400344};
345
Gregoire Payen de La Garanderieb3dced22015-01-12 14:54:55 +0000346// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
347ANGLE_TYPED_TEST_CASE(GLSLTest_ES3, ES3_D3D11);
348
349template<typename T>
350class GLSLTest_ES3 : public GLSLTest<T>
351{
352};
353
Austin Kinross18b931d2014-09-29 12:58:31 -0700354TYPED_TEST(GLSLTest, NamelessScopedStructs)
Jamie Madill96509e42014-05-29 14:33:27 -0400355{
Jamie Madillbfa91f42014-06-05 15:45:18 -0400356 const std::string fragmentShaderSource = SHADER_SOURCE
Jamie Madill96509e42014-05-29 14:33:27 -0400357 (
Jamie Madillbfa91f42014-06-05 15:45:18 -0400358 precision mediump float;
359
Jamie Madill96509e42014-05-29 14:33:27 -0400360 void main()
361 {
Jamie Madillbfa91f42014-06-05 15:45:18 -0400362 struct
363 {
364 float q;
365 } b;
366
367 gl_FragColor = vec4(1, 0, 0, 1);
368 gl_FragColor.a += b.q;
Jamie Madill96509e42014-05-29 14:33:27 -0400369 }
370 );
371
Jamie Madill5599c8f2014-08-26 13:16:39 -0400372 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madillbfa91f42014-06-05 15:45:18 -0400373 EXPECT_NE(0u, program);
374}
Austin Kinross18b931d2014-09-29 12:58:31 -0700375
376TYPED_TEST(GLSLTest, ScopedStructsOrderBug)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400377{
378 const std::string fragmentShaderSource = SHADER_SOURCE
379 (
380 precision mediump float;
381
382 struct T
383 {
384 float f;
385 };
386
387 void main()
388 {
389 T a;
390
391 struct T
392 {
393 float q;
394 };
395
396 T b;
397
398 gl_FragColor = vec4(1, 0, 0, 1);
399 gl_FragColor.a += a.f;
400 gl_FragColor.a += b.q;
401 }
402 );
403
Jamie Madill5599c8f2014-08-26 13:16:39 -0400404 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madillbfa91f42014-06-05 15:45:18 -0400405 EXPECT_NE(0u, program);
406}
407
Austin Kinross18b931d2014-09-29 12:58:31 -0700408TYPED_TEST(GLSLTest, ScopedStructsBug)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400409{
Jamie Madill96509e42014-05-29 14:33:27 -0400410 const std::string fragmentShaderSource = SHADER_SOURCE
411 (
412 precision mediump float;
413
414 struct T_0
415 {
416 float f;
417 };
418
419 void main()
420 {
421 gl_FragColor = vec4(1, 0, 0, 1);
422
423 struct T
424 {
425 vec2 v;
426 };
427
428 T_0 a;
429 T b;
430
431 gl_FragColor.a += a.f;
432 gl_FragColor.a += b.v.x;
433 }
434 );
435
Jamie Madill5599c8f2014-08-26 13:16:39 -0400436 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madill2bf8b372014-06-16 17:18:51 -0400437 EXPECT_NE(0u, program);
438}
439
Austin Kinross18b931d2014-09-29 12:58:31 -0700440TYPED_TEST(GLSLTest, DxPositionBug)
Jamie Madill2bf8b372014-06-16 17:18:51 -0400441{
442 const std::string &vertexShaderSource = SHADER_SOURCE
443 (
444 attribute vec4 inputAttribute;
445 varying float dx_Position;
446 void main()
447 {
448 gl_Position = vec4(inputAttribute);
449 dx_Position = 0.0;
450 }
451 );
452
453 const std::string &fragmentShaderSource = SHADER_SOURCE
454 (
455 precision mediump float;
456
457 varying float dx_Position;
458
459 void main()
460 {
461 gl_FragColor = vec4(dx_Position, 0, 0, 1);
462 }
463 );
464
Jamie Madill5599c8f2014-08-26 13:16:39 -0400465 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill96509e42014-05-29 14:33:27 -0400466 EXPECT_NE(0u, program);
467}
Jamie Madill4836d222014-07-24 06:55:51 -0400468
Austin Kinross18b931d2014-09-29 12:58:31 -0700469TYPED_TEST(GLSLTest, ElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400470{
471 const std::string &vertexShaderSource =
472 "attribute vec4 a_position;\n"
473 "varying float v;\n"
474 "void main() {\n"
475 " gl_Position = a_position;\n"
476 " v = 1.0;\n"
477 " if (a_position.x <= 0.5) {\n"
478 " v = 0.0;\n"
479 " } else if (a_position.x >= 0.5) {\n"
480 " v = 2.0;\n"
481 " }\n"
482 "}\n";
483
484 const std::string &fragmentShaderSource =
485 "precision highp float;\n"
486 "varying float v;\n"
487 "void main() {\n"
488 " vec4 color = vec4(1.0, 0.0, 0.0, 1.0);\n"
489 " if (v >= 1.0) color = vec4(0.0, 1.0, 0.0, 1.0);\n"
490 " if (v >= 2.0) color = vec4(0.0, 0.0, 1.0, 1.0);\n"
491 " gl_FragColor = color;\n"
492 "}\n";
493
Jamie Madill5599c8f2014-08-26 13:16:39 -0400494 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400495 ASSERT_NE(0u, program);
496
497 drawQuad(program, "a_position", 0.5f);
498 swapBuffers();
499
500 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
501 EXPECT_PIXEL_EQ(getWindowWidth()-1, 0, 0, 255, 0, 255);
502}
503
Austin Kinross18b931d2014-09-29 12:58:31 -0700504TYPED_TEST(GLSLTest, TwoElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400505{
506 const std::string &vertexShaderSource =
507 "attribute vec4 a_position;\n"
508 "varying float v;\n"
509 "void main() {\n"
510 " gl_Position = a_position;\n"
Jamie Madill778d5272014-08-04 13:13:25 -0400511 " if (a_position.x == 0.0) {\n"
Jamie Madill4836d222014-07-24 06:55:51 -0400512 " v = 1.0;\n"
513 " } else if (a_position.x > 0.5) {\n"
514 " v = 0.0;\n"
515 " } else if (a_position.x > 0.75) {\n"
516 " v = 0.5;\n"
517 " }\n"
518 "}\n";
519
520 const std::string &fragmentShaderSource =
521 "precision highp float;\n"
522 "varying float v;\n"
523 "void main() {\n"
524 " gl_FragColor = vec4(v, 0.0, 0.0, 1.0);\n"
525 "}\n";
526
Jamie Madill5599c8f2014-08-26 13:16:39 -0400527 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400528 EXPECT_NE(0u, program);
529}
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400530
Austin Kinross18b931d2014-09-29 12:58:31 -0700531TYPED_TEST(GLSLTest, InvariantVaryingOut)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400532{
533 const std::string fragmentShaderSource = SHADER_SOURCE
534 (
535 precision mediump float;
536 varying float v_varying;
537 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
538 );
539
540 const std::string vertexShaderSource = SHADER_SOURCE
541 (
542 attribute vec4 a_position;
543 invariant varying float v_varying;
544 void main() { v_varying = a_position.x; gl_Position = a_position; }
545 );
546
Jamie Madill5599c8f2014-08-26 13:16:39 -0400547 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400548 EXPECT_NE(0u, program);
549}
550
Austin Kinross18b931d2014-09-29 12:58:31 -0700551TYPED_TEST(GLSLTest, FrontFacingAndVarying)
Jamie Madille6256f82014-09-17 10:31:15 -0400552{
Austin Kinross8b695ee2015-03-12 13:12:20 -0700553 EGLPlatformParameters platform = fixtureType.GetPlatform();
554
555 // Disable this test on D3D11 feature level 9_3, since gl_FrontFacing isn't supported.
556 if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
557 {
558 if (platform.majorVersion == 9 && platform.minorVersion == 3)
559 {
560 return;
561 }
562 }
563
Jamie Madille6256f82014-09-17 10:31:15 -0400564 const std::string vertexShaderSource = SHADER_SOURCE
565 (
566 attribute vec4 a_position;
567 varying float v_varying;
568 void main()
569 {
570 v_varying = a_position.x;
571 gl_Position = a_position;
572 }
573 );
574
575 const std::string fragmentShaderSource = SHADER_SOURCE
576 (
577 precision mediump float;
578 varying float v_varying;
579 void main()
580 {
581 vec4 c;
582
583 if (gl_FrontFacing)
584 {
585 c = vec4(v_varying, 0, 0, 1.0);
586 }
587 else
588 {
589 c = vec4(0, v_varying, 0, 1.0);
590 }
591 gl_FragColor = c;
592 }
593 );
594
595 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
596 EXPECT_NE(0u, program);
597}
598
Austin Kinross18b931d2014-09-29 12:58:31 -0700599TYPED_TEST(GLSLTest, InvariantVaryingIn)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400600{
601 const std::string fragmentShaderSource = SHADER_SOURCE
602 (
603 precision mediump float;
604 invariant varying float v_varying;
605 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
606 );
607
608 const std::string vertexShaderSource = SHADER_SOURCE
609 (
610 attribute vec4 a_position;
611 varying float v_varying;
612 void main() { v_varying = a_position.x; gl_Position = a_position; }
613 );
614
Jamie Madill5599c8f2014-08-26 13:16:39 -0400615 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400616 EXPECT_NE(0u, program);
617}
618
Austin Kinross18b931d2014-09-29 12:58:31 -0700619TYPED_TEST(GLSLTest, InvariantVaryingBoth)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400620{
621 const std::string fragmentShaderSource = SHADER_SOURCE
622 (
623 precision mediump float;
624 invariant varying float v_varying;
625 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
626 );
627
628 const std::string vertexShaderSource = SHADER_SOURCE
629 (
630 attribute vec4 a_position;
631 invariant varying float v_varying;
632 void main() { v_varying = a_position.x; gl_Position = a_position; }
633 );
634
Jamie Madill5599c8f2014-08-26 13:16:39 -0400635 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400636 EXPECT_NE(0u, program);
637}
638
Austin Kinross18b931d2014-09-29 12:58:31 -0700639TYPED_TEST(GLSLTest, InvariantGLPosition)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400640{
641 const std::string fragmentShaderSource = SHADER_SOURCE
642 (
643 precision mediump float;
644 varying float v_varying;
645 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
646 );
647
648 const std::string vertexShaderSource = SHADER_SOURCE
649 (
650 attribute vec4 a_position;
651 invariant gl_Position;
652 varying float v_varying;
653 void main() { v_varying = a_position.x; gl_Position = a_position; }
654 );
655
Jamie Madill5599c8f2014-08-26 13:16:39 -0400656 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400657 EXPECT_NE(0u, program);
658}
659
Austin Kinross18b931d2014-09-29 12:58:31 -0700660TYPED_TEST(GLSLTest, InvariantAll)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400661{
662 const std::string fragmentShaderSource = SHADER_SOURCE
663 (
664 precision mediump float;
665 varying float v_varying;
666 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
667 );
668
669 const std::string vertexShaderSource =
670 "#pragma STDGL invariant(all)\n"
671 "attribute vec4 a_position;\n"
672 "varying float v_varying;\n"
673 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
674
Jamie Madill5599c8f2014-08-26 13:16:39 -0400675 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400676 EXPECT_NE(0u, program);
677}
Austin Kinrossaf875522014-08-25 21:06:07 -0700678
Austin Kinross8b695ee2015-03-12 13:12:20 -0700679TYPED_TEST(GLSLTest, MaxVaryingVec4)
680{
681 GLint maxVaryings = 0;
682 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
683
684 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, false, false, true);
685}
686
687TYPED_TEST(GLSLTest, MaxMinusTwoVaryingVec4PlusTwoSpecialVariables)
688{
689 GLint maxVaryings = 0;
690 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
691
692 // Generate shader code that uses gl_FragCoord and gl_PointCoord, two special fragment shader variables.
693 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, false, true);
694}
695
696TYPED_TEST(GLSLTest, MaxMinusTwoVaryingVec4PlusThreeSpecialVariables)
697{
698 GLint maxVaryings = 0;
699 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
700
701 // Generate shader code that uses gl_FragCoord, gl_PointCoord and gl_PointSize.
702 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, true, true);
703}
704
705TYPED_TEST(GLSLTest, MaxVaryingVec4PlusFragCoord)
706{
707 GLint maxVaryings = 0;
708 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
709
710 // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
711 // This test should fail, since we are really using (maxVaryings + 1) varyings.
712 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, true, false, false, false);
713}
714
715TYPED_TEST(GLSLTest, MaxVaryingVec4PlusPointCoord)
716{
717 GLint maxVaryings = 0;
718 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
719
720 // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
721 // This test should fail, since we are really using (maxVaryings + 1) varyings.
722 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, true, false, false);
723}
724
Austin Kinross18b931d2014-09-29 12:58:31 -0700725TYPED_TEST(GLSLTest, MaxVaryingVec3)
Austin Kinrossaf875522014-08-25 21:06:07 -0700726{
727 GLint maxVaryings = 0;
728 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
729
Austin Kinross8b695ee2015-03-12 13:12:20 -0700730 VaryingTestBase(0, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700731}
732
Austin Kinross18b931d2014-09-29 12:58:31 -0700733TYPED_TEST(GLSLTest, MaxVaryingVec3Array)
Austin Kinrossaf875522014-08-25 21:06:07 -0700734{
735 GLint maxVaryings = 0;
736 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
737
Austin Kinross8b695ee2015-03-12 13:12:20 -0700738 VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700739}
740
Jamie Madillbee59e02014-10-02 10:44:18 -0400741// Disabled because of a failure in D3D9
742TYPED_TEST(GLSLTest, DISABLED_MaxVaryingVec3AndOneFloat)
Austin Kinrossaf875522014-08-25 21:06:07 -0700743{
744 GLint maxVaryings = 0;
745 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
746
Austin Kinross8b695ee2015-03-12 13:12:20 -0700747 VaryingTestBase(1, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700748}
749
Jamie Madillbee59e02014-10-02 10:44:18 -0400750// Disabled because of a failure in D3D9
751TYPED_TEST(GLSLTest, DISABLED_MaxVaryingVec3ArrayAndOneFloatArray)
Austin Kinrossaf875522014-08-25 21:06:07 -0700752{
753 GLint maxVaryings = 0;
754 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
755
Austin Kinross8b695ee2015-03-12 13:12:20 -0700756 VaryingTestBase(0, 1, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700757}
758
Jamie Madillbee59e02014-10-02 10:44:18 -0400759// Disabled because of a failure in D3D9
760TYPED_TEST(GLSLTest, DISABLED_TwiceMaxVaryingVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -0700761{
762 GLint maxVaryings = 0;
763 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
764
Austin Kinross8b695ee2015-03-12 13:12:20 -0700765 VaryingTestBase(0, 0, 2 * maxVaryings, 0, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700766}
767
Jamie Madillbee59e02014-10-02 10:44:18 -0400768// Disabled because of a failure in D3D9
769TYPED_TEST(GLSLTest, DISABLED_MaxVaryingVec2Arrays)
Austin Kinrossaf875522014-08-25 21:06:07 -0700770{
771 GLint maxVaryings = 0;
772 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
773
Austin Kinross8b695ee2015-03-12 13:12:20 -0700774 VaryingTestBase(0, 0, 0, maxVaryings, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700775}
776
Austin Kinross18b931d2014-09-29 12:58:31 -0700777TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec3)
Austin Kinrossaf875522014-08-25 21:06:07 -0700778{
779 GLint maxVaryings = 0;
780 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
781
Austin Kinross8b695ee2015-03-12 13:12:20 -0700782 VaryingTestBase(0, 0, 0, 0, maxVaryings + 1, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700783}
784
Austin Kinross18b931d2014-09-29 12:58:31 -0700785TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec3Array)
Austin Kinrossaf875522014-08-25 21:06:07 -0700786{
787 GLint maxVaryings = 0;
788 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
789
Austin Kinross8b695ee2015-03-12 13:12:20 -0700790 VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2 + 1, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700791}
792
Austin Kinross18b931d2014-09-29 12:58:31 -0700793TYPED_TEST(GLSLTest, MaxVaryingVec3AndOneVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -0700794{
795 GLint maxVaryings = 0;
796 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
797
Austin Kinross8b695ee2015-03-12 13:12:20 -0700798 VaryingTestBase(0, 0, 1, 0, maxVaryings, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700799}
800
Austin Kinross18b931d2014-09-29 12:58:31 -0700801TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -0700802{
803 GLint maxVaryings = 0;
804 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
805
Austin Kinross8b695ee2015-03-12 13:12:20 -0700806 VaryingTestBase(0, 0, 2 * maxVaryings + 1, 0, 0, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700807}
808
Austin Kinross18b931d2014-09-29 12:58:31 -0700809TYPED_TEST(GLSLTest, MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
Austin Kinrossaf875522014-08-25 21:06:07 -0700810{
811 GLint maxVaryings = 0;
812 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
813
Austin Kinross8b695ee2015-03-12 13:12:20 -0700814 VaryingTestBase(0, maxVaryings / 2 + 1, 0, 0, 0, 0, 0, maxVaryings / 2, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700815}
Geoff Langf60fab62014-11-24 11:21:20 -0500816
817// Verify shader source with a fixed length that is less than the null-terminated length will compile.
818TYPED_TEST(GLSLTest, FixedShaderLength)
819{
820 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
821
822 const std::string appendGarbage = "abcasdfasdfasdfasdfasdf";
823 const std::string source = "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" + appendGarbage;
824 const char *sourceArray[1] = { source.c_str() };
825 GLint lengths[1] = { source.length() - appendGarbage.length() };
826 glShaderSource(shader, ArraySize(sourceArray), sourceArray, lengths);
827 glCompileShader(shader);
828
829 GLint compileResult;
830 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
831 EXPECT_NE(compileResult, 0);
832}
833
834// Verify that a negative shader source length is treated as a null-terminated length.
835TYPED_TEST(GLSLTest, NegativeShaderLength)
836{
837 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
838
839 const char *sourceArray[1] = { "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" };
840 GLint lengths[1] = { -10 };
841 glShaderSource(shader, ArraySize(sourceArray), sourceArray, lengths);
842 glCompileShader(shader);
843
844 GLint compileResult;
845 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
846 EXPECT_NE(compileResult, 0);
847}
848
849// Verify that a length array with mixed positive and negative values compiles.
850TYPED_TEST(GLSLTest, MixedShaderLengths)
851{
852 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
853
854 const char *sourceArray[] =
855 {
856 "void main()",
857 "{",
858 " gl_FragColor = vec4(0, 0, 0, 0);",
859 "}",
860 };
861 GLint lengths[] =
862 {
863 -10,
864 1,
865 std::strlen(sourceArray[2]),
866 -1,
867 };
868 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
869
870 glShaderSource(shader, ArraySize(sourceArray), sourceArray, lengths);
871 glCompileShader(shader);
872
873 GLint compileResult;
874 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
875 EXPECT_NE(compileResult, 0);
876}
877
878// Verify that zero-length shader source does not affect shader compilation.
879TYPED_TEST(GLSLTest, ZeroShaderLength)
880{
881 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
882
883 const char *sourceArray[] =
884 {
885 "adfasdf",
886 "34534",
887 "void main() { gl_FragColor = vec4(0, 0, 0, 0); }",
888 "",
889 "asdfasdfsdsdf",
890 };
891 GLint lengths[] =
892 {
893 0,
894 0,
895 -1,
896 0,
897 0,
898 };
899 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
900
901 glShaderSource(shader, ArraySize(sourceArray), sourceArray, lengths);
902 glCompileShader(shader);
903
904 GLint compileResult;
905 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
906 EXPECT_NE(compileResult, 0);
907}
Jamie Madill21c1e452014-12-29 11:33:41 -0500908
909// Tests that bad index expressions don't crash ANGLE's translator.
910// https://code.google.com/p/angleproject/issues/detail?id=857
911TYPED_TEST(GLSLTest, BadIndexBug)
912{
913 const std::string &fragmentShaderSourceVec =
914 "precision mediump float;\n"
915 "uniform vec4 uniformVec;\n"
916 "void main()\n"
917 "{\n"
918 " gl_FragColor = vec4(uniformVec[int()]);\n"
919 "}";
920
921 GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceVec);
922 EXPECT_EQ(0u, shader);
923
924 if (shader != 0)
925 {
926 glDeleteShader(shader);
927 }
928
929 const std::string &fragmentShaderSourceMat =
930 "precision mediump float;\n"
931 "uniform mat4 uniformMat;\n"
932 "void main()\n"
933 "{\n"
934 " gl_FragColor = vec4(uniformMat[int()]);\n"
935 "}";
936
937 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceMat);
938 EXPECT_EQ(0u, shader);
939
940 if (shader != 0)
941 {
942 glDeleteShader(shader);
943 }
944
945 const std::string &fragmentShaderSourceArray =
946 "precision mediump float;\n"
947 "uniform vec4 uniformArray;\n"
948 "void main()\n"
949 "{\n"
950 " gl_FragColor = vec4(uniformArray[int()]);\n"
951 "}";
952
953 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceArray);
954 EXPECT_EQ(0u, shader);
955
956 if (shader != 0)
957 {
958 glDeleteShader(shader);
959 }
Jamie Madill37997142015-01-28 10:06:34 -0500960}
961
962// Tests that using a global static initialized from a varying works as expected.
963// See: https://code.google.com/p/angleproject/issues/detail?id=878
964TYPED_TEST(GLSLTest, GlobalStaticAndVarying)
965{
966 const std::string &vertexShaderSource =
967 "attribute vec4 a_position;\n"
968 "varying float v;\n"
969 "void main() {\n"
970 " gl_Position = a_position;\n"
971 " v = 1.0;\n"
972 "}\n";
973
974 const std::string &fragmentShaderSource =
975 "precision highp float;\n"
976 "varying float v;\n"
977 "float x = v;"
978 "float global_v = x;"
979 "void main() {\n"
980 " gl_FragColor = vec4(global_v, 0.0, 0.0, 1.0);\n"
981 "}\n";
982
983 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
984 ASSERT_NE(0u, program);
985
986 drawQuad(program, "a_position", 0.5f);
987 swapBuffers();
988
989 ASSERT_GL_NO_ERROR();
990 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
991}
Gregoire Payen de La Garanderieb3dced22015-01-12 14:54:55 +0000992
993// Tests that using a global static initialized from gl_InstanceID works as expected.
994TYPED_TEST(GLSLTest_ES3, GlobalStaticAndInstanceID)
995{
996 const std::string &vertexShaderSource =
997 "#version 300 es\n"
998 "precision highp float;\n"
999 "in vec4 a_position;\n"
1000 "out vec4 vColour;"
1001 "int x = gl_InstanceID;"
1002 "int global_v = x;"
1003 "void main() {\n"
1004 " gl_Position = a_position;\n"
1005 " vColour = vec4(float(global_v)/255., 0.0, 0.0, 1.0);\n"
1006 "}\n";
1007
1008 const std::string &fragmentShaderSource =
1009 "#version 300 es\n"
1010 "precision highp float;\n"
1011 "in vec4 vColour;"
1012 "out vec4 colour;"
1013 "void main() {\n"
1014 " colour = vColour;\n"
1015 "}\n";
1016
1017 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1018 ASSERT_NE(0u, program);
1019
1020 GLint positionLocation = glGetAttribLocation(program, "a_position");
1021
1022 glUseProgram(program);
1023
1024 const GLfloat vertices[] =
1025 {
1026 -1.0f, 1.0f, 0.5f,
1027 -1.0f, -1.0f, 0.5f,
1028 1.0f, -1.0f, 0.5f,
1029
1030 -1.0f, 1.0f, 0.5f,
1031 1.0f, -1.0f, 0.5f,
1032 1.0f, 1.0f, 0.5f,
1033 };
1034
1035 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
1036 glEnableVertexAttribArray(positionLocation);
1037
1038 glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 7);
1039
1040 glDisableVertexAttribArray(positionLocation);
1041 glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
1042
1043 glUseProgram(0);
1044
1045 swapBuffers();
1046
1047 ASSERT_GL_NO_ERROR();
1048 EXPECT_PIXEL_EQ(0, 0, 6, 0, 0, 255);
1049}