1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.0 Module
3 * -------------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
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
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
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.
18 *
19 *//*!
20 * \file
21 * \brief Buffer copying tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es3fBufferCopyTests.hpp"
25 #include "glsBufferTestUtil.hpp"
26 #include "tcuTestLog.hpp"
27 #include "deMemory.h"
28 #include "deString.h"
29 #include "glwEnums.hpp"
30 #include "glwFunctions.hpp"
31
32 #include <algorithm>
33
34 using std::vector;
35 using std::string;
36 using tcu::TestLog;
37
38 namespace deqp
39 {
40 namespace gles3
41 {
42 namespace Functional
43 {
44
45 using namespace gls::BufferTestUtil;
46
47 class BasicBufferCopyCase : public BufferCase
48 {
49 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)50 BasicBufferCopyCase (Context& context,
51 const char* name,
52 const char* desc,
53 deUint32 srcTarget,
54 int srcSize,
55 deUint32 srcHint,
56 deUint32 dstTarget,
57 int dstSize,
58 deUint32 dstHint,
59 int copySrcOffset,
60 int copyDstOffset,
61 int copySize,
62 VerifyType verifyType)
63 : BufferCase (context.getTestContext(), context.getRenderContext(), name, desc)
64 , m_srcTarget (srcTarget)
65 , m_srcSize (srcSize)
66 , m_srcHint (srcHint)
67 , m_dstTarget (dstTarget)
68 , m_dstSize (dstSize)
69 , m_dstHint (dstHint)
70 , m_copySrcOffset (copySrcOffset)
71 , m_copyDstOffset (copyDstOffset)
72 , m_copySize (copySize)
73 , m_verifyType (verifyType)
74 {
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));
77 }
78
iterate(void)79 IterateResult iterate (void)
80 {
81 BufferVerifier verifier (m_renderCtx, m_testCtx.getLog(), m_verifyType);
82 ReferenceBuffer srcRef;
83 ReferenceBuffer dstRef;
84 deUint32 srcBuf = 0;
85 deUint32 dstBuf = 0;
86 deUint32 srcSeed = deStringHash(getName()) ^ 0xabcd;
87 deUint32 dstSeed = deStringHash(getName()) ^ 0xef01;
88 bool isOk = true;
89
90 srcRef.setSize(m_srcSize);
91 fillWithRandomBytes(srcRef.getPtr(), m_srcSize, srcSeed);
92
93 dstRef.setSize(m_dstSize);
94 fillWithRandomBytes(dstRef.getPtr(), m_dstSize, dstSeed);
95
96 // Create source buffer and fill with data.
97 srcBuf = genBuffer();
98 glBindBuffer(m_srcTarget, srcBuf);
99 glBufferData(m_srcTarget, m_srcSize, srcRef.getPtr(), m_srcHint);
100 GLU_CHECK_MSG("glBufferData");
101
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");
107
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;
111
112 // Execute copy.
113 deMemcpy(dstRef.getPtr()+m_copyDstOffset, srcRef.getPtr()+m_copySrcOffset, m_copySize);
114
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");
119
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;
123
124 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
125 isOk ? "Pass" : "Buffer verification failed");
126 return STOP;
127 }
128
129 private:
130 deUint32 m_srcTarget;
131 int m_srcSize;
132 deUint32 m_srcHint;
133
134 deUint32 m_dstTarget;
135 int m_dstSize;
136 deUint32 m_dstHint;
137
138 int m_copySrcOffset;
139 int m_copyDstOffset;
140 int m_copySize;
141
142 VerifyType m_verifyType;
143 };
144
145 // Case B: same buffer, take range as parameter
146
147 class SingleBufferCopyCase : public BufferCase
148 {
149 public:
SingleBufferCopyCase(Context & context,const char * name,const char * desc,deUint32 srcTarget,deUint32 dstTarget,deUint32 hint,VerifyType verifyType)150 SingleBufferCopyCase (Context& context,
151 const char* name,
152 const char* desc,
153 deUint32 srcTarget,
154 deUint32 dstTarget,
155 deUint32 hint,
156 VerifyType verifyType)
157 : BufferCase (context.getTestContext(), context.getRenderContext(), name, desc)
158 , m_srcTarget (srcTarget)
159 , m_dstTarget (dstTarget)
160 , m_hint (hint)
161 , m_verifyType (verifyType)
162 {
163 }
164
iterate(void)165 IterateResult iterate (void)
166 {
167 const int size = 1000;
168 BufferVerifier verifier (m_renderCtx, m_testCtx.getLog(), m_verifyType);
169 ReferenceBuffer ref;
170 deUint32 buf = 0;
171 deUint32 baseSeed = deStringHash(getName());
172 bool isOk = true;
173
174 ref.setSize(size);
175
176 // Create buffer.
177 buf = genBuffer();
178 glBindBuffer(m_srcTarget, buf);
179
180 static const struct
181 {
182 int srcOffset;
183 int dstOffset;
184 int copySize;
185 } copyRanges[] =
186 {
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.
191 };
192
193 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(copyRanges) && isOk; ndx++)
194 {
195 int srcOffset = copyRanges[ndx].srcOffset;
196 int dstOffset = copyRanges[ndx].dstOffset;
197 int copySize = copyRanges[ndx].copySize;
198
199 fillWithRandomBytes(ref.getPtr(), size, baseSeed ^ deInt32Hash(ndx));
200
201 // Fill with data.
202 glBindBuffer(m_srcTarget, buf);
203 glBufferData(m_srcTarget, size, ref.getPtr(), m_hint);
204 GLU_CHECK_MSG("glBufferData");
205
206 // Execute copy.
207 deMemcpy(ref.getPtr()+dstOffset, ref.getPtr()+srcOffset, copySize);
208
209 glBindBuffer(m_dstTarget, buf);
210 glCopyBufferSubData(m_srcTarget, m_dstTarget, srcOffset, dstOffset, copySize);
211 GLU_CHECK_MSG("glCopyBufferSubData");
212
213 // Verify buffer after copy.
214 isOk = verifier.verify(buf, ref.getPtr(), 0, size, m_dstTarget) && isOk;
215 }
216
217 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
218 isOk ? "Pass" : "Buffer verification failed");
219 return STOP;
220 }
221
222 private:
223 deUint32 m_srcTarget;
224 deUint32 m_dstTarget;
225 deUint32 m_hint;
226
227 VerifyType m_verifyType;
228 };
229
BufferCopyTests(Context & context)230 BufferCopyTests::BufferCopyTests (Context& context)
231 : TestCaseGroup(context, "copy", "Buffer copy tests")
232 {
233 }
234
~BufferCopyTests(void)235 BufferCopyTests::~BufferCopyTests (void)
236 {
237 }
238
init(void)239 void BufferCopyTests::init (void)
240 {
241 static const deUint32 bufferTargets[] =
242 {
243 GL_ARRAY_BUFFER,
244 GL_COPY_READ_BUFFER,
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,
250 GL_UNIFORM_BUFFER
251 };
252
253 // .basic
254 {
255 tcu::TestCaseGroup* basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic buffer copy cases");
256 addChild(basicGroup);
257
258 for (int srcTargetNdx = 0; srcTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); srcTargetNdx++)
259 {
260 for (int dstTargetNdx = 0; dstTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); dstTargetNdx++)
261 {
262 if (srcTargetNdx == dstTargetNdx)
263 continue;
264
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);
271
272 basicGroup->addChild(new BasicBufferCopyCase(m_context, name.c_str(), "", srcTarget, size, hint, dstTarget, size, hint, 0, 0, size, verify));
273 }
274 }
275 }
276
277 // .subrange
278 {
279 tcu::TestCaseGroup* subrangeGroup = new tcu::TestCaseGroup(m_testCtx, "subrange", "Buffer subrange copy tests");
280 addChild(subrangeGroup);
281
282 static const struct
283 {
284 const char* name;
285 int srcSize;
286 int dstSize;
287 int srcOffset;
288 int dstOffset;
289 int copySize;
290 } cases[] =
291 {
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 }
300 };
301
302 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
303 {
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;
308
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,
313 verify));
314 }
315 }
316
317 // .single_buffer
318 {
319 tcu::TestCaseGroup* singleBufGroup = new tcu::TestCaseGroup(m_testCtx, "single_buffer", "Copies within single buffer");
320 addChild(singleBufGroup);
321
322 for (int srcTargetNdx = 0; srcTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); srcTargetNdx++)
323 {
324 for (int dstTargetNdx = 0; dstTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); dstTargetNdx++)
325 {
326 if (srcTargetNdx == dstTargetNdx)
327 continue;
328
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);
334
335 singleBufGroup->addChild(new SingleBufferCopyCase(m_context, name.c_str(), "", srcTarget, dstTarget, hint, verify));
336 }
337 }
338 }
339 }
340
341 } // Functional
342 } // gles3
343 } // deqp
344