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