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 gl4cDirectStateAccessXFBTests.cpp
27 * \brief Conformance tests for the Direct State Access feature functionality (Transform Feedbeck 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 namespace gl4cts
50 {
51 namespace DirectStateAccess
52 {
53 namespace TransformFeedback
54 {
55 /******************************** Creation Test Implementation ********************************/
56
57 /** @brief Creation Test constructor.
58 *
59 * @param [in] context OpenGL context.
60 */
CreationTest(deqp::Context & context)61 CreationTest::CreationTest(deqp::Context &context)
62 : deqp::TestCase(context, "xfb_creation", "Transform Feedback Creation Test")
63 {
64 /* Intentionally left blank. */
65 }
66
67 /** @brief Iterate Creation Test cases.
68 *
69 * @return Iteration result.
70 */
iterate()71 tcu::TestNode::IterateResult CreationTest::iterate()
72 {
73 /* Shortcut for GL functionality */
74 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
75
76 /* Get context setup. */
77 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
78 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
79
80 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
81 {
82 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
83
84 return STOP;
85 }
86
87 /* Running tests. */
88 bool is_ok = true;
89 bool is_error = false;
90
91 /* Transform feedback objects */
92 static const glw::GLuint xfb_count = 2;
93
94 glw::GLuint xfb_dsa[xfb_count] = {};
95 glw::GLuint xfb_legacy[xfb_count] = {};
96
97 try
98 {
99 /* Sanity default setup. */
100 gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
101 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback have failed");
102
103 /* Check legacy way. */
104 gl.genTransformFeedbacks(xfb_count, xfb_legacy);
105 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks have failed");
106
107 for (glw::GLuint i = 0; i < xfb_count; ++i)
108 {
109 if (gl.isTransformFeedback(xfb_legacy[i]))
110 {
111 is_ok = false;
112
113 /* Log. */
114 m_context.getTestContext().getLog()
115 << tcu::TestLog::Message
116 << "GenTransformFeedbacks has created defualt objects, but only shall reserve names for them."
117 << tcu::TestLog::EndMessage;
118 }
119 }
120
121 /* Check direct state access way. */
122 gl.createTransformFeedbacks(xfb_count, xfb_dsa);
123 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
124
125 for (glw::GLuint i = 0; i < xfb_count; ++i)
126 {
127 if (!gl.isTransformFeedback(xfb_dsa[i]))
128 {
129 is_ok = false;
130
131 /* Log. */
132 m_context.getTestContext().getLog()
133 << tcu::TestLog::Message << "CreateTransformFeedbacks has not created defualt objects."
134 << tcu::TestLog::EndMessage;
135 }
136 }
137
138 /* Check binding point. */
139 glw::GLint xfb_binding_point = -1;
140
141 gl.getIntegerv(GL_TRANSFORM_FEEDBACK_BINDING, &xfb_binding_point);
142 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv have failed");
143
144 if (0 != xfb_binding_point)
145 {
146 if (-1 == xfb_binding_point)
147 {
148 m_context.getTestContext().getLog() << tcu::TestLog::Message
149 << "glGetIntegerv used with GL_TRANSFORM_FEEDBACK_BINDING have not "
150 "returned anything and did not generate error."
151 << tcu::TestLog::EndMessage;
152
153 throw 0;
154 }
155 else
156 {
157 m_context.getTestContext().getLog() << tcu::TestLog::Message
158 << "The usage of glCreateTransformFeedbacks have changed "
159 "GL_TRANSFORM_FEEDBACK_BINDING binding point."
160 << tcu::TestLog::EndMessage;
161
162 is_ok = false;
163 }
164 }
165 }
166 catch (...)
167 {
168 is_ok = false;
169 is_error = true;
170 }
171
172 /* Cleanup. */
173 for (glw::GLuint i = 0; i < xfb_count; ++i)
174 {
175 if (xfb_legacy[i])
176 {
177 gl.deleteTransformFeedbacks(1, &xfb_legacy[i]);
178
179 xfb_legacy[i] = 0;
180 }
181
182 if (xfb_dsa[i])
183 {
184 gl.deleteTransformFeedbacks(1, &xfb_dsa[i]);
185
186 xfb_dsa[i] = 0;
187 }
188 }
189
190 /* Result's setup. */
191 if (is_ok)
192 {
193 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
194 }
195 else
196 {
197 if (is_error)
198 {
199 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
200 }
201 else
202 {
203 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
204 }
205 }
206
207 return STOP;
208 }
209
210 /******************************** Defaults Test Implementation ********************************/
211
212 /** @brief Defaults Test constructor.
213 *
214 * @param [in] context OpenGL context.
215 */
DefaultsTest(deqp::Context & context)216 DefaultsTest::DefaultsTest(deqp::Context &context)
217 : deqp::TestCase(context, "xfb_defaults", "Transform Feedback Defaults Test")
218 , m_gl_getTransformFeedbackiv(DE_NULL)
219 , m_gl_getTransformFeedbacki_v(DE_NULL)
220 , m_gl_getTransformFeedbacki64_v(DE_NULL)
221 , m_xfb_dsa(0)
222 , m_xfb_indexed_binding_points_count(0)
223 {
224 /* Intentionally left blank. */
225 }
226
227 /** @brief Iterate Defaults Test cases.
228 *
229 * @return Iteration result.
230 */
iterate()231 tcu::TestNode::IterateResult DefaultsTest::iterate()
232 {
233 /* Get context setup. */
234 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
235 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
236
237 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
238 {
239 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
240
241 return STOP;
242 }
243
244 /* Running tests. */
245 bool is_ok = true;
246 bool is_error = false;
247
248 try
249 {
250 prepare();
251
252 is_ok &= testBuffersBindingPoints();
253 is_ok &= testBuffersDimensions();
254 is_ok &= testActive();
255 is_ok &= testPaused();
256 }
257 catch (...)
258 {
259 is_ok = false;
260 is_error = true;
261 }
262
263 /* Clean up. */
264 clean();
265
266 /* Result's setup. */
267 if (is_ok)
268 {
269 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
270 }
271 else
272 {
273 if (is_error)
274 {
275 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
276 }
277 else
278 {
279 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
280 }
281 }
282
283 return STOP;
284 }
285
286 /** @brief Create XFB and Buffer Objects. Prepare function pointers.
287 *
288 * @note The function may throw if unexpected error has occured.
289 *
290 * @return True if test succeeded, false otherwise.
291 */
prepare()292 void DefaultsTest::prepare()
293 {
294 /* Shortcut for GL functionality */
295 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
296
297 /* Fetching function pointers. */
298 m_gl_getTransformFeedbackiv = (GetTransformFeedbackiv_ProcAddress)gl.getTransformFeedbackiv;
299 m_gl_getTransformFeedbacki_v = (GetTransformFeedbacki_v_ProcAddress)gl.getTransformFeedbacki_v;
300 m_gl_getTransformFeedbacki64_v = (GetTransformFeedbacki64_v_ProcAddress)gl.getTransformFeedbacki64_v;
301
302 if ((DE_NULL == m_gl_getTransformFeedbackiv) || (DE_NULL == m_gl_getTransformFeedbacki_v) ||
303 (DE_NULL == m_gl_getTransformFeedbacki64_v))
304 {
305 m_context.getTestContext().getLog()
306 << tcu::TestLog::Message << "Function pointers are set to NULL values." << tcu::TestLog::EndMessage;
307
308 throw 0;
309 }
310
311 /* XFB object creation */
312 gl.createTransformFeedbacks(1, &m_xfb_dsa);
313 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
314
315 /* Query limits. */
316 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &m_xfb_indexed_binding_points_count);
317 GLU_EXPECT_NO_ERROR(gl.getError(), "glIntegerv have failed");
318 }
319
320 /** @brief Test default value of GL_TRANSFORM_FEEDBACK_BUFFER_BINDING.
321 *
322 * @note The function may throw if unexpected error has occured.
323 *
324 * @return True if test succeeded, false otherwise.
325 */
testBuffersBindingPoints()326 bool DefaultsTest::testBuffersBindingPoints()
327 {
328 /* Shortcut for GL functionality */
329 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
330
331 /* Check default binding points value. */
332 for (glw::GLint i = 0; i < m_xfb_indexed_binding_points_count; ++i)
333 {
334 glw::GLint buffer_binding = -1;
335
336 m_gl_getTransformFeedbacki_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, &buffer_binding);
337 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");
338
339 if (-1 == buffer_binding)
340 {
341 m_context.getTestContext().getLog()
342 << tcu::TestLog::Message
343 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING has not returned "
344 "anything and error has not been generated."
345 << tcu::TestLog::EndMessage;
346
347 return false;
348 }
349 else
350 {
351 if (0 != buffer_binding)
352 {
353 m_context.getTestContext().getLog()
354 << tcu::TestLog::Message
355 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING has returned "
356 << buffer_binding << ", however 0 is expected." << tcu::TestLog::EndMessage;
357
358 return false;
359 }
360 }
361 }
362
363 return true;
364 }
365
366 /** @brief Test default values of GL_TRANSFORM_FEEDBACK_START and GL_TRANSFORM_FEEDBACK_SIZE.
367 *
368 * @note The function may throw if unexpected error has occured.
369 *
370 * @return True if test succeeded, false otherwise.
371 */
testBuffersDimensions()372 bool DefaultsTest::testBuffersDimensions()
373 {
374 /* Shortcut for GL functionality */
375 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
376
377 /* Check default buffers' start value. */
378 for (glw::GLint i = 0; i < m_xfb_indexed_binding_points_count; ++i)
379 {
380 glw::GLint64 buffer_start = -1;
381
382 m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_START, i, &buffer_start);
383 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");
384
385 if (-1 == buffer_start)
386 {
387 m_context.getTestContext().getLog()
388 << tcu::TestLog::Message
389 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START has not returned "
390 "anything and error has not been generated."
391 << tcu::TestLog::EndMessage;
392
393 return false;
394 }
395 else
396 {
397 if (0 != buffer_start)
398 {
399 m_context.getTestContext().getLog()
400 << tcu::TestLog::Message
401 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START has returned "
402 << buffer_start << ", however 0 is expected." << tcu::TestLog::EndMessage;
403
404 return false;
405 }
406 }
407 }
408
409 /** @brief Check default buffers' size value.
410 *
411 * @note The function may throw if unexpected error has occured.
412 */
413 for (glw::GLint i = 0; i < m_xfb_indexed_binding_points_count; ++i)
414 {
415 glw::GLint64 buffer_size = -1;
416
417 m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, i, &buffer_size);
418 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");
419
420 if (-1 == buffer_size)
421 {
422 m_context.getTestContext().getLog()
423 << tcu::TestLog::Message
424 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE has not returned "
425 "anything and error has not been generated."
426 << tcu::TestLog::EndMessage;
427
428 return false;
429 }
430 else
431 {
432 if (0 != buffer_size)
433 {
434 m_context.getTestContext().getLog()
435 << tcu::TestLog::Message
436 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE has returned "
437 << buffer_size << ", however 0 is expected." << tcu::TestLog::EndMessage;
438
439 return false;
440 }
441 }
442 }
443
444 return true;
445 }
446
447 /** @brief Test default value of GL_TRANSFORM_FEEDBACK_ACTIVE.
448 *
449 * @return True if test succeeded, false otherwise.
450 */
testActive()451 bool DefaultsTest::testActive()
452 {
453 /* Check that it is not active. */
454 glw::GLint is_active = -1;
455 m_gl_getTransformFeedbackiv(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_ACTIVE, &is_active);
456
457 if (-1 == is_active)
458 {
459 m_context.getTestContext().getLog() << tcu::TestLog::Message
460 << "glGetTransformFeedbackiv with parameter GL_TRANSFORM_FEEDBACK_ACTIVE "
461 "has not returned anything and error has not been generated."
462 << tcu::TestLog::EndMessage;
463
464 return false;
465 }
466 else
467 {
468 if (0 != is_active)
469 {
470 m_context.getTestContext().getLog()
471 << tcu::TestLog::Message
472 << "glGetTransformFeedbackiv with parameter GL_TRANSFORM_FEEDBACK_ACTIVE has returned " << is_active
473 << ", however FALSE is expected." << tcu::TestLog::EndMessage;
474
475 return false;
476 }
477 }
478
479 return true;
480 }
481
482 /** @brief Test default value of GL_TRANSFORM_FEEDBACK_PAUSED.
483 *
484 * @return True if test succeeded, false otherwise.
485 */
testPaused()486 bool DefaultsTest::testPaused()
487 {
488 /* Check that it is not paused. */
489 glw::GLint is_paused = -1;
490 m_gl_getTransformFeedbackiv(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_PAUSED, &is_paused);
491
492 if (-1 == is_paused)
493 {
494 m_context.getTestContext().getLog() << tcu::TestLog::Message
495 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_PAUSED "
496 "has not returned anything and error has not been generated."
497 << tcu::TestLog::EndMessage;
498
499 return false;
500 }
501 else
502 {
503 if (0 != is_paused)
504 {
505 m_context.getTestContext().getLog()
506 << tcu::TestLog::Message
507 << "glGetTransformFeedbackiv with parameter GL_TRANSFORM_FEEDBACK_PAUSED has returned " << is_paused
508 << ", however FALSE is expected." << tcu::TestLog::EndMessage;
509
510 return false;
511 }
512 }
513
514 return true;
515 }
516
517 /** @brief Release GL objects.
518 */
clean()519 void DefaultsTest::clean()
520 {
521 /* Shortcut for GL functionality */
522 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
523
524 if (m_xfb_dsa)
525 {
526 gl.deleteTransformFeedbacks(1, &m_xfb_dsa);
527
528 m_xfb_dsa = 0;
529 }
530 }
531
532 /******************************** Buffers Test Implementation ********************************/
533
534 /** @brief Buffers Test constructor.
535 *
536 * @param [in] context OpenGL context.
537 */
BuffersTest(deqp::Context & context)538 BuffersTest::BuffersTest(deqp::Context &context)
539 : deqp::TestCase(context, "xfb_buffers", "Transform Feedback Buffers Test")
540 , m_gl_getTransformFeedbacki_v(DE_NULL)
541 , m_gl_getTransformFeedbacki64_v(DE_NULL)
542 , m_gl_TransformFeedbackBufferBase(DE_NULL)
543 , m_gl_TransformFeedbackBufferRange(DE_NULL)
544 , m_xfb_dsa(0)
545 , m_bo_a(0)
546 , m_bo_b(0)
547 {
548 /* Intentionally left blank. */
549 }
550
551 /** @brief Iterate Buffers Test cases.
552 *
553 * @return Iteration result.
554 */
iterate()555 tcu::TestNode::IterateResult BuffersTest::iterate()
556 {
557 /* Get context setup. */
558 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
559 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
560
561 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
562 {
563 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
564
565 return STOP;
566 }
567
568 /* Running tests. */
569 bool is_ok = true;
570 bool is_error = false;
571
572 try
573 {
574 /* Prepare function pointers, transform feedback and buffer objects. */
575 prepareObjects();
576
577 /* Setup transform feedback object binding points with buffer objects. */
578 is_ok = prepareTestSetup();
579
580 /* Continue only if test setup succeeded */
581 if (is_ok)
582 {
583 is_ok &= testBindingPoint(0, m_bo_a, "glTransformFeedbackBufferBase");
584 is_ok &= testBindingPoint(1, m_bo_b, "glTransformFeedbackBufferRange");
585 is_ok &= testBindingPoint(2, m_bo_b, "glTransformFeedbackBufferRange");
586
587 is_ok &= testStart(0, 0, "glTransformFeedbackBufferBase");
588 is_ok &= testStart(1, 0, "glTransformFeedbackBufferRange");
589 is_ok &= testStart(2, s_bo_size / 2, "glTransformFeedbackBufferRange");
590
591 is_ok &= testSize(0, 0, "glTransformFeedbackBufferBase");
592 is_ok &= testSize(1, s_bo_size / 2, "glTransformFeedbackBufferRange");
593 is_ok &= testSize(2, s_bo_size / 2, "glTransformFeedbackBufferRange");
594 }
595 }
596 catch (...)
597 {
598 is_ok = false;
599 is_error = true;
600 }
601
602 /* Clean up. */
603 clean();
604
605 /* Result's setup. */
606 if (is_ok)
607 {
608 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
609 }
610 else
611 {
612 if (is_error)
613 {
614 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
615 }
616 else
617 {
618 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
619 }
620 }
621
622 return STOP;
623 }
624
625 /** @brief Create XFB amd BO objects. Setup function pointers.
626 *
627 * @note The function may throw if unexpected error has occured.
628 */
prepareObjects()629 void BuffersTest::prepareObjects()
630 {
631 /* Shortcut for GL functionality */
632 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
633
634 /* Fetching function pointers. */
635 m_gl_getTransformFeedbacki_v = (GetTransformFeedbacki_v_ProcAddress)gl.getTransformFeedbacki_v;
636 m_gl_getTransformFeedbacki64_v = (GetTransformFeedbacki64_v_ProcAddress)gl.getTransformFeedbacki64_v;
637 m_gl_TransformFeedbackBufferBase = (TransformFeedbackBufferBase_ProcAddress)gl.transformFeedbackBufferBase;
638 m_gl_TransformFeedbackBufferRange = (TransformFeedbackBufferRange_ProcAddress)gl.transformFeedbackBufferRange;
639
640 if ((DE_NULL == m_gl_getTransformFeedbacki_v) || (DE_NULL == m_gl_getTransformFeedbacki64_v) ||
641 (DE_NULL == m_gl_TransformFeedbackBufferBase) || (DE_NULL == m_gl_TransformFeedbackBufferRange))
642 {
643 m_context.getTestContext().getLog()
644 << tcu::TestLog::Message << "Function pointers are set to NULL values." << tcu::TestLog::EndMessage;
645
646 throw 0;
647 }
648
649 /** @brief XFB object creation */
650 gl.createTransformFeedbacks(1, &m_xfb_dsa);
651 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
652
653 /* Buffer Objects creation. */
654 gl.genBuffers(1, &m_bo_a);
655 gl.genBuffers(1, &m_bo_b);
656 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");
657
658 if ((0 == m_bo_a) || (0 == m_bo_b))
659 {
660 m_context.getTestContext().getLog()
661 << tcu::TestLog::Message << "Buffer object has not been generated and no error has been triggered."
662 << tcu::TestLog::EndMessage;
663
664 throw 0;
665 }
666
667 /* First buffer memory allocation. */
668 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_a);
669 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");
670
671 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY);
672 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed");
673
674 /* Sainty check of buffer size */
675 glw::GLint allocated_size = -1;
676
677 gl.getBufferParameteriv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_BUFFER_SIZE, &allocated_size);
678 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferParameteriv have failed");
679
680 if (allocated_size != (glw::GLint)s_bo_size)
681 {
682 m_context.getTestContext().getLog()
683 << tcu::TestLog::Message << "Buffer allocation failed." << tcu::TestLog::EndMessage;
684
685 throw 0;
686 }
687
688 /* Second buffer memory allocation. */
689 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_b);
690 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");
691
692 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY);
693 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed");
694
695 /* Sainty check of buffer size */
696 allocated_size = -1;
697
698 gl.getBufferParameteriv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_BUFFER_SIZE, &allocated_size);
699 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferParameteriv have failed");
700
701 if (allocated_size != (glw::GLint)s_bo_size)
702 {
703 m_context.getTestContext().getLog()
704 << tcu::TestLog::Message << "Buffer allocation failed." << tcu::TestLog::EndMessage;
705
706 throw 0;
707 }
708
709 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
710 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");
711 }
712
713 /** @brief Setup indexed buffer binding points in the xfb object using
714 * glTransformFeedbackBufferBase and glTransformFeedbackBufferRange
715 * functions.
716 *
717 * @return True if setup succeeded, false otherwise (functions triggered errors).
718 */
prepareTestSetup()719 bool BuffersTest::prepareTestSetup()
720 {
721 /* Shortcut for GL functionality */
722 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
723
724 /* Bind Buffer Object to first indexed binding point. */
725 m_gl_TransformFeedbackBufferBase(m_xfb_dsa, 0, m_bo_a);
726
727 /* Check errors. */
728 glw::GLenum error_value = gl.getError();
729
730 if (GL_NONE != error_value)
731 {
732 m_context.getTestContext().getLog()
733 << tcu::TestLog::Message << "glTransformFeedbackBufferBase has generated unexpected error ("
734 << glu::getErrorStr(error_value) << "). Test Failed." << tcu::TestLog::EndMessage;
735
736 return false;
737 }
738
739 /* Bind Buffer Object to second and third indexed binding point. */
740 m_gl_TransformFeedbackBufferRange(m_xfb_dsa, 1, m_bo_b, 0, s_bo_size / 2);
741 m_gl_TransformFeedbackBufferRange(m_xfb_dsa, 2, m_bo_b, s_bo_size / 2, s_bo_size / 2);
742
743 /* Check errors. */
744 error_value = gl.getError();
745
746 if (GL_NONE != error_value)
747 {
748 m_context.getTestContext().getLog()
749 << tcu::TestLog::Message << "glTransformFeedbackBufferRange has generated unexpected error ("
750 << glu::getErrorStr(error_value) << "). Test Failed." << tcu::TestLog::EndMessage;
751
752 return false;
753 }
754
755 return true;
756 }
757
758 /** @brief Test that xfb object's binding point #<index> has <expected_value>.
759 *
760 * @param [in] index Tested index point.
761 * @param [in] expected_value Value to be expected (buffer name).
762 * @param [in] tested_function_name Name of function which this function is going to test
763 * (glTransformFeedbackBufferBase or glTransformFeedbackBufferRange)
764 * for logging purposes.
765 *
766 * @note The function may throw if unexpected error has occured.
767 *
768 * @return True if test succeeded, false otherwise.
769 */
testBindingPoint(glw::GLuint const index,glw::GLint const expected_value,glw::GLchar const * const tested_function_name)770 bool BuffersTest::testBindingPoint(glw::GLuint const index, glw::GLint const expected_value,
771 glw::GLchar const *const tested_function_name)
772 {
773 /* Shortcut for GL functionality */
774 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
775
776 /* Check default binding points value. */
777 glw::GLint buffer_binding = -1;
778
779 m_gl_getTransformFeedbacki_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, index, &buffer_binding);
780 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");
781
782 if (-1 == buffer_binding)
783 {
784 m_context.getTestContext().getLog()
785 << tcu::TestLog::Message
786 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING "
787 "has not returned anything and error has not been generated."
788 << tcu::TestLog::EndMessage;
789
790 return false;
791 }
792 else
793 {
794 if (expected_value != buffer_binding)
795 {
796 m_context.getTestContext().getLog()
797 << tcu::TestLog::Message
798 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING has returned "
799 << buffer_binding << ", however " << expected_value << " is expected. As a consequence function "
800 << tested_function_name << " have failed to setup proper value." << tcu::TestLog::EndMessage;
801
802 return false;
803 }
804 }
805
806 return true;
807 }
808
809 /** @brief Test that buffer object at xfb object's binding point #<index> has starting offset set to the <expected_value>.
810 *
811 * @param [in] index Tested index point.
812 * @param [in] expected_value Value to be expected (starting offset).
813 * @param [in] tested_function_name Name of function which this function is going to test
814 * (glTransformFeedbackBufferBase or glTransformFeedbackBufferRange)
815 * for logging purposes.
816 *
817 * @note The function may throw if unexpected error has occured.
818 *
819 * @return True if test succeeded, false otherwise.
820 */
testStart(glw::GLuint const index,glw::GLint const expected_value,glw::GLchar const * const tested_function_name)821 bool BuffersTest::testStart(glw::GLuint const index, glw::GLint const expected_value,
822 glw::GLchar const *const tested_function_name)
823 {
824 /* Shortcut for GL functionality */
825 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
826
827 /* Check default buffers' start value. */
828 glw::GLint64 buffer_start = -1;
829
830 m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_START, index, &buffer_start);
831 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");
832
833 /* Checking results and errors. */
834 if (-1 == buffer_start)
835 {
836 m_context.getTestContext().getLog()
837 << tcu::TestLog::Message
838 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START "
839 "has not returned anything and error has not been generated."
840 << tcu::TestLog::EndMessage;
841
842 return false;
843 }
844 else
845 {
846 if (expected_value != buffer_start)
847 {
848 m_context.getTestContext().getLog()
849 << tcu::TestLog::Message
850 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START has returned "
851 << buffer_start << ", however " << expected_value << " is expected. As a consequence function "
852 << tested_function_name << " have failed to setup proper value." << tcu::TestLog::EndMessage;
853
854 return false;
855 }
856 }
857
858 return true;
859 }
860
861 /** @brief Test that buffer object at xfb object's binding point #<index> has size set to the <expected_value>.
862 *
863 * @param [in] index Tested index point.
864 * @param [in] expected_value Value to be expected (buffer's size).
865 * @param [in] tested_function_name Name of function which this function is going to test
866 * (glTransformFeedbackBufferBase or glTransformFeedbackBufferRange)
867 * for logging purposes.
868 *
869 * @note The function may throw if unexpected error has occured.
870 *
871 * @return True if test succeeded, false otherwise.
872 */
testSize(glw::GLuint const index,glw::GLint const expected_value,glw::GLchar const * const tested_function_name)873 bool BuffersTest::testSize(glw::GLuint const index, glw::GLint const expected_value,
874 glw::GLchar const *const tested_function_name)
875 {
876 /* Shortcut for GL functionality */
877 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
878
879 /* Check default buffer's size value. */
880 glw::GLint64 buffer_size = -1;
881
882 m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, index, &buffer_size);
883 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");
884
885 /* Checking results and errors. */
886 if (-1 == buffer_size)
887 {
888 m_context.getTestContext().getLog()
889 << tcu::TestLog::Message
890 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE "
891 "has not returned anything and error has not been generated."
892 << tcu::TestLog::EndMessage;
893
894 return false;
895 }
896 else
897 {
898 if (expected_value != buffer_size)
899 {
900 m_context.getTestContext().getLog()
901 << tcu::TestLog::Message
902 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE has returned "
903 << buffer_size << ", however " << expected_value << " is expected. As a consequence function "
904 << tested_function_name << " have failed to setup proper value." << tcu::TestLog::EndMessage;
905
906 return false;
907 }
908 }
909
910 return true;
911 }
912
913 /** @brief Clean al GL objects
914 */
clean()915 void BuffersTest::clean()
916 {
917 /* Shortcut for GL functionality */
918 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
919
920 /* Release transform feedback object. */
921 if (m_xfb_dsa)
922 {
923 gl.deleteTransformFeedbacks(1, &m_xfb_dsa);
924
925 m_xfb_dsa = 0;
926 }
927
928 /* Release buffer objects. */
929 if (m_bo_a)
930 {
931 gl.deleteBuffers(1, &m_bo_a);
932
933 m_bo_a = 0;
934 }
935
936 if (m_bo_b)
937 {
938 gl.deleteBuffers(1, &m_bo_b);
939
940 m_bo_b = 0;
941 }
942 }
943
944 /** @brief Buffer Object Size */
945 const glw::GLuint BuffersTest::s_bo_size = 512;
946
947 /******************************** Errors Test Implementation ********************************/
948
949 /** @brief Errors Test constructor.
950 *
951 * @param [in] context OpenGL context.
952 */
ErrorsTest(deqp::Context & context)953 ErrorsTest::ErrorsTest(deqp::Context &context)
954 : deqp::TestCase(context, "xfb_errors", "Transform Feedback Errors Test")
955 , m_gl_getTransformFeedbackiv(DE_NULL)
956 , m_gl_getTransformFeedbacki_v(DE_NULL)
957 , m_gl_getTransformFeedbacki64_v(DE_NULL)
958 {
959 /* Intentionally left blank. */
960 }
961
962 /** @brief Iterate Errors Test cases.
963 *
964 * @return Iteration result.
965 */
iterate()966 tcu::TestNode::IterateResult ErrorsTest::iterate()
967 {
968 /* Get context setup. */
969 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
970 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
971
972 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
973 {
974 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
975
976 return STOP;
977 }
978
979 /* Running tests. */
980 bool is_ok = true;
981 bool is_error = false;
982
983 try
984 {
985 prepareFunctionPointers();
986
987 is_ok &= testCreateTransformFeedbacksForInvalidNumberOfObjects();
988 cleanErrors();
989
990 is_ok &= testQueriesForInvalidNameOfObject();
991 cleanErrors();
992
993 is_ok &= testGetTransformFeedbackivQueryForInvalidParameterName();
994 cleanErrors();
995
996 is_ok &= testGetTransformFeedbacki_vQueryForInvalidParameterName();
997 cleanErrors();
998
999 is_ok &= testGetTransformFeedbacki64_vQueryForInvalidParameterName();
1000 cleanErrors();
1001
1002 is_ok &= testIndexedQueriesForInvalidBindingPoint();
1003 cleanErrors();
1004 }
1005 catch (...)
1006 {
1007 is_ok = false;
1008 is_error = true;
1009 }
1010
1011 /* Result's setup. */
1012 if (is_ok)
1013 {
1014 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1015 }
1016 else
1017 {
1018 if (is_error)
1019 {
1020 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1021 }
1022 else
1023 {
1024 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1025 }
1026 }
1027
1028 return STOP;
1029 }
1030
1031 /** @brief Fetch GL function pointers.
1032 *
1033 * @note The function may throw if unexpected error has occured.
1034 */
prepareFunctionPointers()1035 void ErrorsTest::prepareFunctionPointers()
1036 {
1037 /* Shortcut for GL functionality */
1038 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1039
1040 /* Fetching function pointers. */
1041 m_gl_getTransformFeedbackiv = (GetTransformFeedbackiv_ProcAddress)gl.getTransformFeedbackiv;
1042 m_gl_getTransformFeedbacki_v = (GetTransformFeedbacki_v_ProcAddress)gl.getTransformFeedbacki_v;
1043 m_gl_getTransformFeedbacki64_v = (GetTransformFeedbacki64_v_ProcAddress)gl.getTransformFeedbacki64_v;
1044
1045 if ((DE_NULL == m_gl_getTransformFeedbackiv) || (DE_NULL == m_gl_getTransformFeedbacki_v) ||
1046 (DE_NULL == m_gl_getTransformFeedbacki64_v))
1047 {
1048 m_context.getTestContext().getLog()
1049 << tcu::TestLog::Message << "Function pointers are set to NULL values." << tcu::TestLog::EndMessage;
1050
1051 throw 0;
1052 }
1053 }
1054
1055 /** @brief Sanity clean-up of GL errors.
1056 *
1057 * @note This function is to only make sure that failing test will not affect other tests.
1058 */
cleanErrors()1059 void ErrorsTest::cleanErrors()
1060 {
1061 /* Shortcut for GL functionality */
1062 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1063
1064 /* Cleaning errors. */
1065 while (GL_NO_ERROR != gl.getError())
1066 ;
1067 }
1068
1069 /** @brief Test Creation of Transform Feedbacks using Invalid Number Of Objects
1070 *
1071 * @note Test checks that CreateTransformFeedbacks generates INVALID_VALUE error if
1072 * number of transform feedback objects to create is negative.
1073 *
1074 * @return true if test succeded, false otherwise.
1075 */
testCreateTransformFeedbacksForInvalidNumberOfObjects()1076 bool ErrorsTest::testCreateTransformFeedbacksForInvalidNumberOfObjects()
1077 {
1078 /* Shortcut for GL functionality */
1079 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1080
1081 glw::GLuint xfbs = 314159;
1082
1083 gl.createTransformFeedbacks(-1 /* invalid count */, &xfbs);
1084
1085 glw::GLenum error = gl.getError();
1086
1087 if (GL_INVALID_VALUE != error)
1088 {
1089 m_context.getTestContext().getLog() << tcu::TestLog::Message
1090 << "glCreateTransformFeedbacks called with negative number of objects had "
1091 "been expected to generate GL_INVALID_VALUE. However, "
1092 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1093
1094 return false;
1095 }
1096
1097 if (314159 != xfbs)
1098 {
1099 m_context.getTestContext().getLog() << tcu::TestLog::Message
1100 << "glCreateTransformFeedbacks called with negative number of objects had "
1101 "been expected not to change the given buffer."
1102 << tcu::TestLog::EndMessage;
1103
1104 return false;
1105 }
1106
1107 return true;
1108 }
1109
1110 /** @brief Test Direct State Access queries with invalid object name
1111 *
1112 * @note Test checks that GetTransformFeedbackiv, GetTransformFeedbacki_v and
1113 * GetTransformFeedbacki64_v generate INVALID_OPERATION error if xfb is not
1114 * zero or the name of an existing transform feedback object.
1115 *
1116 * @return true if test succeded, false otherwise.
1117 */
testQueriesForInvalidNameOfObject()1118 bool ErrorsTest::testQueriesForInvalidNameOfObject()
1119 {
1120 /* Shortcut for GL functionality */
1121 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1122
1123 /* Generating not a-TransformFeedback name. */
1124 glw::GLuint invalid_name = 0;
1125
1126 while (GL_TRUE == gl.isTransformFeedback(++invalid_name))
1127 ;
1128
1129 /* unused storage. */
1130 glw::GLint buffer = 314159;
1131 glw::GLint64 buffer64 = 314159;
1132
1133 /* Error variable. */
1134 glw::GLenum error = 0;
1135
1136 /* Test of GetTransformFeedbackiv. */
1137 m_gl_getTransformFeedbackiv(invalid_name, GL_TRANSFORM_FEEDBACK_PAUSED, &buffer);
1138
1139 if (GL_INVALID_OPERATION != (error = gl.getError()))
1140 {
1141 m_context.getTestContext().getLog() << tcu::TestLog::Message
1142 << "glGetTransformFeedbackiv called with invalid object name had been "
1143 "expected to generate GL_INVALID_OPERATION. However, "
1144 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1145
1146 return false;
1147 }
1148
1149 if (314159 != buffer)
1150 {
1151 m_context.getTestContext().getLog() << tcu::TestLog::Message
1152 << "glGetTransformFeedbackiv called with invalid object name had been "
1153 "expected not to change the given buffer."
1154 << tcu::TestLog::EndMessage;
1155
1156 return false;
1157 }
1158
1159 while (GL_NO_ERROR != (error = gl.getError()))
1160 {
1161 m_context.getTestContext().getLog() << tcu::TestLog::Message
1162 << "Warning! glGetTransformFeedbackiv called with invalid object name has "
1163 "generated more than one error, The next error was "
1164 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1165 }
1166
1167 /* Test of GetTransformFeedbacki_v. */
1168 m_gl_getTransformFeedbacki_v(invalid_name, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, &buffer);
1169
1170 if (GL_INVALID_OPERATION != (error = gl.getError()))
1171 {
1172 m_context.getTestContext().getLog() << tcu::TestLog::Message
1173 << "glGetTransformFeedbacki_v called with invalid object name had been "
1174 "expected to generate GL_INVALID_OPERATION. However, "
1175 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1176
1177 return false;
1178 }
1179
1180 if (314159 != buffer)
1181 {
1182 m_context.getTestContext().getLog() << tcu::TestLog::Message
1183 << "glGetTransformFeedbacki_v called with invalid object name had been "
1184 "expected not to change the given buffer."
1185 << tcu::TestLog::EndMessage;
1186
1187 return false;
1188 }
1189
1190 while (GL_NO_ERROR != (error = gl.getError()))
1191 {
1192 m_context.getTestContext().getLog() << tcu::TestLog::Message
1193 << "Warning! glGetTransformFeedbacki_v called with invalid object name has "
1194 "unexpectedly generated more than one error, The next error was "
1195 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1196 }
1197
1198 /* Test of GetTransformFeedbacki64_v. */
1199 m_gl_getTransformFeedbacki64_v(invalid_name, GL_TRANSFORM_FEEDBACK_BUFFER_START, 0, &buffer64);
1200
1201 if (GL_INVALID_OPERATION != (error = gl.getError()))
1202 {
1203 m_context.getTestContext().getLog() << tcu::TestLog::Message
1204 << "glGetTransformFeedbacki64_v called with invalid object name had been "
1205 "expected to generate GL_INVALID_OPERATION. However, "
1206 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1207
1208 return false;
1209 }
1210
1211 if (314159 != buffer64)
1212 {
1213 m_context.getTestContext().getLog() << tcu::TestLog::Message
1214 << "glGetTransformFeedbacki64_v called with invalid object name had been "
1215 "expected not to change the given buffer."
1216 << tcu::TestLog::EndMessage;
1217
1218 return false;
1219 }
1220
1221 while (GL_NO_ERROR != (error = gl.getError()))
1222 {
1223 m_context.getTestContext().getLog() << tcu::TestLog::Message
1224 << "Warning! glGetTransformFeedbacki64_v called with invalid object name "
1225 "has unexpectedly generated more than one error, The next error was "
1226 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1227 }
1228
1229 return true;
1230 }
1231
1232 /** @brief Test Direct State Access queries with invalid parameter name
1233 *
1234 * @note Test checks that GetTransformFeedbackiv generates INVALID_ENUM error if pname
1235 * is not TRANSFORM_FEEDBACK_PAUSED or TRANSFORM_FEEDBACK_ACTIVE.
1236 *
1237 * @note The function may throw if unexpected error has occured.
1238 *
1239 * @return true if test succeded, false otherwise.
1240 */
testGetTransformFeedbackivQueryForInvalidParameterName()1241 bool ErrorsTest::testGetTransformFeedbackivQueryForInvalidParameterName()
1242 {
1243 /* Shortcut for GL functionality */
1244 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1245
1246 /* Creating XFB object. */
1247 glw::GLuint xfb = 0;
1248
1249 gl.createTransformFeedbacks(1, &xfb);
1250 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
1251
1252 /* Generating invalid parameter name. */
1253 glw::GLuint invalid_parameter_name = 0;
1254
1255 /* Unused storage. */
1256 glw::GLint buffer = 314159;
1257
1258 /* Error variable. */
1259 glw::GLenum error = 0;
1260
1261 /* Default result. */
1262 bool is_ok = true;
1263
1264 /* Test of GetTransformFeedbackiv. */
1265 m_gl_getTransformFeedbackiv(xfb, invalid_parameter_name, &buffer);
1266
1267 if (GL_INVALID_ENUM != (error = gl.getError()))
1268 {
1269 m_context.getTestContext().getLog() << tcu::TestLog::Message
1270 << "glGetTransformFeedbackiv called with invalid parameter name had been "
1271 "expected to generate GL_INVALID_ENUM. However, "
1272 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1273
1274 is_ok = false;
1275 }
1276
1277 if (314159 != buffer)
1278 {
1279 m_context.getTestContext().getLog() << tcu::TestLog::Message
1280 << "glGetTransformFeedbackiv called with invalid parameter name had been "
1281 "expected not to change the given buffer."
1282 << tcu::TestLog::EndMessage;
1283
1284 is_ok = false;
1285 }
1286
1287 while (GL_NO_ERROR != (error = gl.getError()))
1288 {
1289 m_context.getTestContext().getLog() << tcu::TestLog::Message
1290 << "Warning! glGetTransformFeedbackiv called with invalid parameter name "
1291 "has generated more than one error, The next error was "
1292 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1293 }
1294
1295 /* Clean-up. */
1296 gl.deleteTransformFeedbacks(1, &xfb);
1297 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");
1298
1299 return is_ok;
1300 }
1301
1302 /** @brief Test Direct State Access indexed integer query with invalid parameter name
1303 *
1304 * @note Test checks that GetTransformFeedbacki_v generates INVALID_ENUM error if pname
1305 * is not TRANSFORM_FEEDBACK_BUFFER_BINDING.
1306 *
1307 * @note The function may throw if unexpected error has occured.
1308 *
1309 * @return true if test succeded, false otherwise.
1310 */
testGetTransformFeedbacki_vQueryForInvalidParameterName()1311 bool ErrorsTest::testGetTransformFeedbacki_vQueryForInvalidParameterName()
1312 {
1313 /* Shortcut for GL functionality */
1314 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1315
1316 /* Creating XFB object. */
1317 glw::GLuint xfb = 0;
1318
1319 gl.createTransformFeedbacks(1, &xfb);
1320 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
1321
1322 /* Generating invalid parameter name. */
1323 glw::GLuint invalid_parameter_name = 0;
1324
1325 /* Unused storage. */
1326 glw::GLint buffer = 314159;
1327
1328 /* Error variable. */
1329 glw::GLenum error = 0;
1330
1331 /* Default result. */
1332 bool is_ok = true;
1333
1334 /* Test of GetTransformFeedbackiv. */
1335 m_gl_getTransformFeedbacki_v(xfb, invalid_parameter_name, 0, &buffer);
1336
1337 if (GL_INVALID_ENUM != (error = gl.getError()))
1338 {
1339 m_context.getTestContext().getLog() << tcu::TestLog::Message
1340 << "glGetTransformFeedbacki_v called with invalid parameter name had been "
1341 "expected to generate GL_INVALID_ENUM. However, "
1342 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1343
1344 is_ok = false;
1345 }
1346
1347 if (314159 != buffer)
1348 {
1349 m_context.getTestContext().getLog() << tcu::TestLog::Message
1350 << "glGetTransformFeedbacki_v called with invalid parameter name had been "
1351 "expected not to change the given buffer."
1352 << tcu::TestLog::EndMessage;
1353
1354 is_ok = false;
1355 }
1356
1357 while (GL_NO_ERROR != (error = gl.getError()))
1358 {
1359 m_context.getTestContext().getLog() << tcu::TestLog::Message
1360 << "Warning! glGetTransformFeedbacki_v called with invalid parameter name "
1361 "has generated more than one error, The next error was "
1362 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1363 }
1364
1365 /* Clean-up. */
1366 gl.deleteTransformFeedbacks(1, &xfb);
1367 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");
1368
1369 return is_ok;
1370 }
1371
1372 /** @brief Test Direct State Access indexed 64 bit integer query with invalid parameter name
1373 *
1374 * @note Test checks that GetTransformFeedbacki64_v generates INVALID_ENUM error if
1375 * pname is not TRANSFORM_FEEDBACK_BUFFER_START or
1376 * TRANSFORM_FEEDBACK_BUFFER_SIZE.
1377 *
1378 * @note The function may throw if unexpected error has occured.
1379 *
1380 * @return true if test succeded, false otherwise.
1381 */
testGetTransformFeedbacki64_vQueryForInvalidParameterName()1382 bool ErrorsTest::testGetTransformFeedbacki64_vQueryForInvalidParameterName()
1383 {
1384 /* Shortcut for GL functionality */
1385 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1386
1387 /* Creating XFB object. */
1388 glw::GLuint xfb = 0;
1389
1390 gl.createTransformFeedbacks(1, &xfb);
1391 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
1392
1393 /* Generating invalid parameter name. */
1394 glw::GLuint invalid_parameter_name = 0;
1395
1396 /* Unused storage. */
1397 glw::GLint64 buffer = 314159;
1398
1399 /* Error variable. */
1400 glw::GLenum error = 0;
1401
1402 /* Default result. */
1403 bool is_ok = true;
1404
1405 /* Test of GetTransformFeedbackiv. */
1406 m_gl_getTransformFeedbacki64_v(xfb, invalid_parameter_name, 0, &buffer);
1407
1408 if (GL_INVALID_ENUM != (error = gl.getError()))
1409 {
1410 m_context.getTestContext().getLog() << tcu::TestLog::Message
1411 << "glGetTransformFeedbacki64_v called with invalid parameter name had "
1412 "been expected to generate GL_INVALID_ENUM. However, "
1413 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1414
1415 is_ok = false;
1416 }
1417
1418 if (314159 != buffer)
1419 {
1420 m_context.getTestContext().getLog() << tcu::TestLog::Message
1421 << "glGetTransformFeedbacki64_v called with invalid parameter name had "
1422 "been expected not to change the given buffer."
1423 << tcu::TestLog::EndMessage;
1424
1425 is_ok = false;
1426 }
1427
1428 while (GL_NO_ERROR != (error = gl.getError()))
1429 {
1430 m_context.getTestContext().getLog() << tcu::TestLog::Message
1431 << "Warning! glGetTransformFeedbacki64_v called with invalid parameter "
1432 "name has generated more than one error, The next error was "
1433 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1434 }
1435
1436 /* Clean-up. */
1437 gl.deleteTransformFeedbacks(1, &xfb);
1438 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");
1439
1440 return is_ok;
1441 }
1442
1443 /** @brief Test Direct State Access indexed queries with invalid index
1444 *
1445 * @note Test checks that GetTransformFeedbacki_v and GetTransformFeedbacki64_v
1446 * generate INVALID_VALUE error by GetTransformFeedbacki_v and
1447 * GetTransformFeedbacki64_v if index is greater than or equal to the
1448 * number of binding points for transform feedback (the value of
1449 * MAX_TRANSFORM_FEEDBACK_BUFFERS).
1450 *
1451 * @note The function may throw if unexpected error has occured.
1452 *
1453 * @return true if test succeded, false otherwise.
1454 */
testIndexedQueriesForInvalidBindingPoint()1455 bool ErrorsTest::testIndexedQueriesForInvalidBindingPoint()
1456 {
1457 /* Shortcut for GL functionality */
1458 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1459
1460 /* Generating invalid index. */
1461 glw::GLint max_transform_feedback_buffers =
1462 4; /* Default limit is 4 - OpenGL 4.5 Core Specification, Table 23.72: Implementation Dependent Transform Feedback Limits. */
1463
1464 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
1465 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv have failed");
1466
1467 /* Creating XFB object. */
1468 glw::GLuint xfb = 0;
1469
1470 gl.createTransformFeedbacks(1, &xfb);
1471 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
1472
1473 /* Unused storage. */
1474 glw::GLint buffer = 314159;
1475 glw::GLint64 buffer64 = 314159;
1476
1477 /* Error variable. */
1478 glw::GLenum error = 0;
1479
1480 /* Default result. */
1481 bool is_ok = true;
1482
1483 /* Test of GetTransformFeedbacki_v. */
1484 m_gl_getTransformFeedbacki_v(xfb, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, max_transform_feedback_buffers, &buffer);
1485
1486 if (GL_INVALID_VALUE != (error = gl.getError()))
1487 {
1488 m_context.getTestContext().getLog() << tcu::TestLog::Message
1489 << "glGetTransformFeedbacki_v called with invalid index had been expected "
1490 "to generate GL_INVALID_VALUE. However, "
1491 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1492
1493 is_ok = false;
1494 }
1495
1496 if (314159 != buffer)
1497 {
1498 m_context.getTestContext().getLog()
1499 << tcu::TestLog::Message
1500 << "glGetTransformFeedbacki_v called with invalid index had been expected not to change the given buffer."
1501 << tcu::TestLog::EndMessage;
1502
1503 is_ok = false;
1504 }
1505
1506 while (GL_NO_ERROR != (error = gl.getError()))
1507 {
1508 m_context.getTestContext().getLog() << tcu::TestLog::Message
1509 << "Warning! glGetTransformFeedbacki_v called with invalid index has "
1510 "unexpectedly generated more than one error, The next error was "
1511 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1512 }
1513
1514 /* Test of GetTransformFeedbacki64_v. */
1515 m_gl_getTransformFeedbacki64_v(xfb, GL_TRANSFORM_FEEDBACK_BUFFER_START, max_transform_feedback_buffers, &buffer64);
1516
1517 if (GL_INVALID_VALUE != (error = gl.getError()))
1518 {
1519 m_context.getTestContext().getLog() << tcu::TestLog::Message
1520 << "glGetTransformFeedbacki64_v called with invalid index had been "
1521 "expected to generate GL_INVALID_VALUE. However, "
1522 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1523
1524 is_ok = false;
1525 }
1526
1527 if (314159 != buffer64)
1528 {
1529 m_context.getTestContext().getLog()
1530 << tcu::TestLog::Message
1531 << "glGetTransformFeedbacki64_v called with invalid index had been expected not to change the given buffer."
1532 << tcu::TestLog::EndMessage;
1533
1534 is_ok = false;
1535 }
1536
1537 while (GL_NO_ERROR != (error = gl.getError()))
1538 {
1539 m_context.getTestContext().getLog() << tcu::TestLog::Message
1540 << "Warning! glGetTransformFeedbacki64_v called with invalid index has "
1541 "unexpectedly generated more than one error, The next error was "
1542 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1543 }
1544
1545 /* Clean-up. */
1546 gl.deleteTransformFeedbacks(1, &xfb);
1547 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");
1548
1549 return is_ok;
1550 }
1551
1552 /******************************** Functional Test Implementation ********************************/
1553
1554 /** @brief Functional Test constructor.
1555 *
1556 * @param [in] context OpenGL context.
1557 */
FunctionalTest(deqp::Context & context)1558 FunctionalTest::FunctionalTest(deqp::Context &context)
1559 : deqp::TestCase(context, "xfb_functional", "Transform Feedback Functional Test")
1560 , m_gl_getTransformFeedbackiv(DE_NULL)
1561 , m_gl_TransformFeedbackBufferBase(DE_NULL)
1562 , m_xfb_dsa(0)
1563 , m_bo(0)
1564 , m_po(0)
1565 , m_vao(0)
1566 {
1567 /* Intentionally left blank. */
1568 }
1569
1570 /** @brief Iterate Functional Test cases.
1571 *
1572 * @return Iteration result.
1573 */
iterate()1574 tcu::TestNode::IterateResult FunctionalTest::iterate()
1575 {
1576 /* Get context setup. */
1577 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
1578 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
1579
1580 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
1581 {
1582 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1583
1584 return STOP;
1585 }
1586
1587 /* Running tests. */
1588 bool is_ok = true;
1589 bool is_error = false;
1590
1591 try
1592 {
1593 prepareFunctionPointers();
1594 prepareTransformFeedback();
1595 prepareBuffer();
1596 prepareProgram();
1597 prepareVertexArrayObject();
1598
1599 is_ok &= draw();
1600 is_ok &= verifyBufferContent();
1601 }
1602 catch (...)
1603 {
1604 is_ok = false;
1605 is_error = true;
1606 }
1607
1608 /* Releasing GL objects. */
1609 clean();
1610
1611 /* Result's setup. */
1612 if (is_ok)
1613 {
1614 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1615 }
1616 else
1617 {
1618 if (is_error)
1619 {
1620 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1621 }
1622 else
1623 {
1624 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1625 }
1626 }
1627
1628 return STOP;
1629 }
1630
1631 /** @brief Get access pointers to GL functions.
1632 *
1633 * @note The function may throw if unexpected error has occured.
1634 */
prepareFunctionPointers()1635 void FunctionalTest::prepareFunctionPointers()
1636 {
1637 /* Shortcut for GL functionality */
1638 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1639
1640 /* Fetching function pointers. */
1641 m_gl_getTransformFeedbackiv = (GetTransformFeedbackiv_ProcAddress)gl.getTransformFeedbackiv;
1642 m_gl_TransformFeedbackBufferBase = (TransformFeedbackBufferBase_ProcAddress)gl.transformFeedbackBufferBase;
1643
1644 if ((DE_NULL == m_gl_getTransformFeedbackiv) || (DE_NULL == m_gl_TransformFeedbackBufferBase))
1645 {
1646 m_context.getTestContext().getLog()
1647 << tcu::TestLog::Message << "Function pointers are set to NULL values." << tcu::TestLog::EndMessage;
1648
1649 throw 0;
1650 }
1651 }
1652
1653 /** @brief Create transform feedback object using direct access function.
1654 *
1655 * @note The function may throw if unexpected error has occured.
1656 */
prepareTransformFeedback()1657 void FunctionalTest::prepareTransformFeedback()
1658 {
1659 /* Shortcut for GL functionality */
1660 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1661
1662 /* XFB object creation. */
1663 gl.createTransformFeedbacks(1, &m_xfb_dsa);
1664 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
1665 }
1666
1667 /** @brief Create buffer object and bind it to transform feedback object using direct access function.
1668 *
1669 * @note The function may throw if unexpected error has occured.
1670 */
prepareBuffer()1671 void FunctionalTest::prepareBuffer()
1672 {
1673 /* Shortcut for GL functionality */
1674 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1675
1676 /* Buffer creation and memory allocation. */
1677 gl.genBuffers(1, &m_bo);
1678 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");
1679
1680 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo);
1681 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer have failed");
1682
1683 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, DE_NULL, GL_DYNAMIC_COPY);
1684 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed");
1685
1686 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
1687 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer have failed");
1688
1689 /* Bind buffer to xfb object (using direct state access function). */
1690 m_gl_TransformFeedbackBufferBase(m_xfb_dsa, 0, m_bo);
1691 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackBufferBase have failed");
1692 }
1693
1694 /** @brief Build test's GLSL program.
1695 *
1696 * @note The function may throw if unexpected error has occured.
1697 */
prepareProgram()1698 void FunctionalTest::prepareProgram()
1699 {
1700 /* Shortcut for GL functionality */
1701 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1702
1703 struct Shader
1704 {
1705 glw::GLchar const *const source;
1706 glw::GLenum const type;
1707 glw::GLuint id;
1708 } shader[] = {{s_vertex_shader, GL_VERTEX_SHADER, 0}, {s_fragment_shader, GL_FRAGMENT_SHADER, 0}};
1709
1710 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
1711
1712 try
1713 {
1714 /* Create program. */
1715 m_po = gl.createProgram();
1716 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
1717
1718 /* Shader compilation. */
1719
1720 for (glw::GLuint i = 0; i < shader_count; ++i)
1721 {
1722 if (DE_NULL != shader[i].source)
1723 {
1724 shader[i].id = gl.createShader(shader[i].type);
1725
1726 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
1727
1728 gl.attachShader(m_po, shader[i].id);
1729
1730 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
1731
1732 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
1733
1734 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
1735
1736 gl.compileShader(shader[i].id);
1737
1738 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
1739
1740 glw::GLint status = GL_FALSE;
1741
1742 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
1743 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
1744
1745 if (GL_FALSE == status)
1746 {
1747 glw::GLint log_size = 0;
1748 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
1749 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
1750
1751 glw::GLchar *log_text = new glw::GLchar[log_size];
1752
1753 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
1754
1755 m_context.getTestContext().getLog()
1756 << tcu::TestLog::Message << "Shader compilation has failed.\n"
1757 << "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
1758 << "Shader compilation error log:\n"
1759 << log_text << "\n"
1760 << "Shader source code:\n"
1761 << shader[i].source << "\n"
1762 << tcu::TestLog::EndMessage;
1763
1764 delete[] log_text;
1765
1766 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
1767
1768 throw 0;
1769 }
1770 }
1771 }
1772
1773 /* Transform Feedback setup. */
1774 gl.transformFeedbackVaryings(m_po, 1, &s_xfb_varying, GL_INTERLEAVED_ATTRIBS);
1775 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
1776
1777 /* Link. */
1778 gl.linkProgram(m_po);
1779
1780 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
1781
1782 glw::GLint status = GL_FALSE;
1783
1784 gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
1785
1786 if (GL_TRUE == status)
1787 {
1788 for (glw::GLuint i = 0; i < shader_count; ++i)
1789 {
1790 if (shader[i].id)
1791 {
1792 gl.detachShader(m_po, shader[i].id);
1793
1794 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
1795 }
1796 }
1797 }
1798 else
1799 {
1800 glw::GLint log_size = 0;
1801
1802 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
1803
1804 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
1805
1806 glw::GLchar *log_text = new glw::GLchar[log_size];
1807
1808 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
1809
1810 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
1811 << log_text << "\n"
1812 << tcu::TestLog::EndMessage;
1813
1814 delete[] log_text;
1815
1816 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
1817
1818 throw 0;
1819 }
1820 }
1821 catch (...)
1822 {
1823 if (m_po)
1824 {
1825 gl.deleteProgram(m_po);
1826
1827 m_po = 0;
1828 }
1829 }
1830
1831 for (glw::GLuint i = 0; i < shader_count; ++i)
1832 {
1833 if (0 != shader[i].id)
1834 {
1835 gl.deleteShader(shader[i].id);
1836
1837 shader[i].id = 0;
1838 }
1839 }
1840
1841 if (m_po)
1842 {
1843 gl.useProgram(m_po);
1844 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
1845 }
1846
1847 if (0 == m_po)
1848 {
1849 throw 0;
1850 }
1851 }
1852
1853 /** @brief Create and bind empty vertex array object.
1854 *
1855 * @note The function may throw if unexpected error has occured.
1856 */
prepareVertexArrayObject()1857 void FunctionalTest::prepareVertexArrayObject()
1858 {
1859 /* Shortcut for GL functionality */
1860 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1861
1862 /* Creating and binding empty vertex array object. */
1863 gl.genVertexArrays(1, &m_vao);
1864 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
1865
1866 gl.bindVertexArray(m_vao);
1867 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
1868 }
1869
1870 /** @brief Draw with XFB.
1871 *
1872 * @note Function follows steps:
1873 * Begin transform feedback environment.
1874 *
1875 * Using the program with discarded rasterizer, draw array of 4 indices
1876 * using POINTS.
1877 *
1878 * Pause transform feedback environment.
1879 *
1880 * Query parameter TRANSFORM_FEEDBACK_PAUSED using GetTransformFeedbackiv.
1881 * Expect value equal to TRUE.
1882 *
1883 * Query parameter TRANSFORM_FEEDBACK_ACTIVE using GetTransformFeedbackiv.
1884 * Expect value equal to TRUE.
1885 *
1886 * Resume transform feedback environment.
1887 *
1888 * Query parameter TRANSFORM_FEEDBACK_PAUSED using GetTransformFeedbackiv.
1889 * Expect value equal to FALSE.
1890 *
1891 * Query parameter TRANSFORM_FEEDBACK_ACTIVE using GetTransformFeedbackiv.
1892 * Expect value equal to TRUE.
1893 *
1894 * End Transform feedback environment.
1895 *
1896 * Query parameter TRANSFORM_FEEDBACK_ACTIVE using GetTransformFeedbackiv.
1897 * Expect value equal to FALSE.
1898 *
1899 * @note The function may throw if unexpected error has occured.
1900 *
1901 * @return True if included tests succeded, false otherwise.
1902 */
draw()1903 bool FunctionalTest::draw()
1904 {
1905 /* Shortcut for GL functionality */
1906 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1907
1908 /* Default result. */
1909 bool is_ok = true;
1910
1911 /* Start transform feedback environment. */
1912 gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_dsa);
1913 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback call failed.");
1914
1915 gl.beginTransformFeedback(GL_POINTS);
1916 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
1917
1918 /* Use only xfb. No rendering. */
1919 gl.enable(GL_RASTERIZER_DISCARD);
1920 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed.");
1921
1922 /* Draw. */
1923 gl.drawArrays(GL_POINTS, 0, 4);
1924 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
1925
1926 /* Pause Transform Feedback and tests direct state queries related to paused state. */
1927 gl.pauseTransformFeedback();
1928 GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback call failed.");
1929
1930 is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_PAUSED, GL_TRUE);
1931 is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_ACTIVE, GL_TRUE);
1932
1933 /* Activate Transform Feedback and tests direct state queries related to paused state. */
1934 gl.resumeTransformFeedback();
1935 GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback call failed.");
1936
1937 is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_PAUSED, GL_FALSE);
1938 is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_ACTIVE, GL_TRUE);
1939
1940 /* Finish transform feedback. */
1941 gl.endTransformFeedback();
1942 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
1943
1944 is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_ACTIVE, GL_FALSE);
1945
1946 return is_ok;
1947 }
1948
1949 /** @brief Check that selected Transform Feedback state has an expected value.
1950 *
1951 * @param [in] parameter_name Name of the parameter to be queried.
1952 * It must be GL_TRANSFORM_FEEDBACK_PAUSED or
1953 * GL_TRANSFORM_FEEDBACK_ACTIVE
1954 * @param [in] expected_value The expected value of the query.
1955 *
1956 * @note The function may throw if unexpected error has occured.
1957 *
1958 * @return True if the queried value is equal to expected value, false otherwise.
1959 */
testTransformFeedbackStatus(glw::GLenum parameter_name,glw::GLint expected_value)1960 bool FunctionalTest::testTransformFeedbackStatus(glw::GLenum parameter_name, glw::GLint expected_value)
1961 {
1962 /* Shortcut for GL functionality */
1963 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1964
1965 /* Unused storage. */
1966 glw::GLint value = 314159;
1967
1968 /* Test of GetTransformFeedbackiv. */
1969 m_gl_getTransformFeedbackiv(m_xfb_dsa, parameter_name, &value);
1970 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbackiv call failed.");
1971
1972 if (expected_value != value)
1973 {
1974 m_context.getTestContext().getLog()
1975 << tcu::TestLog::Message << "It was expected that glGetTransformFeedbackiv query of parameter "
1976 << ((parameter_name == GL_TRANSFORM_FEEDBACK_PAUSED) ? "GL_TRANSFORM_FEEDBACK_PAUSED" :
1977 "GL_TRANSFORM_FEEDBACK_ACTIVE")
1978 << " shall return " << ((expected_value == GL_TRUE) ? "GL_TRUE" : "GL_FALSE") << "however, "
1979 << ((value == GL_TRUE) ? "GL_TRUE" : "GL_FALSE") << " was returned." << tcu::TestLog::EndMessage;
1980
1981 return false;
1982 }
1983
1984 return true;
1985 }
1986
1987 /** @brief Check that transform feedback buffer contains
1988 * consecutive integer numbers from 0 to 3 (included).
1989 *
1990 * @note The function may throw if unexpected error has occured.
1991 *
1992 * @return True if buffer conatins consecutive integer
1993 * numbers from 0 to 3 (included), false otherwise.
1994 */
verifyBufferContent()1995 bool FunctionalTest::verifyBufferContent()
1996 {
1997 /* Shortcut for GL functionality */
1998 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1999
2000 /* Default result. */
2001 bool is_ok = true;
2002
2003 /* Mapping buffer object to the user-space. */
2004 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo);
2005 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
2006
2007 glw::GLint *buffer = (glw::GLint *)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
2008 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
2009
2010 for (glw::GLint i = 0; i < 4 /* Number of emitted vertices. */; ++i)
2011 {
2012 if (buffer[i] != i)
2013 {
2014 is_ok = false;
2015
2016 break;
2017 }
2018 }
2019
2020 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
2021 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
2022
2023 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
2024 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
2025
2026 return is_ok;
2027 }
2028
2029 /** Release GL objects, return to the default state
2030 */
clean()2031 void FunctionalTest::clean()
2032 {
2033 /* Shortcut for GL functionality */
2034 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2035
2036 /* Release transform feedback object. */
2037 if (m_xfb_dsa)
2038 {
2039 gl.deleteTransformFeedbacks(1, &m_xfb_dsa);
2040
2041 m_xfb_dsa = 0;
2042 }
2043
2044 /* Release buffer object. */
2045 if (m_bo)
2046 {
2047 gl.deleteBuffers(1, &m_bo);
2048
2049 m_bo = 0;
2050 }
2051
2052 /* Release GLSL program. */
2053 if (m_po)
2054 {
2055 gl.useProgram(0);
2056
2057 gl.deleteProgram(m_po);
2058
2059 m_po = 0;
2060 }
2061
2062 /* Release vertex array object. */
2063 if (m_vao)
2064 {
2065 gl.bindVertexArray(0);
2066
2067 gl.deleteVertexArrays(1, &m_vao);
2068
2069 m_vao = 0;
2070 }
2071
2072 /* Returning to default rasterizer state. */
2073 gl.disable(GL_RASTERIZER_DISCARD);
2074 }
2075
2076 const glw::GLuint FunctionalTest::s_bo_size = 4 * sizeof(glw::GLint);
2077
2078 const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 130\n"
2079 "\n"
2080 "out int result;\n"
2081 "\n"
2082 "void main()\n"
2083 "{\n"
2084 "\n"
2085 " result = gl_VertexID;\n"
2086 " gl_Position = vec4(1.0);\n"
2087 "}\n";
2088
2089 const glw::GLchar FunctionalTest::s_fragment_shader[] = "#version 130\n"
2090 "\n"
2091 "out vec4 color;\n"
2092 "\n"
2093 "void main()\n"
2094 "{\n"
2095 " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
2096 "}\n";
2097
2098 const glw::GLchar *const FunctionalTest::s_xfb_varying = "result";
2099
2100 } // namespace TransformFeedback
2101 } // namespace DirectStateAccess
2102 } // namespace gl4cts
2103