1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.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 Implementation-defined limit tests.
22 *//*--------------------------------------------------------------------*/
23
24#include "es2fImplementationLimitTests.hpp"
25#include "tcuTestLog.hpp"
26#include "gluDefs.hpp"
27#include "gluStrUtil.hpp"
28#include "gluRenderContext.hpp"
29
30#include "glwEnums.hpp"
31#include "glwFunctions.hpp"
32
33namespace deqp
34{
35namespace gles2
36{
37namespace Functional
38{
39
40using namespace glw; // GL types
41
42namespace LimitQuery
43{
44
45// Query function template.
46template<typename T>
47T query (const glw::Functions& gl, deUint32 param);
48
49// Compare template.
50template<typename T>
51inline bool compare (const T& min, const T& reported) { return min <= reported; }
52
53// Types for queries
54
55struct NegInt
56{
57	GLint value;
58	NegInt (GLint value_) : value(value_) {}
59};
60
61std::ostream& operator<< (std::ostream& str, const NegInt& v) { return str << v.value; }
62
63struct FloatRange
64{
65	float min;
66	float max;
67	FloatRange (float min_, float max_) : min(min_), max(max_) {}
68};
69
70std::ostream& operator<< (std::ostream& str, const FloatRange& range) { return str << range.min << ", " << range.max; }
71
72// For custom formatting
73struct Boolean
74{
75	GLboolean value;
76	Boolean (GLboolean value_) : value(value_) {}
77};
78
79std::ostream& operator<< (std::ostream& str, const Boolean& boolean) { return str << (boolean.value ? "GL_TRUE" : "GL_FALSE"); }
80
81// Query function implementations.
82template<>
83GLint query<GLint> (const glw::Functions& gl, deUint32 param)
84{
85	GLint val = -1;
86	gl.getIntegerv(param, &val);
87	return val;
88}
89
90template<>
91GLfloat query<GLfloat> (const glw::Functions& gl, deUint32 param)
92{
93	GLfloat val = -1000.f;
94	gl.getFloatv(param, &val);
95	return val;
96}
97
98template<>
99NegInt query<NegInt> (const glw::Functions& gl, deUint32 param)
100{
101	return NegInt(query<GLint>(gl, param));
102}
103
104template<>
105Boolean query<Boolean> (const glw::Functions& gl, deUint32 param)
106{
107	GLboolean val = GL_FALSE;
108	gl.getBooleanv(param, &val);
109	return Boolean(val);
110}
111
112template<>
113FloatRange query<FloatRange> (const glw::Functions& gl, deUint32 param)
114{
115	float v[2] = { -1.0f, -1.0f };
116	gl.getFloatv(param, &v[0]);
117	return FloatRange(v[0], v[1]);
118}
119
120// Special comparison operators
121template<>
122bool compare<Boolean> (const Boolean& min, const Boolean& reported)
123{
124	return !min.value || (min.value && reported.value);
125}
126
127template<>
128bool compare<NegInt> (const NegInt& min, const NegInt& reported)
129{
130	// Reverse comparison.
131	return reported.value <= min.value;
132}
133
134template<>
135bool compare<FloatRange> (const FloatRange& min, const FloatRange& reported)
136{
137	return reported.min <= min.min && min.max <= reported.max;
138}
139
140} // LimitQuery
141
142using namespace LimitQuery;
143using tcu::TestLog;
144
145template<typename T>
146class LimitQueryCase : public TestCase
147{
148public:
149	LimitQueryCase (Context& context, const char* name, const char* description, deUint32 limit, const T& minRequiredValue)
150		: TestCase				(context, name, description)
151		, m_limit				(limit)
152		, m_minRequiredValue	(minRequiredValue)
153	{
154	}
155
156	IterateResult iterate (void)
157	{
158		const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
159		const T					value	= query<T>(m_context.getRenderContext().getFunctions(), m_limit);
160		GLU_EXPECT_NO_ERROR(gl.getError(), "Query failed");
161
162		const bool isOk = compare<T>(m_minRequiredValue, value);
163
164		m_testCtx.getLog() << TestLog::Message << "Reported: " << value << TestLog::EndMessage;
165		m_testCtx.getLog() << TestLog::Message << "Minimum required: " << m_minRequiredValue << TestLog::EndMessage;
166
167		if (!isOk)
168			m_testCtx.getLog() << TestLog::Message << "FAIL: reported value is less than minimum required value!" << TestLog::EndMessage;
169
170		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
171								isOk ? "Pass"				: "Requirement not satisfied");
172		return STOP;
173	}
174
175private:
176	deUint32	m_limit;
177	T			m_minRequiredValue;
178};
179
180ImplementationLimitTests::ImplementationLimitTests (Context& context)
181	: TestCaseGroup(context, "implementation_limits", "Implementation-defined limits")
182{
183}
184
185ImplementationLimitTests::~ImplementationLimitTests (void)
186{
187}
188
189void ImplementationLimitTests::init (void)
190{
191#define LIMIT_CASE(NAME, PARAM, TYPE, MIN_VAL)	\
192	addChild(new LimitQueryCase<TYPE>(m_context, #NAME, #PARAM, PARAM, MIN_VAL))
193
194	LIMIT_CASE(subpixel_bits,						GL_SUBPIXEL_BITS,						GLint,		4);
195	LIMIT_CASE(max_texture_size,					GL_MAX_TEXTURE_SIZE,					GLint,		64);
196	LIMIT_CASE(max_cube_map_texture_size,			GL_MAX_CUBE_MAP_TEXTURE_SIZE,			GLint,		16);
197	// GL_MAX_VIEWPORT_DIMS
198	LIMIT_CASE(aliased_point_size_range,			GL_ALIASED_POINT_SIZE_RANGE,			FloatRange,	FloatRange(1,1));
199	LIMIT_CASE(aliased_line_width_range,			GL_ALIASED_LINE_WIDTH_RANGE,			FloatRange,	FloatRange(1,1));
200//	LIMIT_CASE(sample_buffers,						GL_SAMPLE_BUFFERS,						GLint,		0);
201//	LIMIT_CASE(samples,								GL_SAMPLES,								GLint,		0);
202	LIMIT_CASE(num_compressed_texture_formats,		GL_NUM_COMPRESSED_TEXTURE_FORMATS,		GLint,		0);
203	LIMIT_CASE(num_shader_binary_formats,			GL_NUM_SHADER_BINARY_FORMATS,			GLint,		0);
204	LIMIT_CASE(shader_compiler,						GL_SHADER_COMPILER,						Boolean,	GL_FALSE);
205	// Shader precision format
206	LIMIT_CASE(max_vertex_attribs,					GL_MAX_VERTEX_ATTRIBS,					GLint,		8);
207	LIMIT_CASE(max_vertex_uniform_vectors,			GL_MAX_VERTEX_UNIFORM_VECTORS,			GLint,		128);
208	LIMIT_CASE(max_varying_vectors,					GL_MAX_VARYING_VECTORS,					GLint,		8);
209	LIMIT_CASE(max_combined_texture_image_units,	GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,	GLint,		8);
210	LIMIT_CASE(max_vertex_texture_image_units,		GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,		GLint,		0);
211	LIMIT_CASE(max_texture_image_units,				GL_MAX_TEXTURE_IMAGE_UNITS,				GLint,		8);
212	LIMIT_CASE(max_fragment_uniform_vectors,		GL_MAX_FRAGMENT_UNIFORM_VECTORS,		GLint,		16);
213	LIMIT_CASE(max_renderbuffer_size,				GL_MAX_RENDERBUFFER_SIZE,				GLint,		1);
214}
215
216} // Functional
217} // gles2
218} // deqp
219