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