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() << tcu::TestLog::Message
136 << "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() << tcu::TestLog::Message << "Shader compilation has failed.\n"
367 << "Shader type: " << glu::getShaderTypeStr(shader[i].type)
368 << "\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() << tcu::TestLog::Message << "Shader compilation has failed.\n"
933 << "Shader type: " << glu::getShaderTypeStr(shader[i].type)
934 << "\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() << tcu::TestLog::Message
1080 << "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() << tcu::TestLog::Message << "Result vector is equal to [" << result[0]
1154 << ", " << result[1] << ", " << result[2]
1155 << "], 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() << tcu::TestLog::Message << "Shader compilation has failed.\n"
1380 << "Shader type: " << glu::getShaderTypeStr(shader[i].type)
1381 << "\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() << tcu::TestLog::Message
1522 << "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() << tcu::TestLog::Message
1536 << "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),
1544 sizeof(glw::GLint) * 2);
1545
1546 if (glw::GLenum error = gl.getError())
1547 {
1548 m_context.getTestContext().getLog() << tcu::TestLog::Message
1549 << "VertexArrayVertexBuffer has unexpectedly generated "
1550 << glu::getErrorStr(error) << "error. Test fails.\n"
1551 << tcu::TestLog::EndMessage;
1552
1553 return false;
1554 }
1555 }
1556
1557 gl.enableVertexAttribArray(0);
1558 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
1559
1560 gl.enableVertexAttribArray(1);
1561 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
1562
1563 /* Array buffer 1 creation. */
1564 glw::GLint array_data_1[2] = { 4, 5 };
1565
1566 gl.genBuffers(1, &m_bo_array_1);
1567 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
1568
1569 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array_1);
1570 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
1571
1572 gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data_1), array_data_1, GL_STATIC_DRAW);
1573 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
1574
1575 gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_2"), 2);
1576 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed.");
1577
1578 gl.vertexAttribIFormat(gl.getAttribLocation(m_po, "a_2"), 1, GL_INT, 0);
1579 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIFormat call failed.");
1580
1581 if (use_multiple_buffers_function)
1582 {
1583 glw::GLintptr offset = (glw::GLintptr)NULL;
1584 glw::GLsizei stride = sizeof(glw::GLint);
1585
1586 gl.vertexArrayVertexBuffers(m_vao, 2, 1, &m_bo_array_1, &offset, &stride);
1587
1588 if (glw::GLenum error = gl.getError())
1589 {
1590 m_context.getTestContext().getLog() << tcu::TestLog::Message
1591 << "VertexArrayVertexBuffers has unexpectedly generated "
1592 << glu::getErrorStr(error) << "error. Test fails.\n"
1593 << tcu::TestLog::EndMessage;
1594
1595 return false;
1596 }
1597 }
1598 else
1599 {
1600 gl.vertexArrayVertexBuffer(m_vao, 2, m_bo_array_1, (glw::GLintptr)NULL, sizeof(glw::GLint));
1601
1602 if (glw::GLenum error = gl.getError())
1603 {
1604 m_context.getTestContext().getLog() << tcu::TestLog::Message
1605 << "VertexArrayVertexBuffer has unexpectedly generated "
1606 << glu::getErrorStr(error) << "error. Test fails.\n"
1607 << tcu::TestLog::EndMessage;
1608
1609 return false;
1610 }
1611 }
1612
1613 gl.enableVertexAttribArray(2);
1614 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
1615
1616 gl.bindVertexArray(0);
1617 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
1618
1619 return true;
1620 }
1621
1622 /** @brief Prepare buffer object for test GLSL program transform feedback results.
1623 */
PrepareXFB()1624 void VertexBuffersTest::PrepareXFB()
1625 {
1626 /* Shortcut for GL functionality */
1627 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1628
1629 /* Buffer creation. */
1630 gl.genBuffers(1, &m_bo_xfb);
1631 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
1632
1633 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
1634 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
1635
1636 /* Preparing storage. */
1637 gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, 2 * sizeof(glw::GLint), NULL, GL_MAP_READ_BIT);
1638 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");
1639
1640 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
1641 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
1642 }
1643
1644 /** @brief Draw test program, fetch transform feedback results and compare them with expected values.
1645 *
1646 * @return True if expected results are equal to returned by XFB, false otherwise.
1647 */
DrawAndCheck()1648 bool VertexBuffersTest::DrawAndCheck()
1649 {
1650 /* Shortcut for GL functionality */
1651 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1652
1653 /* Setup state. */
1654 gl.useProgram(m_po);
1655 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
1656
1657 gl.bindVertexArray(m_vao);
1658 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
1659
1660 gl.beginTransformFeedback(GL_POINTS);
1661 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
1662
1663 /* Draw. */
1664 gl.drawArrays(GL_POINTS, 0, 2);
1665 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
1666
1667 /* State reset. */
1668 gl.endTransformFeedback();
1669 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
1670
1671 /* Result query. */
1672 glw::GLint* result_ptr = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
1673 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
1674
1675 glw::GLint result[2] = { result_ptr[0], result_ptr[1] };
1676
1677 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
1678 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
1679
1680 static const glw::GLint reference[2] = { 0 + 2 + 4, 1 + 3 + 5 };
1681
1682 /* Check result and return. */
1683 for (glw::GLint i = 0; i < 2; ++i)
1684 {
1685 if (reference[i] != result[i])
1686 {
1687 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Result vector is equal to [" << result[0]
1688 << ", " << result[1] << "], but [" << reference[0] << ", "
1689 << reference[1] << "] was expected." << tcu::TestLog::EndMessage;
1690
1691 return false;
1692 }
1693 }
1694
1695 return true;
1696 }
1697
1698 /** @brief Clean GL objects. */
Clean()1699 void VertexBuffersTest::Clean()
1700 {
1701 /* Shortcut for GL functionality */
1702 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1703
1704 gl.useProgram(0);
1705
1706 if (m_po)
1707 {
1708 gl.deleteProgram(m_po);
1709
1710 m_po = 0;
1711 }
1712
1713 if (m_vao)
1714 {
1715 gl.deleteVertexArrays(1, &m_vao);
1716
1717 m_vao = 0;
1718 }
1719
1720 if (m_bo_array_0)
1721 {
1722 gl.deleteBuffers(1, &m_bo_array_0);
1723
1724 m_bo_array_0 = 0;
1725 }
1726
1727 if (m_bo_array_1)
1728 {
1729 gl.deleteBuffers(1, &m_bo_array_1);
1730
1731 m_bo_array_1 = 0;
1732 }
1733
1734 if (m_bo_xfb)
1735 {
1736 gl.deleteBuffers(1, &m_bo_xfb);
1737
1738 m_bo_xfb = 0;
1739 }
1740
1741 while (gl.getError())
1742 ;
1743 }
1744
1745 const glw::GLchar VertexBuffersTest::s_vertex_shader[] = "#version 450\n"
1746 "\n"
1747 "in int a_0;"
1748 "in int a_1;"
1749 "in int a_2;"
1750 "\n"
1751 "out int result;\n"
1752 "\n"
1753 "void main()\n"
1754 "{\n"
1755 " gl_Position = vec4(1.0);\n"
1756 " result = a_0 + a_1 + a_2;"
1757 "}\n";
1758
1759 const glw::GLchar VertexBuffersTest::s_fragment_shader[] = "#version 450\n"
1760 "\n"
1761 "out vec4 color;\n"
1762 "\n"
1763 "void main()\n"
1764 "{\n"
1765 " color = vec4(1.0);"
1766 "}\n";
1767
1768 /******************************** Vertex Array Object Attribute Format Test Implementation ********************************/
1769
1770 /** @brief Vertex Array Object Element Buffer Test constructor.
1771 *
1772 * @param [in] context OpenGL context.
1773 */
AttributeFormatTest(deqp::Context & context)1774 AttributeFormatTest::AttributeFormatTest(deqp::Context& context)
1775 : deqp::TestCase(context, "vertex_arrays_attribute_format", "Vertex Array Object Attribute Format Test")
1776 , m_po(0)
1777 , m_vao(0)
1778 , m_bo_array(0)
1779 , m_bo_xfb(0)
1780 {
1781 /* Intentionally left blank. */
1782 }
1783
1784 /** @brief Iterate Vertex Array Object Enable Disable Attributes Test cases.
1785 *
1786 * @return Iteration result.
1787 */
iterate()1788 tcu::TestNode::IterateResult AttributeFormatTest::iterate()
1789 {
1790 /* Shortcut for GL functionality. */
1791 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1792
1793 /* Get context setup. */
1794 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
1795 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
1796
1797 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
1798 {
1799 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1800
1801 return STOP;
1802 }
1803
1804 /* Running tests. */
1805 bool is_ok = true;
1806 bool is_error = false;
1807
1808 try
1809 {
1810 PrepareXFB();
1811
1812 /* Test floating function. */
1813 for (glw::GLuint i = 1; i <= 4 /* max size */; ++i)
1814 {
1815 PrepareProgram(i, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
1816
1817 is_ok &= PrepareVAO<glw::GLfloat>(i, GL_FLOAT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
1818 is_ok &= DrawAndCheck<glw::GLfloat>(i, false);
1819
1820 CleanVAO();
1821
1822 is_ok &= PrepareVAO<glw::GLbyte>(i, GL_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
1823 is_ok &= DrawAndCheck<glw::GLfloat>(i, false);
1824
1825 CleanVAO();
1826
1827 is_ok &= PrepareVAO<glw::GLbyte>(i, GL_BYTE, true, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
1828 is_ok &= DrawAndCheck<glw::GLfloat>(i, true);
1829
1830 CleanVAO();
1831
1832 is_ok &= PrepareVAO<glw::GLubyte>(i, GL_UNSIGNED_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
1833 is_ok &= DrawAndCheck<glw::GLfloat>(i, false);
1834
1835 CleanVAO();
1836
1837 is_ok &= PrepareVAO<glw::GLshort>(i, GL_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
1838 is_ok &= DrawAndCheck<glw::GLfloat>(i, false);
1839
1840 CleanVAO();
1841
1842 is_ok &= PrepareVAO<glw::GLushort>(i, GL_UNSIGNED_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
1843 is_ok &= DrawAndCheck<glw::GLfloat>(i, false);
1844
1845 CleanVAO();
1846
1847 is_ok &= PrepareVAO<glw::GLint>(i, GL_INT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
1848 is_ok &= DrawAndCheck<glw::GLfloat>(i, false);
1849
1850 CleanVAO();
1851
1852 is_ok &= PrepareVAO<glw::GLuint>(i, GL_UNSIGNED_INT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
1853 is_ok &= DrawAndCheck<glw::GLfloat>(i, false);
1854
1855 CleanVAO();
1856
1857 CleanProgram();
1858 }
1859
1860 for (glw::GLuint i = 1; i <= 2 /* max size */; ++i)
1861 {
1862 PrepareProgram(i, ATTRIBUTE_FORMAT_FUNCTION_DOUBLE);
1863
1864 is_ok &= PrepareVAO<glw::GLdouble>(i, GL_DOUBLE, false, ATTRIBUTE_FORMAT_FUNCTION_DOUBLE);
1865 is_ok &= DrawAndCheck<glw::GLdouble>(i, false);
1866
1867 CleanProgram();
1868 CleanVAO();
1869 }
1870
1871 for (glw::GLuint i = 1; i <= 4 /* max size */; ++i)
1872 {
1873 PrepareProgram(i, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
1874
1875 is_ok &= PrepareVAO<glw::GLbyte>(i, GL_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
1876 is_ok &= DrawAndCheck<glw::GLint>(i, false);
1877
1878 CleanVAO();
1879
1880 is_ok &= PrepareVAO<glw::GLubyte>(i, GL_UNSIGNED_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
1881 is_ok &= DrawAndCheck<glw::GLint>(i, false);
1882
1883 CleanVAO();
1884
1885 is_ok &= PrepareVAO<glw::GLshort>(i, GL_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
1886 is_ok &= DrawAndCheck<glw::GLint>(i, false);
1887
1888 CleanVAO();
1889
1890 is_ok &= PrepareVAO<glw::GLushort>(i, GL_UNSIGNED_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
1891 is_ok &= DrawAndCheck<glw::GLint>(i, false);
1892
1893 CleanVAO();
1894
1895 is_ok &= PrepareVAO<glw::GLint>(i, GL_INT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
1896 is_ok &= DrawAndCheck<glw::GLint>(i, false);
1897
1898 CleanVAO();
1899
1900 is_ok &= PrepareVAO<glw::GLuint>(i, GL_UNSIGNED_INT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
1901 is_ok &= DrawAndCheck<glw::GLint>(i, false);
1902
1903 CleanVAO();
1904
1905 CleanProgram();
1906 }
1907 }
1908 catch (...)
1909 {
1910 is_ok = false;
1911 is_error = true;
1912 }
1913
1914 /* Cleanup. */
1915 CleanProgram();
1916 CleanVAO();
1917 CleanXFB();
1918
1919 /* Errors clean up. */
1920 while (gl.getError())
1921 ;
1922
1923 /* Result's setup. */
1924 if (is_ok)
1925 {
1926 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1927 }
1928 else
1929 {
1930 if (is_error)
1931 {
1932 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1933 }
1934 else
1935 {
1936 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1937 }
1938 }
1939
1940 return STOP;
1941 }
1942
1943 /** @brief Build test's GLSL program.
1944 *
1945 * @note The function may throw if unexpected error has occured.
1946 */
PrepareProgram(glw::GLint size,AtributeFormatFunctionType function_selector)1947 void AttributeFormatTest::PrepareProgram(glw::GLint size, AtributeFormatFunctionType function_selector)
1948 {
1949 /* Shortcut for GL functionality */
1950 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1951
1952 struct Shader
1953 {
1954 glw::GLchar const* source[3];
1955 glw::GLuint const count;
1956 glw::GLenum const type;
1957 glw::GLuint id;
1958 } shader[] = { { { s_vertex_shader_head, s_vertex_shader_declaration[function_selector][size - 1],
1959 s_vertex_shader_body },
1960 3,
1961 GL_VERTEX_SHADER,
1962 0 },
1963 { { s_fragment_shader, DE_NULL, DE_NULL }, 1, GL_FRAGMENT_SHADER, 0 } };
1964
1965 glw::GLuint const shader_count = DE_LENGTH_OF_ARRAY(shader);
1966
1967 try
1968 {
1969 /* Create program. */
1970 m_po = gl.createProgram();
1971 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
1972
1973 /* Shader compilation. */
1974
1975 for (glw::GLuint i = 0; i < shader_count; ++i)
1976 {
1977 {
1978 shader[i].id = gl.createShader(shader[i].type);
1979
1980 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
1981
1982 gl.attachShader(m_po, shader[i].id);
1983
1984 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
1985
1986 gl.shaderSource(shader[i].id, shader[i].count, shader[i].source, NULL);
1987
1988 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
1989
1990 gl.compileShader(shader[i].id);
1991
1992 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
1993
1994 glw::GLint status = GL_FALSE;
1995
1996 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
1997 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
1998
1999 if (GL_FALSE == status)
2000 {
2001 glw::GLint log_size = 0;
2002 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
2003 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
2004
2005 glw::GLchar* log_text = new glw::GLchar[log_size];
2006
2007 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
2008
2009 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
2010 << "Shader type: " << glu::getShaderTypeStr(shader[i].type)
2011 << "\n"
2012 << "Shader compilation error log:\n"
2013 << log_text << "\n"
2014 << "Shader source code:\n"
2015 << shader[i].source << "\n"
2016 << tcu::TestLog::EndMessage;
2017
2018 delete[] log_text;
2019
2020 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
2021
2022 throw 0;
2023 }
2024 }
2025 }
2026
2027 /* Transform Feedback setup. */
2028 static const glw::GLchar* xfb_varying = "result";
2029
2030 gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS);
2031 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
2032
2033 /* Link. */
2034 gl.linkProgram(m_po);
2035
2036 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
2037
2038 glw::GLint status = GL_FALSE;
2039
2040 gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
2041
2042 if (GL_TRUE == status)
2043 {
2044 for (glw::GLuint i = 0; i < shader_count; ++i)
2045 {
2046 if (shader[i].id)
2047 {
2048 gl.detachShader(m_po, shader[i].id);
2049
2050 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
2051 }
2052 }
2053 }
2054 else
2055 {
2056 glw::GLint log_size = 0;
2057
2058 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
2059
2060 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
2061
2062 glw::GLchar* log_text = new glw::GLchar[log_size];
2063
2064 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
2065
2066 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
2067 << log_text << "\n"
2068 << tcu::TestLog::EndMessage;
2069
2070 delete[] log_text;
2071
2072 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
2073
2074 throw 0;
2075 }
2076 }
2077 catch (...)
2078 {
2079 if (m_po)
2080 {
2081 gl.deleteProgram(m_po);
2082
2083 m_po = 0;
2084 }
2085 }
2086
2087 for (glw::GLuint i = 0; i < shader_count; ++i)
2088 {
2089 if (0 != shader[i].id)
2090 {
2091 gl.deleteShader(shader[i].id);
2092
2093 shader[i].id = 0;
2094 }
2095 }
2096
2097 if (0 == m_po)
2098 {
2099 throw 0;
2100 }
2101 }
2102
2103 template <>
NormalizationScaleFactor()2104 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLuint>()
2105 {
2106 return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLuint) - 4 /* 1.0 / 16.0 */));
2107 }
2108
2109 template <>
NormalizationScaleFactor()2110 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLushort>()
2111 {
2112 return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLushort) - 4 /* 1.0 / 16.0 */));
2113 }
2114
2115 template <>
NormalizationScaleFactor()2116 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLubyte>()
2117 {
2118 return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLubyte) - 4 /* 1.0 / 16.0 */));
2119 }
2120
2121 template <>
NormalizationScaleFactor()2122 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLint>()
2123 {
2124 return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLint) - 4 /* 1.0 / 16.0 */ - 1 /* sign bit */));
2125 }
2126
2127 template <>
NormalizationScaleFactor()2128 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLshort>()
2129 {
2130 return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLshort) - 4 /* 1.0 / 16.0 */ - 1 /* sign bit */));
2131 }
2132
2133 template <>
NormalizationScaleFactor()2134 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLbyte>()
2135 {
2136 return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLbyte) - 4 /* 1.0 / 16.0 */ - 1 /* sign bit */));
2137 }
2138
2139 template <typename T>
NormalizationScaleFactor()2140 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor()
2141 {
2142 return 1.0; /* Rest of the types cannot be normalized. */
2143 }
2144
2145 /** @brief Prepare vertex array object for the test of VertexArrayAttrib*Format function.
2146 *
2147 * @param [in] size Size passed to VertexArrayAttrib*Format.
2148 * @param [in] type_gl_name Type passed to VertexArrayAttrib*Format.
2149 * @param [in] function_selector Selects one of VertexArrayAttrib*Format functions.
2150 *
2151 * @return True if function VertexArrayAttrib*Format does not generate any error.
2152 */
2153 template <typename T>
PrepareVAO(glw::GLint size,glw::GLenum type_gl_name,bool normalized,AtributeFormatFunctionType function_selector)2154 bool AttributeFormatTest::PrepareVAO(glw::GLint size, glw::GLenum type_gl_name, bool normalized,
2155 AtributeFormatFunctionType function_selector)
2156 {
2157 /* Shortcut for GL functionality */
2158 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2159
2160 /* VAO creation. */
2161 gl.genVertexArrays(1, &m_vao);
2162 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
2163
2164 gl.bindVertexArray(m_vao);
2165 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
2166
2167 /* Array buffer 0 creation. */
2168
2169 const glw::GLdouble scale = normalized ? NormalizationScaleFactor<T>() : 1.0;
2170
2171 const T array_data[16] = { (T)(0.0 * scale), (T)(1.0 * scale), (T)(2.0 * scale), (T)(3.0 * scale),
2172 (T)(4.0 * scale), (T)(5.0 * scale), (T)(6.0 * scale), (T)(7.0 * scale),
2173 (T)(8.0 * scale), (T)(9.0 * scale), (T)(10.0 * scale), (T)(11.0 * scale),
2174 (T)(12.0 * scale), (T)(13.0 * scale), (T)(14.0 * scale), (T)(15.0 * scale) };
2175
2176 gl.genBuffers(1, &m_bo_array);
2177 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
2178
2179 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array);
2180 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
2181
2182 gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data), array_data, GL_STATIC_DRAW);
2183 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
2184
2185 /* Attribute setup. */
2186 gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_0"), 0);
2187 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed.");
2188
2189 gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_1"), 1);
2190 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed.");
2191
2192 /* Tested attribute format setup. */
2193 switch (function_selector)
2194 {
2195 case ATTRIBUTE_FORMAT_FUNCTION_FLOAT:
2196 gl.vertexArrayAttribFormat(m_vao, gl.getAttribLocation(m_po, "a_0"), size, type_gl_name, normalized, 0);
2197 gl.vertexArrayAttribFormat(m_vao, gl.getAttribLocation(m_po, "a_1"), size, type_gl_name, normalized, 0);
2198 break;
2199
2200 case ATTRIBUTE_FORMAT_FUNCTION_DOUBLE:
2201 gl.vertexArrayAttribLFormat(m_vao, gl.getAttribLocation(m_po, "a_0"), size, type_gl_name, 0);
2202 gl.vertexArrayAttribLFormat(m_vao, gl.getAttribLocation(m_po, "a_1"), size, type_gl_name, 0);
2203 break;
2204
2205 case ATTRIBUTE_FORMAT_FUNCTION_INTEGER:
2206 gl.vertexArrayAttribIFormat(m_vao, gl.getAttribLocation(m_po, "a_0"), size, type_gl_name, 0);
2207 gl.vertexArrayAttribIFormat(m_vao, gl.getAttribLocation(m_po, "a_1"), size, type_gl_name, 0);
2208 break;
2209 default:
2210 throw 0;
2211 }
2212
2213 if (glw::GLenum error = gl.getError())
2214 {
2215 m_context.getTestContext().getLog()
2216 << tcu::TestLog::Message
2217 << ((ATTRIBUTE_FORMAT_FUNCTION_FLOAT == function_selector) ?
2218 "VertexArrayAttribFormat" :
2219 ((ATTRIBUTE_FORMAT_FUNCTION_DOUBLE == function_selector) ?
2220 "VertexArrayAttribLFormat" :
2221 ((ATTRIBUTE_FORMAT_FUNCTION_INTEGER == function_selector) ? "VertexArrayAttribIFormat" :
2222 "VertexArrayAttrib?Format")))
2223 << " has unexpectedly generated " << glu::getErrorStr(error) << "error for test with size = " << size
2224 << ", type = " << glu::getTypeStr(type_gl_name)
2225 << ((ATTRIBUTE_FORMAT_FUNCTION_FLOAT == function_selector) ?
2226 (normalized ? ", which was normalized." : ", which was not normalized.") :
2227 ".")
2228 << " Test fails.\n"
2229 << tcu::TestLog::EndMessage;
2230
2231 return false;
2232 }
2233
2234 gl.bindVertexBuffer(0, m_bo_array, 0, static_cast<glw::GLsizei>(sizeof(T) * size * 2));
2235 gl.bindVertexBuffer(1, m_bo_array, size * sizeof(T),
2236 static_cast<glw::GLsizei>(sizeof(T) * size * 2));
2237
2238 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
2239
2240 gl.enableVertexAttribArray(0);
2241 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
2242
2243 gl.enableVertexAttribArray(1);
2244 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
2245
2246 gl.bindVertexArray(0);
2247 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
2248
2249 return true;
2250 }
2251
2252 /** @brief Prepare buffer object for test GLSL program transform feedback results.
2253 */
PrepareXFB()2254 void AttributeFormatTest::PrepareXFB()
2255 {
2256 /* Shortcut for GL functionality */
2257 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2258
2259 /* Buffer creation. */
2260 gl.genBuffers(1, &m_bo_xfb);
2261 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
2262
2263 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
2264 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
2265
2266 /* Calculating maximum size. */
2267 glw::GLsizei size = static_cast<glw::GLsizei>(
2268 de::max(sizeof(glw::GLubyte),
2269 de::max(sizeof(glw::GLbyte),
2270 de::max(sizeof(glw::GLushort),
2271 de::max(sizeof(glw::GLshort),
2272 de::max(sizeof(glw::GLhalf),
2273 de::max(sizeof(glw::GLint),
2274 de::max(sizeof(glw::GLuint),
2275 de::max(sizeof(glw::GLfixed),
2276 de::max(sizeof(glw::GLfloat),
2277 sizeof(glw::GLdouble)))))))))) *
2278 4 /* maximum number of components */);
2279
2280 /* Preparing storage. */
2281 gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, size, NULL, GL_MAP_READ_BIT);
2282 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");
2283
2284 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
2285 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
2286 }
2287
2288 template <>
compare(glw::GLfloat a,glw::GLfloat b)2289 bool AttributeFormatTest::compare<glw::GLfloat>(glw::GLfloat a, glw::GLfloat b)
2290 {
2291 if (de::abs(a - b) < 0.03125)
2292 {
2293 return true;
2294 }
2295
2296 return false;
2297 }
2298
2299 template <>
compare(glw::GLdouble a,glw::GLdouble b)2300 bool AttributeFormatTest::compare<glw::GLdouble>(glw::GLdouble a, glw::GLdouble b)
2301 {
2302 if (de::abs(a - b) < 0.03125)
2303 {
2304 return true;
2305 }
2306
2307 return false;
2308 }
2309
2310 template <typename T>
compare(T a,T b)2311 bool AttributeFormatTest::compare(T a, T b)
2312 {
2313 return (a == b);
2314 }
2315
2316 /** @brief Draw test program, fetch transform feedback results and compare them with expected values.
2317 *
2318 * @param [in] size Count of elements of the XFB vector is expected.
2319 * @param [in] normalized Normalized values are expected.
2320 *
2321 * @return True if expected results are equal to returned by XFB, false otherwise.
2322 */
2323 template <typename T>
DrawAndCheck(glw::GLint size,bool normalized)2324 bool AttributeFormatTest::DrawAndCheck(glw::GLint size, bool normalized)
2325 {
2326 /* Shortcut for GL functionality */
2327 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2328
2329 /* Setup state. */
2330 gl.useProgram(m_po);
2331 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
2332
2333 gl.bindVertexArray(m_vao);
2334 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
2335
2336 /* Draw. */
2337 gl.beginTransformFeedback(GL_POINTS);
2338 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
2339
2340 gl.drawArrays(GL_POINTS, 0, 2);
2341 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
2342
2343 gl.endTransformFeedback();
2344 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
2345
2346 /* Result query. */
2347 T* result_ptr = (T*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
2348 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
2349
2350 T result[8] = { 0 };
2351
2352 for (glw::GLint i = 0; i < size * 2 /* two points */; ++i)
2353 {
2354 result[i] = result_ptr[i];
2355 }
2356
2357 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
2358 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
2359
2360 const glw::GLdouble scale = normalized ? (1.0 / 16.0) /* Floating point scalling factor. */ : 1.0;
2361
2362 const T array_data[16] = { (T)(0.0 * scale), (T)(1.0 * scale), (T)(2.0 * scale), (T)(3.0 * scale),
2363 (T)(4.0 * scale), (T)(5.0 * scale), (T)(6.0 * scale), (T)(7.0 * scale),
2364 (T)(8.0 * scale), (T)(9.0 * scale), (T)(10.0 * scale), (T)(11.0 * scale),
2365 (T)(12.0 * scale), (T)(13.0 * scale), (T)(14.0 * scale), (T)(15.0 * scale) };
2366
2367 T reference[8] = { 0 };
2368
2369 for (glw::GLint i = 0; i < 2 /* two points */; ++i)
2370 {
2371 for (glw::GLint j = 0; j < size /* size components */; ++j)
2372 {
2373 reference[i * size + j] = array_data[i * size * 2 + j] + array_data[i * size * 2 + j + size];
2374 }
2375 }
2376
2377 /* Check result and return. */
2378 for (glw::GLint i = 0; i < size * 2 /* two points */; ++i)
2379 {
2380 if (!AttributeFormatTest::compare<T>(reference[i], result[i]))
2381 {
2382 std::string reference_str = "[ ";
2383
2384 for (glw::GLint j = 0; j < size * 2 /* two points */; ++j)
2385 {
2386 std::stringstream ss;
2387
2388 ss << reference[j];
2389
2390 reference_str.append(ss.str());
2391
2392 if (j < size * 2 - 1 /* if it is not the last value */)
2393 {
2394 reference_str.append(", ");
2395 }
2396 else
2397 {
2398 reference_str.append(" ]");
2399 }
2400 }
2401
2402 std::string result_str = "[ ";
2403
2404 for (glw::GLint j = 0; j < size * 2 /* two points */; ++j)
2405 {
2406 std::stringstream ss;
2407
2408 ss << result[j];
2409
2410 result_str.append(ss.str());
2411
2412 if (j < size * 2 - 1 /* if it is not the last value */)
2413 {
2414 result_str.append(", ");
2415 }
2416 else
2417 {
2418 result_str.append(" ]");
2419 }
2420 }
2421
2422 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Result vector is equal to "
2423 << result_str.c_str() << ", but " << reference_str.c_str()
2424 << " was expected." << tcu::TestLog::EndMessage;
2425
2426 return false;
2427 }
2428 }
2429
2430 return true;
2431 }
2432
2433 /** @brief Clean GLSL program object. */
CleanProgram()2434 void AttributeFormatTest::CleanProgram()
2435 {
2436 /* Shortcut for GL functionality */
2437 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2438
2439 gl.useProgram(0);
2440
2441 if (m_po)
2442 {
2443 gl.deleteProgram(m_po);
2444
2445 m_po = 0;
2446 }
2447 }
2448
2449 /** @brief Clean Vertex Array Object and related buffer. */
CleanVAO()2450 void AttributeFormatTest::CleanVAO()
2451 {
2452 /* Shortcut for GL functionality */
2453 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2454
2455 if (m_vao)
2456 {
2457 gl.deleteVertexArrays(1, &m_vao);
2458
2459 m_vao = 0;
2460 }
2461
2462 if (m_bo_array)
2463 {
2464 gl.deleteBuffers(1, &m_bo_array);
2465
2466 m_bo_array = 0;
2467 }
2468 }
2469
2470 /** @brief Clean GL objects related to transform feedback. */
CleanXFB()2471 void AttributeFormatTest::CleanXFB()
2472 {
2473 /* Shortcut for GL functionality */
2474 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2475
2476 if (m_bo_xfb)
2477 {
2478 gl.deleteBuffers(1, &m_bo_xfb);
2479
2480 m_bo_xfb = 0;
2481 }
2482
2483 while (gl.getError())
2484 ;
2485 }
2486
2487 const glw::GLchar* AttributeFormatTest::s_vertex_shader_head = "#version 450\n"
2488 "\n";
2489
2490 const glw::GLchar* AttributeFormatTest::s_vertex_shader_body = "\n"
2491 "void main()\n"
2492 "{\n"
2493 " gl_Position = vec4(1.0);\n"
2494 " result = a_0 + a_1;"
2495 "}\n";
2496
2497 const glw::GLchar* AttributeFormatTest::s_vertex_shader_declaration[ATTRIBUTE_FORMAT_FUNCTION_COUNT]
2498 [4 /* sizes count */] = { {
2499 "in float a_0;"
2500 "in float a_1;"
2501 "out float result;\n",
2502
2503 "in vec2 a_0;"
2504 "in vec2 a_1;"
2505 "out vec2 result;\n",
2506
2507 "in vec3 a_0;"
2508 "in vec3 a_1;"
2509 "out vec3 result;\n",
2510
2511 "in vec4 a_0;"
2512 "in vec4 a_1;"
2513 "out vec4 result;\n",
2514 },
2515 {
2516 "in double a_0;"
2517 "in double a_1;"
2518 "out double result;\n",
2519
2520 "in dvec2 a_0;"
2521 "in dvec2 a_1;"
2522 "out dvec2 result;\n",
2523
2524 "in dvec3 a_0;"
2525 "in dvec3 a_1;"
2526 "out dvec3 result;\n",
2527
2528 "in dvec4 a_0;"
2529 "in dvec4 a_1;"
2530 "out dvec4 result;\n",
2531 },
2532 {
2533 "in int a_0;"
2534 "in int a_1;"
2535 "out int result;\n",
2536
2537 "in ivec2 a_0;"
2538 "in ivec2 a_1;"
2539 "out ivec2 result;\n",
2540
2541 "in ivec3 a_0;"
2542 "in ivec3 a_1;"
2543 "out ivec3 result;\n",
2544
2545 "in ivec4 a_0;"
2546 "in ivec4 a_1;"
2547 "out ivec4 result;\n",
2548 } };
2549
2550 const glw::GLchar* AttributeFormatTest::s_fragment_shader = "#version 450\n"
2551 "\n"
2552 "out vec4 color;\n"
2553 "\n"
2554 "void main()\n"
2555 "{\n"
2556 " color = vec4(1.0);"
2557 "}\n";
2558
2559 /******************************** Vertex Array Object Attribute Binding Test Implementation ********************************/
2560
2561 /** @brief Attribute Binding Test constructor.
2562 *
2563 * @param [in] context OpenGL context.
2564 */
AttributeBindingTest(deqp::Context & context)2565 AttributeBindingTest::AttributeBindingTest(deqp::Context& context)
2566 : deqp::TestCase(context, "vertex_arrays_attribute_binding", "Vertex Array Objects Attribute Binding Test")
2567 , m_po(0)
2568 , m_vao(0)
2569 , m_bo_array(0)
2570 , m_bo_xfb(0)
2571 {
2572 /* Intentionally left blank. */
2573 }
2574
2575 /** @brief Iterate Attribute Binding Test cases.
2576 *
2577 * @return Iteration result.
2578 */
iterate()2579 tcu::TestNode::IterateResult AttributeBindingTest::iterate()
2580 {
2581 /* Shortcut for GL functionality. */
2582 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2583
2584 /* Get context setup. */
2585 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
2586 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
2587
2588 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
2589 {
2590 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
2591
2592 return STOP;
2593 }
2594
2595 /* Running tests. */
2596 bool is_ok = true;
2597 bool is_error = false;
2598
2599 try
2600 {
2601 PrepareProgram();
2602 is_ok &= PrepareVAO();
2603 PrepareXFB();
2604 is_ok &= DrawAndCheck();
2605 }
2606 catch (...)
2607 {
2608 is_ok = false;
2609 is_error = true;
2610 }
2611
2612 /* Cleanup. */
2613 Clean();
2614
2615 /* Errors clean up. */
2616 while (gl.getError())
2617 ;
2618
2619 /* Result's setup. */
2620 if (is_ok)
2621 {
2622 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2623 }
2624 else
2625 {
2626 if (is_error)
2627 {
2628 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
2629 }
2630 else
2631 {
2632 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2633 }
2634 }
2635
2636 return STOP;
2637 }
2638
2639 /** @brief Build test's GLSL program.
2640 *
2641 * @note The function may throw if unexpected error has occured.
2642 */
PrepareProgram()2643 void AttributeBindingTest::PrepareProgram()
2644 {
2645 /* Shortcut for GL functionality */
2646 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2647
2648 struct Shader
2649 {
2650 glw::GLchar const* const source;
2651 glw::GLenum const type;
2652 glw::GLuint id;
2653 } shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
2654
2655 glw::GLuint const shader_count = DE_LENGTH_OF_ARRAY(shader);
2656
2657 try
2658 {
2659 /* Create program. */
2660 m_po = gl.createProgram();
2661 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
2662
2663 /* Shader compilation. */
2664
2665 for (glw::GLuint i = 0; i < shader_count; ++i)
2666 {
2667 if (DE_NULL != shader[i].source)
2668 {
2669 shader[i].id = gl.createShader(shader[i].type);
2670
2671 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
2672
2673 gl.attachShader(m_po, shader[i].id);
2674
2675 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
2676
2677 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
2678
2679 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
2680
2681 gl.compileShader(shader[i].id);
2682
2683 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
2684
2685 glw::GLint status = GL_FALSE;
2686
2687 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
2688 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
2689
2690 if (GL_FALSE == status)
2691 {
2692 glw::GLint log_size = 0;
2693 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
2694 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
2695
2696 glw::GLchar* log_text = new glw::GLchar[log_size];
2697
2698 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
2699
2700 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
2701 << "Shader type: " << glu::getShaderTypeStr(shader[i].type)
2702 << "\n"
2703 << "Shader compilation error log:\n"
2704 << log_text << "\n"
2705 << "Shader source code:\n"
2706 << shader[i].source << "\n"
2707 << tcu::TestLog::EndMessage;
2708
2709 delete[] log_text;
2710
2711 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
2712
2713 throw 0;
2714 }
2715 }
2716 }
2717
2718 /* Binding attributes. */
2719 gl.bindAttribLocation(m_po, 0, "a_0");
2720 gl.bindAttribLocation(m_po, 1, "a_1");
2721 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindAttribLocation call failed.");
2722
2723 /* Transform Feedback setup. */
2724 static const glw::GLchar* xfb_varying = "result";
2725 gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS);
2726 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
2727
2728 /* Link. */
2729 gl.linkProgram(m_po);
2730
2731 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
2732
2733 glw::GLint status = GL_FALSE;
2734
2735 gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
2736
2737 if (GL_TRUE == status)
2738 {
2739 for (glw::GLuint i = 0; i < shader_count; ++i)
2740 {
2741 if (shader[i].id)
2742 {
2743 gl.detachShader(m_po, shader[i].id);
2744
2745 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
2746 }
2747 }
2748 }
2749 else
2750 {
2751 glw::GLint log_size = 0;
2752
2753 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
2754
2755 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
2756
2757 glw::GLchar* log_text = new glw::GLchar[log_size];
2758
2759 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
2760
2761 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
2762 << log_text << "\n"
2763 << tcu::TestLog::EndMessage;
2764
2765 delete[] log_text;
2766
2767 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
2768
2769 throw 0;
2770 }
2771 }
2772 catch (...)
2773 {
2774 if (m_po)
2775 {
2776 gl.deleteProgram(m_po);
2777
2778 m_po = 0;
2779 }
2780 }
2781
2782 for (glw::GLuint i = 0; i < shader_count; ++i)
2783 {
2784 if (0 != shader[i].id)
2785 {
2786 gl.deleteShader(shader[i].id);
2787
2788 shader[i].id = 0;
2789 }
2790 }
2791
2792 if (0 == m_po)
2793 {
2794 throw 0;
2795 }
2796 }
2797
2798 /** @brief Prepare vertex array object for the test.
2799 *
2800 * @return True if function VertexArrayAttribBinding does not generate any error.
2801 */
PrepareVAO()2802 bool AttributeBindingTest::PrepareVAO()
2803 {
2804 /* Shortcut for GL functionality */
2805 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2806
2807 /* VAO creation. */
2808 gl.genVertexArrays(1, &m_vao);
2809 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
2810
2811 gl.bindVertexArray(m_vao);
2812 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
2813
2814 /* Array buffer creation. */
2815 glw::GLint array_data[2] = { 1, 0 };
2816
2817 gl.genBuffers(1, &m_bo_array);
2818 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
2819
2820 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array);
2821 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
2822
2823 gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data), array_data, GL_STATIC_DRAW);
2824 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
2825
2826 gl.vertexAttribIPointer(0, 1, GL_INT, sizeof(glw::GLint) * 2, NULL);
2827 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer call failed.");
2828
2829 gl.vertexAttribIPointer(1, 1, GL_INT, sizeof(glw::GLint) * 2, glu::BufferOffsetAsPointer(1 * sizeof(glw::GLint)));
2830 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer call failed.");
2831
2832 gl.enableVertexAttribArray(0);
2833 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
2834
2835 gl.enableVertexAttribArray(1);
2836 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
2837
2838 gl.vertexArrayAttribBinding(m_vao, 0, 1);
2839 gl.vertexArrayAttribBinding(m_vao, 1, 0);
2840
2841 if (glw::GLenum error = gl.getError())
2842 {
2843 m_context.getTestContext().getLog() << tcu::TestLog::Message
2844 << "VertexArrayAttribBinding has unexpectedly generated "
2845 << glu::getErrorStr(error) << "error. Test fails.\n"
2846 << tcu::TestLog::EndMessage;
2847
2848 return false;
2849 }
2850
2851 return true;
2852 }
2853
2854 /** @brief Prepare buffer object for test GLSL program transform feedback results.
2855 */
PrepareXFB()2856 void AttributeBindingTest::PrepareXFB()
2857 {
2858 /* Shortcut for GL functionality */
2859 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2860
2861 /* Buffer creation. */
2862 gl.genBuffers(1, &m_bo_xfb);
2863 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
2864
2865 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
2866 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
2867
2868 /* Preparing storage. */
2869 gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, 2 * sizeof(glw::GLint), NULL, GL_MAP_READ_BIT);
2870 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");
2871
2872 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
2873 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
2874 }
2875
2876 /** @brief Draw test program, fetch transform feedback results and compare them with expected values.
2877 *
2878 * @return True if expected results are equal to returned by XFB, false otherwise.
2879 */
DrawAndCheck()2880 bool AttributeBindingTest::DrawAndCheck()
2881 {
2882 /* Shortcut for GL functionality */
2883 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2884
2885 /* Setup state. */
2886 gl.useProgram(m_po);
2887 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
2888
2889 gl.bindVertexArray(m_vao);
2890 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
2891
2892 gl.beginTransformFeedback(GL_POINTS);
2893 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
2894
2895 /* Draw. */
2896 gl.drawArrays(GL_POINTS, 0, 1);
2897 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
2898
2899 /* State reset. */
2900 gl.endTransformFeedback();
2901 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
2902
2903 /* Result query. */
2904 glw::GLint* result_ptr = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
2905 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
2906
2907 glw::GLint result[2] = { result_ptr[0], result_ptr[1] };
2908
2909 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
2910 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
2911
2912 /* Check result and return. */
2913 if ((0 == result[0]) || (1 == result[1]))
2914 {
2915 return true;
2916 }
2917
2918 return false;
2919 }
2920
2921 /** @brief Clean GL objects. */
Clean()2922 void AttributeBindingTest::Clean()
2923 {
2924 /* Shortcut for GL functionality */
2925 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2926
2927 gl.useProgram(0);
2928
2929 if (m_po)
2930 {
2931 gl.deleteProgram(m_po);
2932
2933 m_po = 0;
2934 }
2935
2936 if (m_vao)
2937 {
2938 gl.deleteVertexArrays(1, &m_vao);
2939
2940 m_vao = 0;
2941 }
2942
2943 if (m_bo_array)
2944 {
2945 gl.deleteBuffers(1, &m_bo_array);
2946
2947 m_bo_array = 0;
2948 }
2949
2950 if (m_bo_xfb)
2951 {
2952 gl.deleteBuffers(1, &m_bo_xfb);
2953
2954 m_bo_xfb = 0;
2955 }
2956
2957 while (gl.getError())
2958 ;
2959 }
2960
2961 const glw::GLchar AttributeBindingTest::s_vertex_shader[] = "#version 450\n"
2962 "\n"
2963 "in int a_0;\n"
2964 "in int a_1;\n"
2965 "out ivec2 result;\n"
2966 "\n"
2967 "void main()\n"
2968 "{\n"
2969 " gl_Position = vec4(1.0);\n"
2970 " result[0] = a_0;\n"
2971 " result[1] = a_1;\n"
2972 "}\n";
2973
2974 const glw::GLchar AttributeBindingTest::s_fragment_shader[] = "#version 450\n"
2975 "\n"
2976 "out vec4 color;\n"
2977 "\n"
2978 "void main()\n"
2979 "{\n"
2980 " color = vec4(1.0);"
2981 "}\n";
2982
2983 /******************************** Vertex Array Attribute Binding Divisor Test Implementation ********************************/
2984
2985 /** @brief Vertex Array Attribute Binding Divisor Test constructor.
2986 *
2987 * @param [in] context OpenGL context.
2988 */
AttributeBindingDivisorTest(deqp::Context & context)2989 AttributeBindingDivisorTest::AttributeBindingDivisorTest(deqp::Context& context)
2990 : deqp::TestCase(context, "vertex_arrays_attribute_binding_divisor", "Vertex Array Attribute Binding Divisor Test")
2991 , m_po(0)
2992 , m_vao(0)
2993 , m_bo_array(0)
2994 , m_bo_xfb(0)
2995 {
2996 /* Intentionally left blank. */
2997 }
2998
2999 /** @brief Iterate Vertex Array Attribute Binding Divisor Test cases.
3000 *
3001 * @return Iteration result.
3002 */
iterate()3003 tcu::TestNode::IterateResult AttributeBindingDivisorTest::iterate()
3004 {
3005 /* Shortcut for GL functionality. */
3006 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3007
3008 /* Get context setup. */
3009 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
3010 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
3011
3012 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
3013 {
3014 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
3015
3016 return STOP;
3017 }
3018
3019 /* Running tests. */
3020 bool is_ok = true;
3021 bool is_error = false;
3022
3023 try
3024 {
3025 PrepareProgram();
3026 PrepareVAO();
3027 PrepareXFB();
3028
3029 {
3030 glw::GLint reference[] = { 0, 2 };
3031 is_ok = SetDivisor(2);
3032 Draw(1, 2);
3033 is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference,
3034 "Draw of 1 point with 2 instances with 2 divisor has failed.");
3035 }
3036
3037 {
3038 glw::GLint reference[] = { 0, 0, 1, 1 };
3039 is_ok = SetDivisor(1);
3040 Draw(2, 2);
3041 is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference,
3042 "Draw of 2 points with 2 instances with 1 divisor has failed.");
3043 }
3044
3045 {
3046 glw::GLint reference[] = { 0, 1, 2, 3 };
3047 is_ok = SetDivisor(1);
3048 Draw(1, 4);
3049 is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference,
3050 "Draw of 1 point with 4 instances with 1 divisor has failed.");
3051 }
3052
3053 {
3054 glw::GLint reference[] = { 0, 1, 0, 1 };
3055 is_ok = SetDivisor(0);
3056 Draw(2, 2);
3057 is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference,
3058 "Draw of 2 points with 2 instances with 0 divisor has failed.");
3059 }
3060
3061 {
3062 glw::GLint reference[] = { 0, 1, 2, 3 };
3063 is_ok = SetDivisor(0);
3064 Draw(4, 1);
3065 is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference,
3066 "Draw of 4 points with 1 instance with 0 divisor has failed.");
3067 }
3068 }
3069 catch (...)
3070 {
3071 is_ok = false;
3072 is_error = true;
3073 }
3074
3075 /* Cleanup. */
3076 Clean();
3077
3078 /* Errors clean up. */
3079 while (gl.getError())
3080 ;
3081
3082 /* Result's setup. */
3083 if (is_ok)
3084 {
3085 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3086 }
3087 else
3088 {
3089 if (is_error)
3090 {
3091 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
3092 }
3093 else
3094 {
3095 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3096 }
3097 }
3098
3099 return STOP;
3100 }
3101
3102 /** @brief Build test's GLSL program.
3103 *
3104 * @note The function may throw if unexpected error has occured.
3105 */
PrepareProgram()3106 void AttributeBindingDivisorTest::PrepareProgram()
3107 {
3108 /* Shortcut for GL functionality */
3109 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3110
3111 struct Shader
3112 {
3113 glw::GLchar const* const source;
3114 glw::GLenum const type;
3115 glw::GLuint id;
3116 } shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
3117
3118 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
3119
3120 try
3121 {
3122 /* Create program. */
3123 m_po = gl.createProgram();
3124 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
3125
3126 /* Shader compilation. */
3127
3128 for (glw::GLuint i = 0; i < shader_count; ++i)
3129 {
3130 if (DE_NULL != shader[i].source)
3131 {
3132 shader[i].id = gl.createShader(shader[i].type);
3133
3134 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
3135
3136 gl.attachShader(m_po, shader[i].id);
3137
3138 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
3139
3140 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
3141
3142 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
3143
3144 gl.compileShader(shader[i].id);
3145
3146 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
3147
3148 glw::GLint status = GL_FALSE;
3149
3150 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
3151 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
3152
3153 if (GL_FALSE == status)
3154 {
3155 glw::GLint log_size = 0;
3156 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
3157 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
3158
3159 glw::GLchar* log_text = new glw::GLchar[log_size];
3160
3161 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
3162
3163 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
3164 << "Shader type: " << glu::getShaderTypeStr(shader[i].type)
3165 << "\n"
3166 << "Shader compilation error log:\n"
3167 << log_text << "\n"
3168 << "Shader source code:\n"
3169 << shader[i].source << "\n"
3170 << tcu::TestLog::EndMessage;
3171
3172 delete[] log_text;
3173
3174 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
3175
3176 throw 0;
3177 }
3178 }
3179 }
3180
3181 /* Transform Feedback setup. */
3182 static const glw::GLchar* xfb_varying = "result";
3183
3184 gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS);
3185 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
3186
3187 /* Link. */
3188 gl.linkProgram(m_po);
3189
3190 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
3191
3192 glw::GLint status = GL_FALSE;
3193
3194 gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
3195
3196 if (GL_TRUE == status)
3197 {
3198 for (glw::GLuint i = 0; i < shader_count; ++i)
3199 {
3200 if (shader[i].id)
3201 {
3202 gl.detachShader(m_po, shader[i].id);
3203
3204 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
3205 }
3206 }
3207 }
3208 else
3209 {
3210 glw::GLint log_size = 0;
3211
3212 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
3213
3214 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
3215
3216 glw::GLchar* log_text = new glw::GLchar[log_size];
3217
3218 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
3219
3220 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
3221 << log_text << "\n"
3222 << tcu::TestLog::EndMessage;
3223
3224 delete[] log_text;
3225
3226 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
3227
3228 throw 0;
3229 }
3230 }
3231 catch (...)
3232 {
3233 if (m_po)
3234 {
3235 gl.deleteProgram(m_po);
3236
3237 m_po = 0;
3238 }
3239 }
3240
3241 for (glw::GLuint i = 0; i < shader_count; ++i)
3242 {
3243 if (0 != shader[i].id)
3244 {
3245 gl.deleteShader(shader[i].id);
3246
3247 shader[i].id = 0;
3248 }
3249 }
3250
3251 if (m_po)
3252 {
3253 gl.useProgram(m_po);
3254 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
3255 }
3256
3257 if (0 == m_po)
3258 {
3259 throw 0;
3260 }
3261 }
3262
3263 /** @brief Prepare vertex array object for the test.
3264 */
PrepareVAO()3265 void AttributeBindingDivisorTest::PrepareVAO()
3266 {
3267 /* Shortcut for GL functionality */
3268 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3269
3270 /* VAO creation. */
3271 gl.genVertexArrays(1, &m_vao);
3272 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
3273
3274 gl.bindVertexArray(m_vao);
3275 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
3276
3277 /* Array buffer 0 creation. */
3278 glw::GLint array_data[4] = { 0, 1, 2, 3 };
3279
3280 gl.genBuffers(1, &m_bo_array);
3281 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
3282
3283 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array);
3284 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
3285
3286 gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data), array_data, GL_STATIC_DRAW);
3287 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
3288
3289 gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a"), 0);
3290 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed.");
3291
3292 gl.vertexAttribIFormat(gl.getAttribLocation(m_po, "a"), 1, GL_INT, 0);
3293 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIFormat call failed.");
3294
3295 gl.bindVertexBuffer(0, m_bo_array, 0, sizeof(glw::GLint));
3296 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexBuffer call failed.");
3297
3298 gl.enableVertexAttribArray(gl.getAttribLocation(m_po, "a"));
3299 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
3300 }
3301
3302 /** @brief Prepare buffer object for test GLSL program transform feedback results.
3303 */
PrepareXFB()3304 void AttributeBindingDivisorTest::PrepareXFB()
3305 {
3306 /* Shortcut for GL functionality */
3307 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3308
3309 /* Buffer creation. */
3310 gl.genBuffers(1, &m_bo_xfb);
3311 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
3312
3313 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
3314 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
3315
3316 /* Preparing storage. */
3317 gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, 4 * sizeof(glw::GLint), NULL, GL_MAP_READ_BIT);
3318 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");
3319
3320 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
3321 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
3322 }
3323
3324 /** @brief Draw number of points and number of instances with XFB environment.
3325 *
3326 * @param [in] number_of_points Number of points to be drawn.
3327 * @param [in] number_of_instances Number of instances to be drawn.
3328 */
Draw(glw::GLuint number_of_points,glw::GLuint number_of_instances)3329 void AttributeBindingDivisorTest::Draw(glw::GLuint number_of_points, glw::GLuint number_of_instances)
3330 {
3331 /* Shortcut for GL functionality */
3332 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3333
3334 /* Setup state. */
3335 gl.beginTransformFeedback(GL_POINTS);
3336 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
3337
3338 /* Draw. */
3339 gl.drawArraysInstanced(GL_POINTS, 0, number_of_points, number_of_instances);
3340 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArraysInstanced call failed.");
3341
3342 /* State reset. */
3343 gl.endTransformFeedback();
3344 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
3345 }
3346
3347 /** @brief Call VertexArrayBindingDivisor on m_vao object and check errors.
3348 *
3349 * @param [in] divisor Divisor to be passed.
3350 *
3351 * @return True if VertexArrayBindingDivisor doe not generate any error, false otherwise.
3352 */
SetDivisor(glw::GLuint divisor)3353 bool AttributeBindingDivisorTest::SetDivisor(glw::GLuint divisor)
3354 {
3355 /* Shortcut for GL functionality */
3356 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3357
3358 /* Setup. */
3359 gl.vertexArrayBindingDivisor(m_vao, 0, divisor);
3360
3361 /* Checking for errors (this is tested function so it fail the test if there is error). */
3362 if (glw::GLenum error = gl.getError())
3363 {
3364 m_context.getTestContext().getLog()
3365 << tcu::TestLog::Message << "VertexArrayBindingDivisor unexpectedl generated " << glu::getErrorStr(error)
3366 << " error when called with divisor" << divisor << ". " << tcu::TestLog::EndMessage;
3367
3368 return false;
3369 }
3370
3371 return true;
3372 }
3373
3374 /** @brief Check transform feedback results and log.
3375 *
3376 * @param [in] count Number of results to be checked.
3377 * @param [in] expected Expected results.
3378 * @param [in] log_message Message to be logged if expected values are not equal to queried.
3379 *
3380 * @return True if expected values are equal to queried, false otherwise.
3381 */
CheckXFB(const glw::GLuint count,const glw::GLint expected[],const glw::GLchar * log_message)3382 bool AttributeBindingDivisorTest::CheckXFB(const glw::GLuint count, const glw::GLint expected[],
3383 const glw::GLchar* log_message)
3384 {
3385 /* Shortcut for GL functionality */
3386 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3387
3388 /* Result setup */
3389 bool is_ok = true;
3390
3391 /* Result query. */
3392 glw::GLint* result = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
3393 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
3394
3395 /* Check result and return. */
3396 for (glw::GLuint i = 0; i < count; ++i)
3397 {
3398 if (expected[i] != result[i])
3399 {
3400 std::string expected_str = "[";
3401 std::string result_str = "[";
3402
3403 for (glw::GLuint j = 0; j < count; ++j)
3404 {
3405 expected_str.append(Utilities::itoa((glw::GLuint)expected[j]));
3406 result_str.append(Utilities::itoa((glw::GLuint)result[j]));
3407
3408 if (j < count - 1)
3409 {
3410 expected_str.append(", ");
3411 result_str.append(", ");
3412 }
3413 else
3414 {
3415 expected_str.append("]");
3416 result_str.append("]");
3417 }
3418 }
3419
3420 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Result is " << result_str << ", but "
3421 << expected_str << " was expected. " << log_message
3422 << tcu::TestLog::EndMessage;
3423
3424 is_ok = false;
3425 break;
3426 }
3427 }
3428
3429 /* Unmaping GL buffer. */
3430 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
3431 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
3432
3433 return is_ok;
3434 }
3435
3436 /** @brief Clean GL objects. */
Clean()3437 void AttributeBindingDivisorTest::Clean()
3438 {
3439 /* Shortcut for GL functionality */
3440 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3441
3442 gl.useProgram(0);
3443
3444 if (m_po)
3445 {
3446 gl.deleteProgram(m_po);
3447
3448 m_po = 0;
3449 }
3450
3451 if (m_vao)
3452 {
3453 gl.deleteVertexArrays(1, &m_vao);
3454
3455 m_vao = 0;
3456 }
3457
3458 if (m_bo_array)
3459 {
3460 gl.deleteBuffers(1, &m_bo_array);
3461
3462 m_bo_array = 0;
3463 }
3464
3465 if (m_bo_xfb)
3466 {
3467 gl.deleteBuffers(1, &m_bo_xfb);
3468
3469 m_bo_xfb = 0;
3470 }
3471
3472 while (gl.getError())
3473 ;
3474 }
3475
3476 const glw::GLchar AttributeBindingDivisorTest::s_vertex_shader[] = "#version 450\n"
3477 "\n"
3478 "in int a;\n"
3479 "out int result;\n"
3480 "\n"
3481 "void main()\n"
3482 "{\n"
3483 " gl_Position = vec4(1.0);\n"
3484 " result = a;"
3485 "}\n";
3486
3487 const glw::GLchar AttributeBindingDivisorTest::s_fragment_shader[] = "#version 450\n"
3488 "\n"
3489 "out vec4 color;\n"
3490 "\n"
3491 "void main()\n"
3492 "{\n"
3493 " color = vec4(1.0);"
3494 "}\n";
3495
3496 /******************************** Get Vertex Array Test Implementation ********************************/
3497
3498 /** @brief Get Vertex Array Test constructor.
3499 *
3500 * @param [in] context OpenGL context.
3501 */
GetVertexArrayTest(deqp::Context & context)3502 GetVertexArrayTest::GetVertexArrayTest(deqp::Context& context)
3503 : deqp::TestCase(context, "vertex_arrays_get_vertex_array", "Get Vertex Array Test")
3504 {
3505 /* Intentionally left blank. */
3506 }
3507
3508 /** @brief Iterate Vertex Array Attribute Binding Divisor Test cases.
3509 *
3510 * @return Iteration result.
3511 */
iterate()3512 tcu::TestNode::IterateResult GetVertexArrayTest::iterate()
3513 {
3514 /* Shortcut for GL functionality. */
3515 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3516
3517 /* Get context setup. */
3518 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
3519 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
3520
3521 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
3522 {
3523 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
3524
3525 return STOP;
3526 }
3527
3528 /* Running tests. */
3529 bool is_ok = true;
3530 bool is_error = false;
3531
3532 /* Test objects. */
3533 glw::GLuint vao = 0;
3534 glw::GLuint bo = 0;
3535
3536 try
3537 {
3538 gl.genVertexArrays(1, &vao);
3539 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
3540
3541 gl.bindVertexArray(vao);
3542 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
3543
3544 gl.genBuffers(1, &bo);
3545 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed.");
3546
3547 gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, bo);
3548 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
3549
3550 glw::GLint result = 0;
3551 gl.getVertexArrayiv(vao, GL_ELEMENT_ARRAY_BUFFER_BINDING, &result);
3552
3553 if (glw::GLenum error = gl.getError())
3554 {
3555 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetVertexArrayiv unexpectedly generated "
3556 << glu::getErrorStr(error) << "error. Test fails."
3557 << tcu::TestLog::EndMessage;
3558
3559 is_ok = false;
3560 }
3561
3562 if ((glw::GLuint)result != bo)
3563 {
3564 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetVertexArrayiv was expected to return "
3565 << bo << ", but " << result << " was observed. Test fails."
3566 << tcu::TestLog::EndMessage;
3567
3568 is_ok = false;
3569 }
3570 }
3571 catch (...)
3572 {
3573 is_ok = false;
3574 is_error = true;
3575 }
3576
3577 /* Cleanup. */
3578 if (vao)
3579 {
3580 gl.deleteVertexArrays(1, &vao);
3581 }
3582
3583 if (bo)
3584 {
3585 gl.deleteBuffers(1, &bo);
3586 }
3587
3588 /* Errors clean up. */
3589 while (gl.getError())
3590 ;
3591
3592 /* Result's setup. */
3593 if (is_ok)
3594 {
3595 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3596 }
3597 else
3598 {
3599 if (is_error)
3600 {
3601 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
3602 }
3603 else
3604 {
3605 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3606 }
3607 }
3608
3609 return STOP;
3610 }
3611
3612 /******************************** Get Vertex Array Test Indexed Implementation ********************************/
3613
3614 /** @brief Get Vertex Array Indexed Test constructor.
3615 *
3616 * @param [in] context OpenGL context.
3617 */
GetVertexArrayIndexedTest(deqp::Context & context)3618 GetVertexArrayIndexedTest::GetVertexArrayIndexedTest(deqp::Context& context)
3619 : deqp::TestCase(context, "vertex_arrays_get_vertex_array_indexed", "Get Vertex Array Indexed Test"), m_vao(0)
3620 {
3621 m_bo[0] = 0;
3622 m_bo[1] = 0;
3623 m_bo[2] = 0;
3624 m_bo[3] = 0;
3625 }
3626
3627 /** @brief Iterate Vertex Array Attribute Binding Divisor Test cases.
3628 *
3629 * @return Iteration result.
3630 */
iterate()3631 tcu::TestNode::IterateResult GetVertexArrayIndexedTest::iterate()
3632 {
3633 /* Shortcut for GL functionality. */
3634 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3635
3636 /* Get context setup. */
3637 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
3638 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
3639
3640 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
3641 {
3642 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
3643
3644 return STOP;
3645 }
3646
3647 /* Running tests. */
3648 bool is_ok = true;
3649 bool is_error = false;
3650
3651 try
3652 {
3653 PrepareVAO();
3654
3655 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 0, GL_TRUE);
3656 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 1, GL_TRUE);
3657 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 2, GL_TRUE);
3658 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 3, GL_TRUE);
3659 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 5, GL_FALSE);
3660
3661 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 0, 0);
3662 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 1, 2);
3663 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 2, 0);
3664 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 3, 8);
3665
3666 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 0, GL_BYTE);
3667 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 1, GL_SHORT);
3668 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 2, GL_FLOAT);
3669 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 3, GL_UNSIGNED_INT_2_10_10_10_REV);
3670
3671 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 0, GL_TRUE);
3672 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 1, GL_FALSE);
3673 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 2, GL_FALSE);
3674 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 3, GL_FALSE);
3675
3676 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 0, GL_FALSE);
3677 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 1, GL_TRUE);
3678 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 2, GL_FALSE);
3679 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 3, GL_FALSE);
3680
3681 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 0, 3);
3682 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 1, 2);
3683 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 2, 1);
3684 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 3, 0);
3685
3686 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 0, GL_FALSE);
3687 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 1, GL_FALSE);
3688 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 2, GL_FALSE);
3689 is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 3, GL_FALSE);
3690
3691 is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 0, 0);
3692 is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 1, 0);
3693 is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 2, 4);
3694 is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 3, 0);
3695
3696 is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 0, 0);
3697 is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 1, 2);
3698 is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 2, 8);
3699 is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 3, 4);
3700 }
3701 catch (...)
3702 {
3703 is_ok = false;
3704 is_error = true;
3705 }
3706
3707 /* Cleanup. */
3708 if (m_vao)
3709 {
3710 gl.deleteVertexArrays(1, &m_vao);
3711
3712 m_vao = 0;
3713 }
3714
3715 if (m_bo[0] || m_bo[1] || m_bo[2] || m_bo[3])
3716 {
3717 gl.deleteBuffers(4, m_bo);
3718
3719 m_bo[0] = 0;
3720 m_bo[1] = 0;
3721 m_bo[2] = 0;
3722 m_bo[3] = 0;
3723 }
3724
3725 /* Errors clean up. */
3726 while (gl.getError())
3727 ;
3728
3729 /* Result's setup. */
3730 if (is_ok)
3731 {
3732 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3733 }
3734 else
3735 {
3736 if (is_error)
3737 {
3738 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
3739 }
3740 else
3741 {
3742 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3743 }
3744 }
3745
3746 return STOP;
3747 }
3748
3749 /** @brief Prepare vertex array object for the test.
3750 */
PrepareVAO()3751 void GetVertexArrayIndexedTest::PrepareVAO()
3752 {
3753 /* Shortcut for GL functionality. */
3754 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3755
3756 gl.genVertexArrays(1, &m_vao);
3757 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
3758
3759 gl.bindVertexArray(m_vao);
3760 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
3761
3762 gl.genBuffers(4, m_bo);
3763 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed.");
3764
3765 /* Attribute 0. */
3766 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[0]);
3767 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
3768
3769 gl.vertexAttribPointer(0, 1, GL_BYTE, GL_TRUE, 0, NULL);
3770 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
3771
3772 gl.enableVertexAttribArray(0);
3773 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
3774
3775 gl.vertexAttribDivisor(0, 3);
3776 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor call failed.");
3777
3778 /* Attribute 1. */
3779 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[1]);
3780 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
3781
3782 gl.vertexAttribIPointer(1, 2, GL_SHORT, 2, glu::BufferOffsetAsPointer(2 * sizeof(glw::GLchar)));
3783 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
3784
3785 gl.enableVertexAttribArray(1);
3786 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
3787
3788 gl.vertexAttribDivisor(1, 2);
3789 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor call failed.");
3790
3791 /* Attribute 2. */
3792 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[2]);
3793 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
3794
3795 gl.vertexAttribBinding(2, 2);
3796 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed.");
3797
3798 gl.vertexAttribFormat(2, 3, GL_FLOAT, GL_FALSE, 4);
3799 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIFormat call failed.");
3800
3801 gl.bindVertexBuffer(2, m_bo[2], 8, 0);
3802 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexBuffer call failed.");
3803
3804 gl.enableVertexAttribArray(2);
3805 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
3806
3807 gl.vertexAttribDivisor(2, 1);
3808 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor call failed.");
3809
3810 /* Attribute 3. */
3811 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[3]);
3812 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
3813
3814 gl.vertexAttribPointer(3, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 8, 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() << tcu::TestLog::Message << "GetVertexArrayIndexediv called with index "
3844 << index << ", with pname" << glu::getVertexAttribParameterNameStr(pname)
3845 << " 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() << tcu::TestLog::Message << "GetVertexArrayIndexediv called with index "
3854 << index << " and with pname" << glu::getVertexAttribParameterNameStr(pname)
3855 << " 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() << tcu::TestLog::Message << "GetVertexArrayIndexed64iv called with index "
3884 << index << ", with pname" << glu::getVertexAttribParameterNameStr(pname)
3885 << " 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() << tcu::TestLog::Message << "GetVertexArrayIndexed64iv called with index "
3894 << index << " and with pname" << glu::getVertexAttribParameterNameStr(pname)
3895 << " 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"), m_vao(0)
3912 {
3913 }
3914
3915 /** @brief Iterate Defaults Test cases.
3916 *
3917 * @return Iteration result.
3918 */
iterate()3919 tcu::TestNode::IterateResult DefaultsTest::iterate()
3920 {
3921 /* Shortcut for GL functionality. */
3922 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3923
3924 /* Get context setup. */
3925 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
3926 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
3927
3928 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
3929 {
3930 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
3931
3932 return STOP;
3933 }
3934
3935 /* Running tests. */
3936 bool is_ok = true;
3937 bool is_error = false;
3938
3939 /* Test objects. */
3940 glw::GLint max_attributes = 8;
3941
3942 try
3943 {
3944 /* Query limits. */
3945 gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_attributes);
3946 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
3947
3948 /* Prepare default Vertex Array Object. */
3949 PrepareVAO();
3950
3951 /* Check default values per attribute index. */
3952 for (glw::GLint i = 0; i < max_attributes; ++i)
3953 {
3954 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_ENABLED, i, GL_FALSE);
3955 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_SIZE, i, 4);
3956 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_STRIDE, i, 0);
3957 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_TYPE, i, GL_FLOAT);
3958 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, i, GL_FALSE);
3959 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_INTEGER, i, GL_FALSE);
3960 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, i, 0);
3961 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_LONG, i, GL_FALSE);
3962 is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, i, 0);
3963 is_ok &= CheckIndexed64(GL_VERTEX_BINDING_OFFSET, i, 0);
3964 }
3965
3966 /* Check default values per vertex array object. */
3967 is_ok &= Check(GL_ELEMENT_ARRAY_BUFFER_BINDING, 0);
3968 }
3969 catch (...)
3970 {
3971 is_ok = false;
3972 is_error = true;
3973 }
3974
3975 /* Cleanup. */
3976 if (m_vao)
3977 {
3978 gl.deleteVertexArrays(1, &m_vao);
3979
3980 m_vao = 0;
3981 }
3982
3983 /* Errors clean up. */
3984 while (gl.getError())
3985 ;
3986
3987 /* Result's setup. */
3988 if (is_ok)
3989 {
3990 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3991 }
3992 else
3993 {
3994 if (is_error)
3995 {
3996 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
3997 }
3998 else
3999 {
4000 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4001 }
4002 }
4003
4004 return STOP;
4005 }
4006
4007 /** @brief Prepare vertex array object for the test.
4008 */
PrepareVAO()4009 void DefaultsTest::PrepareVAO()
4010 {
4011 /* Shortcut for GL functionality. */
4012 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4013
4014 gl.createVertexArrays(1, &m_vao);
4015 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
4016 }
4017
4018 /** @brief Compare value queried using GetVertexArrayiv with expected value and log.
4019 *
4020 * @param [in] pname Parameter to be queried.
4021 * @param [in] expected Expected error.
4022 *
4023 * @return True if value is equal to expected, false otherwise.
4024 */
Check(const glw::GLenum pname,const glw::GLint expected)4025 bool DefaultsTest::Check(const glw::GLenum pname, const glw::GLint expected)
4026 {
4027 /* Shortcut for GL functionality. */
4028 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4029
4030 glw::GLint result = 0;
4031
4032 gl.getVertexArrayiv(m_vao, pname, &result);
4033 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetVertexArrayiv call failed.");
4034
4035 if (result != expected)
4036 {
4037 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Default Vertex Array Object has parameter "
4038 << glu::getVertexAttribParameterNameStr(pname) << " equal to " << result
4039 << ", but " << expected << " was expected. Test fails."
4040 << tcu::TestLog::EndMessage;
4041
4042 return false;
4043 }
4044
4045 return true;
4046 }
4047
4048 /** @brief Compare value queried using GetVertexArrayIndexediv with expected value and log.
4049 *
4050 * @param [in] pname Parameter to be queried.
4051 * @param [in] index Index to be queried.
4052 * @param [in] expected Expected error.
4053 *
4054 * @return True if value is equal to expected, false otherwise.
4055 */
CheckIndexed(const glw::GLenum pname,const glw::GLuint index,const glw::GLint expected)4056 bool DefaultsTest::CheckIndexed(const glw::GLenum pname, const glw::GLuint index, const glw::GLint expected)
4057 {
4058 /* Shortcut for GL functionality. */
4059 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4060
4061 glw::GLint result = 0;
4062
4063 gl.getVertexArrayIndexediv(m_vao, index, pname, &result);
4064 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetVertexArrayIndexediv call failed.");
4065
4066 if (result != expected)
4067 {
4068 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Default Vertex Array Object at index " << index
4069 << " has parameter " << glu::getVertexAttribParameterNameStr(pname)
4070 << " equal to " << result << ", but " << expected
4071 << " was expected. Test fails." << tcu::TestLog::EndMessage;
4072
4073 return false;
4074 }
4075
4076 return true;
4077 }
4078
4079 /** @brief Compare value queried using GetVertexArrayIndexed64iv with expected value and log.
4080 *
4081 * @param [in] pname Parameter to be queried.
4082 * @param [in] index Index to be queried.
4083 * @param [in] expected Expected error.
4084 *
4085 * @return True if value is equal to expected, false otherwise.
4086 */
CheckIndexed64(const glw::GLenum pname,const glw::GLuint index,const glw::GLint64 expected)4087 bool DefaultsTest::CheckIndexed64(const glw::GLenum pname, const glw::GLuint index, const glw::GLint64 expected)
4088 {
4089 /* Shortcut for GL functionality. */
4090 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4091
4092 glw::GLint64 result = 0;
4093
4094 gl.getVertexArrayIndexed64iv(m_vao, index, pname, &result);
4095 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetVertexArrayIndexed64iv call failed.");
4096
4097 if (result != expected)
4098 {
4099 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Default Vertex Array Object at index " << index
4100 << " has parameter " << glu::getVertexAttribParameterNameStr(pname)
4101 << " equal to " << result << ", but " << expected
4102 << " was expected. Test fails." << tcu::TestLog::EndMessage;
4103
4104 return false;
4105 }
4106
4107 return true;
4108 }
4109
4110 /******************************** Creation Error Test Implementation ********************************/
4111
4112 /** @brief Creation Error Test constructor.
4113 *
4114 * @param [in] context OpenGL context.
4115 */
CreationErrorTest(deqp::Context & context)4116 CreationErrorTest::CreationErrorTest(deqp::Context& context)
4117 : deqp::TestCase(context, "vertex_arrays_creation_error", "Creation Error Test")
4118 {
4119 }
4120
4121 /** @brief Iterate Creation Error Test cases.
4122 *
4123 * @return Iteration result.
4124 */
iterate()4125 tcu::TestNode::IterateResult CreationErrorTest::iterate()
4126 {
4127 /* Shortcut for GL functionality. */
4128 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4129
4130 /* Get context setup. */
4131 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
4132 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
4133
4134 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
4135 {
4136 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
4137
4138 return STOP;
4139 }
4140
4141 /* Running tests. */
4142 bool is_ok = true;
4143 bool is_error = false;
4144
4145 try
4146 {
4147 glw::GLuint negative_vao = 0;
4148
4149 gl.createVertexArrays(-1, &negative_vao);
4150
4151 is_ok = CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated if n is negative.");
4152 }
4153 catch (...)
4154 {
4155 is_ok = false;
4156 is_error = true;
4157 }
4158
4159 /* Errors clean up. */
4160 while (gl.getError())
4161 ;
4162
4163 /* Result's setup. */
4164 if (is_ok)
4165 {
4166 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4167 }
4168 else
4169 {
4170 if (is_error)
4171 {
4172 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
4173 }
4174 else
4175 {
4176 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4177 }
4178 }
4179
4180 return STOP;
4181 }
4182
4183 /** @brief Compare error returned by GL with expected value and log.
4184 *
4185 * @param [in] expected Expected error.
4186 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one.
4187 *
4188 * @return True if GL error is equal to expected, false otherwise.
4189 */
CheckError(const glw::GLenum expected,const glw::GLchar * log_message)4190 bool CreationErrorTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
4191 {
4192 /* Shortcut for GL functionality. */
4193 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4194
4195 glw::GLenum error = 0;
4196
4197 if (expected != (error = gl.getError()))
4198 {
4199 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
4200 << "was observed instead." << tcu::TestLog::EndMessage;
4201
4202 return false;
4203 }
4204
4205 return true;
4206 }
4207
4208 /******************************** Enable Disable Attribute Errors Test Implementation ********************************/
4209
4210 /** @brief Enable Disable Attribute Errors Test constructor.
4211 *
4212 * @param [in] context OpenGL context.
4213 */
EnableDisableAttributeErrorsTest(deqp::Context & context)4214 EnableDisableAttributeErrorsTest::EnableDisableAttributeErrorsTest(deqp::Context& context)
4215 : deqp::TestCase(context, "vertex_arrays_enable_disable_attribute_errors", "Enable Disable Attribute Errors Test")
4216 {
4217 }
4218
4219 /** @brief Enable Disable Attribute Errors Test cases.
4220 *
4221 * @return Iteration result.
4222 */
iterate()4223 tcu::TestNode::IterateResult EnableDisableAttributeErrorsTest::iterate()
4224 {
4225 /* Shortcut for GL functionality. */
4226 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4227
4228 /* Get context setup. */
4229 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
4230 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
4231
4232 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
4233 {
4234 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
4235
4236 return STOP;
4237 }
4238
4239 /* Running tests. */
4240 bool is_ok = true;
4241 bool is_error = false;
4242
4243 /* Test objects. */
4244 glw::GLint max_attributes = 8;
4245
4246 /* Tested VAOs. */
4247 glw::GLuint vao = 0;
4248 glw::GLuint not_a_vao = 0;
4249 try
4250 {
4251 /* Query limits. */
4252 gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_attributes);
4253 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
4254
4255 /* Prepare valid VAO. */
4256 gl.createVertexArrays(1, &vao);
4257 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
4258
4259 /* Prepare invalid VAO. */
4260 while (gl.isVertexArray(++not_a_vao))
4261 ;
4262
4263 /* Test not a VAO. */
4264 gl.enableVertexArrayAttrib(0, not_a_vao);
4265
4266 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by EnableVertexArrayAttrib if "
4267 "vaobj is not the name of an existing vertex array object.");
4268
4269 gl.disableVertexArrayAttrib(0, not_a_vao);
4270
4271 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by DisableVertexArrayAttrib if "
4272 "vaobj is not the name of an existing vertex array object.");
4273
4274 /* Test to big attribute index. */
4275 gl.enableVertexArrayAttrib(max_attributes, vao);
4276
4277 is_ok &= CheckError(
4278 GL_INVALID_OPERATION,
4279 "INVALID_VALUE was not generated by EnableVertexArrayAttrib if index is equal to MAX_VERTEX_ATTRIBS.");
4280
4281 gl.disableVertexArrayAttrib(max_attributes, vao);
4282
4283 is_ok &= CheckError(
4284 GL_INVALID_OPERATION,
4285 "INVALID_VALUE was not generated by DisableVertexArrayAttrib if index is equal to MAX_VERTEX_ATTRIBS.");
4286
4287 gl.enableVertexArrayAttrib(max_attributes + 1, vao);
4288
4289 is_ok &= CheckError(
4290 GL_INVALID_OPERATION,
4291 "INVALID_VALUE was not generated by EnableVertexArrayAttrib if index is greater than MAX_VERTEX_ATTRIBS.");
4292
4293 gl.disableVertexArrayAttrib(max_attributes + 1, vao);
4294
4295 is_ok &= CheckError(
4296 GL_INVALID_OPERATION,
4297 "INVALID_VALUE was not generated by DisableVertexArrayAttrib if index is greater than MAX_VERTEX_ATTRIBS.");
4298 }
4299 catch (...)
4300 {
4301 is_ok = false;
4302 is_error = true;
4303 }
4304
4305 /* Clean up. */
4306 if (vao)
4307 {
4308 gl.deleteVertexArrays(1, &vao);
4309 }
4310
4311 /* Errors clean up. */
4312 while (gl.getError())
4313 ;
4314
4315 /* Result's setup. */
4316 if (is_ok)
4317 {
4318 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4319 }
4320 else
4321 {
4322 if (is_error)
4323 {
4324 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
4325 }
4326 else
4327 {
4328 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4329 }
4330 }
4331
4332 return STOP;
4333 }
4334
4335 /** @brief Compare error returned by GL with expected value and log.
4336 *
4337 * @param [in] expected Expected error.
4338 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one.
4339 *
4340 * @return True if GL error is equal to expected, false otherwise.
4341 */
CheckError(const glw::GLenum expected,const glw::GLchar * log_message)4342 bool EnableDisableAttributeErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
4343 {
4344 /* Shortcut for GL functionality. */
4345 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4346
4347 glw::GLenum error = 0;
4348
4349 if (expected != (error = gl.getError()))
4350 {
4351 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
4352 << "was observed instead." << tcu::TestLog::EndMessage;
4353
4354 return false;
4355 }
4356
4357 return true;
4358 }
4359
4360 /******************************** Element Buffer Errors Test Implementation ********************************/
4361
4362 /** @brief Element Buffer Errors Test constructor.
4363 *
4364 * @param [in] context OpenGL context.
4365 */
ElementBufferErrorsTest(deqp::Context & context)4366 ElementBufferErrorsTest::ElementBufferErrorsTest(deqp::Context& context)
4367 : deqp::TestCase(context, "vertex_arrays_element_buffer_errors", "Element Buffer Errors Test")
4368 {
4369 }
4370
4371 /** @brief Element Buffer Errors Test cases.
4372 *
4373 * @return Iteration result.
4374 */
iterate()4375 tcu::TestNode::IterateResult ElementBufferErrorsTest::iterate()
4376 {
4377 /* Shortcut for GL functionality. */
4378 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4379
4380 /* Get context setup. */
4381 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
4382 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
4383
4384 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
4385 {
4386 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
4387
4388 return STOP;
4389 }
4390
4391 /* Running tests. */
4392 bool is_ok = true;
4393 bool is_error = false;
4394
4395 /* Tested Objects. */
4396 glw::GLuint vao = 0;
4397 glw::GLuint not_a_vao = 0;
4398 glw::GLuint bo = 0;
4399 glw::GLuint not_a_bo = 0;
4400
4401 try
4402 {
4403 /* Prepare valid Objects. */
4404 gl.createVertexArrays(1, &vao);
4405 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
4406
4407 gl.createBuffers(1, &bo);
4408 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed.");
4409
4410 /* Prepare invalid VAO. */
4411 while (gl.isVertexArray(++not_a_vao))
4412 ;
4413 while (gl.isBuffer(++not_a_bo))
4414 ;
4415
4416 /* Test not a VAO. */
4417 gl.vertexArrayElementBuffer(not_a_vao, bo);
4418
4419 is_ok &=
4420 CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error was not generated by VertexArrayElementBuffer if "
4421 "vaobj is not the name of an existing vertex array object.");
4422
4423 /* Test not a BO. */
4424 gl.vertexArrayElementBuffer(vao, not_a_bo);
4425
4426 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error is generated by VertexArrayElementBuffer if "
4427 "buffer is not zero or the name of an existing buffer object.");
4428 }
4429 catch (...)
4430 {
4431 is_ok = false;
4432 is_error = true;
4433 }
4434
4435 /* Clean up. */
4436 if (vao)
4437 {
4438 gl.deleteVertexArrays(1, &vao);
4439 }
4440
4441 if (bo)
4442 {
4443 gl.deleteBuffers(1, &bo);
4444 }
4445
4446 /* Errors clean up. */
4447 while (gl.getError())
4448 ;
4449
4450 /* Result's setup. */
4451 if (is_ok)
4452 {
4453 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4454 }
4455 else
4456 {
4457 if (is_error)
4458 {
4459 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
4460 }
4461 else
4462 {
4463 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4464 }
4465 }
4466
4467 return STOP;
4468 }
4469
4470 /** @brief Compare error returned by GL with expected value and log.
4471 *
4472 * @param [in] expected Expected error.
4473 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one.
4474 *
4475 * @return True if GL error is equal to expected, false otherwise.
4476 */
CheckError(const glw::GLenum expected,const glw::GLchar * log_message)4477 bool ElementBufferErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
4478 {
4479 /* Shortcut for GL functionality. */
4480 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4481
4482 glw::GLenum error = 0;
4483
4484 if (expected != (error = gl.getError()))
4485 {
4486 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
4487 << " was observed instead." << tcu::TestLog::EndMessage;
4488
4489 return false;
4490 }
4491
4492 return true;
4493 }
4494
4495 /******************************** Vertex Buffers Errors Test Implementation ********************************/
4496
4497 /** @brief Vertex Buffers Errors Test constructor.
4498 *
4499 * @param [in] context OpenGL context.
4500 */
VertexBuffersErrorsTest(deqp::Context & context)4501 VertexBuffersErrorsTest::VertexBuffersErrorsTest(deqp::Context& context)
4502 : deqp::TestCase(context, "vertex_arrays_vertex_buffers_errors", "Vertex Buffers Errors Test")
4503 {
4504 }
4505
4506 /** @brief Vertex Buffers Errors Test cases.
4507 *
4508 * @return Iteration result.
4509 */
iterate()4510 tcu::TestNode::IterateResult VertexBuffersErrorsTest::iterate()
4511 {
4512 /* Shortcut for GL functionality. */
4513 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4514
4515 /* Get context setup. */
4516 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
4517 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
4518
4519 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
4520 {
4521 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
4522
4523 return STOP;
4524 }
4525
4526 /* Running tests. */
4527 bool is_ok = true;
4528 bool is_error = false;
4529
4530 /* Tested Objects. */
4531 glw::GLuint vao = 0;
4532 glw::GLuint not_a_vao = 0;
4533 glw::GLuint bo = 0;
4534 glw::GLuint not_a_bo = 0;
4535
4536 /* Valid setup. */
4537 glw::GLintptr valid_offset = 0;
4538 glw::GLsizei valid_stride = 1;
4539
4540 /* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */
4541 glw::GLint max_vertex_attrib_bindings = 16;
4542 glw::GLint max_vertex_attrib_stride = 2048;
4543
4544 try
4545 {
4546 /* Prepare valid Objects. */
4547 gl.createVertexArrays(1, &vao);
4548 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
4549
4550 gl.createBuffers(1, &bo);
4551 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed.");
4552
4553 /* Prepare invalid VAO. */
4554 while (gl.isVertexArray(++not_a_vao))
4555 ;
4556 while (gl.isBuffer(++not_a_bo))
4557 ;
4558
4559 /* Prepare limits. */
4560 gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_vertex_attrib_bindings);
4561 gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, &max_vertex_attrib_stride);
4562 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
4563
4564 /* Invalid setup. */
4565 glw::GLintptr invalid_offset = -1;
4566 glw::GLsizei invalid_stride_0 = -1;
4567 glw::GLsizei invalid_stride_1 = max_vertex_attrib_stride + 1;
4568
4569 /* Test not a VAO. */
4570 gl.vertexArrayVertexBuffer(not_a_vao, 0, bo, valid_offset, valid_stride);
4571
4572 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffer if "
4573 "vaobj is not the name of an existing vertex array object.");
4574
4575 gl.vertexArrayVertexBuffers(not_a_vao, 0, 1, &bo, &valid_offset, &valid_stride);
4576
4577 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffers if "
4578 "vaobj is not the name of an existing vertex array object.");
4579
4580 /* Test not a BO. */
4581 gl.vertexArrayVertexBuffer(vao, 0, not_a_bo, valid_offset, valid_stride);
4582
4583 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffer if "
4584 "vaobj is not the name of an existing vertex array object.");
4585
4586 gl.vertexArrayVertexBuffers(vao, 0, 1, ¬_a_bo, &valid_offset, &valid_stride);
4587
4588 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffers if "
4589 "vaobj is not the name of an existing vertex array object.");
4590
4591 /* Test too big binding index. */
4592 gl.vertexArrayVertexBuffer(vao, max_vertex_attrib_bindings, bo, valid_offset, valid_stride);
4593
4594 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayVertexBuffer if "
4595 "bindingindex is equal to the value of MAX_VERTEX_ATTRIB_BINDINGS.");
4596
4597 gl.vertexArrayVertexBuffer(vao, max_vertex_attrib_bindings + 1, bo, valid_offset, valid_stride);
4598
4599 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayVertexBuffer if "
4600 "bindingindex is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS.");
4601
4602 gl.vertexArrayVertexBuffers(vao, max_vertex_attrib_bindings, 1, &bo, &valid_offset, &valid_stride);
4603
4604 is_ok &=
4605 CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffers if "
4606 "first+count is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS.");
4607
4608 /* Test too big stride. */
4609 gl.vertexArrayVertexBuffer(vao, 0, bo, -1, valid_stride);
4610
4611 is_ok &= CheckError(GL_INVALID_VALUE,
4612 "INVALID_VALUE is generated by VertexArrayVertexBuffer if offset less than zero.");
4613
4614 gl.vertexArrayVertexBuffer(vao, 0, bo, valid_offset, -1);
4615
4616 is_ok &= CheckError(GL_INVALID_VALUE,
4617 "INVALID_VALUE is generated by VertexArrayVertexBuffer if stride is less than zero.");
4618
4619 gl.vertexArrayVertexBuffer(vao, 0, bo, valid_offset, max_vertex_attrib_stride + 1);
4620
4621 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE is generated by VertexArrayVertexBuffer if stride is "
4622 "greater than the value of MAX_VERTEX_ATTRIB_STRIDE.");
4623
4624 gl.vertexArrayVertexBuffers(vao, 0, 1, &bo, &invalid_offset, &valid_stride);
4625
4626 is_ok &=
4627 CheckError(GL_INVALID_VALUE,
4628 "INVALID_VALUE is generated by VertexArrayVertexBuffers if any value in offsets is negative.");
4629
4630 gl.vertexArrayVertexBuffers(vao, 0, 1, &bo, &valid_offset, &invalid_stride_0);
4631
4632 is_ok &=
4633 CheckError(GL_INVALID_VALUE,
4634 "INVALID_VALUE is generated by VertexArrayVertexBuffers if any value in strides is negative.");
4635
4636 gl.vertexArrayVertexBuffers(vao, 0, 1, &bo, &valid_offset, &invalid_stride_1);
4637
4638 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE is generated by VertexArrayVertexBuffers if a value in "
4639 "strides is greater than the value of MAX_VERTEX_ATTRIB_STRIDE.");
4640 }
4641 catch (...)
4642 {
4643 is_ok = false;
4644 is_error = true;
4645 }
4646
4647 /* Clean up. */
4648 if (vao)
4649 {
4650 gl.deleteVertexArrays(1, &vao);
4651 }
4652
4653 if (bo)
4654 {
4655 gl.deleteBuffers(1, &bo);
4656 }
4657
4658 /* Errors clean up. */
4659 while (gl.getError())
4660 ;
4661
4662 /* Result's setup. */
4663 if (is_ok)
4664 {
4665 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4666 }
4667 else
4668 {
4669 if (is_error)
4670 {
4671 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
4672 }
4673 else
4674 {
4675 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4676 }
4677 }
4678
4679 return STOP;
4680 }
4681
4682 /** @brief Compare error returned by GL with expected value and log.
4683 *
4684 * @param [in] expected Expected error.
4685 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one.
4686 *
4687 * @return True if GL error is equal to expected, false otherwise.
4688 */
CheckError(const glw::GLenum expected,const glw::GLchar * log_message)4689 bool VertexBuffersErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
4690 {
4691 /* Shortcut for GL functionality. */
4692 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4693
4694 glw::GLenum error = 0;
4695
4696 if (expected != (error = gl.getError()))
4697 {
4698 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
4699 << " was observed instead." << tcu::TestLog::EndMessage;
4700
4701 return false;
4702 }
4703
4704 return true;
4705 }
4706
4707 /******************************** Attribute Format Errors Test Implementation ********************************/
4708
4709 /** @brief Attribute Format Errors Test constructor.
4710 *
4711 * @param [in] context OpenGL context.
4712 */
AttributeFormatErrorsTest(deqp::Context & context)4713 AttributeFormatErrorsTest::AttributeFormatErrorsTest(deqp::Context& context)
4714 : deqp::TestCase(context, "vertex_arrays_attribute_format_errors", "Attribute Format Errors Test")
4715 {
4716 }
4717
4718 /** @brief Attribute Format Errors Test cases.
4719 *
4720 * @return Iteration result.
4721 */
iterate()4722 tcu::TestNode::IterateResult AttributeFormatErrorsTest::iterate()
4723 {
4724 /* Shortcut for GL functionality. */
4725 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4726
4727 /* Get context setup. */
4728 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
4729 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
4730
4731 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
4732 {
4733 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
4734
4735 return STOP;
4736 }
4737
4738 /* Running tests. */
4739 bool is_ok = true;
4740 bool is_error = false;
4741
4742 /* Tested Objects. */
4743 glw::GLuint vao = 0;
4744 glw::GLuint not_a_vao = 0;
4745
4746 /* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */
4747 glw::GLint max_vertex_attribs = 16;
4748 glw::GLint max_vertex_attrib_relative_offset = 2047;
4749
4750 /* Invalid values. */
4751 glw::GLenum bad_type = 0;
4752
4753 static const glw::GLenum accepted_types[] = { GL_BYTE,
4754 GL_SHORT,
4755 GL_INT,
4756 GL_FIXED,
4757 GL_FLOAT,
4758 GL_HALF_FLOAT,
4759 GL_DOUBLE,
4760 GL_UNSIGNED_BYTE,
4761 GL_UNSIGNED_SHORT,
4762 GL_UNSIGNED_INT,
4763 GL_INT_2_10_10_10_REV,
4764 GL_UNSIGNED_INT_2_10_10_10_REV,
4765 GL_UNSIGNED_INT_10F_11F_11F_REV };
4766
4767 {
4768 bool is_accepted_type = true;
4769 while (is_accepted_type)
4770 {
4771 bad_type++;
4772 is_accepted_type = false;
4773 for (glw::GLuint i = 0; i < DE_LENGTH_OF_ARRAY(accepted_types); ++i)
4774 {
4775 if (accepted_types[i] == bad_type)
4776 {
4777 is_accepted_type = true;
4778 break;
4779 }
4780 }
4781 }
4782 }
4783
4784 try
4785 {
4786 /* Prepare valid Objects. */
4787 gl.createVertexArrays(1, &vao);
4788 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
4789
4790 /* Prepare invalid VAO. */
4791 while (gl.isVertexArray(++not_a_vao))
4792 ;
4793
4794 /* Prepare limits. */
4795 gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs);
4796 gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &max_vertex_attrib_relative_offset);
4797 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
4798
4799 /* TESTS OF VERTEXARRAYATTRIBFORMAT */
4800
4801 /* MAX_VERTEX_ATTRIBS < */
4802 gl.vertexArrayAttribFormat(vao, max_vertex_attribs, 1, GL_BYTE, GL_FALSE, 0);
4803
4804 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribFormat if "
4805 "attribindex is equal to the value of MAX_VERTEX_ATTRIBS.");
4806
4807 gl.vertexArrayAttribFormat(vao, max_vertex_attribs + 1, 1, GL_BYTE, GL_FALSE, 0);
4808
4809 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribFormat if "
4810 "attribindex is greater than the value of MAX_VERTEX_ATTRIBS.");
4811
4812 gl.vertexArrayAttribIFormat(vao, max_vertex_attribs, 1, GL_BYTE, 0);
4813
4814 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if "
4815 "attribindex is equal to the value of MAX_VERTEX_ATTRIBS.");
4816
4817 gl.vertexArrayAttribIFormat(vao, max_vertex_attribs + 1, 1, GL_BYTE, 0);
4818
4819 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if "
4820 "attribindex is greater than the value of MAX_VERTEX_ATTRIBS.");
4821
4822 gl.vertexArrayAttribLFormat(vao, max_vertex_attribs, 1, GL_DOUBLE, 0);
4823
4824 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if "
4825 "attribindex is equal to the value of MAX_VERTEX_ATTRIBS.");
4826
4827 gl.vertexArrayAttribLFormat(vao, max_vertex_attribs + 1, 1, GL_DOUBLE, 0);
4828
4829 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if "
4830 "attribindex is greater than the value of MAX_VERTEX_ATTRIBS.");
4831
4832 /* size */
4833 gl.vertexArrayAttribFormat(vao, 0, 0, GL_BYTE, GL_FALSE, 0);
4834
4835 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttrib*Format if size is "
4836 "not one of the accepted values (0).");
4837
4838 gl.vertexArrayAttribFormat(vao, 0, 5, GL_BYTE, GL_FALSE, 0);
4839
4840 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttrib*Format if size is "
4841 "not one of the accepted values (5).");
4842
4843 gl.vertexArrayAttribIFormat(vao, 0, 0, GL_BYTE, 0);
4844
4845 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if size is "
4846 "not one of the accepted values (0).");
4847
4848 gl.vertexArrayAttribIFormat(vao, 0, 5, GL_BYTE, 0);
4849
4850 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if size is "
4851 "not one of the accepted values (5).");
4852
4853 gl.vertexArrayAttribLFormat(vao, 0, 0, GL_DOUBLE, 0);
4854
4855 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if size is "
4856 "not one of the accepted values (0).");
4857
4858 gl.vertexArrayAttribLFormat(vao, 0, 5, GL_DOUBLE, 0);
4859
4860 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if size is "
4861 "not one of the accepted values (5).");
4862
4863 /* relative offset */
4864 gl.vertexArrayAttribFormat(vao, 0, 1, GL_BYTE, GL_FALSE, max_vertex_attrib_relative_offset + 1);
4865
4866 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttrib*Format if "
4867 "relativeoffset is greater than the value of "
4868 "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");
4869
4870 gl.vertexArrayAttribIFormat(vao, 0, 1, GL_BYTE, max_vertex_attrib_relative_offset + 1);
4871
4872 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if "
4873 "relativeoffset is greater than the value of "
4874 "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");
4875
4876 gl.vertexArrayAttribLFormat(vao, 0, 1, GL_DOUBLE, max_vertex_attrib_relative_offset + 1);
4877
4878 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if "
4879 "relativeoffset is greater than the value of "
4880 "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");
4881
4882 /* type */
4883 gl.vertexArrayAttribFormat(vao, 0, 1, bad_type, GL_FALSE, 0);
4884
4885 is_ok &= CheckError(
4886 GL_INVALID_ENUM,
4887 "INVALID_ENUM was not generated by VertexArrayAttribFormat if type is not one of the accepted tokens.");
4888
4889 gl.vertexArrayAttribIFormat(vao, 0, 1, bad_type, 0);
4890
4891 is_ok &= CheckError(
4892 GL_INVALID_ENUM,
4893 "INVALID_ENUM was not generated by VertexArrayAttribIFormat if type is not one of the accepted tokens.");
4894
4895 gl.vertexArrayAttribLFormat(vao, 0, 1, bad_type, 0);
4896
4897 is_ok &= CheckError(
4898 GL_INVALID_ENUM,
4899 "INVALID_ENUM was not generated by VertexArrayAttribLFormat if type is not one of the accepted tokens.");
4900
4901 /* type UNSIGNED_INT_10F_11F_11F_REV case */
4902 gl.vertexArrayAttribIFormat(vao, 0, 1, GL_UNSIGNED_INT_10F_11F_11F_REV, 0);
4903
4904 is_ok &= CheckError(
4905 GL_INVALID_ENUM,
4906 "INVALID_ENUM was not generated by VertexArrayAttribIFormat if type is UNSIGNED_INT_10F_11F_11F_REV.");
4907
4908 gl.vertexArrayAttribLFormat(vao, 0, 1, GL_UNSIGNED_INT_10F_11F_11F_REV, 0);
4909
4910 is_ok &= CheckError(
4911 GL_INVALID_ENUM,
4912 "INVALID_ENUM was not generated by VertexArrayAttribLFormat if type is UNSIGNED_INT_10F_11F_11F_REV.");
4913
4914 /* Test not a VAO. */
4915 gl.vertexArrayAttribFormat(not_a_vao, 0, 1, GL_BYTE, GL_FALSE, 0);
4916
4917 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if "
4918 "vaobj is not the name of an existing vertex array object.");
4919
4920 gl.vertexArrayAttribIFormat(not_a_vao, 0, 1, GL_BYTE, 0);
4921
4922 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribIFormat if "
4923 "vaobj is not the name of an existing vertex array object.");
4924
4925 gl.vertexArrayAttribLFormat(not_a_vao, 0, 1, GL_DOUBLE, 0);
4926
4927 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribLFormat if "
4928 "vaobj is not the name of an existing vertex array object.");
4929
4930 /* BGRA */
4931 gl.vertexArrayAttribFormat(vao, 0, GL_BGRA, GL_BYTE, GL_TRUE, 0);
4932
4933 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if "
4934 "size is BGRA and type is not UNSIGNED_BYTE, INT_2_10_10_10_REV or "
4935 "UNSIGNED_INT_2_10_10_10_REV.");
4936
4937 gl.vertexArrayAttribFormat(vao, 0, 1, GL_INT_2_10_10_10_REV, GL_TRUE, 0);
4938
4939 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if "
4940 "type is INT_2_10_10_10_REV and size is neither 4 nor BGRA.");
4941
4942 gl.vertexArrayAttribFormat(vao, 0, 1, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 0);
4943
4944 is_ok &=
4945 CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if type "
4946 "is UNSIGNED_INT_2_10_10_10_REV and size is neither 4 nor BGRA.");
4947
4948 gl.vertexArrayAttribFormat(vao, 0, 1, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_TRUE, 0);
4949
4950 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if "
4951 "type is UNSIGNED_INT_10F_11F_11F_REV and size is not 3.");
4952
4953 gl.vertexArrayAttribFormat(vao, 0, GL_BGRA, GL_UNSIGNED_BYTE, GL_FALSE, 0);
4954
4955 is_ok &= CheckError(
4956 GL_INVALID_OPERATION,
4957 "INVALID_OPERATION was not generated by VertexArrayAttribFormat if size is BGRA and normalized is FALSE.");
4958 }
4959 catch (...)
4960 {
4961 is_ok = false;
4962 is_error = true;
4963 }
4964
4965 /* Clean up. */
4966 if (vao)
4967 {
4968 gl.deleteVertexArrays(1, &vao);
4969 }
4970
4971 /* Errors clean up. */
4972 while (gl.getError())
4973 ;
4974
4975 /* Result's setup. */
4976 if (is_ok)
4977 {
4978 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4979 }
4980 else
4981 {
4982 if (is_error)
4983 {
4984 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
4985 }
4986 else
4987 {
4988 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4989 }
4990 }
4991
4992 return STOP;
4993 }
4994
4995 /** @brief Compare error returned by GL with expected value and log.
4996 *
4997 * @param [in] expected Expected error.
4998 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one.
4999 *
5000 * @return True if GL error is equal to expected, false otherwise.
5001 */
CheckError(const glw::GLenum expected,const glw::GLchar * log_message)5002 bool AttributeFormatErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
5003 {
5004 /* Shortcut for GL functionality. */
5005 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5006
5007 glw::GLenum error = 0;
5008
5009 if (expected != (error = gl.getError()))
5010 {
5011 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
5012 << " was observed instead." << tcu::TestLog::EndMessage;
5013
5014 return false;
5015 }
5016
5017 return true;
5018 }
5019
5020 /******************************** Attribute Binding Errors Test Implementation ********************************/
5021
5022 /** @brief Attribute Binding Errors Test constructor.
5023 *
5024 * @param [in] context OpenGL context.
5025 */
AttributeBindingErrorsTest(deqp::Context & context)5026 AttributeBindingErrorsTest::AttributeBindingErrorsTest(deqp::Context& context)
5027 : deqp::TestCase(context, "vertex_arrays_attribute_binding_errors", "Attribute Binding Errors Test")
5028 {
5029 }
5030
5031 /** @brief Attribute Binding Errors Test cases.
5032 *
5033 * @return Iteration result.
5034 */
iterate()5035 tcu::TestNode::IterateResult AttributeBindingErrorsTest::iterate()
5036 {
5037 /* Shortcut for GL functionality. */
5038 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5039
5040 /* Get context setup. */
5041 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
5042 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
5043
5044 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
5045 {
5046 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
5047
5048 return STOP;
5049 }
5050
5051 /* Running tests. */
5052 bool is_ok = true;
5053 bool is_error = false;
5054
5055 /* Tested Objects. */
5056 glw::GLuint vao = 0;
5057 glw::GLuint not_a_vao = 0;
5058
5059 /* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */
5060 glw::GLint max_vertex_attribs = 16;
5061 glw::GLint max_vertex_attrib_bindings = 16;
5062
5063 try
5064 {
5065 /* Prepare valid Objects. */
5066 gl.createVertexArrays(1, &vao);
5067 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
5068
5069 /* Prepare invalid VAO. */
5070 while (gl.isVertexArray(++not_a_vao))
5071 ;
5072
5073 /* Prepare limits. */
5074 gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs);
5075 gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_vertex_attrib_bindings);
5076 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
5077
5078 /* Not a VAO. */
5079 gl.vertexArrayAttribBinding(not_a_vao, 0, 0);
5080
5081 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribBinding if "
5082 "vaobj is not the name of an existing vertex array object.");
5083
5084 /* Too big attribute index. */
5085 gl.vertexArrayAttribBinding(vao, max_vertex_attribs, 0);
5086
5087 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if "
5088 "attribindex is equal to the value of MAX_VERTEX_ATTRIBS.");
5089
5090 gl.vertexArrayAttribBinding(vao, max_vertex_attribs + 1, 0);
5091
5092 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if "
5093 "attribindex is greater than the value of MAX_VERTEX_ATTRIBS.");
5094
5095 /* Too big binding index. */
5096 gl.vertexArrayAttribBinding(vao, 0, max_vertex_attrib_bindings);
5097
5098 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if "
5099 "bindingindex is equal to the value of MAX_VERTEX_ATTRIB_BINDINGS.");
5100
5101 gl.vertexArrayAttribBinding(vao, 0, max_vertex_attrib_bindings + 1);
5102
5103 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if "
5104 "bindingindex is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS.");
5105 }
5106 catch (...)
5107 {
5108 is_ok = false;
5109 is_error = true;
5110 }
5111
5112 /* Clean up. */
5113 if (vao)
5114 {
5115 gl.deleteVertexArrays(1, &vao);
5116 }
5117
5118 /* Errors clean up. */
5119 while (gl.getError())
5120 ;
5121
5122 /* Result's setup. */
5123 if (is_ok)
5124 {
5125 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5126 }
5127 else
5128 {
5129 if (is_error)
5130 {
5131 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
5132 }
5133 else
5134 {
5135 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5136 }
5137 }
5138
5139 return STOP;
5140 }
5141
5142 /** @brief Compare error returned by GL with expected value and log.
5143 *
5144 * @param [in] expected Expected error.
5145 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one.
5146 *
5147 * @return True if GL error is equal to expected, false otherwise.
5148 */
CheckError(const glw::GLenum expected,const glw::GLchar * log_message)5149 bool AttributeBindingErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
5150 {
5151 /* Shortcut for GL functionality. */
5152 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5153
5154 glw::GLenum error = 0;
5155
5156 if (expected != (error = gl.getError()))
5157 {
5158 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
5159 << " was observed instead." << tcu::TestLog::EndMessage;
5160
5161 return false;
5162 }
5163
5164 return true;
5165 }
5166
5167 /******************************** Attribute Binding Divisor Errors Test Implementation ********************************/
5168
5169 /** @brief Attribute Binding Divisor Errors Test constructor.
5170 *
5171 * @param [in] context OpenGL context.
5172 */
AttributeBindingDivisorErrorsTest(deqp::Context & context)5173 AttributeBindingDivisorErrorsTest::AttributeBindingDivisorErrorsTest(deqp::Context& context)
5174 : deqp::TestCase(context, "vertex_arrays_attribute_binding_divisor_errors", "Attribute Binding Divisor Errors Test")
5175 {
5176 }
5177
5178 /** @brief Attribute Binding Divisor Errors Test cases.
5179 *
5180 * @return Iteration result.
5181 */
iterate()5182 tcu::TestNode::IterateResult AttributeBindingDivisorErrorsTest::iterate()
5183 {
5184 /* Shortcut for GL functionality. */
5185 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5186
5187 /* Get context setup. */
5188 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
5189 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
5190
5191 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
5192 {
5193 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
5194
5195 return STOP;
5196 }
5197
5198 /* Running tests. */
5199 bool is_ok = true;
5200 bool is_error = false;
5201
5202 /* Tested Objects. */
5203 glw::GLuint vao = 0;
5204 glw::GLuint not_a_vao = 0;
5205
5206 /* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */
5207 glw::GLint max_vertex_attrib_bindings = 16;
5208
5209 try
5210 {
5211 /* Prepare valid Objects. */
5212 gl.createVertexArrays(1, &vao);
5213 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
5214
5215 /* Prepare invalid VAO. */
5216 while (gl.isVertexArray(++not_a_vao))
5217 ;
5218
5219 /* Prepare limits. */
5220 gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_vertex_attrib_bindings);
5221 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
5222
5223 /* Not a VAO. */
5224 gl.vertexArrayBindingDivisor(not_a_vao, 0, 0);
5225
5226 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayBindingDivisor if "
5227 "vaobj is not the name of an existing vertex array object.");
5228
5229 /* Too big binding index. */
5230 gl.vertexArrayBindingDivisor(vao, max_vertex_attrib_bindings, 0);
5231
5232 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayBindingDivisor if "
5233 "bindingindex is equal to the value of MAX_VERTEX_ATTRIB_BINDINGS.");
5234
5235 gl.vertexArrayBindingDivisor(vao, max_vertex_attrib_bindings + 1, 0);
5236
5237 is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayBindingDivisor if "
5238 "bindingindex is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS.");
5239 }
5240 catch (...)
5241 {
5242 is_ok = false;
5243 is_error = true;
5244 }
5245
5246 /* Clean up. */
5247 if (vao)
5248 {
5249 gl.deleteVertexArrays(1, &vao);
5250 }
5251
5252 /* Errors clean up. */
5253 while (gl.getError())
5254 ;
5255
5256 /* Result's setup. */
5257 if (is_ok)
5258 {
5259 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5260 }
5261 else
5262 {
5263 if (is_error)
5264 {
5265 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
5266 }
5267 else
5268 {
5269 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5270 }
5271 }
5272
5273 return STOP;
5274 }
5275
5276 /** @brief Compare error returned by GL with expected value and log.
5277 *
5278 * @param [in] expected Expected error.
5279 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one.
5280 *
5281 * @return True if GL error is equal to expected, false otherwise.
5282 */
CheckError(const glw::GLenum expected,const glw::GLchar * log_message)5283 bool AttributeBindingDivisorErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
5284 {
5285 /* Shortcut for GL functionality. */
5286 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5287
5288 glw::GLenum error = 0;
5289
5290 if (expected != (error = gl.getError()))
5291 {
5292 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
5293 << " was observed instead." << tcu::TestLog::EndMessage;
5294
5295 return false;
5296 }
5297
5298 return true;
5299 }
5300
5301 /******************************** Get Vertex Array Errors Test Implementation ********************************/
5302
5303 /** @brief Get Vertex Array Errors Test constructor.
5304 *
5305 * @param [in] context OpenGL context.
5306 */
GetVertexArrayErrorsTest(deqp::Context & context)5307 GetVertexArrayErrorsTest::GetVertexArrayErrorsTest(deqp::Context& context)
5308 : deqp::TestCase(context, "vertex_arrays_get_vertex_array_errors", "Get Vertex Array Errors Test")
5309 {
5310 }
5311
5312 /** @brief Iterate over Get Vertex Array Errors Test cases.
5313 *
5314 * @return Iteration result.
5315 */
iterate()5316 tcu::TestNode::IterateResult GetVertexArrayErrorsTest::iterate()
5317 {
5318 /* Shortcut for GL functionality. */
5319 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5320
5321 /* Get context setup. */
5322 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
5323 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
5324
5325 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
5326 {
5327 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
5328
5329 return STOP;
5330 }
5331
5332 /* Running tests. */
5333 bool is_ok = true;
5334 bool is_error = false;
5335
5336 /* Tested Objects. */
5337 glw::GLuint vao = 0;
5338 glw::GLuint not_a_vao = 0;
5339
5340 glw::GLint storage = 0;
5341
5342 try
5343 {
5344 /* Prepare valid Objects. */
5345 gl.createVertexArrays(1, &vao);
5346 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
5347
5348 /* Prepare invalid VAO. */
5349 while (gl.isVertexArray(++not_a_vao))
5350 ;
5351
5352 /* Not a VAO. */
5353 gl.getVertexArrayiv(not_a_vao, GL_ELEMENT_ARRAY_BUFFER_BINDING, &storage);
5354
5355 is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error was not generated by GetVertexArrayiv if "
5356 "vaobj is not the name of an existing vertex array object.");
5357
5358 /* Bad parameter. */
5359 gl.getVertexArrayiv(vao, GL_ELEMENT_ARRAY_BUFFER_BINDING + 1, &storage);
5360
5361 is_ok &= CheckError(
5362 GL_INVALID_ENUM,
5363 "INVALID_ENUM error was not generated by GetVertexArrayiv if pname is not ELEMENT_ARRAY_BUFFER_BINDING.");
5364 }
5365 catch (...)
5366 {
5367 is_ok = false;
5368 is_error = true;
5369 }
5370
5371 /* Clean up. */
5372 if (vao)
5373 {
5374 gl.deleteVertexArrays(1, &vao);
5375 }
5376
5377 /* Errors clean up. */
5378 while (gl.getError())
5379 ;
5380
5381 /* Result's setup. */
5382 if (is_ok)
5383 {
5384 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5385 }
5386 else
5387 {
5388 if (is_error)
5389 {
5390 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
5391 }
5392 else
5393 {
5394 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5395 }
5396 }
5397
5398 return STOP;
5399 }
5400
5401 /** @brief Compare error returned by GL with expected value and log.
5402 *
5403 * @param [in] expected Expected error.
5404 * @param [in] log_message Message to be logged if expected error is not the equal to the reported one.
5405 *
5406 * @return True if GL error is equal to expected, false otherwise.
5407 */
CheckError(const glw::GLenum expected,const glw::GLchar * log_message)5408 bool GetVertexArrayErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
5409 {
5410 /* Shortcut for GL functionality. */
5411 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5412
5413 glw::GLenum error = 0;
5414
5415 if (expected != (error = gl.getError()))
5416 {
5417 m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
5418 << " was observed instead." << tcu::TestLog::EndMessage;
5419
5420 return false;
5421 }
5422
5423 return true;
5424 }
5425
5426 /******************************** Get Vertex Array Indexed Errors Test Implementation ********************************/
5427
5428 /** @brief Get Vertex Array Indexed Errors Test constructor.
5429 *
5430 * @param [in] context OpenGL context.
5431 */
GetVertexArrayIndexedErrorsTest(deqp::Context & context)5432 GetVertexArrayIndexedErrorsTest::GetVertexArrayIndexedErrorsTest(deqp::Context& context)
5433 : deqp::TestCase(context, "vertex_arrays_get_vertex_array_indexed_errors", "Get Vertex Array Indexed Errors Test")
5434 {
5435 }
5436
5437 /** @brief Iterate over Get Vertex Array Indexed Errors Test cases.
5438 *
5439 * @return Iteration result.
5440 */
iterate()5441 tcu::TestNode::IterateResult GetVertexArrayIndexedErrorsTest::iterate()
5442 {
5443 /* Shortcut for GL functionality. */
5444 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5445
5446 /* Get context setup. */
5447 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
5448 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
5449
5450 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
5451 {
5452 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
5453
5454 return STOP;
5455 }
5456
5457 /* Running tests. */
5458 bool is_ok = true;
5459 bool is_error = false;
5460
5461 /* Tested Objects. */
5462 glw::GLuint vao = 0;
5463 glw::GLuint not_a_vao = 0;
5464
5465 /* Dummy storage. */
5466 glw::GLint storage = 0;
5467 glw::GLint64 storage64 = 0;
5468
5469 /* Bad parameter setup. */
5470 glw::GLenum bad_pname = 0;
5471
5472 static const glw::GLenum accepted_pnames[] = { GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_VERTEX_ATTRIB_ARRAY_SIZE,
5473 GL_VERTEX_ATTRIB_ARRAY_STRIDE, GL_VERTEX_ATTRIB_ARRAY_TYPE,
5474 GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_VERTEX_ATTRIB_ARRAY_INTEGER,
5475 GL_VERTEX_ATTRIB_ARRAY_LONG, GL_VERTEX_ATTRIB_ARRAY_DIVISOR,
5476 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 } /* VertexArrays namespace. */
5593 } /* DirectStateAccess namespace. */
5594 } /* gl4cts namespace. */
5595