1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 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 Sample shading tests
22 *//*--------------------------------------------------------------------*/
23
24#include "es31fSampleShadingTests.hpp"
25#include "es31fMultisampleShaderRenderCase.hpp"
26#include "tcuRenderTarget.hpp"
27#include "tcuSurface.hpp"
28#include "glsStateQueryUtil.hpp"
29#include "gluCallLogWrapper.hpp"
30#include "gluContextInfo.hpp"
31#include "gluShaderProgram.hpp"
32#include "gluRenderContext.hpp"
33#include "gluPixelTransfer.hpp"
34#include "glwFunctions.hpp"
35#include "glwEnums.hpp"
36#include "deStringUtil.hpp"
37#include "deRandom.hpp"
38
39#include <map>
40
41namespace deqp
42{
43namespace gles31
44{
45namespace Functional
46{
47namespace
48{
49
50class SampleShadingStateCase : public TestCase
51{
52public:
53	enum VerifierType
54	{
55		TYPE_IS_ENABLED = 0,
56		TYPE_GET_BOOLEAN,
57		TYPE_GET_INTEGER,
58		TYPE_GET_FLOAT,
59		TYPE_GET_INTEGER64,
60		TYPE_LAST
61	};
62
63						SampleShadingStateCase	(Context& ctx, const char* name, const char* desc, VerifierType);
64
65	void				init					(void);
66	IterateResult		iterate					(void);
67
68private:
69	bool				verify					(bool v);
70
71	const VerifierType	m_verifier;
72};
73
74SampleShadingStateCase::SampleShadingStateCase (Context& ctx, const char* name, const char* desc, VerifierType type)
75	: TestCase		(ctx, name, desc)
76	, m_verifier	(type)
77{
78	DE_ASSERT(m_verifier < TYPE_LAST);
79}
80
81void SampleShadingStateCase::init (void)
82{
83	if (!m_context.getContextInfo().isExtensionSupported("GL_OES_sample_shading"))
84		throw tcu::NotSupportedError("Test requires GL_OES_sample_shading extension");
85}
86
87SampleShadingStateCase::IterateResult SampleShadingStateCase::iterate (void)
88{
89	bool				allOk	= true;
90	glu::CallLogWrapper gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
91	gl.enableLogging(true);
92
93	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
94
95	// initial
96	{
97		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying initial value" << tcu::TestLog::EndMessage;
98		allOk &= verify(false);
99	}
100
101	// true and false too
102	{
103		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying random values" << tcu::TestLog::EndMessage;
104
105		gl.glEnable(GL_SAMPLE_SHADING);
106		allOk &= verify(true);
107
108		gl.glDisable(GL_SAMPLE_SHADING);
109		allOk &= verify(false);
110	}
111
112	if (!allOk && m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
113		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected value");
114
115	return STOP;
116}
117
118bool SampleShadingStateCase::verify (bool v)
119{
120	glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
121	gl.enableLogging(true);
122
123	switch (m_verifier)
124	{
125		case TYPE_IS_ENABLED:
126		{
127			const glw::GLboolean retVal = gl.glIsEnabled(GL_SAMPLE_SHADING);
128
129			if ((v && retVal==GL_TRUE) || (!v && retVal==GL_FALSE))
130				return true;
131
132			m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << ((v) ? ("GL_TRUE") : ("GL_FALSE")) << ", got " << ((retVal == GL_TRUE) ? ("GL_TRUE") : (retVal == GL_FALSE) ? ("GL_FALSE") : ("not-a-boolean")) << tcu::TestLog::EndMessage;
133			return false;
134		}
135
136		case TYPE_GET_BOOLEAN:
137		{
138			gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLboolean> state;
139			gl.glGetBooleanv(GL_SAMPLE_SHADING, &state);
140
141			if (!state.verifyValidity(m_testCtx))
142				return false;
143
144			if ((v && state==GL_TRUE) || (!v && state==GL_FALSE))
145				return true;
146
147			m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << ((v) ? ("GL_TRUE") : ("GL_FALSE")) << ", got " << ((state == GL_TRUE) ? ("GL_TRUE") : (state == GL_FALSE) ? ("GL_FALSE") : ("not-a-boolean")) << tcu::TestLog::EndMessage;
148			return false;
149		}
150
151		case TYPE_GET_INTEGER:
152		{
153			gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint> state;
154			gl.glGetIntegerv(GL_SAMPLE_SHADING, &state);
155
156			if (!state.verifyValidity(m_testCtx))
157				return false;
158
159			if ((v && state==1) || (!v && state==0))
160				return true;
161
162			m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << ((v) ? ("1") : ("0")) << ", got " << state << tcu::TestLog::EndMessage;
163			return false;
164		}
165
166		case TYPE_GET_FLOAT:
167		{
168			gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLfloat> state;
169			gl.glGetFloatv(GL_SAMPLE_SHADING, &state);
170
171			if (!state.verifyValidity(m_testCtx))
172				return false;
173
174			if ((v && state==1.0f) || (!v && state==0.0f))
175				return true;
176
177			m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << ((v) ? ("1.0") : ("0.0")) << ", got " << state << tcu::TestLog::EndMessage;
178			return false;
179		}
180
181		case TYPE_GET_INTEGER64:
182		{
183			gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint64> state;
184			gl.glGetInteger64v(GL_SAMPLE_SHADING, &state);
185
186			if (!state.verifyValidity(m_testCtx))
187				return false;
188
189			if ((v && state==1) || (!v && state==0))
190				return true;
191
192			m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << ((v) ? ("1") : ("0")) << ", got " << state << tcu::TestLog::EndMessage;
193			return false;
194		}
195
196		default:
197		{
198			DE_ASSERT(false);
199			return false;
200		}
201	}
202}
203
204class MinSampleShadingValueCase : public TestCase
205{
206public:
207	enum VerifierType
208	{
209		TYPE_GET_BOOLEAN = 0,
210		TYPE_GET_INTEGER,
211		TYPE_GET_FLOAT,
212		TYPE_GET_INTEGER64,
213		TYPE_LAST
214	};
215
216						MinSampleShadingValueCase	(Context& ctx, const char* name, const char* desc, VerifierType);
217
218	void				init						(void);
219	IterateResult		iterate						(void);
220
221private:
222	bool				verify						(float v);
223
224	const VerifierType	m_verifier;
225};
226
227MinSampleShadingValueCase::MinSampleShadingValueCase (Context& ctx, const char* name, const char* desc, VerifierType type)
228	: TestCase		(ctx, name, desc)
229	, m_verifier	(type)
230{
231	DE_ASSERT(m_verifier < TYPE_LAST);
232}
233
234void MinSampleShadingValueCase::init (void)
235{
236	if (!m_context.getContextInfo().isExtensionSupported("GL_OES_sample_shading"))
237		throw tcu::NotSupportedError("Test requires GL_OES_sample_shading extension");
238}
239
240MinSampleShadingValueCase::IterateResult MinSampleShadingValueCase::iterate (void)
241{
242	bool				allOk	= true;
243	glu::CallLogWrapper gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
244	gl.enableLogging(true);
245
246	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
247
248	// initial
249	{
250		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying initial value" << tcu::TestLog::EndMessage;
251		allOk &= verify(0.0);
252	}
253
254	// special values
255	{
256		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying special values" << tcu::TestLog::EndMessage;
257
258		gl.glMinSampleShading(0.0f);
259		allOk &= verify(0.0);
260
261		gl.glMinSampleShading(1.0f);
262		allOk &= verify(1.0);
263
264		gl.glMinSampleShading(0.5f);
265		allOk &= verify(0.5);
266	}
267
268	// random values
269	{
270		const int	numRandomTests	= 10;
271		de::Random	rnd				(0xde123);
272
273		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying random values" << tcu::TestLog::EndMessage;
274
275		for (int randNdx = 0; randNdx < numRandomTests; ++randNdx)
276		{
277			const float value = rnd.getFloat();
278
279			gl.glMinSampleShading(value);
280			allOk &= verify(value);
281		}
282	}
283
284	if (!allOk && m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
285		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected value");
286
287	return STOP;
288}
289
290bool MinSampleShadingValueCase::verify (float v)
291{
292	glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
293	gl.enableLogging(true);
294
295	switch (m_verifier)
296	{
297		case TYPE_GET_BOOLEAN:
298		{
299			gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLboolean> state;
300			gl.glGetBooleanv(GL_MIN_SAMPLE_SHADING_VALUE, &state);
301
302			if (!state.verifyValidity(m_testCtx))
303				return false;
304
305			if ((v!=0.0f && state==GL_TRUE) || (v==0.0f && state==GL_FALSE))
306				return true;
307
308			m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << ((v!=0.0f) ? ("GL_TRUE") : ("GL_FALSE")) << ", got " << ((state == GL_TRUE) ? ("GL_TRUE") : (state == GL_FALSE) ? ("GL_FALSE") : ("not-a-boolean")) << tcu::TestLog::EndMessage;
309			return false;
310		}
311
312		case TYPE_GET_INTEGER:
313		{
314			gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint> state;
315			gl.glGetIntegerv(GL_MIN_SAMPLE_SHADING_VALUE, &state);
316
317			if (!state.verifyValidity(m_testCtx))
318				return false;
319
320			if ((v>=0.5f && state==1) || (v<=0.5f && state==0))
321				return true;
322
323			m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << ((v==0.5) ? ("0 or 1") : (v<0.5) ? ("0") : ("1")) << ", got " << state << tcu::TestLog::EndMessage;
324			return false;
325		}
326
327		case TYPE_GET_FLOAT:
328		{
329			gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLfloat> state;
330			gl.glGetFloatv(GL_MIN_SAMPLE_SHADING_VALUE, &state);
331
332			if (!state.verifyValidity(m_testCtx))
333				return false;
334
335			if (v == state)
336				return true;
337
338			m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << v << ", got " << state << tcu::TestLog::EndMessage;
339			return false;
340		}
341
342		case TYPE_GET_INTEGER64:
343		{
344			gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint64> state;
345			gl.glGetInteger64v(GL_MIN_SAMPLE_SHADING_VALUE, &state);
346
347			if (!state.verifyValidity(m_testCtx))
348				return false;
349
350			if ((v>=0.5f && state==1) || (v<=0.5f && state==0))
351				return true;
352
353			m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << ((v==0.5) ? ("0 or 1") : (v<0.5) ? ("0") : ("1")) << ", got " << state << tcu::TestLog::EndMessage;
354			return false;
355		}
356
357		default:
358		{
359			DE_ASSERT(false);
360			return false;
361		}
362	}
363}
364
365class MinSampleShadingValueClampingCase : public TestCase
366{
367public:
368						MinSampleShadingValueClampingCase	(Context& ctx, const char* name, const char* desc);
369
370	void				init								(void);
371	IterateResult		iterate								(void);
372
373private:
374	bool				verify								(float v);
375};
376
377MinSampleShadingValueClampingCase::MinSampleShadingValueClampingCase (Context& ctx, const char* name, const char* desc)
378	: TestCase(ctx, name, desc)
379{
380}
381
382void MinSampleShadingValueClampingCase::init (void)
383{
384	if (!m_context.getContextInfo().isExtensionSupported("GL_OES_sample_shading"))
385		throw tcu::NotSupportedError("Test requires GL_OES_sample_shading extension");
386}
387
388MinSampleShadingValueClampingCase::IterateResult MinSampleShadingValueClampingCase::iterate (void)
389{
390	bool				allOk	= true;
391	glu::CallLogWrapper gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
392	gl.enableLogging(true);
393
394	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
395
396	// special values
397	{
398		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying clamped values. Value is clamped when specified." << tcu::TestLog::EndMessage;
399
400		gl.glMinSampleShading(-0.5f);
401		allOk &= verify(0.0);
402
403		gl.glMinSampleShading(-1.0f);
404		allOk &= verify(0.0);
405
406		gl.glMinSampleShading(-1.5f);
407		allOk &= verify(0.0);
408
409		gl.glMinSampleShading(1.5f);
410		allOk &= verify(1.0);
411
412		gl.glMinSampleShading(2.0f);
413		allOk &= verify(1.0);
414
415		gl.glMinSampleShading(2.5f);
416		allOk &= verify(1.0);
417	}
418
419	if (!allOk && m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
420		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected value");
421
422	return STOP;
423}
424
425bool MinSampleShadingValueClampingCase::verify (float v)
426{
427	glu::CallLogWrapper												gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
428	gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLfloat>	state;
429
430	gl.enableLogging(true);
431
432	gl.glGetFloatv(GL_MIN_SAMPLE_SHADING_VALUE, &state);
433
434	if (!state.verifyValidity(m_testCtx))
435		return false;
436
437	if (v == state)
438		return true;
439
440	m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << v << ", got " << state << tcu::TestLog::EndMessage;
441	return false;
442}
443
444class SampleShadingRenderingCase : public MultisampleShaderRenderUtil::MultisampleRenderCase
445{
446public:
447	enum TestType
448	{
449		TEST_DISCARD = 0,
450		TEST_COLOR,
451
452		TEST_LAST
453	};
454						SampleShadingRenderingCase	(Context& ctx, const char* name, const char* desc, RenderTarget target, int numSamples, TestType type);
455						~SampleShadingRenderingCase	(void);
456
457	void				init						(void);
458private:
459	void				setShadingValue				(int sampleCount);
460
461	void				preDraw						(void);
462	void				postDraw					(void);
463	std::string			getIterationDescription		(int iteration) const;
464
465	bool				verifyImage					(const tcu::Surface& resultImage);
466
467	std::string			genFragmentSource			(int numSamples) const;
468
469	enum
470	{
471		RENDER_SIZE = 128
472	};
473
474	const TestType		m_type;
475};
476
477SampleShadingRenderingCase::SampleShadingRenderingCase (Context& ctx, const char* name, const char* desc, RenderTarget target, int numSamples, TestType type)
478	: MultisampleShaderRenderUtil::MultisampleRenderCase	(ctx, name, desc, numSamples, target, RENDER_SIZE)
479	, m_type												(type)
480{
481	DE_ASSERT(type < TEST_LAST);
482}
483
484SampleShadingRenderingCase::~SampleShadingRenderingCase (void)
485{
486	deinit();
487}
488
489void SampleShadingRenderingCase::init (void)
490{
491	// requirements
492
493	if (!m_context.getContextInfo().isExtensionSupported("GL_OES_sample_shading"))
494		throw tcu::NotSupportedError("Test requires GL_OES_sample_shading extension");
495	if (m_renderTarget == TARGET_DEFAULT && m_context.getRenderTarget().getNumSamples() <= 1)
496		throw tcu::NotSupportedError("Multisampled default framebuffer required");
497
498	// test purpose and expectations
499	m_testCtx.getLog()
500		<< tcu::TestLog::Message
501		<< "Verifying that a varying is given at least N different values for different samples within a single pixel.\n"
502		<< "	Render high-frequency function, map result to black/white. Modify N with glMinSampleShading().\n"
503		<< "	=> Resulting image should contain N+1 shades of gray.\n"
504		<< tcu::TestLog::EndMessage;
505
506	// setup resources
507
508	MultisampleShaderRenderUtil::MultisampleRenderCase::init();
509
510	// set iterations
511
512	m_numIterations = m_numTargetSamples + 1;
513}
514
515void SampleShadingRenderingCase::setShadingValue (int sampleCount)
516{
517	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
518
519	if (sampleCount == 0)
520	{
521		gl.disable(GL_SAMPLE_SHADING);
522		gl.minSampleShading(1.0f);
523		GLU_EXPECT_NO_ERROR(gl.getError(), "set ratio");
524	}
525	else
526	{
527		// Minimum number of samples is max(ceil(<mss> * <samples>),1). Decrease mss with epsilon to prevent
528		// ceiling to a too large sample count.
529		const float epsilon	= 0.25f / (float)m_numTargetSamples;
530		const float ratio	= (sampleCount / (float)m_numTargetSamples) - epsilon;
531
532		gl.enable(GL_SAMPLE_SHADING);
533		gl.minSampleShading(ratio);
534		GLU_EXPECT_NO_ERROR(gl.getError(), "set ratio");
535
536		m_testCtx.getLog()
537			<< tcu::TestLog::Message
538			<< "Setting MIN_SAMPLE_SHADING_VALUE = " << ratio << "\n"
539			<< "Requested sample count: shadingValue * numSamples = " << ratio << " * " << m_numTargetSamples << " = " << (ratio * m_numTargetSamples) << "\n"
540			<< "Minimum sample count: ceil(shadingValue * numSamples) = ceil(" << (ratio * m_numTargetSamples) << ") = " << sampleCount
541			<< tcu::TestLog::EndMessage;
542
543		// can't fail with reasonable values of numSamples
544		DE_ASSERT(deFloatCeil(ratio * m_numTargetSamples) == float(sampleCount));
545	}
546}
547
548void SampleShadingRenderingCase::preDraw (void)
549{
550	setShadingValue(m_iteration);
551}
552
553void SampleShadingRenderingCase::postDraw (void)
554{
555	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
556
557	gl.disable(GL_SAMPLE_SHADING);
558	gl.minSampleShading(1.0f);
559}
560
561std::string	SampleShadingRenderingCase::getIterationDescription (int iteration) const
562{
563	if (iteration == 0)
564		return "Disabled SAMPLE_SHADING";
565	else
566		return "Samples per pixel: " + de::toString(iteration);
567}
568
569bool SampleShadingRenderingCase::verifyImage (const tcu::Surface& resultImage)
570{
571	const int				numShadesRequired	= (m_iteration == 0) ? (2) : (m_iteration + 1);
572	const int				rareThreshold		= 100;
573	int						rareCount			= 0;
574	std::map<deUint32, int>	shadeFrequency;
575
576	// we should now have n+1 different shades of white, n = num samples
577
578	m_testCtx.getLog()
579		<< tcu::TestLog::Image("ResultImage", "Result Image", resultImage.getAccess())
580		<< tcu::TestLog::Message
581		<< "Verifying image has (at least) " << numShadesRequired << " different shades.\n"
582		<< "Excluding pixels with no full coverage (pixels on the shared edge of the triangle pair)."
583		<< tcu::TestLog::EndMessage;
584
585	for (int y = 0; y < RENDER_SIZE; ++y)
586	for (int x = 0; x < RENDER_SIZE; ++x)
587	{
588		const tcu::RGBA	color	= resultImage.getPixel(x, y);
589		const deUint32	packed	= ((deUint32)color.getRed()) + ((deUint32)color.getGreen() << 8) + ((deUint32)color.getGreen() << 16);
590
591		// on the triangle edge, skip
592		if (x == y)
593			continue;
594
595		if (shadeFrequency.find(packed) == shadeFrequency.end())
596			shadeFrequency[packed] = 1;
597		else
598			shadeFrequency[packed] = shadeFrequency[packed] + 1;
599	}
600
601	for (std::map<deUint32, int>::const_iterator it = shadeFrequency.begin(); it != shadeFrequency.end(); ++it)
602		if (it->second < rareThreshold)
603			rareCount++;
604
605	m_testCtx.getLog()
606		<< tcu::TestLog::Message
607		<< "Found " << (int)shadeFrequency.size() << " different shades.\n"
608		<< "\tRare (less than " << rareThreshold << " pixels): " << rareCount << "\n"
609		<< "\tCommon: " << (int)shadeFrequency.size() - rareCount << "\n"
610		<< tcu::TestLog::EndMessage;
611
612	if ((int)shadeFrequency.size() < numShadesRequired)
613	{
614		m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed." << tcu::TestLog::EndMessage;
615		return false;
616	}
617	return true;
618}
619
620std::string SampleShadingRenderingCase::genFragmentSource (int numSamples) const
621{
622	DE_UNREF(numSamples);
623
624	std::ostringstream buf;
625
626	buf <<	"#version 310 es\n"
627			"in highp vec4 v_position;\n"
628			"layout(location = 0) out mediump vec4 fragColor;\n"
629			"void main (void)\n"
630			"{\n"
631			"	highp float field = dot(v_position.xy, v_position.xy) + dot(21.0 * v_position.xx, sin(3.1 * v_position.xy));\n"
632			"	fragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
633			"\n"
634			"	if (fract(field) > 0.5)\n";
635
636	if (m_type == TEST_DISCARD)
637		buf <<	"		discard;\n";
638	else if (m_type == TEST_COLOR)
639		buf <<	"		fragColor = vec4(0.0, 0.0, 0.0, 1.0);\n";
640	else
641		DE_ASSERT(false);
642
643	buf <<	"}";
644
645	return buf.str();
646}
647
648} // anonymous
649
650SampleShadingTests::SampleShadingTests (Context& context)
651	: TestCaseGroup(context, "sample_shading", "Test sample shading")
652{
653}
654
655SampleShadingTests::~SampleShadingTests (void)
656{
657}
658
659void SampleShadingTests::init (void)
660{
661	tcu::TestCaseGroup* const stateQueryGroup = new tcu::TestCaseGroup(m_testCtx, "state_query", "State query tests.");
662	tcu::TestCaseGroup* const minSamplesGroup = new tcu::TestCaseGroup(m_testCtx, "min_sample_shading", "Min sample shading tests.");
663
664	addChild(stateQueryGroup);
665	addChild(minSamplesGroup);
666
667	// .state query
668	{
669		stateQueryGroup->addChild(new SampleShadingStateCase			(m_context, "sample_shading_is_enabled",				"test SAMPLE_SHADING",						SampleShadingStateCase::TYPE_IS_ENABLED));
670		stateQueryGroup->addChild(new SampleShadingStateCase			(m_context, "sample_shading_get_boolean",				"test SAMPLE_SHADING",						SampleShadingStateCase::TYPE_GET_BOOLEAN));
671		stateQueryGroup->addChild(new SampleShadingStateCase			(m_context, "sample_shading_get_integer",				"test SAMPLE_SHADING",						SampleShadingStateCase::TYPE_GET_INTEGER));
672		stateQueryGroup->addChild(new SampleShadingStateCase			(m_context, "sample_shading_get_float",					"test SAMPLE_SHADING",						SampleShadingStateCase::TYPE_GET_FLOAT));
673		stateQueryGroup->addChild(new SampleShadingStateCase			(m_context, "sample_shading_get_integer64",				"test SAMPLE_SHADING",						SampleShadingStateCase::TYPE_GET_INTEGER64));
674		stateQueryGroup->addChild(new MinSampleShadingValueCase			(m_context, "min_sample_shading_value_get_boolean",		"test MIN_SAMPLE_SHADING_VALUE",			MinSampleShadingValueCase::TYPE_GET_BOOLEAN));
675		stateQueryGroup->addChild(new MinSampleShadingValueCase			(m_context, "min_sample_shading_value_get_integer",		"test MIN_SAMPLE_SHADING_VALUE",			MinSampleShadingValueCase::TYPE_GET_INTEGER));
676		stateQueryGroup->addChild(new MinSampleShadingValueCase			(m_context, "min_sample_shading_value_get_float",		"test MIN_SAMPLE_SHADING_VALUE",			MinSampleShadingValueCase::TYPE_GET_FLOAT));
677		stateQueryGroup->addChild(new MinSampleShadingValueCase			(m_context, "min_sample_shading_value_get_integer64",	"test MIN_SAMPLE_SHADING_VALUE",			MinSampleShadingValueCase::TYPE_GET_INTEGER64));
678		stateQueryGroup->addChild(new MinSampleShadingValueClampingCase	(m_context, "min_sample_shading_value_clamping",		"test MIN_SAMPLE_SHADING_VALUE clamping"));
679	}
680
681	// .min_sample_count
682	{
683		static const struct Target
684		{
685			SampleShadingRenderingCase::RenderTarget	target;
686			int											numSamples;
687			const char*									name;
688		} targets[] =
689		{
690			{ SampleShadingRenderingCase::TARGET_DEFAULT,			0,	"default_framebuffer"					},
691			{ SampleShadingRenderingCase::TARGET_TEXTURE,			2,	"multisample_texture_samples_2"			},
692			{ SampleShadingRenderingCase::TARGET_TEXTURE,			4,	"multisample_texture_samples_4"			},
693			{ SampleShadingRenderingCase::TARGET_TEXTURE,			8,	"multisample_texture_samples_8"			},
694			{ SampleShadingRenderingCase::TARGET_TEXTURE,			16,	"multisample_texture_samples_16"		},
695			{ SampleShadingRenderingCase::TARGET_RENDERBUFFER,		2,	"multisample_renderbuffer_samples_2"	},
696			{ SampleShadingRenderingCase::TARGET_RENDERBUFFER,		4,	"multisample_renderbuffer_samples_4"	},
697			{ SampleShadingRenderingCase::TARGET_RENDERBUFFER,		8,	"multisample_renderbuffer_samples_8"	},
698			{ SampleShadingRenderingCase::TARGET_RENDERBUFFER,		16,	"multisample_renderbuffer_samples_16"	},
699		};
700
701		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(targets); ++ndx)
702		{
703			minSamplesGroup->addChild(new SampleShadingRenderingCase(m_context, (std::string(targets[ndx].name) + "_color").c_str(),	"Test multiple samples per pixel with color",	targets[ndx].target, targets[ndx].numSamples, SampleShadingRenderingCase::TEST_COLOR));
704			minSamplesGroup->addChild(new SampleShadingRenderingCase(m_context, (std::string(targets[ndx].name) + "_discard").c_str(),	"Test multiple samples per pixel with",			targets[ndx].target, targets[ndx].numSamples, SampleShadingRenderingCase::TEST_DISCARD));
705		}
706	}
707}
708
709} // Functional
710} // gles31
711} // deqp
712