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