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