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 
33 namespace deqp
34 {
35 namespace gles2
36 {
37 namespace Functional
38 {
39 
40 using namespace glw; // GL types
41 
42 namespace LimitQuery
43 {
44 
45 // Query function template.
46 template<typename T>
47 T query (const glw::Functions& gl, deUint32 param);
48 
49 // Compare template.
50 template<typename T>
compare(const T & min,const T & reported)51 inline bool compare (const T& min, const T& reported) { return min <= reported; }
52 
53 // Types for queries
54 
55 struct NegInt
56 {
57 	GLint value;
NegIntdeqp::gles2::Functional::LimitQuery::NegInt58 	NegInt (GLint value_) : value(value_) {}
59 };
60 
operator <<(std::ostream & str,const NegInt & v)61 std::ostream& operator<< (std::ostream& str, const NegInt& v) { return str << v.value; }
62 
63 struct FloatRange
64 {
65 	float min;
66 	float max;
FloatRangedeqp::gles2::Functional::LimitQuery::FloatRange67 	FloatRange (float min_, float max_) : min(min_), max(max_) {}
68 };
69 
operator <<(std::ostream & str,const FloatRange & range)70 std::ostream& operator<< (std::ostream& str, const FloatRange& range) { return str << range.min << ", " << range.max; }
71 
72 // For custom formatting
73 struct Boolean
74 {
75 	GLboolean value;
Booleandeqp::gles2::Functional::LimitQuery::Boolean76 	Boolean (GLboolean value_) : value(value_) {}
77 };
78 
operator <<(std::ostream & str,const Boolean & boolean)79 std::ostream& operator<< (std::ostream& str, const Boolean& boolean) { return str << (boolean.value ? "GL_TRUE" : "GL_FALSE"); }
80 
81 // Query function implementations.
82 template<>
query(const glw::Functions & gl,deUint32 param)83 GLint query<GLint> (const glw::Functions& gl, deUint32 param)
84 {
85 	GLint val = -1;
86 	gl.getIntegerv(param, &val);
87 	return val;
88 }
89 
90 template<>
query(const glw::Functions & gl,deUint32 param)91 GLfloat query<GLfloat> (const glw::Functions& gl, deUint32 param)
92 {
93 	GLfloat val = -1000.f;
94 	gl.getFloatv(param, &val);
95 	return val;
96 }
97 
98 template<>
query(const glw::Functions & gl,deUint32 param)99 NegInt query<NegInt> (const glw::Functions& gl, deUint32 param)
100 {
101 	return NegInt(query<GLint>(gl, param));
102 }
103 
104 template<>
query(const glw::Functions & gl,deUint32 param)105 Boolean 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 
112 template<>
query(const glw::Functions & gl,deUint32 param)113 FloatRange 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
121 template<>
compare(const Boolean & min,const Boolean & reported)122 bool compare<Boolean> (const Boolean& min, const Boolean& reported)
123 {
124 	return !min.value || (min.value && reported.value);
125 }
126 
127 template<>
compare(const NegInt & min,const NegInt & reported)128 bool compare<NegInt> (const NegInt& min, const NegInt& reported)
129 {
130 	// Reverse comparison.
131 	return reported.value <= min.value;
132 }
133 
134 template<>
compare(const FloatRange & min,const FloatRange & reported)135 bool compare<FloatRange> (const FloatRange& min, const FloatRange& reported)
136 {
137 	return reported.min <= min.min && min.max <= reported.max;
138 }
139 
140 } // LimitQuery
141 
142 using namespace LimitQuery;
143 using tcu::TestLog;
144 
145 template<typename T>
146 class LimitQueryCase : public TestCase
147 {
148 public:
LimitQueryCase(Context & context,const char * name,const char * description,deUint32 limit,const T & minRequiredValue)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 
iterate(void)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 
175 private:
176 	deUint32	m_limit;
177 	T			m_minRequiredValue;
178 };
179 
ImplementationLimitTests(Context & context)180 ImplementationLimitTests::ImplementationLimitTests (Context& context)
181 	: TestCaseGroup(context, "implementation_limits", "Implementation-defined limits")
182 {
183 }
184 
~ImplementationLimitTests(void)185 ImplementationLimitTests::~ImplementationLimitTests (void)
186 {
187 }
188 
init(void)189 void 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