xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fOcclusionQueryTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 Occlusion query tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es3fOcclusionQueryTests.hpp"
25 
26 #include "tcuTestLog.hpp"
27 #include "tcuVector.hpp"
28 #include "tcuSurface.hpp"
29 #include "tcuRenderTarget.hpp"
30 #include "gluShaderProgram.hpp"
31 #include "gluPixelTransfer.hpp"
32 #include "deRandom.hpp"
33 #include "deString.h"
34 
35 #include "glw.h"
36 
37 namespace deqp
38 {
39 namespace gles3
40 {
41 namespace Functional
42 {
43 
44 static const tcu::Vec4 DEPTH_WRITE_COLOR   = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
45 static const tcu::Vec4 DEPTH_CLEAR_COLOR   = tcu::Vec4(0.0f, 0.5f, 0.8f, 1.0f);
46 static const tcu::Vec4 STENCIL_WRITE_COLOR = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
47 static const tcu::Vec4 STENCIL_CLEAR_COLOR = tcu::Vec4(0.0f, 0.8f, 0.5f, 1.0f);
48 static const tcu::Vec4 TARGET_COLOR        = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
49 static const int ELEMENTS_PER_VERTEX       = 4;
50 static const int NUM_CASE_ITERATIONS       = 10;
51 
52 // Constants to tweak visible/invisible case probability balance.
53 
54 static const int DEPTH_CLEAR_OFFSET   = 100;
55 static const int STENCIL_CLEAR_OFFSET = 100;
56 static const int SCISSOR_OFFSET       = 100;
57 static const int SCISSOR_MINSIZE      = 250;
58 
59 enum OccluderType
60 {
61     OCCLUDER_SCISSOR       = (1 << 0),
62     OCCLUDER_DEPTH_WRITE   = (1 << 1),
63     OCCLUDER_DEPTH_CLEAR   = (1 << 2),
64     OCCLUDER_STENCIL_WRITE = (1 << 3),
65     OCCLUDER_STENCIL_CLEAR = (1 << 4)
66 };
67 
68 class OcclusionQueryCase : public TestCase
69 {
70 public:
71     OcclusionQueryCase(Context &context, const char *name, const char *description, int numOccluderDraws,
72                        int numOccludersPerDraw, float occluderSize, int numTargetDraws, int numTargetsPerDraw,
73                        float targetSize, uint32_t queryMode, uint32_t occluderTypes);
74     ~OcclusionQueryCase(void);
75 
76     void init(void);
77     void deinit(void);
78     IterateResult iterate(void);
79 
80 private:
81     OcclusionQueryCase(const OcclusionQueryCase &other);
82     OcclusionQueryCase &operator=(const OcclusionQueryCase &other);
83 
84     int m_numOccluderDraws;
85     int m_numOccludersPerDraw;
86     float m_occluderSize;
87     int m_numTargetDraws;
88     int m_numTargetsPerDraw;
89     float m_targetSize;
90     uint32_t m_queryMode;
91     uint32_t m_occluderTypes;
92 
93     glu::RenderContext &m_renderCtx;
94     glu::ShaderProgram *m_program;
95     int m_iterNdx;
96     de::Random m_rnd;
97 };
98 
OcclusionQueryCase(Context & context,const char * name,const char * description,int numOccluderDraws,int numOccludersPerDraw,float occluderSize,int numTargetDraws,int numTargetsPerDraw,float targetSize,uint32_t queryMode,uint32_t occluderTypes)99 OcclusionQueryCase::OcclusionQueryCase(Context &context, const char *name, const char *description,
100                                        int numOccluderDraws, int numOccludersPerDraw, float occluderSize,
101                                        int numTargetDraws, int numTargetsPerDraw, float targetSize, uint32_t queryMode,
102                                        uint32_t occluderTypes)
103     : TestCase(context, name, description)
104     , m_numOccluderDraws(numOccluderDraws)
105     , m_numOccludersPerDraw(numOccludersPerDraw)
106     , m_occluderSize(occluderSize)
107     , m_numTargetDraws(numTargetDraws)
108     , m_numTargetsPerDraw(numTargetsPerDraw)
109     , m_targetSize(targetSize)
110     , m_queryMode(queryMode)
111     , m_occluderTypes(occluderTypes)
112     , m_renderCtx(context.getRenderContext())
113     , m_program(DE_NULL)
114     , m_iterNdx(0)
115     , m_rnd(deStringHash(name))
116 {
117 }
118 
~OcclusionQueryCase(void)119 OcclusionQueryCase::~OcclusionQueryCase(void)
120 {
121     OcclusionQueryCase::deinit();
122 }
123 
generateVertices(std::vector<float> & dst,float width,float height,int primitiveCount,int verticesPerPrimitive,de::Random rnd,float primitiveSize,float minZ,float maxZ)124 static void generateVertices(std::vector<float> &dst, float width, float height, int primitiveCount,
125                              int verticesPerPrimitive, de::Random rnd, float primitiveSize, float minZ, float maxZ)
126 {
127     float w = width / 2.0f;
128     float h = height / 2.0f;
129     float s = primitiveSize / 2.0f;
130 
131     int vertexCount = verticesPerPrimitive * primitiveCount;
132     dst.resize(vertexCount * ELEMENTS_PER_VERTEX);
133 
134     for (int i = 0; i < vertexCount; i += 3) // First loop gets a random point inside unit square
135     {
136         float rndX = rnd.getFloat(-w, w);
137         float rndY = rnd.getFloat(-h, h);
138 
139         for (int j = 0; j < verticesPerPrimitive;
140              j++) // Second loop gets 3 random points within given distance s from (rndX, rndY)
141         {
142             dst[(i + j) * ELEMENTS_PER_VERTEX]     = rndX + rnd.getFloat(-s, s); // x
143             dst[(i + j) * ELEMENTS_PER_VERTEX + 1] = rndY + rnd.getFloat(-s, s); // y
144             dst[(i + j) * ELEMENTS_PER_VERTEX + 2] = rnd.getFloat(minZ, maxZ);   // z
145             dst[(i + j) * ELEMENTS_PER_VERTEX + 3] = 1.0f;                       // w
146         }
147     }
148 }
149 
init(void)150 void OcclusionQueryCase::init(void)
151 {
152     const char *vertShaderSource = "#version 300 es\n"
153                                    "layout(location = 0) in mediump vec4 a_position;\n"
154                                    "\n"
155                                    "void main (void)\n"
156                                    "{\n"
157                                    "    gl_Position = a_position;\n"
158                                    "}\n";
159 
160     const char *fragShaderSource = "#version 300 es\n"
161                                    "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
162                                    "uniform mediump vec4 u_color;\n"
163                                    "\n"
164                                    "void main (void)\n"
165                                    "{\n"
166                                    "    mediump float depth_gradient = max(gl_FragCoord.z, 0.0);\n"
167                                    "    mediump float bias = 0.1;\n"
168                                    "    dEQP_FragColor = vec4(u_color.xyz * (depth_gradient + bias), 1.0);\n"
169                                    "}\n";
170 
171     DE_ASSERT(!m_program);
172     m_program = new glu::ShaderProgram(m_context.getRenderContext(),
173                                        glu::makeVtxFragSources(vertShaderSource, fragShaderSource));
174 
175     if (!m_program->isOk())
176     {
177         m_testCtx.getLog() << *m_program;
178         delete m_program;
179         m_program = DE_NULL;
180         TCU_FAIL("Failed to compile shader program");
181     }
182 
183     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); // Initialize test result to pass.
184     GLU_CHECK_MSG("Case initialization finished");
185 }
186 
deinit(void)187 void OcclusionQueryCase::deinit(void)
188 {
189     delete m_program;
190     m_program = DE_NULL;
191 }
192 
iterate(void)193 OcclusionQueryCase::IterateResult OcclusionQueryCase::iterate(void)
194 {
195     tcu::TestLog &log                     = m_testCtx.getLog();
196     const tcu::RenderTarget &renderTarget = m_context.getRenderTarget();
197     uint32_t colorUnif                    = glGetUniformLocation(m_program->getProgram(), "u_color");
198 
199     std::vector<float> occluderVertices;
200     std::vector<float> targetVertices;
201     std::vector<uint32_t> queryIds(1, 0);
202     bool queryResult     = false;
203     bool colorReadResult = false;
204     int targetW          = renderTarget.getWidth();
205     int targetH          = renderTarget.getHeight();
206 
207     log << tcu::TestLog::Message << "Case iteration " << m_iterNdx + 1 << " / " << NUM_CASE_ITERATIONS
208         << tcu::TestLog::EndMessage;
209     log << tcu::TestLog::Message << "Parameters:\n"
210         << "- " << m_numOccluderDraws << " occluder draws, " << m_numOccludersPerDraw << " primitive writes per draw,\n"
211         << "- " << m_numTargetDraws << " target draws, " << m_numTargetsPerDraw << " targets per draw\n"
212         << tcu::TestLog::EndMessage;
213 
214     DE_ASSERT(m_program);
215 
216     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
217     glClearDepthf(1.0f);
218     glClearStencil(0);
219     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
220     glUseProgram(m_program->getProgram());
221     glEnableVertexAttribArray(0);
222 
223     // Draw occluders
224 
225     std::vector<OccluderType> occOptions(0);
226     if (m_occluderTypes & OCCLUDER_DEPTH_WRITE)
227         occOptions.push_back(OCCLUDER_DEPTH_WRITE);
228     if (m_occluderTypes & OCCLUDER_DEPTH_CLEAR)
229         occOptions.push_back(OCCLUDER_DEPTH_CLEAR);
230     if (m_occluderTypes & OCCLUDER_STENCIL_WRITE)
231         occOptions.push_back(OCCLUDER_STENCIL_WRITE);
232     if (m_occluderTypes & OCCLUDER_STENCIL_CLEAR)
233         occOptions.push_back(OCCLUDER_STENCIL_CLEAR);
234 
235     for (int i = 0; i < m_numOccluderDraws; i++)
236     {
237         if (occOptions.empty())
238             break;
239 
240         OccluderType type = occOptions[m_rnd.getInt(
241             0, (int)occOptions.size() - 1)]; // Choosing a random occluder type from available options
242 
243         switch (type)
244         {
245         case OCCLUDER_DEPTH_WRITE:
246             log << tcu::TestLog::Message << "Occluder draw " << i + 1 << " / " << m_numOccluderDraws << " : "
247                 << "Depth write" << tcu::TestLog::EndMessage;
248 
249             generateVertices(occluderVertices, 2.0f, 2.0f, m_numOccludersPerDraw, 3, m_rnd, m_occluderSize, 0.0f,
250                              0.6f); // Generate vertices for occluding primitives
251 
252             DE_ASSERT(!occluderVertices.empty());
253 
254             glEnable(GL_DEPTH_TEST);
255             glUniform4f(colorUnif, DEPTH_WRITE_COLOR.x(), DEPTH_WRITE_COLOR.y(), DEPTH_WRITE_COLOR.z(),
256                         DEPTH_WRITE_COLOR.w());
257             glVertexAttribPointer(0, ELEMENTS_PER_VERTEX, GL_FLOAT, GL_FALSE, 0, &occluderVertices[0]);
258             glDrawArrays(GL_TRIANGLES, 0, 3 * m_numOccludersPerDraw);
259             glDisable(GL_DEPTH_TEST);
260 
261             break;
262 
263         case OCCLUDER_DEPTH_CLEAR:
264         {
265             int scissorBoxX = m_rnd.getInt(-DEPTH_CLEAR_OFFSET, targetW);
266             int scissorBoxY = m_rnd.getInt(-DEPTH_CLEAR_OFFSET, targetH);
267             int scissorBoxW = m_rnd.getInt(DEPTH_CLEAR_OFFSET, targetW + DEPTH_CLEAR_OFFSET);
268             int scissorBoxH = m_rnd.getInt(DEPTH_CLEAR_OFFSET, targetH + DEPTH_CLEAR_OFFSET);
269 
270             log << tcu::TestLog::Message << "Occluder draw " << i + 1 << " / " << m_numOccluderDraws << " : "
271                 << "Depth clear" << tcu::TestLog::EndMessage;
272             log << tcu::TestLog::Message << "Depth-clearing box drawn at "
273                 << "(" << scissorBoxX << ", " << scissorBoxY << ")"
274                 << ", width = " << scissorBoxW << ", height = " << scissorBoxH << "." << tcu::TestLog::EndMessage;
275 
276             glEnable(GL_SCISSOR_TEST);
277             glScissor(scissorBoxX, scissorBoxY, scissorBoxW, scissorBoxH);
278             glClearDepthf(0.0f);
279             glClearColor(DEPTH_CLEAR_COLOR.x(), DEPTH_CLEAR_COLOR.y(), DEPTH_CLEAR_COLOR.z(), DEPTH_CLEAR_COLOR.w());
280             glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
281             glDisable(GL_SCISSOR_TEST);
282 
283             break;
284         }
285 
286         case OCCLUDER_STENCIL_WRITE:
287             log << tcu::TestLog::Message << "Occluder draw " << i + 1 << " / " << m_numOccluderDraws << " : "
288                 << "Stencil write" << tcu::TestLog::EndMessage;
289 
290             generateVertices(occluderVertices, 2.0f, 2.0f, m_numOccludersPerDraw, 3, m_rnd, m_occluderSize, 0.0f, 0.6f);
291 
292             glStencilFunc(GL_ALWAYS, 1, 0xFF);
293             glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
294 
295             DE_ASSERT(!occluderVertices.empty());
296 
297             glEnable(GL_STENCIL_TEST);
298             glUniform4f(colorUnif, STENCIL_WRITE_COLOR.x(), STENCIL_WRITE_COLOR.y(), STENCIL_WRITE_COLOR.z(),
299                         STENCIL_WRITE_COLOR.w());
300             glVertexAttribPointer(0, ELEMENTS_PER_VERTEX, GL_FLOAT, GL_FALSE, 0, &occluderVertices[0]);
301             glDrawArrays(GL_TRIANGLES, 0, 3 * m_numOccludersPerDraw);
302             glDisable(GL_STENCIL_TEST);
303 
304             break;
305 
306         case OCCLUDER_STENCIL_CLEAR:
307         {
308             int scissorBoxX = m_rnd.getInt(-STENCIL_CLEAR_OFFSET, targetW);
309             int scissorBoxY = m_rnd.getInt(-STENCIL_CLEAR_OFFSET, targetH);
310             int scissorBoxW = m_rnd.getInt(STENCIL_CLEAR_OFFSET, targetW + STENCIL_CLEAR_OFFSET);
311             int scissorBoxH = m_rnd.getInt(STENCIL_CLEAR_OFFSET, targetH + STENCIL_CLEAR_OFFSET);
312 
313             log << tcu::TestLog::Message << "Occluder draw " << i + 1 << " / " << m_numOccluderDraws << " : "
314                 << "Stencil clear" << tcu::TestLog::EndMessage;
315             log << tcu::TestLog::Message << "Stencil-clearing box drawn at "
316                 << "(" << scissorBoxX << ", " << scissorBoxY << ")"
317                 << ", width = " << scissorBoxW << ", height = " << scissorBoxH << "." << tcu::TestLog::EndMessage;
318 
319             glEnable(GL_SCISSOR_TEST);
320             glScissor(scissorBoxX, scissorBoxY, scissorBoxW, scissorBoxH);
321             glClearStencil(1);
322             glClearColor(STENCIL_CLEAR_COLOR.x(), STENCIL_CLEAR_COLOR.y(), STENCIL_CLEAR_COLOR.z(),
323                          STENCIL_CLEAR_COLOR.w());
324             glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
325             glDisable(GL_SCISSOR_TEST);
326 
327             break;
328         }
329 
330         default:
331             DE_ASSERT(false);
332             break;
333         }
334     }
335 
336     if (m_occluderTypes & OCCLUDER_SCISSOR)
337     {
338         int scissorBoxX = m_rnd.getInt(-SCISSOR_OFFSET, targetW - SCISSOR_OFFSET);
339         int scissorBoxY = m_rnd.getInt(-SCISSOR_OFFSET, targetH - SCISSOR_OFFSET);
340         int scissorBoxW = m_rnd.getInt(SCISSOR_MINSIZE, targetW + SCISSOR_OFFSET);
341         int scissorBoxH = m_rnd.getInt(SCISSOR_MINSIZE, targetH + SCISSOR_OFFSET);
342 
343         log << tcu::TestLog::Message << "Scissor box drawn at "
344             << "(" << scissorBoxX << ", " << scissorBoxY << ")"
345             << ", width = " << scissorBoxW << ", height = " << scissorBoxH << "." << tcu::TestLog::EndMessage;
346 
347         glEnable(GL_SCISSOR_TEST);
348         glScissor(scissorBoxX, scissorBoxY, scissorBoxW, scissorBoxH);
349     }
350 
351     glGenQueries(1, &queryIds[0]);
352     glBeginQuery(m_queryMode, queryIds[0]);
353     GLU_CHECK_MSG("Occlusion query started");
354 
355     // Draw target primitives
356 
357     glEnable(GL_DEPTH_TEST);
358     glEnable(GL_STENCIL_TEST);
359     glStencilFunc(GL_EQUAL, 0, 0xFF);
360 
361     for (int i = 0; i < m_numTargetDraws; i++)
362     {
363         generateVertices(targetVertices, 2.0f, 2.0f, m_numTargetsPerDraw, 3, m_rnd, m_targetSize, 0.4f,
364                          1.0f); // Generate vertices for target primitives
365 
366         if (!targetVertices.empty())
367         {
368             glUniform4f(colorUnif, TARGET_COLOR.x(), TARGET_COLOR.y(), TARGET_COLOR.z(), TARGET_COLOR.w());
369             glVertexAttribPointer(0, ELEMENTS_PER_VERTEX, GL_FLOAT, GL_FALSE, 0, &targetVertices[0]);
370             glDrawArrays(GL_TRIANGLES, 0, 3 * m_numTargetsPerDraw);
371         }
372     }
373 
374     glEndQuery(m_queryMode);
375     glFinish();
376     glDisable(GL_SCISSOR_TEST);
377     glDisable(GL_STENCIL_TEST);
378     glDisable(GL_DEPTH_TEST);
379 
380     // Check that query result is available.
381     {
382         uint32_t resultAvailable = GL_FALSE;
383         glGetQueryObjectuiv(queryIds[0], GL_QUERY_RESULT_AVAILABLE, &resultAvailable);
384 
385         if (resultAvailable == GL_FALSE)
386             TCU_FAIL("Occlusion query failed to return a result after glFinish()");
387     }
388 
389     // Read query result.
390     {
391         uint32_t result = 0;
392         glGetQueryObjectuiv(queryIds[0], GL_QUERY_RESULT, &result);
393         queryResult = (result != GL_FALSE);
394     }
395 
396     glDeleteQueries(1, &queryIds[0]);
397     GLU_CHECK_MSG("Occlusion query finished");
398 
399     // Read pixel data
400 
401     tcu::Surface pixels(renderTarget.getWidth(), renderTarget.getHeight());
402     glu::readPixels(m_context.getRenderContext(), 0, 0, pixels.getAccess());
403 
404     {
405         int width  = pixels.getWidth();
406         int height = pixels.getHeight();
407 
408         for (int y = 0; y < height; y++)
409         {
410             for (int x = 0; x < width; x++)
411             {
412                 if (pixels.getPixel(x, y).getRed() != 0)
413                 {
414                     colorReadResult = true;
415                     break;
416                 }
417             }
418             if (colorReadResult)
419                 break;
420         }
421     }
422 
423     log << tcu::TestLog::Message << "Occlusion query result:  Target " << (queryResult ? "visible" : "invisible")
424         << "\n"
425         << "Framebuffer read result: Target " << (colorReadResult ? "visible" : "invisible")
426         << tcu::TestLog::EndMessage;
427 
428     bool testOk = false;
429     if (m_queryMode == GL_ANY_SAMPLES_PASSED_CONSERVATIVE)
430     {
431         if (queryResult || colorReadResult)
432             testOk = queryResult; // Allow conservative occlusion query to return false positives.
433         else
434             testOk = queryResult == colorReadResult;
435     }
436     else
437         testOk = (queryResult == colorReadResult);
438 
439     if (!testOk)
440     {
441         log << tcu::TestLog::Image("Result image", "Result image", pixels);
442         log << tcu::TestLog::Message << "Case FAILED!" << tcu::TestLog::EndMessage;
443 
444         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
445         return STOP;
446     }
447 
448     log << tcu::TestLog::Message << "Case passed!" << tcu::TestLog::EndMessage;
449 
450     return (++m_iterNdx < NUM_CASE_ITERATIONS) ? CONTINUE : STOP;
451 }
452 
OcclusionQueryTests(Context & context)453 OcclusionQueryTests::OcclusionQueryTests(Context &context)
454     : TestCaseGroup(context, "occlusion_query", "Occlusion Query Tests")
455 {
456 }
457 
~OcclusionQueryTests(void)458 OcclusionQueryTests::~OcclusionQueryTests(void)
459 {
460 }
461 
init(void)462 void OcclusionQueryTests::init(void)
463 {
464     // Strict occlusion query cases
465 
466     addChild(new OcclusionQueryCase(m_context, "scissor", "scissor", 1, 10, 1.6f, 1, 1, 0.3f, GL_ANY_SAMPLES_PASSED,
467                                     OCCLUDER_SCISSOR));
468     addChild(new OcclusionQueryCase(m_context, "depth_write", "depth_write", 8, 10, 1.6f, 1, 7, 0.3f,
469                                     GL_ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE));
470     addChild(new OcclusionQueryCase(m_context, "depth_clear", "depth_clear", 5, 10, 1.6f, 1, 5, 0.2f,
471                                     GL_ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_CLEAR));
472     addChild(new OcclusionQueryCase(m_context, "stencil_write", "stencil_write", 8, 10, 2.0f, 1, 5, 0.4f,
473                                     GL_ANY_SAMPLES_PASSED, OCCLUDER_STENCIL_WRITE));
474     addChild(new OcclusionQueryCase(m_context, "stencil_clear", "stencil_clear", 5, 10, 2.0f, 1, 3, 0.3f,
475                                     GL_ANY_SAMPLES_PASSED, OCCLUDER_STENCIL_CLEAR));
476 
477     addChild(new OcclusionQueryCase(m_context, "scissor_depth_write", "scissor_depth_write", 5, 10, 1.6f, 2, 5, 0.3f,
478                                     GL_ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE));
479     addChild(new OcclusionQueryCase(m_context, "scissor_depth_clear", "scissor_depth_clear", 7, 10, 1.6f, 2, 5, 1.0f,
480                                     GL_ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR));
481     addChild(new OcclusionQueryCase(m_context, "scissor_stencil_write", "scissor_stencil_write", 4, 10, 1.6f, 2, 5,
482                                     0.3f, GL_ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_WRITE));
483     addChild(new OcclusionQueryCase(m_context, "scissor_stencil_clear", "scissor_stencil_clear", 4, 10, 1.6f, 2, 5,
484                                     1.0f, GL_ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_CLEAR));
485     addChild(new OcclusionQueryCase(m_context, "depth_write_depth_clear", "depth_write_depth_clear", 7, 10, 1.6f, 1, 5,
486                                     0.2f, GL_ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR));
487     addChild(new OcclusionQueryCase(m_context, "depth_write_stencil_write", "depth_write_stencil_write", 8, 10, 1.6f, 1,
488                                     5, 0.3f, GL_ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE));
489     addChild(new OcclusionQueryCase(m_context, "depth_write_stencil_clear", "depth_write_stencil_clear", 8, 10, 1.6f, 1,
490                                     5, 0.3f, GL_ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_CLEAR));
491     addChild(new OcclusionQueryCase(m_context, "depth_clear_stencil_write", "depth_clear_stencil_write", 8, 10, 1.6f, 1,
492                                     5, 0.3f, GL_ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
493     addChild(new OcclusionQueryCase(m_context, "depth_clear_stencil_clear", "depth_clear_stencil_clear", 12, 10, 1.6f,
494                                     1, 5, 0.2f, GL_ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
495     addChild(new OcclusionQueryCase(m_context, "stencil_write_stencil_clear", "stencil_write_stencil_clear", 5, 10,
496                                     2.0f, 1, 5, 0.4f, GL_ANY_SAMPLES_PASSED,
497                                     OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
498 
499     addChild(new OcclusionQueryCase(m_context, "scissor_depth_write_depth_clear", "scissor_depth_write_depth_clear", 5,
500                                     10, 1.6f, 2, 5, 0.4f, GL_ANY_SAMPLES_PASSED,
501                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR));
502     addChild(new OcclusionQueryCase(m_context, "scissor_depth_write_stencil_write", "scissor_depth_write_stencil_write",
503                                     4, 10, 1.6f, 2, 5, 0.4f, GL_ANY_SAMPLES_PASSED,
504                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE));
505     addChild(new OcclusionQueryCase(m_context, "scissor_depth_write_stencil_clear", "scissor_depth_write_stencil_clear",
506                                     6, 10, 1.6f, 2, 5, 0.4f, GL_ANY_SAMPLES_PASSED,
507                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_CLEAR));
508     addChild(new OcclusionQueryCase(m_context, "scissor_depth_clear_stencil_write", "scissor_depth_clear_stencil_write",
509                                     4, 10, 1.6f, 2, 5, 0.4f, GL_ANY_SAMPLES_PASSED,
510                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
511     addChild(new OcclusionQueryCase(m_context, "scissor_depth_clear_stencil_clear", "scissor_depth_clear_stencil_clear",
512                                     5, 10, 1.6f, 2, 5, 0.4f, GL_ANY_SAMPLES_PASSED,
513                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
514     addChild(new OcclusionQueryCase(
515         m_context, "scissor_stencil_write_stencil_clear", "scissor_stencil_write_stencil_clear", 4, 10, 1.6f, 2, 5,
516         0.4f, GL_ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
517     addChild(new OcclusionQueryCase(
518         m_context, "depth_write_depth_clear_stencil_write", "depth_write_depth_clear_stencil_write", 7, 10, 1.6f, 2, 5,
519         0.4f, GL_ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
520     addChild(new OcclusionQueryCase(
521         m_context, "depth_write_depth_clear_stencil_clear", "depth_write_depth_clear_stencil_clear", 7, 10, 1.6f, 2, 5,
522         0.4f, GL_ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
523     addChild(new OcclusionQueryCase(
524         m_context, "depth_write_stencil_write_stencil_clear", "depth_write_stencil_write_stencil_clear", 7, 10, 1.6f, 2,
525         5, 0.4f, GL_ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
526     addChild(new OcclusionQueryCase(
527         m_context, "depth_clear_stencil_write_stencil_clear", "depth_clear_stencil_write_stencil_clear", 7, 10, 1.6f, 2,
528         5, 0.4f, GL_ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
529 
530     addChild(new OcclusionQueryCase(
531         m_context, "scissor_depth_write_depth_clear_stencil_write", "scissor_depth_write_depth_clear_stencil_write", 4,
532         10, 1.6f, 2, 5, 0.4f, GL_ANY_SAMPLES_PASSED,
533         OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
534     addChild(new OcclusionQueryCase(
535         m_context, "scissor_depth_write_depth_clear_stencil_clear", "scissor_depth_write_depth_clear_stencil_clear", 4,
536         10, 1.6f, 2, 5, 0.4f, GL_ANY_SAMPLES_PASSED,
537         OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
538     addChild(new OcclusionQueryCase(
539         m_context, "scissor_depth_write_stencil_write_stencil_clear", "scissor_depth_write_stencil_write_stencil_clear",
540         5, 10, 1.6f, 2, 5, 0.4f, GL_ANY_SAMPLES_PASSED,
541         OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
542     addChild(new OcclusionQueryCase(
543         m_context, "scissor_depth_clear_stencil_write_stencil_clear", "scissor_depth_clear_stencil_write_stencil_clear",
544         4, 10, 1.6f, 2, 5, 0.4f, GL_ANY_SAMPLES_PASSED,
545         OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
546     addChild(new OcclusionQueryCase(
547         m_context, "depth_write_depth_clear_stencil_write_stencil_clear",
548         "depth_write_depth_clear_stencil_write_stencil_clear", 7, 10, 1.6f, 2, 5, 0.4f, GL_ANY_SAMPLES_PASSED,
549         OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
550 
551     addChild(new OcclusionQueryCase(m_context, "all_occluders", "all_occluders", 7, 10, 1.6f, 3, 5, 0.6f,
552                                     GL_ANY_SAMPLES_PASSED,
553                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR |
554                                         OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
555 
556     // Conservative occlusion query cases
557 
558     addChild(new OcclusionQueryCase(m_context, "conservative_scissor", "conservative_scissor", 1, 10, 1.6f, 1, 1, 0.3f,
559                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR));
560     addChild(new OcclusionQueryCase(m_context, "conservative_depth_write", "conservative_depth_write", 8, 10, 1.6f, 1,
561                                     7, 0.3f, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE));
562     addChild(new OcclusionQueryCase(m_context, "conservative_depth_clear", "conservative_depth_clear", 5, 10, 1.6f, 1,
563                                     5, 0.2f, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_CLEAR));
564     addChild(new OcclusionQueryCase(m_context, "conservative_stencil_write", "conservative_stencil_write", 8, 10, 2.0f,
565                                     1, 5, 0.4f, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_STENCIL_WRITE));
566     addChild(new OcclusionQueryCase(m_context, "conservative_stencil_clear", "conservative_stencil_clear", 5, 10, 2.0f,
567                                     1, 3, 0.3f, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_STENCIL_CLEAR));
568 
569     addChild(new OcclusionQueryCase(m_context, "conservative_scissor_depth_write", "conservative_scissor_depth_write",
570                                     5, 10, 1.6f, 2, 5, 0.3f, GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
571                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE));
572     addChild(new OcclusionQueryCase(m_context, "conservative_scissor_depth_clear", "conservative_scissor_depth_clear",
573                                     7, 10, 1.6f, 2, 5, 1.0f, GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
574                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR));
575     addChild(new OcclusionQueryCase(m_context, "conservative_scissor_stencil_write",
576                                     "conservative_scissor_stencil_write", 4, 10, 1.6f, 2, 5, 0.3f,
577                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_WRITE));
578     addChild(new OcclusionQueryCase(m_context, "conservative_scissor_stencil_clear",
579                                     "conservative_scissor_stencil_clear", 4, 10, 1.6f, 2, 5, 1.0f,
580                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_CLEAR));
581     addChild(new OcclusionQueryCase(m_context, "conservative_depth_write_depth_clear",
582                                     "conservative_depth_write_depth_clear", 7, 10, 1.6f, 1, 5, 0.2f,
583                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR));
584     addChild(new OcclusionQueryCase(m_context, "conservative_depth_write_stencil_write",
585                                     "conservative_depth_write_stencil_write", 8, 10, 1.6f, 1, 5, 0.3f,
586                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE));
587     addChild(new OcclusionQueryCase(m_context, "conservative_depth_write_stencil_clear",
588                                     "conservative_depth_write_stencil_clear", 8, 10, 1.6f, 1, 5, 0.3f,
589                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_CLEAR));
590     addChild(new OcclusionQueryCase(m_context, "conservative_depth_clear_stencil_write",
591                                     "conservative_depth_clear_stencil_write", 8, 10, 1.6f, 1, 5, 0.3f,
592                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
593     addChild(new OcclusionQueryCase(m_context, "conservative_depth_clear_stencil_clear",
594                                     "conservative_depth_clear_stencil_clear", 12, 10, 1.6f, 1, 5, 0.2f,
595                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
596     addChild(new OcclusionQueryCase(
597         m_context, "conservative_stencil_write_stencil_clear", "conservative_stencil_write_stencil_clear", 5, 10, 2.0f,
598         1, 5, 0.4f, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
599 
600     addChild(new OcclusionQueryCase(m_context, "conservative_scissor_depth_write_depth_clear",
601                                     "conservative_scissor_depth_write_depth_clear", 5, 10, 1.6f, 2, 5, 0.4f,
602                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
603                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR));
604     addChild(new OcclusionQueryCase(m_context, "conservative_scissor_depth_write_stencil_write",
605                                     "conservative_scissor_depth_write_stencil_write", 4, 10, 1.6f, 2, 5, 0.4f,
606                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
607                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE));
608     addChild(new OcclusionQueryCase(m_context, "conservative_scissor_depth_write_stencil_clear",
609                                     "conservative_scissor_depth_write_stencil_clear", 6, 10, 1.6f, 2, 5, 0.4f,
610                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
611                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_CLEAR));
612     addChild(new OcclusionQueryCase(m_context, "conservative_scissor_depth_clear_stencil_write",
613                                     "conservative_scissor_depth_clear_stencil_write", 4, 10, 1.6f, 2, 5, 0.4f,
614                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
615                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
616     addChild(new OcclusionQueryCase(m_context, "conservative_scissor_depth_clear_stencil_clear",
617                                     "conservative_scissor_depth_clear_stencil_clear", 5, 10, 1.6f, 2, 5, 0.4f,
618                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
619                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
620     addChild(new OcclusionQueryCase(m_context, "conservative_scissor_stencil_write_stencil_clear",
621                                     "conservative_scissor_stencil_write_stencil_clear", 4, 10, 1.6f, 2, 5, 0.4f,
622                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
623                                     OCCLUDER_SCISSOR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
624     addChild(new OcclusionQueryCase(m_context, "conservative_depth_write_depth_clear_stencil_write",
625                                     "conservative_depth_write_depth_clear_stencil_write", 7, 10, 1.6f, 2, 5, 0.4f,
626                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
627                                     OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
628     addChild(new OcclusionQueryCase(m_context, "conservative_depth_write_depth_clear_stencil_clear",
629                                     "conservative_depth_write_depth_clear_stencil_clear", 7, 10, 1.6f, 2, 5, 0.4f,
630                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
631                                     OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
632     addChild(new OcclusionQueryCase(m_context, "conservative_depth_write_stencil_write_stencil_clear",
633                                     "conservative_depth_write_stencil_write_stencil_clear", 7, 10, 1.6f, 2, 5, 0.4f,
634                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
635                                     OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
636     addChild(new OcclusionQueryCase(m_context, "conservative_depth_clear_stencil_write_stencil_clear",
637                                     "conservative_depth_clear_stencil_write_stencil_clear", 7, 10, 1.6f, 2, 5, 0.4f,
638                                     GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
639                                     OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
640 
641     addChild(new OcclusionQueryCase(m_context, "conservative_scissor_depth_write_depth_clear_stencil_write",
642                                     "conservative_scissor_depth_write_depth_clear_stencil_write", 4, 10, 1.6f, 2, 5,
643                                     0.4f, GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
644                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR |
645                                         OCCLUDER_STENCIL_WRITE));
646     addChild(new OcclusionQueryCase(m_context, "conservative_scissor_depth_write_depth_clear_stencil_clear",
647                                     "conservative_scissor_depth_write_depth_clear_stencil_clear", 4, 10, 1.6f, 2, 5,
648                                     0.4f, GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
649                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR |
650                                         OCCLUDER_STENCIL_CLEAR));
651     addChild(new OcclusionQueryCase(m_context, "conservative_scissor_depth_write_stencil_write_stencil_clear",
652                                     "conservative_scissor_depth_write_stencil_write_stencil_clear", 5, 10, 1.6f, 2, 5,
653                                     0.4f, GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
654                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE |
655                                         OCCLUDER_STENCIL_CLEAR));
656     addChild(new OcclusionQueryCase(m_context, "conservative_scissor_depth_clear_stencil_write_stencil_clear",
657                                     "conservative_scissor_depth_clear_stencil_write_stencil_clear", 4, 10, 1.6f, 2, 5,
658                                     0.4f, GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
659                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE |
660                                         OCCLUDER_STENCIL_CLEAR));
661     addChild(new OcclusionQueryCase(m_context, "conservative_depth_write_depth_clear_stencil_write_stencil_clear",
662                                     "conservative_depth_write_depth_clear_stencil_write_stencil_clear", 7, 10, 1.6f, 2,
663                                     5, 0.4f, GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
664                                     OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE |
665                                         OCCLUDER_STENCIL_CLEAR));
666 
667     addChild(new OcclusionQueryCase(m_context, "conservative_all_occluders", "conservative_all_occluders", 7, 10, 1.6f,
668                                     3, 5, 0.6f, GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
669                                     OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR |
670                                         OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
671 }
672 
673 } // namespace Functional
674 } // namespace gles3
675 } // namespace deqp
676