es31fAdvancedBlendTests.cpp revision 3c827367444ee418f129b2c238299f49d3264554
1/*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.0 Module 3 * ------------------------------------------------- 4 * 5 * Copyright 2014 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 Advanced blending (GL_KHR_blend_equation_advanced) tests. 22 *//*--------------------------------------------------------------------*/ 23 24#include "es31fAdvancedBlendTests.hpp" 25#include "gluStrUtil.hpp" 26#include "glsFragmentOpUtil.hpp" 27#include "gluPixelTransfer.hpp" 28#include "gluObjectWrapper.hpp" 29#include "gluContextInfo.hpp" 30#include "gluShaderProgram.hpp" 31#include "tcuPixelFormat.hpp" 32#include "tcuTexture.hpp" 33#include "tcuTextureUtil.hpp" 34#include "tcuImageCompare.hpp" 35#include "tcuRenderTarget.hpp" 36#include "tcuTestLog.hpp" 37#include "tcuStringTemplate.hpp" 38#include "deRandom.hpp" 39#include "rrFragmentOperations.hpp" 40#include "sglrReferenceUtils.hpp" 41#include "glwEnums.hpp" 42#include "glwFunctions.hpp" 43 44#include <string> 45#include <vector> 46 47namespace deqp 48{ 49 50using gls::FragmentOpUtil::IntegerQuad; 51using gls::FragmentOpUtil::ReferenceQuadRenderer; 52using tcu::TextureLevel; 53using tcu::Vec2; 54using tcu::Vec4; 55using tcu::UVec4; 56using tcu::TestLog; 57using tcu::TextureFormat; 58using std::string; 59using std::vector; 60using std::map; 61 62namespace gles31 63{ 64namespace Functional 65{ 66 67namespace 68{ 69 70enum 71{ 72 MAX_VIEWPORT_WIDTH = 128, 73 MAX_VIEWPORT_HEIGHT = 128 74}; 75 76enum RenderTargetType 77{ 78 RENDERTARGETTYPE_DEFAULT = 0, //!< Default framebuffer 79 RENDERTARGETTYPE_SRGB_FBO, 80 RENDERTARGETTYPE_MSAA_FBO, 81 82 RENDERTARGETTYPE_LAST 83}; 84 85class AdvancedBlendCase : public TestCase 86{ 87public: 88 AdvancedBlendCase (Context& context, const char* name, const char* desc, deUint32 mode, int overdrawCount, bool coherent, RenderTargetType rtType); 89 90 ~AdvancedBlendCase (void); 91 92 void init (void); 93 void deinit (void); 94 95 IterateResult iterate (void); 96 97private: 98 AdvancedBlendCase (const AdvancedBlendCase&); 99 AdvancedBlendCase& operator= (const AdvancedBlendCase&); 100 101 const deUint32 m_blendMode; 102 const int m_overdrawCount; 103 const bool m_coherentBlending; 104 const RenderTargetType m_rtType; 105 const int m_numIters; 106 107 deUint32 m_colorRbo; 108 deUint32 m_fbo; 109 110 deUint32 m_resolveColorRbo; 111 deUint32 m_resolveFbo; 112 113 glu::ShaderProgram* m_program; 114 115 ReferenceQuadRenderer* m_referenceRenderer; 116 TextureLevel* m_refColorBuffer; 117 118 const int m_renderWidth; 119 const int m_renderHeight; 120 const int m_viewportWidth; 121 const int m_viewportHeight; 122 123 int m_iterNdx; 124}; 125 126AdvancedBlendCase::AdvancedBlendCase (Context& context, 127 const char* name, 128 const char* desc, 129 deUint32 mode, 130 int overdrawCount, 131 bool coherent, 132 RenderTargetType rtType) 133 : TestCase (context, name, desc) 134 , m_blendMode (mode) 135 , m_overdrawCount (overdrawCount) 136 , m_coherentBlending (coherent) 137 , m_rtType (rtType) 138 , m_numIters (5) 139 , m_colorRbo (0) 140 , m_fbo (0) 141 , m_resolveColorRbo (0) 142 , m_resolveFbo (0) 143 , m_program (DE_NULL) 144 , m_referenceRenderer (DE_NULL) 145 , m_refColorBuffer (DE_NULL) 146 , m_renderWidth (rtType != RENDERTARGETTYPE_DEFAULT ? 2*MAX_VIEWPORT_WIDTH : m_context.getRenderTarget().getWidth()) 147 , m_renderHeight (rtType != RENDERTARGETTYPE_DEFAULT ? 2*MAX_VIEWPORT_HEIGHT : m_context.getRenderTarget().getHeight()) 148 , m_viewportWidth (de::min<int>(m_renderWidth, MAX_VIEWPORT_WIDTH)) 149 , m_viewportHeight (de::min<int>(m_renderHeight, MAX_VIEWPORT_HEIGHT)) 150 , m_iterNdx (0) 151{ 152} 153 154const char* getBlendLayoutQualifier (rr::BlendEquationAdvanced equation) 155{ 156 static const char* s_qualifiers[] = 157 { 158 "blend_support_multiply", 159 "blend_support_screen", 160 "blend_support_overlay", 161 "blend_support_darken", 162 "blend_support_lighten", 163 "blend_support_colordodge", 164 "blend_support_colorburn", 165 "blend_support_hardlight", 166 "blend_support_softlight", 167 "blend_support_difference", 168 "blend_support_exclusion", 169 "blend_support_hsl_hue", 170 "blend_support_hsl_saturation", 171 "blend_support_hsl_color", 172 "blend_support_hsl_luminosity", 173 }; 174 DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_qualifiers) == rr::BLENDEQUATION_ADVANCED_LAST); 175 DE_ASSERT(de::inBounds<int>(equation, 0, rr::BLENDEQUATION_ADVANCED_LAST)); 176 return s_qualifiers[equation]; 177} 178 179glu::ProgramSources getBlendProgramSrc (rr::BlendEquationAdvanced equation) 180{ 181 static const char* s_vertSrc = "#version 310 es\n" 182 "in highp vec4 a_position;\n" 183 "in mediump vec4 a_color;\n" 184 "out mediump vec4 v_color;\n" 185 "void main()\n" 186 "{\n" 187 " gl_Position = a_position;\n" 188 " v_color = a_color;\n" 189 "}\n"; 190 static const char* s_fragSrc = "#version 310 es\n" 191 "#extension GL_KHR_blend_equation_advanced : require\n" 192 "in mediump vec4 v_color;\n" 193 "layout(${SUPPORT_QUALIFIER}) out;\n" 194 "layout(location = 0) out mediump vec4 o_color;\n" 195 "void main()\n" 196 "{\n" 197 " o_color = v_color;\n" 198 "}\n"; 199 200 map<string, string> args; 201 202 args["SUPPORT_QUALIFIER"] = getBlendLayoutQualifier(equation); 203 204 return glu::ProgramSources() 205 << glu::VertexSource(s_vertSrc) 206 << glu::FragmentSource(tcu::StringTemplate(s_fragSrc).specialize(args)); 207} 208 209void AdvancedBlendCase::init (void) 210{ 211 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 212 const bool useFbo = m_rtType != RENDERTARGETTYPE_DEFAULT; 213 const bool useSRGB = m_rtType == RENDERTARGETTYPE_SRGB_FBO; 214 215 if (!m_context.getContextInfo().isExtensionSupported("GL_KHR_blend_equation_advanced")) 216 throw tcu::NotSupportedError("GL_KHR_blend_equation_advanced is not supported", DE_NULL, __FILE__, __LINE__); 217 218 if (m_coherentBlending && !m_context.getContextInfo().isExtensionSupported("GL_KHR_blend_equation_advanced_coherent")) 219 throw tcu::NotSupportedError("GL_KHR_blend_equation_advanced_coherent is not supported", DE_NULL, __FILE__, __LINE__); 220 221 TCU_CHECK(gl.blendBarrierKHR); 222 223 DE_ASSERT(!m_program); 224 DE_ASSERT(!m_referenceRenderer); 225 DE_ASSERT(!m_refColorBuffer); 226 227 m_program = new glu::ShaderProgram(m_context.getRenderContext(), getBlendProgramSrc(sglr::rr_util::mapGLBlendEquationAdvanced(m_blendMode))); 228 m_testCtx.getLog() << *m_program; 229 230 if (!m_program->isOk()) 231 { 232 delete m_program; 233 m_program = DE_NULL; 234 TCU_FAIL("Compile failed"); 235 } 236 237 m_referenceRenderer = new ReferenceQuadRenderer; 238 m_refColorBuffer = new TextureLevel(TextureFormat(useSRGB ? TextureFormat::sRGBA : TextureFormat::RGBA, TextureFormat::UNORM_INT8), m_viewportWidth, m_viewportHeight); 239 240 if (useFbo) 241 { 242 const deUint32 format = useSRGB ? GL_SRGB8_ALPHA8 : GL_RGBA8; 243 const int numSamples = m_rtType == RENDERTARGETTYPE_MSAA_FBO ? 4 : 0; 244 245 m_testCtx.getLog() << TestLog::Message << "Using FBO of size (" << m_renderWidth << ", " << m_renderHeight << ") with format " 246 << glu::getPixelFormatStr(format) << " and " << numSamples << " samples" 247 << TestLog::EndMessage; 248 249 gl.genRenderbuffers(1, &m_colorRbo); 250 gl.bindRenderbuffer(GL_RENDERBUFFER, m_colorRbo); 251 gl.renderbufferStorageMultisample(GL_RENDERBUFFER, numSamples, format, m_renderWidth, m_renderHeight); 252 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create color RBO"); 253 254 gl.genFramebuffers(1, &m_fbo); 255 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo); 256 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRbo); 257 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create FBO"); 258 259 TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); 260 261 if (numSamples > 0) 262 { 263 // Create resolve FBO 264 gl.genRenderbuffers(1, &m_resolveColorRbo); 265 gl.bindRenderbuffer(GL_RENDERBUFFER, m_resolveColorRbo); 266 gl.renderbufferStorageMultisample(GL_RENDERBUFFER, 0, format, m_renderWidth, m_renderHeight); 267 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create resolve color RBO"); 268 269 gl.genFramebuffers(1, &m_resolveFbo); 270 gl.bindFramebuffer(GL_FRAMEBUFFER, m_resolveFbo); 271 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_resolveColorRbo); 272 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create FBO"); 273 274 TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); 275 276 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo); 277 } 278 } 279 else 280 DE_ASSERT(m_rtType == RENDERTARGETTYPE_DEFAULT); 281 282 m_iterNdx = 0; 283} 284 285AdvancedBlendCase::~AdvancedBlendCase (void) 286{ 287 AdvancedBlendCase::deinit(); 288} 289 290void AdvancedBlendCase::deinit (void) 291{ 292 delete m_program; 293 delete m_referenceRenderer; 294 delete m_refColorBuffer; 295 296 m_program = DE_NULL; 297 m_referenceRenderer = DE_NULL; 298 m_refColorBuffer = DE_NULL; 299 300 if (m_colorRbo || m_fbo) 301 { 302 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 303 304 gl.bindRenderbuffer(GL_RENDERBUFFER, 0); 305 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 306 307 if (m_colorRbo != 0) 308 { 309 gl.deleteRenderbuffers(1, &m_colorRbo); 310 m_colorRbo = 0; 311 } 312 313 if (m_fbo != 0) 314 { 315 gl.deleteFramebuffers(1, &m_fbo); 316 m_fbo = 0; 317 } 318 319 if (m_resolveColorRbo) 320 { 321 gl.deleteRenderbuffers(1, &m_resolveColorRbo); 322 m_resolveColorRbo = 0; 323 } 324 325 if (m_resolveFbo) 326 { 327 gl.deleteRenderbuffers(1, &m_resolveFbo); 328 m_resolveFbo = 0; 329 } 330 } 331} 332 333static tcu::Vec4 randomColor (de::Random* rnd) 334{ 335 const float rgbValues[] = { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f }; 336 const float alphaValues[] = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f }; 337 338 const float r = rnd->choose<float>(DE_ARRAY_BEGIN(rgbValues), DE_ARRAY_END(rgbValues)); 339 const float g = rnd->choose<float>(DE_ARRAY_BEGIN(rgbValues), DE_ARRAY_END(rgbValues)); 340 const float b = rnd->choose<float>(DE_ARRAY_BEGIN(rgbValues), DE_ARRAY_END(rgbValues)); 341 const float a = rnd->choose<float>(DE_ARRAY_BEGIN(alphaValues), DE_ARRAY_END(alphaValues)); 342 return tcu::Vec4(r, g, b, a); 343} 344 345static tcu::ConstPixelBufferAccess getLinearAccess (const tcu::ConstPixelBufferAccess& access) 346{ 347 if (access.getFormat().order == TextureFormat::sRGBA) 348 return tcu::ConstPixelBufferAccess(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), 349 access.getWidth(), access.getHeight(), access.getDepth(), 350 access.getRowPitch(), access.getSlicePitch(), access.getDataPtr()); 351 else 352 return access; 353} 354 355AdvancedBlendCase::IterateResult AdvancedBlendCase::iterate (void) 356{ 357 const glu::RenderContext& renderCtx = m_context.getRenderContext(); 358 const glw::Functions& gl = renderCtx.getFunctions(); 359 de::Random rnd (deStringHash(getName()) ^ deInt32Hash(m_iterNdx)); 360 const int viewportX = rnd.getInt(0, m_renderWidth - m_viewportWidth); 361 const int viewportY = rnd.getInt(0, m_renderHeight - m_viewportHeight); 362 const bool useFbo = m_rtType != RENDERTARGETTYPE_DEFAULT; 363 const bool requiresResolve = m_rtType == RENDERTARGETTYPE_MSAA_FBO; 364 const int numQuads = m_overdrawCount+1; 365 TextureLevel renderedImg (TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), m_viewportWidth, m_viewportHeight); 366 vector<Vec4> colors (numQuads*4); 367 368 for (vector<Vec4>::iterator col = colors.begin(); col != colors.end(); ++col) 369 *col = randomColor(&rnd); 370 371 // Render with GL. 372 { 373 const deUint32 program = m_program->getProgram(); 374 const int posLoc = gl.getAttribLocation(program, "a_position"); 375 const int colorLoc = gl.getAttribLocation(program, "a_color"); 376 const glu::Buffer indexBuffer (renderCtx); 377 const glu::Buffer positionBuffer (renderCtx); 378 const glu::Buffer colorBuffer (renderCtx); 379 vector<Vec2> positions (numQuads*4); 380 vector<deUint16> indices (numQuads*6); 381 const deUint16 singleQuadIndices[] = { 0, 2, 1, 1, 2, 3 }; 382 const Vec2 singleQuadPos[] = 383 { 384 Vec2(-1.0f, -1.0f), 385 Vec2(-1.0f, +1.0f), 386 Vec2(+1.0f, -1.0f), 387 Vec2(+1.0f, +1.0f), 388 }; 389 390 TCU_CHECK(posLoc >= 0 && colorLoc >= 0); 391 392 for (int quadNdx = 0; quadNdx < numQuads; quadNdx++) 393 { 394 std::copy(DE_ARRAY_BEGIN(singleQuadPos), DE_ARRAY_END(singleQuadPos), &positions[quadNdx*4]); 395 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleQuadIndices); ndx++) 396 indices[quadNdx*6 + ndx] = (deUint16)(quadNdx*4 + singleQuadIndices[ndx]); 397 } 398 399 gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *indexBuffer); 400 gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (glw::GLsizeiptr)(indices.size()*sizeof(indices[0])), &indices[0], GL_STATIC_DRAW); 401 402 gl.bindBuffer(GL_ARRAY_BUFFER, *positionBuffer); 403 gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(positions.size()*sizeof(positions[0])), &positions[0], GL_STATIC_DRAW); 404 gl.enableVertexAttribArray(posLoc); 405 gl.vertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL); 406 407 gl.bindBuffer(GL_ARRAY_BUFFER, *colorBuffer); 408 gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(colors.size()*sizeof(colors[0])), &colors[0], GL_STATIC_DRAW); 409 gl.enableVertexAttribArray(colorLoc); 410 gl.vertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL); 411 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create buffers"); 412 413 gl.useProgram(program); 414 gl.viewport(viewportX, viewportY, m_viewportWidth, m_viewportHeight); 415 gl.blendEquation(m_blendMode); 416 if (m_coherentBlending) 417 gl.enable(GL_BLEND_ADVANCED_COHERENT_KHR); 418 419 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set render state"); 420 421 gl.disable(GL_BLEND); 422 gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL); 423 gl.enable(GL_BLEND); 424 425 if (m_coherentBlending) 426 { 427 gl.drawElements(GL_TRIANGLES, 6*(numQuads-1), GL_UNSIGNED_SHORT, (const void*)(deUintptr)(6*sizeof(deUint16))); 428 } 429 else 430 { 431 for (int quadNdx = 1; quadNdx < numQuads; quadNdx++) 432 { 433 gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const void*)(deUintptr)(quadNdx*6*sizeof(deUint16))); 434 gl.blendBarrierKHR(); 435 } 436 } 437 438 gl.flush(); 439 GLU_EXPECT_NO_ERROR(gl.getError(), "Render failed"); 440 } 441 442 // Render reference. 443 { 444 rr::FragmentOperationState referenceState; 445 const tcu::PixelBufferAccess colorAccess = gls::FragmentOpUtil::getMultisampleAccess(m_refColorBuffer->getAccess()); 446 const tcu::PixelBufferAccess nullAccess (TextureFormat(), 0, 0, 0, DE_NULL); 447 IntegerQuad quad; 448 449 if (!useFbo && m_context.getRenderTarget().getPixelFormat().alphaBits == 0) 450 { 451 // Emulate lack of alpha by clearing to 1 and masking out alpha writes 452 tcu::clear(*m_refColorBuffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 453 referenceState.colorMask = tcu::BVec4(true, true, true, false); 454 } 455 456 referenceState.blendEquationAdvaced = sglr::rr_util::mapGLBlendEquationAdvanced(m_blendMode); 457 458 quad.posA = tcu::IVec2(0, 0); 459 quad.posB = tcu::IVec2(m_viewportWidth-1, m_viewportHeight-1); 460 461 for (int quadNdx = 0; quadNdx < numQuads; quadNdx++) 462 { 463 referenceState.blendMode = quadNdx == 0 ? rr::BLENDMODE_NONE : rr::BLENDMODE_ADVANCED; 464 std::copy(&colors[4*quadNdx], &colors[4*quadNdx] + 4, &quad.color[0]); 465 m_referenceRenderer->render(colorAccess, nullAccess /* no depth */, nullAccess /* no stencil */, quad, referenceState); 466 } 467 } 468 469 if (requiresResolve) 470 { 471 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_resolveFbo); 472 gl.blitFramebuffer(0, 0, m_renderWidth, m_renderHeight, 0, 0, m_renderWidth, m_renderHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); 473 GLU_EXPECT_NO_ERROR(gl.getError(), "Resolve blit failed"); 474 475 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_resolveFbo); 476 } 477 478 glu::readPixels(renderCtx, viewportX, viewportY, renderedImg.getAccess()); 479 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()"); 480 481 if (requiresResolve) 482 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo); 483 484 { 485 const bool isHSLMode = m_blendMode == GL_HSL_HUE_KHR || 486 m_blendMode == GL_HSL_SATURATION_KHR || 487 m_blendMode == GL_HSL_COLOR_KHR || 488 m_blendMode == GL_HSL_LUMINOSITY_KHR; 489 bool comparePass = false; 490 491 if (isHSLMode) 492 { 493 // Compensate for more demanding HSL code by using fuzzy comparison. 494 const float threshold = 0.002f; 495 comparePass = tcu::fuzzyCompare(m_testCtx.getLog(), "CompareResult", "Image Comparison Result", 496 getLinearAccess(m_refColorBuffer->getAccess()), 497 renderedImg.getAccess(), 498 threshold, tcu::COMPARE_LOG_RESULT); 499 } 500 else 501 { 502 const UVec4 compareThreshold = (useFbo ? tcu::PixelFormat(8, 8, 8, 8) : m_context.getRenderTarget().getPixelFormat()).getColorThreshold().toIVec().asUint() 503 * UVec4(5) / UVec4(2) + UVec4(3 * m_overdrawCount); 504 505 comparePass = tcu::bilinearCompare(m_testCtx.getLog(), "CompareResult", "Image Comparison Result", 506 getLinearAccess(m_refColorBuffer->getAccess()), 507 renderedImg.getAccess(), 508 tcu::RGBA(compareThreshold[0], compareThreshold[1], compareThreshold[2], compareThreshold[3]), 509 tcu::COMPARE_LOG_RESULT); 510 } 511 512 if (!comparePass) 513 { 514 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); 515 return STOP; 516 } 517 } 518 519 m_iterNdx += 1; 520 521 if (m_iterNdx < m_numIters) 522 return CONTINUE; 523 else 524 { 525 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 526 return STOP; 527 } 528} 529 530} // anonymous 531 532AdvancedBlendTests::AdvancedBlendTests (Context& context) 533 : TestCaseGroup(context, "blend_equation_advanced", "GL_KHR_blend_equation_advanced Tests") 534{ 535} 536 537AdvancedBlendTests::~AdvancedBlendTests (void) 538{ 539} 540 541void AdvancedBlendTests::init (void) 542{ 543 static const struct 544 { 545 deUint32 mode; 546 const char* name; 547 } s_blendModes[] = 548 { 549 { GL_MULTIPLY_KHR, "multiply" }, 550 { GL_SCREEN_KHR, "screen" }, 551 { GL_OVERLAY_KHR, "overlay" }, 552 { GL_DARKEN_KHR, "darken" }, 553 { GL_LIGHTEN_KHR, "lighten" }, 554 { GL_COLORDODGE_KHR, "colordodge" }, 555 { GL_COLORBURN_KHR, "colorburn" }, 556 { GL_HARDLIGHT_KHR, "hardlight" }, 557 { GL_SOFTLIGHT_KHR, "softlight" }, 558 { GL_DIFFERENCE_KHR, "difference" }, 559 { GL_EXCLUSION_KHR, "exclusion" }, 560 { GL_HSL_HUE_KHR, "hsl_hue" }, 561 { GL_HSL_SATURATION_KHR, "hsl_saturation" }, 562 { GL_HSL_COLOR_KHR, "hsl_color" }, 563 { GL_HSL_LUMINOSITY_KHR, "hsl_luminosity" } 564 }; 565 566 tcu::TestCaseGroup* const basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Single quad only"); 567 tcu::TestCaseGroup* const srgbGroup = new tcu::TestCaseGroup(m_testCtx, "srgb", "Advanced blending with sRGB FBO"); 568 tcu::TestCaseGroup* const msaaGroup = new tcu::TestCaseGroup(m_testCtx, "msaa", "Advanced blending with MSAA FBO"); 569 tcu::TestCaseGroup* const barrierGroup = new tcu::TestCaseGroup(m_testCtx, "barrier", "Multiple overlapping quads with blend barriers"); 570 tcu::TestCaseGroup* const coherentGroup = new tcu::TestCaseGroup(m_testCtx, "coherent", "Overlapping quads with coherent blending"); 571 tcu::TestCaseGroup* const coherentMsaaGroup = new tcu::TestCaseGroup(m_testCtx, "coherent_msaa", "Overlapping quads with coherent blending with MSAA FBO"); 572 573 addChild(basicGroup); 574 addChild(srgbGroup); 575 addChild(msaaGroup); 576 addChild(barrierGroup); 577 addChild(coherentGroup); 578 addChild(coherentMsaaGroup); 579 580 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(s_blendModes); modeNdx++) 581 { 582 const char* const name = s_blendModes[modeNdx].name; 583 const char* const desc = ""; 584 const deUint32 mode = s_blendModes[modeNdx].mode; 585 586 basicGroup->addChild (new AdvancedBlendCase(m_context, name, desc, mode, 1, false, RENDERTARGETTYPE_DEFAULT)); 587 srgbGroup->addChild (new AdvancedBlendCase(m_context, name, desc, mode, 1, false, RENDERTARGETTYPE_SRGB_FBO)); 588 msaaGroup->addChild (new AdvancedBlendCase(m_context, name, desc, mode, 1, false, RENDERTARGETTYPE_MSAA_FBO)); 589 barrierGroup->addChild (new AdvancedBlendCase(m_context, name, desc, mode, 4, false, RENDERTARGETTYPE_DEFAULT)); 590 coherentGroup->addChild (new AdvancedBlendCase(m_context, name, desc, mode, 4, true, RENDERTARGETTYPE_DEFAULT)); 591 coherentMsaaGroup->addChild (new AdvancedBlendCase(m_context, name, desc, mode, 4, true, RENDERTARGETTYPE_MSAA_FBO)); 592 } 593} 594 595} // Functional 596} // gles31 597} // deqp 598