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::string;
35 using std::vector;
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,uint32_t srcTarget,int srcSize,uint32_t srcHint,uint32_t dstTarget,int dstSize,uint32_t dstHint,int copySrcOffset,int copyDstOffset,int copySize,VerifyType verifyType)50 BasicBufferCopyCase(Context &context, const char *name, const char *desc, uint32_t srcTarget, int srcSize,
51 uint32_t srcHint, uint32_t dstTarget, int dstSize, uint32_t dstHint, int copySrcOffset,
52 int copyDstOffset, int copySize, VerifyType verifyType)
53 : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc)
54 , m_srcTarget(srcTarget)
55 , m_srcSize(srcSize)
56 , m_srcHint(srcHint)
57 , m_dstTarget(dstTarget)
58 , m_dstSize(dstSize)
59 , m_dstHint(dstHint)
60 , m_copySrcOffset(copySrcOffset)
61 , m_copyDstOffset(copyDstOffset)
62 , m_copySize(copySize)
63 , m_verifyType(verifyType)
64 {
65 DE_ASSERT(de::inBounds(m_copySrcOffset, 0, m_srcSize) &&
66 de::inRange(m_copySrcOffset + m_copySize, m_copySrcOffset, m_srcSize));
67 DE_ASSERT(de::inBounds(m_copyDstOffset, 0, m_dstSize) &&
68 de::inRange(m_copyDstOffset + m_copySize, m_copyDstOffset, m_dstSize));
69 }
70
iterate(void)71 IterateResult iterate(void)
72 {
73 BufferVerifier verifier(m_renderCtx, m_testCtx.getLog(), m_verifyType);
74 ReferenceBuffer srcRef;
75 ReferenceBuffer dstRef;
76 uint32_t srcBuf = 0;
77 uint32_t dstBuf = 0;
78 uint32_t srcSeed = deStringHash(getName()) ^ 0xabcd;
79 uint32_t dstSeed = deStringHash(getName()) ^ 0xef01;
80 bool isOk = true;
81
82 srcRef.setSize(m_srcSize);
83 fillWithRandomBytes(srcRef.getPtr(), m_srcSize, srcSeed);
84
85 dstRef.setSize(m_dstSize);
86 fillWithRandomBytes(dstRef.getPtr(), m_dstSize, dstSeed);
87
88 // Create source buffer and fill with data.
89 srcBuf = genBuffer();
90 glBindBuffer(m_srcTarget, srcBuf);
91 glBufferData(m_srcTarget, m_srcSize, srcRef.getPtr(), m_srcHint);
92 GLU_CHECK_MSG("glBufferData");
93
94 // Create destination buffer and fill with data.
95 dstBuf = genBuffer();
96 glBindBuffer(m_dstTarget, dstBuf);
97 glBufferData(m_dstTarget, m_dstSize, dstRef.getPtr(), m_dstHint);
98 GLU_CHECK_MSG("glBufferData");
99
100 // Verify both buffers before executing copy.
101 isOk = verifier.verify(srcBuf, srcRef.getPtr(), 0, m_srcSize, m_srcTarget) && isOk;
102 isOk = verifier.verify(dstBuf, dstRef.getPtr(), 0, m_dstSize, m_dstTarget) && isOk;
103
104 // Execute copy.
105 deMemcpy(dstRef.getPtr() + m_copyDstOffset, srcRef.getPtr() + m_copySrcOffset, m_copySize);
106
107 glBindBuffer(m_srcTarget, srcBuf);
108 glBindBuffer(m_dstTarget, dstBuf);
109 glCopyBufferSubData(m_srcTarget, m_dstTarget, m_copySrcOffset, m_copyDstOffset, m_copySize);
110 GLU_CHECK_MSG("glCopyBufferSubData");
111
112 // Verify both buffers after copy.
113 isOk = verifier.verify(srcBuf, srcRef.getPtr(), 0, m_srcSize, m_srcTarget) && isOk;
114 isOk = verifier.verify(dstBuf, dstRef.getPtr(), 0, m_dstSize, m_dstTarget) && isOk;
115
116 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
117 isOk ? "Pass" : "Buffer verification failed");
118 return STOP;
119 }
120
121 private:
122 uint32_t m_srcTarget;
123 int m_srcSize;
124 uint32_t m_srcHint;
125
126 uint32_t m_dstTarget;
127 int m_dstSize;
128 uint32_t m_dstHint;
129
130 int m_copySrcOffset;
131 int m_copyDstOffset;
132 int m_copySize;
133
134 VerifyType m_verifyType;
135 };
136
137 // Case B: same buffer, take range as parameter
138
139 class SingleBufferCopyCase : public BufferCase
140 {
141 public:
SingleBufferCopyCase(Context & context,const char * name,const char * desc,uint32_t srcTarget,uint32_t dstTarget,uint32_t hint,VerifyType verifyType)142 SingleBufferCopyCase(Context &context, const char *name, const char *desc, uint32_t srcTarget, uint32_t dstTarget,
143 uint32_t hint, VerifyType verifyType)
144 : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc)
145 , m_srcTarget(srcTarget)
146 , m_dstTarget(dstTarget)
147 , m_hint(hint)
148 , m_verifyType(verifyType)
149 {
150 }
151
iterate(void)152 IterateResult iterate(void)
153 {
154 const int size = 1000;
155 BufferVerifier verifier(m_renderCtx, m_testCtx.getLog(), m_verifyType);
156 ReferenceBuffer ref;
157 uint32_t buf = 0;
158 uint32_t baseSeed = deStringHash(getName());
159 bool isOk = true;
160
161 ref.setSize(size);
162
163 // Create buffer.
164 buf = genBuffer();
165 glBindBuffer(m_srcTarget, buf);
166
167 static const struct
168 {
169 int srcOffset;
170 int dstOffset;
171 int copySize;
172 } copyRanges[] = {
173 {57, 701, 101}, // Non-adjecent, from low to high.
174 {640, 101, 101}, // Non-adjecent, from high to low.
175 {0, 500, 500}, // Lower half to upper half.
176 {500, 0, 500} // Upper half to lower half.
177 };
178
179 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(copyRanges) && isOk; ndx++)
180 {
181 int srcOffset = copyRanges[ndx].srcOffset;
182 int dstOffset = copyRanges[ndx].dstOffset;
183 int copySize = copyRanges[ndx].copySize;
184
185 fillWithRandomBytes(ref.getPtr(), size, baseSeed ^ deInt32Hash(ndx));
186
187 // Fill with data.
188 glBindBuffer(m_srcTarget, buf);
189 glBufferData(m_srcTarget, size, ref.getPtr(), m_hint);
190 GLU_CHECK_MSG("glBufferData");
191
192 // Execute copy.
193 deMemcpy(ref.getPtr() + dstOffset, ref.getPtr() + srcOffset, copySize);
194
195 glBindBuffer(m_dstTarget, buf);
196 glCopyBufferSubData(m_srcTarget, m_dstTarget, srcOffset, dstOffset, copySize);
197 GLU_CHECK_MSG("glCopyBufferSubData");
198
199 // Verify buffer after copy.
200 isOk = verifier.verify(buf, ref.getPtr(), 0, size, m_dstTarget) && isOk;
201 }
202
203 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
204 isOk ? "Pass" : "Buffer verification failed");
205 return STOP;
206 }
207
208 private:
209 uint32_t m_srcTarget;
210 uint32_t m_dstTarget;
211 uint32_t m_hint;
212
213 VerifyType m_verifyType;
214 };
215
BufferCopyTests(Context & context)216 BufferCopyTests::BufferCopyTests(Context &context) : TestCaseGroup(context, "copy", "Buffer copy tests")
217 {
218 }
219
~BufferCopyTests(void)220 BufferCopyTests::~BufferCopyTests(void)
221 {
222 }
223
init(void)224 void BufferCopyTests::init(void)
225 {
226 static const uint32_t bufferTargets[] = {
227 GL_ARRAY_BUFFER, GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, GL_ELEMENT_ARRAY_BUFFER,
228 GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER, GL_UNIFORM_BUFFER};
229
230 // .basic
231 {
232 tcu::TestCaseGroup *basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic buffer copy cases");
233 addChild(basicGroup);
234
235 for (int srcTargetNdx = 0; srcTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); srcTargetNdx++)
236 {
237 for (int dstTargetNdx = 0; dstTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); dstTargetNdx++)
238 {
239 if (srcTargetNdx == dstTargetNdx)
240 continue;
241
242 uint32_t srcTarget = bufferTargets[srcTargetNdx];
243 uint32_t dstTarget = bufferTargets[dstTargetNdx];
244 const int size = 1017;
245 const uint32_t hint = GL_STATIC_DRAW;
246 VerifyType verify = VERIFY_AS_VERTEX_ARRAY;
247 string name = string(getBufferTargetName(srcTarget)) + "_" + getBufferTargetName(dstTarget);
248
249 basicGroup->addChild(new BasicBufferCopyCase(m_context, name.c_str(), "", srcTarget, size, hint,
250 dstTarget, size, hint, 0, 0, size, verify));
251 }
252 }
253 }
254
255 // .subrange
256 {
257 tcu::TestCaseGroup *subrangeGroup = new tcu::TestCaseGroup(m_testCtx, "subrange", "Buffer subrange copy tests");
258 addChild(subrangeGroup);
259
260 static const struct
261 {
262 const char *name;
263 int srcSize;
264 int dstSize;
265 int srcOffset;
266 int dstOffset;
267 int copySize;
268 } cases[] = {// srcSize dstSize srcOffs dstOffs copySize
269 {"middle", 1000, 1000, 250, 250, 500}, {"small_to_large", 100, 1000, 0, 409, 100},
270 {"large_to_small", 1000, 100, 409, 0, 100}, {"low_to_high_1", 1000, 1000, 0, 500, 500},
271 {"low_to_high_2", 997, 1027, 0, 701, 111}, {"high_to_low_1", 1000, 1000, 500, 0, 500},
272 {"high_to_low_2", 1027, 997, 701, 17, 111}};
273
274 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
275 {
276 uint32_t srcTarget = GL_COPY_READ_BUFFER;
277 uint32_t dstTarget = GL_COPY_WRITE_BUFFER;
278 uint32_t hint = GL_STATIC_DRAW;
279 VerifyType verify = VERIFY_AS_VERTEX_ARRAY;
280
281 subrangeGroup->addChild(new BasicBufferCopyCase(
282 m_context, cases[ndx].name, "", srcTarget, cases[ndx].srcSize, hint, dstTarget, cases[ndx].dstSize,
283 hint, cases[ndx].srcOffset, cases[ndx].dstOffset, cases[ndx].copySize, verify));
284 }
285 }
286
287 // .single_buffer
288 {
289 tcu::TestCaseGroup *singleBufGroup =
290 new tcu::TestCaseGroup(m_testCtx, "single_buffer", "Copies within single buffer");
291 addChild(singleBufGroup);
292
293 for (int srcTargetNdx = 0; srcTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); srcTargetNdx++)
294 {
295 for (int dstTargetNdx = 0; dstTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); dstTargetNdx++)
296 {
297 if (srcTargetNdx == dstTargetNdx)
298 continue;
299
300 uint32_t srcTarget = bufferTargets[srcTargetNdx];
301 uint32_t dstTarget = bufferTargets[dstTargetNdx];
302 const uint32_t hint = GL_STATIC_DRAW;
303 VerifyType verify = VERIFY_AS_VERTEX_ARRAY;
304 string name = string(getBufferTargetName(srcTarget)) + "_" + getBufferTargetName(dstTarget);
305
306 singleBufGroup->addChild(
307 new SingleBufferCopyCase(m_context, name.c_str(), "", srcTarget, dstTarget, hint, verify));
308 }
309 }
310 }
311 }
312
313 } // namespace Functional
314 } // namespace gles3
315 } // namespace deqp
316