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, ¬_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