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