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 Texture State Query tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es2fTextureStateQueryTests.hpp"
25 #include "es2fApiCase.hpp"
26 #include "glsStateQueryUtil.hpp"
27 #include "gluRenderContext.hpp"
28 #include "glwEnums.hpp"
29 #include "glwFunctions.hpp"
30 #include "deRandom.hpp"
31 #include "deMath.h"
32
33 using namespace glw; // GLint and other GL types
34 using namespace deqp::gls;
35 using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
36
37 namespace deqp
38 {
39 namespace gles2
40 {
41 namespace Functional
42 {
43 namespace TextureParamVerifiers
44 {
45
46 // TexParamVerifier
47
48 class TexParamVerifier : protected glu::CallLogWrapper
49 {
50 public:
51 TexParamVerifier(const glw::Functions &gl, tcu::TestLog &log, const char *testNamePostfix);
52 virtual ~TexParamVerifier(); // make GCC happy
53
54 const char *getTestNamePostfix(void) const;
55
56 virtual void verifyInteger(tcu::TestContext &testCtx, GLenum target, GLenum name, GLint reference) = DE_NULL;
57 virtual void verifyFloat(tcu::TestContext &testCtx, GLenum target, GLenum name, GLfloat reference) = DE_NULL;
58
59 private:
60 const char *const m_testNamePostfix;
61 };
62
TexParamVerifier(const glw::Functions & gl,tcu::TestLog & log,const char * testNamePostfix)63 TexParamVerifier::TexParamVerifier(const glw::Functions &gl, tcu::TestLog &log, const char *testNamePostfix)
64 : glu::CallLogWrapper(gl, log)
65 , m_testNamePostfix(testNamePostfix)
66 {
67 enableLogging(true);
68 }
~TexParamVerifier()69 TexParamVerifier::~TexParamVerifier()
70 {
71 }
72
getTestNamePostfix(void) const73 const char *TexParamVerifier::getTestNamePostfix(void) const
74 {
75 return m_testNamePostfix;
76 }
77
78 class GetTexParameterIVerifier : public TexParamVerifier
79 {
80 public:
81 GetTexParameterIVerifier(const glw::Functions &gl, tcu::TestLog &log);
82
83 void verifyInteger(tcu::TestContext &testCtx, GLenum target, GLenum name, GLint reference);
84 void verifyFloat(tcu::TestContext &testCtx, GLenum target, GLenum name, GLfloat reference);
85 };
86
GetTexParameterIVerifier(const glw::Functions & gl,tcu::TestLog & log)87 GetTexParameterIVerifier::GetTexParameterIVerifier(const glw::Functions &gl, tcu::TestLog &log)
88 : TexParamVerifier(gl, log, "_gettexparameteri")
89 {
90 }
91
verifyInteger(tcu::TestContext & testCtx,GLenum target,GLenum name,GLint reference)92 void GetTexParameterIVerifier::verifyInteger(tcu::TestContext &testCtx, GLenum target, GLenum name, GLint reference)
93 {
94 using tcu::TestLog;
95
96 StateQueryMemoryWriteGuard<GLint> state;
97 glGetTexParameteriv(target, name, &state);
98
99 if (!state.verifyValidity(testCtx))
100 return;
101
102 if (state != reference)
103 {
104 testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state
105 << TestLog::EndMessage;
106
107 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
108 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid texture param value");
109 }
110 }
111
verifyFloat(tcu::TestContext & testCtx,GLenum target,GLenum name,GLfloat reference)112 void GetTexParameterIVerifier::verifyFloat(tcu::TestContext &testCtx, GLenum target, GLenum name, GLfloat reference)
113 {
114 using tcu::TestLog;
115
116 const GLint expectedGLStateMax = StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<GLint>(reference);
117 const GLint expectedGLStateMin = StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint>(reference);
118
119 StateQueryMemoryWriteGuard<GLint> state;
120 glGetTexParameteriv(target, name, &state);
121
122 if (!state.verifyValidity(testCtx))
123 return;
124
125 if (state < expectedGLStateMin || state > expectedGLStateMax)
126 {
127 testCtx.getLog() << TestLog::Message << "// ERROR: expected in range [" << expectedGLStateMin << ", "
128 << expectedGLStateMax << "]; got " << state << TestLog::EndMessage;
129
130 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
131 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid texture param value");
132 }
133 }
134
135 class GetTexParameterFVerifier : public TexParamVerifier
136 {
137 public:
138 GetTexParameterFVerifier(const glw::Functions &gl, tcu::TestLog &log);
139
140 void verifyInteger(tcu::TestContext &testCtx, GLenum target, GLenum name, GLint reference);
141 void verifyFloat(tcu::TestContext &testCtx, GLenum target, GLenum name, GLfloat reference);
142 };
143
GetTexParameterFVerifier(const glw::Functions & gl,tcu::TestLog & log)144 GetTexParameterFVerifier::GetTexParameterFVerifier(const glw::Functions &gl, tcu::TestLog &log)
145 : TexParamVerifier(gl, log, "_gettexparameterf")
146 {
147 }
148
verifyInteger(tcu::TestContext & testCtx,GLenum target,GLenum name,GLint reference)149 void GetTexParameterFVerifier::verifyInteger(tcu::TestContext &testCtx, GLenum target, GLenum name, GLint reference)
150 {
151 DE_ASSERT(
152 reference ==
153 GLint(GLfloat(
154 reference))); // reference integer must have 1:1 mapping to float for this to work. Reference value is always such value in these tests
155
156 using tcu::TestLog;
157
158 const GLfloat referenceAsFloat = GLfloat(reference);
159
160 StateQueryMemoryWriteGuard<GLfloat> state;
161 glGetTexParameterfv(target, name, &state);
162
163 if (!state.verifyValidity(testCtx))
164 return;
165
166 if (state != referenceAsFloat)
167 {
168 testCtx.getLog() << TestLog::Message << "// ERROR: expected " << referenceAsFloat << "; got " << state
169 << TestLog::EndMessage;
170
171 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
172 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
173 }
174 }
175
verifyFloat(tcu::TestContext & testCtx,GLenum target,GLenum name,GLfloat reference)176 void GetTexParameterFVerifier::verifyFloat(tcu::TestContext &testCtx, GLenum target, GLenum name, GLfloat reference)
177 {
178 using tcu::TestLog;
179
180 StateQueryMemoryWriteGuard<GLfloat> state;
181 glGetTexParameterfv(target, name, &state);
182
183 if (!state.verifyValidity(testCtx))
184 return;
185
186 if (state != reference)
187 {
188 testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state
189 << TestLog::EndMessage;
190
191 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
192 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
193 }
194 }
195
196 } // namespace TextureParamVerifiers
197
198 namespace
199 {
200
201 using namespace TextureParamVerifiers;
202
203 // Tests
204
205 class TextureCase : public ApiCase
206 {
207 public:
TextureCase(Context & context,TexParamVerifier * verifier,const char * name,const char * description,GLenum textureTarget)208 TextureCase(Context &context, TexParamVerifier *verifier, const char *name, const char *description,
209 GLenum textureTarget)
210 : ApiCase(context, name, description)
211 , m_textureTarget(textureTarget)
212 , m_verifier(verifier)
213 {
214 }
215
216 virtual void testTexture(void) = DE_NULL;
217
test(void)218 void test(void)
219 {
220 GLuint textureId = 0;
221 glGenTextures(1, &textureId);
222 glBindTexture(m_textureTarget, textureId);
223 expectError(GL_NO_ERROR);
224
225 testTexture();
226
227 glDeleteTextures(1, &textureId);
228 expectError(GL_NO_ERROR);
229 }
230
231 protected:
232 GLenum m_textureTarget;
233 TexParamVerifier *m_verifier;
234 };
235
236 class TextureWrapCase : public TextureCase
237 {
238 public:
TextureWrapCase(Context & context,TexParamVerifier * verifier,const char * name,const char * description,GLenum textureTarget,GLenum valueName)239 TextureWrapCase(Context &context, TexParamVerifier *verifier, const char *name, const char *description,
240 GLenum textureTarget, GLenum valueName)
241 : TextureCase(context, verifier, name, description, textureTarget)
242 , m_valueName(valueName)
243 {
244 }
245
testTexture(void)246 void testTexture(void)
247 {
248 const GLenum wrapValues[] = {GL_CLAMP_TO_EDGE, GL_REPEAT, GL_MIRRORED_REPEAT};
249
250 m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_valueName, GL_REPEAT);
251 expectError(GL_NO_ERROR);
252
253 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(wrapValues); ++ndx)
254 {
255 glTexParameteri(m_textureTarget, m_valueName, wrapValues[ndx]);
256 expectError(GL_NO_ERROR);
257
258 m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_valueName, wrapValues[ndx]);
259 expectError(GL_NO_ERROR);
260 }
261
262 //check unit conversions with float
263
264 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(wrapValues); ++ndx)
265 {
266 glTexParameterf(m_textureTarget, m_valueName, (GLfloat)wrapValues[ndx]);
267 expectError(GL_NO_ERROR);
268
269 m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_valueName, wrapValues[ndx]);
270 expectError(GL_NO_ERROR);
271 }
272 }
273
274 private:
275 GLenum m_valueName;
276 };
277
278 class TextureMagFilterCase : public TextureCase
279 {
280 public:
TextureMagFilterCase(Context & context,TexParamVerifier * verifier,const char * name,const char * description,GLenum textureTarget)281 TextureMagFilterCase(Context &context, TexParamVerifier *verifier, const char *name, const char *description,
282 GLenum textureTarget)
283 : TextureCase(context, verifier, name, description, textureTarget)
284 {
285 }
286
testTexture(void)287 void testTexture(void)
288 {
289 const GLenum magValues[] = {GL_NEAREST, GL_LINEAR};
290
291 m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
292 expectError(GL_NO_ERROR);
293
294 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(magValues); ++ndx)
295 {
296 glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, magValues[ndx]);
297 expectError(GL_NO_ERROR);
298
299 m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MAG_FILTER, magValues[ndx]);
300 expectError(GL_NO_ERROR);
301 }
302
303 //check unit conversions with float
304
305 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(magValues); ++ndx)
306 {
307 glTexParameterf(m_textureTarget, GL_TEXTURE_MAG_FILTER, (GLfloat)magValues[ndx]);
308 expectError(GL_NO_ERROR);
309
310 m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MAG_FILTER, magValues[ndx]);
311 expectError(GL_NO_ERROR);
312 }
313 }
314 };
315
316 class TextureMinFilterCase : public TextureCase
317 {
318 public:
TextureMinFilterCase(Context & context,TexParamVerifier * verifier,const char * name,const char * description,GLenum textureTarget)319 TextureMinFilterCase(Context &context, TexParamVerifier *verifier, const char *name, const char *description,
320 GLenum textureTarget)
321 : TextureCase(context, verifier, name, description, textureTarget)
322 {
323 }
324
testTexture(void)325 void testTexture(void)
326 {
327 const GLenum minValues[] = {GL_NEAREST,
328 GL_LINEAR,
329 GL_NEAREST_MIPMAP_NEAREST,
330 GL_NEAREST_MIPMAP_LINEAR,
331 GL_LINEAR_MIPMAP_NEAREST,
332 GL_LINEAR_MIPMAP_LINEAR};
333
334 m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
335 expectError(GL_NO_ERROR);
336
337 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(minValues); ++ndx)
338 {
339 glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, minValues[ndx]);
340 expectError(GL_NO_ERROR);
341
342 m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MIN_FILTER, minValues[ndx]);
343 expectError(GL_NO_ERROR);
344 }
345
346 //check unit conversions with float
347
348 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(minValues); ++ndx)
349 {
350 glTexParameterf(m_textureTarget, GL_TEXTURE_MIN_FILTER, (GLfloat)minValues[ndx]);
351 expectError(GL_NO_ERROR);
352
353 m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MIN_FILTER, minValues[ndx]);
354 expectError(GL_NO_ERROR);
355 }
356 }
357 };
358
359 } // namespace
360
361 #define FOR_EACH_VERIFIER(VERIFIERS, CODE_BLOCK) \
362 do \
363 { \
364 for (int _verifierNdx = 0; _verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); _verifierNdx++) \
365 { \
366 TexParamVerifier *verifier = (VERIFIERS)[_verifierNdx]; \
367 CODE_BLOCK; \
368 } \
369 } while (0)
370
TextureStateQueryTests(Context & context)371 TextureStateQueryTests::TextureStateQueryTests(Context &context)
372 : TestCaseGroup(context, "texture", "Texture State Query tests")
373 , m_verifierInt(DE_NULL)
374 , m_verifierFloat(DE_NULL)
375 {
376 }
377
~TextureStateQueryTests(void)378 TextureStateQueryTests::~TextureStateQueryTests(void)
379 {
380 deinit();
381 }
382
init(void)383 void TextureStateQueryTests::init(void)
384 {
385 using namespace TextureParamVerifiers;
386
387 DE_ASSERT(m_verifierInt == DE_NULL);
388 DE_ASSERT(m_verifierFloat == DE_NULL);
389
390 m_verifierInt =
391 new GetTexParameterIVerifier(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
392 m_verifierFloat =
393 new GetTexParameterFVerifier(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
394
395 TexParamVerifier *verifiers[] = {m_verifierInt, m_verifierFloat};
396
397 const struct
398 {
399 const char *name;
400 GLenum textureTarget;
401 } textureTargets[] = {{"texture_2d", GL_TEXTURE_2D}, {"texture_cube_map", GL_TEXTURE_CUBE_MAP}};
402
403 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureTargets); ++ndx)
404 {
405 FOR_EACH_VERIFIER(
406 verifiers,
407 addChild(new TextureWrapCase(
408 m_context, verifier,
409 (std::string(textureTargets[ndx].name) + "_texture_wrap_s" + verifier->getTestNamePostfix()).c_str(),
410 "TEXTURE_WRAP_S", textureTargets[ndx].textureTarget, GL_TEXTURE_WRAP_S)));
411 FOR_EACH_VERIFIER(
412 verifiers,
413 addChild(new TextureWrapCase(
414 m_context, verifier,
415 (std::string(textureTargets[ndx].name) + "_texture_wrap_t" + verifier->getTestNamePostfix()).c_str(),
416 "TEXTURE_WRAP_T", textureTargets[ndx].textureTarget, GL_TEXTURE_WRAP_T)));
417
418 FOR_EACH_VERIFIER(verifiers,
419 addChild(new TextureMagFilterCase(m_context, verifier,
420 (std::string(textureTargets[ndx].name) +
421 "_texture_mag_filter" + verifier->getTestNamePostfix())
422 .c_str(),
423 "TEXTURE_MAG_FILTER", textureTargets[ndx].textureTarget)));
424 FOR_EACH_VERIFIER(verifiers,
425 addChild(new TextureMinFilterCase(m_context, verifier,
426 (std::string(textureTargets[ndx].name) +
427 "_texture_min_filter" + verifier->getTestNamePostfix())
428 .c_str(),
429 "TEXTURE_MIN_FILTER", textureTargets[ndx].textureTarget)));
430 }
431 }
432
deinit(void)433 void TextureStateQueryTests::deinit(void)
434 {
435 if (m_verifierInt)
436 {
437 delete m_verifierInt;
438 m_verifierInt = NULL;
439 }
440 if (m_verifierFloat)
441 {
442 delete m_verifierFloat;
443 m_verifierFloat = NULL;
444 }
445
446 this->TestCaseGroup::deinit();
447 }
448
449 } // namespace Functional
450 } // namespace gles2
451 } // namespace deqp
452