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 Buffer Object Query tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es3fBufferObjectQueryTests.hpp" 25 #include "glsStateQueryUtil.hpp" 26 #include "es3fApiCase.hpp" 27 #include "gluRenderContext.hpp" 28 #include "glwEnums.hpp" 29 #include "glwFunctions.hpp" 30 #include "deRandom.hpp" 31 #include "deMath.h" 32 33 #include <limits> 34 35 using namespace glw; // GLint and other GL types 36 using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard; 37 38 39 namespace deqp 40 { 41 namespace gles3 42 { 43 namespace Functional 44 { 45 namespace BufferParamVerifiers 46 { 47 48 void checkIntEquals (tcu::TestContext& testCtx, GLint got, GLint expected) 49 { 50 using tcu::TestLog; 51 52 if (got != expected) 53 { 54 testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage; 55 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 56 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value"); 57 } 58 } 59 60 void checkPointerEquals (tcu::TestContext& testCtx, const void* got, const void* expected) 61 { 62 using tcu::TestLog; 63 64 if (got != expected) 65 { 66 testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage; 67 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 68 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value"); 69 } 70 } 71 72 class BufferParamVerifier : protected glu::CallLogWrapper 73 { 74 public: 75 BufferParamVerifier (const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix); 76 virtual ~BufferParamVerifier (); // make GCC happy 77 78 const char* getTestNamePostfix (void) const; 79 80 virtual void verifyInteger (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference) = DE_NULL; 81 virtual void verifyInteger64 (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint64 reference) = DE_NULL; 82 private: 83 const char* const m_testNamePostfix; 84 }; 85 86 BufferParamVerifier::BufferParamVerifier (const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix) 87 : glu::CallLogWrapper (gl, log) 88 , m_testNamePostfix (testNamePostfix) 89 { 90 enableLogging(true); 91 } 92 93 BufferParamVerifier::~BufferParamVerifier () 94 { 95 } 96 97 const char* BufferParamVerifier::getTestNamePostfix (void) const 98 { 99 return m_testNamePostfix; 100 } 101 102 class GetBufferParameterIVerifier : public BufferParamVerifier 103 { 104 public: 105 GetBufferParameterIVerifier (const glw::Functions& gl, tcu::TestLog& log); 106 107 void verifyInteger (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference); 108 void verifyInteger64 (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint64 reference); 109 }; 110 111 GetBufferParameterIVerifier::GetBufferParameterIVerifier (const glw::Functions& gl, tcu::TestLog& log) 112 : BufferParamVerifier(gl, log, "_getbufferparameteri") 113 { 114 } 115 116 void GetBufferParameterIVerifier::verifyInteger (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference) 117 { 118 using tcu::TestLog; 119 120 StateQueryMemoryWriteGuard<GLint> state; 121 glGetBufferParameteriv(target, name, &state); 122 123 if (!state.verifyValidity(testCtx)) 124 return; 125 126 if (state != reference) 127 { 128 testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage; 129 130 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 131 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value"); 132 } 133 } 134 135 void GetBufferParameterIVerifier::verifyInteger64 (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint64 reference) 136 { 137 using tcu::TestLog; 138 139 StateQueryMemoryWriteGuard<GLint> state; 140 glGetBufferParameteriv(target, 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 (!de::inRange(reference, (GLint64)std::numeric_limits<GLint>::min(), (GLint64)std::numeric_limits<GLint>::max())) 147 return; 148 149 if (state != reference) 150 { 151 testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage; 152 153 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 154 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value"); 155 } 156 } 157 158 class GetBufferParameterI64Verifier : public BufferParamVerifier 159 { 160 public: 161 GetBufferParameterI64Verifier (const glw::Functions& gl, tcu::TestLog& log); 162 163 void verifyInteger (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference); 164 void verifyInteger64 (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint64 reference); 165 }; 166 167 GetBufferParameterI64Verifier::GetBufferParameterI64Verifier (const glw::Functions& gl, tcu::TestLog& log) 168 : BufferParamVerifier(gl, log, "_getbufferparameteri64") 169 { 170 } 171 172 void GetBufferParameterI64Verifier::verifyInteger (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference) 173 { 174 using tcu::TestLog; 175 176 StateQueryMemoryWriteGuard<GLint64> state; 177 glGetBufferParameteri64v(target, name, &state); 178 179 if (!state.verifyValidity(testCtx)) 180 return; 181 182 if (state != reference) 183 { 184 testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage; 185 186 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 187 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value"); 188 } 189 } 190 191 void GetBufferParameterI64Verifier::verifyInteger64 (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint64 reference) 192 { 193 using tcu::TestLog; 194 195 StateQueryMemoryWriteGuard<GLint64> state; 196 glGetBufferParameteri64v(target, name, &state); 197 198 if (!state.verifyValidity(testCtx)) 199 return; 200 201 if (state != reference) 202 { 203 testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage; 204 205 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) 206 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value"); 207 } 208 } 209 210 211 } // BufferParamVerifiers 212 213 namespace 214 { 215 216 using namespace BufferParamVerifiers; 217 218 // Tests 219 220 class BufferCase : public ApiCase 221 { 222 public: 223 BufferCase (Context& context, BufferParamVerifier* verifier, const char* name, const char* description) 224 : ApiCase (context, name, description) 225 , m_bufferTarget (0) 226 , m_verifier (verifier) 227 , m_testAllTargets (false) 228 { 229 } 230 231 virtual void testBuffer (void) = DE_NULL; 232 233 void test (void) 234 { 235 const GLenum bufferTargets[] = 236 { 237 GL_ARRAY_BUFFER, GL_COPY_READ_BUFFER, 238 GL_TRANSFORM_FEEDBACK_BUFFER, GL_UNIFORM_BUFFER, 239 240 GL_COPY_WRITE_BUFFER, GL_ELEMENT_ARRAY_BUFFER, 241 GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER 242 }; 243 244 // most test need only to be run with a subset of targets 245 const int targets = m_testAllTargets ? DE_LENGTH_OF_ARRAY(bufferTargets) : 4; 246 247 for (int ndx = 0; ndx < targets; ++ndx) 248 { 249 m_bufferTarget = bufferTargets[ndx]; 250 251 GLuint bufferId = 0; 252 glGenBuffers(1, &bufferId); 253 glBindBuffer(m_bufferTarget, bufferId); 254 expectError(GL_NO_ERROR); 255 256 testBuffer(); 257 258 glDeleteBuffers(1, &bufferId); 259 expectError(GL_NO_ERROR); 260 } 261 } 262 263 protected: 264 GLenum m_bufferTarget; 265 BufferParamVerifier* m_verifier; 266 bool m_testAllTargets; 267 }; 268 269 class BufferSizeCase : public BufferCase 270 { 271 public: 272 BufferSizeCase (Context& context, BufferParamVerifier* verifier, const char* name, const char* description) 273 : BufferCase(context, verifier, name, description) 274 { 275 m_testAllTargets = true; 276 } 277 278 void testBuffer (void) 279 { 280 de::Random rnd(0xabcdef); 281 282 m_verifier->verifyInteger64(m_testCtx, m_bufferTarget, GL_BUFFER_SIZE, 0); 283 284 const int numIterations = 16; 285 for (int i = 0; i < numIterations; ++i) 286 { 287 const GLint len = rnd.getInt(0, 1024); 288 glBufferData(m_bufferTarget, len, DE_NULL, GL_STREAM_DRAW); 289 expectError(GL_NO_ERROR); 290 291 m_verifier->verifyInteger64(m_testCtx, m_bufferTarget, GL_BUFFER_SIZE, len); 292 expectError(GL_NO_ERROR); 293 } 294 } 295 }; 296 297 class BufferUsageCase : public BufferCase 298 { 299 public: 300 BufferUsageCase (Context& context, BufferParamVerifier* verifier, const char* name, const char* description) 301 : BufferCase(context, verifier, name, description) 302 { 303 } 304 305 void testBuffer (void) 306 { 307 m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_USAGE, GL_STATIC_DRAW); 308 309 const GLenum usages[] = 310 { 311 GL_STREAM_DRAW, GL_STREAM_READ, 312 GL_STREAM_COPY, GL_STATIC_DRAW, 313 GL_STATIC_READ, GL_STATIC_COPY, 314 GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, 315 GL_DYNAMIC_COPY 316 }; 317 318 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(usages); ++ndx) 319 { 320 glBufferData(m_bufferTarget, 16, DE_NULL, usages[ndx]); 321 expectError(GL_NO_ERROR); 322 323 m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_USAGE, usages[ndx]); 324 expectError(GL_NO_ERROR); 325 } 326 } 327 }; 328 329 class BufferAccessFlagsCase : public BufferCase 330 { 331 public: 332 BufferAccessFlagsCase (Context& context, BufferParamVerifier* verifier, const char* name, const char* description) 333 : BufferCase(context, verifier, name, description) 334 { 335 } 336 337 void testBuffer (void) 338 { 339 m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_ACCESS_FLAGS, 0); 340 341 const GLenum accessFlags[] = 342 { 343 GL_MAP_READ_BIT, 344 345 GL_MAP_WRITE_BIT, 346 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT, 347 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT, 348 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT, 349 350 GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT, 351 GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT, 352 GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_BUFFER_BIT, 353 GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT, 354 355 GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT, 356 GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_RANGE_BIT, 357 GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT, 358 GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT, 359 360 GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT, 361 GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT, 362 GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_BUFFER_BIT, 363 GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT, 364 365 }; 366 367 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(accessFlags); ++ndx) 368 { 369 glBufferData(m_bufferTarget, 16, DE_NULL, GL_DYNAMIC_COPY); 370 glMapBufferRange(m_bufferTarget, 0, 16, accessFlags[ndx]); 371 expectError(GL_NO_ERROR); 372 373 m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_ACCESS_FLAGS, accessFlags[ndx]); 374 expectError(GL_NO_ERROR); 375 376 glUnmapBuffer(m_bufferTarget); 377 expectError(GL_NO_ERROR); 378 } 379 } 380 }; 381 382 class BufferMappedCase : public BufferCase 383 { 384 public: 385 BufferMappedCase (Context& context, BufferParamVerifier* verifier, const char* name, const char* description) 386 : BufferCase(context, verifier, name, description) 387 { 388 } 389 390 void testBuffer (void) 391 { 392 m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_MAPPED, GL_FALSE); 393 394 glBufferData(m_bufferTarget, 16, DE_NULL, GL_DYNAMIC_COPY); 395 glMapBufferRange(m_bufferTarget, 0, 16, GL_MAP_WRITE_BIT); 396 expectError(GL_NO_ERROR); 397 398 m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_MAPPED, GL_TRUE); 399 expectError(GL_NO_ERROR); 400 401 glUnmapBuffer(m_bufferTarget); 402 expectError(GL_NO_ERROR); 403 } 404 }; 405 406 class BufferOffsetLengthCase : public BufferCase 407 { 408 public: 409 BufferOffsetLengthCase (Context& context, BufferParamVerifier* verifier, const char* name, const char* description) 410 : BufferCase(context, verifier, name, description) 411 { 412 } 413 414 void testBuffer (void) 415 { 416 m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_MAP_OFFSET, 0); 417 m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_MAP_LENGTH, 0); 418 419 glBufferData(m_bufferTarget, 16, DE_NULL, GL_DYNAMIC_COPY); 420 421 const struct BufferRange 422 { 423 int offset; 424 int length; 425 } ranges[] = 426 { 427 { 0, 16 }, 428 { 4, 12 }, 429 { 0, 12 }, 430 { 8, 8 }, 431 }; 432 433 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(ranges); ++ndx) 434 { 435 glMapBufferRange(m_bufferTarget, ranges[ndx].offset, ranges[ndx].length, GL_MAP_WRITE_BIT); 436 expectError(GL_NO_ERROR); 437 438 m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_MAP_OFFSET, ranges[ndx].offset); 439 m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_MAP_LENGTH, ranges[ndx].length); 440 expectError(GL_NO_ERROR); 441 442 glUnmapBuffer(m_bufferTarget); 443 expectError(GL_NO_ERROR); 444 } 445 } 446 }; 447 448 class BufferPointerCase : public ApiCase 449 { 450 public: 451 BufferPointerCase (Context& context, const char* name, const char* description) 452 : ApiCase(context, name, description) 453 { 454 } 455 456 void test (void) 457 { 458 GLuint bufferId = 0; 459 glGenBuffers(1, &bufferId); 460 glBindBuffer(GL_ARRAY_BUFFER, bufferId); 461 expectError(GL_NO_ERROR); 462 463 StateQueryMemoryWriteGuard<GLvoid*> initialState; 464 glGetBufferPointerv(GL_ARRAY_BUFFER, GL_BUFFER_MAP_POINTER, &initialState); 465 initialState.verifyValidity(m_testCtx); 466 checkPointerEquals(m_testCtx, initialState, 0); 467 468 glBufferData(GL_ARRAY_BUFFER, 8, DE_NULL, GL_DYNAMIC_COPY); 469 GLvoid* mapPointer = glMapBufferRange(GL_ARRAY_BUFFER, 0, 8, GL_MAP_READ_BIT); 470 expectError(GL_NO_ERROR); 471 472 StateQueryMemoryWriteGuard<GLvoid*> mapPointerState; 473 glGetBufferPointerv(GL_ARRAY_BUFFER, GL_BUFFER_MAP_POINTER, &mapPointerState); 474 mapPointerState.verifyValidity(m_testCtx); 475 checkPointerEquals(m_testCtx, mapPointerState, mapPointer); 476 477 glDeleteBuffers(1, &bufferId); 478 expectError(GL_NO_ERROR); 479 } 480 }; 481 482 } // anonymous 483 484 #define FOR_EACH_VERIFIER(VERIFIERS, CODE_BLOCK) \ 485 for (int _verifierNdx = 0; _verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); _verifierNdx++) \ 486 { \ 487 BufferParamVerifier* verifier = VERIFIERS[_verifierNdx]; \ 488 CODE_BLOCK; \ 489 } 490 491 BufferObjectQueryTests::BufferObjectQueryTests (Context& context) 492 : TestCaseGroup (context, "buffer_object", "Buffer Object Query tests") 493 , m_verifierInt (DE_NULL) 494 , m_verifierInt64 (DE_NULL) 495 { 496 } 497 498 BufferObjectQueryTests::~BufferObjectQueryTests (void) 499 { 500 deinit(); 501 } 502 503 void BufferObjectQueryTests::init (void) 504 { 505 using namespace BufferParamVerifiers; 506 507 DE_ASSERT(m_verifierInt == DE_NULL); 508 DE_ASSERT(m_verifierInt64 == DE_NULL); 509 510 m_verifierInt = new GetBufferParameterIVerifier (m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog()); 511 m_verifierInt64 = new GetBufferParameterI64Verifier (m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog()); 512 BufferParamVerifier* verifiers[] = {m_verifierInt, m_verifierInt64}; 513 514 FOR_EACH_VERIFIER(verifiers, addChild(new BufferSizeCase (m_context, verifier, (std::string("buffer_size") + verifier->getTestNamePostfix()).c_str(), "BUFFER_SIZE"))); 515 FOR_EACH_VERIFIER(verifiers, addChild(new BufferUsageCase (m_context, verifier, (std::string("buffer_usage") + verifier->getTestNamePostfix()).c_str(), "BUFFER_USAGE"))); 516 FOR_EACH_VERIFIER(verifiers, addChild(new BufferAccessFlagsCase (m_context, verifier, (std::string("buffer_access_flags") + verifier->getTestNamePostfix()).c_str(), "BUFFER_ACCESS_FLAGS"))); 517 FOR_EACH_VERIFIER(verifiers, addChild(new BufferMappedCase (m_context, verifier, (std::string("buffer_mapped") + verifier->getTestNamePostfix()).c_str(), "BUFFER_MAPPED"))); 518 FOR_EACH_VERIFIER(verifiers, addChild(new BufferOffsetLengthCase(m_context, verifier, (std::string("buffer_map_offset_length")+ verifier->getTestNamePostfix()).c_str(), "BUFFER_MAP_OFFSET and BUFFER_MAP_LENGTH"))); 519 520 addChild(new BufferPointerCase(m_context, "buffer_pointer", "GetBufferPointerv")); 521 } 522 523 void BufferObjectQueryTests::deinit (void) 524 { 525 if (m_verifierInt) 526 { 527 delete m_verifierInt; 528 m_verifierInt = NULL; 529 } 530 if (m_verifierInt64) 531 { 532 delete m_verifierInt64; 533 m_verifierInt64 = NULL; 534 } 535 } 536 537 } // Functional 538 } // gles3 539 } // deqp 540