3 class GLSLTest : public ANGLETest
11 setConfigGreenBits(8);
13 setConfigAlphaBits(8);
20 mSimpleVSSource = SHADER_SOURCE
22 attribute vec4 inputAttribute;
25 gl_Position = inputAttribute;
30 std::string GenerateVaryingType(GLint vectorSize)
36 sprintf(varyingType, "float");
40 sprintf(varyingType, "vec%d", vectorSize);
43 return std::string(varyingType);
46 std::string GenerateVectorVaryingDeclaration(GLint vectorSize, GLint arraySize, GLint id)
52 sprintf(buff, "varying %s v%d;\n", GenerateVaryingType(vectorSize).c_str(), id);
56 sprintf(buff, "varying %s v%d[%d];\n", GenerateVaryingType(vectorSize).c_str(), id, arraySize);
59 return std::string(buff);
62 std::string GenerateVectorVaryingSettingCode(GLint vectorSize, GLint arraySize, GLint id)
64 std::string returnString;
69 sprintf(buff, "\t v%d = %s(1.0);\n", id, GenerateVaryingType(vectorSize).c_str());
74 for (int i = 0; i < arraySize; i++)
76 sprintf(buff, "\t v%d[%d] = %s(1.0);\n", id, i, GenerateVaryingType(vectorSize).c_str());
84 std::string GenerateVectorVaryingUseCode(GLint arraySize, GLint id)
89 sprintf(buff, "v%d + ", id);
90 return std::string(buff);
94 std::string returnString;
95 for (int i = 0; i < arraySize; i++)
98 sprintf(buff, "v%d[%d] + ", id, i);
105 void GenerateGLSLWithVaryings(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount, std::string* fragmentShader, std::string* vertexShader)
107 // Generate a string declaring the varyings, to share between the fragment shader and the vertex shader.
108 std::string varyingDeclaration;
110 unsigned int varyingCount = 0;
112 for (GLint i = 0; i < floatCount; i++)
114 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 1, varyingCount);
118 for (GLint i = 0; i < floatArrayCount; i++)
120 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 2, varyingCount);
124 for (GLint i = 0; i < vec2Count; i++)
126 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 1, varyingCount);
130 for (GLint i = 0; i < vec2ArrayCount; i++)
132 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 2, varyingCount);
136 for (GLint i = 0; i < vec3Count; i++)
138 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 1, varyingCount);
142 for (GLint i = 0; i < vec3ArrayCount; i++)
144 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 2, varyingCount);
148 // Generate the vertex shader
149 vertexShader->clear();
150 vertexShader->append(varyingDeclaration);
151 vertexShader->append("\nvoid main()\n{\n");
153 unsigned int currentVSVarying = 0;
155 for (GLint i = 0; i < floatCount; i++)
157 vertexShader->append(GenerateVectorVaryingSettingCode(1, 1, currentVSVarying));
158 currentVSVarying += 1;
161 for (GLint i = 0; i < floatArrayCount; i++)
163 vertexShader->append(GenerateVectorVaryingSettingCode(1, 2, currentVSVarying));
164 currentVSVarying += 1;
167 for (GLint i = 0; i < vec2Count; i++)
169 vertexShader->append(GenerateVectorVaryingSettingCode(2, 1, currentVSVarying));
170 currentVSVarying += 1;
173 for (GLint i = 0; i < vec2ArrayCount; i++)
175 vertexShader->append(GenerateVectorVaryingSettingCode(2, 2, currentVSVarying));
176 currentVSVarying += 1;
179 for (GLint i = 0; i < vec3Count; i++)
181 vertexShader->append(GenerateVectorVaryingSettingCode(3, 1, currentVSVarying));
182 currentVSVarying += 1;
185 for (GLint i = 0; i < vec3ArrayCount; i++)
187 vertexShader->append(GenerateVectorVaryingSettingCode(3, 2, currentVSVarying));
188 currentVSVarying += 1;
191 vertexShader->append("}\n");
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");
199 unsigned int currentFSVarying = 0;
201 // Make use of the float varyings
202 fragmentShader->append("\tretColor += vec4(");
204 for (GLint i = 0; i < floatCount; i++)
206 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
207 currentFSVarying += 1;
210 for (GLint i = 0; i < floatArrayCount; i++)
212 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
213 currentFSVarying += 1;
216 fragmentShader->append("0.0, 0.0, 0.0, 0.0);\n");
218 // Make use of the vec2 varyings
219 fragmentShader->append("\tretColor += vec4(");
221 for (GLint i = 0; i < vec2Count; i++)
223 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
224 currentFSVarying += 1;
227 for (GLint i = 0; i < vec2ArrayCount; i++)
229 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
230 currentFSVarying += 1;
233 fragmentShader->append("vec2(0.0, 0.0), 0.0, 0.0);\n");
235 // Make use of the vec3 varyings
236 fragmentShader->append("\tretColor += vec4(");
238 for (GLint i = 0; i < vec3Count; i++)
240 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
241 currentFSVarying += 1;
244 for (GLint i = 0; i < vec3ArrayCount; i++)
246 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
247 currentFSVarying += 1;
250 fragmentShader->append("vec3(0.0, 0.0, 0.0), 0.0);\n");
251 fragmentShader->append("\tgl_FragColor = retColor;\n}");
254 std::string mSimpleVSSource;
257 TEST_F(GLSLTest, NamelessScopedStructs)
259 const std::string fragmentShaderSource = SHADER_SOURCE
261 precision mediump float;
270 gl_FragColor = vec4(1, 0, 0, 1);
271 gl_FragColor.a += b.q;
275 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
276 EXPECT_NE(0u, program);
278 TEST_F(GLSLTest, ScopedStructsOrderBug)
280 const std::string fragmentShaderSource = SHADER_SOURCE
282 precision mediump float;
300 gl_FragColor = vec4(1, 0, 0, 1);
301 gl_FragColor.a += a.f;
302 gl_FragColor.a += b.q;
306 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
307 EXPECT_NE(0u, program);
310 TEST_F(GLSLTest, ScopedStructsBug)
312 const std::string fragmentShaderSource = SHADER_SOURCE
314 precision mediump float;
323 gl_FragColor = vec4(1, 0, 0, 1);
333 gl_FragColor.a += a.f;
334 gl_FragColor.a += b.v.x;
338 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
339 EXPECT_NE(0u, program);
342 TEST_F(GLSLTest, DxPositionBug)
344 const std::string &vertexShaderSource = SHADER_SOURCE
346 attribute vec4 inputAttribute;
347 varying float dx_Position;
350 gl_Position = vec4(inputAttribute);
355 const std::string &fragmentShaderSource = SHADER_SOURCE
357 precision mediump float;
359 varying float dx_Position;
363 gl_FragColor = vec4(dx_Position, 0, 0, 1);
367 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
368 EXPECT_NE(0u, program);
371 TEST_F(GLSLTest, ElseIfRewriting)
373 const std::string &vertexShaderSource =
374 "attribute vec4 a_position;\n"
377 " gl_Position = a_position;\n"
379 " if (a_position.x <= 0.5) {\n"
381 " } else if (a_position.x >= 0.5) {\n"
386 const std::string &fragmentShaderSource =
387 "precision highp float;\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"
396 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
397 ASSERT_NE(0u, program);
399 drawQuad(program, "a_position", 0.5f);
402 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
403 EXPECT_PIXEL_EQ(getWindowWidth()-1, 0, 0, 255, 0, 255);
406 TEST_F(GLSLTest, TwoElseIfRewriting)
408 const std::string &vertexShaderSource =
409 "attribute vec4 a_position;\n"
412 " gl_Position = a_position;\n"
413 " if (a_position.x == 0.0) {\n"
415 " } else if (a_position.x > 0.5) {\n"
417 " } else if (a_position.x > 0.75) {\n"
422 const std::string &fragmentShaderSource =
423 "precision highp float;\n"
426 " gl_FragColor = vec4(v, 0.0, 0.0, 1.0);\n"
429 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
430 EXPECT_NE(0u, program);
433 TEST_F(GLSLTest, InvariantVaryingOut)
435 const std::string fragmentShaderSource = SHADER_SOURCE
437 precision mediump float;
438 varying float v_varying;
439 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
442 const std::string vertexShaderSource = SHADER_SOURCE
444 attribute vec4 a_position;
445 invariant varying float v_varying;
446 void main() { v_varying = a_position.x; gl_Position = a_position; }
449 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
450 EXPECT_NE(0u, program);
453 TEST_F(GLSLTest, FrontFacingAndVarying)
455 const std::string vertexShaderSource = SHADER_SOURCE
457 attribute vec4 a_position;
458 varying float v_varying;
461 v_varying = a_position.x;
462 gl_Position = a_position;
466 const std::string fragmentShaderSource = SHADER_SOURCE
468 precision mediump float;
469 varying float v_varying;
476 c = vec4(v_varying, 0, 0, 1.0);
480 c = vec4(0, v_varying, 0, 1.0);
486 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
487 EXPECT_NE(0u, program);
490 TEST_F(GLSLTest, InvariantVaryingIn)
492 const std::string fragmentShaderSource = SHADER_SOURCE
494 precision mediump float;
495 invariant varying float v_varying;
496 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
499 const std::string vertexShaderSource = SHADER_SOURCE
501 attribute vec4 a_position;
502 varying float v_varying;
503 void main() { v_varying = a_position.x; gl_Position = a_position; }
506 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
507 EXPECT_NE(0u, program);
510 TEST_F(GLSLTest, InvariantVaryingBoth)
512 const std::string fragmentShaderSource = SHADER_SOURCE
514 precision mediump float;
515 invariant varying float v_varying;
516 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
519 const std::string vertexShaderSource = SHADER_SOURCE
521 attribute vec4 a_position;
522 invariant varying float v_varying;
523 void main() { v_varying = a_position.x; gl_Position = a_position; }
526 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
527 EXPECT_NE(0u, program);
530 TEST_F(GLSLTest, InvariantGLPosition)
532 const std::string fragmentShaderSource = SHADER_SOURCE
534 precision mediump float;
535 varying float v_varying;
536 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
539 const std::string vertexShaderSource = SHADER_SOURCE
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; }
547 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
548 EXPECT_NE(0u, program);
551 TEST_F(GLSLTest, InvariantAll)
553 const std::string fragmentShaderSource = SHADER_SOURCE
555 precision mediump float;
556 varying float v_varying;
557 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
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";
566 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
567 EXPECT_NE(0u, program);
570 TEST_F(GLSLTest, MaxVaryingVec3)
572 GLint maxVaryings = 0;
573 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
575 std::string fragmentShaderSource;
576 std::string vertexShaderSource;
578 GenerateGLSLWithVaryings(0, 0, 0, 0, maxVaryings, 0, &fragmentShaderSource, &vertexShaderSource);
580 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
581 EXPECT_NE(0u, program);
584 TEST_F(GLSLTest, MaxVaryingVec3Array)
586 GLint maxVaryings = 0;
587 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
589 std::string fragmentShaderSource;
590 std::string vertexShaderSource;
592 GenerateGLSLWithVaryings(0, 0, 0, 0, 0, maxVaryings / 2, &fragmentShaderSource, &vertexShaderSource);
594 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
595 EXPECT_NE(0u, program);
598 TEST_F(GLSLTest, MaxVaryingVec3AndOneFloat)
600 GLint maxVaryings = 0;
601 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
603 std::string fragmentShaderSource;
604 std::string vertexShaderSource;
606 GenerateGLSLWithVaryings(1, 0, 0, 0, maxVaryings, 0, &fragmentShaderSource, &vertexShaderSource);
608 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
609 EXPECT_NE(0u, program);
612 TEST_F(GLSLTest, MaxVaryingVec3ArrayAndOneFloatArray)
614 GLint maxVaryings = 0;
615 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
617 std::string fragmentShaderSource;
618 std::string vertexShaderSource;
620 GenerateGLSLWithVaryings(0, 1, 0, 0, 0, maxVaryings / 2, &fragmentShaderSource, &vertexShaderSource);
622 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
623 EXPECT_NE(0u, program);
626 TEST_F(GLSLTest, TwiceMaxVaryingVec2)
628 GLint maxVaryings = 0;
629 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
631 std::string fragmentShaderSource;
632 std::string vertexShaderSource;
634 GenerateGLSLWithVaryings(0, 0, 2 * maxVaryings, 0, 0, 0, &fragmentShaderSource, &vertexShaderSource);
636 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
637 EXPECT_NE(0u, program);
640 TEST_F(GLSLTest, MaxVaryingVec2Arrays)
642 GLint maxVaryings = 0;
643 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
645 std::string fragmentShaderSource;
646 std::string vertexShaderSource;
648 GenerateGLSLWithVaryings(0, 0, 0, maxVaryings, 0, 0, &fragmentShaderSource, &vertexShaderSource);
650 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
651 EXPECT_NE(0u, program);
654 TEST_F(GLSLTest, MaxPlusOneVaryingVec3)
656 GLint maxVaryings = 0;
657 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
659 std::string fragmentShaderSource;
660 std::string vertexShaderSource;
662 GenerateGLSLWithVaryings(0, 0, 0, 0, maxVaryings + 1, 0, &fragmentShaderSource, &vertexShaderSource);
664 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
665 EXPECT_EQ(0u, program);
668 TEST_F(GLSLTest, MaxPlusOneVaryingVec3Array)
670 GLint maxVaryings = 0;
671 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
673 std::string fragmentShaderSource;
674 std::string vertexShaderSource;
676 GenerateGLSLWithVaryings(0, 0, 0, 0, 0, maxVaryings / 2 + 1, &fragmentShaderSource, &vertexShaderSource);
678 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
679 EXPECT_EQ(0u, program);
682 TEST_F(GLSLTest, MaxVaryingVec3AndOneVec2)
684 GLint maxVaryings = 0;
685 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
687 std::string fragmentShaderSource;
688 std::string vertexShaderSource;
690 GenerateGLSLWithVaryings(0, 0, 1, 0, maxVaryings, 0, &fragmentShaderSource, &vertexShaderSource);
692 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
693 EXPECT_EQ(0u, program);
696 TEST_F(GLSLTest, MaxPlusOneVaryingVec2)
698 GLint maxVaryings = 0;
699 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
701 std::string fragmentShaderSource;
702 std::string vertexShaderSource;
704 GenerateGLSLWithVaryings(0, 0, 2 * maxVaryings + 1, 0, 0, 0, &fragmentShaderSource, &vertexShaderSource);
706 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
707 EXPECT_EQ(0u, program);
710 TEST_F(GLSLTest, MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
712 GLint maxVaryings = 0;
713 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
715 std::string fragmentShaderSource;
716 std::string vertexShaderSource;
718 GenerateGLSLWithVaryings(0, maxVaryings / 2 + 1, 0, 0, 0, maxVaryings / 2, &fragmentShaderSource, &vertexShaderSource);
720 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
721 EXPECT_EQ(0u, program);