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 Rasterizer discard tests.
22 *//*--------------------------------------------------------------------*/
23
24#include "es3fRasterizerDiscardTests.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 "deStringUtil.hpp"
34#include "deString.h"
35
36#include "glw.h"
37
38using tcu::Vec4;
39using tcu::TestLog;
40
41namespace deqp
42{
43namespace gles3
44{
45namespace Functional
46{
47
48static const int	NUM_CASE_ITERATIONS = 1;
49static const Vec4	FAIL_COLOR_RED		= Vec4(1.0f, 0.0f, 0.0f, 1.0f);
50static const Vec4	PASS_COLOR_BLUE		= Vec4(0.0f, 0.0f, 0.5f, 1.0f);
51static const Vec4	BLACK_COLOR			= Vec4(0.0f, 0.0f, 0.0f, 1.0f);
52static const float	FAIL_DEPTH			= 0.0f;
53static const int	FAIL_STENCIL		= 1;
54static const float	UNIT_SQUARE[16] =
55{
56	 1.0f,  1.0f, 0.05f, 1.0f,
57	 1.0f, -1.0f, 0.05f, 1.0f,
58	-1.0f,  1.0f, 0.05f, 1.0f,
59	-1.0f, -1.0f, 0.05f, 1.0f
60};
61
62enum CaseType
63{
64	CASE_WRITE_DEPTH,
65	CASE_WRITE_STENCIL,
66	CASE_CLEAR_COLOR,
67	CASE_CLEAR_DEPTH,
68	CASE_CLEAR_STENCIL
69};
70
71enum CaseOptions
72{
73	CASEOPTION_FBO		= (1 << 0),
74	CASEOPTION_SCISSOR	= (1 << 1)
75};
76
77class RasterizerDiscardCase : public TestCase
78{
79public:
80								RasterizerDiscardCase	(Context& context, const char* name, const char* description, int numPrimitives, CaseType caseType, deUint32 caseOptions, deUint32 drawMode = GL_TRIANGLES);
81								~RasterizerDiscardCase	(void);
82
83	void						init					(void);
84	void						deinit					(void);
85	IterateResult				iterate					(void);
86
87private:
88								RasterizerDiscardCase	(const RasterizerDiscardCase& other);
89	RasterizerDiscardCase&		operator=				(const RasterizerDiscardCase& other);
90
91	void						setupFramebufferObject	(void);
92	void						deleteFramebufferObject	(void);
93
94	int							m_numPrimitives;
95	CaseType					m_caseType;
96	deUint32					m_caseOptions;
97	deUint32					m_drawMode;
98
99	glu::ShaderProgram*			m_program;
100	deUint32					m_fbo;
101	deUint32					m_colorBuf;
102	deUint32					m_depthStencilBuf;
103	int							m_iterNdx;
104	de::Random					m_rnd;
105};
106
107RasterizerDiscardCase::RasterizerDiscardCase (Context& context, const char* name, const char* description, int numPrimitives, CaseType caseType, deUint32 caseOptions, deUint32 drawMode)
108	: TestCase				(context, name, description)
109	, m_numPrimitives		(numPrimitives)
110	, m_caseType			(caseType)
111	, m_caseOptions			(caseOptions)
112	, m_drawMode			(drawMode)
113	, m_program				(DE_NULL)
114	, m_fbo					(0)
115	, m_colorBuf			(0)
116	, m_depthStencilBuf		(0)
117	, m_iterNdx				(0)
118	, m_rnd					(deStringHash(name))
119{
120}
121
122RasterizerDiscardCase::~RasterizerDiscardCase (void)
123{
124	RasterizerDiscardCase::deinit();
125}
126
127static void generateVertices (std::vector<float>& dst, int numPrimitives, de::Random& rnd, deUint32 drawMode)
128{
129	int numVertices;
130
131	switch (drawMode)
132	{
133		case GL_POINTS:			numVertices = numPrimitives;	break;
134		case GL_LINES:			numVertices = 2*numPrimitives;	break;
135		case GL_LINE_STRIP:		numVertices = numPrimitives+1;	break;
136		case GL_LINE_LOOP:		numVertices = numPrimitives+2;	break;
137		case GL_TRIANGLES:		numVertices = 3*numPrimitives;	break;
138		case GL_TRIANGLE_STRIP:	numVertices = numPrimitives+2;	break;
139		case GL_TRIANGLE_FAN:	numVertices = numPrimitives+2;	break;
140		default:
141			DE_ASSERT(false);
142			numVertices = 0;
143	}
144
145	dst.resize(numVertices * 4);
146
147	for (int i = 0; i < numVertices; i++)
148	{
149		dst[i*4    ] = rnd.getFloat(-1.0f, 1.0f);	// x
150		dst[i*4 + 1] = rnd.getFloat(-1.0f, 1.0f);	// y
151		dst[i*4 + 2] = rnd.getFloat( 0.1f, 0.9f);	// z
152		dst[i*4 + 3] = 1.0f;						// w
153	}
154}
155
156void RasterizerDiscardCase::setupFramebufferObject (void)
157{
158	int width  = m_context.getRenderTarget().getWidth();
159	int height = m_context.getRenderTarget().getHeight();
160
161	// Create framebuffer object
162
163	glGenFramebuffers	(1, &m_fbo);				// FBO
164	glGenTextures		(1, &m_colorBuf);			// Color attachment
165	glGenRenderbuffers	(1, &m_depthStencilBuf);	// Depth and stencil attachments
166
167	// Create color texture
168
169	glBindTexture	(GL_TEXTURE_2D, m_colorBuf);
170	glTexParameteri	(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
171	glTexParameteri	(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
172	glTexParameteri	(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	GL_LINEAR);
173	glTexParameteri	(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
174	glTexImage2D	(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
175
176	// Create depth and stencil buffers
177
178	glBindRenderbuffer	  (GL_RENDERBUFFER, m_depthStencilBuf);
179	glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
180
181	// Attach texture and buffers to FBO
182
183	glBindFramebuffer		  (GL_FRAMEBUFFER, m_fbo);
184	glFramebufferTexture2D	  (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuf, 0);
185	glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuf);
186	glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuf);
187
188	deUint32 fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
189
190	if (fboStatus == GL_FRAMEBUFFER_UNSUPPORTED)
191		throw tcu::NotSupportedError("Framebuffer unsupported", "", __FILE__, __LINE__);
192	else if (fboStatus != GL_FRAMEBUFFER_COMPLETE)
193		throw tcu::TestError("Failed to create framebuffer object", "", __FILE__, __LINE__);
194}
195
196void RasterizerDiscardCase::deleteFramebufferObject (void)
197{
198	glDeleteTextures		(1, &m_colorBuf);			// Color attachment
199	glDeleteRenderbuffers	(1, &m_depthStencilBuf);	// Depth and stencil attachments
200	glDeleteFramebuffers	(1, &m_fbo);				// FBO
201}
202
203void RasterizerDiscardCase::init (void)
204{
205	const char*	vertShaderSource =
206				"#version 300 es\n"
207				"layout(location = 0) in mediump vec4 a_position;\n"
208				"\n"
209				"void main (void)\n"
210				"{\n"
211				"	gl_Position = a_position;\n"
212				"}\n";
213
214	const char* fragShaderSource =
215				"#version 300 es\n"
216				"layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
217				"uniform mediump vec4 u_color;\n"
218				"\n"
219				"void main (void)\n"
220				"{\n"
221				"	mediump float depth_gradient = gl_FragCoord.z;\n"
222				"	mediump float bias = 0.1;\n"
223				"	dEQP_FragColor = vec4(u_color.xyz * (depth_gradient + bias), 1.0);\n"
224				"}\n";
225
226	DE_ASSERT(!m_program);
227	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertShaderSource, fragShaderSource));
228
229	if (!m_program->isOk())
230	{
231		m_testCtx.getLog() << *m_program;
232		TCU_FAIL("Failed to compile shader program");
233	}
234
235	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); // Initialize test result to pass.
236	GLU_CHECK_MSG ("Case initialization finished");
237}
238
239void RasterizerDiscardCase::deinit (void)
240{
241	deleteFramebufferObject();
242	delete m_program;
243	m_program = DE_NULL;
244}
245
246RasterizerDiscardCase::IterateResult RasterizerDiscardCase::iterate (void)
247{
248	TestLog&					log				= m_testCtx.getLog();
249	const tcu::RenderTarget&	renderTarget	= m_context.getRenderTarget();
250	deUint32					colorUnif		= glGetUniformLocation(m_program->getProgram(), "u_color");
251	bool						failColorFound	= false;
252	bool						passColorFound	= false;
253	std::vector<float>			vertices;
254
255	std::string header = "Case iteration " + de::toString(m_iterNdx+1) + " / " + de::toString(NUM_CASE_ITERATIONS);
256	log << TestLog::Section(header, header);
257
258	DE_ASSERT (m_program);
259
260	// Create and bind FBO if needed
261
262	if (m_caseOptions & CASEOPTION_FBO)
263	{
264		try
265		{
266			setupFramebufferObject();
267		}
268		catch (tcu::NotSupportedError& e)
269		{
270			log << TestLog::Message << "ERROR: " << e.what() << "." << TestLog::EndMessage << TestLog::EndSection;
271			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
272			return STOP;
273		}
274		catch (tcu::InternalError& e)
275		{
276			log << TestLog::Message << "ERROR: " << e.what() << "." << TestLog::EndMessage << TestLog::EndSection;
277			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
278			return STOP;
279		}
280	}
281
282	if (m_caseOptions & CASEOPTION_SCISSOR)
283	{
284		glEnable (GL_SCISSOR_TEST);
285		glScissor(0, 0, renderTarget.getWidth(), renderTarget.getHeight());
286		log << TestLog::Message << "Scissor test enabled: glScissor(0, 0, " << renderTarget.getWidth() << ", " << renderTarget.getHeight() << ")" << TestLog::EndMessage;
287	}
288
289	glUseProgram	(m_program->getProgram());
290
291	glEnable		(GL_DEPTH_TEST);
292	glDepthRangef	(0.0f, 1.0f);
293	glDepthFunc		(GL_LEQUAL);
294
295	glEnable		(GL_STENCIL_TEST);
296	glStencilFunc	(GL_NOTEQUAL, 1, 0xFF);
297	glStencilOp		(GL_REPLACE, GL_KEEP, GL_KEEP);
298
299	glClearColor	(PASS_COLOR_BLUE.x(), PASS_COLOR_BLUE.y(), PASS_COLOR_BLUE.z(), PASS_COLOR_BLUE.w());
300	glClearDepthf	(1.0f);
301	glClearStencil	(0);
302	glClear			(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
303
304	// Generate vertices
305
306	glEnableVertexAttribArray (0);
307	generateVertices		  (vertices, m_numPrimitives, m_rnd, m_drawMode);
308	glVertexAttribPointer	  (0, 4, GL_FLOAT, GL_FALSE, 0, &vertices[0]);
309
310	// Clear color to black for depth and stencil clear cases
311
312	if (m_caseType == CASE_CLEAR_DEPTH || m_caseType == CASE_CLEAR_STENCIL)
313	{
314		glClearColor	(BLACK_COLOR.x(), BLACK_COLOR.y(), BLACK_COLOR.z(), BLACK_COLOR.w());
315		glClear			(GL_COLOR_BUFFER_BIT);
316	}
317
318	// Set fail values for color, depth and stencil
319
320	glUniform4f		(colorUnif, FAIL_COLOR_RED.x(), FAIL_COLOR_RED.y(), FAIL_COLOR_RED.z(), FAIL_COLOR_RED.w());
321	glClearColor	(FAIL_COLOR_RED.x(), FAIL_COLOR_RED.y(), FAIL_COLOR_RED.z(), FAIL_COLOR_RED.w());
322	glClearDepthf	(FAIL_DEPTH);
323	glClearStencil	(FAIL_STENCIL);
324
325	// Enable rasterizer discard
326
327	glEnable		(GL_RASTERIZER_DISCARD);
328	GLU_CHECK_MSG	("Rasterizer discard enabled");
329
330	// Do to-be-discarded primitive draws and buffer clears
331
332	switch (m_caseType)
333	{
334		case CASE_WRITE_DEPTH:			glDrawArrays(m_drawMode, 0, (int)vertices.size() / 4);																	break;
335		case CASE_WRITE_STENCIL:		glDrawArrays(m_drawMode, 0, (int)vertices.size() / 4);																	break;
336		case CASE_CLEAR_COLOR:			(m_caseOptions & CASEOPTION_FBO) ? glClearBufferfv(GL_COLOR, 0, &FAIL_COLOR_RED[0])	: glClear(GL_COLOR_BUFFER_BIT);		break;
337		case CASE_CLEAR_DEPTH:			(m_caseOptions & CASEOPTION_FBO) ? glClearBufferfv(GL_DEPTH, 0, &FAIL_DEPTH)		: glClear(GL_DEPTH_BUFFER_BIT);		break;
338		case CASE_CLEAR_STENCIL:		(m_caseOptions & CASEOPTION_FBO) ? glClearBufferiv(GL_STENCIL, 0, &FAIL_STENCIL)	: glClear(GL_STENCIL_BUFFER_BIT);	break;
339		default:						DE_ASSERT(false);
340	}
341
342	// Disable rasterizer discard
343
344	glDisable		(GL_RASTERIZER_DISCARD);
345	GLU_CHECK_MSG	("Rasterizer discard disabled");
346
347	if (m_caseType == CASE_WRITE_STENCIL)
348	{
349		if ((m_caseOptions & CASEOPTION_FBO) || m_context.getRenderTarget().getStencilBits() > 0)
350		{
351			// Draw a full-screen square that colors all pixels red if they have stencil value 1.
352
353			glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, &UNIT_SQUARE[0]);
354			glStencilFunc		  (GL_EQUAL, 1, 0xFF);
355			glDrawArrays		  (GL_TRIANGLE_STRIP, 0, 4);
356		}
357		// \note If no stencil buffers are present and test is rendering to default framebuffer, test will always pass.
358	}
359	else if (m_caseType == CASE_CLEAR_DEPTH || m_caseType == CASE_CLEAR_STENCIL)
360	{
361		// Draw pass-indicating primitives for depth and stencil clear cases
362
363		glUniform4f	 (colorUnif, PASS_COLOR_BLUE.x(), PASS_COLOR_BLUE.y(), PASS_COLOR_BLUE.z(), PASS_COLOR_BLUE.w());
364		glDrawArrays (m_drawMode, 0, (int)vertices.size() / 4);
365	}
366
367	glFinish  ();
368	glDisable (GL_STENCIL_TEST);
369	glDisable (GL_DEPTH_TEST);
370	glDisable (GL_SCISSOR_TEST);
371
372	// Read and check pixel data
373
374	tcu::Surface pixels(renderTarget.getWidth(), renderTarget.getHeight());
375	glu::readPixels(m_context.getRenderContext(), 0, 0, pixels.getAccess());
376
377	{
378		int width = pixels.getWidth();
379		int height = pixels.getHeight();
380
381		for (int y = 0; y < height; y++)
382		{
383			for (int x = 0; x < width; x++)
384			{
385				if (pixels.getPixel(x,y).getBlue() != 0)
386					passColorFound = true;
387
388				if (pixels.getPixel(x,y).getRed() != 0)
389				{
390					failColorFound = true;
391					break;
392				}
393			}
394			if (failColorFound) break;
395		}
396	}
397
398	// Delete FBO if created
399
400	if (m_caseOptions & CASEOPTION_FBO)
401		deleteFramebufferObject();
402
403	// Evaluate test result
404
405	bool testOk = passColorFound && !failColorFound;
406
407	if (!testOk)
408		log << TestLog::Image ("Result image", "Result image", pixels);
409	log << TestLog::Message << "Test result: " << (testOk ? "Passed!" : "Failed!") << TestLog::EndMessage;
410
411	if (!testOk)
412	{
413		log << TestLog::Message << "Primitive or buffer clear was not discarded." << TestLog::EndMessage << TestLog::EndSection;
414		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
415		return STOP;
416	}
417
418	log << TestLog::Message << "Primitive or buffer clear was discarded correctly." << TestLog::EndMessage << TestLog::EndSection;
419
420	return (++m_iterNdx < NUM_CASE_ITERATIONS) ? CONTINUE : STOP;
421}
422
423RasterizerDiscardTests::RasterizerDiscardTests (Context& context)
424	: TestCaseGroup(context, "rasterizer_discard", "Rasterizer Discard Tests")
425{
426}
427
428RasterizerDiscardTests::~RasterizerDiscardTests (void)
429{
430}
431
432void RasterizerDiscardTests::init (void)
433{
434	tcu::TestCaseGroup* basic	= new tcu::TestCaseGroup(m_testCtx, "basic",	"Rasterizer discard test for default framebuffer");
435	tcu::TestCaseGroup*	scissor	= new tcu::TestCaseGroup(m_testCtx, "scissor",	"Rasterizer discard test for default framebuffer with scissor test enabled");
436	tcu::TestCaseGroup*	fbo		= new tcu::TestCaseGroup(m_testCtx, "fbo",		"Rasterizer discard test for framebuffer object");
437
438	addChild(basic);
439	addChild(scissor);
440	addChild(fbo);
441
442	// Default framebuffer cases
443
444	basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_points",				"points",			4, CASE_WRITE_DEPTH,	0, GL_POINTS));
445	basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_lines",				"lines",			4, CASE_WRITE_DEPTH,	0, GL_LINES));
446	basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_strip",			"line_strip",		4, CASE_WRITE_DEPTH,	0, GL_LINE_STRIP));
447	basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_loop",			"line_loop",		4, CASE_WRITE_DEPTH,	0, GL_LINE_LOOP));
448	basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangles",			"triangles",		4, CASE_WRITE_DEPTH,	0, GL_TRIANGLES));
449	basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_strip",		"triangle_strip",	4, CASE_WRITE_DEPTH,	0, GL_TRIANGLE_STRIP));
450	basic->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_fan",		"triangle_fan",		4, CASE_WRITE_DEPTH,	0, GL_TRIANGLE_FAN));
451
452	basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_points",			"points",			4, CASE_WRITE_STENCIL,	0, GL_POINTS));
453	basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_lines",				"lines",			4, CASE_WRITE_STENCIL,	0, GL_LINES));
454	basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_strip",		"line_strip",		4, CASE_WRITE_STENCIL,	0, GL_LINE_STRIP));
455	basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_loop",			"line_loop",		4, CASE_WRITE_STENCIL,	0, GL_LINE_LOOP));
456	basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangles",			"triangles",		4, CASE_WRITE_STENCIL,	0, GL_TRIANGLES));
457	basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_strip",	"triangle_strip",	4, CASE_WRITE_STENCIL,	0, GL_TRIANGLE_STRIP));
458	basic->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_fan",		"triangle_fan",		4, CASE_WRITE_STENCIL,	0, GL_TRIANGLE_FAN));
459
460	basic->addChild(new RasterizerDiscardCase(m_context, "clear_color",						"clear_color",		4, CASE_CLEAR_COLOR,	0));
461	basic->addChild(new RasterizerDiscardCase(m_context, "clear_depth",						"clear_depth",		4, CASE_CLEAR_DEPTH,	0));
462	basic->addChild(new RasterizerDiscardCase(m_context, "clear_stencil",					"clear_stencil",	4, CASE_CLEAR_STENCIL,	0));
463
464	// Default framebuffer cases with scissor test enabled
465
466	scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_points",			"points",			4, CASE_WRITE_DEPTH,	CASEOPTION_SCISSOR, GL_POINTS));
467	scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_lines",				"lines",			4, CASE_WRITE_DEPTH,	CASEOPTION_SCISSOR, GL_LINES));
468	scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_strip",		"line_strip",		4, CASE_WRITE_DEPTH,	CASEOPTION_SCISSOR, GL_LINE_STRIP));
469	scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_loop",			"line_loop",		4, CASE_WRITE_DEPTH,	CASEOPTION_SCISSOR, GL_LINE_LOOP));
470	scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangles",			"triangles",		4, CASE_WRITE_DEPTH,	CASEOPTION_SCISSOR, GL_TRIANGLES));
471	scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_strip",	"triangle_strip",	4, CASE_WRITE_DEPTH,	CASEOPTION_SCISSOR, GL_TRIANGLE_STRIP));
472	scissor->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_fan",		"triangle_fan",		4, CASE_WRITE_DEPTH,	CASEOPTION_SCISSOR, GL_TRIANGLE_FAN));
473
474	scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_points",			"points",			4, CASE_WRITE_STENCIL,	CASEOPTION_SCISSOR, GL_POINTS));
475	scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_lines",			"lines",			4, CASE_WRITE_STENCIL,	CASEOPTION_SCISSOR, GL_LINES));
476	scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_strip",		"line_strip",		4, CASE_WRITE_STENCIL,	CASEOPTION_SCISSOR, GL_LINE_STRIP));
477	scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_loop",		"line_loop",		4, CASE_WRITE_STENCIL,	CASEOPTION_SCISSOR, GL_LINE_LOOP));
478	scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangles",		"triangles",		4, CASE_WRITE_STENCIL,	CASEOPTION_SCISSOR, GL_TRIANGLES));
479	scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_strip",	"triangle_strip",	4, CASE_WRITE_STENCIL,	CASEOPTION_SCISSOR, GL_TRIANGLE_STRIP));
480	scissor->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_fan",	"triangle_fan",		4, CASE_WRITE_STENCIL,	CASEOPTION_SCISSOR, GL_TRIANGLE_FAN));
481
482	scissor->addChild(new RasterizerDiscardCase(m_context, "clear_color",					"clear_color",		4, CASE_CLEAR_COLOR,	CASEOPTION_SCISSOR));
483	scissor->addChild(new RasterizerDiscardCase(m_context, "clear_depth",					"clear_depth",		4, CASE_CLEAR_DEPTH,	CASEOPTION_SCISSOR));
484	scissor->addChild(new RasterizerDiscardCase(m_context, "clear_stencil",					"clear_stencil",	4, CASE_CLEAR_STENCIL,	CASEOPTION_SCISSOR));
485
486	// FBO cases
487
488	fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_points",			"points",			4, CASE_WRITE_DEPTH,	CASEOPTION_FBO, GL_POINTS));
489	fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_lines",				"lines",			4, CASE_WRITE_DEPTH,	CASEOPTION_FBO, GL_LINES));
490	fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_strip",		"line_strip",		4, CASE_WRITE_DEPTH,	CASEOPTION_FBO, GL_LINE_STRIP));
491	fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_line_loop",			"line_loop",		4, CASE_WRITE_DEPTH,	CASEOPTION_FBO, GL_LINE_LOOP));
492	fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangles",			"triangles",		4, CASE_WRITE_DEPTH,	CASEOPTION_FBO, GL_TRIANGLES));
493	fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_strip",	"triangle_strip",	4, CASE_WRITE_DEPTH,	CASEOPTION_FBO, GL_TRIANGLE_STRIP));
494	fbo->addChild(new RasterizerDiscardCase(m_context, "write_depth_triangle_fan",		"triangle_fan",		4, CASE_WRITE_DEPTH,	CASEOPTION_FBO, GL_TRIANGLE_FAN));
495
496	fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_points",			"points",			4, CASE_WRITE_STENCIL,	CASEOPTION_FBO, GL_POINTS));
497	fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_lines",			"lines",			4, CASE_WRITE_STENCIL,	CASEOPTION_FBO, GL_LINES));
498	fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_strip",		"line_strip",		4, CASE_WRITE_STENCIL,	CASEOPTION_FBO, GL_LINE_STRIP));
499	fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_line_loop",		"line_loop",		4, CASE_WRITE_STENCIL,	CASEOPTION_FBO, GL_LINE_LOOP));
500	fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangles",		"triangles",		4, CASE_WRITE_STENCIL,	CASEOPTION_FBO, GL_TRIANGLES));
501	fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_strip",	"triangle_strip",	4, CASE_WRITE_STENCIL,	CASEOPTION_FBO, GL_TRIANGLE_STRIP));
502	fbo->addChild(new RasterizerDiscardCase(m_context, "write_stencil_triangle_fan",	"triangle_fan",		4, CASE_WRITE_STENCIL,	CASEOPTION_FBO, GL_TRIANGLE_FAN));
503
504	fbo->addChild(new RasterizerDiscardCase(m_context, "clear_color",					"clear_color",		4, CASE_CLEAR_COLOR,	CASEOPTION_FBO));
505	fbo->addChild(new RasterizerDiscardCase(m_context, "clear_depth",					"clear_depth",		4, CASE_CLEAR_DEPTH,	CASEOPTION_FBO));
506	fbo->addChild(new RasterizerDiscardCase(m_context, "clear_stencil",					"clear_stencil",	4, CASE_CLEAR_STENCIL,	CASEOPTION_FBO));
507}
508
509} // Functional
510} // gles3
511} // deqp
512