/*------------------------------------------------------------------------- * 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 <algorithm> using std::set; using std::vector; using std::string; 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, deUint32 bufferTarget, deUint32 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(); deUint32 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); deUint32 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 deUint8*)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: deUint32 m_bufferTarget; deUint32 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, deUint32 bufferTarget, deUint32 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) { deUint32 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); deUint32 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((deUint8*)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: deUint32 m_bufferTarget; deUint32 m_usage; int m_size; VerifyType m_verify; }; class BufferPartialMapWriteCase : public BufferCase { public: BufferPartialMapWriteCase (Context& context, const char* name, const char* desc, deUint32 bufferTarget, deUint32 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) { deUint32 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); deUint32 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: deUint32 m_bufferTarget; deUint32 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, deUint32 bufferTarget, deUint32 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) { deUint32 dataSeed = deStringHash(getName()); deUint32 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((deUint8*)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: deUint32 m_bufferTarget; deUint32 m_usage; bool m_partialWrite; VerifyType m_verify; }; class BufferMapPartialInvalidateCase : public BufferCase { public: BufferMapPartialInvalidateCase (Context& context, const char* name, const char* desc, deUint32 bufferTarget, deUint32 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) { deUint32 dataSeed = deStringHash(getName()); deUint32 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((deUint8*)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: deUint32 m_bufferTarget; deUint32 m_usage; bool m_partialWrite; VerifyType m_verify; }; class BufferMapExplicitFlushCase : public BufferCase { public: BufferMapExplicitFlushCase (Context& context, const char* name, const char* desc, deUint32 bufferTarget, deUint32 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) { deUint32 dataSeed = deStringHash(getName()); deUint32 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: deUint32 m_bufferTarget; deUint32 m_usage; bool m_partialWrite; VerifyType m_verify; }; class BufferMapUnsyncWriteCase : public BufferCase { public: BufferMapUnsyncWriteCase (Context& context, const char* name, const char* desc, deUint32 bufferTarget, deUint32 usage) : BufferCase (context.getTestContext(), context.getRenderContext(), name, desc) , m_bufferTarget (bufferTarget) , m_usage (usage) { } IterateResult iterate (void) { VertexArrayVerifier verifier (m_renderCtx, m_testCtx.getLog()); deUint32 dataSeed = deStringHash(getName()); ReferenceBuffer refBuf; deUint32 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: deUint32 m_bufferTarget; deUint32 m_usage; }; class BufferMapReadWriteCase : public BufferCase { public: BufferMapReadWriteCase (Context& context, const char* name, const char* desc, deUint32 bufferTarget, deUint32 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(); deUint32 dataSeed = deStringHash(getName()); deUint32 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 deUint8*)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: deUint32 m_bufferTarget; deUint32 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 deUint32 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 deUint32 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++) { deUint32 target = bufferTargets[targetNdx]; const deUint32 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++) { deUint32 target = bufferTargets[targetNdx]; deUint32 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++) { deUint32 target = bufferTargets[targetNdx]; deUint32 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++) { deUint32 target = bufferTargets[targetNdx]; deUint32 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++) { deUint32 target = bufferTargets[targetNdx]; deUint32 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++) { deUint32 target = bufferTargets[targetNdx]; deUint32 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++) { deUint32 target = bufferTargets[targetNdx]; deUint32 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++) { deUint32 target = bufferTargets[targetNdx]; deUint32 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++) { deUint32 target = bufferTargets[targetNdx]; deUint32 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++) { deUint32 target = bufferTargets[targetNdx]; deUint32 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)); } } } } } } // Functional } // gles3 } // deqp