1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.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 Integer64 State Query tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es3fInteger64StateQueryTests.hpp"
25 #include "glsStateQueryUtil.hpp"
26 #include "es3fApiCase.hpp"
27 #include "gluRenderContext.hpp"
28 #include "tcuRenderTarget.hpp"
29 #include "glwEnums.hpp"
30
31 #include <limits>
32
33 using namespace glw; // GLint and other
34 using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
35
36 namespace deqp
37 {
38 namespace gles3
39 {
40 namespace Functional
41 {
42 namespace Integer64StateQueryVerifiers
43 {
44
45 // StateVerifier
46
47 class StateVerifier : protected glu::CallLogWrapper
48 {
49 public:
50 StateVerifier (const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix);
51 virtual ~StateVerifier (); // make GCC happy
52
53 const char* getTestNamePostfix (void) const;
54
55 virtual void verifyUnsignedInteger64GreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint64 reference) = DE_NULL;
56
57 private:
58 const char* const m_testNamePostfix;
59 };
60
StateVerifier(const glw::Functions & gl,tcu::TestLog & log,const char * testNamePostfix)61 StateVerifier::StateVerifier (const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix)
62 : glu::CallLogWrapper (gl, log)
63 , m_testNamePostfix (testNamePostfix)
64 {
65 enableLogging(true);
66 }
67
~StateVerifier()68 StateVerifier::~StateVerifier ()
69 {
70 }
71
getTestNamePostfix(void) const72 const char* StateVerifier::getTestNamePostfix (void) const
73 {
74 return m_testNamePostfix;
75 }
76
77 // GetBooleanVerifier
78
79 class GetBooleanVerifier : public StateVerifier
80 {
81 public:
82 GetBooleanVerifier (const glw::Functions& gl, tcu::TestLog& log);
83 void verifyUnsignedInteger64GreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint64 reference);
84 };
85
GetBooleanVerifier(const glw::Functions & gl,tcu::TestLog & log)86 GetBooleanVerifier::GetBooleanVerifier (const glw::Functions& gl, tcu::TestLog& log)
87 : StateVerifier(gl, log, "_getboolean")
88 {
89 }
90
verifyUnsignedInteger64GreaterOrEqual(tcu::TestContext & testCtx,GLenum name,GLuint64 reference)91 void GetBooleanVerifier::verifyUnsignedInteger64GreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint64 reference)
92 {
93 using tcu::TestLog;
94
95 StateQueryMemoryWriteGuard<GLboolean> state;
96 glGetBooleanv(name, &state);
97
98 if (!state.verifyValidity(testCtx))
99 return;
100
101 if (state == GL_TRUE) // state is non-zero, could be greater than reference (correct)
102 return;
103
104 if (state == GL_FALSE) // state is zero
105 {
106 if (reference > 0) // and reference is greater than zero?
107 {
108 testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE" << TestLog::EndMessage;
109 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
110 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
111 }
112 }
113 else
114 {
115 testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE or GL_FALSE" << TestLog::EndMessage;
116 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
117 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
118 }
119 }
120
121 //GetIntegerVerifier
122
123 class GetIntegerVerifier : public StateVerifier
124 {
125 public:
126 GetIntegerVerifier (const glw::Functions& gl, tcu::TestLog& log);
127 void verifyUnsignedInteger64GreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint64 reference);
128 };
129
GetIntegerVerifier(const glw::Functions & gl,tcu::TestLog & log)130 GetIntegerVerifier::GetIntegerVerifier (const glw::Functions& gl, tcu::TestLog& log)
131 : StateVerifier(gl, log, "_getinteger")
132 {
133 }
134
verifyUnsignedInteger64GreaterOrEqual(tcu::TestContext & testCtx,GLenum name,GLuint64 reference)135 void GetIntegerVerifier::verifyUnsignedInteger64GreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint64 reference)
136 {
137 using tcu::TestLog;
138
139 StateQueryMemoryWriteGuard<GLint> state;
140 glGetIntegerv(name, &state);
141
142 if (!state.verifyValidity(testCtx))
143 return;
144
145 // check that the converted value would be in the correct range, otherwise checking wont tell us anything
146 if (reference > (GLuint64)std::numeric_limits<GLint>::max())
147 return;
148
149 if (GLuint(state) < reference)
150 {
151 testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << reference << "; got " << state << TestLog::EndMessage;
152 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
153 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
154 }
155 }
156
157 //GetFloatVerifier
158
159 class GetFloatVerifier : public StateVerifier
160 {
161 public:
162 GetFloatVerifier (const glw::Functions& gl, tcu::TestLog& log);
163 void verifyUnsignedInteger64GreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint64 reference);
164 };
165
GetFloatVerifier(const glw::Functions & gl,tcu::TestLog & log)166 GetFloatVerifier::GetFloatVerifier (const glw::Functions& gl, tcu::TestLog& log)
167 : StateVerifier(gl, log, "_getfloat")
168 {
169 }
170
verifyUnsignedInteger64GreaterOrEqual(tcu::TestContext & testCtx,GLenum name,GLuint64 reference)171 void GetFloatVerifier::verifyUnsignedInteger64GreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLuint64 reference)
172 {
173 using tcu::TestLog;
174
175 StateQueryMemoryWriteGuard<GLfloat> state;
176 glGetFloatv(name, &state);
177
178 if (!state.verifyValidity(testCtx))
179 return;
180
181 if (state < GLfloat(reference))
182 {
183 testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << GLfloat(reference) << "; got " << state << TestLog::EndMessage;
184 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
185 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
186 }
187 }
188
189 } // Integer64StateQueryVerifiers
190
191 namespace
192 {
193
194 using namespace Integer64StateQueryVerifiers;
195
196 class ConstantMinimumValue64TestCase : public ApiCase
197 {
198 public:
ConstantMinimumValue64TestCase(Context & context,StateVerifier * verifier,const char * name,const char * description,GLenum targetName,GLuint64 minValue)199 ConstantMinimumValue64TestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum targetName, GLuint64 minValue)
200 : ApiCase (context, name, description)
201 , m_targetName (targetName)
202 , m_minValue (minValue)
203 , m_verifier (verifier)
204 {
205 }
206
test(void)207 void test (void)
208 {
209 m_verifier->verifyUnsignedInteger64GreaterOrEqual(m_testCtx, m_targetName, m_minValue);
210 expectError(GL_NO_ERROR);
211 }
212
213 private:
214 GLenum m_targetName;
215 GLuint64 m_minValue;
216 StateVerifier* m_verifier;
217 };
218
219 class MaxCombinedStageUniformComponentsCase : public ApiCase
220 {
221 public:
MaxCombinedStageUniformComponentsCase(Context & context,StateVerifier * verifier,const char * name,const char * description,GLenum targetName,GLenum targetMaxUniformBlocksName,GLenum targetMaxUniformComponentsName)222 MaxCombinedStageUniformComponentsCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum targetName, GLenum targetMaxUniformBlocksName, GLenum targetMaxUniformComponentsName)
223 : ApiCase (context, name, description)
224 , m_targetName (targetName)
225 , m_targetMaxUniformBlocksName (targetMaxUniformBlocksName)
226 , m_targetMaxUniformComponentsName (targetMaxUniformComponentsName)
227 , m_verifier (verifier)
228 {
229 }
230
test(void)231 void test (void)
232 {
233 GLint uniformBlockSize = 0;
234 glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &uniformBlockSize);
235 expectError(GL_NO_ERROR);
236
237 GLint maxUniformBlocks = 0;
238 GLint maxUniformComponents = 0;
239 glGetIntegerv(m_targetMaxUniformBlocksName, &maxUniformBlocks);
240 glGetIntegerv(m_targetMaxUniformComponentsName, &maxUniformComponents);
241 expectError(GL_NO_ERROR);
242
243 // MAX_stage_UNIFORM_BLOCKS * MAX_UNIFORM_BLOCK_SIZE / 4 + MAX_stage_UNIFORM_COMPONENTS
244 const GLuint64 minCombinedUniformComponents = GLuint64(maxUniformBlocks) * uniformBlockSize / 4 + maxUniformComponents;
245
246 m_verifier->verifyUnsignedInteger64GreaterOrEqual(m_testCtx, m_targetName, minCombinedUniformComponents);
247 expectError(GL_NO_ERROR);
248 }
249
250 private:
251 GLenum m_targetName;
252 GLenum m_targetMaxUniformBlocksName;
253 GLenum m_targetMaxUniformComponentsName;
254 StateVerifier* m_verifier;
255 };
256
257 #define FOR_EACH_VERIFIER(VERIFIERS, CODE_BLOCK) \
258 for (int _verifierNdx = 0; _verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); _verifierNdx++) \
259 { \
260 StateVerifier* verifier = VERIFIERS[_verifierNdx]; \
261 CODE_BLOCK; \
262 }
263
264 } // anonymous
265
Integer64StateQueryTests(Context & context)266 Integer64StateQueryTests::Integer64StateQueryTests (Context& context)
267 : TestCaseGroup (context, "integers64", "Integer (64) Values")
268 , m_verifierBoolean (DE_NULL)
269 , m_verifierInteger (DE_NULL)
270 , m_verifierFloat (DE_NULL)
271 {
272 }
273
~Integer64StateQueryTests(void)274 Integer64StateQueryTests::~Integer64StateQueryTests (void)
275 {
276 deinit();
277 }
278
init(void)279 void Integer64StateQueryTests::init (void)
280 {
281 DE_ASSERT(m_verifierBoolean == DE_NULL);
282 DE_ASSERT(m_verifierInteger == DE_NULL);
283 DE_ASSERT(m_verifierFloat == DE_NULL);
284
285 m_verifierBoolean = new GetBooleanVerifier (m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
286 m_verifierInteger = new GetIntegerVerifier (m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
287 m_verifierFloat = new GetFloatVerifier (m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
288
289 const struct LimitedStateInteger64
290 {
291 const char* name;
292 const char* description;
293 GLenum targetName;
294 GLuint64 minValue;
295 } implementationLimits[] =
296 {
297 { "max_element_index", "MAX_ELEMENT_INDEX", GL_MAX_ELEMENT_INDEX, 0x00FFFFFF /*2^24-1*/ },
298 { "max_server_wait_timeout", "MAX_SERVER_WAIT_TIMEOUT", GL_MAX_SERVER_WAIT_TIMEOUT, 0 },
299 { "max_uniform_block_size", "MAX_UNIFORM_BLOCK_SIZE", GL_MAX_UNIFORM_BLOCK_SIZE, 16384 }
300 };
301
302 // \note do not check the values with integer64 verifier as that has already been checked in implementation_limits
303 StateVerifier* verifiers[] = {m_verifierBoolean, m_verifierInteger, m_verifierFloat};
304
305 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(implementationLimits); testNdx++)
306 FOR_EACH_VERIFIER(verifiers, addChild(new ConstantMinimumValue64TestCase(m_context, verifier, (std::string(implementationLimits[testNdx].name) + verifier->getTestNamePostfix()).c_str(), implementationLimits[testNdx].description, implementationLimits[testNdx].targetName, implementationLimits[testNdx].minValue)));
307
308 FOR_EACH_VERIFIER(verifiers, addChild(new MaxCombinedStageUniformComponentsCase (m_context, verifier, (std::string("max_combined_vertex_uniform_components") + verifier->getTestNamePostfix()).c_str(), "MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS", GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, GL_MAX_VERTEX_UNIFORM_BLOCKS, GL_MAX_VERTEX_UNIFORM_COMPONENTS)));
309 FOR_EACH_VERIFIER(verifiers, addChild(new MaxCombinedStageUniformComponentsCase (m_context, verifier, (std::string("max_combined_fragment_uniform_components") + verifier->getTestNamePostfix()).c_str(), "MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS", GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, GL_MAX_FRAGMENT_UNIFORM_BLOCKS, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS)));
310 }
311
deinit(void)312 void Integer64StateQueryTests::deinit (void)
313 {
314 if (m_verifierBoolean)
315 {
316 delete m_verifierBoolean;
317 m_verifierBoolean = DE_NULL;
318 }
319 if (m_verifierInteger)
320 {
321 delete m_verifierInteger;
322 m_verifierInteger = DE_NULL;
323 }
324 if (m_verifierFloat)
325 {
326 delete m_verifierFloat;
327 m_verifierFloat = DE_NULL;
328 }
329
330 this->TestCaseGroup::deinit();
331 }
332
333 } // Functional
334 } // gles3
335 } // deqp
336