/*-------------------------------------------------------------------------
* 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