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