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() << tcu::TestLog::Message
133 << "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() << tcu::TestLog::Message << "Function pointers are set to NULL values."
306 << 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() << tcu::TestLog::Message << "Function pointers are set to NULL values."
644 << 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() << tcu::TestLog::Message
661 << "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() << tcu::TestLog::Message << "Buffer allocation failed."
683 << 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() << tcu::TestLog::Message << "Buffer allocation failed."
704 << 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 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING "
786 "has not returned anything and error has not been generated."
787 << tcu::TestLog::EndMessage;
788
789 return false;
790 }
791 else
792 {
793 if (expected_value != buffer_binding)
794 {
795 m_context.getTestContext().getLog()
796 << tcu::TestLog::Message
797 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING has returned "
798 << buffer_binding << ", however " << expected_value << " is expected. As a consequence function "
799 << tested_function_name << " have failed to setup proper value." << tcu::TestLog::EndMessage;
800
801 return false;
802 }
803 }
804
805 return true;
806 }
807
808 /** @brief Test that buffer object at xfb object's binding point #<index> has starting offset set to the <expected_value>.
809 *
810 * @param [in] index Tested index point.
811 * @param [in] expected_value Value to be expected (starting offset).
812 * @param [in] tested_function_name Name of function which this function is going to test
813 * (glTransformFeedbackBufferBase or glTransformFeedbackBufferRange)
814 * for logging purposes.
815 *
816 * @note The function may throw if unexpected error has occured.
817 *
818 * @return True if test succeeded, false otherwise.
819 */
testStart(glw::GLuint const index,glw::GLint const expected_value,glw::GLchar const * const tested_function_name)820 bool BuffersTest::testStart(glw::GLuint const index, glw::GLint const expected_value,
821 glw::GLchar const* const tested_function_name)
822 {
823 /* Shortcut for GL functionality */
824 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
825
826 /* Check default buffers' start value. */
827 glw::GLint64 buffer_start = -1;
828
829 m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_START, index, &buffer_start);
830 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");
831
832 /* Checking results and errors. */
833 if (-1 == buffer_start)
834 {
835 m_context.getTestContext().getLog()
836 << tcu::TestLog::Message << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START "
837 "has not returned anything and error has not been generated."
838 << tcu::TestLog::EndMessage;
839
840 return false;
841 }
842 else
843 {
844 if (expected_value != buffer_start)
845 {
846 m_context.getTestContext().getLog()
847 << tcu::TestLog::Message
848 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START has returned "
849 << buffer_start << ", however " << expected_value << " is expected. As a consequence function "
850 << tested_function_name << " have failed to setup proper value." << tcu::TestLog::EndMessage;
851
852 return false;
853 }
854 }
855
856 return true;
857 }
858
859 /** @brief Test that buffer object at xfb object's binding point #<index> has size set to the <expected_value>.
860 *
861 * @param [in] index Tested index point.
862 * @param [in] expected_value Value to be expected (buffer's size).
863 * @param [in] tested_function_name Name of function which this function is going to test
864 * (glTransformFeedbackBufferBase or glTransformFeedbackBufferRange)
865 * for logging purposes.
866 *
867 * @note The function may throw if unexpected error has occured.
868 *
869 * @return True if test succeeded, false otherwise.
870 */
testSize(glw::GLuint const index,glw::GLint const expected_value,glw::GLchar const * const tested_function_name)871 bool BuffersTest::testSize(glw::GLuint const index, glw::GLint const expected_value,
872 glw::GLchar const* const tested_function_name)
873 {
874 /* Shortcut for GL functionality */
875 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
876
877 /* Check default buffer's size value. */
878 glw::GLint64 buffer_size = -1;
879
880 m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, index, &buffer_size);
881 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");
882
883 /* Checking results and errors. */
884 if (-1 == buffer_size)
885 {
886 m_context.getTestContext().getLog()
887 << tcu::TestLog::Message << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE "
888 "has not returned anything and error has not been generated."
889 << tcu::TestLog::EndMessage;
890
891 return false;
892 }
893 else
894 {
895 if (expected_value != buffer_size)
896 {
897 m_context.getTestContext().getLog()
898 << tcu::TestLog::Message
899 << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE has returned "
900 << buffer_size << ", however " << expected_value << " is expected. As a consequence function "
901 << tested_function_name << " have failed to setup proper value." << tcu::TestLog::EndMessage;
902
903 return false;
904 }
905 }
906
907 return true;
908 }
909
910 /** @brief Clean al GL objects
911 */
clean()912 void BuffersTest::clean()
913 {
914 /* Shortcut for GL functionality */
915 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
916
917 /* Release transform feedback object. */
918 if (m_xfb_dsa)
919 {
920 gl.deleteTransformFeedbacks(1, &m_xfb_dsa);
921
922 m_xfb_dsa = 0;
923 }
924
925 /* Release buffer objects. */
926 if (m_bo_a)
927 {
928 gl.deleteBuffers(1, &m_bo_a);
929
930 m_bo_a = 0;
931 }
932
933 if (m_bo_b)
934 {
935 gl.deleteBuffers(1, &m_bo_b);
936
937 m_bo_b = 0;
938 }
939 }
940
941 /** @brief Buffer Object Size */
942 const glw::GLuint BuffersTest::s_bo_size = 512;
943
944 /******************************** Errors Test Implementation ********************************/
945
946 /** @brief Errors Test constructor.
947 *
948 * @param [in] context OpenGL context.
949 */
ErrorsTest(deqp::Context & context)950 ErrorsTest::ErrorsTest(deqp::Context& context)
951 : deqp::TestCase(context, "xfb_errors", "Transform Feedback Errors Test")
952 , m_gl_getTransformFeedbackiv(DE_NULL)
953 , m_gl_getTransformFeedbacki_v(DE_NULL)
954 , m_gl_getTransformFeedbacki64_v(DE_NULL)
955 {
956 /* Intentionally left blank. */
957 }
958
959 /** @brief Iterate Errors Test cases.
960 *
961 * @return Iteration result.
962 */
iterate()963 tcu::TestNode::IterateResult ErrorsTest::iterate()
964 {
965 /* Get context setup. */
966 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
967 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
968
969 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
970 {
971 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
972
973 return STOP;
974 }
975
976 /* Running tests. */
977 bool is_ok = true;
978 bool is_error = false;
979
980 try
981 {
982 prepareFunctionPointers();
983
984 is_ok &= testCreateTransformFeedbacksForInvalidNumberOfObjects();
985 cleanErrors();
986
987 is_ok &= testQueriesForInvalidNameOfObject();
988 cleanErrors();
989
990 is_ok &= testGetTransformFeedbackivQueryForInvalidParameterName();
991 cleanErrors();
992
993 is_ok &= testGetTransformFeedbacki_vQueryForInvalidParameterName();
994 cleanErrors();
995
996 is_ok &= testGetTransformFeedbacki64_vQueryForInvalidParameterName();
997 cleanErrors();
998
999 is_ok &= testIndexedQueriesForInvalidBindingPoint();
1000 cleanErrors();
1001 }
1002 catch (...)
1003 {
1004 is_ok = false;
1005 is_error = true;
1006 }
1007
1008 /* Result's setup. */
1009 if (is_ok)
1010 {
1011 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1012 }
1013 else
1014 {
1015 if (is_error)
1016 {
1017 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1018 }
1019 else
1020 {
1021 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1022 }
1023 }
1024
1025 return STOP;
1026 }
1027
1028 /** @brief Fetch GL function pointers.
1029 *
1030 * @note The function may throw if unexpected error has occured.
1031 */
prepareFunctionPointers()1032 void ErrorsTest::prepareFunctionPointers()
1033 {
1034 /* Shortcut for GL functionality */
1035 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1036
1037 /* Fetching function pointers. */
1038 m_gl_getTransformFeedbackiv = (GetTransformFeedbackiv_ProcAddress)gl.getTransformFeedbackiv;
1039 m_gl_getTransformFeedbacki_v = (GetTransformFeedbacki_v_ProcAddress)gl.getTransformFeedbacki_v;
1040 m_gl_getTransformFeedbacki64_v = (GetTransformFeedbacki64_v_ProcAddress)gl.getTransformFeedbacki64_v;
1041
1042 if ((DE_NULL == m_gl_getTransformFeedbackiv) || (DE_NULL == m_gl_getTransformFeedbacki_v) ||
1043 (DE_NULL == m_gl_getTransformFeedbacki64_v))
1044 {
1045 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function pointers are set to NULL values."
1046 << tcu::TestLog::EndMessage;
1047
1048 throw 0;
1049 }
1050 }
1051
1052 /** @brief Sanity clean-up of GL errors.
1053 *
1054 * @note This function is to only make sure that failing test will not affect other tests.
1055 */
cleanErrors()1056 void ErrorsTest::cleanErrors()
1057 {
1058 /* Shortcut for GL functionality */
1059 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1060
1061 /* Cleaning errors. */
1062 while (GL_NO_ERROR != gl.getError())
1063 ;
1064 }
1065
1066 /** @brief Test Creation of Transform Feedbacks using Invalid Number Of Objects
1067 *
1068 * @note Test checks that CreateTransformFeedbacks generates INVALID_VALUE error if
1069 * number of transform feedback objects to create is negative.
1070 *
1071 * @return true if test succeded, false otherwise.
1072 */
testCreateTransformFeedbacksForInvalidNumberOfObjects()1073 bool ErrorsTest::testCreateTransformFeedbacksForInvalidNumberOfObjects()
1074 {
1075 /* Shortcut for GL functionality */
1076 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1077
1078 glw::GLuint xfbs = 314159;
1079
1080 gl.createTransformFeedbacks(-1 /* invalid count */, &xfbs);
1081
1082 glw::GLenum error = gl.getError();
1083
1084 if (GL_INVALID_VALUE != error)
1085 {
1086 m_context.getTestContext().getLog() << tcu::TestLog::Message
1087 << "glCreateTransformFeedbacks called with negative number of objects had "
1088 "been expected to generate GL_INVALID_VALUE. However, "
1089 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1090
1091 return false;
1092 }
1093
1094 if (314159 != xfbs)
1095 {
1096 m_context.getTestContext().getLog() << tcu::TestLog::Message
1097 << "glCreateTransformFeedbacks called with negative number of objects had "
1098 "been expected not to change the given buffer."
1099 << tcu::TestLog::EndMessage;
1100
1101 return false;
1102 }
1103
1104 return true;
1105 }
1106
1107 /** @brief Test Direct State Access queries with invalid object name
1108 *
1109 * @note Test checks that GetTransformFeedbackiv, GetTransformFeedbacki_v and
1110 * GetTransformFeedbacki64_v generate INVALID_OPERATION error if xfb is not
1111 * zero or the name of an existing transform feedback object.
1112 *
1113 * @return true if test succeded, false otherwise.
1114 */
testQueriesForInvalidNameOfObject()1115 bool ErrorsTest::testQueriesForInvalidNameOfObject()
1116 {
1117 /* Shortcut for GL functionality */
1118 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1119
1120 /* Generating not a-TransformFeedback name. */
1121 glw::GLuint invalid_name = 0;
1122
1123 while (GL_TRUE == gl.isTransformFeedback(++invalid_name))
1124 ;
1125
1126 /* Dummy storage. */
1127 glw::GLint buffer = 314159;
1128 glw::GLint64 buffer64 = 314159;
1129
1130 /* Error variable. */
1131 glw::GLenum error = 0;
1132
1133 /* Test of GetTransformFeedbackiv. */
1134 m_gl_getTransformFeedbackiv(invalid_name, GL_TRANSFORM_FEEDBACK_PAUSED, &buffer);
1135
1136 if (GL_INVALID_OPERATION != (error = gl.getError()))
1137 {
1138 m_context.getTestContext().getLog() << tcu::TestLog::Message
1139 << "glGetTransformFeedbackiv called with invalid object name had been "
1140 "expected to generate GL_INVALID_OPERATION. However, "
1141 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1142
1143 return false;
1144 }
1145
1146 if (314159 != buffer)
1147 {
1148 m_context.getTestContext().getLog() << tcu::TestLog::Message
1149 << "glGetTransformFeedbackiv called with invalid object name had been "
1150 "expected not to change the given buffer."
1151 << tcu::TestLog::EndMessage;
1152
1153 return false;
1154 }
1155
1156 while (GL_NO_ERROR != (error = gl.getError()))
1157 {
1158 m_context.getTestContext().getLog() << tcu::TestLog::Message
1159 << "Warning! glGetTransformFeedbackiv called with invalid object name has "
1160 "generated more than one error, The next error was "
1161 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1162 }
1163
1164 /* Test of GetTransformFeedbacki_v. */
1165 m_gl_getTransformFeedbacki_v(invalid_name, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, &buffer);
1166
1167 if (GL_INVALID_OPERATION != (error = gl.getError()))
1168 {
1169 m_context.getTestContext().getLog() << tcu::TestLog::Message
1170 << "glGetTransformFeedbacki_v called with invalid object name had been "
1171 "expected to generate GL_INVALID_OPERATION. However, "
1172 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1173
1174 return false;
1175 }
1176
1177 if (314159 != buffer)
1178 {
1179 m_context.getTestContext().getLog() << tcu::TestLog::Message
1180 << "glGetTransformFeedbacki_v called with invalid object name had been "
1181 "expected not to change the given buffer."
1182 << tcu::TestLog::EndMessage;
1183
1184 return false;
1185 }
1186
1187 while (GL_NO_ERROR != (error = gl.getError()))
1188 {
1189 m_context.getTestContext().getLog() << tcu::TestLog::Message
1190 << "Warning! glGetTransformFeedbacki_v called with invalid object name has "
1191 "unexpectedly generated more than one error, The next error was "
1192 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1193 }
1194
1195 /* Test of GetTransformFeedbacki64_v. */
1196 m_gl_getTransformFeedbacki64_v(invalid_name, GL_TRANSFORM_FEEDBACK_BUFFER_START, 0, &buffer64);
1197
1198 if (GL_INVALID_OPERATION != (error = gl.getError()))
1199 {
1200 m_context.getTestContext().getLog() << tcu::TestLog::Message
1201 << "glGetTransformFeedbacki64_v called with invalid object name had been "
1202 "expected to generate GL_INVALID_OPERATION. However, "
1203 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1204
1205 return false;
1206 }
1207
1208 if (314159 != buffer64)
1209 {
1210 m_context.getTestContext().getLog() << tcu::TestLog::Message
1211 << "glGetTransformFeedbacki64_v called with invalid object name had been "
1212 "expected not to change the given buffer."
1213 << tcu::TestLog::EndMessage;
1214
1215 return false;
1216 }
1217
1218 while (GL_NO_ERROR != (error = gl.getError()))
1219 {
1220 m_context.getTestContext().getLog() << tcu::TestLog::Message
1221 << "Warning! glGetTransformFeedbacki64_v called with invalid object name "
1222 "has unexpectedly generated more than one error, The next error was "
1223 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1224 }
1225
1226 return true;
1227 }
1228
1229 /** @brief Test Direct State Access queries with invalid parameter name
1230 *
1231 * @note Test checks that GetTransformFeedbackiv generates INVALID_ENUM error if pname
1232 * is not TRANSFORM_FEEDBACK_PAUSED or TRANSFORM_FEEDBACK_ACTIVE.
1233 *
1234 * @note The function may throw if unexpected error has occured.
1235 *
1236 * @return true if test succeded, false otherwise.
1237 */
testGetTransformFeedbackivQueryForInvalidParameterName()1238 bool ErrorsTest::testGetTransformFeedbackivQueryForInvalidParameterName()
1239 {
1240 /* Shortcut for GL functionality */
1241 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1242
1243 /* Creating XFB object. */
1244 glw::GLuint xfb = 0;
1245
1246 gl.createTransformFeedbacks(1, &xfb);
1247 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
1248
1249 /* Generating invalid parameter name. */
1250 glw::GLuint invalid_parameter_name = 0;
1251
1252 /* Dummy storage. */
1253 glw::GLint buffer = 314159;
1254
1255 /* Error variable. */
1256 glw::GLenum error = 0;
1257
1258 /* Default result. */
1259 bool is_ok = true;
1260
1261 /* Test of GetTransformFeedbackiv. */
1262 m_gl_getTransformFeedbackiv(xfb, invalid_parameter_name, &buffer);
1263
1264 if (GL_INVALID_ENUM != (error = gl.getError()))
1265 {
1266 m_context.getTestContext().getLog() << tcu::TestLog::Message
1267 << "glGetTransformFeedbackiv called with invalid parameter name had been "
1268 "expected to generate GL_INVALID_ENUM. However, "
1269 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1270
1271 is_ok = false;
1272 }
1273
1274 if (314159 != buffer)
1275 {
1276 m_context.getTestContext().getLog() << tcu::TestLog::Message
1277 << "glGetTransformFeedbackiv called with invalid parameter name had been "
1278 "expected not to change the given buffer."
1279 << tcu::TestLog::EndMessage;
1280
1281 is_ok = false;
1282 }
1283
1284 while (GL_NO_ERROR != (error = gl.getError()))
1285 {
1286 m_context.getTestContext().getLog() << tcu::TestLog::Message
1287 << "Warning! glGetTransformFeedbackiv called with invalid parameter name "
1288 "has generated more than one error, The next error was "
1289 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1290 }
1291
1292 /* Clean-up. */
1293 gl.deleteTransformFeedbacks(1, &xfb);
1294 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");
1295
1296 return is_ok;
1297 }
1298
1299 /** @brief Test Direct State Access indexed integer query with invalid parameter name
1300 *
1301 * @note Test checks that GetTransformFeedbacki_v generates INVALID_ENUM error if pname
1302 * is not TRANSFORM_FEEDBACK_BUFFER_BINDING.
1303 *
1304 * @note The function may throw if unexpected error has occured.
1305 *
1306 * @return true if test succeded, false otherwise.
1307 */
testGetTransformFeedbacki_vQueryForInvalidParameterName()1308 bool ErrorsTest::testGetTransformFeedbacki_vQueryForInvalidParameterName()
1309 {
1310 /* Shortcut for GL functionality */
1311 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1312
1313 /* Creating XFB object. */
1314 glw::GLuint xfb = 0;
1315
1316 gl.createTransformFeedbacks(1, &xfb);
1317 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
1318
1319 /* Generating invalid parameter name. */
1320 glw::GLuint invalid_parameter_name = 0;
1321
1322 /* Dummy storage. */
1323 glw::GLint buffer = 314159;
1324
1325 /* Error variable. */
1326 glw::GLenum error = 0;
1327
1328 /* Default result. */
1329 bool is_ok = true;
1330
1331 /* Test of GetTransformFeedbackiv. */
1332 m_gl_getTransformFeedbacki_v(xfb, invalid_parameter_name, 0, &buffer);
1333
1334 if (GL_INVALID_ENUM != (error = gl.getError()))
1335 {
1336 m_context.getTestContext().getLog() << tcu::TestLog::Message
1337 << "glGetTransformFeedbacki_v called with invalid parameter name had been "
1338 "expected to generate GL_INVALID_ENUM. However, "
1339 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1340
1341 is_ok = false;
1342 }
1343
1344 if (314159 != buffer)
1345 {
1346 m_context.getTestContext().getLog() << tcu::TestLog::Message
1347 << "glGetTransformFeedbacki_v called with invalid parameter name had been "
1348 "expected not to change the given buffer."
1349 << tcu::TestLog::EndMessage;
1350
1351 is_ok = false;
1352 }
1353
1354 while (GL_NO_ERROR != (error = gl.getError()))
1355 {
1356 m_context.getTestContext().getLog() << tcu::TestLog::Message
1357 << "Warning! glGetTransformFeedbacki_v called with invalid parameter name "
1358 "has generated more than one error, The next error was "
1359 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1360 }
1361
1362 /* Clean-up. */
1363 gl.deleteTransformFeedbacks(1, &xfb);
1364 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");
1365
1366 return is_ok;
1367 }
1368
1369 /** @brief Test Direct State Access indexed 64 bit integer query with invalid parameter name
1370 *
1371 * @note Test checks that GetTransformFeedbacki64_v generates INVALID_ENUM error if
1372 * pname is not TRANSFORM_FEEDBACK_BUFFER_START or
1373 * TRANSFORM_FEEDBACK_BUFFER_SIZE.
1374 *
1375 * @note The function may throw if unexpected error has occured.
1376 *
1377 * @return true if test succeded, false otherwise.
1378 */
testGetTransformFeedbacki64_vQueryForInvalidParameterName()1379 bool ErrorsTest::testGetTransformFeedbacki64_vQueryForInvalidParameterName()
1380 {
1381 /* Shortcut for GL functionality */
1382 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1383
1384 /* Creating XFB object. */
1385 glw::GLuint xfb = 0;
1386
1387 gl.createTransformFeedbacks(1, &xfb);
1388 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
1389
1390 /* Generating invalid parameter name. */
1391 glw::GLuint invalid_parameter_name = 0;
1392
1393 /* Dummy storage. */
1394 glw::GLint64 buffer = 314159;
1395
1396 /* Error variable. */
1397 glw::GLenum error = 0;
1398
1399 /* Default result. */
1400 bool is_ok = true;
1401
1402 /* Test of GetTransformFeedbackiv. */
1403 m_gl_getTransformFeedbacki64_v(xfb, invalid_parameter_name, 0, &buffer);
1404
1405 if (GL_INVALID_ENUM != (error = gl.getError()))
1406 {
1407 m_context.getTestContext().getLog() << tcu::TestLog::Message
1408 << "glGetTransformFeedbacki64_v called with invalid parameter name had "
1409 "been expected to generate GL_INVALID_ENUM. However, "
1410 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1411
1412 is_ok = false;
1413 }
1414
1415 if (314159 != buffer)
1416 {
1417 m_context.getTestContext().getLog() << tcu::TestLog::Message
1418 << "glGetTransformFeedbacki64_v called with invalid parameter name had "
1419 "been expected not to change the given buffer."
1420 << tcu::TestLog::EndMessage;
1421
1422 is_ok = false;
1423 }
1424
1425 while (GL_NO_ERROR != (error = gl.getError()))
1426 {
1427 m_context.getTestContext().getLog() << tcu::TestLog::Message
1428 << "Warning! glGetTransformFeedbacki64_v called with invalid parameter "
1429 "name has generated more than one error, The next error was "
1430 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1431 }
1432
1433 /* Clean-up. */
1434 gl.deleteTransformFeedbacks(1, &xfb);
1435 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");
1436
1437 return is_ok;
1438 }
1439
1440 /** @brief Test Direct State Access indexed queries with invalid index
1441 *
1442 * @note Test checks that GetTransformFeedbacki_v and GetTransformFeedbacki64_v
1443 * generate INVALID_VALUE error by GetTransformFeedbacki_v and
1444 * GetTransformFeedbacki64_v if index is greater than or equal to the
1445 * number of binding points for transform feedback (the value of
1446 * MAX_TRANSFORM_FEEDBACK_BUFFERS).
1447 *
1448 * @note The function may throw if unexpected error has occured.
1449 *
1450 * @return true if test succeded, false otherwise.
1451 */
testIndexedQueriesForInvalidBindingPoint()1452 bool ErrorsTest::testIndexedQueriesForInvalidBindingPoint()
1453 {
1454 /* Shortcut for GL functionality */
1455 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1456
1457 /* Generating invalid index. */
1458 glw::GLint max_transform_feedback_buffers =
1459 4; /* Default limit is 4 - OpenGL 4.5 Core Specification, Table 23.72: Implementation Dependent Transform Feedback Limits. */
1460
1461 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
1462 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv have failed");
1463
1464 /* Creating XFB object. */
1465 glw::GLuint xfb = 0;
1466
1467 gl.createTransformFeedbacks(1, &xfb);
1468 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
1469
1470 /* Dummy storage. */
1471 glw::GLint buffer = 314159;
1472 glw::GLint64 buffer64 = 314159;
1473
1474 /* Error variable. */
1475 glw::GLenum error = 0;
1476
1477 /* Default result. */
1478 bool is_ok = true;
1479
1480 /* Test of GetTransformFeedbacki_v. */
1481 m_gl_getTransformFeedbacki_v(xfb, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, max_transform_feedback_buffers, &buffer);
1482
1483 if (GL_INVALID_VALUE != (error = gl.getError()))
1484 {
1485 m_context.getTestContext().getLog() << tcu::TestLog::Message
1486 << "glGetTransformFeedbacki_v called with invalid index had been expected "
1487 "to generate GL_INVALID_VALUE. However, "
1488 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1489
1490 is_ok = false;
1491 }
1492
1493 if (314159 != buffer)
1494 {
1495 m_context.getTestContext().getLog()
1496 << tcu::TestLog::Message
1497 << "glGetTransformFeedbacki_v called with invalid index had been expected not to change the given buffer."
1498 << tcu::TestLog::EndMessage;
1499
1500 is_ok = false;
1501 }
1502
1503 while (GL_NO_ERROR != (error = gl.getError()))
1504 {
1505 m_context.getTestContext().getLog() << tcu::TestLog::Message
1506 << "Warning! glGetTransformFeedbacki_v called with invalid index has "
1507 "unexpectedly generated more than one error, The next error was "
1508 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1509 }
1510
1511 /* Test of GetTransformFeedbacki64_v. */
1512 m_gl_getTransformFeedbacki64_v(xfb, GL_TRANSFORM_FEEDBACK_BUFFER_START, max_transform_feedback_buffers, &buffer64);
1513
1514 if (GL_INVALID_VALUE != (error = gl.getError()))
1515 {
1516 m_context.getTestContext().getLog() << tcu::TestLog::Message
1517 << "glGetTransformFeedbacki64_v called with invalid index had been "
1518 "expected to generate GL_INVALID_VALUE. However, "
1519 << glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
1520
1521 is_ok = false;
1522 }
1523
1524 if (314159 != buffer64)
1525 {
1526 m_context.getTestContext().getLog()
1527 << tcu::TestLog::Message
1528 << "glGetTransformFeedbacki64_v called with invalid index had been expected not to change the given buffer."
1529 << tcu::TestLog::EndMessage;
1530
1531 is_ok = false;
1532 }
1533
1534 while (GL_NO_ERROR != (error = gl.getError()))
1535 {
1536 m_context.getTestContext().getLog() << tcu::TestLog::Message
1537 << "Warning! glGetTransformFeedbacki64_v called with invalid index has "
1538 "unexpectedly generated more than one error, The next error was "
1539 << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1540 }
1541
1542 /* Clean-up. */
1543 gl.deleteTransformFeedbacks(1, &xfb);
1544 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");
1545
1546 return is_ok;
1547 }
1548
1549 /******************************** Functional Test Implementation ********************************/
1550
1551 /** @brief Functional Test constructor.
1552 *
1553 * @param [in] context OpenGL context.
1554 */
FunctionalTest(deqp::Context & context)1555 FunctionalTest::FunctionalTest(deqp::Context& context)
1556 : deqp::TestCase(context, "xfb_functional", "Transform Feedback Functional Test")
1557 , m_gl_getTransformFeedbackiv(DE_NULL)
1558 , m_gl_TransformFeedbackBufferBase(DE_NULL)
1559 , m_xfb_dsa(0)
1560 , m_bo(0)
1561 , m_po(0)
1562 , m_vao(0)
1563 {
1564 /* Intentionally left blank. */
1565 }
1566
1567 /** @brief Iterate Functional Test cases.
1568 *
1569 * @return Iteration result.
1570 */
iterate()1571 tcu::TestNode::IterateResult FunctionalTest::iterate()
1572 {
1573 /* Get context setup. */
1574 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
1575 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
1576
1577 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
1578 {
1579 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1580
1581 return STOP;
1582 }
1583
1584 /* Running tests. */
1585 bool is_ok = true;
1586 bool is_error = false;
1587
1588 try
1589 {
1590 prepareFunctionPointers();
1591 prepareTransformFeedback();
1592 prepareBuffer();
1593 prepareProgram();
1594 prepareVertexArrayObject();
1595
1596 is_ok &= draw();
1597 is_ok &= verifyBufferContent();
1598 }
1599 catch (...)
1600 {
1601 is_ok = false;
1602 is_error = true;
1603 }
1604
1605 /* Releasing GL objects. */
1606 clean();
1607
1608 /* Result's setup. */
1609 if (is_ok)
1610 {
1611 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1612 }
1613 else
1614 {
1615 if (is_error)
1616 {
1617 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1618 }
1619 else
1620 {
1621 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1622 }
1623 }
1624
1625 return STOP;
1626 }
1627
1628 /** @brief Get access pointers to GL functions.
1629 *
1630 * @note The function may throw if unexpected error has occured.
1631 */
prepareFunctionPointers()1632 void FunctionalTest::prepareFunctionPointers()
1633 {
1634 /* Shortcut for GL functionality */
1635 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1636
1637 /* Fetching function pointers. */
1638 m_gl_getTransformFeedbackiv = (GetTransformFeedbackiv_ProcAddress)gl.getTransformFeedbackiv;
1639 m_gl_TransformFeedbackBufferBase = (TransformFeedbackBufferBase_ProcAddress)gl.transformFeedbackBufferBase;
1640
1641 if ((DE_NULL == m_gl_getTransformFeedbackiv) || (DE_NULL == m_gl_TransformFeedbackBufferBase))
1642 {
1643 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function pointers are set to NULL values."
1644 << tcu::TestLog::EndMessage;
1645
1646 throw 0;
1647 }
1648 }
1649
1650 /** @brief Create transform feedback object using direct access function.
1651 *
1652 * @note The function may throw if unexpected error has occured.
1653 */
prepareTransformFeedback()1654 void FunctionalTest::prepareTransformFeedback()
1655 {
1656 /* Shortcut for GL functionality */
1657 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1658
1659 /* XFB object creation. */
1660 gl.createTransformFeedbacks(1, &m_xfb_dsa);
1661 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
1662 }
1663
1664 /** @brief Create buffer object and bind it to transform feedback object using direct access function.
1665 *
1666 * @note The function may throw if unexpected error has occured.
1667 */
prepareBuffer()1668 void FunctionalTest::prepareBuffer()
1669 {
1670 /* Shortcut for GL functionality */
1671 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1672
1673 /* Buffer creation and memory allocation. */
1674 gl.genBuffers(1, &m_bo);
1675 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");
1676
1677 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo);
1678 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer have failed");
1679
1680 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, DE_NULL, GL_DYNAMIC_COPY);
1681 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed");
1682
1683 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
1684 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer have failed");
1685
1686 /* Bind buffer to xfb object (using direct state access function). */
1687 m_gl_TransformFeedbackBufferBase(m_xfb_dsa, 0, m_bo);
1688 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackBufferBase have failed");
1689 }
1690
1691 /** @brief Build test's GLSL program.
1692 *
1693 * @note The function may throw if unexpected error has occured.
1694 */
prepareProgram()1695 void FunctionalTest::prepareProgram()
1696 {
1697 /* Shortcut for GL functionality */
1698 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1699
1700 struct Shader
1701 {
1702 glw::GLchar const* const source;
1703 glw::GLenum const type;
1704 glw::GLuint id;
1705 } shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
1706
1707 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
1708
1709 try
1710 {
1711 /* Create program. */
1712 m_po = gl.createProgram();
1713 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
1714
1715 /* Shader compilation. */
1716
1717 for (glw::GLuint i = 0; i < shader_count; ++i)
1718 {
1719 if (DE_NULL != shader[i].source)
1720 {
1721 shader[i].id = gl.createShader(shader[i].type);
1722
1723 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
1724
1725 gl.attachShader(m_po, shader[i].id);
1726
1727 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
1728
1729 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
1730
1731 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
1732
1733 gl.compileShader(shader[i].id);
1734
1735 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
1736
1737 glw::GLint status = GL_FALSE;
1738
1739 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
1740 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
1741
1742 if (GL_FALSE == status)
1743 {
1744 glw::GLint log_size = 0;
1745 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
1746 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
1747
1748 glw::GLchar* log_text = new glw::GLchar[log_size];
1749
1750 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
1751
1752 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
1753 << "Shader type: " << glu::getShaderTypeStr(shader[i].type)
1754 << "\n"
1755 << "Shader compilation error log:\n"
1756 << log_text << "\n"
1757 << "Shader source code:\n"
1758 << shader[i].source << "\n"
1759 << tcu::TestLog::EndMessage;
1760
1761 delete[] log_text;
1762
1763 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
1764
1765 throw 0;
1766 }
1767 }
1768 }
1769
1770 /* Transform Feedback setup. */
1771 gl.transformFeedbackVaryings(m_po, 1, &s_xfb_varying, GL_INTERLEAVED_ATTRIBS);
1772 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
1773
1774 /* Link. */
1775 gl.linkProgram(m_po);
1776
1777 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
1778
1779 glw::GLint status = GL_FALSE;
1780
1781 gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
1782
1783 if (GL_TRUE == status)
1784 {
1785 for (glw::GLuint i = 0; i < shader_count; ++i)
1786 {
1787 if (shader[i].id)
1788 {
1789 gl.detachShader(m_po, shader[i].id);
1790
1791 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
1792 }
1793 }
1794 }
1795 else
1796 {
1797 glw::GLint log_size = 0;
1798
1799 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
1800
1801 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
1802
1803 glw::GLchar* log_text = new glw::GLchar[log_size];
1804
1805 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
1806
1807 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
1808 << log_text << "\n"
1809 << tcu::TestLog::EndMessage;
1810
1811 delete[] log_text;
1812
1813 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
1814
1815 throw 0;
1816 }
1817 }
1818 catch (...)
1819 {
1820 if (m_po)
1821 {
1822 gl.deleteProgram(m_po);
1823
1824 m_po = 0;
1825 }
1826 }
1827
1828 for (glw::GLuint i = 0; i < shader_count; ++i)
1829 {
1830 if (0 != shader[i].id)
1831 {
1832 gl.deleteShader(shader[i].id);
1833
1834 shader[i].id = 0;
1835 }
1836 }
1837
1838 if (m_po)
1839 {
1840 gl.useProgram(m_po);
1841 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
1842 }
1843
1844 if (0 == m_po)
1845 {
1846 throw 0;
1847 }
1848 }
1849
1850 /** @brief Create and bind empty vertex array object.
1851 *
1852 * @note The function may throw if unexpected error has occured.
1853 */
prepareVertexArrayObject()1854 void FunctionalTest::prepareVertexArrayObject()
1855 {
1856 /* Shortcut for GL functionality */
1857 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1858
1859 /* Creating and binding empty vertex array object. */
1860 gl.genVertexArrays(1, &m_vao);
1861 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
1862
1863 gl.bindVertexArray(m_vao);
1864 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
1865 }
1866
1867 /** @brief Draw with XFB.
1868 *
1869 * @note Function follows steps:
1870 * Begin transform feedback environment.
1871 *
1872 * Using the program with discarded rasterizer, draw array of 4 indices
1873 * using POINTS.
1874 *
1875 * Pause transform feedback environment.
1876 *
1877 * Query parameter TRANSFORM_FEEDBACK_PAUSED using GetTransformFeedbackiv.
1878 * Expect value equal to TRUE.
1879 *
1880 * Query parameter TRANSFORM_FEEDBACK_ACTIVE using GetTransformFeedbackiv.
1881 * Expect value equal to TRUE.
1882 *
1883 * Resume transform feedback environment.
1884 *
1885 * Query parameter TRANSFORM_FEEDBACK_PAUSED using GetTransformFeedbackiv.
1886 * Expect value equal to FALSE.
1887 *
1888 * Query parameter TRANSFORM_FEEDBACK_ACTIVE using GetTransformFeedbackiv.
1889 * Expect value equal to TRUE.
1890 *
1891 * End Transform feedback environment.
1892 *
1893 * Query parameter TRANSFORM_FEEDBACK_ACTIVE using GetTransformFeedbackiv.
1894 * Expect value equal to FALSE.
1895 *
1896 * @note The function may throw if unexpected error has occured.
1897 *
1898 * @return True if included tests succeded, false otherwise.
1899 */
draw()1900 bool FunctionalTest::draw()
1901 {
1902 /* Shortcut for GL functionality */
1903 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1904
1905 /* Default result. */
1906 bool is_ok = true;
1907
1908 /* Start transform feedback environment. */
1909 gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_dsa);
1910 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback call failed.");
1911
1912 gl.beginTransformFeedback(GL_POINTS);
1913 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
1914
1915 /* Use only xfb. No rendering. */
1916 gl.enable(GL_RASTERIZER_DISCARD);
1917 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed.");
1918
1919 /* Draw. */
1920 gl.drawArrays(GL_POINTS, 0, 4);
1921 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
1922
1923 /* Pause Transform Feedback and tests direct state queries related to paused state. */
1924 gl.pauseTransformFeedback();
1925 GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback call failed.");
1926
1927 is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_PAUSED, GL_TRUE);
1928 is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_ACTIVE, GL_TRUE);
1929
1930 /* Activate Transform Feedback and tests direct state queries related to paused state. */
1931 gl.resumeTransformFeedback();
1932 GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback call failed.");
1933
1934 is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_PAUSED, GL_FALSE);
1935 is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_ACTIVE, GL_TRUE);
1936
1937 /* Finish transform feedback. */
1938 gl.endTransformFeedback();
1939 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
1940
1941 is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_ACTIVE, GL_FALSE);
1942
1943 return is_ok;
1944 }
1945
1946 /** @brief Check that selected Transform Feedback state has an expected value.
1947 *
1948 * @param [in] parameter_name Name of the parameter to be queried.
1949 * It must be GL_TRANSFORM_FEEDBACK_PAUSED or
1950 * GL_TRANSFORM_FEEDBACK_ACTIVE
1951 * @param [in] expected_value The expected value of the query.
1952 *
1953 * @note The function may throw if unexpected error has occured.
1954 *
1955 * @return True if the queried value is equal to expected value, false otherwise.
1956 */
testTransformFeedbackStatus(glw::GLenum parameter_name,glw::GLint expected_value)1957 bool FunctionalTest::testTransformFeedbackStatus(glw::GLenum parameter_name, glw::GLint expected_value)
1958 {
1959 /* Shortcut for GL functionality */
1960 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1961
1962 /* Dummy storage. */
1963 glw::GLint value = 314159;
1964
1965 /* Test of GetTransformFeedbackiv. */
1966 m_gl_getTransformFeedbackiv(m_xfb_dsa, parameter_name, &value);
1967 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbackiv call failed.");
1968
1969 if (expected_value != value)
1970 {
1971 m_context.getTestContext().getLog()
1972 << tcu::TestLog::Message << "It was expected that glGetTransformFeedbackiv query of parameter "
1973 << ((parameter_name == GL_TRANSFORM_FEEDBACK_PAUSED) ? "GL_TRANSFORM_FEEDBACK_PAUSED" :
1974 "GL_TRANSFORM_FEEDBACK_ACTIVE")
1975 << " shall return " << ((expected_value == GL_TRUE) ? "GL_TRUE" : "GL_FALSE") << "however, "
1976 << ((value == GL_TRUE) ? "GL_TRUE" : "GL_FALSE") << " was returned." << tcu::TestLog::EndMessage;
1977
1978 return false;
1979 }
1980
1981 return true;
1982 }
1983
1984 /** @brief Check that transform feedback buffer contains
1985 * consecutive integer numbers from 0 to 3 (included).
1986 *
1987 * @note The function may throw if unexpected error has occured.
1988 *
1989 * @return True if buffer conatins consecutive integer
1990 * numbers from 0 to 3 (included), false otherwise.
1991 */
verifyBufferContent()1992 bool FunctionalTest::verifyBufferContent()
1993 {
1994 /* Shortcut for GL functionality */
1995 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1996
1997 /* Default result. */
1998 bool is_ok = true;
1999
2000 /* Mapping buffer object to the user-space. */
2001 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo);
2002 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
2003
2004 glw::GLint* buffer = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
2005 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
2006
2007 for (glw::GLint i = 0; i < 4 /* Number of emitted vertices. */; ++i)
2008 {
2009 if (buffer[i] != i)
2010 {
2011 is_ok = false;
2012
2013 break;
2014 }
2015 }
2016
2017 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
2018 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
2019
2020 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
2021 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
2022
2023 return is_ok;
2024 }
2025
2026 /** Release GL objects, return to the default state
2027 */
clean()2028 void FunctionalTest::clean()
2029 {
2030 /* Shortcut for GL functionality */
2031 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2032
2033 /* Release transform feedback object. */
2034 if (m_xfb_dsa)
2035 {
2036 gl.deleteTransformFeedbacks(1, &m_xfb_dsa);
2037
2038 m_xfb_dsa = 0;
2039 }
2040
2041 /* Release buffer object. */
2042 if (m_bo)
2043 {
2044 gl.deleteBuffers(1, &m_bo);
2045
2046 m_bo = 0;
2047 }
2048
2049 /* Release GLSL program. */
2050 if (m_po)
2051 {
2052 gl.useProgram(0);
2053
2054 gl.deleteProgram(m_po);
2055
2056 m_po = 0;
2057 }
2058
2059 /* Release vertex array object. */
2060 if (m_vao)
2061 {
2062 gl.bindVertexArray(0);
2063
2064 gl.deleteVertexArrays(1, &m_vao);
2065
2066 m_vao = 0;
2067 }
2068
2069 /* Returning to default rasterizer state. */
2070 gl.disable(GL_RASTERIZER_DISCARD);
2071 }
2072
2073 const glw::GLuint FunctionalTest::s_bo_size = 4 * sizeof(glw::GLint);
2074
2075 const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 130\n"
2076 "\n"
2077 "out int result;\n"
2078 "\n"
2079 "void main()\n"
2080 "{\n"
2081 "\n"
2082 " result = gl_VertexID;\n"
2083 " gl_Position = vec4(1.0);\n"
2084 "}\n";
2085
2086 const glw::GLchar FunctionalTest::s_fragment_shader[] = "#version 130\n"
2087 "\n"
2088 "out vec4 color;\n"
2089 "\n"
2090 "void main()\n"
2091 "{\n"
2092 " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
2093 "}\n";
2094
2095 const glw::GLchar* const FunctionalTest::s_xfb_varying = "result";
2096
2097 } /* TransformFeedback namespace */
2098 } /* DirectStateAccess namespace */
2099 } /* gl4cts namespace */
2100