• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2015-2016 The Khronos Group Inc.
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
22  */ /*-------------------------------------------------------------------*/
23 
24 /**
25  */ /*!
26  * \file  gl4cDirectStateAccessBuffersTests.cpp
27  * \brief Conformance tests for the Direct State Access feature functionality (Buffer access part).
28  */ /*-----------------------------------------------------------------------------------------------------------*/
29 
30 /* Includes. */
31 #include "gl4cDirectStateAccessTests.hpp"
32 
33 #include "deSharedPtr.hpp"
34 
35 #include "gluContextInfo.hpp"
36 #include "gluDefs.hpp"
37 #include "gluPixelTransfer.hpp"
38 #include "gluStrUtil.hpp"
39 
40 #include "tcuFuzzyImageCompare.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "tcuRenderTarget.hpp"
43 #include "tcuSurface.hpp"
44 #include "tcuTestLog.hpp"
45 
46 #include "glw.h"
47 #include "glwFunctions.hpp"
48 
49 #include <algorithm>
50 #include <climits>
51 #include <set>
52 #include <sstream>
53 #include <stack>
54 #include <string>
55 
56 namespace gl4cts
57 {
58 namespace DirectStateAccess
59 {
60 namespace Buffers
61 {
62 /******************************** Creation Test Implementation   ********************************/
63 
64 /** @brief Creation Test constructor.
65  *
66  *  @param [in] context     OpenGL context.
67  */
CreationTest(deqp::Context & context)68 CreationTest::CreationTest(deqp::Context& context)
69 	: deqp::TestCase(context, "buffers_creation", "Buffer Objects Creation Test")
70 {
71 	/* Intentionally left blank. */
72 }
73 
74 /** @brief Iterate Creation Test cases.
75  *
76  *  @return Iteration result.
77  */
iterate()78 tcu::TestNode::IterateResult CreationTest::iterate()
79 {
80 	/* Shortcut for GL functionality. */
81 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
82 
83 	/* Get context setup. */
84 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
85 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
86 
87 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
88 	{
89 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
90 
91 		return STOP;
92 	}
93 
94 	/* Running tests. */
95 	bool is_ok	= true;
96 	bool is_error = false;
97 
98 	/* Buffers' objects */
99 	static const glw::GLuint buffers_count = 2;
100 
101 	glw::GLuint buffers_legacy[buffers_count] = {};
102 	glw::GLuint buffers_dsa[buffers_count]	= {};
103 
104 	try
105 	{
106 		/* Check legacy state creation. */
107 		gl.genBuffers(buffers_count, buffers_legacy);
108 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");
109 
110 		for (glw::GLuint i = 0; i < buffers_count; ++i)
111 		{
112 			if (gl.isBuffer(buffers_legacy[i]))
113 			{
114 				is_ok = false;
115 
116 				/* Log. */
117 				m_context.getTestContext().getLog()
118 					<< tcu::TestLog::Message
119 					<< "GenBuffers has created default objects, but it should create only a names."
120 					<< tcu::TestLog::EndMessage;
121 			}
122 		}
123 
124 		/* Check direct state creation. */
125 		gl.createBuffers(buffers_count, buffers_dsa);
126 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers have failed");
127 
128 		for (glw::GLuint i = 0; i < buffers_count; ++i)
129 		{
130 			if (!gl.isBuffer(buffers_dsa[i]))
131 			{
132 				is_ok = false;
133 
134 				/* Log. */
135 				m_context.getTestContext().getLog() << tcu::TestLog::Message
136 													<< "CreateBuffers has not created default objects."
137 													<< tcu::TestLog::EndMessage;
138 			}
139 		}
140 	}
141 	catch (...)
142 	{
143 		is_ok	= false;
144 		is_error = true;
145 	}
146 
147 	/* Cleanup. */
148 	for (glw::GLuint i = 0; i < buffers_count; ++i)
149 	{
150 		if (buffers_legacy[i])
151 		{
152 			gl.deleteBuffers(1, &buffers_legacy[i]);
153 
154 			buffers_legacy[i] = 0;
155 		}
156 
157 		if (buffers_dsa[i])
158 		{
159 			gl.deleteBuffers(1, &buffers_dsa[i]);
160 
161 			buffers_dsa[i] = 0;
162 		}
163 	}
164 
165 	/* Errors clean up. */
166 	while (gl.getError())
167 		;
168 
169 	/* Result's setup. */
170 	if (is_ok)
171 	{
172 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
173 	}
174 	else
175 	{
176 		if (is_error)
177 		{
178 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
179 		}
180 		else
181 		{
182 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
183 		}
184 	}
185 
186 	return STOP;
187 }
188 
189 /******************************** Data Test Implementation   ********************************/
190 
191 /** @brief Data Test constructor.
192  *
193  *  @param [in] context     OpenGL context.
194  */
DataTest(deqp::Context & context)195 DataTest::DataTest(deqp::Context& context)
196 	: deqp::TestCase(context, "buffers_data", "Buffer Objects Data Test")
197 	, m_pNamedBufferData(DE_NULL)
198 	, m_pNamedBufferSubData(DE_NULL)
199 	, m_pNamedBufferStorage(DE_NULL)
200 	, m_pCopyNamedBufferSubData(DE_NULL)
201 {
202 	/* Intentionally left blank. */
203 }
204 
205 /** @brief Iterate Data Test cases.
206  *
207  *  @return Iteration result.
208  */
iterate()209 tcu::TestNode::IterateResult DataTest::iterate()
210 {
211 	/* Shortcut for GL functionality. */
212 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
213 
214 	/* Get context setup. */
215 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
216 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
217 
218 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
219 	{
220 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
221 
222 		return STOP;
223 	}
224 
225 	/* Running tests. */
226 	bool is_ok	= true;
227 	bool is_error = false;
228 
229 	m_pNamedBufferData		  = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
230 	m_pNamedBufferSubData	 = (PFNGLNAMEDBUFFERSUBDATA)gl.namedBufferSubData;
231 	m_pNamedBufferStorage	 = (PFNGLNAMEDBUFFERSTORAGE)gl.namedBufferStorage;
232 	m_pCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATA)gl.copyNamedBufferSubData;
233 
234 	try
235 	{
236 		if ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pNamedBufferSubData) ||
237 			(DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pCopyNamedBufferSubData))
238 		{
239 			throw 0;
240 		}
241 
242 		/* BufferData tests */
243 		static const glw::GLenum hints[] = { GL_STREAM_DRAW,  GL_STREAM_READ,  GL_STREAM_COPY,
244 											 GL_STATIC_DRAW,  GL_STATIC_READ,  GL_STATIC_COPY,
245 											 GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, GL_DYNAMIC_COPY };
246 		static const glw::GLuint hints_count = sizeof(hints) / sizeof(hints[0]);
247 
248 		for (glw::GLuint i = 0; i < hints_count; ++i)
249 		{
250 			is_ok &= TestCase(&DataTest::UploadUsingNamedBufferData, hints[i]);
251 			is_ok &= TestCase(&DataTest::UploadUsingNamedBufferSubData, hints[i]);
252 			is_ok &= TestCase(&DataTest::UploadUsingCopyNamedBufferSubData, hints[i]);
253 		}
254 
255 		/* BufferStorage Tests */
256 		static const glw::GLenum bits[] = { GL_MAP_READ_BIT | GL_DYNAMIC_STORAGE_BIT,
257 											GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT,
258 											GL_MAP_READ_BIT | GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT,
259 											GL_MAP_READ_BIT | GL_CLIENT_STORAGE_BIT };
260 		static const glw::GLuint bits_count = sizeof(bits) / sizeof(bits[0]);
261 
262 		for (glw::GLuint i = 0; i < bits_count; ++i)
263 		{
264 			is_ok &= TestCase(&DataTest::UploadUsingNamedBufferStorage, bits[i]);
265 		}
266 	}
267 	catch (...)
268 	{
269 		is_ok	= false;
270 		is_error = true;
271 	}
272 
273 	/* Errors clean up. */
274 	while (gl.getError())
275 		;
276 
277 	/* Result's setup. */
278 	if (is_ok)
279 	{
280 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
281 	}
282 	else
283 	{
284 		if (is_error)
285 		{
286 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
287 		}
288 		else
289 		{
290 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
291 		}
292 	}
293 
294 	return STOP;
295 }
296 
297 /** @brief Data uploading test case function.
298  *
299  *  @param [in] UploadDataFunction      Function pointer to the tested data uploading function.
300  *  @param [in] parameter               Storage Parameter to be used with the function (function dependent).
301  *
302  *  @return True if test case succeeded, false otherwise.
303  */
TestCase(void (DataTest::* UploadDataFunction)(glw::GLuint,glw::GLenum),glw::GLenum parameter)304 bool DataTest::TestCase(void (DataTest::*UploadDataFunction)(glw::GLuint, glw::GLenum), glw::GLenum parameter)
305 {
306 	/* Shortcut for GL functionality. */
307 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
308 
309 	glw::GLuint buffer   = 0;
310 	bool		is_ok	= true;
311 	bool		is_error = false;
312 
313 	try
314 	{
315 		gl.createBuffers(1, &buffer);
316 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
317 
318 		(this->*UploadDataFunction)(buffer, parameter);
319 
320 		gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
321 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer failed.");
322 
323 		glw::GLuint* data = (glw::GLuint*)gl.mapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
324 		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer failed.");
325 
326 		is_ok = compare(data, s_reference, s_reference_count);
327 
328 		if (!is_ok)
329 		{
330 			LogFail(UploadDataFunction, parameter, data, s_reference, s_reference_count);
331 		}
332 
333 		gl.unmapBuffer(GL_ARRAY_BUFFER);
334 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer failed.");
335 	}
336 	catch (...)
337 	{
338 		is_ok	= false;
339 		is_error = true;
340 
341 		LogError(UploadDataFunction, parameter);
342 	}
343 
344 	if (buffer)
345 	{
346 		gl.deleteBuffers(1, &buffer);
347 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
348 	}
349 
350 	if (is_error)
351 	{
352 		throw 0;
353 	}
354 
355 	return is_ok;
356 }
357 
358 /** @brief NamedBufferData data upload function.
359  *
360  *  @param [in] id                      Buffer id to be uploaded.
361  *  @param [in] parameter               Storage Parameter to be used with the function, one of:
362  *                                       -  GL_STREAM_DRAW,
363  *                                       -  GL_STREAM_READ,
364  *                                       -  GL_STREAM_COPY,
365  *                                       -  GL_STATIC_DRAW,
366  *                                       -  GL_STATIC_READ,
367  *                                       -  GL_STATIC_COPY,
368  *                                       -  GL_DYNAMIC_DRAW,
369  *                                       -  GL_DYNAMIC_READ and
370  *                                       -  GL_DYNAMIC_COPY.
371  */
UploadUsingNamedBufferData(glw::GLuint id,glw::GLenum parameter)372 void DataTest::UploadUsingNamedBufferData(glw::GLuint id, glw::GLenum parameter)
373 {
374 	/* Shortcut for GL functionality. */
375 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
376 
377 	m_pNamedBufferData(id, s_reference_size, s_reference, parameter);
378 	GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");
379 }
380 
381 /** @brief NamedBufferSubData data upload function.
382  *
383  *  @param [in] id                      Buffer id to be uploaded.
384  *  @param [in] parameter               Storage parameter to be used with the NamedBufferData for
385  *                                      the storage allocation (before call to NamedBufferSubData), one of:
386  *                                       -  GL_STREAM_DRAW,
387  *                                       -  GL_STREAM_READ,
388  *                                       -  GL_STREAM_COPY,
389  *                                       -  GL_STATIC_DRAW,
390  *                                       -  GL_STATIC_READ,
391  *                                       -  GL_STATIC_COPY,
392  *                                       -  GL_DYNAMIC_DRAW,
393  *                                       -  GL_DYNAMIC_READ and
394  *                                       -  GL_DYNAMIC_COPY.
395  */
UploadUsingNamedBufferSubData(glw::GLuint id,glw::GLenum parameter)396 void DataTest::UploadUsingNamedBufferSubData(glw::GLuint id, glw::GLenum parameter)
397 {
398 	/* Shortcut for GL functionality. */
399 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
400 
401 	m_pNamedBufferData(id, s_reference_size, DE_NULL, parameter);
402 	GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");
403 
404 	m_pNamedBufferSubData(id, 0, s_reference_size, s_reference);
405 	GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferSubData failed.");
406 }
407 
408 /** @brief NamedBufferStorage data upload function.
409  *
410  *  @param [in] id                      Buffer id to be uploaded.
411  *  @param [in] parameter               Storage Parameter to be used with the function, one of:
412  *                                       - GL_MAP_READ_BIT | GL_DYNAMIC_STORAGE_BIT,
413  *                                       - GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
414  *                                       - GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT,
415  *                                       - GL_MAP_READ_BIT | GL_MAP_COHERENT_BIT,
416  *                                       - GL_MAP_READ_BIT | GL_CLIENT_STORAGE_BIT
417  */
UploadUsingNamedBufferStorage(glw::GLuint id,glw::GLenum parameter)418 void DataTest::UploadUsingNamedBufferStorage(glw::GLuint id, glw::GLenum parameter)
419 {
420 	/* Shortcut for GL functionality. */
421 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
422 
423 	m_pNamedBufferStorage(id, s_reference_size, s_reference, parameter);
424 	GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferStorage failed.");
425 }
426 
427 /** @brief CopyNamedBufferSubData data upload function (uses auxiliary buffer object).
428  *
429  *  @param [in] id                      Buffer id to be uploaded.
430  *  @param [in] parameter               Storage parameter to be used with the NamedBufferData for
431  *                                      the auxiliary buffer object storage allocation
432  *                                      (before call to CopyNamedBufferSubData), one of:
433  *                                       -  GL_STREAM_DRAW,
434  *                                       -  GL_STREAM_READ,
435  *                                       -  GL_STREAM_COPY,
436  *                                       -  GL_STATIC_DRAW,
437  *                                       -  GL_STATIC_READ,
438  *                                       -  GL_STATIC_COPY,
439  *                                       -  GL_DYNAMIC_DRAW,
440  *                                       -  GL_DYNAMIC_READ and
441  *                                       -  GL_DYNAMIC_COPY.
442  */
UploadUsingCopyNamedBufferSubData(glw::GLuint id,glw::GLenum parameter)443 void DataTest::UploadUsingCopyNamedBufferSubData(glw::GLuint id, glw::GLenum parameter)
444 {
445 	/* Shortcut for GL functionality. */
446 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
447 
448 	m_pNamedBufferData(id, s_reference_size, DE_NULL, parameter);
449 	GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");
450 
451 	glw::GLuint auxiliary_buffer	   = 0;
452 	bool		auxiliary_buffer_is_ok = true;
453 
454 	try
455 	{
456 		gl.genBuffers(1, &auxiliary_buffer);
457 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers failed.");
458 
459 		gl.bindBuffer(GL_ARRAY_BUFFER, auxiliary_buffer);
460 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer failed.");
461 
462 		gl.bufferData(GL_ARRAY_BUFFER, s_reference_size, s_reference, parameter);
463 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData failed.");
464 
465 		m_pCopyNamedBufferSubData(auxiliary_buffer, id, 0, 0, s_reference_size);
466 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyNamedBufferSubData failed.");
467 	}
468 	catch (...)
469 	{
470 		auxiliary_buffer_is_ok = false;
471 	}
472 
473 	if (auxiliary_buffer)
474 	{
475 		gl.deleteBuffers(1, &auxiliary_buffer);
476 	}
477 
478 	if (!auxiliary_buffer_is_ok)
479 	{
480 		throw 0;
481 	}
482 }
483 
484 /** @brief Compare two unsigned integer arrays.
485  *
486  *  @param [in] data                    Data to be compared.
487  *  @param [in] reference               Reference data to be compared to.
488  *  @param [in] count                   Number of elements to be compared.
489  *
490  *  @return True if count of data the elements are equal to reference counterparts, false otherwise.
491  */
compare(const glw::GLuint * data,const glw::GLuint * reference,const glw::GLsizei count)492 bool DataTest::compare(const glw::GLuint* data, const glw::GLuint* reference, const glw::GLsizei count)
493 {
494 	for (glw::GLsizei i = 0; i < count; ++i)
495 	{
496 		if (data[i] != reference[i])
497 		{
498 			return false;
499 		}
500 	}
501 	return true;
502 }
503 
504 /** @brief Prepare error message and log it.
505  *
506  *  @param [in] UploadDataFunction      Upload function pointer which have failed, one of:
507  *                                       -  DataTest::UploadUsingNamedBufferData,
508  *                                       -  DataTest::UploadUsingNamedBufferSubData
509  *                                       -  DataTest::UploadUsingNamedBufferStorage and
510  *                                       -  DataTest::UploadUsingCopyNamedBufferSubData.
511  *  @param [in] parameter               Parameter which was passed to function.
512  *  @param [in] data                    Data which was downloaded.
513  *  @param [in] reference               Reference data.
514  *  @param [in] count                   Number of elements compared.
515  */
LogFail(void (DataTest::* UploadDataFunction)(glw::GLuint,glw::GLenum),glw::GLenum parameter,const glw::GLuint * data,const glw::GLuint * reference,const glw::GLsizei count)516 void DataTest::LogFail(void (DataTest::*UploadDataFunction)(glw::GLuint, glw::GLenum), glw::GLenum parameter,
517 					   const glw::GLuint* data, const glw::GLuint* reference, const glw::GLsizei count)
518 {
519 	std::string the_log = "The test of ";
520 
521 	if (UploadDataFunction == &DataTest::UploadUsingNamedBufferData)
522 	{
523 		the_log.append("glNamedBufferData");
524 	}
525 	else
526 	{
527 		if (UploadDataFunction == &DataTest::UploadUsingNamedBufferSubData)
528 		{
529 			the_log.append("glNamedBufferSubData");
530 		}
531 		else
532 		{
533 			if (UploadDataFunction == &DataTest::UploadUsingNamedBufferStorage)
534 			{
535 				the_log.append("glNamedBufferStorage");
536 			}
537 			else
538 			{
539 				if (UploadDataFunction == &DataTest::UploadUsingCopyNamedBufferSubData)
540 				{
541 					the_log.append("glCopyNamedBufferSubData");
542 				}
543 				else
544 				{
545 					the_log.append("uknown upload function");
546 				}
547 			}
548 		}
549 	}
550 
551 	if (UploadDataFunction == &DataTest::UploadUsingNamedBufferStorage)
552 	{
553 		the_log.append(" called with usage parameter ");
554 
555 		std::stringstream bitfield_string_stream;
556 		bitfield_string_stream << glu::getBufferMapFlagsStr(parameter);
557 		the_log.append(bitfield_string_stream.str());
558 	}
559 	else
560 	{
561 		the_log.append(" called with usage parameter ");
562 		the_log.append(glu::getUsageName(parameter));
563 	}
564 	the_log.append(". Buffer data is equal to [");
565 
566 	for (glw::GLsizei i = 0; i < count; ++i)
567 	{
568 		std::stringstream number;
569 
570 		number << data[i];
571 
572 		the_log.append(number.str());
573 
574 		if (i != count - 1)
575 		{
576 			the_log.append(", ");
577 		}
578 	}
579 
580 	the_log.append("], but [");
581 
582 	for (glw::GLsizei i = 0; i < count; ++i)
583 	{
584 		std::stringstream number;
585 
586 		number << reference[i];
587 
588 		the_log.append(number.str());
589 
590 		if (i != count - 1)
591 		{
592 			the_log.append(", ");
593 		}
594 	}
595 
596 	the_log.append("] was expected.");
597 
598 	m_context.getTestContext().getLog() << tcu::TestLog::Message << the_log << tcu::TestLog::EndMessage;
599 }
600 
LogError(void (DataTest::* UploadDataFunction)(glw::GLuint,glw::GLenum),glw::GLenum parameter)601 void DataTest::LogError(void (DataTest::*UploadDataFunction)(glw::GLuint, glw::GLenum), glw::GLenum parameter)
602 {
603 	std::string the_log = "Unexpected error occurred during the test of ";
604 
605 	if (UploadDataFunction == &DataTest::UploadUsingNamedBufferData)
606 	{
607 		the_log.append("glNamedBufferData");
608 	}
609 	else
610 	{
611 		if (UploadDataFunction == &DataTest::UploadUsingNamedBufferSubData)
612 		{
613 			the_log.append("glNamedBufferSubData");
614 		}
615 		else
616 		{
617 			if (UploadDataFunction == &DataTest::UploadUsingNamedBufferStorage)
618 			{
619 				the_log.append("glNamedBufferStorage");
620 			}
621 			else
622 			{
623 				if (UploadDataFunction == &DataTest::UploadUsingCopyNamedBufferSubData)
624 				{
625 					the_log.append("glCopyNamedBufferSubData");
626 				}
627 				else
628 				{
629 					the_log.append("uknown upload function");
630 				}
631 			}
632 		}
633 	}
634 
635 	if (UploadDataFunction == &DataTest::UploadUsingNamedBufferStorage)
636 	{
637 		the_log.append(" called with usage parameter ");
638 
639 		std::stringstream bitfield_string_stream;
640 		bitfield_string_stream << glu::getBufferMapFlagsStr(parameter);
641 		the_log.append(bitfield_string_stream.str());
642 	}
643 	else
644 	{
645 		the_log.append(" called with usage parameter ");
646 		the_log.append(glu::getUsageName(parameter));
647 	}
648 	the_log.append(".");
649 
650 	m_context.getTestContext().getLog() << tcu::TestLog::Message << the_log << tcu::TestLog::EndMessage;
651 }
652 
653 const glw::GLuint DataTest::s_reference[] = {
654 	0, 1, 2, 4, 8, 16, 64, 128, 256, 512, 1024, 2048, 4096
655 };																	 //!< Reference data.
656 const glw::GLsizei DataTest::s_reference_size = sizeof(s_reference); //!< Size of the reference data.
657 const glw::GLsizei DataTest::s_reference_count =
658 	s_reference_size / sizeof(s_reference[0]); //!< NUmber of elements of the reference data.
659 
660 /******************************** Clear Test Implementation   ********************************/
661 
662 /** @brief Data Test constructor.
663  *
664  *  @param [in] context     OpenGL context.
665  */
ClearTest(deqp::Context & context)666 ClearTest::ClearTest(deqp::Context& context)
667 	: deqp::TestCase(context, "buffers_clear", "Buffer Objects Clear Test")
668 	, m_pNamedBufferData(DE_NULL)
669 	, m_pClearNamedBufferData(DE_NULL)
670 	, m_pClearNamedBufferSubData(DE_NULL)
671 {
672 	/* Intentionally left blank. */
673 }
674 
675 /** @brief ClearNamedBufferData wrapper implementation.
676  *
677  *  @note USE_SUB_DATA == false, so ClearNamedBufferData will be used.
678  *
679  *  @param [in] buffer                  ID of the buffer to be cleared.
680  *  @param [in] internalformat          GL internal format for clearing, one of the listed in test class description.
681  *  @param [in] size                    Size of the data.
682  *  @param [in] format                  GL Format of the data.
683  *  @param [in] type                    GL Type of the data element.
684  *  @param [in] data                    Data to be cleared with.
685  */
686 template <>
ClearNamedBuffer(glw::GLuint buffer,glw::GLenum internalformat,glw::GLsizei size,glw::GLenum format,glw::GLenum type,glw::GLvoid * data)687 void ClearTest::ClearNamedBuffer<false>(glw::GLuint buffer, glw::GLenum internalformat, glw::GLsizei size,
688 										glw::GLenum format, glw::GLenum type, glw::GLvoid* data)
689 {
690 	(void)size;
691 	/* Shortcut for GL functionality. */
692 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
693 
694 	m_pClearNamedBufferData(buffer, internalformat, format, type, data);
695 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearNamedBufferData failed.");
696 }
697 
698 /** @brief ClearNamedBufferSubData wrapper implementation.
699  *
700  *  @note USE_SUB_DATA == true, so ClearNamedBufferSubData will be used.
701  *
702  *  @param [in] buffer                  ID of the buffer to be cleared.
703  *  @param [in] internalformat          GL internal format for clearing, one of the listed in test class description.
704  *  @param [in] size                    Size of the data.
705  *  @param [in] format                  GL Format of the data.
706  *  @param [in] type                    GL Type of the data element.
707  *  @param [in] data                    Data to be cleared with.
708  */
709 template <>
ClearNamedBuffer(glw::GLuint buffer,glw::GLenum internalformat,glw::GLsizei size,glw::GLenum format,glw::GLenum type,glw::GLvoid * data)710 void ClearTest::ClearNamedBuffer<true>(glw::GLuint buffer, glw::GLenum internalformat, glw::GLsizei size,
711 									   glw::GLenum format, glw::GLenum type, glw::GLvoid* data)
712 {
713 	/* Shortcut for GL functionality. */
714 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
715 
716 	m_pClearNamedBufferSubData(buffer, internalformat, 0, size, format, type, data);
717 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearNamedBufferData failed.");
718 }
719 
720 /** @brief Compare two arrays with elements of type T == GLfloat (specialized).
721  *
722  *  @param [in] data                    Data to be compared.
723  *  @param [in] reference               Reference data to be compared to.
724  *  @param [in] count                   Number of elements to be compared.
725  *
726  *  @return True if count of data the elements are equal to reference counterparts, false otherwise.
727  */
728 template <>
Compare(const glw::GLfloat * data,const glw::GLfloat * reference,const glw::GLsizei count)729 bool ClearTest::Compare<glw::GLfloat>(const glw::GLfloat* data, const glw::GLfloat* reference, const glw::GLsizei count)
730 {
731 	for (glw::GLsizei i = 0; i < count; ++i)
732 	{
733 		if (de::abs(data[i] - reference[i]) > 0.00001 /* Precision. */)
734 		{
735 			return false;
736 		}
737 	}
738 	return true;
739 }
740 
741 /** @brief Compare two arrays with elements of type T.
742  *
743  *  @tparam     T                       Type of data to be compared (anything which is not GLfloat.
744  *                                      Floating point numbers have another specialized implementation,
745  *                                      which accounts the precision issues.
746  *
747  *  @param [in] data                    Data to be compared.
748  *  @param [in] reference               Reference data to be compared to.
749  *  @param [in] count                   Number of elements to be compared.
750  *
751  *  @return True if count of data the elements are equal to reference counterparts, false otherwise.
752  */
753 template <typename T>
Compare(const T * data,const T * reference,const glw::GLsizei count)754 bool ClearTest::Compare(const T* data, const T* reference, const glw::GLsizei count)
755 {
756 	for (glw::GLsizei i = 0; i < count; ++i)
757 	{
758 		if (data[i] != reference[i])
759 		{
760 			return false;
761 		}
762 	}
763 	return true;
764 }
765 
766 /** @brief Prepare error message and log it.
767  *
768  *  @tparam     T                       Type of data to which was tested.
769  *
770  *  @param [in] internalformat          Internal format used for clearing, one of the listed in test class description.
771  *  @param [in] data                    Data which was used for clear test.
772  *  @param [in] reference               Reference data.
773  *  @param [in] count                   Number of elements to be compared.
774  */
775 template <typename T>
LogFail(bool use_sub_data,glw::GLenum internalformat,const T * data,const T * reference,const glw::GLsizei count)776 void ClearTest::LogFail(bool use_sub_data, glw::GLenum internalformat, const T* data, const T* reference,
777 						const glw::GLsizei count)
778 {
779 	(void)internalformat;
780 	std::string the_log = "The test of ";
781 
782 	if (use_sub_data)
783 	{
784 		the_log.append("ClearNamedBufferSubData has failed for internalformat ");
785 	}
786 	else
787 	{
788 		the_log.append("ClearNamedBufferData has failed for internalformat ");
789 	}
790 
791 	//the_log.append(glu::getPixelFormatName(internalformat));
792 	the_log.append(". Cleared buffer data is equal to [");
793 
794 	for (glw::GLsizei i = 0; i < count; ++i)
795 	{
796 		std::stringstream number;
797 
798 		number << data[i];
799 
800 		the_log.append(number.str());
801 
802 		if (i != count - 1)
803 		{
804 			the_log.append(", ");
805 		}
806 	}
807 
808 	the_log.append("], but [");
809 
810 	for (glw::GLsizei i = 0; i < count; ++i)
811 	{
812 		std::stringstream number;
813 
814 		number << reference[i];
815 
816 		the_log.append(number.str());
817 
818 		if (i != count - 1)
819 		{
820 			the_log.append(", ");
821 		}
822 	}
823 
824 	the_log.append("] was expected.");
825 
826 	m_context.getTestContext().getLog() << tcu::TestLog::Message << the_log << tcu::TestLog::EndMessage;
827 }
828 
LogError(bool use_sub_data,glw::GLenum internalformat)829 void ClearTest::LogError(bool use_sub_data, glw::GLenum internalformat)
830 {
831 	(void)internalformat;
832 	std::string the_log = "Unexpected error occurred during Test of ";
833 
834 	if (use_sub_data)
835 	{
836 		the_log.append("ClearNamedBufferSubData with internalformat ");
837 	}
838 	else
839 	{
840 		the_log.append("ClearNamedBufferData with internalformat ");
841 	}
842 
843 	//the_log.append(glu::getPixelFormatName(internalformat));
844 
845 	m_context.getTestContext().getLog() << tcu::TestLog::Message << the_log << tcu::TestLog::EndMessage;
846 }
847 
848 /** @brief Run CLearing test case.
849  *
850  *  @tparam     T                       Type of data to which to be tested.
851  *  @tparam     USE_SUB_DATA            If true ClearNamedBufferSubData will be used, ClearNamedBufferData otherwise.
852  *
853  *  @param [in] internalformat          Internal format used for clearing, one of the listed in test class description.
854  *  @param [in] count                   Number of elements.
855  *  @param [in] internalformat          Data format to be used for clearing.
856  *  @param [in] data                    Data to be used with clear test.
857  *
858  *  @return True if test case succeeded, false otherwise.
859  */
860 template <typename T, bool USE_SUB_DATA>
TestClearNamedBufferData(glw::GLenum internalformat,glw::GLsizei count,glw::GLenum format,glw::GLenum type,T * data)861 bool ClearTest::TestClearNamedBufferData(glw::GLenum internalformat, glw::GLsizei count, glw::GLenum format,
862 										 glw::GLenum type, T* data)
863 {
864 	/* Shortcut for GL functionality. */
865 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
866 
867 	glw::GLuint buffer   = 0;
868 	bool		is_ok	= true;
869 	bool		is_error = false;
870 
871 	try
872 	{
873 		gl.createBuffers(1, &buffer);
874 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
875 
876 		m_pNamedBufferData(buffer, static_cast<glw::GLsizei>(count * sizeof(T)), NULL, GL_DYNAMIC_COPY);
877 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");
878 
879 		ClearNamedBuffer<USE_SUB_DATA>(buffer, internalformat, static_cast<glw::GLsizei>(count * sizeof(T)), format,
880 									   type, data);
881 
882 		gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
883 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer failed.");
884 
885 		T* _data = (T*)gl.mapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
886 		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer failed.");
887 
888 		is_ok = Compare<T>(_data, data, count);
889 
890 		if (!is_ok)
891 		{
892 			/* Log. */
893 			LogFail<T>(USE_SUB_DATA, internalformat, _data, data, count);
894 		}
895 
896 		gl.unmapBuffer(GL_ARRAY_BUFFER);
897 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer failed.");
898 	}
899 	catch (...)
900 	{
901 		is_ok	= false;
902 		is_error = true;
903 
904 		LogError(USE_SUB_DATA, internalformat);
905 	}
906 
907 	if (buffer)
908 	{
909 		gl.deleteBuffers(1, &buffer);
910 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
911 	}
912 
913 	if (is_error)
914 	{
915 		throw 0;
916 	}
917 
918 	return is_ok;
919 }
920 
921 /** @brief Iterate Data Test cases.
922  *
923  *  @return Iteration result.
924  */
iterate()925 tcu::TestNode::IterateResult ClearTest::iterate()
926 {
927 	/* Shortcut for GL functionality. */
928 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
929 
930 	/* Get context setup. */
931 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
932 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
933 
934 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
935 	{
936 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
937 
938 		return STOP;
939 	}
940 
941 	/* Running tests. */
942 	bool is_ok	= true;
943 	bool is_error = false;
944 
945 	m_pNamedBufferData		   = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
946 	m_pClearNamedBufferData	= (PFNGLCLEARNAMEDBUFFERDATA)gl.clearNamedBufferData;
947 	m_pClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATA)gl.clearNamedBufferSubData;
948 
949 	try
950 	{
951 		if ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pClearNamedBufferData) ||
952 			(DE_NULL == m_pClearNamedBufferSubData))
953 		{
954 			throw 0;
955 		}
956 
957 		{
958 			/* unsigned byte norm component ClearNamedBufferData tests */
959 			glw::GLubyte reference[4] = { 5, 1, 2, 3 };
960 
961 			is_ok &= TestClearNamedBufferData<glw::GLubyte, false>(GL_R8, 1, GL_RED, GL_UNSIGNED_BYTE, reference);
962 			is_ok &= TestClearNamedBufferData<glw::GLubyte, false>(GL_RG8, 2, GL_RG, GL_UNSIGNED_BYTE, reference);
963 			is_ok &= TestClearNamedBufferData<glw::GLubyte, false>(GL_RGBA8, 4, GL_RGBA, GL_UNSIGNED_BYTE, reference);
964 
965 			/* unsigned byte norm component ClearNamedBufferSubData tests */
966 			is_ok &= TestClearNamedBufferData<glw::GLubyte, true>(GL_R8, 1, GL_RED, GL_UNSIGNED_BYTE, reference);
967 			is_ok &= TestClearNamedBufferData<glw::GLubyte, true>(GL_RG8, 2, GL_RG, GL_UNSIGNED_BYTE, reference);
968 			is_ok &= TestClearNamedBufferData<glw::GLubyte, true>(GL_RGBA8, 4, GL_RGBA, GL_UNSIGNED_BYTE, reference);
969 
970 			/* unsigned byte component ClearNamedBufferData tests */
971 			is_ok &= TestClearNamedBufferData<glw::GLubyte, false>(GL_R8UI, 1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, reference);
972 			is_ok &= TestClearNamedBufferData<glw::GLubyte, false>(GL_RG8UI, 2, GL_RG_INTEGER, GL_UNSIGNED_BYTE, reference);
973 			is_ok &= TestClearNamedBufferData<glw::GLubyte, false>(GL_RGBA8UI, 4, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, reference);
974 
975 			/* unsigned byte component ClearNamedBufferSubData tests */
976 			is_ok &= TestClearNamedBufferData<glw::GLubyte, true>(GL_R8UI, 1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, reference);
977 			is_ok &= TestClearNamedBufferData<glw::GLubyte, true>(GL_RG8UI, 2, GL_RG_INTEGER, GL_UNSIGNED_BYTE, reference);
978 			is_ok &= TestClearNamedBufferData<glw::GLubyte, true>(GL_RGBA8UI, 4, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, reference);
979 		}
980 
981 		{
982 			/* signed byte component ClearNamedBufferData tests */
983 			glw::GLbyte reference[4] = { 5, 1, -2, 3 };
984 
985 			is_ok &= TestClearNamedBufferData<glw::GLbyte, false>(GL_R8I, 1, GL_RED_INTEGER, GL_BYTE, reference);
986 			is_ok &= TestClearNamedBufferData<glw::GLbyte, false>(GL_RG8I, 2, GL_RG_INTEGER, GL_BYTE, reference);
987 			is_ok &= TestClearNamedBufferData<glw::GLbyte, false>(GL_RGBA8I, 4, GL_RGBA_INTEGER, GL_BYTE, reference);
988 
989 			/* signed byte component ClearNamedBufferSubData tests */
990 			is_ok &= TestClearNamedBufferData<glw::GLbyte, true>(GL_R8I, 1, GL_RED_INTEGER, GL_BYTE, reference);
991 			is_ok &= TestClearNamedBufferData<glw::GLbyte, true>(GL_RG8I, 2, GL_RG_INTEGER, GL_BYTE, reference);
992 			is_ok &= TestClearNamedBufferData<glw::GLbyte, true>(GL_RGBA8I, 4, GL_RGBA_INTEGER, GL_BYTE, reference);
993 		}
994 
995 		{
996 			/* unsigned short norm component ClearNamedBufferData tests */
997 			glw::GLushort reference[4] = { 5, 1, 2, 3 };
998 
999 			is_ok &= TestClearNamedBufferData<glw::GLushort, false>(GL_R16, 1, GL_RED, GL_UNSIGNED_SHORT, reference);
1000 			is_ok &= TestClearNamedBufferData<glw::GLushort, false>(GL_RG16, 2, GL_RG, GL_UNSIGNED_SHORT, reference);
1001 			is_ok &=
1002 				TestClearNamedBufferData<glw::GLushort, false>(GL_RGBA16, 4, GL_RGBA, GL_UNSIGNED_SHORT, reference);
1003 
1004 			/* unsigned short norm component ClearNamedBufferSubData tests */
1005 			is_ok &= TestClearNamedBufferData<glw::GLushort, true>(GL_R16, 1, GL_RED, GL_UNSIGNED_SHORT, reference);
1006 			is_ok &= TestClearNamedBufferData<glw::GLushort, true>(GL_RG16, 2, GL_RG, GL_UNSIGNED_SHORT, reference);
1007 			is_ok &= TestClearNamedBufferData<glw::GLushort, true>(GL_RGBA16, 4, GL_RGBA, GL_UNSIGNED_SHORT, reference);
1008 
1009 			/* unsigned short component ClearNamedBufferData tests */
1010 			is_ok &= TestClearNamedBufferData<glw::GLushort, false>(GL_R16UI, 1, GL_RED_INTEGER, GL_UNSIGNED_SHORT, reference);
1011 			is_ok &= TestClearNamedBufferData<glw::GLushort, false>(GL_RG16UI, 2, GL_RG_INTEGER, GL_UNSIGNED_SHORT, reference);
1012 			is_ok &=
1013 				TestClearNamedBufferData<glw::GLushort, false>(GL_RGBA16UI, 4, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, reference);
1014 
1015 			/* unsigned short component ClearNamedBufferSubData tests */
1016 			is_ok &= TestClearNamedBufferData<glw::GLushort, true>(GL_R16UI, 1, GL_RED_INTEGER, GL_UNSIGNED_SHORT, reference);
1017 			is_ok &= TestClearNamedBufferData<glw::GLushort, true>(GL_RG16UI, 2, GL_RG_INTEGER, GL_UNSIGNED_SHORT, reference);
1018 			is_ok &=
1019 				TestClearNamedBufferData<glw::GLushort, true>(GL_RGBA16UI, 4, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, reference);
1020 		}
1021 
1022 		{
1023 			/* signed short component ClearNamedBufferData tests */
1024 			glw::GLshort reference[4] = { 5, 1, -2, 3 };
1025 
1026 			is_ok &= TestClearNamedBufferData<glw::GLshort, false>(GL_R16I, 1, GL_RED_INTEGER, GL_SHORT, reference);
1027 			is_ok &= TestClearNamedBufferData<glw::GLshort, false>(GL_RG16I, 2, GL_RG_INTEGER, GL_SHORT, reference);
1028 			is_ok &= TestClearNamedBufferData<glw::GLshort, false>(GL_RGBA16I, 4, GL_RGBA_INTEGER, GL_SHORT, reference);
1029 
1030 			/* signed short component ClearNamedBufferSubData tests */
1031 			is_ok &= TestClearNamedBufferData<glw::GLshort, true>(GL_R16I, 1, GL_RED_INTEGER, GL_SHORT, reference);
1032 			is_ok &= TestClearNamedBufferData<glw::GLshort, true>(GL_RG16I, 2, GL_RG_INTEGER, GL_SHORT, reference);
1033 			is_ok &= TestClearNamedBufferData<glw::GLshort, true>(GL_RGBA16I, 4, GL_RGBA_INTEGER, GL_SHORT, reference);
1034 		}
1035 
1036 		{
1037 			/* unsigned int component ClearNamedBufferData tests */
1038 			glw::GLuint reference[4] = { 5, 1, 2, 3 };
1039 
1040 			is_ok &= TestClearNamedBufferData<glw::GLuint, false>(GL_R32UI, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, reference);
1041 			is_ok &= TestClearNamedBufferData<glw::GLuint, false>(GL_RG32UI, 2, GL_RG_INTEGER, GL_UNSIGNED_INT, reference);
1042 			is_ok &= TestClearNamedBufferData<glw::GLuint, false>(GL_RGB32UI, 3, GL_RGB_INTEGER, GL_UNSIGNED_INT, reference);
1043 			is_ok &= TestClearNamedBufferData<glw::GLuint, false>(GL_RGBA32UI, 4, GL_RGBA_INTEGER, GL_UNSIGNED_INT, reference);
1044 
1045 			/* unsigned int component ClearNamedBufferSubData tests */
1046 			is_ok &= TestClearNamedBufferData<glw::GLuint, true>(GL_R32UI, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, reference);
1047 			is_ok &= TestClearNamedBufferData<glw::GLuint, true>(GL_RG32UI, 2, GL_RG_INTEGER, GL_UNSIGNED_INT, reference);
1048 			is_ok &= TestClearNamedBufferData<glw::GLuint, true>(GL_RGB32UI, 3, GL_RGB_INTEGER, GL_UNSIGNED_INT, reference);
1049 			is_ok &= TestClearNamedBufferData<glw::GLuint, true>(GL_RGBA32UI, 4, GL_RGBA_INTEGER, GL_UNSIGNED_INT, reference);
1050 		}
1051 
1052 		{
1053 			/* signed int component ClearNamedBufferData tests */
1054 			glw::GLint reference[4] = { 5, 1, -2, 3 };
1055 
1056 			is_ok &= TestClearNamedBufferData<glw::GLint, false>(GL_R32I, 1, GL_RED_INTEGER, GL_INT, reference);
1057 			is_ok &= TestClearNamedBufferData<glw::GLint, false>(GL_RG32I, 2, GL_RG_INTEGER, GL_INT, reference);
1058 			is_ok &= TestClearNamedBufferData<glw::GLint, false>(GL_RGB32I, 3, GL_RGB_INTEGER, GL_INT, reference);
1059 			is_ok &= TestClearNamedBufferData<glw::GLint, false>(GL_RGBA32I, 4, GL_RGBA_INTEGER, GL_INT, reference);
1060 
1061 			/* signed int component ClearNamedBufferSubData tests */
1062 			is_ok &= TestClearNamedBufferData<glw::GLint, true>(GL_R32I, 1, GL_RED_INTEGER, GL_INT, reference);
1063 			is_ok &= TestClearNamedBufferData<glw::GLint, true>(GL_RG32I, 2, GL_RG_INTEGER, GL_INT, reference);
1064 			is_ok &= TestClearNamedBufferData<glw::GLint, true>(GL_RGB32I, 3, GL_RGB_INTEGER, GL_INT, reference);
1065 			is_ok &= TestClearNamedBufferData<glw::GLint, true>(GL_RGBA32I, 4, GL_RGBA_INTEGER, GL_INT, reference);
1066 		}
1067 
1068 		{
1069 			/* half float component ClearNamedBufferData tests */
1070 			glw::GLhalf reference[4] = { 0x3C00 /* 1.0hf */, 0x0000 /* 0.0hf */, 0xC000 /* -2.0hf */,
1071 										 0x3555 /* 0.333333333hf */ };
1072 
1073 			is_ok &= TestClearNamedBufferData<glw::GLhalf, false>(GL_R16F, 1, GL_RED, GL_HALF_FLOAT, reference);
1074 			is_ok &= TestClearNamedBufferData<glw::GLhalf, false>(GL_RG16F, 2, GL_RG, GL_HALF_FLOAT, reference);
1075 			is_ok &= TestClearNamedBufferData<glw::GLhalf, false>(GL_RGBA16F, 4, GL_RGBA, GL_HALF_FLOAT, reference);
1076 
1077 			/* half float component ClearNamedBufferSubData tests */
1078 			is_ok &= TestClearNamedBufferData<glw::GLhalf, true>(GL_R16F, 1, GL_RED, GL_HALF_FLOAT, reference);
1079 			is_ok &= TestClearNamedBufferData<glw::GLhalf, true>(GL_RG16F, 2, GL_RG, GL_HALF_FLOAT, reference);
1080 			is_ok &= TestClearNamedBufferData<glw::GLhalf, true>(GL_RGBA16F, 4, GL_RGBA, GL_HALF_FLOAT, reference);
1081 		}
1082 
1083 		{
1084 			/* float component ClearNamedBufferData tests */
1085 			glw::GLfloat reference[4] = { 1.f, 0.f, -2.f, 0.3333333333f };
1086 
1087 			is_ok &= TestClearNamedBufferData<glw::GLfloat, false>(GL_R32F, 1, GL_RED, GL_FLOAT, reference);
1088 			is_ok &= TestClearNamedBufferData<glw::GLfloat, false>(GL_RG32F, 2, GL_RG, GL_FLOAT, reference);
1089 			is_ok &= TestClearNamedBufferData<glw::GLfloat, false>(GL_RGB32F, 3, GL_RGB, GL_FLOAT, reference);
1090 			is_ok &= TestClearNamedBufferData<glw::GLfloat, false>(GL_RGBA32F, 4, GL_RGBA, GL_FLOAT, reference);
1091 
1092 			/* float component ClearNamedBufferSubData tests */
1093 			is_ok &= TestClearNamedBufferData<glw::GLfloat, true>(GL_R32F, 1, GL_RED, GL_FLOAT, reference);
1094 			is_ok &= TestClearNamedBufferData<glw::GLfloat, true>(GL_RG32F, 2, GL_RG, GL_FLOAT, reference);
1095 			is_ok &= TestClearNamedBufferData<glw::GLfloat, true>(GL_RGB32F, 3, GL_RGB, GL_FLOAT, reference);
1096 			is_ok &= TestClearNamedBufferData<glw::GLfloat, true>(GL_RGBA32F, 4, GL_RGBA, GL_FLOAT, reference);
1097 		}
1098 	}
1099 	catch (...)
1100 	{
1101 		is_ok	= false;
1102 		is_error = true;
1103 	}
1104 
1105 	/* Errors clean up. */
1106 	while (gl.getError())
1107 		;
1108 
1109 	/* Result's setup. */
1110 	if (is_ok)
1111 	{
1112 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1113 	}
1114 	else
1115 	{
1116 		if (is_error)
1117 		{
1118 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1119 		}
1120 		else
1121 		{
1122 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1123 		}
1124 	}
1125 
1126 	return STOP;
1127 }
1128 
1129 /******************************** Map Read Only Test Implementation   ********************************/
1130 
1131 /** @brief Map Read Only Test constructor.
1132  *
1133  *  @param [in] context     OpenGL context.
1134  */
MapReadOnlyTest(deqp::Context & context)1135 MapReadOnlyTest::MapReadOnlyTest(deqp::Context& context)
1136 	: deqp::TestCase(context, "buffers_map_read_only", "Buffer Objects Map Read Only Test")
1137 	, m_pNamedBufferData(DE_NULL)
1138 	, m_pMapNamedBuffer(DE_NULL)
1139 	, m_pUnmapNamedBuffer(DE_NULL)
1140 {
1141 	/* Intentionally left blank. */
1142 }
1143 
1144 /** @brief Iterate Map Read Only Test cases.
1145  *
1146  *  @return Iteration result.
1147  */
iterate()1148 tcu::TestNode::IterateResult MapReadOnlyTest::iterate()
1149 {
1150 	/* Shortcut for GL functionality. */
1151 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1152 
1153 	/* Get context setup. */
1154 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
1155 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
1156 
1157 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
1158 	{
1159 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1160 
1161 		return STOP;
1162 	}
1163 
1164 	/* Running tests. */
1165 	bool is_ok	= true;
1166 	bool is_error = false;
1167 
1168 	glw::GLuint buffer = 0;
1169 
1170 	m_pNamedBufferData  = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
1171 	m_pMapNamedBuffer   = (PFNGLMAPNAMEDBUFFER)gl.mapNamedBuffer;
1172 	m_pUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;
1173 
1174 	try
1175 	{
1176 		if ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pMapNamedBuffer) || (DE_NULL == m_pUnmapNamedBuffer))
1177 		{
1178 			throw 0;
1179 		}
1180 
1181 		/* Buffer creation. */
1182 		gl.createBuffers(1, &buffer);
1183 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
1184 
1185 		/* Buffer's storage allocation and reference data upload. */
1186 		m_pNamedBufferData(buffer, s_reference_size, s_reference, GL_DYNAMIC_COPY);
1187 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");
1188 
1189 		/* Mapping with new named buffer map function. */
1190 		glw::GLuint* data = (glw::GLuint*)m_pMapNamedBuffer(buffer, GL_READ_ONLY);
1191 		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
1192 
1193 		if (DE_NULL == data)
1194 		{
1195 			/* Log. */
1196 			m_context.getTestContext().getLog()
1197 				<< tcu::TestLog::Message << "glMapNamedBuffer returned NULL pointer, but buffer's data was expected."
1198 				<< tcu::TestLog::EndMessage;
1199 		}
1200 		else
1201 		{
1202 			/* Comparison results with reference data. */
1203 			for (glw::GLsizei i = 0; i < s_reference_count; ++i)
1204 			{
1205 				is_ok &= (data[i] == s_reference[i]);
1206 			}
1207 
1208 			if (!is_ok)
1209 			{
1210 				/* Log. */
1211 				m_context.getTestContext().getLog()
1212 					<< tcu::TestLog::Message
1213 					<< "glMapNamedBuffer returned pointer to data which is not identical to reference data."
1214 					<< tcu::TestLog::EndMessage;
1215 			}
1216 
1217 			/* Unmapping with new named buffer unmap function. */
1218 			if (GL_TRUE != m_pUnmapNamedBuffer(buffer))
1219 			{
1220 				is_ok = false;
1221 
1222 				/* Log. */
1223 				m_context.getTestContext().getLog()
1224 					<< tcu::TestLog::Message
1225 					<< "glUnmapNamedBuffer called on mapped buffer has returned GL_FALSE, but GL_TRUE was expected."
1226 					<< tcu::TestLog::EndMessage;
1227 			}
1228 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
1229 		}
1230 	}
1231 	catch (...)
1232 	{
1233 		is_ok	= false;
1234 		is_error = true;
1235 	}
1236 
1237 	/* Clean up. */
1238 	if (buffer)
1239 	{
1240 		gl.deleteBuffers(1, &buffer);
1241 
1242 		buffer = false;
1243 	}
1244 
1245 	/* Errors clean up. */
1246 	while (gl.getError())
1247 		;
1248 
1249 	/* Result's setup. */
1250 	if (is_ok)
1251 	{
1252 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1253 	}
1254 	else
1255 	{
1256 		if (is_error)
1257 		{
1258 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1259 		}
1260 		else
1261 		{
1262 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1263 		}
1264 	}
1265 
1266 	return STOP;
1267 }
1268 
1269 const glw::GLuint  MapReadOnlyTest::s_reference[]	 = { 0, 1, 2, 4, 8, 16, 64, 128, 256, 512, 1024, 2048, 4096 };
1270 const glw::GLsizei MapReadOnlyTest::s_reference_size  = sizeof(s_reference);
1271 const glw::GLsizei MapReadOnlyTest::s_reference_count = s_reference_size / sizeof(s_reference[0]);
1272 
1273 /******************************** Map Read Write Test Implementation   ********************************/
1274 
1275 /** @brief Map Read Write Test constructor.
1276  *
1277  *  @param [in] context     OpenGL context.
1278  */
MapReadWriteTest(deqp::Context & context)1279 MapReadWriteTest::MapReadWriteTest(deqp::Context& context)
1280 	: deqp::TestCase(context, "buffers_map_read_write", "Buffer Objects Map Read Write Test")
1281 	, m_pNamedBufferData(DE_NULL)
1282 	, m_pMapNamedBuffer(DE_NULL)
1283 	, m_pUnmapNamedBuffer(DE_NULL)
1284 {
1285 	/* Intentionally left blank. */
1286 }
1287 
1288 /** @brief Iterate Map Read Write Test cases.
1289  *
1290  *  @return Iteration result.
1291  */
iterate()1292 tcu::TestNode::IterateResult MapReadWriteTest::iterate()
1293 {
1294 	/* Shortcut for GL functionality. */
1295 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1296 
1297 	/* Get context setup. */
1298 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
1299 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
1300 
1301 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
1302 	{
1303 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1304 
1305 		return STOP;
1306 	}
1307 
1308 	/* Running tests. */
1309 	bool is_ok	= true;
1310 	bool is_error = false;
1311 
1312 	glw::GLuint buffer = 0;
1313 
1314 	m_pNamedBufferData  = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
1315 	m_pMapNamedBuffer   = (PFNGLMAPNAMEDBUFFER)gl.mapNamedBuffer;
1316 	m_pUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;
1317 
1318 	try
1319 	{
1320 		if ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pMapNamedBuffer) || (DE_NULL == m_pUnmapNamedBuffer))
1321 		{
1322 			throw 0;
1323 		}
1324 
1325 		/* Buffer creation. */
1326 		gl.createBuffers(1, &buffer);
1327 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
1328 
1329 		/* Buffer's storage allocation and reference data upload. */
1330 		m_pNamedBufferData(buffer, s_reference_size, s_reference, GL_DYNAMIC_COPY);
1331 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");
1332 
1333 		/* Mapping with new named buffer map function. */
1334 		glw::GLuint* data = (glw::GLuint*)m_pMapNamedBuffer(buffer, GL_READ_WRITE);
1335 		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
1336 
1337 		if (DE_NULL == data)
1338 		{
1339 			/* Log. */
1340 			m_context.getTestContext().getLog()
1341 				<< tcu::TestLog::Message << "glMapNamedBuffer returned NULL pointer, but buffer's data was expected."
1342 				<< tcu::TestLog::EndMessage;
1343 		}
1344 		else
1345 		{
1346 			/* Comparison results with reference data. */
1347 			for (glw::GLsizei i = 0; i < s_reference_count; ++i)
1348 			{
1349 				is_ok &= (data[i] == s_reference[i]);
1350 			}
1351 
1352 			if (!is_ok)
1353 			{
1354 				/* Log. */
1355 				m_context.getTestContext().getLog()
1356 					<< tcu::TestLog::Message
1357 					<< "glMapNamedBuffer returned pointer to data which is not identical to reference data."
1358 					<< tcu::TestLog::EndMessage;
1359 			}
1360 
1361 			/* Writting inverted reference data. */
1362 			for (glw::GLsizei i = 0; i < s_reference_count; ++i)
1363 			{
1364 				data[i] = s_reference[s_reference_count - i - 1];
1365 			}
1366 
1367 			/* Unmapping with new named buffer unmap function. */
1368 			if (GL_TRUE != m_pUnmapNamedBuffer(buffer))
1369 			{
1370 				is_ok = false;
1371 
1372 				/* Log. */
1373 				m_context.getTestContext().getLog()
1374 					<< tcu::TestLog::Message
1375 					<< "glUnmapNamedBuffer called on mapped buffer has returned GL_FALSE, but GL_TRUE was expected."
1376 					<< tcu::TestLog::EndMessage;
1377 			}
1378 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
1379 
1380 			data = DE_NULL;
1381 
1382 			data = (glw::GLuint*)m_pMapNamedBuffer(buffer, GL_READ_WRITE);
1383 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
1384 
1385 			if (DE_NULL == data)
1386 			{
1387 				/* Log. */
1388 				m_context.getTestContext().getLog()
1389 					<< tcu::TestLog::Message
1390 					<< "glMapNamedBuffer returned NULL pointer, but buffer's data was expected."
1391 					<< tcu::TestLog::EndMessage;
1392 			}
1393 			else
1394 			{
1395 				/* Comparison results with inverted reference data. */
1396 				for (glw::GLsizei i = 0; i < s_reference_count; ++i)
1397 				{
1398 					is_ok &= (data[i] == s_reference[s_reference_count - i - 1]);
1399 				}
1400 
1401 				/* Unmapping with new named buffer unmap function. */
1402 				if (GL_TRUE != m_pUnmapNamedBuffer(buffer))
1403 				{
1404 					is_ok = false;
1405 
1406 					/* Log. */
1407 					m_context.getTestContext().getLog()
1408 						<< tcu::TestLog::Message
1409 						<< "glUnmapNamedBuffer called on mapped buffer has returned GL_FALSE, but GL_TRUE was expected."
1410 						<< tcu::TestLog::EndMessage;
1411 				}
1412 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
1413 			}
1414 		}
1415 	}
1416 	catch (...)
1417 	{
1418 		is_ok	= false;
1419 		is_error = true;
1420 	}
1421 
1422 	/* Clean up. */
1423 	if (buffer)
1424 	{
1425 		gl.deleteBuffers(1, &buffer);
1426 
1427 		buffer = false;
1428 	}
1429 
1430 	/* Errors clean up. */
1431 	while (gl.getError())
1432 		;
1433 
1434 	/* Result's setup. */
1435 	if (is_ok)
1436 	{
1437 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1438 	}
1439 	else
1440 	{
1441 		if (is_error)
1442 		{
1443 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1444 		}
1445 		else
1446 		{
1447 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1448 		}
1449 	}
1450 
1451 	return STOP;
1452 }
1453 
1454 const glw::GLuint MapReadWriteTest::s_reference[] = {
1455 	0, 1, 2, 4, 8, 16, 64, 128, 256, 512, 1024, 2048, 4096
1456 };																			 //!< Reference data.
1457 const glw::GLsizei MapReadWriteTest::s_reference_size = sizeof(s_reference); //!< Reference data size.
1458 const glw::GLsizei MapReadWriteTest::s_reference_count =
1459 	s_reference_size / sizeof(s_reference[0]); //!< Reference data elements' count.
1460 
1461 /******************************** Map Write Only Test Implementation   ********************************/
1462 
1463 /** @brief Map Write Only Test constructor.
1464  *
1465  *  @param [in] context     OpenGL context.
1466  */
MapWriteOnlyTest(deqp::Context & context)1467 MapWriteOnlyTest::MapWriteOnlyTest(deqp::Context& context)
1468 	: deqp::TestCase(context, "buffers_map_write_only", "Buffer Objects Map Write Only Test")
1469 	, m_pNamedBufferData(DE_NULL)
1470 	, m_pMapNamedBuffer(DE_NULL)
1471 	, m_pUnmapNamedBuffer(DE_NULL)
1472 {
1473 	/* Intentionally left blank. */
1474 }
1475 
1476 /** @brief Iterate Map Write Only Test cases.
1477  *
1478  *  @return Iteration result.
1479  */
iterate()1480 tcu::TestNode::IterateResult MapWriteOnlyTest::iterate()
1481 {
1482 	/* Shortcut for GL functionality. */
1483 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1484 
1485 	/* Get context setup. */
1486 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
1487 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
1488 
1489 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
1490 	{
1491 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1492 
1493 		return STOP;
1494 	}
1495 
1496 	/* Running tests. */
1497 	bool is_ok	= true;
1498 	bool is_error = false;
1499 
1500 	glw::GLuint buffer = 0;
1501 
1502 	m_pNamedBufferData  = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
1503 	m_pMapNamedBuffer   = (PFNGLMAPNAMEDBUFFER)gl.mapNamedBuffer;
1504 	m_pUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;
1505 
1506 	try
1507 	{
1508 		if ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pMapNamedBuffer) || (DE_NULL == m_pUnmapNamedBuffer))
1509 		{
1510 			throw 0;
1511 		}
1512 
1513 		/* Buffer creation. */
1514 		gl.createBuffers(1, &buffer);
1515 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
1516 
1517 		/* Buffer's storage allocation. */
1518 		m_pNamedBufferData(buffer, s_reference_size, NULL, GL_DYNAMIC_COPY);
1519 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");
1520 
1521 		/* Mapping with new named buffer map function. */
1522 		glw::GLuint* data = (glw::GLuint*)m_pMapNamedBuffer(buffer, GL_WRITE_ONLY);
1523 		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
1524 
1525 		if (DE_NULL == data)
1526 		{
1527 			/* Log. */
1528 			m_context.getTestContext().getLog()
1529 				<< tcu::TestLog::Message << "glMapNamedBuffer returned NULL pointer, but buffer's data was expected."
1530 				<< tcu::TestLog::EndMessage;
1531 		}
1532 		else
1533 		{
1534 			/* Reference data upload. */
1535 			for (glw::GLsizei i = 0; i < s_reference_count; ++i)
1536 			{
1537 				data[i] = s_reference[i];
1538 			}
1539 
1540 			/* Unmapping with new named buffer unmap function. */
1541 			if (GL_TRUE != m_pUnmapNamedBuffer(buffer))
1542 			{
1543 				is_ok = false;
1544 
1545 				/* Log. */
1546 				m_context.getTestContext().getLog()
1547 					<< tcu::TestLog::Message
1548 					<< "glUnmapNamedBuffer called on mapped buffer has returned GL_FALSE, but GL_TRUE was expected."
1549 					<< tcu::TestLog::EndMessage;
1550 			}
1551 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
1552 
1553 			/* Mapping data, the old way. */
1554 			gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
1555 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer failed.");
1556 
1557 			data = DE_NULL;
1558 
1559 			data = (glw::GLuint*)gl.mapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
1560 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer failed.");
1561 
1562 			/* Comparison results with reference data. */
1563 			for (glw::GLsizei i = 0; i < s_reference_count; ++i)
1564 			{
1565 				is_ok &= (data[i] == s_reference[i]);
1566 			}
1567 
1568 			if (!is_ok)
1569 			{
1570 				/* Log. */
1571 				m_context.getTestContext().getLog()
1572 					<< tcu::TestLog::Message
1573 					<< "glMapNamedBuffer, called with GL_WRITE_ONLY access flag, had not stored the reference data."
1574 					<< tcu::TestLog::EndMessage;
1575 			}
1576 
1577 			gl.unmapBuffer(GL_ARRAY_BUFFER);
1578 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer failed.");
1579 		}
1580 	}
1581 	catch (...)
1582 	{
1583 		is_ok	= false;
1584 		is_error = true;
1585 	}
1586 
1587 	/* Clean up. */
1588 	if (buffer)
1589 	{
1590 		gl.deleteBuffers(1, &buffer);
1591 
1592 		buffer = false;
1593 	}
1594 
1595 	/* Errors clean up. */
1596 	while (gl.getError())
1597 		;
1598 
1599 	/* Result's setup. */
1600 	if (is_ok)
1601 	{
1602 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1603 	}
1604 	else
1605 	{
1606 		if (is_error)
1607 		{
1608 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1609 		}
1610 		else
1611 		{
1612 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1613 		}
1614 	}
1615 
1616 	return STOP;
1617 }
1618 
1619 const glw::GLuint MapWriteOnlyTest::s_reference[] = {
1620 	0, 1, 2, 4, 8, 16, 64, 128, 256, 512, 1024, 2048, 4096
1621 };																			 //!< Reference data.
1622 const glw::GLsizei MapWriteOnlyTest::s_reference_size = sizeof(s_reference); //!< Reference data size.
1623 const glw::GLsizei MapWriteOnlyTest::s_reference_count =
1624 	s_reference_size / sizeof(s_reference[0]); //!< Reference data elements' count.
1625 
1626 /******************************** Buffers Range Map Read Bit Test Implementation   ********************************/
1627 
1628 /** @brief Buffers Range Map Read Bit Test constructor.
1629  *
1630  *  @param [in] context     OpenGL context.
1631  */
MapRangeReadBitTest(deqp::Context & context)1632 MapRangeReadBitTest::MapRangeReadBitTest(deqp::Context& context)
1633 	: deqp::TestCase(context, "buffers_map_range_read_bit", "Buffer Objects Map Range Read Bit Test")
1634 	, m_pNamedBufferStorage(DE_NULL)
1635 	, m_pMapNamedBufferRange(DE_NULL)
1636 	, m_pUnmapNamedBuffer(DE_NULL)
1637 {
1638 	/* Intentionally left blank. */
1639 }
1640 
1641 /** @brief Iterate Buffers Range Map Read Bit Test cases.
1642  *
1643  *  @return Iteration result.
1644  */
iterate()1645 tcu::TestNode::IterateResult MapRangeReadBitTest::iterate()
1646 {
1647 	/* Shortcut for GL functionality. */
1648 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1649 
1650 	/* Get context setup. */
1651 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
1652 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
1653 
1654 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
1655 	{
1656 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1657 
1658 		return STOP;
1659 	}
1660 
1661 	/* Running tests. */
1662 	bool is_ok	= true;
1663 	bool is_error = false;
1664 
1665 	glw::GLuint buffer = 0;
1666 
1667 	m_pNamedBufferStorage  = (PFNGLNAMEDBUFFERSTORAGE)gl.namedBufferStorage;
1668 	m_pMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGE)gl.mapNamedBufferRange;
1669 	m_pUnmapNamedBuffer	= (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;
1670 
1671 	try
1672 	{
1673 		if ((DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pMapNamedBufferRange) ||
1674 			(DE_NULL == m_pUnmapNamedBuffer))
1675 		{
1676 			throw 0;
1677 		}
1678 
1679 		glw::GLbitfield access_flags[] = { GL_MAP_READ_BIT, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT,
1680 										   GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT };
1681 
1682 		glw::GLuint access_flags_count = sizeof(access_flags) / sizeof(access_flags[0]);
1683 
1684 		for (glw::GLuint i = 0; i < access_flags_count; ++i)
1685 		{
1686 			/* Buffer creation. */
1687 			gl.createBuffers(1, &buffer);
1688 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
1689 
1690 			/* Buffer's storage allocation and reference data upload. */
1691 			m_pNamedBufferStorage(buffer, s_reference_size, s_reference, access_flags[i]);
1692 			GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");
1693 
1694 			/* Mapping with first half of named buffer. */
1695 			glw::GLuint* data = (glw::GLuint*)m_pMapNamedBufferRange(buffer, 0, s_reference_size / 2, access_flags[i]);
1696 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBufferRange failed.");
1697 
1698 			/* Check with reference. */
1699 			is_ok &= CompareWithReference(data, 0, s_reference_size / 2);
1700 
1701 			/* Unmapping with new named buffer unmap function. */
1702 			m_pUnmapNamedBuffer(buffer);
1703 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
1704 
1705 			/* Mapping with second half of named buffer. */
1706 			data = (glw::GLuint*)m_pMapNamedBufferRange(buffer, s_reference_size / 2, s_reference_size / 2,
1707 														access_flags[i]);
1708 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBufferRange failed.");
1709 
1710 			/* Check with reference. */
1711 			is_ok &= CompareWithReference(data, s_reference_size / 2, s_reference_size / 2);
1712 
1713 			/* Unmapping with new named buffer unmap function. */
1714 			m_pUnmapNamedBuffer(buffer);
1715 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
1716 
1717 			/* Clean up. */
1718 			if (buffer)
1719 			{
1720 				gl.deleteBuffers(1, &buffer);
1721 
1722 				buffer = 0;
1723 			}
1724 		}
1725 	}
1726 	catch (...)
1727 	{
1728 		is_ok	= false;
1729 		is_error = true;
1730 	}
1731 
1732 	/* Clean up. */
1733 	if (buffer)
1734 	{
1735 		gl.deleteBuffers(1, &buffer);
1736 
1737 		buffer = 0;
1738 	}
1739 
1740 	/* Errors clean up. */
1741 	while (gl.getError())
1742 		;
1743 
1744 	/* Result's setup. */
1745 	if (is_ok)
1746 	{
1747 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1748 	}
1749 	else
1750 	{
1751 		if (is_error)
1752 		{
1753 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1754 		}
1755 		else
1756 		{
1757 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1758 		}
1759 	}
1760 
1761 	return STOP;
1762 }
1763 
1764 /** @brief Compare array of unsigned integers with subrange of reference values (s_reference).
1765  *
1766  *  @param [in] data        Data to be compared.
1767  *  @param [in] offset      Offset in the reference data.
1768  *  @param [in] length      Length of the data to be compared.
1769  *
1770  *  @return True if comparison succeeded, false otherwise.
1771  */
CompareWithReference(glw::GLuint * data,glw::GLintptr offset,glw::GLsizei length)1772 bool MapRangeReadBitTest::CompareWithReference(glw::GLuint* data, glw::GLintptr offset, glw::GLsizei length)
1773 {
1774 	if (DE_NULL == data)
1775 	{
1776 		/* Log. */
1777 		m_context.getTestContext().getLog()
1778 			<< tcu::TestLog::Message << "glMapNamedBufferRange called with offset " << offset << " and length "
1779 			<< length << " returned NULL pointer, but buffer's data was expected." << tcu::TestLog::EndMessage;
1780 	}
1781 	else
1782 	{
1783 		glw::GLuint start = static_cast<glw::GLuint>((offset) / sizeof(s_reference[0]));
1784 		glw::GLuint end   = static_cast<glw::GLuint>((offset + length) / sizeof(s_reference[0]));
1785 
1786 		/* Comparison results with reference data. */
1787 		for (glw::GLuint i = start; i < end; ++i)
1788 		{
1789 #if (DE_COMPILER == DE_COMPILER_GCC)
1790 #pragma GCC diagnostic push
1791 #pragma GCC diagnostic ignored "-Warray-bounds"
1792 #endif
1793 			if (data[i - start] != s_reference[i])
1794 			{
1795 				/* Log. */
1796 				m_context.getTestContext().getLog()
1797 					<< tcu::TestLog::Message << "glMapNamedBufferRange called with offset " << offset << " and length "
1798 					<< length << " returned pointer to data which is not identical to reference data."
1799 					<< tcu::TestLog::EndMessage;
1800 
1801 				return false;
1802 			}
1803 #if (DE_COMPILER == DE_COMPILER_GCC)
1804 #pragma GCC diagnostic pop
1805 #endif
1806 		}
1807 	}
1808 
1809 	return true;
1810 }
1811 
1812 const glw::GLuint MapRangeReadBitTest::s_reference[] = {
1813 	1, 2, 4, 8, 16, 64, 128, 256, 512, 1024, 2048, 4096
1814 };																				//!< Reference data.
1815 const glw::GLsizei MapRangeReadBitTest::s_reference_size = sizeof(s_reference); //!< Reference data size.
1816 const glw::GLsizei MapRangeReadBitTest::s_reference_count =
1817 	s_reference_size / sizeof(s_reference[0]); //!< Reference data elements' count.
1818 
1819 /******************************** Buffers Range Map Write Bit Test Implementation   ********************************/
1820 
1821 /** @brief Buffers Range Map Write Bit Test constructor.
1822  *
1823  *  @param [in] context     OpenGL context.
1824  */
MapRangeWriteBitTest(deqp::Context & context)1825 MapRangeWriteBitTest::MapRangeWriteBitTest(deqp::Context& context)
1826 	: deqp::TestCase(context, "buffers_map_range_write_bit", "Buffer Objects Map Range Write Bit Test")
1827 	, m_pNamedBufferStorage(DE_NULL)
1828 	, m_pMapNamedBufferRange(DE_NULL)
1829 	, m_pUnmapNamedBuffer(DE_NULL)
1830 	, m_pFlushMappedNamedBufferRange(DE_NULL)
1831 {
1832 	/* Intentionally left blank. */
1833 }
1834 
1835 /** @brief Iterate Buffers Range Map Read Bit Test cases.
1836  *
1837  *  @return Iteration result.
1838  */
iterate()1839 tcu::TestNode::IterateResult MapRangeWriteBitTest::iterate()
1840 {
1841 	/* Shortcut for GL functionality. */
1842 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1843 
1844 	/* Get context setup. */
1845 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
1846 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
1847 
1848 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
1849 	{
1850 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1851 
1852 		return STOP;
1853 	}
1854 
1855 	/* Running tests. */
1856 	bool is_ok	= true;
1857 	bool is_error = false;
1858 
1859 	glw::GLuint buffer = 0;
1860 
1861 	m_pNamedBufferStorage		   = (PFNGLNAMEDBUFFERSTORAGE)gl.namedBufferStorage;
1862 	m_pMapNamedBufferRange		   = (PFNGLMAPNAMEDBUFFERRANGE)gl.mapNamedBufferRange;
1863 	m_pUnmapNamedBuffer			   = (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;
1864 	m_pFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGE)gl.flushMappedNamedBufferRange;
1865 
1866 	try
1867 	{
1868 		if ((DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pMapNamedBufferRange) ||
1869 			(DE_NULL == m_pUnmapNamedBuffer) || (DE_NULL == m_pFlushMappedNamedBufferRange))
1870 		{
1871 			throw 0;
1872 		}
1873 
1874 		struct
1875 		{
1876 			glw::GLbitfield creation;
1877 			glw::GLbitfield first_mapping;
1878 			glw::GLbitfield second_mapping;
1879 		} access_flags[] = {
1880 			{ GL_MAP_WRITE_BIT | GL_MAP_READ_BIT, GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT },
1881 			{ GL_MAP_WRITE_BIT | GL_MAP_READ_BIT, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT,
1882 			  GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT },
1883 			{ GL_MAP_WRITE_BIT | GL_MAP_READ_BIT, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT, GL_MAP_WRITE_BIT },
1884 			{ GL_MAP_WRITE_BIT | GL_MAP_READ_BIT, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT,
1885 			  GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT },
1886 			{ GL_MAP_WRITE_BIT | GL_MAP_READ_BIT, GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT }
1887 		};
1888 
1889 		glw::GLuint access_flags_count = sizeof(access_flags) / sizeof(access_flags[0]);
1890 
1891 		for (glw::GLuint i = 0; i < access_flags_count; ++i)
1892 		{
1893 			/* Buffer creation. */
1894 			gl.createBuffers(1, &buffer);
1895 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
1896 
1897 			/* Buffer's storage allocation and reference data upload. */
1898 			m_pNamedBufferStorage(buffer, s_reference_size, DE_NULL, access_flags[i].creation);
1899 			GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferStorage failed.");
1900 
1901 			/* Mapping with first half of named buffer. */
1902 			glw::GLuint* data =
1903 				(glw::GLuint*)m_pMapNamedBufferRange(buffer, 0, s_reference_size / 2, access_flags[i].first_mapping);
1904 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBufferRange failed.");
1905 
1906 			/* Write to mapped buffer. */
1907 			for (glw::GLsizei j = 0; j < s_reference_count / 2; ++j)
1908 			{
1909 				data[j] = s_reference[j];
1910 			}
1911 
1912 			/* Flush, if needed. */
1913 			glw::GLenum flush_error = GL_NO_ERROR;
1914 
1915 			if (GL_MAP_FLUSH_EXPLICIT_BIT & access_flags[i].first_mapping)
1916 			{
1917 				m_pFlushMappedNamedBufferRange(buffer, 0, s_reference_size / 2);
1918 
1919 				flush_error = gl.getError();
1920 			}
1921 
1922 			/* Unmapping with new named buffer unmap function. */
1923 			m_pUnmapNamedBuffer(buffer);
1924 			GLU_EXPECT_NO_ERROR(flush_error, "glFlushMappedNamedBufferRange failed.");
1925 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
1926 
1927 			/* Mapping with second half of named buffer. */
1928 			data = (glw::GLuint*)m_pMapNamedBufferRange(buffer, s_reference_size / 2, s_reference_size / 2,
1929 														access_flags[i].second_mapping);
1930 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBufferRange failed.");
1931 
1932 			/* Write to mapped buffer. */
1933 			for (glw::GLsizei j = 0; j < s_reference_count / 2; ++j)
1934 			{
1935 				data[j] = s_reference[j + s_reference_count / 2];
1936 			}
1937 
1938 			/* Flush, if needed. */
1939 			flush_error = GL_NO_ERROR;
1940 
1941 			if (GL_MAP_FLUSH_EXPLICIT_BIT & access_flags[i].second_mapping)
1942 			{
1943 				m_pFlushMappedNamedBufferRange(buffer, 0, s_reference_size / 2);
1944 
1945 				flush_error = gl.getError();
1946 			}
1947 
1948 			/* Unmapping with new named buffer unmap function. */
1949 			m_pUnmapNamedBuffer(buffer);
1950 			GLU_EXPECT_NO_ERROR(flush_error, "glFlushMappedNamedBufferRange failed.");
1951 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
1952 
1953 			/* Check that previous mappings correctly filled buffer with reference data. */
1954 			is_ok &= CompareWithReference(buffer, access_flags[i].first_mapping | access_flags[i].second_mapping);
1955 
1956 			/* Clean up. */
1957 			if (buffer)
1958 			{
1959 				gl.deleteBuffers(1, &buffer);
1960 
1961 				buffer = 0;
1962 			}
1963 		}
1964 	}
1965 	catch (...)
1966 	{
1967 		is_ok	= false;
1968 		is_error = true;
1969 	}
1970 
1971 	/* Clean up. */
1972 	if (buffer)
1973 	{
1974 		gl.deleteBuffers(1, &buffer);
1975 
1976 		buffer = 0;
1977 	}
1978 
1979 	/* Errors clean up. */
1980 	while (gl.getError())
1981 		;
1982 
1983 	/* Result's setup. */
1984 	if (is_ok)
1985 	{
1986 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1987 	}
1988 	else
1989 	{
1990 		if (is_error)
1991 		{
1992 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1993 		}
1994 		else
1995 		{
1996 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1997 		}
1998 	}
1999 
2000 	return STOP;
2001 }
2002 
2003 /** @brief Compare buffer's content with the reference values (s_reference) and log possible failure.
2004  *
2005  *  @param [in] buffer          Buffer to be tested.
2006  *  @param [in] access_flag     Access flag used during test's mapping (for failure logging purposes).
2007  *
2008  *  @return True if comparison succeeded, false otherwise.
2009  */
CompareWithReference(glw::GLuint buffer,glw::GLbitfield access_flag)2010 bool MapRangeWriteBitTest::CompareWithReference(glw::GLuint buffer, glw::GLbitfield access_flag)
2011 {
2012 	/* Shortcut for GL functionality. */
2013 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2014 
2015 	/* Map buffer with legacy API. */
2016 	gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
2017 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer failed.");
2018 
2019 	glw::GLuint* data = (glw::GLuint*)gl.mapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
2020 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer failed.");
2021 
2022 	/* Default return value. */
2023 	bool is_ok = true;
2024 
2025 	if (DE_NULL != data)
2026 	{
2027 		/* Comparison results with reference data. */
2028 		for (glw::GLsizei i = 0; i < s_reference_count; ++i)
2029 		{
2030 			if (data[i] != s_reference[i])
2031 			{
2032 				std::string access_string = "GL_MAP_WRITE_BIT";
2033 
2034 				if (GL_MAP_INVALIDATE_RANGE_BIT & access_flag)
2035 				{
2036 					access_string = "(GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT)";
2037 				}
2038 
2039 				if (GL_MAP_INVALIDATE_BUFFER_BIT & access_flag)
2040 				{
2041 					access_string = "(GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT)";
2042 				}
2043 
2044 				if (GL_MAP_FLUSH_EXPLICIT_BIT & access_flag)
2045 				{
2046 					access_string = "(GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT)";
2047 				}
2048 
2049 				if (GL_MAP_UNSYNCHRONIZED_BIT & access_flag)
2050 				{
2051 					access_string = "(GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT)";
2052 				}
2053 
2054 				/* Log. */
2055 				m_context.getTestContext().getLog()
2056 					<< tcu::TestLog::Message << "Test of glMapNamedBufferRange with access flag " << access_string
2057 					<< " failed to fill the buffer with reference data." << tcu::TestLog::EndMessage;
2058 
2059 				is_ok = false;
2060 
2061 				break;
2062 			}
2063 		}
2064 	}
2065 
2066 	/* Unmap buffer. */
2067 	gl.unmapBuffer(GL_ARRAY_BUFFER);
2068 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer failed.");
2069 
2070 	return is_ok;
2071 }
2072 
2073 const glw::GLuint MapRangeWriteBitTest::s_reference[] = {
2074 	1, 2, 4, 8, 16, 64, 128, 256, 512, 1024, 2048, 4096
2075 };																				 //!< Reference data.
2076 const glw::GLsizei MapRangeWriteBitTest::s_reference_size = sizeof(s_reference); //!< Reference data size.
2077 const glw::GLsizei MapRangeWriteBitTest::s_reference_count =
2078 	s_reference_size / sizeof(s_reference[0]); //!< Reference data elements' count.
2079 
2080 /******************************** Get Named Buffer SubData Query Test Implementation   ********************************/
2081 
2082 /** @brief Get Named Buffer SubData Query Test's static constants. */
2083 const glw::GLuint SubDataQueryTest::s_reference[] = {
2084 	1, 2, 4, 8, 16, 64, 128, 256, 512, 1024, 2048, 4096
2085 };																			 //!< Reference data.
2086 const glw::GLsizei SubDataQueryTest::s_reference_size = sizeof(s_reference); //!< Reference data size.
2087 const glw::GLsizei SubDataQueryTest::s_reference_count =
2088 	s_reference_size / sizeof(s_reference[0]); //!< Reference data elements' count.
2089 
2090 /** @brief Get Named Buffer SubData Query Test constructor.
2091  *
2092  *  @param [in] context     OpenGL context.
2093  */
SubDataQueryTest(deqp::Context & context)2094 SubDataQueryTest::SubDataQueryTest(deqp::Context& context)
2095 	: deqp::TestCase(context, "buffers_get_named_buffer_subdata", "Buffer Objects Get Named Buffer SubData Query Test")
2096 	, m_pNamedBufferData(DE_NULL)
2097 	, m_pGetNamedBufferSubData(DE_NULL)
2098 {
2099 	/* Intentionally left blank. */
2100 }
2101 
2102 /** @brief Iterate Get Named Buffer SubData Query Test cases.
2103  *
2104  *  @return Iteration result.
2105  */
iterate()2106 tcu::TestNode::IterateResult SubDataQueryTest::iterate()
2107 {
2108 	/* Shortcut for GL functionality. */
2109 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2110 
2111 	/* Get context setup. */
2112 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
2113 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
2114 
2115 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
2116 	{
2117 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
2118 
2119 		return STOP;
2120 	}
2121 
2122 	/* Running tests. */
2123 	bool is_ok	= true;
2124 	bool is_error = false;
2125 
2126 	glw::GLuint buffer = 0;
2127 
2128 	m_pNamedBufferData		 = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
2129 	m_pGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATA)gl.getNamedBufferSubData;
2130 
2131 	try
2132 	{
2133 		if ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pGetNamedBufferSubData))
2134 		{
2135 			throw 0;
2136 		}
2137 
2138 		/* Buffer creation. */
2139 		gl.createBuffers(1, &buffer);
2140 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
2141 
2142 		/* Buffer's storage allocation and reference data upload. */
2143 		m_pNamedBufferData(buffer, s_reference_size, s_reference, GL_DYNAMIC_COPY);
2144 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");
2145 
2146 		/* Mapping with new named buffer map function. */
2147 		glw::GLuint data[s_reference_count] = {};
2148 		m_pGetNamedBufferSubData(buffer, 0, s_reference_size / 2, data);
2149 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetNamedBufferSubData failed.");
2150 
2151 		m_pGetNamedBufferSubData(buffer, s_reference_size / 2, s_reference_size / 2, &data[s_reference_count / 2]);
2152 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetNamedBufferSubData failed.");
2153 
2154 		/* Comparison results with reference data. */
2155 		for (glw::GLsizei i = 0; i < s_reference_count; ++i)
2156 		{
2157 			is_ok &= (data[i] == s_reference[i]);
2158 		}
2159 
2160 		if (!is_ok)
2161 		{
2162 			/* Log. */
2163 			m_context.getTestContext().getLog()
2164 				<< tcu::TestLog::Message
2165 				<< "glGetNamedBufferSubData returned data which is not identical to reference data."
2166 				<< tcu::TestLog::EndMessage;
2167 		}
2168 	}
2169 	catch (...)
2170 	{
2171 		is_ok	= false;
2172 		is_error = true;
2173 	}
2174 
2175 	/* Clean up. */
2176 	if (buffer)
2177 	{
2178 		gl.deleteBuffers(1, &buffer);
2179 
2180 		buffer = false;
2181 	}
2182 
2183 	/* Errors clean up. */
2184 	while (gl.getError())
2185 		;
2186 
2187 	/* Result's setup. */
2188 	if (is_ok)
2189 	{
2190 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2191 	}
2192 	else
2193 	{
2194 		if (is_error)
2195 		{
2196 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
2197 		}
2198 		else
2199 		{
2200 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2201 		}
2202 	}
2203 
2204 	return STOP;
2205 }
2206 
2207 /******************************** Defaults Test Implementation   ********************************/
2208 
2209 /** @brief Defaults Query Test constructor.
2210  *
2211  *  @param [in] context     OpenGL context.
2212  */
DefaultsTest(deqp::Context & context)2213 DefaultsTest::DefaultsTest(deqp::Context& context)
2214 	: deqp::TestCase(context, "buffers_defaults", "Buffer Objects Defaults Test")
2215 	, m_pNamedBufferData(DE_NULL)
2216 	, m_pGetNamedBufferParameteri64v(DE_NULL)
2217 	, m_pGetNamedBufferParameteriv(DE_NULL)
2218 	, m_pGetNamedBufferPointerv(DE_NULL)
2219 {
2220 	/* Intentionally left blank. */
2221 }
2222 
2223 /** @brief Compare value with the reference.
2224  *
2225  *  @param [in] value               Value to be compared.
2226  *  @param [in] reference_value     Reference value for comparison.
2227  *  @param [in] pname_string        String of parameter name of the value (for logging).
2228  *  @param [in] function_string     String of function which returned the value (for logging).
2229  *
2230  *  @return True if value is equal to reference value, false otherwise. False solution is logged.
2231  */
2232 template <typename T>
CheckValue(const T value,const T reference_value,const glw::GLchar * pname_string,const glw::GLchar * function_string)2233 bool DefaultsTest::CheckValue(const T value, const T reference_value, const glw::GLchar* pname_string,
2234 							  const glw::GLchar* function_string)
2235 {
2236 	if (reference_value != value)
2237 	{
2238 		/* Log. */
2239 		m_context.getTestContext().getLog() << tcu::TestLog::Message << function_string << " called with "
2240 											<< pname_string << " parameter name returned " << value << ", but "
2241 											<< reference_value << " was expected." << tcu::TestLog::EndMessage;
2242 
2243 		return false;
2244 	}
2245 	return true;
2246 }
2247 
2248 /** @brief Iterate Defaults Test cases.
2249  *
2250  *  @return Iteration result.
2251  */
iterate()2252 tcu::TestNode::IterateResult DefaultsTest::iterate()
2253 {
2254 	/* Shortcut for GL functionality. */
2255 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2256 
2257 	/* Get context setup. */
2258 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
2259 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
2260 
2261 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
2262 	{
2263 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
2264 
2265 		return STOP;
2266 	}
2267 
2268 	/* Running tests. */
2269 	bool is_ok	= true;
2270 	bool is_error = false;
2271 
2272 	glw::GLuint buffer = 0;
2273 
2274 	m_pNamedBufferData			   = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
2275 	m_pGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64V)gl.getNamedBufferParameteri64v;
2276 	m_pGetNamedBufferParameteriv   = (PFNGLGETNAMEDBUFFERPARAMETERIV)gl.getNamedBufferParameteriv;
2277 	m_pGetNamedBufferPointerv	  = (PFNGLGETNAMEDBUFFERPOINTERV)gl.getNamedBufferPointerv;
2278 
2279 	try
2280 	{
2281 		if ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pGetNamedBufferParameteri64v) ||
2282 			(DE_NULL == m_pGetNamedBufferParameteriv) || (DE_NULL == m_pGetNamedBufferPointerv))
2283 		{
2284 			throw 0;
2285 		}
2286 
2287 		/* Buffer creation. */
2288 		gl.createBuffers(1, &buffer);
2289 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
2290 
2291 		/* Test data for glGetNamedBufferParameteri*v. */
2292 		static const struct
2293 		{
2294 			glw::GLenum		   pname;
2295 			const glw::GLchar* pname_string;
2296 			glw::GLint		   expected_data;
2297 		} test_values[] = { { GL_BUFFER_SIZE, "GL_BUFFER_SIZE", 0 },
2298 							{ GL_BUFFER_USAGE, "GL_BUFFER_USAGE", GL_STATIC_DRAW },
2299 							{ GL_BUFFER_ACCESS, "GL_BUFFER_ACCESS", GL_READ_WRITE },
2300 							{ GL_BUFFER_ACCESS_FLAGS, "GL_BUFFER_ACCESS_FLAGS", 0 },
2301 							{ GL_BUFFER_IMMUTABLE_STORAGE, "GL_BUFFER_IMMUTABLE_STORAGE", GL_FALSE },
2302 							{ GL_BUFFER_MAPPED, "GL_BUFFER_MAPPED", GL_FALSE },
2303 							{ GL_BUFFER_MAP_OFFSET, "GL_BUFFER_MAP_OFFSET", 0 },
2304 							{ GL_BUFFER_MAP_LENGTH, "GL_BUFFER_MAP_LENGTH", 0 },
2305 							{ GL_BUFFER_STORAGE_FLAGS, "GL_BUFFER_STORAGE_FLAGS", 0 } };
2306 
2307 		static const glw::GLuint test_dictionary_count = sizeof(test_values) / sizeof(test_values[0]);
2308 
2309 		/* Test glGetNamedBufferParameteriv. */
2310 		for (glw::GLuint i = 0; i < test_dictionary_count; ++i)
2311 		{
2312 			glw::GLint data = -1;
2313 
2314 			m_pGetNamedBufferParameteriv(buffer, test_values[i].pname, &data);
2315 
2316 			is_ok &= CheckParameterError(test_values[i].pname_string, "glGetNamedBufferParameteriv");
2317 
2318 			is_ok &= CheckValue<glw::GLint>(data, test_values[i].expected_data, test_values[i].pname_string,
2319 											"glGetNamedBufferParameteriv");
2320 		}
2321 
2322 		/* Test glGetNamedBufferParameteri64v. */
2323 		for (glw::GLuint i = 0; i < test_dictionary_count; ++i)
2324 		{
2325 			glw::GLint64 data = -1;
2326 
2327 			m_pGetNamedBufferParameteri64v(buffer, test_values[i].pname, &data);
2328 
2329 			is_ok &= CheckParameterError(test_values[i].pname_string, "glGetNamedBufferParameteri64v");
2330 
2331 			is_ok &= CheckValue<glw::GLint64>(data, (glw::GLint64)test_values[i].expected_data,
2332 											  test_values[i].pname_string, "glGetNamedBufferParameteri64v");
2333 		}
2334 
2335 		/* Test glGetNamedBufferPointerv. */
2336 		{
2337 			glw::GLvoid* data = (glw::GLvoid*)1;
2338 
2339 			m_pGetNamedBufferPointerv(buffer, GL_BUFFER_MAP_POINTER, &data);
2340 
2341 			is_ok &= CheckParameterError("GL_BUFFER_MAP_POINTER", "glGetNamedBufferPointer");
2342 
2343 			is_ok &= CheckValue<glw::GLvoid*>(data, (glw::GLvoid*)DE_NULL, "GL_BUFFER_MAP_POINTER",
2344 											  "glGetNamedBufferParameteriv");
2345 		}
2346 	}
2347 	catch (...)
2348 	{
2349 		is_ok	= false;
2350 		is_error = true;
2351 	}
2352 
2353 	/* Clean up. */
2354 	if (buffer)
2355 	{
2356 		gl.deleteBuffers(1, &buffer);
2357 
2358 		buffer = 0;
2359 	}
2360 
2361 	/* Errors clean up. */
2362 	while (gl.getError())
2363 		;
2364 
2365 	/* Result's setup. */
2366 	if (is_ok)
2367 	{
2368 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2369 	}
2370 	else
2371 	{
2372 		if (is_error)
2373 		{
2374 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
2375 		}
2376 		else
2377 		{
2378 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2379 		}
2380 	}
2381 
2382 	return STOP;
2383 }
2384 
2385 /** @brief Check for GL error and log.
2386  *
2387  *  @param [in] pname_string        String of parameter name of the value (for logging).
2388  *  @param [in] function_string     String of function which returned the value (for logging).
2389  *
2390  *  @return True if error was generated, false otherwise. False solution is logged.
2391  */
CheckParameterError(const glw::GLchar * pname_string,const glw::GLchar * function_string)2392 bool DefaultsTest::CheckParameterError(const glw::GLchar* pname_string, const glw::GLchar* function_string)
2393 {
2394 	/* Shortcut for GL functionality. */
2395 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2396 
2397 	/* Error check. */
2398 	if (glw::GLenum error = gl.getError())
2399 	{
2400 		/* Log. */
2401 		m_context.getTestContext().getLog() << tcu::TestLog::Message << function_string << " called with "
2402 											<< pname_string << " parameter name unexpectedly returned "
2403 											<< glu::getErrorStr(error) << "error." << tcu::TestLog::EndMessage;
2404 
2405 		return false;
2406 	}
2407 
2408 	return true;
2409 }
2410 
2411 /******************************** Errors Test Implementation   ********************************/
2412 
2413 /** @brief Errors Query Test constructor.
2414  *
2415  *  @param [in] context     OpenGL context.
2416  */
ErrorsTest(deqp::Context & context)2417 ErrorsTest::ErrorsTest(deqp::Context& context)
2418 	: deqp::TestCase(context, "buffers_errors", "Buffer Objects Errors Test")
2419 	, m_pClearNamedBufferData(DE_NULL)
2420 	, m_pClearNamedBufferSubData(DE_NULL)
2421 	, m_pCopyNamedBufferSubData(DE_NULL)
2422 	, m_pFlushMappedNamedBufferRange(DE_NULL)
2423 	, m_pGetNamedBufferParameteri64v(DE_NULL)
2424 	, m_pGetNamedBufferParameteriv(DE_NULL)
2425 	, m_pGetNamedBufferPointerv(DE_NULL)
2426 	, m_pGetNamedBufferSubData(DE_NULL)
2427 	, m_pMapNamedBuffer(DE_NULL)
2428 	, m_pMapNamedBufferRange(DE_NULL)
2429 	, m_pNamedBufferData(DE_NULL)
2430 	, m_pNamedBufferStorage(DE_NULL)
2431 	, m_pNamedBufferSubData(DE_NULL)
2432 	, m_pUnmapNamedBuffer(DE_NULL)
2433 {
2434 	/* Intentionally left blank. */
2435 }
2436 
2437 /** @brief Iterate Errors Test cases.
2438  *
2439  *  @return Iteration result.
2440  */
iterate()2441 tcu::TestNode::IterateResult ErrorsTest::iterate()
2442 {
2443 	/* Shortcut for GL functionality. */
2444 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2445 
2446 	/* Get context setup. */
2447 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
2448 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
2449 
2450 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
2451 	{
2452 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
2453 
2454 		return STOP;
2455 	}
2456 
2457 	/* Running tests. */
2458 	bool is_ok	= true;
2459 	bool is_error = false;
2460 
2461 	/* API function pointers setup. */
2462 	m_pClearNamedBufferData		   = (PFNGLCLEARNAMEDBUFFERDATA)gl.clearNamedBufferData;
2463 	m_pClearNamedBufferSubData	 = (PFNGLCLEARNAMEDBUFFERSUBDATA)gl.clearNamedBufferSubData;
2464 	m_pCopyNamedBufferSubData	  = (PFNGLCOPYNAMEDBUFFERSUBDATA)gl.copyNamedBufferSubData;
2465 	m_pFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGE)gl.flushMappedNamedBufferRange;
2466 	m_pGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64V)gl.getNamedBufferParameteri64v;
2467 	m_pGetNamedBufferParameteriv   = (PFNGLGETNAMEDBUFFERPARAMETERIV)gl.getNamedBufferParameteriv;
2468 	m_pGetNamedBufferPointerv	  = (PFNGLGETNAMEDBUFFERPOINTERV)gl.getNamedBufferPointerv;
2469 	m_pGetNamedBufferSubData	   = (PFNGLGETNAMEDBUFFERSUBDATA)gl.getNamedBufferSubData;
2470 	m_pMapNamedBuffer			   = (PFNGLMAPNAMEDBUFFER)gl.mapNamedBuffer;
2471 	m_pMapNamedBufferRange		   = (PFNGLMAPNAMEDBUFFERRANGE)gl.mapNamedBufferRange;
2472 	m_pNamedBufferData			   = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
2473 	m_pNamedBufferStorage		   = (PFNGLNAMEDBUFFERSTORAGE)gl.namedBufferStorage;
2474 	m_pNamedBufferSubData		   = (PFNGLNAMEDBUFFERSUBDATA)gl.namedBufferSubData;
2475 	m_pUnmapNamedBuffer			   = (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;
2476 
2477 	try
2478 	{
2479 		/* API function pointers check. */
2480 		if ((DE_NULL == m_pClearNamedBufferData) || (DE_NULL == m_pClearNamedBufferSubData) ||
2481 			(DE_NULL == m_pCopyNamedBufferSubData) || (DE_NULL == m_pFlushMappedNamedBufferRange) ||
2482 			(DE_NULL == m_pGetNamedBufferParameteri64v) || (DE_NULL == m_pGetNamedBufferParameteriv) ||
2483 			(DE_NULL == m_pGetNamedBufferPointerv) || (DE_NULL == m_pGetNamedBufferSubData) ||
2484 			(DE_NULL == m_pMapNamedBuffer) || (DE_NULL == m_pMapNamedBufferRange) || (DE_NULL == m_pNamedBufferData) ||
2485 			(DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pNamedBufferSubData) ||
2486 			(DE_NULL == m_pUnmapNamedBuffer))
2487 		{
2488 			throw 0;
2489 		}
2490 
2491 		/* Running test cases.                              Cleaning errors. */
2492 		is_ok &= TestErrorsOfClearNamedBufferData();
2493 		while (gl.getError())
2494 			;
2495 		is_ok &= TestErrorsOfClearNamedBufferSubData();
2496 		while (gl.getError())
2497 			;
2498 		is_ok &= TestErrorsOfCopyNamedBufferSubData();
2499 		while (gl.getError())
2500 			;
2501 		is_ok &= TestErrorsOfCreateBuffers();
2502 		while (gl.getError())
2503 			;
2504 		is_ok &= TestErrorsOfFlushMappedNamedBufferRange();
2505 		while (gl.getError())
2506 			;
2507 		is_ok &= TestErrorsOfGetNamedBufferParameter();
2508 		while (gl.getError())
2509 			;
2510 		is_ok &= TestErrorsOfGetNamedBufferPointerv();
2511 		while (gl.getError())
2512 			;
2513 		is_ok &= TestErrorsOfGetNamedBufferSubData();
2514 		while (gl.getError())
2515 			;
2516 		is_ok &= TestErrorsOfMapNamedBuffer();
2517 		while (gl.getError())
2518 			;
2519 		is_ok &= TestErrorsOfMapNamedBufferRange();
2520 		while (gl.getError())
2521 			;
2522 		is_ok &= TestErrorsOfNamedBufferData();
2523 		while (gl.getError())
2524 			;
2525 		is_ok &= TestErrorsOfNamedBufferStorage();
2526 		while (gl.getError())
2527 			;
2528 		is_ok &= TestErrorsOfNamedBufferSubData();
2529 		while (gl.getError())
2530 			;
2531 		is_ok &= TestErrorsOfUnmapNamedBuffer();
2532 		while (gl.getError())
2533 			;
2534 	}
2535 	catch (...)
2536 	{
2537 		is_ok	= false;
2538 		is_error = true;
2539 	}
2540 
2541 	/* Errors clean up. */
2542 	while (gl.getError())
2543 		;
2544 
2545 	/* Result's setup. */
2546 	if (is_ok)
2547 	{
2548 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2549 	}
2550 	else
2551 	{
2552 		if (is_error)
2553 		{
2554 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
2555 		}
2556 		else
2557 		{
2558 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2559 		}
2560 	}
2561 
2562 	return STOP;
2563 }
2564 
2565 /** Check if error was generated and if it is equal to expected value. Log possible failure.
2566  *
2567  *  @param [in] function_name               Tested Function.
2568  *  @param [in] expected_error              Expected error function.
2569  *  @param [in] when_shall_be_generated     Description when shall the error occure.
2570  *
2571  *  @return True if GL error is equal to the expected value, false otherwise.
2572  */
ErrorCheckAndLog(const glw::GLchar * function_name,const glw::GLenum expected_error,const glw::GLchar * when_shall_be_generated)2573 bool ErrorsTest::ErrorCheckAndLog(const glw::GLchar* function_name, const glw::GLenum expected_error,
2574 								  const glw::GLchar* when_shall_be_generated)
2575 {
2576 	/* Shortcut for GL functionality. */
2577 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2578 
2579 	/* Error value storage. */
2580 	glw::GLenum error = GL_NO_ERROR;
2581 
2582 	/* Error comparision. */
2583 	if (expected_error != (error = gl.getError()))
2584 	{
2585 		/* Log. */
2586 		m_context.getTestContext().getLog() << tcu::TestLog::Message << function_name << " does not generate "
2587 											<< glu::getErrorStr(expected_error) << when_shall_be_generated
2588 											<< "The error value of " << glu::getErrorStr(error) << " was observed."
2589 											<< tcu::TestLog::EndMessage;
2590 
2591 		/* Error cleanup. */
2592 		while (gl.getError())
2593 			;
2594 
2595 		/* Check failed. */
2596 		return false;
2597 	}
2598 
2599 	/* Error was equal to expected. */
2600 	return true;
2601 }
2602 
2603 /** @brief Test Errors Of ClearNamedBufferData function.
2604  *
2605  *  Check that INVALID_OPERATION is generated by ClearNamedBufferData if
2606  *  buffer is not the name of an existing buffer object.
2607  *
2608  *  Check that INVALID_ENUM is generated by ClearNamedBufferData if
2609  *  internal format is not one of the valid sized internal formats listed in
2610  *  the table above.
2611  *
2612  *  Check that INVALID_OPERATION is generated by ClearNamedBufferData if
2613  *  any part of the specified range of the buffer object is mapped with
2614  *  MapBufferRange or MapBuffer, unless it was mapped with the
2615  *  MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.
2616  *
2617  *  Check that INVALID_VALUE is generated by ClearNamedBufferData if
2618  *  format is not a valid format, or type is not a valid type.
2619  *
2620  *  True if test case succeeded, false otherwise.
2621  */
TestErrorsOfClearNamedBufferData()2622 bool ErrorsTest::TestErrorsOfClearNamedBufferData()
2623 {
2624 	/* Shortcut for GL functionality. */
2625 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2626 
2627 	/* Return value. */
2628 	bool is_ok			= true;
2629 	bool internal_error = false;
2630 
2631 	/* Common variables. */
2632 	glw::GLuint buffer	 = 0;
2633 	glw::GLbyte unused_data = 0;
2634 
2635 	try
2636 	{
2637 		/* Common preparations. */
2638 		gl.createBuffers(1, &buffer);
2639 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
2640 
2641 		m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data,
2642 							  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
2643 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferStorage failed.");
2644 
2645 		/* Test invalid buffer name error behavior. */
2646 		{
2647 			/* Prepare for invalid buffer name error behavior verification. */
2648 			glw::GLuint not_a_buffer_name = 0;
2649 
2650 			while (gl.isBuffer(++not_a_buffer_name))
2651 				;
2652 
2653 			/* Test. */
2654 			m_pClearNamedBufferData(not_a_buffer_name, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &unused_data);
2655 
2656 			is_ok &= ErrorCheckAndLog("glClearNamedBufferData", GL_INVALID_OPERATION,
2657 									  " if buffer is not the name of an existing buffer object.");
2658 		}
2659 
2660 		/* Test invalid sized internal format error behavior. */
2661 		{
2662 			/* Prepare for invalid sized internal format error behavior verification. */
2663 			static const glw::GLenum valid_internal_formats[] = {
2664 				GL_R8,		GL_R16,		GL_R16F,	GL_R32F,	 GL_R8I,	  GL_R16I,	GL_R32I,
2665 				GL_R8UI,	GL_R16UI,   GL_R32UI,   GL_RG8,		 GL_RG16,	 GL_RG16F,   GL_RG32F,
2666 				GL_RG8I,	GL_RG16I,   GL_RG32I,   GL_RG8UI,	GL_RG16UI,   GL_RG32UI,  GL_RGB32F,
2667 				GL_RGB32I,  GL_RGB32UI, GL_RGBA8,   GL_RGBA16,   GL_RGBA16F,  GL_RGBA32F, GL_RGBA8I,
2668 				GL_RGBA16I, GL_RGBA32I, GL_RGBA8UI, GL_RGBA16UI, GL_RGBA32UI, GL_NONE
2669 			};
2670 			static const glw::GLenum valid_internal_formats_last =
2671 				sizeof(valid_internal_formats) / sizeof(valid_internal_formats[0]) - 1;
2672 
2673 			glw::GLenum invalid_internal_format = 0;
2674 
2675 			while (&valid_internal_formats[valid_internal_formats_last] !=
2676 				   std::find(&valid_internal_formats[0], &valid_internal_formats[valid_internal_formats_last],
2677 							 (++invalid_internal_format)))
2678 				;
2679 
2680 			/* Test. */
2681 			m_pClearNamedBufferData(buffer, invalid_internal_format, GL_RED, GL_UNSIGNED_BYTE, &unused_data);
2682 
2683 			is_ok &= ErrorCheckAndLog("glClearNamedBufferData", GL_INVALID_ENUM,
2684 									  " if internal format is not one of the valid sized internal formats "
2685 									  "(GL_R8, GL_R16, GL_R16F, GL_R32F, GL_R8I, GL_R16I, GL_R32I, GL_R8UI,"
2686 									  " GL_R16UI, GL_R32UI, GL_RG8, GL_RG16, GL_RG16F, GL_RG32F, GL_RG8I, GL_RG16I,"
2687 									  " GL_RG32I, GL_RG8UI, GL_RG16UI, GL_RG32UI, GL_RGB32F, GL_RGB32I, GL_RGB32UI,"
2688 									  " GL_RGBA8, GL_RGBA16, GL_RGBA16F, GL_RGBA32F, GL_RGBA8I, GL_RGBA16I, GL_RGBA32I,"
2689 									  " GL_RGBA8UI, GL_RGBA16UI, GL_RGBA32UI).");
2690 		}
2691 
2692 		/* Test of mapped buffer clear error behavior verification (glMapNamedBuffer version). */
2693 		{
2694 			(void)(glw::GLbyte*) m_pMapNamedBuffer(buffer, GL_READ_ONLY);
2695 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
2696 
2697 			m_pClearNamedBufferData(buffer, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &unused_data);
2698 
2699 			is_ok &= ErrorCheckAndLog("glClearNamedBufferData", GL_INVALID_OPERATION,
2700 									  " if any part of the specified range of the buffer"
2701 									  " object is mapped with MapBuffer, unless it was mapped with "
2702 									  "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");
2703 
2704 			m_pUnmapNamedBuffer(buffer);
2705 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
2706 		}
2707 
2708 		/* Test of mapped buffer clear error behavior verification (glMapNamedBufferRange version). */
2709 		{
2710 			(void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_READ_BIT);
2711 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
2712 
2713 			m_pClearNamedBufferData(buffer, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &unused_data);
2714 
2715 			is_ok &= ErrorCheckAndLog("glClearNamedBufferData", GL_INVALID_OPERATION,
2716 									  " if any part of the specified range of the buffer"
2717 									  " object is mapped with MapBufferRange, unless it was mapped with "
2718 									  "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");
2719 
2720 			m_pUnmapNamedBuffer(buffer);
2721 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
2722 		}
2723 
2724 		/* Test of persistently mapped buffer clear error with behavior verification (glMapNamedBufferRange version). */
2725 		{
2726 			(void)(glw::GLbyte*)
2727 				m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
2728 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
2729 
2730 			m_pClearNamedBufferData(buffer, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &unused_data);
2731 
2732 			is_ok &= ErrorCheckAndLog("glClearNamedBufferData", GL_NO_ERROR,
2733 									  " if any part of the specified range of the buffer"
2734 									  " object is mapped with MapBuffer with the MAP_PERSISTENT_BIT"
2735 									  " bit set in the MapBufferRange access flags.");
2736 
2737 			m_pUnmapNamedBuffer(buffer);
2738 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
2739 		}
2740 
2741 		/* Test invalid format error behavior. */
2742 		{
2743 			/* Prepare for invalid format error behavior verification. */
2744 			static const glw::GLenum valid_formats[] = { GL_RED,		   GL_RG,
2745 														 GL_RGB,		   GL_BGR,
2746 														 GL_RGBA,		   GL_BGRA,
2747 														 GL_RED_INTEGER,   GL_RG_INTEGER,
2748 														 GL_RGB_INTEGER,   GL_BGR_INTEGER,
2749 														 GL_RGBA_INTEGER,  GL_BGRA_INTEGER,
2750 														 GL_STENCIL_INDEX, GL_DEPTH_COMPONENT,
2751 														 GL_DEPTH_STENCIL };
2752 			static const glw::GLenum valid_formats_last = sizeof(valid_formats) / sizeof(valid_formats[0]) - 1;
2753 
2754 			glw::GLenum invalid_format = 0;
2755 
2756 			while (&valid_formats[valid_formats_last] !=
2757 				   std::find(&valid_formats[0], &valid_formats[valid_formats_last], (++invalid_format)))
2758 				;
2759 
2760 			/* Test. */
2761 			m_pClearNamedBufferData(buffer, GL_R8, invalid_format, GL_UNSIGNED_BYTE, &unused_data);
2762 
2763 			is_ok &= ErrorCheckAndLog(
2764 				"glClearNamedBufferData", GL_INVALID_VALUE,
2765 				" if format is not a valid format "
2766 				"(one of GL_RED, GL_RG, GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, "
2767 				"GL_RED_INTEGER, GL_RG_INTEGER, GL_RGB_INTEGER, GL_BGR_INTEGER, GL_RGBA_INTEGER, GL_BGRA_INTEGER, "
2768 				"GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL).");
2769 		}
2770 
2771 		/* Test invalid type error behavior. */
2772 		{
2773 			/* Prepare for invalid type error behavior verification. */
2774 			static const glw::GLenum valid_types[] = { GL_RED,			 GL_RG,
2775 													   GL_RGB,			 GL_BGR,
2776 													   GL_RGBA,			 GL_BGRA,
2777 													   GL_RED_INTEGER,   GL_RG_INTEGER,
2778 													   GL_RGB_INTEGER,   GL_BGR_INTEGER,
2779 													   GL_RGBA_INTEGER,  GL_BGRA_INTEGER,
2780 													   GL_STENCIL_INDEX, GL_DEPTH_COMPONENT,
2781 													   GL_DEPTH_STENCIL };
2782 			static const glw::GLenum valid_types_last = sizeof(valid_types) / sizeof(valid_types[0]) - 1;
2783 
2784 			glw::GLenum invalid_type = 0;
2785 
2786 			while (&valid_types[valid_types_last] !=
2787 				   std::find(&valid_types[0], &valid_types[valid_types_last], (++invalid_type)))
2788 				;
2789 
2790 			/* Test. */
2791 			m_pClearNamedBufferData(buffer, GL_R8, GL_RED, invalid_type, &unused_data);
2792 
2793 			is_ok &= ErrorCheckAndLog(
2794 				"glClearNamedBufferData", GL_INVALID_VALUE,
2795 				" if format is not a valid type "
2796 				"(one of GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, "
2797 				"GL_SHORT, GL_UNSIGNED_INT, GL_INT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, "
2798 				"GL_UNSIGNED_BYTE_2_3_3_REV, GL_UNSIGNED_SHORT_5_6_5, "
2799 				"GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, "
2800 				"GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_UNSIGNED_INT_8_8_8_8, "
2801 				"GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2, and GL_UNSIGNED_INT_2_10_10_10_REV).");
2802 		}
2803 	}
2804 	catch (...)
2805 	{
2806 		is_ok		   = false;
2807 		internal_error = true;
2808 	}
2809 
2810 	if (buffer)
2811 	{
2812 		gl.deleteBuffers(1, &buffer);
2813 
2814 		buffer = 0;
2815 	}
2816 
2817 	if (internal_error)
2818 	{
2819 		throw 0;
2820 	}
2821 
2822 	return is_ok;
2823 }
2824 
2825 /** @brief Test Errors Of ClearNamedBufferSubData function.
2826  *
2827  *  Check that INVALID_OPERATION is generated by ClearNamedBufferSubData
2828  *  if buffer is not the name of an existing buffer object.
2829  *
2830  *  Check that INVALID_ENUM is generated by ClearNamedBufferSubData if
2831  *  internal format is not one of the valid sized internal formats listed in
2832  *  the table above.
2833  *
2834  *  Check that INVALID_VALUE is generated by ClearNamedBufferSubData if
2835  *  offset or range are not multiples of the number of basic machine units
2836  *  per-element for the internal format specified by internal format. This
2837  *  value may be computed by multiplying the number of components for
2838  *  internal format from the table by the size of the base type from the
2839  *  specification table.
2840  *
2841  *  Check that INVALID_VALUE is generated by ClearNamedBufferSubData if
2842  *  offset or size is negative, or if offset+size is greater than the value
2843  *  of BUFFER_SIZE for the buffer object.
2844  *
2845  *  Check that INVALID_OPERATION is generated by ClearNamedBufferSubData
2846  *  if any part of the specified range of the buffer object is mapped with
2847  *  MapBufferRange or MapBuffer, unless it was mapped with the
2848  *  MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.
2849  *
2850  *  Check that INVALID_VALUE is generated by ClearNamedBufferSubData if format is not
2851  *  a valid format, or type is not a valid type.
2852  *
2853  *  True if test case succeeded, false otherwise.
2854  */
TestErrorsOfClearNamedBufferSubData()2855 bool ErrorsTest::TestErrorsOfClearNamedBufferSubData()
2856 {
2857 	/* Shortcut for GL functionality. */
2858 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2859 
2860 	/* Return value. */
2861 	bool is_ok			= true;
2862 	bool internal_error = false;
2863 
2864 	/* Common variables. */
2865 	glw::GLuint  buffer		   = 0;
2866 	glw::GLubyte unused_data[4] = {};
2867 
2868 	try
2869 	{
2870 		/* Common preparations. */
2871 		gl.createBuffers(1, &buffer);
2872 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
2873 
2874 		m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data,
2875 							  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
2876 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
2877 
2878 		/* Test invalid buffer name error behavior. */
2879 		{
2880 			/* Prepare for invalid buffer name error behavior verification. */
2881 			glw::GLuint not_a_buffer_name = 0;
2882 
2883 			while (gl.isBuffer(++not_a_buffer_name))
2884 				;
2885 
2886 			/* Test. */
2887 			m_pClearNamedBufferSubData(not_a_buffer_name, GL_R8, 0, sizeof(unused_data), GL_RGBA, GL_UNSIGNED_BYTE,
2888 									   &unused_data);
2889 
2890 			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_OPERATION,
2891 									  " if buffer is not the name of an existing buffer object.");
2892 		}
2893 
2894 		/* Test invalid sized internal format error behavior. */
2895 		{
2896 			/* Prepare for invalid sized internal format error behavior verification. */
2897 			static const glw::GLenum valid_internal_formats[] = {
2898 				GL_R8,		GL_R16,		GL_R16F,	GL_R32F,	 GL_R8I,	  GL_R16I,	GL_R32I,
2899 				GL_R8UI,	GL_R16UI,   GL_R32UI,   GL_RG8,		 GL_RG16,	 GL_RG16F,   GL_RG32F,
2900 				GL_RG8I,	GL_RG16I,   GL_RG32I,   GL_RG8UI,	GL_RG16UI,   GL_RG32UI,  GL_RGB32F,
2901 				GL_RGB32I,  GL_RGB32UI, GL_RGBA8,   GL_RGBA16,   GL_RGBA16F,  GL_RGBA32F, GL_RGBA8I,
2902 				GL_RGBA16I, GL_RGBA32I, GL_RGBA8UI, GL_RGBA16UI, GL_RGBA32UI, GL_NONE
2903 			};
2904 			static const glw::GLenum valid_internal_formats_last =
2905 				sizeof(valid_internal_formats) / sizeof(valid_internal_formats[0]) - 1;
2906 
2907 			glw::GLenum invalid_internal_format = 0;
2908 
2909 			while (&valid_internal_formats[valid_internal_formats_last] !=
2910 				   std::find(&valid_internal_formats[0], &valid_internal_formats[valid_internal_formats_last],
2911 							 (++invalid_internal_format)))
2912 				;
2913 
2914 			/* Test. */
2915 			m_pClearNamedBufferData(buffer, invalid_internal_format, GL_RGBA, GL_UNSIGNED_BYTE, &unused_data);
2916 
2917 			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_ENUM,
2918 									  " if internal format is not one of the valid sized internal formats "
2919 									  "(GL_R8, GL_R16, GL_R16F, GL_R32F, GL_R8I, GL_R16I, GL_R32I, GL_R8UI,"
2920 									  " GL_R16UI, GL_R32UI, GL_RG8, GL_RG16, GL_RG16F, GL_RG32F, GL_RG8I, GL_RG16I,"
2921 									  " GL_RG32I, GL_RG8UI, GL_RG16UI, GL_RG32UI, GL_RGB32F, GL_RGB32I, GL_RGB32UI,"
2922 									  " GL_RGBA8, GL_RGBA16, GL_RGBA16F, GL_RGBA32F, GL_RGBA8I, GL_RGBA16I, GL_RGBA32I,"
2923 									  " GL_RGBA8UI, GL_RGBA16UI, GL_RGBA32UI).");
2924 		}
2925 
2926 		/* Test incorrect offset alignment error behavior. */
2927 		{
2928 			/* Test. */
2929 			m_pClearNamedBufferSubData(buffer, GL_RGBA8, sizeof(unused_data[0]), sizeof(unused_data), GL_RGBA,
2930 									   GL_UNSIGNED_BYTE, &unused_data);
2931 
2932 			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_VALUE,
2933 									  "if offset is not multiples of the number of basic machine units (GLubyte)"
2934 									  "per-element for the internal format (GL_RGBA) specified by internal format.");
2935 		}
2936 
2937 		/* Test incorrect range alignment error behavior. */
2938 		{
2939 			m_pClearNamedBufferSubData(buffer, GL_RGBA8, 0, sizeof(unused_data) - sizeof(unused_data[0]), GL_RGBA,
2940 									   GL_UNSIGNED_BYTE, &unused_data);
2941 
2942 			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_VALUE,
2943 									  "if range is not multiples of the number of basic machine units (GLubyte)"
2944 									  "per-element for the internal format (GL_RGBA) specified by internal format.");
2945 		}
2946 
2947 		/* Test negative offset error behavior. */
2948 		{
2949 			/* Test. */
2950 			m_pClearNamedBufferSubData(buffer, GL_R8, -1, sizeof(unused_data), GL_RGBA, GL_UNSIGNED_BYTE, &unused_data);
2951 
2952 			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_VALUE, " if offset or size is negative.");
2953 		}
2954 
2955 		/* Test negative size error behavior. */
2956 		{
2957 			/* Test. */
2958 			m_pClearNamedBufferSubData(buffer, GL_R8, 0, -((glw::GLsizei)sizeof(unused_data)), GL_RGBA, GL_UNSIGNED_BYTE,
2959 									   &unused_data);
2960 
2961 			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_VALUE, " if offset or size is negative.");
2962 		}
2963 
2964 		/* Test size overflow error behavior. */
2965 		{
2966 			/* Test. */
2967 			m_pClearNamedBufferSubData(buffer, GL_R8, 0, 2 * sizeof(unused_data), GL_RGBA, GL_UNSIGNED_BYTE,
2968 									   &unused_data);
2969 
2970 			is_ok &= ErrorCheckAndLog(
2971 				"glClearNamedBufferSubData", GL_INVALID_VALUE,
2972 				" if offset+size is greater than the value of BUFFER_SIZE for the specified buffer object.");
2973 		}
2974 
2975 		/* Test of mapped buffer clear error behavior verification (glMapNamedBuffer version). */
2976 		{
2977 			(void)(glw::GLbyte*) m_pMapNamedBuffer(buffer, GL_READ_ONLY);
2978 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
2979 
2980 			m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(unused_data), GL_RGBA, GL_UNSIGNED_BYTE, &unused_data);
2981 
2982 			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_OPERATION,
2983 									  " if any part of the specified range of the buffer"
2984 									  " object is mapped with MapBuffer, unless it was mapped with "
2985 									  "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");
2986 
2987 			m_pUnmapNamedBuffer(buffer);
2988 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
2989 		}
2990 
2991 		/* Test of mapped buffer clear error behavior verification (glMapNamedBufferRange version). */
2992 		{
2993 			(void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_READ_BIT);
2994 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
2995 
2996 			m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(unused_data), GL_RGBA, GL_UNSIGNED_BYTE, &unused_data);
2997 
2998 			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_OPERATION,
2999 									  " if any part of the specified range of the buffer"
3000 									  " object is mapped with MapBufferRange, unless it was mapped with "
3001 									  "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");
3002 
3003 			m_pUnmapNamedBuffer(buffer);
3004 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3005 		}
3006 
3007 		/* Test of persistently mapped buffer clear error with behavior verification (glMapNamedBufferRange version). */
3008 		{
3009 			(void)(glw::GLbyte*)
3010 				m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
3011 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3012 
3013 			m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(unused_data), GL_RGBA, GL_UNSIGNED_BYTE, &unused_data);
3014 
3015 			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_NO_ERROR,
3016 									  " if any part of the specified range of the buffer"
3017 									  " object is mapped with MapBuffer with the MAP_PERSISTENT_BIT"
3018 									  " bit set in the MapBufferRange access flags.");
3019 
3020 			m_pUnmapNamedBuffer(buffer);
3021 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3022 		}
3023 
3024 		/* Test invalid format error behavior. */
3025 		{
3026 			/* Prepare for invalid format error behavior verification. */
3027 			static const glw::GLenum valid_formats[] = { GL_RED,		   GL_RG,
3028 														 GL_RGB,		   GL_BGR,
3029 														 GL_RGBA,		   GL_BGRA,
3030 														 GL_RED_INTEGER,   GL_RG_INTEGER,
3031 														 GL_RGB_INTEGER,   GL_BGR_INTEGER,
3032 														 GL_RGBA_INTEGER,  GL_BGRA_INTEGER,
3033 														 GL_STENCIL_INDEX, GL_DEPTH_COMPONENT,
3034 														 GL_DEPTH_STENCIL };
3035 			static const glw::GLenum valid_formats_last = sizeof(valid_formats) / sizeof(valid_formats[0]) - 1;
3036 
3037 			glw::GLenum invalid_format = 0;
3038 
3039 			while (&valid_formats[valid_formats_last] !=
3040 				   std::find(&valid_formats[0], &valid_formats[valid_formats_last], (++invalid_format)))
3041 				;
3042 
3043 			/* Test. */
3044 			m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(unused_data), invalid_format, GL_UNSIGNED_BYTE,
3045 									   &unused_data);
3046 
3047 			is_ok &= ErrorCheckAndLog(
3048 				"glClearNamedBufferSubData", GL_INVALID_VALUE,
3049 				" if format is not a valid format "
3050 				"(one of GL_RED, GL_RG, GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, "
3051 				"GL_RED_INTEGER, GL_RG_INTEGER, GL_RGB_INTEGER, GL_BGR_INTEGER, GL_RGBA_INTEGER, GL_BGRA_INTEGER, "
3052 				"GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL).");
3053 		}
3054 
3055 		/* Test invalid type error behavior. */
3056 		{
3057 			/* Prepare for invalid type error behavior verification. */
3058 			static const glw::GLenum valid_types[] = { GL_RED,			 GL_RG,
3059 													   GL_RGB,			 GL_BGR,
3060 													   GL_RGBA,			 GL_BGRA,
3061 													   GL_RED_INTEGER,   GL_RG_INTEGER,
3062 													   GL_RGB_INTEGER,   GL_BGR_INTEGER,
3063 													   GL_RGBA_INTEGER,  GL_BGRA_INTEGER,
3064 													   GL_STENCIL_INDEX, GL_DEPTH_COMPONENT,
3065 													   GL_DEPTH_STENCIL, GL_NONE };
3066 			static const glw::GLenum valid_types_last = sizeof(valid_types) / sizeof(valid_types[0]) - 1;
3067 
3068 			glw::GLenum invalid_type = 0;
3069 
3070 			while (&valid_types[valid_types_last] !=
3071 				   std::find(&valid_types[0], &valid_types[valid_types_last], (++invalid_type)))
3072 				;
3073 
3074 			/* Test. */
3075 			m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(unused_data), GL_RGBA, invalid_type, &unused_data);
3076 
3077 			is_ok &= ErrorCheckAndLog(
3078 				"glClearNamedBufferSubData", GL_INVALID_VALUE,
3079 				" if format is not a valid type "
3080 				"(one of GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, "
3081 				"GL_SHORT, GL_UNSIGNED_INT, GL_INT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, "
3082 				"GL_UNSIGNED_BYTE_2_3_3_REV, GL_UNSIGNED_SHORT_5_6_5, "
3083 				"GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, "
3084 				"GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_UNSIGNED_INT_8_8_8_8, "
3085 				"GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2, and GL_UNSIGNED_INT_2_10_10_10_REV).");
3086 		}
3087 	}
3088 	catch (...)
3089 	{
3090 		is_ok		   = false;
3091 		internal_error = true;
3092 	}
3093 
3094 	if (buffer)
3095 	{
3096 		gl.deleteBuffers(1, &buffer);
3097 
3098 		buffer = 0;
3099 	}
3100 
3101 	if (internal_error)
3102 	{
3103 		throw 0;
3104 	}
3105 
3106 	return is_ok;
3107 }
3108 
3109 /** @brief Test Errors Of CopyNamedBufferSubData function.
3110  *
3111  *  Check that INVALID_OPERATION is generated by CopyNamedBufferSubData if readBuffer
3112  *  or writeBuffer is not the name of an existing buffer object.
3113  *
3114  *  Check that INVALID_VALUE is generated by CopyNamedBufferSubData if any of
3115  *  readOffset, writeOffset or size is negative, if readOffset+size is
3116  *  greater than the size of the source buffer object (its value of
3117  *  BUFFER_SIZE), or if writeOffset+size is greater than the size of the
3118  *  destination buffer object.
3119  *
3120  *  Check that INVALID_VALUE is generated by CopyNamedBufferSubData if the
3121  *  source and destination are the same buffer object, and the ranges
3122  *  [readOffset,readOffset+size) and [writeOffset,writeOffset+size) overlap.
3123  *
3124  *  Check that INVALID_OPERATION is generated by CopyNamedBufferSubData if
3125  *  either the source or destination buffer object is mapped with
3126  *  MapBufferRange or MapBuffer, unless they were mapped with the
3127  *  MAP_PERSISTENT bit set in the MapBufferRange access flags.
3128  *
3129  *  True if test case succeeded, false otherwise.
3130  */
TestErrorsOfCopyNamedBufferSubData()3131 bool ErrorsTest::TestErrorsOfCopyNamedBufferSubData()
3132 {
3133 	/* Shortcut for GL functionality. */
3134 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3135 
3136 	/* Return value. */
3137 	bool is_ok			= true;
3138 	bool internal_error = false;
3139 
3140 	/* Common variables. */
3141 	glw::GLuint  buffer_r	  = 0;
3142 	glw::GLuint  buffer_w	  = 0;
3143 	glw::GLubyte unused_data[4] = {};
3144 
3145 	try
3146 	{
3147 		/* Common preparations. */
3148 		gl.createBuffers(1, &buffer_r);
3149 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
3150 
3151 		m_pNamedBufferStorage(buffer_r, sizeof(unused_data), &unused_data,
3152 							  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
3153 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
3154 
3155 		gl.createBuffers(1, &buffer_w);
3156 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
3157 
3158 		m_pNamedBufferStorage(buffer_w, sizeof(unused_data), &unused_data,
3159 							  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
3160 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
3161 
3162 		/* Test invalid buffer name error behavior. */
3163 		{
3164 			/* Prepare for invalid buffer name error behavior verification. */
3165 			glw::GLuint not_a_buffer_name = 0;
3166 
3167 			while (gl.isBuffer(++not_a_buffer_name))
3168 				;
3169 
3170 			/* Test. */
3171 			m_pCopyNamedBufferSubData(not_a_buffer_name, buffer_w, 0, 0, sizeof(unused_data));
3172 
3173 			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
3174 									  " if readBuffer is not the name of an existing buffer object.");
3175 
3176 			m_pCopyNamedBufferSubData(buffer_r, not_a_buffer_name, 0, 0, sizeof(unused_data));
3177 
3178 			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
3179 									  " if writeBuffer is not the name of an existing buffer object.");
3180 		}
3181 
3182 		/* Test negative read offset error behavior. */
3183 		{
3184 			/* Test. */
3185 			m_pCopyNamedBufferSubData(buffer_r, buffer_w, -1, 0, sizeof(unused_data));
3186 
3187 			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE, "if readOffset is negative.");
3188 		}
3189 
3190 		/* Test negative write offset error behavior. */
3191 		{
3192 			/* Test. */
3193 			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, -1, sizeof(unused_data));
3194 
3195 			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE, "if writeOffset is negative.");
3196 		}
3197 
3198 		/* Test negative size error behavior. */
3199 		{
3200 			/* Test. */
3201 			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, -1);
3202 
3203 			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE, "if size is negative.");
3204 		}
3205 
3206 		/* Test overflow size error behavior. */
3207 		{
3208 			/* Test. */
3209 			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, 2 * sizeof(unused_data));
3210 
3211 			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE,
3212 									  " if size is greater than the size of the source buffer object.");
3213 		}
3214 
3215 		/* Test overflow read offset and size error behavior. */
3216 		{
3217 			/* Test. */
3218 			m_pCopyNamedBufferSubData(buffer_r, buffer_w, sizeof(unused_data) / 2, 0, sizeof(unused_data));
3219 
3220 			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE,
3221 									  " if readOffset+size is greater than the size of the source buffer object.");
3222 		}
3223 
3224 		/* Test overflow write offset and size error behavior. */
3225 		{
3226 			/* Test. */
3227 			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, sizeof(unused_data) / 2, sizeof(unused_data));
3228 
3229 			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE,
3230 									  " if writeOffset+size is greater than the size of the source buffer object.");
3231 		}
3232 
3233 		/* Test same buffer overlapping error behavior. */
3234 		{
3235 			/* Test. */
3236 			m_pCopyNamedBufferSubData(buffer_w, buffer_w, 0, 0, sizeof(unused_data));
3237 
3238 			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE,
3239 									  " if the source and destination are the same buffer object, and the ranges"
3240 									  " [readOffset,readOffset+size) and [writeOffset,writeOffset+size) overlap.");
3241 		}
3242 
3243 		/* Test of mapped read buffer copy error behavior verification (glMapNamedBuffer version). */
3244 		{
3245 			(void)(glw::GLbyte*) m_pMapNamedBuffer(buffer_r, GL_READ_ONLY);
3246 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3247 
3248 			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(unused_data));
3249 
3250 			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
3251 									  " if the source buffer object is mapped with MapBuffer.");
3252 
3253 			m_pUnmapNamedBuffer(buffer_r);
3254 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3255 		}
3256 
3257 		/* Test of mapped write buffer copy error behavior verification (glMapNamedBuffer version). */
3258 		{
3259 			(void)(glw::GLbyte*) m_pMapNamedBuffer(buffer_w, GL_READ_ONLY);
3260 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3261 
3262 			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(unused_data));
3263 
3264 			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
3265 									  " if the destination buffer object is mapped with MapBuffer.");
3266 
3267 			m_pUnmapNamedBuffer(buffer_w);
3268 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3269 		}
3270 
3271 		/* Test of mapped read buffer copy error behavior verification (glMapNamedBufferRange version). */
3272 		{
3273 			(void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer_r, 0, sizeof(unused_data), GL_MAP_READ_BIT);
3274 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3275 
3276 			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(unused_data));
3277 
3278 			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
3279 									  " if the source buffer object is mapped with MapBuffer.");
3280 
3281 			m_pUnmapNamedBuffer(buffer_r);
3282 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3283 		}
3284 
3285 		/* Test of mapped write buffer copy error behavior verification (glMapNamedBufferRange version). */
3286 		{
3287 			(void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer_w, 0, sizeof(unused_data), GL_MAP_READ_BIT);
3288 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3289 
3290 			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(unused_data));
3291 
3292 			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
3293 									  " if the destination buffer object is mapped with MapBuffer.");
3294 
3295 			m_pUnmapNamedBuffer(buffer_w);
3296 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3297 		}
3298 
3299 		/* Test of persistently mapped read buffer copy error with behavior verification. */
3300 		{
3301 			(void)(glw::GLbyte*)
3302 				m_pMapNamedBufferRange(buffer_r, 0, sizeof(unused_data), GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
3303 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3304 
3305 			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(unused_data));
3306 
3307 			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_NO_ERROR,
3308 									  " if the source buffer object is mapped using "
3309 									  "MapBufferRange with the MAP_PERSISTENT bit "
3310 									  "set in the access flags.");
3311 
3312 			m_pUnmapNamedBuffer(buffer_r);
3313 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3314 		}
3315 
3316 		/* Test of persistently mapped write buffer copy error with behavior verification. */
3317 		{
3318 			(void)(glw::GLbyte*)
3319 				m_pMapNamedBufferRange(buffer_w, 0, sizeof(unused_data), GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
3320 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3321 
3322 			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(unused_data));
3323 
3324 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3325 			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_NO_ERROR,
3326 									  " if the destination buffer object is mapped using "
3327 									  "MapBufferRange with the MAP_PERSISTENT bit "
3328 									  "set in the access flags.");
3329 
3330 			m_pUnmapNamedBuffer(buffer_w);
3331 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3332 		}
3333 	}
3334 	catch (...)
3335 	{
3336 		is_ok		   = false;
3337 		internal_error = true;
3338 	}
3339 
3340 	if (buffer_r)
3341 	{
3342 		gl.deleteBuffers(1, &buffer_r);
3343 
3344 		buffer_r = 0;
3345 	}
3346 
3347 	if (buffer_r)
3348 	{
3349 		gl.deleteBuffers(1, &buffer_r);
3350 
3351 		buffer_r = 0;
3352 	}
3353 
3354 	if (internal_error)
3355 	{
3356 		throw 0;
3357 	}
3358 
3359 	return is_ok;
3360 }
3361 
3362 /** @brief Test Errors Of CreateBuffers function.
3363  *
3364  *  Check that INVALID_VALUE is generated by CreateBuffers if n is negative.
3365  *
3366  *  True if test case succeeded, false otherwise.
3367  */
TestErrorsOfCreateBuffers()3368 bool ErrorsTest::TestErrorsOfCreateBuffers()
3369 {
3370 	/* Shortcut for GL functionality. */
3371 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3372 
3373 	/* Return value. */
3374 	bool is_ok = true;
3375 
3376 	/* Test. */
3377 	glw::GLuint buffer = 0;
3378 
3379 	gl.createBuffers(-1, &buffer);
3380 
3381 	is_ok &= ErrorCheckAndLog("glCreateBuffers", GL_INVALID_VALUE, " if n is negative.");
3382 
3383 	/* Sanity check. */
3384 	if (buffer)
3385 	{
3386 		gl.deleteBuffers(1, &buffer);
3387 
3388 		/* Possible error cleanup. */
3389 		while (gl.getError())
3390 			;
3391 	}
3392 
3393 	return is_ok;
3394 }
3395 
3396 /** @brief Test Errors Of FlushMappedNamedBufferRange function.
3397  *
3398  *  Check that INVALID_OPERATION is generated by FlushMappedNamedBufferRange
3399  *  if buffer is not the name of an existing buffer object.
3400  *
3401  *  Check that INVALID_VALUE is generated by FlushMappedNamedBufferRange if
3402  *  offset or length is negative, or if offset + length exceeds the size of
3403  *  the mapping.
3404  *
3405  *  Check that INVALID_OPERATION is generated by FlushMappedNamedBufferRange
3406  *  if the buffer object is not mapped, or is mapped without the
3407  *  MAP_FLUSH_EXPLICIT_BIT flag.
3408  *
3409  *  True if test case succeeded, false otherwise.
3410  */
TestErrorsOfFlushMappedNamedBufferRange()3411 bool ErrorsTest::TestErrorsOfFlushMappedNamedBufferRange()
3412 {
3413 	/* Shortcut for GL functionality. */
3414 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3415 
3416 	/* Return value. */
3417 	bool is_ok			= true;
3418 	bool internal_error = false;
3419 
3420 	/* Common variables. */
3421 	glw::GLuint  buffer		   = 0;
3422 	glw::GLubyte unused_data[4] = {};
3423 
3424 	try
3425 	{
3426 		/* Common preparations. */
3427 		gl.createBuffers(1, &buffer);
3428 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
3429 
3430 		m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
3431 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
3432 
3433 		/* Test invalid buffer name flush error behavior. */
3434 		{
3435 			/* Prepare for invalid buffer name error behavior verification. */
3436 			glw::GLuint not_a_buffer_name = 0;
3437 
3438 			while (gl.isBuffer(++not_a_buffer_name))
3439 				;
3440 
3441 			/* Test. */
3442 			m_pFlushMappedNamedBufferRange(not_a_buffer_name, 0, 1);
3443 
3444 			is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_OPERATION,
3445 									  " if buffer is not the name of an existing buffer object.");
3446 		}
3447 
3448 		/* Test negative offset flush error behavior. */
3449 		{
3450 			(void)(glw::GLbyte*)
3451 				m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
3452 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3453 
3454 			m_pFlushMappedNamedBufferRange(buffer, -1, 1);
3455 
3456 			is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_VALUE, " if offset is negative.");
3457 
3458 			m_pUnmapNamedBuffer(buffer);
3459 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3460 		}
3461 
3462 		/* Test negative length flush error behavior. */
3463 		{
3464 			(void)(glw::GLbyte*)
3465 				m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
3466 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3467 
3468 			m_pFlushMappedNamedBufferRange(buffer, 0, -1);
3469 
3470 			is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_VALUE, " if length is negative.");
3471 
3472 			m_pUnmapNamedBuffer(buffer);
3473 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3474 		}
3475 
3476 		/* Test length exceeds the mapping size flush error behavior. */
3477 		{
3478 			(void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data) / 2,
3479 														GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
3480 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3481 
3482 			m_pFlushMappedNamedBufferRange(buffer, 0, sizeof(unused_data));
3483 
3484 			is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_VALUE,
3485 									  " if length exceeds the size of the mapping.");
3486 
3487 			m_pUnmapNamedBuffer(buffer);
3488 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3489 		}
3490 
3491 		/* Test offset + length exceeds the mapping size flush error behavior. */
3492 		{
3493 			(void)(glw::GLbyte*)
3494 				m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
3495 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3496 
3497 			m_pFlushMappedNamedBufferRange(buffer, 1, sizeof(unused_data));
3498 
3499 			is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_VALUE,
3500 									  " if offset + length exceeds the size of the mapping.");
3501 
3502 			m_pUnmapNamedBuffer(buffer);
3503 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3504 		}
3505 
3506 		/* Test not mapped buffer flush error behavior. */
3507 		{
3508 			m_pFlushMappedNamedBufferRange(buffer, 0, sizeof(unused_data));
3509 
3510 			is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_OPERATION,
3511 									  " if the buffer object is not mapped.");
3512 		}
3513 
3514 		/* Test buffer flush without the MAP_FLUSH_EXPLICIT_BIT error behavior. */
3515 		{
3516 			(void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_WRITE_BIT);
3517 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3518 
3519 			m_pFlushMappedNamedBufferRange(buffer, 0, sizeof(unused_data));
3520 
3521 			is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_OPERATION,
3522 									  " if the buffer is mapped without the MAP_FLUSH_EXPLICIT_BIT flag.");
3523 
3524 			m_pUnmapNamedBuffer(buffer);
3525 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3526 		}
3527 	}
3528 	catch (...)
3529 	{
3530 		is_ok		   = false;
3531 		internal_error = true;
3532 	}
3533 
3534 	if (buffer)
3535 	{
3536 		gl.deleteBuffers(1, &buffer);
3537 
3538 		buffer = 0;
3539 	}
3540 
3541 	if (internal_error)
3542 	{
3543 		throw 0;
3544 	}
3545 
3546 	return is_ok;
3547 }
3548 
3549 /** @brief Test Errors Of GetNamedBufferParameteriv
3550  *         and GetNamedBufferParameteri64v functions.
3551  *
3552  *  Check that INVALID_OPERATION is generated by GetNamedBufferParameter* if
3553  *  buffer is not the name of an existing buffer object.
3554  *
3555  *  Check that INVALID_ENUM is generated by GetNamedBufferParameter* if
3556  *  pname is not one of the buffer object parameter names: BUFFER_ACCESS,
3557  *  BUFFER_ACCESS_FLAGS, BUFFER_IMMUTABLE_STORAGE, BUFFER_MAPPED,
3558  *  BUFFER_MAP_LENGTH, BUFFER_MAP_OFFSET, BUFFER_SIZE, BUFFER_STORAGE_FLAGS,
3559  *  BUFFER_USAGE.
3560  *
3561  *  True if test case succeeded, false otherwise.
3562  */
TestErrorsOfGetNamedBufferParameter()3563 bool ErrorsTest::TestErrorsOfGetNamedBufferParameter()
3564 {
3565 	/* Shortcut for GL functionality. */
3566 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3567 
3568 	/* Return value. */
3569 	bool is_ok			= true;
3570 	bool internal_error = false;
3571 
3572 	/* Common variables. */
3573 	glw::GLuint  buffer		   = 0;
3574 	glw::GLubyte unused_data[4] = {};
3575 
3576 	try
3577 	{
3578 		/* Common preparations. */
3579 		gl.createBuffers(1, &buffer);
3580 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
3581 
3582 		m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
3583 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
3584 
3585 		/* Test invalid buffer name in GetNamedBufferParameteriv function error behavior. */
3586 		{
3587 			/* Prepare for invalid buffer name error behavior verification. */
3588 			glw::GLuint not_a_buffer_name = 0;
3589 
3590 			while (gl.isBuffer(++not_a_buffer_name))
3591 				;
3592 
3593 			glw::GLint value = 0;
3594 
3595 			/* Test. */
3596 			m_pGetNamedBufferParameteriv(not_a_buffer_name, GL_BUFFER_MAPPED, &value);
3597 
3598 			is_ok &= ErrorCheckAndLog("glGetNamedBufferParameteriv", GL_INVALID_OPERATION,
3599 									  " if buffer is not the name of an existing buffer object.");
3600 		}
3601 
3602 		/* Test invalid buffer name in GetNamedBufferParameteri64v function error behavior. */
3603 		{
3604 			/* Prepare for invalid buffer name error behavior verification. */
3605 			glw::GLuint not_a_buffer_name = 0;
3606 
3607 			while (gl.isBuffer(++not_a_buffer_name))
3608 				;
3609 
3610 			glw::GLint64 value = 0;
3611 
3612 			/* Test. */
3613 			m_pGetNamedBufferParameteri64v(not_a_buffer_name, GL_BUFFER_MAPPED, &value);
3614 
3615 			is_ok &= ErrorCheckAndLog("glGetNamedBufferParameteri64v", GL_INVALID_OPERATION,
3616 									  " if buffer is not the name of an existing buffer object.");
3617 		}
3618 
3619 		/* Test invalid parameter name in GetNamedBufferParameteriv function error behavior. */
3620 		{
3621 			/* Prepare for invalid parameter name error behavior verification. */
3622 			static const glw::GLenum valid_parameters[] = {
3623 				GL_BUFFER_ACCESS, GL_BUFFER_ACCESS_FLAGS,  GL_BUFFER_IMMUTABLE_STORAGE,
3624 				GL_BUFFER_MAPPED, GL_BUFFER_MAP_LENGTH,	GL_BUFFER_MAP_OFFSET,
3625 				GL_BUFFER_SIZE,   GL_BUFFER_STORAGE_FLAGS, GL_BUFFER_USAGE,
3626 				GL_NONE
3627 			};
3628 			static const glw::GLenum valid_parameters_last = sizeof(valid_parameters) / sizeof(valid_parameters[0]) - 1;
3629 
3630 			glw::GLint value = 0;
3631 
3632 			glw::GLenum invalid_parameter = 0;
3633 
3634 			while (&valid_parameters[valid_parameters_last] !=
3635 				   std::find(&valid_parameters[0], &valid_parameters[valid_parameters_last], (++invalid_parameter)))
3636 				;
3637 
3638 			/* Test. */
3639 			m_pGetNamedBufferParameteriv(buffer, invalid_parameter, &value);
3640 
3641 			is_ok &= ErrorCheckAndLog("glGetNamedBufferParameteriv", GL_INVALID_ENUM,
3642 									  " if pname is not one of the buffer object parameter names: BUFFER_ACCESS,"
3643 									  " BUFFER_ACCESS_FLAGS, BUFFER_IMMUTABLE_STORAGE, BUFFER_MAPPED,"
3644 									  " BUFFER_MAP_LENGTH, BUFFER_MAP_OFFSET, BUFFER_SIZE, BUFFER_STORAGE_FLAGS,"
3645 									  " BUFFER_USAGE.");
3646 		}
3647 
3648 		/* Test invalid parameter name in GetNamedBufferParameteri64v function error behavior. */
3649 		{
3650 			/* Prepare for invalid parameter name error behavior verification. */
3651 			static const glw::GLenum valid_parameters[] = {
3652 				GL_BUFFER_ACCESS, GL_BUFFER_ACCESS_FLAGS,  GL_BUFFER_IMMUTABLE_STORAGE,
3653 				GL_BUFFER_MAPPED, GL_BUFFER_MAP_LENGTH,	GL_BUFFER_MAP_OFFSET,
3654 				GL_BUFFER_SIZE,   GL_BUFFER_STORAGE_FLAGS, GL_BUFFER_USAGE,
3655 				GL_NONE
3656 			};
3657 			static const glw::GLenum valid_parameters_last = sizeof(valid_parameters) / sizeof(valid_parameters[0]) - 1;
3658 
3659 			glw::GLint64 value = 0;
3660 
3661 			glw::GLenum invalid_parameter = 0;
3662 
3663 			while (&valid_parameters[valid_parameters_last] !=
3664 				   std::find(&valid_parameters[0], &valid_parameters[valid_parameters_last], (++invalid_parameter)))
3665 				;
3666 
3667 			/* Test. */
3668 			m_pGetNamedBufferParameteri64v(buffer, invalid_parameter, &value);
3669 
3670 			is_ok &= ErrorCheckAndLog("glGetNamedBufferParameteri64v", GL_INVALID_ENUM,
3671 									  " if pname is not one of the buffer object parameter names: BUFFER_ACCESS,"
3672 									  " BUFFER_ACCESS_FLAGS, BUFFER_IMMUTABLE_STORAGE, BUFFER_MAPPED,"
3673 									  " BUFFER_MAP_LENGTH, BUFFER_MAP_OFFSET, BUFFER_SIZE, BUFFER_STORAGE_FLAGS,"
3674 									  " BUFFER_USAGE.");
3675 		}
3676 	}
3677 	catch (...)
3678 	{
3679 		is_ok		   = false;
3680 		internal_error = true;
3681 	}
3682 
3683 	if (buffer)
3684 	{
3685 		gl.deleteBuffers(1, &buffer);
3686 
3687 		buffer = 0;
3688 	}
3689 
3690 	if (internal_error)
3691 	{
3692 		throw 0;
3693 	}
3694 
3695 	return is_ok;
3696 }
3697 
3698 /** @brief Test Errors Of GetNamedBufferPointerv function.
3699  *
3700  *  Check that INVALID_OPERATION is generated by GetNamedBufferPointerv
3701  *  if buffer is not the name of an existing buffer object.
3702  *
3703  *  True if test case succeeded, false otherwise.
3704  */
TestErrorsOfGetNamedBufferPointerv()3705 bool ErrorsTest::TestErrorsOfGetNamedBufferPointerv()
3706 {
3707 	/* Shortcut for GL functionality. */
3708 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3709 
3710 	/* Return value. */
3711 	bool is_ok			= true;
3712 	bool internal_error = false;
3713 
3714 	/* Common variables. */
3715 	glw::GLuint  buffer		   = 0;
3716 	glw::GLubyte unused_data[4] = {};
3717 
3718 	try
3719 	{
3720 		/* Common preparations. */
3721 		gl.createBuffers(1, &buffer);
3722 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
3723 
3724 		m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
3725 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
3726 
3727 		/* Test invalid buffer name in GetNamedBufferPointerv function error behavior. */
3728 		{
3729 			/* Prepare for invalid buffer name error behavior verification. */
3730 			glw::GLuint not_a_buffer_name = 0;
3731 
3732 			while (gl.isBuffer(++not_a_buffer_name))
3733 				;
3734 
3735 			glw::GLvoid* pointer = DE_NULL;
3736 
3737 			/* Test. */
3738 			m_pGetNamedBufferPointerv(not_a_buffer_name, GL_BUFFER_MAP_POINTER, &pointer);
3739 
3740 			is_ok &= ErrorCheckAndLog("glGetNamedBufferPointerv", GL_INVALID_OPERATION,
3741 									  " if buffer is not the name of an existing buffer object.");
3742 		}
3743 	}
3744 	catch (...)
3745 	{
3746 		is_ok		   = false;
3747 		internal_error = true;
3748 	}
3749 
3750 	if (buffer)
3751 	{
3752 		gl.deleteBuffers(1, &buffer);
3753 
3754 		buffer = 0;
3755 	}
3756 
3757 	if (internal_error)
3758 	{
3759 		throw 0;
3760 	}
3761 
3762 	return is_ok;
3763 }
3764 
3765 /** @brief Test Errors Of GetNamedBufferSubData function.
3766  *
3767  *  Check that INVALID_OPERATION is generated by GetNamedBufferSubData if
3768  *  buffer is not the name of an existing buffer object.
3769  *
3770  *  Check that INVALID_VALUE is generated by GetNamedBufferSubData if offset
3771  *  or size is negative, or if offset+size is greater than the value of
3772  *  BUFFER_SIZE for the buffer object.
3773  *
3774  *  Check that INVALID_OPERATION is generated by GetNamedBufferSubData if
3775  *  the buffer object is mapped with MapBufferRange or MapBuffer, unless it
3776  *  was mapped with the MAP_PERSISTENT_BIT bit set in the MapBufferRange
3777  *  access flags.
3778  *
3779  *  True if test case succeeded, false otherwise.
3780  */
TestErrorsOfGetNamedBufferSubData()3781 bool ErrorsTest::TestErrorsOfGetNamedBufferSubData()
3782 {
3783 	/* Shortcut for GL functionality. */
3784 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3785 
3786 	/* Return value. */
3787 	bool is_ok			= true;
3788 	bool internal_error = false;
3789 
3790 	/* Common variables. */
3791 	glw::GLuint  buffer		   = 0;
3792 	glw::GLubyte unused_data[4] = {};
3793 
3794 	try
3795 	{
3796 		/* Common preparations. */
3797 		gl.createBuffers(1, &buffer);
3798 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
3799 
3800 		m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
3801 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
3802 
3803 		/* Test invalid buffer name in pGetNamedBufferSubData function error behavior. */
3804 		{
3805 			/* Prepare for invalid buffer name error behavior verification. */
3806 			glw::GLuint not_a_buffer_name = 0;
3807 
3808 			while (gl.isBuffer(++not_a_buffer_name))
3809 				;
3810 
3811 			/* Query storage. */
3812 			glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3813 
3814 			/* Test. */
3815 			m_pGetNamedBufferSubData(not_a_buffer_name, 0, sizeof(unused_data_query), unused_data_query);
3816 
3817 			is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_OPERATION,
3818 									  " if buffer is not the name of an existing buffer object.");
3819 		}
3820 
3821 		/* Test negative offset error behavior. */
3822 		{
3823 			/* Query storage. */
3824 			glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3825 
3826 			/* Test. */
3827 			m_pGetNamedBufferSubData(buffer, -1, sizeof(unused_data_query), unused_data_query);
3828 
3829 			is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE, " if offset is negative.");
3830 		}
3831 
3832 		/* Test negative size error behavior. */
3833 		{
3834 			/* Query storage. */
3835 			glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3836 
3837 			/* Test. */
3838 			m_pGetNamedBufferSubData(buffer, 0, -1, unused_data_query);
3839 
3840 			is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE, " if size is negative.");
3841 		}
3842 
3843 		/* Test size overflow error behavior. */
3844 		{
3845 			/* Query storage. */
3846 			glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3847 
3848 			/* Test. */
3849 			m_pGetNamedBufferSubData(buffer, 0, 2 * sizeof(unused_data_query), unused_data_query);
3850 
3851 			is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE,
3852 									  " if size is greater than the value of BUFFER_SIZE for the buffer object.");
3853 		}
3854 
3855 		/* Test offset+size overflow error behavior. */
3856 		{
3857 			/* Query storage. */
3858 			glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3859 
3860 			/* Test. */
3861 			m_pGetNamedBufferSubData(buffer, sizeof(unused_data_query) / 2, sizeof(unused_data_query),
3862 									 unused_data_query);
3863 
3864 			is_ok &=
3865 				ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE,
3866 								 " if offset+size is greater than the value of BUFFER_SIZE for the buffer object.");
3867 		}
3868 
3869 		/* Test offset overflow error behavior. */
3870 		{
3871 			/* Query storage. */
3872 			glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3873 
3874 			/* Test. */
3875 			m_pGetNamedBufferSubData(buffer, sizeof(unused_data_query) + 1, 0, unused_data_query);
3876 
3877 			is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE,
3878 									  " if offset is greater than the value of BUFFER_SIZE for the buffer object.");
3879 		}
3880 
3881 		/* Test mapped buffer query error behavior. */
3882 		{
3883 			/* Query storage. */
3884 			glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3885 
3886 			/* Test. */
3887 			(void)(glw::GLbyte*) m_pMapNamedBuffer(buffer, GL_WRITE_ONLY);
3888 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3889 
3890 			m_pGetNamedBufferSubData(buffer, 0, sizeof(unused_data_query), unused_data_query);
3891 
3892 			is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_OPERATION,
3893 									  " if the buffer object is mapped with MapBufferRange.");
3894 
3895 			m_pUnmapNamedBuffer(buffer);
3896 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3897 		}
3898 
3899 		/* Test mapped buffer query error behavior. */
3900 		{
3901 			/* Query storage. */
3902 			glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3903 
3904 			/* Test. */
3905 			(void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_WRITE_BIT);
3906 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3907 
3908 			m_pGetNamedBufferSubData(buffer, 0, sizeof(unused_data_query), unused_data_query);
3909 
3910 			is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_OPERATION,
3911 									  " if the buffer object is mapped with MapBufferRange.");
3912 
3913 			m_pUnmapNamedBuffer(buffer);
3914 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3915 		}
3916 
3917 		/* Test persistently mapped buffer query behavior. */
3918 		{
3919 			/* Query storage. */
3920 			glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3921 
3922 			/* Test. */
3923 			(void)(glw::GLbyte*)
3924 				m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
3925 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3926 
3927 			m_pGetNamedBufferSubData(buffer, 0, sizeof(unused_data_query), unused_data_query);
3928 
3929 			is_ok &= ErrorCheckAndLog(
3930 				"glGetNamedBufferSubData", GL_NO_ERROR,
3931 				" if the buffer object is mapped with MapBufferRange with GL_MAP_PERSISTENT_BIT flag.");
3932 
3933 			m_pUnmapNamedBuffer(buffer);
3934 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3935 		}
3936 	}
3937 	catch (...)
3938 	{
3939 		is_ok		   = false;
3940 		internal_error = true;
3941 	}
3942 
3943 	if (buffer)
3944 	{
3945 		gl.deleteBuffers(1, &buffer);
3946 
3947 		buffer = 0;
3948 	}
3949 
3950 	if (internal_error)
3951 	{
3952 		throw 0;
3953 	}
3954 
3955 	return is_ok;
3956 }
3957 
3958 /** @brief Test Errors Of MapNamedBuffer function.
3959  *
3960  *  Check that INVALID_OPERATION is generated by MapNamedBuffer if buffer is
3961  *  not the name of an existing buffer object.
3962  *
3963  *  Check that INVALID_ENUM is generated by MapNamedBuffer if access is not
3964  *  READ_ONLY, WRITE_ONLY, or READ_WRITE.
3965  *
3966  *  Check that INVALID_OPERATION is generated by MapNamedBuffer if the
3967  *  buffer object is in a mapped state.
3968  *
3969  *  True if test case succeeded, false otherwise.
3970  */
TestErrorsOfMapNamedBuffer()3971 bool ErrorsTest::TestErrorsOfMapNamedBuffer()
3972 {
3973 	/* Shortcut for GL functionality. */
3974 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3975 
3976 	/* Return value. */
3977 	bool is_ok			= true;
3978 	bool internal_error = false;
3979 
3980 	/* Common variables. */
3981 	glw::GLuint  buffer		   = 0;
3982 	glw::GLubyte unused_data[4] = {};
3983 
3984 	try
3985 	{
3986 		/* Common preparations. */
3987 		gl.createBuffers(1, &buffer);
3988 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
3989 
3990 		m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
3991 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
3992 
3993 		/* Test invalid buffer name error behavior. */
3994 		{
3995 			/* Prepare for invalid buffer name error behavior verification. */
3996 			glw::GLuint not_a_buffer_name = 0;
3997 
3998 			while (gl.isBuffer(++not_a_buffer_name))
3999 				;
4000 
4001 			/* Test. */
4002 			m_pMapNamedBuffer(not_a_buffer_name, GL_READ_ONLY);
4003 
4004 			is_ok &= ErrorCheckAndLog("glMapNamedBuffer", GL_INVALID_OPERATION,
4005 									  " if buffer is not the name of an existing buffer object.");
4006 		}
4007 
4008 		/* Test access flag error behavior. */
4009 		{
4010 			/* Prepare for invalid type error behavior verification. */
4011 			static const glw::GLenum valid_access_flags[] = { GL_READ_ONLY, GL_WRITE_ONLY, GL_READ_WRITE, GL_NONE };
4012 			static const glw::GLenum valid_access_flags_last =
4013 				sizeof(valid_access_flags) / sizeof(valid_access_flags[0]) - 1;
4014 
4015 			glw::GLenum invalid_access_flags = 0;
4016 
4017 			while (&valid_access_flags[valid_access_flags_last] !=
4018 				   std::find(&valid_access_flags[0], &valid_access_flags[valid_access_flags_last],
4019 							 (++invalid_access_flags)))
4020 				;
4021 
4022 			/* Test. */
4023 			glw::GLbyte* mapped_data = (glw::GLbyte*)m_pMapNamedBuffer(buffer, invalid_access_flags);
4024 
4025 			is_ok &= ErrorCheckAndLog("glMapNamedBuffer", GL_INVALID_ENUM,
4026 									  " if access is not READ_ONLY, WRITE_ONLY, or READ_WRITE.");
4027 
4028 			/* Sanity unmapping. */
4029 			if (DE_NULL != mapped_data)
4030 			{
4031 				m_pUnmapNamedBuffer(buffer);
4032 				while (gl.getError())
4033 					;
4034 			}
4035 		}
4036 
4037 		/* Test mapping of mapped buffer error behavior. */
4038 		{
4039 			(void)(glw::GLbyte*) m_pMapNamedBuffer(buffer, GL_READ_ONLY);
4040 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer.");
4041 
4042 			glw::GLbyte* subsequent_mapped_data = (glw::GLbyte*)m_pMapNamedBuffer(buffer, GL_READ_ONLY);
4043 
4044 			is_ok &= ErrorCheckAndLog("glMapNamedBuffer", GL_INVALID_OPERATION,
4045 									  " if the buffer object is in a mapped state.");
4046 
4047 			m_pUnmapNamedBuffer(buffer);
4048 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
4049 
4050 			if (subsequent_mapped_data)
4051 			{
4052 				m_context.getTestContext().getLog()
4053 					<< tcu::TestLog::Message
4054 					<< "glMapNamedBuffer called on mapped buffer returned non-NULL pointer when error shall occure."
4055 					   "This may lead to undefined behavior during next tests (object still may be mapped). "
4056 					   "Test was terminated prematurely."
4057 					<< tcu::TestLog::EndMessage;
4058 				throw 0;
4059 			}
4060 		}
4061 	}
4062 	catch (...)
4063 	{
4064 		is_ok		   = false;
4065 		internal_error = true;
4066 	}
4067 
4068 	if (buffer)
4069 	{
4070 		gl.deleteBuffers(1, &buffer);
4071 
4072 		buffer = 0;
4073 	}
4074 
4075 	if (internal_error)
4076 	{
4077 		throw 0;
4078 	}
4079 
4080 	return is_ok;
4081 }
4082 
4083 /** @brief Test Errors Of MapNamedBufferRange function.
4084  *
4085  *  Check that INVALID_OPERATION is generated by MapNamedBufferRange if
4086  *  buffer is not the name of an existing buffer object.
4087  *
4088  *  Check that INVALID_VALUE is generated by MapNamedBufferRange if offset
4089  *  or length is negative, if offset+length is greater than the value of
4090  *  BUFFER_SIZE for the buffer object, or if access has any bits set other
4091  *  than those defined above.
4092  *
4093  *  Check that INVALID_OPERATION is generated by MapNamedBufferRange for any
4094  *  of the following conditions:
4095  *   -  length is zero.
4096  *   -  The buffer object is already in a mapped state.
4097  *   -  Neither MAP_READ_BIT nor MAP_WRITE_BIT is set.
4098  *   -  MAP_READ_BIT is set and any of MAP_INVALIDATE_RANGE_BIT,
4099  *      MAP_INVALIDATE_BUFFER_BIT or MAP_UNSYNCHRONIZED_BIT is set.
4100  *   -  MAP_FLUSH_EXPLICIT_BIT is set and MAP_WRITE_BIT is not set.
4101  *   -  Any of MAP_READ_BIT, MAP_WRITE_BIT, MAP_PERSISTENT_BIT, or
4102  *      MAP_COHERENT_BIT are set, but the same bit is not included in the
4103  *      buffer's storage flags.
4104  *
4105  *  True if test case succeeded, false otherwise.
4106  */
TestErrorsOfMapNamedBufferRange()4107 bool ErrorsTest::TestErrorsOfMapNamedBufferRange()
4108 {
4109 	/* Shortcut for GL functionality. */
4110 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4111 
4112 	/* Return value. */
4113 	bool is_ok			= true;
4114 	bool internal_error = false;
4115 
4116 	/* Common variables. */
4117 	glw::GLuint  buffer				  = 0;
4118 	glw::GLuint  buffer_special_flags = 0;
4119 	glw::GLubyte unused_data[4]		  = {};
4120 
4121 	try
4122 	{
4123 		/* Common preparations. */
4124 		gl.createBuffers(1, &buffer);
4125 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4126 
4127 		m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data,
4128 							  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
4129 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4130 
4131 		/* Test invalid buffer name error behavior. */
4132 		{
4133 			/* Prepare for invalid buffer name error behavior verification. */
4134 			glw::GLuint not_a_buffer_name = 0;
4135 
4136 			while (gl.isBuffer(++not_a_buffer_name))
4137 				;
4138 
4139 			/* Test. */
4140 			m_pMapNamedBufferRange(not_a_buffer_name, 0, sizeof(unused_data), GL_MAP_READ_BIT);
4141 
4142 			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
4143 									  " if buffer is not the name of an existing buffer object.");
4144 		}
4145 
4146 		/* Test negative offset error behavior. */
4147 		{
4148 			glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, -1, sizeof(unused_data), GL_MAP_READ_BIT);
4149 
4150 			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE, " if offset is negative.");
4151 
4152 			/* Sanity unmapping. */
4153 			if (DE_NULL != mapped_data)
4154 			{
4155 				m_pUnmapNamedBuffer(buffer);
4156 				while (gl.getError())
4157 					;
4158 			}
4159 		}
4160 
4161 		/* Test negative length error behavior. */
4162 		{
4163 			glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, 0, -1, GL_MAP_READ_BIT);
4164 
4165 			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE, " if length is negative.");
4166 
4167 			/* Sanity unmapping. */
4168 			if (DE_NULL != mapped_data)
4169 			{
4170 				m_pUnmapNamedBuffer(buffer);
4171 				while (gl.getError())
4172 					;
4173 			}
4174 		}
4175 
4176 		/* Test length overflow error behavior. */
4177 		{
4178 			glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data) * 2, GL_MAP_READ_BIT);
4179 
4180 			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE,
4181 									  " if length is greater than the value of BUFFER_SIZE"
4182 									  " for the buffer object, or if access has any bits set other"
4183 									  " than those defined above.");
4184 
4185 			/* Sanity unmapping. */
4186 			if (DE_NULL != mapped_data)
4187 			{
4188 				m_pUnmapNamedBuffer(buffer);
4189 				while (gl.getError())
4190 					;
4191 			}
4192 		}
4193 
4194 		/* Test (offset+length) overflow error behavior. */
4195 		{
4196 			glw::GLvoid* mapped_data =
4197 				m_pMapNamedBufferRange(buffer, sizeof(unused_data) / 2, sizeof(unused_data), GL_MAP_READ_BIT);
4198 
4199 			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE,
4200 									  " if offset+length is greater than the value of BUFFER_SIZE"
4201 									  " for the buffer object, or if access has any bits set other"
4202 									  " than those defined above.");
4203 
4204 			/* Sanity unmapping. */
4205 			if (DE_NULL != mapped_data)
4206 			{
4207 				m_pUnmapNamedBuffer(buffer);
4208 				while (gl.getError())
4209 					;
4210 			}
4211 		}
4212 
4213 		/* Test zero length error behavior. */
4214 		{
4215 			glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, 0, 0, GL_MAP_READ_BIT);
4216 
4217 			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION, " if length is zero.");
4218 
4219 			/* Sanity unmapping. */
4220 			if (DE_NULL != mapped_data)
4221 			{
4222 				m_pUnmapNamedBuffer(buffer);
4223 				while (gl.getError())
4224 					;
4225 			}
4226 		}
4227 
4228 		/* Test mapping of mapped buffer error behavior. */
4229 		{
4230 			m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_READ_BIT);
4231 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer.");
4232 
4233 			glw::GLvoid* subsequent_mapped_data =
4234 				m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_READ_BIT);
4235 
4236 			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
4237 									  " if the buffer object is in a mapped state.");
4238 
4239 			m_pUnmapNamedBuffer(buffer);
4240 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
4241 
4242 			if (subsequent_mapped_data)
4243 			{
4244 				m_context.getTestContext().getLog()
4245 					<< tcu::TestLog::Message
4246 					<< "glMapNamedBufferRange called on mapped buffer returned non-NULL pointer when error shall "
4247 					   "occure."
4248 					   "This may lead to undefined behavior during next tests (object still may be mapped). "
4249 					   "Test was terminated prematurely."
4250 					<< tcu::TestLog::EndMessage;
4251 				throw 0;
4252 			}
4253 		}
4254 
4255 		/* Test access flag read and write bits are not set error behavior. */
4256 		{
4257 			glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), 0);
4258 
4259 			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
4260 									  " if neither MAP_READ_BIT nor MAP_WRITE_BIT is set.");
4261 
4262 			/* Sanity unmapping. */
4263 			if (DE_NULL != mapped_data)
4264 			{
4265 				m_pUnmapNamedBuffer(buffer);
4266 				while (gl.getError())
4267 					;
4268 			}
4269 		}
4270 
4271 		/* Test read access invalid flags error behavior. */
4272 		{
4273 			glw::GLenum read_access_invalid_flags[] = { GL_MAP_INVALIDATE_RANGE_BIT, GL_MAP_INVALIDATE_BUFFER_BIT,
4274 														GL_MAP_UNSYNCHRONIZED_BIT };
4275 			const glw::GLchar* read_access_invalid_flags_log[] = {
4276 				" if MAP_READ_BIT is set with MAP_INVALIDATE_RANGE_BIT.",
4277 				" if MAP_READ_BIT is set with MAP_INVALIDATE_BUFFER_BIT.",
4278 				" if MAP_READ_BIT is set with MAP_UNSYNCHRONIZED_BIT."
4279 			};
4280 			glw::GLuint read_access_invalid_flags_count =
4281 				sizeof(read_access_invalid_flags) / sizeof(read_access_invalid_flags[0]);
4282 
4283 			for (glw::GLuint i = 0; i < read_access_invalid_flags_count; ++i)
4284 			{
4285 				glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data),
4286 																  GL_MAP_READ_BIT | read_access_invalid_flags[i]);
4287 
4288 				is_ok &=
4289 					ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION, read_access_invalid_flags_log[i]);
4290 
4291 				/* Sanity unmapping. */
4292 				if (DE_NULL != mapped_data)
4293 				{
4294 					m_pUnmapNamedBuffer(buffer);
4295 					while (gl.getError())
4296 						;
4297 				}
4298 			}
4299 		}
4300 
4301 		/* Test access flush bit without write bit error behavior. */
4302 		{
4303 			glw::GLvoid* mapped_data =
4304 				m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_READ_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
4305 
4306 			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
4307 									  " if MAP_FLUSH_EXPLICIT_BIT is set and MAP_WRITE_BIT is not set.");
4308 
4309 			/* Sanity unmapping. */
4310 			if (DE_NULL != mapped_data)
4311 			{
4312 				m_pUnmapNamedBuffer(buffer);
4313 				while (gl.getError())
4314 					;
4315 			}
4316 		}
4317 
4318 		/* Test incompatible buffer flag error behavior. */
4319 		{
4320 			glw::GLenum buffer_flags[] = { GL_MAP_WRITE_BIT, GL_MAP_READ_BIT, GL_MAP_WRITE_BIT,
4321 										   GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT };
4322 			glw::GLenum mapping_flags[] = { GL_MAP_READ_BIT, GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT,
4323 											GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT };
4324 			const glw::GLchar* mapping_flags_log[] = {
4325 				" if MAP_READ_BIT is set, but the same bit is not included in the buffer's storage flags.",
4326 				" if MAP_WRITE_BIT is set, but the same bit is not included in the buffer's storage flags.",
4327 				" if MAP_PERSISTENT_BIT is set, but the same bit is not included in the buffer's storage flags.",
4328 				" if MAP_COHERENT_BIT is set, but the same bit is not included in the buffer's storage flags."
4329 			};
4330 			glw::GLuint flags_count = sizeof(mapping_flags) / sizeof(mapping_flags[0]);
4331 
4332 			for (glw::GLuint i = 0; i < flags_count; ++i)
4333 			{
4334 				/* Create buffer. */
4335 				gl.createBuffers(1, &buffer_special_flags);
4336 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4337 
4338 				m_pNamedBufferStorage(buffer_special_flags, sizeof(unused_data), &unused_data, buffer_flags[i]);
4339 				GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4340 
4341 				/* Test mapping. */
4342 				glw::GLvoid* mapped_data =
4343 					m_pMapNamedBufferRange(buffer_special_flags, 0, sizeof(unused_data), mapping_flags[i]);
4344 
4345 				is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION, mapping_flags_log[i]);
4346 
4347 				/* Sanity unmapping. */
4348 				if (DE_NULL != mapped_data)
4349 				{
4350 					m_pUnmapNamedBuffer(buffer);
4351 					while (gl.getError())
4352 						;
4353 				}
4354 
4355 				/* Releasing buffer. */
4356 				if (buffer_special_flags)
4357 				{
4358 					gl.deleteBuffers(1, &buffer_special_flags);
4359 
4360 					buffer_special_flags = 0;
4361 				}
4362 			}
4363 		}
4364 	}
4365 	catch (...)
4366 	{
4367 		is_ok		   = false;
4368 		internal_error = true;
4369 	}
4370 
4371 	if (buffer)
4372 	{
4373 		gl.deleteBuffers(1, &buffer);
4374 
4375 		buffer = 0;
4376 	}
4377 
4378 	if (buffer_special_flags)
4379 	{
4380 		gl.deleteBuffers(1, &buffer_special_flags);
4381 
4382 		buffer_special_flags = 0;
4383 	}
4384 
4385 	if (internal_error)
4386 	{
4387 		throw 0;
4388 	}
4389 
4390 	return is_ok;
4391 }
4392 
4393 /** @brief Test Errors Of NamedBufferData function.
4394  *
4395  *          Check that INVALID_OPERATION is generated by NamedBufferData if buffer
4396  *          is not the name of an existing buffer object.
4397  *
4398  *          Check that INVALID_ENUM is generated by NamedBufferData if usage is not
4399  *          STREAM_DRAW, STREAM_READ, STREAM_COPY, STATIC_DRAW, STATIC_READ,
4400  *          STATIC_COPY, DYNAMIC_DRAW, DYNAMIC_READ or DYNAMIC_COPY.
4401  *
4402  *          Check that INVALID_VALUE is generated by NamedBufferData if size is
4403  *          negative.
4404  *
4405  *          Check that INVALID_OPERATION is generated by NamedBufferData if the
4406  *          BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE.
4407  *
4408  *  True if test case succeeded, false otherwise.
4409  */
TestErrorsOfNamedBufferData()4410 bool ErrorsTest::TestErrorsOfNamedBufferData()
4411 {
4412 	/* Shortcut for GL functionality. */
4413 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4414 
4415 	/* Return value. */
4416 	bool is_ok			= true;
4417 	bool internal_error = false;
4418 
4419 	/* Common variables. */
4420 	glw::GLuint				buffer			 = 0;
4421 	glw::GLuint				immutable_buffer = 0;
4422 	glw::GLubyte			unused_data[4]	 = {};
4423 	std::stack<glw::GLuint> too_much_buffers;
4424 
4425 	try
4426 	{
4427 		/* Common preparations. */
4428 		gl.createBuffers(1, &buffer);
4429 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4430 
4431 		gl.createBuffers(1, &immutable_buffer);
4432 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4433 
4434 		m_pNamedBufferStorage(immutable_buffer, sizeof(unused_data), &unused_data, GL_MAP_READ_BIT);
4435 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4436 
4437 		/* Test invalid buffer name error behavior. */
4438 		{
4439 			/* Prepare for invalid buffer name error behavior verification. */
4440 			glw::GLuint not_a_buffer_name = 0;
4441 
4442 			while (gl.isBuffer(++not_a_buffer_name))
4443 				;
4444 
4445 			/* Test. */
4446 			m_pNamedBufferData(not_a_buffer_name, sizeof(unused_data), unused_data, GL_DYNAMIC_COPY);
4447 
4448 			is_ok &= ErrorCheckAndLog("glNamedBufferData", GL_INVALID_OPERATION,
4449 									  " if buffer is not the name of an existing buffer object.");
4450 		}
4451 
4452 		/* Test invalid usage error behavior. */
4453 		{
4454 			/* Prepare for invalid type error behavior verification. */
4455 			static const glw::GLenum valid_usages[] = { GL_STREAM_DRAW,  GL_STREAM_READ,  GL_STREAM_COPY,
4456 														GL_STATIC_DRAW,  GL_STATIC_READ,  GL_STATIC_COPY,
4457 														GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, GL_DYNAMIC_COPY,
4458 														GL_NONE };
4459 			static const glw::GLenum valid_usages_last = sizeof(valid_usages) / sizeof(valid_usages[0]) - 1;
4460 
4461 			glw::GLenum invalid_usage = 0;
4462 
4463 			while (&valid_usages[valid_usages_last] !=
4464 				   std::find(&valid_usages[0], &valid_usages[valid_usages_last], (++invalid_usage)))
4465 				;
4466 
4467 			/* Test. */
4468 			m_pNamedBufferData(buffer, sizeof(unused_data), unused_data, invalid_usage);
4469 
4470 			is_ok &=
4471 				ErrorCheckAndLog("glNamedBufferData", GL_INVALID_ENUM,
4472 								 " if usage is not STREAM_DRAW, STREAM_READ, STREAM_COPY, STATIC_DRAW, STATIC_READ,"
4473 								 " STATIC_COPY, DYNAMIC_DRAW, DYNAMIC_READ or DYNAMIC_COPY.");
4474 		}
4475 
4476 		/* Test negative size error behavior. */
4477 		{
4478 			m_pNamedBufferData(buffer, -1, unused_data, GL_DYNAMIC_COPY);
4479 
4480 			is_ok &= ErrorCheckAndLog("glNamedBufferData", GL_INVALID_VALUE, " if size is negative.");
4481 		}
4482 
4483 		/* Test immutable buffer error behavior. */
4484 		{
4485 			m_pNamedBufferData(immutable_buffer, sizeof(unused_data) / 2, unused_data, GL_DYNAMIC_COPY);
4486 
4487 			is_ok &= ErrorCheckAndLog("glNamedBufferData", GL_INVALID_OPERATION,
4488 									  " if the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE.");
4489 		}
4490 	}
4491 	catch (...)
4492 	{
4493 		is_ok		   = false;
4494 		internal_error = true;
4495 	}
4496 
4497 	if (buffer)
4498 	{
4499 		gl.deleteBuffers(1, &buffer);
4500 
4501 		buffer = 0;
4502 	}
4503 
4504 	while (!too_much_buffers.empty())
4505 	{
4506 		glw::GLuint tmp_buffer = too_much_buffers.top();
4507 
4508 		if (tmp_buffer)
4509 		{
4510 			gl.deleteBuffers(1, &tmp_buffer);
4511 		}
4512 
4513 		too_much_buffers.pop();
4514 	}
4515 
4516 	if (immutable_buffer)
4517 	{
4518 		gl.deleteBuffers(1, &immutable_buffer);
4519 
4520 		immutable_buffer = 0;
4521 	}
4522 
4523 	if (internal_error)
4524 	{
4525 		throw 0;
4526 	}
4527 
4528 	return is_ok;
4529 }
4530 
4531 /** @brief Test Errors Of NamedBufferStorage function.
4532  *
4533  *  Check that INVALID_OPERATION is generated by NamedBufferStorage if
4534  *  buffer is not the name of an existing buffer object.
4535  *
4536  *  Check that INVALID_VALUE is generated by NamedBufferStorage if size is
4537  *  less than or equal to zero.
4538  *
4539  *  Check that INVALID_VALUE is generated by NamedBufferStorage if flags has
4540  *  any bits set other than DYNAMIC_STORAGE_BIT, MAP_READ_BIT,
4541  *  MAP_WRITE_BIT, MAP_PERSISTENT_BIT, MAP_COHERENT_BIT or
4542  *  CLIENT_STORAGE_BIT.
4543  *
4544  *  Check that INVALID_VALUE error is generated by NamedBufferStorage if
4545  *  flags contains MAP_PERSISTENT_BIT but does not contain at least one of
4546  *  MAP_READ_BIT or MAP_WRITE_BIT.
4547  *
4548  *  Check that INVALID_VALUE is generated by NamedBufferStorage if flags
4549  *  contains MAP_COHERENT_BIT, but does not also contain MAP_PERSISTENT_BIT.
4550  *
4551  *  True if test case succeeded, false otherwise.
4552  */
TestErrorsOfNamedBufferStorage()4553 bool ErrorsTest::TestErrorsOfNamedBufferStorage()
4554 {
4555 	/* Shortcut for GL functionality. */
4556 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4557 
4558 	/* Return value. */
4559 	bool is_ok			= true;
4560 	bool internal_error = false;
4561 
4562 	/* Common variables. */
4563 	glw::GLuint				buffer		  = 0;
4564 	glw::GLubyte			unused_data[4] = {};
4565 	std::stack<glw::GLuint> too_much_buffers;
4566 
4567 	try
4568 	{
4569 		/* Test invalid buffer name error behavior. */
4570 		{
4571 			/* Prepare for invalid buffer name error behavior verification. */
4572 			glw::GLuint not_a_buffer_name = 0;
4573 
4574 			while (gl.isBuffer(++not_a_buffer_name))
4575 				;
4576 
4577 			/* Test. */
4578 			m_pNamedBufferStorage(not_a_buffer_name, sizeof(unused_data), unused_data, GL_MAP_WRITE_BIT);
4579 
4580 			is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_OPERATION,
4581 									  " if buffer is not the name of an existing buffer object.");
4582 		}
4583 
4584 		/* Test negative or zero size error behavior. */
4585 		{
4586 			/* Object creation. */
4587 			gl.createBuffers(1, &buffer);
4588 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4589 
4590 			/* Test negative size. */
4591 			m_pNamedBufferStorage(buffer, -1, unused_data, GL_DYNAMIC_COPY);
4592 
4593 			is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE, " if size is negative.");
4594 
4595 			/* Test zero size. */
4596 			m_pNamedBufferStorage(buffer, 0, unused_data, GL_DYNAMIC_COPY);
4597 
4598 			is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE, " if size zero.");
4599 
4600 			/* Clean-up. */
4601 			gl.deleteBuffers(1, &buffer);
4602 
4603 			buffer = 0;
4604 
4605 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
4606 		}
4607 
4608 		/* Test invalid usage bit error behavior. */
4609 		{
4610 			/* Prepare for invalid type error behavior verification. */
4611 			glw::GLuint valid_bits = GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT |
4612 									 GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT;
4613 
4614 			if (m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_buffer"))
4615 			{
4616 				valid_bits |= GL_SPARSE_STORAGE_BIT_ARB;
4617 			}
4618 
4619 			if (m_context.getContextInfo().isExtensionSupported("GL_NV_gpu_multicast") ||
4620 				m_context.getContextInfo().isExtensionSupported("GL_NVX_linked_gpu_multicast"))
4621 			{
4622 				valid_bits |= GL_PER_GPU_STORAGE_BIT_NV;
4623 			}
4624 
4625 			if (m_context.getContextInfo().isExtensionSupported("GL_NVX_cross_process_interop"))
4626 			{
4627 				valid_bits |= GL_EXTERNAL_STORAGE_BIT_NVX;
4628 			}
4629 
4630 			glw::GLuint invalid_bits = ~valid_bits;
4631 
4632 			glw::GLuint bits_count = CHAR_BIT * sizeof(invalid_bits);
4633 
4634 			/* Test. */
4635 			for (glw::GLuint i = 0; i < bits_count; ++i)
4636 			{
4637 				glw::GLuint possibly_invalid_bit = (1 << i);
4638 
4639 				if (invalid_bits & possibly_invalid_bit)
4640 				{
4641 					/* Object creation. */
4642 					gl.createBuffers(1, &buffer);
4643 					GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4644 
4645 					/* Test invalid bit. */
4646 					m_pNamedBufferStorage(buffer, sizeof(unused_data), unused_data, possibly_invalid_bit);
4647 
4648 					is_ok &=
4649 						ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE,
4650 										 " if flags has any bits set other than DYNAMIC_STORAGE_BIT, MAP_READ_BIT,"
4651 										 " MAP_WRITE_BIT, MAP_PERSISTENT_BIT, MAP_COHERENT_BIT or CLIENT_STORAGE_BIT.");
4652 
4653 					/* Release object. */
4654 					gl.deleteBuffers(1, &buffer);
4655 
4656 					buffer = 0;
4657 
4658 					GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
4659 				}
4660 			}
4661 		}
4662 
4663 		/* Test improper persistent bit behavior error behavior. */
4664 		{
4665 			/* Object creation. */
4666 			gl.createBuffers(1, &buffer);
4667 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4668 
4669 			/* Test. */
4670 			m_pNamedBufferStorage(buffer, sizeof(unused_data), unused_data, GL_MAP_PERSISTENT_BIT);
4671 
4672 			is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE, " if flags contains MAP_PERSISTENT_BIT "
4673 																				"but does not contain at least one of "
4674 																				"MAP_READ_BIT or MAP_WRITE_BIT.");
4675 
4676 			/* Clean-up. */
4677 			gl.deleteBuffers(1, &buffer);
4678 
4679 			buffer = 0;
4680 
4681 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
4682 		}
4683 
4684 		/* Test improper persistent bit behavior error behavior. */
4685 		{
4686 			/* Object creation. */
4687 			gl.createBuffers(1, &buffer);
4688 			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4689 
4690 			/* Test. */
4691 			m_pNamedBufferStorage(buffer, sizeof(unused_data), unused_data,
4692 								  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT);
4693 
4694 			is_ok &=
4695 				ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE,
4696 								 " if flags contains MAP_COHERENT_BIT, but does not also contain MAP_PERSISTENT_BIT.");
4697 
4698 			/* Clean-up. */
4699 			gl.deleteBuffers(1, &buffer);
4700 
4701 			buffer = 0;
4702 
4703 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
4704 		}
4705 	}
4706 	catch (...)
4707 	{
4708 		is_ok		   = false;
4709 		internal_error = true;
4710 	}
4711 
4712 	if (buffer)
4713 	{
4714 		gl.deleteBuffers(1, &buffer);
4715 
4716 		buffer = 0;
4717 	}
4718 
4719 	while (!too_much_buffers.empty())
4720 	{
4721 		glw::GLuint tmp_buffer = too_much_buffers.top();
4722 
4723 		if (tmp_buffer)
4724 		{
4725 			gl.deleteBuffers(1, &tmp_buffer);
4726 		}
4727 
4728 		too_much_buffers.pop();
4729 	}
4730 
4731 	if (internal_error)
4732 	{
4733 		throw 0;
4734 	}
4735 
4736 	return is_ok;
4737 }
4738 
4739 /** @brief Test Errors Of NamedBufferSubData function.
4740  *
4741  *  Check that INVALID_OPERATION is generated by NamedBufferSubData if
4742  *  buffer is not the name of an existing buffer object.
4743  *
4744  *  Check that INVALID_VALUE is generated by NamedBufferSubData if offset or
4745  *  size is negative, or if offset+size is greater than the value of
4746  *  BUFFER_SIZE for the specified buffer object.
4747  *
4748  *  Check that INVALID_OPERATION is generated by NamedBufferSubData if any
4749  *  part of the specified range of the buffer object is mapped with
4750  *  MapBufferRange or MapBuffer, unless it was mapped with the
4751  *  MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.
4752  *
4753  *  Check that INVALID_OPERATION is generated by NamedBufferSubData if the
4754  *  value of the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE
4755  *  and the value of BUFFER_STORAGE_FLAGS for the buffer object does not
4756  *  have the DYNAMIC_STORAGE_BIT bit set.
4757  *
4758  *  True if test case succeeded, false otherwise.
4759  */
TestErrorsOfNamedBufferSubData()4760 bool ErrorsTest::TestErrorsOfNamedBufferSubData()
4761 {
4762 	/* Shortcut for GL functionality. */
4763 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4764 
4765 	/* Return value. */
4766 	bool is_ok			= true;
4767 	bool internal_error = false;
4768 
4769 	/* Common variables. */
4770 	glw::GLuint  buffer					  = 0;
4771 	glw::GLuint  immutable_storage_buffer = 0;
4772 	glw::GLubyte unused_data[4]			  = {};
4773 
4774 	try
4775 	{
4776 		/* Common preparations. */
4777 		gl.createBuffers(1, &buffer);
4778 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4779 
4780 		m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data,
4781 							  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT | GL_MAP_PERSISTENT_BIT);
4782 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4783 
4784 		gl.createBuffers(1, &immutable_storage_buffer);
4785 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4786 
4787 		m_pNamedBufferStorage(immutable_storage_buffer, sizeof(unused_data), &unused_data, GL_MAP_READ_BIT);
4788 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4789 
4790 		/* Test invalid buffer name error behavior. */
4791 		{
4792 			/* Prepare for invalid buffer name error behavior verification. */
4793 			glw::GLuint not_a_buffer_name = 0;
4794 
4795 			while (gl.isBuffer(++not_a_buffer_name))
4796 				;
4797 
4798 			/* Test. */
4799 			m_pNamedBufferSubData(not_a_buffer_name, 0, sizeof(unused_data), &unused_data);
4800 
4801 			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
4802 									  " if buffer is not the name of an existing buffer object.");
4803 		}
4804 
4805 		/* Test negative offset error behavior. */
4806 		{
4807 			/* Test. */
4808 			m_pNamedBufferSubData(buffer, -1, sizeof(unused_data), &unused_data);
4809 
4810 			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_VALUE, " if offset or size is negative.");
4811 		}
4812 
4813 		/* Test negative size error behavior. */
4814 		{
4815 			/* Test. */
4816 			m_pNamedBufferSubData(buffer, 0, -1, &unused_data);
4817 
4818 			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_VALUE, " if offset or size is negative.");
4819 		}
4820 
4821 		/* Test size overflow error behavior. */
4822 		{
4823 			/* Test. */
4824 			m_pNamedBufferSubData(buffer, 0, sizeof(unused_data) * 2, &unused_data);
4825 
4826 			is_ok &= ErrorCheckAndLog(
4827 				"glNamedBufferSubData", GL_INVALID_VALUE,
4828 				" if offset+size is greater than the value of BUFFER_SIZE for the specified buffer object.");
4829 		}
4830 
4831 		/* Test offset+size overflow error behavior. */
4832 		{
4833 			/* Test. */
4834 			m_pNamedBufferSubData(buffer, sizeof(unused_data) / 2, sizeof(unused_data), &unused_data);
4835 
4836 			is_ok &= ErrorCheckAndLog(
4837 				"glNamedBufferSubData", GL_INVALID_VALUE,
4838 				" if offset+size is greater than the value of BUFFER_SIZE for the specified buffer object.");
4839 		}
4840 
4841 		/* Test of mapped buffer subdata error behavior verification (with glMapBuffer). */
4842 		{
4843 			(void)(glw::GLbyte*) m_pMapNamedBuffer(buffer, GL_READ_ONLY);
4844 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
4845 
4846 			m_pNamedBufferSubData(buffer, 0, sizeof(unused_data), &unused_data);
4847 
4848 			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
4849 									  " if any part of the specified range of the buffer"
4850 									  " object is mapped with MapBuffer, unless it was mapped with "
4851 									  "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");
4852 
4853 			m_pUnmapNamedBuffer(buffer);
4854 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
4855 		}
4856 
4857 		/* Test of mapped buffer subdata error behavior verification (with glMapBufferRange). */
4858 		{
4859 			(void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_READ_BIT);
4860 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
4861 
4862 			m_pNamedBufferSubData(buffer, 0, sizeof(unused_data), &unused_data);
4863 
4864 			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
4865 									  " if any part of the specified range of the buffer"
4866 									  " object is mapped with MapBufferRange, unless it was mapped with "
4867 									  "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");
4868 
4869 			m_pUnmapNamedBuffer(buffer);
4870 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
4871 		}
4872 
4873 		/* Test of persistently mapped buffer clear error with behavior verification. */
4874 		{
4875 			(void)(glw::GLbyte*)
4876 				m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
4877 			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
4878 
4879 			m_pNamedBufferSubData(buffer, 0, sizeof(unused_data), &unused_data);
4880 
4881 			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_NO_ERROR,
4882 									  " if any part of the specified range of the buffer"
4883 									  " object is mapped with MapBuffer with the MAP_PERSISTENT_BIT"
4884 									  " bit set in the MapBufferRange access flags.");
4885 
4886 			m_pUnmapNamedBuffer(buffer);
4887 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
4888 		}
4889 
4890 		/* Test DYNAMIC_STORAGE_BIT bit off immutable buffer not set error behavior. */
4891 		{
4892 			/* Test. */
4893 			m_pNamedBufferSubData(immutable_storage_buffer, 0, sizeof(unused_data), &unused_data);
4894 
4895 			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
4896 									  " if the value of the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE"
4897 									  " and the value of BUFFER_STORAGE_FLAGS for the buffer object does not"
4898 									  " have the DYNAMIC_STORAGE_BIT bit set.");
4899 		}
4900 
4901 		/* Test DYNAMIC_STORAGE_BIT bit off immutable buffer set no error behavior. */
4902 		{
4903 			/* Test. */
4904 			m_pNamedBufferSubData(buffer, 0, sizeof(unused_data), &unused_data);
4905 
4906 			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_NO_ERROR,
4907 									  " if the value of the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE"
4908 									  " and the value of BUFFER_STORAGE_FLAGS for the buffer object"
4909 									  " have the DYNAMIC_STORAGE_BIT bit set.");
4910 		}
4911 	}
4912 	catch (...)
4913 	{
4914 		is_ok		   = false;
4915 		internal_error = true;
4916 	}
4917 
4918 	if (buffer)
4919 	{
4920 		gl.deleteBuffers(1, &buffer);
4921 
4922 		buffer = 0;
4923 	}
4924 
4925 	if (immutable_storage_buffer)
4926 	{
4927 		gl.deleteBuffers(1, &immutable_storage_buffer);
4928 
4929 		buffer = 0;
4930 	}
4931 
4932 	if (internal_error)
4933 	{
4934 		throw 0;
4935 	}
4936 
4937 	return is_ok;
4938 }
4939 
4940 /** @brief Test Errors Of UnmapNamedBuffer function.
4941  *
4942  *  Check that INVALID_OPERATION is generated by UnmapNamedBuffer if buffer
4943  *  is not the name of an existing buffer object.
4944  *
4945  *  Check that INVALID_OPERATION is generated by UnmapNamedBuffer if the
4946  *  buffer object is not in a mapped state.
4947  *
4948  *  True if test case succeeded, false otherwise.
4949  */
TestErrorsOfUnmapNamedBuffer()4950 bool ErrorsTest::TestErrorsOfUnmapNamedBuffer()
4951 {
4952 	/* Shortcut for GL functionality. */
4953 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4954 
4955 	/* Return value. */
4956 	bool is_ok			= true;
4957 	bool internal_error = false;
4958 
4959 	/* Common variables. */
4960 	glw::GLuint  buffer		   = 0;
4961 	glw::GLubyte unused_data[4] = {};
4962 
4963 	try
4964 	{
4965 		/* Common preparations. */
4966 		gl.createBuffers(1, &buffer);
4967 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4968 
4969 		m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data,
4970 							  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT | GL_MAP_PERSISTENT_BIT);
4971 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4972 
4973 		/* Test invalid buffer name error behavior. */
4974 		{
4975 			/* Prepare for invalid buffer name error behavior verification. */
4976 			glw::GLuint not_a_buffer_name = 0;
4977 
4978 			while (gl.isBuffer(++not_a_buffer_name))
4979 				;
4980 
4981 			/* Test. */
4982 			m_pUnmapNamedBuffer(not_a_buffer_name);
4983 
4984 			is_ok &= ErrorCheckAndLog("glUnmapNamedBuffer", GL_INVALID_OPERATION,
4985 									  " if buffer is not the name of an existing buffer object.");
4986 		}
4987 
4988 		/* Test not mapped buffer error behavior verification. */
4989 		{
4990 			m_pUnmapNamedBuffer(buffer);
4991 
4992 			is_ok &= ErrorCheckAndLog("glUnmapNamedBuffer", GL_INVALID_OPERATION,
4993 									  " if the buffer object is not in a mapped state.");
4994 		}
4995 	}
4996 	catch (...)
4997 	{
4998 		is_ok		   = false;
4999 		internal_error = true;
5000 	}
5001 
5002 	if (buffer)
5003 	{
5004 		gl.deleteBuffers(1, &buffer);
5005 
5006 		buffer = 0;
5007 	}
5008 
5009 	if (internal_error)
5010 	{
5011 		throw 0;
5012 	}
5013 
5014 	return is_ok;
5015 }
5016 
5017 /******************************** Functional Test Implementation   ********************************/
5018 
5019 /** @brief Vertex shader source code */
5020 const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 450\n"
5021 													  "\n"
5022 													  "in  int data_in;\n"
5023 													  "out int data_out;\n"
5024 													  "\n"
5025 													  "void main()\n"
5026 													  "{\n"
5027 													  "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
5028 													  "\n"
5029 													  "    data_out = data_in * data_in;\n"
5030 													  "}\n";
5031 
5032 /** @brief Fragment shader source code */
5033 const glw::GLchar FunctionalTest::s_fragment_shader[] = "#version 450\n"
5034 														"\n"
5035 														"out vec4 color;\n"
5036 														"\n"
5037 														"void main()\n"
5038 														"{\n"
5039 														"    color = vec4(0.0);\n"
5040 														"}\n";
5041 
5042 const glw::GLchar FunctionalTest::s_vertex_shader_input_name[] =
5043 	"data_in"; //!< Vertex shader's name of the input attribute.
5044 
5045 const glw::GLchar* FunctionalTest::s_vertex_shader_output_name =
5046 	"data_out"; //!< Vertex shader's name of the transform feedback varying.
5047 
5048 const glw::GLint FunctionalTest::s_initial_data_a[] = {
5049 	1, 2, 3, 4, 5, 5
5050 }; //!< Initial data to be uploaded for the input buffer.
5051 
5052 const glw::GLint FunctionalTest::s_initial_data_b[] = {
5053 	0, 0, 0, 0, 0, 0, 36
5054 }; //!< Initial data to be uploaded for the output buffer.
5055 
5056 const glw::GLint FunctionalTest::s_expected_data[] = {
5057 	0, 1, 4, 9, 16, 25, 36
5058 }; //!< Expected result which shall be read from output buffer.
5059 
5060 /** @brief Functional Test constructor.
5061  *
5062  *  @param [in] context     OpenGL context.
5063  */
FunctionalTest(deqp::Context & context)5064 FunctionalTest::FunctionalTest(deqp::Context& context)
5065 	: deqp::TestCase(context, "buffers_functional", "Buffer Objects Functional Test")
5066 	, m_pClearNamedBufferData(DE_NULL)
5067 	, m_pClearNamedBufferSubData(DE_NULL)
5068 	, m_pCopyNamedBufferSubData(DE_NULL)
5069 	, m_pFlushMappedNamedBufferRange(DE_NULL)
5070 	, m_pGetNamedBufferParameteri64v(DE_NULL)
5071 	, m_pGetNamedBufferParameteriv(DE_NULL)
5072 	, m_pGetNamedBufferPointerv(DE_NULL)
5073 	, m_pGetNamedBufferSubData(DE_NULL)
5074 	, m_pMapNamedBuffer(DE_NULL)
5075 	, m_pMapNamedBufferRange(DE_NULL)
5076 	, m_pNamedBufferData(DE_NULL)
5077 	, m_pNamedBufferStorage(DE_NULL)
5078 	, m_pNamedBufferSubData(DE_NULL)
5079 	, m_pUnmapNamedBuffer(DE_NULL)
5080 	, m_po(0)
5081 	, m_vao(0)
5082 	, m_bo_in(0)
5083 	, m_bo_out(0)
5084 	, m_attrib_location(-1)
5085 {
5086 	/* Intentionally left blank. */
5087 }
5088 
5089 /** @brief Run Functional Test.
5090  *
5091  *  @return Iteration result.
5092  */
iterate()5093 tcu::TestNode::IterateResult FunctionalTest::iterate()
5094 {
5095 	/* Shortcut for GL functionality. */
5096 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5097 
5098 	/* Get context setup. */
5099 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
5100 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
5101 
5102 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
5103 	{
5104 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
5105 
5106 		return STOP;
5107 	}
5108 
5109 	/* Running tests. */
5110 	bool is_ok	= true;
5111 	bool is_error = false;
5112 
5113 	/* API function pointers setup. */
5114 	m_pClearNamedBufferData		   = (PFNGLCLEARNAMEDBUFFERDATA)gl.clearNamedBufferData;
5115 	m_pClearNamedBufferSubData	 = (PFNGLCLEARNAMEDBUFFERSUBDATA)gl.clearNamedBufferSubData;
5116 	m_pCopyNamedBufferSubData	  = (PFNGLCOPYNAMEDBUFFERSUBDATA)gl.copyNamedBufferSubData;
5117 	m_pFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGE)gl.flushMappedNamedBufferRange;
5118 	m_pGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64V)gl.getNamedBufferParameteri64v;
5119 	m_pGetNamedBufferParameteriv   = (PFNGLGETNAMEDBUFFERPARAMETERIV)gl.getNamedBufferParameteriv;
5120 	m_pGetNamedBufferPointerv	  = (PFNGLGETNAMEDBUFFERPOINTERV)gl.getNamedBufferPointerv;
5121 	m_pGetNamedBufferSubData	   = (PFNGLGETNAMEDBUFFERSUBDATA)gl.getNamedBufferSubData;
5122 	m_pMapNamedBuffer			   = (PFNGLMAPNAMEDBUFFER)gl.mapNamedBuffer;
5123 	m_pMapNamedBufferRange		   = (PFNGLMAPNAMEDBUFFERRANGE)gl.mapNamedBufferRange;
5124 	m_pNamedBufferData			   = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
5125 	m_pNamedBufferStorage		   = (PFNGLNAMEDBUFFERSTORAGE)gl.namedBufferStorage;
5126 	m_pNamedBufferSubData		   = (PFNGLNAMEDBUFFERSUBDATA)gl.namedBufferSubData;
5127 	m_pUnmapNamedBuffer			   = (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;
5128 
5129 	try
5130 	{
5131 		/* API function pointers check. */
5132 		if ((DE_NULL == m_pClearNamedBufferData) || (DE_NULL == m_pClearNamedBufferSubData) ||
5133 			(DE_NULL == m_pCopyNamedBufferSubData) || (DE_NULL == m_pFlushMappedNamedBufferRange) ||
5134 			(DE_NULL == m_pGetNamedBufferParameteri64v) || (DE_NULL == m_pGetNamedBufferParameteriv) ||
5135 			(DE_NULL == m_pGetNamedBufferPointerv) || (DE_NULL == m_pGetNamedBufferSubData) ||
5136 			(DE_NULL == m_pMapNamedBuffer) || (DE_NULL == m_pMapNamedBufferRange) || (DE_NULL == m_pNamedBufferData) ||
5137 			(DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pNamedBufferSubData) ||
5138 			(DE_NULL == m_pUnmapNamedBuffer))
5139 		{
5140 			throw 0;
5141 		}
5142 
5143 		/* Running test. */
5144 		BuildProgram();
5145 		PrepareVertexArrayObject();
5146 
5147 		is_ok = is_ok && PrepareInputBuffer();
5148 		is_ok = is_ok && PrepareOutputBuffer();
5149 
5150 		if (is_ok)
5151 		{
5152 			Draw();
5153 		}
5154 
5155 		is_ok = is_ok && CheckArrayBufferImmutableFlag();
5156 		is_ok = is_ok && CheckTransformFeedbackBufferSize();
5157 		is_ok = is_ok && CheckTransformFeedbackResult();
5158 	}
5159 	catch (...)
5160 	{
5161 		is_ok	= false;
5162 		is_error = true;
5163 	}
5164 
5165 	/* Clean Up. */
5166 	Cleanup();
5167 
5168 	/* Errors clean up. */
5169 	while (gl.getError())
5170 		;
5171 
5172 	/* Result's setup. */
5173 	if (is_ok)
5174 	{
5175 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5176 	}
5177 	else
5178 	{
5179 		if (is_error)
5180 		{
5181 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
5182 		}
5183 		else
5184 		{
5185 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5186 		}
5187 	}
5188 
5189 	return STOP;
5190 }
5191 
5192 /** @brief Build test's GL program */
BuildProgram()5193 void FunctionalTest::BuildProgram()
5194 {
5195 	/* Shortcut for GL functionality */
5196 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5197 
5198 	struct Shader
5199 	{
5200 		glw::GLchar const* const source;
5201 		glw::GLenum const		 type;
5202 		glw::GLuint				 id;
5203 	} shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
5204 
5205 	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
5206 
5207 	try
5208 	{
5209 		/* Create program. */
5210 		m_po = gl.createProgram();
5211 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
5212 
5213 		/* Shader compilation. */
5214 
5215 		for (glw::GLuint i = 0; i < shader_count; ++i)
5216 		{
5217 			if (DE_NULL != shader[i].source)
5218 			{
5219 				shader[i].id = gl.createShader(shader[i].type);
5220 
5221 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
5222 
5223 				gl.attachShader(m_po, shader[i].id);
5224 
5225 				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
5226 
5227 				gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
5228 
5229 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
5230 
5231 				gl.compileShader(shader[i].id);
5232 
5233 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
5234 
5235 				glw::GLint status = GL_FALSE;
5236 
5237 				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
5238 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
5239 
5240 				if (GL_FALSE == status)
5241 				{
5242 					glw::GLint log_size = 0;
5243 					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
5244 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
5245 
5246 					glw::GLchar* log_text = new glw::GLchar[log_size];
5247 
5248 					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
5249 
5250 					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
5251 														<< "Shader type: " << glu::getShaderTypeStr(shader[i].type)
5252 														<< "\n"
5253 														<< "Shader compilation error log:\n"
5254 														<< log_text << "\n"
5255 														<< "Shader source code:\n"
5256 														<< shader[i].source << "\n"
5257 														<< tcu::TestLog::EndMessage;
5258 
5259 					delete[] log_text;
5260 
5261 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
5262 
5263 					throw 0;
5264 				}
5265 			}
5266 		}
5267 
5268 		/* Tranform feedback varying */
5269 		gl.transformFeedbackVaryings(m_po, 1, &s_vertex_shader_output_name, GL_INTERLEAVED_ATTRIBS);
5270 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
5271 
5272 		/* Link. */
5273 		gl.linkProgram(m_po);
5274 
5275 		GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram call failed.");
5276 
5277 		glw::GLint status = GL_FALSE;
5278 
5279 		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
5280 
5281 		if (GL_TRUE == status)
5282 		{
5283 			for (glw::GLuint i = 0; i < shader_count; ++i)
5284 			{
5285 				if (shader[i].id)
5286 				{
5287 					gl.detachShader(m_po, shader[i].id);
5288 
5289 					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
5290 				}
5291 			}
5292 		}
5293 		else
5294 		{
5295 			glw::GLint log_size = 0;
5296 
5297 			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
5298 
5299 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
5300 
5301 			glw::GLchar* log_text = new glw::GLchar[log_size];
5302 
5303 			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
5304 
5305 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
5306 												<< log_text << "\n"
5307 												<< tcu::TestLog::EndMessage;
5308 
5309 			delete[] log_text;
5310 
5311 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
5312 
5313 			throw 0;
5314 		}
5315 	}
5316 	catch (...)
5317 	{
5318 		if (m_po)
5319 		{
5320 			gl.deleteProgram(m_po);
5321 
5322 			m_po = 0;
5323 		}
5324 	}
5325 
5326 	for (glw::GLuint i = 0; i < shader_count; ++i)
5327 	{
5328 		if (0 != shader[i].id)
5329 		{
5330 			gl.deleteShader(shader[i].id);
5331 
5332 			shader[i].id = 0;
5333 		}
5334 	}
5335 
5336 	if (m_po)
5337 	{
5338 		gl.useProgram(m_po);
5339 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
5340 	}
5341 
5342 	if (0 == m_po)
5343 	{
5344 		throw 0;
5345 	}
5346 }
5347 
5348 /** @brief Prepare empty vertex array object and bind it. */
PrepareVertexArrayObject()5349 void FunctionalTest::PrepareVertexArrayObject()
5350 {
5351 	/* Shortcut for GL functionality */
5352 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5353 
5354 	gl.genVertexArrays(1, &m_vao);
5355 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
5356 
5357 	gl.bindVertexArray(m_vao);
5358 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
5359 }
5360 
5361 /** Prepare input buffer in the way described in test specification (see class comment). */
PrepareInputBuffer()5362 bool FunctionalTest::PrepareInputBuffer()
5363 {
5364 	/* Shortcut for GL functionality */
5365 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5366 
5367 	/* Constants. */
5368 	static const glw::GLint zero = 0;
5369 	static const glw::GLint one  = 1;
5370 
5371 	/* Buffer preparation */
5372 	gl.createBuffers(1, &m_bo_in);
5373 
5374 	if (GL_NO_ERROR == gl.getError())
5375 	{
5376 		/* Storage and last (6th) element preparation. */
5377 		m_pNamedBufferStorage(m_bo_in, sizeof(s_initial_data_a), s_initial_data_a,
5378 							  GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT | GL_MAP_PERSISTENT_BIT);
5379 
5380 		if (GL_NO_ERROR == gl.getError())
5381 		{
5382 			/* First element preparation. */
5383 			m_pClearNamedBufferSubData(m_bo_in, GL_R8, 0, sizeof(glw::GLint), GL_RED, GL_INT, &zero);
5384 
5385 			if (GL_NO_ERROR == gl.getError())
5386 			{
5387 				/* Second element preparation. */
5388 				m_pNamedBufferSubData(m_bo_in, 1 /* 2nd element */ * sizeof(glw::GLint), sizeof(glw::GLint), &one);
5389 
5390 				if (GL_NO_ERROR == gl.getError())
5391 				{
5392 					/* Third element preparation. */
5393 					glw::GLint* p = (glw::GLint*)m_pMapNamedBuffer(m_bo_in, GL_WRITE_ONLY);
5394 
5395 					if ((GL_NO_ERROR == gl.getError()) || (DE_NULL == p))
5396 					{
5397 						p[2] = 2;
5398 
5399 						m_pUnmapNamedBuffer(m_bo_in);
5400 
5401 						if (GL_NO_ERROR == gl.getError())
5402 						{
5403 							/* Fifth element preparation. */
5404 							m_pCopyNamedBufferSubData(m_bo_in, m_bo_in, sizeof(glw::GLint) * 3, sizeof(glw::GLint) * 4,
5405 													  sizeof(glw::GLint));
5406 
5407 							if (GL_NO_ERROR == gl.getError())
5408 							{
5409 								/* Fourth element preparation. */
5410 								p = (glw::GLint*)m_pMapNamedBufferRange(
5411 									m_bo_in, sizeof(glw::GLint) * 3, sizeof(glw::GLint),
5412 									GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
5413 
5414 								if (GL_NO_ERROR == gl.getError())
5415 								{
5416 									/* Write to mapped buffer. */
5417 									*p = 3;
5418 
5419 									/* Flush test. */
5420 									m_pFlushMappedNamedBufferRange(m_bo_in, 0, sizeof(glw::GLint));
5421 
5422 									if (GL_NO_ERROR == gl.getError())
5423 									{
5424 										/* Mapped Buffer Pointer query. */
5425 										glw::GLvoid* is_p = DE_NULL;
5426 										m_pGetNamedBufferPointerv(m_bo_in, GL_BUFFER_MAP_POINTER, &is_p);
5427 
5428 										if (GL_NO_ERROR == gl.getError())
5429 										{
5430 											/* Mapped Buffer pointer query check. */
5431 											if (p == is_p)
5432 											{
5433 												/* Unmapping. */
5434 												m_pUnmapNamedBuffer(m_bo_in);
5435 
5436 												if (GL_NO_ERROR == gl.getError())
5437 												{
5438 													/* Setup buffer as input for vertex shader. */
5439 													m_attrib_location =
5440 														gl.getAttribLocation(m_po, s_vertex_shader_input_name);
5441 													GLU_EXPECT_NO_ERROR(gl.getError(),
5442 																		"glGetAttribLocation call failed.");
5443 
5444 													gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_in);
5445 													GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
5446 
5447 													gl.vertexAttribIPointer(m_attrib_location, 1, GL_INT, 0, NULL);
5448 													GLU_EXPECT_NO_ERROR(gl.getError(),
5449 																		"glVertexAttribIPointer call failed.");
5450 
5451 													gl.enableVertexAttribArray(m_attrib_location);
5452 													GLU_EXPECT_NO_ERROR(gl.getError(),
5453 																		"glEnableVertexAttribArray call failed.");
5454 
5455 													return true;
5456 												}
5457 												else
5458 												{
5459 													m_context.getTestContext().getLog()
5460 														<< tcu::TestLog::Message << "UnmapNamedBuffer has failed."
5461 														<< tcu::TestLog::EndMessage;
5462 												}
5463 											}
5464 											else
5465 											{
5466 												m_pUnmapNamedBuffer(m_bo_in);
5467 												m_context.getTestContext().getLog()
5468 													<< tcu::TestLog::Message
5469 													<< "Pointer returned by GetNamedBufferPointerv is not proper."
5470 													<< tcu::TestLog::EndMessage;
5471 											}
5472 										}
5473 										else
5474 										{
5475 											m_pUnmapNamedBuffer(m_bo_in);
5476 											m_context.getTestContext().getLog() << tcu::TestLog::Message
5477 																				<< "GetNamedBufferPointerv has failed."
5478 																				<< tcu::TestLog::EndMessage;
5479 										}
5480 									}
5481 									else
5482 									{
5483 										m_pUnmapNamedBuffer(m_bo_in);
5484 										m_context.getTestContext().getLog() << tcu::TestLog::Message
5485 																			<< "FlushMappedNamedBufferRange has failed."
5486 																			<< tcu::TestLog::EndMessage;
5487 									}
5488 								}
5489 								else
5490 								{
5491 									m_context.getTestContext().getLog() << tcu::TestLog::Message
5492 																		<< "MapNamedBufferRange has failed."
5493 																		<< tcu::TestLog::EndMessage;
5494 								}
5495 							}
5496 							else
5497 							{
5498 								m_context.getTestContext().getLog() << tcu::TestLog::Message
5499 																	<< "CopyNamedBufferSubData has failed."
5500 																	<< tcu::TestLog::EndMessage;
5501 							}
5502 						}
5503 						else
5504 						{
5505 							m_context.getTestContext().getLog()
5506 								<< tcu::TestLog::Message << "UnmapNamedBuffer has failed." << tcu::TestLog::EndMessage;
5507 						}
5508 					}
5509 					else
5510 					{
5511 						m_context.getTestContext().getLog() << tcu::TestLog::Message << "MapNamedBuffer has failed."
5512 															<< tcu::TestLog::EndMessage;
5513 					}
5514 				}
5515 				else
5516 				{
5517 					m_context.getTestContext().getLog() << tcu::TestLog::Message << "NamedBufferSubData has failed."
5518 														<< tcu::TestLog::EndMessage;
5519 				}
5520 			}
5521 			else
5522 			{
5523 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "ClearNamedBufferSubData has failed."
5524 													<< tcu::TestLog::EndMessage;
5525 			}
5526 		}
5527 		else
5528 		{
5529 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "NamedBufferStorage has failed."
5530 												<< tcu::TestLog::EndMessage;
5531 		}
5532 	}
5533 	else
5534 	{
5535 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "CreateBuffers has failed."
5536 											<< tcu::TestLog::EndMessage;
5537 	}
5538 
5539 	return false;
5540 }
5541 
5542 /** Prepare output buffer in the way described in test specification (see class comment). */
PrepareOutputBuffer()5543 bool FunctionalTest::PrepareOutputBuffer()
5544 {
5545 	/* Shortcut for GL functionality */
5546 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5547 
5548 	/* Buffer preparation */
5549 	gl.genBuffers(1, &m_bo_out);
5550 
5551 	if (GL_NO_ERROR == gl.getError())
5552 	{
5553 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_out);
5554 
5555 		if (GL_NO_ERROR == gl.getError())
5556 		{
5557 			m_pNamedBufferData(m_bo_out, sizeof(s_initial_data_b), s_initial_data_b, GL_DYNAMIC_COPY);
5558 
5559 			if (GL_NO_ERROR == gl.getError())
5560 			{
5561 				gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_out, 0,
5562 								   sizeof(s_initial_data_a) /* intentionally sizeof(a) < sizeof(b) */);
5563 
5564 				if (GL_NO_ERROR == gl.getError())
5565 				{
5566 					return true;
5567 				}
5568 				else
5569 				{
5570 					m_context.getTestContext().getLog() << tcu::TestLog::Message << "BindBufferRange has failed."
5571 														<< tcu::TestLog::EndMessage;
5572 					throw 0; /* This function is not being tested, throw test internal error */
5573 				}
5574 			}
5575 			else
5576 			{
5577 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "NamedBufferData has failed."
5578 													<< tcu::TestLog::EndMessage;
5579 			}
5580 		}
5581 		else
5582 		{
5583 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "BindBuffer has failed."
5584 												<< tcu::TestLog::EndMessage;
5585 			throw 0; /* This function is not being tested, throw test internal error */
5586 		}
5587 	}
5588 	else
5589 	{
5590 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "GenBuffers has failed."
5591 											<< tcu::TestLog::EndMessage;
5592 		throw 0; /* This function is not being tested, throw test internal error */
5593 	}
5594 
5595 	return false;
5596 }
5597 
5598 /** Draw with the test program and transform feedback. */
Draw()5599 void FunctionalTest::Draw()
5600 {
5601 	/* Shortcut for GL functionality */
5602 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5603 
5604 	/* Draw using transform feedback. */
5605 	gl.disable(GL_RASTERIZER_DISCARD);
5606 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
5607 
5608 	gl.beginTransformFeedback(GL_POINTS);
5609 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
5610 
5611 	gl.drawArrays(GL_POINTS, 0, sizeof(s_initial_data_a) / sizeof(s_initial_data_a[0]));
5612 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
5613 
5614 	gl.endTransformFeedback();
5615 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
5616 
5617 	gl.enable(GL_RASTERIZER_DISCARD);
5618 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
5619 }
5620 
5621 /** @brief Check that input buffer is immutable using GetNamedBufferParameteriv function. */
CheckArrayBufferImmutableFlag()5622 bool FunctionalTest::CheckArrayBufferImmutableFlag()
5623 {
5624 	/* Shortcut for GL functionality. */
5625 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5626 
5627 	/* Local query storage. */
5628 	glw::GLint is_storage_immutable = -1;
5629 
5630 	/* Querry. */
5631 	m_pGetNamedBufferParameteriv(m_bo_in, GL_BUFFER_IMMUTABLE_STORAGE, &is_storage_immutable);
5632 
5633 	/* Error checking. */
5634 	if (GL_NO_ERROR == gl.getError())
5635 	{
5636 		/* Return value checking. */
5637 		if (-1 != is_storage_immutable)
5638 		{
5639 			/* Test. */
5640 			if (GL_TRUE == is_storage_immutable)
5641 			{
5642 				return true;
5643 			}
5644 			else
5645 			{
5646 				m_context.getTestContext().getLog() << tcu::TestLog::Message
5647 													<< "Input buffer storage is unexpectedly mutable."
5648 													<< tcu::TestLog::EndMessage;
5649 			}
5650 		}
5651 		else
5652 		{
5653 			m_context.getTestContext().getLog() << tcu::TestLog::Message
5654 												<< "GetNamedBufferParameteriv has not returned a data."
5655 												<< tcu::TestLog::EndMessage;
5656 		}
5657 	}
5658 	else
5659 	{
5660 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetNamedBufferParameteriv has failed."
5661 											<< tcu::TestLog::EndMessage;
5662 	}
5663 
5664 	return false;
5665 }
5666 
5667 /** @brief Check that output buffer size using GetNamedBufferParameteri64v function. */
CheckTransformFeedbackBufferSize()5668 bool FunctionalTest::CheckTransformFeedbackBufferSize()
5669 {
5670 	/* Shortcut for GL functionality. */
5671 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5672 
5673 	/* Local query storage. */
5674 	glw::GLint64 size = -1;
5675 
5676 	/* Querry. */
5677 	m_pGetNamedBufferParameteri64v(m_bo_out, GL_BUFFER_SIZE, &size);
5678 
5679 	/* Error checking. */
5680 	if (GL_NO_ERROR == gl.getError())
5681 	{
5682 		/* Return value checking. */
5683 		if (-1 != size)
5684 		{
5685 			/* Test. */
5686 			if (sizeof(s_initial_data_b) == size)
5687 			{
5688 				return true;
5689 			}
5690 			else
5691 			{
5692 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Output buffer size is " << size
5693 													<< ", but " << sizeof(s_initial_data_b) << " was expected."
5694 													<< tcu::TestLog::EndMessage;
5695 			}
5696 		}
5697 		else
5698 		{
5699 			m_context.getTestContext().getLog() << tcu::TestLog::Message
5700 												<< "GetNamedBufferParameteri64v has not returned a data."
5701 												<< tcu::TestLog::EndMessage;
5702 		}
5703 	}
5704 	else
5705 	{
5706 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetNamedBufferParameteri64v has failed."
5707 											<< tcu::TestLog::EndMessage;
5708 	}
5709 
5710 	return false;
5711 }
5712 
5713 /** @brief Check that results of the test are equal to the expected reference values. */
CheckTransformFeedbackResult()5714 bool FunctionalTest::CheckTransformFeedbackResult()
5715 {
5716 	/* Shortcut for GL functionality. */
5717 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5718 
5719 	/* Local data storage. */
5720 	glw::GLint output_data[sizeof(s_initial_data_b) / sizeof(s_initial_data_b[0])] = {};
5721 
5722 	/* Fetch data. */
5723 	m_pGetNamedBufferSubData(m_bo_out, 0, sizeof(output_data), output_data);
5724 
5725 	/* Error checking. */
5726 	if (GL_NO_ERROR == gl.getError())
5727 	{
5728 		for (glw::GLuint i = 0; i < sizeof(s_initial_data_b) / sizeof(s_initial_data_b[0]); ++i)
5729 		{
5730 			if (s_expected_data[i] != output_data[i])
5731 			{
5732 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Expected data is not equal to results."
5733 													<< tcu::TestLog::EndMessage;
5734 				return false;
5735 			}
5736 		}
5737 
5738 		return true;
5739 	}
5740 	else
5741 	{
5742 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetNamedBufferSubData has failed."
5743 											<< tcu::TestLog::EndMessage;
5744 	}
5745 	return false;
5746 }
5747 
5748 /** Clean all test's GL objects and state. */
Cleanup()5749 void FunctionalTest::Cleanup()
5750 {
5751 	/* Shortcut for GL functionality. */
5752 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5753 
5754 	/* Cleanup objects. */
5755 	if (m_po)
5756 	{
5757 		gl.useProgram(0);
5758 
5759 		gl.deleteProgram(m_po);
5760 
5761 		m_po = 0;
5762 	}
5763 
5764 	if (m_vao)
5765 	{
5766 		gl.deleteVertexArrays(1, &m_vao);
5767 
5768 		m_vao = 0;
5769 	}
5770 
5771 	if (0 <= m_attrib_location)
5772 	{
5773 		gl.disableVertexAttribArray(m_attrib_location);
5774 
5775 		m_attrib_location = -1;
5776 	}
5777 
5778 	if (m_bo_in)
5779 	{
5780 		gl.deleteBuffers(1, &m_bo_in);
5781 
5782 		m_bo_in = 0;
5783 	}
5784 
5785 	if (m_bo_out)
5786 	{
5787 		gl.deleteBuffers(1, &m_bo_out);
5788 
5789 		m_bo_out = 0;
5790 	}
5791 
5792 	/* Make sure that rasterizer is turned on (default). */
5793 	gl.enable(GL_RASTERIZER_DISCARD);
5794 
5795 	/* Clean all errors. */
5796 	while (gl.getError())
5797 		;
5798 }
5799 
5800 } /* Buffers namespace. */
5801 } /* DirectStateAccess namespace. */
5802 } /* gl4cts namespace. */
5803