1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // EXT_blend_func_extended.cpp:
7 // Test for EXT_blend_func_extended_test
8 //
9
10 #include "tests/test_utils/ShaderExtensionTest.h"
11
12 namespace
13 {
14 const char EXTBFEPragma[] = "#extension GL_EXT_blend_func_extended : require\n";
15
16 const char ESSL100_SimpleShader1[] =
17 "precision mediump float;\n"
18 "void main() { \n"
19 " gl_FragColor = vec4(1.0);\n"
20 " gl_SecondaryFragColorEXT = vec4(gl_MaxDualSourceDrawBuffersEXT / 10);\n"
21 "}\n";
22
23 // Shader that tests only the access to gl_MaxDualSourceDrawBuffersEXT.
24 const char ESSL100_MaxDualSourceAccessShader[] =
25 "precision mediump float;\n"
26 "void main() { gl_FragColor = vec4(gl_MaxDualSourceDrawBuffersEXT / 10); }\n";
27
28 // Shader that writes to SecondaryFragData.
29 const char ESSL100_FragDataShader[] =
30 "#extension GL_EXT_draw_buffers : require\n"
31 "precision mediump float;\n"
32 "void main() {\n"
33 " gl_FragData[gl_MaxDrawBuffers - 1] = vec4(1.0);\n"
34 " gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT - 1] = vec4(0.1);\n"
35 "}\n";
36
37 // Shader that writes to SecondaryFragColor and SecondaryFragData does not compile.
38 const char ESSL100_ColorAndDataWriteFailureShader1[] =
39 "precision mediump float;\n"
40 "void main() {\n"
41 " gl_SecondaryFragColorEXT = vec4(1.0);\n"
42 " gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT] = vec4(0.1);\n"
43 "}\n";
44
45 // Shader that writes to FragColor and SecondaryFragData does not compile.
46 const char ESSL100_ColorAndDataWriteFailureShader2[] =
47 "precision mediump float;\n"
48 "void main() {\n"
49 " gl_FragColor = vec4(1.0);\n"
50 " gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT] = vec4(0.1);\n"
51 "}\n";
52
53 // Shader that writes to FragData and SecondaryFragColor.
54 const char ESSL100_ColorAndDataWriteFailureShader3[] =
55 "#extension GL_EXT_draw_buffers : require\n"
56 "precision mediump float;\n"
57 "void main() {\n"
58 " gl_SecondaryFragColorEXT = vec4(1.0);\n"
59 " gl_FragData[gl_MaxDrawBuffers] = vec4(0.1);\n"
60 "}\n";
61
62 // In GLSL version 300 es, the gl_MaxDualSourceDrawBuffersEXT is available.
63 const char ESSL300_MaxDualSourceAccessShader[] =
64 "precision mediump float;\n"
65 "layout(location = 0) out mediump vec4 fragColor;"
66 "void main() {\n"
67 " fragColor = vec4(gl_MaxDualSourceDrawBuffersEXT / 10);\n"
68 "}\n";
69
70 // In ES 3.0, the locations can be assigned through the API with glBindFragDataLocationIndexedEXT.
71 // It's fine to have a mix of specified and unspecified locations.
72 const char ESSL300_LocationAndUnspecifiedOutputShader[] =
73 "precision mediump float;\n"
74 "layout(location = 0) out mediump vec4 fragColor;"
75 "out mediump vec4 secondaryFragColor;"
76 "void main() {\n"
77 " fragColor = vec4(1.0);\n"
78 " secondaryFragColor = vec4(1.0);\n"
79 "}\n";
80
81 // It's also fine to leave locations completely unspecified.
82 const char ESSL300_TwoUnspecifiedLocationOutputsShader[] =
83 "precision mediump float;\n"
84 "out mediump vec4 fragColor;"
85 "out mediump vec4 secondaryFragColor;"
86 "void main() {\n"
87 " fragColor = vec4(1.0);\n"
88 " secondaryFragColor = vec4(1.0);\n"
89 "}\n";
90
91 // Shader that is specifies two outputs with the same location but different indexes is valid.
92 const char ESSL300_LocationIndexShader[] =
93 R"(precision mediump float;
94 layout(location = 0) out mediump vec4 fragColor;
95 layout(location = 0, index = 1) out mediump vec4 secondaryFragColor;
96 void main() {
97 fragColor = vec4(1);
98 secondaryFragColor = vec4(1);
99 })";
100
101 // Shader that specifies index layout qualifier but not location fails to compile.
102 const char ESSL300_LocationIndexFailureShader[] =
103 R"(precision mediump float;
104 layout(index = 0) out vec4 fragColor;
105 void main() {
106 fragColor = vec4(1.0);
107 })";
108
109 // Shader that specifies index layout qualifier multiple times fails to compile.
110 const char ESSL300_DoubleIndexFailureShader[] =
111 R"(precision mediump float;
112 layout(index = 0, location = 0, index = 1) out vec4 fragColor;
113 void main() {
114 fragColor = vec4(1.0);
115 })";
116
117 // Global index layout qualifier fails.
118 const char ESSL300_GlobalIndexFailureShader[] =
119 R"(precision mediump float;
120 layout(index = 0);
121 out vec4 fragColor;
122 void main() {
123 fragColor = vec4(1.0);
124 })";
125
126 // Index layout qualifier on a non-output variable fails.
127 const char ESSL300_IndexOnUniformVariableFailureShader[] =
128 R"(precision mediump float;
129 layout(index = 0) uniform vec4 u;
130 out vec4 fragColor;
131 void main() {
132 fragColor = u;
133 })";
134
135 // Index layout qualifier on a struct fails.
136 const char ESSL300_IndexOnStructFailureShader[] =
137 R"(precision mediump float;
138 layout(index = 0) struct S {
139 vec4 field;
140 };
141 out vec4 fragColor;
142 void main() {
143 fragColor = vec4(1.0);
144 })";
145
146 // Index layout qualifier on a struct member fails.
147 const char ESSL300_IndexOnStructFieldFailureShader[] =
148 R"(precision mediump float;
149 struct S {
150 layout(index = 0) vec4 field;
151 };
152 out mediump vec4 fragColor;
153 void main() {
154 fragColor = vec4(1.0);
155 })";
156
157 class EXTBlendFuncExtendedTest : public sh::ShaderExtensionTest
158 {
159 protected:
SetUp()160 void SetUp() override
161 {
162 sh::ShaderExtensionTest::SetUp();
163 // EXT_draw_buffers is used in some of the shaders for test purposes.
164 mResources.EXT_draw_buffers = 1;
165 mResources.NV_draw_buffers = 2;
166 }
167 };
168
169 // Extension flag is required to compile properly. Expect failure when it is
170 // not present.
TEST_P(EXTBlendFuncExtendedTest,CompileFailsWithoutExtension)171 TEST_P(EXTBlendFuncExtendedTest, CompileFailsWithoutExtension)
172 {
173 mResources.EXT_blend_func_extended = 0;
174 InitializeCompiler();
175 EXPECT_FALSE(TestShaderCompile(EXTBFEPragma));
176 }
177
178 // Extension directive is required to compile properly. Expect failure when
179 // it is not present.
TEST_P(EXTBlendFuncExtendedTest,CompileFailsWithExtensionWithoutPragma)180 TEST_P(EXTBlendFuncExtendedTest, CompileFailsWithExtensionWithoutPragma)
181 {
182 mResources.EXT_blend_func_extended = 1;
183 mResources.MaxDualSourceDrawBuffers = 1;
184 InitializeCompiler();
185 EXPECT_FALSE(TestShaderCompile(""));
186 }
187
188 // With extension flag and extension directive, compiling succeeds.
189 // Also test that the extension directive state is reset correctly.
TEST_P(EXTBlendFuncExtendedTest,CompileSucceedsWithExtensionAndPragma)190 TEST_P(EXTBlendFuncExtendedTest, CompileSucceedsWithExtensionAndPragma)
191 {
192 mResources.EXT_blend_func_extended = 1;
193 mResources.MaxDualSourceDrawBuffers = 1;
194 InitializeCompiler();
195 EXPECT_TRUE(TestShaderCompile(EXTBFEPragma));
196 // Test reset functionality.
197 EXPECT_FALSE(TestShaderCompile(""));
198 EXPECT_TRUE(TestShaderCompile(EXTBFEPragma));
199 }
200
201 // The SL #version 100 shaders that are correct work similarly
202 // in both GL2 and GL3, with and without the version string.
203 INSTANTIATE_TEST_SUITE_P(CorrectESSL100Shaders,
204 EXTBlendFuncExtendedTest,
205 Combine(Values(SH_GLES2_SPEC, SH_GLES3_SPEC),
206 Values("", sh::ESSLVersion100),
207 Values(ESSL100_SimpleShader1,
208 ESSL100_MaxDualSourceAccessShader,
209 ESSL100_FragDataShader)));
210
211 INSTANTIATE_TEST_SUITE_P(CorrectESSL300Shaders,
212 EXTBlendFuncExtendedTest,
213 Combine(Values(SH_GLES3_SPEC),
214 Values(sh::ESSLVersion300),
215 Values(ESSL300_MaxDualSourceAccessShader,
216 ESSL300_LocationAndUnspecifiedOutputShader,
217 ESSL300_TwoUnspecifiedLocationOutputsShader,
218 ESSL300_LocationIndexShader)));
219
220 class EXTBlendFuncExtendedCompileFailureTest : public EXTBlendFuncExtendedTest
221 {};
222
TEST_P(EXTBlendFuncExtendedCompileFailureTest,CompileFails)223 TEST_P(EXTBlendFuncExtendedCompileFailureTest, CompileFails)
224 {
225 // Expect compile failure due to shader error, with shader having correct pragma.
226 mResources.EXT_blend_func_extended = 1;
227 mResources.MaxDualSourceDrawBuffers = 1;
228 InitializeCompiler();
229 EXPECT_FALSE(TestShaderCompile(EXTBFEPragma));
230 }
231
232 // Incorrect #version 100 shaders fail.
233 INSTANTIATE_TEST_SUITE_P(IncorrectESSL100Shaders,
234 EXTBlendFuncExtendedCompileFailureTest,
235 Combine(Values(SH_GLES2_SPEC),
236 Values(sh::ESSLVersion100),
237 Values(ESSL100_ColorAndDataWriteFailureShader1,
238 ESSL100_ColorAndDataWriteFailureShader2,
239 ESSL100_ColorAndDataWriteFailureShader3)));
240
241 // Correct #version 300 es shaders fail in GLES2 context, regardless of version string.
242 INSTANTIATE_TEST_SUITE_P(CorrectESSL300Shaders,
243 EXTBlendFuncExtendedCompileFailureTest,
244 Combine(Values(SH_GLES2_SPEC),
245 Values("", sh::ESSLVersion100, sh::ESSLVersion300),
246 Values(ESSL300_LocationAndUnspecifiedOutputShader,
247 ESSL300_TwoUnspecifiedLocationOutputsShader)));
248
249 // Correct #version 100 shaders fail when used with #version 300 es.
250 INSTANTIATE_TEST_SUITE_P(CorrectESSL100Shaders,
251 EXTBlendFuncExtendedCompileFailureTest,
252 Combine(Values(SH_GLES3_SPEC),
253 Values(sh::ESSLVersion300),
254 Values(ESSL100_SimpleShader1, ESSL100_FragDataShader)));
255
256 // Incorrect #version 300 es shaders always fail.
257 INSTANTIATE_TEST_SUITE_P(IncorrectESSL300Shaders,
258 EXTBlendFuncExtendedCompileFailureTest,
259 Combine(Values(SH_GLES3_1_SPEC),
260 Values(sh::ESSLVersion300, sh::ESSLVersion310),
261 Values(ESSL300_LocationIndexFailureShader,
262 ESSL300_DoubleIndexFailureShader,
263 ESSL300_GlobalIndexFailureShader,
264 ESSL300_IndexOnUniformVariableFailureShader,
265 ESSL300_IndexOnStructFailureShader,
266 ESSL300_IndexOnStructFieldFailureShader)));
267
268 } // namespace
269