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 Depth & stencil tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es3fDepthStencilTests.hpp" 25 #include "glsFragmentOpUtil.hpp" 26 #include "gluPixelTransfer.hpp" 27 #include "gluStrUtil.hpp" 28 #include "tcuSurface.hpp" 29 #include "tcuRenderTarget.hpp" 30 #include "tcuTestLog.hpp" 31 #include "tcuImageCompare.hpp" 32 #include "tcuCommandLine.hpp" 33 #include "tcuTextureUtil.hpp" 34 #include "deRandom.hpp" 35 #include "deStringUtil.hpp" 36 #include "deMemory.h" 37 #include "deString.h" 38 #include "rrFragmentOperations.hpp" 39 #include "sglrReferenceUtils.hpp" 40 41 #include <algorithm> 42 #include <sstream> 43 44 #include "glw.h" 45 46 namespace deqp 47 { 48 namespace gles3 49 { 50 namespace Functional 51 { 52 53 using std::vector; 54 using tcu::IVec2; 55 using tcu::Vec2; 56 using tcu::Vec4; 57 using tcu::TestLog; 58 using std::ostringstream; 59 60 enum 61 { 62 VIEWPORT_WIDTH = 4*3*4, 63 VIEWPORT_HEIGHT = 4*12, 64 65 NUM_RANDOM_CASES = 25, 66 NUM_RANDOM_SUB_CASES = 10 67 }; 68 69 namespace DepthStencilCaseUtil 70 { 71 72 struct StencilParams 73 { 74 deUint32 function; 75 int reference; 76 deUint32 compareMask; 77 78 deUint32 stencilFailOp; 79 deUint32 depthFailOp; 80 deUint32 depthPassOp; 81 82 deUint32 writeMask; 83 84 StencilParams (void) 85 : function (0) 86 , reference (0) 87 , compareMask (0) 88 , stencilFailOp (0) 89 , depthFailOp (0) 90 , depthPassOp (0) 91 , writeMask (0) 92 { 93 } 94 }; 95 96 struct DepthStencilParams 97 { 98 rr::FaceType visibleFace; //!< Quad visible face. 99 100 bool stencilTestEnabled; 101 StencilParams stencil[rr::FACETYPE_LAST]; 102 103 bool depthTestEnabled; 104 deUint32 depthFunc; 105 float depth; 106 bool depthWriteMask; 107 108 DepthStencilParams (void) 109 : visibleFace (rr::FACETYPE_LAST) 110 , stencilTestEnabled (false) 111 , depthTestEnabled (false) 112 , depthFunc (0) 113 , depth (0.0f) 114 , depthWriteMask (false) 115 { 116 } 117 }; 118 119 tcu::TestLog& operator<< (tcu::TestLog& log, const StencilParams& params) 120 { 121 log << TestLog::Message << " func = " << glu::getCompareFuncStr(params.function) << "\n" 122 << " ref = " << params.reference << "\n" 123 << " compare mask = " << tcu::toHex(params.compareMask) << "\n" 124 << " stencil fail = " << glu::getStencilOpStr(params.stencilFailOp) << "\n" 125 << " depth fail = " << glu::getStencilOpStr(params.depthFailOp) << "\n" 126 << " depth pass = " << glu::getStencilOpStr(params.depthPassOp) << "\n" 127 << " write mask = " << tcu::toHex(params.writeMask) << "\n" 128 << TestLog::EndMessage; 129 return log; 130 } 131 132 tcu::TestLog& operator<< (tcu::TestLog& log, const DepthStencilParams& params) 133 { 134 log << TestLog::Message << "Stencil test: " << (params.stencilTestEnabled ? "enabled" : "disabled") << TestLog::EndMessage; 135 if (params.stencilTestEnabled) 136 { 137 log << TestLog::Message << "Front-face stencil state: " << TestLog::EndMessage; 138 log << params.stencil[rr::FACETYPE_FRONT]; 139 140 log << TestLog::Message << "Back-face stencil state: " << TestLog::EndMessage; 141 log << params.stencil[rr::FACETYPE_BACK]; 142 } 143 144 log << TestLog::Message << "Depth test: " << (params.depthTestEnabled ? "enabled" : "disabled") << TestLog::EndMessage; 145 if (params.depthTestEnabled) 146 { 147 log << TestLog::Message << " func = " << glu::getCompareFuncStr(params.depthFunc) << "\n" 148 " depth value = " << params.depth << "\n" 149 " write mask = " << (params.depthWriteMask ? "true" : "false") << "\n" 150 << TestLog::EndMessage; 151 } 152 153 log << TestLog::Message << "Triangles are " << (params.visibleFace == rr::FACETYPE_FRONT ? "front" : "back") << "-facing" << TestLog::EndMessage; 154 155 return log; 156 } 157 158 struct ClearCommand 159 { 160 rr::WindowRectangle rect; 161 deUint32 buffers; 162 tcu::Vec4 color; 163 int stencil; 164 // \note No depth here - don't use clears for setting depth values; use quad rendering instead. Cleared depths are in [0, 1] to begin with, 165 // whereas rendered depths are given in [-1, 1] and then mapped to [0, 1]; this discrepancy could cause precision issues in depth tests. 166 167 ClearCommand (void) 168 : rect (0, 0, 0, 0) 169 , buffers (0) 170 , stencil (0) 171 { 172 } 173 174 ClearCommand (const rr::WindowRectangle& rect_, 175 deUint32 buffers_, 176 const tcu::Vec4& color_, 177 int stencil_) 178 : rect (rect_) 179 , buffers (buffers_) 180 , color (color_) 181 , stencil (stencil_) 182 { 183 } 184 }; 185 186 struct RenderCommand 187 { 188 DepthStencilParams params; 189 rr::WindowRectangle rect; 190 tcu::Vec4 color; 191 tcu::BVec4 colorMask; 192 193 RenderCommand (void) 194 : rect(0, 0, 0, 0) 195 { 196 } 197 }; 198 199 struct RefRenderCommand 200 { 201 gls::FragmentOpUtil::IntegerQuad quad; 202 rr::FragmentOperationState state; 203 }; 204 205 struct TestRenderTarget 206 { 207 int width; 208 int height; 209 int depthBits; 210 int stencilBits; 211 212 TestRenderTarget (int width_, 213 int height_, 214 int depthBits_, 215 int stencilBits_) 216 : width (width_) 217 , height (height_) 218 , depthBits (depthBits_) 219 , stencilBits (stencilBits_) 220 { 221 } 222 223 TestRenderTarget (void) 224 : width (0) 225 , height (0) 226 , depthBits (0) 227 , stencilBits (0) 228 { 229 } 230 }; 231 232 void getStencilTestValues (int stencilBits, int numValues, int* values) 233 { 234 int numLowest = numValues/2; 235 int numHighest = numValues-numLowest; 236 int maxVal = (1<<stencilBits)-1; 237 238 for (int ndx = 0; ndx < numLowest; ndx++) 239 values[ndx] = ndx; 240 241 for (int ndx = 0; ndx < numHighest; ndx++) 242 values[numValues-ndx-1] = maxVal-ndx; 243 } 244 245 void generateBaseClearAndDepthCommands (const TestRenderTarget& target, vector<ClearCommand>& clearCommands, vector<RenderCommand>& renderCommands) 246 { 247 DE_ASSERT(clearCommands.empty()); 248 DE_ASSERT(renderCommands.empty()); 249 250 const int numL0CellsX = 4; 251 const int numL0CellsY = 4; 252 const int numL1CellsX = 3; 253 const int numL1CellsY = 1; 254 int cellL0Width = target.width/numL0CellsX; 255 int cellL0Height = target.height/numL0CellsY; 256 int cellL1Width = cellL0Width/numL1CellsX; 257 int cellL1Height = cellL0Height/numL1CellsY; 258 259 int stencilValues[numL0CellsX*numL0CellsY]; 260 float depthValues[numL1CellsX*numL1CellsY]; 261 262 if (cellL0Width <= 0 || cellL1Width <= 0 || cellL0Height <= 0 || cellL1Height <= 0) 263 throw tcu::NotSupportedError("Too small render target"); 264 265 // Fullscreen clear to black. 266 clearCommands.push_back(ClearCommand(rr::WindowRectangle(0, 0, target.width, target.height), GL_COLOR_BUFFER_BIT, Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0)); 267 268 // Compute stencil values: numL0CellsX*numL0CellsY combinations of lowest and highest bits. 269 getStencilTestValues(target.stencilBits, numL0CellsX*numL0CellsY, &stencilValues[0]); 270 271 // Compute depth values 272 { 273 int numValues = DE_LENGTH_OF_ARRAY(depthValues); 274 float depthStep = 2.0f/(numValues-1); 275 276 for (int ndx = 0; ndx < numValues; ndx++) 277 depthValues[ndx] = -1.0f + depthStep*ndx; 278 } 279 280 for (int y0 = 0; y0 < numL0CellsY; y0++) 281 { 282 for (int x0 = 0; x0 < numL0CellsX; x0++) 283 { 284 int stencilValue = stencilValues[y0*numL0CellsX + x0]; 285 286 for (int y1 = 0; y1 < numL1CellsY; y1++) 287 { 288 for (int x1 = 0; x1 < numL1CellsX; x1++) 289 { 290 int x = x0*cellL0Width + x1*cellL1Width; 291 int y = y0*cellL0Height + y1*cellL1Height; 292 rr::WindowRectangle cellL1Rect (x, y, cellL1Width, cellL1Height); 293 294 clearCommands.push_back(ClearCommand(cellL1Rect, GL_STENCIL_BUFFER_BIT, Vec4(0), stencilValue)); 295 296 RenderCommand renderCmd; 297 renderCmd.params.visibleFace = rr::FACETYPE_FRONT; 298 renderCmd.params.depth = depthValues[y1*numL1CellsX + x1];; 299 renderCmd.params.depthTestEnabled = true; 300 renderCmd.params.depthFunc = GL_ALWAYS; 301 renderCmd.params.depthWriteMask = true; 302 renderCmd.colorMask = tcu::BVec4(false); 303 renderCmd.rect = cellL1Rect; 304 305 renderCommands.push_back(renderCmd); 306 } 307 } 308 } 309 } 310 } 311 312 void generateDepthVisualizeCommands (const TestRenderTarget& target, vector<RenderCommand>& commands) 313 { 314 const float epsilon = -0.05f; 315 static const float depthSteps[] = {-1.0f, -0.5f, 0.0f, 0.5f, 1.0f}; 316 int numSteps = DE_LENGTH_OF_ARRAY(depthSteps); 317 const float colorStep = 1.0f / (float)(numSteps-1); 318 319 for (int ndx = 0; ndx < numSteps; ndx++) 320 { 321 RenderCommand cmd; 322 323 cmd.params.visibleFace = rr::FACETYPE_FRONT; 324 cmd.rect = rr::WindowRectangle(0, 0, target.width, target.height); 325 cmd.color = Vec4(0.0f, 0.0f, colorStep*ndx, 0.0f); 326 cmd.colorMask = tcu::BVec4(false, false, true, false); 327 cmd.params.depth = depthSteps[ndx]+epsilon; 328 cmd.params.depthTestEnabled = true; 329 cmd.params.depthFunc = GL_LESS; 330 cmd.params.depthWriteMask = false; 331 332 commands.push_back(cmd); 333 } 334 } 335 336 void generateStencilVisualizeCommands (const TestRenderTarget& target, vector<RenderCommand>& commands) 337 { 338 const int numValues = 4*4; 339 float colorStep = 1.0f / numValues; // 0 is reserved for non-matching. 340 int stencilValues[numValues]; 341 342 getStencilTestValues(target.stencilBits, numValues, &stencilValues[0]); 343 344 for (int ndx = 0; ndx < numValues; ndx++) 345 { 346 RenderCommand cmd; 347 348 cmd.params.visibleFace = rr::FACETYPE_FRONT; 349 cmd.rect = rr::WindowRectangle(0, 0, target.width, target.height); 350 cmd.color = Vec4(0.0f, colorStep*(ndx+1), 0.0f, 0.0f); 351 cmd.colorMask = tcu::BVec4(false, true, false, false); 352 cmd.params.stencilTestEnabled = true; 353 354 cmd.params.stencil[rr::FACETYPE_FRONT].function = GL_EQUAL; 355 cmd.params.stencil[rr::FACETYPE_FRONT].reference = stencilValues[ndx]; 356 cmd.params.stencil[rr::FACETYPE_FRONT].compareMask = ~0u; 357 cmd.params.stencil[rr::FACETYPE_FRONT].stencilFailOp = GL_KEEP; 358 cmd.params.stencil[rr::FACETYPE_FRONT].depthFailOp = GL_KEEP; 359 cmd.params.stencil[rr::FACETYPE_FRONT].depthPassOp = GL_KEEP; 360 cmd.params.stencil[rr::FACETYPE_FRONT].writeMask = 0u; 361 362 cmd.params.stencil[rr::FACETYPE_BACK] = cmd.params.stencil[rr::FACETYPE_FRONT]; 363 364 commands.push_back(cmd); 365 } 366 } 367 368 void translateStencilState (const StencilParams& src, rr::StencilState& dst) 369 { 370 dst.func = sglr::rr_util::mapGLTestFunc(src.function); 371 dst.ref = src.reference; 372 dst.compMask = src.compareMask; 373 dst.sFail = sglr::rr_util::mapGLStencilOp(src.stencilFailOp); 374 dst.dpFail = sglr::rr_util::mapGLStencilOp(src.depthFailOp); 375 dst.dpPass = sglr::rr_util::mapGLStencilOp(src.depthPassOp); 376 dst.writeMask = src.writeMask; 377 } 378 379 void translateCommand (const RenderCommand& src, RefRenderCommand& dst, const TestRenderTarget& renderTarget) 380 { 381 const float far = 1.0f; 382 const float near = 0.0f; 383 bool hasDepth = renderTarget.depthBits > 0; 384 bool hasStencil = renderTarget.stencilBits > 0; 385 bool isFrontFacing = src.params.visibleFace == rr::FACETYPE_FRONT; 386 387 dst.quad.posA = IVec2(isFrontFacing ? src.rect.left : (src.rect.left+src.rect.width-1), src.rect.bottom); 388 dst.quad.posB = IVec2(isFrontFacing ? (src.rect.left+src.rect.width-1) : src.rect.left, src.rect.bottom+src.rect.height-1); 389 390 std::fill(DE_ARRAY_BEGIN(dst.quad.color), DE_ARRAY_END(dst.quad.color), src.color); 391 std::fill(DE_ARRAY_BEGIN(dst.quad.depth), DE_ARRAY_END(dst.quad.depth), ((far-near)/2.0f) * src.params.depth + (near+far)/2.0f); 392 393 dst.state.colorMask = src.colorMask; 394 395 dst.state.scissorTestEnabled = false; 396 dst.state.stencilTestEnabled = hasStencil && src.params.stencilTestEnabled; 397 dst.state.depthTestEnabled = hasDepth && src.params.depthTestEnabled; 398 dst.state.blendMode = rr::BLENDMODE_NONE; 399 dst.state.numStencilBits = renderTarget.stencilBits; 400 401 if (dst.state.depthTestEnabled) 402 { 403 dst.state.depthFunc = sglr::rr_util::mapGLTestFunc(src.params.depthFunc); 404 dst.state.depthMask = src.params.depthWriteMask; 405 } 406 407 if (dst.state.stencilTestEnabled) 408 { 409 translateStencilState(src.params.stencil[rr::FACETYPE_BACK], dst.state.stencilStates[rr::FACETYPE_BACK]); 410 translateStencilState(src.params.stencil[rr::FACETYPE_FRONT], dst.state.stencilStates[rr::FACETYPE_FRONT]); 411 } 412 } 413 414 void render (const vector<ClearCommand>& clears, int viewportX, int viewportY) 415 { 416 glEnable(GL_SCISSOR_TEST); 417 418 for (int ndx = 0; ndx < (int)clears.size(); ndx++) 419 { 420 const ClearCommand& clear = clears[ndx]; 421 422 if (clear.buffers & GL_COLOR_BUFFER_BIT) glClearColor(clear.color.x(), clear.color.y(), clear.color.z(), clear.color.w()); 423 if (clear.buffers & GL_STENCIL_BUFFER_BIT) glClearStencil(clear.stencil); 424 425 DE_ASSERT(clear.buffers == (clear.buffers & (GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT))); // \note Don't use clear for depths. 426 427 glScissor(clear.rect.left+viewportX, clear.rect.bottom+viewportY, clear.rect.width, clear.rect.height); 428 glClear(clear.buffers); 429 } 430 431 glDisable(GL_SCISSOR_TEST); 432 } 433 434 void render (gls::FragmentOpUtil::QuadRenderer& renderer, const RenderCommand& command, int viewportX, int viewportY) 435 { 436 if (command.params.stencilTestEnabled) 437 { 438 glEnable(GL_STENCIL_TEST); 439 440 for (int face = 0; face < rr::FACETYPE_LAST; face++) 441 { 442 deUint32 glFace = face == rr::FACETYPE_BACK ? GL_BACK : GL_FRONT; 443 const StencilParams& sParams = command.params.stencil[face]; 444 445 glStencilFuncSeparate(glFace, sParams.function, sParams.reference, sParams.compareMask); 446 glStencilOpSeparate(glFace, sParams.stencilFailOp, sParams.depthFailOp, sParams.depthPassOp); 447 glStencilMaskSeparate(glFace, sParams.writeMask); 448 } 449 } 450 else 451 glDisable(GL_STENCIL_TEST); 452 453 if (command.params.depthTestEnabled) 454 { 455 glEnable(GL_DEPTH_TEST); 456 glDepthFunc(command.params.depthFunc); 457 glDepthMask(command.params.depthWriteMask ? GL_TRUE : GL_FALSE); 458 } 459 else 460 glDisable(GL_DEPTH_TEST); 461 462 glColorMask(command.colorMask[0] ? GL_TRUE : GL_FALSE, 463 command.colorMask[1] ? GL_TRUE : GL_FALSE, 464 command.colorMask[2] ? GL_TRUE : GL_FALSE, 465 command.colorMask[3] ? GL_TRUE : GL_FALSE); 466 glViewport(command.rect.left+viewportX, command.rect.bottom+viewportY, command.rect.width, command.rect.height); 467 468 gls::FragmentOpUtil::Quad quad; 469 470 bool isFrontFacing = command.params.visibleFace == rr::FACETYPE_FRONT; 471 quad.posA = Vec2(isFrontFacing ? -1.0f : 1.0f, -1.0f); 472 quad.posB = Vec2(isFrontFacing ? 1.0f : -1.0f, 1.0f); 473 474 std::fill(DE_ARRAY_BEGIN(quad.color), DE_ARRAY_END(quad.color), command.color); 475 std::fill(DE_ARRAY_BEGIN(quad.depth), DE_ARRAY_END(quad.depth), command.params.depth); 476 477 renderer.render(quad); 478 GLU_CHECK(); 479 } 480 481 void renderReference (const vector<ClearCommand>& clears, const tcu::PixelBufferAccess& dstColor, const tcu::PixelBufferAccess& dstStencil, int stencilBits) 482 { 483 for (int ndx = 0; ndx < (int)clears.size(); ndx++) 484 { 485 const ClearCommand& clear = clears[ndx]; 486 487 if (clear.buffers & GL_COLOR_BUFFER_BIT) 488 tcu::clear(tcu::getSubregion(dstColor, clear.rect.left, clear.rect.bottom, clear.rect.width, clear.rect.height), clear.color); 489 490 if (clear.buffers & GL_STENCIL_BUFFER_BIT && stencilBits > 0) 491 { 492 int maskedVal = clear.stencil & ((1<<stencilBits)-1); 493 tcu::clearStencil(tcu::getSubregion(dstStencil, clear.rect.left, clear.rect.bottom, clear.rect.width, clear.rect.height), maskedVal); 494 } 495 496 DE_ASSERT(clear.buffers == (clear.buffers & (GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT))); // \note Don't use clear for depths. 497 } 498 } 499 500 } // DepthStencilCaseUtil 501 502 using namespace DepthStencilCaseUtil; 503 504 class DepthStencilCase : public TestCase 505 { 506 public: 507 DepthStencilCase (Context& context, const char* name, const char* desc, const std::vector<DepthStencilParams>& cases); 508 ~DepthStencilCase (void); 509 510 void init (void); 511 void deinit (void); 512 513 IterateResult iterate (void); 514 515 private: 516 DepthStencilCase (const DepthStencilCase& other); 517 DepthStencilCase& operator= (const DepthStencilCase& other); 518 519 std::vector<DepthStencilParams> m_cases; 520 521 TestRenderTarget m_renderTarget; 522 std::vector<ClearCommand> m_baseClears; 523 std::vector<RenderCommand> m_baseDepthRenders; 524 std::vector<RenderCommand> m_visualizeCommands; 525 std::vector<RefRenderCommand> m_refBaseDepthRenders; 526 std::vector<RefRenderCommand> m_refVisualizeCommands; 527 528 gls::FragmentOpUtil::QuadRenderer* m_renderer; 529 tcu::Surface* m_refColorBuffer; 530 tcu::TextureLevel* m_refDepthBuffer; 531 tcu::TextureLevel* m_refStencilBuffer; 532 gls::FragmentOpUtil::ReferenceQuadRenderer* m_refRenderer; 533 534 int m_iterNdx; 535 }; 536 537 DepthStencilCase::DepthStencilCase (Context& context, const char* name, const char* desc, const std::vector<DepthStencilParams>& cases) 538 : TestCase (context, name, desc) 539 , m_cases (cases) 540 , m_renderer (DE_NULL) 541 , m_refColorBuffer (DE_NULL) 542 , m_refDepthBuffer (DE_NULL) 543 , m_refStencilBuffer (DE_NULL) 544 , m_refRenderer (DE_NULL) 545 , m_iterNdx (0) 546 { 547 } 548 549 DepthStencilCase::~DepthStencilCase (void) 550 { 551 delete m_renderer; 552 delete m_refColorBuffer; 553 delete m_refDepthBuffer; 554 delete m_refStencilBuffer; 555 delete m_refRenderer; 556 } 557 558 void DepthStencilCase::init (void) 559 { 560 DE_ASSERT(!m_renderer && !m_refColorBuffer && !m_refDepthBuffer && !m_refStencilBuffer && !m_refRenderer); 561 562 // Compute render target. 563 int viewportW = de::min<int>(m_context.getRenderTarget().getWidth(), VIEWPORT_WIDTH); 564 int viewportH = de::min<int>(m_context.getRenderTarget().getHeight(), VIEWPORT_HEIGHT); 565 m_renderTarget = TestRenderTarget(viewportW, viewportH, m_context.getRenderTarget().getDepthBits(), m_context.getRenderTarget().getStencilBits()); 566 567 // Compute base clears & visualization commands. 568 generateBaseClearAndDepthCommands(m_renderTarget, m_baseClears, m_baseDepthRenders); 569 generateDepthVisualizeCommands(m_renderTarget, m_visualizeCommands); 570 generateStencilVisualizeCommands(m_renderTarget, m_visualizeCommands); 571 572 // Translate to ref commands. 573 m_refBaseDepthRenders.resize(m_baseDepthRenders.size()); 574 for (int ndx = 0; ndx < (int)m_baseDepthRenders.size(); ndx++) 575 translateCommand(m_baseDepthRenders[ndx], m_refBaseDepthRenders[ndx], m_renderTarget); 576 577 m_refVisualizeCommands.resize(m_visualizeCommands.size()); 578 for (int ndx = 0; ndx < (int)m_visualizeCommands.size(); ndx++) 579 translateCommand(m_visualizeCommands[ndx], m_refVisualizeCommands[ndx], m_renderTarget); 580 581 m_renderer = new gls::FragmentOpUtil::QuadRenderer(m_context.getRenderContext(), glu::GLSL_VERSION_300_ES); 582 m_refColorBuffer = new tcu::Surface(viewportW, viewportH); 583 m_refDepthBuffer = new tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT), viewportW, viewportH); 584 m_refStencilBuffer = new tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT32), viewportW, viewportH); 585 m_refRenderer = new gls::FragmentOpUtil::ReferenceQuadRenderer(); 586 587 m_iterNdx = 0; 588 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 589 } 590 591 void DepthStencilCase::deinit (void) 592 { 593 delete m_renderer; 594 delete m_refColorBuffer; 595 delete m_refDepthBuffer; 596 delete m_refStencilBuffer; 597 delete m_refRenderer; 598 599 m_renderer = DE_NULL; 600 m_refColorBuffer = DE_NULL; 601 m_refDepthBuffer = DE_NULL; 602 m_refStencilBuffer = DE_NULL; 603 m_refRenderer = DE_NULL; 604 605 m_baseClears.clear(); 606 m_baseDepthRenders.clear(); 607 m_visualizeCommands.clear(); 608 m_refBaseDepthRenders.clear(); 609 m_refVisualizeCommands.clear(); 610 } 611 612 DepthStencilCase::IterateResult DepthStencilCase::iterate (void) 613 { 614 de::Random rnd (deStringHash(getName()) ^ deInt32Hash(m_iterNdx)); 615 int viewportX = rnd.getInt(0, m_context.getRenderTarget().getWidth()-m_renderTarget.width); 616 int viewportY = rnd.getInt(0, m_context.getRenderTarget().getHeight()-m_renderTarget.height); 617 RenderCommand testCmd; 618 619 tcu::Surface renderedImg (m_renderTarget.width, m_renderTarget.height); 620 tcu::RGBA threshold = m_context.getRenderTarget().getPixelFormat().getColorThreshold(); 621 622 // Fill in test command for this iteration. 623 testCmd.color = Vec4(1.0f, 0.0f, 0.0f, 1.0f); 624 testCmd.colorMask = tcu::BVec4(true); 625 testCmd.rect = rr::WindowRectangle(0, 0, m_renderTarget.width, m_renderTarget.height); 626 testCmd.params = m_cases[m_iterNdx]; 627 628 if (m_iterNdx == 0) 629 { 630 m_testCtx.getLog() << TestLog::Message << "Channels:\n" 631 " RED: passing pixels\n" 632 " GREEN: stencil values\n" 633 " BLUE: depth values" 634 << TestLog::EndMessage; 635 } 636 637 if (m_cases.size() > 1) 638 m_testCtx.getLog() << TestLog::Message << "Iteration " << m_iterNdx << "..." << TestLog::EndMessage; 639 640 m_testCtx.getLog() << m_cases[m_iterNdx]; 641 642 // Submit render commands to gl GL. 643 644 // Base clears. 645 render(m_baseClears, viewportX, viewportY); 646 647 // Base depths. 648 for (vector<RenderCommand>::const_iterator cmd = m_baseDepthRenders.begin(); cmd != m_baseDepthRenders.end(); ++cmd) 649 render(*m_renderer, *cmd, viewportX, viewportY); 650 651 // Test command. 652 render(*m_renderer, testCmd, viewportX, viewportY); 653 654 // Visualization commands. 655 for (vector<RenderCommand>::const_iterator cmd = m_visualizeCommands.begin(); cmd != m_visualizeCommands.end(); ++cmd) 656 render(*m_renderer, *cmd, viewportX, viewportY); 657 658 // Re-enable all write masks. 659 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 660 glDepthMask(GL_TRUE); 661 glStencilMask(~0u); 662 663 // Ask GPU to start rendering. 664 glFlush(); 665 666 // Render reference while GPU is doing work. 667 { 668 RefRenderCommand refTestCmd; 669 translateCommand(testCmd, refTestCmd, m_renderTarget); 670 671 // Base clears. 672 renderReference(m_baseClears, m_refColorBuffer->getAccess(), m_refStencilBuffer->getAccess(), m_renderTarget.depthBits); 673 674 // Base depths. 675 for (vector<RefRenderCommand>::const_iterator cmd = m_refBaseDepthRenders.begin(); cmd != m_refBaseDepthRenders.end(); ++cmd) 676 m_refRenderer->render(gls::FragmentOpUtil::getMultisampleAccess(m_refColorBuffer->getAccess()), 677 gls::FragmentOpUtil::getMultisampleAccess(m_refDepthBuffer->getAccess()), 678 gls::FragmentOpUtil::getMultisampleAccess(m_refStencilBuffer->getAccess()), 679 cmd->quad, cmd->state); 680 681 // Test command. 682 m_refRenderer->render(gls::FragmentOpUtil::getMultisampleAccess(m_refColorBuffer->getAccess()), 683 gls::FragmentOpUtil::getMultisampleAccess(m_refDepthBuffer->getAccess()), 684 gls::FragmentOpUtil::getMultisampleAccess(m_refStencilBuffer->getAccess()), 685 refTestCmd.quad, refTestCmd.state); 686 687 // Visualization commands. 688 for (vector<RefRenderCommand>::const_iterator cmd = m_refVisualizeCommands.begin(); cmd != m_refVisualizeCommands.end(); ++cmd) 689 m_refRenderer->render(gls::FragmentOpUtil::getMultisampleAccess(m_refColorBuffer->getAccess()), 690 gls::FragmentOpUtil::getMultisampleAccess(m_refDepthBuffer->getAccess()), 691 gls::FragmentOpUtil::getMultisampleAccess(m_refStencilBuffer->getAccess()), 692 cmd->quad, cmd->state); 693 } 694 695 // Read rendered image. 696 glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedImg.getAccess()); 697 698 m_iterNdx += 1; 699 700 // Compare to reference. 701 bool isLastIter = m_iterNdx >= (int)m_cases.size(); 702 bool compareOk = tcu::pixelThresholdCompare(m_testCtx.getLog(), "CompareResult", "Image Comparison Result", *m_refColorBuffer, renderedImg, threshold, 703 tcu::COMPARE_LOG_RESULT); 704 705 m_testCtx.getLog() << TestLog::Message << (compareOk ? " Passed." : " FAILED!") << TestLog::EndMessage; 706 if (!compareOk) 707 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); 708 709 if (compareOk && !isLastIter) 710 return CONTINUE; 711 else 712 return STOP; 713 } 714 715 DepthStencilTests::DepthStencilTests (Context& context) 716 : TestCaseGroup(context, "depth_stencil", "Depth and Stencil Op Tests") 717 { 718 } 719 720 DepthStencilTests::~DepthStencilTests (void) 721 { 722 } 723 724 static void randomDepthStencilState (de::Random& rnd, DepthStencilParams& params) 725 { 726 const float stencilTestProbability = 0.8f; 727 const float depthTestProbability = 0.7f; 728 729 static const deUint32 compareFuncs[] = 730 { 731 GL_NEVER, 732 GL_ALWAYS, 733 GL_LESS, 734 GL_LEQUAL, 735 GL_EQUAL, 736 GL_GEQUAL, 737 GL_GREATER, 738 GL_NOTEQUAL 739 }; 740 741 static const deUint32 stencilOps[] = 742 { 743 GL_KEEP, 744 GL_ZERO, 745 GL_REPLACE, 746 GL_INCR, 747 GL_DECR, 748 GL_INVERT, 749 GL_INCR_WRAP, 750 GL_DECR_WRAP 751 }; 752 753 static const float depthValues[] = { -1.0f, -0.8f, -0.6f, -0.4f, -0.2f, 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f }; 754 755 params.visibleFace = rnd.getBool() ? rr::FACETYPE_FRONT : rr::FACETYPE_BACK; 756 params.stencilTestEnabled = rnd.getFloat() < stencilTestProbability; 757 params.depthTestEnabled = !params.stencilTestEnabled || (rnd.getFloat() < depthTestProbability); 758 759 if (params.stencilTestEnabled) 760 { 761 for (int ndx = 0; ndx < 2; ndx++) 762 { 763 params.stencil[ndx].function = rnd.choose<deUint32>(DE_ARRAY_BEGIN(compareFuncs), DE_ARRAY_END(compareFuncs)); 764 params.stencil[ndx].reference = rnd.getInt(-2, 260); 765 params.stencil[ndx].compareMask = rnd.getUint32(); 766 params.stencil[ndx].stencilFailOp = rnd.choose<deUint32>(DE_ARRAY_BEGIN(stencilOps), DE_ARRAY_END(stencilOps)); 767 params.stencil[ndx].depthFailOp = rnd.choose<deUint32>(DE_ARRAY_BEGIN(stencilOps), DE_ARRAY_END(stencilOps)); 768 params.stencil[ndx].depthPassOp = rnd.choose<deUint32>(DE_ARRAY_BEGIN(stencilOps), DE_ARRAY_END(stencilOps)); 769 params.stencil[ndx].writeMask = rnd.getUint32(); 770 } 771 } 772 773 if (params.depthTestEnabled) 774 { 775 params.depthFunc = rnd.choose<deUint32>(DE_ARRAY_BEGIN(compareFuncs), DE_ARRAY_END(compareFuncs)); 776 params.depth = rnd.choose<float>(DE_ARRAY_BEGIN(depthValues), DE_ARRAY_END(depthValues)); 777 params.depthWriteMask = rnd.getBool(); 778 } 779 } 780 781 void DepthStencilTests::init (void) 782 { 783 static const struct 784 { 785 const char* name; 786 deUint32 func; 787 } compareFuncs[] = 788 { 789 { "never", GL_NEVER }, 790 { "always", GL_ALWAYS }, 791 { "less", GL_LESS }, 792 { "lequal", GL_LEQUAL }, 793 { "equal", GL_EQUAL }, 794 { "gequal", GL_GEQUAL }, 795 { "greater", GL_GREATER }, 796 { "notequal", GL_NOTEQUAL } 797 }; 798 799 static const struct 800 { 801 const char* name; 802 deUint32 op; 803 } stencilOps[] = 804 { 805 { "keep", GL_KEEP }, 806 { "zero", GL_ZERO }, 807 { "replace", GL_REPLACE }, 808 { "incr", GL_INCR }, 809 { "decr", GL_DECR }, 810 { "invert", GL_INVERT }, 811 { "incr_wrap", GL_INCR_WRAP }, 812 { "decr_wrap", GL_DECR_WRAP } 813 }; 814 815 static const struct 816 { 817 rr::FaceType visibleFace; 818 deUint32 sFail; 819 deUint32 dFail; 820 deUint32 dPass; 821 int stencilRef; 822 deUint32 compareMask; 823 deUint32 writeMask; 824 float depth; 825 } functionCases[] = 826 { 827 { rr::FACETYPE_BACK, GL_DECR, GL_INCR, GL_INVERT, 4, ~0u, ~0u, -0.7f }, 828 { rr::FACETYPE_FRONT, GL_DECR, GL_INCR, GL_INVERT, 2, ~0u, ~0u, 0.0f }, 829 { rr::FACETYPE_BACK, GL_DECR, GL_INCR, GL_INVERT, 1, ~0u, ~0u, 0.2f }, 830 { rr::FACETYPE_FRONT, GL_DECR_WRAP, GL_INVERT, GL_REPLACE, 4, ~0u, ~0u, 1.0f } 831 }; 832 833 // All combinations of depth stencil functions. 834 { 835 tcu::TestCaseGroup* functionsGroup = new tcu::TestCaseGroup(m_testCtx, "stencil_depth_funcs", "Combinations of Depth and Stencil Functions"); 836 addChild(functionsGroup); 837 838 for (int stencilFunc = 0; stencilFunc < DE_LENGTH_OF_ARRAY(compareFuncs)+1; stencilFunc++) 839 { 840 // One extra: depth test disabled. 841 for (int depthFunc = 0; depthFunc < DE_LENGTH_OF_ARRAY(compareFuncs)+1; depthFunc++) 842 { 843 DepthStencilParams params; 844 ostringstream name; 845 bool hasStencilFunc = de::inBounds(stencilFunc, 0, DE_LENGTH_OF_ARRAY(compareFuncs)); 846 bool hasDepthFunc = de::inBounds(depthFunc, 0, DE_LENGTH_OF_ARRAY(compareFuncs)); 847 848 if (hasStencilFunc) 849 name << "stencil_" << compareFuncs[stencilFunc].name << "_"; 850 else 851 name << "no_stencil_"; 852 853 if (hasDepthFunc) 854 name << "depth_" << compareFuncs[depthFunc].name; 855 else 856 name << "no_depth"; 857 858 params.depthFunc = hasDepthFunc ? compareFuncs[depthFunc].func : 0; 859 params.depthTestEnabled = hasDepthFunc; 860 params.depthWriteMask = true; 861 862 params.stencilTestEnabled = hasStencilFunc; 863 864 vector<DepthStencilParams> cases; 865 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(functionCases); ndx++) 866 { 867 rr::FaceType visible = functionCases[ndx].visibleFace; 868 rr::FaceType notVisible = visible == rr::FACETYPE_FRONT ? rr::FACETYPE_BACK : rr::FACETYPE_FRONT; 869 870 params.depth = functionCases[ndx].depth; 871 params.visibleFace = visible; 872 873 params.stencil[visible].function = hasStencilFunc ? compareFuncs[stencilFunc].func : 0; 874 params.stencil[visible].reference = functionCases[ndx].stencilRef; 875 params.stencil[visible].stencilFailOp = functionCases[ndx].sFail; 876 params.stencil[visible].depthFailOp = functionCases[ndx].dFail; 877 params.stencil[visible].depthPassOp = functionCases[ndx].dPass; 878 params.stencil[visible].compareMask = functionCases[ndx].compareMask; 879 params.stencil[visible].writeMask = functionCases[ndx].writeMask; 880 881 params.stencil[notVisible].function = GL_ALWAYS; 882 params.stencil[notVisible].reference = 0; 883 params.stencil[notVisible].stencilFailOp = GL_REPLACE; 884 params.stencil[notVisible].depthFailOp = GL_REPLACE; 885 params.stencil[notVisible].depthPassOp = GL_REPLACE; 886 params.stencil[notVisible].compareMask = 0u; 887 params.stencil[notVisible].writeMask = ~0u; 888 889 890 cases.push_back(params); 891 } 892 893 functionsGroup->addChild(new DepthStencilCase(m_context, name.str().c_str(), "", cases)); 894 } 895 } 896 } 897 898 static const struct 899 { 900 rr::FaceType visibleFace; 901 deUint32 func; 902 int ref; 903 deUint32 compareMask; 904 deUint32 writeMask; 905 } opCombinationCases[] = 906 { 907 { rr::FACETYPE_BACK, GL_LESS, 4, ~0u, ~0u }, 908 { rr::FACETYPE_FRONT, GL_GREATER, 2, ~0u, ~0u }, 909 { rr::FACETYPE_BACK, GL_EQUAL, 3, ~2u, ~0u }, 910 { rr::FACETYPE_FRONT, GL_NOTEQUAL, 1, ~0u, ~1u } 911 }; 912 913 // All combinations of stencil ops. 914 { 915 tcu::TestCaseGroup* opCombinationGroup = new tcu::TestCaseGroup(m_testCtx, "stencil_ops", "Stencil Op Combinations"); 916 addChild(opCombinationGroup); 917 918 for (int sFail = 0; sFail < DE_LENGTH_OF_ARRAY(stencilOps); sFail++) 919 { 920 for (int dFail = 0; dFail < DE_LENGTH_OF_ARRAY(stencilOps); dFail++) 921 { 922 for (int dPass = 0; dPass < DE_LENGTH_OF_ARRAY(stencilOps); dPass++) 923 { 924 DepthStencilParams params; 925 ostringstream name; 926 927 name << stencilOps[sFail].name << "_" << stencilOps[dFail].name << "_" << stencilOps[dPass].name; 928 929 params.depthFunc = GL_LEQUAL; 930 params.depth = 0.0f; 931 params.depthTestEnabled = true; 932 params.depthWriteMask = true; 933 934 params.stencilTestEnabled = true; 935 936 vector<DepthStencilParams> cases; 937 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(opCombinationCases); ndx++) 938 { 939 rr::FaceType visible = opCombinationCases[ndx].visibleFace; 940 rr::FaceType notVisible = visible == rr::FACETYPE_FRONT ? rr::FACETYPE_BACK : rr::FACETYPE_FRONT; 941 942 params.visibleFace = visible; 943 944 params.stencil[visible].function = opCombinationCases[ndx].func; 945 params.stencil[visible].reference = opCombinationCases[ndx].ref; 946 params.stencil[visible].stencilFailOp = stencilOps[sFail].op; 947 params.stencil[visible].depthFailOp = stencilOps[dFail].op; 948 params.stencil[visible].depthPassOp = stencilOps[dPass].op; 949 params.stencil[visible].compareMask = opCombinationCases[ndx].compareMask; 950 params.stencil[visible].writeMask = opCombinationCases[ndx].writeMask; 951 952 params.stencil[notVisible].function = GL_ALWAYS; 953 params.stencil[notVisible].reference = 0; 954 params.stencil[notVisible].stencilFailOp = GL_REPLACE; 955 params.stencil[notVisible].depthFailOp = GL_REPLACE; 956 params.stencil[notVisible].depthPassOp = GL_REPLACE; 957 params.stencil[notVisible].compareMask = 0u; 958 params.stencil[notVisible].writeMask = ~0u; 959 960 961 cases.push_back(params); 962 } 963 964 opCombinationGroup->addChild(new DepthStencilCase(m_context, name.str().c_str(), "", cases)); 965 } 966 } 967 } 968 } 969 970 // Write masks 971 { 972 tcu::TestCaseGroup* writeMaskGroup = new tcu::TestCaseGroup(m_testCtx, "write_mask", "Depth and Stencil Write Masks"); 973 addChild(writeMaskGroup); 974 975 // Depth mask 976 { 977 DepthStencilParams params; 978 979 params.depthFunc = GL_LEQUAL; 980 params.depth = 0.0f; 981 params.depthTestEnabled = true; 982 params.stencilTestEnabled = true; 983 984 params.stencil[rr::FACETYPE_FRONT].function = GL_NOTEQUAL; 985 params.stencil[rr::FACETYPE_FRONT].reference = 1; 986 params.stencil[rr::FACETYPE_FRONT].stencilFailOp = GL_INVERT; 987 params.stencil[rr::FACETYPE_FRONT].depthFailOp = GL_INCR; 988 params.stencil[rr::FACETYPE_FRONT].depthPassOp = GL_DECR; 989 params.stencil[rr::FACETYPE_FRONT].compareMask = ~0u; 990 params.stencil[rr::FACETYPE_FRONT].writeMask = ~0u; 991 992 params.stencil[rr::FACETYPE_BACK].function = GL_ALWAYS; 993 params.stencil[rr::FACETYPE_BACK].reference = 0; 994 params.stencil[rr::FACETYPE_BACK].stencilFailOp = GL_REPLACE; 995 params.stencil[rr::FACETYPE_BACK].depthFailOp = GL_INVERT; 996 params.stencil[rr::FACETYPE_BACK].depthPassOp = GL_INCR; 997 params.stencil[rr::FACETYPE_BACK].compareMask = ~0u; 998 params.stencil[rr::FACETYPE_BACK].writeMask = ~0u; 999 1000 vector<DepthStencilParams> cases; 1001 1002 // Case 1: front, depth write enabled 1003 params.visibleFace = rr::FACETYPE_FRONT; 1004 params.depthWriteMask = true; 1005 cases.push_back(params); 1006 1007 // Case 2: front, depth write disabled 1008 params.visibleFace = rr::FACETYPE_FRONT; 1009 params.depthWriteMask = false; 1010 cases.push_back(params); 1011 1012 // Case 3: back, depth write enabled 1013 params.visibleFace = rr::FACETYPE_BACK; 1014 params.depthWriteMask = true; 1015 cases.push_back(params); 1016 1017 // Case 4: back, depth write disabled 1018 params.visibleFace = rr::FACETYPE_BACK; 1019 params.depthWriteMask = false; 1020 cases.push_back(params); 1021 1022 writeMaskGroup->addChild(new DepthStencilCase(m_context, "depth", "Depth Write Mask", cases)); 1023 } 1024 1025 // Stencil write masks. 1026 { 1027 static const struct 1028 { 1029 rr::FaceType visibleFace; 1030 deUint32 frontWriteMask; 1031 deUint32 backWriteMask; 1032 } stencilWmaskCases[] = 1033 { 1034 { rr::FACETYPE_FRONT, ~0u, 0u }, 1035 { rr::FACETYPE_FRONT, 0u, ~0u }, 1036 { rr::FACETYPE_FRONT, 0xfu, 0xf0u }, 1037 { rr::FACETYPE_FRONT, 0x2u, 0x4u }, 1038 { rr::FACETYPE_BACK, 0u, ~0u }, 1039 { rr::FACETYPE_BACK, ~0u, 0u }, 1040 { rr::FACETYPE_BACK, 0xf0u, 0xfu }, 1041 { rr::FACETYPE_BACK, 0x4u, 0x2u } 1042 }; 1043 1044 DepthStencilParams params; 1045 1046 params.depthFunc = GL_LEQUAL; 1047 params.depth = 0.0f; 1048 params.depthTestEnabled = true; 1049 params.depthWriteMask = true; 1050 params.stencilTestEnabled = true; 1051 1052 params.stencil[rr::FACETYPE_FRONT].function = GL_NOTEQUAL; 1053 params.stencil[rr::FACETYPE_FRONT].reference = 1; 1054 params.stencil[rr::FACETYPE_FRONT].stencilFailOp = GL_INVERT; 1055 params.stencil[rr::FACETYPE_FRONT].depthFailOp = GL_INCR; 1056 params.stencil[rr::FACETYPE_FRONT].depthPassOp = GL_DECR; 1057 params.stencil[rr::FACETYPE_FRONT].compareMask = ~0u; 1058 1059 params.stencil[rr::FACETYPE_BACK].function = GL_ALWAYS; 1060 params.stencil[rr::FACETYPE_BACK].reference = 0; 1061 params.stencil[rr::FACETYPE_BACK].stencilFailOp = GL_REPLACE; 1062 params.stencil[rr::FACETYPE_BACK].depthFailOp = GL_INVERT; 1063 params.stencil[rr::FACETYPE_BACK].depthPassOp = GL_INCR; 1064 params.stencil[rr::FACETYPE_BACK].compareMask = ~0u; 1065 1066 vector<DepthStencilParams> cases; 1067 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stencilWmaskCases); ndx++) 1068 { 1069 params.visibleFace = stencilWmaskCases[ndx].visibleFace; 1070 params.stencil[rr::FACETYPE_FRONT].writeMask = stencilWmaskCases[ndx].frontWriteMask; 1071 params.stencil[rr::FACETYPE_BACK].writeMask = stencilWmaskCases[ndx].backWriteMask; 1072 cases.push_back(params); 1073 } 1074 1075 writeMaskGroup->addChild(new DepthStencilCase(m_context, "stencil", "Stencil Write Mask", cases)); 1076 } 1077 1078 // Depth & stencil write masks. 1079 { 1080 static const struct 1081 { 1082 bool depthWriteMask; 1083 rr::FaceType visibleFace; 1084 deUint32 frontWriteMask; 1085 deUint32 backWriteMask; 1086 } depthStencilWmaskCases[] = 1087 { 1088 { false, rr::FACETYPE_FRONT, ~0u, 0u }, 1089 { false, rr::FACETYPE_FRONT, 0u, ~0u }, 1090 { false, rr::FACETYPE_FRONT, 0xfu, 0xf0u }, 1091 { true, rr::FACETYPE_FRONT, ~0u, 0u }, 1092 { true, rr::FACETYPE_FRONT, 0u, ~0u }, 1093 { true, rr::FACETYPE_FRONT, 0xfu, 0xf0u }, 1094 { false, rr::FACETYPE_BACK, 0u, ~0u }, 1095 { false, rr::FACETYPE_BACK, ~0u, 0u }, 1096 { false, rr::FACETYPE_BACK, 0xf0u, 0xfu }, 1097 { true, rr::FACETYPE_BACK, 0u, ~0u }, 1098 { true, rr::FACETYPE_BACK, ~0u, 0u }, 1099 { true, rr::FACETYPE_BACK, 0xf0u, 0xfu } 1100 }; 1101 1102 DepthStencilParams params; 1103 1104 params.depthFunc = GL_LEQUAL; 1105 params.depth = 0.0f; 1106 params.depthTestEnabled = true; 1107 params.depthWriteMask = true; 1108 params.stencilTestEnabled = true; 1109 1110 params.stencil[rr::FACETYPE_FRONT].function = GL_NOTEQUAL; 1111 params.stencil[rr::FACETYPE_FRONT].reference = 1; 1112 params.stencil[rr::FACETYPE_FRONT].stencilFailOp = GL_INVERT; 1113 params.stencil[rr::FACETYPE_FRONT].depthFailOp = GL_INCR; 1114 params.stencil[rr::FACETYPE_FRONT].depthPassOp = GL_DECR; 1115 params.stencil[rr::FACETYPE_FRONT].compareMask = ~0u; 1116 1117 params.stencil[rr::FACETYPE_BACK].function = GL_ALWAYS; 1118 params.stencil[rr::FACETYPE_BACK].reference = 0; 1119 params.stencil[rr::FACETYPE_BACK].stencilFailOp = GL_REPLACE; 1120 params.stencil[rr::FACETYPE_BACK].depthFailOp = GL_INVERT; 1121 params.stencil[rr::FACETYPE_BACK].depthPassOp = GL_INCR; 1122 params.stencil[rr::FACETYPE_BACK].compareMask = ~0u; 1123 1124 vector<DepthStencilParams> cases; 1125 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilWmaskCases); ndx++) 1126 { 1127 params.depthWriteMask = depthStencilWmaskCases[ndx].depthWriteMask; 1128 params.visibleFace = depthStencilWmaskCases[ndx].visibleFace; 1129 params.stencil[rr::FACETYPE_FRONT].writeMask = depthStencilWmaskCases[ndx].frontWriteMask; 1130 params.stencil[rr::FACETYPE_BACK].writeMask = depthStencilWmaskCases[ndx].backWriteMask; 1131 cases.push_back(params); 1132 } 1133 1134 writeMaskGroup->addChild(new DepthStencilCase(m_context, "both", "Depth and Stencil Write Masks", cases)); 1135 } 1136 } 1137 1138 // Randomized cases 1139 { 1140 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Randomized Depth and Stencil Test Cases"); 1141 addChild(randomGroup); 1142 1143 for (int caseNdx = 0; caseNdx < NUM_RANDOM_CASES; caseNdx++) 1144 { 1145 vector<DepthStencilParams> subCases (NUM_RANDOM_SUB_CASES); 1146 de::Random rnd (deInt32Hash(caseNdx) ^ deInt32Hash(m_testCtx.getCommandLine().getBaseSeed())); 1147 1148 for (vector<DepthStencilParams>::iterator iter = subCases.begin(); iter != subCases.end(); ++iter) 1149 randomDepthStencilState(rnd, *iter); 1150 1151 randomGroup->addChild(new DepthStencilCase(m_context, de::toString(caseNdx).c_str(), "", subCases)); 1152 } 1153 } 1154 } 1155 1156 } // Functional 1157 } // gles3 1158 } // deqp 1159