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 Samplers
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, "samplers_creation", "Sampler Objects 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 /* Samplers objects */
92 static const glw::GLuint samplers_count = 2;
93
94 glw::GLuint samplers_dsa[samplers_count] = {};
95
96 try
97 {
98 /* Check direct state creation. */
99 gl.createSamplers(samplers_count, samplers_dsa);
100 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateSamplers have failed");
101
102 for (glw::GLuint i = 0; i < samplers_count; ++i)
103 {
104 if (!gl.isSampler(samplers_dsa[i]))
105 {
106 is_ok = false;
107
108 /* Log. */
109 m_context.getTestContext().getLog()
110 << tcu::TestLog::Message << "CreateSamplers has not created defualt objects."
111 << tcu::TestLog::EndMessage;
112 }
113 }
114 }
115 catch (...)
116 {
117 is_ok = false;
118 is_error = true;
119 }
120
121 /* Cleanup. */
122 for (glw::GLuint i = 0; i < samplers_count; ++i)
123 {
124 if (samplers_dsa[i])
125 {
126 gl.deleteSamplers(1, &samplers_dsa[i]);
127
128 samplers_dsa[i] = 0;
129 }
130 }
131
132 /* Result's setup. */
133 if (is_ok)
134 {
135 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
136 }
137 else
138 {
139 if (is_error)
140 {
141 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
142 }
143 else
144 {
145 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
146 }
147 }
148
149 return STOP;
150 }
151
152 /******************************** Defaults Test Implementation ********************************/
153
154 /** @brief Defaults Test constructor.
155 *
156 * @param [in] context OpenGL context.
157 */
DefaultsTest(deqp::Context & context)158 DefaultsTest::DefaultsTest(deqp::Context &context)
159 : deqp::TestCase(context, "samplers_defaults", "Samplers Defaults Test")
160 , m_sampler_dsa(0)
161 {
162 /* Intentionally left blank. */
163 }
164
165 /** @brief Iterate Defaults Test cases.
166 *
167 * @return Iteration result.
168 */
iterate()169 tcu::TestNode::IterateResult DefaultsTest::iterate()
170 {
171 /* Get context setup. */
172 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
173 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
174
175 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
176 {
177 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
178
179 return STOP;
180 }
181
182 /* Running tests. */
183 bool is_ok = true;
184 bool is_error = false;
185
186 try
187 {
188 prepare();
189
190 glw::GLfloat expected_vector[4] = {0.0, 0.0, 0.0, 0.0};
191
192 is_ok &= testSamplerFloatVectorParameter(GL_TEXTURE_BORDER_COLOR, expected_vector);
193 is_ok &= testSamplerIntegerParameter(GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
194 is_ok &= testSamplerIntegerParameter(GL_TEXTURE_COMPARE_MODE, GL_NONE);
195 is_ok &= testSamplerFloatParameter(GL_TEXTURE_LOD_BIAS, 0.0);
196 is_ok &= testSamplerFloatParameter(GL_TEXTURE_MAX_LOD, 1000);
197 is_ok &= testSamplerIntegerParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
198 is_ok &= testSamplerIntegerParameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
199 is_ok &= testSamplerFloatParameter(GL_TEXTURE_MIN_LOD, -1000);
200 is_ok &= testSamplerIntegerParameter(GL_TEXTURE_WRAP_S, GL_REPEAT);
201 is_ok &= testSamplerIntegerParameter(GL_TEXTURE_WRAP_T, GL_REPEAT);
202 is_ok &= testSamplerIntegerParameter(GL_TEXTURE_WRAP_R, GL_REPEAT);
203 }
204 catch (...)
205 {
206 is_ok = false;
207 is_error = true;
208 }
209
210 /* Clean up. */
211 clean();
212
213 /* Result's setup. */
214 if (is_ok)
215 {
216 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
217 }
218 else
219 {
220 if (is_error)
221 {
222 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
223 }
224 else
225 {
226 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
227 }
228 }
229
230 return STOP;
231 }
232
233 /** @brief Create Sampler Objects.
234 *
235 * @note The function may throw if unexpected error has occured.
236 *
237 * @return True if test succeeded, false otherwise.
238 */
prepare()239 void DefaultsTest::prepare()
240 {
241 /* Shortcut for GL functionality */
242 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
243
244 /* Sampler object creation */
245 gl.createSamplers(1, &m_sampler_dsa);
246 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
247 }
248
249 /** @brief Test Sampler Integer Parameter.
250 *
251 * @note The function may throw if unexpected error has occured.
252 *
253 * @return True if test succeeded, false otherwise.
254 */
testSamplerIntegerParameter(glw::GLenum pname,glw::GLint expected_value)255 bool DefaultsTest::testSamplerIntegerParameter(glw::GLenum pname, glw::GLint expected_value)
256 {
257 /* Shortcut for GL functionality */
258 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
259
260 /* Get data. */
261 glw::GLint value = -1;
262
263 gl.getSamplerParameteriv(m_sampler_dsa, pname, &value);
264 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSamplerParameteriv have failed");
265
266 if (-1 == value)
267 {
268 m_context.getTestContext().getLog()
269 << tcu::TestLog::Message << "glGetSamplerParameteriv with parameter " << glu::getTextureParameterName(pname)
270 << " has not returned anything and error has not been generated." << tcu::TestLog::EndMessage;
271
272 return false;
273 }
274 else
275 {
276 if (expected_value != value)
277 {
278 m_context.getTestContext().getLog()
279 << tcu::TestLog::Message << "glGetSamplerParameteriv with parameter "
280 << glu::getTextureParameterName(pname) << " has returned " << value << ", however " << expected_value
281 << " was expected." << tcu::TestLog::EndMessage;
282
283 return false;
284 }
285 }
286
287 return true;
288 }
289
290 /** @brief Test Sampler Float Parameter.
291 *
292 * @note The function may throw if unexpected error has occured.
293 *
294 * @return True if test succeeded, false otherwise.
295 */
testSamplerFloatParameter(glw::GLenum pname,glw::GLfloat expected_value)296 bool DefaultsTest::testSamplerFloatParameter(glw::GLenum pname, glw::GLfloat expected_value)
297 {
298 /* Shortcut for GL functionality */
299 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
300
301 /* Get data. */
302 glw::GLfloat value = -1.0;
303
304 gl.getSamplerParameterfv(m_sampler_dsa, pname, &value);
305 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSamplerParameteriv have failed");
306
307 if (de::abs(expected_value - value) > 0.015625f /* Precision */)
308 {
309 m_context.getTestContext().getLog()
310 << tcu::TestLog::Message << "glGetSamplerParameterfv with parameter " << glu::getTextureParameterName(pname)
311 << " has returned " << value << ", however " << expected_value << " was expected."
312 << tcu::TestLog::EndMessage;
313
314 return false;
315 }
316
317 return true;
318 }
319
320 /** @brief Test Sampler Float Parameter.
321 *
322 * @note The function may throw if unexpected error has occured.
323 *
324 * @return True if test succeeded, false otherwise.
325 */
testSamplerFloatVectorParameter(glw::GLenum pname,glw::GLfloat expected_value[4])326 bool DefaultsTest::testSamplerFloatVectorParameter(glw::GLenum pname, glw::GLfloat expected_value[4])
327 {
328 /* Shortcut for GL functionality */
329 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
330
331 /* Get data. */
332 glw::GLfloat value[4] = {-1.0, -1.0, -1.0, -1.0};
333
334 gl.getSamplerParameterfv(m_sampler_dsa, pname, value);
335 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSamplerParameterfv have failed");
336
337 if ((de::abs(expected_value[0] - value[0]) > 0.015625f /* Precision */) ||
338 (de::abs(expected_value[1] - value[1]) > 0.015625f /* Precision */) ||
339 (de::abs(expected_value[2] - value[2]) > 0.015625f /* Precision */) ||
340 (de::abs(expected_value[3] - value[3]) > 0.015625f /* Precision */))
341 {
342 m_context.getTestContext().getLog()
343 << tcu::TestLog::Message << "glGetSamplerParameterfv with parameter " << glu::getTextureParameterName(pname)
344 << " has returned [" << value[0] << ", " << value[1] << ", " << value[2] << ", " << value[3]
345 << "], however " << expected_value << " was expected." << tcu::TestLog::EndMessage;
346
347 return false;
348 }
349
350 return true;
351 }
352
353 /** @brief Release GL objects.
354 */
clean()355 void DefaultsTest::clean()
356 {
357 /* Shortcut for GL functionality */
358 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
359
360 if (m_sampler_dsa)
361 {
362 gl.deleteSamplers(1, &m_sampler_dsa);
363
364 m_sampler_dsa = 0;
365 }
366 }
367
368 /******************************** Errors Test Implementation ********************************/
369
370 /** @brief Errors Test constructor.
371 *
372 * @param [in] context OpenGL context.
373 */
ErrorsTest(deqp::Context & context)374 ErrorsTest::ErrorsTest(deqp::Context &context) : deqp::TestCase(context, "samplers_errors", "Samplers Errors Test")
375 {
376 /* Intentionally left blank. */
377 }
378
379 /** @brief Iterate Errors Test cases.
380 *
381 * @return Iteration result.
382 */
iterate()383 tcu::TestNode::IterateResult ErrorsTest::iterate()
384 {
385 /* Shortcut for GL functionality */
386 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
387
388 /* Get context setup. */
389 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
390 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
391
392 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
393 {
394 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
395
396 return STOP;
397 }
398
399 /* Running tests. */
400 bool is_ok = true;
401 bool is_error = false;
402
403 glw::GLuint sampler_dsa = 0;
404
405 try
406 {
407 /* Check direct state creation. */
408 gl.createSamplers(-1, &sampler_dsa);
409
410 glw::GLenum error = GL_NO_ERROR;
411
412 if (GL_INVALID_VALUE != (error = gl.getError()))
413 {
414 is_ok = false;
415
416 /* Log. */
417 m_context.getTestContext().getLog()
418 << tcu::TestLog::Message
419 << "CreateSamplers has not generated INVALID_VALUE error when callded with "
420 "negative number of samplers to be created."
421 << "Instead, " << glu::getErrorStr(error) << " error value was generated." << tcu::TestLog::EndMessage;
422 }
423 }
424 catch (...)
425 {
426 is_ok = false;
427 is_error = true;
428 }
429
430 /* Cleanup. */
431 if (sampler_dsa)
432 {
433 gl.deleteSamplers(1, &sampler_dsa);
434
435 sampler_dsa = 0;
436 }
437
438 /* Result's setup. */
439 if (is_ok)
440 {
441 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
442 }
443 else
444 {
445 if (is_error)
446 {
447 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
448 }
449 else
450 {
451 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
452 }
453 }
454
455 return STOP;
456 }
457
458 /******************************** Functional Test Implementation ********************************/
459
460 /** @brief Functional Test constructor.
461 *
462 * @param [in] context OpenGL context.
463 */
FunctionalTest(deqp::Context & context)464 FunctionalTest::FunctionalTest(deqp::Context &context)
465 : deqp::TestCase(context, "samplers_functional", "Samplers Functional Test")
466 , m_fbo(0)
467 , m_rbo(0)
468 , m_vao(0)
469 , m_to(0)
470 , m_so(0)
471 , m_po(0)
472 {
473 /* Intentionally left blank. */
474 }
475
476 /** @brief Iterate Functional Test cases.
477 *
478 * @return Iteration result.
479 */
iterate()480 tcu::TestNode::IterateResult FunctionalTest::iterate()
481 {
482 /* Get context setup. */
483 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
484 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
485
486 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
487 {
488 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
489
490 return STOP;
491 }
492
493 /* Running tests. */
494 bool is_ok = true;
495 bool is_error = false;
496
497 try
498 {
499 prepareFramebuffer();
500 prepareVertexArrayObject();
501 prepareProgram();
502 prepareTexture();
503 prepareSampler();
504 draw();
505
506 is_ok &= checkFramebufferContent();
507 }
508 catch (...)
509 {
510 is_ok = false;
511 is_error = true;
512 }
513
514 /* Clean-up. */
515 clean();
516
517 /* Result's setup. */
518 if (is_ok)
519 {
520 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
521 }
522 else
523 {
524 if (is_error)
525 {
526 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
527 }
528 else
529 {
530 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
531 }
532 }
533
534 return STOP;
535 }
536
537 /** @brief Function prepares framebuffer with RGBA8 color attachment.
538 * Viewport is set up. Content of the framebuffer is cleared.
539 *
540 * @note The function may throw if unexpected error has occured.
541 */
prepareFramebuffer()542 void FunctionalTest::prepareFramebuffer()
543 {
544 /* Shortcut for GL functionality. */
545 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
546
547 /* Prepare framebuffer. */
548 gl.genFramebuffers(1, &m_fbo);
549 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
550
551 gl.genRenderbuffers(1, &m_rbo);
552 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
553
554 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
555 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
556
557 gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
558 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
559
560 gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1 /* x size */, 1 /* y size */);
561 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
562
563 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
564 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
565
566 if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
567 {
568 throw 0;
569 }
570
571 gl.viewport(0, 0, 1, 1);
572 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
573
574 /* Clear framebuffer's content. */
575 gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
576 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
577
578 gl.clear(GL_COLOR_BUFFER_BIT);
579 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
580 }
581
582 /** @brief Function generate and bind empty vertex array object.
583 *
584 * @note The function may throw if unexpected error has occured.
585 */
prepareVertexArrayObject()586 void FunctionalTest::prepareVertexArrayObject()
587 {
588 /* Shortcut for GL functionality */
589 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
590
591 gl.genVertexArrays(1, &m_vao);
592 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
593
594 gl.bindVertexArray(m_vao);
595 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
596 }
597
598 /** @brief Function builds test's GLSL program.
599 * If succeded, the program will be set to be used.
600 *
601 * @note The function may throw if unexpected error has occured.
602 */
prepareProgram()603 void FunctionalTest::prepareProgram()
604 {
605 /* Shortcut for GL functionality */
606 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
607
608 struct Shader
609 {
610 glw::GLchar const *const source;
611 glw::GLenum const type;
612 glw::GLuint id;
613 } shader[] = {{s_vertex_shader, GL_VERTEX_SHADER, 0}, {s_fragment_shader, GL_FRAGMENT_SHADER, 0}};
614
615 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
616
617 try
618 {
619 /* Create program. */
620 m_po = gl.createProgram();
621 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
622
623 /* Shader compilation. */
624
625 for (glw::GLuint i = 0; i < shader_count; ++i)
626 {
627 if (DE_NULL != shader[i].source)
628 {
629 shader[i].id = gl.createShader(shader[i].type);
630
631 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
632
633 gl.attachShader(m_po, shader[i].id);
634
635 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
636
637 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
638
639 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
640
641 gl.compileShader(shader[i].id);
642
643 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
644
645 glw::GLint status = GL_FALSE;
646
647 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
648 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
649
650 if (GL_FALSE == status)
651 {
652 glw::GLint log_size = 0;
653 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
654 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
655
656 glw::GLchar *log_text = new glw::GLchar[log_size];
657
658 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
659
660 m_context.getTestContext().getLog()
661 << tcu::TestLog::Message << "Shader compilation has failed.\n"
662 << "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
663 << "Shader compilation error log:\n"
664 << log_text << "\n"
665 << "Shader source code:\n"
666 << shader[i].source << "\n"
667 << tcu::TestLog::EndMessage;
668
669 delete[] log_text;
670
671 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
672
673 throw 0;
674 }
675 }
676 }
677
678 /* Link. */
679 gl.linkProgram(m_po);
680
681 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
682
683 glw::GLint status = GL_FALSE;
684
685 gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
686
687 if (GL_TRUE == status)
688 {
689 for (glw::GLuint i = 0; i < shader_count; ++i)
690 {
691 if (shader[i].id)
692 {
693 gl.detachShader(m_po, shader[i].id);
694
695 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
696 }
697 }
698 }
699 else
700 {
701 glw::GLint log_size = 0;
702
703 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
704
705 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
706
707 glw::GLchar *log_text = new glw::GLchar[log_size];
708
709 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
710
711 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
712 << log_text << "\n"
713 << tcu::TestLog::EndMessage;
714
715 delete[] log_text;
716
717 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
718
719 throw 0;
720 }
721 }
722 catch (...)
723 {
724 if (m_po)
725 {
726 gl.deleteProgram(m_po);
727
728 m_po = 0;
729 }
730 }
731
732 for (glw::GLuint i = 0; i < shader_count; ++i)
733 {
734 if (0 != shader[i].id)
735 {
736 gl.deleteShader(shader[i].id);
737
738 shader[i].id = 0;
739 }
740 }
741
742 if (m_po)
743 {
744 gl.useProgram(m_po);
745 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
746 }
747
748 if (0 == m_po)
749 {
750 throw 0;
751 }
752 }
753
754 /** @brief Function prepares texture object with test's data.
755 *
756 * @note The function may throw if unexpected error has occured.
757 */
prepareTexture()758 void FunctionalTest::prepareTexture()
759 {
760 /* Shortcut for GL functionality */
761 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
762
763 gl.activeTexture(GL_TEXTURE0);
764 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture call failed.");
765
766 /* Texture creation and binding. */
767 gl.genTextures(1, &m_to);
768 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures call failed.");
769
770 gl.bindTexture(GL_TEXTURE_2D, m_to);
771 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture call failed.");
772
773 /* Uploading texture. */
774
775 gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, s_texture_data);
776 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D call failed.");
777
778 /* Setup fragment shader's sampler. */
779 glw::GLint location = 0;
780
781 gl.getUniformLocation(m_po, s_uniform_sampler);
782 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation call failed.");
783
784 gl.uniform1i(location, 0);
785 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i call failed.");
786 }
787
788 /** @brief Function prepares sampler with test setup and binds it to unit 0.
789 *
790 * @note The function may throw if unexpected error has occured.
791 */
prepareSampler()792 void FunctionalTest::prepareSampler()
793 {
794 /* Shortcut for GL functionality. */
795 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
796
797 /* Sampler creation and setup. */
798 gl.createSamplers(1, &m_so);
799 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
800
801 gl.bindSampler(0, m_so);
802 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler have failed");
803
804 gl.samplerParameteri(m_so, GL_TEXTURE_WRAP_S, GL_REPEAT);
805 gl.samplerParameteri(m_so, GL_TEXTURE_WRAP_T, GL_REPEAT);
806 gl.samplerParameteri(m_so, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
807 gl.samplerParameteri(m_so, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
808 GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri have failed");
809 }
810
811 /** @brief Function draws a quad.
812 *
813 * @note The function may throw if unexpected error has occured.
814 */
draw()815 void FunctionalTest::draw()
816 {
817 /* Shortcut for GL functionality. */
818 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
819
820 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
821 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays have failed");
822 }
823
824 /** @brief Check content of the framebuffer and compare it with expected data.
825 *
826 * @note The function may throw if unexpected error has occured.
827 *
828 * @return True if succeeded, false otherwise.
829 */
checkFramebufferContent()830 bool FunctionalTest::checkFramebufferContent()
831 {
832 /* Shortcut for GL functionality. */
833 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
834
835 /* Fetch framebuffer data. */
836 glw::GLubyte pixel[4] = {0};
837
838 gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
839 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels have failed");
840
841 /* Comparison with expected values. */
842 if ((s_texture_data[0] != pixel[0]) || (s_texture_data[1] != pixel[1]) || (s_texture_data[2] != pixel[2]) ||
843 (s_texture_data[3] != pixel[3]))
844 {
845 m_context.getTestContext().getLog()
846 << tcu::TestLog::Message << "Frameuffer content (" << (unsigned int)pixel[0] << ", "
847 << (unsigned int)pixel[1] << ", " << (unsigned int)pixel[2] << ", " << (unsigned int)pixel[3]
848 << ") is different than expected (" << (unsigned int)s_texture_data[0] << ", "
849 << (unsigned int)s_texture_data[1] << ", " << (unsigned int)s_texture_data[2] << ", "
850 << (unsigned int)s_texture_data[3] << ")." << tcu::TestLog::EndMessage;
851
852 return false;
853 }
854
855 return true;
856 }
857
858 /** @brief Release all GL objects.
859 */
clean()860 void FunctionalTest::clean()
861 {
862 /* Shortcut for GL functionality. */
863 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
864
865 /* Release framebuffer. */
866 if (m_fbo)
867 {
868 gl.deleteFramebuffers(1, &m_fbo);
869
870 m_fbo = 0;
871 }
872
873 /* Release renderbuffer. */
874 if (m_rbo)
875 {
876 gl.deleteRenderbuffers(1, &m_rbo);
877
878 m_rbo = 0;
879 }
880
881 /* Release vertex array object. */
882 if (m_vao)
883 {
884 gl.deleteVertexArrays(1, &m_vao);
885
886 m_vao = 0;
887 }
888
889 /* Release texture. */
890 if (m_to)
891 {
892 gl.deleteTextures(1, &m_to);
893
894 m_to = 0;
895 }
896
897 /* Release sampler. */
898 if (m_so)
899 {
900 gl.deleteSamplers(1, &m_so);
901
902 m_so = 0;
903 }
904
905 /* Release GLSL program. */
906 if (m_po)
907 {
908 gl.useProgram(0);
909
910 gl.deleteProgram(m_po);
911
912 m_po = 0;
913 }
914 }
915
916 /* Vertex shader source code. */
917 const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 330\n"
918 "\n"
919 "void main()\n"
920 "{\n"
921 " switch(gl_VertexID)\n"
922 " {\n"
923 " case 0:\n"
924 " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
925 " break;\n"
926 " case 1:\n"
927 " gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
928 " break;\n"
929 " case 2:\n"
930 " gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
931 " break;\n"
932 " case 3:\n"
933 " gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
934 " break;\n"
935 " }\n"
936 "}\n";
937
938 /* Fragment shader source program. */
939 const glw::GLchar FunctionalTest::s_fragment_shader[] =
940 "#version 330\n"
941 "\n"
942 "uniform sampler2D texture_sampler;\n"
943 "\n"
944 "out vec4 color;\n"
945 "\n"
946 "void main()\n"
947 "{\n"
948 " color = texture(texture_sampler, vec2(0.33333, 0.33333));\n"
949 "}\n";
950
951 /* Name of texture sampler uniform. */
952 const glw::GLchar FunctionalTest::s_uniform_sampler[] = "texture_sampler";
953
954 /* Test's texture data. */
955 const glw::GLubyte FunctionalTest::s_texture_data[] = {
956 0xFF, 0x00, 0x00, 0xFF, /* RED */
957 0x00, 0xFF, 0x00, 0xFF, /* GREEN */
958 0x00, 0x00, 0xFF, 0xFF, /* BLUE */
959 0xFF, 0xFF, 0x00, 0xFF /* YELLOW */
960 };
961
962 } // namespace Samplers
963 } // namespace DirectStateAccess
964 } // namespace gl4cts
965