Branch :
//
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// EXT_blend_func_extended.cpp:
// Test for EXT_blend_func_extended_test
//
#include "tests/test_utils/ShaderExtensionTest.h"
namespace
{
const char EXTBFEPragma[] = "#extension GL_EXT_blend_func_extended : require\n";
const char ESSL100_SimpleShader1[] =
"precision mediump float;\n"
"void main() { \n"
" gl_FragColor = vec4(1.0);\n"
" gl_SecondaryFragColorEXT = vec4(gl_MaxDualSourceDrawBuffersEXT / 10);\n"
"}\n";
// Shader that tests only the access to gl_MaxDualSourceDrawBuffersEXT.
const char ESSL100_MaxDualSourceAccessShader[] =
"precision mediump float;\n"
"void main() { gl_FragColor = vec4(gl_MaxDualSourceDrawBuffersEXT / 10); }\n";
// Shader that writes to SecondaryFragData.
const char ESSL100_FragDataShader[] =
"#extension GL_EXT_draw_buffers : require\n"
"precision mediump float;\n"
"void main() {\n"
" gl_FragData[gl_MaxDrawBuffers - 1] = vec4(1.0);\n"
" gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT - 1] = vec4(0.1);\n"
"}\n";
// Shader that writes to SecondaryFragColor and SecondaryFragData does not compile.
const char ESSL100_ColorAndDataWriteFailureShader1[] =
"precision mediump float;\n"
"void main() {\n"
" gl_SecondaryFragColorEXT = vec4(1.0);\n"
" gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT] = vec4(0.1);\n"
"}\n";
// Shader that writes to FragColor and SecondaryFragData does not compile.
const char ESSL100_ColorAndDataWriteFailureShader2[] =
"precision mediump float;\n"
"void main() {\n"
" gl_FragColor = vec4(1.0);\n"
" gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT] = vec4(0.1);\n"
"}\n";
// Shader that writes to FragData and SecondaryFragColor.
const char ESSL100_ColorAndDataWriteFailureShader3[] =
"#extension GL_EXT_draw_buffers : require\n"
"precision mediump float;\n"
"void main() {\n"
" gl_SecondaryFragColorEXT = vec4(1.0);\n"
" gl_FragData[gl_MaxDrawBuffers] = vec4(0.1);\n"
"}\n";
// In GLSL version 300 es, the gl_MaxDualSourceDrawBuffersEXT is available.
const char ESSL300_MaxDualSourceAccessShader[] =
"precision mediump float;\n"
"layout(location = 0) out mediump vec4 fragColor;"
"void main() {\n"
" fragColor = vec4(gl_MaxDualSourceDrawBuffersEXT / 10);\n"
"}\n";
// In GLSL version 300 es, the only way to write a correct shader is to require the extension and
// then leave the locations unspecified. The caller will then bind the variables with the extension
// binding functions.
const char ESSL300_LocationAndUnspecifiedOutputShader[] =
"precision mediump float;\n"
"layout(location = 0) out mediump vec4 fragColor;"
"out mediump vec4 secondaryFragColor;"
"void main() {\n"
" fragColor = vec4(1.0);\n"
" secondaryFragColor = vec4(1.0);\n"
"}\n";
const char ESSL300_TwoUnspecifiedLocationOutputsShader[] =
"precision mediump float;\n"
"out mediump vec4 fragColor;"
"out mediump vec4 secondaryFragColor;"
"void main() {\n"
" fragColor = vec4(1.0);\n"
" secondaryFragColor = vec4(1.0);\n"
"}\n";
// Shader that is correct in GLSL ES 3.10 fails when used in version 300 es.
const char ESSL310_LocationIndexShader[] =
"precision mediump float;\n"
"layout(location = 0) out mediump vec4 fragColor;"
"layout(location = 0, index = 1) out mediump vec4 secondaryFragColor;"
"void main() {\n"
" fragColor = vec4(1);\n"
" secondaryFragColor = vec4(1);\n"
"}\n";
// Shader that specifies index layout qualifier but not location fails to compile. Currently fails
// to compile due to version 310 es not being supported.
const char ESSL310_LocationIndexFailureShader[] =
"precision mediump float;\n"
"layout(location = 0) out mediump vec4 fragColor;"
"layout(index = 1) out mediump vec4 secondaryFragColor;"
"void main() {\n"
" fragColor = vec4(1.0);\n"
" secondaryFragColor = vec4(1.0);\n"
"}\n";
class EXTBlendFuncExtendedTest : public sh::ShaderExtensionTest
{
protected:
void SetUp() override
{
sh::ShaderExtensionTest::SetUp();
// EXT_draw_buffers is used in some of the shaders for test purposes.
mResources.EXT_draw_buffers = 1;
mResources.NV_draw_buffers = 2;
}
};
// Extension flag is required to compile properly. Expect failure when it is
// not present.
TEST_P(EXTBlendFuncExtendedTest, CompileFailsWithoutExtension)
{
mResources.EXT_blend_func_extended = 0;
InitializeCompiler();
EXPECT_FALSE(TestShaderCompile(EXTBFEPragma));
}
// Extension directive is required to compile properly. Expect failure when
// it is not present.
TEST_P(EXTBlendFuncExtendedTest, CompileFailsWithExtensionWithoutPragma)
{
mResources.EXT_blend_func_extended = 1;
mResources.MaxDualSourceDrawBuffers = 1;
InitializeCompiler();
EXPECT_FALSE(TestShaderCompile(""));
}
// With extension flag and extension directive, compiling succeeds.
// Also test that the extension directive state is reset correctly.
TEST_P(EXTBlendFuncExtendedTest, CompileSucceedsWithExtensionAndPragma)
{
mResources.EXT_blend_func_extended = 1;
mResources.MaxDualSourceDrawBuffers = 1;
InitializeCompiler();
EXPECT_TRUE(TestShaderCompile(EXTBFEPragma));
// Test reset functionality.
EXPECT_FALSE(TestShaderCompile(""));
EXPECT_TRUE(TestShaderCompile(EXTBFEPragma));
}
// The SL #version 100 shaders that are correct work similarly
// in both GL2 and GL3, with and without the version string.
INSTANTIATE_TEST_CASE_P(CorrectESSL100Shaders,
EXTBlendFuncExtendedTest,
Combine(Values(SH_GLES2_SPEC, SH_GLES3_SPEC),
Values("", sh::ESSLVersion100),
Values(ESSL100_SimpleShader1,
ESSL100_MaxDualSourceAccessShader,
ESSL100_FragDataShader)));
INSTANTIATE_TEST_CASE_P(CorrectESSL300Shaders,
EXTBlendFuncExtendedTest,
Combine(Values(SH_GLES3_SPEC),
Values(sh::ESSLVersion300),
Values(ESSL300_MaxDualSourceAccessShader,
ESSL300_LocationAndUnspecifiedOutputShader,
ESSL300_TwoUnspecifiedLocationOutputsShader)));
class EXTBlendFuncExtendedCompileFailureTest : public EXTBlendFuncExtendedTest
{
};
TEST_P(EXTBlendFuncExtendedCompileFailureTest, CompileFails)
{
// Expect compile failure due to shader error, with shader having correct pragma.
mResources.EXT_blend_func_extended = 1;
mResources.MaxDualSourceDrawBuffers = 1;
InitializeCompiler();
EXPECT_FALSE(TestShaderCompile(EXTBFEPragma));
}
// Incorrect #version 100 shaders fail.
INSTANTIATE_TEST_CASE_P(IncorrectESSL100Shaders,
EXTBlendFuncExtendedCompileFailureTest,
Combine(Values(SH_GLES2_SPEC),
Values(sh::ESSLVersion100),
Values(ESSL100_ColorAndDataWriteFailureShader1,
ESSL100_ColorAndDataWriteFailureShader2,
ESSL100_ColorAndDataWriteFailureShader3)));
// Correct #version 300 es shaders fail in GLES2 context, regardless of version string.
INSTANTIATE_TEST_CASE_P(CorrectESSL300Shaders,
EXTBlendFuncExtendedCompileFailureTest,
Combine(Values(SH_GLES2_SPEC),
Values("", sh::ESSLVersion100, sh::ESSLVersion300),
Values(ESSL300_LocationAndUnspecifiedOutputShader,
ESSL300_TwoUnspecifiedLocationOutputsShader)));
// Correct #version 100 shaders fail when used with #version 300 es.
INSTANTIATE_TEST_CASE_P(CorrectESSL100Shaders,
EXTBlendFuncExtendedCompileFailureTest,
Combine(Values(SH_GLES3_SPEC),
Values(sh::ESSLVersion300),
Values(ESSL100_SimpleShader1, ESSL100_FragDataShader)));
// Incorrect #version 310 es always fails.
INSTANTIATE_TEST_CASE_P(IncorrectESSL310Shaders,
EXTBlendFuncExtendedCompileFailureTest,
Combine(Values(SH_GLES3_SPEC),
Values(sh::ESSLVersion300, sh::ESSLVersion310),
Values(ESSL310_LocationIndexFailureShader)));
// Correct #version 310 es fails in #version 300 es.
INSTANTIATE_TEST_CASE_P(
CorrectESSL310ShadersInESSL300,
EXTBlendFuncExtendedCompileFailureTest,
Values(make_tuple(SH_GLES3_SPEC, &sh::ESSLVersion300[0], &ESSL310_LocationIndexShader[0])));
// Correct #version 310 es fails in #version 310 es, due to 3.1 not being supported.
INSTANTIATE_TEST_CASE_P(
CorrectESSL310Shaders,
EXTBlendFuncExtendedCompileFailureTest,
Values(make_tuple(SH_GLES3_SPEC, &sh::ESSLVersion310[0], &ESSL310_LocationIndexShader[0])));
} // namespace