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(DE_NULL)
198 , m_pNamedBufferSubData(DE_NULL)
199 , m_pNamedBufferStorage(DE_NULL)
200 , m_pCopyNamedBufferSubData(DE_NULL)
201 {
202 /* Intentionally left blank. */
203 }
204
205 /** @brief Iterate Data Test cases.
206 *
207 * @return Iteration result.
208 */
iterate()209 tcu::TestNode::IterateResult DataTest::iterate()
210 {
211 /* Shortcut for GL functionality. */
212 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
213
214 /* Get context setup. */
215 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
216 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
217
218 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
219 {
220 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
221
222 return STOP;
223 }
224
225 /* Running tests. */
226 bool is_ok = true;
227 bool is_error = false;
228
229 m_pNamedBufferData = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
230 m_pNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATA)gl.namedBufferSubData;
231 m_pNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGE)gl.namedBufferStorage;
232 m_pCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATA)gl.copyNamedBufferSubData;
233
234 try
235 {
236 if ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pNamedBufferSubData) ||
237 (DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pCopyNamedBufferSubData))
238 {
239 throw 0;
240 }
241
242 /* BufferData tests */
243 static const glw::GLenum hints[] = {GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY,
244 GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY,
245 GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, GL_DYNAMIC_COPY};
246 static const glw::GLuint hints_count = sizeof(hints) / sizeof(hints[0]);
247
248 for (glw::GLuint i = 0; i < hints_count; ++i)
249 {
250 is_ok &= TestCase(&DataTest::UploadUsingNamedBufferData, hints[i]);
251 is_ok &= TestCase(&DataTest::UploadUsingNamedBufferSubData, hints[i]);
252 is_ok &= TestCase(&DataTest::UploadUsingCopyNamedBufferSubData, hints[i]);
253 }
254
255 /* BufferStorage Tests */
256 static const glw::GLenum bits[] = {GL_MAP_READ_BIT | GL_DYNAMIC_STORAGE_BIT, 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, DE_NULL, parameter);
402 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");
403
404 m_pNamedBufferSubData(id, 0, s_reference_size, s_reference);
405 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferSubData failed.");
406 }
407
408 /** @brief NamedBufferStorage data upload function.
409 *
410 * @param [in] id Buffer id to be uploaded.
411 * @param [in] parameter Storage Parameter to be used with the function, one of:
412 * - GL_MAP_READ_BIT | GL_DYNAMIC_STORAGE_BIT,
413 * - GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
414 * - GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT,
415 * - GL_MAP_READ_BIT | GL_MAP_COHERENT_BIT,
416 * - GL_MAP_READ_BIT | GL_CLIENT_STORAGE_BIT
417 */
UploadUsingNamedBufferStorage(glw::GLuint id,glw::GLenum parameter)418 void DataTest::UploadUsingNamedBufferStorage(glw::GLuint id, glw::GLenum parameter)
419 {
420 /* Shortcut for GL functionality. */
421 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
422
423 m_pNamedBufferStorage(id, s_reference_size, s_reference, parameter);
424 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferStorage failed.");
425 }
426
427 /** @brief CopyNamedBufferSubData data upload function (uses auxiliary buffer object).
428 *
429 * @param [in] id Buffer id to be uploaded.
430 * @param [in] parameter Storage parameter to be used with the NamedBufferData for
431 * the auxiliary buffer object storage allocation
432 * (before call to CopyNamedBufferSubData), one of:
433 * - GL_STREAM_DRAW,
434 * - GL_STREAM_READ,
435 * - GL_STREAM_COPY,
436 * - GL_STATIC_DRAW,
437 * - GL_STATIC_READ,
438 * - GL_STATIC_COPY,
439 * - GL_DYNAMIC_DRAW,
440 * - GL_DYNAMIC_READ and
441 * - GL_DYNAMIC_COPY.
442 */
UploadUsingCopyNamedBufferSubData(glw::GLuint id,glw::GLenum parameter)443 void DataTest::UploadUsingCopyNamedBufferSubData(glw::GLuint id, glw::GLenum parameter)
444 {
445 /* Shortcut for GL functionality. */
446 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
447
448 m_pNamedBufferData(id, s_reference_size, DE_NULL, parameter);
449 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");
450
451 glw::GLuint auxiliary_buffer = 0;
452 bool auxiliary_buffer_is_ok = true;
453
454 try
455 {
456 gl.genBuffers(1, &auxiliary_buffer);
457 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers failed.");
458
459 gl.bindBuffer(GL_ARRAY_BUFFER, auxiliary_buffer);
460 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer failed.");
461
462 gl.bufferData(GL_ARRAY_BUFFER, s_reference_size, s_reference, parameter);
463 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData failed.");
464
465 m_pCopyNamedBufferSubData(auxiliary_buffer, id, 0, 0, s_reference_size);
466 GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyNamedBufferSubData failed.");
467 }
468 catch (...)
469 {
470 auxiliary_buffer_is_ok = false;
471 }
472
473 if (auxiliary_buffer)
474 {
475 gl.deleteBuffers(1, &auxiliary_buffer);
476 }
477
478 if (!auxiliary_buffer_is_ok)
479 {
480 throw 0;
481 }
482 }
483
484 /** @brief Compare two unsigned integer arrays.
485 *
486 * @param [in] data Data to be compared.
487 * @param [in] reference Reference data to be compared to.
488 * @param [in] count Number of elements to be compared.
489 *
490 * @return True if count of data the elements are equal to reference counterparts, false otherwise.
491 */
compare(const glw::GLuint * data,const glw::GLuint * reference,const glw::GLsizei count)492 bool DataTest::compare(const glw::GLuint *data, const glw::GLuint *reference, const glw::GLsizei count)
493 {
494 for (glw::GLsizei i = 0; i < count; ++i)
495 {
496 if (data[i] != reference[i])
497 {
498 return false;
499 }
500 }
501 return true;
502 }
503
504 /** @brief Prepare error message and log it.
505 *
506 * @param [in] UploadDataFunction Upload function pointer which have failed, one of:
507 * - DataTest::UploadUsingNamedBufferData,
508 * - DataTest::UploadUsingNamedBufferSubData
509 * - DataTest::UploadUsingNamedBufferStorage and
510 * - DataTest::UploadUsingCopyNamedBufferSubData.
511 * @param [in] parameter Parameter which was passed to function.
512 * @param [in] data Data which was downloaded.
513 * @param [in] reference Reference data.
514 * @param [in] count Number of elements compared.
515 */
LogFail(void (DataTest::* UploadDataFunction)(glw::GLuint,glw::GLenum),glw::GLenum parameter,const glw::GLuint * data,const glw::GLuint * reference,const glw::GLsizei count)516 void DataTest::LogFail(void (DataTest::*UploadDataFunction)(glw::GLuint, glw::GLenum), glw::GLenum parameter,
517 const glw::GLuint *data, const glw::GLuint *reference, const glw::GLsizei count)
518 {
519 std::string the_log = "The test of ";
520
521 if (UploadDataFunction == &DataTest::UploadUsingNamedBufferData)
522 {
523 the_log.append("glNamedBufferData");
524 }
525 else
526 {
527 if (UploadDataFunction == &DataTest::UploadUsingNamedBufferSubData)
528 {
529 the_log.append("glNamedBufferSubData");
530 }
531 else
532 {
533 if (UploadDataFunction == &DataTest::UploadUsingNamedBufferStorage)
534 {
535 the_log.append("glNamedBufferStorage");
536 }
537 else
538 {
539 if (UploadDataFunction == &DataTest::UploadUsingCopyNamedBufferSubData)
540 {
541 the_log.append("glCopyNamedBufferSubData");
542 }
543 else
544 {
545 the_log.append("uknown upload function");
546 }
547 }
548 }
549 }
550
551 if (UploadDataFunction == &DataTest::UploadUsingNamedBufferStorage)
552 {
553 the_log.append(" called with usage parameter ");
554
555 std::stringstream bitfield_string_stream;
556 bitfield_string_stream << glu::getBufferMapFlagsStr(parameter);
557 the_log.append(bitfield_string_stream.str());
558 }
559 else
560 {
561 the_log.append(" called with usage parameter ");
562 the_log.append(glu::getUsageName(parameter));
563 }
564 the_log.append(". Buffer data is equal to [");
565
566 for (glw::GLsizei i = 0; i < count; ++i)
567 {
568 std::stringstream number;
569
570 number << data[i];
571
572 the_log.append(number.str());
573
574 if (i != count - 1)
575 {
576 the_log.append(", ");
577 }
578 }
579
580 the_log.append("], but [");
581
582 for (glw::GLsizei i = 0; i < count; ++i)
583 {
584 std::stringstream number;
585
586 number << reference[i];
587
588 the_log.append(number.str());
589
590 if (i != count - 1)
591 {
592 the_log.append(", ");
593 }
594 }
595
596 the_log.append("] was expected.");
597
598 m_context.getTestContext().getLog() << tcu::TestLog::Message << the_log << tcu::TestLog::EndMessage;
599 }
600
LogError(void (DataTest::* UploadDataFunction)(glw::GLuint,glw::GLenum),glw::GLenum parameter)601 void DataTest::LogError(void (DataTest::*UploadDataFunction)(glw::GLuint, glw::GLenum), glw::GLenum parameter)
602 {
603 std::string the_log = "Unexpected error occurred during the test of ";
604
605 if (UploadDataFunction == &DataTest::UploadUsingNamedBufferData)
606 {
607 the_log.append("glNamedBufferData");
608 }
609 else
610 {
611 if (UploadDataFunction == &DataTest::UploadUsingNamedBufferSubData)
612 {
613 the_log.append("glNamedBufferSubData");
614 }
615 else
616 {
617 if (UploadDataFunction == &DataTest::UploadUsingNamedBufferStorage)
618 {
619 the_log.append("glNamedBufferStorage");
620 }
621 else
622 {
623 if (UploadDataFunction == &DataTest::UploadUsingCopyNamedBufferSubData)
624 {
625 the_log.append("glCopyNamedBufferSubData");
626 }
627 else
628 {
629 the_log.append("uknown upload function");
630 }
631 }
632 }
633 }
634
635 if (UploadDataFunction == &DataTest::UploadUsingNamedBufferStorage)
636 {
637 the_log.append(" called with usage parameter ");
638
639 std::stringstream bitfield_string_stream;
640 bitfield_string_stream << glu::getBufferMapFlagsStr(parameter);
641 the_log.append(bitfield_string_stream.str());
642 }
643 else
644 {
645 the_log.append(" called with usage parameter ");
646 the_log.append(glu::getUsageName(parameter));
647 }
648 the_log.append(".");
649
650 m_context.getTestContext().getLog() << tcu::TestLog::Message << the_log << tcu::TestLog::EndMessage;
651 }
652
653 const glw::GLuint DataTest::s_reference[] = {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(DE_NULL)
668 , m_pClearNamedBufferData(DE_NULL)
669 , m_pClearNamedBufferSubData(DE_NULL)
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 ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pClearNamedBufferData) ||
951 (DE_NULL == 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(DE_NULL)
1155 , m_pMapNamedBuffer(DE_NULL)
1156 , m_pUnmapNamedBuffer(DE_NULL)
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 ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pMapNamedBuffer) || (DE_NULL == 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 (DE_NULL == 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(DE_NULL)
1299 , m_pMapNamedBuffer(DE_NULL)
1300 , m_pUnmapNamedBuffer(DE_NULL)
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 ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pMapNamedBuffer) || (DE_NULL == 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 (DE_NULL == 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 = DE_NULL;
1398
1399 data = (glw::GLuint *)m_pMapNamedBuffer(buffer, GL_READ_WRITE);
1400 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
1401
1402 if (DE_NULL == 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(DE_NULL)
1486 , m_pMapNamedBuffer(DE_NULL)
1487 , m_pUnmapNamedBuffer(DE_NULL)
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 ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pMapNamedBuffer) || (DE_NULL == 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 (DE_NULL == 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 = DE_NULL;
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(DE_NULL)
1650 , m_pMapNamedBufferRange(DE_NULL)
1651 , m_pUnmapNamedBuffer(DE_NULL)
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 ((DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pMapNamedBufferRange) ||
1689 (DE_NULL == 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 (DE_NULL == 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(DE_NULL)
1842 , m_pMapNamedBufferRange(DE_NULL)
1843 , m_pUnmapNamedBuffer(DE_NULL)
1844 , m_pFlushMappedNamedBufferRange(DE_NULL)
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 ((DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pMapNamedBufferRange) ||
1883 (DE_NULL == m_pUnmapNamedBuffer) || (DE_NULL == 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, DE_NULL, 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 (DE_NULL != 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(DE_NULL)
2108 , m_pGetNamedBufferSubData(DE_NULL)
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 ((DE_NULL == m_pNamedBufferData) || (DE_NULL == 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(DE_NULL)
2227 , m_pGetNamedBufferParameteri64v(DE_NULL)
2228 , m_pGetNamedBufferParameteriv(DE_NULL)
2229 , m_pGetNamedBufferPointerv(DE_NULL)
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 ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pGetNamedBufferParameteri64v) ||
2293 (DE_NULL == m_pGetNamedBufferParameteriv) || (DE_NULL == 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, (glw::GLvoid *)DE_NULL, "GL_BUFFER_MAP_POINTER",
2355 "glGetNamedBufferParameteriv");
2356 }
2357 }
2358 catch (...)
2359 {
2360 is_ok = false;
2361 is_error = true;
2362 }
2363
2364 /* Clean up. */
2365 if (buffer)
2366 {
2367 gl.deleteBuffers(1, &buffer);
2368
2369 buffer = 0;
2370 }
2371
2372 /* Errors clean up. */
2373 while (gl.getError())
2374 ;
2375
2376 /* Result's setup. */
2377 if (is_ok)
2378 {
2379 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2380 }
2381 else
2382 {
2383 if (is_error)
2384 {
2385 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
2386 }
2387 else
2388 {
2389 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2390 }
2391 }
2392
2393 return STOP;
2394 }
2395
2396 /** @brief Check for GL error and log.
2397 *
2398 * @param [in] pname_string String of parameter name of the value (for logging).
2399 * @param [in] function_string String of function which returned the value (for logging).
2400 *
2401 * @return True if error was generated, false otherwise. False solution is logged.
2402 */
CheckParameterError(const glw::GLchar * pname_string,const glw::GLchar * function_string)2403 bool DefaultsTest::CheckParameterError(const glw::GLchar *pname_string, const glw::GLchar *function_string)
2404 {
2405 /* Shortcut for GL functionality. */
2406 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2407
2408 /* Error check. */
2409 if (glw::GLenum error = gl.getError())
2410 {
2411 /* Log. */
2412 m_context.getTestContext().getLog() << tcu::TestLog::Message << function_string << " called with "
2413 << pname_string << " parameter name unexpectedly returned "
2414 << glu::getErrorStr(error) << "error." << tcu::TestLog::EndMessage;
2415
2416 return false;
2417 }
2418
2419 return true;
2420 }
2421
2422 /******************************** Errors Test Implementation ********************************/
2423
2424 /** @brief Errors Query Test constructor.
2425 *
2426 * @param [in] context OpenGL context.
2427 */
ErrorsTest(deqp::Context & context)2428 ErrorsTest::ErrorsTest(deqp::Context &context)
2429 : deqp::TestCase(context, "buffers_errors", "Buffer Objects Errors Test")
2430 , m_pClearNamedBufferData(DE_NULL)
2431 , m_pClearNamedBufferSubData(DE_NULL)
2432 , m_pCopyNamedBufferSubData(DE_NULL)
2433 , m_pFlushMappedNamedBufferRange(DE_NULL)
2434 , m_pGetNamedBufferParameteri64v(DE_NULL)
2435 , m_pGetNamedBufferParameteriv(DE_NULL)
2436 , m_pGetNamedBufferPointerv(DE_NULL)
2437 , m_pGetNamedBufferSubData(DE_NULL)
2438 , m_pMapNamedBuffer(DE_NULL)
2439 , m_pMapNamedBufferRange(DE_NULL)
2440 , m_pNamedBufferData(DE_NULL)
2441 , m_pNamedBufferStorage(DE_NULL)
2442 , m_pNamedBufferSubData(DE_NULL)
2443 , m_pUnmapNamedBuffer(DE_NULL)
2444 {
2445 /* Intentionally left blank. */
2446 }
2447
2448 /** @brief Iterate Errors Test cases.
2449 *
2450 * @return Iteration result.
2451 */
iterate()2452 tcu::TestNode::IterateResult ErrorsTest::iterate()
2453 {
2454 /* Shortcut for GL functionality. */
2455 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2456
2457 /* Get context setup. */
2458 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
2459 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
2460
2461 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
2462 {
2463 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
2464
2465 return STOP;
2466 }
2467
2468 /* Running tests. */
2469 bool is_ok = true;
2470 bool is_error = false;
2471
2472 /* API function pointers setup. */
2473 m_pClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATA)gl.clearNamedBufferData;
2474 m_pClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATA)gl.clearNamedBufferSubData;
2475 m_pCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATA)gl.copyNamedBufferSubData;
2476 m_pFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGE)gl.flushMappedNamedBufferRange;
2477 m_pGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64V)gl.getNamedBufferParameteri64v;
2478 m_pGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIV)gl.getNamedBufferParameteriv;
2479 m_pGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERV)gl.getNamedBufferPointerv;
2480 m_pGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATA)gl.getNamedBufferSubData;
2481 m_pMapNamedBuffer = (PFNGLMAPNAMEDBUFFER)gl.mapNamedBuffer;
2482 m_pMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGE)gl.mapNamedBufferRange;
2483 m_pNamedBufferData = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
2484 m_pNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGE)gl.namedBufferStorage;
2485 m_pNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATA)gl.namedBufferSubData;
2486 m_pUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;
2487
2488 try
2489 {
2490 /* API function pointers check. */
2491 if ((DE_NULL == m_pClearNamedBufferData) || (DE_NULL == m_pClearNamedBufferSubData) ||
2492 (DE_NULL == m_pCopyNamedBufferSubData) || (DE_NULL == m_pFlushMappedNamedBufferRange) ||
2493 (DE_NULL == m_pGetNamedBufferParameteri64v) || (DE_NULL == m_pGetNamedBufferParameteriv) ||
2494 (DE_NULL == m_pGetNamedBufferPointerv) || (DE_NULL == m_pGetNamedBufferSubData) ||
2495 (DE_NULL == m_pMapNamedBuffer) || (DE_NULL == m_pMapNamedBufferRange) || (DE_NULL == m_pNamedBufferData) ||
2496 (DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pNamedBufferSubData) ||
2497 (DE_NULL == m_pUnmapNamedBuffer))
2498 {
2499 throw 0;
2500 }
2501
2502 /* Running test cases. Cleaning errors. */
2503 is_ok &= TestErrorsOfClearNamedBufferData();
2504 while (gl.getError())
2505 ;
2506 is_ok &= TestErrorsOfClearNamedBufferSubData();
2507 while (gl.getError())
2508 ;
2509 is_ok &= TestErrorsOfCopyNamedBufferSubData();
2510 while (gl.getError())
2511 ;
2512 is_ok &= TestErrorsOfCreateBuffers();
2513 while (gl.getError())
2514 ;
2515 is_ok &= TestErrorsOfFlushMappedNamedBufferRange();
2516 while (gl.getError())
2517 ;
2518 is_ok &= TestErrorsOfGetNamedBufferParameter();
2519 while (gl.getError())
2520 ;
2521 is_ok &= TestErrorsOfGetNamedBufferPointerv();
2522 while (gl.getError())
2523 ;
2524 is_ok &= TestErrorsOfGetNamedBufferSubData();
2525 while (gl.getError())
2526 ;
2527 is_ok &= TestErrorsOfMapNamedBuffer();
2528 while (gl.getError())
2529 ;
2530 is_ok &= TestErrorsOfMapNamedBufferRange();
2531 while (gl.getError())
2532 ;
2533 is_ok &= TestErrorsOfNamedBufferData();
2534 while (gl.getError())
2535 ;
2536 is_ok &= TestErrorsOfNamedBufferStorage();
2537 while (gl.getError())
2538 ;
2539 is_ok &= TestErrorsOfNamedBufferSubData();
2540 while (gl.getError())
2541 ;
2542 is_ok &= TestErrorsOfUnmapNamedBuffer();
2543 while (gl.getError())
2544 ;
2545 }
2546 catch (...)
2547 {
2548 is_ok = false;
2549 is_error = true;
2550 }
2551
2552 /* Errors clean up. */
2553 while (gl.getError())
2554 ;
2555
2556 /* Result's setup. */
2557 if (is_ok)
2558 {
2559 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2560 }
2561 else
2562 {
2563 if (is_error)
2564 {
2565 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
2566 }
2567 else
2568 {
2569 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2570 }
2571 }
2572
2573 return STOP;
2574 }
2575
2576 /** Check if error was generated and if it is equal to expected value. Log possible failure.
2577 *
2578 * @param [in] function_name Tested Function.
2579 * @param [in] expected_error Expected error function.
2580 * @param [in] when_shall_be_generated Description when shall the error occure.
2581 *
2582 * @return True if GL error is equal to the expected value, false otherwise.
2583 */
ErrorCheckAndLog(const glw::GLchar * function_name,const glw::GLenum expected_error,const glw::GLchar * when_shall_be_generated)2584 bool ErrorsTest::ErrorCheckAndLog(const glw::GLchar *function_name, const glw::GLenum expected_error,
2585 const glw::GLchar *when_shall_be_generated)
2586 {
2587 /* Shortcut for GL functionality. */
2588 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2589
2590 /* Error value storage. */
2591 glw::GLenum error = GL_NO_ERROR;
2592
2593 /* Error comparision. */
2594 if (expected_error != (error = gl.getError()))
2595 {
2596 /* Log. */
2597 m_context.getTestContext().getLog()
2598 << tcu::TestLog::Message << function_name << " does not generate " << glu::getErrorStr(expected_error)
2599 << when_shall_be_generated << "The error value of " << glu::getErrorStr(error) << " was observed."
2600 << tcu::TestLog::EndMessage;
2601
2602 /* Error cleanup. */
2603 while (gl.getError())
2604 ;
2605
2606 /* Check failed. */
2607 return false;
2608 }
2609
2610 /* Error was equal to expected. */
2611 return true;
2612 }
2613
2614 /** @brief Test Errors Of ClearNamedBufferData function.
2615 *
2616 * Check that INVALID_OPERATION is generated by ClearNamedBufferData if
2617 * buffer is not the name of an existing buffer object.
2618 *
2619 * Check that INVALID_ENUM is generated by ClearNamedBufferData if
2620 * internal format is not one of the valid sized internal formats listed in
2621 * the table above.
2622 *
2623 * Check that INVALID_OPERATION is generated by ClearNamedBufferData if
2624 * any part of the specified range of the buffer object is mapped with
2625 * MapBufferRange or MapBuffer, unless it was mapped with the
2626 * MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.
2627 *
2628 * Check that INVALID_VALUE is generated by ClearNamedBufferData if
2629 * format is not a valid format, or type is not a valid type.
2630 *
2631 * True if test case succeeded, false otherwise.
2632 */
TestErrorsOfClearNamedBufferData()2633 bool ErrorsTest::TestErrorsOfClearNamedBufferData()
2634 {
2635 /* Shortcut for GL functionality. */
2636 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2637
2638 /* Return value. */
2639 bool is_ok = true;
2640 bool internal_error = false;
2641
2642 /* Common variables. */
2643 glw::GLuint buffer = 0;
2644 glw::GLbyte unused_data = 0;
2645
2646 try
2647 {
2648 /* Common preparations. */
2649 gl.createBuffers(1, &buffer);
2650 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
2651
2652 m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data,
2653 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
2654 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferStorage failed.");
2655
2656 /* Test invalid buffer name error behavior. */
2657 {
2658 /* Prepare for invalid buffer name error behavior verification. */
2659 glw::GLuint not_a_buffer_name = 0;
2660
2661 while (gl.isBuffer(++not_a_buffer_name))
2662 ;
2663
2664 /* Test. */
2665 m_pClearNamedBufferData(not_a_buffer_name, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &unused_data);
2666
2667 is_ok &= ErrorCheckAndLog("glClearNamedBufferData", GL_INVALID_OPERATION,
2668 " if buffer is not the name of an existing buffer object.");
2669 }
2670
2671 /* Test invalid sized internal format error behavior. */
2672 {
2673 /* Prepare for invalid sized internal format error behavior verification. */
2674 static const glw::GLenum valid_internal_formats[] = {
2675 GL_R8, GL_R16, GL_R16F, GL_R32F, GL_R8I, GL_R16I, GL_R32I,
2676 GL_R8UI, GL_R16UI, GL_R32UI, GL_RG8, GL_RG16, GL_RG16F, GL_RG32F,
2677 GL_RG8I, GL_RG16I, GL_RG32I, GL_RG8UI, GL_RG16UI, GL_RG32UI, GL_RGB32F,
2678 GL_RGB32I, GL_RGB32UI, GL_RGBA8, GL_RGBA16, GL_RGBA16F, GL_RGBA32F, GL_RGBA8I,
2679 GL_RGBA16I, GL_RGBA32I, GL_RGBA8UI, GL_RGBA16UI, GL_RGBA32UI, GL_NONE};
2680 static const glw::GLenum valid_internal_formats_last =
2681 sizeof(valid_internal_formats) / sizeof(valid_internal_formats[0]) - 1;
2682
2683 glw::GLenum invalid_internal_format = 0;
2684
2685 while (&valid_internal_formats[valid_internal_formats_last] !=
2686 std::find(&valid_internal_formats[0], &valid_internal_formats[valid_internal_formats_last],
2687 (++invalid_internal_format)))
2688 ;
2689
2690 /* Test. */
2691 m_pClearNamedBufferData(buffer, invalid_internal_format, GL_RED, GL_UNSIGNED_BYTE, &unused_data);
2692
2693 is_ok &= ErrorCheckAndLog("glClearNamedBufferData", GL_INVALID_ENUM,
2694 " if internal format is not one of the valid sized internal formats "
2695 "(GL_R8, GL_R16, GL_R16F, GL_R32F, GL_R8I, GL_R16I, GL_R32I, GL_R8UI,"
2696 " GL_R16UI, GL_R32UI, GL_RG8, GL_RG16, GL_RG16F, GL_RG32F, GL_RG8I, GL_RG16I,"
2697 " GL_RG32I, GL_RG8UI, GL_RG16UI, GL_RG32UI, GL_RGB32F, GL_RGB32I, GL_RGB32UI,"
2698 " GL_RGBA8, GL_RGBA16, GL_RGBA16F, GL_RGBA32F, GL_RGBA8I, GL_RGBA16I, GL_RGBA32I,"
2699 " GL_RGBA8UI, GL_RGBA16UI, GL_RGBA32UI).");
2700 }
2701
2702 /* Test of mapped buffer clear error behavior verification (glMapNamedBuffer version). */
2703 {
2704 (void)(glw::GLbyte *)m_pMapNamedBuffer(buffer, GL_READ_ONLY);
2705 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
2706
2707 m_pClearNamedBufferData(buffer, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &unused_data);
2708
2709 is_ok &= ErrorCheckAndLog("glClearNamedBufferData", GL_INVALID_OPERATION,
2710 " if any part of the specified range of the buffer"
2711 " object is mapped with MapBuffer, unless it was mapped with "
2712 "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");
2713
2714 m_pUnmapNamedBuffer(buffer);
2715 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
2716 }
2717
2718 /* Test of mapped buffer clear error behavior verification (glMapNamedBufferRange version). */
2719 {
2720 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_READ_BIT);
2721 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
2722
2723 m_pClearNamedBufferData(buffer, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &unused_data);
2724
2725 is_ok &= ErrorCheckAndLog("glClearNamedBufferData", GL_INVALID_OPERATION,
2726 " if any part of the specified range of the buffer"
2727 " object is mapped with MapBufferRange, unless it was mapped with "
2728 "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");
2729
2730 m_pUnmapNamedBuffer(buffer);
2731 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
2732 }
2733
2734 /* Test of persistently mapped buffer clear error with behavior verification (glMapNamedBufferRange version). */
2735 {
2736 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data),
2737 GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
2738 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
2739
2740 m_pClearNamedBufferData(buffer, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &unused_data);
2741
2742 is_ok &= ErrorCheckAndLog("glClearNamedBufferData", GL_NO_ERROR,
2743 " if any part of the specified range of the buffer"
2744 " object is mapped with MapBuffer with the MAP_PERSISTENT_BIT"
2745 " bit set in the MapBufferRange access flags.");
2746
2747 m_pUnmapNamedBuffer(buffer);
2748 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
2749 }
2750
2751 /* Test invalid format error behavior. */
2752 {
2753 /* Prepare for invalid format error behavior verification. */
2754 static const glw::GLenum valid_formats[] = {GL_RED, GL_RG,
2755 GL_RGB, GL_BGR,
2756 GL_RGBA, GL_BGRA,
2757 GL_RED_INTEGER, GL_RG_INTEGER,
2758 GL_RGB_INTEGER, GL_BGR_INTEGER,
2759 GL_RGBA_INTEGER, GL_BGRA_INTEGER,
2760 GL_STENCIL_INDEX, GL_DEPTH_COMPONENT,
2761 GL_DEPTH_STENCIL};
2762 static const glw::GLenum valid_formats_last = sizeof(valid_formats) / sizeof(valid_formats[0]) - 1;
2763
2764 glw::GLenum invalid_format = 0;
2765
2766 while (&valid_formats[valid_formats_last] !=
2767 std::find(&valid_formats[0], &valid_formats[valid_formats_last], (++invalid_format)))
2768 ;
2769
2770 /* Test. */
2771 m_pClearNamedBufferData(buffer, GL_R8, invalid_format, GL_UNSIGNED_BYTE, &unused_data);
2772
2773 is_ok &= ErrorCheckAndLog(
2774 "glClearNamedBufferData", GL_INVALID_VALUE,
2775 " if format is not a valid format "
2776 "(one of GL_RED, GL_RG, GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, "
2777 "GL_RED_INTEGER, GL_RG_INTEGER, GL_RGB_INTEGER, GL_BGR_INTEGER, GL_RGBA_INTEGER, GL_BGRA_INTEGER, "
2778 "GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL).");
2779 }
2780
2781 /* Test invalid type error behavior. */
2782 {
2783 /* Prepare for invalid type error behavior verification. */
2784 static const glw::GLenum valid_types[] = {GL_RED, GL_RG,
2785 GL_RGB, GL_BGR,
2786 GL_RGBA, GL_BGRA,
2787 GL_RED_INTEGER, GL_RG_INTEGER,
2788 GL_RGB_INTEGER, GL_BGR_INTEGER,
2789 GL_RGBA_INTEGER, GL_BGRA_INTEGER,
2790 GL_STENCIL_INDEX, GL_DEPTH_COMPONENT,
2791 GL_DEPTH_STENCIL};
2792 static const glw::GLenum valid_types_last = sizeof(valid_types) / sizeof(valid_types[0]) - 1;
2793
2794 glw::GLenum invalid_type = 0;
2795
2796 while (&valid_types[valid_types_last] !=
2797 std::find(&valid_types[0], &valid_types[valid_types_last], (++invalid_type)))
2798 ;
2799
2800 /* Test. */
2801 m_pClearNamedBufferData(buffer, GL_R8, GL_RED, invalid_type, &unused_data);
2802
2803 is_ok &= ErrorCheckAndLog(
2804 "glClearNamedBufferData", GL_INVALID_VALUE,
2805 " if format is not a valid type "
2806 "(one of GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, "
2807 "GL_SHORT, GL_UNSIGNED_INT, GL_INT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, "
2808 "GL_UNSIGNED_BYTE_2_3_3_REV, GL_UNSIGNED_SHORT_5_6_5, "
2809 "GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, "
2810 "GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_UNSIGNED_INT_8_8_8_8, "
2811 "GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2, and GL_UNSIGNED_INT_2_10_10_10_REV).");
2812 }
2813 }
2814 catch (...)
2815 {
2816 is_ok = false;
2817 internal_error = true;
2818 }
2819
2820 if (buffer)
2821 {
2822 gl.deleteBuffers(1, &buffer);
2823
2824 buffer = 0;
2825 }
2826
2827 if (internal_error)
2828 {
2829 throw 0;
2830 }
2831
2832 return is_ok;
2833 }
2834
2835 /** @brief Test Errors Of ClearNamedBufferSubData function.
2836 *
2837 * Check that INVALID_OPERATION is generated by ClearNamedBufferSubData
2838 * if buffer is not the name of an existing buffer object.
2839 *
2840 * Check that INVALID_ENUM is generated by ClearNamedBufferSubData if
2841 * internal format is not one of the valid sized internal formats listed in
2842 * the table above.
2843 *
2844 * Check that INVALID_VALUE is generated by ClearNamedBufferSubData if
2845 * offset or range are not multiples of the number of basic machine units
2846 * per-element for the internal format specified by internal format. This
2847 * value may be computed by multiplying the number of components for
2848 * internal format from the table by the size of the base type from the
2849 * specification table.
2850 *
2851 * Check that INVALID_VALUE is generated by ClearNamedBufferSubData if
2852 * offset or size is negative, or if offset+size is greater than the value
2853 * of BUFFER_SIZE for the buffer object.
2854 *
2855 * Check that INVALID_OPERATION is generated by ClearNamedBufferSubData
2856 * if any part of the specified range of the buffer object is mapped with
2857 * MapBufferRange or MapBuffer, unless it was mapped with the
2858 * MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.
2859 *
2860 * Check that INVALID_VALUE is generated by ClearNamedBufferSubData if format is not
2861 * a valid format, or type is not a valid type.
2862 *
2863 * True if test case succeeded, false otherwise.
2864 */
TestErrorsOfClearNamedBufferSubData()2865 bool ErrorsTest::TestErrorsOfClearNamedBufferSubData()
2866 {
2867 /* Shortcut for GL functionality. */
2868 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2869
2870 /* Return value. */
2871 bool is_ok = true;
2872 bool internal_error = false;
2873
2874 /* Common variables. */
2875 glw::GLuint buffer = 0;
2876 glw::GLubyte unused_data[4] = {};
2877
2878 try
2879 {
2880 /* Common preparations. */
2881 gl.createBuffers(1, &buffer);
2882 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
2883
2884 m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data,
2885 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
2886 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
2887
2888 /* Test invalid buffer name error behavior. */
2889 {
2890 /* Prepare for invalid buffer name error behavior verification. */
2891 glw::GLuint not_a_buffer_name = 0;
2892
2893 while (gl.isBuffer(++not_a_buffer_name))
2894 ;
2895
2896 /* Test. */
2897 m_pClearNamedBufferSubData(not_a_buffer_name, GL_R8, 0, sizeof(unused_data), GL_RGBA, GL_UNSIGNED_BYTE,
2898 &unused_data);
2899
2900 is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_OPERATION,
2901 " if buffer is not the name of an existing buffer object.");
2902 }
2903
2904 /* Test invalid sized internal format error behavior. */
2905 {
2906 /* Prepare for invalid sized internal format error behavior verification. */
2907 static const glw::GLenum valid_internal_formats[] = {
2908 GL_R8, GL_R16, GL_R16F, GL_R32F, GL_R8I, GL_R16I, GL_R32I,
2909 GL_R8UI, GL_R16UI, GL_R32UI, GL_RG8, GL_RG16, GL_RG16F, GL_RG32F,
2910 GL_RG8I, GL_RG16I, GL_RG32I, GL_RG8UI, GL_RG16UI, GL_RG32UI, GL_RGB32F,
2911 GL_RGB32I, GL_RGB32UI, GL_RGBA8, GL_RGBA16, GL_RGBA16F, GL_RGBA32F, GL_RGBA8I,
2912 GL_RGBA16I, GL_RGBA32I, GL_RGBA8UI, GL_RGBA16UI, GL_RGBA32UI, GL_NONE};
2913 static const glw::GLenum valid_internal_formats_last =
2914 sizeof(valid_internal_formats) / sizeof(valid_internal_formats[0]) - 1;
2915
2916 glw::GLenum invalid_internal_format = 0;
2917
2918 while (&valid_internal_formats[valid_internal_formats_last] !=
2919 std::find(&valid_internal_formats[0], &valid_internal_formats[valid_internal_formats_last],
2920 (++invalid_internal_format)))
2921 ;
2922
2923 /* Test. */
2924 m_pClearNamedBufferData(buffer, invalid_internal_format, GL_RGBA, GL_UNSIGNED_BYTE, &unused_data);
2925
2926 is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_ENUM,
2927 " if internal format is not one of the valid sized internal formats "
2928 "(GL_R8, GL_R16, GL_R16F, GL_R32F, GL_R8I, GL_R16I, GL_R32I, GL_R8UI,"
2929 " GL_R16UI, GL_R32UI, GL_RG8, GL_RG16, GL_RG16F, GL_RG32F, GL_RG8I, GL_RG16I,"
2930 " GL_RG32I, GL_RG8UI, GL_RG16UI, GL_RG32UI, GL_RGB32F, GL_RGB32I, GL_RGB32UI,"
2931 " GL_RGBA8, GL_RGBA16, GL_RGBA16F, GL_RGBA32F, GL_RGBA8I, GL_RGBA16I, GL_RGBA32I,"
2932 " GL_RGBA8UI, GL_RGBA16UI, GL_RGBA32UI).");
2933 }
2934
2935 /* Test incorrect offset alignment error behavior. */
2936 {
2937 /* Test. */
2938 m_pClearNamedBufferSubData(buffer, GL_RGBA8, sizeof(unused_data[0]), sizeof(unused_data), GL_RGBA,
2939 GL_UNSIGNED_BYTE, &unused_data);
2940
2941 is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_VALUE,
2942 "if offset is not multiples of the number of basic machine units (GLubyte)"
2943 "per-element for the internal format (GL_RGBA) specified by internal format.");
2944 }
2945
2946 /* Test incorrect range alignment error behavior. */
2947 {
2948 m_pClearNamedBufferSubData(buffer, GL_RGBA8, 0, sizeof(unused_data) - sizeof(unused_data[0]), GL_RGBA,
2949 GL_UNSIGNED_BYTE, &unused_data);
2950
2951 is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_VALUE,
2952 "if range is not multiples of the number of basic machine units (GLubyte)"
2953 "per-element for the internal format (GL_RGBA) specified by internal format.");
2954 }
2955
2956 /* Test negative offset error behavior. */
2957 {
2958 /* Test. */
2959 m_pClearNamedBufferSubData(buffer, GL_R8, -1, sizeof(unused_data), GL_RGBA, GL_UNSIGNED_BYTE, &unused_data);
2960
2961 is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_VALUE, " if offset or size is negative.");
2962 }
2963
2964 /* Test negative size error behavior. */
2965 {
2966 /* Test. */
2967 m_pClearNamedBufferSubData(buffer, GL_R8, 0, -((glw::GLsizei)sizeof(unused_data)), GL_RGBA,
2968 GL_UNSIGNED_BYTE, &unused_data);
2969
2970 is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_VALUE, " if offset or size is negative.");
2971 }
2972
2973 /* Test size overflow error behavior. */
2974 {
2975 /* Test. */
2976 m_pClearNamedBufferSubData(buffer, GL_R8, 0, 2 * sizeof(unused_data), GL_RGBA, GL_UNSIGNED_BYTE,
2977 &unused_data);
2978
2979 is_ok &= ErrorCheckAndLog(
2980 "glClearNamedBufferSubData", GL_INVALID_VALUE,
2981 " if offset+size is greater than the value of BUFFER_SIZE for the specified buffer object.");
2982 }
2983
2984 /* Test of mapped buffer clear error behavior verification (glMapNamedBuffer version). */
2985 {
2986 (void)(glw::GLbyte *)m_pMapNamedBuffer(buffer, GL_READ_ONLY);
2987 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
2988
2989 m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(unused_data), GL_RGBA, GL_UNSIGNED_BYTE, &unused_data);
2990
2991 is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_OPERATION,
2992 " if any part of the specified range of the buffer"
2993 " object is mapped with MapBuffer, unless it was mapped with "
2994 "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");
2995
2996 m_pUnmapNamedBuffer(buffer);
2997 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
2998 }
2999
3000 /* Test of mapped buffer clear error behavior verification (glMapNamedBufferRange version). */
3001 {
3002 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_READ_BIT);
3003 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3004
3005 m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(unused_data), GL_RGBA, GL_UNSIGNED_BYTE, &unused_data);
3006
3007 is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_OPERATION,
3008 " if any part of the specified range of the buffer"
3009 " object is mapped with MapBufferRange, unless it was mapped with "
3010 "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");
3011
3012 m_pUnmapNamedBuffer(buffer);
3013 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3014 }
3015
3016 /* Test of persistently mapped buffer clear error with behavior verification (glMapNamedBufferRange version). */
3017 {
3018 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data),
3019 GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
3020 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3021
3022 m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(unused_data), GL_RGBA, GL_UNSIGNED_BYTE, &unused_data);
3023
3024 is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_NO_ERROR,
3025 " if any part of the specified range of the buffer"
3026 " object is mapped with MapBuffer with the MAP_PERSISTENT_BIT"
3027 " bit set in the MapBufferRange access flags.");
3028
3029 m_pUnmapNamedBuffer(buffer);
3030 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3031 }
3032
3033 /* Test invalid format error behavior. */
3034 {
3035 /* Prepare for invalid format error behavior verification. */
3036 static const glw::GLenum valid_formats[] = {GL_RED, GL_RG,
3037 GL_RGB, GL_BGR,
3038 GL_RGBA, GL_BGRA,
3039 GL_RED_INTEGER, GL_RG_INTEGER,
3040 GL_RGB_INTEGER, GL_BGR_INTEGER,
3041 GL_RGBA_INTEGER, GL_BGRA_INTEGER,
3042 GL_STENCIL_INDEX, GL_DEPTH_COMPONENT,
3043 GL_DEPTH_STENCIL};
3044 static const glw::GLenum valid_formats_last = sizeof(valid_formats) / sizeof(valid_formats[0]) - 1;
3045
3046 glw::GLenum invalid_format = 0;
3047
3048 while (&valid_formats[valid_formats_last] !=
3049 std::find(&valid_formats[0], &valid_formats[valid_formats_last], (++invalid_format)))
3050 ;
3051
3052 /* Test. */
3053 m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(unused_data), invalid_format, GL_UNSIGNED_BYTE,
3054 &unused_data);
3055
3056 is_ok &= ErrorCheckAndLog(
3057 "glClearNamedBufferSubData", GL_INVALID_VALUE,
3058 " if format is not a valid format "
3059 "(one of GL_RED, GL_RG, GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, "
3060 "GL_RED_INTEGER, GL_RG_INTEGER, GL_RGB_INTEGER, GL_BGR_INTEGER, GL_RGBA_INTEGER, GL_BGRA_INTEGER, "
3061 "GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL).");
3062 }
3063
3064 /* Test invalid type error behavior. */
3065 {
3066 /* Prepare for invalid type error behavior verification. */
3067 static const glw::GLenum valid_types[] = {GL_RED, GL_RG,
3068 GL_RGB, GL_BGR,
3069 GL_RGBA, GL_BGRA,
3070 GL_RED_INTEGER, GL_RG_INTEGER,
3071 GL_RGB_INTEGER, GL_BGR_INTEGER,
3072 GL_RGBA_INTEGER, GL_BGRA_INTEGER,
3073 GL_STENCIL_INDEX, GL_DEPTH_COMPONENT,
3074 GL_DEPTH_STENCIL, GL_NONE};
3075 static const glw::GLenum valid_types_last = sizeof(valid_types) / sizeof(valid_types[0]) - 1;
3076
3077 glw::GLenum invalid_type = 0;
3078
3079 while (&valid_types[valid_types_last] !=
3080 std::find(&valid_types[0], &valid_types[valid_types_last], (++invalid_type)))
3081 ;
3082
3083 /* Test. */
3084 m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(unused_data), GL_RGBA, invalid_type, &unused_data);
3085
3086 is_ok &= ErrorCheckAndLog(
3087 "glClearNamedBufferSubData", GL_INVALID_VALUE,
3088 " if format is not a valid type "
3089 "(one of GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, "
3090 "GL_SHORT, GL_UNSIGNED_INT, GL_INT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, "
3091 "GL_UNSIGNED_BYTE_2_3_3_REV, GL_UNSIGNED_SHORT_5_6_5, "
3092 "GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, "
3093 "GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_UNSIGNED_INT_8_8_8_8, "
3094 "GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2, and GL_UNSIGNED_INT_2_10_10_10_REV).");
3095 }
3096 }
3097 catch (...)
3098 {
3099 is_ok = false;
3100 internal_error = true;
3101 }
3102
3103 if (buffer)
3104 {
3105 gl.deleteBuffers(1, &buffer);
3106
3107 buffer = 0;
3108 }
3109
3110 if (internal_error)
3111 {
3112 throw 0;
3113 }
3114
3115 return is_ok;
3116 }
3117
3118 /** @brief Test Errors Of CopyNamedBufferSubData function.
3119 *
3120 * Check that INVALID_OPERATION is generated by CopyNamedBufferSubData if readBuffer
3121 * or writeBuffer is not the name of an existing buffer object.
3122 *
3123 * Check that INVALID_VALUE is generated by CopyNamedBufferSubData if any of
3124 * readOffset, writeOffset or size is negative, if readOffset+size is
3125 * greater than the size of the source buffer object (its value of
3126 * BUFFER_SIZE), or if writeOffset+size is greater than the size of the
3127 * destination buffer object.
3128 *
3129 * Check that INVALID_VALUE is generated by CopyNamedBufferSubData if the
3130 * source and destination are the same buffer object, and the ranges
3131 * [readOffset,readOffset+size) and [writeOffset,writeOffset+size) overlap.
3132 *
3133 * Check that INVALID_OPERATION is generated by CopyNamedBufferSubData if
3134 * either the source or destination buffer object is mapped with
3135 * MapBufferRange or MapBuffer, unless they were mapped with the
3136 * MAP_PERSISTENT bit set in the MapBufferRange access flags.
3137 *
3138 * True if test case succeeded, false otherwise.
3139 */
TestErrorsOfCopyNamedBufferSubData()3140 bool ErrorsTest::TestErrorsOfCopyNamedBufferSubData()
3141 {
3142 /* Shortcut for GL functionality. */
3143 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3144
3145 /* Return value. */
3146 bool is_ok = true;
3147 bool internal_error = false;
3148
3149 /* Common variables. */
3150 glw::GLuint buffer_r = 0;
3151 glw::GLuint buffer_w = 0;
3152 glw::GLubyte unused_data[4] = {};
3153
3154 try
3155 {
3156 /* Common preparations. */
3157 gl.createBuffers(1, &buffer_r);
3158 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
3159
3160 m_pNamedBufferStorage(buffer_r, sizeof(unused_data), &unused_data,
3161 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
3162 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
3163
3164 gl.createBuffers(1, &buffer_w);
3165 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
3166
3167 m_pNamedBufferStorage(buffer_w, sizeof(unused_data), &unused_data,
3168 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
3169 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
3170
3171 /* Test invalid buffer name error behavior. */
3172 {
3173 /* Prepare for invalid buffer name error behavior verification. */
3174 glw::GLuint not_a_buffer_name = 0;
3175
3176 while (gl.isBuffer(++not_a_buffer_name))
3177 ;
3178
3179 /* Test. */
3180 m_pCopyNamedBufferSubData(not_a_buffer_name, buffer_w, 0, 0, sizeof(unused_data));
3181
3182 is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
3183 " if readBuffer is not the name of an existing buffer object.");
3184
3185 m_pCopyNamedBufferSubData(buffer_r, not_a_buffer_name, 0, 0, sizeof(unused_data));
3186
3187 is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
3188 " if writeBuffer is not the name of an existing buffer object.");
3189 }
3190
3191 /* Test negative read offset error behavior. */
3192 {
3193 /* Test. */
3194 m_pCopyNamedBufferSubData(buffer_r, buffer_w, -1, 0, sizeof(unused_data));
3195
3196 is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE, "if readOffset is negative.");
3197 }
3198
3199 /* Test negative write offset error behavior. */
3200 {
3201 /* Test. */
3202 m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, -1, sizeof(unused_data));
3203
3204 is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE, "if writeOffset is negative.");
3205 }
3206
3207 /* Test negative size error behavior. */
3208 {
3209 /* Test. */
3210 m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, -1);
3211
3212 is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE, "if size is negative.");
3213 }
3214
3215 /* Test overflow size error behavior. */
3216 {
3217 /* Test. */
3218 m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, 2 * sizeof(unused_data));
3219
3220 is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE,
3221 " if size is greater than the size of the source buffer object.");
3222 }
3223
3224 /* Test overflow read offset and size error behavior. */
3225 {
3226 /* Test. */
3227 m_pCopyNamedBufferSubData(buffer_r, buffer_w, sizeof(unused_data) / 2, 0, sizeof(unused_data));
3228
3229 is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE,
3230 " if readOffset+size is greater than the size of the source buffer object.");
3231 }
3232
3233 /* Test overflow write offset and size error behavior. */
3234 {
3235 /* Test. */
3236 m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, sizeof(unused_data) / 2, sizeof(unused_data));
3237
3238 is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE,
3239 " if writeOffset+size is greater than the size of the source buffer object.");
3240 }
3241
3242 /* Test same buffer overlapping error behavior. */
3243 {
3244 /* Test. */
3245 m_pCopyNamedBufferSubData(buffer_w, buffer_w, 0, 0, sizeof(unused_data));
3246
3247 is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE,
3248 " if the source and destination are the same buffer object, and the ranges"
3249 " [readOffset,readOffset+size) and [writeOffset,writeOffset+size) overlap.");
3250 }
3251
3252 /* Test of mapped read buffer copy error behavior verification (glMapNamedBuffer version). */
3253 {
3254 (void)(glw::GLbyte *)m_pMapNamedBuffer(buffer_r, GL_READ_ONLY);
3255 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3256
3257 m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(unused_data));
3258
3259 is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
3260 " if the source buffer object is mapped with MapBuffer.");
3261
3262 m_pUnmapNamedBuffer(buffer_r);
3263 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3264 }
3265
3266 /* Test of mapped write buffer copy error behavior verification (glMapNamedBuffer version). */
3267 {
3268 (void)(glw::GLbyte *)m_pMapNamedBuffer(buffer_w, GL_READ_ONLY);
3269 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3270
3271 m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(unused_data));
3272
3273 is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
3274 " if the destination buffer object is mapped with MapBuffer.");
3275
3276 m_pUnmapNamedBuffer(buffer_w);
3277 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3278 }
3279
3280 /* Test of mapped read buffer copy error behavior verification (glMapNamedBufferRange version). */
3281 {
3282 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer_r, 0, sizeof(unused_data), GL_MAP_READ_BIT);
3283 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3284
3285 m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(unused_data));
3286
3287 is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
3288 " if the source buffer object is mapped with MapBuffer.");
3289
3290 m_pUnmapNamedBuffer(buffer_r);
3291 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3292 }
3293
3294 /* Test of mapped write buffer copy error behavior verification (glMapNamedBufferRange version). */
3295 {
3296 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer_w, 0, sizeof(unused_data), GL_MAP_READ_BIT);
3297 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3298
3299 m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(unused_data));
3300
3301 is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
3302 " if the destination buffer object is mapped with MapBuffer.");
3303
3304 m_pUnmapNamedBuffer(buffer_w);
3305 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3306 }
3307
3308 /* Test of persistently mapped read buffer copy error with behavior verification. */
3309 {
3310 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer_r, 0, sizeof(unused_data),
3311 GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
3312 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3313
3314 m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(unused_data));
3315
3316 is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_NO_ERROR,
3317 " if the source buffer object is mapped using "
3318 "MapBufferRange with the MAP_PERSISTENT bit "
3319 "set in the access flags.");
3320
3321 m_pUnmapNamedBuffer(buffer_r);
3322 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3323 }
3324
3325 /* Test of persistently mapped write buffer copy error with behavior verification. */
3326 {
3327 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer_w, 0, sizeof(unused_data),
3328 GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
3329 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3330
3331 m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(unused_data));
3332
3333 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3334 is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_NO_ERROR,
3335 " if the destination buffer object is mapped using "
3336 "MapBufferRange with the MAP_PERSISTENT bit "
3337 "set in the access flags.");
3338
3339 m_pUnmapNamedBuffer(buffer_w);
3340 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3341 }
3342 }
3343 catch (...)
3344 {
3345 is_ok = false;
3346 internal_error = true;
3347 }
3348
3349 if (buffer_r)
3350 {
3351 gl.deleteBuffers(1, &buffer_r);
3352
3353 buffer_r = 0;
3354 }
3355
3356 if (buffer_r)
3357 {
3358 gl.deleteBuffers(1, &buffer_r);
3359
3360 buffer_r = 0;
3361 }
3362
3363 if (internal_error)
3364 {
3365 throw 0;
3366 }
3367
3368 return is_ok;
3369 }
3370
3371 /** @brief Test Errors Of CreateBuffers function.
3372 *
3373 * Check that INVALID_VALUE is generated by CreateBuffers if n is negative.
3374 *
3375 * True if test case succeeded, false otherwise.
3376 */
TestErrorsOfCreateBuffers()3377 bool ErrorsTest::TestErrorsOfCreateBuffers()
3378 {
3379 /* Shortcut for GL functionality. */
3380 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3381
3382 /* Return value. */
3383 bool is_ok = true;
3384
3385 /* Test. */
3386 glw::GLuint buffer = 0;
3387
3388 gl.createBuffers(-1, &buffer);
3389
3390 is_ok &= ErrorCheckAndLog("glCreateBuffers", GL_INVALID_VALUE, " if n is negative.");
3391
3392 /* Quick check. */
3393 if (buffer)
3394 {
3395 gl.deleteBuffers(1, &buffer);
3396
3397 /* Possible error cleanup. */
3398 while (gl.getError())
3399 ;
3400 }
3401
3402 return is_ok;
3403 }
3404
3405 /** @brief Test Errors Of FlushMappedNamedBufferRange function.
3406 *
3407 * Check that INVALID_OPERATION is generated by FlushMappedNamedBufferRange
3408 * if buffer is not the name of an existing buffer object.
3409 *
3410 * Check that INVALID_VALUE is generated by FlushMappedNamedBufferRange if
3411 * offset or length is negative, or if offset + length exceeds the size of
3412 * the mapping.
3413 *
3414 * Check that INVALID_OPERATION is generated by FlushMappedNamedBufferRange
3415 * if the buffer object is not mapped, or is mapped without the
3416 * MAP_FLUSH_EXPLICIT_BIT flag.
3417 *
3418 * True if test case succeeded, false otherwise.
3419 */
TestErrorsOfFlushMappedNamedBufferRange()3420 bool ErrorsTest::TestErrorsOfFlushMappedNamedBufferRange()
3421 {
3422 /* Shortcut for GL functionality. */
3423 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3424
3425 /* Return value. */
3426 bool is_ok = true;
3427 bool internal_error = false;
3428
3429 /* Common variables. */
3430 glw::GLuint buffer = 0;
3431 glw::GLubyte unused_data[4] = {};
3432
3433 try
3434 {
3435 /* Common preparations. */
3436 gl.createBuffers(1, &buffer);
3437 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
3438
3439 m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
3440 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
3441
3442 /* Test invalid buffer name flush error behavior. */
3443 {
3444 /* Prepare for invalid buffer name error behavior verification. */
3445 glw::GLuint not_a_buffer_name = 0;
3446
3447 while (gl.isBuffer(++not_a_buffer_name))
3448 ;
3449
3450 /* Test. */
3451 m_pFlushMappedNamedBufferRange(not_a_buffer_name, 0, 1);
3452
3453 is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_OPERATION,
3454 " if buffer is not the name of an existing buffer object.");
3455 }
3456
3457 /* Test negative offset flush error behavior. */
3458 {
3459 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data),
3460 GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
3461 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3462
3463 m_pFlushMappedNamedBufferRange(buffer, -1, 1);
3464
3465 is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_VALUE, " if offset is negative.");
3466
3467 m_pUnmapNamedBuffer(buffer);
3468 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3469 }
3470
3471 /* Test negative length flush error behavior. */
3472 {
3473 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data),
3474 GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
3475 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3476
3477 m_pFlushMappedNamedBufferRange(buffer, 0, -1);
3478
3479 is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_VALUE, " if length is negative.");
3480
3481 m_pUnmapNamedBuffer(buffer);
3482 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3483 }
3484
3485 /* Test length exceeds the mapping size flush error behavior. */
3486 {
3487 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data) / 2,
3488 GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
3489 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3490
3491 m_pFlushMappedNamedBufferRange(buffer, 0, sizeof(unused_data));
3492
3493 is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_VALUE,
3494 " if length exceeds the size of the mapping.");
3495
3496 m_pUnmapNamedBuffer(buffer);
3497 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3498 }
3499
3500 /* Test offset + length exceeds the mapping size flush error behavior. */
3501 {
3502 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data),
3503 GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
3504 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3505
3506 m_pFlushMappedNamedBufferRange(buffer, 1, sizeof(unused_data));
3507
3508 is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_VALUE,
3509 " if offset + length exceeds the size of the mapping.");
3510
3511 m_pUnmapNamedBuffer(buffer);
3512 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3513 }
3514
3515 /* Test not mapped buffer flush error behavior. */
3516 {
3517 m_pFlushMappedNamedBufferRange(buffer, 0, sizeof(unused_data));
3518
3519 is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_OPERATION,
3520 " if the buffer object is not mapped.");
3521 }
3522
3523 /* Test buffer flush without the MAP_FLUSH_EXPLICIT_BIT error behavior. */
3524 {
3525 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_WRITE_BIT);
3526 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3527
3528 m_pFlushMappedNamedBufferRange(buffer, 0, sizeof(unused_data));
3529
3530 is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_OPERATION,
3531 " if the buffer is mapped without the MAP_FLUSH_EXPLICIT_BIT flag.");
3532
3533 m_pUnmapNamedBuffer(buffer);
3534 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3535 }
3536 }
3537 catch (...)
3538 {
3539 is_ok = false;
3540 internal_error = true;
3541 }
3542
3543 if (buffer)
3544 {
3545 gl.deleteBuffers(1, &buffer);
3546
3547 buffer = 0;
3548 }
3549
3550 if (internal_error)
3551 {
3552 throw 0;
3553 }
3554
3555 return is_ok;
3556 }
3557
3558 /** @brief Test Errors Of GetNamedBufferParameteriv
3559 * and GetNamedBufferParameteri64v functions.
3560 *
3561 * Check that INVALID_OPERATION is generated by GetNamedBufferParameter* if
3562 * buffer is not the name of an existing buffer object.
3563 *
3564 * Check that INVALID_ENUM is generated by GetNamedBufferParameter* if
3565 * pname is not one of the buffer object parameter names: BUFFER_ACCESS,
3566 * BUFFER_ACCESS_FLAGS, BUFFER_IMMUTABLE_STORAGE, BUFFER_MAPPED,
3567 * BUFFER_MAP_LENGTH, BUFFER_MAP_OFFSET, BUFFER_SIZE, BUFFER_STORAGE_FLAGS,
3568 * BUFFER_USAGE.
3569 *
3570 * True if test case succeeded, false otherwise.
3571 */
TestErrorsOfGetNamedBufferParameter()3572 bool ErrorsTest::TestErrorsOfGetNamedBufferParameter()
3573 {
3574 /* Shortcut for GL functionality. */
3575 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3576
3577 /* Return value. */
3578 bool is_ok = true;
3579 bool internal_error = false;
3580
3581 /* Common variables. */
3582 glw::GLuint buffer = 0;
3583 glw::GLubyte unused_data[4] = {};
3584
3585 try
3586 {
3587 /* Common preparations. */
3588 gl.createBuffers(1, &buffer);
3589 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
3590
3591 m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
3592 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
3593
3594 /* Test invalid buffer name in GetNamedBufferParameteriv function error behavior. */
3595 {
3596 /* Prepare for invalid buffer name error behavior verification. */
3597 glw::GLuint not_a_buffer_name = 0;
3598
3599 while (gl.isBuffer(++not_a_buffer_name))
3600 ;
3601
3602 glw::GLint value = 0;
3603
3604 /* Test. */
3605 m_pGetNamedBufferParameteriv(not_a_buffer_name, GL_BUFFER_MAPPED, &value);
3606
3607 is_ok &= ErrorCheckAndLog("glGetNamedBufferParameteriv", GL_INVALID_OPERATION,
3608 " if buffer is not the name of an existing buffer object.");
3609 }
3610
3611 /* Test invalid buffer name in GetNamedBufferParameteri64v function error behavior. */
3612 {
3613 /* Prepare for invalid buffer name error behavior verification. */
3614 glw::GLuint not_a_buffer_name = 0;
3615
3616 while (gl.isBuffer(++not_a_buffer_name))
3617 ;
3618
3619 glw::GLint64 value = 0;
3620
3621 /* Test. */
3622 m_pGetNamedBufferParameteri64v(not_a_buffer_name, GL_BUFFER_MAPPED, &value);
3623
3624 is_ok &= ErrorCheckAndLog("glGetNamedBufferParameteri64v", GL_INVALID_OPERATION,
3625 " if buffer is not the name of an existing buffer object.");
3626 }
3627
3628 /* Test invalid parameter name in GetNamedBufferParameteriv function error behavior. */
3629 {
3630 /* Prepare for invalid parameter name error behavior verification. */
3631 static const glw::GLenum valid_parameters[] = {
3632 GL_BUFFER_ACCESS, GL_BUFFER_ACCESS_FLAGS, GL_BUFFER_IMMUTABLE_STORAGE,
3633 GL_BUFFER_MAPPED, GL_BUFFER_MAP_LENGTH, GL_BUFFER_MAP_OFFSET,
3634 GL_BUFFER_SIZE, GL_BUFFER_STORAGE_FLAGS, GL_BUFFER_USAGE,
3635 GL_NONE};
3636 static const glw::GLenum valid_parameters_last = sizeof(valid_parameters) / sizeof(valid_parameters[0]) - 1;
3637
3638 glw::GLint value = 0;
3639
3640 glw::GLenum invalid_parameter = 0;
3641
3642 while (&valid_parameters[valid_parameters_last] !=
3643 std::find(&valid_parameters[0], &valid_parameters[valid_parameters_last], (++invalid_parameter)))
3644 ;
3645
3646 /* Test. */
3647 m_pGetNamedBufferParameteriv(buffer, invalid_parameter, &value);
3648
3649 is_ok &= ErrorCheckAndLog("glGetNamedBufferParameteriv", GL_INVALID_ENUM,
3650 " if pname is not one of the buffer object parameter names: BUFFER_ACCESS,"
3651 " BUFFER_ACCESS_FLAGS, BUFFER_IMMUTABLE_STORAGE, BUFFER_MAPPED,"
3652 " BUFFER_MAP_LENGTH, BUFFER_MAP_OFFSET, BUFFER_SIZE, BUFFER_STORAGE_FLAGS,"
3653 " BUFFER_USAGE.");
3654 }
3655
3656 /* Test invalid parameter name in GetNamedBufferParameteri64v function error behavior. */
3657 {
3658 /* Prepare for invalid parameter name error behavior verification. */
3659 static const glw::GLenum valid_parameters[] = {
3660 GL_BUFFER_ACCESS, GL_BUFFER_ACCESS_FLAGS, GL_BUFFER_IMMUTABLE_STORAGE,
3661 GL_BUFFER_MAPPED, GL_BUFFER_MAP_LENGTH, GL_BUFFER_MAP_OFFSET,
3662 GL_BUFFER_SIZE, GL_BUFFER_STORAGE_FLAGS, GL_BUFFER_USAGE,
3663 GL_NONE};
3664 static const glw::GLenum valid_parameters_last = sizeof(valid_parameters) / sizeof(valid_parameters[0]) - 1;
3665
3666 glw::GLint64 value = 0;
3667
3668 glw::GLenum invalid_parameter = 0;
3669
3670 while (&valid_parameters[valid_parameters_last] !=
3671 std::find(&valid_parameters[0], &valid_parameters[valid_parameters_last], (++invalid_parameter)))
3672 ;
3673
3674 /* Test. */
3675 m_pGetNamedBufferParameteri64v(buffer, invalid_parameter, &value);
3676
3677 is_ok &= ErrorCheckAndLog("glGetNamedBufferParameteri64v", GL_INVALID_ENUM,
3678 " if pname is not one of the buffer object parameter names: BUFFER_ACCESS,"
3679 " BUFFER_ACCESS_FLAGS, BUFFER_IMMUTABLE_STORAGE, BUFFER_MAPPED,"
3680 " BUFFER_MAP_LENGTH, BUFFER_MAP_OFFSET, BUFFER_SIZE, BUFFER_STORAGE_FLAGS,"
3681 " BUFFER_USAGE.");
3682 }
3683 }
3684 catch (...)
3685 {
3686 is_ok = false;
3687 internal_error = true;
3688 }
3689
3690 if (buffer)
3691 {
3692 gl.deleteBuffers(1, &buffer);
3693
3694 buffer = 0;
3695 }
3696
3697 if (internal_error)
3698 {
3699 throw 0;
3700 }
3701
3702 return is_ok;
3703 }
3704
3705 /** @brief Test Errors Of GetNamedBufferPointerv function.
3706 *
3707 * Check that INVALID_OPERATION is generated by GetNamedBufferPointerv
3708 * if buffer is not the name of an existing buffer object.
3709 *
3710 * True if test case succeeded, false otherwise.
3711 */
TestErrorsOfGetNamedBufferPointerv()3712 bool ErrorsTest::TestErrorsOfGetNamedBufferPointerv()
3713 {
3714 /* Shortcut for GL functionality. */
3715 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3716
3717 /* Return value. */
3718 bool is_ok = true;
3719 bool internal_error = false;
3720
3721 /* Common variables. */
3722 glw::GLuint buffer = 0;
3723 glw::GLubyte unused_data[4] = {};
3724
3725 try
3726 {
3727 /* Common preparations. */
3728 gl.createBuffers(1, &buffer);
3729 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
3730
3731 m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
3732 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
3733
3734 /* Test invalid buffer name in GetNamedBufferPointerv function error behavior. */
3735 {
3736 /* Prepare for invalid buffer name error behavior verification. */
3737 glw::GLuint not_a_buffer_name = 0;
3738
3739 while (gl.isBuffer(++not_a_buffer_name))
3740 ;
3741
3742 glw::GLvoid *pointer = DE_NULL;
3743
3744 /* Test. */
3745 m_pGetNamedBufferPointerv(not_a_buffer_name, GL_BUFFER_MAP_POINTER, &pointer);
3746
3747 is_ok &= ErrorCheckAndLog("glGetNamedBufferPointerv", GL_INVALID_OPERATION,
3748 " if buffer is not the name of an existing buffer object.");
3749 }
3750 }
3751 catch (...)
3752 {
3753 is_ok = false;
3754 internal_error = true;
3755 }
3756
3757 if (buffer)
3758 {
3759 gl.deleteBuffers(1, &buffer);
3760
3761 buffer = 0;
3762 }
3763
3764 if (internal_error)
3765 {
3766 throw 0;
3767 }
3768
3769 return is_ok;
3770 }
3771
3772 /** @brief Test Errors Of GetNamedBufferSubData function.
3773 *
3774 * Check that INVALID_OPERATION is generated by GetNamedBufferSubData if
3775 * buffer is not the name of an existing buffer object.
3776 *
3777 * Check that INVALID_VALUE is generated by GetNamedBufferSubData if offset
3778 * or size is negative, or if offset+size is greater than the value of
3779 * BUFFER_SIZE for the buffer object.
3780 *
3781 * Check that INVALID_OPERATION is generated by GetNamedBufferSubData if
3782 * the buffer object is mapped with MapBufferRange or MapBuffer, unless it
3783 * was mapped with the MAP_PERSISTENT_BIT bit set in the MapBufferRange
3784 * access flags.
3785 *
3786 * True if test case succeeded, false otherwise.
3787 */
TestErrorsOfGetNamedBufferSubData()3788 bool ErrorsTest::TestErrorsOfGetNamedBufferSubData()
3789 {
3790 /* Shortcut for GL functionality. */
3791 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3792
3793 /* Return value. */
3794 bool is_ok = true;
3795 bool internal_error = false;
3796
3797 /* Common variables. */
3798 glw::GLuint buffer = 0;
3799 glw::GLubyte unused_data[4] = {};
3800
3801 try
3802 {
3803 /* Common preparations. */
3804 gl.createBuffers(1, &buffer);
3805 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
3806
3807 m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
3808 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
3809
3810 /* Test invalid buffer name in pGetNamedBufferSubData function error behavior. */
3811 {
3812 /* Prepare for invalid buffer name error behavior verification. */
3813 glw::GLuint not_a_buffer_name = 0;
3814
3815 while (gl.isBuffer(++not_a_buffer_name))
3816 ;
3817
3818 /* Query storage. */
3819 glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3820
3821 /* Test. */
3822 m_pGetNamedBufferSubData(not_a_buffer_name, 0, sizeof(unused_data_query), unused_data_query);
3823
3824 is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_OPERATION,
3825 " if buffer is not the name of an existing buffer object.");
3826 }
3827
3828 /* Test negative offset error behavior. */
3829 {
3830 /* Query storage. */
3831 glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3832
3833 /* Test. */
3834 m_pGetNamedBufferSubData(buffer, -1, sizeof(unused_data_query), unused_data_query);
3835
3836 is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE, " if offset is negative.");
3837 }
3838
3839 /* Test negative size error behavior. */
3840 {
3841 /* Query storage. */
3842 glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3843
3844 /* Test. */
3845 m_pGetNamedBufferSubData(buffer, 0, -1, unused_data_query);
3846
3847 is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE, " if size is negative.");
3848 }
3849
3850 /* Test size overflow error behavior. */
3851 {
3852 /* Query storage. */
3853 glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3854
3855 /* Test. */
3856 m_pGetNamedBufferSubData(buffer, 0, 2 * sizeof(unused_data_query), unused_data_query);
3857
3858 is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE,
3859 " if size is greater than the value of BUFFER_SIZE for the buffer object.");
3860 }
3861
3862 /* Test offset+size overflow error behavior. */
3863 {
3864 /* Query storage. */
3865 glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3866
3867 /* Test. */
3868 m_pGetNamedBufferSubData(buffer, sizeof(unused_data_query) / 2, sizeof(unused_data_query),
3869 unused_data_query);
3870
3871 is_ok &=
3872 ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE,
3873 " if offset+size is greater than the value of BUFFER_SIZE for the buffer object.");
3874 }
3875
3876 /* Test offset overflow error behavior. */
3877 {
3878 /* Query storage. */
3879 glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3880
3881 /* Test. */
3882 m_pGetNamedBufferSubData(buffer, sizeof(unused_data_query) + 1, 0, unused_data_query);
3883
3884 is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE,
3885 " if offset is greater than the value of BUFFER_SIZE for the buffer object.");
3886 }
3887
3888 /* Test mapped buffer query error behavior. */
3889 {
3890 /* Query storage. */
3891 glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3892
3893 /* Test. */
3894 (void)(glw::GLbyte *)m_pMapNamedBuffer(buffer, GL_WRITE_ONLY);
3895 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3896
3897 m_pGetNamedBufferSubData(buffer, 0, sizeof(unused_data_query), unused_data_query);
3898
3899 is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_OPERATION,
3900 " if the buffer object is mapped with MapBufferRange.");
3901
3902 m_pUnmapNamedBuffer(buffer);
3903 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3904 }
3905
3906 /* Test mapped buffer query error behavior. */
3907 {
3908 /* Query storage. */
3909 glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3910
3911 /* Test. */
3912 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_WRITE_BIT);
3913 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3914
3915 m_pGetNamedBufferSubData(buffer, 0, sizeof(unused_data_query), unused_data_query);
3916
3917 is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_OPERATION,
3918 " if the buffer object is mapped with MapBufferRange.");
3919
3920 m_pUnmapNamedBuffer(buffer);
3921 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3922 }
3923
3924 /* Test persistently mapped buffer query behavior. */
3925 {
3926 /* Query storage. */
3927 glw::GLubyte unused_data_query[sizeof(unused_data) / sizeof(unused_data[0])] = {};
3928
3929 /* Test. */
3930 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data),
3931 GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
3932 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
3933
3934 m_pGetNamedBufferSubData(buffer, 0, sizeof(unused_data_query), unused_data_query);
3935
3936 is_ok &= ErrorCheckAndLog(
3937 "glGetNamedBufferSubData", GL_NO_ERROR,
3938 " if the buffer object is mapped with MapBufferRange with GL_MAP_PERSISTENT_BIT flag.");
3939
3940 m_pUnmapNamedBuffer(buffer);
3941 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
3942 }
3943 }
3944 catch (...)
3945 {
3946 is_ok = false;
3947 internal_error = true;
3948 }
3949
3950 if (buffer)
3951 {
3952 gl.deleteBuffers(1, &buffer);
3953
3954 buffer = 0;
3955 }
3956
3957 if (internal_error)
3958 {
3959 throw 0;
3960 }
3961
3962 return is_ok;
3963 }
3964
3965 /** @brief Test Errors Of MapNamedBuffer function.
3966 *
3967 * Check that INVALID_OPERATION is generated by MapNamedBuffer if buffer is
3968 * not the name of an existing buffer object.
3969 *
3970 * Check that INVALID_ENUM is generated by MapNamedBuffer if access is not
3971 * READ_ONLY, WRITE_ONLY, or READ_WRITE.
3972 *
3973 * Check that INVALID_OPERATION is generated by MapNamedBuffer if the
3974 * buffer object is in a mapped state.
3975 *
3976 * True if test case succeeded, false otherwise.
3977 */
TestErrorsOfMapNamedBuffer()3978 bool ErrorsTest::TestErrorsOfMapNamedBuffer()
3979 {
3980 /* Shortcut for GL functionality. */
3981 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3982
3983 /* Return value. */
3984 bool is_ok = true;
3985 bool internal_error = false;
3986
3987 /* Common variables. */
3988 glw::GLuint buffer = 0;
3989 glw::GLubyte unused_data[4] = {};
3990
3991 try
3992 {
3993 /* Common preparations. */
3994 gl.createBuffers(1, &buffer);
3995 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
3996
3997 m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
3998 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
3999
4000 /* Test invalid buffer name error behavior. */
4001 {
4002 /* Prepare for invalid buffer name error behavior verification. */
4003 glw::GLuint not_a_buffer_name = 0;
4004
4005 while (gl.isBuffer(++not_a_buffer_name))
4006 ;
4007
4008 /* Test. */
4009 m_pMapNamedBuffer(not_a_buffer_name, GL_READ_ONLY);
4010
4011 is_ok &= ErrorCheckAndLog("glMapNamedBuffer", GL_INVALID_OPERATION,
4012 " if buffer is not the name of an existing buffer object.");
4013 }
4014
4015 /* Test access flag error behavior. */
4016 {
4017 /* Prepare for invalid type error behavior verification. */
4018 static const glw::GLenum valid_access_flags[] = {GL_READ_ONLY, GL_WRITE_ONLY, GL_READ_WRITE, GL_NONE};
4019 static const glw::GLenum valid_access_flags_last =
4020 sizeof(valid_access_flags) / sizeof(valid_access_flags[0]) - 1;
4021
4022 glw::GLenum invalid_access_flags = 0;
4023
4024 while (&valid_access_flags[valid_access_flags_last] !=
4025 std::find(&valid_access_flags[0], &valid_access_flags[valid_access_flags_last],
4026 (++invalid_access_flags)))
4027 ;
4028
4029 /* Test. */
4030 glw::GLbyte *mapped_data = (glw::GLbyte *)m_pMapNamedBuffer(buffer, invalid_access_flags);
4031
4032 is_ok &= ErrorCheckAndLog("glMapNamedBuffer", GL_INVALID_ENUM,
4033 " if access is not READ_ONLY, WRITE_ONLY, or READ_WRITE.");
4034
4035 /* Sanity unmapping. */
4036 if (DE_NULL != mapped_data)
4037 {
4038 m_pUnmapNamedBuffer(buffer);
4039 while (gl.getError())
4040 ;
4041 }
4042 }
4043
4044 /* Test mapping of mapped buffer error behavior. */
4045 {
4046 (void)(glw::GLbyte *)m_pMapNamedBuffer(buffer, GL_READ_ONLY);
4047 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer.");
4048
4049 glw::GLbyte *subsequent_mapped_data = (glw::GLbyte *)m_pMapNamedBuffer(buffer, GL_READ_ONLY);
4050
4051 is_ok &= ErrorCheckAndLog("glMapNamedBuffer", GL_INVALID_OPERATION,
4052 " if the buffer object is in a mapped state.");
4053
4054 m_pUnmapNamedBuffer(buffer);
4055 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
4056
4057 if (subsequent_mapped_data)
4058 {
4059 m_context.getTestContext().getLog()
4060 << tcu::TestLog::Message
4061 << "glMapNamedBuffer called on mapped buffer returned non-NULL pointer when error shall occure."
4062 "This may lead to undefined behavior during next tests (object still may be mapped). "
4063 "Test was terminated prematurely."
4064 << tcu::TestLog::EndMessage;
4065 throw 0;
4066 }
4067 }
4068 }
4069 catch (...)
4070 {
4071 is_ok = false;
4072 internal_error = true;
4073 }
4074
4075 if (buffer)
4076 {
4077 gl.deleteBuffers(1, &buffer);
4078
4079 buffer = 0;
4080 }
4081
4082 if (internal_error)
4083 {
4084 throw 0;
4085 }
4086
4087 return is_ok;
4088 }
4089
4090 /** @brief Test Errors Of MapNamedBufferRange function.
4091 *
4092 * Check that INVALID_OPERATION is generated by MapNamedBufferRange if
4093 * buffer is not the name of an existing buffer object.
4094 *
4095 * Check that INVALID_VALUE is generated by MapNamedBufferRange if offset
4096 * or length is negative, if offset+length is greater than the value of
4097 * BUFFER_SIZE for the buffer object, or if access has any bits set other
4098 * than those defined above.
4099 *
4100 * Check that INVALID_OPERATION is generated by MapNamedBufferRange for any
4101 * of the following conditions:
4102 * - length is zero.
4103 * - The buffer object is already in a mapped state.
4104 * - Neither MAP_READ_BIT nor MAP_WRITE_BIT is set.
4105 * - MAP_READ_BIT is set and any of MAP_INVALIDATE_RANGE_BIT,
4106 * MAP_INVALIDATE_BUFFER_BIT or MAP_UNSYNCHRONIZED_BIT is set.
4107 * - MAP_FLUSH_EXPLICIT_BIT is set and MAP_WRITE_BIT is not set.
4108 * - Any of MAP_READ_BIT, MAP_WRITE_BIT, MAP_PERSISTENT_BIT, or
4109 * MAP_COHERENT_BIT are set, but the same bit is not included in the
4110 * buffer's storage flags.
4111 *
4112 * True if test case succeeded, false otherwise.
4113 */
TestErrorsOfMapNamedBufferRange()4114 bool ErrorsTest::TestErrorsOfMapNamedBufferRange()
4115 {
4116 /* Shortcut for GL functionality. */
4117 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
4118
4119 /* Return value. */
4120 bool is_ok = true;
4121 bool internal_error = false;
4122
4123 /* Common variables. */
4124 glw::GLuint buffer = 0;
4125 glw::GLuint buffer_special_flags = 0;
4126 glw::GLubyte unused_data[4] = {};
4127
4128 try
4129 {
4130 /* Common preparations. */
4131 gl.createBuffers(1, &buffer);
4132 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4133
4134 m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data,
4135 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
4136 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4137
4138 /* Test invalid buffer name error behavior. */
4139 {
4140 /* Prepare for invalid buffer name error behavior verification. */
4141 glw::GLuint not_a_buffer_name = 0;
4142
4143 while (gl.isBuffer(++not_a_buffer_name))
4144 ;
4145
4146 /* Test. */
4147 m_pMapNamedBufferRange(not_a_buffer_name, 0, sizeof(unused_data), GL_MAP_READ_BIT);
4148
4149 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
4150 " if buffer is not the name of an existing buffer object.");
4151 }
4152
4153 /* Test negative offset error behavior. */
4154 {
4155 glw::GLvoid *mapped_data = m_pMapNamedBufferRange(buffer, -1, sizeof(unused_data), GL_MAP_READ_BIT);
4156
4157 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE, " if offset is negative.");
4158
4159 /* Sanity unmapping. */
4160 if (DE_NULL != mapped_data)
4161 {
4162 m_pUnmapNamedBuffer(buffer);
4163 while (gl.getError())
4164 ;
4165 }
4166 }
4167
4168 /* Test negative length error behavior. */
4169 {
4170 glw::GLvoid *mapped_data = m_pMapNamedBufferRange(buffer, 0, -1, GL_MAP_READ_BIT);
4171
4172 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE, " if length is negative.");
4173
4174 /* Sanity unmapping. */
4175 if (DE_NULL != mapped_data)
4176 {
4177 m_pUnmapNamedBuffer(buffer);
4178 while (gl.getError())
4179 ;
4180 }
4181 }
4182
4183 /* Test length overflow error behavior. */
4184 {
4185 glw::GLvoid *mapped_data = m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data) * 2, GL_MAP_READ_BIT);
4186
4187 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE,
4188 " if length is greater than the value of BUFFER_SIZE"
4189 " for the buffer object, or if access has any bits set other"
4190 " than those defined above.");
4191
4192 /* Sanity unmapping. */
4193 if (DE_NULL != mapped_data)
4194 {
4195 m_pUnmapNamedBuffer(buffer);
4196 while (gl.getError())
4197 ;
4198 }
4199 }
4200
4201 /* Test (offset+length) overflow error behavior. */
4202 {
4203 glw::GLvoid *mapped_data =
4204 m_pMapNamedBufferRange(buffer, sizeof(unused_data) / 2, sizeof(unused_data), GL_MAP_READ_BIT);
4205
4206 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE,
4207 " if offset+length is greater than the value of BUFFER_SIZE"
4208 " for the buffer object, or if access has any bits set other"
4209 " than those defined above.");
4210
4211 /* Sanity unmapping. */
4212 if (DE_NULL != mapped_data)
4213 {
4214 m_pUnmapNamedBuffer(buffer);
4215 while (gl.getError())
4216 ;
4217 }
4218 }
4219
4220 /* Test zero length error behavior. */
4221 {
4222 glw::GLvoid *mapped_data = m_pMapNamedBufferRange(buffer, 0, 0, GL_MAP_READ_BIT);
4223
4224 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION, " if length is zero.");
4225
4226 /* Sanity unmapping. */
4227 if (DE_NULL != mapped_data)
4228 {
4229 m_pUnmapNamedBuffer(buffer);
4230 while (gl.getError())
4231 ;
4232 }
4233 }
4234
4235 /* Test mapping of mapped buffer error behavior. */
4236 {
4237 m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_READ_BIT);
4238 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer.");
4239
4240 glw::GLvoid *subsequent_mapped_data =
4241 m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_READ_BIT);
4242
4243 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
4244 " if the buffer object is in a mapped state.");
4245
4246 m_pUnmapNamedBuffer(buffer);
4247 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
4248
4249 if (subsequent_mapped_data)
4250 {
4251 m_context.getTestContext().getLog()
4252 << tcu::TestLog::Message
4253 << "glMapNamedBufferRange called on mapped buffer returned non-NULL pointer when error shall "
4254 "occure."
4255 "This may lead to undefined behavior during next tests (object still may be mapped). "
4256 "Test was terminated prematurely."
4257 << tcu::TestLog::EndMessage;
4258 throw 0;
4259 }
4260 }
4261
4262 /* Test access flag read and write bits are not set error behavior. */
4263 {
4264 glw::GLvoid *mapped_data = m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), 0);
4265
4266 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
4267 " if neither MAP_READ_BIT nor MAP_WRITE_BIT is set.");
4268
4269 /* Sanity unmapping. */
4270 if (DE_NULL != mapped_data)
4271 {
4272 m_pUnmapNamedBuffer(buffer);
4273 while (gl.getError())
4274 ;
4275 }
4276 }
4277
4278 /* Test read access invalid flags error behavior. */
4279 {
4280 glw::GLenum read_access_invalid_flags[] = {GL_MAP_INVALIDATE_RANGE_BIT, GL_MAP_INVALIDATE_BUFFER_BIT,
4281 GL_MAP_UNSYNCHRONIZED_BIT};
4282 const glw::GLchar *read_access_invalid_flags_log[] = {
4283 " if MAP_READ_BIT is set with MAP_INVALIDATE_RANGE_BIT.",
4284 " if MAP_READ_BIT is set with MAP_INVALIDATE_BUFFER_BIT.",
4285 " if MAP_READ_BIT is set with MAP_UNSYNCHRONIZED_BIT."};
4286 glw::GLuint read_access_invalid_flags_count =
4287 sizeof(read_access_invalid_flags) / sizeof(read_access_invalid_flags[0]);
4288
4289 for (glw::GLuint i = 0; i < read_access_invalid_flags_count; ++i)
4290 {
4291 glw::GLvoid *mapped_data = m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data),
4292 GL_MAP_READ_BIT | read_access_invalid_flags[i]);
4293
4294 is_ok &=
4295 ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION, read_access_invalid_flags_log[i]);
4296
4297 /* Sanity unmapping. */
4298 if (DE_NULL != mapped_data)
4299 {
4300 m_pUnmapNamedBuffer(buffer);
4301 while (gl.getError())
4302 ;
4303 }
4304 }
4305 }
4306
4307 /* Test access flush bit without write bit error behavior. */
4308 {
4309 glw::GLvoid *mapped_data =
4310 m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_READ_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
4311
4312 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
4313 " if MAP_FLUSH_EXPLICIT_BIT is set and MAP_WRITE_BIT is not set.");
4314
4315 /* Sanity unmapping. */
4316 if (DE_NULL != mapped_data)
4317 {
4318 m_pUnmapNamedBuffer(buffer);
4319 while (gl.getError())
4320 ;
4321 }
4322 }
4323
4324 /* Test incompatible buffer flag error behavior. */
4325 {
4326 glw::GLenum buffer_flags[] = {GL_MAP_WRITE_BIT, GL_MAP_READ_BIT, GL_MAP_WRITE_BIT,
4327 GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT};
4328 glw::GLenum mapping_flags[] = {GL_MAP_READ_BIT, GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT,
4329 GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT};
4330 const glw::GLchar *mapping_flags_log[] = {
4331 " if MAP_READ_BIT is set, but the same bit is not included in the buffer's storage flags.",
4332 " if MAP_WRITE_BIT is set, but the same bit is not included in the buffer's storage flags.",
4333 " if MAP_PERSISTENT_BIT is set, but the same bit is not included in the buffer's storage flags.",
4334 " if MAP_COHERENT_BIT is set, but the same bit is not included in the buffer's storage flags."};
4335 glw::GLuint flags_count = sizeof(mapping_flags) / sizeof(mapping_flags[0]);
4336
4337 for (glw::GLuint i = 0; i < flags_count; ++i)
4338 {
4339 /* Create buffer. */
4340 gl.createBuffers(1, &buffer_special_flags);
4341 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4342
4343 m_pNamedBufferStorage(buffer_special_flags, sizeof(unused_data), &unused_data, buffer_flags[i]);
4344 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4345
4346 /* Test mapping. */
4347 glw::GLvoid *mapped_data =
4348 m_pMapNamedBufferRange(buffer_special_flags, 0, sizeof(unused_data), mapping_flags[i]);
4349
4350 is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION, mapping_flags_log[i]);
4351
4352 /* Sanity unmapping. */
4353 if (DE_NULL != mapped_data)
4354 {
4355 m_pUnmapNamedBuffer(buffer);
4356 while (gl.getError())
4357 ;
4358 }
4359
4360 /* Releasing buffer. */
4361 if (buffer_special_flags)
4362 {
4363 gl.deleteBuffers(1, &buffer_special_flags);
4364
4365 buffer_special_flags = 0;
4366 }
4367 }
4368 }
4369 }
4370 catch (...)
4371 {
4372 is_ok = false;
4373 internal_error = true;
4374 }
4375
4376 if (buffer)
4377 {
4378 gl.deleteBuffers(1, &buffer);
4379
4380 buffer = 0;
4381 }
4382
4383 if (buffer_special_flags)
4384 {
4385 gl.deleteBuffers(1, &buffer_special_flags);
4386
4387 buffer_special_flags = 0;
4388 }
4389
4390 if (internal_error)
4391 {
4392 throw 0;
4393 }
4394
4395 return is_ok;
4396 }
4397
4398 /** @brief Test Errors Of NamedBufferData function.
4399 *
4400 * Check that INVALID_OPERATION is generated by NamedBufferData if buffer
4401 * is not the name of an existing buffer object.
4402 *
4403 * Check that INVALID_ENUM is generated by NamedBufferData if usage is not
4404 * STREAM_DRAW, STREAM_READ, STREAM_COPY, STATIC_DRAW, STATIC_READ,
4405 * STATIC_COPY, DYNAMIC_DRAW, DYNAMIC_READ or DYNAMIC_COPY.
4406 *
4407 * Check that INVALID_VALUE is generated by NamedBufferData if size is
4408 * negative.
4409 *
4410 * Check that INVALID_OPERATION is generated by NamedBufferData if the
4411 * BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE.
4412 *
4413 * True if test case succeeded, false otherwise.
4414 */
TestErrorsOfNamedBufferData()4415 bool ErrorsTest::TestErrorsOfNamedBufferData()
4416 {
4417 /* Shortcut for GL functionality. */
4418 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
4419
4420 /* Return value. */
4421 bool is_ok = true;
4422 bool internal_error = false;
4423
4424 /* Common variables. */
4425 glw::GLuint buffer = 0;
4426 glw::GLuint immutable_buffer = 0;
4427 glw::GLubyte unused_data[4] = {};
4428 std::stack<glw::GLuint> too_much_buffers;
4429
4430 try
4431 {
4432 /* Common preparations. */
4433 gl.createBuffers(1, &buffer);
4434 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4435
4436 gl.createBuffers(1, &immutable_buffer);
4437 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4438
4439 m_pNamedBufferStorage(immutable_buffer, sizeof(unused_data), &unused_data, GL_MAP_READ_BIT);
4440 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4441
4442 /* Test invalid buffer name error behavior. */
4443 {
4444 /* Prepare for invalid buffer name error behavior verification. */
4445 glw::GLuint not_a_buffer_name = 0;
4446
4447 while (gl.isBuffer(++not_a_buffer_name))
4448 ;
4449
4450 /* Test. */
4451 m_pNamedBufferData(not_a_buffer_name, sizeof(unused_data), unused_data, GL_DYNAMIC_COPY);
4452
4453 is_ok &= ErrorCheckAndLog("glNamedBufferData", GL_INVALID_OPERATION,
4454 " if buffer is not the name of an existing buffer object.");
4455 }
4456
4457 /* Test invalid usage error behavior. */
4458 {
4459 /* Prepare for invalid type error behavior verification. */
4460 static const glw::GLenum valid_usages[] = {
4461 GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, GL_STATIC_READ,
4462 GL_STATIC_COPY, GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, GL_DYNAMIC_COPY, GL_NONE};
4463 static const glw::GLenum valid_usages_last = sizeof(valid_usages) / sizeof(valid_usages[0]) - 1;
4464
4465 glw::GLenum invalid_usage = 0;
4466
4467 while (&valid_usages[valid_usages_last] !=
4468 std::find(&valid_usages[0], &valid_usages[valid_usages_last], (++invalid_usage)))
4469 ;
4470
4471 /* Test. */
4472 m_pNamedBufferData(buffer, sizeof(unused_data), unused_data, invalid_usage);
4473
4474 is_ok &=
4475 ErrorCheckAndLog("glNamedBufferData", GL_INVALID_ENUM,
4476 " if usage is not STREAM_DRAW, STREAM_READ, STREAM_COPY, STATIC_DRAW, STATIC_READ,"
4477 " STATIC_COPY, DYNAMIC_DRAW, DYNAMIC_READ or DYNAMIC_COPY.");
4478 }
4479
4480 /* Test negative size error behavior. */
4481 {
4482 m_pNamedBufferData(buffer, -1, unused_data, GL_DYNAMIC_COPY);
4483
4484 is_ok &= ErrorCheckAndLog("glNamedBufferData", GL_INVALID_VALUE, " if size is negative.");
4485 }
4486
4487 /* Test immutable buffer error behavior. */
4488 {
4489 m_pNamedBufferData(immutable_buffer, sizeof(unused_data) / 2, unused_data, GL_DYNAMIC_COPY);
4490
4491 is_ok &= ErrorCheckAndLog("glNamedBufferData", GL_INVALID_OPERATION,
4492 " if the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE.");
4493 }
4494 }
4495 catch (...)
4496 {
4497 is_ok = false;
4498 internal_error = true;
4499 }
4500
4501 if (buffer)
4502 {
4503 gl.deleteBuffers(1, &buffer);
4504
4505 buffer = 0;
4506 }
4507
4508 while (!too_much_buffers.empty())
4509 {
4510 glw::GLuint tmp_buffer = too_much_buffers.top();
4511
4512 if (tmp_buffer)
4513 {
4514 gl.deleteBuffers(1, &tmp_buffer);
4515 }
4516
4517 too_much_buffers.pop();
4518 }
4519
4520 if (immutable_buffer)
4521 {
4522 gl.deleteBuffers(1, &immutable_buffer);
4523
4524 immutable_buffer = 0;
4525 }
4526
4527 if (internal_error)
4528 {
4529 throw 0;
4530 }
4531
4532 return is_ok;
4533 }
4534
4535 /** @brief Test Errors Of NamedBufferStorage function.
4536 *
4537 * Check that INVALID_OPERATION is generated by NamedBufferStorage if
4538 * buffer is not the name of an existing buffer object.
4539 *
4540 * Check that INVALID_VALUE is generated by NamedBufferStorage if size is
4541 * less than or equal to zero.
4542 *
4543 * Check that INVALID_VALUE is generated by NamedBufferStorage if flags has
4544 * any bits set other than DYNAMIC_STORAGE_BIT, MAP_READ_BIT,
4545 * MAP_WRITE_BIT, MAP_PERSISTENT_BIT, MAP_COHERENT_BIT or
4546 * CLIENT_STORAGE_BIT.
4547 *
4548 * Check that INVALID_VALUE error is generated by NamedBufferStorage if
4549 * flags contains MAP_PERSISTENT_BIT but does not contain at least one of
4550 * MAP_READ_BIT or MAP_WRITE_BIT.
4551 *
4552 * Check that INVALID_VALUE is generated by NamedBufferStorage if flags
4553 * contains MAP_COHERENT_BIT, but does not also contain MAP_PERSISTENT_BIT.
4554 *
4555 * True if test case succeeded, false otherwise.
4556 */
TestErrorsOfNamedBufferStorage()4557 bool ErrorsTest::TestErrorsOfNamedBufferStorage()
4558 {
4559 /* Shortcut for GL functionality. */
4560 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
4561
4562 /* Return value. */
4563 bool is_ok = true;
4564 bool internal_error = false;
4565
4566 /* Common variables. */
4567 glw::GLuint buffer = 0;
4568 glw::GLubyte unused_data[4] = {};
4569 std::stack<glw::GLuint> too_much_buffers;
4570
4571 try
4572 {
4573 /* Test invalid buffer name error behavior. */
4574 {
4575 /* Prepare for invalid buffer name error behavior verification. */
4576 glw::GLuint not_a_buffer_name = 0;
4577
4578 while (gl.isBuffer(++not_a_buffer_name))
4579 ;
4580
4581 /* Test. */
4582 m_pNamedBufferStorage(not_a_buffer_name, sizeof(unused_data), unused_data, GL_MAP_WRITE_BIT);
4583
4584 is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_OPERATION,
4585 " if buffer is not the name of an existing buffer object.");
4586 }
4587
4588 /* Test negative or zero size error behavior. */
4589 {
4590 /* Object creation. */
4591 gl.createBuffers(1, &buffer);
4592 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4593
4594 /* Test negative size. */
4595 m_pNamedBufferStorage(buffer, -1, unused_data, GL_DYNAMIC_COPY);
4596
4597 is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE, " if size is negative.");
4598
4599 /* Test zero size. */
4600 m_pNamedBufferStorage(buffer, 0, unused_data, GL_DYNAMIC_COPY);
4601
4602 is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE, " if size zero.");
4603
4604 /* Clean-up. */
4605 gl.deleteBuffers(1, &buffer);
4606
4607 buffer = 0;
4608
4609 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
4610 }
4611
4612 /* Test invalid usage bit error behavior. */
4613 {
4614 /* Prepare for invalid type error behavior verification. */
4615 glw::GLuint valid_bits = GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT |
4616 GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT;
4617
4618 if (m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_buffer"))
4619 {
4620 valid_bits |= GL_SPARSE_STORAGE_BIT_ARB;
4621 }
4622
4623 if (m_context.getContextInfo().isExtensionSupported("GL_NV_gpu_multicast") ||
4624 m_context.getContextInfo().isExtensionSupported("GL_NVX_linked_gpu_multicast"))
4625 {
4626 valid_bits |= GL_PER_GPU_STORAGE_BIT_NV;
4627 }
4628
4629 if (m_context.getContextInfo().isExtensionSupported("GL_NVX_cross_process_interop"))
4630 {
4631 valid_bits |= GL_EXTERNAL_STORAGE_BIT_NVX;
4632 }
4633
4634 glw::GLuint invalid_bits = ~valid_bits;
4635
4636 glw::GLuint bits_count = CHAR_BIT * sizeof(invalid_bits);
4637
4638 /* Test. */
4639 for (glw::GLuint i = 0; i < bits_count; ++i)
4640 {
4641 glw::GLuint possibly_invalid_bit = (1 << i);
4642
4643 if (invalid_bits & possibly_invalid_bit)
4644 {
4645 /* Object creation. */
4646 gl.createBuffers(1, &buffer);
4647 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4648
4649 /* Test invalid bit. */
4650 m_pNamedBufferStorage(buffer, sizeof(unused_data), unused_data, possibly_invalid_bit);
4651
4652 is_ok &=
4653 ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE,
4654 " if flags has any bits set other than DYNAMIC_STORAGE_BIT, MAP_READ_BIT,"
4655 " MAP_WRITE_BIT, MAP_PERSISTENT_BIT, MAP_COHERENT_BIT or CLIENT_STORAGE_BIT.");
4656
4657 /* Release object. */
4658 gl.deleteBuffers(1, &buffer);
4659
4660 buffer = 0;
4661
4662 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
4663 }
4664 }
4665 }
4666
4667 /* Test improper persistent bit behavior error behavior. */
4668 {
4669 /* Object creation. */
4670 gl.createBuffers(1, &buffer);
4671 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4672
4673 /* Test. */
4674 m_pNamedBufferStorage(buffer, sizeof(unused_data), unused_data, GL_MAP_PERSISTENT_BIT);
4675
4676 is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE,
4677 " if flags contains MAP_PERSISTENT_BIT "
4678 "but does not contain at least one of "
4679 "MAP_READ_BIT or MAP_WRITE_BIT.");
4680
4681 /* Clean-up. */
4682 gl.deleteBuffers(1, &buffer);
4683
4684 buffer = 0;
4685
4686 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
4687 }
4688
4689 /* Test improper persistent bit behavior error behavior. */
4690 {
4691 /* Object creation. */
4692 gl.createBuffers(1, &buffer);
4693 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4694
4695 /* Test. */
4696 m_pNamedBufferStorage(buffer, sizeof(unused_data), unused_data,
4697 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT);
4698
4699 is_ok &=
4700 ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE,
4701 " if flags contains MAP_COHERENT_BIT, but does not also contain MAP_PERSISTENT_BIT.");
4702
4703 /* Clean-up. */
4704 gl.deleteBuffers(1, &buffer);
4705
4706 buffer = 0;
4707
4708 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
4709 }
4710 }
4711 catch (...)
4712 {
4713 is_ok = false;
4714 internal_error = true;
4715 }
4716
4717 if (buffer)
4718 {
4719 gl.deleteBuffers(1, &buffer);
4720
4721 buffer = 0;
4722 }
4723
4724 while (!too_much_buffers.empty())
4725 {
4726 glw::GLuint tmp_buffer = too_much_buffers.top();
4727
4728 if (tmp_buffer)
4729 {
4730 gl.deleteBuffers(1, &tmp_buffer);
4731 }
4732
4733 too_much_buffers.pop();
4734 }
4735
4736 if (internal_error)
4737 {
4738 throw 0;
4739 }
4740
4741 return is_ok;
4742 }
4743
4744 /** @brief Test Errors Of NamedBufferSubData function.
4745 *
4746 * Check that INVALID_OPERATION is generated by NamedBufferSubData if
4747 * buffer is not the name of an existing buffer object.
4748 *
4749 * Check that INVALID_VALUE is generated by NamedBufferSubData if offset or
4750 * size is negative, or if offset+size is greater than the value of
4751 * BUFFER_SIZE for the specified buffer object.
4752 *
4753 * Check that INVALID_OPERATION is generated by NamedBufferSubData if any
4754 * part of the specified range of the buffer object is mapped with
4755 * MapBufferRange or MapBuffer, unless it was mapped with the
4756 * MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.
4757 *
4758 * Check that INVALID_OPERATION is generated by NamedBufferSubData if the
4759 * value of the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE
4760 * and the value of BUFFER_STORAGE_FLAGS for the buffer object does not
4761 * have the DYNAMIC_STORAGE_BIT bit set.
4762 *
4763 * True if test case succeeded, false otherwise.
4764 */
TestErrorsOfNamedBufferSubData()4765 bool ErrorsTest::TestErrorsOfNamedBufferSubData()
4766 {
4767 /* Shortcut for GL functionality. */
4768 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
4769
4770 /* Return value. */
4771 bool is_ok = true;
4772 bool internal_error = false;
4773
4774 /* Common variables. */
4775 glw::GLuint buffer = 0;
4776 glw::GLuint immutable_storage_buffer = 0;
4777 glw::GLubyte unused_data[4] = {};
4778
4779 try
4780 {
4781 /* Common preparations. */
4782 gl.createBuffers(1, &buffer);
4783 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4784
4785 m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data,
4786 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT | GL_MAP_PERSISTENT_BIT);
4787 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4788
4789 gl.createBuffers(1, &immutable_storage_buffer);
4790 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4791
4792 m_pNamedBufferStorage(immutable_storage_buffer, sizeof(unused_data), &unused_data, GL_MAP_READ_BIT);
4793 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4794
4795 /* Test invalid buffer name error behavior. */
4796 {
4797 /* Prepare for invalid buffer name error behavior verification. */
4798 glw::GLuint not_a_buffer_name = 0;
4799
4800 while (gl.isBuffer(++not_a_buffer_name))
4801 ;
4802
4803 /* Test. */
4804 m_pNamedBufferSubData(not_a_buffer_name, 0, sizeof(unused_data), &unused_data);
4805
4806 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
4807 " if buffer is not the name of an existing buffer object.");
4808 }
4809
4810 /* Test negative offset error behavior. */
4811 {
4812 /* Test. */
4813 m_pNamedBufferSubData(buffer, -1, sizeof(unused_data), &unused_data);
4814
4815 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_VALUE, " if offset or size is negative.");
4816 }
4817
4818 /* Test negative size error behavior. */
4819 {
4820 /* Test. */
4821 m_pNamedBufferSubData(buffer, 0, -1, &unused_data);
4822
4823 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_VALUE, " if offset or size is negative.");
4824 }
4825
4826 /* Test size overflow error behavior. */
4827 {
4828 /* Test. */
4829 m_pNamedBufferSubData(buffer, 0, sizeof(unused_data) * 2, &unused_data);
4830
4831 is_ok &= ErrorCheckAndLog(
4832 "glNamedBufferSubData", GL_INVALID_VALUE,
4833 " if offset+size is greater than the value of BUFFER_SIZE for the specified buffer object.");
4834 }
4835
4836 /* Test offset+size overflow error behavior. */
4837 {
4838 /* Test. */
4839 m_pNamedBufferSubData(buffer, sizeof(unused_data) / 2, sizeof(unused_data), &unused_data);
4840
4841 is_ok &= ErrorCheckAndLog(
4842 "glNamedBufferSubData", GL_INVALID_VALUE,
4843 " if offset+size is greater than the value of BUFFER_SIZE for the specified buffer object.");
4844 }
4845
4846 /* Test of mapped buffer subdata error behavior verification (with glMapBuffer). */
4847 {
4848 (void)(glw::GLbyte *)m_pMapNamedBuffer(buffer, GL_READ_ONLY);
4849 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
4850
4851 m_pNamedBufferSubData(buffer, 0, sizeof(unused_data), &unused_data);
4852
4853 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
4854 " if any part of the specified range of the buffer"
4855 " object is mapped with MapBuffer, unless it was mapped with "
4856 "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");
4857
4858 m_pUnmapNamedBuffer(buffer);
4859 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
4860 }
4861
4862 /* Test of mapped buffer subdata error behavior verification (with glMapBufferRange). */
4863 {
4864 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data), GL_MAP_READ_BIT);
4865 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
4866
4867 m_pNamedBufferSubData(buffer, 0, sizeof(unused_data), &unused_data);
4868
4869 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
4870 " if any part of the specified range of the buffer"
4871 " object is mapped with MapBufferRange, unless it was mapped with "
4872 "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");
4873
4874 m_pUnmapNamedBuffer(buffer);
4875 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
4876 }
4877
4878 /* Test of persistently mapped buffer clear error with behavior verification. */
4879 {
4880 (void)(glw::GLbyte *)m_pMapNamedBufferRange(buffer, 0, sizeof(unused_data),
4881 GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
4882 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
4883
4884 m_pNamedBufferSubData(buffer, 0, sizeof(unused_data), &unused_data);
4885
4886 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_NO_ERROR,
4887 " if any part of the specified range of the buffer"
4888 " object is mapped with MapBuffer with the MAP_PERSISTENT_BIT"
4889 " bit set in the MapBufferRange access flags.");
4890
4891 m_pUnmapNamedBuffer(buffer);
4892 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
4893 }
4894
4895 /* Test DYNAMIC_STORAGE_BIT bit off immutable buffer not set error behavior. */
4896 {
4897 /* Test. */
4898 m_pNamedBufferSubData(immutable_storage_buffer, 0, sizeof(unused_data), &unused_data);
4899
4900 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
4901 " if the value of the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE"
4902 " and the value of BUFFER_STORAGE_FLAGS for the buffer object does not"
4903 " have the DYNAMIC_STORAGE_BIT bit set.");
4904 }
4905
4906 /* Test DYNAMIC_STORAGE_BIT bit off immutable buffer set no error behavior. */
4907 {
4908 /* Test. */
4909 m_pNamedBufferSubData(buffer, 0, sizeof(unused_data), &unused_data);
4910
4911 is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_NO_ERROR,
4912 " if the value of the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE"
4913 " and the value of BUFFER_STORAGE_FLAGS for the buffer object"
4914 " have the DYNAMIC_STORAGE_BIT bit set.");
4915 }
4916 }
4917 catch (...)
4918 {
4919 is_ok = false;
4920 internal_error = true;
4921 }
4922
4923 if (buffer)
4924 {
4925 gl.deleteBuffers(1, &buffer);
4926
4927 buffer = 0;
4928 }
4929
4930 if (immutable_storage_buffer)
4931 {
4932 gl.deleteBuffers(1, &immutable_storage_buffer);
4933
4934 buffer = 0;
4935 }
4936
4937 if (internal_error)
4938 {
4939 throw 0;
4940 }
4941
4942 return is_ok;
4943 }
4944
4945 /** @brief Test Errors Of UnmapNamedBuffer function.
4946 *
4947 * Check that INVALID_OPERATION is generated by UnmapNamedBuffer if buffer
4948 * is not the name of an existing buffer object.
4949 *
4950 * Check that INVALID_OPERATION is generated by UnmapNamedBuffer if the
4951 * buffer object is not in a mapped state.
4952 *
4953 * True if test case succeeded, false otherwise.
4954 */
TestErrorsOfUnmapNamedBuffer()4955 bool ErrorsTest::TestErrorsOfUnmapNamedBuffer()
4956 {
4957 /* Shortcut for GL functionality. */
4958 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
4959
4960 /* Return value. */
4961 bool is_ok = true;
4962 bool internal_error = false;
4963
4964 /* Common variables. */
4965 glw::GLuint buffer = 0;
4966 glw::GLubyte unused_data[4] = {};
4967
4968 try
4969 {
4970 /* Common preparations. */
4971 gl.createBuffers(1, &buffer);
4972 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");
4973
4974 m_pNamedBufferStorage(buffer, sizeof(unused_data), &unused_data,
4975 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT | GL_MAP_PERSISTENT_BIT);
4976 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");
4977
4978 /* Test invalid buffer name error behavior. */
4979 {
4980 /* Prepare for invalid buffer name error behavior verification. */
4981 glw::GLuint not_a_buffer_name = 0;
4982
4983 while (gl.isBuffer(++not_a_buffer_name))
4984 ;
4985
4986 /* Test. */
4987 m_pUnmapNamedBuffer(not_a_buffer_name);
4988
4989 is_ok &= ErrorCheckAndLog("glUnmapNamedBuffer", GL_INVALID_OPERATION,
4990 " if buffer is not the name of an existing buffer object.");
4991 }
4992
4993 /* Test not mapped buffer error behavior verification. */
4994 {
4995 m_pUnmapNamedBuffer(buffer);
4996
4997 is_ok &= ErrorCheckAndLog("glUnmapNamedBuffer", GL_INVALID_OPERATION,
4998 " if the buffer object is not in a mapped state.");
4999 }
5000 }
5001 catch (...)
5002 {
5003 is_ok = false;
5004 internal_error = true;
5005 }
5006
5007 if (buffer)
5008 {
5009 gl.deleteBuffers(1, &buffer);
5010
5011 buffer = 0;
5012 }
5013
5014 if (internal_error)
5015 {
5016 throw 0;
5017 }
5018
5019 return is_ok;
5020 }
5021
5022 /******************************** Functional Test Implementation ********************************/
5023
5024 /** @brief Vertex shader source code */
5025 const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 450\n"
5026 "\n"
5027 "in int data_in;\n"
5028 "out int data_out;\n"
5029 "\n"
5030 "void main()\n"
5031 "{\n"
5032 " gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
5033 "\n"
5034 " data_out = data_in * data_in;\n"
5035 "}\n";
5036
5037 /** @brief Fragment shader source code */
5038 const glw::GLchar FunctionalTest::s_fragment_shader[] = "#version 450\n"
5039 "\n"
5040 "out vec4 color;\n"
5041 "\n"
5042 "void main()\n"
5043 "{\n"
5044 " color = vec4(0.0);\n"
5045 "}\n";
5046
5047 const glw::GLchar FunctionalTest::s_vertex_shader_input_name[] =
5048 "data_in"; //!< Vertex shader's name of the input attribute.
5049
5050 const glw::GLchar *FunctionalTest::s_vertex_shader_output_name =
5051 "data_out"; //!< Vertex shader's name of the transform feedback varying.
5052
5053 const glw::GLint FunctionalTest::s_initial_data_a[] = {1, 2, 3,
5054 4, 5, 5}; //!< Initial data to be uploaded for the input buffer.
5055
5056 const glw::GLint FunctionalTest::s_initial_data_b[] = {
5057 0, 0, 0, 0, 0, 0, 36}; //!< Initial data to be uploaded for the output buffer.
5058
5059 const glw::GLint FunctionalTest::s_expected_data[] = {
5060 0, 1, 4, 9, 16, 25, 36}; //!< Expected result which shall be read from output buffer.
5061
5062 /** @brief Functional Test constructor.
5063 *
5064 * @param [in] context OpenGL context.
5065 */
FunctionalTest(deqp::Context & context)5066 FunctionalTest::FunctionalTest(deqp::Context &context)
5067 : deqp::TestCase(context, "buffers_functional", "Buffer Objects Functional Test")
5068 , m_pClearNamedBufferData(DE_NULL)
5069 , m_pClearNamedBufferSubData(DE_NULL)
5070 , m_pCopyNamedBufferSubData(DE_NULL)
5071 , m_pFlushMappedNamedBufferRange(DE_NULL)
5072 , m_pGetNamedBufferParameteri64v(DE_NULL)
5073 , m_pGetNamedBufferParameteriv(DE_NULL)
5074 , m_pGetNamedBufferPointerv(DE_NULL)
5075 , m_pGetNamedBufferSubData(DE_NULL)
5076 , m_pMapNamedBuffer(DE_NULL)
5077 , m_pMapNamedBufferRange(DE_NULL)
5078 , m_pNamedBufferData(DE_NULL)
5079 , m_pNamedBufferStorage(DE_NULL)
5080 , m_pNamedBufferSubData(DE_NULL)
5081 , m_pUnmapNamedBuffer(DE_NULL)
5082 , m_po(0)
5083 , m_vao(0)
5084 , m_bo_in(0)
5085 , m_bo_out(0)
5086 , m_attrib_location(-1)
5087 {
5088 /* Intentionally left blank. */
5089 }
5090
5091 /** @brief Run Functional Test.
5092 *
5093 * @return Iteration result.
5094 */
iterate()5095 tcu::TestNode::IterateResult FunctionalTest::iterate()
5096 {
5097 /* Shortcut for GL functionality. */
5098 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
5099
5100 /* Get context setup. */
5101 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
5102 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
5103
5104 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
5105 {
5106 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
5107
5108 return STOP;
5109 }
5110
5111 /* Running tests. */
5112 bool is_ok = true;
5113 bool is_error = false;
5114
5115 /* API function pointers setup. */
5116 m_pClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATA)gl.clearNamedBufferData;
5117 m_pClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATA)gl.clearNamedBufferSubData;
5118 m_pCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATA)gl.copyNamedBufferSubData;
5119 m_pFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGE)gl.flushMappedNamedBufferRange;
5120 m_pGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64V)gl.getNamedBufferParameteri64v;
5121 m_pGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIV)gl.getNamedBufferParameteriv;
5122 m_pGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERV)gl.getNamedBufferPointerv;
5123 m_pGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATA)gl.getNamedBufferSubData;
5124 m_pMapNamedBuffer = (PFNGLMAPNAMEDBUFFER)gl.mapNamedBuffer;
5125 m_pMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGE)gl.mapNamedBufferRange;
5126 m_pNamedBufferData = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
5127 m_pNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGE)gl.namedBufferStorage;
5128 m_pNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATA)gl.namedBufferSubData;
5129 m_pUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;
5130
5131 try
5132 {
5133 /* API function pointers check. */
5134 if ((DE_NULL == m_pClearNamedBufferData) || (DE_NULL == m_pClearNamedBufferSubData) ||
5135 (DE_NULL == m_pCopyNamedBufferSubData) || (DE_NULL == m_pFlushMappedNamedBufferRange) ||
5136 (DE_NULL == m_pGetNamedBufferParameteri64v) || (DE_NULL == m_pGetNamedBufferParameteriv) ||
5137 (DE_NULL == m_pGetNamedBufferPointerv) || (DE_NULL == m_pGetNamedBufferSubData) ||
5138 (DE_NULL == m_pMapNamedBuffer) || (DE_NULL == m_pMapNamedBufferRange) || (DE_NULL == m_pNamedBufferData) ||
5139 (DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pNamedBufferSubData) ||
5140 (DE_NULL == m_pUnmapNamedBuffer))
5141 {
5142 throw 0;
5143 }
5144
5145 /* Running test. */
5146 BuildProgram();
5147 PrepareVertexArrayObject();
5148
5149 is_ok = is_ok && PrepareInputBuffer();
5150 is_ok = is_ok && PrepareOutputBuffer();
5151
5152 if (is_ok)
5153 {
5154 Draw();
5155 }
5156
5157 is_ok = is_ok && CheckArrayBufferImmutableFlag();
5158 is_ok = is_ok && CheckTransformFeedbackBufferSize();
5159 is_ok = is_ok && CheckTransformFeedbackResult();
5160 }
5161 catch (...)
5162 {
5163 is_ok = false;
5164 is_error = true;
5165 }
5166
5167 /* Clean Up. */
5168 Cleanup();
5169
5170 /* Errors clean up. */
5171 while (gl.getError())
5172 ;
5173
5174 /* Result's setup. */
5175 if (is_ok)
5176 {
5177 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5178 }
5179 else
5180 {
5181 if (is_error)
5182 {
5183 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
5184 }
5185 else
5186 {
5187 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5188 }
5189 }
5190
5191 return STOP;
5192 }
5193
5194 /** @brief Build test's GL program */
BuildProgram()5195 void FunctionalTest::BuildProgram()
5196 {
5197 /* Shortcut for GL functionality */
5198 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
5199
5200 struct Shader
5201 {
5202 glw::GLchar const *const source;
5203 glw::GLenum const type;
5204 glw::GLuint id;
5205 } shader[] = {{s_vertex_shader, GL_VERTEX_SHADER, 0}, {s_fragment_shader, GL_FRAGMENT_SHADER, 0}};
5206
5207 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
5208
5209 try
5210 {
5211 /* Create program. */
5212 m_po = gl.createProgram();
5213 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
5214
5215 /* Shader compilation. */
5216
5217 for (glw::GLuint i = 0; i < shader_count; ++i)
5218 {
5219 if (DE_NULL != shader[i].source)
5220 {
5221 shader[i].id = gl.createShader(shader[i].type);
5222
5223 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
5224
5225 gl.attachShader(m_po, shader[i].id);
5226
5227 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
5228
5229 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
5230
5231 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
5232
5233 gl.compileShader(shader[i].id);
5234
5235 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
5236
5237 glw::GLint status = GL_FALSE;
5238
5239 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
5240 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
5241
5242 if (GL_FALSE == status)
5243 {
5244 glw::GLint log_size = 0;
5245 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
5246 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
5247
5248 glw::GLchar *log_text = new glw::GLchar[log_size];
5249
5250 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
5251
5252 m_context.getTestContext().getLog()
5253 << tcu::TestLog::Message << "Shader compilation has failed.\n"
5254 << "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
5255 << "Shader compilation error log:\n"
5256 << log_text << "\n"
5257 << "Shader source code:\n"
5258 << shader[i].source << "\n"
5259 << tcu::TestLog::EndMessage;
5260
5261 delete[] log_text;
5262
5263 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
5264
5265 throw 0;
5266 }
5267 }
5268 }
5269
5270 /* Tranform feedback varying */
5271 gl.transformFeedbackVaryings(m_po, 1, &s_vertex_shader_output_name, GL_INTERLEAVED_ATTRIBS);
5272 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
5273
5274 /* Link. */
5275 gl.linkProgram(m_po);
5276
5277 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram call failed.");
5278
5279 glw::GLint status = GL_FALSE;
5280
5281 gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
5282
5283 if (GL_TRUE == status)
5284 {
5285 for (glw::GLuint i = 0; i < shader_count; ++i)
5286 {
5287 if (shader[i].id)
5288 {
5289 gl.detachShader(m_po, shader[i].id);
5290
5291 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
5292 }
5293 }
5294 }
5295 else
5296 {
5297 glw::GLint log_size = 0;
5298
5299 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
5300
5301 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
5302
5303 glw::GLchar *log_text = new glw::GLchar[log_size];
5304
5305 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
5306
5307 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
5308 << log_text << "\n"
5309 << tcu::TestLog::EndMessage;
5310
5311 delete[] log_text;
5312
5313 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
5314
5315 throw 0;
5316 }
5317 }
5318 catch (...)
5319 {
5320 if (m_po)
5321 {
5322 gl.deleteProgram(m_po);
5323
5324 m_po = 0;
5325 }
5326 }
5327
5328 for (glw::GLuint i = 0; i < shader_count; ++i)
5329 {
5330 if (0 != shader[i].id)
5331 {
5332 gl.deleteShader(shader[i].id);
5333
5334 shader[i].id = 0;
5335 }
5336 }
5337
5338 if (m_po)
5339 {
5340 gl.useProgram(m_po);
5341 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
5342 }
5343
5344 if (0 == m_po)
5345 {
5346 throw 0;
5347 }
5348 }
5349
5350 /** @brief Prepare empty vertex array object and bind it. */
PrepareVertexArrayObject()5351 void FunctionalTest::PrepareVertexArrayObject()
5352 {
5353 /* Shortcut for GL functionality */
5354 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
5355
5356 gl.genVertexArrays(1, &m_vao);
5357 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
5358
5359 gl.bindVertexArray(m_vao);
5360 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
5361 }
5362
5363 /** Prepare input buffer in the way described in test specification (see class comment). */
PrepareInputBuffer()5364 bool FunctionalTest::PrepareInputBuffer()
5365 {
5366 /* Shortcut for GL functionality */
5367 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
5368
5369 /* Constants. */
5370 static const glw::GLint zero = 0;
5371 static const glw::GLint one = 1;
5372
5373 /* Buffer preparation */
5374 gl.createBuffers(1, &m_bo_in);
5375
5376 if (GL_NO_ERROR == gl.getError())
5377 {
5378 /* Storage and last (6th) element preparation. */
5379 m_pNamedBufferStorage(m_bo_in, sizeof(s_initial_data_a), s_initial_data_a,
5380 GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT | GL_MAP_PERSISTENT_BIT);
5381
5382 if (GL_NO_ERROR == gl.getError())
5383 {
5384 /* First element preparation. */
5385 m_pClearNamedBufferSubData(m_bo_in, GL_R8, 0, sizeof(glw::GLint), GL_RED, GL_INT, &zero);
5386
5387 if (GL_NO_ERROR == gl.getError())
5388 {
5389 /* Second element preparation. */
5390 m_pNamedBufferSubData(m_bo_in, 1 /* 2nd element */ * sizeof(glw::GLint), sizeof(glw::GLint), &one);
5391
5392 if (GL_NO_ERROR == gl.getError())
5393 {
5394 /* Third element preparation. */
5395 glw::GLint *p = (glw::GLint *)m_pMapNamedBuffer(m_bo_in, GL_WRITE_ONLY);
5396
5397 if ((GL_NO_ERROR == gl.getError()) || (DE_NULL == p))
5398 {
5399 p[2] = 2;
5400
5401 m_pUnmapNamedBuffer(m_bo_in);
5402
5403 if (GL_NO_ERROR == gl.getError())
5404 {
5405 /* Fifth element preparation. */
5406 m_pCopyNamedBufferSubData(m_bo_in, m_bo_in, sizeof(glw::GLint) * 3, sizeof(glw::GLint) * 4,
5407 sizeof(glw::GLint));
5408
5409 if (GL_NO_ERROR == gl.getError())
5410 {
5411 /* Fourth element preparation. */
5412 p = (glw::GLint *)m_pMapNamedBufferRange(
5413 m_bo_in, sizeof(glw::GLint) * 3, sizeof(glw::GLint),
5414 GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | 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 = DE_NULL;
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