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 dummy_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(dummy_data), &dummy_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, &dummy_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, &dummy_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, &dummy_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(dummy_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, &dummy_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(dummy_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, &dummy_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, &dummy_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, &dummy_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 dummy_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(dummy_data), &dummy_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(dummy_data), GL_RGBA, GL_UNSIGNED_BYTE,
2888 &dummy_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, &dummy_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(dummy_data[0]), sizeof(dummy_data), GL_RGBA,
2930 GL_UNSIGNED_BYTE, &dummy_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(dummy_data) - sizeof(dummy_data[0]), GL_RGBA,
2940 GL_UNSIGNED_BYTE, &dummy_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(dummy_data), GL_RGBA, GL_UNSIGNED_BYTE, &dummy_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(dummy_data)), GL_RGBA, GL_UNSIGNED_BYTE,
2959 &dummy_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(dummy_data), GL_RGBA, GL_UNSIGNED_BYTE,
2968 &dummy_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(dummy_data), GL_RGBA, GL_UNSIGNED_BYTE, &dummy_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(dummy_data), GL_MAP_READ_BIT);
2994 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
2995
2996 m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(dummy_data), GL_RGBA, GL_UNSIGNED_BYTE, &dummy_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(dummy_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(dummy_data), GL_RGBA, GL_UNSIGNED_BYTE, &dummy_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(dummy_data), invalid_format, GL_UNSIGNED_BYTE,
3045 &dummy_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(dummy_data), GL_RGBA, invalid_type, &dummy_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 dummy_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(dummy_data), &dummy_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(dummy_data), &dummy_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(dummy_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(dummy_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(dummy_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(dummy_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(dummy_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(dummy_data) / 2, 0, sizeof(dummy_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(dummy_data) / 2, sizeof(dummy_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(dummy_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(dummy_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(dummy_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(dummy_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(dummy_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(dummy_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(dummy_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(dummy_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(dummy_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(dummy_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(dummy_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 dummy_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(dummy_data), &dummy_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(dummy_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(dummy_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*)
3479 m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data) / 2, 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(dummy_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(dummy_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(dummy_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(dummy_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(dummy_data), GL_MAP_WRITE_BIT);
3517 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3518
3519 m_pFlushMappedNamedBufferRange(buffer, 0, sizeof(dummy_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 dummy_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(dummy_data), &dummy_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 dummy_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(dummy_data), &dummy_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 dummy_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(dummy_data), &dummy_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 dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};
3813
3814 /* Test. */
3815 m_pGetNamedBufferSubData(not_a_buffer_name, 0, sizeof(dummy_data_query), dummy_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 dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};
3825
3826 /* Test. */
3827 m_pGetNamedBufferSubData(buffer, -1, sizeof(dummy_data_query), dummy_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 dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};
3836
3837 /* Test. */
3838 m_pGetNamedBufferSubData(buffer, 0, -1, dummy_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 dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};
3847
3848 /* Test. */
3849 m_pGetNamedBufferSubData(buffer, 0, 2 * sizeof(dummy_data_query), dummy_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 dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};
3859
3860 /* Test. */
3861 m_pGetNamedBufferSubData(buffer, sizeof(dummy_data_query) / 2, sizeof(dummy_data_query), dummy_data_query);
3862
3863 is_ok &=
3864 ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE,
3865 " if offset+size is greater than the value of BUFFER_SIZE for the buffer object.");
3866 }
3867
3868 /* Test offset overflow error behavior. */
3869 {
3870 /* Query storage. */
3871 glw::GLubyte dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};
3872
3873 /* Test. */
3874 m_pGetNamedBufferSubData(buffer, sizeof(dummy_data_query) + 1, 0, dummy_data_query);
3875
3876 is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE,
3877 " if offset is greater than the value of BUFFER_SIZE for the buffer object.");
3878 }
3879
3880 /* Test mapped buffer query error behavior. */
3881 {
3882 /* Query storage. */
3883 glw::GLubyte dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};
3884
3885 /* Test. */
3886 (void)(glw::GLbyte*) m_pMapNamedBuffer(buffer, GL_WRITE_ONLY);
3887 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3888
3889 m_pGetNamedBufferSubData(buffer, 0, sizeof(dummy_data_query), dummy_data_query);
3890
3891 is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_OPERATION,
3892 " if the buffer object is mapped with MapBufferRange.");
3893
3894 m_pUnmapNamedBuffer(buffer);
3895 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3896 }
3897
3898 /* Test mapped buffer query error behavior. */
3899 {
3900 /* Query storage. */
3901 glw::GLubyte dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};
3902
3903 /* Test. */
3904 (void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_WRITE_BIT);
3905 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3906
3907 m_pGetNamedBufferSubData(buffer, 0, sizeof(dummy_data_query), dummy_data_query);
3908
3909 is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_OPERATION,
3910 " if the buffer object is mapped with MapBufferRange.");
3911
3912 m_pUnmapNamedBuffer(buffer);
3913 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3914 }
3915
3916 /* Test persistently mapped buffer query behavior. */
3917 {
3918 /* Query storage. */
3919 glw::GLubyte dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};
3920
3921 /* Test. */
3922 (void)(glw::GLbyte*)
3923 m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
3924 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3925
3926 m_pGetNamedBufferSubData(buffer, 0, sizeof(dummy_data_query), dummy_data_query);
3927
3928 is_ok &= ErrorCheckAndLog(
3929 "glGetNamedBufferSubData", GL_NO_ERROR,
3930 " if the buffer object is mapped with MapBufferRange with GL_MAP_PERSISTENT_BIT flag.");
3931
3932 m_pUnmapNamedBuffer(buffer);
3933 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3934 }
3935 }
3936 catch (...)
3937 {
3938 is_ok = false;
3939 internal_error = true;
3940 }
3941
3942 if (buffer)
3943 {
3944 gl.deleteBuffers(1, &buffer);
3945
3946 buffer = 0;
3947 }
3948
3949 if (internal_error)
3950 {
3951 throw 0;
3952 }
3953
3954 return is_ok;
3955 }
3956
3957 /** @brief Test Errors Of MapNamedBuffer function.
3958 *
3959 * Check that INVALID_OPERATION is generated by MapNamedBuffer if buffer is
3960 * not the name of an existing buffer object.
3961 *
3962 * Check that INVALID_ENUM is generated by MapNamedBuffer if access is not
3963 * READ_ONLY, WRITE_ONLY, or READ_WRITE.
3964 *
3965 * Check that INVALID_OPERATION is generated by MapNamedBuffer if the
3966 * buffer object is in a mapped state.
3967 *
3968 * True if test case succeeded, false otherwise.
3969 */
TestErrorsOfMapNamedBuffer()3970 bool ErrorsTest::TestErrorsOfMapNamedBuffer()
3971 {
3972 /* Shortcut for GL functionality. */
3973 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3974
3975 /* Return value. */
3976 bool is_ok = true;
3977 bool internal_error = false;
3978
3979 /* Common variables. */
3980 glw::GLuint buffer = 0;
3981 glw::GLubyte dummy_data[4] = {};
3982
3983 try
3984 {
3985 /* Common preparations. */
3986 gl.createBuffers(1, &buffer);
3987 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
3988
3989 m_pNamedBufferStorage(buffer, sizeof(dummy_data), &dummy_data, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
3990 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
3991
3992 /* Test invalid buffer name error behavior. */
3993 {
3994 /* Prepare for invalid buffer name error behavior verification. */
3995 glw::GLuint not_a_buffer_name = 0;
3996
3997 while (gl.isBuffer(++not_a_buffer_name))
3998 ;
3999
4000 /* Test. */
4001 m_pMapNamedBuffer(not_a_buffer_name, GL_READ_ONLY);
4002
4003 is_ok &= ErrorCheckAndLog("glMapNamedBuffer", GL_INVALID_OPERATION,
4004 " if buffer is not the name of an existing buffer object.");
4005 }
4006
4007 /* Test access flag error behavior. */
4008 {
4009 /* Prepare for invalid type error behavior verification. */
4010 static const glw::GLenum valid_access_flags[] = { GL_READ_ONLY, GL_WRITE_ONLY, GL_READ_WRITE, GL_NONE };
4011 static const glw::GLenum valid_access_flags_last =
4012 sizeof(valid_access_flags) / sizeof(valid_access_flags[0]) - 1;
4013
4014 glw::GLenum invalid_access_flags = 0;
4015
4016 while (&valid_access_flags[valid_access_flags_last] !=
4017 std::find(&valid_access_flags[0], &valid_access_flags[valid_access_flags_last],
4018 (++invalid_access_flags)))
4019 ;
4020
4021 /* Test. */
4022 glw::GLbyte* mapped_data = (glw::GLbyte*)m_pMapNamedBuffer(buffer, invalid_access_flags);
4023
4024 is_ok &= ErrorCheckAndLog("glMapNamedBuffer", GL_INVALID_ENUM,
4025 " if access is not READ_ONLY, WRITE_ONLY, or READ_WRITE.");
4026
4027 /* Sanity unmapping. */
4028 if (DE_NULL != mapped_data)
4029 {
4030 m_pUnmapNamedBuffer(buffer);
4031 while (gl.getError())
4032 ;
4033 }
4034 }
4035
4036 /* Test mapping of mapped buffer error behavior. */
4037 {
4038 (void)(glw::GLbyte*) m_pMapNamedBuffer(buffer, GL_READ_ONLY);
4039 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer.");
4040
4041 glw::GLbyte* subsequent_mapped_data = (glw::GLbyte*)m_pMapNamedBuffer(buffer, GL_READ_ONLY);
4042
4043 is_ok &= ErrorCheckAndLog("glMapNamedBuffer", GL_INVALID_OPERATION,
4044 " if the buffer object is in a mapped state.");
4045
4046 m_pUnmapNamedBuffer(buffer);
4047 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
4048
4049 if (subsequent_mapped_data)
4050 {
4051 m_context.getTestContext().getLog()
4052 << tcu::TestLog::Message
4053 << "glMapNamedBuffer called on mapped buffer returned non-NULL pointer when error shall occure."
4054 "This may lead to undefined behavior during next tests (object still may be mapped). "
4055 "Test was terminated prematurely."
4056 << tcu::TestLog::EndMessage;
4057 throw 0;
4058 }
4059 }
4060 }
4061 catch (...)
4062 {
4063 is_ok = false;
4064 internal_error = true;
4065 }
4066
4067 if (buffer)
4068 {
4069 gl.deleteBuffers(1, &buffer);
4070
4071 buffer = 0;
4072 }
4073
4074 if (internal_error)
4075 {
4076 throw 0;
4077 }
4078
4079 return is_ok;
4080 }
4081
4082 /** @brief Test Errors Of MapNamedBufferRange function.
4083 *
4084 * Check that INVALID_OPERATION is generated by MapNamedBufferRange if
4085 * buffer is not the name of an existing buffer object.
4086 *
4087 * Check that INVALID_VALUE is generated by MapNamedBufferRange if offset
4088 * or length is negative, if offset+length is greater than the value of
4089 * BUFFER_SIZE for the buffer object, or if access has any bits set other
4090 * than those defined above.
4091 *
4092 * Check that INVALID_OPERATION is generated by MapNamedBufferRange for any
4093 * of the following conditions:
4094 * - length is zero.
4095 * - The buffer object is already in a mapped state.
4096 * - Neither MAP_READ_BIT nor MAP_WRITE_BIT is set.
4097 * - MAP_READ_BIT is set and any of MAP_INVALIDATE_RANGE_BIT,
4098 * MAP_INVALIDATE_BUFFER_BIT or MAP_UNSYNCHRONIZED_BIT is set.
4099 * - MAP_FLUSH_EXPLICIT_BIT is set and MAP_WRITE_BIT is not set.
4100 * - Any of MAP_READ_BIT, MAP_WRITE_BIT, MAP_PERSISTENT_BIT, or
4101 * MAP_COHERENT_BIT are set, but the same bit is not included in the
4102 * buffer's storage flags.
4103 *
4104 * True if test case succeeded, false otherwise.
4105 */
TestErrorsOfMapNamedBufferRange()4106 bool ErrorsTest::TestErrorsOfMapNamedBufferRange()
4107 {
4108 /* Shortcut for GL functionality. */
4109 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4110
4111 /* Return value. */
4112 bool is_ok = true;
4113 bool internal_error = false;
4114
4115 /* Common variables. */
4116 glw::GLuint buffer = 0;
4117 glw::GLuint buffer_special_flags = 0;
4118 glw::GLubyte dummy_data[4] = {};
4119
4120 try
4121 {
4122 /* Common preparations. */
4123 gl.createBuffers(1, &buffer);
4124 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4125
4126 m_pNamedBufferStorage(buffer, sizeof(dummy_data), &dummy_data,
4127 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
4128 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4129
4130 /* Test invalid buffer name error behavior. */
4131 {
4132 /* Prepare for invalid buffer name error behavior verification. */
4133 glw::GLuint not_a_buffer_name = 0;
4134
4135 while (gl.isBuffer(++not_a_buffer_name))
4136 ;
4137
4138 /* Test. */
4139 m_pMapNamedBufferRange(not_a_buffer_name, 0, sizeof(dummy_data), GL_MAP_READ_BIT);
4140
4141 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
4142 " if buffer is not the name of an existing buffer object.");
4143 }
4144
4145 /* Test negative offset error behavior. */
4146 {
4147 glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, -1, sizeof(dummy_data), GL_MAP_READ_BIT);
4148
4149 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE, " if offset is negative.");
4150
4151 /* Sanity unmapping. */
4152 if (DE_NULL != mapped_data)
4153 {
4154 m_pUnmapNamedBuffer(buffer);
4155 while (gl.getError())
4156 ;
4157 }
4158 }
4159
4160 /* Test negative length error behavior. */
4161 {
4162 glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, 0, -1, GL_MAP_READ_BIT);
4163
4164 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE, " if length is negative.");
4165
4166 /* Sanity unmapping. */
4167 if (DE_NULL != mapped_data)
4168 {
4169 m_pUnmapNamedBuffer(buffer);
4170 while (gl.getError())
4171 ;
4172 }
4173 }
4174
4175 /* Test length overflow error behavior. */
4176 {
4177 glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data) * 2, GL_MAP_READ_BIT);
4178
4179 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE,
4180 " if length is greater than the value of BUFFER_SIZE"
4181 " for the buffer object, or if access has any bits set other"
4182 " than those defined above.");
4183
4184 /* Sanity unmapping. */
4185 if (DE_NULL != mapped_data)
4186 {
4187 m_pUnmapNamedBuffer(buffer);
4188 while (gl.getError())
4189 ;
4190 }
4191 }
4192
4193 /* Test (offset+length) overflow error behavior. */
4194 {
4195 glw::GLvoid* mapped_data =
4196 m_pMapNamedBufferRange(buffer, sizeof(dummy_data) / 2, sizeof(dummy_data), GL_MAP_READ_BIT);
4197
4198 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE,
4199 " if offset+length is greater than the value of BUFFER_SIZE"
4200 " for the buffer object, or if access has any bits set other"
4201 " than those defined above.");
4202
4203 /* Sanity unmapping. */
4204 if (DE_NULL != mapped_data)
4205 {
4206 m_pUnmapNamedBuffer(buffer);
4207 while (gl.getError())
4208 ;
4209 }
4210 }
4211
4212 /* Test zero length error behavior. */
4213 {
4214 glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, 0, 0, GL_MAP_READ_BIT);
4215
4216 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION, " if length is zero.");
4217
4218 /* Sanity unmapping. */
4219 if (DE_NULL != mapped_data)
4220 {
4221 m_pUnmapNamedBuffer(buffer);
4222 while (gl.getError())
4223 ;
4224 }
4225 }
4226
4227 /* Test mapping of mapped buffer error behavior. */
4228 {
4229 m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_READ_BIT);
4230 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer.");
4231
4232 glw::GLvoid* subsequent_mapped_data =
4233 m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_READ_BIT);
4234
4235 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
4236 " if the buffer object is in a mapped state.");
4237
4238 m_pUnmapNamedBuffer(buffer);
4239 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
4240
4241 if (subsequent_mapped_data)
4242 {
4243 m_context.getTestContext().getLog()
4244 << tcu::TestLog::Message
4245 << "glMapNamedBufferRange called on mapped buffer returned non-NULL pointer when error shall "
4246 "occure."
4247 "This may lead to undefined behavior during next tests (object still may be mapped). "
4248 "Test was terminated prematurely."
4249 << tcu::TestLog::EndMessage;
4250 throw 0;
4251 }
4252 }
4253
4254 /* Test access flag read and write bits are not set error behavior. */
4255 {
4256 glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), 0);
4257
4258 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
4259 " if neither MAP_READ_BIT nor MAP_WRITE_BIT is set.");
4260
4261 /* Sanity unmapping. */
4262 if (DE_NULL != mapped_data)
4263 {
4264 m_pUnmapNamedBuffer(buffer);
4265 while (gl.getError())
4266 ;
4267 }
4268 }
4269
4270 /* Test read access invalid flags error behavior. */
4271 {
4272 glw::GLenum read_access_invalid_flags[] = { GL_MAP_INVALIDATE_RANGE_BIT, GL_MAP_INVALIDATE_BUFFER_BIT,
4273 GL_MAP_UNSYNCHRONIZED_BIT };
4274 const glw::GLchar* read_access_invalid_flags_log[] = {
4275 " if MAP_READ_BIT is set with MAP_INVALIDATE_RANGE_BIT.",
4276 " if MAP_READ_BIT is set with MAP_INVALIDATE_BUFFER_BIT.",
4277 " if MAP_READ_BIT is set with MAP_UNSYNCHRONIZED_BIT."
4278 };
4279 glw::GLuint read_access_invalid_flags_count =
4280 sizeof(read_access_invalid_flags) / sizeof(read_access_invalid_flags[0]);
4281
4282 for (glw::GLuint i = 0; i < read_access_invalid_flags_count; ++i)
4283 {
4284 glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data),
4285 GL_MAP_READ_BIT | read_access_invalid_flags[i]);
4286
4287 is_ok &=
4288 ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION, read_access_invalid_flags_log[i]);
4289
4290 /* Sanity unmapping. */
4291 if (DE_NULL != mapped_data)
4292 {
4293 m_pUnmapNamedBuffer(buffer);
4294 while (gl.getError())
4295 ;
4296 }
4297 }
4298 }
4299
4300 /* Test access flush bit without write bit error behavior. */
4301 {
4302 glw::GLvoid* mapped_data =
4303 m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_READ_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
4304
4305 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
4306 " if MAP_FLUSH_EXPLICIT_BIT is set and MAP_WRITE_BIT is not set.");
4307
4308 /* Sanity unmapping. */
4309 if (DE_NULL != mapped_data)
4310 {
4311 m_pUnmapNamedBuffer(buffer);
4312 while (gl.getError())
4313 ;
4314 }
4315 }
4316
4317 /* Test incompatible buffer flag error behavior. */
4318 {
4319 glw::GLenum buffer_flags[] = { GL_MAP_WRITE_BIT, GL_MAP_READ_BIT, GL_MAP_WRITE_BIT,
4320 GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT };
4321 glw::GLenum mapping_flags[] = { GL_MAP_READ_BIT, GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT,
4322 GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT };
4323 const glw::GLchar* mapping_flags_log[] = {
4324 " if MAP_READ_BIT is set, but the same bit is not included in the buffer's storage flags.",
4325 " if MAP_WRITE_BIT is set, but the same bit is not included in the buffer's storage flags.",
4326 " if MAP_PERSISTENT_BIT is set, but the same bit is not included in the buffer's storage flags.",
4327 " if MAP_COHERENT_BIT is set, but the same bit is not included in the buffer's storage flags."
4328 };
4329 glw::GLuint flags_count = sizeof(mapping_flags) / sizeof(mapping_flags[0]);
4330
4331 for (glw::GLuint i = 0; i < flags_count; ++i)
4332 {
4333 /* Create buffer. */
4334 gl.createBuffers(1, &buffer_special_flags);
4335 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4336
4337 m_pNamedBufferStorage(buffer_special_flags, sizeof(dummy_data), &dummy_data, buffer_flags[i]);
4338 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4339
4340 /* Test mapping. */
4341 glw::GLvoid* mapped_data =
4342 m_pMapNamedBufferRange(buffer_special_flags, 0, sizeof(dummy_data), mapping_flags[i]);
4343
4344 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION, mapping_flags_log[i]);
4345
4346 /* Sanity unmapping. */
4347 if (DE_NULL != mapped_data)
4348 {
4349 m_pUnmapNamedBuffer(buffer);
4350 while (gl.getError())
4351 ;
4352 }
4353
4354 /* Releasing buffer. */
4355 if (buffer_special_flags)
4356 {
4357 gl.deleteBuffers(1, &buffer_special_flags);
4358
4359 buffer_special_flags = 0;
4360 }
4361 }
4362 }
4363 }
4364 catch (...)
4365 {
4366 is_ok = false;
4367 internal_error = true;
4368 }
4369
4370 if (buffer)
4371 {
4372 gl.deleteBuffers(1, &buffer);
4373
4374 buffer = 0;
4375 }
4376
4377 if (buffer_special_flags)
4378 {
4379 gl.deleteBuffers(1, &buffer_special_flags);
4380
4381 buffer_special_flags = 0;
4382 }
4383
4384 if (internal_error)
4385 {
4386 throw 0;
4387 }
4388
4389 return is_ok;
4390 }
4391
4392 /** @brief Test Errors Of NamedBufferData function.
4393 *
4394 * Check that INVALID_OPERATION is generated by NamedBufferData if buffer
4395 * is not the name of an existing buffer object.
4396 *
4397 * Check that INVALID_ENUM is generated by NamedBufferData if usage is not
4398 * STREAM_DRAW, STREAM_READ, STREAM_COPY, STATIC_DRAW, STATIC_READ,
4399 * STATIC_COPY, DYNAMIC_DRAW, DYNAMIC_READ or DYNAMIC_COPY.
4400 *
4401 * Check that INVALID_VALUE is generated by NamedBufferData if size is
4402 * negative.
4403 *
4404 * Check that INVALID_OPERATION is generated by NamedBufferData if the
4405 * BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE.
4406 *
4407 * True if test case succeeded, false otherwise.
4408 */
TestErrorsOfNamedBufferData()4409 bool ErrorsTest::TestErrorsOfNamedBufferData()
4410 {
4411 /* Shortcut for GL functionality. */
4412 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4413
4414 /* Return value. */
4415 bool is_ok = true;
4416 bool internal_error = false;
4417
4418 /* Common variables. */
4419 glw::GLuint buffer = 0;
4420 glw::GLuint immutable_buffer = 0;
4421 glw::GLubyte dummy_data[4] = {};
4422 std::stack<glw::GLuint> too_much_buffers;
4423
4424 try
4425 {
4426 /* Common preparations. */
4427 gl.createBuffers(1, &buffer);
4428 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4429
4430 gl.createBuffers(1, &immutable_buffer);
4431 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4432
4433 m_pNamedBufferStorage(immutable_buffer, sizeof(dummy_data), &dummy_data, GL_MAP_READ_BIT);
4434 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4435
4436 /* Test invalid buffer name error behavior. */
4437 {
4438 /* Prepare for invalid buffer name error behavior verification. */
4439 glw::GLuint not_a_buffer_name = 0;
4440
4441 while (gl.isBuffer(++not_a_buffer_name))
4442 ;
4443
4444 /* Test. */
4445 m_pNamedBufferData(not_a_buffer_name, sizeof(dummy_data), dummy_data, GL_DYNAMIC_COPY);
4446
4447 is_ok &= ErrorCheckAndLog("glNamedBufferData", GL_INVALID_OPERATION,
4448 " if buffer is not the name of an existing buffer object.");
4449 }
4450
4451 /* Test invalid usage error behavior. */
4452 {
4453 /* Prepare for invalid type error behavior verification. */
4454 static const glw::GLenum valid_usages[] = { GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY,
4455 GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY,
4456 GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, GL_DYNAMIC_COPY,
4457 GL_NONE };
4458 static const glw::GLenum valid_usages_last = sizeof(valid_usages) / sizeof(valid_usages[0]) - 1;
4459
4460 glw::GLenum invalid_usage = 0;
4461
4462 while (&valid_usages[valid_usages_last] !=
4463 std::find(&valid_usages[0], &valid_usages[valid_usages_last], (++invalid_usage)))
4464 ;
4465
4466 /* Test. */
4467 m_pNamedBufferData(buffer, sizeof(dummy_data), dummy_data, invalid_usage);
4468
4469 is_ok &=
4470 ErrorCheckAndLog("glNamedBufferData", GL_INVALID_ENUM,
4471 " if usage is not STREAM_DRAW, STREAM_READ, STREAM_COPY, STATIC_DRAW, STATIC_READ,"
4472 " STATIC_COPY, DYNAMIC_DRAW, DYNAMIC_READ or DYNAMIC_COPY.");
4473 }
4474
4475 /* Test negative size error behavior. */
4476 {
4477 m_pNamedBufferData(buffer, -1, dummy_data, GL_DYNAMIC_COPY);
4478
4479 is_ok &= ErrorCheckAndLog("glNamedBufferData", GL_INVALID_VALUE, " if size is negative.");
4480 }
4481
4482 /* Test immutable buffer error behavior. */
4483 {
4484 m_pNamedBufferData(immutable_buffer, sizeof(dummy_data) / 2, dummy_data, GL_DYNAMIC_COPY);
4485
4486 is_ok &= ErrorCheckAndLog("glNamedBufferData", GL_INVALID_OPERATION,
4487 " if the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE.");
4488 }
4489 }
4490 catch (...)
4491 {
4492 is_ok = false;
4493 internal_error = true;
4494 }
4495
4496 if (buffer)
4497 {
4498 gl.deleteBuffers(1, &buffer);
4499
4500 buffer = 0;
4501 }
4502
4503 while (!too_much_buffers.empty())
4504 {
4505 glw::GLuint tmp_buffer = too_much_buffers.top();
4506
4507 if (tmp_buffer)
4508 {
4509 gl.deleteBuffers(1, &tmp_buffer);
4510 }
4511
4512 too_much_buffers.pop();
4513 }
4514
4515 if (immutable_buffer)
4516 {
4517 gl.deleteBuffers(1, &immutable_buffer);
4518
4519 immutable_buffer = 0;
4520 }
4521
4522 if (internal_error)
4523 {
4524 throw 0;
4525 }
4526
4527 return is_ok;
4528 }
4529
4530 /** @brief Test Errors Of NamedBufferStorage function.
4531 *
4532 * Check that INVALID_OPERATION is generated by NamedBufferStorage if
4533 * buffer is not the name of an existing buffer object.
4534 *
4535 * Check that INVALID_VALUE is generated by NamedBufferStorage if size is
4536 * less than or equal to zero.
4537 *
4538 * Check that INVALID_VALUE is generated by NamedBufferStorage if flags has
4539 * any bits set other than DYNAMIC_STORAGE_BIT, MAP_READ_BIT,
4540 * MAP_WRITE_BIT, MAP_PERSISTENT_BIT, MAP_COHERENT_BIT or
4541 * CLIENT_STORAGE_BIT.
4542 *
4543 * Check that INVALID_VALUE error is generated by NamedBufferStorage if
4544 * flags contains MAP_PERSISTENT_BIT but does not contain at least one of
4545 * MAP_READ_BIT or MAP_WRITE_BIT.
4546 *
4547 * Check that INVALID_VALUE is generated by NamedBufferStorage if flags
4548 * contains MAP_COHERENT_BIT, but does not also contain MAP_PERSISTENT_BIT.
4549 *
4550 * True if test case succeeded, false otherwise.
4551 */
TestErrorsOfNamedBufferStorage()4552 bool ErrorsTest::TestErrorsOfNamedBufferStorage()
4553 {
4554 /* Shortcut for GL functionality. */
4555 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4556
4557 /* Return value. */
4558 bool is_ok = true;
4559 bool internal_error = false;
4560
4561 /* Common variables. */
4562 glw::GLuint buffer = 0;
4563 glw::GLubyte dummy_data[4] = {};
4564 std::stack<glw::GLuint> too_much_buffers;
4565
4566 try
4567 {
4568 /* Test invalid buffer name error behavior. */
4569 {
4570 /* Prepare for invalid buffer name error behavior verification. */
4571 glw::GLuint not_a_buffer_name = 0;
4572
4573 while (gl.isBuffer(++not_a_buffer_name))
4574 ;
4575
4576 /* Test. */
4577 m_pNamedBufferStorage(not_a_buffer_name, sizeof(dummy_data), dummy_data, GL_MAP_WRITE_BIT);
4578
4579 is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_OPERATION,
4580 " if buffer is not the name of an existing buffer object.");
4581 }
4582
4583 /* Test negative or zero size error behavior. */
4584 {
4585 /* Object creation. */
4586 gl.createBuffers(1, &buffer);
4587 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4588
4589 /* Test negative size. */
4590 m_pNamedBufferStorage(buffer, -1, dummy_data, GL_DYNAMIC_COPY);
4591
4592 is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE, " if size is negative.");
4593
4594 /* Test zero size. */
4595 m_pNamedBufferStorage(buffer, 0, dummy_data, GL_DYNAMIC_COPY);
4596
4597 is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE, " if size zero.");
4598
4599 /* Clean-up. */
4600 gl.deleteBuffers(1, &buffer);
4601
4602 buffer = 0;
4603
4604 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
4605 }
4606
4607 /* Test invalid usage bit error behavior. */
4608 {
4609 /* Prepare for invalid type error behavior verification. */
4610 glw::GLuint valid_bits = GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT |
4611 GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT;
4612
4613 if (m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_buffer"))
4614 {
4615 valid_bits |= GL_SPARSE_STORAGE_BIT_ARB;
4616 }
4617
4618 if (m_context.getContextInfo().isExtensionSupported("GL_NV_gpu_multicast") ||
4619 m_context.getContextInfo().isExtensionSupported("GL_NVX_linked_gpu_multicast"))
4620 {
4621 valid_bits |= GL_PER_GPU_STORAGE_BIT_NV;
4622 }
4623
4624 if (m_context.getContextInfo().isExtensionSupported("GL_NVX_cross_process_interop"))
4625 {
4626 valid_bits |= GL_EXTERNAL_STORAGE_BIT_NVX;
4627 }
4628
4629 glw::GLuint invalid_bits = ~valid_bits;
4630
4631 glw::GLuint bits_count = CHAR_BIT * sizeof(invalid_bits);
4632
4633 /* Test. */
4634 for (glw::GLuint i = 0; i < bits_count; ++i)
4635 {
4636 glw::GLuint possibly_invalid_bit = (1 << i);
4637
4638 if (invalid_bits & possibly_invalid_bit)
4639 {
4640 /* Object creation. */
4641 gl.createBuffers(1, &buffer);
4642 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4643
4644 /* Test invalid bit. */
4645 m_pNamedBufferStorage(buffer, sizeof(dummy_data), dummy_data, possibly_invalid_bit);
4646
4647 is_ok &=
4648 ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE,
4649 " if flags has any bits set other than DYNAMIC_STORAGE_BIT, MAP_READ_BIT,"
4650 " MAP_WRITE_BIT, MAP_PERSISTENT_BIT, MAP_COHERENT_BIT or CLIENT_STORAGE_BIT.");
4651
4652 /* Release object. */
4653 gl.deleteBuffers(1, &buffer);
4654
4655 buffer = 0;
4656
4657 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
4658 }
4659 }
4660 }
4661
4662 /* Test improper persistent bit behavior error behavior. */
4663 {
4664 /* Object creation. */
4665 gl.createBuffers(1, &buffer);
4666 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4667
4668 /* Test. */
4669 m_pNamedBufferStorage(buffer, sizeof(dummy_data), dummy_data, GL_MAP_PERSISTENT_BIT);
4670
4671 is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE, " if flags contains MAP_PERSISTENT_BIT "
4672 "but does not contain at least one of "
4673 "MAP_READ_BIT or MAP_WRITE_BIT.");
4674
4675 /* Clean-up. */
4676 gl.deleteBuffers(1, &buffer);
4677
4678 buffer = 0;
4679
4680 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
4681 }
4682
4683 /* Test improper persistent bit behavior error behavior. */
4684 {
4685 /* Object creation. */
4686 gl.createBuffers(1, &buffer);
4687 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4688
4689 /* Test. */
4690 m_pNamedBufferStorage(buffer, sizeof(dummy_data), dummy_data,
4691 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT);
4692
4693 is_ok &=
4694 ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE,
4695 " if flags contains MAP_COHERENT_BIT, but does not also contain MAP_PERSISTENT_BIT.");
4696
4697 /* Clean-up. */
4698 gl.deleteBuffers(1, &buffer);
4699
4700 buffer = 0;
4701
4702 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
4703 }
4704 }
4705 catch (...)
4706 {
4707 is_ok = false;
4708 internal_error = true;
4709 }
4710
4711 if (buffer)
4712 {
4713 gl.deleteBuffers(1, &buffer);
4714
4715 buffer = 0;
4716 }
4717
4718 while (!too_much_buffers.empty())
4719 {
4720 glw::GLuint tmp_buffer = too_much_buffers.top();
4721
4722 if (tmp_buffer)
4723 {
4724 gl.deleteBuffers(1, &tmp_buffer);
4725 }
4726
4727 too_much_buffers.pop();
4728 }
4729
4730 if (internal_error)
4731 {
4732 throw 0;
4733 }
4734
4735 return is_ok;
4736 }
4737
4738 /** @brief Test Errors Of NamedBufferSubData function.
4739 *
4740 * Check that INVALID_OPERATION is generated by NamedBufferSubData if
4741 * buffer is not the name of an existing buffer object.
4742 *
4743 * Check that INVALID_VALUE is generated by NamedBufferSubData if offset or
4744 * size is negative, or if offset+size is greater than the value of
4745 * BUFFER_SIZE for the specified buffer object.
4746 *
4747 * Check that INVALID_OPERATION is generated by NamedBufferSubData if any
4748 * part of the specified range of the buffer object is mapped with
4749 * MapBufferRange or MapBuffer, unless it was mapped with the
4750 * MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.
4751 *
4752 * Check that INVALID_OPERATION is generated by NamedBufferSubData if the
4753 * value of the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE
4754 * and the value of BUFFER_STORAGE_FLAGS for the buffer object does not
4755 * have the DYNAMIC_STORAGE_BIT bit set.
4756 *
4757 * True if test case succeeded, false otherwise.
4758 */
TestErrorsOfNamedBufferSubData()4759 bool ErrorsTest::TestErrorsOfNamedBufferSubData()
4760 {
4761 /* Shortcut for GL functionality. */
4762 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4763
4764 /* Return value. */
4765 bool is_ok = true;
4766 bool internal_error = false;
4767
4768 /* Common variables. */
4769 glw::GLuint buffer = 0;
4770 glw::GLuint immutable_storage_buffer = 0;
4771 glw::GLubyte dummy_data[4] = {};
4772
4773 try
4774 {
4775 /* Common preparations. */
4776 gl.createBuffers(1, &buffer);
4777 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4778
4779 m_pNamedBufferStorage(buffer, sizeof(dummy_data), &dummy_data,
4780 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT | GL_MAP_PERSISTENT_BIT);
4781 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4782
4783 gl.createBuffers(1, &immutable_storage_buffer);
4784 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4785
4786 m_pNamedBufferStorage(immutable_storage_buffer, sizeof(dummy_data), &dummy_data, GL_MAP_READ_BIT);
4787 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4788
4789 /* Test invalid buffer name error behavior. */
4790 {
4791 /* Prepare for invalid buffer name error behavior verification. */
4792 glw::GLuint not_a_buffer_name = 0;
4793
4794 while (gl.isBuffer(++not_a_buffer_name))
4795 ;
4796
4797 /* Test. */
4798 m_pNamedBufferSubData(not_a_buffer_name, 0, sizeof(dummy_data), &dummy_data);
4799
4800 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
4801 " if buffer is not the name of an existing buffer object.");
4802 }
4803
4804 /* Test negative offset error behavior. */
4805 {
4806 /* Test. */
4807 m_pNamedBufferSubData(buffer, -1, sizeof(dummy_data), &dummy_data);
4808
4809 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_VALUE, " if offset or size is negative.");
4810 }
4811
4812 /* Test negative size error behavior. */
4813 {
4814 /* Test. */
4815 m_pNamedBufferSubData(buffer, 0, -1, &dummy_data);
4816
4817 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_VALUE, " if offset or size is negative.");
4818 }
4819
4820 /* Test size overflow error behavior. */
4821 {
4822 /* Test. */
4823 m_pNamedBufferSubData(buffer, 0, sizeof(dummy_data) * 2, &dummy_data);
4824
4825 is_ok &= ErrorCheckAndLog(
4826 "glNamedBufferSubData", GL_INVALID_VALUE,
4827 " if offset+size is greater than the value of BUFFER_SIZE for the specified buffer object.");
4828 }
4829
4830 /* Test offset+size overflow error behavior. */
4831 {
4832 /* Test. */
4833 m_pNamedBufferSubData(buffer, sizeof(dummy_data) / 2, sizeof(dummy_data), &dummy_data);
4834
4835 is_ok &= ErrorCheckAndLog(
4836 "glNamedBufferSubData", GL_INVALID_VALUE,
4837 " if offset+size is greater than the value of BUFFER_SIZE for the specified buffer object.");
4838 }
4839
4840 /* Test of mapped buffer subdata error behavior verification (with glMapBuffer). */
4841 {
4842 (void)(glw::GLbyte*) m_pMapNamedBuffer(buffer, GL_READ_ONLY);
4843 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
4844
4845 m_pNamedBufferSubData(buffer, 0, sizeof(dummy_data), &dummy_data);
4846
4847 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
4848 " if any part of the specified range of the buffer"
4849 " object is mapped with MapBuffer, unless it was mapped with "
4850 "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");
4851
4852 m_pUnmapNamedBuffer(buffer);
4853 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
4854 }
4855
4856 /* Test of mapped buffer subdata error behavior verification (with glMapBufferRange). */
4857 {
4858 (void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_READ_BIT);
4859 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
4860
4861 m_pNamedBufferSubData(buffer, 0, sizeof(dummy_data), &dummy_data);
4862
4863 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
4864 " if any part of the specified range of the buffer"
4865 " object is mapped with MapBufferRange, unless it was mapped with "
4866 "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");
4867
4868 m_pUnmapNamedBuffer(buffer);
4869 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
4870 }
4871
4872 /* Test of persistently mapped buffer clear error with behavior verification. */
4873 {
4874 (void)(glw::GLbyte*)
4875 m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
4876 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
4877
4878 m_pNamedBufferSubData(buffer, 0, sizeof(dummy_data), &dummy_data);
4879
4880 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_NO_ERROR,
4881 " if any part of the specified range of the buffer"
4882 " object is mapped with MapBuffer with the MAP_PERSISTENT_BIT"
4883 " bit set in the MapBufferRange access flags.");
4884
4885 m_pUnmapNamedBuffer(buffer);
4886 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
4887 }
4888
4889 /* Test DYNAMIC_STORAGE_BIT bit off immutable buffer not set error behavior. */
4890 {
4891 /* Test. */
4892 m_pNamedBufferSubData(immutable_storage_buffer, 0, sizeof(dummy_data), &dummy_data);
4893
4894 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
4895 " if the value of the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE"
4896 " and the value of BUFFER_STORAGE_FLAGS for the buffer object does not"
4897 " have the DYNAMIC_STORAGE_BIT bit set.");
4898 }
4899
4900 /* Test DYNAMIC_STORAGE_BIT bit off immutable buffer set no error behavior. */
4901 {
4902 /* Test. */
4903 m_pNamedBufferSubData(buffer, 0, sizeof(dummy_data), &dummy_data);
4904
4905 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_NO_ERROR,
4906 " if the value of the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE"
4907 " and the value of BUFFER_STORAGE_FLAGS for the buffer object"
4908 " have the DYNAMIC_STORAGE_BIT bit set.");
4909 }
4910 }
4911 catch (...)
4912 {
4913 is_ok = false;
4914 internal_error = true;
4915 }
4916
4917 if (buffer)
4918 {
4919 gl.deleteBuffers(1, &buffer);
4920
4921 buffer = 0;
4922 }
4923
4924 if (immutable_storage_buffer)
4925 {
4926 gl.deleteBuffers(1, &immutable_storage_buffer);
4927
4928 buffer = 0;
4929 }
4930
4931 if (internal_error)
4932 {
4933 throw 0;
4934 }
4935
4936 return is_ok;
4937 }
4938
4939 /** @brief Test Errors Of UnmapNamedBuffer function.
4940 *
4941 * Check that INVALID_OPERATION is generated by UnmapNamedBuffer if buffer
4942 * is not the name of an existing buffer object.
4943 *
4944 * Check that INVALID_OPERATION is generated by UnmapNamedBuffer if the
4945 * buffer object is not in a mapped state.
4946 *
4947 * True if test case succeeded, false otherwise.
4948 */
TestErrorsOfUnmapNamedBuffer()4949 bool ErrorsTest::TestErrorsOfUnmapNamedBuffer()
4950 {
4951 /* Shortcut for GL functionality. */
4952 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4953
4954 /* Return value. */
4955 bool is_ok = true;
4956 bool internal_error = false;
4957
4958 /* Common variables. */
4959 glw::GLuint buffer = 0;
4960 glw::GLubyte dummy_data[4] = {};
4961
4962 try
4963 {
4964 /* Common preparations. */
4965 gl.createBuffers(1, &buffer);
4966 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4967
4968 m_pNamedBufferStorage(buffer, sizeof(dummy_data), &dummy_data,
4969 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT | GL_MAP_PERSISTENT_BIT);
4970 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4971
4972 /* Test invalid buffer name error behavior. */
4973 {
4974 /* Prepare for invalid buffer name error behavior verification. */
4975 glw::GLuint not_a_buffer_name = 0;
4976
4977 while (gl.isBuffer(++not_a_buffer_name))
4978 ;
4979
4980 /* Test. */
4981 m_pUnmapNamedBuffer(not_a_buffer_name);
4982
4983 is_ok &= ErrorCheckAndLog("glUnmapNamedBuffer", GL_INVALID_OPERATION,
4984 " if buffer is not the name of an existing buffer object.");
4985 }
4986
4987 /* Test not mapped buffer error behavior verification. */
4988 {
4989 m_pUnmapNamedBuffer(buffer);
4990
4991 is_ok &= ErrorCheckAndLog("glUnmapNamedBuffer", GL_INVALID_OPERATION,
4992 " if the buffer object is not in a mapped state.");
4993 }
4994 }
4995 catch (...)
4996 {
4997 is_ok = false;
4998 internal_error = true;
4999 }
5000
5001 if (buffer)
5002 {
5003 gl.deleteBuffers(1, &buffer);
5004
5005 buffer = 0;
5006 }
5007
5008 if (internal_error)
5009 {
5010 throw 0;
5011 }
5012
5013 return is_ok;
5014 }
5015
5016 /******************************** Functional Test Implementation ********************************/
5017
5018 /** @brief Vertex shader source code */
5019 const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 450\n"
5020 "\n"
5021 "in int data_in;\n"
5022 "out int data_out;\n"
5023 "\n"
5024 "void main()\n"
5025 "{\n"
5026 " gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
5027 "\n"
5028 " data_out = data_in * data_in;\n"
5029 "}\n";
5030
5031 /** @brief Fragment shader source code */
5032 const glw::GLchar FunctionalTest::s_fragment_shader[] = "#version 450\n"
5033 "\n"
5034 "out vec4 color;\n"
5035 "\n"
5036 "void main()\n"
5037 "{\n"
5038 " color = vec4(0.0);\n"
5039 "}\n";
5040
5041 const glw::GLchar FunctionalTest::s_vertex_shader_input_name[] =
5042 "data_in"; //!< Vertex shader's name of the input attribute.
5043
5044 const glw::GLchar* FunctionalTest::s_vertex_shader_output_name =
5045 "data_out"; //!< Vertex shader's name of the transform feedback varying.
5046
5047 const glw::GLint FunctionalTest::s_initial_data_a[] = {
5048 1, 2, 3, 4, 5, 5
5049 }; //!< Initial data to be uploaded for the input buffer.
5050
5051 const glw::GLint FunctionalTest::s_initial_data_b[] = {
5052 0, 0, 0, 0, 0, 0, 36
5053 }; //!< Initial data to be uploaded for the output buffer.
5054
5055 const glw::GLint FunctionalTest::s_expected_data[] = {
5056 0, 1, 4, 9, 16, 25, 36
5057 }; //!< Expected result which shall be read from output buffer.
5058
5059 /** @brief Functional Test constructor.
5060 *
5061 * @param [in] context OpenGL context.
5062 */
FunctionalTest(deqp::Context & context)5063 FunctionalTest::FunctionalTest(deqp::Context& context)
5064 : deqp::TestCase(context, "buffers_functional", "Buffer Objects Functional Test")
5065 , m_pClearNamedBufferData(DE_NULL)
5066 , m_pClearNamedBufferSubData(DE_NULL)
5067 , m_pCopyNamedBufferSubData(DE_NULL)
5068 , m_pFlushMappedNamedBufferRange(DE_NULL)
5069 , m_pGetNamedBufferParameteri64v(DE_NULL)
5070 , m_pGetNamedBufferParameteriv(DE_NULL)
5071 , m_pGetNamedBufferPointerv(DE_NULL)
5072 , m_pGetNamedBufferSubData(DE_NULL)
5073 , m_pMapNamedBuffer(DE_NULL)
5074 , m_pMapNamedBufferRange(DE_NULL)
5075 , m_pNamedBufferData(DE_NULL)
5076 , m_pNamedBufferStorage(DE_NULL)
5077 , m_pNamedBufferSubData(DE_NULL)
5078 , m_pUnmapNamedBuffer(DE_NULL)
5079 , m_po(0)
5080 , m_vao(0)
5081 , m_bo_in(0)
5082 , m_bo_out(0)
5083 , m_attrib_location(-1)
5084 {
5085 /* Intentionally left blank. */
5086 }
5087
5088 /** @brief Run Functional Test.
5089 *
5090 * @return Iteration result.
5091 */
iterate()5092 tcu::TestNode::IterateResult FunctionalTest::iterate()
5093 {
5094 /* Shortcut for GL functionality. */
5095 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5096
5097 /* Get context setup. */
5098 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
5099 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
5100
5101 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
5102 {
5103 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
5104
5105 return STOP;
5106 }
5107
5108 /* Running tests. */
5109 bool is_ok = true;
5110 bool is_error = false;
5111
5112 /* API function pointers setup. */
5113 m_pClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATA)gl.clearNamedBufferData;
5114 m_pClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATA)gl.clearNamedBufferSubData;
5115 m_pCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATA)gl.copyNamedBufferSubData;
5116 m_pFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGE)gl.flushMappedNamedBufferRange;
5117 m_pGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64V)gl.getNamedBufferParameteri64v;
5118 m_pGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIV)gl.getNamedBufferParameteriv;
5119 m_pGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERV)gl.getNamedBufferPointerv;
5120 m_pGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATA)gl.getNamedBufferSubData;
5121 m_pMapNamedBuffer = (PFNGLMAPNAMEDBUFFER)gl.mapNamedBuffer;
5122 m_pMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGE)gl.mapNamedBufferRange;
5123 m_pNamedBufferData = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
5124 m_pNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGE)gl.namedBufferStorage;
5125 m_pNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATA)gl.namedBufferSubData;
5126 m_pUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;
5127
5128 try
5129 {
5130 /* API function pointers check. */
5131 if ((DE_NULL == m_pClearNamedBufferData) || (DE_NULL == m_pClearNamedBufferSubData) ||
5132 (DE_NULL == m_pCopyNamedBufferSubData) || (DE_NULL == m_pFlushMappedNamedBufferRange) ||
5133 (DE_NULL == m_pGetNamedBufferParameteri64v) || (DE_NULL == m_pGetNamedBufferParameteriv) ||
5134 (DE_NULL == m_pGetNamedBufferPointerv) || (DE_NULL == m_pGetNamedBufferSubData) ||
5135 (DE_NULL == m_pMapNamedBuffer) || (DE_NULL == m_pMapNamedBufferRange) || (DE_NULL == m_pNamedBufferData) ||
5136 (DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pNamedBufferSubData) ||
5137 (DE_NULL == m_pUnmapNamedBuffer))
5138 {
5139 throw 0;
5140 }
5141
5142 /* Running test. */
5143 BuildProgram();
5144 PrepareVertexArrayObject();
5145
5146 is_ok = is_ok && PrepareInputBuffer();
5147 is_ok = is_ok && PrepareOutputBuffer();
5148
5149 if (is_ok)
5150 {
5151 Draw();
5152 }
5153
5154 is_ok = is_ok && CheckArrayBufferImmutableFlag();
5155 is_ok = is_ok && CheckTransformFeedbackBufferSize();
5156 is_ok = is_ok && CheckTransformFeedbackResult();
5157 }
5158 catch (...)
5159 {
5160 is_ok = false;
5161 is_error = true;
5162 }
5163
5164 /* Clean Up. */
5165 Cleanup();
5166
5167 /* Errors clean up. */
5168 while (gl.getError())
5169 ;
5170
5171 /* Result's setup. */
5172 if (is_ok)
5173 {
5174 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5175 }
5176 else
5177 {
5178 if (is_error)
5179 {
5180 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
5181 }
5182 else
5183 {
5184 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5185 }
5186 }
5187
5188 return STOP;
5189 }
5190
5191 /** @brief Build test's GL program */
BuildProgram()5192 void FunctionalTest::BuildProgram()
5193 {
5194 /* Shortcut for GL functionality */
5195 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5196
5197 struct Shader
5198 {
5199 glw::GLchar const* const source;
5200 glw::GLenum const type;
5201 glw::GLuint id;
5202 } shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
5203
5204 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
5205
5206 try
5207 {
5208 /* Create program. */
5209 m_po = gl.createProgram();
5210 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
5211
5212 /* Shader compilation. */
5213
5214 for (glw::GLuint i = 0; i < shader_count; ++i)
5215 {
5216 if (DE_NULL != shader[i].source)
5217 {
5218 shader[i].id = gl.createShader(shader[i].type);
5219
5220 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
5221
5222 gl.attachShader(m_po, shader[i].id);
5223
5224 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
5225
5226 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
5227
5228 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
5229
5230 gl.compileShader(shader[i].id);
5231
5232 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
5233
5234 glw::GLint status = GL_FALSE;
5235
5236 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
5237 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
5238
5239 if (GL_FALSE == status)
5240 {
5241 glw::GLint log_size = 0;
5242 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
5243 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
5244
5245 glw::GLchar* log_text = new glw::GLchar[log_size];
5246
5247 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
5248
5249 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
5250 << "Shader type: " << glu::getShaderTypeStr(shader[i].type)
5251 << "\n"
5252 << "Shader compilation error log:\n"
5253 << log_text << "\n"
5254 << "Shader source code:\n"
5255 << shader[i].source << "\n"
5256 << tcu::TestLog::EndMessage;
5257
5258 delete[] log_text;
5259
5260 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
5261
5262 throw 0;
5263 }
5264 }
5265 }
5266
5267 /* Tranform feedback varying */
5268 gl.transformFeedbackVaryings(m_po, 1, &s_vertex_shader_output_name, GL_INTERLEAVED_ATTRIBS);
5269 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
5270
5271 /* Link. */
5272 gl.linkProgram(m_po);
5273
5274 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram call failed.");
5275
5276 glw::GLint status = GL_FALSE;
5277
5278 gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
5279
5280 if (GL_TRUE == status)
5281 {
5282 for (glw::GLuint i = 0; i < shader_count; ++i)
5283 {
5284 if (shader[i].id)
5285 {
5286 gl.detachShader(m_po, shader[i].id);
5287
5288 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
5289 }
5290 }
5291 }
5292 else
5293 {
5294 glw::GLint log_size = 0;
5295
5296 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
5297
5298 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
5299
5300 glw::GLchar* log_text = new glw::GLchar[log_size];
5301
5302 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
5303
5304 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
5305 << log_text << "\n"
5306 << tcu::TestLog::EndMessage;
5307
5308 delete[] log_text;
5309
5310 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
5311
5312 throw 0;
5313 }
5314 }
5315 catch (...)
5316 {
5317 if (m_po)
5318 {
5319 gl.deleteProgram(m_po);
5320
5321 m_po = 0;
5322 }
5323 }
5324
5325 for (glw::GLuint i = 0; i < shader_count; ++i)
5326 {
5327 if (0 != shader[i].id)
5328 {
5329 gl.deleteShader(shader[i].id);
5330
5331 shader[i].id = 0;
5332 }
5333 }
5334
5335 if (m_po)
5336 {
5337 gl.useProgram(m_po);
5338 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
5339 }
5340
5341 if (0 == m_po)
5342 {
5343 throw 0;
5344 }
5345 }
5346
5347 /** @brief Prepare empty vertex array object and bind it. */
PrepareVertexArrayObject()5348 void FunctionalTest::PrepareVertexArrayObject()
5349 {
5350 /* Shortcut for GL functionality */
5351 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5352
5353 gl.genVertexArrays(1, &m_vao);
5354 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
5355
5356 gl.bindVertexArray(m_vao);
5357 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
5358 }
5359
5360 /** Prepare input buffer in the way described in test specification (see class comment). */
PrepareInputBuffer()5361 bool FunctionalTest::PrepareInputBuffer()
5362 {
5363 /* Shortcut for GL functionality */
5364 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5365
5366 /* Constants. */
5367 static const glw::GLint zero = 0;
5368 static const glw::GLint one = 1;
5369
5370 /* Buffer preparation */
5371 gl.createBuffers(1, &m_bo_in);
5372
5373 if (GL_NO_ERROR == gl.getError())
5374 {
5375 /* Storage and last (6th) element preparation. */
5376 m_pNamedBufferStorage(m_bo_in, sizeof(s_initial_data_a), s_initial_data_a,
5377 GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT | GL_MAP_PERSISTENT_BIT);
5378
5379 if (GL_NO_ERROR == gl.getError())
5380 {
5381 /* First element preparation. */
5382 m_pClearNamedBufferSubData(m_bo_in, GL_R8, 0, sizeof(glw::GLint), GL_RED, GL_INT, &zero);
5383
5384 if (GL_NO_ERROR == gl.getError())
5385 {
5386 /* Second element preparation. */
5387 m_pNamedBufferSubData(m_bo_in, 1 /* 2nd element */ * sizeof(glw::GLint), sizeof(glw::GLint), &one);
5388
5389 if (GL_NO_ERROR == gl.getError())
5390 {
5391 /* Third element preparation. */
5392 glw::GLint* p = (glw::GLint*)m_pMapNamedBuffer(m_bo_in, GL_WRITE_ONLY);
5393
5394 if ((GL_NO_ERROR == gl.getError()) || (DE_NULL == p))
5395 {
5396 p[2] = 2;
5397
5398 m_pUnmapNamedBuffer(m_bo_in);
5399
5400 if (GL_NO_ERROR == gl.getError())
5401 {
5402 /* Fifth element preparation. */
5403 m_pCopyNamedBufferSubData(m_bo_in, m_bo_in, sizeof(glw::GLint) * 3, sizeof(glw::GLint) * 4,
5404 sizeof(glw::GLint));
5405
5406 if (GL_NO_ERROR == gl.getError())
5407 {
5408 /* Fourth element preparation. */
5409 p = (glw::GLint*)m_pMapNamedBufferRange(
5410 m_bo_in, sizeof(glw::GLint) * 3, sizeof(glw::GLint),
5411 GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
5412
5413 if (GL_NO_ERROR == gl.getError())
5414 {
5415 /* Write to mapped buffer. */
5416 *p = 3;
5417
5418 /* Flush test. */
5419 m_pFlushMappedNamedBufferRange(m_bo_in, 0, sizeof(glw::GLint));
5420
5421 if (GL_NO_ERROR == gl.getError())
5422 {
5423 /* Mapped Buffer Pointer query. */
5424 glw::GLvoid* is_p = DE_NULL;
5425 m_pGetNamedBufferPointerv(m_bo_in, GL_BUFFER_MAP_POINTER, &is_p);
5426
5427 if (GL_NO_ERROR == gl.getError())
5428 {
5429 /* Mapped Buffer pointer query check. */
5430 if (p == is_p)
5431 {
5432 /* Unmapping. */
5433 m_pUnmapNamedBuffer(m_bo_in);
5434
5435 if (GL_NO_ERROR == gl.getError())
5436 {
5437 /* Setup buffer as input for vertex shader. */
5438 m_attrib_location =
5439 gl.getAttribLocation(m_po, s_vertex_shader_input_name);
5440 GLU_EXPECT_NO_ERROR(gl.getError(),
5441 "glGetAttribLocation call failed.");
5442
5443 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_in);
5444 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
5445
5446 gl.vertexAttribIPointer(m_attrib_location, 1, GL_INT, 0, NULL);
5447 GLU_EXPECT_NO_ERROR(gl.getError(),
5448 "glVertexAttribIPointer call failed.");
5449
5450 gl.enableVertexAttribArray(m_attrib_location);
5451 GLU_EXPECT_NO_ERROR(gl.getError(),
5452 "glEnableVertexAttribArray call failed.");
5453
5454 return true;
5455 }
5456 else
5457 {
5458 m_context.getTestContext().getLog()
5459 << tcu::TestLog::Message << "UnmapNamedBuffer has failed."
5460 << tcu::TestLog::EndMessage;
5461 }
5462 }
5463 else
5464 {
5465 m_pUnmapNamedBuffer(m_bo_in);
5466 m_context.getTestContext().getLog()
5467 << tcu::TestLog::Message
5468 << "Pointer returned by GetNamedBufferPointerv is not proper."
5469 << tcu::TestLog::EndMessage;
5470 }
5471 }
5472 else
5473 {
5474 m_pUnmapNamedBuffer(m_bo_in);
5475 m_context.getTestContext().getLog() << tcu::TestLog::Message
5476 << "GetNamedBufferPointerv has failed."
5477 << tcu::TestLog::EndMessage;
5478 }
5479 }
5480 else
5481 {
5482 m_pUnmapNamedBuffer(m_bo_in);
5483 m_context.getTestContext().getLog() << tcu::TestLog::Message
5484 << "FlushMappedNamedBufferRange has failed."
5485 << tcu::TestLog::EndMessage;
5486 }
5487 }
5488 else
5489 {
5490 m_context.getTestContext().getLog() << tcu::TestLog::Message
5491 << "MapNamedBufferRange has failed."
5492 << tcu::TestLog::EndMessage;
5493 }
5494 }
5495 else
5496 {
5497 m_context.getTestContext().getLog() << tcu::TestLog::Message
5498 << "CopyNamedBufferSubData has failed."
5499 << tcu::TestLog::EndMessage;
5500 }
5501 }
5502 else
5503 {
5504 m_context.getTestContext().getLog()
5505 << tcu::TestLog::Message << "UnmapNamedBuffer has failed." << tcu::TestLog::EndMessage;
5506 }
5507 }
5508 else
5509 {
5510 m_context.getTestContext().getLog() << tcu::TestLog::Message << "MapNamedBuffer has failed."
5511 << tcu::TestLog::EndMessage;
5512 }
5513 }
5514 else
5515 {
5516 m_context.getTestContext().getLog() << tcu::TestLog::Message << "NamedBufferSubData has failed."
5517 << tcu::TestLog::EndMessage;
5518 }
5519 }
5520 else
5521 {
5522 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ClearNamedBufferSubData has failed."
5523 << tcu::TestLog::EndMessage;
5524 }
5525 }
5526 else
5527 {
5528 m_context.getTestContext().getLog() << tcu::TestLog::Message << "NamedBufferStorage has failed."
5529 << tcu::TestLog::EndMessage;
5530 }
5531 }
5532 else
5533 {
5534 m_context.getTestContext().getLog() << tcu::TestLog::Message << "CreateBuffers has failed."
5535 << tcu::TestLog::EndMessage;
5536 }
5537
5538 return false;
5539 }
5540
5541 /** Prepare output buffer in the way described in test specification (see class comment). */
PrepareOutputBuffer()5542 bool FunctionalTest::PrepareOutputBuffer()
5543 {
5544 /* Shortcut for GL functionality */
5545 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5546
5547 /* Buffer preparation */
5548 gl.genBuffers(1, &m_bo_out);
5549
5550 if (GL_NO_ERROR == gl.getError())
5551 {
5552 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_out);
5553
5554 if (GL_NO_ERROR == gl.getError())
5555 {
5556 m_pNamedBufferData(m_bo_out, sizeof(s_initial_data_b), s_initial_data_b, GL_DYNAMIC_COPY);
5557
5558 if (GL_NO_ERROR == gl.getError())
5559 {
5560 gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_out, 0,
5561 sizeof(s_initial_data_a) /* intentionally sizeof(a) < sizeof(b) */);
5562
5563 if (GL_NO_ERROR == gl.getError())
5564 {
5565 return true;
5566 }
5567 else
5568 {
5569 m_context.getTestContext().getLog() << tcu::TestLog::Message << "BindBufferRange has failed."
5570 << tcu::TestLog::EndMessage;
5571 throw 0; /* This function is not being tested, throw test internal error */
5572 }
5573 }
5574 else
5575 {
5576 m_context.getTestContext().getLog() << tcu::TestLog::Message << "NamedBufferData has failed."
5577 << tcu::TestLog::EndMessage;
5578 }
5579 }
5580 else
5581 {
5582 m_context.getTestContext().getLog() << tcu::TestLog::Message << "BindBuffer has failed."
5583 << tcu::TestLog::EndMessage;
5584 throw 0; /* This function is not being tested, throw test internal error */
5585 }
5586 }
5587 else
5588 {
5589 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GenBuffers has failed."
5590 << tcu::TestLog::EndMessage;
5591 throw 0; /* This function is not being tested, throw test internal error */
5592 }
5593
5594 return false;
5595 }
5596
5597 /** Draw with the test program and transform feedback. */
Draw()5598 void FunctionalTest::Draw()
5599 {
5600 /* Shortcut for GL functionality */
5601 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5602
5603 /* Draw using transform feedback. */
5604 gl.disable(GL_RASTERIZER_DISCARD);
5605 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
5606
5607 gl.beginTransformFeedback(GL_POINTS);
5608 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
5609
5610 gl.drawArrays(GL_POINTS, 0, sizeof(s_initial_data_a) / sizeof(s_initial_data_a[0]));
5611 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
5612
5613 gl.endTransformFeedback();
5614 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
5615
5616 gl.enable(GL_RASTERIZER_DISCARD);
5617 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
5618 }
5619
5620 /** @brief Check that input buffer is immutable using GetNamedBufferParameteriv function. */
CheckArrayBufferImmutableFlag()5621 bool FunctionalTest::CheckArrayBufferImmutableFlag()
5622 {
5623 /* Shortcut for GL functionality. */
5624 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5625
5626 /* Local query storage. */
5627 glw::GLint is_storage_immutable = -1;
5628
5629 /* Querry. */
5630 m_pGetNamedBufferParameteriv(m_bo_in, GL_BUFFER_IMMUTABLE_STORAGE, &is_storage_immutable);
5631
5632 /* Error checking. */
5633 if (GL_NO_ERROR == gl.getError())
5634 {
5635 /* Return value checking. */
5636 if (-1 != is_storage_immutable)
5637 {
5638 /* Test. */
5639 if (GL_TRUE == is_storage_immutable)
5640 {
5641 return true;
5642 }
5643 else
5644 {
5645 m_context.getTestContext().getLog() << tcu::TestLog::Message
5646 << "Input buffer storage is unexpectedly mutable."
5647 << tcu::TestLog::EndMessage;
5648 }
5649 }
5650 else
5651 {
5652 m_context.getTestContext().getLog() << tcu::TestLog::Message
5653 << "GetNamedBufferParameteriv has not returned a data."
5654 << tcu::TestLog::EndMessage;
5655 }
5656 }
5657 else
5658 {
5659 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetNamedBufferParameteriv has failed."
5660 << tcu::TestLog::EndMessage;
5661 }
5662
5663 return false;
5664 }
5665
5666 /** @brief Check that output buffer size using GetNamedBufferParameteri64v function. */
CheckTransformFeedbackBufferSize()5667 bool FunctionalTest::CheckTransformFeedbackBufferSize()
5668 {
5669 /* Shortcut for GL functionality. */
5670 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5671
5672 /* Local query storage. */
5673 glw::GLint64 size = -1;
5674
5675 /* Querry. */
5676 m_pGetNamedBufferParameteri64v(m_bo_out, GL_BUFFER_SIZE, &size);
5677
5678 /* Error checking. */
5679 if (GL_NO_ERROR == gl.getError())
5680 {
5681 /* Return value checking. */
5682 if (-1 != size)
5683 {
5684 /* Test. */
5685 if (sizeof(s_initial_data_b) == size)
5686 {
5687 return true;
5688 }
5689 else
5690 {
5691 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Output buffer size is " << size
5692 << ", but " << sizeof(s_initial_data_b) << " was expected."
5693 << tcu::TestLog::EndMessage;
5694 }
5695 }
5696 else
5697 {
5698 m_context.getTestContext().getLog() << tcu::TestLog::Message
5699 << "GetNamedBufferParameteri64v has not returned a data."
5700 << tcu::TestLog::EndMessage;
5701 }
5702 }
5703 else
5704 {
5705 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetNamedBufferParameteri64v has failed."
5706 << tcu::TestLog::EndMessage;
5707 }
5708
5709 return false;
5710 }
5711
5712 /** @brief Check that results of the test are equal to the expected reference values. */
CheckTransformFeedbackResult()5713 bool FunctionalTest::CheckTransformFeedbackResult()
5714 {
5715 /* Shortcut for GL functionality. */
5716 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5717
5718 /* Local data storage. */
5719 glw::GLint output_data[sizeof(s_initial_data_b) / sizeof(s_initial_data_b[0])] = {};
5720
5721 /* Fetch data. */
5722 m_pGetNamedBufferSubData(m_bo_out, 0, sizeof(output_data), output_data);
5723
5724 /* Error checking. */
5725 if (GL_NO_ERROR == gl.getError())
5726 {
5727 for (glw::GLuint i = 0; i < sizeof(s_initial_data_b) / sizeof(s_initial_data_b[0]); ++i)
5728 {
5729 if (s_expected_data[i] != output_data[i])
5730 {
5731 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Expected data is not equal to results."
5732 << tcu::TestLog::EndMessage;
5733 return false;
5734 }
5735 }
5736
5737 return true;
5738 }
5739 else
5740 {
5741 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetNamedBufferSubData has failed."
5742 << tcu::TestLog::EndMessage;
5743 }
5744 return false;
5745 }
5746
5747 /** Clean all test's GL objects and state. */
Cleanup()5748 void FunctionalTest::Cleanup()
5749 {
5750 /* Shortcut for GL functionality. */
5751 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5752
5753 /* Cleanup objects. */
5754 if (m_po)
5755 {
5756 gl.useProgram(0);
5757
5758 gl.deleteProgram(m_po);
5759
5760 m_po = 0;
5761 }
5762
5763 if (m_vao)
5764 {
5765 gl.deleteVertexArrays(1, &m_vao);
5766
5767 m_vao = 0;
5768 }
5769
5770 if (0 <= m_attrib_location)
5771 {
5772 gl.disableVertexAttribArray(m_attrib_location);
5773
5774 m_attrib_location = -1;
5775 }
5776
5777 if (m_bo_in)
5778 {
5779 gl.deleteBuffers(1, &m_bo_in);
5780
5781 m_bo_in = 0;
5782 }
5783
5784 if (m_bo_out)
5785 {
5786 gl.deleteBuffers(1, &m_bo_out);
5787
5788 m_bo_out = 0;
5789 }
5790
5791 /* Make sure that rasterizer is turned on (default). */
5792 gl.enable(GL_RASTERIZER_DISCARD);
5793
5794 /* Clean all errors. */
5795 while (gl.getError())
5796 ;
5797 }
5798
5799 } /* Buffers namespace. */
5800 } /* DirectStateAccess namespace. */
5801 } /* gl4cts namespace. */
5802