xref: /aosp_15_r20/external/deqp/modules/gles31/functional/es31fTextureBufferTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.1 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 Texture buffer tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es31fTextureBufferTests.hpp"
25 
26 #include "glsTextureBufferCase.hpp"
27 #include "glsStateQueryUtil.hpp"
28 
29 #include "tcuTestLog.hpp"
30 
31 #include "gluRenderContext.hpp"
32 #include "gluContextInfo.hpp"
33 #include "gluCallLogWrapper.hpp"
34 #include "gluStrUtil.hpp"
35 
36 #include "glwEnums.hpp"
37 
38 #include "deStringUtil.hpp"
39 
40 #include <string>
41 
42 using std::string;
43 using namespace deqp::gls::TextureBufferCaseUtil;
44 using deqp::gls::TextureBufferCase;
45 
46 namespace deqp
47 {
48 namespace gles31
49 {
50 namespace Functional
51 {
52 namespace
53 {
54 
toTestName(RenderBits renderBits)55 string toTestName(RenderBits renderBits)
56 {
57     struct
58     {
59         RenderBits bit;
60         const char *str;
61     } bitInfos[] = {{RENDERBITS_AS_VERTEX_ARRAY, "as_vertex_array"},
62                     {RENDERBITS_AS_INDEX_ARRAY, "as_index_array"},
63                     {RENDERBITS_AS_VERTEX_TEXTURE, "as_vertex_texture"},
64                     {RENDERBITS_AS_FRAGMENT_TEXTURE, "as_fragment_texture"}};
65 
66     std::ostringstream stream;
67     bool first = true;
68 
69     DE_ASSERT(renderBits != 0);
70 
71     for (int infoNdx = 0; infoNdx < DE_LENGTH_OF_ARRAY(bitInfos); infoNdx++)
72     {
73         if (renderBits & bitInfos[infoNdx].bit)
74         {
75             stream << (first ? "" : "_") << bitInfos[infoNdx].str;
76             first = false;
77         }
78     }
79 
80     return stream.str();
81 }
82 
toTestName(ModifyBits modifyBits)83 string toTestName(ModifyBits modifyBits)
84 {
85     struct
86     {
87         ModifyBits bit;
88         const char *str;
89     } bitInfos[] = {{MODIFYBITS_BUFFERDATA, "bufferdata"},
90                     {MODIFYBITS_BUFFERSUBDATA, "buffersubdata"},
91                     {MODIFYBITS_MAPBUFFER_WRITE, "mapbuffer_write"},
92                     {MODIFYBITS_MAPBUFFER_READWRITE, "mapbuffer_readwrite"}};
93 
94     std::ostringstream stream;
95     bool first = true;
96 
97     DE_ASSERT(modifyBits != 0);
98 
99     for (int infoNdx = 0; infoNdx < DE_LENGTH_OF_ARRAY(bitInfos); infoNdx++)
100     {
101         if (modifyBits & bitInfos[infoNdx].bit)
102         {
103             stream << (first ? "" : "_") << bitInfos[infoNdx].str;
104             first = false;
105         }
106     }
107 
108     return stream.str();
109 }
110 
operator |(RenderBits a,RenderBits b)111 RenderBits operator|(RenderBits a, RenderBits b)
112 {
113     return (RenderBits)(uint32_t(a) | uint32_t(b));
114 }
115 
116 } // namespace
117 
118 // Queries
119 
120 namespace
121 {
122 
checkSupport(Context & ctx)123 static void checkSupport(Context &ctx)
124 {
125     auto ctxType = ctx.getRenderContext().getType();
126     if (!glu::contextSupports(ctxType, glu::ApiType::es(3, 2)) &&
127         !glu::contextSupports(ctxType, glu::ApiType::core(4, 5)) &&
128         !ctx.getContextInfo().isExtensionSupported("GL_EXT_texture_buffer"))
129         TCU_THROW(NotSupportedError, "GL_EXT_texture_buffer is not supported");
130 }
131 
132 using namespace gls::StateQueryUtil;
133 
134 class LimitQueryCase : public TestCase
135 {
136 public:
137     LimitQueryCase(Context &ctx, const char *name, const char *desc, glw::GLenum target, int minLimit, QueryType type);
138 
139 private:
140     IterateResult iterate(void);
141 
142     const glw::GLenum m_target;
143     const int m_minValue;
144     const QueryType m_type;
145 };
146 
LimitQueryCase(Context & context,const char * name,const char * desc,glw::GLenum target,int minLimit,QueryType type)147 LimitQueryCase::LimitQueryCase(Context &context, const char *name, const char *desc, glw::GLenum target, int minLimit,
148                                QueryType type)
149     : TestCase(context, name, desc)
150     , m_target(target)
151     , m_minValue(minLimit)
152     , m_type(type)
153 {
154 }
155 
iterate(void)156 LimitQueryCase::IterateResult LimitQueryCase::iterate(void)
157 {
158     checkSupport(m_context);
159 
160     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
161     tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
162 
163     gl.enableLogging(true);
164     verifyStateIntegerMin(result, gl, m_target, m_minValue, m_type);
165 
166     result.setTestContextResult(m_testCtx);
167     return STOP;
168 }
169 
170 class AlignmentQueryCase : public TestCase
171 {
172 public:
173     AlignmentQueryCase(Context &ctx, const char *name, const char *desc, glw::GLenum target, int maxAlign,
174                        QueryType type);
175 
176 private:
177     IterateResult iterate(void);
178 
179     const glw::GLenum m_target;
180     const int m_maxValue;
181     const QueryType m_type;
182 };
183 
AlignmentQueryCase(Context & context,const char * name,const char * desc,glw::GLenum target,int maxAlign,QueryType type)184 AlignmentQueryCase::AlignmentQueryCase(Context &context, const char *name, const char *desc, glw::GLenum target,
185                                        int maxAlign, QueryType type)
186     : TestCase(context, name, desc)
187     , m_target(target)
188     , m_maxValue(maxAlign)
189     , m_type(type)
190 {
191 }
192 
iterate(void)193 AlignmentQueryCase::IterateResult AlignmentQueryCase::iterate(void)
194 {
195     checkSupport(m_context);
196 
197     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
198     tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
199 
200     gl.enableLogging(true);
201     verifyStateIntegerMax(result, gl, m_target, m_maxValue, m_type);
202 
203     result.setTestContextResult(m_testCtx);
204     return STOP;
205 }
206 
207 class TextureBufferBindingQueryCase : public TestCase
208 {
209 public:
210     TextureBufferBindingQueryCase(Context &ctx, const char *name, const char *desc, QueryType type);
211 
212 private:
213     IterateResult iterate(void);
214 
215     const QueryType m_type;
216 };
217 
TextureBufferBindingQueryCase(Context & context,const char * name,const char * desc,QueryType type)218 TextureBufferBindingQueryCase::TextureBufferBindingQueryCase(Context &context, const char *name, const char *desc,
219                                                              QueryType type)
220     : TestCase(context, name, desc)
221     , m_type(type)
222 {
223 }
224 
iterate(void)225 TextureBufferBindingQueryCase::IterateResult TextureBufferBindingQueryCase::iterate(void)
226 {
227     checkSupport(m_context);
228 
229     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
230     tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
231 
232     gl.enableLogging(true);
233 
234     // initial
235     {
236         const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial value");
237 
238         verifyStateInteger(result, gl, GL_TEXTURE_BUFFER_BINDING, 0, m_type);
239     }
240 
241     // bind
242     {
243         const tcu::ScopedLogSection section(m_testCtx.getLog(), "bind", "After bind");
244 
245         glw::GLuint buffer;
246 
247         gl.glGenBuffers(1, &buffer);
248         gl.glBindBuffer(GL_TEXTURE_BUFFER, buffer);
249         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind buffer");
250 
251         verifyStateInteger(result, gl, GL_TEXTURE_BUFFER_BINDING, buffer, m_type);
252 
253         gl.glDeleteBuffers(1, &buffer);
254     }
255 
256     // after delete
257     {
258         const tcu::ScopedLogSection section(m_testCtx.getLog(), "bind", "After delete");
259 
260         verifyStateInteger(result, gl, GL_TEXTURE_BUFFER_BINDING, 0, m_type);
261     }
262 
263     result.setTestContextResult(m_testCtx);
264     return STOP;
265 }
266 
267 class TextureBindingBufferQueryCase : public TestCase
268 {
269 public:
270     TextureBindingBufferQueryCase(Context &ctx, const char *name, const char *desc, QueryType type);
271 
272 private:
273     IterateResult iterate(void);
274 
275     const QueryType m_type;
276 };
277 
TextureBindingBufferQueryCase(Context & context,const char * name,const char * desc,QueryType type)278 TextureBindingBufferQueryCase::TextureBindingBufferQueryCase(Context &context, const char *name, const char *desc,
279                                                              QueryType type)
280     : TestCase(context, name, desc)
281     , m_type(type)
282 {
283 }
284 
iterate(void)285 TextureBindingBufferQueryCase::IterateResult TextureBindingBufferQueryCase::iterate(void)
286 {
287     checkSupport(m_context);
288 
289     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
290     tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
291 
292     gl.enableLogging(true);
293 
294     // initial
295     {
296         const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial value");
297 
298         verifyStateInteger(result, gl, GL_TEXTURE_BINDING_BUFFER, 0, m_type);
299     }
300 
301     // bind
302     {
303         const tcu::ScopedLogSection section(m_testCtx.getLog(), "bind", "After bind");
304 
305         glw::GLuint texture;
306 
307         gl.glGenTextures(1, &texture);
308         gl.glBindTexture(GL_TEXTURE_BUFFER, texture);
309         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind texture");
310 
311         verifyStateInteger(result, gl, GL_TEXTURE_BINDING_BUFFER, texture, m_type);
312 
313         gl.glDeleteTextures(1, &texture);
314     }
315 
316     // after delete
317     {
318         const tcu::ScopedLogSection section(m_testCtx.getLog(), "bind", "After delete");
319 
320         verifyStateInteger(result, gl, GL_TEXTURE_BINDING_BUFFER, 0, m_type);
321     }
322 
323     result.setTestContextResult(m_testCtx);
324     return STOP;
325 }
326 
327 class TextureBufferDataStoreQueryCase : public TestCase
328 {
329 public:
330     TextureBufferDataStoreQueryCase(Context &ctx, const char *name, const char *desc, QueryType type);
331 
332 private:
333     IterateResult iterate(void);
334 
335     const QueryType m_type;
336 };
337 
TextureBufferDataStoreQueryCase(Context & context,const char * name,const char * desc,QueryType type)338 TextureBufferDataStoreQueryCase::TextureBufferDataStoreQueryCase(Context &context, const char *name, const char *desc,
339                                                                  QueryType type)
340     : TestCase(context, name, desc)
341     , m_type(type)
342 {
343 }
344 
iterate(void)345 TextureBufferDataStoreQueryCase::IterateResult TextureBufferDataStoreQueryCase::iterate(void)
346 {
347     checkSupport(m_context);
348 
349     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
350     tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
351 
352     gl.enableLogging(true);
353 
354     // non-buffer
355     {
356         const tcu::ScopedLogSection section(m_testCtx.getLog(), "NonBuffer", "Non-buffer");
357 
358         glw::GLuint texture;
359 
360         gl.glGenTextures(1, &texture);
361         gl.glBindTexture(GL_TEXTURE_2D, texture);
362         gl.glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32);
363         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "gen texture");
364 
365         verifyStateTextureLevelInteger(result, gl, GL_TEXTURE_2D, 0, GL_TEXTURE_BUFFER_DATA_STORE_BINDING, 0, m_type);
366 
367         gl.glDeleteTextures(1, &texture);
368     }
369 
370     // buffer
371     {
372         const tcu::ScopedLogSection section(m_testCtx.getLog(), "Buffer", "Texture buffer");
373 
374         glw::GLuint texture;
375         glw::GLuint buffer;
376 
377         gl.glGenTextures(1, &texture);
378         gl.glBindTexture(GL_TEXTURE_BUFFER, texture);
379         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind texture");
380 
381         gl.glGenBuffers(1, &buffer);
382         gl.glBindBuffer(GL_TEXTURE_BUFFER, buffer);
383         gl.glBufferData(GL_TEXTURE_BUFFER, 32, DE_NULL, GL_STATIC_DRAW);
384         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind buf");
385 
386         gl.glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, buffer);
387         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "tex buffer");
388 
389         verifyStateTextureLevelInteger(result, gl, GL_TEXTURE_BUFFER, 0, GL_TEXTURE_BUFFER_DATA_STORE_BINDING, buffer,
390                                        m_type);
391 
392         gl.glDeleteTextures(1, &texture);
393         gl.glDeleteBuffers(1, &buffer);
394     }
395 
396     result.setTestContextResult(m_testCtx);
397     return STOP;
398 }
399 
400 class TextureBufferOffsetQueryCase : public TestCase
401 {
402 public:
403     TextureBufferOffsetQueryCase(Context &ctx, const char *name, const char *desc, QueryType type);
404 
405 private:
406     IterateResult iterate(void);
407 
408     const QueryType m_type;
409 };
410 
TextureBufferOffsetQueryCase(Context & context,const char * name,const char * desc,QueryType type)411 TextureBufferOffsetQueryCase::TextureBufferOffsetQueryCase(Context &context, const char *name, const char *desc,
412                                                            QueryType type)
413     : TestCase(context, name, desc)
414     , m_type(type)
415 {
416 }
417 
iterate(void)418 TextureBufferOffsetQueryCase::IterateResult TextureBufferOffsetQueryCase::iterate(void)
419 {
420     checkSupport(m_context);
421 
422     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
423     tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
424 
425     gl.enableLogging(true);
426 
427     // non-buffer
428     {
429         const tcu::ScopedLogSection section(m_testCtx.getLog(), "NonBuffer", "Non-buffer");
430 
431         glw::GLuint texture;
432 
433         gl.glGenTextures(1, &texture);
434         gl.glBindTexture(GL_TEXTURE_2D, texture);
435         gl.glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32);
436         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "gen texture");
437 
438         verifyStateTextureLevelInteger(result, gl, GL_TEXTURE_2D, 0, GL_TEXTURE_BUFFER_OFFSET, 0, m_type);
439 
440         gl.glDeleteTextures(1, &texture);
441     }
442 
443     // buffer
444     {
445         const tcu::ScopedLogSection section(m_testCtx.getLog(), "Buffer", "Texture buffer");
446 
447         glw::GLuint texture;
448         glw::GLuint buffer;
449 
450         gl.glGenTextures(1, &texture);
451         gl.glBindTexture(GL_TEXTURE_BUFFER, texture);
452         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind texture");
453 
454         gl.glGenBuffers(1, &buffer);
455         gl.glBindBuffer(GL_TEXTURE_BUFFER, buffer);
456         gl.glBufferData(GL_TEXTURE_BUFFER, 1024, DE_NULL, GL_STATIC_DRAW);
457         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind buf");
458 
459         {
460             const tcu::ScopedLogSection subsection(m_testCtx.getLog(), "Offset0", "Offset 0");
461             gl.glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, buffer);
462             GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "tex buffer");
463 
464             verifyStateTextureLevelInteger(result, gl, GL_TEXTURE_BUFFER, 0, GL_TEXTURE_BUFFER_OFFSET, 0, m_type);
465         }
466         {
467             const tcu::ScopedLogSection subsection(m_testCtx.getLog(), "Offset256", "Offset 256");
468             gl.glTexBufferRange(GL_TEXTURE_BUFFER, GL_R32UI, buffer, 256, 512);
469             GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "tex buffer");
470 
471             verifyStateTextureLevelInteger(result, gl, GL_TEXTURE_BUFFER, 0, GL_TEXTURE_BUFFER_OFFSET, 256, m_type);
472         }
473 
474         gl.glDeleteTextures(1, &texture);
475         gl.glDeleteBuffers(1, &buffer);
476     }
477 
478     result.setTestContextResult(m_testCtx);
479     return STOP;
480 }
481 
482 class TextureBufferSizeQueryCase : public TestCase
483 {
484 public:
485     TextureBufferSizeQueryCase(Context &ctx, const char *name, const char *desc, QueryType type);
486 
487 private:
488     IterateResult iterate(void);
489 
490     const QueryType m_type;
491 };
492 
TextureBufferSizeQueryCase(Context & context,const char * name,const char * desc,QueryType type)493 TextureBufferSizeQueryCase::TextureBufferSizeQueryCase(Context &context, const char *name, const char *desc,
494                                                        QueryType type)
495     : TestCase(context, name, desc)
496     , m_type(type)
497 {
498 }
499 
iterate(void)500 TextureBufferSizeQueryCase::IterateResult TextureBufferSizeQueryCase::iterate(void)
501 {
502     checkSupport(m_context);
503 
504     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
505     tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
506 
507     gl.enableLogging(true);
508 
509     // non-buffer
510     {
511         const tcu::ScopedLogSection section(m_testCtx.getLog(), "NonBuffer", "Non-buffer");
512 
513         glw::GLuint texture;
514 
515         gl.glGenTextures(1, &texture);
516         gl.glBindTexture(GL_TEXTURE_2D, texture);
517         gl.glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32);
518         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "gen texture");
519 
520         verifyStateTextureLevelInteger(result, gl, GL_TEXTURE_2D, 0, GL_TEXTURE_BUFFER_SIZE, 0, m_type);
521 
522         gl.glDeleteTextures(1, &texture);
523     }
524 
525     // buffer
526     {
527         const tcu::ScopedLogSection section(m_testCtx.getLog(), "Buffer", "Texture buffer");
528 
529         glw::GLuint texture;
530         glw::GLuint buffer;
531 
532         gl.glGenTextures(1, &texture);
533         gl.glBindTexture(GL_TEXTURE_BUFFER, texture);
534         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind texture");
535 
536         gl.glGenBuffers(1, &buffer);
537         gl.glBindBuffer(GL_TEXTURE_BUFFER, buffer);
538         gl.glBufferData(GL_TEXTURE_BUFFER, 1024, DE_NULL, GL_STATIC_DRAW);
539         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "bind buf");
540 
541         {
542             const tcu::ScopedLogSection subsection(m_testCtx.getLog(), "SizeAll", "Bind whole buffer");
543             gl.glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, buffer);
544             GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "tex buffer");
545 
546             verifyStateTextureLevelInteger(result, gl, GL_TEXTURE_BUFFER, 0, GL_TEXTURE_BUFFER_SIZE, 1024, m_type);
547         }
548         {
549             const tcu::ScopedLogSection subsection(m_testCtx.getLog(), "Partial", "Partial buffer");
550             gl.glTexBufferRange(GL_TEXTURE_BUFFER, GL_R32UI, buffer, 256, 512);
551             GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "tex buffer");
552 
553             verifyStateTextureLevelInteger(result, gl, GL_TEXTURE_BUFFER, 0, GL_TEXTURE_BUFFER_SIZE, 512, m_type);
554         }
555 
556         gl.glDeleteTextures(1, &texture);
557         gl.glDeleteBuffers(1, &buffer);
558     }
559 
560     result.setTestContextResult(m_testCtx);
561     return STOP;
562 }
563 
564 } // namespace
565 
createTextureBufferTests(Context & context)566 TestCaseGroup *createTextureBufferTests(Context &context)
567 {
568     TestCaseGroup *const root = new TestCaseGroup(context, "texture_buffer", "Texture buffer syncronization tests");
569 
570     const size_t bufferSizes[] = {512, 513, 65536, 65537, 131071};
571 
572     const size_t rangeSizes[] = {
573         512,
574         513,
575         65537,
576         98304,
577     };
578 
579     const size_t offsets[] = {1, 7};
580 
581     const RenderBits renderTypeCombinations[] = {
582         RENDERBITS_AS_VERTEX_ARRAY,
583         RENDERBITS_AS_INDEX_ARRAY,
584         RENDERBITS_AS_VERTEX_ARRAY | RENDERBITS_AS_INDEX_ARRAY,
585 
586         RENDERBITS_AS_VERTEX_TEXTURE,
587         RENDERBITS_AS_VERTEX_ARRAY | RENDERBITS_AS_VERTEX_TEXTURE,
588         RENDERBITS_AS_INDEX_ARRAY | RENDERBITS_AS_VERTEX_TEXTURE,
589         RENDERBITS_AS_VERTEX_ARRAY | RENDERBITS_AS_INDEX_ARRAY | RENDERBITS_AS_VERTEX_TEXTURE,
590 
591         RENDERBITS_AS_FRAGMENT_TEXTURE,
592         RENDERBITS_AS_VERTEX_ARRAY | RENDERBITS_AS_FRAGMENT_TEXTURE,
593         RENDERBITS_AS_INDEX_ARRAY | RENDERBITS_AS_FRAGMENT_TEXTURE,
594         RENDERBITS_AS_VERTEX_ARRAY | RENDERBITS_AS_INDEX_ARRAY | RENDERBITS_AS_FRAGMENT_TEXTURE,
595         RENDERBITS_AS_VERTEX_TEXTURE | RENDERBITS_AS_FRAGMENT_TEXTURE,
596         RENDERBITS_AS_VERTEX_ARRAY | RENDERBITS_AS_VERTEX_TEXTURE | RENDERBITS_AS_FRAGMENT_TEXTURE,
597         RENDERBITS_AS_INDEX_ARRAY | RENDERBITS_AS_VERTEX_TEXTURE | RENDERBITS_AS_FRAGMENT_TEXTURE,
598         RENDERBITS_AS_VERTEX_ARRAY | RENDERBITS_AS_INDEX_ARRAY | RENDERBITS_AS_VERTEX_TEXTURE |
599             RENDERBITS_AS_FRAGMENT_TEXTURE};
600 
601     const ModifyBits modifyTypes[] = {MODIFYBITS_BUFFERDATA, MODIFYBITS_BUFFERSUBDATA, MODIFYBITS_MAPBUFFER_WRITE,
602                                       MODIFYBITS_MAPBUFFER_READWRITE};
603 
604     // State and limit queries
605     {
606         TestCaseGroup *const queryGroup = new TestCaseGroup(context, "state_query", "Query states and limits");
607         root->addChild(queryGroup);
608 
609         queryGroup->addChild(new LimitQueryCase(context, "max_texture_buffer_size_getboolean",
610                                                 "Test MAX_TEXTURE_BUFFER_SIZE", GL_MAX_TEXTURE_BUFFER_SIZE, 65536,
611                                                 QUERY_BOOLEAN));
612         queryGroup->addChild(new LimitQueryCase(context, "max_texture_buffer_size_getinteger",
613                                                 "Test MAX_TEXTURE_BUFFER_SIZE", GL_MAX_TEXTURE_BUFFER_SIZE, 65536,
614                                                 QUERY_INTEGER));
615         queryGroup->addChild(new LimitQueryCase(context, "max_texture_buffer_size_getinteger64",
616                                                 "Test MAX_TEXTURE_BUFFER_SIZE", GL_MAX_TEXTURE_BUFFER_SIZE, 65536,
617                                                 QUERY_INTEGER64));
618         queryGroup->addChild(new LimitQueryCase(context, "max_texture_buffer_size_getfloat",
619                                                 "Test MAX_TEXTURE_BUFFER_SIZE", GL_MAX_TEXTURE_BUFFER_SIZE, 65536,
620                                                 QUERY_FLOAT));
621         queryGroup->addChild(new AlignmentQueryCase(context, "texture_buffer_offset_alignment_getboolean",
622                                                     "Test TEXTURE_BUFFER_OFFSET_ALIGNMENT",
623                                                     GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, 256, QUERY_BOOLEAN));
624         queryGroup->addChild(new AlignmentQueryCase(context, "texture_buffer_offset_alignment_getinteger",
625                                                     "Test TEXTURE_BUFFER_OFFSET_ALIGNMENT",
626                                                     GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, 256, QUERY_INTEGER));
627         queryGroup->addChild(new AlignmentQueryCase(context, "texture_buffer_offset_alignment_getinteger64",
628                                                     "Test TEXTURE_BUFFER_OFFSET_ALIGNMENT",
629                                                     GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, 256, QUERY_INTEGER64));
630         queryGroup->addChild(new AlignmentQueryCase(context, "texture_buffer_offset_alignment_getfloat",
631                                                     "Test TEXTURE_BUFFER_OFFSET_ALIGNMENT",
632                                                     GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, 256, QUERY_FLOAT));
633 
634         queryGroup->addChild(new TextureBufferBindingQueryCase(context, "texture_buffer_binding_getboolean",
635                                                                "TEXTURE_BUFFER_BINDING", QUERY_BOOLEAN));
636         queryGroup->addChild(new TextureBufferBindingQueryCase(context, "texture_buffer_binding_getinteger",
637                                                                "TEXTURE_BUFFER_BINDING", QUERY_INTEGER));
638         queryGroup->addChild(new TextureBufferBindingQueryCase(context, "texture_buffer_binding_getinteger64",
639                                                                "TEXTURE_BUFFER_BINDING", QUERY_INTEGER64));
640         queryGroup->addChild(new TextureBufferBindingQueryCase(context, "texture_buffer_binding_getfloat",
641                                                                "TEXTURE_BUFFER_BINDING", QUERY_FLOAT));
642 
643         queryGroup->addChild(new TextureBindingBufferQueryCase(context, "texture_binding_buffer_getboolean",
644                                                                "TEXTURE_BINDING_BUFFER", QUERY_BOOLEAN));
645         queryGroup->addChild(new TextureBindingBufferQueryCase(context, "texture_binding_buffer_getinteger",
646                                                                "TEXTURE_BINDING_BUFFER", QUERY_INTEGER));
647         queryGroup->addChild(new TextureBindingBufferQueryCase(context, "texture_binding_buffer_getinteger64",
648                                                                "TEXTURE_BINDING_BUFFER", QUERY_INTEGER64));
649         queryGroup->addChild(new TextureBindingBufferQueryCase(context, "texture_binding_buffer_getfloat",
650                                                                "TEXTURE_BINDING_BUFFER", QUERY_FLOAT));
651 
652         queryGroup->addChild(new TextureBufferDataStoreQueryCase(context, "texture_buffer_data_store_binding_integer",
653                                                                  "TEXTURE_BUFFER_DATA_STORE_BINDING",
654                                                                  QUERY_TEXTURE_LEVEL_INTEGER));
655         queryGroup->addChild(new TextureBufferDataStoreQueryCase(context, "texture_buffer_data_store_binding_float",
656                                                                  "TEXTURE_BUFFER_DATA_STORE_BINDING",
657                                                                  QUERY_TEXTURE_LEVEL_FLOAT));
658 
659         queryGroup->addChild(new TextureBufferOffsetQueryCase(context, "texture_buffer_offset_integer",
660                                                               "TEXTURE_BUFFER_OFFSET", QUERY_TEXTURE_LEVEL_INTEGER));
661         queryGroup->addChild(new TextureBufferOffsetQueryCase(context, "texture_buffer_offset_float",
662                                                               "TEXTURE_BUFFER_OFFSET", QUERY_TEXTURE_LEVEL_FLOAT));
663 
664         queryGroup->addChild(new TextureBufferSizeQueryCase(context, "texture_buffer_size_integer",
665                                                             "TEXTURE_BUFFER_SIZE", QUERY_TEXTURE_LEVEL_INTEGER));
666         queryGroup->addChild(new TextureBufferSizeQueryCase(context, "texture_buffer_size_float", "TEXTURE_BUFFER_SIZE",
667                                                             QUERY_TEXTURE_LEVEL_FLOAT));
668     }
669 
670     // Rendering test
671     {
672         TestCaseGroup *const renderGroup = new TestCaseGroup(
673             context, "render", "Setup texture buffer with glBufferData and render data in different ways");
674         root->addChild(renderGroup);
675 
676         for (int renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypeCombinations); renderTypeNdx++)
677         {
678             const RenderBits renderType = renderTypeCombinations[renderTypeNdx];
679             TestCaseGroup *const renderTypeGroup =
680                 new TestCaseGroup(context, toTestName(renderType).c_str(), toTestName(renderType).c_str());
681 
682             renderGroup->addChild(renderTypeGroup);
683 
684             for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(bufferSizes); sizeNdx++)
685             {
686                 const size_t size = bufferSizes[sizeNdx];
687                 const string name("buffer_size_" + de::toString(size));
688 
689                 renderTypeGroup->addChild(new TextureBufferCase(context.getTestContext(), context.getRenderContext(),
690                                                                 GL_RGBA8, size, 0, 0, RENDERBITS_NONE, MODIFYBITS_NONE,
691                                                                 renderType, name.c_str(), name.c_str()));
692             }
693 
694             for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(rangeSizes); sizeNdx++)
695             {
696                 const size_t size = rangeSizes[sizeNdx];
697                 const string name("range_size_" + de::toString(size));
698                 const size_t bufferSize = 131072;
699 
700                 renderTypeGroup->addChild(new TextureBufferCase(
701                     context.getTestContext(), context.getRenderContext(), GL_RGBA8, bufferSize, 0, size,
702                     RENDERBITS_NONE, MODIFYBITS_NONE, renderType, name.c_str(), name.c_str()));
703             }
704 
705             for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
706             {
707                 const size_t offset     = offsets[offsetNdx];
708                 const size_t bufferSize = 131072;
709                 const size_t size       = 65537;
710                 const string name("offset_" + de::toString(offset) + "_alignments");
711 
712                 renderTypeGroup->addChild(new TextureBufferCase(
713                     context.getTestContext(), context.getRenderContext(), GL_RGBA8, bufferSize, offset, size,
714                     RENDERBITS_NONE, MODIFYBITS_NONE, renderType, name.c_str(), name.c_str()));
715             }
716         }
717     }
718 
719     // Modify tests
720     {
721         TestCaseGroup *const modifyGroup =
722             new TestCaseGroup(context, "modify", "Modify texture buffer content in multiple ways");
723         root->addChild(modifyGroup);
724 
725         for (int modifyNdx = 0; modifyNdx < DE_LENGTH_OF_ARRAY(modifyTypes); modifyNdx++)
726         {
727             const ModifyBits modifyType = modifyTypes[modifyNdx];
728             TestCaseGroup *const modifyTypeGroup =
729                 new TestCaseGroup(context, toTestName(modifyType).c_str(), toTestName(modifyType).c_str());
730 
731             modifyGroup->addChild(modifyTypeGroup);
732 
733             for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(bufferSizes); sizeNdx++)
734             {
735                 const size_t size = bufferSizes[sizeNdx];
736                 const string name("buffer_size_" + de::toString(size));
737 
738                 modifyTypeGroup->addChild(new TextureBufferCase(
739                     context.getTestContext(), context.getRenderContext(), GL_RGBA8, size, 0, 0, RENDERBITS_NONE,
740                     modifyType, RENDERBITS_AS_FRAGMENT_TEXTURE, name.c_str(), name.c_str()));
741             }
742 
743             for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(rangeSizes); sizeNdx++)
744             {
745                 const size_t size = rangeSizes[sizeNdx];
746                 const string name("range_size_" + de::toString(size));
747                 const size_t bufferSize = 131072;
748 
749                 modifyTypeGroup->addChild(new TextureBufferCase(
750                     context.getTestContext(), context.getRenderContext(), GL_RGBA8, bufferSize, 0, size,
751                     RENDERBITS_NONE, modifyType, RENDERBITS_AS_FRAGMENT_TEXTURE, name.c_str(), name.c_str()));
752             }
753 
754             for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
755             {
756                 const size_t offset     = offsets[offsetNdx];
757                 const size_t bufferSize = 131072;
758                 const size_t size       = 65537;
759                 const string name("offset_" + de::toString(offset) + "_alignments");
760 
761                 modifyTypeGroup->addChild(new TextureBufferCase(
762                     context.getTestContext(), context.getRenderContext(), GL_RGBA8, bufferSize, offset, size,
763                     RENDERBITS_NONE, modifyType, RENDERBITS_AS_FRAGMENT_TEXTURE, name.c_str(), name.c_str()));
764             }
765         }
766     }
767 
768     // Modify-Render tests
769     {
770         TestCaseGroup *const modifyRenderGroup = new TestCaseGroup(
771             context, "modify_render", "Modify texture buffer content in multiple ways and render in different ways");
772         root->addChild(modifyRenderGroup);
773 
774         for (int modifyNdx = 0; modifyNdx < DE_LENGTH_OF_ARRAY(modifyTypes); modifyNdx++)
775         {
776             const ModifyBits modifyType = modifyTypes[modifyNdx];
777             TestCaseGroup *const modifyTypeGroup =
778                 new TestCaseGroup(context, toTestName(modifyType).c_str(), toTestName(modifyType).c_str());
779 
780             modifyRenderGroup->addChild(modifyTypeGroup);
781 
782             for (int renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypeCombinations); renderTypeNdx++)
783             {
784                 const RenderBits renderType = renderTypeCombinations[renderTypeNdx];
785                 const size_t size           = 16 * 1024;
786                 const string name(toTestName(renderType));
787 
788                 modifyTypeGroup->addChild(new TextureBufferCase(context.getTestContext(), context.getRenderContext(),
789                                                                 GL_RGBA8, size, 0, 0, RENDERBITS_NONE, modifyType,
790                                                                 renderType, name.c_str(), name.c_str()));
791             }
792         }
793     }
794 
795     // Render-Modify tests
796     {
797         TestCaseGroup *const renderModifyGroup =
798             new TestCaseGroup(context, "render_modify", "Render texture buffer and modify.");
799         root->addChild(renderModifyGroup);
800 
801         for (int renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypeCombinations); renderTypeNdx++)
802         {
803             const RenderBits renderType = renderTypeCombinations[renderTypeNdx];
804             TestCaseGroup *const renderTypeGroup =
805                 new TestCaseGroup(context, toTestName(renderType).c_str(), toTestName(renderType).c_str());
806 
807             renderModifyGroup->addChild(renderTypeGroup);
808 
809             for (int modifyNdx = 0; modifyNdx < DE_LENGTH_OF_ARRAY(modifyTypes); modifyNdx++)
810             {
811                 const ModifyBits modifyType = modifyTypes[modifyNdx];
812                 const size_t size           = 16 * 1024;
813                 const string name(toTestName(modifyType));
814 
815                 renderTypeGroup->addChild(new TextureBufferCase(
816                     context.getTestContext(), context.getRenderContext(), GL_RGBA8, size, 0, 0, renderType, modifyType,
817                     RENDERBITS_AS_FRAGMENT_TEXTURE, name.c_str(), name.c_str()));
818             }
819         }
820     }
821 
822     return root;
823 }
824 
825 } // namespace Functional
826 } // namespace gles31
827 } // namespace deqp
828