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