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 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 68 StateVerifier::~StateVerifier () 69 { 70 } 71 72 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 86 GetBooleanVerifier::GetBooleanVerifier (const glw::Functions& gl, tcu::TestLog& log) 87 : StateVerifier(gl, log, "_getboolean") 88 { 89 } 90 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 130 GetIntegerVerifier::GetIntegerVerifier (const glw::Functions& gl, tcu::TestLog& log) 131 : StateVerifier(gl, log, "_getinteger") 132 { 133 } 134 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 166 GetFloatVerifier::GetFloatVerifier (const glw::Functions& gl, tcu::TestLog& log) 167 : StateVerifier(gl, log, "_getfloat") 168 { 169 } 170 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: 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 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: 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 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 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 274 Integer64StateQueryTests::~Integer64StateQueryTests (void) 275 { 276 deinit(); 277 } 278 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 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