xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl4cDirectStateAccessSamplersTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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