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