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