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 map tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es3fBufferMapTests.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::set;
35 using std::string;
36 using std::vector;
37 using tcu::TestLog;
38
39 namespace deqp
40 {
41 namespace gles3
42 {
43 namespace Functional
44 {
45
46 using namespace gls::BufferTestUtil;
47
48 // Test cases.
49
50 class BufferMapReadCase : public BufferCase
51 {
52 public:
BufferMapReadCase(Context & context,const char * name,const char * desc,uint32_t bufferTarget,uint32_t usage,int bufferSize,int mapOffset,int mapSize,WriteType write)53 BufferMapReadCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget, uint32_t usage,
54 int bufferSize, int mapOffset, int mapSize, WriteType write)
55 : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc)
56 , m_bufferTarget(bufferTarget)
57 , m_usage(usage)
58 , m_bufferSize(bufferSize)
59 , m_mapOffset(mapOffset)
60 , m_mapSize(mapSize)
61 , m_write(write)
62 {
63 }
64
iterate(void)65 IterateResult iterate(void)
66 {
67 TestLog &log = m_testCtx.getLog();
68 uint32_t dataSeed = deStringHash(getName());
69 ReferenceBuffer refBuf;
70 BufferWriter writer(m_renderCtx, m_testCtx.getLog(), m_write);
71 bool isOk = false;
72
73 // Setup reference data.
74 refBuf.setSize(m_bufferSize);
75 fillWithRandomBytes(refBuf.getPtr(), m_bufferSize, dataSeed);
76
77 uint32_t buf = genBuffer();
78 glBindBuffer(m_bufferTarget, buf);
79 glBufferData(m_bufferTarget, m_bufferSize, DE_NULL, m_usage);
80 writer.write(buf, 0, m_bufferSize, refBuf.getPtr(), m_bufferTarget);
81
82 glBindBuffer(m_bufferTarget, buf);
83 void *ptr = glMapBufferRange(m_bufferTarget, m_mapOffset, m_mapSize, GL_MAP_READ_BIT);
84 GLU_CHECK_MSG("glMapBufferRange");
85 TCU_CHECK(ptr);
86
87 isOk = compareByteArrays(log, (const uint8_t *)ptr, refBuf.getPtr(m_mapOffset), m_mapSize);
88
89 glUnmapBuffer(m_bufferTarget);
90 GLU_CHECK_MSG("glUnmapBuffer");
91
92 deleteBuffer(buf);
93
94 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
95 isOk ? "Pass" : "Buffer verification failed");
96 return STOP;
97 }
98
99 private:
100 uint32_t m_bufferTarget;
101 uint32_t m_usage;
102 int m_bufferSize;
103 int m_mapOffset;
104 int m_mapSize;
105 WriteType m_write;
106 };
107
108 class BufferMapWriteCase : public BufferCase
109 {
110 public:
BufferMapWriteCase(Context & context,const char * name,const char * desc,uint32_t bufferTarget,uint32_t usage,int size,VerifyType verify)111 BufferMapWriteCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget, uint32_t usage,
112 int size, VerifyType verify)
113 : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc)
114 , m_bufferTarget(bufferTarget)
115 , m_usage(usage)
116 , m_size(size)
117 , m_verify(verify)
118 {
119 }
120
iterate(void)121 IterateResult iterate(void)
122 {
123 uint32_t dataSeed = deStringHash(getName());
124 ReferenceBuffer refBuf;
125 BufferVerifier verifier(m_renderCtx, m_testCtx.getLog(), m_verify);
126
127 // Setup reference data.
128 refBuf.setSize(m_size);
129 fillWithRandomBytes(refBuf.getPtr(), m_size, dataSeed);
130
131 uint32_t buf = genBuffer();
132 glBindBuffer(m_bufferTarget, buf);
133 glBufferData(m_bufferTarget, m_size, DE_NULL, m_usage);
134
135 void *ptr = glMapBufferRange(m_bufferTarget, 0, m_size, GL_MAP_WRITE_BIT);
136 GLU_CHECK_MSG("glMapBufferRange");
137 TCU_CHECK(ptr);
138
139 fillWithRandomBytes((uint8_t *)ptr, m_size, dataSeed);
140 glUnmapBuffer(m_bufferTarget);
141 GLU_CHECK_MSG("glUnmapBuffer");
142
143 bool isOk = verifier.verify(buf, refBuf.getPtr(), 0, m_size, m_bufferTarget);
144 deleteBuffer(buf);
145
146 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
147 isOk ? "Pass" : "Buffer verification failed");
148 return STOP;
149 }
150
151 private:
152 uint32_t m_bufferTarget;
153 uint32_t m_usage;
154 int m_size;
155 VerifyType m_verify;
156 };
157
158 class BufferPartialMapWriteCase : public BufferCase
159 {
160 public:
BufferPartialMapWriteCase(Context & context,const char * name,const char * desc,uint32_t bufferTarget,uint32_t usage,int bufferSize,int mapOffset,int mapSize,VerifyType verify)161 BufferPartialMapWriteCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget,
162 uint32_t usage, int bufferSize, int mapOffset, int mapSize, VerifyType verify)
163 : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc)
164 , m_bufferTarget(bufferTarget)
165 , m_usage(usage)
166 , m_bufferSize(bufferSize)
167 , m_mapOffset(mapOffset)
168 , m_mapSize(mapSize)
169 , m_verify(verify)
170 {
171 }
172
iterate(void)173 IterateResult iterate(void)
174 {
175 uint32_t dataSeed = deStringHash(getName());
176 ReferenceBuffer refBuf;
177 BufferVerifier verifier(m_renderCtx, m_testCtx.getLog(), m_verify);
178
179 // Setup reference data.
180 refBuf.setSize(m_bufferSize);
181 fillWithRandomBytes(refBuf.getPtr(), m_bufferSize, dataSeed);
182
183 uint32_t buf = genBuffer();
184 glBindBuffer(m_bufferTarget, buf);
185 glBufferData(m_bufferTarget, m_bufferSize, refBuf.getPtr(), m_usage);
186
187 // Do reference map.
188 fillWithRandomBytes(refBuf.getPtr(m_mapOffset), m_mapSize, dataSeed & 0xabcdef);
189
190 void *ptr = glMapBufferRange(m_bufferTarget, m_mapOffset, m_mapSize, GL_MAP_WRITE_BIT);
191 GLU_CHECK_MSG("glMapBufferRange");
192 TCU_CHECK(ptr);
193
194 deMemcpy(ptr, refBuf.getPtr(m_mapOffset), m_mapSize);
195 glUnmapBuffer(m_bufferTarget);
196 GLU_CHECK_MSG("glUnmapBuffer");
197
198 bool isOk = verifier.verify(buf, refBuf.getPtr(), 0, m_bufferSize, m_bufferTarget);
199 deleteBuffer(buf);
200
201 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
202 isOk ? "Pass" : "Buffer verification failed");
203 return STOP;
204 }
205
206 private:
207 uint32_t m_bufferTarget;
208 uint32_t m_usage;
209 int m_bufferSize;
210 int m_mapOffset;
211 int m_mapSize;
212 VerifyType m_verify;
213 };
214
215 class BufferMapInvalidateCase : public BufferCase
216 {
217 public:
BufferMapInvalidateCase(Context & context,const char * name,const char * desc,uint32_t bufferTarget,uint32_t usage,bool partialWrite,VerifyType verify)218 BufferMapInvalidateCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget, uint32_t usage,
219 bool partialWrite, VerifyType verify)
220 : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc)
221 , m_bufferTarget(bufferTarget)
222 , m_usage(usage)
223 , m_partialWrite(partialWrite)
224 , m_verify(verify)
225 {
226 }
227
iterate(void)228 IterateResult iterate(void)
229 {
230 uint32_t dataSeed = deStringHash(getName());
231 uint32_t buf = 0;
232 ReferenceBuffer refBuf;
233 BufferVerifier verifier(m_renderCtx, m_testCtx.getLog(), m_verify);
234 const int bufferSize = 1300;
235 const int mapOffset = 200;
236 const int mapSize = 1011;
237 const int mapWriteOffs = m_partialWrite ? 91 : 0;
238 const int verifyOffset = mapOffset + mapWriteOffs;
239 const int verifySize = mapSize - mapWriteOffs;
240
241 // Setup reference data.
242 refBuf.setSize(bufferSize);
243 fillWithRandomBytes(refBuf.getPtr(), bufferSize, dataSeed);
244
245 buf = genBuffer();
246 glBindBuffer(m_bufferTarget, buf);
247 glBufferData(m_bufferTarget, bufferSize, refBuf.getPtr(), m_usage);
248
249 // Do reference map.
250 fillWithRandomBytes(refBuf.getPtr(mapOffset + mapWriteOffs), mapSize - mapWriteOffs, dataSeed & 0xabcdef);
251
252 void *ptr =
253 glMapBufferRange(m_bufferTarget, mapOffset, mapSize, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
254 GLU_CHECK_MSG("glMapBufferRange");
255 TCU_CHECK(ptr);
256
257 deMemcpy((uint8_t *)ptr + mapWriteOffs, refBuf.getPtr(mapOffset + mapWriteOffs), mapSize - mapWriteOffs);
258 glUnmapBuffer(m_bufferTarget);
259 GLU_CHECK_MSG("glUnmapBuffer");
260
261 bool isOk = verifier.verify(buf, refBuf.getPtr(), verifyOffset, verifySize, m_bufferTarget);
262 deleteBuffer(buf);
263
264 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
265 isOk ? "Pass" : "Buffer verification failed");
266 return STOP;
267 }
268
269 private:
270 uint32_t m_bufferTarget;
271 uint32_t m_usage;
272 bool m_partialWrite;
273 VerifyType m_verify;
274 };
275
276 class BufferMapPartialInvalidateCase : public BufferCase
277 {
278 public:
BufferMapPartialInvalidateCase(Context & context,const char * name,const char * desc,uint32_t bufferTarget,uint32_t usage,bool partialWrite,VerifyType verify)279 BufferMapPartialInvalidateCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget,
280 uint32_t usage, bool partialWrite, VerifyType verify)
281 : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc)
282 , m_bufferTarget(bufferTarget)
283 , m_usage(usage)
284 , m_partialWrite(partialWrite)
285 , m_verify(verify)
286 {
287 }
288
iterate(void)289 IterateResult iterate(void)
290 {
291 uint32_t dataSeed = deStringHash(getName());
292 uint32_t buf = 0;
293 ReferenceBuffer refBuf;
294 BufferVerifier verifier(m_renderCtx, m_testCtx.getLog(), m_verify);
295 const int bufferSize = 1300;
296 const int mapOffset = 200;
297 const int mapSize = 1011;
298 const int mapWriteOffs = m_partialWrite ? 91 : 0;
299 const int verifyOffset = m_partialWrite ? mapOffset + mapWriteOffs : 0;
300 const int verifySize = bufferSize - verifyOffset;
301
302 // Setup reference data.
303 refBuf.setSize(bufferSize);
304 fillWithRandomBytes(refBuf.getPtr(), bufferSize, dataSeed);
305
306 buf = genBuffer();
307 glBindBuffer(m_bufferTarget, buf);
308 glBufferData(m_bufferTarget, bufferSize, refBuf.getPtr(), m_usage);
309
310 // Do reference map.
311 fillWithRandomBytes(refBuf.getPtr(mapOffset + mapWriteOffs), mapSize - mapWriteOffs, dataSeed & 0xabcdef);
312
313 void *ptr =
314 glMapBufferRange(m_bufferTarget, mapOffset, mapSize, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
315 GLU_CHECK_MSG("glMapBufferRange");
316 TCU_CHECK(ptr);
317
318 deMemcpy((uint8_t *)ptr + mapWriteOffs, refBuf.getPtr(mapOffset + mapWriteOffs), mapSize - mapWriteOffs);
319 glUnmapBuffer(m_bufferTarget);
320 GLU_CHECK_MSG("glUnmapBuffer");
321
322 bool isOk = verifier.verify(buf, refBuf.getPtr(), verifyOffset, verifySize, m_bufferTarget);
323 deleteBuffer(buf);
324
325 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
326 isOk ? "Pass" : "Buffer verification failed");
327 return STOP;
328 }
329
330 private:
331 uint32_t m_bufferTarget;
332 uint32_t m_usage;
333 bool m_partialWrite;
334 VerifyType m_verify;
335 };
336
337 class BufferMapExplicitFlushCase : public BufferCase
338 {
339 public:
BufferMapExplicitFlushCase(Context & context,const char * name,const char * desc,uint32_t bufferTarget,uint32_t usage,bool partialWrite,VerifyType verify)340 BufferMapExplicitFlushCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget,
341 uint32_t usage, bool partialWrite, VerifyType verify)
342 : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc)
343 , m_bufferTarget(bufferTarget)
344 , m_usage(usage)
345 , m_partialWrite(partialWrite)
346 , m_verify(verify)
347 {
348 }
349
iterate(void)350 IterateResult iterate(void)
351 {
352 uint32_t dataSeed = deStringHash(getName());
353 uint32_t buf = 0;
354 ReferenceBuffer refBuf;
355 BufferVerifier verifier(m_renderCtx, m_testCtx.getLog(), m_verify);
356 const int bufferSize = 1300;
357 const int mapOffset = 200;
358 const int mapSize = 1011;
359 const int sliceAOffs = m_partialWrite ? 1 : 0;
360 const int sliceASize = m_partialWrite ? 96 : 473;
361 const int sliceBOffs = m_partialWrite ? 503 : sliceAOffs + sliceASize;
362 const int sliceBSize = mapSize - sliceBOffs;
363 bool isOk = true;
364
365 // Setup reference data.
366 refBuf.setSize(bufferSize);
367 fillWithRandomBytes(refBuf.getPtr(), bufferSize, dataSeed);
368
369 buf = genBuffer();
370 glBindBuffer(m_bufferTarget, buf);
371 glBufferData(m_bufferTarget, bufferSize, refBuf.getPtr(), m_usage);
372
373 // Do reference map.
374 fillWithRandomBytes(refBuf.getPtr(mapOffset), mapSize, dataSeed & 0xabcdef);
375
376 void *ptr = glMapBufferRange(m_bufferTarget, mapOffset, mapSize, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
377 GLU_CHECK_MSG("glMapBufferRange");
378 TCU_CHECK(ptr);
379
380 deMemcpy(ptr, refBuf.getPtr(mapOffset), mapSize);
381
382 glFlushMappedBufferRange(m_bufferTarget, sliceAOffs, sliceASize);
383 GLU_CHECK_MSG("glFlushMappedBufferRange");
384 glFlushMappedBufferRange(m_bufferTarget, sliceBOffs, sliceBSize);
385 GLU_CHECK_MSG("glFlushMappedBufferRange");
386
387 glUnmapBuffer(m_bufferTarget);
388 GLU_CHECK_MSG("glUnmapBuffer");
389
390 if (m_partialWrite)
391 {
392 if (!verifier.verify(buf, refBuf.getPtr(), mapOffset + sliceAOffs, sliceASize, m_bufferTarget))
393 isOk = false;
394
395 if (!verifier.verify(buf, refBuf.getPtr(), mapOffset + sliceBOffs, sliceBSize, m_bufferTarget))
396 isOk = false;
397 }
398 else
399 {
400 if (!verifier.verify(buf, refBuf.getPtr(), mapOffset, mapSize, m_bufferTarget))
401 isOk = false;
402 }
403
404 deleteBuffer(buf);
405
406 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
407 isOk ? "Pass" : "Buffer verification failed");
408 return STOP;
409 }
410
411 private:
412 uint32_t m_bufferTarget;
413 uint32_t m_usage;
414 bool m_partialWrite;
415 VerifyType m_verify;
416 };
417
418 class BufferMapUnsyncWriteCase : public BufferCase
419 {
420 public:
BufferMapUnsyncWriteCase(Context & context,const char * name,const char * desc,uint32_t bufferTarget,uint32_t usage)421 BufferMapUnsyncWriteCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget,
422 uint32_t usage)
423 : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc)
424 , m_bufferTarget(bufferTarget)
425 , m_usage(usage)
426 {
427 }
428
iterate(void)429 IterateResult iterate(void)
430 {
431 VertexArrayVerifier verifier(m_renderCtx, m_testCtx.getLog());
432 uint32_t dataSeed = deStringHash(getName());
433 ReferenceBuffer refBuf;
434 uint32_t buf = 0;
435 bool isOk = true;
436 const int size = 1200;
437
438 // Setup reference data.
439 refBuf.setSize(size);
440 fillWithRandomBytes(refBuf.getPtr(), size, dataSeed);
441
442 buf = genBuffer();
443 glBindBuffer(m_bufferTarget, buf);
444 glBufferData(m_bufferTarget, size, refBuf.getPtr(), m_usage);
445
446 // Use for rendering.
447 if (!verifier.verify(buf, refBuf.getPtr(), 0, size))
448 isOk = false;
449 // \note ReadPixels() implies Finish
450
451 glBindBuffer(m_bufferTarget, buf);
452 void *ptr = glMapBufferRange(m_bufferTarget, 0, size, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
453 GLU_CHECK_MSG("glMapBufferRange");
454 TCU_CHECK(ptr);
455
456 fillWithRandomBytes(refBuf.getPtr(), size, dataSeed & 0xabcdef);
457 deMemcpy(ptr, refBuf.getPtr(), size);
458
459 glUnmapBuffer(m_bufferTarget);
460 GLU_CHECK_MSG("glUnmapBuffer");
461
462 // Synchronize.
463 glFinish();
464
465 if (!verifier.verify(buf, refBuf.getPtr(), 0, size))
466 isOk = false;
467
468 deleteBuffer(buf);
469
470 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
471 isOk ? "Pass" : "Buffer verification failed");
472 return STOP;
473 }
474
475 private:
476 uint32_t m_bufferTarget;
477 uint32_t m_usage;
478 };
479
480 class BufferMapReadWriteCase : public BufferCase
481 {
482 public:
BufferMapReadWriteCase(Context & context,const char * name,const char * desc,uint32_t bufferTarget,uint32_t usage,int bufferSize,int mapOffset,int mapSize,VerifyType verify)483 BufferMapReadWriteCase(Context &context, const char *name, const char *desc, uint32_t bufferTarget, uint32_t usage,
484 int bufferSize, int mapOffset, int mapSize, VerifyType verify)
485 : BufferCase(context.getTestContext(), context.getRenderContext(), name, desc)
486 , m_bufferTarget(bufferTarget)
487 , m_usage(usage)
488 , m_bufferSize(bufferSize)
489 , m_mapOffset(mapOffset)
490 , m_mapSize(mapSize)
491 , m_verify(verify)
492 {
493 }
494
iterate(void)495 IterateResult iterate(void)
496 {
497 TestLog &log = m_testCtx.getLog();
498 uint32_t dataSeed = deStringHash(getName());
499 uint32_t buf = 0;
500 ReferenceBuffer refBuf;
501 BufferVerifier verifier(m_renderCtx, m_testCtx.getLog(), m_verify);
502 bool isOk = true;
503
504 // Setup reference data.
505 refBuf.setSize(m_bufferSize);
506 fillWithRandomBytes(refBuf.getPtr(), m_bufferSize, dataSeed);
507
508 buf = genBuffer();
509 glBindBuffer(m_bufferTarget, buf);
510 glBufferData(m_bufferTarget, m_bufferSize, refBuf.getPtr(), m_usage);
511
512 // Verify before mapping.
513 if (!verifier.verify(buf, refBuf.getPtr(), 0, m_bufferSize, m_bufferTarget))
514 isOk = false;
515
516 glBindBuffer(m_bufferTarget, buf);
517 void *ptr = glMapBufferRange(m_bufferTarget, m_mapOffset, m_mapSize, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
518 GLU_CHECK_MSG("glMapBufferRange");
519 TCU_CHECK(ptr);
520
521 // Compare mapped ptr.
522 if (!compareByteArrays(log, (const uint8_t *)ptr, refBuf.getPtr(m_mapOffset), m_mapSize))
523 isOk = false;
524
525 fillWithRandomBytes(refBuf.getPtr(m_mapOffset), m_mapSize, dataSeed & 0xabcdef);
526 deMemcpy(ptr, refBuf.getPtr(m_mapOffset), m_mapSize);
527
528 glUnmapBuffer(m_bufferTarget);
529 GLU_CHECK_MSG("glUnmapBuffer");
530
531 // Compare final buffer.
532 if (!verifier.verify(buf, refBuf.getPtr(), 0, m_bufferSize, m_bufferTarget))
533 isOk = false;
534
535 deleteBuffer(buf);
536
537 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
538 isOk ? "Pass" : "Buffer verification failed");
539 return STOP;
540 }
541
542 private:
543 uint32_t m_bufferTarget;
544 uint32_t m_usage;
545 int m_bufferSize;
546 int m_mapOffset;
547 int m_mapSize;
548 VerifyType m_verify;
549 };
550
BufferMapTests(Context & context)551 BufferMapTests::BufferMapTests(Context &context) : TestCaseGroup(context, "map", "Buffer map tests")
552 {
553 }
554
~BufferMapTests(void)555 BufferMapTests::~BufferMapTests(void)
556 {
557 }
558
init(void)559 void BufferMapTests::init(void)
560 {
561 static const uint32_t bufferTargets[] = {
562 GL_ARRAY_BUFFER, GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, GL_ELEMENT_ARRAY_BUFFER,
563 GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER, GL_UNIFORM_BUFFER};
564
565 static const uint32_t usageHints[] = {GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY,
566 GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY,
567 GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, GL_DYNAMIC_COPY};
568
569 static const struct
570 {
571 const char *name;
572 WriteType write;
573 } bufferDataSources[] = {{"sub_data", WRITE_BUFFER_SUB_DATA}, {"map_write", WRITE_BUFFER_WRITE_MAP}};
574
575 static const struct
576 {
577 const char *name;
578 VerifyType verify;
579 } bufferUses[] = {{"map_read", VERIFY_BUFFER_READ_MAP},
580 {"render_as_vertex_array", VERIFY_AS_VERTEX_ARRAY},
581 {"render_as_index_array", VERIFY_AS_INDEX_ARRAY}};
582
583 // .read
584 {
585 tcu::TestCaseGroup *mapReadGroup =
586 new tcu::TestCaseGroup(m_testCtx, "read", "Buffer read using glMapBufferRange()");
587 addChild(mapReadGroup);
588
589 // .[data src]
590 for (int srcNdx = 0; srcNdx < DE_LENGTH_OF_ARRAY(bufferDataSources); srcNdx++)
591 {
592 WriteType write = bufferDataSources[srcNdx].write;
593 tcu::TestCaseGroup *writeGroup = new tcu::TestCaseGroup(m_testCtx, bufferDataSources[srcNdx].name, "");
594 mapReadGroup->addChild(writeGroup);
595
596 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
597 {
598 uint32_t target = bufferTargets[targetNdx];
599 const uint32_t hint = GL_STATIC_READ;
600 const int size = 1019;
601 const int partialOffs = 17;
602 const int partialSize = 501;
603
604 writeGroup->addChild(new BufferMapReadCase(m_context,
605 (string(getBufferTargetName(target)) + "_full").c_str(), "",
606 target, hint, size, 0, size, write));
607 writeGroup->addChild(new BufferMapReadCase(m_context,
608 (string(getBufferTargetName(target)) + "_partial").c_str(),
609 "", target, hint, size, partialOffs, partialSize, write));
610 }
611 }
612
613 // .usage_hints
614 {
615 tcu::TestCaseGroup *hintsGroup =
616 new tcu::TestCaseGroup(m_testCtx, "usage_hints", "Different usage hints with glMapBufferRange()");
617 mapReadGroup->addChild(hintsGroup);
618
619 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
620 {
621 for (int hintNdx = 0; hintNdx < DE_LENGTH_OF_ARRAY(usageHints); hintNdx++)
622 {
623 uint32_t target = bufferTargets[targetNdx];
624 uint32_t hint = usageHints[hintNdx];
625 const int size = 1019;
626 string name = string(getBufferTargetName(target)) + "_" + getUsageHintName(hint);
627
628 hintsGroup->addChild(new BufferMapReadCase(m_context, name.c_str(), "", target, hint, size, 0, size,
629 WRITE_BUFFER_SUB_DATA));
630 }
631 }
632 }
633 }
634
635 // .write
636 {
637 tcu::TestCaseGroup *mapWriteGroup =
638 new tcu::TestCaseGroup(m_testCtx, "write", "Buffer write using glMapBufferRange()");
639 addChild(mapWriteGroup);
640
641 // .[verify type]
642 for (int useNdx = 0; useNdx < DE_LENGTH_OF_ARRAY(bufferUses); useNdx++)
643 {
644 VerifyType verify = bufferUses[useNdx].verify;
645 tcu::TestCaseGroup *useGroup = new tcu::TestCaseGroup(m_testCtx, bufferUses[useNdx].name, "");
646 mapWriteGroup->addChild(useGroup);
647
648 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
649 {
650 uint32_t target = bufferTargets[targetNdx];
651 uint32_t hint = GL_STATIC_DRAW;
652 const int size = 1019;
653 const int partialOffs = 17;
654 const int partialSize = 501;
655 string name = string(getBufferTargetName(target)) + "_" + getUsageHintName(hint);
656
657 useGroup->addChild(new BufferMapWriteCase(m_context,
658 (string(getBufferTargetName(target)) + "_full").c_str(), "",
659 target, hint, size, verify));
660 useGroup->addChild(
661 new BufferPartialMapWriteCase(m_context, (string(getBufferTargetName(target)) + "_partial").c_str(),
662 "", target, hint, size, partialOffs, partialSize, verify));
663 }
664 }
665
666 // .usage_hints
667 {
668 tcu::TestCaseGroup *hintsGroup = new tcu::TestCaseGroup(m_testCtx, "usage_hints", "Usage hints");
669 mapWriteGroup->addChild(hintsGroup);
670
671 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
672 {
673 for (int hintNdx = 0; hintNdx < DE_LENGTH_OF_ARRAY(usageHints); hintNdx++)
674 {
675 uint32_t target = bufferTargets[targetNdx];
676 uint32_t hint = usageHints[hintNdx];
677 const int size = 1019;
678 string name = string(getBufferTargetName(target)) + "_" + getUsageHintName(hint);
679
680 hintsGroup->addChild(new BufferMapWriteCase(m_context, name.c_str(), "", target, hint, size,
681 VERIFY_AS_VERTEX_ARRAY));
682 }
683 }
684 }
685
686 // .invalidate
687 {
688 tcu::TestCaseGroup *invalidateGroup = new tcu::TestCaseGroup(m_testCtx, "invalidate", "Buffer invalidate");
689 mapWriteGroup->addChild(invalidateGroup);
690
691 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
692 {
693 uint32_t target = bufferTargets[targetNdx];
694 uint32_t hint = GL_STATIC_DRAW;
695
696 invalidateGroup->addChild(
697 new BufferMapInvalidateCase(m_context, (string(getBufferTargetName(target)) + "_write_all").c_str(),
698 "", target, hint, false, VERIFY_AS_VERTEX_ARRAY));
699 invalidateGroup->addChild(new BufferMapInvalidateCase(
700 m_context, (string(getBufferTargetName(target)) + "_write_partial").c_str(), "", target, hint, true,
701 VERIFY_AS_VERTEX_ARRAY));
702 }
703 }
704
705 // .partial_invalidate
706 {
707 tcu::TestCaseGroup *invalidateGroup =
708 new tcu::TestCaseGroup(m_testCtx, "partial_invalidate", "Partial invalidate");
709 mapWriteGroup->addChild(invalidateGroup);
710
711 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
712 {
713 uint32_t target = bufferTargets[targetNdx];
714 uint32_t hint = GL_STATIC_DRAW;
715
716 invalidateGroup->addChild(new BufferMapPartialInvalidateCase(
717 m_context, (string(getBufferTargetName(target)) + "_write_all").c_str(), "", target, hint, false,
718 VERIFY_AS_VERTEX_ARRAY));
719 invalidateGroup->addChild(new BufferMapPartialInvalidateCase(
720 m_context, (string(getBufferTargetName(target)) + "_write_partial").c_str(), "", target, hint, true,
721 VERIFY_AS_VERTEX_ARRAY));
722 }
723 }
724
725 // .explicit_flush
726 {
727 tcu::TestCaseGroup *flushGroup = new tcu::TestCaseGroup(m_testCtx, "explicit_flush", "Explicit flush");
728 mapWriteGroup->addChild(flushGroup);
729
730 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
731 {
732 uint32_t target = bufferTargets[targetNdx];
733 uint32_t hint = GL_STATIC_DRAW;
734
735 flushGroup->addChild(
736 new BufferMapExplicitFlushCase(m_context, (string(getBufferTargetName(target)) + "_all").c_str(),
737 "", target, hint, false, VERIFY_AS_VERTEX_ARRAY));
738 flushGroup->addChild(new BufferMapExplicitFlushCase(
739 m_context, (string(getBufferTargetName(target)) + "_partial").c_str(), "", target, hint, true,
740 VERIFY_AS_VERTEX_ARRAY));
741 }
742 }
743
744 // .unsynchronized
745 {
746 tcu::TestCaseGroup *unsyncGroup = new tcu::TestCaseGroup(m_testCtx, "unsynchronized", "Unsynchronized map");
747 mapWriteGroup->addChild(unsyncGroup);
748
749 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
750 {
751 uint32_t target = bufferTargets[targetNdx];
752 uint32_t hint = GL_STATIC_DRAW;
753
754 unsyncGroup->addChild(
755 new BufferMapUnsyncWriteCase(m_context, getBufferTargetName(target), "", target, hint));
756 }
757 }
758 }
759
760 // .read_write
761 {
762 tcu::TestCaseGroup *mapReadWriteGroup =
763 new tcu::TestCaseGroup(m_testCtx, "read_write", "Buffer read and write using glMapBufferRange()");
764 addChild(mapReadWriteGroup);
765
766 // .[verify type]
767 for (int useNdx = 0; useNdx < DE_LENGTH_OF_ARRAY(bufferUses); useNdx++)
768 {
769 VerifyType verify = bufferUses[useNdx].verify;
770 tcu::TestCaseGroup *useGroup = new tcu::TestCaseGroup(m_testCtx, bufferUses[useNdx].name, "");
771 mapReadWriteGroup->addChild(useGroup);
772
773 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
774 {
775 uint32_t target = bufferTargets[targetNdx];
776 uint32_t hint = GL_STATIC_DRAW;
777 const int size = 1019;
778 const int partialOffs = 17;
779 const int partialSize = 501;
780 string name = string(getBufferTargetName(target)) + "_" + getUsageHintName(hint);
781
782 useGroup->addChild(new BufferMapReadWriteCase(m_context,
783 (string(getBufferTargetName(target)) + "_full").c_str(),
784 "", target, hint, size, 0, size, verify));
785 useGroup->addChild(
786 new BufferMapReadWriteCase(m_context, (string(getBufferTargetName(target)) + "_partial").c_str(),
787 "", target, hint, size, partialOffs, partialSize, verify));
788 }
789 }
790
791 // .usage_hints
792 {
793 tcu::TestCaseGroup *hintsGroup = new tcu::TestCaseGroup(m_testCtx, "usage_hints", "Usage hints");
794 mapReadWriteGroup->addChild(hintsGroup);
795
796 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
797 {
798 for (int hintNdx = 0; hintNdx < DE_LENGTH_OF_ARRAY(usageHints); hintNdx++)
799 {
800 uint32_t target = bufferTargets[targetNdx];
801 uint32_t hint = usageHints[hintNdx];
802 const int size = 1019;
803 string name = string(getBufferTargetName(target)) + "_" + getUsageHintName(hint);
804
805 hintsGroup->addChild(new BufferMapReadWriteCase(m_context, name.c_str(), "", target, hint, size, 0,
806 size, VERIFY_AS_VERTEX_ARRAY));
807 }
808 }
809 }
810 }
811 }
812
813 } // namespace Functional
814 } // namespace gles3
815 } // namespace deqp
816