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 35using namespace glw; // GLint and other GL types 36using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard; 37 38 39namespace deqp 40{ 41namespace gles3 42{ 43namespace Functional 44{ 45namespace BufferParamVerifiers 46{ 47 48void 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 60void 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 72class BufferParamVerifier : protected glu::CallLogWrapper 73{ 74public: 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; 82private: 83 const char* const m_testNamePostfix; 84}; 85 86BufferParamVerifier::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 93BufferParamVerifier::~BufferParamVerifier () 94{ 95} 96 97const char* BufferParamVerifier::getTestNamePostfix (void) const 98{ 99 return m_testNamePostfix; 100} 101 102class GetBufferParameterIVerifier : public BufferParamVerifier 103{ 104public: 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 111GetBufferParameterIVerifier::GetBufferParameterIVerifier (const glw::Functions& gl, tcu::TestLog& log) 112 : BufferParamVerifier(gl, log, "_getbufferparameteri") 113{ 114} 115 116void 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 135void 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 158class GetBufferParameterI64Verifier : public BufferParamVerifier 159{ 160public: 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 167GetBufferParameterI64Verifier::GetBufferParameterI64Verifier (const glw::Functions& gl, tcu::TestLog& log) 168 : BufferParamVerifier(gl, log, "_getbufferparameteri64") 169{ 170} 171 172void 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 191void 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 213namespace 214{ 215 216using namespace BufferParamVerifiers; 217 218// Tests 219 220class BufferCase : public ApiCase 221{ 222public: 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 263protected: 264 GLenum m_bufferTarget; 265 BufferParamVerifier* m_verifier; 266 bool m_testAllTargets; 267}; 268 269class BufferSizeCase : public BufferCase 270{ 271public: 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 297class BufferUsageCase : public BufferCase 298{ 299public: 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 329class BufferAccessFlagsCase : public BufferCase 330{ 331public: 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 382class BufferMappedCase : public BufferCase 383{ 384public: 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 406class BufferOffsetLengthCase : public BufferCase 407{ 408public: 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 448class BufferPointerCase : public ApiCase 449{ 450public: 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 491BufferObjectQueryTests::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 498BufferObjectQueryTests::~BufferObjectQueryTests (void) 499{ 500 deinit(); 501} 502 503void 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 523void 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