3 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
4 typedef ::testing::Types<TFT<Gles::Two, Rend::D3D11>, TFT<Gles::Two, Rend::D3D9>> TestFixtureTypes;
5 TYPED_TEST_CASE(GLSLTest, TestFixtureTypes);
8 class GLSLTest : public ANGLETest
11 GLSLTest() : ANGLETest(T::GetGlesMajorVersion(), T::GetRequestedRenderer())
16 setConfigGreenBits(8);
18 setConfigAlphaBits(8);
25 mSimpleVSSource = SHADER_SOURCE
27 attribute vec4 inputAttribute;
30 gl_Position = inputAttribute;
35 std::string GenerateVaryingType(GLint vectorSize)
41 sprintf(varyingType, "float");
45 sprintf(varyingType, "vec%d", vectorSize);
48 return std::string(varyingType);
51 std::string GenerateVectorVaryingDeclaration(GLint vectorSize, GLint arraySize, GLint id)
57 sprintf(buff, "varying %s v%d;\n", GenerateVaryingType(vectorSize).c_str(), id);
61 sprintf(buff, "varying %s v%d[%d];\n", GenerateVaryingType(vectorSize).c_str(), id, arraySize);
64 return std::string(buff);
67 std::string GenerateVectorVaryingSettingCode(GLint vectorSize, GLint arraySize, GLint id)
69 std::string returnString;
74 sprintf(buff, "\t v%d = %s(1.0);\n", id, GenerateVaryingType(vectorSize).c_str());
79 for (int i = 0; i < arraySize; i++)
81 sprintf(buff, "\t v%d[%d] = %s(1.0);\n", id, i, GenerateVaryingType(vectorSize).c_str());
89 std::string GenerateVectorVaryingUseCode(GLint arraySize, GLint id)
94 sprintf(buff, "v%d + ", id);
95 return std::string(buff);
99 std::string returnString;
100 for (int i = 0; i < arraySize; i++)
103 sprintf(buff, "v%d[%d] + ", id, i);
104 returnString += buff;
110 void GenerateGLSLWithVaryings(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount, std::string* fragmentShader, std::string* vertexShader)
112 // Generate a string declaring the varyings, to share between the fragment shader and the vertex shader.
113 std::string varyingDeclaration;
115 unsigned int varyingCount = 0;
117 for (GLint i = 0; i < floatCount; i++)
119 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 1, varyingCount);
123 for (GLint i = 0; i < floatArrayCount; i++)
125 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 2, varyingCount);
129 for (GLint i = 0; i < vec2Count; i++)
131 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 1, varyingCount);
135 for (GLint i = 0; i < vec2ArrayCount; i++)
137 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 2, varyingCount);
141 for (GLint i = 0; i < vec3Count; i++)
143 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 1, varyingCount);
147 for (GLint i = 0; i < vec3ArrayCount; i++)
149 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 2, varyingCount);
153 // Generate the vertex shader
154 vertexShader->clear();
155 vertexShader->append(varyingDeclaration);
156 vertexShader->append("\nvoid main()\n{\n");
158 unsigned int currentVSVarying = 0;
160 for (GLint i = 0; i < floatCount; i++)
162 vertexShader->append(GenerateVectorVaryingSettingCode(1, 1, currentVSVarying));
163 currentVSVarying += 1;
166 for (GLint i = 0; i < floatArrayCount; i++)
168 vertexShader->append(GenerateVectorVaryingSettingCode(1, 2, currentVSVarying));
169 currentVSVarying += 1;
172 for (GLint i = 0; i < vec2Count; i++)
174 vertexShader->append(GenerateVectorVaryingSettingCode(2, 1, currentVSVarying));
175 currentVSVarying += 1;
178 for (GLint i = 0; i < vec2ArrayCount; i++)
180 vertexShader->append(GenerateVectorVaryingSettingCode(2, 2, currentVSVarying));
181 currentVSVarying += 1;
184 for (GLint i = 0; i < vec3Count; i++)
186 vertexShader->append(GenerateVectorVaryingSettingCode(3, 1, currentVSVarying));
187 currentVSVarying += 1;
190 for (GLint i = 0; i < vec3ArrayCount; i++)
192 vertexShader->append(GenerateVectorVaryingSettingCode(3, 2, currentVSVarying));
193 currentVSVarying += 1;
196 vertexShader->append("}\n");
198 // Generate the fragment shader
199 fragmentShader->clear();
200 fragmentShader->append("precision highp float;\n");
201 fragmentShader->append(varyingDeclaration);
202 fragmentShader->append("\nvoid main() \n{ \n\tvec4 retColor = vec4(0,0,0,0);\n");
204 unsigned int currentFSVarying = 0;
206 // Make use of the float varyings
207 fragmentShader->append("\tretColor += vec4(");
209 for (GLint i = 0; i < floatCount; i++)
211 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
212 currentFSVarying += 1;
215 for (GLint i = 0; i < floatArrayCount; i++)
217 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
218 currentFSVarying += 1;
221 fragmentShader->append("0.0, 0.0, 0.0, 0.0);\n");
223 // Make use of the vec2 varyings
224 fragmentShader->append("\tretColor += vec4(");
226 for (GLint i = 0; i < vec2Count; i++)
228 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
229 currentFSVarying += 1;
232 for (GLint i = 0; i < vec2ArrayCount; i++)
234 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
235 currentFSVarying += 1;
238 fragmentShader->append("vec2(0.0, 0.0), 0.0, 0.0);\n");
240 // Make use of the vec3 varyings
241 fragmentShader->append("\tretColor += vec4(");
243 for (GLint i = 0; i < vec3Count; i++)
245 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
246 currentFSVarying += 1;
249 for (GLint i = 0; i < vec3ArrayCount; i++)
251 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
252 currentFSVarying += 1;
255 fragmentShader->append("vec3(0.0, 0.0, 0.0), 0.0);\n");
256 fragmentShader->append("\tgl_FragColor = retColor;\n}");
259 std::string mSimpleVSSource;
262 TYPED_TEST(GLSLTest, NamelessScopedStructs)
264 const std::string fragmentShaderSource = SHADER_SOURCE
266 precision mediump float;
275 gl_FragColor = vec4(1, 0, 0, 1);
276 gl_FragColor.a += b.q;
280 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
281 EXPECT_NE(0u, program);
284 TYPED_TEST(GLSLTest, ScopedStructsOrderBug)
286 const std::string fragmentShaderSource = SHADER_SOURCE
288 precision mediump float;
306 gl_FragColor = vec4(1, 0, 0, 1);
307 gl_FragColor.a += a.f;
308 gl_FragColor.a += b.q;
312 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
313 EXPECT_NE(0u, program);
316 TYPED_TEST(GLSLTest, ScopedStructsBug)
318 const std::string fragmentShaderSource = SHADER_SOURCE
320 precision mediump float;
329 gl_FragColor = vec4(1, 0, 0, 1);
339 gl_FragColor.a += a.f;
340 gl_FragColor.a += b.v.x;
344 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
345 EXPECT_NE(0u, program);
348 TYPED_TEST(GLSLTest, DxPositionBug)
350 const std::string &vertexShaderSource = SHADER_SOURCE
352 attribute vec4 inputAttribute;
353 varying float dx_Position;
356 gl_Position = vec4(inputAttribute);
361 const std::string &fragmentShaderSource = SHADER_SOURCE
363 precision mediump float;
365 varying float dx_Position;
369 gl_FragColor = vec4(dx_Position, 0, 0, 1);
373 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
374 EXPECT_NE(0u, program);
377 TYPED_TEST(GLSLTest, ElseIfRewriting)
379 const std::string &vertexShaderSource =
380 "attribute vec4 a_position;\n"
383 " gl_Position = a_position;\n"
385 " if (a_position.x <= 0.5) {\n"
387 " } else if (a_position.x >= 0.5) {\n"
392 const std::string &fragmentShaderSource =
393 "precision highp float;\n"
396 " vec4 color = vec4(1.0, 0.0, 0.0, 1.0);\n"
397 " if (v >= 1.0) color = vec4(0.0, 1.0, 0.0, 1.0);\n"
398 " if (v >= 2.0) color = vec4(0.0, 0.0, 1.0, 1.0);\n"
399 " gl_FragColor = color;\n"
402 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
403 ASSERT_NE(0u, program);
405 drawQuad(program, "a_position", 0.5f);
408 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
409 EXPECT_PIXEL_EQ(getWindowWidth()-1, 0, 0, 255, 0, 255);
412 TYPED_TEST(GLSLTest, TwoElseIfRewriting)
414 const std::string &vertexShaderSource =
415 "attribute vec4 a_position;\n"
418 " gl_Position = a_position;\n"
419 " if (a_position.x == 0.0) {\n"
421 " } else if (a_position.x > 0.5) {\n"
423 " } else if (a_position.x > 0.75) {\n"
428 const std::string &fragmentShaderSource =
429 "precision highp float;\n"
432 " gl_FragColor = vec4(v, 0.0, 0.0, 1.0);\n"
435 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
436 EXPECT_NE(0u, program);
439 TYPED_TEST(GLSLTest, InvariantVaryingOut)
441 const std::string fragmentShaderSource = SHADER_SOURCE
443 precision mediump float;
444 varying float v_varying;
445 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
448 const std::string vertexShaderSource = SHADER_SOURCE
450 attribute vec4 a_position;
451 invariant varying float v_varying;
452 void main() { v_varying = a_position.x; gl_Position = a_position; }
455 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
456 EXPECT_NE(0u, program);
459 TYPED_TEST(GLSLTest, FrontFacingAndVarying)
461 const std::string vertexShaderSource = SHADER_SOURCE
463 attribute vec4 a_position;
464 varying float v_varying;
467 v_varying = a_position.x;
468 gl_Position = a_position;
472 const std::string fragmentShaderSource = SHADER_SOURCE
474 precision mediump float;
475 varying float v_varying;
482 c = vec4(v_varying, 0, 0, 1.0);
486 c = vec4(0, v_varying, 0, 1.0);
492 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
493 EXPECT_NE(0u, program);
496 TYPED_TEST(GLSLTest, InvariantVaryingIn)
498 const std::string fragmentShaderSource = SHADER_SOURCE
500 precision mediump float;
501 invariant varying float v_varying;
502 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
505 const std::string vertexShaderSource = SHADER_SOURCE
507 attribute vec4 a_position;
508 varying float v_varying;
509 void main() { v_varying = a_position.x; gl_Position = a_position; }
512 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
513 EXPECT_NE(0u, program);
516 TYPED_TEST(GLSLTest, InvariantVaryingBoth)
518 const std::string fragmentShaderSource = SHADER_SOURCE
520 precision mediump float;
521 invariant varying float v_varying;
522 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
525 const std::string vertexShaderSource = SHADER_SOURCE
527 attribute vec4 a_position;
528 invariant varying float v_varying;
529 void main() { v_varying = a_position.x; gl_Position = a_position; }
532 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
533 EXPECT_NE(0u, program);
536 TYPED_TEST(GLSLTest, InvariantGLPosition)
538 const std::string fragmentShaderSource = SHADER_SOURCE
540 precision mediump float;
541 varying float v_varying;
542 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
545 const std::string vertexShaderSource = SHADER_SOURCE
547 attribute vec4 a_position;
548 invariant gl_Position;
549 varying float v_varying;
550 void main() { v_varying = a_position.x; gl_Position = a_position; }
553 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
554 EXPECT_NE(0u, program);
557 TYPED_TEST(GLSLTest, InvariantAll)
559 const std::string fragmentShaderSource = SHADER_SOURCE
561 precision mediump float;
562 varying float v_varying;
563 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
566 const std::string vertexShaderSource =
567 "#pragma STDGL invariant(all)\n"
568 "attribute vec4 a_position;\n"
569 "varying float v_varying;\n"
570 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
572 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
573 EXPECT_NE(0u, program);
576 TYPED_TEST(GLSLTest, MaxVaryingVec3)
578 GLint maxVaryings = 0;
579 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
581 std::string fragmentShaderSource;
582 std::string vertexShaderSource;
584 GenerateGLSLWithVaryings(0, 0, 0, 0, maxVaryings, 0, &fragmentShaderSource, &vertexShaderSource);
586 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
587 EXPECT_NE(0u, program);
590 TYPED_TEST(GLSLTest, MaxVaryingVec3Array)
592 GLint maxVaryings = 0;
593 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
595 std::string fragmentShaderSource;
596 std::string vertexShaderSource;
598 GenerateGLSLWithVaryings(0, 0, 0, 0, 0, maxVaryings / 2, &fragmentShaderSource, &vertexShaderSource);
600 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
601 EXPECT_NE(0u, program);
604 // Disabled because of a failure in D3D9
605 TYPED_TEST(GLSLTest, DISABLED_MaxVaryingVec3AndOneFloat)
607 GLint maxVaryings = 0;
608 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
610 std::string fragmentShaderSource;
611 std::string vertexShaderSource;
613 GenerateGLSLWithVaryings(1, 0, 0, 0, maxVaryings, 0, &fragmentShaderSource, &vertexShaderSource);
615 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
616 EXPECT_NE(0u, program);
619 // Disabled because of a failure in D3D9
620 TYPED_TEST(GLSLTest, DISABLED_MaxVaryingVec3ArrayAndOneFloatArray)
622 GLint maxVaryings = 0;
623 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
625 std::string fragmentShaderSource;
626 std::string vertexShaderSource;
628 GenerateGLSLWithVaryings(0, 1, 0, 0, 0, maxVaryings / 2, &fragmentShaderSource, &vertexShaderSource);
630 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
631 EXPECT_NE(0u, program);
634 // Disabled because of a failure in D3D9
635 TYPED_TEST(GLSLTest, DISABLED_TwiceMaxVaryingVec2)
637 GLint maxVaryings = 0;
638 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
640 std::string fragmentShaderSource;
641 std::string vertexShaderSource;
643 GenerateGLSLWithVaryings(0, 0, 2 * maxVaryings, 0, 0, 0, &fragmentShaderSource, &vertexShaderSource);
645 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
646 EXPECT_NE(0u, program);
649 // Disabled because of a failure in D3D9
650 TYPED_TEST(GLSLTest, DISABLED_MaxVaryingVec2Arrays)
652 GLint maxVaryings = 0;
653 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
655 std::string fragmentShaderSource;
656 std::string vertexShaderSource;
658 GenerateGLSLWithVaryings(0, 0, 0, maxVaryings, 0, 0, &fragmentShaderSource, &vertexShaderSource);
660 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
661 EXPECT_NE(0u, program);
664 TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec3)
666 GLint maxVaryings = 0;
667 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
669 std::string fragmentShaderSource;
670 std::string vertexShaderSource;
672 GenerateGLSLWithVaryings(0, 0, 0, 0, maxVaryings + 1, 0, &fragmentShaderSource, &vertexShaderSource);
674 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
675 EXPECT_EQ(0u, program);
678 TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec3Array)
680 GLint maxVaryings = 0;
681 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
683 std::string fragmentShaderSource;
684 std::string vertexShaderSource;
686 GenerateGLSLWithVaryings(0, 0, 0, 0, 0, maxVaryings / 2 + 1, &fragmentShaderSource, &vertexShaderSource);
688 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
689 EXPECT_EQ(0u, program);
692 TYPED_TEST(GLSLTest, MaxVaryingVec3AndOneVec2)
694 GLint maxVaryings = 0;
695 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
697 std::string fragmentShaderSource;
698 std::string vertexShaderSource;
700 GenerateGLSLWithVaryings(0, 0, 1, 0, maxVaryings, 0, &fragmentShaderSource, &vertexShaderSource);
702 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
703 EXPECT_EQ(0u, program);
706 TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec2)
708 GLint maxVaryings = 0;
709 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
711 std::string fragmentShaderSource;
712 std::string vertexShaderSource;
714 GenerateGLSLWithVaryings(0, 0, 2 * maxVaryings + 1, 0, 0, 0, &fragmentShaderSource, &vertexShaderSource);
716 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
717 EXPECT_EQ(0u, program);
720 TYPED_TEST(GLSLTest, MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
722 GLint maxVaryings = 0;
723 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
725 std::string fragmentShaderSource;
726 std::string vertexShaderSource;
728 GenerateGLSLWithVaryings(0, maxVaryings / 2 + 1, 0, 0, 0, maxVaryings / 2, &fragmentShaderSource, &vertexShaderSource);
730 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
731 EXPECT_EQ(0u, program);