1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.0 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Buffer copying tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es3fBufferCopyTests.hpp"
25 #include "glsBufferTestUtil.hpp"
26 #include "tcuTestLog.hpp"
29 #include "glwEnums.hpp"
30 #include "glwFunctions.hpp"
45 using namespace gls::BufferTestUtil;
47 class BasicBufferCopyCase : public BufferCase
50 BasicBufferCopyCase (Context& context,
62 VerifyType verifyType)
63 : BufferCase (context.getTestContext(), context.getRenderContext(), name, desc)
64 , m_srcTarget (srcTarget)
67 , m_dstTarget (dstTarget)
70 , m_copySrcOffset (copySrcOffset)
71 , m_copyDstOffset (copyDstOffset)
72 , m_copySize (copySize)
73 , m_verifyType (verifyType)
75 DE_ASSERT(de::inBounds(m_copySrcOffset, 0, m_srcSize) && de::inRange(m_copySrcOffset+m_copySize, m_copySrcOffset, m_srcSize));
76 DE_ASSERT(de::inBounds(m_copyDstOffset, 0, m_dstSize) && de::inRange(m_copyDstOffset+m_copySize, m_copyDstOffset, m_dstSize));
79 IterateResult iterate (void)
81 BufferVerifier verifier (m_renderCtx, m_testCtx.getLog(), m_verifyType);
82 ReferenceBuffer srcRef;
83 ReferenceBuffer dstRef;
86 deUint32 srcSeed = deStringHash(getName()) ^ 0xabcd;
87 deUint32 dstSeed = deStringHash(getName()) ^ 0xef01;
90 srcRef.setSize(m_srcSize);
91 fillWithRandomBytes(srcRef.getPtr(), m_srcSize, srcSeed);
93 dstRef.setSize(m_dstSize);
94 fillWithRandomBytes(dstRef.getPtr(), m_dstSize, dstSeed);
96 // Create source buffer and fill with data.
98 glBindBuffer(m_srcTarget, srcBuf);
99 glBufferData(m_srcTarget, m_srcSize, srcRef.getPtr(), m_srcHint);
100 GLU_CHECK_MSG("glBufferData");
102 // Create destination buffer and fill with data.
103 dstBuf = genBuffer();
104 glBindBuffer(m_dstTarget, dstBuf);
105 glBufferData(m_dstTarget, m_dstSize, dstRef.getPtr(), m_dstHint);
106 GLU_CHECK_MSG("glBufferData");
108 // Verify both buffers before executing copy.
109 isOk = verifier.verify(srcBuf, srcRef.getPtr(), 0, m_srcSize, m_srcTarget) && isOk;
110 isOk = verifier.verify(dstBuf, dstRef.getPtr(), 0, m_dstSize, m_dstTarget) && isOk;
113 deMemcpy(dstRef.getPtr()+m_copyDstOffset, srcRef.getPtr()+m_copySrcOffset, m_copySize);
115 glBindBuffer(m_srcTarget, srcBuf);
116 glBindBuffer(m_dstTarget, dstBuf);
117 glCopyBufferSubData(m_srcTarget, m_dstTarget, m_copySrcOffset, m_copyDstOffset, m_copySize);
118 GLU_CHECK_MSG("glCopyBufferSubData");
120 // Verify both buffers after copy.
121 isOk = verifier.verify(srcBuf, srcRef.getPtr(), 0, m_srcSize, m_srcTarget) && isOk;
122 isOk = verifier.verify(dstBuf, dstRef.getPtr(), 0, m_dstSize, m_dstTarget) && isOk;
124 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
125 isOk ? "Pass" : "Buffer verification failed");
130 deUint32 m_srcTarget;
134 deUint32 m_dstTarget;
142 VerifyType m_verifyType;
145 // Case B: same buffer, take range as parameter
147 class SingleBufferCopyCase : public BufferCase
150 SingleBufferCopyCase (Context& context,
156 VerifyType verifyType)
157 : BufferCase (context.getTestContext(), context.getRenderContext(), name, desc)
158 , m_srcTarget (srcTarget)
159 , m_dstTarget (dstTarget)
161 , m_verifyType (verifyType)
165 IterateResult iterate (void)
167 const int size = 1000;
168 BufferVerifier verifier (m_renderCtx, m_testCtx.getLog(), m_verifyType);
171 deUint32 baseSeed = deStringHash(getName());
178 glBindBuffer(m_srcTarget, buf);
187 { 57, 701, 101 }, // Non-adjecent, from low to high.
188 { 640, 101, 101 }, // Non-adjecent, from high to low.
189 { 0, 500, 500 }, // Lower half to upper half.
190 { 500, 0, 500 } // Upper half to lower half.
193 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(copyRanges) && isOk; ndx++)
195 int srcOffset = copyRanges[ndx].srcOffset;
196 int dstOffset = copyRanges[ndx].dstOffset;
197 int copySize = copyRanges[ndx].copySize;
199 fillWithRandomBytes(ref.getPtr(), size, baseSeed ^ deInt32Hash(ndx));
202 glBindBuffer(m_srcTarget, buf);
203 glBufferData(m_srcTarget, size, ref.getPtr(), m_hint);
204 GLU_CHECK_MSG("glBufferData");
207 deMemcpy(ref.getPtr()+dstOffset, ref.getPtr()+srcOffset, copySize);
209 glBindBuffer(m_dstTarget, buf);
210 glCopyBufferSubData(m_srcTarget, m_dstTarget, srcOffset, dstOffset, copySize);
211 GLU_CHECK_MSG("glCopyBufferSubData");
213 // Verify buffer after copy.
214 isOk = verifier.verify(buf, ref.getPtr(), 0, size, m_dstTarget) && isOk;
217 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
218 isOk ? "Pass" : "Buffer verification failed");
223 deUint32 m_srcTarget;
224 deUint32 m_dstTarget;
227 VerifyType m_verifyType;
230 BufferCopyTests::BufferCopyTests (Context& context)
231 : TestCaseGroup(context, "copy", "Buffer copy tests")
235 BufferCopyTests::~BufferCopyTests (void)
239 void BufferCopyTests::init (void)
241 static const deUint32 bufferTargets[] =
245 GL_COPY_WRITE_BUFFER,
246 GL_ELEMENT_ARRAY_BUFFER,
247 GL_PIXEL_PACK_BUFFER,
248 GL_PIXEL_UNPACK_BUFFER,
249 GL_TRANSFORM_FEEDBACK_BUFFER,
255 tcu::TestCaseGroup* basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic buffer copy cases");
256 addChild(basicGroup);
258 for (int srcTargetNdx = 0; srcTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); srcTargetNdx++)
260 for (int dstTargetNdx = 0; dstTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); dstTargetNdx++)
262 if (srcTargetNdx == dstTargetNdx)
265 deUint32 srcTarget = bufferTargets[srcTargetNdx];
266 deUint32 dstTarget = bufferTargets[dstTargetNdx];
267 const int size = 1017;
268 const deUint32 hint = GL_STATIC_DRAW;
269 VerifyType verify = VERIFY_AS_VERTEX_ARRAY;
270 string name = string(getBufferTargetName(srcTarget)) + "_" + getBufferTargetName(dstTarget);
272 basicGroup->addChild(new BasicBufferCopyCase(m_context, name.c_str(), "", srcTarget, size, hint, dstTarget, size, hint, 0, 0, size, verify));
279 tcu::TestCaseGroup* subrangeGroup = new tcu::TestCaseGroup(m_testCtx, "subrange", "Buffer subrange copy tests");
280 addChild(subrangeGroup);
292 // srcSize dstSize srcOffs dstOffs copySize
293 { "middle", 1000, 1000, 250, 250, 500 },
294 { "small_to_large", 100, 1000, 0, 409, 100 },
295 { "large_to_small", 1000, 100, 409, 0, 100 },
296 { "low_to_high_1", 1000, 1000, 0, 500, 500 },
297 { "low_to_high_2", 997, 1027, 0, 701, 111 },
298 { "high_to_low_1", 1000, 1000, 500, 0, 500 },
299 { "high_to_low_2", 1027, 997, 701, 17, 111 }
302 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
304 deUint32 srcTarget = GL_COPY_READ_BUFFER;
305 deUint32 dstTarget = GL_COPY_WRITE_BUFFER;
306 deUint32 hint = GL_STATIC_DRAW;
307 VerifyType verify = VERIFY_AS_VERTEX_ARRAY;
309 subrangeGroup->addChild(new BasicBufferCopyCase(m_context, cases[ndx].name, "",
310 srcTarget, cases[ndx].srcSize, hint,
311 dstTarget, cases[ndx].dstSize, hint,
312 cases[ndx].srcOffset, cases[ndx].dstOffset, cases[ndx].copySize,
319 tcu::TestCaseGroup* singleBufGroup = new tcu::TestCaseGroup(m_testCtx, "single_buffer", "Copies within single buffer");
320 addChild(singleBufGroup);
322 for (int srcTargetNdx = 0; srcTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); srcTargetNdx++)
324 for (int dstTargetNdx = 0; dstTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); dstTargetNdx++)
326 if (srcTargetNdx == dstTargetNdx)
329 deUint32 srcTarget = bufferTargets[srcTargetNdx];
330 deUint32 dstTarget = bufferTargets[dstTargetNdx];
331 const deUint32 hint = GL_STATIC_DRAW;
332 VerifyType verify = VERIFY_AS_VERTEX_ARRAY;
333 string name = string(getBufferTargetName(srcTarget)) + "_" + getBufferTargetName(dstTarget);
335 singleBufGroup->addChild(new SingleBufferCopyCase(m_context, name.c_str(), "", srcTarget, dstTarget, hint, verify));