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