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