344 lines
10 KiB
C++
344 lines
10 KiB
C++
/*-------------------------------------------------------------------------
|
|
* 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 copying tests.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "es3fBufferCopyTests.hpp"
|
|
#include "glsBufferTestUtil.hpp"
|
|
#include "tcuTestLog.hpp"
|
|
#include "deMemory.h"
|
|
#include "deString.h"
|
|
#include "glwEnums.hpp"
|
|
#include "glwFunctions.hpp"
|
|
|
|
#include <algorithm>
|
|
|
|
using std::vector;
|
|
using std::string;
|
|
using tcu::TestLog;
|
|
|
|
namespace deqp
|
|
{
|
|
namespace gles3
|
|
{
|
|
namespace Functional
|
|
{
|
|
|
|
using namespace gls::BufferTestUtil;
|
|
|
|
class BasicBufferCopyCase : public BufferCase
|
|
{
|
|
public:
|
|
BasicBufferCopyCase (Context& context,
|
|
const char* name,
|
|
const char* desc,
|
|
deUint32 srcTarget,
|
|
int srcSize,
|
|
deUint32 srcHint,
|
|
deUint32 dstTarget,
|
|
int dstSize,
|
|
deUint32 dstHint,
|
|
int copySrcOffset,
|
|
int copyDstOffset,
|
|
int copySize,
|
|
VerifyType verifyType)
|
|
: BufferCase (context.getTestContext(), context.getRenderContext(), name, desc)
|
|
, m_srcTarget (srcTarget)
|
|
, m_srcSize (srcSize)
|
|
, m_srcHint (srcHint)
|
|
, m_dstTarget (dstTarget)
|
|
, m_dstSize (dstSize)
|
|
, m_dstHint (dstHint)
|
|
, m_copySrcOffset (copySrcOffset)
|
|
, m_copyDstOffset (copyDstOffset)
|
|
, m_copySize (copySize)
|
|
, m_verifyType (verifyType)
|
|
{
|
|
DE_ASSERT(de::inBounds(m_copySrcOffset, 0, m_srcSize) && de::inRange(m_copySrcOffset+m_copySize, m_copySrcOffset, m_srcSize));
|
|
DE_ASSERT(de::inBounds(m_copyDstOffset, 0, m_dstSize) && de::inRange(m_copyDstOffset+m_copySize, m_copyDstOffset, m_dstSize));
|
|
}
|
|
|
|
IterateResult iterate (void)
|
|
{
|
|
BufferVerifier verifier (m_renderCtx, m_testCtx.getLog(), m_verifyType);
|
|
ReferenceBuffer srcRef;
|
|
ReferenceBuffer dstRef;
|
|
deUint32 srcBuf = 0;
|
|
deUint32 dstBuf = 0;
|
|
deUint32 srcSeed = deStringHash(getName()) ^ 0xabcd;
|
|
deUint32 dstSeed = deStringHash(getName()) ^ 0xef01;
|
|
bool isOk = true;
|
|
|
|
srcRef.setSize(m_srcSize);
|
|
fillWithRandomBytes(srcRef.getPtr(), m_srcSize, srcSeed);
|
|
|
|
dstRef.setSize(m_dstSize);
|
|
fillWithRandomBytes(dstRef.getPtr(), m_dstSize, dstSeed);
|
|
|
|
// Create source buffer and fill with data.
|
|
srcBuf = genBuffer();
|
|
glBindBuffer(m_srcTarget, srcBuf);
|
|
glBufferData(m_srcTarget, m_srcSize, srcRef.getPtr(), m_srcHint);
|
|
GLU_CHECK_MSG("glBufferData");
|
|
|
|
// Create destination buffer and fill with data.
|
|
dstBuf = genBuffer();
|
|
glBindBuffer(m_dstTarget, dstBuf);
|
|
glBufferData(m_dstTarget, m_dstSize, dstRef.getPtr(), m_dstHint);
|
|
GLU_CHECK_MSG("glBufferData");
|
|
|
|
// Verify both buffers before executing copy.
|
|
isOk = verifier.verify(srcBuf, srcRef.getPtr(), 0, m_srcSize, m_srcTarget) && isOk;
|
|
isOk = verifier.verify(dstBuf, dstRef.getPtr(), 0, m_dstSize, m_dstTarget) && isOk;
|
|
|
|
// Execute copy.
|
|
deMemcpy(dstRef.getPtr()+m_copyDstOffset, srcRef.getPtr()+m_copySrcOffset, m_copySize);
|
|
|
|
glBindBuffer(m_srcTarget, srcBuf);
|
|
glBindBuffer(m_dstTarget, dstBuf);
|
|
glCopyBufferSubData(m_srcTarget, m_dstTarget, m_copySrcOffset, m_copyDstOffset, m_copySize);
|
|
GLU_CHECK_MSG("glCopyBufferSubData");
|
|
|
|
// Verify both buffers after copy.
|
|
isOk = verifier.verify(srcBuf, srcRef.getPtr(), 0, m_srcSize, m_srcTarget) && isOk;
|
|
isOk = verifier.verify(dstBuf, dstRef.getPtr(), 0, m_dstSize, m_dstTarget) && isOk;
|
|
|
|
m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
|
|
isOk ? "Pass" : "Buffer verification failed");
|
|
return STOP;
|
|
}
|
|
|
|
private:
|
|
deUint32 m_srcTarget;
|
|
int m_srcSize;
|
|
deUint32 m_srcHint;
|
|
|
|
deUint32 m_dstTarget;
|
|
int m_dstSize;
|
|
deUint32 m_dstHint;
|
|
|
|
int m_copySrcOffset;
|
|
int m_copyDstOffset;
|
|
int m_copySize;
|
|
|
|
VerifyType m_verifyType;
|
|
};
|
|
|
|
// Case B: same buffer, take range as parameter
|
|
|
|
class SingleBufferCopyCase : public BufferCase
|
|
{
|
|
public:
|
|
SingleBufferCopyCase (Context& context,
|
|
const char* name,
|
|
const char* desc,
|
|
deUint32 srcTarget,
|
|
deUint32 dstTarget,
|
|
deUint32 hint,
|
|
VerifyType verifyType)
|
|
: BufferCase (context.getTestContext(), context.getRenderContext(), name, desc)
|
|
, m_srcTarget (srcTarget)
|
|
, m_dstTarget (dstTarget)
|
|
, m_hint (hint)
|
|
, m_verifyType (verifyType)
|
|
{
|
|
}
|
|
|
|
IterateResult iterate (void)
|
|
{
|
|
const int size = 1000;
|
|
BufferVerifier verifier (m_renderCtx, m_testCtx.getLog(), m_verifyType);
|
|
ReferenceBuffer ref;
|
|
deUint32 buf = 0;
|
|
deUint32 baseSeed = deStringHash(getName());
|
|
bool isOk = true;
|
|
|
|
ref.setSize(size);
|
|
|
|
// Create buffer.
|
|
buf = genBuffer();
|
|
glBindBuffer(m_srcTarget, buf);
|
|
|
|
static const struct
|
|
{
|
|
int srcOffset;
|
|
int dstOffset;
|
|
int copySize;
|
|
} copyRanges[] =
|
|
{
|
|
{ 57, 701, 101 }, // Non-adjecent, from low to high.
|
|
{ 640, 101, 101 }, // Non-adjecent, from high to low.
|
|
{ 0, 500, 500 }, // Lower half to upper half.
|
|
{ 500, 0, 500 } // Upper half to lower half.
|
|
};
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(copyRanges) && isOk; ndx++)
|
|
{
|
|
int srcOffset = copyRanges[ndx].srcOffset;
|
|
int dstOffset = copyRanges[ndx].dstOffset;
|
|
int copySize = copyRanges[ndx].copySize;
|
|
|
|
fillWithRandomBytes(ref.getPtr(), size, baseSeed ^ deInt32Hash(ndx));
|
|
|
|
// Fill with data.
|
|
glBindBuffer(m_srcTarget, buf);
|
|
glBufferData(m_srcTarget, size, ref.getPtr(), m_hint);
|
|
GLU_CHECK_MSG("glBufferData");
|
|
|
|
// Execute copy.
|
|
deMemcpy(ref.getPtr()+dstOffset, ref.getPtr()+srcOffset, copySize);
|
|
|
|
glBindBuffer(m_dstTarget, buf);
|
|
glCopyBufferSubData(m_srcTarget, m_dstTarget, srcOffset, dstOffset, copySize);
|
|
GLU_CHECK_MSG("glCopyBufferSubData");
|
|
|
|
// Verify buffer after copy.
|
|
isOk = verifier.verify(buf, ref.getPtr(), 0, size, m_dstTarget) && isOk;
|
|
}
|
|
|
|
m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
|
|
isOk ? "Pass" : "Buffer verification failed");
|
|
return STOP;
|
|
}
|
|
|
|
private:
|
|
deUint32 m_srcTarget;
|
|
deUint32 m_dstTarget;
|
|
deUint32 m_hint;
|
|
|
|
VerifyType m_verifyType;
|
|
};
|
|
|
|
BufferCopyTests::BufferCopyTests (Context& context)
|
|
: TestCaseGroup(context, "copy", "Buffer copy tests")
|
|
{
|
|
}
|
|
|
|
BufferCopyTests::~BufferCopyTests (void)
|
|
{
|
|
}
|
|
|
|
void BufferCopyTests::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
|
|
};
|
|
|
|
// .basic
|
|
{
|
|
tcu::TestCaseGroup* basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic buffer copy cases");
|
|
addChild(basicGroup);
|
|
|
|
for (int srcTargetNdx = 0; srcTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); srcTargetNdx++)
|
|
{
|
|
for (int dstTargetNdx = 0; dstTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); dstTargetNdx++)
|
|
{
|
|
if (srcTargetNdx == dstTargetNdx)
|
|
continue;
|
|
|
|
deUint32 srcTarget = bufferTargets[srcTargetNdx];
|
|
deUint32 dstTarget = bufferTargets[dstTargetNdx];
|
|
const int size = 1017;
|
|
const deUint32 hint = GL_STATIC_DRAW;
|
|
VerifyType verify = VERIFY_AS_VERTEX_ARRAY;
|
|
string name = string(getBufferTargetName(srcTarget)) + "_" + getBufferTargetName(dstTarget);
|
|
|
|
basicGroup->addChild(new BasicBufferCopyCase(m_context, name.c_str(), "", srcTarget, size, hint, dstTarget, size, hint, 0, 0, size, verify));
|
|
}
|
|
}
|
|
}
|
|
|
|
// .subrange
|
|
{
|
|
tcu::TestCaseGroup* subrangeGroup = new tcu::TestCaseGroup(m_testCtx, "subrange", "Buffer subrange copy tests");
|
|
addChild(subrangeGroup);
|
|
|
|
static const struct
|
|
{
|
|
const char* name;
|
|
int srcSize;
|
|
int dstSize;
|
|
int srcOffset;
|
|
int dstOffset;
|
|
int copySize;
|
|
} cases[] =
|
|
{
|
|
// srcSize dstSize srcOffs dstOffs copySize
|
|
{ "middle", 1000, 1000, 250, 250, 500 },
|
|
{ "small_to_large", 100, 1000, 0, 409, 100 },
|
|
{ "large_to_small", 1000, 100, 409, 0, 100 },
|
|
{ "low_to_high_1", 1000, 1000, 0, 500, 500 },
|
|
{ "low_to_high_2", 997, 1027, 0, 701, 111 },
|
|
{ "high_to_low_1", 1000, 1000, 500, 0, 500 },
|
|
{ "high_to_low_2", 1027, 997, 701, 17, 111 }
|
|
};
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
|
|
{
|
|
deUint32 srcTarget = GL_COPY_READ_BUFFER;
|
|
deUint32 dstTarget = GL_COPY_WRITE_BUFFER;
|
|
deUint32 hint = GL_STATIC_DRAW;
|
|
VerifyType verify = VERIFY_AS_VERTEX_ARRAY;
|
|
|
|
subrangeGroup->addChild(new BasicBufferCopyCase(m_context, cases[ndx].name, "",
|
|
srcTarget, cases[ndx].srcSize, hint,
|
|
dstTarget, cases[ndx].dstSize, hint,
|
|
cases[ndx].srcOffset, cases[ndx].dstOffset, cases[ndx].copySize,
|
|
verify));
|
|
}
|
|
}
|
|
|
|
// .single_buffer
|
|
{
|
|
tcu::TestCaseGroup* singleBufGroup = new tcu::TestCaseGroup(m_testCtx, "single_buffer", "Copies within single buffer");
|
|
addChild(singleBufGroup);
|
|
|
|
for (int srcTargetNdx = 0; srcTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); srcTargetNdx++)
|
|
{
|
|
for (int dstTargetNdx = 0; dstTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); dstTargetNdx++)
|
|
{
|
|
if (srcTargetNdx == dstTargetNdx)
|
|
continue;
|
|
|
|
deUint32 srcTarget = bufferTargets[srcTargetNdx];
|
|
deUint32 dstTarget = bufferTargets[dstTargetNdx];
|
|
const deUint32 hint = GL_STATIC_DRAW;
|
|
VerifyType verify = VERIFY_AS_VERTEX_ARRAY;
|
|
string name = string(getBufferTargetName(srcTarget)) + "_" + getBufferTargetName(dstTarget);
|
|
|
|
singleBufGroup->addChild(new SingleBufferCopyCase(m_context, name.c_str(), "", srcTarget, dstTarget, hint, verify));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
} // Functional
|
|
} // gles3
|
|
} // deqp
|