Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / tests / angle_tests / GLSLTest.cpp
1 #include "ANGLETest.h"
2
3 class GLSLTest : public ANGLETest
4 {
5 protected:
6     GLSLTest()
7     {
8         setWindowWidth(128);
9         setWindowHeight(128);
10         setConfigRedBits(8);
11         setConfigGreenBits(8);
12         setConfigBlueBits(8);
13         setConfigAlphaBits(8);
14     }
15
16     virtual void SetUp()
17     {
18         ANGLETest::SetUp();
19
20         mSimpleVSSource = SHADER_SOURCE
21         (
22             attribute vec4 inputAttribute;
23             void main()
24             {
25                 gl_Position = inputAttribute;
26             }
27         );
28     }
29
30     std::string GenerateVaryingType(GLint vectorSize)
31     {
32         char varyingType[10];
33
34         if (vectorSize == 1)
35         {
36             sprintf(varyingType, "float");
37         }
38         else
39         {
40             sprintf(varyingType, "vec%d", vectorSize);
41         }
42
43         return std::string(varyingType);
44     }
45
46     std::string GenerateVectorVaryingDeclaration(GLint vectorSize, GLint arraySize, GLint id)
47     {
48         char buff[100];
49
50         if (arraySize == 1)
51         {
52             sprintf(buff, "varying %s v%d;\n", GenerateVaryingType(vectorSize).c_str(), id);
53         }
54         else
55         {
56             sprintf(buff, "varying %s v%d[%d];\n", GenerateVaryingType(vectorSize).c_str(), id, arraySize);
57         }
58
59         return std::string(buff);
60     }
61
62     std::string GenerateVectorVaryingSettingCode(GLint vectorSize, GLint arraySize, GLint id)
63     {
64         std::string returnString;
65         char buff[100];
66
67         if (arraySize == 1)
68         {
69             sprintf(buff, "\t v%d = %s(1.0);\n", id, GenerateVaryingType(vectorSize).c_str());
70             returnString += buff;
71         }
72         else
73         {
74             for (int i = 0; i < arraySize; i++)
75             {
76                 sprintf(buff, "\t v%d[%d] = %s(1.0);\n", id, i, GenerateVaryingType(vectorSize).c_str());
77                 returnString += buff;
78             }
79         }
80
81         return returnString;
82     }
83
84     std::string GenerateVectorVaryingUseCode(GLint arraySize, GLint id)
85     {
86         if (arraySize == 1)
87         {
88             char buff[100];
89             sprintf(buff, "v%d + ", id);
90             return std::string(buff);
91         }
92         else
93         {
94             std::string returnString;
95             for (int i = 0; i < arraySize; i++)
96             {
97                 char buff[100];
98                 sprintf(buff, "v%d[%d] + ", id, i);
99                 returnString += buff;
100             }
101             return returnString;
102         }
103     }
104
105     void GenerateGLSLWithVaryings(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount, std::string* fragmentShader, std::string* vertexShader)
106     {
107         // Generate a string declaring the varyings, to share between the fragment shader and the vertex shader.
108         std::string varyingDeclaration;
109
110         unsigned int varyingCount = 0;
111
112         for (GLint i = 0; i < floatCount; i++)
113         {
114             varyingDeclaration += GenerateVectorVaryingDeclaration(1, 1, varyingCount);
115             varyingCount += 1;
116         }
117
118         for (GLint i = 0; i < floatArrayCount; i++)
119         {
120             varyingDeclaration += GenerateVectorVaryingDeclaration(1, 2, varyingCount);
121             varyingCount += 1;
122         }
123
124         for (GLint i = 0; i < vec2Count; i++)
125         {
126             varyingDeclaration += GenerateVectorVaryingDeclaration(2, 1, varyingCount);
127             varyingCount += 1;
128         }
129
130         for (GLint i = 0; i < vec2ArrayCount; i++)
131         {
132             varyingDeclaration += GenerateVectorVaryingDeclaration(2, 2, varyingCount);
133             varyingCount += 1;
134         }
135
136         for (GLint i = 0; i < vec3Count; i++)
137         {
138             varyingDeclaration += GenerateVectorVaryingDeclaration(3, 1, varyingCount);
139             varyingCount += 1;
140         }
141
142         for (GLint i = 0; i < vec3ArrayCount; i++)
143         {
144             varyingDeclaration += GenerateVectorVaryingDeclaration(3, 2, varyingCount);
145             varyingCount += 1;
146         }
147
148         // Generate the vertex shader
149         vertexShader->clear();
150         vertexShader->append(varyingDeclaration);
151         vertexShader->append("\nvoid main()\n{\n");
152
153         unsigned int currentVSVarying = 0;
154
155         for (GLint i = 0; i < floatCount; i++)
156         {
157             vertexShader->append(GenerateVectorVaryingSettingCode(1, 1, currentVSVarying));
158             currentVSVarying += 1;
159         }
160
161         for (GLint i = 0; i < floatArrayCount; i++)
162         {
163             vertexShader->append(GenerateVectorVaryingSettingCode(1, 2, currentVSVarying));
164             currentVSVarying += 1;
165         }
166
167         for (GLint i = 0; i < vec2Count; i++)
168         {
169             vertexShader->append(GenerateVectorVaryingSettingCode(2, 1, currentVSVarying));
170             currentVSVarying += 1;
171         }
172
173         for (GLint i = 0; i < vec2ArrayCount; i++)
174         {
175             vertexShader->append(GenerateVectorVaryingSettingCode(2, 2, currentVSVarying));
176             currentVSVarying += 1;
177         }
178
179         for (GLint i = 0; i < vec3Count; i++)
180         {
181             vertexShader->append(GenerateVectorVaryingSettingCode(3, 1, currentVSVarying));
182             currentVSVarying += 1;
183         }
184
185         for (GLint i = 0; i < vec3ArrayCount; i++)
186         {
187             vertexShader->append(GenerateVectorVaryingSettingCode(3, 2, currentVSVarying));
188             currentVSVarying += 1;
189         }
190
191         vertexShader->append("}\n");
192
193         // Generate the fragment shader
194         fragmentShader->clear();
195         fragmentShader->append("precision highp float;\n");
196         fragmentShader->append(varyingDeclaration);
197         fragmentShader->append("\nvoid main() \n{ \n\tvec4 retColor = vec4(0,0,0,0);\n");
198
199         unsigned int currentFSVarying = 0;
200
201         // Make use of the float varyings
202         fragmentShader->append("\tretColor += vec4(");
203
204         for (GLint i = 0; i < floatCount; i++)
205         {
206             fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
207             currentFSVarying += 1;
208         }
209
210         for (GLint i = 0; i < floatArrayCount; i++)
211         {
212             fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
213             currentFSVarying += 1;
214         }
215
216         fragmentShader->append("0.0, 0.0, 0.0, 0.0);\n");
217
218         // Make use of the vec2 varyings
219         fragmentShader->append("\tretColor += vec4(");
220
221         for (GLint i = 0; i < vec2Count; i++)
222         {
223             fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
224             currentFSVarying += 1;
225         }
226
227         for (GLint i = 0; i < vec2ArrayCount; i++)
228         {
229             fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
230             currentFSVarying += 1;
231         }
232
233         fragmentShader->append("vec2(0.0, 0.0), 0.0, 0.0);\n");
234
235         // Make use of the vec3 varyings
236         fragmentShader->append("\tretColor += vec4(");
237
238         for (GLint i = 0; i < vec3Count; i++)
239         {
240             fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
241             currentFSVarying += 1;
242         }
243
244         for (GLint i = 0; i < vec3ArrayCount; i++)
245         {
246             fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
247             currentFSVarying += 1;
248         }
249
250         fragmentShader->append("vec3(0.0, 0.0, 0.0), 0.0);\n");
251         fragmentShader->append("\tgl_FragColor = retColor;\n}");
252     }
253
254     std::string mSimpleVSSource;
255 };
256
257 TEST_F(GLSLTest, NamelessScopedStructs)
258 {
259     const std::string fragmentShaderSource = SHADER_SOURCE
260     (
261         precision mediump float;
262
263         void main()
264         {
265             struct
266             {
267                 float q;
268             } b;
269
270             gl_FragColor = vec4(1, 0, 0, 1);
271             gl_FragColor.a += b.q;
272         }
273     );
274
275     GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
276     EXPECT_NE(0u, program);
277 }
278 TEST_F(GLSLTest, ScopedStructsOrderBug)
279 {
280     const std::string fragmentShaderSource = SHADER_SOURCE
281     (
282         precision mediump float;
283
284         struct T
285         {
286             float f;
287         };
288
289         void main()
290         {
291             T a;
292
293             struct T
294             {
295                 float q;
296             };
297
298             T b;
299
300             gl_FragColor = vec4(1, 0, 0, 1);
301             gl_FragColor.a += a.f;
302             gl_FragColor.a += b.q;
303         }
304     );
305
306     GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
307     EXPECT_NE(0u, program);
308 }
309
310 TEST_F(GLSLTest, ScopedStructsBug)
311 {
312     const std::string fragmentShaderSource = SHADER_SOURCE
313     (
314         precision mediump float;
315
316         struct T_0
317         {
318             float f;
319         };
320
321         void main()
322         {
323             gl_FragColor = vec4(1, 0, 0, 1);
324
325             struct T
326             {
327                 vec2 v;
328             };
329
330             T_0 a;
331             T b;
332
333             gl_FragColor.a += a.f;
334             gl_FragColor.a += b.v.x;
335         }
336     );
337
338     GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
339     EXPECT_NE(0u, program);
340 }
341
342 TEST_F(GLSLTest, DxPositionBug)
343 {
344     const std::string &vertexShaderSource = SHADER_SOURCE
345     (
346         attribute vec4 inputAttribute;
347         varying float dx_Position;
348         void main()
349         {
350             gl_Position = vec4(inputAttribute);
351             dx_Position = 0.0;
352         }
353     );
354
355     const std::string &fragmentShaderSource = SHADER_SOURCE
356     (
357         precision mediump float;
358
359         varying float dx_Position;
360
361         void main()
362         {
363             gl_FragColor = vec4(dx_Position, 0, 0, 1);
364         }
365     );
366
367     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
368     EXPECT_NE(0u, program);
369 }
370
371 TEST_F(GLSLTest, ElseIfRewriting)
372 {
373     const std::string &vertexShaderSource =
374         "attribute vec4 a_position;\n"
375         "varying float v;\n"
376         "void main() {\n"
377         "  gl_Position = a_position;\n"
378         "  v = 1.0;\n"
379         "  if (a_position.x <= 0.5) {\n"
380         "    v = 0.0;\n"
381         "  } else if (a_position.x >= 0.5) {\n"
382         "    v = 2.0;\n"
383         "  }\n"
384         "}\n";
385
386     const std::string &fragmentShaderSource =
387         "precision highp float;\n"
388         "varying float v;\n"
389         "void main() {\n"
390         "  vec4 color = vec4(1.0, 0.0, 0.0, 1.0);\n"
391         "  if (v >= 1.0) color = vec4(0.0, 1.0, 0.0, 1.0);\n"
392         "  if (v >= 2.0) color = vec4(0.0, 0.0, 1.0, 1.0);\n"
393         "  gl_FragColor = color;\n"
394         "}\n";
395
396     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
397     ASSERT_NE(0u, program);
398
399     drawQuad(program, "a_position", 0.5f);
400     swapBuffers();
401
402     EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
403     EXPECT_PIXEL_EQ(getWindowWidth()-1, 0, 0, 255, 0, 255);
404 }
405
406 TEST_F(GLSLTest, TwoElseIfRewriting)
407 {
408     const std::string &vertexShaderSource =
409         "attribute vec4 a_position;\n"
410         "varying float v;\n"
411         "void main() {\n"
412         "  gl_Position = a_position;\n"
413         "  if (a_position.x == 0.0) {\n"
414         "    v = 1.0;\n"
415         "  } else if (a_position.x > 0.5) {\n"
416         "    v = 0.0;\n"
417         "  } else if (a_position.x > 0.75) {\n"
418         "    v = 0.5;\n"
419         "  }\n"
420         "}\n";
421
422     const std::string &fragmentShaderSource =
423         "precision highp float;\n"
424         "varying float v;\n"
425         "void main() {\n"
426         "  gl_FragColor = vec4(v, 0.0, 0.0, 1.0);\n"
427         "}\n";
428
429     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
430     EXPECT_NE(0u, program);
431 }
432
433 TEST_F(GLSLTest, InvariantVaryingOut)
434 {
435     const std::string fragmentShaderSource = SHADER_SOURCE
436     (
437         precision mediump float;
438         varying float v_varying;
439         void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
440     );
441
442     const std::string vertexShaderSource = SHADER_SOURCE
443     (
444         attribute vec4 a_position;
445         invariant varying float v_varying;
446         void main() { v_varying = a_position.x; gl_Position = a_position; }
447     );
448
449     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
450     EXPECT_NE(0u, program);
451 }
452
453 TEST_F(GLSLTest, FrontFacingAndVarying)
454 {
455     const std::string vertexShaderSource = SHADER_SOURCE
456     (
457         attribute vec4 a_position;
458         varying float v_varying;
459         void main()
460         {
461             v_varying = a_position.x;
462             gl_Position = a_position;
463         }
464     );
465
466     const std::string fragmentShaderSource = SHADER_SOURCE
467     (
468         precision mediump float;
469         varying float v_varying;
470         void main()
471         {
472             vec4 c;
473
474             if (gl_FrontFacing)
475             {
476                 c = vec4(v_varying, 0, 0, 1.0);
477             }
478             else
479             {
480                 c = vec4(0, v_varying, 0, 1.0);
481             }
482             gl_FragColor = c;
483         }
484     );
485
486     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
487     EXPECT_NE(0u, program);
488 }
489
490 TEST_F(GLSLTest, InvariantVaryingIn)
491 {
492     const std::string fragmentShaderSource = SHADER_SOURCE
493     (
494         precision mediump float;
495         invariant varying float v_varying;
496         void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
497     );
498
499     const std::string vertexShaderSource = SHADER_SOURCE
500     (
501         attribute vec4 a_position;
502         varying float v_varying;
503         void main() { v_varying = a_position.x; gl_Position = a_position; }
504     );
505
506     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
507     EXPECT_NE(0u, program);
508 }
509
510 TEST_F(GLSLTest, InvariantVaryingBoth)
511 {
512     const std::string fragmentShaderSource = SHADER_SOURCE
513     (
514         precision mediump float;
515         invariant varying float v_varying;
516         void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
517     );
518
519     const std::string vertexShaderSource = SHADER_SOURCE
520     (
521         attribute vec4 a_position;
522         invariant varying float v_varying;
523         void main() { v_varying = a_position.x; gl_Position = a_position; }
524     );
525
526     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
527     EXPECT_NE(0u, program);
528 }
529
530 TEST_F(GLSLTest, InvariantGLPosition)
531 {
532     const std::string fragmentShaderSource = SHADER_SOURCE
533     (
534         precision mediump float;
535         varying float v_varying;
536         void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
537     );
538
539     const std::string vertexShaderSource = SHADER_SOURCE
540     (
541         attribute vec4 a_position;
542         invariant gl_Position;
543         varying float v_varying;
544         void main() { v_varying = a_position.x; gl_Position = a_position; }
545     );
546
547     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
548     EXPECT_NE(0u, program);
549 }
550
551 TEST_F(GLSLTest, InvariantAll)
552 {
553     const std::string fragmentShaderSource = SHADER_SOURCE
554     (
555         precision mediump float;
556         varying float v_varying;
557         void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
558     );
559
560     const std::string vertexShaderSource =
561         "#pragma STDGL invariant(all)\n"
562         "attribute vec4 a_position;\n"
563         "varying float v_varying;\n"
564         "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
565
566     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
567     EXPECT_NE(0u, program);
568 }
569
570 TEST_F(GLSLTest, MaxVaryingVec3)
571 {
572     GLint maxVaryings = 0;
573     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
574
575     std::string fragmentShaderSource;
576     std::string vertexShaderSource;
577
578     GenerateGLSLWithVaryings(0, 0, 0, 0, maxVaryings, 0, &fragmentShaderSource, &vertexShaderSource);
579
580     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
581     EXPECT_NE(0u, program);
582 }
583
584 TEST_F(GLSLTest, MaxVaryingVec3Array)
585 {
586     GLint maxVaryings = 0;
587     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
588
589     std::string fragmentShaderSource;
590     std::string vertexShaderSource;
591
592     GenerateGLSLWithVaryings(0, 0, 0, 0, 0, maxVaryings / 2, &fragmentShaderSource, &vertexShaderSource);
593
594     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
595     EXPECT_NE(0u, program);
596 }
597
598 TEST_F(GLSLTest, MaxVaryingVec3AndOneFloat)
599 {
600     GLint maxVaryings = 0;
601     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
602
603     std::string fragmentShaderSource;
604     std::string vertexShaderSource;
605
606     GenerateGLSLWithVaryings(1, 0, 0, 0, maxVaryings, 0, &fragmentShaderSource, &vertexShaderSource);
607
608     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
609     EXPECT_NE(0u, program);
610 }
611
612 TEST_F(GLSLTest, MaxVaryingVec3ArrayAndOneFloatArray)
613 {
614     GLint maxVaryings = 0;
615     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
616
617     std::string fragmentShaderSource;
618     std::string vertexShaderSource;
619
620     GenerateGLSLWithVaryings(0, 1, 0, 0, 0, maxVaryings / 2, &fragmentShaderSource, &vertexShaderSource);
621
622     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
623     EXPECT_NE(0u, program);
624 }
625
626 TEST_F(GLSLTest, TwiceMaxVaryingVec2)
627 {
628     GLint maxVaryings = 0;
629     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
630
631     std::string fragmentShaderSource;
632     std::string vertexShaderSource;
633
634     GenerateGLSLWithVaryings(0, 0, 2 * maxVaryings, 0, 0, 0, &fragmentShaderSource, &vertexShaderSource);
635
636     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
637     EXPECT_NE(0u, program);
638 }
639
640 TEST_F(GLSLTest, MaxVaryingVec2Arrays)
641 {
642     GLint maxVaryings = 0;
643     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
644
645     std::string fragmentShaderSource;
646     std::string vertexShaderSource;
647
648     GenerateGLSLWithVaryings(0, 0, 0, maxVaryings, 0, 0, &fragmentShaderSource, &vertexShaderSource);
649
650     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
651     EXPECT_NE(0u, program);
652 }
653
654 TEST_F(GLSLTest, MaxPlusOneVaryingVec3)
655 {
656     GLint maxVaryings = 0;
657     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
658
659     std::string fragmentShaderSource;
660     std::string vertexShaderSource;
661
662     GenerateGLSLWithVaryings(0, 0, 0, 0, maxVaryings + 1, 0, &fragmentShaderSource, &vertexShaderSource);
663
664     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
665     EXPECT_EQ(0u, program);
666 }
667
668 TEST_F(GLSLTest, MaxPlusOneVaryingVec3Array)
669 {
670     GLint maxVaryings = 0;
671     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
672
673     std::string fragmentShaderSource;
674     std::string vertexShaderSource;
675
676     GenerateGLSLWithVaryings(0, 0, 0, 0, 0, maxVaryings / 2 + 1, &fragmentShaderSource, &vertexShaderSource);
677
678     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
679     EXPECT_EQ(0u, program);
680 }
681
682 TEST_F(GLSLTest, MaxVaryingVec3AndOneVec2)
683 {
684     GLint maxVaryings = 0;
685     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
686
687     std::string fragmentShaderSource;
688     std::string vertexShaderSource;
689
690     GenerateGLSLWithVaryings(0, 0, 1, 0, maxVaryings, 0, &fragmentShaderSource, &vertexShaderSource);
691
692     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
693     EXPECT_EQ(0u, program);
694 }
695
696 TEST_F(GLSLTest, MaxPlusOneVaryingVec2)
697 {
698     GLint maxVaryings = 0;
699     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
700
701     std::string fragmentShaderSource;
702     std::string vertexShaderSource;
703
704     GenerateGLSLWithVaryings(0, 0, 2 * maxVaryings + 1, 0, 0, 0, &fragmentShaderSource, &vertexShaderSource);
705
706     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
707     EXPECT_EQ(0u, program);
708 }
709
710 TEST_F(GLSLTest, MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
711 {
712     GLint maxVaryings = 0;
713     glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
714
715     std::string fragmentShaderSource;
716     std::string vertexShaderSource;
717
718     GenerateGLSLWithVaryings(0, maxVaryings / 2 + 1, 0, 0, 0, maxVaryings / 2, &fragmentShaderSource, &vertexShaderSource);
719
720     GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
721     EXPECT_EQ(0u, program);
722 }