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 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 } 69 TexParamVerifier::~TexParamVerifier () 70 { 71 } 72 73 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 87 GetTexParameterIVerifier::GetTexParameterIVerifier (const glw::Functions& gl, tcu::TestLog& log) 88 : TexParamVerifier(gl, log, "_gettexparameteri") 89 { 90 } 91 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 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 142 GetTexParameterFVerifier::GetTexParameterFVerifier (const glw::Functions& gl, tcu::TestLog& log) 143 : TexParamVerifier(gl, log, "_gettexparameterf") 144 { 145 } 146 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 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: 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 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: 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 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: 272 TextureMagFilterCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget) 273 : TextureCase(context, verifier, name, description, textureTarget) 274 { 275 } 276 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: 309 TextureMinFilterCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget) 310 : TextureCase(context, verifier, name, description, textureTarget) 311 { 312 } 313 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 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 359 TextureStateQueryTests::~TextureStateQueryTests (void) 360 { 361 deinit(); 362 } 363 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 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