/*------------------------------------------------------------------------- * drawElements Quality Program OpenGL ES 3.0 Module * ------------------------------------------------- * * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Buffer map tests. *//*--------------------------------------------------------------------*/ #include "es3fBufferMapTests.hpp" #include "glsBufferTestUtil.hpp" #include "tcuTestLog.hpp" #include "deMemory.h" #include "deString.h" #include "glwEnums.hpp" #include "glwFunctions.hpp" #include using std::set; using std::string; using std::vector; using tcu::TestLog; namespace deqp { namespace gles3 { namespace Functional { using namespace gls::BufferTestUtil; // Test cases. class BufferMapReadCase : public BufferCase { public: BufferMapReadCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget, uint32_t usage, int bufferSize, int mapOffset, int mapSize, WriteType write) : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc) , m_bufferTarget(bufferTarget) , m_usage(usage) , m_bufferSize(bufferSize) , m_mapOffset(mapOffset) , m_mapSize(mapSize) , m_write(write) { } IterateResult iterate(void) { TestLog &log = m_testCtx.getLog(); uint32_t dataSeed = deStringHash(getName()); ReferenceBuffer refBuf; BufferWriter writer(m_renderCtx, m_testCtx.getLog(), m_write); bool isOk = false; // Setup reference data. refBuf.setSize(m_bufferSize); fillWithRandomBytes(refBuf.getPtr(), m_bufferSize, dataSeed); uint32_t buf = genBuffer(); glBindBuffer(m_bufferTarget, buf); glBufferData(m_bufferTarget, m_bufferSize, DE_NULL, m_usage); writer.write(buf, 0, m_bufferSize, refBuf.getPtr(), m_bufferTarget); glBindBuffer(m_bufferTarget, buf); void *ptr = glMapBufferRange(m_bufferTarget, m_mapOffset, m_mapSize, GL_MAP_READ_BIT); GLU_CHECK_MSG("glMapBufferRange"); TCU_CHECK(ptr); isOk = compareByteArrays(log, (const uint8_t *)ptr, refBuf.getPtr(m_mapOffset), m_mapSize); glUnmapBuffer(m_bufferTarget); GLU_CHECK_MSG("glUnmapBuffer"); deleteBuffer(buf); m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Buffer verification failed"); return STOP; } private: uint32_t m_bufferTarget; uint32_t m_usage; int m_bufferSize; int m_mapOffset; int m_mapSize; WriteType m_write; }; class BufferMapWriteCase : public BufferCase { public: BufferMapWriteCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget, uint32_t usage, int size, VerifyType verify) : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc) , m_bufferTarget(bufferTarget) , m_usage(usage) , m_size(size) , m_verify(verify) { } IterateResult iterate(void) { uint32_t dataSeed = deStringHash(getName()); ReferenceBuffer refBuf; BufferVerifier verifier(m_renderCtx, m_testCtx.getLog(), m_verify); // Setup reference data. refBuf.setSize(m_size); fillWithRandomBytes(refBuf.getPtr(), m_size, dataSeed); uint32_t buf = genBuffer(); glBindBuffer(m_bufferTarget, buf); glBufferData(m_bufferTarget, m_size, DE_NULL, m_usage); void *ptr = glMapBufferRange(m_bufferTarget, 0, m_size, GL_MAP_WRITE_BIT); GLU_CHECK_MSG("glMapBufferRange"); TCU_CHECK(ptr); fillWithRandomBytes((uint8_t *)ptr, m_size, dataSeed); glUnmapBuffer(m_bufferTarget); GLU_CHECK_MSG("glUnmapBuffer"); bool isOk = verifier.verify(buf, refBuf.getPtr(), 0, m_size, m_bufferTarget); deleteBuffer(buf); m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Buffer verification failed"); return STOP; } private: uint32_t m_bufferTarget; uint32_t m_usage; int m_size; VerifyType m_verify; }; class BufferPartialMapWriteCase : public BufferCase { public: BufferPartialMapWriteCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget, uint32_t usage, int bufferSize, int mapOffset, int mapSize, VerifyType verify) : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc) , m_bufferTarget(bufferTarget) , m_usage(usage) , m_bufferSize(bufferSize) , m_mapOffset(mapOffset) , m_mapSize(mapSize) , m_verify(verify) { } IterateResult iterate(void) { uint32_t dataSeed = deStringHash(getName()); ReferenceBuffer refBuf; BufferVerifier verifier(m_renderCtx, m_testCtx.getLog(), m_verify); // Setup reference data. refBuf.setSize(m_bufferSize); fillWithRandomBytes(refBuf.getPtr(), m_bufferSize, dataSeed); uint32_t buf = genBuffer(); glBindBuffer(m_bufferTarget, buf); glBufferData(m_bufferTarget, m_bufferSize, refBuf.getPtr(), m_usage); // Do reference map. fillWithRandomBytes(refBuf.getPtr(m_mapOffset), m_mapSize, dataSeed & 0xabcdef); void *ptr = glMapBufferRange(m_bufferTarget, m_mapOffset, m_mapSize, GL_MAP_WRITE_BIT); GLU_CHECK_MSG("glMapBufferRange"); TCU_CHECK(ptr); deMemcpy(ptr, refBuf.getPtr(m_mapOffset), m_mapSize); glUnmapBuffer(m_bufferTarget); GLU_CHECK_MSG("glUnmapBuffer"); bool isOk = verifier.verify(buf, refBuf.getPtr(), 0, m_bufferSize, m_bufferTarget); deleteBuffer(buf); m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Buffer verification failed"); return STOP; } private: uint32_t m_bufferTarget; uint32_t m_usage; int m_bufferSize; int m_mapOffset; int m_mapSize; VerifyType m_verify; }; class BufferMapInvalidateCase : public BufferCase { public: BufferMapInvalidateCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget, uint32_t usage, bool partialWrite, VerifyType verify) : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc) , m_bufferTarget(bufferTarget) , m_usage(usage) , m_partialWrite(partialWrite) , m_verify(verify) { } IterateResult iterate(void) { uint32_t dataSeed = deStringHash(getName()); uint32_t buf = 0; ReferenceBuffer refBuf; BufferVerifier verifier(m_renderCtx, m_testCtx.getLog(), m_verify); const int bufferSize = 1300; const int mapOffset = 200; const int mapSize = 1011; const int mapWriteOffs = m_partialWrite ? 91 : 0; const int verifyOffset = mapOffset + mapWriteOffs; const int verifySize = mapSize - mapWriteOffs; // Setup reference data. refBuf.setSize(bufferSize); fillWithRandomBytes(refBuf.getPtr(), bufferSize, dataSeed); buf = genBuffer(); glBindBuffer(m_bufferTarget, buf); glBufferData(m_bufferTarget, bufferSize, refBuf.getPtr(), m_usage); // Do reference map. fillWithRandomBytes(refBuf.getPtr(mapOffset + mapWriteOffs), mapSize - mapWriteOffs, dataSeed & 0xabcdef); void *ptr = glMapBufferRange(m_bufferTarget, mapOffset, mapSize, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); GLU_CHECK_MSG("glMapBufferRange"); TCU_CHECK(ptr); deMemcpy((uint8_t *)ptr + mapWriteOffs, refBuf.getPtr(mapOffset + mapWriteOffs), mapSize - mapWriteOffs); glUnmapBuffer(m_bufferTarget); GLU_CHECK_MSG("glUnmapBuffer"); bool isOk = verifier.verify(buf, refBuf.getPtr(), verifyOffset, verifySize, m_bufferTarget); deleteBuffer(buf); m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Buffer verification failed"); return STOP; } private: uint32_t m_bufferTarget; uint32_t m_usage; bool m_partialWrite; VerifyType m_verify; }; class BufferMapPartialInvalidateCase : public BufferCase { public: BufferMapPartialInvalidateCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget, uint32_t usage, bool partialWrite, VerifyType verify) : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc) , m_bufferTarget(bufferTarget) , m_usage(usage) , m_partialWrite(partialWrite) , m_verify(verify) { } IterateResult iterate(void) { uint32_t dataSeed = deStringHash(getName()); uint32_t buf = 0; ReferenceBuffer refBuf; BufferVerifier verifier(m_renderCtx, m_testCtx.getLog(), m_verify); const int bufferSize = 1300; const int mapOffset = 200; const int mapSize = 1011; const int mapWriteOffs = m_partialWrite ? 91 : 0; const int verifyOffset = m_partialWrite ? mapOffset + mapWriteOffs : 0; const int verifySize = bufferSize - verifyOffset; // Setup reference data. refBuf.setSize(bufferSize); fillWithRandomBytes(refBuf.getPtr(), bufferSize, dataSeed); buf = genBuffer(); glBindBuffer(m_bufferTarget, buf); glBufferData(m_bufferTarget, bufferSize, refBuf.getPtr(), m_usage); // Do reference map. fillWithRandomBytes(refBuf.getPtr(mapOffset + mapWriteOffs), mapSize - mapWriteOffs, dataSeed & 0xabcdef); void *ptr = glMapBufferRange(m_bufferTarget, mapOffset, mapSize, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT); GLU_CHECK_MSG("glMapBufferRange"); TCU_CHECK(ptr); deMemcpy((uint8_t *)ptr + mapWriteOffs, refBuf.getPtr(mapOffset + mapWriteOffs), mapSize - mapWriteOffs); glUnmapBuffer(m_bufferTarget); GLU_CHECK_MSG("glUnmapBuffer"); bool isOk = verifier.verify(buf, refBuf.getPtr(), verifyOffset, verifySize, m_bufferTarget); deleteBuffer(buf); m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Buffer verification failed"); return STOP; } private: uint32_t m_bufferTarget; uint32_t m_usage; bool m_partialWrite; VerifyType m_verify; }; class BufferMapExplicitFlushCase : public BufferCase { public: BufferMapExplicitFlushCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget, uint32_t usage, bool partialWrite, VerifyType verify) : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc) , m_bufferTarget(bufferTarget) , m_usage(usage) , m_partialWrite(partialWrite) , m_verify(verify) { } IterateResult iterate(void) { uint32_t dataSeed = deStringHash(getName()); uint32_t buf = 0; ReferenceBuffer refBuf; BufferVerifier verifier(m_renderCtx, m_testCtx.getLog(), m_verify); const int bufferSize = 1300; const int mapOffset = 200; const int mapSize = 1011; const int sliceAOffs = m_partialWrite ? 1 : 0; const int sliceASize = m_partialWrite ? 96 : 473; const int sliceBOffs = m_partialWrite ? 503 : sliceAOffs + sliceASize; const int sliceBSize = mapSize - sliceBOffs; bool isOk = true; // Setup reference data. refBuf.setSize(bufferSize); fillWithRandomBytes(refBuf.getPtr(), bufferSize, dataSeed); buf = genBuffer(); glBindBuffer(m_bufferTarget, buf); glBufferData(m_bufferTarget, bufferSize, refBuf.getPtr(), m_usage); // Do reference map. fillWithRandomBytes(refBuf.getPtr(mapOffset), mapSize, dataSeed & 0xabcdef); void *ptr = glMapBufferRange(m_bufferTarget, mapOffset, mapSize, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); GLU_CHECK_MSG("glMapBufferRange"); TCU_CHECK(ptr); deMemcpy(ptr, refBuf.getPtr(mapOffset), mapSize); glFlushMappedBufferRange(m_bufferTarget, sliceAOffs, sliceASize); GLU_CHECK_MSG("glFlushMappedBufferRange"); glFlushMappedBufferRange(m_bufferTarget, sliceBOffs, sliceBSize); GLU_CHECK_MSG("glFlushMappedBufferRange"); glUnmapBuffer(m_bufferTarget); GLU_CHECK_MSG("glUnmapBuffer"); if (m_partialWrite) { if (!verifier.verify(buf, refBuf.getPtr(), mapOffset + sliceAOffs, sliceASize, m_bufferTarget)) isOk = false; if (!verifier.verify(buf, refBuf.getPtr(), mapOffset + sliceBOffs, sliceBSize, m_bufferTarget)) isOk = false; } else { if (!verifier.verify(buf, refBuf.getPtr(), mapOffset, mapSize, m_bufferTarget)) isOk = false; } deleteBuffer(buf); m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Buffer verification failed"); return STOP; } private: uint32_t m_bufferTarget; uint32_t m_usage; bool m_partialWrite; VerifyType m_verify; }; class BufferMapUnsyncWriteCase : public BufferCase { public: BufferMapUnsyncWriteCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget, uint32_t usage) : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc) , m_bufferTarget(bufferTarget) , m_usage(usage) { } IterateResult iterate(void) { VertexArrayVerifier verifier(m_renderCtx, m_testCtx.getLog()); uint32_t dataSeed = deStringHash(getName()); ReferenceBuffer refBuf; uint32_t buf = 0; bool isOk = true; const int size = 1200; // Setup reference data. refBuf.setSize(size); fillWithRandomBytes(refBuf.getPtr(), size, dataSeed); buf = genBuffer(); glBindBuffer(m_bufferTarget, buf); glBufferData(m_bufferTarget, size, refBuf.getPtr(), m_usage); // Use for rendering. if (!verifier.verify(buf, refBuf.getPtr(), 0, size)) isOk = false; // \note ReadPixels() implies Finish glBindBuffer(m_bufferTarget, buf); void *ptr = glMapBufferRange(m_bufferTarget, 0, size, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); GLU_CHECK_MSG("glMapBufferRange"); TCU_CHECK(ptr); fillWithRandomBytes(refBuf.getPtr(), size, dataSeed & 0xabcdef); deMemcpy(ptr, refBuf.getPtr(), size); glUnmapBuffer(m_bufferTarget); GLU_CHECK_MSG("glUnmapBuffer"); // Synchronize. glFinish(); if (!verifier.verify(buf, refBuf.getPtr(), 0, size)) isOk = false; deleteBuffer(buf); m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Buffer verification failed"); return STOP; } private: uint32_t m_bufferTarget; uint32_t m_usage; }; class BufferMapReadWriteCase : public BufferCase { public: BufferMapReadWriteCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget, uint32_t usage, int bufferSize, int mapOffset, int mapSize, VerifyType verify) : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc) , m_bufferTarget(bufferTarget) , m_usage(usage) , m_bufferSize(bufferSize) , m_mapOffset(mapOffset) , m_mapSize(mapSize) , m_verify(verify) { } IterateResult iterate(void) { TestLog &log = m_testCtx.getLog(); uint32_t dataSeed = deStringHash(getName()); uint32_t buf = 0; ReferenceBuffer refBuf; BufferVerifier verifier(m_renderCtx, m_testCtx.getLog(), m_verify); bool isOk = true; // Setup reference data. refBuf.setSize(m_bufferSize); fillWithRandomBytes(refBuf.getPtr(), m_bufferSize, dataSeed); buf = genBuffer(); glBindBuffer(m_bufferTarget, buf); glBufferData(m_bufferTarget, m_bufferSize, refBuf.getPtr(), m_usage); // Verify before mapping. if (!verifier.verify(buf, refBuf.getPtr(), 0, m_bufferSize, m_bufferTarget)) isOk = false; glBindBuffer(m_bufferTarget, buf); void *ptr = glMapBufferRange(m_bufferTarget, m_mapOffset, m_mapSize, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT); GLU_CHECK_MSG("glMapBufferRange"); TCU_CHECK(ptr); // Compare mapped ptr. if (!compareByteArrays(log, (const uint8_t *)ptr, refBuf.getPtr(m_mapOffset), m_mapSize)) isOk = false; fillWithRandomBytes(refBuf.getPtr(m_mapOffset), m_mapSize, dataSeed & 0xabcdef); deMemcpy(ptr, refBuf.getPtr(m_mapOffset), m_mapSize); glUnmapBuffer(m_bufferTarget); GLU_CHECK_MSG("glUnmapBuffer"); // Compare final buffer. if (!verifier.verify(buf, refBuf.getPtr(), 0, m_bufferSize, m_bufferTarget)) isOk = false; deleteBuffer(buf); m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Buffer verification failed"); return STOP; } private: uint32_t m_bufferTarget; uint32_t m_usage; int m_bufferSize; int m_mapOffset; int m_mapSize; VerifyType m_verify; }; BufferMapTests::BufferMapTests(Context &context) : TestCaseGroup(context, "map", "Buffer map tests") { } BufferMapTests::~BufferMapTests(void) { } void BufferMapTests::init(void) { static const uint32_t bufferTargets[] = { GL_ARRAY_BUFFER, GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER, GL_UNIFORM_BUFFER}; static const uint32_t usageHints[] = {GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, GL_DYNAMIC_COPY}; static const struct { const char *name; WriteType write; } bufferDataSources[] = {{"sub_data", WRITE_BUFFER_SUB_DATA}, {"map_write", WRITE_BUFFER_WRITE_MAP}}; static const struct { const char *name; VerifyType verify; } bufferUses[] = {{"map_read", VERIFY_BUFFER_READ_MAP}, {"render_as_vertex_array", VERIFY_AS_VERTEX_ARRAY}, {"render_as_index_array", VERIFY_AS_INDEX_ARRAY}}; // .read { tcu::TestCaseGroup *mapReadGroup = new tcu::TestCaseGroup(m_testCtx, "read", "Buffer read using glMapBufferRange()"); addChild(mapReadGroup); // .[data src] for (int srcNdx = 0; srcNdx < DE_LENGTH_OF_ARRAY(bufferDataSources); srcNdx++) { WriteType write = bufferDataSources[srcNdx].write; tcu::TestCaseGroup *writeGroup = new tcu::TestCaseGroup(m_testCtx, bufferDataSources[srcNdx].name, ""); mapReadGroup->addChild(writeGroup); for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++) { uint32_t target = bufferTargets[targetNdx]; const uint32_t hint = GL_STATIC_READ; const int size = 1019; const int partialOffs = 17; const int partialSize = 501; writeGroup->addChild(new BufferMapReadCase(m_context, (string(getBufferTargetName(target)) + "_full").c_str(), "", target, hint, size, 0, size, write)); writeGroup->addChild(new BufferMapReadCase(m_context, (string(getBufferTargetName(target)) + "_partial").c_str(), "", target, hint, size, partialOffs, partialSize, write)); } } // .usage_hints { tcu::TestCaseGroup *hintsGroup = new tcu::TestCaseGroup(m_testCtx, "usage_hints", "Different usage hints with glMapBufferRange()"); mapReadGroup->addChild(hintsGroup); for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++) { for (int hintNdx = 0; hintNdx < DE_LENGTH_OF_ARRAY(usageHints); hintNdx++) { uint32_t target = bufferTargets[targetNdx]; uint32_t hint = usageHints[hintNdx]; const int size = 1019; string name = string(getBufferTargetName(target)) + "_" + getUsageHintName(hint); hintsGroup->addChild(new BufferMapReadCase(m_context, name.c_str(), "", target, hint, size, 0, size, WRITE_BUFFER_SUB_DATA)); } } } } // .write { tcu::TestCaseGroup *mapWriteGroup = new tcu::TestCaseGroup(m_testCtx, "write", "Buffer write using glMapBufferRange()"); addChild(mapWriteGroup); // .[verify type] for (int useNdx = 0; useNdx < DE_LENGTH_OF_ARRAY(bufferUses); useNdx++) { VerifyType verify = bufferUses[useNdx].verify; tcu::TestCaseGroup *useGroup = new tcu::TestCaseGroup(m_testCtx, bufferUses[useNdx].name, ""); mapWriteGroup->addChild(useGroup); for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++) { uint32_t target = bufferTargets[targetNdx]; uint32_t hint = GL_STATIC_DRAW; const int size = 1019; const int partialOffs = 17; const int partialSize = 501; string name = string(getBufferTargetName(target)) + "_" + getUsageHintName(hint); useGroup->addChild(new BufferMapWriteCase(m_context, (string(getBufferTargetName(target)) + "_full").c_str(), "", target, hint, size, verify)); useGroup->addChild( new BufferPartialMapWriteCase(m_context, (string(getBufferTargetName(target)) + "_partial").c_str(), "", target, hint, size, partialOffs, partialSize, verify)); } } // .usage_hints { tcu::TestCaseGroup *hintsGroup = new tcu::TestCaseGroup(m_testCtx, "usage_hints", "Usage hints"); mapWriteGroup->addChild(hintsGroup); for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++) { for (int hintNdx = 0; hintNdx < DE_LENGTH_OF_ARRAY(usageHints); hintNdx++) { uint32_t target = bufferTargets[targetNdx]; uint32_t hint = usageHints[hintNdx]; const int size = 1019; string name = string(getBufferTargetName(target)) + "_" + getUsageHintName(hint); hintsGroup->addChild(new BufferMapWriteCase(m_context, name.c_str(), "", target, hint, size, VERIFY_AS_VERTEX_ARRAY)); } } } // .invalidate { tcu::TestCaseGroup *invalidateGroup = new tcu::TestCaseGroup(m_testCtx, "invalidate", "Buffer invalidate"); mapWriteGroup->addChild(invalidateGroup); for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++) { uint32_t target = bufferTargets[targetNdx]; uint32_t hint = GL_STATIC_DRAW; invalidateGroup->addChild( new BufferMapInvalidateCase(m_context, (string(getBufferTargetName(target)) + "_write_all").c_str(), "", target, hint, false, VERIFY_AS_VERTEX_ARRAY)); invalidateGroup->addChild(new BufferMapInvalidateCase( m_context, (string(getBufferTargetName(target)) + "_write_partial").c_str(), "", target, hint, true, VERIFY_AS_VERTEX_ARRAY)); } } // .partial_invalidate { tcu::TestCaseGroup *invalidateGroup = new tcu::TestCaseGroup(m_testCtx, "partial_invalidate", "Partial invalidate"); mapWriteGroup->addChild(invalidateGroup); for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++) { uint32_t target = bufferTargets[targetNdx]; uint32_t hint = GL_STATIC_DRAW; invalidateGroup->addChild(new BufferMapPartialInvalidateCase( m_context, (string(getBufferTargetName(target)) + "_write_all").c_str(), "", target, hint, false, VERIFY_AS_VERTEX_ARRAY)); invalidateGroup->addChild(new BufferMapPartialInvalidateCase( m_context, (string(getBufferTargetName(target)) + "_write_partial").c_str(), "", target, hint, true, VERIFY_AS_VERTEX_ARRAY)); } } // .explicit_flush { tcu::TestCaseGroup *flushGroup = new tcu::TestCaseGroup(m_testCtx, "explicit_flush", "Explicit flush"); mapWriteGroup->addChild(flushGroup); for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++) { uint32_t target = bufferTargets[targetNdx]; uint32_t hint = GL_STATIC_DRAW; flushGroup->addChild( new BufferMapExplicitFlushCase(m_context, (string(getBufferTargetName(target)) + "_all").c_str(), "", target, hint, false, VERIFY_AS_VERTEX_ARRAY)); flushGroup->addChild(new BufferMapExplicitFlushCase( m_context, (string(getBufferTargetName(target)) + "_partial").c_str(), "", target, hint, true, VERIFY_AS_VERTEX_ARRAY)); } } // .unsynchronized { tcu::TestCaseGroup *unsyncGroup = new tcu::TestCaseGroup(m_testCtx, "unsynchronized", "Unsynchronized map"); mapWriteGroup->addChild(unsyncGroup); for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++) { uint32_t target = bufferTargets[targetNdx]; uint32_t hint = GL_STATIC_DRAW; unsyncGroup->addChild( new BufferMapUnsyncWriteCase(m_context, getBufferTargetName(target), "", target, hint)); } } } // .read_write { tcu::TestCaseGroup *mapReadWriteGroup = new tcu::TestCaseGroup(m_testCtx, "read_write", "Buffer read and write using glMapBufferRange()"); addChild(mapReadWriteGroup); // .[verify type] for (int useNdx = 0; useNdx < DE_LENGTH_OF_ARRAY(bufferUses); useNdx++) { VerifyType verify = bufferUses[useNdx].verify; tcu::TestCaseGroup *useGroup = new tcu::TestCaseGroup(m_testCtx, bufferUses[useNdx].name, ""); mapReadWriteGroup->addChild(useGroup); for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++) { uint32_t target = bufferTargets[targetNdx]; uint32_t hint = GL_STATIC_DRAW; const int size = 1019; const int partialOffs = 17; const int partialSize = 501; string name = string(getBufferTargetName(target)) + "_" + getUsageHintName(hint); useGroup->addChild(new BufferMapReadWriteCase(m_context, (string(getBufferTargetName(target)) + "_full").c_str(), "", target, hint, size, 0, size, verify)); useGroup->addChild( new BufferMapReadWriteCase(m_context, (string(getBufferTargetName(target)) + "_partial").c_str(), "", target, hint, size, partialOffs, partialSize, verify)); } } // .usage_hints { tcu::TestCaseGroup *hintsGroup = new tcu::TestCaseGroup(m_testCtx, "usage_hints", "Usage hints"); mapReadWriteGroup->addChild(hintsGroup); for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++) { for (int hintNdx = 0; hintNdx < DE_LENGTH_OF_ARRAY(usageHints); hintNdx++) { uint32_t target = bufferTargets[targetNdx]; uint32_t hint = usageHints[hintNdx]; const int size = 1019; string name = string(getBufferTargetName(target)) + "_" + getUsageHintName(hint); hintsGroup->addChild(new BufferMapReadWriteCase(m_context, name.c_str(), "", target, hint, size, 0, size, VERIFY_AS_VERTEX_ARRAY)); } } } } } } // namespace Functional } // namespace gles3 } // namespace deqp