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 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 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 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 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 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 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 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."); 179 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx) 180 { 181 glu::ShaderProgram program(ctx.getRenderContext(), generateProgramSources(ctx, s_equations[ndx])); 182 183 ctx.getLog() << program; 184 TCU_CHECK(program.isOk()); 185 186 ctx.glUseProgram(program.getProgram()); 187 ctx.expectError(GL_NO_ERROR); 188 189 for (int ndx2 = 0; ndx2 < DE_LENGTH_OF_ARRAY(s_equations); ++ndx2) 190 { 191 if (s_equations[ndx] == s_equations[ndx2]) 192 continue; 193 194 ctx.glEnable(GL_BLEND); 195 ctx.glBlendEquation(getEquation(s_equations[ndx2])); 196 ctx.expectError(GL_NO_ERROR); 197 ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0); 198 ctx.expectError(GL_INVALID_OPERATION); 199 200 ctx.glDisable(GL_BLEND); 201 ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0); 202 ctx.expectError(GL_NO_ERROR); 203 } 204 } 205 ctx.endSection(); 206 } 207 208 void attachment_advanced_equation (NegativeTestContext& ctx) 209 { 210 TCU_CHECK_AND_THROW(NotSupportedError, 211 ctx.isExtensionSupported("GL_KHR_blend_equation_advanced") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), 212 "This test requires support for the extension GL_KHR_blend_equation_advanced or context version 3.2 or higher."); 213 214 glw::GLuint fbo = 0x1234; 215 glw::GLuint texture = 0x1234; 216 const glw::GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; 217 218 ctx.glGenTextures(1, &texture); 219 ctx.glBindTexture(GL_TEXTURE_2D, texture); 220 ctx.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 221 ctx.glGenFramebuffers(1, &fbo); 222 ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo); 223 ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); 224 ctx.expectError(GL_NO_ERROR); 225 ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER); 226 227 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."); 228 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx) 229 { 230 glu::ShaderProgram program(ctx.getRenderContext(), generateProgramSources(ctx, s_equations[ndx])); 231 ctx.getLog() << program; 232 TCU_CHECK(program.isOk()); 233 234 ctx.glUseProgram(program.getProgram()); 235 ctx.glEnable(GL_BLEND); 236 ctx.glDrawBuffers(2, attachments); 237 ctx.expectError(GL_NO_ERROR); 238 ctx.glBlendEquation(getEquation(s_equations[ndx])); 239 ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0); 240 if (ctx.isExtensionSupported("GL_NVX_blend_equation_advanced_multi_draw_buffers")) 241 ctx.expectError(GL_NO_ERROR); 242 else 243 ctx.expectError(GL_INVALID_OPERATION); 244 } 245 ctx.endSection(); 246 247 ctx.beginSection("GL_NO_ERROR is generated if no advanced blend equations are used."); 248 ctx.glBlendEquation(GL_FUNC_ADD); 249 ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0); 250 ctx.expectError(GL_NO_ERROR); 251 ctx.endSection(); 252 253 ctx.beginSection("GL_NO_ERROR is generated if blending is disabled."); 254 ctx.glDisable(GL_BLEND); 255 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx) 256 { 257 ctx.glBlendEquation(getEquation(s_equations[ndx])); 258 ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0); 259 ctx.expectError(GL_NO_ERROR); 260 } 261 ctx.endSection(); 262 263 ctx.glDeleteFramebuffers(1, &fbo); 264 ctx.glDeleteTextures(1, &texture); 265 } 266 267 } // anonymous 268 269 std::vector<FunctionContainer> getNegativeAdvancedBlendEquationTestFunctions (void) 270 { 271 const FunctionContainer funcs[] = 272 { 273 {blend_qualifier_mismatch, "blend_qualifier_mismatch", "Test blend qualifier mismatch." }, 274 {attachment_advanced_equation, "attachment_advanced_equation", "Test draw buffer for other color outputs." }, 275 }; 276 277 return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs)); 278 } 279 280 } // NegativeTestShared 281 } // Functional 282 } // gles31 283 } // deqp 284