xref: /aosp_15_r20/external/deqp/modules/gles31/functional/es31fNegativeAdvancedBlendEquationTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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