xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fBufferMapTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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