1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 Module
3 * -------------------------------------------------
4 *
5 * Copyright 2016 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Negative Advanced Blend Equation Tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "es31fNegativeAdvancedBlendEquationTests.hpp"
25
26 #include "gluShaderProgram.hpp"
27 #include "glwEnums.hpp"
28
29 namespace deqp
30 {
31 namespace gles31
32 {
33 namespace Functional
34 {
35 namespace NegativeTestShared
36 {
37 namespace
38 {
39
40 enum BlendEquation
41 {
42 BLEND_EQUATION_MULTIPLY = 0,
43 BLEND_EQUATION_SCREEN,
44 BLEND_EQUATION_OVERLAY,
45 BLEND_EQUATION_DARKEN,
46 BLEND_EQUATION_LIGHTEN,
47 BLEND_EQUATION_COLORDODGE,
48 BLEND_EQUATION_COLORBURN,
49 BLEND_EQUATION_HARDLIGHT,
50 BLEND_EQUATION_SOFTLIGHT,
51 BLEND_EQUATION_DIFFERENCE,
52 BLEND_EQUATION_EXCLUSION,
53 BLEND_EQUATION_HSL_HUE,
54 BLEND_EQUATION_HSL_SATURATION,
55 BLEND_EQUATION_HSL_COLOR,
56 BLEND_EQUATION_HSL_LUMINOSITY,
57 BLEND_EQUATION_ALL_EQUATIONS,
58
59 BLEND_EQUATION_LAST
60 };
61
62 static const BlendEquation s_equations[] = {
63 BLEND_EQUATION_MULTIPLY, BLEND_EQUATION_SCREEN, BLEND_EQUATION_OVERLAY, BLEND_EQUATION_DARKEN,
64 BLEND_EQUATION_LIGHTEN, BLEND_EQUATION_COLORDODGE, BLEND_EQUATION_COLORBURN, BLEND_EQUATION_HARDLIGHT,
65 BLEND_EQUATION_SOFTLIGHT, BLEND_EQUATION_DIFFERENCE, BLEND_EQUATION_EXCLUSION, BLEND_EQUATION_HSL_HUE,
66 BLEND_EQUATION_HSL_SATURATION, BLEND_EQUATION_HSL_COLOR, BLEND_EQUATION_HSL_LUMINOSITY};
67
getShaderLayoutEquation(BlendEquation equation)68 std::string getShaderLayoutEquation(BlendEquation equation)
69 {
70 switch (equation)
71 {
72 case BLEND_EQUATION_MULTIPLY:
73 return "blend_support_multiply";
74 case BLEND_EQUATION_SCREEN:
75 return "blend_support_screen";
76 case BLEND_EQUATION_OVERLAY:
77 return "blend_support_overlay";
78 case BLEND_EQUATION_DARKEN:
79 return "blend_support_darken";
80 case BLEND_EQUATION_LIGHTEN:
81 return "blend_support_lighten";
82 case BLEND_EQUATION_COLORDODGE:
83 return "blend_support_colordodge";
84 case BLEND_EQUATION_COLORBURN:
85 return "blend_support_colorburn";
86 case BLEND_EQUATION_HARDLIGHT:
87 return "blend_support_hardlight";
88 case BLEND_EQUATION_SOFTLIGHT:
89 return "blend_support_softlight";
90 case BLEND_EQUATION_DIFFERENCE:
91 return "blend_support_difference";
92 case BLEND_EQUATION_EXCLUSION:
93 return "blend_support_exclusion";
94 case BLEND_EQUATION_HSL_HUE:
95 return "blend_support_hsl_hue";
96 case BLEND_EQUATION_HSL_SATURATION:
97 return "blend_support_hsl_saturation";
98 case BLEND_EQUATION_HSL_COLOR:
99 return "blend_support_hsl_color";
100 case BLEND_EQUATION_HSL_LUMINOSITY:
101 return "blend_support_hsl_luminosity";
102 case BLEND_EQUATION_ALL_EQUATIONS:
103 return "blend_support_all_equations";
104 default:
105 DE_FATAL("Equation not supported.");
106 }
107 return "";
108 }
109
getEquation(BlendEquation equation)110 glw::GLenum getEquation(BlendEquation equation)
111 {
112 switch (equation)
113 {
114 case BLEND_EQUATION_MULTIPLY:
115 return GL_MULTIPLY;
116 case BLEND_EQUATION_SCREEN:
117 return GL_SCREEN;
118 case BLEND_EQUATION_OVERLAY:
119 return GL_OVERLAY;
120 case BLEND_EQUATION_DARKEN:
121 return GL_DARKEN;
122 case BLEND_EQUATION_LIGHTEN:
123 return GL_LIGHTEN;
124 case BLEND_EQUATION_COLORDODGE:
125 return GL_COLORDODGE;
126 case BLEND_EQUATION_COLORBURN:
127 return GL_COLORBURN;
128 case BLEND_EQUATION_HARDLIGHT:
129 return GL_HARDLIGHT;
130 case BLEND_EQUATION_SOFTLIGHT:
131 return GL_SOFTLIGHT;
132 case BLEND_EQUATION_DIFFERENCE:
133 return GL_DIFFERENCE;
134 case BLEND_EQUATION_EXCLUSION:
135 return GL_EXCLUSION;
136 case BLEND_EQUATION_HSL_HUE:
137 return GL_HSL_HUE;
138 case BLEND_EQUATION_HSL_SATURATION:
139 return GL_HSL_SATURATION;
140 case BLEND_EQUATION_HSL_COLOR:
141 return GL_HSL_COLOR;
142 case BLEND_EQUATION_HSL_LUMINOSITY:
143 return GL_HSL_LUMINOSITY;
144 default:
145 DE_FATAL("Equation not supported.");
146 }
147 return DE_NULL;
148 }
149
generateVertexShaderSource(NegativeTestContext & ctx)150 std::string generateVertexShaderSource(NegativeTestContext &ctx)
151 {
152 const bool supportsES32 = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
153 const glu::GLSLVersion version = supportsES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
154 std::ostringstream source;
155
156 source << glu::getGLSLVersionDeclaration(version) << "\n"
157 << "void main ()\n"
158 << "{\n"
159 << " gl_Position = vec4(0.0);\n"
160 << "}\n";
161
162 return source.str();
163 }
164
generateFragmentShaderSource(NegativeTestContext & ctx,BlendEquation equation)165 std::string generateFragmentShaderSource(NegativeTestContext &ctx, BlendEquation equation)
166 {
167 const bool supportsES32 = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
168 const glu::GLSLVersion version = supportsES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
169 std::ostringstream source;
170
171 source << glu::getGLSLVersionDeclaration(version) << "\n"
172 << (supportsES32 ? "" : "#extension GL_KHR_blend_equation_advanced : enable\n") << "layout("
173 << getShaderLayoutEquation(equation) << ") out;\n"
174 << "layout(location=0) out mediump vec4 o_color;\n"
175 << "void main ()\n"
176 << "{\n"
177 << " o_color = vec4(0);\n"
178 << "}\n";
179
180 return source.str();
181 }
182
generateProgramSources(NegativeTestContext & ctx,BlendEquation equation)183 glu::ProgramSources generateProgramSources(NegativeTestContext &ctx, BlendEquation equation)
184 {
185 return glu::ProgramSources() << glu::VertexSource(generateVertexShaderSource(ctx))
186 << glu::FragmentSource(generateFragmentShaderSource(ctx, equation));
187 }
188
blend_qualifier_mismatch(NegativeTestContext & ctx)189 void blend_qualifier_mismatch(NegativeTestContext &ctx)
190 {
191 TCU_CHECK_AND_THROW(NotSupportedError,
192 ctx.isExtensionSupported("GL_KHR_blend_equation_advanced") ||
193 contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
194 "This test requires support for the extension GL_KHR_blend_equation_advanced or context "
195 "version 3.2 or higher.");
196
197 glw::GLuint vao = 0;
198 bool isES = glu::isContextTypeES(ctx.getRenderContext().getType());
199 if (!isES)
200 {
201 ctx.glGenVertexArrays(1, &vao);
202 ctx.glBindVertexArray(vao);
203 }
204
205 ctx.beginSection("GL_INVALID_OPERATION is generated if blending is enabled, and the blend qualifier is different "
206 "from blend_support_all_equations and does not match the blend equation.");
207 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx)
208 {
209 glu::ShaderProgram program(ctx.getRenderContext(), generateProgramSources(ctx, s_equations[ndx]));
210
211 ctx.getLog() << program;
212 TCU_CHECK(program.isOk());
213
214 ctx.glUseProgram(program.getProgram());
215 ctx.expectError(GL_NO_ERROR);
216
217 for (int ndx2 = 0; ndx2 < DE_LENGTH_OF_ARRAY(s_equations); ++ndx2)
218 {
219 if (s_equations[ndx] == s_equations[ndx2])
220 continue;
221
222 ctx.glEnable(GL_BLEND);
223 ctx.glBlendEquation(getEquation(s_equations[ndx2]));
224 ctx.expectError(GL_NO_ERROR);
225 ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
226 ctx.expectError(GL_INVALID_OPERATION);
227
228 ctx.glDisable(GL_BLEND);
229 ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
230 ctx.expectError(GL_NO_ERROR);
231 }
232 }
233 ctx.endSection();
234
235 if (!isES)
236 ctx.glDeleteVertexArrays(1, &vao);
237 }
238
attachment_advanced_equation(NegativeTestContext & ctx)239 void attachment_advanced_equation(NegativeTestContext &ctx)
240 {
241 TCU_CHECK_AND_THROW(NotSupportedError,
242 ctx.isExtensionSupported("GL_KHR_blend_equation_advanced") ||
243 contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
244 "This test requires support for the extension GL_KHR_blend_equation_advanced or context "
245 "version 3.2 or higher.");
246
247 glw::GLuint vao = 0;
248 glw::GLuint fbo = 0x1234;
249 glw::GLuint texture = 0x1234;
250 const glw::GLenum attachments[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
251 const bool isES = glu::isContextTypeES(ctx.getRenderContext().getType());
252
253 if (!isES)
254 {
255 ctx.glGenVertexArrays(1, &vao);
256 ctx.glBindVertexArray(vao);
257 }
258
259 ctx.glGenTextures(1, &texture);
260 ctx.glBindTexture(GL_TEXTURE_2D, texture);
261 ctx.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
262 ctx.glGenFramebuffers(1, &fbo);
263 ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
264 ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
265 ctx.expectError(GL_NO_ERROR);
266 ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
267
268 ctx.beginSection(
269 "GL_INVALID_OPERATION is generated if blending is enabled, advanced equations are used, and the draw buffer "
270 "for other color outputs is not NONE unless NVX_blend_equation_advanced_multi_draw_buffers is supported.");
271 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx)
272 {
273 glu::ShaderProgram program(ctx.getRenderContext(), generateProgramSources(ctx, s_equations[ndx]));
274 ctx.getLog() << program;
275 TCU_CHECK(program.isOk());
276
277 ctx.glUseProgram(program.getProgram());
278 ctx.glEnable(GL_BLEND);
279 ctx.glDrawBuffers(2, attachments);
280 ctx.expectError(GL_NO_ERROR);
281 ctx.glBlendEquation(getEquation(s_equations[ndx]));
282 ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
283 if (ctx.isExtensionSupported("GL_NVX_blend_equation_advanced_multi_draw_buffers"))
284 ctx.expectError(GL_NO_ERROR);
285 else
286 ctx.expectError(GL_INVALID_OPERATION);
287 }
288 ctx.endSection();
289
290 ctx.beginSection("GL_NO_ERROR is generated if no advanced blend equations are used.");
291 ctx.glBlendEquation(GL_FUNC_ADD);
292 ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
293 ctx.expectError(GL_NO_ERROR);
294 ctx.endSection();
295
296 ctx.beginSection("GL_NO_ERROR is generated if blending is disabled.");
297 ctx.glDisable(GL_BLEND);
298 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx)
299 {
300 ctx.glBlendEquation(getEquation(s_equations[ndx]));
301 ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
302 ctx.expectError(GL_NO_ERROR);
303 }
304 ctx.endSection();
305
306 if (!isES)
307 ctx.glDeleteVertexArrays(1, &vao);
308
309 ctx.glDeleteFramebuffers(1, &fbo);
310 ctx.glDeleteTextures(1, &texture);
311 }
312
313 } // namespace
314
getNegativeAdvancedBlendEquationTestFunctions(void)315 std::vector<FunctionContainer> getNegativeAdvancedBlendEquationTestFunctions(void)
316 {
317 const FunctionContainer funcs[] = {
318 {blend_qualifier_mismatch, "blend_qualifier_mismatch", "Test blend qualifier mismatch."},
319 {attachment_advanced_equation, "attachment_advanced_equation", "Test draw buffer for other color outputs."},
320 };
321
322 return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
323 }
324
325 } // namespace NegativeTestShared
326 } // namespace Functional
327 } // namespace gles31
328 } // namespace deqp
329