• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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