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 {
64 BLEND_EQUATION_MULTIPLY,
65 BLEND_EQUATION_SCREEN,
66 BLEND_EQUATION_OVERLAY,
67 BLEND_EQUATION_DARKEN,
68 BLEND_EQUATION_LIGHTEN,
69 BLEND_EQUATION_COLORDODGE,
70 BLEND_EQUATION_COLORBURN,
71 BLEND_EQUATION_HARDLIGHT,
72 BLEND_EQUATION_SOFTLIGHT,
73 BLEND_EQUATION_DIFFERENCE,
74 BLEND_EQUATION_EXCLUSION,
75 BLEND_EQUATION_HSL_HUE,
76 BLEND_EQUATION_HSL_SATURATION,
77 BLEND_EQUATION_HSL_COLOR,
78 BLEND_EQUATION_HSL_LUMINOSITY
79 };
80
getShaderLayoutEquation(BlendEquation equation)81 std::string getShaderLayoutEquation (BlendEquation equation)
82 {
83 switch (equation)
84 {
85 case BLEND_EQUATION_MULTIPLY: return "blend_support_multiply";
86 case BLEND_EQUATION_SCREEN: return "blend_support_screen";
87 case BLEND_EQUATION_OVERLAY: return "blend_support_overlay";
88 case BLEND_EQUATION_DARKEN: return "blend_support_darken";
89 case BLEND_EQUATION_LIGHTEN: return "blend_support_lighten";
90 case BLEND_EQUATION_COLORDODGE: return "blend_support_colordodge";
91 case BLEND_EQUATION_COLORBURN: return "blend_support_colorburn";
92 case BLEND_EQUATION_HARDLIGHT: return "blend_support_hardlight";
93 case BLEND_EQUATION_SOFTLIGHT: return "blend_support_softlight";
94 case BLEND_EQUATION_DIFFERENCE: return "blend_support_difference";
95 case BLEND_EQUATION_EXCLUSION: return "blend_support_exclusion";
96 case BLEND_EQUATION_HSL_HUE: return "blend_support_hsl_hue";
97 case BLEND_EQUATION_HSL_SATURATION: return "blend_support_hsl_saturation";
98 case BLEND_EQUATION_HSL_COLOR: return "blend_support_hsl_color";
99 case BLEND_EQUATION_HSL_LUMINOSITY: return "blend_support_hsl_luminosity";
100 case BLEND_EQUATION_ALL_EQUATIONS: return "blend_support_all_equations";
101 default:
102 DE_FATAL("Equation not supported.");
103 }
104 return DE_NULL;
105 }
106
getEquation(BlendEquation equation)107 glw::GLenum getEquation (BlendEquation equation)
108 {
109 switch (equation)
110 {
111 case BLEND_EQUATION_MULTIPLY: return GL_MULTIPLY;
112 case BLEND_EQUATION_SCREEN: return GL_SCREEN;
113 case BLEND_EQUATION_OVERLAY: return GL_OVERLAY;
114 case BLEND_EQUATION_DARKEN: return GL_DARKEN;
115 case BLEND_EQUATION_LIGHTEN: return GL_LIGHTEN;
116 case BLEND_EQUATION_COLORDODGE: return GL_COLORDODGE;
117 case BLEND_EQUATION_COLORBURN: return GL_COLORBURN;
118 case BLEND_EQUATION_HARDLIGHT: return GL_HARDLIGHT;
119 case BLEND_EQUATION_SOFTLIGHT: return GL_SOFTLIGHT;
120 case BLEND_EQUATION_DIFFERENCE: return GL_DIFFERENCE;
121 case BLEND_EQUATION_EXCLUSION: return GL_EXCLUSION;
122 case BLEND_EQUATION_HSL_HUE: return GL_HSL_HUE;
123 case BLEND_EQUATION_HSL_SATURATION: return GL_HSL_SATURATION;
124 case BLEND_EQUATION_HSL_COLOR: return GL_HSL_COLOR;
125 case BLEND_EQUATION_HSL_LUMINOSITY: return GL_HSL_LUMINOSITY;
126 default:
127 DE_FATAL("Equation not supported.");
128 }
129 return DE_NULL;
130 }
131
generateVertexShaderSource(NegativeTestContext & ctx)132 std::string generateVertexShaderSource (NegativeTestContext& ctx)
133 {
134 const bool supportsES32 = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
135 const glu::GLSLVersion version = supportsES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
136 std::ostringstream source;
137
138 source << glu::getGLSLVersionDeclaration(version) << "\n"
139 << "void main ()\n"
140 << "{\n"
141 << " gl_Position = vec4(0.0);\n"
142 << "}\n";
143
144 return source.str();
145 }
146
generateFragmentShaderSource(NegativeTestContext & ctx,BlendEquation equation)147 std::string generateFragmentShaderSource (NegativeTestContext& ctx, BlendEquation equation)
148 {
149 const bool supportsES32 = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
150 const glu::GLSLVersion version = supportsES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
151 std::ostringstream source;
152
153 source << glu::getGLSLVersionDeclaration(version) << "\n"
154 << (supportsES32 ? "" : "#extension GL_KHR_blend_equation_advanced : enable\n")
155 << "layout(" << getShaderLayoutEquation(equation) << ") out;\n"
156 << "layout(location=0) out mediump vec4 o_color;\n"
157 << "void main ()\n"
158 << "{\n"
159 << " o_color = vec4(0);\n"
160 << "}\n";
161
162 return source.str();
163 }
164
generateProgramSources(NegativeTestContext & ctx,BlendEquation equation)165 glu::ProgramSources generateProgramSources (NegativeTestContext& ctx, BlendEquation equation)
166 {
167 return glu::ProgramSources()
168 << glu::VertexSource(generateVertexShaderSource(ctx))
169 << glu::FragmentSource(generateFragmentShaderSource(ctx, equation));
170 }
171
blend_qualifier_mismatch(NegativeTestContext & ctx)172 void blend_qualifier_mismatch (NegativeTestContext& ctx)
173 {
174 TCU_CHECK_AND_THROW(NotSupportedError,
175 ctx.isExtensionSupported("GL_KHR_blend_equation_advanced") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
176 "This test requires support for the extension GL_KHR_blend_equation_advanced or context version 3.2 or higher.");
177
178 glw::GLuint vao = 0;
179 bool isES = glu::isContextTypeES(ctx.getRenderContext().getType());
180 if (!isES)
181 {
182 ctx.glGenVertexArrays(1, &vao);
183 ctx.glBindVertexArray(vao);
184 }
185
186 ctx.beginSection("GL_INVALID_OPERATION is generated if blending is enabled, and the blend qualifier is different from blend_support_all_equations and does not match the blend equation.");
187 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx)
188 {
189 glu::ShaderProgram program(ctx.getRenderContext(), generateProgramSources(ctx, s_equations[ndx]));
190
191 ctx.getLog() << program;
192 TCU_CHECK(program.isOk());
193
194 ctx.glUseProgram(program.getProgram());
195 ctx.expectError(GL_NO_ERROR);
196
197 for (int ndx2 = 0; ndx2 < DE_LENGTH_OF_ARRAY(s_equations); ++ndx2)
198 {
199 if (s_equations[ndx] == s_equations[ndx2])
200 continue;
201
202 ctx.glEnable(GL_BLEND);
203 ctx.glBlendEquation(getEquation(s_equations[ndx2]));
204 ctx.expectError(GL_NO_ERROR);
205 ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
206 ctx.expectError(GL_INVALID_OPERATION);
207
208 ctx.glDisable(GL_BLEND);
209 ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
210 ctx.expectError(GL_NO_ERROR);
211 }
212 }
213 ctx.endSection();
214
215 if (!isES)
216 ctx.glDeleteVertexArrays(1, &vao);
217 }
218
attachment_advanced_equation(NegativeTestContext & ctx)219 void attachment_advanced_equation (NegativeTestContext& ctx)
220 {
221 TCU_CHECK_AND_THROW(NotSupportedError,
222 ctx.isExtensionSupported("GL_KHR_blend_equation_advanced") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
223 "This test requires support for the extension GL_KHR_blend_equation_advanced or context version 3.2 or higher.");
224
225 glw::GLuint vao = 0;
226 glw::GLuint fbo = 0x1234;
227 glw::GLuint texture = 0x1234;
228 const glw::GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
229 const bool isES = glu::isContextTypeES(ctx.getRenderContext().getType());
230
231 if (!isES)
232 {
233 ctx.glGenVertexArrays(1, &vao);
234 ctx.glBindVertexArray(vao);
235 }
236
237 ctx.glGenTextures(1, &texture);
238 ctx.glBindTexture(GL_TEXTURE_2D, texture);
239 ctx.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
240 ctx.glGenFramebuffers(1, &fbo);
241 ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
242 ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
243 ctx.expectError(GL_NO_ERROR);
244 ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
245
246 ctx.beginSection("GL_INVALID_OPERATION is generated if blending is enabled, advanced equations are used, and the draw buffer for other color outputs is not NONE unless NVX_blend_equation_advanced_multi_draw_buffers is supported.");
247 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx)
248 {
249 glu::ShaderProgram program(ctx.getRenderContext(), generateProgramSources(ctx, s_equations[ndx]));
250 ctx.getLog() << program;
251 TCU_CHECK(program.isOk());
252
253 ctx.glUseProgram(program.getProgram());
254 ctx.glEnable(GL_BLEND);
255 ctx.glDrawBuffers(2, attachments);
256 ctx.expectError(GL_NO_ERROR);
257 ctx.glBlendEquation(getEquation(s_equations[ndx]));
258 ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
259 if (ctx.isExtensionSupported("GL_NVX_blend_equation_advanced_multi_draw_buffers"))
260 ctx.expectError(GL_NO_ERROR);
261 else
262 ctx.expectError(GL_INVALID_OPERATION);
263 }
264 ctx.endSection();
265
266 ctx.beginSection("GL_NO_ERROR is generated if no advanced blend equations are used.");
267 ctx.glBlendEquation(GL_FUNC_ADD);
268 ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
269 ctx.expectError(GL_NO_ERROR);
270 ctx.endSection();
271
272 ctx.beginSection("GL_NO_ERROR is generated if blending is disabled.");
273 ctx.glDisable(GL_BLEND);
274 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx)
275 {
276 ctx.glBlendEquation(getEquation(s_equations[ndx]));
277 ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
278 ctx.expectError(GL_NO_ERROR);
279 }
280 ctx.endSection();
281
282 if (!isES)
283 ctx.glDeleteVertexArrays(1, &vao);
284
285 ctx.glDeleteFramebuffers(1, &fbo);
286 ctx.glDeleteTextures(1, &texture);
287 }
288
289 } // anonymous
290
getNegativeAdvancedBlendEquationTestFunctions(void)291 std::vector<FunctionContainer> getNegativeAdvancedBlendEquationTestFunctions (void)
292 {
293 const FunctionContainer funcs[] =
294 {
295 {blend_qualifier_mismatch, "blend_qualifier_mismatch", "Test blend qualifier mismatch." },
296 {attachment_advanced_equation, "attachment_advanced_equation", "Test draw buffer for other color outputs." },
297 };
298
299 return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
300 }
301
302 } // NegativeTestShared
303 } // Functional
304 } // gles31
305 } // deqp
306