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 Multisample interpolation state query tests
22 *//*--------------------------------------------------------------------*/
23
24#include "es31fShaderMultisampleInterpolationStateQueryTests.hpp"
25#include "tcuTestLog.hpp"
26#include "gluCallLogWrapper.hpp"
27#include "gluContextInfo.hpp"
28#include "gluRenderContext.hpp"
29#include "glsStateQueryUtil.hpp"
30#include "glwEnums.hpp"
31#include "glwFunctions.hpp"
32
33
34namespace deqp
35{
36namespace gles31
37{
38namespace Functional
39{
40namespace
41{
42
43using namespace gls::StateQueryUtil;
44
45class InterpolationOffsetCase : public TestCase
46{
47public:
48	enum TestType
49	{
50		TEST_MIN_OFFSET = 0,
51		TEST_MAX_OFFSET,
52
53		TEST_LAST
54	};
55
56						InterpolationOffsetCase		(Context& context, const char* name, const char* desc, QueryType verifier, TestType testType);
57						~InterpolationOffsetCase	(void);
58
59	void				init						(void);
60	IterateResult		iterate						(void);
61
62private:
63	const QueryType		m_verifier;
64	const TestType		m_testType;
65};
66
67InterpolationOffsetCase::InterpolationOffsetCase (Context& context, const char* name, const char* desc, QueryType verifier, TestType testType)
68	: TestCase		(context, name, desc)
69	, m_verifier	(verifier)
70	, m_testType	(testType)
71{
72	DE_ASSERT(m_testType < TEST_LAST);
73}
74
75InterpolationOffsetCase::~InterpolationOffsetCase (void)
76{
77}
78
79void InterpolationOffsetCase::init (void)
80{
81	auto		ctxType			= m_context.getRenderContext().getType();
82	const bool	isES32orGL45	= glu::contextSupports(ctxType, glu::ApiType::es(3, 2)) ||
83								  glu::contextSupports(ctxType, glu::ApiType::core(4, 5));
84
85	if (!isES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
86		throw tcu::NotSupportedError("Test requires GL_OES_shader_multisample_interpolation extension");
87}
88
89InterpolationOffsetCase::IterateResult InterpolationOffsetCase::iterate (void)
90{
91	glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
92	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");
93	gl.enableLogging(true);
94
95	if (m_testType == TEST_MAX_OFFSET)
96	{
97		glw::GLfloat fragmentInterpolationOffsetBits = 0.0;
98		gl.glGetFloatv(GL_FRAGMENT_INTERPOLATION_OFFSET_BITS, &fragmentInterpolationOffsetBits);
99		GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv");
100
101		glw::GLfloat ULP = 1.0f / powf(2, fragmentInterpolationOffsetBits);
102
103		verifyStateFloatMin(result, gl, GL_MAX_FRAGMENT_INTERPOLATION_OFFSET, 0.5f-ULP, m_verifier);
104	}
105	else if (m_testType == TEST_MIN_OFFSET)
106		verifyStateFloatMax(result, gl, GL_MIN_FRAGMENT_INTERPOLATION_OFFSET, -0.5f, m_verifier);
107	else
108		DE_ASSERT(false);
109
110	result.setTestContextResult(m_testCtx);
111	return STOP;
112}
113
114class FragmentInterpolationOffsetBitsCase : public TestCase
115{
116public:
117						FragmentInterpolationOffsetBitsCase		(Context& context, const char* name, const char* desc, QueryType verifier);
118						~FragmentInterpolationOffsetBitsCase	(void);
119
120	void				init									(void);
121	IterateResult		iterate									(void);
122
123private:
124	const QueryType		m_verifier;
125};
126
127FragmentInterpolationOffsetBitsCase::FragmentInterpolationOffsetBitsCase (Context& context, const char* name, const char* desc, QueryType verifier)
128	: TestCase		(context, name, desc)
129	, m_verifier	(verifier)
130{
131}
132
133FragmentInterpolationOffsetBitsCase::~FragmentInterpolationOffsetBitsCase (void)
134{
135}
136
137void FragmentInterpolationOffsetBitsCase::init (void)
138{
139	auto		ctxType			= m_context.getRenderContext().getType();
140	const bool	isES32orGL45	= glu::contextSupports(ctxType, glu::ApiType::es(3, 2)) ||
141								  glu::contextSupports(ctxType, glu::ApiType::core(4, 5));
142
143	if (!isES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
144		throw tcu::NotSupportedError("Test requires GL_OES_shader_multisample_interpolation extension");
145}
146
147FragmentInterpolationOffsetBitsCase::IterateResult FragmentInterpolationOffsetBitsCase::iterate (void)
148{
149	glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
150	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");
151	gl.enableLogging(true);
152
153	verifyStateIntegerMin(result, gl, GL_FRAGMENT_INTERPOLATION_OFFSET_BITS, 4, m_verifier);
154
155	result.setTestContextResult(m_testCtx);
156	return STOP;
157}
158
159} // anonymous
160
161ShaderMultisampleInterpolationStateQueryTests::ShaderMultisampleInterpolationStateQueryTests (Context& context)
162	: TestCaseGroup(context, "multisample_interpolation", "Test multisample interpolation states")
163{
164}
165
166ShaderMultisampleInterpolationStateQueryTests::~ShaderMultisampleInterpolationStateQueryTests (void)
167{
168}
169
170void ShaderMultisampleInterpolationStateQueryTests::init (void)
171{
172	static const struct Verifier
173	{
174		QueryType		verifier;
175		const char*		name;
176		const char*		desc;
177	} verifiers[] =
178	{
179		{ QUERY_BOOLEAN,	"get_boolean",		"Test using getBoolean"		},
180		{ QUERY_INTEGER,	"get_integer",		"Test using getInteger"		},
181		{ QUERY_FLOAT,		"get_float",		"Test using getFloat"		},
182		{ QUERY_INTEGER64,	"get_integer64",	"Test using getInteger64"	},
183	};
184
185	// .min_fragment_interpolation_offset
186	{
187		tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "min_fragment_interpolation_offset", "Test MIN_FRAGMENT_INTERPOLATION_OFFSET");
188		addChild(group);
189
190		for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)
191			group->addChild(new InterpolationOffsetCase(m_context, verifiers[verifierNdx].name, verifiers[verifierNdx].desc, verifiers[verifierNdx].verifier, InterpolationOffsetCase::TEST_MIN_OFFSET));
192	}
193
194	// .max_fragment_interpolation_offset
195	{
196		tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "max_fragment_interpolation_offset", "Test MAX_FRAGMENT_INTERPOLATION_OFFSET");
197		addChild(group);
198
199		for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)
200			group->addChild(new InterpolationOffsetCase(m_context, verifiers[verifierNdx].name, verifiers[verifierNdx].desc, verifiers[verifierNdx].verifier, InterpolationOffsetCase::TEST_MAX_OFFSET));
201	}
202
203	// .fragment_interpolation_offset_bits
204	{
205		tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "fragment_interpolation_offset_bits", "Test FRAGMENT_INTERPOLATION_OFFSET_BITS");
206		addChild(group);
207
208		for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)
209			group->addChild(new FragmentInterpolationOffsetBitsCase(m_context, verifiers[verifierNdx].name, verifiers[verifierNdx].desc, verifiers[verifierNdx].verifier));
210	}
211}
212
213} // Functional
214} // gles31
215} // deqp
216