Fix GLES2 format mismatch
[platform/upstream/VK-GL-CTS.git] / modules / gles3 / functional / es3fDepthStencilTests.cpp
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/(float)(numValues-1);
275
276                 for (int ndx = 0; ndx < numValues; ndx++)
277                         depthValues[ndx] = -1.0f + depthStep*(float)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*(float)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*float(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